How to Make Decisions in Code Using Python

In this tutorial, we are going to learn how to use if-else statements in Python to make decisions. This is a core concept in robotics, where your robot needs to decide its actions based on sensor inputs and internal states. 

Prerequisites

Working with if-else Statements

Let’s get started by opening your code editor and creating a new file named robot_decision_making.py inside the following folder: ~/Documents/python_tutorial.

Type the following code:

# if-else statement for robot movement
obstacle_detected = True

if obstacle_detected:
    print("Stop or change direction.")
else:
    print("Continue moving forward.")

In this script, our robot checks if there’s an obstacle. If obstacle_detected is True, the robot will stop or change direction. Otherwise, it will keep moving forward.

1-obstacle-detected

Now, let’s simulate more complex decision-making with an elif statement, useful for handling different types of sensors.

# Using elif for sensor-based conditions
sensor_reading = 'low_battery'

if sensor_reading == 'obstacle':
    print("Avoid obstacle.")
elif sensor_reading == 'low_battery':
    print("Return to charging station.")
else:
    print("Normal operation.")

This script helps a robot decide actions based on its sensor readings, whether to avoid obstacles, recharge, or proceed with normal tasks.

2-return-to-charging-station

We can also nest if-else statements to handle hierarchical decisions.

# Nested if-else for more detailed decision-making
if sensor_reading == 'obstacle':
    distance = 5  # distance to obstacle in meters
    if distance < 1:
        print("Immediate stop.")
    else:
        print("Prepare to change direction.")
else:
    print("Continue exploration.")

This approach lets our robot make more nuanced decisions based on the distance to an obstacle.

3-continue-exploration

To manage multiple conditions simultaneously, like combining sensor checks and operational states, we use logical operators.

# Logical operators for complex conditions
battery_level = 20  # percentage
if sensor_reading == 'obstacle' and battery_level > 50:
    print("Navigate around the obstacle.")
elif sensor_reading == 'obstacle' and battery_level <= 50:
    print("Return to base for recharge.")
else:
    print("Continue on current path.")

This script demonstrates how our robot can decide whether to navigate around obstacles or return to base for a recharge based on its battery level.

4-continue-on-current-path

Working with if-elif Statements

In this tutorial, we’re going to dive deeper into using if-elif statements in Python to handle multiple conditions more efficiently. This is important for making your programs smarter and more responsive to a range of inputs.

Let’s start by creating a new file called robot_decision_system.py inside the following folder: ~/Documents/python_tutorial.

If-elif statements allow our robots to evaluate multiple conditions and react appropriately, which is important for tasks like navigation and interaction.

Here is an example with a robot deciding how to move based on sensor data.

# Robot movement decision system
obstacle_type = 'wall'

if obstacle_type == 'wall':
    print("Turn around")
elif obstacle_type == 'small object':
    print("Go over")
elif obstacle_type == 'gap':
    print("Stop and find another path")
else:
    print("Clear path, continue moving")

In this script, the robot checks the type of obstacle and decides its action. The if-elif chain stops checking after it finds a true condition.

5-turn-around

To add more complexity, we’ll integrate a power check.

# Power-aware robot decision system
battery_level = 20  # percentage

if obstacle_type == 'wall' and battery_level > 20:
    print("Turn around")
elif obstacle_type == 'small object' and battery_level > 10:
    print("Go over")
elif obstacle_type == 'gap':
    print("Stop and find another path")
else:
    print("Low power: Return to base")

You can see how the robot’s decision-making adjusts based on the obstacle type and battery level. This method is efficient for guiding a robot’s actions.

6-low-power-return-to-base

Implementing Comparison Operators

Let’s open your code editor and create a new file named comparison_operators.py inside the following folder: ~/Documents/python_tutorial.

Comparison operators compare two values and return a Boolean value, either True or False. They’re useful for directing the flow of logic in programs, particularly in if statements.

Let’s take a look at each of the primary comparison operators.

# Equal to
print("10 == 10:", 10 == 10)  # Outputs True

# Equal to
print("10 == 5:", 10 == 5)  # Outputs False

# Not equal to
print("10 != 5:", 10 != 5)    # Outputs True

