
Глава 9 Моделирование и проектирование.ppt
- Количество слайдов: 79
Программирование на Python’е: Введение в информатику Глава 9 Моделирование и проектирование Python Programming, 2/e 1
Задачи n n n Понимать моделирование как составную часть решения практических задач. Применять псевдослучайные числа в моделировании Монте Карло. Понимать и уметь применять методы разработки сверху вниз и спиральный метод при написании сложных программ. Python Programming, 2/e 2
Задачи n Понимать методику тестирования элементов программы и уметь применять эту методику при реализации и отладке сложных программ. Python Programming, 2/e 3
Моделирование рэкетбола n Моделирование может решить практические проблемы, заменяя реальные процессы на изучение модели, что позволяет получить данные, которые в некоторых случаях невозможно получить иначе. n Компьютерное моделирование используется при предсказании погоды, проектировании самолётов, создании специальных эффектов в кино. Python Programming, 2/e 4
Модельная проблема n n Денис Дубков часто играет в рэкетбол с игроком, который играет немного лучше, чем он сам. Денис обычно проигрывает матчи. Не должен ли игрок, который играет немного лучше и выигрывать немного больше? Света предложила смоделировать игру, чтобы проверить может ли небольшое различие в умении играть приводить к большой разнице в счете. Python Programming, 2/e 5
Анализ и спецификации n n n В рэкетбол играют два игрока, которые бьют по мячу ракетками на огороженной 4 стенами площадке. Один из игроков начинает игру, подавая мяч. Игроки по очереди бьют по мячу, поддерживая его в игре. Отрезок игры от подачи до момента, когда один из игроков не может нанести удар по правилам, называют розыгрышем мяча. Python Programming, 2/e 6
Анализ и спецификации n n n Игрок не нанёсший удар по мячу проигрывает розыгрыш. Если проигравший подавал, то подача переходит противнику. Если подающий выиграл розыгрыш, то ему начисляется бал. Бал можно получить только во время своей подачи. Первый из игроков, набравший 15 балов, выигрывает игру. Python Programming, 2/e 7
Анализ и спецификации n n В нашей модели уровень игроков будет задаваться вероятностью того, что игрок выиграл подачу, когда он подавал. Пример: Игрок с вероятностью 0. 60 выиграть бал выигрывает его в 60% своих подач. Программа попросит пользователя ввести вероятности выигрыша подач для обоих игроков и смоделирует несколько игр в рэкетбол. В завершение работы программа напечатает обзор результатов своей работы. Python Programming, 2/e 8
Анализ и спецификации n Ввод: Программа просит ввести вероятности выигрыша подач игроками A и Б. Программа затем запрашивает и получает количество игр, которые нужно смоделировать. Python Programming, 2/e 9
Анализ и спецификации n Вывод: Программа сначала выдаст начальные данные: Какова вероятность игроку А выиграть подачу? Какова вероятность игроку Б выиграть подачу? Сколько игр смоделировать? n Программа затем печатает красиво отформатированный отчет о количестве смоделированных игр и их результатах. Смоделировано игр: 500 Выиграл А: 268 (53. 6%) Выиграл Б: 232 (46. 4%) Python Programming, 2/e 10
Анализ и спецификации n n n Замечания: Предполагается, что все данные вводятся правильно, проверка данных не требуется. В каждой смоделированной игре игрок А подаёт первым. Python Programming, 2/e 11
Псевдослучайные числа n n Если мы говорим, что игрок A выигрывает в 50% случаев, то это не означает, что он выигрывает каждую вторую игру. Скорее результат похож на результат подбрасывания монеты. Суммарно, примерно в половине случаев монета выпадет орлом, в оставшихся случаях решкой, но результат каждого подбрасывания никак не зависит от предыдущих результатов. (мы можем получить 8 орлов подряд) Python Programming, 2/e 12
Псевдослучайные числа n n Многие модели требуют, чтобы события происходили с определённой вероятностью. Такое моделирование называют моделированием Монте Карло, потому что результаты зависят от вероятностей. Вспомните программу chaos из главы 1. Кажущаяся случайность результатов программы является результатом повторного применения функции для генерации последовательности чисел. Python Programming, 2/e 13
Псевдослучайные числа n n n Похожий подход используется для генерации псевдослучайных чисел, которые заменяют случайные. Генератор псевдослучайных чисел начинает работу с порождающего значения. Это значение передаётся функции для обеспечения «случайности» . Следующий раз, когда нужно будет случайное значение, текущее значение передаётся функции, чтобы произвести новое значение. Python Programming, 2/e 14
Псевдослучайные числа n n Эта последовательность чисел кажется случайной, но если вы начнёте процесс снова с тем же начальным значением, то вы получите ту же последовательность «случайных» чисел. Python предоставляет библиотеку для работы с псевдослучайными числами. Python Programming, 2/e 15
Псевдослучайные числа n n Эти функции берут начальное значение из компьютерных даты и времени, когда загружается модуль, поэтому всякий раз когда работает программа производится своя последовательность случайных чисел. . Наибольший интерес представляют функции randrange и random. Python Programming, 2/e 16
Псевдослучайные числа n n Функция randrange используется для выбора псевдослучайных целых из заданного диапазона. Синтаксис функции randrangeпохож на синтаксис функции range. randrange(1, 6) возвращает число из списка [1, 2, 3, 4, 5], а randrange(5, 105, 5) возвращает кратные между 5 и 100, включительно. Диапазон доходит до конечного значения, но не включает его. Python Programming, 2/e 17
Псевдослучайные числа n >>> 5 >>> 3 >>> 2 >>> 5 >>> 4 Каждое обращение к randrange порождает новое псевдослучайное целое from random import randrange(1, 6) randrange(1, 6) Python Programming, 2/e 18
Псевдослучайные числа n n Значение 5 встречается более, чем в половине случаев, демонстрируя вероятностный аспект природы псевдослучайных чисел. С течением времени функция даст более равномерное распределение, что означает, что все значения будут встречаться примерно одно и то же число раз. Python Programming, 2/e 19
Псевдослучайные числа n n Функция random используется для генерации псевдослучайных чисел с плавающей точкой. У неё нет параметров и она возвращает значения равномерно распределённые между 0 и 1 (включая 0, но исключая 1). Python Programming, 2/e 20
Псевдослучайные числа >>> from random import random >>> random() 0. 79432800912898816 >>> random() 0. 00049858619405451776 >>> random() 0. 1341231400816878 >>> random() 0. 98724554535361653 >>> random() 0. 21429424175032197 >>> random() 0. 23903583712127141 >>> random() 0. 72918328843408919 Python Programming, 2/e 21
Псевдослучайные числа n n Моделирование игры рэкетбол использует функцию random, чтобы определить выиграл ли игрок подачу. Предположим, что вероятность для игрока выиграть подачу равна 70%, или 0. 70. if <выигрывает подачу>: score = score + 1 Нам нужно вставить вероятностную функцию, которая успешна в 70% случаев. Python Programming, 2/e 22
Псевдослучайные числа n n Предположим, что мы сгенерировали случайное число из полуинтервала [0, 1). Точно 70% отрезка находится слева от 0. 7. Поэтому в 70% случаев случайное число будет < 0. 7, и будет ≥ 0. 7 в 30% случаев. (Знак = только слева, так как генератор может выдать 0, и не выдаёт 1. ) Python Programming, 2/e 23
Псевдослучайные числа n n Если переменная prob задаёт вероятность выиграть подачу игрока А, то условие random() < prob моделирует розыгрыш мяча при подаче А. if random() < prob: score = score + 1 Python Programming, 2/e 24
Проектирование сверху вниз n n n При проектировании сверху вниз решение большой сложной проблемы сводится к решению меньших более простых проблем. Эти меньшие проблемы решаются сведением к более мелким и простым проблемам. Это продолжается до тех пор, пока не получаем тривиальные проблемы. Их решение соединяем вместе и получаем решение первоначальной проблемы. Python Programming, 2/e 25
Проектирование сверху вниз n n Обычно программа состоит из трёх составляющих ввод данных, преобразование данных, вывод результатов. Алгоритм для моделирования игр в рэкетбол: Печатаем введение Получаем входные данные: prob. A, prob. B, n Моделируем n игр в рэкетбол с помощью вероятностей prob. A and prob. B Печатаем отчет о победах игроков А и Б. Python Programming, 2/e 26
Проектирование сверху вниз n n Это проектирование на высшем уровне. Если мы не знаем как что-то делать, то пока мы не обращаем на это внимание. Предположим, что все компоненты, нужные для реализации алгоритма уже написаны и наша задача завершить алгоритм высшего уровня с помощью этих компонентов. Python Programming, 2/e 27
Проектирование сверху вниз n n Во-первых, мы пишем введение. Это легко, и мы не хотим об этом беспокоиться. def main(): print. Intro() Мы полагаем, что функция print. Intro, которая печатает введение уже написана. Python Programming, 2/e 28
Проектирование сверху вниз n n На следующем шаге нужно получить входные данные. Мы знаем как это сделать. Предположим, что у нас уже есть этот компонент программы функция get. Inputs. Функция get. Inputs получает значения переменных prob. A, prob. B, and n. def main(): print. Intro() prob. A, prob. B, n = get. Inputs() Python Programming, 2/e 29
Проектирование сверху вниз n n Теперь нам нужно смоделировать n игр в рэкетбол с помощью значений prob. A и prob. B. Как это сделать? Мы можем отложить написание этого кода, вводя функцию, sim. NGames, и добавить вызов этой функции в main. Python Programming, 2/e 30
Проектирование сверху вниз n Если бы моделировали игру вручную, то что вам было бы нужно? n n Что нужно было бы получить? n n n prob. A prob. B n Число игр, выигранных игроком А Число игр, выиграных игроком Б Эти числа должны быть результатом работы функции sim. NGames. Python Programming, 2/e 31
Проектирование сверху вниз n Мы знаем, что основная программа должна выглядеть таким образом: def main(): print. Intro() prob. A, prob. B, n = get. Inputs() wins. A, wins. B = sim. NGames(n, prob. A, prob. B) n n Какие данные нужно получить, чтобы программа продолжила работу? Нужно знать количество выигрышей у каждого игрока – это будут входные данные для следующей функции. Python Programming, 2/e 32
Проектирование сверху вниз n Полностью основная программа выглядит следующим образом: def main(): print. Intro() prob. A, prob. B, n = get. Inputs() wins. A, wins. B = sim. NGames(n, prob. A, prob. B) print. Summary(wins. A, wins. B) Python Programming, 2/e 33
Разделение задач n Первоначальная задача была поделена на четыре независимые задачи: n n n print. Intro get. Inputs sim. NGames print. Summary Для этих функций определили имена, параметры, и возвращаемые значения. Эти данные называются интерфейсом или сигнатурой функции. Python Programming, 2/e 34
Разделение задач n n Зная сигнатуры функций, над отдельными частями программы можно работать независимо. Например, что касается программы main, то для нас неважно как работает функция sim. NGames только бы по заданным вероятностям и количеству игр она бы выдавала правильное число побед каждого игрока. Python Programming, 2/e 35
Разделение задач n n n В структурной схеме (или иерархии модулей) каждый компонент проекта изображается прямоугольником. Отрезок, соединяющий прямоугольники, указывает, что прямоугольник, который расположен выше использует прямоугольник, расположенный ниже. . Стрелки и аннотации показывают интерфейсы между компонентами. Python Programming, 2/e 36
Разделение задач Python Programming, 2/e 37
Разделение задач n n n На каждом уровне проектирования интерфейс говорит нам какие детали более низкого уровня важны. Общий процесс определения важных характеристик чего-то и игнорирование прочих деталей называется абстрагированием. Проектирование сверху вниз это методичный процесс нахождения полезных абстракций. Python Programming, 2/e 38
Проектирование второго уровня n n На следующем шаге повторяем процесс для каждого модуля, определённого на предыдущем шаге. Функция print. Intro должна печатать введение к программе. Написание кода функции не вызывает затруднений. Python Programming, 2/e 39
Проектирование второго уровня def print. Intro(): # Печатает введение к программе print("Эта программа моделирует игру в рэкетбол между игроками ") print('называемыми "A" и "Б". Способности каждого игрока') print("задаются вероятностями (числами между 0 и 1) с которыми") print("tигроки выигрывают розыгрыш при своей подаче. Игрок A ") print("всегда подаёт первую подачу в игре. n“) n n Вторая строка заключена в апострофы, так как мы используем кавычки внутри строки. Так как нет новых функций, то нет и изменений в схеме. Python Programming, 2/e 40
Проектирование второго уровня В функции get. Inputs, мы просим и получаем три значения, которые возвращаем в основную программу. . def get. Inputs(): # ВОЗВРАЩАЕТ prob. A, prob. B, число игр a = eval(input("С какой вер-тью игрок А выигрывает подачу? ")) b = eval(input("С какой вер-тью игрок Б выигрывает подачу? ")) n = eval(input("Сколько игр нужно смоделировать? ")) return a, b, n Python Programming, 2/e 41
Проектирование sim. NGames n n Эта функция моделирует n игр и ведёт учет, сколько раз победил каждый из игроков. “Моделирует n игр” звучит как определённый цикл, а ведёт учет побед, как хорошая работа для переменнойнакопителя. Python Programming, 2/e 42
Проектирование sim. NGames n Инициализируем wins. A и wins. B в 0 цикл n раз моделируем игру если игрок A выигрывает прибавь 1 к wins. A иначе прибавь 1 к wins. B Python Programming, 2/e 43
Проектирование sim. NGames n У нас уже есть сигнатура функции: def sim. NGames(n, prob. A, prob. B): # Моделируем n игр в рэкетбол между игроками А и Б # ВОЗВРАЩАЕТ число побед игрока А и число побед игрока Б n С этими данными легко начать. def sim. NGames(n, prob. A, prob. B): # Моделируем n игр в рэкетбол между игроками А и Б # ВОЗВРАЩАЕТ число побед игрока А и число побед игрока Б wins. A = 0 wins. B = 0 for i in range(n): Python Programming, 2/e 44
Проектирование sim. NGames n n n Следующая вещь, которую мы должны сделать это смоделировать игру в рэкетбол. Мы пока не знаем как это сделать, поэтому отложим на попозже. Предположим, что функция sim. One. Game может это делать. Ввод в функцию sim. One. Game – вероятности для каждого игрока. Каков вывод у функции? Python Programming, 2/e 45
Проектирование sim. NGames n n n Нам нужно узнать кто выиграл игру. Как получить эти данные? Простейший способ узнать окончательный счет. Игрок с большим счетом выигрывает и его накопитель побед увеличивается на 1. Python Programming, 2/e 46
Проектирование sim. NGames def sim. NGames(n, prob. A, prob. B): # Моделирует n игр в рэкетбол между игроками А и Б # ВОЗВРАЩАЕТ число побед A, число побед Б wins. A = wins. B = 0 for i in range(n): score. A, score. B = sim. One. Game(prob. A, prob. B) if score. A > score. B: wins. A = wins. A + 1 else: wins. B = wins. B + 1 return wins. A, wins. B Python Programming, 2/e 47
Проектирование sim. NGames Python Programming, 2/e 48
Проектирование третьего уровня n n Следующая функция, которую нам нужно написать это sim. One. Game, в ней содержатся правила игры в рэкетбол. Игроки разыгрывают мячи до тех пор пока окончится игра, что предполагает использование неопределённого цикла, потому что мы заранее не знаем продолжительность игры. Python Programming, 2/e 49
Проектирование третьего уровня n n Мы также должны следить за счетом и за тем, кто подаёт. Счет храним в двух накопителях, а как следить за тем, кто подаёт? Один из подходов воспользоваться переменной типа цепочка, со значениями “A” и “Б”. Python Programming, 2/e 50
Проектирование третьего уровня n Инициализируем счет в 0 Подаёт “A” Цикл пока игра не закончится: моделируем подачу игрока, который подаёт актуализируем статус игры Возвращаем счет n Def sim. One. Game(prob. A, prob. B): score. A = 0 score. B = 0 serving = “A” while
Проектирование третьего уровня Python Programming, 2/e 52
Проектирование третьего уровня n n В этой точке функция sim. One. Game выглядит так: Def sim. One. Game(prob. A, prob. B): score. A = 0 score. B = 0 serving = “A” while not game. Over(score. A, score. B): Python Programming, 2/e 53
Проектирование третьего уровня n n В цикле мы должны сделать одну подачу. Мы сравним случайное число с имеющейся вероятностью, чтобы определить выиграл ли подающий (random() < prob). Вероятность, которую мы сравниваем определяется подающим, кто подаёт определяется значением переменной serving. Python Programming, 2/e 54
Проектирование третьего уровня n n Если подаёт A, то мы используем prob. A, и основываясь на результате подачи то ли увеличиваем счет у A, то ли передаём подачу Б. if serving == "A": if random() < prob. A: score. A = score. A + 1 else: serving = "Б" Python Programming, 2/e 55
Проектирование третьего уровня n n Аналогично, если подаёт Б, мы делаем то же самое с игроком Б, меняя в коде буквы «А» и «Б» . if serving == "A": if random() < prob. A: score. A = score. A + 1 else: serving = "B“ else: if random() < prob. B: score. B = score. B + 1 else: serving = "A" Python Programming, 2/e 56
Проектирование третьего уровня Собираем функции вместе: def sim. One. Game(prob. A, prob. B): # Моделируем одну игру в рэкетбол между игроками А и Б. # ВОЗВРАЩАЕТ окончательный счет игры A и Б serving = "A" score. A = 0 score. B = 0 while not game. Over(score. A, score. B): if serving == "A": if random() < prob. A: score. A = score. A + 1 else: serving = " Б" else: if random() < prob. B: score. B = score. B + 1 else: serving = "A" return score. A, score. B Python Programming, 2/e 57
Доводка n Осталась написать одну функцию game. Over. Вот что мы знаем: def game. Over(a, b): # a и b задают счет между игроками А и Б # ВОЗВРАЩАЕТ true, если игра закончена, false в противном случае n Согласно правилам, игра закончена, когда один из игроков наберёт 15 очков. Это можно проверить булевым выражением: a==15 or b==15 Python Programming, 2/e 58
Доводка n Поэтому полный код функции game. Over выглядит так: def game. Over(a, b): # a и b задают счет между игроками А и Б # ВОЗВРАЩАЕТ true, если игра закончена, false # в противном случае return a == 15 or b == 15 n Функция print. Summary тоже проста. def print. Summary(wins. A, wins. B): # Печатает число побед каждого игрока. n = wins. A + wins. B print "n. Число смоделированных игр: ", n print "Побед у A: {0} ({1: 0. 1%})". format(wins. A, wins. A)/n) print "Побед у B: {0} ({1: 0. 1%})". format(wins. B, wins. B/n) n Заметьте знак % при форматировании вывода Python Programming, 2/e 59
Обзор процесса проектирования n n n Мы начали на самом высоком уровне схемы программы и проделали весь путь вниз. На каждом уровне мы начинали с общего алгоритма и уточняли его до точного кода. Этот процесс иногда называется пошаговым уточнением. Python Programming, 2/e 60
Обзор процесса проектирования 1. 2. 3. 4. Выразите алгоритм как последовательность более мелких проблем. Разработайте интерфейс для каждой из более мелких проблем. Опишите алгоритм в терминах его интерфейсов с более мелкими проблемами. Повторите процесс для каждой из более мелких проблем. Python Programming, 2/e 61
Реализация снизу вверх n n Хотя мы были очень внимательны в процессе проектирования, у нас нет гарантий, что мы не совершили ошибок. Реализовывать лучше всего маленькими кусками. Python Programming, 2/e 62
Тестирование элементов программы n n Хорошим способом планомерного тестирования реализации программы скромного размера является тестирование компонентов программы, начиная с самого нижнего уровня, по мере их появления. Например, мы можем импортировать нашу программу и выполнить различные подпрограммы/функции, чтобы убедиться в правильности их работы. Python Programming, 2/e 63
Тестирование элементов программы n n Мы могли бы начать с функции game. Over. >>> import rball >>> rball. game. Over(0, 0) False >>> rball. game. Over(5, 10) False >>> rball. game. Over(15, 3) True >>> rball. game. Over(3, 15) True Python Programming, 2/e 64
Тестирование элементов программы n Заметьте, что мы протестировали функцию game. Over во всех важных случаях. n n n Мы дали счет (0, 0) как это будет при первом вызове функции. Второй тест для середины игры и функция правильно ответила, что игра еще не закончена. В последних двух случаях мы протестировали выигрыш каждого из игроков. Python Programming, 2/e 65
Тестирование элементов программы Теперь когда мы видим, что функция game. Over работает переходим к sim. One. Game. >>> sim. One. Game(. 5, (11, 15) >>> sim. One. Game(. 5, (13, 15) >>> sim. One. Game(. 3, (11, 15) >>> sim. One. Game(. 3, (15, 4) >>> sim. One. Game(. 4, (2, 15) >>> sim. One. Game(. 4, (1, 15) >>> sim. One. Game(. 9, (15, 0) >>> sim. One. Game(. 4, (10, 15) >>> sim. One. Game(. 4, (9, 15) . 5). 3). 9). 4). 6) Python Programming, 2/e 66
Тестирование элементов программы n n Когда вероятности равны, то счет отличается не сильно. Когда вероятности отличаются больше, то получаем сокрушительное поражение. Тестирование каждого компонента называется блочным, модульным или компонентным тестированием. Тестирование по отдельности каждой функции облегчает поиск ошибок и способствует гладкому прохождению тестирования. Python Programming, 2/e 67
Результаты моделирования n n n Заложено ли в природу рэкетбола, что небольшая разница в уровне игры ведёт к большой разнице в счете? Допустим, что Денис выигрывает 60% своих подач, а противник на 5% больше. Как часто Денис должен выигрывать? Давайте смоделируем игру, в которой противник Дениса подаёт первым. Python Programming, 2/e 68
Результаты моделирования Эта программа моделирует игру в рэкетбол между двумя игроками, называемыми "A" и "B". Способности каждого игрока к игре указываются вероятностью (число между 0 and 1), с которой игрок выигрывает розыгрыш мяча при своей подаче. Игрок A всегда подаёт первым. has the first serve. Какова вер-ть игрока А выиграть подачу? Какова вер-ть игрока Б выиграть подачу? Сколько игр смоделировать? 5000 . 65. 6 Games simulated: 5000 Wins for A: 3329 (66. 6%) Wins for B: 1671 (33. 4%) n С такой небольшой разницей в умении Денис выигрывает только одну игру из 3! Python Programming, 2/e 69
Другие методики проектирования Проектирование сверху вниз не единственный способ создавать программы. Python Programming, 2/e 70
Прототипирование и спиральная разработка n n Другой подход к разработке программ заключается в том, что разработка программы начинается с простой версии программы, затем постепенно добавляются новые возможности до тех пор пока программа не будет удовлетворять всем требованиям. Начальная упрощенная версия программы называется прототипом. Python Programming, 2/e 71
Прототипирование и спиральная разработка n n Прототипирование часто приводит к спиральному процессу разработки. Не охватывая всю проблему целиком, её детальное описание, её проект и её реализацию, мы сначала проектируем реализуем и тестируем прототип. Мы осуществляем много минициклов в процессе разработки по мере того как прототип приращениями доводится до финальной версии программы. Python Programming, 2/e 72
Прототипирование и спиральная разработка n Как моделирование рэкетбола можно осуществить с помощью спиральной разработки? n n Напишите прототип, в котором предполагается, что с вероятностью 50 -50 разыгрывается каждый мяч и играют до 30 розыгрышей. Постепенно добавляем к прототипу, включая присуждаемые очки, смену подачи, разные вероятности и т. д. Python Programming, 2/e 73
Прототипирование и спиральная разработка from random import random def sim. One. Game(): score. A = 0 score. B = 0 serving = "A" for i in range(30): if serving == "A": if random() <. 5: score. A = score. A + 1 else: serving = "B" else: if random() <. 5: score. B = score. B + 1 else: serving = "A" print(score. A, score. B) >>> sim. One. Game() 0 0 0 1 … 2 7 2 8 3 8 3 9 4 9 5 9 Python Programming, 2/e 74
Прототипирование и спиральная разработка n Программу можно улучшать постепенно: n n Фаза 1: Начальный прототип. Играем 30 розыгрышей, подающий выигрывает с вероятностью 0. 5. Печатаем счет после каждого розыгрыша. Phase 2: Добавляем два параметра, чтобы представлять разные вероятности выиграть подачу у двух игроков. Python Programming, 2/e 75
Прототипирование и спиральная разработка n n n Фаза 3: Играем до тех пор пока один из игроков не наберёт 15 очков. В этой точке у нас есть модель одной игры. Фаза 4: Расширяем программу до многократных игр. На выходе считаем игрв выигранные каждым игроком. Фаза 5: Строим полную программу. Добавляем интерактивный ввод и красиво форматируем отчет о результатах. Python Programming, 2/e 76
Прототипирование и спиральная разработка n n Спиральная разработка полезна, когда разработка связана с неизвестными элементами или технологиями. Если разработка сверху вниз у вас не работает, то попробуйте спиральную разработку. Python Programming, 2/e 77
Искусство проектирования n n Спиральная разработка не альтернатива проектированию сверху вниз, а скорее добавление к нему – когда проектируется прототип, то используется техника сверху вниз. Хороший проект это и творчество и наука, здесь нет твёрдо установленных правил. Python Programming, 2/e 78
Искусство проектирования n n Хотите узнать три самых полезных совета? Практикуйтесь, практикуйтесь. Python Programming, 2/e 79