Python tkinter for loop not displaying correcty - python

Making a blackjack game and this for loop is not printing the correct cards. It prints the first card and second card fine, but when it gets to the third card it reprints the first card instead in the third one's place. I have tried both deleting and not deleting the images before print but it doesn't work out.
if len(playerCards) > 0:
for i in range(len(playerCards)):
#print(currentHand[i])
#print currentHand
#print(i)
#print(playerCards[i])
GAME_CANVAS._tkcanvas.delete("pCard" + str(i))
GAME_CANVAS._tkcanvas.create_image(125+((i-1)*80), 75, image = playerCards[i].image, tag = "pCard" + str(i))
I have the current print statements commented because they should not affect the code in any way.

Related

Python random.randint stops randomizing after a few loops

I'm running a python script that will display messages on a board. One of the subroutines that I've created is supposed to grab a random line from a small text file, and display that line. It mostly works, except after looping a few times, it gets stuck on the same number, and just displays the same thing over and over.
I am running this in Python 2.7, on a Raspberry Pi in Raspbian. I am using this github as the base for the project, and added lines of my own to it:
https://github.com/CalebKussmaul/Stranger-Things-Integrated
This is part of a halloween display that will be Stranger Things-themed, so the preloaded messages have a reference to the show. I noticed this issue the other day, and have been pouring over the internet to try and figure out what the problem could be. I've tried doing different methods of selecting a randomized number, including some in some similar (but different) threads on this site. All of them produce exactly the same issue.
Below is the subroutine I created:
def preloaded_messages():
print "Preloaded Messages thread is loaded."
global displaying
while True:
if not displaying:
with open('preloaded_messages.txt') as f:
lines = len(f.readlines())
rgn = random.randint(1,lines)
msg = linecache.getline('preloaded_messages.txt', rgn)
print "rng: ", rgn
print "total lines: ", lines
print "line: ", msg
print "displaying from preloaded_messages.txt: ", msg
display(msg)
time.sleep(10)
And here's my preloaded_messages.txt file:
help me
im trapped in the upside down
leggo my eggo
friends dont lie
run /!
hopper is alive
rip barb
demogorgon is coming /!
mouthbreather
When I run it, my output is like this:
rng: 6
total lines: 9
line: hopper is alive
rng: 2
total lines: 9
line: im trapped in the upside down
rng: 9
total lines: 9
line: mouthbreather
...
rng: 9
total lines: 9
line: mouthbreather
the first few times are always random (and the number of times it successfully randomizes varies), but when it gets on 9, it just stays there for as long as I let it run. I am at a loss as to why it works the first few times, but not once it gets to 9.
EDIT: Interestingly, as I've been writing this, I also tried adding a blank line at the end, and while it looked like it'd be stuck again, as it did that one three times in a row, then it finally moved to others. I'm not sure how that changes things. And ideally, I'd rather not have the blank line in there, as it eats up time displaying nothing. So it'd be nice to fix the issue. Anyone have any ideas?
It is reseeding the random generator. See line 49 of stranger.py in the https://github.com/CalebKussmaul/Stranger-Things-Integrated: random.seed(i).
The color_of function should be written as:
def color_of(i):
"""
This function generates a color based on the index of an LED. This will always return the same color for a given
index. This allows the lights to function more like normal christmas lights where the color of one bulb wont change.
:param i: index of LED to get color of
:return: a pseudorandom color based on the index of the light
"""
_random = random.Random(i)
rgb = colorsys.hsv_to_rgb(_random.random(), 1, 1)
return int(rgb[0] * 255), int(rgb[1] * 255), int(rgb[2] * 255)
To create its own Random instance with the given seed rather than reseeding the Random instance that is a singleton in the random module.
This appears to work for me. Note that I'm seeding the RNG.
import time
import random
from datetime import datetime
def preloaded_messages():
print("Preloaded Messages thread is loaded.")
displaying = False
while True:
if not displaying:
with open('preloaded_messages.txt') as f:
random.seed(datetime.utcnow())
text = f.read().splitlines()
msg = random.choice(text)
print("line: ", msg)
# print("displaying from preloaded_messages.txt: ", msg)
time.sleep(10)
if __name__ == "__main__":
preloaded_messages()

