Форум программистов, компьютерный форум, киберфорум C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
38 / 27 / 13
Регистрация: 18.12.2019
Сообщений: 423
Записей в блоге: 1

Разделить класс ReportMaker по ответственности за оформление отчета и за исчисление показателей: Как угодить NUnitLite ?

15.11.2020, 12:17. Показов 1920. Ответов 1

Author24 — интернет-сервис помощи студентам
Задание №1
Петр разработал генератор отчетов в проекте Delegates.Reports, который считает простую статистику о погоде по нескольким параметрам через несколько дней.
Его генератор может создавать два отчета: отчет в HTML, который считает среднее и стандартное отклонение, и отчет в Markdown, который считает медианы.
Однако, что делать, если нужно посчитать медианы и вывести результат в HTML? А если нужен будет третий отчет в HTML?
Текущее решение крайне неудобно для таких ситуаций.
Помогите Петру перевести его код по наследованию на делегирование.
Разделите ответственности за оформление отчета и по исчислению показателей.
В результате сам класс ReportMaker вам, возможно, уже и не понадобится.
Program.cs

C# Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*Завдання 1
Петро розробив генератор звітів в проекті Delegates.Reports, який рахує просту статистику про погоду за кількома параметрами за кілька днів. 
Його генератор може створювати два звіти: звіт в HTML, який рахує середнє і стандартне відхилення, і звіт в Markdown, який рахує медіани.
Однак, що робити, якщо потрібно порахувати медіани і вивести результат в HTML? 
А якщо потрібен буде третій звіт в HTML? 
Поточне рішення вкрай незручно для таких ситуацій.
Допоможіть Петру перевести його код з успадкування на делегування. 
Розділіть відповідальності за оформлення звіту і по обчисленню показників. 
В результаті сам клас ReportMaker вам, можливо, вже й не знадобиться.
*/
 
using NUnitLite;
 
namespace _12112020dz
{
    class Program
    {
        static void Main(string[] args)
        {
            new AutoRun().Execute(args);
        }
    }
}
MeanAndStd.cs
C# Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System.Globalization;
 
namespace _12112020dz
{
    public class MeanAndStd
    {
        public double Mean { get; set; }
        public double Std { get; set; }
        public override string ToString()
        {
            return Mean.ToString(CultureInfo.InvariantCulture) + "±" + Std.ToString(CultureInfo.InvariantCulture); //Возможно проблема тут
        }
    }
}
 
/* // оригинал:
using System.Globalization;
 
namespace _12112020dz
{
    public class MeanAndStd
    {
        public double Mean { get; set; }
        public double Std { get; set; }
        public override string ToString()
        {
            return Mean.ToString(CultureInfo.InvariantCulture) + "±" + Std.ToString(CultureInfo.InvariantCulture);
        }
    }
}
*/
Measurement.cs
C# Скопировано
1
2
3
4
5
6
7
8
namespace _12112020dz
{
    public class Measurement
    {
        public double Temperature { get; set; }
        public double Humidity { get; set; }
    }
}
ReportMaker.cs
C# Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
using System;
using System.Collections.Generic;
using System.Linq;
 
namespace _12112020dz
{
    public static class ReportCalculation
    {
        public static object MakeStatisticsMeanAndStd(IEnumerable<double> _data)
        {
            var data = _data.ToList();
            var mean = data.Average();
            var std = Math.Sqrt(data.Select(z => Math.Pow(z - mean, 2)).Sum() / (data.Count - 1));
            return new MeanAndStd { Mean = mean, Std = std };
        }
        public static object MakeStatisticsMedian(IEnumerable<double> data)
        {
            var list = data.OrderBy(z => z).ToList();
            if (list.Count % 2 == 0)
                return (list[list.Count / 2] + list[list.Count / 2 - 1]) / 2;
            return list[list.Count / 2];
        }
 
    }
    public static class WrapperReportMaker
    {
        public static string HTMLReportMaker(string caption, IEnumerable<Measurement> data, Func<IEnumerable<double>, object> func)
        {
            var temperature = func(data.Select(e => e.Temperature));
            var humidity = func(data.Select(e => e.Humidity));
            return $"<h1>{caption}</h1><ul><li><b>Temperature</b>: {temperature}<li><b>Humidity</b>: {humidity}</ul>";
        }
 
