How hard is programming?

In a comment to Alfred Thompson’s blog post on “Any monkey can code” I talked briefly about a simple coding problem “given a list of integers find the sum of the evens (or the odds or the integers divisible by 3 or whatever).  The Python book I am using has a lot of problems like this scattered through it.  How difficult are these problems?  Anyone with experience in programming will think the problem is pretty trivial.  Depending on the language it is 6 lines of code.  Here is my solution in Python.  (There may be a better solution but this is my solution so all you programming brain surgeons out there, lighten up.)

  1. ints = (1,2,3,4,5,6,7)
  2. n = 0
  3. for i in ints:
  4.     if i % 2 == 0:
  5.         n = n + i
  6. print(n)

I took me maybe 5 minutes to come up with this solution, mostly because I am a slow typist.  Now let’s look at what is involved in this little program and how a kid would have problems coming up with a solution.

There are a lot of simple concepts in this little program that all have to work together to get a result.  Starting at line 1 here I am making a single variable equal to a list with bunch of numbers in it.  Kids know what a variable is; they have been dealing with them in math for years.  That still does not mean they have a firm grasp of the idea, and this variable name is more than one character, not allowable in the math world they know.  Programming teachers keep saying use variables that make sense, but variables with more than one letter do not make sense in the math and math is their only close framework at the moment.  There is no previous framework for them to put this weird variable into.  This idea is not a big deal to most kids but in typical teaching fashion we show it one minute and tell them to use it the next.  There are also the little confusers like parentheses or square brackets and reserved words they may not know that they try to use for a variable name.  (Trying to use “sum” was in my learning curve).  So even line 1 is not as simple as it looks.

Now line 2.  “Why do we need to do that?”  “Because we need to define the variable before we use it.”   “How come we do not have to define the ‘i’?”  “Because it is the index variable in the ‘for’ loop and is self defining.”  “Yah, right, whatever you say.”  I can convince the kids of this one fairly easy.

Line 3 is part of the standard programming curriculum.  A nice simple “for” loop with two variables, one of which is a list of numbers and not a number at all, and the other keeps changing.  All with a colon on the end that does some magic.  Simple syntax memorization.  Now I just have to convince the kids this is the right programming doohickey to use.  My students are in at least their second semester of programming so they know the syntax but they still have issues with strategy.  Most can see the need to use a “for” loop.  Since this is the first time they have used lists in “for” loops (Python thing) it does require learning a new capability of the “for“ loop.

Lines 4 and 5 are the money lines.  These are the logic lines that seem to stump most of the kids.  The “if” part is well understood.  From there things can get a little fuzzy for them.  Determining if an integer is even or odd or divisible by something by looking at the remainder seems totally foreign to the kids.  Now that I think about it math curriculum has done some evolving that has eliminated the remainder from the curriculum.  In pre-calculator years the remainder was used a lot.  Long division and fractional answers have sort of gone the way of the slide rule and with it the use of remainders.  Remainders were useful in finding factors and roots of polynomials but those techniques were replaced by the graphing calculator and algebraic computation software.  The kids are just not used to using them.  Now let’s throw in the new operator, mod (or modulus if you prefer), that the kids have no experience with.  They have to remember the % sign means something other than percent.  Then pile it on with a double equal Boolean operator which may also be a new symbol.  That simple “if” statement the kids thought they knew has become a monster.

Line 5 makes absolutely no sense, at least if you have been taking math for the last umpteen years.  There is no way that n can equal n plus some non-zero number.  “Wait, what do you mean that is not an equal sign!  Is too, just look at it!”  An equal sign is an equal sign and the kids know an equal sign.  That stupid equal sign is the bane of programming teachers.  Personally I think this is one of the really big mistakes in programming languages.  That equal sign is confusing and needs to be replaced by some kind of assignment symbol.  I know there are languages that use a <= symbol which is a bit better.

The kids can get line 6 on their own (usually).  They know there has to be an output somewhere.  With Python’s indent format they sometimes get confused what it should be lined up with but they will get it on the second try if necessary.

