lidiya3001
@lidiya3001
Обожаю сов :)

Почему возникает ошибка «can only join an iterable» при повторном прохождении цикла? И как сравнить имя пользователя с именем ключа словаря?

Здравствуйте. Пишу терминальную игрушку по угадыванию числа. Первая проблема возникла на этапе логина (при вводе он пишет, что такого пользователя нет, хотя он есть, а дальше сохраняет (т.е. тупо перезаписывает) его), таким образом каждую игру очки пользователя окончательно сбрасываются. И вторая, как по мне, более критичная - в конце цикла (т.е. при выигрыше или проигрыше) пользователю предлагают, грубо говоря, выйти из игры, сменить пользователя или продолжить игру с текущим именем. При выборе последнего варианта вылетает ошибка при подсчете очков:
scoreN = ("".join(dic[key])) TypeError: can only join an iterable
хотя в первоначальном варианте ее не возникало. Так же ошибка отсутствует, если поменять имя пользователя...
Вот код:
#******************* ИМПОРТ КАТАЛОГОВ *******************************************************************************************
import sys 
import json
import random
import msvcrt

#****************** ОБЪЯВЛЕНИЕ ГЛОБАЛЬНЫХ ПЕРЕМЕННЫХ И КЛАССОВ *******************************************************************
dic = {}
class Igrok():
    name = 'imya'
    score = 0
    i = 0
polsovatel = Igrok()
polsovatel.i = 0 
#polsovatel.name
chislo = '-1'
min = -1
max = -1
n = -1
z = -1
name = ' '
key = ' '

#****************** ФУНКЦИИ ******************************************************************************************************
#*** Ввод имени пользователя ***
def NewIgra():
    global polsovatel
    global name
    global dic
    polsovatel.name = input("Введите имя игрока ")
    Proverka()
    Random()

#*** Логика игры ***
def Logika():
    global polsovatel
    global name
    global chislo
    global z
    global dic
    global min
    global max
    print(polsovatel.name)#DEBAG
    while polsovatel.i!=(int(n)):
        if int(chislo) != int(z):
            try: # Отлавливаем ошибки ввода (а именно, буквам нет!)
                chislo = int(input("Введите загаданное число "))
            except ValueError:
                print("Ошибка ввода! ")
                chislo = input("Пожалуйста, введите ЧИСЛО еще раз ")
            if chislo < min or chislo > max: 
                print("Число выходит за пределы заданного вами диапазона!")
                chislo = input("Введите число еще раз ")
            if int(chislo) < int(z): 
                print("Слишком мало!")
                polsovatel.i+=1
                print(polsovatel.i)
            if int(chislo) > int(z):
                print("Слишком много!")
                polsovatel.i+=1
                print(polsovatel.i)
            if int(chislo) == int(z):
                key = polsovatel.name
                scoreN = ("".join(dic[key]))
                print(scoreN)#DEBAG
                print(dic[key]) #DEBAG
                polsovatel.score = int(scoreN) + (int(n)-polsovatel.i)*2
                scoreS = polsovatel.score - int(scoreN)
                dic[key] = polsovatel.score
                print(polsovatel.name, ", вы выиграли! Ваши очки за игру: ", scoreS)
                print("Ваше общее количество очков: ", polsovatel.score)
                print("Ваши очки сохранены!")
                print(dic[key])#DEBAG
                Exit()             
    else: 
        print("У вас закончиличь попытки, вы проиграли!")
        key = polsovatel.name
        if dic[key] >= 10:
            scoreN = ("".join(dic[key]))
            polsovatel.score = int(scoreN) - 10
            dic[key] = polsovatel.score
            print(polsovatel.name, " вы оштрафованы на 10 очков. Ваш баланс: ", polsovatel.score)
            print(dic[key]) #DEBAG
            Exit()

#*** Выход или продолжение игры ***          
def Exit():
    print ("\nНажмите <Esc> для закрытия окна или любую клавишу для продолжения игры")
    kay = ord(msvcrt.getch())
    if kay == 27:    # ESC
        print("Программа завершена")
        Save()
        sys.exit()
    PodMenu()

#*** Поиск и запись пользователя в базу ***
def Proverka(): #!
    global polsovatel
    global name
    global dic
    if name.find(polsovatel.name) != -1 : #Если имя пользователя есть в словаре начинаем игру
        print("Игра началась!")
    
    else:
        dic[polsovatel.name] = '0' #Если нет - добавляем
        print("Пользователь сохранен")
        print(dic)

#*** Выборы для подменю ***
def Punkt():
    try:
        punkt = int(input())
        if punkt == 1: Menu()
        if punkt == 2: Random()
        if punkt == 3: NewIgra()
        else:
            print("Такой пункт отсутствует! Повторите ввод!")
            Punkt()
    except ValueError:
        print("Не верный формат ввода! Введите ЧИСЛО для продолжения сценария")
        Punkt()

#*** Подменю ***
def PodMenu():
    print("Выберите что хотите сделать: ")
    print("Нажмите 1 для перехода в главное меню ")
    print("Нажмите 2 для продолжения игры с введенным именем пользователя ")
    print("Нажмите 3 для смены имени ")
    Punkt()
   
#*** Выгрузка***
def Slovar():
    global polsovatel
    global name
    global dic
    #Выгрузка таблицы очков из файла в словарь:
    with open('C:\\Users\\Professional\\Desktop\\Tokarev\\table.txt', 'r', encoding='utf-8') as file: #Читаем файл
        indata = file.read().splitlines() # read().splitlines() - чтобы небыло пустых строк

        """for line in indata: # Проходимся по каждой строчке
            key, *value = line.split() #Разбиваем строку по пробелам
            dic[key] = value # Добавляем в словарь
            name = (', '.join(list(dic))) #Конвертируем имена ключей в строку"""
        
        # проходим в цикле по списку строк
        for i in indata:
            # присваиваем переменным k и v левую и правую часть подстроки,
            # разделяя по символу ':'
            k, v = i.split(': ')
            # убираем лишние концевые пробелы
            v = v.strip()
            # определяем, является ли значение переменной v числом, и если да, то 
            # преобразуем к целому числу, иначе оставляем строкой
            v = int(v) if v.isdigit() else v
            # добавляем в словарь соответствующие пары ключ:значение
            dic[k] =  v
            print(list(dic)) #DEBAG

#*** Сохранение игры ***
def Save():
    global dic
    with open('C:\\Users\\Professional\\Desktop\\Tokarev\\table.txt', 'w', encoding='utf-8') as file: #Открываем файл на запись
        for key,val in dic.items():
            file.write('{}: {}\n'.format(key,val))

#************************************ Сама программа ******************************************

Slovar()
Menu()
  • Вопрос задан
  • 1623 просмотра
Решения вопроса 1
@o5a
Так там join вообще не нужен, у Вас же в этом dic[key] хранятся просто целые числа.
join используется для объединения последовательностей (список, кортеж, буквы из строки и т.п.) в одну строку.
scoreN = dic[key]
и в подобных местах, где строка, тоже заменить на число:
dic[polsovatel.name] = 0
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы