GIDForums  

Go Back   GIDForums > Computer Programming Forums > C Programming Language
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 30-Dec-2005, 06:17
ldn ldn is offline
New Member
 
Join Date: Nov 2005
Posts: 29
ldn is on a distinguished road

sunhour


Hi everyone
one of the C++ programs that Iam reading, it supposes to calculate the sunhour.so it require to enter the Latitude, longitute and time zone, the problem is whenever I am enter london Latitude 51 30 N, Longtitute 0 10 N, time zone 13:15 it or any time it gives me wrong output, I am not sure is my entry wrong or what.
CPP / C++ / C Code:
// C program calculating the sunrise and sunset for
// the current date and a fixed location(latitude,longitude)
// Note, twilight calculation gives insufficient accuracy of results
// Jarmo Lammi 1999 - 2001
// Last update July 21st, 2001

#include <stdio.h>
#include <math.h>
#include <stdlib.h> 
#include <time.h>

double pi = 3.14159;
double degs;
double rads;

double L,g,daylen;
double SunDia = 0.53;     // Sunradius degrees

double AirRefr = 34.0/60.0; // athmospheric refraction degrees //

//   Get the days to J2000
//   h is UT in decimal hours
//   FNday only works between 1901 to 2099 - see Meeus chapter 7

double FNday (int y, int m, int d, float h) {
long int luku = - 7 * (y + (m + 9)/12)/4 + 275*m/9 + d;
// type casting necessary on PC DOS and TClite to avoid overflow
luku+= (long int)y*367;
return (double)luku - 730531.5 + h/24.0;
};

//   the function below returns an angle in the range
//   0 to 2*pi

double FNrange (double x) {
    double b = 0.5*x / pi;
    double a = 2.0*pi * (b - (long)(b));
    if (a < 0) a = 2.0*pi + a;
    return a;
};

// Calculating the hourangle
//
double f0(double lat, double declin) {
double fo,dfo;
// Correction: different sign at S HS
dfo = rads*(0.5*SunDia + AirRefr); if (lat < 0.0) dfo = -dfo;
fo = tan(declin + dfo) * tan(lat*rads);
if (fo>0.99999) fo=1.0; // to avoid overflow //
fo = asin(fo) + pi/2.0;
return fo;
};

// Calculating the hourangle for twilight times
//
double f1(double lat, double declin) {
double fi,df1;
// Correction: different sign at S HS
df1 = rads * 6.0; if (lat < 0.0) df1 = -df1;
fi = tan(declin + df1) * tan(lat*rads);
if (fi>0.99999) fi=1.0; // to avoid overflow //
fi = asin(fi) + pi/2.0;
return fi;
};


//   Find the ecliptic longitude of the Sun

double FNsun (double d) {

//   mean longitude of the Sun

L = FNrange(280.461 * rads + .9856474 * rads * d);

//   mean anomaly of the Sun

g = FNrange(357.528 * rads + .9856003 * rads * d);

//   Ecliptic longitude of the Sun

return FNrange(L + 1.915 * rads * sin(g) + .02 * rads * sin(2 * g));
};


// Display decimal hours in hours and minutes
void showhrmn(double dhr) {
int hr,mn;
hr=(int) dhr;
mn = (dhr - (double) hr)*60;

printf("%0d:%0d",hr,mn);
};

