Why is my code getting an infinite loop? - python-2.7

minimunpaymonth = 0
balance = 4773
annualInterestRate = 0.2
def function(minimunpaymonth):
global balance
month = 1
while month <= 12:
balance = balance - minimunpaymonth
anninterest = annualInterestRate/12 * balance
balance = balance + anninterest
month += 1
return balance
while function(minimunpaymonth) >= 0:
minimunpaymonth += 10
print "Lowest Payment: " + str(minimunpaymonth)
the second while loop is infinite and i dont know why. the first is ok because i have ran it
when the loop increases minimunpaymonth, value of balance goes down, so there will be a moment when balance is negative
def function(minimunpaymonth, balance, annualInterestRate):
month = 1
while month <= 12:
balance = balance - minimunpaymonth
anninterest = annualInterestRate/12 * balance
balance = balance + anninterest
month += 1
return balance
while function(minimunpaymonth, balance, annualInterestRate) >= 0:
minimunpaymonth += 10
print "Lowest Payment: " + str(minimunpaymonth)
ok i just solved it. i change the function to give 3 arguments instead of 1

your second loop is checking to see if minimunpaymonth is >= 0, if it is then it performs the loop again.
Your minimunpaymonth will always be >=0 because it starts at 0 & is only ever added to. There is no subtraction from this value.

the second loop keeps adding to minimum payment, it will always be >= 0 till it reaches the numeric limit of the variable; however as the comment pointed out, the "function" could get less, but perhaps the interest rate always keeps the balance above zero and the minimum payments don't get it there -- plausible enough in real life!

Related

Cant display the numbers lost over 100

So in my little game, there is a happiness mechanic, I want it to be capped at 100, and show the player how much happiness they lost due to the overflow, but it keeps showing 100. (I created the integer happiness at the very start), its in a switch statement, all other parts of the switch work well.
case 5:
if (happiness <= 100) {
happiness = happiness + 20;
cout<< "The festival goes well";
if (happiness > 100) {
int lost_happiness = happiness - (happiness%100);
happiness = happiness - (happiness%100);
cout << ", however, happiness has reached the cap of 100. The amount lost is " << lost_happiness;
}
}
break;
Any ideas why?
From what I understand case 5 is always showing 100 and it should . Just think let initial happiness be 95 , you add 20 it becomes 115 .then you are subtracting 115%100 I.e. 15 from it , so the answer will become 100 in every case .
You are using the same formula to calculate both the lost_happiness and new happiness values:
int lost_happiness = happiness - (happiness%100); // Notice the similarity
happiness = happiness - (happiness%100); // in the two RHS codes?
This is incorrect, and the former should just be happiness % 100.
if (happiness <= 100) {
happiness += 20;
cout<< "The festival goes well";
if (happiness > 100) {
int lost_happiness = happiness % 100; // DON'T subtract this from total
happiness -= lost_happiness; // No need to recalculate the "%"
cout << ", however, happiness has reached the cap of 100. The amount lost is " << lost_happiness;
}
}
Note that I have also used some techniques to make your code rather more succinct; please feel free to ask for further details and/or clarification.

Transforming a logic constraint into python pulp code

I started working on a problem in the past several days...
A company plans its business in a three month period. It can produce
110 units at a cost of 600 each. The minimum amount it must produce
per month is 15 units if active (but of course, it can choose to be closed
during the month, and produce 0 units). Each month it can subcotract the
prodution of 60 units, at a cost of 660 each. Storing a unit for one month
costs 20$ per unit per month. The marketing department has forcasted
sales of 100, 130 and 150 units for the next three months, respectively.
The goal is to meet the demand each month while minimizing the total
cost.
I deduced that we need to have an objective function of form min[Sum(i=0..3) 600*x1+660*x2+20*x3].
We need to add some constrains on x1>=15, and on x2 0<=x2<=60
Also we will also need another constraint for each month...
For the first one i=1 => x1+x2 = 100 - x3last (x3last is an extra variable that should hold the amount existing in deposit from the previous month), and for i=2 and i=3 same constraints.
I don't have any idea how to write this in pulp, and i would appreciate some help. Thx ^_^
I'd tend to agree with #Erwin that you should focus on formulating the problem as a Linear Program. It is then easy to translate this into code in PULP or one of many other PULP libraries/tools/languages.
As an example of this - lets work through this process for the example problem you have written out in your question.
Decision Variables
The first thing to decide is what you can/should decide. This set of information is called the decision variables. Picking the best/easiest decision variables for your problem comes with practice - the important thing is that once you know the values of the variables you have a unique solution to the problem.
Here I would suggest the following. These assume that the forecasts for demand are perfect. For each month i:
Whether the production line should be open - o[i]
How much to produce in that month - p[i]
How much to hold in storage for next month - s[i]
How much to get made externally - e[i]
Objective Function
The objective in your case is obvious - minimise the total cost. So we can just write this down: sum(i=0...2)[p[i]*600 + s[i]*20 + e[i]*660]
Constraints
Let's lift these directly our of your problem description:
"It can produce 110 units at a cost of 600 each. The minimum amount it must produce per month is 15 units if active (but of course, it can choose to be closed during the month, and produce 0 units)."
p[i] >= o[i]*15
p[i] <= o[i]*110
The first constraint forces the minimum production about to be 15 if the production is open that month (o[i] == 1), if the production is not open this constraint has not effect. The second constraint sets a maximum value on p[i] of 110 if the production is open and a maximum production of 0 if the production is closed that month (o[i] == 0).
"Each month it can subcotract the prodution of 60 units, at a cost of 660 each"
e[i] <= 60
"The marketing department has forcasted sales of 100, 130 and 150 units for the next three months, respectively. The goal is to meet the demand each month while minimizing the total cost." If we declare the sales in each mongth to be sales[i], we can define our "flow constraint" as:
p[i] + e[i] + s[i-1] == s[i] + sales[i]
The way to think of this constraint is inputs on the left, and outputs on the right. Inputs of units are production, external production, and stuff taken out of storage from last month. Outputs are units left/put in storage for next month and sales.
Finally in code:
from pulp import *
all_i = [1,2,3]
all_i_with_0 = [0,1,2,3]
sales = {1:100, 2:130, 3:150}
o = LpVariable.dicts('open', all_i, cat='Binary')
p =LpVariable.dicts('production', all_i, cat='Linear')
s =LpVariable.dicts('stored', all_i_with_0, lowBound=0, cat='Linear')
e =LpVariable.dicts('external', all_i, lowBound=0, cat='Linear')
prob = LpProblem("MinCost", LpMinimize)
prob += lpSum([p[i]*600 + s[i]*20 + e[i]*660 for i in all_i]) # Objective
for i in all_i:
prob += p[i] >= o[i]*15
prob += p[i] <= o[i]*110
prob += e[i] <= 60
prob += p[i] + e[i] + s[i-1] == sales[i] + s[i]
prob += s[0] == 0 # No stock inherited from previous monts
prob.solve()
# The status of the solution
print ("Status:", LpStatus [prob.status])
# Dislay the optimums of each var
for v in prob.variables ():
print (v.name, "=", v.varValue)
# Objective fcn
print ("Obj. Fcn: ", value(prob.objective))
Which returns:
Status: Optimal
external_1 = 0.0
external_2 = 10.0
external_3 = 40.0
open_1 = 1.0
open_2 = 1.0
open_3 = 1.0
production_1 = 110.0
production_2 = 110.0
production_3 = 110.0
stored_0 = 0.0
stored_1 = 10.0
stored_2 = 0.0
stored_3 = 0.0
Obj. Fcn: 231200.0

Invalid Syntax attempting to write Python closure

