ответвлено от main/python
193 строки
11 KiB
Markdown
193 строки
11 KiB
Markdown
---
|
||
title: Комментарии к пособию
|
||
author: Дмитрий Козлюк
|
||
date: 2024-10-07
|
||
---
|
||
|
||
## Тема 3
|
||
|
||
### 5.1
|
||
|
||
Почему `~9` дает `-10`, а не `-9`?
|
||
|
||
1. Двоичные числа в компьютере представлены в [дополнительном коде][complement].
|
||
|
||
2. Если числа представлены $N$ битами, то в дополнительном коде число $(-X)$
|
||
представляется как $2^N - X$, что легко видеть на рисунке:
|
||
|
||

|
||
|
||
3. Можно заметить, что `~X` есть то же самое, что `(2**N - 1) - X`,
|
||
потому что при вычитании из `11....11` все 0 заменяются на 1 и наоборот.
|
||
Итого `~X` имеет то же битовое представление, что и `-(X+1)`.
|
||
|
||
Иначе это можно видеть из рисунка:
|
||
$9$ есть десятое число, если двигаться в сторону положительных,
|
||
а $(-10)$ есть десятое число, если двигаться в сторону отрицательных.
|
||
|
||
[complement]: https://ru.wikipedia.org/wiki/%D0%94%D0%BE%D0%BF%D0%BE%D0%BB%D0%BD%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4
|
||
|
||
## Тема 4
|
||
|
||
### 2.4, 2.5
|
||
|
||
> Похожая на eval функция exec – чтение и выполнение объекта-аргумента функции.
|
||
>
|
||
> exec(input('введите инструкции='))
|
||
|
||
Вопреки написанному, `exec()` не занимается считыванием ввода пользователя.
|
||
Вместо `input()` аргумент `exec()` мог бы быть переменной
|
||
или фиксированной строкой;
|
||
и наоборот, аргументом `eval()` мог бы быть пользовательский ввод.
|
||
|
||
Отличие `eval()` от `exec()` в том,
|
||
что `eval()` вычисляет выражение (expression),
|
||
а `exec()` выполняет инструкции (statements).
|
||
Выражения — подмножество инструкций, отличающееся наличием результата.
|
||
Например, `1`, `1+2`, `a+3` — выражения,
|
||
а присваивание или условный оператор — инструкции.
|
||
|
||
Единственное адекватное использование `eval()` на практике —
|
||
вычисление по выражению, заданному пользователем.
|
||
[Никогда][kungfu] не используйте `exec()` в реальных задачах (пока эти советы вам нужны).
|
||
На занятиях используйте `exec()` только если задание явно это подразумевает,
|
||
например, требуется создать заранее неизвестное количество переменных.
|
||
|
||
[kungfu]: http://rsdn.org/forum/info/FAQ.philosophy.kungfu
|
||
|
||
### 5
|
||
|
||
Функция `random.seed()` инициализирует начальное состояние генератора
|
||
псевдослучайных чисел.
|
||
|
||
В обычном компьютере нет ничего случайного.
|
||
Как же работает `random.random()`?
|
||
Используется генератор *псевдослучайных* чисел (ГПСЧ):
|
||
есть скрытое состояние (переменная в модуле `random`),
|
||
на основе которого генерируется очередной результат `random.random()`,
|
||
а само состояние обновляется.
|
||
Генерация устроена так, что распределение результатов близко к равномерному.
|
||
Очевидно, что последовательность полностью определяется начальным состоянием.
|
||
Оно и называется seed (англ. «семечко»), по-русски — затравка.
|
||
Если вызвать `random.seed()` без параметров или не вызывать ее,
|
||
начальное состояние будет зависеть от текущего времени
|
||
или от времени запуска программы.
|
||
|
||
Зачем задавать начальное состояние, иначе говоря, зачем может понадобиться
|
||
зафиксировать последовательность, которую выдает `random.seed()`?
|
||
|
||
* **Воспроизводимость результатов.**
|
||
Если программа моделирует что-то, используя случайные числа,
|
||
то желательно, чтобы результаты были одинаковы при каждом запуске.
|
||
Тогда исследователи могут повторять и проверять эксперименты друг друга.
|
||
Например, статьи по машинному обучению часто начинаются с задания seed.
|
||
|
||
* **Компактное представление случайных параметров.**
|
||
Если программа генерирует что-либо с большим количеством случайных
|
||
параметров, она может не сохранять их все, а сохранить только seed,
|
||
параметры же сгенерировать снова при следующем запуске.
|
||
Так генерируются игровые миры в Minecraft и Dwarf Fortress.
|
||
|
||
[Аналогичное объяснение, которое иногда находят и присылают.][random.seed]
|
||
|
||
[random.seed]: https://docs-python.ru/standart-library/modul-random-python/initsializatsija-sostojanie-generatora
|
||
|
||
## Тема 5
|
||
|
||
### 3.5
|
||
|
||
Такая конструкция называется list comprehension, а не «запись цикла в строке».
|
||
Внутри квадратных скобок записано выражение-генератор (см. тему 4).
|
||
|
||
## Тема 6
|
||
|
||
### 2.2
|
||
|
||
Насчет псевдокомментария `# -*- coding: utf-8 -*-`
|
||
|
||
Как и любой текст, код в файле `*.py` может быть в разных кодировках.
|
||
По умолчанию Python ожидает кодировку UTF-8.
|
||
Таким образом, указывать псевдокомментарий выше бессмысленно —
|
||
он требует от Python сделать то, что делается и без псевдокомментариев.
|
||
Имеет смысл использовать UTF-8 для своих программ.
|
||
Если же по какой-то причине файл сохранен, например, в кодировке Windows-1251,
|
||
псевдокомментарий будет `# -*- coding: windows-1251 -*-`.
|
||
Если его не поставить, а в коде есть символы кириллицы,
|
||
интерпретация завершится с ошибкой:
|
||
|
||
```
|
||
SyntaxError: Non-UTF-8 code starting with '\x...' in file ...
|
||
```
|
||
|
||
Кодировка программы не влияет на ее возможность работы с кириллицей,
|
||
только на использование кириллицы в коде программы, в том числе в комментариях.
|
||
|
||
### 2.3
|
||
|
||
Обратите внимание, что при вызове `sys.stdout.write()`
|
||
печатается не только аргумент функции, но и некоторое число.
|
||
Разберитесь, что это за число и почему оно печатается.
|
||
|
||
### 4.4
|
||
|
||
Частая ошибка: `fp.close` вместо `fp.close()`.
|
||
Первое выражение не вызывает метод `close()`, поэтому файл остается открытым.
|
||
|
||
На практике для работы с файлами рекомендуется конструкция `with`:
|
||
|
||
```python
|
||
with open('path', 'r') as fp:
|
||
... # работа с fp
|
||
# блок with окончен, fp автоматически закрыт
|
||
```
|
||
|
||
### ОКЗ
|
||
|
||
В последнем пункте каждый список должен быть занесен в отдельную переменную,
|
||
имя которой формируется динамически.
|
||
|
||
## Тема 7
|
||
|
||
### 4.8, 4.8
|
||
|
||
О синтаксисе аргументов с одной (`*args`) или двумя (`**kwargs`) звездочками
|
||
можно найти сведения по запросу «keyword arguments».
|
||
|
||
### 6
|
||
|
||
Никогда не используйте глобальные переменные, кроме констант.
|
||
Иначе ни про какой вызов функции нельзя будет сказать, что он сделает,
|
||
ориентируясь на аргументы, потому что еще может быть зависимость
|
||
от текущего значения глобальной переменной.
|
||
Это крайне затрудняет понимание и отладку программ.
|
||
|
||
### ОКЗ, пункт 2
|
||
|
||
Рекомендуется проверить построение гистограммы на таких списках:
|
||
|
||
* `list(range(1, 8))`
|
||
* `list(range(1, 9))`
|
||
|
||
## Тема 8
|
||
|
||
### 2.3
|
||
|
||
При использовании `import` Python по умолчанию считает,
|
||
что файл имеет кодировку UTF-8, а также учитывает псевдокомментарии.
|
||
При использовании `open()` Python считает, что у файла «системная» кодировка,
|
||
которая в Linux обычно UTF-8, а в Windows — UTF-16.
|
||
Поэтому, если файл в UTF-8, то нужно передать `open()` дополнительный аргумент
|
||
для указания кодировки (найдите его в справке), иначе код модуля будет выполнен,
|
||
но вместо кириллицы будут кракозябры.
|
||
|
||
### 3.3
|
||
|
||
Обратите внимание: нужно именно изменить `Mod1.perm1`,
|
||
а не взять ее значение, умножить на три и вывести либо присвоить
|
||
новой переменной.
|
||
|
||
## Тема 9
|
||
|
||
Будьте готовы объяснить, что дает программисту использование классов
|
||
по сравнению с использованием функций.
|