[IMPROVED] Calcular tarifa de fullstack como 1.5 veces el valor máximo encontrado
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
9b4288492c
commit
604786ad5f
1 changed files with 173 additions and 1 deletions
|
@ -448,6 +448,23 @@ def update_single_rate(programmer_type):
|
|||
# Crear la carpeta rates si no existe
|
||||
os.makedirs(RATES_DIR, exist_ok=True)
|
||||
|
||||
# Diccionario para almacenar las tarifas calculadas y existentes
|
||||
rates_dict = {}
|
||||
|
||||
# Si es fullstack, necesitamos primero obtener el valor más alto de todos los tipos
|
||||
if programmer_type == 'fullstack':
|
||||
# Leer las tarifas existentes
|
||||
for prog_type in get_programmer_types():
|
||||
if prog_type != 'fullstack':
|
||||
rate_file = RATES_DIR / f"{prog_type}.rate"
|
||||
if rate_file.exists():
|
||||
try:
|
||||
with open(rate_file, 'r', encoding='utf-8') as f:
|
||||
rates_dict[prog_type] = float(f.read().strip())
|
||||
logger.info(f"Tarifa leída para {prog_type}: {rates_dict[prog_type]:.2f}")
|
||||
except (FileNotFoundError, ValueError) as e:
|
||||
logger.warning(f"Error al leer tarifa de {prog_type}: {e}")
|
||||
|
||||
# Si es bash, necesitamos primero obtener o actualizar la tarifa de devops
|
||||
devops_rate = None
|
||||
if programmer_type == 'bash':
|
||||
|
@ -460,6 +477,7 @@ def update_single_rate(programmer_type):
|
|||
try:
|
||||
with open(devops_rate_file, 'r', encoding='utf-8') as f:
|
||||
devops_rate = float(f.read().strip())
|
||||
rates_dict['devops'] = devops_rate
|
||||
logger.info(f"Tarifa leída para devops: {devops_rate:.2f}")
|
||||
except (FileNotFoundError, ValueError) as e:
|
||||
logger.error(f"Error al leer tarifa de devops: {e}")
|
||||
|
@ -502,6 +520,9 @@ def update_single_rate(programmer_type):
|
|||
with open(devops_rate_file, 'w', encoding='utf-8') as f:
|
||||
f.write(f"{devops_rate:.2f}")
|
||||
|
||||
# Añadir al diccionario
|
||||
rates_dict['devops'] = devops_rate
|
||||
|
||||
# Mostrar el resultado en la consola
|
||||
result_message = f"Tarifa para devops: {devops_rate:.2f} USD/hora"
|
||||
logger.info(f"Actualizado archivo {devops_rate_file} con valor: {devops_rate:.2f}")
|
||||
|
@ -518,6 +539,47 @@ def update_single_rate(programmer_type):
|
|||
logger.info(f"Calculando tarifa para bash como 0.4 * {devops_rate:.2f}")
|
||||
rate = 0.4 * devops_rate
|
||||
logger.info(f"Tarifa calculada para bash: {rate:.2f}")
|
||||
# Caso especial para fullstack
|
||||
elif programmer_type == 'fullstack':
|
||||
# Primero calculamos el valor más alto entre todos los tipos
|
||||
max_rate_value = 0.0
|
||||
for prog_type, rate_value in rates_dict.items():
|
||||
if prog_type != 'fullstack' and rate_value > max_rate_value:
|
||||
max_rate_value = rate_value
|
||||
|
||||
logger.info(f"Valor más alto encontrado: {max_rate_value:.2f}")
|
||||
|
||||
# Obtener tarifa para fullstack vía API
|
||||
api_rate = None
|
||||
if api_available:
|
||||
prompt = generate_prompt_base(programmer_type)
|
||||
logger.info(f"Consultando tarifa para {programmer_type}")
|
||||
|
||||
try:
|
||||
# Consultar a Perplexity
|
||||
api_rate = query_perplexity(prompt, model)
|
||||
|
||||
if api_rate is not None:
|
||||
logger.info(f"Tarifa obtenida correctamente: {api_rate:.2f}")
|
||||
else:
|
||||
logger.error(f"No se pudo obtener la tarifa para {programmer_type}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error al consultar tarifa para {programmer_type}: {e}")
|
||||
|
||||
# Si la API falló, usar el valor predeterminado
|
||||
if api_rate is None:
|
||||
logger.warning(f"Usando valor predeterminado para {programmer_type}")
|
||||
api_rate = get_default_rate(programmer_type)
|
||||
logger.info(f"Valor predeterminado: {api_rate:.2f}")
|
||||
|
||||
# Calcular el valor de fullstack
|
||||
# Si el valor de la API es menor o igual al valor más alto, usar 1.5 veces el valor más alto
|
||||
if api_rate <= max_rate_value:
|
||||
rate = 1.5 * max_rate_value
|
||||
logger.info(f"API rate ({api_rate:.2f}) <= max rate ({max_rate_value:.2f}), ajustando fullstack a 1.5 * {max_rate_value:.2f} = {rate:.2f}")
|
||||
else:
|
||||
rate = api_rate
|
||||
logger.info(f"API rate ({api_rate:.2f}) > max rate ({max_rate_value:.2f}), manteniendo valor API")
|
||||
else:
|
||||
# Para otros tipos, procedemos como antes
|
||||
prompt = generate_prompt_base(programmer_type)
|
||||
|
@ -593,6 +655,23 @@ def update_rate_files(force_update=False):
|
|||
programmer_types = get_programmer_types()
|
||||
logger.info(f"Procesando {len(programmer_types)} tipos de programadores.")
|
||||
|
||||
# Diccionario para almacenar las tarifas ya calculadas
|
||||
rates_dict = {}
|
||||
|
||||
# Leer las tarifas existentes primero
|
||||
if 'fullstack' in programmer_types:
|
||||
# Primero leer los valores existentes de tipos que no vamos a actualizar
|
||||
for prog_type in get_programmer_types():
|
||||
if prog_type not in programmer_types:
|
||||
rate_file = RATES_DIR / f"{prog_type}.rate"
|
||||
if rate_file.exists():
|
||||
try:
|
||||
with open(rate_file, 'r', encoding='utf-8') as f:
|
||||
rates_dict[prog_type] = float(f.read().strip())
|
||||
logger.info(f"Tarifa leída para {prog_type}: {rates_dict[prog_type]:.2f}")
|
||||
except (FileNotFoundError, ValueError) as e:
|
||||
logger.warning(f"Error al leer tarifa de {prog_type}: {e}")
|
||||
|
||||
# Procesamos primero devops siempre que force_update sea True o bash esté pendiente
|
||||
devops_rate = None
|
||||
need_devops_for_bash = ('bash' in programmer_types and (not (RATES_DIR / "bash.rate").exists() or force_update))
|
||||
|
@ -638,6 +717,9 @@ def update_rate_files(force_update=False):
|
|||
with open(devops_rate_file, 'w', encoding='utf-8') as f:
|
||||
f.write(f"{devops_rate:.2f}")
|
||||
|
||||
# Guardar en el diccionario de tarifas
|
||||
rates_dict['devops'] = devops_rate
|
||||
|
||||
# Mostrar el resultado en la consola
|
||||
result_message = f"Tarifa para devops: {devops_rate:.2f} USD/hora"
|
||||
logger.info(f"{'Actualizado' if force_update else 'Creado'} archivo {devops_rate_file} con valor: {devops_rate:.2f}")
|
||||
|
@ -657,18 +739,35 @@ def update_rate_files(force_update=False):
|
|||
try:
|
||||
with open(devops_rate_file, 'r', encoding='utf-8') as f:
|
||||
devops_rate = float(f.read().strip())
|
||||
rates_dict['devops'] = devops_rate
|
||||
logger.info(f"Tarifa leída para devops: {devops_rate:.2f}")
|
||||
except (FileNotFoundError, ValueError) as e:
|
||||
logger.error(f"Error al leer tarifa de devops: {e}")
|
||||
devops_rate = get_default_rate('devops')
|
||||
rates_dict['devops'] = devops_rate
|
||||
|
||||
# Procesar cada tipo de programador
|
||||
# Procesar los demás tipos de programador antes de fullstack
|
||||
fullstack_type = None
|
||||
if 'fullstack' in programmer_types:
|
||||
# Guardar para procesarlo después
|
||||
fullstack_type = 'fullstack'
|
||||
# Eliminarlo temporalmente de la lista
|
||||
programmer_types.remove('fullstack')
|
||||
|
||||
# Procesar cada tipo de programador (excepto fullstack)
|
||||
for programmer_type in programmer_types:
|
||||
# Comprobar si ya existe el archivo para este tipo de programador
|
||||
rate_file = RATES_DIR / f"{programmer_type}.rate"
|
||||
|
||||
# Si el archivo ya existe y no estamos forzando la actualización, saltamos este tipo
|
||||
if rate_file.exists() and not force_update:
|
||||
# Leer el valor para almacenarlo en el diccionario
|
||||
try:
|
||||
with open(rate_file, 'r', encoding='utf-8') as f:
|
||||
rates_dict[programmer_type] = float(f.read().strip())
|
||||
except (FileNotFoundError, ValueError) as e:
|
||||
logger.warning(f"Error al leer archivo {rate_file}: {e}")
|
||||
|
||||
logger.info(f"El archivo {rate_file} ya existe. Saltando.")
|
||||
continue
|
||||
|
||||
|
@ -713,6 +812,9 @@ def update_rate_files(force_update=False):
|
|||
logger.warning(f"Ajustando tarifa {rate:.2f} al máximo permitido de {max_rate}")
|
||||
rate = max_rate
|
||||
|
||||
# Guardar la tarifa en el diccionario
|
||||
rates_dict[programmer_type] = rate
|
||||
|
||||
# Guardar el resultado en el archivo - solo el valor numérico con dos decimales, sin salto de línea
|
||||
with open(rate_file, 'w', encoding='utf-8') as f:
|
||||
f.write(f"{rate:.2f}")
|
||||
|
@ -724,6 +826,76 @@ def update_rate_files(force_update=False):
|
|||
|
||||
# Pequeña pausa para no sobrecargar la API
|
||||
time.sleep(1)
|
||||
|
||||
# Procesar fullstack al final si está en la lista
|
||||
if fullstack_type:
|
||||
rate_file = RATES_DIR / f"{fullstack_type}.rate"
|
||||
|
||||
# Si el archivo ya existe y no estamos forzando la actualización, saltamos
|
||||
if rate_file.exists() and not force_update:
|
||||
# Leer el valor para mostrarlo
|
||||
try:
|
||||
with open(rate_file, 'r', encoding='utf-8') as f:
|
||||
fullstack_rate = float(f.read().strip())
|
||||
logger.info(f"El archivo {rate_file} ya existe con valor {fullstack_rate:.2f}. Saltando.")
|
||||
except (FileNotFoundError, ValueError) as e:
|
||||
logger.warning(f"Error al leer archivo {rate_file}: {e}")
|
||||
return
|
||||
|
||||
# Primero calculamos el valor más alto entre todos los tipos
|
||||
max_rate_value = 0.0
|
||||
for prog_type, rate_value in rates_dict.items():
|
||||
if prog_type != 'fullstack' and rate_value > max_rate_value:
|
||||
max_rate_value = rate_value
|
||||
|
||||
logger.info(f"Valor más alto encontrado: {max_rate_value:.2f}")
|
||||
|
||||
# Obtener tarifa para fullstack vía API
|
||||
api_rate = None
|
||||
if api_available:
|
||||
prompt = generate_prompt_base(fullstack_type)
|
||||
logger.info(f"Consultando tarifa para {fullstack_type}")
|
||||
|
||||
try:
|
||||
# Consultar a Perplexity
|
||||
api_rate = query_perplexity(prompt, model)
|
||||
|
||||
if api_rate is not None:
|
||||
logger.info(f"Tarifa obtenida correctamente: {api_rate:.2f}")
|
||||
else:
|
||||
logger.error(f"No se pudo obtener la tarifa para {fullstack_type}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error al consultar tarifa para {fullstack_type}: {e}")
|
||||
|
||||
# Si la API falló, usar el valor predeterminado
|
||||
if api_rate is None:
|
||||
logger.warning(f"Usando valor predeterminado para {fullstack_type}")
|
||||
api_rate = get_default_rate(fullstack_type)
|
||||
logger.info(f"Valor predeterminado: {api_rate:.2f}")
|
||||
|
||||
# Calcular el valor de fullstack
|
||||
# Si el valor de la API es menor o igual al valor más alto, usar 1.5 veces el valor más alto
|
||||
if api_rate <= max_rate_value:
|
||||
fullstack_rate = 1.5 * max_rate_value
|
||||
logger.info(f"API rate ({api_rate:.2f}) <= max rate ({max_rate_value:.2f}), ajustando fullstack a 1.5 * {max_rate_value:.2f} = {fullstack_rate:.2f}")
|
||||
else:
|
||||
fullstack_rate = api_rate
|
||||
logger.info(f"API rate ({api_rate:.2f}) > max rate ({max_rate_value:.2f}), manteniendo valor API")
|
||||
|
||||
# Limitar a tarifas menores de 200 USD/hora
|
||||
max_limit = 200.00
|
||||
if fullstack_rate > max_limit:
|
||||
logger.warning(f"Ajustando tarifa {fullstack_rate:.2f} al máximo permitido de {max_limit}")
|
||||
fullstack_rate = max_limit
|
||||
|
||||
# Guardar el resultado en el archivo
|
||||
with open(rate_file, 'w', encoding='utf-8') as f:
|
||||
f.write(f"{fullstack_rate:.2f}")
|
||||
|
||||
# Mostrar el resultado en la consola
|
||||
result_message = f"Tarifa para {fullstack_type}: {fullstack_rate:.2f} USD/hora"
|
||||
logger.info(f"{'Actualizado' if force_update and rate_file.exists() else 'Creado'} archivo {rate_file} con valor: {fullstack_rate:.2f}")
|
||||
show_result(result_message)
|
||||
|
||||
def generate_prompt_base(programmer_type):
|
||||
"""
|
||||
|
|
Loading…
Reference in a new issue