Using Range Function - python

My goal is to make a program that takes an input (Battery_Capacity) and ultimately spits out a list of the (New_Battery_Capacity) and the Number of (Cycle) it takes for it ultimately to reach maximum capacity of 80.
Cycle = range (160)
Charger_Rate = 0.5 * Cycle
Battery_Capacity = float(raw_input("Enter Current Capacity:"))
New_Battery_Capacity = Battery_Capacity + Charger_Rate
if Battery_Capacity < 0:
print 'Battery Reading Malfunction (Negative Reading)'
elif Battery_Capacity > 80:
print 'Battery Reading Malfunction (Overcharged)'
elif float(Battery_Capacity) % 0.5 !=0:
print 'Battery Malfunction (Charges Only 0.5 Interval)'
while Battery_Capacity >= 0 and Battery_Capacity < 80:
print New_Battery_Capacity
I was wondering why my Cycle = range(160) isn't working in my program?

Your first problem is that you have the first two lines in the wrong order. You need a "Cycle" variable to exist before you can use it.
You'll still get an error when you swap them, though. You can't multiply a list by a float. A list comprehension is more what you want:
Charger_Rate = [i * .5 for i in Cycle]
As far as I can tell, the range(160) part is fine.

Related

Loop code with: {x_(n+1) = x_n * r * (1- x_n)}

Little new here and any help would be appreciated.
I have been tooling around with this code for a while now and I cant seem to wrap my head around it. Im fairly new to python so I dont quite know or remember all the tricks yet/skills.
So the question at hand:
Equation: {x_(n+1) = x_n * r * (1- x_n)}
With x_n between (0,1) and r between (0,4).
The goal here is to make a loop function that will gather a value for 'x_n' and 'r' and spit out the iteration 'n' and the current 'x_n+1'; i.e. print(n , x_n+1), at each 'n' step while checking to see if the new value is within 0.0000001 of the old value.
If it settles on a fixed point within 20,000 (0.0000001), print the final 'n' + message. If not then and goes to 20,000 then print another message.
All i have so far is:
import math
x_o=float(input("Enter a 'seed' value: "))
r=float(input("Enter an 'r' value: "))
x_a=((x_o + 0) * r * (1-(x_o + 0)))
while x_a != (0.0000001, x_o , 0.0000001):
for n in range(0,99):
x_a=((x_o + n) * r * (1-(x_o + n)))
print(n , x_a)
I'm pretty sure this is no where close so any help would be awesome; if you need any more info let me know.
Much appreciated,
Genosphere
You could write a generator function and use it directly in your for loop. If you need to keep track of the rank of intermediate values you can use enumerate on the generator.
def fnIter(fn,x,delta=0.000001):
while True:
yield x
prev,x = x,fn(x)
if abs(x-prev)<delta:break
output:
r = 2
seed = 0.1
for i,Xn in enumerate(fnIter(lambda x:x*r*(1-x),seed)):
print(i,Xn)
0 0.1
1 0.18000000000000002
2 0.2952
3 0.41611392
4 0.4859262511644672
5 0.49960385918742867
6 0.49999968614491325
7 0.49999999999980305
To implement the maximum iteration check you can either add a conditional break in the loop or use zip with a range:
maxCount = 20000
n,Xn = max(zip(range(maxCount+1),fnIter(lambda x:x*r*(1-x),seed)))
if n < maxCount:
print(n,Xn)
else:
print(Xn,"not converging")
This is an exponentially-weighted moving average. Pandas has a function for this: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.ewm.html
You have a good start so far. You might be overthinking it, though.
The following approach just tries to generate this sequence for 20,000 terms. Each time, it checks whether the new value is within 0.0000001 from the previous value. If so, it breaks out of the loop and prints that. If not, it uses python's for/else construct to print a different value. Note the different levels of indentation.
x_0 = float(input("enter a 'seed' value: "))
r = float(input("enter an 'r' value: "))
x_m = x_0 # placeholder for 'previous value'
delta = 0.0000001
# Try to calculate 20 thousand terms of this sequence
# We will break out of the loop early if our x_n converges
for _ in range(20000):
x_n = x_m * r * (1 - x_m)
if abs(x_n - x_m) < delta:
print("Settled on value for x_n: ", x_n)
break
else:
x_m = x_n # move forward to the next value
else:
print("x_n did not converge in 20000 terms")

How do I return the middle of a python array?

Here is the prompt:
On the first line display the first, last and middle element of the list separated by the , character.
I have been trying to get this figured out for a few hours now, but do not know the correct process to return the middle of the array. Here is my code so far:
primary = []
length = 0
i = ("MORE")
while i != "NOMORE":
i = str(input("?"))
print(i)
if i == "NOMORE":
break
primary.append(i)
length = length + 1
mid = (length/2)
print(primary[0]," , ", primary[-1]," , ",primary.pop([mid]))
The code works to get the correct inputs from the program, but as the lists will be variable lengths I assume some form of a loop will be used. The primary.pop([mid]) was my poor attempt at getting the median printed. I know that the mid will not be printed as it is the wrong variable type, but how would I replace this?
Any help is appreciated.
You're unnecessarily calling the pop() method on primary with [mid] when you should simply be indexing primary with mid. You should also use the // operator instead of / to obtain an integer value for the index. Since the index is 0-based, the mid point should be (length - 1) // 2 instead:
primary = []
length = 0
i = ("MORE")
while i != "NOMORE":
i = str(input("?"))
print(i)
if i == "NOMORE":
break
primary.append(i)
length = length + 1
mid = (length - 1) // 2
print(primary[0]," , ", primary[-1]," , ",primary[mid])

Optimized way to find in which range does a number lie

