No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Convierte tus certificados en títulos universitarios en USA

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

18 Días
14 Hrs
0 Min
48 Seg

Desarrollando la simulación

7/24
Recursos

Aportes 135

Preguntas 31

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

El problema es que el profesor Aroesti IMPLEMENTA directo sus algoritmos, sin explicar el proceso mental o lógico que lo llevo a saber que ese algoritmo es el mejor. Eso provoca que nosotros solo veamos como escribe código sin saber EXACTAMENTE cuál es el propósito de lo que el profesor programa. Por favor Aroesti, si ves este mensaje trata de incluir en estos videos una pequeña sección al inicio que nos explique de manera GRÁFICA qué es lo que intentas lograr con cada clase de tu código y CÓMO SE RELACIONAN ENTRE SÍ.

Estuvo muy pesada la clase, creo que muchos estamos solo copiando el código para que quizás más adelante podamos entender. Faltan muchas explicaciones.

Realice este código no pensando en la solución planteada por el tutor, sino estableciendo una logica lógica para solucionar este ejercicio. Por lo que mi código es muy diferente a lo anteriormente planteado basándome en la ejecución de 3 pasos:

  1. Decidir sobre que eje me voy a desplazar
  2. Realizar desplazamiento calculando la posición final
  3. Actualizar las listas para obtener el tracking del camino recorrido

Módulo Principal
La lógica de este módulo parte del entendimiento que al momento de graficar el plot final, deben estar almacenados en dos listas los movimientos realizados por el “borracho” (pasos_x, pasos_y), como esta probabilidad de decisión es del 25% (arriba, abajo, izquierda, derecha) en cada paso, es importante entender que si la decisión de desplazarse fue sobre el eje horizontal (pasos_x) no debe afectar los valores correspondientes al eje vertical (pasos_y) y viceversa; por tal motivo en el módulo principal únicamente se toma la decisión de realizar el movimiento de manera vertical u horizontal.
Módulo de movimiento
Una vez decidido el eje sobre el cual se va a realizar el movimiento se determina hacia dónde va a ser realizado el siguiente paso (positivo o negativo) de manera aleatoria, como este afecta de forma iterativa la última posición del sujeto “borracho” debe obtenerse la última posición y aplicarle el respectivo movimiento.
Como ejemplo podría tomarse el caso de que durante la simulación el borracho decidió caminar un paso hacia la derecha X 1 y el siguiente paso es hacia la izquierda 1  X por lo que la posición final será el mismo lugar de partida (por esa razón el sujeto esta “borracho” xD), en términos de programación el número de pasos realizados fueron 2 aumentando el tamaño de la lista, pero el ultimo valor es cero, reflejando la acción de dar un paso y luego devolverse.
La lista debería tener estos valores:
pasos_x =
[0 --> origen / paso 0 /
1 --> derecha / paso 1
0] --> izquierda / paso 2 / vuelvo al origen
Como todos los pasos fueron en el eje horizontal el vertical debe permanecer vacío
[0 --> paso 0
0 --> paso 1
0] --> paso 2
Módulo de igualación de listas
Este modulo únicamente iguala el tamaño de las listas repitiendo el ultimo valor en la lista sobre la que no se efectúa ningún desplazamiento.
Ya con las listas actualizadas y todos los pasos realizados solo me queda graficar las dos variables para ver el “camino del borracho”

import os
import random as random
from bokeh.plotting import figure, output_file, show
os.system('cls')

# Inicializa las listas 

pasos_x = [0]
pasos_y = [0]

# Módulo de movimiento

def mover(pasos):
    #print(f'iteracion: {i}')
    move = random.choice([-1, 1])
    #print(f'choice: ({move})')
    last = len(pasos)
    delta = pasos[last-1] + move
    pasos.append(delta)
    #print(pasos)
    return pasos

# Módulo de igualación de listas

def equal_array(pasos):
    last = len(pasos)
    pasos.append(pasos[last-1])
    return pasos

# Módulo Principal

def random_direction(pasos_x, pasos_y, num):
    for i in range(num):
        direc = random.choice([-1,1])
        if direc == -1:
            #print(f'Horizontal')
            pasos_x = mover(pasos_x)
            pasos_y = equal_array(pasos_y)
        else:
            #print(f'Vertical')
            pasos_y = mover(pasos_y)
            pasos_x = equal_array(pasos_x)
    #print(pasos_x,pasos_y)
    return pasos_x, pasos_y

# Inicio del programa con ingreso de cantidad de pasos mediante consola

num = int(input('Numero de pasos aleatorios: '))
random_direction(pasos_x, pasos_y, num)

# Modulo de plotting

output_file("line.html")
plot = figure(plot_width=600, plot_height=600)
plot.line(pasos_x, pasos_y, line_width=2)
show(plot)

Me gustan los temas que quieren abordar con esta serie de cursos de python, pero un problema como este deberia tener una explicación (whiteboarding) previa, para entender lo que vamos a hacer, pues creo que al final del dia solo estamos viendo como David escribe codigo y tendremos que entender todo por nuestra cuenta.

Yo soy nueva programando y me costo casi que todo el día para poder entender esto, pero luego de rayar bastante en el cuaderno, repasar, buscar más información y hacer unas pruebas en la terminal creo que pude entenderlo. Aqui van mis recomendaciones:

Hagan un diagrama UML de las clases. Yo lo hice en la clase pasada y aunque no es perfecto me ayudo a entender las dependencias entre clases. Sabiendo esto se hace más facil entender lo que viene. Dejo el UML que hice por aquí:

Analicen el orden del código y vayan armándolo función por función. Por ejemplo, la “primera” función que se ejecuta es main(), que a su vez, tiene en sí misma la funcion simular_caminata(), que tiene al mismo tiempo la funcion caminata(). Si lo hacen en papel les va a quedar algo así:

Si escriben el código linea por linea y funcion por funcion se darán cuenta que le programa en esencia lo que hace es:

  1. Mover el borracho x pasos y en cada paso registrar su nueva coordenada.
  2. Añadir esa nueva coordenada a una lista de distancias recorridas
  3. Hacer operaciones con la lista de distancias recorridas.

Espero que ayude, he visto muchos comentarios en donde se quejan sobre la falta explicación del código, pero creo que esa es justamente la parte que nos toca a nosotros: desarrollar herramientas para entender por nosotros mismos el código. No siempre va a haber alguien que nos las haga fácil.

Estos cursos son muy buenos, pero podrian ser mucho mejor si se explicaran los algoritmos en vez de solo implementarlos, tienen ejemplos claros en los cursos de Freddy, el explica graficamente y luego implementa. No me gusta comparar pero con esa metodologia estos cursos estarian a un nivel muy alto. Ojala en proximos cursos de David podamos ver eso ya que el es sin duda uno de los mejores profesores.

Hola, si a alguno le costó algo de trabajo entender el código tal vez este colab (Jupyter Notebook de Google) les sirva, tiene el código en un sólo documento junto con la documentación para ir siguiendolo. Saludos.

https://colab.research.google.com/drive/1wQD3jQcXzsYnTr6s98W0QtCOhgU3-x-F?usp=sharing

Creo que la forma correcta seria que primero explicara de manera grafica que debemos hacer para nosotros también tener algún precedente y no solo copiar el código conforme el profesor lo escribe

No se porque, pero los últimos cursos que he visto de David, he sentido que su forma de explicar ha desmejorado… pareciera mas una demostración de lo que el sabe hacer y no una clase donde se enseñe a hacer algo… puede ser que sea yo, pero la verdad siento que para aprender basicamente me toca tomar el titulo del tema e ir a investigar a otra parte, porque aqui solo veo lo que el Profe hace pero no explica el porque de las cosas…

Sería bueno que el profesor comentara el código a medida que lo va escribiendo para mejorar el entendimiento de los algoritmos

camino_aleatorio.py


from borracho import BorrachoTradicional
from campo import Campo
from coordenada import Coordenada

def caminata(campo, borracho, pasos):
	inicio = campo.obtener_coordenada(borracho)

	for _ in rango(pasos):
		campo.mover_borracho(borracho)

	return inicio.distancia(campo.obtener_coordenada(borracho))


def simular_caminata(pasos, numero_de_intentos, tipo_de_borracho):
	borracho = tipo_de_borracho(nombre = 'David')
	origen = Coordenada(0,0)
	distancias = []

	for _ in range(numero_de_intentos):
		campo = Campo()
		campo.anadir_borracho(borracho, origen)
		simulacion_caminata = caminata(campo, borracho, pasos)
		distancias.append(round(simulacion_caminata, 1))

	return distancias

def main(distancias_de_caminata, numero_de_intentos, tipo_de_borracho):
	
	for pasos in distancias_de_caminata:
		distancias = simular_caminata(pasos, numero_de_intentos, tipo_de_borracho)
		distancia_media = round(sum(distancias) / len(distancias), 4)
		distancia_maxima = max(distancias)
		distancia_minima = min(distancias)
		print(f'{tipo_de_borracho.__name__} caminata aleatoria de {pasos}')
		print(f'Media = {distancia_media}')
		print(f'Max = {distancia_maxima}')
		print(f'Min = {distancia_minimas}')

if __name__ == '__main__':
	distancias_de_caminata = [10,100,1000,10000]
	numero_de_intentos = 100

	main(distancias_de_caminata, numero_de_intentos,BorrachoTradicional)

Estuvo muy buena esta serie de el camino de borrachos, aplicamos al mismo tiempo varios conocimientos adquiridos en cursos y clases pasadas

Aunque creo que David podría asignar nombres un poquito mejores para algunas variables y así lograr un mejor entendimiento del código… Por ejemplo: La lista declarada como “distancias_de_caminata” no tiene mucho que ver con su significado y funcionamiento en el código… ya que en realidad esa lista no guarda las distancias de las caminatas de los borrachos… mas bien guarda las 4 cantidades diferentes de pasos (10, 100, 1000 & 10000 pasos) que va a dar un borracho en la simulación.

Saludos y que Viva México!! ❤️

esta es la parte cuando te sientas con los codos sobre las rodillas y aumentas tu concentración al maximo en pleno juego de play station.


from borracho import BorrachoTradicional
from campo import Campo
from coordenada import Coordenada

#Obtiene la distancia entre la 1ra coord y la ultima
def caminata(campo, borracho, pasos):
	inicio = campo.obtener_coordenada(borracho) #Obtenemos la coordenada (0,0) ,el origen
	#inicio es el objeto coordenada de la clase Coordenada, aca esta el truco

	for _ in range(pasos): #Pasos = 10, aca se va a mover 10 veces, luego 100 y asi
		campo.mover_borracho(borracho) 
	
	"""def mover_borracho(self, borracho): 
        delta_x, delta_y = borracho.camina()
        coordenada_actual = self.coordenadas_de_borrachos[borracho]
        nueva_coordenada = coordenada_actual.mover(delta_x, delta_y)
        self.coordenadas_de_borrachos[borracho] = nueva_coordenada"""


	return inicio.distancia(campo.obtener_coordenada(borracho))
	#Sacamos la distancia entre la primera coordernada (0,0) y la ultima despues de los 10 pasos

#Numero de intentos siempre es 100
#Pasos : 10, 100, 10000, 100000
def simular_caminata(pasos, numero_de_intentos, tipo_de_borracho):
	borracho = tipo_de_borracho(name = 'David') #obj de la clase Borracho
	#Crea un objeto de la clase Coordenada
	origen = Coordenada(0,0)
	distancias = []

	for _ in range(numero_de_intentos): #100 veces 
		#Objeto de la clase campo
		campo = Campo()
		campo.anadir_borracho(borracho, origen) #campo tiene borracho(Borracho) y origen(Coordenada)
		simulacion_caminata = caminata(campo, borracho, pasos) #Obtenemos una distancia
		distancias.append(round(simulacion_caminata, 1))

	return distancias
	#Obtenemos 100 distancias y la anexamos a la lista

def main(distancias_de_caminata, numero_de_intentos, tipo_de_borracho):
	
	for pasos in distancias_de_caminata: 
		#Obtenemos 100 distancias por cada paso
		distancias = simular_caminata(pasos, numero_de_intentos, tipo_de_borracho)
		#Aca sacan la media y todo eso
		
		
