Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Отладка программных решений. Учебно-методическое пособие для студентов направлений подготовки бакалавриата 09.03.03 «Прикладная информатика», 09.03.04

.pdf
Скачиваний:
0
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
71
Информация о действиях пользователя. Подобная информация,
как говорилась выше, может относится к отладочной, но может выделяться в отдельный уровень. Ее выделяют в отдельный уровень, если необходимо отслеживать действия пользователя, например, для своевременного выявления потенциальных угроз (например, для выявления попыток несанкционированного доступа к информации или функциям программы). В таком случае следует информацию о действиях пользователя отсекать от отладочной и обрабатывать отдельно (например, через модуль аудита безопасности).
Некритические ошибки. К такого рода информации относятся
действия пользователя или результат работы программы, при котором ее дальнейшая работа может быть затруднена (например, пользователь ввел не все данные, либо к каким-то ресурсам нет доступа). При этом для подобных ситуаций были прописаны в коде определенные механизмы, которые позволяют выполнять работу программы далее без серьезных ограничений. Такого рода записи должны встречаться в логах гораздо реже, нежели отладочные логи (особенно на этапе внедрения программы) и им должно уделяться больше внимания, чтобы они возникали как можно реже.
Критические ошибки. Подобные записи должны появляться в
случае возникновения непредвиденных ошибок в ходе работы программы, требующих оперативного вмешательства и разбора. Как правило, возникновение критической ошибки говорит о том, что программа не в состоянии далее выполнять свои операции (либо, часть операций) и необходимо как можно скорее понять, почему так произошло и что делать, чтобы такого не случилось в будущем.
72
«Крах». Подобного рода ситуаций возникают в случае «падения»
системы, когда она прекращает полностью свою работу. Главное отличие от критических ошибок заключается как раз в том, что в случае критических ошибок программа еще продолжает функционирование (возможно, просто, с очень ограниченной функциональностью), а в случае «краха» она полностью прекращает свою работу. На подобные ситуации следует реагировать незамедлительно, а, следовательно, подобная информация должна незамедлительно отображаться у специалистов, отвечающих за работу программы.
В современном программировании крайне редко пишут собственный
логгер, как правило, используют готовое решение. При этом, логгер должен обладать следующим набором функций:
поддерживать различные уровни логирования (то, что
обсуждалось выше);
уметь записывать логи в разные места (файлы, базы данных,
отправлять сообщения через интернет и т.п.);
выполнять ротацию файлов (в случае записи в файл, не копить все
в одном гигантском файле, а создавать много файлов, например, на каждый день, либо по достижению определенного размера файла);
быть потокобезопасным (не влиять на работу основной системы:
не выбрасывать ошибки, не загружать своими операциями работу основной системы);
асинхронное логирование (запись в логи через отдельные потоки,
опять же, чтобы не тормозить работу основной системы);
иметь возможность оперативно настраивать формат логов,
уровни логирования, по которым ведется запись и прочее (при этом без пересборки и переразвертывания проекта).
73
Работа с логгером в коде выполняется в 3 шага:
1. В файле конфигурации проекта прописать настройки для логгера.
2. В коде (обычно при запуске системы) прописать загрузку настроек
логгера.
3. Вызывать запись логов нужного уровня в требуемых местах.
Общее задание
2. Требуется сделать desktop-приложение по расчету функции Y
через ряд Тейлора. Необходимо реализовать следующее:
а. На форме разместить элемент(ы) TextBox для ввода
исходных данных для отработки задания по варианту. На форме разместить элемент Button при нажатии которого запускается механизм расчета. В процессе расчета в лог­файл записываются все действия.
б. Результат расчета через ряд Тейлора (Сумма S) при
количестве слагаемых n должен быть равен расчету функции Y примерно до 3-4 знака после запятой (это записи логов уровня отладки).
в. Обязательно! Программа должна корректно
отрабатывать случаи недостаточности данных для выполнения задания (это записи логов уровня некритических ошибок).
Задание
N
Сумма S
n
Функция Y
1.
 


 
30
 
󰇛
  󰇜
  
 
󰇛󰇜
2.
󰇛󰇜
󰇛
󰇜
󰇛
󰇜
 
40
 
74
3.
󰇛󰇜
󰇛
󰇜
󰇛
󰇜

 
40
 

4.
     
 
󰇛
     
󰇜
 
󰇛
     
󰇜 
10
 
󰇛󰇜
5.
 󰇛󰇜
󰇛
󰇜
󰇛
󰇜
 
20
 
󰇛
󰇜
6.


 
30
  
󰇛󰇜
 
7.
󰇛
󰇜
󰇛
󰇜

󰇛
󰇜

 
50
 
󰇛󰇜
8.
 
 
40
󰇛󰇜
9.
󰇛  
󰇜
󰇛
  
󰇜
󰇛
  
󰇜
 
40
󰇛
    
󰇜
10.

 
20
󰇛  󰇜
75
ПРАКТИЧЕСКАЯ РАБОТА № 06.
ОТЛАДКА
Цель
Разработать программу и выполнить отладку кода по вариантам с
использованием механизма отладки среды выполнения.
Теория
Для примера рассмотрим функцию   , разложенную в сумме ряда
   
󰇛󰇜

 
󰇛󰇜

  (количество слагаемых n=10). В задаче
необходимо протабулировать эти функции на интервале изменения x [0,1; 1]. Заметим, что значения s и y при одинаковых значениях x будут приблизительно равными.
Примечание: k! – факториал числа k. Вычисляется по формуле
          
Код программы будет следующим (листинг 6.1).
double x = 0; double h = 0.05; int n = 10; while (x <= 1 + h)
{ double y = Math.Pow(3, x); double s = 1; int k = 1; for (int i = 1; i <= n; i++) { for (int j = 2; j <= i; j++) k *= j; double slag = Math.Pow(Math.Log(3.0), i) / k * Math.Pow(x, i); s += slag; } Console.WriteLine("| {0}\t| {1}\t| {2}\t|\n", x, y, s); x += h;
}
Листинг 6.1 – Фрагмент кода
Но вот незадача, он неправильный (рисунок 6.1).
76
Рисунок 6.1 – Результат работы
Значение в столбце s не соответствует значению в столбце y. Более того,
он не высчитывается вовсе. Придется разбираться в коде.
И так, рассмотрим, что же здесь происходит. На первом шаге мы
инициализируем некоторые переменные: задаем начальное значение для x, задаем шаг h и количество слагаемых n. На втором шаге задаем цикл с предусловием для прохождения диапазона x. Внутри цикла мы рассчитываем значения функций y и s для определенного значения x, выводим их на экран, увеличиваем значение x и переходим к следующему шагу цикла.
С расчетом функции y проблем нет, там простая формула, ошибок там
не должно быть и простая проверка на калькуляторе запросто это подтвердит.
Перейдем к расчету s. На первом шаге мы инициализируем значение s
единицей, так как в формуле у нас первое слагаемое равно 1. Саму сумму s
можно представить в виде:   
󰇛󰇛󰇜󰇜

 
 
. Поэтому для подсчета
суммы слагаемых s можно использовать цикл. Для подсчета слагаемого требуется найти факториал от числа. Найти его можно различными способами. Мы воспользуемся еще одним дополнительным циклом. Так как факториал – это произведение чисел от 1 и до самого числа, то получаем (листинг 6.2):
77
int k = 1; for (int j = 2; j <= i; j++)
k *= j;
Листинг 6.2 – Фрагмент кода цикла для расчета факториала
Начальное значение k мы задали единице. Далее, в цикле мы проходим
числа от 2 до текущего значение i и домножаем k на каждое из этих чисел. В результате у нас получается в k факториал числа i.
Остальная часть формулы расчета слагаемого простая, поэтому сразу его
высчитываем (листинг 6.3):
double slag = Math.Pow(Math.Log(3.0), i) / k * Math.Pow(x, i);
Листинг 6.3 – Фрагмент кода для расчета факториала
Полученное значение прибавляем к s. В результате по окончанию цикла
по i мы получим значение суммы 10 слагаемых. И мы можем вывести полученные значения на экран. Теперь остается только найти, где же была допущена ошибка. Воспользуемся отладчиком Visual Studio. Установим точку прерывания напротив вычисления формулы y (рисунок 6.2).
Рисунок 6.2 – Установка точки остановки
Запустим программу и дождемся вызова прерывания (всплывет окно
Visual Studio и в красном кружке появится желтая стрелка) (рисунок 6.3).
78
Рисунок 6.3 – Остановка выполнения программы
Внизу справа выберем вкладку «Контрольные значения 1» и введем туда
наши переменные i, s, k, slag (рисунок 6.4).
Рисунок 6.4 – Ввод переменных в «Контрольные значения»
Теперь начнем прохождение по коду (нажимаем клавишу F10).
79
В результате расчетов наши значения будут меняться так (каждая строка
в таблице – это изменение значения одной из переменных, оно обозначается красным цветом) (таблица 6.1). Таблица 6.1 – Результаты работы через отладчик
i s k
slag
1
1,00
1
-9.2559631349317831e+061
1
1,00
1
0
2
1,00
1 0 2
1,00
2 0 2
1,00
2 0 3
1,00
2
0
3
1,00
4
0
3
1,00
12 0 3
1,00
12 0 4
1,00
12
0
4
1,00
24
0
4
1,00
72
0
4
1,00
288
0 4 1,00
288
0
Дальше вычисления можно не проводить, так как ошибку можно
обнаружить уже сейчас: факториал считается неправильно. 3! = 1 *2 *3 = 6, а у нас факториал от 3 равен 12. 4! = 1 *2 *3 *4 = 24, а у нас 288. Отчего он считается неправильно? Посмотрим, как считается факториал от 3 у нас: 2 * 2 * 3 = 12. У нас вместо 1 идет 2. При расчете 4 = 12 * 2 * 3 * 4 = 288. Здесь уже вместо 1 идет 12, т.е. вместо 1 идет значение расчета факториала от предыдущего числа. Все потому что, значение в переменной k сбрасывается в 1 только при переходе на расчет следующего значения х. А необходимо сбрасывать при переходе на расчет следующего слагаемого s (листинг 6.4).
80
while (x <= 1 + h)
{ double y = Math.Pow(3, x); double s = 1; for (int i = 1; i <= n; i++) { int k = 1;
for (int j = 2; j <= i; j++) k *= j; double slag = Math.Pow(Math.Log(3.0), i) / k * Math.Pow(x, i); s += slag; } Console.WriteLine("| {0}\t| {1}\t| {2}\t|\n", x, y, s); x += h;
}
Листинг 6.4 –Исправленный код программы
Запускаем программу и получаем (рисунок 6.5):
Рисунок 6.5 – Корректный результат работы программы
Значение в столбце s полностью идентично значению в столбце y.
Программа работает корректно.
Общее задание
1. Исправить программы (console-приложения) табулирования двух
функций S и Y в заданном диапазоне изменения аргумента x. Необходимо реализовать следующее:
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]