From 8792556454643d9b80fcc58c12163c1ac0ecf4aa Mon Sep 17 00:00:00 2001 From: tripplerizz Date: Tue, 14 Apr 2020 18:57:20 -0400 Subject: [PATCH] adding updated changes... but this doesn't work --- Cell.py | 97 ++++++++++++++----------------------------- GameBoard.py | 29 ++++++++----- GermTheory.py | 4 +- info.py | 60 +++++++++++++++++++++++--- populationExcel.xlsx | Bin 0 -> 18129 bytes 5 files changed, 106 insertions(+), 84 deletions(-) create mode 100644 populationExcel.xlsx diff --git a/Cell.py b/Cell.py index 9f71127..f079b11 100644 --- a/Cell.py +++ b/Cell.py @@ -56,7 +56,7 @@ def isOld(self): return int(self.age >= 74) def hasVirus(self): - return self.infectionStatus == 2 + return int(self.infectionStatus == 2 ) # ----------------------------------------------------------------------------------------- # set functions @@ -75,13 +75,13 @@ def setInfectionStatus(self, stat): self.infectionStatus = stat # move functions--------------------------------------------------------------------------------- - def setPos(self, x, y): # setting x,y coords - # this function checks the bounds of the board - if (x >= self.gameBoard.size - 1): + def setPos(self,x,y): # setting x,y coords + # this function checks the bounds of the board + if(x > self.gameBoard.size -1): return - if (y >= self.gameBoard.size - 1): + if (y > self.gameBoard.size - 1): return - if (x <= 1): + if ( x <= 1): return if (y <= 1): return @@ -89,70 +89,37 @@ def setPos(self, x, y): # setting x,y coords self.Column = y self.Row = x - def returnKernel(self): - miniboard = numpy.ones((3, 3), dtype=int) # this function creates a sub grid of neighbors around cell - gameGrid = self.gameBoard.grid - gameSize = self.gameBoard.size - #------------------------------------ - rowDown = self.Row - 1 # these variables represent pos on grid next to cell - rowUp = self.Row + 1 - columnDown = self.Column -1 - columnUp = self.Column + 1 - - miniboard[0][0] = gameGrid[(rowDown) % gameSize][columnDown % gameSize] - miniboard[0][1] = gameGrid[rowDown % gameSize][(self.Column)] - miniboard[0][2] = gameGrid[rowDown % gameSize][columnUp % gameSize] - miniboard[1][0] = gameGrid[(self.Row)][columnDown % gameSize] - miniboard[1][1] = self.infectionStatus - miniboard[1][2] = gameGrid[(self.Row)][columnUp % gameSize] - miniboard[2][0] = gameGrid[rowUp % gameSize][columnDown % gameSize] - miniboard[2][1] = gameGrid[rowUp % gameSize][(self.Column)] - miniboard[2][2] = gameGrid[rowUp % gameSize][columnUp % gameSize] - - return miniboard - - - def getPosInGrid(self, x, y): - return self.Row + x, self.Column + y - - def move(self): - newrow = self.Row - newcol = self.Column - if (self.infectionStatus == 1): # move for healthy cells, finding the least crowded space - kernel = numpy.ones((3, 3), dtype=numpy.int8) - kernel[1, 1] = 0 - miniboard = self.returnKernel() - neighbour = signal.convolve(miniboard, kernel, mode='same') # count neighbors - neighbour[1][1] = 999 - j = numpy.argwhere(neighbour == numpy.min(neighbour)) - x = random.randrange(0, len(j)) - minindex = j[x] - newrow, newcol = self.getPosInGrid(minindex[0] - 1, minindex[1]- 1) - - elif(self.infectionStatus==2): - #SET RANDOM POSITION FOR INFECTED CELLS - newrow = self.Row + (random.randint(-1, 1)) - newcol = self.Column + (random.randint(-1, 1)) - - # IF POSITION OCCUPIED, perform collision - if(self.gameBoard.grid[newrow][newcol]!=0): - self.collision() - self.time +=1 - self.setPos(newrow, newcol) - - def collision(self): # Collision function with other cells - if (self.infectionStatus == 1): - x = random.randint(0, 2) + def move(self, cellDict): + while True: + x = self.Row + (random.randint(-1,1)) + y = self.Column + (random.randint(-1,1)) + if x > 0 and x < self.gameBoard.size -1 and y > 0 and y < self.gameBoard.size -1: + break + + while(self.gameBoard.grid[x,y] != 0): + if cellDict[x,y].infectionStatus == 2: + self.collision() + + x = self.Row + (random.randint(-1,1)) + y = self.Column + (random.randint(-1,1)) + + self.setPos(x, y) + self.time += 1 + + + def collision(self): + if(self.infectionStatus == 1): + x = random.randint(0,2) if (x == 2): - self.infectionStatus = 2 # set to infected - self.gameBoard.infectedCount += 1 # updating infected count of population + self.infectionStatus = 2 + self.gameBoard.infectedCount += 1 # updating infected count of population def deathRate(self): # All encompassing death rate function for cells. virus = self.hasVirus() vulnerable = self.isVulnerable() - daily = 0.00005 - total = (daily + vulnerable + virus) - if random.random() <= total: + total = (vulnerable + virus) + print(total) + if random.randint(0, 10) <= total: self.gameBoard.infectedCount -= 1 return 1 return 0 \ No newline at end of file diff --git a/GameBoard.py b/GameBoard.py index f7881d7..b831217 100644 --- a/GameBoard.py +++ b/GameBoard.py @@ -2,7 +2,8 @@ import matplotlib.pyplot as plt import random as rd from Cell import Cell -from info import getTotalCases, getTotalDeaths, getDeathRate, getPopulation +import info +# from info import getTotalCases, getTotalDeaths, getDeathRate, getPopulation class Board: @@ -19,18 +20,24 @@ def __init__(self, inSize): # creating parameter for user self.grid = np.zeros((inSize, inSize)) cell_dict = {} - def createPopulation (self, population, infected): # creates a population based on parameters and board + def relativePopulation(self, state): # this function grabs population from census information + return int(info.getPopulation(state)/ self.size **2) + + def getPercentInfected(self, state): + return float(info.getTotalCases(state)/info.getPopulation(state)) + + def createPopulation (self, state): # creates a population based on parameters and board - self.population = population + 1 - self.infectedCount = infected + self.population = self.relativePopulation(state) + self.infectedCount = int(self.population * self.getPercentInfected(state)) randomCoord = [0,0] randomCoord[0] = (rd.randint(1, self.size - 1)) # location x randomCoord[1] = (rd.randint(1, self.size - 1)) # location y - for x in range(0, self.population -1): + for x in range(0, self.population): infectionStatus = 1 - if x < infected: # this condition creates number of infected sells specified by parameters + if x < self.infectedCount: # this condition creates number of infected sells specified by parameters infectionStatus = 2 # get random coordinates for cell @@ -50,24 +57,24 @@ def createPopulation (self, population, infected): # creates a population based self.grid[new_cell.Row, new_cell.Column] = new_cell.infectionStatus # add cell status to grid def update_grid(self): - for x in range(0, self.size-1): - for y in range(0, self.size-1): + for x in range(0, self.size): + for y in range(0, self.size): if (x, y) in self.cell_dict: popped_cell = self.cell_dict.pop((x, y)) # get cell from 'grid' (accessed via dictionary) self.grid[x][y] = 0 # set grid cell to 0 - popped_cell.move() # call move on cell + popped_cell.move(self.cell_dict) # call move on cell if(popped_cell.time % 10 != 0): # Every 10 moves, no deaths self.cell_dict[popped_cell.Row, popped_cell.Column] = popped_cell self.grid[popped_cell.Row][popped_cell.Column] = popped_cell.infectionStatus else: - #if(popped_cell.deathRate() == 0): # Otherwise, call for death + if (popped_cell.deathRate() == 0): # Otherwise, call for death self.cell_dict[popped_cell.Row, popped_cell.Column] = popped_cell self.grid[popped_cell.Row][popped_cell.Column] = popped_cell.infectionStatus def show(self): - while len(self.cell_dict) != 20: # Visualize the grid + while len(self.cell_dict) > 150: # Visualize the grid plt.imshow(self.grid) plt.title("Population: " + str(len(self.cell_dict))) plt.xlabel("starting infection count = " + str(self.infectedCount)) diff --git a/GermTheory.py b/GermTheory.py index 888005b..29b15f7 100644 --- a/GermTheory.py +++ b/GermTheory.py @@ -7,8 +7,8 @@ def main(): b1 = Board(100) # Create board - b1.createPopulation( 10 , int(input("how many infected members: "))) # Create population - b1.update_grid() # Update grid + b1.createPopulation( input("What state are you in? ")) # Create population + b1.update_grid() # Update gridFlo b1.show() # Show main() diff --git a/info.py b/info.py index 82f2698..b65dcdc 100644 --- a/info.py +++ b/info.py @@ -1,10 +1,7 @@ import requests import pandas as pd -url = 'https://covidtracking.com/api/states' -response = requests.request("GET", url) -data = response.json() def prepareData(): @@ -29,10 +26,62 @@ def getPopulation(input): return int(data.at[state, 'population']) +url = 'https://covidtracking.com/api/states' + +response = requests.request("GET", url) +data = response.json() + +stateConversion = { "Alabma" :"AL", + "Alaska": "AK", + "Arizona": "AZ", + "Arkansas" : "AR", + "California" : "CA", + "Connecticut" : "CO", + "Delaware": "DE", + "Florida" : "FL", + "Georgia" : "GA", + "Hawaii" : "HI", + "Idaho" : "ID", + "Illinois" : "IL", + "Indiana" : "IN", + "Iowa" : "IA", + "Kansas" : "KS", + "Kentucky" : "KY", + "Louisiana" : "LA", + "Maine": "ME", + "Maryland" : "MD", + "Massachusetts" : "MA", + "Michigan" : "MI", + "Minnesota" : "MN", + "Mississipi" : "MS", + "Missouri" : "MO", + "Montana" : "MT", + "Nebraska" : "Nevada", + "New Hampshire" : "NH", + "New Jersey" : "NJ", + "New Mexico" : "NM", + "New York" : "NY", + "North Carolina" : "NC", + "North Dakota" : "ND", + "Ohio" : "OH", + "Oklahoma" : "OK", + "Oregon" : "OR", + "Pennsylvania" :"PA", + "Rhode Island" : "RI", + "South Carolina" : "SC", + "Tennessee" : "TN", + "Texas" : "TX", + "Utah" : "UT", + "Vermont" : "VT", + "Virginia" : "VA", + "Washington" : "WA", + "West Virginia" : "WV", + "Wisconsin" : "WI", + "Wyoming" : "WY"} def getState(state): - for index,list in enumerate(data): - if list['state'] == state: + for list in data: + if list['state'] == stateConversion.get(state): return list def getTotalCases(state): @@ -46,4 +95,3 @@ def getTotalDeaths(state): def getDeathRate(state): return (getTotalDeaths(state)/getTotalCases(state)) * 100 -print(getPopulation(input("what state?"))) \ No newline at end of file diff --git a/populationExcel.xlsx b/populationExcel.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..9993055ec0f8788f781a19355a0d0c5facc33206 GIT binary patch literal 18129 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 literal 0 HcmV?d00001