While loop with min and max conditions Python - python

I would like to charge a car under the condition that in the end it is charged at least 75% and if prices are positive I would like it to continue charging, but not surpass the maximum of 100%. The list of prices are the prices for everytime I charge (or decide not to charge) the car.
So here is what I have so far:
maxF = 100
minF = 75
SoC = 55
i = 0
chargeRate = 10
price = [2,-2,3,4]
while SoC < minF:
if price[i] > 0:
SoC += chargeRate
i += 1
# if there is no time left (no prices available), I have to charge in order to reach 75%
elif (minF - SoC)/chargeRate <= (len(price) - i):
SoC += chargeRate
i += 1
else:
i += 1
print(SoC)
In this piece of code the car charges prices 2 and 3, but not 4. I don't know how to include for the car to continue charging, after having passed the 75%.
I am greatful for any suggestions.
Many thanks,
Elena

From my understanding, you should try the following code:
while SoC <= 100:
if (i < len(price)) and (SoC < 75 or price[i] > 0):
SoC += chargeRate
else:
break
i+=1
print(SoC)
This should work for you. I'm not sure what you are trying to do with the line
elif (minF - SoC)/chargeRate <= (len(price) - i):

Related

index element creates not needed input

I want to make a code that would propose a customer one or more of products to add to his shop list if he has total cart less than available budget (for example, he bought products for 120 dollars, and program should ask him if he want to add one or a couple of products (for example for 20 and 30 dollars) in list so budget gets close to 150 dollars limit)
My problem here is that somehow i += 1 creates an unwanted input() process which i cannot explain
I am a newbie in Python so maybe someone can propose the solving of problem or even better version of my code, i'll be greatful for every help!
https://ibb.co/vJwhMw0 link for image here
inp = 'bar'
product_list = ['bar', 'bread', 'milk', 'coconut']
product_price = [10, 24, 30, 25]
indx = product_list.index(inp)
price = product_price[indx]
budget = 150
total = 120
proposal_list = ''
i = 0
while total < budget:
if (product_price[i] + total) <= budget:
total += product_price[i]
proposal_list += product_list[i]
i = i + 1
print (f'You can also add: {proposal_list}')
There is some problems with your code. No unwanted input() is created it's just that your while loop is infinite because i never changes because the condition is never true at some point.
while total < budget:
if i >= len(product_price):
break
elif (product_price[i] + total) <= budget:
total += product_price[i]
proposal_list += product_list[i]
i += 1
You code got inside infinite loop right after this line:
while total < budget:
Once the code inside this line is executed
if (product_price[i] + total) <= budget:
total become equal 130. Condition total < budget is still true but condition
if (product_price[i] + total) <= budget:
is not.
You need to exit the while loop. You can't do it until you update total.

python only activating first elif, ignoring others

# user input
num = int(input("Please enter engine size: "))
# calculations
if num <= 1000:
print("The motor tax for your vehicle is €150")
elif num >= 1001 <= 1200:
print("The motor tax for your vehicle is €175")
elif num >= 1201 <= 1400:
print("The motor tax for your vehicle is €200")
elif num >= 1401 <= 1600:
print("The motor tax for your vehicle is €250")
elif num >= 1601 <= 1800:
print("The motor tax for your vehicle is €300")
elif num >= 1801 <= 2000:
print("The motor tax for your vehicle is €350")
else:
print("The motor tax for your vehicle is €500")
I know I've probably made a stupid mistake here, I'm just hoping someone could point me in the right direction.
I'm trying to get python to print the relevant amount for each of the specified engine size.
Each time I run it with any amount greater than 1000 it will only give me the output of €175.
Thanks so much in advance!
This isn't doing what you want or expect it to be doing:
elif num >= 1001 <= 1200:
You should replace it with something like:
elif num in range(1001, 1201):
NOTE: to check <=, you need to have upper bound of range incremented by 1!
Otherwise, you could write what you originally had as:
elif 1001 <= num <= 1200:
Welcome to Stack Overflow!
i have updated the answer to PL200 to provide an answer to your question. This is a suggestion to improve a bit your code:
# Motor tax is based on ranges
if num <= 1000:
tax = 150
elif num <= 1200:
tax = 175
elif num <= 1400:
tax = 200
elif num <= 1600:
tax = 250
elif num <= 1800:
tax = 300
elif num <= 2000:
tax = 350
else:
tax = 500
print("The motor tax for your vehicle is €{}".format(tax))
You actually don't need 2 inequations because of the if / elif chain.
Or you could do even better to avoid a long if/elif:
def get_tax(num):
"""Return the vehicle tax based on ranges"""
# Ranges are stored as "maximum size" / "tax"
tax_ranges = (
(1000, 150),
(1200, 175),
(1400, 200),
(1600, 250),
(1800, 300),
(2000, 350),
)
default_tax = 500
for max_size, tax in tax_ranges:
if num <= max_size:
return tax
return default_tax
num = int(input("Please enter engine size: "))
print(f"The motor tax for your vehicle is {get_tax(num)}")
NOTE: I added a f-string at the end to print but it might not supported by your version of Python if you have a version earlier than 3.6. In that case, just replace {get_tax(num)} by "... {}".format(get_tax(num)) and remove the f before the string

Python bisection search not running and no error message. MIT edX

The problem is from the MIT edX Python Course 6.00.1 Problem Set 1 Part C. Here are the problems. Scroll to part C. I'm aware that there are countless questions asked about the edX course but none of them have really helped me. Whenever I run my bisection search code, nothing happens. No error message, nothing. Could someone help me find the issue in my code? Sorry if code is horribly inefficient, very new to python and programming.
#Python script for finding optimal saving rate of monthly salary in order to purchase 1M house in 36 months
salary = float(input("Enter salary: "))
total_cost = 1000000
salary_raise = 0.07 #semiannual raise rate
down = 0.25 * total_cost #downpayment
steps = 0
r = 0.04 #annual investments returns
low = 0 #low parameter for bisection search
high = 10000 #high parameter
current_savings = 0
while (current_savings <= (down - 100)) or (current_savings >= (down + 100)):
current_savings = 0
monthly_salary = salary/12
guess_raw = (high + low)/2
guess = guess_raw/10000.0
months = 0
steps += 1
while months < 36: #Finds end amount of money after 36 months based on guess
months += 1
multiple = months%6
monthly_savings = monthly_salary * guess
current_savings = current_savings + monthly_savings + current_savings*r/12
if multiple == 0:
monthly_salary += salary_raise * monthly_salary
if (current_savings >= (down - 100)) and (current_savings <= (down + 100)): #If the guess is close enough, print the rate and number of steps taken
print ("Best savings rate: ",guess)
print ("Steps in bisection search: ",steps)
break
elif current_savings < (down - 100): #If the guess is low, set the low bound to the guess
if guess == 9999:
print ("It is not possible to pay the down payment in three years.")
break
else:
low = guess
elif current_savings > (down + 100): #If the guess is high, set the high bound to the guess
high = guess

Distributing points for lottery.py

I'm trying to figure out how to get my bot to distrubute points from a pot from the lottery game when it ends each time. So each game starts out at 1 point but everytime someone buys a ticket it goes up by a random amount. At the end of fifteen minutes it's supposed to retrieve the players and the pot and based off of where you're ranked in the list your points are determined. So basically if you're first in the list you win over the pot value. And when the ranking goes down your points that you win go down and if your near or at last place you lose points. The sum of all the points that the players earn does not have to equal 0 after they are distrubuted.
For example: Tim got 1st in the lottery. He should get 5676*1.66. Also, all the points you receive from the pot should be different based on your rank in the lottery. But if you're at the end of the list in the lottery you should lose points.
This is what I have so far:
lotteryStart = time.time()
players = []
pot = 1
def buyLottery(name):
if name not in players:
amount = int("30")
if Point.getCost(name, amount) == True:
multiplier = random.randint(217, 453)
pot = int(multiplier+pot)
different = float(time.time() - lotteryStart)
years = int(different / Point.YEAR)
days = int((different % Point.YEAR) / Point.DAY)
hours = int((different % Point.DAY) / Point.HOUR)
mins = int((different % Point.HOUR) / Point.MINUTE)
secs = int(different % Point.MINUTE)
if secs <= 0:
if len(players) > 0:
random.shuffle(players)
for i in range(1,len(players)):
if i == 1:
pot2 = int(pot*1.66)
elif i == 2:
pot2 = int(pot*1.33)
elif i == 3:
pot2 = int(pot)
elif i == 4:
pot = int(pot/1.66) #And so on but i dont want to keep doing elif
I do not understand your lottery; I can't imagine a lottery where you buy a ticket for a random amount and could lose money on top of the ticket price being very popular in real life!
That being said, I think you want to do something like this:
ratios = []
for i in range(-2, len(players) - 2):
if i < 0:
ratios.append(1 - (i * 0.33)) # ratio > 1
else:
ratios.append(1 / (1 + (i * 0.33))) # ratio <= 1
winnings = [pot * r for r in ratios]
You can then easily match players[i] with their winnings[i]. Note that I have assumed that you missed out pot / 1.33 accidentally; otherwise, you will have to adjust this slightly.
For 10 players, I get:
ratios == [1.6600000000000001, 1.33, 1.0, 0.7518796992481203,
0.6024096385542168, 0.5025125628140703, 0.43103448275862066,
0.3773584905660377, 0.33557046979865773, 0.3021148036253776]

Probability Dice Game in Python with two dices

I want to interate 1000 times over the following function to find out if you win or loose money in this game.
The game is designed as such that you throw a pair of dice and get money back or loose money. Let's say we start with 5 coins.
Throwing a 12 yields 1.5 coins.
Throwing an 11 yields 1 coins.
Throwing a 10 yields 0.5 coins.
Throwing a 9,8 or 7 yields nothing.
Throwing a 6,5,4,3,2 or 1 deducts 0.5 coins from your amount of coins.
This is what my implementation looks like so far:
def luckCalc():
amount = 5
# if 12 then 1/36 chance
if random.randrange(1,7) == 6 and random.randrange(1,7) == 6:
amount = amount + 1.5
# if 11 then 2/36 chance
elif (random.randrange(1,7) == 5 and random.randrange(1,7) == 6) or (random.randrange(1,7) == 6 and random.randrange(1,7) == 5):
amount = amount + 1
# if 10 then 3/36 chance
elif (random.randrange(1,7) == 5 and random.randrange(1,7) == 5) or (random.randrange(1,7) == 4 and random.randrange(1,7) == 6) or (random.randrange(1,7) == 6 and random.randrange(1,7) == 4):
amount = amount + 0.5
# if 9,8,7
# 4/36 + 5/36 + 6/36 chance
# 1+6, 2+5, 3+4, 4+3, 5+2, 6+1 chance
# 2+6, 3+5, 4+4, 5+3, 6+2 chance
# 3+6, 4+5, 5+4, 6+3 chance
# then no change in amount
# if 6,5,4,3,2,1
# chances...
# then amount -0.5
return amount
# Iterate over the dice throwing simulator and calculate total
total = 0.0
for a in range(1000):
total = total + luckCalc()
print (total)
I stopped coding towards the end of the function, because I recognised that there must be a more elegant solution on how to achieve this. Any interesting suggestions, what is this Monte Carlo I keep hearing about?
Each time you call random.randrange(1,7), you generate a new random number. Since you're testing a single "turn", roll twice:
def roll_die():
return random.randrange(1, 7)
total = roll_die() + roll_die()
And see if the sum is in a range:
def play_turn():
total = roll_die() + roll_die()
if total == 12:
return 1.5
elif total == 11:
return 1.0
elif total == 10:
return 0.5
elif total <= 6:
return -0.5
else: # total is 7, 8, or 9
return 0
Here's the result of 100,000 rounds:
>>> from collections import Counter
>>> counts = Counter(play_turn() for i in xrange(100000))
>>> counts
Counter({-0.5: 41823, 0: 41545, 0.5: 8361, 1.0: 5521, 1.5: 2750})
>>> probabilities = {score: count / 100000.0 for score, count in counts.items()}
>>> probabilities
{-0.5: 0.41823, 0: 0.41545, 0.5: 0.08361, 1.0: 0.05521, 1.5: 0.0275}
You can actually roll (ha!) everything you are doing into a single function:
from random import randrange
def play_game(rolls=1000, amount=5, n=6):
"""Play game 'rolls' times, starting with 'amount' on 'n'-sided dice."""
for i in range(rolls):
roll = randrange(1, n+1) + randrange(1, n+1)
if roll == 12:
amount += 1.5
elif roll == 11:
amount += 1
elif roll == 10:
amount += 0.5
elif roll < 7:
amount -= 0.5
return amount
I notice a few things in your code. First, for the 6-1 cases you're not actually subtracting 0.5 from the amount. Second, since you don't pass in the initial amount each loop you're adding between 5 and 6.5 to your total, which makes the total pretty pointless.
A more effective total would be to pass in the amount each time:
def luckCalc( amount ):
And then for your loop:
total = 5.0
for a in range(1000):
total = luckCalc(total)
Blender's answer, which just posted as I was writing this, is a great way to simplify your main function.
I personally like setting up my results table as an array (or a dictionary, but this suited my purpose better since every result was one of a small number of possible integers), with the index of each dice roll set to the value of the resulting change. See below.
import random
def luckCalc(coins=5):
diceroll = random.randint(1,6)+random.randint(1,6) #roll them bones
#here's that table I was talking about....
results_table = ['index 0 is blank',"you can't roll a one on two dice",-.5,-.5,-.5,-.5,-.5,0,0,0,.5,1,1.5]
coins += results_table[diceroll] #changes your coins value based on your roll (as an index of results_table)
if results_table[diceroll] > 0: #change the string if your result was + or -
result = "gained {}".format(results_table[diceroll])
else:
result = "lost {}".format(results_table[diceroll]*-1)
print("You {} coins, putting you at {}".format(result,coins)) #report back to the user
return coins #this is how you save your output
#CONSTANTS GO HERE -- YOU CAN CHANGE THESE TO CHANGE YOUR PROGRAM
STARTING_COINS = 5
HOW_MANY_ITERATIONS = 1000
#this way we don't modify a constant
coins = STARTING_COINS
#do it how many times?
for _ in range(HOW_MANY_ITERATIONS): #oh yeah that many times
coins = luckCalc(coins) #runs the function and saves the result back to coins
#report to the user your final result.
print("After {} rolls, your final total is {}".format(HOW_MANY_ITERATIONS,coins))

Categories