#python #algorithm
#питон #алгоритм
Вопрос:
Я изо всех сил пытаюсь проверить, является ли данный «пакет» элементов key: value правильным, но сначала я хотел бы сообщить вам о нескольких фактах, чтобы описать контекст:
Это упражнение дня 4 AoC (но я пришел с ним к вам, потому что я хочу понять, почему, а не только решение).
Мои входные данные выглядят так:
byr:1983
iyr:2017
pid:796082981
cid:129
eyr:2030
ecl:oth
hgt:182cm
iyr:2019
cid:314
eyr:2039
hcl:#cfa07d
hgt:171cm
ecl:#0180ce
byr:2006
pid:8204115568
byr:1991
eyr:2022
hcl:#341e13
iyr:2016
pid:729933757
hgt:167cm
ecl:gry
и так далее 250 пакетов (package — set of byr, iyr… разделяется пустой строкой) вот так.
Я уже проверил каждую объявленную функцию на ее корректность (они работают правильно), поэтому проблема находится под комментарием «ниже», который находится в коде (в этом коде есть и другие комментарии, чтобы лучше описать проблему)
Мой код выглядит так:
def check_fields(list):
comparison_list = ['byr', 'iyr', 'eyr',
'hgt', 'hcl', 'ecl',
'pid']
statement = True
for i in comparison_list:
statement = statement and (i in list)
return statement
def check_byr_iyr_eyr(line):
prefix,value = line.split(':')
cases = {'byr':{'min':1920, 'max':2002},
'iyr':{'min':2010, 'max':2020},
'eyr':{'min':2020, 'max':2030} }
return cases[prefix]['min'] <= int(value) <= cases[prefix]['max']
def check_hgt(line):
unit = line[len(line)-2] line[len(line)-1]
value = line[line.index(':') 1: -2]
cases = {'cm':{'min':150, 'max':193},
'in':{'min':59, 'max':76}}
return cases[unit]['min'] <= int(value) <= cases[unit]['max']
def check_hcl(line):
statement = True
if line[line.index(':') 1] != '#' or len(line[line.index(':') 2:]) != 6:
return False
else:
string = line[line.index('#') 1:]
for i in string:
statement = statement and (97 <= ord(i) <= 102 or 48 <= ord(i) <= 57)
return statement
def check_ecl(line):
comparison_list = ['amb', 'blu', 'brn',
'gry', 'grn', 'hzl',
'oth' ]
if line[line.index(':') 1:] in comparison_list:
return True
return False
def check_pid(line):
if len(line[line.index(':') 1:]) != 9:
return False
try:
int(line[line.index(':') 1:])
return True
except:
return False
''' below '''
line_list = []
valid_passports = 0
function_pool = {'ecl':check_ecl,'byr':check_byr_iyr_eyr, 'iyr':check_byr_iyr_eyr,
'hgt':check_hgt, 'hcl':check_hcl, 'eyr':check_byr_iyr_eyr, 'pid':check_pid}
statement = True
with open('results.txt', 'r') as f:
for line in f:
if line != 'n':
line_list.append(line.strip('n'))
else:
print(line_list)
if check_fields(line_list):
print('check_fields(line_list) == True') # this message doesn't appear in console
for i in line_list:
print('prefix - i[:3]:', i[:3]) # this message doesnt appear in console
checking_function = function_pool[i[:3]]
statement = statement and checking_function(i)
if statement:
valid_passports = 1
else:
statement = True
line_list.clear()
print(valid_passports)
Для ввода, показанного вверху, мой вывод будет выглядеть так:
['byr:1983', 'iyr:2017', 'pid:796082981', 'cid:129', 'eyr:2030', 'ecl:oth', 'hgt:182cm']
['iyr:2019', 'cid:314', 'eyr:2039', 'hcl:#cfa07d', 'hgt:171cm', 'ecl:#0180ce', 'byr:2006', 'pid:8204115568']
['byr:1991', 'eyr:2022', 'hcl:#341e13', 'iyr:2016', 'pid:729933757', 'hgt:167cm', 'ecl:gry']
0
Печать результатов разделения пакетов была добавлена для целей тестирования (и, как вы можете видеть выше, это работает),
и теперь мой вопрос и суть проблемы таковы:
почему valid_passports не увеличился? — и как всегда: это решение кажется мне правильным, и я не могу найти в своих рассуждениях ничего, что вызывает проблемы.
Пожалуйста, помогите. Заранее спасибо!
Ответ №1:
Ваша check_fields
функция работает на
lst = ['byr:1983', 'iyr:2017', 'pid:796082981', 'cid:129', 'eyr:2030', 'ecl:oth', 'hgt:182cm']
таким образом, что-то вроде "byr" in lst
возвращает False, потому что оно проверяет только строку «byr». Сначала вы должны обработать список. Что-то вроде:
headers = [pair.split(":")[0] for pair in lst]
Это даст
headers = ['byr', 'iyr', 'pid', 'cid', 'eyr', 'ecl', 'hgt']
И это список, по которому вы должны работать check_fields