diff --git a/Anotaciones y Comentarios/Anotaciones_sobre_Python.txt b/Anotaciones y Comentarios/Anotaciones_sobre_Python.txt new file mode 100644 index 0000000..6b70f1a --- /dev/null +++ b/Anotaciones y Comentarios/Anotaciones_sobre_Python.txt @@ -0,0 +1,35 @@ +Anotaciones importantes sobre Python + +Antes de llegar al tema de Funciones Integradas, habia estado llamando metodos al int(), float(), str() y a unos cuantos mas. Sin embargo en Python NO se les conoce como metodos, si no como funciones integradas. + +Una Funcion Integrada es aquella que nos permite cambiar de tipo de dato + +Sobre las Tuplas + +- Permiten extraer porciones, pero el resultado de la extracción es una tupla nueva + +Utilidad o ventaja respecto a las listas + +- Mas rápidas +- Menos espacio (mayor optimización) +- Formatean Strings +- Pueden utilizarse como claves en un diccionario. (las listas no) + +Pueden existir tuplas que se conocen como tupla unitaria, que es una tupla con un solo elemento, sin embargo para que esta sea una tupla unitaria despues del valor agregado a la tupla se le añade la coma (mitupla = ('Moises',)), de lo contrario no seria una tupla unitaria + +En las tuplas podemos omitir los parentesis, es decir crear la tupla de forma directa sin estos miTupla = 'Moises', 25, 09, 1990 sin embargo esto no es lo mas recomendable, ya que a futuro se puede prestar para confusiones, sin embargo se puede y a esto se le conoce como empaquetado de tuplas + +Tambien tenemos el desempaquetado de tuplas y esto es basicamente poder almacenar los valores o elementos de una tupla en diferentes variables y esto se hace de la siguiente manera: creando varias variables en una sola linea separadas por coma e igualando estas variables a la tupla, con esto Python va a saber que cada elemento de la tupla lo tiene que asignar a cada variable declarada en el orden como van de izquierda a derecha + +miTupla = ('Eliab', 'Hernandez', 25, 09, 90) +nombre, apellido, dia, mes, year = miTupla + +Con esto ultimo estamos asignando cada elemento de la tupla a la variable que le corresponde de acuerdo al orden de izq a derecha, a esto se le conoce como desempaquetado de tuplas + +Sobre los diccionarios + +- Admiten tuplas como el clave + +miTupla = ('Mexico', 'Estados Unidos', 'Canada', 'Alemania', 'Irlanda') +diccionario = {miTupla[0]:'CDMX', miTupla[1]:'Washington', miTupla[2]:'Toronto', miTupla[3]:'Berlín', miTupla[4]:'Dublin'} + diff --git a/Anotaciones y Comentarios/Prueba_PaqueteInstalado.py b/Anotaciones y Comentarios/Prueba_PaqueteInstalado.py new file mode 100644 index 0000000..090803b --- /dev/null +++ b/Anotaciones y Comentarios/Prueba_PaqueteInstalado.py @@ -0,0 +1,10 @@ +# Prueba de paquetes con modulos instalados en la pc mediante lo que se vio en el tema Paquetes Distribuibles + +# Archivo creado en la carpeta raiz y posteriormente movido a la carpeta donde se encuentra actualmente para ver su funcionamiento, y la diferencia que hay entre un paquete instalado y uno NO instalado + +from calculos.potencia_porcentaje.potencia_porcentaje import * + +op_potencia(5,3) +op_porcentaje(200,10) + +# Este archivo sigue funcionando y ejecutando el codigo utilizando el paquete y los modulos que se importaron aunque este cambio su ubicacion \ No newline at end of file diff --git a/Anotaciones y Comentarios/Prueba_PaqueteNoInstalado.py b/Anotaciones y Comentarios/Prueba_PaqueteNoInstalado.py new file mode 100644 index 0000000..4cba2f2 --- /dev/null +++ b/Anotaciones y Comentarios/Prueba_PaqueteNoInstalado.py @@ -0,0 +1,7 @@ +# Prueba de paquetes con modulos NO instalados en la pc mediante lo que se vio en el tema Paquetes Distribuibles + +# Archivo creado en la carpeta raiz y posteriormente movido a la carpeta donde se encuentra actualmente para ver su funcionamiento, el error y la diferencia que hay entre un paquete instalado y uno NO instalado + +from calculos.basicos.operaciones_basicas import * + +op_suma(5,3) \ No newline at end of file diff --git "a/Archivos Ejercicios Pildoras_Informaticas/Ejercicios Python. V\303\255deo 11.pdf" "b/Archivos Ejercicios Pildoras_Informaticas/Ejercicios Python. V\303\255deo 11.pdf" new file mode 100644 index 0000000..2270093 Binary files /dev/null and "b/Archivos Ejercicios Pildoras_Informaticas/Ejercicios Python. V\303\255deo 11.pdf" differ diff --git "a/Archivos Ejercicios Pildoras_Informaticas/Ejercicios Python. V\303\255deo 16.pdf" "b/Archivos Ejercicios Pildoras_Informaticas/Ejercicios Python. V\303\255deo 16.pdf" new file mode 100644 index 0000000..20b421f Binary files /dev/null and "b/Archivos Ejercicios Pildoras_Informaticas/Ejercicios Python. V\303\255deo 16.pdf" differ diff --git "a/Archivos Ejercicios Pildoras_Informaticas/Ejercicios Python. V\303\255deo 17.pdf" "b/Archivos Ejercicios Pildoras_Informaticas/Ejercicios Python. V\303\255deo 17.pdf" new file mode 100644 index 0000000..2980f31 Binary files /dev/null and "b/Archivos Ejercicios Pildoras_Informaticas/Ejercicios Python. V\303\255deo 17.pdf" differ diff --git "a/Archivos Ejercicios Pildoras_Informaticas/Ejercicios Python. V\303\255deo 33.pdf" "b/Archivos Ejercicios Pildoras_Informaticas/Ejercicios Python. V\303\255deo 33.pdf" new file mode 100644 index 0000000..214afbf Binary files /dev/null and "b/Archivos Ejercicios Pildoras_Informaticas/Ejercicios Python. V\303\255deo 33.pdf" differ diff --git a/Archivos_Externos.py b/Archivos_Externos.py new file mode 100644 index 0000000..41c04ec --- /dev/null +++ b/Archivos_Externos.py @@ -0,0 +1,169 @@ +# Archivos Externos --> Trabajar con ficheros externos de texto con el modulo 'io' + +""" Objetivo de trabajar con archivos externos: + + - Persistencia de datos: Es la posibilidad de guardar los datos que se han estado utilizando en la aplicacion o en el programa para que no se pierdan + + A la hora de almacenar datos tenemos dos opciones o alternativas + + Alternativas: + + - Manejo de archivos externos --> Guardar los datos en archivos externos + + - Trabajo con BBDD: Guardar la informacion o datos en base de datos """ + +""" Fases necesarias para guardar informacion en archivos externos + + - Creación + - Apertura + - Manipulación + - Cierre """ + +""" Diferencias entre el modo write (w) y el modo append (a) + + - El modo escritura nos permite añadir contenido pero este contenido sustituye el contenido actual, es decir borra el contenido que tiene actualmente el archivo para sustituirlo por el nuevo contenido que estamos definiendo en el modo write + + - El modo append nos permite añadir contenido sumandolo al contenido actual que ya tiene. El contenido que agregamos con el append se incorpora al archivo despues del contenido que este ya tiene """ + +# Esto de los archivos externos es algo confuso, pero a como lo entendi es poder crear archivos, si es que no existen utilizando codigo mediante el modulo 'io', si ya existen se pueden manipular los existentes o los que python crea al momento. Estos archivos se cierran y se abren pero ojo, esto de abrir y cerrar no es como dar doble click en el archivo para abrirlo y pulsar en la X para cerrarlo, no es esto, es abrir o cerrar el espacio en memoria para poder interactuar con ellos + +# Si el archivo no existe, python lo crea + +# Para que los cambios surtan efecto, desde que el archivo sea creado por python hasta lo que agreguemos al archivo en modo escritura es necesario ejecutar el codigo, no basta con guardar los cambios en el editor de texto, es necesario ejecutar el programa si o si + +# A continuacion podemos ver en el ejemplo las fases que corresponden a los archivos externos + +from io import open + +archivo_texto = open('archivo_texto.txt', 'w') # Creacion y apertura. Abierto en modo escritura (w) + +texto = 'Katana esta en la ventana... \nChismorreando como siempre!!!' + +archivo_texto.write(texto) # Manipulacion + +archivo_texto.close() # Cierre + +# Abrir programa en modo lectura (r) + +archivo_read = open('archivo_texto.txt', 'r') + +leer_contenido = archivo_read.read() + +archivo_read.close() + +print(leer_contenido) + +archivo_read.close() + +# Metodo readlines() --> Este metodo lo que hace es guardar la informacion en una lista. Cada linea de texto que conforma el contenido es un elemento de la lista + +archivo_read2 = open('archivo_texto.txt', 'r') + +lineas_texto = archivo_read2.readlines() + +archivo_read2.close() + +print(lineas_texto) + +archivo_read2.close() + +# Podemos hacer con esta lista devuelta por el metodo readlines lo mismo que hariamos con una lista cualquiera creada en un principio como tal + +print('---Imprimiendo el primer elemento de la lista---') +print(lineas_texto[0]) + +print('---Imprimiendo el segundo elemento de la lista---') +print(lineas_texto[1]) + +# append (a) --> Este sirve para agregar informacion a un archivo + +archivo_append = open('archivo_texto.txt', 'a') + +archivo_append.write('\nLe encanta estar asomada y sacar la cabeza') + +archivo_append.close() + +print('-----Manejo del puntero en archivos externos-----') + +# Como manejar el puntero dentro de un fichero de texto + +# Esto nos permitara trabajar solo con cierto texto del archivo + +archivo_texto2 = open('archivo_texto.txt', 'r') + +print(archivo_texto2.read()) + +# Cuando trabajamos con archivos externos estos no se comportan de la misma manera que el codigo, un ejemplo de esto es que aqui podemos ver que tenemos dos veces print con el mismo codigo en el interior de los parentesis, pero al momento de ejecutar el programa e imprimirlo en consola el segundo no se imprime, no como cuando trabajmos con codigo normal que podemos imprimir lo mismo cuantas veces queramos y esto se debe a la posicion del puntero en el archivo de texto externo que estamos leyendo e imprimiendo +print(archivo_texto2.read()) + +# Este archivo de texto al abrirlo podremos ver que el puntero se encuentra al inicio del texto, pero despues de haberlo leido una vez este puntero termina al final del texto y ahi se queda, entonces al momento de volverle a dar el siguiente print ya no nos imprime nada en consola porque en el archivo ya no hay nada que leer despues de la posicion del puntero el cual se encuentra al final del texto + +# Podemos manipular la posicion del puntero para asi conseguir trabajar o utilizar cierto contenido del texto, en este caso como tener 2 print tener algo mas que leer e imprimir al momento de ejecutar el segundo print y esto lo hacemos con el metodo seek(), el cual nos permite pasarle un valor el cual hara referencia a la posicion en la que se ubicara el puntero. Este metodo no hace que el puntero al momento de leer el archivo termine en esa posicion, si no que el puntero regrese a esa posicion despues de haber leido todo el texto. En lugar de quedarse al final del texto este se coloca en la posicion asignada en el metodo seek() + +print('-----Metodo seek()-----') + +archivo_texto2.seek(11) + +print(archivo_texto2.read()) + +# Tambien el metodo read() nos sirve para posicionar el puntero en una posicion, sin embargo hay una diferencia entre el metodo seek y el metodo read cuando lo ocupamos para posicionar el puntero y esta es que el metodo seek() lo posiciona en la ubicacion que le indiquemos, mientras read(valor) hace una lectura hasta el valor que le hayamos definido + +archivo_texto2.seek(0) # Posicione el puntero en indice 0 para que empiece la lectura al principio del archivo y no tener que comentar el seek de arriba, ya que si no posiciono el puntero al inicio, este despues de la lectura del primer seek que se encuentra arriba se quedaria al final del texto + +print('-----Metodo read(valor) para posicionar el puntero-----') + +print(archivo_texto2.read(11)) # Como podemos observar con el read(valor) lo que conseguimos es lea hasta la posicion que le hemos indicado se coloque el puntero, que en este caso es al final de la palabra 'esta', abarcando nada mas 'Katana esta' + +print(archivo_texto2.read()) # Aqui podemos ver que aunque tenemos un segundo read si nos imprime en consola texto, ya que el read anterior tiene un valor (11) y esto hace que al final de esa lectura el puntero se quede en esa posicion y por lo tanto el siguiente read() empezara a leer desde esa posicion hasta el final del texto + +# Apartir de esto podemos hacer diferentes cosas como posicionar el puntero en medio del texto, como hariamos esto? + +archivo_texto2.close() + +print('---Archivo texto 3---') + +archivo_texto3 = open('archivo_texto.txt', 'r') + +archivo_texto3.seek(len(archivo_texto3.read())/2) + +print(archivo_texto3.read()) + +archivo_texto3.close() + +print('---archivo texto 4---') + +archivo_texto4 = open('archivo_texto.txt', 'r') + +archivo_texto4.seek(len(archivo_texto4.readline())) + +print(archivo_texto4.read()) + +archivo_texto4.close() + +print('---archivo texto 5---') + +archivo_texto5 = open('archivo_texto.txt', 'r+') # Abierto en modo lectura y escritura + +archivo_texto5.write('Inicio del texto') # Estos cambios los podemos ver si abrimos el archivo desde la carpeta donde se encuentra + +archivo_texto5.close() + +print('---archivo texto 6---') + +archivo_texto6 = open('archivo_texto.txt', 'r+') + +# print(archivo_texto5.readlines()) + +lista_texto = archivo_texto6.readlines() + +lista_texto[1] = 'Dandose un llegue de aire fresco \n' + +print(lista_texto) + +archivo_texto6.seek(0) + +archivo_texto6.writelines(lista_texto) + +print(archivo_texto6.read()) + +archivo_texto6.close() \ No newline at end of file diff --git a/Bucle_For.py b/Bucle_For.py new file mode 100644 index 0000000..ad08679 --- /dev/null +++ b/Bucle_For.py @@ -0,0 +1,84 @@ +# Bucle For + +# Al igual que el bucle While, el bucle For es un ciclo donde mientras se cumpla la condicion asignada este se ejecutara las veces que sea necesario, al momento de que se deje de cumplir la condicion, este se detendra y dejara de ejecutarse + +# El Bucle For es un bucle con un numero determinado de iteraciones, ya que de antemano vamos a saber cuantas veces se va a repetir + +# El bucle for trabaja en conjunto con colecciones, ya que son estas las que ocupara para recorrer y hacer las iteraciones o repeticiones. Este bucle esta conformado por un iterador o variable iteradora (i, o cualquier otro nombre, sin embargo normalmente se ocupa la letra i para este un iterador) seguido de la palabra in y posteriormente la coleccion a recorrer + +for i in [1,'Moises',3,4,'Hernandez',True]: + print('Hola Mundo') + +# Y bueno que fue lo que hizo el bucle for en lo anterior? Lo que hizo fue que recorrio la lista elemento por elemento, y al momento de que el iterador (i) fue recorriendo elemento por elemento, por cada elemento que recorria imprimia el Hola Mundo, es por eso que decimos que en el bucle for sabemos cuantas iteraciones va a hacer + +# La variable iteradora toma el valor de cada elemento que recorre + +# La coleccion a recorrer se puede poner de forma directa o bien estar en una variable y ser esta variable la que se ponga en el bucle for + +coleccion = [1,'Eliab',2,3,'Lopez',4] + +for i in coleccion: + print(f'Elemento del iterador {i}') + +# El ciclo for funciona con cualquier tipo de coleccion, listas, tuplas e incluso diccionarios donde tenemos dos elementos por posicion, clave y valor. En este ultimo veremos que el comportamiento del bucle for trabaja un poco diferente + +print('***Diccionarios***') + +personas = {'Moises':31, 'Susett':29, 'Efrain':33} + +for i in personas: + print(f'Elemento del iterador {i}') # Aqui solo nos muestra la clave del diccionario + +# Si lo que queremos no es la clave si no los valores de las claves necesitamos tomar el diccionario y entre corchetes como parametros ponemos la clave, y esto al estar en un bucle for hay que recordar que la variable iteradora toma las claves, por lo tanto es el parametro que tenemos que poner entre los corchetes + +for i in personas: + print(personas[i]) # Con esto lo que conseguimos son los valores + +# Pero que pasa si lo que queremos es tanto la clave como el valor pero desglosado por medio del bucle, pues tenemos que solicitar la clave por medio de la variable iteradora seguido del valor por medio del diccionario con la clave que en este caso es el iterador + +for i in personas: + print(f'{i} --> {personas[i]}') + +# Para lo anterior hay otro metodo, el cual puede ser el mas visto, ademas de que es mas entendible y visualmente mejor. Este metodo es ocupar dos variables iteradoras, una para la clave y otra para el valor, para que al momento de llamar a cada elemento lo hagamos mediante su variable junto con el metodo intems() para el diccionario + +print('***Forma 2, con dos variables iteradoras y metodo items()***') + +for clave,valor in personas.items(): + print(f'{clave} --> {valor}') # Como podemos observar el resultado es el mismo que el anterior, sin embargo este es como mas directo, mas claro e incluso mas sencillo, ya que es mas entendible de alguna manera + +# Con el bucle for tambien se pueden recorrer cadenas, esta la estara recorriendo elemento por elemento o letra por letra de la cadena + +persona = 'Eliab' + +for i in persona: + print('Hola') # Esta imprimiendo el mensaje una vez por cada letra que contiene la cadena + +for i in persona: + print(i) + +# Podemos modificar el print para que cuando recorramos una cadena por ejemplo, todas las letras nos salgan en una sola linea, de forma normal cada letra se imprime en una linea diferente, se imprimen con un salto de linea y esto es debido a que el print de forma predeterminada cada vez que se termina de ejecutar uno genera un salto de linea, pero eso lo podemos modificar + +for i in persona: + print(i, end='.') # Con el end= cambiamos este comportamiento cada vez que el print se ejecuta a cada vuelta del ciclo y podemos ponerle como parametro un espacio, un punto, un guion etc + +# Bucle for in range - Pildoras Informaticas + +# El bucle for in range es un bucle que nos permite indicar el numero de veces que se repetira o ejecutara el codigo que tenga el cuerpo del bucle. Este almacena en su variable iteradora el indice de cada vuelta que da + +for i in range(5): + print('Hola Mundo') + +for i in range(10): + print(i) + +# El bucle for in range nos permite como su nombre lo indica marcar un rango, tanto apartir de que numero empezar como hasta que numero terminar, y ademas admite un tercer parametro el cual va a indicar de cuanto en cuanto tiene que aumentar este conteo en cada vuelta + +print('***comienza en y termina en***') + +for i in range(5,10): + print(f'El valor de la variables es: {i}') + +print('***comienza en, termina en, contando cada cuanto***') + +for i in range(5,20,3): + print(f'El valor de la variables es: {i}') \ No newline at end of file diff --git a/Bucle_While.py b/Bucle_While.py new file mode 100644 index 0000000..5f1115d --- /dev/null +++ b/Bucle_While.py @@ -0,0 +1,91 @@ +# Bucle While + +# En pocas palabras los bucles son ciclos que mientras se cumpla la condicion que se les asigna estos se siguen ejecutando, en el momento que deje de cumplirse la condicion, este se detiene y deja de ejecutarse. Esto aplica para cualquier bucle o ciclo + +# El bucle while se conoce por ser un bucle con un numero indeterminado de iteraciones, esto quiere decir que se puede repetir x cantidad de veces, todas las que sean necesarias o ninguna vez, dependiendo de si se cumple la condicion o no + +import math + +numero = int(input('Digite un número: ')) + +while numero < 0: + print('Error: El numero a digitar tiene que ser positivo') + numero = int(input('Digite un número: ')) + +print(f'\nLa raiz cuadrada es: {math.sqrt(numero):.2f}') + +# Podemos ocupar variables iteradoras para cumplir un determinado numero de repeticiones en un bucle + +print('***Bucle 1***') + +i = 0 + +while i < 5: + print('Hello World') + i += 1 + +# Con el siguiente bucle imprimimos el numero de vueltas que da el ciclo mientras la condicion se cumpla, por lo tanto me imprime hasta el numero 4, ya que al momento de llegar al 5 la condicion se cumple y ahi ya no se ejecuta el bucle y ya no imprime el 5 + +print('***Bucle 2***') + +i = 0 + +while i < 5: + print(i) + i += 1 + +# Si lo que queremos es que por ej se imprima del 1 al 5, tenemos que cambiar la condicion, al igual que el valor de la variable, ya que la primera impresion es con el valor inicial de la variable debido a que la primer vuelta antes del primer aumento a la variable iteradoradora tambien cuenta + +print('***Bucle 3***') + +i = 1 + +while i <= 5: # Le tenemos que especificar <= ya que aunque queremos que en cuanto llegue al 5 se detenga, si solo igualamos a 5 (i == 5), este bucle no se ejecutaria, debido a que como empezamos con el valor de 1, la variable i nunca valdria 5, debido a que como solo hay aumento de la variable si vale 5 y no puede llegar a este 5 sin tener aumento pues jamas entraria al bucle + print(i) + i += 1 + +# Informacion adicional del Bucle While - Pildoras Informaticas + +# Como podemos hacer que el Bucle While en ciertos casos no sea un bucle infinito? Ej si tenemos un programa donde nos pida la edad del usuario y este lo limitamos con un bucle while para que la edad este entre 5 y 100 y el usuario se empeña en meter un dato menor a 5 o mayor a 100 el bucle se repetiria de forma infinita ya que el usuario no pasaria nunca un valor entre 5 y 100. Hay una manera de que este bucle pare en cierto punto y es mediante el break. El break lo que hace es decirle al bucle que se rompa y se salga de este. Veamos esto con un ejemplo practico para entenderlo + +print('Programa validación edad del usuario') + +edad = int(input('Introduce tu edad: ')) +intentos = 0 + +while edad < 5 or edad > 100: + error = 'Edad incorrecta. Vuelve a intentarlo' + print(error) + intentos += 1 + edad = int(input('Introduce tu edad: ')) + if intentos == 5: + print('Edad inválida. Haz alcanzado el límite de intentos') + break +if intentos < 5: + print('Edad válida') + +print('Fin del programa') + +# Ejercicio realizado por el profe Juan de Pildoras Informaticas en el video del curso + +# print('Programa de calculo de raiz cuadrada') + +# numero = int(input('Introduce un numero: ')) +# intentos = 0 + +# while numero < 0: +# print('No se puede calcular la raiz cuadrada de un numero negativo') + +# if intentos == 2: +# print('Haz consumido demasiados intentos') +# break + +# numero = int(input('Introduce un numero positivo: ')) +# if numero < 0: +# intentos += 1 + +# if intentos < 2: +# solucion = math.sqrt(numero) +# print(f'La raiz cuadrada de {numero} es: {solucion}') + +# print('Fin del programa') \ No newline at end of file diff --git a/Bucles_Instrucciones - continue, pass y else.py b/Bucles_Instrucciones - continue, pass y else.py new file mode 100644 index 0000000..92cd88e --- /dev/null +++ b/Bucles_Instrucciones - continue, pass y else.py @@ -0,0 +1,50 @@ +# Las instucciones continue, pass y else se pueden utilizar tanto con los bucles for como con los while + +""" + - continue --> Salta a la siguiente iteracion del bucle. Supongamos que hay un bucle con 10 repeticiones y en la quinta esta la instruccion continue, lo que hace es saltar, brincar o ignorar esa quinta vuelta y brinca a la sexta + + - pass --> Devuelve null en cuanto se le en el interior del bucle. El bucle devolveria null, es como si no ejecutara el bucle. Esta instruccion se utiliza en casos muy especificos + + - else --> Tiene la misma funcion y el mismo proposito que el else en el condicional if, es decir, si la condicion previa al else no se cumple, se ejecutara el else """ + +# Lo que estamos viendo a continuacion es que gracias a la instruccion continue, no se esta imprimiendo la h y esto se debe no a que este ignorando a la h, si no que el continue lo que hace es ignorar el codigo que se tendria que ejecutar que se encuentre despues del continue, en este caso el print, se lo brinca y vuelve a ejecutar el bucle de forma normal + +for i in 'Python': + if i == 'h': + continue + print(i) + +# Un ejemplo del para que nos pueda servir el continue es para que si queremos contar las letras de un string podamos ignorar los espacios en blanco para NO contar los caracteres si no las letras del string + +nombre = 'Curso Pildoras Informaticas' +contador = 0 + +for i in nombre: + if i == ' ': + continue + contador += 1 + +print(contador) # El string almacenado en la variable nombre tiene 27 caracteres y 25 letras, con el codigo anterior podemos confirmar que ignoramos los espacios en blanco y solo contabilizamos el numero de letras en el string + +# La instruccion pass se utiliza en casos muy concretos que por el momento no hay algun ejemplo practico donde ocuparlo, pero se puede ocupar en funciones o clases para dejarla como nula por si se requiere o se va a implementar despues + +class miClase: + pass # Para programar mas adelante + +def miFuncion(): + pass # Para programar mas adelante + +# La instruccion pass no se suele utilizar mucho ni es muy comun verla debido a su objetivo, su funcionamiento y lo que conseguimos con esta + +# La instruccion else dentro de un bucle for o while cambia un poco en cuestion de como funciona en comparacion con un condicional. Y este cambio es que mientras el else pertenece a un condicional, este se ejecuta cuando la condicion del condicional no se cumple, mientras que en los bucles, se va a ejecutar en el momento en que el bucle termina de hacer su ejecucion o recorrido por completo, si este no termina y por alguna razon se queda a medias el else no se ejecutara en ningun momento + +email = input('Introduce tu email: ') + +for i in email: + if i == '@': + arroba = True + break +else: + arroba = False + +print(arroba) \ No newline at end of file diff --git a/Catalogo Productos b/Catalogo Productos new file mode 100644 index 0000000..39a6d97 Binary files /dev/null and b/Catalogo Productos differ diff --git a/Clientes b/Clientes new file mode 100644 index 0000000..7a9c6ff Binary files /dev/null and b/Clientes differ diff --git a/Colecciones_Colas(con listas).py b/Colecciones_Colas(con listas).py new file mode 100644 index 0000000..d878ace --- /dev/null +++ b/Colecciones_Colas(con listas).py @@ -0,0 +1,29 @@ +# Colas (con listas) + +# Las colas son una estructuras que funcionan bajo el concepto 'fifo', por su siglas en ingles 'first input, first output' --> 'el primero en entrar, el primero en salir' + +# Para crear colas en Python se puede importar el modulo collections con el deque, sin embargo se pueden simular colas con listas de la misma forma que con las pilas, al igual que las pilas los elementos que se agreguen iran al final pero con la diferencia de que en las colas al sacar elementos, el primero en salir tiene que ser el primer elemento de la cola + +# from collections import deque # Este es el modulo a importar para la creacion de colas + +filaBanco = ['Moises', 'Nahun', 'Efrain', 'Arnulfo'] + +print(filaBanco) + +# Agregando elementos al final de la cola +filaBanco.append('Lilia') +filaBanco.append('Susett') + +print(filaBanco) + +# Sacando elemento de la cola por el principio + +# De igual manera para sacar elementos utilizamos el metodo pop(), pero a este le pasamos el indice del elemento que queremos sacar, al ser una cola siempre tiene que ser el primer elemento de esta, por lo tanto el indice que pasemos como parametro del metodo pop(), siempre tendra que ser el indice 0 + +firstPerson = filaBanco.pop(0) +print(f'Atendiendo a {firstPerson}') +print(filaBanco) + +firstPerson = filaBanco.pop(0) +print(f'Atendiendo a {firstPerson}') +print(filaBanco) \ No newline at end of file diff --git a/Colecciones_Conjuntos.py b/Colecciones_Conjuntos.py new file mode 100644 index 0000000..329bb19 --- /dev/null +++ b/Colecciones_Conjuntos.py @@ -0,0 +1,168 @@ +# Conjuntos + +# Los conjuntos son un tipo de coleccion donde los elementos se agregan de forma desordenada. Donde su principal caracteristica es que no puede haber elementos duplicados + +# El conjunto se invoca mediante set(), seguido de llaves {} para la creacion del conjunto + +# Los conjuntos al igual que las listas y las tuplas pueden almacenar cualquier tipo de dato, incluso pueden almacenar datos de diferentes tipos. + +# Dentro de los conjuntos NO puede abrir otro tipo de colecciones como listas, tuplas o incluso otro conjunto + +conjunto = set() # El set sirve para especificar que sera un conjunto, ya que si solo se ponen las llaves, Python lo identifica como un diccionario. Este set se declara siempre y cuando se vaya a crear en un inicio un conjunto vacio y posteriormente se le vaya a agregar contenido con el metodo add(). Si el conjunto que se crea va a tener contenido desde un inicio, no es necesario el set(), ya que en el momento de asignar contenido al conjunto y estar separados por comas y no haber : en este, Python sabe que es un conjunto y no un diccionario + +conjunto = {1,2,3,'Hola', 4.56} + +print(conjunto) + +# Para agregar elementos a un conjunto se emplea el metodo add() + +print('*****agregar elementos*****') + +conjunto.add(5) # En los conjuntos al momento de agregar elementos no es como con las listas que el metodo mas basico para agregar añade el elemento al final, en los conjuntos al ser grupos de elementos desordenados agrega los nuevos elementos de forma aleatoria, donde el metodo quiera + +print(conjunto) + +conjunto.add('Adios') +conjunto.add('z') + +print(conjunto) + +# Para eliminar elementos se emplea el metodo discard(). A este se le pasa como parametro directamente el elemento a eliminar + +print('*****eliminar elementos*****') + +conjunto.discard('Adios') + +print(conjunto) + +# De igual manera podemos limpiar o vaciar el conjunto con el metodo clear() + +conjunto.clear() + +print(conjunto) # Como podemos observar aqui cuando corremos el programa no nos quedas las llaves vacias, si no que directamente podemos ver que nos arroja el set(), que es como que la base del conjunto y apartir de este set(), de esta base ya creamos el conjunto con las llaves + +# Tambien se puede buscar un elemento en especifico con el in + +print('*****existencia de elementos*****') + +conjuntoUno = set() +conjuntoUno = {1,2,3,'Hello', 'World'} + +print(3 in conjuntoUno) +print('Hello' in conjuntoUno) +print('Mundo' in conjuntoUno) + +# Tambien se pueden generar negaciones en el in + +print('*****negacion en el in*****') + +print('World' not in conjuntoUno) +print(5 not in conjuntoUno) + +# A continuacion creamos un conjunto sin la necesidad del set(), debido a que desde la creacion inicial del conjunto se esta creando con contenido + +# Se pueden comparar dos conjuntos para saber si son iguales y tienen el mismo contenido. Esto regresara un valor de tipo booleano como resultado + +conjunto2 = {1,2,3} +conjunto3 = {3,4,5} + +print('****Igualdad entre conjuntos****') + +print(conjunto2 == conjunto3) # Aqui vemos que nos da como resultado False debido a que claramente no tienen el mismo contenido, pero que pasa si tuvieran el mismo contenido aunque fuera en diferente orden??? + +conjA = {1,2,3} +conjB = {2,1,3} + +print(conjA == conjB) # Pues como se puede observar en el resultado este da True debido a que aunque el contenido esta en diferente orden este es igual + +# Tambien podemos ocupar el metodo o la funcion len() para saber cuantos elementos tiene el conjunto + +print('***Metodo len()***') + +print(len(conjA)) + +# Union de dos conjuntos + +print('***Union conjuntos***') + +# Para unir o los elementos de dos conjuntos no nos vale el signo + como en las listas, para los conjuntos necesitamos el signo '|'. Esto debido a que a las listas las podemos concatenar, in embargo a los conjuntos no, a los conjuntos los juntamos y mas en concreto unimos sus elementos + +conjA = {1,2,3} +conjA = {3,4,5} + +conjC = conjA | conjB + +print(conjC) # Recordar que en los conjuntos no puede haber elementos duplicados, es por eso que el 3 al estar repetido en ambos conjuntos al momento de la union solo queda uno + +print('***Interseccion de conjuntos***') + +# La intersección son aquellos elementos que se encuentran en ambos conjuntos + +# Para la intersección se utiliza el signo de ampersan '&' + +conjC = conjA & conjB + +print(conjC) # El resultado es 3 debido a que es el unico elemento que cae en la intersección, ya que es el único elemento que se encuentra en ambos conjuntos y lo tienen en comun + +print('***Diferencia de conjuntos***') + +# La diferencia en los conjuntos son los elementos que tiene un conjunto y que no tiene el otro. Para la diferencia utilizamos el signo de guiñon medio '-'. Vaya los elementos que tiene el conjunto a con respecto a los que no tiene el conjunto b y visceversa + +conjC = conjA - conjB +print(conjC) + +conjC = conjB - conjA +print(conjC) + +print('***Diferencia simetrica***') + +# La diferencia simetrica son los elementos que se encuentran en los conjuntos pero que no estan en ambos conjuntos + +conjC = conjA ^ conjB + +print(conjC) + +# Podemos saber si un conjunto es un subconjunto o superconjunto de otro. Para que esto de como resultado True ambos conjuntos que se comparen deben tener los mismos elementos + +print('***subconjuntos y superconjuntos***') + +conjA = {1,2,3} +conjB = {3,4,5} +conjC = {1,2,3,4,5} + +print('***Subconjunto***') + +print(conjA.issubset(conjC)) +print(conjB.issubset(conjC)) +print(conjC.issubset(conjA)) + +print('***Superconjunto***') + +print(conjC.issuperset(conjA)) +print(conjC.issuperset(conjB)) +print(conjA.issuperset(conjC)) +print(conjB.issuperset(conjC)) + +# Los conjuntos disconexos son aquellos conjuntos que no tienen ni un elemento en comun + +print('***Conjuntos disconexos ***') + +conjA = {1,2,3} +conjB = {3,4,5} + +print(conjA.isdisjoint(conjB)) # El resultado el False ya que ambos conjuntos comparten al menos un elemento en comun + +# En caso contrario de no compartir ni un elemento + +conjA = {1,2,3} +conjB = {4,5,6} + +print(conjA.isdisjoint(conjB)) # El resultado es True ya que ambos conjuntos no comparten ni un elemento en comun, todos sus elementos son diferentes, por lo tanto son conjuntos disconexos + +# Tambien podemos convertir un conjunto en inmutable, como las tuplas, donde no se pueda agregar ni eliminar elementos. Esto se hace mediante el metodo frozenset() + +conjA = frozenset({1,2,3}) + +# conjA.add(4) # Si esto lo descomentamos y lo tratamos de imprimir veremos que nos arroja con error, debido a que el conjunto tiene el metodo frozenset() y por lo tanto no podemos modificarlo de ninguna manera. De echo si imprimimos un conjunto congelado veremos que en la impresion en consola nos aparece el metodo frozenset() + +print(conjA) \ No newline at end of file diff --git a/Colecciones_Diccionarios.py b/Colecciones_Diccionarios.py new file mode 100644 index 0000000..e662e57 --- /dev/null +++ b/Colecciones_Diccionarios.py @@ -0,0 +1,88 @@ +# Diccionarios + +# Son otro tipo de colección que de igual manera a los conjuntos los elementos se almacenan de forma desordenada. + +# La principal caracteristica de los diccionarios es que tienen dos elementos por posición,la clave y el valor. En estos no puede haber claves duplicadas, estas tienen que ser unicas + +# Los diccionarios tienen la caracteristica de que dos elementos de su contenido van de la mano, esto quiere decir que la clave va ligada al valor y estas se separan por dos puntos (:), estos valores por decirlo de alguna manera equivalen uno al otro, pero en otro sentido + +# Para los diccionarios basta con poner las llaves, ya que si esta vacio de entrada Python sabra que es un diccionario, y si no lo esta, de acuerdo al contenido Python sabra si es un diccionario o un conjunto, esto lo hace mediante la clave, el valor y los dos puntos que unen estos dos ultimos, mientras que en los conjuntos solo hay valores y estos estan separados por comas. En los diccionarios tanto la clave como el valor corresponden a una sola posicion, digamos que para el indice ambos cuentan como uno solo. Primero se pone la clave y depues el valor ('clave':'valor') + +diccionario = {'azul':'blue', 'rojo':'red', 'verde':'green'} + +print(diccionario) + +# Podemos mandar a llamar solo un valor del diccionario mediante su clave + +print(diccionario['rojo']) +print(diccionario['verde']) + +# Tambien podemos agregar mas elementos al diccionario, asi como modificar los elementos ya existentes. Para ambos casos se ocupa la misma forma o metodo y este es declarando el diccionario, entre corchetes y asignando el nuevo valor para el nuevo elemento o el nuevo valor para el elemento ya existente + +diccionario['azul'] = 'BLUE' # Aqui lo unico que estoy cambiando es el nombre a puras mayusculas. Estoy modificando un elemento ya existente +diccionario['amarillo'] = 'yellow' # Aqui estoy agregando un nuevo elemento + +print(diccionario) + +# Tambien podemos eliminar elementos del diccionario y para este usamos la funcion del(), la cual lleva como parametro el diccionario al cual le vamos a eliminar un elemento y dentro de corchetes el elemento a eliminar + +del(diccionario['amarillo']) + +print(diccionario) + +# Los diccionarios al igual que otra colecciones pueden almacenar cualquier tipo de dato y tambien estos datos de diferente tipo pueden estar en un mismo diccionario + +personalEmpresa = {'Moises':{'edad':31,'sexo':'masculino', 'estatura':1.76}, 'Nahun':[48,'Arquitecto'], 'Efrain':[33,1.83]} + +print(personalEmpresa) +print(personalEmpresa['Moises']) +print(personalEmpresa['Nahun']) +print(personalEmpresa['Efrain']) + +print('*****Diccionarios Parte II*****') + +motoGP = {46:'Valentino Rossi', 93:'Marc Márquez', 99:'Jorge Lorenzo', 26:'Dani Pedrosa'} + +print(motoGP) +print(motoGP[93]) # En los diccionarios es importante no confundir la clave con el indice, ya que cuando queremos solicitar un elemento en especifico del diccionario, utilizamos corchetes y dentro de estos anotamos la clave del elemento que queremos ver y esto se puede prestar para una confusion pensando que estamos diciendole al programa que queremos el elemento en el indice 99 por ejemplo en este caso, cuando no es asi, mas bien el 99 corresponde a la clave de un elemento que se encuentra dentro del diccionario +print(motoGP[46]) + +# Hay dos maneras de mostrar u obtener la informacion del contenido de un diccionario. La primera es poniendo directamente entre corchetes la clave del elemento, sin embargo con esta forma, necesitas estar seguro del contenido del diccionario y de que la clave que estas poniendo existe y pertenece a un elemento, de lo contrario estaria arrojando un error, ya que no estaria encontrando la clave ni ningun valor correspondiente a esta + +# La segunda manera es mediante el metodo get() y la ventaja de este metodo es que si no existe la clave que estamos solicitando podemos hacer una anotacion o poner un mensaje el cual se nos estaria mostrando al momento de no encontrar la clave solicitada y estariamos evitando como tal el error + +print('*****Obtencion de datos mediante corchetes y metodo get()*****') + +print(motoGP[99]) +# print(motoGP[4]) # Como podemos ver al momento de ejecutar esta linea, la consola nos arroja un error debido a que no encuentra esa clave dentro del diccionario +print(motoGP.get(26, 'No existe ese numero de piloto')) +print(motoGP.get(4, 'No existe ese numero de piloto')) +print(motoGP.get(29, 'No existe ese numero de piloto')) # En los ultimos dos casos vemos que aunque no existe la clave 4 y 29 dentro de nuestro diccionario al momento de ejecutar la consola no nos esta arrojando ningun error como en el caso anterior que esta comentado, si no que por el contrario nos arroja el mensaje que pusimos en el metodo get si este no encontraba la clave solicitada, esto hace que el programa no se detenga por un error + +# Podemos utilizar el metodo in como en las listas etc para buscar o confirmar la existencia de un elemento dentro de nuestro diccionario + +print(46 in motoGP) +print(93 in motoGP) +print(4 in motoGP) + +print('*****Solicitud de claves o valores*****') + +# Tambien podemos realizar busquedas o mas que busqueda solicitar que claves o valores contiene nuestro diccionario, en lugar de que nos salga todo el contenido, nos mostraria uno en especifico, ya sea las claves o los valores existentes, dependiendo de lo solicitado + +# Esto lo hacemos mediante los metodos keys() para las claves y values() para los valores + +print(motoGP.keys()) # El metodo key() nos muestra todas las claves del diccionario, solo las claves +print(motoGP.values()) # El metodo values() nos muestra todos los valores del diccionario, solo los valores + +# De igual forma podemos solicitar el contenido completo poniendo el nombre del diccionario, pero tambien lo podemos hacer mediante el metodo items(), el cual nos mostrara todo los elementos, pero este lo hara en forma de lista y cada elemento conformado por su clave y valor en un tupla + +print(motoGP.items()) # Como se menciono anteriormente todos el contenido del diccionario se encuentra en una lista pero cada clave con su valor esta almacenado en una tupla + +# Tambien podemos ocupar el metodo len() para saber cuantos elementos conforman el diccionario + +print(len(motoGP)) + +# Podemos ocupar el metodo clear() para limpiar y vaciar el diccionario + +motoGP.clear() +print(motoGP) \ No newline at end of file diff --git a/Colecciones_Listas.py b/Colecciones_Listas.py new file mode 100644 index 0000000..beb98a6 --- /dev/null +++ b/Colecciones_Listas.py @@ -0,0 +1,172 @@ +# Listas + +# Las listas son estructuras de elementos muy flexibles ya que nos permiten almacenar cualqier tipo de datos en ellas y no necesariamente de un tipo de dato en concreto, podemos almacenar diferentes tipos de datos en la misma lista. + +# Las listas en Python son el equivalente a los arreglos (arrays) en otros lenguajes de programacion. + +# Podemos almacenar cadenas, enteros, flotantes, booleanos, otras listas etc y estan se crean a partir de corchetes [] + +lista = ["Lunes", "Martes", "Miercoles", "Jueves", "Viernes"] + +print(lista) + +# Podemos recorrer las listas como cualquier otro arreglo, sin olvidar que al igual que en los arrreglos los elementos de las listas comienzan a contabilizarse en el indice 0 su primer elemento. Podemos indicar desde que posicion queremos empezar y hasta que posicion queremos finalizar, esto lo hacemos mediante :. Si no le especificamos alguno de los dos parametros estara empezando desde el inicio o bien terminando hasta el final. + +# De igual manera podemos empezar desde el final hacia el inicio especificandolo con numeros negativos, donde -1 es el ultimo elemento de la lista y hacia atras siguen los siguientes elementos -2, penultimo elemento, -3 antepenultimo elemento y asi sucesivamente + +print(lista[0]) +print(lista[-1]) +print(lista[-4]) + +print(lista[0:3]) # Al indicar hasta donde queremos que nos muestre es importante recordar que nos va a mostrar un elementos antes del numero que le especifiquemos, por ej en este caso, le estamos diciendo que llegue hasta el elemento con el indice 3, sin embargo no es este elemento hasta donde llegara o el ultimo que nos mostrara, ya que llega uno antes, por lo tanto nos estara mostrando hasta el elemento con el indice 2 +print(lista[1:4]) +print(lista[:3]) +print(lista[3:]) + +# Como se menciono anteriormente se pueden crear listas con diferentes tipos de datos en una misma + +lista2 = ['Moises', 'Hernandez', 31, 8.5, True, ['facebook', 25, 90, 5555555]] + +print(lista2) + +#Podemos saber el numero de elementos de una lista con el metodo len() + +print('****lenght****') + +listaUno = [1,2,3,4,5] + +print(len(lista2)) # Las listas dentro de listas cuentan como un solo elemento +print(len(listaUno)) + +# Podemos agregar elementos a las listas. Para esto hay 3 diferentes metodos + +""" Metodos para agregar elementos + append() - Agrega un elemento al final de la lista + insert() - Inserta un elemento en la lista. Este nos permite agregarlo en el lugar que queramos. Requiere de dos parametros, el primero es el numero de indice donde queremos insertar el elemento y el segundo el elemento a insertar + extend() - Nos permite agregar varios elementos al final de la lista, para esto necesitamos capturar estos elementos en forma de lista [] ej extend([1,2,3]) """ + +print('****agregar elementos****') + +print(listaUno) + +listaUno.append(7) + +print((listaUno)) + +listaUno.insert(5, 6) + +print(listaUno) + +listaUno.extend([8,9,10]) + +print(listaUno) + +# Tambien podemos sumar o concatenar 2 listas + +print('****concatenar listas****') + +listaDos = [11,12,13,14,15] +listaTres = listaUno + listaDos # Aqui estamos concatenando dos listas y la listaUno se concatena junto con todos los cambios que se le realizaron atravez del programa, con los elementos desde el 1 hasta el 10 + +print(listaTres) + +# Podemos saber si un elemento se encuentra en una lista o no con el metodo in. Este nos retornara un valor booleano, ya sea True o False + +print('****elemento existente en la lista****') + +listaUno = [1,2,3,4,5, 'Eliab'] + +print(5 in listaUno) +print('Eliab' in listaUno) +print('Hernandez'in listaUno) + +# Tambien podemos saber el numero del indice de 'x' elemento con el metodo index(). Este metodo como se describio anteriormente nos arrojara como resultado el indice del elemento en cuestion + +print('****numero de indice de un elemento****') + +print(listaUno.index(3)) +print(listaUno.index(5)) +print(listaUno.index('Eliab')) + +listaUno.extend([6,7,8,9,10]) + +print(listaUno.index(10)) +# print(listaUno.index(11)) # Cuando se le pasa un elemento que no existe en la lista nos arroja un error, pero este error claramente nos especifica que el elemento no existe en la lista + +# Tambien podemos saber cuantas veces se repite un elemento dentro de una lsita. Esto lo hacemos con el metodo count() + +print('****numero de veces de un elemento en la lista****') + +lista = [1,2,3,4,5,'Eliab',1,2,3,'Eliab',1,3,5] + +print(lista.count(1)) +print(lista.count('Eliab')) +print(lista.count(3)) +print(lista.count(4)) +print(lista.count(5)) +print(lista.count(10)) + +# Tambien podemos eliminar elementos de una lista, con los metodos pop(), remove() y clear() + +""" Metodos para eliminar elemenetos de una lista + pop() - Elimina un elemento a la vez, si no se le pasa ningun parametro, este metodo eliminara el ultimo elemento elemento de la lista. El parametro que recibe o se le puede pasar es el indice del elemento que queremos eliminar. + remove() - Elimina el elemento que le pasemos como parametro. Asi que el parametro que recibe es directamente el elemento que queremos eliminar + clear() - Elimina todos los elementos de la lista. Limpia la lista y la deja vacia """ + +print('****eliminar elementos****') + +lista = [1,2,3,4,5,'Eliab',1,2,3,'Eliab',1,3,5] + +lista.pop() +print(lista) +lista.pop(2) +print(lista) +lista.remove('Eliab') # Si hay varios elementos iguales en una lista, al momento de remover alguno de estos elimina el primero que encuentra +print(lista) +lista.clear() +print(lista) + +# Se puede invertir el sentido de la lista + +print('****invertir / voltear lista****') + +lista = [1,2,3,'Meraxes'] + +lista.reverse() + +print(lista) + +# Podemos duplicar el contenido de la lista, en el mismo orden que se encuentra las veces que desemos + +print('****duplicar contenido****') + +lista = [1,2,3,'Meraxes']*2 + +print(lista) + +lista = [1,2,3,'Meraxes']*3 + +print(lista) + +# Algo que tambien podemos hacer y que podria resultar bastante util seria ordenar los elementos de una lista. Este metodo sirve siempre y cuando los elementos sean de tipo numerico + +print('****ordenar elementos****') + +lista = [5,4,-6,9,0,1,2] + +lista.sort() # El metodo sort ordena los elementos de forma ascendente + +print(lista) + +# Que pasa si queremos ordenar los elementos de forma descendente. Pues solo aplicamos un reverse +lista.sort(reverse=True) + +print(lista) + +# Veamos que pasa cuando hay otro tipo de dato que no sea numerico + +listaPrueba = ['World', 'Hello', 5, 3, 1, -10] + +# listaPrueba.sort() # No se puede ocupar el metodo sort() cuando la lista contiene datos que no son numericos, marca error!!! + +# print(listaPrueba) \ No newline at end of file diff --git a/Colecciones_Pilas(con listas).py b/Colecciones_Pilas(con listas).py new file mode 100644 index 0000000..3d0d05d --- /dev/null +++ b/Colecciones_Pilas(con listas).py @@ -0,0 +1,36 @@ +# Pilas + +# Las pilas son estructuras de datos conocida como lifo. En Python no hay una manera de trabajar con pilas de forma directa como tal, no se pueden crear pilas asi como se crean listas, tuplas o diccionarios, sin embargo se pueden simular de una manera muy sencilla con listas + +# A las pilas tambien se les conoce como lifo por sus siglas en ingles que significan 'last input, first output' --> 'ultimo en entrar, primero en salir', es el concepto con el que se le conoce a la forma en que trabajan las pilas + +pila = [1,2,3] + +# Tanto para agregar como para sacar elementos de una pila creada a partir de una lista se hace mediante le concepto lifo, esto quiere decir que al agregar tenemos que agregar el elemento nuevo al final y para eliminar el primer elemento a eliminar tiene que ser el ultimo elemento de la lista, el agregado al ultimo + +# Agregando elementos al final + +pila.append(4) +pila.append(5) +pila.append(6) +pila.append(7) + +print(pila) + +# Sacando elementos del final + +pila.pop() +print(pila) + +pila.pop() +print(pila) + +# Hay que saber que el metodo pop() aparte de sacar el elemento, tambien lo retorna para que se pueda trabajar con el. Normalmente cuando se saca un elemento de una pila es para y porque se va a trabajar con el de alguna u otra manera, por lo tanto esta disponible este elemento al momento de sacarlo con el metodo pop() + +eleRet = pila.pop() +print(f'Elemento retirado de la pila --> {eleRet}') + +eleRet = pila.pop() +print(f'Elemento retirado de la pila --> {eleRet}') + +print(pila) \ No newline at end of file diff --git a/Colecciones_Tuplas.py b/Colecciones_Tuplas.py new file mode 100644 index 0000000..2232c3d --- /dev/null +++ b/Colecciones_Tuplas.py @@ -0,0 +1,42 @@ +# Tuplas + +# Las tuplas son otro tipo de Colecciones, estas son muy parecidas a las Listas, las diferencias radican en dos puntos. El primero es que estan se generan entre parentesis () y la segunda es que son inmutables, es decir, no se pueden modificar de ninguna manera, esto quiere decir que no vamos a poder agregar, modificar y/o eliminar elementos + +# Las listas y las tuplas son como las variables y las constantes en JavaScript, donde la variable puede empezar teniendo un valor y a medida que avanza el programa cambiar su valor, a diferencia de las constantes, las cuales no puede cambiar su valor y todo el programa se queda con el valor asignado desde el principio. En las listas y las tuplas en Python es lo mismo, donde las listas vendrian siendo las variables y poder cambiar y modificar sus elementos y su contenido, mientras las tuplas son las constantes y estas no puede sufrir alteracion alguna y se quedan con los valores asignados inicialmente durante todo el programa + +tupla = (4, 'Hola', 6.78, [1,2,3], 4) + +# tupla[0] = 8 # Esto seria una forma de modificar un elemento de una lista, sin embargo en la tuplas esto no es posible, si lo descomentamos y corremos el programa veremos que esto nos da un error + +print(tupla) +print(tupla[1]) + +# Con las tuplas se pueden usar los mismo metodos que con las listas, metodos como len(), index(), count(), buscar por medio del in, seleccionar apartir de que elemento y hasta que elemento queremos ver etc... + +print(4 in tupla) +print('Hola' in tupla) +print(tupla[1:4]) +print(len(tupla)) +print(tupla.index(6.78)) +print(tupla.index('Hola')) +print(tupla.count(4)) + +tupla2 = ('moises', 'hernandez')*2 + +print(tupla2) + +# Adicionalmente se pueden convertir tuplas en listas y listas en tuplas + +tuplaUno = ('Tupla', 'de', 'Prueba') +print(tuplaUno) + +listaUno = list(tuplaUno) +print(listaUno) + +listaDos = ['Lista', 'de', 'Prueba'] +print(listaDos) + +tuplaDos = tuple(listaDos) +print(tuplaDos) + +# Para efectos de ejecucion, las tuplas son mas rapidas y no consumen tantos recursos como las listas \ No newline at end of file diff --git a/Condicionales_Combinados.py b/Condicionales_Combinados.py new file mode 100644 index 0000000..d23bba7 --- /dev/null +++ b/Condicionales_Combinados.py @@ -0,0 +1,48 @@ +# Condicionales Combinados y Anidados + +# Los condicionales pueden trabajar en conjunto con otros condicionales ademas de que pueden tener otros condicionales dentro, a estos se les conocen como condicionales anidados + +edad = int(input("Digite su edad: ")) + +if edad >= 18: + print("Es mayor de edad") +else: + print("NO es mayor de edad") + +# Pero que pasa si el usuario nos pasa un valor negativo? Pues como no se esta cumpliendo la primera condicion no arojaria que es menor de edad, pero no es posible que una edad se un numero negativo, por lo tanto tendriamos que usar condicionales anidados (un condicional dentro de otro condicional) + +# Tambien queremos que si el usuario nos pasa un numero bastante alto, que si bien es valido, no seria creible como para una edad, ej 150 o 200, ya no hay persona que tenga esa edad, asi que necesitamos marcar un limite. Para esto hay 2 maneras. La primera es con los Operadores Logicos y la segunda con los Operadores Relacionales, esta segunda es la mas rapida y practica forma de hacerlo. Veamos ambas maneras + +# La siguiente forma es una manera de combinar condicionales utilizando operadores logicos + +edad2 = int(input("Digite su edad: ")) + +if edad2 > 0 and edad2 < 100: + print('Edad correcta') + if edad2 >= 18: + print('Es mayor de edad') + else: + print('NO es mayor de edad') +elif edad2 == 0: + print('El numero 0 no es valido') +else: + print('El valor ingresado no es valido') + +# La siguiente forma es una manera de combinar condicionales utilizando operadores relacionales combinado. Ademas de ser la forma mas practica y rapida. En esta forma lo que estamos haciendo es una comparacion de valores de forma consecutiva. En teoria es lo mismo que el ejemplo anterior, solo que este es mas practico y directo + +edad3 = int(input('Digite la edad del sujeto #3: ')) + +if 0 < edad3 < 100: + print('Edad valida') + if edad3 >= 18: + print('El sujeto #3 es mayor de edad') + else: + print('El sujeto #3 NO es mayor de edad') +elif edad3 == 0: + print('El numero "0" no es válido') +elif edad3 < 0: + print('Error: Edad incorrecta') +else: + print('El dato ingresado no es válido') + +# En python no existen los condicionales multiples, tambien conocidos como switch (tal es el caso como en JavaScript), podemos llegar al mismo resultado pero de diferente manera, por medio de otra ruta \ No newline at end of file diff --git a/Condicionales_Estructura_if_elif_else.py b/Condicionales_Estructura_if_elif_else.py new file mode 100644 index 0000000..38f1c12 --- /dev/null +++ b/Condicionales_Estructura_if_elif_else.py @@ -0,0 +1,21 @@ +# Condicionales + +# Los condicionales nos sirven para evaluar y comparar datos y valores, que de acuerdo a cierta instruccion, resultado o sentencia se ejecute "x" accion. Estos condicionales comparan dos valores para determinar que accion llevar a cabo. En pocas palabras actuan de la siguiente manera... + +""" + "si (if)" se cumple esta condicion --> ejecuta esta accion + "si no, si (elif)" se cumple esta condicion --> ejecuta esta accion (Este se vendria ocupando cuando vamos a tener varias condiciones diferentes, es decir que si no es una, es otras y si no otras y asi sucesivamente) + "si no (else)" --> ejecuta esta accion (si no se cumplio ninguna de las anteriores) (Este seria el utimo a poner, quiere decir que llevara la ultima condicion, ya no habra mas condicionales despues de este) +""" + + +numero = int(input("Digite un numero: ")) + +if numero > 0: + print("El numero es positivo") +elif numero == 0: + print("El numero es 0") +else: + print("El numero es negativo") + +print('Fin del programa') \ No newline at end of file diff --git a/DataBase/BBDD I - Bases de Datos.py b/DataBase/BBDD I - Bases de Datos.py new file mode 100644 index 0000000..8a525a0 --- /dev/null +++ b/DataBase/BBDD I - Bases de Datos.py @@ -0,0 +1,105 @@ +# BBDD I / Bases de Datos - Pildoras Informaticas / Videos 55 y 56 + +# SQL (Structured Query Language) --> Es el lenguaje de las bases de datos, con este es posible manejar base de datos con cualquier lenguaje de programacion + +""" Creación de BBDD + - Conexión con BBDD + - Inserción de registros en BBDD + + SGDB (system gestor database) y Python + Python es capaz de trabajar con diferentes gestores de base de datos como por ejemplo + - SQL Server + - Oracle + - MySQL + - SQLite + - PostgreSQL + - Etc... """ + +""" SQLite + - Sistema de gestion de BBDD relacional + - Escrito en C, es de codigo abierto + - Forma parte integral del programa + - Se guarda como un unico fichero en host + + Ventajas + - Ocupa muy poco espacio en disco y memoria + - Muy eficiente y rapido + - Multiplataforma + - Sin administracion / configuracion + - Dominio publico. Sin costo + + Desventajas + - No admite clausulas anidadas (where) + - No existen usuarios (no acceso, simultaneo por parte de varios usuarios a la vez) + - Falta de clave foranea cuando se crea en modo consola """ + +""" Pasos a seguir para conectar con BBDD + + 1.- Abrir / Crear conexion + 2.- Crear puntero: El puntero es un objeto que se crear que nos permitira hacer 2 cosas; ejecutar querys / consultas y manejar los resultados, es decir nos permitira hacer los pasos 3 y 4 + 3.- Ejecutar query (consulta) SQL + 4.- Manejar los resultados de la query (consulta) + - Insertar, Leer, Actualizar, Borrar (Create, Read, Update, Delete) - CRUD + 5.- Cerrar puntero + 6.- Cerrar conexion """ + +# No es necesario poner las instrucciones de sql en mayusculas, lo estoy haciendo asi ya que estoy siguiendo la forma en que lo hace el profe y el tiene la maña de poner las instrucciones de sql en mayusculas, pero hay que tener claro que esto no forzosamente tiene que ser asi + +# A los datos o la informacion de la base de datos tambien se le conocen como registros + +import sqlite3 + +conexion = sqlite3.connect('Date Base 1') # Aqui generamos la conexion con la base de datos. Si esta base no llegara a existir, con esto mismo se estaria creando la base de datos, asignandole el nombre que hemos definido + +puntero = conexion.cursor() # Creamos el cursor o puntero + +# puntero.execute('CREATE TABLE PRODUCTOS (NOMBRE VARCHAR(50), PRECIO INTEGER, CATEGORIA VARCHAR(20))') # Creamos la tabla que va a contener la base de datos y que almacenara los datos que vayan dentro de esta tabla. Esta despues de crearla y ejecutar el programa para que se cree y se vea reflejada en la base de datos despues de guardar el archivo y ejecutar hay que comentar la linea, quitarla o lo que sea pero esta linea de codigo no tiene que volverse a ejecutar ya que estaria arrojando un error al momento de correr el programa + +# varchar = cadena de texto o string y el valor entre parentesis hace referencia al numero maximo de caracteres que podra tener esta string + +# integer = valor de tipo numerico + +# puntero.execute('INSERT INTO PRODUCTOS VALUES("CAJA PAPEL BOND TAMAÑO CARTA MARCA SCRIBE", 980, "Papel Bond")') # Agregamos datos o informacion a la tabla. + +# Posterior a esto hay que decirle al programa que vamos a aceptar los cambios o modificaciones que estamos generando y esto lo hacemos mediante el metodo commit() + +# Se pueden insertar lotes de registros utilizando listas y tuplas (con lotes de registros nos referimos a varios datos a la vez), y esto lo hacemos de la siguiente manera + +# Creamos una lista con tuplas dentro que contendran los datos qe vamos a añadir a la tabla de la base de datos + +# listaProductos1 = [ +# ('Cinta de empaque trasnparente', 55, 'Cintas'), +# ('Playo Calibre 60', 180, 'Playo'), +# ('Hielera de Unicel', 30, 'Unicel') +# ] + +# Posteriormente tenemos que agregar esta lista con los datos a la base de datos + +# puntero.executemany('INSERT INTO PRODUCTOS VALUES (?,?,?)', listaProductos1) # Utilizamos el metodo executemany que nos sirve para agregar una lista con datos en forma de tupla, de ahi el many que es agregar o executar 'muchos' y en el valor tenemos que poner entre parentesis un signo de ? por cada dato que contenga cada tupla, en este caso son 3 que corresponden a nombre, precio y categoria, seguido del nombre de la lista que queremos agregar + +puntero.execute('select * from productos') # De esta manera leemos informacion de la base de datos. Con esto leemos la informacion pero no la vemos, para ver la informacion tenemos que hacer lo siguiente + +# Ahora para ver la informacion que estamos leyendo de la base de datos tenemos que crear una variable la cual almacenara una lista la cual va a contener los registros leidos de la base de datos y esta a su vez como lo mencionamos anteriormente se tiene que almacenar en algun sitio y este sitio es una variable + +listaProductos = puntero.fetchall() # Recuperamos la informacion que se encuentra en la base de datos + +for p in listaProductos: + print(p) + +print('--- Nombre Productos ---') + +for p in listaProductos: + print(p[0]) + +print('--- Nombre y categorias Productos ---') + +for p in listaProductos: + print(f'Nombre: {p[0]} - Categoria: {p[2]}') + +# print(listaProductos) # imprimimos para poder ver la informacion recuperada de la base de datos + +conexion.commit() # Aceptamos los cambios o modificaciones que estamos haciendo + +puntero.close() # Creo de esta manera cerramos el puntero o cursor y digo creo porque fue algo le falto enseñar al profe en el curso o al menos en los dos videos referentes a este archivo, posiblemente lo veamos o lo enseñe mas adelante, de ser asi procurare cambiar la info de este archivo si es que no se me olvida, si se me olvida, seguramente tendre un comentario de como cerrar el puntero o cursor en el momento en que lo enseñe + +conexion.close() # Cerramos la conexion \ No newline at end of file diff --git a/DataBase/BBDD II - Bases de Datos.py b/DataBase/BBDD II - Bases de Datos.py new file mode 100644 index 0000000..6c7ce31 --- /dev/null +++ b/DataBase/BBDD II - Bases de Datos.py @@ -0,0 +1,77 @@ +# BBDD I / Bases de Datos - Pildoras Informaticas / Video 57 + +# Campos Clave + +# Los campos clave es un codigo de identificacion el cual puede estar confomado por letras, numeros o ambos que perteneces a los registros de las bases de datos para su identificacion y estos codigos o claves son unicos para cada elemento o registro + +# Podemos automatizar el campo clave para que python y el gestor de base de datos asignen este codigo o clave de forma automatica y que ese vaya incrementando automaticamente con cada entrada de registros. De esta manera si se le asigna un numero, pero tenemos la ventaja de que no necesitamos estarnos acordando de los codigo o claves que ya hayamos utilizado para no cometer el error de duplicarlos + +import sqlite3 + +# conexion = sqlite3.connect('Gestion de Productos') + +conexion = sqlite3.connect('Gestion de Productos 2 - Camplo Clave Automatico') + +puntero = conexion.cursor() + +# Para poder definir el campo clave ocupamos la instruccion PRIMARY KEY y esta debe de ir en el campo que queremos que sea clave, en este caso en particular el codigo del articulo + +# Para automatizar el campo clave podriamos dejar el nombre de Codigo_Articulo, pero normalmente por convencion a este campo se le suele denominar ID y el tipo de valor que va a recibir se le cambia a valor de tipo numerico, es decir INTEGER y ademas despues de la instruccion Primary Key agregamos la instruccion AUTOINCREMENT, la cual como su nombre lo indica es que sera de incremento automatico. Tambien a la hora de insertar registros en la base de datos ya no es necesario que nuestros registros en sus datos lleven el campo que corresponderian al campo clave. Y en el metodo clave, hay que modificar el valor de los values, en donde ira el campo clave le quitamos el signo ? y lo sustituimos por NULL + +# puntero.execute(""" +# CREATE TABLE CATALOGO ( +# Codigo_Articulo VARCHAR(4) PRIMARY KEY, +# Nombre_Articulo VARCHAR(50), +# Precio INTEGER, +# Categoria VARCHAR(20)) +# """) + +# puntero.execute(""" +# CREATE TABLE CATALOGO ( +# ID INTEGER PRIMARY KEY AUTOINCREMENT, +# Nombre_Articulo VARCHAR(50), +# Precio INTEGER, +# Categoria VARCHAR(20)) +# """) + +# El campo clave que asignemos (codigo articulo para este caso debe ser unico, no se debe repetir) + +# productos = [ +# ('PB01', 'CAJA PAPEL BOND T/C MARCA SCRIBE', 980, 'PAPEL BOND'), +# ('PB02', 'CAJA PAPEL BOND T/C MARCA SCOOL', 1050, 'PAPEL BOND'), +# ('CE01', 'CINTA DE EMPAQUE TRANSPARENTE MARCA TUK', 55, 'CINTAS DE EMPAQUE'), +# ('CE02', 'CAJA CINTA DE EMPAQUE TRANSPARENTE MARCA TUK 36PZAS', 1900, 'CINTAS DE EMPAQUE'), +# ('PS01', 'PLAYO TRANSPARENTE CALIBRE 60', 180, 'PLAYO'), +# ('PS02', 'PLAYO TRANSPARENTE CALIBRE 80', 165, 'PLAYO'), +# ('HU01', 'HIELERA UNICEL #1', 30, 'UNICEL'), +# ('HU02', 'HIELERA UNICEL #2', 50, 'UNICEL') +# ] + +# Aqui ya no es necesario indicar o agregar la informacion que iria en el campo clave como en el caso que se ve arriba de este comentario + +# productos = [ +# ('CAJA PAPEL BOND T/C MARCA SCRIBE', 980, 'PAPEL BOND'), +# ('CAJA PAPEL BOND T/C MARCA SCOOL', 1050, 'PAPEL BOND'), +# ('CINTA DE EMPAQUE TRANSPARENTE MARCA TUK', 55, 'CINTAS DE EMPAQUE'), +# ('CAJA CINTA DE EMPAQUE TRANSPARENTE MARCA TUK 36PZAS', 1900, 'CINTAS DE EMPAQUE'), +# ('PLAYO TRANSPARENTE CALIBRE 60', 180, 'PLAYO'), +# ('PLAYO TRANSPARENTE CALIBRE 80', 165, 'PLAYO'), +# ('HIELERA UNICEL #1', 30, 'UNICEL'), +# ('HIELERA UNICEL #2', 50, 'UNICEL') +# ] + +# puntero.executemany('INSERT INTO CATALOGO VALUES (?,?,?,?)', productos) + +# Aqui sustituimos el valor o signo ? por NULL. Si el campo clave sera automatico no debe llevar el simbolo el ?. Si se sigue respetando su espacio y lo seguimos declarando pero con la instruccion NULL + +# puntero.executemany('INSERT INTO CATALOGO VALUES (NULL,?,?,?)', productos) + +puntero.execute('INSERT INTO CATALOGO VALUES (NULL, "LIGAS DE HULE NATURAL #18", 25, "LIGAS")') + +# puntero.execute('INSERT INTO CATALOGO VALUES ("LH01", "LIGAS DE HULE NATURAL #18", 25, "LIGAS DE HULE")',) + +#puntero.execute('INSERT INTO CATALOGO VALUES ("HU02", "LIGAS DE HULE NATURAL #18", 25, "LIGAS DE HULE")',) # Como podemos ver con esta linea de codigo al momento de ejecutar el programa nos arroja un error, debido a que se esta utilizando un campo clave que ya existe y esto no puede ser asi, estos deben de ser unicos, no se pueden duplicar, de hecho el error es de tipo UNIQUE, que hace referencia a unico. + +conexion.commit() + +conexion.close() \ No newline at end of file diff --git a/DataBase/BBDD III - Bases de Datos.py b/DataBase/BBDD III - Bases de Datos.py new file mode 100644 index 0000000..1329a6a --- /dev/null +++ b/DataBase/BBDD III - Bases de Datos.py @@ -0,0 +1,99 @@ +# BBDD III / Bases de Datos - Pildoras Informaticas / Video 58 + +# Clausula / Instruccion UNIQUE + +""" La instruccion o clausula UNIQUE la debemos definir en el campo que la requiera y solo afectar de forma personal a este. Esta instruccion se puede colocar en cualquier campo y se puede utilizar las veces que sea necesario, aun en el mismo archivo, la misma tabla etc. Este no es clave o codigo principal como el que se genera con la instruccion PRIMARY KEY, pero si tiene en comun con este ultimo que no se pueda repetir y que su valor tiene que ser unico para cada registro """ + +# Operaciones CRUD + +""" CRUD = Create, Read, Update, Delete + - Asi se define o conoce a estos cuatro procesos que podemos hacer a la tabla de una base de datos. Estos como ya hemos visto con los dos primeros (Create y Read), se realizan mediante instrucciones del lenguajes SQL, y los dos ultimo no son la excepcion + + - Create es para crear. Nos sirve tanto para crear la tabla misma como registros que seran añadidos a las tablas + + - Read nos sirve para leer la informacion de la tabla, sin embargo esta palabra de READ no se emplea como tal o al menos no se a empleado hasta ahora, para leer lo tenemos que hacer mediante la instruccion 'SELECT * FROM' si no mal recuerdo, si no es asi, o hay algun cambio o añadido respecto a esto, cambiare esta informacion """ + +import sqlite3 + +conexion = sqlite3.connect('Catalogo Productos') + +puntero = conexion.cursor() + +# El unique en el campo articulo nos va a servir para que dos articulos no puedan tener el mismo nombre o valor + +# puntero.execute(""" +# CREATE TABLE CATALOGO ( +# ID INTEGER PRIMARY KEY AUTOINCREMENT, +# ARTICULO VARCHAR(50) UNIQUE, +# PRECIO INTEGER, +# CATEGORIA VARCHAR(20)) """) + +# productos = [ +# ('CJ PAPEL BOND T/C', 980, 'PAPEL'), +# ('CJ PAPEL BOND T/O', 1350, 'PAPEL'), +# ('CINTA TRANSPARENTE', 55, 'CINTA EMPAQUE'), +# ('PLAYO 18" CAL 60', 180, 'PLAYO') +# ] + +# puntero.executemany('INSERT INTO CATALOGO VALUES (NULL,?,?,?)', productos) + +#puntero.execute('INSERT INTO CATALOGO VALUES (NULL,"CINTA TRANSPARENTE", 54, "CINTA EMPAQUE")') # Con esta linea obtenemos un error ya que le hemos definido al campo ARTICULO de la tabla que sea de tipo unique, esto quiere decir que el valor dado a los registros en este campo no pueden repetirse, ser el mismo,de ahi el termino unique, tienen que ser valores unicos. Por lo tanto lo tendre que comentar + +# Aqui vamos a probar haciendo una nueva insercion en la tabla de la base de datos pero esta vez cambiando un poco el nombre del articulo para que corroboremos que al momento de asignarle un nombre diferente este registro se agrega sin ningun problema + +# puntero.execute('INSERT INTO CATALOGO VALUES (NULL,"CINTA TRANSPARENTE JANEL", 55, "CINTA EMPAQUE")') + +# Porque no dio error con los otros campos aun siendo iguales? Porque el valor unique solo afecta en donde se ponga, en este caso como tenemos el unique solo en el campo de ARTICULO, este no afecta a los campos de precio y categoria, es por eso que aunque en estos campos no cambia la informacion, podemos hacer la incersion del registro sin problema alguno. Podemos poner la instruccion unique donde queramos, cuantas veces queramos o necesitemos + +# --------------- Read ------------------- + +""" + -SELECT * FROM significa "selecciona de donde" seguido del nombre de la tabla. Esta instruccion se ocupa en el execute() + + - WHERE tambien significa "donde" pero este va enfocado y apuntando a los valores de la tabla, se pone where seguida del nombre del valor igualando este valor al valor que hay dentro, es decir en este caso un valor de la tabla como podria ser id, articulo etc igualando este a un valor dentro de este que puede ser el id de un articulo, el nombre de un articulo, su categoria etc. Esta instruccion tiene que ir definida en el execute() + + EL WHERE ES IMPORTANTE UTILIZARLO Y SABER DONDE, YA QUE ESTE APUNTA DE FORMA DIRECTA A LOS REGISTROS. SI ESTE NO SE OCUPA COMO SE DEBE O EN EL MOMENTO QUE SE DEBE PODRIA SER PERJUDICIAL, YA QUE SI NO LO LLEGAMOS A OCUPAR AL MOMENTO DE QUERER ELIMINAR O ACTUALIZAR UN REGISTRO, ESTARIAMOS ELIMINANDO O ACTUALIZANDO TODOS LOS REGISTROS DE LA TABLA, ASI QUE ES IMPORTANTE PRESTAR ATENCION AL MOMENTO DE HACER ALGO Y SABER SI LO TENEMOS QUE OCUPAR O NO + + fetchall() --> Con esta instruccion generamos la lectura y esta va definida y de la mano del puntero o curso, es por esto que se ocupa con este """ + +print('-------- Instruccion READ ---------') + +puntero.execute('SELECT * FROM CATALOGO') # Con esta instruccion le estamos diciendo que queremos leer + +catalogo = puntero.fetchall() # Y esta instruccion es la que se encarga de hacer la lectura, en este caso la estamos almacenando en una variable para despues imprimirla en consola + +for c in catalogo: + print(c) + +print('-------- Catalogo por Seccion ---------') + +puntero.execute('SELECT * FROM CATALOGO WHERE CATEGORIA = "PAPEL"') # Con esta instruccion tambien le decimos que queremos leer pero agregamos parametros adicionales para hacer una lectura especifica, diciendo en concreto que queremos leer, en este caso los productos de la categoria papel de la base de datos catalogo + +catalogo = puntero.fetchall() + +print(catalogo) + +for c in catalogo: + print(c) + +# --------------- Update ------------------- + +# Vamos a actualizar el precio de la cinta de empaque janel. Actualmente el precio de esta cinta es de 55 + +print('-------- Instruccion UPDATE ---------') + +puntero.execute('UPDATE CATALOGO SET PRECIO = 47 WHERE ARTICULO = "CINTA TRANSPARENTE JANEL"') + +# --------------- Delete ------------------- + +# Vamos a eliminar un articulo de la tabla perteneciente a la base de datos + +# De entrada debemos definir el criterio que utilizaremos para hacer la eliminacion, con esto me refiero a que valor de la tabla vamos a ocupar para hacer, es decir por medio del articulo, el id, la categoria y el precio. Hay que tener en cuenta que si utilizamos algun valor que no este definido como clave o codigo y como unique al momento de hacer el delete se borrarian todos los registros que tengan el mismo valor o parametro, es decir, si elegimos borrar por precio o categoria y este precio lo tienen varios articulos, se estaria borrando todos los registros que tengan el mismo precio, al igual que la categoria, si nos definidos por esta al hacer un delete, todos los registros que esten dentro de la categoria definida se estarian eliminando, con articulo esto no pasaria al menos en este archivo ya que esta definido como unique, pero de no estarlo podria pasar lo mismo si uno o varios prodcutos tienen el mismo nombre o valor en este campo de articulo. Esto tampoco pasaria con el id ya que esta definido como primary key + +# Para este ejemplo haremos uso del ID + +puntero.execute('DELETE FROM CATALOGO WHERE ID = 4') + +conexion.commit() + +conexion.close() \ No newline at end of file diff --git a/Date Base 1 b/Date Base 1 new file mode 100644 index 0000000..a7587c4 Binary files /dev/null and b/Date Base 1 differ diff --git a/Documentacion y Pruebas.py b/Documentacion y Pruebas.py new file mode 100644 index 0000000..c4be7e5 --- /dev/null +++ b/Documentacion y Pruebas.py @@ -0,0 +1,94 @@ +# Documentacion y Pruebas + +# Vamos a utilizar la documentacion para realizar pruebas. Para esto vamos a necesitar hacer uso del Módulo doctest + +# Esto nos sirve para saber si el codigo que vamos escribiendo funcionara de manera correcta antes de poner el programa o aplicacion en produccion y esto lo podemos hacer mediante la documentacion + +def areaTriangulo(base, altura): + + """ Calcula el area de un Triangulo + + Para hacer pruebas mediante la documentacion primero debemos situarnos entre las comillas triples de apertura y cierre del comentario y posteriormente poner tres signos de mayor, un espacio y el nombre de la funcion en este caso. Y por debajo debemos especificar el resultado que nos deberia arrojar la funcion. Si al momento de ejecutar no pasa nada quiere decir que todo va bien, de lo contrario nos arrojara un resultado donde nos especifica que el ejemplo es fallido, el resultado esperado (que es el que nosotros especificamos) y el resultado obtenido + + >>> areaTriangulo(3,6) + 9.0 + + >>> areaTriangulo(5,8) + 20.0 + + """ + return (base * altura) / 2 + +import doctest + +doctest.testmod() + +# El resultado que nosotros pongamos en nuestras pruebas debe de ser igual resultado que deberia arrojar el resultado final como tal, es decir, que si nosotros ponemos como resultado una cadena este debe ser igual tanto en el resultado obtenido como en el resultado esperado, si lleva puntos, acentos, comas, dos puntos, mayusculas etc. Veamos un ejemplo + +# Se pueden realizar varias pruebas o test dentro de una misma documentacion o comentario, solo es cosa de especificarlas, si no pasa nada quiere decir que todas las pruebas han ido correctamente, si llegase a haber un error en alguna de ellas, no estaria marcando en cual esta el error concretamente + +def suma(num1, num2): + + """ Suma dos numeros que se le pasen como parametros + + >>> suma(2,9) + 'La suma de los dígitos es: 11' + + >>> suma(4,5) + 'La suma de los dígitos es: 9' + + >>> suma(3,3.5) + 'La suma de los dígitos es: 6.5' + + """ + + return f'La suma de los dígitos es: {num1 + num2}' + +doctest.testmod() + +# Dejo cometada la funcion de abajo que es la que nos arroja error abajo mencionado, meramente para que podamos confirmar las pruebas siguientes sin que esta no afecte en el proceso de verificacion + +# def suma1(num1, num2): + +# """ Suma dos numeros que se le pasen como parametros + +# >>> suma1(5,3) +# 'La suma de los dígitos es: 8' + +# """ + +# return f'La suma de los digitos es: {num1 + num2}' + +# doctest.testmod() + +# Como podemos observar en el caso anterior nos arroja un error ya que el resultado obtenido no es igual al esperado que es la cadena de texto mas la operacion matematica de la suma de los numeros. La identificaicon de los resultados es tan sutil que hasta por un acento o una letra de mas podriamos ver un error, como lo podemos observar en el ejemplo anterior donde por el acento de la i en la palabra digitos nos da como resultado un error, ya que en el esperado tiene acento y en el obtenido no + +def confirmarEmail(mail): + + """ Comprobacion de arroba en el email del usuario. Si tiene 2 o mas, si esta al principio o final del email etc + + >>> confirmarEmail('moises.hdez@paperforall.com') + True + + >>> confirmarEmail('@moises.hdezpaperforall.com') + False + + >>> confirmarEmail('moises.hdezpaperforall.com@') + False + + >>> confirmarEmail('moises.hdezpaperforall.com') + False + + >>> confirmarEmail('moises.@hdez@paperforall.com') + False + + """ + + arroba = mail.count('@') + + if arroba != 1 or mail.rfind('@') == len(mail)-1 or mail.find('@') == 0 or mail.rfind('@') == len(mail) == 0: # Esta ultima comprobacion esta como de mas ya el primer condicional tambien la cumpliria + return False + else: + return True + +doctest.testmod() \ No newline at end of file diff --git a/Documentacion.py b/Documentacion.py new file mode 100644 index 0000000..f88f88b --- /dev/null +++ b/Documentacion.py @@ -0,0 +1,101 @@ +# Documentacion + +""" Documentar un programa + + Que es la documentacion? + + - Es incluir comentarios en clases, metodos, modulos etc + + Para que sirve? + + - Para ayudar en el trabajo en equipo. Especialmente util en aplicaciones complejas + + - No solo ayuda al trabajar en equipo, tambien es util aun cuando el unico desarrollador del programa sea uno mismo, ya que sirve de ayuda y guia cuando se vuelva a trabajar en la aplicacion o programa meses años despues """ + +# Para documentar un programa es necesario forsozamente usar las tres comillas (''' '''), ya que son estas las que Python toma como validas para un comentario al momento de documentar y tomar este comentario como un comentario de documentacion. En otras palabras hay posibilidad de poder imprimir los comentarios que generamos para documentar nuestro codigo, si estos comentarios estan entre las comillas triples, pero NO es posible hacerlo si generamos estos comentarios con el simbolo de almohadilla o gato + +# Ejemplo abajo donde estamos documentando la funcion areaCuadrado, a esta le agregamos un comentarios especificano que hace esta funcion, si ejecutamos el programa de forma normal este comentarios no sera visible ni aparecera en ningun lado ni en ningun momento, pero tenemos la opcion de imprimirlo si asi lo deseamos con el metodo .__doc__ despues del nombre de la funcion. Esta impresion en consola del comentario es posible ya que este comentario se genero mediante las comillas triples, de no ser asi, Python no lo reconoceria y por lo tanto no lo imprimiria, como es el caso del comentario generado mediante la almohadilla donde no tenemos ningun resultado en consola, ya que Python no toma como valida la almohadilla para un comentario documentativo + +# No es necesaio ejecutar o llamar a la funcion antes de imprimir la documentacion o el comentario, podemos hacerlo de forma independiente + +from modulos import funciones_matematicas + +def areaCuadrado(lado): + '''Cálcula el area de un cuadrado. Elevando al cuadrado el valor pasado como parametro''' + # Comentario adicional de prueba con almohadilla + lado_cuadrado = lado + return f'El area del cuadrado es: {lado_cuadrado * lado_cuadrado}' + +def areaTriangulo(base, altura): + base_triangulo = base + altura_triangulo = altura + return f'El area del triangulo es: {(base_triangulo * altura_triangulo) / 2}' + +def funcionPrueba(): + + """ Comentario de prueba para confirmar que no es necesario llamar a la funcion antes de imṕrimir o llamar a la documentacion o comentario de la funcion en cuestion """ + + nombre = 'Moises Hernandez' + + if len(nombre) > 0 and len(nombre) < 50: + print('El nombre es válido') + else: + print('El nombre es inválido') + + return f'El nombre es: {nombre}' + +print(areaCuadrado(5)) +print(areaTriangulo(3,8)) + +print(areaCuadrado.__doc__) + +print('') +print('------- Documentacion/Comentario Funcion Prueba antes de llamarla -------') + +print(funcionPrueba.__doc__) + +print('') +print('--- Funcion Prueba ---') + +funcionPrueba() + +# Tenemos otra instruccion que nos permite imprimir la documentacion sin la necesidad de utilizar la funcion print, y esta es la funcion help + +# help() --> dentro de los parentesis la funcion de la que quieres obtener la ayuda + +help(areaCuadrado) +help(funcionPrueba) + +# Con la funcion help se abre la ayuda de Python y nos ofrece una informacion mas detallada, donde nos muestra a que modulo pertenece la funcion que tiene la documentacion, nos muestra la funcion y dentro de esta el comentario o la documentacion generada. Hago incapie en que nos muestra la funcion y el modulo donde pertenece esta funcion ya que es donde puse el comentario documentativo, pero supongo que si esta en una clase, metodo, etc sera lo mismo pero cambiando los detalles en la ayuda con respecto a donde se encuentre dicha documentacion + +# La funcion help la visualizamos de forma independiente, no se imprime en la consola junto con lo demas como si lo hicieramos con un print + +# Si queremos obtener ayuda de una funcion que se encuentra de una clase, tenemos que especificar en el help primero la clase a la que pertenece la funcion seguido de la nomenclatura del punto y a continuacion el nombre de la funcion de la cual queremos obtener la ayuda + +print('') +print('-------- Obteniendo ayuda de una funcion dentro de una clase --------') + +class Areas: + """ Clase para calcular areas de figuras geometricas """ + + def areaCuadrado(lado): + '''Calculando area de un cuadrado''' + # Comentario adicional de prueba con almohadilla + lado_cuadrado = lado + return f'El area del cuadrado es: {lado_cuadrado * lado_cuadrado}' + + def areaTriangulo(base, altura): + """ Calculando el area de un triangulo """ + base_triangulo = base + altura_triangulo = altura + return f'El area del triangulo es: {(base_triangulo * altura_triangulo) / 2}' + +help(Areas.areaCuadrado) + +# Tambien podemos obtener una ayuda mas general de una clase, donde nos brindara toda la documentacion o comentarios que contenga esta clase ya sea en la clase misma, en sus funciones o en su codigo en general + +help(Areas) + +# De igual manera podemos documentar modulos y solicitar la ayuda de la documentacion o comentarios establecidos en los modulos que hayamos importado. Al solicitar la documentacion de los modulos nos aparece la documentacion o comentarios generados en el modulo o archivo como tal como los comentarios o la documentacion generados en las clases, funciones etc que contenga este modulo + +help(funciones_matematicas) \ No newline at end of file diff --git a/Ejercicio1_PildorasInformaticas.py b/Ejercicio1_PildorasInformaticas.py new file mode 100644 index 0000000..ce3496f --- /dev/null +++ b/Ejercicio1_PildorasInformaticas.py @@ -0,0 +1,36 @@ +# Ejercicio 1 - Pildoras Informaticas + +# Crea un programa que pida dos numeros por teclado. El programa tendra una funcion llamada devuelveMax encargada de devolver el número más alto de los dos ingresados + +num1 = int(input('Introduzca el primer digito: ')) +num2 = int(input('Introduzca el segundo digito: ')) + +def devuelveMax(num1, num2): + if num1 > num2: + print(f'El numero mas alto es: {num1}') + elif num2 > num1: + print(f'El numero mas alto es: {num2}') + else: + print('Ambos numeros introducidos son iguales') + +devuelveMax(num1, num2) + +print('Fin del programa escrito por Moises') + +# Metodo de solucion del profe Juan de Pildoras Informaticas + +print('*****Metodo solucion profe*****') + +def devuelve(n1, n2): + if n1 < n2: + print(n2) + elif n1 > n2: + print(n1) + else: + print('Son iguales') + +print('El numero mas alto es: ') + +devuelve(num1, num2) + +print('Fin del programa escrito por el profe Juan de Pildoras Informaticas') \ No newline at end of file diff --git a/Ejercicio2_PildorasInformaticas.py b/Ejercicio2_PildorasInformaticas.py new file mode 100644 index 0000000..d202bbf --- /dev/null +++ b/Ejercicio2_PildorasInformaticas.py @@ -0,0 +1,26 @@ +# Ejercicio 2 - Pildoras Informaticas + +# Crea un programa que pida por teclado Nombre, Direccion y telefono. Esos tres datos deberán ser almacenados en una lista y mostrar en consola el mensaje: 'Los datos personales son: nombre, apellido, telefono' (Se mostraran los datos introducidos) + +nombre = input('Escribe tu nombre --> ') +direccion = input('Escribe tu dirección completa --> ') +telefono = input('Escribe tu número telefónico --> ') + +lista = list() +lista.append(nombre) +lista.append(direccion) +lista.append(telefono) + +print(f'Los datos personales son: Nombre: {lista[0]}, Direccion: {lista[1]}, Teléfono: {lista[2]}') + +print('***Solucion Profe***') + +# Solucion profe + +Nombre = input('Introduce el nombre: ') +Direccion = input('Introduce la direccion: ') +Tfno = input('Introduce el teléfono: ') + +listaDatos = [Nombre, Direccion, Tfno] + +print('Los datos personales son: Nombre: ' + listaDatos[0] + ' Dirección: ' + listaDatos[1] + ' Teléfono: ' + listaDatos[2]) \ No newline at end of file diff --git a/Ejercicio3_PildorasInformaticas.py b/Ejercicio3_PildorasInformaticas.py new file mode 100644 index 0000000..c34fb79 --- /dev/null +++ b/Ejercicio3_PildorasInformaticas.py @@ -0,0 +1,11 @@ +# Ejercicio 3 - Pildoras Informaticas + +# Crea un programa que pida tres numeros por teclado. El programa imprime en consola la media aritmpetica de los números introducidos + +num1 = float(input('Digita el primer número: ')) +num2 = float(input('Digita el segundo número: ')) +num3 = float(input('Digita el tercer número: ')) + +mediaAritmetica = (num1 + num2 + num3) / 3 + +print(f'La media aritmpetica es: {mediaAritmetica:.2f}') \ No newline at end of file diff --git a/Ejercicio4_PildorasInformaticas.py b/Ejercicio4_PildorasInformaticas.py new file mode 100644 index 0000000..528972f --- /dev/null +++ b/Ejercicio4_PildorasInformaticas.py @@ -0,0 +1,14 @@ +# Ejercicio 4 Bucle for - Pildoras Informaticas + +# Crea un programa que muestre los numeros impares del 1 al 100. Los números deberán aparecer uno al lado del otro sin salto de línea + +for i in range(0,100): + if i % 2 == 1: + print(i, end=' ') + +# Solucion profe Juan Pildoras Informaticas + +print('\n***Solucion profe Juan***') + +for i in range(1,100,2): + print(i, end=' ') \ No newline at end of file diff --git a/Ejercicio5_PildorasInformaticas.py b/Ejercicio5_PildorasInformaticas.py new file mode 100644 index 0000000..02ed139 --- /dev/null +++ b/Ejercicio5_PildorasInformaticas.py @@ -0,0 +1,29 @@ +# Ejercicio 5 Bucle for - Pildoras Informaticas + +# Crea un programa que pida por teclado introducir una contraseña. La contraseña no podrá tener menos de 8 caracteres ni espacios en blanco. Si la contraseña es correcta, el programa imprime 'Contraseña OK'. En caso contrario imprime 'Contraseña incorrecta' + + +password = input('Introduce una contraseña: ') +contador = 0 + +for i in password: + if i == ' ': + contador = 1 + +if len(password) >= 8 and contador == 0: + print('Contraseña OK') +else: + print('Contraseña incorrecta') + +print('Forma de solucion del profe con for in range') + +for i in range(len(password)): + if password[i] == ' ': + contador = 1 + +if len(password) >= 8 and contador == 0: + print('Contraseña OK') +else: + print('Contraseña incorrecta') + +# Cabe mencionar que no pude solucionarlo solo, la primera solucion la saque de la solucion del profe pero quite el range haber si seguia sirviendo con el for normal \ No newline at end of file diff --git a/Ejercicio6_PildorasInformaticas.py b/Ejercicio6_PildorasInformaticas.py new file mode 100644 index 0000000..d6b7862 --- /dev/null +++ b/Ejercicio6_PildorasInformaticas.py @@ -0,0 +1,29 @@ +# Ejercicio 6 Bucle for - Pildoras Informaticas + +# Crea un programa que evalue si una dirección de correo electrónico es válida o no en función de si tiene '@' o '.'. Hay que tener en cuenta que la dirección se considera correcta si solo tiene un @ y si tiene uno o mas puntos '.' + +email = input('Introduce tu email: ') +contador1 = 0 +contador2 = 0 + +for i in email: + if i == '@': + contador1 = contador1 + 1 + if i == '.': + contador2 = contador2 + 1 +if contador1 == 1 and contador2 >= 1: + print('Email válido') +else: + print('Error: Email inválido') + +print('***Solucion profe Juan Pildoras Informaticas***') + +for i in range(len(email)): + if email[i] == '@': + contador1 = contador1 + 1 + if email[i] == '.': + contador2 = 1 +if contador2 == 0 or contador1 != 1: + print('email incorrecto') +else: + print('email correcto') \ No newline at end of file diff --git a/Ejercicio7_PildorasInformaticas.py b/Ejercicio7_PildorasInformaticas.py new file mode 100644 index 0000000..d7d7f6a --- /dev/null +++ b/Ejercicio7_PildorasInformaticas.py @@ -0,0 +1,14 @@ +# Ejercicio 7 - Pildoras Informaticas + +# Crea un programa que pida números infinitamente. Los números introducidos deben ser cada vez mayores. El programa finalizará cuando se introduzca un número menor que el anterior + +numMenor = int(input('Introduce un numero: ')) +numMayor = int(input(f'Introduzca un numero mayor a {numMenor}: ')) + +while numMayor > numMenor: + numMenor = numMayor + numMayor = int(input('Introduce un numero: ')) + +print('El numero introducido es menor que el anterior') + +print('Fin del programa') \ No newline at end of file diff --git a/Ejercicio8_PildorasInformaticas.py b/Ejercicio8_PildorasInformaticas.py new file mode 100644 index 0000000..8ba2cb0 --- /dev/null +++ b/Ejercicio8_PildorasInformaticas.py @@ -0,0 +1,13 @@ +# Ejercicio 8 - Pildoras Informaticas + +# Crea un programa que pida números positivos indefinidamente. El programa termina cuando se introduce un número negativo. Finalmente el programa muestra la suma de todos los numeros introducidos + +numPos = int(input('Introduce un numero positivo: ')) +suma = 0 + +while numPos > 0: + suma = suma + numPos + numPos = int(input('Introduce un numero positivo: ')) + +print(f'La suma de los numeros es {suma}') +print('Fin del programa') \ No newline at end of file diff --git a/Ejercicio9_PildorasInformaticas.py b/Ejercicio9_PildorasInformaticas.py new file mode 100644 index 0000000..4fa65bc --- /dev/null +++ b/Ejercicio9_PildorasInformaticas.py @@ -0,0 +1,47 @@ +# Crea un programa que pida introducir una dirección de email por teclado. El programa debe imprimir en consola si la dirección de email es correcta o no en función de si esta tiene el símbolo ‘@’. Si tiene una ‘@’ la dirección será correcta. Si tiene más de una o ninguna ‘@’ la dirección será errónea. Si la ‘@’ está al comienzo de la dirección de email o al final, la dirección también será errónea + +# la siguiente solucion al ejercicio es mi solucion, la cual abarca un poco mas que lo que se solicita en el ejercicio donde pide solo corroborar si el email tiene arroba o no y dependiendo de esto informar si el email es correcto o no. En mi solucion agregue la terminacion .com, .com.mx y .mx, ademas de que si el email es erroneo solicite volverlo a introducir + +# email = input('Introduce tu correo electronico: ') + +# while (email.startswith('@') == True or email.endswith('@') == True): +# print('Email invalido. Error de sintaxis. Introduce un correo valido') + +# email = input('Introduce tu email: ') + +# while (email.endswith('.com') == False and (email.endswith('.mx') == False)): +# print('Direccion de correo electronico invalida. Favor de introducir un email valido') + +# email = input('Introduce tu email: ') + +# while (email.count('@') != 1): +# print('Email invalido. Introduce una direccion de email valida') + +# email = input('Introduce tu email: ') + +# print(f'Tu direccion de correo electronico es: {email}') + +# # A continuacion veremos la solucion dada al ejercicio por el profe Juan, en la cual se limita a solo hacer lo que dice el ejercicio, pero solo en parte ya que no esta evaluando si el arroba se encuentra al inicio o final del email + +email_usuario = input('Introduce tu email: ') + +arroba = email_usuario.count('@') + +if arroba != 1 or email_usuario.rfind('@') == (len(email_usuario)) == -1 or email_usuario.find('@') == 0: + print('Email incorrecto') +else: + print('Email correcto') + +# Me doy cuenta que la forma de resolver el ejercicio del profe Juan tiene una deficiencia o mas que deficiencia le falta evaluar si el arroba esta al final. Trato de entender que esto lo quizo lograr con el metodo rfind(), seguido del metodo len, sin embargo encontre un inconveniente con esto y no se si siempre ha sido asi o esto ya cambio desde que el profe hizo el curso al momento en que yo lo estoy tomando. Y este inconveniente es que el metodo rfind(), da como resultado el indice donde se encuentra la palabra, letra etc indicado dentro de los parentesis, pero que este metodo no cuenta como tal de atras para adelante o de derecha a izquierda como el en algun momento lo menciono, si no que mas bien, el indice que arroja como resultado es el correspondiente a la ultima palabra, letra etc que encuentra dentro de la cadena, es decir si cuenta de derecha a izquierda pero no el indice si no la palabra o letra que esta como parametro y esta es la que toma en cuenta para arrojar el indice como resultado. Ej 'hola cruel mundo mundo cruel'. Si utilizamos el rfind con esta cadena y pasamos como metodo el rfind y como parametro 'cruel' nos va a arojar el indice donde empieza la ultima palabra cruel que se encuentra dentro de esta cadena, es decir la ultima palabra de esta, pasaria lo mismo si como parametro ponemos mundo, indicara el indice donde comienza la ultima palabra que coincida con mundo que en el caso del ejemplo es la penultima palabra + +# Para logra el objetivo del ejercicio simplificandolo a meramente lo que nos pide este quedaria de la siguiente manera. (Esta solucion la hice yo mismo) + +email_usuario2 = input('Introduce tu correo electronico: ') + +arroba = email_usuario2.count('@') + +if arroba != 1 or email_usuario2.startswith('@') or email_usuario2.endswith('@'): + print('Email incorrecto. Favor de verificarlo') + +else: + print('Email válido') \ No newline at end of file diff --git a/Ejercicio_1_Colecciones.py b/Ejercicio_1_Colecciones.py new file mode 100644 index 0000000..c1d3c39 --- /dev/null +++ b/Ejercicio_1_Colecciones.py @@ -0,0 +1,30 @@ +# Ejercicio 1 - Eliminar duplicados de una lista + +# Escribe un programa que contenga una lista y que, a continuación, elimine los elementos duplicados y por último mostrar la lista + +print('***Lista***') + +lista1 = [1,2,3,4,5,1,3,5,'Moises','Hernandez','Eliab','Hernandez'] +print(lista1) + +# No hay manera de detectar y eliminar elementos duplicados de forma directa en una lista, por lo tanto, lo que se tiene que hacer es convertir esta lista en una coleccion que no permita elementos duplicados como los conjuntos y ya que no haya elementos duplicados regresarla nuevamente a ser una lista + +print('***Conjunto***') + +conjunto = set(lista1) # 1 +print(conjunto) + +print('***Lista nuevamente***') + +lista1 = list(conjunto) # 2 +print(lista1) + +# De esta manera estamos generando el codigo necesario para el cometido en dos lineas de codigo, sin embargo los podemos hacer de una forma mas directa y en una sola linea de codigo + +print('***Forma 2***') + +lista2 = [1,2,3,4,'Moises','Hernandez','Eliab','Hernandez',1,3,5] + +lista2 = list(set(lista2)) # Esta seria la forma rapida y abreviada, donde lo hacemos todo mas compacto y de un solo tajo, en lugar de ir desglosando el proceso lo hacemos de forma mas directa + +print(lista2) \ No newline at end of file diff --git a/Ejercicio_1_Condicionales.py b/Ejercicio_1_Condicionales.py new file mode 100644 index 0000000..313293d --- /dev/null +++ b/Ejercicio_1_Condicionales.py @@ -0,0 +1,15 @@ +# Ejercicio 1 + +# Hacer un programa que pida 2 numeros y se de cuenta cual de ellos es par, o si ambos lo son + +num1 = int(input('Digite el primer numero: ')) +num2 = int(input('Digite el segundo numero: ')) + +if num1 % 2 == 0 and num2 % 2 == 0: + print('Ambos numeros son pares') +elif num1 % 2 == 0: + print(f'{num1} es par') +elif num2 % 2 == 0: + print(f'{num2}) es par') +else: + print('Ambos numeros son impares') \ No newline at end of file diff --git a/Ejercicio_1_ElementosBasicos.py b/Ejercicio_1_ElementosBasicos.py new file mode 100644 index 0000000..b904d8b --- /dev/null +++ b/Ejercicio_1_ElementosBasicos.py @@ -0,0 +1,11 @@ +# Escribir la siguiente expresión en forma de expresión algoritmica (Checar la expresion en la imagen en la carpeta Referencias del Proyecto) + +a = float(input("a = ")) +b = float(input("b = ")) +c = float(input("c = ")) + +resultado = (a**3 * (b**2 - 2*a*c)) / (2*b) + +print(f"El resultado es : {resultado}") + +# Se pueden trabajar con valores tanto enteros como flotantes, al momento de escribir los valores de las variables en la consola \ No newline at end of file diff --git a/Ejercicio_2_Colecciones.py b/Ejercicio_2_Colecciones.py new file mode 100644 index 0000000..a6097d7 --- /dev/null +++ b/Ejercicio_2_Colecciones.py @@ -0,0 +1,78 @@ +# Ejercicio 2 + +""" Escribe un programa que tenga dos listas y que, a continuación, cree las siguientes listas (en las que no debe haber repeticiones) + + - Lista de palabras que aparecen en las dos listas + - Lista de palabras que aparecen en la primera lista, pero no en la segunda + - Lista de palabras que aparecen en la segunda lista, pero no en la primera + - Lista de palabras que aparecen en ambas listas """ + + +famHdez = ['Moises', 'Nahun', 'Efrain', 'Lilia', 'Arnulfo', 'Susett', 'Brenda', 'Zully'] +famNoDirecta = ['Susett', 'Brenda', 'Zully', 'Angelita'] + +print('*****Nombres en las dos listas*****') + +lista1 = famHdez + famNoDirecta +print(lista1) + +lista1 = list(set(lista1)) +print(lista1) +print(len(lista1)) + +print('*****Nombres en la primera lista, que no estan en la segunda*****') + +conjunto1 = set(famHdez) +conjunto2 = set(famNoDirecta) + +lista2 = list(conjunto1 - conjunto2) +print(lista2) + +print('*****Nombres en la segunda lista, que no estan en la primera*****') + +conj1 = set(famHdez) +conj2 = set(famNoDirecta) + +lista3 = list(conj2 - conj1) +print(lista3) + +print('*****Nombres que aparecen en ambas listas*****') + +conjA = set(famHdez) +conjB = set(famNoDirecta) + +lista4 = list(conjA & conjB) +print(lista4) + +""" Forma de resolver el ejercicio de Alejandro """ + +famMoy = ['Moises', 'Nahun', 'Efrain', 'Lilia', 'Arnulfo', 'Susett', 'Brenda', 'Zully'] +famNoDir = ['Susett', 'Brenda', 'Zully', 'Angelita'] + +# Primero eliminio los elementos duplicados creando conjuntos + +a = set(famMoy) +b = set(famNoDir) + +# Seguido unio los conjuntos para formar la primera lista del ejercicio + +# Lista 1 +union = list(a | b) + +# Lista 2 +soloFamMoy = list(a - b) + +# Lista 3 +soloFamNoDir = b - a + +# Lista 4 +interseccion = list(a & b) + +print('***Lista 1***') +print(union) +print('***Lista 2***') +print(soloFamMoy) +print('***Lista 3***') +print(soloFamNoDir) +print('***Lista 4***') +print(interseccion) \ No newline at end of file diff --git a/Ejercicio_2_Condicionales.py b/Ejercicio_2_Condicionales.py new file mode 100644 index 0000000..4b89a93 --- /dev/null +++ b/Ejercicio_2_Condicionales.py @@ -0,0 +1,16 @@ +# Ejercicio 2 + +# Hacer un programa que pida 3 numeros y determine cual es el mayor + +num1 = int(input("Digite el primer numero: ")) +num2 = int(input("Digite el segundo numero: ")) +num3 = int(input("Digite el tercer numero: ")) + +if num1 >= num2 and num1 >= num3: + print(f'El numero mas alto es {num1}') +elif num2 >= num3 and num2 >= num1: + print(f'El numero mas alto es {num2}') +elif num3 >= num1 and num3 >= num2: + print(f'El numero mas alto es {num3}') +else: + print('Todos los numeros son iguales') diff --git a/Ejercicio_2_ElementosBasicos.py b/Ejercicio_2_ElementosBasicos.py new file mode 100644 index 0000000..48885c8 --- /dev/null +++ b/Ejercicio_2_ElementosBasicos.py @@ -0,0 +1,10 @@ +# Determinar la solución lógica de la siguiente operación (Imagen de referencia de la operacion en la carpeta referencias) + +a = float(input("Digite el valor de a: ")) +b = float(input("Digite el valor de b: ")) + +resultado = ((3+5*8)<3 and ((-6/3*4)+2<2)) or (a>b) # Solucion propia + +print(f"El resultado es: {resultado}") + +resultado = ((3+5*8)<3 and (-6/3*4)+2<2) or (a>b) # Solucion Alejandro. No puso un par de parentesis, pero al parecer no afectan al resultado, ya que eventualmente se estaran eliminando al ser parentesis internos y ser de los primeros en resolverse. De todos modos, podemos hacer un ejercicio despues similar para saber con mas certeza si afecta o no al resultado \ No newline at end of file diff --git a/Ejercicio_3_Colecciones.py b/Ejercicio_3_Colecciones.py new file mode 100644 index 0000000..0ccc6d9 --- /dev/null +++ b/Ejercicio_3_Colecciones.py @@ -0,0 +1,37 @@ +# Ejercicio 3 + +""" Escribe un programa donde cree una lista con los siguientes personajes del Señor de los Anillos + + Nombre: Aragorn + Clase: Guerrero + Raza: Dúnadan del Norte + + Nombre: Gandalf + Clase: Mago + Raza: Istar + + Nombre: Legolas + Clase: Arquero + Raza: Elfo Sindar """ + +personajes = [{'Aragorn':{'Nombre':'Aragorn', 'Clase':'Guerrero', 'Raza':'Dúnadan del Norte'},'Gandalf':{'Nombre':'Gandalf', 'Clase':'Mago', 'Raza':'Istar'}, 'Legolas':{'Nombre':'Legolas', 'Clase':'Arquero', 'Raza':'Elfo Sindar'}}] + +print(personajes) +print(type(personajes)) + +# Forma de resolverlo de Alejandro + +personajes1 = [] + +p = {'Nombre':'Aragorn', 'Clase':'Guerrero', 'Raza':'Dúnadan del Norte'} +personajes1.append(p) + +p = {'Nombre':'Gandalf', 'Clase':'Mago', 'Raza':'Istar'} +personajes1.append(p) + +p = {'Nombre':'Legolas', 'Clase':'Arquero', 'Raza':'Elfo Sindar'} +personajes1.append(p) + +print(personajes1) + +# La diferencia entre como lo hice yo a como lo hizo Alejandro fue que yo lo hice de forma mas directa, creando la lista y dentro de esta el diccionario con los personajes, mientras que Alejandro creo la lista vacia, posteriormente fue creando personaje por personaje en forma de diccionario y agregandolo a la lista vacia que previamente habia creado. En su metodo solo ocupa una variable para la creacion de los 3 personajes, debido a que conforme los iba creando los iba agregando a la lista por lo tanto cuando el valor de la variable con el siguiente personaje, no se veia afectado el personaje creado con anterioridad debido a que ya estaba almacena como un elemento de la lista \ No newline at end of file diff --git a/Ejercicio_3_Condicionales.py b/Ejercicio_3_Condicionales.py new file mode 100644 index 0000000..263bddf --- /dev/null +++ b/Ejercicio_3_Condicionales.py @@ -0,0 +1,14 @@ +# Ejercicio 3 - Comprobar vocales + +# Hacer un programa que pida un caracter e indique si es una vocal o no + +letra = input("Introduzca una letra, numero o caracter --> ").lower() # Alejandro lo hizo de esta manera, donde puso el metodo lower() de forma directa en la variable despues del input, asi en cuanto el usuario digite el dato, este se convierte y ya despues se almacena en la variable + +# letra = letra.lower() # Yo lo habia puesto de esta manera, donde estaba reasigando la variable + +# Tambien explico porque esto --> letra.lower() que estaba haciendo no funciona. Esto es porqueel metodo lower() y upper() retornan una copia y que esta necesita ser almacenada, es por eso que necesitamos declarar o guardar el resultado de estos metodos en variables, de no ser asi es como si no estuvieramos haciendo nada, ya que la copia se queda vagando por ahi sin registro + +if letra == "a" or letra == "e" or letra == "i" or letra == "o" or letra == "u": + print(f"'{letra.upper()}' es una vocal") +else: + print(f"'{letra.upper()}' NO es una vocal") \ No newline at end of file diff --git a/Ejercicio_3_ElementosBasicos.py b/Ejercicio_3_ElementosBasicos.py new file mode 100644 index 0000000..fced3e9 --- /dev/null +++ b/Ejercicio_3_ElementosBasicos.py @@ -0,0 +1,39 @@ +# Ejercicio 3 + +# Hacer un programa para intercambiar el valor de 2 variables + +""" Variables + a = 10 --> a = 5 + b = 5 --> b = 10 +""" + +a = int(input("Define el valor de a: ")) +b = int(input("Define el valor de b: ")) + +# Podemos intercambiar valores de las variables, asignando el valor de la variable a alguna otra, pero dentro de la misma linea de codigo, como se muestra abajo, donde estamos indicando el orden que deben obtener con respecto a los valores, es decir la primer variable del lado izquierdo del igual va a almacenar el valor de la primer variable del lado derecho del igual, y asi con las otras variables que le preceden + +# Hay otras formas de intercambiar valores de variables, alguna otra puede ser usar una variable auxiliar o temporal que nos almacene el valor destinado para despues agregarlo a nuestra variable final + +a , b = b , a + +print(f"El nuevo valor de 'a' es: {a}") +print(f"El nuevo valor de 'b' es: {b}") + +nombre = "Hernandez" +apellido = "Moises" + +nombre , apellido = apellido , nombre + +print(f"Tu nombres es: {nombre}") +print(f"Tu apellido es: {apellido}") + +# En esta forma estamos utilizando una variable auxiliar o temporal para lograr intercambiar los valores, y tambien esta bien echo, sin embargo es mas laborioso y largo, la primer forma es la mas rapida y sencilla + +varA = 10 +varB = 20 +varAux = varA + +varA = varB +varB = varAux + +print(varA, varB) \ No newline at end of file diff --git a/Ejercicio_4_Condicionales.py b/Ejercicio_4_Condicionales.py new file mode 100644 index 0000000..8bd407e --- /dev/null +++ b/Ejercicio_4_Condicionales.py @@ -0,0 +1,29 @@ +# Ejercicio 4 - Calculadora Basica + +# Construir un programa que simule el funcionamiento de una calculadora que puede realizar las 4 operaciones aritméticas básicas (suma, resta, multiplicación y división). El usuario debe especificar la operación con el primer carácter del nombre de la operación + +# S, s --> Suma +# R, r --> Resta +# M, m --> Multiplicación +# D, d --> División + +num1 = int(input('Digite un numero: ')) +num2 = int(input('Digite otro numero: ')) +op = input('Digite la letra inicial de la operacion a realizar: s - suma, r - resta, m - multiplicacion, d - division. Que operación desea realizar? ') + +op = op.lower() + +if op == "s": + resultado = num1 + num2 + print(f'El resultado es: {resultado}') +elif op == "r": + resultado = num1 - num2 + print(f'El resultado es: {resultado}') +elif op == "m": + resultado = num1 * num2 + print(f'\nEl resultado es: {resultado}') +elif op == "d": + resultado = num1 / num2 + print(f'\nEl resultado es: {resultado:.2f}') +else: + print("La letra ingresada no es válida.") \ No newline at end of file diff --git a/Ejercicio_4_ElementosBasicos.py b/Ejercicio_4_ElementosBasicos.py new file mode 100644 index 0000000..b470cdf --- /dev/null +++ b/Ejercicio_4_ElementosBasicos.py @@ -0,0 +1,18 @@ +# Ejercicio 4 + +# Hacer un programa para ingresar el radio de un circulo y se reporte su area y la longitud de la circunferencia + +""" area = pi * r2 + longitud = 2 * pi * r +""" +import math # Aqui estamos importando el modulo math que contiene el valor de pi, aunque ya sabemos cuanto vale pi y podriamos poner el dato de forma directa, los modulos nos sirven para este cometido y ya tiene los datos cargados en variables especificas y reservadas + +# Para hacer uso del modulo math y del pi que viene en este, es necesario declarar el modulo seguido de la variable de este que queremos ocupar, ej math.pi + +radio = float(input("Digite el radio del circulo -> ")) + +area = math.pi * (radio**2) +diametro = 2 * math.pi * radio + +print(f"El area del circulo es: {area:.2f}") +print(f"El diametro del circulo es: {diametro:.4f}") # Que significa el 2 y el 4f en las variables??? Lo que estamos haciendo con esa parte de codigo es decirle a la variable cuanto numeros decimales queremos depues del punto. Si no especificamos por defecto al ser un numero flotante el resultado vendra con los 16 digitos que permiten los numeros flotantes despues del punto. Para evitar estohacemos uso de un metodo o forma para decirle a python cuanto numeros decimales queremos despues del punto en un numero flotante. Esto lo hacemos de la siguiente manera: despues de la variable agregamos dos puntos seguido de un punto normal y por ultimo el numero de decimales que queramos mas la letra f. Ej variable:.3f, lo cual hara que el resultado tenga 3 numero despues del punto decimal \ No newline at end of file diff --git a/Ejercicio_5_Condicionales.py b/Ejercicio_5_Condicionales.py new file mode 100644 index 0000000..8b90ec5 --- /dev/null +++ b/Ejercicio_5_Condicionales.py @@ -0,0 +1,48 @@ +# Ejercicio 5 - Cajero Automático + +""" Hacer un programa que simule un cajero automático con un saldo inicial de $1000 y tendrá el siguiente menú de opciones + + 1 - Ingresar dinero a la cuenta + 2 - Retirar dinero de la cuenta + 3 - Mostrar dinero disponible + 4 - Salir """ + +saldoInicial = 1000 + +titleMenu = '\t.:MENU:.' # \t significa tabulacion de 4 espacios. Los puntitos solo es decoracion +# opsMenu = "1-Ingresar dinero en la cta 2-Retirar dinero de la cta 3-Mostrar saldo disponible 4-Salir" + +print(titleMenu) +print('1. Ingresar dinero en la cuenta') +print('2. Retirar dinero de la cuenta') +print('3. Mostrar saldo disponible') +print('4. Salir') +# print(opsMenu) + +opcion = int(input('\nDigite la opcion deseada > ')) + +if opcion == 1: + ingresar = float(input('Digite el monto a ingresar: ')) + if ingresar > 0: + saldoInicial += ingresar + print(f'Su saldo actual es de: {saldoInicial:.2f}') + print('\nGracias por usar nuestro cajero') + else: + print('El monto ingresado no es válido') +elif opcion == 2: + retirar = float(input('Ingrese la cantidad a retirar: ')) + if retirar > saldoInicial: + print('\nSaldo insuficiente') + elif retirar > 0: + saldoInicial -= retirar + print(f'Su saldo actual es de: {saldoInicial:.2f}') + print('\nGracias por usar nuestro cajero') + else: + print('El monto ingresado no es válido') +elif opcion == 3: + print(f'Su saldo disponible es: {saldoInicial:.2f}') + print('\nGracias por usar nuestro cajero') +elif opcion == 4: + print('Gracias por usar unuestro cajero automático') +else: + print('Opción de menú no válida') \ No newline at end of file diff --git a/Ejercicio_5_ElementosBasicos.py b/Ejercicio_5_ElementosBasicos.py new file mode 100644 index 0000000..908322a --- /dev/null +++ b/Ejercicio_5_ElementosBasicos.py @@ -0,0 +1,15 @@ +# Ejercicio 5 + +# Una tienda ofrece un descuento de 15% sobre el total de la compra y un cliente desea saber cuánto deberá pagar finalmente por su compra. + +# porcDescuento = 15 +compra = float(input("Monto de la compra: $")) +descuento = (compra * 0.15) # Esta es la forma rapida de sacar el valor del porcentaje + +""" Otra forma de hacerlo, requiere de un paso adicional y esta es la que normalmente se enseña. Basicamente es cantidad * porcentaje / 100 + (compra * 15) / 100 -> Como podemos observar con el metodo anterior no estamos ahorrando la division entre 100, ya que al hacer la multiplicacion por .15 (porcentaje descuento) nos da el resultado de una forma mas directa +""" + +TotalPagar = compra - descuento + +print(f"El monto total de la compra es de: ${TotalPagar:.2f}") \ No newline at end of file diff --git a/Entrada_de_Datos.py b/Entrada_de_Datos.py new file mode 100644 index 0000000..f9f2815 --- /dev/null +++ b/Entrada_de_Datos.py @@ -0,0 +1,19 @@ +# Entrada de Datos + +# La entrada de datos se hace mediante el metodo input(), sin embargo este metodo solo almacena y permite datos de tipo string, si queremos ingresar un dato de tipo numerico ya sea entero o flotante no no lo va a permitir hasta cierto aspecto y por que digo hasta cierto aspecto? Porque si bien si lo vamos a poder almacenar en ingresar el dato no sera como tal de tipo numerico, si no de tipo string + +#nombre = input("Digite su nombre: ") + +#print(f"Hola {nombre}") + +edad = input("Digite su edad: ") # Lo que estamos haciendo en ingresar un numero, sin embargo este numero para Python no es un dato de tipo numerico, es de tipo string + +print(f"Su edad es {edad}") # Por lo tanto aqui vemos que nos permite generar la entrada de datos aunque este sea un numero, pero no lo podemos tratar como tal, si dentro de la variable numero ejecutamos una suma {numero + 1} veremos que nos arroja un error, esto es debido a que para Python este numero es de tipo string y no se pueden sumar numeros con strings + +# Para poder trabajar con numeros en las entradas necesitamos añadir los metodos int o float (segun sea el caso) antes del input + +numEnt = int(input("Digite un numero: ")) +print(f"El numero ingresado es: {numEnt}. Si sumamos 31 el resultado final es: {numEnt + 31}") # Como podemos observar aqui ya nos permite hacer una suma o cualquier operacion matematica con el valor de la variable ya que nos encargamos de cambiar el tipo de dato de string a number con el metodo int, sin embargo el resultado siempre sera un entero debido a que el metodo es de tipo numerico entero + +numFloat = float(input("Digite el valor de PI: ")) +print(f"El valor de PI es: {numFloat}. Multiplicado por 5, el resultado final es {numFloat * 5}") # Al igual que en el caso anterior aqui pudimos ejecutar una operacion matematica, solo que esta vez fue con numeros flotantes debido a que utilizamos el metodo float() \ No newline at end of file diff --git a/Excepciones.py b/Excepciones.py new file mode 100644 index 0000000..746d8b5 --- /dev/null +++ b/Excepciones.py @@ -0,0 +1,164 @@ +# Excepciones - Pildoras Informaticas + +# Las excepciones son errores que ocurren durante la ejecución del programa. La sintaxís del código es correcta pero durante la ejecución ha ocurrido 'algo inesperado' + +# def suma(num1, num2): +# return num1 + num2 + +# def resta(num1, num2): +# return num1 - num2 + +# def multiplicacion(num1, num2): +# return num1 * num2 + +# def division(num1, num2): +# return num1 / num2 + +# numeroUno = int(input('Ingrese el primer número: ')) + +# numeroDos = int(input('Ingrese el segundo número: ')) + +# operacion = input('Digite la operación matematica a realizar: ') + +# if operacion == 'suma': +# print(suma(numeroUno, numeroDos)) + +# elif operacion == 'resta': +# print(resta(numeroUno, numeroDos)) + +# elif operacion == 'multiplicacion': +# print(multiplicacion(numeroUno, numeroDos)) + +# elif operacion == 'division': +# print(division(numeroUno, numeroDos)) + +# else: +# print('La operacion ingresada no es válida') + +# print('Continuación de la ejecución del programa') + +# Una excepcion clara es dividir un numero entre 0. Ya que la division de un número entre 0 es infinita, esta considerada como una indefinicion. En otras palabras no podemos dividir un numero entre 0. Si corremos el programa actual y hacemos esta division, veremos que el programa nos arroja un error, y esto es un ejemplo claro de una excepcion, ya que no hay error de sintaxis, error de identado, error de tipo etc etc etc, no hay ningun tipo de error en el codigo, sin embargo al generar esta division el programa genera un error y se detiene en esa linea de codigo + +# Podemos controlar este tipo de ejecucion de errores, para que la ejecucion del programa continue. A esto se le conoce como 'manejo o control de excepciones'. Y esto nos sirve para que si nuestro codigo tiene lineas vitales para la ejecucion del programa despues de donde arroja una excepcion, el programa no se caiga ni se detenga por estas excepciones, si no que intente realizar la ejecucion de esa linea que marca la excepcion y si no lo consigue que continue con la ejecucion del codigo que sigue y asi proceder con la ejecucion del codigo y del programa + +# Para controlar las excepciones lo hacemos mediante las instrucciones try y except. Estas instrucciones funcionan de una manera muy similar al if - else. Donde si el try se cumple o se logra ejecutar ignora el except y continua con la ejecucion del programa y viceversa, si el try no se logra ejecutar, pasa al except lo ejecuta y continua con la ejecucion del programa + +# Para controlar la excepcion es necesario utilizar el try y el except en la linea del codigo que nos genera el error. En el try ponemos el codigo que queremos que intente ejecutar y el except es importante que pongamos el error que nos arroja cuando no estamos controlando la excepcion seguido del codigo que queramos que ejecute en el except, este codigo va en el cuerpo + +# Si el error que nos a generado la linea coincide con el error que hemos descrito o estipulado en el except ejecutara el codigo descrito en el cuerpo del except, de no coincidir los errores el programa se detendra y se caera de igual manera que lo hace cuando no estamos controlando la excepcion. En otras palabras si el error generado en la linea no es el mismo descrito en el except el control de excepciones con el try y el except no funcionara + +def suma(num1, num2): + return num1 + num2 + +def resta(num1, num2): + return num1 - num2 + +def multiplicacion(num1, num2): + return num1 * num2 + +def division(num1, num2): + try: + return num1 / num2 + except ZeroDivisionError: + print('No se puede dividir entre 0') + return 'Operación no válida' + +# Aun con el control de excepciones tenemos dos inconvenientes. El primero es que aun funcionando el try el programa seguira corriendo, lo cual hara que nos pida la operacion matematica y no tiene caso alguno la operacion matematica si no tenemos valores numericos ingresados. Y el segundo es que lo anterior nos lleva a otro error que nos genera una excpecion, ya que al no haber valores numericos el programa no sabe que hacer y por ende no puede hacer ninguna operacion matematica, lo cual nos arroja el error NameError, el cual hace referencia a que al no tener la variable el valor correcto esta variable la toma como no definida. Esto (tanto la excepcion como el que pida la operacion matematica a realizar si el dato ingresado NO es un numero) lo podemos solucionar generando un bucle infinito para que mientras el usuario nos ingrese un dato que no sea numerico, se lo vuelva a solicitar y asi no permitir que el programa avance a la linea de codigo que pide la operacion. Este bucle tiene que encerrar el control de excepciones + +while True: + try: + numeroUno = int(input('Ingrese el primer número: ')) + + numeroDos = int(input('Ingrese el segundo número: ')) # Que pasa si en esta linea al momento de que el usuario tenga que ingresar un valor numerico, ingresa algun otro valor? Pues tambien tendriamos una excepcion, ya que nuestro codigo esta bien, no hay errores de sintaxis ni de ningun otro tipo, pero el usuario puede ingresar cualquier valor y si este no es numerico estaria generando un error que esta fuera de nuestro alcance y que tampoco es generado por estar mal el codigo, en este caso tendriamos que controlar esta excepcion de igual manera con un try y un except + break + except ValueError: + print('Los valores ingresados no son válidos. Se requieren valores numericos. Intentalo de nuevo') + +operacion = int(input('''Operaciones matematicas disponibles: + 1 - Sumar + 2 - Restar + 3 - Mulltiplicar + 4 - Dividir + Selecciona la opcion con la operacion a realizar: ''')) + +while operacion < 1 or operacion > 4: + try: + operacion = int(input('''Opción no válida. Opciones válidas: + 1 - Sumar + 2 - Restar + 3 - Mulltiplicar + 4 - Dividir + Inténtalo de nuevo. Selecciona la opción deseada: ''')) + except ValueError: + print('Solo se acepta un valor numerico indicando la operacion deseada') + + +if operacion == 1: + print(suma(numeroUno, numeroDos)) +elif operacion == 2: + print(resta(numeroUno, numeroDos)) +elif operacion == 3: + print(multiplicacion(numeroUno, numeroDos)) +elif operacion == 4: + print(division(numeroUno, numeroDos)) +# else: +# print('La operacion ingresada no es válida') + +print('Continuación de la ejecución del programa') + +# Podemos programar varias excepciones en un mismo try. Ademas tambien podemos hacer una excepcion general, esto quiere decir que no ponemos un error en concreto, si no que con cualquier error sea del tipo que sea estara saltando la excepcion general + +# Y tenemos otra instruccion que es 'finally' esta se ejecuta si o si, aunque haya errores esta se estara ejecutando. Esta instruccion puede ir de forma directa en un try, prescindiendo de los except y esta se ejecutara de igual manera, haya errores o no en el try, finally se ejecutara. Lo que no se puede es tener un try solo, sin excepts o finally porque esto generara un error de sintaxis + +# Vamos a ver lo antes mencionado en otro ejemplo de codigo ya mas breve y abarcando todo en un solo ejemplo + +# Este ejemplo sera diferente al anterior, ya que todo el codigo quedara dentro de una funcion, por lo tanto la funcion sera la encargada de hacerlo todo + +def divide(): + try: + numero1 = float(input('Ingrese el primer numero --> ')) + numero2 = float(input('Ingrese el segundo numero --> ')) + resultado = numero1 / numero2 + print(f'El resultado es: {resultado}') + except ValueError: + print('Error: Solo se acpetan valores numericos') + except ZeroDivisionError: + print('Error: No se puede dividir entre 0') + + # En este ejemplo estamos haciendo uso de varios except en el mismo try, ya que como tal el codigo de la funcion nos puede dar varios posibles errores, por lo tanto para simplificarlo y hacer excepciones de todos ellos podemos hacerlo de generando todas las excepciones posibles dentro del mismo try + + print('Calculo finalizado') + +divide() + +def divide2(): + try: + numero1 = float(input('Ingrese el primer numero --> ')) + numero2 = float(input('Ingrese el segundo numero --> ')) + resultado = numero1 / numero2 + print(f'El resultado es: {resultado}') + except: + print('Ha ocurrido un error. Verifica los datos ingresados') # Esto seria una excpecion general, la cual ocurra el error que ocurra, ya sea en este caso en especifico un ValueError o un ZeroDivisionError ejecutara una sola excepcion y nos imprimira siempre el mismo mensaje de error sea cual sea el error generado + + print('Calculo finalizado') + +divide2() + +print('*****Intruccion finally*****') + +def divide3(): + try: + numero1 = float(input('Ingrese el primer numero --> ')) + numero2 = float(input('Ingrese el segundo numero --> ')) + resultado = numero1 / numero2 + print(f'El resultado es: {resultado}') + finally: + print('Este es el print del finally. Este se ejecuta siempre si o si') + + # Como lo mencionamos anteriormente el finally puede ir solamente con el try, y lo que hara es que si el try da error o no el finally se ejecutara, de echo el finally se ejecutara antes de marcar el error del try en caso de haberlo + + # Con except puede ser que no veamos la diferencia de tener un finally o no, sin embargo si la hay y se ocupa en muchos casos, donde tener o no tener finally marca la diferencia, puede que mas tarde en el curso veamos algun ejemplo, sin embargo en nuestro ejemplo tan sencillo podemos ver la diferencia de tenerlo o no, ya que no hay except de por medio y esto provoca que si tenemos el finally y ejecutamos la funcion el try se ejcutara y sin importar el resultado del try se ejecutara el print del finally, a diferencia de que si no lo tenemos y solo queremos imprimir el print con el try solo veremos que nos arroja un error de sintaxis, debido que no puede haber un try sin except o finally + + print('Calculo finalizado') + +divide3() \ No newline at end of file diff --git a/Excepciones_III.py b/Excepciones_III.py new file mode 100644 index 0000000..224256e --- /dev/null +++ b/Excepciones_III.py @@ -0,0 +1,45 @@ +# Excepciones III - Pildoras Informaticas + +# Lanzamiento de excepciones + +# Con lanzamiento de excepciones no nos referimos a la excepciones que lanza el programa cuando ocurre un error. Mas bien nos referimos a que nosotros como programadores seamos quienes de forma intencional provoquemos y lancemos excepciones cuando ocurra alguna circunstancia en nuestro codigo. En pocas palabras que no sea el programa si no nostros de forma intencionada. + +# Lo anteriormente mencionado lo hacemos con la instruccion Raise. Esta intruccion sera la base para que en un futuro creemos excepciones propias y con esto es donde adquiere la verdadera utilidad (Esto ultimo lo veremos mas adelante cuando veamos la programacion orientada a objetos - POO) + +import math + +def evaluaEdad(edad): + edad = int(input('Introduzca su edad: ')) + if edad < 0: + raise TypeError('No se permiten numeros negativos para la edad') # Es importante recordar que si hacemos uso del raise necesitamos ponerle a este el error que queremos que arroje, puede ser cualquiera como el TypeError, ZeroDivisioError, NameError etc... + + # Con el raise estamos generando un error, una excepcion nosotros mismos cuando asi lo deseemos, en este caso lo estamos haciendo cuando el usuario al momento de ingresar su edad introduzca un numero negativo. Tiene sentido ya que al momento de ingresar un dato erroneo lo mas factible es que el programa se caiga, nos arroje un error y nos diga cual es el error. Adicionalmente el raise como podemos ver nos permite ingresar un texto o algo adicional con lo cual podemos especificar cualquier cosa, en este caso el error que esta comentiendo el usuario al ingresar su edad + if edad < 10: + return 'Eres un niño' + elif edad < 18: + return 'Eres menor de edad y eres un joven' + elif edad < 60: + return 'Eres mayor de edad y ya eres un adulto maduro' + elif edad >= 60: + return 'Eres una persona de la tercera edad. Cuidate...' + +print(evaluaEdad(31)) + +print('Fin del programa 1') + +def calculaRaiz(num): + if num < 0: + raise ValueError('No se aceptan numeros negativos') + else: + return math.sqrt(num) + +digito = int(input('Introduce un numero --> ')) + +try: + print(calculaRaiz(digito)) +except ValueError as ErrorNumeroNegativo: # Podemos darle un nombre o un alias al error con la instruccion 'as'. Esto es como crear una variable y que el alias sea el nombre de la variable y el tipo de error que especificamos en este caso ValueError sera el valor de dicha variable. Si el error tiene un mensaje este se imprimira junto con el tipo de error. Y en el print ponemos el alias que le dimos al error, esto seria como poner el nombre de la variable para que nos imprima su valor + print(ErrorNumeroNegativo) + +print('Fin del programa 2') + +# Al momento de generar el error y este aparecernos en consola, en esta ultima nos aparecen las lineas donde se esta generando dicho error, tanto la linea donde salta la excepcion como la linea que la esta provocando, que en el ejemplo anterior la linea que nos arroja la excepcion es la 'linea 32' y las que esta generando el error es la 'linea 38', antes de hacer uso del try, ya que el print sin el try se recorre una linea para arriba, si comentamos el try la linea que genera el problema seria la linea 39. En otras palabras seria la linea que contiene el llamado de la funcion donde se almacena el digito ingresado por el usuario y que este digito es el que se va a ocupar en la funcion para calcular la raiz cuadrada \ No newline at end of file diff --git a/Expresiones_Regulares.py b/Expresiones_Regulares.py new file mode 100644 index 0000000..54d795a --- /dev/null +++ b/Expresiones_Regulares.py @@ -0,0 +1,237 @@ +# Expresiones Regulares o regex - Pildoras Informaticas / Videos 69 y 70 + +# Metacaracteres, clases de caracteres y algunas expresiones regulares del modulo re + +""" Las expresiones regualares son una secuencia de caracteres que forman un patron de busqueda + + Sirven para el trabajo y procesamiento de texto + + Algunos ejemplos serian: + + - Buscar un texto que se ajuste a un formato determinado (email) + - Buscar si existe o no una cadena de caracteres dentro de un texto + - Contar el numero de coincidencias dentro de un texto + - Etc... """ + +# Para trabajar con regex hay que importar el metodo 're'. Este metodo almacena varias regex que podemos utilizar. Para ver todos las regex de este metodo podemos buscar en google regex en python y en la documentacion oficial encontraremos todos las regex disponibles en este metodo. + +# En este archivo solo veremos algunas de estas regex + +# Podemos crear nuestras propias expresiones regulares dentro de Python + +import re + +# ----- Regex search() ----- + +print('----- Regex search -----') + +cadena = 'Vamos a aprender expresiones regulares' + +texto_buscar = 'aprender' + +# is not es el equivalente a !=, este 'is not' no lo hemos visto hasta ahora pero es mas que valido en python + +if re.search(texto_buscar, cadena) is not None: + print(f'Eh encontrado el texto "{texto_buscar}"') + +else: + print(f'No eh encontrado el texto "{texto_buscar}"') + +texto_buscar = 'regex' + +if re.search(texto_buscar, cadena) != None: + print(f'Eh encontrado el texto "{texto_buscar}"') + +else: + print(f'No eh encontrado el texto "{texto_buscar}"') + +# ----- Regex start() ----- + +print('----- Regex start -----') + +# La regex start nos arroja como resultado el index o caracter donde comienza la palabra, el valor o caracter que le pasamos como parametro a buscar + +indice_comienzo = 'expresiones' + +texto_encontrado = re.search(indice_comienzo, cadena) + +print(texto_encontrado.start()) + +# ----- Regex end() ----- + +print('----- Regex end -----') + +# La regex end nos arroja como resultado el index o caracter donde finaliza la palabra, el valor o caracter que le pasamos como parametro a buscar + +indice_comienzo = 'expresiones' + +texto_encontrado = re.search(indice_comienzo, cadena) + +print(texto_encontrado.end()) + +# ----- Regex span() ----- + +print('----- Regex span -----') + +# La regex span nos arroja como resultado en forma de tupla los indices donde comienza y finaliza la palabra, el valor o caracter que le pasamos como parametro a buscar. Es un 2 es 1, hace el trabajo del start y del end en uno solo + +indices = 'regulares' + +texto_encontrado = re.search(indices, cadena) + +print(texto_encontrado.span()) + +# ----- Regex findall() ----- + +print('----- Regex findall -----') + +# La regex findall nos arroja como resultado en forma de lista todas las coincidencias que encontro de la palabra, el valor o caracter que le pasamos como parametro a buscar + +cadena = 'Vamos a aprender expresiones regulares en Python. Python cuenta con una libreria o metodo que ya tiene expresiones regulares las cuales las podemos ocupar de forma libre. Estas expresiones son muy utilizadas a la hora de programar' + +coincidencias = 'Python' + +print(re.findall('Python', cadena)) + +print(re.findall('expresiones', cadena)) + +print(re.findall('regulares', cadena)) + +# Dentro de la lista que arroja el resultado del findall nos dara no el numero de veces que se repite una palabra, valor o caracter si no todas las coincidencias de estos ultimos, ya se una, dos, diez, cien etc. Pero ya con esto podemos saber cuantas veces se repite una palabra, valor o caracter con el metodo len por si llegasen a ser muchos no estar contando uno por uno para saber el numero de veces que se repite + +print(len(re.findall('Python', cadena)),'- Son las veces que se repite la palabra Python en el texto') + +print(len(re.findall('expresiones', cadena)),'- Son las veces que se repite la palabra expresiones en el texto') + +print(len(re.findall('regulares', cadena)),'- Son las veces que se repite la palabra regulares en el texto') + +print('') +print('----- EXPRESIONES REGULARES 2DA PARTE -----') +print('') + +# metacaracteres (tambien se llegan a conocer como caracteres comodin) + +# Anclas y clases de caracteres + +# ----- Anclas ----- + +# Hay anclas de principio y fin y estas nos sirven para determinar busquedas que empiecen o terminen con una palabra, valor o caracter en especifico + +# Lo que vamos a hacer a continuacion es usar anclas de principio (^) y fin ($) para buscar dentro de una lista personas que empiecen con un nombre en especifico asi como las personas que terminen con un apellido en especifico + +lista_nombres = [ + 'Ana Gomez', + 'Maria Martín', + 'Sandra López', + 'Santiago Martín', + 'Sandra Fernández' +] + +print('----- Metacaracter inicio / Ancla ^ -----') + +for elemento in lista_nombres: + if re.findall('^Sandra', elemento): + print(elemento) + +print('----- Metacaracter fin / Ancla $ -----') + +for elemento in lista_nombres: + if re.findall('Martín$', elemento): + print(elemento) + +print('----- Ejemplos con urls -----') + +lista_urls = [ + 'http://paperforall.com', + 'ftp://paperforall.com', + 'http://paperforall.es', + 'ftp://paperforall.es', + 'http://paperforall.mx', + 'ftp://paperforall.mx' +] + +print('--- Comienzo ftp ---') + +for elemento in lista_urls: + if re.findall('^ftp', elemento): + print(elemento) + +print('--- Termina es ---') + +for elemento in lista_urls: + if re.findall('es$', elemento): + print(elemento) + +print('--- Comienzo http ---') + +for elemento in lista_urls: + if re.findall('^http', elemento): + print(elemento) + +print('--- Termina com ---') + +for elemento in lista_urls: + if re.findall('com$', elemento): + print(elemento) + +print('--- Termina mx ---') + +for elemento in lista_urls: + if re.findall('mx$', elemento): + print(elemento) + +print('--- Termina com.mx ---') + +for elemento in lista_urls: + if re.findall('com.mx$', elemento): + print(elemento) + else: + print('No hay urls con dominios .com.mx') + + +# Clases de caracteres --> Estos van entre corchetes [] y nos sirven como patron de busqueda, lo que vaya dentro de los cochetes es lo que va a buscar pero no necesariamente en el orden en el que se encuentren + +print('----- Clases de caracteres -----') + +lista_paginas = [ + 'https://elpapeldelmañana.com', + 'https://paperforall.com', + 'https://labodegadepapel.com' +] + +for elemento in lista_paginas: + if re.findall('[ñ]', elemento): + print(elemento) + +# Vemos al imprimir que nos imprime la primer pagina ya que esta contiene en su nombre el caracter 'ñ' + +# Tambien podemos hacer patrones de busquedas mas complejos o especificos + +print('') + +lista_seres = [ + 'hombres', + 'mujeres', + 'niños', + 'niñas', + 'mascotas', +] + +for elemento in lista_seres: + if re.findall('niñ[oa]s', elemento): + print(elemento) + +# El patron de busqueda diferencia caracteres como el acento y tambien entre mayusculas y minusculas + +print('') + +lista_camion = [ + 'camión', + 'camion', + 'Camion', + 'Camión' +] + +for elemento in lista_camion: + if re.findall('Cami[oó]n', elemento): + print(elemento) \ No newline at end of file diff --git a/Expresiones_Regulares2.py b/Expresiones_Regulares2.py new file mode 100644 index 0000000..cff21d5 --- /dev/null +++ b/Expresiones_Regulares2.py @@ -0,0 +1,222 @@ +# Expresiones Regulares 2 - Pildoras Informaticas / Videos 71 y 72 + +# Rangos, Match y Search + +# Rangos + +# Diferencia entre mayusculas y minusculas + +""" Metacaracteres / Anclas --> '^', '$' (Inicio / Fin) + Clases de caracteres --> [] + Rangos --> Determinar un rango especifico: ej de una letra a otra. Este rango se especifica dentro de los corchetes (clases de caracteres) """ + +import re + +lista_nombres = [ + 'Moises', + 'Efrain', + 'Nahun', + 'Arnulfo', + 'Lilia', + 'Susett', + 'Sandra' +] + +print('--- Nombres que contengan las letras entre la o y la t en ellos ---') + +for element in lista_nombres: + if re.findall('[o-t]', element): + print(element) + +print('--- Nombres que comiencen con las letras entre la O y la T ---') + +for element in lista_nombres: + if re.findall('^[O-T]', element): + print(element) + +print('--- Nombres que terminan con las letras entre la o y la t ---') + +for element in lista_nombres: + if re.findall('[o-t]$', element): + print(element) + +# Como podemos observar los rangos van de la mano con las clases de caracteres y se pueden utilizar en conjunto con los metacaracteres para generar busquedas mas detallas o especificas + +# Los rangos suelen ser bastantes utiles cuando tenemos codigos como de productos, zonas, clientes etc dentro de una lista + +# Supongamos que creamos un programa que determine mediante el numero de cliente el numero de pedido que ha hecho y que estos los queremos filtrar o mostrar ya sea de acuerdo al codigo del cliente o a numeros de pedidos similares etc + +print('--- Numero de pedidos de un cliente mediante el rango ---') + +lista_pedidos = [ + 'Mo-1', + 'Ef.1', + 'Na:1', + 'Mo-2', + 'Ar.1', + 'Ar.2', + 'Li:1', + 'Na-2', + 'Li:2', + 'Ef.2', + 'Mo-3', + 'Li:3', + 'Mo-4', + 'Mo-A', + 'Mo-5', + 'Mo-B', + 'Mo-C' +] + +for element in lista_pedidos: + if re.findall('Mo-[0-3]', element): + print(element) + +# Podemos generar el resultado inverso, que en ves de que nos arroje del 0 al 3, sean estos los que no tome en cuenta, y esto lo hacemos con el acento circunflejo, de esta manera estamos como invirtiendo o negando el rango, no entendi muy bien como funciona y porque, pero de esta manera generamos el resultado contrario o inverso + +print('--- Resultado inverso del anterior ---') + +for element in lista_pedidos: + if re.findall('Mo-[^0-3]', element): + print(element) + +print('--- Resultado mezclando diferentes caracteres ---') + +for element in lista_pedidos: + if re.findall('Mo-[0-3A-B]', element): + print(element) + +print('--- Resultado con signos ---') + +for element in lista_pedidos: + if re.findall('[.:]', element): + print(element) + +# De igual manera podemos filtras estos resultados con el codigo de un cliente en concreto + +print('--- Filtrado por un cliente en concreto ---') + +for element in lista_pedidos: + if re.findall('Ar[.:]', element) or re.findall('Li[.:]', element): + print(element) + +print('--- Filtrado por un cliente en concreto 2 ---') + +for element in lista_pedidos: + if re.findall('Ef[.:]', element) or re.findall('Na[.:]', element): + print(element) + +# Funciones match y search + +# match() --> Busca si hay coincidencias en un patron de busqueda al comienzo de una cadena de texto, siempre al comienzo. + +# La funcion match distingue entre mayusuclas y minusculas + +# De entrada lleva 2 parametros, el primero es el patron de busqueda y el segundo es con quien lo queremos comparar o donde lo queremos buscar. Adicional acepta un tercer parametro que hace referencia a lo que se denomina 'flag'. Este tercer parametro es para el case sensitive, para que no haga distincion entre mayusculas y minusculas y el parametro es re.IGNORECASE + +print('----- Funcion match() -----') + +nombre_uno = 'Sandra López' + +nombre_dos = 'Antonio Gómez' + +nombre_tres = 'María López' + +if re.match('Sandra', nombre_uno): + print('Nombre encontrado') +else: + print('Nombre NO encontrado') + +if re.match('Sandra', nombre_dos): + print('Nombre encontrado') +else: + print('Nombre NO encontrado') + +if re.match('sandra', nombre_uno): + print('Nombre encontrado') +else: + print('Nombre NO encontrado') + +if re.match('Sandra', nombre_uno, re.IGNORECASE): + print('Nombre encontrado') +else: + print('Nombre NO encontrado') + +# Podemos utilizar el punto que sirve como comodin + +print('--- Comodin punto (.) ---') + +nombre_uno = 'Jara Lopez' + +nombre_dos = 'Lara Croft' + +if re.match('.ara', nombre_uno): + print(f'Se ha encontrado el nombre {nombre_uno}') +else: + print('No se ha encontrado ninguna coincidencia') + +if re.match('.ara', nombre_dos): + print(f'Se ha encontrado el nombre {nombre_dos}') +else: + print('No se ha encontrado ninguna coincidencia') + +# Cadenas que empiecen con numeros + +# Hay una expresion regular en Python la cual es \d, esta lo que hara ver si la cadena comienza con un numero o no. Con match buscara al inicio, ya que match siempre busca al comienzo + +print('--- Cadenas con numeros ---') + +cadena_uno = '51349' + +cadena_dos = 'a56457' + +if re.match('\d', cadena_uno): + print('La cadena comienza con un numero') +else: + print('La cadena NO comienza con un numero') + +if re.match('\d', cadena_dos): + print('La cadena comienza con un numero') +else: + print('La cadena NO comienza con un numero') + +# Funcion search() --> Busca si hay coincidencias en un patron de busqueda en toda la cadena de texto + +print('----- Funcion search() -----') + +nombre_uno = 'Sandra López' + +nombre_dos = 'Antonio Gómez' + +nombre_tres = 'María López' + +if re.search('Lopez', nombre_uno): + print('Se ha encontrado el apellido López') +else: + print('No se ha encontrado el apellido López') + +if re.search('L[oó]pez', nombre_uno): + print('Se ha encontrado el apellido López') +else: + print('No se ha encontrado el apellido López') + +codigo_uno = 'kjskdhf jsdklfid71fjek njvbnvcxlk sdkjfdf' + +codigo_dos = 'hjshdus71ksdj fijdifdñdf kodkfo' + +codigo_tres = 'mnjdhfui ewioejf nklsc jpomd' + +if re.search('71', codigo_uno): + print('Se a encontrado el numero 71') +else: + print('No se ha encontrado el numero 71') + +if re.search('71', codigo_dos): + print('Se a encontrado el numero 71') +else: + print('No se ha encontrado el numero 71') + +if re.search('71', codigo_tres): + print('Se a encontrado el numero 71') +else: + print('No se ha encontrado el numero 71') \ No newline at end of file diff --git a/Funcion_Filter.py b/Funcion_Filter.py new file mode 100644 index 0000000..350ca60 --- /dev/null +++ b/Funcion_Filter.py @@ -0,0 +1,50 @@ +# Funcion Filter + +# La funcion filter forma parte de un grupo de funciones que se les denomina funciones de orden superior. Nos permiten utilizar un paradigma que se denomina programacion funcional + +# La funcion filter verifica que los elementos de una secuencia cumplen una condicion devolviendo un iterador con los elementos que cumplen dicha condicion + + +def numeroPar(num): + + if num % 2 == 0: + return True + +numeros = {17, 24, 7, 39, 8, 51, 92} + +print(list(filter(numeroPar, numeros))) + +numero_par = lambda num: num % 2 == 0 + +print(list(filter(numero_par, numeros))) + +# Podemos hacer la funcin lambda directamente en el print + +print(list(filter(lambda num : num % 2 == 1, numeros))) # Al hacerlo mediante la funcion lambda estamos prescindiendo de la declaracion de la funcion como tal, ya que esta la podemos declarar de forma directa en el print + +print('----- Salarios Empleados -----') + +class Empleados: + + def __init__(self, nombre, puesto, salario): + self.nombre = nombre + self.puesto = puesto + self.salario = salario + + def __str__(self): + + return f'Nombre: {self.nombre} - Puesto: {self.puesto} - Sueldo: {self.salario}' + +lista_empleados = [ + Empleados('Moises Hernandez', 'Presidente', 60000), + Empleados('Nahun Fernandez', 'Director', 55000), + Empleados('Efrain Hernandez', 'Subdirector', 45000), + Empleados('Sandra Arzate', 'Contadora', 30000), + Empleados('Lilia Lopez', 'Jefa de Ventas', 20000), + Empleados('Arnulfo Hernandez', 'Jefe de Repartos y Entregas', 20000) +] + +salariosSocios = filter(lambda empleado: empleado.salario > 50000, lista_empleados) + +for mayoresSalarios in salariosSocios: + print(mayoresSalarios) \ No newline at end of file diff --git a/Funcion_Map.py b/Funcion_Map.py new file mode 100644 index 0000000..ddce023 --- /dev/null +++ b/Funcion_Map.py @@ -0,0 +1,60 @@ +# Funcion Map + +# La funcion map aplica una funcion a cada elemento de una lista iterable (listas, tuplas, etc...) devolviendo una lista con los resultados + +class Empleado(): + + def __init__(self, nombre, puesto, sueldo): + self.nombre = nombre + self.puesto = puesto + self.sueldo = sueldo + + def __str__(self): + return f'Nombre: {self.nombre} / Puesto: {self.puesto} / Sueldo: {self.sueldo}' + +lista_empleados = [ + Empleado('Moises', 'Jefe de Logistica', 15000), + Empleado('Efrain', 'Jefe de Mercadotecnia', 15000), + Empleado('Nahun', 'Jefe de Proyectos', 15000), + Empleado('Lilia', 'Jefa de Ventas', 8000), + Empleado('Arnulfo', 'Jefe de Envios y Repartos', 8000) +] + +lista_empleados2 = [ + Empleado('Moises', 'Jefe de Logistica', 15000), + Empleado('Efrain', 'Jefe de Mercadotecnia', 15000), + Empleado('Nahun', 'Jefe de Proyectos', 15000), + Empleado('Arnulfo', 'Jefe de envios y repartos', 8000), + Empleado('Lilia', 'Jefa de Ventas', 8000) +] + +def comision(empleado): + empleado.sueldo = empleado.sueldo * 1.05 + + return empleado + +# En la funcion map el primer parametro que se pone es una funcion (la funcion que queremos que se ejecute con ese map) + +lista_comisionEmpleados = map(comision, lista_empleados) + +for empleado in lista_comisionEmpleados: + print(empleado) + +# Con la funcion map se pueden hacer muchas mas cosas y cosas mas complejas en comparacion con la funcion filter, ya que la funcion map si bien no se le pone como tal funciones dentro de esta si trabaja con funciones ya creadas y estas solo se le pasan a la funcion map + +# En el siguiente caso vamos a hacer mediante la funcion map que solo empleados con sueldos abajo de los 10000 tengan el beneficio de la comision + +print() +print('----- Comision a salarios por debajo de 10,000 -----') + +def comisionSalariosBajos(empleado): + if empleado.sueldo <= 10000: + empleado.sueldo = empleado.sueldo * 1.03 + return empleado + +comision_sueldosBajos = map(comisionSalariosBajos, lista_empleados2) + +# print(comision_sueldosBajos) Si solo dejo este print veremos que nos arroja como resultaodp un objeto de tipo map, tal vez de primeras pensemos que esto es un error o algo por el estilo por la forma en que lo presenta y sobre todo por lo ultimo que aparece en el print que parece no tener sentido, pero en realidad el codigo se esta ejecutando correctamente, solo que no arroja la lista que guarda, para esto tenemos que hacer que la imprima, de lo contario solo nos estaria imprimiend el tipo de objeto que en este caso en un objeto de tipo map, esto mismo pasa con la funcion filter + +for empleado in comision_sueldosBajos: + print(empleado) \ No newline at end of file diff --git a/Funciones.py b/Funciones.py new file mode 100644 index 0000000..7c366a1 --- /dev/null +++ b/Funciones.py @@ -0,0 +1,93 @@ +# Funciones + +# Conjunto de lineas de código agrupadas (bloque de código) que funcionan como una unidad realizando una tarea específica + +#Las funciones en Python pueden devolver valores + +# Las funciones en Python pueden tener parámetros/argumentos + +# A las funciones también se les denomina métodos cuando se encuentran definidas dentro de una clase + +""" Utilidad de las funciones + + Reutilizar el codigo (si es necesario o cuando sea necesario) """ + +""" Sintaxís de las funciones (def es una palabra reservada para la creacion de funciones) + + def nombre_funcion(): + Instrucciones de la función + return (opcional) + + def nombre_función(parámetros) + Instrucciones de la función + return (opcional) """ + +""" Ejecutar función + + nombre_funcion() + + nombre_funcion(parámetros) """ + +def mensajes(): # Aqui estamos declarando la funcion + print('Aprendiendo funciones') + print('Nueva funcion') + print('Hola Mundo') + +# Es importante recordar que una funcion no se ejecutara hasta que esta no sea llamada + +mensajes() # Aqui estamos llamando a la funcion + +# Funciones con parametros/argumentos + +def suma(): + num1 = 5 + num2 = 3 + resultado = num1 + num2 + print(resultado) + +suma() + +# En el caso anterior vemos una funcion simple, sin parametros, pero que pasa si queremos reutilizar esta funcion y cada vez que la reutilicemos necesitamos o queremos que los valores de num1 y num2 sean diferentes? Pues aqui es donde entran los parametros para poder hacer esto + +def suma2(num1, num2): + resultado = num1 + num2 + print(resultado) + +# Al momento de declarar los parametros ya no es necesario asignar los valores de num1 y num2 dentro del cuerpo de la funcion, ya que lo estariamos haciendo al momento de llamar la funcion, y asi cada vez que la llamemos o reutilicemos podemos agregar valores diferentes y estos se almacenaran en los parametros asignados a la funcion. Los valores se almacen en el orden de los parametros + +# Se le pueden pasar parametros de cualquier tipo de dato, numericos enteros o flotantes, cadenas o strings y / o booleanos, de echo pueden estar mezclados + +print('Llamada 1') +suma2(5,7) + +print('Llamada 2') +suma2(2,6) + +print('Llamada 3') +suma2(220,165) + +# Con esto podemos ver de forma mas clara la utilidad de las funciones + +# Return en una funcion + +# Podria parecer que el utilizar el return no tiene sentido y hasta se vuelve mas engrolloso y se le da mas vuelta y ms codigo, ya que se podria poner de forma directa por ejemplo el print del resultado, sin embargo aunque asi pueda parecer, tiene gran potencial y gran utilidad tener un return ya que este se puede almacenar en una variable y despues reutilizar esta variable por poner un ejemplo practico del porque y para que nos sirve el return + +# Si tenemos un return en nuestra funcion y mandamos a llamar la funcion pareciera que no hace nada y esto es porque aunque el programa se esta ejecutando correctamente el return es eso un return, esta regresando un valor, pero este no actua como un print o algo mas, por lo tanto si queremos visualizar el return tendriamos que ocupar el print al momento de llamar la funcion + +""" Ejemplo llamada funcion con return + + def funcion(num1, num2): + resultado = num1 + num2 + return resultado + + print(funcion(5,8))""" + +print('Funcion con Return') + +def conRegreso(num1, num2): + resultado = num1 + num2 + return resultado + +resFuncion = conRegreso(5,8) + +print(resFuncion) \ No newline at end of file diff --git a/Funciones_Decoradoras.py b/Funciones_Decoradoras.py new file mode 100644 index 0000000..75be54a --- /dev/null +++ b/Funciones_Decoradoras.py @@ -0,0 +1,115 @@ +# Funciones Decoradoras + +# Son funciones que añaden funcionalidades a otras funciones + +""" Estructura de un decorador + + - Una funcion decoradora esta conformado por 3 funciones (A, B y C) donde A recibe como parametro a B para devolver C + + - Un decorador devuelve una funcion + + def funcion_decoradora(funcion): + def funcion_interna(): + < codigo de la funcion interna > + return funcion_interna +""" + +def funcion_decoradora(funcion_externa): + + def funcion_interna(): + + print('El resultado de la operacion es: ') + + funcion_externa() + + print('¡El cálculo se ha realizado con éxito!') + + return funcion_interna + +# Para que esta funcion decoradora surta efecto en las demas funciones, hay que decorar, decirle al programa las funciones que queremos que lleve esta decoracion o esta funcion decoradora, y esto lo hacemos mediante la nomenclatura @nombre_funcion_decoradora, esta nomenclatura debe de ir encima de la funcion que queremos que lleve la funcion decoradora + +@funcion_decoradora +def suma(): + print(15 + 20) + +def resta(): + print(30 - 10) + +@funcion_decoradora +def multiplicacion(): + print(5 * 12) + +print('--- Funcion suma ---') +suma() + +print('--- Funcion resta ---') +resta() + +print('--- Funcion multiplicacion ---') +multiplicacion() + +# Funciones decoradoras con parametros en funciones externas + +def funcionDecoradoraUno(funcion_externa): + + def funcion_interna(*args): # Con la nomenclatura *args (que 'args' es un estandar, una convencion, se le puede dar cualquier nombre), le estamos diciendo que la funcion externa a la cual le vamos a agregar la funcion decoradora va a recibir o tiene que recibir parametros + + print('El resultado del cálculo es:') + + funcion_externa(*args) # Aqui le agregamos ese parametro ya que aqui es donde estamos llamamando por decirlo de alguna manera a la funcion externa + + return funcion_interna + +@funcionDecoradoraUno +def suma_uno(num1, num2): + print(num1 + num2) + +@funcionDecoradoraUno +def resta_uno(num1, num2): + print(num1 - num2) + +@funcionDecoradoraUno +def mult_uno(num1, num2): + print(num1 * num2) + +@funcionDecoradoraUno +def opLibre(num1, num2, num3, num4): + print(num1 + num2 * num3 / num4) + +print('--- Funcion suma con parametros ---') +suma_uno(13,5) + +print('--- Funcion resta con parametros ---') +resta_uno(7,1) + +print('--- Funcion multiplicacion con parametros ---') +mult_uno(9,8) + +print('--- Funcion operacion libre con parametros ---') +opLibre(9.2, 8, 1.5, 7) + +# Adicionalmente podemos agregarle otro parametros a la funcion interna, el cual hace referencia a keywords, que es esto de keywords? Es lo que se conoce como clave-valor y esto es cuando especificamos que un valor corresponde a algo en especifico, este parametro se suele definir con kwargs que es como la abreviacion y conjuncion de keywords con arguments. Veamoslo en un ejemplo practico para que sea mas entendible + +print('--- Parametro kwargs ---') + +def funcionDecoradoraDos(funcion_externa): + + def funcionInterna(*args, **kwargs): + + print('El resultado de la potencia es:') + + funcion_externa(*args, **kwargs) + + return funcionInterna + +def potencia(base, exponente): + print(pow(base, exponente)) + +potencia(5, 3) + +# La clave-valor es cuando especificamos que corresponde a que, en otras palabras cuando ocupamos una clave y a esa clave le damos un valor, esto a modo de identificacion por decirlo de alguna manera, veamos un ejemplo + +def potenciaClaveValor(base, exponente): + print(pow(base, potencia)) + + potenciaClaveValor(base=5, exponente=3) # Esto es clave-valor, donde al valor de 5 le estamos dando la clave 'base' y al valor de 3 le estamos dando la clave 'exponente'. Si en la funcion interna quitamos el parametro **kwargs al momento de llegar a esta parte del codigo nos daria un error, ya que el parametro *args solo sirve para dar o asignar varios parametros, pero no cuando estos parametros o valores tiene una clave, para eso agregamos el parametro **kwargs \ No newline at end of file diff --git a/Funciones_Integradas.py b/Funciones_Integradas.py new file mode 100644 index 0000000..e641fb1 --- /dev/null +++ b/Funciones_Integradas.py @@ -0,0 +1,61 @@ +# Funciones Integradas + +# Una funcion integrada sirve para hacer conversiones de tipos de datos. int(), float() etc... + +""" Algunas funciones integradas son: + - int() --> Convierte el dato a tipo numerico entero + - float() --> Convierte el dato a tipo numerico float + - str() --> Convierte el dato a tipo string + - bin() --> Convierte el dato a tipo binario (los dos primeros valores indican que es un dato de tipo binario) + - hex() --> Convierte el dato a tipo hexadecimal (los dos primeros valores indican que es un dato de tipo hexadecimal) + - abs() --> Da como resultado el valor absoluto de "x" numero. (El valor absoluto es el valor positivo) + - round() --> Redondea el valor hacia la baja o alza dependiendo del decimal, de .5 para arriba se va para el alza, de .4 para abajo se para la baja + - len() --> Cuenta el numero de caracteres que conforman una string +""" + +a = int("10") +print(a) +print(type(a)) + +a = float("10.59") +print(a) +print(type(a)) + +a = str(10.9) +print(a) +print(type(a)) + +b = bin(10) +print(b) +print(type(b)) + +h = hex(10) +print(h) +print(type(h)) + +# Tanto en la funcion integrada bin() como en la hex() aunque en el tipo de dato aparezca como str, los primeros digitos del resultado de estas dos nos indican que tipo de dato es. Para los binarios sera "0b" y para los hexadecimales sera "0x", con esto podemos asegurarnos que nuesto valor no es una string si no un binario o hexadecimal + +# De igual forma podemos convertir binarios o hexadecimales a tipo de dato entero + +# Para convertir datos de tipo binario y hexadecimal a entero es necesario poner el valor en forma de string, seguido de una coma y por ultimo la base en la que se encuentra el valor a convertir --> binario = 2 y hexadecimal = 16 + +b = int("0b1010", 2) +print(b) +print(type(b)) + +h = int("0xa", 16) +print(h) +print(type(h)) + +pos = abs(-8) +print(pos) +print(type(pos)) + +red = round(5.6) +red2 = round(5.4) + +print(red, red2) +print(type(red), type(red2)) + +nombre = len("Eliab Hdez") # Los espacios cuentan como caracteres +print(nombre) \ No newline at end of file diff --git a/Funciones_Lambda.py b/Funciones_Lambda.py new file mode 100644 index 0000000..908f505 --- /dev/null +++ b/Funciones_Lambda.py @@ -0,0 +1,64 @@ +# Funciones Lambda + +# Las funciones lambda son funciones anonimas y sirven para abreviar la sintaxis y que el codigo sea mas ligero y menor + +# Todo lo que podemos hacer con una funcion lambda se puede hacer con una funcion normal, pero NO al reves, no todo lo que se puede hacer con una funcion normal, lo podemos hacer con una funcion lambda + +# Las funciones lambda no pueden contener bucles, condicionales etc... + +# Se les conoce como funciones anonimas ya que no tienen nombre alguno, se generan o guardan mediante una variable, pero la funcion como tal no tiene un nombre. Si nos fijamos en los ejemplos siguientes del archivo, la funcion normal tiene un nombre 'areaTriangulo', mientras que la funcion lambda no tiene nombre, esta almacenada en una variable y el nombre corresponde a la variable, pero la funcion como tal no tiene uno + +# Tambien podemos encotrar estas funciones como 'on the go', 'on demand' y/o 'online'. Son terminos con los que tambien se les conoce a las funciones lambda + +# --------- Funcion normal --------- + +print('------Funcione normal------') + +def areaTriangulo(base, altura): + + return (base*altura)/2 + +print(areaTriangulo(5,7)) + +triangulo_uno = areaTriangulo(5,7) + +triangulo_dos = areaTriangulo(9,6) + +print(triangulo_uno) +print(triangulo_dos) + +# --------- Funcion Lambda --------- + +# En las funciones lambda los dos puntos es el equivalente al return de una funcion normal + +print('------Funcion Lambda 1------') + +area_triandulo_lambda = lambda base, altura: (base * altura) / 2 + +print(area_triandulo_lambda(12,35)) +print(area_triandulo_lambda(3,8)) + +area_triangulo_uno = area_triandulo_lambda(2,4) +area_triangulo_dos = area_triandulo_lambda(17,25) + +print(area_triangulo_uno) +print(area_triangulo_dos) + +print('------Funcion Lambda 2------') + +al_cubo = lambda numero: pow(numero, 3) + +al_cubo_dos = lambda numero: numero ** 3 + +print(al_cubo(3)) +print(al_cubo_dos(5)) + +print('------Funcion Lambda 3------') + +destacar_comision = lambda comision: f"!$ {comision}¡ de comisión" + +comision_Ana_valorString = '12,384' +comision_Ana_valorNumerico = '6,823' + +print(destacar_comision(comision_Ana_valorString)) +print(destacar_comision(comision_Ana_valorNumerico)) \ No newline at end of file diff --git a/Generadores.py b/Generadores.py new file mode 100644 index 0000000..d93d7dd --- /dev/null +++ b/Generadores.py @@ -0,0 +1,118 @@ +# Generadores - Pildoras Informaticas + +# Los Generadores son estructuras que extraen valores de la función (del mismo generador) y se almacenan en objetos iterables, esto quiere decir que lo que se extraiga se va a poder recorrer con un bucle for o while o con alguna otra estructura como iteradores o el metodo next + +# Los valores extraidos se almacena de uno en uno + +# Cada vez que un generador almacena un valor, este permanece en estado pausado hasta que se solicita el siguiente. Esta caracteristica es conocida como 'suspensión de estado' + +""" Las utilidades que tienen por mencionar algunas son: + + - Son más eficientes que las funciones tradicionales + - Muy útiles con listas de valores infinitos + - Bajo determinados escenario, será muy útil que un generador devuelva los valores de uno en uno """ + +""" Sintaxis de un generador + + - Basicamente la misma que la de una funcion + + def --> Palabra reservada + nombreFuncion + codigo del cuerpo + yield --> Palabra reservada + + Y tambien adicionalmente puede tener un 'return' + + def miGenerador(): + codigo del cuerpo a ejecutar + yield + """ + +# La instruccion yield es la que se encarga de construir el objeto iterable que va a almacenar los valores del objeto generador + +# Vamos a crear un programa que nos genere una lista de numeros pares. De entrada se hara con una funcion tradicional y posteriormente vamos a copias y modificar el codigo para convertirlo en un generador y de esta manera ver la diferencia que hay entre los dos + +print('Programa con funcion tradicional') + +def generaPares(limite): + num = 1 + miLista = [] + while num < limite: + miLista.append(num * 2) + num += 1 + return miLista + +print(generaPares(10)) + +# Generador + +print('Programa con Generador') + +def generaPares2(limite): + num = 1 + while num < limite: + yield num*2 + num += 1 + +devuelvePares = generaPares2(10) + +# Si lo que queremos es que nos arroje valor por valor, uno a la vez que es el fuerte de los generadores en comparacion con las funciones tradicionales, lo tenemos que hacer mediante el metodo next(). Este metodo lo que hace es ir extrayendo a cada llamada del generador el siguiente valor y de ahi el nombre next + +print(next(devuelvePares)) + +print('Aqui podria ir mas codigo') + +print('Despues de varias lineas de codigo de nuestro programa, volvemos a llamar al siguiente valor del generador') + +print(next(devuelvePares)) + +print('Aqui podria ir mas codigo') + +print('Volvemos a llamar una vez mas al generador para el siguiente valor y asi sucesivamente') + +print(next(devuelvePares)) + +# for i in devuelvePares: # el bucle for nos sirve para recorrer todos los elementos del objeto generador y asi obtener el objeto en su totalidad +# print(i) + +# Como podemos ver el generador no a construido del todo el objeto con todos los numeros pares que solicitamos en el limte del generador, esto hace que no se consuman recursos de mas e innecesarios cuando no necesitamos todos los valores del objeto en su totalidad y asi optimizar recursos y velocidad solicitando solo los valores del objeto generador conforme los vayamos requiriendo + +# Instruccion 'yield from' + +# La instruccion yield from tiene la utilidad de simplificar el código de los generadores en el caso de utilizar bucles anidados dentro del generador + +# En python cuando ponemos un asterisco (*) antes de un parametro o argumento en una funcion l estamos diciendo que va a recibir un numero indeterminado de elementos, que podrian ser 1, 2, 3, 5 o 20 y que ademas esos argumentos o elementos los va a recibir en forma de tupla + +def devuelveCiudades(*ciudades): + for elemento in ciudades: + yield elemento + +ciudadesDevueltas = devuelveCiudades('Madrid', 'Barcelona', 'Valencia', 'Bilbao') + +print(next(ciudadesDevueltas)) +print(next(ciudadesDevueltas)) + +# Los elementos del generador tienen a su vez subelementos y con esto no queremos decir que cada elemento tenga otro elemento como tal dentro, si no que lo que conforma el elemento es un subelemento. En otras palabras los elementos que son ciudades por ejemplo Madrid, tiene a su vez subelementos y estos subelementos son las letras que conforman la palabra Madrid + +# Para poder acceder a estos subelementos (letras) necesitariamos hacer uso de un bucle for anidado en el generador + +# Sin embargo la instruccion yield from simplifica el codigo al hacer esto y con el uso de esta eliminamos el uso del bucle anidado + +def devuelveCiudades2(*ciudades): + for elemento in ciudades: + # for subElemento in elemento: # Con este bucle for anidado accedemos a los subelementos de los elementos del generador + yield from elemento # Con el yield from como podemos observar obtenemos el mismo resultado eliminando el uso del bucle for anidado. Basicamente le estamos diciendo 'devuelvenos desde el elemento' que se podria traducir a que el elemento es el objetivo y que nos devuelva un resultado desde este elemento + +ciudadesDevueltas2 = devuelveCiudades2('Madrid', 'Barcelona', 'Valencia') + +print(next(ciudadesDevueltas2)) +print(next(ciudadesDevueltas2)) +print(next(ciudadesDevueltas2)) +print(next(ciudadesDevueltas2)) +print(next(ciudadesDevueltas2)) +print(next(ciudadesDevueltas2)) +print(next(ciudadesDevueltas2)) +print(next(ciudadesDevueltas2)) +print(next(ciudadesDevueltas2)) + +# Y por ultimo el resultado de este ultimo generador utilizando tanto un bucle for anidado como la instruccion yield from que uno de los puntos de este tema es que no nos arroja como resultado el elemento del generador, si no los subelementos de un elemento del generador, que en este caso nos esta devolviendo la 'M' y la 'a' correspondientes al primer elemento que es 'Madrid' y estas dos letras corresponden al numero de veces que hemos ejecutado el print con la variable que guarda el generador, si lo imprimimos mas veces, nos ira dando las siguientes letras correspondientes al elemento 'Madrid' y asi consecutivamente, si imprimimos mas veces del numero de letras que contenga el elemento Madrid, se seguira con el siguiente elemento del generador ('Barcelona', 'Valencia' etc), pero de igual manera devolviendo los subelementos de los elementos en cuestion \ No newline at end of file diff --git a/Gestion de Productos b/Gestion de Productos new file mode 100644 index 0000000..57fb9dc Binary files /dev/null and b/Gestion de Productos differ diff --git a/Gestion de Productos 2 - Camplo Clave Automatico b/Gestion de Productos 2 - Camplo Clave Automatico new file mode 100644 index 0000000..c1275b2 Binary files /dev/null and b/Gestion de Productos 2 - Camplo Clave Automatico differ diff --git a/Graphical User Interfaces/Calculadora/GUI_Calculadora.py b/Graphical User Interfaces/Calculadora/GUI_Calculadora.py new file mode 100644 index 0000000..d9ec2ef --- /dev/null +++ b/Graphical User Interfaces/Calculadora/GUI_Calculadora.py @@ -0,0 +1,325 @@ +# Calculadora - Interfez Grafica + +from tkinter import * + +# Ventana Raiz + +root = Tk() +root.title('Calculadora') +# root.iconbitmap('Imagenes_Ico/calc.ico') + +# Ventana frame 1 + +frame1 = Frame(root) +frame1.pack() +frame1.config(bg='#222222') + +# Variables globales + +operacion = '' + +resultado = 0 + +resetPantalla = False + +numApoyo = 0 + +punto = '' + +# Ventana tipo de calculadora + +tipoCalculadora = Label(frame1, text='Estandar') +tipoCalculadora.grid(row=1, columnspan=6, padx=5, sticky='w') +tipoCalculadora.config(bg='#222222', fg='#DCDCDC') + +# Pantalla de Digitos Pulsados + +numero = StringVar() + +pantallaDigitos = Entry(frame1, textvariable=numero, font=('Z003', 13)) +pantallaDigitos.grid(row=3, columnspan=6, pady=10, padx=5, sticky='we') +pantallaDigitos.config(bg='#333333', fg='#03f943', justify='right') + +# Pantalla Almecenamiento de Digitos y Operaciones + +pantallaAlmacenamiento = Label(frame1, textvariable=numero, font=('Z003', 10)) +pantallaAlmacenamiento.grid(row=2, columnspan=6, padx=5, sticky='we') +pantallaAlmacenamiento.config(bg='#DCDCDC', fg='#222222') + +# Teclado numerico + +def botonPulsado(num): + global resetPantalla + + if resetPantalla != False: + numero.set(num) + resetPantalla = False + else: + numero.set(f'{numero.get()}{num}') + # numero.set(numero.get()+num) Esto es lo mismo de arriba, solo que con diferente sintaxis + +def reset(): + global resetPantalla + global resultado + + resultado = 0 + numero.set('') + resetPantalla = False + +# def borrar(): +# numero.set() + +# Suma + +def suma(num): + global operacion + global resultado + global resetPantalla + + resultado = int(num) + + operacion = 'suma' + + numero.set(resultado) + + resetPantalla = True + +# Resta + +contador_resta = 0 + +def resta(num): + global operacion + global resultado + global numApoyo + global resetPantalla + global contador_resta + + if contador_resta == 0: + numApoyo = int(num) + resultado = numApoyo + + else: + if contador_resta == 1: + resultado = numApoyo - int(num) + + else: + resultado = resultado - int(num) + + numero.set(resultado) + resultado = numero.get() + + contador_resta = contador_resta + 1 + + operacion = 'resta' + + resetPantalla = True + +# Multiplicacion + +contador_mult = 0 + +def multiplicacion(num): + global operacion + global resultado + global numApoyo + global resetPantalla + global contador_mult + + if contador_mult == 0: + numApoyo = int(num) + resultado = numApoyo + + else: + if contador_mult == 1: + resultado = numApoyo * int(num) + + else: + resultado = resultado * int(num) + + numero.set(resultado) + resultado = numero.get() + + contador_mult = contador_mult + 1 + + operacion = 'multiplicacion' + + resetPantalla = True + +# Division + +contador_div = 0 + +def division(num): + global operacion + global resultado + global numApoyo + global resetPantalla + global contador_div + + if contador_div == 0: + numApoyo = float(num) + resultado = numApoyo + + else: + if contador_div == 1: + resultado = numApoyo / float(num) + + else: + resultado = resultado / float(num) + + numero.set(resultado) + resultado = numero.get() + + contador_div = contador_div + 1 + + operacion = 'division' + + resetPantalla = True + +# Porcentaje + +numSacarPorc = 0 +contador_porc = 0 + +def porcentaje(num): + global operacion + global resultado + global numApoyo + global resetPantalla + global contador_porc + global numSacarPorc + + if contador_porc == 0: + numSacarPorc = float(num) + numApoyo = float(num) + resultado = numApoyo + + else: + if contador_porc == 1: + resultado = numApoyo * float(num) / 100 + numSacarPorc = numSacarPorc - resultado + resultado = numSacarPorc + + else: + resultado = int(resultado) * float(num) / 100 + numSacarPorc = numSacarPorc - resultado + resultado = numSacarPorc + + numero.set(resultado) + resultado = numero.get() + + contador_porc = contador_porc + 1 + + operacion = 'porcentaje' + + resetPantalla = True + +def resultadoTotal(): + global resultado + global operacion + global contador_resta + global contador_mult + global contador_div + global numSacarPorc + + if operacion == 'suma': + numero.set(resultado + int(numero.get())) + resultado = 0 + + elif operacion == 'resta': + numero.set(resultado - int(numero.get())) + resultado = 0 + contador_resta = 0 + + elif operacion == 'multiplicacion': + numero.set(resultado * int(numero.get())) + resultado = 0 + contador_mult = 0 + + elif operacion == 'division': + numero.set(resultado / float(numero.get())) + resultado = 0 + contador_div = 0 + + elif operacion == 'porcentaje': + print(resultado) + numSacarPorc = resultado * float(numero.get()) + numSacarPorc = numSacarPorc / 100 + resultado = resultado - numSacarPorc + numero.set(resultado) + resultado = 0 + +# Fila 1 + +boton7 = Button(frame1, text='7', width=5, height=2, command=lambda:botonPulsado('7')) +boton7.grid(row=4, column=2) +boton7.config(bg='#222222', fg='#FE3131') +boton8 = Button(frame1, text='8', width=5, height=2, command=lambda:botonPulsado('8')) +boton8.grid(row=4, column=3) +boton8.config(bg='#222222', fg='#FE3131') +boton9 = Button(frame1, text='9', width=5, height=2, command=lambda:botonPulsado('9')) +boton9.grid(row=4, column=4) +boton9.config(bg='#222222', fg='#FE3131') +botonDiv = Button(frame1, text='/', width=5, height=2, command=lambda:division(numero.get())) +botonDiv.grid(row=4, column=5) +botonDiv.config(bg='#444444', fg='#DCDCDC') +botonBorrar = Button(frame1, text='Del', width=5, height=2) +botonBorrar.grid(row=4, column=1) +botonBorrar.config(bg='#444444', fg='#DCDCDC') + +# Fila 2 + +boton4 = Button(frame1, text='4', width=5, height=2, command=lambda:botonPulsado('4')) +boton4.grid(row=5, column=2) +boton4.config(bg='#222222', fg='#FE3131') +boton5 = Button(frame1, text='5', width=5, height=2, command=lambda:botonPulsado('5')) +boton5.grid(row=5, column=3) +boton5.config(bg='#222222', fg='#FE3131') +boton6 = Button(frame1, text='6', width=5, height=2, command=lambda:botonPulsado('6')) +boton6.grid(row=5, column=4) +boton6.config(bg='#222222', fg='#FE3131') +botonMult = Button(frame1, text='x', width=5, height=2, command=lambda:multiplicacion(numero.get())) +botonMult.grid(row=5, column=5) +botonMult.config(bg='#444444', fg='#DCDCDC') +botonC = Button(frame1, text='C', width=5, height=2, command=lambda:reset()) +botonC.grid(row=5, column=1) +botonC.config(bg='#444444', fg='#DCDCDC') + +# Fila 3 + +boton1 = Button(frame1, text='1', width=5, height=2, command=lambda:botonPulsado('1')) +boton1.grid(row=6, column=2) +boton1.config(bg='#222222', fg='#FE3131') +boton2 = Button(frame1, text='2', width=5, height=2, command=lambda:botonPulsado('2')) +boton2.grid(row=6, column=3) +boton2.config(bg='#222222', fg='#FE3131') +boton3 = Button(frame1, text='3', width=5, height=2, command=lambda:botonPulsado('3')) +boton3.grid(row=6, column=4) +boton3.config(bg='#222222', fg='#FE3131') +botonResta = Button(frame1, text='-', width=5, height=2, command=lambda:resta(numero.get())) +botonResta.grid(row=6, column=5) +botonResta.config(bg='#444444', fg='#DCDCDC') +botonCe = Button(frame1, text='CE', width=5, height=2) +botonCe.grid(row=6, column=1) +botonCe.config(bg='#444444', fg='#DCDCDC') + +# Fila 4 + +botonPunto = Button(frame1, text='.', width=5, height=2, command=lambda:botonPulsado('.')) +botonPunto.grid(row=7, column=2) +botonPunto.config(bg='#444444', fg='#DCDCDC') +boton0 = Button(frame1, text='0', width=5, height=2, command=lambda:botonPulsado('0')) +boton0.grid(row=7, column=3) +boton0.config(bg='#222222', fg='#FE3131') +botonPorc = Button(frame1, text='%', width=5, height=2, command=lambda:porcentaje(numero.get())) +botonPorc.grid(row=7, column=1) +botonPorc.config(bg='#444444', fg='#DCDCDC') +botonSuma = Button(frame1, text='+', width=5, height=2, command=lambda:suma(numero.get())) +botonSuma.grid(row=7, column=5) +botonSuma.config(bg='#444444', fg='#DCDCDC') +botonIgual = Button(frame1, text='=', width=5, height=2, command=lambda:resultadoTotal()) +botonIgual.grid(row=7, column=4) +botonIgual.config(bg='#444444', fg='#DCDCDC') + +root.mainloop() \ No newline at end of file diff --git a/Graphical User Interfaces/GUI_1.py b/Graphical User Interfaces/GUI_1.py new file mode 100644 index 0000000..89bbbb7 --- /dev/null +++ b/Graphical User Interfaces/GUI_1.py @@ -0,0 +1,43 @@ +# Interfaces Graficas - GUI 1ra y 2da Parte - Pildoras Informaticas / Videos 42 y 43 + +from tkinter import * + +# El metodo mainloop tiene que estar siempre al final + +raiz = Tk() # Llamamos o intancias la clase Tk() de la libreria Tkinter + +raiz.title('Ventana de pruebas') # Ponemos titulo a la ventana + +# raiz.resizable(True,1) # Nos permite decidir si queremos que la ventana se pueda redimensionar. Este metodo acepta valores booleanos, ya sea que pongamos 1 o 0 o bien True o False. El 1 equivale a True y 0 a False. El primer valor corresponde a width (ancho) y el segundo a height (alto) + +#raiz.iconbitmap("Graphical User Interfaces/icono.ico") # Asignar un icono a la ventana. Este icono debe estar en formato .ico + +raiz.geometry('650x350') # Damos una medida a la ventana + +raiz.config(bg='white') # Le asignamos un color de fondo a la ventana + +raiz.config(relief='sunken') + +raiz.config(bd='30') + +raiz.config(cursor='pirate') + +miFrame = Frame() # Este frame hay que meterlo dentro de la raiz. Para esto usamos el metodo pack + +miFrame.pack(side='left', anchor='n') # Empaquetamos el frame dentro de la raiz. Esta dentro de la raiz. El metodo pack tambien nos sirve para definir donde queremos que este anclado el frame dentro de la raiz y esto lo hacemos con el parametro side dandole como valor una direccion (right, left, top, bottom). Si queremos utilizar dos direcciones para que quede por ejemplo a la izquierda y arriba debemos utilizar otro parametro el cual es anchor y este recibe como valor una cordenada de brujula, es decir norte, sur, este u oeste, pero en ingles y solo la inicial, es decir n=north, s=south, e=east, w=west + +# Tambien existe otro parametro para el metodo pack que es el parametro fill, que lo que hace es rellenar para que el frame se expanda junto con la raiz pero que abarque por completo este ultimo, sin embargo este parametro tiene un particularidad y es que para el valor x (horizontal), si funciona solo pasando ese valor, pero para el valor y (vertical) no funciona por si solo, para este tenemos que pasar un paramtro adicional el cual es expand con el valor de true, al igual que si queremos que sea para ambos sentidos ocupamos el parametro fill con el valor both y el parametro expand con el valor true + +miFrame.pack(fill='y', expand=True) + +miFrame.config(bg='red') # Si ejecutamos el programa en este punto aunque ya creamos el frame, lo pusimos dentro de la raiz y le dimos un color veremos que al parecer no ha pasado nada y esto se debe a que al frame hay que darle un tamaño y hasta no asignarle un tamaño no podremos visualizarlo. Adicional a esto hay que desabilitar el metodo geometry de la raiz ya que la raiz siempre se va a adaptar al tamaño del fram, es por eso que le debemos asignar un tamaño al frame y no a la raiz + +miFrame.config(width='650', height='350') # Asignamos un tamaño al frame. El frame tiene siempre el mismo tamaño, es fijo, este no se adapta si redimensionamos la raiz + +miFrame.config(relief='groove') # Con esto asignamos un tipo de borde. Sin embargo con este parametro podriamos ver que no pasa nada y esto se debe a que debemos asignar un grosor de borde + +miFrame.config(bd='15') # Asinamos el tamaño o grosor del borde + +miFrame.config(cursor='hand2') # Cambiamos el tipo de cursor al momento en que este se posiciona sobre el frame + +raiz.mainloop() # Este metodo lo que hace es mantener la ventana en un bucle infinito para que se este ejecutando y a la espera y escucha de eventos. Esto lo hacen todas las ventanas de todos los programas, lo cual nos permite a los usuarios interactuar con ellas \ No newline at end of file diff --git a/Graphical User Interfaces/GUI_2.py b/Graphical User Interfaces/GUI_2.py new file mode 100644 index 0000000..d702e59 --- /dev/null +++ b/Graphical User Interfaces/GUI_2.py @@ -0,0 +1,51 @@ +# Interfaces Graficas - GUI 1ra y 2da Parte - Pildoras Informaticas / Video 44 + +# Widget Label --> Nos permiten mostrar texto o imagenes. Tienen como unica finalidad mostrar texto, no se puede interactuar con el + +""" Sintaxis del label + + - variableLabel = Label(contenedor, opciones) + + Opciones para los label (unas de las mas utilizadas) + + - text --> Texto que se muestra en el label + - anchor --> Controla la posicion del texto si hay espacio suficiente para el (center por defecto) + - bg --> Color de fondo + - bitmap --> Mapa de bits que se mostrara como grafico + - bd --> Grosor del borde (2px por defecto) + - font --> Tipo de fuente a mostrar + - fg --> Color de la fuente + - width --> Ancho del label en caracteres (no en pixeles) + - height --> Altura del label en caracteres (no en pixeles) + - image --> Muestra imagen en el label en lugar de texto + - justify --> Justificacion del texto del label """ + +from tkinter import * + +root = Tk() + +root.title('GUI 2') + +# root.iconbitmap('Graphical User Interfaces/kali.ico') + +miFrame = Frame(root, width=600, height=400) + +miFrame.pack() + +# miLabel = Label(miFrame, text='Hola mundo') + +#miLabel.pack() # Si ejecutamos el programa podemos ver que la ventana es pequeña, esta ajustada al contenido del label y eso se debe a que estamos empaquetando el label lo cual hace que el contenedor se adapte al tamaño del label, si queremos que esto no ocurra tenemos que cambiar el pack por el metodo llamado place + +#miLabel.place(x=10, y=20) # Este metodo nos permite ubicar el label en la posicion que nosotros queramos dandole como parametros medidas en pixeles en la direccion 'x' o 'y'. Esta sintaxis junto con la de la variable miLabel se puede abreviar. Si no vamos a ocupar la variable miLabel mas adelante para algo mas podemos prescindir de declarar la variable y ponemos el metodo Label de forma directa y a este le agregamos el metodo place con la nomenclatura del punto + +Label(miFrame, text='Saludos terricolas').place(x=250, y=5) # Esto es una forma de abeviar el codigo si que el label no lo vamos a ocupar mas adelante como para que sea necesario guardarlo en una variable como lo hicimos anteriormente. Ademas podemos seguir agregando opciones dentro del label y funcionara. Lo voy a hacer en una linea de codigo abajo para que se vea la diferencia + +Label(miFrame, text='Venimos en paz', fg='red', font=('Z003', 18)).place(x=200, y=50) + +imagen = PhotoImage('lobo_2.png') + +Label(miFrame, image=imagen).place(x=20, y=20) # Lo de las imagenes lo tengo que revisar ya que tengo un problema con estas y este es que siempre me da un error ya sea con la imagen .ico al utilizar el metodo iconbitmap asi como con esta imagen que estoy tratando de colocar en el frame mediante el metodo PhotoImage y al colocarla en el frame me da igual un error, el mismo que me da cuando quiero poner una imagen en la ventana con el metodo iconbitmap + +root.mainloop() + +# iMPORTANTE: NO ENTIENDO PORQUE TENGO PROBLEMAS AL QUERER COLOCAR IMAGENES, YA SE EN EL FRAME, EN LA RAIZ O EN DONDE SEA, SIEMPRE ME ARROJA UN ERROR DE QUE EL ARCHIVO NO EXISTE AUNQUE ESTE EN LA MISMA CARPETA O LE PONGA LA RUTA COMPLETA, NO IMPORTA COMO DEFINA LA IMAGEN, SIN O CON RUTA, SIN O CON EXTENSION ETC ETC ETC (YA HICE DIFERETES DE PRUEBAS DE COMO PONER EL CODIGO HABAER SI CAMBIANDO LA SINTAXIS FUNCIONA PERO NO, NO FUNCIONA) \ No newline at end of file diff --git a/Graphical User Interfaces/GUI_3.py b/Graphical User Interfaces/GUI_3.py new file mode 100644 index 0000000..b18dcce --- /dev/null +++ b/Graphical User Interfaces/GUI_3.py @@ -0,0 +1,96 @@ +# Interfaces Graficas - Pildoras Informaticas / Video 45 + +# Widget Entry --> Cuadro de texto (Introducir texto) + +# Clases... Todas las clases que declaremos para crear widgets en la interfaz grafica deben de llevar dentro de los parentesis como parametro cual va a ser su contenedor padre y el los parametros adicionales que le queramos dar + +# Entry() --> Creamos un cuadro de texto con el cual el usuario puede interactuar escribiendo en el + +# Text() --> Creamos un cuadro de texto amplio, al igual que el entry el usuario puede escribir en este widget pero de forma mas amplia y extensa ya que este widget esta pensado y diseñado para muchos mas caracteres. De forma predeterminada este se crea muy grande, pero podemos darle un tamaño en especifico con width y height + +# Scrollbar() --> Creamos una barra de desplazamiento para cuando haya mucho texto podamos hacer scroll y deplazarnos por todo el texto, esta barra se crea de forma independiente al Text por lo tanto hay que asignarle un espacio en la grilla (grid) al igual que como cualquier otro widget, ademas de eso de forma predeterminada aparece muy pequeña y su compotamiento no es el mejor, asi como la barra con la que nos podemos desplazar sin la necesidad de las flechas no viene por defecto activada, asi que nosotros debemos activarla, esta y varias configuraciones adicionales se le tiene que dar para que tenga un aspecto como se les ve mas comunmente, asi como indicarle la direccion en la que se va a desplazar. Es importante tener en cuenta que el objeto Scrollbar() debemos declarar a donde va a pertenecer como el frame o la raiz y tambien que es lo que va a controlar por decirlo de alguna manera, este ultimo lo hacemos con el parametro command y dentro de este definimos el cuadro de texto (Text) a controlar. Sin embargo para activar la barra de desplazamiento es necesario hacer una configuracion no en el Scrollbar si no en el Text que va a manejar esta barra de desplazamiento y lo hacemos con el parametro yscrollcommand seguido del Text en cuestion seguido del parametro set utilizando la nomenclatura del punto, esta declaracion del codigo debe de ir despues de el codigo donde definamos la scrollbar, de lo contrario nos arrojara un error, Ej: yscrollcommand=barraDesp.set. Ej2: linea de codigo 68 + +# Buttom() --> Creamos un boton con el cual el usuario puede interactuar y con el que podemos ejecutar alguna accion en la interfaz grafica + +# Veremos dos metodos los cuales son grid y sticky + +# Grid es como en CSS, nos permite acomodar elementos dentro de una grilla ficticia la cual estara definida en el metodo, este metodo a diferencia de css donde se define la grilla de forma general en toda pagina y despues vamos acomodando los elementos aqui en python se estipula directamente sin crear como tal una grilla antes, esta se va creando conforme vamos agregando y acomodando los elementos, es decir no estamos diviendo la interfaz grafica de manera anticipada con una grilla con filas y columnas determinadas. Tanto las filas como las columnas empiezan a contar desde 0 + +# Sticky nos permite ubicar el contenido en cualquier punto dentro de los puntos cardinales de una brujula, norte, sur, este, oeste y tambien noreste, sureste, noroeste y suroeste, estos estan definidos en ingles y para definirlos solo ocupamos las iniciales... n, s, e, w, ne, se, nw y sw + +# pady y padx nos permiten definir paddings como en css para darle un espaciado entre el contenido que tiene definido el padding de su contenedor padre (raiz, frame etc...). Con pady controlamos el padding de superior e inferior y con el padx controlamos el padding de la derecha e izquierda + +from tkinter import * + +root = Tk() + +root.title('Velkan') + +frame1 = Frame(root, width=400, height=300) + +frame1.pack() + +nombreUsuario = StringVar() # Con el stringvar le indicamos a la variable que su contenido o valor seran una serie de caracteres. Esta variable y su valor la tenemos que asociar al entry nombre para que al pulsar el boton imprima en este cuadro el valor de esta variable que sera un nombre. Y como asociamos esta variable al Entry(? Esto lo hacemos directamente en el Entry con el valor de textvariable + +contacto = StringVar() + +nombreLabel = Label(frame1, text='Nombre') +nombreLabel.grid(row=0, column=0, sticky='w', pady=10, padx=10) + +apellidoLabel = Label(frame1, text='Apellido') +apellidoLabel.grid(row=1, column=0, sticky='w', pady=10, padx=10) + +emailLabel = Label(frame1, text='Email') +emailLabel.grid(row=2, column=0, sticky='w', pady=10, padx=10) + +passLabel = Label(frame1, text='Password') +passLabel.grid(row=3, column=0, sticky='w', pady=10, padx=10) + +comentarioLabel = Label(frame1, text='Comentarios') +comentarioLabel.grid(row=4, column=0, sticky='w', pady=10, padx=10) + +contactoLabel = Label(frame1, text='Datos de Contacto') +contactoLabel.grid(row=5, column=0, padx=10, pady=10) + +contactoCuadroMensaje = Label(frame1, textvariable=contacto) +contactoCuadroMensaje.grid(row=5, column=1, padx=10, pady=10) + +nombreCuadro = Entry(frame1, textvariable=nombreUsuario) +nombreCuadro.grid(row=0, column=1, pady=10, padx=10) +nombreCuadro.config(justify='center') + +apellidoCuadro = Entry(frame1) +apellidoCuadro.grid(row=1, column=1, pady=10, padx=10) +apellidoCuadro.config(justify='center') + +emailCuadro = Entry(frame1) +emailCuadro.grid(row=2, column=1, pady=10, padx=10) +emailCuadro.config(justify='center') + +passCuadro = Entry(frame1) +passCuadro.grid(row=3, column=1, pady=10, padx=10) +passCuadro.config(fg='red', show='*', justify='center') + +comentarioCuadro = Text(frame1, width=18, height=6) +comentarioCuadro.grid(row=4, column=1, pady=10, padx=10) + +barraDesp = Scrollbar(frame1, command=comentarioCuadro.yview) +barraDesp.grid(row=4, column=3, sticky='ns', pady=10) + +comentarioCuadro.config(yscrollcommand=barraDesp.set) + +def codigoBoton(): + nombreUsuario.set('Moises') + +def mensajeContacto(): + contacto.set('Si lo prefieres puedes ponerte en contacto con nostros por telefono o via email \nTelefonos: 55-5555-5555\n 55-6666-6666\nEmail: contacto.soporte@miemail.com') + +botonEnviarDatos = Button(root, text='Enviar', command=codigoBoton) +botonEnviarDatos.pack() + +botonContacto = Button(root, text='Contactanos', pady=7, command=mensajeContacto) +botonContacto.pack() + +# cuadroNombre.place(x=5, y=5) + +root.mainloop() \ No newline at end of file diff --git a/Graphical User Interfaces/GUI_4.py b/Graphical User Interfaces/GUI_4.py new file mode 100644 index 0000000..555b43c --- /dev/null +++ b/Graphical User Interfaces/GUI_4.py @@ -0,0 +1,136 @@ +# Interfaces Graficas - Pildoras Informaticas / Videos 50 y 51 - Radiobuttons y Checkbuttons + +# Radiobuttons / Botones de Radio --> Son botones de seleccion, los cuales se caracterizan por aceptar una respuesta unica al poder seleccionar solo uno de ellos + +# Los radiobuttons reciben dos parametros: 1.- Cual va a ser su contenedor padre. 2.- El texto que va a acompañar este radiobutton el cual va a describir lo que se va a seleccionar + +# Al momento de crearlos no podemos interactuar con ellos, de hecho aparecen en la interfaz grafica todos los que hayamos puesto como seleccionados y no podemos deseleccionarlos aunque presionemos con el mouse + +# Se trata de que aparezcan desactivados y sea el usuario el que seleccione uno u otro. Y esto lo hacemos por medio de una variable y un valor. La particularidad de poder seleccionar solo uno, es que al momento de seleccionar otro el que estaba seleccionado se deselecciona. Solo puede haber uno activado + +# Checkbuttons / Botones de seleccion multiple --> Son botones de seleccion multiple, los cuales tienen un diseño cuadrado, permiten seleccionar uno o mas al mismo tiempo + +from tkinter import * + +root = Tk() +root.title('Radio & Check Buttons') + +main_frame = Frame(root) +main_frame.pack() + +var_opcion = IntVar() + +def mostrarSeleccion(): + print('1 - Masculino \n2 - Femenino') + print(f'Usuario selecciono {var_opcion.get()}') + +def mostrarGenero(): + + if var_opcion.get() == 1: + seleccion_usuario.config(fg='#FF1414', text='Tu género es Masculino') + seleccion_usuario2.config(fg='#DCDCDC', text='Elegiste Masculino') + + elif var_opcion.get() == 2: + seleccion_usuario.config(fg='#FF1414', text='Tu género es Femenino') + seleccion_usuario2.config(fg='#DCDCDC', text='Elegiste Femenino') + + else: + seleccion_usuario.config(fg='#FF1414', text='Tu género no fue definido') + seleccion_usuario2.config(fg='#DCDCDC', text='Elegiste no definir') + + +genero = Label(main_frame, text='Selecciona tu Género', width=45) +genero.grid(row=1, column=1) + +rb = Radiobutton(main_frame, text='Masculino', variable=var_opcion, value=1, command=mostrarGenero) +rb.grid(row=2, column=1, sticky='nswe') + +rb2 = Radiobutton(main_frame, text='Femenino', variable=var_opcion, value=2, command=mostrarGenero) +rb2.grid(row=3, column=1, sticky='nswe') + +rb3 = Radiobutton(main_frame, text='Sin definir', variable=var_opcion, value=3, command=mostrarGenero) +rb3.grid(row=4, column=1, sticky='nsew') + +seleccion_usuario = Label(main_frame) +seleccion_usuario.grid(row=5, column=1, pady=5, sticky='we') + +seleccion_usuario2 = Label(main_frame) +seleccion_usuario2.grid(row=6, column=1, pady=5, sticky='we') +seleccion_usuario2.config(bg='#222222', fg='#DCDCDC') + +# Con la variable creada asignandole un valor de tipo entero conseguimos que estos radiobuttons trabajen de forma adecuada y esta es permitiendo que el usuario sea quien pueda elegir uno de estos y que al momento de seleccionar uno si hay otro seleccionado este ultimo se deseleccione. Tengo que analizar porque funciona de esta manera o si solo es lo estipulado para que funcione, ya que aunque lo tengo anotado, no entendi muy bien a que se debe y porque tenemos que crear una variable de tipo entero y esta declararla en el radiobutton junto con un valor para que estos trabajen de forma adecuada + +frame2 = Frame(root) +frame2.pack() + +imagen_viaje = PhotoImage(file='Imagenes/avion.png') +label_imagen = Label(frame2, image=imagen_viaje) +label_imagen.grid(row=6, column=1) + +seleccion_destinos = Label(frame2, text='Elige tus destinos') +seleccion_destinos.grid(row=7, column=1, padx=67, pady=10) + +# Lo siguiente fue lo que yo hice tratando de lograr hacer lo que aparecera despues de este comentario incluyendo la funcion comentada + +# value_destino = 0 +# var_opcion_destinos = IntVar() + +# def seleccionDestino(destino): +# global value_destino +# global var_opcion_destinos + +# if destino == 'playa': +# value_destino += 1 +# var_opcion_destinos = 1 +# print('Selecciono Playa como destino') +# print(int(value_destino)) +# elif destino == 'selva': +# value_destino += 1 +# var_opcion_destinos = 2 +# print('Selecciono Selva como destino') +# print(value_destino) +# elif destino == 'desierto': +# value_destino += 1 +# var_opcion_destinos = 3 +# print('Selecciono Desierto como destino') +# print(value_destino) + +# if var_opcion_destinos == 1: +# destinos_viaje.config(text='Has seleccionado 1 destino') +# elif var_opcion_destinos == 2: +# destinos_viaje.config(text='Has seleccionado 2 destinos') +# elif var_opcion_destinos == 3: +# destinos_viaje.config(text='Has seleccionado 3 destinos') + +playa = IntVar() +selva = IntVar() +desierto = IntVar() + +def seleccionDestios(): + op_elegida = 'Has seleccionado como destino(s): ' + + if playa.get() == 1: + op_elegida += 'Playa' + + if selva.get() == 1: + op_elegida += ', Selva' + + if desierto.get() == 1: + op_elegida += ', Desierto' + + destinos_viaje.config(text=op_elegida) + +cb = Checkbutton(frame2, text='Playa', variable=playa, onvalue=1, offvalue=0, command=seleccionDestios) +cb.grid(row=8, column=1, sticky='w', padx=100) + +cb2 = Checkbutton(frame2, text='Selva', variable=selva, onvalue=1, offvalue=0, command=seleccionDestios) +cb2.grid(row=9, column=1, sticky='w', padx=100) + +cb3 = Checkbutton(frame2, text='Desierto', variable=desierto, onvalue=1, offvalue=0, command=seleccionDestios) +cb3.grid(row=10, column=1, sticky='w', padx=100) + +destinos_viaje = Label(frame2) +destinos_viaje.grid(row=11, column=1, pady=5, sticky='we') +destinos_viaje.config(bg='red', fg='#DCDCDC') + +root.mainloop() \ No newline at end of file diff --git a/Graphical User Interfaces/GUI_5.py b/Graphical User Interfaces/GUI_5.py new file mode 100644 index 0000000..d3767ce --- /dev/null +++ b/Graphical User Interfaces/GUI_5.py @@ -0,0 +1,59 @@ +# Interfaces Graficas - Pildoras Informaticas / Video 52 - Menus y submenus + +# Menus y submenus + +from tkinter import * + +root = Tk() +root.title('Menus y submenus') + +main_menu = Menu(root) # Creamos la variable que albergara el menu, por lo tanto esta variable sera el menu de forma directa como tal +root.config(menu=main_menu, width=350, height=200) # Creamos el menu en la interfaz grafica, es decir lo ponemos ahi para que sea visible en la IG + +archivo_menu = Menu(main_menu, tearoff=0) # Determinamos que sera un submenu y a que menu va a pertenecer este submenu y con tearoff=0 quitamos la franja de lineas intercaladas que viene por defecto +archivo_menu.add_command(label='Nuevo') # Creamos los submenus y los agregamos a la pestaña correspondiente del menu principal, asi como tambien le damos un nombre a cada elemento del submenu +archivo_menu.add_command(label='Abrir') +archivo_menu.add_command(label='Guardar') +archivo_menu.add_command(label='Guardar Como') +archivo_menu.add_separator() # Agregamos separadores que se ven comunmente en los submenus que sirven para separar bloques de elementos que son similares o que pertenecen a un grupo de acciones en comun +archivo_menu.add_command(label='Cerrar') +archivo_menu.add_command(label='Salir') +archivo_menu.add_command(label='Salir') + +edicion_menu = Menu(main_menu, tearoff=0) +edicion_menu.add_command(label='Deshacer') +edicion_menu.add_command(label='Rehacer') +edicion_menu.add_separator() +edicion_menu.add_command(label='Copiar') +edicion_menu.add_command(label='Cortar') +edicion_menu.add_command(label='Pegar') + +herramientas_menu = Menu(main_menu, tearoff=0) +herramientas_menu.add_command(label='Seleccionar Todo') +herramientas_menu.add_command(label='Expandir Seleccion') +herramientas_menu.add_command(label='Recortar Seleccion') +herramientas_menu.add_separator() +herramientas_menu.add_command(label='Búsqueda') +herramientas_menu.add_separator() +herramientas_menu.add_command(label='Apariencia') +herramientas_menu.add_command(label='Configuracion') + +ayuda_menu = Menu(main_menu, tearoff=0) +ayuda_menu.add_command(label='Licencia') +ayuda_menu.add_separator() +ayuda_menu.add_command(label='Comenzar') +ayuda_menu.add_command(label='Documentación') +ayuda_menu.add_separator() +ayuda_menu.add_command(label='Reportar un problema') +ayuda_menu.add_separator() +ayuda_menu.add_command(label='Acerca de') + +ir_menu = Menu(main_menu, tearoff=0) + +main_menu.add_cascade(label='Archivo', menu=archivo_menu) # Agregamos el submenu al menu al que pertenecera, el menu padre, asi mismo le asignamos un nombre al submenu o a la pestaña que representara a este mismo +main_menu.add_cascade(label='Edición', menu=edicion_menu) +main_menu.add_cascade(label='Herramientas', menu=herramientas_menu) +main_menu.add_cascade(label='Ayuda', menu=ayuda_menu) +main_menu.add_cascade(label='Ir a', menu=ir_menu) + +root.mainloop() \ No newline at end of file diff --git a/Graphical User Interfaces/GUI_6.py b/Graphical User Interfaces/GUI_6.py new file mode 100644 index 0000000..29ddd1e --- /dev/null +++ b/Graphical User Interfaces/GUI_6.py @@ -0,0 +1,90 @@ +# Interfaces Graficas - Pildoras Informaticas / Videos 53 y 54 - Ventanas Emergentes + +# Ventanas emergentes --> Son ventanas modales para informar, avisar o permitir realizar tareas al usuario + +# Ventana emergente para abrir archivos --> Esta ventana es la tipica ventana que vemos en la mayoria de programas que nos permiten abrir archivos desde su interfaz grafica mediante la pestaña de "Archivo --> Abrir como o Abrir" + +# Para hacer uso de estas ventanas emergentes de apertura de archivos es necesario importar otra libreria de tkinter de forma independiente y esta es 'filedialog' + +# La libreria filedialog contiene funciones que nos permiten abrir, guardar y mas, y obviamente debemos de llamar a las funciones encargadas de cada una de estas acciones al momento de quererlas realizar. El nombre de estas funciones las podemos encontrar en la documentacion oficial de Python, mas concretamente en el apartado de tkinter, pero para efectos de este tema utilizaremos la funcion llamada 'askopenfilename', el cual nos permite desplegar la ventana emergente que nos permitira navegar entre nuestros archivos y poder abrir el que queramos. Esta funcion admite y puede recibir varios parametros, de entrada el parametro title el cual contendra el nombre de la ventana, el parametro initialdir el cual nos permite definir la ruta en la que se encontrara al abrir esta ventana, y tambien podemos definir el tipo de archivo que queremos se puedan abrir, esto ultimo lo hacemos con el parametro filetypes() y dentro de este tenemos que pasarle en forma de tuplas los tipos de archivos que queremos que se puedan abrir, debemos poner como minimos 2 tuplas para que la ventana tenga opciones y podamos tener a nuestra dispocion esta opcion. Las tuplas deben contener 2 valores, el primero sera el nombre con el que vamos a identificar el tipo de archivos y el segundo la extension de estos, estas tuplas deben de ir de forma independiente y separadas por una coma, pero todas y cada una de ellas dentro de los parentesis del parametro filetypes + +# Las ventanas emergentes no forman parte de la biblioteca estandar de tkinter, por lo tanto hay que importarlas de forma independiente + +from tkinter import * +from tkinter import messagebox +from tkinter import filedialog + +root = Tk() +root.title('Ventanas emergentes') + +def acerca_de(): + messagebox.showinfo('Paladium', 'Programa Paladium para la automatización de sistemas de control de diferentes marcas que permitan la inteacción con audio, iluminación, redes etc...') + +def licencia(): + messagebox.showwarning('Licencia', 'Licencia bajo la norma GUI. Licencia no reestrictiva') + +def salir(): + valor = messagebox.askquestion('Salir', 'Deseas salir del programa?') + + if valor == 'yes': + root.destroy() + +def cerrar_sesion(): + valor = messagebox.askokcancel('Cerrar Sesión', 'Esta seguro que desea cerrar la sesión?') + + if valor == True: + root.destroy() + +def reintentarGurdado(): + valor = messagebox.askretrycancel('Reintentar guardado', 'No ha sido posible guarda el archivo. Desea reintentar?') + + if valor == False: + root.destroy() + +def reportarProblema(): + valor = messagebox.askretrycancel('Problema Reportado', 'No ha sido posible reportar el problema. Desea intentarlo de nuevo?') + + if valor != True: + root.destroy() + +def abrirArchivo(): + abrir_file = filedialog.askopenfilename(title='Abrir', initialdir='/home/eliab_hdez', filetypes=(('Archivos de Python', '*.py'), ('Archivos de texto', '*.txt'), ('Todos los archivos', '*.*'))) + + print(abrir_file) + +main_menu = Menu(root) +root.config(menu=main_menu, width=400, height=200) + +boton_abrir = Button(root, text='Open file', command=abrirArchivo) +boton_abrir.grid(row=1, column=1, padx=100, pady=50) + +archivo = Menu(main_menu, tearoff=0) +archivo.add_command(label='Nuevo') +archivo.add_command(label='Abrir', command=abrirArchivo) +archivo.add_command(label='Guardar', command=reintentarGurdado) +archivo.add_command(label='Cerrar Sesión', command=cerrar_sesion) +archivo.add_command(label='Salir', command=salir) + +edicion = Menu(main_menu, tearoff=0) +edicion.add_command(label='Copiar') +edicion.add_command(label='Cortar') +edicion.add_command(label='Pegar') + +tools = Menu(main_menu, tearoff=0) +tools.add_command(label='Seleccionar todo') +tools.add_command(label='Busqueda') +tools.add_command(label='Configuración') + +ayuda = Menu(main_menu, tearoff=0) +ayuda.add_command(label='Licencia', command=licencia) +ayuda.add_command(label='Reportar un problema', command=reportarProblema) +ayuda.add_command(label='Acerca de', command=acerca_de) + +main_menu.add_cascade(label='Archivo', menu=archivo) +main_menu.add_cascade(label='Edición', menu=edicion) +main_menu.add_cascade(label='Herramientas', menu=tools) +main_menu.add_cascade(label='Ayuda', menu=ayuda) + +root.mainloop() + +# Porque estamos haciendo uso de los nombres de las librerias importadas cada vez que las queremos utilizar como la libreria messagebox y la libreria filedialog??? Recordar que cuando importamos librerias tenemos 3 formas y cuando no importamos por medio del '*' es necesario anteponer el nombre de la libreria al metodo que vamos a ocupar de esa libreria, es decir, estamos llamando a la libreria y posteriormente a la funcion que contiene esa libreria, en el caso de estas dos librerias tenemos que hacerlo de esta manera ya que aunque la estamos importando desde la libreria tkinter estas no vienen dentro del conjunto general de librerias por lo tanto no estan disponibles con el 'from tkinter import *', asi que hay que llamarlas de forma independiente y al hacerlo estamos generando el llamado de estas librerias por su cuenta, por lo tanto ponemos from tkinter import filedialog y esto hace que cada vez que queramos ocupar una de las funciones de estas librerias tengamos que llamar a la libreria antes que a su funcion \ No newline at end of file diff --git a/Guardado_Permanente.py b/Guardado_Permanente.py new file mode 100644 index 0000000..ed3c730 --- /dev/null +++ b/Guardado_Permanente.py @@ -0,0 +1,89 @@ +# Guardado permanente --> Guardar datos de forma permanente en ficheros externos + +# Vamos a utilizar un fichero para ir guardando paulatinamente informacion dentro de el desde diferentes programas para tener esta informacion siempre disponible + +import pickle + + +class Consolas(): + def __init__(self, nombre, marca, modelo): + self.nombre = nombre + self.marca = marca + self.modelo = modelo + print(f'Creacion nueva consola. Nombre asignado: {self.nombre}') + + def __str__(self): + return f'Nombre: {self.nombre}\n Marca: {self.marca}\n Modelo: {self.modelo}\n' + +class listaConsolas(): + consolas = [] + + def __init__(self): + fichero_Consolas = open('fichero_consolas', 'ab+') # Formato para agregar informacion binaria + fichero_Consolas.seek(0) + + try: + self.consolas = pickle.load(fichero_Consolas) + print(f'Se han agregado {len(self.consolas)} consolas') + except: + print('El fichero esta vacio') + finally: + fichero_Consolas.close() + del(fichero_Consolas) + + def agregarConsolas(self, consola): + self.consolas.append(consola) + self.guardarConsolasFicheroExterno() + + def mostrarConsolas(self): + for c in self.consolas: + print(c) + + def guardarConsolasFicheroExterno(self): + fichero_Consolas = open('fichero_consolas', 'wb') + pickle.dump(self.consolas, fichero_Consolas) + fichero_Consolas.close() + del(fichero_Consolas) + + def mostarContenidoFicheroExterno(self): + print('El contenido del fichero externo es el siguiente: ') + for c in self.consolas: + print(c) + +lista_Consolas = listaConsolas() + +# consolaUno = Consolas('Play Station 4', 'Sony', 'Slim') +# lista_Consolas.agregarConsolas(consolaUno) +# lista_Consolas.mostarContenidoFicheroExterno() + +# consolaDos = Consolas('Xbox One', 'Microsoft', 'Series S') +# lista_Consolas.agregarConsolas(consolaDos) +# lista_Consolas.mostarContenidoFicheroExterno() + +# consolaTres = Consolas('WiiU', 'Nintendo', 'WiiU') +# lista_Consolas.agregarConsolas(consolaTres) +# lista_Consolas.mostarContenidoFicheroExterno() + +# consolaCuatro = Consolas('Play Station 5', 'Sony', 'Fat') +# lista_Consolas.agregarConsolas(consolaCuatro) +# lista_Consolas.mostarContenidoFicheroExterno() + +consolaCinco = Consolas('Xbox One X', 'Microsoft', 'Series X') +lista_Consolas.agregarConsolas(consolaCinco) +lista_Consolas.mostarContenidoFicheroExterno() + +# consola2 = Consolas('Xbox', 'Microsoft', 'OneS') +# almacenar_listaConsolas.agregarConsolas(consola2) + +# consola3 = Consolas('WiiU', 'Nintendo', 'Wii') +# almacenar_listaConsolas.agregarConsolas(consola3) + +# almacenar_listaConsolas.mostrarConsolas() + +# Podria prescindir de la clase listaConsolas y hacerlo de forma directa con el codigo escrito aqui abajo, sin embargo dejo la clase para hacerlo como en el curso, ademas que esta clase tambien se ocupa para empaquetar el archivo en un fichero externo + +# almacenar_listaConsolas.append(consola1) +# almacenar_listaConsolas.append(consola2) +# almacenar_listaConsolas.append(consola3) +# for c in almacenar_listaConsolas: +# print(c) \ No newline at end of file diff --git a/Imagenes/avion.png b/Imagenes/avion.png new file mode 100644 index 0000000..788feee Binary files /dev/null and b/Imagenes/avion.png differ diff --git a/Imagenes/calc.ico b/Imagenes/calc.ico new file mode 100644 index 0000000..6bc5fb4 Binary files /dev/null and b/Imagenes/calc.ico differ diff --git a/Imagenes/calc.png b/Imagenes/calc.png new file mode 100644 index 0000000..ffd3133 Binary files /dev/null and b/Imagenes/calc.png differ diff --git a/Imagenes/eclog2.ico b/Imagenes/eclog2.ico new file mode 100644 index 0000000..e7a304b Binary files /dev/null and b/Imagenes/eclog2.ico differ diff --git a/Imagenes/kali.ico b/Imagenes/kali.ico new file mode 100644 index 0000000..15e05d8 Binary files /dev/null and b/Imagenes/kali.ico differ diff --git a/Imagenes/tierra.gif b/Imagenes/tierra.gif new file mode 100644 index 0000000..b9db086 Binary files /dev/null and b/Imagenes/tierra.gif differ diff --git a/Interfaces_Graficas(GUI).py b/Interfaces_Graficas(GUI).py new file mode 100644 index 0000000..8b0e710 --- /dev/null +++ b/Interfaces_Graficas(GUI).py @@ -0,0 +1,18 @@ +# Interfaces graficas --> Mejor conocidas como GUI por sus siglas en ingles de Graphic User Interface. Es o son la forma en que la que nosotros vemos los programas mediante ventanas, iconos, botones etc... + +# Son intermediarios entre el usuario y el programa formadas por un conjunto de graficos como ventanas, botones, menus, casillas de verificacion etc + +""" Librerias disponibles en Python para la creacion de GUI + + - Tkinter + - WxPython + - PyQT + - PyGTK """ + +""" Estructura de ventana con Tkinter + + - Raiz(tk) --> La ventana (lo primero en construir) + - Frame --> Se contruye dentro de la raiz o ventana como organizador o aglutinador de widgets o elementos + - Widgets / Elementos --> Estan dentro del frame y podrian ser botones, menus desplegables, casillas de verificacion, cuadros de texto etc... """ + +# Investigar los problemas relacionados con todo lo que tiene que ver con poner imagenes, como el iconbitmap, el PhotoImage etc, ya que no es posible correr el programa cuando ocupo estos metodos, aun teniendo las imagenes en la misma carpeta que el archivo py ni tampoco poniendo la ruta completa, me arroja un error de que el archivo no existe \ No newline at end of file diff --git a/Metodos_de_Cadenas.py b/Metodos_de_Cadenas.py new file mode 100644 index 0000000..c11318d --- /dev/null +++ b/Metodos_de_Cadenas.py @@ -0,0 +1,38 @@ +# Metodos de cadenas + +# Los metodos de cadenas son aquellos metodos que nos permiten interactuar con los strings (cadenas de texto), ya sea para conocer algo en particular o modificar en algun punto estas cadenas de texto + +""" Algunos de estos metodos, son los siguientes. Que si bien no son los mas importantes si pueden ser de los mas utilizados + + - upper() --> Convierte las letras en mayusculas + - lower() --> Convierte las letras en minusculas + - capitalize() --> Pone la primer letra del string en mayuscula + - count() --> Indica cuantas veces se repite una letra o una cadena dentro de un texto + - find() --> Representa el indice (posicion) de un caracter o grupo de caracteres dentro de un texto + - isdigit() --> Comprueba si un valor es numerico, es un digito o no lo es + - isalum() --> Comprueba si un valor es alphanumerico + - isalpha() --> Comprueba si hay solo letras (los espacios en blanco no los toma en cuenta) + - split() --> Separa por palabras usando espacios + - strip() --> Eliminas los espacios vacios o sobrantes al principio y al final + - replace() --> Reemplaza una letra o palabra por otra dentro de un string + - rfind() --> Comprueba el indice (posicion) de un caracter al igual que el find() solo que este lo hace empezando el conteo desde atras, es decir de derecha a izquierda """ + +nombre_usuario = input('Introduce tu nombre de usuario: ') + +print(f'Tu nombre de usuario es: {nombre_usuario}') +print(f'Tu nombre de usuario es: {nombre_usuario.upper()}') +print(f'Tu nombre de usuario es: {nombre_usuario.lower()}') +print(f'Tu nombre de usuario es: {nombre_usuario.capitalize()}') + +edad = input('Introduce tu edad: ') + +while (edad.isdigit() == False): + print('Introduce un valor numerico correspondiente a tu edad') + + edad = input('Introduce tu edad: ') + +if int(edad) < 18: + print('No se puede generar tu registro') + +else: + print('Ya puedes generar tu registro') \ No newline at end of file diff --git a/Mis_Coches b/Mis_Coches new file mode 100644 index 0000000..92b239a Binary files /dev/null and b/Mis_Coches differ diff --git a/Modulos.py b/Modulos.py new file mode 100644 index 0000000..e81305e --- /dev/null +++ b/Modulos.py @@ -0,0 +1,79 @@ +# Módulos --> Son archivos con extensión .py .pyc (Python compilado) o archivo escrito en C para Python, que posee su propio espacio de nombres y que puede contener variables, funciones, clases e incluso otro módulos. En otras palabras es el archivo donde escribimos el codigo de nuestro programa + +# Los modulos sirven para organizar y reutilizar el codigo (modularizacion y reutilizacion) + +# Reutilizacion --> En la programacion orientada a objetos siempre hay que reutilizar el codigo ya que es una de las maximas ventajas que nos ofrece. Con reutilizar no queremos decir que copiemos y peguemos codigo que hayamos hecho con anterioridad, si no que utilicemos los modulos de otros programas o aplicaciones que ya tienen cierto codigo y que nos pueden servir para el nuevo programa que estamos creando + +# Modularizacion --> Como su nombre lo indica es dividir el codigo en modulos, es decir en pequeñas partes. En la creacion de una aplicacion siempre es mejor y mas facil manejar una aplicacion que esta divida en pequeñas piezas que una que esta hecha en un solo mega archivo con miles de lineas de codigo. Ya sea para implementar, corregir, añadir, quitar etc codigo en la aplicacion es mejor tenerla divida en pequeños modulos, que en un solo archivo que contenga todo el codigo el cual podria ser demasiado. La modularizacion implica que nuestros programas o aplicaciones funcionen como un tipo de puzzle donde un monton de piezas trabajan de forma conjunta para dar como resultado un todo, en este caso una aplicacion o programa en su totalidad + +# Para crear un modulo es tan sencillo como crear un archivo con extension .py (o .pyc o archivo C) y guardarlo donde nos interese + +# A CONTINUACION EMPEZAREMOS A HACER USO DE LOS MODULOS EXTERNOS A ESTE COMO EL MODULO DE FUNCIONES MATEMATICAS, EL MODULO DE VEHICULOS ETC + +# Para utilizar un modulo en Python lo primero que hay que hacer es importarlo, para eso hacemos uso de la palabra reservada import seguido del nombre del modulo a importar + +""" Cuando importamos modulos no solo basta con importarlos para poder ocuparlos, para esto ultimo tenemos que definir ciertas acciones o codigos los cuales nos permitiran utilizar los modulos importados + + Formas de utilizar los modulos importados + + - import - Nomenclatura del punto: Este se ocupa cuando solo se utiliza la directiva import. Al igual que en la programacion orientada a objetos es necesario hacer uso del punto para llamar a la funcion del modulo. Ej. modulo_funcionesMatematicas.sumar(). Este forma tiene un inconveniente hasta cierto aspecto y es que cada vez que quieras utilizar una funcion del modulo hay que llamar al modulo seguido de la funcion con el punto entre ambos, esto no viene bien si lo que se busca es hacer uso del modulo completo, esto viene bien si solo se va a ocupar alguna funcion o codigo en concreto, ya que consume menos recursos que llamar y tener disponible el modulo completo + + - from: Para evitar el tener que llamar al modulo cada vez que se ocupe una funcion de este o cualquier otro fragmento de codigo cambiamos la directiva import por from seguida del nombre del modulo añadiendo el import y la funcion o codigo a ejecutar. Este al igual que el anterior (directiva import) tiene el inconveniente que tienes que definir que funcion o codigo vas a utilizar, por lo tanto si quieres hacer uso de codigo diferente o alguna otra funcion el programa arrojara un error. Este al igual que el anterior sirve para economizar recursos y viene bastante bien cuando vas a ocupar algo en especifico y no todo lo que contiene el modulo como tal + + - from... import *: La directiva from con el import * nos sirve para ocupar en su totalidad y tener disponible sin restriccion alguna todo lo que tenemos en el modulo que estamos importando. Esto viene bastante bien cuando vamos a hacer uso de todo o de varias funciones o codigo que vienen en el modulo y asi evitar el inconveniente que se tiene con las 2 formas anteriores. Sin embargo esto consume mas recursos, ya que almacena un espacio considerable en memoria para tener disponible todo el contenido del modulo """ + +# IMPORTANTE: Para efectos practivos y entendibles yo estoy importando los modulos en la seccion donde estoy haciendo referencia a cada uno de estos, pero esto no debe de ser asi, los modulos se tienen que importar al inicio del archivo, por encima de todo nuestro codigo + +print('-----Directiva From-----') + +# Directiva import +import modulo_funcionesMatematicas + +modulo_funcionesMatematicas.suma(7, 5) +modulo_funcionesMatematicas.resta(9, 5) + +print('-----Directiva From-----') + +# Directiva from +from modulo_funcionesMatematicas import suma + +suma(7,5) +# resta(9,5) + +print('-----Directiva From... import *-----') + +# Directiva from... import * +from modulo_funcionesMatematicas import * + +suma(7,5) +resta(9,5) +multiplicacion(6,3) +division(8,4) + +# Esto puede que nos haga pensar que entonces cual es la diferencia de utilizar solo el import, el from o el from... import *, si poniendo este ultimo te quitas de problemas al tener todo disponible... Y esta diferencia son los recursos, es un tema de optimizacion, donde al ocupar el * para tener disponible el modulo completo se esta reservando un espacio muy grande en memoria para tener el modulo completo disponible y esto en estos programas de ejercicios y pequeños no resulte ser un problema ya que no vemos el consumo excesivo de recursos, pero si el programa es grande, el modulo sera grande y podra tener miles de lineas de codigo y es aqui donde los recursos a ocupar son muchos y el espacio en memoria para reservar este modulo seria bastante grande, mientras que cuando ocupas el import o el from solo estamos generando que se reserve un espacio de memoria pequeño para la funcion, clase o codigo que vamos a ocupar y no para todo el modulo completo + +print('-----Vehiculos-----') + +from modulo_vehiculos import * + +print('---Coches---') + +cocheUno = Vehiculos('Chevrolet', 'Camaro') +cocheUno.arrancar() +cocheUno.propiedadesEstado() + +print('---Motos---') + +motoUno = Moto('HONDA', 'CBR600RR') +motoUno.caballo() +motoUno.propiedades() + +print('') + +motoDos = Moto('KAWASAKY', 'H2R') +motoDos.arrancar() +motoDos.acelerando() +motoDos.caballo() +motoDos.propiedades() + +# Cuando se importan modulos, el interprete de Python busca estos modulos en la misma ruta en la que se encuentra el modulo o script que lo esta llamando, si el modulo a importar no se encuentra en esta ruta Python procedera a buscarlo en la ruta 'syspath' que es la ruta donde se encuentra instalado Python y si el modulo no se encuentra en ninguna de estas dos rutas el programa dara error. Si que hay una forma de importar modulos se encuentren en rutas diferentes, vaya se encuentren donde se encuentren los modulos los podemos importar, pero esto lo hacemos mediante lo que se denominan 'paquetes' un tema que veremos en el siguiente capitulo... \ No newline at end of file diff --git a/POO 1_Teoria y Conceptos.py b/POO 1_Teoria y Conceptos.py new file mode 100644 index 0000000..fcebd63 --- /dev/null +++ b/POO 1_Teoria y Conceptos.py @@ -0,0 +1,108 @@ +# POO - Programacion Orientada a Objetos - Pildoras Informaticas / Videos 24,25 y 26 del Curso + +""" En que consiste??? + Trasladar la naturaleza de los objetos de la vida real al codigo de programacion + + Cual es la naturaleza de un objeto de la vida real??? + Los objetos tienen un estado, un comportamiento (que puede hacer?), y unas propiedades + + Pongamos un ejemplo: El objeto coche + Cual es el estado de un coche? Un coche puede estar parado, circulando, aparcado etc... + Que propiedades tiene un coche? Un coche tiene un color, un peso, un tamaño etc... + Que comportamiento tiene un coche? Un coche puede arrancar, frenar, acelerar, girar, etc...""" + +""" Ventajas de la POO + - Programas dividos en 'trozo', 'partes', 'modulos' o 'clases'. Modularizacion + - Muy reutilizable. Herencia + - Si existe fallo en alguna linea de codigo, el programa continuara con su funcionamiento. Tratamiento de excepciones + - Encapsulamiento """ + +""" Vocabulario de la POO + - Clase + - Objeto + - Ejemplar de clase o Instancia de clase. Ejemplarizar una clase o Instanciar una clase + - Modularizacion + - Encapsulamiento / encapsulacion + - Herencia + - Polimorfismo """ + +# Clase - Modelo donde se redactan las caracteristicas comunes de un grupo de objetos. Creando 'metodos de acceso' se consigue conectar clases entre si, una clase a otra para que funcionen en conjunto, como una unidad o equipo. Los metodos de acceso solo tienen acceso a ciertas caracteristicas de cada una de las clases + +# Ejemplar, intancia u objeto de clase es lo mismo, son sinonimos - Esto es un objeto o ejemplar perteneciente a una clase + +# Modularizacion - En parte son las clases que contiene un programa, la modularizacion hace referencia a trozos o partes del programa que como su nombre lo indica son modulos por decirlo de alguna manera. Esto sirve para reutilizar trozos de codigo. Esto de la modularizacion es como un amplificador gradiente, el cual se compone de varios modulos (tornamesa, amplificador, equalizador etc) los cuales tienen funciones diferentes pero que a su vez juntando todos los modulos forman el amplificador como tal, pero que a su vez si uno fallaba los demas modulos seguian funcionando + +# La encapsulacion es muy parecida en ciertos aspectos a la modularizacion y se podria decir que van de la mano, ya que la encapsulacion hace referencia a lo que contiene cada clase en particular y que no tiene relacion de forma directa con otra clase, no obstante el que no tenga relacion de forma directa no quiere decir que no tenga nada que ver, ya que todas en conjunto forman el programa entero. Si regresamos al ejemplo del amplificador, la encapsulacion seria lo que cada modulo que conforman el amplificador contiene en su interior y aunque cada modulo tiene su electronica de forma independiente dentro de su gabinete correspondiente y la electronica de los demas modulos no tengan nada que ver con la electronica de los demas funcionan en conjunto para hacer lo que seria todo el amplificador como tal, conectandose estos modulos entre si. Lo mismo es en la programacion, todas las clases aunque son modulos independientes y estan encapsuladas tambien estan conectadas entre si para trabajar en conjunto y asi formar el programa como tal. Otra forma de ver la encapsulacion es que no hay forma de llegar a algo desde fuera + +""" Para acceder a las propiedades y comportamientos del objeto se usa lo que se conoce como 'nomenclatura del punto' +Objeto - miCoche + Para acceder a las propiedades: + nombreObjeto.propiedad = 'valor' + + + miCoche.color = 'rojo' + miCoche.peso = 1500 + +Objeto - miCoche + Para acceder a los comportamientos: + nombreObjeto.comportamiento() + + miCoche.arranca() + miCoche.frena() + miCoche.acelera()""" + +# La clase es la base para despues crear objetos, instancias o ejemplares que pertenezcan a una clase + +# El nombre de la clase la primera letra debe ser mayuscula + +class Coche(): # Esta clase tiene 4 propiedades y 2 comportamientos + # Propiedades + # Todos los objetos, intancias o ejemplares que pertenezcan a esta clase van a tener estas propiedades + largoChasis = 250 + anchoChasis = 120 + numRuedas = 4 + encendido = False + + # Comportamientos + + # Los comportamientos vienen determinados por lo que se denominan 'metodos'. Es decir se tienen que establecer metodos para los comportamientos, un metodo para cada comportamiento + + # Un metodo es una funcion que pertenece a la clase en la que se esta creando, es de la clase. Mientras que una funcion no pertenece a ninguna clase + + # Los metodos se crean con la palabra reservada 'def' (misma palabra reservada para las funciones), las diferencias entre una funcion y un metodo, es que la funcion no pertenece a ninguna clase, mientras que el metodo si pertenece a la clase en la cual se esta creando, ademas el metodo lleva el parametro 'self' de forma obligatoria que hace referencia al objeto mismo, es decir hace referencia al objeto que creemos que va a pertenecer a la clase que tiene ese metodo, mientras que a la funcion le damos como parametro el que nosotros queramos o necesitemos + + # Algunas editores al momento de crear un metodo y hacerlo mediante la ayuda del editor al escribir codigo y crear la estructura del metodo pone un pass de forma predeterminada para que si no agregamos codigo dentro del metodo este no genere un conflicto o error al momento de correr el codigo + + def arrancar(self): + self.encendido = True + + def estado(self): + # Podemos omitir el True y solo poner if(self.encendido:). Al momento de omitir el True Python interpetra que es True, si fuera False si lo tendriamos que poner, sin embargo y aunque puedo omitirlo, lo escribo para evitar confusiones + if(self.encendido) == True: + return 'El coche esta encendido' + else: + return 'El coche esta apagado' + +# Para construir un objeto debemos salir de la clase y esto lo hacemos igual que todo lo demas, no dando identacion al momento de crear el codigo que hace referencia al objeto, es decir el codigo creador del objeto tiene que estar al mismo nivel de linea que la clase + +coche1 = Coche() # Con esto hemos creado un objeto perteneciente a la clase Coche. A esto se le conoce como instancia una clase + +# Nomencatura del punto + +# Para saber las propiedas, conocer o cambiar el comprtamiento del objeto utilizamos la nomenclatura del punto + +# Podemos hacerlo de forma directa desde un print o bien almacenando la propiedad o comportamiento en una variable y despues imprimir esta variable + +largoCoche1 = coche1.largoChasis + +print('El largo del coche es:',coche1.largoChasis,'cms') +print('El ancho del coche es:', coche1.anchoChasis, 'cms') +print(f'El numero de ruedas que tiene el coche es: {coche1.numRuedas}') +print(f'El coche tiene {coche1.numRuedas} ruedas') + +# Como podemos observar en los prints de arriba podemos concatenar textos con codigo de diferente forma, ya sea utilizando el metodo de la 'f' o bien separando por comas el texto del codigo. Con el metodo de la f todo va dentro de las comillas y es necesario darle el espaciado normal si es que lo necesitamos para que al momento de imprimirlo tenga espaciado, mientas que si lo hacemos de la otra forma no es necesario dar espacios, ya que la coma que podemos para separar texto del codigo nos genera dicho espacio, aun asi podemos darle espacio, sin embargo no es necesario adenas de que no habra cambio alguno al momento de imprimirlo en la consola + +print(coche1.estado()) # Aqui no hemos llamado al metodo arrancar, por lo tanto la propiedad encendido esta en False, esto nos da como resultado el mensaje que definimos en el if del metodo estado si es que la propiedad encendido no cambia a True + +coche1.arrancar() # Aqui hemos llamado al metodo arrancar el cual hace que la propiedad encendido cambie a True +print(coche1.estado()) # Y por ultimo volvemos a imprimir el estado del coche despues de haber llamado al metodo arrancar y podemos ver que ahora nos arroja como mensaje el que pusimos en el if del metodo estado si es que la propiedad encendido cambiaba a True \ No newline at end of file diff --git a/POO 2_Encapsulacion de variables y Constructor.py b/POO 2_Encapsulacion de variables y Constructor.py new file mode 100644 index 0000000..1083e61 --- /dev/null +++ b/POO 2_Encapsulacion de variables y Constructor.py @@ -0,0 +1,156 @@ +# POO - Programacion Orientada a Objetos 2da Parte - Pildoras Informaticas / Video 27 del Curso + +# En esta 2da parte veremos la encapsulación de variables y el constructor + +class Coche(): + largoChasis = 250 + anchoChasis = 120 + numRuedas = 4 + encendido = False + + def arrancar(self): + self.encendido = True + + def estado(self): + # Podemos omitir el True y solo poner if(self.encendido:). Al momento de omitir el True Python interpetra que es True, si fuera False si lo tendriamos que poner, sin embargo y aunque puedo omitirlo, lo escribo para evitar confusiones + if(self.encendido): + return 'El coche esta encendido' + else: + return 'El coche esta apagado' + + def arrancarEnMarcha(self, arrancamos): # El parametro adicional que le estamos pasando al metodo lo declaramos al momento de llamar al metodo, estamos obligados a pasarle un valor al parametro, si no lo hacemos el programa dara error + self.arrancarEnMarcha = arrancamos + + if(self.arrancarEnMarcha) == True: + return 'El carro esta prendido y en marcha' + + else: + return 'El coche esta apagado y parado' + + def propiedades(self): + print(f"""El carro tiene las siguientes propiedades + Largo: {self.largoChasis} cms + Ancho: {self.anchoChasis} cms + Ruedas: {self.numRuedas}""") + +print('-------Coche 1------') + +coche1 = Coche() + +print(f'El largo del coche es {coche1.largoChasis} cms') +print(f'El ancho del coche es {coche1.anchoChasis} cms') +print(f'El coche tiene {coche1.numRuedas} ruedas') +coche1.arrancar() +print(coche1.estado()) + +print('-------Coche 2------') + +coche2 = Coche() + +print(f'El largo del coche es {coche2.largoChasis} cms') +print(f'El ancho del coche es {coche2.anchoChasis} cms') +print(f'El coche tiene {coche2.numRuedas} ruedas') +coche2.estado() +print(coche2.estado()) + +print('-------Coche 3------') + +coche3 = Coche() + +# print(f'El largo del coche es {coche3.largoChasis} cms') +# print(f'El ancho del coche es {coche3.anchoChasis} cms') +# print(f'El coche tiene {coche3.numRuedas} ruedas') +print(coche3.arrancarEnMarcha(True)) # El print en consola dependera si el metodo ya tiene un print declarado dentro de el o no, si no lo tiene hay que hacer uso del print al momento de llamar al metodo para que imprima el resultado de la llamada +coche3.propiedades() # Si el metodo ya tiene un print dentro de el, solo sera necesario llamar al metodo ya que imprimira lo que tiene almacenado dicho metodo + +print('-------Coche 4------') + +coche4 = Coche() + +# print(f'El largo del coche es {coche4.largoChasis} cms') +# print(f'El ancho del coche es {coche4.anchoChasis} cms') +# print(f'El coche tiene {coche4.numRuedas} ruedas') +print(coche4.arrancarEnMarcha(False)) # Aqui estamos pasando el valor al parametro adicional correspondiente al asignado al metodo. Este es un parametro adicional al que recibe por defecto, el que ya viene implicito que es self +coche4.propiedades() + +# Comente los print que nos dan la informacion acerca de las propiedades del coche por separado debido a que ya estan de mas, ya que el metodo propiedades nos esta dando como resultado todas las caracteristicas del carro + +# Estado inicial --> Normalmente se acostumbra que al crear una instancia de clase el objeto creado tenga las caracteristicas de la clase de forma predeterminada, como de fabrica, es decir que al momento de crear un objeto o una instancia, por el hecho de haberlo creado ya tenga de forma automatica las caracteristicas comunes de la clase, para esto se usa el 'estado inicial' + +# Constructor --> Es un metodo especial con el cual se les da un 'estado inicial' a los objetos. Es por medio del cual especificamos cual va a ser el estado inicial de los objetos que se creen, es decir cuales seran las caracteristicas de la clase que tendran los objetos o instancias de forma predeterminada al momento de crearlos. + +""" Para utilizar un constructor es necesario crearlo y dentro de este poner las caracteristicas que llevaran los objetos de forma predeterminada + + Para crear un constructor lo hacemos de la siguiente manera + - Palabra reservada def, seguida de dos guiones bajos, seguida de la palabra init y por ultimo otros dos guiones bajos, con sus respectivos parentesis como cualquier metodo y dentro de estos la palabra reservada self + + def __init__(self) + + Las caracteristicas dentro del constructor tienen que estar precedidas por self.""" + +print('---------Estado Inicial y Constructor--------') + +class Coche2(): + def __init__(self): # Encapsulación de variables + self.largoChasis = 250 + self.anchoChasis = 120 + self.numRuedas = 4 + self.__numRuedas1 = 4 # De esta manera con los dos guiones bajos precediendo el nombre de la caracterista la encapsulamos y protegemos de que sea accesible a modificaciones o alteraciones desde fuera de la clase. Sin embargo si sera accesible a modificaciones desde dentro de la clase. Esto provoca que donde se escriba esta caracteristica se tiene que poner con el mismo nombre, es decir con los dos guiones bajos precediendo el nombre + self.encendido = False + + def arrancar(self): + self.encendido = True + + def estado(self): + # Podemos omitir el True y solo poner if(self.encendido:). Al momento de omitir el True Python interpetra que es True, si fuera False si lo tendriamos que poner, sin embargo y aunque puedo omitirlo, lo escribo para evitar confusiones + if(self.encendido): + return 'El coche esta encendido' + else: + return 'El coche esta apagado' + + def arrancarEnMarcha(self, arrancamos): # El parametro adicional que le estamos pasando al metodo lo declaramos al momento de llamar al metodo, estamos obligados a pasarle un valor al parametro, si no lo hacemos el programa dara error + self.arrancarEnMarcha = arrancamos + + if(self.arrancarEnMarcha) == True: + return 'El carro esta prendido y en marcha' + + else: + return 'El coche esta apagado y parado' + + def propiedades(self): + print(f'El carro tiene {self.numRuedas} ruedas. Un largo de {self.largoChasis} cms. Y un ancho de {self.anchoChasis} cms') + + def propiedades2(self): + print(f'El carro tiene {self.__numRuedas1} ruedas, un largo de {self.largoChasis} cms y un ancho de {self.anchoChasis} cms') + +print('--------Coche Uno-------') + +cocheUno = Coche2() + +cocheUno.arrancar() +print(cocheUno.estado()) +print(cocheUno.arrancarEnMarcha(True)) +cocheUno.propiedades() + +print('--------Coche Dos-------') + +cocheDos = Coche2() + +cocheDos.arrancar() +print(cocheDos.estado()) +print(cocheDos.arrancarEnMarcha(False)) +cocheDos.numRuedas = 2 # Como podemos observar aqui estamos modificando el numero de ruedas mediante el objeto, la conotacion del punto y entrando a una de las caracteristicas de la clase, sin embargo aunque esto es posible y en algun momento nos valdra para algo y nos servira, en este caso en particular no es asi, ya que no tienes sentido debido a que ningun coche tiene 2 ruedas. Para evitar esto y que ciertas caracteristicas no puedan ser modificadas utilizamos la encapsulacion +cocheDos.propiedades() + +# Encapsulación --> La encapsulacion nos sirve para que como su nombre lo indica encapsulemos caracteristicas de las clases y asi protegerlas y no poderlas modificar desde fuera de la clase y asi evitar en este caso un coche de 2 ruedas + +# Para encapsular una variable o caractristica de una clase en Python, tenemos que preceder el nombre de esta con dos guiones bajos (__), con esto le estamos diciendo a python que encapsule esta caracterista y por lo tanto esta no sera accesible desde fuera de la clase. Ej __numRuedas1 + +print('--------Coche Tres-------') + +cocheTres = Coche2() + +cocheTres.__numRuedas1 = 2 +cocheTres.propiedades2() # Aqui como podemos observar la caracteristica numRuedas1 no cambio su valor, aunque en la linea de codigo anterior tecnicamente lo hicimos, este cambio no surtio efecto ya que esta caracteristica esta encapsulada y protegida para que no pueda ser modificable desde fuera de la clase + +# Si al hacer uso de una caracteristica o variable que esta encapsulada no ponemos los dos guiones bajos (__) el programa no fallara ni dara error por que no lo hay, porque lo que esta pasando en realidad es que se estaria hablando de dos variables diferentes, que no tienen nada que ver. Ej No es lo mismo numRuedas a __NumRuedas, esto para Python son dos variables completamente diferentes \ No newline at end of file diff --git a/POO 3_Encapsulacion de metodos.py b/POO 3_Encapsulacion de metodos.py new file mode 100644 index 0000000..73917c3 --- /dev/null +++ b/POO 3_Encapsulacion de metodos.py @@ -0,0 +1,124 @@ +# POO - Programacion Orientada a Objetos 3ra Parte - Pildoras Informaticas / Video 28 del Curso + +# En esta 3ra parte veremos la encapsulación de métodos + +# Para encapsular un método lo hacemos de la misma manera que con las variables, anteponiendo al nombre del método dos guiones bajos (__) + +# Para que nos sirve encapsular un método? Pues para la mismo que sirve encapsular una variable. Que no pueda ser accesible desde fuera de la clase. Y Esto para que nos sirve? Para que el programa no haga cosas que no debe o que no tiene sentido alguno. Ej: que en el programa que estamos haciendo aqui el metodo revisionInicial no se ejecute una vez que el carro ya esta encendido y vuelva a ejecutar este metodo, esto no tiene sentido ya que este chequeo se debe hacer antes de arrancar el coche, o peor aun que ejecute el metodo revisionInicial al carro que esta parado y que ni siquiera estamos intentado arrancar, este todavia tendria menos sentido que el anterior + +class Coche(): + def __init__(self): + self.__largoChasis = 250 + self.__anchoChasis = 120 + self.__ruedas = 4 + self.__encender = False + self.color = 'rojo' + + def arrancar(self, arrancamos): + self.__encender = arrancamos + + if self.__encender: + chequeo = self.revisionInicial() + + if self.__encender and chequeo: + return 'Revision inicial existosa. El vehiculo a sido arrancado' + elif self.__encender and chequeo == False: + return 'Revision inicial fallida. Revise el estado del vehiculo' + else: + return 'El vehiculo esta parado y parqueado' + + def propiedades(self): + print(f'El vehiculo es de color {self.color}, tiene un largo de {self.__largoChasis} cms, un ancho de {self.__anchoChasis} cms y un total de {self.__ruedas} ruedas.') + + def revisionInicial(self): + print('***Realizando revision inicial***') + + self.gasolina = 'ok' + self.aceite = 'ok' + self.puertas = 'close' + + if self.gasolina == 'ok' and self.aceite == 'ok' and self.puertas == 'close': + return True + + else: + return False + +print('------Carro 1------') + +carro1 = Coche() +print(carro1.arrancar(True)) +carro1.propiedades() +print(carro1.revisionInicial()) # Aqui estamos llamando al metodo revisionInicial y esta haciendo este chequeo una vez que el carro esta encendido y esto eventualmente no deberia pasar ya que esta revision la debe hacer unica y exclusivamente antes de encender el carro + +print('------Carro 2------') + +carro2 = Coche() +print(carro2.arrancar(False)) +carro2.color = 'negro' +carro2.propiedades() +print(carro2.revisionInicial()) # De igual manera aqui estamos ejecutando el metodo revisionInicial y este todavia tiene menos sentido que el anterior ya que aqui el carro esta parado y ni siquiera estamos haciendo el intento de encenderlo y aun asi esta haciendo la revision que se supone debe hacer solamente antes de querer encender en carro + +# Para eso sirve la encapsulacion de metodos, para evitar cosas como las anteriores donde el programa hace cosas que no debe hacer, que no tienen sentido etc + +# A diferencia de las variables donde podemos intentar modificarlas y estar el codigo escrito con la modificacion aunque esta no surta efecto, en los metodos no es asi. Los metodos con el simple hecho de llamarlos si estan encapsulados el programa nos dara error, por lo tanto estos si a estos los estamos llamando y estan encapsulados hay que comentarlos o mejor aun eliminarlos. + +class Coche2(): + def __init__(self): + self.__largoChasis = 250 + self.__anchoChasis = 120 + self.__ruedas = 4 + self.__encender = False + self.color = 'rojo' + self.presionNeumaticos = 'ok' + + def arrancar(self, arrancamos): + self.__encender = arrancamos + + if self.__encender: + chequeo = self.__revisionInicial() # Al igual que las variables encapsuladas los metodos encapsulados al momento de llamarlos o utilizarlos en otra parte de nuestro codigo los tenemos que poner tal cual como esta, con los dos guiones bajos (__) + + if self.__encender and chequeo and self.presionNeumaticos == 'ok': + return 'Revision inicial existosa. El vehiculo a sido arrancado' + elif self.__encender == True and chequeo == False or self.presionNeumaticos != 'ok': + return 'Revision inicial fallida. Revise el estado del vehiculo' + else: + return 'El vehiculo esta parado y parqueado' + + def propiedades(self): + print(f'El vehiculo es de color {self.color}, tiene un largo de {self.__largoChasis} cms, un ancho de {self.__anchoChasis} cms y un total de {self.__ruedas} ruedas.') + + def __revisionInicial(self): + print('***Realizando revision inicial***') + + self.gasolina = 'ok' + self.aceite = 'ok' + self.puertas = 'close' + + if self.gasolina == 'ok' and self.aceite == 'ok' and self.puertas == 'close': + return True + + else: + return False + +print('------Carro 3------') + +carro3 = Coche2() +print(carro3.arrancar(True)) +carro3.propiedades() +# print(carro3.revisionInicial()) # Si dejamos estas linea de codigo establecida el programa dara un error, ya que el metodo revisionInicial esta encapsulado, por lo tanto no es posible acceder a el desde afuera de la clase y con acceder a el me refiero a llamarlo para quererlo ejecutar + +print('------Carro 4------') + +carro4 = Coche2() +print(carro4.arrancar(False)) +carro4.color = 'verde' +carro4.propiedades() +# print(carro4.revisionInicial()) # Si dejamos estas linea de codigo establecida el programa dara un error, ya que el metodo revisionInicial esta encapsulado, por lo tanto no es posible acceder a el desde afuera de la clase y con acceder a el me refiero a llamarlo para quererlo ejecutar + +print('------Carro 5------') + +carro5 = Coche2() +carro5.presionNeumaticos = 'low' +print(carro5.arrancar(True)) +carro5.color = 'blanco' +carro5.propiedades() \ No newline at end of file diff --git a/POO 4_Herencia 1.py b/POO 4_Herencia 1.py new file mode 100644 index 0000000..d0edb94 --- /dev/null +++ b/POO 4_Herencia 1.py @@ -0,0 +1,103 @@ +# POO - Programacion Orientada a Objetos 3ra Parte - Pildoras Informaticas / Videos 29 y 30 del Curso + +# Herencia + +# Herencia --> La herencia se trata de que como su nombre lo indica heredar lo que alguien mas tiene. Como suele pasar en la vida real con los bienes de las personas. Supongamos una familia donde esta el abuelo, el padre y los hijos. Cuando el abuelo fallece, el padre 'hereda' los bienes del abuelo, cuando el padre fallece, los hijos 'heredan' los bienes del padre. Este mismo concepto lo toma la programacion en las clases, donde existe la clase 1 (abuelo), la clase 2 (padre) y las clases 3, 4, 5 etc (hijos), donde las clases inferiores van 'heredando' lo de las clases superiores + +# En la programacion la clase con la jerarquia mas alta (abuelo) se le conoce como 'clase padre' o 'superclase', a la clase que le sigue (padre), se le conoce como 'subclase' o 'superclase' (subclase de la clase mas alta (abuelo) y superclase de las clases que estan por debajo (hijos)) + +""" Clase 1 --> superclase o clasepadre (abuelo) + Clase 2 --> subclase o superclase (padre) + Clase 3 Clase 4 Clase 5 (hijos) +""" + +# Para que sirve la Herencia? --> Sirve para reutilizar codigo en caso de crear objetos similares. En los archivos anteriores de la Programacion Orientada a Objetos hemos creado objetos, pero estos han sido iguales o del mismo tipo... carros, pero supongamos que ahora vamos a crear un programa mas complejo donde no solo vamos a crear objetos de tipo carro si no que tambien vamos a crear objetos de tipo moto, camiones, lanchas, autobuses etc, estos aunque no son iguales si son similares, ya que todos estos van a tener caracteristicas y comportamientos en comun como por ej: caracteristicas en comun --> Marca, Modelo, un Motor / comportamientos en comun --> Acelerar, Frenar, Arrancar + +# Si no existiera la herencia, tendriamos que crear cada objeto de forma individual, uno por uno con sus correspondientes caracteristicas y metodos por separado aunque fueran comunes de todos ellos + +# La herencia consiste en crear todas las caracteristicas o propiedades junto con los comportamientos en comun y englobarlos en una clase la cual va a ser o se va a denominar la clase padre o superclase + +# Las particularidades especficas o individuales de cada uno de los objetos las construiremos en su propia clase + +class Vehiculos(): + def __init__(self, marca, modelo): + self.marca = marca + self.modelo = modelo + self.encendido = False + self.acelerar = False + self.frenar = False + + def arrancar(self): + self.encendido = True + + def acelerando(self): + self.acelerar = True + + def frenando(self): + self.frenar = True + + def propiedadesEstado(self): + print(f'Marca: {self.marca} \nModelo: {self.modelo} \nPrendida: {self.encendido} \nAcelerando: {self.acelerar} \nFrenando: {self.frenar}') + +class Moto(Vehiculos): + motoCaballo = 'Caballando' # No entiendo porque se declaro antes la variable fuera del metodo. Y con un string vacio + def caballo(self): + self.motoCaballo = 'Caballito en proceso' + + def propiedadesEstado(self): + print(f'Marca: {self.marca} \nModelo: {self.modelo} \nPrendida: {self.encendido} \nAcelerando: {self.acelerar} \nFrenando: {self.frenar} \nCaballo: {self.motoCaballo}') + +print('-----Motorcicle-----') + +moto1 = Moto('Honda', 'CBR') +# moto1.arrancar() +moto1.caballo() +moto1.propiedadesEstado() + +print('-----Van-----') + +# Cuando creamos metodos, al momento de crear variables dentro de estas, quererlas modificar, darles 'x' valor, utilizarlas en un if etc etc etc hay que tener cuidados y utilizar el nombre de las variables, NO el nombre del metodo, tambien no se nos debe olvidar hacer uso del self anteponiendolo al nombre de las variables + +class Camioneta(Vehiculos): + def carga(self, cargada): + self.cargar = cargada + if self.cargar: + return 'La camioneta está cargada' + else: + return 'La camioneta no está cargada' + +myVan = Camioneta('Chevrolet', 'Silverado') +myVan.arrancar() +myVan.propiedadesEstado() +print(myVan.carga(True)) + +print('-----Electric Car-----') + +class ElectricCars(): + def __init__(self): + self.autonomia = '100 kms' + + def chargeBattery(self, charging): + self.chargeBat = charging + if self.chargeBat: + return 'The battery is charging' + else: + return 'The battery is not charging' + +myElectricCar = ElectricCars() +print(myElectricCar.chargeBattery(True)) +print(myElectricCar.autonomia) + +print('-----Electric Bike-----') + +class ElectricBike(ElectricCars, Vehiculos): # Aqui estamos haciendo uso de la Herencia Multiple, la cual nos permite heredar de mas de una clase, para hacer esto se tienen que poner todas las clases de las cuales se va a heredar separadas por comas. En la Herencia multiple, se le da prioridad/preferencia a la clase que se defina primero dentro de los parentesis + pass + +# myBike = ElectricBike('GT', 'X500') # Si descomentamos esta línea veremos que nos arroja un error, porque? Si se le estan pasando los argumentos correspondientes a marca y modelo. Esto es debido a que como se comento anteriormente al hacer uso de la herencia multiple, esta le da prioridad a la clase que se esta definiendo primero en los parentesis, la cual en el ej anterior es la clase correspondiente a ElectricsCars, por lo tanto estamos heredando el constructor correspondiente a esta clase y este constructor no nos pida marca ni modelo y por lo tanto no tiene estos argumentos definidos. Si invertimos la posicion de las clases de las que esta heredando estariamos cambiando la proiridad de la herencia y por lo tanto ya no habria error. + +class ElectricBike2(Vehiculos, ElectricCars): + pass + +miBike = ElectricBike2('GT', 'X500') +miBike.propiedadesEstado() +print(miBike.chargeBattery(False)) \ No newline at end of file diff --git a/POO 5_Herencia 2.py b/POO 5_Herencia 2.py new file mode 100644 index 0000000..cbc8600 --- /dev/null +++ b/POO 5_Herencia 2.py @@ -0,0 +1,205 @@ +# POO - Programacion Orientada a Objetos 3ra Parte - Pildoras Informaticas / Video 31 del Curso + +# Terminos super(), isinstance() y concepto de princpio de sustitucion + +class Vehiculos(): + def __init__(self, marca, modelo): + self.marca = marca + self.modelo = modelo + self.encendido = False + self.acelerar = False + self.frenar = False + + def arrancar(self): + self.encendido = True + + def acelerando(self): + self.acelerar = True + + def frenando(self): + self.frenar = True + + def propiedadesEstado(self): + print(f'Marca: {self.marca} \nModelo: {self.modelo} \nPrendida: {self.encendido} \nAcelerando: {self.acelerar} \nFrenando: {self.frenar}') + +class Moto(Vehiculos): + motoCaballo = 'Caballando' + def caballo(self): + self.motoCaballo = 'Caballito en proceso' + + def propiedadesEstado(self): + print(f'Marca: {self.marca} \nModelo: {self.modelo} \nPrendida: {self.encendido} \nAcelerando: {self.acelerar} \nFrenando: {self.frenar} \nCaballo: {self.motoCaballo}') + +print('-----Motorcicle-----') + +moto1 = Moto('Honda', 'CBR') +# moto1.arrancar() +moto1.caballo() +moto1.propiedadesEstado() + +print('-----Van-----') + +class Camioneta(Vehiculos): + def carga(self, cargada): + self.cargar = cargada + if self.cargar: + return 'La camioneta está cargada' + else: + return 'La camioneta no está cargada' + +myVan = Camioneta('Chevrolet', 'Silverado') +myVan.arrancar() +myVan.propiedadesEstado() +print(myVan.carga(True)) + +print('-----Electric Car-----') + +class ElectricCars(): + def __init__(self): + self.autonomia = '100 kms' + + def chargeBattery(self, charging): + self.chargeBat = charging + if self.chargeBat: + return 'The battery is charging' + else: + return 'The battery is not charging' + +myElectricCar = ElectricCars() +print(myElectricCar.chargeBattery(True)) +print(myElectricCar.autonomia) + +# En los siguientes ejemplos podemos ver la prioridad que tiene la herencia conforme a las clases cuando se ocupa herencia multiple. Esta preferencia implica que cuando hay clases con el mismo nombre en los metodos, tome el metodo que corresponde a la clase a la que se le esta dando prioridad. Esto conlleva a que si necesitamos ocupar el metodo de la otra clase pero tiene el mismo nombre no lo vamos a poder hacer, es cierto que podemos encontrar la manera de resolverlo, pero no seria la mejor forma o la mas adecuada + +# En estos ejemplos tenemos herencia multiple y ambas clases que se ocupan para la herencia tienen un metodo con el mismo nombre... __init__ y aunque este es un constructor no deja de ser un metodo, por lo tanto cuando queremos ocupar el metodo o constructor de la clase que no tiene la preferencia nos arroja un error. Como dijimos anteriormente podemos solucionar esto de alguna manera, ya sea declarando otro metodo, cambiando el nombre etc, pero no siempre sera la mejor solucion o la que necesitemos. Por ej en el caso de Bike 1, a la clase ElectricsCars que es la que tiene la prioridad podemos agregarle al constructor los parametros necesarios para definir marca y modelo como en la clase Vehiculos, pero no seria la mejor solucion ni la mas elegante. Para solucionar esto tenemos el la funcion super() + +print('-----Electrics Bikes-----') + +class ElectricBike(ElectricCars, Vehiculos): + pass + +print('-----Bike 1-----') + +myBike1 = ElectricBike() +print(myBike1.autonomia) + +class ElectricBike2(Vehiculos, ElectricCars): + pass + +print('-----Bike 2-----') + +myBike2 = ElectricBike2('GT', 'X500') +# print(myBike2.autonomia) +myBike2.propiedadesEstado() +print(myBike2.chargeBattery(False)) + +# Super() --> Esta funcion sirve para que haya donde la definidas en tu codigo va a llamar al metodo de la clase padre + +class Persona(): + def __init__(self, nombre, edad, residencia): + self.nombre = nombre + self.edad = edad + self.lugarResidencia = residencia + + def datosPersona(self): + print(f'Nombre: {self.nombre}, Edad: {self.edad}, Pais de Residencia: {self.lugarResidencia}') + +class Empleado(Persona): + def __init__(self, salario, antigüedad, nombre_empleado, edad_empleado, residencia_empleado): + # super().__init__('Eliab', 31, 'México') + super().__init__(nombre_empleado, edad_empleado, residencia_empleado) + self.salario = salario + self.antigüedad = antigüedad + + def datosPersona(self): + super().datosPersona() + print(f' Salario: {self.salario}, Antigüedad: {self.antigüedad}') + +print('-----Persona-----') + +Moises = Persona('Moises', 31, 'México') +Moises.datosPersona() + +# Si el siguiente codigo lo dejamos asi como esta sin utilizar la funcion super veremos que nos da error, debido a que el metodo Empleado no nos pide 3 valores que son nombre, edad ni lugar de residencia, aunque llegasemos a cambiar estos valores por el salario y la antigüedad de igual forma nos daria error debido a que estamos llamando al metodo datosPersona y aunque este esta heredado de la clase Persona en la clase Empleado no va a reconocer las variables en su interior como nombre, edad y lugarResidencia. Para solucionar esto hacemos uso de la funcion super(), en este caso la debemos declarar en la clase empleado dentro del constructor para que jale el metodo de la clase padre que vendria siendo la clase Persona. Debemos definir en la funcion super el nombre del metodo que queremos jalar, en este caso __init__. Aunque aqui nos encontramos con un problema, el cual es que como le estamos pasando datos especificos, un nombre, una edad y una residencia, todos las instancias u objetos que creemos traeran estos datos, que no siempre sera lo que vayamos a querer. Adicional a esto en la descripcion solo nos esta arrojando los datos de la persona, pero no nos esta arrojando los datos como empleado que son el salario y la antigüedad. Este codigo hay que depurarlo y mejorar para solucionar estos detalles, lo cual haremos a continuacion + +# Para solucionar el problema de los datos especificos lo que tenemos que hacer es añadir parametros dentro del constructor de la clase empleado. Los datos especificos definidos en la funcion super los vamos a sustituir por los argumentos definidos en el constructor de la clase Empleado. Esto conlleva a que al crear un objeto de la clase empleado le pasemos los parametros especificados en su constructor, los cuales en este caso en especifico son 5 y 3 de esos 5 seran utilizados para llamar al constructor de la clase padre + +# Para solucionar el problema de la descripcion donde no nos dice nada del salario y de la antigüedad, lo que tenemos que hacer es crear un metodo en la clase empleado con la funcion super el cual se encargara de llamar al metodo de la clase padre Persona, para tener el metodo descripcion de la clase persona que nos da los datos de la misma y ademas agregar un print o lo que necesitemos para los datos del salario y de la antigüedad + +# Eliab = Empleado('Eliab', 31, 'México') +Eliab = Empleado(8000, 5, 'Eliab', 31, 'México') +Eliab.datosPersona() # Aqui ya estamos ocupando el metodo datosPersona() de la clase Empleado y no de la clase heredada Persona() + +# Que nos estamos ahorrando o en que nos esta beneficiando el uso de la funcion super??? Que en la clase Empleado tengamos que declarar todas las variables que tiene la clase Persona que son nombre, edad y residencia y en el metodo datosPersona tener que repetir toda la linea de codigo que nos da los datos de la persona que se encuentra en la clase Persona(), en este programa no pareceria ser la gran cosa, pero un programa mucho mas extenso o complejo donde hay muchas clases y estan se estan heredando entre si nos estariamos ahorrando muchas lineas de codigo y si no lineas, si repetir o escribir mucho mas codigo + +# A la hora de trabajar con Herencias existe un concepto que se conoce como principio de sustitucion + +# Principio de sustitucion --> Consiste en aplicar el 'es siempre un/una'. Esto quiere decir que al momento de heredar, la clase hijo que hereda a la clase padre tiene que ser algo con sentido logico de la clase padre. A que se refiere esto? A que por ejemplo en el caso de nuestras clases Persona() y Empleado(), la clase Empleado hereda de la clase Persona() y esto quiere decir que en terminos faciles de entender un empleado siempre y antes que ser empleado sera una persona, pero esto no puede ser al reves, un empleado no puede ser empleado si no es una persona, pero una persona no puede ser siempre un empleado, al igual que en ejemplos anteriores anteriores como las clases de coche(), moto() y vehiculos; una moto siempre sera un vehiculo, pero un vehiculo no siempre sera una moto, por lo tanto no tendria sentido que la clase Vehiculo herede de la clase Moto(), asi como que la clase Persona(), herede la clase Empleado(), pero si al reves. Si las clases y las herencias estan definidas con este principio quiere decir que esta bien hechas y que nuestro codigo y logica de programacion es correcto(a) + +# isinstance + +# La funcion isinstance() nos va a informar siempre si un objeto es instancia de una clase determinada. Esta funcion devuelve True si pertence es instancia de la clase que le pasemos o False si es lo contrario, es decir que no sea instancia de la clase. + +# La funcion isinstance nos solicita dos argumentos, el primero la instancia u objeto al cual nos referimos y el segundo la clase de la que vamos a comprobar si pertenece o no + +print(isinstance(Moises, Persona)) +print(isinstance(Moises, Empleado)) +print(isinstance(Eliab, Empleado)) +print(isinstance(Eliab, Persona)) + +# Ahora veremos la manera de agregar marca y modelo a un vehiculo de clase electrica lo cual no nos era posible anteriormente ya que al crear un objeto perteneciente a esta clase y heredar de la clase electricCars de primera mano tomaba el metodo init de esta y no de la clase vehiculos, lo cual hacia imposible asignar una marca y modelo + +# Para esto vamos a crear una clase nueva de carros electricos para ver la diferencia entre esta ultima y la anterior + +print('-----Electric Car 2-----') + +class ElectricCars2(Vehiculos): + def __init__(self, marca, modelo, autonomia): + super().__init__(marca, modelo) + self.autonomia = autonomia + # self.autonomia = '100 kms' + + def chargeBattery(self, charging): + self.chargeBat = charging + if self.chargeBat: + return 'The battery is charging' + else: + return 'The battery is not charging' + + def propiedades(self): + super().propiedadesEstado() + print(f'Autonomia: {self.autonomia}') + # print(f'La autonomia es de: {self.autonomia}') + +electricCar2 = ElectricCars2('Volvo', 'C-40', '100 kms') +electricCar2.arrancar() +electricCar2.propiedades() + +print('-----Electric Bike 5-----') + +class ElectricBike5(ElectricCars2, Vehiculos): + + def cargaManual(self, cargando, porcentaje): + self.pedalear = cargando + self.porcentaje_carga = porcentaje + if self.pedalear == True and self.porcentaje_carga >= 0 and self.porcentaje_carga < 100: + return f'Bateria al {self.porcentaje_carga}% y cargando' + elif self.pedalear == True and self.porcentaje_carga == 100: + return f'Bateria al {self.porcentaje_carga}%. Carga completa' + elif self.pedalear == True and self.porcentaje_carga < 0 or self.porcentaje_carga > 100: + return f'Error de carga. Favor de llevar su bicicleta a su agencia' + elif self.pedalear == False and self.porcentaje_carga < 0 or self.porcentaje_carga > 100: + return f'Error de carga. Favor de llevar su bicicleta a su agencia' + else: + return f'Bateria descargandose. Resta {self.porcentaje_carga}%' + +miBike5 = ElectricBike5('Benotto', 'BT-7274', '65 kms') +miBike5.propiedades() +print(miBike5.cargaManual(True, 0)) +print(miBike5.cargaManual(True, 2)) +print(miBike5.cargaManual(True, 99)) +print(miBike5.cargaManual(True, 100)) +print(miBike5.cargaManual(True, 134)) +print(miBike5.cargaManual(False, 79)) +print(miBike5.cargaManual(False, 101)) +print(miBike5.cargaManual(False, -99)) \ No newline at end of file diff --git a/POO 6_Polimorfismo.py b/POO 6_Polimorfismo.py new file mode 100644 index 0000000..f02e4f4 --- /dev/null +++ b/POO 6_Polimorfismo.py @@ -0,0 +1,64 @@ +# Polimorfismo + +# El polimorfismo en la programacion se da cuando un objeto cambia de forma dependiendo del contexto en el que se utilice y por lo tanto al cambiar de forma, el objeto cambia de comportamiento + +# Si trasladamos este concepto del polimorfismo al ejemplo que hemos estado viendo en el tema del POO, quiere decir que los objetos vehiculos, ya sea coche, moto, camion etc pueden cambiar de forma, es decir pasar de ser un camion y ser una moto y de una moto pasar a ser un coche y por lo tanto ese objeto cambiaria su comportamiento + +class Moto(): + def num_ruedas(self): + print('Tiene 2 ruedas') + def cambio_velocidades(self): + print('El cambio se realiza con el pie izquierdo') + +class Coche(): + def num_ruedas(self): + print('Tiene 4 ruedas') + def cambio_velocidades(self): + print('El cambio se realiza con la mano') + +class Camion(): + def num_ruedas(self): + print('Tiene 8 ruedas') + def cambio_velocidades(self): + print('El cambio se realiza con la mano y los dedos') + +# Para hacer uso del polimorfimso creamos una funcion o un metodo el cual recibe un parametro y este parametro es el que se va encargar de almacenar el tipo de vehiculo u objeto que se esta creando para que asi tenga la forma y el comportamiento adecuado + +# OJO: No confundir las funciones o metodos generales con los metodos de las clases, los cuales son metodos pertenecientes unica y exclusivamente a estas + +def ruedas_vehiculos(numRuedas): # El parametro de esta funcion es el que se encarga de hacer la funcion del polimorfismo ya que almacenara el objeto que es generico, que puede ser de cualquier tipo o clase al momento de asignarlo a la funcion cuando la llamemos, pero antes este objeto ya va a estar definido con una clase a la que pertence para asi poder llamar a los metodos correspondientes + numRuedas.num_ruedas() + +def cambio_velocidades(cambioVelocidades): + cambioVelocidades.cambio_velocidades() + + +miVehiculo = Camion() +ruedas_vehiculos(miVehiculo) # Este parametro se almacena en el parametro de la funcion, y despues de esto evalua a donde pertence y es lo que llama o ejecuta +cambio_velocidades(miVehiculo) + +miVehiculo2 = Coche() +ruedas_vehiculos(miVehiculo2) +cambio_velocidades(miVehiculo2) + +miVehiculo3 = Moto() +ruedas_vehiculos(miVehiculo3) +cambio_velocidades(miVehiculo3) + +# Tal vez en los 3 ej anteriores no veamos con nitidez esto del polimorfismo, ya que estamos creando 3 objetos diferentes, pero a continuacion si que podemos ver la magia del polimorfismo ya que el ultimo objeto creado que es el vehiculo 3 que es una moto lo estamos cambiando a ser un camion y gracias al polimorfismo veemos que cambia su forma y su comportamiento sin problema alguno. Y como nos damos cuenta de esto? Bueno que al momento de cambiarlo, le estamos asignado que pertenezca a una clase diferente y esto hace que cambie su forma y comportamiento y lo comprobamos imprimiento los metodos ruedas y velocidades donde podemos ver que ahora arroja los resultados correspondientes al comportamiento y las propiedades de un camion tanto en el cambio de velocidades como en el numero de ruedas que tiene y es el mismo objeto 'miVehiculo3' + +miVehiculo3 = Camion() +ruedas_vehiculos(miVehiculo3) +cambio_velocidades(miVehiculo3) + +# Y esto mismo lo podemos hacer con los otros dos objetos para hacer un poco mas de enfasis al tema tratado que es el polimorfismo + +miVehiculo = Coche() +ruedas_vehiculos(miVehiculo) +cambio_velocidades(miVehiculo) + +miVehiculo2 = Moto() +ruedas_vehiculos(miVehiculo2) +cambio_velocidades(miVehiculo2) + +# Como podemos ver al principio el vehiculo 1 era un camion y despues paso a ser un coche, el vehiculo 2 era un coche y paso a ser una moto y el vehiculo 3 era una moto y paso a ser un camion. Esto es el polimorfismo, hacer que un mismo objeto cambie de forma y por ende su comportamiento \ No newline at end of file diff --git a/Paquete_Calculos_Potencia_y_Porcentaje.egg-info/PKG-INFO b/Paquete_Calculos_Potencia_y_Porcentaje.egg-info/PKG-INFO new file mode 100644 index 0000000..7a0b2a3 --- /dev/null +++ b/Paquete_Calculos_Potencia_y_Porcentaje.egg-info/PKG-INFO @@ -0,0 +1,12 @@ +Metadata-Version: 2.1 +Name: Paquete-Calculos-Potencia-y-Porcentaje +Version: 1.0 +Summary: Paquete para calcular la potencia y el porcentaje +Home-page: www.eh.com +Author: Eliab Hernandez +Author-email: moises_hl_zod@hotmail.com +License: UNKNOWN +Platform: UNKNOWN + +UNKNOWN + diff --git a/Paquete_Calculos_Potencia_y_Porcentaje.egg-info/SOURCES.txt b/Paquete_Calculos_Potencia_y_Porcentaje.egg-info/SOURCES.txt new file mode 100644 index 0000000..4483637 --- /dev/null +++ b/Paquete_Calculos_Potencia_y_Porcentaje.egg-info/SOURCES.txt @@ -0,0 +1,10 @@ +README.md +setup.py +Paquete_Calculos_Potencia_y_Porcentaje.egg-info/PKG-INFO +Paquete_Calculos_Potencia_y_Porcentaje.egg-info/SOURCES.txt +Paquete_Calculos_Potencia_y_Porcentaje.egg-info/dependency_links.txt +Paquete_Calculos_Potencia_y_Porcentaje.egg-info/top_level.txt +calculos/__init__.py +calculos/calculos_generales.py +calculos/potencia_porcentaje/__init__.py +calculos/potencia_porcentaje/potencia_porcentaje.py \ No newline at end of file diff --git a/Paquete_Calculos_Potencia_y_Porcentaje.egg-info/dependency_links.txt b/Paquete_Calculos_Potencia_y_Porcentaje.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Paquete_Calculos_Potencia_y_Porcentaje.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/Paquete_Calculos_Potencia_y_Porcentaje.egg-info/top_level.txt b/Paquete_Calculos_Potencia_y_Porcentaje.egg-info/top_level.txt new file mode 100644 index 0000000..ddcd7ae --- /dev/null +++ b/Paquete_Calculos_Potencia_y_Porcentaje.egg-info/top_level.txt @@ -0,0 +1 @@ +calculos diff --git a/Paquetes.py b/Paquetes.py new file mode 100644 index 0000000..9c54232 --- /dev/null +++ b/Paquetes.py @@ -0,0 +1,32 @@ +# Paquetes --> Son los directorios que almacenan los modulos relacionados entre si + +# Los paquetes sirven para organizar y reutilizar los modulos + +# Los paquetes se crean a partir de una carpeta la cual tiene que contener un archivo con el nombre __init__.py + +# Con esto podemos decir que estamos reutilizando codigo, ya que en ves de crear nuevamente el codigo, estamos reutilizando un modulo que ya lo contiene + +# Si vamos a hacer uso de subpaquetes lo unico que tenemos que hacer es anotar la ruta completa donde se encuentran estos subpaquetes seguido de igual manera que en los paquetes del nombre del modulo a importar + +# Eso de la ruta tambien se puede simplificar, sim embargo es algo que se vera mas adelante, de momento hay que tener en cuenta que hay que anotar la ruta completa!!! + +from calculos.calculos_generales import * # Paquete +from calculos.basicos.operaciones_basicas import * # Subpaquete +from calculos.potencia_porcentaje.potencia_porcentaje import * # Subpaquete + +suma(5,2) +multiplicacion(9,9) + +# Se pueden tener paquetes dentro de paquetes, o subpaquetes como se les podria conocer, estos de igual manera deben contener el archivo __init__.py + +# Hemos agregado subpaquetes al paquetes calculos, estos subpaquetes son las carpetas que tienen dentro de estas un archivo __init__.py, las cuales son basicos y potencia_porcentaje, asi como el modulo que utilizaremos para importar y estarlo reutilizando + +print('-----Paquete basicos-----') + +op_resta(10,7) +op_division(50,5) + +print('-----Paquete potencia_porcentaje-----') + +op_potencia(5,5) +op_porcentaje(100,15) \ No newline at end of file diff --git a/Paquetes_Distribuibles.py b/Paquetes_Distribuibles.py new file mode 100644 index 0000000..72b9d10 --- /dev/null +++ b/Paquetes_Distribuibles.py @@ -0,0 +1,32 @@ +# Paquetes distribuibles --> Los paquetes distribuibles son aquelos modulos que nosotros vamos a poder compartir mediante correo electronico o bien subiendolos a una plataforma que permita distribuir estos paquetes + +# Esto nos permite crear nuestros propios modulos o scripts, empaquetarlos y enviarlos a donde o a quien queramos + +""" Para hacer uso de paquetes distribuibles, es necesario dos pasos + + - Crear el paquete + Una vez creado el paquete y que este haya sido distribuido, haya donde se haya distribuido... + + - Instalar el paquete """ + +""" Pasos para la creacion de un paquete distribuible + + - Crear un archivo en la carpeta raiz con el nombre de 'setup.py'. Con respecto a la carpeta raiz supongo que habla en el caso del video, en la ruta donde el profe esta trabajando, pero este se puede crear en cualquier sitio + + Este archivo llamado setup va a contener una descripcion del paquete que vamos a distribuir. Descripcion que va contener nombre del paquete, version, autor etc... + + - Crear el archivo distribuible --> Irnos en la consola a la ruta/directorio donde se encuentra el archivo setup.py. Ya estando en la ruta lo que sigue es escribir 'python setup.py (nombre del archivo) sdist' para crear un paquete distribuible. Si todo a ido bien y lo hemos echo correctamente nos tiene que crear en la carpeta raiz dos carpetas, una que diga nombrePaquete.egg-info para este ej en particular y otra que diga dist que es la importante que es la carpeta de distribucion y esta debe de contener un paquete comprimido en formato .tar.gz. Este ultimo es el archivo distribuible, el que deberiamos de enviar por correo o subirlo a alguna plataforma de nube en la red para asi poder distribuirlo + + - Instalar el paquete --> Para instalar el paquete debemos en la consola ir a la ruta o directorio dist que es donde se encuentra el archivo empaquetado y a continuacion poner el siguiente comando 'pip3 install nombrePaquete' + + Que conseguimos con esto? Al instalar paquetes conseguimos que cualquier archivo con extension de python pueda hacer uso del modulo y de su contenido este donde este el archivo de python. El instalar paquetes es algo asi como instalar un programa en la pc, el cual vas a poder ocupar libremente, y esto es lo que sucede cuando importamos el modulo math de python, este modulo fue creado como un paquete distribuible y al momento de instalar python se instala este paquete para que cuando nosotros creemos nuestro codigo de nuestras aplicaciones o programas en python, lo hagamos donde lo hagamos en la ruta que lo hagamos este modulo math este disponible para su uso """ + +# Vamos a hacer una prueba de esto creando un archivo nuevo el cual hara uso de un modulo que no este instalado y posteriormente lo moveremos dentro de la carpeta Anotaciones y comentarios para verificar que el mismo modulo no sera posible ocuparlo ya que no lo encuentra y por lo tanto a la hora de ejecutar nos da error. Posterior a esto haremos lo mismo pero con otro archivo nuevo y utilizando el paquete que contiene los modulos instalados para que veamos que con este archivo nos permite hacer uso de los modulos tengamos el archivo donde lo tengamos aunque este lo estemos moviendo de ubicacion y su ruta cambie + +""" Desinstalacion de un paquete + + Para desinstalar un paquete lo unico que tenemos que hacer es abrir la consola o cmd (como administrador) y utilizar el siguiente comando 'pip3 unistall '. Para la desinstalacion no es necesario irnos hasta la ruta donde se encuentra el archivo ni a ninguna otra ruta en especifico, da igual, lo podemos hacer desde cualquier ruta. Yo no lo voy a hacer hasta posiblemente despues para tener disponible la diferencia entre el archivo que utiliza el paquete instalado y el que ocupa uno NO instalado """ + +# NOTA IMPORTANTE: PROCURAR PONERLE NOMBRES FACILES DE RECORDAR A LOS PAQUETES DISTRIBUIBLES, YA QUE AL MOMENTO DE DESINSTALARLOS NECESITAREMOS HACER USO DE ESTE NOMBRE Y SI NO NOS ACORDAMOS DEL NOMBRE NO PODREMOS DESINSTALARLO Y PODRIA SER BASTANTE FRUSTANTE ESTAR TRATANDO DE ACORDARNOS DEL NOMBRE QUE LE PUSIMOS + +# Nombre del paquete creado para el ejercicio 'Paquete Calculos - Potencia y Porcentaje' \ No newline at end of file diff --git a/Programa Controlador DataBase/Imagenes_cbd/eclog.jpg b/Programa Controlador DataBase/Imagenes_cbd/eclog.jpg new file mode 100644 index 0000000..29c4c6c Binary files /dev/null and b/Programa Controlador DataBase/Imagenes_cbd/eclog.jpg differ diff --git a/Programa Controlador DataBase/Imagenes_cbd/error iconbitmap 1.JPG b/Programa Controlador DataBase/Imagenes_cbd/error iconbitmap 1.JPG new file mode 100644 index 0000000..d4f31d7 Binary files /dev/null and b/Programa Controlador DataBase/Imagenes_cbd/error iconbitmap 1.JPG differ diff --git a/Programa Controlador DataBase/Imagenes_cbd/error iconbitmap 2.JPG b/Programa Controlador DataBase/Imagenes_cbd/error iconbitmap 2.JPG new file mode 100644 index 0000000..341fb20 Binary files /dev/null and b/Programa Controlador DataBase/Imagenes_cbd/error iconbitmap 2.JPG differ diff --git a/Programa Controlador DataBase/main.py b/Programa Controlador DataBase/main.py new file mode 100644 index 0000000..f6f34c7 --- /dev/null +++ b/Programa Controlador DataBase/main.py @@ -0,0 +1,432 @@ +# CONTROLADOR DE BASE DE DATOS + +# INTERFAZ GRAFICA + +import sqlite3 +from tkinter import * +from tkinter import messagebox +from tkinter.scrolledtext import ScrolledText # Libreria para importar cuadros de texto pero con la barra de desplazamiento integrada dentro del mismo cuadro de texto y configurada para que trabaje de forma normal y adecuada, como conoces que trabajan estas barras de desplazamiento + +root = Tk() +root.title('DATABASE CONTROLLER') +root.resizable(0,0) + +# ----------- Imagen ico a mostrar en Windows ---------- + +root.iconbitmap('Imagenes/eclog2.ico') + +# ---------- Variables contenedoras de la informacion proporcionada por el cliente en los campos de la entrada de datos ---------- + +id_cliente = StringVar() +nombre_cliente = StringVar() +apellido_cliente = StringVar() +telefono_cliente = StringVar() +email_cliente = StringVar() +empresa_cliente = StringVar() + +# ------------ Funciones menu ------------- + +def crearBaseDatos(): + + establecer_conexion = sqlite3.connect('Clientes') + + puntero = establecer_conexion.cursor() + + # Yo habia puesto la conexion a la base de datos y el puntero dentro del try, pero no es necesario ya que el error se generaria al querer crear la base de datos si esta ya existe, pero la conexion y la creacion del puntero no dan error alguno, al contrario, se necesitan hacer para poder trabajar con la base de datos, por lo tanto no es necesario que esten dentro del try y pueden quedar fuera sin problema alguno + + try: + puntero.execute(''' + CREATE TABLE CLIENTES ( + ID INTEGER PRIMARY KEY AUTOINCREMENT, + NOMBRE VARCHAR(20), + APELLIDOS VARCHAR(30), + TELEFONO VARCHAR(15) UNIQUE, + EMAIL VARCHAR(50) UNIQUE, + EMPRESA VARCHAR(30), + COMENTARIOS VARCHAR(100)) + ''') + + messagebox.showinfo('Base de Datos', 'Base de Datos creada con éxito') + + except: # sqlite3.OperationalError --> Yo habia puesto el error que generaba la creacion de la base de datos si esta ya existia, pero no es necesario ya que el except se estaria ejecutando si o si tenga declarado o no el error, siempre y cuando el try no se cumpla o se ejecute + messagebox.showwarning('Advertencia', 'La Base de Datos "Clientes" ya existe') + + establecer_conexion.close() + +def salir(): + exit = messagebox.askquestion('Salir', '¿Desea salir del programa?') + + if exit == 'yes': + root.destroy() + +def crearRegistro(): + + resultado_bd_texto.delete('1.0', END) + + establecer_conexion = sqlite3.connect('Clientes') + + puntero = establecer_conexion.cursor() + + # ------- Registros agregados mediante concatenacion de la instruccion SQL a los valores de la base de datos + + # puntero.execute("INSERT INTO CLIENTES VALUES(NULL, '" + nombre_cliente.get() + + # "','" + apellido_cliente.get() + + # "','" + telefono_cliente.get() + + # "','" + email_cliente.get() + + # "','" + empresa_cliente.get() + + # "','" + info_adicional.get("1.0", END) + "')") + + # -------- Registros agregados mediante la creacion de una lista, la cual nos permite eliminar la concatenacion del ejemplo anterior + + # clientes = [ + # nombre_cliente.get(), + # apellido_cliente.get(), + # telefono_cliente.get(), + # email_cliente.get(), + # empresa_cliente.get(), + # info_adicional.get('1.0', END) + # ] + + # puntero.execute('''INSERT INTO CLIENTES VALUES (NULL,?,?,?,?,?,?)''', clientes) + + # CONSULTAS PARAMETRIZADAS + + # Las consultas parametrizadas son las que en lugar de criterios utilizan interrogantes y estas las podemos utilizar en instrucciones SQL de tipo insert y update. Con estas nos evitamos el el engorroso codigo de ir concatenando la instruccion sql con los criterios + + # Para hacer uso de las consultas parametrizadas necesitamos almacenar en una variable la informacion de los campos que estarian conformando la instruccion sql y que seran relacionados con los interrogantes + + # Es muy similar a hacerlo mediante una lista, sin embargo esto solo es para la creacion de registros, pero para el update es mejor y mas sencillo, ya que para el update la creacion de una lista y actualizar mediante esta lista es mas lioso + + datos_clientes = nombre_cliente.get(), apellido_cliente.get(), telefono_cliente.get(), email_cliente.get(), empresa_cliente.get(), info_adicional.get('1.0', END) + + puntero.execute("""INSERT INTO CLIENTES VALUES (NULL,?,?,?,?,?,?)""", (datos_clientes)) + + establecer_conexion.commit() + + establecer_conexion.close() + + resultado_bd_texto.insert(END, f'Se agrego el siguiente cliente\n{nombre_cliente.get()} | {apellido_cliente.get()} | {telefono_cliente.get()} | {email_cliente.get()}') + + messagebox.showinfo('Base de Datos', 'Registro insertado con éxito') + + id_cliente.set('') + nombre_cliente.set('') + apellido_cliente.set('') + telefono_cliente.set('') + email_cliente.set('') + empresa_cliente.set('') + info_adicional.delete('1.0', END) + +def mostrarRegistro(): + + name = f"'{nombre_cliente.get()}'" + + establecer_conexion = sqlite3.connect('Clientes') + + puntero = establecer_conexion.cursor() + + puntero.execute(""" SELECT * FROM CLIENTES WHERE NOMBRE = """ + name) + + usuario = puntero.fetchall() + + for i in usuario: + + info_adicional.delete('1.0', END) + id_cliente.set(i[0]) + nombre_cliente.set(i[1]) + apellido_cliente.set(i[2]) + telefono_cliente.set(i[3]) + email_cliente.set(i[4]) + empresa_cliente.set(i[5]) + info_adicional.insert(1.0, i[6]) + + establecer_conexion.commit() + + resultado_bd_texto.delete('1.0', END) + + resultado_bd_texto.insert(END, f'Cliente:\n{id_cliente.get()} - {nombre_cliente.get()} - {apellido_cliente.get()} - {telefono_cliente.get()} - {email_cliente.get()} - {empresa_cliente.get()}') + + if len(usuario) > 1: + messagebox.showinfo('Clientes', f'Tiene 2 o mas clientes con el nombre de "{name}"\n\n {usuario}') + +def borrarRegistro(): + + resultado_bd_texto.delete('1.0', END) + + establecer_conexion = sqlite3.connect('Clientes') + + puntero = establecer_conexion.cursor() + + puntero.execute(""" DELETE FROM CLIENTES WHERE ID = """ + id_cliente.get()) + + establecer_conexion.commit() + + messagebox.showinfo('Base de Datos', 'Registro borrado con éxito') + + resultado_bd_texto.insert(END, f'Se elimino el registro asociado al ID: {id_cliente.get()}') + + id_cliente.set('') + nombre_cliente.set('') + apellido_cliente.set('') + telefono_cliente.set('') + email_cliente.set('') + empresa_cliente.set('') + info_adicional.delete('1.0', END) + +def actualizarRegistro(): + + resultado_bd_texto.delete('1.0', END) + + establecer_conexion = sqlite3.connect('Clientes') + + puntero = establecer_conexion.cursor() + + # puntero.execute("UPDATE CLIENTES SET NOMBRE = '" + nombre_cliente.get() + + # "', APELLIDOS ='" + apellido_cliente.get() + + # "', TELEFONO ='" + telefono_cliente.get() + + # "', EMAIL ='" + email_cliente.get() + + # "', EMPRESA ='" + empresa_cliente.get() + + # "', COMENTARIOS ='" + info_adicional.get("1.0", END) + + # "'WHERE ID = " + id_cliente.get()) + + # ------ Actualizacion de un registro mediante consulta parametrizada + + datos_clientes = nombre_cliente.get(), apellido_cliente.get(), telefono_cliente.get(), email_cliente.get(), empresa_cliente.get(), info_adicional.get('1.0', END) + + puntero.execute('''UPDATE CLIENTES SET NOMBRE=?, APELLIDOS=?, TELEFONO=?, EMAIL=?, EMPRESA=?, COMENTARIOS=? WHERE ID = ''' + id_cliente.get(),(datos_clientes)) + + establecer_conexion.commit() + + establecer_conexion.close() + + resultado_bd_texto.insert(END, f'Se actualizo el cliente\n\nDatos nuevos:\n{id_cliente.get()} | {nombre_cliente.get()} | {apellido_cliente.get()} | {telefono_cliente.get()} | {email_cliente.get()}') + + messagebox.showinfo('Base de Datos', 'Registro actualizado con éxito') + + id_cliente.set('') + nombre_cliente.set('') + apellido_cliente.set('') + telefono_cliente.set('') + email_cliente.set('') + empresa_cliente.set('') + info_adicional.delete('1.0', END) + +def borrarCampos(): + id_cliente.set('') + nombre_cliente.set('') + apellido_cliente.set('') + telefono_cliente.set('') + email_cliente.set('') + empresa_cliente.set('') + # Para borrar el texto de un Text() se hace de la siguiente manera: Variable asignada al Text(), (cuadro de texto) mas la funcion delete() usando la nomenclatura del punto + info_adicional.delete('1.0', END) # Con el delete borramos la informacion del cuadro de texto y con los parametros entre parentesis (1.0 y END) le estamos diciendo que borre desde el primer caracter hasta el final del texto + +def resaltarCampos(): + id_entry.config(bg='#92D6FF') + nombre_entry.config(bg='#92D6FF') + apellido_entry.config(bg='#92D6FF') + telefono_entry.config(bg='#92D6FF') + email_entry.config(bg='#92D6FF') + +def ayudaUsuario(): + messagebox.showinfo('Ayuda', 'El Controlador de Base de Datos - DBC es un programa sencillo y facil de usar al igual que muy útil, eficiente y bastante potente para su propósito.\n\nEn el menú superior encontraras 5 pestañas: BBDD, Campos, Acciones y Ayuda.\n\n< BBDD >\n Conectar: Crea y conecta con una Base de Datos nueva denomida "Clientes"\n Salir: Cierra la aplicación.\n\n< CAMPOS >\n Borrar campos: Borra la información ingresada en los campos.\n Campos obligatorios: Resalta los campos que son obligatorios para su llenado.\n\n< ACCIONES >\n Crear registro: Crea un registro nuevo.\n Mostrar registro: Muestra en los campos un registro existente en la Base de Datos.\n Borrar registro: Borra un registro ya existente en la Base de Datos.\n Actualizar registro: Actuliza la información y/o datos de un registro existente.\n\n< AYUDA >\n Ayuda: Despliega una ventana con la ayuda referente al uso del programa DBC.\n Licencia: Muestra el tipo de Licencia de DBC.\n Acerca de: Informa del propósito, ventajas y forma en la que se rige DBC.') + +def licencia(): + messagebox.showinfo('Licencia', 'Licencia GNU\n\nSoftware libre y de codigo abierto, registrado bajo el usuario que lo instala y registra') + +def acercaDe(): + messagebox.showinfo('Acerca de DBC','Creador DBC: Moises Eliab Hernandez Lopez\n\nProgramado y escrito en: Python 3.10.1\n\nVersion: v1.0\n\nEl programa Controlador de Base de Datos - DBC tiene como finalidad brindar al usuario una forma rapida y sencila de crear base de datos sencilas pero útiles que le permitan controlar y organizar los clientes que tiene registrados en su empresa o corporación.\n\nTeniendo como principios el software libre, con el propósito de que este al alcance de cualquiera, sin la necesidad de un gasto monetario. Este se sostiene de apoyos y donaciones.\n\nSi te interesa colaborar con el proyecto de forma economica para continuar con su desarrollo y mejora, puedes hacerlo poniendote en contacto al número telefónico 55-5555-5555, o bien donando a nuestra cuenta de PayPal') + +def mostrarBaseDatos(): + + resultado_bd_texto.delete('1.0', END) + + resultado_bd_texto.insert('1.0', 'ID | NOMBRE | APELLIDO | TELEFONO | EMAIL | EMPRESA\n\n') + + establecer_conexion = sqlite3.connect('Clientes') + + puntero = establecer_conexion.cursor() + + puntero.execute('SELECT * FROM CLIENTES') + + extraer_Bd = puntero.fetchall() + + + for c in extraer_Bd: + clientes = c + id_db, nombre_db, apellido_db, telefono_db, email_db, empresa_db, comentario_db = clientes + # resultado_bd_texto.insert('1.0', f'{clientes[0:6]}\n') + resultado_bd_texto.insert(END, f'{id_db}, {nombre_db}, {apellido_db}, {telefono_db}, {email_db}, {empresa_db}\n') + +# ----------- Menu principal ------------ + +main_menu = Menu(root, relief='flat', bg='#333333', fg='#85C1E9') +root.config(menu=main_menu) +root.config(bg='#333333') + +# ------------ Contenido botones menu ------------- + +bbdd = Menu(main_menu, tearoff=0) +bbdd.add_command(label='Conectar', command=crearBaseDatos) +bbdd.add_separator() +bbdd.add_command(label='Salir', command=salir) + +acciones = Menu(main_menu, tearoff=0) +acciones.add_command(label='Crear registro', command=crearRegistro) +acciones.add_command(label='Mostrar registro', command=mostrarRegistro) +acciones.add_command(label='Borrar registro', command=borrarRegistro) +acciones.add_command(label='Actualizar BBDD', command=actualizarRegistro) + +campos = Menu(main_menu, tearoff=0) +campos.add_command(label='Borrar campos', command=borrarCampos) +campos.add_command(label='Campos Obligatorios', command=resaltarCampos) + +ayuda = Menu(main_menu, tearoff=0) +ayuda.add_command(label='Ayuda', command=ayudaUsuario) +ayuda.add_separator() +ayuda.add_command(label='Licencia', command=licencia) +ayuda.add_command(label='Acerca de', command=acercaDe) + +main_menu.add_cascade(label='BBDD', menu=bbdd) +main_menu.add_cascade(label='Acciones', menu=acciones) +main_menu.add_cascade(label='Campos', menu=campos) +main_menu.add_cascade(label='Ayuda', menu=ayuda) +# main_menu.config(bg='#333333', fg='#85C1E9') + +# ----------- Frame principal ----------- + +main_frame = Frame(root) +main_frame.pack() +main_frame.config(bg='#333333') + +# ---------- Entrada de Datos ------------- + +id_label = Label(main_frame, text='ID Cliente', bg='#333333', fg='#DCDCDC') +id_label.grid(row=1, column=1, padx=10, pady=2, sticky='w') + +id_entry = Entry(main_frame, textvariable=id_cliente) +id_entry.grid(row=2, column=1, padx=20, pady=2) +id_entry.config(justify='center') + +nombre_label = Label(main_frame, text='Nombre(s)', bg='#333333', fg='#DCDCDC') +nombre_label.grid(row=1, column=2, padx=10, pady=2, sticky='w') + +nombre_entry = Entry(main_frame, textvariable=nombre_cliente, ) +nombre_entry.grid(row=2, column=2, padx=20, pady=2) +nombre_entry.config(justify='center') + +apellido_label = Label(main_frame, text='Apellidos', bg='#333333', fg='#DCDCDC') +apellido_label.grid(row=1, column=3, padx=10, pady=2, sticky='w') + +apellido_entry = Entry(main_frame, textvariable=apellido_cliente) +apellido_entry.grid(row=2, column=3, padx=20, pady=2) +apellido_entry.config(justify='center') + +telefono_label = Label(main_frame, text='Teléfono', bg='#333333', fg='#DCDCDC') +telefono_label.grid(row=3, column=1, padx=10, pady=2, sticky='w') + +telefono_entry = Entry(main_frame, textvariable=telefono_cliente) +telefono_entry.grid(row=4, column=1, padx=20, pady=2) +telefono_entry.config(justify='center') + +email_label = Label(main_frame, text='Email', bg='#333333', fg='#DCDCDC') +email_label.grid(row=3, column=2, padx=10, pady=2, sticky='w') + +email_entry = Entry(main_frame, textvariable=email_cliente) +email_entry.grid(row=4, column=2, padx=20, pady=2) +email_entry.config(justify='center') + +empresa_label = Label(main_frame, text='Empresa', bg='#333333', fg='#DCDCDC') +empresa_label.grid(row=3, column=3, padx=10, pady=2, sticky='w') + +empresa_entry = Entry(main_frame, textvariable=empresa_cliente) +empresa_entry.grid(row=4, column=3, padx=20, pady=2) +empresa_entry.config(justify='center') + +comentarios_label = Label(main_frame, text='Información Adicional', bg='#333333', fg='#DCDCDC') +comentarios_label.grid(row=1, column=4, padx=10, pady=2, sticky='nswe') + +#info_adicional = Text(main_frame, width=15, height=5, font=('Z003', 10)) +info_adicional = ScrolledText(main_frame, width=15, height=4, font=('Z003', 10)) # Cuadro de texto con barra de desplazamiento integrada +info_adicional.grid(row=2, rowspan=4, column=4, padx=10, pady=5) + +# barra_desp = Scrollbar(main_frame, command=info_adicional.yview) +# barra_desp.grid(row=7, column=3, sticky='ns', pady=10) + +# info_adicional.config(yscrollcommand=barra_desp.set) + +# --------- Frame contenedor botones ----------- + +frame_botones = Frame(root, width=320, height=40, bg='#333333', pady=6) +frame_botones.pack() + +# --------- Botones inferiores ------------ + +# campos_botones = Label(frame_botones, text='Campos Formulario', bg='#333333', fg='#DCDCDC', font=('Z003', 12)) +# campos_botones.grid(row=1, column=1, columnspan=4, padx=2, pady=5) + +# borrar_campos = Button(frame_botones, text='Resetear campos', bg='#333333', highlightthickness=0, fg='#F9F850', padx=8, pady=2, command=borrarCampos) +# borrar_campos.grid(row=2, column=1, columnspan=2, padx=2, pady=5) + +# campos_obligatorios = Button(frame_botones, text='Campos obligatorios', bg='#333333', highlightthickness=0, fg='#F9F850', padx=8, pady=2, command=resaltarCampos) +# campos_obligatorios.grid(row=2, column=3, columnspan=2, padx=2, pady=5) + +# registros_botones = Label(frame_botones, text='Registros', bg='#333333', fg='#DCDCDC', font=('Z003', 12)) +# registros_botones.grid(row=3, column=1, columnspan=4, padx=2, pady=5) + +# crear_registro = Button(frame_botones, text='Crear', bg='#333333', highlightthickness=0, fg='#85C1E9', padx=8, pady=2, command=crearRegistro) +# crear_registro.grid(row=4, column=1, padx=2) + +# mostar_registro = Button(frame_botones, text='Mostrar', bg='#333333', highlightthickness=0, fg='#85C1E9', padx=8, pady=2) +# mostar_registro.grid(row=4, column=2, padx=2) + +# borrar_registro = Button(frame_botones, text='Borrar', bg='#333333', highlightthickness=0, fg='#F7441D', padx=8, pady=2) +# borrar_registro.grid(row=4, column=3, padx=2) + +# update_BBDD = Button(frame_botones, text='Actualizar', bg='#333333', highlightthickness=0, fg='#2AEE4D', padx=8, pady=2) +# update_BBDD.grid(row=4, column=4, padx=2) + +registros_botones = Label(frame_botones, text='REGISTROS', bg='#333333', fg='#DCDCDC', font=('Z003', 10), width=20) +registros_botones.grid(row=1, column=1, columnspan=4, padx=2, pady=10, sticky='nswe') + +crear_registro = Button(frame_botones, text='Crear', bg='#333333', highlightthickness=0, fg='#85C1E9', padx=8, pady=2, width=10, command=crearRegistro) +crear_registro.grid(row=2, column=1, padx=2) + +mostar_registro = Button(frame_botones, text='Mostrar', bg='#333333', highlightthickness=0, fg='#85C1E9', padx=8, pady=2, width=10, command=mostrarRegistro) +mostar_registro.grid(row=2, column=2, padx=2) + +borrar_registro = Button(frame_botones, text='Borrar', bg='#333333', highlightthickness=0, fg='#F7441D', padx=8, pady=2, width=10, command=borrarRegistro) +borrar_registro.grid(row=2, column=3, padx=2) + +update_BBDD = Button(frame_botones, text='Actualizar', bg='#333333', highlightthickness=0, fg='#2AEE4D', padx=8, pady=2, width=10, command=actualizarRegistro) +update_BBDD.grid(row=2, column=4, padx=2) + +separador_botones = Label(frame_botones, text='', bg='#333333', highlightthickness=0, fg='#DCDCDC', padx=8, pady=2, width=2) +separador_botones.grid(row=2, column=5, padx=2) + +campos_botones = Label(frame_botones, text='CAMPOS', bg='#333333', fg='#DCDCDC', font=('Z003', 10), width=20) +campos_botones.grid(row=1, column=6, columnspan=7, padx=2, pady=10, sticky='nswe') + +borrar_campos = Button(frame_botones, text='Resetear', bg='#333333', highlightthickness=0, fg='#F9F850', padx=8, pady=2, width=10, command=borrarCampos) +borrar_campos.grid(row=2, column=6, padx=2, pady=5) + +campos_obligatorios = Button(frame_botones, text='Resaltar C/O', bg='#333333', highlightthickness=0, fg='#F9F850', padx=8, pady=2, width=10, command=resaltarCampos) +campos_obligatorios.grid(row=2, column=7, padx=2, pady=5) + +# --------- Frame contenedor interaccion Base de Datos ----------- + +frame_bd = Frame(root, width=200, height=100, bg='#333333', pady=6) +frame_bd.pack() + +base_datos = Label(frame_bd, text='BASE DE DATOS', bg='#333333', fg='#DCDCDC', font=('Z003', 15)) +base_datos.grid(row=1, column=3, padx=10, pady=10, sticky='nswe') + +resultado_bd_texto = Text(frame_bd, bg='#222222', fg='#F7441D', width=90, height=13, font=('Z003', 10)) +resultado_bd_texto.grid(row=2, rowspan=5, column=3, padx=15, pady=10) +resultado_bd_texto.insert('1.0', 'ID | NOMBRE | APELLIDO | TELEFONO | EMAIL | EMPRESA') +# resultado_bd_texto.index(END) + +base_de_datos = Button(frame_bd, text='Mostar Base de Datos', bg='#333333', fg='#DCDCDC', font=('Z003', 10), width=30, command=mostrarBaseDatos) +base_de_datos.grid(row=7, column=3, padx=5, pady=5) + +main_frame.mainloop() \ No newline at end of file diff --git a/Referencias/Referencia_Ejercicio1.jpg b/Referencias/Referencia_Ejercicio1.jpg new file mode 100644 index 0000000..d27838c Binary files /dev/null and b/Referencias/Referencia_Ejercicio1.jpg differ diff --git a/Referencias/Referencia_Ejercicio2.jpg b/Referencias/Referencia_Ejercicio2.jpg new file mode 100644 index 0000000..e3a8dc6 Binary files /dev/null and b/Referencias/Referencia_Ejercicio2.jpg differ diff --git a/Referencias/Referencia_Ejercicio3.jpg b/Referencias/Referencia_Ejercicio3.jpg new file mode 100644 index 0000000..16a6b63 Binary files /dev/null and b/Referencias/Referencia_Ejercicio3.jpg differ diff --git a/Referencias/Referencia_Ejercicio4.jpg b/Referencias/Referencia_Ejercicio4.jpg new file mode 100644 index 0000000..ffd8100 Binary files /dev/null and b/Referencias/Referencia_Ejercicio4.jpg differ diff --git a/Referencias/Solucion_Grafica_Desglosada_Ejercicio2.jpg b/Referencias/Solucion_Grafica_Desglosada_Ejercicio2.jpg new file mode 100644 index 0000000..1321f81 Binary files /dev/null and b/Referencias/Solucion_Grafica_Desglosada_Ejercicio2.jpg differ diff --git a/Salidas.py b/Salidas.py new file mode 100644 index 0000000..3efd0fa --- /dev/null +++ b/Salidas.py @@ -0,0 +1,22 @@ +# Salidas + +# Hay varias formas de poder imprimir en consola la salida de datos, si bien se tiene que hacer mediante el print(), la forma de ponerlo en este es variada, es decir que hay varias maneras en que podemos concatenar mensajes con variables + +# Lo que se va a ver realmente en este tema, son las diferentes formas de concatenar variables en un mensaje al momento de imprimirlos en consola + +nombre = "Moises" +edad = 31 + +print("Hola",nombre, "tienes", edad, "años") # Esta es una forma, sin embargo no es la unica, ademas de ser algo engrollosa y corremos el riesgo de que nos falte alguna coma, comillas, mala sintaxis etc + +print("-------------------") + +# La otra forma es la llamada format() + +print("Hola {} tienes {} años".format(nombre,edad)) + +print("-------------------") + +# La otra forma es de igual manera con el metodo format, pero en su version abreviada (f al inicio del todo) + +print(f"Hola {nombre} tienes {edad} años") \ No newline at end of file diff --git a/Serializacion.py b/Serializacion.py new file mode 100644 index 0000000..3a4d763 --- /dev/null +++ b/Serializacion.py @@ -0,0 +1,97 @@ +# Serialización de colecciones, objetos + +# Serializacion --> Consiste en un guardar un fiche externo una coleccion, un diccionario e incluso un objeto. Pero la particularidad de la serializacion es que vamos a guardarlo en un fichero externo codificado en codigo binario + +# El objetivo de guardar un fichero en este formato puede ser diversa. Por ej si queremos distribuir un objeto que hemos construido en python por internet, viene muy bien que este objeto este codificado en codigo binario ya que la distribucion se hace mas facil, asi como cuando queremos guardarlo en un dispositivo de almacenamiento externo o bien cuando queremos guardar un objeto, coleccion o diccionario en una base de datos + +""" Para llevar a cabo este proceso de serializacion es necesario hacer uso de una biblioteca de Python, la cual es la biblioteca Pickle. Esta biblioteca tiene toda una coleccion de metodos, de los cuales destacan 2 que son los que vamos a ocupar en este tema + + Estos 2 metodos son los siguientes: + + - dump(): Nos permite hacer un volcado de datos al fichero binario externo + + - load(): Nos permite cargar los datos del fichero binario externo """ + +# Serializacion de colecciones + +import pickle + +lista_nombres = ['Pedro', 'Ana', 'Maria', 'Isabel'] + +fichero_listaBinaria = open('lista_nombres', 'wb') # Creando el fichero binario + +pickle.dump(lista_nombres, fichero_listaBinaria) # Volcando el fichero binario + +fichero_listaBinaria.close() + +del(fichero_listaBinaria) # Aqui lo que estamos haciendo es borrarlo de la memoria virtual pero no estamos borrando el archivo fisico que se creo + +ficheroBinario = open('lista_nombres', 'rb') # Abriendo el fichero binario en modo lectura + +lista_1 = pickle.load(ficheroBinario) # Cargando y guardando el fichero binario en una variable mediante el metodo load() de la biblioteca pickle + +print(lista_1) + +# Serializacion de objetos + +class Vehiculos(): + def __init__(self, marca, modelo): + self.marca = marca + self.modelo = modelo + self.encendido = False + self.acelerar = False + self.frenar = False + + def arrancar(self): + self.encendido = True + + def acelerando(self): + self.acelerar = True + + def frenando(self): + self.frenar = True + + def propiedadesEstado(self): + print(f'Marca: {self.marca} \nModelo: {self.modelo} \nPrendida: {self.encendido} \nAcelerando: {self.acelerar} \nFrenando: {self.frenar}') + +coche1 = Vehiculos('Chrysler', 'Stratus RT') +coche2 = Vehiculos('Chevrolet', 'Cavalier') +coche3 = Vehiculos('Chevrolet', 'Chevy Nova') + +coches = [coche1, coche2, coche3] + +fichero_Coches = open('Mis_Coches', 'wb') + +pickle.dump(coches, fichero_Coches) + +fichero_Coches.close() + +del(fichero_Coches) + +# Recuperacion de archivo binario Mis_Coches + +ficheroCoches = open('Mis_Coches', 'rb') + +misCoches = pickle.load(ficheroCoches) + +ficheroCoches.close() + +for c in misCoches: + c.propiedadesEstado() + print('') + +""" En este archivo estamos generando tanto la creación como la apertura del archivo y es por eso mismo que no tenemos ningun error al momento de ejecutar el programa. Pero que pasa si queremos abrir el fichero binario desde otro archivo? Bueno lo logico dicta que en el nuevo archivo pongamos los siguiente: + + import pickle + + ficheroCoches = open('Mis_Coches', 'rb') + + misCoches = pickle.load(ficheroCoches) + + ficheroCoches.close() + + for c in misCoches: + c.propiedadesEstado() + print('') + +Pero esto nos daria un error, el cual seria que no encuentra Vehiculos() y esto se debe a que al momento de generar la apertura del archivo, los objetos son de tipo Vehiculo, pero tanto la clase Vehiculo como el metodo propiedadesEstado no estan definidos en el nuevo archivo, y como el nuevo archivo no tiene relacion ninguna con el archivo donde se creo el fichero binario no tiene ni idea de que es Vehiculos(), ni tampoco lo que es propiedadesEstado(), asi que nos estaria arrojando un error. Esto se soluciona de una forma rapida y practica y es poner el codigo de la clase Vehiculos en el nuevo archivo, asi cuando se haga la apertura este archivo va a tener Vehiculos() y propiedadesEstado() por lo que el archivo ahora si sabra que son esos dos a los que hacen referencias los objetos del fichero binario y podra ejecutarse el programa sin problema o error alguno """ \ No newline at end of file diff --git a/__pycache__/modulo_funcionesMatematicas.cpython-310.pyc b/__pycache__/modulo_funcionesMatematicas.cpython-310.pyc new file mode 100644 index 0000000..edb980c Binary files /dev/null and b/__pycache__/modulo_funcionesMatematicas.cpython-310.pyc differ diff --git a/__pycache__/modulo_funcionesMatematicas.cpython-39.pyc b/__pycache__/modulo_funcionesMatematicas.cpython-39.pyc new file mode 100644 index 0000000..a043c70 Binary files /dev/null and b/__pycache__/modulo_funcionesMatematicas.cpython-39.pyc differ diff --git a/__pycache__/modulo_vehiculos.cpython-310.pyc b/__pycache__/modulo_vehiculos.cpython-310.pyc new file mode 100644 index 0000000..9a99419 Binary files /dev/null and b/__pycache__/modulo_vehiculos.cpython-310.pyc differ diff --git a/__pycache__/modulo_vehiculos.cpython-39.pyc b/__pycache__/modulo_vehiculos.cpython-39.pyc new file mode 100644 index 0000000..a3ab9d2 Binary files /dev/null and b/__pycache__/modulo_vehiculos.cpython-39.pyc differ diff --git a/archivo_texto.txt b/archivo_texto.txt new file mode 100644 index 0000000..65d8f64 --- /dev/null +++ b/archivo_texto.txt @@ -0,0 +1,3 @@ +Inicio del textoa ventana... +Dandose un llegue de aire fresco +Le encanta estar asomada y sacar la cabeza \ No newline at end of file diff --git a/calculos/__init__.py b/calculos/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/calculos/__pycache__/__init__.cpython-310.pyc b/calculos/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..e466ad7 Binary files /dev/null and b/calculos/__pycache__/__init__.cpython-310.pyc differ diff --git a/calculos/__pycache__/__init__.cpython-38.pyc b/calculos/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..2ec1540 Binary files /dev/null and b/calculos/__pycache__/__init__.cpython-38.pyc differ diff --git a/calculos/__pycache__/__init__.cpython-39.pyc b/calculos/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..c7223d2 Binary files /dev/null and b/calculos/__pycache__/__init__.cpython-39.pyc differ diff --git a/calculos/__pycache__/calculos_generales.cpython-310.pyc b/calculos/__pycache__/calculos_generales.cpython-310.pyc new file mode 100644 index 0000000..cd9ba2a Binary files /dev/null and b/calculos/__pycache__/calculos_generales.cpython-310.pyc differ diff --git a/calculos/basicos/__init__.py b/calculos/basicos/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/calculos/basicos/__pycache__/__init__.cpython-310.pyc b/calculos/basicos/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..fa75899 Binary files /dev/null and b/calculos/basicos/__pycache__/__init__.cpython-310.pyc differ diff --git a/calculos/basicos/__pycache__/__init__.cpython-38.pyc b/calculos/basicos/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..709fa49 Binary files /dev/null and b/calculos/basicos/__pycache__/__init__.cpython-38.pyc differ diff --git a/calculos/basicos/__pycache__/__init__.cpython-39.pyc b/calculos/basicos/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..d933ff0 Binary files /dev/null and b/calculos/basicos/__pycache__/__init__.cpython-39.pyc differ diff --git a/calculos/basicos/__pycache__/operaciones_basicas.cpython-310.pyc b/calculos/basicos/__pycache__/operaciones_basicas.cpython-310.pyc new file mode 100644 index 0000000..4aac9ae Binary files /dev/null and b/calculos/basicos/__pycache__/operaciones_basicas.cpython-310.pyc differ diff --git a/calculos/basicos/operaciones_basicas.py b/calculos/basicos/operaciones_basicas.py new file mode 100644 index 0000000..15c9222 --- /dev/null +++ b/calculos/basicos/operaciones_basicas.py @@ -0,0 +1,11 @@ +def op_suma(num1, num2): + print(f'El resultado de la suma es: {num1 + num2}') + +def op_resta(num1, num2): + print(f'El resultado de la resta es: {num1 - num2}') + +def op_multiplicacion(num1, num2): + print(f'El resultado de la multiplicacion es: {num1 * num2}') + +def op_division(num1, num2): + print(f'El resultado de la division es: {num1 / num2}') \ No newline at end of file diff --git a/calculos/calculos_generales.py b/calculos/calculos_generales.py new file mode 100644 index 0000000..b9df172 --- /dev/null +++ b/calculos/calculos_generales.py @@ -0,0 +1,22 @@ +def suma(num1, num2): + print(f'El resultado de la suma es: {num1 + num2}') + +def resta(num1, num2): + print(f'El resultado de la resta es: {num1 - num2}') + +def multiplicacion(num1, num2): + print(f'El resultado de la multiplicacion es: {num1 * num2}') + +def division(num1, num2): + print(f'El resultado de la division es: {num1 / num2}') + +def potencia(base, exponente): + print(f'El resultado de la potencia es: {base ** exponente}') + +def porcentaje(num1, num2): + porcentaje = (num1 * num2) / 100 + total = num1 - porcentaje + print(f'El resultado del porcentaje es: {total}') + +def redondeo(numero): + print(f'El resultado del redondeo es: {round(numero)}') \ No newline at end of file diff --git a/calculos/potencia_porcentaje/__init__.py b/calculos/potencia_porcentaje/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/calculos/potencia_porcentaje/__pycache__/__init__.cpython-310.pyc b/calculos/potencia_porcentaje/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..0df2c9f Binary files /dev/null and b/calculos/potencia_porcentaje/__pycache__/__init__.cpython-310.pyc differ diff --git a/calculos/potencia_porcentaje/__pycache__/__init__.cpython-38.pyc b/calculos/potencia_porcentaje/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..fad3184 Binary files /dev/null and b/calculos/potencia_porcentaje/__pycache__/__init__.cpython-38.pyc differ diff --git a/calculos/potencia_porcentaje/__pycache__/__init__.cpython-39.pyc b/calculos/potencia_porcentaje/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..3665de9 Binary files /dev/null and b/calculos/potencia_porcentaje/__pycache__/__init__.cpython-39.pyc differ diff --git a/calculos/potencia_porcentaje/potencia_porcentaje.py b/calculos/potencia_porcentaje/potencia_porcentaje.py new file mode 100644 index 0000000..04cfc15 --- /dev/null +++ b/calculos/potencia_porcentaje/potencia_porcentaje.py @@ -0,0 +1,7 @@ +def op_potencia(base, exponente): + print(f'El resultado de la potencia es: {base ** exponente}') + +def op_porcentaje(num1, num2): + porcentaje = (num1 * num2) / 100 + total = num1 - porcentaje + print(f'El resultado del porcentaje es: {total}') \ No newline at end of file diff --git a/dist/Paquete Calculos - Potencia y Porcentaje-1.0.tar.gz b/dist/Paquete Calculos - Potencia y Porcentaje-1.0.tar.gz new file mode 100644 index 0000000..dddcecf Binary files /dev/null and b/dist/Paquete Calculos - Potencia y Porcentaje-1.0.tar.gz differ diff --git a/fichero_consolas b/fichero_consolas new file mode 100644 index 0000000..c08babb Binary files /dev/null and b/fichero_consolas differ diff --git a/lista_nombres b/lista_nombres new file mode 100644 index 0000000..09fa757 Binary files /dev/null and b/lista_nombres differ diff --git a/modulo_funcionesMatematicas.py b/modulo_funcionesMatematicas.py new file mode 100644 index 0000000..9d3e994 --- /dev/null +++ b/modulo_funcionesMatematicas.py @@ -0,0 +1,17 @@ +# Funciones matematicas + +def suma(num1, num2): + suma = num1 + num2 + print(f'El resultado de la suma es: {suma}') + +def resta(num1, num2): + resta = num1 - num2 + print(f'El resultado de la resta es: {resta}') + +def multiplicacion(num1, num2): + multiplicacion = num1 * num2 + print(f'El resultado de la multiplicación es: {multiplicacion}') + +def division(num1, num2): + division = num1 / num2 + print(f'El resultado de la división es: {division}') \ No newline at end of file diff --git a/modulo_vehiculos.py b/modulo_vehiculos.py new file mode 100644 index 0000000..5b14052 --- /dev/null +++ b/modulo_vehiculos.py @@ -0,0 +1,72 @@ +class Vehiculos(): + def __init__(self, marca, modelo): + self.marca = marca + self.modelo = modelo + self.encendido = False + self.acelerar = False + self.frenar = False + + def arrancar(self): + self.encendido = True + + def acelerando(self): + self.acelerar = True + + def frenando(self): + self.frenar = True + + def propiedadesEstado(self): + print(f'Marca: {self.marca} \nModelo: {self.modelo} \nPrendida: {self.encendido} \nAcelerando: {self.acelerar} \nFrenando: {self.frenar}') + +class Moto(Vehiculos): + motoCaballo = 'Caballando' + + def caballo(self): + if self.acelerar == True: + self.motoCaballo = 'Caballito en proceso' + else: + self.motoCaballo = 'Caballito en espera de ejecucion' + + def propiedades(self): + super().propiedadesEstado() + print(f'Caballo: {self.motoCaballo}') + +class Camioneta(Vehiculos): + def carga(self, cargada): + self.cargar = cargada + if self.cargar: + return 'La camioneta está cargada' + else: + return 'La camioneta no está cargada' + +class ElectricCars2(Vehiculos): + def __init__(self, marca, modelo, autonomia): + super().__init__(marca, modelo) + self.autonomia = autonomia + + def chargeBattery(self, charging): + self.chargeBat = charging + if self.chargeBat: + return 'The battery is charging' + else: + return 'The battery is not charging' + + def propiedades(self): + super().propiedadesEstado() + print(f'Autonomia: {self.autonomia}') + +class ElectricBike(ElectricCars2, Vehiculos): + + def cargaManual(self, cargando, porcentaje): + self.pedalear = cargando + self.porcentaje_carga = porcentaje + if self.pedalear == True and self.porcentaje_carga >= 0 and self.porcentaje_carga < 100: + return f'Bateria al {self.porcentaje_carga}% y cargando' + elif self.pedalear == True and self.porcentaje_carga == 100: + return f'Bateria al {self.porcentaje_carga}%. Carga completa' + elif self.pedalear == True and self.porcentaje_carga < 0 or self.porcentaje_carga > 100: + return f'Error de carga. Favor de llevar su bicicleta a su agencia' + elif self.pedalear == False and self.porcentaje_carga < 0 or self.porcentaje_carga > 100: + return f'Error de carga. Favor de llevar su bicicleta a su agencia' + else: + return f'Bateria descargandose. Resta {self.porcentaje_carga}%' \ No newline at end of file diff --git a/modulos/__pycache__/funciones_matematicas.cpython-38.pyc b/modulos/__pycache__/funciones_matematicas.cpython-38.pyc new file mode 100644 index 0000000..8ef6f44 Binary files /dev/null and b/modulos/__pycache__/funciones_matematicas.cpython-38.pyc differ diff --git a/modulos/funciones_matematicas.py b/modulos/funciones_matematicas.py new file mode 100644 index 0000000..c2d0f3c --- /dev/null +++ b/modulos/funciones_matematicas.py @@ -0,0 +1,23 @@ +# Funciones matematicas + +""" Este modulo realiza operaciones matematicas basicas """ + +def suma(num1, num2): + """ Operacion de suma """ + suma = num1 + num2 + print(f'El resultado de la suma es: {suma}') + +def resta(num1, num2): + """ Operacion de resta """ + resta = num1 - num2 + print(f'El resultado de la resta es: {resta}') + +def multiplicacion(num1, num2): + """ Operacion de multiplicacion """ + multiplicacion = num1 * num2 + print(f'El resultado de la multiplicación es: {multiplicacion}') + +def division(num1, num2): + """ Operacion de division """ + division = num1 / num2 + print(f'El resultado de la división es: {division}') \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..e6d25fb --- /dev/null +++ b/setup.py @@ -0,0 +1,13 @@ +from setuptools import setup + +setup( + name='Paquete Calculos - Potencia y Porcentaje', + version='1.0', + description='Paquete para calcular la potencia y el porcentaje', + author='Eliab Hernandez', + author_email='moises_hl_zod@hotmail.com', # Dato no obligatorio + url='www.eh.com', + packages=['calculos','calculos.potencia_porcentaje'] # Aqui tenemos que indicar donde se encuentra (ruta) el paquete o subpaquetes que queremos empaquetar. No se necesario especificar la carpeta raiz. Para anotar la ruta es necesario hacerle entre corchetes y primero va la carpeta consecutiva a la raiz y despues el subpaquete con la ruta completa, es decir de nueva cuenta la carpeta anotada al inicio que es la que le sigue de la carpeta raiz +) + +# Con esto ya estaria completo el setup \ No newline at end of file