def air_neighbours_available(self): '''Returns a list with neighbours with open airport''' a_n_a = LinkedList() for neib in self.air_neighbours: if self.open_airport and neib.open_airport: a_n_a.append(neib) return a_n_a
def neighbours_available(self): '''Returns list with neighbours with opened fronteir''' n_a = LinkedList() for neib in self.neighbours: if self.open_fronteir and neib.open_fronteir: n_a.append(neib) return n_a
def get_llst(lst1, lst2): llst1 = LinkedList() llst2 = LinkedList() for value in lst1: llst1.append(value) for value in lst2: llst2.append(value) return llst1, llst2
def union(llist_1, llist_2): llst = LinkedList() lst_1 = llist_1.to_list() lst_2 = llist_2.to_list() nodes = set(lst_1 + lst_2) for node in nodes: llst.append(node) return llst
def intersection(llist_1, llist_2): llst = LinkedList() lst_1 = llist_1.to_list() lst_2 = llist_2.to_list() nodes = set(lst_1).intersection(set(lst_2)) for node in nodes: llst.append(node) return llst
def linkedlist(self, e1, e2, e3): linkedlist = LinkedList(e1) linkedlist.append(e2) linkedlist.append(e3) return linkedlist
for node in nodes: llst.append(node) return llst if __name__ == '__main__': # Test case 1 linked_list_1 = LinkedList() linked_list_2 = LinkedList() element_1 = [3, 2, 4, 35, 6, 65, 6, 4, 3, 21] element_2 = [6, 32, 4, 9, 6, 1, 11, 21, 1] for i in element_1: linked_list_1.append(i) for i in element_2: linked_list_2.append(i) print(union(linked_list_1, linked_list_2)) print(intersection(linked_list_1, linked_list_2)) # Test case 2 linked_list_3 = LinkedList() linked_list_4 = LinkedList() element_1 = [3, 2, 4, 35, 6, 65, 6, 4, 3, 23] element_2 = [1, 7, 8, 9, 11, 21, 1] for i in element_1: linked_list_3.append(i)
class Country: def __init__(self, name, initial_population): self.name = name self.initial_population = initial_population self.healthy_total = initial_population self.dead_total = 0 self.infected_total = 0 self.actions_queue = LinkedList() self.neighbours = LinkedList() self.neighbours_names = LinkedList() self.air_neighbours = LinkedList() self.air_neighbours_names = LinkedList() self.open_airport = True self.open_fronteir = True self.has_cure = False self.has_mask = False self.infected_this_day = 0 self.dead_this_day = 0 @property def alive_total(self): '''Returns the total amount of living people''' return self.healthy_total + self.infected_total @property def status(self): '''Returns the state of a country as a string''' s = None if self.infected_total == 0: s = "Limpio" elif self.infected_total > 0: s = "Infectado" if self.dead_total == self.initial_population: s = "Muerto" return s @property def neighbours_available(self): '''Returns list with neighbours with opened fronteir''' n_a = LinkedList() for neib in self.neighbours: if self.open_fronteir and neib.open_fronteir: n_a.append(neib) return n_a @property def air_neighbours_available(self): '''Returns a list with neighbours with open airport''' a_n_a = LinkedList() for neib in self.air_neighbours: if self.open_airport and neib.open_airport: a_n_a.append(neib) return a_n_a @property def prob_spread_land(self): '''Returns the probability of spreading the infection by land''' try: num_conections = len(self.neighbours_available) p = min( 0.07 * self.infected_total / (self.alive_total * num_conections), 1) except ZeroDivisionError: return False else: return p @property def prob_spread_air(self): '''Returns the probabily of infection by air''' try: num_conections = len(self.air_neighbours_available) p = min( 0.07 * self.infected_total / (self.alive_total * num_conections), 1) except ZeroDivisionError: return False else: return p def add_neighbour(self, other): '''Checks if the two countries are already connected and adds them to each other lists''' if other.name not in self.neighbours_names: self.neighbours.append(other) self.neighbours_names.append(other.name) if self.name not in other.neighbours_names: other.neighbours.append(self) other.neighbours_names.append(self.name) def add_air_neighbour(self, other): '''Checks if the two countries are already connected and adds them to each other lists. This one is by air.''' if other.name not in self.air_neighbours_names: self.air_neighbours.append(other) self.air_neighbours_names.append(other.name) if self.name not in other.air_neighbours_names: other.air_neighbours.append(self) other.air_neighbours_names.append(self.name) def simulate_one_day(self, infection, prob_die): '''It simulates the actions of one day. First they can cure themselves, then they infect other people and finally they can die. This order makes sense to me''' if self.status == "Infectado": if self.has_cure: p = 0.25 * infection.resistencia_medicina if self.infected_total >= 1000: sample = int(str(self.infected_total)[0:3]) x = sum(bernoulli(p) for i in range(sample)) / sample new_cured = round(x * self.infected_total) for i in range(new_cured): self.cure_one() else: for i in range(self.infected_total): x = bernoulli(p) if x == 1: self.cure_one() if self.infected_total >= 1000: sample = int(str(self.infected_total)[0:3]) u_prom = sum(uniform() for i in range(sample)) / sample n = round(u_prom * infection.tasa_contagiosidad) if self.has_mask: n *= 0.3 new_infected = round(n * self.infected_total) self.infect_one(new_infected) self.infected_this_day = min(new_infected, self.healthy_total) else: self.infected_this_day = 0 for i in range(self.infected_total): u = uniform() n = u * infection.tasa_contagiosidad if self.has_mask: n *= 0.3 self.infect_one(int(n)) self.infected_this_day += min(int(n), self.healthy_total) if self.infected_total >= 1000: sample = int(str(self.infected_total)[0:3]) x = sum(bernoulli(prob_die) for i in range(sample)) / sample new_dead = round(x * self.infected_total) self.kill_one(new_dead) self.dead_this_day = min(new_dead, self.infected_total) else: self.dead_this_day = 0 for i in range(self.infected_total): x = bernoulli(prob_die) if x == 1: self.kill_one() self.dead_this_day += min(1, self.infected_total) def simulate_spread_land(self): '''Simulates the event of infecting other country by land''' if self.infected_total >= 0.2 * self.initial_population: for country in self.neighbours_available: if country.status == 'Limpio': p = self.prob_spread_land x = bernoulli(p) if x == 1: country.infect_one() def simulate_spread_air(self): '''Simulates the event of infecting other country by air. This does not includes the 4 percent condition''' for country in self.air_neighbours_available: if country.status == 'Limpio': p = self.prob_spread_air x = bernoulli(p) if x == 1: country.infect_one() def simulate_share_cure(self): '''It gives the cure to the countries with open airport''' if self.has_cure: for country in self.air_neighbours_available: if not country.has_cure: country.has_cure = True def add_proposal(self, proposal_object, world_actions_queue): found_another = False replace = False for action in self.actions_queue: if action.message == proposal_object.message: found_another = True if proposal_object.priority > action.priority: replace = True self.actions_queue.remove(action) if not found_another: self.actions_queue.append(proposal_object) if replace: self.actions_queue.append(proposal_object) world_actions_queue.append(proposal_object) def simulate_propose(self, cure_discovered, world_actions_queue): '''It simulates the gobernment decitions on a day''' ratio = self.infected_total / self.initial_population if (self.infected_total > self.initial_population / 2 or self.dead_total >= self.initial_population / 4) and\ self.open_fronteir and not cure_discovered: action = 0 for country in self.neighbours: action += country.infected_total / country.initial_population if len(self.neighbours) != 0 and action != 0: action /= len(self.neighbours) priority = action * ratio proposal_msg = 'close fronteirs' proposal_object = Proposal(priority, proposal_msg, self) self.add_proposal(proposal_object, world_actions_queue) # world_actions_queue.append(proposal_object) if (self.infected_total > 0.8 * self.initial_population or self.dead_total > 0.2 * self.initial_population) and\ self.open_airport and not cure_discovered: action = 0.8 priority = action * ratio proposal_msg = 'close airports' proposal_object = Proposal(priority, proposal_msg, self) self.add_proposal(proposal_object, world_actions_queue) # world_actions_queue.append(proposal_object) if self.infected_total > self.initial_population / 3 and not self.has_mask: action = 0.5 priority = action * ratio proposal_msg = 'give masks' proposal_object = Proposal(priority, proposal_msg, self) self.add_proposal(proposal_object, world_actions_queue) # world_actions_queue.append(proposal_object) if ((self.infected_total <= self.initial_population / 2 and self.dead_total < self.initial_population / 4) and not self.open_fronteir) or (cure_discovered and not self.open_fronteir): action = 1 if cure_discovered else 0.7 priority = action * ratio proposal_msg = 'open fronteirs' proposal_object = Proposal(priority, proposal_msg, self) self.add_proposal(proposal_object, world_actions_queue) # world_actions_queue.append(proposal_object) if ((self.infected_total <= 0.8 * self.initial_population and self.dead_total <= 0.2 * self.initial_population) and not self.open_airport) or (cure_discovered and not self.open_airport): action = 1 if cure_discovered else 0.7 priority = action * ratio proposal_msg = 'open airports' proposal_object = Proposal(priority, proposal_msg, self) self.add_proposal(proposal_object, world_actions_queue) # world_actions_queue.append(proposal_object) def infect_one(self, num=1): if self.healthy_total >= num: self.infected_total += num self.healthy_total -= num else: new_infected = self.healthy_total self.infected_total += new_infected self.healthy_total -= new_infected def kill_one(self, num=1): if self.infected_total >= num: self.dead_total += num self.infected_total -= num else: new_dead = self.infected_total self.dead_total += new_dead self.infected_total -= new_dead def cure_one(self, num=1): if self.infected_total >= num: self.healthy_total += num self.infected_total -= num else: new_cured = self.infected_total self.healthy_total += new_cured self.infected_total -= new_cured
class World: def __init__(self, file_population, file_borders, file_airports, file_ramdom_airports): self.file_population = file_population self.file_borders = file_borders self.file_airports = file_airports self.file_ramdom_airports = file_ramdom_airports self.countries = LinkedList() self.names = LinkedList() self.cure_progress = 0.0 self.cure_delivered = False self.infection_detected = False self.infection_detection_day = 0 self.actions_queue = LinkedQueue() self.infection = None self.day = 0 self.closed_airports_today = "" self.closed_fronteirs_today = "" self.gave_masks_today = "" # sum of the new infected every day # It does not include the healing process self.infected_to_this_day = 0 self.infected_per_day_list = LinkedList(1) self.dead_per_day_list = LinkedList(0) @property def infected_total(self): inf = 0 for country in self.countries: inf += country.infected_total return inf @property def healthy_total(self): h = 0 for country in self.countries: h += country.healthy_total return h @property def dead_total(self): dead = 0 for country in self.countries: dead += country.dead_total return dead @property def alive_total(self): alive = 0 for country in self.countries: alive += country.alive_total return alive @property def initial_population(self): initial = 0 for country in self.countries: initial += country.initial_population return initial @property def prob_detect_infection(self): p = (self.infection.visibilidad * self.infected_total * self.dead_total**2) / self.initial_population**3 return p @property def prob_die(self): a = max(0.2, self.day**2 / 100000) p = min(a * self.infection.tasa_mortalidad, 1) return p @property def condition_spread_air(self): return self.infected_total >= 0.04 * self.initial_population def simulate_infection_detection(self): '''Simulates the bernoulli event of detecting the infection''' x = bernoulli(self.prob_detect_infection) if x == 1: self.infection_detected = True self.infection_detection_day = self.day def simulate_cure_progress(self): '''Simulates the cure progress in one day If the cure is completely researched, then it is delivered''' if self.infection_detected and not self.cure_delivered: self.cure_progress += self.healthy_total / ( 2 * self.initial_population * 100) if self.cure_progress >= 1 and not self.cure_delivered: random_country = choice(self.countries) random_country.has_cure = True self.cure_delivered = True def add_country(self, country): '''It checks if the country is already in the list. If not, then appends it''' if self.countries.find_name(country.name) is None: self.countries.append(country) self.names.append(country.name) def load_countries_csv(self): '''Reads and loads the borders.csv file''' with open(self.file_population) as csvfile: readCSV = csv.reader(csvfile, delimiter=",") header = next(readCSV) for row in readCSV: name = str(row[0]) population = int(row[1]) country = Country(name, population) self.add_country(country) def load_neighbours(self): with open(self.file_borders) as csvfile: readCSV = csv.reader(csvfile, delimiter=";") header = next(readCSV) for row in readCSV: country_name_1 = row[0] country_name_2 = row[1] country_1 = self.countries.find_name(country_name_1) country_2 = self.countries.find_name(country_name_2) country_1.add_neighbour(country_2) def load_air_neighbours(self): with open(self.file_ramdom_airports) as csvfile: readCSV = csv.reader(csvfile, delimiter=",") header = next(readCSV) for row in readCSV: country_name_1 = row[0] country_name_2 = row[1] country_1 = self.countries.find_name(country_name_1) country_2 = self.countries.find_name(country_name_2) country_1.add_air_neighbour(country_2) def simulate_goverment_decitions(self): '''It simulates the three actions per day. It clears the list every day.''' self.closed_fronteirs_today = "" self.closed_airports_today = "" self.gave_masks_today = "" if self.infection_detected: # sorted_forbidden = sorted(self.actions_queue, reverse=True) # sorted_nice = LinkedList(*sorted_forbidden) sorted_nice = self.actions_queue.sorted() for i in range(min(3, len(self.actions_queue))): to_do = sorted_nice.pop_left() if to_do.message == 'close fronteirs' and to_do.origin.open_fronteir: to_do.origin.open_fronteir = False print("{} hizo: {}".format(to_do.origin.name, to_do.message)) for action in to_do.origin.actions_queue: if action.message == to_do.message: to_do.origin.actions_queue.remove(action) self.closed_fronteirs_today += str( to_do.origin.name) + "\n\t\t" elif to_do.message == 'open fronteirs' and not to_do.origin.open_fronteir: to_do.origin.open_fronteir = True for action in to_do.origin.actions_queue: if action.message == to_do.message: to_do.origin.actions_queue.remove(action) print("{} hizo: {}".format(to_do.origin.name, to_do.message)) elif to_do.message == 'close airports' and to_do.origin.open_airport: to_do.origin.open_airport = False for action in to_do.origin.actions_queue: if action.message == to_do.message: to_do.origin.actions_queue.remove(action) print("{} hizo: {}".format(to_do.origin.name, to_do.message)) self.closed_airports_today += str( to_do.origin.name) + "\n\t\t" elif to_do.message == 'open airports' and not to_do.origin.open_airport: to_do.origin.open_airport = True for action in to_do.origin.actions_queue: if action.message == to_do.message: to_do.origin.actions_queue.remove(action) print("{} hizo: {}".format(to_do.origin.name, to_do.message)) elif to_do.message == 'give masks' and not to_do.origin.has_mask: to_do.origin.has_mask = True for action in to_do.origin.actions_queue: if action.message == to_do.message: to_do.origin.actions_queue.remove(action) print("{} hizo: {}".format(to_do.origin.name, to_do.message)) self.gave_masks_today += str(to_do.origin.name) + "\n\t\t" self.closed_airports_today = self.closed_airports_today.strip() self.closed_fronteirs_today = self.closed_fronteirs_today.strip() self.gave_masks_today = self.gave_masks_today.strip() self.actions_queue.clear() def simulate_one_day(self): condition_spread_air = self.condition_spread_air world_infected_this_day = 0 world_dead_this_day = 0 self.day += 1 self.simulate_cure_progress() for country in self.countries: country.simulate_one_day(self.infection, self.prob_die) country.simulate_spread_land() if condition_spread_air: country.simulate_spread_air() country.simulate_share_cure() country.simulate_propose(self.cure_progress >= 1, self.actions_queue) world_infected_this_day += country.infected_this_day world_dead_this_day += country.dead_this_day self.simulate_infection_detection() self.simulate_goverment_decitions() self.infected_to_this_day += world_infected_this_day self.dead_per_day_list.append(world_dead_this_day) self.infected_per_day_list.append(world_infected_this_day) def show_global_status(self): s_infected = "INFECTADOS: \n" s_clean = "LIMPIOS: \n" s_dead = "MUERTOS: \n" for country in self.countries: if country.status == 'Limpio': s_clean += "\t" + str(country.name) + "\n" elif country.status == 'Infectado': s_infected += "\t" + str(country.name) + "\n" elif country.status == 'Muerto': s_dead += "\t" + str(country.name) + "\n" print(s_clean) print(s_infected) print(s_dead) print("Poblacion total:") print("\t Viva: {}".format(self.alive_total)) print("\t Muerta: {}".format(self.dead_total)) print("\t Infectada: {}".format(self.infected_total)) print("\t Sana: {}".format(self.healthy_total)) def show_day_summary(self): world_infected_this_day = 0 world_dead_this_day = 0 for country in self.countries: world_infected_this_day += country.infected_this_day world_dead_this_day += country.dead_this_day print("Sucesos del DIA: ") print("\t Gente INFECTADA: {}".format(world_infected_this_day)) print("\t Gente MUERTA: {}".format(world_dead_this_day)) print("\t Aeorpuertos cerrados: \n\t\t" + str(self.closed_airports_today)) print("\t Fronteras cerradas: \n\t\t" + str(self.closed_fronteirs_today)) print("\t Mascarillas entregadas: \n\t\t" + str(self.gave_masks_today)) def show_country_status(self): loop = True while loop: country_input = input("Nombre del pais: ").strip().title() country = self.countries.find_name(country_input) if country is None: print("Pais invalido. Intenta nuevamente.") else: loop = False print(country.name) print("\t Personas VIVAS: {}".format(country.alive_total)) print("\t Personas INFECTADAS: {}".format(country.infected_total)) print("\t Personas MUERTAS: {}".format(country.dead_total)) print("\t Aciones propuestas no realizadas: {}".format( country.actions_queue)) def show_averages(self): death_average = self.dead_total / self.day if self.day != 0 else 0 infected_average = self.infected_to_this_day / self.day if self.day != 0 else 1 print("Promedio de muertes diarias \t: {}".format(death_average)) print("Promedio de infectados diarios \t: {}".format(infected_average)) def show_dead_infected_per_day(self): # print("DIA \t | MUERTOS \t\t | INFECTADOS") # for i in range(self.day + 1): # dead = self.dead_per_day_list[i] # infected = self.infected_per_day_list[i] # print(str(i) + "\t\t |" + str(dead) + "\t\t\t\t |" + str(infected)) # print("-" * 25) infected_list = [num for num in self.infected_per_day_list] infected = np.array(infected_list) time = np.arange(0, self.day + 1) plt.plot(time, infected) plt.title('Infected per day') plt.ylabel('Infected') plt.xlabel('Day') plt.show()