However, every year, I find a small number of students who just don't seem to get it. They get through, but the CS major program becomes harder and harder for them as their four years go by. Must it be this way?
Think of it this way:
An alien lands on Earth. He sees a human, who encounters another human. The first human flips the second one off. In response, the second one flips the first one off.
The alien goes on to meet world leaders, scientists, philosophers, ... Every time he meets someone, he flips them off. After flipping them off, the alien's behavior is perfect, he makes no other mistakes. No one corrects the alien, because they understand that he's culturally unaware of its meaning and they understand that the alien is trying to say hello. Since the alien is capable of being friendly, no one is really incentivized to address that one mistake that the alien makes. It seems like nitpicking.
After the alien has met with diplomats (and diplomatically minded people), he eventually ends up in situations where there is less goodwill towards the alien's cultural obliviousness. The alien starts noticing that people are reacting less friendly towards him, even though he's still trying to use human greetings.
As time goes on, the alien struggles more and more to keep interactions with humans on a friendly level. After several years, he finally fails and ends up in a fight with an angry human.
The inept student, just like the alien, was initially in a position where little to no mistakes could be made (first year only uses simple examples, the alien only meets diplomatically minded people). The flaws of the student/alien are not big enough to fail a test/conversation.
But as the student/alien progresses through the ranks, it gets harder (harder examples, less diplomatic people). Eventually, there comes abreaking point where the mistakes of the student/alien are important enough that they do prevent a good outcome, and this is where the student/alien fails for the first time, even though they were making the same mistake all along.
As a student, it's a curse to only be somewhat inept. If you're completely inept, then teachers will focus on you and will make sure that you do it right. But if you're stuck in the "not good but good enough" zone, then you may never receive that attention from your teacher (because they're focusing on students with bigger problems), and you'll never be told that what you're doing is wrong.
When no one tells you that what you are doing is wrong, then you can't know that what you're doing is wrong (or could be improved).
Is there any evidence or reason to believe that there are students who genuinely can't learn to program?
Yes and no.
Everyone is capable of learning programming, but different people will have different levels of intuition and will learn things at a different pace.
Yes
In college, I studied Digital Arts and Entertainment. This course was unique in the world (at the time), because it was both a full-fledged course for artistic design (concept art, freehand drawing, 3D modeling) but also technical game development (programming, ranging into complex geometrical mathematics).
There were two very clear groups in our class: the artists and the analysts (I was in the latter group). The artists passed the art classes without breaking a sweat, but needed to learn programming step by step and never seemed to really intuitively understand something (e.g. int division) without having it intricately explained time and time again.
The analysts, on the other hand, were passing the programming classes with flying colors, but often couldn't manage to design or draw anything halfway decent, especially compared to the artists. They would have to redo freehand perspective drawings many times over, whereas the artists managed to get it right the first time and then had a lot of time left to improve their already succesful drawing (thus creating even more of a gap between the art that the artists and the analysts produced).
This course irrefutably proved to me that some people are wired differently than others. It was so very obvious to see it happen for every class we took. The people who were outclassing me in art class would need my help in programming class, and vice versa.
Out of the 300 students who started the course in my year (I'm already omitting those who gave up midway. 300 students took the final exams of the first year), 8 managed to pass all classes. Almost everyone else got caught up on either the art or the programming.
This was my second time in college, and I have to admit that the % of driven students was much higher than in other courses. There were <10% slackers, most people were spending their nights designing (either games or art, whichever held their fancy).
Seeing less than 3% of students pass both art and programming classes proves the point.
No
But then again, 8 students managed to pass.
I personally knew 3 of them. One had not programmed before the course, the other two had never been artistically inclined. So it's possible to learn a skill, even if it's almost completely orthogonal to your current skillset.
I'm also a strong believer in the fact that if someone does not understand something; that it simply hasn't been explained to them in a way that makes sense to them (or they haven't been driven enough to find out for themselves).
You need to investigate the ignorance.
For your current example, this does mean that we should investigate what exactly she wasn't understanding.
She couldn't identify the ending condition of the loop
There's a "spectrum" of ignorance here. It's important to figure out which one applies to this student:
- Was she aware of what a
while
is used for in general? (regardless of why it was being used in this particular example)
- Was she aware that it is an ending condition? (regardless of what the specific condition itself was)
- Was she aware that this was a boolean evaluation? (regardless of what was being evaluated)
- Could she explain the evaluations (evaluating if a number is bigger than another number) but not the combined intention of both evaluations (evaluating that the number was between a lower and upper bound)
Based on which of these describes her situation (or something I didn't list), you can work towards filling in the gaps in her knowledge.
To use my college example, if she has an artist's mindset, she may never be able to intuititively understand code and read it like a second language, but given enough effort, she should be able to eventually identify what happens.
Without making this a personal attack on you, I think it's important to consider that when a teacher considers a student incapable of something, that this could also mean that the teacher is incapable of teaching it.
As the teacher, you can never be sure which one it is.
This is a variation on the Dunning Kruger effect. If you apply the principles of the effect, that means that it's possible that a teacher's evaluation of a student's incapability to learn something may simply be a misinterpretation. The teacher doesn't know how to teach this student effectively, and therefore considers the student flawed, instead of their own teaching ability.
This can be subconscious and is in no way malevolent on the teacher's part.
From my experience with teaching programming (and being taught programming), the most effective way to gauge student skills and also teach them how to read code is to play the breakpoint guessing game.
In essence, put some breakpoints in the code (this can be on every line if you want), start the program, and have the students try to predict what the next breakpoint will be.
Note: this is very easily gamified. People love betting, so allowing them to bet on the outcome teaches them to figure out what the outcome is.
For a student who is vastly underskilled and not getting it (as you suspect this student is), you'd expect an inability to make any reasonable prediction, or continuously stating that the next step cannot be predicted.
Step through the whole program. Keep repeating the same code over and over again, until she makes accurate predictions (even if she's only reciting it from memory rather than understanding).
Once she is able to recite the steps, change one thing in the code (e.g. one of the numbers in the while condition). Repeat the breakpoint guessing game.
If she actively disagrees with what you say the next breakpoint will be; that's a really good thing. This means that she has an opinion about the flow of the code. Ask her to justify her claims. Do not correct her, just get her to clearly express her own thoughts. Find the error in her claims, but don't point it out.
Instead of correcting her, show what the next breakpoint is. Ask her to explain why the outcome is different from what she said. Only explain things once she gives up with explaining, or is clearly saying random things and hoping to get lucky.
As a software developer, I notice every day how often I spend talking to myself about how the code is going to flow. This is a quintessential skill for a programmer. If you're too quick to explain, you're effectively preventing her from trying to think for herself. The idea is that she shouldn't rely on what others say, but rather try to find the answer for herself.
Every person should be able to understand the logical flow of a simple code snippet, given enough repetition of the guessing game. Every human is innately able to distinguish and recognize patterns (even if they can't do it intuitively).
Everyone is capable of learning programming, but different people will have different levels of intuition and will learn things at a different pace.
The only people who actually cannot be taught something, are the people who do not want to be taught something (or do not want to put effort in learning). As long as she wants to understand it, she eventually will.