Skip to content

Commit

Permalink
Fixed nested repository issue and updated capstone project files
Browse files Browse the repository at this point in the history
  • Loading branch information
cgeraghty1 committed Dec 9, 2024
1 parent bcd247e commit ea6944b
Show file tree
Hide file tree
Showing 17 changed files with 678 additions and 168 deletions.
Binary file modified .DS_Store
Binary file not shown.
17 changes: 17 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Use the official Python image
FROM python:3.9-slim

# Set the working directory in the container
WORKDIR /app

# Copy the current directory contents to the container
COPY . /app

# Install Python dependencies
RUN pip install --no-cache-dir dash plotly pandas

# Expose the port that the Dash app runs on
EXPOSE 8080

# Run the application
CMD ["python", "fisher_dash_app.py"]
Empty file added app.py
Empty file.
1 change: 1 addition & 0 deletions capstone
Submodule capstone added at bcd247
3 changes: 3 additions & 0 deletions config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[server]
enableCORS = false
enableWebsocketCompression = false
35 changes: 5 additions & 30 deletions fisher.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,38 +18,13 @@ <h1>Fisher Doubles Down</h1>
<p>
After World War II, the world declared, “never again.” Racial pseudoscience and the atrocities it justified faced universal condemnation. Yet, categorization itself persisted. Statistical methods advanced, but their application to groups of people continued to legitimize harmful hierarchies.
</p>
<p>
Ronald Fisher, a pioneer of modern statistics, carried the torch of eugenics from Francis Galton and Karl Pearson, both of whom laid the groundwork for applying statistical methods to human populations. Fisher’s contributions to statistics are immense: his work on analysis of variance (ANOVA), maximum likelihood estimation, and the design of experiments revolutionized mathematics, genetics, and scientific research. Yet, Fisher also believed deeply in eugenics, insisting that statistical tools could objectively determine which groups were "fit" to thrive. For Fisher, subjective judgments about "inferior" and "superior" populations became "scientific" through the application of mathematical methods.
</p>
<p>
Rather than abandoning eugenic thinking after the war, Fisher doubled down—arguing that the Earth’s finite resources required humanity to make hard choices. He claimed that statistical tools could help identify which populations contributed to sustainability and which were burdens. This rationalization gave his worldview a veneer of scientific legitimacy, even as it concealed its subjective roots.
</p>
</section>

<!-- Embed Fisher Visualization -->
<section id="ethnic-visualization">
<p>
Step into Fisher’s mindset: Adjust the weights assigned to variables like IQ, moral character, and crime statistics to explore how hierarchies might emerge.
</p>
<ul>
<li>Click on the variable names at the top of the visualization to include or exclude them from the analysis.</li>
<li>Adjust the sliders to assign weights to each variable. Observe how changing these weights shifts the bar chart and alters the perceived rankings of groups.</li>
<li>Reflect on the narratives created by your adjustments. Which groups appear to "succeed" under certain weightings? Which are marginalized? How does this depend on the values embedded in the variables?</li>
</ul>
<iframe
src="https://colingeraghty.pythonanywhere.com/fisher_weight1"
title="Fisher Visualization"
width="100%"
height="600px"
style="border: none;">
</iframe>
</section>

<!-- Conclusion -->
<section id="conclusion">
<p>
These exercises reveal how statistical tools, designed to understand the world, can easily divide it. From Fisher’s justification of resource allocation to today’s efforts to measure societal progress, the ability to assign weights and create hierarchies reflects subjective values rather than objective truths.
</p>
<!-- Fisher Visualization -->
<section id="fisher-visualization">
<p>Adjust the weights assigned to variables like IQ, moral character, and crime statistics to explore how hierarchies might emerge.</p>
<!-- Embed the Dash app -->
<iframe src="https://fisher-statistical-app-o6a2yfdseq-uc.a.run.app" title="Fisher Statistical Visualization" width="100%"height="600" style="border: none;"></iframe>
</section>
</div>

Expand Down
142 changes: 142 additions & 0 deletions fisher_dash_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
import pandas as pd

# Initialize Dash app
app = dash.Dash(__name__)
app.title = "Fisher Statistical Analysis Visualization"

# Data for visualization
fisher_data = pd.DataFrame({
"Group": ["White", "Black", "Asian", "Hispanic", "Other"],
"IQ": [100, 108, 105, 102, 98],
"Moral Character": [95, 85, 90, 80, 85],
"Violent Crime": [30, 35, 25, 40, 45],
"Income": [75, 45, 70, 50, 55],
"Reproduction Rate": [48, 55, 47, 60, 52]
})

