Guid for Python Noobs: Workflow with Usefull Tools

2024-11-15

This is a guide to show you around some very usefull tools.

The knowledge how to use a terminal emulator and command line interfaces is required.

UV

UV is essentially a dependency management tool for python. Instead of using python in the traditional sense, you’re better of using uv.

Use the standalone installer from https://docs.astral.sh/uv/getting-started/installation/#standalone-installer.

If python is not installed, install python with uv python install 3.13.

To start a new project, run:

uv init hello

To run your project, first enter the new project:

cd hello

And then execute with:

uv run hello.py

UV will handle all dependencies. To add numpy, you’d run:

uv add numpy

Scoop (Windows)

Scoop is a package manager for windows.

Please head to https://scoop.sh/ and install Scoop following the Quickstart.

On https://scoop.sh/ you’ll also find most packages.

Git

Git is a version manager for text files.

Git saves snapshots (commits) of your project and even allows working on multiple versions of your project at the same time (branches).

Please install git via scoop install git if it is not allready installed.

Configuration

git config --global user.name "Your Name"
git config --global user.email "Your E-Mail Address"

Basic Usage

We’ll create a folder called hello:

mkdir hello

We’ll then enter said folder:

cd hello

We’ll initialize a git repo:

git init

We’ll add a new file:

"Write-Host 'Hello World'" >> Hello.ps1

The changes we made are untracked. If we try to commit now, git will error. To check that this is indeed the case, we’ll call:

git status

Red means untracked, green means tracked. To track our changes, we call:

git add Hello.ps1

Or to track all changes, we call:

git add *

We’ll commit our changes, which means that we essentially save the current state.

git commit -m "Added hello script."

Commit messages should always be meaningfull!

Let’s check out the history:

git log

We can checkout previous commits by using the hashes we saw in git log:

git checkout [hash of a commit]

To checkout the head again we can call:

git checkout master

or

git checkout main

Branches

I’ll spare you for now.

Reset

You accidentaly added a large file with git add? No problem:

git reset

You hate the changes you made and want a hard reset to the last commit? No problem

git reset --hard

.gitignore

The .gitignore file is used to exclude certain directories or files from git versioning. You always should exclude build and release artifacts!

Here is a nice list of usefull gitignore files: https://github.com/github/gitignore.

Github

Github isn’t a tool, but a service. It is very usefull to store your git repos online, to work with others and to publish your code.

https://docs.github.com/en/get-started/start-your-journey/about-github-and-git

VSCode

Visual Studio Code is a very popular IDE (Integrated Development Environment).

Please install it from https://code.visualstudio.com/.

I won’t give you a guide for VSCode…

Plugins

VSCode mostly is dependant on plugins for it’s functionality.

Ruff

Ruff is a very nice formatter and linter. Install Ruff with:

uv tool install ruff

You’ll need to install Ruff as plugin in VSCode. (https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruf)

You’ll then need to configure VSCode to use ruff: Hit Ctrl+Shift+P and type in “Open User Settings (JSON)”.

It should at least contain the following:

{
    "notebook.formatOnSave.enabled": true,
    "notebook.codeActionsOnSave": {
        "notebook.source.fixAll": "explicit",
        "notebook.source.organizeImports": "explicit"
    },
    "[python]": {
        "editor.formatOnSave": true,
        "editor.codeActionsOnSave": {
        "source.fixAll": "explicit",
        "source.organizeImports": "explicit"
        },
        "editor.defaultFormatter": "charliermarsh.ruff"
    }
}

Jupyter Notebooks

Some usefull links:

More

The above where the usefull tools. They’ll won’t be much of help if you aren’t testing your code. And this you cannot do, if you only write very long scripts 👀👀👀👀

Tipps

  • Split up your scripts into functions!

    Instead of

    numbers = [1, 2, 3, 4]
    result = 0
    
    for e in numbers:
        result += e
    
    print(e)
    
    

    do

    def sum(numbers):
        result = 0
    
        for e in numbers:
            result += e
    
        return result
    
    def main():
        numbers = [1, 2, 3, 4]
        print(sum(numbers))
    
    if __name__ == "__main__":
        main()
    
  • Use type hints!

    Instead of

    def sum(numbers):
        result = 0
    
        for e in numbers:
            result += e
    
        return result
    
    def main():
        numbers = [1, 2, 3, 4]
        print(sum(numbers))
    
    if __name__ == "__main__":
        main()
    

    do

    def sum[T](numbers: list[T]) -> T:
        result = 0
    
        for e in numbers:
            result += e
    
        return result
    
    def main() -> None:
        numbers = [1, 2, 3, 4]
        print(sum(numbers))
    
    if __name__ == "__main__":
        main()
    
  • Read the documentation of the tools and libraries you use!

  • Write documentation!

    """
    This is a simple program summing up a few numbers.
    """
    
    def sum[T](numbers: list[T]) -> T:
        """
        Returns the sum of a list of numbers.
        """
        result = 0
    
        for e in numbers:
            result += e
    
        return result
    
    def main() -> None:
        numbers = [1, 2, 3, 4]
        print(sum(numbers))
    
    if __name__ == "__main__":
        main()
    
  • Do NOT write functions with side effects!

    The following is a big no no!

    result = 0
    numbers = [1, 2, 3, 4]
    
    
    def sum():
        global result
        for e in numbers:
            result += e
    
    
    def main() -> None:
        sum()
        print(result)
    
    
    if __name__ == "__main__":
        main()
    
  • Don’t use too short variables!

  • Constant variables are always caps lock!

    NEVER_MORE = "Never changing variable."
    

Test

We’ll be using pytest here.

Add pytest to your current project:

uv add --dev pytest

To test your hello.py from above, create a new file called test_hello.py with the following content:

from hello import sum


def test_sum():
    numbers = [1, 2, 3, -4]
    assert sum(numbers) == 2

To run the unit test, call:

uv run pytest

Rich

Rich is very nice for displaying colors on the terminal. Though another feature is the nicer looking tracebacks.

uv add rich
from rich.traceback import install


def main():
    install()

    assert 0 == 1


if __name__ == "__main__":
    main()