SkillGridИзучай computer science на практике

Значения и типы: почему 1 это не "1"

Тип — это множество допустимых значений. Одно это предложение из logic:1 объясняет каждую странную ошибку новичка.

13 мин · 40 XP

Программа — это куча значений, которые перекладывают с места на место. Число, кусок текста, да или нет, список оценок. Всё остальное в этом уроке про один вопрос: что это за значение и что с ним вообще разрешено делать.

В logic:1 тип был просто множеством. Булево множество состоит ровно из двух элементов: true и false. Множество целых чисел хранит целые числа. Множество строк хранит текст любой длины, включая пустую строку. Сказать, что у значения есть тип, значит сказать, из какого множества оно взялось. Каждая операция, которую ты пишешь, это утверждение о множествах: сложение хочет два числа, склейка текста хочет две строки.

bool   = { true, false }
int    = { ..., -2, -1, 0, 1, 2, ... }
string = any sequence of characters

age + 1   needs a value from int
"1" + 1   mixes a value from string with a value from intТип — это множество значений, а операция — утверждение о множествах.

Вот одни и те же значения, записанные на трёх языках. Не пытайся это заучить. Читай так, как читал бы одно и то же предложение на трёх диалектах: слова меняются, смысл нет.

name = "Ada"
age = 36
tall = True
scores = [90, 85, 77]
prices = {"soup": 2.50, "juice": 1.90}Python: тип нигде не написан руками, его определяет само значение.
const name = "Ada";
const age = 36;
const tall = true;
const scores = [90, 85, 77];
const prices = { soup: 2.50, juice: 1.90 };JavaScript: const для имени, которому больше не присвоят новое значение.
var name string = "Ada"
var age int = 36
var tall bool = true
scores := []int{90, 85, 77}
prices := map[string]float64{"soup": 2.50, "juice": 1.90}Go: тип написан рядом с именем, и компилятор его проверяет.

А теперь классическая катастрофа новичка. Форма регистрации спрашивает возраст. Форма отправляет текст, потому что всё, что отправляет форма, это текст. И тут твой код пытается прибавить к нему единицу.

form sends: age = "16"
8 + 1  = 9
"16" + 1 = ?Восемь плюс один будет девять. А сколько будет текст "16" плюс один?

Последняя идея — изменяемость, и она стоит людям больше часов отладки, чем всё остальное в этом уроке. Список — это один объект, на который могут указывать много имён. Измени список через одно имя, и это увидят все остальные имена, потому что список всегда был один.

scores = [90, 85]
same = scores
same.append(77)
print(scores)

[90, 85, 77]Два имени, один список. Изменение видно через оба.
scoressame[90, 85]namesnamesone list, two namesappend 77[90, 85, 77][90, 85, 77]

Коллекции ещё несут в себе идею Big-O из logic:1. Выбрать правильную коллекцию часто выгоднее, чем переписывать циклы. Список нужен для порядка и для обхода всех элементов. Словарь нужен для поиска по ключу. Таблица стоимости ниже — это и есть всё обоснование того, зачем существуют словари.

list.append(x)      O(1)
map[key]            O(1) average
x in list           O(n)
x in map            O(1) averageСтоимость операции — это стоимость коллекции, в которой лежат значения.

Практика

  1. Форма регистрации присылает возраст текстом: age = "16". Код выполняет age + 1. Как честно описать, что здесь пошло не так?

    Подсказки
    • Поле приходит из формы, а форма всегда отправляет только текст.
    • Спроси, какое из двух значений лежит во множестве строк, а какое во множестве чисел.
  2. Сопоставь каждую задачу с коллекцией, которая для неё и придумана. Важна задача, а не синтаксис.

    Подсказки
    • Python и Go записывают одну и ту же коллекцию по-разному: список имён остаётся списком имён.
    • Словарь отвечает, какое значение лежит по данному ключу, не перебирая всю коллекцию.
  3. Расставь по порядку шаги чтения возраста из формы. Так устроена почти любая программа, которая общается с внешним миром.

    1. 1Проверить, что текст действительно похож на целое число
    2. 2Превратить текст в число
    3. 3Снова отправить результат наружу уже как текст
    4. 4Прочитать сырой текст ровно таким, каким его прислала форма
    5. 5Выполнить арифметику над числом
    Подсказки
    • Ничего нельзя считать числом, пока это не стало числом.
    • Проверка идёт до арифметики: программа никогда не делает третий шаг, если не смогла сделать второй.