[ADDED] Implementar parámetro --type para seleccionar tipo de programador

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Mauro Rosero P. 2025-03-12 14:15:17 -05:00
parent 08dfaef620
commit a656592601
Signed by: mrosero
GPG key ID: 83BD2A5F674B7E26

View file

@ -257,21 +257,70 @@ def determine_cocomo_model(loc):
else:
return 'embedded' # Proyectos grandes (más de 300K líneas)
def get_fullstack_rate():
def get_available_programmer_types():
"""
Obtiene la tarifa por hora de un desarrollador fullstack desde el archivo de configuración.
Si el archivo no existe, devuelve un valor predeterminado de 45.00 USD/hora.
Obtiene una lista de los tipos de programadores disponibles
basados en los archivos .rate existentes en el directorio de tarifas.
Returns:
List: Lista de tipos de programadores disponibles
"""
if not RATES_DIR.exists():
logger.warning(f"El directorio de tarifas no existe: {RATES_DIR}")
return ['fullstack'] # Por defecto solo fullstack si no hay directorio
try:
# Buscar archivos .rate en el directorio
rate_files = list(RATES_DIR.glob('*.rate'))
# Extraer nombres de programadores de los nombres de archivo
programmer_types = [file.stem for file in rate_files]
if not programmer_types:
logger.warning("No se encontraron archivos de tarifas. Usando solo 'fullstack' por defecto.")
return ['fullstack']
return sorted(programmer_types)
except Exception as e:
logger.error(f"Error al buscar tipos de programadores disponibles: {e}")
return ['fullstack'] # En caso de error, devolver tipo por defecto
def get_programmer_rate(programmer_type='fullstack'):
"""
Obtiene la tarifa por hora de un tipo específico de programador desde el archivo de configuración.
Si el archivo no existe, devuelve un valor predeterminado según el tipo.
Args:
programmer_type: Tipo de programador (por defecto: 'fullstack')
Returns:
Float: Tarifa por hora en USD
"""
rate_file = RATES_DIR / "fullstack.rate"
rate_file = RATES_DIR / f"{programmer_type}.rate"
# Valores predeterminados por tipo de programador
default_rates = {
'fullstack': 45.00,
'frontend': 40.00,
'backend': 42.00,
'devops': 50.00,
'python': 35.00,
'java': 40.00,
'php': 30.00,
'mobile': 45.00,
'data': 55.00,
'ml': 65.00,
'cloud': 60.00,
'bash': 20.00
}
default_rate = default_rates.get(programmer_type, 40.00)
# Comprobar si existe el archivo
if not rate_file.exists():
logger.warning(f"No se encontró el archivo de tarifa: {rate_file}")
logger.warning("Usando tarifa predeterminada de 45.00 USD/hora")
return 45.00
logger.warning(f"Usando tarifa predeterminada de {default_rate:.2f} USD/hora para {programmer_type}")
return default_rate
# Leer la tarifa del archivo
try:
@ -281,8 +330,8 @@ def get_fullstack_rate():
return rate
except (FileNotFoundError, ValueError, IOError) as e:
logger.warning(f"Error al leer el archivo de tarifa {rate_file}: {e}")
logger.warning("Usando tarifa predeterminada de 45.00 USD/hora")
return 45.00
logger.warning(f"Usando tarifa predeterminada de {default_rate:.2f} USD/hora para {programmer_type}")
return default_rate
def print_results(results):
"""
@ -307,13 +356,19 @@ def print_results(results):
print("=====================================================\n")
if __name__ == "__main__":
# Obtener los tipos de programadores disponibles para el parámetro --type
available_types = get_available_programmer_types()
available_types_str = ', '.join(available_types)
# Parámetros de línea de comandos
parser = argparse.ArgumentParser(description='Calculadora COCOMO para estimar costos de proyectos de software')
parser.add_argument('--project', required=True, help='Ruta del directorio del proyecto a analizar')
parser.add_argument('--model', choices=['organic', 'semi-detached', 'embedded', 'auto'],
default='auto', help='Tipo de modelo COCOMO a utilizar (por defecto: auto)')
parser.add_argument('--type', choices=available_types, default='fullstack',
help=f'Tipo de programador para calcular costos (por defecto: fullstack). Disponibles: {available_types_str}')
parser.add_argument('--cost', type=float,
help='Costo por persona-mes en USD (por defecto: tarifa fullstack × 176)')
help='Costo por persona-mes en USD (por defecto: tarifa del tipo de programador × 176)')
parser.add_argument('--ignore', action='append',
help='Patrones adicionales de archivos a ignorar')
parser.add_argument('--ext', action='append',
@ -348,16 +403,18 @@ if __name__ == "__main__":
except Exception as e:
logger.error(f"Error al crear el directorio de tarifas: {e}")
# Obtener costo por hora desde fullstack.rate y convertir a costo por persona-mes
programmer_type = 'fullstack' # Por defecto usamos la tarifa de fullstack
# Obtener tipo de programador y su tarifa
programmer_type = args.type # Usar el tipo especificado por el usuario
# Obtener costo por hora desde el archivo .rate y convertir a costo por persona-mes
if args.cost is None:
# Obtener la tarifa por hora y multiplicar por las horas mensuales
hourly_rate = get_fullstack_rate()
hourly_rate = get_programmer_rate(programmer_type)
cost_per_pm = hourly_rate * HOURS_PER_MONTH
logger.info(f"Costo por hora ({programmer_type}): ${hourly_rate:.2f} × {HOURS_PER_MONTH} horas = ${cost_per_pm:.2f} por persona-mes")
else:
cost_per_pm = args.cost
programmer_type = 'personalizado' # Si se especifica manualmente
programmer_type = f"{programmer_type} (personalizado)" # Indicar que es un valor personalizado
hourly_rate = cost_per_pm / HOURS_PER_MONTH
logger.info(f"Usando costo por persona-mes especificado: ${cost_per_pm:.2f} (${hourly_rate:.2f}/hora)")