Skip to content

Commit

Permalink
Added documentation for python scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
Erik-Brown01 committed Dec 21, 2023
1 parent 2893e24 commit 79fb662
Show file tree
Hide file tree
Showing 4 changed files with 378 additions and 223 deletions.
33 changes: 26 additions & 7 deletions scripts/legislation_info_generator.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
import os
import pyairtable
import json
LEGISLATION_INFO = os.environ['LEGISLATION_INFO']
api = pyairtable.Api(LEGISLATION_INFO)
table = api.table('apps7I6q0g9Hyb6j9','tblydWhHOZeqjzycO')
legislation = table.all()
legislation_list = [x['fields'] for x in legislation]
with open("public/legislations_info.json", "w") as outfile:
json.dump(legislation_list, fp = outfile,indent = 4)

def generate_legislation_info(API_KEY, APP_KEY, TBL_KEY):
"""
Generates legislation information and saves it to a JSON file.
This function retrieves legislation information from an Airtable database,
converts it to a list of dictionaries, and saves it to a JSON file for the front-end to access.
Args:
API_KEY (str): The API key for accessing the Airtable database.
APP_KEY (str): The application key for accessing the Airtable database.
TBL_KEY (str): The table key for accessing the specific table in the Airtable database.
Returns:
None
"""
api = pyairtable.Api(API_KEY)
table = api.table(APP_KEY, TBL_KEY)
legislation = table.all()
legislation_list = [x['fields'] for x in legislation]
with open("public/legislations_info.json", "w") as outfile:
json.dump(legislation_list, fp=outfile, indent=4)

if __name__ == '__main__':
API_KEY = os.environ['LEGISLATION_INFO']
generate_legislation_info(API_KEY, 'apps7I6q0g9Hyb6j9', 'tblydWhHOZeqjzycO')
139 changes: 100 additions & 39 deletions scripts/legislation_votes_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,45 @@
import pandas as pd
import json

senate_data = []
with open("public/senate.geo.json", 'r') as f:
senate_data = json.load(f)
assembly_data = []
with open("public/assembly.geo.json", 'r') as f:
assembly_data = json.load(f)

# Function to extract unique bill names from "HCMC support"
def extract_unique_bills(features):
unique_bills = set()
for feature in features:
hcmc_support = feature['properties'].get('HCMC support', [])
unique_bills.update(hcmc_support)
return unique_bills
def create_summary_data(counts, house):
"""
Creates a summary of vote counts for each party in the given house.
Args:
counts (dict): A dictionary containing the vote counts for each party and bill.
house (str): The name of the house.
# Extracting unique bills from Senate and Assembly
unique_bills_senate = extract_unique_bills(senate_data['features'])
unique_bills_assembly = extract_unique_bills(assembly_data['features'])
Returns:
list: A list of dictionaries, where each dictionary represents a party and its vote counts.
Each dictionary contains the following keys:
- "House": The name of the house.
- "Party": The name of the party.
- The bill names as keys, and the corresponding vote counts as string values.
"""
summary = []
for party, bills in counts.items():
party_data = {"House": house, "Party": party}
party_data.update({bill: str(count) for bill, count in bills.items()})
summary.append(party_data)
return summary

