Our lab assignment this week is to make a simple version of blackjack running in Python 3. I've got most of the assignment finished but I'm having trouble with the part where I need to determine points for each card. Here's a mockup of my code for the segment I'm stuck on.
def score(playerhand, comhand):
playerscore = 0
comscore = 0
for i in playerhand:
if playerhand == str('A'):
playerscore += int(11)
elif playerhand == str('J'):
playerscore += int(10)
elif playerhand == str('Q'):
playerscore += int(10)
elif playerhand == str('K'):
playerscore += int(10)
else:
playerscore += int(playerhand) #This is where it breaks
Playerhand is a list that will contain 2 or 3 random strings between 1-10, or A, J, Q, or K (These are aces and face cards). As it stands, I can't think of a simple way to convert the value of playerhand to an integer without making a bunch of elif statements to convert every string to its integer counterpart. I can't use playerhand[x] since the for loop is going to loop through every value in playerhand anyway. I've been at this for a while, if anyone can throw some help, I'd really appreciate it.
First of all, you are misusing playerhand inside the loop. Given the loop expression for i in playerhand, i represents a single element of the list. So inside the loop, you should be using i instead of playerhand to refer to the current element. playerhand still refers to the entire list.
With that change, the solution you have of calling int() may work fine. A better overall solution would be using a dictionary as already suggested in a comment, but given that this is a lab assignment, it may be intended for you to use only certain data structures.
Another solution would be to have a list that contains all the possible strings, and a second list of the same length that contains the corresponding scores. Find a given string in the first list, then find the element of the second list at the same position, and that is the score.
The problem within the given text of code I see straight away is using playerhand rather than i; for i represents each value of playerhand in sequential order from the beginning of the list.
Everything else seems as though it'd work fine, nevertheless using a dictionary may be a good way to go as well. Though since you're doing this as a lab assignment, that may be more than what your teacher is looking for.
Related
I am creating a bingo game where the user is guessing on five numbers and the computer takes out ten random numbers between 1-26.
The part I am having trouble with is that when the user have guessed, the numbers have been compared and added to the dictionary. If I then play the "game" once more it overwrites the last rounds points (which I want to keep).
def user_vs_cpu(cpu_random):
global players
for player in players:
correct_guess = 0
for guess in player["guess"]:
for bingo_number in cpu_random:
if guess == bingo_number:
correct_guess += 1
player["points"] = {correct_guess}
print(players)
players is a list that contains the dictionaries.
cpu_random is the computer's randomly generated numbers.
player["points"] is where the compared points is stored.
-edit-
I forgot to mention is that there is more dicts in the list players so that i can add more players to the game.
With player["points"] = {correct_guess} you're correct_guess variable turns into a set object due to the curly braces. You could then operate with this object according to PythonDocs Set Types. That's not what you want. Like suggested try to work with a list with append or use an integer if only the current points are important, this would be for example:
player["points"] += 1
See also 'PythonDocs Data Structures'
Suggestion: Try to get familiar with a good IDE like PyCharm, set a BreakPoint to player["points"] = {correct_guess} and see where you going wrong (you will be able to see the state of all variables/objects simultaneously.
I have the following code.
for idx in range(len(networks)):
net_ = networks[idx]
lastId=0
for layerUptID in range(len(net_[1])):
retNet,lastId=cn_.UpdateTwoConvLayers(deepcopy(net_),lastId)
networks.append(retNet)
if(lastId==-1):
break
networks has only one net at the beginning.
After running the line retNet,lastId=cn_.UpdateTwoConvLayers(deepcopy(net_),lastId), I have additional six nets and appended to networks.
So after this lastId ==-1, go back to first for loop with len(networks) is 7.
For the next idx, idx=1 and continue.
Then, len(networks) is 13. Then go back to first for loop.
After this, the first for loop breaks.
I am expecting to continue for idx is 2, but it breaks.
What could be the issue?
If you try using a WHILE loop instead of FOR loop, the break statement would be check if the loop is on the last item in 'networks' collection.
This way the network length would be calculated in each loop iteration
For starters: Iterating, or looping, over the list (or data) you're editing is bad practice. Keep that in mind while coding.
This means if you plan to edit what you're looping on, in your case networks, then you're going to have a bad time looping over it. I would advise to break it up into two code parts:
The first part creates a new list of whatever it is you want WHILE looping.
The second part replaces the list you've used to generate what you wanted.
Another thing which could go wrong is net_[i] may not be set up for some i, and you're trying to access it here:
for layerUptID in range(len(net_[1])):
What if there is nothing in net_[1]?
To avoid these errors, usually verifying your data is a great way to start. If it is not null, then proceed, otherwise, print an error.
This is what I can think of. Hope it helps.
If I understood correctly your problem is that you've added new elements to networks, i.e. have increased length of networks and expect that for-loop will pick up this changes, well it's not, let's look at following snippet
elements = [1]
indices = range(len(elements))
for index in indices:
print('index is', index)
elements.append(2)
print('elements count is', len(elements))
print('indices count is', len(indices))
outputs are
index is 0
elements count is 2
indices count is 1
so as we can see despite the fact that length of elements list has changed, range object which is used in for-loop has not. This happens because len returns int object which are immutable, so when you change list length its length becomes different object and range function has no idea about this changes.
Finally, we can use while loop here like
while networks:
net_ = networks.pop()
lastId = 0
for layerUptID in range(len(net_[1])):
retNet, lastId = cn_.UpdateTwoConvLayers(deepcopy(net_), lastId)
networks.append(retNet)
if lastId == -1:
break
I'm currently writing a function to play Connect Four in Python3. I've progressed well through much of it but am having trouble alternating between two players.
What I'm trying to do is run a function that will place a chip in the appropriate location as a function of the current player, playturn(curr). So what I'm trying to say is that while there's no tie and while there's no winner, the game will continue and alternate between the two players.
If it's Player 1's turn, curr=1, and if it's Player 2's turn, curr=2.
My current code isn't working, as it won't allow me to switch between players after each turn if there's no tie or no winner. My logic here was that if curr=1 is initially 1, then I'll have to set curr=2 after the first move. Then, when curr=2, I have to switch curr equal back to 1. In the following code, checkforwinner and checkfortie are two functions that will return False if there is no winner and if there is no tie. playturn(curr) will place a chip in the correct column depending on the column chosen by either Player1 or Player2.
curr=1
while checkforwinner==False and checkfortie==False:
if curr==1:
curr==2
print(playturn(curr))
if curr==2:
curr==1
print(playturn(curr))
Can someone explain why this code is not working and what can be done to fix it?
curr==2 is a comparison. You probably want curr=2. The second if should be an elif.
There are a couple ways to make this nicer!
To make your original code work, you should use jspcal's recommendation to turn the comparison operators (==) to assignment operators (=).
You also need to use an elif for the second comparison, or every single loop will switch the player twice.
curr=1
while not (checkforwinner() or checkfortie()):
if curr==1:
curr=2
print(playturn(curr))
elif curr==2:
curr=1
print(playturn(curr))
You can also clean up the code a little:
def switch_player(current_player):
if current_player == 1:
return 2
elif current_player == 2:
return 1
while not (checkforwinner() or checkfortie()):
print(playerturn(curr))
curr = switch_player(curr)
The last version you might go with is the shortest, but is a little harder to read:
while not (checkforwinner() or checkfortie()):
print(playerturn(curr))
curr = 1 if curr == 2 else 2
If checkforwinner and checkfortie are functions, you need parenthesis after them:
while checkforwinner()==False and checkfortie()==False:
Also, as #jspcal pointed out, you want to assign values with a single '=' and only use '==' for boolean comparison.
I'm trying to do a bingo game, I had some struggle with it but finally sorted it out.
However, my main "problem" (more like, I've heard its bad programming) is that with my function I'm calling my function inside it in an else statement. I don't think that it's how you suppose to do it, i have not found any way around it though.. Because this function is called from another function called menu() so when i use a loop, it goes back to the menu if false.
Here's my code:
def selectingNumbers():
numbers = []
dupl = []
j = 0
print("Now you are gonna select 5 number\n")
while j < 5:
nummer = int(input("Your choice:\n"))
numbers.append(int(nummer))
j = j+1
for i in numbers:
if i not in dupl:
dupl.append(i) #New list without duplicates
if dupl == numbers: #Comparing new list with old list
print("No equal numbers found")
dragning(numbers)
else:
print("Equal numbers found")
selectingNumbers() #Is there a better way to do it?
I also had some issues with the list at the beginning, I know I can use the set() function but i want to keep the original list as it is and compare the new one with the old one, can I do that in a better way with "real" programming instead of import modules?
Hope you can answer or guide me on these two questions with alternatives and if so, say why my code is "bad" if it is.
Well you have to decide if you want to use recursion to solve the problem. This line is a recursive call:
selectingNumbers() #Is there a better way to do it?
Which is fine, and does not equate to bad programming. However, the rest of your function does no cater to a recursive function. You reset your variables and have no true base case because of that. See google, or here for examples.
Recursion is confusing for beginners, so I would take an iterative only approach. Here is a bingo python example.
In addition, I'm not sure this line works:
if dupl == numbers: #Comparing new list with old list
I am not too familiar with python, but in my experience, arrays are treated as objects, so in that line you would be asking python to compare two seperate objects with unique references in memory. So they will never be equal, even if the values inside of them are the same because they are both referenced seperately. I found this link to answer that concern.
Recursion isn't "bad". In fact it can sometimes greatly simplify a solution to a problem. However in the case of your code it isn't necessary. Fortunately, it can sometimes be replaced with a loop. In the case of your code it looks like it could just loop until it gets a list from the user that doesn't contain any duplicates. That means it could be rewritten as shown below (I also simplified a few other things):
def selectingNumbers():
while True:
print("Now you are gonna select 5 different numbers\n")
numbers = []
for _ in range(5):
number = int(input("Your choice:\n"))
numbers.append(number)
unique = set(numbers) # will remove any duplicates
if len(unique) == len(numbers): # no dups?
print("No equal numbers found")
break # <--- terminates loop
else:
print("Equal numbers found")
# allow loop to continue
dragning(numbers)
I'm taking a course on programming (I'm a complete beginner) and the current assignment is to create a Python script that sorts a list of numbers in ascending order without using built-in functions like "sorted".
The script I started to come up with is probably laughably convoluted and inefficient, but I'd like to try to make it work eventually. In other words, I don't want to just copy someone else's script that's better.
Also, as far as I can tell, this script (if it ever functioned) would probably just put things in a NEW order that wouldn't necessarily be ascending. This is just a start, though, and hopefully I'll fix that later.
Anyway, I've run in to several problems with the current incarnation, and the latest is that it just runs forever without printing anything.
So here it is (with hashes explaining what I was trying to accomplish). If someone could look over it and tell me why the code does not match my explanations of what each block is supposed to do, that would be great!
# The numbers to be inputted, could be anything
numList = [1, 25, 5, 6, 17, 4]
# The final (hopefully sorted) list
numSort = []
# The index
i = 0
# Run the loop until you run out of numbers
while len(numList) != 0:
# If there's only one value left in numList,
# attach it to the end of numSort.
# (Variable 'basket' is just for transporting numbers)
if len(numList) == 1:
basket = numList.pop()
numSort.append(basket)
# The rest of the elifs are supposed to compare values
# that sit next to each other.
# If there's still a number in numList after 'i'
# and 'i' is smaller than that next number
# then pop 'i' and attach it to the end of numSort
elif numList[i+1] != numList[-1] and numList[i] < numList[i+1]:
basket = numList.pop(i)
numSort.append(basket)
# If there's NOT a number after 'i'
# then compare 'i' to the first number in the list instead.
elif numList[i+1] == numList[-1] and numList[i] < numList[0]:
basket = numList.pop(i)
numSort.append(basket)
# If 'i' IS the last number in the list
# and has nothing to compare itself to,
# Then start over and go through it again
# from the beginning
elif numList [i+1] == numList[-1]:
i = 0
# If 'i' is not at the end of numList yet
# and 'i' is NOT smaller than the next number
# and there are still numbers left
# then move on to the next pair
# and continue comparing and moving numbers
else:
i = i+1
# Hopefully these will be in ascending order eventually.
print(numSort)
Here is a simple way to sort your list with a classic loop :
myList = [2,99,0,56,8,1]
for i,value in enumerate(myList):
for j,innerValue in enumerate(myList):
if value < innerValue: #for order desc use '>'
myList[j],myList[i]=myList[i],myList[j]
print(myList)
The Algorithm behind this code is :
fix one value of the list and compare it with the rest
if it is smallest then switch the index of two values
I hope this will help you
Your conditions are essentially:
If there is only one number in the list
The current number is less than the next, which is not equal to the last number
The current number is less than the first number, and the next number is equal to the last number
The next number is equal to the last number
If you trace out the code by hand you will see how in many cases, none of these will evaluate to true and your "else" will be executed and i will be incremented. Under these conditions, certain numbers will never be removed from your original list (none of your elifs will catch them), i will increment until the next number is equal to the last number, i will be reset to zero, repeat. You are stuck in an infinite loop. You will need to update your if-statement in such a way that all numbers will eventually be caught by a block other than your final elif.
On a separate note, you are potentially comparing a number to only one number in the current list before appending it to the "sorted" list. You will likely need to compare the number you want to add to your "sorted" list and find its proper place in THAT list rather than merely appending.
You should also consider finding the end of list using a method more like
if i == len(numList) - 1
This will compare the index to the length of the list rather than comparing more values in the list which are not necessarily relevant to the order you are trying to create.