Could someone please explain what questions I should be asking when approaching an exercise? (simple loops Q)
Posted by Slight_Total4874@reddit | learnprogramming | View on Reddit | 15 comments
I know this is quite a lengthy post, so I apologize, but would really appreciate if someone could help me.
Exercise asks -
"Please write a program which asks the user for a year, and prints out the next leap year."
Sample output:
Year:
2023
The next leap year after 2023 is 2024
If the user inputs a year which is a leap year (such as 2024), the program should print out the following leap year:
Year: 2024
The next leap year after 2024 is 2028
The model solution:
start_year = int(input("Year: "))
year = start_year + 1
while True:
if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
print(f"The next leap year after {start_year} is {year}")
break
year += 1
What I'm having difficulty with:
-
Well, I had no idea it was even a loop question;
-
I wrote code that only produced the correct outputs for the sample output but didn't work for anything else;
-
Even after seeing the solution, it still doesn't make sense to me and because of this, if a similiar question is asked, where they'll probably tweak one aspect, I'll struggle again because I don't understand how to ask the right questions and build accordingly.
I sort of managed with everything leading up to this particular question, even if I didn't fully understand/got my code wrong, after seeing the model solution, it made sense.
Tia!
SwordsAndElectrons@reddit
First ask what the requirements are.
Then ask yourself how you would do this. Explain it in plain English, or whatever your native tongue is, not in whatever programming language. You can use "pseudocode" if that helps you, but the point is to understand the process you need to implement before you get bogged down with the programming.
It's not, necessarily.
First, let's answer the how would you do it question. If your answer is that you would count up from the starting year until you found the next leap year, then a loop makes sense. (You can also do that with a series of conditionals, but a lot of people would call that kind of amateurish and sloppy.)
But you can also solve it algorithmically in a few steps. The first step remains the same. Since we want the next leap year even when the input is a leap year, we can just add 1 to start with. Then divide by 4 and take the remainder to get the number of years to the next multiple of 4. After adding that, we see if it is a multiple of 100 but not 400, and add another 4 if it is.
I'm on mobile and not testing right now, so please excuse any errors, but something like this should work too.
Literally nothing else? Hard to say where you went wrong without the code, but I guess the first thing here is to understand the sample is literally just one sample. It's meant to help understand what the intended functionality is, but just a single data point. Read the description and don't assume it's only supposed to work for that one input.
JGhostThing@reddit
The first question should be "how do I detect if a year is a leap year?" What you have used is not a valid test for leap year. Google it.
Then just loop through the years (starting at the next year or the current year, depending on the exact wording of the question), until you find the next leap year.
Leap year detection is a complex statement.
If the year is evenly divisible by four, it may be a leap year.
If the year is evenly divisible by ten, then it is NOT a leap year.
If the year is evenly divisible by 100, then it is a leap year.
Bacon_Techie@reddit
That is not the rule for leap years.
The rule is as follows:
A year is a leap year if:
It is congruent to 0 mod 4 and not congruent to 0 mod 100, except for years congruent to 0 mod 400.
Your rules would state that the year 2020 wasn’t a leap year, but it was.
JGhostThing@reddit
Well, I did say that the proper way included looking it up. I should have done that.
I haven't had to deal with leap years in over 20 years.
Slight_Total4874@reddit (OP)
thanks for your response, but the solution I included was directly from the modules 'model solution', if that's what you were referring to when you said "What you have used is not a valid test for leap year. Google it."
JGhostThing@reddit
You should really google it. The model solution is *wrong*.
Dazzling_Music_2411@reddit
Well, since you keep on trying the next year until you find a leap one, I'd have thought it was fairly obviously a loop question.
Is there some other approach that you can use, which does NOT involve loops? How did you approach it?
Dazzling_Music_2411@reddit
Actually, come to think of it, such an algorithm need not be complicated at all.
Since a "missed" leap year (i.e. divisible by 100 but not by 400) is never followed by another one, then all you have to do is advance 4 years at most from a missed one. So:
next_leap_candidate = startyear - (startyear % 4) + 4
if is_leap(next_leap_candidate) then next_leap_year = next_leap_candidate
else next_leap_year = next_leap_candidate + 4
Short and sweet, no iterations necessary
Bacon_Techie@reddit
That is pretty much how I’d implement it.
It’s more efficient than the loop too.
Temporary_Pie2733@reddit
It’s not necessarily a loop question. The sample solution is just doing a linear search of every year after the input year to find the next leap year. You can do it differently, for example output year + (4 - year % 4). (Which is not quite right, as it doesn’t handle the century exceptions, but there are only two, so they can be tested for and fixed by adding another 4 if necessary. )
peterlinddk@reddit
The question you should ask yourself, is:
"How would I find the next year that is a leap year?"
Meaning, that you would need to figure out a solution that isn't a program, but some "procedure" that you yourself should follow.
If you tell yourself, "well, I need to add 1 to the year, and then check if the resulting year is a leap year, and if not, then add another 1, and keep repeating" - then you've answered that you need to loop.
If you tell yourself, "well, I need to calculate the remainder of the year divided by 4, and add that to the year, so that I get the next year divisible by four - but if it is divisible by 100, then I need to add another 4" - then you've answered that you need a calculation, and an if-statement.
The thing is - to know how to program the solution, you need to know what the solution is - the solution to solving the problem, not the "finished program". You need to know how to do the calculation manually - and there might be several different ways of doing it. And only then can you begin to think about coding it. And again, there can be several different ways of writing the code!
Slight_Total4874@reddit (OP)
omg thank you!!! you explained it in a way that FINALLY made it click.
Immereally@reddit
If it’s AI corrected, It might be that you haven’t actually used the while loop efficiently? Set up a bool instead of true and switch it to false, reverse would be better: “”” Leap_year = false;
While (! Leap_year): “””
And just flip to true under the right condition.
Otherwise they’re looking for an actual for loop in which case you’d want:
“”” For( int add_year = 0; year %4 !=0 ; add_year++) “””
I know with cs50 they fused to check for specific conditions or functions so that might be the issue?
The break condition would get kinda long in the for-loop, so I’d probably move that to a function and return a book there also
forced_lambchop@reddit
This is a while loop. The word true is the condition. Meaning until I see false I will continue to run. What is making the code exit is the keyword break and break is only read when the if statements condition is met (once a year is a leap year) until that if statement runs it keep adding 1 to the input year. Once it's a leap year it prints the statement and breaks out of the loop.
tb5841@reddit
1) You don't need to use a loop here. You could easily do this with multiple if statements, or some other way to round-up-to-the-next-four.
2) But if the instructions want it to work for any year, your code has to work for any year. Sample inputs aren't really relevant here, you usually want your code to be general rather than specific.