Is a loop an example of abstraction?

So I’m giving feedback to my students’ written responses from this practice PT and several of them wrote about loops as an example of abstraction because it makes code more efficient. Here’s an example:

“An abstraction would be the for loop that was used to make multiple sound waves in the program. A for loop runs the code that is within it until the variable, that was declared within the loop, does not fulfill the condition that is given in the parameters for the for loop. Using a for loop helped us reduce the amount of lines in the program because it ran the code without us having to copy and paste multiple times.”

This student seems to be responding to the fact that this loop helps ‘reduce the complexity’ of his code because he doesn’t have to ‘copy and paste multiple times’. I’ve been responding that this helps makes his code more efficient, but actually doesn’t address this complexity issue.

Thinking about the actual AP task - a loop isn’t an example of an abstraction, right? And when it asks about reducing complexity, the AP is looking for responses more aligned to how it helps organize/partition/group together lower-level code into something bigger, right?

Yeah, calling a loop an example of abstraction is probably not right. Your response is good. Let me ramble here a few more thoughts that might help you (and your student(s))

  1. First, let’s just get this out of the way: for all practical purposes when it comes to the AP Performance Task “abstraction” means a “function”. So you are never wrong to point to some function you wrote, call that the abstraction, and explain what it does. (There are other things you might “abstract” but the easy one is always a function).

  2. There is a particular nuance to “reducing complexity” that is part of an abstraction that I think is missing from your student’s response – and that is about hiding unnecessary or complicated details. “Unnecessary” here means unnecessary for understanding what the code is doing.

  3. related - Another typical property of an abstraction is that it nicely “encapsulates” a solution to a problem, and presumably that solution can be re-used and applied to other larger problems or in other contexts without having to worry about the inner details. Once you have encapsulated a solution to a problem it’s specific details can be put out of mind, freeing your mind to solve more complex problems.

Here is an example – Take this code, something akin to your student’s loop, I assume.

for(var i=0; i<4; i++){
    moveForward(100);
    turnLeft(90);
}

In some sense this loop makes the code less complicated than it otherwise would be because without the loop you’d need many more lines. But as a reader of this code, to understand what it’s doing, I have to consider the details, I have reason about it, and mentally trace it out to figure out what it’s doing. Now if instead the line of code were:

drawSqaure(100);

I don’t even have to think it all to understand what this is trying to do. It reduces complexity because it hides details about exactly how the square is being drawn - really it doesn’t matter whether this function is implemented with a loop or not if what I care about is drawing a square - which makes it easier for me to reason about and furthermore to use the drawSquare behavior in other code that needs square-drawing.

drawSquare is a very small example, but when faced with programs or problems where the code is really complex and tough to reason about, bottling it up into a well-named function really helps. And also, loops usually complicate code because they are hard to reason about.

Here’s another example to prove my point. Imagine you’re reading along in some code and you come across this chunk that uses a loop. Try to figure out what it’s doing:

var newStr ="";
for(var i=0; i<str.length; i++){
    var ascii = str[i].charCodeAt(0);
    if(ascii >= 97 && ascii <= 122){
       ascii-=32;
    }
    newStr += String.fromCharCode(ascii);
}

Now what if instead, you were reading along in some code and found:

convertToUpperCase(str);

Even if I am an expert and can read the first code segment and figure out what it’s doing in 5 seconds - it’s NOT abstract. It’s a very concrete, explicit process for converting characters to upper case. It takes some amount of brain power to figure it out. Whereas, that same code encapsulated in a function convertToUpperCase it takes me no time to understand and I can use my brain for other things, like whatever larger task I need this case conversion for.

I think it’s fair to say with abstractions there is a bit of a you-know-it-when-you-see-it kind of thing that comes with experience and is hard for the new student to grok. And it’s hard to define because you can start to go down the rabbit’s hole with abstraction - let’s not forget that EVERYTHING we do on the computer is an abstraction in some sense - the whole machine is an abstraction. You’re seeing characters on the screen that are being represented by pulses of electricity behind the screen.

I hope this helps.

9 Likes

In a non-computer explanation of abstraction, we talk about driving a car. We don’t need to know how the engine or gears work, we accept that they will do their job. I then get them to come up with other examples. I know it probably seems a bit simplistic, but I can then extrapolate on to code etc and they seem to get it easier.

4 Likes

I really like using the car to help explain abstractions. Tapping into their life experiences is a great idea!

1 Like

