T. Файловая сумма

Вы скорее всего знаете, что существуют не только текстовые файлы. Различные форматы данных предусматривают специальное кодирование. Например, BMP изображения хранят некоторую заголовочную информацию и цвета всех пикселей в виде чисел.

Давайте поработаем с такими данными. Нам дают файл в некотором формате, назовем его NUM. Он содержит список 2-байтных чисел. Для простоты будем считать, что отрицательных чисел не существует.

Напишите программу, которая вычисляет сумму всех записанных в файле чисел в 2-байтном диапазоне.

Формат ввода

В файле numbers.num содержатся числа в указанном формате.

Формат вывода

Одно число — сумма всех чисел в файле на 2-байтном диапазоне.

Примечание

Для простоты файлы в примерах записаны в HEX формате. В этом виде файл представляется как последовательность четырехзначных шестнадцатеричных чисел.

В первом примере записано 5 шестнадцатеричных чисел: 1, 2, 3, 4, 5. Их сумма равна 15.
Во втором — 255 и 257. Их сумма равна 512.

Файл из примеров в изначальном виде можно загрузить здесь:

Если вы хотите изучить принцип хранения целых чисел в ЭВМ, советуем почитать про прямой, обратный и дополнительный коды.

Пример

Ввод

# ВНИМАНИЕ СОДЕРЖИМОЕ НАСТОЯЩЕГО ФАЙЛА ДРУГОЕ

0001 0002 0003 0004 0005

Вывод

15

Ввод

# ВНИМАНИЕ СОДЕРЖИМОЕ НАСТОЯЩЕГО ФАЙЛА ДРУГОЕ

00FF 0101

Вывод

512

Решение

Очень простая линейная задача на освоение чтения данных из бинарных файлов.

И в то же время, в материалах к заданиям не упомянуты ряд аспектов. Например не рассказано как открыть файл в двоичном режиме, не расказано как прочитать два байта,упоминаются символы, но для начинающих программистов не очевидно что символ в этой терминологии эквивалентен байту. Да и кодировка UTF-8 добавляет сумятицы, потому что в ней символ может быть и два и три байта. Все это начит что надо изучить документацию на методы open() и read(). Кроме того, чтобы последовательность двух байт превратить в целое число необходимо прочитать про методы и параметры функции int(), в плане порядка байтов и его беззнаковости.

Другая сложность – понять правильно требование в условии вывода. Дело в том, что часто “2-байтный диапазон” относят к числам, которые читают из файла, а не интерпретируют как “отбросьте старшие разряды у ответа так, чтобы ответ “влез в два байта”. Но как бы то ни было, именно эта простая вещь скрывается за мудреной и неоднозначной фразой.

Поэтому открываем файл в решиме двоичного чтения, читаем порциями по два байта, каждую порцию конвертируем в число с помощью функции int.from_bytes() и накапливаем в результат.

После того, как все данные прочитаны делим результат на 65536 по модулю и выводим остаток.

Посмотреть код

Решение

Python
file_in = 'numbers.num'
sum = 0

with open(file_in, 'rb') as file:
    while (chunk := file.read(2)):
        sum += int.from_bytes(chunk)

print(sum % 0x10000)  # 65535
Подписаться
Уведомить о
guest
4 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Никита
Никита
08.02.2024 14:10

Здравствуйте, Ваше решение не проходит ни один тест ни проходит. Данное решение не проходит третий тест, единственную подсказку я нашел, что нужно отбрасывать старшие байты

with open(‘numbers.num’, ‘rb’) as file:
    values = []
    while True:
        bytes_chunk = file.read(2)
        if not bytes_chunk:
            break
        values.append(int.from_bytes(bytes_chunk, ‘big’))
print(sum(values))

Ivan
Ivan
Ответить на  Сергей Клочко
17.08.2024 10:53

Почему нужно делить именно на 6536, понимаю что это степень двойки, но почему именно это число?