Как сделать оформление словаря в txt файле и вычитывание значений из этого файла?

что есть:
1. Файл с перечнем жанров игр в формате
genres.txt

RPG
Action
MMORPG
и т.д. каждый новый жанр с новой строки

2. Есть перечень игр в формате
games.txt

RPG = Dragon_Age, The_Elder_Scrolls_Skyrim
Shooter = Bulletstorm, Splinter_Cell
MMORPG = Lineage_2, Aion
Action = Grand_Theft_Auto_V, Watch_Dogs
Racing = Need_For_Speed_Payback, Blur
и т.д. каждый новый жанр с новой строки

3. И есть вот такой код... (сразу обозначусь что я новичок и пока только базу изучил, но без частой практики, поэтому эта ошибка может быть банальной и лежать где-то на поверхности)
Код

#-*- coding:cp1251 -*-

from random import randint

GenreList = []
FilteredGames = []
GameList = dict()
selected_genre = str()
selected_game = str()


def GenreSelection():
    genre_file = open('genres.txt')
    for line in genre_file.readlines():
        GenreList.append(line.strip())
    rand_range_genres = len(GenreList)
    print(rand_range_genres)
    selected_genre = GenreList[random.randint((rand_range_genres-rand_range_genres)-1,rand_range_genres)]
    print(selected_genre)
    genre_file.close()
    
def GameSelection():
    #genre = "".join(selected_genre)
    games_file = open("games.txt")
    onstring = games_file.read().split("\n")
    for item in onstring:
       key = item.split(" ")[0]
       value = item.split(" ")[1:]
       GameList[key] = value
    
    if item == selected_genre:
        FilteredGames.append(key[value])
    rand_drange_games = len(FilteredGames)
    print(FilteredGames)
    print(rand_range_games)
    print(GameList)
    #selected_game = GameList[random.randint((rand_range_games-rand_range_games)-1,rand_range_games)]
    #print(selected_game)
    games_file.close()

input('Для генерации жанра нажмите Enter')
GenreSelection()
input('Для генерации игры нажмите Enter')
GameSelection()



ошибки в том, что вычитывает данные из списка, потому-что когда вывожу данные из словаря print(GameList) , он их выводит в формате:
print(GameList)
{'RPG': ['Dragon_Age,', 'The_Elder_Scrolls_Skyrim'], 'Shooter': ['Bulletstorm,', 'Splinter_Cell'], 'MMORPG': ['Lineage_2,', 'Aion'], 'Action': ['Grand_Theft_Auto_V,', 'Watch_Dogs'], 'Racing': ['Need_For_Speed_Payback,', 'Blur']}

*Баг с запятыми фиксится их убиранием и оставлением пробела*

Но эти списки в квадратных скобках он не добавляет через Append в переменную FilteredGames.

Возможно я как-то не так оформил сам словарь? Есть какие-то правила оформления словарей в текстовом файле? Или их надо оформлять так-же как в самом питоне через фигурные скобки и двоеточия?

Из-за нулевой длинны списка, последующие закомментированные строки тоже выдают ошибку
  • Вопрос задан
  • 166 просмотров
Решения вопроса 2
trapwalker
@trapwalker Куратор тега Python
Программист, энтузиаст
Надо вам бы книжечку почитать по питону. Быстрее и полезнее было бы для вас в плане освоения.
Вот, например устаревшая конструкция:
#-*- coding:cp1251 -*-
Сейчас принято весь код держать в utf-8 и испоьзовать свежий питон третьей версии.

Прочитайте про PEP8.
Считается плохим стилем использовать CamelCase для чего-то кроме классов.
Для переменных и имен функций нужно использовать snake_case.
selected_genre = str()
selected_game = str()

Ни к чему объявлять такие переменные присвоением пустой строки, причем с вызовом явного конструктора. В Питоне строки - неизменяемый тип, а переменные. это не ячейки, зарезервированные в памяти, а, как бы, "бирки" с именем, которые вешаются на объекты. ВОт строки - это объекты, которые нельзя менять. Как создаются, так и остаются.

genre_file = open('genres.txt')
Не хорошо так открывать файл. Для такого мелкого скрипта это не так важно, но хорошую привычку у себя формировать надо всегда и всегда надо работать с файлами правильно. Через контекстный менеджер with и используя pathlib.

GenreList.append(line.strip())
Обратите внимание на разницу между append и extend, именно в этом одна из причин проблемы, с которой вы тут боретесь.

value = item.split(" ")[1:]
Сплит можно делать по знаку равно, а не только по пробелу. Такое ощущение, что вы не особо задумываетесь, что пишете в коде.

