Smelly Coding

ilan

Expert
Longtime User
Can you make this pice of code more sexy?

B4X:
``````public static int dayOfYear(int month, int dayOfMonth, int year) {
if (month == 2) {
dayOfMonth += 31;
} else if (month == 3) {
dayOfMonth += 59;
} else if (month == 4) {
dayOfMonth += 90;
} else if (month == 5) {
dayOfMonth += 31 + 28 + 31 + 30;
} else if (month == 6) {
dayOfMonth += 31 + 28 + 31 + 30 + 31;
} else if (month == 7) {
dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30;
} else if (month == 8) {
dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31;
} else if (month == 9) {
dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31;
} else if (month == 10) {
dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30;
} else if (month == 11) {
dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31;
} else if (month == 12) {
dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31;
}
return dayOfMonth;
}``````

should be possible to do with 3 lines (at least thats the best i could do)
lets see your dry code

ps: a very nice article to read: https://ocw.mit.edu/ans7870/6/6.005/s16/classes/04-code-review/

Star-Dust

Expert
1.
B4X:
``````Public Sub dayOfYear (month As Int, dayOfMonth As Int,year As Int) As Int
Dim Sum() As Int = Array As Int (0,0,31,59,90,120,151,181,212,243,273,304,334)
Return dayOfMonth + Sum(month)
End Sub``````
2.
B4X:
``````Public Sub dayOfYear (month As Int, dayOfMonth As Int,year As Int) As Int
Dim Sum() As Int = Array As Int (0,31, 28, 31, 30, 31, 30, 31, 31, 30,31, 30)
For i=1 To month
dayOfMonth = dayOfMonth + Sum(i)
Next
Return dayOfMonth
End Sub``````

Last edited:

JordiCP

Expert
Longtime User
My untested approach takes into account that November has 30days in Spain , and also leap years

