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?

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

А
import название_файла
позволит подключить функцию getParameters? А то я ее из другого скрипта запускаю.

Конечно. Только вызывать надо module_name.getParameters().

Или можно сделать from module_name import getParameters и вызывать просто по имени. Но это, как бы, плохой стиль.

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

Да. 'название_файла' в этом случае должно быть либо в одной директории с основным скриптом, либо лежать в ${PYTHONPATH}. Можно еще в поддиретории класть но тогда в них надо создавать файл __init__.py и использовать другую структуру импорта:

 import subdir_name.script_name
fat_angel ★★★★★
()
Ответ на: комментарий от schizoid

можно сделать from module_name import getParameters и вызывать просто по имени. Но это, как бы, плохой стиль.

Вовсе нет, плохой стиль это: from module_name import *, и то не всегда.

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

Обнаружил в чем проблема: окно даже не успевает показаться, как функция getParameters возвращает пустой массив. Таки нужно как-то ждать окончания ввода.

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

Какое все-таки говно этот ваш питон!

Вообще жесть, а не язык: типы переменных не определяются, в массиве может храниться свалка, от форматирования зависит логика программы…

Нет уж…

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

Здесь это звучит буквально так: Взять нечто(функцию класс, другой модуль) с именем Parameter из модуля module_name и именовать дальше как Parm. Иногда полезно использовать.(например если Parameter имя другого модуля и его каждый раз надо писать... или когда уже такое имя закреплено за другим объектом)

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

К фрикаду документации почти нет. И как к нему прикрутить сишный функционал - непонятно.

На питоне по крайней мере есть примеры. Да и консоль у него питоновская (правда, конечно, можно выполнять из питона любой бинарь…)

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

Да ладно. «Забью» на то, что не понимаю: в питоновской консоли работает - и хватит. А если уж кому GUI нужно будет - нехай сам лепит. Я и так уже чуть клавиатуру от злости не расколотил из-за этого скотского питона, кактус в задницу его создателю!

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

Ну пц., почитайте ченьть по основам гуи на python+gtk.

У вас куча куча каких-то невообразимых ошибок.

C фрикадом не сталкивался и не понимаю что вам конкретно надо, типа этого чтоли

#!/usr/bin/python
# coding: utf-8
import gtk

class MyWin:
	def __init__(self, labels=None):
		window = gtk.Window(gtk.WINDOW_TOPLEVEL)
		window.set_title("Table")
		window.connect("destroy", self.delete_event)
		vbox = gtk.VBox(False, 5)
		window.add(vbox)
		self.edits = []
		for label in labels:
			box = gtk.HBox(False, 5)
			vbox.pack_start(box, True, True, 0)
			edit = gtk.Entry()
			glabel = gtk.Label(label)
			box.pack_start(glabel, False, False, 0)
			box.pack_end(edit, True, True, 0)
			self.edits.append(edit)
		box = gtk.HBox(False, 5)
		vbox.pack_start(box, True, True, 0)

		button = gtk.Button("OK")
		button.connect("clicked", self.ok)
		box.pack_start(button, False, False, 0)

		button = gtk.Button("Cancel")
		button.connect("clicked", self.no)
		box.pack_start(button, True, True, 0)

		window.show_all()


	def ok(self, widget):
		print "O.K.!"
		allvals = []
		for e in self.edits:
			value = e.get_text()
			if value:
				allvals.append(value)

 		print ', '.join(allvals)


	def no(self, widget):
		print "Cancel!"
		gtk.main_quit()


	def delete_event(self, widget):
		gtk.main_quit()


if __name__ == "__main__":
	alllab = ("label1", "label2", "label3")
	MyWin(labels=alllab)
	gtk.main()

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

Мне из этой штуки надо вернуть параметры, введенные пользователем. А параметры используются в другом модуле. В этом-то и проблема: freecad либо сразу же закрывает окно, либо открывает его, но возвращает основной функции управление.

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

Примеры фрикадовских диалогов есть (правда, на дурацких кутях). Но там все введенные пользователем значения остаются внутри функции, а не передаются «наружу».

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

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

Импортируйте ваш исполняющий модуль(CopyTools.py как я понимаю?) в эту гуйню

А, пригляделся - у вас всё ровно наборот, гуйня в CopyTools импортируется.Ну это неверно имхо, хотя можно и так.

Например это типа ваш CopyTools

