2021
Introduction⚑
- New: Simplify the landing page text.
- Reorganization: Merge the Meta article into the index.
Projects⚑
-
Improvement: Add mkdocs-newsletter as a dormant plant.
MkDocs plugin to show the changes of documentation repositories in a user friendly format, at the same time that it's easy for the authors to maintain.
It creates daily, weekly, monthly and yearly newsletter articles with the changes of each period. Those pages, stored under the
Newsletters
section, are filled with the changes extracted from the commit messages of the git history. The changes are grouped by categories, subcategories and then by file using the order of the site's navigation structure. RSS feeds are also created for each newsletter type, so it's easy for people to keep updated with the evolution of the site. -
Reorganization: Update and reorganize projects.
Following the digital garden metaphor
-
Reorganization: Merge the wish_list article into the projects.
- New: Add seed to follow the updates of software.
- New: Add seed to automatically update the dockers of maintained services.
-
Improvement: Explain the updates on the repository-orm project.
In the latest version
0.2.0
, we added:- Support for the TinyDB repository.
- Support for regular expressions in the
search
method. - Easier repository loading with
load_repository
function.
-
Improvement: Add a link to the meilisearch blog.
-
New: Create the quantified self project.
-
New: Sketch how to automate repetitive tasks prompted by email events.
Most of the emails I receive require repetitive actions that can be automated, I've stumbled upon notmuchmail, which looks very promising. A friend suggested to use afew for tagging, and I'd probably use alot to interact with the system (and finally be able to use email from the cli).
-
Improvement: Add interesting interface.
For the interface adri's memex looks awesome! It's inspired in the Andrew Louis talk Building a Memex whose blog posts seems to be a gold mine.
Also look at hpi's compilation.
-
New: Sketch how to improve the launching of applications with i3wm.
In the past I tried installing rofi without success, I should try again. If the default features are not enough, check adi1090x's custom resources.
-
Improvement: Show the changes of repository-orm 0.3.1.
+* Add
first
andlast
methods to the repositories. +* Make entityid_
definition optional. +* add_model_name
attribute to entities. -
Improvement: Add woop awesome quantified self resources to the research list.
- New: Add project to migrate software bug tracker to a vendor free one like
git-bug
. -
New: Improve the notification management in Linux.
Create new seed project to be able to group and silence the notifications under a custom logic. For example:
- If I want to focus on a task, only show the most important ones.
- Only show alerts once every X minutes. Or define that I want to receive them the first 10 minutes of every hour.
- If I'm not working, silence all work alerts.
-
New: Improve the hard drive monitor system.
Create new seed project to use something like scrutiny (there's a linuxserver image) to collect and display the information. For alerts, use one of their supported providers.
-
New: Aggregate all notifications.
Instead of reading the email, github, gitlab, discourse, reddit notifications, aggregate all in one place and show them to the user in a nice command line interface.
For the aggregator server, my first choice would be gotify.
- New: Add seedling project to create factoryboy factories from pydantic models automatically.
- New: Explain the idea of how to improve the record of ideas, tasks,.
- New: Add git-bug as an interesting distributed issue tracker.
-
New: Add the Improve the reliability of the Open Science collections project.
The current free knowledge efforts: are based on the health of a collection of torrents. This project aims to create a command line tool or service that makes it easier to automate the seeding of ill torrents.
-
New: Add the Monitor and notify on disk prices project.
Diskprices.com sorts the prices of the disks on the different amazon sites based on many filters. It will be interesting to have a service that monitors the data on this site and alerts the user once there is a deal that matches its criteria.
-
Reorganization: Move the automation of computer file management project to the projects page.
- Reorganization: Move the dying projects below the seeds as they are less important.
-
New: Introduce seedling self-hosted map project.
I love maps, as well as traveling and hiking. This project aims to create a web interface that let's me interact with the data gathered throughout my life. I'd like to:
- Browse the waypoints and routes that I've done.
- Create routes and export the gpx.
- Be able to search through the data
- Plan trips
-
New: Add the Life seedling project.
Life is a real time sandbox role game where you play as yourself surviving in today's world.
-
New: Add bruty to the dormant plant projects.
bruty is a Python program to bruteforce dynamic web applications with Selenium.
-
Improvement: Add rsarai hq to interesting sources for lifelogging.
-
New: Introduce pynbox the inbox management tool.
Pynbox is a tool to improve the management of ideas, tasks, references, suggestions when I'm not in front of the computer. Right now I've got Markor for Android to register these quicknotes, but the reality is that I don't act upon them, so it's just a log of tasks that never get done, and ideas, references and suggestions that aren't registered in my knowledge or media management systems.
On the computer there are also cases of tasks that are not worth registering in the task management system, or ideas that I get at a moment but don't have time to process at the moment.
The idea then is to automatically sync the Android quicknote with syncthing, and have a special format for the file that allows
pynbox
to extract the elements from that file to the "inbox system". For example: +t. buy groceries tv. IT crowd i. Improve the inbox management I want a system to improve ...
Gets introduced in the "inbox system" as a task, a TV suggestion and an idea.
-
New: Introduce nyxt as a solution for a better browser.
-
New: Introduce the shared accounting seed project.
I use beancount for my personal accounting, I'd like to have a system that integrates more less easily with beancount and let's do a shared accounting with other people, for example in trips. I've used settle up in the past but it requires access to their servers, and an account linked to google, facebook or one you register in their servers.
I've looked at facto but it uses a logic that doesn't apply to my case, it does a heavy use on a common account, instead +of minimizing the transactions between the people. I also tried tabby, even though they still don't support Docker, but it doesn't suit my case either :(.
Until a new solution shows up, I'll go with Tricky Tripper available in F-Droid, and manage the expenses myself and periodically send the html reports to the rest of the group.
-
Improvement: Add quickwit as an interesting database solution for personal knowledge search engine.
- New: Promote the automation of email management project to seedling.
-
New: Introduce the pomodoro command line seed project.
Command line to help with the pomodoro workflow, besides the basic stuff it will interact with the task manager, activitywatch and the notifications system.
-
New: Introduce the ordered list of digital gardens project.
Use best-of-lists to create an awesome list of digital gardens.
-
Correction: Clean up deprecated projects.
-
New: Add seed to self host a routing web application.
Host and play around with brouter and brouter-web.
Activism⚑
-
New: Introduce the anonymous feedback tool to improve diversity, equity and inclusion in an organization.
Anonymous Feedback is a communication tool where people share feedback to teammates or other organizational members while protecting their identities.
Until the safe space is built where direct feedback is viable, anonymous feedback gives these employees a mechanism to raise their concerns, practice their feedback-giving skills, test the waters, and understand how people perceive their constructive (and sometimes critical) opinions, thus building the needed trust.
-
New: Define Diversity, Equity and Inclusion.
-
Diversity is the representation and acknowledgement of the multitudes of identities, experiences, and ways of moving through the world. This includes—but is not limited to—ability, age, citizenship status, criminal record and/or incarceration, educational attainment, ethnicity, gender, geographical location, language, nationality, political affiliation, religion, race, sexuality, socioeconomic status, and veteran status. Further, we recognize that each individual's experience is informed by intersections across multiple identities.
-
Equity seeks to ensure respect and equal opportunity for all, using all resources and tools to elevate the voices of under-represented and/or disadvantaged groups.
-
Inclusion is fostering an environment in which people of all identities are welcome, valued, and supported. An inclusive organization solicits, listens to, learns from, and acts on the contributions of all its stakeholders.
-
-
New: Introduce Anti-transphobia.
Anti-transphobia being reductionist is the opposition to the collection of ideas and phenomena that encompass a range of negative attitudes, feelings or actions towards transgender people or transness in general. Transphobia can include fear, aversion, hatred, violence, anger, or discomfort felt or expressed towards people who do not conform to social gender expectations. It is often expressed alongside homophobic views and hence is often considered an aspect of homophobia.
-
New: Introduce arguments against terf ideology.
TERF is an acronym for trans-exclusionary radical feminist. The term originally applied to the minority of feminists that expressed transphobic sentiments such as the rejection of the assertion that trans women are women, the exclusion of trans women from women's spaces, and opposition to transgender rights legislation. The meaning has since expanded to refer more broadly to people with trans-exclusionary views who may have no involvement with radical feminism.
Antifascism⚑
-
New: Introduce antifascism.
Antifascism is a method of politics, a locus of individual and group self-indentification, it's a transnational movement that adapted preexisting socialist, anarchist, and communist currents to a sudden need to react to the fascist menace (Mark p. 11). It's based on the idea that any oppression form can't be allowed, and should be actively fought with whatever means are necessary.
Antifascist Actions⚑
-
New: A fake company and five million recycled flyers.
A group of artists belonging to the Center for political beauty created a fake company Flyerservice Hahn and convinced more than 80 regional sections of the far right party AfD to hire them to deliver their electoral propaganda.
They gathered five million flyers, with a total weight of 72 tons. They justify that they wouldn't be able to lie to the people, so they did nothing in the broader sense of the word. They declared that they are the "world wide leader in the non-delivery of nazi propaganda". At the start of the electoral campaign, they went to the AfD stands, and they let their members to give them flyers the throw them to the closest bin. "It's something that any citizen can freely do, we have only industrialized the process".
They've done a crowdfunding to fund the legal process that may result.
Feminism⚑
Privileges⚑
-
New: Feminist analysis of privileges and rights.
Privileges are a group of special structural benefits, social advantages, that a group holds over another. So they are elements that should be removed from our lives.
Some of the topics included are:
- What's the difference between privilege and right
- What can we do to fight the privileges?
Free Knowledge⚑
-
New: Introduce how to contribute to the free knowledge initiative.
One of the early principles of the internet has been to make knowledge free to everyone. Alexandra Elbakyan of Sci-Hub, bookwarrior of Library Genesis, Aaron Swartz, and countless unnamed others have fought to free science from the grips of for-profit publishers. Today, they do it working in hiding, alone, without acknowledgment, in fear of imprisonment, and even now wiretapped by the FBI. They sacrifice everything for one vision: Open Science.
If you want to know how to contribute, check the article.
Life Management⚑
-
Reorganization: Split the life automation article into life management and process automation.
I understand life management as the act of analyzing yourself and your interactions with the world to define processes and automations that shape the way to efficiently achieve your goals.
I understand process automation as the act of analyzing yourself and your interactions with the world to find the way to reduce the time or willpower spent on your life processes.
Time Management⚑
-
New: Introduce the time management concept.
Time management is the process of planning and exercising conscious control of time spent on specific activities, especially to increase effectiveness, efficiency, and productivity. It involves a juggling act of various demands upon a person relating to work, social life, family, hobbies, personal interests, and commitments with the finiteness of time. Using time effectively gives the person "choice" on spending or managing activities at their own time and expediency.
-
New: Start analyzing the ways to reduce the time spent doing unproductive tasks.
By minimizing the context switches and managing the interruptions.
-
Improvement: Explain how to improve your efficiency by better using your everyday tools.
-
Improvement: Add two more ways to avoid loosing time in unproductive tasks.
- New: Explain how to improve efficiency by taking care of yourself.
- New: Explain how to prevent blocks by efficiently switching mental processes.
Task Management⚑
-
New: Introduce the task management concept.
Task management is the process of managing a task through its life cycle. It involves planning, testing, tracking, and reporting. Task management can help either individual achieve goals, or groups of individuals collaborate and share knowledge for the accomplishment of collective goals.
-
Improvement: Introduce the main task management tools.
The inbox does not refer only to your e-mail inbox. It is a broader concept that includes all the elements you have collected in different ways: tasks you have to do, ideas you have thought of, notes, bills, business cards, etc…
The task manager tool to make your interaction with the tasks easier. You can start with the simplest task manager, a markdown file in your computer with a list of tasks to do. Annotate only the actionable tasks that you need to do today, otherwise it can quickly grow to be unmanageable.
-
Improvement: Add the benefits when you do task management well, and the side effects if you do it wrong.
- Improvement: Add a small guide on how to introduce yourself into task management.
Task Management Workflows⚑
-
New: Introduce the main task management workflows.
Task management can be done at different levels. All of them help you in different ways to reduce the mental load, each also gives you extra benefits that can't be gained by the others. Going from lowest to highest abstraction level we have:
- Pomodoro.
- Task plan.
- Day plan.
- Week plan.
- Month plan.
- Semester plan.
In the commit I've detailed the Pomodoro technique and the task, day and week plans.
-
New: Explain the difference of surfing the hype flow versus following a defined plan.
Interruption Management⚑
-
New: Introduce the interruption management concept.
Interruption management is the life management area that gathers the processes to minimize the time and willpower toll consumed by interruptions.
The article proposes a way to analyze your existent interruptions and define how can you improve your interaction with them. I've applied it both to my work and personal interruptions.
-
Improvement: Explain what to do once you have the interruption analysis.
Work Interruption Analysis⚑
- Improvement: Add analysis of instant message interruptions.
Personal Interruption Analysis⚑
- Improvement: Add analysis of instant message interruptions.
Money Management⚑
- Reorganization: Move the accounting automation to money management.
Email Management⚑
- New: Explain how I configure and interact with email efficiently.
Email Automation⚑
- New: Explain how setup an infrastructure to automate.
Music Management⚑
- New: Introduce how I manage my music library.
MusicBrainz⚑
-
New: How to contribute to MusicBrainz.
MusicBrainz is an open music encyclopedia that collects music metadata and makes it available to the public.
MusicBrainz aims to be:
- The ultimate source of music information by allowing anyone to contribute and releasing the data under open licenses.
- The universal lingua franca for music by providing a reliable and unambiguous form of music identification, enabling both people and machines to have meaningful conversations about music.
Like Wikipedia, MusicBrainz is maintained by a global community of users and we want everyone — including you — to participate and contribute.
Book Management⚑
-
New: Introduce the book management concept.
Book management is the set of systems and processes to get and categorize books so it's easy to browse and discover new content. It involves the next actions:
- Automatically index and download metadata of new books.
- Notify the user when a new book is added.
- Monitor the books of an author, and get them once they are released.
- Send books to the e-reader.
- A nice interface to browse the existent library, with the possibility of filtering by author, genre, years, tags or series.
- An interface to preview or read the items.
- An interface to rate and review library items.
- An interface to discover new content based on the ratings and item metadata.
I haven't yet found a single piece of software that fulfills all these needs, in the article I tell you about Readarr, Calibre-web, [calibre]((https://manual.calibre-ebook.com/), Polar bookself, GCStar, and how they interact with each other.
-
Improvement: Add link to the calibre-web kobo integration project.
Map Management⚑
-
New: How I manage maps in my life.
For navigating on the go, I strongly recommend OSMand+, for browsing maps in the browser, use OpenStreetMaps or CyclOSM if you want to move by bike.
To plan routes, you can use brouter.de, it works perfectly for bikes. For hiking is awesome too, it shows you a lot of data needed to plan your tracks (check the settings on the right). If you want to invest a little more time, you can even set your personalize profiles, so that the routing algorithm prioritizes the routes to your desires. It's based on brouter and both can be self-hosted, although brouter does not yet use Docker.
Instant Messages Management⚑
- New: Explain how I configure and interact with chat applications efficiently.
Process Automation⚑
- Improvement: Add xkcd comics that gather the essence and pitfalls of process automation.
Virtual Assistant⚑
- New: Introduce project with kalliope.
- New: Explain the Speech-To-Text open source solutions.
Health⚑
Sleep⚑
-
Humans cycle through two types of sleep in a regular pattern throughout the night with a period of 90 minutes. They were called non-rapid eye movement (NREM) and rapid eye movement (REM).
I answer the questions:
- What is the period of the REM/NREM cycle?
- What happens to your body in REM and NREM phases?
- How does the ratio of REM/NREM changes throughout the night? with a possible explanation.
- Why sleeping 6 hours can make you loose up to 90% of your REM or NREM phases?
-
New: Explain sleeping time and sense distortions.
Answer the questions:
- Why time feels longer in our dreams?
- How do we loose awareness of the outside world when sleeping?
Teeth⚑
-
New: Explain how to take care of your teeth.
A full guide on why should you take care of your teeth, the description on how the basic oral diseases work, why and how to brush your teeth, floss and usage of mouthwash
-
Correction: Recommend a regular clean instead of a deep clean.
Deep cleaning⚑
-
New: Explain what a deep cleaning is and when should you do it.
Analyze the reasons why would you need to do this procedure, how it works, when you need to do it, side effects and scientific evidences of it's effectiveness.
Fitness Tracker⚑
-
New: Introduce the fitness band in your life automation.
Fitness tracker or activity trackers are devices or applications for monitoring and tracking fitness-related metrics such as distance walked or run, calorie consumption, and in some cases heartbeat. It is a type of wearable computer.
Explain also why it's interesting
-
Improvement: Discovery of wasp-os and Colmi P8.
wasp-os is an open source firmware for smart watches that are based on the nRF52 family of microcontrollers. Fully supported by gadgetbridge, Wasp-os features full heart rate monitoring and step counting support together with multiple clock faces, a stopwatch, an alarm clock, a countdown timer, a calculator and lots of other games and utilities. All of this, and still with access to the MicroPython REPL for interactive tweaking, development and testing.
One of the supported devices, the Colmi P8, looks really good.
Amazfit Band 5⚑
-
New: Add insights on sleep detection.
The sleep tracking using Gadgetbridge is not good at all. After two nights, the band has not been able to detect when I woke in the middle of the night, or when I really woke up, as I usually stay in the bed for a time before standing up. I'll try with the proprietary application soon and compare results.
-
New: Explain how to upgrade the firmware.
Gadgetbridge people have a guide on how to upgrade the firmware, you need to get the firmware from the geek doing forum though, so it is interesting to create an account and watch the post.
-
Improvement: Add insights on sleep tracking.
You can't use the Withings sleep analyzer without their app (as expected), maybe the Emfit QS is the way to go.
Coding⚑
-
New: Introduce Vue.js.
Vue.js is a progressive framework for building user interfaces.
Generic Coding Practices⚑
Program Versioning⚑
-
New: Define how to use versioning in software.
A long article on how to use versioning both as a developer and as a consumer. It includes:
- Deciding what version system to use for your programs.
- How to evolve your code version.
- Deciding how to manage the versions of your dependencies.
- A huge rant on Upper version pinning.
- When to use lower version pinning.
- How to automatically upgrade and test your dependencies.
- Monitor your dependencies evolution.
Keep a Changelog⚑
-
New: Introduce the Changelog practice.
A changelog is a file which contains a curated, chronologically ordered list of notable changes for each version of a project.
It's purpose is to make it easier for users and contributors to see precisely what notable changes have been made between each release (or version) of the project.
In the article we added:
- Guidelines on how to build good changelogs
- How to reduce the effort required to maintain a changelog
-
New: Introduce Semantic Versioning.
Semantic Versioning is a way to define your program's version based on the type of changes you've introduced. It's defined as a three-number string (separated with a period) in the format of
MAJOR.MINOR.PATCH
.Also included in the article is:
Calendar Versioning⚑
-
New: Start explaining how to write good documentation for a software project.
It doesn't matter how good your program is, because if its documentation is not good enough, people will not use it.
People working with software need different kinds of documentation at different times, in different circumstances, so good software documentation needs them all. In this first iteration, I define the five kinds of documentation, and give the ideas to write good introduction and get started sections.
-
New: Introduce Calendar Versioning.
Calendar Versioning is a versioning convention based on your project's release calendar, instead of arbitrary numbers.
CalVer suggests version number to be in format of:
YEAR.MONTH.sequence
. For example,20.1
indicates a release in 2020 January, while20.5.2
indicates a release that occurred in 2020 May, while the2
indicates this is the third release of the month.
Python⚑
- New: Explain how to check if a loop ends completely.
- New: Explain how to merge lists and dictionaries.
- New: Explain how to create your own exceptions.
- New: Add python landing page.
-
Improvement: Add aiomultiprocess to the list of libraries to test.
aiomultiprocess: Presents a simple interface, while running a full AsyncIO event loop on each child process, enabling levels of concurrency never before seen in a Python application. Each child process can execute multiple coroutines at once, limited only by the workload and number of cores available.
-
New: Add interesting links on how to write good documentation.
I would like to refactor divio's and Vue's guidelines and apply it to my projects.
-
Improvement: Add FastAPI docs as a model to study and follow.
-
New: Add apprise to the interesting libraries to explore.
apprise: Allows you to send a notification to almost all of the most popular notification services available to us today such as: Linux, Telegram, Discord, Slack, Amazon SNS, Gotify, etc. Look at all the supported notifications
(¬º-°)¬
. -
New: Add kivi and kivimd to the interesting libraries to explore.
kivi is used to create android/Linux/iOS/Windows applications with python. Use it with kivimd to make it beautiful, check the examples and the docs.
-
New: Add parso library to interesting libraries to explore.
parso is a library to parse Python code.
-
Improvement: Add textual as interesting library to explore.
textual: Textual is a TUI (Text User Interface) framework for Python using Rich as a renderer.
-
New: Add schedule to interesting libraries to explore.
schedule is a Python job scheduling for humans. Run Python functions (or any other callable) periodically using a friendly syntax.
-
New: Add tryceratops to interesting linters to try.
tryceratops is a linter of exceptions.
Pydantic Field Types⚑
-
New: Introduce the asyncio library.
asyncio is a library to write concurrent code using the async/await syntax.
asyncio is used as a foundation for multiple Python asynchronous frameworks that provide high-performance network and web-servers, database connection libraries, distributed task queues, etc.
asyncio is often a perfect fit for IO-bound and high-level structured network code.
-
New: Limit concurrency.
Use
asyncio.Semaphore
.sem = asyncio.Semaphore(10) async with sem: # work with shared resource
-
New: Using constrained strings in list attributes.
import re import pydantic from pydantic import Field from typing import List class Regex(pydantic.ConstrainedStr): regex = re.compile("^[0-9a-z_]*$") class Data(pydantic.BaseModel): regex: List[Regex] data = Data(**{"regex": ["abc", "123", "asdf"]}) print(data) print(data.json())
Pipenv⚑
- New: Explain how to set cookies and headers in responses.
-
New: Introduce the AWS SDK library and explain how to test it.
Boto3 is the AWS SDK for Python to create, configure, and manage AWS services, such as Amazon Elastic Compute Cloud (Amazon EC2) and Amazon Simple Storage Service (Amazon S3). The SDK provides an object-oriented API as well as low-level access to AWS services.
For testing, try to use moto, using the Botocore's stubber as fallback option.
-
New: Explain how to test ec2, route53, s3, and rds resources.
- New: Explain how to test vpc and auto scaling group resources.
-
Improvement: Explain how to extract the instance when testing autoscaling groups.
Also track the issue to add support to launch templates.
-
Correction: Add note that pagination is not yet supported when testing route53.
I've opened an issue to solve it.
- Improvement: Monitor motor issue with the
cn-north-1
rds and autoscaling endpoints. - New: Testing full screen applications.
-
To map an action to two key presses use
kb.add('g', 'g')
. -
New: Add note on how to debug the styles of the components.
Set the style to
bg:#dc322f
and it will be highlighted in red. -
New: How to use Conditional Containers.
from prompt_toolkit.layout import ConditionalContainer from prompt_toolkit.filters.utils import to_filter show_header = True ConditionalContainer( Label('This is an optional text'), filter=to_filter(show_header) )
-
New: Introduce the pipenv package manager.
Pipenv is a tool that aims to bring the best of all packaging worlds (bundler, composer, npm, cargo, yarn, etc.) to the Python world.
Poetry⚑
-
Improvement: Explain how to ignore a linter error and a type error.
With
# type: ignore # noqa: W0212
-
Improvement: Explain how to define the type hints of functions and methods that use subclasses.
It's a complex topic that has taken me many months to get it right :).
-
New: Explain how to write type hints for generator functions.
-
New: Explain how to log in using pass.
pass show dockerhub | docker login --username foo --password-stdin
-
New: Explain how not to store the credentials in plaintext.
It doesn't work, don't go this painful road and assume that docker is broken.
The official steps are horrible, and once you've spent two hours debugging them, you won't be able to push or pull images with your user.
-
Improvement: Explain how to change the command line help description.
-
New: Explain how to use watchtower to keep docker containers updated.
With watchtower you can update the running version of your containerized app simply by pushing a new image to the Docker Hub or your own image registry. Watchtower will pull down your new image, gracefully shut down your existing container and restart it with the same options that were used when it was deployed initially.
-
Correction: Explain how to run the watchtower checks immediately.
With the
--run-once
flag -
New: Invoke other commands from a command.
This is a pattern that is generally discouraged with Click, but possible nonetheless. For this, you can use the
Context.invoke()
orContext.forward()
methods. -
New: Define a TypeVar with restrictions.
from typing import TypeVar AnyStr = TypeVar('AnyStr', str, bytes)
-
New: Use a constrained TypeVar in the definition of a class attributes.
If you try to use a
TypeVar
in the definition of a class attribute:class File: """Model a computer file.""" path: str content: Optional[AnyStr] = None # mypy error!
mypy will complain with
Type variable AnyStr is unbound [valid-type]
, to solve it, you need to make the class inherit from theGeneric[AnyStr]
.class File(Generic[AnyStr]): """Model a computer file.""" path: str content: Optional[AnyStr] = None
-
New: Deeply introduce Poetry, a python package manager.
Poetry is a command line program that helps you declare, manage and install dependencies of Python projects, ensuring you have the right stack everywhere.
-
New: Debugging why a package is not updated to the latest version.
- New: Checking what package is using a dependency.
- New: Try to use
pass
as a keyring backend to store the PYPI token. -
Correction: Warn against upper version pinning.
The main problem is that
poetry add
does upper pinning of dependencies by default, which is a really bad idea.
Dash⚑
-
New: Explain how to log python program exceptions better than to a file.
Using
logging
to write write exceptions and breadcrumbs to a file might not be the best solution because unless you look at it directly most errors will pass unnoticed.To actively monitor and react to code exceptions use an application monitoring platform like sentry.
In the article I explain what are the advantages of using this solution and do a comparison between Sentry and GlitchTip.
-
New: Testing Dash applications.
dash.testing
provides some off-the-rack pytest fixtures and a minimal set of testing APIs with our internal crafted best practices at the integration level. The commit includes a simple example and some guides on how to test Dash application. -
New: Test programs that use
sh
.sh
can be patched in your tests the typical way, withunittest.mock.patch()
:from unittest.mock import patch import sh def get_something(): return sh.pwd() @patch("sh.pwd", create=True) def test_something(pwd): pwd.return_value = "/" assert get_something() == "/"
Code Styling⚑
-
Improvement: Don't use try-except to initialize dictionaries.
Instead of:
try: dictionary['key'] except KeyError: dictionary['key'] = {}
Use:
dictionary.setdefault('key', {})
-
New: Introduce the awesome, life saving library
pydantic_factories
.Pydantic factories is a library offers powerful mock data generation capabilities for pydantic based models and dataclasses. It automatically creates FactoryBoy factories from a pydantic model.
from datetime import date, datetime from typing import List, Union from pydantic import BaseModel, UUID4 from pydantic_factories import ModelFactory class Person(BaseModel): id: UUID4 name: str hobbies: List[str] age: Union[float, int] birthday: Union[datetime, date] class PersonFactory(ModelFactory): __model__ = Person result = PersonFactory.build()
-
Reorganization: Moved the semantic versioning commit guidelines to the semver article.
DeepDiff⚑
-
Correction: Remove murmur from the installation steps.
It seems it's the default for the new versions
-
Improvement: Add warning that regular expressions are not yet supported.
Until #239 is merged, the official library doesn't support searching for regular expressions. You can use my fork instead.
-
Improvement: Remove advice to use my fork instead.
The original one has already merged my PR
\\ ٩( ᐛ )و //
. Beware though as theregexp
are not enabled by default (against my will). You need to use theuse_regexp=True
as an argument togrep
orDeepSearch
.
Properties⚑
-
New: Explain how to generate your own attributes.
We earlier used lazy_attribute but if you want to use Faker inside the attribute definition, you're going to have a bad time. The new solution uses the creation of custom Fake providers.
-
New: Automatically generate a factory from a pydantic model.
Sadly it's not yet supported, it will at some point though. If you're interested in following this path, you can start with mgaitan snippet for dataclasses.
-
New: Give an overview on Python's @property decorator.
Package Management⚑
-
New: Explain how to create your own provider.
Useful to generate custom objects for testing purposes.
-
New: Explain how to create
Optional
data.faker-optional
is a custom faker provider that acts as a wrapper over other Faker providers to return their value orNone
. Useful to create data of typeOptional[Any]
. -
New: Create a random string with a defined format.
faker.pystr_format("id-#######{{random_letter}}") 'id-6443059M'
-
faker.ipv4()
If you want a CIDR, use
network=True
. -
New: Compare Poetry, Pipenv and PDM package management tools.
Pipenv has broad support. It is an official project of the Python Packaging Authority, alongside pip. It's also supported by the Heroku Python buildpack, which is useful for anyone with Heroku or Dokku-based deployment strategies.
Poetry is a one-stop shop for dependency management and package management. It simplifies creating a package, managing its dependencies, and publishing it. Compared to Pipenv, Poetry's separate add and install commands are more explicit, and it's faster for everything except for a full dependency install.
I liked Poetry most, and in the end I didn't analyze
pdm
. -
New: Describe what a dependency solver does.
A Solver tries to find a working set of dependencies that all agree with each other. By looking back in time, it’s happy to solve very old versions of packages if newer ones are supposed to be incompatible. This can be helpful, but is slow, and also means you can easily get a very ancient set of packages when you thought you were getting the latest versions.
In the section we compare Pip's and Poetry's solver.
-
It does upper version capping by default, which is becoming a big problem in the Python environment.
This is specially useless when you add dependencies that follow CalVer.
poetry add
packaging will still do^21
for the version it adds. You shouldn’t be capping versions, but you really shouldn’t be capping CalVer.It's equally troublesome that it upper pins the python version.
FastAPI⚑
-
New: Introduce FastAPI the pydantic friendly python framework to build APIs.
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints.
-
New: Sum up the basic documentation.
Explain how to:
- Sending data to the server: Through path parameters, query parameters and body requests.
- Handle errors.
- Update data
- Configure OpenAPI
- Test FastAPI applications
And add a lot of more interesting features I've discovered.
-
New: Explain how to send raw data to the client.
With the
Response
object. - New: Explain how to inject a testing configuration in the tests.
- New: Explain how to deploy it using Docker.
- New: Explain how to show logging messages in the logs.
- New: Explain how to make redirections with fastapi.
- New: Explain how to run a FastAPI server in the background for testing purposes.
- Improvement: Add link to the Awesome FastAPI page.
Plugin System⚑
-
New: Add beets system as a first approach.
When building Python applications, it's good to develop the core of your program, and allow extension via plugins.
I still don't know how to do it, but Beets plugin system looks awesome for a first start.
Flask Restplus⚑
-
New: Introduce the Flask-RESTPlus library.
Flask-RESTPlus is an extension for Flask that adds support for quickly building REST APIs, but I'd use FastAPI instead.
Optimization⚑
-
New: Add tips on how to optimize your python command line tools.
-
Minimize the relative import statements on command line tools:
When developing a library, it's common to expose the main objects into the package
__init__.py
under the variable__all__
. The problem with command line programs is that each time you run the command it will load those objects, which can mean an increase of 0.5s or even a second for each command, which is unacceptable. * Don't dynamically install the package:If you install the package with
pip install -e .
you will see an increase on the load time of ~0.2s. It is useful to develop the package, but when you use it, do so from a virtualenv that installs it directly without the-e
flag.
-
GitPython⚑
-
New: Introduce the python library.
GitPython is a python library used to interact with git repositories, high-level like git-porcelain, or low-level like git-plumbing.
It provides abstractions of git objects for easy access of repository data, and additionally allows you to access the git repository more directly using either a pure python implementation, or the faster, but more resource intensive git command implementation.
Explain how to:
- Initialize or load repositories.
- Make commits.
- Interact with the history.
- Test applications that use it.
-
Improvement: Explain how to get the working directory of a repo.
Using the
working_dir
attribute.perf(python_snippets#Group a list of dictionaries by a specific key) Explain how to group a list of dictionaries by a specific key
With
itertools.groupby
. -
New: Clone a repository.
from git import Repo Repo.clone_from(git_url, repo_dir)
-
New: Create a branch.
new_branch = repo.create_head('new_branch') assert repo.active_branch != new_branch # It's not checked out yet repo.head.reference = new_branch assert not repo.head.is_detached
-
New: Get the latest commit of a repository.
repo.head.object.hexsha
Pytest⚑
-
New: Explain how to exclude code from the coverage report.
Add
# pragma: no cover
. -
New: Explain how to run tests in parallel.
pytest-xdist
makes it possible to run the tests in parallel, useful when the test suit is large or when the tests are slow.pip install pytest-xdist pytest -n auto
-
New: Explain how to set a timeout for your tests.
Using pytest-timeout.
-
New: Explain how to rerun tests that fail sometimes.
With pytest-rerunfailures that is a plugin for pytest that re-runs tests to eliminate intermittent failures. Using this plugin is generally a bad idea, it would be best to solve the reason why your code is not reliable. It's useful when you rely on non robust third party software in a way that you can't solve, or if the error is not in your code but in the testing code, and again you are not able to fix it.
feat(python_snippets#Create combination of elements in groups of two): Explain how to create combination of elements in groups of two
>>> list(itertools.combinations('ABC', 2)) [('A', 'B'), ('A', 'C'), ('B', 'C')]
-
New: Exclude the
if TYPE_CHECKING
code from the coverage.If you want other code to be excluded, for example the statements inside the
if TYPE_CHECKING:
add to yourpyproject.toml
:[tool.coverage.report] exclude_lines = [ # Have to re-enable the standard pragma 'pragma: no cover', # Type checking can not be tested 'if TYPE_CHECKING:', ]
-
New: Introduce goodconf the pyndantic YAML friendly configuration management.
goodconf is a thin wrapper over Pydantic's settings management. Allows you to define configuration variables and load them from environment or JSON/YAML file. Also generates initial configuration files and documentation for your defined configuration.
-
New: Capture deprecation warnings.
Python and its ecosystem does not have an assumption of strict SemVer, and has a tradition of providing deprecation warnings. If you have good CI, you should be able to catch warnings even before your users see them. Try the following pytest configuration:
[tool.pytest.ini_options] filterwarnings = ["error"]
This will turn warnings into errors and allow your CI to break before users break.
Other sections added are:
Python Snippets⚑
- Correction: Explain how to show the message in custom exceptions.
- New: Explain how to import a module or object from within a python program.
-
New: Add today's learned python tricks.
-
New: Explain how to use Jinja2.
Jinja2 is a modern and designer-friendly templating language for Python, modelled after Django’s templates. It is fast, widely used and secure with the optional sandboxed template execution environment.
Add installation, usage and basic and advanced template guidelines.
-
New: Add date management snippets.
-
Get the week number of a datetime:
datetime.datetime(2010, 6, 16).isocalendar()[1]
.
import datetime d = "2013-W26" r = datetime.datetime.strptime(d + '-1', "%Y-W%W-%w")
* Get ordinal from numberimport calendar >> calendar.month_name[3] 'March'
def int_to_ordinal(number: int) -> str: '''Convert an integer into its ordinal representation. make_ordinal(0) => '0th' make_ordinal(3) => '3rd' make_ordinal(122) => '122nd' make_ordinal(213) => '213th' Args: number: Number to convert Returns: ordinal representation of the number ''' suffix = ['th', 'st', 'nd', 'rd', 'th'][min(number % 10, 4)] if 11 <= (number % 100) <= 13: suffix = 'th' return f"{number}{suffix}"
-
-
New: Add file management snippets.
-
Improvement: Get the first day of next month.
- New: Explain how to test directories and files.
-
New: Explain how to install dependencies from git repositories.
With pip you can:
pip install git+git://github.com/path/to/repository@master
If you want to hard code it in your
setup.py
, you need to:install_requires = [ 'some-pkg @ git+ssh://git@github.com/someorgname/pkg-repo-name@v1.1#egg=some-pkg', ]
-
Correction: Explain how to create PyPI valid packages with direct dependencies.
It looks like PyPI don't want pip to reach out to URLs outside their site when installing from PyPI. So you can't define the direct dependencies in the
install_requires
. Instead you need to install them in aPostInstall
custom script. Ugly as hell. -
Correction: Add warning about the method to use direct dependencies.
Last time I used this solution, when I added the library on a
setup.py
the direct dependencies weren't installed :S -
New: Explain how to convert html code to readable plaintext.
pip install html2text
import html2text html = open("foobar.html").read() print(html2text.html2text(html))
-
New: Explain how to parse a datetime from a string.
from dateutil import parser parser.parse("Aug 28 1999 12:00AM") # datetime.datetime(1999, 8, 28, 0, 0)
-
New: Explain how to find a static file of a python module.
import pkg_resources file_path = pkg_resources.resource_filename("my_package", "assets/config.yaml"),
-
New: Explain how to delete a file.
import os os.remove('demofile.txt')
-
New: Explain how to measure elapsed time between lines of code.
import time start = time.time() print("hello") end = time.time() print(end - start)
-
New: Document when to use
isinstance
and when to usetype
.isinstance
takes into account inheritance, whiletype
doesn't. So if you want to make sure you're dealing with a specific class, and not any of it's parents or subclasses, usetype(obj) == class
. -
New: Check if a dictionary is a subset of another.
If you have two dictionaries
big = {'a': 1, 'b': 2, 'c':3}
andsmall = {'c': 3, 'a': 1}
, and want to check whethersmall
is a subset ofbig
, use the next snippet:>>> small.items() <= big.items() True
-
Correction: Group or sort a list of dictionaries or objects by a specific key.
Improve previous method with the concepts learned from the official docs
Particularly improve the sorting by multiple keys with the next function:
>>> def multisort(xs, specs): for key, reverse in reversed(specs): xs.sort(key=attrgetter(key), reverse=reverse) return xs >>> multisort(list(student_objects), (('grade', True), ('age', False))) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
-
Correction: Install default directories and files for a command line program.
I've been trying for a long time to configure
setup.py
to run the required steps to configure the required directories and files when doingpip install
without success.Finally, I decided that the program itself should create the data once the
FileNotFoundError
exception is found. That way, you don't penalize the load time because if the file or directory exists, that code is not run. -
a = ['a', 'b'] index = a.index('b')
-
New: Transpose a list of lists.
>>> l=[[1,2,3],[4,5,6],[7,8,9]] >>> [list(i) for i in zip(*l)] ... [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
-
New: Check the type of a list of strings.
def _is_list_of_lists(data: Any) -> bool: """Check if data is a list of strings.""" if data and isinstance(data, list): return all(isinstance(elem, list) for elem in data) else: return False
-
New: Replace all characters of a string with another character.
mystring = '_'*len(mystring)
-
New: Make a flat list of lists with a list comprehension.
There is no nice way to do it :(. The best I've found is:
t = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] flat_list = [item for sublist in t for item in sublist]
-
New: Remove a substring from the end of a string.
On Python 3.9 and newer you can use the
removeprefix
andremovesuffix
methods to remove an entire substring from either side of the string:url = 'abcdc.com' url.removesuffix('.com') # Returns 'abcdc' url.removeprefix('abcdc.') # Returns 'com'
On Python 3.8 and older you can use
endswith
and slicing:url = 'abcdc.com' if url.endswith('.com'): url = url[:-4]
-
New: Capture the stdout of a function.
import io from contextlib import redirect_stdout f = io.StringIO() with redirect_stdout(f): do_something(my_object) out = f.getvalue()
-
import tempfile dirpath = tempfile.mkdtemp()
-
New: Change the working directory of a test.
import unittest import os from src.main import get_cwd class TestMain(unittest.TestCase): def test_get_cwd(self): os.chdir('src') print('testing get_cwd()') current_dir = get_cwd() self.assertIsNotNone(current_dir) self.assertEqual(current_dir, 'src')
-
New: Copy a directory.
import shutil shutil.copytree('bar', 'foo')
-
Correction: Use fixture to change the working directory of a test.
The previous code didn't work, instead use the next fixture:
@pytest.fixture(name="change_test_dir") def change_test_dir_(request: SubRequest) -> Any: os.chdir(request.fspath.dirname) yield os.chdir(request.config.invocation_dir)
-
regex = re.compile( r"(?<![-\.\d])(?:0{0,2}?[0-9]\.|1\d?\d?\.|2[0-5]?[0-5]?\.){3}" r'(?:0{0,2}?[0-9]|1\d?\d?|2[0-5]?[0-5]?)(?![\.\d])"^[0-9]{1,3}*$' )
-
New: Remove the elements of a list from another.
>>> set([1,2,6,8]) - set([2,3,5,8]) set([1, 6])
-
New: Change the logging level of a library.
sh_logger = logging.getLogger("sh") sh_logger.setLevel(logging.WARN)
-
New: Get all subdirectories of a directory.
[x[0] for x in os.walk(directory)]
-
New: Move a file.
import os os.rename("path/to/current/file.foo", "path/to/new/destination/for/file.foo")
-
New: Copy a file.
import shutil shutil.copyfile(src_file, dest_file)
mkdocstrings⚑
-
New: How to write good test docstrings.
Both without a template and using the Given When Then style.
NetworkX⚑
-
New: Introduce the python library.
NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks.
pexpect⚑
-
New: Introduce the pexpect python library.
A pure Python module for spawning child applications; controlling them; and responding to expected patterns in their output. Pexpect works like Don Libes’ Expect. Pexpect allows your script to spawn a child application and control it as if a human were typing commands.
-
New: Explain how to read the output of a command run by pexpect.
import sys import pexpect child = pexpect.spawn('ls') child.logfile = sys.stdout child.expect(pexpect.EOF)
Prompt Toolkit⚑
-
New: Introduce the tui python library.
Useful to build text-based user interfaces, it allows the creation of intelligent prompts, dialogs, and full screen ncurses-like applications.
-
New: Basic concepts of building full screen applications with python prompt toolkit.
prompt_toolkit
can be used to create complex full screen terminal applications. Typically, an application consists of a layout (to describe the graphical part) and a set of key bindings.In the section we cover:
- The layout
- The controls
- How to use key bindings
- How to apply styles
- A difficult ordered list of examples to get a grasp of these concepts with simple working code.
Pydantic⚑
-
New: Explain how to initialize attributes.
Use validators to initialize attributes
-
New: Name the pros and cons of using the library.
- New: Explain how to create bidirectional relationship between entities.
- New: Warn on the lack of TypeDict support.
-
Correction: How to solve the No name 'BaseModel' in module 'pydantic'.
It's still a patch, so I've also monitored the relevant issues
-
Improvement: Change parse_obj definition to find how to import pydantic models from dictionary.
-
New: Explain how to use private attributes.
With the
PrivateAttr
object. -
New: Explain how to update entity attributes with a dictionary.
You can create a new object with the new data using the
update
argument of thecopy
entity method. -
New: Copy produces copy that modifies the original.
When copying a model, changing the value of an attribute on the copy updates the value of the attribute on the original. This only happens if
deep != True
. To fix it use:model.copy(deep=True)
. -
New: Define fields to exclude from exporting at config level.
Eagerly waiting for the release of the version 1.9 because you can define the fields to exclude in the
Config
of the model using something like:class User(BaseModel): id: int username: str password: str class Transaction(BaseModel): id: str user: User value: int class Config: fields = { 'value': { 'alias': 'Amount', 'exclude': ..., }, 'user': { 'exclude': {'username', 'password'} }, 'id': { 'dump_alias': 'external_id' } }
The release it's taking its time because the developer's gremlin and salaried work are sucking his time off.
-
New: Field customization.
Optionally, the
Field
function can be used to provide extra information about the field and validations. Such as thetitle
,default
,description
and many others
Pypika⚑
- New: Explain how to insert, update, select data.
- New: Explain how to join tables.
Python Mysql⚑
- New: Give examples on joins for each relationship type.
- New: Explain how to interact with MySQL databases with Python.
-
Correction: Correct the syntax of the left joins.
Instead of using
ON users.id == addresses.user_id
, useON users.id = addresses.user_id
questionary⚑
-
New: Introduce tui python library.
questionary is a Python library for effortlessly building pretty command line interfaces. It makes it very easy to query your user for input.
-
Correction: Correct the link to the examples.
-
New: Conditionally skip questions.
Sometimes it is helpful to be able to skip a question based on a condition. To avoid the need for an if around the question, you can pass the condition when you create the question:
import questionary DISABLED = True response = questionary.confirm("Are you amazed?").skip_if(DISABLED, default=True).ask()
-
New: Don't highlight the selected option by default.
If you don't want to highlight the default choice in the
select
question use the next style:from questionary import Style choice = select( "Question title: ", choices=['a', 'b', 'c'], default='a', style=Style([("selected", "noreverse")]), ).ask()
rich⚑
-
New: Introduce the python cli builder library and it's progress bar.
Rich is a Python library for rich text and beautiful formatting in the terminal.
Check out the beautiful progress bar:
pip install rich python -m rich.progress
-
New: Explain how to build pretty tables with rich.
from rich.console import Console from rich.table import Table table = Table(title="Star Wars Movies") table.add_column("Released", justify="right", style="cyan", no_wrap=True) table.add_column("Title", style="magenta") table.add_column("Box Office", justify="right", style="green") table.add_row("Dec 20, 2019", "Star Wars: The Rise of Skywalker", "$952,110,690") table.add_row("May 25, 2018", "Solo: A Star Wars Story", "$393,151,347") table.add_row("Dec 15, 2017", "Star Wars Ep. V111: The Last Jedi", "$1,332,539,889") table.add_row("Dec 16, 2016", "Rogue One: A Star Wars Story", "$1,332,439,889") console = Console() console.print(table)
-
New: Explain how to print pretty text with rich.
from rich.console import Console from rich.text import Text console = Console() text = Text.assemble(("Hello", "bold magenta"), " World!") console.print(text)
Ruamel YAML⚑
-
Improvement: Suggest to use ruyaml instead of ruamel.yaml.
As it's maintained by the community and versioned with git.
Selenium⚑
- New: Explain how to use selenium with python.
-
New: Explain how to Set timeout of a response.
driver.set_page_load_timeout(30)
-
New: Explain how to fix when Chromedriver hangs up unexpectedly.
os.environ["DBUS_SESSION_BUS_ADDRESS"] = "/dev/null"
sqlite3⚑
Requests⚑
- New: Introduce the requests python library.
Rq⚑
-
New: Add note to test arq.
arq is a similar library that can be better.
Tenacity⚑
-
New: Introduce the Tenacity python library.
Tenacity is an Apache 2.0 licensed general-purpose retrying library, written in Python, to simplify the task of adding retry behavior to just about anything.
TinyDB⚑
SQLite⚑
- New: Solve the autoincrementation not working bug.
-
New: Explain how to configure sqlite to be able to use the REGEXP operator.
It's not enabled by default.
-
Improvement: Add rqlite as an interesting distributed solution of.
-
New: Get the columns of a database.
PRAGMA table_info(table_name);
Promql⚑
Javascript⚑
MermaidJS⚑
-
New: Introduce the diagram library and how to make flowchart diagrams.
MermaidJS is a Javascript library that lets you create diagrams using text and code.
It can render the next diagram types:
- Flowchart
- Sequence.
- Gantt
- Class
- Git graph
- Entity Relationship
- User journey
Issues⚑
-
New: Introduce the issue tracking document.
I haven't found a tool to monitor the context it made me track certain software issues, so I get lost when updates come. Until a tool shows up, I'll use the good old markdown to keep track of them.
-
New: Add today's issues.
- Gadgetbridge improvements
- Ombi improvements
-
Improvement: Monitor today's issues.
- Mkdocs migration to 7.x is giving errors with the search bar and repo stats.
-
Improvement: Track python dependency errors.
- Correction: Gitdb has updated smmap.
-
New: Jellyfin 10.7.1 broke the login page.
Don't upgrade till it's solved, as the rollback is not easy.
-
Correction: Jellyfin login page problem after upgrade to 10.7.X is solved.
Surprisingly the instructions in #5489 solved it.
systemctl stop jellyfin.service mv /var/lib/jellyfin/data/jellyfin.db{,.bak} systemctl start jellyfin.service [ Go to JF URL, get asked to log in even though there are no Users in the JF DB now] systemctl stop jellyfin.service mv /var/lib/jellyfin/data/jellyfin.db{.bak,} systemctl start jellyfin.service
DevOps⚑
- New: Comment on the DevOps pitfalls and update the learn path.
Infrastructure as Code⚑
Helmfile⚑
-
Correction: Improve the helmfile chart update process.
Updating charts with
helmfile
is easy as long as you don't use environments, you runhelmfile deps
, thenhelmfile diff
and finallyhelmfile apply
. The tricky business comes when you want to use environments to reuse your helmfile code and don't repeat yourself. I've updated the process to include this case. -
New: Document the directory and files structure for multi-environment projects.
- New: Document how to use helmfile environments to follow DRY.
-
New: Document how to avoiding code repetition.
Besides environments,
helmfile
gives other useful tricks to prevent the illness of code repetition, such as using release templates, or layering the state. -
New: Document how to manage dependencies between the charts, to be able to use concurrency.
Helmfile support concurrency with the option
--concurrency=N
so we can take advantage of it and improve our deployment speed, but to ensure it works as expected we have to define the dependencies among charts. For example, if an application needs a database, it has to be deployed before hand. -
Correction: Use environment name instead of get values.
Instead of
.Environment.Name
, in theory you could have used.Vars | get "environment"
, which could have prevented the variables and secrets of the default environment will need to be calleddefault_values.yaml
, anddefault_secrets.yaml
, which is misleading. But you can't use.Values
in thehelmfile.yaml
as it's not loaded when the file is parsed, and you get an error. A solution would be to layer the helmfile state files but I wasn't able to make it work. -
New: How to install a chart only in one environment.
environments: default: production: --- releases: - name: newrelic-agent installed: {{ eq .Environment.Name "production" | toYaml }} # snip
-
New: Add note that templates can't be used inside the secrets.
See this issue
Terraform⚑
-
New: Introduce terraform and how to handle RDS secrets.
Terraform is an open-source infrastructure as code software tool created by HashiCorp. It enables users to define and provision a datacenter infrastructure using an awful high-level configuration language known as Hashicorp Configuration Language (HCL), or optionally JSON. Terraform supports a number of cloud infrastructure providers such as Amazon Web Services, IBM Cloud , Google Cloud Platform, DigitalOcean, Linode, Microsoft Azure, Oracle Cloud Infrastructure, OVH, or VMware vSphere as well as OpenNebula and OpenStack.
-
New: Explain how to ignore the change of an attribute.
resource "aws_instance" "example" { # ... lifecycle { ignore_changes = [ # Ignore changes to tags, e.g. because a management agent # updates these based on some ruleset managed elsewhere. tags, ] } }
-
New: Explain how to define the default value of an variable that contains an object as empty.
variable "database" { type = object({ size = number instance_type = string storage_type = string engine = string engine_version = string parameter_group_name = string multi_az = bool }) default = null
-
New: Explain how to do a conditional if a variable is not null.
resource "aws_db_instance" "instance" { count = var.database == null ? 0 : 1 ...
-
New: How to do elif conditionals in terraform.
locals { test = "${ condition ? value : (elif-condition ? elif-value : else-value)}" }
-
New: How to enable debug traces.
You can set the
TF_LOG
environmental variable to one of the log levelsTRACE
,DEBUG
,INFO
,WARN
orERROR
to change the verbosity of the logs.
Helm Secrets⚑
-
Correction: Update the repository url.
The last fork is dead, long live the fork
-
New: How to install the plugin.
Helm Git⚑
-
Correction: Suggest version 0.8.0 until issue is solved.
Newer versions have a bug that makes impossible to use helm_git with a repository that contains just one chart in the root of the git repository.
-
Correction: Update installation method.
In the last version 0.11.1, the issue that forced us to use the version 0.8.0 was solved
Infrastructure Solutions⚑
Kubernetes⚑
-
New: Add Velero as interesting tool.
Velero is a tool to backup and migrate Kubernetes resources and persistent volumes.
Architecture⚑
-
New: Give suggestions on how to choose the number of kubernetes clusters to use.
You can run a given set of workloads either on few large clusters (with many workloads in each cluster) or on many clusters (with few workloads in each cluster).
Here's a table that summarizes the pros and cons of various approaches:
Figure: Possibilities of number of clusters from learnk8s.io article
Jobs⚑
-
Improvement: Remove false positive alerts on failed jobs that succeeded.
A Kubernetes cronjob spawns jobs, if the first one fails, it will try to spawn a new one. If the second succeeds, the cronjob status should be success, but with the rule we had before, a successful job with failed past jobs will still raise an alert.
-
New: Explain how to rerun failed cronjobs.
If you have a job that has failed after the 6 default retries, it will show up in your monitorization forever, to fix it, you can manually trigger the job.
kubectl get job "your-job" -o json \ | jq 'del(.spec.selector)' \ | jq 'del(.spec.template.metadata.labels)' \ | kubectl replace --force -f -
-
New: Manually creating a job from a cronjob.
kubectl create job {{ job_name }} -n {{ namespace }} \ --from=cronjobs/{{ cronjob_name}}
Continuous Integration⚑
-
New: Explain how to troubleshoot the error: pathspec master did not match any file.
Remove all git hooks with
rm -r .git/hooks
.
Flakehell⚑
- New: Explain how to ignore errors.
-
Correction: Update the git repository.
The existent repository has been archived in favor of this one
-
New: Explain how to patch the extended_default_ignore error for versions > 3.9.0.
Add to your your
pyproject.toml
:[tool.flakeheaven] extended_default_ignore=[] # add this
-
New: Troubleshoot the 'Namespace' object has no attribute 'extended_default_ignore' error.
Add to your
pyproject.toml
:[tool.flakeheaven] extended_default_ignore=[]
-
New: Latest version is broken.
It returns an ImportError: cannot import name 'MergedConfigParser' from 'flake8.options.config', wait for the issue to be solved before upgrading.
Pyment⚑
-
New: Introduce Pyment.
Pyment is a python3 program to automatically create, update or convert docstrings in existing Python files, managing several styles.
As of 2021-11-17, the program is not production ready yet for me, I've tested it in one of my projects and found some bugs that needed to be fixed before it's usable. Despite the number of stars, it looks like the development pace has dropped dramatically, so it needs our help to get better :).
Dependency managers⚑
-
New: Sync the virtualenv libraries with the requirements files.
python -m piptools sync requirements.txt requirements-dev.txt
-
Correction: Use
-c
instead of-r
in the nested requirement files.To avoid duplication of version pins.
-
Correction: Deprecate in favour of Poetry.
Automating Processes⚑
cruft⚑
Monitoring⚑
Monitoring Comparison⚑
- New: Compare Nagios and Prometheus as monitoring.
-
Correction: Improve the comparison.
- State that nagios is not easy to configure. If you're used to it it is, otherwise it's not.
- Add that grafana has a huge community building graphs.
- Mention Thanos as the long term storage solution for Prometheus.
-
Correction: Add the insights of a nagios power user.
- Update open source and community analysis with nagios exchange.
- Correct nagios community analysis with its trajectory
- Correct the analysis of the high availability of nagios
- Add the option to host the script exporter in a dedicated server
Prometheus Install⚑
-
Correction: Add warning that helm 2 support is dropped.
If you want to use the helm chart above 11.1.7 you need to use helm 3.
-
Improvement: Add upgrading notes from 10.x -> 11.1.7.
Don't upgrade to 12.x if you're still using Helm 2.
Elasticsearch Exporter⚑
-
New: Introduce the prometheus elasticsearch exporter.
The elasticsearch exporter allows monitoring Elasticsearch clusters with Prometheus.
Explain how to install it, configure the grafana dashboards and the alerts.
-
Improvement: Add more elasticsearch alerts.
Measure the search latency, search rate and create alerts on the garbage collector, json parser and circuit breaker errors
-
New: Add alert on low number of healthy master nodes.
Scrum⚑
-
New: Introduce the scrum framework.
Scrum is an agile framework for developing, delivering, and sustaining complex products, with an initial emphasis on software development, although it has been used in other fields such as personal task management. It is designed for teams of ten or fewer members, who break their work into goals that can be completed within time-boxed iterations, called sprints, no longer than one month and most commonly two weeks. The Scrum Team track progress in 15-minute time-boxed daily meetings, called daily scrums. At the end of the sprint, the team holds sprint review, to demonstrate the work done, a sprint retrospective to improve continuously, and a sprint planning to prepare next sprint's tasks.
In the article I explain:
- I use to do the meetings: Daily, Refinement, Retros, Reviews and Plannings.
- The relevant roles.
- Some definitions, such as definition of done and definition of ready.
Software Architecture⚑
Domain Driven Design⚑
-
Improvement: Add warning when migrating old code.
You may be tempted to migrate all your old code to this architecture once you fall in love with it. Truth being told, it's the best way to learn how to use it, but it's time expensive too! The last refactor I did required a change of 60% of the code. The upside is that I reduced the total lines of code a 25%.
Architecture Decision Record⚑
-
New: Introduce the Architecture Decision Records.
ADR are short text documents that captures an important architectural decision made along with its context and consequences.
-
New: Update the ADR template with the week learnings.
- Add the Proposals and Date sections
- Explain the possible Status states.
- Add an Ultisnip vim snippet.
- Explain how I've used it to create mkdocs-newsletter.
-
Improvement: Explain how to show relationship between ADRs.
Suggest a mermaidjs diagram to show the state of the project ADRs.
Operative Systems⚑
Linux⚑
-
New: Introduce Tahoe-LAFS.
Tahoe-LAFS is a free and open, secure, decentralized, fault-tolerant, distributed data store and distributed file system.
Tahoe-LAFS is a system that helps you to store files. You run a client program on your computer, which talks to one or more storage servers on other computers. When you tell your client to store a file, it will encrypt that file, encode it into multiple pieces, then spread those pieces out among multiple servers. The pieces are all encrypted and protected against modifications. Later, when you ask your client to retrieve the file, it will find the necessary pieces, make sure they haven’t been corrupted, reassemble them, and decrypt the result.
Linux Snippets⚑
-
New: Explain how to split a file into many with equal number of lines.
split -l 200000 filename
-
New: Explain how to identify what a string or file contains.
Using pywhat
-
New: Explain how to allocate space for a virtual filesystem.
fallocate -l 20G /path/to/file
-
New: Document how to bypass client SSL certificate with a cli tool.
Websites that require clients to authorize with an TLS certificate are difficult to interact with through command line tools that don't support this feature.
To solve it, we can use a transparent proxy that does the exchange for us.
afew⚑
- New: Explain how to use tabs, buffers and windows in vim.
-
New: Introduce afew.
afew is an initial tagging script for notmuch mail.
Its basic task is to provide automatic tagging each time new mail is registered with
notmuch
. In a classic setup, you might call it afternotmuch new
in an offlineimap post sync hook.
alot⚑
- New: Follow the issue to add elipsis instead of ... in vim-abolish.
-
Correction: Forget to use abolish to insert the elipsis symbol.
Tpope said that it's not going to happen.
-
New: Introduce vim-easymotion.
EasyMotion provides a much simpler way to use some motions in vim. It takes the
<number>
out of<number>w
or<number>f{char}
by highlighting all possible choices and allowing you to press one key to jump directly to the target.When one of the available motions is triggered, all visible text preceding or following the cursor is faded, and motion targets are highlighted.
-
Reorganization: Move vim-test to the plugins page.
-
Correction: Typo.
There was a missing comma in the list.
-
Improvement: Explain how to configure the vim-easymotion movement keys.
-
New: Introduce alot.
alot is a terminal-based mail user agent based on the notmuch mail indexer. It is written in python using the urwid toolkit and features a modular and command prompt driven interface to provide a full MUA experience.
ActivityWatch⚑
-
New: Introduce ActivityWatch tracking software.
It's a web application that can be installed both in Linux and Android that automatically tracks where you spend the time on.
Super interesting for life logging and automating stuff. Until I save some time to react on the data, I'll just gather it and see how to aggregate it.
-
Improvement: Add week insights.
- The browser watcher is not very accurate.
- The vim editor watcher doesn't add git branch information.
- Syncing data between devices is not yet supported.
beancount⚑
- New: Introduce the cli double entry accounting program.
- New: Add links on how to use as a library.
- Correction: Correct the git repository link.
Beets⚑
-
New: Introduce Beets the music management library.
Beets is a music management library used to get your music collection right once and for all. It catalogs your collection, automatically improving its metadata as it goes using the MusicBrainz database. Then it provides a set of tools for manipulating and accessing your music.
dunst⚑
-
New: Introduce dunst.
Dunst is a lightweight replacement for the notification daemons provided by most desktop environments. It’s very customizable, isn’t dependent on any toolkits, and therefore fits into those window manager centric setups we all love to customize to perfection.
Dynamic DNS⚑
-
New: Introduce the Dynamic DNS concept.
Dynamic DNS (DDNS) is a method of automatically updating a name server in the Domain Name Server (DNS), often in real time, with the active DDNS configuration of its configured hostnames, addresses or other information.
elasticsearch⚑
- New: Explain how to reindex an index.
-
Correction: Explain how to restore only some indices.
curl -X POST "{{ url }}/_snapshot/{{ backup_path }}/{{ snapshot_name }}/_restore?pretty" -H 'Content-Type: application/json' -d' { "indices": "{{ index_to_restore }}", }'
-
Correction: Correct the way of closing an index.
Use a POST instead of a GET
-
New: Explain how to calculate the amount of memory required to do KNN operations.
- New: Explain how to do KNN warmup to speed up the queries.
- New: Explain how to deal with the AWS service timeout.
Gajim⚑
-
New: Introduce gajim.
Gajim is the best Linux XMPP client in terms of end-to-end encryption support as it's able to speak OMEMO.
Github cli⚑
-
New: Basic usage of gh.
gh
is GitHub’s official command line tool.It can be used to speed up common operations done with github, such as opening PRs, merging them or checking the checks of the PRs
Graylog⚑
-
New: Introduce Graylog.
Graylog is a log management tool. The commit includes some tips like how to send a test message to check an input.
HAProxy⚑
- New: Add interesting guidelines on how to configure HAProxy in AWS.
Hard drive health⚑
-
New: Taking care of your hard drives.
Hard drives die, so we must be ready for that to happen. There are several solutions, such as using RAID to minimize the impact of a disk loss, but even then, we should monitor the bad sectors to see when are our disks dying.
In the article we talk about S.M.A.R.T and how to solve some hard drive problems.
Hushboard⚑
-
New: Introduce Husboard.
Hushboard is an utility that mutes your microphone while you’re typing.
(Thanks M0wer!)
Jellyfin⚑
-
New: Introduce the media system and monitor interesting issues.
Jellyfin is a Free Software Media System that puts you in control of managing and streaming your media. It is an alternative to the proprietary Emby and Plex, to provide media from a dedicated server to end-user devices via multiple apps. Jellyfin is descended from Emby's 3.5.2 release and ported to the .NET Core framework to enable full cross-platform support. There are no strings attached, no premium licenses or features, and no hidden agendas: just a team who want to build something better and work together to achieve it.
-
Correction: Explain how to fix the stuck at login page issue.
systemctl stop jellyfin.service mv /var/lib/jellyfin/data/jellyfin.db{,.bak} systemctl start jellyfin.service systemctl stop jellyfin.service mv /var/lib/jellyfin/data/jellyfin.db{.bak,} systemctl start jellyfin.service
-
Correction: Explain how to fix the Intel Hardware transcoding.
docker exec -it jellyfin /bin/bash wget https://repo.jellyfin.org/releases/server/ubuntu/versions/jellyfin-ffmpeg/4.3.2-1/jellyfin-ffmpeg_4.3.2-1-focal_amd64.deb dpkg -i jellyfin-ffmpeg_4.3.2-1-focal_amd64.deb
-
Improvement: Explain how to fix the wrong image covers.
Remove all the
jpg
files of the directory and then fetch again the data from your favourite media management software. - New: Explain how to fix the green bars in the reproduction.
-
Correction: Fix the stuck at login page error.
If you use jfa-go for the invites, you may need to regenerate all the user profiles, so that the problem is not introduced again.
-
New: Track subtitles get delayed from the video on some devices issue.
ffmpeg⚑
-
New: Introduce the program and multiple of it's uses.
ffmpeg is a complete, cross-platform solution to record, convert and stream audio and video.
Kitty⚑
-
New: Introduce kitty the terminal emulator.
kitty is a fast, feature-rich, GPU based terminal emulator written in C and Python with nice features for the keyboard driven humans like me.
-
New: Scrollback when ssh into a machine doesn't work.
This happens because the kitty terminfo files are not available on the server. You can ssh in using the following command which will automatically copy the terminfo files to the server:
kitty +kitten ssh myserver
-
New: Enable infinite scrollback history.
To make the history scrollback infinite add the next lines:
scrollback_lines -1 scrollback_pager_history_size 0
-
New: Reasons to migrate from urxvt to kitty.
- It doesn't fuck up your terminal colors.
- You can use peek to record your screen.
- Easier to extend.
LUKS⚑
-
New: Explain how to change a LUKS key.
cryptsetup luksChangeKey {{ luks_device }} -s 0
mkdocs⚑
- New: Explain how to develop your own plugins.
-
New: Document the Navigation object and the on_nav event.
Useful if you develop MkDocs plugins, it holds the information to build the navigation of the site.
-
New: Describe navigation objects used in plugins.
Explain how to use the Page, Section, and SectionPage objects.
-
Correction: You need to edit the nav in the on_nav and not in the on_files event.
Even though it seems more easy to create the nav structure in the
on_files
event, by editing thenav
dictionary of theconfig
object, there is no way of returning theconfig
object in that event, so we're forced to do it in this event. -
Correction: Explain how to add files through a plugin.
Long story short, use the
on_config
event instead ofon_files
andon_nav
if you need to add files and want to change the navigation menu. -
New: Explain how to use MermaidJS diagrams.
- New: Explain how to test mkdocs plugins.
-
New: Explain additions of version 7.1.0 of the material theme.
Mopidy⚑
-
New: Introduce the music server.
Mopidy is an extensible music server written in Python, that plays perfectly with beets and the MPD ecosystem.
The awesome documentation, being Python based, the extension system, JSON-RPC, and JavaScript APIs make Mopidy a perfect base for your projects.
Oracle Database⚑
- New: Explain how to build an oracle database docker while feeling dirty inside.
Peek⚑
-
New: Introduce Peek the screen recorder.
Peek is a simple animated GIF screen recorder with an easy to use interface.
If you try to use it with i3, you're going to have a bad time, you'd need to install Compton, and then the elements may not even be clickable.
-
Correction: Add note that it works with kitty.
Syncthing⚑
-
Improvement: Mention privacy configurations.
Disable the Global Discovery and Relaying connections options.
-
New: Investigate if Syncthing can be used over Tor.
I haven't found a reliable and safe way to do it, but I've set a path to follow if you're interested.
Vim⚑
- New: Configure Vim to set the upstream by default when git pushing.
- New: Add vim landing page.
- Reorganization: Refactor the vim_automation article into vim and vim_plugins.
- Correction: Correct vim snippet to remember the folds when saving a file.
Android⚑
cone⚑
- New: Introduce the mobile double entry accounting application.
- Correction: Correct the description of the transaction to be beancount compatible.
GadgetBridge⚑
- New: Add more guidelines to reverse engineer the band protocol.
OsmAnd⚑
-
New: Introduce OsmAnd.
OsmAnd is a mobile application for global map viewing and navigating based on OpenStreetMaps. Perfect if you're looking for a privacy focused, community maintained open source alternative to google maps.
Signal⚑
- New: Introduce the messaging app and how to decrypt the backups.
Arts⚑
Writing⚑
-
New: Try vim-pencil without success, but love mdnav.
mdnav opens links to urls or files when pressing
enter
in normal mode over a markdown link, similar togx
but more powerful. I specially like the ability of following[self referencing link][]
links, that allows storing the links at the bottom. -
New: Explain when to use I'm good or I'm well.
Use I'm well when referring to being ill, use I'm good for the rest.
Grammar and Orthography⚑
-
New: Explain how to enable clickable navigation sections in your mkdocs repository.
oprypin has solved it with the mkdocs-section-index plugin.
-
Improvement: Expand the introduction and add Dave's suggested link.
-
New: Explain where to add your pronouns.
Hi, I’m Lyz (he/him), I'm writing to tell you…
-
New: Explain when to capitalize after a question mark.
If the sentence ends after the question mark you should capitalize, if it doesn't end, you shouldn't have used the question mark, since it ends a sentence.
-
New: Add textstat tests.
To analyze the text readability
-
New: Explain when to write won't or wont.
- Won't is the correct way to contract will not.
- Wont is a synonym of "a habit". For example, "He went for a morning jog, as was his wont".
-
New: Explain what collocations are and how to avoid the word very.
Collocation refers to a natural combination of words that are closely affiliated with each other. They make it easier to avoid overused or ambiguous words like "very", "nice", or "beautiful", by using a pair of words that fit the context better and that have a more precise meaning.
-
New: Explain what can you use instead of I know.
Using "I know" may not be the best way to show the other person that you've got the information. You can take the chance to use other words that additionally gives more context on how you stand with the information you've received, thus improving the communication and creating a bond.
-
New: Explain the use of z or s in some words.
It looks like American english uses
z
while British usess
, some examples:Both forms are correct, so choose the one that suits your liking.
Forking this garden⚑
-
New: Analyze interesting books on writing style.
- The elements of style by William Strunk Jr and E.B White
- On writing well by William Zinsser
- Bird by bird by Anne Lamott
- On writing by Stephen King
-
New: Explain how to end a letter.
Use Sincerely in doubt and Best if you have more confidence. Add a comma after the sign-off and never use Cheers (it's what I've been doing all my life
(◞‸◟;)
). -
New: Explain how to fork the blue book.
Digital Gardens⚑
-
New: Introduce the digital garden concept.
Digital Garden is a method of storing and maintaining knowledge in an maintainable, scalable and searchable way. They are also known as second brains.
Cooking⚑
- New: Introduce the cooking art.
Cooking Basics⚑
- New: Refactor the perfect technique to boil an egg.
-
New: Explain how to boil chickpeas when you've forgotten to soak them.
Add a level teaspoon of baking soda to the pot and cook them as usual
Pilates⚑
-
New: Introduce the art.
Pilates is a physical fitness system based on controlled movements putting emphasis on alignment, breathing, developing a strong core, and improving coordination and balance. The core (or powerhouse), consisting of the muscles of the abdomen, low back, and hips, is thought to be the key to a person's stability.
Pilates' system allows for different exercises to be modified in range of difficulty from beginner to advanced or to any other level, and also in terms of the instructor and practitioner's specific goals and/or limitations. Intensity can be increased over time as the body adapts itself to the exercises.
You can think of yoga, but without the spiritual aspects.
Also added:
- It's principles
- The swing from table exercise.
Board Gaming⚑
Regicide⚑
-
New: Introduce the awesome Regicide card game.
Regicide is a wonderful cooperative card game for 1 to 4 players. It's awesome how they've built such a rich game dynamic with a normal deck of cards. Even if you can play it with any deck, I suggest to buy the deck they sell because their cards are magnificent and they deserve the money for their impressive game. Another thing I love about them is that even if you can't or don't want to pay for the game, they give the rules for free.
If you don't like reading the rules directly from their pdf (although it's quite short), they explain them in this video.
I've loved the game so much, that I've created some variations of the rules to make each game more different and changeling.
Drawing⚑
-
Ellipses are the next basic shape we're going to study (after the lines). They are extremely important and notoriously annoying to draw. Important because we're going to be using ellipses in 2D space to represent circles that exist in 3D space.
In this section we:
- Introduce the basic concepts surrounding the ellipses
- How to draw them.
Exercise Pool⚑
-
New: Add the Tables of ellipses drawing exercise.
This exercise is meant to get you used to drawing ellipses, in a variety of sizes, orientations and degrees. It also sets out a clear space each ellipse is meant to occupy, giving us a means to assess whether or not an ellipse was successful, or if there were visible mistakes (where it went outside of its allotted space, or ended up falling short). Practicing against set criteria, with a way to judge success/failure is an important element of learning. There's nothing wrong with failure - it's an opportunity to learn. Having a clearly defined task allows us to analyze those failures and make the most of them.
Origami⚑
- New: Add mark1626 digital garden article on origamis.
Contact⚑
-
Correction: Update the XMPP address.
Riseup has stopped giving support for XMPP :(
Other⚑
- New: Add remote work tips.
- New: Introduce lazy loading implementation paradigm with python.
- New: Explain how to lazy load pydantic objects.
- New: Explain my accounting automation workflow.
- New: Feature mkdocs-rss-plugin as a solution of publishing mkdocs updates as an RSS.
- New: Add a git issue tracker and markdown formatter.
-
Correction: Deprecate mkdocs issues.
They've been fixed in the last release
-
New: Suggest organize to act on computer file changes.
organize looks good for automating processes on files. Maybe it's interesting to run it with inotifywait instead of with a cron job.
-
New: Introduce Outrun.
Outrun lets you execute a local command using the processing power of another Linux machine.
-
Correction: Broken links.
Removed the link to (everything_i_know.md) since it no longer exists. Updated some links that where broken due to a folder structure change.
-
New: Explain how to select a random choice from
Enum
objects.pydantic uses
Enum
objects to define the choices of fields, so we need them to create the factories of those objects. -
New: Improve the periodic tasks and application metrics monitoring.
Setup an healthchecks instance with the linuxserver image to monitor cronjobs.
For the notifications either use the prometheus metrics or an apprise compatible system.
-
New: Explain how to check if an rsync command has gone well.
Run
diff -r --brief source/ dest/
, and check that there is no output. -
Reorganization: Reorder the sections of the site navigation menu.
Give more importance to Coding, Activism and Life Management, reducing the Software Architecture and Data Analysis sections.
-
New: Introduce the tool management section.
Most of the tasks or processes we do involve some kind of tool, the better you know how to use them, the better your efficiency will be. The more you use a tool, the more it's worth the investment of time to improve your usage of it.
Whenever I use a tool, I try to think if I could configure it or use it in a way that will make it easier or quicker. Don't go crazy and try to change everything. Go step by step, and once you've internalized the improvement, implement the next.
-
Reorganization: Move the tasks tools from the task management article to their own.