        public static string MarkdownReportMaker(string caption, IEnumerable<Measurement> data, Func<IEnumerable<double>, object> func)
        {
            var temperature = func(data.Select(e => e.Temperature));
            var humidity = func(data.Select(e => e.Humidity));
            return $"## {caption}\n\n * **Temperature**: {temperature}\n\n * **Humidity**: {humidity}\n\n";
        }
    }
    public static class ReportMakerHelper
    {
        public static string MeanAndStdHtmlReport(IEnumerable<Measurement> data)
        {
            return WrapperReportMaker.HTMLReportMaker("Mean and Std", data, ReportCalculation.MakeStatisticsMeanAndStd);
        }
 
        public static string MedianMarkdownReport(IEnumerable<Measurement> data)
        {
            return WrapperReportMaker.MarkdownReportMaker("Median", data, ReportCalculation.MakeStatisticsMedian);
        }
 
        public static string MeanAndStdMarkdownReport(IEnumerable<Measurement> measurements)
        {
            return WrapperReportMaker.MarkdownReportMaker("Mean and Std", measurements, ReportCalculation.MakeStatisticsMeanAndStd);
        }
 
        public static string MedianHtmlReport(IEnumerable<Measurement> measurements)
        {
            return WrapperReportMaker.HTMLReportMaker("Median", measurements, ReportCalculation.MakeStatisticsMedian);
        }
    }
 
 
 
    //public abstract class ReportMaker
    //{
    //  protected abstract string MakeCaption(string caption);
    //  protected abstract string BeginList();
    //  protected abstract string MakeItem(string valueType, string entry);
    //  protected abstract string EndList();
    //  protected abstract object MakeStatistics(IEnumerable<double> data);
    //  protected abstract string Caption { get; }
    //  public string MakeReport(IEnumerable<Measurement> measurements)
    //  {
    //      var data = measurements.ToList();
    //      var result = new StringBuilder();
    //      result.Append(MakeCaption(Caption));
    //      result.Append(BeginList());
    //      result.Append(MakeItem("Temperature", MakeStatistics(data.Select(z => z.Temperature)).ToString()));
    //      result.Append(MakeItem("Humidity", MakeStatistics(data.Select(z => z.Humidity)).ToString()));
    //      result.Append(EndList());
    //      return result.ToString();
    //  }
    //}
 
    //public class MeanAndStdHtmlReportMaker : ReportMaker
    //{
    //  protected override string Caption
    //  {
    //      get
    //      {
    //          return "Mean and Std";
    //      }
    //  }
 
    //  protected override string MakeCaption(string caption)
    //  {
    //      return $"<h1>{caption}</h1>";
    //  }
 
    //  protected override string BeginList()
    //  {
    //      return "<ul>";
    //  }
 
    //  protected override string EndList()
    //  {
    //      return "</ul>";
    //  }
 
    //  protected override string MakeItem(string valueType, string entry)
    //  {
    //      return $"<li><b>{valueType}</b>: {entry}";
    //  }
 
    //  protected override object MakeStatistics(IEnumerable<double> _data)
    //  {
    //      var data = _data.ToList();
    //      var mean = data.Average();
    //      var std = Math.Sqrt(data.Select(z => Math.Pow(z - mean, 2)).Sum() / (data.Count - 1));
 
    //      return new MeanAndStd
    //      {
    //          Mean = mean,
    //          Std = std
    //      };
    //  }
    //}
 
    //public class MedianMarkdownReportMaker : ReportMaker
    //{
    //  protected override string Caption
    //  {
    //      get
    //      {
    //          return "Median";
    //      }
    //  }
 
    //  protected override string BeginList()
    //  {
    //      return "";
    //  }
 
    //  protected override string EndList()
    //  {
    //      return "";
    //  }
 
