In [1]:
"""
IPython Notebook v4.0 para python 2.7
Librerías adicionales: Ninguna.
Contenido bajo licencia CC-BY 4.0. Código bajo licencia MIT. (c) Sebastian Flores.
"""

# Configuracion para recargar módulos y librerías 
%reload_ext autoreload
%autoreload 2

from IPython.core.display import HTML

HTML(open("style/iwi131.css", "r").read())


Out[1]:






IWI131

Programación de Computadores

Sebastián Flores

http://progra.usm.cl/

https://www.github.com/usantamaria/iwi131

Soluciones a Certamen 3, S1 2015, Casa Central

Pregunta 1 [25%]

(a) La web Linkedpy analiza los procesos de postulación de recién titulados a empresas. Para ello tiene el archivo titulados.txt, donde cada línea tiene a los titulados en el formato nombre;rut, y el archivo postulaciones.txt, donde cada línea tiene un rut del titulado, el puesto y la empresa a la que cada titulado postula en el formato rut#puesto#empresa.

A partir de estos archivos se desea generar un archivo por empresa, los cuales deben tener los titulados que postularon a algún puesto en la empresa con el formato rut;nombre;puesto.

A continuación se presentan las líneas de código que resuelven este problema, pero que están desordenadas. Usted debe ordenarlas e indentarlas (dejar los espacios correspondientes de python) para que ambas funciones estén correctas. La primera función retorna una lista con todas las empresas en el archivo con postulaciones (recibido como parámetro). Y la segunda función resuelve el problema antes descrito, recibiendo como parámetro el nombre del archivo con titulados y el nombre del archivo con postulaciones.

La primera función retorna una lista con todas las empresas en el archivo con postulaciones (recibido como parámetro).


In [ ]:
def empresas(post):
emp.append(e)
arch_P.close()
for li in arch_P:
r, p, e = li.strip().split('#')
if e not in emp:
arch_P = open(post)
emp = list()
return emp

In [2]:
# Solucion Ordenada
def empresas(post):
    arch_P = open(post)
    emp = list()
    for li in arch_P:
        r, p, e = li.strip().split('#')
        if e not in emp:
            emp.append(e)
    arch_P.close()
    return emp

In [3]:
print empresas("data/postulaciones.txt")


['SalcoBar', 'CascosAzules']

La segunda función resuelve el problema antes descrito (generar un archivo por empresa, los cuales deben tener los titulados que postularon a algún puesto en la empresa con el formato rut;nombre;puesto), recibiendo como parámetro el nombre del archivo con titulados y el nombre del archivo con postulaciones.


In [ ]:
arch_E = open(e + '.txt', 'w')
for pos in arch_P:
arch_T.close()
def registros(tit, post):
arch_E.write(li.format(r, n, p))
emp = empresas(post)
arch_T = open(tit)
n, r2 = titu.strip().split(';')
arch_P.close()
for e in emp:
arch_E.close()
if e2 == e:
r, p, e2 = pos.strip().split('#')
if r2 == r:
li = '{0};{1};{2}\n'
arch_P = open(post)
return None
for titu in arch_T:

In [4]:
# Solución ordenada
def registros(tit, post):
    li = '{0};{1};{2}\n'
    emp = empresas(post)
    for e in emp:
        arch_E = open(e + '.txt', 'w')
        arch_P = open(post)
        for pos in arch_P:
            r, p, e2 = pos.strip().split('#')
            if e2 == e:
                arch_T = open(tit)
                for titu in arch_T:
                    n, r2 = titu.strip().split(';')
                    if r2 == r:
                        arch_E.write(li.format(r, n, p))
                arch_T.close()
        arch_E.close()
        arch_P.close()
    return None

In [5]:
# Utilización
registros("data/titulados.txt", "data/postulaciones.txt")

Pregunta 2 [35%]

Andrónico Bank es un banco muy humilde que hasta hace poco usaban sólo papel y lápiz para manejar toda la información de sus clientes, también humildes. Como una manera de mejorar sus procesos, Andrónico Bank quiere utilizar un sistema computacional basado en Python. Por eso se traspasa la información de sus clientes a un archivo de texto, indicando su rut, nombre y clase cliente. El archivo clientes.txt es un ejemplo de lo anterior:

9234539-9;Sebastian Davalos;VIP
11231709-k;Choclo Delano;Pendiente
5555555-6;Sebastian Pinera;VIP
9999999-k;Gladis Maryn;RIP
12312312-1;Michel Bachelet;VIP
8888888-8;Companero Yuri;Estandar
7987655-1;Sergio Estandarte;RIP

Pregunta 2.a

Escriba una función buscar_clientes(archivo, clase) que reciba como parámetros el nombre del archivo de clientes y una clase, y retorne un diccionario con los rut de los clientes como llaves y los nombres como valor de todos los clientes pertenecientes a la clase entregada como parámetro.

>>> buscar_clientes('clientes.txt', 'Pendiente')
{'11231709-k': 'Choclo Delano'}

Estrategia de solución:

  • ¿Qué estructura tienen los datos de entrada?
  • ¿Qué estructura deben tener los datos de salida?
  • ¿Cómo proceso los inputs para generar el output deseado?

In [7]:
def buscar_clientes(nombre_archivo, clase_buscada):
    archivo = open(nombre_archivo)
    clientes_buscados = {}
    for linea in archivo:
        rut,nombre,clase = linea[:-1].split(";")
        if clase==clase_buscada:
            clientes_buscados[rut] = nombre
    archivo.close()
    return clientes_buscados

print buscar_clientes('data/clientes.txt', 'Pendiente')
print buscar_clientes('data/clientes.txt', 'VIP')
print buscar_clientes('data/clientes.txt', 'RIP')
print buscar_clientes('data/clientes.txt', 'Estandar')


{'11231709-k': 'Choclo Delano'}
{'12312312-1': 'Michel Bachelet', '9234539-9': 'Sebastian Davalos', '5555555-6': 'Sebastian Pinera'}
{'7987655-1': 'Sergio Estandarte', '9999999-k': 'Gladis Maryn'}
{'8888888-8': 'Companero Yuri'}

Pregunta 2.b

Escriba una función dar_credito(archivo, rut) que reciba como parámetros el nombre del archivo de clientes y el rut de un cliente, y que retorne True si éste es VIP o False si no lo es. Si no encuentra el cliente la función retorna False

>>> dar_credito('clientes.txt', '9999999-k')
False

Estrategia de solución:

  • ¿Qué estructura tienen los datos de entrada?
  • ¿Qué estructura deben tener los datos de salida?
  • ¿Cómo proceso los inputs para generar el output deseado?

In [8]:
def dar_credito(nombre_archivo, rut):
    clientes_VIP = buscar_clientes(nombre_archivo, "VIP")
    return rut in clientes_VIP

print dar_credito('data/clientes.txt', '9999999-k')
print dar_credito('data/clientes.txt', '11231709-k')
print dar_credito('data/clientes.txt', '9234539-9')


False
False
True

Pregunta 2.c

Escriba una función contar_clientes(archivo) que reciba como parámetros el nombre del archivo de clientes y que retorne un diccionario con la cantidad de clientes de cada clase en el archivo.

>>> contar_clientes('clientes.txt')
{'VIP': 3, 'Pendiente': 1, 'RIP': 2, 'Estandar': 1}

Estrategia de solución:

  • ¿Qué estructura tienen los datos de entrada?
  • ¿Qué estructura deben tener los datos de salida?
  • ¿Cómo proceso los inputs para generar el output deseado?

In [12]:
def contar_clientes(nombre_archivo):
    archivo = open(nombre_archivo)
    cantidad_clases = {}
    for linea in archivo:
        rut,nombre,clase = linea.strip().split(";")
        if clase in cantidad_clases:
            cantidad_clases[clase] += 1
        else:
            cantidad_clases[clase] = 1
    archivo.close()
    return cantidad_clases

print contar_clientes('data/clientes.txt')


{'VIP': 3, 'Estandar': 1, 'Pendiente': 1, 'RIP': 2}

Pregunta 3 [40%]

Complementando la pregunta 2, se le solicita:

Pregunta 3.a

Escriba la función nuevo_cliente(archivo, rut, nombre, clase) que reciba como parámetro el nombre del archivo de clientes y el rut, nombre y clase de un nuevo cliente. La función debe agregar el nuevo cliente al final del archivo. Esta función retorna None.

>>> nuevo_cliente('clientes.txt', '2121211-2', 'Sergio Lagos', 'VIP')
>>>

Estrategia de solución:

  • ¿Qué estructura tienen los datos de entrada?
  • ¿Qué estructura deben tener los datos de salida?
  • ¿Cómo proceso los inputs para generar el output deseado?

In [15]:
def nuevo_cliente(nombre_archivo, rut, nombre, clase):
    archivo = open(nombre_archivo,"a")
    formato_linea = "{0};{1};{2}\n"
    linea = formato_linea.format(rut, nombre, clase)
    archivo.write(linea)
    archivo.close()
    return None
    
print nuevo_cliente('data/clientes.txt', '2121211-2', 'Sergio Lagos', 'VIP')


None

Pregunta 3.b

Escriba la función actualizar_clase(archivo, rut, clase) que reciba como parámetro el nombre del archivo de clientes, el rut de un cliente y una nueva clase. La función debe modificar la clase del cliente con el rut indicado, cambiándola por clase en el archivo. Esta función retorna True si logra hacer el cambio o False si no encuentra al cliente con el rut indicado.

>>> actualizar_clase('clientes.txt', '9234539-9', 'Estandar')
True

Estrategia de solución:

  • ¿Qué estructura tienen los datos de entrada?
  • ¿Qué estructura deben tener los datos de salida?
  • ¿Cómo proceso los inputs para generar el output deseado?

In [17]:
def actualizar_clase(nombre_archivo, rut_buscado, nueva_clase):
    archivo = open(nombre_archivo)
    lista_lineas = []
    formato_linea = "{0};{1};{2}\n"
    rut_hallado = False
    for linea in archivo:
        rut,nombre,clase = linea[:-1].split(";")
        if rut==rut_buscado:
            nueva_linea = formato_linea.format(rut,nombre,nueva_clase)
            lista_lineas.append(nueva_linea)
            rut_hallado = True
        else:
            lista_lineas.append(linea)
    archivo.close()
    # Ahora escribir todas las lineas, si es necesario
    if rut_hallado:
        archivo = open(nombre_archivo, "w")
        for linea in lista_lineas:
            archivo.write(linea)
        archivo.close()
    return rut_hallado

actualizar_clase('data/clientes.txt', '9234539-9', 'Estandar')


Out[17]:
False

Pregunta 3.c

Escriba una función filtrar_clientes(archivo, clase) que reciba como parámetros el nombre del archivo de clientes y una clase de cliente. La función debe crear un archivo clientes_[clase].txt con los rut y los nombres de los clientes pertenecientes a esa clase. Note que el archivo debe ser nombrado según la clase solicitada. Esta función retorna None.

>>> filtrar_clientes('clientes.txt', 'VIP')
>>>

genera el archivo clientes_VIP.txt con el siguiente contenido

5555555-6;Sebastian Pinera
12312312-1;Michel Bachelet
2121211-2;Sergio Lagos

Estrategia de solución:

  • ¿Qué estructura tienen los datos de entrada?
  • ¿Qué estructura deben tener los datos de salida?
  • ¿Cómo proceso los inputs para generar el output deseado?

In [21]:
def filtrar_clientes(nombre_archivo, clase_buscada):
    archivo_original = open(nombre_archivo)
    nombre_archivo_clase = "data\clientes_"+clase_buscada+".txt"
    archivo_clase = open(nombre_archivo_clase,"w")
    formato_linea = "{0};{1}\n"
    for linea in archivo_original:
        rut,nombre,clase = linea[:-1].split(";")
        if clase==clase_buscada:
            nueva_linea = formato_linea.format(rut,nombre)
            archivo_clase.write(nueva_linea)
    archivo_original.close()
    archivo_clase.close()
    return None
    
filtrar_clientes('data/clientes.txt', 'VIP')