Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 5, 2017 00:14:32

arctikbear
Зарегистрирован: 2017-09-05
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Бесконечный цикл с проверкой правильности ввода <input()>

Здравствуйте!
Столкнулся с трудностью понимания проверки, перепробывал всё, что понимаю, но видимо, распутаться без помощи не получится.
Задача:
Есть список слов с соответствующими им номерами, например:

 [ [1, 'Лопата'], [2, 'Ведро'], [3, 'Помидор'] ]
и т.д., не менее 200 слов
Пользователь отвечает, к какой категории он отнесет каждое из слов в списке.
Изначально категорий этих нет, он придумывает названия сам.
Чтобы он не вводил каждый раз категорию, которая уже есть в списке, на экран выводится этот список с ключами и ему остается ввести ключ, например:
“Введите новую категорию или выберите из списка и введите цифру: (1:Инструменты, 2:Овощи)”
Количество категорий в списке может быть не более, чем количество изначальных слов (Лопата, Ведро, …)
На выхоте желательно получить следующий список:
 [[1, 'Лопата', 'Инструменты'], [2, 'Ведро', 'Инструменты'], [3, 'Помидор', 'Овощи']]
И вроде, всё понятно, но начинается тупняк, если при выполнении опроса в цикле
for i in <Изначальный список>:
userAnswer = input('bla bla')
пользователь начинает отвечать то цифрами, не существующими в словаре, то словами, то опять цифрами
помогите найти ошибку
 myList = [[1, 'Lopata'], [2, 'Vedro'], [3, 'Pomidor'], [4, 'Molotok']]
categoryDict = {0:''}
for i in myList:
    userInput = input('Enter new category (or number): ')
    try:
        val = int(userInput)
        if val in categoryDict.keys():
            i.append(categoryDict[val])
        else:
            print(' wrong number! ')
            userInput = input('Enter valid number: ')
            while userInput not in categoryDict.keys():
                userInput = input('Enter valid number: ')
                try:
                    val = int(userInput)
                except ValueError:
                    categoryDict.update({list(categoryDict.keys())[-1] + 1:userInput})
                    i.append(userInput)
                    break
            i.append(categoryDict[int(userInput)])
    except ValueError:
        categoryDict.update({list(categoryDict.keys())[-1] + 1:userInput})
        if userInput not in i:
            i.append(userInput)
print(categoryDict)
print(myList)

Отредактировано arctikbear (Сен. 5, 2017 00:28:00)

Офлайн

#2 Сен. 5, 2017 00:56:44

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10015
Репутация: +  857  -
Профиль   Отправить e-mail  

Бесконечный цикл с проверкой правильности ввода <input()>

Непонятно, зачем тебе это надо. Само задание мутно выглядит.
Если тебе надо раскидать слова по категориям, то у тебя должен быть список слов, список категорий и словарь пар вида <категория, список слов>. Никаких цифр там быть не должно. Нумерация либо делается на лету, либо же должен быть отдельный список пар <слово, номер>. Если же это вообще для меню, то часто делается список пар <строка, слово>, где строка может быть как числовой, так и буквенной (буква q, например, ведёт к выходу; буква h ведёт к помощи).



Отредактировано py.user.next (Сен. 5, 2017 00:57:32)

Офлайн

#3 Сен. 5, 2017 01:31:39

arctikbear
Зарегистрирован: 2017-09-05
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Бесконечный цикл с проверкой правильности ввода <input()>

Задание реальное, но так как плохо дружу с PyQt, приходится плясать с бубном, иначе все решилось бы выпадающим списком, от незнания работы с Gui пытаюсь что то сделать хотя бы в консоли
Это часть теста для детей (психосоматика), только в настоящее время диагностика проводится с бумажными карточками и человек переписывает все названия вручную, а заполняют мамы этих детей и че они там введут - одному Б.. известно, хотел исключить ошибки. На выходе нужен файл хотя бы .txt, лучше - PDF? Это я сделаю, а вот как уйти от ошибок ввода - не могу понять
Основная идея - ребенок для каждого слова сам придумывает категорию или использует уже существующую, но тоже им придуманную раньше. От адекватности его ответов зависит его диагностика

Отредактировано arctikbear (Сен. 5, 2017 01:34:23)

Офлайн

#4 Сен. 5, 2017 02:01:55

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10015
Репутация: +  857  -
Профиль   Отправить e-mail  

Бесконечный цикл с проверкой правильности ввода <input()>

arctikbear
Задание реальное, но так как плохо дружу с PyQt, приходится плясать с бубном, иначе все решилось бы выпадающим списком, от незнания работы с Gui пытаюсь что то сделать хотя бы в консоли
Сначала его нужно превратить в техническое задание - набор требований на языке компьютерных терминов (экран, кнопки, пользователь и так далее). Ты задачу не поставил и пытаешься что-то приблизительное написать. Комьютер-то не знает, кто там сидит и что он думает, как устроены бумажки и какие там связи между ними, для него есть понятия только: “ввели то-то”, “вывести то-то”, “достать из памяти то-то”, “сохранить в память то-то”, - и твоя задача в том, чтобы всё это соединить в коде (сформировать ему мышление). Он не будет сам каким-то чудесным образом понимать, что ему делать; это всё зависит только от тебя.

arctikbear
иначе все решилось бы выпадающим списком
И с выпадающим списком ты бы тоже не сделал, так как он тоже не знает когда и что выбирать при его активации пользователем.

arctikbear
то словами, то опять цифрами помогите найти ошибку
Ошибка в том, что ты без плана начал писать программу. Только полный план сначала надо составить и потом его шлифануть, а уже после этого записывать по нему программу на языке программирования. Язык программирования программу не делает. Это как пытаться построить дом, укладывая кирпичи. Кирпичи-то нормальные, но надо знать, куда их класть и по каким линиям. Без плана получится просто груда кирпичей или даже отдельные стены, но в виде треугольника, да ещё и разъединённого. Тебе нужен нормальный дом, а не какое-то треугольное фуфло.

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



Отредактировано py.user.next (Сен. 5, 2017 02:14:12)

Офлайн

#5 Сен. 5, 2017 09:12:07

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Бесконечный цикл с проверкой правильности ввода <input()>

наверное gui лучше для работы с детишками.

 from bottle import route, request, template, run
import json
from collections import defaultdict
words="мама папа яблоко".split()
classes =set("люди фрукты".split())
tpl="""
<html>
<head>
<meta charset="utf-8">
</head>
<form action="/login" method="post">
    Username: <input name="username" type="text" /></br>
    %for k,i in enumerate(w):
{{i}}:<input list="ili" name="k{{k}}"></br>
    %end
  <datalist id="ili">
     %for i in c:
       <option value="{{i}}">
     %end
  </datalist>
<input value="Done" type="submit" />
</form>
</html>
"""
@route('/login')
def login():
    return template(tpl, w = words, c = classes)
@route('/login', method='POST')
def do_login():
    username = request.forms.username
    result =defaultdict(list)
    for k,i in enumerate(words):
        val = getattr(request.forms, "k{}".format(k))
        classes.add(val)
        result[val].append(i)
    with open(username+".json","w",encoding="utf-8") as f:
        json.dump(dict(result),f,indent=2, ensure_ascii=0)
    return template(tpl, w = words, c = classes)
run(host='localhost', port=8080)

Классы предметов очевидно можно сохранять для дальнейшего использования в файл…



Отредактировано doza_and (Сен. 5, 2017 09:13:23)

Офлайн

#6 Сен. 6, 2017 03:15:36

arctikbear
Зарегистрирован: 2017-09-05
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Бесконечный цикл с проверкой правильности ввода <input()>

py.user.next
Ошибка в том, что ты без плана начал писать программу. Только полный план сначала надо составить и потом его шлифануть, а уже после этого записывать по нему программу на языке программирования. Язык программирования программу не делает. Это как пытаться построить дом, укладывая кирпичи. Кирпичи-то нормальные, но надо знать, куда их класть и по каким линиям. Без плана получится просто груда кирпичей или даже отдельные стены, но в виде треугольника, да ещё и разъединённого. Тебе нужен нормальный дом, а не какое-то треугольное фуфло.

