<jupyter_start><jupyter_text>miércoles 22 de abril de 2019_<NAME>_  _Departamento de Ingeniería Informática (DIINF)_  _Universidad de Santiago de Chile (USACH)_ Tarea 1 - Distributed systems for Big DataA continuación se presentan las implementaciones de código de los ejercicios asignados y que se contemplan en el libro [The Python Workbook](https://link.springer.com/book/10.1007/978-3-319-14240-1) de <NAME>son.     Ejercicio N° 43: De Fechas a Nombres de FeriadosCanadá tiene tres feriados nacionales que caen en las mismas fechas cada año.| Feriado        | Fecha       ||----------------|-------------|| New year’s day | January 1   || Canada day     | July 1      || Christmas day  | December 25 |Escriba un programa que lea un mes y un día del usuario. Si el mes y el día coinciden con uno de los feriados enumerados anteriormente, entonces su programa debería mostrar el nombre del feriado. De lo contrario, su programa debería indicar que el mes y el día ingresados no corresponden a un día festivo de fecha fija.<jupyter_code>holidays = {
    "January 1":"New year's day",
    "July 1":"Canada day",
    "December 25":"Christmas day"
}

month = input("Ingrese un mes (EN INGLÉS): ")
day = input("Ingresa un día para ese mes (i.e. 24): ")
date = month.capitalize() + " " + day
if date in holidays:
    print(f"Nombre del feriado: {holidays[date]}")
    print(f"Fecha del feriado: {date}")
else:
    print(f"El {date} no corresponde a un día festivo de fecha fija")<jupyter_output>Nombre del feriado: New year's day
Fecha del feriado: January 1<jupyter_text>Ejercicio N° 61: PromedioEn este ejercicio creará un programa que calcula el promedio de una colección de valores ingresados por el usuario. El usuario ingresará 0 como valor centinela para indicar que no se proporcionarán más valores. Su programa debe mostrar un mensaje de error apropiado si el primer valor ingresado por el usuario es 0.<jupyter_code>colection = []
counter = 0

while True:
    value = input("Ingrese un número a añadir a la colección (Ingrese 0 para finalizar): ")
    if value.isdigit():
        value = int(value)
    if counter is 0 and value is 0:
        print(f'ERROR: Debe ingresar por lo menos 1 número a la colección')
        break
    if value is not 0:
        counter += 1
        colection.append(value)
    else:
        break

if counter is not 0:
    sum = 0
    for digit in colection:
        sum += digit
    average = sum / counter
    print(f'La colección ingresada es {colection}')
    print(f'El promedio de la colección es de números es: {average}')<jupyter_output>La colección ingresada es [1, 2, 3, 4, 5]
El promedio de la colección es de números es: 3.0<jupyter_text>Ejercicio N° 79: Máximo EnteroCree un programa que comience seleccionando un número entero aleatorio entre 1 y 100. Guarde este número entero como el número máximo encontrado hasta ahora. Después de que se haya seleccionado el entero inicial, genere 99 enteros aleatorios adicionales entre 1 y 100. Verifique cada entero tal como se genera para ver si es mayor que el número máximo encontrado hasta aquí. Si es así, su programa debería actualizar el número máximo encontrado y contar el hecho de que realizó una actualización. Muestra cada número entero después de generarlo. Incluya una notación con esos enteros que representan un nuevo máximo.Después de haber mostrado 100 enteros, su programa debería mostrar el valor máximo encontrado, junto con la cantidad de veces que el valor máximo se actualizó durante el proceso.<jupyter_code>import random

i = 1
previous_maximum = random.randint(1, 100)
counter_maximum = 0
print(previous_maximum)

while i < 100:
    actual_maximum = random.randint(1, 100)
    output = str(actual_maximum)
    if actual_maximum > previous_maximum:
        previous_maximum = actual_maximum
        output += " <== Actualización del máximo"
        counter_maximum += 1
    print(output)
    i += 1

print(f'El máximo valor encontrado fue: {previous_maximum}',
      f'El máximo valor fue actualizado {counter_maximum}', sep = '\n')<jupyter_output>62
80 <== Actualización del máximo
55
10
81 <== Actualización del máximo
48
40
87 <== Actualización del máximo
88 <== Actualización del máximo
20
95 <== Actualización del máximo
46
96 <== Actualización del máximo
50
76
88
28
18
12
28
71
65
75
92
73
90
49
50
39
71
42
24
61
54
96
80
70
55
57
9
88
67
69
94
20
99 <== Actualización del máximo
4
62
20
72
76
93
62
61
38
73
39
38
24
54
83
83
21
43
47
22
28
78
81
39
34
7
89
1
97
15
99
29
80
8
41
78
88
12
21
33
86
21
64
57
78
50
2
85
85
89
4
26
34
52
El máximo valor encontrado fue: 99
El máximo valor fue actualizado 7<jupyter_text>Ejercicio N° 98: Dígitos Hexadecimales y DecimalesEscriba dos funciones, **hex2int** e **int2hex**, que conviertan entre dígitos hexadecimales (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E y F) y enteros de base 10. La función hex2int es responsable de convertir una cadena que contiene un solo dígito hexadecimal en un entero de base 10, mientras que la función int2hex es responsable de convertir un entero entre 0 y 15 en un solo dígito hexadecimal. Cada función tomará el valor para convertir como su único parámetro y devolverá el valor convertido como el único resultado de la función. Asegúrese de que la función hex2int funcione correctamente para letras mayúsculas y minúsculas. Sus funciones deberían finalizar el programa con un mensaje de error significativo si se proporciona un parámetro no válido.<jupyter_code>def hex2int(hex_digit):
    if not isinstance(hex_digit, str):
        print("ERROR: El parámetro ingresado no corresponde a un 'string'")
        return -1
    hex_digits = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']
    hex_digit = hex_digit.upper()
    if not hex_digit in hex_digits:
        print("ERROR: El parámetro ingresado no corresponde a un dígito hexadecimal")
        return -1
    return hex_digits.index(hex_digit)

def int2hex(int_digit):
    if not isinstance(int_digit, int):
        print("ERROR: El parámetro ingresado no corresponde a un 'int'")
        return -1
    hex_digits = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']
    if not (0 <= int_digit <= 15):
        print("ERROR: El parámetro ingresado no corresponde a un dígito válido " \
              "para ser convertido en hexadecimal")
        return -1
    return hex_digits[int_digit]

hex_digit = input("Ingrese el dígito hexadecimal a convertir en decimal: ")
int_digit = int(input("Ingrese el dígito decimal a convertir en hexadecimal: "))

result_hex2int = hex2int(hex_digit)
result_int2hex = int2hex(int_digit)

if result_hex2int != -1:
    print(f"El dígito hexadecimal {hex_digit} es equivalente a {result_hex2int} en decimal")

if result_int2hex != -1:
    print(f"El dígito decimal {int_digit} es equivalente a {result_int2hex} en hexadecimal")<jupyter_output>El dígito hexadecimal B es equivalente a 11 en decimal
El dígito decimal 15 es equivalente a F en hexadecimal<jupyter_text>Ejercicio N° 114: Números Aleatorios de LoteríaPara ganar el primer premio en una lotería en particular, uno debe hacer coincidir los 6 números en su boleto con los 6 números entre 1 y 49 que son sorteados por el organizador de la lotería. Escriba un programa que genere una selección aleatoria de 6 números para un boleto de lotería. Asegúrese de que los 6 números seleccionados no contengan duplicados. Mostrar los números en orden ascendente.<jupyter_code>import random
def get_lottery_ticket():
    i = 0
    ticket = list()
    while i < 6:
        random_number = random.randint(1, 49)
        if not (random_number in ticket):
            ticket.append(random_number)
            i += 1
    ticket.sort()
    return ticket

ticket = get_lottery_ticket()
print("El ticket generado es:", ticket)<jupyter_output>El ticket generado es: [7, 19, 32, 38, 39, 42]<jupyter_text>Ejercicio N° 132: Códigos PostalesEn un código postal canadiense, el primer, tercer y quinto caracteres son letras, mientras que el segundo, cuarto y sexto caracteres son números. La provincia se puede determinar a partir del primer carácter de un código postal, como se muestra en la siguiente tabla. Actualmente, no hay códigos postales válidos que comiencen con D, F, I, O, Q, U, W o Z.| Provincia             | Primer(os) carácter(es) ||-----------------------|-------------------------|| Newfoundland          | A                       || Nova Scotia           | B                       || Prince Edward Island  | C                       || New Brunswick         | E                       || Quebec                | G, H y J                || Ontario               | K, L, M, N y P          || Manitoba              | R                       || Saskatchewan          | S                       || Alberta               | T                       || British Columbia      | V                       || Nunavut               | X                       || Northwest Territories | X                       || Yukon                 | Y                       |El segundo carácter en un código postal identifica si la dirección es rural o urbana. Si ese carácter es un 0, entonces la dirección es rural. De lo contrario, es urbano.Cree un programa que lea un código postal del usuario y muestre la provincia asociada con él, junto con si la dirección es urbana o rural. Por ejemplo, si el usuario ingresa T2N 1N4, entonces su programa debe indicar que el código postal es para una dirección urbana en Alberta. Si el usuario ingresa X0A 1B2, entonces su programa debe indicar que el código postal es para una dirección rural en Nunavut o los Territorios del Noroeste. Use un diccionario para asignar desde el primer carácter del código postal al nombre de la provincia. Mostrar un mensaje de error significativo si el código postal comienza con un carácter no válido.<jupyter_code>postal_codes = {
    'A':'Newfoundland',
    'B':'Nova Scotia',
    'C':'Prince Edward Island',
    'E':'New Brunswick',
    'G':'Quebec',
    'H':'Quebec',
    'J':'Quebec',
    'K':'Ontario',
    'L':'Ontario',
    'N':'Ontario',
    'M':'Ontario',
    'P':'Ontario',
    'R':'Manitoba',
    'S':'Saskatchewan',
    'T':'Alberta',
    'V':'British Columbia',
    'X':('Nunavut','Northwest Territories'),
    'Y':'Yukon'
}

def check_postal_code(postal_code):
    if not isinstance(postal_code, str):
        print("ERROR: El parámetro ingresado no corresponde a un 'string'")
        return None
    province = postal_code[0]
    direction_type = postal_code[1]
    if not province in postal_codes.keys() or not direction_type.isnumeric():
        print("ERROR: El código postal contiene un carácter que no es reconocible")
        return None
    province = postal_codes[province]
    direction_type = int(direction_type)
    if direction_type == 0: direction_type = 'rural'
    else: direction_type = 'urbana'
    return f'El código postal {postal_code} pertenece a una dirección {direction_type} de {province}'

postal_code = input('Ingrese un código postal: ')
postal_code = check_postal_code(postal_code)
print(postal_code)<jupyter_output>El código postal T2N 1N4 pertenece a una dirección urbana de Alberta<jupyter_text>Ejercicio N° 150: Remover ComentariosPython usa el carácter  para marcar el comienzo de un comentario. El comentario termina al final de la línea que contiene el carácter . En este ejercicio, creará un programa que eliminará todos los comentarios de un archivo fuente de Python. Verifique cada línea en el archivo para determinar si hay un carácter  presente. Si es así, su programa debería eliminar todos los caracteres del carácter  hasta el final de la línea (ignoraremos la situación en la que el carácter del comentario aparece dentro de una cadena). Guarde el archivo modificado con un nuevo nombre que será ingresado por el usuario. El usuario también ingresará el nombre del archivo de entrada. Asegúrese de que se muestre un mensaje de error apropiado si se encuentra un problema al acceder a los archivos.<jupyter_code>import os
dirname = os.getcwd() + "\\"

try:
    in_name = input("Ingrese el nombre de un archivo Python: ")
    inf = open(dirname + in_name, 'r')
except:
    print("Se ha encontrado un problema mientras se abría el archivo de entrada.")
    print("Saliendo...")
    quit()

try:
    out_name = input("Ingrese el nombre del archivo de salida: ")
    outf = open(dirname + out_name, "w")
except:
    print("Se ha encontrado un problema mientras se abría el archivo de salida.")
    print("Saliendo...")
    quit()

try:
    for line in inf:
        pos = line.find("#")
        if pos > -1:
            line = line[0 : pos]
            line = line + "\n"
        outf.write(line)
    inf.close()
    outf.close()
except:
    print("Se ha encontrado un problema mientras se procesaba el archivo.")
    print("Saliendo...")
    quit()<jupyter_output><empty_output><jupyter_text>Ejercicio N° 168: Raíz Cuadrada RecursivaCree una función de raíz cuadrada que tome dos parámetros. El primer parámetro, **n**, será el número para el que se calcula la raíz cuadrada. El segundo parámetro, **guess**, será la estimación actual para la raíz cuadrada. El parámetro **guess** debe tener un valor predeterminado de 1.0. No proporcione un valor predeterminado para el primer parámetro.Su función de raíz cuadrada será recursiva. El caso base ocurre cuando $guess^2$ está dentro de $10^{−12}$ de n. En este caso, su función debe devolver **guess** porque está lo suficientemente cerca de la raíz cuadrada de n. De lo contrario, su función debería devolver el resultado de llamarse recursivamente con n como primer parámetro y $\frac{guess + \frac{n}{guess}}{2}$Escriba un programa principal que demuestre su función de raíz cuadrada calculando la raíz cuadrada de varios valores diferentes. Cuando llama a su función de raíz cuadrada desde el programa principal, solo debe pasarle un parámetro para que se use el valor predeterminado para **guess**.<jupyter_code>def wrong_input_handling(data):
    while True:
        try:
            data = float(data)
        except ValueError:
            print("ERROR: Acaba de ingresar algo no reconocible como un número")
            data = input("Ingrese un número positivo: ")
            continue
        if data < 0:
            print("ERROR: El algoritmo no permite calcular raíces para número negativos")
            data = input("Ingrese un número positivo: ")
            continue
        else:
            break
    return data


def square_root(number, guess = 1):
    number = wrong_input_handling(number)
    if number == 0:
        return 0
    elif number < 0: 
        return 
    else:    
        if abs(guess**2 - number) < 10**(-12) * number:
            return guess
        else:
            guess = (guess + (number/guess)) / 2
            return square_root(number, guess)
    
number = input("Ingrese el número a buscar la raíz: ")
print(f"La raíz aproximada de {number} es: {square_root(number)}")<jupyter_output>La raíz aproximada de 2 es: 1.414213562373095
{'fraction_non_alphanumeric': 0.08286114259049397, 'fraction_numerical': 0.02926471568562096, 'mean_word_length': 3.231875881523272, 'pattern_counts': {'":': 3, '<': 43, '<?xml version=': 0, '>': 30, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '208105', 'license': 'MIT', 'n_tokens_mistral': 5201, 'n_tokens_neox': 4915, 'n_words': 1904, 'path': 'Tarea 1/Tarea1-BigData.ipynb', 'repo_name': 'BHernandez18/distributed_systems_big-data', 'size': '15025'}