From aa4e513a99f126d36b3614dd29ce8a58ced336f4 Mon Sep 17 00:00:00 2001 From: Bjoern Hartmann Date: Thu, 29 May 2025 17:12:42 +0200 Subject: [PATCH 1/2] [GS] New: Python Hello World --- .../2025-05-12-gs_00010_python-hello-world.md | 272 ++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 _posts/2025-05-12-gs_00010_python-hello-world.md diff --git a/_posts/2025-05-12-gs_00010_python-hello-world.md b/_posts/2025-05-12-gs_00010_python-hello-world.md new file mode 100644 index 00000000..10923a0b --- /dev/null +++ b/_posts/2025-05-12-gs_00010_python-hello-world.md @@ -0,0 +1,272 @@ +--- +layout: single +title: "Python: Hello World" +category: Getting Started +permalink: /categories/getting_started/python_hello_world +excerpt: "Your first Python Program" +description: + In this blog post you will learn how to write your first Python program. +author: Bjoern Hartmann +toc: true +toc_label: "Content" +toc_sticky: true +toc_icon: "align-justify" +sidebar: + nav: "getting_started_0" +header: + overlay_color: "#000" + overlay_filter: "0.5" + overlay_image: /assets/images/getting_started.jpeg +--- + +Welcome back to our next post where you'll finally learn how to write your first +Python program. In our latest [post](/categories/getting_started/visual_code), +we introduced VS Code, a modern and flexible IDE. The prepared profile, which we +used to set up the editor, already includes extensions for the Python language. +So, everything should be ready to get started. In another previous post about +[programming concepts](/categories/getting_started/programming_tutorial_II), we +learned about concepts, such as functions or loops, that all programming +languages have in common. We will see how these simple structures are used in a +working program. + +Python is one of the most beginner-friendly programming languages, known for its +readability and simplicity. Therefore, it's a perfect starting point for us. +Once you know how to use one language it's just a small step to learn another +language. The core principles are always the same. In our first program, we'll +implement the traditional "Hello, World!". + +## Hello World! + +A "Hello, World!" program is usually the first piece of code written when +learning a new programming language. It does something very simple: It displays +the message **Hello, World!**. While it may seem trivial, this program serves a +very important purpose. First, it helps to verify that your development +environment is set up correctly. If the program runs and outputs "Hello, World!" +to your screen, you know that your interpreter, editor, and everything else are +working as expected. Secondly, it introduces the basic syntax of the language. +It shows how to output data to the console, which is a fundamental capability in +programming. Lastly, it serves as a confidence booster. By successfully running +your first program, you're building momentum for more complex projects. + +Inside VS Code, open a folder of your choice and create a new file +_hello_world.py_. By the _.py_ extension, VS Code knows immediately that it is a +Python file. In the lower-right corner, VS Code shows that it is in Python mode +and it shows the current Python version (see the picture below). Just a quick +note on Python versions: Each version introduces new features of the programming +language. Usually, this is backward compatible. So, a program written for Python +3.6 also works for our 3.13 version. This is not true for major releases. It's +not possible to run a Python 2 program with Python 3. + +Now, write the following code and save it: + +```python + print("Hello World!") +``` + +The code is probably very easy to understand. _print_ is a Python function that +can be used to print a message to the console. The message itself has to be +within single or double quotes. To run the code you can hit the run button in +the upper-right. This will open a terminal where your Python script is executed. +If everything goes well you should see the _Hello World!_ output. Alternatively, +you can directly run the program by typing _python hello_world.py_ into the +console. + +Congrats! This was your very first Python program. + +
+ Hello World +
+ +Note that the terminal probably looks different for you. We will cover this in a +later post. + +## Python as Calculator + +In most cases, you will write all Python commands into a file and execute the +file, as we did in our _Hello World!_ program. However, sometimes it is useful +to execute the commands interactively. Inside the terminal, just type the +command + + $ python + +This will lead you to an input prompt where you can type your Python commands, +for example, the _print("Hello World!")_ command from the previous section. You +can also do calculations such as _3\*3_. This can be very handy. Just play +around with it! + +
+ Python as calculator +
+ +## Let's Build a Counter + +Now that you’ve successfully written your first Python program, let’s build +something a little more useful: a counter. This simple project will introduce us +to more key concepts in Python, such as variables, loops, functions, and +conditional statements. + +### Starting with a simple counter + +We can begin by writing a basic counter that prints numbers. Create a new file +_counter.py_ and add the following code: + +```python +count = 1 +print("Count is:", count) +``` + +In this case, we define a **variable** called count and set it to 1. The print() +function is used to output the value of count to the screen. Unlike printing a +fixed message like "Hello World", notice that we don't put the variable name in +quotes. Doing so would print the word "count" instead of its value. + +> Count is: 1 + +### Adding a while Loop + +Next, let's use a **while loop** to make the counter print numbers from 1 to 5. +A loop helps us automate repetitive tasks, so instead of manually printing each +count, we can write a single block of code that runs until a condition is met. + +Here’s how we modify the counter to use a loop: + +```python +count = 1 +while count <= 5: + print("Count is:", count) + count += 1 +``` + +In this version, the variable count starts at 1. The while loop checks whether +count is less than or equal to 5. As long as that condition is true, the loop +keeps running. Inside the loop, the program prints the current value of count, +then increases it by 1 using count += 1. Once the count reaches 6, the condition +becomes false, and the loop ends. + +An important detail here is **indentation**. Python uses indentation to show +which lines of code belong to the loop. Any indented lines after the while +statement are considered part of the loop and will be repeated each time it +runs. Without the correct indentation, Python won’t know what to include in the +loop and will raise an error. + +> Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5 + +### Encapsulating the Code in a Function + +Another useful concept in programming is the **function**. Functions allow you +to group code to be reused in different parts of your program. Let’s put our +counter logic into a function: + +```python +def simple_counter(target): + count = 1 + while count <= target: + print("Count is:", count) + count += 1 + +simple_counter(5) +``` + +Functions are **defined** by the keyword _def_ followed by a function name. +Here, we additionally add a **parameter** with the name _target_ to set the +upper limit for our counter. Observe that the previous limit _5_ is replaced by +the parameter. Also note that again indentation defines which commands belong to +the function. + +At the end, you just have to **call** the function passing a value for the +parameter. If you pass _5_, the output is exactly the same as with the previous +code without function. Using functions has three major benefits: + +1. **Code organization**: It is easy to understand your code if it is structured + in small logical blocks. +2. **Reusability**: If you need a second counter, you just need to call the + function again +3. **Abstraction**: Functions can be very complex, but often it's not required + to know how they work. It is sufficient to know what they do and how you can + use them. Take the print() function as an example. We didn't explain how it + works, but you still can use it. + +### Conditional statements + +Next, we want to improve the text output using the following logic: + +- If the count has reached the target, print "finally done". +- If the count is greater than or equal to the target minus 2, print "almost + there". +- Otherwise, print "stay patient". + +We can use **if-else** statements to directly translate this logic into +programming code: + +```python +def simple_counter(target): + count = 1 + while count <= target: + if count == target: + print("Finally done! Count is:", count) + elif count >= target - 2: + print("Almost there! Count is:", count) + else: + print("Stay patient! Count is:", count) + count += 1 + +simple_counter(5) +``` + +**if** is used to check for a condition. Note that if you want to check for +equality, you have to use "==" and **not** "=". This is a common beginner +mistake. **elif** (short for 'else if') is used to check a second condition if +the if condition is false. You can include as many elif clauses as needed. +**else** handles all remaining cases and acts as the "otherwise" in your +program. Again, indentation shows which command belongs to which structure. + +> Stay patient! Count is: 1
Stay patient! Count is: 2
Almost there! +> Count is: 3
Almost there! Count is: 4
Finally done! Count is: 5 + +### Side Note: Indentation & Style Guides + +You've learned already that indentation is crucial for structuring your program. +In Python, it plays an even more important role because it defines which +commands belong to which blocks of code. However, we haven't yet defined what +indentation actually is. The reason is that there’s no single standard and +programmers often debate the best way to handle it. On the one hand, you can use +**tabs**, which take up less space in a file but may look different depending on +the editor or environment. On the other hand, you can use **spaces**. Typically, +2 or 4 spaces are used. Spaces offer a consistent appearance across all tools. +In this blog, we’ve chosen to use four spaces, as they provide a clear and +easy-to-read structure for your code. No matter what you use, use it +consistently! + +Beyond indentation, there are many other aspects of coding style. For example, +notice that we use one empty line between the function definition and the +function call. This raises more questions: + +- Where should I use empty lines? +- What’s the ideal maximum line length? +- How should variables be named? + +There are many practical aspects that people try to standardize in so-called +**style guides**. For Python, the most popular style guide is +[PEP 8](https://peps.python.org/pep-0008/). While following such guides isn’t +mandatory, doing so helps you write clean, readable, and maintainable code. + +## Summary + +We hope you enjoyed writing your first Python program! Let's quickly recap what +we covered: + +- _Hello World_ programs are used to test your environment +- Python can be used with scripts or interactively, for example, as a handy + calculator +- You implemented your first program using basic programming concepts: + - Printing to the console + - Variables + - Loops + - Functions + - Conditional statements (if-else) +- [PEP 8](https://peps.python.org/pep-0008/) is a popular style guide for + Python. + +In our next post, we’ll build on this foundation by exploring more core Python +concepts. Until then, happy coding, and don't forget to follow us on +[X](https://x.com/bitsandvolts). From 563072be0199707110567d30fe7a8910e2d6815a Mon Sep 17 00:00:00 2001 From: Bjoern Hartmann Date: Thu, 29 May 2025 20:01:57 +0200 Subject: [PATCH 2/2] [GS] New: Python packages and venvs --- _data/navigation.yml | 2 + _posts/2026-01-01-gs_00011_python-venvs.md | 208 +++++++++++++++++++++ assets/images/gs_00011_color_output.png | Bin 0 -> 7220 bytes 3 files changed, 210 insertions(+) create mode 100644 _posts/2026-01-01-gs_00011_python-venvs.md create mode 100644 assets/images/gs_00011_color_output.png diff --git a/_data/navigation.yml b/_data/navigation.yml index 69872ebc..c718b01b 100644 --- a/_data/navigation.yml +++ b/_data/navigation.yml @@ -36,3 +36,5 @@ getting_started_0: url: /categories/getting_started/programming_tutorial_II - title: "Python: Hello World" url: /categories/getting_started/python_hello_world + - title: "Python Packages & Venvs" + url: /categories/getting_started/python_packages_and_venvs diff --git a/_posts/2026-01-01-gs_00011_python-venvs.md b/_posts/2026-01-01-gs_00011_python-venvs.md new file mode 100644 index 00000000..9fca6ac0 --- /dev/null +++ b/_posts/2026-01-01-gs_00011_python-venvs.md @@ -0,0 +1,208 @@ +--- +layout: single +title: "Python: Python Packages & Virtual Environments" +category: Getting Started +permalink: /categories/getting_started/python_packages_and_venvs +excerpt: "Organize Python Packages in Virtual Environments" +description: + In this blog post, you will learn how to use a Python virtual environment to + organize Python packages for your project. +author: Bjoern Hartmann +toc: true +toc_label: "Content" +toc_sticky: true +toc_icon: "align-justify" +sidebar: + nav: "getting_started_0" +header: + overlay_color: "#000" + overlay_filter: "0.5" + overlay_image: /assets/images/getting_started.jpeg +--- + +Hello and welcome to our next post. We hope you take the great momentum of our +[last post](/categories/getting_started/programming_hello_world) where you were +able to run your first Python program. In this post, you'll learn about Python +Packages and Virtual Environments. Let's get started! + +## Python Packages + +The beauty of Python and one of the reasons why it is so popular and +beginner-friendly is the huge community: There are a lot of people in forums +that can help you if you get stuck, and there is a lot of code created by other +people that you can reuse for your own projects. + +While implementing your program, you'll face multiple challenges. Imagine you +want to plot some data or you want to solve some mathematical equation. No +matter what, chances are high that someone else has already done that exercise +before and most likely there is a Python **package** that you can download and +use to solve your problem. + +Isn't this cool? We will show a quick example in this post. + +## Virtual Environments + +One challenge is to keep all packages, that are relevant to your project, +organized. This is what **virtual environments** are for. Let's skip the theory +and directly jump into a concrete example. Typically, you create one virtual +environment (short: _venv_) per project. For the counter, that we've implemented +in our [previous post](/categories/getting_started/programming_hello_world) we +haven't created a venv yet. So, let's do it now. Here is again the code we +developed in our previous post: + +```python +def simple_counter(target): + count = 1 + while count <= target: + if count == target: + print("Finally done! Count is:", count) + elif count >= target - 2: + print("Almost there! Count is:", count) + else: + print("Stay patient! Count is:", count) + count += 1 + +simple_counter(5) +``` + +You create the venv using: + + $ python -m venv counter_venv + +This creates a new venv called counter_venv. Of course, you can choose whatever +name you like. If we want to work with a venv we have to activate it: + + $ source counter_venv/bin/activate + +You can check that it works with the following command: + + $ which python + counter_venv/bin/python + +This command returns the path to the used Python binary. In our case, it should +point to a path inside our created environment. + +## Pip - Python's Package Manager + +Let's take our counter and put some colors on the output. And yes! There is a +package called _rich_ that makes our lives very easy. For installation, we use +Python's package manager **Pip**: + + $ pip install rich + +Note that this will install the package only for the activated venv. + +## Our Counter with beautiful colors + +```python +from rich import print + +def simple_counter(target): + count = 1 + while count <= target: + if count == target: + print("[green]Finally done![/green] Count is:", count) + elif count >= target - 2: + print("[yellow]Almost there[/yellow]! Count is:", count) + else: + print("[red]Stay patient[/red]! Count is:", count) + count += 1 + +simple_counter(5) +``` + +
+ Colored counter +
+ +At the beginning of our code, you see a new **import statement**. The _rich_ +package defines a _print_ function that we want to use. Inside the _print_, we +simply annotate the desired color in square brackets. Isn't that easy? + +Well ... You might wonder how we know about this package and how to use it. The +answer is a mix of Google, ChatGPT, and documentation. For example, you can find +the documentation of the _rich_ package +[here](https://rich.readthedocs.io/en/stable/introduction.html). After some time +you will know the most popular packages. + +## Finalize your project + +When your project is ready and you want to distribute it to others, you need to +make sure that they install the same packages as you did. This can easily be +done using: + + $ pip freeze > requirements.txt + +If you open the file, you'll find the following content: + + markdown-it-py==3.0.0 + mdurl==0.1.2 + Pygments==2.19.1 + rich==14.0.0 + +At the end, you can spot the _rich_ package including a version tag. This is +important and guarantees that someone else uses the exact same version as you +used for development. But what about the other listed packages? They are +required by the _rich_ package itself. Pip keeps track of all dependencies +automatically and installs required packages for you. You can check a package's +information using: + + $ pip show markdown-it-py + Name: markdown-it-py + Version: 3.0.0 + Summary: Python port of markdown-it. Markdown parsing, done right! + Home-page: https://github.com/executablebooks/markdown-it-py + Author: + Author-email: Chris Sewell + License: + Location: /home/bjoern/projects/hello_world/counter_venv/lib/python3.13/site-packages + Requires: mdurl + Required-by: rich + +You can see that it is required by the _rich_ package and itself requires +_mdurl_. + +Once you have exported your requirements, someone else just needs to install +them using: + + $ pip install -r requirements.txt + +When you want to leave your venv you can deactivate it using: + + $ deactivate + +## Useful Packages + +While the most useful Python packages will depend on your specific project, here +are some widely used and popular packages that are definitely worth exploring: + +- NumPy – Core library for numerical computing and working with arrays. +- Pandas – Powerful data analysis and manipulation toolkit. +- Requests – Elegant and simple HTTP library for making API calls. +- Matplotlib – 2D plotting library for creating charts and graphs. +- Scikit-learn – Machine learning library for classification, regression, + clustering, and more. +- BeautifulSoup – HTML and XML parser used for web scraping. +- Pytest – Popular framework for writing and running tests. +- FastAPI – Modern, fast (high-performance) web framework for building APIs. + +## Summary + +We hope this post helped you understand how to organize Python packages using +virtual environments! Let’s quickly recap what we covered: + +- Python has a huge ecosystem of reusable packages you can install and use in + your projects. +- Virtual environments (venv) help to organize packages for your project +- You learned how to: + - Create and activate a virtual environment + - Use pip to install packages like _rich_ + - Use _pip freeze_ to save dependencies to a requirements.txt file + - Use _pip show_ to inspect package metadata and dependencies +- We also introduced some popular Python packages worth checking out. + +At this point, you are ready to start your own project! You can start by picking +one of the listed packages and playing around with it. The internet is full of +awesome projects, so we are sure you will find an idea for your first own +project! Happy coding, and don't forget to follow us on +[X](https://x.com/bitsandvolts). diff --git a/assets/images/gs_00011_color_output.png b/assets/images/gs_00011_color_output.png new file mode 100644 index 0000000000000000000000000000000000000000..4cfe4b21c72e9bcb9b8aada2bb6e5410ac051a2a GIT binary patch literal 7220 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