From fbcd1ae592a592a3e0536bec926698463ecbb374 Mon Sep 17 00:00:00 2001 From: rvolosenkov Date: Fri, 7 May 2021 15:49:35 +0300 Subject: [PATCH 1/4] task01 --- .../01-primitive-types/Numbers/FloatNumbers.cs | 9 +++++---- .../01-primitive-types/Numbers/Integers.cs | 16 ++++++++-------- .../01-primitive-types/Numbers/Program.cs | 17 +++++++++++++++++ 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/course-2021-1/exercises/01-primitive-types/Numbers/FloatNumbers.cs b/course-2021-1/exercises/01-primitive-types/Numbers/FloatNumbers.cs index 9cb1d053..b8107575 100644 --- a/course-2021-1/exercises/01-primitive-types/Numbers/FloatNumbers.cs +++ b/course-2021-1/exercises/01-primitive-types/Numbers/FloatNumbers.cs @@ -17,7 +17,8 @@ internal static double GetNaN() Необходимо вернуть значение, не используя непосредственно саму константу. Для этого подумай, какой смысл в себе несет эта константа и где бы она могла стать результатом операции или вычисления функции. */ - throw new NotImplementedException(); + double zero = 0.0; + return 0 / zero; } /// @@ -28,20 +29,20 @@ internal static double GetNaN() internal static bool IsNaN(double d) { // Подсказка: по аналогии с константами типа int, у типа double тоже есть свой набор констант. - throw new NotImplementedException(); + return d.Equals(double.NaN); } /// /// Возвращает результат сравнения двух вещественнозначных чисел. /// /// -1 - первое меньше второго, 0 - значения равны, 1 - первое больше второго. - internal static int Compare(/* дополни сигнатуру метода как считаешь правильным */) + internal static int Compare(double x, double y, double eps) { /* Подумай, почему это задание дано в части про вещественнозначные числа. И почему не дана полная сигнатура метода. Если сходу идей нет, перестань искать подвох и просто реализуй дословно. Теперь еще раз посмотри на код и подумай в чем может быть проблема, сколько должно быть аргументов. */ - throw new NotImplementedException(); + return (Math.Abs(x - y) < eps ? 0 : x < y ? -1 : 1); } // и все?!! О_о diff --git a/course-2021-1/exercises/01-primitive-types/Numbers/Integers.cs b/course-2021-1/exercises/01-primitive-types/Numbers/Integers.cs index b1d90398..343d9f56 100644 --- a/course-2021-1/exercises/01-primitive-types/Numbers/Integers.cs +++ b/course-2021-1/exercises/01-primitive-types/Numbers/Integers.cs @@ -46,7 +46,7 @@ internal static int HalfIntMaxValue() Особенно это касается связки Visual Studio + Resharper, используя которую, если просто набрать return и нажать пробел, то в появившемся списке автодополнения одной из первых будет нужная тебе константа :) */ - throw new NotImplementedException(); + return int.MaxValue / 2; } /// @@ -55,7 +55,7 @@ internal static int HalfIntMaxValue() internal static int Cube(int x) { // не сомневайся, пиши. Тут без подвохов. - throw new NotImplementedException(); + return x * x * x; } /// @@ -67,7 +67,7 @@ internal static int CubeWithOverflowCheck(int x) Если спал на лекции, то тут придется погуглить, сорри. И заодно подумай какой режим выставлен по умолчанию. Почему. И почему категорически нельзя надеяться на режим по умолчанию. */ - throw new NotImplementedException(); + return checked(x * x * x); } /// @@ -76,7 +76,7 @@ И заодно подумай какой режим выставлен по у internal static int CubeWithoutOverflowCheck(int x) { // если сделал предыдущие, то с этим уже должно быть понятно. - throw new NotImplementedException(); + return unchecked(x * x * x); } /// @@ -93,7 +93,7 @@ internal static string ToString(int x) Подсказка: нужно воспользоваться методом, который есть у абсолютно всех объектов. */ - throw new NotImplementedException(); + return x.ToString(); } /// @@ -107,7 +107,7 @@ internal static int Parse(string s) Продолжай идти простым путем -нужен метод, обратный методу ToString выше, который распарсит дефолтное строковое представление числа. Подсказка: у каждого примитивного типа есть набор статических методов, среди которых есть нужный. */ - throw new NotImplementedException(); + return int.Parse(s); } /// @@ -119,7 +119,7 @@ internal static int TenTimes(int x) Реализуй умножение числа на 10 без использования арифметических операций над числами. Воспользуйся реализованными выше методами ToString и Parse. И не думай ни о каких переполнениях - задача не на это :) */ - throw new NotImplementedException(); + return Parse(ToString(x) + "0"); } /// @@ -133,7 +133,7 @@ internal static string ToHexString(int x) У метода ToString числовых типов есть перегрузка, которая принимает строку с одним из заданного набора форматов. В студии дается хорошая и понятная подсказка с этим набором форматов, в других же IDE скорее всего такого не будет, и придется погуглить форматы. */ - throw new NotImplementedException(); + return x.ToString("X"); } /* diff --git a/course-2021-1/exercises/01-primitive-types/Numbers/Program.cs b/course-2021-1/exercises/01-primitive-types/Numbers/Program.cs index 78460c01..cf196ded 100644 --- a/course-2021-1/exercises/01-primitive-types/Numbers/Program.cs +++ b/course-2021-1/exercises/01-primitive-types/Numbers/Program.cs @@ -19,6 +19,23 @@ private static void Main() // твои бро: Console.WriteLine и Console.ReadLine Console.WriteLine("Hello World!"); + Console.WriteLine(Numbers.Integers.HalfIntMaxValue()); + Console.WriteLine(Numbers.Integers.Cube(3)); + // Console.WriteLine(Numbers.Integers.CubeWithOverflowCheck(1234567891)); + // Console.WriteLine(Numbers.Integers.CubeWithoutOverflowCheck(1234567891)); + Console.WriteLine(Numbers.Integers.ToString(1234)); + Console.WriteLine(Numbers.Integers.Parse("38216283")); + Console.WriteLine(Numbers.Integers.TenTimes(54321)); + Console.WriteLine(Numbers.Integers.ToHexString(1234)); + Console.WriteLine(Numbers.FloatNumbers.GetNaN()); + Console.WriteLine(Numbers.FloatNumbers.IsNaN(Numbers.FloatNumbers.GetNaN())); + Console.WriteLine(Numbers.FloatNumbers.IsNaN(double.NaN)); + Console.WriteLine(Numbers.FloatNumbers.IsNaN(7.55)); + double x = 33.5321; + double y = 33.5320; + Console.WriteLine(Numbers.FloatNumbers.Compare(x, y, 0.001)); + Console.WriteLine(Numbers.FloatNumbers.Compare(x, y, 0.0001)); + Console.WriteLine(Numbers.FloatNumbers.Compare(y, x, 0.0001)); } } } From 082ed82bdb9ddbecfd616f453fcb0ce21266d1f1 Mon Sep 17 00:00:00 2001 From: rvolosenkov Date: Tue, 18 May 2021 21:34:22 +0300 Subject: [PATCH 2/4] task02 --- .../AdventureTime/AdventureTime/Program.cs | 67 ++++++++++++++++++- .../AdventureTime/AdventureTime/Time.cs | 44 +++++++----- 2 files changed, 92 insertions(+), 19 deletions(-) diff --git a/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/Program.cs b/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/Program.cs index af4efcae..99bd0c7e 100644 --- a/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/Program.cs +++ b/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/Program.cs @@ -1,9 +1,74 @@ -namespace AdventureTime +using System; + +namespace AdventureTime { internal class Program { private static void Main() { + Console.WriteLine(Time.WhatTimeIsIt()); + Console.WriteLine(Time.WhatTimeIsItInUtc()); + + Console.WriteLine(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Local)); + Console.WriteLine(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Utc)); + Console.WriteLine(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Unspecified)); + + Console.WriteLine(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Local).ToLocalTime()); + Console.WriteLine(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Utc).ToLocalTime()); + Console.WriteLine(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Unspecified).ToLocalTime()); + + Console.WriteLine(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Local).ToUniversalTime()); + Console.WriteLine(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Utc).ToUniversalTime()); + Console.WriteLine(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Unspecified).ToUniversalTime()); + + Console.WriteLine(Time.ToRoundTripFormatString(Time.WhatTimeIsIt())); + Console.WriteLine(Time.ToRoundTripFormatString(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Local))); + Console.WriteLine(Time.ToRoundTripFormatString(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Utc))); + Console.WriteLine(Time.ToRoundTripFormatString(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Unspecified))); + + Console.WriteLine(Time.ParseFromRoundTripFormat(Time.ToRoundTripFormatString(Time.WhatTimeIsIt()))); + Console.WriteLine(Time.ParseFromRoundTripFormat(Time.ToRoundTripFormatString(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Local)))); + Console.WriteLine(Time.ParseFromRoundTripFormat(Time.ToRoundTripFormatString(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Utc)))); + Console.WriteLine(Time.ParseFromRoundTripFormat(Time.ToRoundTripFormatString(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Unspecified)))); + + Console.WriteLine(Time.ToUtc(Time.WhatTimeIsIt())); + Console.WriteLine(Time.ToUtc(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Local))); + Console.WriteLine(Time.ToUtc(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Utc))); + Console.WriteLine(Time.ToUtc(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Unspecified))); + + Console.WriteLine(Time.AddTenSeconds(Time.WhatTimeIsIt())); + Console.WriteLine(Time.AddTenSeconds(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Local))); + Console.WriteLine(Time.AddTenSeconds(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Utc))); + Console.WriteLine(Time.AddTenSeconds(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Unspecified))); + + Console.WriteLine(Time.AddTenSecondsV2(Time.WhatTimeIsIt())); + Console.WriteLine(Time.AddTenSecondsV2(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Local))); + Console.WriteLine(Time.AddTenSecondsV2(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Utc))); + Console.WriteLine(Time.AddTenSecondsV2(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Unspecified))); + + Console.WriteLine(Time.GetHoursBetween(Time.WhatTimeIsIt(), new DateTime(2021, 5, 8, 10, 0, 0))); + Console.WriteLine(Time.GetHoursBetween(new DateTime(2021, 5, 8, 10, 0, 0), Time.WhatTimeIsIt())); + Console.WriteLine(Time.GetHoursBetween(Time.WhatTimeIsIt(), Time.WhatTimeIsIt())); + Console.WriteLine(Time.GetHoursBetween(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Local), Time.SpecifyKind(new DateTime(2021, 5, 8, 10, 0, 0), DateTimeKind.Local))); + Console.WriteLine(Time.GetHoursBetween(Time.SpecifyKind(new DateTime(2021, 5, 8, 10, 0, 0), DateTimeKind.Local), Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Local))); + Console.WriteLine(Time.GetHoursBetween(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Local), Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Local))); + Console.WriteLine(Time.GetHoursBetween(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Utc), Time.SpecifyKind(new DateTime(2021, 5, 8, 10, 0, 0), DateTimeKind.Utc))); + Console.WriteLine(Time.GetHoursBetween(Time.SpecifyKind(new DateTime(2021, 5, 8, 10, 0, 0), DateTimeKind.Utc), Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Utc))); + Console.WriteLine(Time.GetHoursBetween(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Utc), Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Utc))); + Console.WriteLine(Time.GetHoursBetween(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Unspecified), Time.SpecifyKind(new DateTime(2021, 5, 8, 10, 0, 0), DateTimeKind.Unspecified))); + Console.WriteLine(Time.GetHoursBetween(Time.SpecifyKind(new DateTime(2021, 5, 8, 10, 0, 0), DateTimeKind.Unspecified), Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Unspecified))); + Console.WriteLine(Time.GetHoursBetween(Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Unspecified), Time.SpecifyKind(Time.WhatTimeIsIt(), DateTimeKind.Unspecified))); + + Console.WriteLine(Time.GetTotalMinutesInThreeMonths()); + + Console.WriteLine(Time.AreEqualBirthdays(new DateTime(2000, 6, 7), new DateTime(1995, 3, 5))); + Console.WriteLine(Time.AreEqualBirthdays(new DateTime(1995, 3, 5), new DateTime(1995, 3, 5))); + + Console.WriteLine(Time.GetAdventureTimeDurationInMinutes_ver0_Dumb()); + Console.WriteLine(Time.GetGenderSwappedAdventureTimeDurationInMinutes_ver0_Dumb()); + Console.WriteLine(Time.GetAdventureTimeDurationInMinutes_ver1_FeelsSmarter()); + Console.WriteLine(Time.GetAdventureTimeDurationInMinutes_ver2_FeelsLikeRocketScience()); + Console.WriteLine(Time.GetGenderSwappedAdventureTimeDurationInMinutes_ver2_FeelsLikeRocketScience()); } } } diff --git a/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/Time.cs b/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/Time.cs index 45de70d1..a5217a3c 100644 --- a/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/Time.cs +++ b/course-2021-1/exercises/02-adventure-time/AdventureTime/AdventureTime/Time.cs @@ -14,15 +14,14 @@ internal static class Time /// public static DateTime WhatTimeIsIt() { - throw new NotImplementedException(); + return DateTime.Now; } - /// /// Возвращает текущее время в UTC. /// public static DateTime WhatTimeIsItInUtc() { - throw new NotImplementedException(); + return DateTime.UtcNow; } /// @@ -36,7 +35,7 @@ public static DateTime SpecifyKind(DateTime dt, DateTimeKind kind) /* Подсказка: поищи в статических методах DateTime. */ - throw new NotImplementedException(); + return DateTime.SpecifyKind(dt, kind); } /// @@ -51,7 +50,7 @@ Обязательно поиграйся и посмотри на измене Ну и на будущее запомни этот прекрасный строковый формат представления времени - он твой бро! Название запоминать не нужно, просто помни, что для передачи значения в виде строки, выбирать лучше инвариантные относительно сериализации/десериализации форматы. */ - throw new NotImplementedException(); + return dt.ToString("o"); } /// @@ -65,7 +64,7 @@ public static DateTime ParseFromRoundTripFormat(string dtStr) Поиграйся и проверь, что round-trip действительно round-trip, т.е. туда-обратно равно оригиналу (для туда воспользуйся предыдущим методом). Проверь для всех значений DateTime.Kind. */ - throw new NotImplementedException(); + return DateTime.Parse(dtStr, null, System.Globalization.DateTimeStyles.RoundtripKind); } /// @@ -77,7 +76,7 @@ public static DateTime ToUtc(DateTime dt) Eсли воспользуешься нужным методом, то напоминаю, что результат его работы зависит от dt.Kind. В случае dt.Kind == Unspecified предполагается, что время локальное, т.е. результат работы в случае Local и Unspecified совпадают. Такие дела */ - throw new NotImplementedException(); + return dt.ToUniversalTime(); } /// @@ -88,7 +87,7 @@ public static DateTime ToUtc(DateTime dt) public static DateTime AddTenSeconds(DateTime dt) { // здесь воспользуйся методами самого объекта и заодно посмотри какие еще похожие есть - throw new NotImplementedException(); + return dt.AddSeconds(10); } /// @@ -102,7 +101,7 @@ public static DateTime AddTenSecondsV2(DateTime dt) Ну а здесь воспользуйся сложением с TimeSpan. Обрати внимание, что помимо конструктора, у класса есть набор полезных статических методов-фабрик. Обрати внимание, что у TimeSpan нет статических методов FromMonth, FromYear. Как думаешь, почему? */ - throw new NotImplementedException(); + return dt + new TimeSpan(0, 0, 10); } /// @@ -118,7 +117,7 @@ public static int GetHoursBetween(DateTime dt1, DateTime dt2) 2) Проверь, учитывается ли Kind объектов при арифметических операциях. 3) Подумай, почему возвращаемое значение может отличаться от действительности. */ - throw new NotImplementedException(); + return (int)(DateTime.Compare(dt1, dt2) < 0 ? dt2.Subtract(dt1).TotalHours : dt1.Subtract(dt2).TotalHours); } /// @@ -127,7 +126,7 @@ public static int GetHoursBetween(DateTime dt1, DateTime dt2) public static int GetTotalMinutesInThreeMonths() { // ну тут все просто и очевидно, если сделал остальные и подумал над вопросами в комментах. - throw new NotImplementedException(); + return (int)(new TimeSpan(90, 0, 0, 0)).TotalMinutes; } #region Adventure time saga @@ -147,7 +146,9 @@ public static int GetAdventureTimeDurationInMinutes_ver0_Dumb() Держи, заготовочку для копипасты: - 2010, 3, 28, 2, 15, 0 */ - throw new NotImplementedException(); + DateTimeOffset londonTime = new DateTimeOffset(2010, 3, 28, 2, 15, 0, TimeSpan.FromHours(0)); + DateTimeOffset moscowTime = new DateTimeOffset(2010, 3, 28, 2, 15, 0, TimeSpan.FromHours(3)); + return (int)londonTime.Subtract(moscowTime).TotalMinutes; } /// @@ -165,7 +166,9 @@ public static int GetGenderSwappedAdventureTimeDurationInMinutes_ver0_Dumb() - 2010, 3, 28, 3, 15, 0 - 2010, 3, 28, 1, 15, 0 */ - throw new NotImplementedException(); + DateTimeOffset londonTime = new DateTimeOffset(2010, 3, 28, 1, 15, 0, TimeSpan.FromHours(0)); + DateTimeOffset moscowTime = new DateTimeOffset(2010, 3, 28, 3, 15, 0, TimeSpan.FromHours(3)); + return (int)londonTime.Subtract(moscowTime).TotalMinutes; } /// @@ -180,7 +183,9 @@ Внимательный читатель мог усомниться в дан На самом деле смещения таковы: Лондон +1 (BST - British Summer Time), Москва +4 (MSD - Moscow Daylight Time). Давай теперь учтем правильное смещение. Я понимаю, что это очевидно, что результат не изменится, но тебе же не сложно скопипастить и просто поменять смещения? */ - throw new NotImplementedException(); + DateTimeOffset londonTime = new DateTimeOffset(2010, 3, 28, 2, 15, 0, TimeSpan.FromHours(1)); + DateTimeOffset moscowTime = new DateTimeOffset(2010, 3, 28, 2, 15, 0, TimeSpan.FromHours(4)); + return (int)londonTime.Subtract(moscowTime).TotalMinutes; } // GetGenderSwappedAdventureTimeDurationInMinutes_ver1_FeelsSmarter опустим, там то же самое @@ -204,8 +209,9 @@ ниже ты найдешь готовый метод GetZonedTime. Прост */ const string moscowZoneId = "Russian Standard Time"; const string londonZoneId = "GMT Standard Time"; - - throw new NotImplementedException(); + DateTimeOffset londonTime = GetZonedTime(new DateTime(2010, 3, 28, 2, 15, 0), londonZoneId); + DateTimeOffset moscowTime = GetZonedTime(new DateTime(2010, 3, 28, 2, 15, 0), moscowZoneId); + return (int)londonTime.Subtract(moscowTime).TotalMinutes; } /// @@ -218,7 +224,9 @@ public static int GetGenderSwappedAdventureTimeDurationInMinutes_ver2_FeelsLikeR */ const string moscowZoneId = "Russian Standard Time"; const string londonZoneId = "GMT Standard Time"; - throw new NotImplementedException(); + DateTimeOffset londonTime = GetZonedTime(new DateTime(2010, 3, 28, 1, 15, 0), londonZoneId); + DateTimeOffset moscowTime = GetZonedTime(new DateTime(2010, 3, 28, 3, 15, 0), moscowZoneId); + return (int)londonTime.Subtract(moscowTime).TotalMinutes; } private static DateTimeOffset GetZonedTime(DateTime localTime, string timeZoneId) @@ -277,7 +285,7 @@ private static ZonedDateTime GetZonedTime(LocalDateTime localTime, string timeZo /// True - если родились в один день, иначе - false. internal static bool AreEqualBirthdays(DateTime person1Birthday, DateTime person2Birthday) { - throw new NotImplementedException(); + return DateTime.Equals(person1Birthday, person2Birthday); } } } From b508044d2c64bc573402401623ed2f3b1ec66fa4 Mon Sep 17 00:00:00 2001 From: rvolosenkov Date: Thu, 20 May 2021 09:19:35 +0300 Subject: [PATCH 3/4] task03 --- .../BoringVector.Tests/App.config | 6 + .../BoringVector.Tests/AssemblyInfo.fs | 41 +++++ .../BoringVector.Tests.fsproj | 84 ++++++++++ .../BoringVector.Tests/Program.fs | 7 + .../BoringVector.Tests/packages.config | 4 + .../BoringVector/BoringVector.sln | 10 +- .../BoringVector/BoringVector/Program.cs | 3 + .../BoringVector/BoringVector/Vector.cs | 156 +++++++++++++++++- .../BoringVector/VectorExtensions.cs | 68 +++++++- .../ConsoleApp1/BoringVector.Tests.csproj | 18 ++ .../BoringVector/ConsoleApp1/VectorTests.cs | 61 +++++++ 11 files changed, 450 insertions(+), 8 deletions(-) create mode 100644 course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/App.config create mode 100644 course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/AssemblyInfo.fs create mode 100644 course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/BoringVector.Tests.fsproj create mode 100644 course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/Program.fs create mode 100644 course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/packages.config create mode 100644 course-2021-1/exercises/03-boring-vector/BoringVector/ConsoleApp1/BoringVector.Tests.csproj create mode 100644 course-2021-1/exercises/03-boring-vector/BoringVector/ConsoleApp1/VectorTests.cs diff --git a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/App.config b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/App.config new file mode 100644 index 00000000..731f6de6 --- /dev/null +++ b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/AssemblyInfo.fs b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/AssemblyInfo.fs new file mode 100644 index 00000000..df8b7e92 --- /dev/null +++ b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/AssemblyInfo.fs @@ -0,0 +1,41 @@ +namespace BoringVector.Tests.AssemblyInfo + +open System.Reflection +open System.Runtime.CompilerServices +open System.Runtime.InteropServices + +// Общие сведения о сборке можно задать с помощью следующего +// набора атрибутов. Отредактируйте эти значения атрибутов, чтобы изменить сведения, +// связанные с этой сборкой. +[] +[] +[] +[] +[] +[] +[] +[] + +// При установке значения False в атрибуте ComVisible типы в этой сборке становятся невидимыми +// для COM-компонентов. Если требуется обратиться к типу в этой сборке через +// COM, задайте для атрибута ComVisible значение True для этого типа. +[] + +// Следующий GUID служит для идентификации библиотеки типов, если этот проект видим для COM +[] + +// Сведения о версии сборки состоят из следующих четырех значений: +// +// Основной номер версии +// Дополнительный номер версии +// Номер сборки +// Редакция +// +// Можно задать все значения или принять номера сборки и редакции по умолчанию +// используя "*", как показано ниже: +// [<сборка: AssemblyVersion("1.0.*")>] +[] +[] + +do + () \ No newline at end of file diff --git a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/BoringVector.Tests.fsproj b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/BoringVector.Tests.fsproj new file mode 100644 index 00000000..85b05bae --- /dev/null +++ b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/BoringVector.Tests.fsproj @@ -0,0 +1,84 @@ + + + + + Debug + AnyCPU + 2.0 + b55e87d0-2902-4167-8936-12ca376adf55 + Exe + BoringVector.Tests + BoringVector.Tests + v4.6.1 + true + 4.4.1.0 + BoringVector.Tests + + + true + full + false + false + bin\$(Configuration)\ + DEBUG;TRACE + 3 + AnyCPU + bin\$(Configuration)\$(AssemblyName).XML + true + + + pdbonly + true + true + bin\$(Configuration)\ + TRACE + 3 + AnyCPU + bin\$(Configuration)\$(AssemblyName).XML + true + + + 11 + + + + + $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets + + + + + + + + + + + + + + FSharp.Core + FSharp.Core.dll + $(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\$(TargetFSharpCoreVersion)\FSharp.Core.dll + + + + + + ..\packages\System.ValueTuple.4.3.1\lib\netstandard1.0\System.ValueTuple.dll + True + + + + \ No newline at end of file diff --git a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/Program.fs b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/Program.fs new file mode 100644 index 00000000..35c47dcb --- /dev/null +++ b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/Program.fs @@ -0,0 +1,7 @@ +// Дополнительные сведения о F# см. на http://fsharp.org +// Дополнительную справку см. в проекте "Учебник по F#". + +[] +let main argv = + printfn "%A" argv + 0 // возвращение целочисленного кода выхода diff --git a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/packages.config b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/packages.config new file mode 100644 index 00000000..9958f16f --- /dev/null +++ b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.sln b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.sln index ef06cdd5..f0c2834e 100644 --- a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.sln +++ b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.sln @@ -1,9 +1,11 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.27004.2002 +VisualStudioVersion = 15.0.27004.2010 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BoringVector", "BoringVector\BoringVector.csproj", "{7B438112-6A12-47BC-B494-FF8850924783}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BoringVector", "BoringVector\BoringVector.csproj", "{7B438112-6A12-47BC-B494-FF8850924783}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BoringVector.Tests", "ConsoleApp1\BoringVector.Tests.csproj", "{6CBC1AA9-3409-4FB6-9A31-49F7BC63254A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -15,6 +17,10 @@ Global {7B438112-6A12-47BC-B494-FF8850924783}.Debug|Any CPU.Build.0 = Debug|Any CPU {7B438112-6A12-47BC-B494-FF8850924783}.Release|Any CPU.ActiveCfg = Release|Any CPU {7B438112-6A12-47BC-B494-FF8850924783}.Release|Any CPU.Build.0 = Release|Any CPU + {6CBC1AA9-3409-4FB6-9A31-49F7BC63254A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6CBC1AA9-3409-4FB6-9A31-49F7BC63254A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6CBC1AA9-3409-4FB6-9A31-49F7BC63254A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6CBC1AA9-3409-4FB6-9A31-49F7BC63254A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/Program.cs b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/Program.cs index f5873162..5c94dfd1 100644 --- a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/Program.cs +++ b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/Program.cs @@ -1,4 +1,7 @@ using System; +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("BoringVector.Tests")] namespace BoringVector { diff --git a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/Vector.cs b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/Vector.cs index bb9db585..3aa3a076 100644 --- a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/Vector.cs +++ b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/Vector.cs @@ -8,12 +8,38 @@ namespace BoringVector Реализуй структуру Vector - см. комментарии внутри нее. */ + /// + /// Структура двумерного вектора: пара вещественных координат и методы для выполнения элементарных операций над векторами + /// internal struct Vector { /* Vector задается парой вещественных координат X и Y. */ + public double X; + public double Y; + + /// + /// Конструирует вектор из двух заданных вещественных координат. + /// + /// Значение типа , задающее координату по оси абсцисс. + /// Значение типа , задающее координату по оси ординат. + public Vector(double x, double y) + { + X = x; + Y = y; + } + + /// + /// Конструирует вектор из другого вектора. + /// + /// Объект типа , задающий вектор-образец. + public Vector(Vector v) + { + X = v.X; + Y = v.Y; + } /* На месте заглушек добавь реализацию базовых методов вектора: @@ -24,31 +50,72 @@ Vector задается парой вещественных координат X - векторное произведение (= площадь параллелограмма) */ + /// + /// Подсчитывает квадрат длины текущего вектора. + /// + /// Число типа , равное квадрату длины данного вектора. public double SquareLength() { - throw new NotImplementedException(); + return X * X + Y * Y; } + + /// + /// Прибавляет к текущему вектору другой вектор. + /// + /// Объект типа , который задает прибавляемый вектор. + /// Текущий объект (типа ) с модифицированными координатами. public Vector Add(Vector v) { - throw new NotImplementedException(); + X += v.X; + Y += v.Y; + return this; } + + /// + /// Умножает текущий вектор на заданное число. + /// + /// Значение типа , задающее числовой множитель. + /// Текущий объект (типа ) с модифицированными координатами. public Vector Scale(double k) { - throw new NotImplementedException(); + X *= k; + Y *= k; + return this; } + + /// + /// Вычисляет скалярное произведение текущего вектора с другим. + /// + /// Объект , задающий вектор-множитель. + /// Число типа , равное скалярному произведению двух заданных векторов. public double DotProduct(Vector v) { - throw new NotImplementedException(); + return X * v.X + Y * v.Y; } + + /// + /// Вычисляет модуль векторного произведения текущего вектора с другим. + /// + /// Объект , задающий вектор-множитель. + /// Число типа , равное модулю векторного произведения двух заданных векторов (площади параллелограмма, построенного на них). public double CrossProduct(Vector v) { - throw new NotImplementedException(); + return Math.Abs(X * v.Y - Y * v.X); } /* Переопредели ниже метод ToString - пусть выводит (X; Y) */ + /// + /// Возвращает строковое представление вектора. + /// + /// Строковое представление вектора (тип ). + public override string ToString() + { + return "(" + X + "; " + Y + ")"; + } + #region operators /* @@ -58,6 +125,85 @@ Реализуй также следущие операторы (Vector v, u и - +v, -v */ + /// + /// Вычисляет сумму двух данных векторов. + /// + /// Объект , задающий вектор-слагаемое. + /// Объект , задающий вектор-слагаемое. + /// Объект типа , равный сумме данных векторов. + public static Vector operator +(Vector v, Vector w) + { + Vector sum = new Vector(v); + sum.Add(w); + return sum; + } + + /// + /// Вычисляет разность двух данных векторов. + /// + /// Объект , задающий вектор-уменьшаемое. + /// Объект , задающий вектор-вычитаемое. + /// Объект типа , равный разности данных векторов. + public static Vector operator -(Vector v, Vector w) + { + return new Vector(v.X - w.X, v.Y - w.Y); + } + + /// + /// Возвращает новый вектор, равный произведению данного вектора на число. + /// + /// Объект , задающий вектор-множетель. + /// Числовой множитель типа . + /// Объект , равный произведению данного вектора на число. + public static Vector operator *(Vector v, double k) + { + Vector mul = new Vector(v); + mul.Scale(k); + return mul; + } + + /// + /// Возвращает новый вектор, равный произведению данного вектора на число. + /// + /// Объект , задающий вектор-множетель. + /// Числовой множитель типа . + /// Объект , равный произведению данного вектора на число. + public static Vector operator *(double k, Vector v) + { + return v * k; + } + + /// + /// Возвращает новый вектор, равный частному от деления данного вектора на число. + /// + /// Объект , задающий вектор-делимое. + /// Числовой делитель типа . + /// Объект , равный частному от деления данного вектора на число. + public static Vector operator /(Vector v, double k) + { + return v * (1 / k); + } + + /// + /// Возвращает новый вектор, равный данному вектору, взятому со знаком "+". + /// + /// Объект . + /// Объект , равный данному вектору, взятому со знаком "+". + public static Vector operator +(Vector v) + { + return new Vector(v); + } + + /// + /// Возвращает новый вектор, равный данному вектору, взятому со знаком "-". + /// + /// Объект . + /// Объект , равный данному вектору, взятому со знаком "-". + public static Vector operator -(Vector v) + { + return v * (-1.0); + } + #endregion } diff --git a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/VectorExtensions.cs b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/VectorExtensions.cs index 525be40f..54f95562 100644 --- a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/VectorExtensions.cs +++ b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/VectorExtensions.cs @@ -1,4 +1,6 @@ -namespace BoringVector +using System; + +namespace BoringVector { /* Здесь тебе нужно написать класс с методами-расширениями структуры Vector: @@ -7,4 +9,68 @@ - GetAngleBetween: возвращает угол между двумя векторами в радианах. Примечание: нулевой вектор сонаправлен любому другому. - GetRelation: возвращает значение перечесления VectorRelation(General, Parallel, Orthogonal) - отношение между двумя векторами("общий случай", параллельны, перпендикулярны). Перечисление задавать тоже тебе) */ + + /// + /// Перечисление, задающее возможные отношения между двумя векторами. + /// + internal enum VectorRelation + { + General, + Parallel, + Orthogonal + } + + /// + /// Класс с методами-расширениями структуры Vector. + /// + internal class ExtendedVector + { + /// + /// Проверяет, является ли вектор нулевым, т.е. его координаты близки к нулю. + /// + /// Объект . + /// Число типа , задающее точность. + /// Флаг типа , указывающий (с заданной точностью), является ли вектор нулевым. + public static bool IsZero(Vector v, double eps = 1e-6) + { + return Math.Abs(v.X) < eps && Math.Abs(v.Y) < eps; + } + + /// + /// Нормализует вектор. + /// + /// Объект . + /// Объект , равный данному вектору, делённому на свою длину. + public static Vector Normalize(Vector v) + { + return v / Math.Sqrt(v.SquareLength()); + } + + /// + /// Возвращает угол между двумя векторами в радианах. + /// + /// Объект , задающий один из векторов. + /// Объект , задающий один из векторов. + /// Число типа , углу между двумя заданными векторами в радианах. + public static double GetAngleBetween(Vector v, Vector w) + { + return IsZero(v) || IsZero(w) ? 0 : Math.Acos(Normalize(v).DotProduct(Normalize(w))); + } + + /// + /// Определяет отношение между двумя векторами. + /// + /// Объект , задающий один из векторов. + /// Объект , задающий один из векторов. + /// Число типа , задающее точность. + /// Значение перечисления , указывающее (с заданной точностью) отношение между двумя данными векторами. + public static VectorRelation GetRelation(Vector v, Vector w, double eps = 1e-6) + { + if (IsZero(v) || IsZero(w) || v.CrossProduct(w) < eps) + { + return VectorRelation.Parallel; + } + return Math.Abs(v.DotProduct(w)) < eps ? VectorRelation.Orthogonal : VectorRelation.General; + } + } } diff --git a/course-2021-1/exercises/03-boring-vector/BoringVector/ConsoleApp1/BoringVector.Tests.csproj b/course-2021-1/exercises/03-boring-vector/BoringVector/ConsoleApp1/BoringVector.Tests.csproj new file mode 100644 index 00000000..3b430d43 --- /dev/null +++ b/course-2021-1/exercises/03-boring-vector/BoringVector/ConsoleApp1/BoringVector.Tests.csproj @@ -0,0 +1,18 @@ + + + + Exe + netcoreapp2.0 + + + + + + + + + + + + + diff --git a/course-2021-1/exercises/03-boring-vector/BoringVector/ConsoleApp1/VectorTests.cs b/course-2021-1/exercises/03-boring-vector/BoringVector/ConsoleApp1/VectorTests.cs new file mode 100644 index 00000000..5d18a9f7 --- /dev/null +++ b/course-2021-1/exercises/03-boring-vector/BoringVector/ConsoleApp1/VectorTests.cs @@ -0,0 +1,61 @@ +using System; +using Xunit; + +namespace BoringVector.Tests +{ + public class VectorTests + { + [Theory] + [InlineData(0, 0, 0)] + [InlineData(1, 2, 5)] + [InlineData(5, 50, 2525)] + public void Test_SquareLength(double x, double y, double ans) + { + Assert.Equal(new Vector(x, y).SquareLength(), ans); + } + + [Theory] + [InlineData(0, 0, 0, 0, 0, 0)] + [InlineData(1, 0, -1, 0, 0, 0)] + [InlineData(3, 5, 0, 0, 3, 5)] + [InlineData(6, 10, -11, 2, -5, 12)] + public void Test_Add(double vX, double vY, double wX, double wY, double ansX, double ansY) + { + Vector ans = new Vector(vX, vY).Add(new Vector(wX, wY)); + Assert.Equal(ans.X, ansX); + Assert.Equal(ans.Y, ansY); + } + + [Theory] + [InlineData(0, 0, 2, 0, 0)] + [InlineData(0, 3, 6, 0, 18)] + [InlineData(1, 1, 3, 3, 3)] + [InlineData(2, -3, -1, -2, 3)] + public void Test_Scale(double vX, double vY, double k, double ansX, double ansY) + { + Vector ans = new Vector(vX, vY).Scale(k); + Assert.Equal(ans.X, ansX); + Assert.Equal(ans.Y, ansY); + } + + [Theory] + [InlineData(0, 0, 1, 1, 0)] + [InlineData(0, 4, 7, 0, 0)] + [InlineData(1, -2, -1, 2, -5)] + [InlineData(10, 4, -2, 3, -8)] + public void Test_DotProduct(double vX, double vY, double wX, double wY, double ans) + { + Assert.Equal(new Vector(vX, vY).DotProduct(new Vector(wX, wY)), ans); + } + + [Theory] + [InlineData(0, 0, 1, 1, 0)] + [InlineData(0, 4, 7, 0, 28)] + [InlineData(1, -2, -1, 2, 0)] + [InlineData(10, 4, -2, 3, 38)] + internal void TestCrossProduct(double vX, double vY, double wX, double wY, double ans) + { + Assert.Equal(new Vector(vX, vY).CrossProduct(new Vector(wX, wY)), ans); + } + } +} \ No newline at end of file From 112b81e8d2f4c02c5b1a5fc9c74074d7f5c645a4 Mon Sep 17 00:00:00 2001 From: rvolosenkov Date: Thu, 20 May 2021 09:54:30 +0300 Subject: [PATCH 4/4] task03 (1) --- .../BoringVector/BoringVector/Vector.cs | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/Vector.cs b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/Vector.cs index 3aa3a076..e4d27c92 100644 --- a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/Vector.cs +++ b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/Vector.cs @@ -17,8 +17,8 @@ internal struct Vector Vector задается парой вещественных координат X и Y. */ - public double X; - public double Y; + public readonly double X; + public readonly double Y; /// /// Конструирует вектор из двух заданных вещественных координат. @@ -66,9 +66,7 @@ public double SquareLength() /// Текущий объект (типа ) с модифицированными координатами. public Vector Add(Vector v) { - X += v.X; - Y += v.Y; - return this; + return new Vector(X + v.X, Y + v.Y); } /// @@ -78,9 +76,7 @@ public Vector Add(Vector v) /// Текущий объект (типа ) с модифицированными координатами. public Vector Scale(double k) { - X *= k; - Y *= k; - return this; + return new Vector(X * k, Y * k); } /// @@ -133,9 +129,7 @@ Реализуй также следущие операторы (Vector v, u и /// Объект типа , равный сумме данных векторов. public static Vector operator +(Vector v, Vector w) { - Vector sum = new Vector(v); - sum.Add(w); - return sum; + return v.Add(w); } /// @@ -157,9 +151,7 @@ Реализуй также следущие операторы (Vector v, u и /// Объект , равный произведению данного вектора на число. public static Vector operator *(Vector v, double k) { - Vector mul = new Vector(v); - mul.Scale(k); - return mul; + return v.Scale(k); } /// @@ -181,7 +173,15 @@ Реализуй также следущие операторы (Vector v, u и /// Объект , равный частному от деления данного вектора на число. public static Vector operator /(Vector v, double k) { - return v * (1 / k); + try + { + return v * (1 / k); + } + catch (DivideByZeroException e) + { + Console.WriteLine(e.Message); + return v; + } } ///