Aprender a Programar en Python

Extractos muy modificados, muy incompletos, pero muy importantes para la evocacion y el dimensionamiento de lo aprendido a lo largo del curso de boot.dev (afilar el hacha). Es muy probable que no te sirva tanto como a mi. No te sorprenda que tarde mucho, lo considero necesario. Avanzar rapido es ir lento.

Introducción

Existen errores de sintaxis, logica y desempenio.

Variables

snake-case
var1, var2, var3 = "valor 1", 2, False
+ - * /
# comment
"""
docstring
"""
  
"", 5, 5.3, True
f"You have {num_banana} bananas"
username = None
username = input("What's your name? ")
  

In almost all circumstances, it's a bad to change the var type.

String concatenation vs interpolation.

Funciones y Ambito (scope)

arg = 10
global_factor = 3

def demo_function(param, multiplier=2, extra=None):
    local_sum = param + multiplier

    product = local_sum * global_factor

    if extra is None:
        extra = arg * 5 # global

    return local_sum, product, extra

result_sum, result_product, result_extra = demo_function(arg)
  
#entrypoint
def main():
def add_armor():
def print_health():
main() 
  
# by default
    return None
    return

  

Testing y Despuracion

Computación

+ - * / (float)
// (int redond abajo)
**
player_score = 4
player_score = player_score + 1
player_score += -= *= /= 1
  

sci-notation

and or not

binary numbers, bitwise operators (& |)

bin_str = "100"
print(int(bin_str, 2))
# 4

Comparaciones

< > <= >= == !=
if x > y:
  ...
elif x < y:
  ...
elif x == 365:
  ...
else:
  ...

boolean logic

Bucles

for i in range(0, 10): # step
    print(i)
# 0 to 9
num = 0
while num < 3:
    num += 1
    print(num)
continue, break

Listas []

numbers_strings = ["1", 1, "3", "400", 4, 500]
print(numbers_strings[2])
# "3"
fruits = ["apple", "banana", "pear"]
length = len(fruits)
# 3
inventory = ["Leather", "Iron Ore", "Healing Potion"]
inventory[0] = "Leather Armor"
# ['Leather Armor', 'Iron Ore', 'Healing Potion']
cards = []
cards.append("nvidia")
cards.append("amd")
# ['nvidia', 'amd']
vegetables = ["broccoli", "cabbage", "kale", "tomato"]
last_vegetable = vegetables.pop()
# vegetables = ['broccoli', 'cabbage', 'kale']
# last_vegetable = 'tomato'
vegetables.pop(1) would remove "cabbage" from the list.
for i in range(0, len(sports)):
    print(sports[i])
for tree in trees:
    print(tree)
max_so_far = float("-inf")
    for num in nums:
        if num > max_so_far:
            max_so_far = num
    return max_so_far
remainder = 8 % 3

Slicing

scores = [50, 70, 30, 20, 90, 10, 50]
print(scores[1:5:2])
# [70, 20]
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
numbers[:3] # Gives [0, 1, 2]
numbers[3:] # Gives [3, 4, 5, 6, 7, 8, 9]
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
numbers[::2] # Gives [0, 2, 4, 6, 8]
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
numbers[-3:] # Gives [7, 8, 9]

Operations

total = [1, 2, 3] + [4, 5, 6]
print(total)
# Prints: [1, 2, 3, 4, 5, 6]
fruits = ["apple", "orange", "banana"]
print("banana" in fruits) # or not in
# True/False
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
del nums[3]

# delete the second item up to (but not including) the fourth item
del nums[1:3]
print(nums)
# [1, 4, 5, 6, 7, 8, 9]

del nums[:]
print(nums)
# []

Tuplas ()

single = (45,)
my_tuple = ("this is a tuple", 45, True)
print(my_tuple[1])
# 45

Often used to store very small groups (like 2 or 3 items). Multiple tuples can be stored within a list.

my_tuples = [
    ("this is the first tuple in the list", 45, True),
    ("this is the second tuple in the list", 21, False)
]
print(my_tuples[1][2]) # False
dog = ("Fido", 4)
dog_name, dog_age = dog

split and join

message = "hello there sam"
words = message.split()
print(words)
# ["hello", "there", "sam"]
list_of_words = ["hello", "there", "sam"]
sentence = " ".join(list_of_words)
print(sentence)
# "hello there sam"

Diccionarios

# key-value pairs
car = {
  "brand": "Ford",
  "brand": "Toyota",
  "model": "Camry",
  "year": 2019,
}
print(car["brand"])
# Prints: Toyota
planets["Pluto"] = False
print(planets["Pluto"])
# Prints False
del names_dict["joe"] # if not exist, error
"brand" in car # True

3.7+ ordered

Conjuntos (Sets)

fruits = {"apple", "banana", "grape"}
print(type(fruits)) # <class 'set'>

print(fruits) # {'banana', 'grape', 'apple'}
fruits.add("pear")
fruits = set()
set1 = {"apple", "banana", "grape"}
set2 = {"apple", "banana"}
set3 = set1 - set2 # {'grape'}
set()

Errores and Exceptions

There are two main kinds of distinguishable errors:

Python uses a try-except pattern for handling errors.

try:
    10 / 0
except Exception:
    print("can't divide by zero")
# except Exception as e:
#     print(e)
# prints "division by zero"

Using these blocks allows error handling without program crashing.

Raising Your Own Exceptions

def craft_sword(metal_bar):
    # ... block
    raise Exception("invalid metal bar")

Don't Catch Your Own Exceptions

try:
    craft_sword("gold bar")
except Exception as e:
    print(e)

Different Types of Exceptions

Some exceptions are more specific and others more general. Catch most specific ones first (python stops checking once finds a matching handler).

try:
    10/0
except ZeroDivisionError: # specific
    print("0 division")
except Exception as e: # general
    print(e)

Almost all exceptions count as the parent Exception type.

Práctica

4. factorials!

Podemos escribir los tests unitarios desde cero o usar bibliotecas como pytest o unittest.

Some programmers like to work this way; it's called "test-driven development" or "TDD":

  1. Stub out a function
  2. Write tests that expect the correct behavior
  3. Run the tests (they should fail)
  4. Write the function and keep updating it until it passes the tests

TDD is sometimes a controversial topic, and we won't dive into that here. But we will give you much more practice with writing tests in later courses.

Quiz

Tim Peters, The Zen of Python

Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one - and preferably only one - obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than right now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea - let's do more of those!