# Ejercicio: proyecto "P0"

Para terminar, vamos a realizar un **ejercicio que ponga en práctica todas las herramientas que hemos visto**: terminal Bash, desarrollo de proyectos con Python, y editor de texto vim. Deberéis realizarlo <mark style="background-color:green;">**de forma individual**</mark>.&#x20;

El proyecto es extremadamente sencillo en cuanto a complejidad conceptual y de programación. **La dificultad radica exclusivamente en el aprendizaje de uso de las herramientas** del entorno de programación, especialmente la terminal Bash y el editor Vim.&#x20;

{% hint style="info" %}
Es muy importante que realicéis esta actividad usando las herramientas presentadas, tal y como se indica en cada paso. De hecho, el propósito principal de este actividad es que practiquéis con ellas y que aprendais a utilizarlas.&#x20;

En la evaluación, el **uso de bash i vim es obligatorio** (si no, finalización prematura de la prueba y nota de 0 puntos) y <mark style="background-color:$danger;">**supone un 40% de la nota de prácticas**</mark>**.**&#x20;

<mark style="background-color:green;">**En definitiva: debéis exponeros, salir de vuestra zona de confort, y experimentar la curva de aprendizaje de estas herramientas.**</mark>
{% endhint %}

## Estructura del proyecto

El proyecto P0 tendrá una estructura de ficheros típica de paquete *(package)* + código principal:

```
P0
├── main.py
└── utils
    ├── funciones.py
    └── __init__.py
```

Donde:

* **`main.py`:** fichero con código principal, que importará y testeará un conjunto de funciones implementadas en el paquete `utils`.
* **`utils/`:** directorio que da nombre al paquete homónimo que vamos a implementar.
  * **`funciones.py`:** módulo homónimo que contendrá un conjunto de funciones sencillas, las cuales serán invocadas por `main.py`.
  * **`__init__.py`:** componente especial del sistema de paquetes y módulos de Python que se utiliza para indicar que un directorio es un paquete (package).&#x20;
    * El código contenido en `__init__.py` se ejecuta automáticamente la primera vez que se importa el paquete o cualquiera de sus módulos.
    * Su función principal es inicializar el paquete (configurar variables de entorno, importar dependencias de otros módulos) y definir su API pública (qué módulos, submódulos, funciones, clases, etc. se exponen cuando se importa).
    * Su uso hoy en día es opcional (en versiones < 3.2 de Python era obligatorio), pero recomendable por convención.&#x20;

## Tareas a realizar

{% hint style="danger" %}
Es ahora el momento!&#x20;

1. **Abre la terminal Bash.**

2. **Divide verticalmente la pantalla** con la terminal a la izquierda y el navegador (esta página web) a la derecha. ¡Aprovecha máximamente la pantalla!

3. **ALEJA EL RATÓN** (mouse). No vas a usarlo, excepto si tienes que usar el navegador, o copiar texto de la terminal.&#x20;
   {% endhint %}

4. En la terminal, sitúate en un directorio donde quieras guardar tus prácticas de la asignatura (`$HOME/W`, si estás en el escritorio DSIC-Linux de Polilabs), y crea la ruta de directorios `"PRG/Lab/P0"`.  Sitúate en el directorio `P0`. Crea el subdirectorio `utils` del paquete, y accede a él.&#x20;

5. Crea, con vim, el fichero (módulo) **`funciones.py`**, e implementa estas 4 funciones:
   * `saludar()`: muestra un mensaje amistoso por pantalla.&#x20;
   * `maximo(a, b)`: devuelve el máximo valor entre `a` y `b`.
   * `factorial(x)`: calcula y devuelve el factorial de `x`, siguiendo una aproximación iterativa.
   * `print_lista(mi_lista)`: imprime, en una sola línea, separados por coma, todos los elementos de la lista `mi_lista`.

6. Valida que la implementación es correcta sintácticamente, ejecutando el módulo (`python3 funciones.py`).
   * Esto simplemente ejecutará las definiciones de las funciones, sin invocarlas.&#x20;
   * Por tanto, si está todo correcto, no generará ninguna salida.
   * Si genera una excepción, es por un error de sintaxis. Lee atentamente el mensaje de error y trata de solucionarlo.&#x20;

7. Crea, con vim, el fichero `__init__.py` , y añade la siguiente línea:

```py
​from .funciones import saludar, maximo, factorial, print_lista
```

{% hint style="info" %}
Esta línea hace que, cuando se importe el paquete, se importen en el primer nivel las 4 funciones del módulo `funciones` , el cual está asociado al fichero `funciones.py` ubicado en el mismo directorio que el fichero `__init__.py`  (el carácter `.`  es una referencia al directorio actual).&#x20;

De esta manera, el usuario del paquete (p.e. desde `main.py`) puede importarlas directamente:

```py
from utils import saludar, maximo, factorial, print_lista
```

De lo contrario, tendría que conocer la estructura interna de módulos y submódulos; concretamente, debería especificar el módulo funciones:

```py
from utils.funciones import saludar, maximo, factorial, print_lista
```

{% endhint %}

5. Sal del subdirectorio `utils/`, regresando así al directorio raíz del proyecto (`P0/`), y crea, con vim, un fichero **`main.py`**, que importe las cuatro funciones del paquete `utils`, e implementa en él un bloque de código principal  que:
   1. Invoque la función `saludar()`.
   2. Imprima por pantalla el máximo de los números enteros 5 y 7 (usando `maximo()`).
   3. Imprima por pantalla el valor de 5! (usando `factorial()`).
   4. Cree una lista de 4 enteros con los elementos \[1,2,3,4], e imprima sus contenidos (usando `print_lista()`).
6. Ejecuta el programa principal y comprueba que el resultado obtenido es correcto. Si no, depura tu implementación.
