diff --git a/.github/classroom/autograding.json b/.github/classroom/autograding.json new file mode 100644 index 0000000..ebad661 --- /dev/null +++ b/.github/classroom/autograding.json @@ -0,0 +1,44 @@ +{ + "tests": [ + { + "name": "Test 1", + "setup": "", + "run": "dotnet test --filter TestCategory=1", + "input": "", + "output": "", + "comparison": "exact", + "timeout": 1, + "points": 3 + }, + { + "name": "Test 2", + "setup": "", + "run": "dotnet test --filter TestCategory=2", + "input": "", + "output": "", + "comparison": "exact", + "timeout": 1, + "points": 2 + }, + { + "name": "Test 3", + "setup": "", + "run": "dotnet test --filter TestCategory=3", + "input": "", + "output": "", + "comparison": "exact", + "timeout": 1, + "points": 3 + }, + { + "name": "Test 4", + "setup": "", + "run": "dotnet test --filter TestCategory=4", + "input": "", + "output": "", + "comparison": "exact", + "timeout": 1, + "points": 2 + } + ] +} diff --git a/.github/workflows/classroom.yml b/.github/workflows/classroom.yml new file mode 100644 index 0000000..a4dc534 --- /dev/null +++ b/.github/workflows/classroom.yml @@ -0,0 +1,19 @@ +name: GitHub Classroom Workflow + +on: + - push + - workflow_dispatch + +permissions: + checks: write + actions: read + contents: read + +jobs: + build: + name: Autograding + runs-on: ubuntu-latest + if: github.actor != 'github-classroom[bot]' && github.actor != 'sangkilc' + steps: + - uses: actions/checkout@v4 + - uses: education/autograding@v1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4eb29fe --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +[Dd]ebug/ +[Rr]elease/ +[Bb]in/ +[Oo]bj/ + +.vscode +.vs/ +.DS_Store diff --git a/Homework1.fsproj b/Homework1.fsproj new file mode 100644 index 0000000..5a3c697 --- /dev/null +++ b/Homework1.fsproj @@ -0,0 +1,12 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <OutputType>Exe</OutputType> + <TargetFramework>net8.0</TargetFramework> + </PropertyGroup> + + <ItemGroup> + <Compile Include="Program.fs" /> + </ItemGroup> + +</Project> diff --git a/Homework1.sln b/Homework1.sln new file mode 100644 index 0000000..8697e09 --- /dev/null +++ b/Homework1.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Homework1", "Homework1.fsproj", "{E719E6F5-32C4-4F65-842F-4DD030EAAB7C}" +EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Tests", "Tests\Tests.fsproj", "{2935EE11-D675-4545-BA6A-9DD6EF124B6B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E719E6F5-32C4-4F65-842F-4DD030EAAB7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E719E6F5-32C4-4F65-842F-4DD030EAAB7C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E719E6F5-32C4-4F65-842F-4DD030EAAB7C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E719E6F5-32C4-4F65-842F-4DD030EAAB7C}.Release|Any CPU.Build.0 = Release|Any CPU + {2935EE11-D675-4545-BA6A-9DD6EF124B6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2935EE11-D675-4545-BA6A-9DD6EF124B6B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2935EE11-D675-4545-BA6A-9DD6EF124B6B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2935EE11-D675-4545-BA6A-9DD6EF124B6B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/Program.fs b/Program.fs new file mode 100644 index 0000000..ed5e951 --- /dev/null +++ b/Program.fs @@ -0,0 +1,41 @@ +module CS220.Program + +/// Define a function `prob1` that takes in three (int) numbers as input and +/// returns the sum of the squares of the two large numbers. If there is any +/// error in processing the inputs, e.g., integer overflows, then the function +/// should simply return -1 (do not raise an exception). +let prob1 a b c = + failwith "TODO" + +/// Define a function `prob2` that takes in a string and returns a new string +/// that ends with a newline character '\n'. The function appends a newline +/// character to the given string only if the string does not already end with a +/// newline character. Note that a string in F# is indeed, an array of +/// characters, and each character in a string can be accessed through an item +/// accessor. For example, str[0] returns the first character of the string str. +/// Also, one can get the length of a string s by calling a function +/// String.length: String.length s returns the length of the string s. Finally, +/// you can append two strings using the + operator. +let prob2 (str: string) = + failwith "TODO" + +/// Write a function `prob3` that takes in as input three floating point numbers +/// a, b, and c, and returns a root of the quadratic formula $ax^2 + bx + c = +/// 0$. If there are two roots, then the function should return the bigger root. +/// If there is only one root, then the function should return the root. If +/// there are no real roots, then the function should return nan, which is a +/// special floating point number representing "Not a Number". +let prob3 a b c = + failwith "TODO" + +/// Define a function `prob4` that returns the number of days in a month. The +/// function takes in as input an integer representing a month, and outputs the +/// number of days. You can assume that February has 28 days. The function +/// returns -1 for any error cases. For example, if a number big than 12 is +/// given as input, then the function should return -1. +let prob4 month = + failwith "TODO" + +[<EntryPoint>] +let main _args = + 0 diff --git a/README.md b/README.md new file mode 100644 index 0000000..92ca532 --- /dev/null +++ b/README.md @@ -0,0 +1,85 @@ +CS220 - HW1 +=== + +## Build? + +You can compile the project by typing `dotnet build`. + +## Test? + +You can test your implementation by typing `dotnet test`. If you can pass +all the tests, you should be good to commit and push your code. + +## Structure + +- `Program.fs`: The main entry point of the project. +- `Tests/Tests.fs`: The test suite for the project. +- `HomeworkX.fsproj`: The F# project file for the project, where `X` is the + homework number. + +## Problems + +You should read the fsproj file and read the relevant source files to understand +the problems. Typically, we will provide an empty (or partial) implementation +for you to fill in where you can find some comments describing the problem. Of +course, you can also read the relevant test cases to understand the problem. + +## Submission + +You are given a GitHub classroom link to start the assignment, which will +automatically create a private repository for you. If your repository URL +contains your GitHub username, then you are in the right place. If not, please +get your own private repository from the GitHub classroom link. + +You should make modification to your own repository to finish your homework. +Again, your own repository is only visible to you and the course staff. Plus, +your repository URL should contain your GitHub username. You should commit and +push your code to your own repository in order to get a grade. + +Whenever you push your code to your repository, the GitHub classroom workflow +will automatically run the test cases and give you a grade based on the test +results. You can check the test results by clicking the "Actions" tab in your +repository page. + +If you see a red cross in the "Actions" tab, it means that some of the test +cases are failing. You should check the test results to understand why the test +cases are failing. If you see a green check, it means that all the test cases +are passing, and you should be good to go. + +You can always make another commit to fix problems in your implementation, and +push the changes to the repository. The GitHub classroom workflow will +re-evaluate your implementation and update your grade. + +## Failure from the Workflow? + +Don't panic if you see a red cross in the "Actions" tab. You can always make +another commit to fix problems in your implementation, and push the changes to +the repository. The GitHub classroom workflow will re-evaluate your +implementation and update your grade automatically. + +## Auto-Grading? + +Auto-grading is performed via the GitHub classroom workflow, which is defined in +`.github/workflows/classroom.yml`. The workflow basically runs `dotnet test` to +test your implementation and then gives you a grade based on the test results. +If you can pass all the tests in your local environment, you should be able to +get a full score. + +## Cheating Policy + +One may exploit the automatic grading system by hardcoding the expected result +in the test cases --- that is, one can simply add if-then-else statements in the +program to pass all the tests. But, we consider this attempt as cheating. + +If we detect any cheating attempt (including but not limited to the one above), +we will immediately give you an F grade for the course, and report the case to +the department. + +## Solutions? + +There is no single correct solution to the problems. You can always come up with +your own solution as long as it can pass the test cases. If you have any +questions about the problems, feel free to write an issue in the +[main](https://github.com/KAIST-CS220/CS220-Main) repository. But please do +search the existing issues to see if your question has already been answered +before writing a new one. \ No newline at end of file diff --git a/Tests/Program.fs b/Tests/Program.fs new file mode 100644 index 0000000..fdc31cd --- /dev/null +++ b/Tests/Program.fs @@ -0,0 +1 @@ +module Program = let [<EntryPoint>] main _ = 0 diff --git a/Tests/Tests.fs b/Tests/Tests.fs new file mode 100644 index 0000000..68fec71 --- /dev/null +++ b/Tests/Tests.fs @@ -0,0 +1,96 @@ +namespace CS220 + +open Microsoft.VisualStudio.TestTools.UnitTesting + +[<TestClass>] +type TestClass () = + + [<TestMethod; Timeout 1000; TestCategory "1">] + member __.``Probem 1.A``() = + let r = Program.prob1 1 2 2 + Assert.AreEqual (8, r) + + [<TestMethod; Timeout 1000; TestCategory "1">] + member __.``Probem 1.B``() = + let r = Program.prob1 10 1 20 + Assert.AreEqual (500, r) + + [<TestMethod; Timeout 1000; TestCategory "1">] + member __.``Probem 1.C``() = + let r = Program.prob1 -1 -1 -1 + Assert.AreEqual (2, r) + + [<TestMethod; Timeout 1000; TestCategory "1">] + member __.``Probem 1.D``() = + let r = Program.prob1 0x12345 1 2 + Assert.AreEqual (-1, r) + + [<TestMethod; Timeout 1000; TestCategory "1">] + member __.``Probem 1.E``() = + let r = Program.prob1 -0x12345 -0x123456 0x42 + Assert.AreEqual (-1, r) + + [<TestMethod; Timeout 1000; TestCategory "1">] + member __.``Probem 1.F``() = + let r = Program.prob1 0xa000 0xd000 0x8000 + Assert.AreEqual (-1, r) + + [<TestMethod; Timeout 1000; TestCategory "2">] + member __.``Probem 2.A``() = + let r = Program.prob2 "AAA" + Assert.AreEqual ("AAA\n", r) + + [<TestMethod; Timeout 1000; TestCategory "2">] + member __.``Probem 2.B``() = + let r = Program.prob2 "" + Assert.AreEqual ("\n", r) + + [<TestMethod; Timeout 1000; TestCategory "3">] + member __.``Probem 3.A``() = + let r = Program.prob3 1.0 0.0 0.0 + Assert.AreEqual (0.0, r) + + [<TestMethod; Timeout 1000; TestCategory "3">] + member __.``Probem 3.B``() = + let r = Program.prob3 1.1 1.1 1.1 + Assert.AreEqual (nan, r) + + [<TestMethod; Timeout 1000; TestCategory "3">] + member __.``Probem 3.C``() = + let r = Program.prob3 1.0 2.0 1.0 + Assert.AreEqual (-1.0, r, 0.0000001) + + [<TestMethod; Timeout 1000; TestCategory "3">] + member __.``Probem 3.D``() = + let r = Program.prob3 0.0 0.0 2.0 + Assert.AreEqual (nan, r) + + [<TestMethod; Timeout 1000; TestCategory "3">] + member __.``Probem 3.E``() = + let r = Program.prob3 nan nan nan + Assert.AreEqual (nan, r) + + [<TestMethod; Timeout 1000; TestCategory "4">] + member __.``Probem 4.A``() = + let r = Program.prob4 10 + Assert.AreEqual (31, r) + + [<TestMethod; Timeout 1000; TestCategory "4">] + member __.``Probem 4.B``() = + let r = Program.prob4 2 + Assert.AreEqual (28, r) + + [<TestMethod; Timeout 1000; TestCategory "4">] + member __.``Probem 4.C``() = + let r = Program.prob4 9 + Assert.AreEqual (30, r) + + [<TestMethod; Timeout 1000; TestCategory "4">] + member __.``Probem 4.D``() = + let r = Program.prob4 -1 + Assert.AreEqual (-1, r) + + [<TestMethod; Timeout 1000; TestCategory "4">] + member __.``Probem 4.E``() = + let r = Program.prob4 0 + Assert.AreEqual (-1, r) diff --git a/Tests/Tests.fsproj b/Tests/Tests.fsproj new file mode 100644 index 0000000..b3da832 --- /dev/null +++ b/Tests/Tests.fsproj @@ -0,0 +1,27 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>net8.0</TargetFramework> + + <IsPackable>false</IsPackable> + <GenerateProgramFile>false</GenerateProgramFile> + <IsTestProject>true</IsTestProject> + </PropertyGroup> + + <ItemGroup> + <Compile Include="Tests.fs" /> + <Compile Include="Program.fs" /> + </ItemGroup> + + <ItemGroup> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" /> + <PackageReference Include="MSTest.TestAdapter" Version="3.0.4" /> + <PackageReference Include="MSTest.TestFramework" Version="3.0.4" /> + <PackageReference Include="coverlet.collector" Version="6.0.0" /> + </ItemGroup> + + <ItemGroup> + <ProjectReference Include="..\Homework1.fsproj" /> + </ItemGroup> + +</Project>