Типы данных. Целые и вещественные числа. Случайные числа.
10 класс, углублённый уровень — занятие третье.
В прошлый раз мы смотрели, как программа выполняется. Сегодня — из чего сделаны значения, которыми она оперирует, и где каждый тип подводит того, кто об этом не думает.
int x = 5;
x = "пять"; // ошибка до запуска
Тип объявляется у переменной и закреплён за ней навсегда. Это статическая типизация.
x = 5
x = "пять" # можно
print(type(x)) <class 'str'>
Тип принадлежит значению, переменная — имя, привязанное к нему. Это динамическая типизация.
| Тип | Что хранит | Как получить |
|---|---|---|
int | целые | int("7"), a // b, round(x) |
float | вещественные | float("3.5"), a / b |
str | строки | input(), str(5), кавычки |
bool | True / False |
любое сравнение, bool(x) |
В C++ есть ещё символьный тип char — один символ. В Python
его нет: символ — это строка длины 1. Код символа даёт
ord("A") = 65, символ по коду — chr(66) = "B".
print(17 // 5, 17 % 5) 3 2
print(-17 // 5, -17 % 5) -4 3 # не -3 и не -2!
Python округляет частное вниз, к минус бесконечности, а остаток подбирает так, чтобы тождество держалось всегда:
a == (a // b) * b + a % b
−17 = −4·5 + 3
Остаток при положительном делителе — всегда от 0 до b−1. Поэтому
n % 10 у отрицательного числа — не его последняя цифра.
print(divmod(17, 5)) (3, 2) # сразу оба
print(2 ** 100) 1267650600228229401496703205376
Целое в Python не ограничено размером. В C++ обычный int —
32 бита, максимум 2 147 483 647, дальше переполнение.
n % 10 # последняя
n // 10 # отрезать её
if n % d == 0:
print(d, "делитель")
% — это задание 25 ЕГЭ. Сегодня
первая программа практикума ровно про это: все делители числа.
print(0.1 + 0.2) 0.30000000000000004
print(0.1 + 0.2 == 0.3) False
Это не ошибка Python. В десятичной системе 1/3 — бесконечная дробь 0,3333… В двоичной так же бесконечна дробь 0,1:
Число хранится в 64 битах, около 16 верных десятичных знаков, — и обрезается. Сумма двух обрезанных чисел не обязана совпасть с третьим.
total = 0.7 + 0.1 # курьер проехал 0.7 и 0.1 км
plan = 0.8
print(total >= plan) False # 0.7999999999999999
abs(a - b) < 0.000001
total + 0.000001 >= plan
round(a, 2) == round(b, 2)
round(total, 2) >= plan
Деньги, километры, проценты — всё, что считают с дробями, сравнивают только так. Оболочка сегодня подаст ровно такие данные.
print(round(2.5), round(3.5)) 2 4
print(int(3.9), int(-3.9)) 3 -3
print(f"{2.5:.2f}") 2.50
| Что | Делает | Тип результата |
|---|---|---|
round(x) | к ближайшему целому; ровно половина — к чётному | int |
round(x, 2) | до двух знаков | float |
int(x) | отбрасывает дробную часть, не округляет | int |
f"{x:.2f}" | меняет вид, а не число: 2.5 → "2.50" | str |
print(6 / 3) 2.0
print(6 // 3) 2
print(7 // 2.0) 3.0 # делитель вещественный — и результат тоже
print(1.5 + 2) 3.5 # int + float = float
2.0 — это не то же самое, что
2, когда ответ читает машина.
a = input() # ввели 5
print(a + a) 55
print(a * 3) 555
print(a + 1) TypeError
print("9" > "10") True # строки сравниваются как слова в словаре
int("5") 5
float("3.5") 3.5
int("5.0") ValueError
float("3,5") ValueError
str(5) '5'
str(2.5) '2.5'
len(str(1234)) 4
input() возвращает строку всегда. Запятая в дробном —
ошибка: Python ждёт точку.
print(3 == 3.0, "3" == 3) True False
print(True + True) 2
print(bool(0), bool("0")) False True
print(1 < 7 < 10) True
bool — подвид целого: True хранится как 1,
False как 0. Их можно складывать.bool(x): ноль и пустая строка — False, всё
остальное — True. Строка "0" не пустая.1 < x < 10 — это 1 < x and x < 10.Которые на самом деле не случайные.
from random import * # функции зовём по имени, без random.
randint(1, 6) # целое от 1 до 6, ОБА конца входят
randrange(1, 6) # от 1 до 5 — как range
random() # вещественное от 0 включительно до 1 не включая
randrange(0, 100, 5) # от 0 до 95 с шагом 5
seed(7) # закрепить начало: дальше числа одни и те же
randrange(1, 6) шестёрку не даст
никогда, а randint(1, 6) даст. Кубик — это
randint. И вторая: после from random import *
своей переменной нельзя дать имя функции — seed = 5 затрёт
seed().
Случайности внутри компьютера нет. Есть формула.
x = (x * 1664525 + 1013904223) % 2**32 # следующее из предыдущего
Каждое следующее число вычисляется из предыдущего. Значит, всё зависит от первого — его называют seed. Обычно seed берётся от часов, и запуски различаются.
seed(42)
print(randint(1, 100), randint(1, 100)) 82 15
seed(42)
print(randint(1, 100), randint(1, 100)) 82 15 # те же
Двенадцать коротких программ: какого типа результат, что напечатает — с целыми, вещественными, строками, логическими и случайными.
Считаем в уме и на бумаге. Ответ — ровно то, что на экране:
2.0 и 2 — разные ответы.
Сохраняем в свою папку как zadanie1.py …
zadanie3.py.
| Что | Где | Сколько |
|---|---|---|
| Тренажёр | практикум, наверху страницы | 15 минут |
| Три программы | IDLE | 30 минут |
| Проверка | Проверка.bat | попыток сколько угодно |
seed(start) обязателен.
Открывайте практикум. Начинаем с тренажёра.
Застряли на программе — не угадывайте. Посмотрите на тип каждого значения: целое, вещественное, строка. Половина ошибок сегодня будет именно в этом.