LinkedIn Reddit icon

Dunder Doc

by Valdir Stumm Jr

Blog Posts

Tips for boosting your Python scripts

I find myself writing quick command line scripts every so often. They usually automate a random task from my daily routine and end up saving me a bunch of time. These scripts usually start as quick and dirty snippets, but once I figure that they are not a one-off thing, then I iterate to make them more usable. There are several things that I find valuable in scripts like these:

Why I Abandoned Dark Mode

15 years ago, my whole desktop environment was dark. Dark terminal, dark vim, dark graphic environment, and dark mp3 player. It was pretty cool. I felt like a hacker in those unrealistic 90s movies. Whoever stepped into my room would think that I was doing some rocket science. In fact, I was probaby just listening to mp3, learning some bash scripting and taking screenshots to share my cool desktop in online forums.

Writing Scrapy Spiders in 2020

I am a huge fan of Scrapy and I’ve used it extensively for 3+ wonderful years working at Scrapinghub, the company behind this framework. It’s been one and a half year since I used it for the last time, but last week I had to build a spider for a personal project. To my surprise, I am not just rusty but pretty outdated in terms of the new shiny features of Scrapy.

Debugging Python with pudb

Pudb is, in my opinion, the most underrated Python package out there. I know this is a bold statement, but that’s how I feel about it. It helped me so much in a daily basis for so many years and I still feel like not too many people know about it. Debugging in Python There are several good debuggers for Python. I know a ton of people that use pdb, ipdb, VSCode/PyCharm embedded debuggers, among others.

Building a custom Flake8 plugin

Linters are everywhere. Be it in a fancy IDE, a CI pipeline or in the command line, linters help us to spot potential issues in our codebases. My favorite linter is flake8 and I use it in my VSCode setup, in my git pre-commit hooks and CI pipelines. But the thing is that flake8 doesn’t catch all the stuff I wanted it to catch. For example, I’d like my linter to catch the usage of the map and filter functions.

The curious case of the else in Python loops

One of the first things to stand out when I was starting with Python was the else clause. I guess everyone knows the normal usage of such clauses in any programming language, which is to define an alternate path for the if condition. Oddly enough, in Python we can add else clauses in loop constructions, such as for and while. For example, this is valid Python: for number in some_sequence: if is_the_magic_number(number): print('found the magic number') break else: print('magic number not found') Notice how the else is aligned with the for and not with the if.

How to customize your IPython 5+ prompt

IPython is wonderful and I ❤️ it. I can’t see myself using the default Python shell in a daily basis. However, its default prompt kind of annoys me: Some of the things that I dislike: the banner displayed when we start it; the In[x] and Out[x] displayed for inputs and outputs; the newline in between commands; and last, but far from least, the uber-annoying “do you really want to exit?

Python 3 rounding oddities

Rounding a decimal number with Python 3 is as simple as invoking the round() builtin: >>> round(1.2) 1 >>> round(1.8) 2 We can also pass an extra parameter called ndigits, which defines the precision we want in the result. Such parameter defaults to 0, but we can pass anything: >>> round(1.847, ndigits=2) 1.85 >>> round(1.847, ndigits=1) 1.8 And what happens when we want to round a number like 1.5? Will it round it up or down?

Drop Duplicates from a List in Order

Let’s say you have a list containing all the URLs extracted from a web page and you want to get rid of duplicate URLs. The most common way of achieving that might be building a set from that list, given that such operation automatically drops the duplicates. Something like: >>> urls = [ 'http://api.example.com/b', 'http://api.example.com/a', 'http://api.example.com/c', 'http://api.example.com/b' ] >>> set(urls) {'http://api.example.com/a', 'http://api.example.com/b', 'http://api.example.com/c'} The problem is that we just lost the original order of the list.