254
votes

I have some computer science students in a compulsory introductory programming course who see a programming language as a set of magic spells, which must be cast in order to achieve some effect (instead of seeing it as a flexible medium for expressing their idea of solution).

They tend to copy-paste code from previous, similar-looking assignments without considering the essence of the problem.

Are there some exercises or analogies to make these students more confident that they can, and should, understand the structure and meaning of each piece of code they write?

8
  • 8
    Commenters: Do not leave an answer here in the comments. Write your own answer. Comments are not a venue for discussing various possible answers to the question: either put forth your suggestion as an answer or take it to chat to flesh it out first.
    – user8
    Commented Nov 30, 2011 at 21:54
  • 50
    Whenever academia get's on here - I become concerned for my future... I just imagine being on a Boeing 7-28-7 and the Turbines spinning at 200,000 RPM running on control software written in C by one of your barely passing students... Anyways I digress.
    – Ben DeMott
    Commented Dec 1, 2011 at 8:22
  • 67
    Have you considered FAILING them a couple of times, not everyone is cut out for software development! They aren't all special snowflakes!
    – user7519
    Commented Dec 1, 2011 at 21:14
  • 6
    Isn't SICP kind of famous for saying that programming is analogous to spell casting? I mean, I doubt your students are quoting SICP or even making a comparison akin to what Abelson and Sussman were trying to portray, but I don't see how it's inherently wrong that someone compare program writing to spellcasting, when one of the most famous computer programming books out there does the exact same thing in the first couple pages.
    – Robbie
    Commented Dec 1, 2011 at 22:38
  • 9
    Eric Lippert has a lot to say regarding this subject. And in a much more elegant and concise way than I possibly can: blogs.msdn.com/b/ericlippert/archive/2004/03/01/82168.aspx Commented Dec 1, 2011 at 22:38

33 Answers 33

118
votes

You could present them a series of exercises, each one building on the previous while adding some extra element or twist to the problem, or investigating the issue from a different perspective, which reveals a weakness of the previous solution, requiring a new, different approach. This forces them to think about, analyse, modify and experiment with each solution, instead of just copy-pasting a ready-made piece of code.

Another possibility - although not strictly a programming task - is to ask them to estimate various things. E.g. how much water flows through the Mississippi delta per second? Such questions don't have a set answer, especially because one needs to make certain assumptions to get to a convincing (range of) value(s). And - although answers to many of these "classic" ones can be googled indeed - you can easily make up new ones which aren't (yet) found anywhere on the net.

Examples to both of these kinds of exercises can be found in e.g. Programming Pearls by Jon Bentley. Also The Pragmatic Programmer has some good challenges.

A third kind of task would be to present them some piece of code with (one or more) bugs in it, which they must find and fix. This again forces them to use their analytical skills and reason about how the program is actually working.

Update

Feedback from a comment by Billy ONeal:

The problem with the "series of exercises" is that students who have a problem with an earlier exercise are completely screwed for remaining exercises.

You are right, although I feel this is more about the general problem of setting course difficulty to the right level / grouping students of similar skill level together. Moreover, one can arrange the students into smaller groups where they are required to discuss and debate about the problems and solutions, and solve the problems together. If someone doesn't get it, the others can help (this setup would improve teamwork skills too). And if someone tries to be lazy and let the others do all the work, it is surely noticed by the teacher (who is supposed to be walking around, supervising and mentoring the students, not playing WoW on his laptop in the corner ;-)

And one can also adjust the exercises to accommodate students with different skill levels. Beginners can go slower, experienced ones faster.

1
  • I would add to this nice answer a link to a simple website, that, IMHO should be set as a complement to courses : http://projecteuler.net/ this is THE website to stimulate their appetite for code. It has increasing difficulty problems that have to be solved with the language they want. First, it is addictive, and it also stimulates competition : you can follow their progress through their accounts, they can do it too.
    – Nicolas C.
    Commented Mar 17, 2012 at 11:10
139
votes

You are battling the students' balancing act of their need to care about your subject and their need to get passing grades. Many students feel that:

(Get it Wrong || Experiment) == (Failing Grade && Waste Time)

As soon as a student feels that their time or grade is at risk, even for an interesting subject, they stop learning and jump straight to "I don't care, just give the teacher the right answer". Your students are trying to cut corners (or so they think) by thinking as little as possible about the problem and just hacking away at it by copying and pasting.

Here are my suggestions on how to deal with this:

  1. Use the Bob Ross method: Prove to them that it is both possible and faster to start anew vs. copying and pasting. Create new programs before their eyes during class - really show them that programming can be like painting a picture.
  2. Provide assignments that require creativity. For example, have each student create their own data structures (what are the objects required to create a Zoo, Pet Store, Town, College etc.) on paper to use throughout the course. Assignment #2 can be converting those structures to classes or objects, etc. Basically, entice them into thinking abstractly - reward them for being creative, and then reward them for turning their creativity into a computer program.
  3. Use the least amount of syntax possible. Boilerplate stuff like creating classes and language syntax is so prevalent in the introduction of programming that it often misleads students into thinking that all of programming is just knowing where to put curly braces - they don't realize that what is in the middle of the curly braces is where creativity flows. Pick a simple language, and provide sample files (such as an empty class file) for the students who still want to copy and paste something. You can gradually become more strict about syntax and compilable assignments as the course progresses.
11
  • That should be && - though I suspect it might also succeed as a bitwise operation.
    – tvanfosson
    Commented Nov 30, 2011 at 20:39
  • I don't really know what the data looks like, but yes a bitwise operation is what I intended. Good catch :-) Commented Nov 30, 2011 at 21:34
  • 3
    "what is in the middle of the curly braces is where creativity flows" ==> oops he/she won't teach them Python then... Commented Dec 5, 2011 at 7:55
  • 3
    Another problem with with just trying to give the teacher the 'right' answer instead of learning, is that people often think that's learning. E.g. lesswrong.com/lw/iq/guessing_the_teachers_password
    – Wilka
    Commented Dec 7, 2011 at 9:57
  • 6
    And then I'm going to add a few happy semi-colons here... Commented Feb 17, 2013 at 10:42
44
votes

Several things that come to my mind:

  • Give them assignments where they actually have to explain the code someone else (you) wrote. Understanding of the previous code or more specifically lack of it is both the largest cause and danger of cargo cult programming. Ask them to use comments, line by line if necessary, to explain your program in plain English (or whichever human language you use).

  • Only after they've explained the code, ask them to modify it in order to make a certain change. For example, if you gave them a sort function that sorts descending, ask them to make it sort ascending. Or something more demanding. But make sure it's something that requires understanding of the given code.

  • You can, if you like, put some easter eggs in code. A line or two that does nothing useful or even related to the problem at all. Give them a hint that such lines exist and grant extra points to those who remove them.

  • Then and only then you can give them an assignment to write a piece of code from scratch on their own. At this point they should have a much better understanding of what code really is. They might even find it a little easier to do it themselves.

The basic idea is that programming is not just writing code, it's also reading it. Reading code should also be taught.

2
  • 4
    The easter egg idea seems like it would also be a good way to teach testing/verification. Along the lines of "wat can be removed without breaking any of the contracts?"
    – Neil N
    Commented Dec 1, 2011 at 22:26
  • 3
    +1 to reading code. I see a lot of guys fixing bugs by making an intuitive guess and then seeking out to prove it. I find that reading the code provides clues that take to you the right solution. It sounds obvious, but I see it neglected a lot.
    – Chris
    Commented Dec 4, 2011 at 21:25
37
votes

Look at it in another way. This cargo-cult phenomenon is the novice stage of the Dreyfus Model of skill acquisition. This is how we learn. When I first learned to program, all I was doing was typing in pages of code from the back of Compute! magazine. Repetition is key. Babies learn to talk by copying the sounds they hear their parents make. Everything we learn is through imitation. We just have to be taught how to go from imitation to mastery.

The problem you have is your students aren't repeating anything, they're copying it from the Internet. There is some benefit to that but gains are minimal. The act of actually typing out the code is what got me to a place of understanding. I started to see patterns in what I was typing and gained an understanding of what I was doing.

One option is to structure your lab as a code dojo. Have students take turns pairing with each other on the same problem. Pick a problem that takes about 10 to 15 minutes to solve. Repeat that problem over a few labs and introduce a new twist to the problem as the class' proficiency grows. Perhaps start the lab by having the students watch you program the solution, and have them repeat it. Switching pairs with each iteration.

For your tests have a code kata where each student works through the problems from the semester in front of the rest of the class. Focus not only on correctness but form and creativity. I think this would provide a deeper understanding of how to program than giving take home assignments.

4
  • "When I first learned to program, all I was doing was typing in pages of code from the back of Compute! magazine.": This was my very early stage when I was using a Commodore Vic20 for running small toy programs and it soon became very boring. I soon developed the opposite attitude: write yourself even the code that you could copy from somewhere else, otherwise you'll never be sure what is really going on in the code.
    – Giorgio
    Commented Dec 1, 2011 at 8:29
  • One of our teachers would give us assignments to copy an assembler program he gave us and he required the copy be made with our own handwriting. He also wanted us to write our names at the first page before him so he could check that the handwriting is ours. That assignment took me about 3 hours.
    – sashoalm
    Commented Dec 1, 2011 at 13:34
  • 1
    A distraction free environment like Jon Jagger's Cyberdojo can be excellent for this, and setting up your own server is as simple as downloading the virtual machine or source from github.
    – Mark Booth
    Commented Dec 4, 2011 at 14:01
  • @giorgio I was 8 at the time. My skill level was "type this in get a free game" Commented Mar 10, 2013 at 6:58
