diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bc78471
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,484 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from `dotnet new gitignore`
+
+# dotenv files
+.env
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# Tye
+.tye/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.tlog
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio 6 auto-generated project file (contains which files were open etc.)
+*.vbp
+
+# Visual Studio 6 workspace and project file (working project files containing files to include in project)
+*.dsw
+*.dsp
+
+# Visual Studio 6 technical files
+*.ncb
+*.aps
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# Visual Studio History (VSHistory) files
+.vshistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
+
+# VS Code files for those working on multiple tools
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+*.code-workspace
+
+# Local History for Visual Studio Code
+.history/
+
+# Windows Installer files from build outputs
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# JetBrains Rider
+*.sln.iml
+.idea/
+
+##
+## Visual studio for Mac
+##
+
+
+# globs
+Makefile.in
+*.userprefs
+*.usertasks
+config.make
+config.status
+aclocal.m4
+install-sh
+autom4te.cache/
+*.tar.gz
+tarballs/
+test-results/
+
+# Mac bundle stuff
+*.dmg
+*.app
+
+# content below from: https://github.com/github/gitignore/blob/main/Global/macOS.gitignore
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+# content below from: https://github.com/github/gitignore/blob/main/Global/Windows.gitignore
+# Windows thumbnail cache files
+Thumbs.db
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# Vim temporary swap files
+*.swp
diff --git a/OODP2526.sln b/OODP2526.sln
new file mode 100644
index 0000000..f07fe71
--- /dev/null
+++ b/OODP2526.sln
@@ -0,0 +1,155 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.2.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Week01", "Week01", "{D4176A17-D7E5-9C19-FD5F-8803B1692ECF}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "les1", "Week01\les1\les1.csproj", "{F0D6C3B8-D7C4-466A-54D4-6EB613A629A3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "les2", "Week01\les2\les2.csproj", "{78CC799C-8B39-4DA7-8E93-5E43BB13C4CB}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Week02", "Week02", "{131C5CCE-C85E-81CF-EB9F-372398CDB723}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Les1", "Week02\Les1\Les1.csproj", "{D0064FAC-9A55-49AE-9C0A-59954D56B60D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Week04", "Week04", "{AE61C528-FF0A-A1A2-0584-FA705841A90E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Les1", "Week04\Les1\Les1.csproj", "{E5444152-49C6-4BFF-90C8-E1B8A3919723}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Les2", "Week04\Les2\Les2.csproj", "{E291036E-106F-4982-B82A-76D46642D400}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Week05", "Week05", "{1E7C7822-1A97-FCE8-C1CC-7282E8F41E48}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Les1", "Week05\Les1\Les1.csproj", "{36DD2085-3891-4CD4-9133-3524D1870482}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Les02", "Week05\Les02\Les02.csproj", "{B1F283DA-925D-4840-A523-4EED47AFC3F0}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Week06", "Week06", "{3DCF630A-C2F5-FA6C-1BC6-65B54CBF7084}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Les2", "Week06\Les2\Les2.csproj", "{7C3931E7-1BD5-4BCE-93F7-328D5FEED101}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F0D6C3B8-D7C4-466A-54D4-6EB613A629A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F0D6C3B8-D7C4-466A-54D4-6EB613A629A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F0D6C3B8-D7C4-466A-54D4-6EB613A629A3}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F0D6C3B8-D7C4-466A-54D4-6EB613A629A3}.Debug|x64.Build.0 = Debug|Any CPU
+ {F0D6C3B8-D7C4-466A-54D4-6EB613A629A3}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F0D6C3B8-D7C4-466A-54D4-6EB613A629A3}.Debug|x86.Build.0 = Debug|Any CPU
+ {F0D6C3B8-D7C4-466A-54D4-6EB613A629A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F0D6C3B8-D7C4-466A-54D4-6EB613A629A3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F0D6C3B8-D7C4-466A-54D4-6EB613A629A3}.Release|x64.ActiveCfg = Release|Any CPU
+ {F0D6C3B8-D7C4-466A-54D4-6EB613A629A3}.Release|x64.Build.0 = Release|Any CPU
+ {F0D6C3B8-D7C4-466A-54D4-6EB613A629A3}.Release|x86.ActiveCfg = Release|Any CPU
+ {F0D6C3B8-D7C4-466A-54D4-6EB613A629A3}.Release|x86.Build.0 = Release|Any CPU
+ {78CC799C-8B39-4DA7-8E93-5E43BB13C4CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {78CC799C-8B39-4DA7-8E93-5E43BB13C4CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {78CC799C-8B39-4DA7-8E93-5E43BB13C4CB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {78CC799C-8B39-4DA7-8E93-5E43BB13C4CB}.Debug|x64.Build.0 = Debug|Any CPU
+ {78CC799C-8B39-4DA7-8E93-5E43BB13C4CB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {78CC799C-8B39-4DA7-8E93-5E43BB13C4CB}.Debug|x86.Build.0 = Debug|Any CPU
+ {78CC799C-8B39-4DA7-8E93-5E43BB13C4CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {78CC799C-8B39-4DA7-8E93-5E43BB13C4CB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {78CC799C-8B39-4DA7-8E93-5E43BB13C4CB}.Release|x64.ActiveCfg = Release|Any CPU
+ {78CC799C-8B39-4DA7-8E93-5E43BB13C4CB}.Release|x64.Build.0 = Release|Any CPU
+ {78CC799C-8B39-4DA7-8E93-5E43BB13C4CB}.Release|x86.ActiveCfg = Release|Any CPU
+ {78CC799C-8B39-4DA7-8E93-5E43BB13C4CB}.Release|x86.Build.0 = Release|Any CPU
+ {D0064FAC-9A55-49AE-9C0A-59954D56B60D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D0064FAC-9A55-49AE-9C0A-59954D56B60D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D0064FAC-9A55-49AE-9C0A-59954D56B60D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D0064FAC-9A55-49AE-9C0A-59954D56B60D}.Debug|x64.Build.0 = Debug|Any CPU
+ {D0064FAC-9A55-49AE-9C0A-59954D56B60D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D0064FAC-9A55-49AE-9C0A-59954D56B60D}.Debug|x86.Build.0 = Debug|Any CPU
+ {D0064FAC-9A55-49AE-9C0A-59954D56B60D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D0064FAC-9A55-49AE-9C0A-59954D56B60D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D0064FAC-9A55-49AE-9C0A-59954D56B60D}.Release|x64.ActiveCfg = Release|Any CPU
+ {D0064FAC-9A55-49AE-9C0A-59954D56B60D}.Release|x64.Build.0 = Release|Any CPU
+ {D0064FAC-9A55-49AE-9C0A-59954D56B60D}.Release|x86.ActiveCfg = Release|Any CPU
+ {D0064FAC-9A55-49AE-9C0A-59954D56B60D}.Release|x86.Build.0 = Release|Any CPU
+ {E5444152-49C6-4BFF-90C8-E1B8A3919723}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E5444152-49C6-4BFF-90C8-E1B8A3919723}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E5444152-49C6-4BFF-90C8-E1B8A3919723}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E5444152-49C6-4BFF-90C8-E1B8A3919723}.Debug|x64.Build.0 = Debug|Any CPU
+ {E5444152-49C6-4BFF-90C8-E1B8A3919723}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E5444152-49C6-4BFF-90C8-E1B8A3919723}.Debug|x86.Build.0 = Debug|Any CPU
+ {E5444152-49C6-4BFF-90C8-E1B8A3919723}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E5444152-49C6-4BFF-90C8-E1B8A3919723}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E5444152-49C6-4BFF-90C8-E1B8A3919723}.Release|x64.ActiveCfg = Release|Any CPU
+ {E5444152-49C6-4BFF-90C8-E1B8A3919723}.Release|x64.Build.0 = Release|Any CPU
+ {E5444152-49C6-4BFF-90C8-E1B8A3919723}.Release|x86.ActiveCfg = Release|Any CPU
+ {E5444152-49C6-4BFF-90C8-E1B8A3919723}.Release|x86.Build.0 = Release|Any CPU
+ {E291036E-106F-4982-B82A-76D46642D400}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E291036E-106F-4982-B82A-76D46642D400}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E291036E-106F-4982-B82A-76D46642D400}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E291036E-106F-4982-B82A-76D46642D400}.Debug|x64.Build.0 = Debug|Any CPU
+ {E291036E-106F-4982-B82A-76D46642D400}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E291036E-106F-4982-B82A-76D46642D400}.Debug|x86.Build.0 = Debug|Any CPU
+ {E291036E-106F-4982-B82A-76D46642D400}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E291036E-106F-4982-B82A-76D46642D400}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E291036E-106F-4982-B82A-76D46642D400}.Release|x64.ActiveCfg = Release|Any CPU
+ {E291036E-106F-4982-B82A-76D46642D400}.Release|x64.Build.0 = Release|Any CPU
+ {E291036E-106F-4982-B82A-76D46642D400}.Release|x86.ActiveCfg = Release|Any CPU
+ {E291036E-106F-4982-B82A-76D46642D400}.Release|x86.Build.0 = Release|Any CPU
+ {36DD2085-3891-4CD4-9133-3524D1870482}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {36DD2085-3891-4CD4-9133-3524D1870482}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {36DD2085-3891-4CD4-9133-3524D1870482}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {36DD2085-3891-4CD4-9133-3524D1870482}.Debug|x64.Build.0 = Debug|Any CPU
+ {36DD2085-3891-4CD4-9133-3524D1870482}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {36DD2085-3891-4CD4-9133-3524D1870482}.Debug|x86.Build.0 = Debug|Any CPU
+ {36DD2085-3891-4CD4-9133-3524D1870482}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {36DD2085-3891-4CD4-9133-3524D1870482}.Release|Any CPU.Build.0 = Release|Any CPU
+ {36DD2085-3891-4CD4-9133-3524D1870482}.Release|x64.ActiveCfg = Release|Any CPU
+ {36DD2085-3891-4CD4-9133-3524D1870482}.Release|x64.Build.0 = Release|Any CPU
+ {36DD2085-3891-4CD4-9133-3524D1870482}.Release|x86.ActiveCfg = Release|Any CPU
+ {36DD2085-3891-4CD4-9133-3524D1870482}.Release|x86.Build.0 = Release|Any CPU
+ {B1F283DA-925D-4840-A523-4EED47AFC3F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B1F283DA-925D-4840-A523-4EED47AFC3F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B1F283DA-925D-4840-A523-4EED47AFC3F0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B1F283DA-925D-4840-A523-4EED47AFC3F0}.Debug|x64.Build.0 = Debug|Any CPU
+ {B1F283DA-925D-4840-A523-4EED47AFC3F0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B1F283DA-925D-4840-A523-4EED47AFC3F0}.Debug|x86.Build.0 = Debug|Any CPU
+ {B1F283DA-925D-4840-A523-4EED47AFC3F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B1F283DA-925D-4840-A523-4EED47AFC3F0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B1F283DA-925D-4840-A523-4EED47AFC3F0}.Release|x64.ActiveCfg = Release|Any CPU
+ {B1F283DA-925D-4840-A523-4EED47AFC3F0}.Release|x64.Build.0 = Release|Any CPU
+ {B1F283DA-925D-4840-A523-4EED47AFC3F0}.Release|x86.ActiveCfg = Release|Any CPU
+ {B1F283DA-925D-4840-A523-4EED47AFC3F0}.Release|x86.Build.0 = Release|Any CPU
+ {7C3931E7-1BD5-4BCE-93F7-328D5FEED101}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7C3931E7-1BD5-4BCE-93F7-328D5FEED101}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7C3931E7-1BD5-4BCE-93F7-328D5FEED101}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7C3931E7-1BD5-4BCE-93F7-328D5FEED101}.Debug|x64.Build.0 = Debug|Any CPU
+ {7C3931E7-1BD5-4BCE-93F7-328D5FEED101}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7C3931E7-1BD5-4BCE-93F7-328D5FEED101}.Debug|x86.Build.0 = Debug|Any CPU
+ {7C3931E7-1BD5-4BCE-93F7-328D5FEED101}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7C3931E7-1BD5-4BCE-93F7-328D5FEED101}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7C3931E7-1BD5-4BCE-93F7-328D5FEED101}.Release|x64.ActiveCfg = Release|Any CPU
+ {7C3931E7-1BD5-4BCE-93F7-328D5FEED101}.Release|x64.Build.0 = Release|Any CPU
+ {7C3931E7-1BD5-4BCE-93F7-328D5FEED101}.Release|x86.ActiveCfg = Release|Any CPU
+ {7C3931E7-1BD5-4BCE-93F7-328D5FEED101}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {F0D6C3B8-D7C4-466A-54D4-6EB613A629A3} = {D4176A17-D7E5-9C19-FD5F-8803B1692ECF}
+ {78CC799C-8B39-4DA7-8E93-5E43BB13C4CB} = {D4176A17-D7E5-9C19-FD5F-8803B1692ECF}
+ {D0064FAC-9A55-49AE-9C0A-59954D56B60D} = {131C5CCE-C85E-81CF-EB9F-372398CDB723}
+ {E5444152-49C6-4BFF-90C8-E1B8A3919723} = {AE61C528-FF0A-A1A2-0584-FA705841A90E}
+ {E291036E-106F-4982-B82A-76D46642D400} = {AE61C528-FF0A-A1A2-0584-FA705841A90E}
+ {36DD2085-3891-4CD4-9133-3524D1870482} = {1E7C7822-1A97-FCE8-C1CC-7282E8F41E48}
+ {B1F283DA-925D-4840-A523-4EED47AFC3F0} = {1E7C7822-1A97-FCE8-C1CC-7282E8F41E48}
+ {7C3931E7-1BD5-4BCE-93F7-328D5FEED101} = {3DCF630A-C2F5-FA6C-1BC6-65B54CBF7084}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {EA3191B1-F198-4728-A54F-AA6189439B3A}
+ EndGlobalSection
+EndGlobal
diff --git a/Week01/les1/Program.cs b/Week01/les1/Program.cs
new file mode 100644
index 0000000..b3d8750
--- /dev/null
+++ b/Week01/les1/Program.cs
@@ -0,0 +1,288 @@
+
+
+
+static class Program
+{
+ static void Main()
+ {
+ string klas = "BC11G";
+ int year = 1;
+ int semester = 2;
+
+ float minimumGrade = 5.5f;
+ double onTime = 0.99;
+
+ long longNumber = 238L;
+ bool passedBaseCamp = true;
+ char Initial = 'B';
+
+
+ klas = "INF1E";
+
+
+ // For now not advised.
+ // learn how to work with data types yourself
+ var number = 2;
+ //number = "hoi";
+
+ Comments(param1: "hoi");
+
+ Operators();
+
+ ConsoleInOutput();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ static void Comments(string param1)
+ {
+ // line comments. same as '#' in python
+
+ /*
+ block comments
+ */
+ }
+
+ static void Operators()
+ {
+ double f = 2.2;
+ int a = 5;
+ int b = (int)f;
+
+ // addition
+ int c = a + b;
+ // subtraction
+ c = a - b;
+
+ float aa = a;
+ // Be aware of integer division
+ float d = aa / b; // this will give 2, not 2.5.
+ // In python it is the // operator
+
+ // Shortcuts ++ -- (post/pre) += -= *= /=
+ int num = 1;
+ int num2 = num++; // post
+ int num3 = ++num; // pre
+ num += 10;
+ }
+
+ static void ConsoleInOutput()
+ {
+ Console.Write("Hello ");
+ Console.WriteLine("World");
+
+ Console.Write("What is your name? ");
+ string name = Console.ReadLine();
+ // string concatenation
+ Console.WriteLine("Hello " + name);
+ // string interpolation
+ Console.WriteLine($"Hello {name}");
+ string gradeString = $"Your grade is {6.5:f2}";// f2 means 2 decimal places
+ }
+
+ static void typeConversions()
+ {
+ int a = 5;
+ double b = a; // implicit conversion
+
+ double c = 5.5;
+ int d = (int)c; // explicit conversion, will truncate the decimal part
+
+
+ // Converting from string
+ int number1 = int.Parse("123");
+ double number2 = Convert.ToDouble("123.45");
+
+ if (int.TryParse("2", out int n))
+ {
+
+ }
+
+ long longNumber = 1234567890123456789L;
+ int shortNumber = (int)longNumber; // This will cause data loss, be careful!
+ }
+
+ static void ErrorsAndWarnings()
+ {
+ // warning for example unused variables
+ int unusedVariable = 0;
+
+ // runtime errors:
+ // int divisionByZero = 5 / 0; // This will throw a DivideByZeroException
+
+ // compile time errors:
+ // int invalidSyntax = 5 / ; // This will cause a compile-time error
+ // int typeMismatch = "hello"; // This will cause a compile-time error
+
+ // logical errors
+ int average = (1 + 2) * 2;
+ }
+
+ // Class Exercises: W01.1.T01 - W01.1.T03
+
+
+ // Part 2
+ static void part2()
+ {
+ StringMethods();
+ }
+
+ static void StringMethods()
+ {
+ string text = "Hello World";
+
+ // Length
+ int length = text.Length;
+
+ // ToUpper and ToLower
+ string upper = text.ToUpper();
+ string lower = text.ToLower();
+
+ // Substring
+ string sub = text.Substring(0, 5); // "Hello"
+
+ // Contains
+ bool containsWorld = text.Contains("World");
+
+ // Replace
+ string replaced = text.Replace("World", "C#");
+
+ // Trim
+ string padded = " Hello World ";
+ string trimmed = padded.Trim(); // "Hello World"
+
+ // string comparison
+ bool isEqual = text == "Hello World"; // true
+ bool isEqualIgnoreCase = text.Equals("hello world", StringComparison.OrdinalIgnoreCase);
+ }
+
+ static void comparisonOperators()
+ {
+ bool b1 = 5 <= 2;
+ bool b2 = 5 < 2;
+
+ bool b3 = "a" != "b";
+ }
+
+ static void logicalOperators()
+ {
+ bool b = !true; // not
+ b = true && true; // and
+ b = false || true; // or
+ }
+
+ static void ifElse()
+ {
+ int age = 17;
+ if (age >= 18)
+ {
+ Console.WriteLine("You can vote!");
+ string scopedResult = "My own scope";
+ }
+ else
+ {
+ Console.WriteLine($"You have to wait {18-age} years!");
+ age++;
+ }
+
+ //Console.WriteLine(scopedResult);
+
+ string canVote = age >= 18 ? "yes" : "no";
+
+ if (canVote == "yes")
+ {
+ Console.WriteLine("Welcome 18 March");
+ }
+ else if (canVote == "no")
+ {
+ Console.WriteLine("Probably soon :)");
+ }
+ else
+ {
+ Console.WriteLine("Sorry don't understand your answer");
+ }
+
+
+ }
+
+ // Class Exercises: W01.1.T04 - W01.1.T07
+ public static void SwitchStatementAndExpressions()
+ {
+ // What does the following code do?
+ Console.WriteLine("Enter a number");
+ int num1 = Convert.ToInt32(Console.ReadLine());
+ Console.WriteLine("Enter another number");
+ int num2 = Convert.ToInt32(Console.ReadLine());
+
+ Console.WriteLine("Enter a symbol");
+ string symbol = Console.ReadLine();
+
+ string result = $"{num1} {symbol} {num2} = ";
+
+
+ if (symbol == "+")
+ {
+ result += (num1 + num2);
+ }
+ else if (symbol == "-")
+ {
+ result += (num1 - num2);
+ }
+ else if (symbol == "*")
+ {
+ result += (num1 * num2);
+ }
+ else if (symbol == "/")
+ {
+ result += (num1 / num2);
+ }
+ else
+ {
+ result += "Operation not supported";
+ }
+ Console.WriteLine(result);
+
+ string result2 = $"{num1} {symbol} {num2} = ";
+ switch (symbol)
+ {
+ case "+":
+ result2 += (num1 + num2);
+ break;
+ case "-":
+ result2 += (num1 - num2);
+ break;
+ case "*":
+ result2 += (num1 * num2);
+ break;
+ case "/":
+ result2 += (num1 / num2);
+ break;
+ default:
+ result += "Operation not supported";
+ break;
+ }
+
+ string result3 = $"{num1} {symbol} {num2} = ";
+ result3 += symbol switch
+ {
+ "+" => num1 + num2,
+ "-" => num1 - num2,
+ "*" => num1 * num2,
+ "/" => num1 / num2,
+ _ => "Operation not supported"
+ };
+
+ int number = 42;
+ string description = number switch
+ {
+ <10 => "Lower than 10",
+ >= 10 and <= 15 => "between 10 and 15",
+ > 20 when number % 2 == 0 => "even above 20",
+ _ => "the rest"
+ };
+ }
+
+ // Class Exercises: W01.1.T08 - W.01.1.T09
+}
\ No newline at end of file
diff --git a/Week01/les1/les1.csproj b/Week01/les1/les1.csproj
new file mode 100644
index 0000000..ed9781c
--- /dev/null
+++ b/Week01/les1/les1.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
diff --git a/Week01/les2/Program.cs b/Week01/les2/Program.cs
new file mode 100644
index 0000000..bc4991b
--- /dev/null
+++ b/Week01/les2/Program.cs
@@ -0,0 +1,208 @@
+// loops.
+
+// what loops do we know from python?
+
+{
+ bool correctInput = false;
+ while (!correctInput)
+ {
+ Console.WriteLine("Enter a nickname:");
+ string input = Console.ReadLine();
+
+ if (input.Length > 4 && input[0] >= 'A' && input[0] <= 'Z')
+ {
+ correctInput = true;
+ Console.WriteLine("correct");
+ }
+ else
+ {
+ Console.WriteLine("Try again");
+ }
+ }
+}
+
+{
+ bool q = false;
+ do
+ {
+ Console.WriteLine("1) option 1");
+ Console.WriteLine("2) option 2");
+ Console.WriteLine("3) option 3");
+ Console.WriteLine("4) quit");
+
+ string choice = Console.ReadLine();
+ switch (choice)
+ {
+ case "1" or "2" or "3":
+ break;
+ case "4":
+ q = true;
+ break;
+ }
+ }
+ while(!q);
+}
+
+//for loop
+{
+ // for i in range(0, 10):
+ // print(i)
+ for (int i = 0; i < 10; i+=2)
+ {
+ Console.WriteLine(i);
+ }
+
+ // this is not common
+ foreach(int i in Enumerable.Range(0, 10))
+ {
+ Console.WriteLine(i);
+ }
+
+ // normally to iterate over a collection.
+ // for example a string
+ foreach(char letter in "Hello world")
+ {
+ char c = '\n'!;
+ Console.WriteLine(letter);
+ }
+
+ foreach(var word in "Hello world, hope you are doing fine".Split(" "))
+ {
+ Console.WriteLine(word);
+ }
+}
+
+
+// lists
+{
+ // List
+ List helloWorld = new List();
+ helloWorld.Add("Hello");
+ helloWorld.Add("world");
+
+ helloWorld = new List(){"Hello", "world"};
+ helloWorld = new (){"Hello", "world"};
+ helloWorld = ["Hello", "world"];
+
+ // amount of items, with count not with length.
+ // under the hood there is a fixed size array. This can be bigger than the amount of items.
+ int amountOfItems = helloWorld.Count;
+ // sneak peak in to later weeks. Use linq to count specific items.
+ helloWorld.Count(s => s.StartsWith("H"));
+
+ helloWorld.Remove("world");
+ helloWorld.RemoveAt(0);
+
+ helloWorld.Add("Hello");
+ helloWorld[0] = "Hello";
+
+ for (int i = 0; i < helloWorld.Count; i++)
+ {
+ Console.WriteLine(helloWorld[i]);
+ }
+
+ // better for simple cases.
+ foreach(string item in helloWorld)
+ {
+ Console.WriteLine(item);
+ }
+
+ // an exception is if you want to mutate the data.
+ // this is not aloud and possible in a foreach
+ for (int i = 0; i < helloWorld.Count; i++)
+ {
+ helloWorld[i] += " ";
+ }
+
+
+}
+
+// dictionaries
+{
+ //Dictionary
+ Dictionary Grades = new Dictionary();
+ Grades.Add("Jan", 7);
+ Grades.Add("Josefien", 9);
+
+ Grades = new (){
+ ["Jan"] = 7,
+ ["Jan"] = 6, // is overwriting the value
+ };
+
+ // old fashion
+ var capitals = new Dictionary
+ {
+ { "Nederland", "Amsterdam" },
+ { "België", "Brussel" },
+ { "Duitsland", "Berlijn" },
+ // { "Duitsland", "Berlijn" } will give runtime exception
+ };
+
+ capitals.Remove("Duitsland");
+ if (capitals.ContainsKey("Nederland"))
+ {
+ Console.WriteLine($"capital is {capitals["Nederland"]}");
+ }
+
+ Console.WriteLine($"capital is {capitals.GetValueOrDefault("Nederland", "Rotterdam")}");
+
+ if (capitals.TryGetValue("Nederland", out string capital))
+ {
+ Console.WriteLine($"capital is {capital}");
+ }
+
+ foreach (KeyValuePair item in capitals)
+ {
+ Console.WriteLine($"{item.Key}: {item.Value}");
+ }
+
+ foreach(var (country, city) in capitals)
+ {
+ Console.WriteLine($"{country}: {city}");
+ }
+
+ Dictionary> students = new ()
+ {
+
+ };
+}
+
+{
+ // Built-in classes: Random
+ // Creating a random object (Pseudorandom - uses system clock to generate)
+ Random randomGenerator = new Random();
+
+ // Next (int maxValue) int [0, maxValue)
+ int rNum1 = randomGenerator.Next(10);
+
+ // ext (int minValue, int maxValue) [minValue, maxValue)
+ int rNum2 = randomGenerator.Next(5, 10);
+
+ // NextDouble () (0.0, 1.0)
+ double rNum3 = randomGenerator.NextDouble();
+
+ // How to get a random double between 4 and 10?
+ // -> r * (max - min) + min
+ int min = 4;
+ int max = 10;
+ double rNum4 = (randomGenerator.NextDouble()) * (max - min) + min;
+ // 0.0 * 6 = 0.0 + 4 = 4.0 -> 0.9 * 6 = 5.4 + 4 = 9
+
+ // Reproducible sequence of random numbers - supply the seed
+ Random predictable1 = new Random(1);
+ Random predictable2 = new Random(1);
+
+ int p1n1 = predictable1.Next(10);
+ int p1n2 = predictable1.Next(10);
+
+ int p2n1 = predictable2.Next(10);
+ int p2n2 = predictable2.Next(10);
+
+ // Shortcut: new(), new(1)
+ Random r = new(); // instead of Random()
+ Random r1 = new(1); // instead of Random(1)
+}
+
+
+
+
diff --git a/Week01/les2/les2.csproj b/Week01/les2/les2.csproj
new file mode 100644
index 0000000..ed9781c
--- /dev/null
+++ b/Week01/les2/les2.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
diff --git a/Week02/Les1/Les1.csproj b/Week02/Les1/Les1.csproj
new file mode 100644
index 0000000..ed9781c
--- /dev/null
+++ b/Week02/Les1/Les1.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
diff --git a/Week02/Les1/Program.cs b/Week02/Les1/Program.cs
new file mode 100644
index 0000000..85dc3c4
--- /dev/null
+++ b/Week02/Les1/Program.cs
@@ -0,0 +1,36 @@
+
+public class Menu
+{
+ public Dictionary MenuItems = new ();
+ public Menu()
+ {
+
+ }
+
+ public bool HasMenuOptionAvailable(string key)
+ {
+ return MenuItems.ContainsKey(key);
+ }
+
+ // public string GetMenuItem(string key)
+ // {
+ // if (HasMenuOptionAvailable(key))
+ // {
+ // return MenuItems[key];
+ // }
+ // }
+
+ public void PrintMenu()
+ {
+ foreach(var item in this.MenuItems)
+ {
+ Console.WriteLine($"{item.Key}) {item.Value}");
+ }
+ }
+
+ public int AmountOfMenuItems() => MenuItems.Count;
+
+
+
+
+}
diff --git a/Week03/W03_2/Material/UnderstandingUsing.cs b/Week03/W03_2/Material/UnderstandingUsing.cs
index 19eab0a..90cf49e 100644
--- a/Week03/W03_2/Material/UnderstandingUsing.cs
+++ b/Week03/W03_2/Material/UnderstandingUsing.cs
@@ -59,6 +59,7 @@ to be written and closes the file properly.
{
System.Console.WriteLine("Could not write to file, exception: " + e);
}
+ // otherwise https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/exceptions/how-to-execute-cleanup-code-using-finally
}
public static bool IsValidPath(string path)
diff --git a/Week04/Les1/Circle.cs b/Week04/Les1/Circle.cs
new file mode 100644
index 0000000..8242f8e
--- /dev/null
+++ b/Week04/Les1/Circle.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace Les1;
+
+public class Circle
+{
+ public int Size;
+ public bool Filled = false;
+
+ public Circle()
+ {
+ this.Size = 1;
+ }
+
+ public Circle(int size)
+ {
+ this.Size = size;
+ }
+
+ public Circle(int size, bool filled)
+ : this(size)
+ {
+ this.Filled = filled;
+ }
+}
diff --git a/Week04/Les1/Les1.csproj b/Week04/Les1/Les1.csproj
new file mode 100644
index 0000000..ed9781c
--- /dev/null
+++ b/Week04/Les1/Les1.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
diff --git a/Week04/Les1/Program.cs b/Week04/Les1/Program.cs
new file mode 100644
index 0000000..51b711a
--- /dev/null
+++ b/Week04/Les1/Program.cs
@@ -0,0 +1,35 @@
+// See https://aka.ms/new-console-template for more information
+
+
+// We start with method overloading.
+// That is multiple methods with the same name but with different parameter signatures.
+// Have we seen this before
+
+// what is the type of print in python?
+
+// how can we solve this in C#
+// https://learn.microsoft.com/en-us/dotnet/api/system.console.writeline?view=net-10.0
+
+using Les1;
+
+void exampleMethodOverloadingInFramework()
+{
+ Console.WriteLine();
+ Console.WriteLine(0);
+ Console.WriteLine(0.0);
+ Console.WriteLine(true);
+ Console.WriteLine("test");
+ Console.WriteLine("With parameters {0}", 0);
+ Console.WriteLine("With two parameters {0} {1}", 0, 1);
+}
+
+
+Vehicle drone = new Vehicle(0);
+
+Bike bike = new Bike();
+
+Vehicle v = bike;
+bike = (Bike)v;
+
+bike.RingBell();
+
diff --git a/Week04/Les1/ShapeDrawer.cs b/Week04/Les1/ShapeDrawer.cs
new file mode 100644
index 0000000..df67219
--- /dev/null
+++ b/Week04/Les1/ShapeDrawer.cs
@@ -0,0 +1,60 @@
+using System;
+
+namespace Les1;
+
+public static class ShapeDrawer
+{
+ public static void DrawHorizontalLine()
+ => DrawHorizontalLine(20, "-");
+
+
+ public static void DrawHorizontalLine(int length)
+ {
+ for (int i = 0; i < length; i++)
+ {
+ Console.Write("-");
+ }
+ // next content on new line.
+ Console.WriteLine();
+ }
+
+ public static void DrawHorizontalLine(int length, string symbol)
+ {
+ for (int i = 0; i < length; i++)
+ {
+ Console.Write(symbol);
+ }
+ // next content on new line.
+ Console.WriteLine();
+ }
+
+ public static void DrawCircle(
+ double sizePercentage,
+ double positionLeftPercentage,
+ double positionTopPercentage,
+ string color,
+ bool filled
+ )
+ {
+ // implementation
+ }
+
+ public static void DrawCircle(
+ double sizePercentage,
+ double positionLeftPercentage,
+ double positionTopPercentage,
+ string color
+ )
+ {
+ DrawCircle(sizePercentage, positionLeftPercentage, positionTopPercentage, color, false);
+ }
+
+ public static void DrawCircle(
+ double sizePercentage,
+ double positionLeftPercentage,
+ double positionTopPercentage
+ )
+ {
+ DrawCircle(sizePercentage, positionLeftPercentage, positionTopPercentage, "black", false);
+ }
+}
diff --git a/Week04/Les1/Vehicle.cs b/Week04/Les1/Vehicle.cs
new file mode 100644
index 0000000..3739ab1
--- /dev/null
+++ b/Week04/Les1/Vehicle.cs
@@ -0,0 +1,54 @@
+using System;
+
+namespace Les1;
+
+public class Vehicle
+{
+ public readonly int PassengerCapacity;
+ public Vehicle(int passengerCapacity)
+ {
+ this.PassengerCapacity = passengerCapacity;
+ }
+}
+
+public class Bike : Vehicle
+{
+ public Bike(int passengerCapacity)
+ : base(passengerCapacity)
+ {
+
+ }
+
+ public Bike() : this(1)
+ {
+
+ }
+
+ public void RingBell()
+ {
+ Console.WriteLine("Ring Ring");
+ }
+}
+
+public class Tandem : Bike
+{
+ public Tandem() : base(2)
+ {
+
+ }
+
+ public void DoubleRingBell()
+ {
+ this.RingBell();
+ this.RingBell();
+ }
+}
+
+public class Car : Vehicle
+{
+ public readonly double HP;
+ public Car(int passengerCapacity, double HP) : base(passengerCapacity)
+ {
+ this.HP = HP;
+ }
+}
diff --git a/Week04/Les2/Les2.csproj b/Week04/Les2/Les2.csproj
new file mode 100644
index 0000000..ed9781c
--- /dev/null
+++ b/Week04/Les2/Les2.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
diff --git a/Week04/Les2/Person.cs b/Week04/Les2/Person.cs
new file mode 100644
index 0000000..5885930
--- /dev/null
+++ b/Week04/Les2/Person.cs
@@ -0,0 +1,16 @@
+
+
+public class Person
+{
+ public string Name;
+
+ public Person(string name)
+ {
+ this.Name = name;
+ }
+
+ public void SayHello()
+ {
+ Console.WriteLine($"Hello, I'm {this.Name}");
+ }
+}
\ No newline at end of file
diff --git a/Week04/Les2/Program.cs b/Week04/Les2/Program.cs
new file mode 100644
index 0000000..28884a2
--- /dev/null
+++ b/Week04/Les2/Program.cs
@@ -0,0 +1,78 @@
+
+using Les2;
+
+
+Vehicle v1 = new Vehicle(0);
+
+v1 = new Tandem();
+
+// error
+// v1.DoubleRingBell()
+((Tandem)v1).DoubleRingBell();
+(v1 as Tandem).DoubleRingBell();
+(v1 as Tandem)?.DoubleRingBell();
+
+if (v1 is Tandem t)
+{
+ t.DoubleRingBell();
+
+ // error: t = new Bike();
+ // allowed
+ Bike b = t;
+ b = (Bike)v1;
+
+}
+
+List myVehicles = new List()
+{
+ new Car(4, 100),
+ new Bike(2),
+ new Tandem(),
+};
+
+foreach(Vehicle v in myVehicles)
+{
+ // You only know it is a vehicle
+ if (v is Car)
+ {
+ Console.WriteLine(((Car)v).maxSpeed);
+ }
+
+ Console.WriteLine(v.Identify());
+}
+
+Vehicle bike = new Bike();
+Vehicle tandem = new Tandem();
+
+Console.WriteLine(bike.Identify());
+Console.WriteLine(tandem.Identify());
+
+
+// private vs public
+// access modifiers are saying something about who can do what.
+// private is the most restrictive and public is the most loose.
+
+// If something is private it can only be accessed from within the same class
+// If something is public it can be accessed everywhere.
+
+
+// go to class car
+Car c = new Car(4, 100);
+Person p = new Person("Jip");
+
+c.CalculateMaxSpeed();
+
+
+// The base of all objects is: `Object`
+
+object o = new Tandem();
+o.Equals(v1);
+o.GetHashCode();
+o.GetType();
+o.ToString();
+
+
+Console.WriteLine(o);
+
+
+
diff --git a/Week04/Les2/Vehicle.cs b/Week04/Les2/Vehicle.cs
new file mode 100644
index 0000000..489db2e
--- /dev/null
+++ b/Week04/Les2/Vehicle.cs
@@ -0,0 +1,80 @@
+using System;
+
+namespace Les2;
+
+public class Vehicle
+{
+ public readonly int PassengerCapacity;
+ public Vehicle(int passengerCapacity)
+ {
+ this.PassengerCapacity = passengerCapacity;
+ }
+
+ public virtual string Identify() => $"I'm a {nameof(Vehicle)}";
+}
+
+public class Bike : Vehicle
+{
+ public Bike(int passengerCapacity)
+ : base(passengerCapacity)
+ {
+
+ }
+
+ public Bike() : this(1)
+ {
+
+ }
+
+ public void RingBell()
+ {
+ Console.WriteLine("Ring Ring");
+ }
+}
+
+public class Tandem : Bike
+{
+ public Tandem() : base(2)
+ {
+
+ }
+
+ public void DoubleRingBell()
+ {
+ this.RingBell();
+ this.RingBell();
+ }
+
+ public override string Identify()=> $"I'm a {nameof(Tandem)}";
+
+ public override string ToString()
+ {
+ return this.Identify();
+ }
+}
+
+public class Car : Vehicle
+{
+ public readonly double HP;
+ public readonly double maxSpeed;
+
+ public Car(int passengerCapacity, double HP) : base(passengerCapacity)
+ {
+ this.HP = HP;
+ this.maxSpeed = this.CalculateMaxSpeed();
+ }
+
+ public double CalculateMaxSpeed()
+ {
+ // Base speed in km/h based on aerodynamic drag (cube root of HP)
+ double aeroSpeedKmh = 40 * Math.Pow(HP, 1.0 / 3.0);
+
+ // Minor penalty (2.5 km/h per person) for rolling resistance
+ double passengerPenalty = PassengerCapacity * 2.5;
+
+ // Calculate final speed, ensuring it doesn't drop below 0
+ double maxSpeedKmh = aeroSpeedKmh - passengerPenalty;
+
+ return Math.Max(0, Math.Round(maxSpeedKmh, 1));
+ }
+}
diff --git a/Week05/Les02/Les02.csproj b/Week05/Les02/Les02.csproj
new file mode 100644
index 0000000..ed9781c
--- /dev/null
+++ b/Week05/Les02/Les02.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
diff --git a/Week05/Les02/MultipleInheritance.cs b/Week05/Les02/MultipleInheritance.cs
new file mode 100644
index 0000000..eb67f6c
--- /dev/null
+++ b/Week05/Les02/MultipleInheritance.cs
@@ -0,0 +1,39 @@
+// See https://aka.ms/new-console-template for more information
+
+namespace MultipleInheritance;
+
+// multiple inheritance
+public class Printer
+{
+ public void TurnOn()
+ {
+ Console.WriteLine("Printer is on");
+ }
+
+ public void Print(string text)
+ {
+ Console.WriteLine(text);
+ }
+}
+
+public class Scanner
+{
+ public void TurnOn()
+ {
+ Console.WriteLine("Scanner is on");
+ }
+
+ public string Scan()
+ {
+ return Console.ReadLine();
+ }
+}
+
+// is niet toegestaan
+public class MultiFunctional: Printer, Scanner
+{
+
+}
+
+
+
diff --git a/Week05/Les02/Program.cs b/Week05/Les02/Program.cs
new file mode 100644
index 0000000..3529b06
--- /dev/null
+++ b/Week05/Les02/Program.cs
@@ -0,0 +1,43 @@
+
+
+
+// interfaces
+// classes implementing multiple interfaces
+// interfaces inheriting from other interfaces
+//
+
+// common interfaces in C#
+// IEnumerable
+// ICollection
+// IList
+// IDisposable
+
+IEnumerable numbers = new List {1, 2, 3, 4, 5};
+IList numbersList = new List {1, 2, 3, 4, 5};
+
+numbersList.Add(6);
+// numbers.Add(6); // this will not work
+// IEnumerable kan alleen maar de collectie lezen maar je weet niet wat de implementatie is.
+
+IEnumerable AllNumbers()
+{
+ for (int i = int.MinValue; i <= int.MaxValue; i++)
+ {
+ yield return i;
+ }
+}
+
+numbers = AllNumbers();
+
+
+
+// things de did not cover about interfaces
+// default implementations
+// static methods
+// static properties
+
+
+
+// volgende les
+// Abstract classes
+// abstract methods and properties
\ No newline at end of file
diff --git a/Week05/Les02/UseInterfaces.cs b/Week05/Les02/UseInterfaces.cs
new file mode 100644
index 0000000..424ce5b
--- /dev/null
+++ b/Week05/Les02/UseInterfaces.cs
@@ -0,0 +1,114 @@
+
+namespace Interfaces;
+
+public interface IDevice
+{
+ bool IsOn { get; }
+ void TurnOn();
+}
+
+public interface IPrinter : IDevice
+{
+ void Print(string text);
+}
+
+public interface IScanner : IDevice
+{
+ string Scan();
+}
+
+// multiple inheritance
+public class Printer : IPrinter
+{
+ public bool IsOn {get; private set;}
+
+ public void TurnOn()
+ {
+ this.IsOn = true;
+ Console.WriteLine("Printer is on");
+ }
+
+ public void Print(string text)
+ {
+ Console.WriteLine(text);
+ }
+}
+
+public class Scanner : IScanner
+{
+ public bool IsOn {get; private set;}
+
+ public void TurnOn()
+ {
+ this.IsOn = true;
+ Console.WriteLine("Scanner is on");
+ }
+
+ public string Scan()
+ {
+ return Console.ReadLine();
+ }
+
+ void IDevice.TurnOn()
+ {
+ this.IsOn = true;
+ Console.WriteLine("Scanner is on");
+ }
+}
+
+public class MultiFunctional : IPrinter, IScanner
+{
+ public bool IsOn {get; private set;}
+ public void Print(string text)
+ {
+ Console.WriteLine(text);
+ }
+
+ public string Scan()
+ {
+ return Console.ReadLine();
+ }
+
+ public void TurnOn()
+ {
+ this.IsOn = true;
+ Console.WriteLine("MultiFunctional is on");
+ }
+}
+
+public class SmartMultiFunctional : IPrinter, IScanner
+{
+ public bool IsOn => _printer.IsOn && _scanner.IsOn;
+ private readonly IPrinter _printer = new Printer();
+ private readonly IScanner _scanner = new Scanner();
+
+ public void Print(string text)
+ {
+ _printer.Print(text);
+ }
+
+ public string Scan()
+ {
+ return _scanner.Scan();
+ }
+
+ public void TurnOn()
+ {
+ _printer.TurnOn();
+ _scanner.TurnOn();
+ }
+
+}
+
+public class LazyMultiFunctional : IDevice
+{
+ public bool IsOn => Printer.IsOn && Scanner.IsOn;
+ public IPrinter Printer { get; } = new Printer();
+ public IScanner Scanner { get; } = new Scanner();
+
+ public void TurnOn()
+ {
+ Printer.TurnOn();
+ Scanner.TurnOn();
+ }
+}
\ No newline at end of file
diff --git a/Week05/Les02/Validator.cs b/Week05/Les02/Validator.cs
new file mode 100644
index 0000000..4c70281
--- /dev/null
+++ b/Week05/Les02/Validator.cs
@@ -0,0 +1,106 @@
+using System;
+
+namespace Les02;
+
+public interface IStringValidator
+{
+ bool IsValid(string value);
+
+ string GetErrorMessage();
+}
+
+public class NotEmptyStringValidator : IStringValidator
+{
+ public string GetErrorMessage()
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool IsValid(string value)
+ {
+ return !string.IsNullOrEmpty(value);
+ }
+}
+
+public class MaxLengthStringValidator : IStringValidator
+{
+ public int MaxLength { get; }
+
+ public MaxLengthStringValidator(int maxLength)
+ {
+ this.MaxLength = maxLength;
+ }
+
+ public bool IsValid(string value)
+ {
+ return value.Length <= this.MaxLength;
+ }
+
+ public string GetErrorMessage()
+ {
+ throw new NotImplementedException();
+ }
+}
+
+public class ContainsCharacterStringValidator : IStringValidator
+{
+ public char Character { get; }
+
+ public ContainsCharacterStringValidator(char character)
+ {
+ this.Character = character;
+ }
+
+ public bool IsValid(string value)
+ {
+ return value.Contains(this.Character);
+ }
+
+ public string GetErrorMessage()
+ {
+ throw new NotImplementedException();
+ }
+}
+
+public class AndStringValidator : IStringValidator
+{
+ public IEnumerable Validators { get; }
+ public AndStringValidator(IEnumerable validators)
+ {
+ this.Validators = validators;
+ }
+
+ public bool IsValid(string value)
+ {
+ foreach (IStringValidator validator in this.Validators)
+ {
+ if (!validator.IsValid(value))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public string GetErrorMessage()
+ {
+ throw new NotImplementedException();
+ }
+}
+
+public static class StringValidatorFactory
+{
+ public static IStringValidator EmailValidator => new AndStringValidator(new List
+ {
+ new NotEmptyStringValidator(),
+ new ContainsCharacterStringValidator('@'),
+ new ContainsCharacterStringValidator('.'),
+ new MaxLengthStringValidator(20),
+ });
+
+ public static IStringValidator UsernameValidator => new AndStringValidator(new List
+ {
+ new NotEmptyStringValidator(),
+ new MaxLengthStringValidator(15),
+ });
+}
diff --git a/Week05/Les1/Les1.csproj b/Week05/Les1/Les1.csproj
new file mode 100644
index 0000000..ed9781c
--- /dev/null
+++ b/Week05/Les1/Les1.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
diff --git a/Week05/Les1/Person.cs b/Week05/Les1/Person.cs
new file mode 100644
index 0000000..792946d
--- /dev/null
+++ b/Week05/Les1/Person.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Security.Cryptography;
+
+namespace Les1;
+
+public class Person
+{
+ protected string firstName = string.Empty;
+ protected string lastName = string.Empty;
+
+ public string FirstName
+ {
+ get => firstName;
+ set => firstName = value;
+ }
+
+ public string LastName
+ {
+ get { return lastName; }
+ set { lastName = value ?? throw new ArgumentNullException(); }
+ }
+
+ public int Age { get; private set; } = 0;
+
+ public string Gender
+ {
+ get;
+ set
+ {
+ field = value == "Male" || value == "Female"
+ ? value
+ : throw new ArgumentException("Invalid gender");
+ }
+ } = "Female";
+
+ public virtual string FullName => $"{this.FirstName} {this.LastName}";
+}
+
+public class RoyalPerson : Person
+{
+ public override string FullName => $"His/Her Royal Highness {base.FullName}";
+
+ public readonly int age;
+
+ public string Title { get; } = "Ridder";
+
+ public RoyalPerson()
+ {
+ age = 10;
+ Title = "King";
+ }
+
+ public void Hi()
+ {
+ this.firstName.ToUpper();
+ }
+}
diff --git a/Week05/Les1/Program.cs b/Week05/Les1/Program.cs
new file mode 100644
index 0000000..3751555
--- /dev/null
+++ b/Week05/Les1/Program.cs
@@ -0,0 +1,2 @@
+// See https://aka.ms/new-console-template for more information
+Console.WriteLine("Hello, World!");
diff --git a/Week05/testing/Banking.Tests/AccountTests.cs b/Week05/testing/Banking.Tests/AccountTests.cs
new file mode 100644
index 0000000..ec0e8de
--- /dev/null
+++ b/Week05/testing/Banking.Tests/AccountTests.cs
@@ -0,0 +1,96 @@
+using System;
+
+
+namespace Banking.Tests;
+
+[TestClass]
+public class AccountTests
+{
+ Account _account;
+
+ [TestInitialize]
+ public void Initialize()
+ {
+ _account = new Account();
+ }
+
+ [TestMethod]
+ public void Deposit_UpdatesBalance()
+ {
+ _account.Deposit(100);
+ Assert.AreEqual(100, _account.GetBalance());
+ }
+
+ [TestMethod]
+ public void Withdraw_UpdatesBalance()
+ {
+ _account.Deposit(100);
+ _account.Withdraw(50);
+ Assert.AreEqual(50, _account.GetBalance());
+ }
+
+ [TestMethod]
+ public void Withdraw_UpdatesBalance_WithNegativeAmount()
+ {
+ _account.Deposit(100);
+ _account.Withdraw(-50);
+ Assert.AreEqual(50, _account.GetBalance());
+ }
+
+ [TestMethod]
+ public void Withdraw_UpdatesBalance_NegativeBalance()
+ {
+ _account.Deposit(100);
+
+
+ Assert.ThrowsException(() => _account.Withdraw(150));
+
+
+ Assert.AreEqual(100, _account.GetBalance());
+ }
+
+ [TestMethod]
+ public void GetBalance_ReturnsZero()
+ {
+ Assert.AreEqual(0, _account.GetBalance());
+ }
+
+ // dit wil je voorkomen!
+ [TestMethod]
+ public void PrintWarningWhenNegativeBalance_ShouldNotPrintWarning_WhenBalanceIsPositive()
+ {
+ // Arrange
+ var account = new Account();
+ account.Deposit(100);
+
+ using (var sw = new StringWriter())
+ {
+ Console.SetOut(sw);
+
+ // Act
+ account.PrintWarningWhenNegativeBalance();
+
+ // Assert
+ var result = sw.ToString().Trim();
+ Assert.AreEqual(string.Empty, result);
+ }
+ }
+
+ [TestMethod]
+ [DataRow(100, 200, 50)]
+ [DataRow(500, 300, 100)]
+ [DataRow(1000, 500, 250)]
+ public void Transfer_ValidAmount_UpdatesBothAccounts(double initialSourceBalance, double initialTargetBalance, double transferAmount)
+ {
+ // Arrange
+ var sourceAccount = new Account { Transactions = new () {new Transaction (initialSourceBalance, true)} };
+ var targetAccount = new Account { Transactions = new () {new Transaction (initialTargetBalance, true)} };
+
+ // Act
+ sourceAccount.Transfer(transferAmount, targetAccount);
+
+ // Assert
+ Assert.AreEqual(initialSourceBalance - transferAmount, sourceAccount.GetBalance());
+ Assert.AreEqual(initialTargetBalance + transferAmount, targetAccount.GetBalance());
+ }
+}
\ No newline at end of file
diff --git a/Week05/testing/Banking.Tests/Banking.Tests.csproj b/Week05/testing/Banking.Tests/Banking.Tests.csproj
new file mode 100644
index 0000000..14a3af0
--- /dev/null
+++ b/Week05/testing/Banking.Tests/Banking.Tests.csproj
@@ -0,0 +1,22 @@
+
+
+
+ net10.0
+ latest
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week05/testing/Banking.Tests/MSTestSettings.cs b/Week05/testing/Banking.Tests/MSTestSettings.cs
new file mode 100644
index 0000000..aaf278c
--- /dev/null
+++ b/Week05/testing/Banking.Tests/MSTestSettings.cs
@@ -0,0 +1 @@
+[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)]
diff --git a/Week05/testing/Banking/Account.cs b/Week05/testing/Banking/Account.cs
new file mode 100644
index 0000000..39c25e3
--- /dev/null
+++ b/Week05/testing/Banking/Account.cs
@@ -0,0 +1,72 @@
+public class Account
+{
+ public List Transactions = new();
+
+ public void Deposit(double amount)
+ {
+ Transactions.Add(new Transaction(amount));
+ }
+
+ public void Withdraw(double amount)
+ {
+ if (amount < 0)
+ {
+ amount = Math.Abs(amount);
+ }
+
+ if (amount > GetBalance())
+ {
+ throw new InvalidOperationException("Insufficient funds");
+ }
+
+ Transactions.Add(new Transaction(amount, false));
+ }
+
+ public double GetBalance()
+ {
+ double balance = 0;
+ foreach (Transaction transaction in Transactions)
+ {
+ if (transaction.Credit)
+ {
+ balance += transaction.Amount;
+ }
+ else
+ {
+ balance -= transaction.Amount;
+ }
+ }
+ return balance;
+ }
+
+ public void PrintWarningWhenNegativeBalance()
+ {
+ if (GetBalance() < 0)
+ {
+ Console.WriteLine("Warning: Negative balance");
+ }
+ }
+ public void Transfer(double amount, Account destination)
+ {
+ if (amount > GetBalance())
+ {
+ throw new InvalidOperationException("Insufficient funds");
+ }
+
+ Withdraw(amount);
+ destination.Deposit(amount);
+ }
+
+}
+
+public class Transaction
+{
+ public double Amount;
+ public bool Credit;
+
+ public Transaction(double amount, bool credit = true)
+ {
+ this.Amount = amount;
+ this.Credit = credit;
+ }
+}
diff --git a/Week05/testing/Banking/Banking.csproj b/Week05/testing/Banking/Banking.csproj
new file mode 100644
index 0000000..ed9781c
--- /dev/null
+++ b/Week05/testing/Banking/Banking.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
diff --git a/Week05/testing/Banking/Program.cs b/Week05/testing/Banking/Program.cs
new file mode 100644
index 0000000..3751555
--- /dev/null
+++ b/Week05/testing/Banking/Program.cs
@@ -0,0 +1,2 @@
+// See https://aka.ms/new-console-template for more information
+Console.WriteLine("Hello, World!");
diff --git a/Week05/testing/testing.sln b/Week05/testing/testing.sln
new file mode 100644
index 0000000..62efae8
--- /dev/null
+++ b/Week05/testing/testing.sln
@@ -0,0 +1,48 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Banking", "Banking\Banking.csproj", "{B22D55EE-184D-44FB-966F-3B7785066BFE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Banking.Tests", "Banking.Tests\Banking.Tests.csproj", "{0063154E-1DD0-4E7C-9FAE-12BF7D108BE9}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B22D55EE-184D-44FB-966F-3B7785066BFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B22D55EE-184D-44FB-966F-3B7785066BFE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B22D55EE-184D-44FB-966F-3B7785066BFE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B22D55EE-184D-44FB-966F-3B7785066BFE}.Debug|x64.Build.0 = Debug|Any CPU
+ {B22D55EE-184D-44FB-966F-3B7785066BFE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B22D55EE-184D-44FB-966F-3B7785066BFE}.Debug|x86.Build.0 = Debug|Any CPU
+ {B22D55EE-184D-44FB-966F-3B7785066BFE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B22D55EE-184D-44FB-966F-3B7785066BFE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B22D55EE-184D-44FB-966F-3B7785066BFE}.Release|x64.ActiveCfg = Release|Any CPU
+ {B22D55EE-184D-44FB-966F-3B7785066BFE}.Release|x64.Build.0 = Release|Any CPU
+ {B22D55EE-184D-44FB-966F-3B7785066BFE}.Release|x86.ActiveCfg = Release|Any CPU
+ {B22D55EE-184D-44FB-966F-3B7785066BFE}.Release|x86.Build.0 = Release|Any CPU
+ {0063154E-1DD0-4E7C-9FAE-12BF7D108BE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0063154E-1DD0-4E7C-9FAE-12BF7D108BE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0063154E-1DD0-4E7C-9FAE-12BF7D108BE9}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0063154E-1DD0-4E7C-9FAE-12BF7D108BE9}.Debug|x64.Build.0 = Debug|Any CPU
+ {0063154E-1DD0-4E7C-9FAE-12BF7D108BE9}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0063154E-1DD0-4E7C-9FAE-12BF7D108BE9}.Debug|x86.Build.0 = Debug|Any CPU
+ {0063154E-1DD0-4E7C-9FAE-12BF7D108BE9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0063154E-1DD0-4E7C-9FAE-12BF7D108BE9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0063154E-1DD0-4E7C-9FAE-12BF7D108BE9}.Release|x64.ActiveCfg = Release|Any CPU
+ {0063154E-1DD0-4E7C-9FAE-12BF7D108BE9}.Release|x64.Build.0 = Release|Any CPU
+ {0063154E-1DD0-4E7C-9FAE-12BF7D108BE9}.Release|x86.ActiveCfg = Release|Any CPU
+ {0063154E-1DD0-4E7C-9FAE-12BF7D108BE9}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Week06/Les2/IValidator.cs b/Week06/Les2/IValidator.cs
new file mode 100644
index 0000000..42999ac
--- /dev/null
+++ b/Week06/Les2/IValidator.cs
@@ -0,0 +1,81 @@
+
+public interface IValidator
+{
+ public string ErrorExplanation { get; }
+ bool IsValid(T value);
+}
+
+public class EmailValidator : IValidator
+{
+ public string ErrorExplanation => "The value must be a valid email address.";
+
+ public bool IsValid(string value)
+ {
+ return value.Contains("@") && value.Contains(".");
+ }
+}
+
+public interface IStringValidator : IValidator
+{
+
+}
+
+public class PasswordValidator : IStringValidator
+{
+ public string ErrorExplanation => "The password must be at least 8 characters long and contain a number.";
+
+ public bool IsValid(string value)
+ {
+ return value.Length >= 8 && value.Any(char.IsDigit);
+ }
+}
+
+public class UsernameValidator : IStringValidator
+{
+ public string ErrorExplanation => "The username must be at least 5 characters long and contain only letters and numbers.";
+
+ public bool IsValid(string value)
+ {
+ return value.Length >= 5 && value.All(char.IsLetterOrDigit);
+ }
+}
+
+public interface IParseInput
+{
+ bool TryParse(string input, out T result);
+}
+
+public class ReadValueFromConsole
+{
+ public required IEnumerable> Validators { get; set; }
+ public required IParseInput Parser { get; set; }
+
+ public T GetValue()
+ {
+ T result = default;
+ bool valid = false;
+ while (!valid)
+ {
+ string input = Console.ReadLine();
+ if (Parser.TryParse(input, out result))
+ {
+ valid = false;
+ foreach (var validator in Validators)
+ {
+ if (!validator.IsValid(result))
+ {
+ Console.WriteLine(validator.ErrorExplanation);
+ valid = false;
+ break;
+ }
+ valid = true;
+ }
+ }
+ else
+ {
+ Console.WriteLine("Invalid input, try again");
+ }
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/Week06/Les2/Les2.csproj b/Week06/Les2/Les2.csproj
new file mode 100644
index 0000000..ed9781c
--- /dev/null
+++ b/Week06/Les2/Les2.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
diff --git a/Week06/Les2/LinkedList.cs b/Week06/Les2/LinkedList.cs
new file mode 100644
index 0000000..239b001
--- /dev/null
+++ b/Week06/Les2/LinkedList.cs
@@ -0,0 +1,14 @@
+
+public class LinkedListNode
+{
+ public T Value { get; set; }
+ public LinkedListNode? Next { get; set; }
+}
+
+// visual explanin linked list
+// [value | Next]
+// [value | Next]
+
+// [1 | Next]
+// [2 | Next]
+// null
\ No newline at end of file
diff --git a/Week06/Les2/Program.cs b/Week06/Les2/Program.cs
new file mode 100644
index 0000000..0e7efee
--- /dev/null
+++ b/Week06/Les2/Program.cs
@@ -0,0 +1,110 @@
+
+// Generics
+
+// A really powerful concept.
+// But also quite abstract and hard to understand at first.
+
+
+// Generic types we know already:
+
+using System.Numerics;
+
+List numbers = new List();
+List names = new List();
+List doubles = new ();
+Dictionary nameToAge = new Dictionary();
+
+// if we didn't have generics, we would have to do something like this:
+List