[Zope] Returning a list of dictionaries from an external method yields "Loop over non-sequence" when tested

Thomas Weholt t-weh@online.no
Tue, 9 Jul 2002 01:03:36 +0200


This is a multi-part message in MIME format.

------=_NextPart_000_004B_01C226E4.742A3F80
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

I've got a simple external method that returns a list containing =
dictionaries. If I run it from python it works fine, imported and used =
in Zope it raises an exception "Loop over non-sequence".
The script extracts some data from a table, containing the results from =
a parsed logfile, created by the game Counter-strike ( if you're =
interested ). I'm no expert in SQL ( as the code below probably shows )
but doing it in Python is no match ( even if the code is verbose and =
perhaps a bit inefficient. Tips and clues are appreciated if you can =
make anything out of it ).=20

I import the method in Zope, calling it PlayerStats, from the module =
CSPlayerStats. The file itself is the Extensions-folder under the Zope =
main-folder. Try to test it in the ZMI and the error pops up. Thought of =
using it like so  :

<dtml-in PlayerStats>
  <dtml-let item=3Dsequence-item>
    <dtml-var "item['player']"><!-- more fields from the dictionary, =
here represented as item --><br>
  </dtml-let>
</dtml-in>

The external method :

import MySQLdb

SQL_PLAYER_INFO =3D """
select
    cs_attacker,
    cs_attacker_clantag,
    cs_weapon,
    cs_event,
    cs_health,
    cs_damage,
    cs_armor,
    cs_damage_armor,
    cs_victim,
    cs_team_attacker,
    cs_team_victim
from cs_log
order by
    cs_attacker,
    cs_event,
    cs_weapon
"""

SQL_DEATHS =3D """
select
   cs_victim,
   count(*) as deaths
from cs_log
where cs_event =3D 1
group by cs_victim
order by deaths desc
"""

SQL_KILLS =3D """
select
   cs_attacker,
   count(*) as kills
from cs_log
where cs_event =3D 1
group by cs_attacker
order by kills desc
"""

SQL_HOSTAGE_KILLS =3D """
select
   cs_attacker,
   count(*) as kills
from cs_log
where cs_event =3D 5
group by cs_attacker
order by kills desc
"""

SQL_TEAM_KILLS =3D """
select
   cs_attacker,
   count(*) as kills
from cs_log
where cs_event =3D 3
group by cs_attacker
order by kills desc
"""

SQL_RESCUED_HOSTAGE =3D """
select
   cs_attacker,
   count(*) as rescued_hostages
from cs_log
where cs_event =3D 7
group by cs_attacker
order by rescued_hostages desc
"""

SQL_MOST_TEAM_DAMAGE =3D """
select cs_attacker, sum(cs_damage) + sum(cs_damage_armor) as damage
from cs_log
where cs_event =3D 4
group by cs_attacker
order by damage desc
"""

SQL_MOST_DAMAGE =3D """
select cs_attacker, sum(cs_damage)+sum(cs_damage_armor) as damage
from cs_log
where cs_event =3D 2
group by cs_attacker
order by damage desc
"""

def PlayerStats(self):
    players =3D {}
    db =3D MySQLdb.connect(db=3D'zopetest')
    cur =3D db.cursor()

    cur.execute(SQL_KILLS)
    for player, kills in cur.fetchall():
        players[player] =3D {'kills':kills,
                           'deaths':0,
                           'team_kills':0,
                           'team_damage':0,
                           'hostage_kills':0,
                           'hostage_rescued':0}

    cur.execute(SQL_DEATHS)
    res =3D cur.fetchall()
    for player, deaths in res:
        if not players.has_key(player):
            players[player] =3D {}
        players[player]['deaths'] =3D deaths

    cur.execute(SQL_TEAM_KILLS)
    res =3D cur.fetchall()
    for player, team_kills in res:
        if not players.has_key(player):
            players[player] =3D {}
        players[player]['team_kills'] =3D team_kills

    cur.execute(SQL_RESCUED_HOSTAGE)
    res =3D cur.fetchall()
    for player, hostage_rescued in res:
        if not players.has_key(player):
            players[player] =3D {}
        players[player]['hostage_rescued'] =3D hostage_rescued

    cur.execute(SQL_MOST_TEAM_DAMAGE)
    res =3D cur.fetchall()
    for player, team_damage in res:
        if not players.has_key(player):
            players[player] =3D {}
        players[player]['team_damage'] =3D team_damage

    cur.execute(SQL_MOST_DAMAGE)
    res =3D cur.fetchall()
    for player, damage in res:
        if not players.has_key(player):
            players[player] =3D {}
        players[player]['damage'] =3D damage

    cur.execute(SQL_HOSTAGE_KILLS)
    res =3D cur.fetchall()
    for player, hostage_kills in res:
        if not players.has_key(player):
            players[player] =3D {}
        players[player]['hostage_kills'] =3D hostage_kills

    result =3D []
    for player in players:
        kill_death_ratio =3D float(players[player]['kills']) / =
