Re: how can this iterator be optimized?

2009-02-12 Thread josh logan
On Feb 11, 8:22 pm, Basilisk96  wrote:
> Hello all,
>
> I have the following function that uses an intermediate iterator
> "rawPairs":
>
> def MakePairs(path):
>     import os
>     import operator
>     join = os.path.join
>     rawPairs = (
>         (join(path, s), func(s))
>         for s in os.listdir(path)
>         if func(s) is not None and func(s).endswith("some criterion")
>     )
>     #Use the second item in the pair as the sort criterion
>     result = sorted(rawPairs, key=operator.itemgetter(1))
>     return result
>
> where "func" is a single-argument function that returns either a
> string or None, but is an expensive call.
> I am pretty sure that the sorted() construct cannot be improved much
> further, but...
> ...does anyone have ideas on improving the "rawPairs" iterator so that
> it calls "func(s)" only once per iteration?  Perhaps a lambda
> construct, but I am not sure how to go about it...?
>
> Cheers,
> Basilisk96

Hi,
Try something like this:

import os
from os.path import join
from itertools import ifilter #assuming 2.5 and earlier, for 3.0 just
use the filter builtin
from operator import itemgetter

def isvalid(pair):
return (s[1] is not None) and s[1].endswith('some criteria')

def makepairs(path):
pair_iter = ((join(path,s), func(s)) for s in os.listdir(path))
pair_iter = ifilter(isvalid, pair_iter)
result = sorted(pair_iter, key=itemgetter(1))

return result


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


Re: Read Only attributes, auto properties and getters and setters

2009-02-12 Thread josh logan
On Feb 12, 10:58 am, TechieInsights  wrote:
> Oh... one other thing that would be really cool is to do this with AOP/
> descriptors!  I just haven't been able to get that to work either.
> Basics...
>
> @readonly
> class MyClass(object):
>         def __init__(self, x):
>                 self.set_x(x)
>
>         def get_x(self):
>                 return self.__x
>
>         def set_x(self, x):
>                 print 'Hello the setter was called!'
>                 self.__x = x
>
> and it's done!  I don't think this will work because (maybe I'm wrong)
> but I don't think you can set the metaclass in the descriptor???  If
> this is the case, it is more work to do the AOP and set a metaclass...
> better to just inherit.  If it can be done... that would be awesome!
>
> Greg

Are your needs not already satisfied by the Python built-in property?

http://docs.python.org/dev/3.0/library/functions.html#property
--
http://mail.python.org/mailman/listinfo/python-list


Re: Read Only attributes, auto properties and getters and setters

2009-02-12 Thread josh logan
On Feb 12, 12:27 pm, TechieInsights  wrote:
> Ok... for some closure I have written a class to automate the
> process.  It takes getters and setters and deleters and then sets the
> property automatically.  Sweet!
>
> class AutoProperty(type):
>         def __new__(cls, name, bases, methoddict):
>                 processed = []
>                 getter = 'get_'
>                 setter = 'set_'
>                 deleter = 'del_'
>
>                 starters = {getter:PropertyAttr(getter, PropertyAttr.FGET),
>                                         setter:PropertyAttr(setter, 
> PropertyAttr.FSET),
>                                         deleter:PropertyAttr(deleter, 
> PropertyAttr.FDEL)
>                                         }
>                 for key, value in methoddict.items():
>                         var = None
>                         for start in starters.keys():
>                                 if key.startswith(start):
>                                         var = key[len(start):]
>                                         break
>                         if var is None or var in processed:
>                                 continue
>                         property_values = []
>
>                         for start in starters.keys():
>                                 if '%s%s' %(start, var) in methoddict.keys():
>                                         
> property_values.append(starters[start].tostring(var))
>                                 else:
>                                         
> property_values.append(starters[start].tostring(None))
>                         property_map = 'methoddict["%s"] = property(%s)' 
> %(var, ','.join
> (property_values))
>                         exec(property_map)
>                 return type.__new__(cls, name, bases, methoddict)
>
> class PropertyAttr(object):
>         FGET = 'fget'
>         FSET = 'fset'
>         FDEL = 'fdel'
>         def __init__(self, start, type = FGET):
>                 self.start = start
>                 self.type = type
>
>         def tostring(self, var):
>                 if self.type == self.FSET:
>                         vars = ['v']
>                 else:
>                         vars = []
>                 fullvar = ['self'] + vars
>                 if var is None:
>                         return '%s=None' %(self.type)
>                 return '%s=lambda %s: self.%s%s(%s)' %(self.type, 
> ','.join(fullvar),
> self.start, var, ','.join(vars))
>
> class ReadOnly(object):
>         __metaclass__ = AutoProperty
>
> class MyClass(ReadOnly):
>         def __init__(self, x, y):
>                 self.__x = x
>                 self.__y = y
>
>         def get_x(self):
>                 return self.__x
>
>         def set_x(self, x):
>                 self.__x = x
>
>         def get_y(self):
>                 return self.__y
>
> mc = MyClass(10, 100)
> print mc.x, mc.y
> mc.x = 10
> print mc.x
> try:
>         mc.y = 100
> except AttributeError:
>         print 'Yea it worked!'
>
> try:
>         del mc.y
> except AttributeError:
>         print "It's read only!"
>
> And the output:
> 10 100
> 10
> Yea it worked!
> It's read only!
>
> Now to work on descriptors doing it for you.

I think I'll stick with the built-in, Thanks :)
--
http://mail.python.org/mailman/listinfo/python-list


Re: how can this iterator be optimized?

2009-02-14 Thread josh logan
On Feb 13, 7:44 pm, Basilisk96  wrote:
> On Feb 12, 1:15 am, Steven D'Aprano
>
>  wrote:
> > > I usually strive
> > > for comprehensions if a for loop can be reduced to such.
>
> > Any particular reason?
>
> Only two.
> 1.) I was impressed by their clarity and conciseness when I first
> discovered them.
> 2.) I also read now and then that simple list comprehensions are
> faster when compared with their for-loop equivalents because of the
> way comprehensions are implemented under the hood. My example is a far
> cry from a "simple" comprehension, however. :)
>
> > If there's only one call to func(), and you ignore the (probably) fixed
> > cost of jumping into a generator each time, then it shouldn't make any
> > difference.
>
> > If you are comparing one call to func() in a for loop versus three calls
> > to func() in a list comp or generator expression, then of course the for
> > loop will be more efficient.
>
> I agree. I would rather call func() only once per iteration in any
> case. I will revise it to a plain for loop with a single call.
>
> Thanks,
> -Basilisk96

Just as long as you do realize that it is possible to do what you were
looking with one call to func() using chained generators, as
demonstrated in my post above. Whichever way is clearest for you would
be the way I'd go.
--
http://mail.python.org/mailman/listinfo/python-list


Where is the correct round() method?

2008-07-27 Thread josh logan
Hello,

I need a round function that _always_ rounds to the higher integer if
the argument is equidistant between two integers. In Python 3.0, this
is not the advertised behavior of the built-in function round() as
seen below:

>>> round(0.5)
0
>>> round(1.5)
2
>>> round(2.5)
2


I would think this is a common need, but I cannot find a function in
the Python library to do it. I wrote my own, but did I miss such a
method in my search of the Python library?

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


Re: Where is the correct round() method?

2008-07-27 Thread josh logan
On Jul 27, 7:58 pm, Gary Herron <[EMAIL PROTECTED]> wrote:
> josh logan wrote:
> > Hello,
>
> > I need a round function that _always_ rounds to the higher integer if
> > the argument is equidistant between two integers. In Python 3.0, this
> > is not the advertised behavior of the built-in function round() as
> > seen below:
>
> >>>> round(0.5)
>
> > 0
>
> >>>> round(1.5)
>
> > 2
>
> >>>> round(2.5)
>
> > 2
>
> Huh?
>
>  >>> round(2.5)
> 3.0
>
> Works for me on Python 2.5 on Linux running on "Intel(R) Core(TM)2 Duo
> CPU".  What system are you on?
>
> It could be that 2.5 is really 2.4... which would round down to 2,
> but on any modern CPU (using IEEE floating point), 2.5 should be
> representable exactly.
>
> However, as with any floating point calculations, if you expect exact
> representation or calculations with any numbers, then you are misusing
> floating points.
>
> Gary Herron
>
> > I would think this is a common need, but I cannot find a function in
> > the Python library to do it. I wrote my own, but did I miss such a
> > method in my search of the Python library?
>
> > Thanks
> > --
> >http://mail.python.org/mailman/listinfo/python-list
>
>

I should reiterate that I am using Python 3.0 and not Python 2.x.
It looks like the behavior round() has changed between these two
versions.
Here is the documentation for round() in Python 3.0:
http://docs.python.org/dev/3.0/library/functions.html#round

Of interest in this discussion is the second paragraph, which explains
the change:

Does anyone know the reason behind this change, and what replacement
method I can use to get the original behavior?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Where is the correct round() method?

