Favorite non-python language trick?

G

George Sakkis

Konstantin Veretennicov said:
If they go to itertools, they can simply be:

def map(f, *iterables):
return list(imap(f,*iterables))

def filter(f, seq):
return list(ifilter(f,seq))
from itertools import ifilter
def filter(f, seq): ... return list(ifilter(f,seq))
filter(str.isalpha, 'not quite!') ['n', 'o', 't', 'q', 'u', 'i', 't', 'e']
__builtins__.filter(str.isalpha, 'not quite!')
'notquite'

Oops ! I've used filter only with lists and didn't know that it
preserves the type for strings and tuples. Here's a (hopefully) correct
version:

def filter(f,seq):
it = ifilter(f,seq)
if isinstance(seq,basestring):
return ''.join(it)
elif isinstance(seq,tuple):
return tuple(it)
else:
return list(it)


By the way, the documentation of filter is unclear on what is the
return type if seq is a subclass of list, tuple, str, or unicode; is it
type(seq) or the base builtin type ? Let's see:

def subclassFactory(cls):
return type("Dummy_" + cls.__name__, (cls,),
{'__new__' : lambda self, seq: cls.__new__(self, seq)})

baseToSub = dict([(base,subclassFactory(base))
for base in list,tuple,str,unicode])

f = lambda x: x.lower()
for Base,Sub in baseToSub.iteritems():
assert type(__builtins__.filter(f, Sub('lowerUPPERCap'))) is Base

for Base,Sub in baseToSub.iteritems():
for cls in Base,Sub:
args = (f, cls('lowerUPPERCap'))
assert filter(*args) == __builtins__.filter(*args)


George
 
G

GodFoca

I'm curious -- what is everyone's favorite trick from a non-python
language? And -- why isn't it in Python?

Hmm... I used to be quite the fan of Python, yet not long ago I met
Ruby and fell in love almost instantly. Some of the features I like the
most:

- statement modifiers:

< "return a if a.value == true"
< "database.query(q) unless database.connect == error
(etc)

- unless as "if not", since it gives nicer code to read

< unless false then print 1 # this prints 1 forever

- iterators, such as times (already mentioned)

- 'case'

< case var
< when 3 then do_sth
< when 4 then do_sth_else
< # etc...
< end

- everything returns a value, so you can do:

< foo = case foo2
< when 1 then yadda_yadda
< when 2 then blah_blah
< # etc
< end

And when foo2 == 2 then "blah_blah" gets executed and returned as the
'case' return value, thus assigning foo the value that results from
evaluating blah_blah

And some more, but those are the ones I like the best and python
doesn't have :)

- greetings -
Nicolas
 
D

Devan L

< "return a if a.value == true"
< "database.query(q) unless database.connect == error
(etc)

if a.value == True:
return a

if not database.connect == error:
database.query(q)

Trading two words for one word doesn't necessarily make the code
better.

< unless false then print 1 # this prints 1 forever
while not False:
print 1

"unless" seems to become "while not", as opposed to "if not". Should be
more consistent.
 
B

Bengt Richter

]
The single line replacing
"""
with colour do begin
red := 0; blue := 255; green := 0;
end;
"""
follows:


The point is that a hypothetical "with" block would have to allow
arbitrary access to dotted names: getting, setting, deletion, and method
calling, not just one very limited form of keyword assignment. Point taken.

I understand how to manipulate __dict__ as an more complicated (dare I say
obfuscated?) way of assigning to object attributes.
Yes, it's a bit obfuscated.

[snip]
We can clear those attributes from the instance dict:
{}

Which has the unfortunate side effect of also destroying any other
instance attributes.
You wouldn't do something unfortunate, would you? ;-)
I just wanted to clear them all at that point in the interaction.
you might do this:

with myobject:
# read a class attribute
print .__class__.myattribute
# set an instance attribute
.widget.datapoints[.collector] = .dispatcher(.widget.current_value)

def mywith(o=myobject):
# read a class attribute
print o.__class__.myattribute
# set an instance attribute
o.widget.datapoints[o.collector] = o.dispatcher(o.widget.current_value)
mywith()
[snip]

Is a one-character prefix to the dot objectionable?

That's a good workaround, subject to namespace pollution issues, and one
that I'm aware of. Although do you really want to be creating a unique
function definition every time you want to use the with idiom?
The only thing, ISTM, that would not also be unique in the with construct
is the function name, and you snipped the anonymnous def version that would
eliminate that. The main question in my mind would be binding of non-leading-dot
names. Would they work as in the suite of an "if" (i.e., binding in the same scope)
or as in a function with a new local scope that disappears on exit?

