Using if between else in SAS - if-statement

I am trying to create 2 new variables (AGEGRP and AGEGRP2) using AGE. The AGE variable includes numerical ages that I would like to bucket into ranges.
Here is my code:
DATA MYTEST;
SET test;
if (AGE < 18) then AGEGRP = '<18';
if (18 <= AGE < 65) then AGEGRP = '>=18 to <65';
else if (AGE >= 65) then AGEGRP = '>=65';
if (AGE < 2) then AGEGRP2 = '<2';
if (2 <= AGE < 12) then AGEGRP2 = '>=2 to <12';
if (12 <= AGE < 18) then AGEGRP2 = '>=12 to <18';
else if (AGE >= 18) then AGEGRP2 = '<=18';
RUN;
PROC PRINT DATA = MYTEST;
RUN;
This yields the following:
AGE AGEGRP AGEGRP2
5 <18 >=
15 <18 >=
20 >=18 to <65 >=
1 <18 >=
80 >=65 >=
I suspect there is something wrong with my between ( <= __ < ) statements. How can I yield correct AGEGRP2 ranges?

If you do not include all of the ELSE then the last else clause overwrites the results of the earlier IF statements. IF ... THEN ...; ELSE IF ... THEN ...; ELSE ... ;
Make sure to define your variables before using them. Otherwise SAS will guess how to define them based on how they are first used. In your example AGEGRP will be length $3 and AGEGRP2 will be length $2.
Add this line before starting your IF cascades.
length AGEGRP AGEGRP2 $11;

Your issues is with the IF/ELSE IF. You haven't chained them together properly.
if (AGE < 18) then AGEGRP = '<18'; * Codes less than 18;
*codes 18 to 65;
if (18 <= AGE < 65) then AGEGRP = '>=18 to <65';
*anything else (including < 18) is recoded;
else if (AGE >= 65) then AGEGRP = '>=65';
This should work for you.
if (AGE < 18) then AGEGRP = '<18'; * Codes less than 18;
*codes 18 to 65;
else if (18 <= AGE < 65) then AGEGRP = '>=18 to <65';
*anything else (including < 18) is recoded;
else if (AGE >= 65) then AGEGRP = '>=65';

Related

Codecademy Race Day else statment isn't working

Here's my code for this test project. My else statement isn't returning when my age is set to 18. Ignore the change in double/single quotes; I accidentally clicked on the Clean Up button and Codecademy switched them.
let raceNumber = Math.floor(Math.random() * 1000);
const early = true;
const age = 18;
if (early && age > 18) {
raceNumber += 1000;
console.log("Your race starts at 9:30am, and your number is " + raceNumber + ".");
} else if (!early && age > 18) {
console.log("Your race starts at 11:00am, and your number is " + raceNumber + ".");
} else if (early || !early && age < 18) {
console.log('Your race starts at 12:30pm, and your number is ' + raceNumber + '.');
} else {
console.log('Please see the registration desk for your race time and number');
}
If early is always true, then early || !early && age < 18 is true, and the final else will never be reached.
You might be in need of some parentheses

adding dates in C++, using class