float(players[player]['deaths'])
        damage_team_damage_ratio =3D float(players[player]['damage']) / =
float(players[player]['team_damage'])
        score =3D kill_death_ratio * damage_team_damage_ratio
       =20
        result.append((score, player, players[player]['kills'], =
players[player]['deaths'], players[player]['damage'], =
players[player]['team_damage'], kill_death_ratio, =
damage_team_damage_ratio))

    result.sort()
    result.reverse()
    stats =3D []
    for piece in result:
        score, player, kills, deaths, damage, team_damage, kd_ratio, =
dt_ratio =3D piece
        stats.append({'player':player, 'score':score, 'kills': kills, =
'deaths': deaths, 'damage': damage, 'team_damage': team_damage, =
'kd_ratio':kd_ratio, 'dt_ratio':dt_ratio})

    return stats

Doing something simple like this :

def AList(self):
    return [{'fname':'Thomas'}, {'fname':'Roger'}]

in a module and importing it works just fine. Testing is ok and the same =
DTML-piece fitted to the simple method works like a charm.

What am I doing wrong???

Appreciate any help you can provide.

Best regards,
Thomas Weholt, not yet Zope-meister but want to be ;-)

------=_NextPart_000_004B_01C226E4.742A3F80
Content-Type: text/html;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2716.2200" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>I've got a simple external method that =
returns a=20
list containing dictionaries. If I run it from python it works fine, =
imported=20
and used in Zope it raises an&nbsp;exception "Loop over=20
non-sequence".</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>The script extracts some data from a =
table,=20
containing the results from a parsed logfile, created by the game =
Counter-strike=20
( if you're interested ). I'm no expert in SQL ( as the code below =
probably=20
shows )</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>but doing it in Python is no match ( =
even if the=20
code is verbose and perhaps a bit inefficient. Tips and clues are =
appreciated if=20
you can make anything out of it ). </FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>I import the method in Zope, calling it =

PlayerStats, from the module CSPlayerStats. The file itself is the=20
Extensions-folder under the Zope main-folder. Try to test it in the ZMI =
and the=20
error pops up. Thought of using it like so&nbsp; :</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>&lt;dtml-in PlayerStats&gt;<BR>&nbsp; =
&lt;dtml-let=20
item=3Dsequence-item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;dtml-var=20
"item['player']"&gt;&lt;!-- more fields from the dictionary, here =
represented as=20
item&nbsp;--&gt;&lt;br&gt;<BR>&nbsp;=20
&lt;/dtml-let&gt;<BR>&lt;/dtml-in&gt;<BR></FONT></DIV>
<DIV><FONT face=3DArial size=3D2>The external method :</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>import MySQLdb</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>SQL_PLAYER_INFO =3D=20
"""<BR>select<BR>&nbsp;&nbsp;&nbsp; cs_attacker,<BR>&nbsp;&nbsp;&nbsp;=20
cs_attacker_clantag,<BR>&nbsp;&nbsp;&nbsp; =
cs_weapon,<BR>&nbsp;&nbsp;&nbsp;=20
cs_event,<BR>&nbsp;&nbsp;&nbsp; cs_health,<BR>&nbsp;&nbsp;&nbsp;=20
cs_damage,<BR>&nbsp;&nbsp;&nbsp; cs_armor,<BR>&nbsp;&nbsp;&nbsp;=20
cs_damage_armor,<BR>&nbsp;&nbsp;&nbsp; cs_victim,<BR>&nbsp;&nbsp;&nbsp;=20
cs_team_attacker,<BR>&nbsp;&nbsp;&nbsp; cs_team_victim<BR>from =
cs_log<BR>order=20
by<BR>&nbsp;&nbsp;&nbsp; cs_attacker,<BR>&nbsp;&nbsp;&nbsp;=20
cs_event,<BR>&nbsp;&nbsp;&nbsp; cs_weapon<BR>"""</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>SQL_DEATHS =3D =
"""<BR>select<BR>&nbsp;&nbsp;=20
cs_victim,<BR>&nbsp;&nbsp; count(*) as deaths<BR>from cs_log<BR>where =
cs_event =3D=20
1<BR>group by cs_victim<BR>order by deaths desc<BR>"""</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>SQL_KILLS =3D =
"""<BR>select<BR>&nbsp;&nbsp;=20
cs_attacker,<BR>&nbsp;&nbsp; count(*) as kills<BR>from cs_log<BR>where =
cs_event=20
=3D 1<BR>group by cs_attacker<BR>order by kills desc<BR>"""</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>SQL_HOSTAGE_KILLS =3D =
"""<BR>select<BR>&nbsp;&nbsp;=20
cs_attacker,<BR>&nbsp;&nbsp; count(*) as kills<BR>from cs_log<BR>where =
cs_event=20
=3D 5<BR>group by cs_attacker<BR>order by kills desc<BR>"""</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>SQL_TEAM_KILLS =3D =
"""<BR>select<BR>&nbsp;&nbsp;=20
cs_attacker,<BR>&nbsp;&nbsp; count(*) as kills<BR>from cs_log<BR>where =
cs_event=20
=3D 3<BR>group by cs_attacker<BR>order by kills desc<BR>"""</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>SQL_RESCUED_HOSTAGE =3D =
"""<BR>select<BR>&nbsp;&nbsp;=20
cs_attacker,<BR>&nbsp;&nbsp; count(*) as rescued_hostages<BR>from=20
cs_log<BR>where cs_event =3D 7<BR>group by cs_attacker<BR>order by=20
rescued_hostages desc<BR>"""</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>SQL_MOST_TEAM_DAMAGE =3D """<BR>select =
cs_attacker,=20
sum(cs_damage) + sum(cs_damage_armor) as damage<BR>from cs_log<BR>where =
cs_event=20
=3D 4<BR>group by cs_attacker<BR>order by damage =
desc<BR>"""</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>SQL_MOST_DAMAGE =3D """<BR>select =
cs_attacker,=20
sum(cs_damage)+sum(cs_damage_armor) as damage<BR>from cs_log<BR>where =
cs_event =3D=20
2<BR>group by cs_attacker<BR>order by damage desc<BR>"""</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>def =
PlayerStats(self):<BR>&nbsp;&nbsp;&nbsp;=20
players =3D {}<BR>&nbsp;&nbsp;&nbsp; db =3D=20
MySQLdb.connect(db=3D'zopetest')<BR>&nbsp;&nbsp;&nbsp; cur =3D=20
db.cursor()</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>&nbsp;&nbsp;&nbsp;=20
cur.execute(SQL_KILLS)<BR>&nbsp;&nbsp;&nbsp; for player, kills in=20
cur.fetchall():<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
players[player] =3D=20
{'kills':kills,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
'deaths':0,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;=20
'team_kills':0,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
'team_damage':0,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
'hostage_kills':0,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
'hostage_rescued':0}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>&nbsp;&nbsp;&nbsp;=20
cur.execute(SQL_DEATHS)<BR>&nbsp;&nbsp;&nbsp; res =3D=20
cur.fetchall()<BR>&nbsp;&nbsp;&nbsp; for player, deaths in=20
res:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not=20
players.has_key(player):<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;=20
players[player] =3D {}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
players[player]['deaths'] =3D deaths</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>&nbsp;&nbsp;&nbsp;=20
cur.execute(SQL_TEAM_KILLS)<BR>&nbsp;&nbsp;&nbsp; res =3D=20
cur.fetchall()<BR>&nbsp;&nbsp;&nbsp; for player, team_kills in=20
res:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not=20
players.has_key(player):<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;=20
players[player] =3D {}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
players[player]['team_kills'] =3D team_kills</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>&nbsp;&nbsp;&nbsp;=20
cur.execute(SQL_RESCUED_HOSTAGE)<BR>&nbsp;&nbsp;&nbsp; res =3D=20
cur.fetchall()<BR>&nbsp;&nbsp;&nbsp; for player, hostage_rescued in=20
res:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not=20
players.has_key(player):<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;=20
players[player] =3D {}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
players[player]['hostage_rescued'] =3D hostage_rescued</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>&nbsp;&nbsp;&nbsp;=20
cur.execute(SQL_MOST_TEAM_DAMAGE)<BR>&nbsp;&nbsp;&nbsp; res =3D=20
cur.fetchall()<BR>&nbsp;&nbsp;&nbsp; for player, team_damage in=20
res:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not=20
players.has_key(player):<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;=20
players[player] =3D {}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
players[player]['team_damage'] =3D team_damage</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>&nbsp;&nbsp;&nbsp;=20
cur.execute(SQL_MOST_DAMAGE)<BR>&nbsp;&nbsp;&nbsp; res =3D=20
cur.fetchall()<BR>&nbsp;&nbsp;&nbsp; for player, damage in=20
res:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not=20
players.has_key(player):<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;=20
players[player] =3D {}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
players[player]['damage'] =3D damage</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>&nbsp;&nbsp;&nbsp;=20
cur.execute(SQL_HOSTAGE_KILLS)<BR>&nbsp;&nbsp;&nbsp; res =3D=20
cur.fetchall()<BR>&nbsp;&nbsp;&nbsp; for player, hostage_kills in=20
res:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not=20
players.has_key(player):<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;=20
players[player] =3D {}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
players[player]['hostage_kills'] =3D hostage_kills</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>&nbsp;&nbsp;&nbsp; result =3D=20
[]<BR>&nbsp;&nbsp;&nbsp; for player in=20
players:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kill_death_ratio =
=3D=20
float(players[player]['kills']) /=20
float(players[player]['deaths'])<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;=20
damage_team_damage_ratio =3D float(players[player]['damage']) /=20
float(players[player]['team_damage'])<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;=20
score =3D kill_death_ratio *=20
damage_team_damage_ratio<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result.append((score, =
player,=20
players[player]['kills'], players[player]['deaths'], =
players[player]['damage'],=20
players[player]['team_damage'], kill_death_ratio,=20
damage_team_damage_ratio))</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>&nbsp;&nbsp;&nbsp;=20
result.sort()<BR>&nbsp;&nbsp;&nbsp; =
result.reverse()<BR>&nbsp;&nbsp;&nbsp; stats=20
=3D []<BR>&nbsp;&nbsp;&nbsp; for piece in=20
result:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; score, player, =
kills,=20
deaths, damage, team_damage, kd_ratio, dt_ratio =3D=20
piece<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
stats.append({'player':player, 'score':score, 'kills': kills, 'deaths': =
deaths,=20
'damage': damage, 'team_damage': team_damage, 'kd_ratio':kd_ratio,=20
'dt_ratio':dt_ratio})</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>&nbsp;&nbsp;&nbsp; return =
stats</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>Doing something simple like this =
:</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>def AList(self):<BR>&nbsp;&nbsp;&nbsp; =
return=20
[{'fname':'Thomas'}, {'fname':'Roger'}]</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>in a module and importing it works just =
fine.=20
Testing is ok and the same DTML-piece fitted to the simple method works =
like a=20
charm.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>What am I doing wrong???</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>Appreciate any help you can =
provide.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>Best regards,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>Thomas Weholt, not yet Zope-meister but =
want to be=20
;-)</FONT></DIV></BODY></HTML>

------=_NextPart_000_004B_01C226E4.742A3F80--