I have made this short questionnaire:
from random import randint
def pancakes():
q = raw_input("Do you like pancakes?")
if q == "yes":
print("Great!")
elif q == "no":
print("Hmmm...")
def french_toast():
q = raw_input("Do you like french toast?")
if q == "yes":
print("Oh!")
elif q == "no":
print("Same here!")
def random():
num = 2
while num > 0:
random = randint(1, 2)
if random == 1:
num = num -1
pancakes()
elif random == 2:
num = num -1
french_toast()
random()
My goal here was to get the questions in a random order. But sometimes the same question will be asked twice since it's randomly chosen.
So how can I make it ask the same question only once?
Instead of a while loop, I'd suggest you use a for loop in conjunction with random.sample. Create a list of functions before-hand to provide to sample:
from random import sample
funcs = [french_toast, pancakes]
for func in sample(funcs, len(funcs)):
func()
this will now loop through all functions randomly selecting a function in each iteration.
Alternatively, you could shuffle the list (performs in-place) with random.shuffle and then iterate through it, that will be faster too (though, speed shouldn't be the biggest concern here):
from random import shuffle
funcs = [french_toast, pancakes]
shuffle(funcs)
for func in funcs:
func()
Put these in a function if so required:
from random import shuffle
# use *funcs for passing arbitrary number of
# functions as positional arguments.
def call_funcs_randomly(funcs):
shuffle(funcs)
for func in funcs:
func()
and call them:
call_funcs_randomly([french_toast, pancakes])
As a comment noted, don't use random as a function name, it has the possibility of masking the module random leading to odd looking errors.
I would use random.sample Link. Just create a list of indices to your questions and sample 2 of them.
EDIT:
additionally, you could use random.shuffle Link:
random.shuffle(questions)
for question in questions:
# process your random question once
how about this for your last question (random is not a good name! you might overwrite the module of the same name [although you are fine the way do do it right now])
def random_questions():
eligible_questions = [pancakes, french_toast]
while eligible_questions:
question = random.choice(eligible_questions)
eligible_questions.remove(question)
question()
put the questions in a list, select one with random.choice, remove it from the list and execute it. stop if the question list is empty. this way every question is selected exactly once.
this is easily extended if you want to add more questions.
on second thought: the shuffle version in Jim Fasarakis-Hilliard's answer is a lot cleaner!
Related
I'm trying to write a function which takes my input as amount of dicerolls, gets a random number between 1,6 for that amount of dicerolls, and then appends these to a list.
I've tried different return messages, but I can't seem to to make it append to a list, and can't really think of what else I can do with my code.
terninger = []
def terning_kast(antal_kast = int(input("Hvor mange terningekast? "))):
for x in range(antal_kast, 0, -1):
resultat = random.randint(1, 6)
terninger.append(resultat)
return resultat
print(terninger)
I'm expecting the code to append the random number 1,6 into my list above (terninger), but I'm only receiving an empty list.
you forgot to call your function => terning_kast()
terninger = []
def terning_kast(antal_kast = int(input("Hvor mange terningekast? "))):
for x in range(antal_kast, 0, -1):
resultat = random.randint(1, 6)
terninger.append(resultat)
return resultat
print('before', terninger)
terning_kast() # this is the line which you have missed
print('after', terninger)
There are few points that you need to correct in your logic. Meantime, following is probably that you want.
import random as rnd
def terning_kast(count):
terninger = []
for x in range(count, 0, -1):
resultat = rnd.randint(1, 6)
terninger.append(resultat)
return terninger
if __name__ == "__main__":
cnt = input("Hvor mange terningekast? ")
if cnt.isdigit():
print(terning_kast(int(cnt)))
else:
print("Invalid entry")
In order to use the random module, first you need to import it into your module.
Though you are appending the generated random number to list, you never attempt to return that list. What you are returning is the last instance of result from the randint(x,y) function call.
You are defining your function as part of your module/script. In order to execute that function, you must either call it within module or import it to some other module. If you look at my example the if __name__ == "__main__": instruct the python interpreter to run your script if you were to execute from same module. If you were to consume this module (importing) from some other then you don't need to mentioned this if __name__ == "__main__":
I'm trying to demonstrate how yield in Python is used. I want to demonstrate that through an example.
The example will ask the user to enter yes or no, and increase the counter n by 1 every time yes is entered.
The part I want to show how yield works is when the user calls the function again, and getting an updated value of the number of times. For instance, if return was used, and the user runs the script again, it will start from scratch and the number of times would be 1. Rather, I want the user to get 1,2,3,...etc, that is the number of times yes was entered.
The issue here is how to use yield to demonstrate such example. In the code I wrote below, I always get a generator object returned rather than the value of n. How can I get the integer value n returned instead?
def yes_times(answer):
n = 0
if answer == 'yes':
n = n + 1
yield n
answer = raw_input('"yes" or "no": ')
times = yes_times(answer)
print 'You answered yes ' + str(times) + ' times'
Thanks.
I'm trying to demonstrate how yield in Python is used.
... example problem ...
The issue here is how to use yield to demonstrate such example.
You're doing this backwards.
Don't demonstrate how yield is used by picking some arbitrary example, which is unrelated to generator behaviour, and try implementing it using yield.
Instead, choose something that yield is good at, and implement that - ideally with a comparable non-yield implementation so you can show the benefits.
Simple example: toy implementation of range
def naive_range(begin, end):
i = begin
result = []
while i < end:
result.append(i)
i = i + 1
return result
def generate_range(begin, end):
i = begin
while i < end:
yield i
i = i + 1
Now, can you name the drawbacks of the naive implementation? When will it be significantly worse than the generator, and why?
For your example, you can try:
def yes_times(answer = None):
count = 0
while True:
if answer=="yes":
count += 1
answer = yield count
else:
answer = yield count
gen = yes_times()
gen.next()
while True:
answer = raw_input('"yes" or "no": ')
print 'You answered yes ' + str(gen.send(answer)) + ' times'
The problem is that you're trying to use the generator as if it were a function. I strongly recommend that you go through a tutorial on line until you grasp the difference -- after all, that's how I quit making exactly this mistake. :-)
Your statement
times = yes_times(answer)
instantiates the generator, which is what you get when you print. Instead, you need to either use the next function ...
times = next(yes_times(answer))
... or properly employ a generator that does what you need. The general use of a generator is to recognize it as a stream of data, something like
for times in yes_times(answer):
However, this requires that you update your generator to get the input itself.
Is that enough to get you moving?
I'm pretty much a complete beginner to python, and i'm having problems removing an integer from a list. I'm getting a error, AttributeError: 'int' object has no attribute 'remove', and i don't know how to fix it. This is probably really easy to experienced eyes, and I have looked at past answers but keep returning same error
repeat = 0
while repeat <= 4:
question_list = [1,2,3,4,5]
number = random.choice(question_list)
if number == 1:
print(question1())
repeat = repeat + 1
number.remove(1)
elif number == 2:
print(question2())
repeat = repeat + 1
number.remove(2)
elif number == 3:
print(question3())
repeat = repeat + 1
number.remove(3)
elif number == 4:
print(question4())
repeat = repeat + 1
number.remove(4)
elif number == 5:
print(question5())
repeat = repeat + 1
number.remove(5)
number = random.choice(question_list) assigns number to an int returned from calling random.choice on your question list. If you want to remove from question_list call remove on the list not number:
question_list.remove(x)
You need to assign question_list outside the while loop, if you put it inside you keep creating a new list so the remove never persists.
question_list = [1,2,3,4,5] # here
while repeat <= 4:
A nicer implementation may be to use a dict and just use range:
import random
# map numbers to functions
questions = {1:question1,2:question2,3:question3,4:question4,5: question5}
question_list = [1, 2, 3, 4, 5] # outside loop
for _ in range(4): # loop in range 4
number = random.choice(question_list)
question_list[func]() # call function using dict key val
question_list.remove(number)
Or simply store the functions in a list and randomly choose one:
question_list = [question1,question2,question3,question4,question5]
for _ in range(4):
func = random.choice(question_list)
func()
question_list.remove(func)
Since a comment already explained why your code doesn't work, I'd like to suggest a simpler alternative.
It seems like you have a few functions you want to call in a random order.
There is no need to complicate things the way you're doing it, and mess around with removing elements from the list.
You can simply have a list of functions, shuffle it, and call every function in order:
questions = [question1, question2, question3, question4, question5]
random.shuffle(questions)
for question in questions:
question()
You should use the remove function on the list, and give the int as a parameter. So it should become:
question_list.remove(something)
But be careful, because if there is no "something" you will get an error.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have to write a Python script that will allow the user to enter a set of positive numbers and then count how many are
equal to 50
greater than 50
less than 50
Use appropriate output to prove that your program is working.
Just for example's sake, let's write a function that counts how many numbers are above 50, then one for equal to 50, then one for less than 50. Disclaimer: this is not the only, or even the BEST way to accomplish what you want to do, this is just the best teaching aid :). Also, some of the nomenclature may change if you're not using Python 3.x.
#this function returns how many values in the list that's passed to it
#are greater than 50
def greaterThanFifty(list_to_compare):
how_many_above_fifty = 0
for value in list_to_compare:
if value > 50:
how_many_above_fifty += 1
return how_many_above_fifty
#this function returns how many values in the list that's passed to it
#are less than 50
def lessThanFifty(list_to_compare):
how_many_under_fifty = 0
for value in list_to_compare:
if value < 50:
how_many_under_fifty += 1
return how_many_under_fifty
#this function returns how many values in the list that's passed to it
#are equal to 50
def equalToFifty(list_to_compare):
how_many_are_fifty = 0
for value in list_to_compare:
if value == 50:
how_many_are_fifty += 1
return how_many_are_fifty
Now we have our functions that will return the values we need. Again, this is not the only or even the best way to do this, but it's the way I'm using because it teaches a lot of basic strategies like writing modular programs (each function is performed by its own bit of code) and using functions rather than straight code to perform your task. Unfortunately, on their own, this code doesn't do anything. It just defines functions that we'll leverage to solve the problem at hand. In essence -- we've made our hammer, nails, and saw, but now we have to cut the lumber to size and nail it up. Let's do that.
def main(): #this is always the name of our function that does the heavy lifting
list_of_numbers = []
user_input = input("List some numbers, comma separated please: ")
for num in user_input.split(","):
#loop through user_input, split by commas
list_of_numbers.append(num.strip())
#add to list_of_numbers each item that we find in user_input,
#stripped of leading and trailing whitespace
#at this point we've looped through all of user_input and added each number
#to list_of_numbers, so we can use our functions, defined earlier, to return
#the requested values. Luckily we set up our functions to accept
#lists!
greater_than_fifty = greaterThanFifty(list_of_numbers)
less_than_fifty = lessThanFifty(list_of_numbers)
equal_to_fifty = equalToFifty(list_of_numbers)
#now just to display the results to the user, and we're done.
print("There are "+str(greater_than_fifty)+" numbers over fifty")
print("There are "+str(less_than_fifty)"+ numbers under fifty")
print("There are "+str(equal_to_fifty)"+ numbers that are fifty")
We still haven't actually DONE anything, though, since all we've done is define functions that do what we want from start to finish. our greaterThanFifty function is our hammer, our lessThanFifty function is our saw, and our equalToFifty function is our nails. Now we've added a main function, which is our handyman. Now we need to tell him to work. Luckily that's easy :)
main()
That's it! We're done!
For comparison purposes, this is how I'd write all that:
input_list = [int(each.strip()) for each in input("Enter a list of numbers, comma-separated: ").split(",")]
print("{} are less than 50, {} are more than 50, {} are 50".format(len([each for each in input_list if each<50]),len([each for each in input_list if each>50]),len([each for each in input_list if each==50])))
You'll get there, young padawan :)
def main():
inp = input('enter number of positive numbers to enter ')
print 'enter the list of positive numbers'
num = []
count_eq = 0
count_gr = 0
count_ls = 0
for elem in range(inp):
num.append(input(''))
for item in num:
if item == 50:
count_eq += 1
if item > 50:
count_gr += 1
if item < 50:
count_ls += 1
print '%d are equal %d are less than and %d are greater than 50' % (count_eq, count_ls, count_gr)
main()
This is a very basic program ! You should start python's beginner tutorial here
Is there a quick and easy way that is not computationally expensive to overwrite an element in a list corresponding to an element in another list (of the same length)?
iterates = input("How many iterates: ")
trials = input("How many trials: ")
aggregateList = [iterates]
def function():
recordList = []
for i in range(iterates):
# math goes here
recordList.append()
aggregateList[i] += recordList[i]
for i in range(trials):
function()
The problem is coming from aggregateList[i] += recordList[i]Any ideas on something else that will work? Say the value in recordList[i] is 5 for the first "iteration", 5 for the second, 5 for the third, at this time aggregateList[i] should be 15.
I think you are looking for either:
aggregateList += recordList
or
aggregateList.append(recordList)
depending on whether you want your aggregate to be flat or nested.
And change aggregateList = [iterates] to aggregateList = [].
This is how I personally would implement it:
iterates = input("How many iterates: ")
trials = input("How many trials: ")
def function():
recordList = []
for i in range(iterates):
# math goes here
recordList.append()
return recordList
aggregateList = []
for i in range(trials):
aggregateList.append(function())
Or even:
def calculate (i): pass #math goes here
#nested:
aggregateList = [[calculate(i) for i in range(iterates)] for _ in range(trials)]
#flat:
aggregateList = [x for trial in ([calculate(i) for i in range(iterates)] for _ in range(trials)) for x in trial]
Let us assume you've have a list of lists (in a variable name lists). This would be after you have called your 'function()' function (not the greatest function name by the way) and collected your recordLists in a list.
trials = 3
lists = [[1,2,3],[4,5,6],[7,8,9]]
for i in range(trials):
aggregateList = [reduce(lambda x, y: x+y, [listn[i] for listn in lists]) for i in range(trials)]
print aggregateList
would output
[12, 15, 18]
which I think is the type of solution you are looking for.
reduce is a fun function from functional programming. It allows you to apply the anonymous function lambda continuously to items of a list and then return the accumulated value. So in this case, it is preforming (1+4)+7,(2+5)+8,(3+6)+9. The list we are applying reduce to is constructed through a comprehension to extract the i's from the lists inside lists. The call to reduce is wrapped inside another comprehension to return a list of the results.
So iterates is a number like 4, and trials another like 3.
aggregateList = [iterates]
now aggregateList = [4]. What's the purpose of that?
def function():
recordList = []
for i in range(iterates):
# math goes here
recordList.append()
what are you appending to recordList? That last line should produce an error like: append() takes exactly one argument (0 given)
aggregateList[i] += recordList[i]
what is i at this point? The last value of the above iteration, i.e. iterates-1 =3, or is supposed to be the trials iterator. How many items do you expect aggregateList to have at this point? As written I expect it to give an error: IndexError: list assignment index out of range.
for i in range(trials):
function()
What is 'the problem'? What error message or bad result were you getting?
I suspect you are more familiar with another language, and trying to apply its idioms to Python. Also, get the calculation working before worrying about efficiency. At some point, though you might want to use numpy which adds arrays, and the ability to do math on a whole array at once.