Each month I shall look closely at one program - at its merits, at how it can be improved, and at what certain commands do. The listing need not be lengthy, just well structured, interesting and simple to follow. Remember last month I said that logic plays an important part in computer programing? Well, this month's listing, Week-day, is riddled with ANDs, ORs and IFs. Enough waffle -let's find out how the program works.
A clever listing from Gary Nugent of Churchdown, Dublin, determines the weekday of any given date. This works with any year BC as well as AD. Enter years BC as negative numbers, although the day and month remain positive.
There was no year 0. The mathematical concept of zero displaced Homan numerals many centuries after Constantine's decree that years were to be numbered from the birth of Christ which was about 300 years ago by then, and they were out by at least four years. Anyway the years jumped from 1 BC to 1 AD. The program accounts for this and leapyears. It also works for both Gregorian and Julian calendars.
Enter the date in the form day, month, year. For example, to find out the weekday of June 23. 1986, then enter 23,6, 1986 at the prompt. Year must be in full: typing 86 will land you near Nero.
Rememberer to REM
1 ' Weekday
2 ' by Gary Nugent
3 ' Amstrad Action July 87
Label your listing. Identify what each section does. It makes it easier for everyone concerned. Gary's program is short and therefore does not need many RE Ms. Indeed the majority here are the credits at the top of the listing - which will remind you six months from now where to find all these explanations.
110 DIM day$(6)
120 FOR i=0 TO 6: READ day$(i): NEXT i
130 MODE 1: BORDER 0:INK 0,0:INK 1,26:INK 2,24:INK 3,6:CLS
140 WINDOW #0,1,40,2,25: WINDOW #1,1,40,1,1
150 PAPER #1,1: PEN #1,3: CLS#1: PRINT#1,SPC(16);"Weekday"
160 LOCATE 3,7: PAPER 3: PEN 1: PRINT"Enter date: ";
Restoring your work
The first line of Gary's program, DIM day$(6). would be necessary on many home micros. Not. however, the Amstrad. Why? Well, as you'll remember from last issue's discussion of arrays. Arnold automatically dimensions a 10-item array. There is no need for you to do this. Gary has dimensioned a string array capable of holding seven items - superfluous, although it does make the listing more intelligible.
Line 120 loops from 0 to 6. As it does this, it READs in an item of DATA and places it in one of the free spaces provided by the array, day$. The data it reads is held in lines 270 and 280. The computer automatically searches out the data so you don't have to specify where it is. The only occasions when you'd need to tell the computer where the data lies (with the command RESTORE line-number) is when you have lots of it scattered throughout the program, or when some of it is to be used more than once in the same run. The RESTORE command can also simplify debugging. Imagine you had loads of READs and DATAs in your listing. How could you tell which set of data was being read? You couldn't. Use RESTORE Iine number. In this case it would be RESTORE 270. If you peer at line 270 you'll notice "Sunday, Monday. Tuesday..." We now know what day$ does - it contains the names of the days of the week.
All the other lines in the section deal with setting up the colours and screen mode. Windows are also defined to highlight certain bits of text They act like individual screens. The parameters following WINDOW are window number (between 0 and 7) , left side of window, right side, top of window and bottom. You must place a hash (#) before the window number. Once a window has been defined, you can PRINT #windownumber, INPUT #windownumber, PAPER #windownumber, CLS #windownumber... Very useful.
170 PAPER 0: PEN 2: INPUT" ", day, month, year
180 IF month>2 THEN yy=year: mm=month ELSE yy=year-1: mm=month+12
190 y1=year-INT(year/4)*4: y2=year-INT(year/100)*100: y3=year-INT(year/400)*400: ly=(y1=0 AND y2<>0 OR y3=0)
200 IF year=0 OR month=0 OR month>12 OR day=0 OR day>31 OR ((month=4 OR month=6 OR month=9 OR month=11) AND day>30) OR (month=2 AND day>28-ly) THEN LOCATE 3,9: PAPER 2: PEN 0: PRINT" Invalid Date ";CHR$(7): GOTO 260
210 IF day>4 AND day<15 AND year=1582 AND month=10 THEN LOCATE 3,9: PAPER 2: PEN 0: PRINT" Date did not exist ";CHR$(7): GOTO 260
220 IF year>1582 OR (year=1582 AND month>10) OR (year=1582 AND month=10 AND day>14) THEN a=INT(yy/100): b=2-a+INT(a/4) ELSE b=0
After you have told it the day. month and year with INPUT, the program, starting from line 180. will set up some variables according to your input. The expression y1=year-INT(year/4)*4 in line 190 can be simplified to y1=year MOD 4. The other formulae in the line could similarly be reduced in size - and , by the way. in execution speed. All do the same thing: the answer is the remainder after dividing year by a certain number. If you see. say. 7 MOD 2 or 7-INT(7/2)*2 you should be able to determine the result , 1, without too much trouble.
The reason for all this kerfuffle is to check if year is a leapyear. Leapyears occur if the year divides by four. But there are exceptions (and this is the correction the Gregonan calendar made on the Julian, because it was found that the year is not 365 1/4 days long but 365 days, 5 hours , 48 minutes and 46 seconds). Years that divide by 100 are not leapyears unless they also divide by 400.
That's the meaning of the last statement in line 190:
ly = (y1=0 AND y<>0 OR y3=0)
Looks a rather odd equanon at first, doesn't it? Puzzle through the right-hand side by thinking "true" or "false" for each part Then convert a final result to a number: "true" is -1. "false" is 0. So ly ends up as 0 or -1 depending if year was normal or leap. In other words, there are two possibilities that produce a leapyear:
- y 1 (which is year MOD 4) equals zero at the same time as y2 (which is year MOD 100) does not equal zero
- y3 (which is year MOD 400) equals zero.
In these cases the result for ly will be -1 (a leapyear). If any of these results prove to be opposite then year is normal. Phew!
As you can see from the last paragraph, it is much easier to manipulate logic by using mathematical shorthand than by waffling on in English.
The Pope's patch
Lines 200 and 210 aren't much easier to follow. They both check that the date you entered exists and is legal. The first line checks that neither the year nor month equal zero or the month is greater than 12. It then looks to see that the date is not equal to zero or greater than 31 or greater than 30 if the month happens to be 4, 6 , 9 or 11. If any of these possibilities fall true or the month is 2 (February) and the day greater than 28 (29 for a leapyear) then the program throws up the message “Invalid Date."
Pope Gregory XIII made life interesting by decreeing that in 1582 ten days would be skipped to get the calendar back into step with the seasons. Some poor sod will have missed his birthday, because 15 October came immediately after the 4th that year Line 210 makes sure that you haven't typed one of these dates in. If you have then it chucks you out saying, “Date does not exist ”
Complication. Lines 210 and 220 above are correct for Catholic countries. But Protestant and Orthodox countries protested. This resulted in considerable calendar confusion for centimes. Not until September 1752 did England follow suit - and by then had to lose 11 days to match up. Russia stuck to the old calendar till after 1917. which is why the October Revolution took place in November. If you wish the listing to work for historical British dates then alter as follows:
205 REM Calendar correction in England
210 IF day>2 AND day<14 AND year=1752 AND month=9 THEN LOCATE 3,9: PAPER 2: PEN 0: PRINT" Date did not exist ";CHR$(7): GOTO 260
220 IF year>1752 OR (year=1752 AND month>9) OR (year=1752 AND month=9 AND day>14) THEN a=INT(yy/100): b=2-a+INT(a/4) ELSE b=0
250 LOCATE 3,10: PAPER 2: PEN 0: PRINT" That was a ";day$(dd);" "
260 PAPER 0: PEN 1: LOCATE 1,23: END
270 DATA Sunday, Monday, Tuesday, Wednesday
280 DATA Thursday, Friday, Saturday
Finally the last few lines of the program. Lines 230 and 240 calculate the weekday from the data you typed in earlier. Line 250 prints the weekday and line 260 returns you to the Ready prompt.
|★ AMSTRAD CPC ★ DOWNLOAD ★|
|★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...|
|QUE DIT LA LOI FRANÇAISE:|
L'alinéa 8 de l'article L122-5 du Code de la propriété intellectuelle explique que « Lorsque l'œuvre a été divulguée, l'auteur ne peut interdire la reproduction d'une œuvre et sa représentation effectuées à des fins de conservation ou destinées à préserver les conditions de sa consultation à des fins de recherche ou détudes privées par des particuliers, dans les locaux de l'établissement et sur des terminaux dédiés par des bibliothèques accessibles au public, par des musées ou par des services d'archives, sous réserve que ceux-ci ne recherchent aucun avantage économique ou commercial ». Pas de problème donc pour nous!
CPCrulez[Content Management System] v8.7-desktop/cache
Page créée en 146 millisecondes et consultée 282 fois
L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.