[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:
parent
08dfaef620
commit
a656592601
1 changed files with 70 additions and 13 deletions
|
@ -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)")
|
||||
|
||||
|
|
Loading…
Reference in a new issue