from random import randint

class Die():

. ."""Класс, представляющий один кубик."""

. .

(1) . .def __init__(self, num_sides=6):

. . . ."""По умолчанию используется шестигранный кубик."""

. . . .self.num_sides = num_sides

. . . .

. .def roll(self):

. . . .""""Возвращает случайное число от 1 до числа граней."""

(2) . . . .return randint(1, self.num_sides)

Метод __init__() получает один необязательный аргумент. Если при создании экземпляра кубика аргумент с количеством сторон не передается, по умолчанию создается шестигранный кубик. Если же аргумент присутствует, то переданное значение используется для определения количества граней (1) . (Кубики принято обозначать по количеству граней: шестигранный кубик — D6, восьмигранный — D8 и т.д.)

Метод roll() использует функцию randint() для получения случайного числа в диапазоне от 1 до количества граней (2). Функция может вернуть начальное значение (1) , конечное значение (num_sides) или любое целое число в этом диапазоне.

<p>Бросок кубика</p>

Прежде чем строить визуализацию на основе этого класса, бросим кубик D6, выведем результаты и убедимся в том, что они выглядят разумно:

die_visual.py

from die import Die

# Создание кубика D6.

(1) die = Die()

# Моделирование серии бросков с сохранением результатов в списке.

results = []

(2)for roll_num in range(100):

. .result = die.roll()

. .results.append(result)

. .

print(results)

В точке (1) создается экземпляр Die с шестью гранями по умолчанию. В точке (2) моделируются 100 бросков кубика, а результат каждого броска сохраняется в списке results. Выборка выглядит примерно так:

[4, 6, 5, 6, 1, 5, 6, 3, 5, 3, 5, 3, 2, 2, 1, 3, 1, 5, 3, 6, 3, 6, 5, 4,

1, 1, 4, 2, 3, 6, 4, 2, 6, 4, 1, 3, 2, 5, 6, 3, 6, 2, 1, 1, 3, 4, 1, 4,

3, 5, 1, 4, 5, 5, 2, 3, 3, 1, 2, 3, 5, 6, 2, 5, 6, 1, 3, 2, 1, 1, 1, 6,

5, 5, 2, 2, 6, 4, 1, 4, 5, 1, 1, 1, 4, 5, 3, 3, 1, 3, 5, 4, 5, 6, 5, 4,

1, 5, 1, 2]

Беглое знакомство с результатами показывает, что класс Die работает. В результатах встречаются граничные значения 1 и 6, то есть модель возвращает наименьшее и наибольшее возможное значение; значения 0 и 7 не встречаются, а значит, все результаты лежат в диапазоне допустимых значений. Также в выборке встречаются все числа от 1 до 6, то есть представлены все возможные результаты.

<p>Анализ результатов</p>

Чтобы проанализировать результаты бросков одного кубика D6, мы подсчитаем, сколько раз выпадало каждое число:

die_visual.py

...

# Моделирование серии бросков с сохранением результатов в списке.

results = []

(1) for roll_num in range(1000):

result = die.roll()

results.append(result)

# Анализ результатов.

frequencies = []

(2)for value in range(1, die.num_sides+1):

(3) . .frequency = results.count(value)

(4) . .frequencies.append(frequency)

. .

print(frequencies)

Так как Pygal используется для анализа, а не для вывода результатов, количество моделируемых бросков можно увеличить до 1000 (1) . Для анализа создается пустой список frequencies, в котором хранится количество выпадений каждого значения. Программа перебирает возможные значения (от 1 до 6 в данном случае) в цикле (2), подсчитывает количество вхождений каждого числа в результатах (3), после чего присоединяет полученное значение к списку frequencies (4). Содержимое списка выводится перед построением визуализации:

[155, 167, 168, 170, 159, 181]

Результаты выглядят разумно: мы видим все шесть частот, по одной для каждого возможного результата при броске D6, и ни одна из частот не выделяется на общем фоне. А теперь займемся наглядным представлением результатов.

<p>Построение гистограммы</p>

Имея список частот, можно построить гистограмму результатов. Гистограмма представляет собой столбцовую диаграмму, наглядно отображающую относительные частоты результатов. Код построения гистограммы выглядит так:

die_visual.py

import pygal

...

# Анализ результатов.

frequencies = []

for value in range(1, die.num_sides+1):

frequency = results.count(value)

frequencies.append(frequency)

. .

# Визуализация результатов.

(1) hist = pygal.Bar()

hist.title = "Results of rolling one D6 1000 times."

(2)hist.x_labels = ['1', '2', '3', '4', '5', '6']

hist.x_title = "Result"

hist.y_title = "Frequency of Result"

(3)hist.add('D6', frequencies)

hist.render_to_file('die_visual.svg')

Чтобы построить столбцовую диаграмму, мы создаем экземпляр pygal.Bar(), который сохраняется в переменной hist (1) . Затем мы задаем атрибут title объекта hist (обычная строка, используемая как заголовок гистограммы), используем возможные результаты броска D6 как метки оси x (2), а также добавляем надпись для каждой из осей. Метод add() используется для добавления на гистограмму серии значений (3) (при этом ему передается метка для добавляемого набора и список значений, отображаемых на диаграмме). Наконец, диаграмма записывается в файл SVG, что предполагает имя файла с расширением .svg.

Перейти на страницу:

Все книги серии Библиотека программиста

Похожие книги