Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Pythoncard question

4 views
Skip to first unread message

DarkBlue

unread,
May 4, 2006, 7:34:16 AM5/4/06
to
I am trying to port a Delphi database application
to python on linux with a firebird database backend
and I am using pythoncard to recreate the gui.

I will have about 25 delphi forms to
be recreated and I would like to know
what is the best way to call them up
from within each other .
There is a main screen where I must
be able to call up any of the subscreens
and on any given subscreen there would
be buttons to call up 1-5 of the other subscreens
or go back to the mainscreen.

The database is connected on the mainscreen
and relevant connections/cursors shall be accessible
from any of the subscreens.

While I am able to connect to the database and create the
different screens I am stumped at how to efficiently
call them up and pass the cursors between them as needed.

Sorry for the long post.


Thanks for any hint
Db

Michael Yanowitz

unread,
May 4, 2006, 8:00:47 AM5/4/06
to pytho...@python.org
I am still new to Python but have used it for the last 2+ months.
One thing I'm still not used to is that functions parameters can't
change as expected. For example in C, I can have
status = get_network_info (strIpAddress, &strHostname, &nPortNumber)
where this fictitious function returns a status, but also returns modified
values for a hostname and a port number.
In Python, there does not seem to be an easy way to have functions return
multiple values except it can return a list such as:
strHostname, nPortNumber, status = get_network_info (strIpAddress,
strHostname,
nPortNumber)
Am I missing something obvious? Is there a better, or more standard way
to return values from functions?

Thanks in advance:
Michael Yanowitz


bryan rasmussen

unread,
May 4, 2006, 8:13:17 AM5/4/06
to pytho...@python.org
Hi, I'm doing a sort of symbolic linking app in Windows for my own
enjoyment, and figured I would do it in python for the same reason +
learning the language.

The following functions could obviously do with some refactoring. One
obvious thing would be to make wordsetter and wordsforfolder more
generic, and just pass a few extra parameters. But that seems sort of
stupid.

Any suggestions on refactoring here? other improvements?


def getwordslist(word):
thisword = wordpath + word + ".xml"
if exists(thisword):
doc = xml.dom.minidom.parse(thisword)
loc = doc.childNodes[0]
for i in range(0, len(loc.childNodes)):
if (loc.childNodes[i].firstChild.data == thispath):
break
else:
wordsetter(thisword,doc,loc)

else :
doc = xml.dom.minidom.Document()
loc = doc.createElementNS("", "locations")
doc.appendChild(loc)
wordsetter(thisword,doc,loc)

return None

def getfolderwords(word):

if exists(normpath(folderwords)):
doc = xml.dom.minidom.parse(folderwords)
loc = doc.childNodes[0]
wordsforfolder(word,doc,loc)

else :

doc = xml.dom.minidom.Document()
loc = doc.createElementNS("", "wordlist")
doc.appendChild(loc)
xml.dom.ext.PrettyPrint(doc, open(normpath(folderwords), "w"))
wordsforfolder(word,doc,loc)

return None

def wordsetter(word,doc,loc):
thisloc = doc.createElementNS("", "location")
xexpr= "//location[.='" + thispath + "']"

xp = Evaluate(xexpr,doc.documentElement)
if len(xp) < 1:

loc.appendChild(thisloc)
text = doc.createTextNode(thispath)
thisloc.appendChild(text)
fi = open(word, "w")
fi.write(doc.toxml())


def wordsforfolder(word,doc,loc):
thisloc = doc.createElementNS("", "word")
xexpr= "//word[.='" + word + "']"

xp = Evaluate(xexpr,doc.documentElement)
if len(xp) < 1:

loc.appendChild(thisloc)
text = doc.createTextNode(word)
thisloc.appendChild(text)
fi = open(folderwords, "w")
fi.write(doc.toxml())

Cheers,
Bryan Rasmussen

bryan rasmussen

unread,
May 4, 2006, 8:15:37 AM5/4/06
to pytho...@python.org
oops, sorry about that. I copied the message over in gmail but forgot
to change the subject.