I'm a novice in coding...
I've written a code in C++ to calculate the date after adding new numbers to date, month, and year. However, it's become too long and my computer can't process it if the date goes over 50.
Could you give me a few tips if there was a way to shorten this?
#include <iostream>
class Date{
int year; int month; int day;
}
public:
void set_date(int _year, int _month, int _day){
year=_year;
month=_month;
day=_day;
}
void add_day(int inc){
day+=inc;
}
void add_month(int inc){
month+=inc;
}
void add_year(int inc){
year+=inc;
}
void get_date(){
while (day>31){
if ((year%4)==0 && month==2 && day > 29){
month+=1;day-=29;
}
else if(month==2 && day > 28){
month+=1;day-=28;
}
else if((day>30)&&(month==4||month==6||month==9||month==11)){
month+=1;day-=30;
}
else if((day>31)&&(month==3||month==5||month==7||month==8||month==10||month==12||month==1)){
month+=1;day-=31;
}
}
if (month>12){
year+=month/12;
month=month%12;
}
std::cout<<"year"<<year<<std::endl;
std::cout<<"month"<<month<<std::endl;
std::cout<<"day"<<day<<std::endl;
}
int main(){
Date date;
date.set_data(191,2,10);
date.add_day(60);
date.add_month(10);
date.add_year(3);
date.get_date();
return 0;
}
When I run your code it loops forever with day=39 and month=13, which is a condition you don't check for. You might want to move the whole if (month>12) into your loop, so that the months get corrected while processing the days. You also want to add an else that stops the loop:
bool doneProcessing = false;
do
{
if ((year % 4) == 0 && month == 2 && day > 29)
{
month += 1;
day -= 29;
}
else if (month == 2 && day > 28)
{
month += 1;
day -= 28;
}
else if ((day > 30) && (month == 4 || month == 6 || month == 9 || month == 11))
{
month += 1;
day -= 30;
}
else if ((day > 31) && (month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 || month == 1))
{
month += 1;
day -= 31;
}
else
{
doneProcessing = true;
}
if (month > 12)
{
year += month / 12;
month = month % 12;
}
}
while (!doneProcessing);
I didn't check the validity of your semantics, but I did notice one thing: When you have month=2 and day=30, you'd want to process that as well, but you only check day>31, thus I changed the loop to simply run until the else is hit (all days are valid now).
With this change your code properly terminates after printing this result:
year195
month2
day8
PS: With a debugger you can easily and quickly find such issues. See What is a debugger and how can it help me diagnose problems?

After input my program seems to skip the first IF statement and go directly to ELSE

I have a problem with the code. It compiles with no errors, but right after taking input from the user it even with correct values it seems to skip the first conditional statement and go directly to ELSE which causes the program to terminate. I can't seem to find the cause for this behavior.
I think it might the issue with the way the conditional statement is constructed:
if( ((S <= 25 && S <= 75) % 5 == 0) && (U < 0.2 && U < 0.7) ){
I need to check if the value entered is 25 <= S <= 75 and is divisible by 5, as well as the other value being 0.2 < U < 0.7
Course Assignment
//#include "stdafx.h" // Header File used VS.
#include <iostream>
//#include <iomanip> // Used to format the output.
#include <cstdlib> // Used for system().
#include <math.h> // Used for sqrt().
using namespace std;// ?
int main (){
int S; // Gram/Litre
double U; // Specific Max. Growth Rate. Per Hour.
double D; // Maximum Dilution Rate.
const int K = rand() % 7 + 2; // Saturation Constant - Randomly Gegerated Number Between 2 & 7. In Hour/Litre.
cout << "Enter value between 25 and 75, divisible by 5, for S in Gram/Litre: ";
cin >> S;
cout << "Enter value bigger than 0.2, but less than 0.7, for U per Hour: ";
cin >> U;
if( ((S <= 25 && S <= 75) % 5 == 0) && (U < 0.2 && U < 0.7) ){ // Check Condition ***May Need Adjustments***
D = U * ( 1 - sqrt ( K / ( K + S) ) ); // Might have to adjust values to fit data type double. Add .00
cout.precision(3); // Prints 3 values after decimal point.
cout << "Maximum dilution rate is: " << D << endl;
if( D < 0.35 && D < 0.45 ){
cout << "Kinetic parameters are acceptable." << endl;
}
else{
cout << "Kinetic parameters are not acceptable." << endl;
}
}
else{
cout << "Invalid Input. Program will now terminate." << endl;
}
system("PAUSE"); // Pauses the program before termination.
return 0;
}
First, if you want 25 <= S <= 75, you should have
25 <= S && S <= 75, not S <= 25 && S <= 75. Same with U < 0.2 and D < 0.35 - they should be 0.2 < U and 0.35 < D.
Second, the above statement returns a boolean - thus, if S is a value between 25 and 75, the boolean will be cast to an integer value of 1, and 1 % 5 == 0 always be false. (Similarly, if S is outside this range, the boolean will be cast to an integer 0 and 0 % 5 == 0 will always be true)
A correct, complete if-statement is as follows:
if((25 <= S && S <= 75) && (S % 5 == 0) && (0.2 < U && U < 0.7)){
...
if(0.35 < D && D < 0.45){
...
}
...
}
If you read a number between 25 and 75 from the input, the if( ((S <= 25 is always false.
You must use if( ((S >= 25 && ....
The problem mainly lies in your loop conditions. For example, in this line from your code:
if( ((S <= 25 && S <= 75) % 5 == 0) && (U < 0.2 && U < 0.7) ){
//...
}
The if condition S <= 25 && S <= 75 simply can be rewritten as S <= 25 because in words, your parameter states that if S is less than or equal to 25 OR if S is less than or equal to 75, and so on.
The same problem exists here: U < 0.2 && U < 0.7. Once again, the if statement simply checks whether U is less than 0.2 and U is less than 0.7, the latter always being true if the former is true.
However, in your output statement before accepting the 2 inputs, you state that S should have a range of 25 <= S <= 75, meaning that S is greater than 25; not less. The same issue for U: you are expecting input ranging between 0.2 < U < 0.7.
How you should rewrite your if-then statement is as follows:
if( (S >= 25 && S <= 75) && (S % 5 == 0) && (U > 0.2 && U < 0.7) ){
//...
}
This not only makes your if-statement's conditions easier to read and comprehend, but it also eliminates the errors. This should work now. The meaning of the code stays the same: S has to be between 25 and 75 (including these numbers), it should be divisible by 5, and U should be between 0.2 and 0.7.
BTW, the same mistake exists in this part of your code also:
if( D < 0.35 && D < 0.45 ){...
I fixed it below:
if( D > 0.35 && D < 0.45 ){...
Good luck!

In C++, using a loop to find the # of days on any given date?

And yes this is an assignment-- So please don't post solutions, but detailed pseudocodes are extremely helpful!
I already have a program in C++ that accepts a date from the user and will determine if it is a leap year or not.
Here is my leap year function so far (I do hope that this is the correct logic):
bool isLeapYear (int year){
int leapYear = 0;
//leapyear = 1 when true, = 0 when false
if ((year%400 == 0) && (year%100 != 100)) {
leapYear = 1;
}
else if (year%4 == 0) {
leapYear = 1;
}
else {
leapYear = 0;
}
if (leapYear == 1) {
return 1;
}
else {
return 0;
}
}
Here is a paraphrase of what I must do next:
You MUST use a loop that adds months one at a time to an accumulated sum.
Don't use any hardcoded values
Such as 152 for the first 5 months in a leap year
And to clarify, this is my first programming class and have been in this C++ class for just about a month now.
So it would be greatly appreciated if anyone could help me figure out how to do the loop statements to add the number of the months?
(IE: 12/31/2013 should be "365" in a non leap year, and "366" in a leap year).
I know this is wrong but this is what I have so far for a function "dayNumber" that simply return the number of days in the year to the main function (which is calling the dayNumber function):
int dayNumber (int day, int month, int year){
//variable declarations
int sumTotal = 0;
for ( int loop = 1; loop < month; loop++) {
sumTotal = (( month-1 ) * 31);
sumTotal = sumTotal + day + 1;
if ( (loop==4) || (loop=6) || (loop=9) ||
(loop==11) ) {
sumTotal = ( sumTotal - 1 );
}
else if ( isLeapYear(year) == 1 ) {
sumTotal = (sumTotal - 2);
}
else {
sumTotal = (sumTotal - 3);
}
}
return sumTotal;
}
I started to mess around with it to get to a proper value for days I knew but it kind of messed it up more, haha.
If anyone has any guidance on how to appropriately do a loop, I would be extremely greatful!:)
EDIT:
Alright, I think I may have answered my own question.
int dayNumber (int day, int month, int year){
//variable declarations
int sumTotal = 0;
for ( int loop = 1; loop < month; loop++) {
sumTotal = ( sumTotal + 31 );
if ( (loop==4) || (loop==6) || (loop==9) ||
(loop==11) ) {
sumTotal = ( sumTotal - 1 );
}
}
if ((month !=2) && (month > 1)) {
if (isLeapYear(year) ==1) {
sumTotal = ( sumTotal - 2 );
}
else {
sumTotal = ( sumTotal - 3);
}
}
else {
sumTotal = sumTotal;
}
sumTotal = sumTotal + day;
return sumTotal;
}
I definitely need to work on my loops.
I appreciate letting me know that my '=' should have been '=='!
I believe this is an appropriate code using a simple enough loop?
I will test some more dates. I've only tested the few provided on the class site so far.
I can't answer my own posts, I don't have enough reputation.
I know an answer has been accepted, but it took me some time writing my own, let's see if it can adds some informations overall.
Let's review this slowly.
First, your isLeapYear() function isn't completely right.
Without delving into the algorithm part, two or three things can be improved.
You're returning a bool, yet your return statements are returning ints. This isn't wrong in itself, but using the true and false keywords can improve the readability and consistency.
Instead of creating, assigning and returning a variable, you should instantly return your result.
Add spaces around your operators : year%400 should become year % 400.
Now your code.
This condition :
if ((year%400 == 0) && (year%100 != 100))
... especially this part :
(year%100 != 100)
Isn't doing what you expect.
Overall, the algorithm is as follow :
if year is not divisible by 4 then common year
else if year is not divisible by 100 then leap year
else if year is not divisible by 400 then common year
else leap year
Translating it in code:
/**/ if (year % 4 != 0)
return false;
else if (year % 100 != 0)
return true;
else if (year % 400 != 0)
return false;
else
return true;
Now let's simplify this a bit:
/**/ if (year % 4 == 0 && year % 100 != 0)
return true;
else if (year % 400 == 0)
return true;
else
return false;
Again:
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
return true;
else
return false;
And finally, the whole boolean expression can be directly returned:
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
Now that your function is correct, let's try an algorithm to your dayNumber function :
If the date provided in parameters is considered correct, then the algorithm is quite simple :
Start sum from 0
Loop from 1 to month excluded
If month is Frebruary then add 29 if isLeapYear returns true, else 28
If month is January, March, May, July, August, October or December add 31
Else add 30
Add day to sum.
I know that giving detailed pseudocode helps more than a solution, but I'm not that good of a teacher yet :/ Good luck with this answer, and get some sleep when you're done :)
I'm assuming that dayNumber(8, 3, 1914) is supposed to return the ISO day number of 1914, March 8th.
What you want to do is the following:
procedure dayNumber(theDay, theMonth, theYear):
set answer to 1 // the first day of the year is day 1
for every month 'thisMonth', up to and excluding theMonth:
increment answer by the number of days in thisMonth
increment answer by (theDay - 1) // the first day of the month is monthday 1
return answer
In the iteration statement (or 'loop body'), there are three cases:
February: if it's a leap year, increment thisMonth by 29, otherwise increment by 28.
Short months (April, June, September, November): increment by 30 days.
Otherwise, long months (January, March, May, July, August, October, December): increment by 31 days.
This translates to:
if (thisMonth == 2) {
// February
if (isLeapYear(theYear))
thisMonth += 29;
else
thisMonth += 28;
} else if (thisMonth == 4 || thisMonth == 6 || thisMonth == 9 || thisMonth == 11) {
// Short month
thisMonth += 30;
} else {
// Long month
thisMonth += 31;
}
(Note: X += Y is, or should be, short for X = X + Y.)
The loop logic you use looks mostly correct to me, except for 1) off-by-one errors because you start with day 0, and 2) adding the monthday inside the loop rather than outside of it:
int dayNumber (int theDay, int theMonth, int theYear) {
int result = 1;
for (int thisMonth = 1; thisMonth < theMonth; thisMonth++) {
/* ... see above ... */
}
return result + theDay - 1;
}
Now, about making the iteration statement prettier, there are basically two ways (and if your course hasn't yet covered them, I of course recommend against using them in an answer). One is using a switch statement, but I'm really not a fan of them, and it doesn't provide much benefit over the code I already gave. The other would be to use arrays:
int dayNumber (int theDay, int theMonth, int theYear) {
int monthDays[12] = { 31, 28, 31, 30, 31, 30, 31
, 31, 30, 31, 30, 31 }
int result = 1;
for (int thisMonth = 1; thisMonth < theMonth; thisMonth++) {
if (thisMonth == 2 && isLeapYear(theYear))
// Special case: February in a leap year.
result += 29;
else
/* Take the month length from the array.
* Because C++'s array indices begin at 0,
* but our first month is month 1,
* we have to subtract one from thisMonth.
*/
result += monthDays[thisMonth - 1];
}
return result + theDay - 1;
}
#include <ctime>
static int GetDaysInMonthOfTheDate(std::tm curDate)
{
std::tm date = curDate;
int i = 0;
for (i = 29; i <= 31; i++)
{
date.tm_mday = i;
mktime(&date);
if (date1->tm_mon != curDate.tm_mon)
{
break;
}
}
return i - 1;
}

if else statment in go lang

Could someone help me debug this program, only the else part is processed on every input.
This id a program for grading students. a student inputs a mark and the the grade is displayed
func main(){
var x int
fmt.Println("Enter your marks")
fmt.Scanf("%d",&x)
if (100 <= x) && (x<=75){
fmt.Println("D1")
}else if (74 <= x)&&(x <= 70){
fmt.Println("D2")
}else if (69 <= x )&&(x<=65){
fmt.Println("C3")
}else if (64 <= x)&&(x <= 60){
fmt.Println("C4")
}else if (59 <= x)&&(x <= 55){
fmt.Println("C5")
}else if (54 <= x)&&( x<= 50){
fmt.Println("C6")
}else if (49 <= x )&&(x<= 45){
fmt.Println("P7")
}else{
fmt.Println("Work harder")
}
}
You have a logic problem.
Change
if (100 <= x) && (x<=75){
to
if 75 <= x && x <= 100 { // numbers here are ordered from smallest to greatest
because a number can't be greater than 100 and smaller than 75.
And it's the same for the other lines of course.
Note that you could make less comparisons. Suppose you test if the number is smaller than 100 initially, then you don't have to test if it's smaller than 75 just after you tested it's smaller than 75.
A typical Go code would probably have a switch here instead of all those if/else. See switch in the documentation. Here's how it could be written with a switch :
switch {
case x > 100:
fmt.Println("Congrats!") // you forgot this one
case x >= 75:
fmt.Println("D1")
case x >= 70:
fmt.Println("D2")
case x >= 65:
fmt.Println("C3")
case x >= 60:
fmt.Println("C4")
case x >= 55:
fmt.Println("C5")
case x >= 50:
fmt.Println("C6")
case x >= 45:
fmt.Println("P7")
default:
fmt.Println("Work harder")
}
A last comment : This type of switching code rarely occurs because normally the thresholds and related notes are stored as data, for example in a struct.
Your IF statement says:
if 100 is less than x (which means x has to be greater than 100)
AND
x less than (or equal to) 75
do this--
x will never be greater than 100 AND less than 75, so it always does the ELSE ...
all if and if else statements provided in this code are logically incorrect
example:
if (100 <= x) && (x<=75)
here if (100 <= x) is false, the compiler will not even consider the next condition.
This is called SHORT CIRCUIT, the lazy evaluation of condition statements.
this is also applicable to OR conditions i.e in case the first condition is true the second condition will not be evaluated.
So according to the code you have written, the ideal solution will be
func main() {
var x int
fmt.Println("Enter your marks")
fmt.Scanf("%d", &x)
if (100 >= x) && (x >= 75) {
fmt.Println("D1")
} else if (74 >= x) && (x >= 70) {
fmt.Println("D2")
} else if (69 >= x) && (x >= 65) {
fmt.Println("C3")
} else if (64 >= x) && (x >= 60) {
fmt.Println("C4")
} else if (59 >= x) && (x >= 55) {
fmt.Println("C5")
} else if (54 >= x) && (x >= 50) {
fmt.Println("C6")
} else if (49 >= x) && (x >= 45) {
fmt.Println("P7")
} else {
fmt.Println("Work harder")
}
Thankx finaly got with your help. hope it helps someone else some time in future
package main
import "fmt"
func main(){
var x int
fmt.Println("Enter your marks")
fmt.Scanf("%d",&x)
if (75<= x) && (x<=100){
fmt.Println("D1")
}else if (70 <= x)&&(x <= 74){
fmt.Println("D2")
}else if (65 <= x )&&(x<=69){
fmt.Println("C3")
}else if (60 <= x)&&(x <= 64){
fmt.Println("C4")
}else if (55 <= x)&&(x <= 59){
fmt.Println("C5")
}else if (50 <= x)&&( x<= 54){
fmt.Println("C6")
}else if (45 <= x )&&(x<= 49){
fmt.Println("P7")
}else{
fmt.Println("Work harder")
}
}