"list index out of range" exception (Python3) - python

I keep getting a list index out of range exception when I check the length of the list a. The error pops up for either the if or elif part of the second if statement, depending on what the user inputs. I know that when the user input is split the list is created correctly because I print it out... So I'm a little lost about why I'm getting that error.
if __name__ == '__main__':
for line in sys.stdin:
s = line.strip()
if not s: break
if (str(s) is "quit") == True: quit()
elif (str(s) is "quit") == False:
a = s.split()
print(a)
if (len(a) == 2) == True: first(a)
elif (len(a) == 3) == True: first(a)
else: print("Invalid Input. Please Re-enter.")
The first method is: (The methods it calls in the if statement just print things out at the moment)
def first(self, a = list()):
word = a[0]
if word is ls:
ls(a[1])
elif word is format:
form(a[1]) # EDIT: was format
elif word is reconnect:
reconnect(a[1])
elif word is mkfile:
mkfile(a[1])
elif word is mkdir:
mkdir(a[1])
elif word is append:
append(a[1], a[2])
elif word is delfile:
delfile(a[1])
elif word is deldir:
deldir(a[1])
else:
print("Invalid Prompt. Please Re-enter.")
Other methods:
def reconnect(one = ""):
print("Reconnect")
def ls(one = ""):
print("list")
def mkfile(one = ""):
print("make file")
def mkdir(one = ""):
print("make drive")
def append(one = "", two = ""):
print("append")
def form(one = ""):
print("format")
def delfile(one = ""):
print("delete file")
def deldir(one = ""):
print("delete directory")
def quit():
print("quit")
sys.exit(0)

The problem seems to be the definition of first(). You invoke it as a function:
if (len(a) == 2) == True: first(a)
elif (len(a) == 3) == True: first(a)
But you define it as a method:
def first(self, a = list()):
The array of command and argument gets put into self and a is always an empty list which you attempt to index and fail. Also, you shouldn't use a mutable type like list() as a default value unless you're certain what you are doing. I suggest simply:
def first(a):
As far as your __main__ code goes, simplify:
if __name__ == '__main__':
for line in sys.stdin:
string = line.strip()
if not string:
break
if string == "quit":
quit()
tokens = string.split()
length = len(tokens)
if 2 <= length <= 3:
first(tokens)
else:
print("Invalid Input. Please Re-enter.")

Real issue:
To solve your error you have to remove the self parameter of the first function
def first(a=list())
Basically the self is only used for object orientation creating methods.
Function like yours can't use self otherwise you will passing the first parameter to self not to a which you want to.
My second issue I can point out is that, You are trying to compare using is between a string and a function.
def first(a = list()):
word = a[0]
if word is "ls":
ls(a[1])
elif word is "format":
format(a[1])
elif word is "reconnect":
reconnect(a[1])
elif word is "mkfile":
mkfile(a[1])
elif word is "mkdir":
mkdir(a[1])
elif word is "append":
append(a[1], a[2])
elif word is "delfile":
delfile(a[1])
elif word is "deldir":
deldir(a[1])
else:
print("Invalid Prompt. Please Re-enter.")
Extra
The is function on built in operations in Python. is compare the equity of the objects.
But this expression:
if (str(s) is "quit") == True:
Can be simpler like:
if str(s) == "quit":
Or:
if str(s) is "quit":
The == True is meaningless either == False you can use not more pythonicly.

Related

Restarting while loop when returning None from another function