И без структурного программирования в такой программе делать нечего. То, что ты выложил, - это просто набор слов (набор операторов). Там их не много (действий немного выполняется), но ты уже запутался в этой куче и не можешь понять, как она работает. Нужно делать отдельные функции и вызывать их, только когда это нужно: функцию ввода, функцию поиска, функцию сохранения, функцию вывода. Тогда оно будет и читаемым (понятным), и пригодным для разработки в каждой своей части.
Большое спасибо за разъяснения.
хотел быстро - получил “спагетти код”
сижу читаю про Дейкстру, думаю какие логические блоки и сущности здесь будут нужны.
без структуры на любом языке запутаешься, понял - синтаксис - дело десятое, спасибо.

P.S. Очень помог фрагмент из вики про построение программы сверху-вниз с заглушками на местах функций. Это жесть, что я до сих пор про это не слышал, не читал и не догадался.
Ждет меня рефакторинг…

Отредактировано arctikbear (Сен. 6, 2017 03:23:39)

Офлайн

#7 Сен. 6, 2017 04:10:55

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10015
Репутация: +  857  -
Профиль   Отправить e-mail  

Бесконечный цикл с проверкой правильности ввода <input()>

arctikbear
думаю какие логические блоки и сущности здесь будут нужны.
Меню, которое ты взялся делать, - это очень сложная конструкция, несмотря на кажущуюся простоту. Когда я делал меню в консоли несколько лет назад, мне пришлось пройти несколько этапов, прежде чем я получил что-то приемлемое. Переписывал (менял архитектуру меню) с нуля три раза. Это не то, что где какой пункт и подпункт, это вообще полное устройство меню и его элементов. Проблемы возникали при общении пунктов меню друг с другом: передача информации из нижнего меню в верхнее меню; передача информации из верхнего меню в нижнее; никакой симметрии в этом нет, всё нужно было продумывать по отдельности. При возникновении ошибок в нижнем меню нужно было передать эту информацию в верхнее меню, чтобы там отобразилось сообщение, а при обратном спуске нижнее меню должно было помнить, что это не новый вход, а спуск из верхнего после ошибки, и тоже отображать соотвествующую информацию. И когда возникал какой-то баг (а они возникают всегда неожиданно, непредсказуемо и из ниоткуда), была целая проблема его исправить - мешала архитектура меню. Пришлось переписывать, пришлось всё думать заново, и так несколько раз в разные месяцы. Ты полгода используешь программу, а потом понимаешь, что она неправильная - не очень весело. Но в этом опыт и состоит. Когда ты его приобретаешь, то все последующие программы становятся проще. А без него ни одна программа у тебя не получается, вот прямо как сейчас.

Что я хочу сказать: не надо думать, что всё будет просто. Просто пользоваться != просто под капотом. Пока опыта нет и точно не знаешь, что это и как будет, не ищи простые решения, их может просто не быть. Иногда только сложное решение может дать тебе саму программу, которая тебе и нужна, а не какой-то красивый код.

Я думаю, даже если ты определишь все функции, ты эту программу не напишешь, потому что утонешь в консоли. Если же ты будешь делать через Qt Designer, то графику ты ещё сделаешь, но ты не потянешь подключение графики к коду с вычислениями. Так что, максимум, ты можешь потренироваться в элементарных навыках программирования и понять, насколько это сложно всё. Первоначальный план - написать программу для детей и родителей - не сбудется, для этого надо уже уметь всё делать.



Отредактировано py.user.next (Сен. 6, 2017 04:19:37)

Офлайн

#8 Сен. 6, 2017 11:56:31

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Бесконечный цикл с проверкой правильности ввода <input()>

Замечу вдогонку что есть модуль cmd https://docs.python.org/3/library/cmd.html
который облегчает создание консольной интерактивной программы.
Еще я не думаю что надо вводить новую сущность в виде номеров выбираемых категорий, она лишняя. Лучше прикрутить readline подсказки при выборе. Правда это может потребовать усилий под виндой.

По поводу сможете или не сможете сделать, то думаю сможете. Но надо нарабатывать навык.

Посмотрите на приведенный мной кусок кода. Он на мой взгляд полностью решает вашу задачу с вводом данных с использованием GUI. Так что для решения вашей задачи нужна всего пара - тройка абзацев кода.
Для консоли или Qt наверное будет чуток больше кода.
Дерзайте!



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version