I am trying to calculate the cost each person will have to pay daily on a trip. I can get the prompts to work, but not the math. I have no idea on how to do the math with the lists. Anyone got any ideas?
Here is what I have so far:
def main():
morepeople = True
NumPPL = list()
Days = list()
Gas = list()
Food = list ()
Nopeople = 0
while(morepeople):
Numppl = (input('Enter the amount of people traveling: '))
if(Numppl == Nopeople):
morepeople = False
else:
NumPPL.append(Numppl)
Days.append(input('Enter the amount of predicted days traveling: '))
Gas.append(input('Enter gas cost per day: '))
Food.append(input('Enter food cost per day: '))
break
Cost = sum(Gas) and sum(Food)/ sum(NumPPL)
print('Everyones daily share is: ', Cost)
main()
welcome to these boards.
This is a curious approach and interesting question.
Couple things to help you...
1> Input() passes a string regardless of the value actually input. You should convert it to an integer or float before using it in a mathematical operation.
2> As dea87 called out, aggregations on list objects require sum() or len() to get the total of values or count of entries, respectively.
Related
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))
Here is my function that uses the Poloniex Exchange API. It gets a dict of asks (tuples of price and amount) and then calculates the total amount of BTC that would be obtained using a given spend.
But running the function several times returns different amounts despite the dict of asks and spend remaining the same. This problem should be replicable by printing "asks" (defined below) and the function result several times.
def findBuyAmount(spend):
#getOrderBook
URL = "https://poloniex.com/public?command=returnOrderBook¤cyPair=USDT_BTC&depth=20"
#request the bids and asks (returns nested dict)
r_ab = requests.get(url = URL)
# extracting data in json format -> returns a dict in this case!
ab_data = r_ab.json()
asks = ab_data.get('asks',[])
#convert strings into decimals
asks=[[float(elem[0]), elem[1]] for elem in asks]
amount=0
for elem in asks: #each elem is a tuple of price and amount
if spend > 0:
if elem[1]*elem[0] > spend: #check if the ask exceeds volume of our spend
amount = amount+((elem[1]/elem[0])*spend) #BTC that would be obtained using our spend at this price
spend = 0 #spend has been used entirely, leading to a loop break
if elem[1]*elem[0] < spend: #check if the spend exceeds the current ask
amount = amount + elem[1] #BTC that would be obtained using some of our spend at this price
spend = spend - elem[1]*elem[0] #remainder
else:
break
return amount
If the first ask in the asks dict was [51508.93591717, 0.62723766] and spend was 1000, I would expect amount to equal (0.62723766/51508.93591717) * 1000 but I get all kinds of varied outputs instead. How can I fix this?
You get all kinds of varied outputs because you're fetching new data every time you run the function. Split the fetch and the calculation into separate functions so you can test them independently. You can also make the logic much clearer by naming your variables properly:
import requests
def get_asks(url="https://poloniex.com/public?command=returnOrderBook¤cyPair=USDT_BTC&depth=20"):
response = requests.get(url=url)
ab_data = response.json()
asks = ab_data.get('asks', [])
#convert strings into decimals
return [(float(price), qty) for price, qty in asks]
def find_buy_amount(spend, asks):
amount = 0
for price, qty in asks:
if spend > 0:
ask_value = price * qty
if ask_value >= spend:
amount += spend / price
spend = 0
else:
amount += qty
spend -= ask_value
else:
break
return amount
asks = get_asks()
print("Asks:", asks)
print("Buy: ", find_buy_amount(1000, asks))
Your math was wrong for when the ask value exceeds remaining spend; the quantity on the order book doesn't matter at that point, so the amount you can buy is just spend / price.
With the functions split up, you can also run find_buy_amount any number of times with the same order book and see that the result is, in fact, always the same.
The problem is in your "we don't have enough money" path. In that case, the amount you can buy does not depend on the amount that was offered.
if elem[1]*elem[0] > spend:
amount += spend/elem[0]
A simple program to help me calculate costs for some new flooring, but my final outputs are not what i expect.
In particular, when underlay is "No", the variable for underlayarea is still picking up a value and being printed at the end.
If it isn't painfully obvious, this is my first crack at it. Ever.
I was expecting that while the variables for 'edging' and 'underlay' remained "No" that no values would be stored in that while loop.
underlay='No'
edging=input('Are you ordering Edging?').title()
underlay=input('Are you ordering underlay?').title()
roomsize=input('How many square meters is the room?')
roomflt=float(roomsize)
while edging =='Yes':
#ask for user inputs
edgeprice=input("How much is the edging per meter?")
edgeperim=input('What is the perimeter of the room?')
#convert to float for calculation
one=float(edgeperim)
two=float(edgeprice)
#calculate
edgearea=one*two
#reset flag
edging='No'
while underlay=='Yes':
#ask for user input
underlayprice=input('How much per square meter for the Underlay?')
#convert to float for calculation
three=float(underlayprice)
four=float(roomflt)
#calculate
underlayarea=three*four
#reset flag
underlay='No'
#set the floor price
floorprice=input("How much is the floor per square meter?")
#convert to float for calculation
five=float(floorprice)
six=float(roomflt)
#calculate
area=five*six
#get the cost
addemup=(edgearea+underlayarea+area)
print("\n----------------------------------------------\nThe total is £{0:.2f} to purchase the flooring.".format(addemup))
print("This is made up of £{0:.2f} for the floor itself,".format(area))
print("This is made up of £{0:.2f} for the edging,".format(edgearea))
print("and £{0:.2f} for the underlay".format(underlayarea))
You should use simple if-statements instead of using a while-loop and "resetting the flag" at the bottom of the loop. I also improved readability of your code by giving the variables telling names (never give variables names such as one, two and so on). You also have to define edgearea and underlayarea, because else a NameError would be raised in case the user does enter "No" in at least one of the inputs.
edgearea = 0
underlayarea = 0
edging = input('Are you ordering Edging?').title()
underlay = input('Are you ordering underlay?').title()
roomsize = input('How many square meters is the room?')
roomsize = float(roomsize)
if edging == 'Yes':
edgeprice = float(input("How much is the edging per meter?"))
edgeperim = float(input('What is the perimeter of the room?'))
edgearea = edgeperim * edgeprice
if underlay == 'Yes':
underlayprice = float(input('How much per square meter for the Underlay?'))
underlayarea = underlayprice * roomsize
floorprice = float(input("How much is the floor per square meter?"))
area = floorprice * roomsize
total_price = edgearea + underlayarea + area
print(f"\n----------------------------------------------\nThe total is {total} to purchase the flooring.")
print(f"This is made up of {area} for the floor itself,")
if edgearea:
print(f"This is made up of {edgearea} for the edging,")
if underlayarea:
print(f"and {underlayarea} for the underlay")
I would also like to recommend having a look at the DRY principle, aka "Don't repeat yourself". The three calculations have basically the same form. That's why it would be better code style to define a function for these calculations which takes the necessary parameters. A DRY solution could look similar to the following:
def calculate(
name: str,
dimension: str,
unit: str,
mandatory: bool = True,
) -> float:
mandatory = mandatory or input(f"Do you order {name}?") == "Yes"
if mandatory:
relative_price = float(input(f"How much is the {name} per {unit}?"))
size = float(input(f"How much {dimension} is the room?"))
return size * relative_price
return 0
floor_price = calculate("floor", "area", "squaremeters")
edging_price = calculate("edging", "perimeter", "meters", False)
underlay_price = calculate("underlay", "area", "squaremeters", False)
total_price = floor_price + edging_price + underlay_price
I need some help here, without using lists and strictly for loop, how do I implement my for loop to insert different variable with different user input?
def prompt():
total = int(input("How many books do you have in your basket? "))
return total
x = prompt()
book = 0
for i in range(x):
book = (float(input('What is the price of book number ' + str(i+1))))
""" book(i) = book """
""" I do not know how to implement the next code to put the book into a different variable to declare that e.g book = book1, book = book2 etc."""
Appreciate if someone can help me out. thanks!
You don't need to create variable here. Here is how you would do the sum, I'll leave the average to you:
def prompt():
total = int(input("How many books do you have in your basket? "))
return total
total_price = 0
N = prompt()
for i in range(N):
msg = 'What is the price of book number '+str(i+1)+' '
price = float(input(msg))
total_price += price
print("The total price is ", total_price)
Creating dynamic variables is generally a very bad practice, and is almost certainly not what your instructor is expecting you to do. Indeed, how would you know how to refer to them? Even if you did do that, it would require using much more arcane things than a list.
I am a novice python code writer and i am starting small with a fuel conversion program. The program asks for your name and then converts a miles per gallon rate or a kilometers per litre rate. Currently, the program runs fine until it gets to the convert to MPG line. then once you press y, it does nothing. funny thing is, no syntax error has been returned. please help as i cannot find anything on it :(
import time
y = 'y', 'yes', 'yep', 'yea', 'ye'
n = 'n', 'no', 'nup', 'nay'
name = str(input("Hey, User, whats your name? "))
time.sleep(1.5)
print("Alright", name, "Welcome the the *gravynet* Fuel Efficiency Converter!")
time.sleep(1.5)
str(input("Would you like to convert the fuel efficiency of your motor vehcile? (Miles Per Gallon) (y/n): "))
if y is True:
miles = int(input("How far did you travel (in miles): "))
galls = int(input("How much fuel did you consume (in gallons): "))
mpgc = (galls/miles)
print("The MPG Rate is: ", int(mpgc))
time.sleep(2)
print("test print")
if y is (not True):
input(str("Would you like to convert KPL instead? (y/n): "))
time.sleep(1.5)
if y is True:
kilometers = int(input("How far did you travel (in kilometers): "))
litres = int(input("How much fuel did you consume (in litres): "))
kplc = ( litres / kilometers )
print("The KPL Rate is: ", int(kplc))
time.sleep(3)
exit()
if y is not True:
print("No worries")
time.sleep(1.5)
print("Thanks", name, "for using *gravynet* Fuel Efficiency Coverter")
time.sleep(1.5)
print("Have a good day!")
time.sleep(1.5)
exit()
else :
print("Sorry, invalid response. Try again")
exit()
elif not y:
print("Please use y/n to answer" )
time.sleep(2)
elif not n:
print("Please use y/n to answer" )
time.sleep(2)
sorry if you think that is bad but i just started python and i need some help :)
Severely trimmed down and indentation fixed (I think....)
if y is True and similarly if y is not True make no sense here.
Also, speaking of is.. is and == may be work as equivalent expressions sometimes for checking for "equality", but not necessarily. == checks for equality whereas is checks for object identity. You should use == for checking for equality between two objects. Except for None in which case it's generally preferred to use is instead of == for this.
You're converting to str in a bunch of places unnecessarily. They're already strings.
In your mpg conversion you already have a floating point number (possibly an int). There's no need to convert to an int here. Suppose mpg is < 1. Then int casting will make this return zero
Your math is also backwards. miles per gallon. Similarly, kilometers per gallon.
name = input("Hey, User, whats your name? ")
print("Alright", name, "Welcome the the *gravynet* Fuel Efficiency Converter!")
mpg = input("Would you like to convert the fuel efficiency of your motor vehcile? (Miles Per Gallon) (y/n): ")
if mpg in y:
miles = int(input("How far did you travel (in miles): "))
galls = int(input("How much fuel did you consume (in gallons): "))
mpgc = miles / galls
print("The MPG Rate is: ", mpgc)
else:
kpl = input("Would you like to convert KPL instead? (y/n): ")
if kpl in y:
kilometers = int(input("How far did you travel (in kilometers): "))
litres = int(input("How much fuel did you consume (in litres): "))
kplc = kilometers / litres
print("The KPL Rate is: ", kplc)
else:
print("No worries")
print("Thanks", name, "for using *gravynet* Fuel Efficiency Coverter")
print("Have a good day!")
The is keyword in python checks if two variables point to the same location in memory. y will never point to the same memory location as the singleton True because it's value is a string. I suspect what you mean to do is something like
inp = str(input("Would you like to convert the fuel efficiency of your motor vehcile? (Miles Per Gallon) (y/n): "))
if inp in y:
...
You cannot directly take y as pressed from the keyboard, you have to take it as an input(Pressing enter would be required), store it, check if it satisfies the conditions, then apply the logic.
I see you tried to define y and n as a tuple (deliberately or not), In that case I assume you also want to take those other words as yes or or too.
In that case you can apply this logic;
inp = input("Would you like to convert the fuel efficiency of your motor vehcile? (Miles Per Gallon) (y/n): ")
if inp in y: # Check if inp corresponds any of the words defined in y
# Things to do if `yes` or anything similar entered.
Some notes:
You don't need to use str() after you take input if you are using
Python3 (Which seems you are). Because input() returns string.
In somewhere you did something like this:
input(str("Would you like to convert KPL instead? (y/n): "))
Which is even more reduntant because the value you entered is already
a string.
You also didn't assign some inputs to any variable throughout the
code. You should assign them If you are to use them later.
Please take care of these issues.