Fun with Python. Part 2

Onze verontschuldigingen, dit bericht is alleen beschikbaar in Amerikaans Engels. Voor het gemak van de kijker, is de inhoud hieronder weergegeven in de alternatieve taal. Je kunt klikken op de link om naar de actieve taal over te schakelen.

  “Python is the most powerful language you can still read.”
Paul Dubois

  Being a developer, it is hard to stay focused on one programming language only, there have been at least a few projects in your career that required from you some knowledge about a different programming language than the one you are specialized in. Under this circumstances you start to compare them, to notice their particularities and very often you are trying to write the code in the same manner you were used to do it in your favourite language.

  Soon you get disappointed, because this new language doesn’t support some features you expected. After a few hundred of written lines of code you start to notice that this language can actually meet your requirements, you start to understand the way it works and perhaps what were the reasons the authors built it like this. This is the challenge and the beauty of being a developer, you never know what language will you be “speaking” during your next project.

  In this article, I’m going to continue exploring Python and share with you the curiosities I found about it while working on a project.

Methods that return more than one result

  It happens sometimes that I want to have a method that would return more than one result. I could try grouping things into a logical structure, but it’s not always the case. You might think that this approach automatically violates the rule of having a method that does one single thing, because two returned results mean two processes executed inside that method.

  Let’s suppose we want to have a method that would divide two numbers and return the quotient and the remainder:

def divide(a, b):
   quotient = a // b
   remainder = a % b

   return quotient, remainder
                               

  Calling this method and assigning the result to some variables can be done in the following manner:

quotient, remainder = divide(6, 2)
                                  

  The result of this method is assigned to the variables by keeping the order from the return statement. Here’s the example of an output:

Experiment 1: 6 / 2
  Quotient = 3
  Remainder = 0

Experiment 2: 5 / 2
  Quotient = 2
  Remainder = 1
                 

  Under the hood though, this method still returns one value, just this value is a tuple. A return statement with multiple comma separated values, presumes an internal transformation of these values into a tuple and vice-versa, called packing & unpacking a tuple.

Fig. 1 Unpacking a tuple

  A tuple is a sequence of values much like a list. The values stored in a tuple can be of any type, and they are indexed by integers. The important difference between a list and a tuple is that the latter one is immutable. More about tuples you can find here, it’s quite a good resource.

Swap 2 variables

  Going further with the tuples in Python, let’s have a look at how would you swap two variables, a and b. First thing you might think about, is to use a third variable, like in the following example:

temp = a
a = b
b = temp
      

  If we consider these two variables to be some numbers, someone may use the Math to do the swapping:

a = a + b                  x = x * y                  x = x ^ y
b = a - b        or        y = x / y        or        y = x ^ y
a = a - b                  x = x / y                  x = x ^ y
           

  Of course every approach you have seen so far has its advantages and disadvantages, but we are not going to look into this right now. Coming back to tuples, here is how you can easily swap two variables in Python:

a, b = b, a
    

  If you haven’t realized yet, Python is dynamically typed, which means that these two variables that are being swapped can be of any type.

Constants in Python

  There were a few times when I wanted to create some constants in Python, but I realized very soon that I cannot do it in a simple and safe way, because there is no final or const keyword available. The recommendation is to follow the naming conventions for constants and try not to change that variable:

  • Capital letters must be used when declaring a constant. For example: PI = 3.14;
  • Constants must be put inside a Python module and aren’t meant to be changed;
  • Constant names can have combination of letters in uppercase (A to Z) or digits (0 to 9) or an underscore (_). For example: CONST_NAME.

  However, if it’s really necessary to make sure that the value of a constant won’t ever change, there are several ways of achieving it:

  Option 1. Wrap the constant inside a function at the module level:

def PI():
    return 3.14
   

  Option 2. Declare a property without a setter, if the constant is part of some specific class:

@property
def pi(self):
    return 3.14
   

  Option 3. Use named tuples. Remember I said before that a tuple is immutable, as soon as you define a value, it cannot be changed anymore:

from collections import namedtuple

Color = namedtuple('Color','BLUE YELLOW RED')
Color = Color(BLUE = '#0000FF', YELLOW = '#FFFF00', RED = '#FF0000')

print(Color.BLUE) # #0000FF
   

  Option 4. Use Metaclasses. They are used to define how should a class behave.

class MetaConst(type):
    def __getattr__(cls, key):
        return cls[key]

    def __setattr__(cls, key, value):
        raise TypeError
   

  With the definition above, any static properties will be immutable, because we defined a valid getter, while the setter will raise an exception.

  Now that we have a metaclass, we can create a class that would represent a wrapper for our constants:

class Const(object, metaclass=MetaConst):
    def __getattr__(self, name):
        return self[name]

    def __setattr__(self, name, value):
        raise TypeError
   

  Creating the wrapper for a group of constants can be done in the following manner:

class Color(Const):
    BLUE = '#0000FF'
    YELLOW = '#FFFF00'
    RED = '#FF0000'

print(Color.BLUE) # #0000FF
   

  Adding or removing a constant is as easy as declaring a new variable inside the wrapper.

Flow controls

  Speaking about the amount of lines that would have to be written for an if, for, while or any other control structure, Python is definitely a winner. Python is one of the programming languages which uses indentation to separate the code into blocks, while Java or JavaScript and most other languages, uses curly braces to define the beginning and the end of a function or class definition.

  Let’s see an example based on a game you played most probably at least once in your life – Rock–paper–scissors.

public void play() {
    Scanner sc = new Scanner(System.in);
    System.out.print("Rock, Paper or Scissors?"); 
    String userInput = sc.next().toLowerCase();

    if ("paper".equals(userInput)) {
        paper();
    }
    else if ("rock".equals(userInput)) {
        rock();
    }
    else if ("scissors".equals(userInput)) {
        scissors();
    }
    else {
        System.out.println("Invalid choice!");
        play();
    }
}
   
def play():
    user_input = str(input("Rock, Paper or Scissors?")).lower()

    if user_input == "paper":
        paper()
    elif user_input == "rock":
        rock()
    elif user_input == "scissors":
        scissors()
    else:
        print("Invalid choice!")
        play()
   

  As you might have noticed, the code written in Python is more readable, clean and compact. When you look at it, you clearly see it’s intent, identify the scope without being disturbed by syntax elements.

  The fact that is doesn’t have brackets around control flows could be considered as an advantage actually, the indentation forcing you to set your program out in a way that is easy to read, reducing the chances of errors resulting from a missing brace. Understandable code is easier to maintain and less likely to contain bugs.

  On the other hand, any language is difficult to read if there are too many indentation levels, but this is a problem with the program (and the developer), not with the language. It is desirable for a too long routine to be broken into smaller pieces.

  Python is easy to learn and is fun too, though you should keep in mind that it is a scripting language and building an enterprise application might be a big challenge. A weakly typed language like Python cannot catch all your typos, which might create serious damage at runtime, however this wasn’t an impediment for Google, Facebook, Instagram, YouTube, Spotify or Netflix to use Python for data analysis, back-end services and infrastructure management. The main reason for that being Python’s reputation for simplicity and practicality, ease of deployment and how simple is to maintain.

Share this article:

Nicolae Sîrbu
Java Developer