code: def find_n50(self):
          
          for sample in self.metadata:
              # Initialise the N50 attribute in case there is no assembly, and the attribute is not created in the loop
              sample[self.analysistype].n50 = '-'
              # Initialise a variable to store a running total of contig lengths
              currentlength = 0
              for contig_length in sample[self.analysistype].contig_lengths:
                  # Increment the current length with the length of the current contig
                  currentlength += contig_length
                  # If the current length is now greater than the total genome / 2, the current contig length is the N50
                  if currentlength >= sample[self.analysistype].genome_length * 0.5:
                      # Populate the dictionary, and break the loop
                      sample[self.analysistype].n50 = contig_length
                      break
docs: Calculate the N50 for each strain. N50 is defined as the largest contig such that at least half of the total
          genome size is contained in contigs equal to or larger than this contig