# Less than
print("5 < 10:", 5 < 10)      # Outputs True

# Greater than
print("10 > 5:", 10 > 5)      # Outputs True

# Less than or equal to
print("5 <= 5:", 5 <= 5)      # Outputs True

# Greater than or equal to
print("10 >= 5:", 10 >= 5)    # Outputs True
7-implementing-comparison

These examples show how we can evaluate basic numerical comparisons.

Let’s apply these in a practical scenario, like a robotic sensor reading that determines if an action is needed.

# Robot sensor threshold check
sensor_threshold = 10
sensor_reading = 12

if sensor_reading >= sensor_threshold:
    print("Sensor threshold exceeded, take action.")
else:
    print("Sensor levels normal, no action required.")

In this script, we check if a sensor reading exceeds a set threshold, a common task in robotic programming.

8-take-action

Comparison operators aren’t limited to numbers. Let’s look at how they work with strings.

# String comparison
print("'abc' < 'def':", 'abc' < 'def')  # Outputs True
9-compare-string

This example demonstrates that ‘abc’ is less than ‘def’ based on alphabetical order, similar to how words are ordered in a dictionary.

That’s it! Keep building!

How to Create Basic Programs Using Python

In this tutorial, we are going to build basic programs using Python.

Prerequisites

  • You have completed this tutorial.
  • I am using VS Code for my Python development environment, but you are free to use any development environment you wish.

Build a Basic Calculator

Let’s start by building a basic calculator. This exercise will help you understand how to handle user input and perform basic arithmetic operations in Python.

Open a new terminal window, and move to the directory where we will store our code.

cd ~/Documents/python_tutorial

I will open VS Code.

code .

Right-click in the Explorer pane and select “New File”.

Name the file basic_calculator.py, and press Enter.

First, let’s ask the user to input two numbers. Type the following lines:

num1 = float(input("Enter first number: "))
num2 = float(input("Enter second number: "))

These commands prompt the user for input, converting the input into floating point numbers for arithmetic operations.

Next, we need to ask the user to choose the operation. Add this line:

operation = input("Choose the operation (+, -, *, /): ")

Now, we’ll use conditional statements to perform the operation selected by the user.

if operation == '+':
    result = num1 + num2
elif operation == '-':
    result = num1 - num2
elif operation == '*':
    result = num1 * num2
elif operation == '/':
    if num2 != 0:
        result = num1 / num2
    else:
        result = "Error! Division by zero."
else:
    result = "Invalid operation selected."

print(result)

This if-else structure helps our calculator decide what to do based on the user’s choice.

After writing the code, save your file. Let’s now run our program to see how it works.

Enter the numbers and the operation when prompted. 

Watch as your program calculates and displays the result.

1-basic-calculator

Making Your Program Executable

Let’s see how to make basic_calculator.py executable. We will do this directly from the command line. This will enhance your workflow by allowing you to run your Python scripts without explicitly calling the Python interpreter each time.

Let’s begin by opening the basic_calculator.py script we created in the previous lecture. Once open, we need to add a shebang line at the very top of the file.

Type the following line as the first line in your file:

#!/usr/bin/env python3

This shebang line tells the system that this script should be run using Python 3, which we’ve installed on our machine. Make sure this line is at the top, before any other code.

After adding the shebang, save your file. 

The next step is to make the script executable. We’ll do this using the terminal.

Open your terminal in Visual Studio Code by going to View -> Terminal

Navigate to the directory where your  basic_calculator.py file is located. Now, type the following command:

cd ~/Documents/python_tutorial
chmod +x basic_calculator.py 

This command changes the file’s permissions, making it executable. 

Now, you can run your Python script directly from the command line.

To run your script, simply type the following in your terminal:”

./basic_calculator.py 
2-make-program-executable

Notice how we didn’t have to type ‘python3’ before our script name. The system recognizes it as an executable file and runs it using the Python interpreter specified in the shebang line.

Go ahead and test different inputs to see how your calculator works now as an executable script.

Doing Basic Calculations

Let’s explore how to perform basic calculations in Python. We’ll cover addition, subtraction, multiplication, division, and a bit about modulus operations.

