I want to copy a list to another recursively in python. For that purpose, i have taken string as input, defined an empty list and send them to recursive function as lists, so that i can copy the list to another list. However, the error displays "NoneType" object has no attribute "append".
What am i missing ? i have defined "S" as list in main().
If there are other recursive methods, they are welcomed.
Error shown:
line 35, in string_copy
return string_copy(k,s.append(k[i]),i+1)
AttributeError: 'NoneType' object has no attribute 'append'
The code is :
def string_copy(k,s,i):
if (i == len(k)):
return s;
else:
return string_copy(k,s.append(k[i]),i+1)
def main():
print("enter the string you want to copy:");
k = input();
s = [None];
i = 0;
print("the type of k and s is:", type(k),type(s));
res = string_copy(list(k),list(s),i);
print("the desired results are:","\n", res);
if __name__ == "__main__": main() `
return string_copy(k,s.append(k[i]),i+1)
The list append() method does not return the updated list; it adds the new item in-place and returns None.
Therefore the next call to string_copy() will have None as the value for s.
The final solution is:
def string_copy(k,s,i):
if (i == len(k)):
return s
else:
s.append(k[i])
return string_copy(k,s,i+1)
def main():
print("enter the string you want to copy:")
k = input()
s = ""
i = 0;
print("the type of k is:", type(k))
res = string_copy(list(k),list(s),i)
print("the desired results are:","\n", "".join(res))
if __name__ == "__main__": main()
Better way of approaching this problem:
def string_copy(k):
if (len(k) == 0):
return k
else:
return k[0] + string_copy(k[1:])
def main():
print("enter the string you want to copy:")
k = input()
print("the type of k is:", type(k))
res = string_copy(k)
print("the copied string is:","\n",res)
if __name__ == "__main__": main()
Related
import random
value = {
"Two":2,"Three":3, "Four":4,
"Five":5, "Six":6, "Seven":7,
"Eight":8, "Nine":9, "Ten":10,
"Jack":10, "Queen":10, "King":10,
"Ace":10
}
suit = {
"H":"Hearts","C":"Clubs",
"S":"Spades","D":"Diamonds",
}
def getList(value):
return list(value.keys())
def getList(suit):
return list(suit.keys())
listValue = getList(value)
print(list)
listSuit = getList(suit)
deck = []
for s in listSuit:
for v in listValue:
deck.append((value[v], suit[s]))
random.shuffle(deck)
print(deck)
state = 'Y'
score = 0
print('Please answer with Y(yes) or N(no)!')
while (state == 'Y'):
print('Draw a card? (Y/N)')
state = input()
if (state == "Y"):
score += deck.top()
print(deck.pop())
print(score)
I don't know why, but it all works well up to that point — where I want to calculate the score using .top() — and just gets the error message
AttributeError: 'list' object has no attribute 'top'
It works with .pop() so I'm just confused.
If I understand correctly you want to get the first element in deck, add it to score, and then remove it from deck.
You will achieve this with the following code:
top_card = deck.pop(0) # return the first element in your list object and remove it from the object
score += top_card
My goal is to:
take an input (until user enters 0) or quit (if a letter is entered),
run a few checks to throw out non-integers,
add those values to a list, and
then print the sum of list.
I'm trying to capture the boolean value for variable close in main but I'm getting an error.
Error: "close = addToList() TypeError: addToList() missing 1 required
positional argument: 'numberList'."
#function to create a list
def createList():
numberList = []
return numberList
#function to add integers from user to list
def addToList(numberList):
stopAdding = False
close = False
while stopAdding == False:
integerInput = input("Please enter a number [1-9] or '0' to stop: ")
if integerInput.isalpha():
badInput()
close = True
break
elif integerInput == '0':
stopAdding = True
else:
numberList.append(int(integerInput))
if close == True:
return close
else:
return numberList
#function for when invalid number entered
def badInput():
print("Invalid number entered.")
#function to sum the numbers in list
def sumList(numberList):
sumTotal = 0
for number in numberList:
sumTotal = sumTotal + number
return sumTotal
#function to print the list sum
def printSum(sumTotal):
print("The sum is: ", sumTotal)
#the main function
def main():
numberList = createList()
addToList(numberList)
sumTotal = sumList(numberList)
close = addToList()
if close == True:
pass
else:
printSum(sumTotal)
#call main
main()
What would be a better way to exit gracefully if a non-integer was entered? Thanks.
Change you main function to look like this;
def main():
numberList = createList()
close = addToList(numberList)
sumTotal = sumList(numberList)
if not close:
printSum(sumTotal)
Other things you can do to make your code cleaner is to remove the sumList function and just use the builtin sum function, and remove the createList since it really doesn't need to be it's own function. Then your main would look like this;
def main():
numberList = []
close = addToList(numberList)
if not close:
printSum(sum(sumTotal))
You forgot your argument in the second call:
close = addToList(sumTotal)
Thanks guys/gals.
I got rid of my if else at the end of addToList function and returned both close value and numberList value: return (close,numberList)
And then for main use builtin sum function:
close, numberList = addToList(numberList)
#the main function
def main():
numberList = createList()
close, numberList = addToList(numberList)
if not close:
printSum(sum(numberList))
Lastly, for throwing out all non-integer inputs entered, I used:
if not stringname.isdigit():
Works well now.
This is a training version of Calculator, for some reason I am getting the error:
File "C:/Users/stazc/PycharmProjects/project00/Calculator.py", line 54, in calculate
print(sum(self.numY,self.numX))
TypeError: 'int' object is not iterable
The interesting part is that I am not using the iterator here, even though I wanted to. I executed the code before and run just fine the added some code for looping and it gave this error. Now the looping part is in comments so it should not affect the code although it is still giving me the same error!!
class Calculator:
numX = 0
numY = 0
__sign = ''
def __init__(self):
pass
# self.numX = x
# self.numY = y
# self.__sign = sign
def set_key_values(self):
print("Input numbers and then symbol")
self.numX = int(input("X: "))
self.__sign = input("Input symbol: ")
self.numY = int(input("Y: "))
#functions
def sum(self,numX, numY):
return numX+numY
def minus(self,numX, numY):
return numX-numY
def mult(self,numX, numY):
return numX*numY
def divide(self,numX, numY):
return numX/numY
#setters
def set_x(self,x):
self.numX = x
def set_y(self,y):
self.numY = y
def set_sign(self,sign):
self.__sign = sign
numX = numX
#getters
def get_x(self):
return self.numX
def get_y(self):
return self.numY
def get_sign(self):
return self.__sign
def calculate(self):
if self.__sign == '+':
print(sum(self.numY,self.numX))
elif self.__sign == '-':
print(self.minus(self.numX,self.numY))
elif self.__sign == '*':
print(self.mult(self.numX,self.numY))
elif self.__sign == '/':
print(self.divide(self.numX,self.numY))
else:
print('Incorrect Input, try again!')
c = Calculator()
c.set_key_values()
c.calculate()
Here I tried to add a loop that you can keep adding stuff but this error made my code stop working completely and can't see why?
#
# loop = input("Keep Going? y/n")
# cont = True
# if loop[0] == 'y':
# cont = True
# else:
# cont = False
#
# while cont:
# c = Calculator()
# c.set_key_values()
# c.calculate()
# else:
# quit()
#
The reason why you get this error:
print(sum(self.numY,self.numX))
TypeError: 'int' object is not iterable
Is because you are using Pythons built-in sum(iterable[, start]) method. And the first parameter it takes expects an iterable. Instead you will want to use your defined method self.sum that belongs to your Calculator class.
print(self.sum(self.numY,self.numX))
Replace sum() with self.sum() where you get your error.
You want to do this because python's version is different from yours and needs an iterable as first argument to work. Everything in your calculator is using the self function instead of the python too so thats another reason.
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.
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")