From 89ad89186e15cc5b08df83bf6bde3c350c5b7989 Mon Sep 17 00:00:00 2001 From: khusainovilas Date: Mon, 27 Oct 2025 21:55:15 +0300 Subject: [PATCH 1/2] init proj --- HW5/HW5.sln | 16 +++++++ HW5/MyLinq/Linq.cs | 98 ++++++++++++++++++++++++++++++++++++++++ HW5/MyLinq/MyLinq.csproj | 21 +++++++++ HW5/MyLinq/stylecop.json | 9 ++++ 4 files changed, 144 insertions(+) create mode 100644 HW5/HW5.sln create mode 100644 HW5/MyLinq/Linq.cs create mode 100644 HW5/MyLinq/MyLinq.csproj create mode 100644 HW5/MyLinq/stylecop.json diff --git a/HW5/HW5.sln b/HW5/HW5.sln new file mode 100644 index 0000000..8f0ac9b --- /dev/null +++ b/HW5/HW5.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyLinq", "MyLinq\MyLinq.csproj", "{9E0833E5-8DE4-4505-BB56-7C17CFBB40E6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9E0833E5-8DE4-4505-BB56-7C17CFBB40E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9E0833E5-8DE4-4505-BB56-7C17CFBB40E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9E0833E5-8DE4-4505-BB56-7C17CFBB40E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9E0833E5-8DE4-4505-BB56-7C17CFBB40E6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/HW5/MyLinq/Linq.cs b/HW5/MyLinq/Linq.cs new file mode 100644 index 0000000..b485394 --- /dev/null +++ b/HW5/MyLinq/Linq.cs @@ -0,0 +1,98 @@ +// +// Copyright (c) khusainovilas. All rights reserved. +// + +namespace MyLinq; + +/// +/// methods for IEnumerable collections. +/// +public static class Linq +{ + /// + /// Generates an infinite lazy sequence of prime numbers. + /// + /// An IEnumerable of prime numbers. + public static IEnumerable GetPrimes() + { + yield return 2; + + var knownPrimes = new List { 2 }; + + long current = 3; + + while (true) + { + var isPrime = knownPrimes.TakeWhile(prime => prime * prime <= current).All(prime => current % prime != 0); + + if (isPrime) + { + yield return current; + knownPrimes.Add(current); + } + + checked + { + current += 2; + } + } + } + + /// + /// Extension method to take the first n elements from a sequence lazily. + /// + /// Type of elements in the sequence. + /// The source sequence. + /// Number of elements to take. + /// An IEnumerable with the first n elements. + public static IEnumerable Take(this IEnumerable sequence, int count) + { + ArgumentNullException.ThrowIfNull(sequence); + + switch (count) + { + case < 0: + throw new ArgumentOutOfRangeException(nameof(count), "Count cannot be negative."); + case 0: + yield break; + } + + var taken = 0; + foreach (var item in sequence) + { + yield return item; + taken++; + if (taken >= count) + { + yield break; + } + } + } + + /// + /// Extension method to skip the first n elements of a sequence lazily. + /// + /// Type of elements in the sequence. + /// The source sequence. + /// Number of elements to skip. + /// An IEnumerable without the first n elements. + public static IEnumerable Skip(this IEnumerable sequence, int count) + { + ArgumentNullException.ThrowIfNull(sequence); + + if (count < 0) + { + throw new ArgumentOutOfRangeException(nameof(count), "Count cannot be negative."); + } + + var skipped = 0; + foreach (var item in sequence) + { + skipped++; + if (skipped > count) + { + yield return item; + } + } + } +} \ No newline at end of file diff --git a/HW5/MyLinq/MyLinq.csproj b/HW5/MyLinq/MyLinq.csproj new file mode 100644 index 0000000..82fd482 --- /dev/null +++ b/HW5/MyLinq/MyLinq.csproj @@ -0,0 +1,21 @@ + + + + Library + net8.0 + enable + enable + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/HW5/MyLinq/stylecop.json b/HW5/MyLinq/stylecop.json new file mode 100644 index 0000000..76c8e76 --- /dev/null +++ b/HW5/MyLinq/stylecop.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", + "settings": { + "documentationRules": { + "companyName": "khusainovilas", + "copyrightText": "Copyright (c) {companyName}. All rights reserved." + } + } +} \ No newline at end of file From 4667a80f36440d986764f2e07155b03fa72af24b Mon Sep 17 00:00:00 2001 From: khusainovilas Date: Sun, 2 Nov 2025 17:23:20 +0300 Subject: [PATCH 2/2] add basic tests --- HW5/HW5.sln | 6 ++++ HW5/MyLinq.Test/MyLinq.Test.csproj | 39 +++++++++++++++++++++ HW5/MyLinq.Test/MyLinqTests.cs | 56 ++++++++++++++++++++++++++++++ HW5/MyLinq.Test/stylecop.json | 9 +++++ HW5/MyLinq/Linq.cs | 19 ++++++---- 5 files changed, 122 insertions(+), 7 deletions(-) create mode 100644 HW5/MyLinq.Test/MyLinq.Test.csproj create mode 100644 HW5/MyLinq.Test/MyLinqTests.cs create mode 100644 HW5/MyLinq.Test/stylecop.json diff --git a/HW5/HW5.sln b/HW5/HW5.sln index 8f0ac9b..53ef0d2 100644 --- a/HW5/HW5.sln +++ b/HW5/HW5.sln @@ -2,6 +2,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyLinq", "MyLinq\MyLinq.csproj", "{9E0833E5-8DE4-4505-BB56-7C17CFBB40E6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyLinq.Test", "MyLinq.Test\MyLinq.Test.csproj", "{A48D14A0-31F1-43A2-9A88-2FF814891FF3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -12,5 +14,9 @@ Global {9E0833E5-8DE4-4505-BB56-7C17CFBB40E6}.Debug|Any CPU.Build.0 = Debug|Any CPU {9E0833E5-8DE4-4505-BB56-7C17CFBB40E6}.Release|Any CPU.ActiveCfg = Release|Any CPU {9E0833E5-8DE4-4505-BB56-7C17CFBB40E6}.Release|Any CPU.Build.0 = Release|Any CPU + {A48D14A0-31F1-43A2-9A88-2FF814891FF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A48D14A0-31F1-43A2-9A88-2FF814891FF3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A48D14A0-31F1-43A2-9A88-2FF814891FF3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A48D14A0-31F1-43A2-9A88-2FF814891FF3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/HW5/MyLinq.Test/MyLinq.Test.csproj b/HW5/MyLinq.Test/MyLinq.Test.csproj new file mode 100644 index 0000000..3c981b2 --- /dev/null +++ b/HW5/MyLinq.Test/MyLinq.Test.csproj @@ -0,0 +1,39 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/HW5/MyLinq.Test/MyLinqTests.cs b/HW5/MyLinq.Test/MyLinqTests.cs new file mode 100644 index 0000000..63c66b7 --- /dev/null +++ b/HW5/MyLinq.Test/MyLinqTests.cs @@ -0,0 +1,56 @@ +// +// Copyright (c) khusainovilas. All rights reserved. +// + +namespace MyLinq.Test; + +/// +/// Unit tests for MyLinq. +/// +public class MyLinqTests +{ + /// + /// test method GetPrimes by taking first 5 numbers. + /// + [Test] + public void Linq_GetPrimes_FirstFiveNumbers() + => Assert.That(Linq.GetPrimes().Take(5), Is.EquivalentTo(new[] { 2L, 3L, 5L, 7L, 11L })); + + /// + /// test method Take by taking first 4 elements of char array. + /// + [Test] + public void Linq_Take_FirstFourElements() + => Assert.That(new[] { 'a', 'b', 'c', 'd', 'e', 'f' }.Take(4), Is.EquivalentTo(new[] { 'a', 'b', 'c', 'd' })); + + /// + /// test method Skip by skipping first 8 elements of char array. + /// + [Test] + public void Linq_Skip_SkipEightElements() + { + var text = "Hello, World!".ToCharArray(); + Assert.That(text.Skip(8), Is.EquivalentTo("orld!".ToCharArray())); + } + + /// + /// test method take and skip combination by getting 5 elements after skipping first 3 primes. + /// + [Test] + public void Linq_SkipAndTakeCombination() + => Assert.That(Linq.GetPrimes().Skip(3).Take(5), Is.EquivalentTo(new[] { 7L, 11L, 13L, 17L, 19L })); + + /// + /// test skip with negative count should return empty sequence. + /// + [Test] + public void Linq_Skip_NegativeCount() + => Assert.That(Linq.GetPrimes().Skip(-5), Is.Empty); + + /// + /// test take with negative count should return empty sequence. + /// + [Test] + public void Linq_Take_NegativeCount() + => Assert.That(Linq.GetPrimes().Take(-10), Is.Empty); +} \ No newline at end of file diff --git a/HW5/MyLinq.Test/stylecop.json b/HW5/MyLinq.Test/stylecop.json new file mode 100644 index 0000000..76c8e76 --- /dev/null +++ b/HW5/MyLinq.Test/stylecop.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", + "settings": { + "documentationRules": { + "companyName": "khusainovilas", + "copyrightText": "Copyright (c) {companyName}. All rights reserved." + } + } +} \ No newline at end of file diff --git a/HW5/MyLinq/Linq.cs b/HW5/MyLinq/Linq.cs index b485394..a62ad31 100644 --- a/HW5/MyLinq/Linq.cs +++ b/HW5/MyLinq/Linq.cs @@ -49,12 +49,9 @@ public static IEnumerable Take(this IEnumerable sequence, int count) { ArgumentNullException.ThrowIfNull(sequence); - switch (count) + if (count <= 0) { - case < 0: - throw new ArgumentOutOfRangeException(nameof(count), "Count cannot be negative."); - case 0: - yield break; + yield break; } var taken = 0; @@ -80,9 +77,17 @@ public static IEnumerable Skip(this IEnumerable sequence, int count) { ArgumentNullException.ThrowIfNull(sequence); - if (count < 0) + if (count <= 0) { - throw new ArgumentOutOfRangeException(nameof(count), "Count cannot be negative."); + if (count == 0) + { + foreach (var item in sequence) + { + yield return item; + } + } + + yield break; } var skipped = 0;