Колоноскопия
ASCII и UNICODE, оба определяют символ 0x3A как COLON .Этот символ выглядит как две точки, одна над другой: :
ASCII и UNICODE, оба определяют символ 0x3B как SEMICOLON .Этот символ выглядит как точка над запятой: ;
Вы были последовательны в использовании двоеточия в своем примере: fff:cc3:4
и вы были последовательны в использовании слова точка с запятой в вашем описательном тексте: Letters, semicolon, alphanumeric, semicolon, integer, newline.
Я предполагаю, что вы имели в виду двоеточие (':') так как это символ, который вы напечатали.Если нет, вы должны изменить его на точку с запятой (';') везде, где это необходимо.
Ваш код
Вот ваш код для справки:
def opener(file):
#Opens a file and creates a list of lines
fi=open(file).read().splitlines()
import string
res = True
for i in fi:
#Checks whether any characters in the first column is not a letter
if any(j not in string.ascii_letters for j in i.split(':')[0]):
res = False
else:
continue
return res
Ваша проблема
Проблема, о которой вы спрашивали, заключалась в том, что функция всегда возвращала false.В приведенном вами примере между первым примером и вторым была пустая строка.Я хотел бы предостеречь вас, чтобы не пропустить пробелы или табуляции в этих пустых строках.Вы можете исправить это, явно перехватывая пустые строки и пропуская их:
for i in fi:
if i.isspace():
# skip blank lines
continue
Некоторые другие проблемы
Теперь вот некоторые другие вещи, которые вы, возможно, не заметили:
Вы предоставили хороший комментарий в своей функции.Это должна была быть строка документа:
def opener(file):
""" Opens a file and creates a list of lines.
"""
Вы import string
в середине вашей функции.Не делай этого.Переместите импорт вверх в верхнюю часть модуля:
import string # at top of file
def opener(file): # Not at top of file
Вы открыли файл с помощью open()
и никогда не закрывали его.Это точно , почему ключевое слово with
было добавлено в python:
with open(file) as infile:
fi = infile.read().splitlines()
Вы открыли файл, прочитали все его содержимое в память, а затем разбили егов строки, отбрасывая новые строки в конце.Все, чтобы вы могли разделить его на двоеточия и игнорировать все, кроме первого поля.
Было бы проще просто вызвать readlines()
для файла:
with open(file) as infile:
fi = infile.readlines()
res = True
for i in fi:
Было быбыло еще проще и еще проще просто итерировать по файлу напрямую:
with open(file) as infile:
res = True
for i in infile:
Похоже, вы наращиваете в сторону проверкивесь формат, который вы дали в начале.Я подозреваю, что регулярное выражение будет (1) легче писать и поддерживать;(2) легче понять позже;и (3) быстрее выполнить.И сейчас, для этого простого случая, и позже, когда у вас будет больше правил:
import logging
import re
bad_lines = 0
for line in infile:
if line.isspace():
continue
if re.match(valid_line, line):
continue
logging.warn(f"Bad line: {line}")
bad_lines += 1
return bad_lines == 0
Ваши имена плохие.Ваша функция включает имена file
, fi
, i
, j
и res
.Единственное, что едва имеет смысл - это file.
Учитывая, что вы просите людей прочитать ваш код и помочь вам найти проблему, пожалуйста, , пожалуйста, используйте лучшие имена.Если вы просто заменили эти имена на file
(то же самое), infile
, line
, ch
и result
, код станет более читабельным.Если вы реструктурировали код, используя стандартные рекомендации Python, такие как with
, он станет еще более читабельным.(И имеет меньше ошибок!)