Home » Main » The trouble with Python

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 8 other subscribers.

The trouble with Python

Daisy trouble image
My daughter’s next reading book

Python is the de facto language in Secondary schools currently. I’m a fan of it myself. I have used it as part of teaching GCSE computing in the past and I like the clean and simple syntax which presents a low barrier to entry for pupils creating simple programs. I actually see a need for it at KS3 as a getting-things-done-easily introductory textual programming language.The trouble is, with recent changes to the GCSE specifications, I’m not convinced about how suitable it remains into KS4.

My issue is that other languages that are available can be used to illustrate concepts in a more direct way without muddying the waters and potentially confusing pupils by learning just the ‘Way of the Python’. Remember that computing is a creative subject, (as the National Curriculum mentions,) and it has been suggested that pupils best learn how to program by applying their base knowledge to solve different problems (Robins, Rountree and Rountree, 2003).

I believe it is important to develop knowledge of programming fundamentals at the point at which they are applied. I would suggest, for example, that the best way to appreciate what a constant is, and how it works, is to use it within some example programs. Unfortunately, you can’t create constants in Python so you are limited to only discussing these points. I found it a more effective exercise to use a language that supports the creation of constants and have pupils investigate how they can’t be changed and what the side effects are if you don’t use them. The choice of language in this case limits the learning that takes place.

CS version of Shakespeare
Modern classic

I consider Python a slang or txt-speak language. Mannila, Peltomäki and Salakoski (2006) consider it a “strange language” but one with educational benefits. You can get your message across by taking short-cuts but I always wanted the pupils I taught understand the specifics about what was going on so that their skills would be transferable to any language. At times, Python allows you to get around problems easily without really having to understand the complex relationships between all the component parts. You could write a book using txt-speak, and you may be able to get the meaning across, but it isn’t suitable for all. It’s the same with programming. I can use the Python FOR construct, (which isn’t actually a FOR loop, it’s a FOREACH loop that iterates over a collection of objects,) to iterate over characters in a string quite easily:

for letter in theWord:
    print(letter)

However, this hides the complexity that a string is actually an array of characters. We don’t need to find the length of the string. We don’t need to reference individual elements using an index. That’s fine when you already understand the underlying concepts but what about if we want pupils to understand these things? We could do something similar in C that might shed light into how a string is implemented:

for (i = 0; i < strlen(theWord); i++) {
      printf("%c", theWord[i]);
}

At the point at which pupils have to write exam answers about programming, surely a more tightly-controlled formal language will help them understand what is really going on under the hood.

Here are some more examples of concepts that need to be learnt within the GCSEs but can’t be done (directly) in Python. I think that sometimes the Python code is more readable and a better solution, but that doesn’t mean it teaches the concepts identified.

Record structures

Learning point: Structures can be created to collect and organise data in a predefined format.If you are dealing with sets of the same data it makes sense to create a reusable structure.

Python fudge:

# Use OOP class
class customer():
   def __init__(self, name, phone, email):
      self.name = name
      self.phone = phone
      self.email = email
      # Object references obscure what we want pupils to focus on

Traditional C approach:

struct account {
   char *name;
   char *phone;
   char *email;
};
/* Structure elements only */

Post-test condition controlled loop (aka REPEAT UNTIL)

Learning point: Conditional loops can be tested either at the start or the end. Using a condition at the end of a loop ensures it runs at least once with all the repeated code contained within the loop.This is useful for verifying the results of an action, e.g. checking an input and repeating if the value is invalid.

Python fudge:

# Forcing a WHILE loop to run at least once
validIn = False
while not validIn:
   score = int(input("Enter score: "))
   # Condition to force the loop to end
   if 0 <= score <= 10:
      validIn = True

Traditional C approach:

do {
   printf("Enter score: ");
   scanf(%d, &score);
} while(score<0 || score>10);
/* Construct is structured by default to behave in the way we need */

Passing subroutine arguments by reference

Learning point: When calling a subroutine with arguments, the subroutine can modify the values directly (using a reference to the data) or with a copy of the values (the values are passed preserving the original data).References are useful if you need the subroutine to work on the original data without
having to make copies of the values.

Python fudge:

# Nice, clean function
def swapNums(a,b):
   return b,a
 
num1 = 2
num2 = 8
# ...but we have to return the values and a lot of languages can only return one
num2,num1 = swapNums(num1,num2)

Traditional C approach:

/* Use pointers for reference addresses */
void swapNums(int *a, int *b) {
   int temp;
   temp = *b;
   *b = *a;
   *a = temp;
   return;
}
...
int num1 = 2;
int num2 = 8;
swapNums(&num1,&num2);
/* Once called, variables are changed */
...

Arrays

Learning point: Collections of data all of the same type stored using a single common identifier.Creating an array is more convenient and flexible than creating the same number of individual variables. Depending on how deep you want to go, arrays may offer better performance over alternative data structure implementations.

Python fudge:

# Pretend list is an array
scores = [10,15,19]
# ...but you can add to it with different data types
scores.append("twenty")

# ...or use a limited library from array import array
scores = array("i", [10,15,19])
# ...which you can still add to!
scores.append(20)

Traditional C approach:

int scores[3] = {10,15,19}
/* Fixed size that cannot be added to */

Summary

Man wrestling python
Snakes can be constricting

In practice, there is no one ideal language to use. Each have benefits and drawbacks to the process of learning about programming languages.

What teachers need to be careful of is not to teach concepts through an individual language. They should also consider exactly what they want pupils to learn. Sometimes we need pupils to understand theoretical concepts and relate these to practical examples. Just be careful if you use Python as you might be limiting their understanding of the topic you are teaching.

 

References

Mannila, L., Peltomäki, M. and Salakoski, T., 2006. What about a simple language? Analyzing the difficulties in learning to program. Computer Science Education, 16(3), pp.211-227.

Robins, A., Rountree, J. and Rountree, N., 2003. Learning and teaching programming: A review and discussion. Computer science education, 13(2), pp.137-172.


4 Comments

  1. My reply to comment on Facebook:

    I was thinking Python may be a problem for GCSE questions like this.

    http://mrcompsci.uk/aqa_gcse_q/

    If all that pupils have done to loop through a string is use a FOR loop then they will struggle to gain marks (i.e. from the mark scheme: “1 mark for using an index variable to access the individual characters in the array; “).

    It’s my worry that non-specialists will just use Python alone and concepts that need to be covered will be missed. You can code a solution to this in Python using a FOR loop but I think it will be messy. You could/should use a WHILE loop and Python would be fine in that case but, as per my post, sometimes Python is too flexible.

  2. Good article!

    I absolutely agree with you that the choice of language influences the teaching that can take place. And I agree that students should clearly see the fundamental concept, separate from its instantiation in one particular programming language.

    On the other hand, how many of the “programming fundamentals” you mention are fundamentals, and how may are artefacts of fitting into the strictures of a von Neumann architecture? And if you want to show off that kind of programming close to the metal, more assembler/Little Man might be the way to go.

    For instance, why do I care if a string is an array of characters? But if you ask that question, why not also ask if it’s a C-style string (null-terminated) or Pascal-style string (prefixed with length)? And where does non-ascii unicode fit in?

    But! For many of your examples, you can use bits of Python to illustrate the concepts you’re after.

    For record structures, use a dict. If you really want fixed and mandatory fields, `collections.namedtuple` is simpler than defining classes.

    No repeat-until loops? Yes, and all workarounds are ugly.

    Pass by reference vs pass by value? Just use some container types as parameters. (I find people get bitten by this kind of thing all the time.)

    >>> def swapl(nums):
    … temp = nums[0]
    … nums[0] = nums[1]
    … nums[1] = temp

    >>> ns = [2, 4]
    >>> swapl(ns)
    >>> ns
    [4, 2]

    Arrays? If you really want fixed-size, use a tuple. If you want constant-time access, use a dict. But why is fixed size an advantage?

    —-

    As for the “prefix” exam question, it’s a fine question, but a marking scheme that eliminates alternative solutions is rubbish. I mean, this is correct (Prolog), but how many marks would any recursive solution get? Or, a solution using zip?

    prefix(_, []).
    prefix([H|Ls], [H|Ps]) :- prefix(Ls, Ps).

    • Thanks Neil. Some really good examples. Please note I was never justifying what should be taught rather the process involved in learning the content that is specified. Perhaps the “programming fundamentals” are symptoms of the specifications teachers have to deliver. Miles Berry alluded to the same on Twitter.

      It’s the limitations of the systems we are in at the moment and the move to exams only reinforces this. I have really liked using Python to teach concepts and through experience was able to fill in the blanks, (or perhaps even use the language to teach the concepts). Unfortunately, exams needs answers and if the markers are working to a strict the knowledge and skills required will be limited.

      I think now my choice of language at GCSE would (sadly) have an eye on what will give pupils the best chance of success.

      • I agree about assessment. It’s really hard to create mark schemes that are flexible enough to deal with the range of approaches students could use, while still being specific enough to ensure different markers are consistent, and its hard to create problems that are complex enough to be interesting while being small enough to understand and solve in an exam. But the mark schemes need to allow for solutions in programming languages created after 1957.

        Sounds like we’re in agreement here.

Leave a comment

Your email address will not be published. Required fields are marked *