Python: Кодировка

На самом базовом уровне компьютер работает только с нулями и единицами — это так называемый двоичный код. Каждую единицу или ноль называют битом (от binary digit — «двоичная цифра»).

Любые данные — изображения, музыка, текст — в компьютере представлены просто как последовательность битов.

Например, привычные нам числа из десятичной системы можно представить в двоичной форме:

  • 0 → 0
  • 1 → 1
  • 2 → 10
  • 3 → 11
  • 4 → 100
  • 5 → 101

Как закодировать текст?

Компьютер не «понимает» текст. Чтобы работать с буквами и другими символами, их тоже нужно превратить в числа. Это делают с помощью кодировок — таблиц, в которых каждому символу соответствует определённое число.

Самый простой способ — пронумеровать буквы, начиная с 1:

  • a1
  • b2
  • c3
  • ...
  • z26

Теперь мы можем представить слово hello как набор чисел:

h e l l o
↓ ↓ ↓ ↓ ↓
8 5 12 12 15

А good превращается в:

g o o d
↓ ↓ ↓ ↓
7 15 15 4

Программа не знает, что это слово. Она просто видит: «нужно отобразить символ с кодом 8, потом с кодом 5 и т.д.»

ASCII: первая массовая кодировка

Первые компьютеры работали в основном с английским языком. Для него в 1960-х годах придумали таблицу ASCII — она включала 128 символов: латинский алфавит, цифры, знаки препинания, спецсимволы (@, #, !, \n) и управляющие коды.

Этого хватало для первых программ, но не для всего мира.

Когда компьютеры начали использовать в других странах, возникла проблема: в ASCII нет кириллицы, иероглифов, арабского письма, ударений, валютных символов и т. д.

Каждая страна или компания начала делать свою кодировку на основе ASCII:

  • Windows придумала Windows-1251 для русского
  • Apple — Mac Roman
  • IBM — свои версии
  • Страны Восточной Европы, Азии и Ближнего Востока — свои

Все эти кодировки были несовместимы между собой. Код 226 в одной мог быть буквой é, в другой — и, в третьей — вообще техническим символом. Это приводило к настоящему хаосу.

Как выглядели проблемы с кодировками

Если вы видите в тексте вот это:

Привет!

или

���� �������� ������

— значит, программа неправильно определила кодировку текста. Она получила последовательность байтов, но прочитала их не той таблицей.

Это было нормой в 1990–2000-х. Одна программа писала текст в Windows-1251, другая читала его как ISO-8859-1, и в результате получался мусор.

Unicode и UTF-8: конец бардака

Чтобы всё починить, в 1990-х начали создавать универсальную таблицу Unicode, которая содержит символы всех письменных систем мира — от латинского и кириллицы до китайского, арабского, математических знаков, древнеегипетских и даже эмодзи.

Внутри Unicode есть несколько форматов хранения. Самый распространённый — UTF-8. Он компактно кодирует английские символы, но может расширяться под любые другие.

Сегодня UTF-8 — это стандарт по умолчанию в интернете, Python, Linux, базах данных и редакторах кода.

Зачем это знать программисту?

  • Вы будете работать с текстом: ошибки кодировки по-прежнему случаются, особенно при чтении файлов, обработке данных, взаимодействии с API и базами данных.
  • Python по умолчанию использует UTF-8, но иногда приходится явно указывать кодировку при чтении файлов:
  • Нужно уметь диагностировать проблемы. Например, если видите «кракозябры», это почти наверняка ошибка кодировки.

Задание

Внутри компьютера каждый символ — это просто число. Например, A, ?, % или даже пробел — всё это закодировано числами. Такой список называется таблицей ASCII. Именно эту таблицу используют программы, чтобы превращать текст в «понятные» компьютеру числа и обратно.

В Python есть специальная команда chr(число), которая показывает, какой символ стоит за этим числом. Например:

print(chr(63))

Эта команда напечатает на экран:

?

Почему именно ?? Потому что в таблице ASCII символ вопроса ? имеет номер 63.

Теперь задание:

  1. Перейдите в таблицу кодов ASCII
  2. Найдите номера (в колонке Decimal) для следующих символов:
  • ~ (тильда)
  • ^ (крышка/каретка)
  • % (знак процента)
  1. Напишите код, который по этим номерам выведет нужные символы с помощью chr(...)

Каждый символ должен выводиться на своей строке, как в примере выше.

✅ Примерный шаблон

print(chr(...))  # какой-то символ
print(chr(...))  # ещё один
print(chr(...))  # и третий

🙃 Конечно, можно просто написать print('~'), но это не так интересно. Гораздо полезнее понять, как компьютер понимает текст, и поиграться с этим напрямую.

Готовы? Тогда ищите нужные номера и пробуйте!

Определения

Кодировка
набор символов, закодированных с помощью чисел для представления текста в электронном виде.
Как с вами связаться? 🙃

Команда проекта находится в телеграм-сообществе по ссылке https://ttttt.me/HexletLearningBot. Там можно задать любой вопрос и повлиять на проект

Упражнение не проходит проверку — что делать? 😶

Если вы зашли в тупик, то самое время поговорить с нашим асситентом Тота во вкладке "Обсуждение". Как правильно задать вопрос:

В моей среде код работает, а здесь нет 🤨

Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.

Мой код отличается от решения учителя 🤔

Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи. В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.

Прочитал урок — ничего не понятно 🙄

Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в обратной связи нашего сообщества

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются

Привет! Я Тота и моя задача помочь в обучении. Чтобы активировать меня, нужно зарегистрироваться или залогиниться, если у вас уже есть аккаунт

Loading...

Ваше упражнение проверяется по этим тестам

1from hexlet.test import expect_output
2
3
4def test(capsys):
5    expected = "~\n^\n%"
6    expect_output(capsys, expected)
7

Решение учителя откроется через:

20:00
waiting_clock