Přednáška: Čtvrtek, 12:20, N1 (Pavel Ježek)
Cvičení:
Úterý, 9:00, SW2 (Jan Pacovský)
Úterý, 10:40, SW2 (Jan Pacovský)
Úterý, 12:20, SU2 (Filip Kliber)
Úterý, 17:20, SW2 (Jan Pacovský)
Středa, 10:40, SW2 (Martin Blicha)
Středa, 14:00, N11 (Filip Kliber)
Středa, 12:20, SW2 (Pavel Ježek)
Stránka v SIS: NPRG035
Zakončení: Zkouška a zápočet
Table of contents
- Náplň přednášek
- Náplň cvičení
- Informace o zkoušce
- Informace o zápočtu
- Uznávání povinností z minulých let
[in English] This page contains information for Czech students of the Programming in C# Language course. For english, switch the language in the page header.
Náplň přednášek
1. přednáška
- Představení předmětu, zkouška
- Rozdíly v reprezentaci proměnných v paměti v jazycích Python, C++ a C#
- Rozdíly referenčních a hodnotových typů, předávání argumentů hodnotou
- Paměťový overhead u referenčních typů, třída
Type
record (class)
,record struct
Materiály
2. Přednáška
- Připomenutí rozdílu referenčních a hodnotových typů, rozhodnut při deklaraci typu
- Příklady typicky referenčních, resp. typicky hodnotových typů
- Implicitní typované proměnné (
var
),new
bez jména typu v kontextu kde je to zřejmé (parametr, deklarace) - Položky (field) vs. vlastnosti (property) v typech,
readonly
- Automaticky implementované vlastnosti
- Alokace na GC haldě, nulování paměti, konstruktory, initializers
init
settery u vlastnosti (C#9), klíčové slovorequired
(C#11)- Primary constructor pro
record class
arecord struct
- Nullable hodnotové typy,
is null
operátor
Materiály
3. Přednáška
- Připomenutí nullable hodnotových typů
null
v běhovém prostředí .NET (CLR) a přístup knull
jakoNullReferenceException
- Nullable referenční typy (C#8)
- Duck typing v Pythonu, dynamicky typované jazyky
- Interface v C#, tabulka interface
I
u typuA : I
a najití metody několika dereferencemi v situaciI i = new A(); i.m1();
- Překryté metody klíčovým slovem
new
a hledání správné metody, která se bude volat - Operátor
is
aInvalidCastException
i v lepší variantěvariable is Type newVariable
- Vlastnosti=Properties (ne položky=fields) jakou součástí kontraktu v interface
Materiály
4. Přednáška
- Nepřenositelnost (závislost na platformě) u přeloženého C++
- Řešení přenositelnosti pomocí universal executable (fat binary) na MacOS
- Překlad C# kódu (
csc.exe
) do (přenositelné) assembly (.dll) a následně JIT (Just in time) překlad na specifické platformě - Možnosti optimalizace v situacích JIT nebo AOT (Ahead of time) překladu
- CIL (Common intermediate language), metadata v assembly
- Spouštění C# programu přes příkaz
dotnet
a přes přeložené.exe
(windows only) - Nástroje
ildasm
(součást .NET SDK) ailspy
(standalone nástroj), ladící informace (soubor.pdb
) - Dědičnost v C#, volání instančních metod (schovaný parametr
this
) - Abstraktní třída, společný předek
object
, volání konstruktoru předka přesbase
- Operátor
is
, třídaType
, metodaGetType()
a operátortypeof
- Operátor
is
a pattern-matching (C#9)
Materiály
5. Přednáška
- Konstanty
readonly
,readonly static
,const
- Optimalizace překladače na
const
, konstanta na úrovni CIL const
pro základní typy astring
- Class (static) constructor,
.cctor
- Delegování konstruktoru pomocí
: this()
, pořadí inicializace - Nulování paměti před voláním konstruktoru díky GC
- Klíčové slovo
nameof
, podtržítko (_
) v číselném literálu enum
,System.Enum
, metodaToString
, atribut[Flags]
,enum.Parse
using
alias astruct
jako alternativa kenum
Materiály
6. Přednáška
- úvod do NuGet-ových balíčků
- (micro)benchmarky a BenchmarkDotNet
- úvod do atributů (třídy
*Attribute
) - JIT optimalizace
- Překlad funkce (prolog, tělo, epilog), method inlining
System.Runtime.CompilerServices.MethodImpl
,MethodImplOptions
- micro-optimalizace
- Volání metod
- zakrývání metod v potomkovi klíčovým slovem
new
, výběr metody za překladu (generování instrukcecall
) - virtuální metody (
virtual
),override
, tabulka virtuálních metod (vType
), volání metody za běhu (instrukcecallvirt
)
- zakrývání metod v potomkovi klíčovým slovem
Materiály
7. Přednáška
- Zakrývání členů v potomkovi (klíčové slovo
new
), warning vs. error - Syntaktický zápis virtuálních metod v jazycích C++, C# a Java a problémy s defaultně virtuálními metodami v Javě
- Optimalizace virtuálního volání
sealed override
metod asealed
typů (devirtualizace) - Tabulka virtuálních metod, interface tabulka a volání skrz interface
- Rozdíl mezi
interface
aabstract
třídou interface
rozšiřující jiný interface a problém diamantové dědičnosti- Důvody pro explicitní
override
v C# oproti implicitnímu v C++ - Klíčové slovo
base
pro generování nevirtuálního volání z předka
Materiály
8. Přednáška
- Volání virtuálních metod v konstruktoru
- Hra Stardew Valley a návrhový vzor Factory
- Generování instrukce
callvirt
i při volání nevirtuálních metod - Připomenutí automaticky implementovaných vlastností (s backing field)
- Obecné vlastnosti,
get
,set
, kontextové klíčové slovovalue
, metodyget_*
,set_*
- Expression-bodied members (funkce
=>
tělo) pro funkce, ale i pro vlastnosti - Rozdíly mezi vlastností a funkcí, požadavky na rychlost vlastností, konvence pojmenování
double.NaN
místodouble?
a porovnávání pomocídouble.IsNaN
- virtuální a abstraktní vlastnosti a vlastnosti jako API v
interface
, statické vlastnosti - Rozdíly mezi různými syntaxemi pro zápis vlastností a metod v kombinaci s expression-bodied members
- Side-efekty u vlastností
- Viditelnost členů třídy (
public
,protected
,private
,internal
,protected internal
,private protected
,file
) a implicitní viditelnost při deklaraci - Deklarace/alokace proměnné, životnost proměnných, JIT optimalizace, omezení životnosti pomocí
{
a}
- Bonus: Parametrické vlastnosti (obecný .NET koncept), indexery (C#), syntaxe, interoperabilita C# s jinými .NET jazyky podporujícími plné parametrické vlastnosti, default parametrická vlastnost
Item
, přetěžování indexerů (ale ne vlastností)
Materiály
9. Přednáška
- Zakrývání položek třídy (klíčové slovo
new
) a zakrývání lokálních proměnných v C++ (ve vnitřnějším scope), ale ne v C# - Nutnost inicializace lokálních proměnných před jejich čtením, inicializace u pattern-matching konstrukce, explicitní scope
- Připomenutí hodnotových a referenčních typů, reference, boxing, volání metod na zaboxované instanci, unboxing a explicitní konverze,
InvalidCastException
, kompatibilita sobject
- funkce s proměnlivým počtem parametrů a klíčové slovo
params
- nemožnost kombinování unboxování a jiného přetypovaní a řešení pomoci více (explicitních) konverzí
- boxování nullable hodnotových typů
- ukazatele (pointers), nepoužívat
- tracking reference, ukázka na archaickém jazyce C++/CLI
Materiály
10. Přednáška
- Připomenutí tracking referencí a problémů obecných tracking referencí, nutnost inicializace tracking referencí
ref
parametry, automatické dereference, tracking reference na proměnné referenčních typů, nutnost použití klíčového slova i ve volání funkceout
parametry, nutnost zápisů do parametrů, možnost předat neinicializovanou proměnnou, deklarace proměnné přímo jako parametr- discard proměnná podtržítko (
_
), jenom pokud neexistuje v aktuálním kontextu identifikátor_
, zahazování výsledku přiřazovacího příkazu in
parametr a možnost implicitního získání reference (využití pro micro-optimalizace), ref readonly parametr- tracking reference jako lokální proměnné nebo jako návratová hodnota
interface
mimo typovou hierarchii (není potomkemobject
), ale možnost volat metodyobject
u na proměnné typuinterface
- Proč je
struct
implicitněsealed
a řešení v C++ - Volání metod struktur se skrytým parametrem
this
deklarovaným jako tracking reference struct
implementujícíinterface
a problémy s boxingem
Materiály
11. Přednáška
- pole, klíčové slovo
default
, inicializace proměnných, rozdíl mezi[]
na poli a na typech implementujících indexer (this[]
),System.Array
- více rozměrná pole (jagged pole polí, rectangular více-dimenzionální pole), více-dimenzionální pole s libovolným počátečním a koncovým indexem a problémy s efektivitou
- typová bezpečnost přístupu k prvkům pole (runtime check), pole struktur vs.
List
struktur ([]
vs. indexer), indexer vracející tracking referenci - konstruktory ve strukturách, výchozí hodnoty položek ve strukturách, inicializace položek struktury
- návěští, příkaz
goto
a omezení, implementace stavových automatů - příkaz
switch
a výrazswitch
(a pattern matching)
Materiály
12. Přednáška
- výraz
switch
(a pattern-matching) a jeho překlad do CIL kódu - další varianty pattern matchingu, přítomnost vlastností, zkonstruovatelnost a metoda
Deconstruct
a dekonstruktor ve formě duck typing record
aDeconstruct
- (C#11) pattern-matching na seznam,
..
syntaxe a kopírování (alokace) a potenciální problémy s kolekcemi co neví o své délce (více v LS) - Inicializace kolekcí pomocí
{}
a (C#12) inicializace kolekcí pomocí[]
a slicing pomocí..
- výjimky, třída
Exception
, C# příkazthrow
(a CIL instrukcethrow
) - chybové stavy bez výjimek pomocí
Try*
metod aout
parametrů, pomocí nullable typů try
-catch
blok, vyhození výjimky, zachytávání výjimky, stack-unrolling, vlastnostMessage
aStackTrace
, dopad na výkon- anotace
throws
v jazyce Java - Code Contracts (více na předmětu Program Analysis & Code Verification)
NullReferenceException
aIndexOutOfRangeException
vs.ArgumentNullException
aArgumentOutOfRangeException
Materiály
13. Přednáška
- Zachytávání výjimek,
catch
blok, znovu vyhození výjimek (throw;
) nebo zahození historie (throw ex;
) finally
block, dispose pattern,IDisposable
aObjectDisposedException
, příkaz a blokusing
, global using (a vylepšení v C#12)- různé scénáře pro zachytávání výjimek a best practices, použití pattern matching pro zachytávání specifických výjimek
Materiály
14. Přednáška
- Manuální alokace v C (
malloc
,free
) a C++ (new
/delete
) ownership v C++ volitelně pomocístd::unique_ptr
/std::shared_ptr
, v Rust povinně pomocíRc
- Alternativa v C# pomocí Garbace collector (GC), Small object heap (SOH), Large object heap (LOH)
- Připomenutí stránkování v OS, operace reserve a commit, .NET Core region
- work-station vs. server-mode GC, pravidla pro spouštění GC, GC roots, fáze markování, fragmentace haldy, heap compacting (v SOH), opravování referencí,
GCSettings
,GC.Collect
, alokace a nulování paměti - generační GC, memory-leaks, implementace
List<T>.Clear()
string
(System.String
), char literals, escape sekvence, immutable, implementacestring.Substring
,StringBuilder
a fluent syntax,string.Concat
string.Format
, interpolované řetězce (InterpolatedStringHandler
)
Materiály
Doporučená literatura
- Mark Michaelis with Eric Lippert: Essential C# 5.0, Addison-Wesley, 2013 (lze koupit např. na Amazon UK)
- Jeffrey Richter: CLR via C# (4th Edition), Microsoft Press, December 2012 (lze koupit např. na Amazon UK)
- Jon Skeet: C# in Depth (3rd Edition), Manning Publications, September 2013 (lze koupit např. na Amazon UK)
- blog Erica Lipperta (bývalý člen C# týmu v Microsoftu): Fabulous Adventures In Coding
- C# Language Specification 7.0
Případně
- Christian Nagel, Evjen, Jay Glynn, Karli Watson, Morgan Skinner: Professional C# 4.0 and .NET 4, Wrox, John Wiley & Sons, March 2010 (lze koupit např. na Amazon UK
Náplň cvičení
1. Cvičení
- Informace o předmětu, podmínky získáni zápočtu (k dispozici na této stránce), koncept cvičení
- IDE: Visual Studio, jak získat a alternativy
- Příklady na procvičení rozdílů mezi referenčními a hodnotovými typy
- velikosti proměnných a instancí, alignment, pole
- Zadání úloh Počítání slov a Četnosti slov
Materiály
2. Cvičení
- Klíčové aspekty řešení (obecně)
- funkční (v rámci specifikace)
- efektivní (v rámci použití)
- hezké (udržitelné, rozšiřitelné, dokumentované)
- Čtení slov:
File.ReadAllText
(nedostatečně oddělené kde jsou data a jak se data čtou)
- Kde jsou data:
File.OpenText
nebonew StreamReader
(případněConsole.In
,StringReader
), jakoTextReader
(a jako protipól vztah meziStreamWriter
,StringWriter
,Console.Out
jakoTextWriter
)
- Jak se čtou?
- ✖
ReadToEnd
(problém s velkými soubory) - ✖
ReadLine
(možný problém s dlouhými řádkami) - ✔
Read
(po znacích; pozor že funkce vracíint
) - rozdíl mezi rozdělováním slov (
string.Split
a varianta sStringSplitOptions.RemoveEmptyEntries
) a skládáním slov (string += char
, resp.StringBuilder
)
- ✖
- Přístup více shora (bez technických detailů)
- nějaký
WordReader
, co umí zTextReader
tahatstring
jako slova - nějaký
WordProcessor
(WordCounter
,WordFrequencyCounter
), co umí vzítstring
jako slovo a zpracovat jej (a možná nějak zařídit výstup) - nějaká společná část (argumenty, chyby, propojení), demonstrované na LineCounter
- nějaký
- Zadání nových úloh Odstavcové počítání slov a Sčítat, či nesčítat
- Jenom vágní zadání, ať je možnost rozmyslet dekompozici bez nutnosti řešit technické detaily
- V ReCodExu zveřejnění se zpožděním, ale deadline do příštího cvičení
- Hamlet.txt, ZeleninaShort.txt, ZeleninaShort-Vystup.txt
- Doplňkové videozáznamy:
- Testovací a datové soubory ve VS, Parametry příkazové řádky pro ladění/spouštění z VS, Launch profiles,
Property/launchSettings.json
- xUnit testovací framework, integrace s VS, vytváření projektů, project reference, psaní testů, integrační testy,
Assert
- Testovací a datové soubory ve VS, Parametry příkazové řádky pro ladění/spouštění z VS, Launch profiles,
3. Cvičení
- Prodloužení deadline na Odstavcové počítání slov a Sčítat, či nesčítat
- Připomenutí
interface
jako specifikace kontraktu a příklady - Kontrakt přímo ve formě typů (a rozdíl oproti python duck-typingu)
- Kontrakt pomocí výčtových typů (
enum
) a příklady - Diskuse nad možným objektovým návrhem prvních čtyř úloh
interface IWordReader
a implementaceWordReaderByLines
,WordReaderByClass
interface IWordProcessor
a implementaceWordCounter
,WordFrequencyCounter
,ParagraphWordCounter
,TableSummarizer
- obálka co to spojí a využívá těchto rozhraní
- Jaké metody má mít
IWordReader
, jaké mají mít návratové hodnoty, jaké parametry, kde číst slova? - Jaké metody má mít
IWordProcessor
, jaké mají mít návratové hodnoty, jaké parametry, kam vypisovat výstup? string
vs.string?
vs.Token
- Do příště
- (4+4 body) opravit své řešení úloh Odstavcové počítání slov a Sčítat, či nesčítat (pokud neprocházelo v ReCodExu)
- (5+5 bodů) odevzdat integrační testy pomocí frameworku xUnit, nUnit nebo MSTest (alespoň 10 testovacích scénářů na úlohu)
- (0+0 bodů) vylepšit své řešení úloh Odstavcové počítání slov a Sčítat, či nesčítat (bude se hodit na další úlohu)
4. Cvičení
- Operátor
is
a jak funguje - Různé způsoby reprezentace rolí uživatelů v aplikaci
- Implementace
Token
aTokenReader
, návrhový vzor Decorator/Wrapper, ladící hlášky pomocí návrhového vzoru decorator, různé alternativy refaktorování pomocí ChatGPT, příklady - Různé přístupy jak zkontrolovat, že je znak bílý a rozdíly v rychlosti
- Rozdíly mezi
Equals
a==
a potenciální problémy ITokenProcessor
co umí zpracovávat všechny druhy tokenů zní jako dobrý nápad, ale vede to na špatný návrh a krkolomnou implementaci- Zadání nové úlohy Zarovnání do bloku
- Bonusové body za integrační/unit testy, více bonusových bodů, pokud testy odevzdáte první a řešení bude rozumně procházet
- Důležitost vhodného pojmenovávání testů (nikoliv
UnitTest17
, ale radějiSingleParagraph_LongLines_SimpleWhitespaces
)
5. Cvičení
- GC, memory-leak v C# a možnosti jak to opravit
string
je immutable, mutable variantaStringBuilder
- rozdíl mezi
" "
a' '
jako reprezentace mezery (paměťový i v použití v kontextu metod, které beroustring
vs.char
) - Zakázání používání vlastnosti ze
System.Linq
(více o LINQ až v letním semestru) - Konvence psaní kódu, pojmenovávání identifikátorů
- zotavitelné vs. nezotavitelné chyby, rozdíl v identifikaci chyby a její prezentaci uživateli/programátorovi
- vlastní typy na chyby, s daty
- Popis řešení `WordProcessingToolkit`
- vlastní
ApplicationException
aAppErrorHandler
, rozšířenýTableSummatorAppErrorHandler
ArgsToIOState
a konverze ze systémových chyb na aplikačnítry
,finally
(oIDisposable
až jindy)
- vlastní
- Experiment, pohádka O hledání bugu
- Rozdíly mezi integračními testy a unit testy
- Testování metody, co vyžaduje kontrakt, Fake/Mock kontrakt, příklad na `LegacyWordCounterApp`
- Do příště
- Prodloužení deadline na Zarovnání do bloku
- (5 bodů) Na
ParagraphDetectingTokenReaderDecorator
napsat unit testy a opravit bugy v implementaci - (5 bodů) Refaktorovat
TableSummatorProcessor
, aby se dal unit testovat + na část napsat unit testy
6. Cvičení
- Virtuální metody, interface metody,
abstract
, příklad LegacyWordCounter
a refaktorování proFileProcessingConsoleAppFramework
IWordReader
naITokenReader
z minula- potřebujeme
WordCounter
jakoITokenProcessor
, ale jeIWordProcessor
, ale nechceme modifikovat (funkční, otestovanou) implementaci => návrhový vzor Adapter
- TestDrivenDevelopment
- ChatGPT unit testy na
int.Parse(string)
(nedostatečné), příklad - Komentáře k unit testování
ParagraphDetectingTokenReaderDecorator
- Komentáře k
TableSummator
až příště - Do příště
- 1. (micro)benchmark s využitím Benchmark.NET na srovnání použití datových struktur
SortedList
,SortedDictionary
aDictionary
+Sort
v kontextu úlohy Četnosti slov - 2. (micro)benchmark s využitím Benchmark.NET na srovnání různých přístupů k datové struktuře
Dictionary
v kontextu úlohy Četnosti slov, přístupy - Je přirozenější úlohy dělat v pořadí 2. -> 1. Za řešení až 8b manuálně v ReCodExu
- 1. (micro)benchmark s využitím Benchmark.NET na srovnání použití datových struktur
7. Cvičení
- Komentáře k refaktorování
TableSumatorProcessor
pro vhodnější unit testování- Rozdělení na nezávislé třídy
HeaderProcessor
DataColumnSumator
,TableSumatorProcessor
s jasně daným vstupem a výstupem - Předávání dat mezi vrstvami pomocí veřejného API tříd, nikoliv předáváním tříd samotných
- Rozdělení na nezávislé třídy
- Komentáře k Benchmarkování úlohy Četnosti Slov
- Scénář modifikace existujícího slova v
Dictionary
- Scénář přidání nového záznamu do
Dictionary
a způsoby jak to měřit (a neměřit něco jiného, jako alokaci klíčů nebo datové struktury),[IterationSetup]
aManualConfig
- Zdrojové kódy k .NET jako repozitář nebo jako prohlížeč
- Diskuse nad složitostí datových struktur a závěry benchmarků
- Scénář modifikace existujícího slova v
- Připomenutí hry Stardew Valley
- Přidání nového ovoce jako
abstract class Fruit
vs.interface IFruit
ainterface IEatable
- Frňákovník a návrhový vzor Abstract factory
- Ještě větší rozdělení a návrhový vzor Strategy
- Přidání nového ovoce jako
- Do příště
- (5b) Vícesouborové zarovnání v ReCodExu + (5b) Unit Testy
- (5b) Zahrát si hru DynaBlaster, analyzovat obrazovky v módu BATTLE a nakreslit graf, kde vrcholy jsou různé obrazovky, hrany znázorňují možné přechody mezi obrazovkami a hodnoty hran jsou data, které mezi obrazovkami tečou
8. Cvičení
- Příklad na IMT a VMT a řešení
- Komentáře k řešení úlohy Zarovnání do bloku
BlockJustifier
,LeftJustifier
- Komentáře k řešení úlohy Vícesouborové zarovnání (z řešení původní úlohy, ideálně bez nutnosti mazat existující kód)
ForwardingStringWriterAdapter
,HighlightingStringWriterDecorator
,TokenReaderFactory
- Komentáře k řešení úlohy Dynablaster a diskuse nad možnou implementací
- Návrhový vzor Model-View-Controller (MVC)
- Do příště
- Internetové knihkupectví v ReCodExu s využitím MVC
9. Cvičení
- Příklady na procvičení tracking referencí: Přiřazování hodnotových typů, referenčních typů, předávání referencí
- Heartbleed bug v knihovně OpenSSL
- Komentáře k řešení Internetového knihkupectví, diskuse, možné řešení
- Základní řešení
- Pokročilejší řešení (více separované a s využitím abstract factory na vracení views)
- Nová úloha Huffman I
- Strom je třeba mít uložený v paměti v nějaké objektové reprezentaci. Nestačí jej postupně tisknout.
10. Cvičení
- Komentáře k úloze Huffman I
- Uvědomění si, kde je kladen důraz na výkon (čtení souboru nebo stavění stromu)
- Rozdíly mezi
BinaryReader
aFileStream
, interní implementační detaily a možnost zefektivnění ještě dalším vlastním bufferováním (o velikosti 2n) - Přístupy k počítání frekvencí:
Dictionary<byte, long>
vs.new long[256]
(int
není dostatečně velký pro 1TiB soubory) - Reprezentace
HuffmanTree
: přímočarý přístup nebo více objektově orientovaný přístup
- Nová úloha Huffman II
- Bitové operace v C#: or
|
, and&
, xor^
, not~
, left shift<<
right shift>>
(>>
je závislé na znaménkovosti typu) BinaryWriter
BitConverter
,byte[] GetBytes(int)
,GetInt32(byte[])
, …
- Bitové operace v C#: or
11. Cvičení
- Komentáře k úloze Huffman II
- Zase, uvědomění si, ve které části programu jde o výkon (čtení souboru vs. stavění stromu vs. čtení souboru podruhé vs. zapisování do souboru)
- Ukládání bitových sekvencí
- ✖
string
("1011" + "0"
) alokuje novou paměť pro každou konkatenaci a kopíruje znaky z původních řetězců - ✖ Převod
string
nabyte
pomocíConvert.ToByte("10110", 2)
je univerzální algoritmus (podporuje více soustav, než jen binární) - ✔ Bitové operace (or
|
, and&
, xor^
, not~
, left shift<<
right shift>>
)
- ✖
- Nastavení n-tého bitu
value
na 1 jakovalue | x
, kde binární reprezentacex
má samé nuly, kromě jedné1
na n-té pozici (což je nějaká druhá mocnina)- ✖
Math.Pow(2, x)
univerzální funkce na mocniny, která podporuje i reálná čísla (tedy obecný algoritmus, neoptimalizovaný na mocniny dvojky) - ✔
1 << x
- ✖
- Odnastavení n-tého bitu (nastavit na 0)
value
jhakovalue & x
, kde binární reprezentacex
má samé jedničky, kromě jedné0
na n-té pozici, což je negace mocniny dvojky.value & ~(1 << n)
- Cache kódů vs. opakované procházení stromu
- verbatim identifier (
byte @byte
void @while()
) pro interakci s .NET jazykem L s identifikátorem, který je v C# klíčové slovo, ale v L není - digit separator v číselné konstantě jakožto oddělovač cifer pro lepší čitelnost (např.
int price = 12_751;
neboulong bits = 0b10110010_10010101
) - Nová trojice úloh Excel (level 0, level 1, level 2)
- Nesnažte se za běhu vypisovat výstup, ale první načtěte list, ten vyhodnoťte, a pak až vypište do souboru
- Nesnažte se podporovat vyhodnocování vzorců v jiném typu (např.
double
nebostring
) - Nesnažte se podporovat jiné druhy vzorců (funkce, více operátorů, konstanty)
12. Cvičení
- Hinty k úloze Excel a zadání bonusových úloh Hradlové sítě v separátním bonusovém videu
- Excel experiment a jak funguje debugger
- C#
readonly
jako alternative k C++const
funkci, příklad - Bug v java knihovně Log4j
- Další myšlenky k Excelu, fast-fail parsování, nevýhody výjimek a regulárních výrazů, hornovo schéma pro parsování referencí místo
int.TryParse
- Nová úloha Vyhodnocování Výrazů
- Načtení výrazu a jeho vyhodnocení, základ knihovny pro práci s výrazy
- Budou nové operátory, nebudou nové typy (
string
,double
), principiálně proměnné - Vyhodnocování rekurzí
- 5b za nějaké řešení + 5b za vhodný návrh
13. Cvičení
- Komentáře k řešení Vyhodnocování výrazů I
- Reprezentace výrazů jako strom (což vede na jednoduchou manipulaci s pod-výrazy; Abstract Syntax Tree)
- Použití klíčových slov
sealed
aabstract
jako rady ostatním programátorům kde se má aplikace rozšiřovat/které typy se mají vyrábět. Zároveň to může použít i překladač pro nějaké micro-optimalizace - Nevýhody implementace pod-uzlů jako
Expression[] array
. Použití specifických tříd (BinaryOperator
, …) s danou aritou - Specifické třídy
PlusExpression
,MinusExpression
, … pro oddělení vyhodnocování výrazů a výpočtu hodnot checked
blok- Parsování vstupu pomocí zásobníku ještě nedodělaných výrazů, což vyžaduje podporu v třídě
Operator
metodouAddOperand
(která ale nerozbíjí immutability) - Nevýhody použití
switch (token)
pro vytváření jednotlivých operátorů. Řešení tohoto problému nebylo prezentování (vizte Bonus níže) - Možné řešení
- Představení návrhového vzoru Visitor
- Nová úloha Vyhodnocování výrazů II
- 5 bodů za funkční řešení
- 5 bonusových bodů za využití návrhového vzoru visitor pro implementaci dvou vyhodnocovacích algoritmů v celých a reálných číslech
- Bonus: 5 dalších bodů za implementaci parsovacího algoritmu takovým způsobem, který umožní jednoduché začlenění nových operátorů (jinými programátory, kteří používají naši knihovnu) bez nutnosti nějaké formy
switch (operator)
Informace o zkoušce
Zkouška probíhá primárně písemnou formou, a v každé zkouškové písemce je kolem 6 až 8 otázek (některé obsahují podotázky). U každé otázky, případně podotázky, je dole uvedeno, jaký maximální počet bodů (=N
) lze za správně odpovězenou otázku/podotázku získat: N
bodů získáte v případě, že je odpověď na otázku správně; 0,5 * N
bodu získáte, pokud odpověď není zcela kompletní, ale jinak je správná (tj. nějaká malá část odpovědi chybí nebo je nepřesná); v ostatních případech získáte 0
bodů (tj. pokud v odpovědi chybí větší část, nebo je odpověď na otázku plně nebo i jen z části nesprávná).
Celkem lze z každé písemky získat maximálně 10
bodů. Mapování získaných bodů na výslednou známku je následující:
Body z písemky | Výsledná známka |
---|---|
10 – 8,5 | 1 |
8 – 6,5 | 2 |
6 – 5 | 3 |
4.5 – 0 | 4 |
Každá zkoušková písemka trvá 150 minut, tj. ideálně 20 minut na každou otázku + 30 minut bezpečnostní rezerva. Po písemné části následuje ústní část, kde zkoušející se studentem prochází jeho písemku, a případně nepřesností/nejasností u některých odpovědí se ptá na doplňující otázky — na základě toho je určeno finální bodové hodnocení každé otázky. Základem hodnocení je ale vždy písemná část, tedy u otázky bez odpovědi nebo se špatnou odpovědí nelze ani po ústní části získat více než 0 bodů.
Níže budou pro ilustraci uvedena zadání vybraných písemek z již proběhlých termínů:
- 13.1.2023 (PDF)
- 9.1.2023 (PDF)
- 16.1.2019 (PDF) [příloha zadání (dokumentace List<T>.RemoveAt)]
- 16.1.2018 (PDF) [příloha zadání (dokumentace List<T>.Insert)]
- 25.1.2017 (PDF)
- 1.2.2016 (PDF)
- 27.1.2016 (PDF)
- 20.1.2016 (PDF)
Doplňkové informace o zkoušce
Kromě informací uvedených ve slidech z první přednášky navíc pro zkoušky z NPRG035, NPRG038, a NPRG057 platí následující 2 body:
- Pokud někdo bude zapsán na nějakém z termínů zkoušky a na termín se nedostaví, bude mu tento termín v SISu označen jako propadlý (tj. student přijde o jeden pokus). Cílem tohoto opatření je optimalizace vytíženosti jednotlivých termínů, aby všichni studenti měli možnost přijít až na 3 termíny zkoušky.
- Pokud někdo na zkoušce získá známku 2 nebo 3 a bude si chtít svůj výsledek zlepšit, může explicitně na místě během vyhodnocení zkouškové písemky požádat zkoušejícího o nezapsání známky. Zkušební termín mu pak bude v SISu označen jako propadlý. Takový student může pak později
- požádat o dodatečné zapsání získané známky, nebo
- přijít na jiný termín zkoušky (jakýmkoliv výsledkem této “opravné” zkoušky se ovšem anuluje předchozí získaná známka).
Modelový příklad 1:
Student X získá na 1. termínu známku 2 a odmítne ji. Na 2. termínu získá známku 3 a odmítne ji. Na 3. termínu získá známku 1.
Aktuální stav studenta X: 1. termín = propadlý, 2. termín = propadlý, 3. termín = 1, tj. student X zkoušku splnil s hodnocením 1.
Modelový příklad 2:
Student Y získá na 1. termínu známku 3 a odmítne ji. Na 2. termínu získá známku 4.
Aktuální stav studenta Y: 1. termín = propadlý, 2. termín = 4, tj. pokud chce zkoušku splnit, musí student Y přijít na 3. termín. Pokud na 3. termínu opět získá známku 4, tak zkoušku nesplnil.
Modelový příklad 3:
Student Z se nedostaví na 1. termín, na 2. termínu získá známku 3 a odmítne ji, na 3. termínu získá známku 4.
Aktuální stav studenta Z: 1. termín = propadlý, 2. termín = propadlý, 3. termín = 4, tj. student Z zkoušku nesplnil.
Informace o zápočtu
Pro získání zápočtu je nutné splnit tři podmínky:
1. Zápočtový test
Naprogramovat a odladit jeden jednoduchý příklad v časovém limitu 3 hodiny. Koná se během zkouškového období v počítačové laboratoři. Celkem pět pokusu na splnění testu, maximálně však tři během zimního zkouškového období (další pak případně v letním termínu).
2. Zápočtový program
Termíny NPRG035 (zima) i NPRG038 (léto), NPRG057 (léto), NPRG064 (léto):
- Specifikace: 12. 7. 2024
- Předvedení finální plně funkční verze (včetně uživatelské a programátorské dokumentace):
-
- deadline: 9. 8. 2024
-
- deadline: 6. 9. 2024
-
Požadavky na program z NPRG035, NPRG064 (zdrojového kódu v jazyce C# ⇒ nevygenerovaný (ručně psaný) rozumný kód včetně rozumných komentářů):
- Předvedeno do 1. deadline: minimálně 30 kB zdrojového kódu v jazyce C#
- Předvedeno do 2. deadline: minimálně 45 kB zdrojového kódu v jazyce C#
- Předvedeno po 2. deadline: minimálně 60 kB zdrojového kódu v jazyce C#
Požadavky na program z NPRG038, NPRG057 (zdrojového kódu v jazyce C# ⇒ nevygenerovaný (ručně psaný) rozumný kód včetně rozumných komentářů + netriviální a rozumné použití některé z „technologií“ probíraných v NPRG038, resp. NPRG057 [více viz dané předměty]):
- Předvedeno do 1. deadline: minimálně 45 kB zdrojového kódu v jazyce C#
- Předvedeno do 2. deadline: minimálně 60 kB zdrojového kódu v jazyce C#
- Předvedeno po 2. deadline: minimálně 90 kB zdrojového kódu v jazyce C#
Poznámka: Každý zápočtový program, který splňuje požadavky NPRG038, resp. NPRG057, splňuje i požadavky NPRG035 (tj. lze odevzdat jeden program za oba předměty).
Poznámka: rozumný/rozumné = na požádání posoudí cvičící
POZOR! Osobní předvedení je součástí odevzdání. Na předvádění si připravte několik slidů shrnujících: hlavní funkce programu + hlavní řešené problémy + nástin architektury.
3. Domácí úkoly
Na cvičeních se budou postupně zadávat domácí úkoly, za jejichž vyřešení obdržíte body. Povinnost vám bude uznána pokud získáte dostatečné množství bodů. Získání většího množství bodů vám může pomoct získat body i ke zkoušce dle tabulky níže. K uznání povinnosti je třeba získat alespoň 80b.
Všechny domácí úkoly postupně najdete v ReCodExu pro NPRG035. Tam je také řešte a odevzdávejte. POZOR: Na úkoly zadané na cvičení je standardní deadline 7 dní (tj. do začátku příštího cvičení)!
Upozornění: Domácí úkoly jsou samostatnou prací, jejímž cílem je zhodnotit schopnost studenta samostatně vypracovat složitější program v jazyce C#. Pokud bude zjištěno, že některý student odevzdal cizí řešení (např. několik studentů odevzdalo různé instance stejného řešení některého domácího úkolu, apod.), bude to považováno za pokus o podvod. Všichni takoví studenti nesplní předmět NPRG035 v tomto akademickém roce a přicházejí o možnost uznání splněných povinností v roce příštím; případně bude disciplinární komisi UK MFF doporučeno jejich vyloučení ze studia!
Za nadstandardní množství bodů z úkolů je možné získat body ke zkoušce, a sice takto:
- min. 80 bodů = úroveň “I Can Win” → splněn jeden z požadavků na zápočet, konkrétně bod “povinnosti ze cvičení”
- min. 100 bodů → získání 1,25 silných bodů do zkoušky z NPRG035
- min. 120 bodů = úroveň “Hardcore” → získání dalších 0,75 silného bodu do zkoušky z NPRG035
- min. 150 bodů = úroveň “Nightmare!” → získání 0,5 slabého bodu do zkoušky z NPRG035
- min. 200 bodů = úroveň “Mission Impossible” → získání dalšího 0,5 slabého bodu do zkoušky z NPRG035
- min. 228 bodů = “božská úroveň” → na 1 rok propůjčen titul “bohyně veškerého Csharpistva” nebo titul “bůh veškerého Csharpistva”
Celkem lze tedy získat až 2 silné bonusové body a až 1 slabý bonusový bod do zkoušky z NPRG035 (hodnocení zkoušky viz slidy z první přednášky). Pozor — tyto silné bonusové body se budou započítávat pouze při 1. pokusu o složení zkoušky (tj. při svém 2. i 3. pokusu mají všichni 0 silných bonusových bodů). Nerozlišuje se z jakého důvodu student přichází na 2. nebo 3. termín (tj. zda např. odmítl známku na 1. termínu). Slabé bonusové body se budou započítávat při všech pokusech o složení zkoušky, ale pozor: slabé bonusové body nedokáží prorazit bariéru mezi známkou 4 a známkou 3 (tj. pokud po přičtení silných bonusových bodů stále vychází známka 4, tak se slabé bonusové body do výsledku zkoušky nezapočítávají).
Poznámka: Virtuální cvičení je určeno pro studenty, kteří nechtějí chodit na cvičení (např. protože minulý rok nestihli dodělat pouze zápočtový program, splnit zápočtový test, apod.).
Uznávání povinností z minulých let
Pokud jste tento předmět měli zapsaný loňský akademický rok a splnili jste pouze některé z povinností potřebných pro udělení zápočtu, může vám je po explicitním požádání (např. při předvádění zápočtového programu) uznat váš letošní cvičící (lze uznat domácí úkoly, zápočtový test, odevzdaný a schválený zápočtový program). Téma zápočtového programu (pokud ho ještě nemáte dokončený) nemusí být novým cvičícím uznáno. Pokud jste v loňském roce úspěšně složili zkoušku, ale nepodařilo se vám získat zápočet, lze opět po explicitním požádání požádat o uznání zkoušky. Toto je iniciativa vyučujících tohoto předmětu a nelze ji požadovat po studijním oddělení!