Re: Is there a better way? [combining f-string, thousands separator, right align]

2024-08-26 Thread dn via Python-list

On 26/08/24 23:00, Dan Sommers via Python-list wrote:

On 2024-08-26 at 20:42:32 +1200,
dn via Python-list  wrote:


and if we really want to go over-board:


RIGHT_JUSTIFIED = ">"
THOUSANDS_SEPARATOR = ","
s_format = F"{RIGHT_JUSTIFIED}{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}"


or (better) because right-justification is the default for numbers:


s_format = F"{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}"



To the extreme that if your user keeps fiddling with presentations (none
ever do, do they?), all settings to do with s_format could be added to a
config/environment file, and thus be even further separated from
program-logic!


And then you'll need a parser, many of whose Unique Challenges™ aren't
even apparent until you start parsing files from actual users, and
you'll still need some sort of fallback in the code anyway for the case
that s_format can't be parsed (for whatever reason).

Isn't a config file what just caused the global CrowdStrike outage?  ;-)

That said, I understand that report generators are a thing, not to
mention RPG (https://en.wikipedia.org/wiki/IBM_RPG).

Okay, sorry; I'll just crawl back into the hole from whence I came.



Not at all. Please continue to question/ask/suggest!

This is a valid point. There are costs and benefits (trade-offs) to all 
decisions!


That said, writing one's own parser would become a veritable can of 
worms/rabbit hole. Here be dragons!


Similarly, explaining this takes longer than writing the example itself!


Older Windows users will know about .ini files, and Linux Admins are 
familiar with .conf files. Many of us are already using JSON or YAML 
formats. Any of these (and more) could be pressed into service, as 
above. At the 'top end', there are also whole libraries devoted to 
establishing application configuration or "environments": default 
values, config files, command-line options, user-input...


Have switched to using Python-poetry, which replaces packaging methods 
such as setuptools (as well as virtual-environment tools). It takes its 
project configuration specifications from a pyproject.toml file. So, for 
a few projects lately, I've been using .toml for application-config as 
well. However, I have to say, this more from an attempt at consistency 
than a decision of logic. (critique welcome)


That said, a setup.py configuration, took the form:

setup(
name='demo_project',
version='1.1.0',
packages=find_packages(),
install_requires=[
'requests',
'numpy',
...
],
entry_points={
...

Accordingly, it offers an example of the simplest format (for us), and 
one which has a zero-learning pre-requisite. At execution-time, the 
moment such a config is import-ed, a syntax-error will immediately bring 
proceedings to a halt!



I have some stats-wonks as clients. They dabble in programming, but 
(fortunately) realise their limitations. (usually!) The boss has had to 
ban them from 'improving' my code ($paid to be an improvement on their 
usual quality), but including a .py configuration/options file has 
proven to be an honor-preserving compromise. Of course, they manage 
their own runs, adjusting parameters as they go. So, any errors are 
their own, and they can fix themselves (without anyone else knowing!).


Such would not work in many?most other environments - children: do not 
try this at home!



An irritation for those of us who have to delve into projects after 
they've been written, is a git-history full of the sorts of 
user-tweaking changes vilified earlier. Putting user-config into a 
separate file, even a separate sub-directory, makes it easy to spot 
which updates to ignore, and thus, which to consider!



PS the reason why CrowdStrike was not the end of humanity as we know it, 
(and only that of those who only know MSFT's eco-system) is because the 
majority of the world's Internet servers run Linux - including Azure 
(brings to mind the old saw: the package said "runs on Windows-95 or 
better" so I installed it on Linux!)


Joking aside, we (virtuous ones) ALWAYS test BEFORE release. Correct?

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way? [combining f-string, thousands separator, right align]

2024-08-26 Thread Dan Sommers via Python-list
On 2024-08-26 at 20:42:32 +1200,
dn via Python-list  wrote:

> and if we really want to go over-board:
> 
> >>> RIGHT_JUSTIFIED = ">"
> >>> THOUSANDS_SEPARATOR = ","
> >>> s_format = F"{RIGHT_JUSTIFIED}{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}"
> 
> or (better) because right-justification is the default for numbers:
> 
> >>> s_format = F"{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}"
> 
> 
> To the extreme that if your user keeps fiddling with presentations (none
> ever do, do they?), all settings to do with s_format could be added to a
> config/environment file, and thus be even further separated from
> program-logic!

And then you'll need a parser, many of whose Unique Challenges™ aren't
even apparent until you start parsing files from actual users, and
you'll still need some sort of fallback in the code anyway for the case
that s_format can't be parsed (for whatever reason).

Isn't a config file what just caused the global CrowdStrike outage?  ;-)

That said, I understand that report generators are a thing, not to
mention RPG (https://en.wikipedia.org/wiki/IBM_RPG).

Okay, sorry; I'll just crawl back into the hole from whence I came.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way? [combining f-string, thousands separator, right align]

2024-08-26 Thread dn via Python-list

On 26/08/24 03:12, Gilmeh Serda via Python-list wrote:

Subject explains it, or ask.

This is a bloody mess:


s = "123456789" # arrives as str
f"{f'{int(s):,}': >20}"

' 123,456,789'



With recent improvements to the expressions within F-strings, we can 
separate the string from the format required. (reminiscent of FORTRAN 
which had both WRITE and FORMAT statements, or for that matter HTML 
which states the 'what' and CSS the 'how')


Given that the int() instance-creation has a higher likelihood of 
data-error, it is recommended that it be a separate operation for ease 
of fault-finding - indeed some will want to wrap it with try...except.


>>> s = "123456789" # arrives as str
>>> s_int = int( s )  # makes the transformation obvious and distinct

>>> s_format = ">20,"  # define how the value should be presented

>>> F"{s_int:{s_format}}"
' 123,456,789'


Further, some of us don't like 'magic-constants', hence (previously):

>>> S_FIELD_WIDTH = 20
>>> s_format = F">{S_FIELD_WIDTH},"


and if we really want to go over-board:

>>> RIGHT_JUSTIFIED = ">"
>>> THOUSANDS_SEPARATOR = ","
>>> s_format = F"{RIGHT_JUSTIFIED}{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}"

or (better) because right-justification is the default for numbers:

>>> s_format = F"{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}"


To the extreme that if your user keeps fiddling with presentations (none 
ever do, do they?), all settings to do with s_format could be added to a 
config/environment file, and thus be even further separated from 
program-logic!


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way? [combining f-string, thousands separator, right align]

2024-08-25 Thread Pierre Fortin via Python-list
On Sun, 25 Aug 2024 15:12:20 GMT Gilmeh Serda via Python-list wrote:

>Subject explains it, or ask.
>
>This is a bloody mess:
>
 s = "123456789" # arrives as str
 f"{f'{int(s):,}': >20}"  
>' 123,456,789'
>

f"{s:>20}"
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way? [combining f-string, thousands separator, right align]

2024-08-25 Thread MRAB via Python-list

On 2024-08-25 16:12, Gilmeh Serda via Python-list wrote:

Subject explains it, or ask.

This is a bloody mess:


s = "123456789" # arrives as str
f"{f'{int(s):,}': >20}"

' 123,456,789'


You don't need to format twice; you can combine them:

>>> s = "123456789"
>>> f'{int(s): >20,}'
' 123,456,789'

or if you rely on default behaviour:

>>> f'{int(s):20,}'
' 123,456,789'

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


Re: Is there a better way? [combining f-string, thousands separator, right align]

2024-08-25 Thread Pierre Fortin via Python-list
On Sun, 25 Aug 2024 15:12:20 GMT Gilmeh Serda via Python-list wrote:

>Subject explains it, or ask.
>
>This is a bloody mess:
>
 s = "123456789" # arrives as str
 f"{f'{int(s):,}': >20}"  
>' 123,456,789'
>
Oops.. forgot comma

f"{int(s):>20,}"
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to create a list of None objects?

2021-08-12 Thread Dennis Lee Bieber
On Thu, 12 Aug 2021 09:57:33 +0100, Stephen Tucker 
declaimed the following:


>
># Logic Effect
>
>#
>
># [None * 8]TypeError: unsupported operand type(s) for *: ...
>
># [(None) * 8]  TypeError: unsupported operand type(s) for *: ...
>
># [((None)) * 8]TypeError: unsupported operand type(s) for *: ...
>
># [(None,) * 8] [(None, None, None, None, None, None, None, None)]
>
># list ((None) * 8) TypeError: unsupported operand type(s) for *: ...
>

In all the above, you've put the *8 INSIDE the list structure. You
"working" example is actually creating a TUPLE stored (as the only element)
inside a LIST.

>>> [None] * 8
[None, None, None, None, None, None, None, None]
>>> 

Creates a LIST of 8 elements, each being None.


-- 
Wulfraed Dennis Lee Bieber AF6VN
wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/

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


Re: Is there a better way to create a list of None objects?

2021-08-12 Thread Stephen Tucker
Thanks for this feedback, Chris, Matthieu. Both are spot on - and thanks
for the timing comparison, Matthieu. I suppose I didn't think to try the
solution you suggest because I didn't think that I would end up with a
single list, but 8 of them.

OK, I'll stop wriggling.

Stephen.

On Thu, Aug 12, 2021 at 10:22 AM Matthieu Dartiailh 
wrote:

> You can achieve the same result by writing:
> [None] * 8
>
> Comparing both cases in IPython I get:
>
> In [1]: %timeit list((None,)*8)
> 110 ns ± 0.785 ns per loop (mean ± std. dev. of 7 runs, 1000 loops
> each)
>
> In [2]: %timeit [None] * 8
> 88.2 ns ± 0.432 ns per loop (mean ± std. dev. of 7 runs, 1000 loops
> each)
>
> So the list multiplication appears a bit faster.
>
> Best
>
> Matthieu
>
> Le 8/12/2021 à 10:57 AM, Stephen Tucker a écrit :
> > Hi,
> >
> > I thought I'd share the following piece of code that I have recently
> written
> > (a) to check that what I have done is reasonable - even optimum,
> > (b) to inform others who might be wanting to do similar things, and
> > (c) to invite comment from the community.
> >
> > ---
> >
> > #
> >
> > # Yes: Create an empty list of Band Limits for this language
> >
> > #
> >
> > # Note. The rather complicated logic on the right-hand side of the
> >
> > #   assignment below is used here because none of the following
> >
> > #   alternatives had the desired effect:
> >
> > #
> >
> > # Logic Effect
> >
> > #
> >
> > # [None * 8]TypeError: unsupported operand type(s) for *: ...
> >
> > # [(None) * 8]  TypeError: unsupported operand type(s) for *: ...
> >
> > # [((None)) * 8]TypeError: unsupported operand type(s) for *: ...
> >
> > # [(None,) * 8] [(None, None, None, None, None, None, None, None)]
> >
> > # list ((None) * 8) TypeError: unsupported operand type(s) for *: ...
> >
> > #
> >
> > diclll_BLim [thisISO_] = list ((None,) * 8)
> >
> >
> > ---
> >
> > Thanks in anticipation.
> >
> > Stephen Tucker.
>
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to create a list of None objects?

2021-08-12 Thread Matthieu Dartiailh

You can achieve the same result by writing:
[None] * 8

Comparing both cases in IPython I get:

In [1]: %timeit list((None,)*8)
110 ns ± 0.785 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [2]: %timeit [None] * 8
88.2 ns ± 0.432 ns per loop (mean ± std. dev. of 7 runs, 1000 loops 
each)


So the list multiplication appears a bit faster.

Best

Matthieu

Le 8/12/2021 à 10:57 AM, Stephen Tucker a écrit :

Hi,

I thought I'd share the following piece of code that I have recently written
(a) to check that what I have done is reasonable - even optimum,
(b) to inform others who might be wanting to do similar things, and
(c) to invite comment from the community.

---

#

# Yes: Create an empty list of Band Limits for this language

#

# Note. The rather complicated logic on the right-hand side of the

#   assignment below is used here because none of the following

#   alternatives had the desired effect:

#

# Logic Effect

#

# [None * 8]TypeError: unsupported operand type(s) for *: ...

# [(None) * 8]  TypeError: unsupported operand type(s) for *: ...

# [((None)) * 8]TypeError: unsupported operand type(s) for *: ...

# [(None,) * 8] [(None, None, None, None, None, None, None, None)]

# list ((None) * 8) TypeError: unsupported operand type(s) for *: ...

#

diclll_BLim [thisISO_] = list ((None,) * 8)


---

Thanks in anticipation.

Stephen Tucker.


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


Re: Is there a better way to create a list of None objects?

2021-08-12 Thread Chris Angelico
On Thu, Aug 12, 2021 at 6:59 PM Stephen Tucker  wrote:
>
> Hi,
>
> I thought I'd share the following piece of code that I have recently written
> (a) to check that what I have done is reasonable - even optimum,
> (b) to inform others who might be wanting to do similar things, and
> (c) to invite comment from the community.
>
> ---
>
> #
>
> # Yes: Create an empty list of Band Limits for this language
>
> #
>
> # Note. The rather complicated logic on the right-hand side of the
>
> #   assignment below is used here because none of the following
>
> #   alternatives had the desired effect:
>
> #
>
> # Logic Effect
>
> #
>
> # [None * 8]TypeError: unsupported operand type(s) for *: ...
>
> # [(None) * 8]  TypeError: unsupported operand type(s) for *: ...
>
> # [((None)) * 8]TypeError: unsupported operand type(s) for *: ...
>
> # [(None,) * 8] [(None, None, None, None, None, None, None, None)]
>
> # list ((None) * 8) TypeError: unsupported operand type(s) for *: ...
>
> #
>
> diclll_BLim [thisISO_] = list ((None,) * 8)
>

Why not just:

[None] * 8

?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to do this snippet?

2012-04-03 Thread nn
On Apr 3, 12:26 pm, Alain Ketterlin 
wrote:
> nn  writes:
> >> > for item in tag23gr:
> >> > ...        value, key = tuple(item)
> >> > ...        if(g23tag.get(key)):
> >> > ...                g23tag[key].append(value)
> >> > ...        else:
> >> > ...                g23tag[key] = [value]
>
> >> for item in tag23gr:
> >>     g23tag.setdefault(item[0],[]).append(item[1])
> > Or alternatively:
>
> > from collections import defaultdict
> > g23tag = defaultdict(list)
> > for item in tag23gr:
> > g23tag[item[0]].append(item[1])
>
> Very handy in that case, but in general I dislike the idea of silently
> inserting a default value when the access is a read, e.g., in
> x=g23tag[wrung]. Explicit is better than implicit, as they say. YMMV.
>
> -- Alain.

Valid point. Preferred choice depends on the access patterns to the
dict (e.g. one write and multiple reads, multiple writes and one loop
over items, etc.)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to do this snippet?

2012-04-03 Thread Alain Ketterlin
nn  writes:

>> > for item in tag23gr:
>> > ...        value, key = tuple(item)
>> > ...        if(g23tag.get(key)):
>> > ...                g23tag[key].append(value)
>> > ...        else:
>> > ...                g23tag[key] = [value]
>>
>> for item in tag23gr:
>>     g23tag.setdefault(item[0],[]).append(item[1])

> Or alternatively:
>
> from collections import defaultdict
> g23tag = defaultdict(list)
> for item in tag23gr:
> g23tag[item[0]].append(item[1])

Very handy in that case, but in general I dislike the idea of silently
inserting a default value when the access is a read, e.g., in
x=g23tag[wrung]. Explicit is better than implicit, as they say. YMMV.

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


Re: Is there a better way to do this snippet?

2012-04-03 Thread nn
On Apr 3, 11:02 am, Alain Ketterlin 
wrote:
> python  writes:
> > tag23gr is a list of lists each with two items.
> > g23tag is an empty dictionary when I run the for loop below.
> > When is is complete each key is a graphic name who's values are a list
> > of tags.
>
> > for item in tag23gr:
> > ...        value, key = tuple(item)
> > ...        if(g23tag.get(key)):
> > ...                g23tag[key].append(value)
> > ...        else:
> > ...                g23tag[key] = [value]
>
> for item in tag23gr:
>     g23tag.setdefault(item[0],[]).append(item[1])
>
> -- Alain.

Or alternatively:

from collections import defaultdict
g23tag = defaultdict(list)
for item in tag23gr:
g23tag[item[0]].append(item[1])
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to do this snippet?

2012-04-03 Thread Peter Otten
python wrote:

> I played around with a few things and this works but was wondering if
> there was a better way to do this.
> My first thought was list comprehension but could not get a figure out
> the syntax.
> 
> tag23gr is a list of lists each with two items.
> g23tag is an empty dictionary when I run the for loop below.
> When is is complete each key is a graphic name who's values are a list
> of tags.
> 
> for item in tag23gr:
> ...   value, key = tuple(item)
> ...   if(g23tag.get(key)):

That should be

 if key in g23tag:

Your version means trouble for keys that evaluate to False in a boolean 
context, e. g. 0, False, None, "", (),...

> ...   g23tag[key].append(value)
> ...   else:
> ...   g23tag[key] = [value]

from collections import defaultdict
g23tag = defaultdict(list)

for value, key in tag23gr:
g23tag[key].append(value)


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


Re: Is there a better way to do this snippet?

2012-04-03 Thread Chris Angelico
On Wed, Apr 4, 2012 at 12:36 AM, python  wrote:
> for item in tag23gr:
> ...     value, key = tuple(item)
> ...     if(g23tag.get(key)):
> ...             g23tag[key].append(value)
> ...     else:
> ...             g23tag[key] = [value]

Simple enhancement: Use setdefault. Instead of the if, just use:

g23tag.setdefault(key,[]).append(value)

That'll cover both cases in one.

You can leave off the explicit tuple construction; if item is a
two-element list, you can unpack it directly. You can also embed that
straight into your for loop:

for value,key in tag23gr:

Do both and you cut your loop down to two lines. Cool! :)

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


Re: Is there a better way to do this snippet?

2012-04-03 Thread Alain Ketterlin
python  writes:

> tag23gr is a list of lists each with two items.
> g23tag is an empty dictionary when I run the for loop below.
> When is is complete each key is a graphic name who's values are a list
> of tags.
>
> for item in tag23gr:
> ...   value, key = tuple(item)
> ...   if(g23tag.get(key)):
> ...   g23tag[key].append(value)
> ...   else:
> ...   g23tag[key] = [value]

for item in tag23gr:
g23tag.setdefault(item[0],[]).append(item[1])

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


Re: Is there a better way to solve this?

2011-05-23 Thread Steven D'Aprano
On Mon, 23 May 2011 11:55:08 -0700, kracekumar ramaraju wrote:

> You can use sizeof function,

Who are you talking to, and what question did they ask?

Please always quote enough of the post that you are replying to to 
establish context.


 a=12234
 b=23456.8
 a.__sizeof__()
> 12
 b.__sizeof__()
> 16
> So sizeof int is 12 bytes and float is 16 bytes

You shouldn't be calling special methods directly (except under unusual 
circumstances). That's like calling s.__len__() instead of len(s).

The public function for getting the size of an object is in the sys 
module:

sys.getsizeof(a)



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


Re: Is there a better way to solve this?

2011-05-23 Thread Terry Reedy

On 5/23/2011 2:55 PM, kracekumar ramaraju wrote:

You can use sizeof function,


Appears not to be in manuals, that I could find. As a special method, it 
is intended to be called through sys.getsizeof.



a=12234
b=23456.8
a.__sizeof__()

12

b.__sizeof__()

16
So sizeof int is 12 bytes and float is 16 bytes


Depends on system. On my winxp machine, ints are 14 bytes.

>>> import sys
>>> size = sys.getsizeof
>>> size(1)
14
>>> size(1.0)
16
>>> size([])
36
>>> size([1,2,3])
48

--
Terry Jan Reedy

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


Re: Is there a better way to solve this?

2011-05-23 Thread David Robinow
On Mon, May 23, 2011 at 2:55 PM, kracekumar ramaraju
 wrote:
> You can use sizeof function,
 a=12234
 b=23456.8
 a.__sizeof__()
> 12
 b.__sizeof__()
> 16
> So sizeof int is 12 bytes and float is 16 bytes

I'm not sure what you're trying to show here, but try the following in
Python 3.2

>>> a = 
>>> for i in range(5):
...  a*= 10
...  a.__sizeof__()
...
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to solve this?

2011-05-23 Thread kracekumar ramaraju
You can use sizeof function,
>>> a=12234
>>> b=23456.8
>>> a.__sizeof__()
12
>>> b.__sizeof__()
16
So sizeof int is 12 bytes and float is 16 bytes
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to solve this?

2011-05-21 Thread Chris Rebert
On Sat, May 21, 2011 at 11:28 PM, Ganapathy Subramanium
 wrote:
> Hello,
>
> I'm a new bie to python programming and on the processing of learning python
> programming. I have coded my first program of fibonnaci generation and would
> like to know if there are better ways of achieving the same.
>
> I still feel quite a few things to be improved. Just wanted experts thoughts
> on this.
>
> try:
>
>     length = input('Enter the length till which you want to generate the
> fibonnaci series: \n')
>     print type(length)
>
> except:
>     print 'Invalid input detected'
>     exit(0)

Never use the input() function in Python 2.x; it does an eval(), which
is evil. Always use raw_input() and an explicit conversion instead;
e.g.

Q = 'Enter the length till which you want to generate the fibonnaci series: \n'
try:
length = int(raw_input(Q))
except ValueError:
print 'Invalid input detected'
exit(0)


Also, as a sidenote:

> if type(length) is int:

Is normally written:

if isinstance(length, int):

Cheers,
Chris
--
http://rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to set a system clock in Python (on a Linux system)

2010-05-13 Thread Lawrence D'Oliveiro
In message , J wrote:

> Like I said, it works well, I just wonder if there is a cleaner way of
> setting the local clock to a different time in python without having
> to do all this.

How about one line in Bash:

date -s $(date --rfc-3339=date -d "+1 hour")

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


Re: Is there a better way to set a system clock in Python (on a Linux system)

2010-05-05 Thread KDr2
man 2 clock_settime
call it with ctypes
--
Best Regards,
 -- KDr2 http://kdr2.net




On Thu, May 6, 2010 at 10:47 AM, J  wrote:

> Is there a better way to do this?
>
> def SkewTime():
>'''
>Optional function. We can skew time by 1 hour if we'd like to see real
> sync
>changes being enforced
>'''
>TIME_SKEW=1
>logging.info('Time Skewing has been selected. Setting clock ahead 1
> hour')
># Let's get our current time
>t = TimeCheck()
>logging.info('Current time is: %s' % time.asctime(t))
># Now create new time string in the form MMDDhhmm for the date
> program
>hr = t.tm_hour + TIME_SKEW
>date_string = time.strftime('%m%d%H%M%Y',(t.tm_year,
>t.tm_mon,
>t.tm_mday,
>hr,
>t.tm_min,
>t.tm_sec,
>t.tm_wday,
>t.tm_yday,
>t.tm_isdst))
>logging.debug('New date string is: %s' % date_string)
>logging.debug('Setting new system time/date')
>status = SilentCall('/bin/date %s' % date_string)
>logging.info('Pre-sync time is: %s' % time.asctime())
>
> TimeCheck() as referenced above is a simple function that just returns
> the time.time_struct object from time.localtime().  I pull time a few
> times and it was a little cleaner to put that into a function and just
> call the function whenever I needed to.
>
> SilentCall() is a modification of subprocess.call() (which in reality
> just calls Popen(*popenargs,**kwargs).wait()) but it defaults to
> redirecting stdin and stdout to /dev/null to suppress shell output
> from the command being called.
>
> Anyway, what I'm wondering, is, while this works, is there a better
> way to do it than using part of the originally returned time_struct
> and injecting my own new hour argument (hr).
>
> The goal of this function is to just set the system clock one hour
> ahead, so when I call the Linux command 'ntpdate' I can get a real
> time change when it syncs the local clock to an NTP server.
>
> This just looks... well, big to me.  I tried passing only the things I
> really needed to time.strftime(), but apparently, that requires the
> full 9-tuple from time_struct, not just individual parts of it.
>
> Like I said, it works well, I just wonder if there is a cleaner way of
> setting the local clock to a different time in python without having
> to do all this.  The reason most of that exists, is because the linux
> date command expects to see the new date/time like this:
> MMDDhhmm.ss.
>
> Or am I just looking at this too hard and really did work it out nicely?
>
> Cheers
> Jeff
> --
> http://mail.python.org/mailman/listinfo/python-list
>
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to set a system clock in Python (on a Linux system)

2010-05-05 Thread Chris Rebert
On Wed, May 5, 2010 at 7:47 PM, J  wrote:
> Is there a better way to do this?

Yes:

from datetime import datetime, timedelta
> def SkewTime():
>    '''
>    Optional function. We can skew time by 1 hour if we'd like to see real sync
>    changes being enforced
>    '''
>    TIME_SKEW=1
>    logging.info('Time Skewing has been selected. Setting clock ahead 1 hour')
>    # Let's get our current time
skewed = datetime.now() + timedelta(hours=TIME_SKEW)
>    # Now create new time string in the form MMDDhhmm for the date program
date_time_str = skewed.strftime('%m%d%H%M%Y')
    logging.debug('New date string is: %s' % date_time_str)
>    logging.debug('Setting new system time/date')
    status = SilentCall('/bin/date %s' % date_time_str)
>    logging.info('Pre-sync time is: %s' % time.asctime())
>
> Anyway, what I'm wondering, is, while this works, is there a better
> way to do it than using part of the originally returned time_struct
> and injecting my own new hour argument (hr).

Use the datetime module roughly as shown. (Disclaimer: Code is untested).
Also, I'm not sure if your original code worked properly after 11PM;
my code definitely should.

> This just looks... well, big to me.  I tried passing only the things I
> really needed to time.strftime(), but apparently, that requires the
> full 9-tuple from time_struct, not just individual parts of it.

Cheers,
Chris
--
http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to do this?

2010-03-01 Thread Richard Brodie

"Matt Mitchell"  wrote in message 
news:mailman.65.1267464765.23598.python-l...@python.org...
> My initial idea was to make a list of all the different
> ways "project" has been capitalized in my repo and try each one.  The
> code looks like this:

I would use pysvn.Client.list to get a list of files at whatever directory level
you require. Then you can do a case insensitive compare or whatever else.


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


Re: Is there a better way to code variable number of return arguments?

2009-10-08 Thread Hendrik van Rooyen
On Thursday, 8 October 2009 18:41:31 Dr. Phillip M. Feldman wrote:
> I currently have a function that uses a list internally but then returns
> the list items as separate return
> values as follows:
>
> if len(result)==1: return result[0]
> if len(result)==2: return result[0], result[1]
>
> (and so on).  Is there a cleaner way to accomplish the same thing?

Why do you not change the list into a tuple and return the tuple, and let 
automatic unpacking handle it?

As I see it, the problem is not in the return, but in the call - how do you 
know now, which of the following to write:

answer = thing(params)
answer0,answer1 = thing(params)
answer0,answer1,answer2 = thing(params)
answer0,answer1,answer2,answer3 = thing(params)

and so on...

probably best to write:

answers = thing(params)

for answer in answers:
do something with answer

- Hendrik

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


Re: Is there a better way to code variable number of return arguments?

2009-10-08 Thread Simon Forman
On Thu, Oct 8, 2009 at 7:14 PM, Dr. Phillip M. Feldman
 wrote:
>
> I'm amazed that this works.  I had not realized that
>
> x,y= [3,4]
>
> is equivalent to
>
> x= 3; y= 4
>
> Python is rather clever.
>
> Thanks!
>

Python is very clever:

>>> (a, b), c = (1, 2), 3
>>> a, b, c
(1, 2, 3)

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


Re: Is there a better way to code variable number of return arguments?

2009-10-08 Thread Alan G Isaac

Dr. Phillip M. Feldman writes:

I currently have a function that uses a list internally but then returns the
list items as separate return
values as follows:

if len(result)==1: return result[0]
if len(result)==2: return result[0], result[1]

(and so on).  Is there a cleaner way to accomplish the same thing?



The suggestions to return result
or if needed tuple(result) are good,
if a sequence is expected.

But perhaps better if each element has separate meaning:
return a defaultdict;
document the keys.
http://docs.python.org/library/collections.html#collections.defaultdict

Cheers,
Alan Isaac
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to code variable number of return arguments?

2009-10-08 Thread Robert Kern

Dr. Phillip M. Feldman wrote:

I'm amazed that this works.  I had not realized that

x,y= [3,4]

is equivalent to

x= 3; y= 4

Python is rather clever.

Thanks!



To elaborate on Paul's answer, returning the list will also unpack it if 
you have it set up that way.  E.g.


def func(alist):
return alist

some_list = [1, 2]
this, that = func(alist)

At least, in 2.5.4 this works.  :-)


In just about all Python versions for all sequence types, in fact.

Mind you, if you don't have the correct number of return names to match 
the unpacking you'll get the normal errors from that.


Yes. This is why people are suggesting that you be consistent about what you 
return. This is quite different from Matlab where the interpreter knows how many 
return values the caller is expecting in order to overload functions, but I 
think it makes for much more understandable code.


--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
 that is made terrible by our own mad attempt to interpret it as though it had
 an underlying truth."
  -- Umberto Eco

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


Re: Is there a better way to code variable number of return arguments?

2009-10-08 Thread Phillip M. Feldman
This is an interesting alternative.  If one wants to generate everything 
and return it at one shot, the list approach is better, but there are 
situations where generating things incrementally is preferrable, e.g., 
because the caller doesn't know a priori how many things he wants.  I 
will try this out.


Thanks!

Jack Norton wrote:

Dr. Phillip M. Feldman wrote:
I currently have a function that uses a list internally but then 
returns the

list items as separate return
values as follows:

if len(result)==1: return result[0]
if len(result)==2: return result[0], result[1]

(and so on).  Is there a cleaner way to accomplish the same thing?
  

How about using yield and then iterate over the answer:

def some_fun():
\tfor result in some_loopable_stuff:
\t\t yield result

Then call it thusly:

for i in some_fun()
  result = i

-Jack (PS, sorry to the OP, you will get two of these -- I forgot to 
CC the list)




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


Re: Is there a better way to code variable number of return arguments?

2009-10-08 Thread Dr. Phillip M. Feldman

I'm amazed that this works.  I had not realized that

x,y= [3,4]

is equivalent to

x= 3; y= 4

Python is rather clever.

Thanks!



To elaborate on Paul's answer, returning the list will also unpack it if 
you have it set up that way.  E.g.

def func(alist):
return alist

some_list = [1, 2]
this, that = func(alist)

At least, in 2.5.4 this works.  :-)

Mind you, if you don't have the correct number of return names to match 
the unpacking you'll get the normal errors from that.

Hope this helps!

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



-- 
View this message in context: 
http://www.nabble.com/Is-there-a-better-way-to-code-variable-number-of-return-arguments--tp25803294p25813206.html
Sent from the Python - python-list mailing list archive at Nabble.com.

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


Re: Is there a better way to code variable number of return arguments?

2009-10-08 Thread Jack Norton

Dr. Phillip M. Feldman wrote:

I currently have a function that uses a list internally but then returns the
list items as separate return
values as follows:

if len(result)==1: return result[0]
if len(result)==2: return result[0], result[1]

(and so on).  Is there a cleaner way to accomplish the same thing?
  

How about using yield and then iterate over the answer:

def some_fun():
\tfor result in some_loopable_stuff:
\t\t yield result

Then call it thusly:

for i in some_fun()
  result = i

-Jack (PS, sorry to the OP, you will get two of these -- I forgot to CC 
the list)

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


Re: Is there a better way to code variable number of return arguments?

2009-10-08 Thread Ethan Furman

Paul Rubin wrote:

Ethan Furman  writes:


some_list = [1, 2]
this, that = func(alist)

At least, in 2.5.4 this works.  :-)



But that fails if there are fewer than two elements in the list.  It's
better to just make the logic either expect a list, or if it's
implementing something like an optional value, code it up explicitly.
You may even want to return two lists, the second one possibly empty.


It also fails if there are more than two elements in the list, as the 
rest of my post went on to say.  I myself would generally not use such a 
structure, but that doesn't mean the OP doesn't have a good use case for 
it.  Don't forget, his original question indicated that there could be 
more than two return elements also.


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


Re: Is there a better way to code variable number of return arguments?

2009-10-08 Thread Paul Rubin
Ethan Furman  writes:
> some_list = [1, 2]
> this, that = func(alist)
> 
> At least, in 2.5.4 this works.  :-)

But that fails if there are fewer than two elements in the list.  It's
better to just make the logic either expect a list, or if it's
implementing something like an optional value, code it up explicitly.
You may even want to return two lists, the second one possibly empty.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to code variable number of return arguments?

2009-10-08 Thread Ethan Furman

Dr. Phillip M. Feldman wrote:

I currently have a function that uses a list internally but then returns the
list items as separate return
values as follows:

if len(result)==1: return result[0]
if len(result)==2: return result[0], result[1]

(and so on).  Is there a cleaner way to accomplish the same thing?


To elaborate on Paul's answer, returning the list will also unpack it if 
you have it set up that way.  E.g.


def func(alist):
   return alist

some_list = [1, 2]
this, that = func(alist)

At least, in 2.5.4 this works.  :-)

Mind you, if you don't have the correct number of return names to match 
the unpacking you'll get the normal errors from that.


Hope this helps!

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


Re: Is there a better way to code variable number of return arguments?

2009-10-08 Thread Simon Forman
On Thu, Oct 8, 2009 at 12:41 PM, Dr. Phillip M. Feldman
 wrote:
>
> I currently have a function that uses a list internally but then returns the
> list items as separate return
> values as follows:
>
> if len(result)==1: return result[0]
> if len(result)==2: return result[0], result[1]
>
> (and so on).  Is there a cleaner way to accomplish the same thing?

It kind of depends on how the caller of your function handles the return values.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to code variable number of return arguments?

2009-10-08 Thread Jean-Michel Pichavant

Dr. Phillip M. Feldman wrote:

I currently have a function that uses a list internally but then returns the
list items as separate return
values as follows:

if len(result)==1: return result[0]
if len(result)==2: return result[0], result[1]

(and so on).  Is there a cleaner way to accomplish the same thing?
  


return tuple(result)

But you down want to do that, cause the caller will have a hell of a job 
getting your result. You may want to simply return the list itself.


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


Re: Is there a better way to code variable number of return arguments?

2009-10-08 Thread Christian Heimes
Dr. Phillip M. Feldman schrieb:
> I currently have a function that uses a list internally but then returns the
> list items as separate return
> values as follows:
> 
> if len(result)==1: return result[0]
> if len(result)==2: return result[0], result[1]
> 
> (and so on).  Is there a cleaner way to accomplish the same thing?

You can simply "return result". If you want to make sure that you return
a copy of the internal list, do "return list(result)" or "return
tuple(result)".

Christian

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


Re: Is there a better way to code variable number of return arguments?

2009-10-08 Thread Paul Rubin
"Dr. Phillip M. Feldman"  writes:
> if len(result)==1: return result[0]
> if len(result)==2: return result[0], result[1]
> 
> (and so on).  Is there a cleaner way to accomplish the same thing?

That is poor style.  Just return the result as a list.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to chose a slice of a list?

2009-05-21 Thread Rhodri James
On Wed, 20 May 2009 17:08:08 +0100, walterbyrd   
wrote:



I am processing a huge spreadsheet which I have converted to a csv
format. Each row will be a wiki page with several sub-headings. The
spreadsheet contains information about servers. Wiki sub-headings may
include: 'hardware', 'software', 'users', 'network swith settings'.
'Hardware' may include the spreadsheet columns: 'memory', 'cpu', and
so on. So the first six columns in the spreadsheet may go under
'hardware' the next six under 'software' and so on.

I have already created the wiki pages, using a method similar to what
I first posted. But, it seems like there should be a better way to to
do it. So, for future reference, I was just wondering.


Given that you're already making presumptions about the nature of your
data, named constants or enums are the most concise thing to use together
with a quick check of the column header row to make sure that the
constants really do refer to the right columns.

If you want something a little more bullet-proof, create a dictionary
mapping the column headers (as read in) to column numbers and use that
to generate the slice limits.  Since that still relies on the column
headers being what you expect them to be, and at least partially in the
order you expect them to be, it's probably not enough of a win to bother
with.

Trying to slice a list by value is never going to look pretty because
lists aren't designed to be indexed by value.  Worse, if you were
doing this a lot (as you imply) then it's going to be horribly
inefficient, since you're doing an extra two (or more) O(n) searches
for every row.

--
Rhodri James *-* Wildebeeste Herder to the Masses
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to chose a slice of a list?

2009-05-20 Thread walterbyrd
On May 19, 5:31 pm, Ben Finney  wrote:

> That's just the same micro-goal re-stated. What is your larger problem
> of which this is a part? Perhaps a better approach can be suggested when
> that context is known.

I am processing a huge spreadsheet which I have converted to a csv
format. Each row will be a wiki page with several sub-headings. The
spreadsheet contains information about servers. Wiki sub-headings may
include: 'hardware', 'software', 'users', 'network swith settings'.
'Hardware' may include the spreadsheet columns: 'memory', 'cpu', and
so on. So the first six columns in the spreadsheet may go under
'hardware' the next six under 'software' and so on.

I have already created the wiki pages, using a method similar to what
I first posted. But, it seems like there should be a better way to to
do it. So, for future reference, I was just wondering.

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


Re: Is there a better way to chose a slice of a list?

2009-05-20 Thread Piet van Oostrum
> walterbyrd  (w) wrote:

>w> On May 8, 5:55 pm, John Yeung  wrote:
>>> On May 8, 3:03 pm,walterbyrd wrote:
>>> 
>>> > This works, but it seems like there should be a better way.
>>> 
>>> > --
>>> > week = ['sun','mon','tue','wed','thu','fri','sat']
>>> > for day in week[week.index('tue'):week.index('fri')]:
>>> >    print day
>>> > ---
>>> 
>>> I think you should provide much more information, primarily why you
>>> want to do this.  What is the larger goal you are trying to achieve?

>w> I am just looking for a less verbose, more elegant, way to print a
>w> slice of a list. What is hard to understand about that? I am not sure
>w> how enumerated types help.

You didn't say that in the OP.

But you can extend the list type to accept slices with strings in them.
The language spec says they should be ints but apparently this is not
enforced. Of course this makes it vulnerable for future misbehaviour.

class KeyList(list):
def __getitem__(self, indx):
if isinstance(indx, slice):
start = indx.start
stop = indx.stop
# add support for step if you want
if not isinstance(start, int):
start = self.index(start)
if not isinstance(stop, int):
stop = self.index(stop)
return list.__getitem__(self, slice(start,stop))
return list.__getitem__(self, indx)

week = KeyList(['sun','mon','tue','wed','thu','fri','sat'])
for day in week['tue':'fri']:
   print day

tue
wed
thu

Note that 'fri' is not included according to standard Python conventions
about the end of a slice. Change the code if you are not happy with it
and you don't mind getting inconsistent semantics.
-- 
Piet van Oostrum 
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email: p...@vanoostrum.org
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to chose a slice of a list?

2009-05-19 Thread Steven D'Aprano
On Tue, 19 May 2009 14:38:19 -0700, walterbyrd wrote:

> On May 8, 5:55 pm, John Yeung  wrote:
>> On May 8, 3:03 pm,walterbyrd wrote:
>>
>> > This works, but it seems like there should be a better way.
>>
>> > --
>> > week = ['sun','mon','tue','wed','thu','fri','sat'] for day in
>> > week[week.index('tue'):week.index('fri')]:
>> >    print day
>> > ---
>>
>> I think you should provide much more information, primarily why you
>> want to do this.  What is the larger goal you are trying to achieve?
> 
> I am just looking for a less verbose, more elegant, way to print a slice
> of a list. What is hard to understand about that? I am not sure how
> enumerated types help.

Printing a slice of a list is about as concise and elegant as possible:

print alist[slice_obj]

or

print alist[start:end:step]

But that's not what the example in your first post suggests. Your example 
suggests you have *two* problems:

(1) Given a slice, how to print each item in the slice _individually_.

The answer to that is 

for x in aslice:
print x

Pretty concise and elegant.



(2) Given an arbitrary starting and ending _item_ rather than _position_, 
how to concisely and elegantly generate a slice.

There are many answers, depending on _why_ you want to do this. One 
possible answer is to write a function to do it:

def print_slice(alist, start_item, end_item):
start_pos = alist.index(start_item)
end_pos = alist.index(end_item)
for x in alist[start_pos:end_pos]:
print x

Now print_slice(week, 'tue', 'fri') is pretty concise and elegant.

Another answer is: Don't do that, do something else. If you have an 
enumerated type, then you could (in principle) do this:

week = enumerated('mon tue wed thu fri sat sun')
for x in week.tue-week.fri:
print x


depending on the enumerated type itself naturally.



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


Re: Is there a better way to chose a slice of a list?

2009-05-19 Thread John Machin
On May 20, 7:38 am, walterbyrd  wrote:
> On May 8, 5:55 pm, John Yeung  wrote:
>
> > On May 8, 3:03 pm,walterbyrd wrote:
>
> > > This works, but it seems like there should be a better way.
>
> > > --
> > > ---
>
> > I think you should provide much more information, primarily why you
> > want to do this.  What is the larger goal you are trying to achieve?
>
> I am just looking for a less verbose, more elegant, way to print a
> slice of a list. What is hard to understand about that?

Ummm two things, (1) You didn't say that was what you wanted (2) It's
a nonsense anyway:

Your original statement "choose a slice of alist": answer = alist
[lo:hi]

Your current statement "print a slice of a list" (one element per line
as per your example): can not be done much less verbosely and more
elegantly than:
for x in alist[lo:hi]:
print x

Your real problem appears to be the horrid method of deriving lo and
hi.

You gave ONE example without stating anything more precise than that
it was an example of a slice of a list [which was obvious anyway] and
didn't specify in what sense of "better" you wanted a better way. So
people have to guess what you really want.

Guessing that the 'tue' and 'fri' in your one example will always be
constants, here are two options:

E.g. given
week = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']

Option (1):
SUN, MON, TUE, WED, THU, FRI, SAT = range(7)
for day in week[TUE:FRI]:
print day

Option (2):
for day in week[2:5]:
print day

HTH,
John
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to chose a slice of a list?

2009-05-19 Thread Ben Finney
walterbyrd  writes:

> On May 8, 5:55 pm, John Yeung  wrote:
> > On May 8, 3:03 pm,walterbyrd wrote:
> > I think you should provide much more information, primarily why you
> > want to do this.  What is the larger goal you are trying to achieve?
> 
> I am just looking for a less verbose, more elegant, way to print a
> slice of a list.

That's just the same micro-goal re-stated. What is your larger problem
of which this is a part? Perhaps a better approach can be suggested when
that context is known.

-- 
 \ “What's another word for Thesaurus?” —Steven Wright |
  `\   |
_o__)  |
Ben Finney
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to chose a slice of a list?

2009-05-19 Thread Rhodri James
On Tue, 19 May 2009 22:38:19 +0100, walterbyrd   
wrote:



On May 8, 5:55 pm, John Yeung  wrote:

On May 8, 3:03 pm,walterbyrd wrote:

> This works, but it seems like there should be a better way.

> --
> week = ['sun','mon','tue','wed','thu','fri','sat']
> for day in week[week.index('tue'):week.index('fri')]:
>    print day
> ---

I think you should provide much more information, primarily why you
want to do this.  What is the larger goal you are trying to achieve?


I am just looking for a less verbose, more elegant, way to print a
slice of a list. What is hard to understand about that? I am not sure
how enumerated types help.


This is verbose and inelegant because of the way you're storing and
using the data, hence (I presume) John's question.  The more elegant
approach is not to try to index a list with strings, but to keep you
"day" data in numeric form and use that to slice with, and for that
enums will greatly help you keep things clear.  However, whether that's
worth doing or not depends on the bigger picture, and you haven't
told us anything that would help us figure that out.

--
Rhodri James *-* Wildebeeste Herder to the Masses
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to chose a slice of a list?

2009-05-19 Thread Terry Reedy

walterbyrd wrote:

On May 8, 5:55 pm, John Yeung  wrote:

On May 8, 3:03 pm,walterbyrd wrote:


This works, but it seems like there should be a better way.
--
week = ['sun','mon','tue','wed','thu','fri','sat']
for day in week[week.index('tue'):week.index('fri')]:
   print day
---

I think you should provide much more information, primarily why you
want to do this.  What is the larger goal you are trying to achieve?


I am just looking for a less verbose, more elegant, way to print a
slice of a list. 


week[2:5] # ;-)

If you want the interpreter to turn non-ints into ints for you, you will 
have to give it some sort of function or mapping to use.


dayint = {day:i for i,day in enumeratr(week)} # works in Py3 at least
week[dayint['tue']:dayint['fri']]

# or, untested, basing attrodic on memory of posted code

class attrodic(): #py3
  def __init__(self, dic):
self.__dict__.update(dic)

di = attrodic(week)
week[di.tue:di.fri]

Most elegant, and most setup work ;-).

Terry Jan Reedy

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


Re: Is there a better way to chose a slice of a list?

2009-05-19 Thread walterbyrd
On May 8, 5:55 pm, John Yeung  wrote:
> On May 8, 3:03 pm,walterbyrd wrote:
>
> > This works, but it seems like there should be a better way.
>
> > --
> > week = ['sun','mon','tue','wed','thu','fri','sat']
> > for day in week[week.index('tue'):week.index('fri')]:
> >    print day
> > ---
>
> I think you should provide much more information, primarily why you
> want to do this.  What is the larger goal you are trying to achieve?

I am just looking for a less verbose, more elegant, way to print a
slice of a list. What is hard to understand about that? I am not sure
how enumerated types help.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to chose a slice of a list?

2009-05-09 Thread John Yeung
On May 8, 3:03 pm, walterbyrd  wrote:
> This works, but it seems like there should be a better way.
>
> --
> week = ['sun','mon','tue','wed','thu','fri','sat']
> for day in week[week.index('tue'):week.index('fri')]:
>    print day
> ---

I think you should provide much more information, primarily why you
want to do this.  What is the larger goal you are trying to achieve?

In the absence of further information, it seems to me that you are
trying to create an enumerated type.  For various ideas to achieve
this simply, depending on your purpose, see

  http://norvig.com/python-iaq.html

If you want a more thorough treatment, maybe try this package:

  http://pypi.python.org/pypi/enum/

There may be other recipes and packages; you can Google for them using
keywords "python enum" or similar.

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


Re: Is there a better way to chose a slice of a list?

2009-05-09 Thread pruebauno
On May 8, 3:03 pm, walterbyrd  wrote:
> This works, but it seems like there should be a better way.
>
> --
> week = ['sun','mon','tue','wed','thu','fri','sat']
> for day in week[week.index('tue'):week.index('fri')]:
>    print day
> ---

Depending on the context this style might help:

>>> week = ['sun','mon','tue','wed','thu','fri','sat']
>>> tue_fri = slice(week.index('tue'), week.index('fri'))
>>> for day in week[tue_fri]:
print day

But I don't really see it as an improvement unless you are using those
intervals repeatedly.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way of doing this?

2009-03-07 Thread Tim Wintle
On Sun, 2009-03-08 at 15:49 +1100, Steven D'Aprano wrote:
> If the environmental costs of recycling something are worse than the
> environmental costs of throwing it away and making a new one, then
> recycling that object is actually harmful. But I digress.

Unless you live in a country that imports most of these goods, in which
case by recycling you keep money in the economy rather than buying goods
from elsewhere - it's never mentioned, but I'm fairly certain that's one
of the main reasons that the UK government loves forcing us to recycle
so much.

(obviously doesn't change how "environmentally harmful" something is)

Tim Wintle



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


Re: Is there a better way of doing this?

2009-03-07 Thread Steven D'Aprano
Gabriel Genellina wrote:

> Imagine you're working with someone side by side. You write a note in a
> piece of paper, put it into an envelope, and hand it to your co-worker. He
> opens the envelope, throws it away, takes the note and files it inside a
> folder right at the end. And you do this over and over. What's wrong in
> this story?
> 
> Please save our trees! Don't waste so many envelopes

Nice story, but the moral "conserve what you use" is not always good advice.
Bits are not envelopes -- sometimes it is more environmentally friendly to
throw them away and create new ones. Consider:

mylist[:] = [x for x in mylist if not condition(x)]

versus:

for i in xrange(len(mylist)-1, -1, -1):
x = mylist[i]
if condition(x):
del mylist[i]


The first "wastefully" creates a new list, and the second tries to recycle
bits by deleting the items in place. Unless mylist is so huge that your
computer starts thrashing trying to make two copies in memory, the first is
not only simpler to write and understand, but almost certainly much, much
faster than the second.

That's not the case in this specific example, but as a general principle,
it's worth remembering that it's often better to be wasteful with temporary
objects than to use miserly algorithms invented for machines with 64K of
memory.

(The same lessons can apply for re-world considerations as well. Recycling
doesn't just happen, it requires energy and water and other costs. If the
environmental costs of recycling something are worse than the environmental
costs of throwing it away and making a new one, then recycling that object
is actually harmful. But I digress.)


-- 
Steven

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


Re: Is there a better way of doing this?

2009-03-07 Thread Peter Otten
Lie Ryan wrote:

> mattia wrote:

>> Yes, sorry, I have to recycle! But how about this:

> rw = [[2,4], [4,5,6],[5,5]]
> rw += [[1,1]]*2
> rw
>> [[2, 4], [4, 5, 6], [5, 5], [1, 1], [1, 1]]

>> How can I recicle in this way using append?
> 
> Not .append() but .extend()

Whether you use

items += [item]*N

or

items.extend([item]*N)

is mostly a matter of style. You can avoid the intermediate list with

items.extend(itertools.repeat(item, N))

but I don't think this approach is faster.

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


Re: Is there a better way of doing this?

2009-03-07 Thread Lie Ryan

mattia wrote:

Il Sat, 07 Mar 2009 00:05:53 -0200, Gabriel Genellina ha scritto:


En Fri, 06 Mar 2009 21:31:01 -0200, mattia  escribió:


Thanks, I've found another solution here:
http://www.obitko.com/tutorials/
genetic-algorithms/selection.php
so here is my implementation:


def get_fap(fitness, population):
fap = []
total = 0
for x in population:
f = fitness(x)
fap += [(f, x)]
total += f
return sorted(fap, reverse=True), total

Imagine you're working with someone side by side. You write a note in a
piece of paper, put it into an envelope, and hand it to your co-worker.
He opens the envelope, throws it away, takes the note and files it
inside a folder right at the end. And you do this over and over. What's
wrong in this story?

Please save our trees! Don't waste so many envelopes - that's just what
this line does:

  fap += [(f, x)]

Environmentally friendly Pythoneers avoid using discardable intermediate
envelopes:

  fap.append((f, x))

Please recycle!


Yes, sorry, I have to recycle! But how about this:

rw = [[2,4], [4,5,6],[5,5]]
rw += [[1,1]]*2
rw

[[2, 4], [4, 5, 6], [5, 5], [1, 1], [1, 1]]

rw = [[2,4], [4,5,6],[5,5]]
rw.append([1,1]*2)
rw

[[2, 4], [4, 5, 6], [5, 5], [1, 1, 1, 1]]

rw = [[2,4], [4,5,6],[5,5]]
rw.append([[1,1]]*2)
rw

[[2, 4], [4, 5, 6], [5, 5], [[1, 1], [1, 1]]]
How can I recicle in this way using append?


Not .append() but .extend()

>>> rw = [[2,4], [4,5,6],[5,5]]
>>> rw.extend([[1,1]]*2)
>>> rw
> [[2, 4], [4, 5, 6], [5, 5], [1, 1], [1, 1]]
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way of doing this?

2009-03-07 Thread mattia
Il Sat, 07 Mar 2009 00:05:53 -0200, Gabriel Genellina ha scritto:

> En Fri, 06 Mar 2009 21:31:01 -0200, mattia  escribió:
> 
>> Thanks, I've found another solution here:
>> http://www.obitko.com/tutorials/
>> genetic-algorithms/selection.php
>> so here is my implementation:
>>
>>
>> def get_fap(fitness, population):
>> fap = []
>> total = 0
>> for x in population:
>> f = fitness(x)
>> fap += [(f, x)]
>> total += f
>> return sorted(fap, reverse=True), total
> 
> Imagine you're working with someone side by side. You write a note in a
> piece of paper, put it into an envelope, and hand it to your co-worker.
> He opens the envelope, throws it away, takes the note and files it
> inside a folder right at the end. And you do this over and over. What's
> wrong in this story?
> 
> Please save our trees! Don't waste so many envelopes - that's just what
> this line does:
> 
>   fap += [(f, x)]
> 
> Environmentally friendly Pythoneers avoid using discardable intermediate
> envelopes:
> 
>   fap.append((f, x))
> 
> Please recycle!

Yes, sorry, I have to recycle! But how about this:
>>> rw = [[2,4], [4,5,6],[5,5]]
>>> rw += [[1,1]]*2
>>> rw
[[2, 4], [4, 5, 6], [5, 5], [1, 1], [1, 1]]
>>> rw = [[2,4], [4,5,6],[5,5]]
>>> rw.append([1,1]*2)
>>> rw
[[2, 4], [4, 5, 6], [5, 5], [1, 1, 1, 1]]
>>> rw = [[2,4], [4,5,6],[5,5]]
>>> rw.append([[1,1]]*2)
>>> rw
[[2, 4], [4, 5, 6], [5, 5], [[1, 1], [1, 1]]]
>>>
How can I recicle in this way using append?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way of doing this?

2009-03-06 Thread Paul Rubin
"Gabriel Genellina"  writes:
> > for x in population:
> > f = fitness(x)
> > fap += [(f, x)]
> > total += f
> > return sorted(fap, reverse=True), total
> ...
> Environmentally friendly Pythoneers avoid using discardable
> intermediate  envelopes:
> 
>   fap.append((f, x))

I'd probably use:

 fap = list((fitness(x),x) for x in population)
 total = sum(x for x,y in fap)
 return sorted(fap, reverse=True), total
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way of doing this?

2009-03-06 Thread Gabriel Genellina

En Fri, 06 Mar 2009 21:31:01 -0200, mattia  escribió:

Thanks, I've found another solution here:  
http://www.obitko.com/tutorials/

genetic-algorithms/selection.php
so here is my implementation:


def get_fap(fitness, population):
fap = []
total = 0
for x in population:
f = fitness(x)
fap += [(f, x)]
total += f
return sorted(fap, reverse=True), total


Imagine you're working with someone side by side. You write a note in a  
piece of paper, put it into an envelope, and hand it to your co-worker. He  
opens the envelope, throws it away, takes the note and files it inside a  
folder right at the end. And you do this over and over. What's wrong in  
this story?


Please save our trees! Don't waste so many envelopes - that's just what  
this line does:


 fap += [(f, x)]

Environmentally friendly Pythoneers avoid using discardable intermediate  
envelopes:


 fap.append((f, x))

Please recycle!

--
Gabriel Genellina

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


Re: Is there a better way of doing this?

2009-03-06 Thread mattia
Il Fri, 06 Mar 2009 14:13:47 -0800, Scott David Daniels ha scritto:

> mattia wrote:
>> Here is my last shot, where I get rid of all the old intermediate
>> functions:
>> 
>> def selection(fitness, population):
>> lp = len(population)
>> roulette_wheel = []
>> for x in population:
>> roulette_wheel += [x]*fitness(x)
>> selected_population = [[]]*lp
>> selected_population[:2] = sorted(population, key=fitness,
>> reverse=True)[:2]
>> selected_population[2:] = [choice(roulette_wheel) for _ in range
>> (lp-2)]
> Try something like this to choose likely couples:
> 
>  import random
>  import bisect
> 
>  def choose_pairs(fitness_population, decider=random):
>  '''Pick and yield pairs weighted by fitness for crossing.
> 
>  We assume weighted_population has fitness already calculated.
>  decide is a parameter to allow testing. '''
>  total = 0
>  cumulative = []
>  candidates = []
>  for fitness, individual in set(fitness_population):
>  # calculate total weights, extract real candidates if
>  fitness > 0:
>  total += fitness
>  cumulative.append(total)
>  candidates.append(individual)
>  assert len(candidates) > 1
>  while True:
>  # pick a candidate by weight
>  c0 = decider.random() * total
>  first = bisect.bisect_left(cumulative, c0) if first:
>  weighting = cumulative[first] - cumulative[first - 1]
>  else:
>  weighting = cumulative[0]
>  # pick another distinct candidate by fitness c1 = choice =
>  decider.random() * (total - weighting) if choice >=
>  cumulative[first] - weighting:
>  choice += weight # adjust to avoid selecting first
>  second = bisect.bisect_left(cumulative, choice) yield
>  candidates[first], candidates[second]
> 
> --Scott David Daniels
> scott.dani...@acm.org

Thanks, I've found another solution here: http://www.obitko.com/tutorials/
genetic-algorithms/selection.php
so here is my implementation:

def create_chromosome(min, max, length):
return [randint(min, max) for i in range(length)]

def create_population(nelem, min, max, length):
# preconditions: nelem > 1 and nelem is even
if not nelem > 1:
nelem = 2
if not nelem%2 == 0:
print("The population must have an even number of elements. 
Correcting...")
nelem += 1  
return [create_chromosome(min, max, length) for i in range(nelem)]

def get_fap(fitness, population):
fap = []
total = 0
for x in population:
f = fitness(x)
fap += [(f, x)]
total += f
return sorted(fap, reverse=True), total

def my_rw():
list, tot = get_fap(sum, pop)
r = randint(0, tot-1)
i = 0
print(r)
for f, e in list:
i += f
print(i)
if i > r:
return e
return [] # never reached

if __name__ == "__main__":
pop = create_population(5, 0, 1, 10)
# selection_mat(sum, pop)
#print(rw(sum, pop))
list, tot = get_fap(sum, pop)
print(list)
print(tot)
for i in range(6):
print(my_rw())
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way of doing this?

2009-03-06 Thread mattia
Il Fri, 06 Mar 2009 18:46:44 -0300, andrew cooke ha scritto:

> i have not been following this discussion in detail, so someone may have
> already explained this, but it should not be necessary to actually
> construct the roulette wheel to select values from it.  what you are
> doing is selecting from a list where the there are different
> probabilities of selecting different entries.  i am pretty sure that can
> be done more efficiently than by constructing a new list with many more
> entries whose aim is to simulate that (which is what the roulette wheel
> seems to be in your code, if i have understood correctly).
> 
> more precisely, i think you can adapt the trick used to select a line at
> random from a file by scanning the file just once.
> 
> sorry if i have misunderstood,
> andrew

Well, I believe that using the right distribution I can for sure find a 
better way for doing the roulette wheel selection. When I'll have enough 
time I'll pick up my statistics book.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way of doing this?

2009-03-06 Thread Scott David Daniels

mattia wrote:
Here is my last shot, where I get rid of all the old intermediate 
functions:


def selection(fitness, population):
lp = len(population)
roulette_wheel = []
for x in population:
roulette_wheel += [x]*fitness(x)
selected_population = [[]]*lp
selected_population[:2] = sorted(population, key=fitness, 
reverse=True)[:2]

selected_population[2:] = [choice(roulette_wheel) for _ in range
(lp-2)]

Try something like this to choose likely couples:

import random
import bisect

def choose_pairs(fitness_population, decider=random):
'''Pick and yield pairs weighted by fitness for crossing.

We assume weighted_population has fitness already calculated.
decide is a parameter to allow testing.
'''
total = 0
cumulative = []
candidates = []
for fitness, individual in set(fitness_population):
# calculate total weights, extract real candidates
if fitness > 0:
total += fitness
cumulative.append(total)
candidates.append(individual)
assert len(candidates) > 1
while True:
# pick a candidate by weight
c0 = decider.random() * total
first = bisect.bisect_left(cumulative, c0)
if first:
weighting = cumulative[first] - cumulative[first - 1]
else:
weighting = cumulative[0]
# pick another distinct candidate by fitness
c1 = choice = decider.random() * (total - weighting)
if choice >= cumulative[first] - weighting:
choice += weight # adjust to avoid selecting first
second = bisect.bisect_left(cumulative, choice)
yield candidates[first], candidates[second]

--Scott David Daniels
scott.dani...@acm.org
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way of doing this?

2009-03-06 Thread andrew cooke

i have not been following this discussion in detail, so someone may have
already explained this, but it should not be necessary to actually
construct the roulette wheel to select values from it.  what you are doing
is selecting from a list where the there are different probabilities of
selecting different entries.  i am pretty sure that can be done more
efficiently than by constructing a new list with many more entries whose
aim is to simulate that (which is what the roulette wheel seems to be in
your code, if i have understood correctly).

more precisely, i think you can adapt the trick used to select a line at
random from a file by scanning the file just once.

sorry if i have misunderstood,
andrew


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


Re: Is there a better way of doing this?

2009-03-06 Thread mattia
Il Fri, 06 Mar 2009 22:28:00 +0100, Peter Otten ha scritto:

> mattia wrote:
> 
>> Il Fri, 06 Mar 2009 14:06:14 +0100, Peter Otten ha scritto:
>> 
>>> mattia wrote:
>>> 
 Hi, I'm new to python, and as the title says, can I improve this
 snippet (readability, speed, tricks):
 
 def get_fitness_and_population(fitness, population):
 return [(fitness(x), x) for x in population]
 
 def selection(fitness, population):
 '''
 Select the parent chromosomes from a population according to
 their fitness (the better fitness, the bigger chance to be
 selected) ''' selected_population = []
 fap = get_fitness_and_population(fitness, population) pop_len =
 len(population)
 # elitism (it prevents a loss of the best found solution) # take
 the only 2 best solutions
 elite_population = sorted(fap)
 selected_population += [elite_population[pop_len-1][1]] +
 [elite_population[pop_len-2][1]]
 # go on with the rest of the elements for i in range(pop_len-2):
 # do something
>>> 
>>> def selection1(fitness, population, N=2):
>>> rest = sorted(population, key=fitness, reverse=True) best =
>>> rest[:N] del rest[:N]
>>> # work with best and rest
>>> 
>>> 
>>> def selection2(fitness, population, N=2):
>>> decorated = [(-fitness(p), p) for p in population]
>>> heapq.heapify(decorated)
>>> 
>>> best = [heapq.heappop(decorated)[1] for _ in range(N)] rest = [p
>>> for f, p in decorated]
>>> # work with best and rest
>>> 
>>> Both implementations assume that you are no longer interested in the
>>> individuals' fitness once you have partitioned the population in two
>>> groups.
>>> 
>>> In theory the second is more efficient for "small" N and "large"
>>> populations.
>>> 
>>> Peter
>> 
>> Ok, but the fact is that I save the best individuals of the current
>> population, than I'll have to choose the others elements of the new
>> population (than will be N-2) in a random way. The common way is using
>> a roulette wheel selection (based on the fitness of the individuals, if
>> the total fitness is 200, and one individual has a fitness of 10, that
>> this individual will have a 0.05 probability to be selected to form the
>> new population). So in the selection of the best solution I have to use
>> the fitness in order to get the best individual, the last individual
>> use the fitness to have a chance to be selected. Obviously the old
>> population anf the new population must have the same number of
>> individuals.
> 
> You're right, it was a bad idea.
> 
> Peter

Here is my last shot, where I get rid of all the old intermediate 
functions:

def selection(fitness, population):
lp = len(population)
roulette_wheel = []
for x in population:
roulette_wheel += [x]*fitness(x)
selected_population = [[]]*lp
selected_population[:2] = sorted(population, key=fitness, 
reverse=True)[:2]
selected_population[2:] = [choice(roulette_wheel) for _ in range
(lp-2)]
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way of doing this?

2009-03-06 Thread Peter Otten
mattia wrote:

> Il Fri, 06 Mar 2009 14:06:14 +0100, Peter Otten ha scritto:
> 
>> mattia wrote:
>> 
>>> Hi, I'm new to python, and as the title says, can I improve this
>>> snippet (readability, speed, tricks):
>>> 
>>> def get_fitness_and_population(fitness, population):
>>> return [(fitness(x), x) for x in population]
>>> 
>>> def selection(fitness, population):
>>> '''
>>> Select the parent chromosomes from a population according to their
>>> fitness (the better fitness, the bigger chance to be selected) '''
>>> selected_population = []
>>> fap = get_fitness_and_population(fitness, population) pop_len =
>>> len(population)
>>> # elitism (it prevents a loss of the best found solution) # take
>>> the only 2 best solutions
>>> elite_population = sorted(fap)
>>> selected_population += [elite_population[pop_len-1][1]] +
>>> [elite_population[pop_len-2][1]]
>>> # go on with the rest of the elements for i in range(pop_len-2):
>>> # do something
>> 
>> def selection1(fitness, population, N=2):
>> rest = sorted(population, key=fitness, reverse=True) best = rest[:N]
>> del rest[:N]
>> # work with best and rest
>> 
>> 
>> def selection2(fitness, population, N=2):
>> decorated = [(-fitness(p), p) for p in population]
>> heapq.heapify(decorated)
>> 
>> best = [heapq.heappop(decorated)[1] for _ in range(N)] rest = [p for
>> f, p in decorated]
>> # work with best and rest
>> 
>> Both implementations assume that you are no longer interested in the
>> individuals' fitness once you have partitioned the population in two
>> groups.
>> 
>> In theory the second is more efficient for "small" N and "large"
>> populations.
>> 
>> Peter
> 
> Ok, but the fact is that I save the best individuals of the current
> population, than I'll have to choose the others elements of the new
> population (than will be N-2) in a random way. The common way is using a
> roulette wheel selection (based on the fitness of the individuals, if the
> total fitness is 200, and one individual has a fitness of 10, that this
> individual will have a 0.05 probability to be selected to form the new
> population). So in the selection of the best solution I have to use the
> fitness in order to get the best individual, the last individual use the
> fitness to have a chance to be selected. Obviously the old population anf
> the new population must have the same number of individuals.

You're right, it was a bad idea.

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


Re: Is there a better way of doing this?

2009-03-06 Thread mattia
Il Fri, 06 Mar 2009 14:06:14 +0100, Peter Otten ha scritto:

> mattia wrote:
> 
>> Hi, I'm new to python, and as the title says, can I improve this
>> snippet (readability, speed, tricks):
>> 
>> def get_fitness_and_population(fitness, population):
>> return [(fitness(x), x) for x in population]
>> 
>> def selection(fitness, population):
>> '''
>> Select the parent chromosomes from a population according to their
>> fitness (the better fitness, the bigger chance to be selected) '''
>> selected_population = []
>> fap = get_fitness_and_population(fitness, population) pop_len =
>> len(population)
>> # elitism (it prevents a loss of the best found solution) # take
>> the only 2 best solutions
>> elite_population = sorted(fap)
>> selected_population += [elite_population[pop_len-1][1]] +
>> [elite_population[pop_len-2][1]]
>> # go on with the rest of the elements for i in range(pop_len-2):
>> # do something
> 
> def selection1(fitness, population, N=2):
> rest = sorted(population, key=fitness, reverse=True) best = rest[:N]
> del rest[:N]
> # work with best and rest
> 
> 
> def selection2(fitness, population, N=2):
> decorated = [(-fitness(p), p) for p in population]
> heapq.heapify(decorated)
> 
> best = [heapq.heappop(decorated)[1] for _ in range(N)] rest = [p for
> f, p in decorated]
> # work with best and rest
> 
> Both implementations assume that you are no longer interested in the
> individuals' fitness once you have partitioned the population in two
> groups.
> 
> In theory the second is more efficient for "small" N and "large"
> populations.
> 
> Peter

Ok, but the fact is that I save the best individuals of the current 
population, than I'll have to choose the others elements of the new 
population (than will be N-2) in a random way. The common way is using a 
roulette wheel selection (based on the fitness of the individuals, if the 
total fitness is 200, and one individual has a fitness of 10, that this 
individual will have a 0.05 probability to be selected to form the new 
population). So in the selection of the best solution I have to use the 
fitness in order to get the best individual, the last individual use the 
fitness to have a chance to be selected. Obviously the old population anf 
the new population must have the same number of individuals.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way of doing this?

2009-03-06 Thread Paul Rubin
Chris Rebert  writes:
>for i in range(len(fap)):
>selected_population.append(choice(rw))

"for i in range(len(something))" is a bit of a code smell.  You could
instead say:

   selected_population.extend(choice(rw) for x in fap)

The unused "x" is also a slight code smell, but the most obvious cures
involve using the itertools module in ways that are worse than the disease.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way of doing this?

2009-03-06 Thread Peter Otten
mattia wrote:

> Hi, I'm new to python, and as the title says, can I improve this snippet
> (readability, speed, tricks):
> 
> def get_fitness_and_population(fitness, population):
> return [(fitness(x), x) for x in population]
> 
> def selection(fitness, population):
> '''
> Select the parent chromosomes from a population according to their
> fitness (the better fitness, the bigger chance to be selected)
> '''
> selected_population = []
> fap = get_fitness_and_population(fitness, population)
> pop_len = len(population)
> # elitism (it prevents a loss of the best found solution)
> # take the only 2 best solutions
> elite_population = sorted(fap)
> selected_population += [elite_population[pop_len-1][1]] +
> [elite_population[pop_len-2][1]]
> # go on with the rest of the elements
> for i in range(pop_len-2):
> # do something

def selection1(fitness, population, N=2):
rest = sorted(population, key=fitness, reverse=True)
best = rest[:N]
del rest[:N]
# work with best and rest


def selection2(fitness, population, N=2):
decorated = [(-fitness(p), p) for p in population]
heapq.heapify(decorated)

best = [heapq.heappop(decorated)[1] for _ in range(N)]
rest = [p for f, p in decorated]
# work with best and rest

Both implementations assume that you are no longer interested in the
individuals' fitness once you have partitioned the population in two
groups.

In theory the second is more efficient for "small" N and "large"
populations.

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


Re: Is there a better way of doing this?

2009-03-06 Thread Chris Rebert
On Fri, Mar 6, 2009 at 3:52 AM, mattia  wrote:
> Il Fri, 06 Mar 2009 03:43:22 -0800, Chris Rebert ha scritto:
>
>> On Fri, Mar 6, 2009 at 3:07 AM, mattia  wrote:
>>> Great, the for statement has not to deal with fap anymore, but with
>>> another sequence, like this:
>>>
>>> def get_roulette_wheel(weight_value_pairs):
>>>    roulette_wheel = []
>>>    for weight, value in weight_value_pairs:
>>>        roulette_wheel += [value]*weight
>>>    return roulette_wheel
>>>
>>> def selection(fitness, population):
>>>    ...
>>>    rw = get_roulette_wheel(fap)
>>>    for i in range(pop_len-2):
>>>        selected_population += [choice(rw)]
>>>    return selected_population
>>>
>>> I think that using [choice(rw)]*len(fap) will produce the same sequence
>>> repeted len(fap) times...
>>
>> Revision to this new code:
>>
>> def get_roulette_wheel(weight_value_pairs):
>>    return [[value]*weight for weight, value in weight_value_pairs]
>>
>> def selection(fitness, population):
>>    ...
>>    rw = get_roulette_wheel(fap)
>>    for i in range(len(fap)):
>>        selected_population.append(choice(rw))
>>    return selected_population
>>
>> Cheers,
>> Chris
>
> Great, append is equivalent to += right? or more efficient?

Yes. .append(item) is equivalent to += [item] and is more efficient.

Cheers,
Chris

-- 
I have a blog:
http://blog.rebertia.com
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way of doing this?

2009-03-06 Thread mattia
Il Fri, 06 Mar 2009 03:43:22 -0800, Chris Rebert ha scritto:

> On Fri, Mar 6, 2009 at 3:07 AM, mattia  wrote:
>> Great, the for statement has not to deal with fap anymore, but with
>> another sequence, like this:
>>
>> def get_roulette_wheel(weight_value_pairs):
>>    roulette_wheel = []
>>    for weight, value in weight_value_pairs:
>>        roulette_wheel += [value]*weight
>>    return roulette_wheel
>>
>> def selection(fitness, population):
>>    ...
>>    rw = get_roulette_wheel(fap)
>>    for i in range(pop_len-2):
>>        selected_population += [choice(rw)]
>>    return selected_population
>>
>> I think that using [choice(rw)]*len(fap) will produce the same sequence
>> repeted len(fap) times...
> 
> Revision to this new code:
> 
> def get_roulette_wheel(weight_value_pairs):
>return [[value]*weight for weight, value in weight_value_pairs]
> 
> def selection(fitness, population):
>...
>rw = get_roulette_wheel(fap)
>for i in range(len(fap)):
>selected_population.append(choice(rw))
>return selected_population
> 
> Cheers,
> Chris

Great, append is equivalent to += right? or more efficient?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way of doing this?

2009-03-06 Thread Chris Rebert
On Fri, Mar 6, 2009 at 3:07 AM, mattia  wrote:
> Great, the for statement has not to deal with fap anymore, but with
> another sequence, like this:
>
> def get_roulette_wheel(weight_value_pairs):
>    roulette_wheel = []
>    for weight, value in weight_value_pairs:
>        roulette_wheel += [value]*weight
>    return roulette_wheel
>
> def selection(fitness, population):
>    ...
>    rw = get_roulette_wheel(fap)
>    for i in range(pop_len-2):
>        selected_population += [choice(rw)]
>    return selected_population
>
> I think that using [choice(rw)]*len(fap) will produce the same sequence
> repeted len(fap) times...

Revision to this new code:

def get_roulette_wheel(weight_value_pairs):
   return [[value]*weight for weight, value in weight_value_pairs]

def selection(fitness, population):
   ...
   rw = get_roulette_wheel(fap)
   for i in range(len(fap)):
   selected_population.append(choice(rw))
   return selected_population

Cheers,
Chris

-- 
I have a blog:
http://blog.rebertia.com
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way of doing this?

2009-03-06 Thread mattia
Il Fri, 06 Mar 2009 10:19:22 +, mattia ha scritto:

> Hi, I'm new to python, and as the title says, can I improve this snippet
> (readability, speed, tricks):
> 
> def get_fitness_and_population(fitness, population):
> return [(fitness(x), x) for x in population]
> 
> def selection(fitness, population):
> '''
> Select the parent chromosomes from a population according to their
> fitness (the better fitness, the bigger chance to be selected) '''
> selected_population = []
> fap = get_fitness_and_population(fitness, population) pop_len =
> len(population)
> # elitism (it prevents a loss of the best found solution) # take the
> only 2 best solutions
> elite_population = sorted(fap)
> selected_population += [elite_population[pop_len-1][1]] +
> [elite_population[pop_len-2][1]]
> # go on with the rest of the elements for i in range(pop_len-2):
> # do something

Great, the for statement has not to deal with fap anymore, but with 
another sequence, like this:

def get_roulette_wheel(weight_value_pairs):
roulette_wheel = []
for weight, value in weight_value_pairs:
roulette_wheel += [value]*weight
return roulette_wheel

def selection(fitness, population):
...
rw = get_roulette_wheel(fap)
for i in range(pop_len-2):
selected_population += [choice(rw)]
return selected_population

I think that using [choice(rw)]*len(fap) will produce the same sequence 
repeted len(fap) times...
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way of doing this?

2009-03-06 Thread Chris Rebert
On Fri, Mar 6, 2009 at 2:19 AM, mattia  wrote:
> Hi, I'm new to python, and as the title says, can I improve this snippet
> (readability, speed, tricks):
>
> def get_fitness_and_population(fitness, population):
>    return [(fitness(x), x) for x in population]
>
> def selection(fitness, population):
>    '''
>    Select the parent chromosomes from a population according to their
>    fitness (the better fitness, the bigger chance to be selected)
>    '''
>    selected_population = []
>    fap = get_fitness_and_population(fitness, population)
>    pop_len = len(population)
>    # elitism (it prevents a loss of the best found solution)
>    # take the only 2 best solutions
>    elite_population = sorted(fap)
>    selected_population += [elite_population[pop_len-1][1]] +
> [elite_population[pop_len-2][1]]
>    # go on with the rest of the elements
>    for i in range(pop_len-2):
>        # do something

Removing the unnecessary use of sorted() and using list.pop() rather
than explicit indices:

def selection(fitness, population):
   '''
   Select the parent chromosomes from a population according to their
   fitness (the better fitness, the bigger chance to be selected)
   '''
   fap = get_fitness_and_population(fitness, population)
   fap.sort()
   # elitism (it prevents a loss of the best found solution)
   # take the only 2 best solutions
   selected_population = [fap.pop()[1] for i in range(2)]

   # go on with the rest of the elements
   for fit, pop in fap:
   #do something

Cheers,
Chris

-- 
I have a blog:
http://blog.rebertia.com
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way to implement this:

2007-01-23 Thread Peter Otten
Paul Boddie wrote:

> Michael Yanowitz wrote:
>>
>>I guess I am looking for something portable (both
>> Windows and Linux) where I can abort a function after
>> a certain time limit expires.
> 
> Doing a search for "timeout function Python" on Google reveals a number
> of approaches.
 
> Using threads:
> 
>   * http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473878

That doesn't abort the calculation, however -- it just moves on with a
default value instead of the actual result if that is not available after
the specified timespan. 

The calculation may go on forever eating up resources.

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


Re: Is there a better way to implement this:

2007-01-22 Thread Paul Boddie
Michael Yanowitz wrote:
>
>I guess I am looking for something portable (both
> Windows and Linux) where I can abort a function after
> a certain time limit expires.

Doing a search for "timeout function Python" on Google reveals a number
of approaches.

Using signals:

  * http://nick.vargish.org/clues/python-tricks.html
  * http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/307871

Using threads:

  * http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473878

Using processes:

  * http://lfw.org/python/delegate.html

Paul

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


RE: Is there a better way to implement this:

2007-01-22 Thread Michael Yanowitz
Thanks.

   I suppose I could have used time.sleep(seconds) here.
I did it in 0.01 because in an earlier verion, I did something
else between the sleeps.
   I guess I am looking for something portable (both
Windows and Linux) where I can abort a function after
a certain time limit expires.

-Original Message-
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] Behalf
Of Benjamin Niemann
Sent: Monday, January 22, 2007 11:19 AM
To: python-list@python.org
Subject: Re: Is there a better way to implement this:


Michael Yanowitz wrote:

> Hello:
>
>I wrote the code below (much irrelevant code removed).
> This doesn't quite work. What I wanted it to do was
>  a) Execute function ftimed, which takes a function and a timeout
> in seconds.
>  b) This will also execute function abort() as a thread.
> This function just runs for the specified
> number of seconds and returns.
> However, before it returns, throws an exception.
> c)  If test() is still running when abort() is
> finished, ftimed() should catch the exception and
> return.
>
> It is catching the exception, however it continues running the function.
> Why does it continue and not return?

The exception is raised in the thread that executes the abort() function.
The exception does not get caught and terminates this thread. The other
(main) thread is unaffected - exceptions are local to a thread and there is
currently no (portable) way to raise an exception in another thread.

> What am I missing, or is there a better way to
> implement this (having ftimed() return when the
> abort-timer time is exceeded?

You may use the signal.alarm() function, if you are on a UNIXoid system and
you have only a signle time-out at a time (e.g. not nested).

> import time, thread, sys
>
> thread_finished = "MAX RUN TIME EXCEEDED!"
>
> def abort (seconds):
>  start_time = time.time()
>  while ((time.time() - start_time) < seconds):
> time.sleep(0.01)

any reason for not using time.sleep(seconds) here?

I suppose I could have, but in earlier versions

>  print "script run time exceeded max_run_time of", seconds, "seconds."
>  raise thread_finished
>  return
>
>
> def test():
> i = 0
> while (True):
>time.sleep(1)
>print "HELLO", i
>i+=1
>
>
> def ftimed (func, seconds):
> thread.start_new_thread (abort, (seconds,))
>
> try:
> func()
> except thread_finished:
> print  "Timeout"
> return
>
> ftimed (test, 30)
> print "Script finished"

--
Benjamin Niemann
Email: pink at odahoda dot de
WWW: http://pink.odahoda.de/
--
http://mail.python.org/mailman/listinfo/python-list


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


Re: Is there a better way to implement this:

2007-01-22 Thread Benjamin Niemann
Michael Yanowitz wrote:

> Hello:
> 
>I wrote the code below (much irrelevant code removed).
> This doesn't quite work. What I wanted it to do was
>  a) Execute function ftimed, which takes a function and a timeout
> in seconds.
>  b) This will also execute function abort() as a thread.
> This function just runs for the specified
> number of seconds and returns.
> However, before it returns, throws an exception.
> c)  If test() is still running when abort() is
> finished, ftimed() should catch the exception and
> return.
> 
> It is catching the exception, however it continues running the function.
> Why does it continue and not return?

The exception is raised in the thread that executes the abort() function.
The exception does not get caught and terminates this thread. The other
(main) thread is unaffected - exceptions are local to a thread and there is
currently no (portable) way to raise an exception in another thread.

> What am I missing, or is there a better way to
> implement this (having ftimed() return when the
> abort-timer time is exceeded?

You may use the signal.alarm() function, if you are on a UNIXoid system and
you have only a signle time-out at a time (e.g. not nested).

> import time, thread, sys
> 
> thread_finished = "MAX RUN TIME EXCEEDED!"
> 
> def abort (seconds):
>  start_time = time.time()
>  while ((time.time() - start_time) < seconds):
> time.sleep(0.01)

any reason for not using time.sleep(seconds) here?

>  print "script run time exceeded max_run_time of", seconds, "seconds."
>  raise thread_finished
>  return
> 
> 
> def test():
> i = 0
> while (True):
>time.sleep(1)
>print "HELLO", i
>i+=1
> 
> 
> def ftimed (func, seconds):
> thread.start_new_thread (abort, (seconds,))
> 
> try:
> func()
> except thread_finished:
> print  "Timeout"
> return
> 
> ftimed (test, 30)
> print "Script finished"

-- 
Benjamin Niemann
Email: pink at odahoda dot de
WWW: http://pink.odahoda.de/
-- 
http://mail.python.org/mailman/listinfo/python-list


Test functions and test discovery (was: Re: Is there a better way of accessing functions in a module?)

2006-06-13 Thread Ben Finney
"Ant" <[EMAIL PROTECTED]> writes:

> def a_test():
> print "Test A"
> 
> def b_test():
> print "Test B"

Incidentally, the convention is to name test functions as 'test_foo'
not 'foo_test'; this will make your module more easily compatible with
existing testing tools.

> if __name__ == "__main__":
> tests = ["%s()" % x for x in dir() if x.endswith("test")]
> 
> for test in tests:
> eval(test)

No need for eval. (You already found globals(), so I'll use that.)

if __name__ == "__main__":
test_funcs = [x for name, x in globals()
if name.startswith("test") and hasattr(x, "__call__")
]

for test in test_funcs:
test()

I'll concur with other posters on this thread and encourage you to
consider using the standard 'unittest' module, and recommend 'nose'
for test discovery and execution:

http://somethingaboutorange.com/mrl/projects/nose/>

-- 
 \ "Unix is an operating system, OS/2 is half an operating system, |
  `\   Windows is a shell, and DOS is a boot partition virus."  -- |
_o__)  Peter H. Coffin |
Ben Finney

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


Re: Is there a better way of accessing functions in a module?

2006-06-13 Thread Kent Johnson
Ant wrote:
> Ant wrote:
> ...
>> But this feels like a hack... Is there a cleaner way for accessing the
>> functions of the current module similar to the __dict__ attribute of
>> classes? i.e. a way to access the local symbol table?
> 
> Sorry - posted too soon. Found the globals() built-in...

You can also
import __main__
tests = [x for x in dir(__main__) if x.endswith("test")]

for test in tests:
getattr(__main__, test)()

but I second the suggestion of looking in to unittest or one of the 
other test frameworks.

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


Re: Is there a better way of accessing functions in a module?

2006-06-13 Thread Mike Kent
Yes, you can go that route.  But since it appears that what you are
doing is unit testing related, and you are interested in aranging for
all of your unit test cases to be run automatically, I'd suggest using
the unittest module.

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


Re: Is there a better way of accessing functions in a module?

2006-06-13 Thread Ant

Ant wrote:
...
> But this feels like a hack... Is there a cleaner way for accessing the
> functions of the current module similar to the __dict__ attribute of
> classes? i.e. a way to access the local symbol table?

Sorry - posted too soon. Found the globals() built-in...

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


Re: is there a better way?

2006-02-13 Thread Magnus Lycka
[EMAIL PROTECTED] wrote:
> Problem:
> 
> You have a list of unknown length, such as this: list =
> [X,X,X,O,O,O,O].  You want to extract all and only the X's.  You know
> the X's are all up front and you know that the item after the last X is
> an O, or that the list ends with an X.  There are never O's between
> X's.
> 
> I have been using something like this:
> _
> 
> while list[0] != O:
> storage.append(list[0])
> list.pop(0)
> if len(list) == 0:
> break
> _
> 
> But this seems ugly to me, and using "while" give me the heebies.  Is
> there a better approach?

It seems few suggested solutions actually do the same thing as
your code shows. I think this does. (Untested)

try:
 ix = aList.index(O)
 storage, aList = aList[:ix], aList[ix:]
except ValueError:
 # No O's
 storage, aList = aList, []


The main advantage with my approach over yours is that
all iterations, all the looping, takes place in fast C
code, unless your list elements are Python classes that
implement __cmp__ etc. If testing 'aList[0] == O'
involves Python, things might slow down a bit...

.index() takes linear time, but it's fairly fast. As
Alex suggested, you might want to replace it with a
O(log n) solution for big lists. You might need rather
big lists for the Python based O(log n) to get faster
than the C based O(n) though. Measure.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: is there a better way?

2006-02-12 Thread drrngrvy

Bruno Desthuilliers wrote:
> [EMAIL PROTECTED] a écrit :
> > Problem:
> >
> > You have a list of unknown length,
>
> This doesn't exist in Python:
>len(alist)
>
> > such as this: list > [X,X,X,O,O,O,O].  You want to extract all and only the 
> > X's.
>
> braindead solution - relying on zeros being zeros or any other False value:
> all_xxx
> >  You know
> > the X's are all up front and you know that the item after the last X is
> > an O, or that the list ends with an X.  There are never O's between
> > X's.
> >
>
> Then it *may* be possible to optimize - but code will break as soon as
> this rule change. So is there a real need for optimisation ? (hint: dont
> guess, profile)
>
>
> FWIW, I've collected all suggestions here (and perhaps some others) and
> hacked a Q&D benchmark. Usage is:
>
> python test_lists.py [repeat [list_size [xcount]]
>
> where:
> * repeat is the number of iteration, default to 1000
> * list_size is the size of the list, default to 100
> * xcount is the number or non-zero values in the list, default is random
>
> I've run it a few times, and it seems that in most cases,
>   *  the bisect-like approach (Alex Martelli / Karl Friedrich Bolz) is
> the winner
>   * the while/pop approach of the OP (slightly rewritten...) is really wrong
>
> FWIW, one of the dummiest possible approach IMHO
> (ie filter(None, alist)) behaves quite correctly wrt some other
> 'optimized' approachs - and is still safe if the rules about the
> composition of the list changes... Could it be that no optimization is
> sometime the best optimisation ?-)
>
>
> # test_lists.py
> from itertools import takewhile
> from timeit import Timer
> from random import randint
>
> def get_list(size, xcount=None):
>  if xcount is None:
>  xcount  else:
>  assert xcount < zcount  return [1] * xcount + [0] * zcount
>
> def with_while(alist):
>  res  while alist and alist[0]:
>  res.append(alist.pop(0))
>  return res
>
> def with_for(alist):
>  res  for x in alist:
>  if not x: break
>  res.append(x)
>  return res
>
> def with_filter(alist):
>  return filter(None, alist)
>
> def with_comprehension(alist):
>  return [x for x in alist if x]
>
> def with_takewhile(alist):
>  return list(takewhile(lambda x: x!=0, alist))
>
> def with_slice_try(alist):
>  try:
>  return alist[:alist.index(0)]
>  except ValueError:
>  return alist[:]
>
> def with_slice_safe(alist):
>  alist.append(0)
>  return alist[:alist.index(0)]
>
> def with_delslice_safe(alist):
>  alist.append(0)
>  del alist[alist.index(0):]
>  return alist
>
> def with_sect(alist):
>  low  high  while low < high:
>  mid  if alist[mid] = 0:
>  high  else:
>  low  return alist[:low]
>
> _candidates if n.startswith('with_') and callable(o)]
>
> def run_test(repeat00, list_size='100', xcount='None'):
>  global _candidate
>
>  print """
> params :
>   * repeat : %s
>   * list_size : %s
>   * xcounts : %s
> """  % (repeat, list_size, xcount)
>  results  for n in _candidates:
>  stm, stp  'from __main__ import %s, get_list' % 
> n)
>  results[n]
>  sorted_resultsfor n, time in 
> results.items()])
>  for _, result in sorted_results:
>  print "%s : %s" % result
>
>
> def main(args):
>  try:
>  repeat  except:
>  repeat  try:
>  list_size  except:
>  list_size  try:
>  xcount  except:
>  xcount
>  run_test(repeat, list_size, xcount)
>
> if __name__ = '__main__':
>  import sys
>  main(sys.argv[1:])
> 
> 
> HTH

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


Re: is there a better way?

2006-02-12 Thread Bruno Desthuilliers
[EMAIL PROTECTED] a écrit :
> Problem:
> 
> You have a list of unknown length,

This doesn't exist in Python:
   len(alist)

> such as this: list =
> [X,X,X,O,O,O,O].  You want to extract all and only the X's.

braindead solution - relying on zeros being zeros or any other False value:
all_xxx = filter(None, [X,X,X,O,O,O,O])

>  You know
> the X's are all up front and you know that the item after the last X is
> an O, or that the list ends with an X.  There are never O's between
> X's.
> 

Then it *may* be possible to optimize - but code will break as soon as 
this rule change. So is there a real need for optimisation ? (hint: dont 
guess, profile)


FWIW, I've collected all suggestions here (and perhaps some others) and 
hacked a Q&D benchmark. Usage is:

python test_lists.py [repeat [list_size [xcount]]

where:
* repeat is the number of iteration, default to 1000
* list_size is the size of the list, default to 100
* xcount is the number or non-zero values in the list, default is random

I've run it a few times, and it seems that in most cases,
  *  the bisect-like approach (Alex Martelli / Karl Friedrich Bolz) is 
the winner
  * the while/pop approach of the OP (slightly rewritten...) is really wrong

FWIW, one of the dummiest possible approach IMHO
(ie filter(None, alist)) behaves quite correctly wrt some other 
'optimized' approachs - and is still safe if the rules about the 
composition of the list changes... Could it be that no optimization is 
sometime the best optimisation ?-)