#!/usr/bin/python
# coding: utf-8
import getGUIParams
alllab = ("label1", "label2", "label3")
getGUIParams.runner(alllab)
print getGUIParams.allvals
вышеприведённый пример назовем как и у вас, getGUIParams, только вот небольшие изменения
--- getGUIParamsOLD.py	2012-06-15 10:49:41.935701007 +0400
+++ getGUIParams.py	2012-06-15 10:52:49.479701001 +0400
@@ -2,6 +2,8 @@
 # coding: utf-8
 import gtk
 
+allvals = []
+
 class MyWin:
 	def __init__(self, labels=None):
 		window = gtk.Window(gtk.WINDOW_TOPLEVEL)
@@ -34,13 +36,12 @@
 
 	def ok(self, widget):
 		print "O.K.!"
-		allvals = []
 		for e in self.edits:
 			value = e.get_text()
 			if value:
 				allvals.append(value)
 
- 		print ', '.join(allvals)
+		gtk.main_quit()
 
 
 	def no(self, widget):
@@ -52,9 +53,8 @@
 		gtk.main_quit()
 
 
-if __name__ == "__main__":
-	alllab = ("label1", "label2", "label3")
-	MyWin(labels=alllab)
-	gtk.main()
-
+class runner:
+	def __init__(self, alllab):
+		MyWin(labels=alllab)
+		gtk.main()
 

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

Сделал так:

import sys
import pygtk
pygtk.require('2.0')
import gtk
#import FreeCAD, FreeCADGui

allvals = []

class MyWin:
	def __init__(self, labels, title):
		window = gtk.Window(gtk.WINDOW_TOPLEVEL)
		window.set_title(title)
		window.connect("destroy", self.delete_event)
		vbox = gtk.VBox(False, 5)
		window.add(vbox)
		self.edits = []
		for label in labels:
			box = gtk.HBox(False, 5)
			vbox.pack_start(box, True, True, 0)
			edit = gtk.Entry()
			glabel = gtk.Label(label)
			box.pack_start(glabel, False, False, 0)
			box.pack_end(edit, True, True, 0)
			self.edits.append(edit)
		box = gtk.HBox(False, 5)
		vbox.pack_start(box, True, True, 0)
		button = gtk.Button("OK")
		button.connect("clicked", self.ok)
		box.pack_start(button, False, False, 0)
		button = gtk.Button("Cancel")
		button.connect("clicked", self.no)
		box.pack_start(button, True, True, 0)
		window.show_all()
	def ok(self, widget):
		print "O.K.!"
		global allvals
		for e in self.edits:
			value = e.get_text()
			if value:
				allvals.append(value)
 		gtk.main_quit()
	def no(self, widget):
		print "Cancel!"
		gtk.main_quit()
	def delete_event(self, widget):
		gtk.main_quit()

class runner:
	def __init__(self, alllab, atitle='Title'):
		MyWin(labels=alllab, title=atitle)
		gtk.main()

#~ def getNparametersFromWindow(labels, title='Title'):
	#~ MyWin(labels, title)
	#~ gtk.main()
Вызваю так:
		from getGUIparams import runner as getWinPars
		from getGUIparams import allvals as L
		FreeCAD.Console.PrintMessage("CopyVec activated!\n")
		getWinPars(["a","b","c","d"])
		is_array = lambda var: isinstance(var, (list, tuple))
		if (is_array(L) and len(L) != 4):
			return
		try:
			N = int(L[0].text())
			dx = float(L[1].text())
			dy = float(L[2].text())
			dz = float(L[3].text())
		except:
			FreeCAD.Console.PrintError("Wrong input! Only numbers allowed...\n")
		else:
			copyVec(N, Base.Vector(dx,dy,dz))
Фигвам. Не работает. И при нажатии на «кнопки» в первый раз окно все равно не закрывается, а при втором нажатии фрикад падает.

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

жесть, а не язык

с таким подходом ничего не получится у вас. :) Настройтесь на позитив и читайте маны.

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

Какое все-таки говно этот ваш питон!

Создатели brainworkshop должны быть, по логике, умными ребятами, но он написан на питоне. Хм..

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

Да ужас же: скопипастишь код, где отступы пробелами; сделаешь отступы табами (у меня везде так) - фигвам.

Нет switch'а - это жесть!
Классы… Нафиг?
Нет типов данных.
Нет указателей в явном виде.

В общем, дрянной язык.

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

Нет switch'а - это жесть!

хуже того... GOTO НЕТУ!!!! 11111111111;-)

А чего, Tkinetr не подойдет? А то у меня под него есть феня для создания форточек с параметрами.

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

GOTO НЕТУ!

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

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

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

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

В общем, дрянной язык.

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

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

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

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

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

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

Нет switch'а - это жесть!

Косяк конечно, но if'ов обычно хватает.

Классы… Нафиг?

Не осилившим ООП, разрешаю классами не пользоваться.

Нет типов данных.

Все там есть — это тебе не баш, man утиная типизация.

Нет указателей в явном виде.

Указатели в скриптовом языке? Да ты в конец упоролся!

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

Какое все-таки говно этот ваш питон!

лучше руки распрями вместо матюканий

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

Я и так уже чуть клавиатуру от злости не расколотил из-за своей тупости, кактус в задницу мне за то что плохо учился в институте!

// поправил

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

Да ужас же: скопипастишь код

и правда - ужас

такие вот как ты «умельцы» тот FreakAD писали и теперь ты злишься, а надо бы задуматься :)

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

Нет switch'а - это жесть!

есть, и это не жесть в любом разе

Классы… Нафиг?

ну есть же, ну

Нет типов данных.

есть, не пясди

Нет указателей в явном виде.

они тебе не нужны здесь

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

а для тех у кого баттхёрт по поводу слова switch можно написать класс из десятка строчек и будет как в такой родной и такой знакомой сищечке

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

Указатели в скриптовом языке? Да ты в конец упоролся

Это ты упоролся! А как передавать в функцию массив и менять его значения?

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

Чувак, в институте я отлично учился. Только какая связь может быть у астрофизика с говнопитоном?

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

Хрена с 2 это, а не switch!

Как сделать так:

switch (a){
    case 1:
        do_someth();
    case 2:
        do_more();
    break;
    case 3:
        do_three();
    default:
        do_four();
}
?

break'и здесь пропущены не случайно!

Вот такую конструкцию я хотел в питоне сделать. Но этот недоязык так не умеет. А когда у тебя с десяток проверок, как-то if'ами задолбаешься расписывать. Пришлось повторять куски кода.

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

А как передавать в функцию массив и менять его значения?

В пайтоне все предается по ссылкам

nkt@arnor ~ % python
Python 2.7.3 (default, Jun 16 2012, 11:07:05) 
[GCC 4.5.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> ar = ['a', 's', 'd', 'f']
>>> def f(v):
...   v[2] = 'ololo'
... 
>>> f(ar)
>>> ar
['a', 's', 'ololo', 'f']

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

какая связь может быть у астрофизика с говнопитоном?

например, такая: http://www.astropython.org/

PS и если ты астрофизик-и-точка то не выставляй себя идиотом комментируя то в чём не разбираешься нифига

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

Как сделать так:

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

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

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

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

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

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

Я вот о чем, как сделать на питоне так:

void f(type **x){
  f1(x[0]);
  f2(x[1]);
  f3(x[2]);
  f4(x[4]);
}
type a1, a2, a3, a4;
type *b[4] = [ &a1, &a2, &a3, &a4 ];
f(b);
…
?

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

Слушай, ты почитай хотя бы исходный пост темы!

Я сразу сказал: мне этот питон 7 лет не втарахтелся, но т.к. во фрикаде используется питон для скриптования, я задал вопрос: как сделать «формочку» на этом языке.

А тут сразу пошли метания говна…

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

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

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

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

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

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

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

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

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

я задал вопрос: как сделать «формочку» на этом языке.

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

и да, я вообще не понимаю как можно задавая ламеркие вопросы одной рукой другой рукой с серьёзным видом рассуждать что там говно, а что нет

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

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

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

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

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

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


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

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

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

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

и да, я вообще не понимаю как можно задавая ламеркие вопросы одной рукой другой рукой с серьёзным видом рассуждать что там говно, а что нет

Будто ты меня не знаешь. Это же моя «мирдверьмячная» натура ☺

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

А я и не удивляюсь особо. ЛОР - он такой: из любого вопросика можно срач развести. А этот вопрос я бы удалил (все равно, толку 0 - надо либо забить, либо на сях попытаться сделать .so, которую из питона вытаскивать). Да не могу уже удалить.

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

Я вот о чем, как сделать на питоне так

def f(x) :
    f1(x[0])
    f2(x[1])
    f3(x[2])
    f4(x[4])

a1, a2, a3, a4 = type(), type(), type(), type()
b = [a1, a2, a3, a4]
f(b)

будет работать если type изменяемый тип (я так понимаю что f1-4 меняют свои аргументы).

Но питон - это не С, и не надо писать на нем как на С. Все таки питон гораздо изящней и лаконичней, привычка управлять бульдозером не повод жаловаться, что дескать у нормальной бэхи с автоматом вместо рычагов руль и странная ручка;-)
AIv ★★★★★
()
Ответ на: комментарий от Eddy_Em

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

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

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