    //  protected override string MakeCaption(string caption)
    //  {
    //      return $"## {caption}\n\n";
    //  }
 
    //  protected override string MakeItem(string valueType, string entry)
    //  {
    //      return $" * **{valueType}**: {entry}\n\n";
    //  }
 
    //  protected override object MakeStatistics(IEnumerable<double> data)
    //  {
    //      var list = data.OrderBy(z => z).ToList();
    //      if (list.Count % 2 == 0)
    //          return (list[list.Count / 2] + list[list.Count / 2 - 1]) / 2;
 
    //      return list[list.Count / 2];
    //  }
    //}
 
    //public static class ReportMakerHelper
    //{
    //  public static string MeanAndStdHtmlReport(IEnumerable<Measurement> data)
    //  {
    //      return new MeanAndStdHtmlReportMaker().MakeReport(data);
    //  }
 
    //  public static string MedianMarkdownReport(IEnumerable<Measurement> data)
    //  {
    //      return new MedianMarkdownReportMaker().MakeReport(data);
    //  }
 
    //  public static string MeanAndStdMarkdownReport(IEnumerable<Measurement> measurements)
    //  {
    //      throw new NotImplementedException();
    //  }
 
    //  public static string MedianHtmlReport(IEnumerable<Measurement> measurements)
    //  {
    //      throw new NotImplementedException();
    //  }
    //}
}
ReportMaker_should.cs
C# Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
using NUnit.Framework;
using System.Collections.Generic;
 
namespace _12112020dz
{
    [TestFixture]
    public class ReportMaker_should
    {
        private readonly List<Measurement> data = new List<Measurement>
        {
            new Measurement
            {
                Humidity=1,
                Temperature=-10,
            },
            new  Measurement
            {
                Humidity=2,
                Temperature=2,
            },
            new Measurement
            {
                Humidity=3,
                Temperature=14
            },
            new Measurement
            {
                Humidity=2,
                Temperature=30
            }
        };
        [Test]
        public void MeanAndStdHtml()
        {
            var expected = @"<h1>Mean and Std</h1><ul><li><b>Temperature</b>: 9±17.0880074906351<li><b>Humidity</b>: 2±0.816496580927726</ul>";
            var actual = ReportMakerHelper.MeanAndStdHtmlReport(data);
            Assert.AreEqual(expected, actual); // вылетает:
            /*NUnit.Framework.AssertionException: '  Expected string length 112 but was 113. Strings differ at index 66.
               Expected: "...7.0880074906351<li><b>Humidity</b>: 2±0.816496580927726</ul>"
               But was:  "...7.08800749063506<li><b>Humidity</b>: 2±0.816496580927726</ul>"
               ----------------------------^
               '
               */
        }
 
        [Test]
        public void MedianMarkdown()
        {
            var expected = "## Median\n\n * **Temperature**: 8\n\n * **Humidity**: 2\n\n";
            var actual = ReportMakerHelper.MedianMarkdownReport(data);
            Assert.AreEqual(expected, actual);
        }
 
        [Test(Description = "Новый тест, который нужно сделать рабочим после рефакторинга")]
        public void MeanAndStdMarkdown()
        {
            var expected = "## Mean and Std\n\n * **Temperature**: 9±17.0880074906351\n\n * **Humidity**: 2±0.816496580927726\n\n";
            var actual = ReportMakerHelper.MeanAndStdMarkdownReport(data);
            Assert.AreEqual(expected, actual); // вылетает:
            /*NUnit.Framework.AssertionException: '  Expected string length 95 but was 96. Strings differ at index 54.
               Expected: "...: 9±17.0880074906351\n\n * **Humidity**: 2±0.816496580927726\n\n"
               But was:  "...: 9±17.08800749063506\n\n * **Humidity**: 2±0.816496580927726\n\n"
               ---------------------------------^
               '
               */
        }
 
        [Test(Description = "Новый тест, который нужно сделать рабочим после рефакторинга")]
        public void MedianHtml()
        {
            var expected = "<h1>Median</h1><ul><li><b>Temperature</b>: 8<li><b>Humidity</b>: 2</ul>";
            var actual = ReportMakerHelper.MedianHtmlReport(data);
            Assert.AreEqual(expected, actual);
        }
    }
}
Вылетает на тестах, в файле ReportMaker_should.cs

