Python Templates

Enable Javascript for TOC.

Commandline Argument Parsing

Using argparse parser:
#!/usr/bin/env python3

import argparse


def main() -> None:
    # Instantiate the parser
    parser = argparse.ArgumentParser(description='Optional app description')
    # Required positional argument
    parser.add_argument('pos_arg', type=int,
                        help='A required integer positional argument')
    # Optional positional argument
    parser.add_argument('opt_pos_arg', type=int, nargs='?', default=2,
                        help='An optional integer positional argument')
    # Optional argument
    parser.add_argument('--opt_arg', type=int,
                        help='An optional integer argument')
    # Switch
    parser.add_argument('--switch', action='store_true',
                        help='A boolean switch')

    args = parser.parse_args()

    print("Argument values:")
    print(args.pos_arg)
    print(args.opt_pos_arg)
    print(args.opt_arg)
    print(args.switch)

    if args.pos_arg > 10:
        parser.error("pos_arg cannot be larger than 10")

if __name__ == '__main__':
    main()
Source: stackoverflow.com

Classes

Classes boundle methods on their data (static and class variables). When the methods or variables start with an __ they are private, otherwise they are public.
#!/usr/bin/env python3

class Student():
	# private static variables
	__student_count = 0

	def __init__(self, surname, firstname):
		# private class variables
		self.__surname = surname
		self.__firstname = firstname
		self.__student_count = self.__student_count + 1

	def name(self):
		return self.__firstname + " " + self.__surname

	# converts object to string
	def __str__(self):
		return "Student(" + self.name() + ")"

	# similar to __str__()
	def __repr__(self):
		return self.__str__()

	# called by len(obj) method
	def __len__(self):
		return 192

Exceptions

In Python you can create your own exceptions. A list of built-in exception can be found here.
import sys, traceback

def do_something():
    raise IndexError("Index %d not allowed" % -12)

try:
    do_something()
except FileNotFoundError as fnfe:
	# will print "Error: [Errno 2] No such file or directory: 'myfile.txt'"
	print("Error: {}".format(fnfe))
except (RuntimeError, TypeError, NameError):
	# will forward the exception to the caller
	raise
except Exception as e:
	print(f"Caught unexpected exception: {e}")
	print("-" * 60)
	# prints the stacktrace, the exception type and message (works also for logger)
	print(traceback.format_exc())
	print("-" * 60)
else:
	print("No exception was thrown!")
finally:
	close_something()

(Asynchronous) Context Manager

#!/usr/bin/env python3
#
# Example to create classes to be used with 'async with.."
#

import asyncio

class MyConnection:

	# Static constructor method
	def connect(name):
		return MyConnection.__AsyncContextManager(name)

	class __AsyncContextManager:
		def __init__(self, name):
			self.__name = name;

		async def print_name(self):
			print("my name is %s" % self.__name);

		# Method to be performed on enter - e.g. for connect
		async def __aenter__(self):
			print('%s: entering context' % self.__name)
			return self

		# Method to be performed on exit - e.g. to disconnect
		async def __aexit__(self, exc_type, exc, tb):
			print('%s: exit context' % self.__name)


async def doit():
	name = "kkr"
	async with MyConnection.connect(name) as obj:
		await obj.print_name()

if __name__ == '__main__':
	# Need eventloop to perform asynchronous methods
	asyncio.get_event_loop().run_until_complete(doit())

Modules

Modules in Python are either simple python files in the same directory (then they are included with import NAME when the file was NAME.py) or folders, which contain python files - mainly classes (then the import syntax changes to from MODULE import NAME, where MODULE is the folder name and the file was NAME.py).

Modules in folders must have at least an empty file __init__.py, which can have the following content:

# To allow 'from MODULE import *', where MODULE is the directory name and the file is called NAME.py
__all__ = ["NAME"]

# To allow 'import MODULE'
from . import NAME

Inheritance

When in Python classes are inherit each other, the base-class can be called with super().
#!/usr/bin/env python3

class Person():
	def __init__(self):
		self.surname = ""
		self.firstname = ""


class Student(Person):
	def __init__(self):
		super().__init__()
		self.semester = 1

Imports and Modules

The following syntax can be used for importing modules:
import matplotlib.pyplot

matplotlib.pyplot.plot(...)
When importing a class matplotlib.pyplot, the whole module and class name must be used every time.
from matplotlib import pyplot

pyplot.plot(...)
When importing a class pyplot from module matplotlib, the class name must be unique in your code - but the class can be referenced by its name.
from matplotlib import pyplot as plt

plt.plot(...)
When importing a class pyplot from module matplotlib and name it plt, the class can be reference by the name plt.

Websockets

The following example is based on the python3-websockets API:
#!/usr/bin/env python3

import asyncio
# sudo apt install python3-websockets
import websockets

async def hello():
    uri = "ws://echo.websocket.org/"
    async with websockets.connect(uri) as wsock:
        await wsock.send("huhu")
        result = await wsock.recv()
        print("result is " + result)

asyncio.get_event_loop().run_until_complete(hello())

JSON

JSON is supported in python natively.
import json

received = '{"category":"welcome", "values":{"name":"KKR"}}'
json_recv = json.loads(received)

for key in json_recv["values"]:
    print(key + "=>" + json_recv["values"][key])

list = { "speed": 12, "position":"Ingolstadt" }
json_list = json.dumps(list)
print(json_list)
The same example with loading and saving to disk:
with open('settings.json') as json_file:
    settings = json.load(json_file)

settings['last_changed'] = datetime.strftime("%Y-%m-%d %H:%M:%S")

with open('settings.json', 'w') as outfile:
    json.dump(settings, outfile)

Plotting Graphs

The following code will plot a parabola into the file graph.png:
#!/usr/bin/env python3

# sudo apt install python3-matplotlib
import matplotlib.pyplot as plt

xs = [x   for x in range(-10,10)]
ys = [x*x for x in xs]
plt.plot(xs, ys)
plt.savefig("graph.png")

The following code will plot a histogram into the file histogram.png:

#!/usr/bin/env python3

# sudo apt install python3-matplotlib
import matplotlib.pyplot as plt

data = {-10:1, -9:2, -8:4, -7:12, -6:11, -5:3, -4:0.1, -3:-2, -2:-4, -1:-5,
        0:-4, 1:-3, 2:-2, 3:-1, 4:0.2, 5:2, 6:4, 7:6, 8:12, 9:15, 10:25}
plt.title("Example Histogram")
plt.xlabel("Temperature")
plt.ylabel("Hits")
plt.grid(True)
plt.bar(data.keys(), data.values())
plt.savefig("histogram.png")

The following code will plot a logarithmic histogram into the file histogram.png:

#!/usr/bin/env python3

# sudo apt install python3-matplotlib
import matplotlib.pyplot as plt

data = {-10:1, -9:2, -8:4, -7:12, -6:11, -5:3, -4:0.1, -3:-2, -2:-4, -1:-5,
        0:-4, 1:-3, 2:-2, 3:-1, 4:0.2, 5:2, 6:4, 7:6, 8:12, 9:15, 10:25}
plt.title("Logarithmic Histogram")
plt.yscale("log")
plt.grid(b=True, which="major", linestyle="-")
plt.grid(b=True, which="minor", linestyle="--")
plt.bar(data.keys(), data.values())
plt.savefig("histogram_log.png")