This file is indexed.

/usr/share/pyshared/Bio/GA/Organism.py is in python-biopython 1.58-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
"""Deal with an Organism in a Genetic Algorithm population.
"""
# standard modules
import sys #for Python 3 hack
import random
import array

# Sequence objects from Biopython
from Bio.Seq import MutableSeq

def function_population(new_genome, num_organisms, fitness_calculator):
    """Generate a population given a function to create genomes

    Arguments:

    o new_genome - A function or callable object that will return
    a genome that can be used for a new organism. This new genome
    should be a MutableSeq object with a specified alphabet.

    o num_organisms - The number of individuals we want in the population.

    o fitness_calculator -- A funtion that will calculate the fitness
    of the organism when given the organisms genome.
    """
    all_orgs = []

    for org_num in range(num_organisms):
        cur_genome = new_genome()
        all_orgs.append(Organism(cur_genome, fitness_calculator))

    return all_orgs

def random_population(genome_alphabet, genome_size, num_organisms,
                      fitness_calculator):
    """Generate a population of individuals with randomly set genomes.

    Arguments:

    o genome_alphabet -- An Alphabet object describing all of the
    possible letters that could potentially be in the genome of an
    organism.

    o genome_size -- The size of each organisms genome.

    o num_organism -- The number of organisms we want in the population.

    o fitness_calculator -- A funtion that will calculate the fitness
    of the organism when given the organisms genome.
    """
    all_orgs = []

    # a random number generator to get letters for the genome
    letter_rand = random.Random()

    # figure out what type of characters are in the alphabet
    if type(genome_alphabet.letters[0]) == type("A"):
        if sys.version_info[0] == 3:
            alphabet_type = "u" #Use unicode string on Python 3
        else:
            alphabet_type = "c" #Use byte string on Python 2
    elif type(genome_alphabet.letters[0]) == type(1):
        alphabet_type = "i"
    elif type(genome_alphabet.letters[0]) == type(1.0):
        alphabet_type = "d"
    else:
        raise ValueError(\
            "Alphabet type is unsupported: %s" % genome_alphabet.letters)

    for org_num in range(num_organisms):
        new_genome = MutableSeq(array.array(alphabet_type), genome_alphabet)

        # generate the genome randomly
        for gene_num in range(genome_size):
            new_gene = letter_rand.choice(genome_alphabet.letters)
            new_genome.append(new_gene)

        # add the new organism with this genome
        all_orgs.append(Organism(new_genome, fitness_calculator))

    return all_orgs

class Organism(object):
    """Represent a single individual in a population.

    Attributes:

    o genome -- The genome of the organism. This is a Bio.MutableSeq
    object that has the sequence of the genome, and the alphabet
    describing all elements that can be a part of the genome.

    o fitness -- The calculate fitness of the organism. This fitness is
    based on the last time it was calculated using the fitness_calculator.
    So... the fitness could potentially be out of date with the real genome
    if you are not careful to recalculate it after changes with
    recalculate_fitness()
    """
    def __init__(self, genome, fitness_calculator, start_fitness = None):
        """Initialize an organism

        Arguments:

        o genome -- A MutableSeq object representing the sequence of the
        genome.

        o fitness_calculator -- A funtion that will calculate the fitness
        of the organism when given the organisms genome.

        o start_fitness - the starting fitness corresponding with the
        given genome. If not supplied, the fitness will be calculated
        using fitness_calculator.
        """
        assert isinstance(genome, MutableSeq), "Genome must be a MutableSeq"
        
        self.genome = genome
        self._fitness_calc = fitness_calculator

        # calculate the fitness of the genome
        if start_fitness is None:
            self.fitness = self._fitness_calc(self.genome)
        else:
            self.fitness = start_fitness

    def __str__(self):
        """Provide a string output for debugging.
        """
        return "Genome: %s; Fitness %s" % (self.genome.tostring(), self.fitness)

    def __eq__(self, other):
        """Compare organisms by their genomes (as strings of letters).
        """
        # See Bio/Seq.py and the comments there about shifting to
        # using simple string equality. Previously Seq objects used
        # object equality, while MutableSeq objects used alphabet
        # aware string equality.
        return str(self.genome) == str(other.genome)

    def __ne__(self, other):
        """Compare organisms by their genomes (as strings of letters).
        """
        return str(self.genome) != str(other.genome)

    def __lt__(self, other):
        """Compare organisms by their genomes (as strings of letters).
        """
        return str(self.genome) < str(other.genome)

    def __le__(self, other):
        """Compare organisms by their genomes (as strings of letters).
        """
        return str(self.genome) <= str(other.genome)

    def __gt__(self, other):
        """Compare organisms by their genomes (as strings of letters).
        """
        return str(self.genome) > str(other.genome)

    def __ge__(self, other):
        """Compare organisms by their genomes (as strings of letters).
        """
        return str(self.genome) >= str(other.genome)

    def copy(self):
        """Return a copy of the organism.

        This makes it easy to duplicate an organism before changing it.
        """
        copy_genome = self.genome[:]
        return Organism(copy_genome, self._fitness_calc, self.fitness)

    def recalculate_fitness(self):
        """Calculate and reset the fitness of the current genome

        This should be called after the genome is updated to ensure that
        fitness always stays in sync with the current genome.
        """
        self.fitness = self._fitness_calc(self.genome)