25
votes

I have taught introductory classes in the past and as I recall looking back now:

Some students think programming is like that for different reasons. I remember once a good kid that cargo-culted a lot what I did:

Believing that it was not an isolated issue, but other students in the same class might have similar behaviour or approaching to the problem and not express it, I was always addressing the class.

  1. Some time was spent to explain some stuff such as determinism, which meant for them that in the same environment with the same data and code, they will have the same results (dispell the "randomness"),

  2. Since problem solving is up to what the student's actions and not anything else, the attention should be in solving the problem and not finding the right spell,

  3. They are in an education environment, so the problems are crafted in order to offer a learning experience, the outcome is to learn how to program (or in some cases like classes for System Administrators, how programs work, which is different) and not to give me a solution. ("World does not need another calculator, it is an exercise"), so their problems could be solved with the materials available (example: notes provided),

  4. I think it is in Code Complete: "Even if you copy and paste, the code is yours". If someone did it, it should not be cargo-style. Every line had to be explained to me (individually) or to another student (same) or to the class.

0
23
votes

Did your students start at the correct 'abstraction level' at the beginning of the course? E.g. a homework that introduces them to the main programming structures like loops and conditionals without writing a single line of code?

When I took intro to programming, our first assignment was called 'Rick the Robot'. We had a piece of paper with an aerial map of a city with interesting points, like banks, grocery stores, etc... We had a dude called 'Rick' and had actions like 'take one step', 'look left', 'look right', 'cross the road' and we could use things like 'repeat' and 'if something, then do something'. (This is not 100%, as I could not find this assignment) The idea was that Rick could only use what he was given and he had to get to different places on the map.

This was a fun exercise and something that introduced you to the basics (which are sometimes the hardest to grasp to newcomers). There is no one good answer to this problem (its a game) and there are no solutions to copy and paste from. Something like this might also allow you to play with their creativity a bit more without intimidating them with code.

Finally, the idea is that you start with the abstract and move towards the concrete. They cannot copy paste abstract. They have to understand it to solve a problem.

10
  • 3
    Loops and conditions? I'd start them off with variables, assignments and expressions. Have them read two numbers off the command line and add them, then print the result. Often doing something almost painfully obvious gives students the confidence that they can understand what's going on, and encourages them to experiment.
    – TMN
    Commented Nov 30, 2011 at 13:44
  • 2
    @c_maker: Your assignment looks like a game for pre-schoolers. Giving your students too easy tasks can only decrease their interest in the subject. Commented Nov 30, 2011 at 14:13
  • 2
    @c_maker: I think your answer has merit, I just didn't see how to move from while not at-corner do take-one-step end to actual code without "backfilling" on things like variables and data types. Apologies, my response does seem a little harsh on reflection.
    – TMN
    Commented Nov 30, 2011 at 15:01
  • 7
    I think the main value behind Rick the Robot is not in helping to understand loops, if statements, etc. The main value is in helping them understand the general process of how to write a program. It helps them see problems in a specific, step-by-step, algorithmic way. Once they understand the programming process in English with an example like this, then you can fill in the details by teaching them what the code looks like. This is a brilliant idea. +1
    – Phil
    Commented Nov 30, 2011 at 17:21
  • 1
    Reminds me of my introductory course (30 years ago!), which was based on [Karel the Robot](en.wikipedia.org/wiki/Karel_(programming_language). (Note: the link fails because the actual url has parens in it. Click the first option on the page that does come up.) Anyway, Karel used a Pascal-like syntax, but not too much of it.
    – JeffK
    Commented Dec 1, 2011 at 21:44
20
votes

What you're asking them to do is demonstrate analysis and synthesis in the cognitive domain of Bloom's Taxonomy, where they're currently only demonstrating application.

Unfortunately, it's sort of a "lead the horse the water" type of situation. Analysis and synthesis are also very difficult to do when you are still struggling with comprehension. Without the comprehension in place, analysis and synthesis activities are going to act more as weed outs than learning activities.

My personal opinion is that it's okay not to expect anything more than application in intro to programming classes. This is the first time students have been exposed to these concepts, so it's like teaching kids to read before asking them to write an essay. Those higher order skills will follow in their later classes.

2
  • 2
    Very interesting bit about Bloom's Taxonomy. In my opinion, it's more important to get a student to understand the code than to copy/paste it in an intro class. They need to know how if statements work and be able to write their own from scratch before they move on. Get the cognitive part working, then move on to application.
    – Phil
    Commented Nov 30, 2011 at 17:14
  • I recently attended a great teaching related course by Richard Felder. His opinion was that you don't need to "master" lower levels of Bloom's taxonomy before stepping up. As an example he told how kindergarden children are practicing analysis when they are asked to compare which TV-show is better -- Sesame Street or [...?] and why.
    – Aivar
    Commented Nov 30, 2011 at 18:53
11
votes

Have you considered supplying them with some code to start with? Whatever simple scaffolding the assignment needs, like an empty main function (I don't know what language you're using). Something that compiles and runs and does nothing. Then they can start adding their code with some degree of confidence that at least part of it works.

This is actually pretty common in the "real world"; lots of IDEs and other tools create empty projects with typical libraries/templates/configuration files already in place.

4
  • Another way to supply code is to require them to interact with a class you've written (that doesn't work with previous code) and make a requirement of the assignment that your code can't be changed, and they must modify their own code to make the assignment work.
    – Zoot
    Commented Nov 30, 2011 at 16:25
  • Or even provide the code to make it work one way, and make the assignment to change/add the behavior. That way they focus on the particular behavior rather than the basic getting it to work.
    – JohnMcG
    Commented Dec 1, 2011 at 17:42
  • for first language, try to use a language that does not require any boilerplates to start with. Python is good in this respect, C/C++/Java is a bad for example.
    – Lie Ryan
    Commented Dec 4, 2011 at 7:05
  • If anything, IDE's, code completion and templates promote cargo-cult mentality. If students take the time to understand why that template code is needed and they will learn much more than blindly following the recipe.
    – Mark Booth
    Commented Dec 4, 2011 at 14:09
7
votes

Change your idea of projects!

In the programming world, rarely do we actually create new projects for every solution that comes around. Most of the time we modify old ones.

Change your idea of a project from one solution for each assignment to one solution for the entire semester. Each assignment builds on the previous assignment.

Example

Project: Build an elevator system

  • Assignment 1: Print out the current floor
  • Assignment 2: Create the data structures for an elevator class and print out the floor based on the elevator
  • Assignment 3: Create code that "moves the elevator", printing out the floor. Accept keyboard input (>enter floor: )
  • Assignment 4: Handle multiple elevators

The point is that you build on the previous assignment instead of recycling old assignments for a new task.

5
  • 2
    Well the copy-paste is not the problem, problem is that they don't understand what they are copying.
    – Aivar
    Commented Nov 30, 2011 at 19:03
  • 1
    One problem with incremental assignments is that if the student messes up an early one, they are stuck with non-working code for the rest of them. Many instructors will helpfully supply working code to use as the basis for subsequent assignments, but then they're back to the original problem: modifying someone else's code that they don't understand. Commented Dec 1, 2011 at 20:52
  • Really? If an instructor isn't helpful enough to help the student get their code working, are they really doing their job?
    – Richard
    Commented Dec 1, 2011 at 21:09
  • Not everyone will get their assignment working by the due date. Commented Dec 4, 2011 at 6:20
  • @Barry, isn't this the case with every subject that builds logically throughout the course? For instance, if you don't ever learn set Unions and Intersections, you are screwed for the rest of your Discrete Mathematics course. Or if you never learn your periodic table you are s.o.l for the remaining Chemistry course. The idea is to force students to master concepts in the right order and to work their asses off until they master them. If they can't spend all night for a week to get a program right to be ready for the next day of class, they don't need to make a career of software development. Commented Dec 18, 2011 at 1:31
7
votes

Any sort of cargo-cult mentality (including cargo cults themselves) comes from a lack of fundamental understanding of the technology involved.

Cargo-cult programming shouldn't be thought of as a problematic habit, but rather a symptom of the underlying confusion that the programmer is facing.

More importantly, the assumption that the student's lack of understanding of is simply the outgrowth of his lack of confidence is fundamentally misguided and does not address the underlying problem.

Instead, the student's copy-paste programming style should be a red flag telling you that this student is overwhelmed by the complexity of what he's expected to do.

He's instinctively using past work as a scaffold upon which to build his current project, attempting to compose a solution using previously solved problems as building blocks. We all do this to a certain extent, but most of us do this by using the knowledge gained from past work as our building blocks. This student is instead using the work itself, which means he doesn't truly understand the blocks he's working with. He's decomposed the work as far as his understanding permits, and treating large blocks of code as atomic units because he does not understand how they work. He only knows what they do.