I am trying to program a Streets and Alleys card game with Python and I'm having some trouble handling when a function returns None. Essentially, my program prompts the menu of choices, then another line calling a function which is get_option. When the get_option is returned, it is returned as a list and the list could be either a single character long (U, R, H, Q), it could be 1 string and 2 ints (MTF 5 2) or just return None. In my main, I'm having trouble trying to restart my original while loop which contains the get_option function being called. If what I'm asking doesn't make sense, let me know and I can try to explain it more in depth. Here is my code:
def get_option():
'''Prints option menu and takes
user input to determine which
option will follow'''
while True:
option = str(input("\nInput an option (MTT,MTF,MFT,U,R,H,Q): ")).lower()
option_list = option.split()
mxx = ["MTT", "MTF", "MFT"]
for item in option_list:
mode = str(item[0])
for c in mode:
if c == "u":
option_list[0] = c.upper()
return option_list
if c == "r":
option_list[0] = c.upper()
return option_list
if c == "h":
option_list[0] = c.upper()
return option_list
if c == "q":
option_list[0] = c.upper()
return option_list
else:
print("Error in option:", option_list[0])
return None
break
if mode not in mxx:
return None
else:
return option_list
source = int(item[1])
if 7 > source > 0:
print("Error in Source.")
return None
else:
return option_list
destination = int(item[2])
if 3 > destination > 0:
print("Error in Destination")
return None
else:
return option_list
def main():
the_deck = cards.Deck()
print("\nWelcome to Streets and Alleys Solitaire.\n")
the_deck.shuffle()
the_deck.display()
print(MENU)
while True:
option_list = get_option()
while True:
if option_list == None:
option_list = get_option()
break
else:
break
if "U" in option_list:
print("Undo:")
continue
if "R" in option_list:
print("\n- - - - New Game. - - - -\n")
the_deck.shuffle()
the_deck.display()
continue
if "H" in option_list:
print(MENU)
continue
if "Q" in option_list:
break
print("Thank you for playing.")
if __name__ == '__main__':
main()
You shouldn't break in both the if and else branches of in the while loop. You need to repeat the loop until you get a result that isn't None, and that's when you should break out.
def main():
the_deck = cards.Deck()
print("\nWelcome to Streets and Alleys Solitaire.\n")
the_deck.shuffle()
the_deck.display()
print(MENU)
while True:
while True:
option_list = get_option()
if option_list is not None:
break
if "U" in option_list:
print("Undo:")
continue
if "R" in option_list:
print("\n- - - - New Game. - - - -\n")
the_deck.shuffle()
the_deck.display()
continue
if "H" in option_list:
print(MENU)
continue
if "Q" in option_list:
break
print("Thank you for playing.")
If you use a return statement inside a function, it will automatically break out of the function. If you need your function to continue to run you could try using a generator function or change your code so your while loop runs outside your function.

How can I fix EOF problem in the second script (below the dotted line)?

This program essentially encodes and decodes a message and code respectively. I only did the decoding part so far. However I keep getting an EOF error even though I made sure to end parentheses, checked my syntax and kept tampering with it. Unfortunately no luck. Anyone know why this error keeps popping up? I would greatly appreciate it. Also I copied both files that i'm using.
from LetterCodeLogic import LCL
def main():
print("Welcome to the LetterCode program")
choice = getChoice()
while choice !=0:
if choice == 1:
#Encode logic...
print()
elif choice == 2:
#Decode logic...
msg = input("Enter your numbers to decode (separate with commas): ")
#send msg to Decode function in LCL class (LetterCodeLogic.py file)
result = LCL.Decode(msg)
print("Your decoded message is: \n" + result)
else:
print("Unknown process...")
print()
choice = getChoice()
print("Thanks for using the Letter Code program")
def getChoice():
c = int(input("Choice? (1=Encode, 2=Decode, 0=Quit): "))
return c
if __name__ == "__main__":
main()
class LCL:
"""Encode/Decode Functions"""
#staticmethod
def Decode(msg):
#separate numbers from msg string (e.g., "1,2,3")
nums = msg.split(",") #produces list of separate items
result = ""
for x in nums:
try:
n = int(x.strip()) #remove leading/trailing spaces...
if n == 0:
c = " "
elif n < 0 or n > 26:
c = "?"
else:
#ASCII scheme has A=65, B=66, etc.
c = chr(n+64)
except ValueError:
c = "?"
result += c #same as: result = result + c
return result
#staticmethod
def Encode(msg):
the "#staticmethod" and "def Encode()" function was empty and that was the end of line parsing error. When I was coding this and ran it, it ran with no problems. So I removed it for the time being.

NameError: name 'form' is not defined (Python3)

