My personal collection of Python (and Django) recipes

“And now something completely different”: my personal, living collection of Python (and Django) recipes.

How to make an installable Python package

For a Python package to be installable the project should have a file named setup.py in the project root. setup.py should have a call to the setup function from setuptools which takes at least the following arguments:

from setuptools import setup

setup(
    name="tweeter",
    version="0.0.1",
    description="Tweet bot",
    author="You don't want to know",
    packages=["tweeter"],
    install_requires=["tweepy>=3.8.0"],
)
  • name is the package name, tweeter in my example
  • version is the package version
  • description is a short summary of the package’s purpose
  • author is of course the package’s author
  • packages is the name of your package
  • install_requires is a list of dependencies for the package, much like “dependecies” in package.json

Once a package is ready you can install it with pip, either from the Python package index (if you published it there) or from a Github repo (see below).

Reference: Writing the setup script.

How to install a Python package from a Github repo

Long story short: installing a zipped version is even better than cloning the whole repo, and reportedly faster. All you need to do is grab the URL from Github:

pip install https://github.com/valentinogagliardi/tweeter/archive/0.0.1.zip

Now you might ask: how to install a Python package from a Github branch? Look again at the URL below. 0.0.1 is the branch. Easy peasy!

How to install a Python package from a Github repo with requirements.txt

It’s easy as declaring the same URL in requirements.txt:

https://github.com/valentinogagliardi/tweeter/archive/0.0.1.zip

Python dictionaries and the get method

Python dictionaries are containers for key/value pairs (much like JavaScript objects):

my_dict = {
    "name": "John", 
    "city": "Rome", 
    "age": 44
}

To access or modify a value from the dictionary simply call the key in square brackets:

my_dict = {
    "name": "John", 
    "city": "Rome", 
    "age": 44
}

my_dict["name"]

my_dict["city"] = "Florence"

Now, things get interesting when trying to access a non-existent key:

my_dict = {
    "name": "John", 
    "city": "Rome", 
    "age": 44
    }

my_dict["not here"]

You get:

Traceback (most recent call last):
  File "<input>", line 1, in <module>
KeyError: 'not here'

The KeyError exception is raised any time Python can’t find a dictionary’s key. To catch these kind of errors you can use try/catch, but that would be not optimal, especially for multiple objects.

Luckily the dict object in Python has a get() method which is more convenient than direct access because:

  • it does not raise any exception
  • you can provide a default value

Here’s dict.get() in action:

my_dict = {
    "name": "John", 
    "city": "Rome", 
    "age": 44
    }

# No error is thrown
my_dict.get("not here")

# Provide a default
my_dict.get("not here", "a default value")

How to get a random object for a model with the Django ORM

Imagine a simple Django model:

from django.db import models


class Link(models.Model):
    title = models.CharField(max_length=250, unique=True)
    url = models.URLField(max_length=250, unique=True)
    tags = models.ManyToManyField(Tag)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.title}"

Imagine also you have a bunch of objects for this model in the database and you want to fetch a random object with the Django ORM. Here’s how you’d go:

link = Link.objects.order_by("?").first()

Reference: order-by.

Python recipes: filtering lists with list comprehension

To filter a list in Python I prefer using list comprehension over high order functions (like in JavaScript):

numbers = [3, 4, 88, 85, 99, 150]


def greater_than(x, y=0):
    return x > y


filtered_numbers = [n for n in numbers if greater_than(n, 88)]

Python recipes: the sum built-in

The sum() built-in function in Python takes an iterable (like a list) and returns the sum of said iterable. If you pass a list of numbers and booleans the latter are converted respectively to 0 for False and 1 for True. Is that some sort of type coercion like in JS? Python:

sum([3, 4, 5, 6, False, True, True, True])

# Output: 21

The sum() function resembles JavaScript’s reduce:

[3, 4, 5, 6, false, true, true, true].reduce(function(accumulator, element) {
  return accumulator + element;
});

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.