Monthly and Annual Compound Interest in SAS using DO Loop - sas

I am studying SAS on my own. I have no one to refer to so I just wanted to check if my code is correct.
In a fixed term deposit of 25 years calculate the total amount at the end of
term with initial amount of $5,00,000 and annual interest rate of 7 % */
1) Compounded Annually
2) Compounded Monthly.Show the amount at monthly level
My Code:
data deposit;
amount = 500000;
rate = 0.07;
do year = 1 to 25;
amount + earned;
earned + (amount*0.07);
principal = amount + earned;
output;
end;
run;
For the second question compounded monthly
data deposit1;
rate = 0.006;
amount1 = 500000;
do year = 1 to 25;
do month = 1 to 12;
earned1 + (earned1 + amount1)*0.006;
amount1 + earned1;
output;
end;
end;
run;
Pasting the Screenshots of Solution 1 and Solution 2
I am confused because when I compound annually and monthly both have different results at the end of a particular year.
Please suggest if anything is wrong in my code. Thank you for your time and attention.

It looks like you are double-counting your earned1 variable in the monthly compounding code.
earned1 + (earned1 + amount1)*0.006;
amount1 + earned1;
Should be:
earned1 = amount1*0.07**(1/12);
amount1 + earned1;
Note also you will not want to round the interest rate.

Related

Adjusting hour to account for time difference

I have an edit check
"If Period = 1,2,3 or 4 and Study Hour = 1 then the Time should be 1 hour plus or minus 15 minutes post-dose of study drug from the same period".These are to be programmed with a +/- 20-minute window of Study Hour 1.00 (relative to their dosing time) It is the protocol window, so even if the event was scheduled not exactly at the 1 hour, we are looking for the deviation window from the 1 hour not the time point of the event. Here is the merged data
This is my code. I'm getting a lot of flags here so what am I doing wrong?. For context, there is a prothour variable that is 1 but the actual hour time point is 0.77. Should I adjust the 0.77 somehow to account for this?
data medfst;
set dm.ex;
ptno=strip(compress(clientid,'-'))+0;
if ex_stdat=. or ex_sttim=. then delete;
medday= day;
rename hour=medhour;
proc sort;
by ptno period day medhour;
run;
data medfst;
set medfst;
by ptno period;
if first.period;
ex_datetime1=put(ex_stdat,date9.-r)||' '||put(ex_sttim,time8.-l);
ex_datetime=input(ex_datetime1,datetime20.);
keep scrid clientid ptno period ex_datetime ex_stdat ex_sttim medhour day;
format ex_datetime datetime20.;
proc sort;
by ptno period day medhour;
run;
data vs;
set dm.vs;
ptno=strip(compress(clientid,'-'))+0;
if VS_TEST in ('SYSTOLIC');
if prothour in ('1');
proc sort nodupkey;
by ptno period day hour;
run;
data vs1;
set vs;
vs_datetime1=put(vs_dat,date9.-r)||' '||put(vs_tim,time8.-l);
vs_datetime=input(vs_datetime1,datetime20.);
keep scrid clientid day hour ptno period vs_dat vs_tim vs_datetime vs_com;
format vs_datetime datetime20.;
proc sort;
by ptno period day;
run;
data temp;
merge medfst (in=a) vs1;
by ptno period;
if a;
run;
data final_temp;
set temp;
newhour=hour-medhour;
datediff=vs_dat-ex_stdat;
timediff=vs_tim-ex_sttim;
diff=datediff*24*3600+timediff;
newdiff=round(diff-newhour*(60*60));
format diff time8. newdiff time8. timediff time8.;
run;
data final;
set final_temp;
%inc_subjs;
***** *****;
*********************************************************************************************************;
attrib extra reason length=$5000.;
*********************************************************************************************************;
* Edit check code and footnote *;
***** *****;
if abs(diff) lt '00:45:00't or abs(diff) gt '01:15:00't then do;
reason=trim(reason)||'If Period = 1,2,3 or 4 and Study Hour = 1 then the Time should be 1 hour plus or minus 15 minutes post dose of study drug from the same period#';
extra = trim(extra)||', Hour based on Dose = '||trim(left(medhour))||', Vital Signs hour = '||trim(left(prothour))||', Time deviated = '||trim(put(diff,time8.))||', comment = '||trim(left(vs_com));
end;
You can round to a nearest multiple using the second argument of ROUND function.
ROUND(argument <, rounding-unit>)
Required Argument
argument
is a numeric constant, variable, or expression to be rounded.
Optional Argument
rounding-unit
is a positive, numeric constant, variable, or expression that specifies the rounding unit.
Round a time value to the nearest hour (time is seconds, hour is 3600 seconds)
closest_hour = ROUND(mytime, 3600);
Round hour (number) to nearest hour (time value)
closest_hour = ROUND(myhour*3600, 3600);
and of course, round hour (number) to nearest whole hour (number)
closest_hr = ROUND(myhour); * default rounding unit is 1;

Why does using do until give me only one observation in SAS?

Hello I am trying to solve a problem using iteration with do until but I don't get any results. Also I am learning SAS at the moment on my own using books, documentation and videos so I am new to this language. My problem is :
A car delivers a mileage of 20 miles per galon. Write a program so that the program stops generating observations when distance reaches 250 miles or when 10 gallons of fuel have been used
Hint Miles = gallon * mpg
I used the following code:
data mileage;
mpg = 20;
do until (miles le 250);
miles +1;
do until (gallon le 10);
gallon + 1;
miles = gallon * mpg;
end;
end;
output;
run;
Please tell me what am I doing wrong here?
Many thanks for your time and attention !
Because you waited until after the DO loops finished to write out any observations. If you want to write multiple observations you should move your output statement inside the do loop.
Also your program is never initializing gallon so mpg will always be missing and so less than 250 which means your outer DO loop will only execute once.
Your question as written can be answered without a program since 10*20 is less than 250. Assuming that you also want to change the mpg values then perhaps this is more what you wanted?
data mileage;
do mpg = 20 by 1 until (miles ge 250);
do gallon=1 to 10 until (miles ge 250);
miles = gallon * mpg;
output;
end;
end;
run;
The ability to combine both an iterative loop with an UNTIL condition is one of the many nice features of the data step DO loop.

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