if __name__ == '__main__':
	distancias_de_caminata = [10,100,1000,10000]
	numero_de_intentos = 100

	main(distancias_de_caminata, numero_de_intentos,BorrachoTradicional)```

Realmente no es dificil el algoritmo, de hecho es bastante sencillo.
Si escriben el código de forma procedimental veran la sencillez.

Siento que se volvió complejo porque el profe lo escribió con programación orientado a objetos desde el inicio. Lo que es bueno, porque modularizó ya los distintos componentes, y la próxima vez que escriba otro tipo de borracho solo será agregando el borracho a una clase.

cuando empece la ruta le entendía muy claro a David, incluso me anticipaba, siento que va muy rapido, y que no esta siendo claro, en este punto me han sido de gran ayuda los comentarios del curso por que ya han realizado el curso personas, con las mismas dudas y su explicación es más breve

subió bastante de nivel la clase, costo trabajo seguirla

No es dificil el codigo pero la explicacion de David es como si solo estuviera leyendo el codigo y es dificil de seguir

No es dificil el codigo, pero bastaaaaaante enredadito el borracho, por el nombre de las variables.

creo que esta clase y la pasada podían haberse dividido para hacerlas 4 clases. A veces no se entiende bien el proceso o el por qué del código, lo cual puede solucionarse con clases mas al detalle de cada parte, primero explicando de forma abstracta y luego ejecutando el código.

Deben invertir más en sus testers, este curso es un ejemplo de que nos usan como testers a los mismos alumnos que estamos pagando por productos de calidad.
Se pierde mucho tiempo, energía y motivación tratando de deducir lo que el profesor hace, o sea, parece más una demostración verbalizada de como el profesor soluciona algunas problemáticas pero no hay una explicación de la lógica detrás (algo muy similar pasa con los cursos de Ardila)
Podrían a incentivar a alumnos que apenas cumplen o que tienen ligeras carencias técnicas para aproximarse a sus cursos y evaluar a partir de ellos si el curso es accesible para todo aquel que esté en cierto margen de aprovechar la información
Y es tal vez donde se ve el impacto de una buena formación y la importancia de la Universidad en nuestra vida, hay una MUY MARCADA diferencia entre la calidad que ofrece un profesional de la talla Natalia Usme con bases bien sólidas y el como aborda la vida un simple técnico medianamente calificado.

A mi parecer, escribir tres clases para este problema es complicar demasiado las cosas. Tanto Coordenada como Campo se podrían incorporar fácilmente a Borracho. Por ejemplo:

import random
from bokeh.plotting import figure, show


class Borracho:

    def __init__(self, nombre, x=0, y=0):
        self.nombre = nombre
        self.x = x
        self.y = y

    def posicion(self):
        return (self.x, self.y)

    def distancia_origen(self):
        return (self.x**2 + self.y**2)**0.5  # Pitágoras


class Borracho_Tradicional(Borracho):

    def __init__(self, nombre):
        super().__init__(nombre)

    def camina(self):
        # Se mueve arriba, abajo, a la derecha o a la izquierda
        # devuelve uno de los cuatro vectores
        dx, dy = random.choice([(0, 1), (0, -1), (1, 0), (-1, 0)])
        self.x += dx
        self.y += dy
        return [dx, dy]


def caminata(borracho, pasos):
    inicio = [borracho.posicion()]
    x_graph = []
    y_graph = []
    for _ in range(pasos):
        borracho.camina()
        x, y = borracho.posicion()
        x_graph.append(x)
        y_graph.append(y)
    graficar_pasos(x_graph, y_graph)
    return borracho.distancia_origen()


def simular_caminata(pasos, numero_de_intentos, tipo_de_borracho):
    # Se recibe una clase como parámetro
    borracho = []
    distancias = []
    for i in range(numero_de_intentos):
        borracho.append(tipo_de_borracho(nombre=f'Daniel {i}'))
        simular_caminata = caminata(borracho[i], pasos)
        distancias.append(round(simular_caminata, 1))
    return distancias


def graficar_pasos(x_graph, y_graph):
    grafica = figure(title="Pasos aleatorios",
                     x_axis_label="Eje X", y_axis_label="Eje Y")
    grafica.line(x_graph, y_graph, legend_label="Coordenadas")
    show(grafica)


def main(distancias_de_caminata, numero_de_intentos, tipo_de_borracho):
    # distancias_media_por_caminata = []

    for pasos in distancias_de_caminata:
        # Del origen al punto final
        distancias = simular_caminata(
            pasos, numero_de_intentos, tipo_de_borracho)
        distancia_media = round(sum(distancias) / len(distancias), 4)
        distancia_maxima = max(distancias)
        distancia_minima = min(distancias)
        print(f'{tipo_de_borracho.__name__} caminata aleatoria de {pasos} pasos')
        print(f'Media = {distancia_media}')
        print(f'Max = {distancia_maxima}')
        print(f'Min = {distancia_minima}')


if __name__ == "__main__":
    distancias_de_caminata = [1000]
    numero_de_intentos = 1

    main(distancias_de_caminata, numero_de_intentos, Borracho_Tradicional)

Algo me dice que voy a ver la clase 10, 100, 1000 y 10 000 veces

Muy enredado jaja. La parte que si causa mucho conflicto es la instancia borracho en la llamada de las funciones.

A pesar de que aún debo revisar y leer el código varias veces más para comprenderlo desde la razón, mi método de aprendizaje es más el de “pongo manos a la obra” y luego voy entendiendo.
Ha estado genial el inicio de este curso. Ya estoy enganchado, me pasé del número de clases a estudiar hoy.

me parece que van muy rapido, escriben codigo y ni si quiera lo entendemos

Considero que al instructor le hace falta mas orden en su manera de desarrollo, no esta bien ya que confunde bastante

Está un poco pesado el código pero aquí les dejo el código comentado para que lo puedan entender mejor:
Recomendación: Léanlo de abajo para arriba.

from borracho import BorrachoTradicional
from borracho import BorrachoPitagorico
from campo import Campo
from coordenada import Coordenada

def caminata(campo, borracho,pasos):
    # obtenemos la coordenada y la guardamos en inicio
    inicio = campo.obtener_coordenada(borracho)

    # por cada paso que damos moveremos al borracho una vez.
    for _ in range(pasos):
        campo.mover_borracho(borracho)

    # distancia es un parámetro en la clase campo que nos regresa "distancia" :v
    return inicio.distancia(campo.obtener_coordenada(borracho))




def simular_caminata(pasos, numero_de_intentos,tipo_de_borracho):
    # invocamos al borracho, ponemos el nombre porque la clase lo pide
    borracho = tipo_de_borracho(nombre='David')

    # Iniciamos coordenada con 0,0 porque nos pide en la clase
    origen= Coordenada(0,0)
    distancia =[] #guardaremos las distancias obtenidas por la simulacion

    for _ in range(numero_de_intentos):
        #ponemos al borracho en el campo, no agregamos nada porque no pide la clase
        campo = Campo()

        # iniciamos un parámetro de la funcion
        # boracho, que recive BorrachoTracicional y origen (0,0)
        campo.añadir_borracho(borracho,origen)

        # añadimos una funcion que vamos a crear(arriba), la que nos devolverá la distancia
        simulacion_caminata = caminata(campo, borracho, pasos)
        distancia.append(round(simulacion_caminata,1))
    return distancia

def main (distancias_de_caminata, numero_de_intentos, tipo_de_borracho):
    # vamos a simular varias caminatas
    for pasos in distancias_de_caminata:
        # tomará distancia de caminata 10, 100,.. y hará correr la simulacion (se implementa arriba)
        distancias = simular_caminata(pasos, numero_de_intentos, tipo_de_borracho)

        # estos son datos adicionales de estadísticas
        # (OJO con la diferencia entre distancia y distancias)
        distancia_media = round(sum(distancias)/len(distancias))
        distancia_maxima = max(distancias)
        distancia_minima = min(distancias)
        print(f'El borracho {tipo_de_borracho.__name__} con {pasos} pasos, tiene:')
        print(f'Distancia Maxima = {distancia_maxima}')
        print(f'Distancia Minima = {distancia_minima}')
        print(f'Distancia Media = {distancia_media} \n')


if __name__ == '__main__':
    # Vamos a hacer caminar la cantidad de pasos indicados en la lista
    # Ademas se hará la simulicon un determinado número de veces
    distancias_de_caminata=[10,100,1000,10000]
    numero_de_intentos = 100

    main(distancias_de_caminata, numero_de_intentos, BorrachoTradicional)

Este vídeo tiene la PEOR pedagogía que he visto, muy malo explicando el desarrollo del código

No me hubiera importado que la clase durara 45 minutos mientras explicara bien paso por paso, dado que aun no dominamos bien todo lo que es POO y esta forma de escribir el codigo.

from prueba_prog_din import borracho_tra
from Campo_borracho import Campo
from Coord_borracho import Coordenada

def caminata(campo,borracho,pasos):
    inicio = campo.obtener_coordenada(borracho)

    for i in range(pasos):
        campo.mover_borracho(borracho)

    return inicio.distancia(campo.obtener_coordenada(borracho))


def simular_caminata(pasos, numero_intentos,tipo_borracho):
    borracho= tipo_borracho(nombre='Fernando')
    origen= Coordenada(0,0)
    distancias= []

    for _ in range(numero_intentos):
        campo= Campo()
        campo.anadir_borracho(borracho,origen)
        simulacion_caminata= caminata(campo,borracho,pasos)
        distancias.append(round(simulacion_caminata,1))

    return distancias


def main(distancias_caminata,numero_intentos,tipo_borracho):

    for pasos in distancias_caminata:
        distancias = simular_caminata(pasos,numero_intentos,tipo_borracho)
        distancia_media= round(sum(distancias)/ len(distancias), 4)
        distancia_maxima= max(distancias)
        distancia_minima= min(distancias)
        print(f'{tipo_borracho.__name__} caminata aleatoria de {pasos}')
        print(f'Media={distancia_media}')
        print(f'Maxima= {distancia_maxima}')
        print(f'Minima= {distancia_minima}')


if __name__ == '__main__':
    distancias_caminata=[10,100,1000,10000]
    numero_intentos= 100

    main(distancias_caminata,numero_intentos,borracho_tra)


Al profesor aquí se le olvidó retornar en el método simular_caminata.
Para entender este tipo de códigos les recomiendo ir haciendo comentarios en su propio código describiendo cada acción, así tendrán una mayor idea de lo que se desea lograr. Aquí les dejo mi código comentado.

from drunk import TraditionalDrunk
from field import Field
from coordinates import Coordinate


def walk(field, drunk, steps):
    # Wich is te starting position of the drunk
    startingPoint = field.getCoordinate(drunk)

    # For each step we move the drunk
    for _ in range(steps):
        field.moveDrunk(drunk)
    # Finally we get the distance between the starting position of the drunk and the final position after walk n steps
    return startingPoint.getDistance(field.getCoordinate(drunk))


def simulateWalk(steps, iterations, DrunkType):
    drunk = DrunkType(name='Henry')
    startingPoint = Coordinate(0, 0)
    distancesTraveled = []

    # We will execute the simulation n times
    for _ in range(iterations):
        field = Field()
        field.addDrunk(drunk, startingPoint)
        distanceWalked = walk(field, drunk, steps)
        distancesTraveled.append(round(distanceWalked, 1))

    return distancesTraveled


def main(stepsList, iterations, DrunkType):

    # For each step we create a simulation
    for steps in stepsList:
        distancesTraveled = simulateWalk(steps, iterations, DrunkType)

        # Formula media => SUM(elementos) / LEN(elementos)
        # round(MEDIA, 4) => 4 = 3 decimales
        midDistance = round(sum(distancesTraveled) / len(distancesTraveled), 4)
        maxDistance = max(distancesTraveled)
        minDistance = min(distancesTraveled)
        print(f'{DrunkType.__name__} random walk of {steps} steps')
        print(f'Mid distance: {midDistance}')
        print(f'Max distance: {maxDistance}')
        print(f'Min distance: {minDistance}')


if __name__ == '__main__':

    # setepList represent the number of steps that the drunk will make
    stepsList = [10, 100, 1000, 100000]

    # how many times we will execute the simulation
    iterations = 100

    main(stepsList, iterations, TraditionalDrunk)

Apoyo la moción de que David es un excelente profesor, pero sería bueno que se expliquen los algoritmos en gráficas antes de su despliegue en código, los conceptos se explican muy bien, pero si no hay una visualización, es dificil que se queden en la memoria a largo plazo.

esta clase de una me mando a revisar anteriores

creo que estoy solo copiando codigo porque la verdad, estoy un poco perdido en esto, y no es lo que yo esperaba de este curso la verdad.

Demasiado velocidad, no explica nada, solo escribe código. Confunde mucho con los métodos

Dudas: Muchas, Razon, Nose, Perdido? Si…

Esta muyinteresante, pero todo el codigo de golpe fue muy repentino

ENTENDIBLES LAS MOLESTIAS: pero hay distintos métodos para aprender por INDUCCION, como es el caso de la plataforma de Platzi.

  • primera solución: comentar el programa que proporciona el docente, o el que tu vayas desarrollando.

  • segunda solución: hacer tu propio diagrama de flujo, a partir del programa que implementa el docente.

  • tercera solución: traducir a pseudocodigo lo que vas leyendo

  • es decir, razonamiento inductivo.

  • NOTA: estos nos son cursos introductorios, mas bien son cursos complementarios para personas que tienen una base de años de práctica construyendo algoritmos.

  • es entendible la molestia, pero … es la forma en que se enseña en este nivel.

  • talvez Platzi puede darles un curso muy basico, para los que tienen dificultad en traducir algoritmos

No puedo ni programar una borrachera con mis amigos y creen que yo podría programar de la nada algo así? ToT
.
Ya fuera de chiste, les comparto mi código con comentarios que me ayudó a medio entenderlo un poco mejor.
.

from borracho import BorrachoTradicional
from coordenada import Coordenada
from campo import Campo

def caminata(campo, borracho, pasos):
    inicio = campo.obtener_coordenadas[borracho] # Método creado en Campo

    for _ in range(pasos):
        campo.mover_borracho(borracho) # Método creado en campo para cambiar la posición y guardar las coordenadas

        return inicio.distancia(campo.obtener_coordenadas(borracho)) # Método creado en Coordenada para calcular la distancia entre coordenadas


def simular_caminata(pasos, numero_de_intentos, tipo_de_borracho):
    # Me trae cualquier tipo de borracho sin importar su tipo 
    borracho = tipo_de_borracho(nombre = 'Sumatra')
    # La clase Coordenada recibe como parámetros (x, y)
    origen = Coordenada(0, 0)
    # Diccionario que va guardando las distancias
    distancias = []

    # Por cada intento en un numero_de_intentos
    # _ quiere decir que no usamos la variable
    for _ in range(numero_de_intentos):
        campo = Campo() # Genero el campo con la clase, la cual no recibe parámetros
        campo.agregar_borracho(borracho, origen) # Método creado en campo

        simulacion_caminata = caminata(campo, borracho, pasos) # Es para ver el resultado de la simulación y usa una f(x) auxiliar
        
        distancias.append(round(simulacion_caminata, 1)) # Agregamos las distancias de la simulación de la caminata sin decimal

        return distancias


def main(distancias_de_caminata, numero_de_intentos, tipo_de_borracho):
    for pasos in distancias_de_caminata:
        distancias = simular_caminata(pasos, numero_de_intentos, tipo_de_borracho)
        
        # Suma de las distancias dividido el número de distancias, redondeado a 3 decimales. 4 = 3 en "round()"
        distancia_media = round(sum(distancias) / len(distancias), 4)

        distancia_max = max(distancias)
        distancia_min = min(distancias)

        # Imprimimos estadísticas descriptivas de lo que sucede
        print(f'{tipo_de_borracho.__name__} caminata aleatoria de {pasos}')
        print(f'Media = {distancia_media}')
        print(f'Max = {distancia_max}')
        print(f'Min = {distancia_min}')


if __name__ == "__main__":
    distancias_de_caminata = [10, 100, 1000, 10000]
    numero_de_intentos = 100

    main(distancias_de_caminata, numero_de_intentos, BorrachoTradicional)

veo que muchos comentarios se basan en a falta de explicacion grafica, veo que ya se corrigio, sin embargo, algo que me sucedio es que el codigo al inicio no corria, ello me abstrajo por varias horas, llevandome incluso a pensar en el codigo hasta cuando almorzaba, despues de revisar todo nuevamente por ‘n’ vez, encontre la solucion. Moraleja, sigamos intentando, repasemos los pasos hasta que calen en nuestro pensamiento, ningun curso es perfecto, nuestro esfuerzo lo hace!

A veces, de verdad caen en lo negligente. Se supone que nos están capacitando en temas que sus capacitadores deberían estar capacitados.

Opte por ir a ver otros tutoriales en youtube y cursos de pago, ya que tengo la misma impresión de los compañeros, no se explica la lógica de por que hacer las cosas de una manera clara, se supone nos estamos formando. He visto y aprobado los primeros 4 cursos de la ruta de Data Sciene pero con este curso me siento muy desanimado.

Saludos amigos. He leído comentarios sobre lo difícil que han sentido esta clase en particular, y los entiendo. Como dijo David en un video previo, él no suele usar diagramas, va diseñando la solución conforme programa, y cada uno puede usar una metodología diferente. A mi me funciona desarrollar el código en un Jupyter Notebook que me permita ir interactuando con el código conforme voy avanzando. Se los sugiero si quiere poder probar bloques de código especifico en lugar de ejecutar todo el bloque cada vez que quieran probar como funciona.

Les comparto mi implementación con documentación en cada función, parar que vayan viendo como documento cada función y sé en todo momento que hace la función que voy llamando:

import random

class Borracho:

    def __init__(self, nombre):
        self.nombre = nombre

class BorrachoTradicional(Borracho):
    
    def __init__(self, nombre):
        super().__init__(nombre)

    def caminar(self):
        return random.choice([(0,1), (1,0), (0,-1), (-1,0)])

class Coordenada:

    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def mover(self, delta_x, delta_y):
        return Coordenada(self.x + delta_x, self.y + delta_y)
    
    def calcular_distancia(self, otra_coordenada):
        delta_x = self.x - otra_coordenada.x
        delta_y = self.y - otra_coordenada.y

        distancia = ((delta_x ** 2) + (delta_y ** 2)) ** 0.5

        return distancia

class Campo:

    def __init__(self):
        self.coordenadas = {}
    
    def agregar_borracho(self, borracho, coordenada):
        self.coordenadas[borracho] = coordenada
    
    def mover_borracho(self, borracho):
        delta_x, delta_y = borracho.caminar()
        coordenada_actual = self.coordenadas[borracho]
        nueva_coordenada = coordenada_actual.mover(delta_x, delta_y)

        self.coordenadas[borracho] = nueva_coordenada
    
    def obtener_coordenada(self, borracho):

        return self.coordenadas[borracho]

def caminata(campo, borracho, pasos):
    """Este método ejecuta la caminata del borracho, deplazandolo 
     sobre campo la cantidad de pasos definidos en los argumentos

    Arguments : 
        campo : Instancia de la clase Campo
        borracho : instancia de la clase BorrachoTradicional
        pasos : cantidad de pasos que el borracho caminara sobre
            el campo
    
    Returns : 
        desplazamiento : Distancia que se ha movido el borracho
    """
    inicio = campo.obtener_coordenada(borracho)

    for _ in range(pasos):
        campo.mover_borracho(borracho)
    
    desplazamiento = inicio.calcular_distancia(campo.obtener_coordenada(borracho))
    
    return desplazamiento

def simular_caminata(pasos, intentos, borracho):
    """Este método simula la caminata del borracho ejecutando 
    el método caminata.

    Ejecuta una caminata por cada intento especificado, y agrega
    el resultado de la caminata a la lista distancias. 

    Arguments : 
        pasos : La cantidad de pasos que el borracho caminará en 
            cada intento
        intentos : La cantidad de veces que se simulara la caminata
        borracho : instancia de la clase BorrachoTradicional
    
    Returns :
        distancias : Lista de las distancias recorridas en cada 
            simulación
    """
    origen = Coordenada(0, 0)
    distancias = []

    for _ in range(intentos):
        campo = Campo()
        campo.agregar_borracho(borracho = borracho, coordenada = origen)
        caminata_borracho = caminata(campo, borracho, pasos)
        distancias.append(round(caminata_borracho, 1))
    
    return distancias

def main(distancias_de_caminata, intentos, borracho):
    """Este método ejecuta la simulación de la caminata e imprime 
    la máxima distancia recorrida, la distancia media y la distancia minima 
    en los diferentes intentos. 

    Arguments : 
        distancias_de_caminata : lista con la cantidad de pasos que queremos que
            el borracho camine en cada simulación
        intentos : cuantas veces se va a simular cada caminata
        borracho : instancia de la clase BorrachoTradicional
    """
    for pasos in distancias_de_caminata:
        distancias = simular_caminata(pasos, intentos, borracho)
        distancia_media = round((max(distancias) / len(distancias)), 4)
        distancia_maxima = max(distancias)
        distancia_minima = min(distancias)
        print(f'La distancia media que el borracho {borracho.nombre} se movio es {distancia_media}')
        print(f'Lo máximo que el borracho se movio es {distancia_maxima}')
        print(f'Lo mínimo que el borracho se movio es {distancia_minima}')

if __name__ == '__main__':
    distancias_de_caminata = [10, 100, 1000, 10000]
    intentos = 100
    nombre_borracho = input('Define el nombre del borrachito que va a caminar: ')
    main(distancias_de_caminata, intentos, BorrachoTradicional(nombre_borracho))

Es una clase un poco complicada de entender ya que se detienen muy poco a explicar el código.
Comparto mis apuntes donde en una sección trato de explicar el código, espero que sean de ayuda. ❤️

https://github.com/abdielgv162/Estadistica_Computacional/tree/master#explicacion-de-simulación

Hola, a mi me costó trabajo hacerlo y lo hice desde cero, lo logré con una lógica diferente pero aplicando todos los conceptos, demás de que exporta los resultados del camino de borrachos a un archivo CSV

<
import random
import csv

class persona():
    def __init__(self, nombre):
        self.nombre = nombre
        self.posicion = (0,0)
 
    def saluda(self):
        print(f'Hola mi nombre es {self.nombre} y estoy en {self.posicion}')
   
class borracho(persona):
    def __init__(self, nombre, pasos, intentos):
        super().__init__(nombre)
        self.pasos = pasos
        self.intentos = intentos

    def caminar_borracho(self):
        self.direccion_paso = random.choice([(1,0),(0,1),(-1,0),(0,-1)])
        self.recorrido_x = []
        self.recorrido_y = []
        self.contador_pasos = []
        self.contador_intentos = []
        self.nombre_borracho = []
        self.tipo_de_paso = []


        for i in range (self.intentos):
            self.nueva_x = self.posicion[0]
            self.nueva_y = self.posicion[1]
            self.nombre_borracho.append(self.nombre)
            self.recorrido_x.append(self.posicion[0])
            self.recorrido_y.append(self.posicion[1])
            self.contador_intentos.append(0)
            self.contador_pasos.append(0)
            self.tipo_de_paso.append('INICIO_DEL_RECORRIDO')

            for j in range (self.pasos):
                if j+1 == self.pasos:
                    self.tipo_de_paso.append('FIN_DEL_RECORRIDO')
                else:
                    self.tipo_de_paso.append(f'PASO_{j+1}')
                self.nombre_borracho.append(self.nombre)
                self.contador_intentos.append(i+1)
                self.contador_pasos.append(j+1)
                self.direccion_paso = random.choice([(1,0),(0,1),(-1,0),(0,-1)])
                self.recorrido_x.append(self.nueva_x + self.direccion_paso[0])
                self.recorrido_y.append(self.nueva_y + self.direccion_paso[1])
                self.nueva_x = self.nueva_x + self.direccion_paso[0]
                self.nueva_y = self.nueva_y + self.direccion_paso[1]   


    def saluda(self):
        super().saluda()
        print('Creo que estoy borracho')

class observador_del_borracho(borracho,persona):
    def __init__(self, nombre, pasos, intentos):
        super().__init__(nombre, pasos, intentos)
        pass

    def exportar_csv_rows(self):
        self.data_base_1 = [self.nombre_borracho, self.tipo_de_paso ,self.contador_intentos, self.contador_pasos, self.recorrido_x, self.recorrido_y ]
        print(self.data_base_1)
        # with open('file4.csv','w') as f:
        #     for raw in self.data_base_1:
        #         for x in raw:
        #             f.write (str(x) + ',')
        #         f.write('\n')
        with open('camino_de_borrachos.csv','w') as f:
            fieldnames = ['NOMBRE_BORRACHO', 'TIPO_DE_PASO' ,  'INTENTOS', 'PASOS', 'COORDENADA_X', 'COORDENADA_Y']
            writer = csv.DictWriter(f, fieldnames=fieldnames)
            writer.writeheader()
            for i in range( len(self.recorrido_x) ):
                writer.writerow({'NOMBRE_BORRACHO': self.nombre_borracho[i], 'TIPO_DE_PASO': self.tipo_de_paso[i] , 'INTENTOS':self.contador_intentos[i], 'PASOS':self.contador_pasos[i], 'COORDENADA_X':self.recorrido_x[i], 'COORDENADA_Y':self.recorrido_y[i]})
                pass


def run():
    persona_1 = observador_del_borracho('Fernando', 10 , 2)
    persona_1.saluda()
    persona_1.caminar_borracho()
    persona_1.exportar_csv_rows()


if __name__ == "__main__":
    run()

Dejo la misma imagen que en el video anterior, quiza ayuda a entender mejor el codigo

(

Si tienen alguna duda de por qué no les funciona el código como debería o les manda error, adjunten una captura del problema en su pregunta. Esto es para poder ayudarlos más rápido.

Revisión de lo que hace el programa.

alguien me pasa el programa que no se donde esta mi error ???

Les digo la verdad? La única forma de aprender esto es haciendo ejercicios. Uno puede entender el concepto y todo, pero de ahí a saber hacerlo, falta bastante practica.

Un poco confuso, pero vamos a dedicarle un tiempo a enteder todo el codigo.

Todos se quejan de la explicación, a esas personas les digo solo es un ejemplo más bien busquen un reto y resuélvanlo o implementen su propia versión ya vieron como funciona, les será fácil hacer su versión

Que bueno que era un ejercicio sencillo si no imaginate XD

Es un algoritmo algo complejo y mas en un lenguaje que apenas se esta aprendiendo, gracias a varios compañeros que han publicado sus analisis se ha logrado entender mejor.

Esta clase estuvo poco explicativa, es cierto que muchas delas cosas se han explicado en módulos anteriores pero considero que la diferencia de ““nivel”” entre el video anterior y este es DEMASIADO ALTA jajjajaj, aun asi intenté entender y creo que algo al menos me entró. fue interesante como agrega las cosas antes de crearlas xd

La verdad siento que si estas tomando este curso es porque ya sabes leer código, no se me hace complicado entender el como funciona, o para que tal cosa, solo escribelo y genera comentarios de lo que entiendes, así será mucho mejor tú aprendizaje.

el codigo del profe necesita ser refactorizado para hacerlo mas simple, igual esta bueno como implementa composición pero deberia tipar los datos para que se entienda mejor…

si no tipas los datos de python, esto se vuelve un caos al volver a ver tu codigo o tratar de entenderlo

Soy muy principiante en POO, pero no se si es el paradigma en si
comparado con la programación funcional, pero me da que son
demasiadas funciones, muchas de las cuales puede que no se
usen para, mover un abjeto. ademas de la complejidad de entender en profundidad la POO, tal vez deberia ir en la ruta un
curso mas profundo de POO, que lo que se ve en el curso anterior antes de poner un aplicacion tan compleja, aunque
es intuitivo lo que el profe hace es dificil de poner el reto de hacerlo uno mismo antes de ver la demostracion.

[Diagrama de flujo]

Inicio
Importar módulos
Definir función "caminata"
Definir función "simular_caminata"
Definir función "graficar"
Definir función "main"
Inicializar lista "distancias_media_por_caminata"
Bucle “for” a través de distancias de caminata
Simular varias caminatas de borracho
Calcular distancias media, máxima y mínima
Agregar distancia media a "distancias_media_por_caminata"
Graficar resultados
Mostrar gráfica
Fin

La comprensión de esta clase se facilita si se tiene experiencia previa con la programación orientada a objetos en algún lenguaje como Java, dado que el profesor David estructura su programa muy afín a las reglas que allí se siguen (recomendaría como ejercicio replicar el código en Java y verán cómo todo es muchísimo más claro y solucionará dudas sobre el uso de clases y abstracciones en funciones).

Diría que en Python es incluso más rápido y sencillo hacer una implementación como un script (sin usar paradigma POO) para este problema pero siento que lo que nos quiere enseñar el profesor sin ir a mucho detalle es que en las simulaciones y también en la inteligencia artificial debemos delimitar (para una mayor comprensión) quién es nuestro agente, cuál es el entorno del agente y cuál es su comportamiento; además de implementar algunas funcionalidades de evaluación.

El proceso de abstracción es muy importante a la hora de realizar el código, incluso la clase que se incluyó después no es lo suficientemente clara, porque explica la idea pero no explica la implementación.
Todos los cursos con Aroesti son iguales, realmente ser profesor no es lo suyo.

Es dificil enternder viendo código y escuchando al profesor, hace falta flujogramas.

Pague la suscripción a Platzi para que el aprendizaje sea más sencillo y me ayuden con la documentación y mejor explicación de lo que voy aprendiendo, y no recurrir a fuentes externas pues para eso no me hace falta gastar dinero ya que en internet hay información gratis pudiendo aprender por mi cuenta

Facundo explica con mayor claridad.

De acuerdo con un par de comentarios que leí. A esta clase le falta la explicación de la arquitectura del programa. Creo que se entiende que David la construye sobre la marcha, per sería muy bueno que hubiera esa estructura vista de una forma más gráfica ANTES de empezar a programar.
En su momento así aprendí a programar por primera vez y (al menos para quien sea como yo) es mucho más fácil entender de esa forma.

estuvo como pesada la clases, y los nombres de las variables confunden mucho…pero a seguirle

Utilizar el under score en un ciclo, es para indicar que no vamos a utilizar esa variable.

Podemos hacer, que los objetos que inicializamos, puedan variar, solo con la referencia de un parámetro.

También puedes poner _ como nombre xd

Hay que generar mucho, para estudiar una base de resultados.

La idea de las simulaciones, es correrlas muchas veces.

AYUDA, esto no es un meme!

Un algoritmo mas interesante puede hacerse con

import numpy as np
import numpy.random as rd
# random orientation converted from degrees to radians
direction = rd.uniform(low=0, high=360) * np.pi / 180
x = np.cos(direction)
y = np.sin(direction)

esto daría un aspecto circular al movimiento.

Les recomiendo este video donde explican la misma idea de Caminos borrachos pero más sencillo y de varias formas para luego comprender mejor el algoritmo que uso el profesor en esta clase.
https://www.youtube.com/watch?v=BfS2H1y6tzQ

Pienso que se debería tomar un poco más de tiempo para explicar los códigos , el objetivo no es entregar un algoritmo, el objetivo es que todos los que estamos realizando este curso podamos acceder a su entendimiento

David es excelente profesor y es brillante al momento de explicar los conceptos y concatenar ideas. Codea como excelente ingeniero y usa las palabras como excelente abogado. Sin embargo, muchos estudiantes somos visuales y es ahí cuando los modelos, diagramas o esquemas nos ayudan a entender sistémicamente (holisticamente, como un todo) aquellos conceptos y luego el código que lo operativiza.

like fredie vega

comenta david aroesti

Aún falta mucho para llegar al deep learning asi que sin miedo compañeros…estamos en las puertas de hadeesss!!

Es horrible ver cómo alguien programa sin explicar bien… me quedo con la teoría 😕

Hola.
Leyendo los comentarios, las principales quejas van sobre que no se presentan ayudas visuales y diagramas. Considero que con lo que hemos aprendido hasta aquí (siguiendo la ruta de aprendizaje), es suficiente para abordar una clase como esta. Si no se entiende el algoritmo a la primero, podemos escribir los comentarios de profe David en el código; con lápiz y papel correr el código con los primeros valores y ahí mismo trazar nuestros diagramas, entre otros métodos.
Creo que es de mucho más provecho el que nosotros mismos diseñemos nuestros propios métodos de comprensión de ejercicios a que se nos explique de manera ultra detallada cada parte del código.
Soy nuevo programando, y el entender esto es perfectamente alcanzable. Ánimo!!!

Buenas, cuando ejectuo el codigo, tal como esta en el video me resulta
’TypeError: camina() takes 0 positional arguments but 1 was given’

Me costó un poco entender éste algoritmo, tuve que ver las clases varias veces para poder implementarlo correctamente. Pero lo logré! 😁 Vamooooooossss!

a probar 😉

Pffff de verdad que desde un curso de Ardila que no me encabronaba tanto. Es increible como a temas que fundamentales les es imposible aterrizarlos en su complejidad. Con este tipo de manifestaciones catedráticas hacen quedar en ridículo su postura contra la universidad a la par que hacen ver el promedio de lo que forman es empleados copiacódigo

wow… es lo mas complejo que he hecho

Al momento de crear el objeto tipo_de_borracho(nombre==‘David’), deberia ser ‘name’ en lugar de nombre ya que el argumento de la clase BorrachoTradicional es name y al hacer la herencia de Borracho (la clase padre) convierte ese ‘name’ en self.nombre:

lass Borracho:
    """Clase para los borrachos."""

    def __init__(self, nombre):
        """Inicializa el borracho."""
        self.nombre = nombre


class BorrachoTradicional(Borracho):
    """Clase para el borracho tradicional."""

    def __init__(self, name):
        """Inicializa el borracho tradicional."""
        super().__init__(name)  <-------------------

    def camina():
        """Retorna una tupla.

        Calcula el valor aleatorio con la direccion
        a donde se mueve el borracho.
        """
        return random.choice([(0, 1), (0, -1), (1, 0), (-1, 0)])```

