Skip to content

And she’s back!

March 15, 2010

After way too long a hiatus, our group is starting up our Monday night meetings again.  Tonight will be our first meeting since December (at which point everyone got busy with holiday parties, hometown travel, and other festivities), so look for some posts about that a little later this week.

In the meantime, I have been soaking up a lot of Python-related content thanks to three fabulous days at PyCon and many subsequent hours of catching up on all the talks I missed (because I was busy attending concurrent sessions or indulging in spontaneous conversations) online.  A lot of great technical content was presented (including a lot more beginner-level talks than in previous years), so be sure to check out the videos.

I took my own notes on a lot of these, but I want to share with you some notes from one of the community-oriented talks I attended.  Anna Martelli Ravenscroft (whom you may know as co-editor of the Python Cookbook Second Edition) gave a really wonderful talk entitled “Diversity as a Dependency” that was a fresh take on why diversity is important to a community like Python.  My notes follow, but I also encourage you to watch the talk for yourself.

The main thrust of the talk (and the point that, for me, made it feel different from other talks I’ve heard on the subject) was that too often the rhetoric around diversity comes down to guilt.  Diversity is not a club to beat people with, Anna insisted.  Nobody wins diverser-than-thou games.  So in that room, there were to be no traps: “nobody gets set up here.”  The idea was to approach diversity a little differently.  Instead of making it about moral or political correctness, she said, we need instead to focus on the ways in which diversity tangibly benefits our community (and it does).

To show this, Anna went through some compelling case studies showing that a diversity of perspectives, skill sets, needs, and motivations generates creativity and leads to innovative problem-solving.  In other words, interactions among diverse individuals lead to better outcomes.  This is because we all see problems in different ways; we may even see different problems.  And we certainly see different solutions.

In addition, Anna highlighted the benefits of universal design: what was designed for people with specific differences in ability (e.g., curb cuts designed to allow easier wheelchair access to sidewalks), often turns out to be useful to everyone (e.g., people with wheeled luggage, strollers, shopping carts, etc.).

These principles from the larger world also hold true within Python, she said.  We need Tim Peters to invent Timsort. We need Steve Holden to start PyCon. We need Catherine Devlin to bring Python to secretaries. Not everyone can give a talk like Alex Martelli.  Not everyone can wade through the legalese like Van Lindberg.  We all come to Python with different backgrounds and experiences.  And this is where the typical forms of diversity come into play, because our perspectives are informed by our identities (which are the personal characteristics that most diversity talks focus on). Our culture, race, gender, religion, primary language, country of origin, orientation: all of these impact who we are and what we bring to the table.

But, Anna continued, diversity is hard. You can’t just grab random people, put them together, and expect creative miracles.  All those differences cause friction, and there can be trouble communicating. People have different goals and priorities, and so you may have conflicts there.  Learning to value other perspectives and skill sets can be a challenge.  Imagine that you’re creating a web app that needs to work across multiple browsers and platforms: it’s a pain.  In the same way , every person runs their own OS, so to speak, and comes with a unique chipset and browser… and people don’t come with docs.

So really, harnessing diversity is a matter of creating documentation for people, and learning how to work together effectively.  In order to do this, we mostly just need a willingness to work at the issue, knowing that it will lead to mutual benefits and a more robust language and community.  Python is already a great language, but it’s not the best language it can be yet.  For Python to be the very best it can be, she concluded, to reach the broadest audience and be useful to people around the world, diversity is necessary.

This talk definitely came at a good time.  Anna made of point of saying that this topic is not something we need to talk about because we (as a community) are horrible at it; rather, it’s something we need to discuss because there’s still room to do better.  At this year’s PyCon, more than 1100 pythonistas attended (the biggest one ever!) and of those attendees over 11% were female.  This is a great accomplishment, but there’s room to improve even more (and gender is clearly only one limited measure of diversity).

So whoever you are, check out Python!  And encourage your friends, family, coworkers, and pets to do the same.  We all have something to contribute, and to learn.  With that, I’m off to learn some things at our Monday night meeting…

Catching up

December 11, 2009

Hi again!  After too long a hiatus, I’m back to coding and blogging.  I’ve spent the last couple of weeks fighting with a pygame install (it turns out that because bdist_mpgk and setuptools haven’t been ported yet, there’s no Mac OS installer available for Python 3.1 and we need to build it from source—oh joy). I’m just about at the point where I’m ready to skip that chapter because I miss making progress and the exercise just isn’t worth the frustration anymore.  But I do hope to circle back to it at some point.  In the meantime, I thought I’d catch you up on Chapter 6…

Chapter 6 sees us writing a point-of-sale (POS*) program for a health club and/or its attached coffee shop.

*[Yes: my brain, too, does a double-take at that abbreviation throughout the chapter. Why, I wonder at first, am I being encouraged to write crappy code? English is great.]

At first, our task was simple: we needed to collect information for each order comprising the customer’s credit card number, the item’s price (without a decimal point) and a brief item description.  We used this formatted string to collect the information (which then got appended to a text file):

“%16s%07d%16s\n” % (credit_card, price*100, description)

Okay, no problem.  We’ve allotted the standard 16 digits for the credit card, 7 digits padded out with 0s for the price (that way we can charge up to $99,999.99 for our merchandise; heckuva coffee shop, Brownie), and we have 16 characters for our item description.

Naturally, by the time we got around to running the program and providing input, I had to try to break the thing.  First, I played nice.  I ordered a latte and cashier me entered my credit card number as 1234567890123456.  The text file showed:

12345678901234560000200           LATTE

Fine.  But then I was hungry.  So I ordered a muffin, but cashier me must have accidentally hit an extra key because 17 digits were entered.  I ran over to my text file, expecting it to have truncated the entry.  But no, I got:

123456789012345670000120          MUFFIN

Ooo, so the format doesn’t provide an upper-bound for the entry.  Good to know.  But my understanding is it provides a lower-bound; let’s test that.  More caffeine, please, with a 10-digit card number:

12345678900000200           LATTE

Right, this is what I expected.  If I’d coded “%016s%07d%16s\n” % (credit_card, price*100, description) then it would have filled in leading 0’s.  Good.  Okay, what happens when I throw it a curveball in the form of some irreverently arranged letters in there with the numbers?  Turns out, it will spit out what you put in:

kick me0000150           DONUT

Nice.  But I suppose that makes sense, since I told it to expect a string.  What if I tell it to expect a number?  Let’s try modifying the string format to:

“%16d%07d%16s\n” % (credit_card, price*100, description)

Now it should expect a number, right?  And indeed, when the sassy cashier me inputs another erroneous card entry, I get a TypeError:

1. DONUT
2. LATTE
3. FILTER
4. MUFFIN
5. Quit
Choose an option: 2
Credit card number: kick me
Traceback (most recent call last):
File “/Users/xfer/Desktop/Python/pos.py”, line 19, in <module>
save_transaction(prices[choice – 1], credit_card, items[choice – 1])
File “/Users/xfer/Desktop/Python/transactions.py”, line 3, in save_transaction
file.write(“%16d%07d%16s\n” % (credit_card, price*100, description))
TypeError: %d format: a number is required, not str

Interesting.  Okay, let’s make sure it works when I play nice.  Whoops!  Another TypeError!  I’m not entirely sure why this happened, so if anyone has any insight, please do tell.

The rest of the chapter progressed fairly smoothly.  We learned how to separate functions we’d written into modules we could call, so that they could be used in multiple locations and remain consistent across updates and multiple uses.

Tangentially, we learned how to comment our code, which is always a good thing.

Finally, we learned how to apply a discount or two to our prices—via another module—and the importance of qualifying function names.  We used a standard discount that applied to all customers because of a limited-time promotion, and a conditional discount that applied only to customers with a “club card” of sorts.  Both of these functions were called “discount”, so we needed to use FQNs to distinguish them in the code.  Seems pretty straightforward.

Onward and upward!

A word about women

November 23, 2009

This started as a reply to Kevin’s comment under my Is it in you? post, but I decided it deserved its own spot as a separate post.

Although I’m extremely interested in other people’s thoughts on the matter, I usually avoid weighing in on the whole “Women in Tech” question for two reasons: 1) I don’t feel qualified to speak for an entire gender, and 2) I don’t feel like I qualify as a woman in tech.  I’m a woman who likes tech.  I’m a woman who observes tech from the fringes.  But I’m not in there with a soldering iron or up to my elbows in code.  (Yet.)  It occurs to me, however, that these feelings probably aren’t unique to me, and that if more women who are comfortable on the fringes felt free to dive into the middle, we wouldn’t have as big a gender imbalance (and we could eventually move on to talking about and solving other problems, which I think we’d all like to do).

So Kev, thanks for your thoughts and questions.  I still don’t feel comfortable speaking for an entire demographic, but maybe it’s time I speak for myself.  Everyone’s childhood is unique; not even your siblings will have exactly the same experiences you have.  But I do think I can extrapolate pieces of my own experience into things that may push other women toward or away from tech.

1. Individual personality.

I think we can agree that some things are innate.  The whole nature/nurture debate is clearly beyond the scope of this post, but I think it’s good for us to remember that some boys and girls will have traits that make tech a good fit, and some boys and girls will have traits that make tech a poor fit.  That’s okay.

Looking back on my own experiences in the light of my education and career choices, it makes sense to me that I took this circuitous route to coding.  I was never one of those kids who took stuff apart all the time for the heck of it.  I definitely wasn’t shy about getting in there with a screwdriver if something was broken, but as long as it was functional my clock radio remained intact.  I was, instead, the kind of kid curled up in her room with a book (unless there was an opportunity to swim, and then my butt was in the water until I was a shriveled little prune of a child; but I digress).  I did love to solve problems and ask questions, and I was very receptive to my dad’s explanations of math (one time in the third grade I came home with a question on long division, and by the end of the evening he had taught me log tables).  I ended up taking to math quite a bit, to the point that I skipped a level in middle school and participated in ASHME (now AMC) competitions all throughout high school.

So perhaps the lesson for parents here is to be open to your daughters’ interests and make all kinds of information available to them as far as their innate interests go.

2. Role models.

My mom was a double major in math and computer science, and went on to get her master’s in computer science from MIT.  While she stayed home to raise my brothers and myself, I was always very aware of her educational background and her interest in tech topics, and I think I owe a lot of my comfort level and early interest in such things to the fact that I had a strong role model in such close proximity.

It’s possible, though, that had I grown up knowing women who were currently working in tech fields, I might have been inclined to pursue them more actively when in high school and college.  I remember going to the office with my dad on “take your child to work” day (I don’t recall now whether it was specifically daughters at that point—might have been), and that the overall impression was: wow, this office has lots of computers, bright carpeting, blinky lights, and a lot of dudes in sneakers! Not that there’s anything wrong with dudes in sneakers, mind you, but I remember very few, if any, dudettes.  That’s probably different now in many offices, but not in all.

So perhaps the lesson for parents here is to be conscious of the kind of role models your daughters have, and that it might be worth going out of your way to help them see other women doing cool stuff in tech—not just on TV or in the paper, but IRL.

3. Peers.

In high school, math was my strongest subject.  In fact, I got a perfect score on the math portion of the SATs (but not on the verbal portion).  So how did I end up an English major?

I went to a small, private, college prep school and graduated with a class of 27 people (most classes had 50 people, but any way you slice it it’s not a large school).  20 of my classmates were female; just 7 were male.  But when I looked around at my fellow ASHME competitors, the gender balance was 50/50.  If I included competitors from other class years near mine, it skewed wildly toward the male side.  Where were my peers?  Then there was the question of who were my peers.  The other “math girls” were shy, introverted, and socially awkward.  (Of course, now I realize that it was high school, and we were all socially awkward.)  I played two varsity sports, sang in the chorale, and participated in student government; I wasn’t sure I really fit in with the math and science crowd.  Of course, I didn’t fit in with the “math is hard and boring” crowd either.  I felt like a misfit.

And where do all misfits fit in?  As English majors!  Ta-da!

Seriously, though, the best place for someone who is interested in a little bit of everything, but hasn’t yet discovered an in-depth passion for anything, is with a whole bunch of books.  Publishing, the industry that finds, curates, and spreads every kind of idea via books, was the ideal career for me.  And still is.  But I’m more and more coming to realize that tech serves this same purpose.  (This is probably because tech has been growing into this role with the rise of the internet.  Keep in mind that when I was making these decisions in high school, the mainstream world was just beginning to discover email and AOL.  Today’s students can certainly more easily recognize the ways in which tech dovetails with their other interests.  Including, of course, publishing.)

So perhaps the lesson for parents here is to help kids discover what their interests are, what those interests say about who they are as people, what that means about how they relate to their peers, and how various forms of tech might support or augment those interests (and, therefore, how tech might support or augment them as people).

4. Leaving the door open.

My grandmother likes to say (and I’ve obviously taken to repeating it), “You can do everything, you just can’t do it all at the same time.”  This is a woman who’s 78 years old and currently enjoying her fifth or sixth career as a university professor (previous careers include middle school teacher, opera singer, television personality, church organist and pastor’s wife, and probably another one I’m forgetting at the moment).  This also relates to the point about role models, of course.  But the main idea is that even though I didn’t gravitate to coding right away, I had enough of a taste of those concepts to come back around to it at this point in my life.

The freedom to observe tech culture, to be surrounded by tech-related ideas, and to finally dive into the actual coding nitty-gritty when I felt good and ready has been integral to my enthusiasm and willingness to embrace it.

So perhaps the lesson for parents here is that you don’t have to panic if your daughters choose something else.  Even if you think they have the innate personality for it; even if you’ve gone out of your way to provide role models; even if their peers are going into tech: there’s always time to come back around when they’re so inclined.  Do them a favor by keeping that door open via the willingness to talk about what you know, to share ideas, and to keep providing encouragement.

—-

There are probably other things I’m failing to distill here, and other women who have taken other paths have made other great points.  (If you or your kids are interested in reading some of them, I highly recommend an essay collection called She’s Such a Geek.)  But this is what I have to add to the conversation at the moment.  And thanks for asking—I think the fact that parents like you are sensitive to these questions is a huge step forward for your daughters and for us as a community.

I Feel Happy

November 13, 2009

I want to go for a walk.

I’m not dead yet, just buried under comp exams this week.  But I’ve been sneaking in some Python time as well, and will have a couple of new posts by Monday or Tuesday.  Stay tuned!  Modular programming is up next…

Hashing it out

November 2, 2009

Well it turns out that all but three of us had other plans tonight, so we decided to postpone Meeting #3 until next week. We’re working through chapters on our own in the meantime, so tonight I sat down with Chapter 5.

If you recall, Chapter 4 had us split a list of Surf-A-Thon results into names and scores, then sort the scores and print the top three. But we need to know who those scores belong to, so we need a way to associate the names with the scores.  I’ve been thinking about this.

If you also recall, I’ve recently read a chapter on PHP arrays, and thus have just enough knowledge to be dangerous (or plain stupid). According to that chapter, PHP allows you to store a whole other array (array’, if you will) inside an array element. [This makes me think of a universe within a universe, or, in other words: “Phenomenal cosmic power… itty-bitty living space.”]  In any case, it seems to me that one way to solve our name-score problem is to create an array whose elements are scores, and then to create a one-element array’ for each of those, whose one element would be the associated name.

Actually, if Python allows strings as keys, perhaps we could just make each name the key and each score the value?  One possible catch comes to mind here: In the array with numerical keys, the values became “detached” from these keys when they were sorted.  If the same phenomenon occurs with strings as keys, that won’t work.

Here’s another way to say it: Think about each element in the array as a train car, with the keys painted on the side and the values stored within.  When the keys were numerical (0, 1, 2, etc.) and we sorted the contents, the train cars stayed hitched in the same order, and the contents were removed, reshuffled, and reinserted.  Then we were able to print the contents of cars 0, 1, 2 and we received the three highest scores.  So I wonder: if we paint strings on the sides of the cars, names in this case…

  1. will the cars get unhitched—with their contents still inside—and reshuffled?
  2. will the cars stay where they are while the contents are removed, reshuffled, and reinserted (as before)?
  3. or, perhaps, will the contents be removed, reshuffled, and reinserted while someone scrubs off the paint and repaints the cars so that the strings are also sorted (in some kind of order—alphabetical?)?

It’s difficult for me to think of more than one or two scenarios in which option 3 would be useful, so I hope that’s not the way it was designed.

Chapter 5 begins by asking us to be like the fox, who makes more tracks than necessary, some in the wrong direction: it suggests that we create two arrays (one for names and one for scores).  Well it takes me all of two seconds to recognize that this is a thoroughly useless approach; the minute we cleave this data and shuffle it, we’re done for. It’s like cutting a stack of papers at the margins containing the page numbers, and then dropping the resulting stacks on the floor.

So, okay, flipping ahead… I’m told there’s this thing called a hash.  Well, actually, the Pythonic term is a dictionary.  (Python peeps, enough of this alternative vocabulary.  What are you, special?  So some of you have a pony.  Good for you.*)  Well, actually, I’m told there’s a hash, and a set (no problems), and a queue (no problems), and a linked list, and a multi-dimensional array.  Perhaps this last is the equivalent of the PHP genie?  But no matter, the hash has exactly two columns, so it appears to be what I really need.

At this point, potential dinner plans appear and I decide to seize the moment, so tune in later to see how all this works out…

*Nuthin’ but love, peeps.  Nuthin’ but love.  :-)

More coffee anyone?

November 1, 2009

Hey, thanks so much for all the great discussion and engagement.  It’s a huge encouragement to have experienced Pythonistas (and fellow n00bs!) join in the conversation.

Just a quick update on what I’ve been doing this weekend as I finish up Chapter 3 (which I started Monday night) and move through Chapter 4.

I mentioned in my last post that Chapter 3 continues to look at the coffee bean pricing example, and that it has us interacting with the Twitter API.  That piece of code was given to us as:

def send_to_twitter(msg):
    password_manager = urllib.request.HTTPPasswordMgr()
    password_manager.add_password(“Twitter API”,         “http://twitter.com/statuses&#8221;, username, password)
    http_handler =         urllib.request.HTTPBasicAuthHandler(password_manager)
    page_opener = urllib.request.build_opener(http_handler)
    urllib.request.install_opener(page_opener)
    params = urllib.parse.urlencode( {‘status': msg} )
    resp = urllib.request.urlopen(“http://twitter.com/statuses/
        update.json”, params)
    resp.read()

I guess I basically understand what this does, but it wasn’t presented in detail.  One question it raised for me concerns the functions in the urllib.request library (or module, as I’m told is a Pythonic synonym).  You may remember an earlier post in which I consulted a Pythonista friend of mine who suggested the use of:

from urllib.request import urlopen

Well, looking at the send_to_twitter() function, I of course notice that we’re calling half a dozen different functions from the same module.  Surely it’s easier to import the whole module (in one line of code) than to import the functions individually (in six lines of code), yeah?  Where would the line be drawn on this Pythonic technique?  It’s okay to import two functions individually?  Three?  Opinions, please.

All that aside, we did learn to define our own functions (and to use these to avoid code duplication) as well as how to pass parameters to functions.  We also covered stack frames and local variables.  So far, so good.

Chapter 4 covers files and arrays.  Hooray!  To explore data structures, we left behind coffee beans for a more recreational example: Codeville’s annual “Surf-A-Thon”.  First we learned to read a text file stored on disk, and to do so line-by-line using a for loop.  Each line contained a name and a score, so we used split() to divide the strings and learned to create an array with names and scores.  Finally, we learned to use sort() and reverse() so that we could print the top three scores.  Chapter 5 will apparently show us how to retrieve and display the corresponding names.

Coincidentally, I’m currently editing a book on PHP and happened to read the chapter on arrays earlier this week.  So as I was working through Chapter 4 I had fresh in my mind certain details from the PHP chapter, and these structures seem to work in similar ways with Python.  One thing I wonder about: PHP distinguishes between indexed arrays (with numerical keys) and associative arrays (which allow strings as keys).  With the Surf-A-Thon example, we didn’t specify our keys but let Python auto-populate them for us by using append(), and Python chose numerical keys beginning with 0 (which PHP would do as well).  But I wonder whether Python also allows strings as keys, and whether it distinguishes arrays by key type.  I could go look it up (and might soon), but conversation is much more fun, so feel free to jump in on that.  :-)

Our group’s next meeting is tomorrow night (Monday again), and hopefully the rest of the group has also gotten through Chapter 4 so we can all start Chapter 5 together.  More updates soon!

Is it in you?

October 27, 2009

I just had the most wonderful moment. At home after our second in-person meeting tonight, I was working my way through an exercise in Chapter 3. Continuing the coffee bean example program from Chapter 2, we were using the Twitter API to post coffee bean prices to Twitter (more on that later).

In summary, the exercise asked us to create two options for the user, an option to immediately report the current price of coffee beans or the option to monitor the price and send an alert when it dips below a certain point.  For immediate reporting, the example had it send the floating point number we had fetched as the price.  Well, I thought it would be a little odd to post a random number to my Twitter stream; I wanted to be able to surround it with text, including our group’s hash: “The price of coffee beans is now: $X.XX (Python rules!) #learnpython”

So I tried this:

if price_now == “Y”:
    send_to_twitter(“The price of coffee beans is now: $” + get_price() +         ” (Python rules!) #learnpython”)

But that resulted in a TypeError, as my definition of get_price() asked it to return a float.  Hmmm.  I needed to find a way to convert the price back into a string.  I had not yet been taught how to do that.  Okay, no worries.  I had seen str() somewhere before—I probably needed to use that.  How about :

if price_now == “Y”:
    send_to_twitter(“The price of coffee beans is now: $” + str(get_price())         + ” (Python rules!) #learnpython”)

No go.  Okay, let’s try:

if price_now == “Y”:
    return str(get_price())
    send_to_twitter(“The price of coffee beans is now: $” + get_price() +         ” (Python rules!) #learnpython”)

No good either.  I tried one or two other things, before arriving at this, which worked:

if price_now == “Y”:
    current_price = str(get_price())
    send_to_twitter(“The price of coffee beans is now: $” + current_price +         ” (Python rules!) #learnpython”)

When no error came back, I triumphantly ran over to my browser and refreshed my Twitter page, cheering aloud when my nice little post appeared!  (Then I revised my code because I had made a punctuation typo in my string, and we can’t have that now, can we?)

But none of that is the point.

The point is: it’s in me.  I wasn’t sure that is was, and now I know—it is.

And what, exactly, is “it”?  It is the bug.  It is the combination of native curiosity and stubbornness that made me play around with the code and take some wild guesses instead of running straight to Google (or choosing to stay within the bounds of the exercise).  That might sound like a small thing, but I know it is not.  I was determined to make the program do what I wanted it to do, I came up with a few guesses as to how to do that, and I kept trying different things until I succeeded (and then I felt thrilled).

As much as I have to learn, I know now that I really am hooked.  And that I’ll get there.

Follow

Get every new post delivered to your Inbox.