[<< Day 1](../readme.md) | [Day 3 >>](../03_Day_Operators/03_operators.md)

- [📘 Day 2](#-day-2)
- [Built in functions](#built-in-functions)
- [Variables](#variables)
- [Declaring Multiple Variable in a Line](#declaring-multiple-variable-in-a-line)
- [Data Types](#data-types)
- [Checking Data types and Casting](#checking-data-types-and-casting)
- [Numbers](#numbers)
- [💻 Exercises - Day 2](#-exercises---day-2)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
# 📘 Day 2
## Built in functions
In Python we have lots of built-in functions. Built-in functions are globally available for your use that mean you can make use of the built-in functions without importing or configuring. Some of the most commonly used Python built-in functions are the following: _print()_, _len()_, _type()_, _int()_, _float()_, _str()_, _input()_, _list()_, _dict()_, _min()_, _max()_, _sum()_, _sorted()_, _open()_, _file()_, _help()_, and _dir()_. In the following table you will see an exhaustive list of Python built-in functions taken from [python documentation](https://docs.python.org/3/library/functions.html).

Let us open the Python shell and start using some of the most common built-in functions.

Let us practice more by using different built-in functions

As you can see from the terminal above, Python has got reserved words. We do not use reserved words to declare variables or functions. We will cover variables in the next section.
I believe, by now you are familiar with built-in functions. Let us do one more practice of built-in functions and we will move on to the next section.

## Variables
Variables store data in a computer memory. Mnemonic variables are recommended to use in many programming languages. A mnemonic variable is a variable name that can be easily remembered and associated. A variable refers to a memory address in which data is stored.
Number at the beginning, special character, hyphen are not allowed when naming a variable. A variable can have a short name (like x, y, z), but a more descriptive name (firstname, lastname, age, country) is highly recommended.
Python Variable Name Rules
- A variable name must start with a letter or the underscore character
- A variable name cannot start with a number
- A variable name can only contain alpha-numeric characters and underscores (A-z, 0-9, and \_ )
- Variable names are case-sensitive (firstname, Firstname, FirstName and FIRSTNAME) are different variables)
Here are some example of valid variable names:
```shell
firstname
lastname
age
country
city
first_name
last_name
capital_city
_if # if we want to use reserved word as a variable
year_2021
year2021
current_year_2021
birth_year
num1
num2
```
Invalid variables names
```shell
first-name
first@name
first$name
num-1
1num
```
We will use standard Python variable naming style which has been adopted by many Python developers. Python developers use snake case(snake_case) variable naming convention. We use underscore character after each word for a variable containing more than one word(eg. first_name, last_name, engine_rotation_speed). The example below is an example of standard naming of variables, underscore is required when the variable name is more than one word.
When we assign a certain data type to a variable, it is called variable declaration. For instance in the example below my first name is assigned to a variable first_name. The equal sign is an assignment operator. Assigning means storing data in the variable. The equal sign in Python is not equality as in Mathematics.
_Example:_
```py
# Variables in Python
first_name = 'Asabeneh'
last_name = 'Yetayeh'
country = 'Finland'
city = 'Helsinki'
age = 250
is_married = True
skills = ['HTML', 'CSS', 'JS', 'React', 'Python']
person_info = {
'firstname':'Asabeneh',
'lastname':'Yetayeh',
'country':'Finland',
'city':'Helsinki'
}
```
Let us use the _print()_ and _len()_ built-in functions. Print function takes unlimited number of arguments. An argument is a value which we can be passed or put inside the function parenthesis, see the example below.
**Example:**
```py
print('Hello, World!') # The text Hello, World! is an argument
print('Hello',',', 'World','!') # it can take multiple arguments, four arguments have been passed
print(len('Hello, World!')) # it takes only one argument
```
Let us print and also find the length of the variables declared at the top:
**Example:**
```py
# Printing the values stored in the variables
print('First name:', first_name)
print('First name length:', len(first_name))
print('Last name: ', last_name)
print('Last name length: ', len(last_name))
print('Country: ', country)
print('City: ', city)
print('Age: ', age)
print('Married: ', is_married)
print('Skills: ', skills)
print('Person information: ', person_info)
```
### Declaring Multiple Variable in a Line
Multiple variables can also be declared in one line:
**Example:**
```py
first_name, last_name, country, age, is_married = 'Asabeneh', 'Yetayeh', 'Helsink', 250, True
print(first_name, last_name, country, age, is_married)
print('First name:', first_name)
print('Last name: ', last_name)
print('Country: ', country)
print('Age: ', age)
print('Married: ', is_married)
```
Getting user input using the _input()_ built-in function. Let us assign the data we get from a user into first_name and age variables.
**Example:**
```py
first_name = input('What is your name: ')
age = input('How old are you? ')
print(first_name)
print(age)
```
## Data Types
There are several data types in Python. To identify the data type we use the _type_ built-in function. I would like to ask you to focus on understanding different data types very well. When it comes to programming, it is all about data types. I introduced data types at the very beginning and it comes again, because every topic is related to data types. We will cover data types in more detail in their respective sections.
## Checking Data types and Casting
- Check Data types: To check the data type of certain data/variable we use the _type_
**Examples:**
```py
# Different python data types
# Let's declare variables with various data types
first_name = 'Asabeneh' # str
last_name = 'Yetayeh' # str
country = 'Finland' # str
city= 'Helsinki' # str
age = 250 # int, it is not my real age, don't worry about it
# Printing out types
print(type('Asabeneh')) # str
print(type(first_name)) # str
print(type(10)) # int
print(type(3.14)) # float
print(type(1 + 1j)) # complex
print(type(True)) # bool
print(type([1, 2, 3, 4])) # list
print(type({'name':'Asabeneh'})) # dict
print(type((1,2))) # tuple
print(type(zip([1,2],[3,4]))) # zip
```
- Casting: Converting one data type to another data type. We use _int()_, _float()_, _str()_, _list_, _set_
When we do arithmetic operations string numbers should be first converted to int or float otherwise it will return an error. If we concatenate a number with a string, the number should be first converted to a string. We will talk about concatenation in String section.
**Examples:**
```py
# int to float
num_int = 10
print('num_int',num_int) # 10
num_float = float(num_int)
print('num_float:', num_float) # 10.0
# float to int
gravity = 9.81
print(int(gravity)) # 9
# int to str
num_int = 10
print(num_int) # 10
num_str = str(num_int)
print(num_str) # '10'
# str to int or float
num_str = '10.6'
num_float = float(num_str) # Convert the string to a float first
num_int = int(num_float) # Then convert the float to an integer
print('num_int', int(num_str)) # 10
print('num_float', float(num_str)) # 10.6
num_int = int(num_float)
print('num_int', int(num_int)) # 10
# str to list
first_name = 'Asabeneh'
print(first_name) # 'Asabeneh'
first_name_to_list = list(first_name)
print(first_name_to_list) # ['A', 's', 'a', 'b', 'e', 'n', 'e', 'h']
```
## Numbers
Number data types in Python:
1. Integers: Integer(negative, zero and positive) numbers
Example:
... -3, -2, -1, 0, 1, 2, 3 ...
2. Floating Point Numbers(Decimal numbers)
Example:
... -3.5, -2.25, -1.0, 0.0, 1.1, 2.2, 3.5 ...
3. Complex Numbers
Example:
1 + j, 2 + 4j, 1 - 1j
🌕 You are awesome. You have just completed day 2 challenges and you are two steps ahead on your way to greatness. Now do some exercises for your brain and muscles.
## 💻 Exercises - Day 2
### Exercises: Level 1
1. Inside 30DaysOfPython create a folder called day_2. Inside this folder create a file named variables.py
2. Write a python comment saying 'Day 2: 30 Days of python programming'
3. Declare a first name variable and assign a value to it
4. Declare a last name variable and assign a value to it
5. Declare a full name variable and assign a value to it
6. Declare a country variable and assign a value to it
7. Declare a city variable and assign a value to it
8. Declare an age variable and assign a value to it
9. Declare a year variable and assign a value to it
10. Declare a variable is_married and assign a value to it
11. Declare a variable is_true and assign a value to it
12. Declare a variable is_light_on and assign a value to it
13. Declare multiple variable on one line
### Exercises: Level 2
1. Check the data type of all your variables using type() built-in function
2. Using the _len()_ built-in function, find the length of your first name
3. Compare the length of your first name and your last name
4. Declare 5 as num_one and 4 as num_two
5. Add num_one and num_two and assign the value to a variable total
6. Subtract num_two from num_one and assign the value to a variable diff
7. Multiply num_two and num_one and assign the value to a variable product
8. Divide num_one by num_two and assign the value to a variable division
9. Use modulus division to find num_two divided by num_one and assign the value to a variable remainder
10. Calculate num_one to the power of num_two and assign the value to a variable exp
11. Find floor division of num_one by num_two and assign the value to a variable floor_division
12. The radius of a circle is 30 meters.
1. Calculate the area of a circle and assign the value to a variable name of _area_of_circle_
2. Calculate the circumference of a circle and assign the value to a variable name of _circum_of_circle_
3. Take radius as user input and calculate the area.
13. Use the built-in input function to get first name, last name, country and age from a user and store the value to their corresponding variable names
14. Run help('keywords') in Python shell or in your file to check for the Python reserved words or keywords
🎉 CONGRATULATIONS ! 🎉
[<< Day 1](../readme.md) | [Day 3 >>](../03_Day_Operators/03_operators.md)
================================================
FILE: 02_Day_Variables_builtin_functions/variables.py
================================================
# Variables in Python
first_name = 'Asabeneh'
last_name = 'Yetayeh'
country = 'Finland'
city = 'Helsinki'
age = 250
is_married = True
skills = ['HTML', 'CSS', 'JS', 'React', 'Python']
person_info = {
'firstname': 'Asabeneh',
'lastname': 'Yetayeh',
'country': 'Finland',
'city': 'Helsinki'
}
# Printing the values stored in the variables
print('First name:', first_name)
print('First name length:', len(first_name))
print('Last name: ', last_name)
print('Last name length: ', len(last_name))
print('Country: ', country)
print('City: ', city)
print('Age: ', age)
print('Married: ', is_married)
print('Skills: ', skills)
print('Person information: ', person_info)
# Declaring multiple variables in one line
first_name, last_name, country, age, is_married = 'Asabeneh', 'Yetayeh', 'Helsink', 250, True
print(first_name, last_name, country, age, is_married)
print('First name:', first_name)
print('Last name: ', last_name)
print('Country: ', country)
print('Age: ', age)
print('Married: ', is_married)
================================================
FILE: 03_Day_Operators/03_operators.md
================================================
[<< Day 2](../02_Day_Variables_builtin_functions/02_variables_builtin_functions.md) | [Day 4 >>](../04_Day_Strings/04_strings.md)

- [📘 Day 3](#-day-3)
- [Boolean](#boolean)
- [Operators](#operators)
- [Assignment Operators](#assignment-operators)
- [Arithmetic Operators:](#arithmetic-operators)
- [Comparison Operators](#comparison-operators)
- [Logical Operators](#logical-operators)
- [💻 Exercises - Day 3](#-exercises---day-3)
# 📘 Day 3
## Boolean
A boolean data type represents one of the two values: _True_ or _False_. The use of these data types will be clear once we start using the comparison operator. The first letter **T** for True and **F** for False should be capital unlike JavaScript.
**Example: Boolean Values**
```py
print(True)
print(False)
```
## Operators
Python language supports several types of operators. In this section, we will focus on few of them.
### Assignment Operators
Assignment operators are used to assign values to variables. Let us take = as an example. Equal sign in mathematics shows that two values are equal, however in Python it means we are storing a value in a certain variable and we call it assignment or a assigning value to a variable. The table below shows the different types of python assignment operators, taken from [w3school](https://www.w3schools.com/python/python_operators.asp).

### Arithmetic Operators:
- Addition(+): a + b
- Subtraction(-): a - b
- Multiplication(*): a * b
- Division(/): a / b
- Modulus(%): a % b
- Floor division(//): a // b
- Exponentiation(**): a ** b

**Example:Integers**
```py
# Arithmetic Operations in Python
# Integers
print('Addition: ', 1 + 2) # 3
print('Subtraction: ', 2 - 1) # 1
print('Multiplication: ', 2 * 3) # 6
print ('Division: ', 4 / 2) # 2.0 Division in Python gives floating number
print('Division: ', 6 / 2) # 3.0
print('Division: ', 7 / 2) # 3.5
print('Division without the remainder: ', 7 // 2) # 3, gives without the floating number or without the remaining
print ('Division without the remainder: ',7 // 3) # 2
print('Modulus: ', 3 % 2) # 1, Gives the remainder
print('Exponentiation: ', 2 ** 3) # 8 it means 2 * 2 * 2
```
**Example:Floats**
```py
# Floating numbers
print('Floating Point Number, PI', 3.14)
print('Floating Point Number, gravity', 9.81)
```
**Example:Complex numbers**
```py
# Complex numbers
print('Complex number: ', 1 + 1j)
print('Multiplying complex numbers: ',(1 + 1j) * (1 - 1j))
```
Let's declare a variable and assign a number data type. I am going to use single character variable but remember do not develop a habit of declaring such types of variables. Variable names should be all the time mnemonic.
**Example:**
```python
# Declaring the variable at the top first
a = 3 # a is a variable name and 3 is an integer data type
b = 2 # b is a variable name and 3 is an integer data type
# Arithmetic operations and assigning the result to a variable
total = a + b
diff = a - b
product = a * b
division = a / b
remainder = a % b
floor_division = a // b
exponential = a ** b
# I should have used sum instead of total but sum is a built-in function - try to avoid overriding built-in functions
print(total) # if you do not label your print with some string, you never know where the result is coming from
print('a + b = ', total)
print('a - b = ', diff)
print('a * b = ', product)
print('a / b = ', division)
print('a % b = ', remainder)
print('a // b = ', floor_division)
print('a ** b = ', exponential)
```
**Example:**
```py
print('== Addition, Subtraction, Multiplication, Division, Modulus ==')
# Declaring values and organizing them together
num_one = 3
num_two = 4
# Arithmetic operations
total = num_one + num_two
diff = num_two - num_one
product = num_one * num_two
div = num_two / num_one
remainder = num_two % num_one
# Printing values with label
print('total: ', total)
print('difference: ', diff)
print('product: ', product)
print('division: ', div)
print('remainder: ', remainder)
```
Let us start connecting the dots and start making use of what we already know to calculate (area, volume,density, weight, perimeter, distance, force).
**Example:**
```py
# Calculating area of a circle
radius = 10 # radius of a circle
area_of_circle = 3.14 * radius ** 2 # two * sign means exponent or power
print('Area of a circle:', area_of_circle)
# Calculating area of a rectangle
length = 10
width = 20
area_of_rectangle = length * width
print('Area of rectangle:', area_of_rectangle)
# Calculating a weight of an object
mass = 75
gravity = 9.81
weight = mass * gravity
print(weight, 'N') # Adding unit to the weight
# Calculate the density of a liquid
mass = 75 # in Kg
volume = 0.075 # in cubic meter
density = mass / volume # 1000 Kg/m^3
print(density, 'Kg/m^3') # Adding unit to the density
```
### Comparison Operators
In programming we compare values, we use comparison operators to compare two values. We check if a value is greater or less or equal to other value. The following table shows Python comparison operators which was taken from [w3shool](https://www.w3schools.com/python/python_operators.asp).

**Example: Comparison Operators**
```py
print(3 > 2) # True, because 3 is greater than 2
print(3 >= 2) # True, because 3 is greater than 2
print(3 < 2) # False, because 3 is greater than 2
print(2 < 3) # True, because 2 is less than 3
print(2 <= 3) # True, because 2 is less than 3
print(3 == 2) # False, because 3 is not equal to 2
print(3 != 2) # True, because 3 is not equal to 2
print(len('mango') == len('avocado')) # False
print(len('mango') != len('avocado')) # True
print(len('mango') < len('avocado')) # True
print(len('milk') != len('meat')) # False
print(len('milk') == len('meat')) # True
print(len('tomato') == len('potato')) # True
print(len('python') > len('dragon')) # False
# Comparing something gives either a True or False
print('True == True: ', True == True)
print('True == False: ', True == False)
print('False == False:', False == False)
```
In addition to the above comparison operator Python uses:
- _is_: Returns true if both variables are the same object(x is y)
- _is not_: Returns true if both variables are not the same object(x is not y)
- _in_: Returns True if the queried list contains a certain item(x in y)
- _not in_: Returns True if the queried list doesn't have a certain item(x not in y)
```py
print('1 is 1', 1 is 1) # True - because the data values are the same
print('1 is not 2', 1 is not 2) # True - because 1 is not 2
print('A in Asabeneh', 'A' in 'Asabeneh') # True - A found in the string
print('B not in Asabeneh', 'B' in 'Asabeneh') # False - there is no uppercase B
print('coding' in 'coding for all') # True - because coding for all has the word coding
print('a in an:', 'a' in 'an') # True
print('4 is 2 ** 2:', 4 is 2 ** 2) # True
```
### Logical Operators
Unlike other programming languages python uses keywords _and_, _or_ and _not_ for logical operators. Logical operators are used to combine conditional statements:

```py
print(3 > 2 and 4 > 3) # True - because both statements are true
print(3 > 2 and 4 < 3) # False - because the second statement is false
print(3 < 2 and 4 < 3) # False - because both statements are false
print('True and True: ', True and True)
print(3 > 2 or 4 > 3) # True - because both statements are true
print(3 > 2 or 4 < 3) # True - because one of the statements is true
print(3 < 2 or 4 < 3) # False - because both statements are false
print('True or False:', True or False)
print(not 3 > 2) # False - because 3 > 2 is true, then not True gives False
print(not True) # False - Negation, the not operator turns true to false
print(not False) # True
print(not not True) # True
print(not not False) # False
```
🌕 You have boundless energy. You have just completed day 3 challenges and you are three steps ahead on your way to greatness. Now do some exercises for your brain and your muscles.
## 💻 Exercises - Day 3
1. Declare your age as integer variable
2. Declare your height as a float variable
3. Declare a variable that store a complex number
4. Write a script that prompts the user to enter base and height of the triangle and calculate an area of this triangle (area = 0.5 x b x h).
```py
Enter base: 20
Enter height: 10
The area of the triangle is 100
```
5. Write a script that prompts the user to enter side a, side b, and side c of the triangle. Calculate the perimeter of the triangle (perimeter = a + b + c).
```py
Enter side a: 5
Enter side b: 4
Enter side c: 3
The perimeter of the triangle is 12
```
6. Get length and width of a rectangle using prompt. Calculate its area (area = length x width) and perimeter (perimeter = 2 x (length + width))
7. Get radius of a circle using prompt. Calculate the area (area = pi x r x r) and circumference (c = 2 x pi x r) where pi = 3.14.
8. Calculate the slope, x-intercept and y-intercept of y = 2x -2
9. Slope is (m = y2-y1/x2-x1). Find the slope and [Euclidean distance](https://en.wikipedia.org/wiki/Euclidean_distance#:~:text=In%20mathematics%2C%20the%20Euclidean%20distance,being%20called%20the%20Pythagorean%20distance.) between point (2, 2) and point (6,10)
10. Compare the slopes in tasks 8 and 9.
11. Calculate the value of y (y = x^2 + 6x + 9). Try to use different x values and figure out at what x value y is going to be 0.
12. Find the length of 'python' and 'dragon' and make a falsy comparison statement.
13. Use _and_ operator to check if 'on' is found in both 'python' and 'dragon'
14. _I hope this course is not full of jargon_. Use _in_ operator to check if _jargon_ is in the sentence.
15. There is no 'on' in both dragon and python
16. Find the length of the text _python_ and convert the value to float and convert it to string
17. Even numbers are divisible by 2 and the remainder is zero. How do you check if a number is even or not using python?
18. Check if the floor division of 7 by 3 is equal to the int converted value of 2.7.
19. Check if type of '10' is equal to type of 10
20. Check if int('9.8') is equal to 10
21. Write a script that prompts the user to enter hours and rate per hour. Calculate pay of the person?
```py
Enter hours: 40
Enter rate per hour: 28
Your weekly earning is 1120
```
22. Write a script that prompts the user to enter number of years. Calculate the number of seconds a person can live. Assume a person can live hundred years
```py
Enter number of years you have lived: 100
You have lived for 3153600000 seconds.
```
23. Write a Python script that displays the following table
```py
1 1 1 1 1
2 1 2 4 8
3 1 3 9 27
4 1 4 16 64
5 1 5 25 125
```
🎉 CONGRATULATIONS ! 🎉
[<< Day 2](../02_Day_Variables_builtin_functions/02_variables_builtin_functions.md) | [Day 4 >>](../04_Day_Strings/04_strings.md)
================================================
FILE: 03_Day_Operators/day-3.py
================================================
# Arithmetic Operations in Python
# Integers
print('Addition: ', 1 + 2)
print('Subtraction: ', 2 - 1)
print('Multiplication: ', 2 * 3)
# Division in python gives floating number
print('Division: ', 4 / 2)
print('Division: ', 6 / 2)
print('Division: ', 7 / 2)
# gives without the floating number or without the remaining
print('Division without the remainder: ', 7 // 2)
print('Modulus: ', 3 % 2) # Gives the remainder
print('Division without the remainder: ', 7 // 3)
print('Exponential: ', 3 ** 2) # it means 3 * 3
# Floating numbers
print('Floating Number,PI', 3.14)
print('Floating Number, gravity', 9.81)
# Complex numbers
print('Complex number: ', 1+1j)
print('Multiplying complex number: ', (1+1j) * (1-1j))
# Declaring the variable at the top first
a = 3 # a is a variable name and 3 is an integer data type
b = 2 # b is a variable name and 3 is an integer data type
# Arithmetic operations and assigning the result to a variable
total = a + b
diff = a - b
product = a * b
division = a / b
remainder = a % b
floor_division = a // b
exponential = a ** b
# I should have used sum instead of total but sum is a built-in function try to avoid overriding builtin functions
print(total) # if you don't label your print with some string, you never know from where is the result is coming
print('a + b = ', total)
print('a - b = ', diff)
print('a * b = ', product)
print('a / b = ', division)
print('a % b = ', remainder)
print('a // b = ', floor_division)
print('a ** b = ', exponential)
# Declaring values and organizing them together
num_one = 3
num_two = 4
# Arithmetic operations
total = num_one + num_two
diff = num_two - num_one
product = num_one * num_two
div = num_two / num_two
remainder = num_two % num_one
# Printing values with label
print('total: ', total)
print('difference: ', diff)
print('product: ', product)
print('division: ', div)
print('remainder: ', remainder)
# Calculating area of a circle
radius = 10 # radius of a circle
# two * sign means exponent or power
area_of_circle = 3.14 * radius ** 2
print('Area of a circle:', area_of_circle)
# Calculating area of a rectangle
length = 10
width = 20
area_of_rectangle = length * width
print('Area of rectangle:', area_of_rectangle)
# Calculating a weight of an object
mass = 75
gravity = 9.81
weight = mass * gravity
print(weight, 'N')
print(3 > 2) # True, because 3 is greater than 2
print(3 >= 2) # True, because 3 is greater than 2
print(3 < 2) # False, because 3 is greater than 2
print(2 < 3) # True, because 2 is less than 3
print(2 <= 3) # True, because 2 is less than 3
print(3 == 2) # False, because 3 is not equal to 2
print(3 != 2) # True, because 3 is not equal to 2
print(len('mango') == len('avocado')) # False
print(len('mango') != len('avocado')) # True
print(len('mango') < len('avocado')) # True
print(len('milk') != len('meat')) # False
print(len('milk') == len('meat')) # True
print(len('tomato') == len('potato')) # True
print(len('python') > len('dragon')) # False
# Boolean comparison
print('True == True: ', True == True)
print('True == False: ', True == False)
print('False == False:', False == False)
print('True and True: ', True and True)
print('True or False:', True or False)
# Another way comparison
# True - because the data values are the same
print('1 is 1', 1 is 1)
print('1 is not 2', 1 is not 2) # True - because 1 is not 2
print('A in Asabeneh', 'A' in 'Asabeneh') # True - A found in the string
print('B in Asabeneh', 'B' in 'Asabeneh') # False -there is no uppercase B
# True - because coding for all has the word coding
print('coding' in 'coding for all')
print('a in an:', 'a' in 'an') # True
print('4 is 2 ** 2:', 4 is 2 ** 2) # True
print(3 > 2 and 4 > 3) # True - because both statements are true
print(3 > 2 and 4 < 3) # False - because the second statement is false
print(3 < 2 and 4 < 3) # False - because both statements are false
print(3 > 2 or 4 > 3) # True - because both statements are true
print(3 > 2 or 4 < 3) # True - because one of the statement is true
print(3 < 2 or 4 < 3) # False - because both statements are false
print(not 3 > 2) # False - because 3 > 2 is true, then not True gives False
print(not True) # False - Negation, the not operator turns true to false
print(not False) # True
print(not not True) # True
print(not not False) # False
================================================
FILE: 04_Day_Strings/04_strings.md
================================================
[<< Day 3](../03_Day_Operators/03_operators.md) | [Day 5 >>](../05_Day_Lists/05_lists.md)

- [Day 4](#day-4)
- [Strings](#strings)
- [Creating a String](#creating-a-string)
- [String Concatenation](#string-concatenation)
- [Escape Sequences in Strings](#escape-sequences-in-strings)
- [String formatting](#string-formatting)
- [Old Style String Formatting (% Operator)](#old-style-string-formatting--operator)
- [New Style String Formatting (str.format)](#new-style-string-formatting-strformat)
- [String Interpolation / f-Strings (Python 3.6+)](#string-interpolation--f-strings-python-36)
- [Python Strings as Sequences of Characters](#python-strings-as-sequences-of-characters)
- [Unpacking Characters](#unpacking-characters)
- [Accessing Characters in Strings by Index](#accessing-characters-in-strings-by-index)
- [Slicing Python Strings](#slicing-python-strings)
- [Reversing a String](#reversing-a-string)
- [Skipping Characters While Slicing](#skipping-characters-while-slicing)
- [String Methods](#string-methods)
- [💻 Exercises - Day 4](#-exercises---day-4)
# Day 4
## Strings
Text is a string data type. Any data type written as text is a string. Any data under single, double or triple quote are strings. There are different string methods and built-in functions to deal with string data types. To check the length of a string use the len() method.
### Creating a String
```py
letter = 'P' # A string could be a single character or a bunch of texts
print(letter) # P
print(len(letter)) # 1
greeting = 'Hello, World!' # String could be made using a single or double quote,"Hello, World!"
print(greeting) # Hello, World!
print(len(greeting)) # 13
sentence = "I hope you are enjoying 30 days of Python Challenge"
print(sentence)
```
Multiline string is created by using triple single (''') or triple double quotes ("""). See the example below.
```py
multiline_string = '''I am a teacher and enjoy teaching.
I didn't find anything as rewarding as empowering people.
That is why I created 30 days of python.'''
print(multiline_string)
# Another way of doing the same thing
multiline_string = """I am a teacher and enjoy teaching.
I didn't find anything as rewarding as empowering people.
That is why I created 30 days of python."""
print(multiline_string)
```
### String Concatenation
We can connect strings together. Merging or connecting strings is called concatenation. See the example below:
```py
first_name = 'Asabeneh'
last_name = 'Yetayeh'
space = ' '
full_name = first_name + space + last_name
print(full_name) # Asabeneh Yetayeh
# Checking the length of a string using len() built-in function
print(len(first_name)) # 8
print(len(last_name)) # 7
print(len(first_name) > len(last_name)) # True
print(len(full_name)) # 16
```
### Escape Sequences in Strings
In Python and other programming languages \ followed by a character is an escape sequence. Let us see the most common escape characters:
- \n: new line
- \t: Tab means(8 spaces)
- \\\\: Back slash
- \\': Single quote (')
- \\": Double quote (")
Now, let us see the use of the above escape sequences with examples.
```py
print('I hope everyone is enjoying the Python Challenge.\nAre you ?') # line break
print('Days\tTopics\tExercises') # adding tab space or 4 spaces
print('Day 1\t5\t5')
print('Day 2\t6\t20')
print('Day 3\t5\t23')
print('Day 4\t1\t35')
print('This is a backslash symbol (\\)') # To write a backslash
print('In every programming language it starts with \"Hello, World!\"') # to write a double quote inside a single quote
# output
I hope every one is enjoying the Python Challenge.
Are you ?
Days Topics Exercises
Day 1 5 5
Day 2 6 20
Day 3 5 23
Day 4 1 35
This is a backslash symbol (\)
In every programming language it starts with "Hello, World!"
```
### String formatting
#### Old Style String Formatting (% Operator)
In Python there are many ways of formatting strings. In this section, we will cover some of them.
The "%" operator is used to format a set of variables enclosed in a "tuple" (a fixed size list), together with a format string, which contains normal text together with "argument specifiers", special symbols like "%s", "%d", "%f", "%.number of digitsf".
- %s - String (or any object with a string representation, like numbers)
- %d - Integers
- %f - Floating point numbers
- "%.number of digitsf" - Floating point numbers with fixed precision
```py
# Strings only
first_name = 'Asabeneh'
last_name = 'Yetayeh'
language = 'Python'
formated_string = 'I am %s %s. I teach %s' %(first_name, last_name, language)
print(formated_string)
# Strings and numbers
radius = 10
pi = 3.14
area = pi * radius ** 2
formated_string = 'The area of circle with a radius %d is %.2f.' %(radius, area) # 2 refers the 2 significant digits after the point
python_libraries = ['Django', 'Flask', 'NumPy', 'Matplotlib','Pandas']
formated_string = 'The following are python libraries:%s' % (python_libraries)
print(formated_string) # "The following are python libraries:['Django', 'Flask', 'NumPy', 'Matplotlib','Pandas']"
```
#### New Style String Formatting (str.format)
This format was introduced in Python version 3.
```py
first_name = 'Asabeneh'
last_name = 'Yetayeh'
language = 'Python'
formated_string = 'I am {} {}. I teach {}'.format(first_name, last_name, language)
print(formated_string)
a = 4
b = 3
print('{} + {} = {}'.format(a, b, a + b))
print('{} - {} = {}'.format(a, b, a - b))
print('{} * {} = {}'.format(a, b, a * b))
print('{} / {} = {:.2f}'.format(a, b, a / b)) # limits it to two digits after decimal
print('{} % {} = {}'.format(a, b, a % b))
print('{} // {} = {}'.format(a, b, a // b))
print('{} ** {} = {}'.format(a, b, a ** b))
# output
4 + 3 = 7
4 - 3 = 1
4 * 3 = 12
4 / 3 = 1.33
4 % 3 = 1
4 // 3 = 1
4 ** 3 = 64
# Strings and numbers
radius = 10
pi = 3.14
area = pi * radius ** 2
formated_string = 'The area of a circle with a radius {} is {:.2f}.'.format(radius, area) # 2 digits after decimal
print(formated_string)
```
#### String Interpolation / f-Strings (Python 3.6+)
Another new string formatting is string interpolation, f-strings. Strings start with f and we can inject the data in their corresponding positions.
```py
a = 4
b = 3
print(f'{a} + {b} = {a +b}')
print(f'{a} - {b} = {a - b}')
print(f'{a} * {b} = {a * b}')
print(f'{a} / {b} = {a / b:.2f}')
print(f'{a} % {b} = {a % b}')
print(f'{a} // {b} = {a // b}')
print(f'{a} ** {b} = {a ** b}')
```
### Python Strings as Sequences of Characters
Python strings are sequences of characters, and share their basic methods of access with other Python ordered sequences of objects – lists and tuples. The simplest way of extracting single characters from strings (and individual members from any sequence) is to unpack them into corresponding variables.
#### Unpacking Characters
```
language = 'Python'
a,b,c,d,e,f = language # unpacking sequence characters into variables
print(a) # P
print(b) # y
print(c) # t
print(d) # h
print(e) # o
print(f) # n
```
#### Accessing Characters in Strings by Index
In programming counting starts from zero. Therefore the first letter of a string is at zero index and the last letter of a string is the length of a string minus one.

```py
language = 'Python'
first_letter = language[0]
print(first_letter) # P
second_letter = language[1]
print(second_letter) # y
last_index = len(language) - 1
last_letter = language[last_index]
print(last_letter) # n
```
If we want to start from right end we can use negative indexing. -1 is the last index.
```py
language = 'Python'
last_letter = language[-1]
print(last_letter) # n
second_last = language[-2]
print(second_last) # o
```
#### Slicing Python Strings
In python we can slice strings into substrings.
```py
language = 'Python'
first_three = language[0:3] # starts at zero index and up to 3 but not include 3
print(first_three) #Pyt
last_three = language[3:6]
print(last_three) # hon
# Another way
last_three = language[-3:]
print(last_three) # hon
last_three = language[3:]
print(last_three) # hon
```
#### Reversing a String
We can easily reverse strings in python.
```py
greeting = 'Hello, World!'
print(greeting[::-1]) # !dlroW ,olleH
```
#### Skipping Characters While Slicing
It is possible to skip characters while slicing by passing step argument to slice method.
```py
language = 'Python'
pto = language[0:6:2] #
print(pto) # Pto
```
### String Methods
There are many string methods which allow us to format strings. See some of the string methods in the following example:
- capitalize(): Converts the first character of the string to capital letter
```py
challenge = 'thirty days of python'
print(challenge.capitalize()) # 'Thirty days of python'
```
- count(): returns occurrences of substring in string, count(substring, start=.., end=..). The start is a starting indexing for counting and end is the last index to count.
```py
challenge = 'thirty days of python'
print(challenge.count('y')) # 3
print(challenge.count('y', 7, 14)) # 1,
print(challenge.count('th')) # 2`
```
- endswith(): Checks if a string ends with a specified ending
```py
challenge = 'thirty days of python'
print(challenge.endswith('on')) # True
print(challenge.endswith('tion')) # False
```
- expandtabs(): Replaces tab character with spaces, default tab size is 8. It takes tab size argument
```py
challenge = 'thirty\tdays\tof\tpython'
print(challenge.expandtabs()) # 'thirty days of python'
print(challenge.expandtabs(10)) # 'thirty days of python'
```
- find(): Returns the index of the first occurrence of a substring, if not found returns -1
```py
challenge = 'thirty days of python'
print(challenge.find('y')) # 5
print(challenge.find('th')) # 0
```
- rfind(): Returns the index of the last occurrence of a substring, if not found returns -1
```py
challenge = 'thirty days of python'
print(challenge.rfind('y')) # 16
print(challenge.rfind('th')) # 17
```
- format(): formats string into a nicer output
More about string formatting check this [link](https://www.programiz.com/python-programming/methods/string/format)
```py
first_name = 'Asabeneh'
last_name = 'Yetayeh'
age = 250
job = 'teacher'
country = 'Finland'
sentence = 'I am {} {}. I am a {}. I am {} years old. I live in {}.'.format(first_name, last_name, job, age, country)
print(sentence) # I am Asabeneh Yetayeh. I am 250 years old. I am a teacher. I live in Finland.
radius = 10
pi = 3.14
area = pi * radius ** 2
result = 'The area of a circle with radius {} is {}'.format(str(radius), str(area))
print(result) # The area of a circle with radius 10 is 314
```
- index(): Returns the lowest index of a substring, additional arguments indicate starting and ending index (default 0 and string length - 1). If the substring is not found it raises a valueError.
```py
challenge = 'thirty days of python'
sub_string = 'da'
print(challenge.index(sub_string)) # 7
print(challenge.index(sub_string, 9)) # error
```
- rindex(): Returns the highest index of a substring, additional arguments indicate starting and ending index (default 0 and string length - 1)
```py
challenge = 'thirty days of python'
sub_string = 'da'
print(challenge.rindex(sub_string)) # 7
print(challenge.rindex(sub_string, 9)) # error
print(challenge.rindex('on', 8)) # 19
```
- isalnum(): Checks alphanumeric character
```py
challenge = 'ThirtyDaysPython'
print(challenge.isalnum()) # True
challenge = '30DaysPython'
print(challenge.isalnum()) # True
challenge = 'thirty days of python'
print(challenge.isalnum()) # False, space is not an alphanumeric character
challenge = 'thirty days of python 2019'
print(challenge.isalnum()) # False
```
- isalpha(): Checks if all string elements are alphabet characters (a-z and A-Z)
```py
challenge = 'thirty days of python'
print(challenge.isalpha()) # False, space is once again excluded
challenge = 'ThirtyDaysPython'
print(challenge.isalpha()) # True
num = '123'
print(num.isalpha()) # False
```
- isdecimal(): Checks if all characters in a string are decimal (0-9)
```py
challenge = 'thirty days of python'
print(challenge.isdecimal()) # False
challenge = '123'
print(challenge.isdecimal()) # True
challenge = '\u00B2'
print(challenge.isdigit()) # True
challenge = '12 3'
print(challenge.isdecimal()) # False, space not allowed
```
- isdigit(): Checks if all characters in a string are numbers (0-9 and some other unicode characters for numbers)
```py
challenge = 'Thirty'
print(challenge.isdigit()) # False
challenge = '30'
print(challenge.isdigit()) # True
challenge = '\u00B2'
print(challenge.isdigit()) # True
```
- isnumeric(): Checks if all characters in a string are numbers or number related (just like isdigit(), just accepts more symbols, like ½)
```py
num = '10'
print(num.isnumeric()) # True
num = '\u00BD' # ½
print(num.isnumeric()) # True
num = '10.5'
print(num.isnumeric()) # False
```
- isidentifier(): Checks for a valid identifier - it checks if a string is a valid variable name
```py
challenge = '30DaysOfPython'
print(challenge.isidentifier()) # False, because it starts with a number
challenge = 'thirty_days_of_python'
print(challenge.isidentifier()) # True
```
- islower(): Checks if all alphabet characters in the string are lowercase
```py
challenge = 'thirty days of python'
print(challenge.islower()) # True
challenge = 'Thirty days of python'
print(challenge.islower()) # False
```
- isupper(): Checks if all alphabet characters in the string are uppercase
```py
challenge = 'thirty days of python'
print(challenge.isupper()) # False
challenge = 'THIRTY DAYS OF PYTHON'
print(challenge.isupper()) # True
```
- join(): Returns a concatenated string
```py
web_tech = ['HTML', 'CSS', 'JavaScript', 'React']
result = ' '.join(web_tech)
print(result) # 'HTML CSS JavaScript React'
```
```py
web_tech = ['HTML', 'CSS', 'JavaScript', 'React']
result = '# '.join(web_tech)
print(result) # 'HTML# CSS# JavaScript# React'
```
- strip(): Removes all given characters starting from the beginning and end of the string
```py
challenge = 'thirty days of pythoonnn'
print(challenge.strip('noth')) # 'irty days of py'
```
- replace(): Replaces substring with a given string
```py
challenge = 'thirty days of python'
print(challenge.replace('python', 'coding')) # 'thirty days of coding'
```
- split(): Splits the string, using given string or space as a separator
```py
challenge = 'thirty days of python'
print(challenge.split()) # ['thirty', 'days', 'of', 'python']
challenge = 'thirty, days, of, python'
print(challenge.split(', ')) # ['thirty', 'days', 'of', 'python']
```
- title(): Returns a title cased string
```py
challenge = 'thirty days of python'
print(challenge.title()) # Thirty Days Of Python
```
- swapcase(): Converts all uppercase characters to lowercase and all lowercase characters to uppercase characters
```py
challenge = 'thirty days of python'
print(challenge.swapcase()) # THIRTY DAYS OF PYTHON
challenge = 'Thirty Days Of Python'
print(challenge.swapcase()) # tHIRTY dAYS oF pYTHON
```
- startswith(): Checks if String Starts with the Specified String
```py
challenge = 'thirty days of python'
print(challenge.startswith('thirty')) # True
challenge = '30 days of python'
print(challenge.startswith('thirty')) # False
```
🌕 You are an extraordinary person and you have a remarkable potential. You have just completed day 4 challenges and you are four steps a head in to your way to greatness. Now do some exercises for your brain and muscles.
## 💻 Exercises - Day 4
1. Concatenate the string 'Thirty', 'Days', 'Of', 'Python' to a single string, 'Thirty Days Of Python'.
2. Concatenate the string 'Coding', 'For' , 'All' to a single string, 'Coding For All'.
3. Declare a variable named company and assign it to an initial value "Coding For All".
4. Print the variable company using _print()_.
5. Print the length of the company string using _len()_ method and _print()_.
6. Change all the characters to uppercase letters using _upper()_ method.
7. Change all the characters to lowercase letters using _lower()_ method.
8. Use capitalize(), title(), swapcase() methods to format the value of the string _Coding For All_.
9. Cut(slice) out the first word of _Coding For All_ string.
10. Check if _Coding For All_ string contains a word Coding using the method index, find or other methods.
11. Replace the word coding in the string 'Coding For All' to Python.
12. Change "Python for Everyone" to "Python for All" using the replace method or other methods.
13. Split the string 'Coding For All' using space as the separator (split()) .
14. "Facebook, Google, Microsoft, Apple, IBM, Oracle, Amazon" split the string at the comma.
15. What is the character at index 0 in the string _Coding For All_.
16. What is the last index of the string _Coding For All_.
17. What character is at index 10 in "Coding For All" string.
18. Create an acronym or an abbreviation for the name 'Python For Everyone'.
19. Create an acronym or an abbreviation for the name 'Coding For All'.
20. Use index to determine the position of the first occurrence of C in Coding For All.
21. Use index to determine the position of the first occurrence of F in Coding For All.
22. Use rfind to determine the position of the last occurrence of l in Coding For All People.
23. Use index or find to find the position of the first occurrence of the word 'because' in the following sentence: 'You cannot end a sentence with because because because is a conjunction'
24. Use rindex to find the position of the last occurrence of the word because in the following sentence: 'You cannot end a sentence with because because because is a conjunction'
25. Slice out the phrase 'because because because' in the following sentence: 'You cannot end a sentence with because because because is a conjunction'
26. Find the position of the first occurrence of the word 'because' in the following sentence: 'You cannot end a sentence with because because because is a conjunction'
27. Slice out the phrase 'because because because' in the following sentence: 'You cannot end a sentence with because because because is a conjunction'
28. Does 'Coding For All' start with a substring _Coding_?
29. Does 'Coding For All' end with a substring _coding_?
30. ' Coding For All ' , remove the left and right trailing spaces in the given string.
31. Which one of the following variables return True when we use the method isidentifier():
- 30DaysOfPython
- thirty_days_of_python
32. The following list contains the names of some of python libraries: ['Django', 'Flask', 'Bottle', 'Pyramid', 'Falcon']. Join the list with a hash with space string.
33. Use the new line escape sequence to separate the following sentences.
```py
I am enjoying this challenge.
I just wonder what is next.
```
34. Use a tab escape sequence to write the following lines.
```py
Name Age Country City
Asabeneh 250 Finland Helsinki
```
35. Use the string formatting method to display the following:
```sh
radius = 10
area = 3.14 * radius ** 2
The area of a circle with radius 10 is 314 meters square.
```
36. Make the following using string formatting methods:
```sh
8 + 6 = 14
8 - 6 = 2
8 * 6 = 48
8 / 6 = 1.33
8 % 6 = 2
8 // 6 = 1
8 ** 6 = 262144
```
🎉 CONGRATULATIONS ! 🎉
[<< Day 3](../03_Day_Operators/03_operators.md) | [Day 5 >>](../05_Day_Lists/05_lists.md)
================================================
FILE: 04_Day_Strings/day_4.py
================================================
# Single line comment
letter = 'P' # A string could be a single character or a bunch of texts
print(letter) # P
print(len(letter)) # 1
greeting = 'Hello, World!' # String could be a single or double quote,"Hello, World!"
print(greeting) # Hello, World!
print(len(greeting)) # 13
sentence = "I hope you are enjoying 30 days of python challenge"
print(sentence)
# Multiline String
multiline_string = '''I am a teacher and enjoy teaching.
I didn't find anything as rewarding as empowering people.
That is why I created 30 days of python.'''
print(multiline_string)
# Another way of doing the same thing
multiline_string = """I am a teacher and enjoy teaching.
I didn't find anything as rewarding as empowering people.
That is why I created 30 days of python."""
print(multiline_string)
# String Concatenation
first_name = 'Asabeneh'
last_name = 'Yetayeh'
space = ' '
full_name = first_name + space + last_name
print(full_name) # Asabeneh Yetayeh
# Checking length of a string using len() builtin function
print(len(first_name)) # 8
print(len(last_name)) # 7
print(len(first_name) > len(last_name)) # True
print(len(full_name)) # 15
# Unpacking characters
language = 'Python'
a, b, c, d, e, f = language # unpacking sequence characters into variables
print(a) # P
print(b) # y
print(c) # t
print(d) # h
print(e) # o
print(f) # n
# Accessing characters in strings by index
language = 'Python'
first_letter = language[0]
print(first_letter) # P
second_letter = language[1]
print(second_letter) # y
last_index = len(language) - 1
last_letter = language[last_index]
print(last_letter) # n
# If we want to start from right end we can use negative indexing. -1 is the last index
language = 'Python'
last_letter = language[-1]
print(last_letter) # n
second_last = language[-2]
print(second_last) # o
# Slicing
language = 'Python'
# starts at zero index and up to 3 but not include 3
first_three = language[0:3]
last_three = language[3:6]
print(last_three) # hon
# Another way
last_three = language[-3:]
print(last_three) # hon
last_three = language[3:]
print(last_three) # hon
# Skipping character while splitting Python strings
language = 'Python'
pto = language[0:6:2]
print(pto) # pto
# Escape sequence
print('I hope every one enjoying the python challenge.\nDo you ?') # line break
print('Days\tTopics\tExercises')
print('Day 1\t3\t5')
print('Day 2\t3\t5')
print('Day 3\t3\t5')
print('Day 4\t3\t5')
print('This is a back slash symbol (\\)') # To write a back slash
print('In every programming language it starts with \"Hello, World!\"')
# String Methods
# capitalize(): Converts the first character the string to Capital Letter
challenge = 'thirty days of python'
print(challenge.capitalize()) # 'Thirty days of python'
# count(): returns occurrences of substring in string, count(substring, start=.., end=..)
challenge = 'thirty days of python'
print(challenge.count('y')) # 3
print(challenge.count('y', 7, 14)) # 1
print(challenge.count('th')) # 2`
# endswith(): Checks if a string ends with a specified ending
challenge = 'thirty days of python'
print(challenge.endswith('on')) # True
print(challenge.endswith('tion')) # False
# expandtabs(): Replaces tab character with spaces, default tab size is 8. It takes tab size argument
challenge = 'thirty\tdays\tof\tpython'
print(challenge.expandtabs()) # 'thirty days of python'
print(challenge.expandtabs(10)) # 'thirty days of python'
# find(): Returns the index of first occurrence of substring
challenge = 'thirty days of python'
print(challenge.find('y')) # 5
print(challenge.find('th')) # 0
# format() formats string into nicer output
first_name = 'Asabeneh'
last_name = 'Yetayeh'
job = 'teacher'
country = 'Finland'
sentence = 'I am {} {}. I am a {}. I live in {}.'.format(
first_name, last_name, job, country)
print(sentence) # I am Asabeneh Yetayeh. I am a teacher. I live in Finland.
radius = 10
pi = 3.14
area = pi # radius ## 2
result = 'The area of circle with {} is {}'.format(str(radius), str(area))
print(result) # The area of circle with 10 is 314.0
# index(): Returns the index of substring
challenge = 'thirty days of python'
print(challenge.find('y')) # 5
print(challenge.find('th')) # 0
# isalnum(): Checks alphanumeric character
challenge = 'ThirtyDaysPython'
print(challenge.isalnum()) # True
challenge = '30DaysPython'
print(challenge.isalnum()) # True
challenge = 'thirty days of python'
print(challenge.isalnum()) # False
challenge = 'thirty days of python 2019'
print(challenge.isalnum()) # False
# isalpha(): Checks if all characters are alphabets
challenge = 'thirty days of python'
print(challenge.isalpha()) # True
num = '123'
print(num.isalpha()) # False
# isdecimal(): Checks Decimal Characters
challenge = 'thirty days of python'
print(challenge.find('y')) # 5
print(challenge.find('th')) # 0
# isdigit(): Checks Digit Characters
challenge = 'Thirty'
print(challenge.isdigit()) # False
challenge = '30'
print(challenge.isdigit()) # True
# isdecimal():Checks decimal characters
num = '10'
print(num.isdecimal()) # True
num = '10.5'
print(num.isdecimal()) # False
# isidentifier():Checks for valid identifier means it check if a string is a valid variable name
challenge = '30DaysOfPython'
print(challenge.isidentifier()) # False, because it starts with a number
challenge = 'thirty_days_of_python'
print(challenge.isidentifier()) # True
# islower():Checks if all alphabets in a string are lowercase
challenge = 'thirty days of python'
print(challenge.islower()) # True
challenge = 'Thirty days of python'
print(challenge.islower()) # False
# isupper(): returns if all characters are uppercase characters
challenge = 'thirty days of python'
print(challenge.isupper()) # False
challenge = 'THIRTY DAYS OF PYTHON'
print(challenge.isupper()) # True
# isnumeric():Checks numeric characters
num = '10'
print(num.isnumeric()) # True
print('ten'.isnumeric()) # False
# join(): Returns a concatenated string
web_tech = ['HTML', 'CSS', 'JavaScript', 'React']
result = '#, '.join(web_tech)
print(result) # 'HTML# CSS# JavaScript# React'
# strip(): Removes both leading and trailing characters
challenge = ' thirty days of python '
print(challenge.strip('y')) # 5
# replace(): Replaces substring inside
challenge = 'thirty days of python'
print(challenge.replace('python', 'coding')) # 'thirty days of coding'
# split():Splits String from Left
challenge = 'thirty days of python'
print(challenge.split()) # ['thirty', 'days', 'of', 'python']
# title(): Returns a Title Cased String
challenge = 'thirty days of python'
print(challenge.title()) # Thirty Days Of Python
# swapcase(): Checks if String Starts with the Specified String
challenge = 'thirty days of python'
print(challenge.swapcase()) # THIRTY DAYS OF PYTHON
challenge = 'Thirty Days Of Python'
print(challenge.swapcase()) # tHIRTY dAYS oF pYTHON
# startswith(): Checks if String Starts with the Specified String
challenge = 'thirty days of python'
print(challenge.startswith('thirty')) # True
challenge = '30 days of python'
print(challenge.startswith('thirty')) # False
================================================
FILE: 05_Day_Lists/05_lists.md
================================================
[<< Day 4](../04_Day_Strings/04_strings.md) | [Day 6 >>](../06_Day_Tuples/06_tuples.md)

- [Day 5](#day-5)
- [Lists](#lists)
- [How to Create a List](#how-to-create-a-list)
- [Accessing List Items Using Positive Indexing](#accessing-list-items-using-positive-indexing)
- [Accessing List Items Using Negative Indexing](#accessing-list-items-using-negative-indexing)
- [Unpacking List Items](#unpacking-list-items)
- [Slicing Items from a List](#slicing-items-from-a-list)
- [Modifying Lists](#modifying-lists)
- [Checking Items in a List](#checking-items-in-a-list)
- [Adding Items to a List](#adding-items-to-a-list)
- [Inserting Items into a List](#inserting-items-into-a-list)
- [Removing Items from a List](#removing-items-from-a-list)
- [Removing Items Using Pop](#removing-items-using-pop)
- [Removing Items Using Del](#removing-items-using-del)
- [Clearing List Items](#clearing-list-items)
- [Copying a List](#copying-a-list)
- [Joining Lists](#joining-lists)
- [Counting Items in a List](#counting-items-in-a-list)
- [Finding Index of an Item](#finding-index-of-an-item)
- [Reversing a List](#reversing-a-list)
- [Sorting List Items](#sorting-list-items)
- [💻 Exercises: Day 5](#-exercises-day-5)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
# Day 5
## Lists
There are four collection data types in Python :
- List: is a collection which is ordered and changeable(modifiable). Allows duplicate members.
- Tuple: is a collection which is ordered and unchangeable or unmodifiable(immutable). Allows duplicate members.
- Set: is a collection which is unordered, un-indexed and unmodifiable, but we can add new items to the set. Duplicate members are not allowed.
- Dictionary: is a collection which is unordered, changeable(modifiable) and indexed. No duplicate members.
A list is collection of different data types which is ordered and modifiable(mutable). A list can be empty or it may have different data type items.
### How to Create a List
In Python we can create lists in two ways:
- Using list built-in function
```py
# syntax
lst = list()
```
```py
empty_list = list() # this is an empty list, no item in the list
print(len(empty_list)) # 0
```
- Using square brackets, []
```py
# syntax
lst = []
```
```py
empty_list = [] # this is an empty list, no item in the list
print(len(empty_list)) # 0
```
Lists with initial values. We use _len()_ to find the length of a list.
```py
fruits = ['banana', 'orange', 'mango', 'lemon'] # list of fruits
vegetables = ['Tomato', 'Potato', 'Cabbage','Onion', 'Carrot'] # list of vegetables
animal_products = ['milk', 'meat', 'butter', 'yoghurt'] # list of animal products
web_techs = ['HTML', 'CSS', 'JS', 'React','Redux', 'Node', 'MongDB'] # list of web technologies
countries = ['Finland', 'Estonia', 'Denmark', 'Sweden', 'Norway']
# Print the lists and its length
print('Fruits:', fruits)
print('Number of fruits:', len(fruits))
print('Vegetables:', vegetables)
print('Number of vegetables:', len(vegetables))
print('Animal products:',animal_products)
print('Number of animal products:', len(animal_products))
print('Web technologies:', web_techs)
print('Number of web technologies:', len(web_techs))
print('Countries:', countries)
print('Number of countries:', len(countries))
```
```sh
output
Fruits: ['banana', 'orange', 'mango', 'lemon']
Number of fruits: 4
Vegetables: ['Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
Number of vegetables: 5
Animal products: ['milk', 'meat', 'butter', 'yoghurt']
Number of animal products: 4
Web technologies: ['HTML', 'CSS', 'JS', 'React', 'Redux', 'Node', 'MongDB']
Number of web technologies: 7
Countries: ['Finland', 'Estonia', 'Denmark', 'Sweden', 'Norway']
Number of countries: 5
```
- Lists can have items of different data types
```py
lst = ['Asabeneh', 250, True, {'country':'Finland', 'city':'Helsinki'}] # list containing different data types
```
### Accessing List Items Using Positive Indexing
We access each item in a list using their index. A list index starts from 0. The picture below shows clearly where the index starts

```py
fruits = ['banana', 'orange', 'mango', 'lemon']
first_fruit = fruits[0] # we are accessing the first item using its index
print(first_fruit) # banana
second_fruit = fruits[1]
print(second_fruit) # orange
last_fruit = fruits[3]
print(last_fruit) # lemon
# Last index
last_index = len(fruits) - 1
last_fruit = fruits[last_index]
```
### Accessing List Items Using Negative Indexing
Negative indexing means beginning from the end, -1 refers to the last item, -2 refers to the second last item.

```py
fruits = ['banana', 'orange', 'mango', 'lemon']
first_fruit = fruits[-4]
last_fruit = fruits[-1]
second_last = fruits[-2]
print(first_fruit) # banana
print(last_fruit) # lemon
print(second_last) # mango
```
### Unpacking List Items
```py
lst = ['item1','item2','item3', 'item4', 'item5']
first_item, second_item, third_item, *rest = lst
print(first_item) # item1
print(second_item) # item2
print(third_item) # item3
print(rest) # ['item4', 'item5']
```
```py
# First Example
fruits = ['banana', 'orange', 'mango', 'lemon','lime','apple']
first_fruit, second_fruit, third_fruit, *rest = fruits
print(first_fruit) # banana
print(second_fruit) # orange
print(third_fruit) # mango
print(rest) # ['lemon','lime','apple']
# Second Example about unpacking list
first, second, third,*rest, tenth = [1,2,3,4,5,6,7,8,9,10]
print(first) # 1
print(second) # 2
print(third) # 3
print(rest) # [4,5,6,7,8,9]
print(tenth) # 10
# Third Example about unpacking list
countries = ['Germany', 'France','Belgium','Sweden','Denmark','Finland','Norway','Iceland','Estonia']
gr, fr, bg, sw, *scandic, es = countries
print(gr)
print(fr)
print(bg)
print(sw)
print(scandic)
print(es)
```
### Slicing Items from a List
- Positive Indexing: We can specify a range of positive indexes by specifying the start, end and step, the return value will be a new list. (default values for start = 0, end = len(lst) - 1 (last item), step = 1)
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
all_fruits = fruits[0:4] # it returns all the fruits
# this will also give the same result as the one above
all_fruits = fruits[0:] # if we don't set where to stop it takes all the rest
orange_and_mango = fruits[1:3] # it does not include the first index
orange_mango_lemon = fruits[1:]
orange_and_lemon = fruits[::2] # here we used a 3rd argument, step. It will take every 2cnd item - ['banana', 'mango']
```
- Negative Indexing: We can specify a range of negative indexes by specifying the start, end and step, the return value will be a new list.
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
all_fruits = fruits[-4:] # it returns all the fruits
orange_and_mango = fruits[-3:-1] # it does not include the last index,['orange', 'mango']
orange_mango_lemon = fruits[-3:] # this will give starting from -3 to the end,['orange', 'mango', 'lemon']
reverse_fruits = fruits[::-1] # a negative step will take the list in reverse order,['lemon', 'mango', 'orange', 'banana']
```
### Modifying Lists
List is a mutable or modifiable ordered collection of items. Lets modify the fruit list.
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits[0] = 'avocado'
print(fruits) # ['avocado', 'orange', 'mango', 'lemon']
fruits[1] = 'apple'
print(fruits) # ['avocado', 'apple', 'mango', 'lemon']
last_index = len(fruits) - 1
fruits[last_index] = 'lime'
print(fruits) # ['avocado', 'apple', 'mango', 'lime']
```
### Checking Items in a List
Checking an item if it is a member of a list using *in* operator. See the example below.
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
does_exist = 'banana' in fruits
print(does_exist) # True
does_exist = 'lime' in fruits
print(does_exist) # False
```
### Adding Items to a List
To add item to the end of an existing list we use the method *append()*.
```py
# syntax
lst = list()
lst.append(item)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.append('apple')
print(fruits) # ['banana', 'orange', 'mango', 'lemon', 'apple']
fruits.append('lime') # ['banana', 'orange', 'mango', 'lemon', 'apple', 'lime']
print(fruits)
```
### Inserting Items into a List
We can use *insert()* method to insert a single item at a specified index in a list. Note that other items are shifted to the right. The *insert()* methods takes two arguments:index and an item to insert.
```py
# syntax
lst = ['item1', 'item2']
lst.insert(index, item)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.insert(2, 'apple') # insert apple between orange and mango
print(fruits) # ['banana', 'orange', 'apple', 'mango', 'lemon']
fruits.insert(3, 'lime') # ['banana', 'orange', 'apple', 'lime', 'mango', 'lemon']
print(fruits)
```
### Removing Items from a List
The remove method removes a specified item from a list
```py
# syntax
lst = ['item1', 'item2']
lst.remove(item)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon', 'banana']
fruits.remove('banana')
print(fruits) # ['orange', 'mango', 'lemon', 'banana'] - this method removes the first occurrence of the item in the list
fruits.remove('lemon')
print(fruits) # ['orange', 'mango', 'banana']
```
### Removing Items Using Pop
The *pop()* method removes the specified index, (or the last item if index is not specified):
```py
# syntax
lst = ['item1', 'item2']
lst.pop() # last item
lst.pop(index)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.pop()
print(fruits) # ['banana', 'orange', 'mango']
fruits.pop(0)
print(fruits) # ['orange', 'mango']
```
### Removing Items Using Del
The *del* keyword removes the specified index and it can also be used to delete items within index range. It can also delete the list completely
```py
# syntax
lst = ['item1', 'item2']
del lst[index] # only a single item
del lst # to delete the list completely
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon', 'kiwi', 'lime']
del fruits[0]
print(fruits) # ['orange', 'mango', 'lemon', 'kiwi', 'lime']
del fruits[1]
print(fruits) # ['orange', 'lemon', 'kiwi', 'lime']
del fruits[1:3] # this deletes items between given indexes, so it does not delete the item with index 3!
print(fruits) # ['orange', 'lime']
del fruits
print(fruits) # This should give: NameError: name 'fruits' is not defined
```
### Clearing List Items
The *clear()* method empties the list:
```py
# syntax
lst = ['item1', 'item2']
lst.clear()
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.clear()
print(fruits) # []
```
### Copying a List
It is possible to copy a list by reassigning it to a new variable in the following way: list2 = list1. Now, list2 is a reference of list1, any changes we make in list2 will also modify the original, list1. But there are lots of case in which we do not like to modify the original instead we like to have a different copy. One of way of avoiding the problem above is using _copy()_.
```py
# syntax
lst = ['item1', 'item2']
lst_copy = lst.copy()
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits_copy = fruits.copy()
print(fruits_copy) # ['banana', 'orange', 'mango', 'lemon']
```
### Joining Lists
There are several ways to join, or concatenate, two or more lists in Python.
- Plus Operator (+)
```py
# syntax
list3 = list1 + list2
```
```py
positive_numbers = [1, 2, 3, 4, 5]
zero = [0]
negative_numbers = [-5,-4,-3,-2,-1]
integers = negative_numbers + zero + positive_numbers
print(integers) # [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
fruits = ['banana', 'orange', 'mango', 'lemon']
vegetables = ['Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
fruits_and_vegetables = fruits + vegetables
print(fruits_and_vegetables ) # ['banana', 'orange', 'mango', 'lemon', 'Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
```
- Joining using extend() method
The *extend()* method allows to append list in a list. See the example below.
```py
# syntax
list1 = ['item1', 'item2']
list2 = ['item3', 'item4', 'item5']
list1.extend(list2) # ['item1', 'item2', 'item3', 'item4', 'item5']
```
```py
num1 = [0, 1, 2, 3]
num2= [4, 5, 6]
num1.extend(num2)
print('Numbers:', num1) # Numbers: [0, 1, 2, 3, 4, 5, 6]
negative_numbers = [-5,-4,-3,-2,-1]
positive_numbers = [1, 2, 3,4,5]
zero = [0]
negative_numbers.extend(zero)
negative_numbers.extend(positive_numbers)
print('Integers:', negative_numbers) # Integers: [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
fruits = ['banana', 'orange', 'mango', 'lemon']
vegetables = ['Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
fruits.extend(vegetables)
print('Fruits and vegetables:', fruits ) # Fruits and vegetables: ['banana', 'orange', 'mango', 'lemon', 'Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
```
### Counting Items in a List
The *count()* method returns the number of times an item appears in a list:
```py
# syntax
lst = ['item1', 'item2']
lst.count(item)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
print(fruits.count('orange')) # 1
ages = [22, 19, 24, 25, 26, 24, 25, 24]
print(ages.count(24)) # 3
```
### Finding Index of an Item
The *index()* method returns the index of an item in the list:
```py
# syntax
lst = ['item1', 'item2']
lst.index(item)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
print(fruits.index('orange')) # 1
ages = [22, 19, 24, 25, 26, 24, 25, 24]
print(ages.index(24)) # 2, the first occurrence
```
### Reversing a List
The *reverse()* method reverses the order of a list.
```py
# syntax
lst = ['item1', 'item2']
lst.reverse()
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.reverse()
print(fruits) # ['lemon', 'mango', 'orange', 'banana']
ages = [22, 19, 24, 25, 26, 24, 25, 24]
ages.reverse()
print(ages) # [24, 25, 24, 26, 25, 24, 19, 22]
```
### Sorting List Items
To sort lists we can use _sort()_ method or _sorted()_ built-in functions. The _sort()_ method reorders the list items in ascending order and modifies the original list. If an argument of _sort()_ method reverse is equal to true, it will arrange the list in descending order.
- sort(): this method modifies the original list
```py
# syntax
lst = ['item1', 'item2']
lst.sort() # ascending
lst.sort(reverse=True) # descending
```
**Example:**
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.sort()
print(fruits) # sorted in alphabetical order, ['banana', 'lemon', 'mango', 'orange']
fruits.sort(reverse=True)
print(fruits) # ['orange', 'mango', 'lemon', 'banana']
ages = [22, 19, 24, 25, 26, 24, 25, 24]
ages.sort()
print(ages) # [19, 22, 24, 24, 24, 25, 25, 26]
ages.sort(reverse=True)
print(ages) # [26, 25, 25, 24, 24, 24, 22, 19]
```
sorted(): returns the ordered list without modifying the original list
**Example:**
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
print(sorted(fruits)) # ['banana', 'lemon', 'mango', 'orange']
# Reverse order
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits = sorted(fruits,reverse=True)
print(fruits) # ['orange', 'mango', 'lemon', 'banana']
```
🌕 You are diligent and you have already achieved quite a lot. You have just completed day 5 challenges and you are 5 steps a head in to your way to greatness. Now do some exercises for your brain and muscles.
## 💻 Exercises: Day 5
### Exercises: Level 1
1. Declare an empty list
2. Declare a list with more than 5 items
3. Find the length of your list
4. Get the first item, the middle item and the last item of the list
5. Declare a list called mixed_data_types, put your(name, age, height, marital status, address)
6. Declare a list variable named it_companies and assign initial values Facebook, Google, Microsoft, Apple, IBM, Oracle and Amazon.
7. Print the list using _print()_
8. Print the number of companies in the list
9. Print the first, middle and last company
10. Print the list after modifying one of the companies
11. Add an IT company to it_companies
12. Insert an IT company in the middle of the companies list
13. Change one of the it_companies names to uppercase (IBM excluded!)
14. Join the it_companies with a string '#; '
15. Check if a certain company exists in the it_companies list.
16. Sort the list using sort() method
17. Reverse the list in descending order using reverse() method
18. Slice out the first 3 companies from the list
19. Slice out the last 3 companies from the list
20. Slice out the middle IT company or companies from the list
21. Remove the first IT company from the list
22. Remove the middle IT company or companies from the list
23. Remove the last IT company from the list
24. Remove all IT companies from the list
25. Destroy the IT companies list
26. Join the following lists:
```py
front_end = ['HTML', 'CSS', 'JS', 'React', 'Redux']
back_end = ['Node','Express', 'MongoDB']
```
27. After joining the lists in question 26. Copy the joined list and assign it to a variable full_stack, then insert Python and SQL after Redux.
### Exercises: Level 2
1. The following is a list of 10 students ages:
```sh
ages = [19, 22, 19, 24, 20, 25, 26, 24, 25, 24]
```
- Sort the list and find the min and max age
- Add the min age and the max age again to the list
- Find the median age (one middle item or two middle items divided by two)
- Find the average age (sum of all items divided by their number )
- Find the range of the ages (max minus min)
- Compare the value of (min - average) and (max - average), use _abs()_ method
1. Find the middle country(ies) in the [countries list](https://github.com/Asabeneh/30-Days-Of-Python/tree/master/data/countries.py)
1. Divide the countries list into two equal lists if it is even if not one more country for the first half.
1. ['China', 'Russia', 'USA', 'Finland', 'Sweden', 'Norway', 'Denmark']. Unpack the first three countries and the rest as scandic countries.
🎉 CONGRATULATIONS ! 🎉
[<< Day 4](../04_Day_Strings/04_strings.md) | [Day 6 >>](../06_Day_Tuples/06_tuples.md)
================================================
FILE: 05_Day_Lists/day_5.py
================================================
empty_list = list() # this is an empty list, no item in the list
print(len(empty_list)) # 0
# list of fruits
fruits = ['banana', 'orange', 'mango', 'lemon']
vegetables = ['Tomato', 'Potato', 'Cabbage',
'Onion', 'Carrot'] # list of vegetables
animal_products = ['milk', 'meat', 'butter',
'yoghurt'] # list of animal products
web_techs = ['HTML', 'CSS', 'JS', 'React', 'Redux',
'Node', 'MongDB'] # list of web technologies
countries = ['Finland', 'Estonia', 'Denmark', 'Sweden', 'Norway']
# Print the lists and it length
print('Fruits:', fruits)
print('Number of fruits:', len(fruits))
print('Vegetables:', vegetables)
print('Number of vegetables:', len(vegetables))
print('Animal products:', animal_products)
print('Number of animal products:', len(animal_products))
print('Web technologies:', web_techs)
print('Number of web technologies:', len(web_techs))
print('Number of countries:', len(countries))
# Modifying list
fruits = ['banana', 'orange', 'mango', 'lemon']
first_fruit = fruits[0] # we are accessing the first item using its index
print(first_fruit) # banana
second_fruit = fruits[1]
print(second_fruit) # orange
last_fruit = fruits[3]
print(last_fruit) # lemon
# Last index
last_index = len(fruits) - 1
last_fruit = fruits[last_index]
# Accessing itmes
fruits = ['banana', 'orange', 'mango', 'lemon']
last_fruit = fruits[-1]
second_last = fruits[-2]
print(last_fruit) # lemon
print(second_last) # mango
# Slicing items
fruits = ['banana', 'orange', 'mango', 'lemon']
all_fruits = fruits[0:4] # it returns all the fruits
# this is also give the same result as the above
all_fruits = fruits[0:] # if we don't set where to stop it takes all the rest
orange_and_mango = fruits[1:3] # it does not include the end index
orange_mango_lemon = fruits[1:]
fruits = ['banana', 'orange', 'mango', 'lemon']
all_fruits = fruits[-4:] # it returns all the fruits
# this is also give the same result as the above
orange_and_mango = fruits[-3:-1] # it does not include the end index
orange_mango_lemon = fruits[-3:]
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits[0] = 'Avocado'
print(fruits) # ['avocado', 'orange', 'mango', 'lemon']
fruits[1] = 'apple'
print(fruits) # ['avocado', 'apple', 'mango', 'lemon']
last_index = len(fruits)
fruits[last_index] = 'lime'
print(fruits) # ['avocado', 'apple', 'mango', 'lime']
# checking items
fruits = ['banana', 'orange', 'mango', 'lemon']
does_exist = 'banana' in fruits
print(does_exist) # True
does_exist = 'lime' in fruits
print(does_exist) # False
# Append
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.append('apple')
print(fruits) # ['banana', 'orange', 'mango', 'lemon', 'apple']
# ['banana', 'orange', 'mango', 'lemon', 'apple', 'lime]
fruits.append('lime')
print(fruits)
# insert
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.insert(2, 'apple') # insert apple between orange and mango
print(fruits) # ['banana', 'orange', 'apple', 'mango', 'lemon']
# ['banana', 'orange', 'apple', 'mango', 'lime','lemon',]
fruits.list(3, 'lime')
print(fruits)
# remove
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.remove('banana')
print(fruits) # ['orange', 'mango', 'lemon']
fruits.remove('lemon')
print(fruits) # ['orange', 'mango']
# pop
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.remove()
print(fruits) # ['banana', 'orange', 'mango']
fruits.remove(0)
print(fruits) # ['orange', 'mango']
# del
fruits = ['banana', 'orange', 'mango', 'lemon']
del fruits[0]
print(fruits) # ['orange', 'mango', 'lemon']
del fruits[1]
print(fruits) # ['orange', 'lemon']
del fruits
print(fruits) # This should give: NameError: name 'fruits' is not defined
# clear
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.clear()
print(fruits) # []
# copying a lits
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits_copy = fruits.copy()
print(fruits_copy) # ['banana', 'orange', 'mango', 'lemon']
# join
positive_numbers = [1, 2, 3, 4, 5]
zero = [0]
negative_numbers = [-5, -4, -3, -2, -1]
integers = negative_numbers + zero + positive_numbers
print(integers)
fruits = ['banana', 'orange', 'mango', 'lemon']
vegetables = ['Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
fruits_and_vegetables = fruits + vegetables
print(fruits_and_vegetables)
# join with extend
num1 = [0, 1, 2, 3]
num2 = [4, 5, 6]
num1.extend(num2)
print('Numbers:', num1)
negative_numbers = [-5, -4, -3, -2, -1]
positive_numbers = [1, 2, 3, 4, 5]
zero = [0]
negative_numbers.extend(zero)
negative_numbers.extend(positive_numbers)
print('Integers:', negative_numbers)
fruits = ['banana', 'orange', 'mango', 'lemon']
vegetables = ['Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
fruits.extend(vegetables)
print('Fruits and vegetables:', fruits)
# count
fruits = ['banana', 'orange', 'mango', 'lemon']
print(fruits.count('orange')) # 1
ages = [22, 19, 24, 25, 26, 24, 25, 24]
print(ages.count(24)) # 3
# index
fruits = ['banana', 'orange', 'mango', 'lemon']
print(fruits.index('orange')) # 1
ages = [22, 19, 24, 25, 26, 24, 25, 24]
print(ages.index(24))
# Reverse
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.reverse()
print(fruits.reverse())
ages = [22, 19, 24, 25, 26, 24, 25, 24]
ages.reverse()
print(ages.reverse())
# sort
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.sort()
print(fruits)
fruits.sort(reverse=True)
print(fruits)
ages = [22, 19, 24, 25, 26, 24, 25, 24]
ages.sort()
print(ages)
ages.sort(reverse=True)
print(ages)
================================================
FILE: 06_Day_Tuples/06_tuples.md
================================================
[<< Day 5](../05_Day_Lists/05_lists.md) | [Day 7 >>](../07_Day_Sets/07_sets.md)

- [Day 6:](#day-6)
- [Tuples](#tuples)
- [Creating a Tuple](#creating-a-tuple)
- [Tuple length](#tuple-length)
- [Accessing Tuple Items](#accessing-tuple-items)
- [Slicing tuples](#slicing-tuples)
- [Changing Tuples to Lists](#changing-tuples-to-lists)
- [Checking an Item in a Tuple](#checking-an-item-in-a-tuple)
- [Joining Tuples](#joining-tuples)
- [Deleting Tuples](#deleting-tuples)
- [💻 Exercises: Day 6](#-exercises-day-6)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
# Day 6:
## Tuples
A tuple is a collection of different data types which is ordered and unchangeable (immutable). Tuples are written with round brackets, (). Once a tuple is created, we cannot change its values. We cannot use add, insert, remove methods in a tuple because it is not modifiable (mutable). Unlike list, tuple has few methods. Methods related to tuples:
- tuple(): to create an empty tuple
- count(): to count the number of a specified item in a tuple
- index(): to find the index of a specified item in a tuple
- `+` operator: to join two or more tuples and to create a new tuple
### Creating a Tuple
- Empty tuple: Creating an empty tuple
```py
# syntax
empty_tuple = ()
# or using the tuple constructor
empty_tuple = tuple()
```
- Tuple with initial values
```py
# syntax
tpl = ('item1', 'item2','item3')
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
```
### Tuple length
We use the _len()_ method to get the length of a tuple.
```py
# syntax
tpl = ('item1', 'item2', 'item3')
len(tpl)
```
### Accessing Tuple Items
- Positive Indexing
Similar to the list data type we use positive or negative indexing to access tuple items.

```py
# Syntax
tpl = ('item1', 'item2', 'item3')
first_item = tpl[0]
second_item = tpl[1]
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
first_fruit = fruits[0]
second_fruit = fruits[1]
last_index =len(fruits) - 1
last_fruit = fruits[last_index]
```
- Negative indexing
Negative indexing means beginning from the end, -1 refers to the last item, -2 refers to the second last and the negative of the list/tuple length refers to the first item.

```py
# Syntax
tpl = ('item1', 'item2', 'item3','item4')
first_item = tpl[-4]
second_item = tpl[-3]
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
first_fruit = fruits[-4]
second_fruit = fruits[-3]
last_fruit = fruits[-1]
```
### Slicing tuples
We can slice out a sub-tuple by specifying a range of indexes where to start and where to end in the tuple, the return value will be a new tuple with the specified items.
- Range of Positive Indexes
```py
# Syntax
tpl = ('item1', 'item2', 'item3','item4')
all_items = tpl[0:4] # all items
all_items = tpl[0:] # all items
middle_two_items = tpl[1:3] # does not include item at index 3
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
all_fruits = fruits[0:4] # all items
all_fruits= fruits[0:] # all items
orange_mango = fruits[1:3] # doesn't include item at index 3
orange_to_the_rest = fruits[1:]
```
- Range of Negative Indexes
```py
# Syntax
tpl = ('item1', 'item2', 'item3','item4')
all_items = tpl[-4:] # all items
middle_two_items = tpl[-3:-1] # does not include item at index 3 (-1)
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
all_fruits = fruits[-4:] # all items
orange_mango = fruits[-3:-1] # doesn't include item at index 3
orange_to_the_rest = fruits[-3:]
```
### Changing Tuples to Lists
We can change tuples to lists and lists to tuples. Tuple is immutable if we want to modify a tuple we should change it to a list.
```py
# Syntax
tpl = ('item1', 'item2', 'item3','item4')
lst = list(tpl)
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
fruits = list(fruits)
fruits[0] = 'apple'
print(fruits) # ['apple', 'orange', 'mango', 'lemon']
fruits = tuple(fruits)
print(fruits) # ('apple', 'orange', 'mango', 'lemon')
```
### Checking an Item in a Tuple
We can check if an item exists or not in a tuple using _in_, it returns a boolean.
```py
# Syntax
tpl = ('item1', 'item2', 'item3','item4')
'item2' in tpl # True
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
print('orange' in fruits) # True
print('apple' in fruits) # False
fruits[0] = 'apple' # TypeError: 'tuple' object does not support item assignment
```
### Joining Tuples
We can join two or more tuples using + operator
```py
# syntax
tpl1 = ('item1', 'item2', 'item3')
tpl2 = ('item4', 'item5','item6')
tpl3 = tpl1 + tpl2
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
vegetables = ('Tomato', 'Potato', 'Cabbage','Onion', 'Carrot')
fruits_and_vegetables = fruits + vegetables
```
### Deleting Tuples
It is not possible to remove a single item in a tuple but it is possible to delete the tuple itself using _del_.
```py
# syntax
tpl1 = ('item1', 'item2', 'item3')
del tpl1
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
del fruits
```
🌕 You are so brave, you made it to this far. You have just completed day 6 challenges and you are 6 steps a head in to your way to greatness. Now do some exercises for your brain and for your muscle.
## 💻 Exercises: Day 6
### Exercises: Level 1
1. Create an empty tuple
2. Create a tuple containing names of your sisters and your brothers (imaginary siblings are fine)
3. Join brothers and sisters tuples and assign it to siblings
4. How many siblings do you have?
5. Modify the siblings tuple and add the name of your father and mother and assign it to family_members
### Exercises: Level 2
1. Unpack siblings and parents from family_members
1. Create fruits, vegetables and animal products tuples. Join the three tuples and assign it to a variable called food_stuff_tp.
1. Change the about food_stuff_tp tuple to a food_stuff_lt list
1. Slice out the middle item or items from the food_stuff_tp tuple or food_stuff_lt list.
1. Slice out the first three items and the last three items from food_stuff_lt list
1. Delete the food_stuff_tp tuple completely
1. Check if an item exists in tuple:
- Check if 'Estonia' is a nordic country
- Check if 'Iceland' is a nordic country
```py
nordic_countries = ('Denmark', 'Finland','Iceland', 'Norway', 'Sweden')
```
[<< Day 5](../05_Day_Lists/05_lists.md) | [Day 7 >>](../07_Day_Sets/07_sets.md)
================================================
FILE: 07_Day_Sets/07_sets.md
================================================
[<< Day 6](../06_Day_Tuples/06_tuples.md) | [Day 8 >>](../08_Day_Dictionaries/08_dictionaries.md)

- [📘 Day 7](#-day-7)
- [Sets](#sets)
- [Creating a Set](#creating-a-set)
- [Getting Set's Length](#getting-sets-length)
- [Accessing Items in a Set](#accessing-items-in-a-set)
- [Checking an Item](#checking-an-item)
- [Adding Items to a Set](#adding-items-to-a-set)
- [Removing Items from a Set](#removing-items-from-a-set)
- [Clearing Items in a Set](#clearing-items-in-a-set)
- [Deleting a Set](#deleting-a-set)
- [Converting List to Set](#converting-list-to-set)
- [Joining Sets](#joining-sets)
- [Finding Intersection Items](#finding-intersection-items)
- [Checking Subset and Super Set](#checking-subset-and-super-set)
- [Checking the Difference Between Two Sets](#checking-the-difference-between-two-sets)
- [Finding Symmetric Difference Between Two Sets](#finding-symmetric-difference-between-two-sets)
- [Joining Sets](#joining-sets-1)
- [💻 Exercises: Day 7](#-exercises-day-7)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# 📘 Day 7
## Sets
Set is a collection of items. Let me take you back to your elementary or high school Mathematics lesson. The Mathematics definition of a set can be applied also in Python. Set is a collection of unordered and un-indexed distinct elements. In Python set is used to store unique items, and it is possible to find the _union_, _intersection_, _difference_, _symmetric difference_, _subset_, _super set_ and _disjoint set_ among sets.
### Creating a Set
To create an empty set, we use the set() function. Empty curly brackets {} will create a dictionary.
- Creating an empty set
```py
# syntax
st = set()
```
- Creating a set with initial items
```py
# syntax
st = {'item1', 'item2', 'item3', 'item4'}
```
**Example:**
```py
# syntax
fruits = {'banana', 'orange', 'mango', 'lemon'}
```
### Getting Set's Length
We use **len()** method to find the length of a set.
```py
# syntax
st = {'item1', 'item2', 'item3', 'item4'}
len(st)
```
**Example:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
len(fruits)
```
### Accessing Items in a Set
We use loops to access items. We will see this in loop section
### Checking an Item
To check if an item exist in a list we use _in_ membership operator.
```py
# syntax
st = {'item1', 'item2', 'item3', 'item4'}
print("Does set st contain item3? ", 'item3' in st) # Does set st contain item3? True
```
**Example:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
print('mango' in fruits ) # True
```
### Adding Items to a Set
Once a set is created we cannot change any items and we can also add additional items.
- Add one item using _add()_
```py
# syntax
st = {'item1', 'item2', 'item3', 'item4'}
st.add('item5')
```
**Example:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
fruits.add('lime')
```
- Add multiple items using _update()_
The _update()_ allows to add multiple items to a set. The _update()_ takes a list argument.
```py
# syntax
st = {'item1', 'item2', 'item3', 'item4'}
st.update(['item5','item6','item7'])
```
**Example:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
vegetables = ('tomato', 'potato', 'cabbage','onion', 'carrot')
fruits.update(vegetables)
```
### Removing Items from a Set
We can remove an item from a set using _remove()_ method. If the item is not found _remove()_ method will raise errors, so it is good to check if the item exist in the given set. However, _discard()_ method doesn't raise any errors.
```py
# syntax
st = {'item1', 'item2', 'item3', 'item4'}
st.remove('item2')
```
The pop() methods remove a random item from a list and it returns the removed item.
**Example:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
fruits.pop() # removes a random item from the set
```
If we are interested in the removed item.
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
removed_item = fruits.pop()
```
### Clearing Items in a Set
If we want to clear or empty the set we use _clear_ method.
```py
# syntax
st = {'item1', 'item2', 'item3', 'item4'}
st.clear()
```
**Example:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
fruits.clear()
print(fruits) # set()
```
### Deleting a Set
If we want to delete the set itself we use _del_ operator.
```py
# syntax
st = {'item1', 'item2', 'item3', 'item4'}
del st
```
**Example:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
del fruits
```
### Converting List to Set
We can convert list to set and set to list. Converting list to set removes duplicates and only unique items will be reserved.
```py
# syntax
lst = ['item1', 'item2', 'item3', 'item4', 'item1']
st = set(lst) # {'item2', 'item4', 'item1', 'item3'} - the order is random, because sets in general are unordered
```
**Example:**
```py
fruits = ['banana', 'orange', 'mango', 'lemon','orange', 'banana']
fruits = set(fruits) # {'mango', 'lemon', 'banana', 'orange'}
```
### Joining Sets
We can join two sets using the _union()_ or _update()_ method or _|_ symbol .
- Union
This method returns a new set
```py
# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item5', 'item6', 'item7', 'item8'}
st3 = st1.union(st2) #st3 = st1 | st2
```
**Example:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
vegetables = {'tomato', 'potato', 'cabbage','onion', 'carrot'}
print(fruits.union(vegetables)) # {'lemon', 'carrot', 'tomato', 'banana', 'mango', 'orange', 'cabbage', 'potato', 'onion'}
# or using this : print(fruits | vegetables)
```
- Update
This method inserts a set into a given set
```py
# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item5', 'item6', 'item7', 'item8'}
st1.update(st2) # st2 contents are added to st1
```
**Example:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
vegetables = {'tomato', 'potato', 'cabbage','onion', 'carrot'}
fruits.update(vegetables)
print(fruits) # {'lemon', 'carrot', 'tomato', 'banana', 'mango', 'orange', 'cabbage', 'potato', 'onion'}
```
### Finding Intersection Items
Intersection returns a set of items which are in both the sets or using _&_ symbol. See the example
```py
# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item3', 'item2'}
st1.intersection(st2) # {'item3', 'item2'}
# or using thia : st1 & st2
```
**Example:**
```py
whole_numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
even_numbers = {0, 2, 4, 6, 8, 10}
whole_numbers.intersection(even_numbers) # {0, 2, 4, 6, 8, 10}
python = {'p', 'y', 't', 'h', 'o','n'}
dragon = {'d', 'r', 'a', 'g', 'o','n'}
python.intersection(dragon) # {'o', 'n'}
# python & dragon
```
### Checking Subset and Super Set
A set can be a subset or super set of other sets:
- Subset: _issubset()_
- Super set: _issuperset_
```py
# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item2', 'item3'}
st2.issubset(st1) # True
st1.issuperset(st2) # True
```
**Example:**
```py
whole_numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
even_numbers = {0, 2, 4, 6, 8, 10}
whole_numbers.issubset(even_numbers) # False, because it is a super set
whole_numbers.issuperset(even_numbers) # True
python = {'p', 'y', 't', 'h', 'o','n'}
dragon = {'d', 'r', 'a', 'g', 'o','n'}
python.issubset(dragon) # False
```
### Checking the Difference Between Two Sets
It returns the difference between two sets or using _-_ symbol .
```py
# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item2', 'item3'}
st2.difference(st1) # set() : st2 - st1
st1.difference(st2) # {'item1', 'item4'} => st1\st2 : st2 - st1
```
**Example:**
```py
whole_numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
even_numbers = {0, 2, 4, 6, 8, 10}
whole_numbers.difference(even_numbers) # {1, 3, 5, 7, 9}
python = {'p', 'y', 't', 'o','n'}
dragon = {'d', 'r', 'a', 'g', 'o','n'}
python.difference(dragon) # {'p', 'y', 't'} - the result is unordered (characteristic of sets)
# python - dragon
dragon.difference(python) # {'d', 'r', 'a', 'g'}
# dragon - python
```
### Finding Symmetric Difference Between Two Sets
It returns the symmetric difference between two sets. It means that it returns a set that contains all items from both sets, except items that are present in both sets, mathematically: (A\B) ∪ (B\A)
```py
# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item2', 'item3'}
# it means (A\B)∪(B\A)
st2.symmetric_difference(st1) # {'item1', 'item4'} : st2 ^ st1
```
**Example:**
```py
whole_numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
some_numbers = {1, 2, 3, 4, 5}
whole_numbers.symmetric_difference(some_numbers) # {0, 6, 7, 8, 9, 10}
python = {'p', 'y', 't', 'h', 'o','n'}
dragon = {'d', 'r', 'a', 'g', 'o','n'}
python.symmetric_difference(dragon) # {'r', 't', 'p', 'y', 'g', 'a', 'd', 'h'}
# python ^ dragon
```
### Joining Sets
If two sets do not have a common item or items we call them disjoint sets. We can check if two sets are joint or disjoint using _isdisjoint()_ method.
```py
# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item2', 'item3'}
st2.isdisjoint(st1) # False
```
**Example:**
```py
even_numbers = {0, 2, 4 ,6, 8}
odd_numbers = {1, 3, 5, 7, 9}
even_numbers.isdisjoint(odd_numbers) # True, because no common item
python = {'p', 'y', 't', 'h', 'o','n'}
dragon = {'d', 'r', 'a', 'g', 'o','n'}
python.isdisjoint(dragon) # False, there are common items {'o', 'n'}
```
🌕 You are a rising star . You have just completed day 7 challenges and you are 7 steps ahead in to your way to greatness. Now do some exercises for your brain and muscles.
## 💻 Exercises: Day 7
```py
# sets
it_companies = {'Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon'}
A = {19, 22, 24, 20, 25, 26}
B = {19, 22, 20, 25, 26, 24, 28, 27}
age = [22, 19, 24, 25, 26, 24, 25, 24]
```
### Exercises: Level 1
1. Find the length of the set it_companies
2. Add 'Twitter' to it_companies
3. Insert multiple IT companies at once to the set it_companies
4. Remove one of the companies from the set it_companies
5. What is the difference between remove and discard
### Exercises: Level 2
1. Join A and B
2. Find A intersection B
3. Is A subset of B
4. Are A and B disjoint sets
5. Join A with B and B with A
6. What is the symmetric difference between A and B
7. Delete the sets completely
### Exercises: Level 3
1. Convert the ages to a set and compare the length of the list and the set, which one is bigger?
2. Explain the difference between the following data types: string, list, tuple and set
3. _I am a teacher and I love to inspire and teach people._ How many unique words have been used in the sentence? Use the split methods and set to get the unique words.
🎉 CONGRATULATIONS ! 🎉
[<< Day 6](../06_Day_Tuples/06_tuples.md) | [Day 8 >>](../08_Day_Dictionaries/08_dictionaries.md)
================================================
FILE: 08_Day_Dictionaries/08_dictionaries.md
================================================
[<< Day 7 ](../07_Day_Sets/07_sets.md) | [Day 9 >>](../09_Day_Conditionals/09_conditionals.md)

- [📘 Day 8](#-day-8)
- [Dictionaries](#dictionaries)
- [Creating a Dictionary](#creating-a-dictionary)
- [Dictionary Length](#dictionary-length)
- [Accessing Dictionary Items](#accessing-dictionary-items)
- [Adding Items to a Dictionary](#adding-items-to-a-dictionary)
- [Modifying Items in a Dictionary](#modifying-items-in-a-dictionary)
- [Checking Keys in a Dictionary](#checking-keys-in-a-dictionary)
- [Removing Key and Value Pairs from a Dictionary](#removing-key-and-value-pairs-from-a-dictionary)
- [Changing Dictionary to a List of Items](#changing-dictionary-to-a-list-of-items)
- [Clearing a Dictionary](#clearing-a-dictionary)
- [Deleting a Dictionary](#deleting-a-dictionary)
- [Copy a Dictionary](#copy-a-dictionary)
- [Getting Dictionary Keys as a List](#getting-dictionary-keys-as-a-list)
- [Getting Dictionary Values as a List](#getting-dictionary-values-as-a-list)
- [💻 Exercises: Day 8](#-exercises-day-8)
# 📘 Day 8
## Dictionaries
A dictionary is a collection of unordered, modifiable(mutable) paired (key: value) data type.
### Creating a Dictionary
To create a dictionary we use curly brackets, {} or the *dict()* built-in function.
```py
# syntax
empty_dict = {}
# Dictionary with data values
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
```
**Example:**
```py
person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_marred':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
```
The dictionary above shows that a value could be any data types:string, boolean, list, tuple, set or a dictionary.
### Dictionary Length
It checks the number of 'key: value' pairs in the dictionary.
```py
# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
print(len(dct)) # 4
```
**Example:**
```py
person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_married':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
print(len(person)) # 7
```
### Accessing Dictionary Items
We can access Dictionary items by referring to its key name.
```py
# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
print(dct['key1']) # value1
print(dct['key4']) # value4
```
**Example:**
```py
person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_marred':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
print(person['first_name']) # Asabeneh
print(person['country']) # Finland
print(person['skills']) # ['JavaScript', 'React', 'Node', 'MongoDB', 'Python']
print(person['skills'][0]) # JavaScript
print(person['address']['street']) # Space street
print(person['city']) # Error
```
Accessing an item by key name raises an error if the key does not exist. To avoid this error first we have to check if a key exist or we can use the _get_ method. The get method returns None, which is a NoneType object data type, if the key does not exist.
```py
person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_marred':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
print(person.get('first_name')) # Asabeneh
print(person.get('country')) # Finland
print(person.get('skills')) #['JavaScript', 'React', 'Node', 'MongoDB', 'Python']
print(person.get('city')) # None
```
### Adding Items to a Dictionary
We can add new key and value pairs to a dictionary
```py
# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
dct['key5'] = 'value5'
```
**Example:**
```py
person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_marred':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
person['job_title'] = 'Instructor'
person['skills'].append('HTML')
print(person)
```
### Modifying Items in a Dictionary
We can modify items in a dictionary
```py
# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
dct['key1'] = 'value-one'
```
**Example:**
```py
person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_marred':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
person['first_name'] = 'Eyob'
person['age'] = 252
```
### Checking Keys in a Dictionary
We use the _in_ operator to check if a key exist in a dictionary
```py
# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
print('key2' in dct) # True
print('key5' in dct) # False
```
### Removing Key and Value Pairs from a Dictionary
- _pop(key)_: removes the item with the specified key name:
- _popitem()_: removes the last item
- _del_: removes an item with specified key name
```py
# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
dct.pop('key1') # removes key1 item
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
dct.popitem() # removes the last item
del dct['key2'] # removes key2 item
```
**Example:**
```py
person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_marred':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
person.pop('first_name') # Removes the firstname item
person.popitem() # Removes the address item
del person['is_married'] # Removes the is_married item
```
### Changing Dictionary to a List of Items
The _items()_ method changes dictionary to a list of tuples.
```py
# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
print(dct.items()) # dict_items([('key1', 'value1'), ('key2', 'value2'), ('key3', 'value3'), ('key4', 'value4')])
```
### Clearing a Dictionary
If we don't want the items in a dictionary we can clear them using _clear()_ method
```py
# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
print(dct.clear()) # None
```
### Deleting a Dictionary
If we do not use the dictionary we can delete it completely
```py
# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
del dct
```
### Copy a Dictionary
We can copy a dictionary using a _copy()_ method. Using copy we can avoid mutation of the original dictionary.
```py
# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
dct_copy = dct.copy() # {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
```
### Getting Dictionary Keys as a List
The _keys()_ method gives us all the keys of a a dictionary as a list.
```py
# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
keys = dct.keys()
print(keys) # dict_keys(['key1', 'key2', 'key3', 'key4'])
```
### Getting Dictionary Values as a List
The _values_ method gives us all the values of a a dictionary as a list.
```py
# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
values = dct.values()
print(values) # dict_values(['value1', 'value2', 'value3', 'value4'])
```
🌕 You are astonishing. Now, you are super charged with the power of dictionaries. You have just completed day 8 challenges and you are 8 steps a head in to your way to greatness. Now do some exercises for your brain and muscles.
## 💻 Exercises: Day 8
1. Create an empty dictionary called dog
2. Add name, color, breed, legs, age to the dog dictionary
3. Create a student dictionary and add first_name, last_name, gender, age, marital status, skills, country, city and address as keys for the dictionary
4. Get the length of the student dictionary
5. Get the value of skills and check the data type, it should be a list
6. Modify the skills values by adding one or two skills
7. Get the dictionary keys as a list
8. Get the dictionary values as a list
9. Change the dictionary to a list of tuples using _items()_ method
10. Delete one of the items in the dictionary
11. Delete one of the dictionaries
🎉 CONGRATULATIONS ! 🎉
[<< Day 7 ](../07_Day_Sets/07_sets.md) | [Day 9 >>](../09_Day_Conditionals/09_conditionals.md)
================================================
FILE: 09_Day_Conditionals/09_conditionals.md
================================================
[<< Day 8](../08_Day_Dictionaries/08_dictionaries.md) | [Day 10 >>](../10_Day_Loops/10_loops.md)

- [📘 Day 9](#-day-9)
- [Conditionals](#conditionals)
- [If Condition](#if-condition)
- [If Else](#if-else)
- [If Elif Else](#if-elif-else)
- [Short Hand](#short-hand)
- [Nested Conditions](#nested-conditions)
- [If Condition and Logical Operators](#if-condition-and-logical-operators)
- [If and Or Logical Operators](#if-and-or-logical-operators)
- [💻 Exercises: Day 9](#-exercises-day-9)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# 📘 Day 9
## Conditionals
By default, statements in Python script are executed sequentially from top to bottom. If the processing logic require so, the sequential flow of execution can be altered in two way:
- Conditional execution: a block of one or more statements will be executed if a certain expression is true
- Repetitive execution: a block of one or more statements will be repetitively executed as long as a certain expression is true. In this section, we will cover _if_, _else_, _elif_ statements. The comparison and logical operators we learned in previous sections will be useful here.
### If Condition
In python and other programming languages the key word _if_ is used to check if a condition is true and to execute the block code. Remember the indentation after the colon.
```py
# syntax
if condition:
this part of code runs for truthy conditions
```
**Example: 1**
```py
a = 3
if a > 0:
print('A is a positive number')
# A is a positive number
```
As you can see in the example above, 3 is greater than 0. The condition was true and the block code was executed. However, if the condition is false, we do not see the result. In order to see the result of the falsy condition, we should have another block, which is going to be _else_.
### If Else
If condition is true the first block will be executed, if not the else condition will run.
```py
# syntax
if condition:
this part of code runs for truthy conditions
else:
this part of code runs for false conditions
```
**Example:**
```py
a = 3
if a < 0:
print('A is a negative number')
else:
print('A is a positive number')
```
The condition above proves false, therefore the else block was executed. How about if our condition is more than two? We could use _elif_.
### If Elif Else
In our daily life, we make decisions on daily basis. We make decisions not by checking one or two conditions but multiple conditions. As similar to life, programming is also full of conditions. We use _elif_ when we have multiple conditions.
```py
# syntax
if condition:
code
elif condition:
code
else:
code
```
**Example:**
```py
a = 0
if a > 0:
print('A is a positive number')
elif a < 0:
print('A is a negative number')
else:
print('A is zero')
```
### Short Hand
```py
# syntax
code if condition else code
```
**Example:**
```py
a = 3
print('A is positive') if a > 0 else print('A is negative') # first condition met, 'A is positive' will be printed
```
### Nested Conditions
Conditions can be nested
```py
# syntax
if condition:
code
if condition:
code
```
**Example:**
```py
a = 0
if a > 0:
if a % 2 == 0:
print('A is a positive and even integer')
else:
print('A is a positive number')
elif a == 0:
print('A is zero')
else:
print('A is a negative number')
```
We can avoid writing nested condition by using logical operator _and_.
### If Condition and Logical Operators
```py
# syntax
if condition and condition:
code
```
**Example:**
```py
a = 0
if a > 0 and a % 2 == 0:
print('A is an even and positive integer')
elif a > 0 and a % 2 != 0:
print('A is a positive integer')
elif a == 0:
print('A is zero')
else:
print('A is negative')
```
### If and Or Logical Operators
```py
# syntax
if condition or condition:
code
```
**Example:**
```py
user = 'James'
access_level = 3
if user == 'admin' or access_level >= 4:
print('Access granted!')
else:
print('Access denied!')
```
🌕 You are doing great.Never give up because great things take time. You have just completed day 9 challenges and you are 9 steps a head in to your way to greatness. Now do some exercises for your brain and muscles.
## 💻 Exercises: Day 9
### Exercises: Level 1
1. Get user input using input(“Enter your age: ”). If user is 18 or older, give feedback: You are old enough to drive. If below 18 give feedback to wait for the missing amount of years. Output:
```sh
Enter your age: 30
You are old enough to learn to drive.
Output:
Enter your age: 15
You need 3 more years to learn to drive.
```
2. Compare the values of my_age and your_age using if … else. Who is older (me or you)? Use input(“Enter your age: ”) to get the age as input. You can use a nested condition to print 'year' for 1 year difference in age, 'years' for bigger differences, and a custom text if my_age = your_age. Output:
```sh
Enter your age: 30
You are 5 years older than me.
```
3. Get two numbers from the user using input prompt. If a is greater than b return a is greater than b, if a is less b return a is smaller than b, else a is equal to b. Output:
```sh
Enter number one: 4
Enter number two: 3
4 is greater than 3
```
### Exercises: Level 2
1. Write a code which gives grade to students according to theirs scores:
```sh
90-100, A
80-89, B
70-79, C
60-69, D
0-59, F
```
2. Get the month from user input then check if the season is Autumn, Winter, Spring or Summer. If the user input is:
September, October or November, the season is Autumn.
December, January or February, the season is Winter.
March, April or May, the season is Spring
June, July or August, the season is Summer
3. The following list contains some fruits:
```sh
fruits = ['banana', 'orange', 'mango', 'lemon']
```
If a fruit doesn't exist in the list add the fruit to the list and print the modified list. If the fruit exists print('That fruit already exist in the list')
### Exercises: Level 3
1. Here we have a person dictionary. Feel free to modify it!
```py
person={
'first_name': 'Asabeneh',
'last_name': 'Yetayeh',
'age': 250,
'country': 'Finland',
'is_married': True,
'skills': ['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address': {
'street': 'Space street',
'zipcode': '02210'
}
}
```
* Check if the person dictionary has skills key, if so print out the middle skill in the skills list.
* Check if the person dictionary has skills key, if so check if the person has 'Python' skill and print out the result.
* If a person skills has only JavaScript and React, print('He is a front end developer'), if the person skills has Node, Python, MongoDB, print('He is a backend developer'), if the person skills has React, Node and MongoDB, Print('He is a fullstack developer'), else print('unknown title') - for more accurate results more conditions can be nested!
* If the person is married and if he lives in Finland, print the information in the following format:
```py
Asabeneh Yetayeh lives in Finland. He is married.
```
🎉 CONGRATULATIONS ! 🎉
[<< Day 8](../08_Day_Dictionaries/08_dictionaries.md) | [Day 10 >>](../10_Day_Loops/10_loops.md)
================================================
FILE: 10_Day_Loops/10_loops.md
================================================
[<< Day 9](../09_Day_Conditionals/09_conditionals.md) | [Day 11 >>](../11_Day_Functions/11_functions.md)

- [📘 Day 10](#-day-10)
- [Loops](#loops)
- [While Loop](#while-loop)
- [Break and Continue - Part 1](#break-and-continue---part-1)
- [For Loop](#for-loop)
- [Break and Continue - Part 2](#break-and-continue---part-2)
- [The Range Function](#the-range-function)
- [Nested For Loop](#nested-for-loop)
- [For Else](#for-else)
- [Pass](#pass)
- [💻 Exercises: Day 10](#-exercises-day-10)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# 📘 Day 10
## Loops
Life is full of routines. In programming we also do lots of repetitive tasks. In order to handle repetitive task programming languages use loops. Python programming language also provides the following types of two loops:
1. while loop
2. for loop
### While Loop
We use the reserved word _while_ to make a while loop. It is used to execute a block of statements repeatedly until a given condition is satisfied. When the condition becomes false, the lines of code after the loop will be continued to be executed.
```py
# syntax
while condition:
code goes here
```
**Example:**
```py
count = 0
while count < 5:
print(count)
count = count + 1
#prints from 0 to 4
```
In the above while loop, the condition becomes false when count is 5. That is when the loop stops.
If we are interested to run block of code once the condition is no longer true, we can use _else_.
```py
# syntax
while condition:
code goes here
else:
code goes here
```
**Example:**
```py
count = 0
while count < 5:
print(count)
count = count + 1
else:
print(count)
```
The above loop condition will be false when count is 5 and the loop stops, and execution starts the else statement. As a result 5 will be printed.
### Break and Continue - Part 1
- Break: We use break when we like to get out of or stop the loop.
```py
# syntax
while condition:
code goes here
if another_condition:
break
```
**Example:**
```py
count = 0
while count < 5:
print(count)
count = count + 1
if count == 3:
break
```
The above while loop only prints 0, 1, 2, but when it reaches 3 it stops.
- Continue: With the continue statement we can skip the current iteration, and continue with the next:
```py
# syntax
while condition:
code goes here
if another_condition:
continue
```
**Example:**
```py
count = 0
while count < 5:
if count == 3:
count += 1
continue
print(count)
count = count + 1
```
The above while loop only prints 0, 1, 2 and 4 (skips 3).
### For Loop
A _for_ keyword is used to make a for loop, similar with other programming languages, but with some syntax differences. Loop is used for iterating over a sequence (that is either a list, a tuple, a dictionary, a set, or a string).
-Using For loop on list
```py
# syntax
for iterator in lst:
code goes here
```
**Example:**
```py
numbers = [0, 1, 2, 3, 4, 5]
for number in numbers: # number is temporary name to refer to the list's items, valid only inside this loop
print(number) # the numbers will be printed line by line, from 0 to 5
```
-Using For loop on string
```py
# syntax
for iterator in string:
code goes here
```
**Example:**
```py
language = 'Python'
for letter in language:
print(letter)
for i in range(len(language)):
print(language[i])
```
-Using For loop on tuple
```py
# syntax
for iterator in tpl:
code goes here
```
**Example:**
```py
numbers = (0, 1, 2, 3, 4, 5)
for number in numbers:
print(number)
```
- For loop with dictionary
Looping through a dictionary gives you the key of the dictionary.
```py
# syntax
for iterator in dct:
code goes here
```
**Example:**
```py
person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_marred':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
for key in person:
print(key)
for key, value in person.items():
print(key, value) # this way we get both keys and values printed out
```
-Using For Loop in set
```py
# syntax
for iterator in st:
code goes here
```
**Example:**
```py
it_companies = {'Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon'}
for company in it_companies:
print(company)
```
### Break and Continue - Part 2
Short reminder:
_Break_: We use break when we want to stop our loop before it is completed.
```py
# syntax
for iterator in sequence:
code goes here
if condition:
break
```
**Example:**
```py
numbers = (0,1,2,3,4,5)
for number in numbers:
print(number)
if number == 3:
break
```
In the above example, the loop stops when it reaches 3.
Continue: We use continue when we want to skip some of the steps in the iteration of the loop.
```py
# syntax
for iterator in sequence:
code goes here
if condition:
continue
```
**Example:**
```py
numbers = (0,1,2,3,4,5)
for number in numbers:
print(number)
if number == 3:
continue
print('Next number should be ', number + 1) if number != 5 else print("loop's end") # for short hand conditions need both if and else statements
print('outside the loop')
```
In the example above, if the number equals 3, the step _after_ the condition (but inside the loop) is skipped and the execution of the loop continues if there are any iterations left.
### The Range Function
The _range()_ function is used to return a list of numbers. The _range(start, end, step)_ takes three parameters: starting, ending and increment. By default it starts from 0 and the increment is 1. The range sequence needs at least 1 argument (end).
Creating sequences using range
```py
lst = list(range(11))
print(lst) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
st = set(range(1, 11)) # 2 arguments indicate start and end of the sequence, step set to default 1
print(st) # {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
lst = list(range(0,11,2))
print(lst) # [0, 2, 4, 6, 8, 10]
st = set(range(0,11,2))
print(st) # {0, 2, 4, 6, 8, 10}
# for backward from start to end
lst = list(range(11,0,-2))
print(lst) # [11,9,7,5,3,1]
```
```py
# syntax
for iterator in range(start, end, step):
```
**Example:**
```py
for number in range(11):
print(number) # prints 0 to 10, not including 11
```
### Nested For Loop
We can write loops inside a loop.
```py
# syntax
for x in y:
for t in x:
print(t)
```
**Example:**
```py
person = {
'first_name': 'Asabeneh',
'last_name': 'Yetayeh',
'age': 250,
'country': 'Finland',
'is_marred': True,
'skills': ['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address': {
'street': 'Space street',
'zipcode': '02210'
}
}
for key in person:
if key == 'skills':
for skill in person['skills']:
print(skill)
```
### For Else
If we want to execute some message when the loop ends, we use else.
```py
# syntax
for iterator in range(start, end, step):
do something
else:
print('The loop ended')
```
**Example:**
```py
for number in range(11):
print(number) # prints 0 to 10, not including 11
else:
print('The loop stops at', number)
```
### Pass
In python when statement is required (after semicolon), but we don't like to execute any code there, we can write the word _pass_ to avoid errors. Also we can use it as a placeholder, for future statements.
**Example:**
```py
for number in range(6):
pass
```
🌕 You established a big milestone, you are unstoppable. Keep going! You have just completed day 10 challenges and you are 10 steps a head in to your way to greatness. Now do some exercises for your brain and muscles.
## 💻 Exercises: Day 10
### Exercises: Level 1
1. Iterate 0 to 10 using for loop, do the same using while loop.
2. Iterate 10 to 0 using for loop, do the same using while loop.
3. Write a loop that makes seven calls to print(), so we get on the output the following triangle:
```py
#
##
###
####
#####
######
#######
```
4. Use nested loops to create the following:
```sh
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
```
5. Print the following pattern:
```sh
0 x 0 = 0
1 x 1 = 1
2 x 2 = 4
3 x 3 = 9
4 x 4 = 16
5 x 5 = 25
6 x 6 = 36
7 x 7 = 49
8 x 8 = 64
9 x 9 = 81
10 x 10 = 100
```
6. Iterate through the list, ['Python', 'Numpy','Pandas','Django', 'Flask'] using a for loop and print out the items.
7. Use for loop to iterate from 0 to 100 and print only even numbers
8. Use for loop to iterate from 0 to 100 and print only odd numbers
### Exercises: Level 2
1. Use for loop to iterate from 0 to 100 and print the sum of all numbers.
```sh
The sum of all numbers is 5050.
```
2. Use for loop to iterate from 0 to 100 and print the sum of all evens and the sum of all odds.
```sh
The sum of all evens is 2550. And the sum of all odds is 2500.
```
### Exercises: Level 3
1. Go to the data folder and use the [countries.py](https://github.com/Asabeneh/30-Days-Of-Python/blob/master/data/countries.py) file. Loop through the countries and extract all the countries containing the word _land_.
1. This is a fruit list, ['banana', 'orange', 'mango', 'lemon'] reverse the order using loop.
1. Go to the data folder and use the [countries_data.py](https://github.com/Asabeneh/30-Days-Of-Python/blob/master/data/countries-data.py) file.
1. What are the total number of languages in the data
2. Find the ten most spoken languages from the data
3. Find the 10 most populated countries in the world
🎉 CONGRATULATIONS ! 🎉
[<< Day 9](../09_Day_Conditionals/09_conditionals.md) | [Day 11 >>](../11_Day_Functions/11_functions.md)
================================================
FILE: 11_Day_Functions/11_functions.md
================================================
[<< Day 10](../10_Day_Loops/10_loops.md) | [Day 12 >>](../12_Day_Modules/12_modules.md)

- [📘 Day 11](#-day-11)
- [Functions](#functions)
- [Defining a Function](#defining-a-function)
- [Declaring and Calling a Function](#declaring-and-calling-a-function)
- [Function without Parameters](#function-without-parameters)
- [Function Returning a Value - Part 1](#function-returning-a-value---part-1)
- [Function with Parameters](#function-with-parameters)
- [Passing Arguments with Key and Value](#passing-arguments-with-key-and-value)
- [Function Returning a Value - Part 2](#function-returning-a-value---part-2)
- [Function with Default Parameters](#function-with-default-parameters)
- [Arbitrary Number of Arguments](#arbitrary-number-of-arguments)
- [Default and Arbitrary Number of Parameters in Functions](#default-and-arbitrary-number-of-parameters-in-functions)
- [Function as a Parameter of Another Function](#function-as-a-parameter-of-another-function)
- [Testimony](#testimony)
- [💻 Exercises: Day 11](#-exercises-day-11)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# 📘 Day 11
## Functions
So far we have seen many built-in Python functions. In this section, we will focus on custom functions. What is a function? Before we start making functions, let us learn what a function is and why we need them?
### Defining a Function
A function is a reusable block of code or programming statements designed to perform a certain task. To define or declare a function, Python provides the _def_ keyword. The following is the syntax for defining a function. The function block of code is executed only if the function is called or invoked.
### Declaring and Calling a Function
When we make a function, we call it declaring a function. When we start using the it, we call it _calling_ or _invoking_ a function. Functions can be declared with or without parameters.
```py
# syntax
# Declaring a function
def function_name():
codes
codes
# Calling a function
function_name()
```
### Function without Parameters
Function can be declared without parameters.
**Example:**
```py
def generate_full_name ():
first_name = 'Asabeneh'
last_name = 'Yetayeh'
space = ' '
full_name = first_name + space + last_name
print(full_name)
generate_full_name () # calling a function
def add_two_numbers ():
num_one = 2
num_two = 3
total = num_one + num_two
print(total)
add_two_numbers()
```
### Function Returning a Value - Part 1
Functions return values using the _return_ statement. If a function has no return statement, it returns None. Let us rewrite the above functions using return. From now on, we get a value from a function when we call the function and print it.
```py
def generate_full_name ():
first_name = 'Asabeneh'
last_name = 'Yetayeh'
space = ' '
full_name = first_name + space + last_name
return full_name
print(generate_full_name())
def add_two_numbers ():
num_one = 2
num_two = 3
total = num_one + num_two
return total
print(add_two_numbers())
```
### Function with Parameters
In a function we can pass different data types(number, string, boolean, list, tuple, dictionary or set) as parameters.
- Single Parameter: If our function takes a parameter we should call our function with an argument
```py
# syntax
# Declaring a function
def function_name(parameter):
codes
codes
# Calling function
print(function_name(argument))
```
**Example:**
```py
def greetings (name):
message = name + ', welcome to Python for Everyone!'
return message
print(greetings('Asabeneh'))
def add_ten(num):
ten = 10
return num + ten
print(add_ten(90))
def square_number(x):
return x * x
print(square_number(2))
def area_of_circle (r):
PI = 3.14
area = PI * r ** 2
return area
print(area_of_circle(10))
def sum_of_numbers(n):
total = 0
for i in range(n+1):
total+=i
return total
print(sum_of_numbers(10)) # 55
print(sum_of_numbers(100)) # 5050
```
- Two Parameter: A function may or may not have a parameter or parameters. A function may also have two or more parameters. If our function takes parameters we should call it with arguments. Let us check a function with two parameters:
```py
# syntax
# Declaring a function
def function_name(para1, para2):
codes
codes
# Calling function
print(function_name(arg1, arg2))
```
**Example:**
```py
def generate_full_name (first_name, last_name):
space = ' '
full_name = first_name + space + last_name
return full_name
print('Full Name: ', generate_full_name('Asabeneh','Yetayeh'))
def sum_two_numbers (num_one, num_two):
sum = num_one + num_two
return sum
print('Sum of two numbers: ', sum_two_numbers(1, 9))
def calculate_age (current_year, birth_year):
age = current_year - birth_year
return age
print('Age: ', calculate_age(2021, 1819))
def weight_of_object (mass, gravity):
weight = str(mass * gravity)+ ' N' # the value has to be changed to a string first
return weight
print('Weight of an object in Newtons: ', weight_of_object(100, 9.81))
```
### Passing Arguments with Key and Value
If we pass the arguments with key and value, the order of the arguments does not matter.
```py
# syntax
# Declaring a function
def function_name(para1, para2):
codes
codes
# Calling function
print(function_name(para1 = 'John', para2 = 'Doe')) # the order of arguments does not matter here
```
**Example:**
```py
def print_fullname(firstname, lastname):
space = ' '
full_name = firstname + space + lastname
print(full_name)
print_fullname(firstname = 'Asabeneh', lastname = 'Yetayeh')
def add_two_numbers (num1, num2):
total = num1 + num2
return total
print(add_two_numbers(num2 = 3, num1 = 2)) # Order does not matter
```
### Function Returning a Value - Part 2
If we do not return a value with a function, then our function is returning _None_ by default. To return a value with a function we use the keyword _return_ followed by the variable we are returning. We can return any kind of data types from a function.
- Returning a string:
**Example:**
```py
def print_name(firstname):
return firstname
print_name('Asabeneh') # Asabeneh
def print_full_name(firstname, lastname):
space = ' '
full_name = firstname + space + lastname
return full_name
print_full_name(firstname='Asabeneh', lastname='Yetayeh')
```
- Returning a number:
**Example:**
```py
def add_two_numbers (num1, num2):
total = num1 + num2
return total
print(add_two_numbers(2, 3))
def calculate_age (current_year, birth_year):
age = current_year - birth_year
return age
print('Age: ', calculate_age(2019, 1819))
```
- Returning a boolean:
**Example:**
```py
def is_even (n):
if n % 2 == 0:
return True # return stops further execution of the function, similar to break
return False
print(is_even(10)) # True
print(is_even(7)) # False
```
- Returning a list:
**Example:**
```py
def find_even_numbers(n):
evens = []
for i in range(n + 1):
if i % 2 == 0:
evens.append(i)
return evens
print(find_even_numbers(10))
```
### Function with Default Parameters
Sometimes we pass default values to parameters, when we invoke the function. If we do not pass arguments when calling the function, their default values will be used.
```py
# syntax
# Declaring a function
def function_name(param = value):
codes
codes
# Calling function
function_name()
function_name(arg)
```
**Example:**
```py
def greetings (name = 'Peter'):
message = name + ', welcome to Python for Everyone!'
return message
print(greetings())
print(greetings('Asabeneh'))
def generate_full_name (first_name = 'Asabeneh', last_name = 'Yetayeh'):
space = ' '
full_name = first_name + space + last_name
return full_name
print(generate_full_name())
print(generate_full_name('David','Smith'))
def calculate_age (birth_year,current_year = 2021):
age = current_year - birth_year
return age
print('Age: ', calculate_age(1821))
def weight_of_object (mass, gravity = 9.81):
weight = str(mass * gravity)+ ' N' # the value has to be changed to string first
return weight
print('Weight of an object in Newtons: ', weight_of_object(100)) # 9.81 - average gravity on Earth's surface
print('Weight of an object in Newtons: ', weight_of_object(100, 1.62)) # gravity on the surface of the Moon
```
### Arbitrary Number of Arguments
If we do not know the number of arguments we pass to our function, we can create a function which can take arbitrary number of arguments by adding \* before the parameter name.
```py
# syntax
# Declaring a function
def function_name(*args):
codes
codes
# Calling function
function_name(param1, param2, param3,..)
```
**Example:**
```py
def sum_all_nums(*nums):
total = 0
for num in nums:
total += num # same as total = total + num
return total
print(sum_all_nums(2, 3, 5)) # 10
```
### Default and Arbitrary Number of Parameters in Functions
```py
def generate_groups (team,*args):
print(team)
for i in args:
print(i)
generate_groups('Team-1','Asabeneh','Brook','David','Eyob')
```
### Dictionary unpacking
You can call a function which has named arguments using a dictionary with matching key names. You do so using ``**``.
```py
# Define a function that takes two arguments: 'name' and 'location'
def greet(name, location):
# Print a greeting message using the provided arguments
print("Hi there", name, "how is the weather in", location)
# Call the function using keyword arguments
greet(name="Alice", location="New York")
# Output: Hi there Alice how is the weather in New York
# Create a dictionary with keys matching the function's parameter names
my_dict = {"name": "Alice", "location": "New York"}
# Call the function using dictionary unpacking
greet(**my_dict)
# The ** operator unpacks the dictionary, passing its key-value pairs
# as keyword arguments to the function.
# Output: Hi there Alice how is the weather in New York
```
### Arbitrary Number of Named Arguments
You can also define a function to accept an arbitrary number of named arguments.
```py
def arbitrary_named_args(**args):
print("I received an arbitrary number of arguments, totaling", len(args))
print("They are provided as a dictionary in my function:", type(args))
print("Let's print them:")
for k, v in args.items():
print(" * key:", k, "value:", v)
```
Generally avoid this unless required as it makes it harder to understand what the function accepts and does.
### Function as a Parameter of Another Function
```py
#You can pass functions around as parameters
def square_number (n):
return n ** n
def do_something(f, x):
return f(x)
print(do_something(square_number, 3)) # 27
```
🌕 You achieved quite a lot so far. Keep going! You have just completed day 11 challenges and you are 11 steps a head in to your way to greatness. Now do some exercises for your brain and muscles.
## Testimony
Now it is time to express your thoughts about the Author and 30DaysOfPython. You can leave your testimonial on this [link](https://testimonial-s3sw.onrender.com/)
## 💻 Exercises: Day 11
### Exercises: Level 1
1. Declare a function _add_two_numbers_. It takes two parameters and it returns a sum.
2. Area of a circle is calculated as follows: area = π x r x r. Write a function that calculates _area_of_circle_.
3. Write a function called add_all_nums which takes arbitrary number of arguments and sums all the arguments. Check if all the list items are number types. If not do give a reasonable feedback.
4. Temperature in °C can be converted to °F using this formula: °F = (°C x 9/5) + 32. Write a function which converts °C to °F, _convert_celsius_to-fahrenheit_.
5. Write a function called check-season, it takes a month parameter and returns the season: Autumn, Winter, Spring or Summer.
6. Write a function called calculate_slope which return the slope of a linear equation
7. Quadratic equation is calculated as follows: ax² + bx + c = 0. Write a function which calculates solution set of a quadratic equation, _solve_quadratic_eqn_.
8. Declare a function named print_list. It takes a list as a parameter and it prints out each element of the list.
9. Declare a function named reverse_list. It takes an array as a parameter and it returns the reverse of the array (use loops).
```py
print(reverse_list([1, 2, 3, 4, 5]))
# [5, 4, 3, 2, 1]
print(reverse_list(["A", "B", "C"]))
# ["C", "B", "A"]
```
10. Declare a function named capitalize_list_items. It takes a list as a parameter and it returns a capitalized list of items
11. Declare a function named add_item. It takes a list and an item parameters. It returns a list with the item added at the end.
```py
food_stuff = ['Potato', 'Tomato', 'Mango', 'Milk'];
print(add_item(food_stuff, 'Meat')) # ['Potato', 'Tomato', 'Mango', 'Milk','Meat'];
numbers = [2, 3, 7, 9];
print(add_item(numbers, 5)) # [2, 3, 7, 9, 5]
```
12. Declare a function named remove_item. It takes a list and an item parameters. It returns a list with the item removed from it.
```py
food_stuff = ['Potato', 'Tomato', 'Mango', 'Milk']
print(remove_item(food_stuff, 'Mango')) # ['Potato', 'Tomato', 'Milk'];
numbers = [2, 3, 7, 9]
print(remove_item(numbers, 3)) # [2, 7, 9]
```
13. Declare a function named sum_of_numbers. It takes a number parameter and it adds all the numbers in that range.
```py
print(sum_of_numbers(5)) # 15
print(sum_of_numbers(10)) # 55
print(sum_of_numbers(100)) # 5050
```
14. Declare a function named sum_of_odds. It takes a number parameter and it adds all the odd numbers in that range.
15. Declare a function named sum_of_even. It takes a number parameter and it adds all the even numbers in that - range.
### Exercises: Level 2
1. Declare a function named evens_and_odds . It takes a positive integer as parameter and it counts number of evens and odds in the number.
```py
print(evens_and_odds(100))
# The number of odds are 50.
# The number of evens are 51.
```
1. Call your function factorial, it takes a whole number as a parameter and it return a factorial of the number
1. Call your function _is_empty_, it takes a parameter and it checks if it is empty or not
1. Write different functions which take lists. They should calculate_mean, calculate_median, calculate_mode, calculate_range, calculate_variance, calculate_std (standard deviation).
1. Write a function called _greet_ which takes a default argument, _name_. If no argument is supplied it should print "Hello, Guest!", otherwise it should greet the person by name.
```py
greet()
# "Hello, Guest!
greet("Alice")
# "Hello, Alice!"
```
1. Create a function called _show_args_ to take an arbitrary number of named arguments and print their names and values.
```py
show_args(name="Alice", age=30, city="New York")
# Received: name: Alice, age: 30, city: New York
show_args(name="Bob", pet="Fluffy, the bunny")
# Received: name: Bob, pet: Fluffy, the bunny
```
### Exercises: Level 3
1. Write a function called is_prime, which checks if a number is prime.
1. Write a functions which checks if all items are unique in the list.
1. Write a function which checks if all the items of the list are of the same data type.
1. Write a function which check if provided variable is a valid python variable
1. Go to the data folder and access the countries-data.py file.
- Create a function called the most_spoken_languages in the world. It should return 10 or 20 most spoken languages in the world in descending order
- Create a function called the most_populated_countries. It should return 10 or 20 most populated countries in descending order.
🎉 CONGRATULATIONS ! 🎉
[<< Day 10](../10_Day_Loops/10_loops.md) | [Day 12 >>](../12_Day_Modules/12_modules.md)
================================================
FILE: 12_Day_Modules/12_modules.md
================================================
[<< Day 11](../11_Day_Functions/11_functions.md) | [Day 13>>](../13_Day_List_comprehension/13_list_comprehension.md)

- [📘 Day 12](#-day-12)
- [Modules](#modules)
- [What is a Module](#what-is-a-module)
- [Creating a Module](#creating-a-module)
- [Importing a Module](#importing-a-module)
- [Import Functions from a Module](#import-functions-from-a-module)
- [Import Functions from a Module and Renaming](#import-functions-from-a-module-and-renaming)
- [Import Built-in Modules](#import-built-in-modules)
- [OS Module](#os-module)
- [Sys Module](#sys-module)
- [Statistics Module](#statistics-module)
- [Math Module](#math-module)
- [String Module](#string-module)
- [Random Module](#random-module)
- [💻 Exercises: Day 12](#-exercises-day-12)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# 📘 Day 12
## Modules
### What is a Module
A module is a file containing a set of codes or a set of functions which can be included to an application. A module could be a file containing a single variable, a function or a big code base.
### Creating a Module
To create a module we write our codes in a python script and we save it as a .py file. Create a file named mymodule.py inside your project folder. Let us write some code in this file.
```py
# mymodule.py file
def generate_full_name(firstname, lastname):
return firstname + ' ' + lastname
```
Create main.py file in your project directory and import the mymodule.py file.
### Importing a Module
To import the file we use the _import_ keyword and the name of the file only.
```py
# main.py file
import mymodule
print(mymodule.generate_full_name('Asabeneh', 'Yetayeh')) # Asabeneh Yetayeh
```
### Import Functions from a Module
We can have many functions in a file and we can import all the functions differently.
```py
# main.py file
from mymodule import generate_full_name, sum_two_nums, person, gravity
print(generate_full_name('Asabneh','Yetayeh'))
print(sum_two_nums(1,9))
mass = 100
weight = mass * gravity
print(weight)
print(person['firstname'])
```
### Import Functions from a Module and Renaming
During importing we can rename the name of the module.
```py
# main.py file
from mymodule import generate_full_name as fullname, sum_two_nums as total, person as p, gravity as g
print(fullname('Asabneh','Yetayeh'))
print(total(1, 9))
mass = 100
weight = mass * g
print(weight)
print(p)
print(p['firstname'])
```
## Import Built-in Modules
Like other programming languages we can also import modules by importing the file/function using the key word _import_. Let's import the common module we will use most of the time. Some of the common built-in modules: _math_, _datetime_, _os_,_sys_, _random_, _statistics_, _collections_, _json_,_re_
### OS Module
Using python _os_ module it is possible to automatically perform many operating system tasks. The OS module in Python provides functions for creating, changing current working directory, and removing a directory (folder), fetching its contents, changing and identifying the current directory.
```py
# import the module
import os
# Creating a directory
os.mkdir('directory_name')
# Changing the current directory
os.chdir('path')
# Getting current working directory
os.getcwd()
# Removing directory
os.rmdir()
```
### Sys Module
The sys module provides functions and variables used to manipulate different parts of the Python runtime environment. Function sys.argv returns a list of command line arguments passed to a Python script. The item at index 0 in this list is always the name of the script, at index 1 is the argument passed from the command line.
Example of a script.py file:
```py
import sys
#print(sys.argv[0], argv[1],sys.argv[2]) # this line would print out: filename argument1 argument2
print('Welcome {}. Enjoy {} challenge!'.format(sys.argv[1], sys.argv[2]))
```
Now to check how this script works I wrote in command line:
```sh
python script.py Asabeneh 30DaysOfPython
```
The result:
```sh
Welcome Asabeneh. Enjoy 30DayOfPython challenge!
```
Some useful sys commands:
```py
# to exit sys
sys.exit()
# To know the largest integer variable it takes
sys.maxsize
# To know environment path
sys.path
# To know the version of python you are using
sys.version
```
### Statistics Module
The statistics module provides functions for mathematical statistics of numeric data. The popular statistical functions which are defined in this module: _mean_, _median_, _mode_, _stdev_ etc.
```py
from statistics import * # importing all the statistics modules
ages = [20, 20, 4, 24, 25, 22, 26, 20, 23, 22, 26]
print(mean(ages)) # ~22.9
print(median(ages)) # 23
print(mode(ages)) # 20
print(stdev(ages)) # ~2.3
```
### Math Module
Module containing many mathematical operations and constants.
```py
import math
print(math.pi) # 3.141592653589793, pi constant
print(math.sqrt(2)) # 1.4142135623730951, square root
print(math.pow(2, 3)) # 8.0, exponential function
print(math.floor(9.81)) # 9, rounding to the lowest
print(math.ceil(9.81)) # 10, rounding to the highest
print(math.log10(100)) # 2, logarithm with 10 as base
```
Now, we have imported the *math* module which contains lots of function which can help us to perform mathematical calculations. To check what functions the module has got, we can use _help(math)_, or _dir(math)_. This will display the available functions in the module. If we want to import only a specific function from the module we import it as follows:
```py
from math import pi
print(pi)
```
It is also possible to import multiple functions at once
```py
from math import pi, sqrt, pow, floor, ceil, log10
print(pi) # 3.141592653589793
print(sqrt(2)) # 1.4142135623730951
print(pow(2, 3)) # 8.0
print(floor(9.81)) # 9
print(ceil(9.81)) # 10
print(math.log10(100)) # 2
```
But if we want to import all the function in math module we can use \* .
```py
from math import *
print(pi) # 3.141592653589793, pi constant
print(sqrt(2)) # 1.4142135623730951, square root
print(pow(2, 3)) # 8.0, exponential
print(floor(9.81)) # 9, rounding to the lowest
print(ceil(9.81)) # 10, rounding to the highest
print(math.log10(100)) # 2
```
When we import we can also rename the name of the function.
```py
from math import pi as PI
print(PI) # 3.141592653589793
```
### String Module
A string module is a useful module for many purposes. The example below shows some use of the string module.
```py
import string
print(string.ascii_letters) # abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
print(string.digits) # 0123456789
print(string.punctuation) # !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
```
### Random Module
By now you are familiar with importing modules. Let us do one more import to get very familiar with it. Let us import _random_ module which gives us a random number between 0 and 0.9999.... The _random_ module has lots of functions but in this section we will only use _random_ and _randint_.
```py
from random import random, randint
print(random()) # it doesn't take any arguments; it returns a value between 0 and 0.9999
print(randint(5, 20)) # it returns a random integer number between [5, 20] inclusive
```
🌕 You are going far. Keep going! You have just completed day 12 challenges and you are 12 steps a head in to your way to greatness. Now do some exercises for your brain and muscles.
## 💻 Exercises: Day 12
### Exercises: Level 1
1. Write a function which generates a six digit/character random_user_id.
```py
print(random_user_id())
'1ee33d'
```
2. Modify the previous task. Declare a function named user_id_gen_by_user. It doesn’t take any parameters but it takes two inputs using input(). One of the inputs is the number of characters and the second input is the number of IDs which are supposed to be generated.
```py
print(user_id_gen_by_user()) # user input: 5 5
#output:
#kcsy2
#SMFYb
#bWmeq
#ZXOYh
#2Rgxf
print(user_id_gen_by_user()) # 16 5
#1GCSgPLMaBAVQZ26
#YD7eFwNQKNs7qXaT
#ycArC5yrRupyG00S
#UbGxOFI7UXSWAyKN
#dIV0SSUTgAdKwStr
```
3. Write a function named rgb_color_gen. It will generate rgb colors (3 values ranging from 0 to 255 each).
```py
print(rgb_color_gen())
# rgb(125,244,255) - the output should be in this form
```
### Exercises: Level 2
1. Write a function list_of_hexa_colors which returns any number of hexadecimal colors in an array (six hexadecimal numbers written after #. Hexadecimal numeral system is made out of 16 symbols, 0-9 and first 6 letters of the alphabet, a-f. Check the task 6 for output examples).
1. Write a function list_of_rgb_colors which returns any number of RGB colors in an array.
1. Write a function generate_colors which can generate any number of hexa or rgb colors.
```py
generate_colors('hexa', 3) # ['#a3e12f','#03ed55','#eb3d2b']
generate_colors('hexa', 1) # ['#b334ef']
generate_colors('rgb', 3) # ['rgb(5, 55, 175','rgb(50, 105, 100','rgb(15, 26, 80']
generate_colors('rgb', 1) # ['rgb(33,79, 176)']
```
### Exercises: Level 3
1. Call your function shuffle_list, it takes a list as a parameter and it returns a shuffled list
1. Write a function which returns an array of seven random numbers in a range of 0-9. All the numbers must be unique.
🎉 CONGRATULATIONS ! 🎉
[<< Day 11](../11_Day_Functions/11_functions.md) | [Day 13>>](../13_Day_List_comprehension/13_list_comprehension.md)
================================================
FILE: 12_Day_Modules/main.py
================================================
from mymodule import generate_full_name as fullname, sum_two_nums as total, person as p, gravity as g
print(fullname('Asabneh','Yetayeh'))
print(total(1, 9))
mass = 100
print(mass)
weight = mass * g
print(weight)
print(p)
print(p['firstname'])
================================================
FILE: 12_Day_Modules/mymodule.py
================================================
def generate_full_name(firstname, lastname):
space = ' '
fullname = firstname + space + lastname
return fullname
def sum_two_nums (num1, num2):
return num1 + num2
gravity = 9.81
person = {
"firstname": "Asabeneh",
"age": 250,
"country": "Finland",
"city":'Helsinki'
}
================================================
FILE: 13_Day_List_comprehension/13_list_comprehension.md
================================================
[<< Day 12](../12_Day_Modules/12_modules.md) | [Day 14>>](../14_Day_Higher_order_functions/14_higher_order_functions.md)

- [📘 Day 13](#-day-13)
- [List Comprehension](#list-comprehension)
- [Lambda Function](#lambda-function)
- [Creating a Lambda Function](#creating-a-lambda-function)
- [Lambda Function Inside Another Function](#lambda-function-inside-another-function)
- [💻 Exercises: Day 13](#-exercises-day-13)
# 📘 Day 13
## List Comprehension
List comprehension in Python is a compact way of creating a list from a sequence. It is a short way to create a new list. List comprehension is considerably faster than processing a list using the _for_ loop.
```py
# syntax
[expression for i in iterable if condition]
```
**Example:1**
For instance if you want to change a string to a list of characters. You can use a couple of methods. Let's see some of them:
```py
# One way
language = 'Python'
lst = list(language) # changing the string to list
print(type(lst)) # list
print(lst) # ['P', 'y', 't', 'h', 'o', 'n']
# Second way: list comprehension
lst = [i for i in language]
print(type(lst)) # list
print(lst) # ['P', 'y', 't', 'h', 'o', 'n']
```
**Example:2**
For instance if you want to generate a list of numbers
```py
# Generating numbers
numbers = [i for i in range(11)] # to generate numbers from 0 to 10
print(numbers) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# It is possible to do mathematical operations during iteration
squares = [i * i for i in range(11)]
print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# It is also possible to make a list of tuples
numbers = [(i, i * i) for i in range(11)]
print(numbers) # [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
```
**Example:2**
List comprehension can be combined with if expression
```py
# Generating even numbers
even_numbers = [i for i in range(21) if i % 2 == 0] # to generate even numbers list in range 0 to 21
print(even_numbers) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
# Generating odd numbers
odd_numbers = [i for i in range(21) if i % 2 != 0] # to generate odd numbers in range 0 to 21
print(odd_numbers) # [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
# Filter numbers: let's filter out positive even numbers from the list below
numbers = [-8, -7, -3, -1, 0, 1, 3, 4, 5, 7, 6, 8, 10]
positive_even_numbers = [i for i in numbers if i % 2 == 0 and i > 0]
print(positive_even_numbers) # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
# Flattening a two dimensional array
list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened_list = [ number for row in list_of_lists for number in row]
print(flattened_list) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
```
## Lambda Function
Lambda function is a small anonymous function without a name. It can take any number of arguments, but can only have one expression. Lambda function is similar to anonymous functions in JavaScript. We need it when we want to write an anonymous function inside another function.
### Creating a Lambda Function
To create a lambda function we use _lambda_ keyword followed by a parameter(s), followed by an expression. See the syntax and the example below. Lambda function does not use return but it explicitly returns the expression.
```py
# syntax
x = lambda param1, param2, param3: param1 + param2 + param3
print(x(arg1, arg2, arg3))
```
**Example:**
```py
# Named function
def add_two_nums(a, b):
return a + b
print(add_two_nums(2, 3)) # 5
# Lets change the above function to a lambda function
add_two_nums = lambda a, b: a + b
print(add_two_nums(2,3)) # 5
# Self invoking lambda function
(lambda a, b: a + b)(2,3) # 5 - need to encapsulate it in print() to see the result in the console
square = lambda x : x ** 2
print(square(3)) # 9
cube = lambda x : x ** 3
print(cube(3)) # 27
# Multiple variables
multiple_variable = lambda a, b, c: a ** 2 - 3 * b + 4 * c
print(multiple_variable(5, 5, 3)) # 22
```
### Lambda Function Inside Another Function
Using a lambda function inside another function.
```py
def power(x):
return lambda n : x ** n
cube = power(2)(3) # function power now need 2 arguments to run, in separate rounded brackets
print(cube) # 8
two_power_of_five = power(2)(5)
print(two_power_of_five) # 32
```
🌕 Keep up the good work. Keep the momentum going, the sky is the limit! You have just completed day 13 challenges and you are 13 steps a head in to your way to greatness. Now do some exercises for your brain and muscles.
## 💻 Exercises: Day 13
1. Filter only negative and zero in the list using list comprehension
```py
numbers = [-4, -3, -2, -1, 0, 2, 4, 6]
```
2. Flatten the following list of lists of lists to a one dimensional list :
```py
list_of_lists =[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
output
[1, 2, 3, 4, 5, 6, 7, 8, 9]
```
3. Using list comprehension create the following list of tuples:
```py
[(0, 1, 0, 0, 0, 0, 0),
(1, 1, 1, 1, 1, 1, 1),
(2, 1, 2, 4, 8, 16, 32),
(3, 1, 3, 9, 27, 81, 243),
(4, 1, 4, 16, 64, 256, 1024),
(5, 1, 5, 25, 125, 625, 3125),
(6, 1, 6, 36, 216, 1296, 7776),
(7, 1, 7, 49, 343, 2401, 16807),
(8, 1, 8, 64, 512, 4096, 32768),
(9, 1, 9, 81, 729, 6561, 59049),
(10, 1, 10, 100, 1000, 10000, 100000)]
```
4. Flatten the following list to a new list:
```py
countries = [[('Finland', 'Helsinki')], [('Sweden', 'Stockholm')], [('Norway', 'Oslo')]]
output:
[['FINLAND','FIN', 'HELSINKI'], ['SWEDEN', 'SWE', 'STOCKHOLM'], ['NORWAY', 'NOR', 'OSLO']]
```
5. Change the following list to a list of dictionaries:
```py
countries = [[('Finland', 'Helsinki')], [('Sweden', 'Stockholm')], [('Norway', 'Oslo')]]
output:
[{'country': 'FINLAND', 'city': 'HELSINKI'},
{'country': 'SWEDEN', 'city': 'STOCKHOLM'},
{'country': 'NORWAY', 'city': 'OSLO'}]
```
6. Change the following list of lists to a list of concatenated strings:
```py
names = [[('Asabeneh', 'Yetayeh')], [('David', 'Smith')], [('Donald', 'Trump')], [('Bill', 'Gates')]]
output
['Asabeneh Yetaeyeh', 'David Smith', 'Donald Trump', 'Bill Gates']
```
7. Write a lambda function which can solve a slope or y-intercept of linear functions.
🎉 CONGRATULATIONS ! 🎉
[<< Day 12](../12_Day_Modules/12_modules.md) | [Day 14>>](../14_Day_Higher_order_functions/14_higher_order_functions.md)
================================================
FILE: 14_Day_Higher_order_functions/14_higher_order_functions.md
================================================
30 Days Of Python: Day 14 - Higher Order Functions
[<< Day 13](../13_Day_List_comprehension/13_list_comprehension.md) | [Day 15>>](../15_Day_Python_type_errors/15_python_type_errors.md)

- [📘 Day 14](#-day-14)
- [Higher Order Functions](#higher-order-functions)
- [Function as a Parameter](#function-as-a-parameter)
- [Function as a Return Value](#function-as-a-return-value)
- [Python Closures](#python-closures)
- [Python Decorators](#python-decorators)
- [Creating Decorators](#creating-decorators)
- [Applying Multiple Decorators to a Single Function](#applying-multiple-decorators-to-a-single-function)
- [Accepting Parameters in Decorator Functions](#accepting-parameters-in-decorator-functions)
- [Built-in Higher Order Functions](#built-in-higher-order-functions)
- [Python - Map Function](#python---map-function)
- [Python - Filter Function](#python---filter-function)
- [Python - Reduce Function](#python---reduce-function)
- [💻 Exercises: Day 14](#-exercises-day-14)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# 📘 Day 14
## Higher Order Functions
In Python functions are treated as first class citizens, allowing you to perform the following operations on functions:
- A function can take one or more functions as parameters
- A function can be returned as a result of another function
- A function can be modified
- A function can be assigned to a variable
In this section, we will cover:
1. Handling functions as parameters
2. Returning functions as return value from another functions
3. Using Python closures and decorators
### Function as a Parameter
```py
def sum_numbers(nums): # normal function
return sum(nums) # a sad function abusing the built-in sum function :<
def higher_order_function(f, lst): # function as a parameter
summation = f(lst)
return summation
result = higher_order_function(sum_numbers, [1, 2, 3, 4, 5])
print(result) # 15
```
### Function as a Return Value
```py
def square(x): # a square function
return x ** 2
def cube(x): # a cube function
return x ** 3
def absolute(x): # an absolute value function
if x >= 0:
return x
else:
return -(x)
def higher_order_function(type): # a higher order function returning a function
if type == 'square':
return square
elif type == 'cube':
return cube
elif type == 'absolute':
return absolute
result = higher_order_function('square')
print(result(3)) # 9
result = higher_order_function('cube')
print(result(3)) # 27
result = higher_order_function('absolute')
print(result(-3)) # 3
```
You can see from the above example that the higher order function is returning different functions depending on the passed parameter
## Python Closures
Python allows a nested function to access the outer scope of the enclosing function. This is is known as a Closure. Let us have a look at how closures work in Python. In Python, closure is created by nesting a function inside another encapsulating function and then returning the inner function. See the example below.
**Example:**
```py
def add_ten():
ten = 10
def add(num):
return num + ten
return add
closure_result = add_ten()
print(closure_result(5)) # 15
print(closure_result(10)) # 20
```
## Python Decorators
A decorator is a design pattern in Python that allows a user to add new functionality to an existing object without modifying its structure. Decorators are usually called before the definition of a function you want to decorate.
### Creating Decorators
To create a decorator function, we need an outer function with an inner wrapper function.
**Example:**
```py
# Normal function
def greeting():
return 'Welcome to Python'
def uppercase_decorator(function):
def wrapper():
func = function()
make_uppercase = func.upper()
return make_uppercase
return wrapper
g = uppercase_decorator(greeting)
print(g()) # WELCOME TO PYTHON
## Let us implement the example above with a decorator
'''This decorator function is a higher order function
that takes a function as a parameter'''
def uppercase_decorator(function):
def wrapper():
func = function()
make_uppercase = func.upper()
return make_uppercase
return wrapper
@uppercase_decorator
def greeting():
return 'Welcome to Python'
print(greeting()) # WELCOME TO PYTHON
```
### Applying Multiple Decorators to a Single Function
```py
'''These decorator functions are higher order functions
that take functions as parameters'''
# First Decorator
def uppercase_decorator(function):
def wrapper():
func = function()
make_uppercase = func.upper()
return make_uppercase
return wrapper
# Second decorator
def split_string_decorator(function):
def wrapper():
func = function()
splitted_string = func.split()
return splitted_string
return wrapper
#Decorators will be executed from bottom to top
@split_string_decorator
@uppercase_decorator # order with decorators is important in this case - .upper() function does not work with lists
def greeting():
return 'Welcome to Python'
print(greeting()) # ['WELCOME', 'TO', 'PYTHON']
```
### Accepting Parameters in Decorator Functions
Most of the time we need our functions to take parameters, so we might need to define a decorator that accepts parameters.
```py
def decorator_with_parameters(function):
def wrapper_accepting_parameters(para1, para2, para3):
function(para1, para2, para3)
print("I live in {}".format(para3))
return wrapper_accepting_parameters
@decorator_with_parameters
def print_full_name(first_name, last_name, country):
print("I am {} {}. I love to teach.".format(
first_name, last_name))
print_full_name("Asabeneh", "Yetayeh",'Finland')
```
## Built-in Higher Order Functions
Some of the built-in higher order functions that we cover in this part are _map()_, _filter_, and _reduce_.
Lambda function can be passed as a parameter and the best use case of lambda functions is in functions like map, filter and reduce.
### Python - Map Function
The map() function is a built-in function that takes a function and iterable as parameters.
```py
# syntax
map(function, iterable)
```
**Example:1**
```py
numbers = [1, 2, 3, 4, 5] # iterable
def square(x):
return x ** 2
numbers_squared = map(square, numbers)
print(list(numbers_squared)) # [1, 4, 9, 16, 25]
# Lets apply it with a lambda function
numbers_squared = map(lambda x : x ** 2, numbers)
print(list(numbers_squared)) # [1, 4, 9, 16, 25]
```
**Example:2**
```py
numbers_str = ['1', '2', '3', '4', '5'] # iterable
numbers_int = map(int, numbers_str)
print(list(numbers_int)) # [1, 2, 3, 4, 5]
```
**Example:3**
```py
names = ['Asabeneh', 'Lidiya', 'Ermias', 'Abraham'] # iterable
def change_to_upper(name):
return name.upper()
names_upper_cased = map(change_to_upper, names)
print(list(names_upper_cased)) # ['ASABENEH', 'LIDIYA', 'ERMIAS', 'ABRAHAM']
# Let us apply it with a lambda function
names_upper_cased = map(lambda name: name.upper(), names)
print(list(names_upper_cased)) # ['ASABENEH', 'LIDIYA', 'ERMIAS', 'ABRAHAM']
```
What actually map does is iterating over a list. For instance, it changes the names to upper case and returns a new list.
### Python - Filter Function
The filter() function calls the specified function which returns boolean for each item of the specified iterable (list). It filters the items that satisfy the filtering criteria.
```py
# syntax
filter(function, iterable)
```
**Example:1**
```py
# Lets filter only even nubers
numbers = [1, 2, 3, 4, 5] # iterable
def is_even(num):
if num % 2 == 0:
return True
return False
even_numbers = filter(is_even, numbers)
print(list(even_numbers)) # [2, 4]
```
**Example:2**
```py
numbers = [1, 2, 3, 4, 5] # iterable
def is_odd(num):
if num % 2 != 0:
return True
return False
odd_numbers = filter(is_odd, numbers)
print(list(odd_numbers)) # [1, 3, 5]
```
```py
# Filter long name
names = ['Asabeneh', 'Lidiya', 'Ermias', 'Abraham'] # iterable
def is_name_long(name):
if len(name) > 7:
return True
return False
long_names = filter(is_name_long, names)
print(list(long_names)) # ['Asabeneh']
```
### Python - Reduce Function
The _reduce()_ function is defined in the functools module and we should import it from this module. Like map and filter it takes two parameters, a function and an iterable. However, it does not return another iterable, instead it returns a single value.
**Example:1**
```py
numbers_str = ['1', '2', '3', '4', '5'] # iterable
def add_two_nums(x, y):
return int(x) + int(y)
total = reduce(add_two_nums, numbers_str)
print(total) # 15
```
## 💻 Exercises: Day 14
```py
countries = ['Estonia', 'Finland', 'Sweden', 'Denmark', 'Norway', 'Iceland']
names = ['Asabeneh', 'Lidiya', 'Ermias', 'Abraham']
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```
### Exercises: Level 1
1. Explain the difference between map, filter, and reduce.
2. Explain the difference between higher order function, closure and decorator
3. Define a call function before map, filter or reduce, see examples.
4. Use for loop to print each country in the countries list.
5. Use for to print each name in the names list.
6. Use for to print each number in the numbers list.
### Exercises: Level 2
1. Use map to create a new list by changing each country to uppercase in the countries list
1. Use map to create a new list by changing each number to its square in the numbers list
1. Use map to change each name to uppercase in the names list
1. Use filter to filter out countries containing 'land'.
1. Use filter to filter out countries having exactly six characters.
1. Use filter to filter out countries containing six letters and more in the country list.
1. Use filter to filter out countries starting with an 'E'
1. Chain two or more list iterators (eg. arr.map(callback).filter(callback).reduce(callback))
1. Declare a function called get_string_lists which takes a list as a parameter and then returns a list containing only string items.
1. Use reduce to sum all the numbers in the numbers list.
1. Use reduce to concatenate all the countries and to produce this sentence: Estonia, Finland, Sweden, Denmark, Norway, and Iceland are north European countries
1. Declare a function called categorize_countries that returns a list of countries with some common pattern (you can find the [countries list](https://github.com/Asabeneh/30-Days-Of-Python/blob/master/data/countries.py) in this repository as countries.js(eg 'land', 'ia', 'island', 'stan')).
1. Create a function returning a dictionary, where keys stand for starting letters of countries and values are the number of country names starting with that letter.
2. Declare a get_first_ten_countries function - it returns a list of first ten countries from the countries.js list in the data folder.
1. Declare a get_last_ten_countries function that returns the last ten countries in the countries list.
### Exercises: Level 3
1. Use the countries_data.py (https://github.com/Asabeneh/30-Days-Of-Python/blob/master/data/countries-data.py) file and follow the tasks below:
- Sort countries by name, by capital, by population
- Sort out the ten most spoken languages by location.
- Sort out the ten most populated countries.
🎉 CONGRATULATIONS ! 🎉
[<< Day 13](../13_Day_List_comprehension/13_list_comprehension.md) | [Day 15>>](../15_Day_Python_type_errors/15_python_type_errors.md)
================================================
FILE: 15_Day_Python_type_errors/15_python_type_errors.md
================================================
[<< Day 14](../14_Day_Higher_order_functions/14_higher_order_functions.md) | [Day 16 >>](../16_Day_Python_date_time/16_python_datetime.md)

- [📘 Day 15](#-day-15)
- [Python Error Types](#python-error-types)
- [SyntaxError](#syntaxerror)
- [NameError](#nameerror)
- [IndexError](#indexerror)
- [ModuleNotFoundError](#modulenotfounderror)
- [AttributeError](#attributeerror)
- [KeyError](#keyerror)
- [TypeError](#typeerror)
- [ImportError](#importerror)
- [ValueError](#valueerror)
- [ZeroDivisionError](#zerodivisionerror)
- [💻 Exercises: Day 15](#-exercises-day-15)
# 📘 Day 15
## Python Error Types
When we write code it is common that we make a typo or some other common error. If our code fails to run, the Python interpreter will display a message, containing feedback with information on where the problem occurs and the type of an error. It will also sometimes gives us suggestions on a possible fix. Understanding different types of errors in programming languages will help us to debug our code quickly and also it makes us better at what we do.
Let us see the most common error types one by one. First let us open our Python interactive shell. Go to your you computer terminal and write 'python'. The python interactive shell will be opened.
### SyntaxError
**Example 1: SyntaxError**
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print 'hello world'
File "", line 1
print 'hello world'
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('hello world')?
>>>
```
As you can see we made a syntax error because we forgot to enclose the string with parenthesis and Python already suggests the solution. Let us fix it.
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print 'hello world'
File "", line 1
print 'hello world'
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('hello world')?
>>> print('hello world')
hello world
>>>
```
The error was a _SyntaxError_. After the fix our code was executed without a hitch. Let see more error types.
### NameError
**Example 1: NameError**
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print(age)
Traceback (most recent call last):
File "", line 1, in
NameError: name 'age' is not defined
>>>
```
As you can see from the message above, name age is not defined. Yes, it is true that we did not define an age variable but we were trying to print it out as if we had had declared it. Now, lets fix this by declaring it and assigning with a value.
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print(age)
Traceback (most recent call last):
File "", line 1, in
NameError: name 'age' is not defined
>>> age = 25
>>> print(age)
25
>>>
```
The type of error was a _NameError_. We debugged the error by defining the variable name.
### IndexError
**Example 1: IndexError**
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> numbers = [1, 2, 3, 4, 5]
>>> numbers[5]
Traceback (most recent call last):
File "", line 1, in
IndexError: list index out of range
>>>
```
In the example above, Python raised an _IndexError_, because the list has only indexes from 0 to 4 , so it was out of range.
### ModuleNotFoundError
**Example 1: ModuleNotFoundError**
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'maths'
>>>
```
In the example above, I added an extra s to math deliberately and _ModuleNotFoundError_ was raised. Lets fix it by removing the extra s from math.
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'maths'
>>> import math
>>>
```
We fixed it, so let's use some of the functions from the math module.
### AttributeError
**Example 1: AttributeError**
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'maths'
>>> import math
>>> math.PI
Traceback (most recent call last):
File "", line 1, in
AttributeError: module 'math' has no attribute 'PI'
>>>
```
As you can see, I made a mistake again! Instead of pi, I tried to call a PI constant from maths module. It raised an attribute error, it means, that the attribute does not exist in the module. Lets fix it by changing from PI to pi.
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'maths'
>>> import math
>>> math.PI
Traceback (most recent call last):
File "", line 1, in
AttributeError: module 'math' has no attribute 'PI'
>>> math.pi
3.141592653589793
>>>
```
Now, when we call pi from the math module we got the result.
### KeyError
**Example 1: KeyError**
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> users = {'name':'Asab', 'age':250, 'country':'Finland'}
>>> users['name']
'Asab'
>>> users['county']
Traceback (most recent call last):
File "", line 1, in
KeyError: 'county'
>>>
```
As you can see, there was a typo in the key used to get the dictionary value. so, this is a key error and the fix is quite straight forward. Let's do this!
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> user = {'name':'Asab', 'age':250, 'country':'Finland'}
>>> user['name']
'Asab'
>>> user['county']
Traceback (most recent call last):
File "", line 1, in
KeyError: 'county'
>>> user['country']
'Finland'
>>>
```
We debugged the error, our code ran and we got the value.
### TypeError
**Example 1: TypeError**
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 4 + '3'
Traceback (most recent call last):
File "", line 1, in
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>>
```
In the example above, a TypeError is raised because we cannot add a number to a string. First solution would be to convert the string to int or float. Another solution would be converting the number to a string (the result then would be '43'). Let us follow the first fix.
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 4 + '3'
Traceback (most recent call last):
File "", line 1, in
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> 4 + int('3')
7
>>> 4 + float('3')
7.0
>>>
```
Error removed and we got the result we expected.
### ImportError
**Example 1: TypeError**
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from math import power
Traceback (most recent call last):
File "", line 1, in
ImportError: cannot import name 'power' from 'math'
>>>
```
There is no function called power in the math module, it goes with a different name: _pow_. Let's correct it:
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from math import power
Traceback (most recent call last):
File "", line 1, in
ImportError: cannot import name 'power' from 'math'
>>> from math import pow
>>> pow(2,3)
8.0
>>>
```
### ValueError
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> int('12a')
Traceback (most recent call last):
File "", line 1, in
ValueError: invalid literal for int() with base 10: '12a'
>>>
```
In this case we cannot change the given string to a number, because of the 'a' letter in it.
### ZeroDivisionError
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 1/0
Traceback (most recent call last):
File "", line 1, in
ZeroDivisionError: division by zero
>>>
```
We cannot divide a number by zero.
We have covered some of the python error types, if you want to check more about it check the python documentation about python error types.
If you are good at reading the error types, then you will be able to fix your bugs fast and you will also become a better programmer.
🌕 You are excelling. You made it to half way to your way to greatness. Now do some exercises for your brain and for your muscle.
## 💻 Exercises: Day 15
1. Open you python interactive shell and try all the examples covered in this section.
🎉 CONGRATULATIONS ! 🎉
[<< Day 14](../14_Day_Higher_order_functions/14_higher_order_functions.md) | [Day 16 >>](../16_Day_Python_date_time/16_python_datetime.md)
================================================
FILE: 16_Day_Python_date_time/16_python_datetime.md
================================================
[<< Day 15](../15_Day_Python_type_errors/15_python_type_errors.md) | [Day 17 >>](../17_Day_Exception_handling/17_exception_handling.md)

- [📘 Day 16](#-day-16)
- [Python *datetime*](#python-datetime)
- [Getting *datetime* Information](#getting-datetime-information)
- [Formatting Date Output Using *strftime*](#formatting-date-output-using-strftime)
- [String to Time Using *strptime*](#string-to-time-using-strptime)
- [Using *date* from *datetime*](#using-date-from-datetime)
- [Time Objects to Represent Time](#time-objects-to-represent-time)
- [Difference Between Two Points in Time Using](#difference-between-two-points-in-time-using)
- [Difference Between Two Points in Time Using *timedelta*](#difference-between-two-points-in-time-using-timedelta)
- [💻 Exercises: Day 16](#-exercises-day-16)
# 📘 Day 16
## Python *datetime*
Python has got _datetime_ module to handle date and time.
```py
import datetime
print(dir(datetime))
['MAXYEAR', 'MINYEAR', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'date', 'datetime', 'datetime_CAPI', 'sys', 'time', 'timedelta', 'timezone', 'tzinfo']
```
With dir or help built-in commands it is possible to know the available functions in a certain module. As you can see, in the datetime module there are many functions, but we will focus on _date_, _datetime_, _time_ and _timedelta_. Let se see them one by one.
### Getting *datetime* Information
```py
from datetime import datetime
now = datetime.now()
print(now) # 2021-07-08 07:34:46.549883
day = now.day # 8
month = now.month # 7
year = now.year # 2021
hour = now.hour # 7
minute = now.minute # 38
second = now.second
timestamp = now.timestamp()
print(day, month, year, hour, minute)
print('timestamp', timestamp)
print(f'{day}/{month}/{year}, {hour}:{minute}') # 8/7/2021, 7:38
```
Timestamp or Unix timestamp is the number of seconds elapsed from 1st of January 1970 UTC.
### Formatting Date Output Using *strftime*
```py
from datetime import datetime
new_year = datetime(2020, 1, 1)
print(new_year) # 2020-01-01 00:00:00
day = new_year.day
month = new_year.month
year = new_year.year
hour = new_year.hour
minute = new_year.minute
second = new_year.second
print(day, month, year, hour, minute) #1 1 2020 0 0
print(f'{day}/{month}/{year}, {hour}:{minute}') # 1/1/2020, 0:0
```
Formatting date time using *strftime* method and the documentation can be found [here](https://strftime.org/).
```py
from datetime import datetime
# current date and time
now = datetime.now()
t = now.strftime("%H:%M:%S")
print("time:", t) # time: 18:21:40
time_one = now.strftime("%m/%d/%Y, %H:%M:%S")
# mm/dd/YY H:M:S format
print("time one:", time_one) # time one: 06/28/2022, 18:21:40
time_two = now.strftime("%d/%m/%Y, %H:%M:%S")
# dd/mm/YY H:M:S format
print("time two:", time_two) # time two: 28/06/2022, 18:21:40
```
```sh
time: 01:05:01
time one: 12/05/2019, 01:05:01
time two: 05/12/2019, 01:05:01
```
Here are all the _strftime_ symbols we use to format time. An example of all the formats for this module.

### String to Time Using *strptime*
Here is a [documentation](https://www.programiz.com/python-programming/datetime/strptime) hat helps to understand the format.
```py
from datetime import datetime
date_string = "5 December, 2019"
print("date_string =", date_string) # date_string = 5 December, 2019
date_object = datetime.strptime(date_string, "%d %B, %Y")
print("date_object =", date_object) # date_object = 2019-12-05 00:00:00
```
```sh
date_string = 5 December, 2019
date_object = 2019-12-05 00:00:00
```
### Using *date* from *datetime*
```py
from datetime import date
d = date(2020, 1, 1)
print(d) # 2020-01-01
print('Current date:', d.today()) # 2019-12-05
# date object of today's date
today = date.today()
print("Current year:", today.year) # 2019
print("Current month:", today.month) # 12
print("Current day:", today.day) # 5
```
### Time Objects to Represent Time
```py
from datetime import time
# time(hour = 0, minute = 0, second = 0)
a = time()
print("a =", a) # a = 00:00:00
# time(hour, minute and second)
b = time(10, 30, 50)
print("b =", b) # b = 10:30:50
# time(hour, minute and second)
c = time(hour=10, minute=30, second=50)
print("c =", c) # c = 10:30:50
# time(hour, minute, second, microsecond)
d = time(10, 30, 50, 200555)
print("d =", d) # d = 10:30:50.200555
```
output
a = 00:00:00
b = 10:30:50
c = 10:30:50
d = 10:30:50.200555
### Difference Between Two Points in Time Using
```py
from datetime import date, datetime
today = date(year=2019, month=12, day=5)
new_year = date(year=2020, month=1, day=1)
time_left_for_newyear = new_year - today
# Time left for new year: 27 days, 0:00:00
print('Time left for new year: ', time_left_for_newyear) # Time left for new year: 27 days, 0:00:00
t1 = datetime(year = 2019, month = 12, day = 5, hour = 0, minute = 59, second = 0)
t2 = datetime(year = 2020, month = 1, day = 1, hour = 0, minute = 0, second = 0)
diff = t2 - t1
print('Time left for new year:', diff) # Time left for new year: 26 days, 23: 01: 00
```
### Difference Between Two Points in Time Using *timedelta*
```py
from datetime import timedelta
t1 = timedelta(weeks=12, days=10, hours=4, seconds=20)
t2 = timedelta(days=7, hours=5, minutes=3, seconds=30)
t3 = t1 - t2
print("t3 =", t3)
```
```sh
date_string = 5 December, 2019
date_object = 2019-12-05 00:00:00
t3 = 86 days, 22:56:50
```
🌕 You are an extraordinary. You are 16 steps a head to your way to greatness. Now do some exercises for your brain and muscles.
## 💻 Exercises: Day 16
1. Get the current day, month, year, hour, minute and timestamp from datetime module
2. Format the current date using this format: "%m/%d/%Y, %H:%M:%S")
3. Today is 5 December, 2019. Change this time string to time.
4. Calculate the time difference between now and new year.
5. Calculate the time difference between 1 January 1970 and now.
6. Think, what can you use the datetime module for? Examples:
- Time series analysis
- To get a timestamp of any activities in an application
- Adding posts on a blog
🎉 CONGRATULATIONS ! 🎉
[<< Day 15](../15_Day_Python_type_errors/15_python_type_errors.md) | [Day 17 >>](../17_Day_Exception_handling/17_exception_handling.md)
================================================
FILE: 17_Day_Exception_handling/17_exception_handling.md
================================================
[<< Day 16](../16_Day_Python_date_time/16_python_datetime.md) | [Day 18 >>](../18_Day_Regular_expressions/18_regular_expressions.md)

- [📘 Day 17](#-day-17)
- [Exception Handling](#exception-handling)
- [Packing and Unpacking Arguments in Python](#packing-and-unpacking-arguments-in-python)
- [Unpacking](#unpacking)
- [Unpacking Lists](#unpacking-lists)
- [Unpacking Dictionaries](#unpacking-dictionaries)
- [Packing](#packing)
- [Packing Lists](#packing-lists)
- [Packing Dictionaries](#packing-dictionaries)
- [Spreading in Python](#spreading-in-python)
- [Enumerate](#enumerate)
- [Zip](#zip)
- [Exercises: Day 17](#exercises-day-17)
# 📘 Day 17
## Exception Handling
Python uses _try_ and _except_ to handle errors gracefully. A graceful exit (or graceful handling) of errors is a simple programming idiom - a program detects a serious error condition and "exits gracefully", in a controlled manner as a result. Often the program prints a descriptive error message to a terminal or log as part of the graceful exit, this makes our application more robust. The cause of an exception is often external to the program itself. An example of exceptions could be an incorrect input, wrong file name, unable to find a file, a malfunctioning IO device. Graceful handling of errors prevents our applications from crashing.
We have covered the different Python _error_ types in the previous section. If we use _try_ and _except_ in our program, then it will not raise errors in those blocks.

```py
try:
code in this block if things go well
except:
code in this block run if things go wrong
```
**Example:**
```py
try:
print(10 + '5')
except:
print('Something went wrong')
```
In the example above the second operand is a string. We could change it to float or int to add it with the number to make it work. But without any changes, the second block, _except_, will be executed.
**Example:**
```py
try:
name = input('Enter your name:')
year_born = input('Year you were born:')
age = 2019 - year_born
print(f'You are {name}. And your age is {age}.')
except:
print('Something went wrong')
```
```sh
Something went wrong
```
In the above example, the exception block will run and we do not know exactly the problem. To analyze the problem, we can use the different error types with except.
In the following example, it will handle the error and will also tell us the kind of error raised.
```py
try:
name = input('Enter your name:')
year_born = input('Year you were born:')
age = 2019 - year_born
print(f'You are {name}. And your age is {age}.')
except TypeError:
print('Type error occured')
except ValueError:
print('Value error occured')
except ZeroDivisionError:
print('zero division error occured')
```
```sh
Enter your name:Asabeneh
Year you born:1920
Type error occured
```
In the code above the output is going to be _TypeError_.
Now, let's add an additional block:
```py
try:
name = input('Enter your name:')
year_born = input('Year you born:')
age = 2019 - int(year_born)
print(f'You are {name}. And your age is {age}.')
except TypeError:
print('Type error occur')
except ValueError:
print('Value error occur')
except ZeroDivisionError:
print('zero division error occur')
else:
print('I usually run with the try block')
finally:
print('I alway run.')
```
```sh
Enter your name:Asabeneh
Year you born:1920
You are Asabeneh. And your age is 99.
I usually run with the try block
I alway run.
```
It is also shorten the above code as follows:
```py
try:
name = input('Enter your name:')
year_born = input('Year you born:')
age = 2019 - int(year_born)
print(f'You are {name}. And your age is {age}.')
except Exception as e:
print(e)
```
## Packing and Unpacking Arguments in Python
We use two operators:
- \* for tuples
- \*\* for dictionaries
Let us take as an example below. It takes only arguments but we have list. We can unpack the list and changes to argument.
### Unpacking
#### Unpacking Lists
```py
def sum_of_five_nums(a, b, c, d, e):
return a + b + c + d + e
lst = [1, 2, 3, 4, 5]
print(sum_of_five_nums(lst)) # TypeError: sum_of_five_nums() missing 4 required positional arguments: 'b', 'c', 'd', and 'e'
```
When we run the this code, it raises an error, because this function takes numbers (not a list) as arguments. Let us unpack/destructure the list.
```py
def sum_of_five_nums(a, b, c, d, e):
return a + b + c + d + e
lst = [1, 2, 3, 4, 5]
print(sum_of_five_nums(*lst)) # 15
```
We can also use unpacking in the range built-in function that expects a start and an end.
```py
numbers = range(2, 7) # normal call with separate arguments
print(list(numbers)) # [2, 3, 4, 5, 6]
args = [2, 7]
numbers = range(*args) # call with arguments unpacked from a list
print(numbers) # [2, 3, 4, 5,6]
```
A list or a tuple can also be unpacked like this:
```py
countries = ['Finland', 'Sweden', 'Norway', 'Denmark', 'Iceland']
fin, sw, nor, *rest = countries
print(fin, sw, nor, rest) # Finland Sweden Norway ['Denmark', 'Iceland']
numbers = [1, 2, 3, 4, 5, 6, 7]
one, *middle, last = numbers
print(one, middle, last) # 1 [2, 3, 4, 5, 6] 7
```
#### Unpacking Dictionaries
```py
def unpacking_person_info(name, country, city, age):
return f'{name} lives in {country}, {city}. He is {age} year old.'
dct = {'name':'Asabeneh', 'country':'Finland', 'city':'Helsinki', 'age':250}
print(unpacking_person_info(**dct)) # Asabeneh lives in Finland, Helsinki. He is 250 years old.
```
### Packing
Sometimes we never know how many arguments need to be passed to a python function. We can use the packing method to allow our function to take unlimited number or arbitrary number of arguments.
### Packing Lists
```py
def sum_all(*args):
s = 0
for i in args:
s += i
return s
print(sum_all(1, 2, 3)) # 6
print(sum_all(1, 2, 3, 4, 5, 6, 7)) # 28
```
#### Packing Dictionaries
```py
def packing_person_info(**kwargs):
# check the type of kwargs and it is a dict type
# print(type(kwargs))
# Printing dictionary items
for key in kwargs:
print(f"{key} = {kwargs[key]}")
return kwargs
print(packing_person_info(name="Asabeneh",
country="Finland", city="Helsinki", age=250))
```
```sh
name = Asabeneh
country = Finland
city = Helsinki
age = 250
{'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
```
## Spreading in Python
Like in JavaScript, spreading is possible in Python. Let us check it in an example below:
```py
lst_one = [1, 2, 3]
lst_two = [4, 5, 6, 7]
lst = [0, *lst_one, *lst_two]
print(lst) # [0, 1, 2, 3, 4, 5, 6, 7]
country_lst_one = ['Finland', 'Sweden', 'Norway']
country_lst_two = ['Denmark', 'Iceland']
nordic_countries = [*country_lst_one, *country_lst_two]
print(nordic_countries) # ['Finland', 'Sweden', 'Norway', 'Denmark', 'Iceland']
```
## Enumerate
If we are interested in an index of a list, we use _enumerate_ built-in function to get the index of each item in the list.
```py
for index, item in enumerate([20, 30, 40]):
print(index, item)
```
```py
countries = ['Finland', 'Sweden', 'Norway', 'Denmark', 'Iceland']
for index, i in enumerate(countries):
if i == 'Finland':
print(f'The country {i} has been found at index {index}')
```
```sh
The country Finland has been found at index 0.
```
## Zip
Sometimes we would like to combine lists when looping through them. See the example below:
```py
fruits = ['banana', 'orange', 'mango', 'lemon', 'lime']
vegetables = ['Tomato', 'Potato', 'Cabbage','Onion', 'Carrot']
fruits_and_veges = []
for f, v in zip(fruits, vegetables):
fruits_and_veges.append({'fruit':f, 'veg':v})
print(fruits_and_veges)
```
```sh
[{'fruit': 'banana', 'veg': 'Tomato'}, {'fruit': 'orange', 'veg': 'Potato'}, {'fruit': 'mango', 'veg': 'Cabbage'}, {'fruit': 'lemon', 'veg': 'Onion'}, {'fruit': 'lime', 'veg': 'Carrot'}]
```
🌕 You are determined. You are 17 steps a head to your way to greatness. Now do some exercises for your brain and muscles.
## Exercises: Day 17
1. names = ['Finland', 'Sweden', 'Norway','Denmark','Iceland', 'Estonia','Russia']. Unpack the first five countries and store them in a variable nordic_countries, store Estonia and Russia in es, and ru respectively.
🎉 CONGRATULATIONS ! 🎉
[<< Day 16](../16_Day_Python_date_time/16_python_datetime.md) | [Day 18 >>](../18_Day_Regular_expressions/18_regular_expressions.md)
================================================
FILE: 18_Day_Regular_expressions/18_regular_expressions.md
================================================
[<< Day 17](../17_Day_Exception_handling/17_exception_handling.md) | [Day 19>>](../19_Day_File_handling/19_file_handling.md)

- [📘 Day 18](#-day-18)
- [Regular Expressions](#regular-expressions)
- [The *re* Module](#the-re-module)
- [Methods in *re* Module](#methods-in-re-module)
- [Match](#match)
- [Search](#search)
- [Searching for All Matches Using *findall*](#searching-for-all-matches-using-findall)
- [Replacing a Substring](#replacing-a-substring)
- [Splitting Text Using RegEx Split](#splitting-text-using-regex-split)
- [Writing RegEx Patterns](#writing-regex-patterns)
- [Square Bracket](#square-bracket)
- [Escape character(\\) in RegEx](#escape-character-in-regex)
- [One or more times(+)](#one-or-more-times)
- [Period(.)](#period)
- [Zero or more times(\*)](#zero-or-more-times)
- [Zero or one time(?)](#zero-or-one-time)
- [Quantifier in RegEx](#quantifier-in-regex)
- [Cart ^](#cart-)
- [💻 Exercises: Day 18](#-exercises-day-18)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# 📘 Day 18
## Regular Expressions
A regular expression or RegEx is a special text string that helps to find patterns in data. A RegEx can be used to check if some pattern exists in a different data type. To use RegEx in python first we should import the RegEx module which is called *re*.
### The *re* Module
After importing the module we can use it to detect or find patterns.
```py
import re
```
### Methods in *re* Module
To find a pattern we use different set of *re* character sets that allows to search for a match in a string.
- *re.match()*: searches only in the beginning of the first line of the string and returns matched objects if found, else returns None.
- *re.search*: Returns a match object if there is one anywhere in the string, including multiline strings.
- *re.findall*: Returns a list containing all matches
- *re.split*: Takes a string, splits it at the match points, returns a list
- *re.sub*: Replaces one or many matches within a string
#### Match
```py
# syntax
re.match(substring, string, re.I)
# substring is a string or a pattern, string is the text we look for a pattern , re.I is case ignore
```
```py
import re
txt = 'I love to teach python and javaScript'
# It returns an object with span, and match
match = re.match('I love to teach', txt, re.I)
print(match) #
# We can get the starting and ending position of the match as tuple using span
span = match.span()
print(span) # (0, 15)
# Lets find the start and stop position from the span
start, end = span
print(start, end) # 0 15
substring = txt[start:end]
print(substring) # I love to teach
```
As you can see from the example above, the pattern we are looking for (or the substring we are looking for) is *I love to teach*. The match function returns an object **only** if the text starts with the pattern.
```py
import re
txt = 'I love to teach python and javaScript'
match = re.match('I like to teach', txt, re.I)
print(match) # None
```
The string does not string with *I like to teach*, therefore there was no match and the match method returned None.
#### Search
```py
# syntax
re.search(substring, string, re.I)
# substring is a pattern, string is the text we look for a pattern , re.I is case ignore flag
```
```py
import re
txt = '''Python is the most beautiful language that a human being has ever created.
I recommend python for a first programming language'''
# It returns an object with span and match
match = re.search('first', txt, re.I)
print(match) #
# We can get the starting and ending position of the match as tuple using span
span = match.span()
print(span) # (100, 105)
# Lets find the start and stop position from the span
start, end = span
print(start, end) # 100 105
substring = txt[start:end]
print(substring) # first
```
As you can see, search is much better than match because it can look for the pattern throughout the text. Search returns a match object with a first match that was found, otherwise it returns *None*. A much better *re* function is *findall*. This function checks for the pattern through the whole string and returns all the matches as a list.
#### Searching for All Matches Using *findall*
*findall()* returns all the matches as a list
```py
txt = '''Python is the most beautiful language that a human being has ever created.
I recommend python for a first programming language'''
# It return a list
matches = re.findall('language', txt, re.I)
print(matches) # ['language', 'language']
```
As you can see, the word *language* was found two times in the string. Let us practice some more.
Now we will look for both Python and python words in the string:
```py
txt = '''Python is the most beautiful language that a human being has ever created.
I recommend python for a first programming language'''
# It returns list
matches = re.findall('python', txt, re.I)
print(matches) # ['Python', 'python']
```
Since we are using *re.I* both lowercase and uppercase letters are included. If we do not have the re.I flag, then we will have to write our pattern differently. Let us check it out:
```py
txt = '''Python is the most beautiful language that a human being has ever created.
I recommend python for a first programming language'''
matches = re.findall('Python|python', txt)
print(matches) # ['Python', 'python']
#
matches = re.findall('[Pp]ython', txt)
print(matches) # ['Python', 'python']
```
#### Replacing a Substring
```py
txt = '''Python is the most beautiful language that a human being has ever created.
I recommend python for a first programming language'''
match_replaced = re.sub('Python|python', 'JavaScript', txt, re.I)
print(match_replaced) # JavaScript is the most beautiful language that a human being has ever created.I recommend python for a first programming language
# OR
match_replaced = re.sub('[Pp]ython', 'JavaScript', txt, re.I)
print(match_replaced) # JavaScript is the most beautiful language that a human being has ever created.I recommend python for a first programming language
```
Let us add one more example. The following string is really hard to read unless we remove the % symbol. Replacing the % with an empty string will clean the text.
```py
txt = '''%I a%m te%%a%%che%r% a%n%d %% I l%o%ve te%ach%ing.
T%he%re i%s n%o%th%ing as r%ewarding a%s e%duc%at%i%ng a%n%d e%m%p%ow%er%ing p%e%o%ple.
I fo%und te%a%ching m%ore i%n%t%er%%es%ting t%h%an any other %jobs.
D%o%es thi%s m%ot%iv%a%te %y%o%u to b%e a t%e%a%cher?'''
matches = re.sub('%', '', txt)
print(matches)
```
```sh
I am teacher and I love teaching.
There is nothing as rewarding as educating and empowering people.
I found teaching more interesting than any other jobs. Does this motivate you to be a teacher?
```
## Splitting Text Using RegEx Split
```py
txt = '''I am teacher and I love teaching.
There is nothing as rewarding as educating and empowering people.
I found teaching more interesting than any other jobs.
Does this motivate you to be a teacher?'''
print(re.split('\n', txt)) # splitting using \n - end of line symbol
```
```sh
['I am teacher and I love teaching.', 'There is nothing as rewarding as educating and empowering people.', 'I found teaching more interesting than any other jobs.', 'Does this motivate you to be a teacher?']
```
## Writing RegEx Patterns
To declare a string variable we use a single or double quote. To declare RegEx variable *r''*.
The following pattern only identifies apple with lowercase, to make it case insensitive either we should rewrite our pattern or we should add a flag.
```py
import re
regex_pattern = r'apple'
txt = 'Apple and banana are fruits. An old cliche says an apple a day a doctor way has been replaced by a banana a day keeps the doctor far far away. '
matches = re.findall(regex_pattern, txt)
print(matches) # ['apple']
# To make case insensitive adding flag '
matches = re.findall(regex_pattern, txt, re.I)
print(matches) # ['Apple', 'apple']
# or we can use a set of characters method
regex_pattern = r'[Aa]pple' # this mean the first letter could be Apple or apple
matches = re.findall(regex_pattern, txt)
print(matches) # ['Apple', 'apple']
```
* []: A set of characters
- [a-c] means, a or b or c
- [a-z] means, any letter from a to z
- [A-Z] means, any character from A to Z
- [0-3] means, 0 or 1 or 2 or 3
- [0-9] means any number from 0 to 9
- [A-Za-z0-9] any single character, that is a to z, A to Z or 0 to 9
- \\: uses to escape special characters
- \d means: match where the string contains digits (numbers from 0-9)
- \D means: match where the string does not contain digits
- . : any character except new line character(\n)
- ^: starts with
- r'^substring' eg r'^love', a sentence that starts with a word love
- r'[^abc] means not a, not b, not c.
- $: ends with
- r'substring$' eg r'love$', sentence that ends with a word love
- *: zero or more times
- r'[a]*' means a optional or it can occur many times.
- +: one or more times
- r'[a]+' means at least once (or more)
- ?: zero or one time
- r'[a]?' means zero times or once
- {3}: Exactly 3 characters
- {3,}: At least 3 characters
- {3,8}: 3 to 8 characters
- |: Either or
- r'apple|banana' means either apple or a banana
- (): Capture and group

Let us use examples to clarify the meta characters above
### Square Bracket
Let us use square bracket to include lower and upper case
```py
regex_pattern = r'[Aa]pple' # this square bracket mean either A or a
txt = 'Apple and banana are fruits. An old cliche says an apple a day a doctor way has been replaced by a banana a day keeps the doctor far far away.'
matches = re.findall(regex_pattern, txt)
print(matches) # ['Apple', 'apple']
```
If we want to look for the banana, we write the pattern as follows:
```py
regex_pattern = r'[Aa]pple|[Bb]anana' # this square bracket means either A or a
txt = 'Apple and banana are fruits. An old cliche says an apple a day a doctor way has been replaced by a banana a day keeps the doctor far far away.'
matches = re.findall(regex_pattern, txt)
print(matches) # ['Apple', 'banana', 'apple', 'banana']
```
Using the square bracket and or operator , we manage to extract Apple, apple, Banana and banana.
### Escape character(\\) in RegEx
```py
regex_pattern = r'\d' # d is a special character which means digits
txt = 'This regular expression example was made on December 6, 2019 and revised on July 8, 2021'
matches = re.findall(regex_pattern, txt)
print(matches) # ['6', '2', '0', '1', '9', '8', '2', '0', '2', '1'], this is not what we want
```
### One or more times(+)
```py
regex_pattern = r'\d+' # d is a special character which means digits, + mean one or more times
txt = 'This regular expression example was made on December 6, 2019 and revised on July 8, 2021'
matches = re.findall(regex_pattern, txt)
print(matches) # ['6', '2019', '8', '2021'] - now, this is better!
```
### Period(.)
```py
regex_pattern = r'[a].' # this square bracket means a and . means any character except new line
txt = '''Apple and banana are fruits'''
matches = re.findall(regex_pattern, txt)
print(matches) # ['an', 'an', 'an', 'a ', 'ar']
regex_pattern = r'[a].+' # . any character, + any character one or more times
matches = re.findall(regex_pattern, txt)
print(matches) # ['and banana are fruits']
```
### Zero or more times(\*)
Zero or many times. The pattern could may not occur or it can occur many times.
```py
regex_pattern = r'[a].*' # . any character, * any character zero or more times
txt = '''Apple and banana are fruits'''
matches = re.findall(regex_pattern, txt)
print(matches) # ['and banana are fruits']
```
### Zero or one time(?)
Zero or one time. The pattern may not occur or it may occur once.
```py
txt = '''I am not sure if there is a convention how to write the word e-mail.
Some people write it as email others may write it as Email or E-mail.'''
regex_pattern = r'[Ee]-?mail' # ? means here that '-' is optional
matches = re.findall(regex_pattern, txt)
print(matches) # ['e-mail', 'email', 'Email', 'E-mail']
```
### Quantifier in RegEx
We can specify the length of the substring we are looking for in a text, using a curly bracket. Let us imagine, we are interested in a substring with a length of 4 characters:
```py
txt = 'This regular expression example was made on December 6, 2019 and revised on July 8, 2021'
regex_pattern = r'\d{4}' # exactly four times
matches = re.findall(regex_pattern, txt)
print(matches) # ['2019', '2021']
txt = 'This regular expression example was made on December 6, 2019 and revised on July 8, 2021'
regex_pattern = r'\d{1,4}'
matches = re.findall(regex_pattern, txt)
print(matches) # ['6', '2019', '8', '2021']
```
### Cart ^
- Starts with
```py
txt = 'This regular expression example was made on December 6, 2019 and revised on July 8, 2021'
regex_pattern = r'^This' # ^ means starts with
matches = re.findall(regex_pattern, txt)
print(matches) # ['This']
```
- Negation
```py
txt = 'This regular expression example was made on December 6, 2019 and revised on July 8, 2021'
regex_pattern = r'[^A-Za-z ]+' # ^ in set character means negation, not A to Z, not a to z, no space
matches = re.findall(regex_pattern, txt)
print(matches) # ['6,', '2019', '8', '2021']
```
## 💻 Exercises: Day 18
### Exercises: Level 1
1. What is the most frequent word in the following paragraph?
```py
paragraph = 'I love teaching. If you do not love teaching what else can you love. I love Python if you do not love something which can give you all the capabilities to develop an application what else can you love.
```
```sh
[
(6, 'love'),
(5, 'you'),
(3, 'can'),
(2, 'what'),
(2, 'teaching'),
(2, 'not'),
(2, 'else'),
(2, 'do'),
(2, 'I'),
(1, 'which'),
(1, 'to'),
(1, 'the'),
(1, 'something'),
(1, 'if'),
(1, 'give'),
(1, 'develop'),
(1, 'capabilities'),
(1, 'application'),
(1, 'an'),
(1, 'all'),
(1, 'Python'),
(1, 'If')
]
```
2. The position of some particles on the horizontal x-axis are -12, -4, -3 and -1 in the negative direction, 0 at origin, 4 and 8 in the positive direction. Extract these numbers from this whole text and find the distance between the two furthest particles.
```py
points = ['-12', '-4', '-3', '-1', '0', '4', '8']
sorted_points = [-12, -4, -3, -1, -1, 0, 2, 4, 8]
distance = 8 -(-12) # 20
```
### Exercises: Level 2
1. Write a pattern which identifies if a string is a valid python variable
```sh
is_valid_variable('first_name') # True
is_valid_variable('first-name') # False
is_valid_variable('1first_name') # False
is_valid_variable('firstname') # True
```
### Exercises: Level 3
1. Clean the following text. After cleaning, count three most frequent words in the string.
```py
sentence = '''%I $am@% a %tea@cher%, &and& I lo%#ve %tea@ching%;. There $is nothing; &as& mo@re rewarding as educa@ting &and& @emp%o@wering peo@ple. ;I found tea@ching m%o@re interesting tha@n any other %jo@bs. %Do@es thi%s mo@tivate yo@u to be a tea@cher!?'''
print(clean_text(sentence));
I am a teacher and I love teaching There is nothing as more rewarding as educating and empowering people I found teaching more interesting than any other jobs Does this motivate you to be a teacher
print(most_frequent_words(cleaned_text)) # [(3, 'I'), (2, 'teaching'), (2, 'teacher')]
```
🎉 CONGRATULATIONS ! 🎉
[<< Day 17](../17_Day_Exception_handling/17_exception_handling.md) | [Day 19>>](../19_Day_File_handling/19_file_handling.md)
================================================
FILE: 19_Day_File_handling/19_file_handling.md
================================================
[<< Day 18](../18_Day_Regular_expressions/18_regular_expressions.md) | [Day 20 >>](../20_Day_Python_package_manager/20_python_package_manager.md)

- [📘 Day 19](#-day-19)
- [File Handling](#file-handling)
- [Opening Files for Reading](#opening-files-for-reading)
- [Opening Files for Writing and Updating](#opening-files-for-writing-and-updating)
- [Deleting Files](#deleting-files)
- [File Types](#file-types)
- [File with txt Extension](#file-with-txt-extension)
- [File with json Extension](#file-with-json-extension)
- [Changing JSON to Dictionary](#changing-json-to-dictionary)
- [Changing Dictionary to JSON](#changing-dictionary-to-json)
- [Saving as JSON File](#saving-as-json-file)
- [File with csv Extension](#file-with-csv-extension)
- [File with xlsx Extension](#file-with-xlsx-extension)
- [File with xml Extension](#file-with-xml-extension)
- [💻 Exercises: Day 19](#-exercises-day-19)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# 📘 Day 19
## File Handling
So far we have seen different Python data types. We usually store our data in different file formats. In addition to handling files, we will also see different file formats(.txt, .json, .xml, .csv, .tsv, .excel) in this section. First, let us get familiar with handling files with common file format(.txt).
File handling is an import part of programming which allows us to create, read, update and delete files. In Python to handle data we use _open()_ built-in function.
```py
# Syntax
open('filename', mode) # mode(r, a, w, x, t,b) could be to read, write, update
```
- "r" - Read - Default value. Opens a file for reading, it returns an error if the file does not exist
- "a" - Append - Opens a file for appending, creates the file if it does not exist
- "w" - Write - Opens a file for writing, creates the file if it does not exist
- "x" - Create - Creates the specified file, returns an error if the file exists
- "t" - Text - Default value. Text mode
- "b" - Binary - Binary mode (e.g. images)
### Opening Files for Reading
The default mode of _open_ is reading, so we do not have to specify 'r' or 'rt'. I have created and saved a file named reading_file_example.txt in the files directory. Let us see how it is done:
```py
f = open('./files/reading_file_example.txt')
print(f) # <_io.TextIOWrapper name='./files/reading_file_example.txt' mode='r' encoding='UTF-8'>
```
As you can see in the example above, I printed the opened file and it gave some information about it. Opened file has different reading methods: _read()_, _readline_, _readlines_. An opened file has to be closed with _close()_ method.
- _read()_: read the whole text as string. If we want to limit the number of characters we want to read, we can limit it by passing int value to the *read(number)* method.
```py
f = open('./files/reading_file_example.txt')
txt = f.read()
print(type(txt))
print(txt)
f.close()
```
```sh
# output
This is an example to show how to open a file and read.
This is the second line of the text.
```
Instead of printing all the text, let us print the first 10 characters of the text file.
```py
f = open('./files/reading_file_example.txt')
txt = f.read(10)
print(type(txt))
print(txt)
f.close()
```
```sh
# output
This is an
```
- _readline()_: read only the first line
```py
f = open('./files/reading_file_example.txt')
line = f.readline()
print(type(line))
print(line)
f.close()
```
```sh
# output
This is an example to show how to open a file and read.
```
- _readlines()_: read all the text line by line and returns a list of lines
```py
f = open('./files/reading_file_example.txt')
lines = f.readlines()
print(type(lines))
print(lines)
f.close()
```
```sh
# output
['This is an example to show how to open a file and read.\n', 'This is the second line of the text.']
```
Another way to get all the lines as a list is using _splitlines()_:
```py
f = open('./files/reading_file_example.txt')
lines = f.read().splitlines()
print(type(lines))
print(lines)
f.close()
```
```sh
# output
['This is an example to show how to open a file and read.', 'This is the second line of the text.']
```
After we open a file, we should close it. There is a high tendency of forgetting to close them. There is a new way of opening files using _with_ - closes the files by itself. Let us rewrite the the previous example with the _with_ method:
```py
with open('./files/reading_file_example.txt') as f:
lines = f.read().splitlines()
print(type(lines))
print(lines)
```
```sh
# output
['This is an example to show how to open a file and read.', 'This is the second line of the text.']
```
### Opening Files for Writing and Updating
To write to an existing file, we must add a mode as parameter to the _open()_ function:
- "a" - append - will append to the end of the file, if the file does not exist it creates a new file.
- "w" - write - will overwrite any existing content, if the file does not exist it creates.
Let us append some text to the file we have been reading:
```py
with open('./files/reading_file_example.txt','a') as f:
f.write('This text has to be appended at the end')
```
The method below creates a new file, if the file does not exist:
```py
with open('./files/writing_file_example.txt','w') as f:
f.write('This text will be written in a newly created file')
```
### Deleting Files
We have seen in previous section, how to make and remove a directory using _os_ module. Again now, if we want to remove a file we use _os_ module.
```py
import os
os.remove('./files/example.txt')
```
If the file does not exist, the remove method will raise an error, so it is good to use a condition like this:
```py
import os
if os.path.exists('./files/example.txt'):
os.remove('./files/example.txt')
else:
print('The file does not exist')
```
## File Types
### File with txt Extension
File with _txt_ extension is a very common form of data and we have covered it in the previous section. Let us move to the JSON file
### File with json Extension
JSON stands for JavaScript Object Notation. Actually, it is a stringified JavaScript object or Python dictionary.
_Example:_
```py
# dictionary
person_dct= {
"name":"Asabeneh",
"country":"Finland",
"city":"Helsinki",
"skills":["JavaScrip", "React","Python"]
}
# JSON: A string form a dictionary
person_json = "{'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'skills': ['JavaScrip', 'React', 'Python']}"
# we use three quotes and make it multiple line to make it more readable
person_json = '''{
"name":"Asabeneh",
"country":"Finland",
"city":"Helsinki",
"skills":["JavaScrip", "React","Python"]
}'''
```
### Changing JSON to Dictionary
To change a JSON to a dictionary, first we import the json module and then we use _loads_ method.
```py
import json
# JSON
person_json = '''{
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"skills": ["JavaScrip", "React", "Python"]
}'''
# let's change JSON to dictionary
person_dct = json.loads(person_json)
print(type(person_dct))
print(person_dct)
print(person_dct['name'])
```
```sh
# output
{'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'skills': ['JavaScrip', 'React', 'Python']}
Asabeneh
```
### Changing Dictionary to JSON
To change a dictionary to a JSON we use _dumps_ method from the json module.
```py
import json
# python dictionary
person = {
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"skills": ["JavaScrip", "React", "Python"]
}
# let's convert it to json
person_json = json.dumps(person, indent=4) # indent could be 2, 4, 8. It beautifies the json
print(type(person_json))
print(person_json)
```
```sh
# output
# when you print it, it does not have the quote, but actually it is a string
# JSON does not have type, it is a string type.
{
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"skills": [
"JavaScrip",
"React",
"Python"
]
}
```
### Saving as JSON File
We can also save our data as a json file. Let us save it as a json file using the following steps. For writing a json file, we use the json.dump() method, it can take dictionary, output file, ensure_ascii and indent.
```py
import json
# python dictionary
person = {
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"skills": ["JavaScrip", "React", "Python"]
}
with open('./files/json_example.json', 'w', encoding='utf-8') as f:
json.dump(person, f, ensure_ascii=False, indent=4)
```
In the code above, we use encoding and indentation. Indentation makes the json file easy to read.
### File with csv Extension
CSV stands for comma separated values. CSV is a simple file format used to store tabular data, such as a spreadsheet or database. CSV is a very common data format in data science.
**Example:**
```csv
"name","country","city","skills"
"Asabeneh","Finland","Helsinki","JavaScript"
```
**Example:**
```py
import csv
with open('./files/csv_example.csv') as f:
csv_reader = csv.reader(f, delimiter=',') # we use, reader method to read csv
line_count = 0
for row in csv_reader:
if line_count == 0:
print(f'Column names are :{", ".join(row)}')
line_count += 1
else:
print(
f'\t{row[0]} is a teachers. He lives in {row[1]}, {row[2]}.')
line_count += 1
print(f'Number of lines: {line_count}')
```
```sh
# output:
Column names are :name, country, city, skills
Number of lines: 1
Asabeneh is a teacher. He lives in Finland, Helsinki.
Number of lines: 2
```
### File with xlsx Extension
To read excel files we need to install _xlrd_ package. We will cover this after we cover package installing using pip.
```py
import xlrd
excel_book = xlrd.open_workbook('sample.xls')
print(excel_book.nsheets)
print(excel_book.sheet_names)
```
### File with xml Extension
XML is another structured data format which looks like HTML. In XML the tags are not predefined. The first line is an XML declaration. The person tag is the root of the XML. The person has a gender attribute.
**Example:XML**
```xml
AsabenehFinlandHelsinkiJavaScripReactPython
```
For more information on how to read an XML file check the [documentation](https://docs.python.org/2/library/xml.etree.elementtree.html)
```py
import xml.etree.ElementTree as ET
tree = ET.parse('./files/xml_example.xml')
root = tree.getroot()
print('Root tag:', root.tag)
print('Attribute:', root.attrib)
for child in root:
print('field: ', child.tag)
```
```sh
# output
Root tag: person
Attribute: {'gender': 'male'}
field: name
field: country
field: city
field: skills
```
🌕 You are making a big progress. Maintain your momentum, keep the good work. Now do some exercises for your brain and muscles.
## 💻 Exercises: Day 19
### Exercises: Level 1
1. Write a function which count number of lines and number of words in a text. All the files are in the data the folder:
1) Read obama_speech.txt file and count number of lines and words
2) Read michelle_obama_speech.txt file and count number of lines and words
3) Read donald_speech.txt file and count number of lines and words
4) Read melina_trump_speech.txt file and count number of lines and words
2. Read the countries_data.json data file in data directory, create a function that finds the ten most spoken languages
```py
# Your output should look like this
print(most_spoken_languages(filename='./data/countries_data.json', 10))
[(91, 'English'),
(45, 'French'),
(25, 'Arabic'),
(24, 'Spanish'),
(9, 'Russian'),
(9, 'Portuguese'),
(8, 'Dutch'),
(7, 'German'),
(5, 'Chinese'),
(4, 'Swahili'),
(4, 'Serbian')]
# Your output should look like this
print(most_spoken_languages(filename='./data/countries_data.json', 3))
[(91, 'English'),
(45, 'French'),
(25, 'Arabic')]
```
3. Read the countries_data.json data file in data directory, create a function that creates a list of the ten most populated countries
```py
# Your output should look like this
print(most_populated_countries(filename='./data/countries_data.json', 10))
[
{'country': 'China', 'population': 1377422166},
{'country': 'India', 'population': 1295210000},
{'country': 'United States of America', 'population': 323947000},
{'country': 'Indonesia', 'population': 258705000},
{'country': 'Brazil', 'population': 206135893},
{'country': 'Pakistan', 'population': 194125062},
{'country': 'Nigeria', 'population': 186988000},
{'country': 'Bangladesh', 'population': 161006790},
{'country': 'Russian Federation', 'population': 146599183},
{'country': 'Japan', 'population': 126960000}
]
# Your output should look like this
print(most_populated_countries(filename='./data/countries_data.json', 3))
[
{'country': 'China', 'population': 1377422166},
{'country': 'India', 'population': 1295210000},
{'country': 'United States of America', 'population': 323947000}
]
```
### Exercises: Level 2
1. Extract all incoming email addresses as a list from the email_exchange_big.txt file.
2. Find the most common words in the English language. Call the name of your function find_most_common_words, it will take two parameters - a string or a file and a positive integer, indicating the number of words. Your function will return an array of tuples in descending order. Check the output
```py
# Your output should look like this
print(find_most_common_words('sample.txt', 10))
[(10, 'the'),
(8, 'be'),
(6, 'to'),
(6, 'of'),
(5, 'and'),
(4, 'a'),
(4, 'in'),
(3, 'that'),
(2, 'have'),
(2, 'I')]
# Your output should look like this
print(find_most_common_words('sample.txt', 5))
[(10, 'the'),
(8, 'be'),
(6, 'to'),
(6, 'of'),
(5, 'and')]
```
3. Use the function, find_most_frequent_words to find:
1) The ten most frequent words used in [Obama's speech](https://github.com/Asabeneh/30-Days-Of-Python/blob/master/data/obama_speech.txt)
2) The ten most frequent words used in [Michelle's speech](https://github.com/Asabeneh/30-Days-Of-Python/blob/master/data/michelle_obama_speech.txt)
3) The ten most frequent words used in [Trump's speech](https://github.com/Asabeneh/30-Days-Of-Python/blob/master/data/donald_speech.txt)
4) The ten most frequent words used in [Melina's speech](https://github.com/Asabeneh/30-Days-Of-Python/blob/master/data/melina_trump_speech.txt)
4. Write a python application that checks similarity between two texts. It takes a file or a string as a parameter and it will evaluate the similarity of the two texts. For instance check the similarity between the transcripts of [Michelle's](https://github.com/Asabeneh/30-Days-Of-Python/blob/master/data/michelle_obama_speech.txt) and [Melina's](https://github.com/Asabeneh/30-Days-Of-Python/blob/master/data/melina_trump_speech.txt) speech. You may need a couple of functions, function to clean the text(clean_text), function to remove support words(remove_support_words) and finally to check the similarity(check_text_similarity). List of [stop words](https://github.com/Asabeneh/30-Days-Of-Python/blob/master/data/stop_words.py) are in the data directory
5. Find the 10 most repeated words in the romeo_and_juliet.txt
6. Read the [hacker news csv](https://github.com/Asabeneh/30-Days-Of-Python/blob/master/data/hacker_news.csv) file and find out:
1) Count the number of lines containing python or Python
2) Count the number lines containing JavaScript, javascript or Javascript
3) Count the number lines containing Java and not JavaScript
🎉 CONGRATULATIONS ! 🎉
[<< Day 18](../18_Day_Regular_expressions/18_regular_expressions.md) | [Day 20 >>](../20_Day_Python_package_manager/20_python_package_manager.md)
================================================
FILE: 20_Day_Python_package_manager/20_python_package_manager.md
================================================
[<< Day 19](../19_Day_File_handling/19_file_handling.md) | [Day 21 >>](../21_Day_Classes_and_objects/21_classes_and_objects.md)

- [📘 Day 20](#-day-20)
- [Python PIP - Python Package Manager](#python-pip---python-package-manager)
- [What is PIP ?](#what-is-pip-)
- [Installing PIP](#installing-pip)
- [Installing packages using pip](#installing-packages-using-pip)
- [Uninstalling Packages](#uninstalling-packages)
- [List of Packages](#list-of-packages)
- [Show Package](#show-package)
- [PIP Freeze](#pip-freeze)
- [Reading from URL](#reading-from-url)
- [Creating a Package](#creating-a-package)
- [Further Information About Packages](#further-information-about-packages)
- [Exercises: Day 20](#exercises-day-20)
# 📘 Day 20
## Python PIP - Python Package Manager
### What is PIP ?
PIP stands for Preferred installer program. We use _pip_ to install different Python packages.
Package is a Python module that can contain one or more modules or other packages. A module or modules that we can install to our application is a package.
In programming, we do not have to write every utility program, instead we install packages and import them to our applications.
### Installing PIP
If you did not install pip, let us install it now. Go to your terminal or command prompt and copy and paste this:
```sh
asabeneh@Asabeneh:~$ pip install pip
```
Check if pip is installed by writing
```sh
pip --version
```
```py
asabeneh@Asabeneh:~$ pip --version
pip 21.1.3 from /usr/local/lib/python3.7/site-packages/pip (python 3.9.6)
```
As you can see, I am using pip version 21.1.3, if you see some number a bit below or above that, means you have pip installed.
Let us check some of the packages used in the Python community for different purposes. Just to let you know that there are lots of packages available for use with different applications.
### Installing packages using pip
Let us try to install _numpy_, called numeric python. It is one of the most popular packages in machine learning and data science community.
- NumPy is the fundamental package for scientific computing with Python. It contains among other things:
- a powerful N-dimensional array object
- sophisticated (broadcasting) functions
- tools for integrating C/C++ and Fortran code
- useful linear algebra, Fourier transform, and random number capabilities
```sh
asabeneh@Asabeneh:~$ pip install numpy
```
Let us start using numpy. Open your python interactive shell, write python and then import numpy as follows:
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
>>> numpy.version.version
'1.20.1'
>>> lst = [1, 2, 3,4, 5]
>>> np_arr = numpy.array(lst)
>>> np_arr
array([1, 2, 3, 4, 5])
>>> len(np_arr)
5
>>> np_arr * 2
array([ 2, 4, 6, 8, 10])
>>> np_arr + 2
array([3, 4, 5, 6, 7])
>>>
```
Pandas is an open source, BSD-licensed library providing high-performance, easy-to-use data structures and data analysis tools for the Python programming language. Let us install the big brother of numpy, _pandas_:
```sh
asabeneh@Asabeneh:~$ pip install pandas
```
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pandas
```
This section is not about numpy nor pandas, here we are trying to learn how to install packages and how to import them. If it is needed, we will talk about different packages in other sections.
Let us import a web browser module, which can help us to open any website. We do not need to install this module, it is already installed by default with Python 3. For instance if you like to open any number of websites at any time or if you like to schedule something, this _webbrowser_ module can be used.
```py
import webbrowser # web browser module to open websites
# list of urls: python
url_lists = [
'http://www.python.org',
'https://www.linkedin.com/in/asabeneh/',
'https://github.com/Asabeneh',
'https://twitter.com/Asabeneh',
]
# opens the above list of websites in a different tab
for url in url_lists:
webbrowser.open_new_tab(url)
```
### Uninstalling Packages
If you do not like to keep the installed packages, you can remove them using the following command.
```sh
pip uninstall packagename
```
### List of Packages
To see the installed packages on our machine. We can use pip followed by list.
```sh
pip list
```
### Show Package
To show information about a package
```sh
pip show packagename
```
```sh
asabeneh@Asabeneh:~$ pip show pandas
Name: pandas
Version: 1.2.3
Summary: Powerful data structures for data analysis, time series, and statistics
Home-page: http://pandas.pydata.org
Author: None
Author-email: None
License: BSD
Location: /usr/local/lib/python3.7/site-packages
Requires: python-dateutil, pytz, numpy
Required-by:
```
If we want even more details, just add --verbose
```sh
asabeneh@Asabeneh:~$ pip show --verbose pandas
Name: pandas
Version: 1.2.3
Summary: Powerful data structures for data analysis, time series, and statistics
Home-page: http://pandas.pydata.org
Author: None
Author-email: None
License: BSD
Location: /usr/local/lib/python3.7/site-packages
Requires: numpy, pytz, python-dateutil
Required-by:
Metadata-Version: 2.1
Installer: pip
Classifiers:
Development Status :: 5 - Production/Stable
Environment :: Console
Operating System :: OS Independent
Intended Audience :: Science/Research
Programming Language :: Python
Programming Language :: Python :: 3
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Cython
Topic :: Scientific/Engineering
Entry-points:
[pandas_plotting_backends]
matplotlib = pandas:plotting._matplotlib
```
### PIP Freeze
Generate installed Python packages with their version and the output is suitable to use it in a requirements file. A requirements.txt file is a file that should contain all the installed Python packages in a Python project.
```sh
asabeneh@Asabeneh:~$ pip freeze
docutils==0.11
Jinja2==2.7.2
MarkupSafe==0.19
Pygments==1.6
Sphinx==1.2.2
```
The pip freeze gave us the packages used, installed and their version. We use it with requirements.txt file for deployment.
### Reading from URL
By now you are familiar with how to read or write on a file located on you local machine. Sometimes, we would like to read from a website using url or from an API.
API stands for Application Program Interface. It is a means to exchange structured data between servers primarily as json data. To open a network connection, we need a package called _requests_ - it allows to open a network connection and to implement CRUD(create, read, update and delete) operations. In this section, we will cover only reading ore getting part of a CRUD.
Let us install _requests_:
```py
asabeneh@Asabeneh:~$ pip install requests
```
We will see _get_, _status_code_, _headers_, _text_ and _json_ methods in _requests_ module:
- _get()_: to open a network and fetch data from url - it returns a response object
- _status_code_: After we fetched data, we can check the status of the operation (success, error, etc)
- _headers_: To check the header types
- _text_: to extract the text from the fetched response object
- _json_: to extract json data
Let's read a txt file from this website, https://www.w3.org/TR/PNG/iso_8859-1.txt.
```py
import requests # importing the request module
url = 'https://www.w3.org/TR/PNG/iso_8859-1.txt' # text from a website
response = requests.get(url) # opening a network and fetching a data
print(response)
print(response.status_code) # status code, success:200
print(response.headers) # headers information
print(response.text) # gives all the text from the page
```
```sh
200
{'date': 'Sun, 08 Dec 2019 18:00:31 GMT', 'last-modified': 'Fri, 07 Nov 2003 05:51:11 GMT', 'etag': '"17e9-3cb82080711c0;50c0b26855880-gzip"', 'accept-ranges': 'bytes', 'cache-control': 'max-age=31536000', 'expires': 'Mon, 07 Dec 2020 18:00:31 GMT', 'vary': 'Accept-Encoding', 'content-encoding': 'gzip', 'access-control-allow-origin': '*', 'content-length': '1616', 'content-type': 'text/plain', 'strict-transport-security': 'max-age=15552000; includeSubdomains; preload', 'content-security-policy': 'upgrade-insecure-requests'}
```
- Let us read from an API. API stands for Application Program Interface. It is a means to exchange structure data between servers primarily a json data. An example of an API:https://restcountries.eu/rest/v2/all. Let us read this API using _requests_ module.
```py
import requests
url = 'https://restcountries.eu/rest/v2/all' # countries api
response = requests.get(url) # opening a network and fetching a data
print(response) # response object
print(response.status_code) # status code, success:200
countries = response.json()
print(countries[:1]) # we sliced only the first country, remove the slicing to see all countries
```
```sh
200
[{'alpha2Code': 'AF',
'alpha3Code': 'AFG',
'altSpellings': ['AF', 'Afġānistān'],
'area': 652230.0,
'borders': ['IRN', 'PAK', 'TKM', 'UZB', 'TJK', 'CHN'],
'callingCodes': ['93'],
'capital': 'Kabul',
'cioc': 'AFG',
'currencies': [{'code': 'AFN', 'name': 'Afghan afghani', 'symbol': '؋'}],
'demonym': 'Afghan',
'flag': 'https://restcountries.eu/data/afg.svg',
'gini': 27.8,
'languages': [{'iso639_1': 'ps',
'iso639_2': 'pus',
'name': 'Pashto',
'nativeName': 'پښتو'},
{'iso639_1': 'uz',
'iso639_2': 'uzb',
'name': 'Uzbek',
'nativeName': 'Oʻzbek'},
{'iso639_1': 'tk',
'iso639_2': 'tuk',
'name': 'Turkmen',
'nativeName': 'Türkmen'}],
'latlng': [33.0, 65.0],
'name': 'Afghanistan',
'nativeName': 'افغانستان',
'numericCode': '004',
'population': 27657145,
'region': 'Asia',
'regionalBlocs': [{'acronym': 'SAARC',
'name': 'South Asian Association for Regional Cooperation',
'otherAcronyms': [],
'otherNames': []}],
'subregion': 'Southern Asia',
'timezones': ['UTC+04:30'],
'topLevelDomain': ['.af'],
'translations': {'br': 'Afeganistão',
'de': 'Afghanistan',
'es': 'Afganistán',
'fa': 'افغانستان',
'fr': 'Afghanistan',
'hr': 'Afganistan',
'it': 'Afghanistan',
'ja': 'アフガニスタン',
'nl': 'Afghanistan',
'pt': 'Afeganistão'}}]
```
We use _json()_ method from response object, if the we are fetching JSON data. For txt, html, xml and other file formats we can use _text_.
### Creating a Package
We organize a large number of files in different folders and sub-folders based on some criteria, so that we can find and manage them easily. As you know, a module can contain multiple objects, such as classes, functions, etc. A package can contain one or more relevant modules. A package is actually a folder containing one or more module files. Let us create a package named mypackage, using the following steps:
Create a new folder named mypackage inside 30DaysOfPython folder
Create an empty **__init__**.py file in the mypackage folder.
Create modules arithmetic.py and greet.py with following code:
```py
# mypackage/arithmetics.py
# arithmetics.py
def add_numbers(*args):
total = 0
for num in args:
total += num
return total
def subtract(a, b):
return (a - b)
def multiple(a, b):
return a * b
def division(a, b):
return a / b
def remainder(a, b):
return a % b
def power(a, b):
return a ** b
```
```py
# mypackage/greet.py
# greet.py
def greet_person(firstname, lastname):
return f'{firstname} {lastname}, welcome to 30DaysOfPython Challenge!'
```
The folder structure of your package should look like this:
```sh
─ mypackage
├── __init__.py
├── arithmetic.py
└── greet.py
```
Now let's open the python interactive shell and try the package we have created:
```sh
asabeneh@Asabeneh:~/Desktop/30DaysOfPython$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from mypackage import arithmetics
>>> arithmetics.add_numbers(1, 2, 3, 5)
11
>>> arithmetics.subtract(5, 3)
2
>>> arithmetics.multiple(5, 3)
15
>>> arithmetics.division(5, 3)
1.6666666666666667
>>> arithmetics.remainder(5, 3)
2
>>> arithmetics.power(5, 3)
125
>>> from mypackage import greet
>>> greet.greet_person('Asabeneh', 'Yetayeh')
'Asabeneh Yetayeh, welcome to 30DaysOfPython Challenge!'
>>>
```
As you can see our package works perfectly. The package folder contains a special file called **__init__**.py - it stores the package's content. If we put **__init__**.py in the package folder, python start recognizes it as a package.
The **__init__**.py exposes specified resources from its modules to be imported to other python files. An empty **__init__**.py file makes all functions available when a package is imported. The **__init__**.py is essential for the folder to be recognized by Python as a package.
### Further Information About Packages
- Database
- SQLAlchemy or SQLObject - Object oriented access to several different database systems
- _pip install SQLAlchemy_
- Web Development
- Django - High-level web framework.
- _pip install django_
- Flask - micro framework for Python based on Werkzeug, Jinja 2. (It's BSD licensed)
- _pip install flask_
- HTML Parser
- [Beautiful Soup](https://www.crummy.com/software/BeautifulSoup/bs4/doc/) - HTML/XML parser designed for quick turnaround projects like screen-scraping, will accept bad markup.
- _pip install beautifulsoup4_
- PyQuery - implements jQuery in Python; faster than BeautifulSoup, apparently.
- XML Processing
- ElementTree - The Element type is a simple but flexible container object, designed to store hierarchical data structures, such as simplified XML infosets, in memory. --Note: Python 2.5 and up has ElementTree in the Standard Library
- GUI
- PyQt - Bindings for the cross-platform Qt framework.
- TkInter - The traditional Python user interface toolkit.
- Data Analysis, Data Science and Machine learning
- Numpy: Numpy(numeric python) is known as one of the most popular machine learning library in Python.
- Pandas: is a data analysis, data science and a machine learning library in Python that provides data structures of high-level and a wide variety of tools for analysis.
- SciPy: SciPy is a machine learning library for application developers and engineers. SciPy library contains modules for optimization, linear algebra, integration, image processing, and statistics.
- Scikit-Learn: It is NumPy and SciPy. It is considered as one of the best libraries for working with complex data.
- TensorFlow: is a machine learning library built by Google.
- Keras: is considered as one of the coolest machine learning libraries in Python. It provides an easier mechanism to express neural networks. Keras also provides some of the best utilities for compiling models, processing data-sets, visualization of graphs, and much more.
- Network:
- requests: is a package which we can use to send requests to a server(GET, POST, DELETE, PUT)
- _pip install requests_
🌕 You are always progressing and you are a head of 20 steps to your way to greatness. Now do some exercises for your brain and muscles.
## Exercises: Day 20
1. Read this url and find the 10 most frequent words. romeo_and_juliet = 'http://www.gutenberg.org/files/1112/1112.txt'
2. Read the cats API and cats_api = 'https://api.thecatapi.com/v1/breeds' and find :
1. the min, max, mean, median, standard deviation of cats' weight in metric units.
2. the min, max, mean, median, standard deviation of cats' lifespan in years.
3. Create a frequency table of country and breed of cats
3. Read the [countries API](https://restcountries.eu/rest/v2/all) and find
1. the 10 largest countries
2. the 10 most spoken languages
3. the total number of languages in the countries API
4. UCI is one of the most common places to get data sets for data science and machine learning. Read the content of UCL (https://archive.ics.uci.edu/ml/datasets.php). Without additional libraries it will be difficult, so you may try it with BeautifulSoup4
🎉 CONGRATULATIONS ! 🎉
[<< Day 19](../19_Day_File_handling/19_file_handling.md) | [Day 21 >>](../21_Day_Classes_and_objects/21_classes_and_objects.md)
================================================
FILE: 20_Day_Python_package_manager/__init__.py
================================================
================================================
FILE: 20_Day_Python_package_manager/arithmetic.py
================================================
def add_numbers(*args):
total = 0
for num in args:
total += num
return total
def subtract(a, b):
return (a - b)
def multiple(a, b):
return a * b
def division(a, b):
return a / b
def remainder(a, b):
return a % b
def power(a, b):
return a ** b
================================================
FILE: 20_Day_Python_package_manager/greet.py
================================================
def greet_person(firstname, lastname):
return f'{firstname} {lastname}, welcome to 30DaysOfPython Challenge!'
================================================
FILE: 21_Day_Classes_and_objects/21_classes_and_objects.md
================================================
[<< Day 20](../20_Day_Python_package_manager/20_python_package_manager.md) | [Day 22 >>](../22_Day_Web_scraping/22_web_scraping.md)

- [📘 Day 21](#-day-21)
- [Classes and Objects](#classes-and-objects)
- [Creating a Class](#creating-a-class)
- [Creating an Object](#creating-an-object)
- [Class Constructor](#class-constructor)
- [Object Methods](#object-methods)
- [Object Default Methods](#object-default-methods)
- [Method to Modify Class Default Values](#method-to-modify-class-default-values)
- [Inheritance](#inheritance)
- [Overriding parent method](#overriding-parent-method)
- [💻 Exercises: Day 21](#-exercises-day-21)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# 📘 Day 21
## Classes and Objects
Python is an object oriented programming language. Everything in Python is an object, with its properties and methods. A number, string, list, dictionary, tuple, set etc. used in a program is an object of a corresponding built-in class. We create class to create an object. A class is like an object constructor, or a "blueprint" for creating objects. We instantiate a class to create an object. The class defines attributes and the behavior of the object, while the object, on the other hand, represents the class.
We have been working with classes and objects right from the beginning of this challenge unknowingly. Every element in a Python program is an object of a class.
Let us check if everything in python is a class:
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> num = 10
>>> type(num)
>>> string = 'string'
>>> type(string)
>>> boolean = True
>>> type(boolean)
>>> lst = []
>>> type(lst)
>>> tpl = ()
>>> type(tpl)
>>> set1 = set()
>>> type(set1)
>>> dct = {}
>>> type(dct)
```
### Creating a Class
To create a class we need the key word **class** followed by the name and colon. Class name should be **CamelCase**.
```sh
# syntax
class ClassName:
code goes here
```
**Example:**
```py
class Person:
pass
print(Person)
```
```sh
<__main__.Person object at 0x10804e510>
```
### Creating an Object
We can create an object by calling the class.
```py
p = Person()
print(p)
```
### Class Constructor
In the examples above, we have created an object from the Person class. However, a class without a constructor is not really useful in real applications. Let us use constructor function to make our class more useful. Like the constructor function in Java or JavaScript, Python has also a built-in **__init__**() constructor function. The **__init__** constructor function has self parameter which is a reference to the current instance of the class
**Examples:**
```py
class Person:
def __init__ (self, name):
# self allows to attach parameter to the class
self.name =name
p = Person('Asabeneh')
print(p.name)
print(p)
```
```sh
# output
Asabeneh
<__main__.Person object at 0x2abf46907e80>
```
Let us add more parameters to the constructor function.
```py
class Person:
def __init__(self, firstname, lastname, age, country, city):
self.firstname = firstname
self.lastname = lastname
self.age = age
self.country = country
self.city = city
p = Person('Asabeneh', 'Yetayeh', 250, 'Finland', 'Helsinki')
print(p.firstname)
print(p.lastname)
print(p.age)
print(p.country)
print(p.city)
```
```sh
# output
Asabeneh
Yetayeh
250
Finland
Helsinki
```
### Object Methods
Objects can have methods. The methods are functions which belong to the object.
**Example:**
```py
class Person:
def __init__(self, firstname, lastname, age, country, city):
self.firstname = firstname
self.lastname = lastname
self.age = age
self.country = country
self.city = city
def person_info(self):
return f'{self.firstname} {self.lastname} is {self.age} years old. He lives in {self.city}, {self.country}'
p = Person('Asabeneh', 'Yetayeh', 250, 'Finland', 'Helsinki')
print(p.person_info())
```
```sh
# output
Asabeneh Yetayeh is 250 years old. He lives in Helsinki, Finland
```
### Object Default Methods
Sometimes, you may want to have default values for your object methods. If we give default values for the parameters in the constructor, we can avoid errors when we call or instantiate our class without parameters. Let's see how it looks:
**Example:**
```py
class Person:
def __init__(self, firstname='Asabeneh', lastname='Yetayeh', age=250, country='Finland', city='Helsinki'):
self.firstname = firstname
self.lastname = lastname
self.age = age
self.country = country
self.city = city
def person_info(self):
return f'{self.firstname} {self.lastname} is {self.age} years old. He lives in {self.city}, {self.country}.'
p1 = Person()
print(p1.person_info())
p2 = Person('John', 'Doe', 30, 'Nomanland', 'Noman city')
print(p2.person_info())
```
```sh
# output
Asabeneh Yetayeh is 250 years old. He lives in Helsinki, Finland.
John Doe is 30 years old. He lives in Noman city, Nomanland.
```
### Method to Modify Class Default Values
In the example below, the person class, all the constructor parameters have default values. In addition to that, we have skills parameter, which we can access using a method. Let us create add_skill method to add skills to the skills list.
```py
class Person:
def __init__(self, firstname='Asabeneh', lastname='Yetayeh', age=250, country='Finland', city='Helsinki'):
self.firstname = firstname
self.lastname = lastname
self.age = age
self.country = country
self.city = city
self.skills = []
def person_info(self):
return f'{self.firstname} {self.lastname} is {self.age} years old. He lives in {self.city}, {self.country}.'
def add_skill(self, skill):
self.skills.append(skill)
p1 = Person()
print(p1.person_info())
p1.add_skill('HTML')
p1.add_skill('CSS')
p1.add_skill('JavaScript')
p2 = Person('John', 'Doe', 30, 'Nomanland', 'Noman city')
print(p2.person_info())
print(p1.skills)
print(p2.skills)
```
```sh
# output
Asabeneh Yetayeh is 250 years old. He lives in Helsinki, Finland.
John Doe is 30 years old. He lives in Noman city, Nomanland.
['HTML', 'CSS', 'JavaScript']
[]
```
### Inheritance
Using inheritance we can reuse parent class code. Inheritance allows us to define a class that inherits all the methods and properties from parent class. The parent class or super or base class is the class which gives all the methods and properties. Child class is the class that inherits from another or parent class.
Let us create a student class by inheriting from person class.
```py
class Student(Person):
pass
s1 = Student('Eyob', 'Yetayeh', 30, 'Finland', 'Helsinki')
s2 = Student('Lidiya', 'Teklemariam', 28, 'Finland', 'Espoo')
print(s1.person_info())
s1.add_skill('JavaScript')
s1.add_skill('React')
s1.add_skill('Python')
print(s1.skills)
print(s2.person_info())
s2.add_skill('Organizing')
s2.add_skill('Marketing')
s2.add_skill('Digital Marketing')
print(s2.skills)
```
```sh
output
Eyob Yetayeh is 30 years old. He lives in Helsinki, Finland.
['JavaScript', 'React', 'Python']
Lidiya Teklemariam is 28 years old. He lives in Espoo, Finland.
['Organizing', 'Marketing', 'Digital Marketing']
```
We did not call the **__init__**() constructor in the child class. If we didn't call it then we can still access all the properties from the parent. But if we do call the constructor we can access the parent properties by calling _super_.
We can add a new method to the child or we can override the parent class methods by creating the same method name in the child class. When we add the **__init__**() function, the child class will no longer inherit the parent's **__init__**() function.
### Overriding parent method
```py
class Student(Person):
def __init__ (self, firstname='Asabeneh', lastname='Yetayeh',age=250, country='Finland', city='Helsinki', gender='male'):
self.gender = gender
super().__init__(firstname, lastname,age, country, city)
def person_info(self):
gender = 'He' if self.gender =='male' else 'She'
return f'{self.firstname} {self.lastname} is {self.age} years old. {gender} lives in {self.city}, {self.country}.'
s1 = Student('Eyob', 'Yetayeh', 30, 'Finland', 'Helsinki','male')
s2 = Student('Lidiya', 'Teklemariam', 28, 'Finland', 'Espoo', 'female')
print(s1.person_info())
s1.add_skill('JavaScript')
s1.add_skill('React')
s1.add_skill('Python')
print(s1.skills)
print(s2.person_info())
s2.add_skill('Organizing')
s2.add_skill('Marketing')
s2.add_skill('Digital Marketing')
print(s2.skills)
```
```sh
Eyob Yetayeh is 30 years old. He lives in Helsinki, Finland.
['JavaScript', 'React', 'Python']
Lidiya Teklemariam is 28 years old. She lives in Espoo, Finland.
['Organizing', 'Marketing', 'Digital Marketing']
```
We can use super() built-in function or the parent name Person to automatically inherit the methods and properties from its parent. In the example above we override the parent method. The child method has a different feature, it can identify, if the gender is male or female and assign the proper pronoun(He/She).
🌕 Now, you are fully charged with a super power of programming. Now do some exercises for your brain and muscles.
## 💻 Exercises: Day 21
### Exercises: Level 1
1. Python has the module called _statistics_ and we can use this module to do all the statistical calculations. However, to learn how to make function and reuse function let us try to develop a program, which calculates the measure of central tendency of a sample (mean, median, mode) and measure of variability (range, variance, standard deviation). In addition to those measures, find the min, max, count, percentile, and frequency distribution of the sample. You can create a class called Statistics and create all the functions that do statistical calculations as methods for the Statistics class. Check the output below.
```py
ages = [31, 26, 34, 37, 27, 26, 32, 32, 26, 27, 27, 24, 32, 33, 27, 25, 26, 38, 37, 31, 34, 24, 33, 29, 26]
print('Count:', data.count()) # 25
print('Sum: ', data.sum()) # 744
print('Min: ', data.min()) # 24
print('Max: ', data.max()) # 38
print('Range: ', data.range()) # 14
print('Mean: ', data.mean()) # 30
print('Median: ', data.median()) # 29
print('Mode: ', data.mode()) # {'mode': 26, 'count': 5}
print('Standard Deviation: ', data.std()) # 4.2
print('Variance: ', data.var()) # 17.5
print('Frequency Distribution: ', data.freq_dist()) # [(20.0, 26), (16.0, 27), (12.0, 32), (8.0, 37), (8.0, 34), (8.0, 33), (8.0, 31), (8.0, 24), (4.0, 38), (4.0, 29), (4.0, 25)]
```
```sh
# you output should look like this
print(data.describe())
Count: 25
Sum: 744
Min: 24
Max: 38
Range: 14
Mean: 30
Median: 29
Mode: (26, 5)
Variance: 17.5
Standard Deviation: 4.2
Frequency Distribution: [(20.0, 26), (16.0, 27), (12.0, 32), (8.0, 37), (8.0, 34), (8.0, 33), (8.0, 31), (8.0, 24), (4.0, 38), (4.0, 29), (4.0, 25)]
```
### Exercises: Level 2
1. Create a class called PersonAccount. It has firstname, lastname, incomes, expenses properties and it has total_income, total_expense, account_info, add_income, add_expense and account_balance methods. Incomes is a set of incomes and its description. The same goes for expenses.
🎉 CONGRATULATIONS ! 🎉
[<< Day 20](../20_Day_Python_package_manager/20_python_package_manager.md) | [Day 22 >>](../22_Day_Web_scraping/22_web_scraping.md)
================================================
FILE: 22_Day_Web_scraping/22_web_scraping.md
================================================
[<< Day 21](../21_Day_Classes_and_objects/21_classes_and_objects.md) | [Day 23 >>](../23_Day_Virtual_environment/23_virtual_environment.md)

- [📘 Day 22](#-day-22)
- [Python Web Scraping](#python-web-scraping)
- [What is Web Scrapping](#what-is-web-scrapping)
- [💻 Exercises: Day 22](#-exercises-day-22)
# 📘 Day 22
## Python Web Scraping
### What is Web Scrapping
The internet is full of huge amount of data which can be used for different purposes. To collect this data we need to know how to scrape data from a website.
Web scraping is the process of extracting and collecting data from websites and storing it on a local machine or in a database.
In this section, we will use beautifulsoup and requests package to scrape data. The package version we are using is beautifulsoup 4.
To start scraping websites you need _requests_, _beautifoulSoup4_ and a _website_.
```sh
pip install requests
pip install beautifulsoup4
```
To scrape data from websites, basic understanding of HTML tags and CSS selectors is needed. We target content from a website using HTML tags, classes or/and ids.
Let us import the requests and BeautifulSoup module
```py
import requests
from bs4 import BeautifulSoup
```
Let us declare url variable for the website which we are going to scrape.
```py
import requests
from bs4 import BeautifulSoup
url = 'https://archive.ics.uci.edu/ml/datasets.php'
# Lets use the requests get method to fetch the data from url
response = requests.get(url)
# lets check the status
status = response.status_code
print(status) # 200 means the fetching was successful
```
```sh
200
```
Using beautifulSoup to parse content from the page
```py
import requests
from bs4 import BeautifulSoup
url = 'https://archive.ics.uci.edu/ml/datasets.php'
response = requests.get(url)
content = response.content # we get all the content from the website
soup = BeautifulSoup(content, 'html.parser') # beautiful soup will give a chance to parse
print(soup.title) # UCI Machine Learning Repository: Data Sets
print(soup.title.get_text()) # UCI Machine Learning Repository: Data Sets
print(soup.body) # gives the whole page on the website
print(response.status_code)
tables = soup.find_all('table', {'cellpadding':'3'})
# We are targeting the table with cellpadding attribute with the value of 3
# We can select using id, class or HTML tag , for more information check the beautifulsoup doc
table = tables[0] # the result is a list, we are taking out data from it
for td in table.find('tr').find_all('td'):
print(td.text)
```
If you run this code, you can see that the extraction is half done. You can continue doing it because it is part of exercise 1.
For reference check the [beautifulsoup documentation](https://www.crummy.com/software/BeautifulSoup/bs4/doc/#quick-start)
🌕 You are so special, you are progressing everyday. You are left with only eight days to your way to greatness. Now do some exercises for your brain and muscles.
## 💻 Exercises: Day 22
1. Scrape the following website and store the data as json file(url = 'http://www.bu.edu/president/boston-university-facts-stats/').
1. Extract the table in this url (https://archive.ics.uci.edu/ml/datasets.php) and change it to a json file
2. Scrape the presidents table and store the data as json(https://en.wikipedia.org/wiki/List_of_presidents_of_the_United_States). The table is not very structured and the scrapping may take very long time.
🎉 CONGRATULATIONS ! 🎉
[<< Day 21](../21_Day_Web_scraping/21_class_and_object.md) | [Day 23 >>](../23_Day_Virtual_environment/23_virtual_environment.md)
================================================
FILE: 22_Day_Web_scraping/scrapped_data.json
================================================
[
{
"category": "Community",
"Student Body": "34,589",
"Living Alumni": "398,195",
"Total Employees": "10,517",
"Faculty": "4,171",
"Nondegree Students": "2,008",
"Graduate & Professional Students": "15,645",
"Undergraduate Students": "16,936"
},
{
"category": "Campus",
"Classrooms": "834",
"Buildings": "370",
"Laboratories": "1,681",
"Libraries": "21",
"Campus Area (acres)": "169"
},
{
"category": "Academics",
"Study Abroad Programs": "70+",
"Average Class Size": "27",
"Faculty": "4,171",
"Student/Faculty Ratio": "10:1",
"Schools and Colleges": "17",
"Programs of Study": "300+"
},
{
"category": "Grant & Contract Awards",
"Research Awards": "$574.1M",
"BMC Clinical Research Grants": "$88.0M"
},
{
"category": "Undergraduate Financial Aid & Scholarships",
"Average Total Need-Based Financial Aid": "$46,252",
"Average Need-Based Grant/Scholarship": "$40,969",
"Grants & Scholarships (need-based)": "$275.6M",
"Grants & Scholarships (non-need-based)": "$28.7M"
},
{
"category": "Student Life",
"Community Service Hours": "1.6M+",
"Alternative Service Breaks Participants": "300+",
"BU on Social": "new accounts daily",
"Cultural & Religious Organizations": "60+",
"Community Service & Justice Organizations": "80+",
"Academic & Professional Organizations": "120+",
"Art & Performance Organizations": "60+",
"Student Organizations": "450+",
"First-Year Student Outreach Project Volunteers": "800+"
},
{
"category": "Research",
"Faculty Publications": "6,000+",
"Student UROP Participants": "450+",
"Centers & Institutes": "130+"
},
{
"category": "International Community",
"Global Initiatives": "300+",
"Cultural Student Groups": "40+",
"Alumni Countries": "180+",
"International Students": "11,000+"
},
{
"category": "Athletics",
"Intramural Sports & Tournaments": "15+",
"Club and Intramural Sports Participants": "7,000+",
"Club Sports Teams": "50",
"Varsity Sports": "24"
}
]
================================================
FILE: 23_Day_Virtual_environment/23_virtual_environment.md
================================================
[<< Day 22](../22_Day_Web_scraping/22_web_scraping.md) | [Day 24 >>](../24_Day_Statistics/24_statistics.md)

- [📘 Day 23](#-day-23)
- [Setting up Virtual Environments](#setting-up-virtual-environments)
- [💻 Exercises: Day 23](#-exercises-day-23)
# 📘 Day 23
## Setting up Virtual Environments
To start with project, it would be better to have a virtual environment. Virtual environment can help us to create an isolated or separate environment. This will help us to avoid conflicts in dependencies across projects. If you write pip freeze on your terminal you will see all the installed packages on your computer. If we use virtualenv, we will access only packages which are specific for that project. Open your terminal and install virtualenv
```sh
asabeneh@Asabeneh:~$ pip install virtualenv
```
Inside the 30DaysOfPython folder create a flask_project folder.
After installing the virtualenv package go to your project folder and create a virtual env by writing:
For Mac/Linux:
```sh
asabeneh@Asabeneh:~/Desktop/30DaysOfPython/flask_project\$ virtualenv venv
```
For Windows:
```sh
C:\Users\User\Documents\30DaysOfPython\flask_project>python -m venv venv
```
I prefer to call the new project venv, but feel free to name it differently. Let us check if the the venv was created by using ls (or dir for windows command prompt) command.
```sh
asabeneh@Asabeneh:~/Desktop/30DaysOfPython/flask_project$ ls
venv/
```
Let us activate the virtual environment by writing the following command at our project folder.
For Mac/Linux:
```sh
asabeneh@Asabeneh:~/Desktop/30DaysOfPython/flask_project$ source venv/bin/activate
```
Activation of the virtual environment in Windows may very on Windows Power shell and git bash.
For Windows Power Shell:
```sh
C:\Users\User\Documents\30DaysOfPython\flask_project> venv\Scripts\activate
```
For Windows Git bash:
```sh
C:\Users\User\Documents\30DaysOfPython\flask_project> venv\Scripts\. activate
```
After you write the activation command, your project directory will start with venv. See the example below.
```sh
(venv) asabeneh@Asabeneh:~/Desktop/30DaysOfPython/flask_project$
```
Now, lets check the available packages in this project by writing pip freeze. You will not see any packages.
We are going to do a small flask project so let us install flask package to this project.
```sh
(venv) asabeneh@Asabeneh:~/Desktop/30DaysOfPython/flask_project$ pip install Flask
```
Now, let us write pip freeze to see a list of installed packages in the project:
```sh
(venv) asabeneh@Asabeneh:~/Desktop/30DaysOfPython/flask_project$ pip freeze
Click==7.0
Flask==1.1.1
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
Werkzeug==0.16.0
```
When you finish you should dactivate active project using _deactivate_.
```sh
(venv) asabeneh@Asabeneh:~/Desktop/30DaysOfPython$ deactivate
```
The necessary modules to work with flask are installed. Now, your project directory is ready for a flask project. You should include the venv to your .gitignore file not to push it to github.
## 💻 Exercises: Day 23
1. Create a project directory with a virtual environment based on the example given above.
🎉 CONGRATULATIONS ! 🎉
[<< Day 22](../22_Day_Web_scraping/22_web_scraping.md) | [Day 24 >>](../24_Day_Statistics/24_statistics.md)
================================================
FILE: 24_Day_Statistics/24_statistics.md
================================================
[<< Day 24](../24_Day_Statistics/24_statistics.md) | [Day 26 >>](../26_Day_Python_web/26_python_web.md)

- [📘 Day 25](#-day-25)
- [Pandas](#pandas)
- [Installing Pandas](#installing-pandas)
- [Importing Pandas](#importing-pandas)
- [Creating Pandas Series with Default Index](#creating-pandas-series-with-default-index)
- [Creating Pandas Series with custom index](#creating--pandas-series-with-custom-index)
- [Creating Pandas Series from a Dictionary](#creating-pandas-series-from-a-dictionary)
- [Creating a Constant Pandas Series](#creating-a-constant-pandas-series)
- [Creating a Pandas Series Using Linspace](#creating-a--pandas-series-using-linspace)
- [DataFrames](#dataframes)
- [Creating DataFrames from List of Lists](#creating-dataframes-from-list-of-lists)
- [Creating DataFrame Using Dictionary](#creating-dataframe-using-dictionary)
- [Creating DataFrames from a List of Dictionaries](#creating-dataframes-from-a-list-of-dictionaries)
- [Reading CSV File Using Pandas](#reading-csv-file-using-pandas)
- [Data Exploration](#data-exploration)
- [Modifying a DataFrame](#modifying-a-dataframe)
- [Creating a DataFrame](#creating-a-dataframe)
- [Adding a New Column](#adding-a-new-column)
- [Modifying column values](#modifying-column-values)
- [Formatting DataFrame columns](#formatting-dataframe-columns)
- [Checking data types of Column values](#checking-data-types-of-column-values)
- [Boolean Indexing](#boolean-indexing)
- [Exercises: Day 25](#exercises-day-25)
# 📘 Day 25
## Pandas
Pandas is an open source, high-performance, easy-to-use data structures and data analysis tools for the Python programming language.
Pandas adds data structures and tools designed to work with table-like data which is *Series* and *Data Frames*.
Pandas provides tools for data manipulation:
- reshaping
- merging
- sorting
- slicing
- aggregation
- imputation.
If you are using anaconda, you do not have install pandas.
### Installing Pandas
For Mac:
```py
pip install conda
conda install pandas
```
For Windows:
```py
pip install conda
pip install pandas
```
Pandas data structure is based on *Series* and *DataFrames*.
A *series* is a *column* and a DataFrame is a *multidimensional table* made up of collection of *series*. In order to create a pandas series we should use numpy to create a one dimensional arrays or a python list.
Let us see an example of a series:
Names Pandas Series

Countries Series

Cities Series

As you can see, pandas series is just one column of data. If we want to have multiple columns we use data frames. The example below shows pandas DataFrames.
Let us see, an example of a pandas data frame:

Data frame is a collection of rows and columns. Look at the table below; it has many more columns than the example above:

Next, we will see how to import pandas and how to create Series and DataFrames using pandas
### Importing Pandas
```python
import pandas as pd # importing pandas as pd
import numpy as np # importing numpy as np
```
### Creating Pandas Series with Default Index
```python
nums = [1, 2, 3, 4,5]
s = pd.Series(nums)
print(s)
```
```sh
0 1
1 2
2 3
3 4
4 5
dtype: int64
```
### Creating Pandas Series with custom index
```python
nums = [1, 2, 3, 4, 5]
s = pd.Series(nums, index=[1, 2, 3, 4, 5])
print(s)
```
```sh
1 1
2 2
3 3
4 4
5 5
dtype: int64
```
```python
fruits = ['Orange','Banana','Mango']
fruits = pd.Series(fruits, index=[1, 2, 3])
print(fruits)
```
```sh
1 Orange
2 Banana
3 Mango
dtype: object
```
### Creating Pandas Series from a Dictionary
```python
dct = {'name':'Asabeneh','country':'Finland','city':'Helsinki'}
```
```python
s = pd.Series(dct)
print(s)
```
```sh
name Asabeneh
country Finland
city Helsinki
dtype: object
```
### Creating a Constant Pandas Series
```python
s = pd.Series(10, index = [1, 2, 3])
print(s)
```
```sh
1 10
2 10
3 10
dtype: int64
```
### Creating a Pandas Series Using Linspace
```python
s = pd.Series(np.linspace(5, 20, 10)) # linspace(starting, end, items)
print(s)
```
```sh
0 5.000000
1 6.666667
2 8.333333
3 10.000000
4 11.666667
5 13.333333
6 15.000000
7 16.666667
8 18.333333
9 20.000000
dtype: float64
```
## DataFrames
Pandas data frames can be created in different ways.
### Creating DataFrames from List of Lists
```python
data = [
['Asabeneh', 'Finland', 'Helsink'],
['David', 'UK', 'London'],
['John', 'Sweden', 'Stockholm']
]
df = pd.DataFrame(data, columns=['Names','Country','City'])
print(df)
```
### Creating DataFrames from a List of Dictionaries
```python
data = [
{'Name': 'Asabeneh', 'Country': 'Finland', 'City': 'Helsinki'},
{'Name': 'David', 'Country': 'UK', 'City': 'London'},
{'Name': 'John', 'Country': 'Sweden', 'City': 'Stockholm'}]
df = pd.DataFrame(data)
print(df)
```
Name
Country
City
0
Asabeneh
Finland
Helsinki
1
David
UK
London
2
John
Sweden
Stockholm
## Reading CSV File Using Pandas
To download the CSV file, what is needed in this example, console/command line is enough:
```sh
curl -O https://raw.githubusercontent.com/Asabeneh/30-Days-Of-Python/master/data/weight-height.csv
```
Put the downloaded file in your working directory.
```python
import pandas as pd
df = pd.read_csv('weight-height.csv')
print(df)
```
### Data Exploration
Let us read only the first 5 rows using head()
```python
print(df.head()) # give five rows we can increase the number of rows by passing argument to the head() method
```
Gender
Height
Weight
0
Male
73.847017
241.893563
1
Male
68.781904
162.310473
2
Male
74.110105
212.740856
3
Male
71.730978
220.042470
4
Male
69.881796
206.349801
Let us also explore the last recordings of the dataframe using the tail() methods.
```python
print(df.tail()) # tails give the last five rows, we can increase the rows by passing argument to tail method
```
Gender
Height
Weight
9995
Female
66.172652
136.777454
9996
Female
67.067155
170.867906
9997
Female
63.867992
128.475319
9998
Female
69.034243
163.852461
9999
Female
61.944246
113.649103
As you can see the csv file has three rows: Gender, Height and Weight. If the DataFrame would have a long rows, it would be hard to know all the columns. Therefore, we should use a method to know the columns. we do not know the number of rows. Let's use shape method.
```python
print(df.shape) # as you can see 10000 rows and three columns
```
(10000, 3)
Let us get all the columns using columns.
```python
print(df.columns)
```
Index(['Gender', 'Height', 'Weight'], dtype='object')
Now, let us get a specific column using the column key
```python
heights = df['Height'] # this is now a series
```
```python
print(heights)
```
```sh
0 73.847017
1 68.781904
2 74.110105
3 71.730978
4 69.881796
...
9995 66.172652
9996 67.067155
9997 63.867992
9998 69.034243
9999 61.944246
Name: Height, Length: 10000, dtype: float64
```
```python
weights = df['Weight'] # this is now a series
```
```python
print(weights)
```
```sh
0 241.893563
1 162.310473
2 212.740856
3 220.042470
4 206.349801
...
9995 136.777454
9996 170.867906
9997 128.475319
9998 163.852461
9999 113.649103
Name: Weight, Length: 10000, dtype: float64
```
```python
print(len(heights) == len(weights))
```
True
The describe() method provides a descriptive statistical values of a dataset.
```python
print(heights.describe()) # give statistical information about height data
```
```sh
count 10000.000000
mean 66.367560
std 3.847528
min 54.263133
25% 63.505620
50% 66.318070
75% 69.174262
max 78.998742
Name: Height, dtype: float64
```
```python
print(weights.describe())
```
```sh
count 10000.000000
mean 161.440357
std 32.108439
min 64.700127
25% 135.818051
50% 161.212928
75% 187.169525
max 269.989699
Name: Weight, dtype: float64
```
```python
print(df.describe()) # describe can also give statistical information from a dataFrame
```
Height
Weight
count
10000.000000
10000.000000
mean
66.367560
161.440357
std
3.847528
32.108439
min
54.263133
64.700127
25%
63.505620
135.818051
50%
66.318070
161.212928
75%
69.174262
187.169525
max
78.998742
269.989699
Similar to describe(), the info() method also give information about the dataset.
## Modifying a DataFrame
Modifying a DataFrame:
* We can create a new DataFrame
* We can create a new column and add it to the DataFrame,
* we can remove an existing column from a DataFrame,
* we can modify an existing column in a DataFrame,
* we can change the data type of column values in the DataFrame
### Creating a DataFrame
As always, first we import the necessary packages. Now, lets import pandas and numpy, two best friends ever.
```python
import pandas as pd
import numpy as np
data = [
{"Name": "Asabeneh", "Country":"Finland","City":"Helsinki"},
{"Name": "David", "Country":"UK","City":"London"},
{"Name": "John", "Country":"Sweden","City":"Stockholm"}]
df = pd.DataFrame(data)
print(df)
```
Name
Country
City
0
Asabeneh
Finland
Helsinki
1
David
UK
London
2
John
Sweden
Stockholm
Adding a column to a DataFrame is like adding a key to a dictionary.
First let's use the previous example to create a DataFrame. After we create the DataFrame, we will start modifying the columns and column values.
### Adding a New Column
Let's add a weight column in the DataFrame
```python
weights = [74, 78, 69]
df['Weight'] = weights
df
```
Name
Country
City
Weight
0
Asabeneh
Finland
Helsinki
74
1
David
UK
London
78
2
John
Sweden
Stockholm
69
Let's add a height column into the DataFrame aswell
```python
heights = [173, 175, 169]
df['Height'] = heights
print(df)
```
Name
Country
City
Weight
Height
0
Asabeneh
Finland
Helsinki
74
173
1
David
UK
London
78
175
2
John
Sweden
Stockholm
69
169
As you can see in the DataFrame above, we did add new columns, Weight and Height. Let's add one additional column called BMI(Body Mass Index) by calculating their BMI using thier mass and height. BMI is mass divided by height squared (in meters) - Weight/Height * Height.
As you can see, the height is in centimeters, so we shoud change it to meters. Let's modify the height row.
### Modifying column values
```python
df['Height'] = df['Height'] * 0.01
df
```
Name
Country
City
Weight
Height
0
Asabeneh
Finland
Helsinki
74
1.73
1
David
UK
London
78
1.75
2
John
Sweden
Stockholm
69
1.69
```python
# Using functions makes our code clean, but you can calculate the bmi without one
def calculate_bmi ():
weights = df['Weight']
heights = df['Height']
bmi = []
for w,h in zip(weights, heights):
b = w/(h*h)
bmi.append(b)
return bmi
bmi = calculate_bmi()
```
```python
df['BMI'] = bmi
df
```
Name
Country
City
Weight
Height
BMI
0
Asabeneh
Finland
Helsinki
74
1.73
24.725183
1
David
UK
London
78
1.75
25.469388
2
John
Sweden
Stockholm
69
1.69
24.158818
### Formatting DataFrame columns
The BMI column values of the DataFrame are float with many significant digits after decimal. Let's change it to one significant digit after point.
```python
df['BMI'] = round(df['BMI'], 1)
print(df)
```
Name
Country
City
Weight
Height
BMI
0
Asabeneh
Finland
Helsinki
74
1.73
24.7
1
David
UK
London
78
1.75
25.5
2
John
Sweden
Stockholm
69
1.69
24.2
The information in the DataFrame seems not yet complete, let's add birth year and current year columns.
```python
birth_year = ['1769', '1985', '1990']
current_year = pd.Series(2020, index=[0, 1,2])
df['Birth Year'] = birth_year
df['Current Year'] = current_year
df
```
Name
Country
City
Weight
Height
BMI
Birth Year
Current Year
0
Asabeneh
Finland
Helsinki
74
1.73
24.7
1769
2020
1
David
UK
London
78
1.75
25.5
1985
2020
2
John
Sweden
Stockholm
69
1.69
24.2
1990
2020
## Checking data types of Column values
```python
print(df.Weight.dtype)
```
```sh
dtype('int64')
```
```python
df['Birth Year'].dtype # it gives string object , we should change this to number
```
```python
df['Birth Year'] = df['Birth Year'].astype('int')
print(df['Birth Year'].dtype) # let's check the data type now
```
```sh
dtype('int32')
```
Now same for the current year:
```python
df['Current Year'] = df['Current Year'].astype('int')
df['Current Year'].dtype
```
```sh
dtype('int32')
```
Now, the column values of birth year and current year are integers. We can calculate the age.
```python
ages = df['Current Year'] - df['Birth Year']
ages
```
0 251
1 35
2 30
dtype: int32
```python
df['Ages'] = ages
print(df)
```
Name
Country
City
Weight
Height
BMI
Birth Year
Current Year
Ages
0
Asabeneh
Finland
Helsinki
74
1.73
24.7
1769
2019
250
1
David
UK
London
78
1.75
25.5
1985
2019
34
2
John
Sweden
Stockholm
69
1.69
24.2
1990
2019
29
The person in the first row lived so far for 251 years. It is unlikely for someone to live so long. Either it is a typo or the data is cooked. So lets fill that data with average of the columns without including outlier.
mean = (35 + 30)/ 2
```python
mean = (35 + 30)/ 2
print('Mean: ',mean) #it is good to add some description to the output, so we know what is what
```
```sh
Mean: 32.5
```
### Boolean Indexing
```python
print(df[df['Ages'] > 120])
```
Name
Country
City
Weight
Height
BMI
Birth Year
Current Year
Ages
0
Asabeneh
Finland
Helsinki
74
1.73
24.7
1769
2020
251
```python
print(df[df['Ages'] < 120])
```
Name
Country
City
Weight
Height
BMI
Birth Year
Current Year
Ages
1
David
UK
London
78
1.75
25.5
1985
2020
35
2
John
Sweden
Stockholm
69
1.69
24.2
1990
2020
30
## Exercises: Day 25
1. Read the hacker_news.csv file from data directory
1. Get the first five rows
1. Get the last five rows
1. Get the title column as pandas series
1. Count the number of rows and columns
- Filter the titles which contain python
- Filter the titles which contain JavaScript
- Explore the data and make sense of it
🎉 CONGRATULATIONS ! 🎉
[<< Day 24](../24_Day_Statistics/24_statistics.md) | [Day 26 >>](../26_Day_Python_web/26_python_web.md)
================================================
FILE: 26_Day_Python_web/26_python_web.md
================================================
[<< Day 25 ](../25_Day_Pandas/25_pandas.md) | [Day 27 >>](../27_Day_Python_with_mongodb/27_python_with_mongodb.md)

- [📘 Day 26](#-day-26)
- [Python for Web](#python-for-web)
- [Flask](#flask)
- [Folder structure](#folder-structure)
- [Setting up your project directory](#setting-up-your-project-directory)
- [Creating routes](#creating-routes)
- [Creating templates](#creating-templates)
- [Python Script](#python-script)
- [Navigation](#navigation)
- [Creating a layout](#creating-a-layout)
- [Serving Static File](#serving-static-file)
- [Deployment](#deployment)
- [Creating Heroku account](#creating-heroku-account)
- [Login to Heroku](#login-to-heroku)
- [Create requirements and Procfile](#create-requirements-and-procfile)
- [Pushing project to heroku](#pushing-project-to-heroku)
- [Exercises: Day 26](#exercises-day-26)
# 📘 Day 26
## Python for Web
Python is a general purpose programming language and it can be used for many places. In this section, we will see how we use Python for the web. There are many Python web frame works. Django and Flask are the most popular ones. Today, we will see how to use Flask for web development.
### Flask
Flask is a web development framework written in Python. Flask uses Jinja2 template engine. Flask can be also used with other modern front libraries such as React.
If you did not install the virtualenv package yet install it first. Virtual environment will allows to isolate project dependencies from the local machine dependencies.
#### Folder structure
After completing all the step, your project file structure should look like this:
```sh
├── Procfile
├── app.py
├── env
│ ├── bin
├── requirements.txt
├── static
│ └── css
│ └── main.css
└── templates
├── about.html
├── home.html
├── layout.html
├── post.html
└── result.html
```
### Setting up your project directory
Follow the following steps to get started with Flask.
Step 1: install virtualenv using the following command.
```sh
pip install virtualenv
```
Step 2:
```sh
asabeneh@Asabeneh:~/Desktop$ mkdir python_for_web
asabeneh@Asabeneh:~/Desktop$ cd python_for_web/
asabeneh@Asabeneh:~/Desktop/python_for_web$ virtualenv venv
asabeneh@Asabeneh:~/Desktop/python_for_web$ source venv/bin/activate
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip freeze
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip install Flask
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip freeze
Click==7.0
Flask==1.1.1
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
Werkzeug==0.16.0
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$
```
We created a project director named python_for_web. Inside the project we created a virtual environment *venv* which could be any name but I prefer to call it _venv_. Then we activated the virtual environment. We used pip freeze to check the installed packages in the project directory. The result of pip freeze was empty because a package was not installed yet.
Now, let's create app.py file in the project directory and write the following code. The app.py file will be the main file in the project. The following code has flask module, os module.
### Creating routes
The home route.
```py
# let's import the flask
from flask import Flask
import os # importing operating system module
app = Flask(__name__)
@app.route('/') # this decorator create the home route
def home ():
return '
Welcome
'
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
To run the flask application, write python app.py in the main flask application directory.
After you run _python app.py_ check local host 5000.
Let us add additional route.
Creating about route
```py
# let's import the flask
from flask import Flask
import os # importing operating system module
app = Flask(__name__)
@app.route('/') # this decorator create the home route
def home ():
return '
Welcome
'
@app.route('/about')
def about():
return '
About us
'
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
Now, we added the about route in the above code. How about if we want to render an HTML file instead of string? It is possible to render HTML file using the function *render_template*. Let us create a folder called templates and create home.html and about.html in the project directory. Let us also import the *render_template* function from flask.
### Creating templates
Create the HTML files inside templates folder.
home.html
```html
Home
Welcome Home
```
about.html
```html
About
About Us
```
### Python Script
app.py
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
app = Flask(__name__)
@app.route('/') # this decorator create the home route
def home ():
return render_template('home.html')
@app.route('/about')
def about():
return render_template('about.html')
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
As you can see to go to different pages or to navigate we need a navigation. Let's add a link to each page or let's create a layout which we use to every page.
### Navigation
```html
```
Now, we can navigate between the pages using the above link. Let us create additional page which handle form data. You can call it any name, I like to call it post.html.
We can inject data to the HTML files using Jinja2 template engine.
```py
# let's import the flask
from flask import Flask, render_template, request, redirect, url_for
import os # importing operating system module
app = Flask(__name__)
@app.route('/') # this decorator create the home route
def home ():
techs = ['HTML', 'CSS', 'Flask', 'Python']
name = '30 Days Of Python Programming'
return render_template('home.html', techs=techs, name = name, title = 'Home')
@app.route('/about')
def about():
name = '30 Days Of Python Programming'
return render_template('about.html', name = name, title = 'About Us')
@app.route('/post')
def post():
name = 'Text Analyzer'
return render_template('post.html', name = name, title = name)
if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
Let's see the templates too:
home.html
```html
Home
```
### Creating a layout
In the template files, there are lots of repeated codes, we can write a layout and we can remove the repetition. Let's create layout.html inside the templates folder.
After we create the layout we will import to every file.
#### Serving Static File
Create a static folder in your project directory. Inside the static folder create CSS or styles folder and create a CSS stylesheet. We use the *url_for* module to serve the static file.
layout.html
```html
{% if title %}
30 Days of Python - {{ title}}
{% else %}
30 Days of Python
{% endif %}
{% block content %} {% endblock %}
```
Now, lets remove all the repeated code in the other template files and import the layout.html. The href is using _url_for_ function with the name of the route function to connect each navigation route.
home.html
```html
{% extends 'layout.html' %} {% block content %}
Welcome to {{name}}
This application clean texts and analyse the number of word, characters and
most frequent words in the text. Check it out by click text analyzer at the
menu. You need the following technologies to build this web application:
{% endblock %}
```
Request methods, there are different request methods(GET, POST, PUT, DELETE) are the common request methods which allow us to do CRUD(Create, Read, Update, Delete) operation.
In the post, route we will use GET and POST method alternative depending on the type of request, check how it looks in the code below. The request method is a function to handle request methods and also to access form data.
app.py
```py
# let's import the flask
from flask import Flask, render_template, request, redirect, url_for
import os # importing operating system module
app = Flask(__name__)
# to stop caching static file
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
@app.route('/') # this decorator create the home route
def home ():
techs = ['HTML', 'CSS', 'Flask', 'Python']
name = '30 Days Of Python Programming'
return render_template('home.html', techs=techs, name = name, title = 'Home')
@app.route('/about')
def about():
name = '30 Days Of Python Programming'
return render_template('about.html', name = name, title = 'About Us')
@app.route('/result')
def result():
return render_template('result.html')
@app.route('/post', methods= ['GET','POST'])
def post():
name = 'Text Analyzer'
if request.method == 'GET':
return render_template('post.html', name = name, title = name)
if request.method =='POST':
content = request.form['content']
print(content)
return redirect(url_for('result'))
if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
So far, we have seen how to use template and how to inject data to template, how to a common layout.
Now, lets handle static file. Create a folder called static in the project director and create a folder called css. Inside css folder create main.css. Your main. css file will be linked to the layout.html.
You don't have to write the css file, copy and use it. Let's move on to deployment.
### Deployment
#### Creating Heroku account
Heroku provides a free deployment service for both front end and fullstack applications. Create an account on [heroku](https://www.heroku.com/) and install the heroku [CLI](https://devcenter.heroku.com/articles/heroku-cli) for you machine.
After installing heroku write the following command
#### Login to Heroku
```sh
asabeneh@Asabeneh:~$ heroku login
heroku: Press any key to open up the browser to login or q to exit:
```
Let's see the result by clicking any key from the keyboard. When you press any key from you keyboard it will open the heroku login page and click the login page. Then you will local machine will be connected to the remote heroku server. If you are connected to remote server, you will see this.
```sh
asabeneh@Asabeneh:~$ heroku login
heroku: Press any key to open up the browser to login or q to exit:
Opening browser to https://cli-auth.heroku.com/auth/browser/be12987c-583a-4458-a2c2-ba2ce7f41610
Logging in... done
Logged in as asabeneh@gmail.com
asabeneh@Asabeneh:~$
```
#### Create requirements and Procfile
Before we push our code to remote server, we need requirements
- requirements.txt
- Procfile
```sh
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip freeze
Click==7.0
Flask==1.1.1
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
Werkzeug==0.16.0
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ touch requirements.txt
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip freeze > requirements.txt
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ cat requirements.txt
Click==7.0
Flask==1.1.1
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
Werkzeug==0.16.0
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ touch Procfile
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ ls
Procfile env/ static/
app.py requirements.txt templates/
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$
```
The Procfile will have the command which run the application in the web server in our case on Heroku.
```sh
web: python app.py
```
#### Pushing project to heroku
Now, it is ready to be deployed. Steps to deploy the application on heroku
1. git init
2. git add .
3. git commit -m "commit message"
4. heroku create 'name of the app as one word'
5. git push heroku master
6. heroku open(to launch the deployed application)
After this step you will get an application like [this](http://thirdaysofpython-practice.herokuapp.com/)
## Exercises: Day 26
1. You will build [this application](https://thirtydaysofpython-v1-final.herokuapp.com/). Only the text analyser part is left
🎉 CONGRATULATIONS ! 🎉
[<< Day 25 ](../25_Day_Pandas/25_pandas.md) | [Day 27 >>](../27_Day_Python_with_mongodb/27_python_with_mongodb.md)
================================================
FILE: 27_Day_Python_with_mongodb/27_python_with_mongodb.md
================================================
[<< Day 26](../26_Day_Python_web/26_python_web.md) | [Day 28 >>](../28_Day_API/28_API.md)

- [📘 Day 27](#-day-27)
- [Python with MongoDB](#python-with-mongodb)
- [MongoDB](#mongodb)
- [SQL versus NoSQL](#sql-versus-nosql)
- [Getting Connection String(MongoDB URI)](#getting-connection-stringmongodb-uri)
- [Connecting Flask application to MongoDB Cluster](#connecting-flask-application-to-mongodb-cluster)
- [Creating a database and collection](#creating-a-database-and-collection)
- [Inserting many documents to collection](#inserting-many-documents-to-collection)
- [MongoDB Find](#mongodb-find)
- [Find with Query](#find-with-query)
- [Find query with modifier](#find-query-with-modifier)
- [Limiting documents](#limiting-documents)
- [Find with sort](#find-with-sort)
- [Update with query](#update-with-query)
- [Delete Document](#delete-document)
- [Drop a collection](#drop-a-collection)
- [💻 Exercises: Day 27](#-exercises-day-27)
# 📘 Day 27
# Python with MongoDB
Python is a backend technology and it can be connected with different data base applications. It can be connected to both SQL and noSQL databases. In this section, we connect Python with MongoDB database which is noSQL database.
## MongoDB
MongoDB is a NoSQL database. MongoDB stores data in a JSON like document which make MongoDB very flexible and scalable. Let us see the different terminologies of SQL and NoSQL databases. The following table will make the difference between SQL versus NoSQL databases.
### SQL versus NoSQL

In this section, we will focus on a NoSQL database MongoDB. Lets sign up on [mongoDB](https://www.mongodb.com/) by click on the sign in button then click register on the next page.

Complete the fields and click continue

Select the free plan

Choose the proximate free region and give any name for you cluster.

Now, a free sandbox is created

All local host access

Add user and password

Create a mongoDB uri link

Select Python 3.6 or above driver

### Getting Connection String(MongoDB URI)
Copy the connection string link and you will get something like this:
```sh
mongodb+srv://asabeneh:@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority
```
Do not worry about the url, it is a means to connect your application with mongoDB.
Let us replace the password placeholder with the password you used to add a user.
**Example:**
```sh
mongodb+srv://asabeneh:123123123@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority
```
Now, I replaced everything and the password is 123123 and the name of the database is *thirty_days_python*. This is just an example, your password must be stronger than the example password.
Python needs a mongoDB driver to access mongoDB database. We will use _pymongo_ with _dnspython_ to connect our application with mongoDB base . Inside your project directory install pymongo and dnspython.
```sh
pip install pymongo dnspython
```
The "dnspython" module must be installed to use mongodb+srv:// URIs. The dnspython is a DNS toolkit for Python. It supports almost all record types.
### Connecting Flask application to MongoDB Cluster
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
print(client.list_database_names())
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
When we run the above code we get the default mongoDB databases.
```sh
['admin', 'local']
```
### Creating a database and collection
Let us create a database, database and collection in mongoDB will be created if it doesn't exist. Let's create a data base name *thirty_days_of_python* and *students* collection.
To create a database:
```sh
db = client.name_of_databse # we can create a database like this or the second way
db = client['name_of_database']
```
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
# Creating database
db = client.thirty_days_of_python
# Creating students collection and inserting a document
db.students.insert_one({'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250})
print(client.list_database_names())
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
After we create a database, we also created a students collection and we used *insert_one()* method to insert a document.
Now, the database *thirty_days_of_python* and *students* collection have been created and the document has been inserted.
Check your mongoDB cluster and you will see both the database and the collection. Inside the collection, there will be a document.
```sh
['thirty_days_of_python', 'admin', 'local']
```
If you see this on the mongoDB cluster, it means you have successfully created a database and a collection.

If you have seen on the figure, the document has been created with a long id which acts as a primary key. Every time we create a document mongoDB create and unique id for it.
### Inserting many documents to collection
The *insert_one()* method inserts one item at a time if we want to insert many documents at once either we use *insert_many()* method or for loop.
We can use for loop to inset many documents at once.
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
students = [
{'name':'David','country':'UK','city':'London','age':34},
{'name':'John','country':'Sweden','city':'Stockholm','age':28},
{'name':'Sami','country':'Finland','city':'Helsinki','age':25},
]
for student in students:
db.students.insert_one(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
### MongoDB Find
The *find()* and *findOne()* methods are common method to find data in a collection in mongoDB database. It is similar to the SELECT statement in a MySQL database.
Let us use the _find_one()_ method to get a document in a database collection.
- \*find_one({"\_id": ObjectId("id"}): Gets the first occurrence if an id is not provided
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
student = db.students.find_one()
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Helsinki', 'city': 'Helsinki', 'age': 250}
```
The above query returns the first entry but we can target specific document using specific \_id. Let us do one example, use David's id to get David object.
'\_id':ObjectId('5df68a23f106fe2d315bbc8c')
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
from bson.objectid import ObjectId # id object
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
student = db.students.find_one({'_id':ObjectId('5df68a23f106fe2d315bbc8c')})
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
```
We have seen, how to use _find_one()_ using the above examples. Let's move one to _find()_
- _find()_: returns all the occurrence from a collection if we don't pass a query object. The object is pymongo.cursor object.
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
students = db.students.find()
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
```
We can specify which fields to return by passing second object in the _find({}, {})_. 0 means not include and 1 means include but we can not mix 0 and 1, except for \_id.
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
students = db.students.find({}, {"_id":0, "name": 1, "country":1}) # 0 means not include and 1 means include
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'name': 'Asabeneh', 'country': 'Finland'}
{'name': 'David', 'country': 'UK'}
{'name': 'John', 'country': 'Sweden'}
{'name': 'Sami', 'country': 'Finland'}
```
### Find with Query
In mongoDB find take a query object. We can pass a query object and we can filter the documents we like to filter out.
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
query = {
"country":"Finland"
}
students = db.students.find(query)
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
```
Query with modifiers
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
query = {
"city":"Helsinki"
}
students = db.students.find(query)
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
```
### Find query with modifier
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
query = {
"country":"Finland",
"city":"Helsinki"
}
students = db.students.find(query)
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
```
Query with modifiers
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
query = {"age":{"$gt":30}}
students = db.students.find(query)
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
```
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
query = {"age":{"$gt":30}}
students = db.students.find(query)
for student in students:
print(student)
```
```sh
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
```
### Limiting documents
We can limit the number of documents we return using the _limit()_ method.
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
db.students.find().limit(3)
```
### Find with sort
By default, sort is in ascending order. We can change the sorting to descending order by adding -1 parameter.
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
students = db.students.find().sort('name')
for student in students:
print(student)
students = db.students.find().sort('name',-1)
for student in students:
print(student)
students = db.students.find().sort('age')
for student in students:
print(student)
students = db.students.find().sort('age',-1)
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
Ascending order
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
```
Descending order
```sh
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
```
### Update with query
We will use *update_one()* method to update one item. It takes two object one is a query and the second is the new object.
The first person, Asabeneh got a very implausible age. Let us update Asabeneh's age.
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
query = {'age':250}
new_value = {'$set':{'age':38}}
db.students.update_one(query, new_value)
# lets check the result if the age is modified
for student in db.students.find():
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 38}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
```
When we want to update many documents at once we use *upate_many()* method.
### Delete Document
The method *delete_one()* deletes one document. The *delete_one()* takes a query object parameter. It only removes the first occurrence.
Let us remove one John from the collection.
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
query = {'name':'John'}
db.students.delete_one(query)
for student in db.students.find():
print(student)
# lets check the result if the age is modified
for student in db.students.find():
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 38}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
```
As you can see John has been removed from the collection.
When we want to delete many documents we use *delete_many()* method, it takes a query object. If we pass an empty query object to *delete_many({})* it will delete all the documents in the collection.
### Drop a collection
Using the _drop()_ method we can delete a collection from a database.
```py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
db.students.drop()
```
Now, we have deleted the students collection from the database.
## 💻 Exercises: Day 27
🎉 CONGRATULATIONS ! 🎉
[<< Day 26](../26_Day_Python_web/26_python_web.md) | [Day 28 >>](../28_Day_API/28_API.md)
================================================
FILE: 28_Day_API/28_API.md
================================================
[<< Day 27](../27_Day_Python_with_mongodb/27_python_with_mongodb.md) | [Day 29 >>](../29_Day_Building_API/29_building_API.md)

- [📘 Day 28](#-day-28)
- [Application Programming Interface(API)](#application-programming-interfaceapi)
- [API](#api)
- [Building API](#building-api)
- [HTTP(Hypertext Transfer Protocol)](#httphypertext-transfer-protocol)
- [Structure of HTTP](#structure-of-http)
- [Initial Request Line(Status Line)](#initial-request-linestatus-line)
- [Initial Response Line(Status Line)](#initial-response-linestatus-line)
- [Header Fields](#header-fields)
- [The message body](#the-message-body)
- [Request Methods](#request-methods)
- [💻 Exercises: Day 28](#-exercises-day-28)
# 📘 Day 28
# Application Programming Interface(API)
## API
API stands for Application Programming Interface. The kind of API we will cover in this section is going to be Web APIs.
Web APIs are the defined interfaces through which interactions happen between an enterprise and applications that use its assets, which also is a Service Level Agreement (SLA) to specify the functional provider and expose the service path or URL for its API users.
In the context of web development, an API is defined as a set of specifications, such as Hypertext Transfer Protocol (HTTP) request messages, along with a definition of the structure of response messages, usually in an XML or a JavaScript Object Notation (JSON) format.
Web API has been moving away from Simple Object Access Protocol (SOAP) based web services and service-oriented architecture (SOA) towards more direct representational state transfer (REST) style web resources.
Social media services, web APIs have allowed web communities to share content and data between communities and different platforms.
Using API, content that is created in one place dynamically can be posted and updated to multiple locations on the web.
For example, Twitter's REST API allows developers to access core Twitter data and the Search API provides methods for developers to interact with Twitter Search and trends data.
Many applications provide API end points. Some examples of API such as the countries [API](https://restcountries.eu/rest/v2/all), [cat's breed API](https://api.thecatapi.com/v1/breeds).
In this section, we will cover a RESTful API that uses HTTP request methods to GET, PUT, POST and DELETE data.
## Building API
RESTful API is an application program interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. In the previous sections, we have learned about python, flask and mongoDB. We will use the knowledge we acquire to develop a RESTful API using Python flask and mongoDB database. Every application which has CRUD(Create, Read, Update, Delete) operation has an API to create data, to get data, to update data or to delete data from a database.
To build an API, it is good to understand HTTP protocol and HTTP request and response cycle.
## HTTP(Hypertext Transfer Protocol)
HTTP is an established communication protocol between a client and a server. A client in this case is a browser and server is the place where you access data. HTTP is a network protocol used to deliver resources which could be files on the World Wide Web, whether they are HTML files, image files, query results, scripts, or other file types.
A browser is an HTTP client because it sends requests to an HTTP server (Web server), which then sends responses back to the client.
## Structure of HTTP
HTTP uses client-server model. An HTTP client opens a connection and sends a request message to an HTTP server and the HTTP server returns response message which is the requested resources. When the request response cycle completes the server closes the connection.

The format of the request and response messages are similar. Both kinds of messages have
- an initial line,
- zero or more header lines,
- a blank line (i.e. a CRLF by itself), and
- an optional message body (e.g. a file, or query data, or query output).
Let us an example of request and response messages by navigating this site:https://thirtydaysofpython-v1-final.herokuapp.com/. This site has been deployed on Heroku free dyno and in some months may not work because of high request. Support this work to make the server run all the time.

## Initial Request Line(Status Line)
The initial request line is different from the response.
A request line has three parts, separated by spaces:
- method name(GET, POST, HEAD)
- path of the requested resource,
- the version of HTTP being used. eg GET / HTTP/1.1
GET is the most common HTTP that helps to get or read resource and POST is a common request method to create resource.
### Initial Response Line(Status Line)
The initial response line, called the status line, also has three parts separated by spaces:
- HTTP version
- Response status code that gives the result of the request, and a reason which describes the status code. Example of status lines are:
HTTP/1.0 200 OK
or
HTTP/1.0 404 Not Found
Notes:
The most common status codes are:
200 OK: The request succeeded, and the resulting resource (e.g. file or script output) is returned in the message body.
500 Server Error
A complete list of HTTP status code can be found [here](https://httpstatuses.com/). It can be also found [here](https://httpstatusdogs.com/).
### Header Fields
As you have seen in the above screenshot, header lines provide information about the request or response, or about the object sent in the message body.
```sh
GET / HTTP/1.1
Host: thirtydaysofpython-v1-final.herokuapp.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36
Sec-Fetch-User: ?1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Referer: https://thirtydaysofpython-v1-final.herokuapp.com/post
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9,fi-FI;q=0.8,fi;q=0.7,en-CA;q=0.6,en-US;q=0.5,fr;q=0.4
```
### The message body
An HTTP message may have a body of data sent after the header lines. In a response, this is where the requested resource is returned to the client (the most common use of the message body), or perhaps explanatory text if there's an error. In a request, this is where user-entered data or uploaded files are sent to the server.
If an HTTP message includes a body, there are usually header lines in the message that describe the body. In particular,
The Content-Type: header gives the MIME-type of the data in the body(text/html, application/json, text/plain, text/css, image/gif).
The Content-Length: header gives the number of bytes in the body.
### Request Methods
The GET, POST, PUT and DELETE are the HTTP request methods which we are going to implement an API or a CRUD operation application.
1. GET: GET method is used to retrieve and get information from the given server using a given URI. Requests using GET should only retrieve data and should have no other effect on the data.
2. POST: POST request is used to create data and send data to the server, for example, creating a new post, file upload, etc. using HTML forms.
3. PUT: Replaces all current representations of the target resource with the uploaded content and we use it modify or update data.
4. DELETE: Removes data
## 💻 Exercises: Day 28
1. Read about API and HTTP
🎉 CONGRATULATIONS ! 🎉
[<< Day 27](../27_Day_Python_with_mongodb/27_python_with_mongodb.md) | [Day 29 >>](../29_Day_Building_API/29_building_API.md)
================================================
FILE: 29_Day_Building_API/29_building_API.md
================================================
[<< Day 28](../28_Day_API/28_API.md) | [Day 29 >>](../30_Day_Conclusions/30_conclusions.md)

- [Day 29](#day-29)
- [Building API](#building-api)
- [Structure of an API](#structure-of-an-api)
- [Retrieving data using get](#retrieving-data-using-get)
- [Getting a document by id](#getting-a-document-by-id)
- [Creating data using POST](#creating-data-using-post)
- [Updating using PUT](#updating-using-put)
- [Deleting a document using Delete](#deleting-a-document-using-delete)
- [💻 Exercises: Day 29](#-exercises-day-29)
## Day 29
## Building API
In this section, we will cove a RESTful API that uses HTTP request methods to GET, PUT, POST and DELETE data.
RESTful API is an application program interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. In the previous sections, we have learned about python, flask and mongoDB. We will use the knowledge we acquire to develop a RESTful API using python flask and mongoDB. Every application which has CRUD(Create, Read, Update, Delete) operation has an API to create data, to get data, to update data or to delete data from database.
The browser can handle only get request. Therefore, we have to have a tool which can help us to handle all request methods(GET, POST, PUT, DELETE).
Examples of API
- Countries API: https://restcountries.eu/rest/v2/all
- Cats breed API: https://api.thecatapi.com/v1/breeds
[Postman](https://www.getpostman.com/) is a very popular tool when it comes to API development. So, if you like to do this section you need to [download postman](https://www.getpostman.com/). An alternative of Postman is [Insomnia](https://insomnia.rest/download).

### Structure of an API
An API end point is a URL which can help to retrieve, create, update or delete a resource. The structure looks like this:
Example:
https://api.twitter.com/1.1/lists/members.json
Returns the members of the specified list. Private list members will only be shown if the authenticated user owns the specified list.
The name of the company name followed by version followed by the purpose of the API.
The methods:
HTTP methods & URLs
The API uses the following HTTP methods for object manipulation:
```sh
GET Used for object retrieval
POST Used for object creation and object actions
PUT Used for object update
DELETE Used for object deletion
```
Let us build an API which collects information about 30DaysOfPython students. We will collect the name, country, city, date of birth, skills and bio.
To implement this API, we will use:
- Postman
- Python
- Flask
- MongoDB
### Retrieving data using get
In this step, let us use dummy data and return it as a json. To return it as json, will use json module and Response module.
```py
# let's import the flask
from flask import Flask, Response
import json
import os
app = Flask(__name__)
@app.route('/api/v1.0/students', methods = ['GET'])
def students ():
student_list = [
{
'name':'Asabeneh',
'country':'Finland',
'city':'Helsinki',
'skills':['HTML', 'CSS','JavaScript','Python']
},
{
'name':'David',
'country':'UK',
'city':'London',
'skills':['Python','MongoDB']
},
{
'name':'John',
'country':'Sweden',
'city':'Stockholm',
'skills':['Java','C#']
}
]
return Response(json.dumps(student_list), mimetype='application/json')
if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
When you request the http://localhost:5000/api/v1.0/students url on the browser you will get this:

When you request the http://localhost:5000/api/v1.0/students url on the browser you will get this:

In stead of displaying dummy data let us connect the flask application with MongoDB and get data from mongoDB database.
```py
# let's import the flask
from flask import Flask, Response
import json
import pymongo
import os
app = Flask(__name__)
#
MONGODB_URI='mongodb+srv://asabeneh:your_password@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
@app.route('/api/v1.0/students', methods = ['GET'])
def students ():
return Response(json.dumps(student), mimetype='application/json')
if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
By connecting the flask, we can fetch students collection data from the thirty_days_of_python database.
```sh
[
{
"_id": {
"$oid": "5df68a21f106fe2d315bbc8b"
},
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"age": 38
},
{
"_id": {
"$oid": "5df68a23f106fe2d315bbc8c"
},
"name": "David",
"country": "UK",
"city": "London",
"age": 34
},
{
"_id": {
"$oid": "5df68a23f106fe2d315bbc8e"
},
"name": "Sami",
"country": "Finland",
"city": "Helsinki",
"age": 25
}
]
```
### Getting a document by id
We can access single document using an id, let's access Asabeneh using his id.
http://localhost:5000/api/v1.0/students/5df68a21f106fe2d315bbc8b
```py
# let's import the flask
from flask import Flask, Response
import json
from bson.objectid import ObjectId
import json
from bson.json_util import dumps
import pymongo
import os
app = Flask(__name__)
#
MONGODB_URI='mongodb+srv://asabeneh:your_password@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
@app.route('/api/v1.0/students', methods = ['GET'])
def students ():
return Response(json.dumps(student), mimetype='application/json')
@app.route('/api/v1.0/students/', methods = ['GET'])
def single_student (id):
student = db.students.find({'_id':ObjectId(id)})
return Response(dumps(student), mimetype='application/json')
if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
[
{
"_id": {
"$oid": "5df68a21f106fe2d315bbc8b"
},
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"age": 38
}
]
```
### Creating data using POST
We use the POST request method to create data
```py
# let's import the flask
from flask import Flask, Response
import json
from bson.objectid import ObjectId
import json
from bson.json_util import dumps
import pymongo
from datetime import datetime
import os
app = Flask(__name__)
#
MONGODB_URI='mongodb+srv://asabeneh:your_password@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
@app.route('/api/v1.0/students', methods = ['GET'])
def students ():
return Response(json.dumps(student), mimetype='application/json')
@app.route('/api/v1.0/students/', methods = ['GET'])
def single_student (id):
student = db.students.find({'_id':ObjectId(id)})
return Response(dumps(student), mimetype='application/json')
@app.route('/api/v1.0/students', methods = ['POST'])
def create_student ():
name = request.form['name']
country = request.form['country']
city = request.form['city']
skills = request.form['skills'].split(', ')
bio = request.form['bio']
birthyear = request.form['birthyear']
created_at = datetime.now()
student = {
'name': name,
'country': country,
'city': city,
'birthyear': birthyear,
'skills': skills,
'bio': bio,
'created_at': created_at
}
db.students.insert_one(student)
return ;
def update_student (id):
if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
### Updating using PUT
```py
# let's import the flask
from flask import Flask, Response
import json
from bson.objectid import ObjectId
import json
from bson.json_util import dumps
import pymongo
from datetime import datetime
import os
app = Flask(__name__)
#
MONGODB_URI='mongodb+srv://asabeneh:your_password@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
@app.route('/api/v1.0/students', methods = ['GET'])
def students ():
return Response(json.dumps(student), mimetype='application/json')
@app.route('/api/v1.0/students/', methods = ['GET'])
def single_student (id):
student = db.students.find({'_id':ObjectId(id)})
return Response(dumps(student), mimetype='application/json')
@app.route('/api/v1.0/students', methods = ['POST'])
def create_student ():
name = request.form['name']
country = request.form['country']
city = request.form['city']
skills = request.form['skills'].split(', ')
bio = request.form['bio']
birthyear = request.form['birthyear']
created_at = datetime.now()
student = {
'name': name,
'country': country,
'city': city,
'birthyear': birthyear,
'skills': skills,
'bio': bio,
'created_at': created_at
}
db.students.insert_one(student)
return
@app.route('/api/v1.0/students/', methods = ['PUT']) # this decorator create the home route
def update_student (id):
query = {"_id":ObjectId(id)}
name = request.form['name']
country = request.form['country']
city = request.form['city']
skills = request.form['skills'].split(', ')
bio = request.form['bio']
birthyear = request.form['birthyear']
created_at = datetime.now()
student = {
'name': name,
'country': country,
'city': city,
'birthyear': birthyear,
'skills': skills,
'bio': bio,
'created_at': created_at
}
db.students.update_one(query, student)
# return Response(dumps({"result":"a new student has been created"}), mimetype='application/json')
return
def update_student (id):
if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
### Deleting a document using Delete
```py
# let's import the flask
from flask import Flask, Response
import json
from bson.objectid import ObjectId
import json
from bson.json_util import dumps
import pymongo
from datetime import datetime
import os
app = Flask(__name__)
#
MONGODB_URI='mongodb+srv://asabeneh:your_password@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
@app.route('/api/v1.0/students', methods = ['GET'])
def students ():
return Response(json.dumps(student), mimetype='application/json')
@app.route('/api/v1.0/students/', methods = ['GET'])
def single_student (id):
student = db.students.find({'_id':ObjectId(id)})
return Response(dumps(student), mimetype='application/json')
@app.route('/api/v1.0/students', methods = ['POST'])
def create_student ():
name = request.form['name']
country = request.form['country']
city = request.form['city']
skills = request.form['skills'].split(', ')
bio = request.form['bio']
birthyear = request.form['birthyear']
created_at = datetime.now()
student = {
'name': name,
'country': country,
'city': city,
'birthyear': birthyear,
'skills': skills,
'bio': bio,
'created_at': created_at
}
db.students.insert_one(student)
return
@app.route('/api/v1.0/students/', methods = ['PUT']) # this decorator create the home route
def update_student (id):
query = {"_id":ObjectId(id)}
name = request.form['name']
country = request.form['country']
city = request.form['city']
skills = request.form['skills'].split(', ')
bio = request.form['bio']
birthyear = request.form['birthyear']
created_at = datetime.now()
student = {
'name': name,
'country': country,
'city': city,
'birthyear': birthyear,
'skills': skills,
'bio': bio,
'created_at': created_at
}
db.students.update_one(query, student)
# return Response(dumps({"result":"a new student has been created"}), mimetype='application/json')
return
@app.route('/api/v1.0/students/', methods = ['PUT']) # this decorator create the home route
def update_student (id):
query = {"_id":ObjectId(id)}
name = request.form['name']
country = request.form['country']
city = request.form['city']
skills = request.form['skills'].split(', ')
bio = request.form['bio']
birthyear = request.form['birthyear']
created_at = datetime.now()
student = {
'name': name,
'country': country,
'city': city,
'birthyear': birthyear,
'skills': skills,
'bio': bio,
'created_at': created_at
}
db.students.update_one(query, student)
# return Response(dumps({"result":"a new student has been created"}), mimetype='application/json')
return ;
@app.route('/api/v1.0/students/', methods = ['DELETE'])
def delete_student (id):
db.students.delete_one({"_id":ObjectId(id)})
return
if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
## 💻 Exercises: Day 29
1. Implement the above example and develop [this](https://thirtydayofpython-api.herokuapp.com/)
🎉 CONGRATULATIONS ! 🎉
[<< Day 28](../28_Day_API/28_API.md) | [Day 30 >>](../30_Day_Conclusions/30_conclusions.md)
================================================
FILE: 30_Day_Conclusions/30_conclusions.md
================================================
[<< Day 29](../29_Day_Building_API/29_building_API.md)

- [Day 30](#day-30)
- [Conclusions](#conclusions)
- [Testimony](#testimony)
# Day 30
## Conclusions
In the process of preparing this material I have learned quite a lot and you have inspired me to do more. Congratulations for making it to this level. If you have done all the exercise and the projects, now you are capable to go to a data analysis, data science, machine learning or web development paths. [Support the author for more educational materials](https://www.paypal.com/paypalme/asabeneh).
## Testimony
Now it is time to express your thoughts about the Author and 30DaysOfPython. You can leave your testimonial on this [link](https://www.asabeneh.com/testimonials)
GIVE FEEDBACK:
http://thirtydayofpython-api.herokuapp.com/feedback
🎉 CONGRATULATIONS ! 🎉
[<< Day 29](../29_Day_Building_API/29_building_API.md)
================================================
FILE: Chinese/02_variables_builtin_functions.md
================================================
[<< 第 14 天](../14_Day_Higher_order_functions/14_higher_order_functions.md) | [第 16 天 >>](../16_Day_Python_date_time/16_python_datetime.md)

- [📘 第 15 天](#-第15天)
- [Python 错误类型](#python错误类型)
- [SyntaxError](#syntaxerror)
- [NameError](#nameerror)
- [IndexError](#indexerror)
- [ModuleNotFoundError](#modulenotfounderror)
- [AttributeError](#attributeerror)
- [KeyError](#keyerror)
- [TypeError](#typeerror)
- [ImportError](#importerror)
- [ValueError](#valueerror)
- [ZeroDivisionError](#zerodivisionerror)
- [💻 练习: 第 15 天](#练习-第15天)
# 📘 第 15 天
## Python 错误类型
当我们编写代码时,很常见会打错字或出现其他一些常见错误。如果我们的代码不能运行,Python 解释器会显示一条信息,包含关于问题发生在哪里以及错误类型的反馈信息。它有时还会给我们提供可能的修复建议。理解编程语言中的不同类型的错误将有助于我们快速调试代码,同时也会使我们在工作中变得更优秀。
让我们逐个来看最常见的错误类型。首先让我们打开 Python 交互式 Shell。打开电脑终端,输入‘python’,将会打开 Python 交互式 Shell。
### SyntaxError
**示例 1: SyntaxError**
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print 'hello world'
File "", line 1
print 'hello world'
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('hello world')?
>>>
```
如你所见,我们犯了一个语法错误,因为我们忘了用括号包裹字符串,Python 已经建议了解决办法。让我们修复它。
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print 'hello world'
File "", line 1
print 'hello world'
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('hello world')?
>>> print('hello world')
hello world
>>>
```
错误类型是*SyntaxError*。修复之后我们的代码顺利执行了。让我们看看更多的错误类型。
### NameError
**示例 1: NameError**
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print(age)
Traceback (most recent call last):
File "", line 1, in
NameError: name 'age' is not defined
>>>
```
如你所见,消息显示年龄变量未定义。确实,我们没有定义年龄变量,但我们试图打印它。现在,让我们通过定义并赋值它来修复它。
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print(age)
Traceback (most recent call last):
File "", line 1, in
NameError: name 'age' is not defined
>>> age = 25
>>> print(age)
25
>>>
```
错误类型是*NameError*。我们通过定义变量名调试了错误。
### IndexError
**示例 1: IndexError**
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> numbers = [1, 2, 3, 4, 5]
>>> numbers[5]
Traceback (most recent call last):
File "", line 1, in
IndexError: list index out of range
>>>
```
在上面的例子中,Python 引发了 IndexError,因为列表只有 0 到 4 的索引,因此超出了范围。
### ModuleNotFoundError
**示例 1: ModuleNotFoundError**
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'maths'
>>>
```
在上面的例子中,我故意在 math 后面多加了一个 s,所以引发了*ModuleNotFoundError*。让我们通过去掉多余的 s 来修复它。
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'maths'
>>> import math
>>>
```
我们修复了它,让我们使用 math 模块中的一些函数。
### AttributeError
**示例 1: AttributeError**
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (最
澘會末呼つはゃす尽ルル귀행세뿌府ぐ
<|vq_10375|> File "", line 1, in
ModuleNotFoundError: No module named 'maths'
>>> import math
>>> math.PI
Traceback (most recent call last):
File "", line 1, in
AttributeError: module 'math' has no attribute 'PI'
>>>
```
如你所见,我又犯了一个错误!我试图从 math 模块调用 PI 函数,但实际上它是 pi。它引发了属性错误,意味着该函数在模块中不存在。让我们通过将 PI 改为 pi 来修复它。
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'maths'
>>> import math
>>> math.PI
Traceback (most recent call last):
File "", line 1, in
AttributeError: module 'math' has no attribute 'PI'
>>> math.pi
3.141592653589793
>>>
```
现在,当我们从 math 模块调用 pi 时得到了结果。
### KeyError
**示例 1: KeyError**
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> users = {'name':'Asab', 'age':250, 'country':'Finland'}
>>> users['name']
'Asab'
>>> users['county']
Traceback (most recent call last):
File "", line 1, in
KeyError: 'county'
>>>
```
如你所见,用于获取字典值的键存在拼写错误。这是一个 key error,修复非常简单。让我们做一下!
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> user = {'name':'Asab', 'age':250, 'country':'Finland'}
>>> user['name']
'Asab'
>>> user['county']
Traceback (most recent call last):
File "", line 1, in
KeyError: 'county'
>>> user['country']
'Finland'
>>>
```
我们调试了错误,代码运行并获取了值。
### TypeError
**示例 1: TypeError**
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 4 + '3'
Traceback (most recent call last):
File "", line 1, in
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>>
```
在上面的例子中,引发了 TypeError,因为我们不能将数字和字符串相加。第一个解决方法是将字符串转换为 int 或 float。另一种解决方法是将数字转换为字符串(结果将是'43')。让我们跟随第一种解决方案。
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 4 + '3'
Traceback (most recent call last):
File "", line 1, in
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> 4 + int('3')
7
>>> 4 + float('3')
7.0
>>>
```
错误消除,我们得到了期望的结果。
### ImportError
**示例 1: TypeError**
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from math import power
Traceback (most recent call last):
File "", line 1, in
ImportError: cannot import name 'power' from 'math'
>>>
```
数学模块中没有函数叫做 power,它是以另一个名字存在: _pow_。让我们纠正它:
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from math import power
Traceback (most recent call last):
File "", line 1, in
ImportError: cannot import name 'power' from 'math'
>>> from math import pow
>>> pow(2,3)
8.0
>>>
```
### ValueError
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> int('12a')
Traceback (most recent call last):
File "", line 1, in
ValueError: invalid literal for int() with base 10: '12a'
>>>
```
在这种情况下,我们无法将给定字符串更改为数字,因为它包含了'a'字母。
### ZeroDivisionError
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 1/0
Traceback (most recent call last):
File "", line 1, in
ZeroDivisionError: division by zero
>>>
```
我们不能将一个数除以零。
我们已经涵盖了一些 Python 错误类型,如果你想了解更多,请查看 Python 文档中的 Python 错误类型。
如果你能够很好地阅读错误类型,你将能够快速修复你的 bug,并且你也会成为一个更优秀的程序员。
🌕 你正在不断进步。你已经走到了通往卓越的半程。现在来一些锻炼大脑和肌肉的练习吧。
## 💻 练习: 第 15 天
1. 打开你 Python 的交互式 Shell,尝试本节中涵盖的所有示例。
🎉 恭喜! 🎉
[<< 第 14 天](../14_Day_Higher_order_functions/14_higher_order_functions.md) | [第 16 天 >>](../16_Day_Python_date_time/16_python_datetime.md)
================================================
FILE: Chinese/15_python_type_errors_cn.md
================================================
# 30天Python编程挑战:第15天 - Python类型错误
- [Day 15](#day-15)
- [Python错误类型](#python错误类型)
- [SyntaxError (语法错误)](#syntaxerror-语法错误)
- [NameError (名称错误)](#nameerror-名称错误)
- [IndexError (索引错误)](#indexerror-索引错误)
- [ModuleNotFoundError (模块未找到错误)](#modulenotfounderror-模块未找到错误)
- [AttributeError (属性错误)](#attributeerror-属性错误)
- [KeyError (键错误)](#keyerror-键错误)
- [TypeError (类型错误)](#typeerror-类型错误)
- [ImportError (导入错误)](#importerror-导入错误)
- [ValueError (值错误)](#valueerror-值错误)
- [ZeroDivisionError (零除错误)](#zerodivisionerror-零除错误)
- [💻 练习 - 第15天](#-练习---第15天)
# 📘 Day 15
## Python错误类型
当我们编写代码时,常常会出现打字错误或其他常见错误。如果我们的代码运行失败,Python解释器会显示一条消息,提供有关问题发生位置和错误类型的反馈信息。有时它还会给我们提供可能的修复建议。了解编程语言中不同类型的错误将帮助我们快速调试代码,并使我们在编程技能上有所提高。
让我们一一查看最常见的错误类型。首先,让我们打开Python交互式shell。转到你的计算机终端并输入'python'。Python交互式shell将会被打开。
### SyntaxError (语法错误)
**示例1: SyntaxError**
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print 'hello world'
File "", line 1
print 'hello world'
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('hello world')?
>>>
```
如你所见,我们犯了一个语法错误,因为我们忘记用括号括起字符串,而Python已经提出了解决方案。让我们修复它。
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print 'hello world'
File "", line 1
print 'hello world'
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('hello world')?
>>> print('hello world')
hello world
>>>
```
错误是一个_SyntaxError_。修复后,我们的代码顺利执行。让我们看看更多的错误类型。
### NameError (名称错误)
**示例1: NameError**
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print(age)
Traceback (most recent call last):
File "", line 1, in
NameError: name 'age' is not defined
>>>
```
从上面的消息可以看出,名称age没有被定义。是的,确实如此,我们没有定义age变量,但我们试图像已经声明了一样打印它。现在,让我们通过声明变量并为其赋值来修复这个问题。
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print(age)
Traceback (most recent call last):
File "", line 1, in
NameError: name 'age' is not defined
>>> age = 25
>>> print(age)
25
>>>
```
错误类型是_NameError_。我们通过定义变量名来调试了错误。
### IndexError (索引错误)
**示例1: IndexError**
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> numbers = [1, 2, 3, 4, 5]
>>> numbers[5]
Traceback (most recent call last):
File "", line 1, in
IndexError: list index out of range
>>>
```
在上面的例子中,Python抛出了一个_IndexError_,因为列表的索引只有0到4,所以索引5超出了范围。
### ModuleNotFoundError (模块未找到错误)
**示例1: ModuleNotFoundError**
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'maths'
>>>
```
在上面的例子中,我故意在math后面添加了一个多余的s,结果抛出了_ModuleNotFoundError_。让我们通过从math中删除多余的s来修复它。
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'maths'
>>> import math
>>>
```
我们修复了它,所以让我们使用math模块中的一些函数。
### AttributeError (属性错误)
**示例1: AttributeError**
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'maths'
>>> import math
>>> math.PI
Traceback (most recent call last):
File "", line 1, in
AttributeError: module 'math' has no attribute 'PI'
>>>
```
如你所见,我又犯了一个错误!我试图从math模块调用PI函数,而不是pi。这抛出了一个属性错误,表示该函数在模块中不存在。让我们通过将PI更改为pi来修复它。
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'maths'
>>> import math
>>> math.PI
Traceback (most recent call last):
File "", line 1, in
AttributeError: module 'math' has no attribute 'PI'
>>> math.pi
3.141592653589793
>>>
```
现在,当我们从math模块调用pi时,我们得到了结果。
### KeyError (键错误)
**示例1: KeyError**
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> users = {'name':'Asab', 'age':250, 'country':'Finland'}
>>> users['name']
'Asab'
>>> users['county']
Traceback (most recent call last):
File "", line 1, in
KeyError: 'county'
>>>
```
如你所见,在用于获取字典值的键中有一个拼写错误。这是一个键错误,修复方法很简单。让我们来做这个!
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> user = {'name':'Asab', 'age':250, 'country':'Finland'}
>>> user['name']
'Asab'
>>> user['county']
Traceback (most recent call last):
File "", line 1, in
KeyError: 'county'
>>> user['country']
'Finland'
>>>
```
我们调试了错误,我们的代码运行并得到了结果。
### TypeError (类型错误)
**示例1: TypeError**
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 4 + '3'
Traceback (most recent call last):
File "", line 1, in
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>>
```
在上面的例子中,出现了TypeError,因为我们不能将数字与字符串相加。第一个解决方案是将字符串转换为int或float。另一个解决方案是将数字转换为字符串(那么结果将是'43')。让我们采用第一种修复方式。
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 4 + '3'
Traceback (most recent call last):
File "", line 1, in
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> 4 + int('3')
7
>>> 4 + float('3')
7.0
>>>
```
错误已消除,我们得到了预期的结果。
### ImportError (导入错误)
**示例1: ImportError**
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from math import power
Traceback (most recent call last):
File "", line 1, in
ImportError: cannot import name 'power' from 'math'
>>>
```
math模块中没有名为power的函数,它的名字是不同的:_pow_。让我们纠正它:
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from math import power
Traceback (most recent call last):
File "", line 1, in
ImportError: cannot import name 'power' from 'math'
>>> from math import pow
>>> pow(2,3)
8.0
>>>
```
### ValueError (值错误)
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> int('12a')
Traceback (most recent call last):
File "", line 1, in
ValueError: invalid literal for int() with base 10: '12a'
>>>
```
在这种情况下,我们无法将给定的字符串转换为数字,因为其中有字母'a'。
### ZeroDivisionError (零除错误)
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 1/0
Traceback (most recent call last):
File "", line 1, in
ZeroDivisionError: division by zero
>>>
```
我们不能用零去除一个数字。
我们已经介绍了一些Python错误类型,如果你想了解更多,请查看Python文档中关于Python错误类型的内容。
如果你擅长阅读错误类型,那么你将能够快速修复你的bug,你也将成为一个更好的程序员。
🌕 你正在进步。你已经完成了一半的道路,正走向伟大。现在做一些练习来锻炼你的大脑和肌肉。
## 💻 练习 - 第15天
1. 打开你的Python交互式shell,尝试本节中介绍的所有示例。
🎉 恭喜!🎉
[<< 第 14 天](./14_higher_order_functions.md) | [第 16 天 >>](./16_python_datetime_cn.md)
================================================
FILE: Chinese/16_python_datetime.md
================================================
[<< Day 1](../readme.md) | [Day 3 >>](../03_Day_Operators/03_operators.md)

- [📘 Day 2](#-day-2)
- [내장 함수](#내장-함수)
- [변수](#변수)
- [한 줄로 여러개의 변수 선언](#한-줄로-여러개의-변수-선언)
- [자료형](#자료형)
- [자료형 확인 및 형변환](#자료형-확인-및-형변환)
- [숫자](#숫자)
- [💻 Exercises - Day 2](#-exercises---day-2)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
# 📘 Day 2
## 내장 함수
파이썬에는 수많은 내장 함수가 있습니다. 내장 함수는 전역에서 사용 가능하고 그건 importing 이나 configuring없이 내장 함수를 사용 가능하다는 뜻입니다. 다음은 가장 자주 사용되는 파이썬 내장함수들 중 몇가지입니다: _print()_, _len()_, _type()_, _int()_, _float()_, _str()_, _input()_, _list()_, _dict()_, _min()_, _max()_, _sum()_, _sorted()_, _open()_, _file()_, _help()_, and _dir()_. 밑의 표에서 [파이썬 공식문서](https://docs.python.org/3.9/library/functions.html) 에 쓰여진 파이썬 내장 함수의 전체 목록을 볼 수 있습니다.

파이썬 쉘을 열고 가장 자주 사용되는 내장 함수를 사용해봅시다.

다른 내장 함수를 사용해 더 연습해봅시다.

위의 터미널에서 볼 수 있듯이, 파이썬에는 reserved word가 있습니다. reserved word는 변수나 함수를 선언할때 사용되지 않습니다. 변수에 관해서는 다음 장에서 다룰것입니다.
이제 당신은 내장 함수에 익숙해졌을 것이라 믿습니다. 한번 더 내장 함수의 연습을 하고 다음 장으로 넘어갑시다.

## 변수
변수는 컴퓨터 메모리에 정보를 저장합니다. Mnemonic 변수는 많은 프로그래밍 언어에서 사용하도록 권장됩니다. Mnemonic 변수는 쉽게 기억하고 연관지을 수 있는 변수 이름입니다. 한 변수는 정보가 저장되어있는 메모리 주소를 참조합니다.
변수 이름을 지정할 때는 시작 부분의 숫자, 특수 문자, 하이픈을 사용할 수 없습니다. 변수는 짧은 이름(예: x, y, z)을 가질 수 있지만 더 변수에 대한 설명을 담은 이름(이름, 성, 나이, 국가)을 사용하는 것을 추천합니다.
파이썬 변수 이름 규칙
- 변수 이름은 문자 또는 밑줄 문자로 시작해야 합니다
- 변수 이름은 숫자로 시작할 수 없습니다
- 변수 이름에는 알파벳과 숫자와 밑줄(A-z, 0-9 및 \_)만 사용할 수 있습니다
- 변수 이름은 대소문자를 구분합니다(firstname, Firstname, FirstName, FIRSTNAME은 서로 다른 변수)
사용가능한 변수 이름들을 살펴봅시다
```shell
firstname
lastname
age
country
city
first_name
last_name
capital_city
_if # reserved word를 변수 이름으로 사용하고 싶은 경우
year_2021
year2021
current_year_2021
birth_year
num1
num2
```
사용할 수 없는 변수 이름들
```shell
first-name
first@name
first$name
num-1
1num
```
우리는 많은 파이썬 개발자들이 채택한 표준 파이썬 변수 명명 방식을 사용할 것입니다. 파이썬 개발자들은 스네이크 케이스(snake_case) 변수 명명 규칙을 사용합니다. 우리는 두 개 이상의 단어를 포함하는 변수에 대해 각 단어 뒤에 밑줄 문자를 사용합니다(예: first_name, last_name, engine_rotation_speed). 아래 예제는 변수의 표준 명명 예제이며, 변수 이름이 둘 이상의 단어일 경우 밑줄이 필요합니다.
변수에 특정 데이터 유형을 할당할 때 이를 변수 선언이라고 합니다. 예를 들어 아래 예제에서 내 이름은 first_name 변수에 할당됩니다. 등호 기호는 할당 연산자입니다. 할당은 변수에 데이터를 저장하는 것을 의미합니다. 파이썬에서 등호 기호는 수학에서의 등호가 아닙니다.
_Example:_
```py
# Variables in Python
first_name = 'Asabeneh'
last_name = 'Yetayeh'
country = 'Finland'
city = 'Helsinki'
age = 250
is_married = True
skills = ['HTML', 'CSS', 'JS', 'React', 'Python']
person_info = {
'firstname':'Asabeneh',
'lastname':'Yetayeh',
'country':'Finland',
'city':'Helsinki'
}
```
내장 함수인 _print()_ 와 _len()_ 을 사용해봅시다. Print 함수는 인자의 수에 제한이 없습니다. 인자는 함수 괄호 안에 넣어 전달할 수 있는 값입니다. 아래 예제를 봅시다.
**Example:**
```py
print('Hello, World!') # Hello, World! 라는 글이 하나의 인자입니다
print('Hello',',', 'World','!') # 여러개의 인자를 받을 수 있습니다, 네개의 인자가 넘겨졌습니다
print(len('Hello, World!')) # 하나의 인자만을 받습니다
```
위에서 정의된 변수들을 찍어보고 길이를 찾아봅시다:
**Example:**
```py
# 변수에 저장된 값 찍기
print('First name:', first_name)
print('First name length:', len(first_name))
print('Last name: ', last_name)
print('Last name length: ', len(last_name))
print('Country: ', country)
print('City: ', city)
print('Age: ', age)
print('Married: ', is_married)
print('Skills: ', skills)
print('Person information: ', person_info)
```
### 한 줄로 여러개의 변수 선언
하나의 줄에서 여러개의 변수를 선언할 수도 있습니다:
**Example:**
```py
first_name, last_name, country, age, is_married = 'Asabeneh', 'Yetayeh', 'Helsink', 250, True
print(first_name, last_name, country, age, is_married)
print('First name:', first_name)
print('Last name: ', last_name)
print('Country: ', country)
print('Age: ', age)
print('Married: ', is_married)
```
내장 함수 _input()_ 을 사용해 사용자의 입력 받기. 사용자로부터 받은 정보를 first_name과 age 변수에 할당해봅시다.
**Example:**
```py
first_name = input('What is your name: ')
age = input('How old are you? ')
print(first_name)
print(age)
```
## 자료형
파이썬에는 몇 가지 자료형이 있습니다. 자료형을 식별하기 위해 내장 함수 _type()_ 을 사용합니다. 서로 다른 자료형을 잘 이해하는 데 집중해 주시기를 부탁드립니다. 프로그래밍에서 모든것은 자료형과 관련이 있습니다. 처음에 자료형을 소개했지만 모든 주제가 자료형과 관련이 있기 때문에 다시 나옵니다. 자료형에 대해서는 각 섹션에서 자세히 설명하겠습니다.
## 자료형 확인 및 형변환
- 자료형 확인: 특정 정보/변수의 자료형을 확인하기위해 우리는 _type()_ 을 사용합니다
**Example:**
```py
# 다양한 파이썬 자료형
# 다양한 자료형의 변수들을 선언해 봅시다.
first_name = 'Asabeneh' # str
last_name = 'Yetayeh' # str
country = 'Finland' # str
city= 'Helsinki' # str
age = 250 # int, 제 실제 나이가 아닙니다, 걱정마세요
# Printing out types
print(type('Asabeneh')) # str
print(type(first_name)) # str
print(type(10)) # int
print(type(3.14)) # float
print(type(1 + 1j)) # complex
print(type(True)) # bool
print(type([1, 2, 3, 4])) # list
print(type({'name':'Asabeneh','age':250, 'is_married':250})) # dict
print(type((1,2))) # tuple
print(type(zip([1,2],[3,4]))) # set
```
- 형변환: 하나의 자료형을 다른 자료형으로 변환합니다. _int()_, _float()_, _str()_, _list_, _set_ 를 사용합니다.
산술 연산을 수행할 때 문자열 숫자들을 먼저 int 나 float로 변환해야 합니다. 그렇지 않으면 오류가 반환됩니다. 만약 숫자를 문자열과 결합한다면, 그 숫자는 먼저 문자열로 변환되어야 합니다. 결합에 대해서는 String 섹션에서 설명하겠습니다.
**Example:**
```py
# int to float
num_int = 10
print('num_int',num_int) # 10
num_float = float(num_int)
print('num_float:', num_float) # 10.0
# float to int
gravity = 9.81
print(int(gravity)) # 9
# int to str
num_int = 10
print(num_int) # 10
num_str = str(num_int)
print(num_str) # '10'
# str to int or float
num_str = '10.6'
print('num_int', int(num_str)) # 10
print('num_float', float(num_str)) # 10.6
# str to list
first_name = 'Asabeneh'
print(first_name) # 'Asabeneh'
first_name_to_list = list(first_name)
print(first_name_to_list) # ['A', 's', 'a', 'b', 'e', 'n', 'e', 'h']
```
## 숫자
파이썬의 숫자 자료형:
1. Integers: 정수(음수, 0 , 양수)
예:
... -3, -2, -1, 0, 1, 2, 3 ...
2. 부동 소수점 숫자(10진수)
예:
... -3.5, -2.25, -1.0, 0.0, 1.1, 2.2, 3.5 ...
3. 복소수
예:
1 + j, 2 + 4j, 1 - 1j
🌕 당신은 정말 멋집니다. 여러분은 이제 막 2일차 도전을 마쳤고 위대함으로 가는 길에 두 걸음 앞서 있습니다. 이제 여러분의 뇌와 근육을 위한 운동을 하세요.
## 💻 Exercises - Day 2
### Exercises: Level 1
1. 30DaysOfPython 내에 day_2라는 폴더를 생성하세요. 그 폴더 내에 variables.py 라는 파일을 생성하세요.
2. 'Day 2: 30 Days of python programming'이라는 파이썬 주석을 작성합니다.
3. first name 변수를 선언하고 변수에 값을 할당합니다.
4. last name 변수를 선언하고 변수에 값을 할당합니다.
5. full name 변수를 선언하고 변수에 값을 할당합니다.
6. country 변수를 선언하고 값을 할당합니다.
7. city 변수를 선언하고 값을 할당합니다.
8. age 변수를 선언하고 값을 할당합니다.
9. year 변수를 선언하고 값을 할당합니다.
10. is_married 변수를 선언하고 값을 할당합니다.
11. is_true 변수를 선언하고 값을 할당합니다.
12. is_light_on 변수를 선언하고 값을 할당합니다.
13. 한 줄에 여러개의 변수를 선언합니다.
### Exercises: Level 2
1. Check the data type of all your variables using type() built-in function
1. Using the _len()_ built-in function, find the length of your first name
1. Compare the length of your first name and your last name
1. Declare 5 as num_one and 4 as num_two
1. Add num_one and num_two and assign the value to a variable total
2. Subtract num_two from num_one and assign the value to a variable diff
3. Multiply num_two and num_one and assign the value to a variable product
4. Divide num_one by num_two and assign the value to a variable division
5. Use modulus division to find num_two divided by num_one and assign the value to a variable remainder
6. Calculate num_one to the power of num_two and assign the value to a variable exp
7. Find floor division of num_one by num_two and assign the value to a variable floor_division
1. The radius of a circle is 30 meters.
1. Calculate the area of a circle and assign the value to a variable name of _area_of_circle_
2. Calculate the circumference of a circle and assign the value to a variable name of _circum_of_circle_
3. Take radius as user input and calculate the area.
1. Use the built-in input function to get first name, last name, country and age from a user and store the value to their corresponding variable names
1. Run help('keywords') in Python shell or in your file to check for the Python reserved words or keywords
1. type() 내장 함수를 사용하여 모든 변수의 자료형을 확인합니다.
1. _len()_ 내장 함수를 사용하여 당신의 first name 의 길이를 찾습니다.
1. 당신의 first name 과 last name 의 길이를 비교합니다.
1. 5를 num_1로, 4를 num_2로 선언합니다.
1. num_one과 num_two를 더하고 그 값을 변수 total 에 할당합니다.
2. num_1에서 num_2를 빼고 그 값을 변수 diff 에 할당합니다.
3. num_two와 num_one을 곱하여 그 값을 변수 product 에 할당합니다.
4. num_one을 num_two로 나누고 그 값을 변수 division 에 할당합니다.
5. 나머지 연산을 사용하여 num_two를 num_one으로 나눈 값을 찾고 변수 remainder 에 할당합니다.
6. num_one을 num_two의 거듭제곱으로 계산하고 그 값을 변수 exp 에 할당합니다.
7. num_one을 num_two로 나누고 소숫값은 버린 정수 값을 구하고 변수 floor_division 에 값을 할당합니다.
1. 원의 반지름은 30미터입니다.
1. 원의 면적을 계산하여 _area_of_circle_ 이라는 이름의 변수에 값을 할당합니다.
2. 원의 둘레를 계산하여 _circum_of_circum_ 이라는 이름의 변수에 값을 할당합니다.
3. 반경을 사용자 입력으로 받아서 면적을 계산합니다.
1. 내장 함수 input을 사용하여 사용자로부터 이름, 성, 국가 및 나이를 얻고 해당 변수 이름에 값을 저장합니다.
1. Python 셸 또는 파일에서 help('keywords')을 실행하여 파이썬의 reserved words 또는 키워드를 확인합니다.
🎉 축하합니다 ! 🎉
[<< Day 1](../readme.md) | [Day 3 >>](../03_Day_Operators/03_operators.md)
================================================
FILE: Korean/04_strings_ko.md
================================================
[<< Day 3](../03_Day_Operators/03_operators.md) | [Day 5 >>](../05_Day_Lists/05_lists.md)

- [Day 4](#day-4)
- [문자열](#strings)
- [문자열 만들기](#문자열-만들기)
- [문자열 연결](#문자열-연결)
- [문자열의 이스케이프 시퀀스](#문자열의-이스케이프-시퀀스)
- [문자열 포매팅](#문자열-포매팅)
- [올드 스타일 문자열 포매팅(% 연산자)](#올드-스타일-문자열-포매팅%-연산자)
- [새로운 스타일 문자열 포매팅(str.format)](#새로운-스타일-문자열-포매팅str.format)
- [문자열 Interpolation / f-Strings (Python 3.6+)](#string-interpolation--f-strings-python-36)
- [문자 시퀀스로서의 Python 문자열](#문자-시퀀스로서의-Python-문자열)
- [언패킹 문자](#언패킹-문자)
- [인덱스로 문자열의 문자에 액세스](#인덱스로-문자열의-문자에-액세스)
- [파이썬 문자열 슬라이싱](#파이썬-문자열-슬라이싱)
- [문자열 리버스](#문자열-리버스)
- [슬라이싱하는 동안 문자 건너뛰기](#슬라이싱하는-동안-문자-건너뛰기)
- [문자열 메서드](#문자열-메서드)
- [💻 Exercises - Day 4](#-exercises---day-4)
# Day 4
## 문자열
텍스트는 문자열 데이터 유형입니다. 텍스트로 작성된 모든 데이터 유형은 문자열입니다. 작은따옴표, 큰따옴표 또는 삼중따옴표 아래의 모든 데이터는 문자열입니다. 문자열 데이터 유형을 처리하기 위한 다양한 문자열 메서드와 내장 함수가 있습니다. 문자열의 길이를 확인하려면 len() 메서드를 사용하십시오.
### 문자열 만들기
```py
letter = 'P' # A string could be a single character or a bunch of texts
print(letter) # P
print(len(letter)) # 1
greeting = 'Hello, World!' # String could be made using a single or double quote,"Hello, World!"
print(greeting) # Hello, World!
print(len(greeting)) # 13
sentence = "I hope you are enjoying 30 days of Python Challenge"
print(sentence)
```
여러 줄 문자열은 세 개의 작은따옴표(''') 또는 세 개의 큰따옴표(""")를 사용하여 생성됩니다. 아래 예를 참조하십시오.
```py
multiline_string = '''I am a teacher and enjoy teaching.
I didn't find anything as rewarding as empowering people.
That is why I created 30 days of python.'''
print(multiline_string)
# Another way of doing the same thing
multiline_string = """I am a teacher and enjoy teaching.
I didn't find anything as rewarding as empowering people.
That is why I created 30 days of python."""
print(multiline_string)
```
### 문자열 연결
문자열을 함께 연결할 수 있습니다. 문자열을 병합하거나 연결하는 것을 연결이라고 합니다. 아래 예를 참조하십시오.
```py
first_name = 'Asabeneh'
last_name = 'Yetayeh'
space = ' '
full_name = first_name + space + last_name
print(full_name) # Asabeneh Yetayeh
# Checking the length of a string using len() built-in function
print(len(first_name)) # 8
print(len(last_name)) # 7
print(len(first_name) > len(last_name)) # True
print(len(full_name)) # 16
```
### 문자열의 이스케이프 시퀀스
Python 및 기타 프로그래밍 언어에서 \ 다음에 오는 문자는 이스케이프 시퀀스입니다. 가장 일반적인 이스케이프 문자를 살펴보겠습니다.
- \n: 새로운 라인
- \t: 탭은(8칸)을 의미합니다.
- \\: 백슬래시
- \': 작은따옴표(')
- \": 큰따옴표(")
이제 위의 이스케이프 시퀀스를 예제와 함께 사용하는 방법을 살펴보겠습니다.
```py
print('I hope everyone is enjoying the Python Challenge.\nAre you ?') # line break
print('Days\tTopics\tExercises') # adding tab space or 4 spaces
print('Day 1\t3\t5')
print('Day 2\t3\t5')
print('Day 3\t3\t5')
print('Day 4\t3\t5')
print('This is a backslash symbol (\\)') # To write a backslash
print('In every programming language it starts with \"Hello, World!\"') # to write a double quote inside a single quote
# output
I hope every one is enjoying the Python Challenge.
Are you ?
Days Topics Exercises
Day 1 5 5
Day 2 6 20
Day 3 5 23
Day 4 1 35
This is a backslash symbol (\)
In every programming language it starts with "Hello, World!"
```
### 문자열 포매팅
#### 올드 스타일 문자열 형식화(% 연산자)
Python에는 문자열 형식을 지정하는 여러 가지 방법이 있습니다. 이 섹션에서는 그 중 일부를 다룰 것입니다. "%" 연산자는 "인수 지정자", "%s"와 같은 특수 기호와 함께 일반 텍스트를 포함하는 형식 문자열과 함께 "튜플"(고정 크기 목록)로 묶인 변수 세트의 형식을 지정하는 데 사용됩니다. , "%d", "%f", "%. 자릿수 f".
- %s - 문자열(또는 숫자와 같은 문자열 표현이 있는 모든 객체)
- %d - 정수
- %f - 부동 소수점 숫자
- "%. number of digits f" - 정밀도가 고정된 부동 소수점 숫자
```py
# Strings only
first_name = 'Asabeneh'
last_name = 'Yetayeh'
language = 'Python'
formated_string = 'I am %s %s. I teach %s' %(first_name, last_name, language)
print(formated_string)
# Strings and numbers
radius = 10
pi = 3.14
area = pi * radius ** 2
formated_string = 'The area of circle with a radius %d is %.2f.' %(radius, area) # 2 refers the 2 significant digits after the point
python_libraries = ['Django', 'Flask', 'NumPy', 'Matplotlib','Pandas']
formated_string = 'The following are python libraries:%s' % (python_libraries)
print(formated_string) # "The following are python libraries:['Django', 'Flask', 'NumPy', 'Matplotlib','Pandas']"
```
#### 새로운스타일 문자열 형식화(str.format)
이 형식은 Python 버전 3에서 도입되었습니다.
```py
first_name = 'Asabeneh'
last_name = 'Yetayeh'
language = 'Python'
formated_string = 'I am {} {}. I teach {}'.format(first_name, last_name, language)
print(formated_string)
a = 4
b = 3
print('{} + {} = {}'.format(a, b, a + b))
print('{} - {} = {}'.format(a, b, a - b))
print('{} * {} = {}'.format(a, b, a * b))
print('{} / {} = {:.2f}'.format(a, b, a / b)) # limits it to two digits after decimal
print('{} % {} = {}'.format(a, b, a % b))
print('{} // {} = {}'.format(a, b, a // b))
print('{} ** {} = {}'.format(a, b, a ** b))
# output
4 + 3 = 7
4 - 3 = 1
4 * 3 = 12
4 / 3 = 1.33
4 % 3 = 1
4 // 3 = 1
4 ** 3 = 64
# Strings and numbers
radius = 10
pi = 3.14
area = pi * radius ** 2
formated_string = 'The area of a circle with a radius {} is {:.2f}.'.format(radius, area) # 2 digits after decimal
print(formated_string)
```
#### 문자열 Interpolation / f-Strings (Python 3.6+)
또 다른 새로운 문자열 형식화는 문자열 보간법인 f-문자열입니다. 문자열은 f로 시작하고 해당 위치에 데이터를 주입할 수 있습니다.
```py
a = 4
b = 3
print(f'{a} + {b} = {a +b}')
print(f'{a} - {b} = {a - b}')
print(f'{a} * {b} = {a * b}')
print(f'{a} / {b} = {a / b:.2f}')
print(f'{a} % {b} = {a % b}')
print(f'{a} // {b} = {a // b}')
print(f'{a} ** {b} = {a ** b}')
```
### 문자 시퀀스로서의 Python 문자열
Python 문자열은 문자 시퀀스이며, 기본 액세스 방법을 다른 Python 순서 객체 시퀀스(목록 및 튜플)와 공유합니다. 문자열(및 모든 시퀀스의 개별 멤버)에서 단일 문자를 추출하는 가장 간단한 방법은 해당 변수로 압축을 푸는 것입니다.
#### 언패킹 문자
```
language = 'Python'
a,b,c,d,e,f = language # unpacking sequence characters into variables
print(a) # P
print(b) # y
print(c) # t
print(d) # h
print(e) # o
print(f) # n
```
#### 인덱스로 문자열의 문자에 액세스
프로그래밍에서 카운팅은 0부터 시작합니다. 따라서 문자열의 첫 번째 문자는 인덱스가 0이고 문자열의 마지막 문자는 문자열의 길이에서 1을 뺀 값입니다.

```py
language = 'Python'
first_letter = language[0]
print(first_letter) # P
second_letter = language[1]
print(second_letter) # y
last_index = len(language) - 1
last_letter = language[last_index]
print(last_letter) # n
```
오른쪽 끝에서 시작하려면 음수 인덱싱을 사용할 수 있습니다. -1은 마지막 인덱스입니다.
```py
language = 'Python'
last_letter = language[-1]
print(last_letter) # n
second_last = language[-2]
print(second_last) # o
```
#### 파이썬 문자열 슬라이싱
파이썬에서는 문자열을 하위 문자열로 슬라이스할 수 있습니다.
```py
language = 'Python'
first_three = language[0:3] # starts at zero index and up to 3 but not include 3
print(first_three) #Pyt
last_three = language[3:6]
print(last_three) # hon
# Another way
last_three = language[-3:]
print(last_three) # hon
last_three = language[3:]
print(last_three) # hon
```
#### 문자열 리버스
파이썬에서 문자열을 쉽게 뒤집을 수 있습니다.
```py
greeting = 'Hello, World!'
print(greeting[::-1]) # !dlroW ,olleH
```
#### 슬라이싱하는 동안 문자 건너뛰기
슬라이스 메소드에 단계 인수를 전달하여 슬라이스하는 동안 문자를 건너뛸 수 있습니다.
```py
language = 'Python'
pto = language[0:6:2] #
print(pto) # Pto
```
### 문자열 메서드
문자열을 형식화할 수 있는 많은 문자열 메서드가 있습니다. 다음 예제에서 일부 문자열 메서드를 참조하십시오.
- capitalize(): 문자열의 첫 번째 문자를 대문자로 변환
```py
challenge = 'thirty days of python'
print(challenge.capitalize()) # 'Thirty days of python'
```
- count(): 문자열에서 하위 문자열의 발생을 반환합니다. count(substring, start=.., end=..). 시작은 카운트를 위한 시작 인덱싱이고 끝은 카운트할 마지막 인덱스입니다.
```py
challenge = 'thirty days of python'
print(challenge.count('y')) # 3
print(challenge.count('y', 7, 14)) # 1,
print(challenge.count('th')) # 2`
```
- endswith(): 문자열이 지정된 끝으로 끝나는지 확인합니다.
```py
challenge = 'thirty days of python'
print(challenge.endswith('on')) # True
print(challenge.endswith('tion')) # False
```
- expandtabs(): 탭 문자를 공백으로 바꿉니다. 기본 탭 크기는 8입니다. 탭 크기 인수를 사용합니다.
```py
challenge = 'thirty\tdays\tof\tpython'
print(challenge.expandtabs()) # 'thirty days of python'
print(challenge.expandtabs(10)) # 'thirty days of python'
```
- find(): 하위 문자열이 처음 나타나는 인덱스를 반환합니다. 찾을 수 없으면 -1을 반환합니다.
```py
challenge = 'thirty days of python'
print(challenge.count('y')) # 3
print(challenge.count('y', 7, 14)) # 1,
print(challenge.count('th')) # 2`
```
- rfind(): 하위 문자열이 마지막으로 나타나는 인덱스를 반환합니다. 찾을 수 없으면 -1을 반환합니다.
```py
challenge = 'thirty days of python'
print(challenge.rfind('y')) # 5
print(challenge.rfind('th')) # 1
```
- format(): 문자열을 더 나은 출력으로 포맷합니다. 문자열 형식에 대한 자세한 내용은 이 [링크](https://www.programiz.com/python-programming/methods/string/format) 를 확인하세요.
```py
first_name = 'Asabeneh'
last_name = 'Yetayeh'
age = 250
job = 'teacher'
country = 'Finland'
sentence = 'I am {} {}. I am a {}. I am {} years old. I live in {}.'.format(first_name, last_name, age, job, country)
print(sentence) # I am Asabeneh Yetayeh. I am 250 years old. I am a teacher. I live in Finland.
radius = 10
pi = 3.14
area = pi * radius ** 2
result = 'The area of a circle with radius {} is {}'.format(str(radius), str(area))
print(result) # The area of a circle with radius 10 is 314
```
- index(): 하위 문자열의 가장 낮은 색인을 반환하고 추가 인수는 시작 및 끝 색인을 나타냅니다(기본값 0 및 문자열 길이 - 1). 하위 문자열을 찾을 수 없으면 valueError가 발생합니다.
```py
challenge = 'thirty days of python'
sub_string = 'da'
print(challenge.index(sub_string)) # 7
print(challenge.index(sub_string, 9)) # error
```
- rindex(): 하위 문자열의 가장 높은 색인을 반환합니다. 추가 인수는 시작 및 끝 색인을 나타냅니다(기본값 0 및 문자열 길이 - 1).
```py
challenge = 'thirty days of python'
sub_string = 'da'
print(challenge.rindex(sub_string)) # 8
print(challenge.rindex(sub_string, 9)) # error
```
- isalnum(): 영숫자 확인
```py
challenge = 'ThirtyDaysPython'
print(challenge.isalnum()) # True
challenge = '30DaysPython'
print(challenge.isalnum()) # True
challenge = 'thirty days of python'
print(challenge.isalnum()) # False, space is not an alphanumeric character
challenge = 'thirty days of python 2019'
print(challenge.isalnum()) # False
```
- isalpha(): 모든 문자열 요소가 알파벳 문자(az 및 AZ)인지 확인합니다.
```py
challenge = 'thirty days of python'
print(challenge.isalpha()) # False, space is once again excluded
challenge = 'ThirtyDaysPython'
print(challenge.isalpha()) # True
num = '123'
print(num.isalpha()) # False
```
- isdecimal(): 문자열의 모든 문자가 십진수(0-9)인지 확인합니다.
```py
challenge = 'thirty days of python'
print(challenge.isdecimal()) # False
challenge = '123'
print(challenge.isdecimal()) # True
challenge = '\u00B2'
print(challenge.isdigit()) # False
challenge = '12 3'
print(challenge.isdecimal()) # False, space not allowed
```
- isdigit(): 문자열의 모든 문자가 숫자인지 확인합니다(숫자는 0-9 및 일부 다른 유니코드 문자).
```py
challenge = 'Thirty'
print(challenge.isdigit()) # False
challenge = '30'
print(challenge.isdigit()) # True
challenge = '\u00B2'
print(challenge.isdigit()) # True
```
- isnumeric(): 문자열의 모든 문자가 숫자인지 또는 숫자와 관련된 것인지 확인합니다(isdigit()와 마찬가지로 ½과 같은 더 많은 기호를 허용합니다).
```py
num = '10'
print(num.isnumeric()) # True
num = '\u00BD' # ½
print(num.isnumeric()) # True
num = '10.5'
print(num.isnumeric()) # False
```
- isidentifier(): 유효한 식별자를 확인합니다. 문자열이 유효한 변수 이름인지 확인합니다.
```py
challenge = '30DaysOfPython'
print(challenge.isidentifier()) # False, because it starts with a number
challenge = 'thirty_days_of_python'
print(challenge.isidentifier()) # True
```
- islower(): 문자열의 모든 알파벳 문자가 소문자인지 확인
```py
challenge = 'thirty days of python'
print(challenge.islower()) # True
challenge = 'Thirty days of python'
print(challenge.islower()) # False
```
- islower(): 문자열의 모든 알파벳 문자가 소문자인지 확인
```py
challenge = 'thirty days of python'
print(challenge.isupper()) # False
challenge = 'THIRTY DAYS OF PYTHON'
print(challenge.isupper()) # True
```
- join(): 연결된 문자열을 반환합니다.
```py
web_tech = ['HTML', 'CSS', 'JavaScript', 'React']
result = ' '.join(web_tech)
print(result) # 'HTML CSS JavaScript React'
```
```py
web_tech = ['HTML', 'CSS', 'JavaScript', 'React']
result = '# '.join(web_tech)
print(result) # 'HTML# CSS# JavaScript# React'
```
- strip(): 문자열의 시작과 끝에서 시작하여 주어진 모든 문자를 제거합니다.
```py
challenge = 'thirty days of pythoonnn'
print(challenge.strip('noth')) # 'irty days of py'
```
- replace(): 하위 문자열을 주어진 문자열로 대체합니다.
```py
challenge = 'thirty days of python'
print(challenge.replace('python', 'coding')) # 'thirty days of coding'
```
- split(): 주어진 문자열 또는 공백을 구분 기호로 사용하여 문자열을 분할합니다.
```py
challenge = 'thirty days of python'
print(challenge.split()) # ['thirty', 'days', 'of', 'python']
challenge = 'thirty, days, of, python'
print(challenge.split(', ')) # ['thirty', 'days', 'of', 'python']
```
- title(): 제목 케이스 문자열을 반환합니다.
```py
challenge = 'thirty days of python'
print(challenge.title()) # Thirty Days Of Python
```
- swapcase(): 모든 대문자를 소문자로, 모든 소문자를 대문자로 변환
```py
challenge = 'thirty days of python'
print(challenge.swapcase()) # THIRTY DAYS OF PYTHON
challenge = 'Thirty Days Of Python'
print(challenge.swapcase()) # tHIRTY dAYS oF pYTHON
```
- startswith(): 문자열이 지정된 문자열로 시작하는지 확인
```py
challenge = 'thirty days of python'
print(challenge.startswith('thirty')) # True
challenge = '30 days of python'
print(challenge.startswith('thirty')) # False
```
🌕 당신은 특별한 사람이고 놀라운 잠재력을 가지고 있습니다. 당신은 방금 4일 차 도전을 완료했고 당신은 위대함을 향한 당신의 길에 4걸음 남았습니다. 이제 뇌와 근육을 위한 몇 가지 훈련을 하십시오.
## 💻 Exercises - Day 4
1. 문자열 'Thirty', 'Days', 'Of', 'Python'을 단일 문자열 'Thirty Days Of Python'에 연결합니다.
2. 문자열 'Coding', 'For' , 'All'을 단일 문자열 'Coding For All'에 연결합니다.
3. company라는 변수를 선언하고 초기 값 "Coding For All"에 할당합니다.
4. *print()* 를 사용하여 회사 변수를 인쇄합니다.
5. *len()* 메서드와 *print()* 를 사용하여 회사 문자열의 길이를 인쇄합니다.
6. *upper()* 메서드를 사용하여 모든 문자를 대문자로 변경합니다.
7. *lower()* 메서드를 사용하여 모든 문자를 소문자로 변경합니다.
8. 문자열 *Coding For All* 의 값을 형식화하려면 capitalize(), title(), swapcase() 메소드를 사용하십시오.
9. *Coding For All* 문자열의 첫 번째 단어를 잘라냅니다.
10. Index, find 또는 기타 방법을 사용하여 *Coding For All* 문자열에 단어 Coding이 포함되어 있는지 확인합니다.
11. 문자열 'Coding For All'의 코딩이라는 단어를 Python으로 바꿉니다.
12. replace 메서드 또는 기타 메서드를 사용하여 모두를 위한 Python을 모두를 위한 Python으로 변경합니다.
13. 공백을 구분 기호로 사용하여 문자열 'Coding For All'을 분할합니다(split()).
14. "Facebook, Google, Microsoft, Apple, IBM, Oracle, Amazon"은 쉼표에서 문자열을 나눕니다.
15. 문자열 *Coding For All* 에서 인덱스 0에 있는 문자는 무엇입니까?
16. 문자열 *Coding For All* 에서 인덱스 0에 있는 문자는 무엇입니까?
17. "Coding For All" 문자열에서 인덱스 10에 있는 문자는 무엇입니까?
18. 'Python For Everyone'이라는 이름의 약어 또는 약어를 만듭니다.
19. 'Coding For All'이라는 이름의 약어 또는 약어를 만듭니다.
20. Index를 사용하여 Coding For All에서 C가 처음 나타나는 위치를 결정합니다.
21. Index를 사용하여 Coding For All에서 F가 처음 나타나는 위치를 결정합니다.
22. Coding For All People에서 l이 마지막으로 나타나는 위치를 결정하려면 rfind를 사용하십시오.
23. 색인 또는 찾기를 사용하여 다음 문장에서 'because'라는 단어가 처음 나타나는 위치를 찾습니다.
24. 색인 또는 찾기를 사용하여 다음 문장에서 'because'라는 단어가 처음 나타나는 위치를 찾습니다.
25. 색인 또는 찾기를 사용하여 다음 문장에서 'because'라는 단어가 처음 나타나는 위치를 찾습니다.
26. 색인 또는 찾기를 사용하여 다음 문장에서 'because'라는 단어가 처음 나타나는 위치를 찾습니다.
27. 다음 문장에서 'because because because'라는 구문을 잘라냅니다.
28. 'Coding For All'은 하위 문자열 *Coding* 으로 시작합니까?
29. 'Coding For All'은 하위 문자열 *코딩* 으로 끝납니까?
30. ' Coding For All ' , 주어진 문자열에서 왼쪽 및 오른쪽 후행 공백을 제거합니다.
31. 다음 변수 중 isidentifier() 메서드를 사용할 때 True를 반환하는 변수는 무엇입니까?
- 30DaysOfPython
- thirty_days_of_python
32. 다음 목록에는 일부 파이썬 라이브러리의 이름이 포함되어 있습니다: ['Django', 'Flask', 'Bottle', 'Pyramid', 'Falcon']. 공백 문자열이 있는 해시로 목록에 가입하십시오.
33. 새 줄 이스케이프 시퀀스를 사용하여 다음 문장을 구분합니다.
```py
I am enjoying this challenge.
I just wonder what is next.
```
34. 새 줄 이스케이프 시퀀스를 사용하여 다음 문장을 구분합니다.
```py
Name Age Country City
Asabeneh 250 Finland Helsinki
```
35. 문자열 형식 지정 방법을 사용하여 다음을 표시합니다:
```sh
radius = 10
area = 3.14 * radius ** 2
The area of a circle with radius 10 is 314 meters square.
```
1. 문자열 형식화 방법을 사용하여 다음을 작성하십시오:
```sh
8 + 6 = 14
8 - 6 = 2
8 * 6 = 48
8 / 6 = 1.33
8 % 6 = 2
8 // 6 = 1
8 ** 6 = 262144
```
🎉 축하합니다! 🎉
[<< Day 3](../03_Day_Operators/03_operators.md) | [Day 5 >>](../05_Day_Lists/05_lists.md)
================================================
FILE: Korean/05_Day_Lists/05_lists.md
================================================
[<< Day 4](../04_Day_Strings/04_strings.md) | [Day 6 >>](../06_Day_Tuples/06_tuples.md)

- [Day 5](#day-5)
- [Lists](#lists)
- [How to Create a List](#how-to-create-a-list)
- [Accessing List Items Using Positive Indexing](#accessing-list-items-using-positive-indexing)
- [Accessing List Items Using Negative Indexing](#accessing-list-items-using-negative-indexing)
- [Unpacking List Items](#unpacking-list-items)
- [Slicing Items from a List](#slicing-items-from-a-list)
- [Modifying Lists](#modifying-lists)
- [Checking Items in a List](#checking-items-in-a-list)
- [Adding Items to a List](#adding-items-to-a-list)
- [Inserting Items into a List](#inserting-items-into-a-list)
- [Removing Items from a List](#removing-items-from-a-list)
- [Removing Items Using Pop](#removing-items-using-pop)
- [Removing Items Using Del](#removing-items-using-del)
- [Clearing List Items](#clearing-list-items)
- [Copying a List](#copying-a-list)
- [Joining Lists](#joining-lists)
- [Counting Items in a List](#counting-items-in-a-list)
- [Finding Index of an Item](#finding-index-of-an-item)
- [Reversing a List](#reversing-a-list)
- [Sorting List Items](#sorting-list-items)
- [💻 Exercises: Day 5](#-exercises-day-5)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
# Day 5
## Lists
파이썬에는 네 가지 컬렉션 자료형이 있습니다.
- List: 정렬되고 변경 가능(수정 가능)한 컬렉션입니다. 중복 값을 허용합니다.
- Tuple: 정렬되고 변경 불가능하거나 수정 불가능한(불변) 컬렉션입니다. 중복 값을 허용합니다.
- Set: 순서가 지정되지 않고 인덱스가 없고 수정할 수 없는 컬렉션이지만 새 아이템을 추가할 수 있습니다. 중복 값은 허용되지 않습니다.
- Dictionary: 정렬되지 않고 변경 가능(수정 가능)하며 인덱스가 있는 컬렉션입니다. 중복 값이 없습니다.
리스트는 정렬되고 수정(변경) 가능한 다양한 자료형의 컬렉션입니다. 목록은 비어 있거나 다른 자료형 아이템을 가질 수 있습니다.
### How to Create a List
파이썬에서 리스트는 두가지 방법으로 생성할 수 있습니다:
- list 내장 함수를 사용
```py
# syntax
lst = list()
```
```py
empty_list = list() # 이건 빈 리스트 입니다, 리스트 안에 아무 값도 없습니다
print(len(empty_list)) # 0
```
- 대괄호 사용, []
```py
# syntax
lst = []
```
```py
empty_list = [] # 이건 빈 리스트 입니다, 리스트 안에 아무 값도 없습니다
print(len(empty_list)) # 0
```
초기 값이 있는 리스트입니다. _len()_ 을 사용하여 리스트의 길이를 찾습니다.
```py
fruits = ['banana', 'orange', 'mango', 'lemon'] # list of fruits
vegetables = ['Tomato', 'Potato', 'Cabbage','Onion', 'Carrot'] # list of vegetables
animal_products = ['milk', 'meat', 'butter', 'yoghurt'] # list of animal products
web_techs = ['HTML', 'CSS', 'JS', 'React','Redux', 'Node', 'MongDB'] # list of web technologies
countries = ['Finland', 'Estonia', 'Denmark', 'Sweden', 'Norway']
# Print the lists and its length
print('Fruits:', fruits)
print('Number of fruits:', len(fruits))
print('Vegetables:', vegetables)
print('Number of vegetables:', len(vegetables))
print('Animal products:',animal_products)
print('Number of animal products:', len(animal_products))
print('Web technologies:', web_techs)
print('Number of web technologies:', len(web_techs))
print('Countries:', countries)
print('Number of countries:', len(countries))
```
```sh
output
Fruits: ['banana', 'orange', 'mango', 'lemon']
Number of fruits: 4
Vegetables: ['Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
Number of vegetables: 5
Animal products: ['milk', 'meat', 'butter', 'yoghurt']
Number of animal products: 4
Web technologies: ['HTML', 'CSS', 'JS', 'React', 'Redux', 'Node', 'MongDB']
Number of web technologies: 7
Countries: ['Finland', 'Estonia', 'Denmark', 'Sweden', 'Norway']
Number of countries: 5
```
- 리스트는 서로 다른 자료형의 아이템을 가질 수 있습니다.
```py
lst = ['Asabeneh', 250, True, {'country':'Finland', 'city':'Helsinki'}] # 다른 자료형을 가진 리스트
```
### Accessing List Items Using Positive Indexing
인덱스를 사용하여 리스트의 각 아이템에 액세스합니다. 리스트 인덱스는 0부터 시작합니다. 아래 그림은 인덱스가 시작되는 위치를 명확하게 보여줍니다.

```py
fruits = ['banana', 'orange', 'mango', 'lemon']
first_fruit = fruits[0] # 인덱스를 사용해 첫번째 아이템에 접근합니다
print(first_fruit) # banana
second_fruit = fruits[1]
print(second_fruit) # orange
last_fruit = fruits[3]
print(last_fruit) # lemon
# Last index
last_index = len(fruits) - 1
last_fruit = fruits[last_index]
```
### Accessing List Items Using Negative Indexing
음수 인덱스는 끝에서 시작하는 것을 의미하며 -1은 마지막 아이템을, -2는 마지막에서 두번쨰 아이템을 의미합니다.

```py
fruits = ['banana', 'orange', 'mango', 'lemon']
first_fruit = fruits[-4]
last_fruit = fruits[-1]
second_last = fruits[-2]
print(first_fruit) # banana
print(last_fruit) # lemon
print(second_last) # mango
```
### Unpacking List Items
```py
lst = ['item','item2','item3', 'item4', 'item5']
first_item, second_item, third_item, *rest = lst
print(first_item) # item1
print(second_item) # item2
print(third_item) # item3
print(rest) # ['item4', 'item5']
```
```py
# First Example
fruits = ['banana', 'orange', 'mango', 'lemon','lime','apple']
first_fruit, second_fruit, third_fruit, *rest = lst
print(first_fruit) # banana
print(second_fruit) # orange
print(third_fruit) # mango
print(rest) # ['lemon','lime','apple']
# Second Example about unpacking list
first, second, third,*rest, tenth = [1,2,3,4,5,6,7,8,9,10]
print(first) # 1
print(second) # 2
print(third) # 3
print(rest) # [4,5,6,7,8,9]
print(tenth) # 10
# Third Example about unpacking list
countries = ['Germany', 'France','Belgium','Sweden','Denmark','Finland','Norway','Iceland','Estonia']
gr, fr, bg, sw, *scandic, es = countries
print(gr)
print(fr)
print(bg)
print(sw)
print(scandic)
print(es)
```
### Slicing Items from a List
- 양수 인덱싱: start, end 및 step을 지정하여 양수 인덱스 범위를 지정할 수 있습니다. 반환 값은 새 리스트가 됩니다. (start의 디폴트값 = 0, end = len(lst) - 1 (마지막 아이템), step = 1)
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
all_fruits = fruits[0:4] # 모든 fruits를 반환합니다
# 이것또한 위와 같은 값을 반환합니다
all_fruits = fruits[0:] # 우리가 어디서 멈출 지 설정하지 않으면, 모든 것을 포함합니다
orange_and_mango = fruits[1:3] # 첫번째 인덱스를 포함하지 않습니다
orange_mango_lemon = fruits[1:]
orange_and_lemon = fruits[::2] # 여기서 세번째 인자인 step을 사용했습니다. 모든 두번째 아이템을 포함합니다 - ['banana', 'mango']
```
- 음수 인덱싱: start, end 및 step을 지정하여 음수 인덱스의 범위를 지정할 수 있습니다. 반환 값은 새 리스트가 됩니다.
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
all_fruits = fruits[-4:] # 모든 fruits를 반환합니다
orange_and_mango = fruits[-3:-1] # 마지막 인덱스를 포함하지 않습니다,['orange', 'mango']
orange_mango_lemon = fruits[-3:] # 이것은 -3 부터 시작하여 끝까지의 값을 줍니다,['orange', 'mango', 'lemon']
reverse_fruits = fruits[::-1] # 음수의 step은 리스트를 역순으로 가집니다,['lemon', 'mango', 'orange', 'banana']
```
### Modifying Lists
리스트는 변경 가능하거나 수정 가능한 순서가 있는 아이템들의 컬렉션입니다. 과일 리스트를 수정해봅시다.
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits[0] = 'avocado'
print(fruits) # ['avocado', 'orange', 'mango', 'lemon']
fruits[1] = 'apple'
print(fruits) # ['avocado', 'apple', 'mango', 'lemon']
last_index = len(fruits) - 1
fruits[last_index] = 'lime'
print(fruits) # ['avocado', 'apple', 'mango', 'lime']
```
### Checking Items in a List
*in* 연산자를 사용하여 아이템이 리스트의 구성원인지 확인합니다. 아래 예시를 봅시다.
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
does_exist = 'banana' in fruits
print(does_exist) # True
does_exist = 'lime' in fruits
print(does_exist) # False
```
### Adding Items to a List
기존 리스트의 끝에 아이템을 추가하려면 *append()* 메서드를 사용합니다.
```py
# syntax
lst = list()
lst.append(item)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.append('apple')
print(fruits) # ['banana', 'orange', 'mango', 'lemon', 'apple']
fruits.append('lime') # ['banana', 'orange', 'mango', 'lemon', 'apple', 'lime']
print(fruits)
```
### Inserting Items into a List
*insert()* 메서드를 사용하여 목록의 지정된 인덱스에 하나의 아이템을 삽입할 수 있습니다. 다른 아이템들은 오른쪽으로 이동한다는 것에 주의합시다. *insert()* 메서드는 인덱스와 삽입할 아이템이라는 두 가지 인자를 가집니다.
```py
# syntax
lst = ['item1', 'item2']
lst.insert(index, item)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.insert(2, 'apple') # orange와 mango 사이에 apple을 삽입
print(fruits) # ['banana', 'orange', 'apple', 'mango', 'lemon']
fruits.insert(3, 'lime') # ['banana', 'orange', 'apple', 'lime', 'mango', 'lemon']
print(fruits)
```
### Removing Items from a List
remove 메서드는 리스트에서 지정된 아이템을 삭제합니다.
```py
# syntax
lst = ['item1', 'item2']
lst.remove(item)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon', 'banana']
fruits.remove('banana')
print(fruits) # ['orange', 'mango', 'lemon', 'banana'] - 이 메서드는 리스트에서 첫번째로 존재하는 아이템을 삭제합니다
fruits.remove('lemon')
print(fruits) # ['orange', 'mango', 'banana']
```
### Removing Items Using Pop
*pop()* 메서드는 지정된 인덱스를 제거합니다(또는 인덱스가 지정되지 않은 경우 마지막 아이템):
```py
# syntax
lst = ['item1', 'item2']
lst.pop() # 마지막 아이템
lst.pop(index)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.pop()
print(fruits) # ['banana', 'orange', 'mango']
fruits.pop(0)
print(fruits) # ['orange', 'mango']
```
### Removing Items Using Del
*del* 키워드는 지정된 인덱스를 삭제하며 인덱스 범위 내의 아이템을 삭제하는 데도 사용할 수 있습니다. 또한 리스트를 완전히 삭제할 수도 있습니다.
```py
# syntax
lst = ['item1', 'item2']
del lst[index] # 하니의 아이템
del lst # 리스트를 완전히 삭제
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon', 'kiwi', 'lime']
del fruits[0]
print(fruits) # ['orange', 'mango', 'lemon', 'kiwi', 'lime']
del fruits[1]
print(fruits) # ['orange', 'lemon', 'kiwi', 'lime']
del fruits[1:3] # 이것은 주어진 인덱스 사이의 아이템을 삭제합니다, 그러므로 인덱스가 3인 아이템은 삭제되지 않습니다!
print(fruits) # ['orange', 'lime']
del fruits
print(fruits) # NameError: name 'fruits' is not defined 가 발생해야합니다
```
### Clearing List Items
*clear()* 메서드를 사용해 리스트 비우기:
```py
# syntax
lst = ['item1', 'item2']
lst.clear()
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.clear()
print(fruits) # []
```
### Copying a List
다음의 방법으로 새 변수에 재할당하여 리스트를 복사할 수 있습니다:list2 = list1. 이제 list2는 list1의 참조이며, list2에서 변경한 내용은 원본 list1도 수정합니다. 하지만 원본을 수정하고 싶지 않고 다른 사본을 갖고 싶어하는 경우가 많습니다. 위의 문제를 피하는 한 가지 방법은 _copy()_ 를 사용하는 것입니다.
```py
# syntax
lst = ['item1', 'item2']
lst_copy = lst.copy()
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits_copy = fruits.copy()
print(fruits_copy) # ['banana', 'orange', 'mango', 'lemon']
```
### Joining Lists
파이썬에서 두 개 이상의 목록을 결합하거나 연결하는 방법은 여러 가지가 있습니다.
- 플러스 연산자 (+)
```py
# syntax
list3 = list1 + list2
```
```py
positive_numbers = [1, 2, 3, 4, 5]
zero = [0]
negative_numbers = [-5,-4,-3,-2,-1]
integers = negative_numbers + zero + positive_numbers
print(integers) # [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
fruits = ['banana', 'orange', 'mango', 'lemon']
vegetables = ['Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
fruits_and_vegetables = fruits + vegetables
print(fruits_and_vegetables ) # ['banana', 'orange', 'mango', 'lemon', 'Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
```
- extend() 메서드를 사용하여 연결
*extend()* 메서드를 사용하면 리스트에 리스트를 추가할 수 있습니다. 아래 예를 참조합시다.
```py
# syntax
list1 = ['item1', 'item2']
list2 = ['item3', 'item4', 'item5']
list1.extend(list2)
```
```py
num1 = [0, 1, 2, 3]
num2= [4, 5, 6]
num1.extend(num2)
print('Numbers:', num1) # Numbers: [0, 1, 2, 3, 4, 5, 6]
negative_numbers = [-5,-4,-3,-2,-1]
positive_numbers = [1, 2, 3,4,5]
zero = [0]
negative_numbers.extend(zero)
negative_numbers.extend(positive_numbers)
print('Integers:', negative_numbers) # Integers: [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
fruits = ['banana', 'orange', 'mango', 'lemon']
vegetables = ['Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
fruits.extend(vegetables)
print('Fruits and vegetables:', fruits ) # Fruits and vegetables: ['banana', 'orange', 'mango', 'lemon', 'Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
```
### Counting Items in a List
*count()* 메서드는 리스트에 아이템이 나타나는 횟수를 반환합니다:
```py
# syntax
lst = ['item1', 'item2']
lst.count(item)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
print(fruits.count('orange')) # 1
ages = [22, 19, 24, 25, 26, 24, 25, 24]
print(ages.count(24)) # 3
```
### Finding Index of an Item
*index()* 메서드는 리스트에 있는 아이템의 인덱스를 반환합니다:
```py
# syntax
lst = ['item1', 'item2']
lst.index(item)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
print(fruits.index('orange')) # 1
ages = [22, 19, 24, 25, 26, 24, 25, 24]
print(ages.index(24)) # 2, 처음 만난 것
```
### Reversing a List
*reverse()* 메서드는 리스트의 순서를 거꾸로 합니다.
```py
# syntax
lst = ['item1', 'item2']
lst.reverse()
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.reverse()
print(fruits) # ['lemon', 'mango', 'orange', 'banana']
ages = [22, 19, 24, 25, 26, 24, 25, 24]
ages.reverse()
print(ages) # [24, 25, 24, 26, 25, 24, 19, 22]
```
### Sorting List Items
리스트를 정렬하려면 _sort()_ 메서드 또는 _sorted()_ 내장 함수를 사용할 수 있습니다. _sort()_ 메서드는 리스트 아이템을 오름차순으로 정렬하고 원래 리스트를 수정합니다. 만약 _sort()_ 메서드의 reverse의 인자가 true라면, 그것은 목록을 내림차순으로 배열할 것입니다.
- sort(): 이 메서드는 원래 리스트를 수정합니다
```py
# syntax
lst = ['item1', 'item2']
lst.sort() # 오름차순
lst.sort(reverse=True) # 내림차순
```
**Example:**
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.sort()
print(fruits) # 알파벳순으로 정렬, ['banana', 'lemon', 'mango', 'orange']
fruits.sort(reverse=True)
print(fruits) # ['orange', 'mango', 'lemon', 'banana']
ages = [22, 19, 24, 25, 26, 24, 25, 24]
ages.sort()
print(ages) # [19, 22, 24, 24, 24, 25, 25, 26]
ages.sort(reverse=True)
print(ages) # [26, 25, 25, 24, 24, 24, 22, 19]
```
sorted(): 원래 리스트를 수정하지 않고 정렬된 리스트를 반환합니다
**Example:**
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
print(sorted(fruits)) # ['banana', 'lemon', 'mango', 'orange']
# 역순
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits = sorted(fruits,reverse=True)
print(fruits) # ['orange', 'mango', 'lemon', 'banana']
```
🌕 당신은 성실하고 이미 많은 것을 성취했습니다. 여러분은 이제 막 5일차 도전을 마쳤고 위대함을 향한 5걸음 앞에 있습니다. 이제 여러분의 뇌와 근육을 위한 운동을 하세요.
## 💻 Exercises: Day 5
### Exercises: Level 1
1. 빈 리스트를 선언합니다
2. 5개 이상의 아이템을 갖는 리스트를 선언합니다
3. 당신의 리스트의 길이를 알아봅니다
4. 리스트의 첫번째, 중간의, 마지막 아이템을 얻어봅니다
5. mixed_data_types 라는 리스트를 선언하고, 당신의 이름, 나이, 키, 결혼 여부, 주소를 넣어봅시다
6. it_companies 라는 이름의 목록 변수를 선언하고 초기 값에 Facebook, Google, Microsoft, Apple, IBM, Oracle 및 Amazon을 할당합니다
7. _print()_ 를 사용하여 리스트를 프린트 합니다
8. 리스트에 있는 기업 수를 프린트 합니다
9. 첫번째, 중간, 마지막 기업을 프린트 합니다
10. 기업 중 하나를 수정하고 리스트를 프린트 합니다
11. it_companies 에 하나의 IT 기업을 추가합니다
12. 회사 리스트 중간에 IT 기업을 추가합니다
13. it_companies 이름 중 하나를 대문자로 변경합니다 (IBM 제외!)
14. '#; ' 라는 문자열로 it_companies 에 연결합니다
15. it_companies 리스트에 특정 기업이 존재하는 지 확인합니다
16. sort() 메서드를 사용해 리스트를 정렬합니다
17. reverse() 메서드를 사용하여 리스트를 내림차순으로 반전합니다
18. 리스트에서 처음 3개의 기업을 잘라냅니다
19. 리스트에서 마지막 3개의 기업을 잘라냅니다
20. 리스트에서 중간의 IT 기업 또는 기업들을 잘라냅니다
21. 리스트에서 첫번째 IT 기업을 삭제합니다
22. 리스트에서 중간의 IT 기업 또는 기업들을 삭제합니다
23. 리스트에서 마지막 IT 기업을 삭제합니다
24. 리스트에서 모든 IT 기업을 삭제합니다
25. IT 기업 리스트를 완전히 제거합니다
26. 다음 리스트를 연결합니다:
```py
front_end = ['HTML', 'CSS', 'JS', 'React', 'Redux']
back_end = ['Node','Express', 'MongoDB']
```
27. 26번 문제의 리스트를 연결한 후, 연결된 리스트를 복사해 full_stack 변수에 할당합니다. 그리고 Python, SQL, Redux를 삽입합니다.
### Exercises: Level 2
1. 다음은 10명의 학생의 나이 리스트입니다:
```sh
ages = [19, 22, 19, 24, 20, 25, 26, 24, 25, 24]
```
- 리스트를 정렬하고 최소값 및 최대값 찾습니다
- 리스트에 최소값 및 최대값을 다시 추가합니다
- 나이의 중위값을 찾습니다(중간 아이템 하나 또는 중간 아이템 두 개를 2로 나눈 값)
- 평균 나이를 구합니다(모든 아이템의 합을 개수로 나눈 값)
- 나이의 범위를 구합니다(최대값 빼기 최소값)
- (최소값 - 평균)과 (최대값 - 평균)의 값을 비교하고 _abs()_ 메서드를 사용합니다.
1. [국가 목록](https://github.com/Asabeneh/30-Days-Of-Python/tree/master/data/countries.py) 에서 중간 국가를 찾습니다.
1. 국가 리스트를 두개의 리스트로 나눕니다. 짝수라면 두개의 리스트의 크기가 갖게, 아니라면 앞의 리스트가 하나의 국가를 더 갖도록 합니다.
1. ['China', 'Russia', 'USA', 'Finland', 'Sweden', 'Norway', 'Denmark']. 앞의 세개 국가와 나머지를 scandic countries로 unpack합니다.
🎉 CONGRATULATIONS ! 🎉
[<< Day 4](../04_Day_Strings/04_strings.md) | [Day 6 >>](../06_Day_Tuples/06_tuples.md)
================================================
FILE: Korean/07_sets_ko.md
================================================
[<< Day 6](../06_Day_Tuples/06_tuples.md) | [Day 8 >>](../08_Day_Dictionaries/08_dictionaries.md)

- [📘 Day 7](#-day-7)
- [Sets](#sets)
- [세트 만들기](#세트-만들기)
- [세트의 길이 구하기](#세트의-길이-구하기)
- [세트의 항목에 액세스](#세트의-항목에-엑세스)
- [항목 확인](#항목-확인)
- [세트에 항목 추가](#세트에-항목-추가)
- [세트에서 항목 제거](#세트에서-항목-제거)
- [세트의 항목 지우기](#세트의-항목-지우기)
- [세트 삭제](#세트-삭제)
- [목록을 집합으로 변환](#목록을-집합으로-변환)
- [집합 결합](#집합-결합)
- [교차 항목 찾기](#교차-항목-찾기)
- [하위 집합 및 수퍼 집합 확인](#하위-집합-및-수퍼-집합-확인)
- [두 세트 간의 차이 확인](#두-세트-간의-차이-확인)
- [두 집합 간의 대칭적 차이 찾기](#두-집합-간의-대칭적-차이-찾기)
- [집합 결합](#집합-결합)
- [💻 Exercises: Day 7](#-exercises-day-7)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# 📘 Day 7
## Sets
세트는 항목의 모음입니다. 초등학교 또는 고등학교 수학 수업으로 돌아가겠습니다. 집합의 수학 정의는 Python에서도 적용될 수 있습니다. 집합은 순서가 지정되지 않고 인덱싱되지 않은 개별 요소의 모음입니다. Python에서 집합은 고유한 항목을 저장하는 데 사용되며 집합 간에 *합집합* , *교차* , *차이* , *대칭적 차이* , *하위 집합* , *상위 집합* 및 *분리 집합* 을 찾을 수 있습니다.
### 세트 만들기
중괄호 {}를 사용하여 세트 또는 *set()* 내장 함수를 생성합니다.
- 빈 세트 만들기
```py
# syntax
st = {}
# or
st = set()
```
- 초기 항목으로 세트 만들기
```py
# syntax
st = {'item1', 'item2', 'item3', 'item4'}
```
**예시:**
```py
# syntax
fruits = {'banana', 'orange', 'mango', 'lemon'}
```
### 세트의 길이 구하기
**len()** 메서드를 사용하여 집합의 길이를 찾습니다.
```py
# syntax
st = {'item1', 'item2', 'item3', 'item4'}
len(set)
```
**예시:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
len(fruits)
```
### 세트의 항목에 액세스
루프를 사용하여 항목에 액세스합니다. 우리는 루프 섹션에서 이것을 볼 것입니다
### 항목 확인
목록에 항목이 있는지 확인하기 위해 멤버십 연산자 *에서* 사용합니다.
```py
# syntax
st = {'item1', 'item2', 'item3', 'item4'}
print("Does set st contain item3? ", 'item3' in st) # Does set st contain item3? True
```
**예시:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
print('mango' in fruits ) # True
```
### 세트에 항목 추가
세트가 생성되면 항목을 변경할 수 없으며 항목을 추가할 수도 있습니다.
- *add()* 를 사용하여 하나의 항목 추가
```py
# syntax
st = {'item1', 'item2', 'item3', 'item4'}
st.add('item5')
```
**예시:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
fruits.add('lime')
```
- *update()* 를 사용하여 여러 항목 추가 *update()* 를 사용하면 세트에 여러 항목을 추가할 수 있습니다. *update()* 는 목록 인수를 사용합니다.
```py
# syntax
st = {'item1', 'item2', 'item3', 'item4'}
st.update(['item5','item6','item7'])
```
**예시:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
vegetables = ('tomato', 'potato', 'cabbage','onion', 'carrot')
fruits.update(vegetables)
```
### 세트에서 항목 제거
*remove()* 메서드를 사용하여 집합에서 항목을 제거할 수 있습니다. 항목을 찾을 수 없으면 *remove()* 메서드는 오류를 발생시키므로 해당 항목이 주어진 집합에 있는지 확인하는 것이 좋습니다. 그러나, *discard()* 메서드는 오류를 발생시키지 않습니다.
```py
# syntax
st = {'item1', 'item2', 'item3', 'item4'}
st.remove('item2')
```
pop() 메서드는 목록에서 임의의 항목을 제거하고 제거된 항목을 반환합니다.
**예시:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
fruits.pop() # removes a random item from the set
```
제거된 항목에 관심이 있는 경우.
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
removed_item = fruits.pop()
```
### 세트의 항목 지우기
세트를 지우거나 비우려면 *clear* 메소드를 사용합니다.
```py
# syntax
st = {'item1', 'item2', 'item3', 'item4'}
st.clear()
```
**예시:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
fruits.clear()
print(fruits) # set()
```
### 세트 삭제
세트 자체를 삭제하려면 *del* 연산자를 사용합니다.
```py
# syntax
st = {'item1', 'item2', 'item3', 'item4'}
del st
```
**예시:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
del fruits
```
### 목록을 집합으로 변환
리스트를 세트로, 세트를 리스트로 변환할 수 있습니다. 목록을 세트로 변환하면 중복 항목이 제거되고 고유한 항목만 예약됩니다.
```py
# syntax
lst = ['item1', 'item2', 'item3', 'item4', 'item1']
st = set(lst) # {'item2', 'item4', 'item1', 'item3'} - the order is random, because sets in general are unordered
```
**예시:**
```py
fruits = ['banana', 'orange', 'mango', 'lemon','orange', 'banana']
fruits = set(fruits) # {'mango', 'lemon', 'banana', 'orange'}
```
### 집합 결합
*union()* 또는 *update()* 메서드를 사용하여 두 집합을 결합할 수 있습니다.
- Union 이 메서드는 새 집합을 반환합니다.
```py
# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item5', 'item6', 'item7', 'item8'}
st3 = st1.union(st2)
```
**예시:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
vegetables = {'tomato', 'potato', 'cabbage','onion', 'carrot'}
print(fruits.union(vegetables)) # {'lemon', 'carrot', 'tomato', 'banana', 'mango', 'orange', 'cabbage', 'potato', 'onion'}
```
- 업데이트 이 메서드는 주어진 집합에 집합을 삽입합니다.
```py
# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item5', 'item6', 'item7', 'item8'}
st1.update(st2) # st2 contents are added to st1
```
**예시:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
vegetables = {'tomato', 'potato', 'cabbage','onion', 'carrot'}
fruits.update(vegetables)
print(fruits) # {'lemon', 'carrot', 'tomato', 'banana', 'mango', 'orange', 'cabbage', 'potato', 'onion'}
```
### 교차 항목 찾기
Intersection은 두 집합 모두에 있는 항목 집합을 반환합니다. 예를 참조하십시오
```py
# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item3', 'item2'}
st1.intersection(st2) # {'item3', 'item2'}
```
**예시:**
```py
whole_numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
even_numbers = {0, 2, 4, 6, 8, 10}
whole_numbers.intersection(even_numbers) # {0, 2, 4, 6, 8, 10}
python = {'p', 'y', 't', 'h', 'o','n'}
dragon = {'d', 'r', 'a', 'g', 'o','n'}
python.intersection(dragon) # {'o', 'n'}
```
### 하위 집합 및 수퍼 집합 확인
집합은 다른 집합의 하위 집합 또는 상위 집합일 수 있습니다.
- Subset: *issubset()*
- Super set: *issuperset*
```py
# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item2', 'item3'}
st2.issubset(st1) # True
st1.issuperset(st2) # True
```
**예시:**
```py
whole_numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
even_numbers = {0, 2, 4, 6, 8, 10}
whole_numbers.issubset(even_numbers) # False, because it is a super set
whole_numbers.issuperset(even_numbers) # True
python = {'p', 'y', 't', 'h', 'o','n'}
dragon = {'d', 'r', 'a', 'g', 'o','n'}
python.issubset(dragon) # False
```
### 두 세트 간의 차이 확인
두 집합 간의 차이를 반환합니다.
```py
# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item2', 'item3'}
st2.difference(st1) # set()
st1.difference(st2) # {'item1', 'item4'} => st1\st2
```
**예시:**
```py
whole_numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
even_numbers = {0, 2, 4, 6, 8, 10}
whole_numbers.difference(even_numbers) # {1, 3, 5, 7, 9}
python = {'p', 'y', 't', 'o','n'}
dragon = {'d', 'r', 'a', 'g', 'o','n'}
python.difference(dragon) # {'p', 'y', 't'} - the result is unordered (characteristic of sets)
dragon.difference(python) # {'d', 'r', 'a', 'g'}
```
### 두 집합 간의 대칭적 차이 찾기
두 집합 간의 대칭 차이를 반환합니다. 수학적으로 두 세트에 있는 항목을 제외하고 두 세트의 모든 항목을 포함하는 세트를 리턴한다는 의미입니다. (A\B) ∪ (B\A)
```py
# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item2', 'item3'}
# it means (A\B)∪(B\A)
st2.symmetric_difference(st1) # {'item1', 'item4'}
```
**예시:**
```py
whole_numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
some_numbers = {1, 2, 3, 4, 5}
whole_numbers.symmetric_difference(some_numbers) # {0, 6, 7, 8, 9, 10}
python = {'p', 'y', 't', 'h', 'o','n'}
dragon = {'d', 'r', 'a', 'g', 'o','n'}
python.symmetric_difference(dragon) # {'r', 't', 'p', 'y', 'g', 'a', 'd', 'h'}
```
### 집합 결합
두 세트에 공통 항목이 없으면 분리 세트라고 합니다. *isdisjoint()* 메서드를 사용하여 두 집합이 결합인지 분리인지 확인할 수 있습니다.
```py
# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item2', 'item3'}
st2.isdisjoint(st1) # False
```
**예시:**
```py
even_numbers = {0, 2, 4 ,6, 8}
even_numbers = {1, 3, 5, 7, 9}
even_numbers.isdisjoint(odd_numbers) # True, because no common item
python = {'p', 'y', 't', 'h', 'o','n'}
dragon = {'d', 'r', 'a', 'g', 'o','n'}
python.isdisjoint(dragon) # False, there are common items {'o', 'n'}
```
🌕 당신은 떠오르는 별입니다. 당신은 방금 7일차 챌린지를 완료했으며 위대함을 향한 당신의 길에 7걸음 앞서 있습니다. 이제 뇌와 근육을 위한 몇 가지 훈련을 하십시오.
## 💻 Exercises: Day 7
```py
# sets
it_companies = {'Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon'}
A = {19, 22, 24, 20, 25, 26}
B = {19, 22, 20, 25, 26, 24, 28, 27}
age = [22, 19, 24, 25, 26, 24, 25, 24]
```
### Exercises: Level 1
1. 집합 it_companies의 길이 찾기
2. it_companies에 'Twitter' 추가
3. it_companies 집합에 여러 IT 회사를 한 번에 삽입
4. it_companies 집합에서 회사 중 하나를 제거합니다.
5. 제거하다와 버리다의 차이점은 무엇인가요?
### Exercises: Level 2
1. A와 B를 결합
2. 교차 항목 찾기
3. A는 B의 부분집합
4. A와 B는 서로소 집합입니다.
5. A는 B와, B는 A와 조인
6. A와 B의 대칭 차이는 무엇입니까
7. 세트를 완전히 삭제
### Exercises: Level 3
1. 연령을 세트로 변환하고 목록의 길이와 세트의 길이를 비교합니다. 어느 것이 더 큽니까?
2. 문자열, 목록, 튜플 및 집합과 같은 데이터 유형의 차이점을 설명하십시오.
3. *저는 교사이고 사람들에게 영감을 주고 가르치는 것을 좋아합니다.* 문장에 사용된 독특한 단어는 몇 개입니까? 분할 방법을 사용하고 고유한 단어를 가져오도록 설정합니다.
🎉 축하합니다! 🎉
[<< 6일차](../06_Day_Tuples/06_tuples.md) | [8일차 >>](../08_Day_Dictionaries/08_dictionaries.md)
================================================
FILE: Korean/08_Day_Dictionaries/08_dictionaries.md
================================================
[<< Day 9](../09_Day_Conditionals/09_conditionals.md) | [Day 11 >>](../11_Day_Functions/11_functions.md)

- [📘 Day 10](#-day-10)
- [Loops](#loops)
- [While 루프](#while-루프)
- [Break 과 Continue - Part 1](#break-과-continue---part-1)
- [For 루프](#for-루프)
- [Break 과 Continue - Part 2](#break-과-continue---part-2)
- [범위 기능](#범위-기능)
- [중첩 For 루프](#중첩-for-루프)
- [For Else](#for-else)
- [Pass](#pass)
- [💻 Exercises: Day 10](#-exercises-day-10)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# 📘 Day 10
## Loops
인생은 일상으로 가득 차 있습니다. 프로그래밍에서 우리는 또한 많은 반복 작업을 수행합니다. 반복 작업을 처리하기 위해 프로그래밍 언어는 루프를 사용합니다. Python 프로그래밍 언어는 또한 다음 유형의 두 루프를 제공합니다.
1. while loop
2. for loop
### While 루프
우리는 while 루프를 만들기 위해 예약어 *while* 을 사용합니다. 주어진 조건이 만족될 때까지 문 블록을 반복적으로 실행하는 데 사용됩니다. 조건이 거짓이 되면 루프 뒤의 코드 행이 계속 실행됩니다.
```py
# syntax
while condition:
code goes here
```
**예시:**
```py
count = 0
while count < 5:
print(count)
count = count + 1
#prints from 0 to 4
```
위의 while 루프에서 count가 5일 때 조건이 false가 됩니다. 이때 루프가 중지됩니다. 조건이 더 이상 참이 아닐 때 코드 블록을 실행하고 싶다면 *else* 를 사용할 수 있습니다.
```py
# syntax
while condition:
code goes here
else:
code goes here
```
**예시:**
```py
count = 0
while count < 5:
print(count)
count = count + 1
#prints from 0 to 4
```
위의 루프 조건은 count가 5이고 루프가 중지되고 실행이 else 문을 시작하면 거짓이 됩니다. 결과적으로 5가 인쇄됩니다.
### Break 과 Continue - Part 1
- 중단: 루프에서 벗어나거나 중단하고 싶을 때 중단을 사용합니다.
```py
# syntax
while condition:
code goes here
if another_condition:
break
```
**예시:**
```py
count = 0
while count < 5:
print(count)
count = count + 1
if count == 3:
break
```
위의 while 루프는 0, 1, 2만 인쇄하지만 3에 도달하면 중지합니다.
- 계속: continue 문을 사용하면 현재 반복을 건너뛰고 다음을 계속할 수 있습니다.
```py
# syntax
while condition:
code goes here
if another_condition:
continue
```
**예시:**
```py
count = 0
while count < 5:
if count == 3:
continue
print(count)
count = count + 1
```
위의 while 루프는 0, 1, 2 및 4만 인쇄합니다(3을 건너뜁니다).
### For 루프
*for* 키워드는 다른 프로그래밍 언어와 유사하지만 구문이 약간 다른 for 루프를 만드는 데 사용됩니다. 루프는 시퀀스(즉, 목록, 튜플, 사전, 집합 또는 문자열)를 반복하는 데 사용됩니다.
- For loop with list
```py
# syntax
for iterator in lst:
code goes here
```
**예시:**
```py
numbers = [0, 1, 2, 3, 4, 5]
for number in numbers: # number is temporary name to refer to the list's items, valid only inside this loop
print(number) # the numbers will be printed line by line, from 0 to 5
```
- For loop with string
```py
# syntax
for iterator in string:
code goes here
```
**예시:**
```py
language = 'Python'
for letter in language:
print(letter)
for i in range(len(language)):
print(language[i])
```
- For loop with tuple
```py
# syntax
for iterator in tpl:
code goes here
```
**예시:**
```py
numbers = (0, 1, 2, 3, 4, 5)
for number in numbers:
print(number)
```
- 사전을 사용한 For 루프 사전을 통한 루프는 사전의 키를 제공합니다.
```py
# syntax
for iterator in dct:
code goes here
```
**예시:**
```py
person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_marred':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
for key in person:
print(key)
for key, value in person.items():
print(key, value) # this way we get both keys and values printed out
```
- Loops in set
```py
# syntax
for iterator in st:
code goes here
```
**예시:**
```py
it_companies = {'Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon'}
for company in it_companies:
print(company)
```
### Break 과 Continue - Part 2
짧은 알림: *중단* : 루프가 완료되기 전에 중단하고 싶을 때 중단을 사용합니다.
```py
# syntax
for iterator in sequence:
code goes here
if condition:
break
```
**예시:**
```py
numbers = (0,1,2,3,4,5)
for number in numbers:
print(number)
if number == 3:
break
```
위의 예에서 루프는 3에 도달하면 중지됩니다.
계속: 루프 반복에서 일부 단계를 건너뛰고 싶을 때 계속을 사용합니다.
```py
# syntax
for iterator in sequence:
code goes here
if condition:
continue
```
**예시:**
```py
numbers = (0,1,2,3,4,5)
for number in numbers:
print(number)
if number == 3:
continue
print('Next number should be ', number + 1) if number != 5 else print("loop's end") # for short hand conditions need both if and else statements
print('outside the loop')
```
위의 예에서 숫자가 3이면 조건 *다음* 단계(루프 내부)를 건너뛰고 반복이 남아 있으면 루프 실행이 계속됩니다.
### 범위 기능
*range()* 함수는 숫자 목록에 사용됩니다. *범위(시작, 끝, 단계)* 는 시작, 종료 및 증분의 세 가지 매개변수를 사용합니다. 기본적으로 0부터 시작하고 증분은 1입니다. 범위 시퀀스에는 최소 1개의 인수(종료)가 필요합니다. 범위를 사용하여 시퀀스 만들기
```py
lst = list(range(11))
print(lst) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
st = set(range(1, 11)) # 2 arguments indicate start and end of the sequence, step set to default 1
print(st) # {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
lst = list(range(0,11,2))
print(lst) # [0, 2, 4, 6, 8, 10]
st = set(range(0,11,2))
print(st) # {0, 2, 4, 6, 8, 10}
```
```py
# syntax
for iterator in range(start, end, step):
```
**예시:**
```py
for number in range(11):
print(number) # prints 0 to 10, not including 11
```
### 중첩 For 루프
루프 안에 루프를 작성할 수 있습니다.
```py
# syntax
for x in y:
for t in x:
print(t)
```
**예시:**
```py
person = {
'first_name': 'Asabeneh',
'last_name': 'Yetayeh',
'age': 250,
'country': 'Finland',
'is_marred': True,
'skills': ['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address': {
'street': 'Space street',
'zipcode': '02210'
}
}
for key in person:
if key == 'skills':
for skill in person['skills']:
print(skill)
```
### For Else
루프가 끝날 때 메시지를 실행하려면 else를 사용합니다.
```py
# syntax
for iterator in range(start, end, step):
do something
else:
print('The loop ended')
```
**예시:**
```py
for number in range(11):
print(number) # prints 0 to 10, not including 11
else:
print('The loop stops at', number)
```
### Pass
Python에서 when 문이 필요하지만(세미콜론 뒤에) 코드를 실행하는 것을 좋아하지 않으므로 오류를 피하기 위해 *pass* 라는 단어를 쓸 수 있습니다. 또한 향후 진술을 위해 자리 표시자로 사용할 수 있습니다.
**예시:**
```py
for number in range(6):
pass
```
🌕 당신은 큰 이정표를 세웠고, 당신은 멈출 수 없습니다. 계속하세요! 10일차 챌린지를 방금 완료했으며 위대함을 향한 10단계를 앞두고 있습니다. 이제 뇌와 근육을 위한 몇 가지 운동을 하십시오.
## 💻 Exercises: Day 10
### Exercises: Level 1
1. for 루프를 사용하여 0에서 10까지 반복하고 while 루프를 사용하여 동일한 작업을 수행합니다.
2. for 루프를 사용하여 10에서 0까지 반복하고 while 루프를 사용하여 동일한 작업을 수행합니다.
3. print()를 7번 호출하는 루프를 작성하여 다음 삼각형을 출력합니다.
```py
#
##
###
####
#####
######
#######
```
4. 중첩 루프를 사용하여 다음을 만듭니다.
```sh
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
```
5. 다음 패턴을 인쇄합니다.
```sh
0 x 0 = 0
1 x 1 = 1
2 x 2 = 4
3 x 3 = 9
4 x 4 = 16
5 x 5 = 25
6 x 6 = 36
7 x 7 = 49
8 x 8 = 64
9 x 9 = 81
10 x 10 = 100
```
6. for 루프를 사용하여 ['Python', 'Numpy','Pandas','Django', 'Flask'] 목록을 반복하고 항목을 출력합니다.
7. for 루프를 사용하여 0에서 100까지 반복하고 짝수만 출력
8. for 루프를 사용하여 0에서 100까지 반복하고 홀수만 출력
### Exercises: Level 2
1. for 루프를 사용하여 0에서 100까지 반복하고 모든 숫자의 합계를 인쇄합니다.
```sh
The sum of all numbers is 5050.
```
1. for 루프를 사용하여 0에서 100까지 반복하고 모든 짝수의 합과 모든 승산의 합을 인쇄합니다.
```sh
The sum of all evens is 2550. And the sum of all odds is 2500.
```
### Exercises: Level 3
1. 데이터 폴더로 이동하여 [countries.py](https://github.com/Asabeneh/30-Days-Of-Python/blob/master/data/countries.py) 파일을 사용합니다. 국가를 순환하고 단어 *land* 를 포함하는 모든 국가를 추출합니다.
2. 이것은 과일 목록입니다. ['banana', 'orange', 'mango', 'lemon'] 루프를 사용하여 순서를 뒤집습니다.
3. 데이터 폴더로 이동하여 [countries_data.py](https://github.com/Asabeneh/30-Days-Of-Python/blob/master/data/countries-data.py) 파일을 사용합니다.
1. 데이터의 총 언어 수는 얼마입니까?
2. 데이터에서 가장 많이 사용되는 10개 언어 찾기
3. 세계에서 인구가 가장 많은 10개 국가 찾기
🎉 축하합니다! 🎉
[<< Day 9](../09_Day_Conditionals/09_conditionals.md) | [Day 11 >>](../11_Day_Functions/11_functions.md)
================================================
FILE: Korean/readme_ko.md
================================================
# 🐍 30 Days Of Python
|# Day | Topics |
|------|:---------------------------------------------------------:|
| 01 | [Introduction](./readme_ko.md)|
| 02 | [Variables, Built-in Functions](../02_Day_Variables_builtin_functions/02_variables_builtin_functions.md)|
| 03 | [Operators](../03_Day_Operators/03_operators.md)|
| 04 | [Strings](../04_Day_Strings/04_strings.md)|
| 05 | [Lists](../05_Day_Lists/05_lists.md)|
| 06 | [Tuples](../06_Day_Tuples/06_tuples.md)|
| 07 | [Sets](../07_Day_Sets/07_sets.md)|
| 08 | [Dictionaries](../08_Day_Dictionaries/08_dictionaries.md)|
| 09 | [Conditionals](../09_Day_Conditionals/09_conditionals.md)|
| 10 | [Loops](../10_Day_Loops/10_loops.md)|
| 11 | [Functions](../11_Day_Functions/11_functions.md)|
| 12 | [Modules](../12_Day_Modules/12_modules.md)|
| 13 | [List Comprehension](../13_Day_List_comprehension/13_list_comprehension.md)|
| 14 | [Higher Order Functions](../14_Day_Higher_order_functions/14_higher_order_functions.md)|
| 15 | [Python Type Errors](../15_Day_Python_type_errors/15_python_type_errors.md)|
| 16 | [Python Date time](../16_Day_Python_date_time/16_python_datetime.md) |
| 17 | [Exception Handling](../17_Day_Exception_handling/17_exception_handling.md)|
| 18 | [Regular Expressions](../18_Day_Regular_expressions/18_regular_expressions.md)|
| 19 | [File Handling](../19_Day_File_handling/19_file_handling.md)|
| 20 | [Python Package Manager](../20_Day_Python_package_manager/20_python_package_manager.md)|
| 21 | [Classes and Objects](../21_Day_Classes_and_objects/21_classes_and_objects.md)|
| 22 | [Web Scraping](../22_Day_Web_scraping/22_web_scraping.md)|
| 23 | [Virtual Environment](../23_Day_Virtual_environment/23_virtual_environment.md)|
| 24 | [Statistics](../24_Day_Statistics/24_statistics.md)|
| 25 | [Pandas](../25_Day_Pandas/25_pandas.md)|
| 26 | [Python web](../26_Day_Python_web/26_python_web.md)|
| 27 | [Python with MongoDB](../27_Day_Python_with_mongodb/27_python_with_mongodb.md)|
| 28 | [API](../28_Day_API/28_API.md)|
| 29 | [Building API](../29_Day_Building_API/29_building_API.md)|
| 30 | [Conclusions](../30_Day_Conclusions/30_conclusions.md)|
🧡🧡🧡 HAPPY CODING 🧡🧡🧡
Support the author to create more educational materials
[Day 2 >>](../02_Day_Variables_builtin_functions/02_variables_builtin_functions.md)

- [🐍 30 Days Of Python](#-30-days-of-python)
- [📘 Day 1](#-day-1)
- [환영합니다](#환영합니다)
- [소개](#소개)
- [왜 Python이느냐?](#왜-python이느냐?)
- [환경 설정](#환경-설정)
- [Python 설치](#python-설치)
- [Python 셸](#python-셸)
- [Visual Studio Code 설치](#visual-studio-code-설치)
- [visual studio code를 사용하기](#visual-studio-code를-사용하기)
- [Python 기본](#python-기본)
- [Python 구문](#python-구문)
- [Python 들여쓰기](#python-들여쓰기)
- [주석](#주석)
- [데이터 타입](#데이터-타입)
- [Number](#number)
- [String](#string)
- [Booleans](#booleans)
- [List](#list)
- [Dictionary](#dictionary)
- [Tuple](#tuple)
- [Set](#set)
- [데이터 타입 체크](#데이터-타입-체크)
- [Python 파일](#python-파일)
- [💻 Exercises - Day 1](#-exercises---day-1)
- [Exercise: Level 1](#exercise-level-1)
- [Exercise: Level 2](#exercise-level-2)
- [Exercise: Level 3](#exercise-level-3)
# 📘 Day 1
## 환영합니다
_30 days of Python_에 참여하기로 결정하신 것을 **축하드립니다**. 이 챌린지에서는 Python 프로그래머가 되기 위해 필요한 모든 것과 프로그래밍의 전체 개념을 배우게 됩니다. 챌린지가 끝나면 _30DaysOfPython_프로그래밍 챌린지 인증서를 받게 됩니다.
챌린지에 적극적으로 참여하고 싶다면 [30DaysOfPython challenge](https://t.me/ThirtyDaysOfPython) 텔레그램 그룹에 가입할 수 있습니다.
## 소개
Python은 범용 프로그래밍을 위한 고급 프로그래밍 언어입니다. 오픈 소스, 인터프리터, 객체 지향 프로그래밍 언어입니다. Python은 네덜란드 프로그래머 Guido van Rossum이 만들었습니다. Python 프로그래밍 언어의 이름은 영국 스케치 코미디 시리즈 *Month Python's Flying Circus* 에서 파생되었습니다. 첫 번째 버전은 1991년 2월 20일에 출시되었습니다. 이 30일간의 Python 챌린지는 최신 버전의 Python인 Python 3를 차근차근 배울 수 있도록 도와줄 것입니다. 주제는 30일로 나뉘며, 매일 이해하기 쉬운 설명, 실제 사례, 많은 실습 및 프로젝트가 포함된 여러 주제가 포함됩니다.
이 챌린지는 Python 프로그래밍 언어를 배우고자 하는 초보자와 전문가를 위해 고안되었습니다. 챌린지를 완료하는 데 30~100일이 소요될 수 있으며 텔레그램 그룹에 적극적으로 참여하는 사람들이 챌린지를 완료할 확률이 높습니다.
시각적 학습자이거나 동영상을 선호하는 경우 이 [완전 초보를 위한 Python 동영상](https://www.youtube.com/watch?v=11OYpBrhdyM)으로 시작할 수 있습니다.
## 왜 Python이느냐?
인간의 언어에 매우 가깝고 배우기 쉽고 사용하기 쉬운 프로그래밍 언어입니다.
Python은 다양한 산업 및 회사(Google 포함)에서 사용됩니다. 웹 응용 프로그램, 데스크톱 응용 프로그램, 시스템 관리 및 기계 학습 라이브러리를 개발하는 데 사용되었습니다. Python은 데이터 과학 및 기계 학습 커뮤니티에서 널리 사용되는 언어입니다. 이것이 Python 학습을 시작하도록 설득하기에 충분하기를 바랍니다. Python은 세상을 지배하고 있으니 지배 당하기 전에 Python을 지배하십시오.
## 환경 설정
### Python 설치
Python 스크립트를 실행하려면 Python을 설치해야 합니다. Python을 [다운로드](https://www.python.org/)합시다.
Windows 사용자인 경우. 빨간색 동그라미 친 버튼을 클릭합니다.
macOS 사용자인 경우. 빨간색 동그라미 친 버튼을 클릭합니다.
[](https://www.python.org/)
Python이 설치되어 있는지 확인하려면 장치 터미널에 다음 명령을 작성하십시오.
```shell
python --version
```

터미널에서 보시다시피 저는 현재 _Python 3.7.5_ 버전을 사용하고 있습니다. 귀하의 Python 버전은 내 버전과 다를 수 있지만 3.6 이상이어야 합니다. Python 버전을 볼 수 있다면 잘한 것입니다. 이제 컴퓨터에 Python이 설치되었습니다. 다음 섹션으로 계속 진행하십시오.
### Python 셸
Python은 해석된 스크립팅 언어이므로 컴파일할 필요가 없습니다. 코드를 한 줄씩 실행한다는 의미입니다. Python은 _Python Shell(Python Interactive Shell)_과 함께 제공됩니다. 단일 Python 명령을 실행하고 결과를 얻는 데 사용됩니다.
Python Shell은 사용자의 Python 코드를 기다립니다. 코드를 입력하면 코드를 해석하여 다음 줄에 결과를 표시합니다.
터미널이나 명령 프롬프트(cmd)를 열고 쓰기:
```shell
python
```

Python 대화형 셸이 열리고 Python 코드(Python 스크립트)를 작성하기를 기다립니다. 기호 >>> 옆에 Python 스크립트를 작성하고 Enter를 누릅니다.
Python 스크립팅 셸에서 첫 번째 스크립트를 작성해 보겠습니다.

훌륭합니다. Python 대화형 셸에서 첫 번째 Python 스크립트를 작성했습니다. Python 대화형 셸을 어떻게 닫습니까?
셸을 닫으려면 기호 옆에 >> **exit()** 명령을 작성하고 Enter 키를 누릅니다.

이제 Python 대화형 셸을 여는 방법과 종료하는 방법을 알았습니다.
Python은 Python이 이해하는 스크립트를 작성하면 결과를 제공하고 그렇지 않으면 오류를 반환합니다. 고의적인 실수를 하고 Python이 무엇을 반환하는지 봅시다.

반환된 오류에서 볼 수 있듯이 Python은 우리가 저지른 실수와 _Syntax Error: invalid syntax_를 알고 있을 정도로 영리합니다. Python에서 x를 곱셈으로 사용하는 것은 (x)가 Python에서 유효한 구문이 아니기 때문에 구문 오류입니다. (**x**) 대신 곱셈에 별표(*)를 사용합니다. 반환된 오류는 수정해야 할 사항을 명확하게 보여줍니다.
프로그램에서 오류를 식별하고 제거하는 프로세스를 *디버깅*이라고 합니다. **x** 대신 *를 넣어 디버깅해 봅시다.

버그가 수정되었고 코드가 실행되었으며 예상했던 결과를 얻었습니다. 프로그래머로서 매일 이러한 종류의 오류를 보게 될 것입니다. 디버깅 방법을 아는 것이 좋습니다. 디버깅을 잘하려면 어떤 종류의 오류가 발생했는지 이해해야 합니다. 발생할 수 있는 Python 오류 중 일부는 *SyntaxError*, *IndexError*, *NameError*, *ModuleNotFoundError*, *KeyError*, *ImportError*, *AttributeError*, *TypeError*, *ValueError*, *ZeroDivisionError* 등입니다. 이후 섹션에서 다른 Python **_오류 유형_**에 대해 자세히 알아볼 것입니다.
Python 대화형 셸을 사용하는 방법을 더 연습해 보겠습니다. 터미널이나 명령 프롬프트로 이동하여 **python**이라는 단어를 씁니다.

Python 대화형 셸이 열립니다. 몇 가지 기본적인 수학 연산(더하기, 빼기, 곱하기, 나누기, 나머지, 지수)을 수행해 보겠습니다.
Python 코드를 작성하기 전에 먼저 몇 가지 수학을 수행해 보겠습니다:
- 2 + 3 = 5
- 3 - 2 = 1
- 3 \* 2 = 6
- 3 / 2 = 1.5
- 3 ^ 2 = 3 x 3 = 9
Python에는 다음과 같은 추가 작업이 있습니다:
- 3 % 2 = 1 => 나머지를 구함
- 3 // 2 = 1 => 나머지를 제거
위의 수학식을 Python 코드로 바꿔봅시다. Python 셸이 열렸으며 셸 맨 처음에 주석을 작성하겠습니다.
_comment_는 Python에 의해 실행되지 않는 코드의 일부입니다. 따라서 코드를 더 읽기 쉽게 만들기 위해 코드에 일부 텍스트를 남길 수 있습니다. Python은 주석 부분을 실행하지 않습니다. Python에서 주석은 해시(#) 기호로 시작합니다.
이것이 Python에서 주석을 작성하는 방법입니다
```shell
# 주석은 해시로 시작합니다.
# (#) 심볼로 시작하기 때문에 이것은 파이썬 주석입니다.
```

다음 섹션으로 이동하기 전에 Python 대화형 셸에서 더 많은 연습을 해 보겠습니다. 셸에서 _exit()_를 작성하여 열린 셸을 닫았다가 다시 열어 Python 셸에서 텍스트를 쓰는 방법을 연습해 봅시다.

### Visual Studio Code 설치
Python 대화형 셸은 작은 스크립트 코드를 시도하고 테스트하는 데 적합하지만 큰 프로젝트에는 적합하지 않습니다. 실제 작업 환경에서 개발자는 다양한 코드 편집기를 사용하여 코드를 작성합니다. 이 30일간의 Python 프로그래밍 챌린지에서는 Visual Studio 코드를 사용합니다. Visual Studio Code는 매우 인기 있는 오픈 소스 텍스트 편집기입니다. 나는 vscode의 팬이고 Visual Studio 코드를 [다운로드](https://code.visualstudio.com/)하는 것을 추천하고 싶지만, 다른 편집자를 선호한다면 가지고 있는 것을 자유롭게 따르십시오.
[](https://code.visualstudio.com/)
Visual Studio Code를 설치하셨다면 어떻게 사용하는지 알아보겠습니다.
비디오를 선호하는 경우 Python용 Visual Studio Code[비디오 자습서](https://www.youtube.com/watch?v=bn7Cx4z-vSo)를 따를 수 있습니다.
#### visual studio code를 사용하기
Visual Studio 아이콘을 두 번 클릭하여 Visual Studio 코드를 엽니다. 열면 이런 종류의 인터페이스가 나타납니다. 레이블이 지정된 아이콘을 따라해보세요.

바탕 화면에 30DaysOfPython이라는 폴더를 만듭니다. 그런 다음 Visual Studio 코드를 사용하여 엽시다.


파일을 열면 30DaysOfPython 프로젝트의 디렉토리 내부에 파일과 폴더를 생성하기 위한 바로 가기가 표시됩니다. 아래에서 볼 수 있듯이 첫 번째 파일인 helloworld.py를 만들었습니다. 당신도 똑같이 할 수 있습니다.

하루동안 오래 코딩을 한 후에 코드 편집기를 닫고 싶습니까? 이렇게 열린 프로젝트를 닫으면 됩니다.

축하합니다. 개발 환경 설정을 완료했습니다. 코딩을 시작해 봅시다.
## Python 기본
### Python 구문
Python 스크립트는 Python 대화형 셸 또는 코드 편집기에서 작성할 수 있습니다. Python 파일의 확장자는 .py입니다.
### Python 들여 쓰기
들여쓰기는 텍스트의 공백입니다. 많은 언어에서 들여쓰기는 코드 가독성을 높이는 데 사용되지만 Python은 들여쓰기를 사용하여 코드 블록을 만듭니다. 다른 프로그래밍 언어에서는 중괄호를 사용하여 들여쓰기 대신 코드 블록을 만듭니다. Python 코드를 작성할 때 흔히 발생하는 버그 중 하나는 잘못된 들여쓰기입니다.

### 주석
주석은 코드를 더 읽기 쉽게 만들고 코드에 설명을 남기기 위해 매우 중요합니다. Python은 코드의 주석 부분을 실행하지 않습니다.
Python에서 해시(#)로 시작하는 모든 텍스트는 주석입니다.
**예시:한 문장 주석**
```shell
# This is the first comment
# This is the second comment
# Python is eating the world
```
**예시: 여러 문장 주석**
Triple quote can be used for multiline comment if it is not assigned to a variable
```shell
"""This is multiline comment
multiline comment takes multiple lines.
python is eating the world
"""
```
### 데이터 타입
Python에는 여러 유형의 데이터 유형이 있습니다. 가장 일반적인 것부터 시작하겠습니다. 다른 데이터 유형은 다른 섹션에서 자세히 다룰 것입니다. 당분간 다양한 데이터 유형을 살펴보고 익숙해지도록 합시다. 지금은 명확하게 이해하지 않아도 됩니다.
#### Number
- Integer: 정수(음수, 영 그리고 양수)
예시:
... -3, -2, -1, 0, 1, 2, 3 ...
- Float: 십진수
예시
... -3.5, -2.25, -1.0, 0.0, 1.1, 2.2, 3.5 ...
- Complex
예시
1 + j, 2 + 4j
#### String
작은따옴표 또는 큰따옴표 아래에 있는 하나 이상의 문자 모음입니다. 문자열이 두 문장 이상인 경우 삼중 따옴표를 사용합니다.
**예시:**
```py
'Asabeneh'
'Finland'
'Python'
'I love teaching'
'I hope you are enjoying the first day of 30DaysOfPython Challenge'
```
#### Boolean
부울 데이터 유형은 True 또는 False 값입니다. T와 F는 항상 대문자여야 합니다.
**예시:**
```python
True # 불이 켜져있나요? 그러면 참입니다.
False # 불이 꺼져있나요? 그러면 거짓입니다.
```
#### List
Python 리스트는 다른 데이터 유형 항목을 저장할 수 있는 정렬된 컬렉션입니다. 리스트는 JavaScript의 배열과 비슷합니다.
**Example:**
```py
[0, 1, 2, 3, 4, 5] # 모두 동일한 데이터 유형 - 숫자 리스트
['Banana', 'Orange', 'Mango', 'Avocado'] # 모두 동일한 데이터 유형 - 문자열 리스트(과일)
['Finland','Estonia', 'Sweden','Norway'] # 모두 동일한 데이터 유형 - 문자열 리스트(국가)
['Banana', 10, False, 9.81] # 리스트의 다양한 데이터 유형 - 문자열, 정수, 부울 및 부동 소수점
```
#### Dictionary
Python 사전 개체는 키 값 쌍 형식의 정렬되지 않은 데이터 모음입니다.
**Example:**
```py
{
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'country':'Finland',
'age':250,
'is_married':True,
'skills':['JS', 'React', 'Node', 'Python']
}
```
#### Tuple
튜플은 목록과 같은 다양한 데이터 유형의 정렬된 모음이지만 튜플이 생성되면 수정할 수 없습니다. 그것들은 변할 수 없습니다.
**Example:**
```py
('Asabeneh', 'Pawel', 'Brook', 'Abraham', 'Lidiya') # Names
```
```py
('Earth', 'Jupiter', 'Neptune', 'Mars', 'Venus', 'Saturn', 'Uranus', 'Mercury') # planets
```
#### Set
집합은 목록 및 튜플과 유사한 데이터 유형의 모음입니다. 목록 및 튜플과 달리 집합은 순서가 지정된 항목 모음이 아닙니다. 수학에서와 마찬가지로 Python에서 set은 고유한 항목만 저장합니다.
이후 섹션에서는 각각의 모든 Python 데이터 유형에 대해 자세히 설명합니다.
**Example:**
```py
{2, 4, 3, 5}
{3.14, 9.81, 2.7} # order is not important in set
```
### 데이터 타입 체크
특정 데이터/변수의 데이터 유형을 확인하기 위해 **type** 기능을 사용합니다. 다음 터미널에서 다양한 Python 데이터 유형을 볼 수 있습니다:

### Python 파일
먼저 프로젝트 폴더인 30DaysOfPython을 엽니다. 이 폴더가 없으면 30DaysOfPython이라는 폴더 이름을 만듭니다. 이 폴더 안에 helloworld.py라는 파일을 만듭니다. 이제 Visual Studio 코드를 사용하여 Python 대화형 셸에서 수행한 작업을 수행해 보겠습니다.
Python 대화형 셸은 **print**를 사용하지 않고 인쇄했지만 Visual Studio 코드에서 결과를 보려면 내장 함수 *print()를 사용해야 합니다. *print()* 내장 함수는 *print('arument1', 'argument2', 'argument3')*와 같이 하나 이상의 인수를 사용합니다. 아래 예를 참조하십시오.
**Example:**
파일 이름은 helloworld.py.
```py
# Day 1 - 30DaysOfPython Challenge
print(2 + 3) # addition(+)
print(3 - 1) # subtraction(-)
print(2 * 3) # multiplication(*)
print(3 / 2) # division(/)
print(3 ** 2) # exponential(**)
print(3 % 2) # modulus(%)
print(3 // 2) # Floor division operator(//)
# Checking data types
print(type(10)) # Int
print(type(3.14)) # Float
print(type(1 + 3j)) # Complex number
print(type('Asabeneh')) # String
print(type([1, 2, 3])) # List
print(type({'name':'Asabeneh'})) # Dictionary
print(type({9.8, 3.14, 2.7})) # Set
print(type((9.8, 3.14, 2.7))) # Tuple
```
Python 파일을 실행하려면 아래 이미지를 확인하세요. Visual Studio Code에서 녹색 버튼을 실행하거나 터미널에 *python helloworld.py*를 입력하여 Python 파일을 실행할 수 있습니다.

🌕 좋습니다. 당신은 방금 1일차 도전을 완료했고 당신은 위대한 여정에 있습니다. 이제 뇌와 근육을 위한 몇 가지 훈련을 해봅시다.
## 💻 Exercises - Day 1
### Exercise: Level 1
1. 사용 중인 Python 버전 확인
2. Python 대화형 셸을 열고 다음 작업을 수행합니다. 피연산자는 3과 4입니다.
- 더하기(+)
- 빼기(-)
- 곱하기(\*)
- 나머지(%)
- 나누기(/)
- 지수(\*\*)
- 정수 나누기(//)
3. Python 대화형 셸에 문자열을 씁니다. 문자열은 다음과 같습니다:
- 이름
- 가족 이름
- 국가 이름
- I am enjoying 30 days of python
4. 다음 데이터의 데이터 유형을 확인하십시오.:
- 10
- 9.8
- 3.14
- 4 - 4j
- ['Asabeneh', 'Python', 'Finland']
- 이름
- 가족 이름
- 국가 이름
### Exercise: Level 2
1. 30DaysOfPython 폴더 안에 day_1이라는 폴더를 만듭니다. day_1 폴더 안에 python 파일 helloworld.py를 만들고 질문 1, 2, 3, 4를 반복하세요. Python 파일에서 작업할 때 _print()_를 사용하는 것을 잊지 마세요. 파일을 저장한 디렉토리로 이동하여 실행합니다.
### Exercise: Level 3
1. Number(Integer, Float, Complex), String, Boolean, List, Tuple, Set 및 Dictionary와 같은 다양한 Python 데이터 유형에 대한 예제를 작성합니다.
2. 참고 [Euclidean distance](https://en.wikipedia.org/wiki/Euclidean_distance#:~:text=In%20mathematics%2C%20the%20Euclidean%20distance,being%20called%20the%20Pythagorean%20distance.) (2, 3) 과 (10, 8) 사이
🎉 축하합니다 ! 🎉
[Day 2 >>](../02_Day_Variables_builtin_functions/02_variables_builtin_functions.md)
================================================
FILE: Portuguese/02_Dia_Variaveis_BuiltIn_Functions/README.md
================================================
30 Dias de Python: Dia 2 - Variaveis, Builtin Functions
[<< Dia 1](../README.md) | [Dia 3 >>](../03_Day_Operators/03_operators.md)

- [📘 Dia 2](#-dia-2)
- [Built in functions](#built-in-functions)
- [Variaveis](#Variaveis)
- [Declarando múltiplas váriaveis em uma linha](#Declarando-múltiplas-variaveis-em-uma-linha)
- [Tipos de dados](#Tipos-de-Dados)
- [Checando tipos de dados e type Casting](#Checando-tipos-de-dados-e-Casting)
- [Numeros](#Numeros)
- [💻 Exercicios - Dia 2](#-Exercicios---Dia-2)
- [Exercicios: Level 1](#Exercicios-level-1)
- [Exercicios: Level 2](#Exercicios-level-2)
# 📘 Dia 2
## Built in functions
Em Python, temos muitas built-in functions. As built-in functions estão disponíveis globalmente para seu uso, o que significa que você pode fazer uso das built-in functions sem importar ou configurar. Algumas das built-in functions do Python mais usadas são as seguintes: _print()_, _len()_, _type()_, _int()_, _float()_, _str()_, _input()_, _list()_, _dict()_, _min()_, _max()_, _sum()_, _sorted()_, _open()_, _file()_, _help()_ e _dir()_ . Na tabela a seguir, você verá uma lista gigantesca de funções do Python retiradas da [documentação do python](https://docs.python.org/3.9/library/functions.html).

Vamos abrir o shell do Python e começar a usar algumas built-in functions.

Vamos praticar mais usando diferentes built-in functions

Como você pode ver no terminal acima, O Python possui palavras reservadas. Não usamos palavras reservadas para declarar variáveis ou funções. Abordaremos as variáveis na próxima seção.
Acredito que agora você já esteja familiarizado com as built-in functions. Vamos fazer mais uma prática de built-in functions e passaremos para a próxima seção.

## Variaveis
As variáveis armazenam dados na memória do computador. Variáveis mnemônicas são recomendadas para uso em muitas linguagens de programação. Uma variável mnemônica é um nome de variável que pode ser facilmente lembrado e associado. Uma variável refere-se a um endereço de memória no qual os dados são armazenados.
Número no início, caractere especial e hífen não são permitidos ao nomear uma variável. Uma variável pode ter um nome curto (como x, y, z), mas um nome mais descritivo tipo (nome, sobrenome, idade, país) é altamente recomendado.
Regras da nomeclatura de variáveis no Python
- O nome de uma variável deve começar com uma letra ou underline
- O nome de uma variável não pode começar com um número
- Um nome de variável só pode conter caracteres alfanuméricos e underlines (A-z, 0-9 e \_ )
- O interpretador Python diferencia maiúsculas de minúsculas (nome, nome, nome e PRIMEIRO NOME) são variáveis diferentes) então tome cuidado com isso.
Aqui estão alguns exemplos de nomes de variáveis válidos:
```shell
firstname
lastname
age
country
city
first_name
last_name
capital_city
_if # if we want to use reserved word as a variable
year_2021
year2021
current_year_2021
birth_year
num1
num2
```
Nomes invalidos de variaveis
```shell
first-name
first@name
first$name
num-1
1num
```
Usaremos o estilo de nomenclatura de variáveis Python padrão que foi adotado por muitos desenvolvedores Python. Os desenvolvedores Python usam a convenção de nomenclatura de variáveis snake case (snake_case). Usamos underline após cada palavra para uma variável contendo mais de uma palavra (por exemplo, primeiro_nome, sobrenome, velocidade_de_rotação_do_motor). O exemplo abaixo é um exemplo de nomenclatura padrão de variáveis, o underline é necessário quando o nome da variável tem mais de uma palavra (isso é uma boa prática).
Quando atribuímos um determinado tipo de dado a uma variável, isso é chamado de declaração de variável. Por exemplo, no exemplo abaixo, meu primeiro nome é atribuído a uma variável first_name. O sinal de igual é um operador de atribuição. Atribuir significa armazenar dados na variável (dar um valor a uma variavel). O sinal de igual em Python não é igualdade como em Matemática.
_Exemplo:_
```py
# Variables in Python
first_name = 'Asabeneh'
last_name = 'Yetayeh'
country = 'Finland'
city = 'Helsinki'
age = 250
is_married = True
skills = ['HTML', 'CSS', 'JS', 'React', 'Python']
person_info = {
'firstname':'Asabeneh',
'lastname':'Yetayeh',
'country':'Finland',
'city':'Helsinki'
}
```
Vamos usar as funções _print()_ e _len()_. A função de impressão aceita um número ilimitado de argumentos. Um argumento é um valor que podemos passar ou colocar entre parênteses, veja o exemplo abaixo.
**Exemplo:**
```py
print('Hello, World!') # The text Hello, World! is an argument
print('Hello',',', 'World','!') # it can take multiple arguments, four arguments have been passed
print(len('Hello, World!')) # it takes only one argument
```
Vamos imprimir e também encontrar o comprimento das variáveis declaradas no topo:
**Exemplo:**
```py
# Printing the values stored in the variables
print('First name:', first_name)
print('First name length:', len(first_name))
print('Last name: ', last_name)
print('Last name length: ', len(last_name))
print('Country: ', country)
print('City: ', city)
print('Age: ', age)
print('Married: ', is_married)
print('Skills: ', skills)
print('Person information: ', person_info)
```
### Declarando múltiplas variaveis em uma linha
Múltiplas variáveis também podem ser declaradas em uma linha:
**Exemplo:**
```py
first_name, last_name, country, age, is_married = 'Asabeneh', 'Yetayeh', 'Helsink', 250, True
print(first_name, last_name, country, age, is_married)
print('First name:', first_name)
print('Last name: ', last_name)
print('Country: ', country)
print('Age: ', age)
print('Married: ', is_married)
```
Podemos obter a entrada do usuário usando a função _input()_. Vamos atribuir os dados que obtemos de um usuário às variáveis first_name e age.
**Exemplo:**
```py
first_name = input('What is your name: ')
age = input('How old are you? ')
print(first_name)
print(age)
```
## Tipos de Dados
Existem vários tipos de dados no Python. Para identificar o tipo de dados, usamos a função _type_. Gostaria de pedir que você se concentrasse em compreender muito bem os diferentes tipos de dados. Quando se trata de programação, tudo se resume a tipos de dados. Introduzi os tipos de dados logo no início e depois veremos de novo, porque cada tópico está relacionado aos tipos de dados. Abordaremos os tipos de dados com mais detalhes em suas respectivas seções.
## Checando tipos de dados e Casting
- Checando tipos de dados: Para verificar o tipo de dados de determinados dados/variáveis, usamos o _type_
**Exemplo:**
```py
# Different python data types
# Let's declare variables with various data types
first_name = 'Asabeneh' # str
last_name = 'Yetayeh' # str
country = 'Finland' # str
city= 'Helsinki' # str
age = 250 # int, it is not my real age, don't worry about it
# Printing out types
print(type('Asabeneh')) # str
print(type(first_name)) # str
print(type(10)) # int
print(type(3.14)) # float
print(type(1 + 1j)) # complex
print(type(True)) # bool
print(type([1, 2, 3, 4])) # list
print(type({'name':'Asabeneh','age':250, 'is_married':250})) # dict
print(type((1,2))) # tuple
print(type(zip([1,2],[3,4]))) # set
```
- Type Casting: Podemos converter um tipo de dado em outro tipo de dado. Nós podemos usar esses tipos para fazer o casting _int()_, _float()_, _str()_, _list_, _set_
Quando fazemos operações aritméticas, os números das strings devem ser primeiro convertidos para int ou float, caso contrário, retornará um erro. Se concatenarmos um número com uma string, o número deverá primeiro ser convertido em uma string. Falaremos sobre concatenação na seção String.
**Exemplo:**
```py
# int to float
num_int = 10
print('num_int',num_int) # 10
num_float = float(num_int)
print('num_float:', num_float) # 10.0
# float to int
gravity = 9.81
print(int(gravity)) # 9
# int to str
num_int = 10
print(num_int) # 10
num_str = str(num_int)
print(num_str) # '10'
# str to int or float
num_str = '10.6'
print('num_int', int(num_str)) # 10
print('num_float', float(num_str)) # 10.6
# str to list
first_name = 'Asabeneh'
print(first_name) # 'Asabeneh'
first_name_to_list = list(first_name)
print(first_name_to_list) # ['A', 's', 'a', 'b', 'e', 'n', 'e', 'h']
```
## Numeros
Numeros e tipos de dados em python:
1. Inteiros: Inteiros são considerados os(negativos, zero números positivos)
Exemplo:
... -3, -2, -1, 0, 1, 2, 3 ...
2. Float(Números Decimais)
Exemplo:
... -3.5, -2.25, -1.0, 0.0, 1.1, 2.2, 3.5 ...
3. Números Complexos
Exemplo:
1 + j, 2 + 4j, 1 - 1j
🌕 Você é incrível. Você acabou de completar os desafios do dia 2 e está dois passos à frente no caminho para a grandeza. Agora faça alguns exercícios para o cérebro e os músculos.
## 💻 Exercicios - Dia 2
### Exercicios: Level 1
1. Dentro de 30DiasDePython crie uma pasta chamada dia_2. Dentro desta pasta crie um arquivo chamado variáveis.py
2. Escreva um comentário em python dizendo: 'Dia 2/30 dias de programação em python'
3. Declare uma variável de primeiro nome e atribua um valor a ela
4. Declare uma variavel de sobrenome e atribua um valor a ela
5. Declare uma variavel de nome completo e atribua um valor a ela
6. Declare uma variavel do seu país e atribua um valor a ela
7. Declare uma variavel da sua cidade e atribua um valor a ela
8. Declare uma variavel da sua idade e atribua um valor a ela
9. Declare uma variavel ano e atribua um valor a ela
10. Declare uma variavel is_married e atribua um valor a ela
11. Declare uma variavel is_true e atribua um valor a ela
12. Declare uma variavel is_light_on e atribua um valor a ela
13. Declare multiplas variaveis em uma linha
### Exercicios: Level 2
1. Verifique o tipo de dados de todas as suas variáveis usando a função integrada type()
1. Usando a função integrada _len()_, encontre o comprimento do seu primeiro nome
1. Compare o comprimento do seu nome e do seu sobrenome
1. Declare 5 como num_one e 4 como num_two
1. Adicione num_one e num_two e atribua o valor a uma variável total
2. Subtraia num_two de num_one e atribua o valor a uma variável diff
3. Multiplique num_two e num_one e atribua o valor a um produto variável
4. Divida num_one por num_two e atribua o valor a uma divisão variável
5. Use a divisão de módulo para encontrar num_dois dividido por num_um e atribua o valor a uma variável restante
6. Calcule num_one elevado a num_two e atribua o valor a uma variável exp
7. Encontre a divisão mínima de num_one por num_two e atribua o valor a uma variável floor_division
2. O raio de um círculo é de 30 metros.
1. Calcule a área de um círculo e atribua o valor a um nome de variável de _area_of_circle_
2. Calcule a circunferência de um círculo e atribua o valor a um nome de variável _circum_of_circle_
3. Pegue o raio como entrada do usuário e calcule a área.
1. Use a função de entrada integrada para obter nome, sobrenome, país e idade de um usuário e armazenar o valor em seus nomes de variáveis correspondentes
1. Execute help('keywords') no Python shell ou em seu arquivo para verificar as palavras ou palavras-chave reservadas do Python
🎉 PARABÉNS ! 🎉
[<< Day 1](../README.md) | [Day 3 >>](../03_Day_Operators/03_operators.md)
================================================
FILE: Portuguese/README.md
================================================
# 🐍 30 Dias de python
|# Day | Topics |
|------|:---------------------------------------------------------:|
| 01 | [Introdução](./readme.md)|
| 02 | [Variaveis, Built-in Functions](./02_Dia_Variaveis_BuiltIn_Functions/README.md)|
| 03 | [Operadores](./03_Day_Operators/03_operators.md)|
| 04 | [Strings](./04_Day_Strings/04_strings.md)|
| 05 | [Listas](./05_Day_Lists/05_lists.md)|
| 06 | [Tuplas](./06_Day_Tuples/06_tuples.md)|
| 07 | [Conjuntos](./07_Day_Sets/07_sets.md)|
| 08 | [Dicionários](./08_Day_Dictionaries/08_dictionaries.md)|
| 09 | [Condicionais](./09_Day_Conditionals/09_conditionals.md)|
| 10 | [Loops](./10_Day_Loops/10_loops.md)|
| 11 | [Funções](./11_Day_Functions/11_functions.md)|
| 12 | [Modulos](./12_Day_Modules/12_modules.md)|
| 13 | [Compreensão de Listas](./13_Day_List_comprehension/13_list_comprehension.md)|
| 14 | [Higher Order Functions](./14_Day_Higher_order_functions/14_higher_order_functions.md)|
| 15 | [Tripos de Erros](./15_Day_Python_type_errors/15_python_type_errors.md)|
| 16 | [Python Date time](./16_Day_Python_date_time/16_python_datetime.md) |
| 17 | [Manipulação de Excessão](./17_Day_Exception_handling/17_exception_handling.md)|
| 18 | [Regex (Expressões Regulares)](./18_Day_Regular_expressions/18_regular_expressions.md)|
| 19 | [Manipulação De Arquivos](./19_Day_File_handling/19_file_handling.md)|
| 20 | [Gerenciador De Pacotes](./20_Day_Python_package_manager/20_python_package_manager.md)|
| 21 | [Classes e Objetos](./21_Day_Classes_and_objects/21_classes_and_objects.md)|
| 22 | [Web Scraping](./22_Day_Web_scraping/22_web_scraping.md)|
| 23 | [Ambiente Virtual](./23_Day_Virtual_environment/23_virtual_environment.md)|
| 24 | [Estatisticas](./24_Day_Statistics/24_statistics.md)|
| 25 | [Pandas](./25_Day_Pandas/25_pandas.md)|
| 26 | [Python web](./26_Day_Python_web/26_python_web.md)|
| 27 | [Python com MongoDB](./27_Day_Python_with_mongodb/27_python_with_mongodb.md)|
| 28 | [API](./28_Day_API/28_API.md)|
| 29 | [Construindo API's](./29_Day_Building_API/29_building_API.md)|
| 30 | [Conclusão](./30_Day_Conclusions/30_conclusions.md)|
🧡🧡🧡 CODANDO FELIZ 🧡🧡🧡
Ajudem o autor a criar mais materiais educacionais
[Dia 2 >>](./02_Dia_Variaveis_BuiltIn_Functions/README.md)

- [🐍 30 Dias de python](#-30-dias-de-python)
- [📘 Dia 1](#-dia-1)
- [Bem Vindo!](#bem-vindo)
- [Introdução](#introdução)
- [Por quê Python?](#por-quê-python)
- [Setup do ambiente](#setup-do-ambiente)
- [Instalando o Python](#instalando-o-python)
- [Python Shell](#python-shell)
- [Instalando o Visual Studio Code](#instalando-o-visual-studio-code)
- [Como usar o Visual Studio Code](#como-usar-o-visual-studio-code)
- [Basico de Python](#basico-de-python)
- [Sintaxe do Python](#sintaxe-do-python)
- [Identação do Python](#identação-do-python)
- [Comentários](#comentários)
- [Tipos de dados](#tipos-de-dados)
- [Números](#números)
- [Strings](#strings)
- [Booleanos](#booleanos)
- [Listas](#listas)
- [Dicionário](#dicionário)
- [Tupla](#tupla)
- [Set](#set)
- [Checando Tipos de Dados](#checando-tipos-de-dados)
- [Arquivo Python](#arquivo-python)
- [💻 Exercicios - Dia 1](#-exercicios---dia-1)
- [Exercicio: Level 1](#exercicio-level-1)
- [Exercicio: Level 2](#exercicio-level-2)
- [Exercicio: Level 3](#exercicio-level-3)
# 📘 Dia 1
## Bem Vindo!
**Parabéns** por decidir participar do desafio de programação _30 dias de Python_ . E nesse desafio você vai aprender tudo o que você precisa para se tornar um programador python e todo o conceito de programação. No final do desafio você receberá o certificado do desafio de programação _30DiasDePython_.
Se você quiser se envolver ativamente no desafio, você pode se juntar ao grupo do telegram [30DaysOfPython challenge](https://t.me/ThirtyDaysOfPython).
## Introdução
Python é uma linguagem de programação de alto nível para programação de uso geral. É uma linguagem de programação de código aberto, interpretada e orientada a objetos. Python foi criado por um programador holandês, Guido van Rossum. O nome da linguagem de programação Python foi derivado de uma série de comédia britânica, _Monty Python's Flying Circus_. A primeira versão foi lançada em 20 de fevereiro de 1991. Este desafio de 30 dias de Python irá ajudá-lo a aprender a versão mais recente do Python, Python 3, passo a passo. Os tópicos são divididos em 30 dias, onde cada dia contém diversos tópicos com explicações fáceis de entender, exemplos do mundo real, muitos exercícios práticos e projetos.
Este desafio foi desenvolvido para iniciantes e profissionais que desejam aprender a linguagem de programação python. Pode levar de 30 a 100 dias para completar o desafio, as pessoas que participam ativamente do grupo de telegramas têm grande probabilidade de completar o desafio.
Este desafio é fácil de ler, escrito originalmente em inglês coloquial e traduzido para um português, envolvente, motivador e ao mesmo tempo muito exigente. Você precisa destinar muito tempo para terminar este desafio. Se você é um dos que aprendem melhor vendo, você pode assistir às vídeo-aulas em
Canal do Youtube do Washera Você pode começar pelo [Video de Python para iniciantes absolutos](https://youtu.be/OCCWZheOesI). Se inscreva no canal, comente suas dúvidas nos vídeos do YouTube e seja proativo, o autor eventualmente notará você.
O autor gosta de ouvir sua opinião sobre o desafio, compartilhe o artigo do autor dando um feedback com sua opinião sobre o desafio 30DiasDePython. E você pode deixar seu feedback sobre o artigo em: [link](https://www.asabeneh.com/testimonials)
## Por quê Python?
É uma linguagem de programação muito próxima da linguagem humana, com uma sintaxe simples! e por isso fácil de aprender e usar.
Python é usado por vários setores e empresas (incluindo o Google). Ele tem sido usado para desenvolver aplicações web, aplicativos de desktop, administração de sistemas e bibliotecas de machine learning. Python é uma linguagem altamente adotada na comunidade de data science e machine learning. Espero que isso seja suficiente para convencê-lo a começar a aprender Python.
## Setup do ambiente
### Instalando o Python
Para executar um script escrito em Python, você precisa instalar o Python. Vamos para a página [download](https://www.python.org/) python.
Se você for um usuario de windows. Clique no botão circulado em vermelho.
[](https://www.python.org/)
Se você for um usuário de MacOs. Clique no botão circulado em vermelho.
[](https://www.python.org/)
Para verificar se o python está instalado, digite o seguinte comando no terminal do seu dispositivo.
```shell
python --version
```

Como você pode ver no terminal, estou usando a versão _Python 3.7.5_ no momento. Sua versão do Python pode ser diferente da minha, mas deve ser 3.6 ou superior. Se você conseguir ver a versão python, muito bem. Python foi instalado em sua máquina. Continue para a próxima seção.
### Python Shell
Python é uma linguagem de script interpretada, portanto não precisa ser compilada. Isso significa que executa o código linha por linha. O Python vem com um _Python Shell (Shell Interativo do Python)_, também conhecido como REPL (Read Eval Print Loop). E é usado para executar um único comando python e obter o resultado.
O Python Shell aguarda o código Python do usuário. Ao inserir o código, ele o interpreta e mostra o resultado na próxima linha.
Abra seu terminal ou prompt de comando (cmd) e escreva:
```shell
python
```

O shell interativo do Python é aberto e aguarda que você escreva o código em Python (script Python). E você escreverá seu script Python próximo a este símbolo >>> e clique em Enter.
Vamos escrever nosso primeiro scripts no shell de script Python.

Muito bem, você escreveu seu primeiro script Python no shell interativo Python. Como fechamos o shell interativo do Python?
Para fechar o shell, próximo a este símbolo >> escreva o comando **exit()** e pressione Enter.

Agora você sabe como abrir o shell interativo do Python e como sair dele.
Python fornecerá resultados se você escrever scripts que Python entenda; caso contrário, retornará erros. Vamos cometer um erro proposital e ver o que o Python retornará.

Como você pode ver no erro retornado, Python é tão inteligente que sabe o erro que cometemos e que foi _Syntax Error: Invalid Syntax_. Usar x como multiplicação em Python é um erro de sintaxe porque (x) não é uma sintaxe válida em Python. Em vez de (**x**) usamos asterisco (*) para multiplicação. O erro retornado mostra claramente o que corrigir.
O processo de identificação e remoção de erros de um programa é chamado de _depuração_. Vamos depurá-lo colocando * no lugar de **x**.

Nosso bug foi corrigido, o código foi executado e obtivemos o resultado que esperávamos. Como programador, você verá esse tipo de erro diariamente. É bom saber como depurar. Para ser bom em depuração, você deve entender que tipo de erros está enfrentando. Alguns dos erros do Python que você pode encontrar são _SyntaxError_, _IndexError_, _NameError_, _ModuleNotFoundError_, _KeyError_, _ImportError_, _AttributeError_, _TypeError_, _ValueError_, _ZeroDivisionError_ etc. Veremos mais sobre diferentes tipos de erros no Python mais tarde, em outras seções!
Vamos praticar mais como usar o shell interativo Python. Vá para o seu terminal ou prompt de comando e escreva a palavra **python**.

O shell interativo do Python é aberto. Vamos fazer algumas operações matemáticas básicas (adição, subtração, multiplicação, divisão, módulo, exponencial).
Vamos fazer algumas contas antes de escrever qualquer código Python:
- 2 + 3 is 5
- 3 - 2 is 1
- 3 \* 2 is 6
- 3 / 2 is 1.5
- 3 ** 2 is the same as 3 * 3
Em python temos as seguintes operações adicionais:
- 3 % 2 = 1 => que significa encontrar o resto ou (módulo da divisão)
- 3 // 2 = 1 => que significa remover o resto da divisão
Vamos mudar as expressões matemáticas acima para código Python. O shell Python foi aberto e vamos escrever um comentário logo no início do shell.
Um _comentário_ é uma parte do código que não é executada por python o comentário é ignorado pelo interpretador Python. Portanto, podemos deixar algum texto em nosso código para torná-lo mais legível. Python não executa a parte de comentários. Um comentário em python começa com o símbolo hash(#).
É assim que você escreve um comentário em python:
```shell
# comment starts with hash
# this is a python comment, because it starts with a (#) symbol
```

Antes de passarmos para a próxima seção, vamos praticar mais no shell interativo do Python. Feche o shell aberto escrevendo _exit()_ no shell e abra-o novamente e vamos praticar como escrever um texto no shell Python.

### Instalando o Visual Studio Code
O shell interativo Python é bom para testar pequenos códigos de script, mas não será para um grande projeto. No ambiente de trabalho real, os desenvolvedores usam diferentes editores de código para escrever códigos. Neste desafio de programação de 30 dias De Python usaremos código do visual studio. O Visual Studio Code é um editor de texto de código aberto muito popular. Sou fã do vscode e recomendo [download](https://code.visualstudio.com/) visual studio code, mas se você é a adépito a outros editores, fique à vontade para seguir com o que tiver.
[](https://code.visualstudio.com/)
Se você instalou o Visual Studio Code, vamos ver como usá-lo.
Se preferir um vídeo, você pode seguir este tutorial da instalação e configuração do Visual Studio Code para Python [Video tutorial](https://www.youtube.com/watch?v=bn7Cx4z-vSo)
#### Como usar o Visual Studio Code
Abra o visual studio code clicando duas vezes no ícone do visual studio. Ao abri-lo, você obterá esse tipo de interface. Tente interagir com os ícones rotulados.

Crie uma pasta chamada 30DiasDePython no seu desktop. Em seguida, abra-a usando o visual studio code.


Após abri-lo você verá atalhos para criação de arquivos e pastas dentro do diretório do projeto 30DiasDePython. Como você pode ver abaixo, criei o primeiro arquivo, helloworld.py. Você pode fazer o mesmo.

Depois de um longo dia codando, você deseja fechar seu editor de código fonte, certo? É assim que você fechará o projeto aberto.

Parabéns, você concluiu a configuração do ambiente de desenvolvimento. Vamos começar a codar.
## Basico de Python
### Sintaxe do Python
Um script Python pode ser escrito no shell interativo Python ou no editor de código. Um arquivo Python possui uma extensão .py.
### Identação do Python
Uma identação é um espaço em branco em um texto. A identação em muitas linguagens é usada para aumentar a legibilidade do código, mas o Python usa a identação para criar blocos de códigos. Em outras linguagens de programação, chaves são usadas para criar blocos de códigos em vez de a identação. Um dos bugs comuns ao escrever código um python é o erro de identação.

### Comentários
Os comentários são muito importantes para tornar o código mais legível e para deixar comentários em nosso código. Python não executa partes de comentários do nosso código.
Qualquer texto que comece com hash(#) em Python é um comentário.
**Exemplo: de um comentário de uma linha**
```shell
# This is the first comment
# This is the second comment
# Python is eating the world
```
**Exemplo: de um Comentário de multiplas linhas conhecido como docstring**
Aspas triplas podem ser usadas para comentários de múltiplas linhas se não estiverem atribuídas a uma variável
```shell
"""This is multiline comment
multiline comment takes multiple lines.
python is eating the world
"""
```
### Tipos de dados
Em Python existem vários tipos de dados. Vamos começar com os mais comuns. Diferentes tipos de dados serão abordados em detalhes em outras seções. Por enquanto, vamos examinar os diferentes tipos de dados e nos familiarizar com eles. Você não precisa ter um entendimento claro agora.
#### Números
- Inteiro: É considerado Inteiro(números negativos, zero e positivos)
Exemplo:
... -3, -2, -1, 0, 1, 2, 3 ...
- Float: Números decimais
Exemplo:
... -3.5, -2.25, -1.0, 0.0, 1.1, 2.2, 3.5 ...
- Complexos
Exemplo:
1 + j, 2 + 4j
#### Strings
Uma coleção de um ou mais caracteres entre aspas simples ou duplas são considerados strings. Se uma string tiver mais de uma frase, usamos aspas triplas.
**Exemplo:**
```py
'Asabeneh'
'Finland'
'Python'
'I love teaching'
'I hope you are enjoying the first day of 30DaysOfPython Challenge'
```
#### Booleanos
Um tipo de dado booleano é um valor True ou False. T e F devem estar sempre maiúsculos.
**Exemplo:**
```python
True # Is the light on? If it is on, then the value is True
False # Is the light on? If it is off, then the value is False
```
#### Listas
A lista em Python é uma coleção ordenada que permite armazenar itens de diferentes tipos de dados. Uma lista é semelhante a um array em JavaScript.
**Exemplo:**
```py
[0, 1, 2, 3, 4, 5] # all are the same data types - a list of numbers
['Banana', 'Orange', 'Mango', 'Avocado'] # all the same data types - a list of strings (fruits)
['Finland','Estonia', 'Sweden','Norway'] # all the same data types - a list of strings (countries)
['Banana', 10, False, 9.81] # different data types in the list - string, integer, boolean and float
```
#### Dicionário
Um objeto de dicionário Python é uma coleção não ordenada de dados em um formato de par de valores-chave.
**Exemplo:**
```py
{
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'country':'Finland',
'age':250,
'is_married':True,
'skills':['JS', 'React', 'Node', 'Python']
}
```
#### Tupla
Uma tupla é uma coleção ordenada de diferentes tipos de dados, como uma lista, mas as tuplas não podem ser modificadas (são imutáveis) depois de criadas. Eles são imutáveis.
**Exemplo:**
```py
('Asabeneh', 'Pawel', 'Brook', 'Abraham', 'Lidiya') # Names
```
```py
('Earth', 'Jupiter', 'Neptune', 'Mars', 'Venus', 'Saturn', 'Uranus', 'Mercury') # planets
```
#### Set
O set é uma coleção de tipos de dados semelhantes a uma lista e uma tupla. Ao contrário da lista e da tupla, set não é uma coleção ordenada de itens. Como na matemática, o conjunto em Python armazena apenas itens exclusivos.
Nas seções posteriores, entraremos em detalhes sobre cada tipo de dados Python.
**Exemplo:**
```py
{2, 4, 3, 5}
{3.14, 9.81, 2.7} # order is not important in set
```
### Checando Tipos de Dados
Para checar um determinado tipo de dado dados/variáveis, usamos a função **type**. No terminal a seguir você verá diferentes tipos de dados python:

### Arquivo Python
Primeiro abra a pasta do seu projeto, 30DiasDePython. Se você não tiver essa pasta, crie um nome de pasta chamada 30DiasDePython. Dentro desta pasta, crie um arquivo chamado helloworld.py. Agora, vamos fazer o que fizemos no shell interativo python usando o visual studio code.
O shell interativo do Python estava imprimindo sem usar **print** mas no visual studio code para ver nosso resultado deveríamos usar uma função integrada _print(). A função interna _print()_ recebe um ou mais argumentos da seguinte maneira _print('arument1', 'argument2', 'argument3')_. Veja os exemplos abaixo.
**Exemplo:**
O nome do arquivo é helloworld.py
```py
# Day 1 - 30DaysOfPython Challenge
print(2 + 3) # addition(+)
print(3 - 1) # subtraction(-)
print(2 * 3) # multiplication(*)
print(3 / 2) # division(/)
print(3 ** 2) # exponential(**)
print(3 % 2) # modulus(%)
print(3 // 2) # Floor division operator(//)
# Checking data types
print(type(10)) # Int
print(type(3.14)) # Float
print(type(1 + 3j)) # Complex number
print(type('Asabeneh')) # String
print(type([1, 2, 3])) # List
print(type({'name':'Asabeneh'})) # Dictionary
print(type({9.8, 3.14, 2.7})) # Set
print(type((9.8, 3.14, 2.7))) # Tuple
```
Para executar o arquivo python verifique a imagem abaixo. Você pode executar o arquivo python executando o botão verde em Visual Studio Code ou digitando _python helloworld.py_ no seu terminal.

🌕 Você é incrível. Você acabou de completar o desafio do primeiro dia e está a caminho da grandeza. Agora faça alguns exercícios para o cérebro e os músculos.
## 💻 Exercicios - Dia 1
### Exercicio: Level 1
1. Cheque a versão do python que você esta usando
2. Abra o shell interativo python e execute as seguintes operações. Os operandos são 3 e 4.
- adição(+)
- subtração(-)
- multiplicação(\*)
- modulo(%)
- divisão(/)
- exponencial(\*\*)
- Divisão inteira(//)
3. Escreva strings no shell interativo python. As strings são as seguintes:
- Seu nome
- Seu sobrenome
- Seu país
- Eu estou aproveitando o 30 dias de python
4. Verifique os tipos de dados dos seguintes dados:
- 10
- 9.8
- 3.14
- 4 - 4j
- ['Asabeneh', 'Python', 'Finland']
- Seu nome
- O seu sobrenome
- Seu país
### Exercicio: Level 2
1. Crie uma pasta chamada dia_1 dentro da pasta 30DiasDePython. Dentro da pasta day_1, crie um arquivo python helloworld.py e repita as perguntas 1, 2, 3 e 4. Lembre-se de usar _print()_ quando estiver trabalhando em um arquivo python. Navegue até o diretório onde você salvou seu arquivo e execute-o.
### Exercicio: Level 3
1. Escreva um exemplo para diferentes tipos de dados Python, como Número (Inteiro, Flutuante, Complex), Strings, Booleanos, Listas, Tuplas, Set e Dicionário.
2. Ache a [Distancia Euclidiana](https://en.wikipedia.org/wiki/Euclidean_distance#:~:text=In%20mathematics%2C%20the%20Euclidean%20distance,being%20called%20the%20Pythagorean%20distance.) entre (2, 3) e (10, 8)
🎉 PARABÉNS ! 🎉
[Day 2 >>](./02_Dia_Variaveis_BuiltIn_Functions/README.md)
================================================
FILE: Spanish/01_Day_Introduction/helloworld.py
================================================
# Introducción
# Día 1 - Desafío 30DaysOfPython
print(2 + 3) # suma(+)
print(3 - 1) # resta(-)
print(2 * 3) # multiplicación(*)
print(3 / 2) # división(/)
print(3 ** 2) # exponencial(**)
print(3 % 2) # módulo(%)
print(3 // 2) # División de piso(//)
# Comprobando los tipos de datos
print(type(10)) # Int
print(type(3.14)) # Float
print(type(1 + 3j)) # Complejo
print(type('Asabeneh')) # Cadena
print(type([1, 2, 3])) # Lista
print(type({'name':'Asabeneh'})) # Diccionario
print(type({9.8, 3.14, 2.7})) # Conjunto
print(type((9.8, 3.14, 2.7))) # Tupla
================================================
FILE: Spanish/02_Day_Variables_builtin_functions/02_variables_builtin_functions.md
================================================
30 Dias de Python: Dia 2 - Variables, Funciones integradas
[<< Dia 1](../readme.md) | [Dia 3 >>](../03_Day_Operators/03_operators.md)

- [📘 Día 2](#-día-2)
- [Funciones integradas](#funciones-integradas)
- [Variables](#variables)
- [Declaración de múltiples variables en una línea](#declaración-de-múltiples-variables-en-una-línea)
- [Tipos de datos](#tipos-de-datos)
- [Comprobación de tipos de datos y conversión](#comprobación-de-tipos-de-datos-y-conversión)
- [Números](#números)
- [💻 Ejercicios - Día 2](#💻-ejercicios---día-2)
- [Ejercicios: Nivel 1](#ejercicios-nivel-1)
- [Ejercicios: Nivel 2](#ejercicios-nivel-2)
# 📘 Dia 2
## Funciones integradas
En Python tenemos muchas funciones integradas. Las funciones integradas están disponibles globalmente para su uso, lo que significa que puede hacer uso de las funciones integradas sin importarlas ni configurarlas. Algunas de las funciones integradas de Python más utilizadas son las siguientes: _print()_, _len()_, _type()_, _int()_, _float()_, _str()_, _input()_, _list()_, _dict()_, _min()_, _max()_, _sum()_, _sorted()_, _open()_, _file()_, _help()_ y _dir()_ . En la siguiente tabla, verá una lista exhaustiva de las funciones integradas de Python sacadas de la [documentación de Python](https://docs.python.org/3.9/library/functions.html).

Abramos el shell de Python y comencemos a usar algunas de las funciones integradas más comunes.

Practiquemos más usando diferentes funciones integradas

Como puede ver en la terminal de arriba, Python tiene palabras reservadas. No usamos palabras reservadas para declarar variables o funciones. En la siguiente sección cubriremos las variables.
Creo que a estas alturas ya está familiarizado con las funciones integradas. Hagamos una práctica más de funciones integradas y pasaremos a la siguiente sección.

## Variables
Las variables almacenan datos en la memoria de una computadora. Se recomienda el uso de variables mnemotécnicas en muchos lenguajes de programación. Una variable mnemotécnica es un nombre de variable que se puede recordar y asociar fácilmente. Una variable se refiere a una dirección de memoria en la que se almacenan los datos.
Número al principio, carácter especial o guión no están permitidos al nombrar una variable. Una variable puede tener un nombre corto (como x, y, z), pero se recomienda enfáticamente un nombre más descriptivo (nombre, apellido, edad, país).
Reglas de nombres de variables de Python
- Un nombre de variable debe comenzar con una letra o el carácter de subrayado
- Un nombre de variable no puede comenzar con un número
- Un nombre de variable solo puede contener caracteres alfanuméricos y guiones bajos (A-z, 0-9 y \_)
- Los nombres de las variables distinguen entre mayúsculas y minúsculas (firstname, Firstname, FirstName y FIRSTNAME) son variables diferentes)
Estos son algunos ejemplos de nombres de variables válidos:
```shell
firstname
lastname
age
country
city
first_name
last_name
capital_city
_if # si queremos usar palabra reservada como variable
year_2021
year2021
current_year_2021
birth_year
num1
num2
```
Nombres de variables no válidos
```shell
first-name
first@name
first$name
num-1
1num
```
Usaremos el estilo estándar de nomenclatura de variables de Python que ha sido adoptado por muchos desarrolladores de Python. Los desarrolladores de Python usan la convención de nomenclatura de variables de caja de serpiente (snake_case). Usamos un carácter de subrayado después de cada palabra para una variable que contiene más de una palabra (p. ej., nombre, apellido, velocidad de rotación del motor). El siguiente ejemplo es un ejemplo de nomenclatura estándar de variables, se requiere guión bajo cuando el nombre de la variable es más de una palabra.
Cuando asignamos un determinado tipo de datos a una variable, se llama declaración de variable. Por ejemplo, en el siguiente ejemplo, mi nombre se asigna a una variable first_name. El signo igual es un operador de asignación. Asignar significa almacenar datos en la variable. El signo igual en Python no es la igualdad como en Matemáticas.
_Ejemplo:_
```py
# Variables en Python
first_name = 'Asabeneh'
last_name = 'Yetayeh'
country = 'Finland'
city = 'Helsinki'
age = 250
is_married = True
skills = ['HTML', 'CSS', 'JS', 'React', 'Python']
person_info = {
'firstname':'Asabeneh',
'lastname':'Yetayeh',
'country':'Finland',
'city':'Helsinki'
}
```
Usemos las funciones integradas _print()_ y _len()_. La función de impresión toma un número ilimitado de argumentos. Un argumento es un valor que se puede pasar o poner dentro del paréntesis de la función, vea el ejemplo a continuación.
**Ejemplo:**
```py
print('Hello, World!') # El texto Hola, Mundo! es un argumento
print('Hello',',', 'World','!') # Puede tomar varios argumentos, se han pasado cuatro argumentos
print(len('Hello, World!')) # solo se necesita un argumento
```
Imprimamos y también encontremos la longitud de las variables declaradas en la parte superior:
**Ejemplo:**
```py
# Imprimiendo los valores almacenados en las variables
print('First name:', first_name)
print('First name length:', len(first_name))
print('Last name: ', last_name)
print('Last name length: ', len(last_name))
print('Country: ', country)
print('City: ', city)
print('Age: ', age)
print('Married: ', is_married)
print('Skills: ', skills)
print('Person information: ', person_info)
```
### Declaración de múltiples variables en una línea
También se pueden declarar múltiples variables en una línea:
**Ejemplo:**
```py
first_name, last_name, country, age, is_married = 'Asabeneh', 'Yetayeh', 'Helsink', 250, True
print(first_name, last_name, country, age, is_married)
print('First name:', first_name)
print('Last name: ', last_name)
print('Country: ', country)
print('Age: ', age)
print('Married: ', is_married)
```
Obtener la entrada del usuario usando la función integrada _input()_. Asignemos los datos que obtenemos de un usuario a las variables first_name y age.
**Ejemplo:**
```py
first_name = input('What is your name: ')
age = input('How old are you? ')
print(first_name)
print(age)
```
## Tipos de datos
Hay varios tipos de datos en Python. Para identificar el tipo de datos usamos la función incorporada _type_. Me gustaría pedirle que se concentre en comprender muy bien los diferentes tipos de datos. Cuando se trata de programar, todo se trata de tipos de datos. Introduje los tipos de datos desde el principio y viene de nuevo, porque todos los temas están relacionados con los tipos de datos. Cubriremos los tipos de datos con más detalle en sus respectivas secciones.
## Comprobación de tipos de datos y conversión
- Verificar tipos de datos: para verificar el tipo de datos de ciertos datos/variables usamos el _type_
**Ejemplo:**
```py
# Diferentes tipos de datos en python
# Declaremos variables con varios tipos de datos
first_name = 'Asabeneh' # str
last_name = 'Yetayeh' # str
country = 'Finland' # str
city= 'Helsinki' # str
age = 250 # int, no es mi edad real, no te preocupes
# Imprimir tipos
print(type('Asabeneh')) # str
print(type(first_name)) # str
print(type(10)) # int
print(type(3.14)) # float
print(type(1 + 1j)) # complex
print(type(True)) # bool
print(type([1, 2, 3, 4])) # list
print(type({'name':'Asabeneh','age':250, 'is_married':250})) # dict
print(type((1,2))) # tuple
print(type(zip([1,2],[3,4]))) # set
```
- Casting: Conversión de un tipo de dato a otro tipo de dato. Usamos _int()_, _float()_, _str()_, _list_, _set_
Cuando hacemos operaciones aritméticas, los números de cadena deben convertirse primero a int o float; de lo contrario, devolverá un error. Si concatenamos un número con una cadena, el número debe convertirse primero en una cadena. Hablaremos sobre la concatenación en la sección String.
**Ejemplo:**
```py
# int a float
num_int = 10
print('num_int',num_int) # 10
num_float = float(num_int)
print('num_float:', num_float) # 10.0
# float a int
gravity = 9.81
print(int(gravity)) # 9
# int a str
num_int = 10
print(num_int) # 10
num_str = str(num_int)
print(num_str) # '10'
# str a int o float
num_str = '10.6'
print('num_int', int(num_str)) # 10
print('num_float', float(num_str)) # 10.6
# str a list
first_name = 'Asabeneh'
print(first_name) # 'Asabeneh'
first_name_to_list = list(first_name)
print(first_name_to_list) # ['A', 's', 'a', 'b', 'e', 'n', 'e', 'h']
```
## Números
Tipos de datos numéricos en Python:
1. Integers: números enteros (negativos, cero y positivos)
Ejemplo:
... -3, -2, -1, 0, 1, 2, 3...
2. Floating: números de coma (números decimales)
Ejemplo:
... -3,5, -2,25, -1,0, 0,0, 1,1, 2,2, 3,5...
3. Complex: números complejos
Ejemplo:
1 + j, 2 + 4j, 1 - 1j
🌕 Eres increíble. Acaba de completar los desafíos del día 2 y está dos pasos por delante en su camino hacia la grandeza. Ahora haz algunos ejercicios para tu cerebro y tus músculos.
## 💻 Ejercicios - Día 2
### Ejercicios: Nivel 1
1. Dentro de 30DaysOfPython crea una carpeta llamada day_2. Dentro de esta carpeta crea un archivo llamado variables.py
2. Escriba un comentario de python que diga 'Día 2: 30 días de programación en python'
3. Declarar una variable de nombre y asignarle un valor
4. Declarar una variable de apellido y asignarle un valor
5. Declare una variable de nombre completo y asígnele un valor
6. Declarar una variable de país y asignarle un valor
7. Declarar una variable de ciudad y asignarle un valor
8. Declarar una variable de edad y asignarle un valor
9. Declarar una variable de año y asignarle un valor
10. Declarar una variable is_married y asignarle un valor
11. Declarar una variable is_true y asignarle un valor
12. Declare una variable is_light_on y asígnele un valor
13. Declarar múltiples variables en una línea
### Ejercicios: Nivel 2
1. Verifique el tipo de datos de todas sus variables usando la función incorporada type()
1. Usando la función incorporada _len()_, encuentre la longitud de su nombre
1. Compara la longitud de tu nombre y tu apellido
1. Declarar 5 como num_one y 4 como num_two
1. Sume num_one y num_two y asigne el valor a un total variable
2. Reste num_two de num_one y asigne el valor a una variable diff
3. Multiplique num_two y num_one y asigne el valor a un producto variable
4. Divide num_one por num_two y asigna el valor a una división variable
5. Use la división de módulo para encontrar num_two dividido por num_one y asigne el valor a un residuo variable
6. Calcula num_one a la potencia de num_two y asigna el valor a una variable exp
7. Encuentra la división de piso de num_one por num_two y asigna el valor a una variable floor_division
1. El radio de un círculo es de 30 metros.
1. Calcule el área de un círculo y asigne el valor a una variable con el nombre de _area_of_circle_
2. Calcule la circunferencia de un círculo y asigne el valor a una variable con el nombre de _circum_of_circle_
3. Tome el radio como entrada del usuario y calcule el área.
1. Use la función de entrada integrada para obtener el nombre, el apellido, el país y la edad de un usuario y almacene el valor en sus nombres de variables correspondientes
1. Ejecute la ayuda ('palabras clave') en el shell de Python o en su archivo para verificar las palabras o palabras clave reservadas de Python
🎉 ¡FELICITACIONES! 🎉
[<< Day 1](../readme.md) | [Day 3 >>](../03_Day_Operators/03_operators.md)
================================================
FILE: Spanish/02_Day_Variables_builtin_functions/variables.py
================================================
# Variables en Python
first_name = 'Asabeneh'
last_name = 'Yetayeh'
country = 'Finland'
city = 'Helsinki'
age = 250
is_married = True
skills = ['HTML', 'CSS', 'JS', 'React', 'Python']
person_info = {
'firstname':'Asabeneh',
'lastname':'Yetayeh',
'country':'Finland',
'city':'Helsinki'
}
# Imprimir los valores almacenados en las variables
print('First name:', first_name)
print('First name length:', len(first_name))
print('Last name: ', last_name)
print('Last name length: ', len(last_name))
print('Country: ', country)
print('City: ', city)
print('Age: ', age)
print('Married: ', is_married)
print('Skills: ', skills)
print('Person information: ', person_info)
# Declarar múltiples variables en una línea
first_name, last_name, country, age, is_married = 'Asabeneh', 'Yetayeh', 'Helsink', 250, True
print(first_name, last_name, country, age, is_married)
print('First name:', first_name)
print('Last name: ', last_name)
print('Country: ', country)
print('Age: ', age)
print('Married: ', is_married)
================================================
FILE: Spanish/02_variables_builtin_functions_sp.md
================================================
30 días de Python: Día 2 - Variables y funciones integradas
[<< Día 1](./readme_sp.md) | [Día 3 >>](./03_operators_sp.md)

_Lectura aproximada: 12 min_
- [📘 Día 2](#-día-2)
- [Funciones integradas](#funciones-integradas)
- [Variables](#variables)
- [Declarar varias variables en una línea](#declarar-varias-variables-en-una-línea)
- [Tipos de datos](#tipos-de-datos)
- [Conversión de tipos de datos](#conversión-de-tipos-de-datos)
- [Números](#números)
- [💻 Ejercicios - Día 2](#-ejercicios---día-2)
- [Ejercicio: Nivel 1](#ejercicio-nivel-1)
- [Ejercicio: Nivel 2](#ejercicio-nivel-2)
# 📘 Día 2
## Funciones integradas
Python proporciona muchas funciones integradas. Las funciones integradas están disponibles a nivel global, lo que significa que puede usarlas sin importar o configurar nada. A continuación se muestran algunas de las funciones integradas más comunes de Python: _print()_, _len()_, _type()_, _int()_, _float()_, _str()_, _input()_, _list()_, _dict()_, _min()_, _max()_, _sum()_, _sorted()_, _open()_, _file()_, _help()_, _dir()_. En la tabla siguiente verá la lista completa de funciones integradas obtenida de la [documentación de Python](https://docs.python.org/3.9/library/functions.html).

Abramos el intérprete interactivo de Python y comencemos a usar algunas de las funciones integradas más comunes.

Practique más usando diferentes funciones integradas

Como se muestra arriba, Python tiene palabras reservadas. No podemos usar palabras reservadas para declarar variables o funciones. Presentaremos las variables en la sección siguiente.
Confío en que ahora esté familiarizado con las funciones integradas. Practiquemos más con ellas antes de continuar a la siguiente sección.

## Variables
Las variables almacenan datos en la memoria del ordenador. En muchos lenguajes de programación se recomienda usar nombres de variables mnemotécnicos. Un nombre mnemotécnico es un nombre de variable fácil de recordar y asociar. Una variable hace referencia a la dirección de memoria donde se almacena un dato.
Al nombrar variables, no se permite empezar con un número, usar caracteres especiales ni guiones. Una variable puede tener un nombre corto (por ejemplo x, y, z), pero se recomienda encarecidamente usar nombres más descriptivos (nombre, apellido, edad, país).
Reglas para nombres de variables en Python
- El nombre de la variable debe comenzar con una letra o un guion bajo
- El nombre de la variable no puede comenzar con un número
- El nombre de la variable sólo puede contener caracteres alfanuméricos y guiones bajos (A-z, 0-9 y _)
- Los nombres de variables distinguen mayúsculas de minúsculas (firstname, Firstname, FirstName y FIRSTNAME son variables diferentes)
A continuación algunos ejemplos de nombres válidos:
```shell
firstname
lastname
age
country
city
first_name
last_name
capital_city
_if # si queremos usar una palabra reservada como variable
year_2021
year2021
current_year_2021
birth_year
num1
num2
```
Nombres de variables inválidos
```shell
first-name
first@name
first$name
num-1
1num
```
Usaremos la convención de nombres estándar adoptada por muchos desarrolladores de Python. Los desarrolladores de Python usan la convención snake_case. Para variables que contienen varias palabras usamos guiones bajos entre las palabras (por ejemplo first_name, last_name, engine_rotation_speed). El siguiente ejemplo muestra la convención estándar: cuando el nombre de la variable contiene más de una palabra, se deben usar guiones bajos.
Cuando asignamos un valor a una variable, esto se llama declarar una variable. Por ejemplo, en el siguiente ejemplo mi nombre se asigna a la variable first_name. El signo igual es el operador de asignación. Asignar significa almacenar un dato en una variable. El signo igual en Python no es el mismo que en matemáticas.
_Ejemplo:_
```py
# Variables en Python
first_name = 'Asabeneh'
last_name = 'Yetayeh'
country = 'Finland'
city = 'Helsinki'
age = 250
is_married = True
skills = ['HTML', 'CSS', 'JS', 'React', 'Python']
person_info = {
'firstname':'Asabeneh',
'lastname':'Yetayeh',
'country':'Finland',
'city':'Helsinki'
}
```
Usemos las funciones integradas _print()_ y _len()_. La función print puede aceptar un número ilimitado de argumentos. Un argumento es un valor que podemos pasar dentro de los paréntesis de la función; vea el ejemplo a continuación.
**Ejemplo:**
```py
print('Hello, World!') # The text Hello, World! is an argument
print('Hello',',', 'World','!') # it can take multiple arguments, four arguments have been passed
print(len('Hello, World!')) # it takes only one argument
```
Imprimamos y calculemos la longitud de las variables declaradas arriba:
**Ejemplo:**
```py
# Imprimir valores de las variables
print('First name:', first_name)
print('First name length:', len(first_name))
print('Last name: ', last_name)
print('Last name length: ', len(last_name))
print('Country: ', country)
print('City: ', city)
print('Age: ', age)
print('Married: ', is_married)
print('Skills: ', skills)
print('Person information: ', person_info)
```
### Declarar varias variables en una línea
También se pueden declarar múltiples variables en la misma línea:
**Ejemplo:**
```py
first_name, last_name, country, age, is_married = 'Asabeneh', 'Yetayeh', 'Helsink', 250, True
print(first_name, last_name, country, age, is_married)
print('First name:', first_name)
print('Last name: ', last_name)
print('Country: ', country)
print('Age: ', age)
print('Married: ', is_married)
```
Use la función integrada _input()_ para obtener entrada del usuario. Asignemos los datos ingresados por el usuario a las variables first_name y age.
.
**Ejemplo:**
```py
first_name = input('What is your name: ')
age = input('How old are you? ')
print(first_name)
print(age)
```
## Tipos de datos
Hay varios tipos de datos en Python. Para identificar el tipo de un dato usamos la función integrada _type_. Le recomiendo dominar los distintos tipos de datos: en programación todo está relacionado con los tipos de datos. Ya introduje los tipos de datos al principio y los vuelvo a mencionar porque cada tema está relacionado con los tipos de datos. Estudiaremos cada tipo con más detalle en capítulos posteriores.
## Conversión de tipos de datos
- Comprobar el tipo de dato: Para comprobar el tipo de un dato/variable usamos la función _type_
**Ejemplo:**
```py
# Diferentes tipos de datos en Python
# Declaramos algunas variables con distintos tipos de datos
first_name = 'Asabeneh' # str
last_name = 'Yetayeh' # str
country = 'Finland' # str
city= 'Helsinki' # str
age = 250 # int, no se preocupe, esta no es mi edad real :)
# Printing out types
print(type('Asabeneh')) # str
print(type(first_name)) # str
print(type(10)) # int
print(type(3.14)) # float
print(type(1 + 1j)) # complex
print(type(True)) # bool
print(type([1, 2, 3, 4])) # list
print(type({'name':'Asabeneh','age':250, 'is_married':250})) # dict
print(type((1,2))) # tuple
print(type(zip([1,2],[3,4]))) # set
```
- Conversión de tipos: convertir un tipo de dato a otro. Usamos _int()_, _float()_, _str()_, _list_, _set_.
Cuando realizamos operaciones aritméticas, las cadenas que contienen números deben convertirse primero a int o float, de lo contrario se producirá un error. Si concatenamos un número y una cadena, hay que convertir primero el número a cadena. Veremos la concatenación en la sección de cadenas.
**Ejemplo:**
```py
# De entero a float
num_int = 10
print('num_int',num_int) # 10
num_float = float(num_int)
print('num_float:', num_float) # 10.0
# De float a entero
gravity = 9.81
print(int(gravity)) # 9
# De entero a cadena
num_int = 10
print(num_int) # 10
num_str = str(num_int)
print(num_str) # '10'
# De cadena a entero o float
num_str = '10.6'
print('num_int', int(num_str)) # 10
print('num_float', float(num_str)) # 10.6
# De cadena a lista
first_name = 'Asabeneh'
print(first_name) # 'Asabeneh'
first_name_to_list = list(first_name)
print(first_name_to_list) # ['A', 's', 'a', 'b', 'e', 'n', 'e', 'h']
```
## Números
Diferentes tipos numéricos en Python
- Integer: números enteros (negativos, 0 y positivos)
Ejemplo:
... -3, -2, -1, 0, 1, 2, 3 ...
- Float: números de punto flotante
Ejemplo
... -3.5, -2.25, -1.0, 0.0, 1.1, 2.2, 3.5 ...
- Complex: números complejos
Ejemplo
1 + j, 2 + 4j, 1 - 1j
🌕 ¡Excelente! Acabas de completar el desafío del Día 2, estás un paso más cerca del éxito. Ahora realiza algunos ejercicios para ejercitar tu mente y tus habilidades.
## 💻 Ejercicios - Día 2
### Ejercicio: Nivel 1
1. Crea una carpeta `day_2` dentro de la carpeta `30DaysOfPython`. Dentro de esa carpeta crea un archivo `variables.py`
2. Añade un comentario: 'Día 2: 30 Days of Python programming'
3. Declara una variable `first_name` y asígnale un valor
4. Declara una variable `last_name` y asígnale un valor
5. Declara una variable `full_name` y asígnale un valor
6. Declara una variable `country` y asígnale un valor
7. Declara una variable `city` y asígnale un valor
8. Declara una variable `age` y asígnale un valor
9. Declara una variable `year` y asígnale un valor
10. Declara una variable `is_married` y asígnale un valor
11. Declara una variable `is_true` y asígnale un valor
12. Declara una variable `is_light_on` y asígnale un valor
13. Declara múltiples variables en una sola línea
### Ejercicio: Nivel 2
1. Usa la función integrada _type()_ para comprobar el tipo de las variables que declaraste
1. Usa la función _len()_ para calcular la longitud de la variable `first_name`
1. Compara la longitud de las variables `first_name` y `last_name`
1. Declara las variables `num_one = 5` y `num_two = 4`
1. Suma `num_one` y `num_two` y asigna el resultado a la variable `total`
2. Resta `num_two` de `num_one` y asigna el resultado a la variable `diff`
3. Multiplica `num_one` y `num_two` y asigna el resultado a la variable `product`
4. Divide `num_one` entre `num_two` y asigna el resultado a la variable `division`
5. Usa la operación módulo para obtener el resto de `num_two` dividido por `num_one` y asígnalo a `remainder`
6. Calcula `num_one` elevado a `num_two` y asigna el valor a `exp`
7. Calcula la división entera de `num_one` entre `num_two` (operación de floor division) y asigna el resultado a `floor_division`
1. El círculo tiene un radio de 30 metros.
1. Calcula el área del círculo y asígnala a la variable `_area_of_circle_`
2. Calcula la circunferencia del círculo y asígnala a la variable `_circum_of_circle_`
3. Pide el radio al usuario y calcula el área.
1. Usa la función integrada `input()` para obtener nombre, apellido, país y edad del usuario y almacena los valores en las variables correspondientes
1. Ejecuta `help('keywords')` en el intérprete de Python o en un archivo para comprobar las palabras reservadas (keywords) de Python
🎉 ¡Felicidades! 🎉
[<< Día 1](./readme_sp.md) | [Día 3 >>](./03_operators_sp.md)
================================================
FILE: Spanish/03_Day_Operators/03_operators.md
================================================
[<< Dia 2](../02_Day_Variables_builtin_functions/02_variables_builtin_functions.md) | [Dia 4 >>](../04_Day_Strings/04_strings.md)

- [📘 Día 3](#📘-día-3)
- [Booleano](#booleano)
- [Operadores](#operadores)
- [Operadores de asignación](#operadores-de-asignación)
- [Operadores aritméticos:](#operadores-aritméticos)
- [Operadores de comparación](#operadores-de-comparación)
- [Operadores lógicos](#operadores-lógicos)
- [💻 Ejercicios - Día 3](#💻-ejercicios---día-3)
# 📘 Día 3
## Booleano
Un tipo de datos booleano representa uno de los dos valores: _Verdadero_ o _Falso_. El uso de estos tipos de datos quedará claro una vez que comencemos a usar el operador de comparación. La primera letra **T** para Verdadero y **F** para Falso debe ser en mayúscula a diferencia de JavaScript.
**Ejemplo: valores booleanos**
```py
print(True)
print(False)
```
## Operadores
Python language supports several types of operators. In this section, we will focus on few of them.
### Operadores de asignación
Los operadores de asignación se utilizan para asignar valores a las variables. Tomemos = como ejemplo. El signo igual en matemáticas muestra que dos valores son iguales, sin embargo, en Python significa que estamos almacenando un valor en una determinada variable y lo llamamos asignación o asignación de valor a una variable. La siguiente tabla muestra los diferentes tipos de operadores de asignación de Python, tomados de [w3school](https://www.w3schools.com/python/python_operators.asp).

### Operadores aritméticos:
- Suma (+): a + b
- Resta(-): a - b
- Multiplicación(*): a * b
- División(/): a/b
- Módulo(%): a % b
- División de piso(//): a // b
- Exponenciación(**): a ** b

**Ejemplo: Enteros**
```py
# Operaciones aritméticas en Python
# enteros
print('Addition: ', 1 + 2) # 3
print('Subtraction: ', 2 - 1) # 1
print('Multiplication: ', 2 * 3) # 6
print ('Division: ', 4 / 2) # 2.0 La división en Python da un número flotante
print('Division: ', 6 / 2) # 3.0
print('Division: ', 7 / 2) # 3.5
print('Division without the remainder: ', 7 // 2) # 3, da sin el número flotante o sin el resto
print ('Division without the remainder: ',7 // 3) # 2
print('Modulus: ', 3 % 2) # 1, da el resto
print('Exponentiation: ', 2 ** 3) # 9 significa 2 * 2 * 2
```
**Ejemplo: Floats**
```py
# Números flotantes
print('Floating Point Number, PI', 3.14)
print('Floating Point Number, gravity', 9.81)
```
**Ejemplo: Números complex**
```py
# Números complejos
print('Complex number: ', 1 + 1j)
print('Multiplying complex numbers: ',(1 + 1j) * (1 - 1j))
```
Declaremos una variable y asignemos un tipo de dato numérico. Voy a usar una variable de un solo carácter, pero recuerde que no desarrolle el hábito de declarar este tipo de variables. Los nombres de las variables deben ser siempre mnemotécnicos.
**Ejemplo:**
```python
# Declarar la variable en la parte superior primero
a = 3 # a es un nombre de variable y 3 es un tipo de dato entero
b = 2 # b es un nombre de variable y 3 es un tipo de dato entero
# Operaciones aritméticas y asignación del resultado a una variable
total = a + b
diff = a - b
product = a * b
division = a / b
remainder = a % b
floor_division = a // b
exponential = a ** b
# Debería haber usado sum en lugar de total, pero sum es una función integrada; trate de evitar anular las funciones integradas
print(total) # si no etiqueta su impresión con alguna cadena, nunca sabrá de dónde viene el resultado
print('a + b = ', total)
print('a - b = ', diff)
print('a * b = ', product)
print('a / b = ', division)
print('a % b = ', remainder)
print('a // b = ', floor_division)
print('a ** b = ', exponentiation)
```
**Ejemplo:**
```py
print('== Addition, Subtraction, Multiplication, Division, Modulus ==')
# Declarar valores y organizarlos juntos
num_one = 3
num_two = 4
# Operaciones aritmeticas
total = num_one + num_two
diff = num_two - num_one
product = num_one * num_two
div = num_two / num_one
remainder = num_two % num_one
# Imprimiendo valores con etiqueta
print('total: ', total)
print('difference: ', diff)
print('product: ', product)
print('division: ', div)
print('remainder: ', remainder)
```
Empecemos a conectar los puntos y empecemos a hacer uso de lo que ya sabemos para calcular (área, volumen, densidad, peso, perímetro, distancia, fuerza).
**Ejemplo:**
```py
# Cálculo del área de un círculo
radius = 10 # radio de un circulo
area_of_circle = 3.14 * radius ** 2 # dos signo * significa exponente o potencia
print('Area of a circle:', area_of_circle)
# Calcular el área de un rectángulo
length = 10
width = 20
area_of_rectangle = length * width
print('Area of rectangle:', area_of_rectangle)
# Calcular el peso de un objeto
mass = 75
gravity = 9.81
weight = mass * gravity
print(weight, 'N') # Agregando unidad al peso
# Calcular la densidad de un líquido
mass = 75 # en kg
volume = 0.075 # en metros cúbicos
density = mass / volume # 1000 Kg/m^3
```
### Operadores de comparación
En programación comparamos valores, usamos operadores de comparación para comparar dos valores. Comprobamos si un valor es mayor o menor o igual a otro valor. La siguiente tabla muestra los operadores de comparación de Python que se tomaron de [w3shool](https://www.w3schools.com/python/python_operators.asp).

**Ejemplo: Operadores de comparación**
```py
print(3 > 2) # True, porque 3 es mayor que 2
print(3 >= 2) # True, porque 3 es mayor que 2
print(3 < 2) # False, porque 3 es mayor que 2
print(2 < 3) # True, porque 2 es menor que 3
print(2 <= 3) # True, porque 2 es menor que 3
print(3 == 2) # False, porque 3 no es igual a 2
print(3 != 2) # True, porque 3 no es igual a 2
print(len('mango') == len('avocado')) # False
print(len('mango') != len('avocado')) # True
print(len('mango') < len('avocado')) # True
print(len('milk') != len('meat')) # False
print(len('milk') == len('meat')) # True
print(len('tomato') == len('potato')) # True
print(len('python') > len('dragon')) # False
# Comparar algo da un True o False
print('True == True: ', True == True)
print('True == False: ', True == False)
print('False == False:', False == False)
```
Además del operador de comparación anterior, Python usa:
- _is_: Devuelve True si ambas variables son el mismo objeto (x es y)
- _is not_: Devuelve True si ambas variables no son el mismo objeto (x no es y)
- _in_: Devuelve True si la lista consultada contiene un elemento determinado (x en y)
- _not in_: Devuelve True si la lista consultada no tiene un elemento determinado (x en y)
```py
print('1 is 1', 1 is 1) # True - porque los valores de los datos son los mismos
print('1 is not 2', 1 is not 2) # True - porque 1 no es 2
print('A in Asabeneh', 'A' in 'Asabeneh') # True - A encontrado en la cadena
print('B in Asabeneh', 'B' in 'Asabeneh') # False - no hay b mayúscula
print('coding' in 'coding for all') # True - porque 'coding for all' tiene la palabra 'coding'
print('a in an:', 'a' in 'an') # True
print('4 is 2 ** 2:', 4 is 2 ** 2) # True
```
### Operadores lógicos
A diferencia de otros lenguajes de programación, Python utiliza las palabras clave _and_, _or_ y _not_ para los operadores lógicos. Los operadores lógicos se utilizan para combinar sentencias condicionales:

```py
print(3 > 2 and 4 > 3) # True - porque ambas afirmaciones son verdaderas
print(3 > 2 and 4 < 3) # False - porque la segunda afirmación es falsa
print(3 < 2 and 4 < 3) # False - porque ambas afirmaciones son falsas
print('True and True: ', True and True)
print(3 > 2 or 4 > 3) # True - porque ambas afirmaciones son verdaderas
print(3 > 2 or 4 < 3) # True - porque una de las afirmaciones es verdadera
print(3 < 2 or 4 < 3) # False - porque ambas afirmaciones son falsas
print('True or False:', True or False)
print(not 3 > 2) # False - porque 3 > 2 es verdadero, entonces no verdadero da falso
print(not True) # False - Negación, el operador not devuelve verdadero a falso
print(not False) # True
print(not not True) # True
print(not not False) # False
```
🌕 Tienes una energía ilimitada. Acaba de completar los desafíos del día 3 y está tres pasos por delante en su camino hacia la grandeza. Ahora haz algunos ejercicios para tu cerebro y tus músculos.
## 💻 Ejercicios - Día 3
1. Declara tu edad como variable entera
2. Declara tu altura como una variable flotante
3. Declarar una variable que almacene un número complejo
4. Escriba un script que solicite al usuario que ingrese la base y la altura del triángulo y calcule el área de este triángulo (área = 0,5 x b x h).
```py
Enter base: 20
Enter height: 10
The area of the triangle is 100
```
5. Escriba un script que solicite al usuario que ingrese el lado a, el lado b y el lado c del triángulo. Calcula el perímetro del triángulo (perímetro = a + b + c).
```py
Enter side a: 5
Enter side b: 4
Enter side c: 3
The perimeter of the triangle is 12
```
6. Obtenga la longitud y el ancho de un rectángulo usando el indicador. Calcula su área (área = largo x ancho) y perímetro (perímetro = 2 x (largo + ancho))
7. Obtenga el radio de un círculo usando el aviso. Calcula el área (área = pi x r x r) y la circunferencia (c = 2 x pi x r) donde pi = 3,14.
8. Calcular la pendiente, la intersección x y la intersección y de y = 2x -2
9. La pendiente es (m = y2-y1/x2-x1). Encuentre la pendiente y la [distancia euclidiana](https://en.wikipedia.org/wiki/Euclidean_distance#:~:text=In%20mathematics%2C%20the%20Euclidean%20distance,being%20called%20the%20Pythagorean%20distance.) entre el punto (2, 2) y el punto (6,10)
10. Compara las pendientes en las tareas 8 y 9.
11. Calcula el valor de y (y = x^2 + 6x + 9). Trate de usar diferentes valores de x y descubra en qué valor de x y será 0.
12. Encuentra la longitud de 'python' y 'dragon' y haz una declaración de comparación falsa.
13. Use el operador _and_ para verificar si 'on' se encuentra tanto en 'python' como en 'dragon'
14. _Espero que este curso no esté lleno de jerga_. Use el operador _in_ para verificar si _jerga_ está en la oración.
15. No hay 'on' ni en dragón ni en pitón
16. Encuentre la longitud del texto _python_ y convierta el valor en flotante y conviértalo en cadena
17. Los números pares son divisibles por 2 y el resto es cero. ¿Cómo verifica si un número es par o no usando python?
18. Verifique si la división de piso de 7 por 3 es igual al valor int convertido de 2.7.
19. Comprueba si el tipo de '10' es igual al tipo de 10
20. Comprueba si int('9.8') es igual a 10
21. Escriba un script que solicite al usuario que ingrese las horas y la tarifa por hora. ¿Calcular el salario de la persona?
```py
Enter hours: 40
Enter rate per hour: 28
Your weekly earning is 1120
```
22. Escriba un script que le solicite al usuario que ingrese el número de años. Calcula el número de segundos que una persona puede vivir. Suponga que una persona puede vivir cien años.
```py
Enter number of years you have lived: 100
You have lived for 3153600000 seconds.
```
23. Escriba un script de Python que muestre la siguiente tabla
```py
1 1 1 1 1
2 1 2 4 8
3 1 3 9 27
4 1 4 16 64
5 1 5 25 125
```
🎉 ¡FELICITACIONES! 🎉
[<< Day 2](../02_Day_Variables_builtin_functions/02_variables_builtin_functions.md) | [Day 4 >>](../04_Day_Strings/04_strings.md)
================================================
FILE: Spanish/03_Day_Operators/day-3.py
================================================
# Operaciones aritméticas en Python
# Integers
print('Addition: ', 1 + 2)
print('Subtraction: ', 2 - 1)
print('Multiplication: ', 2 * 3)
print ('Division: ', 4 / 2) # La división en python da un número flotante
print('Division: ', 6 / 2)
print('Division: ', 7 / 2)
print('Division without the remainder: ', 7 // 2) # da sin el número flotante o sin el resto
print('Modulus: ', 3 % 2) # Da el resto
print ('Division without the remainder: ', 7 // 3)
print('Exponential: ', 3 ** 2) # significa 3 * 3
# Números Floating
print('Floating Number,PI', 3.14)
print('Floating Number, gravity', 9.81)
# Números Complex
print('Complex number: ', 1 + 1j)
print('Multiplying complex number: ',(1 + 1j) * (1-1j))
# Declarar la variable en la parte superior primero
a = 3 # a es un nombre de variable y 3 es un tipo de dato entero
b = 2 # b es un nombre de variable y 3 es un tipo de dato entero
# Operaciones aritméticas y asignación del resultado a una variable
total = a + b
diff = a - b
product = a * b
division = a / b
remainder = a % b
floor_division = a // b
exponential = a ** b
# Debería haber usado sum en lugar de total, pero sum es una función integrada. Trate de evitar anular las funciones integradas.
print(total) # si no etiqueta su impresión con alguna cadena, nunca sabrá de dónde viene el resultado
print('a + b = ', total)
print('a - b = ', diff)
print('a * b = ', product)
print('a / b = ', division)
print('a % b = ', remainder)
print('a // b = ', floor_division)
print('a ** b = ', exponential)
# Declarar valores y organizarlos juntos
num_one = 3
num_two = 4
# Operaciones aritmeticas
total = num_one + num_two
diff = num_two - num_one
product = num_one * num_two
div = num_two / num_two
remainder = num_two % num_one
# Imprimiendo valores con etiqueta
print('total: ', total)
print('difference: ', diff)
print('product: ', product)
print('division: ', div)
print('remainder: ', remainder)
# Cálculo del área de un círculo
radius = 10 # radio de un circulo
area_of_circle = 3.14 * radius ** 2 # dos * signo significa exponente o potencia
print('Area of a circle:', area_of_circle)
# Calcular el área de un rectángulo
length = 10
width = 20
area_of_rectangle = length * width
print('Area of rectangle:', area_of_rectangle)
# Calcular el peso de un objeto
mass = 75
gravity = 9.81
weight = mass * gravity
print(weight, 'N')
print(3 > 2) # True, porque 3 es mayor que 2
print(3 >= 2) # True, porque 3 es mayor que 2
print(3 < 2) # False, porque 3 es mayor que 2
print(2 < 3) # True, porque 2 es menor que 3
print(2 <= 3) # True, porque 2 es menor que 3
print(3 == 2) # False, porque 3 no es igual a 2
print(3 != 2) # True, porque 3 no es igual a 2
print(len('mango') == len('avocado')) # False
print(len('mango') != len('avocado')) # True
print(len('mango') < len('avocado')) # True
print(len('milk') != len('meat')) # False
print(len('milk') == len('meat')) # True
print(len('tomato') == len('potato')) # True
print(len('python') > len('dragon')) # False
# Comparación booleana
print('True == True: ', True == True)
print('True == False: ', True == False)
print('False == False:', False == False)
print('True and True: ', True and True)
print('True or False:', True or False)
# Comparación de otra forma
print('1 is 1', 1 is 1) # True - porque los valores de los datos son los mismos
print('1 is not 2', 1 is not 2) # True - porque 1 no es 2
print('A in Asabeneh', 'A' in 'Asabeneh') # True - A encontrado en la cadena
print('B in Asabeneh', 'B' in 'Asabeneh') # False - no hay b mayúscula
print('coding' in 'coding for all') # True - porque codificar para todos tiene la palabra codificar
print('a in an:', 'a' in 'an') # True
print('4 is 2 ** 2:', 4 is 2 ** 2) # True
print(3 > 2 and 4 > 3) # True - porque ambas afirmaciones son verdaderas
print(3 > 2 and 4 < 3) # False - porque la segunda afirmación es falsa
print(3 < 2 and 4 < 3) # False - porque ambas afirmaciones son falsas
print(3 > 2 or 4 > 3) # True - porque ambas afirmaciones son verdaderas
print(3 > 2 or 4 < 3) # True - porque uno de los enunciados es verdadero
print(3 < 2 or 4 < 3) # False - porque ambas afirmaciones son falsas
print(not 3 > 2) # False - porque 3 > 2 es verdadero, entonces not verdadero da falso
print(not True) # False - Negación, el operador not devuelve verdadero a falso
print(not False) # True
print(not not True) # True
print(not not False) # False
================================================
FILE: Spanish/03_operators_sp.md
================================================
[<< Día 2](./02_variables_builtin_functions_sp.md) | [Día 4 >>](./04_strings_sp.md)

_Lectura aproximada: 12 min_
- [📘 Día 3](#-día-3)
- [Boolean](#boolean)
- [Operadores](#operadores)
- [Operadores de asignación](#operadores-de-asignación)
- [Operadores aritméticos](#operadores-aritméticos)
- [Operadores de comparación](#operadores-de-comparación)
- [Operadores lógicos](#operadores-lógicos)
- [💻 Ejercicios - Día 3](#-ejercicios---día-3)
# 📘 Día 3
## Boolean
El tipo booleano representa uno de dos valores: _True_ o _False_. Cuando comencemos a usar operadores de comparación su uso quedará claro. La primera letra **T** representa True y **F** representa False; a diferencia de JavaScript, en Python las palabras booleanas deben escribirse con la primera letra en mayúscula.
**Ejemplo: valores booleanos**
```py
print(True)
print(False)
```
## Operadores
Python soporta varios tipos de operadores. En esta sección nos centraremos en algunos de ellos.
### Operadores de asignación
Los operadores de asignación se usan para asignar valores a las variables. Tomemos = como ejemplo: en matemáticas el signo igual indica que dos valores son iguales, pero en Python indica que estamos almacenando un valor en una variable; esto se llama asignación. La tabla siguiente muestra los diferentes operadores de asignación en Python (tomada de [w3schools](https://www.w3schools.com/python/python_operators.asp)).

### Operadores aritméticos:
- Suma (+): a + b
- Resta (-): a - b
- Multiplicación (*): a * b
- División (/): a / b
- Módulo (%): a % b
- División entera (//): a // b
- Exponenciación (**): a ** b

**Ejemplo: enteros**
```py
# Operadores aritméticos en Python
# Enteros
print('Addition: ', 1 + 2) # 3
print('Subtraction: ', 2 - 1) # 1
print('Multiplication: ', 2 * 3) # 6
print ('Division: ', 4 / 2) # 2.0 la división en Python devuelve float
print('Division: ', 6 / 2) # 3.0
print('Division: ', 7 / 2) # 3.5
print('Division without the remainder: ', 7 // 2) # 3, devuelve la parte entera del cociente
print ('Division without the remainder: ',7 // 3) # 2
print('Modulus: ', 3 % 2) # 1, devuelve el resto
print('Exponentiation: ', 2 ** 3) # 8 representa 2 * 2 * 2
```
**Ejemplo: flotantes**
```py
# Flotantes
print('Floating Point Number, PI', 3.14)
print('Floating Point Number, gravity', 9.81)
```
**Ejemplo: números complejos**
```py
# Números complejos
print('Complex number: ', 1 + 1j)
print('Multiplying complex numbers: ',(1 + 1j) * (1 - 1j))
```
Declararemos una variable y le asignaremos un valor numérico. En el ejemplo uso nombres de una sola letra, pero no acostumbres a nombrar variables así; los nombres deben ser siempre fáciles de recordar.
**Ejemplo:**
```python
# Primero declaramos las variables
a = 3 # a es un nombre de variable, 3 es un valor entero
b = 2 # b es un nombre de variable, 2 es un valor entero
# Realizamos operaciones aritméticas y asignamos los resultados a variables
total = a + b
diff = a - b
product = a * b
division = a / b
remainder = a % b
floor_division = a // b
exponential = a ** b
# Deberíamos usar sum en lugar de total, pero sum es una función integrada — evita sobrescribirla
print(total) # Si no imprimimos etiquetas, no sabremos qué representa cada valor
print('a + b = ', total)
print('a - b = ', diff)
print('a * b = ', product)
print('a / b = ', division)
print('a % b = ', remainder)
print('a // b = ', floor_division)
print('a ** b = ', exponentiation)
```
**Ejemplo:**
```py
print('== Addition, Subtraction, Multiplication, Division, Modulus ==')
# Declaramos las variables
num_one = 3
num_two = 4
# Operaciones aritméticas
total = num_one + num_two
diff = num_two - num_one
product = num_one * num_two
div = num_two / num_one
remainder = num_two % num_one
# Imprimimos con etiquetas
print('total: ', total)
print('difference: ', diff)
print('product: ', product)
print('division: ', div)
print('remainder: ', remainder)
```
Comencemos a usar números con decimales y pongamos en práctica lo aprendido para calcular áreas, volúmenes, densidades, pesos, perímetros, distancias y fuerzas.
**Ejemplo:**
```py
# Calcular el área de un círculo
radius = 10 # radio del círculo
area_of_circle = 3.14 * radius ** 2 # dos * indican exponente o potencia
print('Area of a circle:', area_of_circle)
# Calcular el área del rectángulo
length = 10
width = 20
area_of_rectangle = length * width
print('Area of rectangle:', area_of_rectangle)
# Calcular el peso de un objeto
mass = 75
gravity = 9.81
weight = mass * gravity
print(weight, 'N') # añadimos la unidad para la fuerza
# Calcular la densidad de un líquido
mass = 75 # unidad: Kg
volume = 0.075 # unidad: m³
density = mass / volume # 1000 Kg/m³
```
### Operadores de comparación
En programación usamos operadores de comparación para comparar dos valores. Comprobamos si un valor es mayor, menor o igual a otro. La tabla siguiente muestra los operadores de comparación en Python (tomada de [w3schools](https://www.w3schools.com/python/python_operators.asp)).

**Ejemplo: operadores de comparación**
```py
print(3 > 2) # True, porque 3 es mayor que 2
print(3 >= 2) # True, porque 3 es mayor o igual que 2
print(3 < 2) # False, porque 3 no es menor que 2
print(2 < 3) # True, porque 2 es menor que 3
print(2 <= 3) # True, porque 2 es menor o igual que 3
print(3 == 2) # False, porque 3 no es igual a 2
print(3 != 2) # True, porque 3 no es igual a 2
print(len('mango') == len('avocado')) # False
print(len('mango') != len('avocado')) # True
print(len('mango') < len('avocado')) # True
print(len('milk') != len('meat')) # False
print(len('milk') == len('meat')) # True
print(len('tomato') == len('potato')) # True
print(len('python') > len('dragon')) # False
# Las comparaciones devuelven True o False
print('True == True: ', True == True)
print('True == False: ', True == False)
print('False == False:', False == False)
```
Además de los operadores de comparación anteriores, Python también utiliza:
- _is_: devuelve True si los objetos son idénticos (x is y)
- _is not_: devuelve True si los objetos no son idénticos (x is not y)
- _in_: devuelve True si un elemento está en una secuencia (x in y)
- _not in_: devuelve True si un elemento no está en una secuencia (x not in y)
```py
print('1 is 1', 1 is 1) # True - porque los objetos son idénticos
print('1 is not 2', 1 is not 2) # True - porque los objetos no son idénticos
print('A in Asabeneh', 'A' in 'Asabeneh') # True - la cadena contiene 'A'
print('B in Asabeneh', 'B' in 'Asabeneh') # False - no hay 'B' mayúscula
print('coding' in 'coding for all') # True - 'coding' está en 'coding for all'
print('a in an:', 'a' in 'an') # True
print('4 is 2 ** 2:', 4 is 2 ** 2) # True
```
### Operadores lógicos
A diferencia de otros lenguajes de programación, Python usa las palabras clave _and_, _or_ y _not_ como operadores lógicos. Los operadores lógicos se utilizan para combinar expresiones condicionales:

```py
print(3 > 2 and 4 > 3) # True - porque ambas expresiones son True
print(3 > 2 and 4 < 3) # False - porque una de las expresiones es False
print(3 < 2 and 4 < 3) # False - porque ambas expresiones son False
print('True and True: ', True and True)
print(3 > 2 or 4 > 3) # True - porque una o ambas expresiones son True
print(3 > 2 or 4 < 3) # True - porque una de las expresiones es True
print(3 < 2 or 4 < 3) # False - porque ambas expresiones son False
print('True or False:', True or False)
print(not 3 > 2) # False - 3 > 2 es True, not True es False
print(not True) # False - not convierte True en False
print(not False) # True
print(not not True) # True
print(not not False) # False
```
🌕 ¡Con energía! Acabas de completar el desafío del Día 3 y has avanzado tres pasos en el camino hacia el dominio. Ahora realiza algunos ejercicios para poner a prueba tu mente y tus habilidades.
## 💻 Ejercicios - Día 3
1. Declara una variable entera que represente tu edad
2. Declara una variable float que represente tu altura
3. Declara una variable compleja
4. Escribe un script que pida al usuario la base y la altura de un triángulo y calcule su área (Área = 0,5 x b x h).
```py
Entrada base: 20
Entrada altura: 10
El área del triángulo es 100
```
5. Escribe un script que pida al usuario los lados a, b y c de un triángulo y calcule su perímetro (Perímetro = a + b + c).
```py
Entrada lado a: 5
Entrada lado b: 4
Entrada lado c: 3
El perímetro del triángulo es 12
```
6. Pide al usuario la longitud y la anchura de un rectángulo. Calcula su área (Área = largo x ancho) y su perímetro (Perímetro = 2 x (largo + ancho)).
7. Pide al usuario el radio de un círculo. Calcula su área (Área = pi x r x r) y su circunferencia (Circunferencia = 2 x pi x r), con pi = 3.14.
8. Calcula la pendiente, la intersección en x y la intersección en y de y = 2x - 2.
9. La pendiente se calcula como (m = (y2 - y1) / (x2 - x1)). Encuentra la pendiente y la distancia euclídea entre los puntos (2, 2) y (6, 10).
10. Compara las pendientes obtenidas en los ejercicios 8 y 9.
11. Calcula el valor de y para y = x^2 + 6x + 9. Prueba con distintos valores de x y encuentra cuándo y es 0.
12. Encuentra la longitud de 'python' y 'dragon', y realiza una comparación ficticia.
13. Usa el operador _and_ para comprobar si tanto 'python' como 'dragon' contienen 'on'.
14. En la oración _I hope this course is not full of jargon_, usa el operador _in_ para comprobar si contiene la palabra _jargon_.
15. Comprueba que ni 'dragon' ni 'python' contienen 'on'.
16. Encuentra la longitud de 'python', conviértela a float y luego a string.
17. Los números pares son divisibles por 2 con resto 0. ¿Cómo comprobar en Python si un número es par o impar?
18. Comprueba si la división entera de 7 entre 3 es igual al valor entero de 2.7.
19. Comprueba si el tipo de '10' es igual al tipo de 10.
20. Comprueba si int('9.8') es igual a 10.
21. Escribe un script que solicite las horas trabajadas y la tarifa por hora al usuario y calcule el salario.
```py
Introduce horas trabajadas: 40
Introduce tarifa por hora: 28
Tu salario semanal es 1120
```
22. Escribe un script que pida al usuario los años vividos y calcule cuántos segundos ha vivido una persona (supongamos que puede vivir 100 años).
```py
Introduce cuántos años has vivido: 100
Has vivido 3153600000 segundos.
```
23. Escribe un script en Python que muestre la siguiente tabla
```py
1 1 1 1 1
2 1 2 4 8
3 1 3 9 27
4 1 4 16 64
5 1 5 25 125
```
🎉 ¡Felicidades! 🎉
[<< Día 2](./02_variables_builtin_functions_sp.md) | [Día 4 >>](./04_strings_sp.md)
================================================
FILE: Spanish/04_strings_sp.md
================================================
[<< Día 3](./03_operators_sp.md) | [Día 5 >>](./05_lists_sp.md)

_Lectura aproximada: 20 min_
- [Día 4](#día-4)
- [Cadenas](#cadenas)
- [Crear cadenas](#crear-cadenas)
- [Concatenación de cadenas](#concatenación-de-cadenas)
- [Secuencias de escape en cadenas](#secuencias-de-escape-en-cadenas)
- [Formateo de cadenas](#formateo-de-cadenas)
- [Formateo clásico (% operador)](#formateo-clásico--operador)
- [Formateo moderno (str.format)](#formateo-moderno-strformat)
- [Interpolación / f-Strings (Python 3.6+)](#interpolación--f-strings-python-36)
- [Las cadenas en Python son secuencias de caracteres](#las-cadenas-en-python-son-secuencias-de-caracteres)
- [Desempaquetar caracteres](#desempaquetar-caracteres)
- [Obtener caracteres por índice](#obtener-caracteres-por-índice)
- [Slicing de cadenas](#slicing-de-cadenas)
- [Invertir cadenas](#invertir-cadenas)
- [Saltar caracteres al hacer slicing](#saltar-caracteres-al-hacer-slicing)
- [Métodos de cadenas](#métodos-de-cadenas)
- [💻 Ejercicios - Día 4](#-ejercicios---día-4)
# Día 4
## Cadenas
El texto es un tipo de dato de cadena. Cualquier dato escrito como texto es una cadena. Todo lo que esté entre comillas simples, dobles o triples se considera una cadena. Existen muchos métodos y funciones integradas para trabajar con cadenas. Use la función `len()` para obtener la longitud de una cadena.
### Crear cadenas
```py
letter = 'P' # Una cadena puede ser un carácter o un texto
print(letter) # P
print(len(letter)) # 1
greeting = 'Hello, World!' # Las cadenas se crean con comillas simples o dobles, "Hello, World!"
print(greeting) # Hello, World!
print(len(greeting)) # 13
sentence = "I hope you are enjoying 30 days of Python Challenge"
print(sentence)
```
Las cadenas multilínea se crean utilizando tres comillas simples (`'''`) o tres comillas dobles (`"""`). A continuación un ejemplo:
```py
multiline_string = '''I am a teacher and enjoy teaching.
I didn't find anything as rewarding as empowering people.
That is why I created 30 days of python.'''
print(multiline_string)
# Otra forma
multiline_string = """I am a teacher and enjoy teaching.
I didn't find anything as rewarding as empowering people.
That is why I created 30 days of python."""
print(multiline_string)
```
### Concatenación de cadenas
Podemos concatenar cadenas. La unión de cadenas se llama concatenación. Vea el siguiente ejemplo:
```py
first_name = 'Asabeneh'
last_name = 'Yetayeh'
space = ' '
full_name = first_name + space + last_name
print(full_name) # Asabeneh Yetayeh
# Uso de `len()` para obtener la longitud de una cadena
print(len(first_name)) # 8
print(len(last_name)) # 7
print(len(first_name) > len(last_name)) # True
print(len(full_name)) # 16
```
### Secuencias de escape en cadenas
En Python y otros lenguajes una barra invertida (`\`) seguida de un carácter forma una secuencia de escape. Algunas secuencias comunes son:
- \n: nueva línea
- \t: tabulación (4 espacios)
- \\\\: barra invertida
- \' : comilla simple
- \" : comilla doble
Ahora veamos ejemplos del uso de estas secuencias.
```py
print('I hope everyone is enjoying the Python Challenge.\nAre you ?') # nueva línea
print('Days\tTopics\tExercises') # añade una tabulación
print('Day 1\t5\t5')
print('Day 2\t6\t20')
print('Day 3\t5\t23')
print('Day 4\t1\t35')
print('This is a backslash symbol (\\)') # imprime barra invertida
print('In every programming language it starts with \"Hello, World!\"') # comillas dobles dentro de comillas simples
# Salida
I hope every one is enjoying the Python Challenge.
Are you ?
Days Topics Exercises
Day 1 5 5
Day 2 6 20
Day 3 5 23
Day 4 1 35
This is a backslash symbol (\)
In every programming language it starts with "Hello, World!"
```
### Formateo de cadenas
#### Formateo clásico (% operador)
En Python existen varias maneras de formatear cadenas. En esta sección veremos algunas de ellas.
El operador '%' se usa para formatear una tupla de variables dentro de una cadena de formato, usando especificadores como '%s', '%d', '%f' y '%.nf'.
- %s - cadena (o cualquier objeto representable como cadena)
- %d - entero
- %f - punto flotante
- "%.nf" - punto flotante con precisión fija (n decimales)
```py
# Solo cadenas
first_name = 'Asabeneh'
last_name = 'Yetayeh'
language = 'Python'
formated_string = 'I am %s %s. I teach %s' %(first_name, last_name, language)
print(formated_string)
# Cadenas y números
radius = 10
pi = 3.14
area = pi * radius ** 2
formated_string = 'The area of circle with a radius %d is %.2f.' %(radius, area) # 2 indica 2 decimales
python_libraries = ['Django', 'Flask', 'NumPy', 'Matplotlib','Pandas']
formated_string = 'The following are python libraries:%s' % (python_libraries)
print(formated_string) # imprime "The following are python libraries:['Django', 'Flask', 'NumPy', 'Matplotlib','Pandas']"
```
#### Formateo moderno (str.format)
Este método de formateo se introdujo en Python 3.
```py
first_name = 'Asabeneh'
last_name = 'Yetayeh'
language = 'Python'
formated_string = 'I am {} {}. I teach {}'.format(first_name, last_name, language)
print(formated_string)
a = 4
b = 3
print('{} + {} = {}'.format(a, b, a + b))
print('{} - {} = {}'.format(a, b, a - b))
print('{} * {} = {}'.format(a, b, a * b))
print('{} / {} = {:.2f}'.format(a, b, a / b)) # limitar a dos decimales
print('{} % {} = {}'.format(a, b, a % b))
print('{} // {} = {}'.format(a, b, a // b))
print('{} ** {} = {}'.format(a, b, a ** b))
# Salida
4 + 3 = 7
4 - 3 = 1
4 * 3 = 12
4 / 3 = 1.33
4 % 3 = 1
4 // 3 = 1
4 ** 3 = 64
# Cadenas y números
radius = 10
pi = 3.14
area = pi * radius ** 2
formated_string = 'The area of a circle with a radius {} is {:.2f}.'.format(radius, area) # mantener dos decimales
print(formated_string)
```
#### Interpolación / f-Strings (Python 3.6+)
Otra forma moderna de formatear cadenas es la interpolación con f-strings. Las cadenas empiezan con `f` y se insertan expresiones entre llaves.
```py
a = 4
b = 3
print(f'{a} + {b} = {a +b}')
print(f'{a} - {b} = {a - b}')
print(f'{a} * {b} = {a * b}')
print(f'{a} / {b} = {a / b:.2f}')
print(f'{a} % {b} = {a % b}')
print(f'{a} // {b} = {a // b}')
print(f'{a} ** {b} = {a ** b}')
```
### Las cadenas en Python son secuencias de caracteres
Las cadenas en Python son secuencias de caracteres y comparten los mismos métodos de acceso que otras secuencias como listas y tuplas. La forma más sencilla de extraer caracteres individuales (o elementos de cualquier secuencia) es desempaquetarlos en variables.
#### Desempaquetar caracteres
```
language = 'Python'
a,b,c,d,e,f = language # desempaquetar caracteres y asignarlos a variables
print(a) # P
print(b) # y
print(c) # t
print(d) # h
print(e) # o
print(f) # n
```
#### Obtener caracteres por índice
En programación la indexación comienza en cero. Por tanto, la primera letra está en el índice 0 y la última en la longitud de la cadena menos uno.

```py
language = 'Python'
first_letter = language[0]
print(first_letter) # P
second_letter = language[1]
print(second_letter) # y
last_index = len(language) - 1
last_letter = language[last_index]
print(last_letter) # n
```
Si queremos contar desde la derecha usamos índices negativos; -1 es el último índice.
```py
language = 'Python'
last_letter = language[-1]
print(last_letter) # n
second_last = language[-2]
print(second_last) # o
```
#### Slicing de cadenas
En Python podemos obtener subcadenas mediante slicing.
```py
language = 'Python'
first_three = language[0:3] # empieza en índice 0, hasta 3 pero sin incluir 3
print(first_three) #Pyt
last_three = language[3:6]
print(last_three) # hon
# Otra forma
last_three = language[-3:]
print(last_three) # hon
last_three = language[3:]
print(last_three) # hon
```
#### Invertir cadenas
Podemos invertir fácilmente una cadena.
```py
greeting = 'Hello, World!'
print(greeting[::-1]) # !dlroW ,olleH
```
#### Saltar caracteres al hacer slicing
Al pasar un parámetro de paso en slicing podemos omitir caracteres al extraer subcadenas.
```py
language = 'Python'
pto = language[0:6:2] #
print(pto) # Pto
```
### Métodos de cadenas
Hay muchos métodos para manipular y formatear cadenas. A continuación vemos algunos ejemplos:
- capitalize(): convierte el primer carácter de la cadena a mayúscula
```py
challenge = 'thirty days of python'
print(challenge.capitalize()) # 'Thirty days of python' (primera letra en mayúscula)
```
- count(): devuelve el número de ocurrencias de una subcadena: `count(subcadena, start=.., end=..)`. `start` y `end` definen el rango de conteo.
```py
challenge = 'thirty days of python'
print(challenge.count('y')) # 3
print(challenge.count('y', 7, 14)) # 1, cuenta entre índices 7 y 14
print(challenge.count('th')) # 2
```
- endswith(): determina si la cadena termina con la subcadena dada; devuelve `True` o `False`
```py
challenge = 'thirty days of python'
print(challenge.endswith('on')) # True
print(challenge.endswith('tion')) # False (no termina con 'tion')
```
- expandtabs(): reemplaza tabulaciones por espacios; el tamaño por defecto es 8, acepta parámetro de tamaño.
```py
challenge = 'thirty\tdays\tof\tpython'
print(challenge.expandtabs()) # 'thirty days of python'
print(challenge.expandtabs(10)) # 'thirty days of python' (tabulaciones expandidas a 10 espacios)
```
- find(): devuelve el índice de la primera aparición de una subcadena; si no se encuentra devuelve -1
```py
challenge = 'thirty days of python'
print(challenge.find('y')) # 5
print(challenge.find('th')) # 0
```
- rfind(): devuelve el índice de la última aparición de una subcadena; si no se encuentra devuelve -1
```py
challenge = 'thirty days of python'
print(challenge.rfind('y')) # 16
print(challenge.rfind('th')) # 17
```
- format(): formatea una cadena para una salida más legible
Para más información sobre el formateo de cadenas consulte este [enlace](https://www.programiz.com/python-programming/methods/string/format)
```py
first_name = 'Asabeneh'
last_name = 'Yetayeh'
age = 250
job = 'teacher'
country = 'Finland'
sentence = 'I am {} {}. I am a {}. I am {} years old. I live in {}.'.format(first_name, last_name, age, job, country)
print(sentence) # I am Asabeneh Yetayeh. I am 250 years old. I am a teacher. I live in Finland.
radius = 10
pi = 3.14
area = pi * radius ** 2
result = 'The area of a circle with radius {} is {}'.format(str(radius), str(area))
print(result) # The area of a circle with radius 10 is 314
```
- index(): devuelve el índice de la primera aparición de una subcadena; acepta parámetros de inicio y fin (por defecto 0 y longitud de la cadena). Si la subcadena no se encuentra, lanza `ValueError`.
```py
challenge = 'thirty days of python'
sub_string = 'da'
print(challenge.index(sub_string)) # 7
print(challenge.index(sub_string, 9)) # error
```
- rindex(): devuelve el índice de la última aparición de una subcadena; acepta parámetros de inicio y fin (por defecto 0 y longitud de la cadena).
```py
challenge = 'thirty days of python'
sub_string = 'da'
print(challenge.rindex(sub_string)) # 8
print(challenge.rindex(sub_string, 9)) # error
```
- isalnum(): determina si todos los caracteres de la cadena son alfanuméricos
```py
challenge = 'ThirtyDaysPython'
print(challenge.isalnum()) # True
challenge = '30DaysPython'
print(challenge.isalnum()) # True
challenge = 'thirty days of python'
print(challenge.isalnum()) # False, el espacio no es un carácter alfanumérico
challenge = 'thirty days of python 2019'
print(challenge.isalnum()) # False
```
- isalpha(): determina si todos los caracteres de la cadena son letras (a-z y A-Z)
```py
challenge = 'thirty days of python'
print(challenge.isalpha()) # False, el espacio no es una letra
challenge = 'ThirtyDaysPython'
print(challenge.isalpha()) # True
num = '123'
print(num.isalpha()) # False
```
- isdecimal(): determina si todos los caracteres son decimales (0-9)
```py
challenge = 'thirty days of python'
print(challenge.isdecimal()) # False
challenge = '123'
print(challenge.isdecimal()) # True
challenge = '\u00B2'
print(challenge.isdigit()) # False
challenge = '12 3'
print(challenge.isdecimal()) # False, contiene espacios
```
- isdigit(): determina si todos los caracteres son dígitos (0-9 y otros caracteres numéricos Unicode)
```py
challenge = 'Thirty'
print(challenge.isdigit()) # False
challenge = '30'
print(challenge.isdigit()) # True
challenge = '\u00B2'
print(challenge.isdigit()) # True (caracteres numéricos Unicode)
```
- isnumeric(): determina si todos los caracteres son numéricos o están relacionados con números (similar a `isdigit()` pero acepta más símbolos, p. ej. ½)
```py
num = '10'
print(num.isnumeric()) # True
num = '\u00BD' # ½
print(num.isnumeric()) # True
num = '10.5'
print(num.isnumeric()) # False
```
- isidentifier(): comprueba si la cadena es un identificador válido (nombre de variable válido)
```py
challenge = '30DaysOfPython'
print(challenge.isidentifier()) # False, porque empieza por un número
challenge = 'thirty_days_of_python'
print(challenge.isidentifier()) # True
```
- islower(): determina si todas las letras de la cadena están en minúsculas
```py
challenge = 'thirty days of python'
print(challenge.islower()) # True
challenge = 'Thirty days of python'
print(challenge.islower()) # False
```
- isupper(): determina si todas las letras de la cadena están en mayúsculas
```py
challenge = 'thirty days of python'
print(challenge.isupper()) # False
challenge = 'THIRTY DAYS OF PYTHON'
print(challenge.isupper()) # True
```
- join(): devuelve la cadena resultante tras unir los elementos
```py
web_tech = ['HTML', 'CSS', 'JavaScript', 'React']
result = ' '.join(web_tech)
print(result) # 'HTML CSS JavaScript React' (devuelve la cadena unida)
```
```py
web_tech = ['HTML', 'CSS', 'JavaScript', 'React']
result = '# '.join(web_tech)
print(result) # 'HTML# CSS# JavaScript# React'
```
- strip(): elimina los caracteres dados del inicio y del final de la cadena
```py
challenge = 'thirty days of python'
print(challenge.strip('noth')) # 'irty days of py' (elimina los caracteres dados del inicio y final)
```
- replace(): reemplaza una subcadena por otra dada
```py
challenge = 'thirty days of python'
print(challenge.replace('python', 'coding')) # 'thirty days of coding'
```
- split(): divide una cadena usando un separador dado o espacios
```py
challenge = 'thirty days of python'
print(challenge.split()) # ['thirty', 'days', 'of', 'python']
challenge = 'thirty, days, of, python'
print(challenge.split(', ')) # ['thirty', 'days', 'of', 'python']
```
- title(): devuelve la cadena en formato título (Title Case)
```py
challenge = 'thirty days of python'
print(challenge.title()) # Thirty Days Of Python
```
- swapcase(): convierte mayúsculas a minúsculas y minúsculas a mayúsculas
```py
challenge = 'thirty days of python'
print(challenge.swapcase()) # THIRTY DAYS OF PYTHON
challenge = 'Thirty Days Of Python'
print(challenge.swapcase()) # tHIRTY dAYS oF pYTHON
```
- startswith(): determina si la cadena comienza con la subcadena especificada
```py
challenge = 'thirty days of python'
print(challenge.startswith('thirty')) # True
challenge = '30 days of python'
print(challenge.startswith('thirty')) # False (no empieza con 'thirty')
```
🌕 Eres una persona extraordinaria con un enorme potencial. Acabas de completar el desafío del Día 4; llevas cuatro pasos en tu camino para convertirte en un gran profesional. Ahora realiza algunos ejercicios para entrenar tu mente y tus habilidades.
## 💻 Ejercicios - Día 4
1. Une las cadenas 'Thirty', 'Days', 'Of', 'Python' en 'Thirty Days Of Python'.
2. Une las cadenas 'Coding', 'For', 'All' en 'Coding For All'.
3. Declara la variable `company` y asígnale el valor inicial "Coding For All".
4. Imprime la variable `company` usando `print()`.
5. Usa `len()` y `print()` para mostrar la longitud de la cadena `company`.
6. Usa el método `upper()` para convertir todos los caracteres a mayúsculas.
7. Usa el método `lower()` para convertir todos los caracteres a minúsculas.
8. Aplica `capitalize()`, `title()` y `swapcase()` sobre la cadena 'Coding For All'.
9. Extrae mediante slicing la primera palabra de 'Coding For All'.
10. Usa `index`, `find` u otros métodos para comprobar si la cadena 'Coding For All' contiene la palabra 'Coding'.
11. Reemplaza la palabra 'Coding' por 'Python' en 'Coding For All'.
12. Reemplaza 'Python for Everyone' por 'Python for All' (usa `replace()` u otro método).
13. Separa la cadena 'Coding For All' usando espacios como separador.
14. Divide la cadena 'Facebook, Google, Microsoft, Apple, IBM, Oracle, Amazon' por las comas.
15. ¿Qué carácter está en el índice 0 de 'Coding For All'?
16. ¿Cuál es el índice del último carácter de 'Coding For All'?
17. ¿Qué carácter está en el índice 10 de 'Coding For All'?
18. Crea una sigla (acrónimo) a partir de 'Python For Everyone'.
19. Crea una sigla a partir de 'Coding For All'.
20. Usando `index`, determina la primera aparición de la letra 'C' en 'Coding For All'.
21. Usando `index`, determina la primera aparición de la letra 'F' en 'Coding For All'.
22. Usa `rfind` para determinar la última aparición de 'l' en 'Coding For All People'.
23. Usa `index` o `find` para encontrar la primera aparición de la palabra 'because' en: 'You cannot end a sentence with because because because is a conjunction'
24. Usa `rindex` para encontrar la última aparición de la palabra 'because' en: 'You cannot end a sentence with because because because is a conjunction'.
25. Elimina la frase 'because because because' de: 'You cannot end a sentence with because because because is a conjunction'.
26. Encuentra la primera aparición de la palabra 'because' en: 'You cannot end a sentence with because because because is a conjunction'.
27. Elimina la frase 'because because because' de la oración anterior.
28. ¿La cadena 'Coding For All' empieza con la subcadena 'Coding'?
29. ¿La cadena 'Coding For All' termina con la subcadena 'coding'?
30. Elimina los espacios en blanco a la izquierda y derecha de la cadena ' Coding For All '.
31. Usando `isidentifier()`, ¿cuál de las siguientes devuelve `True`?
- 30DaysOfPython
- thirty_days_of_python
32. Dada la lista ['Django', 'Flask', 'Bottle', 'Pyramid', 'Falcon'], únela en una cadena separada por espacios.
33. Usa la secuencia de escape de nueva línea para separar las siguientes oraciones:
```py
I am enjoying this challenge.
I just wonder what is next.
```
34. Usa la secuencia de tabulación para mostrar:
```py
Name Age Country City
Asabeneh 250 Finland Helsinki
```
35. Usa un método de formateo de cadenas para imprimir:
```py
radius = 10
area = 3.14 * radius ** 2
# The area of a circle with radius 10 is 314 meters square.
```
36. Usa un método de formateo de cadenas para imprimir:
```py
8 + 6 = 14
8 - 6 = 2
8 * 6 = 48
8 / 6 = 1.33
8 % 6 = 2
8 // 6 = 1
8 ** 6 = 262144
```
🎉 ¡Felicidades! 🎉
[<< Día 3](./03_operators_sp.md) | [Día 5 >>](./05_lists_sp.md)
================================================
FILE: Spanish/05_lists_sp.md
================================================
[<< Día 4](./04_strings_sp.md) | [Día 6 >>](./06_tuples_sp.md)

- [Día 5](#día-5)
- [Listas](#listas)
- [Cómo crear listas](#cómo-crear-listas)
- [Acceder por índice positivo](#acceder-por-índice-positivo)
- [Acceder por índice negativo](#acceder-por-índice-negativo)
- [Desempaquetado de listas](#desempaquetado-de-listas)
- [Slicing de listas](#slicing-de-listas)
- [Modificar listas](#modificar-listas)
- [Buscar elementos](#buscar-elementos)
- [Agregar elementos](#agregar-elementos)
- [Insertar elementos](#insertar-elementos)
- [Eliminar elementos](#eliminar-elementos)
- [Eliminar con pop()](#eliminar-con-pop)
- [Eliminar con del](#eliminar-con-del)
- [Vaciar la lista](#vaciar-la-lista)
- [Copiar listas](#copiar-listas)
- [Unir listas](#unir-listas)
- [Contar elementos](#contar-elementos)
- [Encontrar el índice de un elemento](#encontrar-el-índice-de-un-elemento)
- [Invertir listas](#invertir-listas)
- [Ordenar listas](#ordenar-listas)
- [💻 Ejercicios - Día 5](#-ejercicios---día-5)
- [Ejercicios: Nivel 1](#ejercicios-nivel-1)
- [Ejercicios: Nivel 2](#ejercicios-nivel-2)
# Día 5
## Listas
En Python hay cuatro tipos de colecciones:
- List: colección ordenada y mutable. Permite elementos duplicados.
- Tuple: colección ordenada e inmutable. Permite elementos duplicados.
- Set: colección no ordenada e indexable; no permite duplicados (aunque se pueden añadir elementos).
- Dictionary: colección no ordenada, mutable y accesible por clave. No permite claves duplicadas.
Una lista es una colección ordenada y mutable que puede contener elementos de diferentes tipos. Una lista puede estar vacía o contener elementos heterogéneos.
### Cómo crear listas
En Python podemos crear listas de dos maneras:
- Usando la función incorporada `list()`
```py
# Sintaxis
lst = list()
```
```py
empty_list = list() # Esta es una lista vacía
print(len(empty_list)) # 0
```
- Usando corchetes `[]`
```py
# Sintaxis
lst = []
```
```py
empty_list = [] # Esta es una lista vacía
print(len(empty_list)) # 0
```
Listas con valores iniciales. Usamos `len()` para comprobar la longitud.
```py
fruits = ['banana', 'orange', 'mango', 'lemon'] # lista de frutas
vegetables = ['Tomato', 'Potato', 'Cabbage','Onion', 'Carrot'] # lista de verduras
animal_products = ['milk', 'meat', 'butter', 'yoghurt'] # lista de animal products
web_techs = ['HTML', 'CSS', 'JS', 'React','Redux', 'Node', 'MongDB'] # lista de web technologies
countries = ['Finland', 'Estonia', 'Denmark', 'Sweden', 'Norway']
# Imprimir listas y su longitud
print('Fruits:', fruits)
print('Number of fruits:', len(fruits))
print('Vegetables:', vegetables)
print('Number of vegetables:', len(vegetables))
print('Animal products:',animal_products)
print('Number of animal products:', len(animal_products))
print('Web technologies:', web_techs)
print('Number of web technologies:', len(web_techs))
print('Countries:', countries)
print('Number of countries:', len(countries))
```
```sh
Salida
Fruits: ['banana', 'orange', 'mango', 'lemon']
Number of fruits: 4
Vegetables: ['Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
Number of vegetables: 5
Animal products: ['milk', 'meat', 'butter', 'yoghurt']
Number of animal products: 4
Web technologies: ['HTML', 'CSS', 'JS', 'React', 'Redux', 'Node', 'MongDB']
Number of web technologies: 7
Countries: ['Finland', 'Estonia', 'Denmark', 'Sweden', 'Norway']
Number of countries: 5
```
- Las listas pueden contener elementos de distintos tipos
```py
lst = ['Asabeneh', 250, True, {'country':'Finland', 'city':'Helsinki'}] # lista con distintos tipos de datos
```
### Acceder por índice positivo
Usamos índices para acceder a los elementos de una lista. Los índices comienzan en 0. La imagen muestra claramente dónde empiezan los índices.

```py
fruits = ['banana', 'orange', 'mango', 'lemon']
first_fruit = fruits[0] # estamos usando su índice para acceder al primer elemento
print(first_fruit) # banana
second_fruit = fruits[1]
print(second_fruit) # orange
last_fruit = fruits[3]
print(last_fruit) # lemon
# Last index
last_index = len(fruits) - 1
last_fruit = fruits[last_index]
```
### Acceder por índice negativo
Los índices negativos cuentan desde el final; `-1` es el último elemento, `-2` el penúltimo.

```py
fruits = ['banana', 'orange', 'mango', 'lemon']
first_fruit = fruits[-4]
last_fruit = fruits[-1]
second_last = fruits[-2]
print(first_fruit) # banana
print(last_fruit) # lemon
print(second_last) # mango
```
### Desempaquetado de listas
```py
lst = ['item1','item2','item3', 'item4', 'item5']
first_item, second_item, third_item, *rest = lst
print(first_item) # item1
print(second_item) # item2
print(third_item) # item3
print(rest) # ['item4', 'item5']
```
```py
# Ejemplo uno
fruits = ['banana', 'orange', 'mango', 'lemon','lime','apple']
first_fruit, second_fruit, third_fruit, *rest = fruits
print(first_fruit) # banana
print(second_fruit) # orange
print(third_fruit) # mango
print(rest) # ['lemon','lime','apple']
# Ejemplo dos
first, second, third,*rest, tenth = [1,2,3,4,5,6,7,8,9,10]
print(first) # 1
print(second) # 2
print(third) # 3
print(rest) # [4,5,6,7,8,9]
print(tenth) # 10
# Ejemplo tres
countries = ['Germany', 'France','Belgium','Sweden','Denmark','Finland','Norway','Iceland','Estonia']
gr, fr, bg, sw, *scandic, es = countries
print(gr)
print(fr)
print(bg)
print(sw)
print(scandic)
print(es)
```
### Slicing de listas
- Índices positivos: especificando inicio, fin y paso obtenemos una nueva lista. (inicio por defecto 0, fin por defecto len(lst) - 1, paso por defecto 1)
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
all_fruits = fruits[0:4] # devuelve todos los elementos
# mismo resultado que arriba
all_fruits = fruits[0:] # Si no se especifica el índice de fin, devolverá todos los elementos desde el inicio hasta el final
orange_and_mango = fruits[1:3] # no incluye el índice 3
orange_mango_lemon = fruits[1:]
orange_and_lemon = fruits[::2] # usamos el tercer parámetro (paso). Toma cada 2 elementos - ['banana', 'mango']
```
- Índices negativos: especificando inicio, fin y paso con índices negativos se obtiene una nueva lista.
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
all_fruits = fruits[-4:] # Devuelve todos los elementos
orange_and_mango = fruits[-3:-1] # No incluye el último elemento, ['orange', 'mango']
orange_mango_lemon = fruits[-3:] # Devuelve los elementos desde -3 hasta el final, ['orange', 'mango', 'lemon']
reverse_fruits = fruits[::-1] # un paso negativo invierte la lista, ['lemon', 'mango', 'orange', 'banana']
```
### Modificar listas
Una lista es una colección ordenada y mutable. A continuación modificamos la lista `fruits`.
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits[0] = 'avocado'
print(fruits) # ['avocado', 'orange', 'mango', 'lemon']
fruits[1] = 'apple'
print(fruits) # ['avocado', 'apple', 'mango', 'lemon']
last_index = len(fruits) - 1
fruits[last_index] = 'lime'
print(fruits) # ['avocado', 'apple', 'mango', 'lime']
```
### Buscar elementos
Use el operador `in` para comprobar si un elemento es miembro de una lista. Véase el ejemplo.
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
does_exist = 'banana' in fruits
print(does_exist) # True
does_exist = 'lime' in fruits
print(does_exist) # False
```
### Agregar elementos
Para añadir un elemento al final de una lista usamos el método `append()`.
```py
# Sintaxis
lst = list()
lst.append(item)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.append('apple')
print(fruits) # ['banana', 'orange', 'mango', 'lemon', 'apple']
fruits.append('lime') # ['banana', 'orange', 'mango', 'lemon', 'apple', 'lime']
print(fruits)
```
### Insertar elementos
Podemos usar el método *insert()* para insertar un elemento en un índice específico de la lista. Ten en cuenta que los demás elementos se desplazarán a la derecha. El método *insert()* recibe dos parámetros: el índice y el elemento a insertar.
```py
# Sintaxis
lst = ['item1', 'item2']
lst.insert(index, item)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.insert(2, 'apple') # inserta 'apple' entre 'orange' y 'mango'
print(fruits) # ['banana', 'orange', 'apple', 'mango', 'lemon']
fruits.insert(3, 'lime') # ['banana', 'orange', 'apple', 'lime', 'mango', 'lemon']
print(fruits)
```
### Eliminar elementos
- Usa el método *remove()* para eliminar un elemento específico de la lista
```py
# Sintaxis
lst = ['item1', 'item2']
lst.remove(item)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon', 'banana']
fruits.remove('banana')
print(fruits) # ['orange', 'mango', 'lemon', 'banana'] - este método elimina la primera aparición del elemento en la lista
fruits.remove('lemon')
print(fruits) # ['orange', 'mango', 'banana']
```
### Eliminar con `pop()`
Usa `pop()` para eliminar el elemento en el índice dado (si no se indica, elimina el último elemento):
```py
# Sintaxis
lst = ['item1', 'item2']
lst.pop() # Último elemento
lst.pop(index)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.pop()
print(fruits) # ['banana', 'orange', 'mango']
fruits.pop(0)
print(fruits) # ['orange', 'mango']
```
### Eliminar con `del`
Usa la palabra clave *del* para eliminar un índice específico, también puede eliminar un rango de índices o eliminar por completo la lista
```py
# Sintaxis
lst = ['item1', 'item2']
del lst[index] # Elimina solo un elemento
del lst # Elimina la lista completa
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon', 'kiwi', 'lime']
del fruits[0]
print(fruits) # ['orange', 'mango', 'lemon', 'kiwi', 'lime']
del fruits[1]
print(fruits) # ['orange', 'lemon', 'kiwi', 'lime']
del fruits[1:3] # elimina elementos en el rango dado; no eliminará el elemento con índice 3!
print(fruits) # ['orange', 'lime']
del fruits
print(fruits) # Esto producirá: NameError: name 'fruits' is not defined
```
### Vaciar listas
Usa `clear()` para vaciar una lista:
```py
# Sintaxis
lst = ['item1', 'item2']
lst.clear()
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.clear()
print(fruits) # []
```
### Copiar listas
Puedes copiar una lista reasignándola a una nueva variable: `list2 = list1`. En ese caso `list2` referencia el mismo objeto; los cambios se reflejarán en ambos. Si quieres una copia independiente usa el método `copy()`.
```py
# Sintaxis
lst = ['item1', 'item2']
lst_copy = lst.copy()
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits_copy = fruits.copy()
print(fruits_copy) # ['banana', 'orange', 'mango', 'lemon'] (copia de la lista)
```
### Unir listas
Hay varias formas de concatenar o unir dos o más listas.
- Suma (+)
```py
# Sintaxis
list3 = list1 + list2
```
```py
positive_numbers = [1, 2, 3, 4, 5]
zero = [0]
negative_numbers = [-5,-4,-3,-2,-1]
integers = negative_numbers + zero + positive_numbers
print(integers) # [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
fruits = ['banana', 'orange', 'mango', 'lemon']
vegetables = ['Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
fruits_and_vegetables = fruits + vegetables
print(fruits_and_vegetables ) # ['banana', 'orange', 'mango', 'lemon', 'Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
```
- Usar el método *extend()*
El método *extend()* puede anexar una lista a otra. Véase el ejemplo a continuación.
```py
# Sintaxis
list1 = ['item1', 'item2']
list2 = ['item3', 'item4', 'item5']
list1.extend(list2)
```
```py
num1 = [0, 1, 2, 3]
num2= [4, 5, 6]
num1.extend(num2)
print('Numbers:', num1) # Numbers: [0, 1, 2, 3, 4, 5, 6]
negative_numbers = [-5,-4,-3,-2,-1]
positive_numbers = [1, 2, 3,4,5]
zero = [0]
negative_numbers.extend(zero)
negative_numbers.extend(positive_numbers)
print('Integers:', negative_numbers) # Integers: [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
fruits = ['banana', 'orange', 'mango', 'lemon']
vegetables = ['Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
fruits.extend(vegetables)
print('Fruits and vegetables:', fruits ) # Fruits and vegetables: ['banana', 'orange', 'mango', 'lemon', 'Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
```
### Contar elementos
Usa el método *count()* para devolver el número de veces que aparece un elemento en la lista:
```py
# Sintaxis
lst = ['item1', 'item2']
lst.count(item)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
print(fruits.count('orange')) # 1
ages = [22, 19, 24, 25, 26, 24, 25, 24]
print(ages.count(24)) # 3
```
### Encontrar el índice de un elemento
El método *index()* devuelve el índice de un elemento en la lista:
```py
# Sintaxis
lst = ['item1', 'item2']
lst.index(item)
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
print(fruits.index('orange')) # 1
ages = [22, 19, 24, 25, 26, 24, 25, 24]
print(ages.index(24)) # 2, primera aparición
```
### Invertir listas
Usa el método *reverse()* para invertir el orden de la lista.
```py
# Sintaxis
lst = ['item1', 'item2']
lst.reverse()
```
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.reverse()
print(fruits) # ['lemon', 'mango', 'orange', 'banana']
ages = [22, 19, 24, 25, 26, 24, 25, 24]
ages.reverse()
print(ages) # [24, 25, 24, 26, 25, 24, 19, 22]
```
### Ordenar listas
Para ordenar una lista podemos usar el método *sort()* o la función incorporada *sorted()*. El método *sort()* reordena la lista en orden ascendente y modifica la lista original. Si el parámetro reverse de *sort()* es True, ordenará la lista en orden descendente.
- sort(): Este método modifica la lista original
```py
# Sintaxis
lst = ['item1', 'item2']
lst.sort() # ascending
lst.sort(reverse=True) # descending
```
**Ejemplo:**
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits.sort()
print(fruits) # ordenadas alfabéticamente, ['banana', 'lemon', 'mango', 'orange']
fruits.sort(reverse=True)
print(fruits) # ['orange', 'mango', 'lemon', 'banana']
ages = [22, 19, 24, 25, 26, 24, 25, 24]
ages.sort()
print(ages) # [19, 22, 24, 24, 24, 25, 25, 26]
ages.sort(reverse=True)
print(ages) # [26, 25, 25, 24, 24, 24, 22, 19]
```
sorted(): No modifica la lista original; devuelve una nueva lista
**Ejemplo:**
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
print(sorted(fruits)) # ['banana', 'lemon', 'mango', 'orange']
# Reverse order
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits = sorted(fruits,reverse=True)
print(fruits) # ['orange', 'mango', 'lemon', 'banana']
```
🌕 Muy bien, has avanzado mucho. Acabas de completar el desafío del día 5. Ahora realiza algunos ejercicios para practicar.
## 💻 Ejercicios - Día 5
### Ejercicios: Nivel 1
1. Declara una lista vacía
2. Declara una lista con más de 5 elementos
3. Encuentra la longitud de la lista
4. Obtén el primer, medio y último elemento de la lista
5. Declara una lista llamada `mixed_data_types` que contenga tu nombre, edad, altura, estado civil y dirección
6. Declara una lista `it_companies` e inicialízala con: Facebook, Google, Microsoft, Apple, IBM, Oracle y Amazon
7. Imprime la lista usando `print()`
8. Imprime el número de empresas en la lista
9. Imprime la primera, la del medio y la última empresa
10. Cambia el nombre de una de las empresas y vuelve a imprimir la lista
11. Agrega una empresa IT a `it_companies`
12. Inserta una empresa IT en la mitad de la lista
13. Cambia el nombre de una empresa en `it_companies` a mayúsculas (¡excepto IBM!)
14. Une `it_companies` en una cadena usando la cadena '#; '
15. Verifica si una empresa existe en `it_companies`
16. Ordena la lista usando el método `sort()`
17. Invierte la lista en orden descendente usando `reverse()`
18. Corta (slice) las primeras 3 empresas de la lista
19. Corta (slice) las últimas 3 empresas de la lista
20. Corta la(s) empresa(s) del medio de la lista
21. Elimina la primera empresa IT de la lista
22. Elimina la(s) empresa(s) del medio de la lista
23. Elimina la última empresa IT de la lista
24. Elimina todas las empresas IT de la lista
25. Destruye la lista `it_companies`
26. Concatena las siguientes listas:
```py
front_end = ['HTML', 'CSS', 'JS', 'React', 'Redux']
back_end = ['Node','Express', 'MongoDB']
```
27. Inserta 'Python' y 'SQL' después de `full_stack` en la lista concatenada.
### Ejercicios: Nivel 2
1. A continuación, una lista con las edades de 10 estudiantes:
```py
ages = [19, 22, 19, 24, 20, 25, 26, 24, 25, 24]
```
- Ordena la lista y encuentra la edad máxima y mínima
- Agrega la edad mínima y máxima nuevamente a la lista
- Encuentra la mediana de las edades (un elemento medio o el promedio de dos elementos medios)
- Encuentra la edad promedio (suma de todos los elementos dividida por su cantidad)
- Encuentra el rango de edades (máximo - mínimo)
- Compara |min - promedio| y |max - promedio| usando la función `abs()`
1. Encuentra el país del medio en la [lista de países](https://github.com/Taki-Ta/30-Days-Of-Python-Simplified_Chinese_Version/tree/master/data/countries.py)
2. Divide la lista de países en dos listas iguales (si es par; si no, la primera lista tendrá un país más)
3. Para la lista ['China', 'Russia', 'USA', 'Finland', 'Sweden', 'Norway', 'Denmark'], separa los tres primeros países de los países nórdicos restantes.
🎉 ¡Felicidades! 🎉
[<< Día 4](./04_strings_sp.md) | [Día 6 >>](./06_tuples_sp.md)
================================================
FILE: Spanish/06_tuples_sp.md
================================================
[<< Día 5](./05_lists_sp.md) | [Día 7 >>](./07_sets_sp.md)

- [Día 6](#día-6)
- [Tuplas](#tuplas)
- [Cómo crear tuplas](#cómo-crear-tuplas)
- [Longitud de la tupla](#longitud-de-la-tupla)
- [Obtener elementos de la tupla](#obtener-elementos-de-la-tupla)
- [Slicing de tuplas](#slicing-de-tuplas)
- [Convertir tupla a lista](#convertir-tupla-a-lista)
- [Comprobar si un elemento está en la tupla](#comprobar-si-un-elemento-está-en-la-tupla)
- [Unir tuplas](#unir-tuplas)
- [Eliminar tupla](#eliminar-tupla)
- [💻 Ejercicios - Día 6](#-ejercicios---día-6)
- [Ejercicios: Nivel 1](#ejercicios-nivel-1)
- [Ejercicios: Nivel 2](#ejercicios-nivel-2)
# Día 6
## Tuplas
Una tupla es una colección ordenada e inmutable que puede contener distintos tipos de datos. Una vez creada una tupla, no podemos cambiar sus valores. No podemos usar métodos como add, insert o remove en una tupla porque no es modificable (es inmutable). A diferencia de las listas, las tuplas tienen menos métodos. Los métodos asociados a tuplas son:
- tuple(): crea una tupla vacía
- count(): cuenta cuántas veces aparece un elemento en la tupla
- index(): busca el índice de un elemento en la tupla
- Operador +: concatena dos o más tuplas creando una nueva tupla
### Cómo crear tuplas
- Crear una tupla vacía
```py
# Sintaxis
empty_tuple = ()
# o usando el constructor de tuplas
empty_tuple = tuple()
```
- Crear una tupla con valores iniciales
```py
# Sintaxis
tpl = ('item1', 'item2','item3')
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
```
### Longitud de la tupla
Usamos la función _len()_ para obtener la longitud de una tupla.
```py
# Sintaxis
tpl = ('item1', 'item2', 'item3')
len(tpl)
```
### Obtener elementos de la tupla
- Índices positivos
Al igual que con las listas, usamos índices positivos o negativos para acceder a los elementos de una tupla.

```py
# Sintaxis
tpl = ('item1', 'item2', 'item3')
first_item = tpl[0]
second_item = tpl[1]
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
first_fruit = fruits[0]
second_fruit = fruits[1]
last_index =len(fruits) - 1
last_fruit = fruits[las_index]
```
- Índices negativos
Los índices negativos cuentan desde el final: -1 es el último elemento, -2 el penúltimo, y así sucesivamente.

```py
# Sintaxis
tpl = ('item1', 'item2', 'item3','item4')
first_item = tpl[-4]
second_item = tpl[-3]
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
first_fruit = fruits[-4]
second_fruit = fruits[-3]
last_fruit = fruits[-1]
```
### Slicing de tuplas
Podemos extraer subtuplas especificando un rango de índices de inicio y fin; el resultado es una nueva tupla con los elementos seleccionados.
- Rango de índices positivos
```py
# Sintaxis
tpl = ('item1', 'item2', 'item3','item4')
all_items = tpl[0:4] # todos los elementos
all_items = tpl[0:] # todos los elementos
middle_two_items = tpl[1:3] # no incluye el índice 3
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
all_fruits = fruits[0:4] # todos los elementos
all_fruits= fruits[0:] # todos los elementos
orange_mango = fruits[1:3] # no incluye el índice 3
orange_to_the_rest = fruits[1:]
```
- Rango de índices negativos
```py
# Sintaxis
tpl = ('item1', 'item2', 'item3','item4')
all_items = tpl[-4:] # todos los elementos
middle_two_items = tpl[-3:-1] # no incluye el índice 3
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
all_fruits = fruits[-4:] # todos los elementos
orange_mango = fruits[-3:-1] # no incluye el índice 3
orange_to_the_rest = fruits[-3:]
```
### Convertir tupla a lista
Podemos convertir una tupla en una lista y viceversa. Si queremos modificar una tupla, conviene convertirla primero en lista.
```py
# Sintaxis
tpl = ('item1', 'item2', 'item3','item4')
lst = list(tpl)
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
fruits = list(fruits)
fruits[0] = 'apple'
print(fruits) # ['apple', 'orange', 'mango', 'lemon']
fruits = tuple(fruits)
print(fruits) # ('apple', 'orange', 'mango', 'lemon')
```
### Comprobar si un elemento está en la tupla
Podemos usar el operador _in_ para comprobar si un elemento pertenece a la tupla; devuelve un valor booleano.
```py
# Sintaxis
tpl = ('item1', 'item2', 'item3','item4')
'item2' in tpl # True
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
print('orange' in fruits) # True
print('apple' in fruits) # False
fruits[0] = 'apple' # TypeError: 'tuple' object does not support item assignment
```
### Unir tuplas
Podemos concatenar dos o más tuplas usando el operador +.
```py
# Sintaxis
tpl1 = ('item1', 'item2', 'item3')
tpl2 = ('item4', 'item5','item6')
tpl3 = tpl1 + tpl2
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
vegetables = ('Tomato', 'Potato', 'Cabbage','Onion', 'Carrot')
fruits_and_vegetables = fruits + vegetables
```
### Eliminar tupla
No se pueden eliminar elementos individuales de una tupla, pero sí se puede eliminar la tupla completa con la palabra clave _del_.
```py
# Sintaxis
tpl1 = ('item1', 'item2', 'item3')
del tpl1
```
```py
fruits = ('banana', 'orange', 'mango', 'lemon')
del fruits
```
🌕 Muy bien, lo conseguiste. Acabas de completar el desafío del día 6. Ahora realiza algunos ejercicios para practicar.
## 💻 Ejercicios - Día 6
### Ejercicios: Nivel 1
1. Crea una tupla vacía
2. Crea una tupla con los nombres de tus hermanos y hermanas (pueden ser ficticios)
3. Concatena las tuplas de hermanos y asígnalas a `siblings`
4. ¿Cuántos hermanos tienes?
5. Modifica la tupla de `siblings` y añade los nombres de tus padres; asígnala a `family_members`
### Ejercicios: Nivel 2
1. Extrae los hermanos y los padres desde `family_members`
2. Crea las tuplas `fruits`, `vegetables` y `animal_products`. Concatena las tres tuplas y asígnalas a la variable `food_stuff_tp`
3. Convierte la tupla `food_stuff_tp` en la lista `food_stuff_lt`
4. Extrae los elementos del medio desde la tupla `food_stuff_tp` o la lista `food_stuff_lt`
5. Extrae las primeras tres y las últimas tres entradas de la lista `food_stuff_lt`
6. Elimina completamente la tupla `food_stuff_tp`
7. Comprueba si existen los elementos:
- Verifica si 'Estonia' está en la tupla `nordic_countries`
- Verifica si 'Iceland' está en la tupla `nordic_countries`
```py
nordic_countries = ('Denmark', 'Finland','Iceland', 'Norway', 'Sweden')
```
[<< Día 5](./05_lists_sp.md) | [Día 7 >>](./07_sets_sp.md)
================================================
FILE: Spanish/07_sets_sp.md
================================================
[<< Día 6](./06_tuples_sp.md) | [Día 8 >>](./08_dictionaries_sp.md)

- [📘 Día 7](#-día-7)
- [Conjuntos](#conjuntos)
- [Crear conjuntos](#crear-conjuntos)
- [Obtener la longitud del conjunto](#obtener-la-longitud-del-conjunto)
- [Acceder a elementos del conjunto](#acceder-a-elementos-del-conjunto)
- [Comprobar elementos](#comprobar-elementos)
- [Añadir elementos al conjunto](#añadir-elementos-al-conjunto)
- [Eliminar elementos del conjunto](#eliminar-elementos-del-conjunto)
- [Vaciar el conjunto](#vaciar-el-conjunto)
- [Eliminar conjunto](#eliminar-conjunto)
- [Convertir lista a conjunto](#convertir-lista-a-conjunto)
- [Unir conjuntos](#unir-conjuntos)
- [Encontrar intersección](#encontrar-intersección)
- [Comprobar subconjuntos y superconjuntos](#comprobar-subconjuntos-y-superconjuntos)
- [Comprobar la diferencia entre conjuntos](#comprobar-la-diferencia-entre-conjuntos)
- [Encontrar diferencia simétrica](#encontrar-diferencia-simétrica)
- [Comprobar conjuntos disjuntos](#comprobar-conjuntos-disjuntos)
- [💻 Ejercicios - Día 7](#-ejercicios---día-7)
- [Ejercicios: Nivel 1](#ejercicios-nivel-1)
- [Ejercicios: Nivel 2](#ejercicios-nivel-2)
- [Ejercicios: Nivel 3](#ejercicios-nivel-3)
# 📘 Día 7
## Conjuntos
Un conjunto es una colección de elementos. Volvamos a las clases de matemáticas de primaria o secundaria: la definición matemática de conjuntos aplica también en Python. Un conjunto es una colección desordenada y no indexada de elementos distintos. En Python, los conjuntos almacenan elementos únicos y se pueden encontrar la _unión_, la _intersección_, la _diferencia_, la _diferencia simétrica_, los _subconjuntos_, los _superconjuntos_ y los _conjuntos disjuntos_ entre conjuntos.
### Crear conjuntos
Usamos la función incorporada _set()_.
- Crear un conjunto vacío
```py
# Sintaxis
st = set()
```
- Crear un conjunto con elementos iniciales
```py
# Sintaxis
st = {'item1', 'item2', 'item3', 'item4'}
```
**Ejemplo:**
```py
# Sintaxis
fruits = {'banana', 'orange', 'mango', 'lemon'}
```
### Obtener la longitud del conjunto
Usamos la función **len()** para obtener la longitud de un conjunto.
```py
# Sintaxis
st = {'item1', 'item2', 'item3', 'item4'}
len(st)
```
**Ejemplo:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
len(fruits)
```
### Acceder a elementos del conjunto
Usamos bucles para recorrer los elementos. Veremos esto con más detalle en la sección de bucles.
### Comprobar elementos
Para comprobar si un elemento existe en un conjunto usamos el operador de pertenencia _in_.
```py
# Sintaxis
st = {'item1', 'item2', 'item3', 'item4'}
print("Does set st contain item3? ", 'item3' in st) # Does set st contain item3? True
```
**Ejemplo:**
```py
fruits = {'plátano', 'naranja', 'mango', 'limón'}
print('mango' in fruits ) # True
```
### Añadir elementos al conjunto
Una vez creado el conjunto no podemos cambiar elementos existentes, pero sí podemos añadir nuevos.
- Usar el método _add()_ para agregar un solo elemento
```py
# Sintaxis
st = {'item1', 'item2', 'item3', 'item4'}
st.add('item5')
```
**Ejemplo:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
fruits.add('lime')
```
- Usar el método _update()_ para agregar varios elementos
El método _update()_ permite añadir múltiples elementos; recibe un iterable como argumento.
```py
# Sintaxis
st = {'item1', 'item2', 'item3', 'item4'}
st.update(['item5','item6','item7'])
```
**Ejemplo:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
vegetables = ('tomato', 'potato', 'cabbage','onion', 'carrot')
fruits.update(vegetables)
```
### Eliminar elementos del conjunto
Podemos usar el método _remove()_ para eliminar un elemento de un conjunto. Si el elemento no existe, _remove()_ lanzará un error; por eso es útil comprobar antes si existe. El método _discard()_ no lanzará error si el elemento no existe.
```py
# Sintaxis
st = {'item1', 'item2', 'item3', 'item4'}
st.remove('item2')
```
El método _pop()_ elimina y devuelve un elemento aleatorio del conjunto.
**Ejemplo:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
fruits.pop() # Elimina un elemento aleatorio del conjunto
```
Si nos interesa el elemento eliminado.
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
removed_item = fruits.pop()
```
### Vaciar el conjunto
Si queremos vaciar todas las entradas de un conjunto, podemos usar el método _clear()_.
```py
# Sintaxis
st = {'item1', 'item2', 'item3', 'item4'}
st.clear()
```
**Ejemplo:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
fruits.clear()
print(fruits) # set()
```
### Eliminar conjunto
Si queremos eliminar el conjunto por completo, podemos usar el operador _del_.
```py
# Sintaxis
st = {'item1', 'item2', 'item3', 'item4'}
del st
```
**Ejemplo:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
del fruits
```
### Convertir lista a conjunto
Podemos convertir una lista en un conjunto y viceversa. Convertir una lista a conjunto elimina duplicados y conserva solo elementos únicos.
```py
# Sintaxis
lst = ['item1', 'item2', 'item3', 'item4', 'item1']
st = set(lst) # {'item2', 'item4', 'item1', 'item3'} - El orden es aleatorio, ya que los conjuntos son generalmente no ordenados
```
**Ejemplo:**
```py
fruits = ['banana', 'orange', 'mango', 'lemon','orange', 'banana']
fruits = set(fruits) # {'mango', 'lemon', 'banana', 'orange'}
```
### Unir conjuntos
Podemos usar los métodos _union()_ o _update()_ para combinar dos conjuntos.
- Union
Este método devuelve un nuevo conjunto
```py
# Sintaxis
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item5', 'item6', 'item7', 'item8'}
st3 = st1.union(st2)
```
**Ejemplo:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
vegetables = {'tomato', 'potato', 'cabbage','onion', 'carrot'}
print(fruits.union(vegetables)) # {'lemon', 'carrot', 'tomato', 'banana', 'mango', 'orange', 'cabbage', 'potato', 'onion'}
```
- Update
Este método inserta los elementos de un conjunto en el conjunto dado
```py
# Sintaxis
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item5', 'item6', 'item7', 'item8'}
st1.update(st2) # Los elementos de st2 se añaden a st1
```
**Ejemplo:**
```py
fruits = {'banana', 'orange', 'mango', 'lemon'}
vegetables = {'tomato', 'potato', 'cabbage','onion', 'carrot'}
fruits.update(vegetables)
print(fruits) # {'lemon', 'carrot', 'tomato', 'banana', 'mango', 'orange', 'cabbage', 'potato', 'onion'}
```
### Encontrar intersección
La intersección devuelve un conjunto con los elementos que están presentes en ambos conjuntos. Véase el ejemplo.
```py
# Sintaxis
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item3', 'item2'}
st1.intersection(st2) # {'item3', 'item2'}
```
**Ejemplo:**
```py
whole_numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
even_numbers = {0, 2, 4, 6, 8, 10}
whole_numbers.intersection(even_numbers) # {0, 2, 4, 6, 8, 10}
python = {'p', 'y', 't', 'h', 'o', 'n'}
dragon = {'d', 'r', 'a', 'g', 'o', 'n'}
python.intersection(dragon) # {'o', 'n'}
```
### Comprobar subconjuntos y superconjuntos
Un conjunto puede ser subconjunto o superconjunto de otro:
- Subconjunto: _issubset()_
- Superconjunto: _issuperset()_
```py
# Sintaxis
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item2', 'item3'}
st2.issubset(st1) # True
st1.issuperset(st2) # True
```
**Ejemplo:**
```py
whole_numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
even_numbers = {0, 2, 4, 6, 8, 10}
whole_numbers.issubset(even_numbers) # Falso, porque es un superconjunto
whole_numbers.issuperset(even_numbers) # Verdadero
python = {'p', 'y', 't', 'h', 'o', 'n'}
dragon = {'d', 'r', 'a', 'g', 'o', 'n'}
python.issubset(dragon) # Falso
```
### Comprobar la diferencia entre conjuntos
Devuelve la diferencia entre dos conjuntos.
```py
# Sintaxis
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item2', 'item3'}
st2.difference(st1) # set()
st1.difference(st2) # {'item1', 'item4'} => st1\st2
```
**Ejemplo:**
```py
whole_numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
even_numbers = {0, 2, 4, 6, 8, 10}
whole_numbers.difference(even_numbers) # {1, 3, 5, 7, 9}
python = {'p', 'y', 't', 'o', 'n'}
dragon = {'d', 'r', 'a', 'g', 'o', 'n'}
python.difference(dragon) # {'p', 'y', 't'} - El resultado es desordenado (propiedad de los conjuntos)
dragon.difference(python) # {'d', 'r', 'a', 'g'}
```
### Encontrar diferencia simétrica
Devuelve la diferencia simétrica entre dos conjuntos. Es decir, devuelve los elementos que pertenecen a uno de los conjuntos pero no a ambos; matemáticamente: (A\B) ∪ (B\A).
```py
# Sintaxis
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item2', 'item3'}
# Significa (A\B) ∪ (B\A)
st2.symmetric_difference(st1) # {'item1', 'item4'}
```
**Ejemplo:**
```py
whole_numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
some_numbers = {1, 2, 3, 4, 5}
whole_numbers.symmetric_difference(some_numbers) # {0, 6, 7, 8, 9, 10}
python = {'p', 'y', 't', 'h', 'o', 'n'}
dragon = {'d', 'r', 'a', 'g', 'o', 'n'}
python.symmetric_difference(dragon) # {'r', 't', 'p', 'y', 'g', 'a', 'd', 'h'}
```
### Comprobar conjuntos disjuntos
Si dos conjuntos no comparten elementos se dicen disjuntos. Podemos usar el método _isdisjoint()_ para comprobar si dos conjuntos son disjuntos.
```py
# Sintaxis
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item2', 'item3'}
st2.isdisjoint(st1) # Falso
```
**Ejemplo:**
```py
even_numbers = {0, 2, 4, 6, 8}
odd_numbers = {1, 3, 5, 7, 9}
even_numbers.isdisjoint(odd_numbers) # Verdadero, porque no comparten elementos
python = {'p', 'y', 't', 'h', 'o', 'n'}
dragon = {'d', 'r', 'a', 'g', 'o', 'n'}
python.isdisjoint(dragon) # Falso, comparten {'o', 'n'}
```
🌕 Eres una estrella en ascenso. Acabas de completar el desafío del día 7. Ahora realiza algunos ejercicios para practicar.
## 💻 Ejercicios - Día 7
```py
# Conjuntos
it_companies = {'Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon'}
A = {19, 22, 24, 20, 25, 26}
B = {19, 22, 20, 25, 26, 24, 28, 27}
age = [22, 19, 24, 25, 26, 24, 25, 24]
```
### Ejercicios: Nivel 1
1. Encuentra la longitud del conjunto `it_companies`
2. Agrega 'Twitter' a `it_companies`
3. Inserta varias empresas IT a `it_companies` de una sola vez
4. Elimina una empresa de `it_companies`
5. ¿Cuál es la diferencia entre `remove()` y `discard()`?
### Ejercicios: Nivel 2
1. Concatena A y B
2. Encuentra la intersección entre A y B
3. ¿Es A un subconjunto de B?
4. ¿Son A y B conjuntos disjuntos?
5. Combina A con B y viceversa
6. ¿Cuál es la diferencia simétrica entre A y B?
7. Elimina un conjunto por completo
### Ejercicios: Nivel 3
1. Convierte la lista de edades a un conjunto y compara la longitud de la lista y la del conjunto: ¿cuál es mayor?
2. Explica la diferencia entre estos tipos de datos: cadena, lista, tupla y conjunto
3. Para la frase _"Soy profesor, me gusta motivar y enseñar a las personas."_ ¿cuántas palabras únicas tiene? Usa `split()` y conjuntos para obtener las palabras únicas.
🎉 ¡Felicidades! 🎉
[<< Día 6](./06_tuples_sp.md) | [Día 8 >>](./08_dictionaries_sp.md)
================================================
FILE: Spanish/08_dictionaries_sp.md
================================================
[<< Día 7](./07_sets_sp.md) | [Día 9 >>](./09_conditionals_sp.md)

- [📘 Día 8](#-día-8)
- [Diccionarios](#diccionarios)
- [Crear diccionarios](#crear-diccionarios)
- [Longitud del diccionario](#longitud-del-diccionario)
- [Acceder a elementos del diccionario](#acceder-a-elementos-del-diccionario)
- [Añadir elementos al diccionario](#añadir-elementos-al-diccionario)
- [Modificar elementos del diccionario](#modificar-elementos-del-diccionario)
- [Comprobar claves en el diccionario](#comprobar-claves-en-el-diccionario)
- [Eliminar pares clave-valor del diccionario](#eliminar-pares-clave-valor-del-diccionario)
- [Convertir diccionario a lista de tuplas](#convertir-diccionario-a-lista-de-tuplas)
- [Vaciar diccionario](#vaciar-diccionario)
- [Eliminar diccionario](#eliminar-diccionario)
- [Copiar diccionario](#copiar-diccionario)
- [Convertir claves a lista](#convertir-claves-a-lista)
- [Convertir valores a lista](#convertir-valores-a-lista)
- [💻 Ejercicios - Día 8](#-ejercicios---día-8)
# 📘 Día 8
## Diccionarios
Un diccionario es un tipo de datos compuesto por pares clave-valor desordenados y modificables (mutables).
### Crear diccionarios
Para crear diccionarios, usamos llaves {} o la función incorporada _dict()_.
```py
# Sintaxis
empty_dict = {}
# Diccionario con valores
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
```
**Ejemplo:**
```py
person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_married':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
```
El diccionario anterior muestra que los valores pueden ser de cualquier tipo de datos: cadenas, booleanos, listas, tuplas, conjuntos o diccionarios.
### Longitud del diccionario
Esta función comprueba la cantidad de pares clave-valor en el diccionario.
```py
# Sintaxis
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
print(len(dct)) # 4
```
**Ejemplo:**
```py
person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_married':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
print(len(person)) # 7
```
### Acceder a elementos del diccionario
Podemos acceder a los elementos del diccionario referenciando sus claves.
```py
# Sintaxis
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
print(dct['key1']) # value1
print(dct['key4']) # value4
```
**Ejemplo:**
```py
person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_married':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
print(person['first_name']) # Asabeneh
print(person['country']) # Finland
print(person['skills']) # ['JavaScript', 'React', 'Node', 'MongoDB', 'Python']
print(person['skills'][0]) # JavaScript
print(person['address']['street']) # Space street
print(person['city']) # Error
```
Cuando se accede a un elemento por clave, si la clave no existe se lanzará un error. Para evitarlo, primero compruebe si existe la clave o use el método _get_. El método get devuelve None si la clave no existe (que es un objeto de tipo NoneType).
```py
person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_married':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
print(person.get('first_name')) # Asabeneh
print(person.get('country')) # Finland
print(person.get('skills')) #['HTML','CSS','JavaScript', 'React', 'Node', 'MongoDB', 'Python']
print(person.get('city')) # None
```
### Añadir elementos al diccionario
Podemos añadir nuevos pares clave-valor al diccionario
```py
# Sintaxis
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
dct['key5'] = 'value5'
```
**Ejemplo:**
```py
person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_married':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
person['job_title'] = 'Instructor'
person['skills'].append('HTML')
print(person)
```
### Modificar elementos del diccionario
Podemos modificar elementos del diccionario
```py
# Sintaxis
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
dct['key1'] = 'value-one'
```
**Ejemplo:**
```py
person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_married':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
person['first_name'] = 'Eyob'
person['age'] = 252
```
### Comprobar claves en el diccionario
Usamos el operador _in_ para comprobar si una clave existe en el diccionario
```py
# Sintaxis
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
print('key2' in dct) # True
print('key5' in dct) # False
```
### Eliminar pares clave-valor del diccionario
- _pop(key)_: elimina el elemento con la clave especificada
- _popitem()_: elimina el último elemento
- _del_: elimina el elemento con la clave especificada
```py
# Sintaxis
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
dct.pop('key1') # elimina el elemento key1
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
dct.popitem() # elimina el último elemento
del dct['key2'] # elimina el elemento key2
```
**Ejemplo:**
```py
person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_married':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
person.pop('first_name') # elimina el elemento first_name
person.popitem() # elimina el último elemento
del person['is_married'] # elimina el elemento is_married
```
### Convertir diccionario a lista de tuplas
El método _items()_ convierte el diccionario en una lista de tuplas.
```py
# Sintaxis
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
print(dct.items()) # dict_items([('key1', 'value1'), ('key2', 'value2'), ('key3', 'value3'), ('key4', 'value4')])
```
### Vaciar diccionario
Si no necesitamos los elementos del diccionario, podemos usar el método _clear()_ para vaciarlo
```py
# Sintaxis
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
print(dct.clear()) # None
```
### Eliminar diccionario
Si ya no necesitamos el diccionario, podemos eliminarlo por completo
```py
# Sintaxis
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
del dct
```
### Copiar diccionario
Podemos usar el método _copy()_ para copiar un diccionario. Usar copy evita que el diccionario original sea modificado.
```py
# Sintaxis
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
dct_copy = dct.copy() # {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
```
### Obtener lista de claves del diccionario
El método keys() nos da una lista con todas las claves del diccionario.
```py
# Sintaxis
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
keys = dct.keys()
print(keys) # dict_keys(['key1', 'key2', 'key3', 'key4'])
```
### Obtener lista de valores del diccionario
El método values() nos da una lista con todos los valores del diccionario.
```py
# Sintaxis
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
values = dct.values()
print(values) # dict_values(['value1', 'value2', 'value3', 'value4'])
```
🌕 ¡Bien hecho! Ahora dominas las potentes capacidades de los diccionarios. Has completado el desafío del Día 8, estás un paso más cerca del éxito. Ahora ejercita tu mente y tu cuerpo.
## 💻 Ejercicios - Día 8
1. Crea un diccionario vacío llamado dog
2. Añade las claves name, color, breed, legs y age al diccionario dog
3. Crea un diccionario student con las claves first_name, last_name, gender, age, marital status, skills, country, city y address
4. Obtén la longitud del diccionario student
5. Obtén el valor de skills y comprueba su tipo; debe ser una lista
6. Modifica skills añadiendo una o dos habilidades
7. Obtén la lista de claves del diccionario
8. Obtén la lista de valores del diccionario
9. Usa el método _items()_ para convertir el diccionario en una lista de tuplas
10. Elimina un elemento del diccionario
11. Elimina uno de los diccionarios
🎉 ¡Felicidades! 🎉
[<< Día 7](./07_sets_sp.md) | [Día 9 >>](./09_conditionals_sp.md)
================================================
FILE: Spanish/09_conditionals_sp.md
================================================
30 días de Python: Día 9 - Sentencias condicionales
[<< Día 8](./08_dictionaries_sp.md) | [Día 10 >>](./10_loops_sp.md)

- [📘 Día 9](#-día-9)
- [Sentencias condicionales](#sentencias-condicionales)
- [Condición If](#condición-if)
- [If Else](#if-else)
- [If Elif Else](#if-elif-else)
- [Abreviación](#abreviación)
- [Condicionales anidados](#condicionales-anidados)
- [If y operadores lógicos](#if-y-operadores-lógicos)
- [If y operador lógico Or](#if-y-operador-lógico-or)
- [💻 Ejercicios - Día 9](#-ejercicios---día-9)
- [Ejercicios: Nivel 1](#ejercicios-nivel-1)
# 📘 Día 9
## Sentencias condicionales
Por defecto, las sentencias en un script de Python se ejecutan secuencialmente de arriba hacia abajo. Si la lógica lo requiere, podemos cambiar el orden de dos maneras:
- Ejecución condicional: si una expresión es verdadera, se ejecutan uno o más bloques de código
- Ejecución repetitiva: mientras una expresión sea verdadera, se repiten uno o más bloques de código. En esta sección discutiremos las sentencias *if*, *else* y *elif*. Los operadores de comparación y lógicos vistos antes serán útiles aquí.
### Condición If
En Python y otros lenguajes, la palabra clave *if* se usa para comprobar si una condición es verdadera y ejecutar un bloque de código. Recuerda la indentación después de los dos puntos.
```py
# Sintaxis
if condition:
# Si la condición es verdadera, ejecutar este bloque de código
```
**Ejemplo 1**
```py
a = 3
if a > 0:
print('A es un número positivo')
# A es un número positivo
```
Como se muestra arriba, 3 es mayor que 0. La condición es verdadera y se ejecuta el bloque de código. Si la condición fuera falsa, no veríamos resultado; para manejar condiciones falsas usamos el bloque *else*.
### If Else
Si la condición es verdadera se ejecuta el primer bloque, de lo contrario se ejecuta el bloque *else*.
```py
# Sintaxis
if condition:
# Si la condición es verdadera, ejecutar este bloque
else:
# Si la condición es falsa, ejecutar este bloque
```
**Ejemplo:**
```py
a = 3
if a < 0:
print('A es un número negativo')
else:
print('A es un número positivo')
```
La condición anterior es falsa, por eso se ejecuta el bloque *else*. ¿Y si tenemos más de dos condiciones? Podemos usar *elif*.
### If Elif Else
En la vida tomamos decisiones cada día que implican más de una condición. En programación, cuando tenemos múltiples condiciones, usamos *elif*.
```py
# Sintaxis
if condition:
# código
elif condition:
# código
else:
# código
```
**Ejemplo:**
```py
a = 0
if a > 0:
print('A es un número positivo')
elif a < 0:
print('A es un número negativo')
else:
print('A es cero')
```
### Abreviación
```py
# Sintaxis
if condición else
```
**Ejemplo:**
```py
a = 3
print('A es positivo') if a > 0 else print('A es negativo') # Se cumple la primera condición, imprimirá 'A es positivo'
```
### Condicionales anidados
Los condicionales pueden anidarse.
```py
# Sintaxis
if condición:
# código
if condición:
# código
```
**Ejemplo:**
```py
a = 0
if a > 0:
if a % 2 == 0:
print('A es un número positivo y par')
else:
print('A es un número positivo')
elif a == 0:
print('A es cero')
else:
print('A es un número negativo')
```
Podemos usar el operador lógico *and* para evitar escribir condicionales anidados.
### If y operadores lógicos
```py
# Sintaxis
if condición and condición:
# código
```
**Ejemplo:**
```py
a = 0
if a > 0 and a % 2 == 0:
print('A es un número positivo y par')
elif a > 0 and a % 2 != 0:
print('A es un número positivo')
elif a == 0:
print('A es cero')
else:
print('A es un número negativo')
```
### If y operador lógico Or
```py
# Sintaxis
if condición or condición:
# código
```
**Ejemplo:**
```py
user = 'James'
access_level = 3
if user == 'admin' or access_level >= 4:
print('Acceso concedido!')
else:
print('Acceso denegado!')
```
🌕 Lo estás haciendo muy bien. Nunca te rindas; las cosas grandiosas requieren tiempo. Acabas de completar el desafío del Día 9; estás a 9 pasos en tu camino hacia lo grande. Haz ahora algunos ejercicios para entrenar tu mente y tu cuerpo.
## 💻 Ejercicios - Día 9
### Ejercicios: Nivel 1
1. Usa input para obtener la edad del usuario (por ejemplo: "Introduce tu edad:"). Si el usuario tiene 18 años o más, muestra: 'Ya tienes la edad suficiente para aprender a conducir.' Si es menor, muestra cuántos años le faltan. Ejemplo de salida:
```sh
Introduce tu edad: 30
Ya tienes la edad suficiente para aprender a conducir.
Salida:
Introduce tu edad: 15
Aún necesitas esperar 3 años para aprender a conducir.
```
2. Usa if…else para comparar my_age y your_age. ¿Quién es mayor (yo o tú)? Usa input("Introduce tu edad:") para obtener la edad. Puedes usar condicionales anidados para imprimir 'año' cuando la diferencia sea 1, 'años' para diferencias mayores, y un mensaje personalizado si my_age = your_age. Salida de ejemplo:
```sh
Introduce tu edad: 30
Tienes 5 años más que yo.
```
3. Pide al usuario dos números con input. Si a > b, imprime 'a es mayor que b'; si a < b, imprime 'a es menor que b'; si son iguales, imprime 'a es igual a b'.
```sh
Introduce el primer número: 4
Introduce el segundo número: 3
4 es mayor que 3
```
### Ejercicios: Nivel 2
1. Escribe un código que asigne una calificación según la nota del estudiante:
```sh
80-100, A
70-79, B
60-69, C
50-59, D
0-49, F
```
2. Comprueba si es otoño, invierno, primavera o verano. Si el usuario introduce:
Septiembre, Octubre o Noviembre → otoño.
Diciembre, Enero o Febrero → invierno.
Marzo, Abril o Mayo → primavera.
Junio, Julio u Agosto → verano.
3. La siguiente lista contiene algunas frutas:
```py
fruits = ['banana', 'orange', 'mango', 'lemon']
```
Si una fruta no está en la lista, añádela e imprime la lista modificada. Si ya existe, imprime 'La fruta ya está en la lista'.
### Ejercicios: Nivel 3
1. Aquí hay un diccionario persona. ¡Siéntete libre de modificarlo!
```py
person = {
'first_name': 'Asabeneh',
'last_name': 'Yetayeh',
'age': 250,
'country': 'Finlandia',
'is_married': True,
'skills': ['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address': {
'street': 'Calle Espacial',
'zipcode': '02210'
}
}
```
- Comprueba si existe la clave skills en el diccionario; si existe, imprime la habilidad central de la lista skills.
- Comprueba si existe la clave skills; si existe, verifica si la persona tiene la habilidad 'Python' e imprime el resultado.
- Si las habilidades son sólo JavaScript y React, imprime 'Es desarrollador frontend'; si incluyen Node, Python y MongoDB, imprime 'Es desarrollador backend'; si incluyen React, Node y MongoDB, imprime 'Es desarrollador full-stack'; en caso contrario, imprime 'Título desconocido' — puedes anidar más condiciones para mayor precisión.
- Si la persona está casada y vive en Finlandia, imprime la siguiente línea:
```py
print('Asabeneh Yetayeh vive en Finlandia. Está casado.')
```
🎉 ¡Felicidades! 🎉
[<< Día 8](./08_dictionaries_sp.md) | [Día 10 >>](./10_loops_sp.md)
================================================
FILE: Spanish/10_loops_sp.md
================================================
[<< Día 9](./09_conditionals_sp.md) | [Día 11 >>](./11_functions_sp.md)

- [📘 Día 10](#-día-10)
- [Bucles](#bucles)
- [Bucle while](#bucle-while)
- [break y continue - parte 1](#break-y-continue---parte-1)
- [Bucle for](#bucle-for)
- [break y continue - parte 2](#break-y-continue---parte-2)
- [Función range()](#función-range)
- [Bucles for anidados](#bucles-for-anidados)
- [for y else](#for-y-else)
- [Sentencia pass](#sentencia-pass)
- [💻 Ejercicios - Día 10](#-ejercicios---día-10)
- [Ejercicios: Nivel 1](#ejercicios-nivel-1)
- [Ejercicios: Nivel 2](#ejercicios-nivel-2)
- [Ejercicios: Nivel 3](#ejercicios-nivel-3)
# 📘 Día 10
## Bucles
La vida está llena de ciclos. En programación realizamos muchas tareas repetitivas. Los lenguajes de programación usan bucles para gestionar tareas repetitivas; en Python hay principalmente dos tipos de bucles:
1. Bucle while
2. Bucle for
### Bucle while
Usamos la palabra clave `while` para crear un bucle while. Repite un bloque de código mientras la condición se cumpla. Cuando la condición se vuelve falsa, el bucle termina y se ejecuta el código que sigue.
```python
# Sintaxis
while condition:
# código
```
**Ejemplo:**
```python
count = 0
while count < 5:
print(count)
count = count + 1
# prints from 0 to 4
```
En el bucle anterior, cuando count llegue a 5 la condición se vuelve falsa y el bucle se detiene.
Si queremos ejecutar un bloque cuando la condición sea falsa, podemos usar la palabra clave `else`.
```python
# syntax
while condition:
code goes here
else:
code goes here
```
**Ejemplo:**
```python
count = 0
while count < 5:
print(count)
count = count + 1
else:
print(count)
```
Cuando count sea 5 la condición será falsa, el bucle terminará y se ejecutará el bloque else; por tanto se imprimirá 5.
### break y continue - parte 1
* break: cuando queremos salir del bucle usamos la palabra clave \break`.`
```python
# syntax
while condition:
code goes here
if another_condition:
break
```
**Example:**
```python
count = 0
while count < 5:
print(count)
count = count + 1
if count == 3:
break
```
El while anterior solo imprimirá 0, 1, 2; cuando count llegue a 3 el bucle terminará.
- Continue: cuando queremos saltarnos la iteración actual y continuar con la siguiente usamos la palabra clave `continue`.
```python
# syntax
while condition:
code goes here
if another_condition:
continue
```
**Ejemplo:**
```python
count = 0
while count < 5:
if count == 3:
count = count + 1
continue
print(count)
count = count + 1
```
El while anterior imprimirá 0, 1, 2, 4 (3 se saltó).
### Bucle for
La palabra clave `for` se usa para crear bucles for. Es similar a otros lenguajes, pero con diferencias sintácticas. Se usa para iterar sobre secuencias (listas, tuplas, diccionarios, conjuntos, cadenas, etc.).
- Bucle for para listas
```python
# syntax
for iterator in lst:
code goes here
```
**Ejemplo:**
```python
numbers = [0, 1, 2, 3, 4, 5]
for number in numbers: # number es un nombre temporal que referencia el elemento de la lista dentro del bucle
print(number) # number se imprimirá línea por línea, de 0 a 5
```
- Bucle for para cadenas
```python
# syntax
for iterator in string:
code goes here
```
**Ejemplo:**
```python
language = 'Python'
for letter in language:
print(letter)
for i in range(len(language)):
print(language[i])
```
- Bucle for para tuplas
```python
# syntax
for iterator in tpl:
code goes here
```
**Ejemplo:**
```python
numbers = (0, 1, 2, 3, 4, 5)
for number in numbers:
print(number)
```
- Bucle for para diccionarios
Al iterar, se recorrerán las claves del diccionario.
```python
# syntax
for iterator in dct:
code goes here
```
**Ejemplo:**
```python
person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_marred':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
for key in person:
print(key) # sólo imprime las claves
for key, value in person.items():
print(key, value) # así podemos acceder a claves y valores durante la iteración
```
- Bucle for para conjuntos
```python
# syntax
for iterator in st:
code goes here
```
**Ejemplo:**
```python
it_companies = {'Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon'}
for company in it_companies:
print(company)
```
### break y continue - parte 2
Pista:
_break_: cuando queremos terminar el bucle antes de completarlo usamos `break`.
```python
# syntax
for iterator in sequence:
code goes here
if condition:
break
```
**Ejemplo:**
```python
numbers = (0,1,2,3,4,5)
for number in numbers:
print(number) # imprime 0, 1, 2, 3
if number == 3:
break
```
En el ejemplo anterior, cuando number sea 3 el bucle terminará.
_continue_: cuando queremos saltarnos la iteración actual y continuar con la siguiente usamos la palabra clave `continue`.
```python
# syntax
for iterator in sequence:
code goes here
if condition:
continue
```
**Ejemplo:**
```python
numbers = (0,1,2,3,4,5)
for number in numbers:
print(number)
if number == 3:
continue
print('Next number should be ', number + 1) if number != 5 else print("loop's end") # En resumen: para condiciones cortas se puede usar if y else en línea
print('outside the loop')
```
En el ejemplo anterior, cuando number es 3, las instrucciones posteriores dentro del bucle se saltan y si hay más elementos por recorrer, continúa con la siguiente iteración.
### Función range()
La función `range()` genera una secuencia de números. La forma _range(start, end, step)_ acepta tres parámetros: inicio, fin y paso. Por defecto inicio es 0 y el paso es 1. Se necesita al menos un parámetro (el valor de fin).
Usando `range()` para generar secuencias
```python
lst = list(range(11))
print(lst) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
st = set(range(1, 11)) # start y stop, paso por defecto 1
print(st) # {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
lst = list(range(0,11,2))
print(lst) # [0, 2, 4, 6, 8, 10]
st = set(range(0,11,2))
print(st) # {0, 2, 4, 6, 8, 10}
```
```python
# syntax
for iterator in range(start, end, step):
```
**Ejemplo:**
```python
for number in range(11):
print(number) # imprime 0 a 10, no incluye 11.
```
### Bucles for anidados
Podemos anidar un bucle dentro de otro; a esto se le llama bucle anidado.
```python
# syntax
for x in y:
for t in x:
print(t)
```
**Ejemplo:**
```python
person = {
'first_name': 'Asabeneh',
'last_name': 'Yetayeh',
'age': 250,
'country': 'Finland',
'is_marred': True,
'skills': ['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address': {
'street': 'Space street',
'zipcode': '02210'
}
}
for key in person:
if key == 'skills':
for skill in person['skills']:
print(skill)
```
### for y else
Si queremos ejecutar un bloque de código al terminar el bucle, podemos usar la palabra clave `else`.
```python
# syntax
for iterator in range(start, end, step):
do something
else:
print('The loop ended')
```
**Ejemplo:**
```python
for number in range(11):
print(number) # prints 0 to 10, not including 11
else:
print('The loop stops at', number)
```
### Sentencia pass
En Python, cuando se requiere una instrucción (por ejemplo después de `:`) pero no queremos ejecutar código, usamos `pass` para evitar errores. También sirve como marcador para rellenar más adelante.
**Ejemplo:**
```python
for number in range(6):
pass
```
🌕 Has dado un gran paso — ¡bien hecho! Acabas de completar el desafío del Día 10; estás a 10 pasos en tu camino hacia lo grande. Ahora hagamos algunos ejercicios para entrenar la mente y los músculos.
## 💻 Ejercicios - Día 10
### Ejercicios: Nivel 1
1. Implementa iteraciones de 0 a 10 usando while y for.
2. Implementa iteraciones de 10 a 0 usando while y for.
3. Escribe un bucle que llame a `print()` 7 veces para producir este triángulo:
```py
#
##
###
####
#####
######
#######
```
4. Usa bucles anidados para producir la siguiente salida:
```sh
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
```
5. Usando un bucle, produce la siguiente salida:
```sh
0 x 0 = 0
1 x 1 = 1
2 x 2 = 4
3 x 3 = 9
4 x 4 = 16
5 x 5 = 25
6 x 6 = 36
7 x 7 = 49
8 x 8 = 64
9 x 9 = 81
10 x 10 = 100
```
6. Recorre con for la lista `['Python', 'Numpy','Pandas','Django', 'Flask']` e imprime cada elemento.
7. Recorre con for de 0 a 100 e imprime todos los números pares.
8. Recorre con for de 0 a 100 e imprime todos los números impares.
### Ejercicios: Nivel 2
1. Usa un for para sumar los números de 0 a 100.
```sh
The sum of all numbers is 5050.
```
2. Usa un for para sumar por separado los impares y los pares de 0 a 100.
```sh
The sum of all odd numbers is 2500. And the sum of all even numbers is 2550.
```
### Ejercicios: Nivel 3
1. Ve a la carpeta data y usa el archivo [countries.py](https://github.com/Asabeneh/30-Days-Of-Python/blob/master/data/countries.py). Itera los países y extrae aquellos que contienen la cadena `land`.
2. Dada la lista `fruits = ['banana', 'orange', 'mango', 'lemon']`, invierte los elementos usando un bucle.
3. Ve a la carpeta data y usa el archivo [countries-data.py](https://github.com/Asabeneh/30-Days-Of-Python/blob/master/data/countries-data.py).
1. ¿Cuántos idiomas distintos hay en los datos?
2. ¿Cuál es el idioma usado por más países?
3. Encuentra los diez países con mayor población.
🎉 ¡Felicidades! 🎉
[<< Día 9](./09_conditionals_sp.md) | [Día 11 >>](./11_functions_sp.md)
================================================
FILE: Spanish/11_functions_sp.md
================================================
[<< Día 10](./10_loops_sp.md) | [Día 12 >>](./12_modules_sp.md)

- [📘 Día 11](#-día-11)
- [Funciones](#funciones)
- [Definir funciones](#definir-funciones)
- [Declarar y llamar a una función](#declarar-y-llamar-a-una-función)
- [Función sin parámetros](#función-sin-parámetros)
- [Funciones que retornan valores - Parte 1](#funciones-que-retornan-valores---parte-1)
- [Funciones con parámetros](#funciones-con-parámetros)
- [Pasar argumentos por clave y valor](#pasar-argumentos-por-clave-y-valor)
- [Funciones que retornan valores - Parte 2](#funciones-que-retornan-valores---parte-2)
- [Funciones con parámetros por defecto](#funciones-con-parámetros-por-defecto)
- [Número arbitrario de argumentos](#número-arbitrario-de-argumentos)
- [Parámetros por defecto y arbitrarios en funciones](#parámetros-por-defecto-y-arbitrarios-en-funciones)
- [Función como parámetro de otra función](#función-como-parámetro-de-otra-función)
- [💻 Ejercicios: Día 11](#-ejercicios-día-11)
- [Ejercicios: Nivel 1](#ejercicios-nivel-1)
- [Ejercicios: Nivel 2](#ejercicios-nivel-2)
- [Ejercicios: Nivel 3](#ejercicios-nivel-3)
# 📘 Día 11
## Funciones
Hasta ahora hemos aprendido muchas funciones integradas de Python. En esta sección nos centraremos en funciones definidas por el usuario. ¿Qué es una función? Antes de crear funciones, entendamos qué es y por qué las necesitamos.
### Definir funciones
Una función es un bloque de código reutilizable o una sentencia de programación que realiza una tarea específica. Para definir o declarar una función, Python provee la palabra clave def. La sintaxis para definir funciones es la siguiente. El código dentro de la función solo se ejecuta cuando la llamamos o la invocamos.
### Declarar y llamar a una función
Cuando creamos una función, decimos que la declaramos. Cuando la usamos, decimos que la llamamos o invocamos. Las funciones pueden tener parámetros o no.
```py
# Sintaxis
# Declarar una función
def function_name():
codes
codes
# Llamar a una función
function_name()
```
### Función sin parámetros
Una función puede declararse sin parámetros.
**Ejemplo:**
```py
def generate_full_name ():
first_name = 'Asabeneh'
last_name = 'Yetayeh'
space = ' '
full_name = first_name + space + last_name
print(full_name)
generate_full_name () # Llamar a una función
def add_two_numbers ():
num_one = 2
num_two = 3
total = num_one + num_two
print(total)
add_two_numbers()
```
### Funciones que retornan valores - Parte 1
Una función también puede devolver un valor; si una función no tiene return, devuelve None. Reescribamos las funciones anteriores usando return. A partir de ahora, cuando llamemos a la función y la imprimamos, obtendremos un valor.
```py
def generate_full_name ():
first_name = 'Asabeneh'
last_name = 'Yetayeh'
space = ' '
full_name = first_name + space + last_name
return full_name
print(generate_full_name())
def add_two_numbers ():
num_one = 2
num_two = 3
total = num_one + num_two
return total
print(add_two_numbers())
```
### Funciones con parámetros
En una función podemos pasar diferentes tipos de datos (números, cadenas, booleanos, listas, tuplas, diccionarios o sets) como parámetros.
- Parámetro único: si una función necesita un parámetro, la llamamos con un argumento.
```py
# Sintaxis
# Declarar una función
def function_name(parameter):
codes
codes
# Llamar a la función
print(function_name(argument))
```
**Ejemplo:**
```py
def greetings (name):
message = name + ', welcome to Python for Everyone!'
return message
print(greetings('Asabeneh'))
def add_ten(num):
ten = 10
return num + ten
print(add_ten(90))
def square_number(x):
return x * x
print(square_number(2))
def area_of_circle (r):
PI = 3.14
area = PI * r ** 2
return area
print(area_of_circle(10))
def sum_of_numbers(n):
total = 0
for i in range(n+1):
total+=i
print(total)
print(sum_of_numbers(10)) # 55
print(sum_of_numbers(100)) # 5050
```
- Dos parámetros: una función puede no tener parámetros o tener uno o varios. Si necesita dos parámetros, la llamamos con dos argumentos.
```py
# Sintaxis
# Declarar una función
def function_name(para1, para2):
codes
codes
# Llamar a la función
print(function_name(arg1, arg2))
```
**Ejemplo:**
```py
def generate_full_name (first_name, last_name):
space = ' '
full_name = first_name + space + last_name
return full_name
print('Full Name: ', generate_full_name('Asabeneh','Yetayeh'))
def sum_two_numbers (num_one, num_two):
sum = num_one + num_two
return sum
print('Sum of two numbers: ', sum_two_numbers(1, 9))
def calculate_age (current_year, birth_year):
age = current_year - birth_year
return age;
print('Age: ', calculate_age(2021, 1819))
def weight_of_object (mass, gravity):
weight = str(mass * gravity)+ ' N' # El valor necesita convertirse a cadena primero
return weight
print('Weight of an object in Newtons: ', weight_of_object(100, 9.81))
```
### Pasar argumentos por clave y valor
Si pasamos argumentos por clave=valor, el orden de los parámetros no importa.
```py
# Sintaxis
# Declarar una función
def function_name(para1, para2):
codes
codes
# Llamar a la función
print(function_name(para1 = 'John', para2 = 'Doe')) # el orden de los parámetros no importa
```
**Ejemplo:**
```py
def print_fullname(firstname, lastname):
space = ' '
full_name = firstname + space + lastname
print(full_name)
print(print_fullname(firstname = 'Asabeneh', lastname = 'Yetayeh'))
def add_two_numbers (num1, num2):
total = num1 + num2
print(total)
print(add_two_numbers(num2 = 3, num1 = 2)) # el orden no importa
```
### Funciones que retornan valores - Parte 2
Si no retornamos un valor en una función, por defecto devuelve _None_. Para devolver un valor usamos la palabra clave _return_ seguida de la variable a retornar. Podemos devolver cualquier tipo de dato desde una función.
- Devolver cadenas:
**Ejemplo:**
```py
def print_name(firstname):
return firstname
print_name('Asabeneh') # Asabeneh
def print_full_name(firstname, lastname):
space = ' '
full_name = firstname + space + lastname
return full_name
print_full_name(firstname='Asabeneh', lastname='Yetayeh')
```
- Devolver números:
**Ejemplo:**
```py
def add_two_numbers (num1, num2):
total = num1 + num2
return total
print(add_two_numbers(2, 3))
def calculate_age (current_year, birth_year):
age = current_year - birth_year
return age;
print('Age: ', calculate_age(2019, 1819))
```
- Devolver booleanos:
**Ejemplo:**
```py
def is_even (n):
if n % 2 == 0:
print('even')
return True # la instrucción return detiene la ejecución adicional en la función
return False
print(is_even(10)) # True
print(is_even(7)) # False
```
- Devolver listas:
**Ejemplo:**
```py
def find_even_numbers(n):
evens = []
for i in range(n + 1):
if i % 2 == 0:
evens.append(i)
return evens
print(find_even_numbers(10))
```
### Funciones con parámetros por defecto
A veces pasamos valores por defecto a los parámetros. Si no proporcionamos un argumento al llamar la función, se usa el valor por defecto.
```py
# Sintaxis
# Declarar una función
def function_name(param = value):
codes
codes
# Llamar a la función
function_name()
function_name(arg)
```
**Ejemplo:**
```py
def greetings (name = 'Peter'):
message = name + ', welcome to Python for Everyone!'
return message
print(greetings())
print(greetings('Asabeneh'))
def generate_full_name (first_name = 'Asabeneh', last_name = 'Yetayeh'):
space = ' '
full_name = first_name + space + last_name
return full_name
print(generate_full_name())
print(generate_full_name('David','Smith'))
def calculate_age (birth_year,current_year = 2021):
age = current_year - birth_year
return age;
print('Age: ', calculate_age(1821))
def weight_of_object (mass, gravity = 9.81):
weight = str(mass * gravity)+ ' N' # gravedad promedio en la superficie de la Tierra
return weight
print('Weight of an object in Newtons: ', weight_of_object(100)) # 9.81 - gravedad promedio en la Tierra
print('Weight of an object in Newtons: ', weight_of_object(100, 1.62)) # gravedad en la Luna
```
### Número arbitrario de argumentos
Si no sabemos cuántos argumentos se pasarán a la función, podemos usar un parámetro con * para aceptar un número arbitrario de argumentos.
```py
# Sintaxis
# Declarar una función
def function_name(*args):
codes
codes
# Llamar a la función
function_name(param1, param2, param3,..)
```
**Ejemplo:**
```py
def sum_all_nums(*nums):
total = 0
for num in nums:
total += num # equivalente a total = total + num
return total
print(sum_all_nums(2, 3, 5)) # 10
```
### Parámetros por defecto y arbitrarios en funciones
```py
def generate_groups (team,*args):
print(team)
for i in args:
print(i)
print(generate_groups('Team-1','Asabeneh','Brook','David','Eyob'))
```
### Función como parámetro de otra función
```py
# Puedes pasar una función como argumento
def square_number (n):
return n * n
def do_something(f, x):
return f(x)
print(do_something(square_number, 3)) # 27
```
🌕 Has avanzado mucho. ¡Sigue así! Has completado el desafío del día 11 y ya llevas 11 pasos en el camino al éxito. Ahora realiza algunos ejercicios para ejercitar la mente y la práctica.
## Testimonios
Es hora de expresar tu opinión sobre el autor y 30DaysOfPython. Puedes dejar tu testimonio en este [enlace](https://testimonify.herokuapp.com/).
## 💻 Ejercicios: Día 11
### Ejercicios: Nivel 1
1. Declara una función _add_two_numbers_. Debe aceptar dos parámetros y devolver su suma.
2. La fórmula del área de un círculo es: area = π x r x r. Escribe una función _area_of_circle_ que la calcule.
3. Escribe una función llamada add_all_nums que acepte un número arbitrario de argumentos y sume todos. Verifica que todos los elementos sean de tipo numérico. Si no, devuelve un mensaje apropiado.
4. La temperatura en Celsius (°C) se puede convertir a Fahrenheit (°F) con: °F = (°C x 9/5) + 32. Escribe una función _convert_celsius_to_fahrenheit_.
5. Escribe una función llamada check_season que acepte un mes y devuelva la estación: otoño, invierno, primavera o verano.
6. Escribe una función llamada calculate_slope que devuelva la pendiente de una ecuación lineal.
7. La ecuación cuadrática se calcula como: ax² + bx + c = 0. Escribe una función _solve_quadratic_eqn_ que calcule las soluciones.
8. Declara una función llamada print_list que acepte una lista y imprima cada elemento.
9. Declara una función llamada reverse_list que acepte un arreglo y devuelva su reverso (usa un bucle).
```py
print(reverse_list([1, 2, 3, 4, 5]))
# [5, 4, 3, 2, 1]
print(reverse_list1(["A", "B", "C"]))
# ["C", "B", "A"]
```
10. Declara una función capitalize_list_items que acepte una lista y devuelva una lista con los elementos en mayúscula.
11. Declara una función add_item que acepte una lista y un ítem. Debe devolver la lista con el ítem agregado al final.
```py
food_staff = ['Potato', 'Tomato', 'Mango', 'Milk'];
print(add_item(food_staff, 'Meat')) # ['Potato', 'Tomato', 'Mango', 'Milk','Meat'];
numbers = [2, 3, 7, 9];
print(add_item(numbers, 5)) [2, 3, 7, 9, 5]
```
12. Declara una función remove_item que acepte una lista y un ítem. Debe devolver la lista con el ítem eliminado.
```py
food_staff = ['Potato', 'Tomato', 'Mango', 'Milk'];
print(remove_item(food_staff, 'Mango')) # ['Potato', 'Tomato', 'Milk'];
numbers = [2, 3, 7, 9];
print(remove_item(numbers, 3)) # [2, 7, 9]
```
13. Declara una función sum_of_numbers que acepte un número y sume todos los números en ese rango.
```py
print(sum_of_numbers(5)) # 15
print(sum_all_numbers(10)) # 55
print(sum_all_numbers(100)) # 5050
```
14. Declara una función sum_of_odds que acepte un número y sume todos los impares en ese rango.
15. Declara una función sum_of_even que acepte un número y sume todos los pares en ese rango.
### Ejercicios: Nivel 2
1. Declara una función evens_and_odds que acepte un entero positivo y calcule la cantidad de pares e impares en ese número.
```py
print(evens_and_odds(100))
# La cantidad de números pares es 50.
# La cantidad de números impares es 50.
```
2. Llama a tu función factorial que acepte un entero y devuelva su factorial.
3. Llama a tu función _is_empty_ que acepte un argumento y verifique si está vacío.
4. Escribe distintas funciones que acepten listas y calculen: media, mediana, moda, rango, varianza y desviación estándar.
### Ejercicios: Nivel 3
1. Escribe una función is_prime que verifique si un número es primo.
2. Escribe una función que verifique si todos los ítems en una lista son únicos.
3. Escribe una función que verifique si todos los ítems en una lista son del mismo tipo de dato.
4. Escribe una función que verifique si una variable proporcionada es un nombre de variable válido en Python.
5. Accede al archivo de datos countries-data.py.
- Crea una función llamada the_most_spoken_languages que devuelva las 10 o 20 lenguas más habladas en el mundo, ordenadas de mayor a menor.
- Crea una función llamada the_most_populated_countries que devuelva los 10 o 20 países más poblados del mundo, ordenados de mayor a menor.
🎉 ¡Felicidades! 🎉
[<< Día 10](./10_loops_sp.md) | [Día 12 >>](./12_modules_sp.md)
================================================
FILE: Spanish/12_modules_sp.md
================================================
[<< Día 11](./11_functions_sp.md) | [Día 13 >>](./13_list_comprehension_sp.md)

- [📘 Día 12](#-día-12)
- [Módulos](#módulos)
- [¿Qué es un módulo?](#¿qué-es-un-módulo?)
- [Crear módulos](#crear-módulos)
- [Importar módulos](#importar-módulos)
- [Importar funciones desde un módulo](#importar-funciones-desde-un-módulo)
- [Importar funciones y renombrarlas](#importar-funciones-y-renombrarlas)
- [Importar módulos incorporados](#importar-módulos-incorporados)
- [Módulo OS](#módulo-os)
- [Módulo sys](#módulo-sys)
- [Módulo statistics](#módulo-statistics)
- [Módulo math](#módulo-math)
- [Módulo string](#módulo-string)
- [Módulo random](#módulo-random)
- [💻 Ejercicios: Día 12](#-ejercicios-día-12)
- [Ejercicios: Nivel 1](#ejercicios-nivel-1)
- [Ejercicios: Nivel 2](#ejercicios-nivel-2)
- [Ejercicios: Nivel 3](#ejercicios-nivel-3)
# 📘 Día 12
## Módulos
### ¿Qué es un módulo?
Un módulo es un archivo que contiene un conjunto de código o funciones que se pueden incluir en una aplicación. Un módulo puede ser un archivo con una sola variable, una función o una biblioteca de gran escala.
### Crear módulos
Para crear un módulo, escribimos código en un script de Python y lo guardamos con extensión .py. En la carpeta del proyecto crea un archivo llamado mymodule.py. Escribamos algo de código en ese archivo.
```py
# archivo mymodule.py
def generate_full_name(firstname, lastname):
return firstname + ' ' + lastname
```
En el directorio del proyecto crea un archivo main.py e importa mymodule.py.
### Importar módulos
Para importar archivos usamos la palabra clave import y el nombre del archivo.
```py
# archivo main.py
import mymodule
print(mymodule.generate_full_name('Asabeneh', 'Yetayeh')) # Asabeneh Yetayeh
```
### Importar funciones desde un módulo
Podemos tener muchas funciones en un archivo y podemos importar cada una por separado.
```py
# archivo main.py
from mymodule import generate_full_name, sum_two_nums, person, gravity
print(generate_full_name('Asabneh','Yetayeh'))
print(sum_two_nums(1,9))
mass = 100
weight = mass * gravity
print(weight)
print(person['firstname'])
```
### Importar funciones y renombrarlas
Durante la importación también podemos renombrar nombres.
```py
# archivo main.py
from mymodule import generate_full_name as fullname, sum_two_nums as total, person as p, gravity as g
print(fullname('Asabneh','Yetayeh'))
print(total(1, 9))
mass = 100
weight = mass * g
print(weight)
print(p)
print(p['firstname'])
```
## Importar módulos incorporados
Al igual que otros lenguajes, podemos importar módulos usando la palabra clave import. A continuación importamos algunos módulos incorporados que usamos con frecuencia. Algunos módulos comunes son: math, datetime, os, sys, random, statistics, collections, json, re
### Módulo OS
El módulo os de Python permite automatizar muchas tareas del sistema operativo. El módulo OS ofrece funciones para crear, cambiar directorio de trabajo, eliminar directorios (carpetas), obtener su contenido y reconocer/cambiar el directorio actual.
```py
# importar módulo
import os
# crear directorio
os.mkdir('directory_name')
# cambiar el directorio actual
os.chdir('path')
# obtener el directorio actual
os.getcwd()
# eliminar directorio
os.rmdir()
```
### Módulo sys
El módulo sys provee funciones y variables para interactuar con diferentes partes del entorno de ejecución de Python. La función sys.argv devuelve la lista de argumentos de la línea de comandos pasados al script de Python. El elemento en el índice 0 de esa lista es siempre el nombre del script, el índice 1 es el primer argumento pasado desde la línea de comandos.
Ejemplo archivo script.py:
```py
import sys
#print(sys.argv[0], argv[1],sys.argv[2]) # esta línea imprimirá: nombre_archivo argumento1 argumento2
print('Welcome {}. Enjoy {} challenge!'.format(sys.argv[1], sys.argv[2]))
```
Para ver cómo funciona el script, en la línea de comandos escribe:
```sh
python script.py Asabeneh 30DaysOfPython
```
Resultado:
```sh
Welcome Asabeneh. Enjoy 30DayOfPython challenge!
```
Algunos comandos útiles de sys:
```py
# salir del script
sys.exit()
# conocer el tamaño máximo de un entero
sys.maxsize
# conocer la ruta de módulos
sys.path
# conocer la versión de Python en uso
sys.version
```
### Módulo statistics
El módulo statistics proporciona funciones de estadísticas para datos numéricos. Algunas funciones comunes definidas en este módulo: mean, median, mode, stdev, etc.
```py
from statistics import * # importar todo del módulo statistics
ages = [20, 20, 4, 24, 25, 22, 26, 20, 23, 22, 26]
print(mean(ages)) # ~22.9
print(median(ages)) # 23
print(mode(ages)) # 20
print(stdev(ages)) # ~2.3
```
### Módulo math
Contiene muchas operaciones matemáticas y constantes.
```py
import math
print(math.pi) # 3.141592653589793, constante pi
print(math.sqrt(2)) # 1.4142135623730951, raíz cuadrada
print(math.pow(2, 3)) # 8.0, potencia
print(math.floor(9.81)) # 9, redondeo hacia abajo
print(math.ceil(9.81)) # 10, redondeo hacia arriba
print(math.log10(100)) # 2, logaritmo base 10
```
Ahora que hemos importado el módulo math con muchas funciones útiles, podemos ver qué funciones contiene usando help(math) o dir(math). Si sólo queremos importar funciones específicas podemos hacerlo así:
```py
from math import pi
print(pi)
```
También podemos importar múltiples funciones:
```py
from math import pi, sqrt, pow, floor, ceil, log10
print(pi) # 3.141592653589793
print(sqrt(2)) # 1.4142135623730951
print(pow(2, 3)) # 8.0
print(floor(9.81)) # 9
print(ceil(9.81)) # 10
print(math.log10(100)) # 2
```
Si queremos importar todas las funciones del módulo matemático podemos usar *.
```py
from math import *
print(pi) # 3.141592653589793, constante pi
print(sqrt(2)) # 1.4142135623730951, raíz cuadrada
print(pow(2, 3)) # 8.0, potencia
print(floor(9.81)) # 9, redondeo hacia abajo
print(ceil(9.81)) # 10, redondeo hacia arriba
print(math.log10(100)) # 2
```
También podemos renombrar funciones al importarlas.
```py
from math import pi as PI
print(PI) # 3.141592653589793
```
### Módulo string
El módulo string es muy útil. Los siguientes ejemplos muestran algunos usos.
```py
import string
print(string.ascii_letters) # abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
print(string.digits) # 0123456789
print(string.punctuation) # !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
```
### Módulo random
Ahora que sabes importar módulos, familiaricémonos con random. El módulo random nos da números aleatorios entre 0 y 0.9999. El módulo tiene muchas funciones; aquí usamos random y randint.
```py
from random import random, randint
print(random()) # no necesita parámetros; devuelve un valor entre 0 y 0.9999
print(randint(5, 20)) # devuelve un entero aleatorio en [5, 20] (inclusive)
```
🌕 ¡Has llegado muy lejos. Sigue así! Acabas de completar el desafío del Día 12 y has dado 12 pasos hacia algo grandioso. Ahora ejercita tu mente y tus músculos.
## 💻 Ejercicios: Día 12
### Ejercicios: Nivel 1
1. Escribe una función que genere un random_user_id de seis caracteres/dígitos.
```py
print(random_user_id());
'1ee33d'
```
2. Modifica la tarea anterior. Declara una función llamada user_id_gen_by_user. No acepta argumentos, pero pide dos entradas: una es la cantidad de caracteres por ID y la otra es cuántos IDs generar.
```py
print(user_id_gen_by_user()) # entrada del usuario: 5 5
#salida:
#kcsy2
#SMFYb
#bWmeq
#ZXOYh
#2Rgxf
print(user_id_gen_by_user()) # 16 5
#1GCSgPLMaBAVQZ26
#YD7eFwNQKNs7qXaT
#ycArC5yrRupyG00S
#UbGxOFI7UXSWAyKN
#dIV0SSUTgAdKwStr
```
3. Escribe una función llamada rgb_color_gen. Debe generar un color RGB (cada valor en el rango 0-255).
```py
print(rgb_color_gen())
# rgb(125,244,255) - la salida debe estar en este formato
```
### Ejercicios: Nivel 2
1. Escribe una función list_of_hexa_colors que devuelva una lista con cualquier cantidad de colores hexadecimales (seis dígitos hexadecimales después de #; el sistema hex usa 0-9 y a-f).
2. Escribe una función list_of_rgb_colors que devuelva una lista con cualquier cantidad de colores RGB.
3. Escribe una función generate_colors que pueda generar cualquier cantidad de colores hexadecimales o RGB.
```py
generate_colors('hexa', 3) # ['#a3e12f','#03ed55','#eb3d2b']
generate_colors('hexa', 1) # ['#b334ef']
generate_colors('rgb', 3) # ['rgb(5, 55, 175','rgb(50, 105, 100','rgb(15, 26, 80']
generate_colors('rgb', 1) # ['rgb(33,79, 176)']
```
### Ejercicios: Nivel 3
1. Llama a tu función shuffle_list, que recibe una lista y devuelve la lista mezclada.
2. Escribe una función que devuelva una lista de siete números aleatorios únicos en el rango 0-9.
🎉 ¡Felicidades! 🎉
[<< Día 11](./11_functions_sp.md) | [Día 13 >>](./13_list_comprehension_sp.md)
================================================
FILE: Spanish/13_list_comprehension_sp.md
================================================
30 Días de Python: Día 13 - Comprensiones de listas
[<< Día 12](./12_modules_sp.md) | [Día 14 >>](./14_higher_order_functions_sp.md)

- [📘 Día 13](#📘-día-13)
- [Comprensiones de listas](#comprensiones-de-listas)
- [Funciones lambda](#funciones-lambda)
- [Crear una función lambda](#crear-una-función-lambda)
- [Funciones lambda dentro de otra función](#lambda-dentro-de-otra-función)
- [💻 Ejercicios: Día 13](#💻-ejercicios-día-13)
# 📘 Día 13
## Comprensiones de listas
En Python, las comprensiones de listas son una forma concisa de crear listas a partir de secuencias. Es una manera corta de crear nuevas listas a partir de secuencias. Las comprensiones de listas son más rápidas que iterar sobre listas con un bucle for.
```py
# sintaxis
[i for i in iterable if expresión]
```
**Ejemplo 1**
Por ejemplo, si quieres convertir una cadena en una lista de caracteres, puedes hacerlo de varias formas. Veamos algunas:
```py
# un método
language = 'Python'
lst = list(language) # convertir la cadena en lista
print(type(lst)) # list
print(lst) # ['P', 'y', 't', 'h', 'o', 'n']
# segunda forma: comprensión de listas
lst = [i for i in language]
print(type(lst)) # list
print(lst) # ['P', 'y', 't', 'h', 'o', 'n']
```
**Ejemplo 2**
Por ejemplo, si quieres generar una lista de números:
```py
# generar números
numbers = [i for i in range(11)] # genera números de 0 a 10
print(numbers) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# también puedes hacer operaciones matemáticas durante la iteración
squares = [i * i for i in range(11)]
print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# también se pueden generar listas de tuplas
numbers = [(i, i * i) for i in range(11)]
print(numbers) # [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
```
**Ejemplo 3**
Las comprensiones de listas pueden combinarse con expresiones if:
```py
# generar números pares
even_numbers = [i for i in range(21) if i % 2 == 0] # genera pares de 0 a 20
print(even_numbers) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
# generar números impares
odd_numbers = [i for i in range(21) if i % 2 != 0] # genera impares de 0 a 20
print(odd_numbers) # [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
# filtrar números: obtengamos los pares positivos
numbers = [-8, -7, -3, -1, 0, 1, 3, 4, 5, 7, 6, 8, 10]
positive_even_numbers = [i for i in range(21) if i % 2 == 0 and i > 0]
print(positive_even_numbers) # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
# aplanar una lista 2D
list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened_list = [number for row in list_of_lists for number in row]
print(flattened_list) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
```
## Funciones lambda
Las funciones lambda son pequeñas funciones anónimas sin nombre. Pueden aceptar cualquier número de argumentos, pero solo una expresión. Las funciones lambda son similares a las funciones anónimas en JavaScript. Son útiles cuando necesitamos una función anónima dentro de otra función.
### Crear una función lambda
Para crear una función lambda usamos la palabra clave lambda, seguido de uno o más parámetros y luego una expresión. La función lambda no usa return explícito; devuelve la expresión implícitamente.
```py
# sintaxis
x = lambda param1, param2, param3: param1 + param2 + param3
print(x(arg1, arg2, arg3))
```
**Ejemplo:**
```py
# función nombrada
def add_two_nums(a, b):
return a + b
print(add_two_nums(2, 3)) # 5
# con lambda
add_two_nums = lambda a, b: a + b
print(add_two_nums(2, 3)) # 5
# lambda autoejecutable
print((lambda a, b: a + b)(2, 3)) # 5
square = lambda x: x ** 2
print(square(3)) # 9
cube = lambda x: x ** 3
print(cube(3)) # 27
# múltiples variables
multiple_variable = lambda a, b, c: a ** 2 - 3 * b + 4 * c
print(multiple_variable(5, 5, 3)) # 22
```
### Funciones lambda dentro de otra función
Uso de lambda dentro de otra función:
```py
def power(x):
return lambda n: x ** n
cube = power(2)(3) # la función power ahora se usa con dos pares de paréntesis
print(cube) # 8
two_power_of_five = power(2)(5)
print(two_power_of_five) # 32
```
🌕 Sigue con el buen trabajo. Mantente motivado; el cielo es tu límite. Has completado el desafío del Día 13 y has dado 13 pasos hacia algo grandioso. Ahora ejercita tu mente y sigue practicando.
## 💻 Ejercicios: Día 13
1. Usa una comprensión de listas para filtrar los números negativos y ceros de la siguiente lista:
```py
numbers = [-4, -3, -2, -1, 0, 2, 4, 6]
```
2. Aplana la siguiente lista de listas a una lista unidimensional:
```py
list_of_lists = [[[1, 2, 3]], [[4, 5, 6]], [[7, 8, 9]]]
Salida:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
```
3. Crea la siguiente lista de tuplas usando una comprensión de listas:
```py
[(0, 1, 0, 0, 0, 0, 0),
(1, 1, 1, 1, 1, 1, 1),
(2, 1, 2, 4, 8, 16, 32),
(3, 1, 3, 9, 27, 81, 243),
(4, 1, 4, 16, 64, 256, 1024),
(5, 1, 5, 25, 125, 625, 3125),
(6, 1, 6, 36, 216, 1296, 7776),
(7, 1, 7, 49, 343, 2401, 16807),
(8, 1, 8, 64, 512, 4096, 32768),
(9, 1, 9, 81, 729, 6561, 59049),
(10, 1, 10, 100, 1000, 10000, 100000)]
```
4. Aplana la siguiente estructura en una nueva lista:
```py
countries = [[('Finlandia', 'Helsinki')], [('Suecia', 'Estocolmo')], [('Noruega', 'Oslo')]]
Salida:
[['Finlandia', 'FIN', 'Helsinki'], ['Suecia', 'SWE', 'Estocolmo'], ['Noruega', 'NOR', 'Oslo']]
```
5. Convierte la siguiente lista en una lista de diccionarios:
```py
countries = [[('Finlandia', 'Helsinki')], [('Suecia', 'Estocolmo')], [('Noruega', 'Oslo')]]
Salida:
[{'País': 'Finlandia', 'Ciudad': 'Helsinki'},
{'País': 'Suecia', 'Ciudad': 'Estocolmo'},
{'País': 'Noruega', 'Ciudad': 'Oslo'}]
```
6. Convierte la siguiente lista en una lista de cadenas concatenadas:
```py
names = [[('Asabeneh', 'Yetayeh')], [('David', 'Smith')], [('Donald', 'Trump')], [('Bill', 'Gates')]]
Salida:
['Asabeneh Yetayeh', 'David Smith', 'Donald Trump', 'Bill Gates']
```
7. Escribe una función lambda que calcule la pendiente o la ordenada al origen de una función lineal.
🎉 ¡Felicidades! 🎉
[<< Día 12](./12_modules_sp.md) | [Día 14 >>](./14_higher_order_functions_sp.md)
================================================
FILE: Spanish/14_higher_order_functions_sp.md
================================================
30 Días de Python: Día 14 - Funciones de orden superior
[<< Día 13](./13_list_comprehension_sp.md) | [Día 15 >>](./15_python_type_errors_cn_sp.md)

- [📘 Día 14](#-día-14)
- [Funciones de orden superior](#funciones-de-orden-superior)
- [Funciones como parámetros](#funciones-como-parámetros)
- [Funciones como valor de retorno](#funciones-como-valor-de-retorno)
- [Closures en Python](#closures-en-python)
- [Decoradores en Python](#decoradores-en-python)
- [Crear decoradores](#crear-decoradores)
- [Aplicar varios decoradores a una función](#aplicar-varios-decoradores-a-una-función)
- [Aceptar parámetros en decoradores](#aceptar-parámetros-en-decoradores)
- [Funciones integradas de orden superior](#funciones-integradas-de-orden-superior)
- [Python - función map](#python---función-map)
- [Python - función filter](#python---función-filter)
- [Python - función reduce](#python---función-reduce)
- [💻 Ejercicios: Día 14](#-ejercicios-día-14)
- [Ejercicios: Básico](#ejercicios-básico)
- [Ejercicios: Intermedio](#ejercicios-intermedio)
- [Ejercicios: Avanzado](#ejercicios-avanzado)
# 📘 Día 14
## Funciones de orden superior
En Python, las funciones son tratadas como ciudadanos de primera clase; se pueden hacer las siguientes operaciones con funciones:
- Una función puede recibir una o más funciones como parámetros
- Una función puede ser el valor de retorno de otra función
- Una función puede ser modificada
- Una función puede asignarse a una variable
En esta sección discutiremos:
1. Pasar funciones como parámetros
2. Devolver funciones como valores de retorno
3. Usar closures y decoradores en Python
### Funciones como parámetros
```py
def sum_numbers(nums): # función normal
return sum(nums) # usa la función incorporada sum
def higher_order_function(f, lst): # pasar función como argumento
summation = f(lst)
return summation
result = higher_order_function(sum_numbers, [1, 2, 3, 4, 5])
print(result) # 15
```
### Funciones como valor de retorno
```py
def square(x): # función que devuelve el cuadrado
return x ** 2
def cube(x): # función que devuelve el cubo
return x ** 3
def absolute(x): # función que devuelve el valor absoluto
if x >= 0:
return x
else:
return -(x)
def higher_order_function(type): # función de orden superior que devuelve una función
if type == 'square':
return square
elif type == 'cube':
return cube
elif type == 'absolute':
return absolute
result = higher_order_function('square')
print(result(3)) # 9
result = higher_order_function('cube')
print(result(3)) # 27
result = higher_order_function('absolute')
print(result(-3)) # 3
```
En los ejemplos anteriores se observa que la función de orden superior devuelve distintas funciones según el parámetro pasado.
## Closures en Python
Python permite que una función anidada acceda al ámbito de su función envolvente externa. Esto se conoce como closure. Un closure en Python se crea al anidar una función dentro de otra función envolvente y devolver la función interna. Veamos un ejemplo.
**Ejemplo:**
```py
def add_ten():
ten = 10
def add(num):
return num + ten
return add
closure_result = add_ten()
print(closure_result(5)) # 15
print(closure_result(10)) # 20
```
## Decoradores en Python
Un decorador es un patrón de diseño que permite añadir nueva funcionalidad a un objeto sin modificar su estructura. Los decoradores normalmente se usan aplicándolos antes de la definición de la función que se desea decorar.
### Crear decoradores
Para crear un decorador necesitamos una función externa que contenga una función envoltura interna.
**Ejemplo:**
```py
# función normal
def greeting():
return 'Welcome to Python'
def uppercase_decorator(function):
def wrapper():
func = function()
make_uppercase = func.upper()
return make_uppercase
return wrapper
g = uppercase_decorator(greeting)
print(g()) # WELCOME TO PYTHON
# Implementando lo anterior con sintaxis de decorador
'''Esta función decoradora es una función de orden superior que acepta una función como argumento'''
def uppercase_decorator(function):
def wrapper():
func = function()
make_uppercase = func.upper()
return make_uppercase
return wrapper
@uppercase_decorator
def greeting():
return 'Welcome to Python'
print(greeting()) # WELCOME TO PYTHON
```
### Aplicar varios decoradores a una función
```py
'''Estas funciones decoradoras son funciones de orden superior que reciben funciones como argumento'''
# primer decorador
def uppercase_decorator(function):
def wrapper():
func = function()
make_uppercase = func.upper()
return make_uppercase
return wrapper
# segundo decorador
def split_string_decorator(function):
def wrapper():
func = function()
splitted_string = func.split()
return splitted_string
return wrapper
@split_string_decorator
@uppercase_decorator # en este caso el orden importa, ya que .upper() no funciona sobre una lista
def greeting():
return 'Welcome to Python'
print(greeting()) # ['WELCOME', 'TO', 'PYTHON']
```
### Aceptar parámetros en decoradores
A menudo necesitamos que nuestras funciones acepten parámetros; por eso definimos decoradores que también los aceptan.
```py
def decorator_with_parameters(function):
def wrapper_accepting_parameters(para1, para2, para3):
function(para1, para2, para3)
print("I live in {}".format(para3))
return wrapper_accepting_parameters
@decorator_with_parameters
def print_full_name(first_name, last_name, country):
print("I am {} {}. I love to teach.".format(
first_name, last_name, country))
print_full_name("Asabeneh", "Yetayeh",'Finland')
```
## Funciones integradas de orden superior
En esta sección veremos algunas funciones integradas de orden superior como map(), filter() y reduce().
Las funciones lambda se pueden pasar como argumentos; su caso de uso ideal es con map, filter y reduce.
### Python - función map
map() es una función integrada que recibe una función y un iterable como parámetros.
```py
# sintaxis
map(function, iterable)
```
**Ejemplo 1**
```py
numbers = [1, 2, 3, 4, 5] # iterable
def square(x):
return x ** 2
numbers_squared = map(square, numbers)
print(list(numbers_squared)) # [1, 4, 9, 16, 25]
# Usemos lambda
numbers_squared = map(lambda x : x ** 2, numbers)
print(list(numbers_squared)) # [1, 4, 9, 16, 25]
```
**Ejemplo 2**
```py
numbers_str = ['1', '2', '3', '4', '5'] # iterable
numbers_int = map(int, numbers_str)
print(list(numbers_int)) # [1, 2, 3, 4, 5]
```
**Ejemplo 3**
```py
names = ['Asabeneh', 'Lidiya', 'Ermias', 'Abraham'] # iterable
def change_to_upper(name):
return name.upper()
names_upper_cased = map(change_to_upper, names)
print(list(names_upper_cased)) # ['ASABENEH', 'LIDIYA', 'ERMIAS', 'ABRAHAM']
# Usemos lambda
names_upper_cased = map(lambda name: name.upper(), names)
print(list(names_upper_cased)) # ['ASABENEH', 'LIDIYA', 'ERMIAS', 'ABRAHAM']
```
map itera sobre el iterable y devuelve un nuevo iterable transformado.
### Python - función filter
filter() llama a la función especificada que retorna un valor booleano para cada elemento del iterable y filtra los elementos que cumplen la condición.
```py
# sintaxis
filter(function, iterable)
```
**Ejemplo 1**
```py
# filtremos solo los pares
numbers = [1, 2, 3, 4, 5] # iterable
def is_even(num):
if num % 2 == 0:
return True
return False
even_numbers = filter(is_even, numbers)
print(list(even_numbers)) # [2, 4]
```
**Ejemplo 2**
```py
numbers = [1, 2, 3, 4, 5] # iterable
def is_odd(num):
if num % 2 != 0:
return True
return False
odd_numbers = filter(is_odd, numbers)
print(list(odd_numbers)) # [1, 3, 5]
```
```py
# filtrar nombres largos
names = ['Asabeneh', 'Lidiya', 'Ermias', 'Abraham'] # iterable
def is_name_long(name):
if len(name) > 7:
return True
return False
long_names = filter(is_name_long, names)
print(list(long_names)) # ['Asabeneh']
```
### Python - función reduce
reduce() se define en el módulo functools; es necesario importarla desde allí. Al igual que map y filter, recibe una función y un iterable. Sin embargo, no devuelve otro iterable sino un único valor acumulado.
**Ejemplo 1**
```py
numbers_str = ['1', '2', '3', '4', '5'] # iterable
def add_two_nums(x, y):
return int(x) + int(y)
total = reduce(add_two_nums, numbers_str)
print(total) # 15
```
## 💻 Ejercicios: Día 14
```py
countries = ['Estonia', 'Finland', 'Sweden', 'Denmark', 'Norway', 'Iceland']
names = ['Asabeneh', 'Lidiya', 'Ermias', 'Abraham']
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```
### Ejercicios: Básico
1. Explica la diferencia entre map, filter y reduce.
2. Explica la diferencia entre funciones de orden superior, closures y decoradores.
3. Define la función que llama (ver ejemplo).
4. Imprime cada país de la lista countries usando un bucle for.
5. Imprime cada nombre de la lista names usando un bucle for.
6. Imprime cada número de la lista numbers usando un bucle for.
### Ejercicios: Intermedio
1. Usa map para convertir cada país en countries a mayúsculas y genera una nueva lista.
2. Usa map para elevar al cuadrado cada número en numbers y genera una nueva lista.
3. Usa map para convertir cada nombre en names a mayúsculas y genera una nueva lista.
4. Usa filter para filtrar países que contienen 'land'.
5. Usa filter para filtrar países con exactamente seis caracteres.
6. Usa filter para filtrar países con seis o más caracteres.
7. Usa filter para filtrar países que comienzan con 'E'.
8. Encadena dos o más iteradores de lista (por ejemplo arr.map(callback).filter(callback).reduce(callback)).
9. Declara una función get_string_lists que reciba una lista y devuelva una lista con solo los elementos de tipo cadena.
10. Usa reduce para sumar todos los números en la lista numbers.
11. Usa reduce para concatenar todos los países en una oración: Estonia, Finland, Sweden, Denmark, Norway, and Iceland are north European countries.
12. Declara una función categorize_countries que retorne una lista de países que siguen un patrón común (puedes ver la lista de países en el archivo countries.js del repositorio, por ejemplo 'land', 'ia', 'island', 'stan').
13. Crea una función que devuelva un diccionario donde las claves sean la primera letra de los nombres de país y el valor sea el número de países que comienzan con esa letra.
14. Declara una función get_first_ten_countries que devuelva los primeros diez países de la lista countries.js en la carpeta data.
15. Declara una función get_last_ten_countries que devuelva los últimos diez países de la lista.
### Ejercicios: Avanzado
1. Usando el archivo countries_data.py (https://github.com/Asabeneh/30-Days-Of-Python/blob/master/data/countries-data.py), completa lo siguiente:
- Ordena los países por nombre, capital y población.
- Ordena y obtiene los diez idiomas más usados.
- Ordena y obtiene los diez países con mayor población.
🎉 ¡Felicidades! 🎉
[<< Día 13](./13_list_comprehension_sp.md) | [Día 15 >>](./15_python_type_errors_cn_sp.md)
================================================
FILE: Spanish/15_python_type_errors_sp.md
================================================
# Desafío de programación Python: Día 15 - Errores (excepciones) en Python
- [Día 15](#día-15)
- [Tipos de error en Python](#tipos-de-error-en-python)
- [SyntaxError (Error de sintaxis)](#syntaxerror-error-de-sintaxis)
- [NameError (Error de nombre)](#nameerror-error-de-nombre)
- [IndexError (Error de índice)](#indexerror-error-de-índice)
- [ModuleNotFoundError (Módulo no encontrado)](#modulenotfounderror-módulo-no-encontrado)
- [AttributeError (Error de atributo)](#attributeerror-error-de-atributo)
- [KeyError (Error de clave)](#keyerror-error-de-clave)
- [TypeError (Error de tipo)](#typeerror-error-de-tipo)
- [ImportError (Error de importación)](#importerror-error-de-importación)
- [ValueError (Error de valor)](#valueerror-error-de-valor)
- [ZeroDivisionError (Error de división por cero)](#zerodivisionerror-error-de-división-por-cero)
- [💻 Ejercicios - Día 15](#-ejercicios---día-15)
# 📘 Día 15
## Tipos de error en Python
Al escribir código, con frecuencia cometemos errores tipográficos u otros errores comunes. Si nuestro código falla, el intérprete de Python muestra un mensaje que nos da retroalimentación sobre dónde ocurrió el problema y cuál es el tipo de error. A veces incluso sugiere posibles soluciones. Conocer los distintos tipos de errores en el lenguaje nos ayudará a depurar más rápido y a mejorar nuestras habilidades de programación.
Revisemos los tipos de error más comunes uno por uno. Primero, abre el intérprete interactivo de Python. Ve a la terminal de tu equipo e ingresa 'python'. Se abrirá el intérprete interactivo de Python.
### SyntaxError (Error de sintaxis)
**Ejemplo 1: SyntaxError**
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print 'hello world'
File "", line 1
print 'hello world'
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('hello world')?
>>>
```
Como ves, cometimos un error de sintaxis porque olvidamos encerrar la cadena entre paréntesis; Python incluso sugiere la corrección. Arreglémoslo.
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print 'hello world'
File "", line 1
print 'hello world'
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('hello world')?
>>> print('hello world')
hello world
>>>
```
Ese fue un SyntaxError. Tras corregirlo, el código se ejecuta correctamente. Veamos otros tipos de errores.
### NameError (Error de nombre)
**Ejemplo 1: NameError**
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print(age)
Traceback (most recent call last):
File "", line 1, in
NameError: name 'age' is not defined
>>>
```
El mensaje indica que el nombre age no está definido. En efecto, no hemos declarado age pero intentamos imprimirlo. Solucionémoslo declarando la variable y asignándole un valor.
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print(age)
Traceback (most recent call last):
File "", line 1, in
NameError: name 'age' is not defined
>>> age = 25
>>> print(age)
25
>>>
```
Ese fue un NameError. Lo depuramos definiendo la variable.
### IndexError (Error de índice)
**Ejemplo 1: IndexError**
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> numbers = [1, 2, 3, 4, 5]
>>> numbers[5]
Traceback (most recent call last):
File "", line 1, in
IndexError: list index out of range
>>>
```
En este ejemplo Python lanzó un IndexError porque los índices válidos de la lista son 0 a 4; el índice 5 está fuera de rango.
### ModuleNotFoundError (Módulo no encontrado)
**Ejemplo 1: ModuleNotFoundError**
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'maths'
>>>
```
Aquí añadí intencionadamente una 's' extra a math, lo que produjo un ModuleNotFoundError. Corrijámoslo quitando la 's'.
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'maths'
>>> import math
>>>
```
Lo hemos corregido y ahora podemos usar el módulo math.
### AttributeError (Error de atributo)
**Ejemplo 1: AttributeError**
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'maths'
>>> import math
>>> math.PI
Traceback (most recent call last):
File "", line 1, in
AttributeError: module 'math' has no attribute 'PI'
>>>
```
Aquí intenté acceder a math.PI en lugar de math.pi, lo que produjo un AttributeError porque ese atributo no existe. Corrijámoslo usando el nombre correcto:
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'maths'
>>> import math
>>> math.PI
Traceback (most recent call last):
File "", line 1, in
AttributeError: module 'math' has no attribute 'PI'
>>> math.pi
3.141592653589793
>>>
```
Ahora la llamada devuelve el valor esperado.
### KeyError (Error de clave)
**Ejemplo 1: KeyError**
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> users = {'name':'Asab', 'age':250, 'country':'Finland'}
>>> users['name']
'Asab'
>>> users['county']
Traceback (most recent call last):
File "", line 1, in
KeyError: 'county'
>>>
```
Aquí hay un error de ortografía en la clave usada para obtener un valor del diccionario. Es un KeyError; la solución es usar la clave correcta.
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> user = {'name':'Asab', 'age':250, 'country':'Finland'}
>>> user['name']
'Asab'
>>> user['county']
Traceback (most recent call last):
File "", line 1, in
KeyError: 'county'
>>> user['country']
'Finland'
>>>
```
Error depurado; el código devuelve el resultado esperado.
### TypeError (Error de tipo)
**Ejemplo 1: TypeError**
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 4 + '3'
Traceback (most recent call last):
File "", line 1, in
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>>
```
En este caso aparece un TypeError porque no podemos sumar un entero y una cadena. Una solución es convertir la cadena a int o float; otra es convertir el entero a cadena para concatenarlos. Probemos la primera solución:
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 4 + '3'
Traceback (most recent call last):
File "", line 1, in
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> 4 + int('3')
7
>>> 4 + float('3')
7.0
>>>
```
El error desaparece y obtenemos el resultado esperado.
### ImportError (Error de importación)
**Ejemplo 1: ImportError**
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from math import power
Traceback (most recent call last):
File "", line 1, in
ImportError: cannot import name 'power' from 'math'
>>>
```
El módulo math no tiene una función llamada power; la función correcta es pow. Corrijámoslo:
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from math import power
Traceback (most recent call last):
File "", line 1, in
ImportError: cannot import name 'power' from 'math'
>>> from math import pow
>>> pow(2,3)
8.0
>>>
```
### ValueError (Error de valor)
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> int('12a')
Traceback (most recent call last):
File "", line 1, in
ValueError: invalid literal for int() with base 10: '12a'
>>>
```
No podemos convertir la cadena dada a número porque contiene la letra 'a'.
### ZeroDivisionError (Error de división por cero)
```python
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 1/0
Traceback (most recent call last):
File "", line 1, in
ZeroDivisionError: division by zero
>>>
```
No podemos dividir un número por cero.
Hemos revisado varios tipos de errores en Python; para más información, consulta la documentación oficial sobre excepciones en Python. Si te acostumbras a leer los mensajes de error, podrás corregir tus bugs rápidamente y convertirte en un mejor programador.
🌕 Vas progresando. Has completado la mitad del camino hacia algo genial. Ahora haz algunos ejercicios para entrenar tu cerebro y tus manos.
## 💻 Ejercicios - Día 15
1. Abre tu intérprete interactivo de Python y prueba todos los ejemplos mostrados en esta sección.
🎉 ¡Felicidades! 🎉
[<< Día 14](./14_higher_order_functions_sp.md) | [Día 16 >>](./16_python_datetime_sp.md)
================================================
FILE: Spanish/16_python_datetime_sp.md
================================================
# 30 Días de Python: Día 16 - datetime en Python
- [Día 16](#-día-16)
- [Python *datetime*](#python-datetime)
- [Obtener información de *datetime*](#obtener-información-de-datetime)
- [Formatear fecha con *strftime*](#formatear-fecha-con-strftime)
- [Convertir cadena a fecha con *strptime*](#convertir-cadena-a-fecha-con-strptime)
- [Usar *date* desde *datetime*](#usar-date-desde-datetime)
- [Representar tiempo con objetos *time*](#representar-tiempo-con-objetos-time)
- [Calcular la diferencia entre dos puntos en el tiempo](#calcular-la-diferencia-entre-dos-puntos-en-el-tiempo)
- [Calcular diferencias con *timedelta*](#calcular-diferencias-con-timedelta)
- [💻 Ejercicios - Día 16](#-ejercicios---día-16)
# 📘 Día 16
## Python *datetime*
Python tiene un módulo _datetime_ para trabajar con fechas y horas.
```py
import datetime
print(dir(datetime))
['MAXYEAR', 'MINYEAR', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'date', 'datetime', 'datetime_CAPI', 'sys', 'time', 'timedelta', 'timezone', 'tzinfo']
```
Con los comandos incorporados dir o help puedes ver las funciones disponibles de un módulo. Como ves, el módulo datetime tiene muchas clases y funciones; nos centraremos en _date_, _datetime_, _time_ y _timedelta_. Veámoslas una a una.
### Obtener información de *datetime*
```py
from datetime import datetime
now = datetime.now()
print(now) # 2021-07-08 07:34:46.549883
day = now.day # 8
month = now.month # 7
year = now.year # 2021
hour = now.hour # 7
minute = now.minute # 38
second = now.second
timestamp = now.timestamp()
print(day, month, year, hour, minute)
print('timestamp', timestamp)
print(f'{day}/{month}/{year}, {hour}:{minute}') # 8/7/2021, 7:38
```
El timestamp, o Unix timestamp, es el número de segundos transcurridos desde el 1 de enero de 1970 UTC.
### Formatear fecha con *strftime*
```py
from datetime import datetime
new_year = datetime(2020, 1, 1)
print(new_year) # 2020-01-01 00:00:00
day = new_year.day
month = new_year.month
year = new_year.year
hour = new_year.hour
minute = new_year.minute
second = new_year.second
print(day, month, year, hour, minute) #1 1 2020 0 0
print(f'{day}/{month}/{year}, {hour}:{minute}') # 1/1/2020, 0:0
```
Usa el método *strftime* para formatear fechas y horas; la documentación de formatos está [aquí](https://strftime.org/).
```py
from datetime import datetime
# fecha y hora actual
now = datetime.now()
t = now.strftime("%H:%M:%S")
print("Hora:", t)
time_one = now.strftime("%m/%d/%Y, %H:%M:%S")
# formato mm/dd/YY H:M:S
print("Formato uno:", time_one)
time_two = now.strftime("%d/%m/%Y, %H:%M:%S")
# formato dd/mm/YY H:M:S
print("Formato dos:", time_two)
```
```sh
Hora: 01:05:01
Formato uno: 12/05/2019, 01:05:01
Formato dos: 05/12/2019, 01:05:01
```
A continuación se muestran los símbolos de _strftime_ usados para formatear tiempos, como se ve en la imagen de referencia.

### Convertir cadena a fecha con *strptime*
Aquí hay una [guía](https://www.programiz.com/python-programming/datetime/strptimet) que ayuda a entender los formatos.
```py
from datetime import datetime
date_string = "5 December, 2019"
print("date_string =", date_string)
date_object = datetime.strptime(date_string, "%d %B, %Y")
print("date_object =", date_object)
```
```sh
date_string = 5 December, 2019
date_object = 2019-12-05 00:00:00
```
### Usar *date* desde *datetime*
```py
from datetime import date
d = date(2020, 1, 1)
print(d)
print('Fecha actual:', d.today()) # fecha actual
# objeto date de hoy
today = date.today()
print("Año actual:", today.year) # 2019
print("Mes actual:", today.month) # 12
print("Día actual:", today.day) # 5
```
### Representar tiempo con objetos *time*
```py
from datetime import time
# time(hour = 0, minute = 0, second = 0)
a = time()
print("a =", a)
# time(hour, minute y second)
b = time(10, 30, 50)
print("b =", b)
# time(hour, minute y second)
c = time(hour=10, minute=30, second=50)
print("c =", c)
# time(hour, minute, second, microsecond)
d = time(10, 30, 50, 200555)
print("d =", d)
```
Salida:
a = 00:00:00
b = 10:30:50
c = 10:30:50
d = 10:30:50.200555
### Calcular la diferencia entre dos puntos en el tiempo
```py
today = date(year=2019, month=12, day=5)
new_year = date(year=2020, month=1, day=1)
time_left_for_newyear = new_year - today
# Tiempo hasta año nuevo: 27 days, 0:00:00
print('Tiempo hasta año nuevo: ', time_left_for_newyear)
t1 = datetime(year = 2019, month = 12, day = 5, hour = 0, minute = 59, second = 0)
t2 = datetime(year = 2020, month = 1, day = 1, hour = 0, minute = 0, second = 0)
diff = t2 - t1
print('Tiempo hasta año nuevo:', diff) # Tiempo hasta año nuevo: 26 days, 23:01:00
```
### Calcular diferencias con *timedelta*
```py
from datetime import timedelta
t1 = timedelta(weeks=12, days=10, hours=4, seconds=20)
t2 = timedelta(days=7, hours=5, minutes=3, seconds=30)
t3 = t1 - t2
print("t3 =", t3)
```
```sh
date_string = 5 December, 2019
date_object = 2019-12-05 00:00:00
t3 = 86 days, 22:56:50
```
🌕 Eres increíble. Has avanzado 16 pasos hacia la excelencia. Ahora haz algunos ejercicios para entrenar tu mente y tus manos.
## 💻 Ejercicios - Día 16
1. Obtén el día, mes, año, hora, minuto y timestamp actuales desde el módulo datetime.
2. Formatea la fecha actual con el formato: "%m/%d/%Y, %H:%M:%S"
3. Hoy es 5 de diciembre de 2019. Convierte esa cadena de fecha a un objeto datetime.
4. Calcula la diferencia entre ahora y el próximo año nuevo.
5. Calcula la diferencia entre el 1 de enero de 1970 y ahora.
6. Piensa: ¿para qué puedes usar el módulo datetime? Por ejemplo:
- Análisis de series temporales
- Obtener timestamps para eventos en una aplicación
- Añadir la fecha de publicación en un blog
🎉 ¡Felicidades! 🎉
[<< Día 15](./15_python_type_errors_sp.md) | [Día 17 >>](./17_exception_handling_sp.md)
================================================
FILE: Spanish/17_exception_handling_sp.md
================================================
# 30 Días de Python: Día 17 - Manejo de excepciones
- [Día 17](#-día-17)
- [Manejo de excepciones](#manejo-de-excepciones)
- [Empacar y desempacar parámetros en Python](#empacar-y-desempacar-parámetros-en-python)
- [Desempaquetado](#desempaquetado)
- [Desempaquetar listas](#desempaquetar-listas)
- [Desempaquetar diccionarios](#desempaquetar-diccionarios)
- [Empaquetado](#empaquetado)
- [Empaquetar listas](#empaquetar-listas)
- [Empaquetar diccionarios](#empaquetar-diccionarios)
- [Expandir en Python](#expandir-en-python)
- [Enumerar (enumerate)](#enumerar-enumerate)
- [Zip](#zip)
- [Ejercicios: Día 17](#ejercicios-día-17)
# 📘 Día 17
## Manejo de excepciones
Python utiliza _try_ y _except_ para manejar errores de forma elegante. Salir de forma controlada (o manejar errores con elegancia) es una buena práctica: el programa detecta una condición de error y la maneja adecuadamente, normalmente mostrando un mensaje descriptivo en la terminal o en un registro. Las excepciones suelen deberse a factores externos al programa (entrada errónea, nombre de archivo incorrecto, archivo no encontrado, fallos de I/O, etc.). El manejo adecuado de excepciones evita que las aplicaciones se bloqueen.
En la sección anterior hemos cubierto los distintos tipos de errores en Python. Si usamos _try_ y _except_ correctamente, podemos impedir que esos errores hagan que el programa falle.

```py
try:
# si todo va bien, se ejecuta el código en este bloque
except:
# si ocurre un error, se ejecuta el código en este bloque
```
**Ejemplo:**
```py
try:
print(10 + '5')
except:
print('Ocurrió un error')
```
En el ejemplo anterior, el segundo operando es una cadena. Podemos convertirlo a int o float para sumarlo a un número; si no lo hacemos, se ejecutará el bloque _except_.
**Ejemplo:**
```py
try:
name = input('Introduce tu nombre:')
year_born = input('¿En qué año naciste?:')
age = 2019 - year_born
print(f'Eres {name}. Tu edad es {age}.')
except:
print('Ocurrió un error')
```
```sh
Ocurrió un error
```
En el ejemplo anterior, se ejecuta el bloque de excepción, pero no sabemos exactamente qué pasó. Para identificar el problema podemos capturar tipos de excepción concretos.
En el siguiente ejemplo capturamos y mostramos el tipo de error:
```py
try:
name = input('Introduce tu nombre:')
year_born = input('¿En qué año naciste?:')
age = 2019 - year_born
print(f'Eres {name}. Tu edad es {age}.')
except TypeError:
print('Se produjo un error de tipo (TypeError)')
except ValueError:
print('Se produjo un ValueError')
except ZeroDivisionError:
print('Se produjo una división por cero (ZeroDivisionError)')
```
```sh
Introduce tu nombre:Asabeneh
¿En qué año naciste?:1920
Se produjo un error de tipo (TypeError)
```
En el ejemplo anterior la salida será _TypeError_. Ahora añadamos bloques adicionales:
```py
try:
name = input('Introduce tu nombre:')
year_born = input('¿En qué año naciste?:')
age = 2019 - int(year_born)
print(f'Eres {name}. Tu edad es {age}.')
except TypeError:
print('Se produjo un error de tipo (TypeError)')
except ValueError:
print('Se produjo un ValueError')
except ZeroDivisionError:
print('Se produjo una división por cero (ZeroDivisionError)')
else:
print('Este bloque se ejecuta normalmente después de try')
finally:
print('Este bloque siempre se ejecuta.')
```
```sh
Introduce tu nombre:Asabeneh
¿En qué año naciste?:1920
Eres Asabeneh. Tu edad es 99.
Este bloque se ejecuta normalmente después de try
Este bloque siempre se ejecuta.
```
También podemos simplificar el manejo de excepción así:
```py
try:
name = input('Introduce tu nombre:')
year_born = input('¿En qué año naciste?:')
age = 2019 - int(year_born)
print(f'Eres {name}. Tu edad es {age}.')
except Exception as e:
print(e)
```
## Empacar y desempacar parámetros en Python
Usamos dos operadores:
- * para tuplas/listas
- ** para diccionarios
Veamos un ejemplo. Supongamos que una función acepta parámetros separados, pero nosotros tenemos una lista. Podemos desempaquetarla y convertirla en argumentos.
### Desempaquetado
#### Desempaquetar listas
```py
def sum_of_five_nums(a, b, c, d, e):
return a + b + c + d + e
lst = [1, 2, 3, 4, 5]
print(sum_of_five_nums(lst)) # TypeError: sum_of_five_nums() missing 4 required positional arguments: 'b', 'c', 'd', and 'e'
```
Al ejecutar lo anterior ocurre un error porque la función espera números separados, no una lista. Desempaquetemos la lista:
```py
def sum_of_five_nums(a, b, c, d, e):
return a + b + c + d + e
lst = [1, 2, 3, 4, 5]
print(sum_of_five_nums(*lst)) # 15
```
También podemos usar desempaquetado con range(), que acepta inicio y fin:
```py
numbers = range(2, 7) # llamada normal con parámetros separados
print(list(numbers)) # [2, 3, 4, 5, 6]
args = [2, 7]
numbers = range(*args) # llamada usando los parámetros desempaquetados desde la lista
print(list(numbers)) # [2, 3, 4, 5, 6]
```
También podemos usar desempaquetado en asignaciones:
```py
countries = ['Finland', 'Sweden', 'Norway', 'Denmark', 'Iceland']
fin, sw, nor, *rest = countries
print(fin, sw, nor, rest) # Finland Sweden Norway ['Denmark', 'Iceland']
numbers = [1, 2, 3, 4, 5, 6, 7]
one, *middle, last = numbers
print(one, middle, last) # 1 [2, 3, 4, 5, 6] 7
```
#### Desempaquetar diccionarios
```py
def unpacking_person_info(name, country, city, age):
return f'{name} vive en {city}, {country}. Tiene {age} años.'
dct = {'name':'Asabeneh', 'country':'Finland', 'city':'Helsinki', 'age':250}
print(unpacking_person_info(**dct)) # Asabeneh vive en Helsinki, Finland. Tiene 250 años.
```
### Empaquetado
A veces no sabemos cuántos argumentos nos pasarán a una función. Podemos usar empaquetado para aceptar un número variable de argumentos.
### Empaquetar listas
```py
def sum_all(*args):
s = 0
for i in args:
s += i
return s
print(sum_all(1, 2, 3)) # 6
print(sum_all(1, 2, 3, 4, 5, 6, 7)) # 28
```
#### Empaquetar diccionarios
```py
def packing_person_info(**kwargs):
# comprobar el tipo de kwargs: es un dict
# print(type(kwargs))
# imprimir los pares clave-valor
for key in kwargs:
print(f"{key} = {kwargs[key]}")
return kwargs
print(packing_person_info(name="Asabeneh",
country="Finland", city="Helsinki", age=250))
```
```sh
name = Asabeneh
country = Finland
city = Helsinki
age = 250
{'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
```
## Expandir en Python
Al igual que en JavaScript, Python permite expandir listas usando el operador *. Veámoslo:
```py
lst_one = [1, 2, 3]
lst_two = [4, 5, 6, 7]
lst = [0, *lst_one, *lst_two]
print(lst) # [0, 1, 2, 3, 4, 5, 6, 7]
```
## Enumerar (enumerate)
Si necesitamos los índices de una lista, usamos la función integrada enumerate.
```py
for index, item in enumerate([20, 30, 40]):
print(index, item)
```
```py
for index, i in enumerate(countries):
print('hola')
if i == 'Finland':
print(f'El país {i} está en el índice {index}')
```
```sh
0 20
1 30
2 40
```
## Zip
A veces necesitamos combinar listas. Observa el ejemplo:
```py
fruits = ['banana', 'orange', 'mango', 'lemon', 'lime']
vegetables = ['Tomato', 'Potato', 'Cabbage','Onion', 'Carrot']
fruits_and_veges = []
for f, v in zip(fruits, vegetables):
fruits_and_veges.append({'fruit':f, 'veg':v})
print(fruits_and_veges)
```
```sh
[{'fruit': 'banana', 'veg': 'Tomato'}, {'fruit': 'orange', 'veg': 'Potato'}, {'fruit': 'mango', 'veg': 'Cabbage'}, {'fruit': 'lemon', 'veg': 'Onion'}, {'fruit': 'lime', 'veg': 'Carrot'}]
```
## Ejercicios: Día 17
1. Crea en _countries.py_ funciones que usen los datos de _countries_data.py_:
- una función para encontrar los 10 idiomas más usados
- una función para encontrar los 10 países más poblados
🎉 ¡Felicidades! 🎉
[<< Día 16](./16_python_datetime_sp.md) | [Día 18 >>](./18_regular_expressions_sp.md)
================================================
FILE: Spanish/18_regular_expressions_sp.md
================================================
# 30 Días de Python: Día 18 - Expresiones regulares
- [Día 18](#-día-18)
- [Expresiones regulares](#expresiones-regulares)
- [Módulo *re*](#módulo-re)
- [Métodos en el módulo *re*](#métodos-en-el-módulo-re)
- [Match (coincidencia al inicio)](#match-coincidencia-al-inicio)
- [Search (búsqueda)](#search-búsqueda)
- [Buscar todas las coincidencias con *findall*](#buscar-todas-las-coincidencias-con-findall)
- [Reemplazar subcadenas](#reemplazar-subcadenas)
- [Usar RegEx para dividir el texto](#usar-regex-para-dividir-texto)
- [Construir patrones RegEx](#construir-patrones-regex)
- [Corchetes](#corchetes)
- [Caracteres de escape en RegEx (\\)](#caracteres-de-escape-en-regex)
- [Una o más veces (+)](#una-o-más-veces-+)
- [Punto (.)](#punto-)
- [Cero o más veces (*)](#cero-o-más-veces-)
- [Cero o una vez (?)](#cero-o-una-vez-?)
- [Cuantificadores en RegEx](#cuantificadores-en-regex)
- [Circunflejo (^) en RegEx](#circunflejo-^)
- [💻 Ejercicios: Día 18](#-ejercicios-día-18)
- [Ejercicios: Nivel 1](#ejercicios-nivel-1)
- [Ejercicios: Nivel 2](#ejercicios-nivel-2)
- [Ejercicios: Nivel 3](#ejercicios-nivel-3)
# 📘 Día 18
## Expresiones regulares
Las expresiones regulares (RegEx) son cadenas de texto especiales que ayudan a encontrar patrones en los datos. RegEx se puede usar para comprobar la existencia de ciertos patrones en diferentes tipos de datos. Para usar RegEx en Python debemos importar el módulo llamado *re*.
### Módulo *re*
Una vez importado el módulo, podemos usarlo para detectar o buscar patrones.
```py
import re
```
### Métodos en el módulo *re*
Para buscar patrones usamos diferentes conjuntos de caracteres y funciones de *re*, que permiten buscar coincidencias dentro de una cadena.
- *re.match()*: busca solo al inicio de la cadena; devuelve un objeto Match si hay coincidencia, sino None.
- *re.search*: busca en cualquier parte de la cadena (incluyendo textos multilínea); devuelve el primer objeto Match encontrado o None.
- *re.findall*: devuelve una lista con todas las coincidencias.
- *re.split*: acepta una cadena y la divide en los puntos donde hay coincidencia, devolviendo una lista.
- *re.sub*: reemplaza una o más coincidencias en una cadena.
#### Match (coincidencia al inicio)
```py
# sintaxis
re.match(substring, string, re.I)
# substring es una cadena o patrón, string es el texto donde buscamos, re.I indica ignorar mayúsculas/minúsculas
```
```py
import re
txt = 'I love to teach python and javaScript'
# Devuelve un objeto Match con span y match
match = re.match('I love to teach', txt, re.I)
print(match) #
# Podemos usar span para obtener la posición inicial y final como tupla
span = match.span()
print(span) # (0, 15)
# Tomamos inicio y fin desde span
start, end = span
print(start, end) # 0, 15
substring = txt[start:end]
print(substring) # I love to teach
```
Del ejemplo anterior se ve que el patrón buscado es *I love to teach*. La función match **solo** devuelve un objeto si el texto comienza con ese patrón.
```py
import re
txt = 'I love to teach python and javaScript'
match = re.match('I like to teach', txt, re.I)
print(match) # None
```
Esa cadena no comienza con *I like to teach*, por eso match devuelve None.
#### Search (búsqueda)
```py
# sintaxis
re.search(substring, string, re.I)
# substring es un patrón, string es el texto donde buscamos, re.I es la bandera para ignorar mayúsculas/minúsculas
```
```py
import re
txt = '''Python is the most beautiful language that a human being has ever created.
I recommend python for a first programming language'''
# Devuelve un objeto Match con span y match
match = re.search('first', txt, re.I)
print(match) #
# Podemos usar span para obtener inicio y fin como tupla
span = match.span()
print(span) # (100, 105)
# Tomamos inicio y fin
start, end = span
print(start, end) # 100 105
substring = txt[start:end]
print(substring) # first
```
Como puedes ver, search es más potente que match porque busca en todo el texto. search devuelve la primera coincidencia; para obtener todas las coincidencias usamos findall.
#### Buscar todas las coincidencias con *findall*
*findall()* devuelve todas las coincidencias como una lista.
```py
txt = '''Python is the most beautiful language that a human being has ever created.
I recommend python for a first programming language'''
# Devuelve una lista
matches = re.findall('language', txt, re.I)
print(matches) # ['language', 'language']
```
La palabra *language* aparece dos veces en el texto. Practiquemos más: vamos a buscar 'Python' y 'python' en el texto:
```py
txt = '''Python is the most beautiful language that a human being has ever created.
I recommend python for a first programming language'''
# Devuelve una lista
matches = re.findall('python', txt, re.I)
print(matches) # ['Python', 'python']
```
Usando re.I se ignora mayúsculas/minúsculas. Si no usamos la bandera, podemos escribir el patrón de otras formas:
```py
txt = '''Python is the most beautiful language that a human being has ever created.
I recommend python for a first programming language'''
matches = re.findall('Python|python', txt)
print(matches) # ['Python', 'python']
#
matches = re.findall('[Pp]ython', txt)
print(matches) # ['Python', 'python']
```
#### Reemplazar subcadenas
```py
txt = '''Python is the most beautiful language that a human being has ever created.
I recommend python for a first programming language'''
match_replaced = re.sub('Python|python', 'JavaScript', txt, re.I)
print(match_replaced) # JavaScript is the most beautiful language that a human being has ever created.
# o bien
match_replaced = re.sub('[Pp]ython', 'JavaScript', txt, re.I)
print(match_replaced) # JavaScript is the most beautiful language that a human being has ever created.
```
Otro ejemplo: el siguiente texto es difícil de leer por los símbolos '%'. Reemplazarlos por cadena vacía limpia el texto.
```py
txt = '''%I a%m te%%a%%che%r% a%n%d %% I l%o%ve te%ach%ing.
T%he%re i%s n%o%th%ing as r%ewarding a%s e%duc%at%i%ng a%n%d e%m%p%ow%er%ing p%e%o%ple.
I fo%und te%a%ching m%ore i%n%t%er%%es%ting t%h%an any other %jobs.
D%o%es thi%s m%ot%iv%a%te %y%o%u to b%e a t%e%a%cher?'''
matches = re.sub('%', '', txt)
print(matches)
```
```sh
I am teacher and I love teaching.
There is nothing as rewarding as educating and empowering people.
I found teaching more interesting than any other jobs. Does this motivate you to be a teacher?
```
## Usar RegEx para dividir el texto
```py
txt = '''I am teacher and I love teaching.
There is nothing as rewarding as educating and empowering people.
I found teaching more interesting than any other jobs.
Does this motivate you to be a teacher?'''
print(re.split('\n', txt)) # dividir usando \n - salto de línea
```
```sh
['I am teacher and I love teaching.', 'There is nothing as rewarding as educating and empowering people.', 'I found teaching more interesting than any other jobs.', 'Does this motivate you to be a teacher?']
```
## Construir patrones RegEx
Para declarar una cadena usamos comillas simples o dobles. Para declarar un patrón RegEx usamos una cadena raw, escrita como r''.
El siguiente patrón reconoce solo 'apple' en minúsculas; para ignorar mayúsculas/minúsculas reescribimos el patrón o añadimos la bandera re.I.
```py
import re
regex_pattern = r'apple'
txt = 'Apple and banana are fruits. An old cliche says an apple a day a doctor way has been replaced by a banana a day keeps the doctor far far away. '
matches = re.findall(regex_pattern, txt)
print(matches) # ['apple']
# Para ignorar mayúsculas/minúsculas, añadimos la bandera
matches = re.findall(regex_pattern, txt, re.I)
print(matches) # ['Apple', 'apple']
# o podemos usar un conjunto de caracteres
regex_pattern = r'[Aa]pple' # esto permite Apple o apple
matches = re.findall(regex_pattern, txt)
print(matches) # ['Apple', 'apple']
```
* []: un conjunto de caracteres
- [a-c] significa a o b o c
- [a-z] cualquier letra de a a z
- [A-Z] cualquier letra de A a Z
- [0-3] 0 o 1 o 2 o 3
- [0-9] cualquier dígito del 0 al 9
- [A-Za-z0-9] cualquier carácter alfanumérico: a-z, A-Z o 0-9
### Corchetes
Practiquemos más con corchetes. Recuerda usar re.I para búsquedas sin distinción entre mayúsculas y minúsculas.
```py
regex_pattern = r'[Aa]pple|[Bb]anana' # Apple o apple o Banana o banana
txt = 'Apple and banana are fruits. An old cliche says an apple a day a doctor way has been replaced by a banana a day keeps the doctor far far away.'
matches = re.findall(regex_pattern, txt)
print(matches) # ['Apple', 'banana', 'apple', 'banana']
```
Usando corchetes y alternación:
```py
regex_pattern = r'[a-zA-Z0-9]' # caracteres a-z, A-Z, 0-9
txt = 'Apple and banana are fruits. An old cliche says an apple a day a doctor way has been replaced by a banana a day keeps the doctor far far away.'
matches = re.findall(regex_pattern, txt)
print(matches) # ['A', 'p', 'p', 'l', 'e', 'a', 'n', 'd', 'b', 'a', 'n', 'a', 'n', 'a', 'a', 'r', 'e',...]
regex_pattern = r'\d' # \d es un metacarácter que representa dígitos
txt = 'This regular expression example was made on December 6, 2019 and revised on July 8, 2021'
matches = re.findall(regex_pattern, txt)
print(matches) # ['6', '2', '0', '1', '9', '8', '2', '0', '2', '1']
regex_pattern = r'\d+' # \d+ dígitos uno o más
txt = 'This regular expression example was made on December 6, 2019 and revised on July 8, 2021'
matches = re.findall(regex_pattern, txt)
print(matches) # ['6', '2019', '8', '2021']
```
### Caracteres de escape en RegEx (\\)
```py
regex_pattern = r'\d+' # \d dígito, + uno o más
txt = 'This regular expression example was made on December 6, 2019 and revised on July 8, 2021'
matches = re.findall(regex_pattern, txt)
print(matches) # ['6', '2019', '8', '2021']
```
Para buscar la barra invertida '\' en sí usamos doble backslash:
```py
regex_pattern = r'\\d' # busca literal '\d'
txt = 'This regular expression example was made on December 6, 2019 and revised on July 8, 2021'
matches = re.findall(regex_pattern, txt)
print(matches) # []
```
Si no hay '\d' literal en el texto, no se encuentran coincidencias.
### Una o más veces (+)
```py
regex_pattern = r'\d+' # \d dígito, + uno o más
txt = 'This regular expression example was made on December 6, 2019 and revised on July 8, 2021'
matches = re.findall(regex_pattern, txt)
print(matches) # ['6', '2019', '8', '2021']
```
### Punto (.)
```py
regex_pattern = r'[a].' # a seguido de cualquier carácter (excepto nueva línea)
txt = '''Apple and banana are fruits'''
matches = re.findall(regex_pattern, txt)
print(matches) # ['an', 'an', 'an', 'a ', 'ar']
regex_pattern = r'[a].+' # a seguido de cualquier carácter una o más veces
matches = re.findall(regex_pattern, txt)
print(matches) # ['and banana are fruits']
```
### Cero o más veces (*)
Cero o más. Observa con atención el ejemplo.
```py
regex_pattern = r'[a].*' # a seguido de cualquier carácter cero o más veces
txt = '''Apple and banana are fruits'''
matches = re.findall(regex_pattern, txt)
print(matches) # ['and banana are fruits']
```
### Cero o una vez (?)
Cero o una vez: puede existir o no.
```py
txt = '''I am not sure if there is a convention how to write the word e-mail.
Some people write it as email others may write it as Email or E-mail.'''
regex_pattern = r'[Ee]-?mail' # ? indica cero o una vez
matches = re.findall(regex_pattern, txt)
print(matches) # ['e-mail', 'email', 'Email', 'E-mail']
```
### Cuantificadores en RegEx
Con llaves podemos especificar la longitud del patrón:
```py
txt = 'This regular expression example was made on December 6, 2019 and revised on July 8, 2021'
regex_pattern = r'\d{4}' # exactamente 4 dígitos
matches = re.findall(regex_pattern, txt)
print(matches) # ['2019', '2021']
txt = 'This regular expression example was made on December 6, 2019 and revised on July 8, 2021'
regex_pattern = r'\d{1,4}' # entre 1 y 4 dígitos
matches = re.findall(regex_pattern, txt)
print(matches) # ['6', '2019', '8', '2021']
```
### Circunflejo (^) en RegEx
- Indicar inicio
```py
txt = 'This regular expression example was made on December 6, 2019 and revised on July 8, 2021'
regex_pattern = r'^This' # ^ indica que empieza con 'This'
matches = re.findall(regex_pattern, txt)
print(matches) # ['This']
```
- Negación dentro de corchetes
```py
txt = 'This regular expression example was made on December 6, 2019 and revised on July 8, 2021'
regex_pattern = r'[^A-Za-z ]+' # ^ dentro de [] significa negación: no A-Z, no a-z, no espacio
matches = re.findall(regex_pattern, txt)
print(matches) # ['6,', '2019', '8,', '2021']
```
## 💻 Ejercicios: Día 18
### Ejercicios: Nivel 1
1. ¿Qué es una expresión regular?
2. ¿Qué es una variable de expresión regular (regex variable)?
3. Recrea patrones que:
a) Encuentren citas que contengan la palabra *talent* en un libro,
b) Encuentren fechas en formato _DD-MM-YYYY_, por ejemplo 12-01-2021,
c) Encuentren verbos en tiempo -ing en un texto.
### Ejercicios: Nivel 2
1. Escribe un patrón que valide un nombre de variable válido en Python.
2. Limpia el siguiente texto eliminando etiquetas HTML.
```python
text = '''
HTML
Hypertext Markup Language (HTML) is the standard markup language for documents designed to be displayed in a web browser. It can be assisted by technologies such as Cascading Style Sheets (CSS) and scripting languages such as JavaScript.
Web browsers receive HTML documents from a web server or from local storage and render the documents into multimedia web pages. HTML describes the structure of a web page semantically and originally included cues for the appearance of the document.
HTML elements are the building blocks of HTML pages. With HTML constructs, images and other objects such as interactive forms may be embedded into the rendered page. HTML provides a means to create structured documents by denoting structural semantics for text such as headings, paragraphs, lists, links, quotes and other items. HTML elements are delineated by tags, written using angle brackets. Tags such as and directly introduce content into the page. Other tags such as
surround and provide information about document text and may include other tags as sub-elements. Browsers do not display the HTML tags, but use them to interpret the content of the page.
HTML can embed programs written in a scripting language such as JavaScript, which affects the behavior and content of web pages. Inclusion of CSS defines the look and layout of content. The World Wide Web Consortium (W3C), former maintainer of the HTML and current maintainer of the CSS standards, has encouraged the use of CSS over explicit presentational HTML since 1997.
'''
```
### Ejercicios: Nivel 3
1. Limpia el siguiente texto y, tras limpiarlo, calcula las tres palabras más frecuentes:
```python
paragraph = '''I love teaching. If you do not love teaching what else can you love. I love Python if you do not love something which can give you all the capabilities to develop an application what else can you love.'''
```
2. El siguiente texto contiene varias direcciones de correo electrónico. Escribe un patrón que encuentre o extraiga las direcciones de email válidas:
```py
email_address = '''
asabeneh@gmail.com
alex@yahoo.com
kofi@yahoo.com
doe@arc.gov
asabeneh.com
asabeneh@gmail
alex@yahoo
'''
```
🎉 ¡Felicidades! 🎉
[<< Día 17](./17_exception_handling_sp.md) | [Día 19 >>](./19_file_handling_sp.md)
================================================
FILE: Spanish/19_file_handling_sp.md
================================================
# 30 Días de Python: Día 19 - Manejo de archivos
- [Día 19](#-día-19)
- [Manejo de archivos](#manejo-de-archivos)
- [Abrir un archivo para lectura](#abrir-un-archivo-para-lectura)
- [Abrir un archivo para escritura y actualización](#abrir-un-archivo-para-escritura-y-actualización)
- [Eliminar archivos](#eliminar-archivos)
- [Tipos de archivos](#tipos-de-archivos)
- [Archivos con extensión txt](#archivos-con-extensión-txt)
- [Archivos con extensión json](#archivos-con-extensión-json)
- [Convertir JSON a diccionario](#convertir-json-a-diccionario)
- [Convertir diccionario a JSON](#convertir-diccionario-a-json)
- [Guardar como archivo JSON](#guardar-como-archivo-json)
- [Archivos con extensión csv](#archivos-con-extensión-csv)
- [Archivos con extensión xlsx](#archivos-con-extensión-xlsx)
- [Archivos con extensión xml](#archivos-con-extensión-xml)
- [💻 Ejercicios: Día 19](#-ejercicios-día-19)
- [Ejercicios: Nivel 1](#ejercicios-nivel-1)
- [Ejercicios: Nivel 2](#ejercicios-nivel-2)
- [Ejercicios: Nivel 3](#ejercicios-nivel-3)
# 📘 Día 19
## Manejo de archivos
Hasta ahora hemos visto distintos tipos de datos en Python. Normalmente almacenamos datos en distintos formatos de archivo. Además de manejar archivos, en esta sección veremos diferentes formatos (.txt, .json, .xml, .csv, .tsv, .excel). Primero, familiaricémonos con el manejo de archivos usando un formato común (.txt).
El manejo de archivos es una parte importante de la programación; nos permite crear, leer, actualizar y eliminar archivos. En Python usamos la función incorporada _open()_ para manipular archivos.
```py
# sintaxis
open('filename', mode) # mode(r, a, w, x, t, b) puede ser lectura, escritura o actualización
```
- "r" - lectura - valor por defecto. Abre el archivo solo para lectura; si no existe genera un error.
- "a" - append (añadir) - abre el archivo para agregar contenido al final; crea el archivo si no existe.
- "w" - escritura - abre el archivo para escribir, sobrescribe si existe; crea el archivo si no existe.
- "x" - crear - crea el archivo; si existe genera un error.
- "t" - texto - valor por defecto. Modo texto.
- "b" - binario - modo binario (por ejemplo para imágenes).
### Abrir un archivo para lectura
El modo por defecto de _open_ es lectura, así que no es necesario especificar 'r' o 'rt'. He creado un archivo llamado reading_file_example.txt en el directorio files. Veamos:
```py
f = open('./files/reading_file_example.txt')
print(f) # <_io.TextIOWrapper name='./files/reading_file_example.txt' mode='r' encoding='UTF-8'>
```
Como en el ejemplo, al imprimir el objeto archivo obtenemos información sobre él. Un archivo abierto permite distintos métodos de lectura: _read()_, _readline_, _readlines_. Debemos cerrar el archivo con _close()_ cuando terminemos.
- _read()_: lee todo el texto como una cadena. Podemos limitar el número de caracteres pasando un entero a *read(number)*.
```py
f = open('./files/reading_file_example.txt')
txt = f.read()
print(type(txt))
print(txt)
f.close()
```
```sh
# salida
This is an example to show how to open a file and read.
This is the second line of the text.
```
En lugar de imprimir todo el texto, podemos leer solamente los primeros 10 caracteres:
```py
f = open('./files/reading_file_example.txt')
txt = f.read(10)
print(type(txt))
print(txt)
f.close()
```
```sh
# salida
This is an
```
- _readline()_: lee solo la primera línea
```py
f = open('./files/reading_file_example.txt')
line = f.readline()
print(type(line))
print(line)
f.close()
```
```sh
# salida
This is an example to show how to open a file and read.
```
- _readlines()_: lee todo el texto línea por línea y devuelve una lista de líneas
```py
f = open('./files/reading_file_example.txt')
lines = f.readlines()
print(type(lines))
print(lines)
f.close()
```
```sh
# salida
['This is an example to show how to open a file and read.\n', 'This is the second line of the text.']
```
Otra forma de obtener todas las líneas como lista es usar _splitlines()_:
```py
f = open('./files/reading_file_example.txt')
lines = f.read().splitlines()
print(type(lines))
print(lines)
f.close()
```
```sh
# salida
['This is an example to show how to open a file and read.', 'This is the second line of the text.']
```
Debemos cerrar los archivos después de abrirlos. Es fácil olvidarse; por eso existe la construcción _with_ que cierra automáticamente:
```py
with open('./files/reading_file_example.txt') as f:
lines = f.read().splitlines()
print(type(lines))
print(lines)
```
```sh
# salida
['This is an example to show how to open a file and read.', 'This is the second line of the text.']
```
### Abrir un archivo para escritura y actualización
Para escribir en un archivo hay que pasar el modo a _open()_:
- "a" - append - añade al final; crea el archivo si no existe.
- "w" - write - sobrescribe el contenido; crea el archivo si no existe.
Añadamos texto al archivo que hemos estado leyendo:
```py
with open('./files/reading_file_example.txt','a') as f:
f.write('Este texto debe añadirse al final')
```
Si el archivo no existe, el siguiente ejemplo creará uno nuevo:
```py
with open('./files/writing_file_example.txt','w') as f:
f.write('Este texto será escrito en el nuevo archivo creado')
```
### Eliminar archivos
Como vimos anteriormente, podemos crear y eliminar directorios con el módulo _os_. Para eliminar archivos también usamos _os_.
```py
import os
os.remove('./files/example.txt')
```
Si el archivo no existe, remove lanzará un error, por lo que es mejor comprobar:
```py
import os
if os.path.exists('./files/example.txt'):
os.remove('./files/example.txt')
else:
print('El archivo no existe')
```
## Tipos de archivos
### Archivos con extensión txt
Los archivos _txt_ son un formato muy común; ya vimos su uso más arriba. Ahora pasemos a JSON.
### Archivos con extensión json
JSON significa JavaScript Object Notation. Es básicamente una representación en cadena de un objeto JavaScript o de un diccionario Python.
_Ejemplo:_
```py
# diccionario
person_dct= {
"name":"Asabeneh",
"country":"Finland",
"city":"Helsinki",
"skills":["JavaScript", "React","Python"]
}
# JSON: la forma en cadena del diccionario
person_json = "{'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'skills': ['JavaScrip', 'React', 'Python']}"
# Usamos triple comillas para que sea multilínea y más legible
person_json = '''{
"name":"Asabeneh",
"country":"Finland",
"city":"Helsinki",
"skills":["JavaScript", "React","Python"]
}'''
```
### Convertir JSON a diccionario
Para convertir JSON a diccionario importamos el módulo json y usamos _loads_.
```py
import json
# JSON
person_json = '''{
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"skills": ["JavaScript", "React", "Python"]
}'''
# Convertir la cadena JSON a diccionario
person_dct = json.loads(person_json)
print(type(person_dct))
print(person_dct)
print(person_dct['name'])
```
```sh
# salida
{'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'skills': ['JavaScrip', 'React', 'Python']}
Asabeneh
```
### Convertir diccionario a JSON
Para convertir un diccionario a JSON usamos _dumps_.
```py
import json
# diccionario en Python
person = {
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"skills": ["JavaScript", "React", "Python"]
}
# convertir diccionario a cadena JSON
person_json = json.dumps(person, indent=4) # indent puede ser 2, 4, 8; formatea la salida
print(type(person_json))
print(person_json)
```
```sh
# salida
{
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"skills": [
"JavaScript",
"React",
"Python"
]
}
```
### Guardar como archivo JSON
También podemos guardar los datos en un archivo JSON:
```py
import json
# diccionario en Python
person = {
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"skills": ["JavaScript", "React", "Python"]
}
with open('./files/json_example.json', 'w', encoding='utf-8') as f:
json.dump(person, f, ensure_ascii=False, indent=4)
```
En el ejemplo usamos encoding y ensure_ascii para manejar caracteres no ASCII. Ejemplo con caracteres no ASCII:
```py
import json
person = {
"name": "Mark Firenze",
"country": "Spain",
"city": "Madrid",
"skills": ["JavaScript", "React", "Python"]
}
with open('./files/json_example.json', 'w', encoding='utf-8') as f:
json.dump(person, f, ensure_ascii=False, indent=4)
```
Leamos el archivo JSON que acabamos de crear:
```py
import json
with open('./files/json_example.json', 'r', encoding='utf-8') as f:
person = json.load(f)
print(person)
```
```sh
# salida
{'name': 'Mark Firenze', 'country': 'Spain', 'city': 'Madrid', 'skills': ['JavaScript', 'React', 'Python']}
```
### Archivos con extensión csv
CSV significa Comma Separated Values (valores separados por comas). Es un formato sencillo para datos tabulares (como hojas de cálculo o bases de datos) muy común en ciencia de datos.
_Ejemplo CSV:_
```csv
"name","country","city","skills"
"Asabeneh","Finland","Helsinki","JavaScript"
```
Ejemplo de lectura:
```py
import csv
with open('./files/csv_example.csv') as f:
csv_reader = csv.reader(f, delimiter=',') # w+ crea el archivo si no existe
line_count = 0
for row in csv_reader:
if line_count == 0:
print(f'Encabezados: {", ".join(row)}')
line_count += 1
else:
print(f'{row[0]} viene de {row[1]}, {row[2]}. Conoce {row[3]}')
line_count += 1
print(f'Procesadas {line_count} líneas.')
```
```sh
# salida:
Encabezados: name, country, city, skills
Asabeneh viene de Finland, Helsinki. Conoce JavaScript
Procesadas 2 líneas.
```
También podemos escribir CSV:
```py
import csv
with open('./files/csv_example.csv', 'w', encoding='UTF8', newline='') as f:
writer = csv.writer(f)
# escribir encabezados
writer.writerow(['name', 'country', 'city', 'skills'])
# escribir datos
writer.writerow(['Asabeneh', 'Finland', 'Helsinki', 'JavaScript'])
```
### Archivos con extensión xlsx
Para leer archivos Excel necesitamos instalar la librería xlrd (u otras alternativas). Ejemplo:
```py
import xlrd
excel_book = xlrd.open_workbook('sample.xls')
print(excel_book.nsheets)
print(excel_book.sheet_names)
```
### Archivos con extensión xml
XML es un lenguaje de marcado similar a HTML. Permite etiquetas personalizadas y se usa para datos estructurados. En Python hay varias librerías; aquí usamos xml.etree.ElementTree.
_Ejemplo XML:_
```xml
AsabenehFinlandHelsinkiJavaScriptReactPython
```
Usamos xml.etree.ElementTree para parsear:
```py
import xml.etree.ElementTree as ET
tree = ET.parse('./files/xml_example.xml')
root = tree.getroot()
print('Etiqueta raíz:', root.tag)
print('Atributos:', root.attrib)
for child in root:
print('Campo: ', child.tag)
```
```sh
# salida
Etiqueta raíz: person
Atributos: {'gender': 'female'}
Campo: name
Campo: country
Campo: city
Campo: skills
```
Obtener más detalles:
```py
import xml.etree.ElementTree as ET
tree = ET.parse('./files/xml_example.xml')
root = tree.getroot()
print('Etiqueta raíz:', root.tag)
print('Atributos:', root.attrib)
for child in root:
print('Campo: ', child.tag)
if child.tag != 'skills':
print(child.text)
else:
for skill in child:
print(skill.text)
```
```sh
# salida
Etiqueta raíz: person
Atributos: {'gender': 'female'}
field: name
Asabeneh
field: country
Finland
field: city
Helsinki
field: skills
JavaScript
React
Python
```
## 💻 Ejercicios: Día 19
### Ejercicios: Nivel 1
1. Escribe una función que reciba un parámetro (nombre de archivo) y cuente el número de palabras del archivo.
2. Lee el archivo obama_speech.txt y cuenta las palabras.
3. Lee michelle_obama_speech.txt y cuenta las palabras.
4. Lee donald_speech.txt y cuenta las palabras.
5. Lee melina_trump_speech.txt y cuenta las palabras.
### Ejercicios: Nivel 2
1. Extrae todos los archivos Python del directorio del curso:
a) Recorre la carpeta 30DaysOfPython, extrae todos los archivos .py y guarda sus nombres en files_list.txt
b) Crea un script llamado find_python.py que pueda ejecutarse desde la línea de comandos
c) Añade una opción --version para manejar argumentos de línea de comandos
### Ejercicios: Nivel 3
1. Crea un archivo JSON a partir del siguiente dataset:
```py
python_libraries = [
{
"nombre_librería": "Django",
"creador": "Adrian Holovaty",
"primer_año_lanzamiento": 2005,
"versión": "4.0.2",
"uso": "Desarrollo web",
"descripción": "Django permite construir aplicaciones web mejores y más rápido."
},
{
"nombre_librería": "Flask",
"creador": "Armin Ronacher",
"primer_año_lanzamiento": 2010,
"versión": "2.0.2",
"uso": "Desarrollo web",
"descripción": "Flask es un micro framework WSGI para aplicaciones web."
},
{
"nombre_librería": "NumPy",
"creador": "Travis Oliphant",
"primer_año_lanzamiento": 2005,
"versión": "1.22.0",
"uso": "Cómputo científico",
"descripción": "NumPy es la biblioteca fundamental para el cómputo científico en Python."
},
{
"nombre_librería": "Pandas",
"creador": "Wes McKinney",
"primer_año_lanzamiento": 2008,
"versión": "1.4.0",
"uso": "Análisis de datos",
"descripción": "pandas es una librería open source para análisis y manipulación de datos."
},
{
"nombre_librería": "Matplotlib",
"creador": "John D. Hunter",
"primer_año_lanzamiento": 2003,
"versión": "3.5.1",
"uso": "Visualización de datos",
"descripción": "Matplotlib es una librería para crear visualizaciones estáticas, animadas e interactivas en Python."
}
]
```
🎉 ¡Felicidades! 🎉
[<< Día 18](./18_regular_expressions_sp.md) | [Día 20 >>](./20_python_package_manager_sp.md)
================================================
FILE: Spanish/20_python_package_manager_sp.md
================================================
# 30 Días de Python: Día 20 - PIP
- [Día 20](#-día-20)
- [Python PIP - Gestor de paquetes de Python](#python-pip---gestor-de-paquetes-de-python)
- [¿Qué es PIP?](#¿qué-es-pip)
- [Instalar PIP](#instalar-pip)
- [Instalar paquetes con pip](#instalar-paquetes-con-pip)
- [Desinstalar paquetes](#desinstalar-paquetes)
- [Lista de paquetes](#lista-de-paquetes)
- [Mostrar información del paquete](#mostrar-información-del-paquete)
- [PIP Freeze](#pip-freeze)
- [Leer datos desde una URL](#leer-datos-desde-una-url)
- [Crear paquetes](#crear-paquetes)
- [Más información sobre paquetes](#más-información-sobre-paquetes)
- [Ejercicios: Día 20](#ejercicios-día-20)
# 📘 Día 20
## Python PIP - Gestor de paquetes de Python
### ¿Qué es PIP?
PIP significa Preferred Installer Program, que en español puede traducirse como «programa de instalación preferido». Usamos _pip_ para instalar paquetes de Python.
Un paquete es una colección de módulos (o subpaquetes) que podemos instalar y luego importar en nuestras aplicaciones.
En la práctica, en lugar de reescribir utilidades comunes, instalamos paquetes útiles y los importamos.
### Instalar PIP
Si aún no tienes pip instalado, instálalo ahora. En la terminal o símbolo del sistema ejecuta:
```sh
pip install pip
```
Comprueba si pip está instalado con:
```sh
pip --version
```
```py
pip --version
# ejemplo de salida:
# pip 21.1.3 from /usr/local/lib/python3.7/site-packages/pip (python 3.9.6)
```
Si ves un número diferente, significa que pip está instalado en tu sistema.
### Instalar paquetes con pip
Probemos a instalar _numpy_, una librería numérica de Python muy usada en ciencia de datos y aprendizaje automático.
- NumPy ofrece:
- Potentes arrays N-dimensionales
- Operaciones vectorizadas (broadcasting)
- Herramientas para integrar con C/C++ y Fortran
- Funciones de álgebra lineal, transformadas de Fourier y generadores aleatorios
```sh
pip install numpy
```
Ejemplo de uso en el intérprete de Python:
```py
>>> import numpy
>>> numpy.version.version
'1.20.1'
>>> lst = [1, 2, 3, 4, 5]
>>> np_arr = numpy.array(lst)
>>> np_arr
array([1, 2, 3, 4, 5])
>>> len(np_arr)
5
>>> np_arr * 2
array([ 2, 4, 6, 8, 10])
>>> np_arr + 2
array([3, 4, 5, 6, 7])
```
Pandas es otra librería muy usada para estructuras de datos y análisis. Instalémosla:
```sh
pip install pandas
```
```py
>>> import pandas
```
Esta sección no pretende profundizar en NumPy o Pandas, sino solo mostrar cómo instalar e importar paquetes.
Hay módulos de la librería estándar, por ejemplo _webbrowser_, que permiten abrir sitios web. No necesitan instalación.
```py
import webbrowser # módulo para abrir sitios web
# lista de URLs de ejemplo
url_lists = [
'http://www.python.org',
'https://www.linkedin.com/in/asabeneh/',
'https://github.com/Asabeneh',
'https://twitter.com/Asabeneh',
]
# abrir cada URL en una nueva pestaña
for url in url_lists:
webbrowser.open_new_tab(url)
```
### Desinstalar paquetes
Para eliminar un paquete instalado:
```sh
pip uninstall packagename
```
### Lista de paquetes
Para listar los paquetes instalados en tu entorno:
```sh
pip list
```
### Mostrar información del paquete
Para ver información de un paquete:
```sh
pip show packagename
```
Ejemplo:
```sh
pip show pandas
```
Salida de ejemplo:
```txt
Name: pandas
Version: 1.2.3
Summary: Powerful data structures for data analysis, time series, and statistics
Home-page: http://pandas.pydata.org
Author: None
Author-email: None
License: BSD
Location: /usr/local/lib/python3.7/site-packages
Requires: python-dateutil, pytz, numpy
Required-by:
```
Si quieres más detalles puedes añadir --verbose.
### PIP Freeze
Genera una lista de paquetes instalados y sus versiones (útil para requirements.txt):
```sh
pip freeze
```
Salida de ejemplo:
```txt
docutils==0.11
Jinja2==2.7.2
MarkupSafe==0.19
Pygments==1.6
Sphinx==1.2.2
```
### Leer datos desde una URL
A veces queremos leer datos desde una URL (por ejemplo APIs que devuelven JSON). Para eso usamos el paquete _requests_.
Instálalo con:
```sh
pip install requests
```
En requests veremos métodos y atributos como _get()_, _status_code_, _headers_, _text_, _json()_:
- _get()_: solicita una URL y devuelve un objeto Response
- _status_code_: código HTTP de la respuesta
- _headers_: cabeceras de la respuesta
- _text_: contenido en texto
- _json()_: parsea JSON y devuelve estructuras de Python
Ejemplo leyendo un archivo de texto desde la web:
```py
import requests # importar requests
url = 'https://www.w3.org/TR/PNG/iso_8859-1.txt' # URL con texto
response = requests.get(url) # solicitar URL
print(response)
print(response.status_code) # código de estado, 200 indica éxito
print(response.headers) # cabeceras de la respuesta
print(response.text) # contenido en texto
```
Ejemplo leyendo una API que devuelve JSON (API de países):
```py
import requests
url = 'https://restcountries.eu/rest/v2/all' # API con información de países
response = requests.get(url)
print(response) # objeto Response
print(response.status_code) # 200 indica éxito
countries = response.json()
print(countries[:1]) # imprimimos el primer país por brevedad
```
Veamos otro ejemplo con la API del Banco Mundial (datos de Etiopía):
```py
import requests
from pprint import pp # pretty print para mostrar resultados legibles
url = 'http://api.worldbank.org/countries/et?format=json' # API del Banco Mundial para Etiopía
response = requests.get(url)
print(response) # objeto Response
print(response.status_code) # 200 indica éxito
ethiopia_data = response.json()
pp(ethiopia_data) # mostrar datos de forma legible
```
### Crear paquetes
También podemos crear nuestros propios paquetes y subirlos a PyPI. Ejemplo simple: crea un directorio llamado mypackage con un __init__.py (puede estar vacío) y los siguientes módulos.
```py
# mypackage/arithmetics.py
def add_numbers(*args):
total = 0
for num in args:
total += num
return total
def subtract(a, b):
return (a - b)
def multiple(a, b):
return a * b
def division(a, b):
return a / b
def remainder(a, b):
return a % b
def power(a, b):
return a ** b
```
```py
# mypackage/greet.py
def greet_person(firstname, lastname):
return f'{firstname} {lastname}, welcome to 30DaysOfPython Challenge!'
```
__init__.py no es estrictamente necesario en Python ≥3.3, pero se recomienda para compatibilidad.
Usando el paquete:
```py
from mypackage import arithmetics
print(arithmetics.add_numbers(1, 2, 3, 5))
print(arithmetics.subtract(5, 3))
print(arithmetics.multiple(5, 3))
print(arithmetics.division(5, 3))
print(arithmetics.remainder(5, 3))
print(arithmetics.power(5, 3))
from mypackage import greet
print(greet.greet_person('Juan', 'Pérez'))
```
### Más información sobre paquetes
- Python tiene paquetes y módulos incorporados; otros deben instalarse.
- pip es la herramienta recomendada para instalar y gestionar paquetes desde PyPI.
- Para capturar las dependencias de un proyecto usa pip freeze > requirements.txt.
- Para desinstalar: pip uninstall packagename o pip uninstall -r requirements.txt.
- Virtualenv (y venv) permiten crear entornos aislados:
- Instalar virtualenv: pip install virtualenv
- Crear entornos aislados evita conflictos entre proyectos.
## Ejercicios: Día 20
1. Lee sobre entornos virtuales, crea uno e instala al menos un paquete dentro del entorno.
2. Usa una API de países para obtener todos los datos y encuentra los 10 países más poblados.
3. Encuentra todos los países cuyo idioma oficial sea inglés (código 'eng') a partir de los datos de la API.
4. A partir de los datos de la API, encuentra los 10 países con mayor superficie.
5. Encuentra todos los países recién listados (o filtrados según la API) y ordénalos por capital.
🎉 ¡Felicidades! 🎉
[<< Día 19](./19_file_handling_sp.md) | [Día 21 >>](./21_classes_and_objects_sp.md)
================================================
FILE: Spanish/21_classes_and_objects_sp.md
================================================
# 30 Días de Python: Día 21 - Clases y Objetos
- [Día 21](#-día-21)
- [Clases y objetos](#clases-y-objetos)
- [Crear una clase](#crear-una-clase)
- [Crear un objeto](#crear-un-objeto)
- [Constructor de clase](#constructor-de-clase)
- [Métodos de instancia](#métodos-de-instancia)
- [Valores por defecto de los objetos](#valores-por-defecto-de-los-objetos)
- [Modificar valores por defecto de la clase](#modificar-valores-por-defecto-de-la-clase)
- [Herencia](#herencia)
- [Sobrescribir métodos de la clase padre](#sobrescribir-métodos-de-la-clase-padre)
- [💻 Ejercicios: Día 21](#-ejercicios-día-21)
- [Ejercicios: Nivel 1](#ejercicios-nivel-1)
- [Ejercicios: Nivel 2](#ejercicios-nivel-2)
- [Ejercicios: Nivel 3](#ejercicios-nivel-3)
# 📘 Día 21
## Clases y objetos
Python es un lenguaje orientado a objetos. En Python todo es un objeto con atributos y métodos. Los números, cadenas, listas, diccionarios, tuplas, conjuntos, etc. que usamos en programas son instancias de las clases incorporadas correspondientes. Creamos clases para definir objetos. Una clase es como un constructor de objetos o un "molde" para crear objetos. Instanciamos una clase para crear un objeto. La clase define las propiedades y el comportamiento, mientras que el objeto representa la instancia.
Desde el inicio de este reto hemos estado usando clases y objetos sin darnos cuenta. Cada elemento en un programa Python es un objeto perteneciente a alguna clase. Veamos que todo en Python pertenece a una clase:
```py
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> num = 10
>>> type(num)
>>> string = 'string'
>>> type(string)
>>> boolean = True
>>> type(boolean)
>>> lst = []
>>> type(lst)
>>> tpl = ()
>>> type(tpl)
>>> set1 = set()
>>> type(set1)
>>> dct = {}
>>> type(dct)
```
### Crear una clase
Para crear una clase usamos la palabra clave class seguida del nombre de la clase y dos puntos. El nombre de la clase debe usar CamelCase.
```sh
# sintaxis
class NombreClase:
# código aquí
```
**Ejemplo:**
```py
class Person:
pass
print(Person)
```
```sh
<__main__.Person object at 0x10804e510>
```
### Crear un objeto
Creamos un objeto llamando a la clase:
```py
p = Person()
print(p)
```
### Constructor de clase
En el ejemplo anterior creamos un objeto de la clase Person. Sin embargo, una clase sin constructor no es muy útil en la práctica. Usamos el método especial __init__ como constructor en Python. __init__ recibe self, que es la referencia a la instancia actual.
**Ejemplo:**
```py
class Person:
def __init__(self, name):
# self permite ligar parámetros a la instancia
self.name = name
p = Person('Asabeneh')
print(p.name)
print(p)
```
```sh
# salida
Asabeneh
<__main__.Person object at 0x2abf46907e80>
```
Añadamos más parámetros al constructor:
```py
class Person:
def __init__(self, firstname, lastname, age, country, city):
self.firstname = firstname
self.lastname = lastname
self.age = age
self.country = country
self.city = city
p = Person('Asabeneh', 'Yetayeh', 250, 'Finland', 'Helsinki')
print(p.firstname)
print(p.lastname)
print(p.age)
print(p.country)
print(p.city)
```
```sh
# salida
Asabeneh
Yetayeh
250
Finland
Helsinki
```
### Métodos de instancia
Un objeto puede tener métodos, que son funciones pertenecientes a esa instancia.
**Ejemplo:**
```py
class Person:
def __init__(self, firstname, lastname, age, country, city):
self.firstname = firstname
self.lastname = lastname
self.age = age
self.country = country
self.city = city
def person_info(self):
return f'{self.firstname} {self.lastname} tiene {self.age} años. Vive en {self.city}, {self.country}.'
p = Person('Asabeneh', 'Yetayeh', 250, 'Finland', 'Helsinki')
print(p.person_info())
```
```sh
# salida
Asabeneh Yetayeh tiene 250 años. Vive en Helsinki, Finland.
```
### Valores por defecto de los objetos
A veces queremos proporcionar valores por defecto a los parámetros del constructor para evitar errores cuando la clase se instancia sin argumentos.
**Ejemplo:**
```py
class Person:
def __init__(self, firstname='Asabeneh', lastname='Yetayeh', age=250, country='Finland', city='Helsinki'):
self.firstname = firstname
self.lastname = lastname
self.age = age
self.country = country
self.city = city
def person_info(self):
return f'{self.firstname} {self.lastname} tiene {self.age} años. Vive en {self.city}, {self.country}.'
p1 = Person()
print(p1.person_info())
p2 = Person('John', 'Doe', 30, 'Nomanland', 'Noman city')
print(p2.person_info())
```
```sh
# salida
Asabeneh Yetayeh tiene 250 años. Vive en Helsinki, Finland.
John Doe tiene 30 años. Vive en Noman city, Nomanland.
```
### Modificar valores por defecto de la clase
En el siguiente ejemplo todos los parámetros del constructor tienen valores por defecto y añadimos un atributo skills y un método add_skill para añadir habilidades.
```py
class Person:
def __init__(self, firstname='Asabeneh', lastname='Yetayeh', age=250, country='Finland', city='Helsinki'):
self.firstname = firstname
self.lastname = lastname
self.age = age
self.country = country
self.city = city
self.skills = []
def person_info(self):
return f'{self.firstname} {self.lastname} tiene {self.age} años. Vive en {self.city}, {self.country}.'
def add_skill(self, skill):
self.skills.append(skill)
p1 = Person()
print(p1.person_info())
p1.add_skill('HTML')
p1.add_skill('CSS')
p1.add_skill('JavaScript')
p2 = Person('John', 'Doe', 30, 'Nomanland', 'Noman city')
print(p2.person_info())
print(p1.skills)
print(p2.skills)
```
```sh
# salida
Asabeneh Yetayeh tiene 250 años. Vive en Helsinki, Finland.
John Doe tiene 30 años. Vive en Noman city, Nomanland.
['HTML', 'CSS', 'JavaScript']
[]
```
### Herencia
La herencia nos permite definir una clase que hereda el comportamiento de otra, facilitando la reutilización del código.
```py
# sintaxis
class NombreSubclase(NombreSuperclase):
# código aquí
```
Ejemplo:
```py
class Student(Person):
pass
s1 = Student('Eyob', 'Yetayeh', 30, 'Finland', 'Helsinki')
s2 = Student('Lidiya', 'Teklemariam', 28, 'Finland', 'Espoo')
print(s1.person_info())
s1.add_skill('JavaScript')
s1.add_skill('React')
s1.add_skill('Python')
print(s1.skills)
print(s2.person_info())
s2.add_skill('Organizing')
s2.add_skill('Marketing')
s2.add_skill('Digital Marketing')
print(s2.skills)
```
```sh
# salida
Eyob Yetayeh tiene 30 años. Vive en Helsinki, Finland.
['JavaScript', 'React', 'Python']
Lidiya Teklemariam tiene 28 años. Vive en Espoo, Finland.
['Organizing', 'Marketing', 'Digital Marketing']
```
No hemos definido nuevos métodos en Student, pero puede usar los métodos del padre Person. Student hereda el constructor __init__ y el método person_info de Person. Si queremos añadir comportamiento específico en la subclase, definimos nuevos métodos o redefinimos los existentes.
```py
class Student(Person):
def __init__(self, firstname='Asabeneh', lastname='Yetayeh', age=250, country='Finland', city='Helsinki', gender='male'):
self.gender = gender
super().__init__(firstname, lastname, age, country, city)
def person_info(self):
gender = 'él' if self.gender == 'male' else 'ella'
return f'{self.firstname} {self.lastname} tiene {self.age} años. {gender.capitalize()} vive en {self.city}, {self.country}.'
s1 = Student('Eyob', 'Yetayeh', 30, 'Finland', 'Helsinki', 'male')
s2 = Student('Lidiya', 'Teklemariam', 28, 'Finland', 'Espoo', 'female')
print(s1.person_info())
s1.add_skill('JavaScript')
s1.add_skill('React')
s1.add_skill('Python')
print(s1.skills)
print(s2.person_info())
s2.add_skill('Organizing')
s2.add_skill('Marketing')
s2.add_skill('Digital Marketing')
print(s2.skills)
```
```sh
# salida
Eyob Yetayeh tiene 30 años. Él vive en Helsinki, Finland.
['JavaScript', 'React', 'Python']
Lidiya Teklemariam tiene 28 años. Ella vive en Espoo, Finland.
['Organizing', 'Marketing', 'Digital Marketing']
```
Podemos usar super() o el nombre de la clase padre para invocar el comportamiento del padre. En el ejemplo anterior sobrescribimos el método person_info en la subclase con una implementación distinta.
### Sobrescribir métodos de la clase padre
Como se mostró, podemos sobrescribir un método del padre definiendo en la subclase un método con el mismo nombre.
## 💻 Ejercicios: Día 21
### Ejercicios: Nivel 1
1. Python tiene un módulo llamado _statistics_ que podemos usar para calcular estadísticas. Ahora intentemos desarrollar una clase que calcule count, sum, min, max, range, mean, median, mode, standard deviation, variance, frequency distribution y describe.
```py
class Statistics:
def __init__(self, data=[]):
self.data = data
def count(self):
# tu propia implementación
pass
def sum(self):
# tu propia implementación
pass
def min(self):
# tu propia implementación
pass
def max(self):
# tu propia implementación
pass
def range(self):
# tu propia implementación
pass
def mean(self):
# tu propia implementación
pass
def median(self):
# tu propia implementación
pass
def mode(self):
# tu propia implementación
pass
def standard_deviation(self):
# tu propia implementación
pass
def variance(self):
# tu propia implementación
pass
def frequency_distribution(self):
# tu propia implementación
pass
def describe(self):
# tu propia implementación
pass
```
```py
# código de prueba
data = [31, 26, 34, 37, 27, 26, 32, 32, 26, 27, 27, 24, 32, 33, 27, 25, 26, 38, 37, 31, 34, 24, 33, 29, 26]
statistics = Statistics(data)
print('Count:', statistics.count()) # 25
print('Sum: ', statistics.sum()) # 730
print('Min: ', statistics.min()) # 24
print('Max: ', statistics.max()) # 38
print('Range: ', statistics.range()) # 14
print('Mean: ', statistics.mean()) # 29.2
print('Median: ', statistics.median()) # 27
print('Mode: ', statistics.mode()) # {'mode': 26, 'count': 5}
print('Standard Deviation: ', statistics.standard_deviation()) # 4.2
print('Variance: ', statistics.variance()) # 17.5
print('Frequency Distribution: ', statistics.frequency_distribution()) # [(24, 2), (25, 1), (26, 5), (27, 4), (29, 1), (31, 2), (32, 3), (33, 2), (34, 2), (37, 2), (38, 1)]
```
### Ejercicios: Nivel 2
1. Crea una clase llamada PersonAccount. Debe tener firstname, lastname, incomes, expenses como atributos y métodos para añadir ingresos, añadir gastos y calcular el balance.
### Ejercicios: Nivel 3
1. El siguiente código es una función; conviértelo en una clase con comportamiento equivalente.
```python
def print_products(*args, **kwargs):
for product in args:
print(product)
print(kwargs)
for key in kwargs:
print(f"{key}: {kwargs[key]}")
print_products("apple", "banana", "orange", vegetable="tomato", juice="orange")
```
```sh
apple
banana
orange
{'vegetable': 'tomato', 'juice': 'orange'}
vegetable: tomato
juice: orange
```
2. En la clase PersonAccount diseña atributos firstname, lastname, incomes y expenses y añade métodos para calcular el ingreso neto de la persona.
🎉 ¡Felicidades! 🎉
[<< Día 20](./20_python_package_manager_sp.md) | [Día 22 >>](./22_web_scraping_sp.md)
================================================
FILE: Spanish/22_web_scraping_sp.md
================================================
# 30 Días de Python: Día 22 - Web scraping
- [Día 22](#-día-22)
- [Web scraping con Python](#web-scraping-con-python)
- [¿Qué es el web scraping?](#qué-es-el-web-scraping)
- [💻 Ejercicios: Día 22](#-ejercicios-día-22)
# 📘 Día 22
## Web scraping con Python
### ¿Qué es el web scraping?
Internet está lleno de datos que pueden utilizarse para distintos fines. Para recopilar esos datos necesitamos saber cómo extraerlos de sitios web.
El web scraping es el proceso de extraer y recopilar datos de sitios web y almacenarlos en una máquina local o en una base de datos.
En esta sección usaremos los paquetes requests y BeautifulSoup (versión 4).
Para empezar necesitas _requests_,_beautifulsoup4_ y un _sitio web_:
```sh
pip install requests
pip install beautifulsoup4
```
Para hacer scraping necesitas conocimientos básicos de etiquetas HTML y selectores CSS. Usamos etiquetas HTML,clases y/o IDs para localizar contenido en la página.
Importemos requests y BeautifulSoup:
```py
import requests
from bs4 import BeautifulSoup
```
Declaremos una variable url con el sitio que queremos scrapear:
```py
import requests
from bs4 import BeautifulSoup
url = 'https://archive.ics.uci.edu/ml/datasets.php'
# Usamos requests.get para obtener datos de la URL
response = requests.get(url)
# Comprobar el estado
status = response.status_code
print(status) # 200 indica éxito
```
```sh
200
```
Parsear el contenido con BeautifulSoup:
```py
import requests
from bs4 import BeautifulSoup
url = 'https://archive.ics.uci.edu/ml/datasets.php'
response = requests.get(url)
content = response.content # obtenemos todo el contenido del sitio
soup = BeautifulSoup(content, 'html.parser') # BeautifulSoup nos permite parsear el HTML
print(soup.title) # UCI Machine Learning Repository: Data Sets
print(soup.title.get_text()) # UCI Machine Learning Repository: Data Sets
print(soup.body) # muestra el cuerpo completo de la página
print(response.status_code)
tables = soup.find_all('table', {'cellpadding':'3'})
# Localizamos tablas cuyo atributo cellpadding tenga el valor 3
# Podemos usar id, class o etiquetas HTML para seleccionar elementos; consulta la documentación de BeautifulSoup para más información
table = tables[0] # el resultado es una lista; tomamos el primer elemento
for td in table.find('tr').find_all('td'):
print(td.text)
```
Si ejecutas este código verás que la extracción está incompleta.Puedes continuar para completarla,ya que forma parte del ejercicio 1.
Consulta la documentación de BeautifulSoup para más detalles: https://www.crummy.com/software/BeautifulSoup/bs4/doc/#quick-start
🌕 Vas por muy buen camino.Solo te faltan ocho días para alcanzar una meta impresionante.Ahora haz los ejercicios para practicar.
## 💻 Ejercicios: Día 22
1. Raspa el siguiente sitio y guarda los datos como un archivo JSON (url = 'http://www.bu.edu/president/boston-university-facts-stats/').
2. Extrae las tablas de esta URL (https://archive.ics.uci.edu/ml/datasets.php) y conviértelas a un archivo JSON.
3. Raspa la tabla de presidentes y guarda los datos como JSON (https://en.wikipedia.org/wiki/List_of_presidents_of_the_United_States).Esta tabla no está muy bien estructurada,por lo que la extracción puede llevar tiempo.
🎉 ¡Felicidades!🎉
[<< Día 21](./21_classes_and_objects_sp.md) | [Día 23 >>](./23_virtual_environment_sp.md)
================================================
FILE: Spanish/23_virtual_environment_sp.md
================================================
# 30 Días de Python: Día 23 - Entornos virtuales
- [Día 23](#-día-23)
- [Configurar un entorno virtual](#configurar-un-entorno-virtual)
- [💻 Ejercicios: Día 23](#-ejercicios-día-23)
# 📘 Día 23
## Configurar un entorno virtual
Al comenzar un proyecto es recomendable usar un entorno virtual. Un entorno virtual nos permite crear un entorno aislado o independiente, evitando conflictos de dependencias entre proyectos. Si ejecutas pip freeze en la terminal verás todos los paquetes instalados en la máquina. Con virtualenv solo tendrás acceso a los paquetes instalados en ese entorno específico. Abre tu terminal e instala virtualenv:
```sh
pip install virtualenv
```
Dentro de la carpeta 30DaysOfPython crea un directorio llamado flask_project.
Una vez instalado virtualenv, entra en la carpeta del proyecto y crea el entorno virtual:
Para Mac/Linux:
```sh
virtualenv venv
```
Para Windows:
```sh
python -m venv venv
```
A mí me gusta nombrar el entorno como venv, pero puedes elegir otro nombre. Usa ls (o dir en Windows) para comprobar que venv se creó:
```sh
ls
# venv/
```
Activa el entorno virtual desde la carpeta del proyecto:
Para Mac/Linux:
```sh
source venv/bin/activate
```
En Windows la activación puede variar según PowerShell o Git Bash.
Para Windows PowerShell:
```sh
venv\Scripts\activate
```
Para Windows Git Bash:
```sh
venv\Scripts\. activate
```
Tras ejecutar el comando de activación,el prompt mostrará el nombre del entorno (venv) al inicio.Ejemplo:
```sh
(venv) user@host:~/Desktop/30DaysOfPython/flask_project$
```
Ahora,si ejecutas pip freeze no verás los paquetes globales;solo los del entorno.Instalemos Flask para este proyecto:
```sh
pip install Flask
```
Después,comprobemos los paquetes instalados:
```sh
pip freeze
# ejemplo de salida:
# Click==7.0
# Flask==1.1.1
# itsdangerous==1.1.0
# Jinja2==2.10.3
# MarkupSafe==1.1.1
# Werkzeug==0.16.0
```
Cuando termines,ejecuta deactivate para salir del entorno activo:
```sh
deactivate
```
Los módulos necesarios para trabajar con Flask ya están instalados en el entorno del proyecto.Es buena práctica añadir venv al archivo .gitignore para no subir el entorno a GitHub.
## 💻 Ejercicios: Día 23
1. Crea un directorio de proyecto con un entorno virtual siguiendo el ejemplo anterior.
🎉 ¡Felicidades! 🎉
[<< Día 22](./22_web_scraping_sp.md) | [Día 24 >>](./24_statistics_sp.md)
================================================
FILE: Spanish/24_statistics_sp.md
================================================
# 30 Días de Python: Día 24 - Estadística
- [Día 24](#-día-24)
- [Análisis estadístico con Python](#análisis-estadístico-con-python)
- [Estadística](#estadística)
- [Datos](#datos)
- [Módulo statistics](#módulo-statistics)
- [NumPy](#numpy)
- [Importar NumPy](#importar-numpy)
- [Crear arrays con NumPy](#crear-arrays-con-numpy)
- [Crear arrays enteros con NumPy](#crear-arrays-enteros-con-numpy)
- [Crear arrays float con NumPy](#crear-arrays-float-con-numpy)
- [Crear arrays booleanos con NumPy](#crear-arrays-booleanos-con-numpy)
- [Crear arrays multidimensionales con NumPy](#crear-arrays-multidimensionales-con-numpy)
- [Convertir arrays de NumPy a listas](#convertir-arrays-de-numpy-a-listas)
- [Crear arrays desde tuplas](#crear-arrays-desde-tuplas)
- [Forma (shape) de arrays de NumPy](#forma-shape-de-arrays-de-numpy)
- [Tipo de datos de arrays de NumPy](#tipo-de-datos-de-arrays-de-numpy)
- [Tamaño (size) de arrays de NumPy](#tamaño-size-de-arrays-de-numpy)
- [Operaciones matemáticas con NumPy](#operaciones-matemáticas-con-numpy)
- [Suma](#suma)
# 📘 Día 24
## Análisis estadístico con Python
## Estadística
La estadística es la disciplina que estudia la recolección, organización, presentación, análisis, interpretación y comunicación de datos.
La estadística es una rama de las matemáticas y es un conocimiento previo recomendable para ciencia de datos y machine learning. Es un campo muy amplio; en esta sección nos centraremos solo en las partes más relevantes.
Al completar este reto puedes avanzar hacia desarrollo web, análisis de datos, machine learning o ciencia de datos. En algún punto de tu carrera profesional te enfrentarás a datos que necesitan ser procesados. Tener nociones de estadística te ayudará a tomar decisiones basadas en datos: como dice el dicho, "los datos nos hablan".
## Datos
¿Qué son los datos? Los datos son cualquier conjunto de caracteres recogidos y transformados con algún propósito, usualmente para análisis. Pueden ser texto, números, imágenes, audio o vídeo. Si los datos carecen de contexto son poco útiles para humanos o máquinas. Para extraer significado necesitamos herramientas que los procesen.
El flujo de trabajo en análisis de datos, ciencia de datos o machine learning comienza siempre por los datos. Pueden provenir de fuentes externas o ser generados. Existen datos estructurados y no estructurados.
Los datos pueden ser pequeños o masivos. Muchos de los formatos de datos que encontrarás ya se han presentado en la sección de manejo de archivos.
## Módulo statistics
El módulo _statistics_ de Python ofrece funciones para cálculos estadísticos sobre datos numéricos. No compite con bibliotecas avanzadas de terceros (NumPy, SciPy) ni con paquetes profesionales de estadística, sino que provee funcionalidades a un nivel similar al de calculadoras científicas o gráficas.
# NumPy
Como lenguaje general, Python se potencia con librerías como numpy, scipy, matplotlib y pandas, transformándose en un entorno potente para computación científica.
NumPy es la librería central para computación científica en Python; ofrece arrays multidimensionales de alto rendimiento y herramientas para operar con ellos.
Para trabajar con notebooks es recomendable usar Jupyter. Puedes instalar Anaconda para disponer de Jupyter y muchas librerías preinstaladas.
```sh
pip install numpy
```
## Importar NumPy
Si usas Jupyter (recomendado), puedes seguir este notebook de ejemplo.
```py
# cómo importar numpy
import numpy as np
# cómo comprobar la versión de numpy
print('numpy:', np.__version__)
# ver métodos disponibles
print(dir(np))
```
## Crear arrays con NumPy
### Crear arrays enteros con NumPy
```py
# crear una lista de Python
python_list = [1,2,3,4,5]
# comprobar tipo
print('Type:', type(python_list)) #
print(python_list) # [1, 2, 3, 4, 5]
two_dimensional_list = [[0,1,2], [3,4,5], [6,7,8]]
print(two_dimensional_list) # [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
# crear un array NumPy desde la lista de Python
numpy_array_from_list = np.array(python_list)
print(type(numpy_array_from_list)) #
print(numpy_array_from_list) # array([1, 2, 3, 4, 5])
```
### Crear arrays float con NumPy
```py
# lista de Python
python_list = [1,2,3,4,5]
numpy_array_from_list2 = np.array(python_list, dtype=float)
print(numpy_array_from_list2) # array([1., 2., 3., 4., 5.])
```
### Crear arrays booleanos con NumPy
```py
numpy_bool_array = np.array([0, 1, -1, 0, 0], dtype=bool)
print(numpy_bool_array) # array([False, True, True, False, False])
```
### Crear arrays multidimensionales con NumPy
Un array de NumPy puede tener múltiples filas y columnas:
```py
two_dimensional_list = [[0,1,2], [3,4,5], [6,7,8]]
numpy_two_dimensional_list = np.array(two_dimensional_list)
print(type(numpy_two_dimensional_list))
print(numpy_two_dimensional_list)
```
```sh
[[0 1 2]
[3 4 5]
[6 7 8]]
```
### Convertir arrays de NumPy a listas
```py
# podemos usar tolist() para convertir un array a lista de Python
np_to_list = numpy_array_from_list.tolist()
print(type(np_to_list))
print('Array 1D:', np_to_list)
print('Array 2D: ', numpy_two_dimensional_list.tolist())
```
```sh
Array 1D: [1, 2, 3, 4, 5]
Array 2D: [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
```
### Crear arrays desde tuplas
```py
# crear una tupla en Python
python_tuple = (1,2,3,4,5)
print(type(python_tuple)) #
print('python_tuple: ', python_tuple) # python_tuple: (1, 2, 3, 4, 5)
numpy_array_from_tuple = np.array(python_tuple)
print(type(numpy_array_from_tuple)) #
print('numpy_array_from_tuple: ', numpy_array_from_tuple) # numpy_array_from_tuple: [1 2 3 4 5]
```
### Forma (shape) de arrays de NumPy
El método shape devuelve una tupla con la forma del array: filas y columnas. Si el array es 1D devuelve su longitud.
```py
nums = np.array([1, 2, 3, 4, 5])
print(nums)
print('Forma de nums: ', nums.shape)
print(numpy_two_dimensional_list)
print('Forma de numpy_two_dimensional_list: ', numpy_two_dimensional_list.shape)
three_by_four_array = np.array([[0, 1, 2, 3],
[4,5,6,7],
[8,9,10, 11]])
print(three_by_four_array.shape)
```
```sh
[1 2 3 4 5]
Forma de nums: (5,)
[[0 1 2]
[3 4 5]
[6 7 8]]
Forma de numpy_two_dimensional_list: (3, 3)
(3, 4)
```
### Tipo de datos de arrays de NumPy
Tipos de datos: str, int, float, complex, bool, list, None
```py
int_lists = [-3, -2, -1, 0, 1, 2,3]
int_array = np.array(int_lists)
float_array = np.array(int_lists, dtype=float)
print(int_array)
print(int_array.dtype)
print(float_array)
print(float_array.dtype)
```
```sh
[-3 -2 -1 0 1 2 3]
int64
[-3. -2. -1. 0. 1. 2. 3.]
float64
```
### Tamaño (size) de arrays de NumPy
Para conocer el número de elementos de un array utilizamos size:
```py
numpy_array_from_list = np.array([1, 2, 3, 4, 5])
two_dimensional_list = np.array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
print('Tamaño:', numpy_array_from_list.size) # 5
print('Tamaño:', two_dimensional_list.size) # 9
```
```sh
Tamaño: 5
Tamaño: 9
```
## Operaciones matemáticas con NumPy
Los arrays de NumPy permiten operaciones vectorizadas sin necesidad de bucles.
Operaciones disponibles:
- Suma (+)
- Resta (-)
- Multiplicación (*)
- División (/)
- Módulo (%)
- División entera (//)
- Potencia (**)
### Suma
```py
numpy_array_from_list = np.array([1, 2, 3, 4, 5])
print('Array original: ', numpy_array_from_list)
print('Suma: ', numpy_array_from_list + 2)
print('Suma: ', np.add(numpy_array_from_list, 2))
```
```sh
Array original: [1 2 3 4 5]
Suma: [3 4 5 6 7]
Suma: [3 4 5 6 7]
```
### Resta
```py
numpy_array_from_list = np.array([1, 2, 3, 4, 5])
print('Array original: ', numpy_array_from_list)
print('Resta: ', numpy_array_from_list - 2)
print('Resta: ', np.subtract(numpy_array_from_list, 2))
```
```sh
Array original: [1 2 3 4 5]
Resta: [-1 0 1 2 3]
Resta: [-1 0 1 2 3]
```
### Multiplicación
```py
numpy_array_from_list = np.array([1, 2, 3, 4, 5])
print('Array original: ', numpy_array_from_list)
print('Multiplicación: ', numpy_array_from_list * 2)
print('Multiplicación: ', np.multiply(numpy_array_from_list, 2))
```
```sh
Array original: [1 2 3 4 5]
Multiplicación: [ 2 4 6 8 10]
Multiplicación: [ 2 4 6 8 10]
```
### División
```py
numpy_array_from_list = np.array([1, 2, 3, 4, 5])
print('Array original: ', numpy_array_from_list)
print('División: ', numpy_array_from_list / 2)
print('División: ', np.divide(numpy_array_from_list, 2))
```
```sh
Array original: [1 2 3 4 5]
División: [0.5 1. 1.5 2. 2.5]
División: [0.5 1. 1.5 2. 2.5]
```
### Módulo
```py
numpy_array_from_list = np.array([1, 2, 3, 4, 5])
print('Array original: ', numpy_array_from_list)
print('Módulo: ', numpy_array_from_list % 2)
print('Módulo: ', np.mod(numpy_array_from_list, 2))
```
```sh
Array original: [1 2 3 4 5]
Módulo: [1 0 1 0 1]
Módulo: [1 0 1 0 1]
```
### División entera
```py
numpy_array_from_list = np.array([1, 2, 3, 4, 5])
print('Array original: ', numpy_array_from_list)
print('División entera: ', numpy_array_from_list // 2)
print('División entera: ', np.floor_divide(numpy_array_from_list, 2))
```
```sh
Array original: [1 2 3 4 5]
División entera: [0 1 1 2 2]
División entera: [0 1 1 2 2]
```
### Potencia
```py
numpy_array_from_list = np.array([1, 2, 3, 4, 5])
print('Array original: ', numpy_array_from_list)
print('Potencia: ', numpy_array_from_list ** 2)
print('Potencia: ', np.power(numpy_array_from_list, 2))
```
```sh
Array original: [1 2 3 4 5]
Potencia: [ 1 4 9 16 25]
Potencia: [ 1 4 9 16 25]
```
## Comprobar tipos de datos
```py
numpy_int_arr = np.array([1, 2, 3, 4])
numpy_float_arr = np.array([1.1, 2.0, 3.2])
numpy_bool_arr = np.array([-3, -2, 0, 1, 2, 3], dtype='bool')
print(numpy_int_arr.dtype)
print(numpy_float_arr.dtype)
print(numpy_bool_arr.dtype)
```
```sh
int64
float64
bool
```
## Convertir tipos
Podemos convertir tipos con astype:
```py
numpy_int_arr = np.array([1, 2, 3, 4], dtype='float')
numpy_int_arr.astype('int').dtype
numpy_float_arr = np.array([1.1, 2.0, 3.2])
numpy_float_arr.astype('int').dtype
numpy_int_arr = np.array([-3, -2, 0, 1, 2, 3])
numpy_int_arr.astype('bool').dtype
```
```sh
int64
int64
bool
```
## Arrays multidimensionales
Una de las ventajas de NumPy es el manejo de arrays multidimensionales:
```py
two_dimension_array = np.array([(1,2,3),(4,5,6), (7,8,9)])
print(type(two_dimension_array))
print(two_dimension_array)
print('Forma: ', two_dimension_array.shape)
print('Tamaño: ', two_dimension_array.size)
print('Tipo de datos: ', two_dimension_array.dtype)
```
```sh
[[1 2 3]
[4 5 6]
[7 8 9]]
Forma: (3, 3)
Tamaño: 9
Tipo de datos: int64
```
### Acceder a elementos en arrays NumPy
```py
two_dimension_array = np.array([[1,2,3],[4,5,6], [7,8,9]])
first_row = two_dimension_array[0]
second_row = two_dimension_array[1]
third_row = two_dimension_array[2]
print('Primera fila:', first_row)
print('Segunda fila:', second_row)
print('Tercera fila: ', third_row)
```
```sh
Primera fila: [1 2 3]
Segunda fila: [4 5 6]
Tercera fila: [7 8 9]
```
Obtener columnas:
```py
first_column= two_dimension_array[:,0]
second_column = two_dimension_array[:,1]
third_column = two_dimension_array[:,2]
print('Primera columna:', first_column)
print('Segunda columna:', second_column)
print('Tercera columna: ', third_column)
```
```sh
Primera columna: [1 4 7]
Segunda columna: [2 5 8]
Tercera columna: [3 6 9]
```
## Slicing en arrays NumPy
El slicing es similar al de listas, pero admite dos dimensiones.
```py
numpy_array_from_list = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print('Array original:', numpy_array_from_list)
# primer parámetro: inicio
# segundo parámetro: parada
# tercer parámetro: paso
ten_first_items = numpy_array_from_list[0:10]
print('Primeras 10:', ten_first_items)
first_five_items = numpy_array_from_list[:5]
print('Primeras 5:', first_five_items)
last_five_items = numpy_array_from_list[5:]
print('Últimas 5:', last_five_items)
# índice negativo
last_five_items = numpy_array_from_list[-5:]
print('Últimas 5:', last_five_items)
```
```sh
Array original: [ 1 2 3 4 5 6 7 8 9 10]
Primeras 10: [ 1 2 3 4 5 6 7 8 9 10]
Primeras 5: [1 2 3 4 5]
Últimas 5: [ 6 7 8 9 10]
Últimas 5: [ 6 7 8 9 10]
```
Seleccionar cada segundo elemento:
```py
every_two_item = numpy_array_from_list[::2]
print('Cada dos elementos:', every_two_item)
```
```sh
Cada dos elementos: [1 3 5 7 9]
```
Invertir array:
```py
reversed_array = numpy_array_from_list[::-1]
print('Array invertido:', reversed_array)
```
```sh
Array invertido: [10 9 8 7 6 5 4 3 2 1]
```
Slicing en 2D:
```py
two_dimension_array = np.array([[1,2,3],[4,5,6], [7,8,9]])
print(two_dimension_array)
print(two_dimension_array[1, 1])
print(two_dimension_array[1, 1:3])
print(two_dimension_array[1:3, 1:3])
```
```sh
[[1 2 3]
[4 5 6]
[7 8 9]]
5
[5 6]
[[5 6]
[8 9]]
```
## Concatenación de arrays en NumPy
```py
first_array = np.array([1, 2, 3])
second_array = np.array([4, 5, 6])
third_array = np.array([7, 8, 9])
print('Primer array:', first_array)
print('Segundo array:', second_array)
print('Tercer array:', third_array)
```
```sh
Primer array: [1 2 3]
Segundo array: [4 5 6]
Tercer array: [7 8 9]
```
### Concatenación horizontal
```py
horizontal_concat = np.hstack((first_array, second_array, third_array))
print('Concatenación horizontal:', horizontal_concat)
```
```sh
Concatenación horizontal: [1 2 3 4 5 6 7 8 9]
```
### Concatenación vertical
```py
vertical_concat = np.vstack((first_array, second_array, third_array))
print('Concatenación vertical:', vertical_concat)
```
```sh
Concatenación vertical:
[[1 2 3]
[4 5 6]
[7 8 9]]
```
## Funciones comunes de NumPy
### Mínimo, máximo, media, mediana y percentiles
```py
numpy_array_from_list = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print('Mínimo:', numpy_array_from_list.min())
print('Máximo:', numpy_array_from_list.max())
print('Media:', numpy_array_from_list.mean())
```
🎉 ¡Felicidades! 🎉
[<< Día 23](./23_virtual_environment_sp.md) | [Día 25 >>](./25_pandas_sp.md)
================================================
FILE: Spanish/25_pandas_sp.md
================================================
# 30 días de desafío de programación en Python: Día 25 - Pandas
- [Día 25](#-día-25)
- [Pandas](#pandas)
- [InstalarPandas](#instalarpandas)
- [ImportarPandas](#importarpandas)
- [Crear serie de Pandas con índice por defecto](#crear-serie-de-pandas-con-índice-por-defecto)
- [Crear serie de Pandas con índice personalizado](#crear-serie-de-pandas-con-índice-personalizado)
- [Crear serie de Pandas a partir de un diccionario](#crear-serie-de-pandas-a-partir-de-un-diccionario)
- [Crear serie de Pandas constante](#crear-serie-de-pandas-constante)
- [Crear serie de Pandas con Linspace](#crear-serie-de-pandas-con-linspace)
- [DataFrames](#dataframes)
- [Crear DataFrame a partir de una lista de listas](#crear-dataframe-a-partir-de-una-lista-de-listas)
- [Crear DataFrame a partir de un diccionario](#crear-dataframe-a-partir-de-un-diccionario)
- [Crear DataFrame a partir de una lista de diccionarios](#crear-dataframe-a-partir-de-una-lista-de-diccionarios)
- [Leer archivos CSV con Pandas](#leer-archivos-csv-con-pandas)
- [Exploración de datos](#exploración-de-datos)
- [Modificar DataFrame](#modificar-dataframe)
- [Crear DataFrame](#crear-dataframe)
- [Añadir nueva columna](#añadir-nueva-columna)
- [Modificar valores de una columna](#modificar-valores-de-una-columna)
- [Formatear columnas del DataFrame](#formatear-columnas-del-dataframe)
- [Comprobar tipos de datos de columnas](#comprobar-tipos-de-datos-de-columnas)
- [Indexación booleana](#indexación-booleana)
- [Ejercicios: Día 25](#ejercicios-día-25)
# 📘 Día 25
## Pandas
Pandas es una librería open source, de alto rendimiento y fácil de usar para el manejo y análisis de estructuras de datos en Python.
Pandas aporta estructuras y herramientas para manejar datos tabulares: *Series* y *DataFrames*.
Pandas proporciona utilidades para operaciones de datos como:
- reshape (remodelar)
- merge (fusionar)
- sort (ordenar)
- slice (rebanar)
- aggregate (agregar)
- interpolate (interpolar)
Si usas Anaconda no es necesario instalar pandas.
### InstalarPandas
Para Mac:
```sh
pip install conda
conda install pandas
```
Para Windows:
```sh
pip install conda
pip install pandas
```
Las estructuras de datos de Pandas se basan en *Series* y *DataFrames*.
Una *Serie* es una columna, mientras que un DataFrame es una tabla multidimensional compuesta por un conjunto de *Series*. Para crear una serie de Pandas, debemos usar un array unidimensional de NumPy o una lista de Python.
Veamos un ejemplo de una serie:
Serie de Pandas de nombres

Serie de países

Serie de ciudades

Como puedes ver, una serie de Pandas es simplemente una columna de datos. Si queremos tener varias columnas, usamos un DataFrame. El siguiente ejemplo muestra un DataFrame de Pandas.
Veamos un ejemplo de un DataFrame de Pandas:

Un DataFrame es una colección de filas y columnas. Mira la tabla a continuación; tiene más columnas que el ejemplo anterior:

A continuación, veremos cómo importar Pandas y cómo crear Series y DataFrames con Pandas.
### Importar Pandas
```python
import pandas as pd # importar pandas como pd
import numpy as np # importar numpy como np
```
### Crear serie de Pandas con índice por defecto
```python
nums = [1, 2, 3, 4,5]
s = pd.Series(nums)
print(s)
```
```sh
0 1
1 2
2 3
3 4
4 5
dtype: int64
```
### Crear serie de Pandas con índice personalizado
```python
nums = [1, 2, 3, 4, 5]
s = pd.Series(nums, index=[1, 2, 3, 4, 5])
print(s)
```
```sh
1 1
2 2
3 3
4 4
5 5
dtype: int64
```
```python
fruits = ['Orange','Banana','Mango']
fruits = pd.Series(fruits, index=[1, 2, 3])
print(fruits)
```
```sh
1 Orange
2 Banana
3 Mango
dtype: object
```
### Crear serie de Pandas a partir de un diccionario
```python
dct = {'name':'Asabeneh','country':'Finland','city':'Helsinki'}
```
```python
s = pd.Series(dct)
print(s)
```
```sh
name Asabeneh
country Finland
city Helsinki
dtype: object
```
### Crear serie de Pandas constante
```python
s = pd.Series(10, index = [1, 2, 3])
print(s)
```
```sh
1 10
2 10
3 10
dtype: int64
```
### Crear serie de Pandas con Linspace
```python
s = pd.Series(np.linspace(5, 20, 10)) # linspace(inicio, fin, número_de_elementos)
print(s)
```
```sh
0 5.000000
1 6.666667
2 8.333333
3 10.000000
4 11.666667
5 13.333333
6 15.000000
7 16.666667
8 18.333333
9 20.000000
dtype: float64
```
## DataFrames
Pandas DataFrame se puede crear de diferentes maneras:
- Crear a partir de una lista de listas
- Crear a partir de un diccionario
- Crear a partir de una lista de diccionarios
- Crear a partir de un archivo CSV
### Crear DataFrame a partir de una lista de listas
```python
data = [
['Asabeneh', 'Finland', 'Helsinki'],
['David', 'UK', 'London'],
['John', 'Sweden', 'Stockholm']
]
df = pd.DataFrame(data, columns=['Name', 'Country', 'City'])
print(df)
```
```sh
Name Country City
0 Asabeneh Finland Helsinki
1 David UK London
2 John Sweden Stockholm
```
### Crear DataFrame a partir de un diccionario
```python
data = {'Name': ['Asabeneh', 'David', 'John'], 'Country':[
'Finland', 'UK', 'Sweden'], 'City': ['Helsinki', 'London', 'Stockholm']}
df = pd.DataFrame(data)
print(df)
```
```sh
Name Country City
0 Asabeneh Finland Helsinki
1 David UK London
2 John Sweden Stockholm
```
### Crear DataFrame a partir de una lista de diccionarios
```python
data = [
{'Name': 'Asabeneh', 'Country': 'Finland', 'City': 'Helsinki'},
{'Name': 'David', 'Country': 'UK', 'City': 'London'},
{'Name': 'John', 'Country': 'Sweden', 'City': 'Stockholm'}]
df = pd.DataFrame(data)
print(df)
```
```sh
Name Country City
0 Asabeneh Finland Helsinki
1 David UK London
2 John Sweden Stockholm
```
## Leer archivos CSV con Pandas
Leamos el archivo en el directorio de datos, leeremos el archivo weight-height.csv pasando la ruta del archivo como parámetro a la función pd.read_csv(). Usemos el método head() para ver las primeras cinco filas.
```python
import pandas as pd
df = pd.read_csv('./data/weight-height.csv')
print(df.head()) # por defecto muestra las primeras 5 filas
```
```sh
Gender Height Weight
0 Male 73.847017 241.893563
1 Male 68.781904 162.310473
2 Male 74.110105 212.740856
3 Male 71.730978 220.042470
4 Male 69.881796 206.349801
```
Veamos las últimas cinco filas usando el método tail():
```python
print(df.tail()) # últimas 5 filas
```
```sh
Gender Height Weight
9995 Female 66.172652 136.777454
9996 Female 67.067155 170.867906
9997 Female 63.867992 128.475319
9998 Female 69.034243 163.852461
9999 Female 61.944246 113.649103
```
### Exploración de datos
Obtenemos el número de filas y columnas con la propiedad shape:
```python
print(df.shape) # número de filas y columnas
```
```sh
(10000, 3)
```
Como puedes ver, este conjunto de datos tiene 10000 filas y 3 columnas. Obtengamos más información sobre los datos:
```python
print(df.columns) # nombres de las columnas
print(df.head(10)) # primeras 10 filas
print(df.tail(10)) # últimas 10 filas
print(df['Gender'].value_counts()) # contar cuántos hay de cada uno
print(df.describe()) # resumen estadístico de los datos
```
```sh
Index(['Gender', 'Height', 'Weight'], dtype='object')
Gender Height Weight
0 Male 73.847017 241.893563
1 Male 68.781904 162.310473
2 Male 74.110105 212.740856
3 Male 71.730978 220.042470
4 Male 69.881796 206.349801
5 Male 68.767792 152.212156
6 Male 67.961960 183.927889
7 Male 68.563817 175.929316
8 Male 71.267570 196.028855
9 Male 72.040119 205.801386
Gender Height Weight
9990 Female 64.744846 139.725595
9991 Female 62.109532 132.451630
9992 Female 62.593008 130.727432
9993 Female 62.100222 131.220717
9994 Female 63.421888 133.330246
9995 Female 66.172652 136.777454
9996 Female 67.067155 170.867906
9997 Female 63.867992 128.475319
9998 Female 69.034243 163.852461
9999 Female 61.944246 113.649103
Gender
Male 5000
Female 5000
Name: count, dtype: int64
Height Weight
count 10000.000000 10000.000000
mean 66.367560 161.440357
std 3.847528 32.108439
min 54.263133 64.700127
25% 63.505620 135.818051
50% 66.318070 161.212928
75% 69.174262 187.169525
max 78.998742 269.989699
```
## Modificar DataFrame
### Crear DataFrame
Primero, creemos un DataFrame usando lo que aprendimos anteriormente:
```python
# importar pandas y numpy
import pandas as pd
import numpy as np
# datos
data = [
{"Name": "Juan Pérez", "Country":"China", "City":"Shanghái"},
{"Name": "Luis", "Country":"China", "City":"Pekín"},
{"Name": "Carlos", "Country":"China", "City":"Cantón"}]
# crear DataFrame
df = pd.DataFrame(data)
print(df)
```
```sh
Name Country City
0 Juan Pérez China Shanghái
1 Luis China Pekín
2 Carlos China Cantón
```
### Añadir nueva columna
```python
weights = [74, 78, 69]
df['Weight'] = weights
df
```
```sh
Name Country City Weight
0 Juan Pérez China Shanghái 74
1 Luis China Pekín 78
2 Carlos China Cantón 69
```
```python
heights = [173, 175, 169]
df['Height'] = heights
df
```
```sh
Name Country City Weight Height
0 Juan Pérez China Shanghái 74 173
1 Luis China Pekín 78 175
2 Carlos China Cantón 69 169
```
### Modificar valores de una columna
Podemos modificar una columna de tres maneras:
1. Asignación directa:
```python
df['Name'] = ['Miguel', 'Ana', 'Sofía']
df
```
```sh
Name Country City Weight Height
0 Miguel China Shanghái 74 173
1 Ana China Pekín 78 175
2 Sofía China Cantón 69 169
```
2. Modificando con loc:
```python
df.loc[1, 'Name'] = 'Lucía'
df
```
```sh
Name Country City Weight Height
0 Miguel China Shanghái 74 173
1 Lucía China Pekín 78 175
2 Sofía China Cantón 69 169
```
3. Modificando con iloc:
```python
print('Datos originales:\n', df)
df.iloc[1, 0] = 'Paco'
print('Datos modificados:\n', df)
```
```sh
Datos originales:
Name Country City Weight Height
0 Miguel China Shanghái 74 173
1 Lucía China Pekín 78 175
2 Sofía China Cantón 69 169
Datos modificados:
Name Country City Weight Height
0 Miguel China Shanghái 74 173
1 Paco China Pekín 78 175
2 Sofía China Cantón 69 169
```
### Formatear columnas del DataFrame
```python
# añadir columna BMI: peso(kg) / altura^2(m). Redondear a 2 decimales.
df['BMI'] = np.round(df['Weight'] / ((df['Height'] * 0.01) ** 2), 2)
print(df)
```
```sh
Name Country City Weight Height BMI
0 Miguel China Shanghái 74 173 24.73
1 Paco China Pekín 78 175 25.47
2 Sofía China Cantón 69 169 24.16
```
## Comprobar tipos de datos de columnas
```python
print(df.dtypes)
```
```sh
Name object
Country object
City object
Weight int64
Height int64
BMI float64
dtype: object
```
### Indexación booleana
```python
# crear DataFrame
df = pd.DataFrame({
'name': ['Juan', 'Luis', 'Carlos', 'Pedro'],
'country': ['China', 'Estados Unidos', 'Reino Unido', 'España'],
'age': [25, 15, 22, 28],
'empleado': [True, False, True, False]
})
print(df)
```
```sh
name country age empleado
0 Juan China 25 True
1 Luis Estados Unidos 15 False
2 Carlos Reino Unido 22 True
3 Pedro España 28 False
```
Filtrando edad > 20 y empleado == True:
```python
print(df[(df['age'] > 20) & (df['empleado'] == True)])
```
```sh
name country age empleado
0 Juan China 25 True
2 Carlos Reino Unido 22 True
```
## Ejercicios: Día 25
1. Lee el archivo [hacker_news.csv](../data/hacker_news.csv) y muestra las primeras cinco filas.
2. Obtén la columna de títulos.
3. Obtén el número de filas y columnas.
4. Obtén las primeras diez y las últimas diez filas.
5. Obtén la segunda y cuarta fila, columnas 2 a 4.
6. Filtra las filas cuyo tema sea Python.
7. Cuenta cuántas filas tienen tema Python.
8. Filtra las filas con votos mayores a 200.
9. Ordena el DataFrame por votos (ascendente).
10. Ordena el DataFrame por votos (descendente).
11. Excluye las filas con tema Python y ordena por votos.
🎉 ¡Felicidades! 🎉
[<< Día 24](./24_statistics_sp.md) | [Día 26 >>](./26_python_web_sp.md)
================================================
FILE: Spanish/26_python_web_sp.md
================================================
# 30 días de desafío de programación en Python: Día 26 - Programación web con Python
- [Día 26](#-día-26)
- [Programación web con Python](#programación-web-con-python)
- [Flask](#flask)
- [Estructura de carpetas](#estructura-de-carpetas)
- [Configurar el proyecto](#configurar-el-proyecto)
- [Crear rutas](#crear-rutas)
- [Crear plantillas](#crear-plantillas)
- [Script de Python](#script-de-python)
- [Navegación](#navegación)
- [Crear plantilla base](#crear-plantilla-base)
- [Servir archivos estáticos](#servir-archivos-estáticos)
- [Despliegue](#despliegue)
- [Crear cuenta en Heroku](#crear-cuenta-en-heroku)
- [Iniciar sesión en Heroku](#iniciar-sesión-en-heroku)
- [Crear requirements y Procfile](#crear-requirements-y-procfile)
- [Enviar el proyecto a Heroku](#enviar-el-proyecto-a-heroku)
- [Ejercicios: Día 26](#ejercicios-día-26)
# 📘 Día 26
## Programación web con Python
Python es un lenguaje de programación versátil que se puede utilizar para una variedad de propósitos. En esta sección, veremos cómo usar Python para el desarrollo web. Python tiene muchos marcos web disponibles. Django y Flask son los más populares. Hoy, aprenderemos a usar Flask para el desarrollo web.
### Flask
Flask es un marco de desarrollo web escrito en Python. Flask utiliza el motor de plantillas Jinja2. Flask también se puede usar con otras bibliotecas modernas de frontend como React.
Si aún no has instalado el paquete virtualenv, instálalo primero. Un entorno virtual permitirá aislar las dependencias del proyecto de las dependencias de la máquina local.
#### Estructura de carpetas
Después de completar todos los pasos, la estructura de archivos de tu proyecto debería ser la siguiente:
```sh
├── Procfile
├── app.py
├── env
│ ├── bin
├── requirements.txt
├── static
│ └── css
│ └── main.css
└── templates
├── about.html
├── home.html
├── layout.html
├── post.html
└── result.html
```
### Configurar el proyecto
Comienza a usar Flask siguiendo estos pasos.
Paso 1: Instala virtualenv con el siguiente comando.
```sh
pip install virtualenv
```
Paso 2:
```sh
asabeneh@Asabeneh:~/Desktop$ mkdir python_for_web
asabeneh@Asabeneh:~/Desktop$ cd python_for_web/
asabeneh@Asabeneh:~/Desktop/python_for_web$ virtualenv venv
asabeneh@Asabeneh:~/Desktop/python_for_web$ source venv/bin/activate
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip freeze
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip install Flask
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip freeze
Click==7.0
Flask==1.1.1
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
Werkzeug==0.16.0
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$
```
Hemos creado un directorio de proyecto llamado python_for_web. Dentro del proyecto, hemos creado un entorno virtual llamado *venv*, que puede tener cualquier nombre. Luego, activamos el entorno virtual. Usamos pip freeze para verificar los paquetes instalados en el directorio del proyecto. El resultado de pip freeze está vacío porque aún no se han instalado paquetes.
Ahora, creemos el archivo app.py en el directorio del proyecto y escribamos el siguiente código. El archivo app.py será el archivo principal del proyecto. El siguiente código contiene el módulo flask y el módulo os.
### Crear rutas
Ruta de inicio.
```py
# importar flask
from flask import Flask
import os # importar el módulo del sistema operativo
app = Flask(__name__)
@app.route('/') # este decorador crea la ruta de inicio
def home ():
return '
Bienvenido
'
@app.route('/about')
def about():
return '
Acerca de nosotros
'
if __name__ == '__main__':
# usamos variables de entorno para despliegue
# funciona tanto para producción como para desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
Para ejecutar la aplicación flask, ingresa python app.py en el directorio principal de la aplicación flask.
Después de ejecutar _python app.py_, verifica el puerto 5000 de tu localhost.
Agreguemos una ruta adicional creando la ruta "acerca de".
```py
# importar flask
from flask import Flask
import os # importar el módulo del sistema operativo
app = Flask(__name__)
@app.route('/') # este decorador crea la ruta de inicio
def home ():
return '
Bienvenido
'
@app.route('/about')
def about():
return '
Acerca de nosotros
'
if __name__ == '__main__':
# usamos variables de entorno para despliegue
# funciona tanto para producción como para desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
Ahora, hemos agregado la ruta acerca de en el código anterior. ¿Pero qué pasa si queremos renderizar un archivo HTML en lugar de una cadena? Podemos renderizar un archivo HTML usando la función *render_template*. Creamos una carpeta llamada templates en el directorio del proyecto y dentro de ella, creamos home.html y about.html. También importamos *render_template* desde flask.
### Crear plantillas
Crea archivos HTML dentro de la carpeta templates.
home.html
```html
Página principal
Bienvenido de vuelta
```
about.html
```html
Acerca
Acerca de nosotros
```
### Script de Python (con render_template)
app.py
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo del sistema operativo
app = Flask(__name__)
@app.route('/') # este decorador crea la ruta de inicio
def home ():
return render_template('home.html')
@app.route('/about')
def about():
return render_template('about.html')
if __name__ == '__main__':
# usamos variables de entorno para despliegue
# funciona tanto para producción como para desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
Como puedes ver, para acceder a diferentes páginas o navegar, necesitamos un sistema de navegación. Agreguemos un enlace para cada página, o creemos un diseño que usemos para cada página.
### Navegación
```html
```
Ahora, podemos navegar entre páginas usando los enlaces anteriores. Creamos una página adicional para manejar los datos del formulario. Puedes nombrarla como quieras, yo prefiero llamarla post.html.
Podemos inyectar datos en el archivo HTML usando el motor de plantillas Jinja2.
```py
# importar flask
from flask import Flask, render_template, request, redirect, url_for
import os # importar el módulo del sistema operativo
app = Flask(__name__)
@app.route('/') # este decorador crea la ruta de inicio
def home ():
techs = ['HTML', 'CSS', 'Flask', 'Python']
name = '30 días de desafío de programación en Python'
return render_template('home.html', techs=techs, name=name, title='Página principal')
@app.route('/about')
def about():
name = '30 días de desafío de programación en Python'
return render_template('about.html', name=name, title='Acerca de nosotros')
@app.route('/post')
def post():
name = 'Artículos sobre programación'
path = request.path
return render_template('post.html', name=name, path=path, title='Artículos')
if __name__ == '__main__':
# usamos variables de entorno para despliegue
# funciona tanto para producción como para desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
home.html
```html
{{title}}
```
Ahora, agreguemos una ruta que procese los datos del formulario. Usamos el método POST porque recibiremos datos del formulario.
```py
# importar flask
from flask import Flask, render_template, request, redirect, url_for
import os # importar el módulo del sistema operativo
app = Flask(__name__)
@app.route('/') # este decorador crea la ruta de inicio
def home():
techs = ['HTML', 'CSS', 'Flask', 'Python']
name = '30 días de desafío de programación en Python'
return render_template('home.html', techs=techs, name=name, title='Página principal')
@app.route('/about')
def about():
name = '30 días de desafío de programación en Python'
return render_template('about.html', name=name, title='Acerca de nosotros')
@app.route('/post')
def post():
name = 'Artículos'
return render_template('post.html', name=name, title='Artículos')
@app.route('/result', methods=['POST'])
def result():
first_name = request.form['first_name']
last_name = request.form['last_name']
old_job = request.form['old_job']
current_job = request.form['current_job']
country = request.form['country']
print(first_name, last_name, old_job, current_job, country)
result_data = {
'first_name':first_name,
'last_name':last_name,
'old_job': old_job,
'current_job': current_job,
'country':country
}
return render_template('result.html', result_data = result_data, title= 'Resultado')
if __name__ == '__main__':
# usamos variables de entorno para despliegue
# funciona tanto para producción como para desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
result.html
```html
{{title}}
```
En el mundo real, no repetiríamos el código HTML en todas las páginas. En su lugar, crearíamos una plantilla base y las demás heredarían de ella. Usemos la herencia (plantillas). Ahora, en lugar de tres archivos diferentes, necesitamos crear un archivo de diseño llamado layout.html. Luego, otros archivos heredarán de él.
### Crear plantilla base (layout)
layout.html
```html
{% if title %}
30 Días de Python - {{ title}}
{% else %}
30 Días de Python
{% endif %}
{% block content %} {% endblock %}
```
En el diseño anterior, hemos creado una plantilla común que puede ser utilizada por todas las páginas que heredan de ella. Dentro del diseño, podemos ver los enlaces de navegación. Usamos las etiquetas {% block content %}{% endblock %} para permitir que las subplantillas agreguen contenido.
home.html
```html
{% extends 'layout.html' %} {% block content %}
Bienvenido de vuelta a {{name}}
Este proyecto fue construido usando las siguientes tecnologías:
Flask, Python
y HTML, CSS
Este desafío es un desafío de programación de 30 días diseñado para ayudarte a aprender el lenguaje de programación Python, resolviendo un problema de Python cada día.
{% endblock %}
```
#### Servir archivos estáticos
A continuación se muestra el archivo main.css, que colocaremos en el directorio static/css:
```css
/* === GENERAL === */
body {
margin: 0;
padding: 0;
font-family: "Lato", sans-serif;
background-color: #f0f8ea;
}
.container {
max-width: 80%;
margin: auto;
padding: 30px;
}
ul {
list-style-type: none;
padding: 0;
}
.tech {
color: #5bbc2e;
}
/* === HEADER === */
header {
background-color: #5bbc2e;
}
.menu-container {
display: flex;
justify-content: space-between;
padding: 20px 30px;
}
.brand-name {
color: white;
font-weight: 800;
font-size: 24px;
}
.nav-lists {
display: flex;
}
.nav-list {
margin-right: 15px;
}
.nav-link {
text-decoration: none;
color: white;
font-weight: 300;
}
/* === FORM === */
form {
margin: 30px 0;
border: 1px solid #ddd;
padding: 30px;
border-radius: 10px;
}
form > div {
margin-bottom: 15px;
}
input {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
outline: 0;
font-size: 16px;
box-sizing: border-box;
margin-top: 5px;
}
button {
padding: 12px 24px;
border: 0;
background-color: #5bbc2e;
color: white;
border-radius: 10px;
font-size: 16px;
outline: 0;
cursor: pointer;
}
button:hover {
background-color: #4b9c25;
}
```
### Despliegue
#### Crear cuenta en Heroku
Heroku ofrece un servicio de alojamiento gratuito. Si deseas desplegar una aplicación, debes tener una cuenta en Heroku.
#### Iniciar sesión en Heroku
```sh
asabeneh@Asabeneh:~/Desktop/python_for_web$ heroku login
heroku: Press any key to open up the browser to login or q to exit:
Opening browser to https://cli-auth.heroku.com/auth/cli/browser/ec0972d5-d8c6-4adf-b004-a42a22dd09a8
Logging in... done
Logged in as asabeneh@gmail.com
asabeneh@Asabeneh:~/Desktop/python_for_web$
```
#### Crear requirements y Procfile
Antes de desplegar la aplicación, necesitamos informar a Heroku qué dependencias instalar y cómo ejecutar la aplicación. Heroku utiliza el archivo requirements.txt para obtener información sobre las dependencias de la aplicación. Usa el comando pip freeze para listar todas las dependencias y sus versiones, y escríbelas en requirements.txt.
```sh
asabeneh@Asabeneh:~/Desktop/python_for_web$ pip freeze
Click==7.0
Flask==1.1.1
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
Werkzeug==0.16.0
asabeneh@Asabeneh:~/Desktop/python_for_web$ pip freeze > requirements.txt
```
Procfile le dice a Heroku cómo ejecutar la aplicación. En este caso, usamos Gunicorn como servidor HTTP WSGI para ejecutar aplicaciones web en Python. Necesitamos agregar Gunicorn a nuestras dependencias.
```sh
asabeneh@Asabeneh:~/Desktop/python_for_web$ pip install gunicorn
asabeneh@Asabeneh:~/Desktop/python_for_web$ pip freeze > requirements.txt
```
Ahora, creemos un Procfile y agreguemos el siguiente contenido:
```sh
web: gunicorn app:app
```
#### Enviar el proyecto a Heroku
```sh
asabeneh@Asabeneh:~/Desktop/python_for_web$ heroku create 30-days-of-python-app
Creating ⬢ 30-days-of-python-app... done
https://30-days-of-python-app.herokuapp.com/ | https://git.heroku.com/30-days-of-python-app.git
asabeneh@Asabeneh:~/Desktop/python_for_web$ git init
Initialized empty Git repository in /home/asabeneh/Desktop/python_for_web/.git/
asabeneh@Asabeneh:~/Desktop/python_for_web$ heroku git:remote -a 30-days-of-python-app
set git remote heroku to https://git.heroku.com/30-days-of-python-app.git
asabeneh@Asabeneh:~/Desktop/python_for_web$ echo -e "venv\n.vscode" > .gitignore
asabeneh@Asabeneh:~/Desktop/python_for_web$ git add .
asabeneh@Asabeneh:~/Desktop/python_for_web$ git commit -m "primer aplicación web en python"
[master (root-commit) 9dfcc6a] primer aplicación web en python
9 files changed, 403 insertions(+)
create mode 100644 .gitignore
create mode 100644 Procfile
create mode 100644 app.py
create mode 100644 requirements.txt
create mode 100644 static/css/main.css
create mode 100644 templates/about.html
create mode 100644 templates/home.html
create mode 100644 templates/layout.html
create mode 100644 templates/post.html
create mode 100644 templates/result.html
asabeneh@Asabeneh:~/Desktop/python_for_web$ git push heroku master
Enumerating objects: 14, done.
Counting objects: 100% (14/14), done.
Delta compression using up to 2 threads
Compressing objects: 100% (12/12), done.
Writing objects: 100% (14/14), 6.08 KiB | 1.52 MiB/s, done.
Total 14 (delta 2), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Python app detected
remote: -----> Installing python-3.6.10
remote: -----> Installing pip
remote: -----> Installing dependencies with Pipenv 2018.5.18…
remote: Installing dependencies from Pipfile.lock (872ae5)…
remote: -----> Installing SQLite3
remote: -----> $ python manage.py collectstatic --noinput
remote: Traceback (most recent call last):
remote: File "manage.py", line 10, in
remote: from app import app
remote: ModuleNotFoundError: No module named 'app'
remote:
remote: ! Error while running '$ python manage.py collectstatic --noinput'.
remote: See traceback above for details.
remote:
remote: You may need to update application code to resolve this error.
remote: Or, you can disable collectstatic for this application:
remote:
remote: $ heroku config:set DISABLE_COLLECTSTATIC=1
remote:
remote: https://devcenter.heroku.com/articles/django-assets
remote: -----> Discovering process types
remote: Procfile declares types -> web
remote:
remote: -----> Compressing...
remote: Done: 55.7M
remote: -----> Launching...
remote: Released v3
remote: https://30-days-of-python-app.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/30-days-of-python-app.git
* [new branch] master -> master
asabeneh@Asabeneh:~/Desktop/python_for_web$
```
Como puedes ver, hemos creado con éxito nuestra primera aplicación web, la hemos desplegado y la hemos alojado en Heroku. Puedes probar esta aplicación usando este [enlace](https://30-days-of-python-app.herokuapp.com/).
Sin más preámbulos, realicemos algunos ejercicios para reforzar lo aprendido.
## Ejercicios: Día 26
1. Crea una aplicación Flask llamada "Calculadora de calificaciones". El usuario ingresa la nota y el nombre de la asignatura, y la aplicación debe mostrar un mensaje según la nota:
- Si nota ≥ 90: "¡Excelente! Tu calificación en [Asignatura] es [Nota]".
- Si 80 ≤ nota < 90: "¡Muy bien! Tu calificación en [Asignatura] es [Nota]".
- Si 70 ≤ nota < 80: "Regular. Tu calificación en [Asignatura] es [Nota]".
- Si 60 ≤ nota < 70: "Aprobaste. Tu calificación en [Asignatura] es [Nota]".
- Si nota < 60: "¡Necesitas esforzarte más! Tu calificación en [Asignatura] es [Nota]".
2. Crea una aplicación "Calculadora de IMC" que calcule el índice de masa corporal (IMC = peso(kg) / altura(m)²) y muestre el estado según el IMC:
- IMC < 18.5: "Bajo peso"
- 18.5 ≤ IMC < 24.9: "Peso saludable"
- 25 ≤ IMC < 29.9: "Sobrepeso"
- IMC ≥ 30: "Obesidad"
3. Crea una aplicación de blog donde los usuarios puedan añadir, editar y eliminar publicaciones.
4. Crea una aplicación "Gestor de tareas" donde los usuarios puedan añadir, ver y eliminar tareas.
🎉 ¡Felicidades! 🎉
[<< Día 25](./25_pandas_sp.md) | [>> Día 27](./27_python_with_mongodb_sp.md)
================================================
FILE: Spanish/27_python_with_mongodb_sp.md
================================================
# Reto de 30 días de Python: Día 27 - Python y MongoDB
- [Día 27](#-día-27)
- [Python y MongoDB](#python-y-mongodb)
- [MongoDB](#mongodb)
- [Comparación entre SQL y NoSQL](#comparación-entre-sql-y-nosql)
- [Obtener la cadena de conexión (URI de MongoDB)](#obtener-la-cadena-de-conexión-uri-de-mongodb)
- [Conectar una aplicación Flask a un clúster de MongoDB](#conectar-una-aplicación-flask-a-un-clúster-de-mongodb)
- [Crear base de datos y colecciones](#crear-base-de-datos-y-colecciones)
- [Insertar múltiples documentos en una colección](#insertar-múltiples-documentos-en-una-colección)
- [Consultas en MongoDB](#consultas-en-mongodb)
- [Buscar usando una consulta](#buscar-usando-una-consulta)
- [Buscar con modificadores](#buscar-con-modificadores)
- [Limitar la cantidad de documentos](#limitar-la-cantidad-de-documentos)
- [Buscar con ordenamiento](#buscar-con-ordenamiento)
- [Actualizar usando una consulta](#actualizar-usando-una-consulta)
- [Eliminar documentos](#eliminar-documentos)
- [Eliminar una colección](#eliminar-una-colección)
- [💻 Ejercicio: Día 27](#-ejercicio-día-27)
# 📘 Día 27
# Python y MongoDB
Python es una tecnología backend que puede conectarse a distintas bases de datos. Puede conectarse a bases de datos SQL y NoSQL. En esta sección conectaremos Python con la base de datos MongoDB, que es una base de datos NoSQL.
## MongoDB
MongoDB es una base de datos NoSQL. MongoDB almacena datos en documentos tipo JSON, lo que hace a MongoDB muy flexible y escalable. Veamos la terminología que difiere entre bases de datos SQL y NoSQL. La siguiente tabla mostrará la diferencia entre SQL y NoSQL.
### Comparación entre SQL y NoSQL

En esta sección nos centraremos en la base de datos NoSQL MongoDB. Regístrate en [MongoDB](https://www.mongodb.com/) haciendo clic en registrarse y luego en la página siguiente confirma el registro.

Rellena el formulario y haz clic en continuar..

Elige el plan gratuito

Elige la región gratuita más cercana y ponle un nombre a tu clúster.

Ahora se ha creado un sandbox gratuito

Permitir el acceso desde todos los hosts locales

Agregar usuario y contraseña

Crear enlace URI de MongoDB

Selecciona el driver para Python 3.6 o superior

### Obtener la cadena de conexión (URI de MongoDB)
Copia la cadena de conexión; obtendrás algo similar a esto:
```sh
mongodb+srv://asabeneh:@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority
```
No te preocupes por esta URL; es la forma de conectar tu aplicación con MongoDB.
Reemplaza el marcador de contraseña con la contraseña que creaste al añadir el usuario.
Ejemplo:
```sh
mongodb+srv://asabeneh:123123123@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority
```
En este ejemplo reemplacé todo y la contraseña es 123123123; el nombre de la base de datos es *thirty_days_python*. Esto solo es un ejemplo; tu contraseña debe ser más segura.
Python necesita drivers para acceder a MongoDB. Usaremos _pymongo_ y _dnspython_ para conectar nuestra aplicación con la base de MongoDB. Instala pymongo y dnspython en tu directorio de proyecto:
```sh
pip install pymongo dnspython
```
Para usar el URI mongodb+srv:// debes instalar el módulo "dnspython". dnspython es un paquete de utilidades DNS para Python que soporta prácticamente todos los tipos de registros.
### Conectar una aplicación Flask a un clúster de MongoDB
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo os
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
print(client.list_database_names())
app = Flask(__name__)
if __name__ == '__main__':
# en despliegue usamos variables de entorno
# para que funcione tanto en producción como en desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
Al ejecutar el código anterior obtendremos las bases de datos por defecto de MongoDB.
```sh
['admin', 'local']
```
### Crear base de datos y colecciones
Creemos una base de datos; si la base de datos y la colección no existen en MongoDB, se crearán. Crearemos una base de datos llamada *thirty_days_of_python* y una colección *students*.
Formas de crear la base de datos:
```sh
db = client.name_of_database # podemos crear la base de datos así, o usar la segunda forma
db = client['name_of_database']
```
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo os
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
# crear la base de datos
db = client.thirty_days_of_python
# crear la colección students e insertar un documento
db.students.insert_one({'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250})
print(client.list_database_names())
app = Flask(__name__)
if __name__ == '__main__':
# en despliegue usamos variables de entorno
# para que funcione tanto en producción como en desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
Después de crear la base de datos, también creamos la colección students y usamos *insert_one()* para insertar un documento.
Ahora la base de datos *thirty_days_of_python* y la colección *students* han sido creadas y el documento insertado.
Revisa tu clúster MongoDB y verás la base de datos y la colección, con un documento dentro.
```sh
['thirty_days_of_python', 'admin', 'local']
```
Si ves lo anterior en tu clúster, significa que has creado con éxito una base de datos y una colección.

Si ves la imagen anterior, el documento fue creado con un ID largo como clave primaria. Cada vez que incrustamos un documento, MongoDB le asigna un ID único.
### Insertar múltiples documentos en una colección
*insert_one()* inserta un elemento a la vez; si queremos insertar múltiples documentos de una vez podemos usar *insert_many()* o un bucle for.
Podemos usar un bucle for para insertar varios documentos a la vez.
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo os
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
students = [
{'name':'David','country':'UK','city':'London','age':34},
{'name':'John','country':'Sweden','city':'Stockholm','age':28},
{'name':'Sami','country':'Finland','city':'Helsinki','age':25},
]
for student in students:
db.students.insert_one(student)
app = Flask(__name__)
if __name__ == '__main__':
# en despliegue usamos variables de entorno
# para que funcione tanto en producción como en desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
### Consultas en MongoDB
Los métodos *find()* y *findOne()* son formas comunes de buscar datos en una colección MongoDB. Son similares al SELECT en MySQL.
Usemos _find_one()_ para obtener un documento de la colección.
- *find_one({"_id": ObjectId("id")}): si no se proporciona id, devuelve la primera aparición.
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo os
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
student = db.students.find_one()
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# en despliegue usamos variables de entorno
# para que funcione tanto en producción como en desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
```
La consulta anterior devuelve la primera entrada, pero podemos usar un _id_ específico para ubicar un documento concreto. Por ejemplo, usemos el id de David para obtener el objeto David.
'_id':ObjectId('5df68a23f106fe2d315bbc8c')
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo os
from bson.objectid import ObjectId # objeto id
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
student = db.students.find_one({'_id':ObjectId('5df68a23f106fe2d315bbc8c')})
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# en despliegue usamos variables de entorno
# para que funcione tanto en producción como en desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
```
Hemos visto cómo usar _find_one()_. Veamos ahora _find()_.
- _find()_: si no pasamos un objeto consulta devuelve todas las apariciones en la colección. El resultado es un objeto pymongo.cursor.
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo os
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
students = db.students.find()
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# en despliegue usamos variables de entorno
# para que funcione tanto en producción como en desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
```
Podemos especificar los campos a devolver pasando un segundo objeto a _find({}, {})_. 0 significa excluir, 1 incluir; no se puede mezclar 0 y 1 excepto para _id.
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo os
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
students = db.students.find({}, {"_id":0, "name": 1, "country":1}) # 0 excluir, 1 incluir
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# en despliegue usamos variables de entorno
# para que funcione tanto en producción como en desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'name': 'Asabeneh', 'country': 'Finland'}
{'name': 'David', 'country': 'UK'}
{'name': 'John', 'country': 'Sweden'}
{'name': 'Sami', 'country': 'Finland'}
```
### Buscar usando una consulta
En MongoDB, find acepta un objeto de consulta. Podemos pasar ese objeto para filtrar los documentos que queremos.
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo os
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
query = {
"country":"Finland"
}
students = db.students.find(query)
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# en despliegue usamos variables de entorno
# para que funcione tanto en producción como en desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
```
### Buscar con modificadores
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo os
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
query = {
"city":"Helsinki"
}
students = db.students.find(query)
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# en despliegue usamos variables de entorno
# para que funcione tanto en producción como en desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
```
### Buscar con modificadores (combinados)
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo os
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
query = {
"country":"Finland",
"city":"Helsinki"
}
students = db.students.find(query)
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# en despliegue usamos variables de entorno
# para que funcione tanto en producción como en desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
```
Ejemplos con operadores:
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo os
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
query = {"age":{"$gt":30}}
students = db.students.find(query)
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# en despliegue usamos variables de entorno
# para que funcione tanto en producción como en desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
```
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo os
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
query = {"age":{"$lt":30}}
students = db.students.find(query)
for student in students:
print(student)
```
```sh
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
```
### Limitar la cantidad de documentos
Podemos usar el método _limit()_ para restringir el número de documentos devueltos.
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo os
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
db.students.find().limit(3)
```
### Buscar con ordenamiento
Por defecto el orden es ascendente. Podemos cambiar a descendente pasando -1.
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo os
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
students = db.students.find().sort('name')
for student in students:
print(student)
students = db.students.find().sort('name',-1)
for student in students:
print(student)
students = db.students.find().sort('age')
for student in students:
print(student)
students = db.students.find().sort('age',-1)
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# en despliegue usamos variables de entorno
# para que funcione tanto en producción como en desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
Ascendente
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
```
Descendente
```sh
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
```
### Actualizar usando una consulta
Usaremos *update_one()* para actualizar un documento. Acepta dos objetos: la consulta y el nuevo valor.
La primera persona, Asabeneh, tenía una edad poco razonable. Actualicemos la edad de Asabeneh.
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo os
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
query = {'age':250}
new_value = {'$set':{'age':38}}
db.students.update_one(query, new_value)
# verifiquemos el resultado para ver si la edad fue modificada
for student in db.students.find():
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# en despliegue usamos variables de entorno
# para que funcione tanto en producción como en desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 38}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
```
Si queremos actualizar varios documentos a la vez usamos *update_many()*.
### Eliminar documentos
El método *delete_one()* elimina un documento. Acepta un objeto consulta y elimina la primera aparición.
Eliminemos a John de la colección.
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo os
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
query = {'name':'John'}
db.students.delete_one(query)
for student in db.students.find():
print(student)
# verifiquemos el resultado
app = Flask(__name__)
if __name__ == '__main__':
# en despliegue usamos variables de entorno
# para que funcione tanto en producción como en desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
```sh
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 38}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
```
Como puedes ver, John ha sido eliminado de la colección.
Si queremos eliminar varios documentos usamos *delete_many()* con un objeto consulta. Si pasamos un objeto vacío *delete_many({})* eliminará todos los documentos en la colección.
### Eliminar una colección
Usando el método _drop()_ podemos eliminar una colección de la base de datos.
```py
# importar flask
from flask import Flask, render_template
import os # importar el módulo os
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
db.students.drop()
```
Ahora hemos eliminado la colección students de la base de datos.
## 💻 Ejercicio: Día 27
🎉 ¡Felicidades! 🎉
[<< Día 26](./26_python_web_sp.md) | [Día 28 >>](./28_API_sp.md)
================================================
FILE: Spanish/28_API_sp.md
================================================
# Reto de 30 días de Python: Día 28 - API
- [Día 28](#-día-28)
- [Interfaz de Programación de Aplicaciones (API)](#interfaz-de-programación-de-aplicaciones-api)
- [API](#api)
- [Construir una API](#construir-una-api)
- [HTTP (Protocolo de transferencia de hipertexto)](#http-protocolo-de-transferencia-de-hipertexto)
- [Estructura de HTTP](#estructura-de-http)
- [Línea inicial de solicitud (línea de estado)](#línea-inicial-de-solicitud-línea-de-estado)
- [Línea inicial de respuesta (línea de estado)](#línea-inicial-de-respuesta-línea-de-estado)
- [Campos de cabecera](#campos-de-cabecera)
- [Cuerpo del mensaje](#cuerpo-del-mensaje)
- [Métodos de solicitud](#métodos-de-solicitud)
- [💻 Ejercicio: Día 28](#-ejercicio-día-28)
# 📘 Día 28
# Interfaz de Programación de Aplicaciones (API)
## API
API son las siglas de Application Programming Interface (Interfaz de Programación de Aplicaciones). El tipo de API que veremos en esta sección es la Web API.
Una Web API es una interfaz definida que permite la interacción entre organizaciones y las aplicaciones que consumen sus recursos; también actúa como un contrato de nivel de servicio (SLA) que especifica al proveedor de la funcionalidad y expone rutas o URLs de servicio a los usuarios de la API.
En el contexto del desarrollo web, una API se define como un conjunto de especificaciones, por ejemplo mensajes de solicitud HTTP y la estructura de los mensajes de respuesta, normalmente en formato XML o JSON (JavaScript Object Notation).
Las Web APIs han evolucionado de servicios web basados en SOAP y arquitecturas orientadas a servicios (SOA) hacia recursos web más directos en estilo REST.
Los servicios de redes sociales y las Web APIs han permitido a la comunidad web compartir contenido y datos entre comunidades y plataformas.
Con las APIs, el contenido creado en un lugar puede publicarse y actualizarse dinámicamente en múltiples lugares de la web.
Por ejemplo, la REST API de Twitter permite a los desarrolladores acceder a los datos principales de Twitter, mientras que la Search API ofrece formas de interactuar con los datos de búsqueda y tendencias de Twitter.
Muchas aplicaciones exponen endpoints de API. Algunos ejemplos de APIs son la [API de países](https://restcountries.eu/rest/v2/all) y la [API de razas de gatos](https://api.thecatapi.com/v1/breeds).
En esta sección presentaremos una API RESTful que utiliza métodos de solicitud HTTP como GET, PUT, POST y DELETE para manejar datos.
## Construir una API
Una API RESTful es una interfaz que usa solicitudes HTTP para GET, PUT, POST y DELETE datos. En secciones anteriores aprendimos Python, Flask y MongoDB. Aprovecharemos ese conocimiento para desarrollar una API RESTful usando Python, Flask y la base de datos MongoDB. Toda aplicación con operaciones CRUD (Crear, Leer, Actualizar, Eliminar) suele exponer una API para crear datos en la base, obtener datos, actualizarlos o borrarlos.
Para construir una API es útil entender el protocolo HTTP y el ciclo de solicitud-respuesta HTTP.
## HTTP (Protocolo de transferencia de hipertexto)
HTTP es el protocolo de comunicación establecido entre cliente y servidor. En este caso, el cliente es el navegador y el servidor es el lugar desde donde obtienes los datos. HTTP es un protocolo de red utilizado para transferir recursos en la web, como archivos HTML, imágenes, resultados de consultas, scripts u otros tipos de archivos.
El navegador actúa como cliente HTTP porque envía solicitudes al servidor HTTP (servidor web), y el servidor responde al cliente.
## Estructura de HTTP
HTTP utiliza un modelo cliente-servidor. El cliente HTTP abre una conexión y envía un mensaje de solicitud al servidor HTTP; el servidor HTTP devuelve un mensaje de respuesta, es decir, el recurso solicitado. Cuando el ciclo solicitud-respuesta termina, el servidor cierra la conexión.

Los formatos de los mensajes de solicitud y respuesta son similares. Ambos mensajes contienen:
- Una línea inicial
- Cero o más líneas de cabecera
- Una línea en blanco (es decir, un CRLF por separado)
- Un cuerpo de mensaje opcional (por ejemplo, un archivo, datos de formulario o la salida de una consulta)
Navega por este sitio para ver un ejemplo de mensaje de solicitud y respuesta: https://thirtydaysofpython-v1-final.herokuapp.com/. Este sitio está desplegado en un dyno gratuito de Heroku y puede no estar disponible en algunos meses debido al alto tráfico. Apoyar este proyecto ayuda a mantener el servidor activo.

## Línea inicial de solicitud (línea de estado)
La línea inicial de la solicitud difiere de la de la respuesta.
La línea de solicitud tiene tres partes separadas por espacios:
- El nombre del método (GET, POST, HEAD)
- La ruta del recurso solicitado
- La versión HTTP utilizada. Por ejemplo: GET / HTTP/1.1
GET es el método HTTP más común, usado para obtener o leer recursos, mientras que POST es un método común para crear recursos.
### Línea inicial de respuesta (línea de estado)
La línea inicial de la respuesta, llamada línea de estado, también tiene tres partes separadas por espacios:
- La versión HTTP
- El código de estado de la respuesta, que indica el resultado de la solicitud, junto con una razón que describe dicho código. Ejemplos de líneas de estado:
HTTP/1.0 200 OK
o
HTTP/1.0 404 Not Found
**Nota:**
Los códigos de estado más comunes son:
200 OK: la solicitud fue exitosa y el recurso generado (por ejemplo un archivo o la salida de un script) se devuelve en el cuerpo del mensaje.
500 Error del servidor
La lista completa de códigos de estado HTTP puede encontrarse [aquí](https://httpstatuses.com/). También puedes verla [aquí](https://httpstatusdogs.com/).
### Campos de cabecera
Como se observa en la captura anterior, las líneas de cabecera proporcionan información sobre la solicitud o la respuesta, o sobre el objeto enviado en el cuerpo del mensaje.
```sh
GET / HTTP/1.1
Host: thirtydaysofpython-v1-final.herokuapp.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36
Sec-Fetch-User: ?1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Referer: https://thirtydaysofpython-v1-final.herokuapp.com/post
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9,fi-FI;q=0.8,fi;q=0.7,en-CA;q=0.6,en-US;q=0.5,fr;q=0.4
```
### Cuerpo del mensaje
Un mensaje HTTP puede llevar un cuerpo después de las cabeceras. En una respuesta, este es el lugar donde el recurso solicitado se devuelve al cliente (el uso más común del cuerpo). Si hay un error, puede contener texto explicativo. En una solicitud, es el lugar donde se envían los datos introducidos por el usuario o los archivos subidos al servidor.
Si un mensaje HTTP contiene un cuerpo, normalmente hay cabeceras que describen ese cuerpo, en particular:
Content-Type: indica el tipo MIME de los datos en el cuerpo (text/html, application/json, text/plain, text/css, image/gif).
Content-Length: indica el número de bytes en el cuerpo del mensaje.
### Métodos de solicitud
GET, POST, PUT y DELETE son los métodos HTTP que usaremos para implementar la API y las operaciones CRUD.
1. GET: el método GET se usa para recuperar y obtener información desde el servidor dado un URI. Las solicitudes GET deben únicamente recuperar datos y no producir otros efectos.
2. POST: las solicitudes POST se usan para crear datos y enviar datos al servidor, por ejemplo al crear una nueva entrada con un formulario HTML o subir archivos.
3. PUT: reemplaza la representación actual completa del recurso objetivo con la carga enviada; lo usamos para modificar o actualizar datos.
4. DELETE: elimina datos.
## 💻 Ejercicio: Día 28
1. Lee recursos sobre APIs y HTTP
🎉 ¡Felicidades! 🎉
[<< Día 27](./27_python_with_mongodb_sp.md) | [Día 29 >>](./29_building_API_sp.md)
================================================
FILE: Spanish/29_building_API_sp.md
================================================
# Reto de 30 días de Python: Día 29 - Construyendo una API
- [Día 29](#día-29)
- [Construyendo una API](#construyendo-una-api)
- [Estructura de la API](#estructura-de-la-api)
- [Obtener datos con GET](#obtener-datos-con-get)
- [Obtener un documento por ID](#obtener-un-documento-por-id)
- [Crear datos con POST](#crear-datos-con-post)
- [Actualizar con PUT](#actualizar-con-put)
- [Eliminar documentos con DELETE](#eliminar-documentos-con-delete)
- [💻 Ejercicio: Día 29](#-ejercicio-día-29)
## Día 29
## Construyendo una API
En esta sección presentaremos una API RESTful que utiliza métodos HTTP como GET, PUT, POST y DELETE para manejar datos.
Una API RESTful es una interfaz de programación de aplicaciones (API) que usa solicitudes HTTP para GET, PUT, POST y DELETE datos. En secciones anteriores aprendimos Python, Flask y MongoDB. Aprovecharemos ese conocimiento para desarrollar una API RESTful usando Python, Flask y MongoDB. Toda aplicación con operaciones CRUD (Crear, Leer, Actualizar, Eliminar) suele exponer una API para crear datos en la base, obtener datos, actualizarlos o borrarlos.
Los navegadores solo manejan solicitudes GET. Por eso necesitamos una herramienta que nos permita manejar todos los métodos (GET, POST, PUT, DELETE).
Ejemplos de APIs:
- API de países: https://restcountries.eu/rest/v2/all
- API de razas de gatos: https://api.thecatapi.com/v1/breeds
[Postman](https://www.getpostman.com/) es una herramienta muy popular en el desarrollo de APIs. Si quieres seguir esta sección, descarga [Postman](https://www.getpostman.com/). Una alternativa a Postman es [Insomnia](https://insomnia.rest/download).

### Estructura de la API
Un endpoint de API es una URL que ayuda a recuperar, crear, actualizar o eliminar un recurso. La estructura suele ser:
Ejemplo de endpoint:
https://api.twitter.com/1.1/lists/members.json
Este endpoint devuelve los miembros de una lista específica. Las listas privadas muestran miembros solo si el usuario autenticado posee la lista.
El nombre de la empresa va seguido de la versión y del propósito de la API.
Métodos:
Métodos HTTP: método y URL
La API usa los siguientes métodos HTTP para operar sobre objetos:
```sh
GET para recuperar objetos
POST para crear objetos y operaciones relacionadas
PUT para actualizar objetos
DELETE para eliminar objetos
```
Construiremos una API para recopilar información sobre estudiantes de 30DaysOfPython. Recogemos nombre, país, ciudad, año de nacimiento, habilidades y biografía.
Para implementar esta API utilizaremos:
- Postman
- Python
- Flask
- MongoDB
### Obtener datos con GET
En este paso usaremos datos ficticios y los devolveremos como JSON. Para retornarlos como JSON usaremos el módulo json y Response.
```py
# importar flask
from flask import Flask, Response
import json
app = Flask(__name__)
@app.route('/api/v1.0/students', methods = ['GET'])
def students ():
student_list = [
{
'name':'Asabeneh',
'country':'Finland',
'city':'Helsinki',
'skills':['HTML', 'CSS','JavaScript','Python']
},
{
'name':'David',
'country':'UK',
'city':'London',
'skills':['Python','MongoDB']
},
{
'name':'John',
'country':'Sweden',
'city':'Stockholm',
'skills':['Java','C#']
}
]
return Response(json.dumps(student_list), mimetype='application/json')
if __name__ == '__main__':
# usado en despliegue
# para que funcione en producción y desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
Si solicitas http://localhost:5000/api/v1.0/students en el navegador obtendrás:

Si solicitas la misma URL en Postman obtendrás:

En lugar de datos ficticios, conectaremos la aplicación Flask a MongoDB y obtendremos datos desde la base.
```py
# importar flask
from flask import Flask, Response
import json
import pymongo
app = Flask(__name__)
#
MONGODB_URI='mongodb+srv://asabeneh:your_password@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
#Nota: nunca incluyas credenciales reales en el código.
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
@app.route('/api/v1.0/students', methods = ['GET'])
def students ():
return Response(json.dumps(student), mimetype='application/json')
if __name__ == '__main__':
# usado en despliegue
# para que funcione en producción y desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
Al conectar Flask con MongoDB podemos obtener la colección students de la base thirty_days_of_python:
```sh
[
{
"_id": {
"$oid": "5df68a21f106fe2d315bbc8b"
},
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"age": 38
},
{
"_id": {
"$oid": "5df68a23f106fe2d315bbc8c"
},
"name": "David",
"country": "UK",
"city": "London",
"age": 34
},
{
"_id": {
"$oid": "5df68a23f106fe2d315bbc8e"
},
"name": "Sami",
"country": "Finland",
"city": "Helsinki",
"age": 25
}
]
```
### Obtener un documento por ID
Podemos acceder a un documento individual por su ID. Por ejemplo, accedamos a Asabeneh:
http://localhost:5000/api/v1.0/students/5df68a21f106fe2d315bbc8b
```py
# importar flask
from flask import Flask, Response
import json
from bson.objectid import ObjectId
import json
from bson.json_util import dumps
import pymongo
app = Flask(__name__)
#
MONGODB_URI='mongodb+srv://asabeneh:your_password@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
#Nota: nunca incluyas credenciales reales en el código.
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
@app.route('/api/v1.0/students', methods = ['GET'])
def students ():
return Response(json.dumps(student), mimetype='application/json')
@app.route('/api/v1.0/students/', methods = ['GET'])
def single_student (id):
student = db.students.find({'_id':ObjectId(id)})
return Response(dumps(student), mimetype='application/json')
if __name__ == '__main__':
# usado en despliegue
# para que funcione en producción y desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
Respuesta de ejemplo:
```sh
[
{
"_id": {
"$oid": "5df68a21f106fe2d315bbc8b"
},
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"age": 38
}
]
```
### Crear datos con POST
Usamos el método POST para crear datos.
```py
# importar flask
from flask import Flask, Response, Request
import json
from bson.objectid import ObjectId
import json
from bson.json_util import dumps
import pymongo
from datetime import datetime
app = Flask(__name__)
#
MONGODB_URI='mongodb+srv://asabeneh:your_password@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
#Nota: nunca incluyas credenciales reales en el código.
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
@app.route('/api/v1.0/students', methods = ['GET'])
def students ():
return Response(json.dumps(student), mimetype='application/json')
@app.route('/api/v1.0/students/', methods = ['GET'])
def single_student (id):
student = db.students.find({'_id':ObjectId(id)})
return Response(dumps(student), mimetype='application/json')
@app.route('/api/v1.0/students', methods = ['POST'])
def create_student ():
name = request.form['name']
country = request.form['country']
city = request.form['city']
skills = request.form['skills'].split(', ')
bio = request.form['bio']
birthyear = request.form['birthyear']
created_at = datetime.now()
student = {
'name': name,
'country': country,
'city': city,
'birthyear': birthyear,
'skills': skills,
'bio': bio,
'created_at': created_at
}
db.students.insert_one(student)
return ;
def update_student (id):
if __name__ == '__main__':
# usado en despliegue
# para que funcione en producción y desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
### Actualizar con PUT
```py
# importar flask
from flask import Flask, Response
import json
from bson.objectid import ObjectId
import json
from bson.json_util import dumps
import pymongo
from datetime import datetime
app = Flask(__name__)
#
MONGODB_URI='mongodb+srv://asabeneh:your_password@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
#Nota: nunca incluyas credenciales reales en el código.
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
@app.route('/api/v1.0/students', methods = ['GET'])
def students ():
return Response(json.dumps(student), mimetype='application/json')
@app.route('/api/v1.0/students/', methods = ['GET'])
def single_student (id):
student = db.students.find({'_id':ObjectId(id)})
return Response(dumps(student), mimetype='application/json')
@app.route('/api/v1.0/students', methods = ['POST'])
def create_student ():
name = request.form['name']
country = request.form['country']
city = request.form['city']
skills = request.form['skills'].split(', ')
bio = request.form['bio']
birthyear = request.form['birthyear']
created_at = datetime.now()
student = {
'name': name,
'country': country,
'city': city,
'birthyear': birthyear,
'skills': skills,
'bio': bio,
'created_at': created_at
}
db.students.insert_one(student)
return
@app.route('/api/v1.0/students/', methods = ['PUT']) # este decorador crea la ruta para actualizar
def update_student (id):
query = {"_id":ObjectId(id)}
name = request.form['name']
country = request.form['country']
city = request.form['city']
skills = request.form['skills'].split(', ')
bio = request.form['bio']
birthyear = request.form['birthyear']
created_at = datetime.now()
student = {
'name': name,
'country': country,
'city': city,
'birthyear': birthyear,
'skills': skills,
'bio': bio,
'created_at': created_at
}
db.students.update_one(query, {"$set": student})
# return Response(dumps({"result":"a new student has been created"}), mimetype='application/json')
return
def update_student (id):
if __name__ == '__main__':
# usado en despliegue
# para que funcione en producción y desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
### Eliminar documentos con DELETE
```py
# importar flask
from flask import Flask, Response
import json
from bson.objectid import ObjectId
import json
from bson.json_util import dumps
import pymongo
from datetime import datetime
app = Flask(__name__)
#
MONGODB_URI='mongodb+srv://asabeneh:your_password@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority'
#Nota: nunca incluyas credenciales reales en el código.
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # acceder a la base de datos
@app.route('/api/v1.0/students', methods = ['GET'])
def students ():
return Response(json.dumps(student), mimetype='application/json')
@app.route('/api/v1.0/students/', methods = ['GET'])
def single_student (id):
student = db.students.find({'_id':ObjectId(id)})
return Response(dumps(student), mimetype='application/json')
@app.route('/api/v1.0/students', methods = ['POST'])
def create_student ():
name = request.form['name']
country = request.form['country']
city = request.form['city']
skills = request.form['skills'].split(', ')
bio = request.form['bio']
birthyear = request.form['birthyear']
created_at = datetime.now()
student = {
'name': name,
'country': country,
'city': city,
'birthyear': birthyear,
'skills': skills,
'bio': bio,
'created_at': created_at
}
db.students.insert_one(student)
return
@app.route('/api/v1.0/students/', methods = ['PUT']) # este decorador crea la ruta para actualizar
def update_student (id):
query = {"_id":ObjectId(id)}
name = request.form['name']
country = request.form['country']
city = request.form['city']
skills = request.form['skills'].split(', ')
bio = request.form['bio']
birthyear = request.form['birthyear']
created_at = datetime.now()
student = {
'name': name,
'country': country,
'city': city,
'birthyear': birthyear,
'skills': skills,
'bio': bio,
'created_at': created_at
}
db.students.update_one(query, {"$set": student})
# return Response(dumps({"result":"a new student has been created"}), mimetype='application/json')
return ;
@app.route('/api/v1.0/students/', methods = ['DELETE'])
def delete_student (id):
db.students.delete_one({"_id":ObjectId(id)})
return
if __name__ == '__main__':
# usado en despliegue
# para que funcione en producción y desarrollo
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
```
## 💻 Ejercicio: Día 29
1. Implementa los ejemplos anteriores y desarrolla [esta API](https://thirtydayofpython-api.herokuapp.com/)
🎉 ¡Felicidades! 🎉
[<< Día 28](./28_API_sp.md) | [Día 30 >>](./30_conclusions_sp.md)
================================================
FILE: Spanish/30_conclusions_sp.md
================================================
# Reto de 30 días de Python: Día 30 - Conclusiones
- [Día 30](#día-30)
- [Resumen](#resumen)
- [Testimonios](#testimonios)
# Día 30
## Resumen
Al preparar este material aprendí mucho y ustedes me motivaron a hacer más. Felicidades por llegar hasta aquí. Si has completado todos los ejercicios y proyectos, ahora tienes la capacidad de avanzar en análisis de datos, ciencia de datos, aprendizaje automático o desarrollo web. [Apoya al autor para más material educativo](https://www.paypal.com/paypalme/asabeneh).
## Testimonios
Ahora es el momento de compartir tus pensamientos sobre el autor y el reto de 30 días de Python. Puedes dejar tu testimonio en este [enlace](https://www.asabeneh.com/testimonials).
Enviar comentarios/retroalimentación:
http://thirtydayofpython-api.herokuapp.com/feedback
🎉 ¡Felicidades! 🎉
[<< Día 29](./29_building_API_sp.md)
================================================
FILE: Spanish/README_sp.md
================================================
# 🐍 30 Días de Python
| # Día | Tema |
| ------ | :--------------------------------------------------------------------------------------: |
| 01 | [Introducción](./readme_sp.md) |
| 02 | [Variables y funciones integradas](./02_variables_builtin_functions_sp.md) |
| 03 | [Operadores](./03_operators_sp.md) |
| 04 | [Cadenas](./04_strings_sp.md) |
| 05 | [Listas](./05_lists_sp.md) |
| 06 | [Tuplas](./06_tuples_sp.md) |
| 07 | [Conjuntos](./07_sets_sp.md) |
| 08 | [Diccionarios](./08_dictionaries_sp.md) |
| 09 | [Condicionales](./09_conditionals_sp.md) |
| 10 | [Bucles](./10_loops_sp.md) |
| 11 | [Funciones](./11_functions_sp.md) |
| 12 | [Módulos](./12_modules_sp.md) |
| 13 | [Comprensión de listas](./13_list_comprehension_sp.md) |
| 14 | [Funciones de orden superior](./14_higher_order_functions_sp.md) |
| 15 | [Errores de tipo](./15_python_type_errors_sp.md) |
| 16 | [Fechas y horas en Python](./16_python_datetime_sp.md) |
| 17 | [Manejo de excepciones](./17_exception_handling_sp.md) |
| 18 | [Expresiones regulares](./18_regular_expressions_sp.md) |
| 19 | [Manejo de archivos](./19_file_handling_sp.md) |
| 20 | [Gestor de paquetes](./20_python_package_manager_sp.md) |
| 21 | [Clases y objetos](./21_classes_and_objects_sp.md) |
| 22 | [Web scraping](./22_web_scraping_sp.md) |
| 23 | [Entornos virtuales](./23_virtual_environment_sp.md) |
| 24 | [Estadística](./24_statistics_sp.md) |
| 25 | [Pandas](./25_pandas_sp.md) |
| 26 | [Python en la web](./26_python_web_sp.md) |
| 27 | [Python y MongoDB](./27_python_with_mongodb_sp.md) |
| 28 | [API](./28_API_sp.md) |
| 29 | [Construir API](./29_building_API_sp.md) |
| 30 | [Conclusiones](./30_conclusions_sp.md) |
🧡🧡🧡 Feliz codificación 🧡🧡🧡
[Ir al Día 2 >>](./02_variables_builtin_functions_sp.md)

- [🐍 30 Días de Python](#-30-días-de-python)
- [📘 Día 1](#-día-1)
- [¡Bienvenido!](#¡bienvenido!)
- [Introducción](#introducción)
- [¿Por qué elegir Python?](#¿por-qué-elegir-python?)
- [Configuración del entorno](#configuración-del-entorno)
- [Instalar Python](#instalar-python)
- [Python Shell](#python-shell)
- [Instalar Visual Studio Code](#instalar-visual-studio-code)
- [Cómo usar Visual Studio Code](#cómo-usar-visual-studio-code)
- [Fundamentos de Python](#fundamentos-de-python)
- [Sintaxis de Python](#sintaxis-de-python)
- [Indentación en Python](#indentación-en-python)
- [Comentarios](#comentarios)
- [Ejemplo: comentario de una sola línea](#ejemplo-comentario-de-una-sola-línea)
- [Ejemplo: comentario multilínea (docstring)](#ejemplo-comentario-multilínea-docstring)
- [Tipos de datos](#tipos-de-datos)
- [Números](#números)
- [Cadenas](#cadenas)
- [Booleanos](#booleanos)
- [Listas](#listas)
- [Diccionarios](#diccionarios)
- [Tuplas](#tuplas)
- [Conjuntos](#conjuntos)
- [Comprobar tipos de datos](#comprobar-tipos-de-datos)
- [Archivos Python](#archivos-python)
- [💻 Ejercicios - Día 1](#-ejercicios---día-1)
- [Ejercicios: Nivel 1](#ejercicios-nivel-1)
- [Ejercicios: Nivel 2](#ejercicios-nivel-2)
- [Ejercicios: Nivel 3](#ejercicios-nivel-3)
# 📘 Día 1
## ¡Bienvenido!
**Felicidades** por decidir participar en el desafío de programación _30 Días de Python_. En este reto aprenderás todo lo necesario para convertirte en programador Python y la mayoría de los conceptos de programación. Al finalizar el reto recibirás un certificado del desafío _30DaysOfPython_.
Si quieres participar activamente, únete al grupo de Telegram [30DaysOfPython challenge](https://t.me/ThirtyDaysOfPython).
## Introducción
Python es un lenguaje de programación de alto nivel, de propósito general. Es un lenguaje de código abierto, interpretado y orientado a objetos. Python fue creado por el programador holandés Guido van Rossum. El nombre del lenguaje proviene del show cómico británico _Monty Python's Flying Circus_. La primera versión se lanzó el 20 de febrero de 1991. Este desafío de 30 días te ayudará a aprender progresivamente la versión más reciente de Python, Python 3. Cada día cubre un tema diferente con explicaciones claras, ejemplos del mundo real, y muchos ejercicios y proyectos prácticos.
El reto es adecuado para principiantes y profesionales que quieran aprender Python. Completar el reto puede tomar de 30 a 100 días; los miembros activos del grupo de Telegram tienen más probabilidades de terminarlo.
Este reto fue escrito inicialmente en inglés sencillo, y luego traducido al chino. El reto es motivador, accesible y desafiante. Requiere dedicación para completarlo. Si aprendes mejor con vídeos, visita el canal Washera en YouTube:
Washera YouTube channel. Puedes empezar por el video [Python for absolute beginners](https://youtu.be/OCCWZheOesI). Suscríbete, deja tus preguntas en los comentarios y sé proactivo; el autor te podrá notar.
El autor aprecia tus comentarios, que compartas el contenido y la retroalimentación sobre el reto 30DaysOfPython. Puedes dejar feedback aquí: [link](https://www.asabeneh.com/testimonials)
## ¿Por qué elegir Python?
Python es un lenguaje con sintaxis cercana al lenguaje humano, sencillo y fácil de aprender y usar.
Python es usado en muchas industrias y empresas (incluido Google). Se usa para desarrollar aplicaciones web, de escritorio, administración de sistemas y librerías de aprendizaje automático. Python está ampliamente adoptado en la comunidad de ciencia de datos y machine learning. Si esto no te convence, ¡es hora de empezar!
## Configuración del entorno
### Instalar Python
Para ejecutar scripts escritos en Python necesitas instalar Python. Visita la página de descargas de Python: [https://www.python.org/](https://www.python.org/).
Si usas Windows haz clic en el botón marcado en la imagen.
[](https://www.python.org/)
Si usas macOS haz clic en el botón marcado en la imagen.
[](https://www.python.org/)
Para comprobar si Python está instalado, abre la terminal y ejecuta:
```shell
python --version
```

En mi terminal aparece Python 3.7.5. Tu versión puede variar, pero debe ser 3.6 o superior. Si ves la versión, Python está instalado. Continúa al siguiente apartado.
### Python Shell
Python es un lenguaje interpretado, no necesita compilación. Se ejecuta línea por línea. Python incluye el Python Shell (intérprete interactivo), también llamado REPL (Read Eval Print Loop). Se usa para ejecutar comandos Python individuales y ver resultados al instante.
El Python Shell espera código Python. Al escribir código lo interpreta y muestra el resultado.
Abre la terminal o el símbolo del sistema (cmd) y escribe:
```shell
python
```

El intérprete interactivo de Python estará abierto y mostrará el prompt >>> para que escribas comandos Python. Escribe tu primer script y pulsa Enter.
Veamos un ejemplo en el Shell interactivo.

Genial: escribiste tu primer script en el Shell interactivo. ¿Cómo salir del Shell?
Para salir escribe **exit()** y pulsa Enter.

Ahora sabes cómo abrir y cerrar el intérprete interactivo.
Si escribes código inválido, Python mostrará un error. Probemos un error intencional:

El error indica Syntax Error: Invalid Syntax. Usar x para multiplicar no es válido en Python; el operador correcto es el asterisco (*). El error señala exactamente lo que hay que corregir.
El proceso de encontrar y corregir errores se llama depuración (debugging). Reemplazamos x por * y volvemos a ejecutar:

El error se corrige y el código produce el resultado esperado. Verás errores así a diario; aprender a depurar es esencial. Para depurar bien debes reconocer los tipos de errores: SyntaxError, IndexError, NameError, ModuleNotFoundError, KeyError, ImportError, AttributeError, TypeError, ValueError, ZeroDivisionError, etc. Los explicaremos más adelante.
Practiquemos más en el Python Shell. Abre la terminal y escribe python.

Con el Shell abierto hagamos operaciones matemáticas básicas: suma, resta, multiplicación, división, módulo y potencia.
Antes de programar, hagamos algunos cálculos:
- 2 + 3 = 5
- 3 - 2 = 1
- 3 * 2 = 6
- 3 / 2 = 1.5
- 3 ** 2 = 9
En Python también tenemos:
- 3 % 2 = 1 => resto de la división
- 3 // 2 = 1 => división entera (sin resto)
Conviértelo a código Python en el Shell. Primero escribe un comentario.
Un comentario es texto ignorado por Python. Sirve para documentar y mejorar la legibilidad. En Python los comentarios empiezan con #.
Así se escribe un comentario en Python:
```python
# Los comentarios comienzan con una almohadilla
# Este es un comentario en Python porque empieza con (#)
```

Antes de continuar, practica más: cierra el Shell con _exit()_ y vuelve a abrirlo; escribe texto en el Shell:

### Instalar Visual Studio Code
El Python Shell está bien para probar fragmentos, pero para proyectos más grandes se usan editores de código. En este reto usaremos Visual Studio Code. VS Code es un editor de texto de código abierto muy popular. Recomiendo instalar Visual Studio Code, aunque puedes usar otro editor si lo prefieres.
[](https://code.visualstudio.com/)
Si ya tienes Visual Studio Code, veamos cómo usarlo.
Si prefieres vídeos, mira el tutorial de instalación y configuración de VS Code para Python: https://www.youtube.com/watch?v=bn7Cx4z-vSo
#### Cómo usar Visual Studio Code
Abre Visual Studio Code haciendo doble clic en su icono. Aparecerá la interfaz. Interactúa con los iconos marcados en la imagen.

Crea en el escritorio una carpeta llamada 30DaysOfPython. Ábrela con Visual Studio Code.


Dentro del proyecto verás accesos para crear archivos y carpetas. Yo creé el primer archivo helloworld.py; tú puedes hacer lo mismo.

Cuando termines de programar puedes cerrar el proyecto desde el editor:

¡Enhorabuena! El entorno está listo. ¡Manos a la obra!
## Fundamentos de Python
### Sintaxis de Python
Los scripts Python se pueden escribir en el Shell interactivo o en un editor. Los archivos Python usan la extensión .py.
### Indentación en Python
La indentación son espacios en blanco en el código. En muchos lenguajes se usa para mejorar legibilidad; en Python se usa para definir bloques de código. En otros lenguajes se usan llaves. Un error común en Python es el error de indentación.

### Comentarios
Los comentarios son importantes para la legibilidad. Python no ejecuta el texto dentro de comentarios.
Cualquier texto que comience con # en Python es un comentario.
# Ejemplo: comentario de una sola línea
```shell
# Este es el primer comentario
# Este es el segundo comentario
# Python se está apoderando del mundo
```
# Ejemplo: comentario multilínea (docstring)
Se pueden usar comillas triples para comentarios multilínea si no se asignan a una variable.
```shell
"""Este es un comentario multilínea
Los comentarios multilínea ocupan varias líneas.
Python se está apoderando del mundo
"""
```
### Tipos de datos
Python tiene varios tipos de datos. Empecemos por los más comunes. Veremos otros tipos más en detalle en secciones posteriores. A continuación un resumen para familiarizarte.
#### Números
- Enteros: ... -3, -2, -1, 0, 1, 2, 3 ...
- Flotantes: ... -3.5, -2.25, -1.0, 0.0, 1.1, 2.2, 3.5 ...
- Complejos: 1 + j, 2 + 4j
#### Cadenas
Texto entre comillas simples o dobles; para multilínea se usan comillas triples.
**Ejemplos:**
```py
'Asabeneh'
'Finland'
'Python'
'I love teaching'
'I hope you are enjoying the first day of 30DaysOfPython Challenge'
```
#### Booleanos
True o False. Deben estar en mayúscula.
**Ejemplo:**
```python
True # ¿La luz está encendida? Si sí, el valor es True
False # ¿La luz está encendida? Si no, el valor es False
```
#### Listas
Lista ordenada que puede contener distintos tipos, similar a un array en JavaScript.
**Ejemplos:**
```py
[0, 1, 2, 3, 4, 5] # todos números
['Banana', 'Orange', 'Mango', 'Avocado'] # todos cadenas
['Finland','Estonia', 'Sweden','Norway'] # todos cadenas (países)
['Banana', 10, False, 9.81] # mezcla de tipos
```
#### Diccionarios
Colección no ordenada de pares clave:valor.
**Ejemplo:**
```py
{
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'country':'Finland',
'age':250,
'is_married':True,
'skills':['JS', 'React', 'Node', 'Python']
}
```
#### Tuplas
Colección ordenada e inmutable.
**Ejemplo:**
```py
('Asabeneh', 'Pawel', 'Brook', 'Abraham', 'Lidiya') # nombres
```
```py
('Earth', 'Jupiter', 'Neptune', 'Mars', 'Venus', 'Saturn', 'Uranus', 'Mercury') # planetas
```
#### Conjuntos
Colección no ordenada que almacena elementos únicos (sin duplicados).
**Ejemplos:**
```py
{2, 4, 3, 5}
{3.14, 9.81, 2.7} # el orden en un set no importa
```
Detallaremos cada tipo de dato en secciones posteriores.
### Comprobar tipos de datos
Usa la función built-in **type** para comprobar el tipo de una variable. En la imagen puedes ver ejemplos:

### Archivos Python
Abre tu carpeta de proyecto 30DaysOfPython (créala si no existe). Dentro crea helloworld.py. Repite lo que hicimos en el Shell pero usando print() para ver resultados en consola desde un archivo.
En el intérprete se imprime sin print, pero en VS Code debes usar la función _print()_. Ejemplo de uso: _print('argumento1', 'argumento2')_.
**Ejemplo:** archivo helloworld.py
```py
# Día 1 - Desafío 30DaysOfPython
print(2 + 3) # Suma (+)
print(3 - 1) # Resta (-)
print(2 * 3) # Multiplicación (*)
print(3 / 2) # División (/)
print(3 ** 2) # Potencia (**)
print(3 % 2) # Módulo (%)
print(3 // 2) # División entera (//)
# Comprobar tipos de datos
print(type(10)) # entero
print(type(3.14)) # flotante
print(type(1 + 3j)) # complejo
print(type('Asabeneh')) # cadena
print(type([1, 2, 3])) # lista
print(type({'name':'Asabeneh'})) # diccionario
print(type({9.8, 3.14, 2.7})) # conjunto
print(type((9.8, 3.14, 2.7))) # tupla
```
Para ejecutar el archivo: en VS Code usa el botón verde o en la terminal escribe _python helloworld.py_.

Genial. Completaste el Día 1. Practica con los ejercicios siguientes.
## 💻 Ejercicios - Día 1
### Ejercicios: Nivel 1
1. Comprueba la versión de Python que usas.
2. Abre el Python Shell e intenta con los operandos 3 y 4:
- Suma (+)
- Resta (-)
- Multiplicación (*)
- Módulo (%)
- División (/)
- Potencia (**)
- División entera (//)
3. En el Python Shell escribe las siguientes cadenas:
- Tu nombre
- Tu apellido
- Tu país
- Estoy disfrutando 30 días de Python
4. Comprueba el tipo de los siguientes datos:
- 10
- 9.8
- 3.14
- 4 - 4j
- ['Asabeneh', 'Python', 'Finland']
- Tu nombre
- Tu apellido
- Tu país
### Ejercicios: Nivel 2
1. Crea en la carpeta 30DaysOfPython una carpeta llamada day_1. Dentro crea helloworld.py y repite las preguntas 1, 2, 3 y 4. Recuerda usar _print()_ en archivos. Navega a la carpeta donde guardaste el archivo y ejecútalo.
### Ejercicios: Nivel 3
1. Escribe ejemplos para distintos tipos de datos en Python: números (enteros, flotantes, complejos), cadenas, booleanos, listas, tuplas, conjuntos y diccionarios.
2. Calcula la distancia euclídea entre (2, 3) y (10, 8): [Euclidean distance](https://en.wikipedia.org/wiki/Euclidean_distance#:~:text=In%20mathematics%2C%20the%20Euclidean%20distance,being%20called%20the%20Pythagorean%20distance).
🎉 ¡Felicidades! 🎉
[Ir al Día 2 >>](./02_variables_builtin_functions_sp.md)
================================================
FILE: Spanish/readme.md
================================================
# 🐍 30 Days Of Python
|# Day | Topics |
|------|:---------------------------------------------------------:|
| 01 | [Introducción](./readme.md)|
| 02 | [Variables, funciones integradas](./02_Day_Variables_builtin_functions/02_variables_builtin_functions.md)|
| 03 | [Operadores](./03_Day_Operators/03_operators.md)|
| 04 | [Strings](./04_Day_Strings/04_strings.md)|
| 05 | [Lists](./05_Day_Lists/05_lists.md)|
| 06 | [Tuplas](./06_Day_Tuples/06_tuples.md)|
| 07 | [Sets](./07_Day_Sets/07_sets.md)|
| 08 | [Diccionarios](./08_Day_Dictionaries/08_dictionaries.md)|
| 09 | [Condicionales](./09_Day_Conditionals/09_conditionals.md)|
| 10 | [Bucles](./10_Day_Loops/10_loops.md)|
| 11 | [Funciones](./11_Day_Functions/11_functions.md)|
| 12 | [Módulos](./12_Day_Modules/12_modules.md)|
| 13 | [Lista de comprensión](./13_Day_List_comprehension/13_list_comprehension.md)|
| 14 | [Funciones de orden superior](./14_Day_Higher_order_functions/14_higher_order_functions.md)|
| 15 | [Errores de tipo Python](./15_Day_Python_type_errors/15_python_type_errors.md)|
| 16 | [Fecha y hora de Python](./16_Day_Python_date_time/16_python_datetime.md) |
| 17 | [Manejo de excepciones](./17_Day_Exception_handling/17_exception_handling.md)|
| 18 | [Expresiones regulares](./18_Day_Regular_expressions/18_regular_expressions.md)|
| 19 | [Manejo de archivos](./19_Day_File_handling/19_file_handling.md)|
| 20 | [Administrador de paquetes de Python](./20_Day_Python_package_manager/20_python_package_manager.md)|
| 21 | [Clases y Objetos](./21_Day_Classes_and_objects/21_classes_and_objects.md)|
| 22 | [Raspado web](./22_Day_Web_scraping/22_web_scraping.md)|
| 23 | [Ambiente virtual](./23_Day_Virtual_environment/23_virtual_environment.md)|
| 24 | [Estadísticas](./24_Day_Statistics/24_statistics.md)|
| 25 | [Pandas](./25_Day_Pandas/25_pandas.md)|
| 26 | [Python web](./26_Day_Python_web/26_python_web.md)|
| 27 | [Python con MongoDB](./27_Day_Python_with_mongodb/27_python_with_mongodb.md)|
| 28 | [API](./28_Day_API/28_API.md)|
| 29 | [Building API](./29_Day_Building_API/29_building_API.md)|
| 30 | [Conclusiones](./30_Day_Conclusions/30_conclusions.md)|
🧡🧡🧡 FELIZ CODIGO 🧡🧡🧡
Support the author to create more educational materials
[Dia 2 >>](./02_Day_Variables_builtin_functions/02_variables_builtin_functions.md)

- [🐍 30 Days Of Python](#-30-days-of-python)
- [📘 Day 1](#-day-1)
- [Welcome](#welcome)
- [Introduction](#introduction)
- [Why Python ?](#why-python-)
- [Environment Setup](#environment-setup)
- [Installing Python](#installing-python)
- [Python Shell](#python-shell)
- [Installing Visual Studio Code](#installing-visual-studio-code)
- [How to use visual studio code](#how-to-use-visual-studio-code)
- [Basic Python](#basic-python)
- [Python Syntax](#python-syntax)
- [Python Indentation](#python-indentation)
- [Comments](#comments)
- [Data types](#data-types)
- [Number](#number)
- [String](#string)
- [Booleans](#booleans)
- [List](#list)
- [Dictionary](#dictionary)
- [Tuple](#tuple)
- [Set](#set)
- [Checking Data types](#checking-data-types)
- [Python File](#python-file)
- [💻 Exercises - Day 1](#-exercises---day-1)
- [Exercise: Level 1](#exercise-level-1)
- [Exercise: Level 2](#exercise-level-2)
- [Exercise: Level 3](#exercise-level-3)
# 📘 Day 1
## Welcome
**Congratulations** for deciding to participate in a _30 days of Python_ programming challenge . In this challenge you will learn everything you need to be a python programmer and the whole concept of programming. In the end of the challenge you will get a _30DaysOfPython_ programming challenge certificate.
If you would like to actively engage in the challenge, you may join the [30DaysOfPython challenge](https://t.me/ThirtyDaysOfPython) telegram group.
## Introduction
Python is a high-level programming language for general-purpose programming. It is an open source, interpreted, objected-oriented programming language. Python was created by a Dutch programmer, Guido van Rossum. The name of Python programming language was derived from a British sketch comedy series, _Monty Python's Flying Circus_. The first version was released on February 20, 1991. This 30 days of Python challenge will help you learn the latest version of Python, Python 3 step by step. The topics are broken down into 30 days, where each day contains several topics with easy-to-understand explanations, real-world examples, many hands on exercises and projects.
This challenge is designed for beginners and professionals who want to learn python programming language. It may take 30 to 100 days to complete the challenge, people who actively participate on the telegram group have a high probability of completing the challenge.
This challenge is easy to read, written in conversational English, engaging, motivating and at the same time, it is very demanding. You need to allocate much time to finish this challenge. If you are a visual learner, you may get the video lesson on Washera YouTube channel. You may start from [Python for Absolute Beginners video](https://youtu.be/OCCWZheOesI). Subscribe the channel, comment and ask questions on YouTube vidoes and be proactive, the author will eventually notice you.
The author likes to hear your opinion about the challenge, share the author by expressing your thoughts about the 30DaysOfPython challenge. You can leave your testimonial on this [link](https://testimonial-vdzd.onrender.com/)
## Why Python ?
It is a programming language which is very close to human language and because of that it is easy to learn and use.
Python is used by various industries and companies (including Google). It has been used to develop web applications, desktop applications, system adminstration, and machine learning libraries. Python is highly embraced language in the data science and machine learning community. I hope this is enough to convince you to start learning Python. Python is eating the world and you are killing it before it eats you.
## Environment Setup
### Installing Python
To run a python script you need to install python. Let's [download](https://www.python.org/) python.
If your are a windows user. Click the button encircled in red.
[](https://www.python.org/)
If you are a macOS user. Click the button encircled in red.
[](https://www.python.org/)
To check if python is installed write the following command on your device terminal.
```shell
python --version
```

As you can see from the terminal, I am using _Python 3.7.5_ version at the moment. Your version of Python might be different from mine by but it should be 3.6 or above. If you mange to see the python version, well done. Python has been installed on your machine. Continue to the next section.
### Python Shell
Python is an interpreted scripting language, so it does not need to be compiled. It means it executes the code line by line. Python comes with a _Python Shell (Python Interactive Shell)_. It is used to execute a single python command and get the result.
Python Shell waits for the Python code from the user. When you enter the code, it interprets the code and shows the result in the next line.
Open your terminal or command prompt(cmd) and write:
```shell
python
```

The Python interactive shell is opened and it is waiting for you to write Python code(Python script). You will write your Python script next to this symbol >>> and then click Enter.
Let us write our very first script on the Python scripting shell.

Well done, you wrote your first Python script on Python interactive shell. How do we close the Python interactive shell ?
To close the shell, next to this symbol >> write **exit()** command and press Enter.

Now, you know how to open the Python interactive shell and how to exit from it.
Python will give you results if you write scripts that Python understands, if not it returns errors. Let's make a deliberate mistake and see what Python will return.

As you can see from the returned error, Python is so clever that it knows the mistake we made and which was _Syntax Error: invalid syntax_. Using x as multiplication in Python is a syntax error because (x) is not a valid syntax in Python. Instead of (**x**) we use asterisk (*) for multiplication. The returned error clearly shows what to fix.
The process of identifying and removing errors from a program is called _debugging_. Let us debug it by putting * in place of **x**.

Our bug was fixed, the code ran and we got a result we were expecting. As a programmer you will see such kind of errors on daily basis. It is good to know how to debug. To be good at debugging you should understand what kind of errors you are facing. Some of the Python errors you may encounter are _SyntaxError_, _IndexError_, _NameError_, _ModuleNotFoundError_, _KeyError_, _ImportError_, _AttributeError_, _TypeError_, _ValueError_, _ZeroDivisionError_ etc. We will see more about different Python **_error types_** in later sections.
Let us practice more how to use Python interactive shell. Go to your terminal or command prompt and write the word **python**.

The Python interactive shell is opened. Let us do some basic mathematical operations (addition, subtraction, multiplication, division, modulus, exponential).
Let us do some maths first before we write any Python code:
- 2 + 3 is 5
- 3 - 2 is 1
- 3 \* 2 is 6
- 3 / 2 is 1.5
- 3 ** 2 is the same as 3 * 3
In python we have the following additional operations:
- 3 % 2 = 1 => which means finding the remainder
- 3 // 2 = 1 => which means removing the remainder
Let us change the above mathematical expressions to Python code. The Python shell has been opened and let us write a comment at the very beginning of the shell.
A _comment_ is a part of the code which is not executed by python. So we can leave some text in our code to make our code more readable. Python does not run the comment part. A comment in python starts with hash(#) symbol.
This is how you write a comment in python
```shell
# comment starts with hash
# this is a python comment, because it starts with a (#) symbol
```

Before we move on to the next section, let us practice more on the Python interactive shell. Close the opened shell by writing _exit()_ on the shell and open it again and let us practice how to write text on the Python shell.

### Installing Visual Studio Code
The Python interactive shell is good to try and test small script codes but it will not be for a big project. In real work environment, developers use different code editors to write codes. In this 30 days of Python programming challenge we will use visual studio code. Visual studio code is a very popular open source text editor. I am a fan of vscode and I would recommend to [download](https://code.visualstudio.com/) visual studio code, but if you are in favor of other editors, feel free to follow with what you have.
[](https://code.visualstudio.com/)
If you installed visual studio code, let us see how to use it.
If you prefer a video, you can follow this Visual Studio Code for Python [Video tutorial](https://www.youtube.com/watch?v=bn7Cx4z-vSo)
#### How to use visual studio code
Open the visual studio code by double clicking the visual studio icon. When you open it you will get this kind of interface. Try to interact with the labeled icons.

Create a folder named 30DaysOfPython on your desktop. Then open it using visual studio code.


After opening it you will see shortcuts for creating files and folders inside of 30DaysOfPython project's directory. As you can see below, I have created the very first file, helloworld.py. You can do the same.

After a long day of coding, you want to close your code editor, right? This is how you will close the opened project.

Congratulations, you have finished setting up the development environment. Let us start coding.
## Basic Python
### Python Syntax
A Python script can be written in Python interactive shell or in the code editor. A Python file has an extension .py.
### Python Indentation
An indentation is a white space in a text. Indentation in many languages is used to increase code readability, however Python uses indentation to create block of codes. In other programming languages curly brackets are used to create blocks of codes instead of indentation. One of the common bugs when writing python code is wrong indentation.

### Comments
Comments are very important to make the code more readable and to leave remarks in our code. Python does not run comment parts of our code.
Any text starting with hash(#) in Python is a comment.
**Example: Single Line Comment**
```shell
# This is the first comment
# This is the second comment
# Python is eating the world
```
**Example: Multiline Comment**
Triple quote can be used for multiline comment if it is not assigned to a variable
```shell
"""This is multiline comment
multiline comment takes multiple lines.
python is eating the world
"""
```
### Data types
In Python there are several types of data types. Let us get started with the most common ones. Different data types will be covered in detail in other sections. For the time being, let us just go through the different data types and get familiar with them. You do not have to have a clear understanding now.
#### Number
- Integer: Integer(negative, zero and positive) numbers
Example:
... -3, -2, -1, 0, 1, 2, 3 ...
- Float: Decimal number
Example
... -3.5, -2.25, -1.0, 0.0, 1.1, 2.2, 3.5 ...
- Complex
Example
1 + j, 2 + 4j
#### String
A collection of one or more characters under a single or double quote. If a string is more than one sentence then we use a triple quote.
**Example:**
```py
'Asabeneh'
'Finland'
'Python'
'I love teaching'
'I hope you are enjoying the first day of 30DaysOfPython Challenge'
```
#### Booleans
A boolean data type is either a True or False value. T and F should be always uppercase.
**Example:**
```python
True # Is the light on? If it is on, then the value is True
False # Is the light on? If it is off, then the value is False
```
#### List
Python list is an ordered collection which allows to store different data type items. A list is similar to an array in JavaScript.
**Example:**
```py
[0, 1, 2, 3, 4, 5] # all are the same data types - a list of numbers
['Banana', 'Orange', 'Mango', 'Avocado'] # all the same data types - a list of strings (fruits)
['Finland','Estonia', 'Sweden','Norway'] # all the same data types - a list of strings (countries)
['Banana', 10, False, 9.81] # different data types in the list - string, integer, boolean and float
```
#### Dictionary
A Python dictionary object is an unordered collection of data in a key value pair format.
**Example:**
```py
{
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'country':'Finland',
'age':250,
'is_married':True,
'skills':['JS', 'React', 'Node', 'Python']
}
```
#### Tuple
A tuple is an ordered collection of different data types like list but tuples can not be modified once they are created. They are immutable.
**Example:**
```py
('Asabeneh', 'Pawel', 'Brook', 'Abraham', 'Lidiya') # Names
```
```py
('Earth', 'Jupiter', 'Neptune', 'Mars', 'Venus', 'Saturn', 'Uranus', 'Mercury') # planets
```
#### Set
A set is a collection of data types similar to list and tuple. Unlike list and tuple, set is not an ordered collection of items. Like in Mathematics, set in Python stores only unique items.
In later sections, we will go in detail about each and every Python data type.
**Example:**
```py
{2, 4, 3, 5}
{3.14, 9.81, 2.7} # order is not important in set
```
### Checking Data types
To check the data type of certain data/variable we use the **type** function. In the following terminal you will see different python data types:

### Python File
First open your project folder, 30DaysOfPython. If you don't have this folder, create a folder name called 30DaysOfPython. Inside this folder, create a file called helloworld.py. Now, let's do what we did on python interactive shell using visual studio code.
The Python interactive shell was printing without using **print** but on visual studio code to see our result we should use a built in function _print(). The _print()_ built-in function takes one or more arguments as follows _print('arument1', 'argument2', 'argument3')_. See the examples below.
**Example:**
The file name is helloworld.py
```py
# Day 1 - 30DaysOfPython Challenge
print(2 + 3) # addition(+)
print(3 - 1) # subtraction(-)
print(2 * 3) # multiplication(*)
print(3 / 2) # division(/)
print(3 ** 2) # exponential(**)
print(3 % 2) # modulus(%)
print(3 // 2) # Floor division operator(//)
# Checking data types
print(type(10)) # Int
print(type(3.14)) # Float
print(type(1 + 3j)) # Complex number
print(type('Asabeneh')) # String
print(type([1, 2, 3])) # List
print(type({'name':'Asabeneh'})) # Dictionary
print(type({9.8, 3.14, 2.7})) # Set
print(type((9.8, 3.14, 2.7))) # Tuple
```
To run the python file check the image below. You can run the python file either by running the green button on Visual Studio Code or by typing _python helloworld.py_ in the terminal .

🌕 You are amazing. You have just completed day 1 challenge and you are on your way to greatness. Now do some exercises for your brain and muscles.
## 💻 Exercises - Day 1
### Exercise: Level 1
1. Check the python version you are using
2. Open the python interactive shell and do the following operations. The operands are 3 and 4.
- addition(+)
- subtraction(-)
- multiplication(\*)
- modulus(%)
- division(/)
- exponential(\*\*)
- floor division operator(//)
3. Write strings on the python interactive shell. The strings are the following:
- Your name
- Your family name
- Your country
- I am enjoying 30 days of python
4. Check the data types of the following data:
- 10
- 9.8
- 3.14
- 4 - 4j
- ['Asabeneh', 'Python', 'Finland']
- Your name
- Your family name
- Your country
### Exercise: Level 2
1. Create a folder named day_1 inside 30DaysOfPython folder. Inside day_1 folder, create a python file helloworld.py and repeat questions 1, 2, 3 and 4. Remember to use _print()_ when you are working on a python file. Navigate to the directory where you have saved your file, and run it.
### Exercise: Level 3
1. Write an example for different Python data types such as Number(Integer, Float, Complex), String, Boolean, List, Tuple, Set and Dictionary.
2. Find an [Euclidian distance](https://en.wikipedia.org/wiki/Euclidean_distance#:~:text=In%20mathematics%2C%20the%20Euclidean%20distance,being%20called%20the%20Pythagorean%20distance.) between (2, 3) and (10, 8)
🎉 CONGRATULATIONS ! 🎉
[Day 2 >>](./02_Day_Variables_builtin_functions/02_variables_builtin_functions.md)
================================================
FILE: Ukrainian/readme.md
================================================
# 🐍 30 днів з Python
| № дня | Теми |
|-------|:-------------------------------------------------------------------------------------------------------:|
| 01 | [Вступ](./readme.md) |
| 02 | [Variables, Built-in Functions](./02_Day_Variables_builtin_functions/02_variables_builtin_functions.md) |
| 03 | [Operators](../03_Day_Operators/03_operators.md) |
| 04 | [Strings](../04_Day_Strings/04_strings.md) |
| 05 | [Lists](../05_Day_Lists/05_lists.md) |
| 06 | [Tuples](../06_Day_Tuples/06_tuples.md) |
| 07 | [Sets](../07_Day_Sets/07_sets.md) |
| 08 | [Dictionaries](../08_Day_Dictionaries/08_dictionaries.md) |
| 09 | [Conditionals](../09_Day_Conditionals/09_conditionals.md) |
| 10 | [Loops](../10_Day_Loops/10_loops.md) |
| 11 | [Functions](../11_Day_Functions/11_functions.md) |
| 12 | [Modules](../12_Day_Modules/12_modules.md) |
| 13 | [List Comprehension](../13_Day_List_comprehension/13_list_comprehension.md) |
| 14 | [Higher Order Functions](../14_Day_Higher_order_functions/14_higher_order_functions.md) |
| 15 | [Python Type Errors](../15_Day_Python_type_errors/15_python_type_errors.md) |
| 16 | [Python Date time](../16_Day_Python_date_time/16_python_datetime.md) |
| 17 | [Exception Handling](../17_Day_Exception_handling/17_exception_handling.md) |
| 18 | [Regular Expressions](../18_Day_Regular_expressions/18_regular_expressions.md) |
| 19 | [File Handling](../19_Day_File_handling/19_file_handling.md) |
| 20 | [Python Package Manager](../20_Day_Python_package_manager/20_python_package_manager.md) |
| 21 | [Classes and Objects](../21_Day_Classes_and_objects/21_classes_and_objects.md) |
| 22 | [Web Scraping](../22_Day_Web_scraping/22_web_scraping.md) |
| 23 | [Virtual Environment](../23_Day_Virtual_environment/23_virtual_environment.md) |
| 24 | [Statistics](../24_Day_Statistics/24_statistics.md) |
| 25 | [Pandas](../25_Day_Pandas/25_pandas.md) |
| 26 | [Python web](../26_Day_Python_web/26_python_web.md) |
| 27 | [Python with MongoDB](../27_Day_Python_with_mongodb/27_python_with_mongodb.md) |
| 28 | [API](../28_Day_API/28_API.md) |
| 29 | [Building API](../29_Day_Building_API/29_building_API.md) |
| 30 | [Conclusions](../30_Day_Conclusions/30_conclusions.md) |
🧡🧡🧡 ЩАСЛИВОГО ПРОГРАМУВАННЯ 🧡🧡🧡
Підтримайте автора, щобм він створював більше навчальних матеріалів