Looking for contract developer(s) - where can I find them?

2007-02-21 Thread Scott SA
Hi,

I've just sent a job listing to python.org and posted this message on
comp.lang.python, but am also trying to proactively find python developers
through other means. 

python.org and guru.com notwithstanding, most job-sites to seem only support
people/organizations looking for full/part-time employment or with
full-time/part-time positions instead of work-for-hire. I require the latter,
and in the very near future (days). I'm not looking for an employee as I cannot
guarantee long-term work, though much of what is available is fairly consistent
(on the board is a 4-week job, followed by another 6-week one).

If anyone has ideas where I might find talented individuals and small companies
offering (reasonably-priced i.e. not $125/hr like a local firm charges) python
services, I'd be most appreciative.

We are developing and extending a couple of projects previously developed for
clients and replacing a 5-year-old Zope site, all with django, PostgreSQL etc.
The work is immediately available for an experienced, self-motivated python
web-application programmer. 

For those on this list that might be interested, I'm looking for self-motivated
developers with excellent python skills and if possible experience with django
(along with CVS/Subversion, PostgreSQL, SSH, vi/emacs and other open-source
projects & tools). Zope experience would be handy too as one job is to replace
an old site with a spanky-new django one. 

Good communication and organizational skills are important. Documentation &
commenting are also very important along with the ability to work alone and
with others. Meeting deadlines, consistent development pace and accurate
reporting are also key. Finally, having a sense of humor is valuable... as you
might find yourself being called Bruce (especially if your name is Ryan, Shawn
or Mike... as the other guys workin' for me already have those names. Then
again if your name is really Bruce... 8-)

I'd prefer someone from Western Canada (the other half of the country would be
okay too, I guess), but if necessary will consider talented individuals from
North America. Due to time-zone and possible language/communication issues,
off-shore developers are not attractive _at_this_time_ (sorry). 

Please submit a resume or other description of qualifications along with
availability, desired rate and examples of work (i.e. URLs of projects and what
you did on them and/or sample code showing _typical_ style of work).

Thanks for any assitance, greatly appreciated.

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


Re: Binary search tree

2007-11-12 Thread Scott SA
On 11/12/07, Michel Albert ([EMAIL PROTECTED]) wrote:

>On Nov 9, 11:45 pm, Bruno Desthuilliers
><[EMAIL PROTECTED]> wrote:
>> [EMAIL PROTECTED] a Ècrit :
>>
>> > Hi,
>>
>> > I have to get list of URLs one by one and to find the URLs that I have
>> > more than one time(can't be more than twice).
>>
>> > I thought to put them into binary search tree, this way they'll be
>> > sorted and I'll be able to check if the URL already exist.
>>
>> What about a set ?
>>
>> s = set()
>> for url in urls:
>>if url in s:
>>  print "already have ", url
>>else:
>>  set.add(url)
>
>Interesting. For this case I usually used dicts. As in:
>
>d = {}
>for url in urls:
>   if url in d:
>  print "already have ", url
>   else:
>  d[url] = 1
>
>Now, I can see that this method has some superfluous data (the `1`
>that is assigned to the dict). So I suppose this is less memory
>efficient. But is this slower then? As both implementations use hashes
>of the URL to access the data. Just asking out of curiosity ;)


I'm pretty new at python but found this recipie in a cookbook (thanks O'Reilly 
for a useful book). I also found it online later, when the cookbook wasn't 
handy:



... google for more

It uses the 'setdefault' function and works _really_ well.



Basically looks like this:

unique_urls = {}
for url in urls:
unique_urls.setdefault(url)

['www.somewhere.com', 'www.somewherelse.com', 'www.somewherelse.com']

... creates a dict of None's*
{'www.somewhere.com': None, 'www.somewherelse.com': None}


and "harvesting" is trivial:
url_keys= unique_urls.keys()


If you would find an index and count useful, you could do something like this:

for idx in range(len(urls)):
unique_urls.setdefault(urls[idx],[]).append(idx)
...
   {'www.somewhere.com': [0], 'www.somewherelse.com': [1,2]}

later, the url's, their index values and counts could be found by:

url_keys= unique_urls.keys()
for url_key in url_keys:
url_idxs= unique_urls[url_key]
url_hits= len(url_idxs)

Depending upon the data you may have associated with your URLs, or whatever 
else you're working with, this is a very sweet 'shortcut'.

I hope this helps,

Scott

* To be trully Python-esque, 'habits' would be employed and the value would 
have been 'Nun', but I guess the namesake can only be carried so far (^8
-- 
http://mail.python.org/mailman/listinfo/python-list

Re: Binary search tree

2007-11-12 Thread Scott SA
On 11/12/07, Scott SA ([EMAIL PROTECTED]) wrote:

Uhm sorry, there is a slightly cleaner way of running the second option I 
presented (sorry for the second post).

>If you would find an index and count useful, you could do something like this:
>
>for idx in range(len(urls)):
>unique_urls.setdefault(urls[idx],[]).append(idx)

   for idx,url in enumerate(urls):
   unique_urls.setdefault(url,[]).append(idx)


I decided to test the speeds of the four methods:

set_example
s = set()
for url in urls:
if not url in s:
s.add(url)

dict_example
d = {}
for url in urls:
if url in d:
d[url] = 1

setdefault_idx_example
unique_urls   = {}
for idx in range(len(urls)):
unique_urls.setdefault(urls[idx],[]).append(idx)

setdefault_enum_example
unique_urls   = {}
for idx,url in enumerate(urls):
   unique_urls.setdefault(url,[]).append(idx)


Here are the results:

Starting tests with 50 simulated URLs run 3 times.

'set' example
run time: 0.5505 seconds
'dict' example
run time: 0.2521 seconds
'setdefault_idx' example
run time: 3.6476 seconds
'setdefault_enum' example
run time: 2.5606 seconds


For the simple quest of "Find the unique URLs in a list", the 'dict' example is 
by far the quickest.

Buuut, if you need the indexes and possibly a 'hit count', then the enumerated 
example seems about the best (of the possibilities tested)

Scott

PS. For those interesed in my test suite, I submit the following:

import time

#  convenience methods 

def build_list(seed_list,base_count):
"""
Make a bogus list of urls with duplicates 
"""
return_list = []
for x in range(base_count):
temp_list = []
for i in range(1000):
for url in seed_list:   # add a unique set
temp_list.append(('www.%d_%s' % (i,url)))
return_list += temp_list

return return_list

def run_testscript(example_name, urls):
"""
run the given script name
"""
start_time  = time.time()
exec('%s_example(urls)' % example_name)
run_time = time.time() - start_time

return run_time

def run_tests(example_list, urls, iterations):

print "Starting tests with %d simulated URLs run %d times.\n%s" % \
(len(urls), iterations, 60 * '-')

for example_name in example_list:
time_value  = 0.0
for i in range(iterations):
time_value  += run_testscript(example_name, urls)

print '\'%s\' example\n%srun time: %0.4f seconds' % \
(example_name, 20 * ' ', time_value/iterations)
print 60*'-'

#  the various tests/examples 

def setdefault_idx_example(urls):
unique_urls   = {}
for idx in range(len(urls)):
unique_urls.setdefault(urls[idx],[]).append(idx)

def setdefault_enum_example(urls):
unique_urls   = {}
for idx,url in enumerate(urls):
   unique_urls.setdefault(url,[]).append(idx)

def set_example(urls):
s = set()
for url in urls:
if not url in s:
s.add(url)

def dict_example(urls):
d = {}
for url in urls:
if url in d:
d[url] = 1

#  run 'em all 

url_seedlist= 
['somewhere.com','nowhere.net','elsewhere.gov','here.ca','there.org']
dummy_urls  = build_list(url_seedlist,100) # number of duplicates
testscript_list = ['set','dict', 'setdefault_idx','setdefault_enum']

run_tests(testscript_list, dummy_urls, 3)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: which Python ? asks beginner

2007-11-17 Thread Scott SA
On 11/17/07, [EMAIL PROTECTED] ([EMAIL PROTECTED]) wrote:

>Have given up Java. Want to switch to Python.  But _which_ ?
>There is ver : 
> 2.5  out now
> 2.6  in beta , final expected Apr 2008
> 3.0   ? in alpha or beta
> 3.0 final expected Sep 2008 ?
>Will the real python please stand up. 

In the early stages of learning, the core of 2.5 compared to earlier versions 
will be functionally similar if not identical. I have books on version 2.2, for 
example, that are still quite relevent today for a majority of things.

"Go big or go home" can be a precarious philosophy to live by, so why live on 
the edge, when you don't know where the edge is? (let alone how sharp, steep or 
deap it is once you get there).

0.02

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


Re: Interfaces.

2007-11-19 Thread Scott SA
On 11/17/07, Duncan Booth ([EMAIL PROTECTED]) wrote:

>Bjoern Schliessmann <[EMAIL PROTECTED]> wrote:
>
>> Benjamin wrote:
>>> Python is has duck typing. "If it quacks like a duke, it's duck."
>> 
>> How do dukes quack, exactly? :)
>
>They quack with a North-eastern Scottish accent of course.
>
>The following excerpt from "Scots: Practical Approaches" should make it 
>clear:
>
>> A. From Scotland the What?, by Buff Hardie, Stephen Robertson and
>> George Donald (Gordon Wright, 1987) 
>> 
>> In this comic monologue from 1982, the owner of a toy shop in
>> Ballater, near Aberdeen telephones the Princess of Wales to ask what
>> her son would like for Christmas. 
>> 
>> Noo, fit wid he like for his Christmas, the loon? Fit aboot a pair o‚
>> fitba beets? Beets. Beets. B-O-O-T-S, beets. Weel, I ken that, but
../snip/...
>> D-U-C-K, duke. A quack quack duke. Like Donald Duke. Donald Duke. He‚s
>> a freen‚ o‚ Mickey Moose...Moose...M-O-U-S-E, Moose! God, div ye nae
>> understan‚ English, lassie? 

I think me sister wah bit be onae eese. 
Is ears nae long enuff ta be a rrhabbitt, an ah latter nae care fer cheese.

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

Re: may be a bug in string.rstrip

2007-11-22 Thread Scott SA
On 11/23/07, kyo guan ([EMAIL PROTECTED]) wrote:

>   Please look at this code:   
>
 'exe.torrent'.rstrip('.torrent')
>'ex'   <-  it should be 'exe', why?
>
>but this is a right answer:
>
 '120.exe'.rstrip('.exe')
>'120'  <-- this is a right value.
>
>   there is a bug in the rstrip, lstrip there isn't this problem.

Since your error has been addressed, I'd like to offer a point not expressed by 
others (that I've seen yet).

To perform this task, there are a couple of options i.e. string.replace:

>>> string.replace('120.exe','.exe','')
'120'

... but it has a side-effect of mid-string replacements:

>>> string.replace('123.exe.more','.exe','')
'123.more'

or maybe:

>>> if x[-4:] == '.exe': 
... x[:-4]
'123'

... is functional, but not elegant i.e. quick 'n dirty esp. as one line.

The better option, IMO, is probably to use regex. The module you would use is 
"re".

There are a lot of cool things you can do with regex, one of them in relation 
to your needs, is the ability to replace substrings:

>>> import re
>>> reg = re.compile('(.exe)$') # the $ means end of line
>>> reg.sub('','123.exe') 
'123'
>>> reg.sub('','123.exe.more')  # test for mid-string placement
'123.exe.more'

Clearly, it is more typing than your original string.strip approach. But as you 
see, it has the ability to expressly match what you were looking for.

Of course, it has the ability to do case-insensitive replacements too... and 
the elegance _starts_ to show here:

>>> reg = re.compile('.(exe|ini|com|fred|wendy)$',re.IGNORECASE)
>>> reg.sub('','123.exe') 
'123'
>>> reg.sub('','123.EXE') 
'123'
>>> reg.sub('','123.WenDy')
'123'

... would you like fries with that?

Just imagine what this would look like using the previous non-regex examples, 
or maybe not as halloween was _last_ month (scary stuff indeed!).

Here are some links to some great docs 8^):




S&R, what you want, is described in more detail here:



And more links at:


HTH

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


Re: may be a bug in string.rstrip

2007-11-23 Thread Scott SA
On 11/23/07, Bruno Desthuilliers ([EMAIL PROTECTED]) wrote:

>> The better option, IMO, is probably to use regex. 
>
>You forgot at least the simplest solution:
>
>import os.path
>os.path.splitext('132.ext')[0]

Yes, I did miss that one... and while I was typing there was a nagging feeling 
I was missing something. I knew I shouldn't have replied at 12:30 am.

I got on the tangent of regext because of the "rstrip" use in the initial post 
rather than the simple task of splitting the path... that's my story 'n I'm 
sticking to it 8^)



To be constructive, rather than simply spamming the list with my prev. 
comments, I submit this:

As a matter of preference, in simple scripts, prefer to
use the following when splitting paths and files:

file_name, file_ext = os.path.split('some_name.ext')


While the shorthand is cleaner, I'm not always the guy
maintaining the code.

Thanks

Scott

PS. Not all was a loss, I did learn something from one of the other replies... 
not that it helps "the rest of the world".
-- 
http://mail.python.org/mailman/listinfo/python-list


apache/mod_wsgi daemon mode

2008-02-03 Thread Scott SA
HI,

I'm posting this here because it is, I believe, a python config issue (mine) 
that is not correct, but frustration and inexperience has left me without 
further [visible] options for rectification.

I am trying to configure mod_wsgi to run in daemon mode with Apache. I can 
easily get it to run 'normally' under Apache but I obtain permission errors 
_or_ process-failures in daemon mode. Specifically: 

 ... (13)Permission denied: mod_wsgi (pid=26962): Unable to connect 
 to WSGI daemon process '' on 
'/etc/httpd/logs/wsgi.26957.0.1.sock' after multiple attempts.


My httpd.conf contains an entry like this, and has had several variations:


   ServerName host.domain.com

   WSGIDaemonProcess  user= group= threads=10 \
maximum-requests=500

   # the following line has been added/removed with no improved results
   WSGIProcessGroup 

   WSGIScriptAlias /something /path/to/

RE: apache/mod_wsgi daemon mode

2008-02-03 Thread Scott SA
On 2/3/08, Brian Smith ([EMAIL PROTECTED]) wrote:

>Scott SA wrote:
>> I am trying to configure mod_wsgi to run in daemon mode with 
>> Apache. I can easily get it to run 'normally' under Apache 
>> but I obtain permission errors _or_ process-failures in 
>> daemon mode. Specifically: 
>> 
>>  ... (13)Permission denied: mod_wsgi (pid=26962): Unable 
>> to connect 
>>  to WSGI daemon process '' on 
>> '/etc/httpd/logs/wsgi.26957.0.1.sock' after multiple attempts.
>
>> The host is Apache 2.2n under CentOS 5.1 i386 running Python 2.4
>
>Try again after "sudo /usr/sbin/setenforce 0". If it works with SELinux
>disabled then you will have to do a bit more work to get it working with
>SELinux enabled. I suggest creating a directory that is labeled with the
>Apache read/write type, and setting the WSGI socket prefix such that the
>domain sockets will get put in that directory. If that doesn't solve the
>problem then use the procedures in the SELinux documentation to create a
>security policy. And then, please share it with me. :)

I disabled SELinux during system install and have double-checked it is not 
running.

>Also, mod_wsgi has its own mailing list:
>   http://groups.google.com/group/modwsgi

I had previoiusly done what I _thought_ was a good job of searching the wsgi 
mailing list (really!). A reworking of my google search parameters finally 
yeildd a helpful thread:

<http://groups.google.com/group/modwsgi/browse_thread/thread/6d3a2f4d7c294dc/ba5cd5055bb5cc62?lnk=gst&q=daemon+unable-to-connect#ba5cd5055bb5cc62>

The problem was WSGI trying to create its .sock file in /var/log/httpd but 
failing and therefore not running at all. The user I had specified did not have 
enough permissions to do so (part of the point _of_ running in daemon mode, 
LOL). Oddly, I had attempted to grant the permissions for the user but see now 
there was an error in how I did that... oops.

By adding the following to my config:

WSGISocketPrefix /tmp/wsgi 

We now have succe!


So my config now looks like:

   WSGISocketPrefix /tmp/wsgi 

   
   ServerName host.domain.com

   WSGIDaemonProcess  user= group= threads=10 \
maximum-requests=500

   WSGIScriptAlias /something /path/to/

Linux Mag's "Introduction to Python Decorators"

2008-04-09 Thread Scott SA
Hi,

I've been trying to wrap my head around decorators and in my trails found a 
very recent article on Linux Mag's website. I didn't see a post here regarding 
this article and feel it is worth directing interested parties towards:

Introduction to Python Decorators

Have a web app that occasionally hangs? Use signals to 
add a timeout to function requests with Python decorators.

Matthew Wilson
Thursday, March 13th, 2008



The link req. registration (sorry, I can't do anything about that).

In a brief summary: The author has a Linux-hosted Web service that occasionally 
hangs. He uses signals via decorators to overcome the problem in an elegant 
way. While some of the content may not be applicable to all readers needs for 
decorators, his illustration and description of the subject is very good (IMO, 
FWIW).

I hope this helps others as much as it has for me,

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


@classmethod question

2008-04-23 Thread Scott SA
Hi,

I'm using the @classemethod decorator for some convenience methods and for some 
reason, either mental block or otherwise, can't seem to figure out how to 
elegantly detect if the call is from an instance or not.

Here's the problem: Within the class definition, 'isinstance' has nothing to 
compare to because the class does not appear to exist.

This is NOT a great example, but it outlines the the code:

class RecipieClass:
def __init__(self):
pass

@classmethod
def get_ingrendients(self, recipie_list=None):

if isinstnace(self,RecipieClass):
return self.do_something_interesting()
else:
return do_something_boring(recipie_list)

Yes, I can test to see if the param exists, but that makes the call exclusive 
i.e. I can _only_ call it as an instance or with a parameter.

Why am I doing this?

It is a series of convenience methods, in this case I'm interacting with a 
database via an ORM (object-relational model). I want the ability to call a 
class-ojbect and get related values, or pass some criteria and get related 
values for them without collecting the records first as instances, then 
iterating them. I need to call this from several places so I want to be DRY 
(don't repeat yourself).

The easiest way to describe this as an analogy would be like having a recipie 
for cookies and wanting to know all of the ingredients ahead of time. Then, at 
another time, wanting to know what all the ingredients would be to make 
cookies, cake and bread (i.e. complete shopping list).

  cookie_recipie = RecipieClass.get_recipie('cookies')
  cookie_recipie.get_ingredients()
2C Flour
0.5 C Sugar
...

  RecipieClass.get_ingrendients(['cookies','cake','bread'])
8C Flour
2C Sugar
...

Of course any suggestions on how this might be better approached would be 
interesting too.

TIA,

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


Re: @classmethod question

2008-04-29 Thread Scott SA
On 4/24/08, Bruno Desthuilliers ([EMAIL PROTECTED]) wrote:

>> It is a series of convenience methods, in this case I'm interacting
>> with a database via an ORM (object-relational model).
>
>out of curiosity : which one ?

I'm rapidly becoming a "django junkie"^TM

>> I want the ability
>> to call a class-ojbect and get related values, or pass some criteria and
>> get related values for them without collecting the records first as
>> instances, then iterating them. I need to call this from several places
>> so I want to be DRY (don't repeat yourself).
>> 
>> The easiest way to describe this as an analogy would be like having a
>> recipie for cookies and wanting to know all of the ingredients ahead of
>> time. Then, at another time, wanting to know what all the ingredients
>> would be to make cookies, cake and bread (i.e. complete shopping list).
>
>>   cookie_recipie = RecipieClass.get_recipie('cookies')
>>   cookie_recipie.get_ingredients()
>> 2C Flour
>> 0.5 C Sugar
>> ...
>> 
>>   RecipieClass.get_ingrendients(['cookies','cake','bread'])
>> 8C Flour
>> 2C Sugar
>> ...
>
> > Of course any suggestions on how this might be better approached 
>would > be interesting too.
>
>Why do you want the same method to do two different things ? You clearly 
>have two distincts methods doing different things here, and as a user of 

In retrospect, my example was poorer than I first thought - or was it my spec. 
Regardless, it wasn't quite right.

The question/premise should have been:

Is there an effective/accptable way to include
class-related utilities that are callable _without_
instantiating an object?

I now get the feeling that some of what I was thinking of would be considered 
bad form and should be separated into the application or a library of sorts.

>  your code I'd find your API confusing. May I suggest a much simpler 
>approach:
>
>class Recipies(object):
> @property
> def ingredients(self):
> return 
>
> @classmethod
> def get_ingredients_for(cls, *id_recipies):
> return 
>
>print Recipie.get('cookie').ingredients
>print Recipies.get_ingredients_for('cookie', 'cake', 'bread')

Yes, thank you. While my example didn't accurately portray my original 
thoughts, this is an educational example of merit.

I'm still crossing the bridge of conceptual understanding into practical 
application. Decoration appears very useful, it's practical application 
requires a level of thought I'm not fluent. Google is helping.

>My 2 cents...

You're short-changing yourself ;-)

Thanks for your input,

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


Re: @classmethod question

2008-04-29 Thread Scott SA
On 4/23/08, Ivan Illarionov ([EMAIL PROTECTED]) wrote:

>On 24 ???, 07:27, Scott SA <[EMAIL PROTECTED]> wrote:
>> I'm using the @classemethod decorator for some convenience methods and for 
>
>It would make sense to separate instance-level and class-level
>behaviour with additional 'objects' namespace. e.g.
>cookie_recipie.get_ingredients() to get ingredients only for cookie
>recipie and RecipieClass.objects.get_ingrendients([]) to get all
>the ingredients.

As mentioned in another reply, my example was a poor representation of what I 
was tryin to ask.

With that said, your reply is amazingly helpful in my quest to understand 
python, Django, etc. Django is the ORM I referred to, so the material you have 
written helps explain a few things.

>The elegant solution (AFAIK used by Django) would be to use metaclass
>and the object with custom descriptor for class-object/table level
>stuff.
>
>Something like this:
>
>class RecipieMetaclass(type):
>def __new__(cls, bases, attrs):
>new_cls = type.__new__(cls, name, bases, attrs)
>new_cls.objects = IngredientsDescriptor(IngredientsManager())
>return new_cls
>
>class RecipieClass(object):
>__metaclass__ = RecipieMetaclass
>def get_ingredients(self, recipie_list=None):
>return self.do_something_interesting(recipie_list)
>
>class IngredientsManager(object):
>def get_ingredients(self, recipie_list=None):
>return do_something_boring(recipie_list)
>
>class IngredientsDescriptor(object):
>def __init__(self, ingredients_manager):
>self.ingredients_manager = ingredients_manager
>def __get__(self, instance, type=None):
>if instance is not None:
>raise AttributeError, "Access via %s instances is not
>allowed" % type.__name__
>return self.ingredients_manager
>
>Then, "at another time, wanting to know what all the ingredients would
>be to make cookies, cake and bread" you would call:
>RecipieClass.objects.get_ingrendients(['cookies','cake','bread'])

I'm a little vague on the interaction of the IngredientsDescrptor VS 
IngredientsManager. I gather the 'Descriptor' class is called via the __get__ 
which then does the instance check. Could this have been done in the 'Manager' 
class?

>Both Django and Google Apps Engine API use similar concepts and you
>can learn much more interesting looking in their source code.

I have been learning a lot from the Django code and other applications written 
within it. Still, some things just don't seem to gel, even after a host of 
google searches. I've not loked at the Google Apps stuff, but will follow your 
advice.

Thanks,

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


Re: PIL and IPTC

2008-04-30 Thread Scott SA
On 4/30/08, Jumping Arne ([EMAIL PROTECTED]) wrote:

>I'm completely new to PIL and I'm trying to read IPTC info, I understand that 
>it's possible but I can't find out how (and for once Google doesn't seem to 
>be able to help). Does anyone have an example of how it's done?

Some basic PIL info:

 has a tutorial and more info

It has been a while since I had to do it but effectively, you need to open the 
image before you can extract the IPTC as I recall.

This should give you a starting point:
from PIL import IptcImagePlugin

dir(IptcImagePlugin)

then...

help(IptcImagePlugin.getiptcinfo)



A Google Search for 'how-to' gives some insight


The process is similar to reading EXIF info, I suggest you look there and 
modify as necessary. So a modified search to include EXIF


While not PIL exclusive, the following should be useful:


There are also separate libraries for IPTC with Python bindings. One is called 
libiptcdata. It lives here:


Another example using IPTCInfo:


And another python-based (non PIL) one here:


While not a direct answer, I hope this is helpful,

Scott



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


Re: Signals/Slots support in Python

2008-05-01 Thread Scott SA
On 5/1/08, Brian Vanderburg II ([EMAIL PROTECTED]) wrote:

>I don't know if any such support is already built in, so I ended up 
>making my own simple signals/slots like mechanism.  If anyone is 
>interested then here it is, along with a simple test.  It can connect to 
>normal functions as well as instance methods.  It also supports weak 
>connections where when an object is gone, the slot is gone as well, the 
>slot just holds a weak reference to the object.

Did you review this?


from what I understand is originally based upon this:


and subsequently integrated into this:


>-
># Begin Signal
>import weakref
>import random
>
>class Signal:
>class Slot:
>def __init__(self, fn):
>self.__fn = fn
>
>def __call__(self, accum, *args, **kwargs):
>result = self.__fn(*args, **kwargs)
>return accum(result)
>
>class WeakSlot:
>def __init__(self, conn, parent, fn, obj):
>self.__conn = conn
># Avoid circular references so deleting a signal will
># allow deletion of the signal since the slot doesn't ref
># back to it but only weakefs back to it
>self.__parent = weakref.ref(parent)
>
>self.__fn = fn
>self.__obj = weakref.ref(obj, self.Cleanup)
>
>def __call__(self, accum, *args, **kwargs):
>obj = self.__obj()
>if obj is None:
>return True
>
>result = self.__fn(obj, *args, **kwargs)
>return accum(result)
>
>def Cleanup(self, ref):
>parent = self.__parent()
>if parent is not None:
>parent.Disconnect(self.__conn)
>
>class Accumulator:
>def __call__(self, *args, **kwargs):
>return True
>
>def Finalize(self):
>return None
>
>def __init__(self):
>self.__slots = [ ]
>
># This connects a signal to a slot, but stores a strong reference so
># The object will not be deleted as long as the signal is connected
>def Connect(self, fn):
>conn = self.NewConn()
>self.__slots.append([conn, Signal.Slot(fn)])
>return conn
>
># This connects a signal to a slot, but store a weak reference so
># when the object is gone the slot will not be called.  Because of
># the implemenations, it is not possible to do WeakConnect(obj.Fn),
># since obj.Fn is a new object and would go to 0 refcount soon after
># the call to WeakConnect completes.  Instead we must do a call as
># WeakConnect(ObjClass.Fn, obj)
># Only the object is weak-referenced.  The function object is still
># a normal reference, this ensures that as long as the object exists
># the function will also exist.  When the object dies, the slot will
># be removed
>def WeakConnect(self, fn, obj):
>conn = self.NewConn()
>self.__slots.append([conn, Signal.WeakSlot(conn, self, fn, obj)])
>return conn
>
># Disconnect a slot
>def Disconnect(self, conn):
>result = self.Find(conn)
>if result >= 0:
>del self.__slots[result]
>
># Disconnect all slots
>def DisconnectAll(self):
>self.__slots = [ ]
>
># Create an accumulator.  Accumulator will be called as a callable
># for each return value of the executed slots.  Execution of slots
># continues as long as the reutrn value of the accumulator call is
># True.  The 'Finalize'function will be called to get the result
># A custom accumulator can be created by deriving from Signal and
># Creating a custom 'Accumulator' class, or by deriving from Singal
># and creating CreateAccumulator
>def CreateAccumulator(self):
>return self.Accumulator()
>
># Execute the slots
>def __call__(self, *args, **kwargs):
>accum = self.CreateAccumulator()
>for conn in xrange(len(self.__slots)):
>if not self.__slots[conn][1](accum, *args, **kwargs):
>break
>return accum.Finalize()
>
># Create a connection name
>def NewConn(self):
>value = 0
>while self.Find(value) >= 0:
>value = random.randint(1, 1)
>return value
>
>def Find(self, conn):
>for i in xrange(len(self.__slots)):
>if self.__slots[i][0] == conn:
>return i
>
>return -1
>
># End Signal
>
>def fn1():
>print "Hello World"
>
>def fn2():
>print "Goodbye Space"
>
>class O:
>def __init__(self, value):
>self.value = value
>
>def Action(self):
>print "O %d" % self.value
>
>a = Signal()
>
>a.Connect(fn1)
>a.Connect(fn2)
>
>print 

Re: Photo gallery software

2008-05-01 Thread Scott SA
On 5/1/08, Jumping Arne ([EMAIL PROTECTED]) wrote:

>I've searching for some software that would allow me to present my photos on 
>the web (I'm not interested a software that generates static pages that I 
>upload) and there are quite a few, see for example 
>, but I 
>haven't managed to find one that I like - Gallery 2 is close.
>
>So I've started to see if there is one that is based python (PHP isn't really 
>"my language") but when I search on Google almost the only thing I find are 
>photo galleries of snakes (to be honest I didn't know that people were *that* 
>interested in pythons).
>
>Do any anyone know if there exists photo gallery software written in Python?
>
>I've found
>
>

I've been working with Photologue for a while with some nice results.


It is a Django project 
,

It includes support for tagging:
 

It easily allows configuration of different image sizes and integrates with 
generic templates providing gallery and detail view support. 

HTH

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