code: from pathlib import Path
  
  import click
  import numpy as np
  
  from knapsack_solver.knapsack_problem import KnapsackProblem
  from knapsack_solver.plots_util import save_plots
  from knapsack_solver.weight import Weight
  
  
  @click.command()
  @click.argument("output-directory", type=click.Path(file_okay=False))
  @click.option("--mean-mass", type=float, default=5.0)
  @click.option("--mass-std", type=float, default=1.0)
  @click.option("--mean-value", type=float, default=5.0)
  @click.option("--value-std", type=float, default=1.0)
  @click.option("--number-of-weights", type=int, default=100)
  @click.option("--generation-size", type=int, default=50)
  @click.option("--max-mass", type=float, default=25)
  @click.option("--max-iterations", type=int, default=50)
  @click.option("--mutation-rate", type=float, default=0.1)
  @click.option("--crossover-rate", type=float, default=0.3)
  def knapsack_solver_cli(
      output_directory,
      mean_mass,
      mass_std,
      mean_value,
      value_std,
      number_of_weights,
      max_mass,
      max_iterations,
      generation_size,
      mutation_rate,
      crossover_rate,
  ):
      output_directory = Path(output_directory)
      output_directory.mkdir(parents=True, exist_ok=True)
      weights = [
          Weight.random(
              identification=i,
              mean_mass=mean_mass,
              mass_std=mass_std,
              mean_value=mean_value,
              value_std=value_std,
          )
          for i in range(1, number_of_weights + 1)
      ]
      problem = KnapsackProblem(
          weights=weights,
          max_mass=max_mass,
          generation_size=generation_size,
          mutation_rate=mutation_rate,
          crossover_rate=crossover_rate,
      )
      history = []
      generation = problem.create_generation()
      history.append(generation)
      with click.progressbar(np.arange(1, max_iterations + 1), show_pos=True) as bar:
          for i in bar:
              generation = problem.create_next_generation(generation, identification=i)
              history.append(generation)
              bar.label = f"Best sack value: {generation.max_value():.2f}"
  
      best_sack = generation.best_sack()
      click.echo(f"Best sack: {best_sack}")
      for weight in best_sack:
          click.echo(f"\t{weight}")
  
      save_plots(
          output_directory=output_directory, weights=problem.weights, history=history
      )
  
  
  if __name__ == "__main__":
      knapsack_solver_cli()
  
apis: numpy.arange