def run(grid_file, r, m_threshold, b_threshold, max_steps): ''' Put it all together: do the simulation and process the results. ''' if grid_file is None: print("No parameters specified...just loading the code") return grid = utility.read_grid(grid_file) if len(grid) < 20: print("Initial state of city:") for row in grid: print(row) print() opens = utility.find_opens(grid) num_relocations = do_simulation(grid, r, m_threshold, b_threshold, max_steps, opens) print("Number of relocations done: " + str(num_relocations)) if len(grid) < 20: print() print("Final state of the city:") for row in grid: print(row)
def helper(input_filename, expected_filename, R, M_threshold, B_threshold, max_num_steps, expected_num_relocations): ''' Do one simulation with the specified parameters (R, threshold, max_num_steps) starting from the specified input file. Match actual grid generated with the expected grid and match expected steps and actual steps. Inputs: input_filename: (string) name of the input grid file expected_filename: (string) name of the expected grid file. R: (int) radius for the neighborhood M_threshold: lower bound for similarity score for maroon homeowners B_threshold: lower bound for similarity score for blue homeowners max_steps: (int) maximum number of steps to do expected_num_relocations: (int) expected number of relocations performed during the simulation ''' input_filename = os.path.join(BASE_DIR, input_filename) actual_grid = utility.read_grid(input_filename) expected_num_homeowners = count_homeowners(actual_grid) opens = utility.find_opens(actual_grid) actual_num_relocations = do_simulation(actual_grid, R, M_threshold, B_threshold, max_num_steps, opens) actual_num_homeowners = count_homeowners(actual_grid) expected_filename = os.path.join(BASE_DIR, expected_filename) expected_grid = utility.read_grid(expected_filename) if actual_num_relocations != expected_num_relocations: s = ("actual and expected values number of relocations do not match\n" " got {:d}, expected {:d}") s = s.format(actual_num_relocations, expected_num_relocations) pytest.fail(s) if actual_num_homeowners != expected_num_homeowners: if actual_num_homeowners <= expected_num_homeowners: s = "Homeowners are fleeing the city!\n" else: s = ("The city is gaining homeowners.\n") s += (" Actual number of homeowners: {:d}\n" " Expected number of homeowners: {:d}\n") s = s.format(actual_num_homeowners, expected_num_homeowners) pytest.fail(s) mismatch = utility.find_mismatch(actual_grid, expected_grid) if mismatch: (i, j) = mismatch s = ("actual and expected grid values do not match " "at location ({:d}, {:d})\n") s = s.format(i, j) s = s + " got {}, expected {}".format(actual_grid[i][j], expected_grid[i][j]) pytest.fail(s)
def evaluate_open_spot(grid, R, location, M_threshold, B_threshold, opens): ''' Evaluate the best location that an unsatisfied person can move to on the grid from his location, with rules established in PA #2 Inputs: grid: the grid the person is on R: the radius of the neighborhood that will go into determining if he's satisfied location: his current location tuple M_threshold: lower bound for similarity score for maroon homeowners B_threshold: lower bound for similarity score for blue homeowners opens: a list of open locations, such that the latter a position is listed, the more recent they have been on the market ''' assert grid[location[0]][location[1]] != "O" assert is_satisfied(grid, R, location, M_threshold, B_threshold) == False #Initializing all potential location lists location_list = [] second_location_list = [] third_location_list = [] distance_list = [] R1_neighbor_list = [] # Initialting the list of current open spots open_spot_list = utility.find_opens(grid) # Search for locations that meet the satisfaction threshold, add all of them to a list for loc in open_spot_list: swap_value(grid, location, loc) if is_satisfied(grid, R, loc, M_threshold, B_threshold): location_list.append(loc) distance_list.append(distance(location, loc)) swap_value(grid, location, loc) # If there's no open spot, return current location if (len(location_list) == 0): return location # If there's only one location, return that location elif (len(location_list) == 1): return location_list[0] # If there are more than one locations that meets the criteria, we determine the one with shortest distance else: # Check if the new location's distance is the minimum of all viable locations' distances, add them to a new list for loc in location_list: if (distance(location, loc) == min(distance_list)): second_location_list.append(loc) R1_neighbor_list.append(R1_direct_neighbor(grid, loc)) # If there's only one location, return this location if (len(second_location_list) == 1): return second_location_list[0] # If there's more than one location, compare the number of R-1 neigbors between these locations elif (len(second_location_list) > 1): # Check if a neigborhood has the maximum of all viable location's numbers of R-1 neighbors, add them to a new list for loc in second_location_list: if (R1_direct_neighbor(grid, loc) == max(R1_neighbor_list)): third_location_list.append(loc) # If there's one location, return this location if (len(third_location_list) == 1): return third_location_list[0] # If there's more, we see which one is the most recent to go on the market elif (len(third_location_list) > 1): # We loop backwards in the opens list, which ever location appear first, return that location for loc1 in reversed(third_location_list): for loc2 in opens: if (loc1 == loc2): return loc1 # Failsafe if all codes fail return None