B4X:
``````public static int dayOfYear(int month, int dayOfMonth, int year) {
int mdays[] = {31, 28+((year&3)?0:1), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
return( (month>1) ? ( dayOfYear( month-1, mdays[month-1] + dayOfMonth, year)) : dayOfMonth  );
}``````

I like Star-Dust's approach that avoids recursion

ilan

Expert
Longtime User
i must say that i am very surprised. both of you beat me with 2 lines

this was my code:

B4X:
``````public class Main {
public static void main(String[] args) {
System.out.println(getdayofyear(12,3,2000));
}
public static int getdayofyear(int day, int month, int year){
int[] days = new int[]{31,28,31,30,31,30,31,31,30,31,30,31};
//if (day > days[month-1]){System.out.println("you have entered a wrong value."); return 0;} //check if day is correct
for (int i=0;i<month-1;i++){day += days[i];}
//if (year > 1900 && year % 4 == 0){day += 1;} //calculate the leap year
return day;
}
}``````

how did i not think of doing it like this:

Public Sub dayOfYear (month As Int, dayOfMonth As Int,year As Int) As Int
Dim Sum() As Int = Array As Int (0,0,31,59,90,120,151,181,212,243,273,304,334)
Return dayOfMonth + Sum(month)
End Sub

???

really smart. and yours jordi is also really smart. can you please explain this sign ? in your code. what means ? inside the code?

public static int dayOfYear(int month, int dayOfMonth, int year) {
int mdays[] = {
31, 28+((year&3)?0:1), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
return( (month>1) ? ( dayOfYear( month-1, mdays[month-1] + dayOfMonth, year)) : dayOfMonth );
}

JordiCP

Expert
Longtime User
really smart. and yours jordi is also really smart. can you please explain this sign ? in your code. what means ? inside the code?
HERE

Star-Dust

Expert
i must say that i am very surprised. both of you beat me with 2 lines

this was my code:

B4X:
``````public class Main {
public static void main(String[] args) {
System.out.println(getdayofyear(12,3,2000));
}
public static int getdayofyear(int day, int month, int year){
int[] days = new int[]{31,28,31,30,31,30,31,31,30,31,30,31};
//if (day > days[month-1]){System.out.println("you have entered a wrong value."); return 0;} //check if day is correct
for (int i=0;i<month-1;i++){day += days[i];}
//if (year > 1900 && year % 4 == 0){day += 1;} //calculate the leap year
return day;
}
}``````

how did i not think of doing it like this:

code?
I have to thank my informatics teacher (of high school)
It was fixed with the code reduction (at the time the computers had little memory)
He spent many hours teaching us how to reduce the code and different methods, today they would not make sense because they would penalize the performance.

However, as an educational exercise, they are still valid

PS. We still did not talk about recursion. Only in the last year has started to present this topic

ilan

Expert
Longtime User

thanx a lot, i learned something new

Star-Dust

Expert
for the calculation of the leap month
B4X:
``````Public Sub dayOfYear (month As Int, dayOfMonth As Int,year As Int) As Int
Dim bissextile As Int  = 2*(0.5-Min((year Mod 4),0.5)+Min((year Mod 100),0.5)-Min((year Mod 400),0.5))
Dim Sum() As Int = Array As Int (0,0,31,59,90,120,151,181,212,243,273,304,335)

Return dayOfMonth + Sum(month) + (bissextile * Floor(Min(month,2)/2))
End Sub``````

(bissextile * Floor(Min(month,2)/2))
This code serves to add the leap day only if the month is February or later. If it were January (value 1) it would multiply the leap day by zero and then cancel it

2*(0.5-Min((year Mod 4),0.5)+Min((year Mod 100),0.5)-Min((year Mod 400),0.5))
We explain this second formula... Too complicated, try it and it works.
1. Year 1985, it will be: 2 * (0.5-0.5+0.5-0.5) = 0
2. Year 1900, it will be: 2 * (0.5-0.0+0.0 - 0.5) = 0
3. Year 2004 it will be: 2 * (0.5-0.0+0.5 - 0.5) = 1
4. Year 2000, it will be: 2 * (0.5+0.0- 0.0 - 0.0) = 1
PS: When I was studying informatics it was almost forbidden to use "IF" because they used too many machine cycles, so we were looking for other systems for calculation with the Mod and Div that we used less machine cycles and they were faster

Last edited:

Daestrum

Well-Known Member
Longtime User
A bit late but ( java 8+)
B4X:
`````` Dim localDate As JavaObject
localDate.InitializeStatic("java.time.LocalDate")
Log(localDate.RunMethodjo("of",Array(2019,12,31)).RunMethod("getDayOfYear",Null))``````

or shorter but harder to read
B4X:
``````Dim localDate as JavaObject
log(localDate.InitializeStatic("java.time.LocalDate").RunMethodJO("of",Array(2019,12,31)).RunMethod("getDayOfYear",null))``````

Last edited:

LucaMs

Expert
Longtime User
B4X:
``````Sub dayOfYear(month As Int, dayOfMonth As Int, year As Int) As Int
Return DateUtils.PeriodBetweenInDays(DateUtils.SetDate(year,1,1), DateUtils.SetDate(year, month, dayOfMonth)).Days + 1
End Sub``````

DonManfred

Expert
Longtime User
can you please explain this sign ? in your code. what means ? inside the code?
It is an Ternary Operator.

In Java this expression evaluates to:

If foo is selected, assign selected foo to bar. If not, assign baz to bar.

Object bar = foo.isSelected() ? foo : baz;

Erel

B4X founder
Staff member
Longtime User
B4X:
``````Sub DayOfYear(Month As Int, DayOfMonth As Int, Year As Int) As Int
Return DateTime.GetDayOfYear(DateUtils.SetDate(Year, Month, DayOfMonth))
End Sub``````

ilan

Expert
Longtime User

in b4x it would be like:

B4X:
``if a>b then c else d``

B4X:
``````Sub DayOfYear(Month As Int, DayOfMonth As Int, Year As Int) As Int
Return DateTime.GetDayOfYear(DateUtils.SetDate(Year, Month, DayOfMonth))
End Sub``````

no cheating allowed the idea was to create a function to solve the problem without using external libs.

Sandman

Expert
...and if you, for some really strange reason, would need to do this in a bash script:

B4X:
``date --date="2019-01-19" "+%j"``

no cheating allowed

Surely a little cheating is allowed?

DonManfred

Expert
Longtime User
Datetime is an internal Library. Available in every B4A Version

Star-Dust

Expert
I think that @ilan meant that the goal was to optimize the code of the post#1 and make it pleasant (he wrote sexy)
It is only an exercise, obviously with the available libraries it is not necessary to invent anything.

The link ilan posted placed the emphasis on the need to write code that is not only functional but is written in style. So I meant it as an exercise in style.

Last edited:

Sandman

Expert
Surely a little cheating is allowed?

Ok, here's another version, without cheating. PHP this time - a oneliner:

B4X:
``````public function dayOfYear(\$month, \$dayOfMonth)
{
return [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 31][\$month] + \$dayOfMonth;
}``````

Thanks to very clever programming I was also able to remove the input year.

Edit: Oh, I made a bug in there. Oh well, it happens - gonna leave it.

Last edited:

LucaMs

Expert
Longtime User
in b4x it would be like:

B4X:
``if a>b then c else d``
Same as IIF in vb.net.

sorex

Expert
``````Public Sub dayOfYear (month As Int, dayOfMonth As Int,year As Int) As Int