Registrarse

[Otros] Escuela introducción a la programación con python (finalizada)

La tarea 3: ¿prefieren que sea en parejas o individual?

  • En parejas

    Votos: 2 66,7%
  • Individual

    Votos: 0 0,0%
  • Me es indiferente

    Votos: 1 33,3%

  • Votantes totales
    3
  • Encuesta cerrada .
Estado
Cerrado para nuevas respuestas.

Jason

PkPower déjame poner tildes en mi nick ¬¬
Clase 10: conjuntos

Clase 10: conjuntos

Espero que estén emocionados, ya casi estamos en la mitad del curso. Hoy toca ver conjuntos, algo que me pareció buena idea enseñarles para que luego puedan dejar volar su imaginación y puedan jugar a gusto con estas estructuras de datos.

Definición de Conjunto:

Un conjunto es una colección de datos no ordenados ni repetidos, así de simple. Normalmente lidiamos con los conjuntos matemáticos en la escuela o en este mismo curso, a la hora de diferenciar entre ints (conjunto de los enteros) y floats (decimales, o más correctamente, el conjunto de los números racionales).

Conjuntos en programación:

Un conjunto en programación tiene la misma definición y sigue las mismas reglas. Su sintaxis es que los elementos del conjunto van separados por comas y todo dentro de llaves ({, }), como los diccionarios, pero sin las llaves.

Conjunto vacío:

Un conjunto vacío no se crea
Código:
conjunto = {}
porque eso lo que hace es crear un diccionario vacío, aquí la única forma de crear un conjunto vacío es:

Código:
conjunto = set()
Crear un conjunto con elementos:

Código:
conjunto_de_ejemplo = {'manzana', 'pera', 'piña', 'pera', 'arandano'}
Noten que el elemento 'pera' aparece dos veces, si luego lo printeamos:

Código:
print(conjunto_de_ejemplo)
Código:
{'manzana', 'pera', 'arandano', 'piña'}
¿Ven que 'piña' ahora está después de 'arandano'? Eso es porque a diferencia de las listas y tuplas, los conjuntos no están ordenados. Esto también implica que no podemos llamar a algún elemento por su índice.

Añadir elementos a un conjunto:

Para añadir elementos a un conjunto usaremos el método
Código:
set.add(cosa_que_queremos_meter)


Explicación sobre la relación entre dos conjuntos:

Sean dos conjuntos A y B, se puede tener que:

1) A pertenezca a B. Esto es cuando el los elementos del conjunto A están también en el conjunto B, pero B tiene también elementos que no están en A.



2) A es idénticamente igual a B. Esto pasa cuando todos los elementos del conjunto A están en el conjunto B y todos los elementos del conjunto B están en el conjunto A



3) Conjuntos intersectados. Tomemos el conjunto A con n elementos (n entero positivo) y B con m elementos (m entero positivo). Dos conjuntos estarán intersectados cuando existe un número k de elementos (k entero positivo, k menor a n y k menor a m) que estarán tanto en el conjunto A como en el conjunto B.



4) Conjuntos independientes. Esto ocurre cuando los conjuntos A y B no tienen elementos en común.



Operaciones sobre conjuntos:

1) Unión: la unión retorna un conjunto con todos los elementos que están en A o en B (aquí estoy poniendo a prueba lo que aprendieron en la clase de lógica proposicional, lean con cuidado ;) ).

Código:
a = {'manzana', 'pera', 'higo', 'ciruelas', 'damascos'}
b = {'huevos', 'leche', 'plátanos', 'damascos', 'pera', 'piña'}
c = a|b # el operador de unión es esta [COLOR="DarkOrange"][B][U][URL="https://es.wikipedia.org/wiki/Pleca"]barra vertical[/URL][/U][/B][/COLOR]: |  
print(c)
Código:
{'manzana', 'huevos', 'ciruelas', 'higo', 'plátanos', 'leche', 'pera', 'damascos', 'piña'}
2) Intersección: esto lo que hace es retornar los elementos que están en A y en B.

Código:
a = {'manzana', 'pera', 'higo', 'ciruelas', 'damascos'}
b = {'huevos', 'leche', 'plátanos', 'damascos', 'pera', 'piña'}
c = a&b # el operador de intersección es &

print(c)
Código:
{'pera', 'damascos'}
3) Resta de dos conjuntos: es cuando a un conjunto le restas los elementos de otro conjunto. Ojo, aquí no existen "elementos negativos", por lo que si estoy operando

Código:
a = {1, 2, 3}
b = {2, 3, 4}
print(a - b)
El retorno será simplemente:
Código:
{1}
Es decir, si estoy resando B a A, los elementos que están en B pero no en A no influirán en el resultado.

4) Exclusión: (nombre inventado) Si tenemos dos conjuntos intersectados no idénticamente iguales y no uno contenido en otro, podemos buscar todos los elementos que estén únicamente en A o únicamente en B (a esto se le llama una disyunción exclusiva, que a diferencia de la que les enseñé en la clase 4, esta disyunción tiene por tabla de verdad True 'or' True == False).

Código:
a = {1, 2, 3}
b = {2, 3, 4}
print(a ^ b)
Código:
{1, 4}

Pertenencia a un conjunto:

Si queremos comprobar si un elemento pertenece o no a un conjunto, basta con

elemento in conjunto


En cambio, si queremos comprobar que un conjunto (llamémoslo A) está dentro de otro (que sea B), usamos el método set.issuperset() de la siguiente forma:

Código:
B.issuperset(A) #nos dice si A pertenece a B
O, podemos usar el método set.issubset():

Código:
A.issubset(B) #nos dice si B está contenido en A
Al igual que con listas y diccionarios, los conjuntos al asignarse a dos o más variables continúan siendo fundamentalmente el mismo conjunto, por lo que modificarlo en una de las variables lo modifica en toda, por lo tanto tenemos también el método copy() para solucionarnos la existencia.

Función help() de python:
Ya es momento de que aprendan a usar esta maravilla del universo, la propia documentación de python.

Si en el idle escriben

Código:
help(set)
y lo ejecutan, van a salir muchas cosas escritas en azul, eso que sale es todo lo que pueden hacer con los conjuntos, explicado de forma breve. Al final del post les dejo lo que sale.


Ejercicios:
1) Hagan un programa que realice las operaciones que se puede hacer con conjuntos (|, &, - y ^) pero con listas. También un programa que a partir de una lista con elementos repetidos (o no), retorne otra lista con los elementos de la primera pero no repetidos. Restricción: no pueden usar conjuntos para esto.

2) Expliquen qué pasa si aplican la función set() a las otras estructuras de datos que vimos (strings, listas, tuplas y diccionarios) y lo que sucede cuando aplican las funciones list(), tuple(), str() y dict() a un conjunto.

3) Los conjuntos pueden sernos útiles a la hora de programar un juego de pokémon cuando el juego debe decir cuántas especies de pokémon han sido atrapadas y/o avistadas. Nombren otra situación para la que son útiles.

4) Practiquen por su cuenta, experimentando, el uso de conjuntos. Aprendan a usar los métodos que aparecen en la documentación de python.


Help on set object:

class set(object)
| set() -> new empty set object
| set(iterable) -> new set object
|
| Build an unordered collection of unique elements.
|
| Methods defined here:
|
| __and__(self, value, /)
| Return self&value.
|
| __contains__(...)
| x.__contains__(y) <==> y in x.
|
| __eq__(self, value, /)
| Return self==value.
|
| __ge__(self, value, /)
| Return self>=value.
|
| __getattribute__(self, name, /)
| Return getattr(self, name).
|
| __gt__(self, value, /)
| Return self>value.
|
| __iand__(self, value, /)
| Return self&=value.
|
| __init__(self, /, *args, **kwargs)
| Initialize self. See help(type(self)) for accurate signature.
|
| __ior__(self, value, /)
| Return self|=value.
|
| __isub__(self, value, /)
| Return self-=value.
|
| __iter__(self, /)
| Implement iter(self).
|
| __ixor__(self, value, /)
| Return self^=value.
|
| __le__(self, value, /)
| Return self<=value.
|
| __len__(self, /)
| Return len(self).
|
| __lt__(self, value, /)
| Return self<value.
|
| __ne__(self, value, /)
| Return self!=value.
|
| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate signature.
|
| __or__(self, value, /)
| Return self|value.
|
| __rand__(self, value, /)
| Return value&self.
|
| __reduce__(...)
| Return state information for pickling.
|
| __repr__(self, /)
| Return repr(self).
|
| __ror__(self, value, /)
| Return value|self.
|
| __rsub__(self, value, /)
| Return value-self.
|
| __rxor__(self, value, /)
| Return value^self.
|
| __sizeof__(...)
| S.__sizeof__() -> size of S in memory, in bytes
|
| __sub__(self, value, /)
| Return self-value.
|
| __xor__(self, value, /)
| Return self^value.
|
| add(...)
| Add an element to a set.
|
| This has no effect if the element is already present.
|
| clear(...)
| Remove all elements from this set.
|
| copy(...)
| Return a shallow copy of a set.
|
| difference(...)
| Return the difference of two or more sets as a new set.
|
| (i.e. all elements that are in this set but not the others.)
|
| difference_update(...)
| Remove all elements of another set from this set.
|
| discard(...)
| Remove an element from a set if it is a member.
|
| If the element is not a member, do nothing.
|
| intersection(...)
| Return the intersection of two sets as a new set.
|
| (i.e. all elements that are in both sets.)
|
| intersection_update(...)
| Update a set with the intersection of itself and another.
|
| isdisjoint(...)
| Return True if two sets have a null intersection.
|
| issubset(...)
| Report whether another set contains this set.
|
| issuperset(...)
| Report whether this set contains another set.
|
| pop(...)
| Remove and return an arbitrary set element.
| Raises KeyError if the set is empty.
|
| remove(...)
| Remove an element from a set; it must be a member.
|
| If the element is not a member, raise a KeyError.
|
| symmetric_difference(...)
| Return the symmetric difference of two sets as a new set.
|
| (i.e. all elements that are in exactly one of the sets.)
|
| symmetric_difference_update(...)
| Update a set with the symmetric difference of itself and another.
|
| union(...)
| Return the union of sets as a new set.
|
| (i.e. all elements that are in either set.)
|
| update(...)
| Update a set with the union of itself and others.
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __hash__ = None
 
Última edición:

David Phunir

Usuario de platino
Respuesta: Clase 1: el lenguaje y algoritmos

1) Identificar el inicio de la escalera y asegurarse que sea una escalera. Además, verificar si se cuenta con dos piernas y pies útiles para lograr subir.

2) Seleccionar el pie con el que se iniciará y distinguirlo del otro. A uno llamaremos Derecho y otro Izquierdo.

3)Doblar la rodilla y movilizar el pie inicial (Derecho) hacia adelante. Bajar el pie hasta chocar con la superficie del primer peldaño.

4) Estirar la rodilla flexionada y estirarla con una fuerza mayor al peso de la persona, con el fin de elevar el cuerpo. Cuidado con el equilibrio cuando se esté en un solo pie.

5) Repetir paso "3" con la pierna que esté en el aire (izquierda).

6) Repetir paso "4" con la pierna que esté en el peldaño superior (izquierda)

7) Repetir pasos del "3" al "6".

8) Si llegó hasta la siguiente plata (siguiente piso), se interpreta que terminó la escalera. Finalizar el bucle. Felicitaciones, usted subió una escalera con un algoritmo.

Notas importantes a considerar: No confundir el pie con el pie.
 

Jason

PkPower déjame poner tildes en mi nick ¬¬
Clase 11: funciones definidas por el usuario, parte 1

Clase 11: funciones definidas por el usuario, parte 1

Este día marcará un antes y un después en su vida de programadores (para los que no saben programar). De seguro me odiarán un poco ya que no pueden aplicar esto en la tarea 1 pero un poco de copy/paste no mata a nadie.

Una función la podemos ver como un trozo de código que se almacena en otro lado para luego poder utilizarlo muchas veces de forma visualmente más limpia.

Creando nuestras propias funciones:

La sintaxis para crear una función es:
Código:
[B][COLOR="DarkOrange"]def [/COLOR][/B][I]nombre[/I]([I]argumentos[/I]):
	[I]código[/I]
	[B][COLOR="darkorange"]return [/COLOR][/B][I]retorno[/I]
Explicación: estamos definiendo una función de nombre nombre, que recibe argumentos, ejecuta código y retorna el retorno.

Algunos ejemplos:

Código:
def factorial(n): #calcula el factorial de un número
	result = 1
	for i in range(2, n+1):
		result *= n
	return result
Código:
def sqrt(n): #calcula la raíz cuadrada de un número
	return n**0.5
Funciones sin retorno:

Una función sin retorno es una que recibe argumentos pero al luego asignar esa función a una variable, el valor de esa variable pasa a ser None.

Ejemplos:
1.
Código:
def p(k):
	print(2*k)

a = p(4)
print(a)
Código:
8
[B][COLOR="darkorange"]None[/COLOR][/B]
2.
Código:
def int_list(k):
	for i in range(len(k)):
		k[i] = int(k[i])

var = list("1234")
print(var)

int_list(var)
print(var)
Código:
['1', '2', '3', '4']
[1, 2, 3, 4]
¿Cómo usar las funciones dentro del código?

Eso dependerá de si tienen o no retorno. Si tienen un retorno que voy a usar, la forma de usr esa función es a una variable se le asigna una función. Tomando el ejemplo del factorial:

Código:
def factorial(n):
	result = 1
	for i in range(2, n+1):
		result *= n
	return result

k = factorial(n)
Luego, si la función no tiene retorno, bastaría con escribir:

Código:
nombre_funcion(argumentos)
como una línea donde corresponda. Esto ya lo debieron haber visto con sort y sorted:

Mientras que list.sort() no tiene retorno, sorted(list) sí lo tiene.

Scope local:

Scope viene siendo el terreno donde se puede usar una variable, lo que explicaré con esta extremadamente sofisticada infografía:



Y aquí un ejemplo de lo que pasa con las variables locales:




Ejercicios:
1) Díganme a qué tipo de variables (de todas las que hemos visto) se le pueden hacer modificaciones que permanezcan sin necesidad de que esa función tenga un retorno. En el ejemplo 2 les mostré que las listas son uno de ellos.

2) Quiero que estudien el código que les dejo en este link. Hay algunas cosas interesantes que vale mucho la pena que revisen.

