Skip to content

Instantly share code, notes, and snippets.

@fourohfour
Created October 1, 2017 00:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fourohfour/9cc94bef9da32498b25ac6530940094c to your computer and use it in GitHub Desktop.
Save fourohfour/9cc94bef9da32498b25ac6530940094c to your computer and use it in GitHub Desktop.

Hi Victor,

I'm a reasonably experienced programmer and I've identified some areas in which I feel you could improve your program. Firstly, I'd like to congratulate you on building a working version of your game. I remember working on a similar project about five years ago and it was the first non-trivial program I completed in Python. It was then that I first felt the satisfaction of creating something meaningful with a keyboard and a text editor. Enjoy that feeling - it makes up for the frustration of fighting errors after crashes after bugs.

The first suggestion I would make to you would be to reduce your use of global variables. Beginner programmers tend to overuse global variables, as they are very simple to use. If all the information about your program (commonly called 'state') is stored in global variables, you don't have to think very hard about where it is stored when you need to use it. This might seem like a good thing, but when your programs start to get more complex global variables will quickly start to cause you a lot of headaches.

Consider the following analogy. Most kitchens have lots of cupboards, shelves, and drawers which store all the different utensils. This is the equivalent of a well written program (without global variables). A program with global variables is equivalent to having one gigantic shelf with everything on it - from the forks to the saucepans to the mixers. In a small kitchen, with very few tools, this isn't a massive problem. In fact, it might even feel like a better solution, because you never need to open any drawers or cupboards. But as the kitchen gets bigger - or the program gets more complex - things get messy really fast. Suddenly you have to sort through all the spoons to find an apple corer. Worse still, your favourite aunt's lips are swollen because you put the wine glasses too close to the dirty knife that you used to make a peanut butter sandwich earlier in the day. These problems may not seem very relevant to your code, but they are - we just give them different names. In programming, we call this 'functional impurity'. Impurity makes it harder for us to test our code, reason about its behaviour, and change it in the future.

It's not that useful for me to say that global variables are bad without giving you an alternative. One alternative is to use bundles of data called objects to store information in your program - this is known as object oriented programming (OOP). I won't give you an explanation of this here, as there are thousands of excellent tutorials online, but if you are interested in reading more you should read online about classes in Python and more generally the principles of object oriented programming. You should know that these concepts are not easy to understand at first, as they involve types of thinking that you will not encounter in school before your A-Levels. That doesn't mean you should be intimidated - just that you shouldn't be too frustrated if you don't understand much at first. You may well have to read many different perspectives and explanations of the same ideas before you start to build a solid understanding of them in your mind.

Another key aspect of your program which I think you should revisit is the seperation of control code and data. Right now, every single question which you pose the user is given its own if block. There are better ways that you could structure these parts of your program which would reduce the amount of code you have to write, improve its structure and readability, and make it easier to improve the code in the future. Effectively, your code simulations a list of questions, from which one is selected and posed to the user. Your code looks something like this.

i = random.randint(1, 5)

if i == 1:
    print("The colour of the day is Red!")

if i == 2:
    print("The colour of the day is Blue!")

if i == 3:
    print("The colour of the day is Green!")

if i == 4:
    print("The colour of the day is Magenta!")

if i == 5:
    print("The colour of the day is Aquamarine!")

Instead of representing the list of options with control flow code (if statements), you could use a datastructure. I will use a tuple in my example, which is what Python calls an immutable (un-changable) list of items.

colours = ("Red", "Blue", "Green", "Magenta", "Aquamarine")
col_ind = random.randint(0, len(colours) - 1)
day_col = colours[col_ind]
print("The colour of the day is" + day_col)

The variable colours contains a tuple of strings, each of which is a colour that may be chosen at random as the colour of the day. We choose a number at random, which we will use as an index for the colour to be chosen. We will then use square brackets to select the colour day_col from colours using the randomly chosen index col_ind. Finally, we can print out the colour of the day. Now that the data (the tuple of colours) is seperate from the logic of the program, we have much more flexability. We only need to change one line of code to add another colour. If we wanted to make the program even more flexible, we could even load the colours from a text file. Hopefully you can see how these ideas can be transferred across into your program.

I also have some smaller suggestions you may want to consider to improve your 'fluency'. It's little use learning French if no-one can understand you through your english accent, and the same is true for programming (to a more limited extent). Firstly, consider where you can replace if statements with elif or else statements. This will make the structure of your code more visible to other programmers and will also improve efficiency. Read up on Python's module system and when you can use import statements - you should be able to replace your use of Popen with an imported module. It is common in Python to enclose code that runs as soon as the file is executed in an if __name__ == "__main__" block - you might consider searching python name equals main to learn why this is done. As a final point of note, you can easily make your programs look much more professional and clean by adding more whitespace. Whitespace is the term used to refer to blank characters such as spaces and tabs, although in Python the use of tabs is heavily discouraged. Consider aligning variable declarations like so:

really_long_name = 2
short_name       = 3

Sometimes it is worthwhile to add blank lines to your program to better seperate logically distinct blocks of code. This is all down to personal preference - generally whitespace has no effect on how your program works - but just a few blank lines and additional spaces can make a massive difference when you're trying to understand code that you wrote six months previously.

As a final note I will give you the advice which I think will serve you better than any specific tip or correction. Strive to reach a good theoretical understanding of programming and the languages that you work in, just as you learn useful skills and techniques which are more applicable in practice. Don't be scared of documentation (in particular, the Python docs). It may seem dense and impenetrable, but by reading it you will develop an understanding which is deeper and more broadly applicable than you would by simply 'learning through doing'. An engineer combines the hands-on ability of the technician with the abstract mindset of the mathematician - they are the best of both worlds. Be a software engineer. Take pride in the programs that you write, but equally, be introspective enough to be able to see their flaws. Most importantly, have fun!

Regards,

Jack (FourOhFour)

Shark Robotics 3117

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment