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
Related
I have a defined function that includes a counter to know how many times it has been used, and asks for a user input of either L, R or F.
I want it to then check the input and add it to the counter and call the function of that name.
eg:
user choose L
count is at 3
call function L3
here is what I have so far, but I get an error:
def getUserDirection():
getUserDirection.counter = 0
getUserDirection.counter += 1
direction = str(input("Which direction do you wish to go? (L/F/R) "))
direction = direction.upper()
if direction not in ("L", "F", "R"):
print("whats does {} mean? You were meant to type 'L', 'F' or 'R'! Try again..".format(direction))
direction = getUserDirection()
elif direction == "L":
print(direction()+counter())
elif direction == "F":
print(direction()+counter())
elif direction == "R":
print(direction()+counter())
return getUserDirection()
The other functions I want it to call are:
def L1():
print("you go left and see...")
def F1():
print("You continue forward and see...")
def R1():
print("You go right and see...")
The idea is to loop through getUserDirection() and call a different function with each pass. There will be plenty of functions as it progresses eg L1, L2, L3... each having a different story and new choice of direction to make.
What am I doing wrong?
FULL CODE
#PLAYER DETAILS
first_name = input("What is your first name? ")
last_name = input("What is your last name? ")
while True:
middle = input("Do you have a middle name? (y/n) ")
if middle.upper() not in ("Y", "N"):
print("whats does {} mean? You were meant to type 'y' or 'n'! Try again.." .format(middle))
elif middle.upper() == "Y":
middle_name = input("What is it? ")
break
elif middle.upper() == "N":
middle_name = None
break
# is_middle_empty = bool(middle_name)
# print(is_middle_empty)
print("So your full name is {} {} {}? ".format(first_name, '' if middle_name is None else middle_name, last_name))
import time
time.sleep(1)
print("Hmmm..")
time.sleep(1)
just_first = str(input("Should I just call you {}? (y/n) ".format(first_name)))
if just_first.upper() == "Y":
player = first_name
print("Great, nice to meet you", player)
elif just_first.upper() != "Y":
name = first_name, "" if middle_name is None else middle_name, last_name
player = " ".join(name)
print("Sorry about that, let's stick to {} then." .format(player))
print()
#DIRECTION FUNCTION
def getUserDirection():
getUserDirection.counter = 0
getUserDirection.counter += 1
direction = str(input("Which direction do you wish to go? (L/F/R) "))
direction = direction.upper()
if direction not in ("L", "F", "R"):
print("whats does {} mean? You were meant to type 'L', 'F' or 'R'! Try again..".format(direction))
direction = getUserDirection()
elif direction == "L":
print(direction()+counter())
elif direction == "F":
print(direction()+counter())
elif direction == "R":
print(direction()+counter())
return getUserDirection()
#STORY LINES
def start():
print("You have arrived at ... To your left (L) is ..., ahead (F) is ... To your right (R) is ...")
def L1():
print("you go left")
def F1():
print("You continue forward")
def R1():
print("You turn right")
#ADVENTURE-1
adventure = input("So do you fancy a quick adventure? (y/n) ")
if adventure.upper() == "Y":
print("Great then lets set off...")
elif adventure.upper() == "N":
print("Ah well, I guess we can't all be ubercool adventurers like me, fairwell {}, I hope we meet again some day." .format(player))
#ADVENTURE-2
time.sleep(1)
print(start())
print(getUserDirection())
ERROR TRACEBACK
Traceback (most recent call last):
File "C:\Users\admin\PycharmProjects\pythonProject1\main.py", line 70, in <module>
print(getUserDirection())
File "C:\Users\admin\PycharmProjects\pythonProject1\main.py", line 43, in getUserDirection
print(direction()+counter())
TypeError: 'str' object is not callable
The cleanest way is to store your functions in a dict-
def L1():
print("you go left and see...")
def F1():
print("You continue forward and see...")
def R1():
print("You go right and see...")
# define more functions....
inp_to_func = {
'L1': L1,
'F1': F1,
'R1': R1
# define more key-value pairs....
}
Which you can then use like-
func = inp_to_func.get(f'{direction}{counter()}')
if not func:
# no function found for input
# do error handling here
pass
else:
func()
This assumes direction is a string and counter() returns a number - and combining them in the shown order forms the key in the dictionary.
Edit: If you have a counter variable instead, and not a function - you'd have to do f'{direction}{counter}' of course. It just seemed from your code that counter is a function you have defined that returns a number.
Suppose direction is a string variable with the value of 'L', and counter is an int variable with the value of 1.
f'{direction}{counter}' gives you 'L1'
If L1 is a key in the inp_to_func dictionary and its value is a function object, inp_to_func.get('L1') will return said function object.
The function object can now be treated like any other function, that is - it can be called using parens - ().
So, going line by line-
func = inp_to_func.get(f'{direction}{counter}')
# ^ Gets the function object corresponding to the input, or `None`
if not func:
# ^ func was `None` (as in, no key was found)
# no function found for input
# do error handling here
pass
else:
func()
# ^ calls the function
You can do this by accessing the globals or by using eval.
direction, counter = "L", 1
globals()[f"{direction}{counter}"]() # globals return a dictionary, where you can access the variable through this dictionary.
eval(f"{direction}{counter}()") # eval evaluates python expression, in this case, the function call
This is what you're looking for based on your question, although if I would do this... I would probably create a single function then pass the direction and counter arguments to it.
def fun(direction, counter):
if direction == "L":
if counter == 1:
# do something...
elif direction == "R":
# do something...
direction, counter = "L", 1
# then you'll call it like...
fun(direction, counter)
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()
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 got a problem in this part
it seems like many people do get this error
but i cant find one i understand and solve my quetion
i post the whole code on it so i hope people who want to help can spotted even the hidden issues
import random
import sys
global err
global games
global avr
global letter,mults1,mults2,quo1,quo2,ans
def generate():
mults=[random.randint(100,999),random.randint(10,99)]
return mults
def cypher():
let=["A","B","C","D","E","F","G","H","I","J"];
random.shuffle(let)
return let
def display():
print letter
print " ",check(mults1[0]),check(mults1[1]),check(mults1[2])
print "* ",check(mults2[0]),check(mults2[1])
print "------------"
print " ",check(quo1[0]),check(quo1[1]),check(quo1[2]),check(quo1[3])
print " ",check(quo2[0]),check(quo2[1]),check(quo2[2]),check(quo2[3])
print "------------"
print "=",check(ans[0]),check(ans[1]),check(ans[2]),check(ans[3]),check(ans[4])
# if winthegame : return 1
# else : return 0
def check(i):
if i in letter: return letter[i]
else : return i
def play():
inplet=raw_input('Enter the LETTER (A-J): ')
number=raw_input('Enter the matched NUMBER (0-9): ')
number=int(number)
print number
if number in letter : #TypeError argument of type 'int' is not iterable
if inplet == letter[number] : #without the line above Shows another error #'int' object has no attribute '_getitem_' here
print "Answer matched !"
del letter[number]
return true
return false
#main part
while 1:
mul=generate()
print mul
mults1=[mul[0]/100,(mul[0]/10)%10,mul[0]%10]
mults2=[mul[1]/10,mul[1]%10]
tmp1=mul[0]*mults2[1]
quo1=[tmp1/1000,(tmp1/100)%10,(tmp1/10)%10,tmp1%10]
tmp2=mul[0]*mults2[0]
quo2=[tmp2/1000,(tmp2/100)%10,(tmp2/10)%10,tmp2%10]
tmp3=mul[0]*mul[1]
ans=[tmp3/10000,(tmp3/1000)%10,(tmp3/100)%10,(tmp3/10)%10,tmp3%10]
let=cypher()
letter={0:let[0],1:let[1],2:let[2],3:let[3],4:let[4],5:let[5],6:let[6],7:let[7],8:let[8],9:let[9]}
#clean the dictionary
checker=[0,0,0,0,0,0,0,0,0,0]
i=0
while i<3:checker[mults1[i]]=1;i+=1
i=0
while i<2:checker[mults2[i]]=1;i+=1
i=0
while i<4:checker[quo1[i]]=1;i+=1
i=0
while i<4:checker[quo2[i]]=1;i+=1
i=0
while i<5:checker[ans[i]]=1;i+=1
i=0
while i<10:
if checker[i]==0 : del letter[i]
i+=1
display()
letter=input();
#game start
while 1:
play()
thanks a lot for help
ended up i fix it myself
number=raw_input('Enter the matched NUMBER (0-9): ')
number=int(number)
print number
if number in letter : #TypeError argument of type 'int' is not iterable
if inplet == letter[number] : # ERROR
i add a new container for int instead of just resigned it
numb=raw_input('Enter the matched NUMBER (0-9): ')
number=int(numb)
print number
if number in letter : #TypeError argument of type 'int' is not iterable
if inplet == letter[number] : # NO ERROR
Thank you all for help
I Have a list, and every time I enter "N" in my program I want the list to print the contents of the next index.
categories = ["Produce", "Meat", "Dairy" ,"Misc"]
...
elif item == "N":
for d in categories[:1]:
d = categories[0]
d += 1
print(d)
I understand that the above code is trying to add an integer to a string and throwing the error. What I haven't been able to figure out is how to increment the index.
I have looked at a few other posts concerning similar problems but it the solutions aren't clicking for me out of context.
Sample output of what it should look like
Add Item to list
Produce
>>Tomatoes
>>Grapes
Meat
>>Hamburger
Dairy
>>
Entire program
def add_item():
exit_list = ["F", "Finished"]
lists = []
start = input("Would you like to add an item to the list? Y/N")
print("Add Item to list")
categories = ["Produce", "Meat", "dairy","snacks/boxed goods", "Cans", "Misc"]
print(categories[0])
while start in ('y', 'Y'):
item = input(">>")
if item in exit_list:
break
elif item == "N":
for d in categories[:1]:
i = 0
i +=1
d = categories[i]
print(d)
elif item:
lists.append(item)
else:
print("ok")
print(lists)
return lists
add_item()
This code will keep track of an index and increment it each time it's used:
i = 0
categories = ["hey", "1", "2" ,"3"]
...
elif item == "N":
print(categories[i])
i += 1
And note that this code will eventually go out of bounds. If you want to wrap around you can do e.g. % len(categories) on i.
Most of the time it is possible, if not better, to avoid using index in Python. One way in your case would be to use a generator on your list. The following code will quit when the user enters q, print the next item when the user enters n, and do nothing if the input is something else.
categories = ["hey", "1", "2" ,"3"]
user_input = None
# Transform your list into an iterator
categories = iter(categories)
# While the user doesn't want to quit
while user_input != "q":
# The user's input is transformed to lower case
user_input = input("What do you want to do ? ").lower()
if user_input == "n":
try:
# We print the next value on the iterator i.e. the next
# value in your list
print(next(categories))
except StopIteration:
# Raised when the iterator reached the end i.e. when we
# have printed all the values in the list
print("You've printed all the list!")
break
One possible output is:
What do you want to do ? hello # Nothing happens here
What do you want to do ? n
hey
What do you want to do ? n
1
What do you want to do ? n
2
What do you want to do ? n
3
What do you want to do ? n
You've printed all the list!
Note that this example is using Python3+
def add_item():
exit_list = ["F", "Finished"]
lists = []
start = input("Would you like to add an item to the list? Y/N")
print("Add Item to list")
categories = ["Produce", "Meat", "dairy","snacks/boxed goods", "Cans", "Misc"]
print(categories[0])
i=0
while start in ('y', 'Y'):
item = input(">>")
if item in exit_list:
break
elif item == "N":
i +=1
print(categories[i])
elif item:
lists.append(item)
else:
print("ok")
print(lists)
return lists
add_item()