import os def load_tracks(filepath): """Загружает треки из txt файла. При ошибке возвращает пустой список.""" tracks = [] try: with open(filepath, "r", encoding="utf-8") as f: for line in f: line = line.strip() # пропускаем пустые строки if not line: continue parts = line.split("|") # проверяем что полей ровно 10 if len(parts) != 10: print("Пропускаю некорректную строку:", line) continue track = { "track_id": int(parts[0]), "title": parts[1], "artist": parts[2], "album": parts[3], "genre": parts[4], "duration_seconds": int(parts[5]), "plays": int(parts[6]), "likes": int(parts[7]), "release_date": parts[8], "explicit": parts[9] == "true" } tracks.append(track) except FileNotFoundError: print("Файл не найден:", filepath) return [] return tracks def filter_by_genre(tracks, genre): """Возвращает треки с указанным жанром.""" result = [] for track in tracks: if track["genre"].lower() == genre.lower(): result.append(track) return result def filter_by_duration(tracks, min_sec, max_sec): """Возвращает треки с длительностью в диапазоне [min_sec, max_sec].""" result = [] for track in tracks: if min_sec <= track["duration_seconds"] <= max_sec: result.append(track) return result def get_top_tracks(tracks, n): """Возвращает n треков с наибольшим числом прослушиваний.""" sorted_tracks = sorted(tracks, key=lambda t: t["plays"], reverse=True) return sorted_tracks[:n] def calculate_artist_stats(tracks, artist): """Возвращает статистику по исполнителю.""" artist_tracks = [] for track in tracks: if track["artist"].lower() == artist.lower(): artist_tracks.append(track) if len(artist_tracks) == 0: return { "total_tracks": 0, "total_plays": 0, "total_likes": 0, "avg_duration_seconds": 0.0 } total_plays = 0 total_likes = 0 total_duration = 0 for track in artist_tracks: total_plays += track["plays"] total_likes += track["likes"] total_duration += track["duration_seconds"] avg_duration = total_duration / len(artist_tracks) return { "total_tracks": len(artist_tracks), "total_plays": total_plays, "total_likes": total_likes, "avg_duration_seconds": round(avg_duration, 2) } def get_unique_genres(tracks): """Возвращает отсортированный список уникальных жанров.""" genres = [] for track in tracks: if track["genre"] not in genres: genres.append(track["genre"]) return sorted(genres) def calculate_like_rate(tracks): """Считает коэффициент лайков для каждого трека.""" result = [] for track in tracks: if track["plays"] == 0: continue rate = track["likes"] / track["plays"] * 100 rate = round(rate, 2) result.append((track["title"], rate)) result = sorted(result, key=lambda x: x[1], reverse=True) return result def group_by_artist(tracks): """Группирует треки по исполнителю.""" result = {} for track in tracks: artist = track["artist"] if artist not in result: result[artist] = [] result[artist].append(track) return result def filter_by_date_range(tracks, date_from, date_to): """Возвращает треки выпущенные в диапазоне дат.""" result = [] for track in tracks: if date_from <= track["release_date"] <= date_to: result.append(track) return result def save_report(data, filepath): """Сохраняет список треков в txt файл.""" try: directory = os.path.dirname(filepath) if directory and not os.path.exists(directory): os.makedirs(directory) with open(filepath, "w", encoding="utf-8") as f: for track in data: line = "{title} | {artist} | {genre} | {plays} прослушиваний\n".format( title=track["title"], artist=track["artist"], genre=track["genre"], plays=track["plays"] ) f.write(line) return True except Exception as e: print("Ошибка при сохранении файла:", e) return False def main(): # 1. Загружаем треки tracks = load_tracks("data/data.txt") if len(tracks) == 0: print("Нет данных для обработки") return # 2. Общее количество треков и жанры print("=" * 40) print("Всего треков:", len(tracks)) genres = get_unique_genres(tracks) print("Жанры:", ", ".join(genres)) # 3. Фильтрация по жанру print("=" * 40) rock_tracks = filter_by_genre(tracks, "rock") print("Треков в жанре rock:", len(rock_tracks)) # 4. Топ-5 треков по прослушиваниям print("=" * 40) print("Топ-5 треков по прослушиваниям:") top5 = get_top_tracks(tracks, 5) for track in top5: print(" -", track["title"], "—", track["plays"], "прослушиваний") # 5. Статистика исполнителя print("=" * 40) first_artist = tracks[0]["artist"] stats = calculate_artist_stats(tracks, first_artist) print("Статистика исполнителя:", first_artist) print(" - Треков:", stats["total_tracks"]) print(" - Прослушиваний:", stats["total_plays"]) print(" - Лайков:", stats["total_likes"]) print(" - Средняя длительность (сек):", stats["avg_duration_seconds"]) # 6. Фильтрация по длительности print("=" * 40) mid_tracks = filter_by_duration(tracks, 180, 240) print("Треков длительностью 3-4 минуты:", len(mid_tracks)) # 7. Топ-5 по коэффициенту лайков print("=" * 40) print("Топ-5 треков по лайкам:") like_rates = calculate_like_rate(tracks) for title, rate in like_rates[:5]: print(" -", title, "—", rate, "%") # 8. Фильтрация по дате print("=" * 40) date_filtered = filter_by_date_range(tracks, "2020-01-01", "2024-12-31") print("Треков за период 2020-2024:", len(date_filtered)) # 9. Группировка по исполнителям print("=" * 40) print("Треков по исполнителям:") grouped = group_by_artist(tracks) for artist, artist_tracks in grouped.items(): print(" -", artist, ":", len(artist_tracks), "треков") # 10. Сохраняем топ-10 в файл print("=" * 40) top10 = get_top_tracks(tracks, 10) success = save_report(top10, "results/top_tracks.txt") if success: print("Топ-10 треков сохранён в results/top_tracks.txt") else: print("Не удалось сохранить файл") if __name__ == "__main__": main()