Lectures: Irregular, Virtual (Pavel Ježek)
Labs: Monday, 17:20, SW2 (Filip Kliber)
Page in SIS: NPRG038
Grading: Credit and exam
Table of contents
[in Czech] Zde jsou informace pro studenty anglické paralelky předmětu Pokročilé programování v jazyce C#. Pro českou verzi si v záhlaví stránky přepněte jazyk do češtiny.
Lectures outline
There are no regular lectures planned for the purpose of this course. Instead, the students will receive materials for self study that cover the topics for practicals and homeworks. Every 2-4 weeks, there will be a meeting/consultation lead by Pavel Ježek where students can ask questions regarding the provided materials.
Practicals outline
12. Practicals 2/2
- Bonus threading assignment (deadline 31.7.2022, 23:59, in SiS): ThreadSafeObjectHolder
- The goal is to create a light-weight (in terms of memory) data-structure holding a reference to zero, one or more objects (that are not
null) - It is supposed to be optimized in scenarios where the data structure holds zero or one objects
- In situations where it contains more objects, the data structure doesn’t need to be optimized anymore
- It has an API for retrieving first object and adding new object. It won’t support removing objects
- Hot-path of the data structure is calling
GetFirstObjectwhen it contains 0 or 1 objects, or callingAddObjectto change the number of objects from 0 to 1- These operations should be as fast as possible and should consume as little memory as possible
- Ideally 8B at most (one reference), excluding the reference to the data structure and heap overhead (i.e. ideally you should only store one reference).
- These operations mustn’t use any locks (to be as fast as possible), i.e. only use atomic operations (to be thread-safe) from
Interlockedtype
- In other situations (i.e. when the data structure stores more then 1 elements), we do not care how fast/memory efficient the data structure is (i.e. you can waste memory and can use locks)
- Skeleton/API
- The goal is to create a light-weight (in terms of memory) data-structure holding a reference to zero, one or more objects (that are not
12. Practicals 1/2
- Self study materials
- Interlocked (pages 63–64)
- UI threads (pages 30–31)
- ThreadPool, Task basics (pages 14–18)
- Comments on Antisocial Robots assignment (finding the problems with atomicity violations)
- Updating self location (
r.Location =) doesn’t collide with other robots inSimulateOneStepas each robot updates it’s own location (i.e. even though we have write operations, they work with different memory location)- However the former collides with checking the location in
DetermineNewLocationas the location of every robot is checked - We need to synchronize the access with some lock
- ✖ global lock;
DetermineNewLocationis the main algorithm (bottleneck), making it run in complete mutual exclusion would destroy the point of parallelism (and useless, we don’t need to synchronize all reads, just read with relevant write) - ✔ lock per location (per robot)
- ✖ global lock;
- The critical section should be as short as possible, thus
- Only lock the assignment in
SimulateOneStep - Similarly only lock the reading in
DetermineNewLocation(requires splitting the declaration and assignment) - Do not lock the whole iteration of the loop, the complex/time consuming math is working on local copy of the location (isolated)
- Only lock the assignment in
- However the former collides with checking the location in
- Similarly updating the board when moving the robot has such problem (if two robots want to move to single location, we have two write operation with the same memory location)
- ✔ global lock for the whole board; only synchronizes small part of the application, but still could do better if we have large board with distinct groups of robots; Example
- ✔ more fine-grained lock, per single cell on the board; seems like having huge memory overhead, but
- lock is just an
object(0B + 16B overhead + 8B ref) and unlocked lock doesn’t consume any extra memory, while locked does (but we will only have as many locked locks as threads) - we need to solve two data races actually (read + write of original location and read + write of new location), thus we need to lock representing original location and new location, in some order (i.e.
lock(orig) lock(new)); Example - this looks like a consistent order (
origfirst,newsecond), but if robotsAandBwant to switch places, then robot’sA origlocation is robot’sB newlocation and vice versa, which leads to potential deadlock; can be fixed by introducing some consistent order (that doesn’t take much work to deduce); Example
- lock is just an
- This concludes a working (data-race free) solution, but we should think if we are not locking too much
- Since the simulation is non-deterministic (depends on scheduling of individual working threads) we can try different approach
- lock our original location, and only try to lock the new location (needs to use the underlying
Monitor’s API directly) and if not possible, don’t move, as we wouldn’t anyway as someone has locked (attempting to enter) the cell; Example - The
TryEntermethod checks if we can enter the lock and if not, will return, but we already have that check there (if (_roomCells[newLoc.X, newLoc.Y] == null)) - We can instead lock the new location (then nobody else can update it) and check if we can move there, and if we can, only at that point lock the original location (which will not deadlock, as nobody can own our lock, if we are standing on such spot); Example
- lock our original location, and only try to lock the new location (needs to use the underlying
- Just because we found a sequence of operations that complies with the definition of a data race, it doesn’t mean that it is a problem. We can consult the memory model of our language (rules about how memory works for the point of the runtime, and assumptions user can make about the memory)
- C# memory model states, that reading and writing a single reference is atomic. E.g. for reference variables
aandbthe statementa = bis atomic in sense, that other thread will either see the original value ofa(before assigningb) or the new value ofa(afterbis assigned) and no other value is possible. - Which actually means, that we don’t need to protect original location with a lock, as the write is atomic
- Which actually means, that we didn’t have to reason about a deadlock at all, as we reduced the solution to using just one lock
- C# memory model states, that reading and writing a single reference is atomic. E.g. for reference variables
- More synchronization primitives
- New threading assignment (deadline 30.5.2022, 17:20, in SiS): AhoCorasick
- Browsing a file system and finding a text in files
- Useful types for working with file system:
Directory+DirectoryInfoandFile+FileInfo - Goal is to create a console application with the following CLI:
prog.exe text path C=1 S Q- first parameter is a sequence of characters to be found
- second parameter is a directory where to search for files (recursively)
- The search should be done in parallel in the following manner:
- We have a set of crawlers of a size
Cworking independently, that search for files (produce names of files);Cis always 1 (i.e. only one crawler) - And a set of searchers of a size
Sthat given a file will search it’s contents for a sequence of characters (consume the file names);Scan be arbitrary (i.e. 4) - Operating on a single queue of a maximal size
Q(crawlers put files in the queue, searchers take the items from the queue);Qcan be arbitrary (i.e. 16)
- We have a set of crawlers of a size
- The files should be searched in binary for a sequence of bytes that correspond to given text in some encoding. You are supposed to search in some encodings at once (which can be done efficiently using the AhoCorasick algorithm)
- Search for
textin encodingsEncoding.Deafult,Encoding.UTF8andEncoding.Unicode. These are objects that provide.GetBytes(string)method that returns the bytes encoding the string using such encoding - Implementation of AhoCorasick library is available here: DLL, API, Example usage,
- Search for
- The application needs to keep a single list of files in sorted order that contain the given text in any of the encodings, and the application should write a status line every
0.25swith the following content:MATCH #m/ALL #a/ERROR #e/READ #r MB/ Search time: #s s, where#mis number of files that matched,#ais the total number of processed files,#eis the amount of files that couldn’t be read,#ris the total MB read and#sis the amount of seconds that passed since the search started- The list of files is technically not needed for the output, but it is required to have it for the purpose of the assignment. I.e. imagine that any point during the execution of your program some external force could check the content of such a list and would expect the list of files being updated (you don’t have to think about synchronizing with such external force)
11. Practicals
- Self study materials
- Locks, thread safety, Monitor (pages 19–29, for Antisocial Robots assignment)
- Monitor.Wait(), .Pulse() (pages 65–80, for the upcoming assignment)
- Comments for Merge Sort Query assignment
- Straightforward solution: Split the array into halfs, delegate one half to different thread and recurse for the other half
- Pass around the number of threads (by delegating half of the available threads to each half)
- If the amount of available threads is zero, perform single threaded
filter()asort() - After returning from recursion, wait for the other thread (
.Join()) and performmerge() - If the working arrays are copied, there is no data sharing and no problems
- Possible solution
- Presentation about atomicity violations and simple locking
- New threading assignment (deadline 16.5.2022, 17:20, in SiS): Antisocial Robots
- Skeleton (same as before)
Robot.cshasLocation, which is it’s coordinates on the boardRobotSimulationBase.cshas_roomCells, which is the board referencing the robotsRobotSimulation.csis a file with two important functions:SimulateOneStepwhich performs one step of a robot in discrete simulation using the following methodDetermineNewLocationto calculate a new cell, where the robot should move to
- Your goal is to fix those two methods in such a way that they do not contain any atomicity violations; e.g. make sure that usage of every variable is either isolated, immutable or synchronized (notions from the presentation)
- It is expected to use basic locking in the form
lock(obj) { ... }, in such a way that- it works (i.e. no atomicity violations)
- it is efficient (i.e. one global lock is not valid solution)
- there is no possibility for a deadlock
- It is impossible for you to test your solution. Even if your program would run somehow, it doesn’t mean that it would happen like that every time, as the parallelism is not deterministic
- Do not refactor the code (e.g. keep the methods
SimulateOneStepaDetermineNewLocation). Just fix the problems that occur in multi-threaded environment - You can add new fields/variables (e.g. for locks)
- Submit only
RobotSimulation.cs
10. Practicals
- Self study materials
- Threading introduction, Thread class, Thread.Join() (pages 4–13)
- Comments for the Linq assignment
- Explanation of some behavior of modern CPUs and other tips for understanding the results of new assignment
- HyperThreading and the difference between physical core and logical processor (thread)
- PowerSavings, mostly on devices with battery (laptops)
- TurboBoost and automatic tuning of the clock of individual cores
- New threading assignment (deadline 9.5.2022, 17:20, in SiS): Merge Sort Query
- Using raw
System.Threading, notSystem.Threading.Tasks - Do not try to complicate things, the simple, straightforward solution is actually the best one
- Do not use
System.Linq(even though we just learned it, it might have some caveats when used from multiple threads) - Skeleton
LibraryModel/Model.csis a Model of a Library, that is loaded- Contains Books (with ISBN, Title, Author, Shelf)
- Shelf is
00Ato99Z - Library can contain multiple copies of a single Book (
Copy) - This copy can be leant (
CopyState) and has unique ID Copy.OnLoaddescribes who leant what and when will it be returned- Client has a name and surname
- Library is a list of Books, Copies, Loans and Clients
MergeSortQuery/MergeSortQuery.cscontains aMergeSortQueryclass- Property
ThreadCountindicating the maximal number of threads the application can use (including the calling thread) - Property
Libraryhas a reference to the Library model - Method
ExecuteQueryshould return a new list of sorted and filtered copies (see below)
- Property
Program.cshas a settings for random generator for library content (default 800MB, but can be set to 1500MB or 5000MB; those require x64 setting for the assembly)- Also contains
ReferenceTiming*.txtthat contains results on some machine. Your solution should provide similar results, namely- Your solution with
ThreadCount == 1should not be visibly slower than reference single threaded - Multi threaded should be visibly faster than single threaded
- More multi threaded solution (up to the number of physical cores of your machine) should show sings of speedup
- Two threaded solution can’t be two times faster (e.g. because final merge will happen in just one thread)
- Your solution with
- Goal is to do two things: Filter and Sort
- Filter (try to think when you should do the filtering: before sort, during merge, after sort)
- OnLoan == true
- Shelf between
xxAandxxQ
- Sort
- by
DueDate; then - by
LastName; then - by
FirstName; then - by
Shelf; then - by
Id
- by
- You can submit just the
MergeSortQuery/MergeSortQuery.cs(you mustn’t modify other files, except the setting forRandomGeneratorinProgram.cs, but your submission will be graded with some settings) - Your solution also generates
ResultMergesort*Threads.txtandResultReference*.txtfiles that contain the results (i.e. filtered and sorted copies). You solution must also have correct output (i.e. check your results withdiffor with some checksum algorithm).
- Using raw
9. Practicals
- Self study materials
- Anonymous types (can be used in HW)
- Tuples (not required in HW)
- Linq operators (most of them are to be used in HW)
- Several complex LINQ query examples
- Comments for sixth and seventh assignment (
Deque 2.1andDeque 2.2): IDequeinterface is a good idea- This interface should extend
ICollectionorIListinterface (because standalone is not that useful) IndexOf(T t)is a cycle and check whethertis equal to an current element. Problem is that==doesn’t work (asTis generic), soobject.Equals(object)need to be used instead. This causes boxing ifTisValueType=> check ifTimplementsIEquattable<T>and callIEquattable<T>.Equals(T)that accepts generic argument and thus doesn’t need boxing.- This can be delegated to
EqualityComparer<T>.Default - And the whole solution can be improved by accepting arbitrary
IEqualityComparer<T>in constructor and letting the user decide what does being equal mean.
- This can be delegated to
- Using versions to check for concurrent modifications is necessary in
yield returnas well (as no automatic check happens) - Solution
- This interface should extend
- LINQ - Language INtegrated Queries
- Linq is a syntax
from c in customers where c.City == "London" select ctranslated into C#customers.Where(c => c.City == "London") - semantics is provided by a library (Linq to something)
- Linq to Nothing and via extension methods
- Linq is a syntax
- Linq to Objects (
using System.Linq)- Motivation with SQL table and filtering via SQL commands
- As lazy as possible. Query creates a description (
WhereEnumerable),foreachcreates enumerators to iterate over the results of the query (in lazy manner) - Example of laziness in Linq to Objects
- Example of reusability of Linq queries.
- Performance difference between
from a in collection where alpha orderby betavs.from a in collection orderby beta where alpha - More Linq operators in materials by Dr. Ježek (see mail, or above)
- New assignment (deadline 2.5.2022, 17:20, in SiS): Linq
- Skeleton
class Personwith name, age and other people this person considers as their friends (Friends, do not useFriendListInternal)class Groupas a collection ofPerson, with somePersons relationships- Prepare a method, that prints enumerates the result of the query (i.e.
void Print(IEnumerable<Person> enum)) - For every assignment in skeleton provide a single linq query solving the assignment
- Use the LINQ syntax (i.e.
from c in groupA where ..., notgroupA.Where(...)) if possible (not always) - You can reuse previous queries (i.e. with/without repeats)
- No need for extra methods (apart lambdas in queries) or data types (apart from anonymous classes in
select) - Try to think about performance (i.e. try to enumerate collections as little as possible)
- You can check that by comparing output of debugging statements (if your program produces way too more debugging statements for some assignment, the queries could probably be optimized)
- If the assignment doesn’t state what the order of output is, it doesn’t matter if your solution produces the results in different order (as long as the sets are the same)
- Expected output: No debugging, D1, D2 (no need for exactly the same output in D1/D2)
8. Practicals
- Self study materials
- Iterators and yield return (Read just part “Introducing Iterators”)
- More iterator examples (Read part “Enumeration sources with iterator methods”)
- Iterator block implementation details
- More about
git branchand the difference between branch and tag- Using
git tagfor marking a point in a history as final (e.g.release-1.0)
- Using
- How to combine two repositories while keeping both histories
- Via remote repositories and
git mergeof a remote branch - With moving the files for better organization in the file system, which is recognized by git as a rename (and not a removal + addition)
- Via remote repositories and
- Usefulness of
git stashandgit cherry-pick - Hints for
Dequeassignment: - Concurrent collection modification should be detected by the implementation of
IEnumerator, how?- By versioning the collection
int version = 0- Every modifying (only modifying) operation will do
version++ IEnumeratorwill remember theversionwhen it was created- Every method/property of the
IEnumeratorwill check if storedversion == collection.versionand if not, willthrow InvalidOperationException - Similarly for
yield return(doesn’t happen automatically, as there might not even be a backing collection)
- Notes about
ReverseViewof theDeque- A proxy/wrapper class, not a copy
- Different view on the same data (from different angle)
- Used for testing of
Addto the beginning
- usage of
ICollection.Addin value initialization in the form ofnew List<int> { 1, 2, 3 }; - Introducing
IDequemight be a good idea - Implementing
ICollection.Addexplicitly to hide it from public API, asIDequemight provide a more verbose (less confusing) API- Which sadly disables the value initialization
- New assignment (deadline 18.4.2022 (one week), 17:20, in SiS, and ReCodEx): Deque 2.2
- In your
Deque 2.1assignment, create new branch and implement the enumeration viayield returnenumeration methods - Test your solution against ReCodEx submission (join the Advanced programming in C# group)
- After it works 100%, upload as ZIP archive containing GIT repository (with new branch) into SIS
- In your
7. Practicals
- Self study materials
- Namespaces
- Nested types
- Private interface
- IEnumerable
and foreach (Read just part “What Makes a Class a Collection” of)
- Comments for fifth assignment (
Serializerframework):- Separation between delegates retrieving the values from the model and actual serialization into some format
- ✖ Serialization in delegates
- If we were to change the format (XMl to JSON), all users would have to rewrite their descriptions
- ✔ Presented solution
- Using `nameof`
- Problem, if we change the name of the property, then also the name of the tag in XML changes, and if we already had some serialized files, those would be incompatible
- Solution that separates the idea of serialization and output format with visitor pattern (advanced solution, but very nice)
- Talk about
IEnumerable<T>,IEnumerator<T>,ICollection<T>andIList<T>interfaces for collections in .NET- Also problem with backwards compatibility of
IEnumerable,IEnumerator,ICollectionandIListwith need of explicit interface implementation (consult your materials) - Basic example of implementing
IEnumerable<T>andIEnumerator<T>- Works lazy. Enumerator can make up the values (doesn’t need backing connection) — Example of enumerable of infinite stream of random numbers.
- Inability to modify the collection, while it is being enumerated (throws exception, see example).
- How the compiler translates
foreach (ElementType element in collection) statement;can be seen here
- Also problem with backwards compatibility of
- New assignment (deadline 18.4.2022 (two weeks), 17:20, in SiS, and ReCodEx): Deque 2.1
- Same as bonus homework assignment from winter semester
- Implementation of
Dequecollection (amortized constant time complexity of adding and removing from both beginning and end) Deque<T>needs to implementIList<T>(thus alsoICollection<T>aIEnumerable<T>)- Implementation of
ReverseView, which is not a copy of theDequebut rather a proxy view — adding to the beginning of reverse view adds to the end of the standard deque; enumeration of reverse view enumerates the elements in reverse order; … - Without usage of
yield return(extension of this assignment will be published next week (for implementation usingyield return)) - Consult ReCodEx for required implementation
- Test your solution against ReCodEx submission (join the Advanced programming in C# group)
- After it works 100%, upload as ZIP archive containing GIT repository into SIS
6. Practicals
- Self study materials
- Practical introduction to delegates and anonymous functions (lambdas)
- Standard C# delegates
Action,FuncandPredicate Pointtype and algorithm parametrized by function (lambda) computing distance via different types of metrics: Example- Generic
Mapmethods, that can convertIEnumerable<I>intoIEnumerable<O>by providing a function, that convertsItoO: Example- Type inference in this context is not simple, but works and compiler can deduce e.g. type arguments of
Mapfunction from the generic delegate being passed (which type may again be deduced from some other argument)
- Type inference in this context is not simple, but works and compiler can deduce e.g. type arguments of
- Standard C# delegates
- Benchmarking removal of items from a
Listby functionsRemove(T item),RemoveAt(int index)andRemoveAll(Predicate test): Example- If we’re removing more a lot of items,
RemoveandRemoveAtare O(n2), whileRemoveAllisO(n), as it know howListworks and can do the removal in one swoop - But for removing just one element,
RemoveAllis actually worst, as the overhead of calling the method through the delegate is not trivial (and it prevents some optimization, such as method inlining; as delegate can not be inlined since the method that will be called is not known when the enclosing method executes) - Benchmarks are just code, and that can contain bugs, and then the result of the benchmark might be garbage (which we should not try to interpret in any way)
- If we’re removing more a lot of items,
- New assignment (deadline 4.4.2022, 17:20, in SiS): Serialization framework
- Skeleton
- Reference output
- Using
System.Reflectionis forbidden - Task is to create a generic serialization framework; and a configuration for our specific model
- Self study materials (are not required to complete the assignment, but can be useful to get more experience with delegates; and are part of the exam)
5. Practicals
- Self study materials
- Comments on fourth assignment (
Fixedpoint): - Always 32 bit of precision leads to using
intas a backing data type- It makes no sense to use 2x
shortor 4xbyteif I might want aQ4_28type - using
longinstead might seem like a good idea for multiplication/division (better precision), but the signed-extension frominttolongis easy for processor, and thelongitself might be a big (memory) overhead (x2)
- It makes no sense to use 2x
- Deciding between:
- ✖
class; memory overhead (reference,Type, sync block) - ✔
struct; value semantics as typical for other numerical types
- ✖
- Where to store information about precision:
- ✖ In
Fixed<Q>as instance field; overhead, while the precision is tied to the value, it’s same for all the values of the same type - ✔ In
Fixed<Q>as static field; better, but needs to be initialized with specific value, depending onQ; Example - ✔ In
Q(type argument)
- ✖ In
- How to differentiate between constructor
Fixed(int integerValue)andFixed(int internalRepresentation): - How to retrieve precision from
Q(type argument) - Example of nice unit test scenarios:
- Introducing Code Coverage mechanism in Visual Studio to see what portion of the code is covered by unit tests.
- 100% code coverage doesn’t imply bug-free program
- But < 100% code coverage implies not thoroughly tested program
- Presentation of
BenchmarkDotNet(NuGet) package that can be used to create more robust, statistically better benchmarks, when compared to theSystem.Diagnostics.Stopwatchclass- Automatically calls the method multiple times, tries to make sure that the metod is JITted, that there was enough warmup, that the heap is in some reasonable state (non-empty)
- Project has to be compiled in
Releasefor more precise results - Can be configured to keep track of memory allocations, branch mis-predictions, cache misses, and other CPU counters
- Detects and filters outliers, presents statistical data (mean, error, std dev)
- Example benchmark testing the difference between
doublebeing wrapped inclassorstruct
- No new regular homework, but a bonus one (deadline End of Semester, in SiS)
- Extend Fixed point assignment so that the
Fixedtype is proper entityGetHashCode,Equals,IEquattable,IComparable- conversion from/to
int(nodouble) - conversions between different Q types (think about implicit/explicit)
- relational operators, math operators (with
int, with other Q types, nodouble)
- Add a benchmark testing the difference between
float,doubleandfixed- Implement a simple gauss-elimination algorithm to convert matrix to REF form (no RREF)
- Submit a
Notes.mddocumentation that explains the results of the benchmark (or what you think about the results)
- Extend Fixed point assignment so that the
4. Practicals
- Self study materials
- Comments for third assignment:
- Factories in NezarkaGame:
- Presented solution
- Contains GIT repo with (checked out) branch
modelstore-genericfactories
- ImmutablePeople
- Factories in NezarkaGame:
- Semantic division of classes in C# into three categories: entities, collections (of entities) and others
- Collection imposing some requirement on entities
- From
object, methodsEquals,ToStringandGetHashCode - Interfaces
IEquattable<T>andIEqualityComparer<T>, and implementationEqualityComparer<T>.Default
- From
- Recap of class constructors (static initialization) from winter semester
- Using
A<T>doesn’t run class constructor ofT(unlessTis explicitly used as well) - Explicitly run
.cctorviaSystem.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor - Example
- Using
- New assignment (deadline 21.3.2022, 17:20, in SiS, see mail transcript below for details how the submission should look like!)
3. Practicals
- Self study materials
- Generics with constrains (video)
- Type parameters as constraints (Read article from top to part “Type parameters as constraints” (including; you can skip
where T : class?,where T : notnull,where T : unmanagedconstraints) - Generic extension methods
- Comments for first two assignments
- For physics engine:
Second,Meter,MeterPerSecondare to bestructs, as we clearly don’t want reference semantics (they are values)- Benchmark testing the difference between
doublebeing wrapped inclassorstruct(uses BenchmarkDotNet library); Example
- Benchmark testing the difference between
- Implicit conversion between them and
int/doubleare dangerous, as we might accidentally pass seconds into meters (it’s better to enforce the type safety) LimitedPositionUpdateras a grouping of speed and lower/upper bound (visible area in the game), as we again don’t need the reference semantics- Also allows us to reuse the code for
UpdatePosisitonfor both horizontal and vertical movement
- Also allows us to reuse the code for
- For joining Nezarka bookstore customers with our game:
- Extract model into a separate project, as game doesn’t need to know about the webserver
- Inserting an instance of
Customerinto aListBox:- ✖ Adding
ToStringtoModel.Customer; If we had additional project, that needed a differentToStringimplementation, we would not be possible to provide that - ✖ Adding extension method in
JumpingPlatformGameproject; Doesn’t work, as theListBoxselectsToStringduring the compilation of WinForms (and that selectsobject.ToString) - ✔ Adding new class inheriting from
Model.Customerand having it’s ownToString; this has a problem that instances created in theModelare pureModel.Customer(not our inherited classes) and thus we have to parametrizeLoadModelwith factories - ✔ Adding wrapper class holding a reference to
Model.Customerand havingToStringmethod; much easier for programming then factories, but limited usage (but alright for our use case)
- ✖ Adding
- Treating
CustomerasMovableEntityby creating new class (CustomerMovableEntity) that inherits fromMovableEntityand holds a reference to the instance of theModel.Customerclass
- Presented Solution (contains also
modelstore-factoriesbranch) - Reminder of creating a UnitTesting project
- New programming tool: MarkDown
- Historically name of the tool for converting text with marks to
.html(nowadays standalone format) - Source more readable than HTML
- Not actually standardized. There are various markdown flavours that behave differently in advanced features (i.e. tables)
- Historically name of the tool for converting text with marks to
- Immutable types and fluent/
Withsyntax - Problems with
Withsyntax when inheritingclass A { public A With() }returnsA. Havingclass B : A { public void f() }doesn’t allow us to do the following:(new B()).With().f()asfis not declared inA- Solving by having generic class constrained on
Tbeing inherited from itself - Example
- Homework assignment (deadline 14.3.2021 17:20, submit to SIS, as ZIP archive, containing two GIT repositories, without temporary/binary files (clean))
- Extend HW2 (
NezarkaJumpingPlatformGame) to reduce code duplication in factories (by using generics)- You can use yours solution or the presented one
- Submit the implementation as a new branch in existing GIT repository
- New HW,
ImmutablePeople, Skeleton- Add a new file and implement required classes, so that
Program.cscompiles, and it’s output is the same asImmutablePeople.txt - Individual instances have to be immutable, modifiable using the
Withfluent syntax - Without using C#9.0
records - Submit implementation as clean GIT repository containing:
- Implementation of
ImmutablePeople - UnitTests
- Documentation in MarkDown format (how are classes used, which problems you encountered and how were the problems solved, ToDo list, …)
- Implementation of
- Add a new file and implement required classes, so that
2. Practicals
- Self study materials
- Named arguments
- Function
m(int a, int b)and calling such function asm(5, 6),m(a: 5, b: 6)andm(b: 6, a: 5)are equivalent (resolved by C# compiler, not visible in the CIL code) - Use when it would help with understanding the code.
- Function
- Optional arguments
- Function
m(int a, int b = 6)and calling such function asm(1)andm(1, 6)are equivalent (resolved by C# compiler, not visible in the CIL code) - Difference to having two functions
m(int a, int b) {}andm(int a) { m(a, 6) }(these really are two functions in the compiled assembly, the former is a single function)
- Function
- Example
- Creating of solution with multiple project with nice folder hierarchy
- Set as startup project
- Copy to output folder
- Integration of GIT into the VisualStudio
- Simple introduction to WinForms applications
- Using GIT to clean the working directory
- Result solution
- Homework assignment (deadline 7.3.2021, 17:20, submit to SIS, as a ZIP archive, without temporary/binary files (clean), as a GIT repository)
- Extend HW1 (
JumpingPlatformGame) by option to add a customer into a game field as aMovableEntity. Customer is a customer of Nežárka bookstore from winter semester’s assignment. - Solution to Nezarka (use this, for consistency)
- Add a
ListBoxof customers and a button, which will add the entity with a color depending on how many years is the customer registered in the bookstore:< 1: Color.Black== 1: Color.DarkRed== 2: Color.Red== 3: Color.IndianRed> 3: Color.OrangeRed?: Color.Gold, unspecified, meaning from the beginning of the bookstore
- Extend HW1 (
1. Practicals
- Self study materials
- Introductory lecture, course requirements, Slides. The information about requirements is also available on this web page
- User-defined conversion operators
- Other user-defined operators
- Arithmetic:
+,-(unary and binary),*,/,%,++,-- - Relational:
==,!=,<=,>=,<,> - Bitwise:
&,|,^,~,>>,<< - Unary:
!,true,false - if
==(or<,<=,true) is overloaded, then!=(or>=,>,false) must be overloaded as well! - Simple example showing addition of
Fractiontypes
- Arithmetic:
- HomeWork (deadline: 28.2.2022 17:20)
- Skeleton
- Make the
GamePhysicsproject compilable in such a way that the program prints expected output, without modifying theMainfunction (Customer’s API) - Make the
JumpingPlatformGameproject compilable in such a way that the program has the expected behavior, without modifying theMainForm.csfile (Customer’s API) JumpingPlatformGameproject depends on theGamePhysicsproject. It is therefore enough to modifyGamePhysics/Program.csandJumpingPlatformGame/Entities.csfiles
Information about the Exam
Primary part of the exam consist of written part including around 6 to 8 questions (which might include sub-questions). Every question has a visible maximal amount of points that can be awarded for the question (=N). For correct answer, the student will receive N points for the question; for incomplete, but overall good answer (i.e. some part of the answer is missing or is incorrect), the student will receive 0.5 * N points; in other cases, the student will receive 0 points (i.e. if the answer is missing completely or is mostly incorrect).
The student can receive up to 10 points from the Exam. The mapping between points and grade is as follows:
| Points from the exam | Awarded grade |
|---|---|
| 10 – 8.5 | 1 |
| 8 – 6.5 | 2 |
| 6 – 5 | 3 |
| 4.5 – 0 | 4 |
The written part of the exam takes up to 150 minutes (i.e. 20 minutes for each question, with 30 minutes extra time). After the written part, the oral part follows, where the examiner discusses the answers with the student, demands clarification when needed and asks complementary questions if deemed necessary — based on this, the final amount of points for each question is determined. The evaluation is always based on written part of the Exam, which means that student can’t be awarded with more than 0 points for a question without an answer.
Requirements for the Credit
In order to receive the credit, it is necessary to fulfill these requirements:
1. Homeworks
There will be several (10-12) homeworks assigned during the semester. The difficulty of individual homeworks might vary. Successfully solving the homework task will reward the student with OK mark. If there are some problems with the submission (i.e. missing implementation of minor feature) the student will receive OK- mark. On the contrary, if the assignment is solved in elegant way, or somehow stands above the expected level of quality, the student will be marked with OK+. OK+ marks can erase the minus from OK- mark. In order to fulfil this requirement, the student has to have at least 5 OK marks, from which at least two are received for completing the homework on the topic of multi-threaded programming. The homeworks are graded individually. If you are unsure about your overall grading (e.g. you have quite a few OK-), contact your teacher for clarification.
Each extra OK mark above the count of 5 will give an extra 0.25 points for the exam.
Homeworks do not have a formal specification, but are rather vaguely described during the practicals. It is the student’s responsibility to understand the assignment by asking questions about the expected behavior during the practicals. The homeworks are to be submitted via the Study group roster in the SIS. It is necessary to upload whole assignment (i.e. just .cs files might not be enough, if the assignment also wants the student to set up a NuGet packages, etc.) as a ZIP archive. As opposed to the ReCodEx framework, the students will not receive an immediate feedback about the assignment, but rather will have to wait for the teacher to grade them.
Note: Homeworks are strictly individual.
2. Final Project
Deadlines:
- Specification: 15. 7. 2022
- Demonstration of the final (fully functional, according to the specification) version of the application, including both user and development documentation.
-
- deadline: 12. 8. 2022
-
- deadline: 9. 9. 2022
-
You can use single project to complete several courses about C# and .NET, if the project is complex enough:
- Requirements for NPRG035 + NPRG038:
- Demonstrated before the 1. deadline: 45kB of source code written in the C# language
- Demonstrated after the 1. deadline: 60kB of source code written in the C# language
- Demonstrated after the 2. deadline: 90kB of source code written in the C# language
SLOC (Source Lines of Code) is the code you (and only you) wrote in C# language. Comments are included, but everything has to be reasonable.
Final Project requires additional (nontrivial) usage of features and techniques taught on lectures/practicals of these courses (such as Multi-threaded programming, Networking, LINQ, Reflection, …).
Please prepare few slides (talk) about your application’s main features, problems you faced and overall design overview.
Acknowledgement of requirements from past years
If the student was enrolled in this course during the last academic year and fulfilled only some of the requirements for the credit, the teacher can, upon student’s request, acknowledge the fulfillment of requirement from the last year (attendance, homeworks, Practical Test or Final Project). The topic (specification) of Final Project does not need to be acknowledged by new teacher. If the student succeeded in the exam, but didn’t receive the credit, Pavel Ježek can, upon student’s request, acknowledge the result of the exam. This is a good will of teachers of this course and students can’t enforce this on study department!