<jupyter_start><jupyter_text>GEOG5990 Independent Project The Black Death *<NAME>*  ____ In this project, I am an epidemiologist looking back at the Black Death outbreak in 1665. My aim is to calculate the total dealths from the disease using historical figures of rate population (as recorded by local rat-catchers) and the population density (derived from the parish records). This historical data is stored as two text data files, which are visualised by two 400x00 raster maps in this notebook, displaying the area covered by the parish populations, and by the rat catchers. The average death rate is calculated from the equation d = (0.8 x r) x (1.3 x p), where: *d - average weekly deaths* *r  - average rats caught per week* *p - average population density* This project displays the average rat catch map and the average parish population maps separately, and then uses the above equation to combine the two maps to produce the map of average death rate per week.  This project also enables the user to manipulate the equation parameters using scale bars in order to change the average weekly death rate to mimic different scenarios that could have ensued during the Black Death outbreak in London. *  Running the notebook: 1. Ensure the relevant files: TheBlackDeath.ipynb, and deathmap.txt have been downloaded and saved on the Jupyter Home page. 2. For each step starting from Step 1: enter each Kernel with * Run* at the start, and click on the 'Run' buttom at the top of the page, or SHIFT + ENTER. *This runs the instructions in each kernel.* 3. In Step 4, the *deathmap.txt* textfile is created, which you can find from the notebook Home page if you wish! 4. In Step 5, alter the Rats and Parishes paramater bars as you wish to change the equation! 5. From this, Run the kernel below in Step 6 to see how your chosen parameters alter the death rate outcome! _____  **Step 1: Imports**<jupyter_code># Run
'''Step 1: Imports.''' 

%matplotlib inline
import random
import matplotlib
import matplotlib.pyplot
import csv
import numpy as np
import matplotlib.pyplot as plt
import os
# Below imports for the sliding scale bars
import ipywidgets
from ipywidgets import widgets
import ipywidgets as widgets
from matplotlib.widgets import Slider
from pylab import *<jupyter_output><empty_output><jupyter_text>Step 2: Load the parish death rate map<jupyter_code># Run
'''Step 2: Load the parish death rate map.'''

environment1 = [] # The parish death rate map is denoted as environment1

f = open("death_parishes.txt", newline = '')
reader = csv.reader(f,quoting=csv.QUOTE_NONNUMERIC)
for row in reader: # List of rows
    rowlist = []
    for value in row: # List of values
        rowlist.append(value)
    environment1.append(rowlist) # List of values for the row added to total environment
                                 # in the loop, for row in reader, not in loop for value in row.
f.close()

matplotlib.pyplot.xlim(0, 400)
matplotlib.pyplot.ylim(0, 400)
matplotlib.pyplot.imshow(environment1)
matplotlib.pyplot.title('Parish death rate map')

#######################################<jupyter_output><empty_output><jupyter_text>This map displays the average population densities of the 16 parishes in London, 1665.  Step 3: Load the average rat catch map.<jupyter_code># Run
'''Step 3: Load the average rat catch map.'''

environment2 = [] # The average rat catch map is denoted as environment2

f = open("death_rats.txt", newline = '')
reader = csv.reader(f,quoting=csv.QUOTE_NONNUMERIC)
for row in reader: # List of rows
    rowlist = []
    for value in row: # List of values
        rowlist.append(value)
    environment2.append(rowlist) # List of values for the row added to total environment
                                 # in the loop, for row in reader, not in loop for value in row.
f.close()

matplotlib.pyplot.xlim(0, 400)
matplotlib.pyplot.ylim(0, 400)
matplotlib.pyplot.imshow(environment2)
matplotlib.pyplot.title('Average rat catch map')

#######################################<jupyter_output><empty_output><jupyter_text>This map displays the average number of rats caught per week per 100m x 100m square for each rat catcher's area of work.  Step 4: Combine the parish death rate map and average rat catch map<jupyter_code># Run
'''Step 4: Combine the parish death rate map and average rat catch map.'''

# Parish death rate map = environment1
# Average rat catch map = environment2


# Combine the 2 datasets to create a map of average death rate.
result = []

for r in range(len(environment1)):
    row_a = environment1[r]
    row_b = environment2[r]
    rowlist = []
    result.append(rowlist)
    for c in range(len(row_a)):
        r = row_a[c] # rats  
        p = row_b[c] # parishes
        # deaths = (0.8 x rats) x (1.3 x parishes) Equation used to calculate the average death rate.
        d = (0.8 * r) * (1.3 * p)
        rowlist.append(d)
        #print(d) # Test the result.
        
print('Random value generated:', result[250][0])
# The above tests a random value as generated by the equation for average death rate.

# Shows the new map of averarge death rate, calculated from the 2 combined datasets.
matplotlib.pyplot.xlim(0, 400)
matplotlib.pyplot.ylim(0, 400)
matplotlib.pyplot.imshow(result)
matplotlib.pyplot.title('Map of average death rate')

# Shows the average weekly death rate
print('Average weekly death rate =', round(d,2))


'''Step 4.1: Save the average death rate result as a separate textfile.'''

np.savetxt('deathmap.txt', result, fmt='%-6f' , newline="\r\n")
# Makes each line in the textfile equal a new line on the map.

#######################################<jupyter_output>Random value generated: 15912.0
Average weekly death rate = 10670.4<jupyter_text>This map displays the average death rate within the parishes investigated, within a 400x400 environment. This was calculated by combining the average parish population density, and the average weekly rat catch for each rat catcher's area of work. These data were combined with the equation: deaths = (0.8 x rats) x (1.3 x parishes). The result of the average death rate calculation can be found as a textfile, titled 'deathmap.txt' which can be accessed from the Jupyter notebook home page.  Step 5: Display the death rate map with changing, interactive parameters.<jupyter_code># Run
'''Step 5: Display the death rate map with interactive parameters.'''

'''The initial equation for calculating death rate:
deaths = (0.8 x rats) x (1.3 x parishes)'''

'''Step 5.1.1: Create the slider for the average rat population.'''
wR = widgets.FloatSlider(
    value=0.8, # Initial equation value
    min=0, # Minimum range is 0
    max=2.0, # Maximum range is 2.0
    step=0.1, # Increment is 0.1 decimal places
    description='Rats:',
    readout_format='.1f',
)
display(wR) # This displays the slider for the Rats value.


'''Step 5.1.2: Create the slider for the parish population.'''
wP = widgets.FloatSlider(
    value=1.3, # Initial equation value
    min=0, # Minimum range is 0
    max=2.0, # Maximum range is 2.0
    step=0.1, # Increment is 0.1 decimal places
    description='Parishes:',
    readout_format='.1f',
)
display(wP) # This displays the slider for the Parishes value.

#######################################<jupyter_output><empty_output><jupyter_text>Step 6: View the new average death rate outcome.<jupyter_code># Run
'''Step 6: Get the slider results to display on the new map,
enabling user to change the equation parameter weights'''

print('User-generated slider values:')
print (wR.value, 'Rats')
print (wP.value, 'Parishes')
# This prints the slider values in order to display the change made to the equation parameters.

# This displays the map of average death rate with the new values as adjusted by the slider bars.
result = []

for r in range(len(environment1)):
    row_a = environment1[r]
    row_b = environment2[r]
    rowlist = []
    result.append(rowlist)
    for c in range(len(row_a)):
        r = row_a[c] # rats  
        p = row_b[c] # parishes
        # d = (0.8 x r) x (1.3 x p) Original equation used to calculate the average death rate.
        d = (wR.value * r) * (wP.value * p) # Equation accounting for the change in parameter values.
        # Changed 0.8 for wR and 1.3 for wP, to mimic the change in parameters.
        rowlist.append(d)
        #print(d) # Test the result.  

# Show the new map of averarge death rate, with adjusted parameters.
matplotlib.pyplot.xlim(0, 400)
matplotlib.pyplot.ylim(0, 400)
matplotlib.pyplot.imshow(result)
matplotlib.pyplot.title('Map of death rate with changed parameters')


print('New value generated:', result[250][0])
# The above test checks the new value against the initial average death
# rate value of 15912.0 to prove the sliders have altered the map outcome.

# Shows the average weekly death rate for the altered parameters.
print('Average weekly death rate at these parameters =', round(d,2))

#######################################<jupyter_output>User-generated slider values:
1.4 Rats
0.6 Parishes
New value generated: 12852.0
Average weekly death rate at these parameters = 8618.4
{'fraction_non_alphanumeric': 0.10171165240289665, 'fraction_numerical': 0.0228220320386219, 'mean_word_length': 4.041482300884955, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '246607', 'license': 'BSD-2-Clause', 'n_tokens_mistral': 2787, 'n_tokens_neox': 2609, 'n_words': 1187, 'path': 'TheBlackDeath.ipynb', 'repo_name': 'gy18gs/TheBlackDeath', 'size': '9121'}