Skip to content

Commit 54c34a5

Browse files
committed
Corrección Roadmap 37 + Nuevo ejercicio 38
1 parent 7b09edb commit 54c34a5

File tree

4 files changed

+192
-1
lines changed

4 files changed

+192
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*.xml
44
*.iml
55
*.json
6+
*.csv
67
!stats.json
78
.DS_Store
89
.idea/

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@
7171
|34|[ÁRBOL GENEALÓGICO DE LA CASA DEL DRAGÓN](./Roadmap/34%20-%20ÁRBOL%20GENEALÓGICO%20LA%20CASA%20DEL%20DRAGÓN/ejercicio.md)|[📝](./Roadmap/34%20-%20ÁRBOL%20GENEALÓGICO%20LA%20CASA%20DEL%20DRAGÓN/python/mouredev.py)|[▶️](https://youtu.be/GAHBOAzgE2w)|[👥](./Roadmap/34%20-%20ÁRBOL%20GENEALÓGICO%20LA%20CASA%20DEL%20DRAGÓN/)
7272
|35|[REPARTIENDO LOS ANILLOS DE PODER](./Roadmap/35%20-%20REPARTIENDO%20LOS%20ANILLOS%20DE%20PODER/ejercicio.md)|[📝](./Roadmap/35%20-%20REPARTIENDO%20LOS%20ANILLOS%20DE%20PODER/python/mouredev.py)|[▶️](https://youtu.be/10i2dnaMLj8)|[👥](./Roadmap/35%20-%20REPARTIENDO%20LOS%20ANILLOS%20DE%20PODER/)
7373
|36|[EL SOMBRERO SELECCIONADOR](./Roadmap/36%20-%20EL%20SOMBRERO%20SELECCIONADOR/ejercicio.md)|[📝](./Roadmap/36%20-%20EL%20SOMBRERO%20SELECCIONADOR/python/mouredev.py)|[▶️](https://youtu.be/_UjOD587elY)|[👥](./Roadmap/36%20-%20EL%20SOMBRERO%20SELECCIONADOR/)
74-
|37|[OASIS VS LINKIN PARK](./Roadmap/37%20-%20OASIS%20VS%20LINKIN%20PARK/ejercicio.md)|[🗓️ 16/09/24](https://discord.gg/8cxgGTxm?event=1280229634524450877)||[👥](./Roadmap/37%20-%20OASIS%20VS%20LINKIN%20PARK/)
74+
|37|[OASIS VS LINKIN PARK](./Roadmap/37%20-%20OASIS%20VS%20LINKIN%20PARK/ejercicio.md)|[📝](./Roadmap/37%20-%20OASIS%20VS%20LINKIN%20PARK/python/mouredev.py)||[👥](./Roadmap/37%20-%20OASIS%20VS%20LINKIN%20PARK/)
75+
|38|[MOUREDEV PRO](./Roadmap/38%20-%20MOUREDEV%20PRO/ejercicio.md)|[🗓️ 23/09/24](https://discord.gg/xeebRweK?event=1283082037917519985)||[👥](./Roadmap/38%20-%20MOUREDEV%20PRO/)
7576

7677
## Cursos en YouTube
7778

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import base64
2+
import requests
3+
4+
CLIENT_ID = "Mi CLIENT_ID"
5+
CLIENT_SECRET = "Mi CLIENT_SECRET"
6+
7+
8+
def get_token() -> str:
9+
url = "https://accounts.spotify.com/api/token"
10+
headers = {
11+
"Authorization": "Basic " + base64.b64encode(f"{CLIENT_ID}:{CLIENT_SECRET}".encode()).decode(),
12+
"Content-Type": "application/x-www-form-urlencoded"
13+
}
14+
data = {"grant_type": "client_credentials"}
15+
16+
response = requests.post(url, headers=headers, data=data)
17+
if response.status_code != 200:
18+
raise Exception(
19+
f"Error obteniendo el token de Spotify: {response.json()}."
20+
)
21+
22+
return response.json()["access_token"]
23+
24+
25+
def search_artist(token: str, name: str):
26+
url = f"https://api.spotify.com/v1/search?q={name}&type=artist&limit=1"
27+
headers = {"Authorization": f"Bearer {token}"}
28+
29+
response = requests.get(url, headers=headers)
30+
if response.status_code != 200:
31+
raise Exception(
32+
f"Error obteniendo el artista: {response.json()}."
33+
)
34+
35+
results = response.json()
36+
if results["artists"]["items"]:
37+
return results["artists"]["items"][0]["id"]
38+
else:
39+
raise Exception(
40+
f"El artista {name} no se ha encontrado."
41+
)
42+
43+
44+
def get_artist_data(token: str, id: str):
45+
46+
url = f"https://api.spotify.com/v1/artists/{id}"
47+
headers = {"Authorization": f"Bearer {token}"}
48+
49+
response = requests.get(url, headers=headers)
50+
if response.status_code != 200:
51+
raise Exception(
52+
f"Error obteniendo los datos del artista: {response.json()}."
53+
)
54+
55+
results = response.json()
56+
return {
57+
"name": results["name"],
58+
"followers": results["followers"]["total"],
59+
"popularity": results["popularity"]
60+
}
61+
62+
63+
def get_artist_top_track(token: str, id: str):
64+
65+
url = f"https://api.spotify.com/v1/artists/{id}/top-tracks"
66+
headers = {"Authorization": f"Bearer {token}"}
67+
68+
response = requests.get(url, headers=headers)
69+
if response.status_code != 200:
70+
raise Exception(
71+
f"Error obteniendo las canciones del artista: {response.json()}."
72+
)
73+
74+
results = response.json()
75+
76+
top_track = max(results["tracks"], key=lambda track: track["popularity"])
77+
78+
return {
79+
"name": top_track["name"],
80+
"popularity": top_track["popularity"]
81+
}
82+
83+
84+
# 1. Token
85+
token = get_token()
86+
87+
# 2. IDs
88+
artist_1_id = search_artist(token, "Taylor Swift")
89+
artist_2_id = search_artist(token, "Linkin Park")
90+
91+
# 3. Data
92+
93+
# 3.1. Seguidores y popularidad
94+
artist_1 = get_artist_data(token, artist_1_id)
95+
artist_2 = get_artist_data(token, artist_2_id)
96+
97+
# 3.2. Canción más popular
98+
top_track_artist_1 = get_artist_top_track(token, artist_1_id)
99+
top_track_artist_2 = get_artist_top_track(token, artist_2_id)
100+
101+
# 4. Comparativa
102+
artist_1_counter = 0
103+
artist_2_counter = 0
104+
105+
print(f"\nComparación de artistas:\n")
106+
print(f"{artist_1["name"]}")
107+
print(f"{artist_2["name"]}")
108+
109+
# 4.1. Seguidores
110+
print(f"\nComparación seguidores:\n")
111+
print(f"Seguidores {artist_1["name"]}: {artist_1["followers"]}")
112+
print(f"Seguidores {artist_2["name"]}: {artist_2["followers"]}")
113+
114+
if artist_1["followers"] > artist_2["followers"]:
115+
print(f"{artist_1["name"]} es más popular en número de seguidores.")
116+
artist_1_counter += 1
117+
else:
118+
print(f"{artist_2["name"]} es más popular en número de seguidores.")
119+
artist_2_counter += 1
120+
121+
# 4.2. Popularidad
122+
print(f"\nComparación popularidad:\n")
123+
print(f"Popularidad {artist_1["name"]}: {artist_1["popularity"]}")
124+
print(f"Popularidad {artist_2["name"]}: {artist_2["popularity"]}")
125+
126+
if artist_1["popularity"] > artist_2["popularity"]:
127+
print(f"{artist_1["name"]} es más popular a nivel general.")
128+
artist_1_counter += 1
129+
else:
130+
print(f"{artist_2["name"]} es más popular a nivel general.")
131+
artist_2_counter += 1
132+
133+
# 4.3. Canción
134+
print(f"\nComparación canción:\n")
135+
print(
136+
f"Canción {top_track_artist_1["name"]} ({artist_1["name"]}): {top_track_artist_1["popularity"]} popularidad.")
137+
print(
138+
f"Canción {top_track_artist_2["name"]} ({artist_2["name"]}): {top_track_artist_2["popularity"]} popularidad.")
139+
140+
if top_track_artist_1["popularity"] > top_track_artist_2["popularity"]:
141+
print(
142+
f"La canción {top_track_artist_1["name"]} de {artist_1["name"]} es más popular.")
143+
artist_1_counter += 1
144+
else:
145+
print(
146+
f"La canción {top_track_artist_2["name"]} de {artist_2["name"]} es más popular.")
147+
artist_2_counter += 1
148+
149+
# 5. Resultado
150+
print(f"\nResultado final:\n")
151+
print(
152+
f"{artist_1["name"] if artist_1_counter > artist_2_counter else artist_2["name"]} es más popular.")
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# #38 MOUREDEV PRO
2+
> #### Dificultad: Fácil | Publicación: 16/09/24 | Corrección: 23/09/24
3+
4+
## Ejercicio
5+
6+
```
7+
/*
8+
* EJERCICIO:
9+
* He presentado mi proyecto más importante del año: mouredev pro.
10+
* Un campus para la comunidad, que lanzaré en octubre, donde estudiar
11+
* programación de una manera diferente.
12+
* Cualquier persona suscrita a la newsletter de https://mouredev.pro
13+
* accederá a sorteos mensuales de suscripciones, regalos y descuentos.
14+
*
15+
* Desarrolla un programa que lea los registros de un fichero .csv y
16+
* seleccione de manera aleatoria diferentes ganadores.
17+
* Requisitos:
18+
* 1. Crea un .csv con 3 columnas: id, email y status con valor "activo"
19+
* o "inactivo" (y datos ficticios).
20+
* Ejemplo: 1 | [email protected] | activo
21+
* 2 | [email protected] | inactivo
22+
* (El .csv no debe subirse como parte de la corrección)
23+
* 2. Recupera los datos desde el programa y selecciona email aleatorios.
24+
* Acciones:
25+
* 1. Accede al fichero .csv y selecciona de manera aleatoria un email
26+
* ganador de una suscripción, otro ganador de un descuento y un
27+
* último ganador de un libro (sólo si tiene status activo).
28+
* 2. Muestra los emails ganadores y su id.
29+
* 3. Ten en cuenta que la primera fila (con el nombre de las columnas)
30+
* no debe tenerse en cuenta.
31+
*/
32+
```
33+
#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.
34+
35+
Sigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.
36+
37+
> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección "eventos" del servidor de **[Discord](https://discord.gg/mouredev)**.

0 commit comments

Comments
 (0)