3) Ya están muy en condiciones de programar una versión en consola de este juego, les servirá mucho de práctica. Ojo: que el pc construya por si solo un número de x dígitos y el jugador debe adivinarlo.
Reglas de juego simples: Toros y Vacas

 

David Phunir

Usuario de platino
Respuesta: Clase 2: variables tipo int y float

Ejercicios resuelto:

2) Funciones Float() e Int() sirven para ejecutar argumentos aritméticos (no sé si ese es el nombre), por ejemplo
>>> Float ( 4 / 8 )

Y el resultado lo muestra con decimales; de igual forma que Int() sin decimales.

Se puede utilizar dentro de una operación para considerar sólo la parte entera de otra sub-operación, por ejemplo
>>> Print ( 3 + Int (6/4) )
4

3) Ahí va "Muestra los Dígitos "

4) Sale el mismo error que dijo Berserker.
 

Jason

PkPower déjame poner tildes en mi nick ¬¬
Clase 12: funciones definidas por el usuario, parte 2

Clase 12: funciones definidas por el usuario, parte 2

Esta clase se dividirá en cuatro partes.

Parte 1: importando funciones.

Ya vieron y saben usar algunas de las funciones de los módulos random y time, pero ahora les explico un poco más del tema.

Import:

Nosotros al usar import traemos al archivo en el que estemos trabajando todo el contenido de otro, sea este el módulo time, random, math o el que deseen. Hay tres formas de hacerlo:

1) import <nombre>

Esto es lo que hemos estado haciendo hasta ahora, para usar las funciones que contiene el módulo o librería en cuestión debemos anteponer "<nombre>." al nombre de la función en cuestión.

Ejemplo:

Código:
import random

x = random.randint(1, 10)

2) from <nombre> import <nombre_cosa>

Aquí, en lugar de traer todo el módulo o librería en cuestión solo traen lo que necesiten. Con esto ya no es necesario anteponer "<nombre>." a la función, variable o cosa que deseemos usar.

Ejemplos:
1.
Código:
from math import pi
radio = int(input("Ingrese radio de circunferencia: "))
area = pi*(radio**2)
perimetro = 2*pi*radio
print("Me gusta el chocolate.")
2.
Código:
from random import random, randint
a = random()
b = randint(-10, 10)
print("No me llamo Rafa")
Como pueden ver en el ejemplo 2, importé dos funciones del módulo random simplemente separándolos por comas.

3) Lo que por favor, les pido que NO HAGAN (y no solo yo, en el mundo exterior a nadie le gusta esto):

Python nos da la opción de importar todo un módulo como en la segunda modalidad para no tener que anteponer "<nombre>." a cada cosa que hagamos, pero esto no gusta porque si otro lee el código (que uno también programa para que sea entendible, no solo para que funcione) no sabe facilmente de qué módulo/librería viene cada cosa. De todas maneras se los muestro:

Código:
from <nombre> import *

Guardando funciones y cositas varias en otro archivo:

Piensen que si el programa se vuelve más grande, subir y bajar cambiando cosas puede ser caótico, por lo que normalmente agrupamos funciones en distintos archivos para, al igual que si se tratara de una librería o módulo que viene con python (u otro que descarguemos), importarlo a nuestro archivo principal que por convención se deberá llamar "main.py" (main en inglés significa "principal" o "por defecto").

Esta fue mi tarea 2 de un ramo de la universidad (nos pedían que el archivo principal tuviera un nombre en específico distinto a main, en este caso el principal es tarea2_166...):



El archivo principal es el que se ejecuta con doble click para que se abra en la consola y todo funcione, tengan eso en mente.

Así partía mi archivo principal para esa tarea:




Parte 2: poniendo "motes" a funciones.

Esto en lenguaje técnico se llama "instanciar una función", es algo que podemos hacer ya que python es un lenguaje multiparadigmas (tiene varias formas de programar) y esto usa lo que se llama "programación funcional". Si han experimentado lo suficiente, notarán que no es muy buena idea tener una variable y una función con el mismo nombre, pues pasan cosas como esta:



Lo que sucede es que podemos "poner un mote" (o instanciar) una función en una variable, esto se hace de la siguiente forma:



Esto tiene una utilidad muy particular que les mostraré en la parte tres.


Parte 3: funciones de orden superior

¿Sabían que pueden crear funciones dentro de otras funciones?

Este es un ejemplo que tomo prestado de una página que me gusta mucho (python para impacientes). Aquí crean un conversor numérico de decimal a binario, octal y hexadecimal:



sis_func es un diccionario que contiene los nombres de las tres funciones que definió al interior de conversor, de modo que el argumento de la función conversor diga cuál de las tres funciones definidas dentro de conversor es la que va a instanciar. Luego, en el retorno de conversor está la instancia de la función que se va a ejecutar. Ahora lo paso a el editor y se los muestro:

Código:
def conversor(sist):
    def sis_bin(n):
        return bin(n)

    def sis_oct(n):
        return oct(n)

    def sis_hex(n):
        return hex(n)

    sis_func = {"bin": sis_bin, "oct": sis_oct, "hex": sis_hex}

    return sis_func[sist]
Notarán que hice algunos cambios pero al final es lo mismo.

Ahora, ¿cómo usamos estas funciones de orden superior?

1) Método [INNVENTE UN NOMBRE AQUÍ]:

Iba a intentar explicarlo pero mejor se los muestro:

Código:
def conversor(sist):
    def sis_bin(n):
        return bin(n)

    def sis_oct(n):
        return oct(n)

    def sis_hex(n):
        return hex(n)

    sis_func = {"bin": sis_bin, "oct": sis_oct, "hex": sis_hex}

    return sis_func[sist]

print(conversor("bin")(12))
Sí, se ponen dos bloques de paréntesis redondos luego del nombre de la función, el primero es para indicar qué función usaré, "bin" hace que sis_func['bin'] sea la instancia de sis_bin, luego conversor("bin")(12) queda como sis_func['bin'](12) -> sis_bin(12) y voalá!

2) Método [INNVENTE OTRO NOMBRE AQUÍ]:

¿Se acuerdan que podemos instanciar funciones? Vamos a hacer eso:
Código:
# (no voy a poner de nuevo def conversor...)
conversorbin = conversor('bin')
print(conversorbin(12))
Y bueno, es eso: instancio la instancia de sis_bin que retorna conversor en conversorbin para usarla.


Parte 4: sobrecarga.

Esto es algo que ya vieron la clase pasada un poco, concretamente en esta imagen:



La sobrecarga consiste en eso, en sobreescribir una función definiendo otra con el mismo nombre, no tiene más ciencia que eso.
Otro ejemplo:

A mí la verdad es que no me gusta nada la función bool() que tiene python, preferiría que según el string que le doy retorne True o False, porque como está, bool("True") == bool("False") == True. Entonces voy a sobrecargar la función para que funcione como quiero.

Código:
def bool(string):
	if string == "True":
		return True
	elif string == "False":
		return False
	else:
		return None
Noten que las últimas dos líneas son completamente innecesarias, pero prefiero ser explícito.


Ejercicios:

1) Quiero que hagan una función para convertir una lista que únicamente contiene números como dato strings a una lista que contenga los mismos números pero como dato numérico y la pongan en un archivo. Otra función que para, de un tablero de nxm (n filas y m columnas) compuesto por una lista de listas, donde las listas de dentro sean las filas del tablero, sacar la k-ésima columna (indexación parte en cero), y la guarden en un segundo archivo. Luego, en un tercer archivo deben crear un tablero de nxm con números aleatorios entre 1 y 4 pero como dato string. Lo que van a tener que hacer es:
a) Usar las dos funciones anteriormente creadas para cambiar todos los números del tablero en formato string a formato int.
b) Comprobar si está la secuencia [1, 2, 3, 4] en horizontal, vertical o diagonal, al derecho o al revés en el tablero. Imágenes explicativas abajo:

Tablero:


Una columna:


Strings a ints:


Algunas formas válidas de hallar la secuencia:


2) ¿Han notado que algunos pokémon suben de nivel más rápido que otros? Eso es porque existen fundamentalmente seis formas de crecimiento: lento, rápido, normal, parabólico, fluctuante y errático (ver link). Quiero que hagan una función de orden superior que diga cuántos puntos de experiencia tendrá un pokémon según su forma de crecimiento y el nivel al que está. (NOTA IMPORTANTE: para los crecimientos fluctuante y errático deben ustedes determinar en qué intervalo se encuentran de la función por partes). Para los tipos de crecimiento errático y fluctuante, usen las fórmulas de bulbapedia. Nota: a los resultados que les den esa fórmula les deben aplicar la función int(). Si quieren, practiquen strings y verifiquen con la tabla que pone la bulbapedia que su función de los resultados correctos (para los seis tipos).

 
Última edición:

Berserker1523

2-Intentando discernir qué es lo más importante...
Respuesta: Clase 6: ciclos while

Si hacemos un While con un Break, podría usarse igual a un If?
A qué te refieres?
Si es esto:
Código:
while <condicion>:
...
(Identación)break
(Identación)if <condicion>:
(doble identacion para el if)
...
No, con el break te sales del ciclo y no revisaría lo que hay debajo de él (que esté dentro de la identación del while). Si pones el if después del while (que no esté adentro o identando en él) una vez termine el ciclo o pare en un break sí evaluará ese if.
 

Jason

PkPower déjame poner tildes en mi nick ¬¬
Clase 13: input/output - archivos

Clase 13: input/output - archivos


Un archivo es un conjunto de bits almacenados en algún dispositivo, pero no trabajaremos a tan bajo nivel sino a algo más "legible", los .txt.

Apertura, lectura y cierre de un archivo:

Un archivo se abre con python cargándolo en memoria según qué se vaya a hacer con él (veremos tres posiblilidades) asignándolo a una variable y la función open de la siguiente forma:

Código:
var = open(nombre_archivo, modo)
nombre_archivo es un string terminado en .txt, como por ejemplo: "numeros.txt"

modo puede ser: 'r', 'w' y 'a' (hay más pero lo dejaré en estos tres).

Leer un archivo: 'r'
Escribir o crear un archivo: 'w'
Ojo: si el archivo tenía algo, lo sobreescribirá borrando lo que había.
Añadir a o crear un archivo: 'a'
Si el archivo existía, irá agregando al final lo que queramos, de lo contrario, lo creará.

Leer una línea:

Habiendo cargado nuestro archivo en una variable (diremos que se llama 'var'), para leer una línea usaremos el método:

Código:
otra_variable = var.readline()
Ojo, porque si lo hacemos por segunda vez, ahora nos retornará la segunda línea, luego la tercera y así. En caso de que quieran volver al principio ejecutan el método:

Código:
var.seek(0)
O pueden cerrar el archivo y luego volver a abrirlo.
Si llegan al final, readline retornará un string vacío.

Otra forma de leer un archivo es con el método:

Código:
otra_variable = var.readlines()
Que en lugar de retornar un string con la línea leída, retornará una lista con cada línea del archivo en formato string.

Cerrar un archivo:

Continuando con nuestro archivo cargado en una variable de nombre 'var', ahora que ya lo leímos debemos cerrarlo, para ello simplemente usamos el método:

Código:
var.close()
Notar que:
1. Cuando leemos una línea en un archivo de varias líneas, este string incluye '\n' al final, con el método str.strip() lo pueden manejar (ver compilado de ejemplos 1).
2. Si ya habían avanzado leyendo líneas en un archivo con readline y luego usan readlines, este último leerá desde la última línea no leída hacia adelante.

Escribir en un archivo:
Seguimos con nuestro .txt cargadon en nuestra variable 'var' y ahora lo que queremos es escribir en él.
Primero, nos decantamos por 'w' o 'a' según lo que deseemos.
Luego:

Código:
var = open(nombre_archivo, 'w') #elijo 'w' porque sí.
Para escribir una línea usamos:

Código:
print(lo_que_vamos_a_escribir, file = var) 
#siendo var el nombre de nuestra variable.
No existe algo como modificar un trozo de un archivo, deben reescribirlo todo (aunque el 99.999% sea exactamente igual a lo que había).

Recuerden que al terminar de usarlo debemos cerrarlo con el método: var.close()

Módulo os:

Este módulo conecta directamente con el sistema operativo. Por lo que varias cosas difieren según si uno está en Windows, Mac o Linux. Aquí algunas cosas que tendremos con este módulo:
  • sep:
    Es una variable de tipo string que almacena el separador entre carpetas, puesto a que este difiere según el sistema operativo: \ para windows (en string se escribe '\\' para que se lea, porque uno solo indica caracter especial como el ya conocidísimo para ustedes \n) y / en mac o linux.
  • getcwd():
    Retorna un string con la ruta (path) en la que estamos.
  • chdir():
    Nos permite movernos entre las carpetas. No tiene retorno.
    chdir('..') nos envía hacia atrás.
    chdir(ruta) nos envía a la ruta indicada
    chdir(nombre_carpeta) nos hace entrar a la carpeta especificada y que está donde estábamos.

El resto se los dejo a ustedes porque entra directamente en la tarea 2. NUNCA hagan:

Código:
from os import *
Porque el módulo os trae una función open que no es como la que aquí enseño y no la vamos a usar.

Eso es todo por esta clase.
No hay ejercicios esta vez.

PD: les recomiendo también leer sobre el módulo shutil y cómo leer un archivo ".json". No dejo links para que aprendan las prácticas de todo programador que se precie: "si no lo sé, busco en google".


 
Última edición:
Respuesta: Clase 7: ciclos for

#1) Simular con UN while un for anidado (dos variables que se mueven en un rango "rectangular".

#For anidado
Código:
for i in range(8):
	for j in range(9):
		print(str(i)+"x"+str(j))

#While haciendo de for anidado
Código:
rango = [8,9]
n0 = 1
n1 = 0
while True:
    if n1 >= rango[1]:
        n1 = 0
        n0 += 1
    n1 += 1
    print(str(n0) + 'x' + str(n1))
    if n1 >= rango[1] and n0 >= rango[0]:
        break

#2) Hacer un programa que calcule el factorial de un número ingresado por el usuario.
Código:
numero = int(input("Ingrese el numero para calcular el factorial: "))
factorial = 1
for n in range(1, numero):
    factorial += factorial * n
print(factorial)