2008-07-27 Thread josh logan
On Jul 27, 8:45 pm, pigmartian <[EMAIL PROTECTED]> wrote:
> it could be that 3.0 is using "banker's rounding" --- rounding to the
> even digit.  the idea behind it behind it being to reduce error
> accumulation when working with large sets of values.
>
> > Works for me on Python 2.5 on Linux running on "Intel(R) Core(TM)2 Duo
> > CPU".  What system are you on?
>
> > It could be that 2.5 is really 2.4... which would round down to 2,
> > but on any modern CPU (using IEEE floating point), 2.5 should be
> > representable exactly.
>
>

That's exactly what's happening, pigmartian. Thank you for explaining
the reasoning behind this change.
So am I relegated to building my own round() function that behaves
like the original function? Or did they move the functionality to a
new method somewhere for backwards-compatibility?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Concise way to format list/array to custom(hex) string

2008-08-02 Thread josh logan
On Aug 2, 9:29 am, Grant Edwards <[EMAIL PROTECTED]> wrote:
> On 2008-08-02, Zoltán Nagy <[EMAIL PROTECTED]> wrote:
>
>
>
>
>
> > Kurien Mathew írta:
> >> Hello,
>
> >> What will be a concise & efficient way to convert a list/array.array of
> >> n elements into a hex string? For e.g. given the bytes
> >> [116, 111, 110, 103, 107, 97]
> >> I would like the formatted string
> >> 0x74 0x6f 0x6e 0x67 0x6b 0x61
>
> >> Is there an approach better than below:
> >> hex = ''
> >> for b in bytes:
> >>     hex += ('0x%x '%b)
>
> >
>
> > You should avoid multiple string additions, as each one creates a new
> > string object (str objects are immutable). Try this:
>
> > bytes = [116, 111, 110, 103, 107, 97]
> > string = ''.join( ['0x%x '%b for b in bytes] )
>
> That results in an extra ' ' and the end of the string.  Try
> this:
>
> string = ' '.join(['0x%02x' % b for b in bytes])
>
> --
> Grant Edwards                   grante             Yow!  ... Just enough
>                                   at               time to do my LIBERACE
>                                visi.com            impression...

There is also a built-in hex() method in the Python Standard Library.
So, to make it cleaner:
' '.join(hex(x) for x in bytes)
--
http://mail.python.org/mailman/listinfo/python-list


Re: How to ignore the first line of the text read from a file

2008-08-30 Thread josh logan
On Aug 28, 3:47 am, Santiago Romero <[EMAIL PROTECTED]> wrote:
> > I want to read text line-by-line from a text file, but want to ignore
> > only the first line. I know how to do it in Java (Java has been my
> > primary language for the last couple of years) and following is what I
> > have in Python, but I don't like it and want to learn the better way
> > of doing it.
>
>  Why don't you read and discard the first line before processing the
> rest of the file?
>
>  file = open(filename, 'r')
>  file.readline()
>  for line in file: print line,
>
>  (It works).

# You could also do the following:

from itertools import islice

f = open(filename)

for each_line in islice(f, 1, None):
print line
--
http://mail.python.org/mailman/listinfo/python-list


Re: How to check is something is a list or a dictionary or a string?

2008-08-30 Thread josh logan
But this changes with Python 3, right?

On Aug 30, 7:15 am, Ken Starks <[EMAIL PROTECTED]> wrote:
> George Sakkis wrote:
> > On Aug 29, 12:16 pm, [EMAIL PROTECTED] wrote:
> >> Hi,
>
> >> How to check if something is a list or a dictionary or just a string?
> >> Eg:
>
> >> for item in self.__libVerDict.itervalues():
> >>             self.cbAnalysisLibVersion(END, item)
>
> >> where __libVerDict is a dictionary that holds values as strings or
> >> lists. So now, when I iterate this dictionary I want to check whether
> >> the item is a list or just a string?
>
> > if isinstance(item,basestring):
> >    # it's a string
> >     ...
> > else: # it should be a list
> >    # typically you don't have to check it explicitly;
> >    # even if it's not a list, it will raise an exception later anyway
> > if you call a list-specific method
>
> > HTH,
> > George
>
> For a bit more explanation see, for example,
>
> http://evanjones.ca/python-utf8.html
>
> (Quote)
> Working With Unicode Strings
>
> Thankfully, everything in Python is supposed to treat Unicode strings
> identically to byte strings. However, you need to be careful in your own
> code when testing to see if an object is a string. Do not do this:
>
> if isinstance( s, str ): # BAD: Not true for Unicode strings!
>
> Instead, use the generic string base class, basestring:
>
> if isinstance( s, basestring ): # True for both Unicode and byte strings

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


SAXReaderNotAvailble: No parsers found

2008-08-30 Thread josh logan
> Vincent Yau <[EMAIL PROTECTED]> writes:
> > I am trying to use Python SAX API to parse XML files.  I do see expat.py
> > somewhere underneath my Python 2.1.1 installation (on Solaris).
> > But I got this error when invoking the xml.sax.make_parser() call.  Any
> > tip/help much appreciated.
>
> You should install Expat before building Python. Best, you edit
> Modules/Setup to build pyexpat explicitly.
>
> Regards,
> Martin

Fast-forward to 2008

I installed Python 3.0b2 on a Windows Vista laptop (after having
previously installed Python 2.5), and I am getting this same error:

Traceback (most recent call last):
  File "Programming\Python\monkeys.py", line 24, in 
test_parse(sys.argv[1])
  File "Programming\Python\monkeys.py", line 21, in test_parse
xml.sax.parse(f, handler)
  File "C:\Python30\lib\xml\sax\__init__.py", line 30, in parse
parser = make_parser()
  File "C:\Python30\lib\xml\sax\__init__.py", line 90, in make_parser
raise SAXReaderNotAvailable("No parsers found", None)
xml.sax._exceptions.SAXReaderNotAvailable: No parsers found

I see a pyexpat.lib in the C:\Python30\libs folder.
I also see a pyexpat.pyd in the C:\Python30\DLLs folder.

It works in Python 2.5. I installed Python 3.0b2 as admin.
Does anyone know what is wrong and how to fix it?

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


Python 3.0b2 cannot map '\u12b'

2008-08-31 Thread josh logan
Hello,

I am using Python 3.0b2.
I have an XML file that has the unicode character '\u012b' in it,
which, when parsed, causes a UnicodeEncodeError:

'charmap' codec can't encode character '\u012b' in position 26:
character maps to 

This happens even when I assign this character to a reference in the
interpreter:

Python 3.0b2 (r30b2:65106, Jul 18 2008, 18:44:17) [MSC v.1500 32 bit
(Intel)] on
 win32
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '\u012b'
>>> s
Traceback (most recent call last):
  File "", line 1, in 
  File "C:\Python30\lib\io.py", line 1428, in write
b = encoder.encode(s)
  File "C:\Python30\lib\encodings\cp437.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_map)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\u012b' in
position
1: character maps to 

Is this a known issue, or am I doing something wrong?
Here is a link to the XML file. The character is on line 600, char 54

http://rubyquiz.com/SongLibrary.xml.gz
--
http://mail.python.org/mailman/listinfo/python-list


Re: Python 3.0b2 cannot map '\u12b'

2008-09-01 Thread josh logan
On Sep 1, 8:19 am, Marc 'BlackJack' Rintsch <[EMAIL PROTECTED]> wrote:
> On Mon, 01 Sep 2008 02:27:54 -0400, Terry Reedy wrote:
> > I doubt the OP 'chose' cp437.  Why does Python using cp437 even when the
> > default encoding is utf-8?
>
> > On WinXP
> >  >>> sys.getdefaultencoding()
> > 'utf-8'
> >  >>> s='\u012b'
> >  >>> s
> > Traceback (most recent call last):
> >    File "", line 1, in 
> >    File "C:\Program Files\Python30\lib\io.py", line 1428, in write
> >      b = encoder.encode(s)
> >    File "C:\Program Files\Python30\lib\encodings\cp437.py", line 19, in
> > encode
> >      return codecs.charmap_encode(input,self.errors,encoding_map)[0]
> > UnicodeEncodeError: 'charmap' codec can't encode character '\u012b' in
> > position
> > 1: character maps to 
>
> Most likely because Python figured out that the terminal expects cp437.  
> What does `sys.stdout.encoding` say?
>
> > To put it another way, how can one 'choose' utf-8 for display to screen?
>
> If the terminal expects cp437 then displaying utf-8 might give some
> problems.
>
> Ciao,
>         Marc 'BlackJack' Rintsch

So, it is not a problem with the program, but a problem when I print
it out.
sys.stdout.encoding does say cp437.

Now, when I don't print anything out, the program hangs. I will try
this again and let the board know the results.

Thanks for all of your insight.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Eleganz way to get rid of \n

2008-09-01 Thread josh logan
On Sep 1, 9:25 am, Hans Müller <[EMAIL PROTECTED]> wrote:
> Hello,
>
> I'm quite often using this construct:
>
> for l in open("file", "r"):
>         do something
>
> here, l contains the \n or \r\n on windows at the end.
> I get rid of it this way:
>
> for l in open("file", "r"):
>         while l[-1] in "\r\n":
>                 l = l[:-1]
>
> I find this a little bit clumsy, but it works fine.
>
> Has someone a better solution ?
>
> Thanks
>
> Hans