For real life analogies pretty much anything that has a simple user interface to operate something that is mechanically or electronically complicated - car, elevator, tv, microwave, etc. - will work.

They are good for introducing the idea. But programming involves a bit more, so your explanation might eventually evolve to something like this:

One of the reasons you can operate a car without having to know how it mechanically works is because its purpose is very clear. The purpose of a car is to get you from point A to point B. Because you know that fact it makes it intuitive to operate because the abstractions presented to you map to the fundamental things you need to do to get from point A to point B safely - go, stop, turn.

Programming is a little different because it’s less intuitively clear what the fundamental purpose of a computer is. This makes it harder to apply or combine the abstractions because you don’t know where you’re going, so to speak. The fundamental purpose of a computer, by the way, is to process information, but what that information is and how it needs to be processed is an abstract undertaking in and of itself.

So programming is often about combining known abstractions or building your own to solve problems. In programming most abstractions are a procedure of some kind, and each procedure is intended to solve a single problem.

So back to a real world analogy:

Say that your problem is that you need to microwave some popcorn, but the only microwave in town is on the 10th floor of a building downtown. To solve this problem you decide to: drive your car downtown, get in an elevator up to the 10th floor, and use the microwave. Thus your procedure for microwaveThePopcorn involves combining your knowledge of using the abstractions that let you operate several single-purpose devices: your car, an elevator, a microwave.

Now in programming when you give this procedure a name like microwaveThePopcorn you can put out of sight and out of mind the complications you had to go through to solve it, and you can use it and treat it as though it’s also a single-purpose function. So microwaveThePopcorn can be used as a part of a solution to some other larger problem like: preparing to have friends over for a movie.

I hope that’s helpful.

Baker

1 Like

Hey Baker,

I noticed you ended both of your responses with ‘Hope this helps’.

FYI - I copy-and-pasted your first response verbatim and gave it as part of a larger piece of feedback to my students, then had us discuss how this idea of reducing complexity differed from the ones they gave in their written responses. The consensus was that this was incredibly helpful in clarifying what the prompt is looking for in responses and how to better organize their code. I’m on the next round of revisions for their responses and they’re exponentially better than the first round.

So - I can say with confidence that your response tangibly helped my students better understand the prompt and improve their writing. Thanks for the in-depth response.

4 Likes

Ha ha! Great to hear! Thanks much. Glad it worked out.

1 Like

Grading a PT in which a student identifies a loop as an abstraction. I’m letting it slide grade-wise this time because I never mentioned the distinction and I myself was confused whether it should count. Your explanation was informative and I’ll make sure to bring it up with my students in the future so they understand better the concept of abstraction.

1 Like

I told a student to put his loop that calls his function multiple times into a call ALL function. I still can’t decide if this would count as calling it multiple times.

Not speaking from a scoring guide interpretation, but IMO it doesn’t count as calling it multiple times.

I would ask what benefit or simplification does it provide? I see the benefit more specifically from calling it from multiple locations in the code.

One advantage of using a function called from multiple locations is that you don’t have to copy/paste the code into those multiple locations and that if you change that piece of code, you don’t have to change it for every instance.

In the instance you mention, I don’t see any of those advantages. There’s an advantage of using the loop, but it seems the student could replace the one function call with the function definition and there would be no future advantage or disadvantage when he needs to tweak the code.

I would give the points to a student that calls a function in a loop but moves to a different location before calling the function or passes a different parameter each time since each time it is called, the behavior is slightly different. In the example beach scene project, this is what the “student” does in lines 94-97.

As for why you would call the function in the loop instead of just using the code, I think that helps from an abstraction point of view since the function name should make it clear what that chunk of code would do whereas just including the actual code would require a reader or another programmer figuring out how each line works.

I don’t know if that is how a AP reader would grade, but that is what I’m doing for my class.

1 Like

Hi @lynn.garnaat! :smiley: Nice seeing you on the forum!

As for why you would call the function in the loop instead of just using the code, I think that helps from an abstraction point of view since the function name should make it clear what that chunk of code would do whereas just including the actual code would require a reader or another programmer figuring out how each line works.

Great point! I’m also unsure if this counts AP-wise, but I would give it to my students, especially if they were able to identify this idea and communicate it as clearly as you did.

Frank

I know this is a slightly older topic, but it most relates to my question.

Would a for loop inside a function show Mathematical and Logical Concepts? I would argue that it is a mathematical concept.

Hi @glenn.crane,