So how easy is this little program?  From the beginning programmers’ perspective it is anything but easy.  Unfamiliar math, contradictory math caused by ambiguous symbols, new symbols and logic that is vague due to lack of background.  No wonder the kids struggle and some people think programming is more difficult than brain surgery.

Advertisements

11 Responses to “How hard is programming?”

  1. gasstationwithoutpumps Says:

    That looks like a Java or C program, translated into Python.

    A simpler solution would be

    print(sum(i for i in range(8) if i%==0))

  2. gasstationwithoutpumps Says:

    That looks like a Java or C program, translated into Python.

    A simpler solution would be

    print(sum(i for i in range(8) if i%2==0))

    (Correcting the typo in my previous comment—I hit return instead of backspacing)

    One of the nice things about Python is that it often doesn’t require extraneous variables and loops—the iterations can often be done in expressions, and powerful operators like sum are commonly available.

  3. zamanskym Says:

    It’s true that generators like:

    print(sum(i for i in range(8) if i%2==0))

    Can be cleaner and more elegant for an experienced programmer, but they can also be very difficult for beginners to wrap their heads around. They’re also not a substitute in terms of developing a students problem solving and thought skills.

    On a related side, it was interesting to note that in the Udacity courses (at least the first few that I looked over) they avoided list comprehension type stuff and explicitly looped.

    As a programmer I was “aaah – it’s so inelegant and clunky!!!!” but as an educator I felt it was probably the right thing.

  4. gflint Says:

    Looking at that one-liner I can sort of figure it out but I would never think of doing it that way for two reasons. The first is I do not know Python well enough to even understand how it exactly works after looking at it. Second it is not something I would want to use in a high school programming II class. I teach Programming I, II, III so I just do not see the purpose in coding like this. I write clunkers because they are easy for the kids to understand and trace. Clunkers also transfer across languages easily. On the other side I do wish I knew Python well enough to write things like that but with 4 months Python experience I am just happy to be able to write clunkers. I love elegance.

  5. Alfred Thompson Says:

    Great post Garth. I added a link to it from the post you mentioned under related articles.
    BTW I worked through the same task with my C# students last week. I don’t think many experiences programmers remember how difficult something like this is for beginners. The C# solution we discussed is:
    int total = 0;

    for (int i = 1; i < 10; i += 2)
    total = total + i;

    total += i; would also work of course. Oh and remember that PASCAL used := for the assignment operator.

  6. gflint Says:

    I had forgotten the Pascal :=. Anything but an equal sign.

  7. Emmanuel Schanzer Says:

    Great post! The last two really resonate with me, as a former algebra teacher who’s wanted to use programming as a way of helping students understand math. Programming, for the most part, is frustratingly non-mathematical.

    For the last few years I’ve been working with the Program by Design team to create materials that address a lot of the concerns you’ve raised here. The result of our work is a 100% algebra-focused curriculum, which uses a language that is purely algebraic (no assignment, no for-loops, etc) and a pedagogy that mirrors the best-practices that have been coming out of NCTM for quite some time.

    Teachers had a lot of success with the materials, specifically using them to teach mathematics.

    You can find all of the materials (100% free) at http://www.BootstrapWorld.org. I’d be curious to know what you think.

  8. Matthias Felleisen Says:

    Let me illustrate and emphasize what Emmanuel S. posted on March 10. I am going to use Program-by-Design (PbD) notation, but you can use any programming language to design programs this way.

    EMPHASIS: Part of the problem is that the math curriculum and the programming curriculum work against each other instead of re-enforcing ideas that come up in both. This ranges from meta-concepts such as variable and function to concrete math concepts such as remainder and conditionals.

    Most programming languages do NOT use mathematical notions of variables and functions. Most programming courses do NOT place remainder and modulo in context, as domain-specific knowledge.

    Generally speaking, we emphasize the tech wizardry of programming over its concepts, as if all students who enroll in Programming 101 will found another Facebook and foundations don’t matter because the money of tech jobs is all we care about.

    ILLUSTRATION: You can use PbD’s design recipe to systematically design a mathematical function that performs this task:

    ;; List-of-numbers -> List-of-numbers
    ;; pick out all even numbers from a list
    ;; example: given (list 1 2 3 4), wanted: (list 2 4)
    (define (all-evens l)
    (cond
    [(empty? l) ‘()]
    [(zero? (remainder (first l) 2)) (cons (first l) (all-evens (rest l)))]
    [else (all-evens (rest l))]))

    You can then run this function interactively as if you were in a calculator:

    > (all-evens (list 1 2 3 4 5 6 7))

    Once students have seen several of these functions, you will ask them to systematically design an abstraction over all these functions. Then you will show them that such abstract functions already exist in most languages and one can define all-evens with one of them:

    (define (all-evens l) (filter even? l))

    and you can explore this variant like the above.

    EMPHASIS: The little illustration demonstrates several interactions between math and programming:

    — programs are functions
    — programs can be written as if we were in pre-algebra
    — variables in programming and math are the same (for now)
    — on occasion you need specific, small functions from math (mod)
    — functions operate on functions
    filter is like the indeterminate integral,
    just much easier and much more concrete

    — word problems can be solved systematically as if they were programming problems

    — programming problems use the same kind of strategies as word problems.

    POINT: even if your kids never become programmers, they will understand more about mathematics and more about systematic problem solving. And as Emmanuel’s evaluators show, the skills truly transfer now.

    Programming can do much more than train one of your thousands of students to become a Facebook founder. Let’s use it for all of the others, too.

  9. John Burnette Says:

    First, a shout out to Garth from a fellow Computer Science teacher at the high school level.

    Secondly, I’m never played around with Python but I guess it’s one of the currently “hot” languages that the hip kids want to all learn. Sure, why not, if it gets kids in the seats I’m for it. But as a high school teacher I’m pretty sure that there is a zero percent chance that Python will still be the “hot language” 6 years from now when my students all graduate from college. So I can’t let my classes be about the syntax of any particular language.

    So, may I propose this: As I see it, what you’re saying in your post is that the syntax is what’s baffling your students. Why not ask them to solve the problem as posed but first just as pseudo-code.

    Step one: Create a place to put the list of numbers.

    Step two: Create another place where you can store the “running total”

    Step three: Look at the numbers in the list one at a time and if they are even, add that value to your running total.

    Step four: when you’re out of the numbers in the list, the total you want is the last value in your running total.

    I’m guessing that nobody in your class will have trouble with this logic. The point is that once the logical concepts are firmly in their heads, the question simply becomes “What’s the syntax to make the computer do this?”

    Trying to explain both at the same time is what makes this difficult.

    NOW: How does what I’m saying survive when the actual programmers show up with their fancy elegant code….? That’s an interesting question for me.

    print(sum(i for i in range(8) if i%2==0))

    As I said, I’m completely unfamiliar with Python but it seems that it’s reasonably self explanatory. I think it would be an interesting conversation with the students to ask “what happened to needing a placeholder for a list? for a running total variable?” Presumably they’d get that the sum command simply internalizes things.

    Lastly, what if the list of numbers in question were a list of ANY seven numbers. Would they be able to take the syntax from the “book” example and know what to change in the “elegant” solution?

    As a Python novice I’m guessing the elegant solution would become

    print(sum(i in ints: for i in range(8) if i%2==0))

    Did I guess right?

    • gasstationwithoutpumps Says:

      Close, but not quite. “i in ints” is a membership test, “for i in ints” is an iteration over ints.

      print( sum(i for i in ints if i%2==0))

      range(8) is just a way of constructing the list [0, 1, … 7]
      so all that was needed was to replace range(8) by ints

      (I’m talking about Python2 here—I’m aware that in Python3 range(8) is an iterator rather than a list constructor. The effect is the same in the “for i in range(8)” syntax, but there is much less memory management overhead with Python3’s semantics.

  10. gflint Says:

    This is why I started this blog, to get ideas and suggestions. Thank you everybody.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: