Comprender la reutilización de código y la modularidad en Python 3

¿Qué es la Programación Orientada a Objetos (POO)?

OOP es un paradigma de programación basado en el concepto de «objetos», que pueden contener datos, en forma de campos, a menudo conocidos como atributos; y código, en forma de procedimientos, a menudo conocidos como métodos. Obtenga más información aquí , o simplemente busque en Google «OOP».
Los objetos tienen características y características, conocidas como atributos, y pueden hacer varias cosas a través de sus métodos. La característica más importante de OOP es qué tan bien se puede interactuar con los objetos e incluso moldearlos en el futuro, lo que los hace muy amigables para los desarrolladores, la escala, el cambio con el tiempo, las pruebas y mucho más.
 

¿Qué es Modularidad?

La modularidad se refiere al concepto de crear varios módulos primero y luego vincularlos y combinarlos para formar un sistema completo (es decir, la medida en que un software/aplicación web puede dividirse en módulos más pequeños se denomina modularidad). La modularidad permite la reutilización y minimizará la duplicación.
 

Flujo del artículo

Objetivo: Aprender programación orientada a objetos – Modularidad. ¿Cómo podemos convertir algunas partes de nuestro código en una biblioteca para que cualquiera pueda usarla como referencia futura? Hacer que el código sea modular permitirá la reutilización y minimizará la duplicación.

Dependencias: pygame

Resumen: Vamos a hacer un juego pequeño (no es realmente un juego), sino solo un entorno y algunos objetos en él. Intentaremos que el entorno sea estático y los objetos (blobs en nuestro caso) modulares. Haremos uso de PyGame, ya que nos brinda una forma simple de visualizar realmente lo que estamos haciendo y construyendo, para que podamos ver nuestros objetos en acción. Lo que vamos a hacer es construir Blob World, que es un mundo que consta de actores, conocidos como blobs. Diferentes blobs tienen diferentes propiedades, y los blobs necesitan funcionar dentro de su entorno de Blob World. Con este ejemplo, podremos ilustrar la modularidad. 

Estamos dividiendo nuestro proceso de aprendizaje en dos fases.  

  1. Creación del entorno y los blobs
  2. Comprender la modularidad

Repositorio (Github): fuente

MUNDO BLOB (Código Python)

Python

import pygame
import random
 
STARTING_BLUE_BLOBS = 10
STARTING_RED_BLOBS = 3
 
WIDTH = 800
HEIGHT = 600
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
RED = (255, 0, 0)
 
game_display = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Blob World")
clock = pygame.time.Clock()
 
class Blob:
 
    def __init__(self, color):
        self.x = random.randrange(0, WIDTH)
        self.y = random.randrange(0, HEIGHT)
        self.size = random.randrange(4,8)
        self.color = color
 
    def move(self):
        self.move_x = random.randrange(-1,2)
        self.move_y = random.randrange(-1,2)
        self.x += self.move_x
        self.y += self.move_y
 
        if self.x < 0: self.x = 0
        elif self.x > WIDTH: self.x = WIDTH
         
        if self.y < 0: self.y = 0
        elif self.y > HEIGHT: self.y = HEIGHT
 
 
def draw_environment(blob_list):
    game_display.fill(WHITE)
 
    for blob_dict in blob_list:
        for blob_id in blob_dict:
            blob = blob_dict[blob_id]
            pygame.draw.circle(game_display, blob.color, [blob.x, blob.y], blob.size)
            blob.move()
 
    pygame.display.update()
     
 
def main():
    blue_blobs = dict(enumerate([Blob(BLUE) for i in range(STARTING_BLUE_BLOBS)]))
    red_blobs = dict(enumerate([Blob(RED) for i in range(STARTING_RED_BLOBS)]))
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
        draw_environment([blue_blobs,red_blobs])
        clock.tick(60)
 
if __name__ == '__main__':
    main()

Producción: 

PARTE(1/2): Blob World En esta parte, estamos creando un entorno de juego simple y algunos objetos en él porque visualizar lo que hemos creado es una forma excepcional de aprender a programar. La explicación para la creación del mundo blob (es decir, su entorno y sus objetos) usando pygame se explica aquí . Todo lo que necesitamos entender es cómo hacer que nuestro código sea modular.

PARTE(2/2): Modularidad En esta segunda parte, vamos a entender una característica esencial de la Programación Orientada a Objetos, la Modularidad. Hasta ahora, no hemos introducido nada que haga que este ( código BLOB WORLD ) sea demasiado difícil de mantener o escalar con el tiempo, al menos dentro del alcance de lo que podemos hacer con PyGame. ¿Qué hay de hacerlo modular? Hay una prueba realmente fácil para esto, ¡tratemos de importarla! 

Para hacer esto, vamos a tener dos archivos. Copiemos la clase Blob y al azar, y hagamos un nuevo archivo: blob.py  

import random

class Blob:

    def __init__(self, color):
        self.x = random.randrange(0, WIDTH)
        self.y = random.randrange(0, HEIGHT)
        self.size = random.randrange(4,8)
        self.color = color

    def move(self):
        self.move_x = random.randrange(-1,2)
        self.move_y = random.randrange(-1,2)
        self.x += self.move_x
        self.y += self.move_y

        if self.x  WIDTH: self.x = WIDTH
        
        if self.y  HEIGHT: self.y = HEIGHT

Volviendo a nuestro archivo original, eliminemos la clase Blob y luego importemos Blob desde blob.py.  

import pygame
import random
from blob import Blob

STARTING_BLUE_BLOBS = 10
...

Inmediatamente, nos da un error en el archivo blob.py, con respecto a nuestra clase Blob, donde tenemos algunas variables no definidas. Este es definitivamente un problema con la escritura de clases, debemos tratar de evitar el uso de constantes o variables fuera de la clase. Agreguemos estos valores al método __init__, luego modifiquemos todas las partes donde usamos las constantes. 
Entonces, aquí está nuestro nuevo archivo de clase Blob: blob.py 

Luego, dentro de nuestro archivo original, cuando llamamos a la clase Blob, espera algunos valores para esos argumentos, por lo que los agregaría en la función principal:  

def main():
    blue_blobs = dict(enumerate([Blob(BLUE,WIDTH,HEIGHT) for i in range(STARTING_BLUE_BLOBS)]))
    red_blobs = dict(enumerate([Blob(RED,WIDTH,HEIGHT) for i in range(STARTING_RED_BLOBS)]))
    while True:
        ...

Genial, ahora nuestra clase Blob al menos se puede importar, ¡así que ya es modular por naturaleza! Otra buena idea es intentar darle al desarrollador que está usando su código tanto poder como sea posible, y hacer que su clase sea lo más generalizable posible. Al menos un ejemplo en el que definitivamente podríamos darle más al programador que usa esta clase es en la definición del tamaño del blob:  

  self.size = random.randrange(4,8) 

¿Hay alguna razón por la que no querríamos darle al programador una manera fácil de cambiarlos? No me parece. Sin embargo, a diferencia de x_boundary y y_boundary, no necesariamente *necesitamos* que el programador nos proporcione un valor para el tamaño, ya que al menos podemos usar un valor inicial predeterminado razonable. Por lo tanto, podemos hacer algo como:  

class Blob:

    def __init__(self, color, x_boundary, y_boundary, size_range=(4,8)):
        self.x_boundary = x_boundary
        self.y_boundary = y_boundary
        self.x = random.randrange(0, self.x_boundary)
        self.y = random.randrange(0, self.y_boundary)
        self.size = random.randrange(size_range[0],size_range[1])
        self.color = color

Ahora, si el programador quiere cambiar el tamaño, puede hacerlo, de lo contrario no tiene que hacerlo. También podríamos querer permitir que el programador modifique la velocidad del blob si así lo desea: 

import random


class Blob:

    def __init__(self, color, x_boundary, y_boundary, size_range=(4,8), movement_range=(-1,2)):
        self.size = random.randrange(size_range[0],size_range[1])
        self.color = color
        self.x_boundary = x_boundary
        self.y_boundary = y_boundary
        self.x = random.randrange(0, self.x_boundary)
        self.y = random.randrange(0, self.y_boundary)
        self.movement_range = movement_range

    def move(self):
        self.move_x = random.randrange(self.movement_range[0],self.movement_range[1])
        self.move_y = random.randrange(self.movement_range[0],self.movement_range[1])
        self.x += self.move_x
        self.y += self.move_y

        if self.x  self.x_boundary: self.x = self.x_boundary
        
        if self.y  self.y_boundary: self.y = self.y_boundary

Ahora hemos abierto bastante la clase. ¿Algo más salta a la vista? Sí, la línea donde obligamos a la mancha a permanecer dentro de los límites. ¿Podría haber ejemplos en los que nos gustaría que las gotas pudieran deambular libremente fuera de la vista? ¡Seguramente! ¿Sin embargo, es útil este código delimitador? ¿Es probable que los programadores quieran hacer uso de esto con bastante frecuencia? ¡Seguramente! sin embargo, tiene más sentido no tener el código o darle su propio método, así: 

import random

class Blob:

    def __init__(self, color, x_boundary, y_boundary, size_range=(4,8), movement_range=(-1,2)):
        self.size = random.randrange(size_range[0],size_range[1])
        self.color = color
        self.x_boundary = x_boundary
        self.y_boundary = y_boundary
        self.x = random.randrange(0, self.x_boundary)
        self.y = random.randrange(0, self.y_boundary)
        self.movement_range = movement_range

    def move(self):
        self.move_x = random.randrange(self.movement_range[0],self.movement_range[1])
        self.move_y = random.randrange(self.movement_range[0],self.movement_range[1])
        self.x += self.move_x
        self.y += self.move_y

    def check_bounds(self):
        if self.x  self.x_boundary: self.x = self.x_boundary
        
        if self.y  self.y_boundary: self.y = self.y_boundary

Ahora, el programador puede decidir usarlo o no. También podría dar algún tipo de argumento en el método de movimiento, donde, si es Verdadero, se aplicarían los límites. 
Así que pudimos vislumbrar cómo podemos hacer que nuestro código python sea modular.

Recursos: 

Este artículo es una contribución de Amartya Ranjan Saikia . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *