From 09eb0da6cd9f080e95a748d2f093a49a6397efbd Mon Sep 17 00:00:00 2001 From: "github-classroom[bot]" <66690702+github-classroom[bot]@users.noreply.github.com> Date: Sat, 16 Nov 2024 13:07:55 +0000 Subject: [PATCH] Initial commit --- .gitignore | 583 +++++++++++++++++++++++++++ Marathons.Test/MarathonTests.cs | 152 +++++++ Marathons.Test/Marathons.Test.csproj | 29 ++ Marathons.Test/ParticipantTests.cs | 54 +++ Marathons.sln | 31 ++ Marathons/Marathon.cs | 3 + Marathons/Marathons.csproj | 15 + Marathons/Participant.cs | 3 + Marathons/Program.cs | 24 ++ pics/sample_run.png | Bin 0 -> 37189 bytes readme.adoc | 120 ++++++ 11 files changed, 1014 insertions(+) create mode 100644 .gitignore create mode 100644 Marathons.Test/MarathonTests.cs create mode 100644 Marathons.Test/Marathons.Test.csproj create mode 100644 Marathons.Test/ParticipantTests.cs create mode 100644 Marathons.sln create mode 100644 Marathons/Marathon.cs create mode 100644 Marathons/Marathons.csproj create mode 100644 Marathons/Participant.cs create mode 100644 Marathons/Program.cs create mode 100644 pics/sample_run.png create mode 100644 readme.adoc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9209049 --- /dev/null +++ b/.gitignore @@ -0,0 +1,583 @@ +# Created by https://www.toptal.com/developers/gitignore/api/csharp,visualstudio +# Edit at https://www.toptal.com/developers/gitignore?templates=csharp,visualstudio + +### Csharp ### +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# 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 Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# 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 + +# 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 + +### VisualStudio ### + +# User-specific files + +# User-specific files (MonoDevelop/Xamarin Studio) + +# Mono auto generated files + +# Build results + +# Visual Studio 2015/2017 cache/options directory +# Uncomment if you have tasks that create the project's static files in wwwroot + +# Visual Studio 2017 auto generated files + +# MSTest test Results + +# NUnit + +# Build Results of an ATL Project + +# Benchmark Results + +# .NET Core + +# ASP.NET Scaffolding + +# StyleCop + +# Files built by Visual Studio + +# Chutzpah Test files + +# Visual C++ cache files + +# Visual Studio profiler + +# Visual Studio Trace Files + +# TFS 2012 Local Workspace + +# Guidance Automation Toolkit + +# ReSharper is a .NET coding add-in + +# TeamCity is a build add-in + +# DotCover is a Code Coverage Tool + +# AxoCover is a Code Coverage Tool + +# Coverlet is a free, cross platform Code Coverage Tool + +# Visual Studio code coverage results + +# NCrunch + +# MightyMoose + +# Web workbench (sass) + +# Installshield output folder + +# DocProject is a documentation generator add-in + +# Click-Once directory + +# Publish Web Output +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted + +# 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 + +# NuGet Packages +# NuGet Symbol Packages +# The packages folder can be ignored because of Package Restore +# except build/, which is used as an MSBuild target. +# Uncomment if necessary however generally it will be regenerated when needed +# NuGet v3's project.json files produces more ignorable files + +# Microsoft Azure Build Output + +# Microsoft Azure Emulator + +# Windows Store app package directories and files + +# Visual Studio cache files +# files ending in .cache can be ignored +# but keep track of directories ending in .cache + +# Others + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) + +# RIA/Silverlight projects + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) + +# SQL Server files + +# Business Intelligence projects + +# Microsoft Fakes + +# GhostDoc plugin setting file + +# Node.js Tools for Visual Studio + +# Visual Studio 6 build log + +# Visual Studio 6 workspace options file + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) + +# Visual Studio 6 technical files + +# Visual Studio LightSwitch build output + +# Paket dependency manager + +# FAKE - F# Make + +# CodeRush personal settings + +# Python Tools for Visual Studio (PTVS) + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio + +# Telerik's JustMock configuration file + +# BizTalk build output + +# OpenCover UI analysis results + +# Azure Stream Analytics local run output + +# MSBuild Binary and Structured Log + +# NVidia Nsight GPU debugger configuration file + +# MFractors (Xamarin productivity tool) working folder + +# Local History for Visual Studio + +# Visual Studio History (VSHistory) files + +# BeatPulse healthcheck temp database + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 + +# Ionide (cross platform F# VS Code tools) working folder + +# Fody - auto-generated XML schema + +# VS Code files for those working on multiple tools + +# Local History for Visual Studio Code + +# Windows Installer files from build outputs + +# JetBrains Rider + +### VisualStudio Patch ### +# Additional files built by Visual Studio + +# End of https://www.toptal.com/developers/gitignore/api/csharp,visualstudio \ No newline at end of file diff --git a/Marathons.Test/MarathonTests.cs b/Marathons.Test/MarathonTests.cs new file mode 100644 index 0000000..59d5824 --- /dev/null +++ b/Marathons.Test/MarathonTests.cs @@ -0,0 +1,152 @@ +using FluentAssertions; +using Xunit; + +namespace Marathons.Test; + +public sealed class MarathonTests +{ + [Fact] + public void Construction() + { + const string City = "Leonding"; + DateOnly date = new(2024, 11, 15); + + var m = new Marathon(City, date); + + (m.City, m.Date, m.ParticipantCount) + .Should().Be((City, date, 0), "no participants added so far"); + } + + [Fact] + public void AddParticipant_Single() + { + var m = CreateSampleMarathon(); + var participant = CreateSampleParticipants()[0]; + + // should not throw + m.AddParticipant(participant); + + m.ParticipantCount.Should().Be(1, "one participant added"); + } + + [Fact] + public void AddParticipant_Multiple() + { + var m = CreateSampleMarathon(); + var participants = CreateSampleParticipants(); + + foreach (var participant in participants) + { + m.AddParticipant(participant); + } + + m.ParticipantCount.Should().Be(participants.Length, "multiple participants added"); + } + + [Fact] + public void RemoveParticipant_Single() + { + var m = CreateSampleMarathon(); + var participant = CreateSampleParticipants()[0]; + + m.AddParticipant(participant); + m.RemoveParticipant(participant.StartNo) + .Should().BeTrue("previously added participant removed"); + m.ParticipantCount.Should().Be(0, "no participants remain"); + } + + [Fact] + public void RemoveParticipant_Empty() + { + var m = CreateSampleMarathon(); + var participant = CreateSampleParticipants()[0]; + + m.RemoveParticipant(participant.StartNo) + .Should().BeFalse("no participants added"); + } + + [Fact] + public void RemoveParticipant_NotExists() + { + var m = CreateSampleMarathon(); + var participant1 = CreateSampleParticipants()[1]; + var participant2 = CreateSampleParticipants()[2]; + + m.AddParticipant(participant1); + + m.RemoveParticipant(participant2.StartNo) + .Should().BeFalse("not in list"); + m.ParticipantCount.Should().Be(1, "one added participant still remains"); + } + + [Fact] + public void RemoveParticipant_Multiple() + { + var m = CreateSampleMarathon(); + var participants = CreateSampleParticipants(); + + foreach (var participant in participants) + { + m.AddParticipant(participant); + } + + m.RemoveParticipant(participants[2].StartNo) + .Should().BeTrue("was added previously and can now be removed"); + m.RemoveParticipant(participants[2].StartNo) + .Should().BeFalse("no longer in the list"); + m.ParticipantCount.Should().Be(4, "three remaining participants"); + } + + [Fact] + public void GetResultList_Empty() + { + var m = CreateSampleMarathon(); + + m.GetResultList() + .Should().NotBeNull() + .And.BeEmpty("no participants added") + .And.BeSameAs(Array.Empty()); + } + + [Fact] + public void GetResultList_Simple() + { + var m = CreateSampleMarathon(); + var participants = CreateSampleParticipants(); + + foreach (var participant in participants) + { + m.AddParticipant(participant); + } + m.RemoveParticipant(participants[1].StartNo); + + m.GetResultList().Should() + .NotBeNullOrEmpty() + .And.HaveCount(4, "one participant was removed again") + .And.ContainInOrder([ + "#01 Val (Start# 408) finished in 02:05:41", + "#02 Jeb (Start# 591) finished in 02:05:41", + "#03 Bob (Start# 167) finished in 03:34:18", + "#04 Wernher (Start# 008) finished in 05:25:41" + ], "insert in list has to happen in order!"); + } + + [Fact] + public void ToString_Simple() + { + var m = CreateSampleMarathon(); + + m.ToString().Should().Be("Leonding marathon on 15.11.2022"); + } + + private static Marathon CreateSampleMarathon() => new("Leonding", new DateOnly(2022, 11, 15)); + + private static Participant[] CreateSampleParticipants() => + [ + new(591, "Jeb", new TimeSpan(2, 05, 41)), + new(24, "Bill", new TimeSpan(4, 15, 23)), + new(167, "Bob", new TimeSpan(3, 34, 18)), + new(408, "Val", new TimeSpan(2, 05, 41)), + new(8, "Wernher", new TimeSpan(5, 25, 41)) + ]; +} \ No newline at end of file diff --git a/Marathons.Test/Marathons.Test.csproj b/Marathons.Test/Marathons.Test.csproj new file mode 100644 index 0000000..d110bb4 --- /dev/null +++ b/Marathons.Test/Marathons.Test.csproj @@ -0,0 +1,29 @@ + + + + net9.0 + enable + enable + true + false + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + \ No newline at end of file diff --git a/Marathons.Test/ParticipantTests.cs b/Marathons.Test/ParticipantTests.cs new file mode 100644 index 0000000..3ff9364 --- /dev/null +++ b/Marathons.Test/ParticipantTests.cs @@ -0,0 +1,54 @@ +using FluentAssertions; +using Xunit; + +namespace Marathons.Test; + +public sealed class ParticipantTests +{ + [Fact] + public void Construction() + { + const string Name = "Bob"; + const int StartNo = 11; + TimeSpan duration = new(02, 05, 04); + + var bob = new Participant(StartNo, Name, duration); + + (bob.Name, bob.StartNo, bob.CompletionTime).Should() + .Be((Name, StartNo, duration)); + } + + [Fact] + public void CompareTo_DifferentCompletionTime() + { + var bob = new Participant(10, "Bob", new TimeSpan(3, 4, 5)); + var val = new Participant(11, "Val", new TimeSpan(2, 4, 5)); + + bob.CompareTo(val) + .Should().Be(1, "Bob took longer for the run"); + val.CompareTo(bob) + .Should().Be(-1, "Val was faster"); + } + + [Fact] + public void CompareTo_SameCompletionTime() + { + // this case should normally not happen due to business rules, but we test behaviour anyway + + TimeSpan completionTime = new(3, 4, 5); + var bob = new Participant(10, "Bob", completionTime); + var val = new Participant(10, "Val", completionTime); + + bob.CompareTo(val) + .Should().Be(0, "same time and same start no") + .And.Be(val.CompareTo(bob), "True in both directions"); + } + + [Fact] + public void ToString_Simple() + { + var bob = new Participant(2, "Bob", new TimeSpan(15, 01, 12)); + + bob.ToString().Should().Be("Bob (Start# 002) finished in 15:01:12"); + } +} \ No newline at end of file diff --git a/Marathons.sln b/Marathons.sln new file mode 100644 index 0000000..d9feb08 --- /dev/null +++ b/Marathons.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33103.184 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marathons", "Marathons\Marathons.csproj", "{7F30E637-BAFE-42FA-A173-F42B3902ED3B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Marathons.Test", "Marathons.Test\Marathons.Test.csproj", "{161D9B2A-4E8B-43B6-A77E-40BED559521F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7F30E637-BAFE-42FA-A173-F42B3902ED3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7F30E637-BAFE-42FA-A173-F42B3902ED3B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7F30E637-BAFE-42FA-A173-F42B3902ED3B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7F30E637-BAFE-42FA-A173-F42B3902ED3B}.Release|Any CPU.Build.0 = Release|Any CPU + {161D9B2A-4E8B-43B6-A77E-40BED559521F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {161D9B2A-4E8B-43B6-A77E-40BED559521F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {161D9B2A-4E8B-43B6-A77E-40BED559521F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {161D9B2A-4E8B-43B6-A77E-40BED559521F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D322E690-379C-4802-8F7E-1AC6AD090D59} + EndGlobalSection +EndGlobal diff --git a/Marathons/Marathon.cs b/Marathons/Marathon.cs new file mode 100644 index 0000000..c666b2c --- /dev/null +++ b/Marathons/Marathon.cs @@ -0,0 +1,3 @@ +namespace Marathons; + +// TODO \ No newline at end of file diff --git a/Marathons/Marathons.csproj b/Marathons/Marathons.csproj new file mode 100644 index 0000000..2ee6e49 --- /dev/null +++ b/Marathons/Marathons.csproj @@ -0,0 +1,15 @@ + + + + Exe + net9.0 + enable + enable + true + + + + + + + \ No newline at end of file diff --git a/Marathons/Participant.cs b/Marathons/Participant.cs new file mode 100644 index 0000000..c666b2c --- /dev/null +++ b/Marathons/Participant.cs @@ -0,0 +1,3 @@ +namespace Marathons; + +// TODO \ No newline at end of file diff --git a/Marathons/Program.cs b/Marathons/Program.cs new file mode 100644 index 0000000..48757ed --- /dev/null +++ b/Marathons/Program.cs @@ -0,0 +1,24 @@ +using System.Text; +using Marathons; + +Console.OutputEncoding = Encoding.UTF8; + +Console.WriteLine("*** Marathon ***"); + +var p1 = new Participant(591, "Jeb", new TimeSpan(2, 05, 41)); +var p2 = new Participant(24, "Bill", new TimeSpan(4, 15, 23)); +var p3 = new Participant(167, "Bob", new TimeSpan(3, 34, 18)); +var p4 = new Participant(408, "Val", new TimeSpan(2, 05, 41)); +var marathon = new Marathon("Linz", new DateOnly(2024, 10, 30)); + +marathon.AddParticipant(p1); +marathon.AddParticipant(p2); +marathon.AddParticipant(p3); +marathon.AddParticipant(p4); +marathon.RemoveParticipant(p2.StartNo); + +Console.WriteLine($"Here are the results for {marathon}:"); +foreach (var resultLine in marathon.GetResultList()) +{ + Console.WriteLine(resultLine); +} \ No newline at end of file diff --git a/pics/sample_run.png b/pics/sample_run.png new file mode 100644 index 0000000000000000000000000000000000000000..b0032e495f90bd17b4ef77a6be4aa4743a5dc951 GIT binary patch literal 37189 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%0AZdGm?q;mAj7TZ{CpT7PxexCVniHn>+8grM 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 U7N+f!!NOendd9FkUB{sR0(Q_IB>(^b literal 0 HcmV?d00001 diff --git a/readme.adoc b/readme.adoc new file mode 100644 index 0000000..b7482fe --- /dev/null +++ b/readme.adoc @@ -0,0 +1,120 @@ +:sectnums: +:nofooter: +:toc: left +:icons: font +:data-uri: +:source-highlighter: highlightjs +:stem: latexmath + += Col.01 -- Marathon Results + +This time you will create an application which manages results of a marathon run and converts those individual results into an _ordered_ list. + +[plantuml,id=class_diagram] +---- +@startuml + +class Participant { + +int StartNo [readonly] + +string Name [readonly] + +TimeSpan CompletionTime [readonly] + + +Participant(int, string, TimeSpan) + +int CompareTo(Participant) + +string ToString() [override] +} + +class Marathon { + -Node? _head; + +string City [readonly] + +DateOnly Date [readonly] + +int ParticipantCount [private set] + + +Marathon(string, DateOnly) + +void AddParticipant(Participant) + +bool RemoveParticipant(int) + +string[] GetResultList() + +string ToString() [override] +} + +Participant "n"-r-"0..1" Marathon: participates + +@enduml +---- + +WARNING: As usual, you might have to initially comment some code to allow the application to compile. + +== `Participant` + +The participant is very simple and mostly just a data container. +Each instance represents one runner who completed the marathon (for simplicity we are not dealing with half-marathons and the like). + +The two interesting bits are: + +* `CompareTo` +** Compares two instances of the `Participant` class +** First completion times is compared, lower time means higher rank => comes earlier in the list +** If the completion time of two participants is the same compare the start number +*** Business rules dictate, that no two people can have the same start number +* `ToString` +** Has to follow the format ` (Start# ) finished in