Re: lists and dictionaries

2007-07-11 Thread anethema

> li =  [ {'index': 0, 'transport': 'udp', 'service_domain':
> 'dp0.example.com'},
> {'index': 1, 'transport': 'udp', 'service_domain':
> 'dp1.example.com'},
> {'index': 0, 'transport': 'tcp', 'service_domain':
> 'dp0.example.com'},
> {'index': 1, 'transport': 'tcp', 'service_domain':
> 'dp1.example.com'}]

I like this solution:

[{ 'transports': [d['transport'] for d in li if
d['service_domain'] == dom],
   'service_domain': dom,
 } for dom in set(d2['service_domain'] for d2 in li)]

merely because it takes one line.  Humorously enough, it appears to be
twice as efficient, at least when profiled on my computer, if speed is
important in this problem.  Not that this is the best way to do it
either.

Anyway, since the generator expression isn't very clear:

def indexBasedToSDBased(li):
newli = []
# For each service domain in the set read from the original list
for sdom in set(d['service_domain'] for d in li):
# Append a new dictionary mapping all transports for this
domain
newli.append({
'service_domain': sdom,
'transports': [d['transport'] for d in li if
d['service_domain'] == sdom]
})
return newli

(which is slower than the one-line generator :-D  I love generator
expressions)

  - Jeremy

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Imported globals?

2007-07-27 Thread anethema
> It seems that in the first case change_value() called in module_b.py
> ignores the global statement. Is it so? Why? What happens in the second
> case? I really don't get it.

The key is that it doesn't ignore the global statement, but that
global specifically points to the variable 'value' in module A's
namespace.  That is, even though you call change_it() from module B,
it acts on the variable in module A, not B, even though 'value' exists
in B.

consider the following modules:

module_a.py
value = 'initial'

def change_it():
global value
value = 'changed'

def print_it():
print "In module A:", value

print_it()

module_b.py
from module_a import value, change_it, print_it as a_print_it()

def print_it():
print "In module B:", value

print_it()
change_it()
a_print_it()
print_it()


$> python module_b.py
In module A: initial
In module B: initial
In module A: changed
In module B: initial

Here we see that a) print_it() was executed in module A before the
code in module B ran; This happens at import.  b) after change_it()
was executed, 'value' in module A was changed, while 'value' in module
B was left alone.

This demonstrates how the modules have separate namespaces, but also
hinges on the fact that strings are immutable, as star.public
mentions.  'value' in both namespaces do refer to the same object.
What's significant is the action on the method change_it().  For
example,

def change_it():
value = 'changed'

this would do no good at all, as you may have realized, as it merely
assigns the string 'changed' to the name/variable 'value' in the
function namespace.  If there is an assignment to a variable in a
function (not an attribute of some other variable), such as 'a = 2',
the interpreter assumes that the function is declaring a new
variable.  We need to explicitly declare the variable global first.
If we don't, and try to treat it global, the above useless function
can result, or the following

def change_it():
if value == 'initial':
value = 'changed'

which results in a UnboundLocalError, since, defaulting to using
'value' as a local variable (since we have the assign statement `value
= 'changed'`), and we attempt to use the local var before assigning it
a value.

For mutable objects, such as a list, or classes (and their
attributes), the result would be different.

module_a.py
value = ['initial']

def change_it():
value[0] = 'initial' # don't need the 'global value', since
we're accessing attributes
 # of 'value', not directly accessing
value

def print_it():
print "In module A:", value[0]

print_it()

module_b.py
from module_a import value, change_it, print_it as a_print_it

def print_it():
print "In module B:", value[0]

print_it()
change_it()
a_print_it()
print_it()

$> python module_b.py
In module A: initial
In module B: initial
In module A: changed
In module B: changed


In this case, the two module namespaces still each contain a reference
to the same object.  What we did differently is change the object
itself, instead of the reference.  If change_it() assigned to value,
`value = ['changed']`, we would see no different behavior than in the
first case.


Sorry if that was overly winded.  scope and namespaces are tricky (at
least for me) to explain.
  - Jeremy

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: udp, datagram sockets

2007-08-06 Thread anethema
On Aug 6, 1:27 pm, Carsten Haese <[EMAIL PROTECTED]> wrote:
> On Mon, 2007-08-06 at 09:03 -0700, 7stud wrote:
> > server:
> > --
> > import socket
> > import sys
>
> > s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
> > s.bind(("", ))
> > [...]
> > #Send messages back to client:
> > total_sent = 0
> > while total_sent < len(message):
> > print "debug: send while loop"
>
> > size_sent = s.sendto(message[total_sent:], ("localhost",
> > ) )
> > total_sent += size_sent
>
> > print "debug:", total_sent, len(message)
>
> I don't think that sending the datagram to port  on localhost sends
> the message back to the client. I'm guessing the server is sending the
> message back to itself, which throws it into the infinite feedback loop
> you're experiencing.
>
> HTH,
>
> --
> Carsten Haesehttp://informixdb.sourceforge.net

Yes, you want to use the socket.recvfrom() method, store the address,
and send the response to that address.  Your code is indeed repeatedly
sending itself the received message.

You want to change
> > data  = s.recv(1024)
to
data, recv_addr = s.recvfrom(1024)

and
> > size_sent = s.sendto(message[total_sent:], ("localhost",
> > ) )
to
size_sent = s.sendto(message[total_sent:], recv_addr)

However, your client closes immediately after sending all its data, so
it will never receive that message.

-- 
http://mail.python.org/mailman/listinfo/python-list