Let’s get started by opening your code editor. We’ll create a new file named basic_calculations.py.

In this file, we’ll write small code snippets to demonstrate each type of calculation. First, let’s start with addition.

# Addition
print("Addition of 5 + 3 is:", 5 + 3)

This will output the sum of 5 and 3. Now, let’s do subtraction.

# Subtraction
print("Subtraction of 5 - 3 is:", 5 - 3)

Next, we have multiplication.

# Multiplication
print("Multiplication of 5 * 3 is:", 5 * 3)

And then division.

# Division
print("Division of 5 / 3 is:", 5 / 3)

Division in Python gives you a float. If you need the integer quotient, you can use the floor division operator.

# Floor Division
print("Floor division of 5 // 3 is:", 5 // 3)

Lastly, let’s look at the modulus operation, which gives the remainder of a division.

# Modulus
print("Modulus of 5 % 3 is:", 5 % 3)

After typing these examples, save your file. Now, let’s run this script to see the output of these basic calculations.

3-basic-calculations

You should see the results for each operation displayed in the terminal. These operations are fundamental to programming and form the basis for more complex algorithms.

Working with Random Values

Let’s learn how to work with random values in Python. This capability is essential for simulating uncertainty in robotics applications and for creating varied testing scenarios.

Let’s start by opening your code editor. We’ll create a new file and name it working_with_random.py.

To generate random numbers, Python provides a module named random. First, we need to import this module.

import random

Let’s begin with generating a random integer. We’ll use the randint function, which returns an integer between the specified range.

# Generate a random integer between 1 and 10
random_integer = random.randint(1, 10)
print("Random integer between 1 and 10:", random_integer)

Next, we’ll generate a random float. The random function returns a floating-point number between 0.0 and 1.0.

# Generate a random float
random_float = random.random()
print("Random float between 0.0 and 1.0:", random_float)

Sometimes, you may want to generate a float within a different range. You can do this by multiplying the result of random().

# Generate a random float between 0.0 and 5.0
random_float_in_range = random.random() * 5
print("Random float between 0.0 and 5.0:", random_float_in_range)

We can also pick a random element from a list. Let’s create a list of colors and select one randomly.

# Pick a random element from a list
colors = ['red', 'blue', 'green', 'yellow']
random_color = random.choice(colors)
print("Random color selected:", random_color)

Lastly, if you want to shuffle the items in a list randomly, you can use the shuffle method.

# Shuffle a list
random.shuffle(colors)
print("Shuffled colors:", colors)

After entering these examples, don’t forget to save your file. Now, let’s run the script to see how random values are generated.

4-random-variables

You’ll see the outputs for each of the random operations we scripted. This functionality is invaluable for creating diverse and dynamic environments in simulations and tests.

Using Nan and Infinity

Let’s explore how to work with NaN (Not a Number) and Infinity in Python. These are special floating-point values that you may encounter in numerical computations, especially when dealing with undefined or unbounded values.

Let’s start by opening your code editor. We’ll create a new file and name it nan_and_infinity.py.

To use NaN and Infinity, Python doesn’t require any special imports as they are part of the standard float type. Let’s start with Infinity.

# Positive Infinity
positive_infinity = float('inf')
print("Positive Infinity:", positive_infinity)

# Negative Infinity
negative_infinity = float('-inf')
print("Negative Infinity:", negative_infinity)

These lines create variables for positive and negative infinity. Operations with these values yield predictable results, following rules of mathematical infinity.

Next, we have NaN. It’s a special value used to denote that a result of a computation cannot be defined in meaningful terms.

# NaN example
not_a_number = float('nan')
print("Example of NaN:", not_a_number)

Let’s see some operations with NaN. Any operation involving NaN typically results in NaN, indicating an invalid result.

# Operations with NaN
print("NaN added to a number:", not_a_number + 5)
print("NaN multiplied by a number:", not_a_number * 2)

Interestingly, comparing NaN with anything, even itself, is always false. This is useful for checking if a value is NaN.

# Checking if a value is NaN
print("Is NaN equal to NaN?:", not_a_number == not_a_number)

To properly check for NaN, we use the math.isnan() function from the math module.

import math
print("Using math.isnan() to check NaN:", math.isnan(not_a_number))

Now, let’s run the script to see how NaN and Infinity behave in Python.

5-nan-infinity

You’ll see the outputs for each operation, illustrating how special floating-point values like NaN and Infinity are handled in Python.

That’s it. You have gotten some good experience building programs in Python to perform fundamental calculations.

Thank you, and I’ll see you in the next tutorial.

Keep building!

Getting Started with Python for Robotics Projects

In this tutorial, we will get started with Python development for robotics projects.

Prerequisites

ROS 2 Python Style Guide

Before we get started, it is important to note that we will be following the ROS 2 Python Style Guide throughout this tutorial and future tutorials where we use Python. This guide is based on PEP 8, the official style guide for Python code, with some ROS 2-specific modifications. 

  • 4 spaces for indents
  • 100 characters max per line
  • Single quotes for strings
  • Imports at the top, grouped by type
  • snake_case for functions and variables
  • CapWords convention for class names

Adhering to these guidelines will help make sure your code is consistent with ROS 2 projects in the community that use Python.

Create a Folder to Store Your Python Code

Let’s start by creating a folder to store our Python code. Open a terminal window, and type:

mkdir -p ~/Documents/python_tutorial
cd ~/Documents/python_tutorial

Open Visual Studio Code (Optional)

For those of you who will be using Visual Studio Code for your Python development, type this:

code .

Otherwise, you can open your favorite code editor.

Configure Visual Studio Code (Optional)

Let’s configure our settings so that our code follows the ROS 2 Python Style Guide which uses the PEP8 standards.

Click on the Extensions button on the left side.

1-click-on-extensions

Type autopep8 in the search bar.

Click Install the version made by Microsoft.

Type PyLint in the search bar.

Click Install the version made by Microsoft.

Click on “File” in the top-left corner.

Select “Preferences”

Click on “Settings”.

In the search bar at the top of the Settings page, type “editor rulers” and click “Edit in settings.json”.

2-editor-rulers

Add or modify:

{
 "workbench.colorTheme": "Solarized Dark",
 "editor.fontSize": 30,
 "terminal.integrated.fontSize": 30,
 "editor.rulers": [100],
 "[python]": {
   "editor.formatOnSave": true,
   "editor.defaultFormatter": "ms-python.autopep8",
   "editor.tabSize": 4,
   "editor.insertSpaces": true
 },
 "[cpp]": {
   "editor.tabSize": 2,
   "editor.insertSpaces": true
 },
 "editor.tabSize": 2,
 "editor.insertSpaces": true,
 "files.trimTrailingWhitespace": true,
 "autopep8.args": [
   "--max-line-length",
   "100",
   "--aggressive"
 ]
}

Save and close the settings.json file.

Let’s create a new Python file with intentional style issues to test our PEP 8 compliance setup. 

To test the configuration, create a new Python file named test_formatting.py. Right-click underneath the name of the folder on the left panel: “PYTHON_TUTORIAL”.

Click “New File”.

Name the file test_formatting.py.

Press Enter.

Paste the following code with intentional style issues:

class robot:
 def __init__( self,name ):
  self.Name=name

 def greet( self ):
    print( "Hello, my name is "+self.Name )

myRobot=robot("R2D2")
myRobot.greet( )
3-before-saving

Save the file. You should immediately see some changes and warnings. Let’s examine what autopep8 has automatically fixed and what issues remain.

After saving, your code should look more like this:

4-after-saving
class robot:
    def __init__(self, name):
        self.Name = name

    def greet(self):
        print("Hello, my name is " + self.Name)


myRobot = robot("R2D2")
myRobot.greet()

autopep8 has automatically fixed several issues:

  • Corrected indentation to use 4 spaces
  • Fixed spacing around operators and after commas
  • Removed extra spaces inside parentheses

However, there are still style problems that autopep8 doesn’t address. These should be highlighted by PyLint:

  • Class name should be in CapWords format (PascalCase)
  • Variable names should be in snake_case
  • The file, class, and methods need to have docstrings, which provide an explanation of what the code does (docstrings can be added directly in VS Code by going on the line underneath the method or class, and typing “””.

To fix these remaining issues, manually update your code as follows:

"""This module defines a simple Robot class for demonstration purposes."""


class Robot:
    """Simple robot class that can greet."""

    def __init__(self, name):
        """Initialize the robot with a name."""
        self.name = name

    def greet(self):
        """Print a greeting from the robot."""
        print(f"Hello, my name is {self.name}")


my_robot = Robot("R2D2")
my_robot.greet()

After making these changes and saving the file, you should see no more warnings in the “Problems” tab at the bottom of your screen.

5-after-fixing-warnings-pylint-autopep8

By using autopep8 and PyLint in VS Code, we’ve set up an environment that helps us adhere to the ROS 2 Python Style Guide. autopep8 automatically handles many formatting issues, while PyLint provides additional guidance on style and best practices.

Remember, while these tools are extremely helpful, they don’t catch everything. It’s important to understand the principles behind the style guide and apply them as you write your code. 

In future robotics projects, this setup will help you write clean, consistent Python code that adheres to ROS 2 standards, making your code more readable and maintainable. 

Finally, let’s run the code.

Look for the “Run” button (a triangle play icon) in the top-right corner of the editor.

Click this button to run the currently open Python file.

6-run-the-code

You should get this output:

7-run-the-code-test-formatting

Hello, my name is R2D2

You can also run the file, by going to the terminal window, and typing:

python3 test_formatting.py

Creating Variables

In this section, we will learn how to create and use variables in Python.

Variables in Python are like containers; they store data values. Unlike some other programming languages, Python has no command for declaring a variable. A variable is created the moment you first assign a value to it.

Let’s begin. Right-click in the Explorer pane and select “New File”.

Name the file robot_variables.py, and press Enter.

In the new file, let’s start by creating our first variable:

robot_name = 'AutomaticAddison'

Here, robot_name is a variable, and we’ve assigned it the value ‘AutomaticAddison’, which is a string. 

Python knows the type of the variable based on the value it’s given. This feature is known as dynamic typing.

You can also store numbers in variables. Let’s create an integer variable and a floating-point variable:

robot_speed = 5  # This is an integer
robot_accuracy = 99.9  # This is a float

The # symbol in Python is used to create comments. Comments are notes within the code that Python ignores when running the program.

We can use variables to perform calculations. 

For example, if we want to increase the robot_speed by 3, we can do so like this:

robot_speed = robot_speed + 3
print(robot_speed)

Now run the code.

In the terminal, you’ll see the value of robot_speed printed out.

8-robot-speed-printed-out

Notice how we used the same variable to update its own value. 

Python also allows you to create multiple variables in a single line. Here’s how you can assign different robot parts to different variables simultaneously:

arm, leg, head = 'ArmBot', 'LegBot', 'HeadBot'
print(arm)
print(leg)
print(head)

Run the code.

9-run-the-code-arm-leg-head

Finally, variables can be reassigned to different data types.

For example, if we want to reassign robot_speed to a string, we can do that like this:

robot_speed = 'fast'
print(robot_speed)

Run the code again.

10-robot-speed-a-string

And just like that, robot_speed now holds a string instead of an integer.

Understanding Data Types

Let’s learn about data types in Python. 

In Python, data types are the classifications we give to different kinds of data. Understanding them helps you manage how Python will process your data. 

Let’s look at the most common data types used in Python.

In VS Code, right-click in the Explorer pane and select “New File”.

Name the file robot_data_types.py and press Enter.

First, we have integers, known as int. These are whole numbers without a decimal point. For example:

distance = 120
print(distance)

#Check the data type
print(type(distance))

Here is the output:

11-integer

Next is the floating-point number, or float, which is a number with a decimal. It’s often used in Python for more precise measurements or calculations:

speed = 25.5
print(speed)

#Check the data type
print(type(speed))
12-float

Strings, or str, are sequences of characters used for storing text. In Python, you enclose strings in quotes:

robot_name = 'AutomaticAddisonBot'
print(robot_name)

# Check the data type
print(type(robot_name))
13-string

Booleans, or bool, represent one of two values: True or False. This data type is useful when dealing with conditions in your programming:

is_active = True
print(is_active)

# Check the data type
print(type(is_active))
14-boolean

Lists are ordered collections of values that can hold a mix of data types, and they are mutable, meaning you can change their content without changing their identity:

components = ['sensors', 'motors', 'camera']
print(components)

# Check the data type
print(type(components))
14-list

Tuples are similar to lists, but they are immutable, meaning once they are created, their values cannot be changed:

dimensions = (20, 30, 40)
print(dimensions)

# Check the data type
print(type(dimensions))
15-tuple

Dictionaries, or dict, store key-value pairs and are extremely useful for storing data items like a database:

robot_specs = {'name': 'AutoBot', 'speed': 25.5}
print(robot_specs)

# Check the data type
print(type(robot_specs))
16-dictionaries

Understanding Casting

Let’s explore the concept of casting in Python. 

Casting is important when you need to specify or alter the data type of a variable in your code. This is particularly useful in robotics when you need to ensure that data types match expected parameters for functions or calculations.

In VS Code, right-click in the Explorer pane and select “New File”.

Name the file robot_casting.py and press Enter.

First, if you have a number as a string but need to perform mathematical operations, you’ll need to convert it to an integer or float:

speed_str = '30'
print(speed_str)
print(type(speed_str))

speed_int = int(speed_str)
print(speed_int)
print(type(speed_int))
17-casting

This converts the string ’30’ to the integer 30, enabling arithmetic operations.

Similarly, if you’re working with floating-point numbers but need to convert them to integers for functions that do not accept floats, you can use:

distance_float = 120.5
print(distance_float)
print(type(distance_float))

distance_int = int(distance_float)
print(distance_int)
print(type(distance_int))

Here, distance_float is converted to 120, truncating the decimal part.

18-cast-float-to-int

On the other hand, sometimes you need to perform accurate division calculations with integers. In Python, dividing two integers yields an integer result. 

To get a float result, one of the numbers must be a float. You can achieve this by casting:

length = 25
width = 4
aspect_ratio = float(length) / width

print(aspect_ratio)

This ensures aspect_ratio holds the value 6.25 rather than just 6.

19-float-casting

Lastly, let’s look at converting numbers to strings, which is common when you need to concatenate numbers to strings for messages or outputs:

age = 5
age_str = str(age)
message = 'The robot is ' + age_str + ' years old.'
print(message)

This casts the integer 5 to the string ‘5’, making it possible to construct the full message string without errors.

20-cast-string

Working with Output

Let’s see how to work with output in Python. Managing output effectively is important for debugging, monitoring the state of your robotics applications, and providing interactive user experiences. Let’s get started.

In VS Code, right-click in the Explorer pane and select “New File”.

Name the file robot_output.py and press Enter.

In Python, the print() function is the most common way to output data. Whether you’re outputting simple messages or complex data structures, print() can handle it all. Let’s look at some examples.

First, a straightforward message:

print("Hello, robot world!")

This sends the text “Hello, robot world!” to the console, which is useful for simple notifications about the program’s status.

21-hello-robot-world

You can also use the print() function to output multiple items in one line by separating them with commas:

robot_name = 'AutomaticAddisonBot'
task_status = 'active'

print('Robot Name:', robot_name, '- Status:', task_status)

This will output:

22-print-robot-status

For more complex outputs, you might want to format strings. Python’s string formatting capabilities are powerful. 

Here’s how you can use formatted string literals, also known as f-strings:

battery_level = 85
print(f'Battery Level: {battery_level}%')

This injects the value of battery_level directly into the string, making it simpler to construct detailed messages dynamically.

23-battery-level

Sometimes, you may want to redirect your output from the console to a file. This is especially useful for logging data that you want to review later. Here’s how you can do it:

with open('log.txt', 'a') as file:
    print('An error occurred', file=file)

This code snippet opens log.txt in append mode (‘a’) and writes “An error occurred” to the file instead of the console.

In the terminal window, type:

dir

You will see our new file log.txt.

That’s it for this tutorial! You’ve taken your first big step into Python programming. Thanks for following along with me, and I will see you in the next tutorial.

Keep building!