Percentage Calculations on Lists - python

I have created a quiz system which tests the user on two different topics. They are can choose whih topics they would like to do and a difficulty they wish to complete it in. If they get the question correct they get a point if they don't it will display the correct answer.
I am struggling to calculate the percentage based on the user's correct answers. For example, I have came up with "percent = score/100 x 100" which doesn't work. Any suggestions of calculating the percentage from these lists?
t = input("Choose 'a' for arithmetics or 'g' for german:")
d = input("Choose 'e' for easy , 'm' for medium , 'h' for hard:")
arithQeasy = [
("What is 4 + 4? Choose 1 or 2: 1) 8 2) 7","1"),
("What is 16 + 16? Choose 1 or 2: 1) 26 2) 32","2"),
]
arithQmedium = [
("How many 6's in 36? Choose 1, 2 or 3: 1) 6 2) 12 3) 3","1"),
("What is the Square root of 100? Choose 1, 2 or 3: 1) 50 2) 100 3) 10","3"),
("What is 0x1000? Choose 1, 2 or 3: 1) 1000 2) 0 3) 100","2"),
]
if t == "a" and d == "e":
questions = arithQeasy
elif t == "a" and d == "m":
questions = arithQmedium
for question, answer in questions:
userInput = input(question + '')
if userInput == answer:
score +=1
print ("correct your score is:",score)
elif:
print ("Incorrect the anseer is:",answer)

The following seems to work. Note there are a couple of issues with your code snippet:
The elif in the for loop needs to be an else.
You need to initialize score to zero before entering the for loop.
I've fixed these problems and added some code at the end illustrating how to compute the percentage of correct answers, as you asked how to do:
...
score = 0
for question, answer in questions:
userInput = input(question + '')
if userInput == answer:
score += 1
print("correct your score is:", score)
else:
print("Incorrect the anseer is:", answer)
percent = round((score / len(questions)) * 100, 2)
print('percent right: {}%'.format(percent))
Explanation
This works because a percentage is "a number or ratio expressed as a fraction of 100" (from the Wikipedia article on percentage), so the expression calculates the ratio of right answers, score, to the total number of questions, len(questions). It then multiples that by 100 since percentages always express this ratio as a "fraction of 100".
I also added a call to round()—which wasn't strictly necessary—to limit the number of digits after the decimal point to two, so long numbers like 6.666666666666666% would get converted to 6.67%. Technically this makes the final value computed slightly less accurate, but I doubt that matters here.

Related

Wrong Answer in Google Kickstart Practice Round 2019 Question 1 (Number Guessing)

So I am still learning to code and use python as my primary language. The question is we have two numbers. A and B which we have to take as input. A will be 0 and B is given in two test cases as 30 and 10^9. The system will pick a number (say P) between A(exclusive) and B(inclusive). We have to write a program to guess the number. If our guess is higher than P, the system will output "TOO_BIG" and we have to adjust our next guess. If our guess is lower than P, then we'll get "TOO_SMALL". If it's right, then we'll get "CORRECT". We have N tries to guess the number and N = 30.
This is my code:
import sys
def solve(lower,upper):
guessed_right = False
for _ in range(no_of_guesses):
midpoint = (lower + upper)//2
guess = midpoint
print(guess)
sys.stdout.flush()
judge = input()
if judge == "CORRECT":
guessed_right = True
break
elif judge == "TOO_BIG":
upper = midpoint - 1
elif judge == "TOO_SMALL":
lower = midpoint + 1
elif judge == "WRONG_ANSWER":
sys.exit()
def run():
T = int(input())
for case in range(T):
lower, upper = map(int(input().split()))
no_of_guesses = int(input())
solve(lower + 1, upper)
I am getting wrong answer for this and can't seem to find the problem