# App layout
app.layout = html.Div(style={"font-family": "Avenir", "padding": "10px", "max-width": "1000px", "margin": "0 auto", "font-size": "0.95em"}, children=[
# Clickable variable titles for toggling visibility
html.Div(
style={"display": "flex", "justify-content": "center", "gap": "8px", "margin-bottom": "10px"},
children=[
html.Div("IQ", id="toggle-iq", style={"color": "#636EFA", "font-weight": "bold", "cursor": "pointer"}),
html.Div("Moral Character", id="toggle-moral", style={"color": "#EF553B", "font-weight": "bold", "cursor": "pointer"}),
html.Div("Violent Crime", id="toggle-crime", style={"color": "#00CC96", "font-weight": "bold", "cursor": "pointer"}),
html.Div("Income", id="toggle-income", style={"color": "#AB63FA", "font-weight": "bold", "cursor": "pointer"}),
html.Div("Reproduction Rate", id="toggle-reproduction", style={"color": "#FFA15A", "font-weight": "bold", "cursor": "pointer"})
]
),

# Bar Chart
dcc.Graph(id="fisher-chart", style={"width": "100%", "height": "400px", "border": "none"}),

# Sliders with corresponding value display
html.Div(
style={"display": "flex", "justify-content": "space-around", "align-items": "center", "margin-top": "10px"},
children=[
html.Div([
html.Label("IQ", style={"font-weight": "bold", "font-size": "0.85em", "text-align": "center"}),
dcc.Slider(
id="weight-iq",
min=0,
max=5,
step=0.1,
value=1,
marks={i: str(round(i, 1)) for i in range(6)}
),
html.Div(id="weight-iq-value", style={"text-align": "center", "font-size": "0.85em", "margin-top": "-10px"})
], style={"width": "18%"}),
html.Div([
html.Label("Moral Character", style={"font-weight": "bold", "font-size": "0.85em", "text-align": "center"}),
dcc.Slider(
id="weight-moral",
min=0,
max=5,
step=0.1,
value=1,
marks={i: str(round(i, 1)) for i in range(6)}
),
html.Div(id="weight-moral-value", style={"text-align": "center", "font-size": "0.85em", "margin-top": "-10px"})
], style={"width": "18%"}),
html.Div([
html.Label("Violent Crime", style={"font-weight": "bold", "font-size": "0.85em", "text-align": "center"}),
dcc.Slider(
id="weight-crime",
min=0,
max=5,
step=0.1,
value=1,
marks={i: str(round(i, 1)) for i in range(6)}
),
html.Div(id="weight-crime-value", style={"text-align": "center", "font-size": "0.85em", "margin-top": "-10px"})
], style={"width": "18%"}),
html.Div([
html.Label("Income", style={"font-weight": "bold", "font-size": "0.85em", "text-align": "center"}),
dcc.Slider(
id="weight-income",
min=0,
max=5,
step=0.1,
value=1,
marks={i: str(round(i, 1)) for i in range(6)}
),
html.Div(id="weight-income-value", style={"text-align": "center", "font-size": "0.85em", "margin-top": "-10px"})
], style={"width": "18%"}),
html.Div([
html.Label("Reproduction Rate", style={"font-weight": "bold", "font-size": "0.85em", "text-align": "center"}),
dcc.Slider(
id="weight-reproduction",
min=0,
max=5,
step=0.1,
value=1,
marks={i: str(round(i, 1)) for i in range(6)}
),
html.Div(id="weight-reproduction-value", style={"text-align": "center", "font-size": "0.85em", "margin-top": "-10px"})
], style={"width": "18%"})
]
)
])

# Callback to update chart and toggle visibility
@app.callback(
Output("fisher-chart", "figure"),
[Input("weight-iq", "value"),
Input("weight-moral", "value"),
Input("weight-crime", "value"),
Input("weight-income", "value"),
Input("weight-reproduction", "value")]
)
def update_fisher_chart(weight_iq, weight_moral, weight_crime, weight_income, weight_reproduction):
weighted_data = fisher_data.copy()
weighted_data["IQ"] *= weight_iq
weighted_data["Moral Character"] *= weight_moral
weighted_data["Violent Crime"] *= weight_crime
weighted_data["Income"] *= weight_income
weighted_data["Reproduction Rate"] *= weight_reproduction

fig = go.Figure()
for col, color in zip(
["IQ", "Moral Character", "Violent Crime", "Income", "Reproduction Rate"],
["#636EFA", "#EF553B", "#00CC96", "#AB63FA", "#FFA15A"]
):
fig.add_trace(go.Bar(x=weighted_data["Group"], y=weighted_data[col], name=col, marker=dict(color=color), opacity=0.75))

fig.update_layout(
barmode="group",
plot_bgcolor="white",
font=dict(family="Avenir"),
xaxis=dict(showgrid=False, showline=True, zeroline=False, title="Group"),
yaxis=dict(showgrid=True, title="Weighted Value"),
margin=dict(l=10, r=10, t=20, b=10)
)
return fig
if __name__ == "__main__":
app.run_server(debug=True, host="0.0.0.0", port=8080)


65 changes: 65 additions & 0 deletions fisher_dash_app_1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from dash import Dash, dcc, html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
import pandas as pd

app = Dash(__name__)
app.title = "Fisher Statistical Visualization"

fisher_data = pd.DataFrame({
"Group": ["White", "Black", "Asian", "Hispanic", "Other"],
"IQ": [100, 108, 105, 102, 98],
"Moral Character": [95, 85, 90, 80, 85],
"Violent Crime": [30, 35, 25, 40, 45],
"Income": [75, 45, 70, 50, 55],
"Reproduction Rate": [48, 55, 47, 60, 52]
})

app.layout = html.Div([
html.H1("Fisher Statistical Visualization"),
html.Div([
html.Label("Select Variables:"),
dcc.Checklist(
id="variable-selector",
options=[{"label": col, "value": col} for col in fisher_data.columns[1:]],
value=fisher_data.columns[1:]
),
html.Div([
html.Label("Adjust Weights for Each Variable:"),
*[
html.Div([
html.Label(col),
dcc.Slider(id=f"{col}-weight", min=0, max=5, step=0.1, value=1)
]) for col in fisher_data.columns[1:]
]
]),
]),
dcc.Graph(id="fisher-chart")
])

@app.callback(
Output("fisher-chart", "figure"),
[
Input("variable-selector", "value"),
*[Input(f"{col}-weight", "value") for col in fisher_data.columns[1:]]
]
)
def update_chart(variables, *weights):
selected_data = fisher_data[["Group"] + variables].copy()
for i, col in enumerate(variables):
selected_data[col] *= weights[i]

fig = go.Figure()
for col in variables:
fig.add_trace(go.Bar(x=selected_data["Group"], y=selected_data[col], name=col))

fig.update_layout(
barmode="group",
plot_bgcolor="white",
xaxis=dict(title="Group"),
yaxis=dict(title="Weighted Values")
)
return fig

if __name__ == "__main__":
app.run_server(debug=True, host="0.0.0.0", port=8080)
6 changes: 6 additions & 0 deletions fisher_statistical_Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM python:3.9-slim
WORKDIR /app
COPY . /app
RUN pip install --no-cache-dir dash pandas plotly
EXPOSE 8080
CMD ["python", "fisher_statistical_app.py"]
58 changes: 58 additions & 0 deletions fisher_statistical_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
import pandas as pd

app = dash.Dash(__name__)
app.title = "Fisher Statistical Visualization"

fisher_data = pd.DataFrame({
"Group": ["White", "Black", "Asian", "Hispanic", "Other"],
"IQ": [100, 108, 105, 102, 98],
"Moral Character": [95, 85, 90, 80, 85],
"Violent Crime": [30, 35, 25, 40, 45],
"Income": [75, 45, 70, 50, 55],
"Reproduction Rate": [48, 55, 47, 60, 52]
})

app.layout = html.Div([
html.H1("Fisher Statistical Visualization"),
dcc.Graph(id="stat-chart"),
html.Div([
html.Label("Adjust Weights:"),
dcc.Slider(id="weight-iq", min=0, max=5, value=1, marks={i: str(i) for i in range(6)}),
dcc.Slider(id="weight-moral", min=0, max=5, value=1, marks={i: str(i) for i in range(6)}),
dcc.Slider(id="weight-crime", min=0, max=5, value=1, marks={i: str(i) for i in range(6)}),
dcc.Slider(id="weight-income", min=0, max=5, value=1, marks={i: str(i) for i in range(6)}),
dcc.Slider(id="weight-reproduction", min=0, max=5, value=1, marks={i: str(i) for i in range(6)})
])
])

@app.callback(
Output("stat-chart", "figure"),
[Input("weight-iq", "value"),
Input("weight-moral", "value"),
Input("weight-crime", "value"),
Input("weight-income", "value"),
Input("weight-reproduction", "value")]
)
def update_chart(weight_iq, weight_moral, weight_crime, weight_income, weight_reproduction):
weighted_data = fisher_data.copy()
weighted_data["IQ"] *= weight_iq
weighted_data["Moral Character"] *= weight_moral
weighted_data["Violent Crime"] *= weight_crime
weighted_data["Income"] *= weight_income
weighted_data["Reproduction Rate"] *= weight_reproduction

fig = go.Figure()
for col, color in zip(
["IQ", "Moral Character", "Violent Crime", "Income", "Reproduction Rate"],
["#636EFA", "#EF553B", "#00CC96", "#AB63FA", "#FFA15A"]
):
fig.add_trace(go.Bar(x=weighted_data["Group"], y=weighted_data[col], name=col, marker=dict(color=color)))
fig.update_layout(barmode="group", title="Weighted Statistical Values")
return fig

if __name__ == "__main__":
app.run_server(debug=True, host="0.0.0.0", port=8080)
Loading

0 comments on commit ea6944b

Please sign in to comment.