I have multiple ranges lets say 1-1000, 1000-2000, 2000-3000, 3000-4000, 4000-5000. I get a number from the user and now i need to find in which range it lies. One way to do this would be to create multiple if statement and check from there like so:
if num>=1 and num < 1000:
print "1"
elif num >=1000 and num < 2000:
print "2"
....
This method would create a lot of branches.
Is there an optimized way to do this without so many branches and in the least complexity?
PS: I just wrote the code in python since its shorter to write but this can be case in any language. Also the range and output can be very different.
The range and output are examples and can be anything like 1-100, 100-1000, 1000-1500 etc and output like "Very Low, low, medium" something like that.
Store the starting or ending of the range in the list and sort it along with number to find its exact range.
import numpy as np
start = [1,1000,2000,3000,4000]
print(list(np.sort(start+[num])).index(num))
If your ranges don't follow any particular logic, there's not much you can do except testing them one by one, but you can still simplify the code by using a loop:
ranges = [[0,1000],[1500,1600],[1200,1220]]
def find_range(num, ranges)
for low, high in ranges:
if low <= num < high:
return low, high # or any other formating using a dict for example
Of course you can optimize a bit by sorting your ranges and then doing a binary search instead of linear...
my_range=(1,1000), (1000,2000), (2000,3000), (3000,4000), (4000,5000)
my_output='Very Low, Low, Medium, High, Very High'.split(', ')
num=3565
for k,i in enumerate(my_range):
if i[0]<=num<i[1]:print(my_output[k]);break
else:
print('Out of range')
How about something like this:
ranges = {
0: 'undefined range',
1000: '1',
1500: '2',
2500: '3'
}
num = 500
print(ranges[max(ranges, key=lambda x: num < x)])
Output: 1
Suspect that you have many breaks and require an optimized search, you can go with bisection on an ordered list of breakpoints resulting in a logarithmic time consumption:
import random
import time
def split_pivot(intervals, number):
"""Divide and conquer recursively."""
if len(intervals) == 1:
return intervals[0]
if len(intervals) == 2:
if number >= intervals[1][1][0]:
return intervals[1]
elif number < intervals[0][1][1]:
return intervals[0]
else:
raise
pivot = int(len(intervals) // 2.0)
if number < intervals[pivot][1][1]:
return split_pivot(intervals[:pivot + 1], number)
elif number >= intervals[pivot + 1][1][0]:
return split_pivot(intervals[pivot + 1:], number)
else:
raise
if __name__ == '__main__':
UPPER_BOUND = 10000000
newbreak = 0
manybreaks = []
while newbreak < UPPER_BOUND:
step = int(random.random() * 10) + 1
manybreaks.append(newbreak + step)
newbreak = manybreaks[-1]
print('Breaks: {:d}'.format(len(manybreaks)))
intervals = [
(idx, (manybreaks[idx], manybreaks[idx + 1]))
for idx in range(len(manybreaks) - 1)
]
print('Intervals: {:d}'.format(len(intervals)))
print(
' Example: idx {tpl[0]:d}, lower {tpl[1][0]:d}, upper {tpl[1][1]:d}'
.format(tpl=random.choice(intervals)))
thenumber = int(random.random() * UPPER_BOUND)
print('Number: {:d}'.format(thenumber))
t0 = time.time()
result = split_pivot(intervals, thenumber)
t1 = time.time()
print('Result: {e[0]:d} ({e[1][0]:d}, {e[1][1]:d})'.format(e=result))
print(' Done in {:.4f}s'.format(t1 - t0))
The result of the search itself is (on my machine) below 0.05 seconds. The generation of breakpoints and corresponding intervals runs for roughly 4.5 seconds:
Breaks: 1818199
Intervals: 1818198
Example: idx 605849, lower 3330441, upper 3330446
Number: 6951844
Result: 1263944 (6951843, 6951847)
Done in 0.0436s
maybe just divide by 1000 and take the entire part :
here example in python :
>>> x=3608
>>> int(x/1000+1)
4
Following your comment/edit in your post, if you need a different output (a string for example) you can (in python) use a dict :
>>> Output={'1': 'very low', '2': 'low', '3': 'medium','4':'high' }
>>> x=2954
>>> Output[str(int(x/1000+1))]
'medium'

How can I average multiple outputs independently in python

PYTHON 3: Hi, so I have this piece of code
for money in range(0, 2501, 500):
print("{} Euro".format(money), end='')
throws = 0
d = trump.possession(board)
while False in d.values():
prevLoc = piece.location
piece.move(trump.throw())
throws += 1
if piece.location < prevLoc:
money += 200
if board.names[piece.location] in d and d[board.names[piece.location]] == False and money >= board.values[piece.location]:
money -= board.values[piece.location]
d[board.names[piece.location]] = True
return throws
and this code takes 0 money to start with, runs the code, looks for amount of throws required to buy the entire board, does the same with 500 starting money, 1000 and so forth
my question is, how can i take the average of the throws to buy the entire board for each starting value? the way my code is now it returns the amount of throws for all the starting values, but simulated once, so it may not be accurate.
I searched a lot, and tried some things but i had problems with this one because I want to like run it, say for example, 2000 times, and get the average for each starting value for the money.
anyone got any tips for this? been struggling on it for a while..
i tried making a for loop from 0 to 2000 and then inside of that another for loop that prints 0-2500 and then uses the code below in a function, appends the return value of throws into a list and sums it up and devides it by 2000, it did not turn out so good...
I'm going to assume this is in a function, due to the return statement. You need to collect outputs into a list and then average that at the end.
def calc_throws(simulations):
throw_list = []
average = lambda x: sum(x)/len(x)
for i, money in enumerate(range(0, 2501, 500)):
print("{} Euro".format(money), end='')
throw_list.append([money, []])
for _ in range(simulations):
throws = 0
d = trump.possession(board)
while False in d.values():
prevLoc = piece.location
piece.move(trump.throw())
throws += 1
if piece.location < prevLoc:
money += 200
if board.names[piece.location] in d and d[board.names[piece.location]] == False and money >= board.values[piece.location]:
money -= board.values[piece.location]
d[board.names[piece.location]] = True
throw_list[i][1].append(throws)
throw_list[i][1] = average(throw_list[i][1])
return throw_list
Rather than a single number, this returns a list of lists like #[[0,20],[500,15],...[2500,3]] (or whatever reasonable numbers are) which gives you the average for each amount of starting money.

if/elif/else statement help with money

Updated my new code at the bottom of the page as an answer.
So for my CS 170 class, we have to make a program that has user input for less than $10 and change is returned in the least amount of coins, no bills or 50 cent pieces. For the most part the program does well except when you run into a x.x0
e.g.:
Python 2.7.2 (v2.7.2:8527427914a2, Jun 11 2011, 15:22:34)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
Amount due:
7.80
Amount in return
2.20.
Quaters in return 8.
Dimes in return 0.
Nickels in return 4.
>>>
the program completely skips over the dimes section and straight to nickels providing 4 as a solution when the least amount should be 8 quarters, 2 dimes and end. Also I'm not really skilled in loops too much, but I know this would be possible and a lot shorter code, and cleaning up the code advice would be nice as well. Thanks for any help!
# optional.py
# Calculating the least amount of change in return for a $10 bill.
## amount due
due = input("Amount due:\n ")
## if amount is more than 10, exit program
if due > 10.00:
print "Please enter a number lower then 10.00."
exit()
## if amount is less than 0, exit program
if due < 0:
print "Please enter a number greater than 0.00."
exit()
## subtract amount from 10
else:
change = 10.00 - due
print "Amount in return\n %0.2f." % change
## if amount is 0, no change
if change == 0:
print "No change in return."
## passes expression if previous not met
pass
elif change >= .25:
## setting q, dividing change by .25
q = change / .25
## maaking q an integer
quaters = int(q)
print "Quaters in return %r." % quaters
## subtracting quaters from chane
change = change - (quaters *.25)
if change < .10:
pass
elif change >= .10 <= .24:
d = change * .1
dimes = int(d)
print "Dimes in return %r." % dimes
change = change - (dimes * .1)
if change < .05:
pass
elif change >=.05 <=.09:
n = change / .05
nickels = int(n)
print "Nickels in return %r." % nickels
change = change - (nickels * .05)
if change == .01:
pennies = change / .01
print "Pennies in return %r." % pennies
elif change >=.01 <=.04:
p = change / .01
print "Pennies in return %0.0f." % p
There are a few changes you could make to clean up this code, and one of them might fix your problem. First, pass does absolutely nothing. It is usually used as a placeholder for a loop or function that will be filled in later. Also, the conditions of your elif statements are mutually exclusive with the if statements they follow, so
if change == 0:
print "No change in return."
## passes expression if previous not met
pass
elif change >= .25:
## setting q, dividing change by .25
q = change / .25
## maaking q an integer
quaters = int(q)
print "Quaters in return %r." % quaters
## subtracting quaters from chane
change = change - (quaters *.25)
can be rewritten as
if change >= .25:
## setting q, dividing change by .25
q = change / .25
## making q an integer
quaters = int(q)
print "Quaters in return %r." % quaters
## subtracting quaters from change
change = change - (quaters *.25)
for each if/elif statement. Also, in the statement
if change >=.01 <=.04:
you are testing whether
change >= .01 and .01 <= .04
To make it do what you want, the statement should be rewritten as
if .01 <= change <= .04
In addition, you are using floating point numbers, which often lead to rounding errors. To avoid these errors, I would suggest either representing your money as an integer number of cents and multiply all of the numbers in your problem by 100 or use something with fixed point numbers like python's decimal module.
This is not doing what you expect:
elif change >= .10 <= .24:
It looks like you intend something like:
elif change >= .10 and change <= .24:
or Python also supports:
elif .10 <= change <= .24:
However, you will next run into floating point rounding problems of various kinds. I suggest you first convert the input number to an integer number of cents, and perform all your calculations in cents. Avoid floating point numbers when dealing with money.
So I got it worked out in a better format with cleaner print code. Thanks for the help guys!
If anyone wants to know the difference between the 2 codes, it's getting it out of floating point like the others suggested and converting what is needed to integers, multiplying the integers by the specific amount, say a quarter, and then subtracting int * coin/bill from the change. Worked out well. I tried experimenting with a for statement, but that didn't turn out too well since I don't know a lot about it yet either. Until next time...
Again thanks guys!
Here's the finished code for anyone wondering about it:
import sys
due = input("Please enter the amount due on the item(s):\n ")
# if over $10, exit
if due > 10:
print "Please enter an amount lower then 10."
sys.exit(1)
## if under/equal 0, exit
if due <= 0:
print "Please enter an amount greater than 0."
sys.exit(2)
## 10 - due = change, converts change into cents by * by 100 (100 pennies per dollar)
else :
change = 1000 - (due * 100)
## if change is 0, done
if change == 0:
print "No change in return!"
## if not 0 makes change2 for amount in return
else:
change2 = change / 100
print "Amount in return:\n $%.2f." % change2
## if change > 500, subract 500 and you get 1 $5 bill
if 500.0 <= change:
bill_5 = change / 500
b5 = int(bill_5)
change = change - 500
## if change is over 100, change divided by 100 and subtracted from change for quaters
if 100.0 <= change:
dollars = change / 100
dollar = int(dollars)
change = change - (dollar * 100)
if 25 <= change < 100:
quaters = change / 25
quater = int(quaters)
change = change - (quater * 25)
if 10 <= change <= 24:
dimes = change / 10
dime = int(dimes)
change = change - (dime * 10)
if 5 <= change < 10:
nickels = change / 5
nickel = int(nickels)
change = change - (nickel * 5)
if 0 < change < 5:
pennies = change / 1
penny = int(pennies)
change = change - (penny * 1)
print "Change in return:\n $5:%i\n $1:%i\n Quaters:%i\n Dimes:%i\n Nickels:%i\n Pennies:%i " % (
b5, dollar, quater, dime, nickel, penny )
if 0 >= change:
print "Done!"

Categories

Resources