Статья Автор: Деникина Н.В., Деникин А.В.

Таблица по строкам — читаем файл и считаем строки

Как выглядит задание 9

К задаче приложен файл. В нём таблица: в каждой строке несколько чисел, строк — тысячи. Вопрос почти всегда один и тот же: «Определите количество строк таблицы, для которых выполнены оба условия…»

Иногда вместо количества просят номер строки или сумму её чисел. Условий обычно два, реже три.

К этой тетради приложены два файла. 9-1.ods - такой же, как дают на экзамене: 100 строк по шесть чисел. И 9-1.csv - тот же файл после конвертации, о которой речь ниже. Скачай оба.

Вот начало таблицы в формате csv:

10;7;37;33;7;7
12;25;29;20;30;14
38;32;32;17;35;17
2;2;5;32;11;32
25;27;37;27;34;27
23;29;15;23;19;13
16;37;17;17;17;19
2;33;26;27;12;23

Числа разделены точкой с запятой. Дальше по файлу — ещё 92 таких строк.


Файл ods

Файл к задаче приходит в формате .ods  - это родной формат LibreOffice Calc, той самой программы, что стоит на станции КЕГЭ. 

А вот Питон такой файл сам не прочитает. Внутри .ods не текст, а архив с разметкой: переименуй его в .zip и загляни — увидишь content.xml и ещё несколько файлов. Чтобы читать это напрямую, нужна отдельная библиотека, и возиться с ней на экзамене не получится (у вас достыпны только стандартные библиотеки), да и незачем.

Поэтому первым делом таблицу переводят в csv — «таблицу текстом». Полминуты:

  1. Открой .ods двойным щелчком — запустится LibreOffice Calc.
  2. Файл → Сохранить как…
  3. В списке типов выбери Текст CSV (.csv).
  4. Поставь галочку «Изменить настройки фильтра» и нажми «Сохранить». На вопрос о формате отвечай «Использовать формат CSV».
  5. В окне экспорта: кодировка Юникод (UTF-8), разделитель поля — точка с запятой, разделитель текста оставь пустым.
  6. Сохрани рядом с программой — тогда в коде хватит голого имени файла без всяких путей.

Готово: получился обычный текстовый файл, его открывает даже блокнот. Одна строка таблицы - одна строка текста, числа через точку с запятой (открой этот файл в блокноте и проверь разделитель). Ровно то, что ты видел во фрагменте выше.

Почему точка с запятой, а не запятая. В русской раскладке запятая — десятичный разделитель: 3,14. Пока числа целые, разницы нет. Но появятся дробные — и файл с запятыми развалится: программа увидит в 3,14 два числа вместо одного. С точкой с запятой такого не случится, поэтому её и берут по умолчанию.

Почему вообще через csv
  • Читается тремя строками и без единой библиотеки - заработает где угодно.
  • Видно глазами. Открыл блокнотом - и сразу понятно, что не так: не тот разделитель, лишняя шапка, пустая строка.
  • Ничего не ломается при переносе. Текст есть текст.
 
Три мелочи, на которых спотыкаются
  • Выбрал при экспорте запятую - значит и в программе line.split(","). Разделитель обязан совпадать.
  • В файлах задания 9 шапки нет, только числа. Если шапка вдруг есть, первую строку надо пропустить, иначе int споткнётся о текст.
  • Лишние пробелы и перевод строки убирать не надо: int(" 7\n") отработает как надо.

В старых сборниках и в банке задач те же задачи лежат как .xls. Шаги ровно те же, меняется только программа, в которой открываешь.


Читаем файл

Чтение - три строки, и они одинаковы во всех задачах этого типа. Запомни их как заготовку:

rows = []
for line in open("9-1.csv"):
    rows.append([int(x) for x in line.split(";")])

Что тут происходит. Пустой список rows. Цикл идёт по строкам файла. line.split(";") режет строку по точке с запятой и даёт список кусочков-текстов (список подстрок). Списковое включение [int(x) for x in ...] превращает каждый кусочек в число.

После этого rows — список списков. Одна строка таблицы = один список чисел, и с ним работают обычные min, max, sum.

▶ Запусти. Сначала печатается, сколько строк прочиталось, потом три величины для первых восьми.



Что получилось

100
7 37 101
12 30 130
17 38 171
2 32 84
25 37 177
13 29 122
16 37 123
2 33 123

Первое число — 100, файл прочитан целиком. Дальше по строчке на каждую из первых восьми строк: минимум, максимум, сумма.

Сверься с фрагментом выше: первая строка файла 10;7;37;33;7;7, и правда наименьшее 7, наибольшее 37, сумма 101.


Считаем подходящие строки

Теперь главное движение всего задания. Заводим счётчик до цикла, внутри проверяем условие, при совпадении прибавляем единицу. После цикла печатаем.

▶ Запусти: сколько строк файла имеют сумму больше 100?



Что получилось

69

Ровно 69 строк из 100. Обрати внимание: kol = 0 стоит до цикла. Внутри цикла счётчик обнулялся бы на каждой строке, и в ответе всегда была бы единица или ноль — классическая ошибка.


Тот же счёт в таблице

Если решаешь в редакторе, заводишь служебный столбец справа от данных. В первую свободную ячейку — формулу, потом тянешь её вниз до последней строки.

G1=ЕСЛИ(СУММ(A1:F1)>100;1;0)ABCDEFGHIJKLMNO110737337712122529203014133832321735171422532113205252737273427162329152319131716371717171918233262712231дальше выделяешь G1, тянешь за уголок вниз до строки 100 — формула перенастроится сама

Столбец G заполнился единицами и нулями. Ответ — сумма этого столбца:

=СУММ(G1:G100)

Получится то же 69. Два пути сошлись — значит, скорее всего, верно.


Почему kol = 0 пишут до цикла, а не внутри?


К задаче приложен файл .ods. Что делают первым делом?


Что делает line.split(";")?


В таблице формулу вписали в G1 и протянули вниз. Что даст =СУММ(G1:G100)?

Печать