#3) Hacer un programa que verifique si un número es primo o no.
Código:
n_primo = int(input('Ingrese un numero: '))
primo = True
for n in range(2,n_primo-1):
    if n_primo % n == 0:
        primo = False
        break
if primo:
    print('Su numero', n_primo, 'SI es primo')
else:
    print('Su numero', n_primo, 'NO es primo')

#4) Cada uno deberá decirme el n-ésimo primo para un n (uno distinto para cada alumno, la lista está más abajo).
Código:
numeros_primos = 0
inicial = int(input('Ingrese el enesimo numero primo: '))
n_inicio = 2
primos = []
while numeros_primos < inicial:
    primo = True
    for n in range(2, n_inicio):
        if n_inicio % n == 0:
            primo = False
    if primo:
        if n_inicio not in primos:
            primos.append(n_inicio)
            numeros_primos += 1
        else:
            n_inicio += 1
    else:
        n_inicio += 1

print(primos[inicial-1])
__142avo numero primo 821
 

Jason

PkPower déjame poner tildes en mi nick ¬¬
Clase 14: programación orientada a objetos I


Clase 14: programación orientada a objetos (OOP) parte 1

En programación existen diferentes paradigmas, es decir, formas de programar. Ustedes han visto programación estructurada que vendría siendo todo lo de la tarea 1, código que se ejecuta siempre de forma lineal de arriba a abajo. Luego les mostré una pincelada de programación funcional (funciones :nomedigas: ) y ahora les enseñaré el paradigma que está en uso actualmente porque simplemente no se ha encontrado algo mejor: programación orientada a objetos.

Objetos:

De las funciones como abreviación de código pasamos a que en nuestro programa vamos a tener objetos que: guardan información (atributos) y pueden hacer cosas (métodos). ¿Se acuerdan del ejercicio de la primera clase en el que les pedía crear un algoritmo y definir un objeto? Era precisamente por esto. Si antes para propósitos del programa una persona no era más que números, hoy damos un paso hacia adelante: ahora son objetos.

Clases:

Nosotros para crear un objeto en programación necesitamos de un "molde": las clases. Las clases (en el sentido de clase paladín, clase hechicero, etc. como arquetipos de personajes en un RPG) son el molde del o los objetos con esas características que vamos a crear. Ejemplo:

Creemos la clase auto: para ello hay que definir qué atributos va a tener: marca, color, patente, num_puertas, caballos_de_fuerza, num_asientos. Con esto en mente podemos crear infinitos objetos auto que tengan esos mismos atributos pero con diferentes valores. Yo puedo tener un auto color verde y otro puede tener uno color azul. Ambos son distintos objetos pero ambos son del mismo tipo: autos.

Definiendo clases:

Para crear una clase tendremos la siguiente estructura:

Código:
class [I]nombre_objeto[/I]:
	[I]atributo_1 = valor_inicial
	atributo_2 = valor_inicial
	atributo_3 = valor_inicial
	...
	atributo_n = valor_inicial[/I]

	def __init__(self, [I]argumentos[/I]):
		[I]código[/I]
		return None #no hay que ponerlo, yo lo hago para mostrarles
			#que no tiene retorno
Bien, ¿qué es todo esto?

class es la palabra reservada que usamos para decirle al computador que estamos definiendo una clase.

nombre_objeto es el nombre de nuestro objeto.

atributos 1, 2, 3, ..., n son los atributos de nuestra clase, pueden ir cosas como color, vida, mana, rango, tablero, número... en fin, todo lo que necesiten.

def __init__(self, argumentos) es el método constructor de la clase: cuando creemos un objeto de la clase que estemos programando, este es el método que se ejecutará, tomará los argumentos que les den + self y la clase los usará en el código que le coloquen para finalmente tener el objeto que quieren.

self es la palabra clave que usamos como primer argumento de todos los métodos de una clase SIEMPRE. Lo que hace es indicarle al método que como argumento está el propio objeto con todos sus métodos y atributos.

Algunos ejemplos:

1. País.
Código:
class pais:
	nombre = ""
	poblacion = 0 
	continente = None #va a ser una lista
			#hay países que están en más de un continente.
	superficie = 0 #en km2
	
	def __init__(self, name, popu, cont, sup):
		self.nombre = name
		self.poblacion = popu
		self.continente = cont
		self.superficie = sup

2. Autos.
Código:
class auto:
	marca = ""
	color = ""
	patente = ""
	num_puertas = 0
	caballos_fuerza = 0
	num_asientos = 0
	cliente_especifico = ""

	def __init__(self, m, c, p, np, cf, na): #son _ _ init _ _, dos guiones bajo pegados.
		self.marca = m
		self.color = c
		self.patente = p
		self.num_puertas = np
		self.caballos_fuerza = cf
		self.num_asientos = na
		
		if self.caballos_fuerza/self.num_asientos >15 and self.num_asientos >= 5:
			self.cliente_especifico = "familiar_camping"
		elif ca/na <=15 and self.num_asientos >= 5: #ahorrando espacio (caractéres)
			self.cliente_especifico = "familiar_urban"
		elif ca/na > 15 and na<5:
			self.cliente_especifico = "teenager_or_young_boy"
		elif ca/na > 15 and na>=5:
			self.cliente_especifico = "young_student"

3. Paladín.
Les dejo el link a un archivo .py para que lo revisen, me salió más largo de lo que pensaba.

paladín.py


Creando un objeto:

A "crear un objeto" a partir de una clase que ya definimos se le llama "instanciar un objeto". ¿Cómo instanciamos un objeto entonces? Con la sintaxis:

Código:
variable = nombre_clase(args)
A una variable le cargamos un objeto construído con los argumentos que debemos darle. Ojo, el self no debemos ponerlo, es decir, si el constructor tiene los argumentos self, a1, a2 y a3, nosotros solo debemos hacer:

Código:
variable = nombre_clase(a1, a2, a3)

Llamando atributos de clase:

Nosotros queremos saber los ps restantes de un paladín, entonces

Código:
jugador = paladin(...args) #la clase del archivo que les dejé

print("A "+jugador.nombre+" le quedan "+ str(jugador.ps_restantes) +" PS.")
Por lo demás, los atributos de una clase los podemos usar sin problemas como si fueran cualquier variable, dentro de los límites del tipo de dato que sean.


Problema con las listas (again):

Volvamos al ejemplo de los países, ahora les voy a explicar por qué puse continente con el valor None en lugar de como una lista vacía.
Imagínense que la hubiese definido así:

Código:
class pais:
	nombre = ""
	poblacion = 0 
	continente = [] #hay países que están en más de un continente.
	superficie = 0 #en km2
	
	def __init__(self, name, popu, cont, sup):
		self.nombre = name
		self.poblacion = popu
		#nuevamente, cont es una lista.
		for i in cont:
			self.continente.append(i)
		self.superficie = sup
Ahora, creemos dos países.

Código:
pais1 = pais('gringolandia', 300000000, ['américa, por desgracia'], 12.5)
pais2 = pais('chinatopia', 1200000000, ['asia'], 100)

print(pais1.nombre+":", pais1.continente)
print(pais2.nombre+":", pais2.continente)
Eso imprimirá:

Código:
gringolandia: ['américa, por desgracia', 'asia']
chinatopia: ['américa, por desgracia', 'asia']
¿Pero qué ha pasado? ¿Por qué ambos están en ambos continentes? ¿Se ha formado acaso la República Democrática Dictatorial Monárquica Teofáfica Absolutista de Gringochinatopialandia? No.

Esto pasa porque las listas son unas hij... no.
Nosotros definimos una lista vacía como atributo DE LA CLASE que, por la naturaleza de las listas, al asignarse a dos variables continúan conectadas. Entonces ambos países TIENEN LA MISMA LISTA DE CONTINENTES a los que pertenecen.

¿Soluciones?
Lo que hice yo con el None es una solución, como cont ya es una lista, no hace falta más.

Otras opciones:

Código:
class pais:
	nombre = ""
	poblacion = 0 
	continente = None
	superficie = 0 #en km2
	
	def __init__(self, name, popu, cont, sup):
		self.nombre = name
		self.poblacion = popu
		self.continente = []
		for i in cont:
			self.continente.append(i)
		self.superficie = sup
Código:
class pais:
	nombre = ""
	poblacion = 0 
	superficie = 0 #en km2
	
	def __init__(self, name, popu, cont, sup):
		self.nombre = name
		self.poblacion = popu
		self.continente = cont #aquí estoy añadiendo un atributo DEL OBJETO
		self.superficie = sup
Código:
class pais:
	nombre = ""
	poblacion = 0 
	continente = [] 
	superficie = 0 #en km2
	
	def __init__(self, name, popu, cont, sup):
		self.nombre = name
		self.poblacion = popu
		self.continente = cont.copy()
		self.superficie = sup
Y más.

Ejercicios:
1) Creen la clase 'hechicero'. No tiene ataque pero sí ataque_magia y mana como atributos.
2) Creen la clase pokémon con todos los atributos que crean que debe tener. Ojo, debe aplicar tanto a pokémon de un entrenador como a pokémon salvajes.

 
Última edición:

Jason

PkPower déjame poner tildes en mi nick ¬¬
Clase 15: programación orientada a objetos II


Clase 15: programación orientada a objetos (OOP) parte 2

Bienvenidos a la segunda clase de programación orientada a objetos, hoy, finalmente, veremos...

Métodos

Un método es un proceso que puede llevar a cabo un objeto de una clase determinada sobre sí mismo u otros objetos. ¿Recuérdan que les vengo hablando de métodos de los strings, de las listas, tuplas y demás?, bueno, la forma de referirme a todo eso no es lo más correcto, en realidad lo es: métodos de la clase str, clase list, clase dict, clase tuple, etc. No creo que les haya pasado inadvertido que la función type retorna "<class algo>".


Definiendo métodos:

Dentro de una clase y a continuación del método constructor, con la indentación pertinende se definen los métodos como cualquier otra función solo que añadiendo el argumento self como primero de todos. Veamos un ejemplo creando la clase "foro":

Código:
from time import time, ctime

class foro:
        nombre  = ""
        num_usuarios = 0
        webmaster = ""
        admins = None
        gmods = None
        mods = None
        directorio_usuarios = None
        directorio_temas = None

        def __init__(self, staff, usuarios, temas):
                #staff es una lista de listas y un string
                #usuarios es un diccionario en formato:
                #       {id: (nombre, rol, mvs, mps, datos, ...), id: (nombre, ...), ...}
                #temas es un diccionario...
                self.webmaster = staff[0]
                self.admins = staf[1].copy()
                self.gmods = staf[2].copy()
                self.mods = staf[3].copy()
                self.directorio_usuarios = usuarios.copy()
                self.directorio_temas = temas.copy()
                self.nombre = input("Ingrese nombre de su foro: ")
                self.num_usuarios = len(self.directorio_usuarios)
                self.num_ussers_en_creacion = []
                self.num_temas_en_creacion = []
                self.num_usuarios = len(self.directorio_usuarios)

        def postear_nuevo_tema(self, ide):
                if len(self.num_temas_en_creacion) == 0:
                        num = max(self.directorio_temas) +1
                else:
                        num = self.num_temas_en_creacion[-1] +1
                self.num_temas_en_creacion.append(num)
                titulo = input("Ingrese título del tema: ")
                cuerpo = input("Ingrese cuerpo del tema: ")
                fecha = str(ctime(time()))
                creador = ide
                self.directorio_temas[num] = {creador, fecha, titulo, cuerpo}
                self.num_temas_en_creacion.remove(num)

        def registrar_usser(self):
                def comprobar_mail(mail):
                        if mail.count('@') == 1 and mail[mail.find('@'):].count('.')==1\
                           and mail[-1] != '.':
                                return True
                        else:
                                return False
                while True:
                        if len(self.num_ussers_en_creacion) == 0:
                                num = max(self.directorio_usuarios) +1
                        else:
                                num = self.num_ussers_en_creacion[-1] +1
                        
                        nombre_usuario = input("Ingrese nombre de usuario: ")
                        mail = input("Ingrese correo electrónico: ")
                        psw1 = input("Ingrese contraseña: ")
                        psw2 = input("Confirme contraseña: ")
                        aux = True
                        if nombre_usuario in list(self.directorio_usuarios):
                                pass
                        elif comprobar_mail(mail):
                                if psw1 == psw2:
                                        self.directorio_usuarios[nombre_usuario] = {
                                                'nombre': nombre_usuario,
                                                'mail': mail,
                                                'psw': psw1,
                                                'mvs': None,
                                                'mps': None,
                                                'ide': num}
                                        break
                self.num_ussers_en_creacion.remove(num)

¿Para qué hacer todo eso tan largo?

Lo primero es:

Código:
wahack = foro(argumentos...)
Si quiero agregar un nuevo usuario, es cosa de:

Código:
wahack.registrar_usser()
Si quiero postear algo:

Código:
wahack.postear_nuevo_tema(numero)
En resumen, hace la vida mucho más fácil.

Ejercicios:
1) Para lo de la clase pasada: crear una clase "batalla" para que peleen paladines y magos. Los combates serán 1 vs 1, el daño causado se calculará mediante la fórmula: estadistica_ataque*nivel_atacante/estadistica_defensa*random.randint(85, 100)/100. Tanto la clase paladín como la clase mago deben tener los métodos atacar y curarse. El ataque de los magos consume mana.
2) Completar la clase foro para poder: ver un tema y poder responder un tema, van a necesitar modificar un poco los atributos.
3) Agregar el método atacar (orden superior) a la clase pokémon que hicieron la clase pasada, también el método ganar experiencia y el método subir de nivel. Link de interés.


 
Última edición:

Jason

PkPower déjame poner tildes en mi nick ¬¬
Clase 16: programación orientada a objetos III



Clase 16: programación orientada a objetos III

Hoy veremos algunos métodos especiales de la programación orientada a objetos y cómo crear métodos o funciones con argumentos con un valor por defecto.

Argumentos con valores por defecto:

Al definir una función, podemos hacer que algunos argumentos, si no son ingresados por el programador, simplemente tomen un valor que les hayamos dado con anterioridad. Para esto es necesaria la siguiente sintaxis:

Código:
def funcion(arg1, arg2, ..., argA=valor_por_defecto, argB=valor_por_defecto, ...etc.):
En un ejemplo:

Código:
def imprimir_num(num=0):
    print("El número de personas que te ama es:", num)