Sorry,
Bryan Rasmussen

Diez B. Roggisch

unread,
May 4, 2006, 8:35:25 AM5/4/06
to
Michael Yanowitz wrote:

No, that exactly is the way to go. But usually one uses tuples and the
possibility of sequence-unpacking together to reach a solution tha at least
to my eye looks more favorable:


def foo(a, b):
return a*b, a+c

a = 10
b = 20

a, b = foo(a, b)


Diez

Duncan Booth

unread,
May 4, 2006, 8:38:09 AM5/4/06
to
Michael Yanowitz wrote:

> In Python, there does not seem to be an easy way to have functions
> return
> multiple values except it can return a list such as:
> strHostname, nPortNumber, status = get_network_info (strIpAddress,
> strHostname,
> nPortNumber)
> Am I missing something obvious? Is there a better, or more standard
> way
> to return values from functions?

The only obvious thing you are missing is that you don't pass in values
which are only results. Duplicating the parameters and results as you have
above would be unlikely to happen very much in practice.

Oh, and it doesn't return a list, it actually returns a tuple but it is
easiest just to think of your function as just returning three results.

Returning additional results is better than rebinding parameters because it
makes it really clear at the point of calling which variables are
parameters and which are results.

The other not very pythonic thing about your example is that it returns a
status code: Python largely tends towards using exceptions rather than
status codes, so if in C you had:

switch ((status=get_network_info(addr, &host, &port)) {
case S_OK:
break;
case ERROR_1:
... handle error ...
break;
case default:
... handle other errors ...
};

In Python you would have something like:

try:
host, port = get_network_info(addr)
except ERROR_1:
... handle error ...
except:
... handle other errors ...

which means you can handle the error either right next to the call or at
some outer level (you don't have to manually propogate your status), you
can't accidentally forget to check the status code, and the actual call is
much simpler and clearer (especially if the error is handled at some outer
level).

Tim Chase

unread,
May 4, 2006, 8:45:13 AM5/4/06
to m.yan...@kearfott.com, pytho...@python.org
> In Python, there does not seem to be an easy way to have
> functions return multiple values except it can return a
> list such as: strHostname, nPortNumber, status =
> get_network_info (strIpAddress, strHostname, nPortNumber)
> Am I missing something obvious? Is there a better, or
> more standard way to return values from functions?

This *is* the "better" and "standard" way to do it. There
are *worse* ways to emulate C/C++ if you want, but it takes
being *more* obtruse. Because certain objects are mutable,
nothing[*] prevents you from doing something like

x = []
def foo(q):
x.append(42)
foo(x)
print repr(x)

which will return that you've added "42" to your list.
However, it's ugly and relies on side effects.

They Python way (that you deride) is much clearer. Your
input goes in the parameters, and your output gets assigned
the way functions are intended to work. Unambiguous.

I don't expect to call a sine function, and get the result
in the parameter; rather I expect to get it as the result of
the function. Okay...unless I'm working in Assembly
language (but that's one of many reasons *why* I choose
Python ;)

Just a few thoughts,

-tkc
[*] nothing other than being given dirty looks by folks
reading your code...


Roy Smith

unread,
May 4, 2006, 8:57:00 AM5/4/06
to
In article <mailman.5325.1146746...@python.org>,
Tim Chase <pytho...@tim.thechases.com> wrote:

> They Python way (that you deride) is much clearer. Your
> input goes in the parameters, and your output gets assigned
> the way functions are intended to work. Unambiguous.

It's probably worth mentioning that the only reason C/C++ uses pointer
arguments to return multiple values is because in the early versions of C,
a function could not return a struct, so passing in pointers was the only
way to return multiple values.

Don't turn something which was forced upon us by a historical compiler
limitation into something you want to emulate in other langauges which have
better solutions to the problem.

bruno at modulix

unread,
May 4, 2006, 9:18:50 AM5/4/06
to
Michael Yanowitz wrote:
> I am still new to Python but have used it for the last 2+ months.
> One thing I'm still not used to is that functions parameters can't
> change as expected.
>
> For example in C, I can have
> status = get_network_info (strIpAddress, &strHostname, &nPortNumber)

You have to understand that Python and C are totally different beasts.

A C variable is mostly symbolic name for a memory address, tagged with
type infos. Assigning to a variable means storing a value at this
address. Reading a variable means retrieving whatever value is stored at
this memory address.

Python does not in fact have a concept of "variables". It has names and
objects. A binding is the association (in a hash table) of a symbolic
name (which is nothing more than a name) and a reference (read:
something like a smart pointer) to an object (which is itself a complex
data structure). So-called "assignement" (correct term is "binding")
'binds' together a name and a reference to an object. Except for some
special cases (mainly objects - which are they're own namespaces - and
when using the 'global' statement), this creates an entry in the current
namespace. Also, rebinding a name has no effect on other names bound to
the same object.

Function's params are bindings in the function's local namespace. This
means that the params *names* are local to the function. So rebinding a
param in a function won't have no effect on bindings in the caller's
namespace.

*But* - since many names can refer to the same object - *modifying* the
object referenced by a name will, well, modify this object, so this
modification will be visible everywhere.

ie (dummy example):

def appendToList(alist, what):
alist.append(what)

mylist = []
appendToList(mylist, 42)
print mylist

What doesn't work as you'd expect is:

def failsToHaveSideEffects(alist, anything):
print "before rebinding : alist = ", alist, " - anything = ", anything
alist = anything
print "after rebinding: alist = ", alist

mylist = []
print "before function call, mylist = ", mylist
failsToHaveSideEffects(mylist, 42)
print "after function call, mylist = ", mylist


So as you can see, it's quite possible for a function to *modify* it's
params - it's just rebindings of params that won't have side effects
outside the function's namespace.

Now, there is the case of immutable types (int, strings, tuples, ....).
As implied, one cannot modify objects of these types - just create them.
So in order to have a function that "change the value" of an immutable
object, you have to wrap it into a mutable object, ie:

def getAnswer(alist):
alist[0] = "42"

answer = ["answer is ?"]
getAnswer(answer)
print "answer is : ", answer[0]

(snip)

> In Python, there does not seem to be an easy way to have functions return
> multiple values except it can return a list such as:
> strHostname, nPortNumber, status = get_network_info (strIpAddress,
> strHostname,
> nPortNumber)
> Am I missing something obvious? Is there a better, or more standard way
> to return values from functions?

This *is* the 'standard' (ie: idiomatic) way to return multiple values
from a function. The C idiom of passing pointers to variables that are
to be modified comes from C's limitations, namely no exception handling
and only one return value[1], which leads to using the return value as a
status report and relying on side effect for useful values.

[1] To be pedantic, Python only allows one return value too - but this
value can be a tuple or list, and then one can take advantage of
tuple/list expansions that allows multiple assignment...

HTH
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'on...@xiludom.gro'.split('@')])"

Sion Arrowsmith

unread,
May 4, 2006, 11:01:33 AM5/4/06
to
Michael Yanowitz <m.yan...@kearfott.com> wrote:
> In Python, there does not seem to be an easy way to have functions return
>multiple values except it can return a list such as:
>strHostname, nPortNumber, status = get_network_info (strIpAddress,
>strHostname,
> nPortNumber)
> Am I missing something obvious? Is there a better, or more standard way
>to return values from functions?

I'm kind of repeating what other people have said, but there
isn't a better way. Not just in Python, but in any language.
If your function is returning multiple values, why should you
have to split them into one privileged "return value" plus a
bunch of Out (or InOut) parameters? That's a historical mis-
feature of older languages, and one which more newer languages
would do well to fix.

--
\S -- si...@chiark.greenend.org.uk -- http://www.chaos.org.uk/~sion/
___ | "Frankly I have no feelings towards penguins one way or the other"
\X/ | -- Arthur C. Clarke
her nu becomeþ se bera eadward ofdun hlæddre heafdes bæce bump bump bump

0 new messages