Population doubled #years

I have no idea what is wrong in there:
current_pop = 7370000000
print "So the current population is", str(current_pop)
doubled_pop = 14740000000
year_1 = 2
year = 0
while current_pop != doubled_pop:
if current_pop != doubled_pop:
current_pop = current_pop * 2
year += 1
else:
year += 0
print year
I have already tried to like times that current pop by the year_1. But it keeps giving me year = 1
The problem in your program is that you assume that the population doubles every year! So of course under those conditions the population will double in exactly one year. Thankfully, our situation is not so dire. According to data provided by the World Bank, the annual rate of world population growth was 1.182% in 2015.
Your loop was unnecessarily complicated, but more importantly, your test was wrong. You (and a previous answer) had:
while current_pop != doubled_pop:
But this test will usually fail, since it is unlikely that the population will grow at a rate that conveniently lands on double the initial population on an exact year division. You need to use an inequality:
while current_pop < doubled_pop:
Here is a program that works:
current_pop = 7370000000
growth_rate = 0.01182
print "So the current population is", str(current_pop)
doubled_pop = 2 * current_pop
year = 0
while current_pop < doubled_pop:
current_pop = current_pop + (current_pop * growth_rate)
year += 1
print year
And here is the output:
So the current population is 7370000000
59

Find the date given the year, the month and the "nth" occurrance of day within the month C/C++

In order that a device (with limited memory) is able to manage its own timezone and daylight savings, I'm trying to calculate daylight savings triggers for 85 time zones based on a simplified description of each timezone. I have access to minimal C and C++ libraries within the device. The format of the timezone (inc. DST) description for each time zone is as follows:
UTC - the base time and date from system clock
GMTOffsetMinutes - offset from GMT with DST inactive
DSTDeltaMinutes - modifier to above with DST active (as applicable to TZ)
DSTStartMonth - month in which DST becomes active
DSTStartNthOccurranceOfDay - the nth occurrence of the day name in month
DSTDayOfWeek - Sun = 0 through to Sat = 6
DSTStartHour - hour at which DST becomes active
DSTStartMinute - minute at which DST becomes active
and corresponding EndMonth, EndNth..., EndHour, EndMinute
I have found numerous examples going the other way, i.e. starting with the date, but they involve using the modulus, keeping the remainder and dropping the quotient hence I have been unable to transpose the formula to suit my needs.
I also tried to reuse the standard "Jan = 6, Feb = 2, Mar = 2, Apr = 5, May = 0, etc. modifier table and year modifiers from the "tell me what day the 25th of June, 2067 is?" party trick and developed the following algorithm.
Date = DayOfWeek + ((NthOccuranceOfDay - 1) x 7 ) - MonthCode - YearCode
This worked for the first 6 random test dates I selected but then I started to see dates for which it failed. Is it possible that the basic algorithm is sound but I'm missing a further modifier or maybe that I'm applying the modifiers incorrectly?
Is there another solution I could utilize?
Using this open source, cross platform date library, one can write:
#include "date.h"
#include <iostream>
int
main()
{
using namespace date;
year_month_day us_daylight_starts = sys_days(sun[2]/mar/2015);
year_month_day us_daylight_ends = sys_days(sun[1]/nov/2015);
std::cout << us_daylight_starts << '\n';
std::cout << us_daylight_ends << '\n';
}
which will output:
2015-03-08
2015-11-01
The formulas this library is based on are in the public domain and documented here.
The algorithms paper has very complete unit tests validating the date algorithms over a range of millions of years (a far larger range than is necessary).
Sometimes daylight savings rules are written in terms of the last weekday of a month. That is just as easily handled:
year_month_day ymd = sys_days(sun[last]/nov/2015);
std::cout << ymd << '\n'; // 2015-11-29
That formula will be off by one week (or even two weeks) if MonthCode + YearCode is greater than or equal to DayOfWeek, because in that case you will be counting NthOccurenceOfDay from a negative date.
As an alternative, with no tables, you can compute the day of week of the first of the month using, for example, Zeller's algorithm:
int NthOccurrence(int year, int month, int n, int dayOfWeek) {
// year is the current year (eg. 2015)
// month is the target month (January == 1...December == 12)
// Finds the date of the nth dayOfWeek (Sun == 0...Sat == 6)
// Adjust month and year
if (month < 3) { --year, month += 12; }
// The gregorian calendar is a 400-year cycle
year = year % 400;
// There are no leap years in years 100, 200 and 300 of the cycle.
int century = year / 100;
int leaps = year / 4 - century;
// A normal year is 52 weeks and 1 day, so the calendar advances one day.
// In a leap year, it advances two days.
int advances = year + leaps;
// This is either magic or carefully contrived,
// depending on how you look at it:
int month_offset = (13 * (month + 1)) / 5;
// From which, we can compute the day of week of the first of the month:
int first = (month_offset + advances) % 7;
// If the dayOfWeek we're looking for is at least the day we just
// computed, we just add the difference. Otherwise, we need to add 7.
// Then we just add the desired number of weeks.
int offset = dayOfWeek - first;
if (offset < 0) offset += 7;
return 1 + offset + (n - 1) * 7;
}