entonces, si nosotros ejecutamos:

Código:
imprimir_num('todas')
Se imprimirá lo que ustedes desean, pero de lo contrario si hacen:

Código:
imprimir_num()
Se imprimirá en pantalla la verdad (?).

Una cosa más: los argumentos con valores por defecto deben ir al final de todo el resto.

Métodos especiales:

En esta clase estademos trabajando con la clase tablero que les dejo aquí:

Código:
class tablero:
    tab = None
    filas = 0
    columnas = 0

    def __init__(self, filas, columnas, cero='0'):
        self.tab = []
        self.filas = filas
        self.columnas = columnas
        for i in range(filas):
            fila = []
            for j in range(columnas):
                fila.append(cero)
            self.tab.append(fila)

    def marcar(self, fila, columna, marca):
        self.tab[fila][columna] = marca

__str__(self)

Si nosotros intentamos usar la función print en la instancia de una clase, nos mostrará en pantalla el espacio en memoria que ocupa, algo como esto:

<__main__.tablero object at 0x05F0B9B0>

Para cambiar esto, nosotros crearemos el método __str__(self) y en el retorno irá el string que querramos que imprima en pantalla. Ej:

Código:
    def __str__(self):
        string = []
        for i in range(self.filas):
            string.append('  '.join(self.tab[i]))
        return '\n'.join(string)
Eso lo añadimos como método a la clase, dejándola:
Código:
class tablero:
    tab = None
    filas = 0
    columnas = 0

    def __init__(self, filas, columnas, cero='0'):
        self.tab = []
        self.filas = filas
        self.columnas = columnas
        for i in range(filas):
            fila = []
            for j in range(columnas):
                fila.append(cero)
            self.tab.append(fila)

    def marcar(self, fila, columna, marca):
        self.tab[fila][columna] = marca

    def __str__(self):
        string = []
        for i in range(self.filas):
            string.append('  '.join(self.tab[i]))
        return '\n'.join(string)
Entonces ahora sí funciona:




__getitem__(sef, index)

Pongámonos en el caso que quiero saber el valor de la casilla (2, 3) del tablero, para ello tendría que escribir:

n.tab[2][3]

Pero si los nombres son más largos, es mucho código y poco conveniente, entonces hacemos lo siguiente: creamos el método __getitem__ que nos va a permitir la sintaxis:

Código:
n[2][3]
Primero: el código del método.

Código:
    def __getitem__(self,pos):
        return self.tab[pos]
La sintaxis n[index] invoca una vez el método getitem para retornar un objeto, en este caso, retornará una de las filas del tablero, pero si nosotros escribimos n[index1][index2] obtendremos primero el objeto que retorna n[index1], al que le aplicamos nuevamente el método con objeto_resultante[index2] y como objeto_resultante es simplemente una lista, nos dirá la posición de la casilla que deseamos.


Ejercicios:
1. Ya tienen la clase pokémon con sus atributos, los métodos atacar, ganar experiencia y subir_nivel. Bueno, ahora deberán crear la clase Campo de batalla donde transcurrirá el combate. Y la clase entrenador, que deberá poder cambiar de pokémon de su equipo, tener mochila, ficha de entrenador, capturar pokémon salvajes y acceder al pc para depositar, sacar o mover pokémon. PC es otra clase. También agreguen el método curar a la clase pokémon.

2. [100% opcional; desafío] De las clases pasadas tenemos la clase paladín y la clase hechicero, cada una con sus atributos. Ahora: crearán la clase monstruo. A cada una de esas clases les pondrán los métodos "atacar", "defender" y "moverse por tablero*". Además, los paladines y los hechiceros deberán tener los métodos: curar, usar objeto(orden superior), sacar botín de un monstruo, ganar experiencia y subir de nivel. Inventen buenas fórmulas para todo esto.
(* = EL TABLERO DEBERÁ SER DE CELDAS HEXAGONALES, no cuadradas)
Imagen de referencia:

Para moverse, se puede ir a cualquiera de las seis celdas que rodean una casilla y se gasta un punto de movimiento por cada celda que se mueve.

Enjoy~

 

Jason

PkPower déjame poner tildes en mi nick ¬¬
Respuesta: Clase 17: ordenamiento

Clase 17: ordenamiento

En programación el problema del ordenamiento sigue vigente por todas las aplicaciones que lo demandan. En python lo tenemos medianamente resuelto porque python trae su propia función y método de ordenamiento: sorted() y lista.sort()

Tomemos una lista de números desordenada,
Código:
a = [1, 4, 2, 7, 5, 6, 3, 9, 18, 0]
La función sorted se usa así:
Código:
b = sorted(a)
print(b)
Código:
[0, 1, 2, 3, 4, 5, 6, 7, 9, 18]
Retorna una lista ordenada de menor a mayor (orden creciente).

En fambio, el método sorted:
Código:
a = [1, 4, 2, 7, 5, 6, 3, 9, 18, 0]
a.sorted()
print(a)
Código:
[0, 1, 2, 3, 4, 5, 6, 7, 9, 18]
Sobreescribe la misma lista con su contenido ordenado de forma creciente.

¿Y si queremos que sea un orden decreciente?

Código:
b = sorted(a, reverse = True)
a.sort(reverse = True)
o usar

Código:
a= [1, 4, 2, 7, 5, 6, 3, 9, 18, 0]
a.sort()
a.reverse()
luego de ordenarla.


Algoritmos de ordenamiento:

Para ordenar existen nuAquí entran en juego los métodos de ordenamiento que nosotros podemos programar. Les recomiendo no hacer una sobrecarga de la función sorted() para esto, sino crear una con otro nombre. Les voy a mostrar tres métodos:

1. Ordenamiento por selección:

Imaginemos nuevamente una lista de números o de elementos cualesquiera, para ordenarla podemos buscar el elemento menor de todos y cambiarlo por el que está en segunda posición. Luego, buscamos el segundo elemento menor de todos y lo cambiamos por el que esté en la segunda posición, luego el tercero y así hasta terminar con toda la lista.
Les pongo un vídeo que lo grafica:




2. Ordenamiento por insersión:

Aquí recorreremos la lista, para cada número n buscaremos desde el principio hasta el anterior a n una posición i donde: lista<=n<=lista[i+1].
Luego, usamos los métodos de la clase lista: insert(index, obj) y pop(index) para sacar el elemento en el que estamos mirando y luego insertarlo en la posición i con insert.
Ej: del método insert.
Código:
a = [1, 2, 3, 5, 3]
a.insert(2, "holi")
print(a)
Código:
[1, 2, 'holi', 3, 5, 3]

Vídeo:




3. Bubble sort:

El ordenamiento de burbuja, a diferencia de los dos anteriores, requiere pasar varias veces por la lista, sin embargo es más sencillo de programar. Este algoritmo recorre la lista de inicio a fin* comparando el valor de una posición con el siguiente, si lista <= lista[i+1], no hace nada, de lo contrario, los intercambia.


Vídeo:




(*) = si se fijan, en el vídeo, la cota superior a la que llega es una a partir de la que todo ya está ordenado.


¿Y qué pasa con objetos?

Para ordenar objetos es indispensable poder compararlos, y para ello usamos unos métodos especiales:
(Ojo, los guiones bajos son dobles: _ _)