Can you do this:

f = open(fname)
for x in f:
line = x.rstrip('\r\n')
--
http://mail.python.org/mailman/listinfo/python-list


Re: SAXReaderNotAvailble: No parsers found

2008-09-01 Thread josh logan
On Aug 30, 8:59 pm, josh logan <[EMAIL PROTECTED]> wrote:
> > Vincent Yau <[EMAIL PROTECTED]> writes:
> > > I am trying to use Python SAX API to parse XML files.  I do see expat.py
> > > somewhere underneath my Python 2.1.1 installation (on Solaris).
> > > But I got this error when invoking the xml.sax.make_parser() call.  Any
> > > tip/help much appreciated.
>
> > You should install Expat before building Python. Best, you edit
> > Modules/Setup to build pyexpat explicitly.
>
> > Regards,
> > Martin
>
> Fast-forward to 2008
>
> I installed Python 3.0b2 on a Windows Vista laptop (after having
> previously installed Python 2.5), and I am getting this same error:
>
> Traceback (most recent call last):
>   File "Programming\Python\monkeys.py", line 24, in 
>     test_parse(sys.argv[1])
>   File "Programming\Python\monkeys.py", line 21, in test_parse
>     xml.sax.parse(f, handler)
>   File "C:\Python30\lib\xml\sax\__init__.py", line 30, in parse
>     parser = make_parser()
>   File "C:\Python30\lib\xml\sax\__init__.py", line 90, in make_parser
>     raise SAXReaderNotAvailable("No parsers found", None)
> xml.sax._exceptions.SAXReaderNotAvailable: No parsers found
>
> I see a pyexpat.lib in the C:\Python30\libs folder.
> I also see a pyexpat.pyd in the C:\Python30\DLLs folder.
>
> It works in Python 2.5. I installed Python 3.0b2 as admin.
> Does anyone know what is wrong and how to fix it?

Does anyone have an answer for this?

I uninstalled both Python 2.5 and Python 3.0b2 and then re-installed
3.0b2, thinking that the installer was confusing 2.5 and 3.0b2 on
Windows Vista. Still have the same issue.
I had to use my XP machine, since the Vista installation seems broken
for Python 3.0b2. How do I fix this? How do I get Python to notice the
pyexpat.lib in the C:\Python30\DLLs folder in Vista?

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


Re: Eleganz way to get rid of \n

2008-09-01 Thread josh logan
On Sep 1, 9:41 am, Wojtek Walczak <[EMAIL PROTECTED]> wrote:
> On Mon, 01 Sep 2008 15:25:03 +0200, Hans Müller wrote:
> > I'm quite often using this construct:
>
> > for l in open("file", "r"):
> >    do something
> > Has someone a better solution ?
>
> The most general would be to use rstrip() without
> arguments:
>
>
>
> >>> a="some string\r\n"
> >>> a.rstrip()
> 'some string'
>
> but be careful, because it will also cut whitespaces:
>
>
>
> >>> a="some string\t \r\n"
> >>> a.rstrip()
> 'some string'
>
> so maybe you could do this:
>
>
>
> >>> a.rstrip('\n').rstrip('\r')
> 'some string\t '
>
> HTH.
>
> --
> Regards,
> Wojtek Walczak,http://tosh.pl/gminick/

You can send both '\n' and '\r' in one rstrip call. No need for 2
separate calls.
--
http://mail.python.org/mailman/listinfo/python-list


Re: String/Number Conversion

2008-09-06 Thread josh logan
On Sep 6, 5:04 pm, Andreas Hofmann <[EMAIL PROTECTED]>
wrote:
> Hello Folks!
>
> I've got a little problem here, which which really creeps me out at the
> moment.
> I've got some strings, which only contain numbers plus eventually one
> character as si-postfix (k for kilo, m for mega, g for giga). I'm trying
> to convert those strings to integers, with this function:
>
> def eliminate_postfix(value):
>          if type(value) is str:
>                  value.upper()
>                  if value.endswith('K'):
>                          mult = 1000
>                  elif value.endswith('M'):
>                          mult = 100
>                  elif value.endswith('G'):
>                          mult = 10
>                  else:
>                          mult = 1
>
>                  if mult is 1:
>                          value = string.atoi(value)
>                  else:
>                          value = string.atoi(value[:-1]) * mult
>          return value
>
> The problem is as follows: Everytime a string with a postfix should get
> converted, mult does not get set properly. It is always 1. Does anyone
> have an idea how to fix this? I just don't see it, maybe because I'm
> pretty new to python or because I'm just blind I would be really greatful.
>
> Kind regards,
> Andy

