Argparse

Primer: Arguments vs Parameters

I’m sometimes confused. Is it an argument or a parameter? So here it goes:

A parameter is a variable in a function definition.

When a function is called, the arguments are the data you pass into the function’s parameters.

The same goes for a program: A program has parameters, you call a program with arguments.

Argparse Module

Batteries included! The argparse module provides a nice way to parse your program arguments:

import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('positional_param')
    parser.add_argument('-o', '--optional_param')
    parser.add_argument('-r', '--required_param', required=True)
    args = parser.parse_args()
    print(args.positional_param)
    print(args.optional_param)
    print(args.required_param)

Positional Parameters

Positional arguments are useful for shorter programs. These parameters do not have a name. You could call them “unnamed parameters” as well.

It is important that you keep the right sequence when calling the program:

parser = argparse.ArgumentParser()
parser.add_argument('positional_param_one')
parser.add_argument('positional_param_two')
args = parser.parse_args()
print(args.positional_param_one)
print(args.positional_param_two)
$ python positional_args.py foo bar
foo
bar

Optional Parameters

Optional parameters have a name you have to use when providing an argument to the program

parser.add_argument('--optional_param')

The double dash indicates an optional parameter

You can provide a shorthand for an optional parameter as well

parser.add_argument('-o', '--optional_param')

When you leave out an optional argument, the value will be defaulted to None

Two ways of calling a program with optional arguments:

$python optional_args.py
None
$python optional_args.py --optional_param foobar
foobar

Required “Optional” Parameters

Now it gets a bit weird: You can make an optional parameter required.

(another strong argument that these should be named “named parameters”)

parser.add_argument('-r', '--required_param', required=True)

If you don not provide the argument you will get:

$ python required_params.py
usage: required_params.py [-h] -r REQUIRED_PARAM
required_params.py: error: the following arguments are required: -r/--required_param
$python required_params.py -r foobar
foobar

Command Line Help

When you start your script with the -h or –help parameter, you will get a nice overview of the usage

$ python main.py -h
usage: main.py [-h] [-o OPTIONAL_PARAM] -r REQUIRED_PARAM positional_param

positional arguments:
positional_param

optional arguments:
-h, --help show this help message and exit
-o OPTIONAL_PARAM, ---optional_param OPTIONAL_PARAM
-r REQUIRED_PARAM, --required_param REQUIRED_PARAM

Sound and music with pygame

pip install pygame

Sound

import pygame

if __name__ == '__main__':
    pygame.mixer.init()
    sound = pygame.mixer.Sound("./sound.wav")
    channel = sound.play()
    while channel.get_busy():
        pygame.time.wait(100)
        print("Playing...")
    print("Finished.")

 

Music

import pygame

if __name__ == '__main__':
    pygame.mixer.init()
    pygame.mixer.music.load("./sound.mp3")
    pygame.mixer.music.play()
    while pygame.mixer.music.get_busy():
        pygame.time.wait(100)  # ms
        print("Playing...")
    print("Finished.")

Python variable length arguments

def print_person_varargs(name, *vargs):
    print(name)
    print(vargs)
    for arg in vargs:
        print(arg)


def print_person_kwargs(name, **kwargs):
    print(name)
    print(kwargs)
    for i, j in kwargs.items():
        print(i, j)


print_person_varargs("Jörn", 38, "Emskirchen")
print_person_kwargs("Jörn", age=38, city="Emskirchen")

pytest Tutorial – Part 1

At PyConDE Berlin 2019 Florian Bruhin gave a really nice session about testing with pytest, which I try to recap here.

Writing Tests

If You want to work with pytest you can install it via:

pip install pytest

When you know basic python unittest fixtures, good news ahead:

pytest is compatible and will run your old unittest classes as well, but pytest doesn’t need to have a testclass derived from some subclass.

It is sufficient to have a single python file which name starts with test_ containing a function which name also starts with test_ Continue reading “pytest Tutorial – Part 1”

Software Testing Concepts – Part 1

My Tale of Woe

When I graduated from university and had my first job as a software engineer at Harman Becker Automotive Systems GmbH I should do the parental leave cover for a colleague. He showed me his project, gave me some info e.g. contact person and went off to Canada.

Literally on the second day he was away, the phone started to ring. The OEM had a A++ blocker issue found in the software and everything pointed to the component I was now maintaining. Continue reading “Software Testing Concepts – Part 1”

Python Package parameterized

Stackoverflowing around I found this nice package

https://github.com/wolever/parameterized

Parameterized testing in Python sucks.

parameterized fixes that. For everything. Parameterized testing for nose, parameterized testing for py.test, parameterized testing for unittest.

Reading this description I had very high expectations 🙂

so let’s see if the package can hold up to it. Continue reading “Python Package parameterized”

Flask 1.1 is here!

From the flask release notes:

Returning a dict from a view function will produce a JSON response. This makes it even easier to get started building an API.

To get a minimal REST-Api all you have to do is:

from flask import Flask

app = Flask(__name__)

@app.route('/return_dict', methods=['GET'])
def return_dict():
    return {"x": "1"}


if __name__ == '__main__':
    app.run(debug=True)