# Combining and sorting the unique bills
all_unique_bills = sorted(unique_bills_senate.union(unique_bills_assembly))
def count_bills_support(features, unique_bills):
"""
Counts the number of bills supported by Democrats and Republicans.
Args:
features (list): A list of features containing information about each legislator.
unique_bills (list): A list of unique bill names.
Returns:
dict: A dictionary containing the counts of bills supported by Democrats and Republicans.
The dictionary has the following structure:
{
"Democrat": {bill: count},
"Republican": {bill: count}
}
where 'bill' is the name of the bill and 'count' is the number of occurrences.
"""
counts = {
"Democrat": {bill: 0 for bill in unique_bills},
"Republican": {bill: 0 for bill in unique_bills}
Expand All @@ -44,27 +61,71 @@ def count_bills_support(features, unique_bills):

return counts

# Counting bills for Senate and Assembly
senate_bills_counts = count_bills_support(senate_data['features'], all_unique_bills)
assembly_bills_counts = count_bills_support(assembly_data['features'], all_unique_bills)
def create_summary_data(counts, house):
summary = []
for party, bills in counts.items():
party_data = {"House": house, "Party": party}
party_data.update({bill: str(count) for bill, count in bills.items()})
summary.append(party_data)
return summary
def extract_unique_bills(features):
"""
Extracts unique bills from a list of features.
Args:
features (list): A list of features.
Returns:
set: A set of unique bills.
"""
unique_bills = set()
for feature in features:
hcmc_support = feature['properties'].get('HCMC support', [])
unique_bills.update(hcmc_support)
return unique_bills

import json

def generate_legislation_votes():
"""
Generates a JSON file containing the summary data of legislation votes for the Senate and Assembly.
This function reads the Senate and Assembly data from the 'public' directory, extracts unique bills,
counts the support for each bill in the Senate and Assembly, creates summary data for each chamber,
combines the summaries, and writes the final summary data to a new JSON file.
Args:
None
Returns:
None
"""

senate_data = []
with open("public/senate.geo.json", 'r') as f:
senate_data = json.load(f)
assembly_data = []
with open("public/assembly.geo.json", 'r') as f:
assembly_data = json.load(f)

# Extracting unique bills from Senate and Assembly
unique_bills_senate = extract_unique_bills(senate_data['features'])
unique_bills_assembly = extract_unique_bills(assembly_data['features'])

# Combining and sorting the unique bills
all_unique_bills = sorted(unique_bills_senate.union(unique_bills_assembly))

# Counting bills for Senate and Assembly
senate_bills_counts = count_bills_support(senate_data['features'], all_unique_bills)
assembly_bills_counts = count_bills_support(assembly_data['features'], all_unique_bills)

# Creating the summary data for Senate and Assembly
summary_data_senate = create_summary_data(senate_bills_counts, "Senate")
summary_data_assembly = create_summary_data(assembly_bills_counts, "Assembly")

# Combining both summaries
final_summary_data = summary_data_senate + summary_data_assembly

# Creating the summary data for Senate and Assembly
summary_data_senate = create_summary_data(senate_bills_counts, "Senate")
summary_data_assembly = create_summary_data(assembly_bills_counts, "Assembly")
# Path for the new JSON file
output_file_path_dynamic = "public/legislations_votes.json"

# Combining both summaries
final_summary_data = summary_data_senate + summary_data_assembly
# Writing the data to a new JSON file
with open(output_file_path_dynamic, 'w') as file:
json.dump(final_summary_data, file, indent=4)

# Path for the new JSON file
output_file_path_dynamic = "public/legislations_votes.json"

# Writing the data to a new JSON file
with open(output_file_path_dynamic, 'w') as file:
json.dump(final_summary_data, file, indent=4)
if __name__ == '__main__':
generate_legislation_votes()
79 changes: 53 additions & 26 deletions scripts/legislative_support_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,67 @@
import pandas as pd
import geopandas as gpd

LEGISLATIVE_SUPPORT = os.environ['LEGISLATIVE_SUPPORT']
def generate_legislative_support_geojson(API_KEY, APP_KEY, TBL_KEY):
"""
Generates GeoJSON files for New York State Assembly and Senate districts
with legislative support data.
api = pyairtable.Api(LEGISLATIVE_SUPPORT)
The function retrieves data from an Airtable database using the pyairtable library,
merges it with GeoJSON files for district boundaries, and exports the merged data
as separate GeoJSON files for Assembly and Senate districts.
table = api.table('appD3YhFHjmqJKtZ6','tblgyOlrTfYRaodyb')
Args:
API_KEY (str): The API key for accessing the Airtable database.
APP_KEY (str): The application key for accessing the Airtable database.
TBL_KEY (str): The table key for accessing the Airtable database.
table_dict = table.all()
Returns:
None
"""

rows = []
# Initialize pyairtable API
api = pyairtable.Api(API_KEY)

for row in table_dict:
rows.append(row['fields'])
df = pd.DataFrame(rows)
# Load GeoJSONs
gdf_assembly = gpd.read_file("public/NYS_Assembly_Districts.geojson").to_crs("EPSG:4326")
gdf_senate = gpd.read_file("public/NYS_Senate_Districts.geojson").rename(columns={'DISTRICT':'District'}).to_crs("EPSG:4326")
# Get table from Airtable
table = api.table(APP_KEY,TBL_KEY)

# Split your dataframe by house
df_assembly = df[df['House'] == 'Assembly']
df_senate = df[df['House'] == 'Senate']
# Retrieve all records from the table
table_dict = table.all()

# Merge DataFrames with GeoDataFrames
gdf_assembly = gdf_assembly.merge(df_assembly, on='District')
gdf_senate = gdf_senate.merge(df_senate, on='District')
gdf_assembly['Which HCMC legislation do they support?'] = gdf_assembly['Which HCMC legislation do they support?'].fillna('[]')
gdf_senate['Which HCMC legislation do they support?'] = gdf_senate['Which HCMC legislation do they support?'].fillna('[]')
# Extract fields from the records and create a DataFrame
rows = []
for row in table_dict:
rows.append(row['fields'])
df = pd.DataFrame(rows)

# Load GeoJSONs for Assembly and Senate districts
gdf_assembly = gpd.read_file("public/NYS_Assembly_Districts.geojson").to_crs("EPSG:4326")
gdf_senate = gpd.read_file("public/NYS_Senate_Districts.geojson").rename(columns={'DISTRICT':'District'}).to_crs("EPSG:4326")

gdf_assembly['Which HCMC legislation do they support?'] = gdf_assembly['Which HCMC legislation do they support?'].apply(lambda x: str(x))
gdf_senate['Which HCMC legislation do they support?'] = gdf_senate['Which HCMC legislation do they support?'].apply(lambda x: str(x))
# Split the DataFrame by house (Assembly and Senate)
df_assembly = df[df['House'] == 'Assembly']
df_senate = df[df['House'] == 'Senate']

gdf_senate = gdf_senate.rename(columns = {'Which HCMC legislation do they support?':'HCMC support'})
gdf_assembly = gdf_assembly.rename(columns = {'Which HCMC legislation do they support?':'HCMC support'})
# Merge DataFrames with GeoDataFrames based on district
gdf_assembly = gdf_assembly.merge(df_assembly, on='District')
gdf_senate = gdf_senate.merge(df_senate, on='District')

# Export the new GeoJSONs
gdf_assembly.to_file('public/assembly.geo.json', driver='GeoJSON')
gdf_senate.to_file('public/senate.geo.json', driver='GeoJSON')
# Fill missing values in the 'Which HCMC legislation do they support?' column with empty lists
gdf_assembly['Which HCMC legislation do they support?'] = gdf_assembly['Which HCMC legislation do they support?'].fillna('[]')
gdf_senate['Which HCMC legislation do they support?'] = gdf_senate['Which HCMC legislation do they support?'].fillna('[]')

# Convert the 'Which HCMC legislation do they support?' column to string type
gdf_assembly['Which HCMC legislation do they support?'] = gdf_assembly['Which HCMC legislation do they support?'].apply(lambda x: str(x))
gdf_senate['Which HCMC legislation do they support?'] = gdf_senate['Which HCMC legislation do they support?'].apply(lambda x: str(x))

# Rename columns for clarity
gdf_senate = gdf_senate.rename(columns = {'Which HCMC legislation do they support?':'HCMC support'})
gdf_assembly = gdf_assembly.rename(columns = {'Which HCMC legislation do they support?':'HCMC support'})

# Export the new GeoJSONs for Assembly and Senate districts
gdf_assembly.to_file('public/assembly.geo.json', driver='GeoJSON')
gdf_senate.to_file('public/senate.geo.json', driver='GeoJSON')

if __name__ == '__main__':
API_KEY = os.environ['LEGISLATIVE_SUPPORT']
generate_legislative_support_geojson(API_KEY, 'appD3YhFHjmqJKtZ6', 'tblgyOlrTfYRaodyb')
Loading

0 comments on commit 79fb662

Please sign in to comment.