Python list doesn't seem to be updating

I'm fairly new to python and I'm trying to create blackjack. However, when I'm trying to print out what the player's hand is, I run into a few difficulties.
This is my code for hitting (drawing a card):
def hit(card, deck):
global money, choice
choice = input("How much would you like to bet?\n")
money -= int(choice)
print("You have decided to bet $" + str(choice))
card = card.drawCard(deck.deck)
card.getPt()
deck.addScore(card)
deck.addCard(card)
c = str(card)
p = str(deck)
print("You have drawn: " + str(c) + "\n")
print("The player has:\n" + str(p) + "\n")
print("Total score:", deck.score)
And this is my code for printing my cards out:
def __str__(self):
for i in range(0, len(self.deck)):
self.print = self.print + "\n" + str(self.deck[i])
return self.print
The first thing my code does is draw two cards for the dealer and the player, which runs fine. However, after the player draws a card is where it gets a bit wonky. The output is something like this:
The player has drawn Card A
The player has drawn Card B
Total score: number
How much would you like to bet?
number
You have bet number
You have drawn Card B
Player has:
Card A
Card B
Card A
Card B
Card B
When I draw a new card, the card doesn't change, it stays the last card I drew. Then, when I print my deck, it prints my old deck and my new deck. However, the score is correct, which indicates that my list is only three cards long. What is going on, and why is it printing five cards?
Full code
Example output
Well, to get to the answer in short: you never reset Deck.print. So it keeps accumulating at each call to __str__
But in general this code could be improved significantly
E.g. your __str__ function is far from being pythonic. Something along the lines of
return '\n'.join(self.deck)
would look much better.
In general there is no need to prepend each variable with "self." if they are used within the function only. In most cases in a class method you either update an object variable (self.something) or return some value from the function, but not both.
There may, of course, be exceptions to this, but it seems in your case this is the rule and not the exception.
Using globals is also something you should avoid whenever possible.

Modifying a dictionary inside of an if statement

I've been trying to make a basic text game in Python, and I'm using dictionaries to contain the player's information. I want to make it so that when a player's health reaches 0, the code will stop running. I've had trouble making that happen. My dictionary, which is at the beginning of my code, looks like this:
playerAtt = {}
playerAtt["Weapon"] = "Baseball bat"
playerAtt["Party"] = "Empty"
playerAtt["Health"] = 15
playerAtt["Cash"] = "$100"
print(playerAtt)
if playerAtt['Health'] <= 0:
exit()
The bottom section is what I wrote to try and make the code stop running when the player's health reached zero, but it doesn't seem to work. In one path of my game, your health gets set to zero and the game is supposed to end, but the program continues to run:
townChoice = raw_input("You met a traveler in the town. 'Yo. I'm Bob. Let's be friends.' Will you invite him to your party? Y/N\n")
if townChoice == 'y' or townChoice == 'Y':
print("That kind traveler was not such a kind traveler. He stabbed you with a machete. RIP " + Name + '.')
playerAtt['Health'] == 0
When you reach this part of the game, all it does is print the message, and moves on to the next decision. In this situation, I could just manually end the program by doing exit() under the print command, but there are circumstances where the player only loses a fraction of their health, and they would eventually reach zero. Sorry if this is a stupid question, I've only been working on Python for a few days.
You have two "=" when you set the player's health to 0
I had put 2 == instead of 1 = when defining
playerAtt["Health"].
Also, I needed to make sure it was constantly checking if the player's health was zero, so I used a while loop. I used
while playerAtt["Health"] = 0:
deathmsg()
exit()
to fix it. deathMsg was a function I made to display a random death message, for more information.

Attempting to Undraw in my GUI Python Game

