Помогите с странностью петли Python? - PullRequest
1 голос
/ 29 марта 2009

Я изучаю 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

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

Ответы [ 6 ]

9 голосов
/ 29 марта 2009

Если это обычный CSV-файл, не пытайтесь анализировать его самостоятельно. Используйте стандартную библиотеку csv module .

Вот краткий пример из документов:

import csv
reader = csv.reader(open("some.csv", "rb"))
for row in reader:
    print row
7 голосов
/ 29 марта 2009

В вашей программе есть как минимум две ошибки:

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).

Ни одна из этих проблем не обязательно связана с тем, что «скрипт заканчивает цикл только через одну из строк», но вы не предоставили нам достаточно информации, чтобы выяснить, почему это может быть. Более полезный способ задать вопросы - опубликовать краткий , но полный фрагмент кода, который показывает поведение, которое вы наблюдаете, а также образец ввода и полученные сообщения об ошибках, если таковые имеются (вместе с с трассировкой).

5 голосов
/ 29 марта 2009

Вы пробовали что-то более простое? Просто чтобы посмотреть, как ваш файл действительно читается Python:

db = open("db.csv")  
for line in db:  
    print line

Может быть проблема с форматом вашего csv-файла. Это происходит, например, при открытии файла Unix в среде Windows. В этом случае весь файл выглядит как одна строка, поскольку Windows и Unix имеют разные разделители строк. Итак, я не знаю конкретной причины вашей проблемы, но предлагаю подумать в этом направлении.

Обновление: У вас есть несколько путей через тело вашей петли:

  1. когда s равно "no": "They always want alerts, sending email" будет напечатано.
  2. , когда s не "no" и curtime in nrt: "They don't want an alert during the current hour, not sending" будет напечатано.
  3. , когда s не равно "no" и curtime in nrt ложно (последнее else): ничего не будет напечатано и никаких других действий не предпринимается.

Разве вы не должны поместить какой-нибудь оператор print в последнюю ветку else?

Кроме того, каков точный вывод вашего фрагмента? Это "They always want alerts, sending email"?

0 голосов
/ 30 марта 2009

Вы можете перейти к существующему хорошо написанному IRC-боту на Python Скачать

0 голосов
/ 29 марта 2009

Будьте явным с тем, что в строке. Использование 0, 1, 2 ... n на самом деле ваша ошибка, и это делает код очень трудным для чтения в будущем для вас или других. Итак, давайте используем удобный кортеж, чтобы показать, чего мы ожидаем от ряда. Такого рода код работает как документация

db = open("db.csv")
for line in db.readlines():
    recipient, start_hour, end_hour = line.split(",")
    nrt = []
    etc...

Это показывает читателю вашего кода, что вы ожидаете, чтобы строка содержала, и это показало бы вашу ошибку при первом запуске:

0 голосов
/ 29 марта 2009

Я бы проверил логику в ваших условных выражениях. Цикл конструирования должен работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...