text: from algorithms.genetic import Genome
  from collections import namedtuple
  
  Thing = namedtuple('Thing', ['name', 'value', 'weight'])
  
  first_example = [
      Thing('Laptop', 500, 2200),
      Thing('Headphones', 150, 160),
      Thing('Coffee Mug', 60, 350),
      Thing('Notepad', 40, 333),
      Thing('Water Bottle', 30, 192),
  ]
  
  second_example = [
      Thing('Mints', 5, 25),
      Thing('Socks', 10, 38),
      Thing('Tissues', 15, 80),
      Thing('Phone', 500, 200),
      Thing('Baseball Cap', 100, 70)
  ] + first_example
  
  
  def generate_things(num: int):
      return [Thing(f"thing{i}", i, i) for i in range(1, num+1)]
  
  
  def fitness(genome: Genome, things, weight_limit: int) -> int:
      if len(genome) != len(things):
          raise ValueError("genome and things must be of same length")
  
      weight = 0
      value = 0
      for i, thing in enumerate(things):
          if genome[i] == 1:
              weight += thing.weight
              value += thing.value
  
              if weight > weight_limit:
                  return 0
  
      return value
  
  
  def from_genome(genome: Genome, things):
      result = []
      for i, thing in enumerate(things):
          if genome[i] == 1:
              result += [thing]
  
      return result
  
  
  def to_string(things):
      return f"[{', '.join([t.name for t in things])}]"
  
  
  def value(things):
      return sum([t.value for t in things])
  
  
  def weight(things):
      return sum([p.weight for p in things])
  
  
  def print_stats(things):
      print(f"Things: {to_string(things)}")
      print(f"Value {value(things)}")
      print(f"Weight: {weight(things)}")