1
  • Thanks! You gave me lot of food for thought. Initially I thought that maybe they just can't imagine that there is a structure and compositional meaning inside a piece of code. Now I'm thinking that maybe they actually did struggle to understand it but failed and used copy-paste as last resort.
    – Aivar
    Commented Dec 1, 2011 at 13:41
6
votes

Consider using a very high-level language that requires a minimum of boilerplate code.

To me, it's often the boilerplate code in large frameworks or verbose languages that feel like magic spells and hinders comprehension.

I was personally taught ML at my CS introductory programming course. For many years, Lisp was taught as introduction to programming at MIT. Both are excellent choices. Some of the benefits they have are

  • Interactive interpreter. Very important, as this allows exploration.
  • Very succinct. No boilerplate at all. It allows the students to concentrate on the ideas they are trying to express.
  • Relatively obscure and alien (at least compared to Java, C or other mainstream languages that the students may already have some experience with). Yes, I list that as a pro. It levels the playing field for the students, since likely noone will have prior experience. And it makes it less likely that they will be able to just copy-paste solutions to homework form the web.
2
  • ML would be pretty good choice! But Python also fits with your first two points and it's easy to use (meaning no big technical hassles).
    – Aivar
    Commented Nov 30, 2011 at 19:24
  • I also would highly recommend Python, especially when combined with a good IDE like Wing IDE.
    – Ken
    Commented Dec 5, 2011 at 2:22
6
votes

I did some research into the problems of novice programmers in the 80s. Based on my experience with novice programmers today, not much has changed. Novices don't have a useful mental model of what computers actually do. They resort to magic incantations because the machine itself is magical.

Programming requires breaking naturally simple tasks into unnaturally small steps. Since novices don't deal with such fine granularity in daily life, it's hard for them to figure out what the small steps should be, especially when it's not clear what small steps the machine makes available. But even if they do manage to figure that out, they are then confronted with the stilted syntax and limited semantics of a programming language (an unnatural language masquerading as a quasi-natural one) that controls the mystery machine by remote control.

Since they can't make the connection between a logical solution to the problem and the functionality of the machine, they focus on satisfying the demands of the language. The first goal is to write something - anything - that compiles. The second is to tweak that program - whatever it actually does - to keep it from crashing. Then, if they have the time, the energy, and the interest, they try to get the program to produce results that resemble what the problem requires. Along the way, they may accidentally produce well-written code.

In all likelihood, novices who do learn to program succeed because they have inferred a useful mental model of the computer, not because they've been intentionally given one and internalized it.

5
votes

You could ask them questions about pieces of code that require written responses? Like "What is this code doing?" "Why did the programmer solve it like this?" "Is there a better way?", etc?

That will actually get them thinking about the problem, which is something they can do without even touching code.

5
votes
  • Challenge them to create the shortest possible solutions to the problem.
  • Reward the more succinct solutions with an incentive.
  • Create exercises that revolve entirely around refactoring code
  • Have the students trade assignments, and mock grade them for efficiency and code cleanliness, and use some of the least efficient ones as examples, on an overhead projector.
3
  • 2
    Refactoring is extremely important to practice indeed. However, it is good to keep in mind that the shortest solution is not necessarily the cleanest, neither the most efficient (depending also on the definition of these terms). Commented Nov 30, 2011 at 21:09
  • In school I tried to write solutions that were shorter in character length than the solutions of a friend. That meant using short variable names and in general writing code that doesn't read well.
    – Christian
    Commented Nov 27, 2013 at 15:00
  • @Christian By short, I didn't actually mean short in character length, as the compiler doesn't really care about variable names. I'm talking about code complexity... aka KISS. Commented Nov 27, 2013 at 15:57
4
votes

Similar to JoelFans idea is have them do the initial assignments on paper using a pseudo code (language) that you create. You can add the structures as you see fit and they don't worry about the magic box.

4
votes

I'm going to assume that by 'cargo cult', you mean that they're inserting stuff that think is necessary, but actually does absolutely nothing towards solving the problem.

If that's the case, you can always add some factor into the grading that's based on conciseness -- leaving unnecessary or redundant code in your program is asking for problems in the future, as it may break, or just make it more difficult to maintain.

They'd be judged similarly in an writing exercise in an English class -- no one wants stuff that goes off in a random tangent or is just generally rambling without getting to the point.

When I took an assembly class, the teacher would tell us for each exercise if he wanted us to write the code for speed, size, or memory usage, and he'd mark off if you didn't come close to optimizing what he asked for.

...

If they're copy & pasting code from previous similar assignments, and it's actually something to solve the new problem ... well, that's just code re-use, and unless they made bad assumptions about the suitability for the code for re-use, I think it's perfectly reasonable for them to do. (eg, reading from a file, propting for input ... all modular parts that can be re-used. If you didn't want them doing it, you need to make the exercises dissimilar.

1
  • The problem is that they are copy-pasting without seeing the structure of the code -- they just think that this kind of pattern was useful last time, so hopefully it also fits here. They hope and try instead of being confident.
    – Aivar
    Commented Nov 30, 2011 at 19:02
4
votes

Unfortunately, thats the way a lot of people's brains work. So go into this understanding that there are people who you cant 'cure' of this. There are a lot of people who are unable to work at the level of mental precision necessary for programming. Some people are simply not designed for it. I'm not saying give up on the students - I'm saying dont assume you are failing if not everyone picks it up.

Without knowing more about the context of the class, I'd say focus more with these problem students on the very basic structures - simple if/thens, loops, etc. Simple routines to print out odd numbers, every tenth number, etc. Nothing more than 10 lines of code each. If they are 'magic thinking' they obviously havent mastered those basics yet. Have them do a lot of different simple routines until they grasp whats going on. Someone else mentioned writing the code out on paper - I think that'd also be a great way to do these simple routines.

You also might consider having them learn flow charting. For some people, being able to see the flow of an algorithm, and then how that connects to code, may be helpful to them connecting the code to the flow.

3
votes

Ideally in the first lecture, start them out with something completely abstract: have them (as a group, with you as the leader) write up the instructions on how to go grocery shopping from a list, and break down the high-level instructions progressively until they reach enlightenment.

It helps to tell them that these instructions are going to be followed literally by a robot, who doesn't know how to infer things. It has to be a very hands-on activity where you are in charge of guiding them, though.

1
  • Good point! I've done this and I believe this has guided many students on right track. But not all.
    – Aivar
    Commented Nov 30, 2011 at 19:06
3
votes

Alistair Cockburn talks about the concept of Shu-Ha-Ri and how it applies to programming, http://alistair.cockburn.us/Shu+Ha+Ri. I think it may be important to bear in mind where your students are in this continuum. First that will help ease some of your frustration. Copy/imitate is a very natural response and accepted mode when you are first starting to learn something. Second, it may help you get some ideas of how to move forward. For example, you may want to consider choosing a problem that can be solved in multiple ways (loops vs. recursion, console vs. web/gui) then explicitly have them first solve it one way, then another way -- bonus they can learn about legitimate code reuse, componentization, creating reusable libraries, etc.

Another successful way that I've seen used is to have a series of projects that build on one another, making a default, working version available at each step after assignments have been handed in to prevent people from falling behind. Each step of the process should introduce something new. I'll grant you that this may be easier to do in a design class than a programming class, but it should still be doable. One nice thing about this is that you explicitly give them a good (hopefully) implementation to compare against theirs at each step. Expose this comparison as an assignment, i.e., do a mini-code review of their own code against their effort. You might want to make this one of several extra credit options.

While I'm typically not big on "comments," you might want to make documentation of the code one of the grade items. Have them produce a "Theory of Operation" document for each project that describes their approach, how each component fits in, and how they together solve the problem. Normally, I'd want the code to do much of this on its own, but it would drive them to put their thinking caps on and put it to paper.

Lastly, you might want to get creative and have your students review each other's code and give it an evaluation. Put peer pressure to work for you. Allow this to become part of the grade or extra credit for the highest rated code (and docs).

0
3
votes

Just a quick suggestion. Whenever I have a programming problem that needs to be solved or debug I like to look at my code and 'play computer' where In my head I keep track of the variables and their values and what I expect them to be when each line is run. So if I copied some code from somewhere, unless it is complete on it's own and I just need to reference it, I like to go line by line to understand exactly what is going on. Essentially playing computer. VBA Debugger essentially makes this task easier but making your students do it on paper might give them fundamentals like. What does this line actually do?

2
  • I've recommended them to do this, but I guess for some it is too slow and error-prone process, that they decide to skip it.
    – Aivar
    Commented Dec 1, 2011 at 13:58
  • Have you tried doing this in front of them on a projector using markers? If I remember my highschool programming class our teacher did this, and although most of the other students didn't care I thought it was a helpful skill. (Warning gross generalization coming up) It is hard to create motivation in students of my generation and younger, we've learned not to ask questions.
    – Mallow
    Commented Dec 5, 2011 at 18:20
3
votes

I taught introductory programming at the college level. It was a bread-and-butter course, all the faculty did it, and I think we did it quite well. We followed a common text and had common exams, but we each had our own classroom method that worked. It's been a long time since then, but occasionally I get to tutor some kid in programming, and the whole picture is about the same.

The way I do it is to start at the bottom, as concrete as possible. What students know is a structure. They already have a lot of concepts. I am building further concepts on top of those, and I am pruning off concepts they may form which are counter-productive. At the same time, I make them learn by doing.

I had built a little computer with an Intel 8008 chip, some EPROM, and a few circuits. I had programmed it to play a little duet when the I/O chip was connected to a couple speakers. I would explain how the little program worked, with an inner loop to count down a counter. That would act as a delay. Then it would toggle the output bit and do it again. It would do that for a while, and then switch to another delay, giving another pitch, and so on. The memory chip had a little timer, and if I tucked a capacitor lead under one of the timer inputs, the program would run veeeeery slowly. The class could hear the speakers going click, click, click... I wanted the class to understand that the computer was doing very simple things one step at a time. Then I would un-hook the capacitor lead, and the "music" would burst forth. (applause)

Then I had built a simulator for a very simple decimal computer, having 1000 memory locations, each holding a signed 4-digit decimal number. It had very simple opcodes like "add to accumulator", "jump if negative", and so on. I would have them write little programs in this "machine language", like adding two numbers, or adding up a list of numbers. Then they could watch it work by single-stepping, or holding down the Enter key to watch it run "fast".

The point of this was to put in place the concept that computers can only do a very small number of different basic operations, and they do them one-at-a-time. This is to counter the impression they have that computers are complicated, and that they do everything all at the same time, and read your mind in the bargain.

From there we went on to programming in a "real" language (BASIC :), starting with very simple but interesting programs, working up through conditionals, loops, arrays, files, merging, and so on. The object was to put in place a sufficient skill set so they could take on a project of their own choosing, because that's the only thing that makes programming interesting - the use to which you can put it. I would throw out some ideas for projects, and then they would take it from there. I would ask for written ideas, and then progress reports, to keep them from postponing it to the last minute and then panicking. I think the projects were the best part, because they were learning under their own power.

That initial grounding in a very concrete understanding of what computers do made it much easier to teach concepts later on that would otherwise be real speed-bumps, like arrays or (in a later course) pointers. We tend to glorify the concept of "abstraction" as this wonderful thing, but it needs to be built on a concrete foundation, not on air.

3
votes

A s a s e l f - t a u g h t programmer I believe animation to be the most challenging in terms of knowing what the code is doing. When a program contains algorithms and mathematical transformations performing abstract manipulations, the only way to understand what the math is doing at any given point (unless you're a genius) requires understanding the execution of code itself.

Correct me if my naive idea is incorrect. What you want to do is not prevent your students from using "design patterns", but to find a way to ensure they understand what they are CnP's? Then challenge your students to manipulate an animation. In order to tweak the output in an animation its necessary understand what is happening at each step. For your stated concern, I imagine a well conceived animation project will manifest in obvious ways when a student "gets it"--when they have realized a transformation you didn't expect or tweaked certain related, interdependant variables.

Without knowing the pedagogical limits and goals you are working under, I can't say animation is the complete answer. A whole curriculum of animations outside of animation profession is, I should hazard to guess, out of the question. A few projects may none the less result in something artful and wonderful, which isn't bad.

On another note, I read a newspaper article (yes, paper!) about a high school-level Coding Olympics--wot-wot--competition for pre-college programmers. The description of their challenges was the clearest articulation of pure coding I can recall having read. The competitors are judged against each other and by good practice standards. For these competitions students must both plan their solution and hand code the elemental "design pattern" which the problem requires to finish within time limits. Thus, the solution to your concern regarding CnP programming is to test if the students can write the same "code chunks" they are CnP'n!

I'm sure it was in the NY Times. A quick search didn't find it. A similar example is ACM's International Collegiate Programming Contest. This contest emphasizes speedy programming: "Lightning-quick programming in team competition is a decidedly quirky skill, not exactly one many job seekers would place at the top of a résumé." Thus I would recommend abstraction from real-world problems is the answer.

Also,

HP Code Wars

2
votes

Teach the class using a programming language that is technically good but is so obscure they won't be able to find any existing code to copy.

1
  • 1
    I don't worry about them copying someone else's work, but their own work or some example snippets, which are not usable in given situation.
    – Aivar
    Commented Nov 30, 2011 at 13:15
2
votes

You could also treat them the hard way.

Find a way to make a copy-paste harmful to them. I don't have precise example but if you craft a first exercise whose solution, if pasted in a similar looking second exercise, bring the cargo-cult students in a very long and painful "unstable instability" or "silent data corruption" bug. Meanwhile a "non cargo-cult" 2 mn thinking would have brought an obvious solution to even the worst student (hadn't he seen the first exercise solution). Then, maybe there is some possibility they could learn the lesson, and think twice before copy pasting code into the third exercise.

1
vote

I doubt that this behavior is because of a belief that programs are magic spells - more likely it's laziness and lack of motivation.

So I think your job as a teacher is to motivate your students - no student who's genuinely motivated will cut and paste a solution (that's only for working programmers with deadlines and bottom-lines to meet...)

