diff --git a/src/basic.py b/src/basic.py index e69de29..0fa99c7 100644 --- a/src/basic.py +++ b/src/basic.py @@ -0,0 +1,202 @@ +from datetime import datetime + +class ExcelCalculadora: + + # Validación de que todos los argumentos sean números (int o float) + def __validar_numeros(self, *args): + if not args: + raise ValueError("Se requiere al menos un número.") + for arg in args: + if not isinstance(arg, (int, float)): + raise TypeError(f"Argumento no numérico: {arg}") + + # Validación de que todos los argumentos sean cadenas de texto + def __validar_cadenas(self, *args): + if not args: + raise ValueError("Se requiere al menos una cadena.") + for arg in args: + if not isinstance(arg, str): + raise TypeError(f"Argumento no es cadena: {arg}") + + # Validación combinada: cadena y número entero positivo + def __validar_cadena_y_numero(self, cadena, numero): + if not isinstance(cadena, str): + raise TypeError(f"El primer argumento debe ser una cadena: {cadena}") + if not isinstance(numero, int): + raise TypeError(f"El segundo argumento debe ser un número entero: {numero}") + if numero < 0: + raise ValueError("El número de caracteres no puede ser negativo.") + + # Validación general con control de tipos y cantidad mínima + def __validar_argumentos(self, args, tipos_aceptados=None, cantidad_minima=1): + if len(args) < cantidad_minima: + raise ValueError(f"Se requieren al menos {cantidad_minima} argumentos.") + if tipos_aceptados: + for i, arg in enumerate(args): + if not isinstance(arg, tipos_aceptados) and arg is not None: + raise TypeError(f"Argumento en posición {i} no es del tipo esperado.") + + # --------- Métodos matemáticos --------- + + # Suma de números + def suma(self, *args): + self.__validar_numeros(*args) + return sum(args) + + # Promedio de números + def promedio(self, *args): + self.__validar_numeros(*args) + return sum(args) / len(args) + + # Valor máximo + def maximo(self, *args): + self.__validar_numeros(*args) + return max(args) + + # Valor mínimo + def minimo(self, *args): + self.__validar_numeros(*args) + return min(args) + + # Multiplicación de números + def multiplicar(self, *args): + self.__validar_numeros(*args) + resultado = 1 + for num in args: + resultado *= num + return resultado + + # División con validación de división por cero + def dividir(self, a, b): + self.__validar_numeros(a, b) + if b == 0: + raise ZeroDivisionError("No se puede dividir entre cero.") + return a / b + + # Resta de números + def resta(self, *args): + self.__validar_numeros(*args) + if not args: + return 0 + resultado = args[0] + for h in args[1:]: + resultado -= h + return resultado + + # Potenciación + def potencia(self, base, exponente): + self.__validar_numeros(base, exponente) + if exponente == 0: + return 1 + if base == 0: + return 0 + return base ** exponente + + # Cálculo de raíz n-ésima + def raiz(self, base, indice=2): + self.__validar_numeros(base, indice) + if base < 0: + raise ValueError("No se puede calcular la raíz de un número negativo.") + if indice == 0: + raise ValueError("No existe la raíz 0.") + return base ** (1 / indice) + + # --------- Métodos lógicos --------- + + # Simula la función SI(condición, valor_verdadero, valor_falso) + def si(self, condicion, valor_verdadero, valor_falso): + return valor_verdadero if condicion else valor_falso + + # Evaluación lógica tipo Y + def y(self, *args): + return all(args) + + # Evaluación lógica tipo O + def o(self, *args): + return any(args) + + # --------- Métodos de conteo y búsqueda --------- + + # Cuenta los elementos que son números + def CONTAR(self, *args): + self.__validar_argumentos(args, cantidad_minima=1) + return sum(1 for arg in args if isinstance(arg, (int, float))) + + # Cuenta elementos no vacíos ni None + def CONTARA(self, *args): + self.__validar_argumentos(args, cantidad_minima=1) + return sum(1 for arg in args if arg is not None and arg != "") + + # Cuenta elementos que cumplen una condición en un rango + def CONTAR_SI(self, rango, condicion): + if not isinstance(rango, (list, tuple)): + raise TypeError("El rango debe ser una lista o tupla.") + if not callable(condicion): + raise TypeError("La condición debe ser una función.") + return sum(1 for elem in rango if condicion(elem)) + + # Búsqueda vertical (tipo BUSCARV) + def BUSCARV(self, valor, tabla, columna): + if not isinstance(tabla, list) or not all(isinstance(fila, list) for fila in tabla): + raise TypeError("La tabla debe ser una lista de listas.") + for fila in tabla: + if len(fila) <= columna: + raise IndexError("Columna fuera de rango en alguna fila.") + if fila[0] == valor: + return fila[columna] + raise ValueError("Valor no encontrado en la primera columna.") + + # Búsqueda horizontal (tipo BUSCARH) + def BUSCARH(self, valor, tabla, fila): + if not isinstance(tabla, list) or not all(isinstance(f, list) for f in tabla): + raise TypeError("La tabla debe ser una lista de listas.") + if len(tabla) == 0 or len(tabla[0]) == 0: + raise ValueError("La tabla no puede estar vacía.") + if fila >= len(tabla): + raise IndexError("Número de fila fuera de rango.") + for i, encabezado in enumerate(tabla[0]): + if encabezado == valor: + return tabla[fila][i] + raise ValueError("Valor no encontrado en la primera fila.") + + # Concatenación de elementos como texto + def CONCATENAR(self, *args): + self.__validar_argumentos(args, cantidad_minima=1) + return ''.join(str(arg) for arg in args if arg is not None) + + # --------- Métodos de texto --------- + + # Concatenación de cadenas (solo acepta strings) + def concat(self, *args): + self.__validar_cadenas(*args) + return "".join(args) + + # Extrae caracteres desde el inicio (izquierda) + def izquierda(self, cadena, num_caracteres): + self.__validar_cadena_y_numero(cadena, num_caracteres) + if num_caracteres > len(cadena): + return cadena + return cadena[:num_caracteres] + + # Extrae caracteres desde el final (derecha) + def derecha(self, cadena, num_caracteres): + self.__validar_cadena_y_numero(cadena, num_caracteres) + if num_caracteres > len(cadena): + return cadena + return cadena[-num_caracteres:] + + # Devuelve la longitud de una cadena + def largo(self, cadena): + if not isinstance(cadena, str): + raise TypeError(f"El argumento debe ser una cadena: {cadena}") + return len(cadena) + + # --------- Métodos de fecha y hora --------- + + # Devuelve fecha y hora actual con formato + def ahora(self): + return datetime.now().strftime("%d-%m-%Y %H:%M:%S") + + # Devuelve solo la fecha actual + def hoy(self): + return datetime.now().strftime("%d-%m-%Y") \ No newline at end of file diff --git a/test/test.py b/test/test.py index e69de29..e51888f 100644 --- a/test/test.py +++ b/test/test.py @@ -0,0 +1,155 @@ +from ECSolver.src.basic import ExcelCalculadora + +################################ PRUEBAS DE USO ################################ + +def probar_calculadora(): + calc = ExcelCalculadora() + + print("--- CASOS DE PRUEBA ---\n") + + def test_suma(): + calc = ExcelCalculadora() + resultado = calc.suma(1, 2, 3) + print("Resultado de suma:", resultado) + assert resultado == 6 + + def test_promedio(): + calc = ExcelCalculadora() + resultado = calc.promedio(2, 4, 6) + print("Resultado de promedio:", resultado) + assert resultado == 4.0 + + def test_maximo(): + calc = ExcelCalculadora() + resultado = calc.maximo(10, 50, 20) + print("Resultado de maximo:", resultado) + assert resultado == 50 + + def test_minimo(): + calc = ExcelCalculadora() + resultado = calc.minimo(5, 3, 9) + print("Resultado de minimo:", resultado) + assert resultado == 3 + + def test_multiplicar(): + calc = ExcelCalculadora() + resultado = calc.multiplicar(2, 3, 4) + print("Resultado de multiplicar:", resultado) + assert resultado == 24 + + def test_dividir(): + calc = ExcelCalculadora() + resultado = calc.dividir(10, 2) + print("Resultado de dividir:", resultado) + assert resultado == 5.0 + + def test_resta(): + calc = ExcelCalculadora() + resultado = calc.resta(10, 2, 3) + print("Resultado de resta:", resultado) + assert resultado == 5 + + def test_potencia(): + calc = ExcelCalculadora() + resultado = calc.potencia(2, 3) + print("Resultado de potencia:", resultado) + assert resultado == 8 + + def test_raiz(): + calc = ExcelCalculadora() + resultado1 = calc.raiz(9) + resultado2 = calc.raiz(8, 3) + print("Resultado de raiz(9):", resultado1) + print("Resultado de raiz(8, 3):", resultado2) + assert resultado1 == 3 + assert resultado2 == 2 + + def test_si(): + calc = ExcelCalculadora() + resultado1 = calc.si(True, "ok", "fail") + resultado2 = calc.si(False, "ok", "fail") + print("Resultado de si(True, 'ok', 'fail'):", resultado1) + print("Resultado de si(False, 'ok', 'fail'):", resultado2) + assert resultado1 == "ok" + assert resultado2 == "fail" + + def test_y(): + calc = ExcelCalculadora() + resultado1 = calc.y(True, True, True) + resultado2 = calc.y(True, False, True) + print("Resultado de y(True, True, True):", resultado1) + print("Resultado de y(True, False, True):", resultado2) + assert resultado1 is True + assert resultado2 is False + + def test_o(): + calc = ExcelCalculadora() + resultado1 = calc.o(False, False, True) + resultado2 = calc.o(False, False, False) + print("Resultado de o(False, False, True):", resultado1) + print("Resultado de o(False, False, False):", resultado2) + assert resultado1 is True + assert resultado2 is False + + #Función contar + def test_contar(): + assert calc.CONTAR(1, 2.5, "texto", None) == 2 + + #Función contará + def test_contara(): + assert calc.CONTARA(1, "", None, "hola", 0) == 4 + + #Función contar si + def test_contar_si(): + assert calc.CONTAR_SI([1, 2, 3, 4], lambda x: x > 2) == 2 + + #Función buscarv + def test_buscarv(): + tabla = [["Ana", 30], ["Luis", 25]] + assert calc.BUSCARV("Luis", tabla, 1) == 25 + + #Función buscarh + def test_buscarh(): + tabla = [["Nombre", "Edad"], ["Ana", 30]] + assert calc.BUSCARH("Edad", tabla, 1) == 30 + + #Función concatenar + def test_concatenar(): + assert calc.CONCATENAR("Hola", " ", "mundo", "!") == "Hola mundo!" + + + def test_concat(): + calc = ExcelCalculadora() + resultado = calc.concat("Hola", " ", "mundo") + print("Resultado de concat:", resultado) + assert resultado == "Hola mundo" + + def test_izquierda(): + calc = ExcelCalculadora() + resultado = calc.izquierda("Python", 2) + print("Resultado de izquierda:", resultado) + assert resultado == "Py" + + def test_derecha(): + calc = ExcelCalculadora() + resultado = calc.derecha("Python", 3) + print("Resultado de derecha:", resultado) + assert resultado == "hon" + + def test_largo(): + calc = ExcelCalculadora() + resultado = calc.largo("Python") + print("Resultado de largo:", resultado) + assert resultado == 6 + + def test_ahora(): + calc = ExcelCalculadora() + resultado = calc.ahora() + print("Resultado de ahora:", resultado) + assert isinstance(resultado, str) + + def test_hoy(): + calc = ExcelCalculadora() + resultado = calc.hoy() + print("Resultado de hoy:", resultado) + assert isinstance(resultado, str) \ No newline at end of file