Я изучаю Python как свой второй язык программирования (мой первый настоящий, если вы не считаете HTML/CSS/Javascript). Я пытаюсь создать что-то полезное в качестве своего первого реального приложения - бот IRC, который предупреждает людей через SMS, когда в канале происходят определенные вещи. По запросу кого-то я (пытаюсь) построить в настройках планирования, где люди могут не получать предупреждения от часов X и Y дня.
В любом случае, вот код, с которым у меня возникают проблемы:
db = open("db.csv")
for line in db:
row = line.split(",") # storing stuff in a CSV, reading out of it
recipient = row[0] # who the SMS is going to
s = row[1] # gets the first hour of the "no alert" time range
f = row[2] # gets last hour of above
nrt = [] # empty array that will store hours
curtime = time.strftime("%H") # current hour
if s == "no":
print "They always want alerts, sending email" # start time will = "no" if they always want alerts
# send mail code goes here
else:
for hour in range(int(s), int(f)): #takes start, end hours, loops through to get hours in between, stores them in the above list
nrt.append(hour)
if curtime in nrt: # best way I could find of doing this, probably a better way, like I said I'm new
print "They don't want an alert during the current hour, not sending" # <== what it says
else:
# they do want an alert during the current hour, send an email
# send mail code here
Единственная проблема, с которой я столкнулась, - это то, что script заканчивается только одним из строк (или что-то в этом роде), потому что я получаю только один результат каждый раз, даже если у меня есть более одной записи в CSV файл.
В вашей программе есть как минимум две ошибки:
curtime = time.strftime("%H")
...
for hour in range(int(s), int(f)):
nrt.append(hour)
# this is an inefficient synonym for
# nrt = range(int(s), int(f))
if curtime in nrt:
...
Во-первых, curtime - это строка, а nrt - список целых чисел. Python строго типизирован, поэтому они не являются взаимозаменяемыми и не будут сравнивать одинаковые:
'4' == 4 # False
'4' in [3, 4, 5] # False
Этот исправленный код адресует эту проблему, а также более эффективен, чем создание списка и поиск текущего часа в нем:
cur_hour = time.localtime().tm_hour
if int(s) <= cur_hour < int(f):
# You can "chain" comparison operators in Python
# so that a op1 b op2 c is equivalent to a op1 b and b op2c
...
Вторая проблема, о которой говорилось выше, заключается в том, что ваша программа не будет корректно вести себя, если часы будут проходить около полуночи (например, s = 22 и f = 8).
Ни одна из этих проблем не обязательно связана с "тем, что script заканчивается только зацикливанием по одной из строк", но вы не дали нам достаточной информации, чтобы выяснить, почему это возможно. Более полезный способ задать вопросы - опубликовать короткий, но полный фрагмент кода, который показывает поведение, которое вы наблюдаете, вместе с образцом ввода и результирующими сообщениями об ошибках, если они есть (наряду с трассировкой).
Если это обычный CSV файл, вы не должны сами его разбирать. Используйте стандартную библиотеку модуль csv.
Вот краткий пример из документов:
import csv
reader = csv.reader(open("some.csv", "rb"))
for row in reader:
print row
Вы пробовали что-то более простое? Просто, чтобы увидеть, как ваш файл на самом деле читается Python:
db = open("db.csv")
for line in db:
print line
Может возникнуть проблема с форматом вашего csv файла. Это происходит, например, при открытии файла Unix в среде Windows. В этом случае весь файл выглядит как одиночная строка, так как Windows и Unix имеют разные разделители строк. Поэтому я не знаю определенной причины вашей проблемы, но предлагаю думать в этом направлении.
Update: У вас есть несколько путей через тело вашего цикла:
s
будет "no"
: "They always want alerts, sending email"
будет напечатано.s
не "no"
и curtime in nrt
: "They don't want an alert during the current hour, not sending"
будет напечатано.s
не "no"
, а curtime in nrt
- false (последний else
): ничего не будет напечатано и никаких других действий не будет предпринято.Не следует ли разместить какой-либо оператор print
в последней ветке else
?
Кроме того, что такое точный вывод вашего фрагмента? Это "They always want alerts, sending email"
?
Вы можете пройти через хорошо написанный IRC-бот в Python Download
Я бы проверял логику в ваших условностях. Конструкция цикла должна работать.
Быть явным с тем, что в строке. Использование 0, 1, 2... n на самом деле является вашей ошибкой, и это делает код очень трудным для чтения в будущем для себя или для других. Поэтому позвольте использовать удобный кортеж, чтобы показать, что мы ожидаем от строки. Такие работы, как код, как документация
db = open("db.csv")
for line in db.readlines():
recipient, start_hour, end_hour = line.split(",")
nrt = []
etc...
Это показывает читателю вашего кода то, что вы ожидаете от строки, которая будет содержать, и она показала бы вам вашу ошибку при первом запуске:)
for line in db
уже итерации по каждой строке файла. Это функционально эквивалентно for line in db.readlines()
но более эффективно использует память, поскольку не считывает весь файл в список.