Basically the main method takes user input, checks it and calls the first method if the user doesn't enter quit.
The first method checks the first section of the input and calls one of the other methods depending on what the user enters. This is the point I get an error; when the first method calls the form method, for example, I get an NameError: name 'form' is not defined exception. I'm a little confused about this since I've defined each method and they're all spelt correctly, also when I call the quit method it works perfectly fine.
Main method:
if __name__ == '__main__':
for line in sys.stdin:
s = line.strip()
if not s: break
if (str(s) == "quit"): quit()
elif (str(s) == "quit") == False:
a = s.split()
print(a)
if (len(a) is 2): first(a)
elif (len(a) is 3): first(a)
else: print("Invalid Input. Please Re-enter.")
First method:
def first(a = list()):
word = a[0]
if word == "ls":
ls(a[1])
elif word == "format":
form(a[1])
elif word == "reconnect":
reconnect(a[1])
elif word == "mkfile":
mkfile(a[1])
elif word == "mkdir":
mkdir(a[1])
elif word == "append":
append(a[1], a[2])
elif word == "delfile":
delfile(a[1])
elif word == "deldir":
deldir(a[1])
else:
print("Invalid Prompt. Please Re-enter.")
Other methods (these are all called from the first method):
def reconnect(one = ""):
print("Reconnect")
def ls(one = ""):
print("list")
def mkfile(one = ""):
print("make file")
def mkdir(one = ""):
print("make drive")
def append(one = "", two = ""):
print("append")
def form(one = ""):
print("format " + one)
def delfile(one = ""):
print("delete file")
def deldir(one = ""):
print("delete directory")
def quit():
print("quit")
sys.exit(0)
this error is because of
elif word == "format":
form(a[1])
python basically doesn't know what form is.
let me show you:
gaf#$[09:21:56]~> python
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> form()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'form' is not defined
>>>
there is two ways out
>>> def form():
... pass
...
>>> form()
>>> form
<function form at 0x7f49d7f38a28>
>>>
or import it form some library using
import
command
also order is matters too
try:
form()
except NameError:
print('Oops name error raise above')
def form():
print('form foo is called')
try:
form()
except NameError:
print('Oops name error raise below')
will give you
/home/gaf/dashboard/bin/python /home/gaf/PycharmProjects/dashboard/test.py
Oops name error raise above
form foo is called
Process finished with exit code 0
P.S.
take a look at pep8
your code is a mess %)
but no worries this what everybody does with first language
It depends if you use python 2.7 or 3, but your code works with some minor changes.
import sys
def reconnect(one=""):
print("Reconnect")
def ls(one=""):
print("list")
def mkfile(one=""):
print("make file")
def mkdir(one=""):
print("make drive")
def append(one="", two=""):
print("append")
def form(one=""):
print("format " + one)
def delfile(one=""):
print("delete file")
def deldir(one=""):
print("delete directory")
def quit():
print("quit")
sys.exit(0)
def first(a=list()):
word = a[0]
if word == "ls":
ls(a[1])
elif word == "format":
form(a[1])
elif word == "reconnect":
reconnect(a[1])
elif word == "mkfile":
mkfile(a[1])
elif word == "mkdir":
mkdir(a[1])
elif word == "append":
append(a[1], a[2])
elif word == "delfile":
delfile(a[1])
elif word == "deldir":
deldir(a[1])
else:
print("Invalid Prompt. Please Re-enter.")
line = raw_input("Some input please: ") # or `input("Some...` in python 3
print(line)
s = line.strip()
if (str(s) == "quit"):
quit()
elif (str(s) == "quit") == False:
a = s.split()
print(a)
if (len(a) is 2):
first(a)
elif (len(a) is 3):
first(a)
else:
print("Invalid Input. Please Re-enter.")
Test
python pyprog.py
Some input please: ls text.txt
ls text.txt
['ls', 'text.txt']
list
You can also try it online.

int() argument must be a string or a number