4
  • For some of those students, lazyness and/or deadlines are certainly the cause. But some are working really hard...
    – Aivar
    Commented Nov 30, 2011 at 19:09
  • @Aivar - As an instructor, you are probably more knowledgeable about the strengths and weaknesses of the students. Out of curiosity, what do you think are the impediments for those students that are "working hard"?
    – Leigh
    Commented Dec 1, 2011 at 0:25
  • @Leigh - I think they haven't trained the analytical part of their brain enough and they are approaching the assignments with brute force -- their work method is not far from exhaustive search. And explaining the alternative approach to them is hard.
    – Aivar
    Commented Dec 1, 2011 at 13:46
  • @Aivar - Perhaps there should be more focus on analysis in the early stages. For example designing two part excercises. The first segment focuses on the building blocks of the code. While the second deconstructs, debugs and analyzes the same example. ie Asks the "why" questions and discusses ways to improve the code with real world correlations to different approaches (brute force, etc..). Done early and often that would help solidify their knowledge and encourage them to view programming as more than just constructing the right syntax in a particular language.
    – Leigh
    Commented Dec 1, 2011 at 19:52
1
vote

Teach subroutines. Have them take the code they are grabbing from previous assignments and turn it into a subroutine. Teach them about function documentation to help them understand what the subroutine is actually doing.

