I am making a D&D style character generator and I am rolling the stats for them and allowing them to allocate them to the ability score they want. I would like to have the ability to start at the same stat they were at vs the entire section over again.
Here is what I have
from random import randint
def char_stats():
# roll 4 D6s drop the lowest number and add the highest 3
s1,s2,s3,s4,s5,s6 = ([],[],[],[],[],[])
for x in range(4):
s1.append(randint(1,6))
s2.append(randint(1,6))
s3.append(randint(1,6))
s4.append(randint(1,6))
s5.append(randint(1,6))
s6.append(randint(1,6))
stat1 = sorted(s1)
stat2 = sorted(s2)
stat3 = sorted(s3)
stat4 = sorted(s4)
stat5 = sorted(s5)
stat6 = sorted(s6)
return sum(stat1[1:]),sum(stat2[1:]),sum(stat3[1:]),sum(stat4[1:]),sum(stat5[1:]),sum(stat6[1:])
a = list(char_stats())
print "Please choose one of the following for your stat: {}".format(a)
while len(a) > 0:
try:
Strength = int(raw_input('Please input one of these stats for your Strength:\n'))
if Strength in a:
a.remove(Strength)
print a
Wisdom = int(raw_input('Please input one of these stats for your Wisdom:\n'))
if Wisdom in a:
a.remove(Wisdom)
print a
Intelligence = int(raw_input('Please input one of these stats for your Intelligence:\n'))
if Intelligence in a:
a.remove(Intelligence)
print a
Constitution = int(raw_input('Please input one of these stats for your Constitution:\n'))
if Strength in a:
a.remove(Constitution)
print a
Dexterity = int(raw_input('Please input one of these stats for your Dexterity:\n'))
if Dexterity in a:
a.remove(Dexterity)
print a
Charisma = int(raw_input('Please input one of these stats for your Charisma:\n'))
if Charisma in a:
a.remove(Charisma)
except ValueError:
print "Incorrect Input"
continue
I have tried nesting each of the if statements (which I believe is very bad form) and have similar results. I have also tried grouping all the inputs into the try and not the calculations and have gotten the same results. Any advice?
You need to use the "loop until valid" logic for both the format (int) of the input, and the value (is it in the list of rolled stats?). The basic logic is this:
while True:
# get input
# check input
# if input is valid,
# break
In your case, this looks something like
while True:
user = input("Please enter a stat to use")
if user.isnumeric():
stat_choice = int(user)
if stat_choice in a:
break
Now, to make effective use of this, you need to parametrize your six stats and put those into a loop:
stat_name = ["Strength", "Wisdom", ...]
player_stat = [0, 0, 0, 0, 0, 0]
for stat_num in range(len(player_stat)):
while True:
user = input("Please input one of these stats for your" + \
stat_name[stat_num] + ": ")
# Validate input as above
player_stat[stat_num] = stat_choice
Note that you can similarly shorten your char_stats routine to a few lines.
Does that get you moving?
You have at least one function in your code (char_stats) so I feel like you know how to do functions.
This is a great place to use a function.
My suggestion, for this code, would be to write a function that incorporates the try/except, the asking of the question, and the checking against the stats list.
Something like this:
def pick_a_stat(stats, prompt):
"""Prompt the user to pick one of the values in the `stats` list,
and return the chosen value. Keep prompting until a valid entry
is made.
"""
pass # Your code goes here.
Related
I have tried this several different ways, I am still fairly new to Python so go easy on me. I am trying to execute a script where the user can choose to import a list from a plaintext file, or input a list manually, and the script will return the median and mode of the data.
The problem I am having is that my median and mode functions are not recognizing the reference to the raw data, and the main function isn't recognizing the median and mode from their respective functions.
I guess it's safe to say I am not calling these functions correctly, but frankly I just dont know how. Any help here would be much appreciated.
def choice():
##Choose user input type
start = input("Please select your input method by typing 'file' or 'manual' in all lower-case letters: ")
# Import File Type
userData = []
if start == "file":
fileName = input("Please enter the file name with the file's extension, e.g. ' numbers.txt': ")
userData = open(fileName).read().splitlines()
return userData
userData.close()
# Manual Entry Type
elif start == "manual":
while True:
data = float(input("Please enter your manual data one item at a time, press enter twice to continue: "))
if data == "":
break
userData = data
return userData
# Error
else:
print("You have entered incorrectly, please restart program")
def median(medianData):
numbers = []
for line in (choice(userData)):
listData = line.split()
for word in listData:
numbers.append(float(word))
# Sort the list and print the number at its midpoint
numbers.sort()
midpoint = len(numbers) // 2
print("The median is", end=" ")
if len(numbers) % 2 == 1:
medianData = (numbers[midpoint])
return medianData
else:
medianData = ((numbers[midpoint] + numbers[midpoint - 1]) / 2)
return medianData
def mode(modeData):
words = []
for line in (choice(userData)):
wordsInLine = line.split()
for word in wordsInLine:
words.append(word.upper())
theDictionary = {}
for word in words:
number = theDictionary.get(word, None)
if number == None:
theDictionary[word] = 1
else:
theDictionary[word] = number + 1
theMaximum = max(theDictionary.values())
for key in theDictionary:
if theDictionary[key] == theMaximum:
theMaximum = modeData
break
return modeData
def main():
print("The median is", (median(medianData)))
print("The mode is", (mode(modeData)))
Welcome! I think you need to read up a bit more on how functions work. The argument when you define a function is a "dummy" local variable whose name matters only in the definition of a function. You need to supply it a variable or constant whose name makes sense where you use it. It is a very good analogy to functions in mathematics which you may have learned about in school. (Note that these points are not specific to python, although the detailed syntax is.)
So when you have def median(medianData) you need to use medianData in the definition of the function, not userData, and when you call median(somevar) you have to make sure that somevar has a value at that point in your program.
As a simpler example:
def doubleMyVariable(x):
return 2*x
How would you use this? You could just put this somewhere in your code:
print(doubleMyVariable(3))
which should print out 6.
Or this:
z = 12
y = doubleMyVariable(z)
print(y)
which will print 12.
You could even do
z = 36
x = doubleMyVariable(z)
which will assign 72 to the variable x. But do you see how I used x there? It has nothing to do with the x in the definition of the function.
I'm new to stack overflow and Python too. I'm currently coding in Python 3.8.2 on https://www.repl.it.
I am making a math solver which solves things using certain formulas, I have print functions, input functions and variables which are also integers.
What I want to do is that the user will be greeted, then the user will be prompted to choose a certain option (ex. 1, 2, 3, etc.) and each option would be a formula/method.
I have written code for just one formula as of now, but this concept which I'm solving has multiple different formulas.
Have a look at my code below:
print("Hello, welcome to the \nA.P. SOLVER!")
import click
if click.confirm("Do you want to start?", default=True):
print("Ok! Let's start!")
a = input('Type the value of "a" [the first term of the A.P.] ')
d = input('Type the value of "d" [the common difference of the A.P.] ')
n = input('Type the value of "n" [the nth term of the A.P.] ')
print(f"Finding the {n}'th/nd' term...")
a = int(a)
d = int(d)
n = int(n)
x = a + (n-1)*d
print(x)
Please help me out, would be appreciated :)
what I've understood from your question is that you want to make a menu driven program that asks what you want to do. What you can do is take the value (here action) which will decide in the switch() what will happen with it.
import click
def switch(action):
if action==1:
a = int(input('Type the value of "a" [the first term of the A.P.]'))
d = int(input('Type the value of "d" [the common difference of the A.P.]'))
n = int(input('Type the value of "n" [the nth term of the A.P.] '))
print(f"Finding the {n}'th/nd' term...")
x = a + (n-1)*d
print(x)
else:
a=int(input("Number 1 :"))
b=int(input("Number 2 :"))
print("Subtraction :",a-b)
if click.confirm("Do you want to start?", default=True):
print("Ok! Let's start!")
print("1) AP")
print("2) Sub")
action=int(input(":"))
if action not in [1,2]:
print("Invalid")
else:
switch(action)
If you want it to go on until the user wants to quit you can write before the 1) AP part a while loop which will go on until the user enters lets say 3) Exit which will break that while loop.
I am attempting to write a program that generates random numbers, asks how big you want it, between 1-4 for example, then I want it to ask how many numbers you want and finally ask you if you want to run it again. I am attempting to grasp the concepts of recursion and type casting, just trying to learn the concepts of Object Orientated Design with Python. I tried to glean from what I have read so far on the Learn Python Hard Way site.
from random import randint
def random_with_N_digits(n):
range_start = 10**(n-1)
range_end = (10**n)-1
return randint(range_start, range_end)
# Here I am attempting to define the variables I need to convert keyboard input to int
size = raw_input()
intsize = # unsure of how to define this variable
intsize = int(size)
print "How many Digits?",
size = raw_input()
print "How many Times?".
times = raw_input()
# I want to construct a method here that sends my size input to random_with_N_digits(n)
# I need a method that runs the random_with_N_digits according to the input.
# while True:
reply = input('Enter text:')
if reply == 'stop':
break
if reply = times # not sure what to put here
print( def random_with_N_digits)
else:
# I want to tell the my method to run as many as much as 'times' is equal to
print "Again?"
answerMe = raw_input()
# here I want to have a if answerMe = Enter run the method again
print random_with_N_digits()
try this code
from random import randint
def random_with_N_digits(n):
s = int(raw_input("starting from.. "))
e = int(raw_input("upto... "))
l = ""
for i in range(0,n):
l= l +str( randint(s,e))
print int(l)
again = raw_input("print again?")
if again == "yes":
how_many =int(raw_input("how many digits?"))
random_with_N_digits(how_many)
how_many =int(raw_input("how many digits?"))
random_with_N_digits(how_many)
I have something like this:
s=[7777,5454,75000,4545,787,16000,1000,9888,7854,12223]
random.shuffle(s)
ans=input('Press a number from 0 to 9')
I want to associate the input number ans with the s[ans] element. I can do it with 10 if loops, is this the only chance? //SOLVED this
Done that, I want to repeat the random extraction until user digits something like "stop" (here I am) and then sum all the value extracted until "stop" string. How can I do this last point?
Thanks all!
from random import choice
elem = choice (some_list)
If you are only trying to select a random number (and asking for input is only a means to achieve that goal), then you should really look into random.choice. It does exactly what you need, and you won't have to spend time shuffling your list
You can directly access values of an array like so:
s[ans]
But first you may have to convert ans to an integer (and handle cases where a user sends something that's not a number!)
try:
i = int(s)
except ValueError:
i = 0
You've edited your question to declare the original version "solved" and then added a second one. In the future, don't do that; accept the answer that solved the problem for you, then create a new question. (And you should still accept the answer that solved your original problem!) But this time only, here's a second answer:
Done that, I want to repeat the random extraction until user digits something like "stop" (here I am) and then sum all the value extracted until "stop" string. How can I do this last point?
I'm assuming you're on Python 2, and using the input function so the user can just type 2 and you get the number 2 instead of the string "2". (If you're using Python 3, input works like Python 2's raw_input, so see the second version.)
So:
s=[7777,5454,75000,4545,787,16000,1000,9888,7854,12223]
random.shuffle(s)
values = []
while True:
ans=input('Press a number from 0 to 9')
if ans == 'stop':
break
values.append(s[ans])
print sum(values)
Note that the user will have to type "stop" with the quotes this way. If the user instead types stop (or 10, for that matter), the program will quit with an exception. It would be much better to use raw_input instead, and do something like this:
s=[7777,5454,75000,4545,787,16000,1000,9888,7854,12223]
random.shuffle(s)
values = []
while True:
ans=raw_input('Press a number from 0 to 9, or stop when done')
if ans == 'stop':
break
try:
index = int(ans)
values.append(s[ans])
except ValueError:
print '{} is not a number or the word stop'.format(ans)
except IndexError:
print '{} is not between 0 and 9.'.format(ans)
print sum(values)
You may recognize that this values = [], while, values.append pattern is exactly what list comprehensions and iterators are for. And you can easily factor out all the user input into a generator function that just yields each s[ans], and then just print sum(userChoices()), without having to build up a list at all. But I'll leave that as an exercise for the reader.
ans = 0
s = [7777,5454,75000,4545,787,16000,1000,9888,7854,12223]
ans_sums = []
while ans != 'stop': # while the input is not 'stop'
random.shuffle(s)
ans = raw_input('Press a number from 0 to 9: ') # this returns the input as a string
if ans == 'stop':
break
else:
ans_sums.append(int(s[ans])) # adds s[ans] to ans_sums.
# it must be converted to an integer first because raw_input returns it as a string
return sum(s[ans])
Alternatively, you can do something like:
ans = 0
s = [7777,5454,75000,4545,787,16000,1000,9888,7854,12223]
ans_sums = 0
while ans != 'stop': # while the input is not 'stop'
random.shuffle(s)
ans = input('Press a number from 0 to 9: ')
if ans == 'stop':
break
else:
ans_sums += s[ans] # adds s[ans] to ans_sums
return ans_sums
This avoids creating a list and accomplishes the same job: finds the sum of all the input.
Is there any way to generate a number of raw_inputs (With unique variables) based on user input? So, say I had this:
if choice == 1:
noelemen = int(raw_input("Enter total amount of elements: "))
Would there be any way to make it so the integer put in that raw_input field would then "generate" the required amount of raw_inputs? I'd suppose, if it was possible, that it'd make use of functions or something similar, but I'm a bit confused about how I'd get it done to be able to do that.
What I have currently is this:
if noelemen == 1:
first = raw_input("Enter element: ")
#Look for the weight of the entered element
weight1 = float(elemen_data.get(first.lower()))
if weight1 is not None:
total_weight = weight1
print "Total mass =", total_weight
if noelemen == 2:
first = raw_input("Enter first element: ")
second = raw_input("Enter second element: ")
#Look for the weight of the entered element
weight1 = float(elemen_data.get(first.lower()))
weight2 = float(elemen_data.get(second.lower()))
if weight1 is not None:
total_weight = weight1 + weight2
print "Total mass =", total_weight
Which is probably a pretty messy way of doing it, particularly as I'd have to go up to perhaps something like 10 elements, or perhaps even beyond.
So, to repeat... Any way to generate raw_inputs with unique variables based on user input?
how about something like this?
elements = []
numberOfPrompts = raw_input("Enter total amount of elements: ")
for i in range(numberOfPrompts):
# will prompt "Enter Element 1: " on the first iteration
userInput = raw_input("Enter Element %s" % (i+1, ))
elements.append(userInput)
Example case:
>>> Enter total amount of elements: 2 # now hit enter
at this point, the value of the variable numberOfPrompts will be 2.
The value of the variable elements will be [], i.e. it is an empty list
>>> Enter Element 1: 3.1415 # hit enter
numberOfPrompts stays 2,
elements will be ['3.1415']
>>> Enter Element 2: 2.7182
elements will be ['3.1415', '2.7182']
Now the for-loop is done and you got your user inputs conveniently in the 0-indexed list elements, which you access like a tuple (array):
>>> elements[1]
2.7182
Edit:
After reading your comment I noticed what you intend to do and, just like the other answer stated, it would be best to use a dictionary for this. This should work:
elements = {}
numberOfPrompts = raw_input("Enter total amount of elements: ")
for i in range(numberOfPrompts):
# will prompt "Enter Element 1: " on the first iteration
userInput = raw_input("Enter Element %s" % (i+1, ))
userInput = userInput.lower()
elements[userInput] = float(elem_data.get(userInput))
now elements will look like this:
{'oxygen':15.9994, 'hydrogen':1.0079}
you can iterate over all keys like this (to find out, which elements have been entered):
for element in elements.keys():
print element
# output:
oxygen
hydrogen
To get all values (to sum them up, for instance), do something like this:
weightSum = 0
for weight in elements.values():
weightSum += weight
print weightSum
# output:
17,0073
Keep in mind that this example is for python 2.x. For python 3.x you will need to adjust a couple of things.
I would use a dictionary for this:
noelemen = int(raw_input("Enter total amount of elements: "))
elem={}
for x in xrange(1,noelemen+1):
elem[x]=raw_input("Enter element: ")