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 objects = new List(); +objects.Add(1); +<<<<<<< Updated upstream +objects.Add("Hello"); +======= +objects.Add(2); + +int sum = 0; +foreach (object obj in objects) +{ + if (obj is int number) + { + sum += number; + } +} + +objects.Add("Hello"); // this will compile, but will cause a runtime error when we try to cast it to an int + +// We could also have specialized classes for each type we want to use: +// IntList +// StringList + +// But the framework would not have a buildin list for every type. +// Especially for our own custom types, we would have to create a new list class for each type we want to use. + + +// let start with creating our own generic methods + +T GetLastElement(List list) +{ + return list[list.Count - 1]; +} + +List namesList = new List {"Alice", "Bob", "Charlie"}; +string lastName = GetLastElement(namesList); + +List numbersList = new List {1, 2, 3, 4, 5}; +int lastNumber = GetLastElement(numbersList); + +// without Generics, we would have to create a separate method for each type we want to use: +string GetLastStringElement(List list) +{ + return list[list.Count - 1]; +} + +int GetLastIntElement(List list) +{ + return list[list.Count - 1]; +} + +// multiple generic parameters +(T2, T1) Swap(T1 item1, T2 item2) +{ + return (item2, item1); +} + +// Keep in mind that it you can make programs really type save +// Because it is generic you know inside the method nothing about the specific type. + +// If you want to do things you need to add constraints to the generic type parameters: + +int SumInts(T a, T b) +{ + // return a + b; // this will not compile because we don't know if T is an int or not + if (typeof(T) == typeof(int)) + { + return (int)(object)a + (int)(object)b; + } + else + { + throw new InvalidOperationException("T must be int"); + } +} + +T Sum(T a, T b) where T : INumber +{ + return a + b; +} + +T CreateObject() where T : new() +{ + return default(T); +} + +CreateObject(); + +bool useValidalidators(IEnumerable values) +{ + return values.FirstOrDefault().IsValid(""); +} + +useValidalidators(new List()); +>>>>>>> Stashed changes diff --git a/Week06/Template.zip b/Week06/Template.zip new file mode 100644 index 0000000..f3a70ca Binary files /dev/null and b/Week06/Template.zip differ diff --git a/Week06/Template/Template/Project/.vscode/launch.json b/Week06/Template/Template/Project/.vscode/launch.json new file mode 100644 index 0000000..9f1ca0a --- /dev/null +++ b/Week06/Template/Template/Project/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + "version": "0.2.0", + "configurations": [ + { + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/bin/Debug/net8.0/Project.dll", + "args": [], + "cwd": "${workspaceFolder}", + // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console + "console": "internalConsole", + "stopAtEntry": false + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach" + } + ] +} \ No newline at end of file diff --git a/Week06/Template/Template/Project/.vscode/settings.json b/Week06/Template/Template/Project/.vscode/settings.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/Week06/Template/Template/Project/.vscode/settings.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/Week06/Template/Template/Project/.vscode/tasks.json b/Week06/Template/Template/Project/.vscode/tasks.json new file mode 100644 index 0000000..4dc9d3f --- /dev/null +++ b/Week06/Template/Template/Project/.vscode/tasks.json @@ -0,0 +1,41 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/Project.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/Project.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "--project", + "${workspaceFolder}/Project.csproj" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/Week06/Template/Template/Project/DataAccess/AccountsAccess.cs b/Week06/Template/Template/Project/DataAccess/AccountsAccess.cs new file mode 100644 index 0000000..eaca8b4 --- /dev/null +++ b/Week06/Template/Template/Project/DataAccess/AccountsAccess.cs @@ -0,0 +1,38 @@ +using Microsoft.Data.Sqlite; + +using Dapper; + + +public class AccountsAccess +{ + private SqliteConnection _connection = new SqliteConnection($"Data Source=DataSources/project.db"); + + private string Table = "Accounts"; + + public void Write(AccountModel account) + { + string sql = $"INSERT INTO {Table} (email, password, fullname) VALUES (@EmailAddress, @Password, @FullName)"; + _connection.Execute(sql, account); + } + + public AccountModel GetByEmail(string email) + { + string sql = $"SELECT * FROM {Table} WHERE email = @Email"; + return _connection.QueryFirstOrDefault(sql, new { Email = email }); + } + + public void Update(AccountModel account) + { + string sql = $"UPDATE {Table} SET email = @EmailAddress, password = @Password, fullname = @FullName WHERE id = @Id"; + _connection.Execute(sql, account); + } + + public void Delete(AccountModel account) + { + string sql = $"DELETE FROM {Table} WHERE id = @Id"; + _connection.Execute(sql, new { Id = account.Id }); + } + + + +} \ No newline at end of file diff --git a/Week06/Template/Template/Project/DataModels/AccountModel.cs b/Week06/Template/Template/Project/DataModels/AccountModel.cs new file mode 100644 index 0000000..f9f5c74 --- /dev/null +++ b/Week06/Template/Template/Project/DataModels/AccountModel.cs @@ -0,0 +1,23 @@ +public class AccountModel +{ + + public long Id { get; set; } + public string EmailAddress { get; set; } + + public string Password { get; set; } + + public string FullName { get; set; } + + public AccountModel(long id, string email, string password, string fullname) + { + Id = id; + EmailAddress = email; + Password = password; + FullName = fullname; + } + + +} + + + diff --git a/Week06/Template/Template/Project/DataSources/project.db b/Week06/Template/Template/Project/DataSources/project.db new file mode 100644 index 0000000..ddece4a Binary files /dev/null and b/Week06/Template/Template/Project/DataSources/project.db differ diff --git a/Week06/Template/Template/Project/Logic/AccountsLogic.cs b/Week06/Template/Template/Project/Logic/AccountsLogic.cs new file mode 100644 index 0000000..5695d25 --- /dev/null +++ b/Week06/Template/Template/Project/Logic/AccountsLogic.cs @@ -0,0 +1,35 @@ + + +//This class is not static so later on we can use inheritance and interfaces +public class AccountsLogic +{ + + //Static properties are shared across all instances of the class + //This can be used to get the current logged in account from anywhere in the program + //private set, so this can only be set by the class itself + public static AccountModel? CurrentAccount { get; private set; } + private AccountsAccess _access = new(); + + public AccountsLogic() + { + // Could do something here + + } + + public AccountModel CheckLogin(string email, string password) + { + + + AccountModel acc = _access.GetByEmail(email); + if (acc != null && acc.Password == password) + { + CurrentAccount = acc; + return acc; + } + return null; + } +} + + + + diff --git a/Week06/Template/Template/Project/Presentation/Menu.cs b/Week06/Template/Template/Project/Presentation/Menu.cs new file mode 100644 index 0000000..c1f97ae --- /dev/null +++ b/Week06/Template/Template/Project/Presentation/Menu.cs @@ -0,0 +1,28 @@ +static class Menu +{ + + //This shows the menu. You can call back to this method to show the menu again + //after another presentation method is completed. + //You could edit this to show different menus depending on the user's role + static public void Start() + { + Console.WriteLine("Enter 1 to login"); + Console.WriteLine("Enter 2 to do something else in the future"); + + string input = Console.ReadLine(); + if (input == "1") + { + UserLogin.Start(); + } + else if (input == "2") + { + Console.WriteLine("This feature is not yet implemented"); + } + else + { + Console.WriteLine("Invalid input"); + Start(); + } + + } +} \ No newline at end of file diff --git a/Week06/Template/Template/Project/Presentation/UserLogin.cs b/Week06/Template/Template/Project/Presentation/UserLogin.cs new file mode 100644 index 0000000..c5fe0f6 --- /dev/null +++ b/Week06/Template/Template/Project/Presentation/UserLogin.cs @@ -0,0 +1,27 @@ +static class UserLogin +{ + static private AccountsLogic accountsLogic = new AccountsLogic(); + + + public static void Start() + { + Console.WriteLine("Welcome to the login page"); + Console.WriteLine("Please enter your email address"); + string email = Console.ReadLine(); + Console.WriteLine("Please enter your password"); + string password = Console.ReadLine(); + AccountModel acc = accountsLogic.CheckLogin(email, password); + if (acc != null) + { + Console.WriteLine("Welcome back " + acc.FullName); + Console.WriteLine("Your email number is " + acc.EmailAddress); + + //Write some code to go back to the menu + //Menu.Start(); + } + else + { + Console.WriteLine("No account found with that email and password"); + } + } +} \ No newline at end of file diff --git a/Week06/Template/Template/Project/Program.cs b/Week06/Template/Template/Project/Program.cs new file mode 100644 index 0000000..c5073de --- /dev/null +++ b/Week06/Template/Template/Project/Program.cs @@ -0,0 +1,3 @@ +// See https://aka.ms/new-console-template for more information +Console.WriteLine("Welcome to this amazing program"); +Menu.Start(); diff --git a/Week06/Template/Template/Project/Project.csproj b/Week06/Template/Template/Project/Project.csproj new file mode 100644 index 0000000..2154c49 --- /dev/null +++ b/Week06/Template/Template/Project/Project.csproj @@ -0,0 +1,22 @@ + + + + Exe + net8.0 + enable + enable + + + + + Always + + + + + + + + + + diff --git a/Week06/Template/Template/Template.sln b/Week06/Template/Template/Template.sln new file mode 100644 index 0000000..333d6e6 --- /dev/null +++ b/Week06/Template/Template/Template.sln @@ -0,0 +1,30 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Project", "Project\Project.csproj", "{7A5AFDA7-98E5-90C4-3164-A14884667405}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{6E2561A6-A9A0-8B76-749F-D9DB18D15A3F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7A5AFDA7-98E5-90C4-3164-A14884667405}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7A5AFDA7-98E5-90C4-3164-A14884667405}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7A5AFDA7-98E5-90C4-3164-A14884667405}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7A5AFDA7-98E5-90C4-3164-A14884667405}.Release|Any CPU.Build.0 = Release|Any CPU + {6E2561A6-A9A0-8B76-749F-D9DB18D15A3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6E2561A6-A9A0-8B76-749F-D9DB18D15A3F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6E2561A6-A9A0-8B76-749F-D9DB18D15A3F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6E2561A6-A9A0-8B76-749F-D9DB18D15A3F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E1F0F80F-E159-493A-843B-88589F5A3C9C} + EndGlobalSection +EndGlobal diff --git a/Week06/Template/Template/UnitTests/LoginTests.cs b/Week06/Template/Template/UnitTests/LoginTests.cs new file mode 100644 index 0000000..eafc65a --- /dev/null +++ b/Week06/Template/Template/UnitTests/LoginTests.cs @@ -0,0 +1,44 @@ +namespace UnitTests; + + + +[TestClass] +public sealed class Test1 +{ + + + [DataTestMethod] + [DataRow("kevin@kevin.nl", "kevin")] + public void LoginValidCredentials(string m, string p) + { + // arrange + AccountsLogic l = new(); + AccountsAccess access = new(); + + // act + AccountModel result = l.CheckLogin(m, p); + + // assert + Assert.IsNotNull(result); + Assert.AreEqual(m, result.EmailAddress); + Assert.AreEqual(p, result.Password); + } + + [DataTestMethod] + [DataRow("kevin@kevin.nl", "wrong")] // wrong password + [DataRow("wrong1", "kevin")] // wrong email + [DataRow("wrong2", "wrong")] // everything wrong + [DataRow("", "")] + [DataRow(null, null)] + public void LoginInvalidCredentials(string m, string p) + { + // arrange + AccountsLogic l = new(); + + // act + AccountModel result = l.CheckLogin(m, p); + + // assert + Assert.IsNull(result); + } +} diff --git a/Week06/Template/Template/UnitTests/MSTestSettings.cs b/Week06/Template/Template/UnitTests/MSTestSettings.cs new file mode 100644 index 0000000..eb4f469 --- /dev/null +++ b/Week06/Template/Template/UnitTests/MSTestSettings.cs @@ -0,0 +1 @@ +[assembly: DoNotParallelize] \ No newline at end of file diff --git a/Week06/Template/Template/UnitTests/UnitTests.csproj b/Week06/Template/Template/UnitTests/UnitTests.csproj new file mode 100644 index 0000000..7dff56e --- /dev/null +++ b/Week06/Template/Template/UnitTests/UnitTests.csproj @@ -0,0 +1,23 @@ + + + + net8.0 + latest + enable + enable + + + + + + + + + + + + + + + +