commit fd9f7f83d06bde7ff9f43ae2b494335170720ac5 Author: devfzn Date: Thu Nov 9 17:45:00 2023 -0300 init python_by_example diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c18dd8d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..faf7ef9 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# Python by Example + +Guia interactiva con la resolución de los retos propuestos en el libro +[Python by Example](https://www.google.cl/books/edition/Python_by_Example/gDGdDwAAQBAJ) +de *Nichola Lacey* + +## Retos básicos + +- [001-011](./basic/basic01.py) +- [012-019](./basic/basic02.py) +- [020-026](./basic/basic03.py) +- [027-034](./basic/basic04.py) + +## Uso + +```sh +git clone https://gitea.kickto.net/devfzn/python_by_example.git + +cd python_by_example +python main.py +``` diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/basic/__init__.py b/basic/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/basic/basic.py b/basic/basic.py new file mode 100644 index 0000000..9dd2074 --- /dev/null +++ b/basic/basic.py @@ -0,0 +1,171 @@ +from . import basic01 as ex01 +from . import basic02 as ex02 +from . import basic03 as ex03 +from . import basic04 as ex04 +from common.common import ( + print_challenges, + user_input, + run_func, + clear +) + +def challenges_sublist(): + choices = 4 + select_ok = False + while not select_ok: + clear() + selection = user_input(choices) + match selection: + case 1: + challenges01() + case 2: + challenges02() + case 3: + challenges03() + case 4: + challenges04() + case 5: + pass + case 6: + pass + case 7: + pass + case 8: + pass + case 9: + pass + case 10: + pass + case 11: + pass + case 'v': + return + case 's': + exit(0) + case _: + continue + +def challenges01(): + select_ok = False + while not select_ok: + clear() + i, ex1 = print_challenges(ex01.basics_001) + selection = user_input(i) + match selection: + case 1: + run_func(ex1.hola) + case 2: + run_func(ex1.hola2) + case 3: + run_func(ex1.pez) + case 4: + run_func(ex1.dos_nums) + case 5: + run_func(ex1.tres_nums) + case 6: + run_func(ex1.pizza) + case 7: + run_func(ex1.next_age) + case 8: + run_func(ex1.a_medias) + case 9: + run_func(ex1.tiempos) + case 10: + run_func(ex1.pounds) + case 11: + run_func(ex1.cabe) + case 'v': + return + case 's': + select_ok = True + exit(0) + case _: + continue + +def challenges02(): + select_ok = False + while not select_ok: + clear() + i, ex2 = print_challenges(ex02.basics_002) + selection = user_input(i) + match selection: + case 1: + run_func(ex2.mayor) + case 2: + run_func(ex2.muy_alto) + case 3: + run_func(ex2.gracias) + case 4: + run_func(ex2.fav_color) + case 5: + run_func(ex2.clima) + case 6: + run_func(ex2.edad_conducir) + case 7: + run_func(ex2.alto_bajo) + case 8: + run_func(ex2.uno_dos_tres) + case 'v': + return + case 's': + exit(0) + case _: + continue + +def challenges03(): + select_ok = False + while not select_ok: + clear() + i, ex3 = print_challenges(ex03.basics_003) + selection = user_input(i) + match selection: + case 1: + run_func(ex3.name_length) + case 2: + run_func(ex3.fullname_length) + case 3: + run_func(ex3.full_name_lower) + case 4: + run_func(ex3.nursery) + case 5: + run_func(ex3.any_mayus) + case 6: + run_func(ex3.mambo_name) + case 7: + run_func(ex3.pig_latin) + case 'v': + return + case 's': + exit(0) + case _: + continue + +def challenges04(): + select_ok = False + while not select_ok: + clear() + i, ex4 = print_challenges(ex04.basics_004) + selection = user_input(i) + match selection: + case 1: + run_func(ex4.decims) + case 2: + run_func(ex4.decims_round) + case 3: + run_func(ex4.square_root) + case 4: + run_func(ex4.pi_round) + case 5: + run_func(ex4.circle_area) + case 6: + run_func(ex4.cyl_vol) + case 7: + run_func(ex4.friendly_div) + case 8: + run_func(ex4.circ_trian) + case 'v': + return + case 's': + exit(0) + case _: + continue diff --git a/basic/basic01.py b/basic/basic01.py new file mode 100644 index 0000000..5ec36f3 --- /dev/null +++ b/basic/basic01.py @@ -0,0 +1,89 @@ +class basics_001: + + def hola(self): + "Ask for the user's first name and display the output message" + nombre = input("Ingresa tu primer nombre: ") + print(f"Hola {nombre}") + + def hola2(self): + """Ask for the user’s first name and then ask for their surname + and display the output message Hello [First Name] [Surname].""" + nombre = input("Ingresa tu primer nombre: ") + apellido = input("Ingresa tu apellido: ") + print(f"Hola {nombre} {apellido}") + + def pez(self): + """Write code that will display the joke \"What do you call a bear + with no teeth?\" and on the next line display the answer \"A gummy bear!\" + Try to create it using only one line of code.""" + print("¿Que es algo y nada a la vez?\nEl pez") + + def dos_nums(self): + """Ask the user to enter two numbers. Add them together and display + the answer as The total is [answer].""" + print("Ingresa dos números") + num_a = int(input("Primer número: ")) + num_b = int(input("Segundo número: ")) + print(f"{num_a} + {num_b} = {num_a+num_b}") + + def tres_nums(self): + """Ask the user to enter three numbers. Add together the first two + numbers and then multiply this total by the third. Display the answer as + The answer is [answer].""" + print("Ingresa tres números") + num_a = int(input("Primer número: ")) + num_b = int(input("Segundo número: ")) + num_c = int(input("Tercer número: ")) + res = (num_a+num_b)*num_c + print(f"({num_a} + {num_b}) x {num_c} = {res}") + + def pizza(self): + """Ask how many slices of pizza the user started with and ask how + many slices they have eaten. Work out how many slices they have left and + display the answer in a user-friendly format.""" + num_a = int(input("¿Cuantos pedazos de pizza tenías?: ")) + num_b = int(input("¿Cuantos pedazos de pizza comiste?: ")) + print(f"Aún quedan {num_a-num_b} pedazos") + + def next_age(self): + """Ask the user for their name and their age. Add 1 to their age + and display the output [Name] next birthday you will be [new age].""" + name = input("¿Cual es tu nombre?: ") + age = int(input("¿Que edad tienes?: ")) + print(f"{name} en tu próximo cumpleaños tendrás {age+1}") + + def a_medias(self): + """Ask for the total price of the bill, then ask how many diners + there are. Divide the total bill by the number of diners and show how + much each person must pay.""" + total = int(input("¿Cuanto es el total de la cuenta?: ")) + personas = int(input("¿Cuantas personas son?: ")) + print(f"Cada uno debe pagar ${total/personas}") + + def tiempos(self): + """Write a program that will ask for a number of days and then will + show how many hours, minutes and seconds are in that number of days.""" + dias = int(input("Ingresa una cantidad de días: ")) + horas = dias*24 + minutos = horas*60 + segundos = minutos*60 + print(f"{dias} Días es equivalente a {horas} horas, " + +f"o {minutos} minutos, o {segundos} segundos.") + + def pounds(self): + """There are 2,204 pounds in a kilogram. Ask the user to enter a + weight in kilograms and convert it to pounds.""" + peso = int(input("Ingresa un peso en Kilogramos: ")) + libras = peso*2.204 + print(f"{peso} kilogramos equivalen a {libras} libras") + + def cabe(self): + """Task the user to enter a number over 100 and then enter a number + under 10 and tell them how many times the smaller number goes into the + larger number in a user-friendly format.""" + num, num2 = 0, 100 + while num <= 100: + num = int(input("Ingresa un número mayor que 100: ")) + while num2 >= 10: + num2 = int(input("Ingresa un número menor que 10: ")) + print(f"{num2} cabe {num//num2} veces en {num}") diff --git a/basic/basic02.py b/basic/basic02.py new file mode 100644 index 0000000..dbc6673 --- /dev/null +++ b/basic/basic02.py @@ -0,0 +1,104 @@ +class basics_002(): + + def mayor(self): + """Ask for two numbers. If the first one is larger than the second, display + the second number first and then the first number, otherwise show the first + number first and then the second.""" + num_1 = int(input("Ingresa un número :")) + num_2 = int(input("Ingresa otro número :")) + if num_1 > num_2: + print(f"{num_2} {num_1}") + elif num_1 < num_2: + print(f"{num_1} {num_2}") + else: + print(f"{num_1} = {num_2}") + + def muy_alto(self): + """Ask the user to enter a number that is under 20. If they enter a number that + is 20 or more, display the message “Too high”, otherwise display “Thank you”.""" + num = int(input("Ingresa un número menor que 20: ")) + if num >= 20: + print("Muy Alto!") + else: + print("Gracias") + + def gracias(self): + """Ask the user to enter a number between 10 and 20 (inclusive). If they enter a + number within this range, display the message “Thank you”, otherwise display the + message “Incorrect answer”.""" + num = int(input("Ingresa un número entre 10 y 20: ")) + if 10 <= num <= 20: + print("Gracias") + else: + print("El número no es válido") + + def fav_color(self): + """Ask the user to enter their favourite colour. If they enter “red”, “RED” or + “Red” display the message “I like red too”, otherwise display the message + “I don’t like [colour], I prefer red”.""" + color = input("¿Cual es tu color favorito?: ") + match color.lower(): + case "rojo": + print(f"A mi también me gusta el {color.capitalize()}") + case _: + print(f"No me gusta el {color.capitalize()}, prefiero el Rojo") + + def clima(self): + """Ask the user if it is raining and convert their answer to lower case + so it doesn’t matter what case they type it in. If they answer “yes”, + ask if it is windy. If they answer “yes” to this second question, + display the answer “It is too windy for an umbrella”, otherwise + display the message “Take an umbrella”. If they did not answer yes + to the first question, display the answer “Enjoy your day”.""" + llueve = input("¿Está lloviendo?: ").lower() + if llueve == "si": + viento = input("¿Hay viento?: ").lower() + if viento == "si": + print("Es mala idea llevar paraguas") + else: + print("Lleva tu paraguas") + else: + print("Disfruta del día") + + def edad_conducir(self): + """Ask the user’s age. If they are 18 or over, display the message \"You + can vote\", if they are aged 17, display the message \"You can learn to + drive\", if they are 16, display the message \"You can buy a lottery + ticket\", if they are under 16, display the message \"You can go + Trick-or-Treating\".""" + edad = int(input("Ingresa tu edad: ")) + if edad >= 18: + print("Puedes votar") + if edad == 17: + print("Puedes aprender a conducir") + if edad == 16: + print("Puedes comprar un ticket de azar") + if edad < 16: + print("Puedes salir ir jugar en la arena") + + def alto_bajo(self): + """Ask the user to enter a number. If it is under 10, display the message + \"Too low\", if their number is between 10 and 20, display \"Correct\", + otherwise display \"Too high\"""" + num = int(input("Ingresa un número: ")) + if num < 10: + print("El número es muy bajo") + elif 10 <= num <= 20: + print("Correcto") + else: + print("Muy alto") + + def uno_dos_tres(self): + """Ask the user to enter 1, 2 or 3. If they enter a 1, display the message + \"Thank you\", if they enter a 2, display \"Well done\", if they enter a 3, + display \"Correct\". If they enter anything else, display \"Error message\".""" + num = int(input("Ingresa 1 , 2 o 3: ")) + match num: + case 1: + print("Gracias") + case 2: + print("Bién hecho") + case 3: + print("Correcto") + case _: + print("Error") diff --git a/basic/basic03.py b/basic/basic03.py new file mode 100644 index 0000000..c5beb0d --- /dev/null +++ b/basic/basic03.py @@ -0,0 +1,69 @@ +class basics_003: + + def name_length(self): + """Ask the user to enter their first name and then display the length of + their name.""" + name = input("Ingresa tu primer nombre: ") + print(f"{name} tiene {len(name)} letras") + + def fullname_length(self): + """Ask the user to enter their first name and then ask them to enter + their surname. Join them together with a space between and display the + name and the length of whole name.""" + name = input("Ingresa tu primer nombre: ") + surname = input("Ingresa tu apellido: ") + length = len(name) + len(surname) + print(f"\'{name} {surname}\' tiene {length} letras") + + def full_name_lower(self): + """Ask the user to enter their first name and surname in lower case. + Change the case to title case and join them together. Display the + finished result.""" + name = input("Ingresa tu primer nombre en minúsculas: ").title() + surname = input("Ingresa tu apellido en minúsculas: ").title() + print(f"{name} {surname}") + + def nursery(self): + """Ask the user to type in the first line of a nursery rhyme and display + the length of the string. Ask for a starting number and an ending number + and then display just that section of the text.""" + rhyme = input("Escribe la primera linea de una canción de cuna: ") + print("Tiene {len(rhyme)} letras") + ini_num = int(input("Ingresa un número inicial")) + end_num = int(input("Ingresa un número final")) + sel = rhyme[ini_num:end_num] + print(sel) + + def any_mayus(self): + """Ask the user to type in any word and display it in upper case.""" + anyword = input("Ingresa cualquier palabra: ").upper() + print(anyword) + + def mambo_name(self): + """Ask the user to enter their first name. If the length of their first + name is under five characters, ask them to enter their surname and join + them together (without a space) and display the name in upper case. If + the length of the first name is five or more characters, display their + first name in lower case.""" + name = input("Ingresa tu primer nombre: ") + if len(name) < 5: + surname = input("Ingresa tu apellido: ") + fullname = (name+surname).upper() + print(fullname) + else: + print(name.lower()) + + def pig_latin(self): + """Pig Latin takes the first consonant of a word, moves it to the end of + the word and adds on an \"ay\". If a word begins with a vowel you just + add \"way\" to the end. For example, pig becomes igpay, banana becomes + ananabay, and aadvark becomes aadvarkway. Create a program that will ask + the user to enter a word and change it into Pig Latin. Make sure the new + word is displayed in lower case.""" + word = input("Ingresa una palabra: ").lower() + if word[0:1] in 'aeiou': + piglatin = word+'way' + else: + piglatin = word[1:]+word[0]+'ay' + print(piglatin) + diff --git a/basic/basic04.py b/basic/basic04.py new file mode 100644 index 0000000..0522aee --- /dev/null +++ b/basic/basic04.py @@ -0,0 +1,79 @@ +class basics_004: + + def decims(self): + """Ask the user to enter a number with lots of decimal places. Multiply + this number by two and display the answer.""" + num = float(input("Ingresa un número con muchos decimales: ")) + print(num*2) + + def decims_round(self): + """Update last program so that it will display the answer to two decimal + places.""" + num = float(input("Ingresa un número con muchos decimales: ")) + numr = round(num*2, 2) + print(numr) + + def square_root(self): + """Ask the user to enter an integer that is over 500. Work out the + square root of that number and display it to two decimal places.""" + from math import sqrt + num = int("Ingresa un número entero mayor de 500: ") + root = round(sqrt(num), 2) + print(root) + + def pi_round(self): + """Display pi (π) to five decimal places.""" + from math import pi + print(round(pi,5)) + + def circle_area(self): + """Ask the user to enter the radius of a circle. Work out the area of + the circle (π*radius2).""" + from math import pi + radio = float(input("Ingresa el radio de la circunferencia: ")) + area = pi*(radio**2) + print(f"El area de la circunferencia es {round(area, 3)}") + + def cyl_vol(self): + """Ask for the radius and the depth of a cylinder and work out the total + volume (circle area*depth) rounded to three decimal places.""" + from math import pi + radio = float(input("Ingresa el radio del cilindro: ")) + largo = float(input("Ingresa el largo del cilindro: ")) + area = pi*(radio**2) + volumen = round(area*largo, 3) + print(f"El volumen del cilindro es {volumen}") + + def friendly_div(self): + """Ask the user to enter two numbers. Use whole number division to divide + the first number by the second and also work out the remainder and + display the answer in a user-friendly way (e.g. if they enter 7 and 2 + display \"7 divided by 2 is 3 with 1 remaining\").""" + num_1 = float(input("Ingresa un número: ")) + num_2 = float(input("Ingresa otro número: ")) + res_1 = num_1//num_2 + res_2 = num_1%num_2 + print(f"{num_2} cabe {res_1} veces en {num_1}, y sobran {res_2} ") + + def circ_trian(self): + """Display the following message: + 1) Square + 2) Triangle + Enter a number: + If the user enters 1, then it should ask them for the length of one of + its sides and display the area. If they select 2, it should ask for the + base and height of the triangle and display the area. If they type in + anything else, it should give them a suitable error message""" + print(" 1) Cuadrado\n 2) Triangulo\n") + choice = input(" Ingresa un número: ") + match choice: + case '1': + side = int(input("Ingresa el largo del cuadrado: ")) + print(f"El area del cuadrado es {side*side}") + case '2': + base = int(input("Ingresa la base del triagulo: ")) + altura = int(input("Ingresa la altura del triagulo: ")) + area = round((base*altura)/2, 3) + print(f"El area del triangulo rectángulo es {area}") + case _: + print("Debes escoger una opción válida") diff --git a/common/__init__.py b/common/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/common/common.py b/common/common.py new file mode 100644 index 0000000..600a021 --- /dev/null +++ b/common/common.py @@ -0,0 +1,54 @@ +import os +from time import sleep + +clear = lambda: os.system('clear') if os.name == 'posix' else os.system('cls') +tab='\n'+' '*4 + +def excp_handler(function): + def wrapper(*args, **kwargs): + try: + function(*args, **kwargs) + except Exception: + print("Lee atentamente las instrucciones e intenta nuevamente") + sleep(3) + return wrapper + +def opcs_default(): + print(""" v) Volver + s) Salir""") + +def enter_continue(): + input("\n\tPresiona Enter para continuar\n") + +@excp_handler +def run_func(func): + print(tab, func.__doc__, '\n') + func() + enter_continue() + +def user_input(i): + try: + selection = input("\n Ingresa una opción: ") + if selection in 'sSvV': + return selection.lower() + selection = int(selection) + if 0 < selection <= i: + clear() + return selection + else: + raise Exception + except Exception: + print("Debes ingresar una opción válida") + sleep(2) + return 0 + +def print_challenges(exercises): + ex = exercises() + i = 0 + funcs = list(vars(exercises))[1:-3] + while i < len(funcs): + print(f"{i+1}) ".rjust(8), end='') + print(vars(exercises).get(funcs[i]).__doc__) + i+=1 + opcs_default() + return i, ex diff --git a/main.py b/main.py new file mode 100755 index 0000000..6283cb0 --- /dev/null +++ b/main.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python + +from basic import basic +from common.common import clear, user_input, opcs_default + +def toc(): + content="""\tContenido\n + 1) Basicos 001-059 + 2) Intermedio 060-123 + 3) Tkinter 124-138 + 4) SQLite 139-145 + ... + s) Salir + """ + print(content) + +def basic_challenges(): + content = """ + 1) Basics 001-011 + 2) Basics 012-019 + 3) Basics 020-026 + 4) Basics 027-034 + 5) Basics 035-044 + 6) Basics 045-051 + 7) Basics 052-059 + """ + select_ok = False + while not select_ok: + clear() + print(content) + opcs_default() + selection = user_input(5) + match selection: + case 1: + basic.challenges01() + case 2: + basic.challenges02() + case 3: + basic.challenges03() + case 4: + basic.challenges04() + case 5: + pass + case 6: + pass + case 7: + pass + case 'v': + return + case 's': + exit(0) + case _: + continue + +def interm_challenges(): + content = """ + 1) Interm 060-068 + 2) Interm 069-079 + 3) Interm 080-087 + 4) Interm 088-095 + 5) Interm 096-103 + 6) Interm 105-110 + 7) Interm 111-117 + 8) Interm 118-123 + """ + print(content) + +def tkinter_challenges(): + content = """ + 1) Tkinter 124-132 + 2) Tkinter 133-138 + """ + print(content) + +def main(): + clear() + header = """ + ======================================= + \"Learning to Program in 150 Challenges\" + Python by example, Nichola Lacey + ======================================= + programmed by devfzn@gmail.com + ---------------------------------------\n""" + select_ok = False + while not select_ok: + clear() + print(header) + toc() + selection = user_input(5) + match selection: + case 1: + basic_challenges() + case 2: + interm_challenges() + case 3: + tkinter_challenges() + case 4: + pass + case 5: + pass + case 6: + pass + case 7: + pass + case 8: + pass + case 9: + pass + case 10: + pass + case 's': + select_ok = True + exit(0) + case _: + select_ok = False + +if __name__ == '__main__': + main()