Regarding formatting of printed outputs (python) [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have been working on the program that lists out the products (with their cost and quantity) , and they are separately stored in 3 different lists.
However, what I can't figure out how to do is , aligning of the printed outputs
while valid ==1 :
if user_choice == 's':
user_product = str(input("Enter a product name: "))
valid = 2
elif user_choice == 'l':
print ("Product" + " " + "Quantity" +" "+ "Cost")
c = 0
while c < len(product_names):
print (product_names[c] + " " + str(product_costs[c]) + " "+ str(quantity[c]))
c +=1
valid = 0
break
valid = 0
So basically I am not sure on how to actually make output on line 6 and
line 9 be aligned together because I'll be getting a disorganized output because the product names differ in length, cost and quantity differ in length too.
Can anybody teach me how to actually align them all properly so that they might
look like a table?
Thanks so much!
Here is what you wanted, exactly by the prescribed order.
n = -1 # Intentionally an incorrect value
# Ask user for the number while he/she doesn't enter a correct one
while n < 10:
n = int(input("Enter an integer number greater or equal 10: "))
# Preparation for Sieve of Eratosthenes
flags_list = ["P"] # 1st value
flags_list = flags_list * (n + 1) # (n + 1) values
flags_list[0] = "N" # 0 is not a prime number
flags_list[1] = "N" # 1 is not a prime number, too
# Executing Sieve of Eratosthenes
for i in range(2, n + 1):
if flags_list[i] == "P":
for j in range(2 * i, n + 1, i):
flags_list[j] = "N"
# Creating the list of primes from the flags_list
primes = [] # Empty list for adding primes into it
for i in range(0, n + 1):
if flags_list[i] == "P":
primes.append(i)
# Printing the list of primes
i = 0 # We will count from 0 to 9 for every printed row
print()
for prime in primes:
if i < 10:
print("{0:5d}".format(prime), end="")
i = i + 1
else:
print() # New line after the last (10th) number
i = 0
=========== The answer for your EDITED, totally other question: ===========
=========== (Please don't do it, create a new question instead.) ===========
Replace this part of your code:
print ("Product" + " " + "Quantity" +" "+ "Cost")
c = 0
while c < len(product_names):
print (product_names[c] + " " + str(product_costs[c]) + " "+ str(quantity[c]))
c +=1
with this (with the original indentation, as it is important in Python):
print("{:15s} {:>15s} {:>15s}".format("Product", "Quantity", "Cost"))
for c in range(0, len(product_names)):
print("{:15s} {:15d} {:15d}".format(product_names[c], quantity[c], product_costs[c]))
(I changed your order in the second print to name, quantity, cost - to correspond with your 1st print.)
Probably you will want change 15's to other numbers (even individually, e. g. to 12 9 6) but the triad of numbers in the first print must be the same as in the second print().
The explanation:
{: } are placeholders for individual strings / integers listed in the print statements in the .format() method.
The number in the placeholder express the length reserved for the appropriate value.
The optional > means the output has be right aligned in its reserved space, as default alignment for text is to the left and for numbers to the right. (Yes, < means left aligned and ^ centered.)
The letter in the placeholder means s for a string, d (as "decimal") for an integer - and may be also f (as "float") for numbers with decimal point in them - in this case it would be {:15.2f} for 2 decimal places (from reserved 15) in output.
The conversion from number to string is performed automatically for symbols d or f in the placeholder, so str(some_number) is not used here.
Addendum:
If you will have time, please copy / paste your edited version as a new question, then revert this question to its original state, as people commented / answered your original one. I will find your new question and do the same with my answer. Thanks!

What's a better way to calculate score based on attempts and time taken?

I have created a number guessing game, where a user chooses a range of numbers to guess from, and when the user inputs a number, the program will respond if they are too high or too low, until the user guesses correctly. The program currently takes the number of attempts, and the time taken into account. There are also different difficulties (the higher the difficulty the more numbers to guess from). I have tried to create a scoring system but I need a little more help with the math side. Right now I have this code that generates a score:
def scorer(tries, total_time, difficulty):
# Tells the user how much time and how many attempts were made
print "\nCorrect! It took you " + str(round(total_time, 2)) + \
" seconds and " + str(tries) + " tries to guess.\n"
# Calculates score, making lower times and fewer
# tries yield a higher score
# Difmod takes into account the difficulty
# Multiply by 1000 to make number more readable
score = 1 / (1 + (tries * round(total_time, 2))) * 1000 * dif_mod(difficulty)[1]
# Prints the score, rounded to 1 decimal place
print "Score: " + str(round(score, 2))
tries and total_time are self-explanatory, and dif_mod is a value I made to try to make the score 'fairer' to higher difficulties. The value of dif_mod is higher, the higher difficulty there is. As shown here:
def dif_mod(difficulty):
if difficulty == 1:
return [10, 1]
elif difficulty == 2:
return [50, 1.5]
elif difficulty == 3:
return [100, 2]
elif difficulty == 4:
return [1000, 10]
elif difficulty == 5:
return [10000, 20]
elif difficulty == 0:
return [1, 1]
The first value in the list is the highest possible number to guess from, the second item in the list is dif_mod. These are all placeholder values and I want to figure out what I should use for them.
My main aim is to make a score higher based on fewer attempts and less time taken, but to also reward a user with a higher score if they are on a higher difficulty.

Rounding in Python

Hi everyone I am currently doing a school project and even my teacher is stumped. In Canada the penny has been removed so now all purchases are rounded to either 0 or 5. For example 5.53 would become 5.55 and 5.52 would become 5.50. I am trying to get my program to round like this, but I can't figure out how. I know how to round to decimal places, but I don't know how to round to specifics like this. Any help would be appreciated!
Here is my code. The project is about making a program that a cashier would use in a coffee shop.
order = ['coffee', 'tea', 'hashbrown','jelly','cream','chocolate','glazed','sandwich','bagel','cookie','pannini']
quantity = ['0','0','0','0','0','0','0','0','0','0','0']
# coffee = $1
# Tea = $1.30
# hashbrown = $1.25
# all donuts = $1.50
# sandwich = $2.50
# bagel = $2
# cookie = $0.50
# pannini = $4
cashier = 1
total = 0
while cashier == 1:
print "What did the customer order?"
ordered = input ()
while ordered > 10 or ordered < 0:
print "Do you want to input a valid order?"
ordered = input ()
print "How many are being ordered?"
quantityorder = input ()
quantity[ordered] = quantityorder
print "Ordered",quantityorder,"",order[ordered],"!"
if ordered == 0:
ordered = 1.0
elif ordered == 1:
ordered = 1.30
elif ordered == 2:
ordered = 1.25
elif ordered == 3 or ordered == 4 or ordered == 5 or ordered == 6:
ordered = 1.50
elif ordered == 7:
ordered = 2.50
elif ordered == 8:
ordered = 2
elif ordered == 9:
ordered = 0.50
else:
ordered = 4.0
price = ordered * quantityorder
total = total + price
print "Anything else?"
cashier = input () #If the user inputs 1 then they can input another order if they didn't put in 1 then the program assumes that it is the end of a customers order
print "Your total is $", total * 1.13,"!"
total = total * 1.13
print
print "How much money was given?"
print
money = input ()* 1.0
while money < total:
print "Please input a valid number!"
money = input ()
print "The change should be $",money - total,"!"
This tortured me until I solved it. One rule I set for myself was NOT to use a case-by-case switch on modulo 5, but to use builtin functions. Nice puzzle. wim's "double it, round, then halve it" comment was close.
def nickelround(n):
N = int(n)
print "%0.2f" % (N + round((n - N) * 20) * 0.05)
In [42]:
x=0.57
int(x/0.05)*0.05
Out[42]:
0.55
Usually in these programming problems you're explicitly asked to solve for how to "make change", not just provide the total amount of change due (which is trivial). So you can just in-line the pennies correction into that function:
def make_change(bal):
bal = bal + .02 #correction for no pennies
currency = [20,10,5,1,.25,.1,.05]
change = {}
for unit in currency:
change[unit] = int(bal // unit)
bal %= unit
return change
This particular form returns a dict of change denominations and their corresponding counts.
As you already hinted, use the Decimal class (module decimal). Replace all floats in your code with decimal constructors like Decimal('13.52').
Now the function you want to use is 'quantize'.
You use it like that:
Decimal('1.63').quantize(Decimal('0.5'), rounding=ROUND_HALF_DOWN)
The parameter Decimal('0.5') indicates that you want to round to the halves.
UPDATE:
As the OP wanted to round to the units of 0.05, he must obviously use:
Decimal('1.63').quantize(Decimal('0.05'), rounding=ROUND_HALF_DOWN)
I'm going to be old-school and say, convert your number into a list of values with a null or some kind of tag to represent the decimal.
The make a variable to hold your rounded number and add each value from 1000s or whatever, to 100s, 10s and 1s. (You are looping of course).
Once your loop hits the tag, depending on how far you want to round, (this should be a parameter for your function) throw in a conditional to represent how you want to round ie. 5 means round up, 4 round down (this is another parameter). Then add the final value(s) and return your newly rounded number.
Step 2: Fire your teacher because this is an unbelievably easy problem.
Bare in mind, anyone who knows c or has worked with memory assignment should find this question a breeze.
You could use something as simple as this to round your numbers to a given base:
def round_func(x, base=0.05):
return round(base*round(float(x)/base), 2)
And since you want only 2 decimal places, you can just round it to 2 decimals. The inner round function is to round the given number as per the base, which is 0.05 in your case.
Do you know, how to use own functions?
Add this function to your code:
def nickelround(m):
return round(m/0.05,0)*0.05
and use it:
print "The change should be $", nickelround(money - total),"!"

Russian Peasant Multiplication Python 3.3

I need help with a program in python 3.3 that is supposed to do Russian peasant multiplication/ancient Egyptian multiplication. The assignment says," If "A" and "B" are the two integers to be multiplied, we repeatedly multiply "A" by 2 and divide "B" by 2, until "B" cannot divide any more and is not zero (integer division). During each set of multiplying "A" and dividing "B", if the value of "B" is an odd number, you add whatever the "A" value is to a total. At the end, the sum of all the "A" values (when "B" is odd) should be equal to the product of the original "A" and "B" inputs. In short, sum up all the "A" values for which "B" is odd and it will be equal (or close) to the product of "A" and "B".
edit
I may have phrased some of the question wrong.
Here is an example:
If "A" is 34, and "B" is 19, multiplying "A" by two and dividing "B" by two each line.
"A" "B"
(34) (19) ("B" is odd, add "A" to total)
(68) (9) ("B" is odd, add "A" to total)
(136) (4) ("B" is even, ignore "A" value)
(272) (2) ("B" is even, ignore "A" value)
(544) (1) ("B" is odd, add "A" to total)
When you sum all the values of "A" for which "B" is odd, you get (34 + 68 + 544 = 646),
which is equal to just multiplying "A" and "B", (34 * 19 = 646).
The part I'm having trouble with is adding "A" to a total whenever "B" is an odd number.
This is what I have so far,
x = int(input("What is the first number? "))
y = int(input("What is the second number? "))
answer = 0
while y != 0:
if (y%2 != 0):
x*2
y//2
answer == answer + x
if (y%2 == 0):
x*2
y//2
print("the product is",(answer))
I'm very new to python and programming, so any help and/or explanations of why its wrong would be greatly appreciated.
you need to add x to answer first, then update x
here is the correct code
x = int(input("What is the first number? "))
y = int(input("What is the second number? "))
answer = 0
while y != 0:
if (y%2 != 0):
answer=answer+x
x=x*2
y=y//2
if (y%2 == 0):
x=x*2
y=y//2
print("the product is",(answer))
I'm not familiar with the algorithm you are trying to implement, but I have made a few modifications to your code.
x = int(input("What is the first number? "))
y = int(input("What is the second number? "))
answer = 0
# != 0 is redundant: y is True if it is not 0
while y:
# no need to have parentheses here
if y % 2:
# this needs to be an assignment, not a check for equality
answer += x # shorthand for answer = answer + x
# These happen every time, so does not need to be inside the if
# these also need to be an assignment, not just an expression
x *= 2
y /= 2
# total was never defined
print("the product is", (answer))
A side note. Frankly, I did not know about the algorithm until now. The more it surprises me it was used by ancient Egyptians or in old Russia. (Actually, I tend to believe that the Russian origin is more probable as it seem that Slavic nations are directly related to old Etrusks).
The old origin surprises me because it actually is a plain hand-made multiplication that you learned in the basic school. The only difference is that the numbers are converted to binary representation first. Rather machine oriented, isn't it? :)
For the numbers in the question, th 34 in decimal representation is equal to 100010 in binary, the 19 in decimal is 10011 in binary. Now the plain basic school multiplication on paper:
100010
x 10011
------------
100010 i.e. 100010 times 1
100010 1000100 times 1
000000 10001000 times 0
000000 100010000 times 0
100010 1000100000 times 1
------------ ^ binary digits of the multiplier
1010000110 (reminder of division by 2)
^ adding the zero means multiplying by 2
i.e. sum only when 1 is the reminder of division
It seems that the one who designed the metod (in ancient times) knew what the binary numbers are.
The last time you add x is when y is equal to 1. If you keep halving until the number
reaches 0, it will take a very large number of iterations (logically, it will take
forever).
Think about 2x2. If you double x to 4, and halve y to 1, x is your answer.
In other words, think of y as how many of x I need to yield answer. Since you can't multiply, only add/double/halve, you have a choice - you can wait until y is 2 and then add doubled value of x, OR you can wait until y is 1 and simply add value of x. The latter is simpler and clearer, that's all.
I think it's clearer in this case to use a while True loop:
def mult2(x, y):
answer = 0
while True:
if y % 2:
answer += x
if y < 1:
break
x *= 2
y //= 2
print("the product is", answer)
Calling function recursively:
def mult2(x, y):
"""aka 'Russian peasant method'; allowed: addition, halving, doubling."""
if y==1:
return x
else:
add = x if y%2 else 0
return mult2(x*2, y//2) + add
the output is a normal mutiplication display. Please share the code where the output is also displayed showing the Russian Peasent method.
Output should be something like this:
If "A" is 34, and "B" is 19,
(34) (19) ("B" is odd, add "A" to total)
(68) (9) ("B" is odd, add "A" to total)
(136) (4) ("B" is even, ignore "A" value)
(272) (2) ("B" is even, ignore "A" value)
(544) (1) ("B" is odd, add "A" to total)
When you sum all the values of "A" for which "B" is odd, you get (34 + 68 + 544 = 646), which is equal to just multiplying "A" and "B", (34 * 19 = 646).

Categories