I think it could work. You can see some examples here with commentary. You will notice that row #5 seems pretty easy for the examples to get. I would especially say that if the student SAYS it uses math by adding 1 to the variable inside the for loop and checking IF the condition is true, then they should get it for talking about math and logic there.

With most of these, if you write convincingly, that is most of the work!

Happy programming!
KT

Hello. I know that this is older but I’d like some help. I have a student who made this function:
// Draw top of grass
function drawTopOfGrass() {
for (var i = 0; i < 60; i++) {
turnTo(0);
moveTo(randomNumber(1, 500), 420);
moveForward(25);
}
}

But they only called it once, and it clearly has no parameters. My instinct is to say that this is NOT a student developed abstraction, as the function actually serves no purpose, and putting the loop inside it actually adds lines to their program, rather than simply adding the loop.

Would that align properly with AP guidelines and other’s thinking?

Also, I know that they can still get the point for managing complexity even if it is not a student-developed abstraction. Would this response get that point? I have trouble interpreting that point:

This program code segment contains an abstraction because it’s calling a function that contains lots of programming in order to draw the top of the grass as well as using a loop to draw multiple pieces without writing out the code every time. It is called 60 times within the loop; therefore, giving us the ability to not have to write out every piece of code that is defined in the function. This abstraction helped manage the complexity of my program because without it, our group would have way more than 171 lines. Considering the draw grass function would be written out in code 60 times in order to run how it is coded as of right now with the loop and the function.

Hi Kaci - here are some quick thoughts:

I’m 100% positive this function would earn a point for being a student-developed abstraction, since it’s a function that the student created themselves. The “student-developed abstraction” tends to be a very earnable point as long as students are clear that they need to create their own function rather than identify a language-supplied function.

I’m 90% sure their explanation of how it helps manage complexity wouldn’t qualify for the reasons related to the genesis of this post - that ‘reducing lines’ isn’t always the same as managing complexity.

However, this doesn’t mean this student can’t write about this particular function; I just think they’re focusing on the wrong aspect of it. For example, this function is well-named and communicates its purpose clearly. It also looks like it may be part of a larger collection of functions - I wonder what the rest of their code looks like and if it takes advantage of top-down design. Maybe this function is part of a collection of functions which, when taken together, make the code easier to read & compartmentalize because each component piece of the picture is broken into functions, making it easier to test code and find bugs. If that’s the case, then this student could probably still write about this function, but with the focus on how it helps organize their code rather than on how it helps reduce the number of lines.

Sometimes a useful line of questioning from me to a student is: you made a decision to make these lines of code into a function. What was your motivation for doing that? Why did these particular blocks of code deserve to be made a function, and how did that make it easier for you - as a programmer - to write your program? The thoughts that come out of this conversation usually lead into what they can write about for managing complexity.

Thanks for your thorough response!

So even if the code ends up adding extra lines because they’re adding something to a function that doesn’t need to be in a function (i.e., it’s not called more than once, it has no parameters, etc.) it can still be considered at abstraction
if they’re using it for organizational reasons? If it helps their be more readable for them?

Thanks again!

Kaci

It’s a very fuzzy line and I wouldn’t encourage students to set that as their goal - definitely having parameters and using it more than once is best. And (you reminded me): what you’re describing is the baseline requirement for the updated Create Task requirements starting in 2020-2021. So, this is the last year we’ll even be able to have this particular conversation =)

Here’s my take (which could be off-base - hopefully other knowledgeable folks will chime in too): I think a good way to tell if it meets the requirements is what point in the process they decided to make it a function. Perhaps this student started with all their code chunked together in one big clump (kind of like this) and then, partway through, became frustrated with how often they needed to re-read and re-remember what each piece of code did so they decided to organize their code into functions to make it easier to read & debug (kind of like this). Creating a function for organization & clarity as a way to solve a problem of disorganization & to make it easier to add features or debug would earn the point if this is the authentic reason they decided to do this. This also touches on the broader concept of abstraction - hiding details that become part of a solution to a larger problem. If this function helped make it easier to focus on those larger details without worrying always having to remind themselves “What was this loop doing again?”, then it definitely helps manage complexity.

But, if the student just decided to throw a loop into a function at the very end of their process so they could earn this point, they’ll have a really tough time explaining why it helps manage complexity because… well, it doesn’t - that’s not why they made the function in the first place.

Other folks might have other thoughts on this too, but that’s my 2 cents

2 Likes