11.22 Работа с файлами
Просто файлы
- текстовые и бинарные файлы (остальное вроде бы очевидно)
 
 Открытие двоичного файла с русским текстом, чтение по байту оттуда  
 поменять местами половины бинарного файла 
 Вывести первую треть текстового файла, довыведя последнюю строку целиком (до "\n") 
Кодировки
- Кодировки — в файлах или I/O, а некий вариант unicode (UCS16) — внутри Python 
locale.getdefaultlocale()
 encdode() и .decode()
 преобразовать слово "вопрос" в "БНОПНЯ" с помощью encdode() и decode(), получить тем же способом "бМХЛЮМХЭ" и оХРЮМХЕ (используются кодировки cp1251 и koi8-r) 
Сериализация
Pickle
 простые примеры dump()/load() 
 поглядеть глазками protocol=0 
 класс с сериализацией реализуйте класс SerCls с полями lst (список), dct (словарь), num (число), st (строка)
cоздайте экземпляр ser этого класса с непустым наполнением всех полей
сериализуйте ser в строку, удалите ser
десериализуйте строку в новый экземпляр ser1 класса SerCls
Типизированные бинарные файлы
Применение, язык описания структур
проблемы: порядок байтов и выравнивание
 Заполнить двоичный файл 10-ю случайными тройками float, bytes[3], int 
 Прочитать тройки float, bytes[3], int из файла, записать их в файл с сетевым порядком байтов 
 Сравним эти файлы (например, в linux с помощью hexdump -C или в python — binascii.hexlify(Bytes, ' ')) 
Д/З
 Задача_1: - Ввести со стандартного ввода и вывести на стандартный вывод бинарные данные, первый байт которых — это количество равных (±1 байт) частей, на которые нужно разделить остальной ввод, отсортировать эти части между собой по возрастанию, и вывести на стандартный вывод (вместе со стартовым байтом вначале).
 Бинарное чтение / запись — из потока sys.stdin.buffer и в sys.stdout.buffer
- Размер частей вычисляется динамически (если они неравны, пускай Питон сам округляет) по формуле i*L/N …(i+1)*L/N, где i — номер части, L — размер хвоста файла, а N — количество частей
 Минимум по одному тесту на три случая: размер хвоста кратен, не кратен N, меньше N (тогда некоторые части просто пустые)
TODO Добавить более очевидный пример с '!'=33 и длинной строкой
Input: (без перевода строки в конце; первое q — это число 113)
qwerqwerqwerqwerqwerqwer
Output:
qeeeeeeqqqqqrrrrrrwwwwww
 Задача_2: Написать перекодировщик в UTF8 для следующей ситуации:
был текст на русском в кодировке CP1251
этот текст был перекодирован в UTF8 как если бы он был в кодировке latin1 (типичная ситуация с mp3 тегами ID3v1)
На входе — что-то типа áûë òåêñò íà ðóññêîì â êîäèðîâêå
- На выходе — русский текст
 - Несоответствующие кодировке символы заменять на «"?"» (что .decode/encode умеет сам)
 - Минимум по одному тесту на два случая: есть или нет несоответствующих символов 
Input:
ûë òåêñò íà ðóññêîì â êîäèðîâêå â êîâèä
Output:
ыл текст на русском в кодировке в ковид
 
 Задача_3: Вывести заголовок wav-файла (не весь, нужные поля отмечены
 ) Size=…, Type=…, Channels=…, Rate=…, Bits=…, Data size=…
- если это не WAV (проверить строковые маркеры), вывести "NO"
 
Сделать минимум три теста:
- Успешный (настоящий wav)
 Неуспешный (заголовок не распознаётся, например, потому что сам файл короче заголовка)
- Неуспешный (заголовок прочтён, но строковые маркеры не совпадают)
 
- Структура wav-файла: 
Positions off-by-1
Sample Value
Description
1 - 4
"RIFF"
Marks the file as a riff file. Characters are each 1 byte long.
 5 - 8File size (integer)
Size of the overall file in bytes - 4 bytes (32-bit integer). Typically, you'd fill this in after creation.
9 -12
"WAVE"
File Type Header. For our purposes, it always equals "WAVE".
13-16
"fmt "
Format chunk marker. Includes trailing null
17-20
16
Length of format data as listed above
 21-221
Type of format (1 is PCM) - 2 byte integer
 23-242
Number of Channels - 2 byte integer
 25-2844100
Sample Rate - 32 byte integer. Common values are 44100 (CD), 48000 (DAT). Sample Rate = Number of Samples per second, or Hertz.
29-32
176400
(Sample Rate * BitsPerSample * Channels) / 8.
33-34
4
(BitsPerSample * Channels) / 8.1 - 8 bit mono2 - 8 bit stereo/16 bit mono4 - 16 bit stereo
 35-3616
Bits per sample
37-40
"data"
"data" chunk header. Marks the beginning of the data section.
 41-44File size (data)
Size of the data section.
Input (1):
LecturesCMC/PythonIntro2021/Prac/10_Files/phone.wav
Output (1):
Size=108208, Type=1, Channels=2, Rate=44100, Bits=16, Data size=108172
Input (2):
Output (2):
NO
 
