2009-03-29 11 views
1

J'apprends Python comme deuxième langage de programmation (mon premier vrai si vous ne comptez pas HTML/CSS/Javascript). J'essaye de construire quelque chose d'utile comme ma première vraie application - un robot IRC qui alerte les gens par SMS quand certaines choses arrivent dans le canal. À la demande de quelqu'un, j'essaie de créer des préférences de planification où les gens peuvent choisir de ne pas recevoir d'alertes entre les heures X et Y du jour.Aide avec l'étrangeté de la boucle Python?

Quoi qu'il en soit, voici le code que je vais avoir du mal avec:

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 

Le seul problème que je vais avoir est en quelque sorte le script se termine seulement en boucle à travers l'une des lignes (ou quelque chose comme ça) parce que Je n'obtiens qu'un seul résultat à chaque fois, même si j'ai plus d'une entrée dans le fichier CSV.

+0

En général, je n '; t écrire un bot IRC à partir de zéro, et je voudrais essayer d'empêcher les autres de le faire aussi. Ecrire un plugin pour supybot, ou gozerbot. –

+0

Ce n'est pas du tout un robot IRC, tout ce qu'il fait est d'utiliser des sockets, de rejoindre une salle et de déclencher la fonction "envoyer un message" quand il voit x se produire. En d'autres termes, je n'ai pas besoin de toutes les fonctionnalités de Supybot. –

+0

Etes-vous sûr que le programme n'échoue pas ou ne lance pas d'exception? – theycallmemorty

Répondre

7

Il y a au moins deux bugs dans votre programme:

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

D'abord, curtime est une chaîne, alors que TRN est une liste de entiers. Python est fortement typé, donc les deux ne sont pas interchangeables, et ne comparera pas égale:

'4' == 4 # False 
'4' in [3, 4, 5] # False 

Ce code révisé aborde cette question, et est plus efficace que la génération d'une liste et la recherche de l'heure actuelle dans ce :

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

Une deuxième question que le ne répond pas au-dessus est que votre programme ne se comportera pas correctement si les heures wrap vers minuit (par exemple s = 22 et f = 8).

Aucun de ces problèmes n'est nécessairement lié au fait que "le script ne fait que passer en boucle sur l'une des lignes", mais vous ne nous avez pas donné suffisamment d'informations pour comprendre pourquoi cela pourrait être le cas. Un moyen plus utile de poser des questions est de poster un bref mais complet extrait de code qui montre le comportement que vous observez, avec l'exemple d'entrée et les messages d'erreur qui en résultent, le cas échéant (avec traceback).

0

Je vérifierais la logique dans vos conditions. Vous construisez en boucle devrait fonctionner.

+0

Vraiment bizarre, j'ai franchi le flot des instructions if et il me semble que ça devrait marcher. –

0

Soyez explicite avec ce qui est dans une rangée. Utiliser 0, 1, 2 ... n est en fait votre bogue, et cela rend le code très difficile à lire dans le futur pour vous ou pour les autres. Alors utilisons le tuple pratique pour montrer ce que nous attendons d'une rangée. Ce genre d'ouvrages comme le code comme documentation

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

Cela montre le lecteur de votre code ce que vous vous attendez à une ligne pour contenir, et il aurait montré votre bug pour vous la première fois que vous diffusait :)

+0

'pour line in db' se répète déjà sur chaque ligne du fichier. C'est fonctionnellement équivalent à 'pour line dans db.readlines()' mais plus de mémoire efficace, car il ne lit pas le fichier entier dans une liste. – Miles

+0

Deuxième suggestion est bonne, cependant. – Miles

+0

Ahh je ne connaissais pas le fichier itéré comme ça, merci pour l'info. :) –

5

Avez-vous essayé quelque chose de plus simple? Juste pour voir comment votre fichier est lu en fait par Python:

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

Il peut y avoir problème avec le format de votre fichier csv. Cela se produit, par exemple, lorsque vous ouvrez un fichier Unix dans un environnement Windows. Dans ce cas, le fichier entier ressemble à une chaîne unique comme Windows et Unix ont des séparateurs de ligne différents. Donc, je ne connais pas la cause de votre problème, mais je vous propose de penser dans cette direction.

Mise à jour: Votre ont de multiples façons à travers le corps de la boucle:

  1. quand s est "no": "They always want alerts, sending email" sera imprimé.
  2. lorsque s n'est pas "no" et curtime in nrt: "They don't want an alert during the current hour, not sending" sera imprimé.
  3. quand s n'est pas "no" et curtime in nrt est faux (la dernière else): rien sera imprimé et aucune autre action entreprise.

Ne devez-vous pas placer une instruction print dans la dernière branche else?

En outre, quelle est la sortie exacte de votre extrait? Est-ce "They always want alerts, sending email"?

+0

Ceci est un bon moyen de résoudre votre problème. –

+0

Non, ça correspond. –

+0

Les deux extraits s'arrêtent-ils avec un résultat? – Rorick

9

S'il s'agit d'un fichier CSV normal, vous ne devriez pas essayer de l'analyser vous-même. Utilisez la bibliothèque standard csv module.

Voici un court exemple de la documentation:

import csv 
reader = csv.reader(open("some.csv", "rb")) 
for row in reader: 
    print row 
+0

+1 pour ne pas avoir réinventé la roue :) – bedwyr

0

Vous pouvez aller thro un bot IRC bien écrit en Python existant Download