Task: Bioinformatics_Sequence mutation







Python: import random
from collections import Counter

def basecount(dna):
    return sorted(Counter(dna).items())

def seq_split(dna, n=50):
    return [dna[i: i+n] for i in range(0, len(dna), n)]

def seq_pp(dna, n=50):
    for i, part in enumerate(seq_split(dna, n)):
        print(f"{i*n:>5}: {part}")
    print("\n  BASECOUNT:")
    tot = 0
    for base, count in basecount(dna):
        print(f"    {base:>3}: {count}")
        tot += count
    base, count = 'TOT', tot
    print(f"    {base:>3}= {count}")

def seq_mutate(dna, count=1, kinds="IDSSSS", choice="ATCG" ):
    mutation = []
    k2txt = dict(I='Insert', D='Delete', S='Substitute')
    for _ in range(count):
        kind = random.choice(kinds)
        index = random.randint(0, len(dna))
        if kind == 'I':    
            dna = dna[:index] + random.choice(choice) + dna[index:]
        elif kind == 'D' and dna:  
            dna = dna[:index] + dna[index+1:]
        elif kind == 'S' and dna:  
            dna = dna[:index] + random.choice(choice) + dna[index+1:]
        mutation.append((k2txt[kind], index))
    return dna, mutation

if __name__ == '__main__':
    length = 250
    print("SEQUENCE:")
    sequence = ''.join(random.choices('ACGT', weights=(1, 0.8, .9, 1.1), k=length))
    seq_pp(sequence)
    print("\n\nMUTATIONS:")
    mseq, m = seq_mutate(sequence, 10)
    for kind, index in m:
        print(f" {kind:>10} @{index}")
    print()
    seq_pp(mseq)





Ada: with Ada.Containers.Vectors;
with Ada.Numerics.Discrete_Random;
with Ada.Text_Io;

procedure Mutations is

   Width : constant := 60;

   type Nucleotide_Type is (A, C, G, T);
   type Operation_Type is (Delete, Insert, Swap);
   type Position_Type is new Natural;

   package Position_Io   is new Ada.Text_Io.Integer_Io (Position_Type);
   package Nucleotide_Io is new Ada.Text_Io.Enumeration_Io (Nucleotide_Type);
   package Operation_Io  is new Ada.Text_Io.Enumeration_Io (Operation_Type);

   use Ada.Text_Io, Position_Io, Nucleotide_Io, Operation_Io;

   package Sequence_Vectors is new Ada.Containers.Vectors (Index_Type   => Position_Type,
                                                           Element_Type => Nucleotide_Type);
   package Nucleotide_Generators is new Ada.Numerics.Discrete_Random (Result_Subtype => Nucleotide_Type);
   package Operation_Generators  is new Ada.Numerics.Discrete_Random (Result_Subtype => Operation_Type);

   procedure Pretty_Print (Sequence : Sequence_Vectors.Vector) is
      First : Position_Type := Sequence.First_Index;
      Last  : Position_Type;
      Count : array (Nucleotide_Type) of Natural := (others  => 0);
   begin
      Last := Position_Type'Min (First + Width - 1,
                                 Sequence.Last_Index);
      loop
         Position_Io.Put (First, Width => 4);
         Put (": ");
         for N in First .. Last loop
            declare
               Nucleotide : Nucleotide_Type renames Sequence (N);
            begin
               Put (Nucleotide);
               Count (Nucleotide) := Count (Nucleotide) + 1;
            end;
         end loop;
         New_Line;
         exit when Last = Sequence.Last_Index;
         First := Last + 1;
         Last  := Position_Type'Min (First + Width - 1,
                                     Sequence.Last_Index);
      end loop;

      for N in Count'Range loop
         Put ("Count of "); Put (N); Put (" is "); Put (Natural'Image (Count (N))); New_Line;
      end loop;

   end Pretty_Print;

   function Random_Position (First, Last : Position_Type) return Position_Type is
      subtype Position_Range is Position_Type range First .. Last;
      package Position_Generators is new Ada.Numerics.Discrete_Random (Result_Subtype => Position_Range);
      Generator : Position_Generators.Generator;
   begin
      Position_Generators.Reset (Generator);
      return Position_Generators.Random (Generator);
   end Random_Position;

   Nucleotide_Generator : Nucleotide_Generators.Generator;
   Operation_Generator  : Operation_Generators.Generator;

   Sequence   : Sequence_Vectors.Vector;
   Position   : Position_Type;
   Nucleotide : Nucleotide_Type;
   Operation  : Operation_Type;
begin
   Nucleotide_Generators.Reset (Nucleotide_Generator);
   Operation_Generators.Reset (Operation_Generator);

   for A in 1 .. 200 loop
      Sequence.Append (Nucleotide_Generators.Random (Nucleotide_Generator));
   end loop;

   Put_Line ("Initial sequence:");
   Pretty_Print (Sequence);
   New_Line;

   Put_Line ("Mutations:");
   for Mutate in 1 .. 10 loop

      Operation := Operation_Generators.Random (Operation_Generator);
      case Operation is

         when Delete =>
            Position := Random_Position (Sequence.First_Index, Sequence.Last_Index);
            Sequence.Delete (Index => Position);
            Put (Operation); Put (" at position "); Put (Position, Width => 0); New_Line;

         when Insert =>
            Position   := Random_Position (Sequence.First_Index, Sequence.Last_Index + 1);
            Nucleotide := Nucleotide_Generators.Random (Nucleotide_Generator);
            Sequence.Insert (Before   => Position,
                             New_Item => Nucleotide);
            Put (Operation); Put (" "); Put (Nucleotide); Put (" at position ");
            Put (Position, Width => 0); New_Line;

         when Swap =>
            Position   := Random_Position (Sequence.First_Index, Sequence.Last_Index);
            Nucleotide := Nucleotide_Generators.Random (Nucleotide_Generator);
            Sequence.Replace_Element (Index    => Position,
                                      New_Item => Nucleotide);
            Put (Operation); Put (" at position "); Put (Position, Width => 0);
            Put (" to "); Put (Nucleotide); New_Line;

      end case;
   end loop;

   New_Line;
   Put_Line ("Mutated sequence:");
   Pretty_Print (Sequence);

end Mutations;