Home

Powered by Django

Young Coders at PyCon 2015

Date: May 01, 2015

2015 was my third year teaching this class at PyCon, alongside Katie Cunningham. It feels like we've been doing it so much longer, doesn't it?

This year, as last, Young Coders ran for two days - on the Saturday of the conference, we offered the class in French (thanks to two talented Montreal Pythonistas, Davin Baragiotta and David Cormier). And on Sunday, we presented the class in English, with some teaching help from Naomi Ceder and Richard Jones.

Thanks so much to Mathieu Leduc-Hamel and the rest of the Montreal staff and organizers, without whom our last two years in Montreal would not have run so smoothly!

To recap, the classroom workstations consist of Raspberry Pis and the usual peripherals (keyboard, mouse, monitor). We don't use the ethernet connection - none of our beginner material requires internet connectivity, and we'd risk losing the students to Facebook and email anyway. The image we use includes Python 2/3 and comes with Idle installed - that's really all we need, since just about everything we cover is at the interpreter level.

For this year's workstations, we used the Raspberry Pi Basic Starter Kit from ABRA Electronics in Montreal. Each kits contains all you need to get started, minus the peripherals, so all of this year's students got to take home a Raspberry Pi with a sturdy case, an 8Gb SD Card with the image pre-loaded, a power supply, and some documentation.

The curriculum hasn't changed much over the years. We start with a quick chat about what computers do and what programming means, then spend the morning covering the most basic of Python basics: strings, math, Booleans, variables, lists, some functions and logic, even a discussion of basic error interpretation.

The curriculum is on GitHub: https://github.com/mechanicalgirl/young-coders-tutorial

After a lunch break, the rest of the class time is devoted to editing and playing games (using Al Sweigart's pygame library, which also comes installed on the Raspian/NOOB image).

This year we had a great last-minute addition to the program. On Friday morning, I saw Kurt Grandis' terrific talk - Exploring Minecraft and Python: Learning to Code Through Play. I was sitting with Richard Jones, musing about how cool it would be to integrate Minecraft into the Young Coders curriculum for 2016. I hadn't given it much thought before, so I didn't realize how close we were. And then Kurt started talking about this mcpi library that already exists for interacting with Minecraft on the Raspberry Pi.

That afternoon we went to the classroom to start working on the RPi setup for the Saturday class and discovered that we were working with a more recent version of the Raspian image. As of September 2014, Raspian has the mcpi library installed. We spent a good few hours that evening playing around with Minecraft on the Rpis, then were able to make it a part of both classes that weekend. Needless to say, it was a big hit.

We got most of our ideas from Minecraft: Pi Edition - API Tutorial and Getting Started with Minecraft Pi.

But for all the fun we created in the classroom that weekend (it's so great seeing kids excited about learning!), I was reminded of limitations. This year, we capped enrollment at 40 per class, and 40 was just too many. With that many students, it becomes hard to keep everyone moving at the same pace. Adding more TAs or teachers to the mix doesn't really help, it just causes the levels of noise and chaos in the room to go up and makes it very hard to focus on the material.

This year, we also had a fair number of students who were too experienced for the beginner material. I always hate seeing that - I know those kids are going to be bored through about 80% of what we talk about. Unfortunately, up to now a beginner class is all we've been offering. I should have singled those kids out early on and asked them to transition to being TAs for the duration, helping their fellow students, but there was just too much going on with the class that large. Remember this when you plan your own Young Coders event. (You are planning one, right?)

So with all that in mind, I'm working on developing an intermediate curriculum for PyCon 2016.

Aside from writing the curriculum itself, there are going to be some challenges involved. I would like to continue to use the Rapberry Pis, so that setup is familiar and our budget doesn't change, and so that students are working on a common operating system and can take their workstations with them at the end of the day.

So far I've got the frameworks laid out for a couple of game and web projects. I'm currently reviewing learning tools that will make it easy to build these projects in a classroom setting, while still giving students a taste of what it's like to write and publish your own Python code in a real production environment.

PyCon 2016 is still over a year away, so there's a good chance the time will get away from me and I'll finish up the intermediate program a few weeks before heading to Portland. (I finished up materials for the first Young Coders class the week before, and reviewed it with Katie over dinner the night before we went into the classroom for the first time.)

But I'll do my best to get ahead of the planning and share what I'm working on over the next few months.

See you in Portland in 2016!

Powered by Django

Customizing a Django RSS Feed

Date: Mar 09, 2015

The Framework: Django 1.3 (not my choice!)

The Mission: Create an RSS feed that includes an extra field for full story content, plus a few additional fields for images

I know. It's 2015 and we're still on 1.3. But the changes to Django syndication since 1.3 haven't been that dramatic, so you might find this useful if you're in the same boat.

ADDING CUSTOM FIELDS

Let's start with the methods needed to add some custom content to a <content:encoded> element.

The Django feed library comes with a set of standard elements for which you must define the content: <title>, <link>, and <description> for the feed, and then of course <title>, <link>, and <description> for individual feed items.

In our use case, we have a feed containing a list of news stories. We're already sending a truncated version of each story's content to <description>, but we want to add an additional field - <content:encoded> - to return the story's full content.

To add an additional element (or two or three), there are a few places you'll need to update - two (possibly three) standard feed methods and whatever custom method(s) you need to populate the new elements.

In this code sample, follow the trail from item_extra_kwargs() to item_your_custom_field() to add_item_elements().

from django.contrib.syndication.views import Feed
from django.utils.feedgenerator import Rss201rev2Feed

class ExtendedRSSFeed(Rss201rev2Feed):
    """
    Create a type of RSS feed that has content:encoded elements.
    """
    def root_attributes(self):
        attrs = super(ExtendedRSSFeed, self).root_attributes()
        # Because I'm adding a <content:encoded> field, I first need to declare
        # the content namespace. For more information on how this works, check
        # out: http://validator.w3.org/feed/docs/howto/declare_namespaces.html
        attrs['xmlns:content'] = 'http://purl.org/rss/1.0/modules/content/'
        return attrs
    
    def add_item_elements(self, handler, item):
        super(ExtendedRSSFeed, self).add_item_elements(handler, item)

        # 'content_encoded' is added to the item below, in item_extra_kwargs()
        # It's populated in item_your_custom_field(). Here we're creating
        # the <content:encoded> element and adding it to our feed xml
        if item['content_encoded'] is not None:
            handler.addQuickElement(u'content_encoded', item['content_encoded'])

    ...

class YourFeed(Feed):
    feed_type = ExtendedRSSFeed

    ....

    def item_extra_kwargs(self, item):
        # This is probably the first place you'll add a reference to the new
        # content. Start by superclassing the method, then append your
        # extra field and call the method you'll use to populate it.
        extra = super(YourFeed, self).item_extra_kwargs(item)
        extra.update({'content_encoded': self.item_your_custom_field(item)})
        return extra
    
    def item_your_custom_field(self, item):
        # This is your custom method for populating the field.
        # Name it whatever you want, so long as it matches what
        # you're calling from item_extra_kwargs().
        # What you do here is entirely dependent on what your
        # system looks like. I'm using a simple queryset example,
        # but this is not to be taken literally.
        obj_id = item['my_item_id']
        query_obj = MyStoryModel.objects.get(pk=obj_id)
        full_text = query_obj['full_story_content']
        return full_text

This generates a feed that looks something like this:

<?xml version="1.0" encoding="utf-8"?> <rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"> <channel> <title>News List</title> <link>http://www.example.com/</link> <description>List Description</description> <item> <title>News List Story 1</title> <link>http://www.example.com/news/story-one/</link> <description>This is the story description.</description> <content:encoded>This is the story description. This is the full content of the story. (Not a very exciting story, I know.)</content:encoded> </item> </channel> </rss>

My actual use case called for me to extend from a feed that already existed, leaving that original feed intact and only including the new element in the new feed. Here's how you'd do that:

class YourFeed(Feed):
    feed_type = ExtendedRSSFeed

    ....

    def item_extra_kwargs(self, item):
        extra = super(YourFeed, self).item_extra_kwargs(item)
        extra.update({'content_encoded': self.item_your_custom_field(item)})
        return extra
    
    def item_your_custom_field(self, item):
        return None

class YourNewFeed(YourFeed):

    def item_your_custom_field(self, item):
        ...
        return full_text

So in the original feed, 'content_encoded' comes back as None and <content:encoded> never appears. It is only generated for the new feed.

CDATA?

The customer requesting this new feed actually asked for html wrapped in a CDATA section. I never did figure out how to do that with the Django syndicator alone - the CDATA tag always came out encoded, there didn't seem to be any way around that. And every blog post I found lead me back to this old bug ticket - https://code.djangoproject.com/ticket/15936 - which suggests just ditching the CDATA section and letting Django handle the encoding. I tried that, but it didn't pass the W3C feed validator - more on that later.

CUSTOM TEMPLATES

One of the things we tried along the way was a custom template for the CDATA content. That didn't work for creating a CDATA section, as ultimately there was no way to prevent the tag from being encoded. But I didn't find many clear posts about how to do this so I thought I'd share an outline of the attempt here:

from django.template import loader, Context, TemplateDoesNotExist

...

    def item_extra_kwargs(self, item):
        extra = super(ListDetailRSS, self).item_extra_kwargs(item)

        # Define a template - give it any name, the one below is just an example.
        # The path will obviously depend on your settings.
        content_encoded_template = 'feeds/list_detail_content_encoded.html'
        try:
            # Use the Django template loader to get the template
            content_encoded_tmp = loader.get_template(content_encoded_template)
            # Set the field value as template context
            content_encoded = content_encoded_tmp.render(
                        Context({'myobj': self.item_your_custom_field(item)}))
            # Then update your extra kwargs with the rendered template
            # instead of the original value returned from your custom method
            extra.update({'content_encoded': content_encoded})
        except TemplateDoesNotExist:
            # And if you don't have a template, just use the content as
            # returned from your custom method
            extra.update({'content_encoded': self.item_your_custom_field(item)})

    return extra

Your template can be as simple as this:

    {{ myobj }}

This can be useful if you want to customize your value by wrapping some text around it or maybe apply template filters before it's rendered.

WRAPPING ELEMENTS INSIDE OTHER ELEMENTS

Our new <content:encoded> element is supposed to have a few other fields inside it. What I'm showing you here ultimately didn't work for us (see the encoding section below), but I did learn a thing or two about how to wrap elements inside other elements in ways that aren't covered in the Django documentation (I should get on adding that, right?).

    def add_item_elements(self, handler, item):
        super(ExtendedRSSFeed, self).add_item_elements(handler, item)

        if item['content_encoded'] is not None:
            # <content:encoded> is going to wrap around some other elements,
            # so instead of using handler.addQuickElement() we're going to
            # use startElement() (and then end it later)
            handler.startElement(u"content:encoded", {})

            # handler.characters() fills in content between the tags, e.g.:
            # <content:encoded>This is where the content goes.</content:encoded>
            handler.characters(item['content_encoded'])

            # And close the element, ba-bam.
            handler.endElement(u"content:encoded")

If you wanted to apply attributes to the element itself, that empty dict you set at startElement() would look like this instead:

    if item['content_encoded'] is not None:
        handler.startElement(u"content:encoded", {'my-attribute': 'my-value'})

And here's the wrapping around other elements bit:

    if item['content_encoded'] is not None:
        handler.startElement(u"content:encoded", {})
        handler.characters(item['content_encoded'])

        # Suppose we have a photo to go along with this story
        if item['media'] is not None:

            handler.startElement(u'figure', {'type': 'image/jpeg'})
            handler.startElement(u'image', {
                'src': item['media']['src'],
                'caption': item['media']['caption']
            })
            handler.endElement(u'image')
            handler.endElement(u'figure')

        handler.endElement(u"content:encoded")

ENCODING - OR, DOUBLE ENCODING

Back to that old bug ticket. We ultimately decided to follow the sage advice to forget about CDATA, even though the suggested code didn't work exactly as described (whether that's because of our old version of Django, or our version customizations, I don't know, but I never had time to research it).

Instead, we had to ... double encode? Or rather, escape, then let Django encoding do its thing.

After all that work to wrap elements one inside the other, our feed still wasn't validating. So instead of creating them as elements, we just converted the tags to strings:

    if item['content_encoded'] is not None:
        handler.startElement(u"content:encoded", {})
        handler.characters(item['content_encoded'])

        if item['media'] is not None:
            figure = '<figure type="image/jpeg">'
            figure += '<image src="%s" caption="%"></image>' % \
                    (item['media']['src'], item['media']['caption'])
            figure += '</image></figure>'
            # Don't forget to stick that string in the middle of
            # the <content:encoded> element:
            handler.characters(figure)

        handler.endElement(u"content:encoded")

<content:encoded> &lt;p&gt;&amp;lt;p&amp;gt;This is the story description.&amp;lt;/p&amp;gt; &amp;lt;p&amp;gt;This is the full content of the story.&amp;lt;/p&amp;gt; &amp;lt;p&amp;gt;(Not a very exciting story, I know.)&amp;lt;/p&amp;gt;&lt;/p&gt; &amp;lt;figure type="image/jpeg"&amp;gt; &amp;lt;image src="/media/photos/2014/05/07/050714.jpg" caption="Test Photo"&amp;gt; &amp;lt;/figure&amp;gt; </content:encoded>

Ugly, yes, but it almost worked. At least it failed in a different way.

After some trial and error, I found that ultimately I had to do some xml-specific escaping. I wound up using a method out of SAX utilities, applied it to the story content as it was being returned from my custom method, and also to the string for that <figure> tag inside <content:encoded>.

from xml.sax.saxutils import escape

...

    def add_item_elements(self, handler, item):

        ...

        if item['content_encoded'] is not None:
            handler.startElement(u"content:encoded", {})
            handler.characters(item['content_encoded'])

            # Suppose we have a photo to go along with this story
            if item['media'] is not None:

            figure = '<figure type="image/jpeg">'
                ...
                handler.characters(escape(figure))

            handler.endElement(u"content:encoded")

    ...

class YourNewFeed(YourFeed):

    def item_your_custom_field(self, item):
        ...
        return escape(full_text)

What that returns looks slightly uglier. But guess what? It validates.

<content:encoded> &amp;lt;p&amp;gt;&amp;amp;lt;p&amp;amp;gt;This is the story description.&amp;amp;lt;/p&amp;amp;gt; &amp;amp;lt;p&amp;amp;gt;This is the full content of the story.&amp;amp;lt;/p&amp;amp;gt; &amp;amp;lt;p&amp;amp;gt;(Not a very exciting story, I know.)&amp;amp;lt;/p&amp;amp;gt;&amp;lt;/p&amp;gt; &amp;lt;figure type="image/jpeg"&amp;gt; &amp;lt;image src="/media/photos/2014/05/07/050714.jpg" caption="Test Photo"&amp;gt; &amp;lt;/figure&amp;gt; </content:encoded>

THE COMPLETE PICTURE

from xml.sax.saxutils import escape

from django.contrib.syndication.views import Feed
from django.utils.feedgenerator import Rss201rev2Feed

class ExtendedRSSFeed(Rss201rev2Feed):

    def root_attributes(self):
        attrs = super(ExtendedRSSFeed, self).root_attributes()
        attrs['xmlns:content'] = 'http://purl.org/rss/1.0/modules/content/'
        return attrs
    
    def add_item_elements(self, handler, item):
        super(ExtendedRSSFeed, self).add_item_elements(handler, item)

        if item['content_encoded'] is not None:

            handler.startElement(u"content:encoded", {})
            handler.characters(item['content_encoded'])

            if item['media'] is not None:
                figure = '<figure type="image/jpeg">'
                figure += '<image src="%s" caption="%"></image>' % \
                        (item['media']['src'], item['media']['caption'])
                figure += '</image></figure>'
                handler.characters(escape(figure))

            handler.endElement(u"content:encoded")

    ...

class YourFeed(Feed):
    feed_type = ExtendedRSSFeed

    ....

    def item_extra_kwargs(self, item):
        extra = super(YourFeed, self).item_extra_kwargs(item)
        extra.update({'content_encoded': self.item_your_custom_field(item)})
        extra.update({'media': self.item_your_custom_media_field(item)})
        return extra
    
    def item_your_custom_field(self, item):
        return None

    def item_your_custom_media_field(self, item):
        return None

class YourNewFeed(YourFeed):

    def item_your_custom_field(self, item):
        obj_id = item['my_item_id']
        query_obj = MyStoryModel.objects.get(pk=obj_id)
        full_text = query_obj['full_story_content']
        return escape(full_text)

    def item_your_custom_media_field(self, item):
        obj_id = item['my_item_id']
        query_obj = MyStoryModel.objects.get(pk=obj_id)
        photo = query_obj['photo']['url']
        caption = query_obj['photo']['caption']
        return {'src': photo, 'caption': caption}

<?xml version="1.0" encoding="utf-8"?> <rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"> <channel> <title>News List</title> <link>http://www.example.com/</link> <description>List Description</description> <atom:link href="http://www.example.com/" rel="self"></atom:link> <item> <guid isPermaLink="false">http://www.example.com/guid/</guid> <title>News List Story 1</title> <link>http://www.example.com/news/story-one/</link> <description>This is the story description.</description> <content:encoded> &amp;lt;p&amp;gt;&amp;amp;lt;p&amp;amp;gt;This is the story description.&amp;amp;lt;/p&amp;amp;gt; &amp;amp;lt;p&amp;amp;gt;This is the full content of the story.&amp;amp;lt;/p&amp;amp;gt; &amp;amp;lt;p&amp;amp;gt;(Not a very exciting story, I know.)&amp;amp;lt;/p&amp;amp;gt;&amp;lt;/p&amp;gt; &amp;lt;figure type="image/jpeg"&amp;gt; &amp;lt;image src="/media/photos/2014/05/07/050714.jpg" caption="Test Photo"&amp;gt; &amp;lt;/figure&amp;gt; </content:encoded> </item> </channel> </rss>

Powered by Django

PyCon 2014

Date: Apr 27, 2014

I just want to pop in here briefly and let everyone know that PyCon 2014 went well! It's a few weeks in the past already, but I've been busy with a lot of follow-up projects ever since I got back.

A few people remarked - and I agree - that the more years you come to PyCon, the fewer people you get to see each time because you become so much more involved in volunteering. That was definitely true of 2014. Katie Cunningham and I did a talk on Friday, the first day of the conference, then spent that Saturday and Sunday in the classroom.

With all that going on, I was lucky that I got to see anyone at all. I managed to stop at the PyLadies booth for a few minutes, but sadly missed out on the camaraderie of the feminist hackerspace. Aside from my own, I only made time for two other talks. Noah Kantrowitz was enlightening as always with his Application Deployment State of the Onion.

But if you only watch one video from this year's PyCon, make it this one:

It's Dangerous to Go Alone: Battling the Invisible Monsters in Tech

Every programmer I know, myself definitely included, could use some of Julie Pagano's wise words. Her talk brought me to tears, and I'm pretty sure I was not the only one.

This year, instead of being partitioned by age group, the two days of Young Coders classes were split by spoken language - English on the first day and French on the second day. We had two terrific local teachers - David Cormier and Davin Baragiotta - working with the kids on the second day. It was fascinating seeing our teaching materials translated and taught in another language! And Davin and David are terrific teachers - they both brought so much energy and enthusiasm to the kids.

The talk was the hardest part of the conference for me. For as long as I've been going to PyCon, I've sworn that I would never take that stage - I was far too shy and crippled by stage fright. But I got over it and I did it. The conference organizers made the experience really pleasant (thanks so much to Diana, Doug, Tom, and everyone else who helped out!), and I got a lot of support from friends who've been encouraging me to take this leap for years. To anyone else trying to conquer a fear of public speaking, I would say that the most important thing is to really know your material - with that knowing comes confidence.

So here it is: "The Young Coder: Let's Learn Python":

(Also available on PyVideo: http://pyvideo.org/video/2570/the-young-coder-lets-learn-python)

Powered by Django

A computer science classroom project without a name

Date: Sep 17, 2013

A little over a month ago now, just as the new school year was about to begin, I had the privilege of attending a meeting of the local chapter of Computer Science Teachers Association here in Austin. I didn't really have any plans - my goal was just to get to know some of these local teachers and see if there was a way that I could help. Help how? I had no idea.

But as we got to talking, it became clear that what would be most welcome - at least for now - would be to get developers into the classrooms, to have them talk to students about their careers and maybe get involved directly, through mentoring and teaching.

And so the gears in my head started turning.

Last year, I volunteered with a local program called Central Texas Discover Engineering. It's a terrific way to reach out to schools and promote STEM: Through CTDE, science professionals can sign up, get paired with an elementary school teacher/classroom, and make plans for a school visit. This past spring, a few of us from PyLadies went to visit a 5th grade class in south Austin to give a talk about how we use programming in our jobs. The kids were so curious and enthusiastic - imagine how receptive a classroom of aspiring programmers would have been?

CTDE has more of a general science focus, but I wanted to adopt their model, so instead I'm working on building a roster of developers that are available specifically for visiting with Computer Science students in middle and high schools. The way I'm envisioning it, these classroom visits could just mean talking to students about what software development careers are like and what kinds of things you need to learn to get there. They might also involve some teaching, one-on-one mentoring, or extras such as helping to run an after-school computer club, if we find developer volunteers who are interested in doing those things.

And now I'm in a little bit over my head, but loving every minute of it. This is the first time I've ever attempted to put together a program like this. So far, we've gotten a huge response from the handful of user groups we've reached out to. Austin's developer community gets it - they're lining up to get into the classrooms and help kids. It's been a little slower getting the word out to teachers, but that is starting to take off as well. My hope is that signups on both sides will continue, so that Austin developers are continuing to work with area educators throughout the school year.

As teachers and developers have signed on, I've generated welcome emails, but the first letters matching volunteers to school just went out today. Volunteers are being asked to contact the teachers, but both sides are getting information about each other: teachers learn about the specialties and expertise of the volunteers they've been matched with, and volunteers get a little information about the classes they expect to be visiting - how big the classes are, what age group, what languages they're working with. It's up to the teacher and volunteer to negotiate what the content of the classroom visit will be. We're suggesting things like career talks, coding demonstrations, and mentoring, but these visits are really open to whatever the teacher and developer agree on.

In the meantime, I'm hoping to focus on getting a web site together - right now, this whole project consists of a couple of Google Drive forms and a spreadsheet. Oh, and a couple of scripts to generate the emails.

My plan is to harness the brain power of our local PyLadies chapter and put together a team to help with a web site. We just need a handful of features - separate signups for teachers and developers, a page of presentation ideas and activity resources that developers can use when planning their visits, some automation for the teacher/volunteer matching, and automation for the assortment of emails that have to be sent.

There is one thing holding us back - the project does not have a name. So if you know how to reach me and you have an idea, please let me know.

I'm really looking forward to seeing what an impact this program makes on local computer science classrooms this year. We're keeping it simple for 2013-2014, but if it's a success, we might expand and do some different things for the next school year.

Once the first classroom visits begin, I'll update on how well it's all working out.

Powered by Django

An open letter to tech conference organizers

Date: May 31, 2013

Make that "conference organizers who are interested in increasing diversity among your attendees, or in your community, or (hopefully), both".

Take what I'm about to suggest with a grain of salt. I'm a programmer and a woman who's been going to conferences for several years now. I have a ton of experience as an attendee, a little as a speaker and teacher, but I'm not privy to the specific challenges that an organizer faces. That said, I've observed a few things over the years, and I have some ideas that may help.

  1. Have a Code of Conduct.

    Have in place some declaration of how you expect attendees to behave towards one another. It doesn't matter what you call it - a Code of Conduct, an anti-harassment policy. The point is to define, in clear language, what you consider to be offensive behavior, and to let attendees know that it won't be tolerated.

    I'm not going to go into why you need a Code of Conduct - that argument has already been made by more eloquent writers than I, but if you still need convincing, I'd suggest taking a look at Jacob Kaplan-Moss' 2011 post, Why conferences need a code of conduct.

    Not everyone agrees on the finer points of what should be covered in a code of conduct, but I think that there are some general principles that are widely acknowledged as necessary. A good starting point is this sample conference anti-harassment policy developed by the Ada Initiative, released under a Creative Commons Zero license and hosted on the Geek Feminism Wiki.

  2. Tell me how to use it.

    Don't forget to address this prominently in your policy - make clear how you want attendees to report incidents if they occur. Give us a clear point of contact - either with a single staff member, or better yet, with anyone on the conference staff - and make sure everyone knows what form follow-up will take. If it's not clear to me how I should handle a harassment case, I'm likely to take matters into my own hands - tweet about it, blog about it, badmouth you or your conference. Or I may not report anything at all, which means that bad behavior goes unaddressed and someone else will likely have to deal with it down the line.

  3. Make sure I can find it.

    If I'm thinking about registering for your conference, I should be able to check it out first. That means getting at least a general idea of what the content will be - AND what your anti-harassment policy is. Don't hide it, don't make it impossible to find just because it doesn't fit neatly with your conference site's pretty design. Don't bury it in the registration process - if I can't see it beforehand, I might not be registering in the first place.

    • Good: Make sure the policy has its own page, and that there's a link to it from your FAQ or About page.
    • Better: Give it its own link, placed somewhere in a footer, or along with other general information sections such as an FAQ.
    • Best: Display the link prominently in your site's main navigation.

  4. Identify your staff members.

    If your response process involves having attendees contact a staff member, make sure we can tell who your staff members are. Nothing says "we're here to help" better than a conference staff that makes itself easy to find. If it's practical, maybe you can introduce staff during the keynote or opening remarks. Be sure that staff members have badges that look different from those issued to conference attendees - if it's not practical to order separate badges, use ribbons or stickers as an indicator. And if you can swing it, get special shirts of the same color - I'm at JSConf this week, and the conference runners have stood out in every crowd, unmistakable in their bright teal t-shirts. Now that's what I'm talking about.

Powered by Django

About


resume
django people
linkedin
twitter
flickr
readernaut

Blogs I read:
Julia Elman
Die in a Fire
Simon Willison
The Real Katie
Zed Shaw
Girl Developer


Powered by Django

Resume

Barbara Shaurette

LocationAustin, Texas
Emailbarbara.shaurette@gmail.com
Websitehttp://www.mechanicalgirl.com/
LinkedInhttp://www.linkedin.com/in/barbarashaurette/
Otherhttps://people.djangoproject.com/bshaurette/

What I'm interested in:

A position that incorporates application design and development, database design and development, and scripting in a Python-focused environment. I'm looking for the opportunity to do work that involves data analysis and reporting - I have some experience already, and that's the direction I'd like to continue in. I'm also interested in putting my project management skills to work in an engineering leadership role.

What I'm good at:

Why I'm good at it:

Active side projects:
http://www.mechanicalgirl.com/ (Python/Django)
http://www.fivesongsdaily.com/ (Python/Django) (test account available upon request)

Github projects and code samples:
http://github.com/mechanicalgirl
https://github.com/jnoller/PythonSecretSanta
http://resume.github.com/?mechanicalgirl

Conferences and Training:
DjangoCon 2008/2009/2010/2011/2012
PyCon 2009/2010/2012/2013
PDX Python Workshop mentor
PyCon 2013 - Young Coders tutorials, instructor
Austin Women's Python workshops, instructor

Organizations
Python Software Foundation (April 2013 to Present)
Member
Computer Science Teachers Association (September 2012 to Present)
Industry advocate, helping to mentor students and develop primary/high school CS curriculum
PyLadies (November 2012 to Present)
Founder, Austin chapter

Employment History

10/2012 - 04/2013
Texas Tribune
Software Engineer: Python/Django and PostgreSQL/MySQL work on data applications that illustrate the workings of such institutions as the Texas state legislature and prison system for TexasTribune.org.

11/2008 - 09/2012
Live Nation Merchandise
Senior Software Engineer: PHP, Python, Django and MySQL work on high-profile, high-traffic sites for artists such as U2, KISS, and Madonna (including CMS, media processing, reporting tools); API development; database design and management; dev/ops (release management, internal environment administration)

11/2007 - 11/2008
Tippit, Inc.
Senior Software Engineer: Development work on ETL, internal CRM and business intelligence tools, and restructuring of the data warehouse - this work involved Python, Django, PHP, mySQL and other related technologies

07/2007 - 11/2007
Live Nation Merchandise
Senior Software Engineer: Rewrite of the ecommerce site (in XCode/WebObjects), and development/maintenance of artist web sites - this work involved PHP, MySQL, and a significant amount of shell scripting

03/2007 - 06/2007
Live Nation Entertainment
Senior Applications Developer: Development and support on the event search site, Zend Framework upgrade for internationalization and cacheing - this work involved PHP and MySQL, XML/XSLT, and some C++

03/2004 - 03/2007
Adteractive, Inc.
Senior Applications Developer: Platform engineering/data warehousing, ETL, development on our PHP framework, APIs for Java validation service, coordinating the release of new PHP applications
Team Lead/Application Development: Managed developer teams through build/launch/maintenance cycles
Application Developer: Writing data models to evaluate and transfer transaction data - most of this work was in Perl and MySQL

07/2003 - 03/2004
Self-employed
General web development work, contract web design/development for local clients, primarily using HTML, JavaScript and CSS

07/1999 - 07/2003
Vivendi/Universal Inc.
Game Producer/Developer: Writing original game engines for online casual and casino games, primarily in Flash/ActionScript, with some Java work. Developed and supported a network of gaming web sites.
Web Developer: Development and support of Berkeley Systems and Sierra Online gaming sites. Most of this was front-end work - HTML/CSS and JavaScript (with some ColdFusion).

References and Recommendations

References are available upon request. A number of professional recommendations can also be found on my LinkedIn profile: http://www.linkedin.com/in/barbarashaurette

Last updated: September 18, 2012

Powered by Django

Young Coders at PyCon 2015

Date: May 01, 2015 | Category: CS Education PyCon Python

2015 was my third year teaching this class at PyCon, alongside Katie Cunningham. It feels like we've been doing it so much longer, doesn't it?

This year, as last, Young Coders ran for two days - on the Saturday of the conference, we offered the class in ...

Read More

Powered by Django

Customizing a Django RSS Feed

Date: Mar 09, 2015 | Category: Django 1.3

The Framework: Django 1.3 (not my choice!)

The Mission: Create an RSS feed that includes an extra field for full story content, plus a few additional fields for images

I know. It's 2015 and we're still on 1.3. But the changes to Django syndication since 1.3 haven't been that dramatic, ...

Read More

Powered by Django

PyCon 2014

Date: Apr 27, 2014 | Category: PyCon Python

I just want to pop in here briefly and let everyone know that PyCon 2014 went well! It's a few weeks in the past already, but I've been busy with a lot of follow-up projects ever since I got back.

A few people remarked - and I agree - ...

Read More

Powered by Django

A computer science classroom project without a name

Date: Sep 17, 2013 | Category: CS Education

A little over a month ago now, just as the new school year was about to begin, I had the privilege of attending a meeting of the local chapter of Computer Science Teachers Association here in Austin. I didn't really have any plans - my goal was just ...

Read More

Powered by Django

An open letter to tech conference organizers

Date: May 31, 2013 | Category: Personal

Make that "conference organizers who are interested in increasing diversity among your attendees, or in your community, or (hopefully), both".

Take what I'm about to suggest with a grain of salt. I'm a programmer and a woman who's been going to conferences for several years now. I have a ton ...

Read More

Powered by Django