pandemaths.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-"
  3. """
  4. PandeMaths - 2020 - by psy (epsylon@riseup.net)
  5. You should have received a copy of the GNU General Public License along
  6. with PandeMaths; if not, write to the Free Software Foundation, Inc., 51
  7. Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  8. """
  9. VERSION = "v0.2_beta"
  10. RELEASE = "27032020"
  11. SOURCE1 = "https://code.03c8.net/epsylon/pandemaths"
  12. SOURCE2 = "https://github.com/epsylon/pandemaths"
  13. CONTACT = "epsylon@riseup.net - (https://03c8.net)"
  14. pandemic_model_variables_path = "model/pandemia.txt" # pandemia variables file
  15. extended_model_variables_path = "model/extended.txt" # extended model variables file
  16. simulation_templates_path = "templates/" # templates files
  17. reports_path = "reports/" # reports files
  18. import json, datetime, os, random, sys
  19. def model_maths():
  20. print("[Info] Reviewing Model ...\n")
  21. try:
  22. print(" "+"-"*5+"\n")
  23. f = open(pandemic_model_variables_path, "r")
  24. model_variables = f.readlines()
  25. f.close()
  26. for v in model_variables:
  27. print(" - "+str(v.replace("\n", "")))
  28. except:
  29. pass
  30. try:
  31. print("\n "+"-"*5+"\n")
  32. f = open(extended_model_variables_path, "r")
  33. extended_variables = f.readlines()
  34. f.close()
  35. for v in extended_variables:
  36. print(" - "+str(v.replace("\n", "")))
  37. except:
  38. pass
  39. print("\n "+"-"*5+"\n")
  40. def simulation():
  41. print("[Info] Defining ecosystem ...\n")
  42. total_population = input(" + Total population (default: 100000): ")
  43. try:
  44. total_population = int(total_population)
  45. except:
  46. total_population = 100000
  47. if not total_population:
  48. total_population = 100000
  49. starting_population = total_population
  50. infected_starting = input(" + Infected (at the beginning) population (default: 1): ")
  51. try:
  52. infected_starting = int(infected_starting)
  53. except:
  54. infected_starting = 1
  55. if not infected_starting or infected_starting < 1:
  56. infected_starting = 1
  57. infected = infected_starting
  58. print("\n "+"-"*5+"\n")
  59. print("[Info] Establishing time units ...\n")
  60. days = input(" + Number of days (default: 200): ")
  61. try:
  62. days = int(days)
  63. except:
  64. days = 200
  65. if not days:
  66. days = 200
  67. daily_rate_interaction = input(" + Daily rate of interaction between individuals (default: 2.50): ")
  68. try:
  69. daily_rate_interaction = int(daily_rate_interaction)
  70. except:
  71. daily_rate_interaction = 2.50
  72. if not daily_rate_interaction:
  73. daily_rate_interaction = 2.50
  74. print("\n "+"-"*5+"\n")
  75. template = input("+ CHOOSE: (O)pen Simulation or (L)oad template: ").upper()
  76. if template == "O": # New Simulation
  77. average_rate_duration = None
  78. probability_of_contagion = None
  79. recovery_rate = None
  80. simulation_name = "OPEN"
  81. new_simulation(total_population, infected_starting, days, daily_rate_interaction, average_rate_duration, probability_of_contagion, recovery_rate, simulation_name, starting_population)
  82. else: # Load template
  83. load_template(total_population, infected_starting, days, daily_rate_interaction, starting_population)
  84. def load_template(total_population, infected_starting, days, daily_rate_interaction, starting_population):
  85. print("\n "+"-"*5+"\n")
  86. print("[Info] Generating templates ...\n")
  87. import glob
  88. templates = {}
  89. i = 0
  90. for file in glob.iglob(simulation_templates_path + '*', recursive=False):
  91. if(file.endswith(".txt")):
  92. i = i +1
  93. f=open(file, 'r')
  94. template = f.read().replace('\n',' ')
  95. templates[i] = file.replace("templates/",""), template.upper() # add template to main dict
  96. f.close()
  97. for k,v in templates.items():
  98. print (" ["+str(k)+"] - "+str(v[0].replace(".txt","")))
  99. print("\n "+"-"*5+"\n")
  100. template_set = input("+ CHOOSE: Number of template (ex: 1): ").upper()
  101. try:
  102. template_set = int(template_set)
  103. except:
  104. template_set = 1
  105. if not template_set or template_set > len(templates) or template_set < 1:
  106. template_set = 1
  107. for k,v in templates.items():
  108. if template_set == k:
  109. simulation_name = v[0].replace(".txt","")
  110. average_rate_duration = int(v[1].split("DURATION:")[1].split(" ")[0])
  111. probability_of_contagion = int(v[1].split("CONTAGION:")[1].split(" ")[0])
  112. recovery_rate = int(v[1].split("RECOV:")[1].split(" ")[0])
  113. new_simulation(total_population, infected_starting, days, daily_rate_interaction, average_rate_duration, probability_of_contagion, recovery_rate, simulation_name, starting_population)
  114. def new_simulation(total_population, infected_starting, days, daily_rate_interaction, average_rate_duration, probability_of_contagion, recovery_rate, simulation_name, starting_population):
  115. print("\n "+"-"*5+"\n")
  116. print("[Info] Generating variables ...\n")
  117. if average_rate_duration == None:
  118. average_rate_duration = input(" + Average duration of illness (default: 12) (days): ")
  119. try:
  120. if average_rate_duration == 0:
  121. pass
  122. else:
  123. average_rate_duration = int(average_rate_duration)
  124. except:
  125. average_rate_duration = 12
  126. if average_rate_duration < 0 or average_rate_duration > 100:
  127. average_rate_duration = 12
  128. else:
  129. print(" + Average duration of illness: "+str(average_rate_duration)+" days")
  130. if probability_of_contagion == None:
  131. probability_of_contagion = input(" + Infection rate (default: 14%): ")
  132. try:
  133. if probability_of_contagion == 0:
  134. pass
  135. else:
  136. probability_of_contagion = int(probability_of_contagion)
  137. except:
  138. probability_of_contagion = 14
  139. if probability_of_contagion < 0 or probability_of_contagion > 100:
  140. probability_of_contagion = 14
  141. else:
  142. print(" + Infection rate: "+str(probability_of_contagion)+"%")
  143. if recovery_rate == None:
  144. recovery_rate = input(" + Recovery rate (default: 95%): ")
  145. try:
  146. if recovery_rate == 0:
  147. pass
  148. else:
  149. recovery_rate = int(recovery_rate)
  150. except:
  151. recovery_rate = 95
  152. if recovery_rate < 0 or recovery_rate > 100:
  153. recovery_rate = 95
  154. else:
  155. print(" + Recovery rate: "+str(recovery_rate)+"%")
  156. mortality = 100 - recovery_rate
  157. print("\n "+"-"*5+"\n")
  158. print("[Info] Building parameters ...\n")
  159. print(" + Mortality rate: "+str(mortality)+"%")
  160. mortality = mortality / 100
  161. recovery_rate = recovery_rate / 100
  162. probability_of_contagion = probability_of_contagion / 100
  163. infected = infected_starting
  164. susceptible_starting = int(total_population) - int(infected)
  165. susceptible = susceptible_starting # susceptitble at start
  166. print(" + Susceptible: "+str(susceptible))
  167. recovered = 0 # recovered individuals at start
  168. deceased = 0 # deceases individuals at start
  169. print(" + Recovered: "+str(recovered))
  170. print(" + Deceased: "+str(deceased))
  171. print("\n"+"-"*15+"\n")
  172. print("[Info] Launching Simulation: [ "+str(simulation_name)+" ] ...\n")
  173. total_contagion = 0
  174. recoveries = 0
  175. current_time = datetime.datetime.now() # current datetime
  176. if not os.path.exists(reports_path): # create folder for reports
  177. os.makedirs(reports_path)
  178. data = {
  179. 'METADATA': [
  180. {
  181. 'Simulation Name': str(simulation_name),
  182. 'Datetime': str(current_time)
  183. }
  184. ],
  185. 'ECOSYSTEM': [
  186. {
  187. 'Total Population': str(total_population),
  188. 'Infected (at the beginning)': str(infected_starting),
  189. 'Number of days': str(days),
  190. 'Daily rate of interaction between individuals': str(daily_rate_interaction),
  191. 'Average duration of illness': str(average_rate_duration),
  192. 'Infection rate': str(probability_of_contagion),
  193. 'Recovery rate': str(recovery_rate),
  194. 'Mortality': str(mortality),
  195. 'Susceptible': str(susceptible),
  196. 'Recovered': str(recovered),
  197. 'Deceased': str(deceased)
  198. }
  199. ],
  200. 'SIMULATION': [
  201. {}
  202. ]
  203. }
  204. entire_population_infected = 0
  205. day_started = False
  206. for i in range(0, days):
  207. if i > 0:
  208. try:
  209. status_rate = round(int(infected*100/total_population))
  210. except:
  211. status_rate = 100
  212. if status_rate < 11: # ENDEMIA (-11%)
  213. if susceptible > 0:
  214. status = "IMPACT LEVEL: ENDEMIC!"
  215. else:
  216. if int(total_population*100/starting_population) > 49:
  217. status = "PRACTICALLY ERRADICATED BUT AT LEAST HALF OF THE POPULATION HAS DIED!"
  218. else:
  219. status = "PRACTICALLY ERRADICATED!"
  220. elif status_rate > 10 and status_rate < 25: # EPIDEMIA (>10%<25%)
  221. if susceptible > 0:
  222. status = "IMPACT LEVEL: EPIDEMIC!"
  223. else:
  224. status = "IMPORTANT FOCUS OF INCUBATION!"
  225. else: # PANDEMIA (>25%)
  226. if susceptible > 0:
  227. status = "IMPACT LEVEL: PANDEMIC!"
  228. else:
  229. status = "MOSTLY OF THE POPULATION IS INCUBATING!"
  230. sir = susceptible+infected+recovered # S-I-R model
  231. try:
  232. contagion = round(infected*daily_rate_interaction*susceptible/sir*probability_of_contagion) # contagion rounded rate
  233. except:
  234. contagion = 100
  235. recoveries = round(infected*recovery_rate/average_rate_duration) # recoveries rounded rate
  236. deaths = round(infected*mortality/average_rate_duration) # deaths rounded rate
  237. susceptible = susceptible - contagion + recoveries - deaths
  238. infected = infected+contagion-recoveries-deaths
  239. recovered =recovered + recoveries
  240. deceased = deceased + deaths
  241. total_contagion = total_contagion + contagion
  242. total_recovered = recovered
  243. total_deceased = total_deceased + deaths
  244. total_population = starting_population - deceased
  245. total_non_affected = susceptible_starting+infected_starting+0+0-total_contagion
  246. day_started = True
  247. else: # related to the first day
  248. status = "STARTED!"
  249. contagion = 0
  250. recoveries = 0
  251. deaths = 0
  252. total_recovered = 0
  253. total_deceased = 0
  254. deceased = 0
  255. susceptible = total_population - infected
  256. recovered = 0
  257. total_contagion = infected_starting
  258. total_non_affected = susceptible
  259. if total_population < 0:
  260. total_population = 0
  261. if total_contagion < total_contagion < 0:
  262. total_contagion = 0
  263. if contagion > susceptible: # more individuals than susceptible cannot be infected
  264. contagion = susceptible
  265. if contagion < 1:
  266. contagion = 0
  267. if total_non_affected < 1: # cannot be negative non affected individuals
  268. total_non_affected = 0
  269. if recoveries < 1:
  270. recoveries = 0
  271. if susceptible + infected + recovered + deceased > starting_population:
  272. susceptible = int(starting_population - infected - recovered - deceased)
  273. deaths = int(recovered + deceased - starting_population)
  274. if deaths < 1:
  275. deaths = 0
  276. if deaths > total_population:
  277. deaths = total_population
  278. if deaths > infected:
  279. deaths = infected
  280. infected = 0
  281. if susceptible < 1: # cannot be negative susceptible individuals
  282. susceptible = 0
  283. if susceptible == 0:
  284. total_non_affected = 0
  285. if day_started == True:
  286. if int(contagion + recoveries + deaths) == 0: # infected final resolution phase solved by random results
  287. if infected > 0:
  288. deaths = random.randrange(infected)
  289. if deaths > infected:
  290. infected = deaths
  291. if infected == 1: # random final against Existentialism!
  292. res = random.randrange(2)
  293. if res == 1: # survive!
  294. recoveries = recoveries + 1
  295. else: # die!
  296. deaths = deaths + 1
  297. infected = infected+contagion-recoveries-deaths
  298. recovered = recovered + recoveries
  299. total_recovered = total_recovered + recoveries
  300. deceased = deceased+deaths
  301. if infected > starting_population:
  302. infected = starting_population
  303. if total_population > 0:
  304. if infected > 0:
  305. data['SIMULATION'][0]['DAY'] = str(i)
  306. if total_non_affected > 0:
  307. print(" -> [DAY: "+str(i)+"]\n Status: "+str(status)+"\n Contagion: ("+str(int(contagion))+")["+str(round(contagion/total_population*100))+"%] - Recoveries: ("+str(int(recoveries))+")["+str(round(recoveries/total_population*100))+"%] - Deaths: ("+str(int(deaths))+")["+str(round(deaths/total_population*100))+"%] | Susceptible: ("+str(int(susceptible))+")["+str(round(susceptible/total_population*100))+"%] - Infected: ("+str(int(infected))+")["+str(round(infected/total_population*100))+"%] - Recovered: ("+str(int(recovered))+")["+str(round(recovered/total_population*100))+"%]")
  308. print(" Total Population: ("+str(int(total_population))+"/"+str(int(starting_population))+") - Total Contagion: ("+str(int(total_contagion))+")["+str(round(total_contagion/starting_population*100))+"%] - Total Recovered: (" +str(int(total_recovered))+")["+str(round(total_recovered/starting_population*100))+"%] - Total Deceased: ("+str(int(total_deceased))+")["+str(round(total_deceased/starting_population*100))+"%] - Total N/A: ("+str(int(total_non_affected))+")["+str(round(total_non_affected/starting_population*100))+"%]\n")
  309. else:
  310. if entire_population_infected == 0:
  311. total_contagion = starting_population
  312. susceptible = 0
  313. status = "ALL INFECTED !!!"
  314. print("-"*75+"\n")
  315. print(" -> [DAY: "+str(i)+"] -> [ THE ENTIRE POPULATION HAS BEEN INFECTED! ]\n Status: "+str(status)+"\n Contagion: ("+str(int(contagion))+")[100%] - Recoveries: ("+str(int(recoveries))+")["+str(round(recoveries/total_population*100))+"%] - Deaths: ("+str(int(deaths))+")["+str(round(deaths/total_population*100))+"%] | Susceptible: ("+str(int(susceptible))+")[0%] - Infected: ("+str(int(infected))+")[100%] - Recovered: ("+str(int(recovered))+")["+str(round(recovered/total_population*100))+"%]")
  316. entire_population_infected = entire_population_infected + 1
  317. print(" Total Population: ("+str(int(total_population))+"/"+str(int(starting_population))+") - Total Contagion: ("+str(int(total_contagion))+")["+str(round(total_contagion/starting_population*100))+"%] - Total Recovered: (" +str(int(total_recovered))+")["+str(round(total_recovered/starting_population*100))+"%] - Total Deceased: ("+str(int(total_deceased))+")["+str(round(total_deceased/starting_population*100))+"%] - Total N/A: ("+str(int(total_non_affected))+")["+str(round(total_non_affected/starting_population*100))+"%]\n")
  318. print("-"*75+"\n")
  319. else:
  320. print(" -> [DAY: "+str(i)+"]\n Status: "+str(status)+"\n Contagion: ("+str(int(contagion))+")[100%] - Recoveries: ("+str(int(recoveries))+")["+str(round(recoveries/total_population*100))+"%] - Deaths: ("+str(int(deaths))+")["+str(round(deaths/total_population*100))+"%] | Susceptible: ("+str(int(susceptible))+")[0%] - Infected: ("+str(int(infected))+")[100%] - Recovered: ("+str(int(recovered))+")["+str(round(recovered/total_population*100))+"%]")
  321. print(" Total Population: ("+str(int(total_population))+"/"+str(int(starting_population))+") - Total Contagion: ("+str(int(total_contagion))+")["+str(round(total_contagion/starting_population*100))+"%] - Total Recovered: (" +str(int(total_recovered))+")["+str(round(total_recovered/starting_population*100))+"%] - Total Deceased: ("+str(int(total_deceased))+")["+str(round(total_deceased/starting_population*100))+"%] - Total N/A: ("+str(int(total_non_affected))+")["+str(round(total_non_affected/starting_population*100))+"%]\n")
  322. data['SIMULATION'][0]['Status'] = str(status)
  323. data['SIMULATION'][0]['Contagion'] = str(int(contagion)) # generate json
  324. data['SIMULATION'][0]['Recoveries'] = str(int(recoveries))
  325. data['SIMULATION'][0]['Deaths'] = str(int(deaths))
  326. data['SIMULATION'][0]['Susceptible'] = str(int(susceptible))
  327. data['SIMULATION'][0]['Infected'] = str(int(infected))
  328. data['SIMULATION'][0]['Recovered'] = str(int(recovered))
  329. data['SIMULATION'][0]['Deceased'] = str(int(deceased))
  330. data['SIMULATION'][0]['Total Population'] = str(int(total_population))
  331. data['SIMULATION'][0]['Total Contagion'] = str(int(total_contagion))
  332. data['SIMULATION'][0]['Total Recovered'] = str(int(recovered))
  333. data['SIMULATION'][0]['Total Deceased'] = str(int(total_deceased))
  334. data['SIMULATION'][0]['Total N/A'] = str(int(total_non_affected))
  335. with open(reports_path+'PandeMaths-report_'+str(current_time)+'.json', 'a', encoding='utf-8') as f: # append simulation into json
  336. json.dump(data, f, ensure_ascii=False, sort_keys=False, indent=4)
  337. else: # population has passed the pandemia
  338. status = "VACCINED!"
  339. if entire_population_infected == 0:
  340. total_contagion = starting_population
  341. print("-"*75+"\n")
  342. print(" -> [DAY: "+str(i)+"] -> [ NO MORE INFECTED! ]\n Status: "+str(status)+"\n Contagion: ("+str(int(contagion))+")[0%] - Recoveries: ("+str(int(recoveries))+")["+str(round(recoveries/total_population*100))+"%] - Deaths: ("+str(int(deaths))+")["+str(round(deaths/total_population*100))+"%] | Susceptible: ("+str(int(susceptible))+")[0%] - Infected: ("+str(int(infected))+")[0%] - Recovered: ("+str(int(recovered))+")["+str(round(recovered/total_population*100))+"%]")
  343. print(" Total Population: ("+str(int(total_population))+"/"+str(int(starting_population))+") - Total Contagion: ("+str(int(total_contagion))+")["+str(round(total_contagion/starting_population*100))+"%] - Total Recovered: (" +str(int(total_recovered))+")["+str(round(total_recovered/starting_population*100))+"%] - Total Deceased: ("+str(int(total_deceased))+")["+str(round(total_deceased/starting_population*100))+"%] - Total N/A: ("+str(int(total_non_affected))+")["+str(round(total_non_affected/starting_population*100))+"%]\n")
  344. print("-"*75+"\n")
  345. data['SIMULATION'][0]['DAY'] = str(i)
  346. data['SIMULATION'][0]['Status'] = "[ NO MORE INFECTED! ]"
  347. data['SIMULATION'][0]['Contagion'] = str(int(contagion)) # generate json
  348. data['SIMULATION'][0]['Recoveries'] = str(int(recoveries))
  349. data['SIMULATION'][0]['Deaths'] = str(int(deaths))
  350. data['SIMULATION'][0]['Susceptible'] = str(int(susceptible))
  351. data['SIMULATION'][0]['Infected'] = str(int(infected))
  352. data['SIMULATION'][0]['Recovered'] = str(int(recovered))
  353. data['SIMULATION'][0]['Deceased'] = str(int(deceased))
  354. data['SIMULATION'][0]['Total Population'] = str(int(total_population))
  355. data['SIMULATION'][0]['Total Contagion'] = str(int(total_contagion))
  356. data['SIMULATION'][0]['Total Recovered'] = str(int(recovered))
  357. data['SIMULATION'][0]['Total Deceased'] = str(int(total_deceased))
  358. data['SIMULATION'][0]['Total N/A'] = str(int(total_non_affected))
  359. with open(reports_path+'PandeMaths-report_'+str(current_time)+'.json', 'a', encoding='utf-8') as f: # append simulation into json
  360. json.dump(data, f, ensure_ascii=False, sort_keys=False, indent=4)
  361. break
  362. else:
  363. if total_deceased >= starting_population: # the entire population has died! [game over!]
  364. status = "FATAL!"
  365. contagion = 0
  366. recoveries = 0
  367. deaths = 0
  368. susceptible = 0
  369. total_population = 0
  370. total_non_affected = 0
  371. print(" -> [DAY: "+str(i)+"] -> FATAL! [ THE ENTIRE POPULATION HAS DIED! ]\n Status: "+str(status)+"\n Contagion: ("+str(int(contagion))+")[100%] - Recoveries: ("+str(int(recoveries))+")[0%] - Deaths: ("+str(int(deaths))+")[100%] - Susceptible: ("+str(int(susceptible))+")[0%] - Infected: ("+str(int(infected))+")[100%] - Recovered: ("+str(int(recovered))+")[0%]")
  372. print(" Total Population: ("+str(int(total_population))+"/"+str(int(starting_population))+") - Total Contagion: ("+str(int(total_contagion))+")["+str(round(total_contagion/starting_population*100))+"%] - Total Recovered: (" +str(int(total_recovered))+")["+str(round(total_recovered/starting_population*100))+"%] - Total Deceased: ("+str(int(total_deceased))+")["+str(round(total_deceased/starting_population*100))+"%] - Total N/A: ("+str(int(total_non_affected))+")["+str(round(total_non_affected/starting_population*100))+"%]\n")
  373. data['SIMULATION'][0]['DAY'] = str(i)
  374. data['SIMULATION'][0]['Status'] = "FATAL! [ THE ENTIRE POPULATION HAS DIED! ]"
  375. data['SIMULATION'][0]['Contagion'] = str(contagion)
  376. data['SIMULATION'][0]['Recoveries'] = str(recoveries)
  377. data['SIMULATION'][0]['Deaths'] = str(deaths)
  378. data['SIMULATION'][0]['Susceptible'] = str(susceptible)
  379. data['SIMULATION'][0]['Infected'] = str(infected)
  380. data['SIMULATION'][0]['Recovered'] = str(recovered)
  381. data['SIMULATION'][0]['Deceased'] = str(deceased)
  382. data['SIMULATION'][0]['Total Population'] = str(total_population)
  383. data['SIMULATION'][0]['Total Contagion'] = str(total_contagion)
  384. data['SIMULATION'][0]['Total Recovered'] = str(total_recovered)
  385. data['SIMULATION'][0]['Total Deceased'] = str(total_contagion)
  386. data['SIMULATION'][0]['Total N/A'] = str(total_non_affected)
  387. with open(reports_path+'PandeMaths-report_'+str(current_time)+'.json', 'a', encoding='utf-8') as f: # append simulation into json
  388. json.dump(data, f, ensure_ascii=False, sort_keys=False, indent=4)
  389. break
  390. status = "FINISHED!"
  391. if infected == 0:
  392. deaths = 0
  393. recoveries = 0
  394. contagion = 0
  395. print(" -> [DAY: "+str(i)+"] -> [ SIMULATION END! ]\n Status: "+str(status))
  396. print(" Total Population: ("+str(int(total_population))+"/"+str(int(starting_population))+") - Total Contagion: ("+str(int(total_contagion))+")["+str(round(total_contagion/starting_population*100))+"%] - Total Recovered: (" +str(int(total_recovered))+")["+str(round(total_recovered/starting_population*100))+"%] - Total Deceased: ("+str(int(total_deceased))+")["+str(round(total_deceased/starting_population*100))+"%] - Total N/A: ("+str(int(total_non_affected))+")["+str(round(total_non_affected/starting_population*100))+"%]\n")
  397. data['SIMULATION'][0]['DAY'] = str(i)
  398. data['SIMULATION'][0]['Status'] = str(status)
  399. data['SIMULATION'][0]['Contagion'] = str(contagion)
  400. data['SIMULATION'][0]['Recoveries'] = str(recoveries)
  401. data['SIMULATION'][0]['Deaths'] = str(deaths)
  402. data['SIMULATION'][0]['Susceptible'] = str(susceptible)
  403. data['SIMULATION'][0]['Infected'] = str(infected)
  404. data['SIMULATION'][0]['Recovered'] = str(recovered)
  405. data['SIMULATION'][0]['Deceased'] = str(deceased)
  406. data['SIMULATION'][0]['Total Population'] = str(total_population)
  407. data['SIMULATION'][0]['Total Contagion'] = str(total_contagion)
  408. data['SIMULATION'][0]['Total Recovered'] = str(total_recovered)
  409. data['SIMULATION'][0]['Total Deceased'] = str(total_contagion)
  410. data['SIMULATION'][0]['Total N/A'] = str(total_non_affected)
  411. with open(reports_path+'PandeMaths-report_'+str(current_time)+'.json', 'a', encoding='utf-8') as f: # append simulation into json
  412. json.dump(data, f, ensure_ascii=False, sort_keys=False, indent=4)
  413. print("="*50 + "\n")
  414. print ("[Info] Report [SAVED!] at: "+str(reports_path+'PandeMaths-report_'+str(current_time)+'.json')+"\n")
  415. def print_banner():
  416. print("\n"+"="*50)
  417. print(" ____ _ __ __ _ _ ")
  418. print("- _ \ __ _ _ __ __- - ___- \/ - __ _- -_- -__ ___ ")
  419. print("- -_) / _` - '_ \ / _` -/ _ \ -\/- -/ _` - __- '_ \/ __--2020")
  420. print("- __/ (_- - - - - (_- - __/ - - - (_- - -_- - - \__ /")
  421. print("-_- \__,_-_- -_-\__,_-\___-_- -_-\__,_-\__-_- -_-___/-by psy")
  422. print('\n"Pandemics Extensible Mathematical Model"')
  423. print("\n"+"-"*15+"\n")
  424. print(" * VERSION: ")
  425. print(" + "+VERSION+" - (rev:"+RELEASE+")")
  426. print("\n * SOURCES:")
  427. print(" + "+SOURCE1)
  428. print(" + "+SOURCE2)
  429. print("\n * CONTACT: ")
  430. print(" + "+CONTACT+"\n")
  431. print("-"*15+"\n")
  432. print("="*50)
  433. # sub_init #
  434. print_banner() # show banner
  435. try:
  436. option = input("\n+ CHOOSE: (M)odel or (S)imulation: ").upper()
  437. except:
  438. print("\n"+"="*50 + "\n")
  439. print ("[Info] Try to run the tool with Python3.x.y... (ex: python3 pandemaths) -> [EXITING!]\n")
  440. sys.exit()
  441. print("")
  442. print("="*50+"\n")
  443. if option == "S": # simulation
  444. simulation()
  445. else: # model
  446. model_maths()
  447. print ("="*50+"\n")