tag:blogger.com,1999:blog-322279172024-03-13T07:11:34.380-07:00Hexsprites and other thingsSoftware development with Plone, Zope, Python and other OSS tools.hexspritehttp://www.blogger.com/profile/16562427642900080293noreply@blogger.comBlogger14125tag:blogger.com,1999:blog-32227917.post-90252842880100991792009-06-05T10:24:00.000-07:002009-06-05T10:30:34.036-07:00Internationalization & Theming with Deliverance: Toronto Plone Users June 2009 Meeting<p>
This coming <a href="http://torontoplone.ca/events/2009/06/09/june-toronto-plone-users-meeting">Tuesday June 9th</a> the Toronto Plone Users will meet. We have a information packed session ahead of us.</p>
<p>Amir Toole will be presenting on creating multi-lingual plone sites using Plone's excellent Internationalization support.</p>
<p>And following up on our progress on documenting Deliverance for Plone at the Plone Symposium East 2009 Sprint, Adam Kozlowski and myself will be presenting a quick look at Deliverance and how this tool can be used to quickly and easily theme a Plone site.</p>
<p><a href="http://torontoplone.ca/">Toronto Plone Users</a> is welcome to all. Hope you can join us!</p>hexspritehttp://www.blogger.com/profile/16562427642900080293noreply@blogger.com0tag:blogger.com,1999:blog-32227917.post-49981495545649258972009-06-02T20:54:00.000-07:002009-06-03T09:09:18.017-07:00Testing ZODB changes<p>Came up with a handy decorator for asserting that a given method does not modify the ZODB.</p><p>It can be used in tests to ensure that a given test does not change the ZODB in any way (for example views).</p><p>I came up with it because a regression was discovered where a read-only view was modifying some things in ZODB causing ConflictErrors.To ensure it would not come up again I had to come up with a failing test.</p><div class="highlight"><pre><span class="k">def</span> <span class="nf">readonly</span><span class="p">(</span><span class="n">fun</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> requires that self is at least a PortalTestCase</span>
<span class="sd"> </span>
<span class="sd"> Usage hint: Use a savepoint to reset the changed object listing.</span>
<span class="sd"> """</span>
<span class="k">def</span> <span class="nf">decorated</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="c"># this resets registered objects</span>
<span class="n">transaction</span><span class="o">.</span><span class="n">savepoint</span><span class="p">()</span>
<span class="n">before</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">portal</span><span class="o">.</span><span class="n">_p_jar</span><span class="o">.</span><span class="n">_registered_objects</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">fun</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="n">after</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">portal</span><span class="o">.</span><span class="n">_p_jar</span><span class="o">.</span><span class="n">_registered_objects</span>
<span class="k">if</span> <span class="n">before</span> <span class="o">!=</span> <span class="n">after</span><span class="p">:</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">SequenceMatcher</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="n">before</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="n">after</span><span class="p">)</span>
<span class="k">for</span> <span class="n">tag</span><span class="p">,</span> <span class="n">i1</span><span class="p">,</span> <span class="n">i2</span><span class="p">,</span> <span class="n">j1</span><span class="p">,</span> <span class="n">j2</span> <span class="ow">in</span> <span class="n">s</span><span class="o">.</span><span class="n">get_opcodes</span><span class="p">():</span>
<span class="k">print</span> <span class="p">(</span><span class="s">"</span><span class="si">%7s</span><span class="s"> a[</span><span class="si">%d</span><span class="s">:</span><span class="si">%d</span><span class="s">] (</span><span class="si">%s</span><span class="s">) b[</span><span class="si">%d</span><span class="s">:</span><span class="si">%d</span><span class="s">] (</span><span class="si">%s</span><span class="s">)"</span> <span class="o">%</span> <span class="p">(</span><span class="n">tag</span><span class="p">,</span> <span class="n">i1</span><span class="p">,</span> <span class="n">i2</span><span class="p">,</span> <span class="n">before</span><span class="p">[</span><span class="n">i1</span><span class="p">:</span><span class="n">i2</span><span class="p">],</span> <span class="n">j1</span><span class="p">,</span> <span class="n">j2</span><span class="p">,</span> <span class="n">after</span><span class="p">[</span><span class="n">j1</span><span class="p">:</span><span class="n">j2</span><span class="p">]))</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">"ZODB was changed"</span><span class="p">)</span>
<span class="k">return</span> <span class="n">result</span>
<span class="k">return</span> <span class="n">decorated</span>
</pre></div><p>An example of usage:</p><div class="highlight"><pre><span class="k">class</span> <span class="nc">ReadonlyTests</span><span class="p">(</span><span class="n">YourTestCase</span><span class="p">):</span>
<span class="nd">@readonly</span>
<span class="c"># This one will fail</span>
<span class="k">def</span> <span class="nf">test_isnt_readonly</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">portal</span><span class="o">.</span><span class="n">invokeFactory</span><span class="p">(</span><span class="s">'Document'</span><span class="p">,</span> <span class="s">'test'</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">portal</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">setTitle</span><span class="p">(</span><span class="s">'foo'</span><span class="p">)</span>
<span class="nd">@readonly</span>
<span class="k">def</span> <span class="nf">test_is_readonly</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">pass</span>
</pre></div>hexspritehttp://www.blogger.com/profile/16562427642900080293noreply@blogger.com0tag:blogger.com,1999:blog-32227917.post-12323078940059530162008-11-11T03:27:00.000-08:002008-11-11T03:45:12.552-08:00World Plone Day Toronto 2008 Reflections<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_gcl8dl_Ut7Y/SRlvey2ShpI/AAAAAAAAAMs/kGYqjbTqZbY/s1600-h/3012371863_75a9a25bc0.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px; height: 175px;" src="http://1.bp.blogspot.com/_gcl8dl_Ut7Y/SRlvey2ShpI/AAAAAAAAAMs/kGYqjbTqZbY/s320/3012371863_75a9a25bc0.jpg" alt="" id="BLOGGER_PHOTO_ID_5267363814022743698" border="0" /></a>On Friday November 7th, the <a href="http://torontoplone.ca/">Toronto Plone Users</a> put on a World Plone Day event at the <a href="http://www.socialinnovation.ca/">Center for Social Innovation</a> in Toronto, Canada.
<p>Over 40 people showed up to listen to 5 talks that ranged from an introduction to Plone, several case studies and a technical talk covering rapid application development with Plone. We raffled away two books that were generously donated by O'Reilly.
<p>We streamed live via ustream.tv and the recordings and slides from the presenters are now <a href="http://torontoplone.ca/events/2008/11/07/support-materials">available</a>.
<p>Based on our pre-event survey we had a wide range of attendees: new to Plone, developers, managers and end-users from corporate, non-profit and government sectors. We consider the event to be a huge success!
<p>The event was sponsored by my company <a href="http://scryent.com/">Scryent</a>, and co-sponsors <a href="http://dotrust.org/">Digital Opportunity Trust</a> (DOT) and <a href="http://softwerke.ca/">Softwerke</a>.
<p>Hugh Ranalli of DOT also <a href="http://www.dotrust.org/our-people/hranalli/weblog/archive/2008/11/10/world-plone-day-toronto-2008">blogged</a> about the event.
<p>The November Toronto Plone Users is meeting today, Tuesday November 11.hexspritehttp://www.blogger.com/profile/16562427642900080293noreply@blogger.com0tag:blogger.com,1999:blog-32227917.post-25770909706668105042008-11-02T13:22:00.000-08:002008-11-02T13:51:38.241-08:00World Plone Day Toronto<p>
Only 5 days before <a href="http://plone.org/wpd">World Plone Day</a> on November 7!
<p>
In Toronto we're organizing a half-day of talks and case studies on Plone at the
Center for Social Innovation (near Queen & Spadina).
<p>
I'll be giving two talks at the event: one mainly geared to decision makers who want to know why Plone is a competitive CMS solution and what it can do for them. The second talk is "Intranet in 25 minutes" where I'll show building an intranet in real time that truly showcases the power of Plone out of the box and also showcase a couple key add-ons.
<p>
Along with myself will be 3 other speakers covering case studies of Plone in government and non-profit organizations, along with using ArchGenXML to generate Plone applications from UML diagrams.
<p>
There's more info available at the <a href="http://torontoplone.ca/">Toronto Plone Users website</a>.
<p>
There's a free registration and those who do register will get a chance to win one of two Python books donated by O'Reilly!
<p>
Space in our room is limited so register now!hexspritehttp://www.blogger.com/profile/16562427642900080293noreply@blogger.com0tag:blogger.com,1999:blog-32227917.post-32439628432255514652008-07-17T15:18:00.000-07:002008-07-17T17:11:31.105-07:00Zope Crashing, MaximumRecursion & OSX Thread Stack Size<p>Just making a note here about a problem I had earlier today with Zope crashing
under OSX and how I fixed it. This is apparently a well-known issue with Zope
on some platforms including OSX and FreeBSD.</p>
<p>I had just made a small change to an Archetypes schema in my content class and
reloaded the relevant code. When I refreshed the page Zope chugged away for a
bit and then Zope just exited silently.
</p>
<p>Using gdb I tried the request again and found that it was dying from a memory
access violation.
</p>
<p>When I exercised the same code under the testrunner I found that due to a
small omission on my part I had triggered a <em>MaximumRecursion</em> exception.
</p>
<p>So as it turns out there are different stack sizes for child threads. And
under OSX this size is smaller than Zope requires.
</p>
<p>Now Python 2.5 has a runtime option in the <a href="http://docs.python.org/lib/module-thread.html">thread module</a> to set the stack
size, but Python 2.4, required for Zope 2.X, does not.
</p>
<p>The solution I found for Python 2.4 was build Python myself, adding
<code>-DTHREAD_STACK_SIZE=0x100000</code> to CFLAGS in the Python Makefile. This sets to
the child stack size to 1 meg which seems to be sufficient.
</p>
<p>Now when I run the offending code in the Zope server it no longer crashes and`
correctly displays the <em>MaximumRecursion</em> exception.</p>hexspritehttp://www.blogger.com/profile/16562427642900080293noreply@blogger.com0tag:blogger.com,1999:blog-32227917.post-48839087526176573692008-05-30T10:04:00.000-07:002008-05-30T07:22:18.505-07:00Testing OSX applications with Python<p>Recently I started a new wxPython based project that would be primarily be running on OSX.
</p>I figured it would be rather useful and neat to have some tests managed by Python that would exercise the whole system so I took a stab at setting some up using some of my standard toolkit.
You don't have to test exclusively Python-based application. You can use Python to write the test scripts for the application under test which could be written in any language that OSX supports.
<h2> How
</h2>I found out that Apple has already added all the hooks for scripting the UI via an AppleScript service called <a href="http://www.apple.com/applescript/uiscripting/" title="GUI Scripting">GUI Scripting</a> or System Events.
You can script it easily via AppleScript. Or you can access it all from Python using the <a href="http://appscript.sourceforge.net/">appscript</a> module.
<h2> It's Easy
</h2>Here's some code to get you started testing with GUI Scripting.
<div class="highlight"><pre><span class="k">from</span> <span class="nn">appscript</span> <span class="k">import</span> <span class="o">*</span>
<span class="k">import</span> <span class="nn">time</span>
<span class="c"># some boilerplate setup</span>
<span class="n">sysevents</span> <span class="o">=</span> <span class="n">app</span><span class="p">(</span><span class="s">'System Events'</span><span class="p">)</span>
<span class="n">app</span><span class="p">(</span><span class="s">'Finder'</span><span class="p">)</span><span class="o">.</span><span class="n">activate</span><span class="p">()</span>
<span class="n">sysevents</span><span class="o">.</span><span class="n">processes</span><span class="p">[</span><span class="s">'Finder'</span><span class="p">]</span><span class="o">.</span><span class="n">menu_bars</span><span class="p">[</span><span class="mf">1</span><span class="p">]</span><span class="o">.</span><span class="n">menus</span><span class="p">[</span><span class="s">u'Apple'</span><span class="p">]</span><span class="o">.</span><span class="n">menu_items</span><span class="p">[</span><span class="s">u'About This Mac'</span><span class="p">]</span><span class="o">.</span><span class="n">click</span><span class="p">()</span>
<span class="c"># some operations may need a pause</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">1</span><span class="p">)</span>
<span class="n">loginwindow</span> <span class="o">=</span> <span class="n">sysevents</span><span class="o">.</span><span class="n">processes</span><span class="p">[</span><span class="s">'loginwindow'</span><span class="p">]</span>
<span class="c"># Check that an About this Mac window exists</span>
<span class="k">assert</span> <span class="p">[</span> <span class="n">win</span> <span class="k">for</span> <span class="n">win</span> <span class="ow">in</span> <span class="n">loginwindow</span><span class="o">.</span><span class="n">windows</span><span class="p">()</span> <span class="k">if</span> <span class="n">win</span><span class="o">.</span><span class="n">title</span><span class="p">()</span> <span class="o">==</span> <span class="s">'About This Mac'</span><span class="p">]</span>
<span class="c"># Check that there is an All Rights Reserved present.</span>
<span class="k">assert</span> <span class="n">loginwindow</span><span class="o">.</span><span class="n">windows</span><span class="p">[</span><span class="s">'About This Mac'</span><span class="p">]</span><span class="o">.</span><span class="n">static_texts</span><span class="p">[</span><span class="s">'All Rights Reserved.'</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">()</span>
</pre>
The example is a little convoluted because Finder owns the "About This Mac" menu entry, but loginwindow owns the window that pops up.
</div>
The hardest part was figuring out the API to work with Apple's UI scripting support. Especially since all of Apple's examples were in AppleScript.
Thankfully theres some tools that come with appscript that help. One called ASDictionary that autogenerates documentation for the various AppleScript plugins on your system. Also ASTranslate helps with the job of translating AppleScript code into equivalent appscript usage under Python.
<h2> Is that all?
</h2>There don't seem to be many Open Source GUI Functional Testing tools for OSX. Anyone know any ? Lots for Web functional testing but not for UI.
<p> There is <a href="http://pywinauto.openqa.org/">pywinauto</a> for Windows.
</p>Might be nice if OSX had a similar test layer.
pymacauto anyone?hexspritehttp://www.blogger.com/profile/16562427642900080293noreply@blogger.com0tag:blogger.com,1999:blog-32227917.post-58504891221143667752008-05-22T08:37:00.001-07:002008-05-22T08:46:05.281-07:00quick way to debug testbrowser in doctestsWriting doctests I am sometimes wondering what is going on under the hood. Keeping this function around in my test environment makes it a bit easier to find out.
After rendering the output to the browser it will pause waiting for a keypress to continue the test. Note, this code works only on OSX though it should be trivial to modify for any OS.
<pre>>>> def render_browser(browser):
... open('/tmp/browser.html', 'w').write(browser.contents)
... import os
... os.system("open /tmp/browser.html")
... _ = raw_input()
</pre>hexspritehttp://www.blogger.com/profile/16562427642900080293noreply@blogger.com1tag:blogger.com,1999:blog-32227917.post-23990659777650941562007-10-15T08:15:00.001-07:002007-10-15T08:32:51.932-07:00buildout recipe for installing Selenium RCThis weekend at the Plone Naples Sprint one of the things I worked on was a buildout to download and install Selenium RC. It is now available from PYPI under the name <span style="font-style: italic;">collective.recipe.seleniumrc</span>
For some reason the Selenium RC distribution zip file contains version numbers on each subdirectory so this meant I couldn't just use one of the existing download scripts.
But I didn't want to re-invent the download recipe wheel, so I decided to base this recipe on a well-written existing download recipe, <span style="font-style: italic;">hexagonit.recipe.download</span>.
I asked on IRC if the author was present at the sprint and ironically enough he was sitting in the same room as me only two rows away ;)
With some simple changes to his recipe I was able to derive collective.recipe.seleniumrc from it and gain features like download caching and md5 file hash verification.
Along the way I learned that if you want your buildout recipe to be derived by others you should make it a new-style Python class so that super() works. Also that it helps to factor your install() method into submethods for overriding.
The changes I made to hexagonit.recipe.download were cleaned up and integrated into a 1.1.0 release that we made yesterday, along with the 0.1 release of collective.recipe.seleniumrc
If you want to try out the Selenium RC recipe just create a simple buildout.cfg:
<pre>[buildout]
parts=seleniumrc
[seleniumrc]
recipe=collective.recipe.seleniumrc
</pre>After you are finished running this buildout you will get a nice wrapper script in your <span style="font-style: italic;">bin</span> folder named by the part, in this case <span style="font-style: italic;">seleniumrc</span>.
Happy testing!hexspritehttp://www.blogger.com/profile/16562427642900080293noreply@blogger.com4tag:blogger.com,1999:blog-32227917.post-18144289527400859972007-08-15T09:33:00.000-07:002007-08-21T07:12:26.462-07:00WebDAV, cadaver and metadataRecently I wanted to automate some document management processes against a Plone site and was trying to figure out how to do set the Title property on the newly created objects via WebDAV, using the cadaver command line client.
This led me to look a little more closely at how WebDAV does properties. In fact it is not like a simple Python dictionary, rather there is a nested structure like a dictionary of dictionaries. Each application can have its own namespace.
By default cadaver will set properties in its own custom namespace. So you need to use the <span style="font-style: italic;">set namespace</span> command to use the Zope namespace identified by its namespace: http://www.zope.org/propsets/default<code>
</code>
The following example uses cadaver and creates a collection (folder) and sets the title property:
<code></code><pre>
mkcol just_a_folder
set namespace http://www.zope.org/propsets/default
propset just_a_folder title “A long title”
</pre>hexspritehttp://www.blogger.com/profile/16562427642900080293noreply@blogger.com2tag:blogger.com,1999:blog-32227917.post-14096618457629426032007-04-19T20:20:00.000-07:002007-04-19T21:28:48.676-07:00Zope 3 Book Arrived!The book <span style="font-style: italic;">Web Component Development with Zope 3, 2nd Ed.</span> by <span style="font-style: italic;">Philipp von Weitershausen</span> has been on my wishlist for a while now and I finally got around to ordering it.
I only got it last night and already I've made it half way through, though certainly I will re-read it all several times.
The book offers very excellent descriptions of the component architecture and its applications throughout the rest of the Zope 3 framework.
The progression of chapters in the book shows the reuse of the basic building blocks of interfaces, adapters & utilities.
And one of the things I also liked was the "Rocky says" section where the relevant technologies of J2EE were constrasted with those of Zope.
The explanation of ZCML in the book finally made it clear to me. ZCML is on purpose ;)
It forces a separation of roles and make sure that things that would be considered 'configuration' are easily accessible to a non-programmer like a system administrator or integrator.
My impression so far the from the book is one that really showcases Zope 3 as a enterprise-grade framework that is solidly Pythonic.
For more info you can check' the website for <a href="http://worldcookery.com/">Web Component Development with Zope 3, 2nd Ed.</a>hexspritehttp://www.blogger.com/profile/16562427642900080293noreply@blogger.com0tag:blogger.com,1999:blog-32227917.post-89395487395834080562007-04-16T17:09:00.001-07:002007-04-16T17:44:17.948-07:00BuildoutsHow annoying is it to deploy an application? How prone to errors due to the sheer repetitiveness of the common deployment? Buildouts to the rescue!
What is a buildout? It's a automated set of steps for creating a deployment environment. This could mean one little application, or it could be several and they would setup to talk to each other.
<a href="http://cheeseshop.python.org/pypi/zc.buildout">zc.buildout</a> came out sometime last year and I've had my eye on it since then. I'd wanted to do Jim Fulton's tutorial on it at Pycon this year but wasn't able to schedule it in!
I've had the opportunity in the last couple weeks to start using a bit more and I really appreciate the conceptual basis for this framework.
The idea that a deployment consists of parts is something you can explain to anyone, for example.
A web app needs a webserver, some kind of storage backend, the application code and some preexisting data:
<span style="font-family:courier new;"> parts=apache mysql application-data application</span>
or full Zope-based solution:
<span style="font-family:courier new;"> parts=apache zope zeo plone mywebsite mywebsite-data</span>
What I've noticed so far is that for a particular application even though someone might have already wrote a recipe for it actually getting it configured the way you want usually requires extending that recipe slightly.
If the recipe was written with this in mind its easy enough to extend. I did have a bit of problems extending some of the plone.recipe.* recipes because they were old style classes and so I couldn't use super() to extend the default behaviour. Easy to fix though!
<h2>ZOPE / ZEO buildout recipe with multiple database support</h2>
I created a branch that adds the ability to configure multiple databases in your configuration files which I needed for a project, so this should be a fairly decent example for anyone else needed to something similar.
See the <a href="http://dev.plone.org/collective/browser/buildout/plone.recipe.zope2zeoserver/branches/jbb666-storage-config">jbb666-multiple-dbs branch for zeo instance</a> and the corresponding branch for the zope recipe.
For a lot of the Zope recipes the config knobs that need to be exposed will be determined and you won't need to touch the underlying recipe except in well exceptional circumstances.hexspritehttp://www.blogger.com/profile/16562427642900080293noreply@blogger.com0tag:blogger.com,1999:blog-32227917.post-47282720793358708942007-04-12T13:25:00.000-07:002007-04-16T17:55:49.560-07:00copying a plone siteCopying sites has recently gotten a lot better since 2.5.2 fixed some bugs with modification times getting reset but still you generally can't use copy & paste to copy sites as I have found it doesn't retain the review state of your documents (and this is by design actually I think).
Another approach is to import/export. This actually works great so I put together a script that will automate this process.
You need to call this from either an External Method or from zopectl debug (or ipython). That's an exercise up to the reader...
# moveSites.py
<pre># Move a Plone site without losing the modification times and workflow status
# we rely on export/import to do this
# You need to provide a valid REQUEST so that the import doesn't fail
# if running from zopectl debug you can use makerequest to wrap your app object
# with a fake request
# Author: Jordan Baker (jbbNOASPM@scryent.com)
import tempfile
import os
def moveSite(portal, new_location):
# export the site to a tempfile
f = tempfile.NamedTemporaryFile()
portal._p_jar.exportFile(portal._p_oid, f)
# re-import in the correct location
f.seek(0)
new_location._importObjectFromFile(f, verify=False, set_owner=False)
# delete the old site
oid = portal.id
portal.aq_parent.manage_delObjects(ids=[oid])
# update the catalog in the new site
new_location[oid].portal_catalog.refreshCatalog(clear=True)
# NamedTemporaryFile should delete the underlying temporary file
# when its object is garbage collected
</pre>hexspritehttp://www.blogger.com/profile/16562427642900080293noreply@blogger.com0tag:blogger.com,1999:blog-32227917.post-40858004047919249142007-03-22T15:19:00.000-07:002008-12-10T02:58:10.247-08:00I've Joined the Toastmasters!<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_gcl8dl_Ut7Y/RgMGRWkL5EI/AAAAAAAAAFE/mwC2w66x1_k/s1600-h/Induction.jpg"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 178px; height: 186px;" src="http://2.bp.blogspot.com/_gcl8dl_Ut7Y/RgMGRWkL5EI/AAAAAAAAAFE/mwC2w66x1_k/s200/Induction.jpg" alt="" id="BLOGGER_PHOTO_ID_5044882902769984578" border="0" /></a>I've recently joined the <a href="http://www.libertyvillagetoastmasters.com/">Liberty Village Toastmasters</a>. The name perhaps evokes the spirit of another time but Toastmasters is a very relevant organization for today.
The picture from my induction ceremony: me on the right, and Ian Garmaise, the club President on the left.
Ian had introduced me to the club. We have a neat connection because we are also both fans of the Python programming language. We'd first met at <a href="http://web.engcorp.com/pygta">PyGTA</a>, the Toronto Python Users Group.
<a href="http://en.wikipedia.org/wiki/Toastmasters_International">Toastmasters</a> is a bit like a DIY communications class.
At the weekly meetings we are working on our communication and presentation skills among many other things.
Learning to refine and hone the delivery of ideas for impact all the while feeling natural in front of the audience you are addressing.
<span style="font-style: italic;">
</span><span>But the best part is probably all the smart, interesting and generous people I've met at this group.</span><span style="font-style: italic;"><span style="font-style: italic;"><span style="font-style: italic;"><span style="font-style: italic;"><span style="font-style: italic;">
</span></span></span></span></span>My first speech, known as an <span style="font-style: italic;">Ice Breaker</span>, is only two weeks away. I'm getting nervous just thinking about it.
<hr />
At last week's meeting on March 14th, <span style="font-style: italic;">Ted Blanchard</span> gave a great educational talk with some tips. I noted down only a scant few of them that I've tried to summarize here:
<span style="font-style: italic;"><span style="font-weight: bold;">Set Goals</span></span> - there are a series of 10 speeches in the first stage of the Toastmasters. Put yourself on a regular schedule, like a speech every 4 weeks.
<span style="font-weight: bold;">Topic Generation</span> <span style="font-weight: bold;">Exercise</span>. Make a Speech Topic List in 15 minutes by getting a pen and a piece of paper and writing down:
<ul><li>5 current events</li><li>5 things you enjoy doing</li><li>5 things that bug you</li><li>5-20 action words</li></ul><span style="font-weight: bold;">Learn to do an outline</span>. An outline is not finished thinking, just the waypoints your speeches' route. It gets you out of the editing chaos of continual revision.hexspritehttp://www.blogger.com/profile/16562427642900080293noreply@blogger.com0tag:blogger.com,1999:blog-32227917.post-8578168215102438542007-02-23T06:47:00.001-08:002008-12-10T02:58:10.379-08:00Blogging live from PyCon 2007<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_gcl8dl_Ut7Y/RiQXSBLnkfI/AAAAAAAAAFQ/4UX7wKr3qYw/s1600-h/100_1521.JPG"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://2.bp.blogspot.com/_gcl8dl_Ut7Y/RiQXSBLnkfI/AAAAAAAAAFQ/4UX7wKr3qYw/s200/100_1521.JPG" alt="" id="BLOGGER_PHOTO_ID_5054190280138789362" border="0" /></a>
I finally made it! Got switched to another hotel but I will be in the right place for tonight.
Immediately I ran into a couple familiar faces from last October's Plone Conference, Chris Calloway and Josten Ma.
Now I'm sitting in the main room waiting for the morning's keynote to start.
More to come...
<span style="font-weight: bold;">Update</span>
<img src="file:///Users/jordan/Pictures/iPhoto%20Library/Originals/2006/Roll%2036/100_1521.JPG" alt="" />
Well I didn't end up blogging much at Pycon this year. But I have some pretty wonderful excuses. ;)hexspritehttp://www.blogger.com/profile/16562427642900080293noreply@blogger.com0