├── Procfile ├── imgs ├── Itamar.png ├── Romulo.jpg └── itamar.JPG ├── requirements.txt ├── setup.sh ├── README.md ├── apoiasus_helper.py └── apoiasusMAP.ipynb /Procfile: -------------------------------------------------------------------------------- 1 | web: sh setup.sh && streamlit run apoiasus_helper.py 2 | -------------------------------------------------------------------------------- /imgs/Itamar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ItamarRocha/apoiasus/master/imgs/Itamar.png -------------------------------------------------------------------------------- /imgs/Romulo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ItamarRocha/apoiasus/master/imgs/Romulo.jpg -------------------------------------------------------------------------------- /imgs/itamar.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ItamarRocha/apoiasus/master/imgs/itamar.JPG -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pandas 2 | unidecode 3 | streamlit 4 | numpy 5 | geopy 6 | lxml 7 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | mkdir -p ~/.streamlit/ 2 | echo "[general] 3 | email = \"itamardprf@gmail.com\" 4 | " > ~/.streamlit/credentials.toml 5 | echo "[server] 6 | headless = true 7 | port = $PORT 8 | enableCORS = false 9 | " > ~/.streamlit/config.toml 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # apoiasus 2 | 3 | ## up and running locally 4 | 5 | ```shell 6 | streamlit run map_filter.py 7 | ``` 8 | 9 | ## Acess application 10 | 11 | > https://mysterious-chamber-69490.herokuapp.com/ 12 | 13 | ## Heroku deploy 14 | 15 | https://towardsdatascience.com/deploy-streamlit-on-heroku-9c87798d2088 16 | 17 | > change the setup.sh following the comment 18 | -------------------------------------------------------------------------------- /apoiasus_helper.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import unidecode 3 | import streamlit as st 4 | import numpy as np 5 | from geopy.distance import geodesic 6 | 7 | def normalize_city_name(df, column): 8 | df[column] = df[column].str.lower().str.replace("-"," ") 9 | df[column] = df[column].apply(lambda x : unidecode.unidecode(x)) 10 | return df 11 | 12 | @st.cache 13 | def get_data(): 14 | url ='https://sgtes.unasus.gov.br/apoiasus/login/listadevagas.asp' 15 | apoiasus_data = pd.read_html(url)[0] # Returns DataFrame of all tables on page 16 | apoiasus_data = normalize_city_name(apoiasus_data, "Município") 17 | 18 | cidades = pd.read_csv('https://github.com/romulokps/apoiasus/raw/master/populacaoBR2.csv',dtype={"ibgeID": str}, index_col=0) 19 | cidades = normalize_city_name(cidades, "cidade") 20 | 21 | df = pd.merge(apoiasus_data, cidades, left_on = ['UF','Município'], right_on = ['estado','cidade'], how="left") 22 | 23 | df.loc[81, ["ibgeID", "cidade", "estado", "pop"]] = cidades.loc[2341] 24 | 25 | lat_long = pd.read_csv("https://github.com/kelvins/Municipios-Brasileiros/raw/main/csv/municipios.csv", dtype={"codigo_ibge": str}) 26 | lat_long.drop(columns = ["nome", "capital", "codigo_uf"], inplace = True) 27 | 28 | df = pd.merge(df, lat_long, left_on=["ibgeID"], right_on=["codigo_ibge"], how="inner") 29 | df.drop(columns = ["codigo_ibge", "cidade", "estado", "pop"], inplace=True) 30 | 31 | search_df = pd.merge(cidades, lat_long, left_on="ibgeID", right_on="codigo_ibge").drop(columns = ["pop", "codigo_ibge"]) 32 | 33 | return df, search_df 34 | 35 | def calc_distances(df, chosen_city): 36 | distances = {} 37 | chosen_city_coordinates = chosen_city[0][-2:] # pega as coordenadas da cidade escolhida 38 | for i in range(len(df)): 39 | ibge_id = df.loc[i]["ibgeID"] # usa o IBGE ID como chave no dicionário pra facilitar o merge depois 40 | city_coordinates = df.loc[i][-2:].values 41 | distances[ibge_id] = geodesic(city_coordinates, chosen_city_coordinates).km 42 | return distances 43 | 44 | data, search_df = get_data() 45 | 46 | st.title("Helper Brasil Conta Comigo") 47 | st.sidebar.title("Filtros") 48 | st.markdown("Essa é uma aplicação em desenvolvimento com o intuito de ajudar você a achar a cidade mais próxima com vagas no programa Brasil Conta Comigo. Aqui os dados estão sempre atualizados com os do [ApoiASUS](https://sgtes.unasus.gov.br/apoiasus/login/listadevagas.asp)") 49 | st.sidebar.markdown("Aqui você pode filtrar melhor a distância máxima de sua cidade e sua profissão de interesse") 50 | 51 | st.sidebar.title("Configurações") 52 | 53 | # Pegando a distância aproximada entre as cidades 54 | city = st.sidebar.text_input('Digite o nome da sua cidade') 55 | state = st.sidebar.text_input('Digite a sigla de seu estado') 56 | 57 | if city and state: 58 | city = city.lower() 59 | city = unidecode.unidecode(city) 60 | 61 | # retriving data from the chosen city 62 | res = search_df.loc[(search_df["estado"].str.lower() == state.lower()) & (search_df["cidade"] == city)].values 63 | 64 | 65 | # getting distance from each city to the city the user chose 66 | dists = calc_distances(data, res) 67 | dists_dataframe = pd.DataFrame(dists, index=[0]).T.reset_index() 68 | dists_dataframe.columns = ["ibgeID", "distancia"] 69 | 70 | # merging distances 71 | data = pd.merge(data, dists_dataframe, left_on = "ibgeID", right_on="ibgeID") 72 | 73 | # sorting values by distance 74 | data = data.sort_values(by="distancia") 75 | 76 | # Escolhendo a profissão 77 | select = st.sidebar.selectbox('Escolha a profissão de interesse', ["Medicina", "Enfermagem", "Farmácia", "Fisioterapia"]) 78 | data = data.loc[data[select] > 0] 79 | 80 | # Escolhendo a distancia máxima 81 | if city and state: 82 | chosen_dist = st.sidebar.slider("Selecione a distância máxima", int(data.distancia.min()), int(data.distancia.max()), 200) 83 | if chosen_dist: 84 | data = data.loc[data.distancia <= chosen_dist] 85 | 86 | # longitude , latitude 87 | st.title("Mapa com resultados") 88 | st.map(data) 89 | 90 | # Mostrando o dataframe 91 | if st.sidebar.checkbox("Mostrar resultados"): 92 | st.title("Tabela com resultados") 93 | st.write(data[["UF", "Município", select, "ibgeID", "distancia"]]) 94 | 95 | st.title("Autores") 96 | st.image(["imgs/Itamar.png", "imgs/Romulo.jpg"], caption=["Itamar Rocha, estudante de Engenharia da computação - UFPB", "Rômulo Kunrath, estudante de Medicina - UFPB"], width=300) 97 | 98 | st.title("Contato") 99 | st.markdown("Itamar : [linkedin](https://www.linkedin.com/in/itamarrocha/) , [Github](https://github.com/ItamarRocha/)") 100 | st.markdown("Rômulo : [Email](mailto:romulokps@gmail.com) , [Github](https://github.com/romulokps)") -------------------------------------------------------------------------------- /apoiasusMAP.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "apoiasusMAP.ipynb", 7 | "provenance": [], 8 | "authorship_tag": "ABX9TyMpuK4U82fetI01bni3IQEj", 9 | "include_colab_link": true 10 | }, 11 | "kernelspec": { 12 | "name": "python3", 13 | "display_name": "Python 3" 14 | } 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "markdown", 19 | "metadata": { 20 | "id": "view-in-github", 21 | "colab_type": "text" 22 | }, 23 | "source": [ 24 | "\"Open" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "metadata": { 30 | "id": "Z95eAEDte9vf", 31 | "colab_type": "code", 32 | "colab": {} 33 | }, 34 | "source": [ 35 | "#conectar com github\n", 36 | "#site = https://sgtes.unasus.gov.br/apoiasus/login/listadevagas.asp\n", 37 | "path = 'https://sgtes.unasus.gov.br/apoiasus/login/listadevagas.asp'" 38 | ], 39 | "execution_count": null, 40 | "outputs": [] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "metadata": { 45 | "id": "s_po21ewfweQ", 46 | "colab_type": "code", 47 | "colab": {} 48 | }, 49 | "source": [ 50 | "import pandas as pd\n", 51 | "import numpy as np" 52 | ], 53 | "execution_count": null, 54 | "outputs": [] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "metadata": { 59 | "id": "Naq8SY9shH-N", 60 | "colab_type": "code", 61 | "colab": {} 62 | }, 63 | "source": [ 64 | "#importa dados\n", 65 | "import pandas as pd\n", 66 | "url ='https://sgtes.unasus.gov.br/apoiasus/login/listadevagas.asp'\n", 67 | "tables = pd.read_html(url) # Returns list of all tables on page\n", 68 | "tb = tables[0] # Select table of interest\n", 69 | "\n", 70 | "#importa cidades\n", 71 | "cidades = pd.read_csv('https://github.com/romulokps/apoiasus/raw/master/populacaoBR2.csv')\n" 72 | ], 73 | "execution_count": 37, 74 | "outputs": [] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "metadata": { 79 | "id": "SFczx2gUrO-p", 80 | "colab_type": "code", 81 | "colab": { 82 | "base_uri": "https://localhost:8080/", 83 | "height": 419 84 | }, 85 | "outputId": "3c325d16-6130-4e4d-8df6-7c40b8fda1bb" 86 | }, 87 | "source": [ 88 | "df = pd.merge(tb, cidades, left_on = ['UF','Município'], right_on = ['estado','cidade'])\n", 89 | "df" 90 | ], 91 | "execution_count": 38, 92 | "outputs": [ 93 | { 94 | "output_type": "execute_result", 95 | "data": { 96 | "text/html": [ 97 | "
\n", 98 | "\n", 111 | "\n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | " \n", 178 | " \n", 179 | " \n", 180 | " \n", 181 | " \n", 182 | " \n", 183 | " \n", 184 | " \n", 185 | " \n", 186 | " \n", 187 | " \n", 188 | " \n", 189 | " \n", 190 | " \n", 191 | " \n", 192 | " \n", 193 | " \n", 194 | " \n", 195 | " \n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | " \n", 202 | " \n", 203 | " \n", 204 | " \n", 205 | " \n", 206 | " \n", 207 | " \n", 208 | " \n", 209 | " \n", 210 | " \n", 211 | " \n", 212 | " \n", 213 | " \n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | " \n", 266 | " \n", 267 | " \n", 268 | " \n", 269 | " \n", 270 | " \n", 271 | " \n", 272 | " \n", 273 | " \n", 274 | " \n", 275 | " \n", 276 | " \n", 277 | " \n", 278 | " \n", 279 | " \n", 280 | " \n", 281 | " \n", 282 | " \n", 283 | " \n", 284 | "
UFMunicípioMedicinaEnfermagemFarmáciaFisioterapiaUnnamed: 0ibgeIDcidadeestadopop
0ACMâncio Lima2800631200336Mâncio LimaAC18977
1ALSantana do Ipanema200017372708006Santana do IpanemaAL47654
2BAAbaré300018302900207AbaréBA20086
3BAAmargosa042018392901007AmargosaBA37241
4BABarreiras030618672903201BarreirasBA155439
....................................
324SPSão Carlos200038153548906São CarlosSP251983
325SPSão Paulo201038313550308São PauloSP12252023
326SPTabapuã300038553552601TabapuãSP12407
327SPTaubaté1460038733554102TaubatéSP314924
328SPTupi Paulista300038863555109Tupi PaulistaSP15495
\n", 285 | "

329 rows × 11 columns

\n", 286 | "
" 287 | ], 288 | "text/plain": [ 289 | " UF Município Medicina ... cidade estado pop\n", 290 | "0 AC Mâncio Lima 2 ... Mâncio Lima AC 18977\n", 291 | "1 AL Santana do Ipanema 2 ... Santana do Ipanema AL 47654\n", 292 | "2 BA Abaré 3 ... Abaré BA 20086\n", 293 | "3 BA Amargosa 0 ... Amargosa BA 37241\n", 294 | "4 BA Barreiras 0 ... Barreiras BA 155439\n", 295 | ".. .. ... ... ... ... ... ...\n", 296 | "324 SP São Carlos 2 ... São Carlos SP 251983\n", 297 | "325 SP São Paulo 2 ... São Paulo SP 12252023\n", 298 | "326 SP Tabapuã 3 ... Tabapuã SP 12407\n", 299 | "327 SP Taubaté 14 ... Taubaté SP 314924\n", 300 | "328 SP Tupi Paulista 3 ... Tupi Paulista SP 15495\n", 301 | "\n", 302 | "[329 rows x 11 columns]" 303 | ] 304 | }, 305 | "metadata": { 306 | "tags": [] 307 | }, 308 | "execution_count": 38 309 | } 310 | ] 311 | }, 312 | { 313 | "cell_type": "code", 314 | "metadata": { 315 | "id": "yNtTcfN6yF3B", 316 | "colab_type": "code", 317 | "colab": { 318 | "base_uri": "https://localhost:8080/", 319 | "height": 255 320 | }, 321 | "outputId": "3581b32a-7b9e-40dd-fcc5-5a30c428f0bd" 322 | }, 323 | "source": [ 324 | "" 325 | ], 326 | "execution_count": 40, 327 | "outputs": [ 328 | { 329 | "output_type": "stream", 330 | "text": [ 331 | " UF Município Medicina ... cidade estado pop\n", 332 | "0 AC Mâncio Lima 2 ... Mâncio Lima AC 18977\n", 333 | "1 AL Santana do Ipanema 2 ... Santana do Ipanema AL 47654\n", 334 | "2 BA Abaré 3 ... Abaré BA 20086\n", 335 | "3 BA Amargosa 0 ... Amargosa BA 37241\n", 336 | "4 BA Barreiras 0 ... Barreiras BA 155439\n", 337 | ".. .. ... ... ... ... ... ...\n", 338 | "324 SP São Carlos 2 ... São Carlos SP 251983\n", 339 | "325 SP São Paulo 2 ... São Paulo SP 12252023\n", 340 | "326 SP Tabapuã 3 ... Tabapuã SP 12407\n", 341 | "327 SP Taubaté 14 ... Taubaté SP 314924\n", 342 | "328 SP Tupi Paulista 3 ... Tupi Paulista SP 15495\n", 343 | "\n", 344 | "[329 rows x 11 columns]\n" 345 | ], 346 | "name": "stdout" 347 | } 348 | ] 349 | }, 350 | { 351 | "cell_type": "code", 352 | "metadata": { 353 | "id": "SyeALTr8yAgV", 354 | "colab_type": "code", 355 | "colab": {} 356 | }, 357 | "source": [ 358 | "" 359 | ], 360 | "execution_count": null, 361 | "outputs": [] 362 | } 363 | ] 364 | } --------------------------------------------------------------------------------