A function solves the alias name pollution problem, but prevents rebinding
anything external except explicitly declared globals, and closure cell vars
can't be rebound currently.
I'm not about to stop using Python because of the lack of Pascal-like
"with" blocks. It is a nice feature to have, but I'm aware that Guido
prefers explicit to implicit and "with" is extremely implicit.
I wonder what happens when you have multiple withs, e.g.,

with obj_a:
.x = 1
with obj_b:
.x = 2
.y = 3

(I guess you would have to have a stack with only the latest with effective).
whereas a simple aliasing syntax like

(a=obj_a, b=obj_b):
a.x = 1
b.x = 2
b.y = 3

is unambigous and concise and the scope of the namescan be limited
to prevent name pollution at compile time.

OTOH, what should
(a=obj_a):
a = 123 # XXX ??
mean? Should it mean obj_a=123 and rebind in that scope,
like a macro substitution of names at compile time?
I guess the corresponding with thing would be
with obj_a:
. = 123




Regards,
Bengt Richter
 
B

Bengt Richter

oops, for below example, needs global declaration
def foo():
global x
x:=123 #note that x:=123 searches outward through nested scopes,
#not including globals unless explicitly declared, whereas
# x=456 would always {re}bind the global x, as usual with a global x declared.
Given how much the use of global variables are discouraged, is it a
good idea to allow even more inter-namespace interactions?
I forgot some of my previous thoughts on this. It's not as wild as it appears ;-)

I forgot to mention that of course a symbol found in __builtins__ by way
of the usual default lookup should not be rebound. And only globals explicitly
declared should be rebound (error in code above, since foo doesn't have global x).
So that limits it to the local scope and nested scopes and declared globals not
preempted by nearer nested scope variable names.

This is motivated by currently not being able to rebind a closure variable in
a nested scope, and the requirement of pre-existence within a limited range of
namespaces that can (I think ;-) be statically analyzed for is meant to prevent
new accidental collision problems.

Regards,
Bengt Richter
 
T

Terry Hancock

You need to differentiate
a = b = 1
from
a = b == 1

Okay, I see what you mean. I can't ever recall having needed the
second form, though.

Of course, you could still do assignment like this:

a, b = (1,)*2

But I guess that's not exactly elegant. ;-)
 
R

Robert Kern

Terry said:
Okay, I see what you mean. I can't ever recall having needed the
second form, though.

I use it all the time with Numeric's rich comparisons.

mask = some_arr == 999
Of course, you could still do assignment like this:

a, b = (1,)*2

But I guess that's not exactly elegant. ;-)

Ya think? :)

--
Robert Kern
(e-mail address removed)

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter
 
S

Steven D'Aprano

Okay, I see what you mean. I can't ever recall having needed the
second form, though.

Of course, you could still do assignment like this:

a, b = (1,)*2

But I guess that's not exactly elegant. ;-)

In general that is not the same thing as a = b = obj.

py> a, b = ([], [])
py> a.append(1)
py> b
[]
py> a = b = []
py> a.append(1)
py> b
[1]
 
R

Robert Kern

Steven said:
Okay, I see what you mean. I can't ever recall having needed the
second form, though.

Of course, you could still do assignment like this:

a, b = (1,)*2

But I guess that's not exactly elegant. ;-)

In general that is not the same thing as a = b = obj.

py> a, b = ([], [])
py> a.append(1)
py> b
[]
py> a = b = []
py> a.append(1)
py> b
[1]

What you wrote isn't, but what Terry wrote is.

In [1]: a, b = ([],)*2

In [2]: a.append(1)

In [3]: b
Out[3]: [1]

In [4]: a is b
Out[4]: True

--
Robert Kern
(e-mail address removed)

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter
 
T

Tim Peters

[Terry Hancock]
Probably the most pointless Python wart, I would think. The =/==
distinction makes sense in C, but since Python doesn't allow assignments
in expressions, I don't think there is any situation in which the distinction
is needed. Python could easily figure out whether you meant assignment
or equality from the context, just like the programmer does.

That's what Python originally did, before release 0.9.6 (search
Misc/HISTORY for eqfix.py). Even this is ambigous then:

a = b

Especially at an interactive prompt, it's wholly ambiguous then
whether you want to change a's binding, or want to know whether a and
b compare equal.

Just yesterday, I wrote this in a script:

lastinline = ci == ncs - 1

This:

lastinline = ci = ncs - 1

means something very different (or means something identical,
depending on exactly how it is Python "could easily figure out" what I
intended <wink>).

Of course strange rules could have resolved this, like, say, "=" means
assignment, unless that would give a syntax error, and then "=" means
equality. Then

lastinline = ci = ncs - 1

would have been chained assignment, and something like