op. metodo
> __gt__
< __lt__
>= __ge__
<= __le__
== __eq__
!= __ne__


A continuación les dejo la clase "persona" con la implementación de estos métodos.
Código:
class persona:
    def __init__(self, nombre, edad):
        self.nombre = nombre
        self.edad = int(edad)
    def __str__(self):
        return '('+self.nombre+', '+str(self.edad)+')'
    def __gt__(self, otro):#mayor que
        return self.edad > otro.edad
    def __eq__(self, otro):#igual que
        return self.edad == otro.edad
    def __lt__(self, otro):#menor que
        return self.edad < otro.edad
    def __ge__(self, otro):
        return self.edad >= otro.edad
    def __le__(self, otro):
        return self.edad <= otro.edad
    def __ne__(self, otro):
        return self.edad != otro.edad

a = [persona('pedro', 95), persona('julia', 18), persona('alfonso', 25)]

print(*sorted(a), sep='\n')

Ejercicios:
1. Programar la función selection_sort.
2. Programar la función insertion_sort.
3. Programar la función bubble_sort.
4. Hacer un programa que ordene una lista de tuplas con el formato (autor, año_publicación) de acuerdo al autor y para cada autor, en función del año de publicación. Los autores se colocan en orden alfabético y los años de publicación: el más reciente primero.



Anexo: mejores vídeos

A petición de @Berserker1523 les dejo otros vídeos más entendibles.

Selection sort:




Insertion Sort:




Bubble Sort:

 
Última edición:

Jason

PkPower déjame poner tildes en mi nick ¬¬
Clase 18: búsqueda



Clase 18: búsqueda

Bien, ya sabemos ordenar listas. ¿Ahora qué? A buscar. Esta clase les voy a enseñar dos formas de búsqueda que les pueden ser útiles, la primera es la más obvia y la segunda tiene su gracia.


1. Búsqueda secuencial o lineal:


En realidad este algoritmo no tiene nada especial, simplemente es recorrer la lista de principio a fin comparando el valor de cada posición con el buscado (o ver si encaja en las características deseadas).

2. Búsqueda binaria:

Aquí viene lo interesante: lo primero que necesitamos es que la lista esté ordenada de manera creciente. Teniendo eso y el dato que buscamos, a continuación tomaremos el valor de la posición cero, la del centro y la final. A continuación comparamos: ¿el dato que buscamos está en el tramo 0 - centro o centro - final? Ahora tomamos como lista el lado que nos interesa y repetimos el proceso de ir cortando la lista hasta llegar a una lista de largo reducido y hacer una búsqueda secuencial en esta o continuar cortando hasta dar con el valor en una de las tres posiciones que estamos revisando: los dos extremos y el centro.

También se puede seguir la misma idea y hacer una "búsqueda ternaria", "cuaternaria" y así, haciendo dos y tres cortes al centro, respectivamente, o más.

Idea demente:

Mientras escribía esta clase se me ocurrió esto. Tomemos una lista de objetos muy grande. La búsqueda secuencial está descartada por el tiempo y la binaria porque no podemos alterar su orden (el orden en el que está es útil). No vamos a guardar copias de la lista ordenada según varios criterios porque ocuparía demasiado espacio en memoria. ¿Qué podemos hacer? Pensemos en lo que hace una persona; la primera vez se demorará bastante recorriendo la lista, pero luego cuando necesite buscar de nuevo surgirá el "me acuerdo que por aquí estaba algo parecido". Sí, parametricemos la lista.

Con parametrizar me refiero a que establezcamos rangos aproximados, si los objetos tuvieran atributo numérico entre 1 y 1000, creemos particiones cada 100 números y guardemos en archivos separados (particion1, parcicion2, ..., particion10) los índices de los objetos en la lista principal cuyo atributo numérico está en ese rango. Luego repetimos el proceso para los diversos atributos de cada objeto particionando en aproximaciones generales. Luego, imaginemos que queremos todos los objetos que cumplen con tres criterios, en lugar de hacer tres búsquedas secuenciales en toooda la lista (o una si "optimizamos" (el código se vería más feo y sería una función para cada combinación o una sección de código para cada combinación, al final, un monstruo horrible que no se entiende ni él)) simplemente intersectamos tres conjuntos pequeños según en qué intervalo cae cada característica y encontramos lo que queríamos. Lo dejo como idea.


Ejercicios:

1. Programar una búsqueda secuencial (lista de objetos, 3 criterios (manejados como strings) mínimo).
2. Programar una búsqueda binaria, ternaria y cuaternaria y comparar su rapidez. ¿Cuál es más rápida? (lista de objetos, dos atributos buscables).
3. Hacer un programa que parametrice la pokédex regional (johto, pokémon HG/SS) en base a: tipo (ambos, sin distinción entre primario y secundario y otro con distinción de primario y secundario), num dex, color, estatura, peso y localización (ruta en johto). Pásenlo bien.

Nota: les recomiendo orientar los ejercicios 1 y 2 a búsqueda en la pokédex, rutas... cosas así en pokémon.

 

Jason

PkPower déjame poner tildes en mi nick ¬¬
Clase 19: Recursividad

Clase 19: Recursividad
(Última clase)
Aviso: de los nueve alumnos, cero entregaron la tarea 2. No habrá una tercera tarea y esta es la última clase de la escuela.

Sucesión recursiva en matemática (acercamiento):

En matemática una sucesión recursiva es una tal que el n-ésimo valor de la sucesión dependerá del (n-1)-ésimo valor de la misma. En un ejemplo:

a_0 = 2
a_n = a_(n-1)**4 - 30

Entonces, a_3 = a_2**4 - 30, a su vez
a_2 = a_1**4 - 30 y finalmente
a_1 = a_0**4 - 30 = 2**4 - 30 = 16 - 30 = -14
Luego continuamos reemplazando y a_3 = 2171158033437119986.
Tenemos un caso base y lo que pasa para todos los otros.

Funciones recursivas en python:

Programar una función recursiva es muy sencillo, el código para el ejemplo anterior sería:
Código:
def f(n):
    if n==0:
        return 2
    else:
        return f(n-1)**4 - 30

print(f(3))

Otros ejemplos:

Fibonacci:
La sucesión de fibonacci es: 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
Patrón: para calcular un término n sumo los términos n-1 y n-2, ejemplo: 34 = 21 + 13.
Código:
def fib(n):
	if n == 0:
		return 1
	elif n == 1:
		return 1
	else:
		return fib(n-1) + fib(n-2)
Factorial recursivo:
Recordarán que podemos calcular el factorial de un número con un ciclo, pero también podemos hacerlo recursivo y el código se vería así:
Código:
def factorial(n):
	if n==0:
		return 1
	elif n==1:
		return 1
	else:
		return n * factorial(n-1)
Es un código visualmente más sencillo pero consume mucha memoria porque mantiene abiertos todos los procesos a la vez, si le pidiera el factorial de 5000 abriría 5000 veces la función manteniendo todo eso cargado en memoria antes de comenzar a cerrar haciendo las multiplicaciones del caso. Y de hecho, eso no pasa porque me llora antes.



Ejercicio:
1. Programen el método de ordenamiento mergesort (link).

 
Estado
Cerrado para nuevas respuestas.
Arriba