Skip to content

Commit

Permalink
Changes to be committed:
Browse files Browse the repository at this point in the history
	new file:   .DS_Store
	new file:   .ignore/ContributionsList (3).xls
	new file:   .ignore/ContributionsList (4).xls
	new file:   .ignore/ContributionsList.xls
	new file:   .ignore/ContributionsList10.xls
	new file:   .ignore/ContributionsList11.xls
	new file:   .ignore/ContributionsList12.xls
	new file:   .ignore/ContributionsList13.xls
	new file:   .ignore/ContributionsList14.xls
	new file:   .ignore/ContributionsList15.xls
	new file:   .ignore/ContributionsList16.xls
	new file:   .ignore/ContributionsList17.xls
	new file:   .ignore/ContributionsList6.xls
	new file:   .ignore/ContributionsList7.xls
	new file:   .ignore/ContributionsList8.xls
	new file:   .ignore/ContributionsList9.xls
	new file:   .ignore/Untitled.ipynb
	new file:   .ignore/developercrossreference.xls
	new file:   .ipynb_checkpoints/Untitled-checkpoint.ipynb
	new file:   Home.py
	new file:   __pycache__/db_load.cpython-39.pyc
	new file:   __pycache__/functions.cpython-39.pyc
	new file:   __pycache__/sqlite.cpython-39.pyc
	new file:   combined.jpeg
	new file:   contributions.db
	new file:   modules/.DS_Store
	new file:   modules/__pycache__/db_load.cpython-39.pyc
	new file:   modules/__pycache__/functions.cpython-39.pyc
	new file:   modules/db_load.py
	new file:   modules/functions.py
	new file:   pages/1_Overview.py
	new file:   pages/2_Analysis.py
	new file:   pages/3_Figures.py
	new file:   style/style.css
  • Loading branch information
hiruyhadgu committed Apr 10, 2023
0 parents commit 1e10e5a
Show file tree
Hide file tree
Showing 34 changed files with 24,684 additions and 0 deletions.
Binary file added .DS_Store
Binary file not shown.
206 changes: 206 additions & 0 deletions .ignore/ContributionsList (3).xls

Large diffs are not rendered by default.

379 changes: 379 additions & 0 deletions .ignore/ContributionsList (4).xls

Large diffs are not rendered by default.

313 changes: 313 additions & 0 deletions .ignore/ContributionsList.xls

Large diffs are not rendered by default.

374 changes: 374 additions & 0 deletions .ignore/ContributionsList10.xls

Large diffs are not rendered by default.

384 changes: 384 additions & 0 deletions .ignore/ContributionsList11.xls

Large diffs are not rendered by default.

487 changes: 487 additions & 0 deletions .ignore/ContributionsList12.xls

Large diffs are not rendered by default.

704 changes: 704 additions & 0 deletions .ignore/ContributionsList13.xls

Large diffs are not rendered by default.

279 changes: 279 additions & 0 deletions .ignore/ContributionsList14.xls

Large diffs are not rendered by default.

7,377 changes: 7,377 additions & 0 deletions .ignore/ContributionsList15.xls

Large diffs are not rendered by default.

2,975 changes: 2,975 additions & 0 deletions .ignore/ContributionsList16.xls

Large diffs are not rendered by default.

8,142 changes: 8,142 additions & 0 deletions .ignore/ContributionsList17.xls

Large diffs are not rendered by default.

162 changes: 162 additions & 0 deletions .ignore/ContributionsList6.xls

Large diffs are not rendered by default.

303 changes: 303 additions & 0 deletions .ignore/ContributionsList7.xls

Large diffs are not rendered by default.

562 changes: 562 additions & 0 deletions .ignore/ContributionsList8.xls

Large diffs are not rendered by default.

158 changes: 158 additions & 0 deletions .ignore/ContributionsList9.xls

Large diffs are not rendered by default.

597 changes: 597 additions & 0 deletions .ignore/Untitled.ipynb

Large diffs are not rendered by default.

Binary file added .ignore/developercrossreference.xls
Binary file not shown.
677 changes: 677 additions & 0 deletions .ipynb_checkpoints/Untitled-checkpoint.ipynb

Large diffs are not rendered by default.

114 changes: 114 additions & 0 deletions Home.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import streamlit as st

st.title('Howard County Local Election Campaign Finance')
st.write(
"""
This website presents campaign finance data for Howard County candidates. It includes all
contribution data, since 2006, of all candidates who have participated in county council and
county executive races. It will be updated with new candidates over time.
This page provides a visual analysis of all-time campaign contributions for
candidates running for the County Council and County Executive.
"""
)
st.markdown("""
[Click Here](https://data.howardcountymd.gov/DataExplorer/Search.aspx?Application=CouncilMember)
to navigate to the county website to find your Councilmember then pick the **District** and **Filing Period**
to examine from the left sidebar.
""")

st.write('__________________')


st.markdown("""
The entities and individuals classified as developer contributions closely aligns with the classification
in the [No Developer Pledge](https://www.hocopledge.com/candidate-signing/). The process to identify the
entities entails establishing connections based on local groups that deal with zoning and land use, looking
at Maryland Corporate and LLC registration info, looking up reported addresses, reviewing campaign contributions
for other candidates, and public testimony and affidavit. Please use the contact form to share your thoughts on the
list and how it may be improved.
This list will be updated over time.
""")

st.header(":mailbox: Share your thoughts here.")

contact_form = """
<form action="https://formsubmit.co/[email protected]" method="POST">
<input type="hidden" name="_captcha" value="false">
<input type="text" name="name" placeholder="Your name" required>
<input type="email" name="email" placeholder="Your email" required>
<textarea name="message" placeholder="Your message here"></textarea>
<button type="submit">Send</button>
</form>
"""

st.markdown(contact_form, unsafe_allow_html=True)

# Use Local CSS File
def local_css(file_name):
with open(file_name) as f:
st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)


local_css("style/style.css")

hide_st_style = """
<style>
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
header {visibility: hidden;}
</style>
"""
st.markdown(hide_st_style, unsafe_allow_html=True)

# plot_data = st.sidebar.checkbox('Show Plots for Selected Criteria', value=True)

# if plot_data:

# plots = ['Developer Percent Contribution','Top N Contributions', 'By Filing Period']
# picked_plot = st.sidebar.selectbox('Pick a Plot', plots)
# #st.write(f'{len(picked_plot)}')
# if picked_plot == plots[0]:
# if developer:
# try:
# # st.write('Select the "Display Developer Contributions" checkbox')
# data_set=['Developer Donations', 'Remaining']
# percent_dev = df_master[mask]['Contribution Amount'].sum()/df_master[base_mask]['Contribution Amount'].sum()
# values = [percent_dev, 1-percent_dev]
# fig = px.pie(df_master['Contribution Amount'], values=values, names=data_set)
# st.caption('Percent share of contributions from developers. Note that some candidates\
# participate in public financing or did not file for the selected criteria.')
# display = st.plotly_chart(fig)
# except ValueError:
# st.markdown('### Data does not exist for selected criteria.')
# st.code('Try a different filing period.')
# else:
# st.markdown('Select the **Display Developer Contributions Only** checkbox')
# elif picked_plot == plots[1]:
# n = st.sidebar.slider('How Many Contributions?:',
# min_value = 10,
# max_value = 40)
# try:
# table_cols = df_grouped_for_plot.reset_index().sort_values(by=['Total Contribution'], ascending = False).head(n)
# candidate_names(candidates, table_cols, 'Receiving Committee')
# fig = px.bar(table_cols, x=table_cols['Contributor Name'], y=table_cols['Total Contribution'],color=table_cols['Candidate Name'])
# display = st.plotly_chart(fig)
# except ValueError:
# st.markdown('### Data does not exist for selected criteria.')
# st.code('Try a different filing period.')
# elif picked_plot == plots[2]:
# try:
# if bar_mask:
# df_master_bar = df_master[developer_filter]
# else:
# df_master_bar = df_master

# contribution_by_filing_period = df_master_bar.groupby(['Candidate Name','Filing Period'])
# contribution_by_filing_period=contribution_by_filing_period.agg(
# TotalContribution =('Contribution Amount','sum')).reset_index()
# fig = px.bar(contribution_by_filing_period, x = contribution_by_filing_period['Filing Period'],
# y=contribution_by_filing_period['TotalContribution'],color=contribution_by_filing_period['Candidate Name'])
# display = st.plotly_chart(fig)
# except ValueError:
# st.markdown('### Data does not exist for selected criteria.')
# st.code('Try a different filing period.')
Binary file added __pycache__/db_load.cpython-39.pyc
Binary file not shown.
Binary file added __pycache__/functions.cpython-39.pyc
Binary file not shown.
Binary file added __pycache__/sqlite.cpython-39.pyc
Binary file not shown.
Binary file added combined.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added contributions.db
Binary file not shown.
Binary file added modules/.DS_Store
Binary file not shown.
Binary file added modules/__pycache__/db_load.cpython-39.pyc
Binary file not shown.
Binary file added modules/__pycache__/functions.cpython-39.pyc
Binary file not shown.
39 changes: 39 additions & 0 deletions modules/db_load.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import pandas as pd
import sqlite3 as db
import datetime as dt
import streamlit as st

conn = db.connect('contributions.db', check_same_thread=False)
c = conn.cursor()
sql_query = """SELECT name FROM sqlite_master
WHERE type='table';"""

# executing our sql query
c.execute(sql_query)

# printing all tables list
list = c.fetchall()

list.remove(('developercrossreference',))

def contributions(name):
table = pd.read_sql_query(f'select * from {name}',conn)
table['Contribution Date'] = pd.to_datetime(table['Contribution Date']).dt.date
table['Contribution Amount'] = table['Contribution Amount'].astype(float)
table = table.drop(columns='index')
return table

candidate_data_frame = {}

@st.cache_data
def load():
raw_table = pd.DataFrame()
for n in list:
raw_table = pd.concat([raw_table, contributions(n[0])])
raw_table = raw_table.reset_index().drop(columns='index')
return raw_table
@st.cache_data
def developer():
table1 = pd.read_sql_query(f'select * from developercrossreference',conn)
table1 = table1.drop(columns='index')
return table1
8 changes: 8 additions & 0 deletions modules/functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import pandas as pd


def group_by_filing_period(table, args):

group_by_filing_period = table.set_index(args).groupby(level=[i for i in range(len(args))]).sum(numeric_only=True)

return group_by_filing_period
115 changes: 115 additions & 0 deletions pages/1_Overview.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import streamlit as st
import pandas as pd
import sqlite3 as db
import plotly.express as px
import datetime as dt

st.markdown('### Fundraising data for all candidates for county council and county executive since 2006.')

conn = db.connect('contributions.db', check_same_thread=False)
sqlite_select_query = """SELECT name FROM sqlite_master WHERE type='table';"""
c = conn.cursor()
c.execute(sqlite_select_query)
records = c.fetchall()

def contributions(name):
table = pd.read_sql_query(f'select * from {name}',conn)
table['Contribution Date'] = pd.to_datetime(table['Contribution Date']).dt.date
table['Contribution Amount'] = table['Contribution Amount'].astype(float)
table = table.drop(columns='index')
return table

candidate_data_frame = {}

def load():
raw_table = pd.DataFrame()
for n in records:
if n[0] == 'developercrossreference':
continue
raw_table = pd.concat([raw_table, contributions(n[0])])
raw_table = raw_table.reset_index().drop(columns='index')
return raw_table

raw_table = load()

office_options = st.sidebar.selectbox('Office', raw_table['Office'].unique())
mask = raw_table['Office']==office_options
filtered_by_office = raw_table[mask]

district_options= st.sidebar.selectbox('Councilmanic District', filtered_by_office['Councilmanic District'].unique())
mask1 = filtered_by_office['Councilmanic District'] == district_options
filtered_by_district = filtered_by_office[mask1]


name_options = st.sidebar.selectbox('Candidate Name', filtered_by_district['Candidate Name'].unique())
mask2 = filtered_by_district['Candidate Name'] == name_options

filtered_by_name = filtered_by_district[mask2]

start_date = filtered_by_name['Contribution Date'].min()
end_date = filtered_by_name['Contribution Date'].max()
value = [start_date, end_date]

val = st.date_input(label='Date Range: ', value=value, help="The start and end date time")

try:
start_date, end_date = val
except ValueError:
st.error("You must pick a start and end date")
st.stop()

mask3 = (filtered_by_name['Contribution Date']>=val[0]) & (filtered_by_name['Contribution Date'] <=val[1])
filtered_by_date = filtered_by_name[mask3]
filtered_by_date = filtered_by_date.sort_values(['Receiving Committee','Contribution Date']).reset_index().drop(columns='index')

filing_options = filtered_by_date['Filing Period'].unique().tolist()
filing_options.insert(0, 'All Filing Periods')

select_filing_period = st.selectbox('Select Filing Period',options=filing_options)

if select_filing_period =='All Filing Periods':
filtered_by_filing_period = filtered_by_date
else:
mask4 = filtered_by_date['Filing Period']==select_filing_period
filtered_by_filing_period = filtered_by_date[mask4]

# Filter the dataframe based on the selected date range and categories

candidate_options = filtered_by_filing_period['Receiving Committee'].unique()
select_candidates = st.multiselect('Select Campaign Committees',options=candidate_options, default=candidate_options)
mask5 = filtered_by_date['Receiving Committee'].isin(select_candidates)

filtered_by_candidate = filtered_by_filing_period[mask5]
col1, col2 = st.columns(2)

with col1:
st.metric('Total Number of Contributions:',filtered_by_candidate['Contribution Amount'].count())

with col2:
st.metric('Total Money Raised:','${:,.2f}'.format(filtered_by_candidate['Contribution Amount'].sum()))


excluded_row = ['Receiving Committee', 'Filing Period','Office','Fundtype','Candidate Name', 'Councilmanic District']
# Display the filtered dataframe
st.write(filtered_by_candidate.loc[:,~filtered_by_candidate.columns.isin(excluded_row)])

st.markdown("""
<style>
div[data-testid="metric-container"] {
background-color: rgba(28, 131, 225, 0.1);
border: 1px solid rgba(28, 131, 225, 0.1);
padding: 5% 5% 5% 10%;
border-radius: 5px;
color: rgb(30, 103, 119);
overflow-wrap: break-word;
}
/* breakline for metric text */
div[data-testid="metric-container"] > label[data-testid="stMetricLabel"] > div {
overflow-wrap: break-word;
white-space: break-spaces;
color: red; font-size: 200% !important;
}
</style>
"""
, unsafe_allow_html=True)
Loading

0 comments on commit 1e10e5a

Please sign in to comment.