lastinline = (ci = ncs - 1)

would have been needed to get the intent of the current

lastinline = ci == ncs - 1
 
S

Steve Jorgensen

... that quickly becomes quite messy:

- When abused -
with A do begin
.....
with B do begin
.....
with C do begin
x := y;
end;
end;
end;

Like many features that can be helpful when used well, and harmful when used
poorly, it's not a simple question whether it should be in any given language.
It also makes sense to consider whether other features already in the language
can fill the same need (though I don't know Python well enough to address that
yet). Even though I like "With" in VB and use it often, I always consider its
use a warning that perhaps that code should be factored into the class
somehow.
 
G

GodFoca

if a.value == True:
if not database.connect == error:
database.query(q)

Yeah, yeah, I know that :)
What I mean is that most of the time I find the code more "readable" (I
know that more readable code ain't better code, but it helps when you
work with other people...).
"unless" seems to become "while not", as opposed to "if not". Should be
more consistent.

My mistake :-S
The comment in the code was erroneous, I shouldn't write messages to
the list while asleep ^_^

'unless' works as 'if not', not as 'while not'. Sorry for that :)

Anyway, it does improve readability. I know that it doesn't necessarily
makes code better, but it's a nice "trick" that I like :)

Other nice thing about ruby is declaring regexps as /regexp/ rather
than having to re.compile("regexp"), and having a built-in operator to
match against them (of course, as everything in ruby, overloadable in
each class :))

-NIcolas
 
M

Mike Meyer

Tom Anderson said:
I love that expression. I think it started out as 'bondage and
discipline languages', which is even better. I'm going to start
referring to python as a 'sluttily typed' language.

Since the user is the one bound with B&D languages, they are clearly
tops. Which makes Python a bottom.

<mike
 
I

Ivan Van Laningham

M

Mandus

Sun, 26 Jun 2005 08:35:58 +0200 skrev Peter Otten:
Steven said:
Good grief! You've been spying on Mandus! How else could you possibly know
that he doesn't measure performance? Are you running a key-logger on his
machine? *wink*

His mentioning reduce() as a performance panacea was a strong indication
even without looking over his shoulders. He filled in some conditions in a
later post, but "sing reduce ... performs better [than a for-loop]" is
just wrong.


Ok - so sometimes reduce() for convenience (nha, that's just me...),
sometimes for performance. In some cases clever use of map/reduce/etc.
have given a good speedup - say 4 times that of for-loops. But going to
C can give 10 to 100 times speed up over that again... So it depends how
important the performance is. Going to C/Fortran is always a bit more
hassel, while reduce is something you can stick in your interactive
session to finish the work rather before than after lunch :)

[snip]
OK, I am making a guess: "".join(strings) is more often faster than
naive string addition than reduce() wins over a for-loop.

you're probably right.
I don't think my pointed comment qualifies as "abuse", by the way.

neither think I.
 
P

Paddy

Joseph Garvin wrote:
'm curious -- what is everyone's favorite trick from a non-python
language? And -- why isn't it in Python?

I use constraints programming at work, Check out "System Verilog" or
OZ/Mozart.

It would be great if this style of programming could be added to
Python.

It is a declarative programming style
(http://en.wikipedia.org/wiki/Declarative_programming), in which you
can state what discrete values constrained values can take , say in a
list. Give a set of functions that must be true for the variables then
sit back and generate one or many sets of variable values that fit the
constraints.

The OZ homepage has an example for solving the eight queens problem:

http://www.mozart-oz.org/documentation/fdt/node25.html#section.scripts.queens

My use would be for testing. In the electronic design automation
fields, there are several proprietary languages with this feature, here
is an example written in Cadence's Specman 'e' language:
http://www.asic-world.com/specman/specman_one_day2.html


Cheers, Paddy.
 
T

Terry Reedy

Paddy said:
The OZ homepage has an example for solving the eight queens problem:

Buried in the generator test module (something like
lib/test/test_generators.py) are solutions for both 8Queens and Knight's
Tour. You might find these of interest.

Terry J. Reedy
 
P

Paddy

Sadly, its not a solution that I'm after, but a particular toolkit that
can be used for solving that type of problem.

- Pad.
 
T

Terry Hancock

Joseph Garvin wrote:
'm curious -- what is everyone's favorite trick from a non-python
language? And -- why isn't it in Python?

I use constraints programming at work, Check out "System Verilog" or
OZ/Mozart.

It would be great if this style of programming could be added to
Python.

Check out:
http://www.logilab.org/projects/python-logic/

In short, it has been already.

This is something pretty new to me, so I can't comment on how well
it would meet your expectations, but I see now that the site does mention
OZ/Mozart as comparables.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top