Python: список назначений вне диапазона - PullRequest
0 голосов
/ 11 марта 2010

Этот модуль является частью простого приложения todo, которое я сделал с помощью Python ...

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

Число строк в f, очевидно, изменяется при добавлении элементов в список ... Проблема здесь в том, что, например, если пользователь вводит «10», когда в файле только 9 строк (или что-то еще, не находящееся в диапазоне ), он выходит, как и ожидалось, с:

IndexError: list assignment index out of range

Что я могу добавить к модулю, чтобы он предлагал пользователю ввести элемент в пределах диапазона? Я предполагаю, может быть, блок Try ... Или есть способ поймать исключение .. Я предполагаю, что есть простой способ сделать это ...

Ответы [ 6 ]

3 голосов
/ 11 марта 2010

Сначала прочитайте файл, а затем спросите пользователя в цикле, пока ответ не будет приемлемым:

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

Это, конечно, сломается, когда файл пуст и не дает никаких подсказок о приемлемых значениях для пользователя. Но давайте продолжим для вас упражнения.

3 голосов
/ 11 марта 2010

Либо поймайте IndexError при индексации, либо заранее проверьте len() списка.

1 голос
/ 11 марта 2010

Разумные изменения в вашем текущем коде:

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 голосов
/ 11 марта 2010

Для чего бы это ни стоило .... Я добавлю код в мою программу todo.py здесь ... Это просто то, что я запускаю из терминала в OS X, чтобы сохранить контроль над тем, что мне нужно делать на работе. ... Я уверен, что это ужасно непитонно, неэффективно и все остальное ... но, возможно, это будет полезно кому-то, кто натыкается на эту тему:

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 голосов
/ 11 марта 2010

Попробуйте что-то вроде этого:

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 голосов
/ 11 марта 2010
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()
...