# test_lists.py
from itertools import takewhile
from timeit import Timer
from random import randint

def get_list(size, xcount=None):
 if xcount is None:
 xcount = randint(1, size)
 else:
 assert xcount <= size
 zcount = size - xcount
 return [1] * xcount + [0] * zcount

def with_while(alist):
 res = []
 while alist and alist[0]:
 res.append(alist.pop(0))
 return res

def with_for(alist):
 res = []
 for x in alist:
 if not x: break
 res.append(x)
 return res

def with_filter(alist):
 return filter(None, alist)

def with_comprehension(alist):
 return [x for x in alist if x]

def with_takewhile(alist):
 return list(takewhile(lambda x: x!=0, alist))

def with_slice_try(alist):
 try:
 return alist[:alist.index(0)]
 except ValueError:
 return alist[:]

def with_slice_safe(alist):
 alist.append(0)
 return alist[:alist.index(0)]

def with_delslice_safe(alist):
 alist.append(0)
 del alist[alist.index(0):]
 return alist

def with_sect(alist):
 low = 0
 high = len(alist)
 while low < high:
 mid = (low + high) // 2
 if alist[mid] == 0:
 high = mid
 else:
 low = mid + 1
 return alist[:low]

_candidates = [n for n, o  in locals().copy().items() \
if n.startswith('with_') and callable(o)]

def run_test(repeat=1000, list_size='100', xcount='None'):
 global _candidate

 print """
params :
  * repeat : %s
  * list_size : %s
  * xcounts : %s
"""  % (repeat, list_size, xcount)
 results = {}
 for n in _candidates:
 stm, stp = ('%s(get_list(%s, %s))' % (n, list_size, xcount),
 'from __main__ import %s, get_list' % n)
 results[n] =  Timer(stm, stp).timeit(repeat)

 sorted_results = sorted([(time, (n, time)) \
   for n, time in results.items()])
 for _, result in sorted_results:
 print "%s : %s" % result


def main(args):
 try:
 repeat = int(args.pop(0))
 except:
 repeat = 1000
 try:
 list_size = args.pop(0)
 except:
 list_size = '100'
 try:
 xcount = args.pop(0)
 except:
 xcount = 'None' # -> random

 run_test(repeat, list_size, xcount)

if __name__ == '__main__':
 import sys
 main(sys.argv[1:])


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


Re: is there a better way?

2006-02-11 Thread Alex Martelli
Charles Krug <[EMAIL PROTECTED]> wrote:

> On 2006-02-11, Alex Martelli <[EMAIL PROTECTED]> wrote:
> > [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
> >
> >> Problem:
> >> 
> >> You have a list of unknown length, such as this: list =
> >> [X,X,X,O,O,O,O].  You want to extract all and only the X's.  You know
> >> the X's are all up front and you know that the item after the last X is
> >> an O, or that the list ends with an X.  There are never O's between
> >> X's.
> >
> > If the list is incredibly long, you should use a bisection approach.
> > Standard module bisect in the Python library could help, but mostly as
> > an _example_, since it unfortunately relies on normal alphabetic order,
> > and alphabetically speaking X should come _after_ O, not _before_.
> 
> Isn't every call to list.index() an O(n) operation?  We certainly want
> to avoid multiple calls there if we can.

Why should we have ANY call to index whatsoever?

> What happens if your split occurs in the middle of your block of Xs?
> Then the split before/after fails --the stated algorithm says, "If the
> split is an X, choose the front half," so perhaps the statement was
> inprecise?

What statement?  What are you TALKING about?!  What I said, and you
don't quote, was:

> > 2. if it's an X, so are all previous items -- recurse to second half

how can you POSSIBLY read this as "choose the front half"?!  I say to
recurse (iteration works, too, but it's even trickier to code) to the
SECOND half, to find the first-if-any non-'X'.

> The only way you'll know if you have an X in a particular block is using
> a linear search method, either in Python or with list.index()

Reread markscala's problem statement: all the Xs are up front followed
by 0 or more Os.  So, the list is L = ['X']*N + ['O']*M for unknown N>=0
and M>=0.  All we have to do is find N and M (if we know either, the
other is immediately computed, since N+M==len(L) and len() is O(1)).

> If (as the OP seemed to state) we KNOW that there's only one block of
> X's in the list:
> 
> 1. Find the index of the first X

Why would we do that?  He stated, very clearly, and you and I have both
been quoting:

> >> You know
> >> the X's are all up front 

So why would we do any work to find out what we altrady know?

> 2. Find the index of the last X.

Yep, the only certain task, and it's O(log(N+M)).

> 3. Delete the block we've found.

And the deletion is definitely linear time (and trivial), of course.  I
was focusing on the only interesting part, (2).

> Judging from way the OP worded the question, I'd advise making something
> that works and that you understand how it works.
> 
> After that, s/he can worry about whether or not its performance is
> suboptimal.

And indeed, part of what I said (and again you're snipping it rather
than quoting it was:

> > If N is not too huge, O(N) might be OK, and is, of course, way simpler
> > to code!-)

However, even though the O(N) in the deletion subtask would appear to
justify this shortcut, I think the task is way too trivial to justify a
linear-time approach to point 2 -- the obvious N = L.count('X'), of
course.  It seems likely that the whole purpose of the exercise
(probably homework) is to have the student identify and develop a
bisection (a notoriously tricky-to-code thing).


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


Re: is there a better way?

2006-02-11 Thread Carl Friedrich Bolz
Hi!

[EMAIL PROTECTED] wrote:
> Problem:
> 
> You have a list of unknown length, such as this: list =
> [X,X,X,O,O,O,O].  You want to extract all and only the X's.  You know
> the X's are all up front and you know that the item after the last X is
> an O, or that the list ends with an X.  There are never O's between
> X's.
> 
> I have been using something like this:
> _
> 
> while list[0] != O:
> storage.append(list[0])
> list.pop(0)
> if len(list) == 0:
> break
> _
> 
> But this seems ugly to me, and using "while" give me the heebies.  Is
> there a better approach?

Depends on what you mean with "better". I (heavily inspired by the 
bisect module) came up with:

low = 0
high = len(L)
while low < high:
 mid = (low + high) // 2
 if L[mid] == 0:
 high = mid
 else:
 low = mid + 1
storage = L[:low]

This has the advantage to be more efficient compared to other 
approaches, which of course only matters if your list is big. It still 
features a "while" loop, though.

> hope this is clear.

It is not entirely clear what the X is supposed to be. I assumed that it 
can be anything except 0.

Cheers,

Carl Friedrich

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


Re: is there a better way?

2006-02-11 Thread Carl Friedrich Bolz
Alex Martelli wrote:
> [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
> 
> 
>>Problem:
>>
>>You have a list of unknown length, such as this: list =
>>[X,X,X,O,O,O,O].  You want to extract all and only the X's.  You know
>>the X's are all up front and you know that the item after the last X is
>>an O, or that the list ends with an X.  There are never O's between
>>X's.
> 
> 
> If the list is incredibly long, you should use a bisection approach.
> Standard module bisect in the Python library could help, but mostly as
> an _example_, since it unfortunately relies on normal alphabetic order,
> and alphabetically speaking X should come _after_ O, not _before_.
> 
> But the algorithm is still sound:
> 
> 1. look at the midpoint.
> 2. if it's an X, so are all previous items -- recurse to second half
> 3. if it's an O, so are all following items -- recurse to first half
> 
> Getting all conditions exactly right is tricky (which is why bisect is a
> good model!), but this way you get O(log N) performance for a list of
> length N.
> 
> If N is not too huge, O(N) might be OK, and is, of course, way simpler
> to code!-)
> 

The code would look something like this:

low = 0
high = len(L)
while low < high:
 mid = (low + high) // 2
 if L[mid] == 0:
 high = mid
 else:
 low = mid + 1
list_of_X = L[:low]


Cheers,

Carl Friedrich Bolz

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


Re: is there a better way?

2006-02-11 Thread Steve Holden
[EMAIL PROTECTED] wrote:
> Problem:
> 
> You have a list of unknown length, such as this: list =
> [X,X,X,O,O,O,O].  You want to extract all and only the X's.  You know
> the X's are all up front and you know that the item after the last X is
> an O, or that the list ends with an X.  There are never O's between
> X's.
> 
> I have been using something like this:
> _
> 
> while list[0] != O:
> storage.append(list[0])
> list.pop(0)
> if len(list) == 0:
> break
> _
> 
> But this seems ugly to me, and using "while" give me the heebies.  Is
> there a better approach?
> 
> hope this is clear.

  >>> X = "X"
  >>> O = "O"
  >>> def fl(l):
  ...   for i, v in enumerate(l):
  ... if v == O:
  ...   return l[:i]
  ...   return l
  ...
  >>> fl([X,X,X,X,O,O,O])
['X', 'X', 'X', 'X']
  >>> fl([])
[]
  >>> fl([O])
[]
  >>> fl([X])
['X']
  >>>

regards
  Steve
-- 
Steve Holden   +44 150 684 7255  +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006  www.python.org/pycon/

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


Re: is there a better way?

2006-02-11 Thread Charles Krug
On 2006-02-11, Alex Martelli <[EMAIL PROTECTED]> wrote:
> [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
>
>> Problem:
>> 
>> You have a list of unknown length, such as this: list =
>> [X,X,X,O,O,O,O].  You want to extract all and only the X's.  You know
>> the X's are all up front and you know that the item after the last X is
>> an O, or that the list ends with an X.  There are never O's between
>> X's.
>
> If the list is incredibly long, you should use a bisection approach.
> Standard module bisect in the Python library could help, but mostly as
> an _example_, since it unfortunately relies on normal alphabetic order,
> and alphabetically speaking X should come _after_ O, not _before_.
>

Isn't every call to list.index() an O(n) operation?  We certainly want
to avoid multiple calls there if we can.

What happens if your split occurs in the middle of your block of Xs?
Then the split before/after fails --the stated algorithm says, "If the
split is an X, choose the front half," so perhaps the statement was
inprecise?

The only way you'll know if you have an X in a particular block is using
a linear search method, either in Python or with list.index()

If (as the OP seemed to state) we KNOW that there's only one block of
X's in the list:

1. Find the index of the first X
2. Find the index of the last X.
3. Delete the block we've found.

That relies on the underlying language, which means we're working in
"Linear Time in C", more or less.

If we make no such guarantee, then I can do the operation in linear
"Python Time" by scanning the list once, finding each instance and
calling list.del() as I find each block, keeping track of my current
position so I don't have to start over again.

Judging from way the OP worded the question, I'd advise making something
that works and that you understand how it works.

After that, s/he can worry about whether or not its performance is
suboptimal.

How large must the list be before "logarithmic Python algorithm" is
faster than "linear C algorithm"?  I've never measured, but it may be a
question worth exploring if one has a huge pile of data to chew on--like
US Census or UN budget-sized.




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


Re: is there a better way?

2006-02-10 Thread Paul Rubin
"[EMAIL PROTECTED]" <[EMAIL PROTECTED]> writes:
> But this seems ugly to me, and using "while" give me the heebies.  Is
> there a better approach?

Note that "list" is the name of a built-in type; I used "mylist".
Alex Martelli described how to do it in log n time using the bisect
module.  Here's a dumb linear time method that might be faster for
small n (of course you should time the different methods for your
particular Python implementation, if the speed matters):

   del mylist[len(mylist) - mylist.count(0):]

The above an example of where the natural

   del mylist[-mylist.count(0):]

does totally the wrong thing if there are no 0's in the list.  There
was a huge thread a while back about ways to fix that.

Another way, might be faster, esp. there's more than a few 0's:

   try:
 del mylist[mylist.index(0)]
   except ValueError: 
 pass   # no 0's in the list
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: is there a better way?

2006-02-10 Thread Alex Martelli
[EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:

> Problem:
> 
> You have a list of unknown length, such as this: list =
> [X,X,X,O,O,O,O].  You want to extract all and only the X's.  You know
> the X's are all up front and you know that the item after the last X is
> an O, or that the list ends with an X.  There are never O's between
> X's.

If the list is incredibly long, you should use a bisection approach.
Standard module bisect in the Python library could help, but mostly as
an _example_, since it unfortunately relies on normal alphabetic order,
and alphabetically speaking X should come _after_ O, not _before_.

But the algorithm is still sound:

1. look at the midpoint.
2. if it's an X, so are all previous items -- recurse to second half
3. if it's an O, so are all following items -- recurse to first half

Getting all conditions exactly right is tricky (which is why bisect is a
good model!), but this way you get O(log N) performance for a list of
length N.

If N is not too huge, O(N) might be OK, and is, of course, way simpler
to code!-)


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


Re: is there a better way?

2006-02-10 Thread Dave Hansen
On Sat, 11 Feb 2006 01:37:59 +0100 in comp.lang.python, Schüle Daniel
<[EMAIL PROTECTED]> wrote:

>Lonnie Princehouse wrote:
>> everybody is making this way more complicated than it needs to be.
>> 
>> storage = list[:list.index(O)]
>
>the question is whether the old list is needed in the future or not
>if not then it would be easer/mor efficient to use
>
>del lst[lst.index(0):]

And you're both forgetting the list can end with X.  the index method
raises a ValueError exception if the desired value is not found in the
list.  Assuming you want to keep the original list and create a new
list called storage, you could try

   if lst[-1] == X:
  storage = lst[:]
   else:
  storage = lst[:lst.index(O)]

or even

   try:
  storage = lst[:lst.index(O)]
   except ValueError:
  storage = lst[:]

(WARNING: untested!)

Regards,


   
-=Dave

-- 
Change is inevitable, progress is not.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: is there a better way?

2006-02-10 Thread Scott David Daniels
Scott David Daniels wrote:
> [EMAIL PROTECTED] wrote:
>> Problem:
>>
>> You have a list of unknown length, such as this: list =
>> [X,X,X,O,O,O,O].  You want to extract all and only the X's.  You know
>> the X's are all up front and you know that the item after the last X is
>> an O, or that the list ends with an X.  There are never O's between
>> X's.
>>
>> I have been using something like this:
>> while list[0] != O:
>> storage.append(list[0])
>> list.pop(0)
>> if len(list) == 0:
>> break
>> But this seems ugly to me, and using "while" give me the heebies.  Is
>> there a better approach?
>>
> 
> Your names could be better as someone mentioned.
> ex, oh = 7, 13   # for example
> data = [ex, ex, ex, oh, oh, oh, oh]
> If you need a list distinct from the original:
> try:
> result = data[: data.index(oh)]
> except ValueError:
> result = list(data)
> 
> Or you could simply:
> try:
> data = data[: data.index(oh)]
> except ValueError:
> pass
> and data will be either the sublist you want or the original list.

I forgot the obvious:

 result = data.count(ex) * [ex]

-- 
-Scott David Daniels
[EMAIL PROTECTED]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: is there a better way?

2006-02-10 Thread Schüle Daniel
I don't want to hijack the thread I was thinking
whether something like lst.remove(item = 0, all = True)
would be worth adding to Python?

it could have this signature

def remove(item, nItems = 1, all = False)
...
return how_many_deleted

lst.remove(item = 0, nItems = 1)
lst.remove(item = 0, nItems = 2)

lst.remove(item = 0, all = True)
in last case nItems is ignored

Regards, Daniel

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


Re: is there a better way?

2006-02-10 Thread Schüle Daniel
Lonnie Princehouse wrote:
> everybody is making this way more complicated than it needs to be.
> 
> storage = list[:list.index(O)]

the question is whether the old list is needed in the future or not
if not then it would be easer/mor efficient to use

del lst[lst.index(0):]

Regards, Daniel

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


Re: is there a better way?

2006-02-10 Thread Jeremy Dillworth
You could eliminate a few lines like this:

-
while list and list[0] != O:
storage.append(list.pop(0))
-

Adding the "list and " to the front of the logic test will catch when
there are 0 elements, so the "if..break" lines are not needed.  Also
pop() returns the element popped, so there's no need for a separate
"list[0]" and "list.pop(0)"

You could also do the whole thing as a list comprehension (assuming
storage is a list, otherwise += may or may not work):
-
storage += [i for i in list if i == X]
-

But this is less efficient, since it will loop through all the O's too.
 The other solution stops at the first O.  This will also break if
there are any X's mixed with O's, though you've said that's not
currently the case, things can always change.

Lastly, you could do this:
-
list.append(O)
storage += list[:list.index(O)]
-

The first line makes sure there is always an O in list, otherwise
index(O) will throw an exception.  That's slightly ugly, but I still
like this solution, myself.

hope this helps,

Jeremy

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


Re: is there a better way?

2006-02-10 Thread Lonnie Princehouse
everybody is making this way more complicated than it needs to be.

storage = list[:list.index(O)]

incidentally, "list" is the name of a type, so you might want to avoid
using it as a variable name.

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


Re: is there a better way?

2006-02-10 Thread Schüle Daniel
[...]

> I have been using something like this:
> _
> 
> while list[0] != O:
> storage.append(list[0])
> list.pop(0)
> if len(list) == 0:
> break
> _
> 
> But this seems ugly to me, and using "while" give me the heebies.  Is
> there a better approach?

 >>> lst = [1,2,3,4,5,0,0,0,0]
 >>> del lst[lst.index(0):]
 >>> lst
[1, 2, 3, 4, 5]
 >>>

Regards, Daniel

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


Re: is there a better way?

2006-02-10 Thread Schüle Daniel
[...]

> 
> What not
> 
> for x in list:
>   if x == O:
> break
>   storage.append(x)
> 

i think this may take too long
better aproach would be to test for zero from the end

Regards, Daniel

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


Re: is there a better way?

2006-02-10 Thread Scott David Daniels
[EMAIL PROTECTED] wrote:
> Problem:
> 
> You have a list of unknown length, such as this: list =
> [X,X,X,O,O,O,O].  You want to extract all and only the X's.  You know
> the X's are all up front and you know that the item after the last X is
> an O, or that the list ends with an X.  There are never O's between
> X's.
> 
> I have been using something like this:
> while list[0] != O:
> storage.append(list[0])
> list.pop(0)
> if len(list) == 0:
> break
> But this seems ugly to me, and using "while" give me the heebies.  Is
> there a better approach?
> 

Your names could be better as someone mentioned.
 ex, oh = 7, 13   # for example
 data = [ex, ex, ex, oh, oh, oh, oh]
If you need a list distinct from the original:
 try:
 result = data[: data.index(oh)]
 except ValueError:
 result = list(data)

Or you could simply:
 try:
 data = data[: data.index(oh)]
 except ValueError:
 pass
and data will be either the sublist you want or the original list.

-- 
-Scott David Daniels
[EMAIL PROTECTED]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: is there a better way?

2006-02-10 Thread Paul McGuire
"Paul McGuire" <[EMAIL PROTECTED]> wrote in message
news:[EMAIL PROTECTED]
> <[EMAIL PROTECTED]> wrote in message
> news:[EMAIL PROTECTED]
> > Problem:
> >
> > You have a list of unknown length, such as this: list =
> > [X,X,X,O,O,O,O].  You want to extract all and only the X's.  You know
> > the X's are all up front and you know that the item after the last X is
> > an O, or that the list ends with an X.  There are never O's between
> > X's.
> >
> > I have been using something like this:
> > _
> >
> > while list[0] != O:
> > storage.append(list[0])
> > list.pop(0)
> > if len(list) == 0:
> > break
> > _
> >
> > But this seems ugly to me, and using "while" give me the heebies.  Is
> > there a better approach?
> >
> > hope this is clear.
> > thanks
> >
> Use itertools.
>
> >>> import itertools
> >>> lst = "X,X,X,O,O,O,O,O,X,X,X,X,O,X".split(",")
> >>> [z for z in itertools.takewhile(lambda x:x=="X",lst)]
> ['X', 'X', 'X']
>
>
> -- Paul
>

duh, last line should be:

>>> list(itertools.takewhile(lambda x:x=="X",lst))
['X', 'X', 'X']

(Also, don't name variables "list")

-- Paul


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


Re: is there a better way?

2006-02-10 Thread Paul McGuire
<[EMAIL PROTECTED]> wrote in message
news:[EMAIL PROTECTED]
> Problem:
>
> You have a list of unknown length, such as this: list =
> [X,X,X,O,O,O,O].  You want to extract all and only the X's.  You know
> the X's are all up front and you know that the item after the last X is
> an O, or that the list ends with an X.  There are never O's between
> X's.
>
> I have been using something like this:
> _
>
> while list[0] != O:
> storage.append(list[0])
> list.pop(0)
> if len(list) == 0:
> break
> _
>
> But this seems ugly to me, and using "while" give me the heebies.  Is
> there a better approach?
>
> hope this is clear.
> thanks
>
Use itertools.

>>> import itertools
>>> lst = "X,X,X,O,O,O,O,O,X,X,X,X,O,X".split(",")
>>> [z for z in itertools.takewhile(lambda x:x=="X",lst)]
['X', 'X', 'X']


-- Paul


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


  1   2   >