ЕГЭ 2027 · Информатика
Задание 3 ЕГЭ по информатике
Что проверяет линия, сколько она стоит, на чём теряют баллы и как решать — по нашим конспектам. В банке 200+ заданий этой линии с разбором.
Аналитика ЕГЭ: №3 (реляционные базы данных)
- Баллы
- 1 первичный балл
- Частота
- в каждом варианте
Частые ловушки
- Считают по одной таблице, забывая связь по ключу со второй
- Путают ID и IDродителя при поиске предков/потомков в родословных
Совет. Выпиши связи между таблицами по ключу до подсчёта; для родословных строй дерево.
Разборы
Разбор примера
Собираем строку из трёх таблиц вручную
Даны три маленькие таблицы. «Магазин»: 1 — Центральный, ул. Лесная; 2 — Кировский, пр. Мира; 3 — Центральный, ул. Садовая. «Товар»: 1001 — Кефир 1%, цена 78 руб. за упаковку; 1002 — Сметана 20%, цена 145 руб. «Движение товаров» — восемь операций. Определить, на какую сумму продан «Кефир 1%» в Центральном районе с 13 по 21 октября включительно.
Операции (дата, ID магазина, артикул, количество, тип):
- • | 12.10 | 1 | 1001 | 40 | Продажа |
- • | 13.10 | 1 | 1001 | 25 | Продажа |
- • | 14.10 | 2 | 1001 | 60 | Продажа |
- • | 15.10 | 1 | 1001 | 30 | Поступление |
- • | 18.10 | 3 | 1001 | 18 | Продажа |
- • | 21.10 | 1 | 1002 | 12 | Продажа |
- • | 21.10 | 3 | 1001 | 10 | Продажа |
- • | 22.10 | 1 | 1001 | 50 | Продажа |
Показать решение по шагам
- 1. Шаг 1. Разберём каждую операцию так, как это делает программа: подставим вместо ключей значения из справочников и проверим четыре условия. Сама операция не знает ни района, ни наименования — их надо подтянуть.
- 2. Шаг 2. Операция 12.10, магазин 1, артикул 1001, 40 шт., Продажа. Магазин 1 → Центральный ✔ Артикул 1001 → Кефир 1% ✔ Тип «Продажа» ✔ Но дата 12 октября раньше 13-го ✘ Строка отбрасывается. Сорок упаковок не в счёт.
- 3. Шаг 3. Операция 13.10, магазин 1, артикул 1001, 25 шт., Продажа. Район Центральный ✔ Товар Кефир 1% ✔ Тип «Продажа» ✔ Дата 13 октября — граница периода, и она входит ✔ Считаем: 25 × 78 = 1950 руб. Накопитель равен 1950.
- 4. Шаг 4. Операция 14.10, магазин 2, артикул 1001, 60 шт., Продажа. Товар и тип подходят, дата в периоде, но магазин 2 — это Кировский район ✘ Здесь и прячется ловушка: без справочника магазинов в самой операции стоит безобидное число 2, и строку легко засчитать по ошибке.
- 5. Шаг 5. Операция 15.10, магазин 1, артикул 1001, 30 шт., Поступление. Всё совпадает, кроме типа: это поступление товара в магазин, а не продажа ✘ Тридцать упаковок приехали на склад, денег покупатели не платили.
- 6. Шаг 6. Операция 18.10, магазин 3, артикул 1001, 18 шт., Продажа. Магазин 3 → Центральный ✔ Именно здесь второй раз спотыкаются: в Центральном районе два магазина, 1 и 3, и учитывать надо оба. Считаем: 18 × 78 = 1404 руб. Накопитель 1950 + 1404 = 3354.
- 7. Шаг 7. Операция 21.10, магазин 1, артикул 1002, 12 шт., Продажа. Район и дата подходят, но артикул 1002 → Сметана 20%, а нас просили про кефир ✘
- 8. Шаг 8. Операция 21.10, магазин 3, артикул 1001, 10 шт., Продажа. Всё сходится, дата 21 октября — вторая граница, тоже входит ✔ Считаем: 10 × 78 = 780 руб. Накопитель 3354 + 780 = 4134.
- 9. Шаг 9. Операция 22.10, магазин 1, артикул 1001, 50 шт., Продажа. Дата на день позже конца периода ✘ Пятьдесят упаковок — заметная сумма, и если перепутать «по 21-е» с «до 22-го», ответ вырастет на 3900 руб.
- 10. Шаг 10. Итог: 1950 + 1404 + 780 = 4134 руб. Из восьми операций подошли три, и каждая отброшенная строка не прошла по своей причине: дата раньше, чужой район, не тот тип, не тот товар, дата позже. Так устроены и боевые файлы, только строк там несколько тысяч.
Ответ: 4134 руб.
Разбор примера
Тот же ответ программой на Python
Написать программу, которая читает приложенный файл l3-b954af29a0.xlsx с тремя листами и выдаёт сумму продаж товара «Кефир 1%» в магазинах Центрального района с 13 по 21 октября включительно.
Показать решение по шагам
- 1.
Шаг 1. План повторяет ручной разбор: сначала прочитать два справочника в словари, потом один раз пройти по таблице операций. Вся программа:
```python
from openpyxl import load_workbook from datetime import datetimewb = loadworkbook('l3-b954af29a0.xlsx')
rayon_magazina = {} for id_mag, rayon, adres in wb['Магазин'].iter_rows(min_row=2, values_only=True): rayon_magazina[id_mag] = rayonopisanie_tovara = {} for artikul, otdel, nazvanie, ed, v_upakovke, cena in wb['Товар'].iter_rows(min_row=2, values_only=True): opisanie_tovara[artikul] = (nazvanie, cena)nachalo = datetime(2024, 10, 13) konec = datetime(2024, 10, 21)itog = 0 for nomer, data_op, id_mag, artikul, kolichestvo, tip in wb['Движение товаров'].iter_rows(min_row=2, values_only=True): if tip != 'Продажа': continuenazvanie, cena = opisanietovara[artikul]
if nazvanie != 'Кефир 1%': continue if rayon_magazina[id_mag] != 'Центральный': continue if not (nachalo <= data_op <= konec): continue itog += kolichestvo * cenaprint(itog) ```
- 2. Шаг 2. Зачем справочники кладут в словари, а не ищут по списку каждый раз? Потому что поиск в словаре по ключу занимает одинаковое время независимо от размера, а перебор списка — тем дольше, чем он длиннее. В файле восемь тысяч операций и, скажем, сорок магазинов; перебор дал бы триста двадцать тысяч сравнений вместо восьми тысяч мгновенных обращений. На линии 3 это не критично, но привычка правильная — в линии 27 она решает всё.
- 3. Шаг 3. Строка
for id_mag, rayon, adres in ...распаковывает кортеж строки сразу в три имени, по числу столбцов листа «Магазин». Если столбцов окажется больше, Python скажетtoo many values to unpack— сигнал, что вы не посмотрели шапку файла. Смотреть шапку перед написанием кода обязательно: порядок полей в разных вариантах может отличаться. - 4. Шаг 4. Параметр minrow=2 пропускает строку заголовков. Без него первой «операцией» окажется набор подписей «ID операции», «Дата», …, и на сравнении даты программа упадёт с ошибкой типов. Это ровно та ошибка, которую новички лечат случайными правками, хотя причина одна.
- 5. Шаг 5. Проследим выполнение на восьми демонстрационных операциях. Первая, 12.10, 40 шт.: тип «Продажа» — проходит; наименование «Кефир 1%» — проходит; район Центральный — проходит; дата 12 октября меньше
nachalo, условиеnachalo <= data_opложно →continue. Накопитель 0. - 6. Шаг 6. Вторая, 13.10, 25 шт.: все четыре проверки истинны. Двойное сравнение
nachalo <= data_op <= konecв Python работает как обычная математическая запись — это одно выражение, а не два. Накопитель: 0 + 25 × 78 = 1950. - 7. Шаг 7. Третья, 14.10, магазин 2, 60 шт.:
rayon_magazina[2]возвращает «Кировский», сравнение с «Центральный» ложно →continue. Накопитель 1950. Четвёртая, 15.10, Поступление: отсекается первой же проверкой, до справочников дело не доходит. Порядок проверок выбран так, чтобы самые дешёвые шли первыми. - 8. Шаг 8. Пятая, 18.10, магазин 3, 18 шт.:
rayon_magazina[3]— тоже «Центральный», строка засчитана. Накопитель: 1950 + 1404 = 3354. Шестая, 21.10, артикул 1002:opisanie_tovara[1002]даёт «Сметана 20%» →continue. - 9. Шаг 9. Седьмая, 21.10, магазин 3, 10 шт.: дата равна
konec, нестрогое сравнение пропускает её. Накопитель: 3354 + 780 = 4134. Восьмая, 22.10: дата большеkonec→continue. Цикл закончился,printвыводит 4134 — ровно то, что мы получили руками. - 10. Шаг 10. Две поломки, которые случаются именно с этим файлом. Первая:
TypeError: '<=' not supported between instances of 'str' and 'datetime'— значит, даты в листе хранятся текстом, а не датами. Лечится разбором строки:data_op = datetime.strptime(data_op, '%d.%m.%Y'). Вторая:KeyErrorна артикуле — в таблице операций встретился артикул, которого нет в справочнике товаров; в боевых файлах такого не бывает, значит, вы читаете не тот лист или забылиmin_row=2. - 11. Шаг 11. Ответ выводится целым числом, если цены целые. Когда в файле попадаются копейки, итог печатайте как
print(round(itog))или в том виде, который требует формулировка, — но округляйте только в конце, иначе набежит расхождение в несколько рублей и балл потеряется.
Ответ: 4134 (программа выводит ту же сумму, что получена вручную)
Разбор примера
Тот же ответ в таблице: ВПР и СУММЕСЛИМН
Решить ту же задачу линии 3 без программирования — средствами табличного процессора, служебными столбцами на листе «Движение товаров».
Показать решение по шагам
- 1. Шаг 1. В таблице нельзя «подтянуть» район прямо в условии — придётся сначала дописать недостающие поля служебными столбцами. Лист «Движение товаров» занимает столбцы A–F: A — ID операции, B — дата, C — ID магазина, D — артикул, E — количество упаковок, F — тип операции. Свободны G и дальше.
- 2.
Шаг 2. Столбец G — район магазина. В ячейку
G2пишем=ВПР(C2; Магазин!$A$2:$C$100; 2; ЛОЖЬ)и протягиваем вниз. Функция ВПР ищет значение
C2в первом столбце указанного диапазона и возвращает значение из столбца с номером 2 того же диапазона, то есть район. - 3. Шаг 3. Разберём аргументы, потому что здесь теряют больше всего времени. Диапазон закреплён долларами —
$A$2:$C$100: при протягивании он не должен съезжать, иначе нижние строки будут искать в обрезанном справочнике. А вотC2закреплять нельзя: каждая строка смотрит на свой магазин. Последний аргумент ЛОЖЬ означает «точное совпадение»; без него ВПР ищет приблизительно и на неотсортированном справочнике выдаёт чужие значения молча, без ошибки. - 4. Шаг 4. Столбец H — наименование товара:
=ВПР(D2; Товар!$A$2:$F$100; 3; ЛОЖЬ). Номер 3 — потому что на листе «Товар» наименование стоит третьим столбцом (артикул, отдел, наименование). Номер столбца считается внутри диапазона, а не по всему листу; если начать диапазон не с A, нумерация сдвинется, и это ещё одна классическая ошибка. - 5. Шаг 5. Столбец I — стоимость операции:
=E2 * ВПР(D2; Товар!$A$2:$F$100; 6; ЛОЖЬ). Шестой столбец справочника — цена за упаковку. Умножаем её на количество упаковок из E2. Поле «Количество в упаковке» (пятый столбец) в этой формулировке не участвует: цена дана именно за упаковку, а не за литр. Прочитать условие и понять, какая из двух величин нужна, — половина решения. - 6.
Шаг 6. Теперь всё нужное лежит в одной строке, и остаётся одна формула:
=СУММЕСЛИМН(I2:I1000; H2:H1000; "Кефир 1%"; G2:G1000; "Центральный"; F2:F1000; "Продажа"; B2:B1000; ">=" & ДАТА(2024;10;13); B2:B1000; "<=" & ДАТА(2024;10;21)) - 7. Шаг 7. Устройство СУММЕСЛИМН простое: первым идёт диапазон, который суммируем, дальше пары «диапазон условия — само условие». Пар может быть сколько угодно, и все они соединяются по И: строка попадает в сумму, только если выполнены все условия. Именно это нам и нужно — четыре фильтра сразу.
- 8. Шаг 8. Условия по датам записаны как текст со склейкой: знак сравнения в кавычках, амперсанд и функция ДАТА. Почему не написать
">=13.10.2024"целиком? Потому что распознавание даты внутри текста зависит от региональных настроек, и на чужом компьютере условие может не сработать. Функция ДАТА задаёт дату однозначно. - 9. Шаг 9. На нашей демонстрационной таблице из восьми строк формула даст 4134. Проверить себя легко: включите в служебном столбце фильтр по району «Центральный» и типу «Продажа» — останутся строки, которые мы разбирали руками, и их сумму покажет строка состояния внизу окна.
- 10. Шаг 10. Что выбрать на экзамене? Если вы уверенно пишете
ВПР, таблица быстрее: три формулы и протягивание занимают минуты три. Если формулы даются тяжело — Python надёжнее, потому что каждый фильтр там виден отдельной строкой и его легко проверить. Оба пути дают один и тот же балл; провальный путь только один — считать глазами.
Ответ: 4134 руб. — совпадает с ручным разбором и с программой
Разбор примера
Может ли поле быть ключом: проверяем кодом
В таблице «Товар» шесть записей: (1001, Кефир 1%, Молочный, 78), (1002, Сметана 20%, Молочный, 145), (1003, Творог 5%, Молочный, 96), (1004, Кефир 1%, Молочный, 82), (1005, Масло 82,5%, Молочный, 210), (1006, Творог 5%, Молочный, 96). Какие поля могут служить ключом таблицы?
Показать решение по шагам
- 1. Шаг 1. Ключ обязан однозначно определять запись: по его значению должна находиться ровно одна строка. Значит, проверка сводится к вопросу «есть ли в столбце повторы». Повторился хоть раз — ключом быть не может.
- 2. Шаг 2. Поле Артикул: 1001, 1002, 1003, 1004, 1005, 1006 — все значения различны ✔ Кандидат в ключи. Это и есть ключ таблицы «Товар» в задании 3, поэтому именно на артикул ссылается таблица операций.
- 3. Шаг 3. Поле Наименование товара: «Кефир 1%» встречается в записях 1001 и 1004, «Творог 5%» — в 1003 и 1006 ✘ Ключом быть не может. И это не выдумка ради примера: один и тот же продукт от разных поставщиков получает разные артикулы при одинаковом названии.
- 4. Шаг 4. Поле Отдел: во всех шести записях «Молочный» ✘ Столбец, где значение вообще одно на всю таблицу, бесполезен для различения записей — он несёт ноль информации о том, какая именно это строка.
- 5. Шаг 5. Поле Цена: 78, 145, 96, 82, 210, 96 — значение 96 повторилось ✘ И даже если бы все цены случайно оказались различными, ключом такое поле делать нельзя: завтра цены поменяются, и уникальность исчезнет. Ключ выбирают по смыслу, а не по удачному стечению данных.
- 6. Шаг 6. Пара полей тоже может быть ключом — такой называют составным. Пара (Наименование, Цена): («Кефир 1%», 78), («Сметана 20%», 145), («Творог 5%», 96), («Кефир 1%», 82), («Масло 82,5%», 210), («Творог 5%», 96). Последняя пара совпала с третьей ✘ А вот пара (Наименование, Артикул) уникальна — но она уникальна лишь потому, что уникален артикул, и второе поле в ней лишнее.
- 7.
Шаг 7. На реальном файле такие проверки делают программой. Вот она:
```python
from openpyxl import load_workbook from collections import Counterwb = load_workbook('l3-b954af29a0.xlsx') list_tovar = wb['Товар']shapka = [yacheyka.value for yacheyka in list_tovar[1]] stroki = list(list_tovar.iter_rows(min_row=2, values_only=True))for nomer, imya_polya in enumerate(shapka): znacheniya = [stroka[nomer] for stroka in stroki] schetchik = Counter(znacheniya) povtory = [z for z, k in schetchik.items() if k > 1] if povtory: print(imya_polya, '— не ключ, повторы:', povtory[:3]) else: print(imya_polya, '— может быть ключом')```
- 8. Шаг 8. Разберём устройство. Выражение
list_tovar[1]берёт первую строку листа — шапку, и списокshapkaхранит названия полей. Дальшеenumerate(shapka)выдаёт пары «номер столбца, название», аstroka[nomer]достаёт из каждой строки значение именно этого столбца. Получается перебор по столбцам, хотя данные лежат по строкам. - 9. Шаг 9. Класс Counter из модуля
collectionsсчитает, сколько раз встретилось каждое значение: это словарь «значение → количество». Списокpovtoryсобирает те значения, что встретились больше одного раза. Срез[:3]в выводе нужен, чтобы не залить экран тысячами повторов при проверке поля вроде «Отдел». - 10. Шаг 10. Проследим на наших шести записях. Столбец 0 — «Артикул»: Counter даёт по единице на каждое значение,
povtoryпуст → печатается «может быть ключом». Столбец 1 — «Наименование»: Counter выдаёт{'Кефир 1%': 2, 'Сметана 20%': 1, 'Творог 5%': 2, 'Масло 82,5%': 1}, повторы найдены → «не ключ». Столбец 2 — «Отдел»:{'Молочный': 6}→ «не ключ». Столбец 3 — «Цена»: повтор 96 → «не ключ». - 11. Шаг 11. Зачем это на экзамене, если в линии 3 ключи и так отмечены значком на схеме? Затем, что проверка уникальности — рабочий инструмент и в других линиях: так ищут дубликаты строк в файле, и так понимают, по какому полю таблицы соединяются, если схема нарисована неразборчиво. Один запуск даёт полную картину полей за секунду.
Ответ: ключом может быть только Артикул; наименование, отдел и цена повторяются
Разбор примера
Задание 3 в электронной таблице: ВПР и СУММПРОИЗВ
База «Молочные продукты». Лист «Движение товаров» (12 строк данных, строки 2–13, столбцы A–F: ID операции, Дата, ID магазина, Артикул, Количество упаковок, Тип операции), лист «Товар» (строки 2–6, столбцы A–E: Артикул, Наименование, Едизм, Количество в упаковке, Цена за упаковку) и лист «Магазин» (строки 2–6, столбцы A–C: ID магазина, Район, Адрес).
Определите, на какую сумму (в руб.) был продан товар «Кефир 1%» в магазинах Центрального района за период с 13 по 21 октября включительно.
Показать решение по шагам
- 1. Шаг 1. Подтягиваем район. В листе «Движение товаров» встаём в свободный столбец G, в ячейку G2, и пишем:
=ВПР(C2; Магазин!$A$2:$B$6; 2; ЛОЖЬ). ЗдесьC2— ID магазина из строки операции,Магазин!$A$2:$B$6— справочник (обязательно с долларами, иначе при протягивании диапазон уедет вниз),2— номер столбца справочника, из которого берём значение (район),ЛОЖЬ— требование точного совпадения. Протягиваем G2 до G13. - 2. Шаг 2. Подтягиваем наименование и цену. В H2:
=ВПР(D2; Товар!$A$2:$E$6; 2; ЛОЖЬ)— второй столбец таблицы «Товар» это наименование. В I2:=ВПР(D2; Товар!$A$2:$E$6; 5; ЛОЖЬ)— пятый столбец, цена за упаковку. Протягиваем обе формулы до 13-й строки. Теперь в каждой строке операции стоит всё, что нужно для отбора: район (G), наименование (H) и цена (I). - 3. Шаг 3. Считаем одной формулой. В любой свободной ячейке:
=СУММПРОИЗВ((F2:F13="Продажа") * (G2:G13="Центральный") * (H2:H13="Кефир 1%") * (ДЕНЬ(B2:B13)>=13) * (ДЕНЬ(B2:B13)<=21) * E2:E13 * I2:I13). - 4. Шаг 4. Как это читается. Каждая скобка со сравнением даёт массив из ЛОЖЬ и ИСТИНА, то есть из нулей и единиц. Перемножение массивов — это логическое «И» по каждой строке: единица останется только там, где выполнены все пять условий сразу. Дальше произведение умножается на количество упаковок и на цену, и СУММПРОИЗВ складывает результат по всем строкам. Строки, не прошедшие отбор, дают множитель 0 и в сумму не попадают.
- 5. Шаг 5. Что проходит отбор. Из двенадцати строк условиям удовлетворяют пять: 13.10 (8 упаковок), 16.10 (6 упаковок), 18.10 (11 упаковок), 20.10 (3 упаковок) и 21.10 (4 упаковок). Всего 8 + 6 + 11 + 3 + 4 = 32 упаковки.
- 6. Шаг 6. Умножаем на цену кефира: 32 · 62 = 1984.
Ответ: 1984 руб.
Уроки по этой линии
- Реляционные базы данных — открыт бесплатно
- Многотабличные базы и связи
Потренируй задание 3
Задания этой линии с проверкой и разбором решения — после бесплатной регистрации. Ошибки сами попадут в план повторения.