python assign a variable to a randomly selected string - python

my children and I are messing with a random bedtime story generator. And apart from being amazed at how easy python is to use, we want to generate a random name for our protagonist, but for them to keep the same name throughout the story.
import random
names= ["Tim", "Ju Ju", "Legface", "Dusty", "Smudger"]
thing = ["princess", "elf", "fairy", "mermaid", "shoe maker"]
count = 0
while (count < 1):
print "Once upon a time there was a ",
print(random.choice(thing)),
print "whose name was ",
print(random.choice(names)),
so if the random name turns out to be Tim, I would like to continue the story as
print $thevariablethatisTim
print "was a very happy man"
I realise this is a trivial thing, but I can't seem to get it right and we are having such a good laugh at bedtime with this.
Thanks in advance
Neil

Just choose the name of your hero before you enter the while loop.
hero = random.choice(names)
# stuff
while some_condition:
# do stuff
print(hero) # or formatted string
# do other stuff
any time you want to refer to your protagonist, use the variable hero instead of calling random.choice again.

Related

Add more values in a list at once in Python

I'm a beginner in Python and I'm trying to solve this problem.
I'm trying to write a code where you can put your name and the amount that you want to donate.
The thing is, deppending on the amount of the donation you can have more chances to be the winner.
Eg. If you donate $10 (1 chance), $20(2 chances), $30(3 chances).
My biggest problem is because I can't figure out how to solve this problem when the person insert $30 its name goes to the list 3 times and so on. I tried to use "for..inrange():" but without any sucess. Can someone explain me how to do this?
from random import shuffle
from random import choice
list = []
while True:
name = str(input('Write your name: '))
donation = float(input('Enter the amount you want to donate.: $ '))
list.append(name)
print('You donated $ {}. Thank you {} for you donation!'.format(donation, name))
print('=-'*25)
print('[1] YES')
print('[2] NO')
answer = int(input('Would you like to make another donation? '))
if answer == 1:
continue
else:
shuffle(list)
winner = choice(list)
break
print('The winner was: {}' .format(winner))
First do not use the name of a built-in type as a (meaningless) variable name. Change list to entry_list.
For the particular problem
compute the quantity of chances;
make a list of the person's name that many times;
extend the entry list with that list of repeated name.
Code:
entry_list = []
while ...
...
chances = int(donation) // 10
entry_list.extend( [name] * chances )
An alternative to adding another loop with additional control flow, you can use list.extend() with a list expression:
num_chances = donation // 10
chances = [name] * num_chances
all_chances.extend(chances)
Note that list is a built-in python identifier, and it's not a good idea to overwrite it. I've used all_chances instead.
Rather than adding extra names to the list to represent the higher chance, you could use the donations as weights in the random.choices function:
from random import choices
names, donations = [], []
while True:
names.append(input('Write your name: '))
donations.append(float(input('Enter the amount you want to donate.: $')))
print(f'You donated ${donations[-1]}. Thank you {names[-1]} for your donation!')
print('=-'*25)
print('[1] YES')
print('[2] NO')
if input('Would you like to make another donation? ') != '1':
break
winner = choices(names, donations)[0]
print(f'The winner was: {winner}')
This allows for non-integer donations to be counted fairly -- e.g. if Bob donates $0.25 and Fred donates $0.50, the drawing will still work in a reasonable way. It also allows very large donations to be handled without tanking the performance of the program -- if you have one list entry per dollar donated, what happens if Elon donates $20B and Jeff donates $30B? (The answer is that your fan spins really fast for a while and then the program crashes because you can't create a list with 50 billion elements -- but this is not a problem if you simply have a list of two elements with large int values.)
Note that shuffle is not necessary if you're using random.choices (or random.choice for that matter) because those functions will already make a random selection from the list.
You can use a for loop to append the name to the list more than one time :
for i in range(donation//10):
list.append(name)
This code should do the job. Please follow good naming conventions as pointed out by others. I have changed the list variable to donations as it is forbidden to use keywords as variables.
I have included the name in donations int(name) // 10 times using the extend function as pointed out by others. You may change the number of times as you wish.
from random import shuffle
from random import choice
donations = []
makeDonation = True
winner = "Unknown"
while makeDonation:
name = str(input('Write your name: '))
donation = float(input('Enter the amount you want to donate.: $ '))
donations.extend([name for i in range ( int(donation) // 10)])
print('You donated $ {}. Thank you {} for you donation!'.format(donation, name))
print('=-'*25)
print('[1] YES')
print('[2] NO')
answer = int(input('Would you like to make another donation? '))
if answer == 2:
makeDonation = False
shuffle(donations)
winner = choice(donations)
print('The winner was: {}' .format(winner))

local variable 'output_file' referenced before, this code worked a few weeks ago, now it doesnt work how is that possible?

This thing is hard to post code and context inside of.
#This is a menu driven multiplication game. i am attemtping to save the high
#score in a file named multiplication_game.txt...
def single_player():
in_file = open('multiplication_game.txt', 'r')
highest_times_selection = int(in_file.readline())
print('\n____now lets see how u do on the times tables____')
correct = 0
missed = 0
times_selection = int(input(
'\nPlease enter a times time table integer to practice: '))
#This simple generates the multiplation questions and checks for right or
#wrong.
for number in range(0,11):
print(times_selection, 'x' , number, '=')
user_answer=int(input('answer: '))
correct_answer = times_selection * number
if user_answer == correct_answer:
correct+=1
else:
missed+=1
#This is where if its a perfect score and a high times table than the
#previous saved score it should be opened and the new score saved in the
#text document.
if missed == 0 and times_selection > highest_times_selection :
output_file = open('multiplication_game.txt', 'w')
name = input('You have the highest Score!!\n enter your name: ')
output_file.write(str(times_selection)+ '\n')
output_file.write(name + '\n')
else:
print('you missed ', missed, 'and got', correct,'correct\n')
output_file.close()
Try to define output_file = None before any assignment of it.
Tip: before your last if-else condition.
This looks like homework, so I don't want to give you the answer but rather lead you to it.
Take a look at your if/else for your high score table, and walk through your code twice, taking a different branch (different part of the if/else) each time you reach this spot. Write down the variable names on paper as you define them, starting over with a new sheet of paper each time you walk through. If you access a variable, check it off on your list. If you try to access a variable that's not on your list, it's the same as python saying local variable referenced before assignment -- you're trying to access it before you've defined it.
Hope this helps, both in figuring out your problem and learning how to debug in the future.

Adding element to a dictionary in python?

I'm relatively new here, so please tell me if there is anything I should know or any mistakes I am making manner wise!
I am trying to add things onto a dictionary through random choice, but my code doesn't seem to work!
The file:
sports.txt
Soccer, Joshua
Lacrosse, Naome Lee
Soccer, Kat Valentine
Basketball, Huong
Tennis, Sunny
Basketball, Freddie Lacer
my code so far:
def sportFileOpen():
sportFile = open("sport.txt")
readfile = sportFile.readlines()
sportFile.close()
return(readfile)
def sportCreateDict(sportFile):
sportDict = {}
for lines in sportFile:
(sport, name) = lines.split(",")
if sport in sportDict:
sportDict[sport].append(name.strip())
else:
sportDict[sport] = [name.strip()]
return(sportDict)
def sportRandomPick(name, sport, sportDict):
if sport in sportDict:
ransport = random.choice(sportDict.keys())
sportDict[ransport].append(name)
print(name, "has been sorted into", ransport)
def main():
sportFile = sportFileOpen()
sportDict = sportCreateDict(sportFile)
name = input("Enter the name: ")
preferredSport = input("Which sport do they want? ")
sportRandomPick(name, preferredSport, sportDict)
main()
I am trying to allow a user to input their name and preferred group of sport, and whatever sport they prefer will have a higher chance of being randomly picked then the others (for example if Jason chooses soccer his chances of getting in soccer may double).
I don't expect anyone to write code for me, I know it's time consuming and you have better things to do! But can anyone maybe explain to me how I would go about doing this? I understand how to make random choices but I don't know how I would "double" the chances.
Also I keep getting this error when running my code: NameError: global name 'random' is not defined
I thought I was doing that part right but now i'm stuck. Can anyone give their two cents on this?
Try this:
def sportRandomPick(name, sport, sportDict):
if sport in sportDict:
ransport = random.choice(list(sportDict.keys()) + [sport]) # list of sports will contain preferred sport twice.
sportDict[ransport].append(name)
print(name, "has been sorted into", ransport)
This will increase chances of preferred sport to be picked by 2.
And don't forget to import random
I am assuming you are trying to use random.choice from python random.choice
you need to make sure it is imported at the top of your file:
import random
def sportRandomPick(name, sport, sportDict):
if sport in sportDict:
ransport = random.choice(sportDict.keys())
sportDict[ransport].append(name)
print(name, "has been sorted into", ransport)

How can I insert a random element into a dictionary and have it randomised whenever I call it?

I'm writing a Facebook bot which will eventually produce a couple of randomly-generated statuses a day. Right now, I'm at the stage where I've got the logic of selecting bits of phrases from dictionary entries and I've written it so it will just work in the Python shell for the time being - the Facebook authentication stuff will come later.
Right now though, I thought it'd be cool to randomise certain nouns within the phrases contained in the dictionaries, and I was doing this with random.choice() and running a function that should return a new random element every time I generate a status. But the problem is that whenever I call the phrase, I can see that it's generated one random noun, but that noun gets 'fixed' for some reason such that the same random noun is reproduced every time. When I run the function as part of building a status, it seems to be working fine, but for some reason I can't figure, any new random nouns are not passed to the dictionary. Naturally, it works when I restart the program, but if I'm aiming to do this as a bot, I'd ideally like to not have to restart the program every time I want a new status.
I've done some investigating and I think the problem is not to do with my actual random.choice() stuff or the functions that they're in, but that the dictionary gets 'fixed' before my random noun function can touch it (e.g. the random choice function produces a random selection from the fruit list, but the dictionary will only ever have the same fruit selected when I run the StatusBuilder function). I have tried out some potential solutions with global variables and so on, but nothing has worked. The excerpt demonstrated in the code below is, I think, the closest I've come.
from random import randint
from random import choice
from textwrap import fill
def RandomFruit():
return choice(["mango", "pomelo", "guava", "grapefruit", "watermelon"])
class DoTable():
def __init__(self, text):
self.text = text
DoDict = {
"do0": DoTable("sitting on the roof, completely naked, throwing Herb Alpert records at a dog like they were frisbees"),
"do1": DoTable("eating a " + RandomFruit() + " like it's a handfruit"),
"do2": DoTable("lurching around a supermarket"),
}
class BeTable():
def __init__(self, start_text, end_text):
self.start_text = start_text
self.end_text = end_text
BeDict = {
"be0": BeTable("I guess ", " is what my life has come to."),
"be1": BeTable("", ", just waiting for the police to arrive."),
"be2": BeTable("If ", " is wrong, then I don't ever want to be right!"),
}
def StatusBuilder():
#DoDict and BeDict will always have one entry selected from each, though
#BeDict will always have two attributes selected as part of the one entry.
DoRNG = randint(0,len(DoDict)-1)
BeRNG = randint(0,len(BeDict)-1)
#Logic to display concatenated strings
status = BeDict["be" + str(BeRNG)].start_text + DoDict["do" + str(DoRNG)].text + BeDict["be" + str(BeRNG)].end_text
#print the status with textwrapping and with the first letter always capitalised.
print fill((status[0].capitalize() + status[1:]), 80)
print
Controls()
def Controls():
command = raw_input("([RETURN] FOR ANOTHER ROUND OF BULLSHIT, [Q] TO QUIT): ")
if command.lower() == "q":
quit()
elif command.lower() == "":
print
RandomFruit()
StatusBuilder()
else:
print
print fill("Some kind of wise guy are you? Try again, this time with a PROPER command please.", 80)
print
Controls()
#Start the program
print "PHILBOT V1.0"
print "A social media status generator."
print
command = raw_input("(PRESS [RETURN] TO GET STARTED): ")
print
RandomFruit()
StatusBuilder()
The sample dictionaries are included in the code above (which is a massively pared down version of the program which will run if you want to play with it). So the output I'm having trouble with would be the element in DoDict with the key "do1". So for example, say the StatusBuilder function picks the same phrases ("do1" and "be2") consecutively, what I want it to do is produce a different fruit every time when called with the StatusBuilder function, like this:
"If eating a mango like it's a handfruit is wrong, then I don't ever want to be right!"
"If eating a grapefruit like it's a handfruit is wrong, then I don't ever want to be right!"
Currently, whichever fruit is selected first 'sticks' permanently whenever I run it through StatusBuilder(), even though the RandomFruit() function seems to be working normally.
EDIT: I've now tried a few suggested alternatives (using lambdas and using generators) and have tried working with a simpler data format (lists without classes), but the problem is still being reproduced. SO, I'm starting to think it's more to do with my order of operations, as in the dictionary entry gets 'written' after the RandomFruit function is initially run (yay!), but it doesn't get 're-written' when I run it again (boo!)...this gives me a problem, since I can either declare the function then the dictionary (where the function doesn't seem to be speaking to the dictionary after it is first used), or declare the dictionary then the function (which doesn't work since the dictionary is then trying to rely on an as-yet-undeclared function). So, I think this is the root of the problem - any help?
You could use the random.choice function as a value in your dictionary (I've simplified your example quite a bit):
import random
fruits = ["mango", "pomelo", "guava", "grapefruit", "watermelon"]
DoDict = {'do1': random.choice}
This way you get a random fruit every time you access the dictionary:
>>> for i in range(10): print DoDict['do1'](fruits)
guava
pomelo
watermelon
mango
watermelon
grapefruit
pomelo
watermelon
watermelon
watermelon
You could also use a generator:
def random_fruit():
while True:
yield random.choice(["mango", "pomelo", "guava", "grapefruit", "watermelon"])
DoDict = {'do1': random_fruit().next}
In this case you don't need to pass the list of fruits as a parameter:
>>> for i in range(10): print DoDict['do1']()
grapefruit
pomelo
pomelo
guava
grapefruit
pomelo
pomelo
pomelo
mango
guava

Pokemon Battle in Python [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I am not that great with OOP but I am stuck right now. First off, I don't think I set the damage correctly and I am trying to figure out how to output the damage to the user. Any help would be appreciated.
#Pokemon Battle
import random
from time import sleep
from array import *
class Pokemon(object):
def __init__(self, xname, xhealth):
self.name = xname
self.health = xhealth
def damage1(self,Charmander):
Squirtle.health - self.damage
def damage2(self,Charmander):
self.health - Squirtle.damage
print ('What is your name?')
name = input()
print ('Hello '+name+'! You are about to enter a pokemon battle.')
sleep(1)
print ('A wild Charmander appeared!')
sleep(1)
print ('You sent out Squirtle!')
sleep(1)
print ('Do you want to fight(1) or run away(2)?')
choice = input()
damage = random.randint(1,50)
damage = str(damage)
if choice == '1':
print ('You dealt '
sleep(1)
print ('Charmander did ')
if choice == '2':
print ('You ran away.')
else:
print ('Not a valid response.')
Right off the bat, you can use String Formatting to insert variables in strings.
#old way
some_string = "the value of 2+2 = %i",4
#new way
some_string = "the value of 2+2 = {}".format(4)
For your code, try:
if choice == '1':
print("You dealt {}".format(damage_goes_here))
However there's deeper issues with your code. Let me look more and I'll edit.
Object Oriented Programming
Okay so the first problem you have is that you never actually MAKE anything. When you write class SomeClassLikePokemonOrWhatever: what you're doing is making a template of something. It's like making a cast or a mold of an item before you make it -- you want all your Pokemon (or whatever) to be alike, so you make a mold of them and cast them all from the same mold. You can decorate and unique-ify them after that, but we want them all to be the same, basically. So instead, you should have something like this:
class Pokemon:
def __init__(self,name,base_hp):
self.name = name
self.base_hp = base_hp
#the __init__ function gets called when you "instantiate" (e.g. actually MAKE)
#whatever object the class is describing. In most cases, all it does it set
#the starting properties of the object based on how you define it (like this)
#you could also say all pokemon are beautiful, and add something like
self.description = "Absolutely GORGEOUS darling!"
#that will be constant for every pokemon you make through this definition.
#you said you wanted damage to be random between 1-50, so we don't need to add
#that statistic to the class.
That covers the definition of the object, but it still doesn't DO anything. In fact, let's let it do something, shall we? We want it to attack. What's a pokemon that doesn't fight? So let's give it a function (in a class, we call functions "methods.")
def attack(self,target):
#in this method we'll teach the pokemon how to fight
damage = random.randint(1,50) #don't forget to import random to do this
target.hp -= damage
Now you need to make some stuff. You defined what a Pokemon is and what it can do, but you haven't made one. Let's make some. Luckily it's easy.
my_awesome_pokemon = Pokemon("Charizard",200) #you give the args in the same order __init__ takes them
your_sucky_pokemon = Pokemon("Magikarp",20) #same deal here.
That makes two pokemon, one for you and one for them. If you wanted a whole belt full, you could define an array all_my_pokemon and fill it with Pokemon objects defined in this way. Just something to think about.
To actually fight, you'd tell your pokemon to attack.
my_awesome_pokemon.attack(your_sucky_pokemon)
#just that easy, now display how much damage it did....WAIT STOP WE HAVE A PROBLEM!
since you want random damage every time, you can't access it with something like my_awesome_pokemon.damage, since it's a local variable it dies when the attack method ends. You can, however, return that value in the method and use that.... Let's change our method.
def attack(self,target):
damage = random.randint(1,50)
target.hp -= damage
return damage #now we have some way to access how much damage was done from our main thread
Now to display it, we can do
damage_done = my_awesome_pokemon.attack(your_sucky_pokemon) #since .attack() returns the damage it deals, this sets damage_done to a sane amount.
print("My pokemon {} dealt {} damage to {}".format(my_awesome_pokemon.name,damage_done,your_sucky_pokemon.name))
Does that make sense?
I really think you should brush up on your OOP and then come back to this problem, because this is definitely a decent problem to practice on.
First of all, you set damage, and then set it again randomly:
self.damage = xdamage
self.damage = random.randint(1,50)
And this function is left open, which is going to cause compile issues, besides for the fact that you're missing any actual data!
print ('You dealt '
sleep(1)
print ('Charmander did ')
You're going to want to call your damage variable and Charmander's damage variable; think about how that is accomplished in OOP.

Categories