Skip to content

Commit 22e8394

Browse files
committed
tarea
1 parent 77ef73c commit 22e8394

File tree

2 files changed

+225
-0
lines changed

2 files changed

+225
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 16,
6+
"id": "4cf091a5",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"import requests\n",
11+
"import time\n",
12+
"import pandas as pd\n",
13+
"from datetime import datetime\n",
14+
"\n",
15+
"def get_contest_data_to_dataframe(contest_id,participants_limit):\n",
16+
" # Obtener información del concurso\n",
17+
" contest_url = f\"https://codeforces.com/api/contest.standings?contestId={contest_id}&from=1&count={participants_limit}&showUnofficial=false\"\n",
18+
" contest_response = requests.get(contest_url)\n",
19+
" contest_data = contest_response.json()\n",
20+
" \n",
21+
" if contest_data['status'] != 'OK':\n",
22+
" print(\"Error al obtener datos del concurso\")\n",
23+
" return None\n",
24+
" \n",
25+
" contest_info = contest_data['result']['contest']\n",
26+
" contest_name = contest_info['name']\n",
27+
" contest_start_time = datetime.fromtimestamp(contest_info['startTimeSeconds']).strftime('%Y-%m-%d')\n",
28+
" \n",
29+
" # Obtener participantes\n",
30+
" standings_url = f\"https://codeforces.com/api/contest.standings?contestId={contest_id}&from=1&count={participants_limit}&showUnofficial=false\"\n",
31+
" standings_response = requests.get(standings_url)\n",
32+
" standings_data = standings_response.json()\n",
33+
" \n",
34+
" if standings_data['status'] != 'OK':\n",
35+
" print(\"Error al obtener standings\")\n",
36+
" return None\n",
37+
" \n",
38+
" problems = standings_data['result']['problems']\n",
39+
" rows = standings_data['result']['rows']\n",
40+
" num_problems = len(problems)\n",
41+
" \n",
42+
" # Obtener todos los handles\n",
43+
" handles = [row['party']['members'][0]['handle'] for row in rows]\n",
44+
" \n",
45+
" # Obtener metadatos de usuarios\n",
46+
" users_info_url = f\"https://codeforces.com/api/user.info?handles={';'.join(handles)}\"\n",
47+
" users_response = requests.get(users_info_url)\n",
48+
" users_data = users_response.json().get('result', []) if users_response.json()['status'] == 'OK' else []\n",
49+
" \n",
50+
" # Mapear metadatos\n",
51+
" user_metadata = {user['handle']: {\n",
52+
" 'country': user.get('country'),\n",
53+
" 'city': user.get('city'),\n",
54+
" 'rating': user.get('rating'),\n",
55+
" 'maxRating': user.get('maxRating')\n",
56+
" } for user in users_data}\n",
57+
"\n",
58+
" participants_data = []\n",
59+
" \n",
60+
" for row in rows:\n",
61+
" handle = row['party']['members'][0]['handle']\n",
62+
" participant_data = {\n",
63+
" \"author_handle\": handle,\n",
64+
" \"contest_name\": contest_name,\n",
65+
" \"contest_start_time\": contest_start_time,\n",
66+
" **user_metadata.get(handle, {\n",
67+
" 'country': None,\n",
68+
" 'city': None,\n",
69+
" 'rating': None,\n",
70+
" 'maxRating': None\n",
71+
" })\n",
72+
" }\n",
73+
" \n",
74+
" # Procesar problemas\n",
75+
" for i in range(num_problems):\n",
76+
" problem_index = chr(65 + i)\n",
77+
" problem_result = row['problemResults'][i]\n",
78+
" \n",
79+
" # Datos básicos\n",
80+
" participant_data.update({\n",
81+
" f\"finished_{problem_index}\": problem_result['points'] > 0,\n",
82+
" f\"rating_{problem_index}\": problems[i].get('rating')\n",
83+
" })\n",
84+
" \n",
85+
" # Inicializar campos de envío\n",
86+
" participant_data[f\"language_{problem_index}\"] = None\n",
87+
" participant_data[f\"relative_time_{problem_index}\"] = None\n",
88+
" participant_data[f\"time_to_answer_{problem_index}\"] = None\n",
89+
" \n",
90+
" # Obtener envíos\n",
91+
" status_url = f\"https://codeforces.com/api/contest.status?contestId={contest_id}&handle={handle}\"\n",
92+
" status_response = requests.get(status_url)\n",
93+
" time.sleep(1)\n",
94+
" \n",
95+
" if status_response.json()['status'] == 'OK':\n",
96+
" submissions = status_response.json()['result']\n",
97+
" prev_time = 0\n",
98+
" \n",
99+
" for submission in submissions:\n",
100+
" if submission['verdict'] == 'OK':\n",
101+
" problem_index = submission['problem']['index']\n",
102+
" participant_data[f\"language_{problem_index}\"] = submission['programmingLanguage']\n",
103+
" rt = submission['relativeTimeSeconds']\n",
104+
" participant_data[f\"relative_time_{problem_index}\"] = rt\n",
105+
" participant_data[f\"time_to_answer_{problem_index}\"] = rt - prev_time\n",
106+
" prev_time = rt\n",
107+
" \n",
108+
" participants_data.append(participant_data)\n",
109+
" \n",
110+
" # Crear DataFrame\n",
111+
" df = pd.DataFrame(participants_data)\n",
112+
" \n",
113+
" # Ordenar columnas\n",
114+
" ordenadito = ['author_handle']\n",
115+
" \n",
116+
" \n",
117+
" for prefix in ['finished', 'language', 'relative_time', 'time_to_answer', 'rating']:\n",
118+
" ordenadito.extend([f\"{prefix}_{chr(65 + i)}\" for i in range(num_problems)]) # A, B, C, ... el char 65 es A\n",
119+
" \n",
120+
" ordenadito = ordenadito +[\n",
121+
" 'contest_name', 'contest_start_time', \n",
122+
" 'country', 'city', 'rating', 'maxRating'\n",
123+
" ]\n",
124+
" return df[ordenadito] # Retornar el DataFrame con las columnas ordenadas\n",
125+
"\n",
126+
"# Uso\n",
127+
"contest_id = 566\n",
128+
"participants_limit = 10 # Limitar a los primeros 10 participantes\n",
129+
"df = get_contest_data_to_dataframe(contest_id,participants_limit)\n",
130+
"\n",
131+
"if df is not None:\n",
132+
" df.to_csv(f\"codeforces_contest_{contest_id}_participants6.csv\", index=False)"
133+
]
134+
},
135+
{
136+
"cell_type": "code",
137+
"execution_count": null,
138+
"id": "205830ec",
139+
"metadata": {},
140+
"outputs": [],
141+
"source": [
142+
"#Para obtener el CSV iterar en todos los ID de concurso que quieras"
143+
]
144+
},
145+
{
146+
"cell_type": "code",
147+
"execution_count": null,
148+
"id": "3d7574f1",
149+
"metadata": {},
150+
"outputs": [],
151+
"source": [
152+
"# Paso 1 filtrar concursos por fecha y nombre de concurso\n",
153+
"\n",
154+
"url = \"https://codeforces.com/api/contest.list\"\n",
155+
"response = requests.get(url)\n",
156+
"data= response.json()\n",
157+
"data\n",
158+
"\n",
159+
"\n",
160+
"# Filtrar concursos por fecha y nombre\n",
161+
"filtrado = []\n",
162+
"if response.status_code == 200: \n",
163+
" data = response.json() \n",
164+
" if data['status'] == 'OK': \n",
165+
" for contest in data['result']['name']: \n",
166+
" # Verifica si existe 'startTimeSeconds' en el concurso\n",
167+
" if 'startTimeSeconds' in contest:\n",
168+
" start_time = datetime.fromtimestamp(contest['startTimeSeconds']) \n",
169+
" if datetime(2024, 7, 1) <= start_time <= datetime(2024, 12, 31): # Límite de fechas\n",
170+
" filtrado.append({ \n",
171+
" 'id_concurso': contest['id'], \n",
172+
" 'nombre_concurso': contest['name'], \n",
173+
" 'hora_inicio_concurso': start_time, \n",
174+
" 'duracion_(segundos)': contest['durationSeconds'], \n",
175+
" 'tipo': contest['type'], \n",
176+
" })\n",
177+
"\n",
178+
"# Convertir a DataFrame para visualizar mejor \n",
179+
"df = pd.DataFrame(filtrado)\n",
180+
"df_filtrado = df[df[\"nombre_concurso\"].str.contains(\"round|hello|good bye\", case=False, na=False)]\n",
181+
"\n",
182+
"lista_de_concursos = df_filtrado['id_concurso'].tolist() # Obtener lista de IDs de concursos filtrados\n",
183+
"#lista_de_concursos.to_csv(\"lista_de_concursos.csv\", index=False)\n",
184+
"\n",
185+
"for lista in lista_de_concursos:\n",
186+
" df = get_contest_data_to_dataframe(lista,participants_limit=10)\n",
187+
" if df is not None:\n",
188+
" df.to_csv(f\"codeforces_contest_{lista}_num_participantes_{participants_limit}.csv\", index=False)\n",
189+
"\n",
190+
"#Así obtendrás un CSV por cada concurso que cumpla con los criterios de búsqueda, con los primeros 10 participantes de cada concurso., cuyo límite se puede extender."
191+
]
192+
}
193+
],
194+
"metadata": {
195+
"kernelspec": {
196+
"display_name": "sns",
197+
"language": "python",
198+
"name": "python3"
199+
},
200+
"language_info": {
201+
"codemirror_mode": {
202+
"name": "ipython",
203+
"version": 3
204+
},
205+
"file_extension": ".py",
206+
"mimetype": "text/x-python",
207+
"name": "python",
208+
"nbconvert_exporter": "python",
209+
"pygments_lexer": "ipython3",
210+
"version": "3.11.4"
211+
}
212+
},
213+
"nbformat": 4,
214+
"nbformat_minor": 5
215+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
beautifulsoup4==4.12
2+
html5lib==1.1
3+
ipykernel==6.29
4+
ipywidgets==8.1
5+
jupyter==1.1
6+
lxml==5.3
7+
openpyxl==3.1
8+
pandas==2.2
9+
selenium==4.28
10+
tqdm==4.67

0 commit comments

Comments
 (0)