Как исправить/угодить NUnitLite ? Кажется, там что-то с округлением:
9±17.0880074906351
9±17.08800749063506
Заранее спасибо за ответы.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.11.2020, 12:17
Ответы с готовыми решениями:

Оформление отчета
Всем привет оформляю отчет по курсовой копирую текст с модулей в ворд и русские буквы закодировались как скопировать так что бы нормально...

Оформление отчета
Можно ли средствами Access создать из таблицы &quot;исх&quot; отчет в виде &quot;templ&quot; ?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Злой няш
 Аватар для I2um1
2136 / 1505 / 565
Регистрация: 05.04.2010
Сообщений: 2,881
15.11.2020, 12:24
C# Скопировано
1
Assert.AreEqual(expected, actual);
Третий параметр - погрешность.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Ответ Создать тему
Новые блоги и статьи
Async/await в Swift: Асинхронное программировани­е в iOS
mobDevWorks 20.03.2025
Асинхронное программирование долго было одной из самых сложных задач для разработчиков iOS. В течение многих лет мы сражались с замыканиями, диспетчеризацией очередей и обратными вызовами, чтобы. . .
Сложность Колмогорова: Приёмы упрощения кода
ArchitectMsa 20.03.2025
Наверное, каждый программист хотя бы раз сталкивался с кодом, который напоминает запутанный лабиринт — чем дальше в него погружаешься, тем сложнее найти выход. И когда мы говорим о сложности кода, мы. . .
PostgreSQL в Kubernetes: Подготовка кластера и настройка
Mr. Docker 20.03.2025
Когда доходит до контейнеризации баз данных и особенно таких требовательных к ресурсам системах как PostgreSQL, многие команды до сих пор колеблются, прежде чем перенести их в контейнерную. . .
C++26: Индексирование пакетов и метапрограммиро­вание
bytestream 20.03.2025
Эволюция C++ продолжается стремительными темпами – каждый новый стандарт приносит функциональность, о которой мы мечтали годами. Звучит слишком громко? Если вы когда-либо боролись с вариадическими. . .
Состояние гонки в C#: подводные камни многопоточного программировани­я
UnmanagedCoder 20.03.2025
Что такое состояние гонки? Это ситуация, когда результат программы непредсказуемо меняется в зависимости от порядка выполнения потоков. Проще говоря, два или более потока пытаются одновременно. . .
Next.js для разработки React: преимущества серверного рендеринга
Reangularity 20.03.2025
Next. js решает классическую проблему React-приложений: медленную первоначальную загрузку и плохую индексацию поисковиками. Вместо того чтобы заставлять браузер пользователя выполнять всю работу по. . .
JUnit или TestNG: Выбираем Java-фреймворк для тестирования
Javaican 20.03.2025
История тестовых фреймворков в Java началась в конце 90-х, когда Кент Бек и Эрих Гамма разработали JUnit - инструмент, который перевернул представление разработчиков о модульном тестировании. JUnit. . .
Разбиваем монолит на два микросервиса и реализуем CI/CD
ArchitectMsa 20.03.2025
Когда команда растет, а функциональность монолита расширяется, поддерживать и развивать такую систему становится все труднее. Разработчики начинают тратить много времени на разбор сложных. . .
Python и PDF: Создание и редактирование файлов
py-thonny 20.03.2025
Работа с PDF-документами – одна из популярных задач в современной разработке. Python предлагает несколько инструментов для создания, чтения и редактирования PDF-файлов, среди которых особенно. . .
Корутины в Unity и производительно­сть WaitForSeconds
GameUnited 20.03.2025
Разработчики игр на Unity часто сталкиваются с вопросом: как выполнять действия через определённые промежутки времени, не блокируя основной поток игры? Тут как раз и приходят на помощь корутины —. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
Выделить код Копировать код Сохранить код Нормальный размер Увеличенный размер