# 15 Oct 2016, 01:55PM: New Zine "Playing With Python: Two of My Favorite Lenses":
MergeSort, the feminist maker meetup I co-organize, had a table at Maker Faire earlier this month. Last year we'd given away (and taught people how to cut and fold) a few of my zines, and people enjoyed that. A week before Maker Faire this year, I was attempting to nap when I was struck with the conviction that I ought to make a Python zine to give out this year.
So I did! Below is Playing with Python: 2 of my favorite lenses. (As you can see from the photos of the drafting process, I thought about mentioning pdb, various cool libraries, and other great parts of the Python ecology, but narrowed my focus to bpython and python -i.)
Playing with Python
2 of my favorite lenses
[magnifying glass and eyeglass icons]
by Sumana Harihareswara
When I'm getting a Python program running for the 1st time, playing around & lightly sketching or prototyping to figure out what I want to do, I [heart]:
bpython & python -i
[illustrations: sketch of a house, outline of a house in dots]
bpython is an exploratory Python interpreter. It shows what you can do with an object:
>>> dogs = ["Fido", "Toto"]
append count extend index insert pop remove reverse sort
And, you can use Control-R to undo!
[illustrations: bpython logo, pointer to cursor after dogs.]
Use the -i flag when running a script, and when it finishes or crashes, you'll get an interactive Python session so you can inspect the state of your program at that moment!
$ python -i example.py
Traceback (most recent call last):
File "example.py", line 5, in
toprint = varname + "entries"
TypeError: unsupported operand type(s) for + : 'int' and 'str'
[illustration: pointer to type(varname) asking, "wanna make a guess?"]
More: "A Few Python Tips"
This zine made in honor of
NYC's feminist makerspace!
CC BY-SA 2016 Sumana Harihareswara
Everyone has something to teach;
everyone has something to learn.
Here's the directory that contains those thumbnails, plus a PDF to print out and turn into an eight-page booklet with one center cut and a bit of folding. That directory also contains a screenshot of the bpython logo with a grid overlaid, in case you ever want to hand-draw it. Hand-drawing the bpython logo was the hardest thing about making this zine (beating "fitting a sample error message into the width allotted" by a narrow margin).
Libby Horacek and Anne DeCusatis not only volunteered at the MergeSort table -- they also created zines right there and then! (Libby, Anne.) The software zine heritage of The Whole Earth Software Review, 2600, BubbleSort, Julia Evans, The Recompiler, et alia continues!
(I know about bpython and python -i because I learned about them at the Recurse Center. Want to become a better programmer? Join the Recurse Center!)
# (1) 12 Oct 2016, 11:00AM: Rough Notes for New FLOSS Contributors On The Scientific Method and Usable History:
Some thrown-together thoughts towards a more comprehensive writeup. It's advice on about how to get along better as a new open source participant, based on the fundamental wisdom that you weren't the first person here and you won't be the last.
We aren't just making code. We are working in a shared workplace, even if it's an online place rather than a physical office or laboratory, making stuff together. The work includes not just writing functions and classes, but experiments and planning and coming up with "we ought to do this" ideas. And we try to make it so that anyone coming into our shared workplace -- or anyone who's working on a different part of the project than they're already used to -- can take a look at what we've already said and done, and reuse the work that's been done already.
We aren't just making code. We're making history. And we're making a usable history, one that you can use, and one that the contributor next year can use.
So if you're contributing now, you have to learn to learn from history. We put a certain kind of work in our code repositories, both code and notes about the code. git grep idea searches a code repository's code and comments for the word "idea", git log --grep="idea" searches the commit history for times we've used the word "idea" in a commit message, and git blame codefile.py shows you who last changed every line of that codefile, and when. And we put a certain kind of work into our conversations, in our mailing lists and our bug/issue trackers. We say "I tried this and it didn't work" or "here's how someone else should implement this" or "I am currently working on this". You will, with practice, get better at finding and looking at these clues, at finding the bits of code and conversation that are relevant to your question.
And you have to learn to contribute to history. This is why we want you to ask your questions in public -- so that when we answer them, someone today or next week or next year can also learn from the answer. This is why we want you to write emails to our mailing lists where you explain what you're doing. This is why we ask you to use proper English when you write code comments, and why we have rules for the formatting and phrasing of commit messages, so it's easier for someone in the future to grep and skim and understand. This is why a good question or a good answer has enough context that other people, a year from now, can see whether it's relevant to them.
Relatedly: the scientific method is for teaching as well as for troubleshooting. I compared an open source project to a lab before. In the code work we do, we often use the scientific method. In order for someone else to help you, they have to create, test, and prove or disprove theories -- about what you already know, about what your code is doing, about the configuration on your computer. And when you see me asking a million questions, asking you to try something out, asking what you have already tried, and so on, that's what I'm doing. I'm generally using the scientific method. I'm coming up with a question and a hypothesis and I'm testing it, or asking you to test it, so we can look at that data together and draw conclusions and use them to find new interesting questions to pursue.
So I'll ask a question to try and prove or disprove my hypothesis. And if you never reply to my question, or you say "oh I fixed it" but don't say how, or if you say "no that's not the problem" but you don't share the evidence that led you to that conclusion, it's harder for me to help you. And similarly, if I'm trying to figure out what you already know so that I can help you solve a problem, I'm going to ask a lot of diagnostic questions about whether you know how to do this or that. And it's ok not to know things! I want to teach you. And then you'll teach someone else.
- Expected result: doing run-dev.py on your machine will give you the same results as on mine.
- Actual observation: you get a different result, specifically, an error that includes a permissions problem.
- Hypothesis: the relevant directories or users aren't set up with the permissions they need.
- Next step: Request for further data to prove or disprove hypothesis.
In our coding work, it's a shared responsibility to generate hypotheses and to investigate them, to put them to the test, and to share data publicly to help others with their investigations. And it's more fruitful to pursue hypotheses, to ask "I tried ___ and it's not working; could the reason be this?", than it is to merely ask "what's going on?" and push the responsibility of hypothesizing and investigation onto others.
This is a part of balancing self-sufficiency and interdependence. You must try, and then you must ask. Use the scientific method and come up with some hypotheses, then ask for help -- and ask for help in a way that helps contribute to our shared history, and is more likely to help ensure a return-on-investment for other people's time.
So it's likely to go like this:
- you try to solve your problem until you get stuck, including looking through our code and our documentation, then start formulating your request for help
- you ask your question
- someone directs you to a document
- you go read that document, and try to use it to answer your question
- you find you are confused about a new thing
- you ask another question
- now that you have demonstrated that you have the ability to read, think, and learn new things, someone has a longer talk with you to answer your new specific question
- you and the other person collaborate to improve the document that you read in step 4 :-)
This helps us make a balance between person-to-person discussion and documentation that everyone can read, so we save time answering common questions but also get everyone the personal help they need. This will help you understand the rhythm of help we provide in livechat -- including why we prefer to give you help in public mailing lists and channels, instead of in one-on-one private messages or email. We prefer to hear from you and respond to you in public places so more people have a chance to answer the question, and to see and benefit from the answer.
We want you to learn and grow. And your success is going to include a day when you see how we should be doing things better, not just with a new feature or a bugfix in the code, but in our processes, in how we're organizing and running the lab. I also deeply want for you to take the lessons you learn -- about how a group can organize itself to empower everyone, about seeing and hacking systems, about what scaffolding makes people more capable -- to the rest of your life, so you can be freer, stronger, a better leader, a disruptive influence in the oppressive and needless hierarchies you encounter. That's success too. You are part of our history and we are part of yours, even if you part ways with us, even if the project goes defunct.
This is where I should say something about not just making a diff but a difference, or something about the changelog of your life, but I am already super late to go on my morning jog and this was meant to be a quick-and-rough braindump anyway...
# 28 Sep 2016, 04:43PM: Analogy:
At MidAmericon II I got to shake hands with Dr. Stanley Love and tell him that I liked his speech (he had accepted the Campbell Award for Best New Writer on behalf of his friend Andy Weir). When I later recounted this to friends I found myself saying things like "I reassured an astronaut, which means I will surely go to heaven" or "I couldn't lie to an astronaut! That's a sin!"
This led me to realize that astronauts are, vaguely, to the general US public now as Catholic nuns (at least schoolteacher nuns) were to previous generations. They are cloistered away to be closer to heaven. They have to live in close quarters and collaborate under conditions of micromanagement. They go through arduous selection processes and care a lot about education. Nuns had Rome, astronauts have Houston. We are in awe of their dedication and endurance and altruism and grace. And just the sight of one of their uniforms/habits triggers that reaction of awe.
(Your mileage may vary, conditions may apply, vanity, vanity, all is vanity.)
# 26 Sep 2016, 09:33AM: iCalendar Munging with Python 3, Requests, ics.py, and Beautiful Soup:
Leonard and I love seeing movies at the Museum of the Moving Image. Every few months we look at the calendar of upcoming films and decide what we'd possibly like to see together, and put it on our shared calendar so we remember. And for every showing (example) the MoMI provides an iCalendar (.ics) file, to help you add it to your electronic calendar. But it's a pain to individually download or refer to each event's .ics file and import it into my electronic calendar -- and the museum's .ics files' DTEND times are often misleading and imply that the event has a duration of 0 seconds. (I've asked them to fix it, and some of their calendar files have correct durations, but some still have DTEND at the same time as DTSTART.)
Saturday morning I had started individually messing with 30+ events, because the MoMI is doing a complete retrospective of Krzysztof Kieslowski's films and I am inwardly bouncing up and down with joyous anticipation about seeing Dekalog again. And then I thought: I bet I can automate some of this tedious labor!
So I did. The create-fixed-ics.py script (Python 3) takes a plain text file of URLs separated by newlines (see movie-urls-sample-file.txt for an example), downloads iCalendar files from the MoMI site, fixes their event end times, and creates a new unified .ics file ready for import into a calendar. Perhaps the messiest bit is how I use a set of regular expressions, and my observations of the customs of MoMI curators, to figure out the probable duration of the event.
Much thanks to the programming ecology that helped me build this, especially the people who made RegExr, Beautiful Soup (hi Leonard), Requests, ics.py, and the bpython interpreter, and the many who have written excellent documentation on Python's standard library. Thanks also to Christine Spang, whose "Email as Distributed Protocol Transport: How Meeting Invites Work and Ideas for the Future" talk at Open Source Bridge 2015 (video) introduced me to hacking with the iCalendar format.
- It can be a bit slow as the number of URLs adds up -- it took maybe 5 minutes to process about 31 events. I oughta profile it and speed it up. But I usually only need to do this about six times a year.
- This script is not careful, and will overwrite a previously created .ics file at the same address (in case you're running it twice in one day). It has no tests and approximately no error-checking. This was a scratch-my-own-itch, few-hours-on-a-Saturday project. No Maintenance Intended.
- Absolutely not an official project of the Museum of the Moving Image.
# 22 Sep 2016, 03:09PM: New Essay: "Toward a !!Con Aesthetic":
Over at The Recompiler, I have a new essay out: "Toward A !!Con Aesthetic". I talk about (what I consider to be) the countercultural tech conference !!Con, which focuses on "the joy, excitement, and surprise of programming". If you're interested in hospitality and inclusion in tech conferences -- not just in event management but in talks, structure, and themes -- check it out.
Christie Koehler also interviews me about this and about activist role models, my new consulting business, different learning approaches, and more in the latest Recompiler podcast.
[announcement cross-posted from Geek Feminism]
# 13 Aug 2016, 12:40PM: Habit, Identity, Self-Care, and Shame:
Lately I've been working to acknowledge and honor the difference it makes to me to invest in various activities and habits when they do make a difference to me. Exercising every day, and setting out my workout stuff the night before so I can just grab it in the morning. Witnessing live music. Talking with friends via voice or in person, more often than would happen by chance. Using Beeminder to increase the quantity and frequency of good habits, and LeechBlock to reduce the amount of time I spend on Twitter or MetaFilter. Praying every day. Keeping my work area and my chunk of the bedroom relatively uncluttered, so I feel more peaceful and focused. And beside the noticeable positive effects are some strange echoes and murmurs that are also worth attention.
When the bedstand and bureau and desk are clear of clutter, sometimes I feel unmoored, as though I am surely just moved into or about to move away from this apartment. A life with great expanses of unused horizontal surface area is unfamiliar enough to me that it feels liminal, not mine. Yet, anyway; perhaps I can get used to it.
And sometimes, I feel shame about what I want or need, shame about what sustains me. This is different from anti-"guilty pleasure" bias. I engage in self-care in response to specific stress or disappointment. When a blow hits me, I curl up with the latest Courtney Milan romance novel and some combination of tea, cognac, corn nuts, and chocolate. And feminism has helped me overcome fatphobic and anti-feminine prejudice that castigated these forms of comfort. For instance, I now much more rarely use the word "trashy" for a certain genre of fiction; just as Disneyland takes a hell of a lot of engineering, fiction that conveys engaging characters and a diverting plot through accessible prose takes quite a lot of craft. And besides, what I'm feeling isn't guilt anyway; guilt is about what you've done. Shame is about what you are.
I can see that it helps me to use Beeminder and LeechBlock, to exercise, to pray, to make people laugh, to see live music. So why the sense of shame? I think it's because if I like or need those things, then I am not entirely autonomous, I am not entirely self-disciplined, I am not a brain in a jar. My body needs things, my sociability needs to be fed, my focus and persistence need assistance. The analysis presented by the social model of disability holds true here; I get the message that the way I am is wrong, but when I stop accepting that assumption and start systematically asking "why?", I figure out that it's because there's an assumption in my head that I should be as efficient and autarkic as a space probe.
So perhaps, along with "trashy", I should watch out for places in my internal narrative where "need" and "weak" and "strong" show up. Because yes, I need, and maybe needing feels weak, but if I recognize that need and then take care of it, aren't I strong as well?
I'm also disentangling my intuitions about care and power. I am the one setting up these habits, these guardrails, and I'm doing it as self-love, not as self-punishment or as a power play against another faction of myself. My mindfulness meditation practice has been reminding me to be less clingy about what I think my identity is, and Emily Nagoski's excellent Come as You Are: The Surprising New Science that Will Transform Your Sex Life suggests it's helpful to think of one's self as a swarm or constellation. This approach helps me get less hierarchical about all the varying bits of me. So instead of rebelling, I can say "argh" and then say to myself "yeah I know" and then breathe and do the process anyway.
And I can see how I need to show myself self-love via accommodation. I am like both the builder of the building and the person with accessibility needs who needs to use that building. Wouldn't I want some other builder to build hospitably, and wouldn't I want other building users to joyfully make full use of the accommodation available?
And that loving approach, plus seeing my past successes, makes it easier for me to work the way that works for me. Timers, minigoals, setting up mise-en-place ahead of time. The timers and minigoals don't have to be optimal, just right enough to get me in the right neighborhood, then iterate from there. I can have patience and trust the process.
Perhaps the biggest change, the biggest unmooring, is to my identity. I was always behind on correspondence, always surrounded by clutter, fairly sedentary, and I had not realized how these formed part of the furniture of my mind until I started dismantling them. I am curious what the new configuration will be, and whether it will have a chance to consolidate before another set of changes begins.
Thanks to my friend J. and my friend and meditation teacher Emily Herzlin for conversations that led to this post.
# 10 Aug 2016, 10:17AM: Grief:
It's been a tough week. Wednesday of last week, I learned that Kevin Gorman had died. He was only 24 years old. I met Kevin through my work at the Wikimedia Foundation. He was a feminist activist who put a tremendous amount of energy into making Wikipedia a better resource for everyone. He added and improved articles, and he taught others, and he took on the emotional work of moderating and responding to voices that were arguing against feminists, and of fighting harassment (in all his communities). As he said on his user profile:
I dislike systemic biases; both those caused by our gender, racial, and geographic biases, and those caused by no abstract available bias and its kindred. One of my stronger interests on Wikipedia is making available online in a freely available format content that cannot be currently be found on the Wikimedia projects because of our systemic biases. I think that this is some of the most important work that can be done on Wikipedia at this time.
I had known that he'd been fighting various illnesses for some time, but I was still shocked to hear of Kevin's death; he was far too young. My condolences to his family and his friends and his many collaborators in free knowledge and justice. Kevin and I didn't have that many conversations but in every one I heard his deep passion for the work of improving our culture on all levels; he never ceased to be shocked at things that aren't right, and to channel that shock into activism and organizing. I will miss his dedication and I will remember his ideals.
He was only 24. As I handle more and more death I come to learn which deaths cause more painful griefs. I seem to believe, somewhere deep inside, that people younger than me really shouldn't die, that it breaks an axiom.
And then the next day I learned that Chip Deubner had died. Further shock and grief. I met Chip because we worked together at the Wikimedia Foundation; he was a desktop support technician, and the creator and maintainer of the audiovisual recording and conference systems, and then rose to manage others. And I can attest to his work ethic -- he cared about the reliability of the tools that his colleagues used to do their work, and he was that reliable himself, ready at a moment's notice to take on new challenges. He demonstrated a distinctive combination of efficiency and patience: help from Chip was fast, accurate, effective, and judgment-free. If anything, he was too reticent to speak up about his own frustrations. I was glad to see him grow professionally, to take on new responsibility and manage others, and I'm glad he was able to touch so many lives in his time on earth -- I only had a few memorable conversations with him, since he lived in the Bay Area and I mostly telecommuted from New York, but I know he enjoyed office karaoke and that many WMF folks counted him as a friend, and grieve him as one. He was a maintainer and a keeper and a maker of things, in a world that needs more such people. He will be in my thoughts and my prayers. (I wrote much of this in a guestbook that might decay off the web, so I'm publishing the words here too.)
Chip died of a brain tumor. He knew he was dying, months before, so he left his job and went back to his family home in Missouri to die. He died on July 9th. And I didn't know, and didn't have a chance to say goodbye, and I suspect this is because I am not on Facebook. Thus, for the first time, I am seriously considering joining Facebook.
Sometimes, in the stupor of grief, I find comfort in doing certain kinds of work -- repetitive, well-specified, medium-cognition work without much call for self-expression. So the article about Hari Kondabolu on English Wikipedia is a lot better now. I took it from 22 citations to 78, found an openly licensed photo to use, and even created the stub of a Telugu Wikipedia page. My thanks to the makers and maintainers of Citoid and the VisualEditor -- with these tools, it is a positive delight to improve articles, a far better experience than in 2011.
Hari Kondabolu turns his anger into comedy. I turn my grief into Wikipedia edits. We all paint with our pain. If we do it right and we're lucky, the stuff we make helps, even if it's just two inches' worth of help, even if it just helps ourselves.