LINUX.ORG.RU

Как в питоне получить N значений из кутешного окна?

 ,


0

2

По ходу моего знакомства с фрикадом возник вопрос, как в скрипты передавать параметры из GUI. К сожалению, скрипты там на дурацком питоне, который я вообще не знаю.

Для получения N параметров я накатал такую штуку:

def getNparametersFromWindow(Labels, Title="Tell me more"):
	RET = 0
	Parameters = []
	def hide():
		RET = 1
		del Parameters[:]
		dialog.hide()
	def proceed():
		RET = 1
		dialog.hide()
	dialog = QtGui.QDialog()
#	dialog.resize(200,300)
	dialog.setWindowTitle(Title)
	la = QtGui.QVBoxLayout(dialog)
	lbl = []
	for i in range(0, len(Labels)):
		lbl.append(QtGui.QLabel(Labels[i]))
		la.addWidget(lbl[i])
		Parameters.append(QtGui.QLineEdit())
		la.addWidget(Parameters[i])
	okbox = QtGui.QDialogButtonBox(dialog)
	okbox.setOrientation(QtCore.Qt.Horizontal)
	okbox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
	la.addWidget(okbox)
	QtCore.QObject.connect(okbox, QtCore.SIGNAL("accepted()"), proceed)
	QtCore.QObject.connect(okbox, QtCore.SIGNAL("rejected()"), hide)
	QtCore.QMetaObject.connectSlotsByName(dialog)
	dialog.show()
	while (RET != 1):
		pass
	return Parameters
Однако, она подвисает - ничего не происходит.

Вопрос: чего нужно изменить, чтобы эта функция возвращала строковой массив из N введенных пользователем значений, соответствующих меткам из массива Labels?

☆☆☆☆☆
Ответ на: комментарий от AIv

GOTO НЕТУ!

Это тоже косяк. Во многих случаях goto очень даже нужен.

А чего, Tkinetr не подойдет?

Не знаю: я вообще с питоном второй день знаком ☺

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Это тоже косяк. Во многих случаях goto очень даже нужен.

А зачем было из криокамеры вылезать тогда? Замерзли?;-)

AIv ★★★★★
()
Ответ на: комментарий от dmfd

что, в любом языке? даже там где исключения ничего не весят?

shty ★★★★★
()
Ответ на: комментарий от dmfd

Если уж начинать сажать на кол, то первыми должны идти те кто использует вложенные циклы и goto для выхода из них.

fat_angel ★★★★★
()
Ответ на: комментарий от fat_angel

Все равно циклы в конечном итоге превращаются в набор goto… Так что, сажать на кол надо людей вроде тебя, твердящих, что goto не нужно!

А уж без вложенных циклах в обработке изображений вообще делать нечего!

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от fat_angel

те кто использует вложенные циклы

А что за алгоритмы ты пишешь (на языках без оптимизации хвостовой рекурсии), что в них нет вложенных циклов?

и goto для выхода из них.

Честно говоря, давно не сталкивался с тем, чтобы это было нужно. Обычно можно без лишних вычислений засунуть это в условие выхода или обойти ещё как-то. Но catch/throw вместо goto - это просто сказочный говнокод. Заучили, что «goto это не кошерно», а мозг включать не умеют.

dmfd
()
Ответ на: комментарий от Eddy_Em

Все равно циклы в конечном итоге превращаются в набор goto…

ну так и пиши в машинных кодах, чего уж стесняться

shty ★★★★★
()
Ответ на: комментарий от fat_angel

Пример можно?

if( is_stupid(question) ||  is_asshole(author) || my_state==TIRED ) goto PENIS;


как же без этого?
AIv ★★★★★
()
Ответ на: комментарий от Eddy_Em

Так что, сажать на кол надо людей вроде тебя, твердящих, что goto не нужно!

Мы же с Вами вроде коллеги... так вот, goto ненужно!

AIv ★★★★★
()
Ответ на: комментарий от Eddy_Em

«Если оно есть, значит, кому-то оно да нужно» ©

Насчет лиспа это еще справедливо... но не насчет goto.

AIv ★★★★★
()
Ответ на: комментарий от AIv

У меня goto активно используется в вычислителях внутри макроса: если выделение памяти или какая-то другая операция оканчивается неудачей, макрос дает переход на метку в конце функции, где запускаются деструкторы.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

У меня goto активно используется в вычислителях внутри макроса

Ну Вы же знаете какие мы коды пишем?;-) И макросы кстати используются, и свой менеджмент памяти... но ни одного goto там нету.

AIv ★★★★★
()
Ответ на: комментарий от AIv

Если не использовать goto, придется внедрять в функцию уйму if'ов, что сделает ее сильно запутанной. Мне проще с goto.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от AIv

«Если оно есть, значит, кому-то оно да нужно» ©

Насчет лиспа это еще справедливо... но не насчет goto.

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

dave ★★★★★
()
Ответ на: комментарий от AIv

так вот, goto ненужно!

Почему отцы ругали goto? Потому что большинство программистов - трудолюбивые обезьянки без абстрактного мышления. Подаёшь им подпрограммы - они их игнорируют, пишут всё в main, связывая всё в морской узел через goto. Подаёшь им продвинутый синтаксис для циклов - они ляпают if и goto. И всё катится в бездну уныния.

Об отвратительности goto говорили специально, чтобы приучить этот народ к более высокоуровневым конструкциям языка. Ведь программистам нужно создать догмы, религию, иначе они всё будут решать пчелиным трудолюбием. Нужно им внушить, что использовать goto не по-пацански, некошерно, Вирт не велел и т.д.

Но не всегда есть подходящие высокоуровневые конструкции. Пример - выход из вложенного цикла с с++. И вот тут-то goto уместно за неимением лучшего. Но у некоторых догмы полностью заменили собственный разум (так везде происходит, чего уж). И они лепят throw/catch, что гораздо уродливее и нелогичнее.

Так что любой может быть инструмент полезен, если знать применение всем остальным штуковинам из набора.

dmfd
()
Ответ на: комментарий от Eddy_Em

Не смешите мои тапочки... во вложенном цикле основные затраты на внутр. цикле, и лишняя проверка флага во внешнем цикле вообще никакой роли не играет.

Кстати, скорость разработки на питоне как мин на порядок превышает скорость разработки на С/C++, это медицинский много раз проверенный факт.

AIv ★★★★★
()
Ответ на: комментарий от AIv

Кстати, скорость разработки на питоне как мин на порядок превышает скорость разработки на С/C++, это медицинский много раз проверенный факт.

Зато работает оно на три порядка тормознутее!

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Обычно на один-два порядка тормознутее. Но напр. для интерфейса скорость работы НЕ имеет значения.

Для числ моделирования обычно ядро (то что должно работать быстро, но меняется сравнительно редко) пишется на C/C++/Fortran/Pascal и т.д., а оболочка (интерфейс, верхний управляющий уровень и пр. - то, что может работать медленно а меняется постоянно) на питоне. В итоге скорость работы получается как на С, скорость разработки на порядок выше.

AIv ★★★★★
()
Ответ на: комментарий от AIv

интерфейс, верхний управляющий уровень

Нафига всё это в численной модели? У наших программ вообще интерфейса нет, ни gui, ни cli. Едят конфигурационный файлик, шуршат некоторое время и выплёвывают пачку других файлов. Никакой питон не нужен.

dmfd
()
Ответ на: комментарий от dmfd

Интерфейс это не обязательно форточки, и даже не обязательно опции командной строки. Интефейс это механизЪм взаимодействия чего то с чем то.

А куда именно ваши программы выкидывают пачку других файлов? А насколько развесистые возможно у вашего конфигурационного файла?

Нашим программам никакие конфигурационные не нужны. Есть ядро на С++ оформленное в виде библиотеки, подключаемой в питон. Есть головной файл на питоне в котором задаются все параметры, инициализируются массивы, вызывается последовательность функций обеспечивающая расчет, вывод диагностики и т.д. С-но этот файл и является конфигурационным в т.ч.

AIv ★★★★★
()
Ответ на: комментарий от AIv

А насколько развесистые возможно у вашего конфигурационного файла?

Выглядит как-то так: http://pastebin.com/xznSSXm5 (На самом деле там может быть несколько файлов, все лень копипастить.)

А куда именно ваши программы выкидывают пачку других файлов?

Создают папку в рабочей директории (откуда вызвали). Название папки состоит из даты и некой дополнительной информации.

dmfd
()
Ответ на: комментарий от AIv

вызывается последовательность функций обеспечивающая расчет

А у нас эдакий Unix-way. Одна программа считает одно, другая берёт выхлоп первой и считает второе, и т.д.

dmfd
()
Ответ на: комментарий от dmfd

Ну и нафига вводить еще один формат (конфига) если есть питон? Не говоря о том, что бывают весьма нетривиальные настройки. Все таки питон довольно мощный ЯП, и возможностей у него куда больше чем у любого конфига.

А у нас эдакий Unix-way. Одна программа считает одно, другая берёт выхлоп первой и считает второе, и т.д.

А склеивается это все скриптами шелла? Ну а мы склеиваем питоном, тоже unix-way.

AIv ★★★★★
()
Ответ на: комментарий от AIv

Ну и нафига вводить еще один формат (конфига)

Буст и так используется. А тамошнее property_tree - довольно удобная вещь.

А склеивается это все скриптами шелла?

Разными этапами разные люди занимаются. Пока нет нужды чего-то склевать.

Не говоря о том, что бывают весьма нетривиальные настройки.

С помощью древовидной структуры с массивами можно много что сделать. Разве что алгоритмы не встроишь, но их и захардкодить не грех. А генерацию всякой дополнительной ерунды у нас каждый делает как хочет: кто на Mathematica, я на Maple в основном.

dmfd
()
Ответ на: комментарий от dmfd

Разными этапами разные люди занимаются. Пока нет нужды чего-то склевать.

У нас тоже разные люди, но склеивать уже приходиться.

С помощью древовидной структуры с массивами можно много что сделать. Разве что алгоритмы не встроишь, но их и захардкодить не грех.

И дальше вешать выбор алгоритма на переменную/ф-ю и тащить все это через буст? Вообще то алгоритмы выбора параметров бывают ну очень нетривиальные, и кодить их на питоне тупо быстрее чем на С. Да и логика верхнего слоя тоже бывает весьма нетривиальная, типа навороченный расчет выдает одно булево значение, и идет дихотомия по какому то параметру. В описанной архитектуре все делается довольно естественно, а как все это через конфиги и пр...

В моделировании сложные задачи трудно делать пользуясь возможностями одного ЯП - либо не хватает производительности, либо возможности ЯП ограничены. Народ придумывает разные конфиги, черти как изгаляется - я 100500 решений (велосипедов) видел. С/C++ и питон прекрасно друг друга дополняют, и эта связка прекрасно подходит для решения широкого круга задач.

AIv ★★★★★
()
Ответ на: комментарий от AIv

И дальше вешать выбор алгоритма на переменную/ф-ю и тащить все это через буст?

Не совсем понимаю, что это значит, но получение чего-то из конфига делается проще некуда:

using namespace misaki::config;
int foo = get("foobar.bar.foo", default_value);
float3 bar = get("foobar.bar.bar", float3(0, 0, 0));

типа навороченный расчет выдает одно булево значение

Моя программа на выходе делает ещё и конфиг для следующей. Только там не get, а put.

Ещё моя обёртка над конфигом умеет работать так:

misaki::config::CV<int> foo("node1.node2.foo", default_value);
foo += 1;
foo = 2+3;
int x = foo;
...

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

и эта связка прекрасно подходит для решения широкого круга задач.

Объединять код (последовательность вызовов) с данными нехорошо: незнакомый человек может нечаянно что-то поломать, да и незачем ему видеть код. А если их не объединять, получится простой конфиг, и питон уже не особо нужен. Это уже спор о вкусах.

dmfd
()
Ответ на: комментарий от dmfd

Не совсем понимаю, что это значит, но получение чего-то из конфига делается проще некуда:

Проще очень есть куда. Вот задание параметра:

//model.hpp
class model{
...
double a;
...
};
#run.py
from model import *
M = model()
...
M.a = 123
...
это самый тривиальный вариант, мы на питоне давно уже написали БД и набор ф-й, к-е дефолтом задают параметры, создают директорию под расчет (на основании даты, но не в текущей директории а в репозитории), сохраняют исходники расчета, делают выборки по базе и пр.

Но я то говорю про задания вызова метода в конфиге (напр тип инициализации). Через питон - просто вызываем соотв метод, через конфиг - пишем в переменную тип инициализации, а потом в плюсах как то это разруливаем. Особенно весело когда разные варианты имеют разный набор параметров. Конечно деревья это гибко, но, как я уже говорил - на питоне это просто банально быстрее пишется, причем ГОРАЗДО быстрее.

Объединять код (последовательность вызовов) с данными нехорошо

Почитайте напр. Горубнова-Посадова «Расширяемые программы» - не с т.з. описанных там технических решений, а с т.з. идей. В числ. моделировании разделить однозначно код и параметры невозможно. У-е или числ схема может отличаться знаком - это код или параметр? Последовательность вызовов ф-й - это код или параметр?

незнакомый человек может нечаянно что-то поломать, да и незачем ему видеть код.

Гыыы... за 15 лет, к-е я в эти игрушки играю, мне приходилось работать с чужими кодами конечно, но вообще то это страшшшная редкость. Коды обычно пишутся самостоятельно, о каких чужих людях Вы говорите? Если код «пошел по рукам», там уже есть внятная документация и какой никакой интерфейс для человека. А использование библиотек Вас кстати не смущает? ТОже ж вызовы делать приходиться;-)

А если их не объединять, получится простой конфиг, и питон уже не особо нужен.

Я вот не в курсе - в этом Вашем бустовом конфиге можно в качестве значения параметра задавать алгебраическое выражение из уже заданных параметров? В питоне можно, и я Вам скажу очень иногда удобно бывает.

Да и о чем спор то? Есть вариант С++-питон и С++-буст-конфиг. Понятно, что для опред набора задач они близки по возможностям. Но даже в этом наборе, ИМНО лучше то решение, которое дает больше свободы (про расширяемость я не говорю). В решении С++-питон границу (что на чем делать) каждый проводит сам. Ну и, повторюсь - приведенный Вами пример однозначно сложнее (больше букв и дольше пилится) чем вариант С++-питон.

Работал как то с весьма продвинутым но старым кодом для газ.динамики горения, код на фортране, 4000 строк одним куском. ПОЛОВИНА - парсинг конфига (с очень примитивным синтаксисом). Основным гемором было как то этим кодом рулить (надо было провести неск десятков тыс расчетов с весьма нетривиальным выбором параметров и анализом результатов)... уж я и генераторы этих конфигов писал, и пайпы прикручивал... в итоге плюнул, прогнал через f2c, выкинул весь парсинг, и прицепил это хозяйство в питон - сразу жизнь наладилась;-)

AIv ★★★★★
()
Ответ на: комментарий от AIv
 //model.hpp
class model{
...
double a;
...
};
#run.py
from model import *
M = model()
...
M.a = 123
...

Это что, питон прямо умеет брать hpp-шник, парсить и дёргать поля/методы? Без дополнительных телодвижений?

dmfd
()
Ответ на: комментарий от Eddy_Em

Гы.... я знаю, что можно сдлеать в С-шечке (в молодости и свои форматы конфигов писал, и свои парсеры чпециально для моделирования).... поверьте, в смысле моделирования связку питон-C/плюсы (ну или руби-фортран, перл-паскаль, на любителя) голой сишечкой не перешибешь. Т.е. примитивные вещи там ВОЗМОЖНО делаются и проще (от задачи зависит), но что то интересное - гораздо сложнее. Некоторые актуальные вещи делаются настока сложно, что приходиться или припахивать всякие утилиты для генерации тех же парсеров на сишечке, или... просто прикручивать питон;-)

AIv ★★★★★
()
Ответ на: комментарий от dmfd

Это что, питон прямо умеет брать hpp-шник, парсить и дёргать поля/методы? Без дополнительных телодвижений?

Есть макефайл, у меня он занимает в среднем 4ре строчки, типа:

name=model
headers=model.hpp
modules=model.cpp

include aivlib/Makefile
который при сборке дергает swig, который уже без лишних телодвижений парсит хидер, результаты потом собираются в so-шку (это все маке). А уж питон берет эту so-шку и дальше с ней работает как с родным модулем.

AIv ★★★★★
()
Ответ на: комментарий от AIv

Ну, не знаю: мне и примитивные, и сложные вещи намного проще в сях делать.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от AIv

swig

Ох, ну и дрянь…

А я Makefile'ы руками не пишу: даже на малюсеньком проектике получалась такая страшная штука, что перешел просто на cmake.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Ох, ну и дрянь…

Я пока ничего лучше не видел. Он конечно со своими глюками, но в целом весьма хорош, особенно если не выпендриваться с шаблонами и пр.

А я Makefile'ы руками не пишу: даже на малюсеньком проектике получалась такая страшная штука, что перешел просто на cmake.

Я пример своего Makefil-a привел. ЧТо, cmake проще будет О_О? Куда проще то - указали имя модуля, какие хидеры обрабатывать, какие сишники собирать...

AIv ★★★★★
()
Ответ на: комментарий от dmfd

У меня тоже неслабые шаблонные извращения.... ничего, справляется.

Ну с шаблонами конечно все сложнее - во первых их надо явно инстацировать (говорить swig-у с какими именно параметрами раскрутить), во вторых есть ряд ограничений, т.е. стандарт плюсов он скотина воспринимает не полностью. Как он к бусту отнесется не знаю... но обычно совсем страшные извращения просто выносятся в те модули, к-е swig не обрабатывает (или исключаются директивами условной компиляции #ifdef SWIG). Уж наскока коллеги с шаблонами изгаляются (компиляция до получаса, а иногда gcc просто харакири делает) - и то swig ест то, что нужно.

Если интересно, вот статья про swig http://a-iv.ru/pyart/cpp2py.pdf

AIv ★★★★★
()
Ответ на: комментарий от AIv

Не смешите мои тапочки... во вложенном цикле основные затраты на внутр. цикле, и лишняя проверка флага во внешнем цикле вообще никакой роли не играет.

Проверять надо и во внутреннем цикле - ведь мы из него собираемся выйти на самый верх. Да, время. Потом просто некрасиво.

Тут вопрос не в самом goto. Есть частная задача, нужно решение. Во многих языках для этого используют goto, в других - расширенный break или еще что-то там.

dave ★★★★★
()
Ответ на: комментарий от dave

Проверять надо и во внутреннем цикле - ведь мы из него собираемся выйти на самый верх.

Эээ... я наверное нечетко сформулировал. Есть условие с1 проверяемое во внутреннем цикле, есть условие с2 проверяемое во внешнем цикле. Если мы хотим выйти из внутреннего цикла и прервать при этом внешний, то во внешнем цикле кроме с2 проверяем еще флаг выхода, с1 при этом не меянется и ничего лишнего там не проверяется.

Нельзся сказать, что это более изящно чем goto. Но само возникновение подобной ситуации ИМНО говорит о том что с дизайном косяк. Есть ведь return и ф-ии в конце концов...

AIv ★★★★★
()
Ответ на: комментарий от AIv

С дизайном все нормально. Косяков нет. И я вижу, что это очень часто и заменяется отдельной функцией или методом, из которого выходят по return, но это возможно не всегда (не использовать же замыкание).

Возвращаюсь к обычным вложенным циклам, не вынесенным в отдельную функцию, просто представь, что уровень вложенности больше двух. Проблема сохраняется.

Вообще, по-моему этим озадачились еще в аде-83, и там есть какое-то изящное решение, но я его уже не помню. Есть хорошее решение в C# и по-моему в Java. Разумеется, в Си, Лиспе и Си++. Жаль, если нет в Питоне.

dave ★★★★★
()
Ответ на: комментарий от dave

Возвращаюсь к обычным вложенным циклам, не вынесенным в отдельную функцию, просто представь, что уровень вложенности больше двух. Проблема сохраняется.

Сколько угодно уровней вложенности - критичный по производительности самый нижний, а выше можно проверять какие угодно условия.

Жаль, если нет в Питоне.

Сходу не помню что бы было... но там вполне ес-но смотрятся исключения.

AIv ★★★★★
()
Ответ на: комментарий от AIv

Сколько угодно уровней вложенности - критичный по производительности самый нижний, а выше можно проверять какие угодно условия.

В общем, позиция более-менее ясна. По мне же лучше иметь готовое решение для этого случая. И я согласен с одним из предыдущих риторов, что вред от goto несколько преувеличен.

Сходу не помню что бы было... но там вполне ес-но смотрятся исключения.

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

dave ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.