Там дальше вообще какая-то дичь. Так писать нельзя. Код непрозрачный и нечитабельный. Если вы наделали кучу косяков и ошибок в более простом коде, то вот в дальнейшей каше там вообще швах.
Проще надо.

Во-первых, используйте стандартные форматы для сериализации структур данных, например json, а тут лучше yaml. Он лучше подходит для редактирования человеком и не надо его парсить вручную совершая кучу ошибок в никому не нужном коде. Ваша задача вся решается в несколько понятных простых строчек, а вы тут навертели.

Во-вторых, почему вы так странно храните и выбираете игры? Храните их одним перечнем словарей. Каждый словарь в перечне будет соответствовать одной игре. В этом словаре будут все её параметры: название, жанр, рейтинг, если надо, который будет влиять на вероятность выбора...

Разбивайте всегда задачу на ОЧЕНЬ МАЛЕНЬКИЕ подзадачи и решайте их отдельно. Проверяйте решение подзадачек тоже по отдельности, убеждайтесь, что этим мелкие кирпичики работают.

Повторюсь, изучайте питон, чтобы программировать на нем как на питоне, а не вот так вот. Успехов.
Ответ написан
Maksim_64
@Maksim_64
Data Analyst
Когда мы храним информацию в файлах, то эта информация имеет определенную структуру. Вот это RPG = Dragon_Age, The_Elder_Scrolls_Skyrim Плохая структура, которая потребует парсинга, сами себе создаем проблемы.

Мы можем использовать например json для создания хранения.
import json
data = {
    "RPG": ["Dragon_Age", "The_Elder_Scrolls_Skyrim"],
    "Action": ["Grand_Theft_Auto_V", "Watch_Dogs"],
    "MMORPG": ["Lineage_2", "Aion"],
    "Shooter": ["Bulletstorm", "Splinter_Cell"],
    "Racing":["Need_For_Speed_Payback", "Blur"]
}

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

Здесь, мы создаем файл определенной структуры. Из которого нам будет легко извлекать информацию.

with open('data.json', 'r') as f:
    json_object = json.load(f)

Все вся наша информация в словаре. С которым нам удобно работать.

Теперь по поводу случайного выбора. Вы мало информации представили, по этому поводу. Выборка может происходить с заменой Выбрав элемент, я его возвращаю обратно и он может быть выбран снова. без замены Выбрав элемент он больше не может быть выбран снова. Информации как вы хотите осуществлять выборку вы дали мало. Например я могу использовать shuffle (перемешать элементы) и выбирать элемент c нулевым индексом всегда.
from random import shuffle
genres = list(json_object.keys())
shuffle(genres)
genre = genres[0]
print(f'Вам выпал жанр: {genre}')
games = json_object[genre]
shuffle(games)
game = games[0]
print(f'Вам выпала игра: {game}')

Это будет выборка с заменой. Мы можем использовать вместо выборки по индексу метод pop у списка и получим эффект выборки без замены (Но надо понимать объект json_object будет изменяться). Можно пойти и вашим путем. Осуществлять выборку индекса и выбирать по индексу, тоже нормальное решение.

В общем основная проблема это не верно выбранная структура.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@tuwkan
Начни поетапно решать проблемы, например
*Баг с запятыми фиксится их убиранием и оставлением пробела*
подумай, item.split(" ") - а может тут делить не по пробелу?
Ну и так далее со следующими вопросами
Ответ написан
@mumische
У вас код вообще изначально не работает, здесь ошибки с импортом, выход за границы массива, использование отсутствующей переменной. Ну а про добавление в FilteredGames - во-первых, сравнивать нужно не item, а во-вторых, у вас сравнение должно идти внутри for, а не после него.
Ответ написан
@PugLord Автор вопроса
Всем спасибо за советы. Код получился сейчас вот такой:
Код

import random
from random import randint 
import json

def ItemSelection():
    with open('items.json') as f:
        templates = json.load(f)
    
    #Скорее всего этот for даже не нужен
    for key, value in templates.items():
        key = select
        ListLenght = len(templates[select])
        
    print("Значений в данном разделе:",ListLenght)
    ListOfItems = templates[select]
    random.shuffle(ListOfItems)
    selected_item = ListOfItems[1]
    print("И из этого множественного разнообразия, тебе выпадает:", selected_item)
    
print('Введите ключ что бы получить результат')
select = input('Ожидаю ввод: ')
ItemSelection()



Если есть конструктивная критика как его можно улучшить или выполнить более качественно - с радостью выслушаю)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы