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

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

Буст и так используется. А тамошнее 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 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.