11  2022-06-24
Examen de Inteligencia de los Negocios

Fecha de publicación

24 de junio de 2022

Grado: Inteligencia de los Negocios
Fecha: 24 de junio de 2022

Ejercicio 11.1 Las matemáticas financieras, resumidas en una frase, las podríamos definir como la rama de las matemáticas que estudia los flujos de dinero a través del tiempo. Básicamente se presupone que el dinero tiene menos valor en el futuro que en el presente, ya sea por un tema inflacionario o por la preferencia natural de las personas a priorizar el consumo presente.

El valor futuro es el valor alcanzado por un determinado capital al final del período determinado (para el ejemplo usaremos la fórmula del interés compuesto). Para calcularlo se utiliza la siguiente fórmula

\[VF = VA\cdot (1 + i)^n\]

El valor presente de una inversión es cuando calculamos el valor actual que tendrá una determinada cantidad que recibiremos o pagaremos en un futuro. Para calcularlo se utiliza la siguiente fórmula

\[VA = \frac{VF}{(1 + i)^n}\]

Donde \(VF\) es el valor futuro, \(VA\) es el valor actual o inicial de la inversión, \(i\) es el tipo de interés y \(n\) es número de años de la inversión.

  1. Crear una función que reciba como entrada un capital, un tipo de interés y un número de años, y muestre por pantalla el valor futuro de la inversión cada año del periodo indicado.
  2. Crear una función que reciba como entrada un capital, un tipo de interés y un número de años, y muestre por pantalla el valor actual del capital cada año del periodo indicado.

Ejemplo de ejecución

Introduce un capital: 1000
Introduce un tipo de interés: 10
Introduce un número de años: 3
VALOR FUTURO
Año 0 : 1100.0
Año 1 : 1210.0000000000002
Año 2 : 1331.0000000000005
VALOR ACTUAL
Año 0 : 909.090909090909
Año -1 : 826.4462809917354
Año -2 : 751.3148009015775
def vf(capital, tipo, periodo):
    '''
    Función que muestra por pantalla el valor futuro de una inversión cada año de un periodo dado.
    Parámetros: 
        - capital: Es un real con el capital inicial de la inversión.
        - tipo: Es un real con el tipo de interés anual.
        - periodo: Es un entero con el número de años de la inversión.
    '''
    # Bucle iterativo para recorrer la secuencia de años.
    for i in range(periodo):
        # Aplicamos la fórmula para el cálculo del valor futuro para cada año i. 
        print("Año", i, ":", capital * (1 + tipo / 100) ** (i + 1))
    return
 
def va(capital, tipo, periodo):
    '''
    Función que muestra por pantalla el valor actual de una inversión cada año de un periodo dado.
    Parámetros: 
        - capital: Es un real con el capital final de la inversión.
        - tipo: Es un real con el tipo de interés anual.
        - periodo: Es un entero con el número de años de la inversión.
    ''' 
    # Bucle iterativo para recorrer la secuencia de años.
    for i in range(periodo): 
         # Aplicamos la fórmula para el cálculo del valor actual para cada año i. 
        print("Año", -i, ":", capital / (1 + tipo / 100) ** (i + 1))
    return

# Ejemplo
cantidad = float(input("Introduce un capital: "))
tipo = float(input("Introduce un tipo de interés: "))
años = int(input("Introduce un número de años: "))
print("VALOR FUTURO")
vf(cantidad, tipo, años)
print("VALOR ACTUAL")
va(cantidad, tipo, años)
VALOR FUTURO
Año 0 : 1100.0
Año 1 : 1210.0000000000002
Año 2 : 1331.0000000000005
VALOR ACTUAL
Año 0 : 909.090909090909
Año -1 : 826.4462809917354
Año -2 : 751.3148009015775

Ver notebook de la solución en Colab

Ejercicio 11.2 Realizar un programa que simule el juego de las tres en raya. Cada jugador solo debe colocar su ficha una vez por turno y no debe ser sobre una casilla ya ocupada. En caso de que el jugador haga trampa el ganador será el otro. Para ganar se debe conseguir realizar una línea recta (horizontal, vertical o diagonal) con la misma ficha. El tablero es de 3x3 y cualquier casilla podrá estar vacía u ocupada sólo por una ficha X o 0. El programa debe realizar las siguientes operaciones:

  • Mostrar el tablero por pantalla.
  • Poner una ficha en una cuadricula comprobando que no está ocupada.
  • Comprobar si se produce tres en raya e indicar si es de X o de O, o si hay empate.

Ejemplo de ejecución

[' ', ' ', ' ']
[' ', ' ', ' ']
[' ', ' ', ' ']
Introduce la coordenada X del 1 al 3: 2
Introduce la coordenada Y del 1 al 3: 2
Introduce 0 para círculo o X para cruz: X
[' ', ' ', ' ']
[' ', 'X', ' ']
[' ', ' ', ' ']
Introduce la coordenada X del 1 al 3: 2
Introduce la coordenada Y del 1 al 3: 1
Introduce 0 para círculo o X para cruz: 0
[' ', ' ', ' ']
['0', 'X', ' ']
[' ', ' ', ' ']
Introduce la coordenada X del 1 al 3: 2
Introduce la coordenada Y del 1 al 3: 1
Introduce 0 para círculo o X para cruz: X
Esa coordenada ya está siendo utilizada, use una libre.
[' ', ' ', ' ']
['0', 'X', ' ']
[' ', ' ', ' ']
Introduce la coordenada X del 1 al 3: 3
Introduce la coordenada Y del 1 al 3: 1
Introduce 0 para círculo o X para cruz: X
[' ', ' ', ' ']
['0', 'X', ' ']
['X', ' ', ' ']
Introduce la coordenada X del 1 al 3: 1
Introduce la coordenada Y del 1 al 3: 2
Introduce 0 para círculo o X para cruz: 0
[' ', '0', ' ']
['0', 'X', ' ']
['X', ' ', ' ']
Introduce la coordenada X del 1 al 3: 1
Introduce la coordenada Y del 1 al 3: 3
Introduce 0 para círculo o X para cruz: X
[' ', '0', 'X']
['0', 'X', ' ']
['X', ' ', ' ']
La partida la ha ganado el jugador con la ficha X.
# Definimos el tablero como una lista de 3 listas.
tablero = [ 
    [" ", " ", " "], 
    [" ", " ", " "], 
    [" ", " ", " "], 
] 
  
def mostrar_tablero(tablero): 
    '''
    Función que muestra el tablero por pantalla.
    
    Parámetros:
        - tablero: Es una lista de listas con el tablero.
    '''
    # Bucle iterativo para recorrer por valor la lista del tablero. 
    # fila toma como valores cada una de las listas de la lista tablero.
    for fila in tablero: 
        # Mostramos la fila por pantalla. Se muestra como una lista. 
        print(fila) 
    return True 
  
def poner_ficha(tablero, x, y, ficha):
    '''
    Función que pone una ficha en el tablero.

    Parámetros:
        tablero: Es una lista de listas con el tablero.
        x: Es un entero entre 1 y 3 con la fila donde colocar la ficha.
        y: Es un entero entre 1 y 3 con la columna donde colocar la ficha.
        ficha: Es una cadena con el símbolo a colocar.
    Salida:
        El tablero con la nueva ficha colocada si la posición dada está libre o el tablero original si no.
    '''
    # Condicional para ver si la posición indicada está vacía.
    if tablero[x-1][y-1] == " ": 
        # Si la posición está vacía, colocamos la ficha en la posición.
        tablero[x-1][y-1] = ficha
    else: 
        # Si no está vacía, avisamos al usuario.
        print("Esa coordenada ya está siendo utilizada, use una libre.") 
    return tablero 
  
def final(tablero):
    '''
    Función para comprobar si hay ganador en tablero.

    Parámetros:
        - tablero: Es una lista de listas con el tablero.
    Salida:
        Un cadena vacía si no ha terminado la partida o el carácter de la ficha ganadora si se ha terminado y hay ganador o la cadena EMPATE si se ha terminado y no hay ganador..
    '''
    # Bucle iterativo para comprobar si hay tres en raya en alguna fila.
    for fila in range(3): 
        # Condicional para ver si las fichas de la fila son iguales.
        if tablero[fila][0] == tablero[fila][1] == tablero[fila][2] != " " : 
            # Si las fichas de la fila son iguales el jugador con esa ficha es el ganador y la devolvemos.
            return tablero[fila][0]
    # Bucle iterativo para comprobar si hay tres en raya en alguna columna.
    for columna in range(3):
        # Condicional para ver si las fichas de la columna son iguales. 
        if tablero[0][columna] == tablero[1][columna] == tablero[2][columna] != " " : 
            # Si las fichas de la columna son iguales el jugador con esa ficha es el ganador y la devolvemos.
            return tablero[0][columna]
    # Condicional para comprobar la diagonal principal.
    if tablero[0][0] == tablero[1][1] == tablero[2][2] != " ": 
        # Si las fichas de la diagonal principal son iguales el jugador con esa ficha es el ganador y la devolvemos.
        return tablero[0][0]
    # Condicional para comprobar la diagonal secundaria.
    if tablero[0][2] == tablero[1][1] == tablero[2][0] != str(" "): 
        # Si las fichas de la diagonal secundaria son iguales el jugador con esa ficha es el ganador y la devolvemos.
        return tablero[0][2]
    # Bucle iterativo para recorrer las filas del tablero y ver si quedan casillas sin ocupar. 
    # fila toma como valores las filas del tablero.
    for fila in tablero: 
        # Condicional para ver si la fila contiene un espacio en blanco.
        if " " in fila: 
            return ""
    return "EMPATE"
  
def preguntar_casilla(): 
    '''
    Función que pregunta por la casilla y la ficha a colocar.

    Salida:
        Una tupla con los siguientes elementos:
        - x: Un entero con la fila.
        - y: Un entero con la columna.
        - ficha: Una cadena con el carácter de la ficha.
    '''
    # Bucle condicional infinito para preguntar por la fila, columna y ficha.
    while True: 
        # Preguntamos por la fila.
        x = int(input("Introduce la coordenada X del 1 al 3: ")) 
        # Preguntamos por la columna.
        y = int(input("Introduce la coordenada Y del 1 al 3: ")) 
        # Preguntamos por la ficha.
        ficha = input("Introduce 0 para círculo o X para cruz: ")
        # Condional para ver si la fila y columna son válidas.
        if x >= 1 and x <= 3 and y >= 1 and x <= 3: 
            # Si la fila y columna es válida, condicional para ver si la ficha es X o 0.
            if ficha.lower() == "x" or ficha == "0":
                # Si la ficha es válida, terminamos el bucle y devolvemos la fila, columna y ficha.
                return x, y, ficha 
        else: 
            # Si la fila o columna no son válidas, informamos al usuario y le volvemos a preguntar.
            print("Por favor introduce unas coordenadas válidas.") 

# Programa principal
# Bucle condicional para preguntar por el próximo movimiento, hasta que termine la partida.
while True:
    # Mostramos el tablero por pantalla
    mostrar_tablero(tablero)
    print()
    # Preguntamos por la fila, columna y ficha del siguiente movimiento.
    x, y, ficha = preguntar_casilla()
    # Colocamos la ficha en el tablero.
    poner_ficha(tablero, x, y, ficha) 
    # Comprobamos si la partida ha terminado y hay ganador.
    fin = final(tablero)
    # Condicional para ver si la partida ha terminado y hay ganador.
    if fin: 
        # Si la partida ha terminado mostramos el tablero.
        mostrar_tablero(tablero)
        # Condicional para ver si la partida ha terminado en empate. 
        if fin == "EMPATE":
            print("La partida ha terminado en empate.")
        else:
            print("La partida la ha ganado el jugador con la ficha", fin + ".")
        # Salimos del bucle infinito una vez la partida ha terminado.
        break
[' ', ' ', ' ']
[' ', ' ', ' ']
[' ', ' ', ' ']

[' ', ' ', ' ']
[' ', 'X', ' ']
[' ', ' ', ' ']

[' ', ' ', ' ']
['0', 'X', ' ']
[' ', ' ', ' ']

Esa coordenada ya está siendo utilizada, use una libre.
[' ', ' ', ' ']
['0', 'X', ' ']
[' ', ' ', ' ']

[' ', ' ', ' ']
['0', 'X', ' ']
['X', ' ', ' ']

[' ', '0', ' ']
['0', 'X', ' ']
['X', ' ', ' ']

[' ', '0', 'X']
['0', 'X', ' ']
['X', ' ', ' ']
La partida la ha ganado el jugador con la ficha X.

Ver notebook de la solución en Colab