int main(void){

double y,m,day,h,latit,longit;
float inlat,inlon,intz;
double tzone,d,lambda;
double obliq,alpha,delta,LL,equation,ha,hb,twx;
double twam,altmax,noont,settm,riset,twpm;
time_t sekunnit;
struct tm *p;

degs = 180.0/pi;
rads = pi/180.0;
//  get the date and time from the user
// read system date and extract the year

/** First get time **/
time(&sekunnit);

/** Next get localtime **/

 p=localtime(&sekunnit);

 y = p->tm_year;
 // this is Y2K compliant method
 y+= 1900;
 m = p->tm_mon + 1;

 day = p->tm_mday;

 h = 12;

 printf("year %4d month %2d\n",(int)y,(int)m); 
 printf("Input latitude, longitude and timezone\n");
 scanf("%f", &inlat); scanf("%f", &inlon); 
 scanf("%f", &intz);
 latit = (double)inlat; longit = (double)inlon;
 tzone = (double)intz;

// testing
// m=6; day=10;


d = FNday(y, m, day, h);

//   Use FNsun to find the ecliptic longitude of the
//   Sun

lambda = FNsun(d);

//   Obliquity of the ecliptic

obliq = 23.439 * rads - .0000004 * rads * d;

//   Find the RA and DEC of the Sun

alpha = atan2(cos(obliq) * sin(lambda), cos(lambda));
delta = asin(sin(obliq) * sin(lambda));

// Find the Equation of Time
// in minutes
// Correction suggested by David Smith
LL = L - alpha;
if (L < pi) LL += 2.0*pi;
equation = 1440.0 * (1.0 - LL / pi/2.0);
ha = f0(latit,delta);
hb = f1(latit,delta);
twx = hb - ha;	// length of twilight in radians
twx = 12.0*twx/pi;		// length of twilight in hours
printf("ha= %.2f   hb= %.2f \n",ha,hb);
// Conversion of angle to hours and minutes //
daylen = degs*ha/7.5;
     if (daylen<0.0001) {daylen = 0.0;}
// arctic winter     //

riset = 12.0 - 12.0 * ha/pi + tzone - longit/15.0 + equation/60.0;
settm = 12.0 + 12.0 * ha/pi + tzone - longit/15.0 + equation/60.0;
noont = riset + 12.0 * ha/pi;
altmax = 90.0 + delta * degs - latit; 
// Correction for S HS suggested by David Smith
// to express altitude as degrees from the N horizon
if (latit < delta * degs) altmax = 180.0 - altmax;

twam = riset - twx;	// morning twilight begin
twpm = settm + twx;	// evening twilight end

if (riset > 24.0) riset-= 24.0;
if (settm > 24.0) settm-= 24.0;

puts("\n Sunrise and set");
puts("===============");

printf("  year  : %d \n",(int)y);
printf("  month : %d \n",(int)m);
printf("  day   : %d \n\n",(int)day);
printf("Days since Y2K :  %d \n",(int)d);

printf("Latitude :  %3.1f, longitude: %3.1f, timezone: %3.1f \n",(float)latit,(float)longit,(float)tzone);
printf("Declination   :  %.2f \n",delta * degs);
printf("Daylength     : "); showhrmn(daylen); puts(" hours \n");
printf("Civil twilight: ");
showhrmn(twam); puts("");
printf("Sunrise       : ");
showhrmn(riset); puts("");

printf("Sun altitude ");
// Amendment by D. Smith
printf(" %.2f degr",altmax);
printf(latit>=0.0 ? " South" : " North");
printf(" at noontime "); showhrmn(noont); puts("");
printf("Sunset        : ");
showhrmn(settm);  puts("");
printf("Civil twilight: ");
showhrmn(twpm);  puts("\n");

return 0;
}
I paste the program as I found it.
  #2  
Old 30-Dec-2005, 08:14
kobi_hikri's Avatar
kobi_hikri kobi_hikri is offline
Regular Member
 
Join Date: Apr 2005
Location: Israel
Posts: 431
kobi_hikri has a spectacular aura aboutkobi_hikri has a spectacular aura about

Re: sunhour


Quote:
Originally Posted by ldn
Hi everyone
one of the C++ programs that Iam reading, it supposes to calculate the sunhour.so it require to enter the Latitude, longitute and time zone, the problem is whenever I am enter london Latitude 51 30 N, Longtitute 0 10 N, time zone 13:15 it or any time it gives me wrong output, I am not sure is my entry wrong or what.

