Skip to content

Instantly share code, notes, and snippets.

@sbassi
Created April 22, 2014 19:15
Show Gist options
  • Save sbassi/11190962 to your computer and use it in GitHub Desktop.
Save sbassi/11190962 to your computer and use it in GitHub Desktop.
Población cubierta con fingerprinting voluntario
import uuid
import random
import pdb
class Person():
def __init__(self, padre=None, madre=None, generacion=0):
#self.reset()
self.dni = str(uuid.uuid4())
self.sex = random.choice(['F','M'])
self.pareja_con = None
self.sons = set()
self.padre = padre
self.madre = madre
self.generacion = generacion
self.fingerprinted = False
def hechar_cria(self, conyuge, cantidad=1):
# Check sex
nuevos_hijos = set()
nuevos_hijos_dni = set()
if self.sex == conyuge.sex:
return nuevos_hijos
# Distinto sexo pueden tener cria
else:
# Crear hijos
if self.sex == 'M':
padre = self.dni
madre = conyuge.dni
else:
padre = conyuge.dni
madre = self.dni
for x in range(0,cantidad):
np = Person(padre,madre,generacion=self.generacion+1)
nuevos_hijos.add(np)
nuevos_hijos_dni.add(np.dni)
# Agregarlo a self.hijos propio
self.sons = self.sons.union(nuevos_hijos_dni)
# Agregarlo a self.hijos de conyuge
conyuge.sons = conyuge.sons.union(nuevos_hijos_dni)
# Agregar ID de la pareja
self.pareja_con = conyuge.dni
# Agregar hijos al pool total?
return nuevos_hijos
def __str__(self):
return "Generacion: %s; DNI: %s; Sexo: %s"%(self.generacion,self.dni, self.sex)
class Population():
def __init__(self, cantidad):
self.population = set()
for x in range(cantidad):
self.population.add(Person())
#self.pop_ammount = len(self.population)
def index(self, dni):
for x in self.population:
if x.dni==dni:
return x
raise IndexError
def make_new_f(self, fertility_rate=.85, base_pop=100,nro_crias=2):
new_f = set()
#print self.pop_ammount
# Cuento el sexo de menor representatividad
f = 0
m = 0
for x in base_pop:
f += 1 if x.sex=='F' else 0
m = len(base_pop) - f
menor_rep = ('F', f) if m>f else ('M', m)
# Genero subconjunto de menor_rep
conj_menor_rep = set()
conj_mayor_rep = set()
for x in base_pop:
if x.sex==menor_rep[0]:
conj_menor_rep.add(x)
else:
conj_mayor_rep.add(x)
# Get number of couples with sons
print 'conj menor repr %s / total %s'%(len(conj_menor_rep),len(base_pop))
persons_with_sons = int(menor_rep[1]*fertility_rate)
print "parejas con hijos", persons_with_sons
for x in range(persons_with_sons):
p1 = conj_menor_rep.pop()
p2 = conj_mayor_rep.pop()
new_f = new_f.union(p1.hechar_cria(p2,nro_crias))
# Agrego la new_f a la poblacion gral
self.population = self.population.union(new_f)
return new_f
def _son_covered_rec(self,person):
if person.sons:
for p in person.sons:
self.covered.add(p)
self._son_covered_rec(self.index(p))
else:
return None
def _parents_covered_rec(self,person):
if person.padre and person.madre:
parents = person.padre, person.madre
for p in parents:
self.covered.add(p)
self._parents_covered_rec(self.index(p))
else:
return None
def _silbing_covered(self,person):
if person.padre:
for p in self.index(person.padre).sons:
self.covered.add(p)
def get_coverage(self, population):
all_pop_len = len(population)
self.covered = set()
for x in population:
if x.fingerprinted == True:
# The subject is always part covered population
self.covered.add(x.dni)
# Check for sons
#if x.sons:
self._son_covered_rec(x)
self._parents_covered_rec(x)
self._silbing_covered(x)
print 'len covered, ', len(self.covered)
coverage = (float(len(self.covered))/all_pop_len)*100
return coverage
def __str__(self):
return "Amount: %s"%len(self.population)
# self.article = self._remove_tags(self.ensamble_article(article))
p = Population(1000)
f1 = p.make_new_f(.8,p.population,3)
#print [str(x) for x in f1]
print 'cantidad de f1', len(f1)
ori_and_f1 = p.population.union(f1)
print 'cantidad total', len(ori_and_f1)
f2 = p.make_new_f(.8,f1,3)
print 'f2',len(f2)
all_together = p.population | f1 | f2
print len(all_together)
## TODO: someter un % de mujeres al genID
fingerprinted_f_rate = .3
fingerprinted_m_rate = .1
#### WARNING SACAR M
all_together_f = set()
for x in all_together:
if x.sex=='F':
all_together_f.add(x)
all_together_m = set()
for x in all_together:
if x.sex=='M':
all_together_m.add(x)
#all_together_f
sample_f_size = int(len(all_together_f)*fingerprinted_f_rate)
print 'sample_f_size', sample_f_size
fingerprinted_f_pop = random.sample(all_together_f, sample_f_size)
for x in fingerprinted_f_pop:
x.fingerprinted = True
sample_m_size = int(len(all_together_m)*fingerprinted_m_rate)
print 'sample_m_size', sample_m_size
fingerprinted_m_pop = random.sample(all_together_m, sample_m_size)
for x in fingerprinted_m_pop:
x.fingerprinted = True
print p.get_coverage(all_together)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment