File size: 7,162 Bytes
7f53bc2
 
4c8b4d5
1f2416b
fc8894f
346db32
1f2416b
3f8e536
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b5edb7c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ad12a02
b5edb7c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3f8e536
b5edb7c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ad12a02
 
 
 
 
 
 
 
 
 
 
810460f
04cace3
ad12a02
3f8e536
 
 
 
1f63ae9
3f8e536
1f63ae9
ad12a02
3f8e536
 
 
ad12a02
3f8e536
1f63ae9
ad12a02
3f8e536
b5edb7c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67a935e
45f8a50
 
 
 
 
67a935e
014b8a3
45f8a50
d24d4b9
45f8a50
1f2416b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
import streamlit as st
import json
import pandas as pd
import requests
import os
import math

def get_urgency_score(user, shelter):
    if user == "Today": 
        if shelter == "Immdiaite": return 0
        if shelter == "High": return 0.75
        if shelter == "Moderate": return 1
    elif user == "In the next few days":
        if shelter == "Immdiaite": return 0.25
        if shelter == "High": return 0
        if shelter == "Moderate": return 0.75
    elif user == "In a week or so":
        if shelter == "Immdiaite": return 0.75
        if shelter == "High": return 0.25
        if shelter == "Moderate": return 0

def get_duration_score(user, shelter):
    if user == "Overnight":
        if shelter == "Overnight": return 0
        if shelter == "Temporary": return 0.5
        if shelter == "Transitional": return 0.75
        if shelter == "Long-Term": return 1
    elif user == "A month or less":
        if shelter == "Overnight": return 0.5
        if shelter == "Temporary": return 0
        if shelter == "Transitional": return 0.25
        if shelter == "Long-Term": return 0.75
    elif user == "A couple of months":
        if shelter == "Overnight": return 0.75
        if shelter == "Temporary": return 0.25
        if shelter == "Transitional": return 0
        if shelter == "Long-Term": return 0.5
    elif user == "A year or more":
        if shelter == "Overnight": return 1
        if shelter == "Temporary": return 0.75
        if shelter == "Transitional": return 0.5
        if shelter == "Long-Term": return 0

def get_zip_codes(city, state):
    url = f'http://api.zippopotam.us/us/{state}/{city}'
    response = requests.get(url)
    if response.status_code == 200:
        data = response.json()
        return [place['post code'] for place in data['places']]
    else:
        return []

def get_coordinates(address: str, api_key: str) -> list:
    """
    Get the coordinates (latitude and longitude) of an address using the OpenWeather Geocoding API.

    Parameters:
    zipcode (str): The zipcode to geocode.
    api_key (str): Your OpenWeather API key.

    Returns:
    list: A list containing the latitude and longitude of the address.
    """
    return [0,0]

def haversine(lat1, lon1, lat2, lon2):
    R = 6371  # Earth radius in kilometers. Use 3956 for miles.
    dlat = math.radians(lat2 - lat1)
    dlon = math.radians(lon2 - lon1)
    a = math.sin(dlat / 2) ** 2 + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.sin(dlon / 2) ** 2
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
    distance = R * c
    return distance

# Function to handle form submission
@st.experimental_dialog("Fill out the form")
def form_dialog():
    city_zipcodes = {
        "San Francisco": get_zip_codes("San Francisco", "CA"),
        "Oakland": get_zip_codes("Oakland", "CA"),
        "Berkeley": get_zip_codes("Berkeley", "CA")
    }
    
    city = st.selectbox("City", list(city_zipcodes.keys()))
    zipcode = st.selectbox("Zipcode", ['Unsure'] + city_zipcodes[city])
        
    sex = st.radio("Sex", ["Male", "Female", "Other"])
    lgbtq = st.radio("Do you identify as LGBTQ+ (some shelters serve this community specifically)", ["No", "Yes"])
    domestic_violence = st.radio("Have you experienced domestic violence (some shelters serve these individuals specifically", ["No", "Yes"])
    
    urgency = st.radio("How quickly do you need help?", ("Today", "In the next few days", "In a week or more"))
    duration = st.radio("How long do you need a place to stay?", ("Overnight", "A month or less", "A couple of months", "A year or more"))
    needs = st.text_area("Optional - Needs (tell us what you need and how we can help)", value="")

    if st.button("Submit"):
        data = {
            "City": city,
            "Zip Code": zipcode,
            "Sex": sex,
            "LGBTQ": lgbtq,
            "Domestic Violence": domestic_violence,
            "Urgency": urgency,
            "Duration": duration,
            "Needs": needs
        }

        with open('data.json', 'w') as f:
            json.dump(data, f)

        st.session_state.form_submitted = True
        st.session_state.data = data
        st.rerun()

# Initialize session state
if 'form_submitted' not in st.session_state:
    st.session_state.form_submitted = False

if 'shelter_index' not in st.session_state:
    st.session_state.shelter_index = 0

# Page config
st.set_page_config(
    page_title="ShelterSearch",
    layout="wide",
)

st.title("ShelterSearch")

if not st.session_state.form_submitted:
    if st.button("Open Form"):
        form_dialog()
else:
    with open('data.json', 'r') as f:
        data = json.load(f)
    st.json(data)

    shelters = pd.read_csv("database.csv")

    # filter city
    shelters = shelters[(shelters['City'] == data['City'])]
    
    # filter sex
    shelters = shelters[(shelters['Sex'] == data['Sex']) | (shelters['Sex'] == 'All')]

    # filter lgbtq
    if data['LGBTQ'] == 'No':
        shelters = shelters[(shelters['LGBTQ'] == "No")]

    # filter domestic violence
    if data['Domestic Violence'] == "No":
        shelters = shelters[(shelters['Domestic Violence'] == "No")]

    # calculate distances between zipcodes
    geocoding_api_key = os.environ['OpenWeather_API_KEY']
    
    shelters_coordinates = shelters.apply(lambda row: get_coordinates(row['Zip Code'], geocoding_api_key), axis=1).tolist()
    user_coordinates = get_coordinates(data['Zip Code'], geocoding_api_key)

    distances = []
    for coordinates in shelters_coordinates:
         distances.append(haversine(coordinates[0], coordinates[1], user_coordinates[0], user_coordinates[1]))

    max = max(distances) if (max(distances) != 0) else 1
    shelters['zipcode_score'] = [d / max for d in distances]

    # get urgency scores 
    urgency_scores = []
    for shelter in shelters:
        urgency_scores.append(get_urgency_score(data['Urgency'], shelter['Urgency']))

    shelters['urgency_score'] = urgency_scores

    # duration
    duration_scores = []
    for shelter in shelters:
        duration_scores.append(get_duration_score(data['Duration'], shelter['Duration']))

    shelters['duration_score'] = urgency_scores

    # services
    
        
    st.table(shelters)
        
    shelters = [
        {"title": "Shelter 1", "description": "This is the 1st shelter",},
        {"title": "Shelter 2", "description": "This is the 2nd shelter.",},
        {"title": "Shelter 3", "description": "This is the 3rd shelter.",}
    ]

    # Display the current shelter information
    shelter = shelters[st.session_state.shelter_index]
    st.write(shelter["description"])
    
    # Create two columns
    col1, col2 = st.columns([1,1])
    
    # Add buttons to each column
    with col1:
        if st.button("Previous"):
            if st.session_state.shelter_index > 0:
                st.session_state.shelter_index -= 1
                st.experimental_rerun()
    
    with col2:
        if st.button("Next"):
            if st.session_state.shelter_index < len(shelters) - 1:
                st.session_state.shelter_index += 1
                st.experimental_rerun()