Can you try to isolate the problem to a specific part of the code ?
Do you know what the result should be ?
I'd suggest you put printf lines into suspicious parts of the code, and see what the values are in those parts.
Personally, I simply don't know the math behind this so I can't check this code (I'd be happy to learn, if you want to explain this topic).

Shabat Shalom,
Kobi.
__________________
It's actually a one time thing (it just happens alot).
  #3  
Old 30-Dec-2005, 09:03
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,703
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: sunhour


Quote:
Originally Posted by ldn
Hi everyone
one of the C++ programs that Iam reading, it supposes to calculate the sunhour.so it require to enter the Latitude, longitute and time zone, the problem is whenever I am enter london Latitude 51 30 N, Longtitute 0 10 N, time zone 13:15

.
.
.
I paste the program as I found it.

1. If you want someone to help you understand your problem, you should tell us exactly what was the problem. Exactly how did you enter your data? What did you expect to see as the output? What did you get as an output?

I entered numeric values for 51 degrees 30 minutes north latitude and 0 degrees 10 minutes west longitude and 0 for the time zone and got the following output:

Code:
ha= 1.03 hb= 1.17 Sunrise and set =============== year : 2005 month : 12 day : 30 Days since Y2K : 2190 Latitude : 51.5, longitude: 0.2, timezone: 0.0 Declination : -23.14 Daylength : 7:51 hours Civil twilight: 7:33 Sunrise : 8:6 Sun altitude 15.36 degr South at noontime 12:1 Sunset : 15:57 Civil twilight: 16:30

Is any part of this the right answer? Well, I went to a web site that calculates such things: The U.S. Naval Observatory. I entered the latitude and longitude that you gave, and got the following Sun Data:

Code:
Begin civil twilight 07:26 Sunrise 08:06 Sun transit 12:03 Sunset 16:00 End civil twilight 16:40

Now, this looks pretty close (note that the program does not seem to take the day of the month into account). I am not sure what you expected to get.
I really think a little more care could have been given to the appearance of the output. After all, it's the only thing that the user sees. Now, really, how much trouble would it have been to print
Code:
Sunrise : 8:06
or
Code:
Sunrise : 08:06
instead of
Code:
Sunrise : 8:6

Why is this important to me? Because it tells me something about the programmer. Pride? Where is it? Why shouldn't I create something to be proud of? (Especially if I publish it.)

2.
If you are trying to learn good programming practices, this is a pretty good example of bad program practices. Why?

a. Because it uses illegal or non-standard code?
Not really. Other than use of non-standard (for C programs) comments with //, the only other non-standards-compliant sillinesses are where the author put a superfluous semicolon after the closing brace at the end of the functions. (That compiles OK on my compilers, but extra semicolons outside of a function are not allowed by the C standard.) Why is this significant? Because it tells me a little more about the programmer. Why would people throw in extra semicolons just for the heck of it? Maybe unfamiliarity with the language? Maybe didn't have a good role model as a teacher? ??

b. Because it gives the wrong answer?
I can't really tell without analyzing the code more closely, and without more testing, but it seems to have some good possibilities for right answers (based on a sample data set of one item). On the other hand, if I determine that some of the answers are wrong (maybe "nearly" OK but slightly off) where would I start to look for bugs? Well, let's continue...

c. Because the calculations are hard to understand?
Well, the algorithm for calculating the various output variables is documented in various textbooks and websites, and the astronomical terms may be hard to understand if you are not a physics or astronomy major, but that's a learning opportunity. After all, if you weren't interested, you wouldn't even be looking at this, right?

d. Because the code is hard to understand?
That is very subjective, but the answer for someone just learning the language is probably, "Huh? What the heck is going on?" (So I would have to say, "yes.")

d. Because there is no indication to the user how the data are to be entered?
Well, the prompt is:
Code:
Input latitude, longitude and timezone
But you have to look into the source code to realize that the input is in the form of three floating point integers: 51 degrees 30 seconds North Latitude is 51.5; 0 degrees 10 minutes West Longitude is 0.16666667. The timezone is the number of hours west of what we used to call GMT (Greenwich Mean Time), but is now called UTC (French abbreviation for Universal Coordinated Time).

Well what's left to hate about the program?

e. It uses global variables where globals are absolutely not required:

For example the variable g is a global, but it is only used in the function FNsun. Furthermore if you do "need" a global variable in some program, I would recommend that you make its name descriptive. (What the heck is "g"? Gravitational constant or what?)

f. The code is replete with "magic numbers" with no indication of what the numbers are supposed to mean and where the heck they came from. For example
CPP / C++ / C Code:
  return (double)luku - 730531.5 + h/24.0;

Anyone care to tell us what is the significance of "730531.5"? (That is a rhetorical question. I don't care to see any answers here.) How can anyone maintain this code? (Another rhetorical question.) How about "280.461", ".9856474", "357.528", ".9856003", "1.915"?

g. The code is horribly and inconsistently formatted. For example:

CPP / C++ / C Code:
  dfo = rads*(0.5*SunDia + AirRefr); if (lat < 0.0) dfo = -dfo;
  fo = tan(declin + dfo) * tan(lat*rads);
  if (fo>0.99999) fo=1.0; // to avoid overflow //

In addition to being just, well, butt-ugly, how can anyone tell at a glance what this is supposed to be doing?

Here is one way to make things a little more clear (but I concede that there are other, slightly different, formatting conventions that are equally clear).

CPP / C++ / C Code:
  dfo = rads * (0.5 * SunDia + AirRefr); 
  if (lat < 0.0) {
    dfo = -dfo;
  }
  fo = tan(declin + dfo) * tan(lat * rads);
  if (fo > 0.99999) {
    fo = 1.0; // to avoid overflow //
  }
  fo = asin(fo) + pi/2.0;

Which would you rather see? Which would I like to put my name on? Which would I give to my mom to stick on the refrigerator door along with my finger painting of the goats grazing on a hillside (she thought they were cows, but she liked it anyhow)? Which would I rather maintain when a user comes back to me and says that he thinks he is getting the wrong answer? (All rhetorical questions.)

While we are at it, what does he mean "to avoid overflow"? is asin(0.99998) more likely to give an overflow than asin(1)? Time to get a new compiler? (Another rhetorical question). If there was some problem with the code in this area was it fixed by this statement? Huh???

etc.

(If I continue enumerating the things that I hate about this program, I will run right off of the end of the alphabet, and will have to go into greek, as the weather service did when they ran out of names for storms this year.)

Bottom line recommendations (and these are only my opinion; Your Mileage May Vary):

If you want to use this program to learn about programming, clean up the formatting. Look at the use of global variables and eliminate them where appropriate. If you want to have globals for manifest constants (like pi/180 or 180/pi) then make their names descriptive. Maybe use Upper Case names.

then

Look at the "magic numbers". Find out where they came from and what their significance is. Replace them with const data names that are descriptive (or are at least include comments that specify their significance).

Change the user prompt to be more descriptive. Maybe prettify the output. (Why not do this first, so that as you test the program you can refine the input/output appearances as you change the other parts of the code?)

Test for different input data. Compare results with known values for both northern and southern hemispheres and for different time zones.

Regards,

Dave
  #4  
Old 30-Dec-2005, 09:22
kobi_hikri's Avatar
kobi_hikri kobi_hikri is offline
Regular Member
 
Join Date: Apr 2005
Location: Israel
Posts: 431
kobi_hikri has a spectacular aura aboutkobi_hikri has a spectacular aura about

Re: sunhour


Quote:
Originally Posted by davekw7x
this is a pretty good example of bad program practices

Now that you said it, I have to agree.
Those "minor" things, like this line (Why comment an empty line ?) :

CPP / C++ / C Code:

//


or this one (what does an overflow has to do with this ?) :

CPP / C++ / C Code:

if (fo>0.99999) fo=1.0; // to avoid overflow //


bugged me, but I dared not say a thing, not to be suspected as niggling.

Shabat Shalom,
Kobi.
__________________
It's actually a one time thing (it just happens alot).
  #5  
Old 30-Dec-2005, 09:36
ldn ldn is offline
New Member
 
Join Date: Nov 2005
Posts: 29
ldn is on a distinguished road

Re: sunhour


Thanks guys for your information, but I am not sure why they are so proud and put it on the internet.
  #6  
Old 30-Dec-2005, 10:10
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,703
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: sunhour


Quote:
Originally Posted by ldn
Thanks guys for your information, but I am not sure why they are so proud and put it on the internet.

1. My criticism was quite subjective, and I realize it. For some people, the program was worth sharing.

2. Sometimes we learn by setting ourselves up as a target and letting someone else take shots at us (and, maybe, giving us a clue as to how to improve it).

3. Since I don't know the nature of the posting (was it in a forum where students were showing each other their efforts? was it on a tutorial site where mentors were showing students how to solve problems? what???), I can't really guess at the motivation.

4. I learn something every single time that I come to GID forums and browse the various threads. Sometimes I get excited and I sound off (as I did in this case), and sometimes I just nod off to sleep as I try to formulate a response. Sometimes I try to improve some little corner of the world by freely giving free advice. Sometimes I give people a hard time when that's not what they really need (I'm working on trying to figure out how to help more). If you had presented this code as yours and asked for criticism, I think I would have said pretty much the same things, but I hope that I would have been a little less personal (Butt-ugly? That's pretty harsh! See the footnote.)

Anyhow, it's an interesting problem (to me, at least), and I may look into the actual math a little more. As far as criticism of the program itself, I dare say that I can go back to almost any program that I have ever written (more than two weeks ago and more than 10 lines of code), and find something that I might do differently. That's no exaggeration.

I hope that you keep up your interest. Sometimes (always?) you can learn more by looking at "bad" code than by just having an acceptable answer presented to you in finished form. You really learn by making your own program and then scratching your head if (when) it gives unexpected results and digging into the problem. If everything that I have ever tried had worked the first time I tried it, I don't think I ever would have learned anything.

Regards,

Dave

Footnote:
"We have seen that computer programming is an art, because it applies
accumulated knowledge to the world, because it requires skill and
ingenuity, and especially because it produces objects of beauty."

---Donald Knuth
  #7  
Old 30-Dec-2005, 14:25
ldn ldn is offline
New Member
 
Join Date: Nov 2005
Posts: 29
ldn is on a distinguished road

Re: sunhour


Hi Dave
this code I found it on the internet in google search you can find it in this linkhttp://www.sci.fi/~benefon/rscalc_cpp.html
I am always interset in seeing different way of code writing and thanks for anyone effort, we always learning new things in our life.
 
 

Recent GIDBlogToyota - 2008 September Promotion by Nihal

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 06:25.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.