Ejercicio 11.3 El fichero bank-loans.csv contiene información sobre los préstamos de los clientes de un banco. Utilizando la librería Pandas, se pide: 

  • Crear un DataFrame importando los datos del fichero.
  • Mostrar por pantalla el nombre de las columnas del DataFrame. 
  • Mostrar por pantalla las filas del DataFrame múltiplos de 10. 
  • Mostrar por pantalla el número de clientes casados con edad entre 30 y 40 años. 
  • Añadir al DataFrame una columna nueva con la edad en meses. 
  • Mostrar por pantalla las frecuencias de los oficios ordenadas de mayor a menor. 
  • Mostrar por pantalla las edades medias según el nivel de estudios. 
  • Mostrar por pantalla el porcentaje de préstamos hipotecarios (housing) según el estado civil (marital). 
  • Dibujar el diagrama de sectores con los porcentajes de los niveles de estudio y ponerle un título. 
  • Dibujar en una misma figura el histograma y el diagrama de cajas de las edades. El histograma debe tener clases de amplitud 10 desde 20 hasta 70 años, y en color rojo.
import pandas as pd
import matplotlib.pyplot as plt

# Crear el DataFrame a partir de la url del fichero csv
df = pd.read_csv("https://aprendeconalf.es/docencia/python/examenes/inteligencia-negocios/soluciones/examen-2022-06-24/bank-loans.csv")
# Mostrar el índice de las columnas
print(df.columns)
# Mostrar las filas múltiplo de 10
print(df.iloc[range(0, len(df), 10)])
# Mostrar el número de clientes casados entre 30 y 40 años
print(len(df[(df.marital == "married") & (df.age > 30) & (df.age < 40)]))
# Añadir una columna con la edad en meses.
df["months"] = df.age * 12
print(df)
# Frecuencias de oficios ordenados de mayor a menor
print(df.job.value_counts().sort_values(ascending = False))
# Calcular la edad media según el nivel de estudios
print(df.groupby("education").age.mean())
# Calcular el porcentaje de prestamos hipotecarios según el estado civil
print(df.groupby("marital").housing.value_counts(normalize = True) * 100)
# Diagrama de sectores de nivel de estudios
fig, ax = plt.subplots()
df.education.value_counts(normalize = True).plot(kind = "pie", title = "Distribución del nivel de estudios")
plt.show()
# Histograma y diagrama de cajas de edades
fig, ax = plt.subplots(2)
df.age.plot(kind = "hist", ax = ax[0], bins = range(20, 70,10), color = "red")
df.age.plot(kind = "box", ax = ax[1], vert = False)
plt.show()
Index(['age', 'job', 'marital', 'education', 'default', 'housing', 'loan'], dtype='object')
      age          job   marital            education  default housing loan
0      56    housemaid   married             basic.4y       no      no   no
10     41  blue-collar   married              unknown  unknown      no   no
20     30   unemployed   married          high.school       no      no   no
30     46       admin.   married              unknown       no      no   no
40     58   management   unknown    university.degree       no     yes   no
...   ...          ...       ...                  ...      ...     ...  ...
9950   49  blue-collar   married             basic.9y  unknown      no   no
9960   51   unemployed   married          high.school  unknown     yes   no
9970   43   technician    single  professional.course       no     yes   no
9980   49       admin.  divorced    university.degree       no      no   no
9990   35  blue-collar    single              unknown       no      no   no

[1000 rows x 7 columns]
2494
      age          job   marital            education  default  housing  \
0      56    housemaid   married             basic.4y       no       no   
1      57     services   married          high.school  unknown       no   
2      37     services   married          high.school       no      yes   
3      40       admin.   married             basic.6y       no       no   
4      56     services   married          high.school       no       no   
...   ...          ...       ...                  ...      ...      ...   
9995   39  blue-collar   married             basic.4y  unknown      yes   
9996   36   technician   married          high.school       no      yes   
9997   33     services    single             basic.6y       no  unknown   
9998   41   technician   married  professional.course  unknown      yes   
9999   40     services  divorced              unknown       no      yes   

         loan  months  
0          no     672  
1          no     684  
2          no     444  
3          no     480  
4         yes     672  
...       ...     ...  
9995       no     468  
9996       no     432  
9997  unknown     396  
9998       no     492  
9999      yes     480  

[10000 rows x 8 columns]
blue-collar      2980
admin.           2073
technician       1365
services         1172
management        678
entrepreneur      381
self-employed     340
housemaid         297
retired           273
unemployed        236
unknown           125
student            80
Name: job, dtype: int64
education
basic.4y               45.147806
basic.6y               39.448095
basic.9y               39.228571
high.school            38.313602
illiterate             45.000000
professional.course    40.367776
university.degree      39.853485
unknown                43.709278
Name: age, dtype: float64
marital   housing
divorced  no         50.940018
          yes        46.821844
          unknown     2.238138
married   no         51.987494
          yes        45.183862
          unknown     2.828644
single    no         51.931131
          yes        44.671940
          unknown     3.396929