2
  • This doesn't really solve the problem.
    – Pubby
    Commented Nov 30, 2011 at 23:37
  • I think it does. Cargo cult is inclusion of code that doesn't serve a purpose. If they are breaking their code up into subroutines and documenting what those subroutines do this should help. Analysis is a big part of learning and analysis requires breaking things into parts. Commented Dec 1, 2011 at 13:16
1
vote

Make them do the assignment in front of you in the classroom with no Internet access provided (have the school cut it off, allow no phone use as well during class). At least do this for tests. There is no reason at all that they should be using the Internet for basic programming expercises. The book should be a sufficient resource for intro exercises. Allow Internet usage once you are in an advanced class and they already have learned how to think.

1
vote

Never give them similarly sounding assignments.

Or, more crazy, learn them TDD from the beginning. It pushes for writing (not copying, writing) a lot of code (namely tests) that actually helps to formulate the problem that is being solved.

5
  • Writing tests is often harder than writing the code in the first place. I'd suggest that maybe the teacher write the tests, then give them to the students to run against their assignments.
    – TMN
    Commented Nov 30, 2011 at 13:59
  • @TMN: That could backfire. Students would be implicitly encouraged to randomly change code until the tests pass. Commented Nov 30, 2011 at 14:04
  • @GoranJovic: Not sure I agree with "implicitly encouraged", but I do recognize there's no easy way to distinguish between code written with intent and code hacked together just to pass the tests. Of course, this problem isn't restricted to academia, either... ;)
    – TMN
    Commented Nov 30, 2011 at 14:43
  • @TMN: And the incremental "one (as easy as the developer needs) step at a time" would vanish.
    – herby
    Commented Nov 30, 2011 at 15:13
  • Solution: provide a minimal set of tests the students can use while writing their programs, but warn them that their programs will be graded against a much more comprehensive set of tests AND it will be run against the tests the students write. Commented Dec 1, 2011 at 20:47
1
vote

Something I have found to be very helpful for the people in my class is writing a small project on their, on a subject they can choose themselves.

When I started programming, it was hard for me as well, and I did copy a lot in class. Then at home, I started making little games, as I want to become a games programmer, and I found them to be much easier to make. Even though they were much harder then the stuff we saw in class. Just because it interested me.

A few other people in my class went from 40-50% on their exams to 90-100%, because they did the exact same thing.

1
vote

When I was in an introductory programming course, the instructor required everyone to write an algorithm in English and print it out and turn it in before we started writing code. Then we would have to put plenty of comments such as Create variables, Get Input from user, Perform calculations, Print output, etc. I was docked a couple of times for not having enough comments when I thought there were plenty, so I started adding more. This forced me to think about what I was doing and write the solutions and keep translating back and forth between English and Java.

Not the answer you're looking for? Browse other questions tagged or ask your own question.