Hello,

1. You call value.upper(), but you do not capture the results of that
method. Strings are immutable in Python.
>> value = value.upper()

2. You should use == instead of "is" in the comparison of mult being
1.
>> if mult == 1:
--
http://mail.python.org/mailman/listinfo/python-list


Question about sorted in Python 3.0rc1

2008-09-21 Thread josh logan
Hello,


I have 2 questions. Say I have this class:

class Player(object):
def __init__(self, fname, lname, score):
self.score = score
self.fname = fname
self.lname = lname
def __cmp__(self, other):
return (-cmp(self.score, other.score) or
cmp(self.lname, other.lname) or
cmp(self.fname, other.fname))
def __repr__(self):
return 'Player(fname={0.fname}, lname={0.lname},
score={0.score})'.format(self)
def __eq__(self, others):
if isinstance(other, Player):
return (self.score == other.score and
self.lname == other.lname and
self.fname == other.fname)
return False
def __ne__(self, others):
return not self.__eq__(others)



fnames = ['Julie', 'Ben', 'Jason', 'David']
lnames = ['Parks', 'Smith']
scores = [100, 95, 95, 130, 58, 74]

import itertools as it

score_iter = it.cycle(scores)

P = [Player(fn, ln, next(score_iter)) for fn in fnames for ln in
lnames]

cmp(P[0], P[1]) # returns -1

sorted(P) # throws TypeError: unorderable types Player() < Player()

The sorted function works when I define __lt__.
I must be misreading the documentation, because I read for the
documentation __cmp__ that it is called if none of the other rich
comparison functions are defined.
Is this a bug in Python 3.0rc1, or am I missing something?


Secondly, say that we suddenly need another sorting order, where we
want to sort by decreasing score and then by DECREASING last name
(instead of increasing last name, defined above). Now that the
comparison function argument is taken away from the sorted builtin,
how do we accomplish this with the "key" parameter?

Thank you

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


Re: Question about sorted in Python 3.0rc1

2008-09-22 Thread josh logan
On Sep 22, 3:41 am, Arnaud Delobelle <[EMAIL PROTECTED]> wrote:
> On 22 Sep, 04:05, josh logan <[EMAIL PROTECTED]> wrote:
>
>
>
> > Hello,
>
> > I have 2 questions. Say I have this class:
>
> > class Player(object):
> >     def __init__(self, fname, lname, score):
> >         self.score = score
> >         self.fname = fname
> >         self.lname = lname
> >     def __cmp__(self, other):
> >         return (-cmp(self.score, other.score) or
> >                 cmp(self.lname, other.lname) or
> >                 cmp(self.fname, other.fname))
> >     def __repr__(self):
> >         return 'Player(fname={0.fname}, lname={0.lname},
> > score={0.score})'.format(self)
> >     def __eq__(self, others):
> >         if isinstance(other, Player):
> >             return (self.score == other.score and
> >                     self.lname == other.lname and
> >                     self.fname == other.fname)
> >         return False
> >     def __ne__(self, others):
> >         return not self.__eq__(others)
>
> > fnames = ['Julie', 'Ben', 'Jason', 'David']
> > lnames = ['Parks', 'Smith']
> > scores = [100, 95, 95, 130, 58, 74]
>
> > import itertools as it
>
> > score_iter = it.cycle(scores)
>
> > P = [Player(fn, ln, next(score_iter)) for fn in fnames for ln in
> > lnames]
>
> > cmp(P[0], P[1]) # returns -1
>
> > sorted(P) # throws TypeError: unorderable types Player() < Player()
>
> > The sorted function works when I define __lt__.
> > I must be misreading the documentation, because I read for the
> > documentation __cmp__ that it is called if none of the other rich
> > comparison functions are defined.
> > Is this a bug in Python 3.0rc1, or am I missing something?
>
> > Secondly, say that we suddenly need another sorting order, where we
> > want to sort by decreasing score and then by DECREASING last name
> > (instead of increasing last name, defined above). Now that the
> > comparison function argument is taken away from the sorted builtin,
> > how do we accomplish this with the "key" parameter?
>
> > Thank you
>
> I don't know about __cmp__ but for the second part of the question you
> can probably do:
>
>     sorted(P, key=lambda p: (p.score, p.lname), reverse=True)
>
> HTH
>
> --
> Arnaud

Thank you for the prompt reply. I didn't think my second question
completely through.