I'm creating a Memory Matching game for a final project for my compsci class.
As of now, I have the cards all appear on the GUI window once you hit start game.
Once start game is hit, all the cards with their face value shows with the back of the card immediately. (So you never actually see the card fronts)
My reasoning for doing this is so that when you click on a card, I'll simply undraw the back card image instead of "Flipping" anything.
However, I keep getting errors, and when I don't get errors, it simply results in my program saying "Not Responding" and makes me have to restart the Shell.
Here are some little bits and pieces of my code which I think pertain to my issue:
for firstcard in range(6):
firstrow = self.deck.dealCard()
randomsuite = firstrow.getSuite()
randomrank = firstrow.getRank()
#Real image with face value of card
realCard = Image(Point(xpos,ypos),"playingcards/"+ (randomsuite) + str(randomrank) +".gif")
realCard.draw(win)
#Red Back of card to cover image
firstcard = Image(Point(xpos,ypos),"playingcards/b1fv.gif")
firstcard.draw(win)
#pushes the card to the right a bit
xpos += 100
while not Quitbutton.isClicked(p):
#Start Game
if StartGameButton.isClicked(p) and player == True:
if first == True:
Game.gameboard(win,150,125)
firstcard = Image(Point(xpos,ypos),"playingcards/b1fv.gif")
first = False
if StartGameButton.isClicked(p):
p = win.getMouse()
if firstcard.isClicked(p):
firstcard.undraw()
p = win.getMouse()
As of now you can see I have in my code if firstcard.isClicked(p):. However, this doesn't actually work because my isClicked function is a part of a Button Class and therefore, only works when dealing with Buttons and not images. So I'm not entirely sure what to do to select a single card and how to show that that card has been clicked and therefore should be undrawn

How do you make python read a random value it printed and insert it into an array?

I have written a small coin flipping program for Home work Python, it will choose one of two values; Heads or Tails at random and print them, the loop iterates 10 times then stops. As I understand it the only way to count the number of repetitions of some words is to place the words in an array or a split variable string and then run a pre-written cnt. Click Here to see that discussion.
I need to know how you get Python to take the random value it produced and then save it into an array according to the number of iterations of the for loop(in this case x number of iterations).
Here is the variable name and the two options:
coin = ["Heads", "Tails"]
Here is the code for the coin flipper core:
#Flipping core :)
def flipit(random, flip, time, comment, repeat):
time.sleep(1)
print("It begins...")
print("\n")
for x in range(0, 10):
print("Flip number", x + 1)
print(random.choice(comment))
time.sleep(1)
print(random.choice(coin),"\n")
time.sleep(2)
print("\n")
from collections import Counter
counting = []
cnt = Counter(counting)
cnt
print("Type startup(time) to begin flipping coins again")
If you do feel like refining the code please do if you have the time, but all I need is a method that I can put into the overall program that will make it run properly.
Please don't worry about the random comment, that was for a bit of fun.
I have pasted the whole program on PasteBin, Click Here for that.
Thank you for reading this and my gratitude to those who respond or even fix it.
Edit:
Just for reference I am a bit of a newbie to Python, I know some things but not even half of what the people who answer this will know.
Solution:
I have managed to make Python "read" the random value using a per-iteration if statement in my for loop, using if statements I have added 1 to the respective variable according to the random.choice.
Here is the flip core code:
def flipit(random, time, comment, headcount, tailcount, side):
time.sleep(1)
print("It begins...")
print("\n")
for x in range(0, 10):
print("Flip number", x + 1)
side = random.choice(coin) # get the random choice
print(random.choice(comment))
time.sleep(1)
print(side) # print it
if side == "Heads":
headcount += 1
else:
tailcount += 1
time.sleep(2)
print("\n")
print("You got", headcount, "heads and", tailcount, "tails!")
print("Type start() to begin flipping coins again")
resetheadtail()
resetheadtail() is the new function I have added to reset the variables at the end of the program running.
For the full code click Here!
Thanks all who helped, and those who persevered with my newbieness :)
#comment necessary for edit, please ignore
I think what you want to do is:
flip = random.choice(coin) # get the random choice
print(flip) # print it
counting.append(flip) # add it to the list to keep track
Note that you will need to move counting = [] to before your for loop.

Categories

Resources