Т.е. приравнивание b = [a1, a2, a3, a4] в этом случае не поместит в b копии?

Вот в том-то и проблема: слишком уж питон легкомысленный язык. Никакой строгой типизации… Как в нем что-то делать - не представляю…

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

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

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

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

это можно, но не для форточек. Форточки рисуются на питоне гораздо проще чем на С. Попробуйте Tkinter... вот я тут че то писал http://a-iv.ru/pyart/myTkinter.pdf

Вот пример кода относящегося к форточке (это ВЕСЬ код к-й относится к форточке):

   if not dialog_tree( calc.path, calc, 
                        [( 'физические параметры', 
                           { '00':('температура T','.T',16), 
                             '01':('коэффициент диссипации gamma',
                                   '.gamma',16), 
                             '02':('постоянное внешнее поле Hext',
                                   '.Hext',4),
                             '03':('амплитуда переменного внешнего поля Aext',
                                   '.Aext',4),
                             '04':('частота  переменного внешнего поля Omega',
                                   '.Omega',16),
                             '05':('линейная анизотропия','.K2',16), 
                             '06':(' ось','.axe2',4),
                             '07':('кубическая анизотропия','.K4',16), 
                             '08':(' ось','.axe4',4)
                             } ),
                         ( 'начальные условия', 
                           { '00':('начальное значение','.init_value'),
                             '01':(1, '.init_method', ('дельта функция',0), 
                                   ('сферическое распределение',1), 
                                   ('распределение Больцмана',2), 
                                   ) }),
                                          
                         ( 'численные параметры', 
                           { '00':('шаг по времени h','.h'),
                             '01':('вывод каждые nsteps','.nsteps'), '11':'шагов',
                             '02':('время установления колебаний t_relax','.t_relax'),
                             '03':('время расчета Фурье-образа Delta_t','.Delta_t'),
                            '04':'общее число шагов в расчете %(steps_count)g',
                             '05':('подобрать параметры автоматически',mk_ht)
                             } ),
                         ( 'функции распределения', df_gui ) ] ) : sys.exit()
и скриншоты http://a-iv.ru/trash/spm-gui1.png http://a-iv.ru/trash/spm-gui2.png http://a-iv.ru/trash/spm-gui3.png http://a-iv.ru/trash/spm-gui4.png

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

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

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

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

Примеров формирования окон я уже 100500 видел. У меня проблема с тем, как передать полученные данные в другую функцию, вызывающую функцию, отрисовывающую эту «форточку».

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

Я смотрел код некоторых фрикадовских плагинов, вызывающих окна - там формирование окна было внутри функции. Как только мы этот плагин запускаем, и он отрисовывает окно, происходит передача управления обратно фрикаду. Окно работает уже как отдельный поток. А когда уже данные введены, внутри этой функции с окном происходят нужные вычисления и добавление элементов на чертеж.

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

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от 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

слишком уж питон легкомысленный язык. Никакой строгой типизации…

Вы не поверите... но разработчики считают Питон СТРОГО ТИПИЗИРОВАННЫМ ЯП. Я правда с ними не согласен, но это во первых ИМНО, во вторых терминологические споры совершенно бессымсленны (по определению;-)).

Примеров формирования окон я уже 100500 видел.

Таких лаконичных - вряд ли;-)

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

А вот с этим конечно будут проблемы. Я тут не специалист, но наверное это будет зависеть от пакета в к-м происходит рисование. В Tkinter свои фенечки для разрулирования этого вопроса (тамошней цикл обработки событий нельзя запускать не в главном потоке, поэтому приходиться немного извращаться). Но это решается.

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