{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "ULxWGdhVqcRt" }, "source": [ "# Chapter 2: Data Types and Conditional Structures\n", "\n", "```{image} abertura-light.png\n", ":alt: A mosaic of character blocks, each block with a texture and a colour set by the depth of the decision that made it\n", ":class: abertura only-light\n", "```\n", "\n", "```{image} abertura-dark.png\n", ":alt: A mosaic of character blocks, each block with a texture and a colour set by the depth of the decision that made it\n", ":class: abertura only-dark\n", "```" ] }, { "cell_type": "markdown", "metadata": { "id": "euhixBFzp2a9" }, "source": [ "Variables are essential for storing information during program execution. Understanding data types is fundamental for writing functional and readable programs, as each data type is designed to store a specific type of information, such as integers, real numbers, strings, and booleans. Whenever more details about the topics are needed, it's recommended to access the [official Python documentation](https://docs.python.org/3/tutorial/index.html).\n", "\n", "## Defining Variables \n", "\n", "A variable is an identifier that represents a value. Variable declaration is done using the assignment operator (`=`). For example, the following line creates a variable called `name` and assigns the value \"Maria\" to it:\n", "\n", "```python\n", "name = \"Maria\"\n", "```\n", "\n", "
\n", "\n", "To access the value stored in a variable, simply use its name. The following example shows how to print the value stored in the `name` variable:\n", "\n", "```python\n", "name = \"Maria\"\n", "print(name)\n", "```\n", "**Code Output**\n", "```\n", "Maria\n", "```\n", "\n", "### Rules for Naming Variables\n", "\n", "Python has specific rules for creating variable names:\n", "\n", "| Rule | Valid Example | Invalid Example |\n", "|-------|----------------|------------------|\n", "| Must start with letter or `_` | `name`, `_value` | `1name` |\n", "| Can contain letters, numbers and `_` | `grade1`, `total_value` | `total-value` |\n", "| Cannot contain spaces | `my_variable` | `my variable` |\n", "| Case-sensitive | `name` ≠ `Name` | - |\n", "\n", "**Style convention:** In Python, the convention for variable names is to use **snake_case**, that is, lowercase words separated by underscores (`_`).\n", "\n", "```python\n", "# Good practices\n", "user_age = 25\n", "total_value = 100.50\n", "\n", "# Avoid\n", "UserAge = 25 # CamelCase style (used for classes)\n", "```\n", "\n", "
\n", "\n", "### Reserved Words\n", "\n", "Python has reserved words that cannot be used as variable names because they have special meanings in the language. Examples include: `if`, `else`, `for`, `while`, `def`, `class`, `return`, `True`, `False`, `None`, among others.\n", "\n", "```python\n", "# This will cause a syntax error\n", "# class = \"Python\" # 'class' is a reserved word\n", "```\n", "\n", "
\n", "\n", "```{admonition} Reserved Words\n", ":class: seealso\n", "To see the complete list of reserved words, consult the [official Python documentation](https://docs.python.org/3/reference/lexical_analysis.html#keywords).\n", "```\n", "\n", "The following video demonstrates how to use the Python interpreter in the terminal to create a variable and display its value:\n", "\n", "\n", "\n", "## Formatting Data Output \n", "Let's start with formatting, as this will help in understanding all the following examples. The `print()` function is used to display information on the screen, and can print strings, numbers, and other data types. \n", "\n", "**Displaying a Simple Message** \n", "```python\n", "print(\"Hello, world!\")\n", "```\n", "**Code Output**\n", "```\n", "Hello, world!\n", "```\n", "\n", "**Showing Information Concatenated with Commas** \n", "```python\n", "name = \"Maria\"\n", "age = 30\n", "print(\"Her name is\", name, \"and she is\", age, \"years old.\")\n", "```\n", "**Code Output**\n", "```\n", "Her name is Maria and she is 30 years old.\n", "```\n", "\n", "The following video demonstrates creating variables and using the `print()` function with concatenation:\n", "\n", "\n", "\n", "In this example, the `name` and `age` variables are concatenated with strings and separated by commas to create the final message. `print()` automatically inserts a space between elements.\n", "\n", "**Customizing the Separator (`sep`)** \n", "We can modify the separator using the `sep` argument, which defines what will be inserted between items: \n", "```python\n", "print(\"Maria\", \"30 years\", sep=\" - \")\n", "```\n", "**Code Output**\n", "```\n", "Maria - 30 years\n", "```\n", "By default, the separator is a space (`\" \"`), but we can change it as needed.\n", "\n", "**Using f-strings**\n", "\n", "```python\n", "name = \"Maria\"\n", "age = 30\n", "print(f\"Her name is {name} and she is {age} years old.\")\n", "```\n", "**Code Output**\n", "```\n", "Her name is Maria and she is 30 years old.\n", "```\n", "F-strings allow you to directly incorporate variables into the string, making the code more readable and concise.\n", "\n", "**Displaying Information on Multiple Lines with `\\n`**\n", "\n", "```python\n", "name = \"Maria\"\n", "age = 30\n", "print(\"Her name is\", name, \"\\nand she is\", age, \"years old.\")\n", "\n", "# Using f-string to get the same output\n", "print(f\"Her name is {name}\\nand she is {age} years old.\")\n", "```\n", "**Code Output**\n", "```\n", "Her name is Maria \n", "and she is 30 years old.\n", "```\n", "The line break (`\\n`) is used to format the output on multiple lines.\n", "\n", "**Formatting Numbers with Decimal Places**\n", "\n", "```python\n", "value = 123.456789\n", "print(f\"The formatted value is: {value:.2f}\")\n", "```\n", "\n", "**Code Output**\n", "```\n", "The formatted value is: 123.46\n", "```\n", "\n", "Inside the f-string, `:.2f` describes how the number should **look**: the `f` asks for floating-point notation and the `.2`, for two decimal places. The value stored in `value` stays the same; only what goes to the screen changes.\n", "\n", "The number of places is your choice, and the formatting also pads with zeros when places are missing:\n", "\n", "```python\n", "value = 123.456789\n", "print(f\"{value:.1f}\")\n", "print(f\"{10:.2f}\")\n", "```\n", "\n", "**Code Output**\n", "```\n", "123.5\n", "10.00\n", "```\n", "\n", "The second line is why `:.2f` shows up so often with prices: `10` becomes `10.00`, and a column of values lines up.\n", "\n", "Rounding always goes to the nearest value. The last digit can surprise you when a number looks like it falls exactly halfway, because not every decimal has an exact binary representation. That is the subject of **Floating-Point Precision**, later in this chapter." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Reading Data with `input()`\n", "\n", "The `input()` function allows the program to receive data from the user during execution. It displays a message (optional) and waits until the user types something and presses Enter.\n", "\n", "**Basic Example**\n", "```python\n", "name = input(\"Enter your name: \")\n", "print(f\"Hello, {name}!\")\n", "```\n", "**Code Output**\n", "```\n", "Enter your name: Maria\n", "Hello, Maria!\n", "```\n", "\n", "**Important:** The `input()` function always returns a **string** (`str`), even if the user types a number.\n", "\n", "```python\n", "age = input(\"Enter your age: \")\n", "print(f\"Data type: {type(age)}\")\n", "```\n", "**Code Output**\n", "```\n", "Enter your age: 25\n", "Data type: \n", "```\n", "\n", "To perform mathematical operations with numeric values, it's necessary to convert the data using `int()` or `float()`:\n", "\n", "```python\n", "age = int(input(\"Enter your age: \"))\n", "height = float(input(\"Enter your height: \"))\n", "\n", "print(f\"Age: {age}, Height: {height}\")\n", "print(f\"Types: {type(age)}, {type(height)}\")\n", "```\n", "**Code Output**\n", "```\n", "Enter your age: 25\n", "Enter your height: 1.75\n", "Age: 25, Height: 1.75\n", "Types: , \n", "```\n", "\n", "```{admonition} Note\n", ":class: note\n", "Type conversion will be covered in depth in the \"Type Conversion (Casting)\" section later in this chapter.\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Simple (Primitive) Data Types\n", "Simple types, also called primitives, are those that represent basic values used in most programs. They serve as the foundation for building more complex structures, allowing storage of numbers, text, logical values, among others. In Python, the main simple types include integers, floating-point numbers, booleans, and strings.\n", "\n", "### Integer Numbers\n", "\n", "The **integer** data type is used to represent whole numbers, both positive and negative, such as `1`, `2`, `3`, `-1`, `-2`, `-3`, among others. These values are used to express quantities and indices in programming, playing an important role in various applications.\n", "\n", "**Examples of Integer Usage**\n", "\n", "```python\n", "# Declaration and initialization of an integer variable\n", "x = 10\n", "print(f\"The value of x is: {x}, and its type is: {type(x)}\")\n", "\n", "# Assigning a new value to an integer variable\n", "x = 20\n", "print(f\"The new value of x is: {x}, and its type remains: {type(x)}\")\n", "\n", "# Adding two integers\n", "result = x + 10\n", "print(f\"The result of the sum is: {result}, and its type is: {type(result)}\")\n", "```\n", "\n", "**Code Output**\n", "\n", "```\n", "The value of x is: 10, and its type is: \n", "The new value of x is: 20, and its type remains: \n", "The result of the sum is: 30, and its type is: \n", "```\n", "\n", "In the example above, the variable `x` is initially declared and initialized with the value `10`. Then, `x` receives a new value, `20`, maintaining its `int` type. Finally, the operation `x + 10` results in `30`, also of type `int`, which is printed on the screen.\n", "\n", "**Unlimited Integer Size**\n", "\n", "Unlike other programming languages (such as C or Java), integers in Python do not have a fixed size limit. This means you can work with extremely large numbers without worrying about overflow:\n", "\n", "```python\n", "# Very large number\n", "large_number = 10 ** 100 # 10 to the power of 100 (googol)\n", "print(f\"Number with {len(str(large_number))} digits\")\n", "print(f\"Type: {type(large_number)}\")\n", "```\n", "\n", "**Code Output**\n", "\n", "```\n", "Number with 101 digits\n", "Type: \n", "```\n", "\n", "The following video demonstrates the use of large integers in Python:\n", "\n", "\n", "\n", "```{admonition} Practical Applications\n", ":class: tip\n", "This feature makes Python especially useful for applications involving cryptography, computational mathematics, and calculations with very large numbers.\n", "```" ] }, { "cell_type": "markdown", "metadata": { "id": "qzfww3aOmwmp" }, "source": [ "### Floating-Point Numbers \n", "The **floating-point** data type, represented by the `float` type in Python, is used to express decimal values. \n", "\n", "**Usage Examples:** \n", "\n", "```python \n", "# Declaration and initialization of a float variable \n", "y = 3.14 \n", "print(f\"The value of y is: {y}, and its type is: {type(y)}\") \n", "\n", "# Assigning a new value to a float variable \n", "y = 2.5 \n", "print(f\"The new value of y is: {y}, and its type remains: {type(y)}\") \n", "\n", "# Subtracting two floats \n", "result = y - 1.0 \n", "print(f\"The result of the subtraction is: {result}, and its type is: {type(result)}\") \n", "``` \n", "\n", "**Code Output**\n", "``` \n", "The value of y is: 3.14, and its type is: \n", "The new value of y is: 2.5, and its type remains: \n", "The result of the subtraction is: 1.5, and its type is: \n", "``` \n", "\n", "`float` values are essential for calculations involving decimal precision, such as mathematical, scientific, and financial operations.\n", "\n", "**Scientific Notation**\n", "\n", "Python allows representing very large or very small numbers using scientific notation with the letter `e` (or `E`):\n", "\n", "```python\n", "# Scientific notation\n", "speed_of_light = 3e8 # 3 × 10^8 = 300,000,000\n", "electron_mass = 9.1e-31 # 9.1 × 10^-31\n", "\n", "print(f\"Speed of light: {speed_of_light} m/s\")\n", "print(f\"Electron mass: {electron_mass} kg\")\n", "print(f\"Types: {type(speed_of_light)}, {type(electron_mass)}\")\n", "```\n", "\n", "**Code Output**\n", "```\n", "Speed of light: 300000000.0 m/s\n", "Electron mass: 9.1e-31 kg\n", "Types: , \n", "```\n", "\n", "**Floating-Point Precision**\n", "\n", "It's important to know that floating-point numbers have **limited precision** due to how they are stored in binary. This can cause unexpected results:\n", "\n", "```python\n", "# Classic precision problem\n", "result = 0.1 + 0.2\n", "print(f\"0.1 + 0.2 = {result}\")\n", "print(f\"0.1 + 0.2 == 0.3? {result == 0.3}\")\n", "```\n", "\n", "**Code Output**\n", "```\n", "0.1 + 0.2 = 0.30000000000000004\n", "0.1 + 0.2 == 0.3? False\n", "```\n", "\n", "```{admonition} Important - Precision Limitation\n", ":class: warning\n", "This behavior is not a Python bug, but a characteristic of floating-point representation (IEEE 754 standard) common to virtually all programming languages. For financial calculations that require exact precision, consider using the `decimal` module.\n", "```" ] }, { "cell_type": "markdown", "metadata": { "id": "DMSWpKnEandh" }, "source": [ "### Booleans\n", "\n", "Boolean types represent logical values, meaning they can be `True` or `False`. These values are commonly used to represent conditions, test results, and logical expressions.\n", "\n", "**Examples of Boolean Usage**\n", "\n", "```python\n", "# Declaring boolean variables\n", "active = True\n", "completed = False\n", "\n", "print(f\"Active: {active}, Type: {type(active)}\")\n", "print(f\"Completed: {completed}, Type: {type(completed)}\")\n", "\n", "# Comparing two values\n", "print(f\"10 > 20: {10 > 20}\")\n", "print(f\"5 == 5: {5 == 5}\")\n", "```\n", "\n", "**Code Output**\n", "```\n", "Active: True, Type: \n", "Completed: False, Type: \n", "10 > 20: False\n", "5 == 5: True\n", "```\n", "\n", "**Conversion with `bool()`**\n", "\n", "The `bool()` function converts other data types to boolean:\n", "\n", "```python\n", "print(bool(0), bool(''), bool([])) # empty\n", "print(bool(42), bool('text'), bool([1, 2, 3])) # filled\n", "```\n", "\n", "**Code Output**\n", "```\n", "False False False\n", "True True True\n", "```\n", "\n", "```{admonition} General Conversion Rule\n", ":class: tip\n", "In general, \"empty\" values like `0`, `\"\"`, `[]`, `{}` are converted to `False`, while \"filled\" values are converted to `True`.\n", "```" ] }, { "cell_type": "markdown", "metadata": { "id": "t04u6LqcatGa" }, "source": [ "### Strings \n", "The **string** data type, represented by `str` in Python, is used to store sequences of characters as text. \n", "\n", "**Usage Examples:** \n", "\n", "```python \n", "# Declaration and initialization of a string variable \n", "z = \"Hello, class!\" \n", "print(f\"The value of z is: {z}, and its type is: {type(z)}\") \n", "\n", "# Assigning a new value \n", "z = \"123\" \n", "print(f\"The new value of z is: {z}, and its type remains: {type(z)}\") \n", "\n", "# String concatenation \n", "result = z + \", how are you?\" \n", "print(f\"The result of concatenation is: {result}, and its type is: {type(result)}\") \n", "``` \n", "\n", "**Code Output**\n", "``` \n", "The value of z is: Hello, class!, and its type is: \n", "The new value of z is: 123, and its type remains: \n", "The result of concatenation is: 123, how are you?, and its type is: \n", "``` \n", "\n", "**Using Quotes in Strings** \n", "Python allows using both single (`'`) and double (`\"`) quotes to define strings: \n", "\n", "```python \n", "# String with single quotes \n", "text1 = 'Text with single quotes.' \n", "print(f\"Example 1: {text1}\") \n", "\n", "# String with double quotes \n", "text2 = \"Text with double quotes.\" \n", "print(f\"Example 2: {text2}\") \n", "\n", "# String containing different quotes \n", "text3 = \"Contains 'single quotes' inside.\" \n", "text4 = 'Contains \"double quotes\" inside.' \n", "print(f\"Example 3: {text3}\") \n", "print(f\"Example 4: {text4}\")\n", "``` \n", "\n", "**Code Output**\n", "``` \n", "Example 1: Text with single quotes.\n", "Example 2: Text with double quotes.\n", "Example 3: Contains 'single quotes' inside.\n", "Example 4: Contains \"double quotes\" inside.\n", "``` \n", "\n", "**Multiline Strings**\n", "\n", "To create strings that span multiple lines, we use triple quotes (`\"\"\"` or `'''`):\n", "\n", "```python\n", "message = \"\"\"This is a text\n", "that spans multiple lines.\n", "Very useful for long texts.\"\"\"\n", "\n", "print(message)\n", "```\n", "\n", "**Code Output**\n", "```\n", "This is a text\n", "that spans multiple lines.\n", "Very useful for long texts.\n", "```\n", "\n", "**Escape Characters**\n", "\n", "Escape characters allow inserting special characters in strings:\n", "\n", "| Sequence | Description | Example |\n", "|-----------|-----------|---------|\n", "| `\\n` | New line | `\"Line1\\nLine2\"` |\n", "| `\\t` | Tab | `\"Col1\\tCol2\"` |\n", "| `\\\\` | Backslash | `\"C:\\\\folder\"` |\n", "| `\\'` | Single quote | `'It\\'s ok'` |\n", "| `\\\"` | Double quote | `\"He said \\\"Hello\\\"\"` |\n", "\n", "```python\n", "# Examples of escape characters\n", "print(\"First line\\nSecond line\")\n", "print(\"Name:\\tJohn\")\n", "print(\"Path: C:\\\\Users\\\\folder\")\n", "print(\"He said: \\\"Python is amazing!\\\"\")\n", "```\n", "\n", "**Code Output**\n", "```\n", "First line\n", "Second line\n", "Name:\tJohn\n", "Path: C:\\Users\\folder\n", "He said: \"Python is amazing!\"\n", "```\n", "\n", "```{admonition} Tip - Raw Strings\n", ":class: tip\n", "To avoid processing escape characters, use \"raw\" strings by adding `r` before the quotes: `r\"C:\\Users\\folder\"`.\n", "```" ] }, { "cell_type": "markdown", "metadata": { "id": "t04u6LqcatGa" }, "source": [ "**Using `len` to Calculate String Length**\n", "\n", "The `len` is a built-in function [Built-in Functions](https://docs.python.org/3/library/functions.html) in Python that returns the length (number of characters) of a sequence, such as a string. Let's calculate the size of the string `\"Hello, class!\"` using `len`:\n", "\n", "```python\n", "text = \"Hello, class!\"\n", "size = len(text)\n", "print(\"The string length is:\", size)\n", "```\n", "**Code Output**\n", "```\n", "The string length is: 13\n", "```\n", "\n", "**How Indices Work in a String**\n", "\n", "In Python, string indices start at `0` and go up to `(string length - 1)`. This means the first character is at index `0`, the second at index `1`, and so on. We can print specific characters and parts of the string using these indices:\n", "\n", "```python\n", "text = \"Hello, class!\"\n", "\n", "# Printing characters using indices\n", "print(\"First character:\", text[0])\n", "print(\"Second character:\", text[1])\n", "\n", "# Printing the last character using index -1\n", "print(\"Last character:\", text[-1])\n", "\n", "# Printing part of the string using indices\n", "print(\"Part of the string:\", text[7:12])\n", "\n", "# Reverses the string (step -1 traverses backwards)\n", "print(\"Reversed string:\", text[::-1])\n", "```\n", "**Code Output**\n", "```\n", "First character: H\n", "Second character: e\n", "Last character: !\n", "Part of the string: class\n", "Reversed string: !ssalc ,olleH\n", "```\n", "\n", "> In the example above, `text[7:12]` prints the part of the string from index `7` to index `11` (index `12` is not included).\n", "\n", "**String Manipulation**\n", "Later in this material, we will conduct an in-depth study on string manipulation. We will explore a series of methods and operations that are essential for text processing. For example:\n", "\n", "**Using `.upper()` and `.lower()`**\n", "- **`.upper()`**: This method is used to convert all characters in a string to **uppercase**. It's useful when we want to standardize data input or highlight a message.\n", "\n", "```python\n", "text = \"Hello, World!\"\n", "print(text.upper())\n", "```\n", "**Code Output**\n", "```\n", "HELLO, WORLD!\n", "```\n", "\n", "- **`.lower()`**: In contrast, `.lower()` transforms all characters in a string to **lowercase**. This is particularly useful for string comparisons, where capitalization can be ignored.\n", "\n", "```python\n", "text = \"Hello, World!\"\n", "print(text.lower())\n", "```\n", "**Code Output**\n", "```\n", "hello, world!\n", "```\n", "\n", "These methods are just the beginning of what we can do with string manipulation in Python. As we progress, we'll discover more techniques and functions that allow us to manipulate and analyze strings in various situations.\n", "\n", "> In addition to the primitive types presented (`int`, `float`, `bool` and `str`), Python also provides the **`complex`** type, intended for representing complex numbers, although it is less commonly used in everyday applications. To learn more about this type (and other primitive types), see the section [*Numeric Types — int, float, complex*](https://docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex) in the official Python documentation.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Characteristics of Dynamic Typing\n", "\n", "As previously discussed, Python stands out as a dynamically typed programming language, which means that the type of a variable is determined during program execution, not during compilation. Unlike statically typed languages, such as C++ or Java, where a variable's type must be explicitly declared before use, Python allows assigning values to variables without the need to declare the type beforehand.\n", "\n", "It's essential to highlight the flexibility provided by Dynamic Assignment, especially when combined with `None`:\n", "\n", "```python\n", "# Dynamic value assignment\n", "dynamic_variable = 42\n", "print(dynamic_variable)\n", "\n", "dynamic_variable = \"Hello, world!\"\n", "print(dynamic_variable)\n", "\n", "# Declaring variables as None\n", "null_variable = None\n", "print(null_variable)\n", "\n", "# Assigning a value later\n", "null_variable = 100\n", "print(null_variable)\n", "```\n", "**Code Output**\n", "```\n", "42\n", "Hello, world!\n", "None\n", "100\n", "```\n", "\n", "In the example above, the variable `dynamic_variable` is initially assigned the integer 42 and later the string \"Hello, world!\". This illustrates the flexibility and dynamic typing in Python. Additionally, the variable `null_variable` is initialized with `None`, indicating the absence of a value, and later is assigned the integer value 100.\n", "\n", "**Checking Types with `isinstance()`**\n", "\n", "In some situations, it's necessary to check a variable's type at runtime. The `isinstance()` function allows doing this check safely:\n", "\n", "```python\n", "value = 42\n", "\n", "# Simple check\n", "print(f\"Is int? {isinstance(value, int)}\")\n", "print(f\"Is str? {isinstance(value, str)}\")\n", "\n", "# Check with multiple types\n", "print(f\"Is int or float? {isinstance(value, (int, float))}\")\n", "```\n", "**Code Output**\n", "```\n", "Is int? True\n", "Is str? False\n", "Is int or float? True\n", "```\n", "\n", "```{admonition} Good Practice\n", ":class: tip\n", "Prefer `isinstance()` instead of `type(value) == int`, as `isinstance()` also considers class inheritance.\n", "```\n", "\n", "**Removing Variables with `del`**\n", "\n", "Another important feature to mention is the `del` statement, which allows removing an existing variable.\n", "\n", "```python\n", "# Assigning a value to null_variable\n", "null_variable = 100\n", "\n", "# Removing a variable with the 'del' command\n", "del null_variable\n", "# Trying to print the variable after deleting it will result in an error\n", "print(null_variable)\n", "```\n", "**Code Output**\n", "```\n", "Traceback (most recent call last):\n", " File \"\", line 5, in \n", " print(null_variable)\n", "NameError: name 'null_variable' is not defined\n", "```\n", "\n", "In the example above, the `del` command is used to remove the `null_variable` variable. Trying to print this variable after deleting it will result in a `NameError`, indicating that the variable is no longer defined. Using `del` is useful for freeing resources and managing the program structure more efficiently." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Type Conversion (Casting) and Numeric Bases\n", "\n", "Refers to converting one data type to another. This may be necessary when you want to operate on or compare values of different types. A common example is converting a string to a number, such as when using `float(input())` to convert user input to a floating-point number.\n", "\n", "### Conversion Functions\n", "\n", "Python offers built-in functions to convert between basic types:\n", "\n", "| Function | Description | Example | Result |\n", "|--------|-----------|---------|-----------|\n", "| `int()` | Converts to integer | `int(\"42\")` | `42` |\n", "| `float()` | Converts to floating-point | `float(\"3.14\")` | `3.14` |\n", "| `str()` | Converts to string | `str(100)` | `\"100\"` |\n", "| `bool()` | Converts to boolean | `bool(1)` | `True` |\n", "\n", "**Conversion between int and float**\n", "\n", "```python\n", "# Float to int (truncates the decimal part, doesn't round)\n", "float_number = 3.7\n", "int_number = int(float_number)\n", "print(f\"int(3.7) = {int_number}\")\n", "\n", "float_number2 = 3.2\n", "print(f\"int(3.2) = {int(float_number2)}\")\n", "\n", "# Int to float\n", "int_number = 5\n", "float_number = float(int_number)\n", "print(f\"float(5) = {float_number}\")\n", "```\n", "**Code Output**\n", "```\n", "int(3.7) = 3\n", "int(3.2) = 3\n", "float(5) = 5.0\n", "```\n", "\n", "```{admonition} Attention - Truncation vs Rounding\n", ":class: warning\n", "`int()` **truncates** the value (removes the decimal part), it doesn't round. To round, use `round()`.\n", "```\n", "\n", "**Conversion to String**\n", "\n", "```python\n", "age = 25\n", "height = 1.75\n", "active = True\n", "\n", "# Converting to string\n", "print(\"Age: \" + str(age))\n", "print(f\"Type of str(height): {type(str(height))}\")\n", "print(f\"str(active) = '{str(active)}'\")\n", "```\n", "**Code Output**\n", "```\n", "Age: 25\n", "Type of str(height): \n", "str(active) = 'True'\n", "```\n", "\n", "**Converting String to Integer**\n", "\n", "```python\n", "# Asks the user to enter an integer number\n", "user_input = input(\"Enter an integer number: \")\n", "\n", "# Converts the input to an integer number\n", "integer_number = int(user_input)\n", "\n", "# Prints the result\n", "print(\"Integer number entered:\", integer_number)\n", "```\n", "**Code Output**\n", "```\n", "Enter an integer number: 15\n", "Integer number entered: 15\n", "```\n", "\n", "**Converting String to Floating-Point**\n", "\n", "```python\n", "# Asks the user to enter a floating-point number\n", "user_input = input(\"Enter a floating-point number: \")\n", "\n", "# Converts the input to a floating-point number\n", "float_number = float(user_input)\n", "\n", "# Prints the result\n", "print(\"Floating-point number entered:\", float_number)\n", "```\n", "**Code Output**\n", "```\n", "Enter a floating-point number: 3.14\n", "Floating-point number entered: 3.14\n", "```\n", "\n", "### Conversion between Numeric Bases\n", "\n", "Python offers native support for conversion between different numeric bases. The representations include prefixes that indicate the base:\n", "- `0b` for binary (base 2)\n", "- `0o` for octal (base 8)\n", "- `0x` for hexadecimal (base 16)\n", "\n", "**Decimal to Binary:**\n", "```python\n", "decimal_number = 10\n", "binary_number = bin(decimal_number) # Returns string with prefix 0b\n", "print(binary_number) # 0b1010 (where 0b indicates binary format)\n", "```\n", "**Code Output**\n", "```\n", "0b1010\n", "```\n", "\n", "**Binary to Decimal:**\n", "```python\n", "binary_number = 0b1010 # Prefix 0b allows writing binary literal\n", "decimal_number = int(binary_number) # Converts to decimal integer\n", "print(decimal_number)\n", "```\n", "**Code Output**\n", "```\n", "10\n", "```\n", "\n", "An illustration below to help understand the math involved.\n", "\n", "```{image} conversao-bases-light.png\n", ":alt: Two panels. In the first, the successive division of 10 by 2 in four lines, with the column of remainders 0, 1, 0, 1 and an arrow showing that it is read from the bottom up, forming 1010. In the second, the bits 1, 0, 1, 0 with the powers of 2 under each one and the sum 8 plus 0 plus 2 plus 0 equal to 10\n", ":class: only-light\n", "```\n", "\n", "```{image} conversao-bases-dark.png\n", ":alt: Two panels. In the first, the successive division of 10 by 2 in four lines, with the column of remainders 0, 1, 0, 1 and an arrow showing that it is read from the bottom up, forming 1010. In the second, the bits 1, 0, 1, 0 with the powers of 2 under each one and the sum 8 plus 0 plus 2 plus 0 equal to 10\n", ":class: only-dark\n", "```\n", "\n", "\n", "\n", "**Decimal to Hexadecimal:**\n", "```python\n", "decimal_number = 255\n", "hexadecimal_number = hex(decimal_number) # Returns string with prefix 0x\n", "print(hexadecimal_number) # 0xff (where 0x indicates hexadecimal format)\n", "```\n", "**Code Output**\n", "```\n", "0xff\n", "```\n", "\n", "**Hexadecimal to Decimal:**\n", "```python\n", "hexadecimal_number = 0xff # Prefix 0x allows writing hexadecimal literal\n", "decimal_number = int(hexadecimal_number) # Converts to decimal integer\n", "print(decimal_number)\n", "```\n", "**Code Output**\n", "```\n", "255\n", "```\n", "\n", "**Visualizing Memory Addresses in Hexadecimal:**\n", "\n", "In Python, we can visualize the memory address where a variable is stored using the `id()` function combined with `hex()`. This is useful for understanding how Python manages objects in memory:\n", "\n", "```python\n", "a = 123\n", "b = 125\n", "\n", "# Visualizing memory addresses in hexadecimal\n", "print(f\"Address of 'a': {hex(id(a))}\")\n", "print(f\"Address of 'b': {hex(id(b))}\")\n", "```\n", "**Code Output**\n", "```\n", "Address of 'a': 0x7f8b3c0a1e70\n", "Address of 'b': 0x7f8b3c0a1eb0\n", "```\n", "\n", "```{image} enderecos-memoria-light.png\n", ":alt: Two panels. In the first, memory drawn as a row of numbered positions, with the value 123 in one of them and 125 another 64 positions further on, the names a and b pointing at each one and the address written under each position. In the second, the same address written in base 10 and in base 16\n", ":class: only-light\n", "```\n", "\n", "```{image} enderecos-memoria-dark.png\n", ":alt: Two panels. In the first, memory drawn as a row of numbered positions, with the value 123 in one of them and 125 another 64 positions further on, the names a and b pointing at each one and the address written under each position. In the second, the same address written in base 10 and in base 16\n", ":class: only-dark\n", "```\n", "\n", "```{admonition} Note on Memory Addresses\n", ":class: note\n", "Memory addresses vary with each program execution and depend on the operating system and Python implementation.\n", "```\n", "\n", "**Important notes:**\n", "- The functions `bin()`, `oct()` and `hex()` return strings with respective prefixes\n", "- You can use prefixes directly in code to represent literals in these bases\n", "- The `int()` function can convert strings from these formats to decimal when used with the base parameter:\n", " ```python\n", "int('1010', 2) # Binary → 10\n", "int('0xff', 16) # Hexadecimal → 255\n", " ```\n", "\n", "### Where these conversions show up in everyday life\n", "\n", "Conversions between bases appear in things you already use. The four below are explained entirely by what this section has shown.\n", "\n", "**The colour of a website.** The blue of the Python logo is `#3776AB`. It is not an arbitrary code: it is three hexadecimal numbers stuck together, one for each colour the screen mixes. The `37` says how much red, the `76` how much green and the `AB` how much blue. Each one runs from `00` to `FF`, that is, from 0 to 255.\n", "\n", "```python\n", "print(int(\"37\", 16), int(\"76\", 16), int(\"AB\", 16))\n", "```\n", "**Code Output**\n", "```\n", "55 118 171\n", "```\n", "\n", "**The number of an emoji.** Every character has a number, and Unicode tables write that number in hexadecimal, with the prefix `U+`. The snake emoji is `U+1F40D`.\n", "\n", "```python\n", "print(int(\"1F40D\", 16))\n", "```\n", "**Code Output**\n", "```\n", "128013\n", "```\n", "\n", "**The permissions of a file on Linux.** The `chmod 755` command uses octal. Each digit is worth three bits, and each bit turns on one permission: read, write and execute. The `7` turns on all three, and the `5` turns on the first and the third.\n", "\n", "```python\n", "print(bin(7), bin(5))\n", "```\n", "**Code Output**\n", "```\n", "0b111 0b101\n", "```\n", "\n", "**The size of a file.** A kilobyte is 1024 bytes, not 1000. The reason becomes visible in base 2: 1024 is 2 raised to 10, which in binary is a `1` followed by ten zeros.\n", "\n", "```python\n", "print(2 ** 10)\n", "print(bin(1024))\n", "```\n", "**Code Output**\n", "```\n", "1024\n", "0b10000000000\n", "```\n", "\n", "The same conversions support subjects you will meet later on, such as network addresses, microcontroller registers and hash functions. In all of them what you have just seen holds: the number is the same, what changes is the base it is written in." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Composite Data Types (Collections)\n", "\n", "Python comes with four built-in collections: **lists**, **tuples**, **dictionaries** and **sets**. All of them hold several values, and what tells them apart is whether the order matters, whether the content can change, and whether access is by position or by key.\n", "\n", "### Lists\n", "\n", "[Lists](https://docs.python.org/3/tutorial/datastructures.html#more-on-lists) are **mutable, ordered, and heterogeneous** data structures that allow storing collections of items. They are represented by square brackets `[]` and items separated by commas.\n", "\n", "**Main Characteristics:**\n", "- **Mutable**: Can be changed after creation \n", "- **Ordered**: Maintain insertion order \n", "- **Heterogeneous**: Accept different data types \n", "- **Dynamic**: Grow or shrink as needed \n", "\n", "```python\n", "# Basic example\n", "list = [1, \"Python\", 3.14, True]\n", "```\n", "\n", "
\n", "\n", "#### Basic Operations with Lists\n", "\n", "**Creating Lists**\n", "```python\n", "empty_list = [] # Literal syntax\n", "empty_list = list() # Using constructor\n", "numbers = [1, 2, 3] # List of integers\n", "```\n", "\n", "
\n", "\n", "**Accessing Elements**\n", "```python\n", "languages = [\"Python\", \"Java\", \"C++\"]\n", "\n", "print(languages[0]) # First element\n", "print(languages[-1]) # Last element\n", "```\n", "**Code Output:**\n", "```\n", "Python\n", "C++\n", "```\n", "\n", "**Slicing**\n", "\n", "Slicing allows extracting parts of a list using the syntax `list[start:end:step]`:\n", "\n", "```python\n", "numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n", "\n", "# Elements from index 2 to 5 (doesn't include 5)\n", "print(numbers[2:5])\n", "\n", "# From beginning to index 4\n", "print(numbers[:4])\n", "\n", "# From index 6 to the end\n", "print(numbers[6:])\n", "\n", "# Elements every 2\n", "print(numbers[::2])\n", "\n", "# Reversed list\n", "print(numbers[::-1])\n", "```\n", "**Code Output:**\n", "```\n", "[2, 3, 4]\n", "[0, 1, 2, 3]\n", "[6, 7, 8, 9]\n", "[0, 2, 4, 6, 8]\n", "[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]\n", "```\n", "\n", "| Syntax | Description | Example | Result |\n", "|---------|-----------|---------|-----------|\n", "| `list[i:j]` | Elements from index `i` to `j-1` | `[0,1,2,3,4][1:4]` | `[1, 2, 3]` |\n", "| `list[:j]` | From beginning to `j-1` | `[0,1,2,3,4][:3]` | `[0, 1, 2]` |\n", "| `list[i:]` | From `i` to the end | `[0,1,2,3,4][2:]` | `[2, 3, 4]` |\n", "| `list[::p]` | All, skipping by `p` | `[0,1,2,3,4][::2]` | `[0, 2, 4]` |\n", "| `list[::-1]` | Reversed list | `[0,1,2,3,4][::-1]` | `[4, 3, 2, 1, 0]` |\n", "\n", "**Modifying Lists**\n", "```python\n", "languages = [\"Python\", \"Java\", \"C++\"]\n", "languages[1] = \"JavaScript\"\n", "print(languages)\n", "```\n", "**Code Output:**\n", "```\n", "['Python', 'JavaScript', 'C++']\n", "```\n", "\n", "**Modifying with Slicing**\n", "```python\n", "numbers = [0, 1, 2, 3, 4, 5]\n", "numbers[1:4] = [10, 20, 30] # Replaces elements from index 1 to 3\n", "print(numbers)\n", "```\n", "**Code Output:**\n", "```\n", "[0, 10, 20, 30, 4, 5]\n", "```\n", "\n", "#### Main List Methods\n", "\n", "| Method | Description | Example | Output |\n", "|------------------|----------------------------------------|-------------------------------------|------------------------------|\n", "| `append(x)` | Adds `x` to the end | `[1, 2].append(3)` | `[1, 2, 3]` |\n", "| `extend(iter)` | Adds items from another iterable | `[1, 2].extend([3, 4])` | `[1, 2, 3, 4]` |\n", "| `insert(i, x)` | Inserts `x` at position `i` | `['a', 'c'].insert(1, 'b')` | `['a', 'b', 'c']` |\n", "| `remove(x)` | Removes first occurrence of `x` | `[1, 2, 2, 3].remove(2)` | `[1, 2, 3]` |\n", "| `pop([i])` | Removes and returns item at index `i` | `[1, 2, 3].pop(1)` | Returns `2`, list: `[1, 3]` |\n", "| `clear()` | Removes all items | `[1, 2, 3].clear()` | `[]` |\n", "| `index(x)` | Returns index of first occurrence | `['a', 'b', 'c'].index('b')` | `1` |\n", "| `count(x)` | Counts occurrences of `x` | `[1, 2, 2, 3].count(2)` | `2` |\n", "| `sort()` | Sorts the list (in-place) | `[3, 1, 2].sort()` | `[1, 2, 3]` |\n", "| `reverse()` | Reverses the order (in-place) | `[1, 2, 3].reverse()` | `[3, 2, 1]` |\n", "| `copy()` | Returns shallow copy | `[1, 2].copy()` | `[1, 2]` |\n", "\n", "#### List Combination\n", "\n", "**Using `+` (creates new list)**\n", "```python\n", "list1 = [1, 2]\n", "list2 = [3, 4]\n", "combined = list1 + list2\n", "print(combined)\n", "```\n", "**Code Output:**\n", "```\n", "[1, 2, 3, 4]\n", "```\n", "\n", "**Using `+=` (modifies the first list)**\n", "```python\n", "list1 = [1, 2]\n", "list2 = [3, 4]\n", "list1 += list2\n", "print(list1)\n", "```\n", "**Code Output:**\n", "```\n", "[1, 2, 3, 4]\n", "```\n", "\n", "**Using `extend()`**\n", "```python\n", "list1 = ['a', 'b']\n", "list2 = ['c', 'd']\n", "list1.extend(list2)\n", "print(list1)\n", "```\n", "**Code Output:**\n", "```\n", "['a', 'b', 'c', 'd']\n", "```\n", "\n", "#### Integrated Practical Example\n", "\n", "```python\n", "# Creating shopping list\n", "shopping = [\"Apple\", \"Milk\"]\n", "shopping.append(\"Bread\")\n", "shopping.extend([\"Eggs\", \"Cheese\"])\n", "shopping.insert(1, \"Banana\")\n", "\n", "# Concatenating with another list\n", "beverages = [\"Juice\", \"Water\"]\n", "final_list = shopping + beverages\n", "\n", "print(\"Complete shopping list:\", final_list)\n", "```\n", "**Code Output:**\n", "```\n", "Complete shopping list: ['Apple', 'Banana', 'Milk', 'Bread', 'Eggs', 'Cheese', 'Juice', 'Water']\n", "```\n", "\n", "#### Best Practices\n", "\n", "- Prefer `append()`/`extend()` instead of `+` for large lists (better performance) \n", "- Use `list.copy()` or `list(list)` to avoid unwanted modifications \n", "- Use `list.clear()` to empty lists in a readable way \n", "- Check element existence with `x in list` (returns `True` or `False`)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Tuples\n", "\n", "[Tuples](https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences) are fundamental data structures in Python, characterized by being **immutable, ordered, and heterogeneous**. Their syntax uses parentheses `()` with elements separated by commas – the comma, not the parentheses, being the defining element of the tuple.\n", "\n", "**Essential Characteristics:**\n", "- **Immutability**: Once created, cannot be changed.\n", "- **Order preservation**: Maintains insertion sequence.\n", "- **Type flexibility**: Accepts different data types in the same structure.\n", "- **Efficiency**: Consumes fewer resources than lists for constant data.\n", "\n", "```python\n", "# Basic demonstration\n", "language = (\"Python\", 1991, \"Guido van Rossum\", True)\n", "```\n", "\n", "
\n", "\n", "#### Fundamental Operations\n", "\n", "**Creating Tuples**\n", "```python\n", "empty = () # Empty tuple\n", "empty = tuple() # Empty tuple\n", "single = (42,) # Tuple with single element (comma required)\n", "coordinates = (23.5, -46.6) # Tuple of floats\n", "record = (\"ID123\", \"John\", 28) # Heterogeneous tuple\n", "\n", "# Conversion from other iterables\n", "from_list = tuple([1, 2, 3])\n", "from_string = tuple(\"Python\")\n", "```\n", "\n", "
\n", "\n", "**Code Output:**\n", "```\n", "('P', 'y', 't', 'h', 'o', 'n')\n", "```\n", "\n", "\n", "**Accessing Elements**\n", "```python\n", "data = (\"Python\", 3.11, \"Open Source\")\n", "\n", "print(data[0]) # Access by positive index\n", "print(data[-1]) # Access by negative index\n", "```\n", "**Code Output:**\n", "```\n", "Python\n", "Open Source\n", "```\n", "\n", "\n", "**Modification Attempt** \n", "\n", "\n", "```python\n", "tuple = (1, 2, 3)\n", "try:\n", " tuple[1] = 99 # Modification attempt\n", "except TypeError as e:\n", " print(f\"Error: {e}\")\n", "```\n", "**Code Output:**\n", "```\n", "Error: 'tuple' object does not support item assignment\n", "```\n", "> See more details on how to use `try` `except` in {doc}`Chapter 8 <../ch8/ch8>`.\n", "\n", "\n", "#### Native Methods\n", "\n", "| Method | Description | Example | Result |\n", "|--------------|----------------------------------------|----------------------------------|-----------|\n", "| `count()` | Counts occurrences of a value | `(1,2,2,3).count(2)` | `2` |\n", "| `index()` | Position of first occurrence | `('a','b','c').index('b')` | `1` |\n", "\n", "\n", "#### Tuple Combination\n", "\n", "**Concatenation (`+`)**\n", "```python\n", "t1 = (1, 2)\n", "t2 = (3, 4)\n", "combined = t1 + t2\n", "print(combined)\n", "```\n", "**Code Output:**\n", "```\n", "(1, 2, 3, 4)\n", "```\n", "\n", "**Repetition (`*`)**\n", "```python\n", "greeting = (\"Hello\",) * 3\n", "print(greeting)\n", "```\n", "**Output:**\n", "```\n", "('Hello', 'Hello', 'Hello')\n", "```\n", "\n", "**Modern Unpacking**\n", "```python\n", "base_colors = (\"red\", \"blue\")\n", "extra_colors = (\"green\", \"yellow\")\n", "palette = (*base_colors, \"purple\", *extra_colors)\n", "print(palette)\n", "```\n", "**Output:**\n", "```\n", "('red', 'blue', 'purple', 'green', 'yellow')\n", "```\n", "> Note: The `*` works on any type of sequence (lists, tuples, strings, etc.), \"spreading\" the elements in the new context.\n", "\n", "#### Practical Applications\n", "\n", "**Coordinate Systems**\n", "```python\n", "point_a = (-23.55, -46.63) # São Paulo\n", "point_b = (-22.91, -43.17) # Rio de Janeiro\n", "print(f\"Route: {point_a} -> {point_b}\")\n", "```\n", "**Code Output:**\n", "```\n", "Route: (-23.55, -46.63) -> (-22.91, -43.17)\n", "```\n", "\n", "**Composite Keys in Dictionaries (we'll study next)**\n", "```python\n", "inventory = {\n", " (\"t-shirt\", \"M\"): 42,\n", " (\"pants\", \"40\"): 15\n", "}\n", "print(inventory[(\"t-shirt\", \"M\")])\n", "```\n", "**Code Output:**\n", "```\n", "42\n", "```\n", "\n", "**Alternative Syntax**\n", "```python\n", "# Tuple without parentheses (packing)\n", "values = 10, 20, 30\n", "print(type(values))\n", "\n", "# Unpacking\n", "x, y, z = values\n", "print(f\"x={x}, y={y}, z={z}\")\n", "```\n", "**Code Output:**\n", "```\n", "\n", "x=10, y=20, z=30\n", "```\n", "\n", "\n", "#### Practical example with function\n", "For when you've studied Chapter 5.\n", "\n", "```python\n", "# Geolocation system\n", "def calculate_distance(p1, p2):\n", " from math import sqrt\n", " return sqrt((p2[0]-p1[0])**2 + (p2[1]-p1[1])**2)\n", "\n", "sp = (-23.55, -46.63)\n", "rj = (-22.91, -43.17)\n", "\n", "distance_km = calculate_distance(sp, rj) * 111\n", "print(f\"SP-RJ Distance: {distance_km:.1f} km\")\n", "```\n", "**Code Output:**\n", "```\n", "SP-RJ Distance: 358.1 km\n", "```\n", "\n", "#### Best Practices\n", "\n", "- **Constant data**: Use tuples for immutable information.\n", "- **Composite keys**: Ideal for dictionaries with multiple indices.\n", "- **Multiple return**: Efficient pattern for functions.\n", "- **Data security**: Protection against accidental modifications.\n", "- **Performance**: Prefer for large static collections." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Dictionaries\n", "\n", "[Dictionaries](https://docs.python.org/3/tutorial/datastructures.html#dictionaries) are **mutable** data structures that store information as **key-value** pairs, offering fast data access through **unique keys**. They are represented by curly braces `{}` and each element consists of a key and its corresponding value, separated by colons.\n", "\n", "**Main characteristics:**\n", "- Efficient access to values through unique keys\n", "- Do not allow duplicate keys\n", "- Can be modified after creation\n", "- Accept various data types as values\n", "- Optimized for basic operations in constant time\n", "\n", "```python\n", "# Basic dictionary example\n", "person = {\n", " \"name\": \"Maria\",\n", " \"age\": 28,\n", " \"profession\": \"Engineer\",\n", " \"skills\": [\"Python\", \"CAD\", \"Management\"]\n", "}\n", "```\n", "\n", "
\n", "\n", "#### Basic operations with dictionaries\n", "\n", "**Creation:**\n", "```python\n", "empty = {} # Literal syntax\n", "empty = dict() # Using constructor\n", "\n", "registration = {\n", " \"id\": \"user123\",\n", " \"active\": False,\n", " \"last_access\": \"2023-10-15\"\n", "}\n", "```\n", "\n", "
\n", "\n", "**Access and modification:**\n", "```python\n", "person = {\n", " \"name\": \"Maria\",\n", " \"age\": 28,\n", " \"profession\": \"Engineer\",\n", " \"skills\": [\"Python\", \"CAD\", \"Management\"]\n", "}\n", "\n", "# Direct access\n", "print(person[\"name\"]) \n", "\n", "# Safe access with get()\n", "print(person.get(\"salary\", \"Not informed\")) \n", "# Returns default value if key doesn't exist\n", "\n", "# Adding or updating values\n", "person[\"salary\"] = 7500.00 # Ideal for changing or creating a single key\n", "person.update({\"company\": \"Tech Solutions\", \"department\": \"IT\"}) \n", "# Useful (and necessary) when we want to change or add several keys at once\n", "\n", "print(person)\n", "```\n", "\n", "**Code Output:**\n", "```\n", "Maria\n", "Not informed\n", "{'name': 'Maria', 'age': 28, 'profession': 'Engineer', 'skills': ['Python', 'CAD', 'Management'], 'salary': 7500.0, 'company': 'Tech Solutions', 'department': 'IT'}\n", "```\n", "\n", "**Removing items:**\n", "```python\n", "person = {\n", " \"name\": \"Maria\",\n", " \"age\": 28,\n", " \"profession\": \"Engineer\",\n", " \"skills\": [\"Python\", \"CAD\", \"Management\"],\n", " \"salary\": 7500.00,\n", " \"company\": \"Tech Solutions\",\n", " \"department\": \"IT\"\n", "}\n", "\n", "del person[\"skills\"] # Removes specified key\n", "age = person.pop(\"age\") # Removes and returns the value\n", "print(age)\n", "last = person.popitem() # Removes and returns the last item inserted\n", "print(last)\n", "print(person)\n", "```\n", "\n", "**Code Output:**\n", "```\n", "28\n", "('department', 'IT')\n", "{'name': 'Maria', 'profession': 'Engineer', 'salary': 7500.0, 'company': 'Tech Solutions'}\n", "```\n", "\n", "#### Useful methods\n", "\n", "| Method | Description | Example | Typical output |\n", "|-----------------|------------------------------------------|----------------------------------|----------------------------------------|\n", "| keys() | Returns all keys | person.keys() | dict_keys(['name', 'profession', ...]) |\n", "| values() | Returns all values | person.values() | dict_values(['Maria', 'Engineer', ...]) |\n", "| items() | Returns (key, value) pairs as tuples | person.items() | dict_items([('name', 'Maria'), ...]) |\n", "| get(key, def) | Returns value or default if key absent | person.get(\"age\", 30) | 30 |\n", "| update() | Updates with pairs from another dictionary | person.update({\"age\": 29}) | {'name': 'Maria', 'age': 29, ...} |\n", "| clear() | Removes all items | person.clear() | {} |\n", "\n", "#### Practical examples\n", "\n", "**Simple dictionary:**\n", "```python\n", "student = {\n", " \"name\": \"John Silva\",\n", " \"id\": \"2023001\",\n", " \"course\": \"C&T\"\n", "}\n", "print(student)\n", "```\n", "\n", "**Code Output:**\n", "```\n", "{'name': 'John Silva', 'id': '2023001', 'course': 'Computer Science'}\n", "```\n", "\n", "**Access and modification:**\n", "```python\n", "student = {\n", " \"name\": \"John Silva\",\n", " \"id\": \"2023001\",\n", " \"course\": \"C&T\"\n", "}\n", "\n", "print(student[\"name\"]) \n", "student[\"course\"] = \"Software Engineering\"\n", "print(student)\n", "```\n", "\n", "**Code Output:**\n", "```\n", "John Silva\n", "{'name': 'John Silva', 'id': '2023001', 'course': 'Software Engineering'}\n", "```\n", "\n", "**Key verification:**\n", "```python\n", "student = {\n", " \"name\": \"John Silva\",\n", " \"id\": \"2023001\",\n", " \"course\": \"C&T\"\n", "}\n", "\n", "has_id = \"id\" in student\n", "print(has_id) \n", "```\n", "\n", "**Code Output:**\n", "```\n", "True\n", "```\n", "\n", "**Dictionary with different types:**\n", "```python\n", "product = {\n", " \"code\": 123,\n", " \"name\": \"Keyboard\",\n", " \"price\": 99.90,\n", " \"available\": True\n", "}\n", "print(product)\n", "```\n", "\n", "**Code Output:**\n", "```\n", "{'code': 123, 'name': 'Keyboard', 'price': 99.9, 'available': True}\n", "```\n", "\n", "**Dictionary with list as value:**\n", "```python\n", "contacts = {\n", " \"John\": [\"john@email.com\", \"(83) 9999-1111\"],\n", " \"Maria\": [\"maria@email.com\", \"(84) 8888-2222\"]\n", "}\n", "print(contacts[\"Maria\"])\n", "```\n", "\n", "**Code Output:**\n", "```\n", "['maria@email.com', '(84) 8888-2222']\n", "```\n", "\n", "#### Best practices\n", "\n", "- Use `key in dictionary` to check key existence \n", "- Prefer `get()` to avoid errors with non-existent keys \n", "- Tuples can be used as keys when necessary \n", "- Dictionaries maintain insertion order (Python 3.7+) \n", "- `clear()` is more efficient than creating new empty dictionary " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sets\n", "\n", "[Sets](https://docs.python.org/3/tutorial/datastructures.html#sets) are data structures that store **unique** elements, without duplicates. They are very useful for mathematical operations like **union, intersection, difference and symmetric difference** between collections.\n", "\n", "\n", "**Main characteristics**\n", "\n", "* Store unique elements (don't allow duplicates)\n", "* Don't maintain specific element order\n", "* Don't support indexing\n", "* Optimized for fast membership verification\n", "* Accept immutable data types as elements\n", "\n", "```python\n", "# Basic set example\n", "vowels = {'a', 'e', 'i', 'o', 'u'}\n", "```\n", "\n", "
\n", "\n", "\n", "#### Basic operations\n", "\n", "**Creation**\n", "\n", "```python\n", "empty = set() # Empty set\n", "numbers = {1, 2, 3} # Set with elements\n", "```\n", "\n", "
\n", "\n", "**Addition and removal**\n", "\n", "```python\n", "numbers = {1, 2, 3}\n", "\n", "numbers.add(4) \n", "numbers.remove(2) \n", "numbers.discard(5) \n", "\n", "print(numbers)\n", "```\n", "\n", "**Code Output:**\n", "\n", "```\n", "{1, 3, 4}\n", "```\n", "\n", "\n", "#### Operations between sets\n", "\n", "**Union**\n", "\n", "```python\n", "A = {1, 2, 3}\n", "B = {3, 4, 5}\n", "print(A | B) # Or A.union(B)\n", "```\n", "\n", "**Code Output:**\n", "\n", "```\n", "{1, 2, 3, 4, 5}\n", "```\n", "\n", "**Intersection**\n", "\n", "```python\n", "A = {1, 2, 3}\n", "B = {3, 4, 5}\n", "print(A & B) # Or A.intersection(B)\n", "```\n", "\n", "**Code Output:**\n", "\n", "```\n", "{3}\n", "```\n", "\n", "**Difference**\n", "\n", "```python\n", "A = {1, 2, 3}\n", "B = {3, 4, 5}\n", "print(A - B) # Elements that are only in the first set\n", "```\n", "\n", "**Code Output:**\n", "\n", "```\n", "{1, 2}\n", "```\n", "\n", "**Symmetric difference**\n", "\n", "```python\n", "A = {1, 2, 3}\n", "B = {3, 4, 5}\n", "print(A ^ B) # Or A.symmetric_difference(B)\n", "```\n", "\n", "**Code Output:**\n", "\n", "```\n", "{1, 2, 4, 5}\n", "```\n", "\n", "\n", "#### Useful methods\n", "\n", "| Method | Description | Example | Output |\n", "|--------|-----------|---------|-------|\n", "| `add()` | Adds an element | `numbers.add(5)` | `{1, 3, 4, 5}` |\n", "| `remove()` | Removes element (raises error if doesn't exist) | `numbers.remove(3)` | `{1, 4, 5}` |\n", "| `discard()` | Removes element (doesn't raise error) | `numbers.discard(2)` | `{1, 4, 5}` |\n", "| `union()` | Returns union with another set | `A.union(B)` | `{1, 2, 3, 4, 5}` |\n", "| `intersection()` | Returns intersection with another set | `A.intersection(B)` | `{3}` |\n", "| `difference()` | Returns difference between sets | `A.difference(B)` | `{1, 2}` |\n", "| `symmetric_difference()` | Returns symmetric difference | `A.symmetric_difference(B)` | `{1, 2, 4, 5}` |\n", "| `clear()` | Removes all elements | `numbers.clear()` | `set()` |\n", "\n", "\n", "#### Operators and equivalent methods\n", "\n", "| Operator | Method | Description | Example | Output |\n", "|----------|--------|-----------|---------|-------|\n", "| `\\|` | `union()` | Union (elements in at least one) | `{1,2} \\| {2,3}` | `{1, 2, 3}` |\n", "| `&` | `intersection()` | Intersection (elements in both) | `{1,2} & {2,3}` | `{2}` |\n", "| `-` | `difference()` | Difference (elements only in the first) | `{1,2,3} - {2,3}` | `{1}` |\n", "| `^` | `symmetric_difference()` | Symmetric difference (in one OR the other) | `{1,2,3} ^ {2,3,4}` | `{1, 4}` |\n", "\n", "```{admonition} Quick Tip - Set Operators\n", ":class: tip\n", "`|` → all, `&` → common, `-` → only in first, `^` → only in one\n", "```\n", "\n", "\n", "#### Practical examples\n", "\n", "**Checking membership**\n", "\n", "```python\n", "vowels = {'a', 'e', 'i', 'o', 'u'}\n", "print('a' in vowels)\n", "```\n", "\n", "**Code Output:**\n", "\n", "```\n", "True\n", "```\n", "\n", "**Removing duplicates from a list**\n", "\n", "```python\n", "list = [1, 2, 2, 3, 3, 3]\n", "unique = set(list)\n", "print(unique)\n", "```\n", "\n", "**Code Output:**\n", "\n", "```\n", "{1, 2, 3}\n", "```\n", "\n", "**Working with sets of strings**\n", "\n", "```python\n", "colors = {'red', 'green', 'blue'}\n", "colors.add('yellow')\n", "print(colors)\n", "```\n", "\n", "**Code Output:**\n", "\n", "```\n", "{'red', 'green', 'blue', 'yellow'}\n", "```\n", "\n", "#### Best practices\n", "\n", "* Use sets to eliminate list duplicates\n", "* Ideal for testing membership efficiently\n", "* Don't use for data that needs order\n", "* Elements must be immutable (numbers, strings, tuples)\n", "* Prefer `discard()` over `remove()` when not sure of existence" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Decision Structures\n", "\n", "[**Decision structures**](https://docs.python.org/3/tutorial/controlflow.html#) control program execution flow, allowing code to make decisions based on specific conditions and execute different actions according to the result of those conditions.\n", "\n", "### `if`\n", "\n", "The `if` structure executes a code block **only** if a condition is evaluated as **true** (`True`). See the example:\n", "\n", "```python\n", "age = 21\n", "\n", "if age >= 18:\n", " print(\"You are of legal age.\")\n", "```\n", "\n", "**Code Output:**\n", "\n", "```\n", "You are of legal age.\n", "```\n", "\n", "In the example above, the message \"You are of legal age.\" will be printed because the condition `age >= 18` is true.\n", "\n", "### `if-else`\n", "\n", "The `if-else` structure allows code to execute one action when the condition is true and another when the condition is false. See the example:\n", "\n", "\n", "```python\n", "age = 15\n", "\n", "if age >= 18:\n", " print(\"You are of legal age.\")\n", "else:\n", " print(\"You are a minor.\")\n", "```\n", "\n", "**Code Output:**\n", "\n", "```\n", "You are a minor.\n", "```\n", "\n", "If the condition `age >= 18` is **false**, the code inside `else` will be executed, printing \"You are a minor.\"\n", "\n", "### `if-elif-else`\n", "\n", "The `if-elif-else` conditional structure is used when we need to check **multiple conditions** sequentially. The `elif` (abbreviation of \"else if\") allows testing intermediate conditions between the initial `if` and the final `else`.\n", "\n", "#### Basic Example\n", "```python\n", "age = 30\n", "\n", "if age < 18:\n", " print(\"You are a minor.\")\n", "elif 18 <= age < 65: # Pythonic way\n", " print(\"You are an adult.\")\n", "else:\n", " print(\"You are a senior.\")\n", "```\n", "\n", "**Code Output:**\n", "```\n", "You are an adult.\n", "```\n", "\n", "#### Syntax Comparison\n", "| Form | Example | Note |\n", "|----------------------|----------------------------------|--------------------------------|\n", "| **Traditional** | `age >= 18 and age < 65` | More explicit |\n", "| **Pythonic** | `18 <= age < 65` | More concise and idiomatic |\n", "\n", "Both forms are valid, but the Pythonic version is preferable because:\n", "- It's more readable\n", "- It resembles mathematical notation\n", "- It reduces variable repetition" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `match case`\n", "\n", "Starting with **Python 3.10**, the `match case` structure was introduced, which allows comparing a value against multiple patterns in a clearer and more organized way.\n", "It works similarly to `switch` from other languages, but with the advantage of supporting **pattern matching**, which makes the feature much more powerful.\n", "\n", "#### Basic Example\n", "\n", "```python\n", "option = 2\n", "\n", "match option:\n", " case 1:\n", " print(\"Option 1 selected\")\n", " case 2:\n", " print(\"Option 2 selected\")\n", " case 3 | 4: # Pattern combination\n", " print(\"Option 3 or 4 selected\")\n", " case _:\n", " print(\"Invalid option\")\n", "```\n", "\n", "**Code Output:**\n", "\n", "```\n", "Option 2 selected\n", "```\n", "\n", "In this example:\n", "\n", "* The value in `option` is compared with each `case`.\n", "* The `|` operator allows combining multiple patterns.\n", "* The **`_` (underscore)** functions as a wildcard (equivalent to `else`), capturing any value not previously handled.\n", "\n", "\n", "#### Example with Data Structure\n", "\n", "`match case` also allows **unpacking values** directly within the comparison. Each `case` describes the expected **shape** of the data, and each position in the pattern does one of two things: it either holds a fixed value, which must match, or a name, which captures whatever is there.\n", "\n", "```python\n", "point = (0, 5)\n", "\n", "match point:\n", " case (0, y):\n", " print(f\"Point on Y axis, coordinate {y}\")\n", " case (x, 0):\n", " print(f\"Point on X axis, coordinate {x}\")\n", " case (x, y):\n", " print(f\"Point at ({x}, {y})\")\n", "```\n", "\n", "**Code Output:**\n", "\n", "```\n", "Point on Y axis, coordinate 5\n", "```\n", "\n", "\n", "\n", "In this example:\n", "\n", "* `case (0, y)` matches any tuple whose first element is `0`. The `0` **compares**; the `y` **captures**, receiving the second element whatever it is. That is where the `5` in the output comes from.\n", "* **Order matters.** `(0, 5)` matches the first `case`, and the following ones are never tested. A point `(0, 0)` would also fall into the first one, printing `Point on Y axis, coordinate 0`.\n", "* `case (x, y)` at the end matches any two-element tuple and plays the wildcard role that `case _` plays in the previous example.\n", "\n", "```{admonition} Attention - A name in case captures, it does not compare\n", ":class: warning dropdown\n", "A bare name inside a `case` never compares: it always creates a variable. Writing `case ORIGIN:` expecting to compare the value against a constant `ORIGIN` defined earlier compares nothing. The pattern matches any value and also overwrites `ORIGIN`. To compare against a stored value, use a dotted name, such as `case Point.ORIGIN:`, or a guard condition, such as `case p if p == ORIGIN:`.\n", "```\n", "\n", "**Summary Table (complete):**\n", "\n", "| Structure | Description | Use |\n", "| ---------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |\n", "| **if** | Executes a block if the condition is true | When there's **a single condition** |\n", "| **if-else** | Executes a block if the condition is true and another if false | When there are **two possibilities** (true/false) |\n", "| **if-elif-else** | Checks multiple conditions sequentially | When there are **more than two conditions** to be handled |\n", "| **match case** | Compares values against multiple patterns (with pattern matching support) | When there are **many alternatives** or when dealing with **data structures** |\n" ] }, { "cell_type": "markdown", "metadata": { "id": "bEQasNr1dpzk", "jp-MarkdownHeadingCollapsed": true }, "source": [ "## Exercises\n", "\n", "1. Write a program that asks the user for two values, one of type integer (`int`) and another of type floating-point (`float`). After receiving these values as input, the program should assign them to two distinct variables and then print on screen the result of the following mathematical operations:\n", "\n", "- Sum of the two values.\n", "- Subtraction of the float value by the integer value.\n", "- Multiplication of the two values.\n", "- Division of the integer value by the float value.\n", "\n", "Make sure to properly format the output of the results. \n", "\n", "
\n", "\n", "2. Write a program that asks the user to enter a word or phrase. Then, the program should print the length of the string, the first letter of the string, the last letter of the string, and the reversed string.\n", "\n", "
\n", "\n", "3. Write a program that compares two strings provided by the user, considering boolean values `\"True\"` or `\"False\"`. The program should ignore capitalization differences (uppercase and lowercase) and print on screen if the strings are **equal** or **different**.\n", "\n", "
\n", "\n", " \n", "4. Create a program that calculates a person's Body Mass Index (BMI). BMI is calculated by dividing a person's weight by their height squared. BMI is a measure of the relationship between weight and height. The program should print the person's BMI, classifying it according to the table below:\n", "\n", "```\n", "BMI | Classification\n", "\n", "< 18.5 | Underweight\n", "18.5 - 24.9 | Healthy\n", "25.0 - 29.9 | Overweight\n", "30.0 - 34.9 | Obesity grade I\n", "35.0 - 39.9 | Obesity grade II\n", ">= 40.0 | Obesity grade III\n", "```\n", "\n", "
\n", "\n", "5. Create a program that asks the user to enter five different fruits. Before reading the data, create an empty list called `fruits`. Then, store the fruits provided by the user in this list and, at the end, print the complete list on screen.\n", "\n", "
\n", "\n", "6. Write a program that asks the user to enter two coordinates (x and y). Then, create a tuple called `coordinates` with these values and print the tuple content on screen.\n", "\n", "
\n", "\n", "7. Create a dictionary called `contact`. Ask the user to provide the data corresponding to the keys `\"name\"`, `\"phone\"` and `\"address\"`. Then, print the complete content of the dictionary.\n", "\n", "
\n", "\n", "8. Create, before reading the numbers, an empty set called `numbers` using the `set()` function. Then, store the values provided by the user in this set, using the `.add()` method. At the end, display the complete set in the output.\n", "\n", "
\n", "\n", "9. Create a program that asks the user to enter three distinct integer numbers for each set. The sets `set_a` and `set_b` should be created using the `set()` function and filled with the numbers provided by the user, using the `.add()` method. Then, perform the following operations and print the results:\n", "\n", "- **Union**: combine the unique elements from both sets. \n", "- **Intersection**: find elements that are present in both sets. \n", "- **Difference**: identify elements that are in `set_a`, but not in `set_b`.\n", "\n", "
\n", "\n", "10. Given two strings provided by the user, perform the following operations and print the results:\n", "- **Transform to uppercase:** convert the entire first string to uppercase letters.\n", "- **Transform to lowercase:** convert the entire second string to lowercase letters.\n", "- **Concatenate the strings:** combine the first and second string into a single string.\n", "- **Print the result:** display the concatenated string on screen.\n", " \n", "\n", "
\n", "\n", "11. You should create a program that checks if numbers in a list are even or odd. The list has size 5 and will be provided by the user. Each number in the list should be evaluated individually, without using loop structures. The program should display on screen if each number is even or odd.\n", "\n", "
\n", "\n", "12. Write a program to collect information about a student. Using a dictionary named \"student\", ask the user for the following information:\n", "\n", "- Student's name.\n", "- Student's ID.\n", "- Three student grades.\n", "\n", "Then, display on screen the registered data, including name, ID, and the average of the three grades. Use only the special methods of dictionaries to insert and access the data.\n", "\n", "
" ] } ], "metadata": { "colab": { "provenance": [], "toc_visible": true }, "kernelspec": { "display_name": "Python 3 (jupyter)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.20" } }, "nbformat": 4, "nbformat_minor": 4 }