I am attempting to write a function (in Python 2.7) which takes an outstanding balance and annual interest rate then returns the min monthly payment to the nearest cent using bisection search to solve problem #3. I am trying to follow DRY principles by writing a function inside the main function which should return a list with the balance after a year and the number of months (the loop should break if balance hits zero or less) which will need to be calculated twice in my main function. As I try to test this initial closure before moving on I am getting a syntax error on the line assigning monthlyPayment. What am I doing wrong?
# Problem Set 1("C")
# Time Spent: xx hours
def payInOne_BisectionSearch (balance,annualRate):
#initialize variables
initialBalance = balance
monthlyRate = annualRate/12
minMonthly = balance/12
maxMonthly = (balance * (1 + monthlyRate ** 12 )/12
monthlyPayment = (minMonthly + maxMonthly)/2
numMonths = 1
#define function to check balance after 12 months
def balanceAfterYear (balance, monthlyRate, monthlyPayment):
for numMonths in range (1,13):
interest = balance * monthlyRate
balance += interest - monthlyPayment
if balance <= 0:
break
return [balance, numMonths]
resultList = balanceAfterYear(initialBalance, monthlyRate, monthlyPayment)
print resultList[0],resultList[1]
payInOne_BisectionSearch (input("Enter the outstanding balance"),input("Enter annual rate as a decimal"))
You forgot a closing bracket in the previous line.
maxMonthly = (balance * (1 + monthlyRate ** 12 )/12

counters updated according to two different conditions within a loop

I am trying to make a call billing program in c++. One of the features of this small program is the ability to update discount minutes spoken within discount hours and normal-priced minutes during business hours, depending on which time stretch is entered.
The user first enters the time as a string like this 22:00
Then I have a function which takes the string and turns it into an integer. For example the 22:00 above is turned into 2200
I have then another help function that takes an int, the int above and turns it to the decimal time.
double turnTimeToDecimal(int timeRaw){
double decimalTime;
decimalTime = timeRaw * 0.01;
return decimalTime;
}
The business hours which bear no discount and are between 8.00 am and 18.30am in order to deal with this feature I update two counters inside a for loop that goes from 0 to 1417minutes (24hrs):
double myStartDecimal = 0.0;
double myStopDecimal = 0.0;
myStartDecimal = turnTimeToDecimal(myStartRaw);
myStopDecimal = turnTimeToDecimal(myStopRaw);
//hours and minutes start
int hourStart = (int)floor(myStartDecimal);
int minuteStart = (int)round(100*(myStartDecimal - hourStart));
//hours and minutes stop
int hourStop = (int)floor(myStopDecimal);
int minuteStop = (int) round(100*(myStopDecimal - hourStop));
int totalMinutesPremium = 0;
int totalMinutesDiscount = 0;
int i = 0;
int k = 0;
for(k = (hourStart* 60) + minuteStart; k < (hourStop * 60) + minuteStop + round(((double)minuteStop/100)); k++){
//will update the corresponding counter depending
//on the time stretch, business hours 8.00 - 18.30.
if(hourStart >= 8 && hourStop < 18.5){
totalMinutesPremium++;
}else{
totalMinutesDiscount++;
}
}
//will give total minutes
cout << " k is: " << k << endl;
//will give the total number of minutes during the business hours and
//the total number of minutes during the discount hours(non-bussiness hours)
cout << "Total minutes premium " << round(totalMinutesPremium) <<
" Total Minutes discount " << round(totalMinutesDiscount) << endl;
However, the program does detects whether the time stretch entered is within business hours or not, except in one case. If the time for example lies between 7:30 and 8:30 (business hours between 7:59-18:30) it does not return the combination of minutes within the business hours which I would expect to be 30 min and minutes within the discount hours which I would expect to be 30 minutes as well, since the discount stretch ends at 07:59 and it starts again at 18:31.
Hopefully I made myself clear.
Inside the for loop, you allocate the given minute depending on hourStart and hourStop, not on whether the given minute is during business hours. If the call encroaches on discount hours, then the whole call will be discounted.
"However HourStop is an int. same thing goes for hourStart"
Then it's not going to work, if can't use decimal values with ints like you do here:
hourStop < 18.5
well.. you can but it's not going to work the way you want it to. If you have int hourStop = 18.5 then it's going to get truncated to 18 since it can't be a fractional number. You need to use a different type, such as double
Also, the condition in your loop depends on hourStart and hourStop which are never changing in the loop:
if(hourStart >= 8 && hourStop < 18.5){
So you'll always hit the same if condition (which ever it is)
Why use a loop? Why not just do the math?
While not the complete code answer... you can fill in the blanks...
if( startTime >= startOfPremiumPeriod && endTime <= endOfPremiumPeriod )
totalMinutesPremimum = endTime - startTime;
else if( startTime < startOfPremiumPeriod && endTime < startOfPremimumPeriod )
totalMinutesDiscount = endTime - startTime;
.... etc. etc. etc.
You can take into account the case where the start time is before midnight and the end time after midnight by adding 24 hours to the end time...
if( endTime < startTime ) endTime += 1440;

while loop, computing averages

Hello I am fairly new to python and would like to know where my program is failing and why.. thanks, the basic coding is as follows,
grade = 0
total = 0
scorecount = 0
while grade >=0:
grade = raw_input("enter grade ->")
grade = int(grade)
total = total + grade
total = int(total)
scorecount = scorecount + 1
scorecount= int(scorecount)
average = total/scorecount
print average
You accept the grade, then add it to the average even if it is -1, since you don't check for -1 until the loop starts again.
To quit a loop halfway through, use break. Then, you can write
while True: # loop 'forever' until break
grade = raw_input("enter grade ->")
grade = int(grade)
if grade == -1:
break # we're done
# rest of processing...
Your checking for -1 AFTER you change it, so you should check that the raw grade is that and break from the loop before processing.
It'd be smarter to use a list to manage something like this.
grades = []
while True:
grade = int(raw_input('Enter a grade: '))
if grade < 0:
break
grades.append(grade)
print '\nAverage:', float(sum(grades)) / len(grades)
There are better ways to have the user break the loop than entering a negative grade, but there you go.