A better example would be sorting by increasing last name and
decreasing first name. This would be easy with the sort function
comparator, but I can't see how to do the same with the key argument.
Is the only solution to decorate the Player objects in another class
that has the appropriate __cmp__ function (or whatever is needed) and
then retrieve the Player objects back?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Question about sorted in Python 3.0rc1

2008-09-22 Thread josh logan
On Sep 22, 7:32 am, Sion Arrowsmith <[EMAIL PROTECTED]>
wrote:
> josh logan  <[EMAIL PROTECTED]> wrote:
>
> >sorted(P) # throws TypeError: unorderable types Player() < Player()
>
> >The sorted function works when I define __lt__.
> >I must be misreading the documentation, because I read for the
> >documentation __cmp__ that it is called if none of the other rich
> >comparison functions are defined.
>
> You're either misreading or forgetting that __eq__ and __ne__,
> which you define, are rich comparison functions. __cmp__ will only
> be called for a comparison when *none* of the rich comparison
> functions are defined, not just the one in question.
>
> --
> \S -- [EMAIL PROTECTED] --http://www.chaos.org.uk/~sion/
>    "Frankly I have no feelings towards penguins one way or the other"
>         -- Arthur C. Clarke
>    her nu becomeþ se bera eadward ofdun hlæddre heafdes bæce bump bump bump

Hello Sion,

When I don't define the __eq__ and __ne__ comparison functions, the
same unexpected behavior occurs.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Question about sorted in Python 3.0rc1

2008-09-22 Thread josh logan
On Sep 22, 9:29 am, Hrvoje Niksic <[EMAIL PROTECTED]> wrote:
> josh logan <[EMAIL PROTECTED]> writes:
> > sorted(P) # throws TypeError: unorderable types Player() < Player()
>
> > The sorted function works when I define __lt__.
> > I must be misreading the documentation, because I read for the
> > documentation __cmp__ that it is called if none of the other rich
> > comparison functions are defined.
> > Is this a bug in Python 3.0rc1, or am I missing something?
>
> What documentation are you referring to, exactly?  The whole __cmp__
> thing was supposed to be removed from Python 3, so mention of it
> sounds like a documentation bug.
>
> > Secondly, say that we suddenly need another sorting order, where we
> > want to sort by decreasing score and then by DECREASING last name
> > (instead of increasing last name, defined above). Now that the
> > comparison function argument is taken away from the sorted builtin,
> > how do we accomplish this with the "key" parameter?
>
> By calling sort twice on the sequence:
>
> lst.sort(key=lambda x: x.score)
> lst.sort(key=lambda x: x.last_name, reverse=True)
>
> As much as I like the key argument, I believe it was a mistake to
> remove cmp, simply because it was the more general mechanism.
> Emulating cmp with key is possible, but it requires creating a bunch
> of objects for each sort.  (I'm aware that list.sort caches the
> calculated keys, but it still has to create as many of them as there
> are list items.)

It looks like __cmp__ is still in the documentation, and it seems to
work somewhat in Python 3.0rc1. Here is the link to the documnetation
http://docs.python.org/dev/3.0/reference/datamodel.html#object.__cmp__
--
http://mail.python.org/mailman/listinfo/python-list


HTMLParser not parsing whole html file

2010-10-24 Thread josh logan
Hello,

I wanted to use python to scrub an html file for score data, but I'm
having trouble.
I'm using HTMLParser, and the parsing seems to fizzle out around line
192 or so. None of the event functions are being called anymore
(handle_starttag, handle_endtag, etc.) and I don't understand why,
because it is a html page over 1000 lines.

Could someone tell me if this is a bug or simply a misunderstanding on
how HTMLParser works? I'd really appreciate some help in
understanding.

I am using Python 3.1.2 on Windows 7 (hopefully shouldn't matter).

I put the HTML file on pastebin, because I couldn't think of anywhere
better to put it:
http://pastebin.com/wu6Pky2W

The source code has been pared down to the simplest form to exhibit
the problem. It is displayed below, and is also on pastebin for
download (http://pastebin.com/HxwRTqrr):


import sys
import re
import os.path
import itertools as it
import urllib.request
from html.parser import HTMLParser
import operator as op


base_url = 'http://www.dci.org'

class TestParser(HTMLParser):

def handle_starttag(self, tag, attrs):
print('position {}, staring tag {} with attrs
{}'.format(self.getpos(), tag, attrs))

def handle_endtag(self, tag):
print('ending tag {}'.format(tag))


def do_parsing_from_file_stream(fname):
parser = TestParser()

with open(fname) as f:
for num, line in enumerate(f, start=1):
# print('Sending line {} through parser'.format(num))
parser.feed(line)



if __name__ == '__main__':
do_parsing_from_file_stream(sys.argv[1])
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: HTMLParser not parsing whole html file

2010-10-24 Thread josh logan
On Oct 24, 4:36 pm, josh logan  wrote:
> Hello,
>
> I wanted to use python to scrub an html file for score data, but I'm
> having trouble.
> I'm using HTMLParser, and the parsing seems to fizzle out around line
> 192 or so. None of the event functions are being called anymore
> (handle_starttag, handle_endtag, etc.) and I don't understand why,
> because it is a html page over 1000 lines.
>
> Could someone tell me if this is a bug or simply a misunderstanding on
> how HTMLParser works? I'd really appreciate some help in
> understanding.
>
> I am using Python 3.1.2 on Windows 7 (hopefully shouldn't matter).
>
> I put the HTML file on pastebin, because I couldn't think of anywhere
> better to put it:http://pastebin.com/wu6Pky2W
>
> The source code has been pared down to the simplest form to exhibit
> the problem. It is displayed below, and is also on pastebin for
> download (http://pastebin.com/HxwRTqrr):
>
> import sys
> import re
> import os.path
> import itertools as it
> import urllib.request
> from html.parser import HTMLParser
> import operator as op
>
> base_url = 'http://www.dci.org'
>
> class TestParser(HTMLParser):
>
>     def handle_starttag(self, tag, attrs):
>         print('position {}, staring tag {} with attrs
> {}'.format(self.getpos(), tag, attrs))
>
>     def handle_endtag(self, tag):
>         print('ending tag {}'.format(tag))
>
> def do_parsing_from_file_stream(fname):
>     parser = TestParser()
>
>     with open(fname) as f:
>         for num, line in enumerate(f, start=1):
>             # print('Sending line {} through parser'.format(num))
>             parser.feed(line)
>
> if __name__ == '__main__':
>     do_parsing_from_file_stream(sys.argv[1])

Sorry, the group doesn't like how i surrounded the Python code's
pastebin URL with parentheses:

http://pastebin.com/HxwRTqrr
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: HTMLParser not parsing whole html file

2010-10-24 Thread josh logan
On Oct 24, 4:38 pm, josh logan  wrote:
> On Oct 24, 4:36 pm, josh logan  wrote:
>
>
>
>
>
> > Hello,
>
> > I wanted to use python to scrub an html file for score data, but I'm
> > having trouble.
> > I'm using HTMLParser, and the parsing seems to fizzle out around line
> > 192 or so. None of the event functions are being called anymore
> > (handle_starttag, handle_endtag, etc.) and I don't understand why,
> > because it is a html page over 1000 lines.
>
> > Could someone tell me if this is a bug or simply a misunderstanding on
> > how HTMLParser works? I'd really appreciate some help in
> > understanding.
>
> > I am using Python 3.1.2 on Windows 7 (hopefully shouldn't matter).
>
> > I put the HTML file on pastebin, because I couldn't think of anywhere
> > better to put it:http://pastebin.com/wu6Pky2W
>
> > The source code has been pared down to the simplest form to exhibit
> > the problem. It is displayed below, and is also on pastebin for
> > download (http://pastebin.com/HxwRTqrr):
>
> > import sys
> > import re
> > import os.path
> > import itertools as it
> > import urllib.request
> > from html.parser import HTMLParser
> > import operator as op
>
> > base_url = 'http://www.dci.org'
>
> > class TestParser(HTMLParser):
>
> >     def handle_starttag(self, tag, attrs):
> >         print('position {}, staring tag {} with attrs
> > {}'.format(self.getpos(), tag, attrs))
>
> >     def handle_endtag(self, tag):
> >         print('ending tag {}'.format(tag))
>
> > def do_parsing_from_file_stream(fname):
> >     parser = TestParser()
>
> >     with open(fname) as f:
> >         for num, line in enumerate(f, start=1):
> >             # print('Sending line {} through parser'.format(num))
> >             parser.feed(line)
>
> > if __name__ == '__main__':
> >     do_parsing_from_file_stream(sys.argv[1])
>
> Sorry, the group doesn't like how i surrounded the Python code's
> pastebin URL with parentheses:
>
> http://pastebin.com/HxwRTqrr

I found the error. The HTML file I'm parsing has invalid HTML at line
193.
It has something like:



Note there is no space between the closing quote for the "href" tag
and the class attribute. I guess I'll go through each file and correct
these issues as I parse them.

Thanks for reading, anyways.
-- 
http://mail.python.org/mailman/listinfo/python-list