Un Algoritmo algo complejo, toca la verdad sentarse y enteder cada clase que lo hace. La verdad estoy aprendiendo mucho

Entendido y vamos por el borrado de David

Wow…toca ver esto más de una vez e interiorizarlo.

porque usa el init a principio de las funciones

Waooo! … mucho que procesar

Una pregunta, al importar las clases de los demás archivos es necesario que estos estén en la misma carpeta, que están abiertos en simultaneo en el editor de código o cuál es esa condición para que ese archivo al que traemos las clases reconozca ese “import”?

Yo la verdad estoy aprendiendo a manejar python, me cuesta mucho entenderle David Aroesti, no entiendo muchas funciones y la lógica detrás del código - no entiendo tampoco porque no se explica un poco del proceso mental para llegar a la solución del código y porque se tomaría ese camino y no otro. Siento que es muy bueno en lo que hace pero quizás falta bajarle un cambio e ir un poco más despacio, quizás lo que se hace sea intuitivo para alguien que tenga algo de conocimiento, pero para mi seguirle el paso y entender realmente lo que estoy haciendo a sido muy difícil.

Notas:

  • Importar modulo desde un programa exterior:
from <nombre_programa> import <modulo>
  • _ → no vamos a utilizar la variable
  • Generamos la simulación varias veces para obtener una media (tendencia)

Picante borracho

me perdí 😦

Por que se accede al atributo nombre usando el name?

Es una buena práctica, se hizo pesado sobre todo porque llegó un punto en que copiaba el código sin saber qué hacía, pero después de un rato de estarlo analizarlo, lo comprendí. El contenido me gustó

Para la gente que tengais Python 3.8.X y tengais problemas al ejecutar el codigo os recomiendo que los imports los hagais de la siguiente manera:

from .person import Person, BasicPerson
from .coordinate import Coordinate
from .canvas import Canvas

Finalmente en el terminal que navegueis en la carpeta padre de donde tengais el proyecto y ejecuteis (el $ es la representación de que lo ejecuto en el terminal):

$ [python_path] -m [directorio_del_proyecto].[archivo_principal]

En mi caso queda de la siguiente manera:

$ py -m random_paths.__init__