I got an error. I did quick googling and it did not help me well.
I added the whole code, well kind of whole code. request from a user.
from derp_node import *
##############################################################################
# parse
##############################################################################
def parse(tokens, i = 0):
"""parse: tuple(String) * int -> (Node, int)
From an infix stream of tokens, and the current index into the
token stream, construct and return the tree, as a collection of Nodes,
that represent the expression.
NOTE: YOU ARE NOT ALLOWED TO MUTATE 'tokens' (e.g. pop())!!! YOU
MUST USE 'i' TO GET THE CURRENT TOKEN OUT OF 'tokens'
"""
if tokens == []:
raise TypeError("Error: Empty List.")
elif tokens[int(i)] == '*':
tokens.remove(int(i))
return mkMultiplyNode(parse(tokens), parse(tokens))
elif tokens[int(i)] == '//':
tokens.remove(int(i))
return mkDivideNode(parse(tokens), parse(tokens))
elif tokens[int(i)] == '+':
tokens.remove(int(i))
return mkAddNode(parse(tokens), parse(tokens))
elif tokens[int(i)] == '-':
tokens.remove(int(i))
return mkSubtractNode(parse(tokens), parse(tokens))
elif tokens[int(i)].isdigit():
return mkLiteralNode(tokens.remove(int(i)))
elif not tokens[int(i)].isdigit():
return mkVariableNode(tokens.remove(int(i)))
else:
raise TypeError("Error: Invalid Input")
##############################################################################
# main
##############################################################################
def main():
"""main: None -> None
The main program prompts for the symbol table file, and a prefix
expression. It produces the infix expression, and the integer result of
evaluating the expression"""
print("Hello Herp, welcome to Derp v1.0 :)")
inFile = input("Herp, enter symbol table file: ")
symTbl = {}
for line in open(inFile):
i = line.split()
symTbl[i[0]] = int(i[1])
print("Derping the symbol table (variable name => integer value)...")
for variable in sorted(symTbl):
print(variable + " => " + str(symTbl[variable]))
# STUDENT: CONSTRUCT AND DISPLAY THE SYMBOL TABLE HERE
print("Herp, enter prefix expressions, e.g.: + 10 20 (RETURN to quit)...")
# input loop prompts for prefix expressions and produces infix version
# along with its evaluation
while True:
prefixExp = input("derp> ")
if prefixExp == "":
break
# STUDENT: GENERATE A LIST OF TOKENS FROM THE PREFIX EXPRESSION
prefixLst = prefixExp.split()
# STUDENT: CALL parse WITH THE LIST OF TOKENS AND SAVE THE ROOT OF
# THE PARSE TREE.
tokens = []
parseLst = parse(prefixLst, tokens)
# STUDENT: GENERATE THE INFIX EXPRESSION BY CALLING infix AND SAVING
# THE STRING
infixLst = infix(parseLst)
print("Derping the infix expression:")
# STUDENT: EVALUTE THE PARSE TREE BY CALLING evaluate AND SAVING THE
# INTEGER RESULT
print("Derping the evaluation:")
print("Goodbye Herp :(")
if __name__ == "__main__":
main()
The error I received is:
File "derpNew.py", line 31, in parse
if tokens[int(i)] == '*':
TypeError: int() argument must be a string or a number, not 'list'
If I remove the int() from the variable i, then I would get this error: TypeError: list indices must be integers, not list
Am I suppose to convert the list to tuple? Any help would be great. Thank you.
If you guys are curious how I am calling the parse. I put this under main function.
tokens = []
parseLst = parse(tokens, i)
EDIT:
The loop:
while True:
prefixExp = input("derp> ")
if prefixExp == "":
break
prefixLst = prefixExp.split()
tokens = []
parseLst = parse(tokens, i)
parseLst = parse(tokens, i) - this line doesn't make sense unless you define i. If you want to pass default i=0, then just leave it out: parseLst = parse(tokens).
EDIT: After the whole code has been pasted, there is some (apparently irrelevant) i defined before, which is why there was no NameError.
The passed variable i is a list, that's why the errors! Would need more info on the arguments being passed to help you more!
List indices work like this
>>> my_list = [1, 2, 3, 4, 5]
>>> for index in range(5):
... print my_list[i]
1
2
3
4
5
>>> my_list[3]
4
What are you passing to the method parse(...) as second parameter? If it's a list, it shouldn't. You may want to change the value you are passing to parse.
You may also want to check if tokens is an empty list, before the other ifs, or it will cause another error.
if tokens == []:
raise TypeError("Error: Empty List.")
elif tokens[int(i)] == '*':
tokens.remove(int(i))
return mkMultiplyNode(parse(tokens), parse(tokens))
return mkSubtractNode(parse(tokens), parse(tokens))
elif tokens[int(i)].isdigit():
return mkLiteralNode(tokens.remove(int(i)))
elif not tokens[int(i)].isdigit():
return mkVariableNode(tokens.remove(int(i)))
else:
raise TypeError("Error: Invalid Input")

Exploring a maze (using python 2.7)

I have done everything on my homework except a one step.
I did it in a different way, but it gave kind of right answer somehow.
Anyway, I have to explore a maz, so I went all the way through and got everything completely right, except part (Q COMMAND) of this task.
I need to use string method .upper()
2.2.6 The Top-Level Interface
interact() is the top-level function that denes the text-base user interface
as described in the introduction.
Note that when either the user quits or
when the finish square is found, the interact function should exit.
def interact():
mazefile = raw_input('Maze File: ')
maze = load_maze(mazefile)
position = (1, 1)
poshis = [position]
while True:
#print poshis, len(poshis)
print 'You are at position', position
command = raw_input('Command: ')
#print command
if command == '?':
print HELP
elif command == 'N' or command == 'E' or command == 'S'or command == 'W':
mov = move(maze, position, command)
if mov[0] == False: #invalid direction
print "You can't go in that direction"
elif mov[1] == True:#finished
print 'Congratulations - you made it!'
break
else: #can move, but not finished
position = mov[2]
poshis.append(position)
elif command == 'R': # reseting the maze to the first pos
position = (1, 1)
poshis = [position]
elif command == 'B': # back one move
if len(poshis) > 1:
poshis.pop()
position = poshis[-1]
elif command == 'L': # listing all possible leg dir
toggle = 0
result = ''
leg_list = get_legal_directions(maze, poshis[-1])
for Legal in leg_list:
if toggle:
result += ', '
result += Legal
else:
result += Legal
if not toggle:
toggle = 1
print result
elif command == 'Q': #quiting
m = raw_input('Are you sure you want to quit? [y] or n: ')
if m == 'y':
break
#print 'Are you sure you want to quit? [y] or n: '
#if raw_input == 'y':
# break
else: #invalid input
print 'Invalid Command:', command
Your question isn't particularly clear, but I'm guessing that the 'problem' is that if a user were to answer "Y" instead of "y" when asked if they are sure they want to quit, then the loop will continue.
If that is the problem, you should merely replace the line:
if m == 'y':
break
with:
if m.upper() == 'Y':
break
Because regardless of whether the user types "y" or "Y", the loop will still be broken out of.

Categories