2010-03-11 6 views
0

Ce module fait partie d'une application simple todo J'ai fait avec Python ...Python: affectation de liste hors de portée

def deleteitem(): 
      showlist() 
      get_item = int(raw_input("\n Enter number of item to delete: \n")) 
      f = open('todo.txt') 
      lines = f.readlines() 
      f.close() 
      lines[get_item] = "" 
      f = open('todo.txt','w') 
      f.writelines(lines) 
      f.close() 
      showlist() 

Le nombre de lignes f change évidemment que les éléments sont ajoutés à la liste .. . le problème est ici que, par exemple si un utilisateur entre « 10 » quand il y a seulement 9 lignes dans le fichier (ou toute autre chose hors de portée), quand elle sort comme prévu avec:

IndexError: list assignment index out of range 

que puis-je ajouter à le module de façon à ce qu'il invite l'utilisateur à entrer un élément dans la gamme? Je suppose que peut-être un bloc Try ... Ou y at-il un moyen d'attraper une exception .. Je devine qu'il y a un moyen facile de le faire ...

Répondre

1

changements à votre code judicieux actuel:

def deleteitem(): 
    showlist() 

    with open("todo.txt") as f: 
    lines = f.readlines() 
    if len(lines) == 0: # completely empty file 
    return # handle appropriately 
    prompt = "Enter number to delete (1-%d), or 0 to abort: " % len(lines) 
    while True: 
    input = raw_input(prompt) 
    try: 
     input = int(input, 10) 
    except ValueError: 
     print "Invalid input." 
    else: 
     if 0 <= input <= len(lines): 
     break 
     print "Input out of range." 
    if input == 0: 
    return 
    input -= 1 # adjust from [1,len] to [0,len) 

    #del lines[input] # if you want to remove that line completely 
    lines[input] = "\n" # or just make that line blank (what you had) 

    with open("todo.txt", "w") as f: 
    f.writelines(lines) 

    showlist() 
+0

Merci, cela a fonctionné. J'utilise Python 2.5.x..donc je me suis accroché avec 'avec'. J'ai ajouté "de future__import__ with_statement" au script et tout a été défini. Je pense que dans votre code, la ligne "if len (lines) == 0:" peut avoir besoin d'être indentée? ... Je recevais une erreur jusqu'à ce que je l'ai fait – cit

+0

@skylarking: Il ne devrait pas besoin d'indentation, et cette partie devrait fonctionner correctement comme je l'ai ci-dessus. Peut-être que vous avez accidentellement maugréé? –

+0

C'est très probable que j'ai fait une erreur là-bas .... J'ai posté l'application todo complète comme une réponse ici si vous êtes curieux.Je suis sûr qu'il y a beaucoup d'améliorations qui peuvent arriver là aussi. – cit

3

Soit prendre IndexError lors de l'indexation ou vérifier le len() du liste à l'avance.

3

d'abord lire le fichier, puis demander à l'utilisateur dans une boucle, jusqu'à ce que la réponse est acceptable:

while True: 
    get_item = int(raw_input("\n Enter number of item to delete: \n")) 
    if get_item >=0 and get_item < len(lines): 
     break 

Cela, bien sûr, pause lorsque le fichier est vide et ne donne aucune indication sur les valeurs acceptables pour l'utilisateur. Mais gardons un peu d'exercice pour vous.

+0

Ajoutez une belle sortie qui indique le problème à l'utilisateur. –

0
def deleteitem(): 
      showlist() 
      get_item = int(raw_input("\n Enter number of item to delete: \n")) 
      f = open('todo.txt') 
      lines = f.readlines() 
      f.close() 
      try: 
       lines[get_item] = "" 
      except Exception,err: 
       print err 
      f = open('todo.txt','w') 
      f.writelines(lines) 
      f.close() 
      showlist() 
+0

Bares excepts ont quelques utilisations valables, mais ce n'est pas l'un d'entre eux. –

+0

mais c'est suffisant pour son but et il fait le travail. Anymore commentaires? – ghostdog74

+1

Non, ce n'est pas le cas. Il avale silencieusement KeyboardInterrupt, par exemple, si vous avez eu la malchance de l'obtenir au bon moment (ou à un mauvais moment). Autant que possible, je conçois mon code de manière à ce qu'il fonctionne comme prévu et souhaité même dans de telles situations «malchanceuses» et ne peut pas recommander ce code de manière éthique. Est-ce que c'est même si difficile de le corriger? Remplacez "except:" par "sauf IndexError:". –

0

Essayez quelque chose comme ceci:

def deleteitem(): 

showlist() 
f = open('todo.txt') 
lines = f.readlines() 
f.close() 
if len(lines) == 0: 
    print "File is empty!" 
    return False 
print "File has %d items\n" % len(lines) 
item = 0 
while item < len(lines): 
    item = raw_input("\n Enter number of item to delete(0-%d): \n" % len(lines)) 
    item = int(item) # because of the width of the code 
f = open('todo.txt','w') 
f.write(lines[0:item-1]) 
f.write(lines[item::]) 
f.close() 
showlist() 
0

Pour ce que ça vaut la peine .... Je vais mettre le code à mon todo .py programme ici ... C'est juste quelque chose que je cours d'un terminal sous OS X pour garder le contrôle des choses que je dois faire au travail ... Je suis sûr que c'est horriblement non-pythonique, inefficace et tout le reste ... mais peut-être il sera utile à quelqu'un qui trébuche à travers ce fil :

from __future__ import with_statement 
import sys 
import os 
import fileinput 

os.system('clear') 

print ("##############   TO DO LIST  ############") 
print ("##############       ############") 

def showlist(): 
    os.system('clear') 
    print ("############ Current To Do List ######") 
    print ("########################################") 

    get_list = open('todo.txt') 
    entire_list = get_list.readlines() 
    for i in range (len(entire_list)): 
     print i, entire_list[i] 
    get_list.close() 
    print ("########################################") 
    print ("########################################") 

def appendlist(): 
    print ("#######################################") 
    print ("#######################################") 


    addtolist = str(raw_input("Enter new item: \n")) 
    thelist = open('todo.txt', 'a') 
    thelist.write(str(addtolist)) 
    thelist.write(str('\n')) 
    thelist.close() 
    showlist() 


def deleteitem(): 
    showlist() 

     with open("todo.txt") as f: 
      lines = f.readlines() 
      if len(lines) == 0: 
       return 
     prompt = "Enter number to delete or '0' to abort: " 
     while True: 
       input = raw_input(prompt) 
       try: 
        input = int(input, 10) 
       except ValueError: 
        print "Invalid input." 
       else: 
        if 0 <= input <= len(lines): 
         break 
        print "Input out of range." 
     if input == 0: 
        return 

     lines[input] = "" 

      with open("todo.txt", "w") as f: 
       f.writelines(lines) 

     showlist() 

while True: 

    askme = raw_input("\nDo you want to:\n(S)ee list\n(A)ppend list\n(D)elte from list\n(Q)Quit?\n") 
    print str('\n') 

    if askme == "S": 
     showlist() 
    elif askme == "A": 
     appendlist() 
    elif askme == "D": 
     deleteitem() 

    elif askme == "Q": 
     sys.exit() 
    else: 
     print ("Try again?") 

print ("#######################################") 
print ("#######################################") 
+0

Vous mélangez des onglets et des espaces, ou l'indentation a été bousillée lors de la publication sur SO. –

+0

Je pense que je suis allé pour le trifecta et a réussi à faire toutes ces trois choses .. Juste édité pour le nettoyer. – cit

Questions connexes