
Доброе время суток, хабравчане. Несмотря на глубокое название поста, суть его состоит в описании борьбы с собственной глупостью в решении уже изученных проблем. Последнее время часто размышлял над темой «случайность». Что же задает эту самую случайность? Ввиду того, что люблю до всего доходить сам — не полез в поисковики, а полез в Python.
Первым, в голову пришел следующий алгоритм:
1) Получить некоторое количество случайных чисел.
2) Узнать сколько в каждом случайном числе чисел «0», «1», «2» и т. д.
3) Подсчитать сумму этих чисел.
4) Для наглядности построить диаграмму.
Результатом я был по своей глупости крайне удивлен:

Почему количество нолей так заметно превышает количество всех остальных цифр? Ответ был прост, но о нем немного позже.
Я решил увеличить количество случайных чисел, заранее подозревая, что количество будет выравниваться.
Однако картина, которую я лицезрел была пугающей:


Вопрос после такого сразу возник к коду, в котором «рандомное» число генерируется как:
while ii<kol: a = random.random() z = str(a) L = len(z) i = 0 while i <L: if z[i]=="0": s0 +=1 elif z[i]=="1": s1 +=1 elif z[i]=="2": s2 +=1 elif z[i]=="3": s3 +=1 elif z[i]=="4": s4 +=1 elif z[i]=="5": s5 +=1 elif z[i]=="6": s6 +=1 elif z[i]=="7": s7 +=1 elif z[i]=="8": s8 +=1 elif z[i]=="9": s9 +=1 i+=1 ii +=1
Думаю вы уже догадались, в чем была моя первая ошибка? А была она в random.random(), возвращающей случайное число от 0 до 1 с определенным количеством знаков после запятой.
На этом дело не закончилось. Исправив ошибку:
... while ii<kol: a = random.random() z = str(a) l = len(z) i = 2 while i <L: if z[i]=="0": s0 +=1 elif z[i]=="1": ...
Получил следующую картину «рандома»:

Эта ситуация не менялась с увеличением количества чисел. Однако и здесь ответ крылся вовсе не в теории, а опять же в реализации. Догадались?
Дело в том, что Python округляет число, полученное с помощью random.random(). Достаточно легко понять, что при округлении, «округлиться в 0» шансов гораздо меньше, чем «округлиться в любое другое число». Т.к. для того, чтобы «округлиться в 0», необходимо, чтобы предпоследняя цифра случайного числа была 9. И этот шанс — 1 к 10.
«Подлечив» код:
while ii<kol: a = random.random() z = str(a) l = len(z) i = 2 while i <L-1: if z[i]=="0": s0 +=1 elif z[i]=="1":