unknown   no         64.705882
          yes        35.294118
Name: housing, dtype: float64
<Figure size 432x288 with 1 Axes><Figure size 432x288 with 2 Axes>

Ver notebook de la solución en Colab

Ejercicio 11.4 El fichero bank-loans.csv contiene información sobre los préstamos de los clientes de un banco. Utilizando ficheros (sin usar la librería Pandas), crear una función que tenga como parámetros la url del fichero, el nombre de una columna cualitativa y un booleano para los porcentajes (False por defecto), que devuelva un diccionario con las frecuencias absolutas de las categorías de la columna indicada. Si se pasa True como argumento del parámetro para el porcentaje, la función debe devolver el diccionario de porcentajes de las categorías. 

Ejemplo de ejecución

Salida de la llamada a la función con la columna “education”.

{'basic.4y': 1299, 'high.school': 2382, 'basic.6y': 761, 'basic.9y': 1820, 'professional.course': 1142, 'unknown': 485, 'university.degree': 2109, 'illiterate': 2}

Salida de la llamada a la función con la columna “housing” y porcentaje = True.

{'no': 51.88, 'yes': 45.24, 'unknown': 2.88}
# Importamos las librerías
from urllib import request
from urllib.error import URLError

def frecuencias(url, columna, porcentaje = False):
    '''
    Función que calcula la tabla de frecuencias absoluta o relativa de una columna de un fichero csv.
    
    Parámetros:
        - url: Es una cadena con la url del fichero csv.
        - columna: Es una cadena con el nombre de la columna.
        - porcentaje: Es un booleano (False por defecto) que indica si las frecuencias son relativas o no.
    
    Salida:
        Un diccionario con las categorías de la columna y sus frecuencias.
    '''
    try:
        # Intentamos abrir el fichero a partir de su url.
        with request.urlopen(url) as f:
            # Leemos el contenido del fichero, lo decodificamos y creamos una lista partiendo el contenido por el carácter de cambio de linea.
            contenido = f.read().decode().split("\n")
    except URLError:
        # Si no existe el fichero en la url indicada controlamos el error y avisamos al usuario.
        print("La url", url, "no existe")
    else:
        # Creamos una lista con los encabezados dividiendo la primera línea por la coma. 
        encabezado = contenido.pop(0).split(",")
        # Obtenemos la posición de la columna indicada en la lista de encabezados.
        numcol = encabezado.index(columna)
        # Inicializamos un diccionario vacío para ir guardando los pares con las categorías y sus frecuencias.
        dic_frec = {}
        # Bucle iterativo para recorrer por valor las líneas del fichero.
        # i toma como valores las líneas del fichero.
        for i in contenido:
            # Obtenemos la clave dividiendo la línea por la coma y accediendo a la posición de la columna indicada.
            clave = i.split(",")[numcol]
            # Condicional para ver si la clave está ya en el diccionario.
            if clave in dic_frec:
                # Si la clave está ya en el diccionario incrementamos la frecuencia en 1.
                dic_frec[clave] += 1
            else:
                # Si la clave no está en el diccionario, añadimos un nuevo par con la clave y frecuencia 1.
                dic_frec[clave] = 1
        # Condicional para ver si se quieren relativas (porcentajes)
        if porcentaje:
            # Si se quieren porcentajes.
            # Calculamos el número de filas del fichero.
            total = len(contenido)
            # Bucle iterativo para recorrer el diccionario por clave y valor.
            for clave, valor in dic_frec.items():
                # Actualizamos la frecuencia del par dividiendo la frecuencia absoluta por el tamaño de la muestra y multiplicando por 100.
                dic_frec[clave] = dic_frec[clave] / total * 100
        # Devolvemos el diccionario con las frecuencias.
        return dic_frec

# Ejemplos      
print(frecuencias("https://aprendeconalf.es/docencia/python/examenes/inteligencia-negocios/soluciones/examen-2022-06-24/bank-loans.csv", "education"))
print(frecuencias("https://aprendeconalf.es/docencia/python/examenes/inteligencia-negocios/soluciones/examen-2022-06-24/bank-loans.csv", "housing", porcentaje = True))
{'basic.4y': 1299, 'high.school': 2382, 'basic.6y': 761, 'basic.9y': 1820, 'professional.course': 1142, 'unknown': 485, 'university.degree': 2109, 'illiterate': 2}
{'no': 51.88, 'yes': 45.24, 'unknown': 2.88}

Ver notebook de la solución en Colab