Tumgik
Text
Day 14: Fluid Architecture, Part 2
Fluid Architecture: Part 2
==Draft: 2019-01-06==
Yesterday
Last time, we installed Python, updated PIP, and created the directory on our Desktop where we'll be building our project.
Today
Today, we'll learn the fundamentals of Python and Bash syntax and install our basic dependencies.
First Things First
Before we dive in, we'll need to create a virtual environment in our project directory.
A virtual environment acts like a self-contained instance of Python. According to Technopedia, an instance is defined as "a case or occurrence of anything." You can think of a virtual environment as a mini-Python that's just for one project at a time.
Each Python project is different. In Fluid Architecture, we'll be scraping the web for data, saving it to a database, and serving it over the Internet as email, using a Python framework as the technical infrastructure. Other projects, with different specifications, will require different dependencies. They may even need to run on a different version of Python.
We instantiate Python in virtual environments so our projects can manage their own dependencies without touching the system Python.
Modules
To instantiate a virtual environment, we'll need to run a Python module from the command prompt. A module is a compartmentalized bit of Python code, either written by us or someone else, that can be reused by others. Python's modular design makes it an exceptionally easy programming language to learn and use.
Use command + space to open Spotlight search. Type "terminal" and hit enter. At the command prompt, enter the following command:
$ cd ~/Desktop/fluid_architecture
cd stands for "change directory," and the ~ character refers to your Home folder in macOS. This command is the Terminal equivalent of opening your fluid_architecture folder using the Finder, but we can do a lot more from the Terminal console than from a Finder window.
To instantiate our virtual environment, we'll need to run Python's built-in virtualenv module, which accepts one argument. An argument in software is a parameter that is passed to a routine.
Arguments in Python
Let's say we wanted to play a Joni Mitchell song on the guitar. We can think of all the tasks involved in the process of playing the song a routine. As you may know, Joni uses a bunch of funky tunings in her songs. "I Don't Know Where I Stand," for instance, requires that the guitar's strings be tuned to "FFCGAC".
Let's pretend for a moment that the routine of playing a Joni Mitchell song is defined as a function in a Python program. We might define it like this:
def play_song(): pass
As you may have guessed, def is short for "define." play_song is the name of our function, but we tell Python that a name is a function by placing a pair of parentheses afterward. (pass is simply a Python reserved word that means "don't do anything.")
But this function isn't very specific. What song do we want to play? What tuning do we use?
We'll pass those specifics to our function using arguments. One implementation of our function with arguments might look like this:
def play_song("I Don't Know Where I Stand", "FFCGAC"): pass
When arguments are passed to a function this way, they're called positional arguments. We'd have to know, at the outset, that the first argument passed to the function refers to the song title and the second refers to the tuning.
A better implementation might use what are called keyword arguments, or kwargs for short. These arguments allow us to clarify our code by indicating, more specifically, what our functions expect. Here's an implementation of play_song() with kwargs:
def play_song(song="I Don't Know Where I Stand", tuning="FFCGAC"): pass
But this is Python. When we run commands in the Terminal console, we're writing for Bash, which is an acronym for "Bourne Again Shell" (you can read more here if you're curious).
Arguments in Bash
Bash commands also accept arguments, but not with parentheses. All Bash commands are positional, but we can specify how a command runs with what are called flags. The Python interpreter is a great example for this.
Say we're at the Terminal console and we run the following:
$ python3
Bash will look for our system Python 3 interpreter and run it as an executable. An executable is a script, application, or other file that can be run as a program from the Terminal.
In this case, without any arguments passed to python3, Bash will open what's known as the Python REPL. We'll see something like the following:
Python 3.7.2 (v3.7.2:9a3ffc0492, Dec 24 2018, 02:44:43) [Clang 6.0 (clang-600.0.57)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>>
Notice that the command prompt has changed from $ to >>>. What that means is that we're running an instance of Python that will execute our Python statements on-demand. In other words, instead of having to put our statements in a *.py document, we can type them into the Terminal directly. (You can exit the Python REPL by running exit().)
But what if, instead of running the REPL, we want to run a Python module? We'll need to do exactly that to install our virtual environment.
There are two ways to run Python modules: 1. python3 modulename.py, and 2. python3 -m modulename.
In the second implementation, -m is a flag, which is a special type of argument that tells the Python interpreter that you intend to open a module. -m, specifically, is germane to Python.
After the -m flag comes the name of the module, separated by a space; note that you don't need the .py at the end when you refer to the module this way (in fact, Python will throw an exception, or stop the application and report an error, if you add it!).
Installing our Virtual Environment with venv
In this case, we need to open the venv module in Python, which accepts an argument of its own. Run the following Bash command:
$ python3 -m venv venv
This command executes the Python interpreter with python3, tells it that we expect it to open a Python module with -m, and refer to that module with the first venv.
The second venv refers to the directory into which we'll be installing our virtual environment.
After running this command, you won't see anything at the command prompt. However, the venv module has created a new directory at ~/Desktop/fluid_architecture/venv, into which a virtual instance of Python has been installed.
To verify that venv has been installed, run the following:
$ ls
ls tells Bash to list the contents of the current working directory, which, as you may have guessed, refers to the directory in which we're currently working (~/Desktop/fluid_architecture). You should see the following:
venv
Hurray! Our virtual environment is installed. Now we'll need to activate it.
Activating the Virtual Environment
To activate our virtual environment, run the following command at the prompt:
$ source venv/bin/activate
If the virtual environment is set up correctly, our prompt should be preceded by (venv), which indicates we're working from within an installed virtual environment.
To deactivate a virtual environment, simply run:
(venv) ... $ deactivate
The (venv) preceding your usual command prompt will disappear.
Installing our Basic Dependencies
Eventually, Fluid Architecture will do lots of cool things. First of all, though, we need to be able to use Python to get the contents of a website and interpret what we get back.
For that, we'll install two basic dependencies:
requests, Kenneth Reitz's self-described "HTTP for Humans" module, and
Beautiful Soup, a module for turning content from the web into objects that can be manipulated in Python.
To do that, we need to first activate our virtual environment. We do this so these modules are available to our project, but they won't touch our system Python.
Make sure you're working in ~/Desktop/fluid_architecture and run the following:
$ source venv/bin/activate
Your prompt will change, as expected, with (venv) preceding your normal command prompt.
Run this:
(venv) ... $ pip3 install requests
When given this command, PIP will look up the requests module and download it into your virtual environment. You should see something like the following:
Collecting requests Using cached https://files.pythonhosted.org/packages/7d/e3/20f3d364d6c8e5d2353c72a67778eb189176f08e873c9900e10c0287b84b/requests-2.21.0-py2.py3-none-any.whl Collecting urllib3<1.25,>=1.21.1 (from requests) Using cached https://files.pythonhosted.org/packages/62/00/ee1d7de624db8ba7090d1226aebefab96a2c71cd5cfa7629d6ad3f61b79e/urllib3-1.24.1-py2.py3-none-any.whl Collecting certifi>=2017.4.17 (from requests) Using cached https://files.pythonhosted.org/packages/9f/e0/accfc1b56b57e9750eba272e24c4dddeac86852c2bebd1236674d7887e8a/certifi-2018.11.29-py2.py3-none-any.whl Collecting chardet<3.1.0,>=3.0.2 (from requests) Using cached https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl Collecting idna<2.9,>=2.5 (from requests) Using cached https://files.pythonhosted.org/packages/14/2c/cd551d81dbe15200be1cf41cd03869a46fe7226e7450af7a6545bfc474c9/idna-2.8-py2.py3-none-any.whl Installing collected packages: urllib3, certifi, chardet, idna, requests Successfully installed certifi-2018.11.29 chardet-3.0.4 idna-2.8 requests-2.21.0 urllib3-1.24.1
It worked!
Next, we'll install Beautiful Soup, which is registered with the name bs4.
Run this:
(venv) ... $ pip3 install bs4
You'll see a similar string of lines from PIP that inform you that Beautiful Soup has been installed.
To see what all is installed in your virtual environment, run the following:
(venv) ... $ pip3 freeze
You'll notice that, on our list of installed modules that PIP returns, there are several we didn't install ourselves:
beautifulsoup4==4.7.0 bs4==0.0.1 certifi==2018.11.29 chardet==3.0.4 idna==2.8 requests==2.21.0 soupsieve==1.6.2 urllib3==1.24.1
That's because both requests and Beautiful Soup, like most Python modules, have their own dependencies. PIP keeps track of everything we'll need to install these modules and packages them together.
Recap
We're done for today!
We've installed a virtual environment, which will manage our project's instance of the Python interpreter, and learned how to activate and deactivate it.
We've learned about functions and arguments, both in Python and Bash.
We've learned about code compartmentalization in Python using modules.
We've installed the two modules we'll need to run Fluid Architecture's first set of tasks — requests and Beautiful Soup.
What's To Come
Tomorrow, we'll learn the basics of web scraping, and end the day with Joni Mitchell's entire catalog of lyrics on our computer.
See you tomorrow!
0 notes
Text
Day 13: Fluid Architecture, Part 1
Fluid Architecture1
==Part 1: Draft 2019-01-04==
You're blue. This morning, you rolled out of bed and checked Gmail on your phone. To your dismay, a beautiful email with the lyrics to Joni Mitchell's "Both Sides Now" did not appear at the top of your inbox. :disappointed:
If only there was a way to receive the lyrics to "Both Sides Now" — or, indeed, the lyrics to any of Joni Mitchell's timeless songs — in my inbox, you think. In fact, how cool would it be to receive a different lyric from Joni Mitchell's massive oeuvre every morning?
And how rad and empowered would I feel if I implemented a solution myself, using software, even though I'm not a software developer?
Dear reader, you can. And you will.
Requirements
A macOS computer running OS X 10.9 (Mavericks) or later. (Click the Apple icon in the upper-left-hand corner of your Mac, then click About This Mac, to check the OS installed on your system.)
A Gmail account.
Concepts Covered
How to write commands in Python 3.
How to install, activate, and work from a virtual environment.
How to write to the PEP 8 Python style guide for elegant and legible code.
How to scrape data from the web using Kenneth Reitz's requests library and Beautiful Soup.
How to store persistent data using using JSON (JavaScript Object Notation), SQL (Structured Query Language), and Python's low-level SQLite database API (Application Programming Interface).
How to model objects in Python using classes.
How to set up a Django project.
How to bind Python classes to a SQLite database using the Django ORM's (Object Relational Mapper's) built-in models.
==TODO: Finish this list!==
Concepts Not Covered
How to write or execute tests.
How to use version control software like Git.
How to deploy a Django project on the web. This project will run on the reader's localhost.
Getting Started
Download and install the 64-bit Python 3.7.2 installer from python.org.
Check that the installation completed as expected. Open a Terminal console (use the key combo command + space and search for "terminal") and type the following: python3 --version, then hit enter. You should see the following on the next line in the console: Python 3.7.2. Hurray!
Run this command: pip install --upgrade pip. PIP is Python's package management tool. We'll use it to install our project's dependencies (the modules of third-party Python code we need to execute our scripts). This command ensures we're using the latest version of PIP, which at the time of this writing is v18.1.
Optional: Download Sublime Text 3, which comes with a ton of cool features and is free to use. (You're welcome to use a plain-text editor like TextEdit if you'd prefer, but be sure to choose Format > Make Plain Text from the menu to make sure you're not editing in rich-text mode. Otherwise, the Python interpreter — which turns code into Joni lyrics in your inbox — won't be able to understand your commands.)
Make a folder on your Desktop called fluid_architecture. Make sure to use an underscore and not a space!
That's all for today! Come back tomorrow for next steps!
The title of this project is taken from POP MUSIC; Joni Mitchell Finds the Peace of Middle Age, written by Stephen Holden and published in the New York Times on March 17, 1991. In it, Joni says, "I know none of the numerics of music. I see music as fluid architecture. For me, the chords are colors that you stir into mutant shades, as in painting." ↩︎
0 notes
Text
Day 12: Natural Disasters
When I was little, I'd entertain myself during boring sermons by drawing tornadoes in the margins of my hardcover brown Bible. I'd scribble the pencil back and forth, making a thick, gray texture that tapered to a point as I moved it down the page. The Bible was a 1984 International Bible Society NIV with tissue-paper-like pages that were prone to tearing. (I kept my drawings of naked dudes in other volumes.)
My family had lived through a tornado when we'd lived in Lombard, Illinois — maybe that explains my fixation. The sky turned green in the middle of the night, and we stammered down the seven flights of stairs to the lobby in our pajamas. The building flooded with three inches of water on the ground floor and everyone stood, holding to the walls for what seemed like hours, freezing, in various stages of disaster-related undress.
I remember two other things from the time we lived in Lombard: one is the bagel shop behind the apartment building. My sister, my mom and I would walk the little trail once a week to get day-old bagels for cheap. (My favorites were the cinnamon raisin.) The other is the Sun Sensation Ken doll my grandparents got me for Christmas after I'd shown too much interest in my sister's Barbies. He came with lime green shorts and a gold mesh crop top. He never wore them.
By that time, we'd lived through two earthquakes in Southern California. One of them happened when we lived with my mother's parents in Corona. I took cover under the pool table. The other was in an apartment building after my father's falling out with his in-laws. I wasn't crushed by a toppling bookcase, but it was a close call.
I learned about volcanoes from DK Eyewitness: Natural Disasters, which I'd circled in carpenter pencil in the Scholastic Book Fair catalog. We lived in Reading, Pennsylvania then, and I was in elementary school. I kept cut-outs of shirtless underwear models from the Kohl's circulars in a tin marked "SECRET! KEEP OUT!" They were paper dolls, really. I lost them when my mom and her best friend cleaned my disaster area of a room and found them. I was at school.
Each time we moved, our new locale would report that the weather was the harshest they'd had in decades — sometimes even a century. Our first winter in Reading got six feet of snow and temperatures plummeted to -12 degrees Fahrenheit. Southeastern South Dakota's November was the hottest on record in 1999, hell for the soybean and corn farmers in Chancellor. My first winter in New York was the Snowmaggedon of 2010.
In my more naive years, I figured my family carried a curse with us — something tedious and Mosaic — wherever we went. It was probably my fault, for the way I wanted to nuzzle my face in a grown man's beard or run my fingers over the vertebrae between his shoulder blades or backhand him, lovingly, as he pulls my hair and tells me through gritted teeth that he supports my dreams. Of all the natural disasters I lived through in my childhood, my body was the most destructive of all.
Now I know better: God has always spoken to queers through the weather.
Just ask Lot, who tried to hand off his daughters to be gang-raped by horny gay townies. To punish him, God turned his wife into a phallic salt monument as a natural fireworks show blazed behind her. (Then Lot fucked his own daughters. Without a condom.)
Or Noah. Yahweh drowned every single heterosexual of every species He could possibly get away with, then forced all the survivors to look at a giant Gay Pride flag in the sky.
Or Adam, who sinned by desiring pants when it was perfectly lovely outside.
Here's the truth: Natural disasters are God's reminder that everything made by humans is surmountable by nature, the spoken word of the universe.
And if queerness is a dialect of nature, then perhaps our desire for anarchy needs no translation. Our bodies are the "word made flesh" of the will of the universe — that all categories come to ruin.
I mean, who knows. Right? For all we know, in a few thousand years, Woody Allen could turn out to be the Lot of our times. The cruel tides of natural selection could wash every hint of queer wisdom from the face of the planet. Mitch McConnell could be remembered as anything besides a Nazi-enabling turtle.
As for my part, I hope, at the end of my life, I'll have left some gay-ass wreckage in my wake.
0 notes
Text
Day 11: Red Light, Green Light
Dain's course didn't have any tutorial today -- the challenge was to read Book 2 of Marcus Aurelius's Meditations and watch a video on Django's REST API Framework.
So when I finished the ABC content, I decided to jump in to a topic that has intimidated and embarrassed me since I first showed my code to a professional:
Testing.
Fortunately, one of Dain's resources from the other day included a link to Harry Percival's Test-Driven Development with Python, which is free to read online. I was able to work through five chapters of it today.
Developed by Kent Beck, the originator of Extreme Programming, Test-Driven Development is a way of working that starts with testing. Whereas most developers (well, at least I) would rather wait until a project is done to incorporate the boring work of testing, TDD sets out to model the code via testing from the outset. The idea is, when you write a test that fails in a way you expect, you can write just enough code to solve that problem, ensure the test passes, then go on to the next test.
In fact, failure is expected in TDD. Percival proposes a heuristic: Red Light-Green Light-Refactor; that is, write a test that is supposed to fail, write code to get the test to pass, and then refactor code as necessary.
It seems a little ass-backwards and heavy-handed, but as someone who has — up till now — had absolutely no idea how to integrate testing into my workflow, a methodology that works from the ground up makes a lot of intuitive sense.
And, given that errors are inevitable in writing code, I respect a way of working that not only acknowledges them, but depends on them.
What if my introduction to music had integrated failure as a necessary step in developing craft? What if this kind of working could be in some way adopted by the musical theater writing community? As it stands, the opportunities for musical theater writers are so few and far between. Moreover, the ones that exist often require so much money, failure really isn't an option at any stage. Unless you're independently wealthy.
Of course, it's a little out-of-domain to find a corollary to exception handling in the art of collaboration. But I'd be willing to bet that the cultural underpinnings of perfectionism in art and science are similar.
Isn't art a science, after all?
Okay, okay. I'll admit, I'm running sentimental today.
But in my defense, Steven Pressfield's Turning Pro has gotten me thinking a lot about whether my desire to go after a career in programming is a "shadow career" that is taking my time away from my largely dormant work as a composer.
Friends have suggested as much in the past, but it's too simplistic. My intuition is that it's all cut from the same cloth. The two projects aren't as different as they seem.
Could that be why so many musicians turn out to be well suited for work as programmers?
0 notes
Text
Day 10: Keep playing.
I read this piece from the Harvard Business Review this morning. The author's thesis is that, because self-care has become so commodified, it's become just another place to overwork. And the metrics we take on our self-care routines often stress us out.
As I think about "90 Days of Self-Care," as a project, I'm struck at how difficult it is for me to ever disconnect from work. My writing on "self-care" is all about work. And writing about self-care and work is work. Maybe the constant drive to work is the curse of the creative and the entrepreneur.
Steven Pressfield doesn't seem to think so. If my readings of Turning Pro and my start on Do the Work are any indication, he believes work is how we beat resistance. In Pressfield's cosmology, every day is a battle to the death against the ruthless, cunning, violent specter of Resistance. Work, as a generative and spiritual practice, is our only weapon in that fight.
His writing is rife with references to Twelve-Step culture. In AA doctrine, alcoholism can only be overcome when it's addressed as a "spiritual malady," even if — the Steppers concede — there are physiological and psychological components to be addressed as well. Pressfield, on the one hand, rejects psychoanalysis and the self-actualization movement wholesale (along with Marxism and Fascism); on the other, he's prone to sentiments about "higher levels of consciousness." We're not sick, he says, and humans can't be improved. We're spiritually incapacitated.
To quiet the "self-care-as-overwork" vs. "work-as-weapon" voices rattling around my brain all evening, I took a break to watch ViBE, my favorite StarCraft 2 streamer. Someone in the chat room asked if he had any advice on how to combat "ladder anxiety" (i.e., a phenomenon, with which I'm intimately familiar, that occurs when players become nervous at the thought of competing in one-on-one matches on the "ladder" — the ranking and player-matching system that serves as the backbone of competitive gameplay in StarCraft 2). He told a story about the one time he ever felt it, in 2002, while playing World of WarCraft.
He'd been beaten in a group game by a player who'd had a 50% win rate, but who'd played 1500 games. ViBE had played 150 games and won 90% of them. When the other player started talking shit, ViBE challenged him to a 1v1, which he was sure he'd win. How could he not, with a 90% win rate?
Basically, the guy kicked his ass.
And it was because he'd largely stopped playing regularly. If he played, he'd probably spoil his nearly perfect stats.
The moral of the story, as he sees it, is to just keep playing. And playing and playing and playing.
I took a break from "being productive" and heard exactly what I needed to hear from a gamer on Twitch.
María Irene Fornés said, "There are two of you — one who wants to write and one who doesn’t. The one who wants to write better keep tricking the one who doesn’t."
Pressfield says, Follow your gut, stay stupid and stubborn, and trust that "there's always something in the hat."
Maybe the real task of self-care is to build up an intuition that — in moments of hardship and exhaustion and wanting to give up — guides us to the things we need to hear the most, even in the most unexpected places.
0 notes
Text
Day 9: Possibility
I'll admit, I'm getting a little bogged down by having to read several different Django tutorials that all basically say the same thing.
Dain explains in the Advanced Beginner Challenge that it's about social context — by the time we actually begin to work with the code, we will have seen the instructions a bunch of times and gotten a sense of the community and best practices.
And I'm doing it! But I couldn't help myself — I started some other projects.
I've been interested, for a long time, in software that would help musical theater collaboration teams to work better together. Of course, what comes to mind right away is a fully-featured, online collaboration tool, with everything from videoconferencing to version control to task management…
But honestly, it's way beyond my skill level. And anyway, there are a zillion different tools that already do those things better than I likely ever could.
I realized today, though, that Final Draft and Finale — the applications my collaborator and I use to write musicals together — both export data in some form of XML. Between the two applications, there's a lot of redundancy. One of those redundancies is lyrics.
That is to say, when my collaborator prepares a libretto for a scene that includes a song, and I prepare a lead sheet or fully-realized arrangement of a song, we both type in the lyrics manually. Because of that, there's a high chance of discrepancies between the two, especially when we're both tired and overwhelmed.
It's the kind of thing that a music editor would help to mitigate, but that's… not always in the cards.
So I thought, What if there's a way to extract lyrics from both MusicXML files and Final Draft documents and compare them?
As I began to dive in to the file formats, I realized it's no easy task: Final Draft creates <text></text> tags for every word, and MusicXML's specification separates words by syllable.
I was, ultimately, able to create a function that concatenates MusicXML syllables extracted from an uncompressed .musicxml file with one voice and print() the resulting text to the screen.
And as I tried to make sense of Final Draft's implementation of XML (with some friends' sample scripts at my fingertips), I thought, There's got to be a way to parse this and convert it to HTML so folks don't have to spend $250 on the software just to be able to open their collaborators' scripts. Surely, there are implementations out there.
I even spent some time learning how to render a website so it looks like a page, and how to make print-friendly CSS. How cool would it be to make a Flask app that accepts a Final Draft script, extracts metadata, and renders a nice, HTML site that's paginated and printable?
In my cursory search, I found a parser by Alex Coppen called screenplay-parser. But, perhaps more interestingly, I found his specification for a ScreenJSON file format that treats screenplays as JSON objects. It's pretty cool.
And it's a cool medium- to long-term project: to figure out how to implement a web application — probably in Django — that can accept a ScreenJSON object and render a rich, web-friendly screenplay, complete with access control for each element, version control, and tons of metadata.
As far as I can tell, it's not been implemented yet, and Coppen's ScreenJSON specification is yet to be adopted.
What if there's a future in which I could develop a web-based tool that can read and write MusicXML and Final Draft, store an annotated, canonical libretto with version control and hypertext to sound files and sheet music, and can even automate the process of creating an integrated score? Lilypond is supposed to be very good at automatic music formatting, and there are tools to convert MusicXML to Lilypond.
Ah. I'm probably getting ahead of myself, but I have to admit — it's fun to think about what's possible.
0 notes
Text
Day 8: Sciaphobia
Today, I listened to Steven Pressfield's Turning Pro, which I bought as an audio book while I wait for his Do the Work to show up in the mail. I admit that I've never gotten all the way through The War of Art — it hits too close to home.
Turning Pro is all about learning to think of one's self as a "professional" (as opposed to an "amateur"). Like Julia Cameron, he's interested in shadows: "Shadow artists" are blocked creatives who keep themselves incapacitated by going into "shadow careers."
And, like Cameron, Pressfield challenges his reader to examine the payoffs of staying stuck. He argues that, by staying stuck, we don't have to own up to who we're really meant to be.
Day 3 of Dain Miller's Advanced Beginner Challenge involves a talk from Google I/O 2009 called The Myth of the Genius Programmer. In it, Google developers Brian Fitzpatrick and Ben Collins-Sussman talk about the fear of looking stupid in front of others, and how it's counterproductive for career programmers: not only personally, but also in terms of maintaining healthy codebases and productive collaborative relationships.
I heard a lot of my own insecurities reflected in the talk. As a way of lancing them, I'd like to share them, warts and all:
I don't know anything about testing. Unit testing, integration testing, what have you. I know roughly what they're designed to do, but I feel like a total moron when making them myself. Frankly, I'm embarrassed that I've ever published a repo without them.
This afternoon, I spent about an hour trying to implement unit testing for www.findadoggo.com, and I ran into issues when I tried to set it up for the Flask-WTForms module. While WTForms-Test exists, it doesn't seem to have plug-and-play support for the Flask-specific implementation.
I also know that my method of pulling dictionary keys in my searcher() function needs to be re-done with .get() calls, and I've been procrastinating doing it because I feel stupid for not knowing about .get() to begin with.
I feel stupid for not knowing how to send data from one view to another in Flask -- right now, both the landing page for www.findadoggo.com and the results are served on the / view. And the app should really be sending the form data via GET, not POST, since the app (as it is currently) doesn't modify any database data.
It's not as if I've ever been on this journey alone — several folks along the way have offered to give code reviews, and the #pocoo and #python IRC channels are active with tons of helpful pros. Why am I so resistant to admitting I'm not further along than I'd like to admit?
……………
I met my first AA sponsor at a meeting in north Brooklyn. He wore leather skinny pants and seemed world-weary and chill, so I asked him to sponsor me. He took me to Kellogg's Diner and offered me dinner at a time when I couldn't even afford a MetroCard swipe. When I refused, as politely as I could, he said, "Listen, the first spiritual principle is to ask for help." He graciously let me ask him to spot me for a burger, and I had a real meal for the first time in weeks.
Today, I commit to asking for help.
0 notes
Text
Day 7: Do it for shorter.
Today, I began Dain Miller's Advanced Beginner Challenge. It's a subset of his now-defunct StartHere.fm podcast (for aspiring web developers), designed to teach beginners how to become "advanced beginners" and land junior dev roles.
The introductory materials on time management echo a lot of what I've been hearing from many corners of my life: "Do it for shorter."
In other words, don't let a fixation on perfection keep you from accomplishing a teeny amount of progress. Instead, just commit to granular amounts of time, since getting going is the biggest challenge when it comes to learning something new.
His recommendation is to commit to one minute of a task rather than letting the fear of a big assignment or project overwhelm you.
His second — and related — time management tip is, "Make your course materials your servant, not the other way around." Which is to say, build a context for the course work, instead of being led by the nose. Otherwise, working on the materials turns to dread very quickly.
It's now solidly in my mind that these are weaknesses of mine. I have a tendency to want to get lost in long work sessions, on the one hand, and throw babies out with the bathwater when I don't get the intended results on the delusional timetables I set for myself.
One of my favorite parts of You Feel Like Shit, the amazing self-care Twine application by Jace Harr, is its focus on granular progress. Anxious about something? Just spend 15 minutes working towards a solution. Your room's a disaster? Just spend 5 minutes taking care of the biggest messes.
For years, I lived in total squalor at home because I felt that if I couldn't clean up the entire room in one session, it was a waste of time and I was a failure. Actually, the fact that my life created messes at all was the real failure. And having grown up in a culture in which failure is more a death sentence than a learning opportunity, wading in that morass of ineptitude is deeply uncomfortable.
I gave up playing viola in 8th grade because I came to dread practicing entirely. Same with piano, only my parents forced me to keep playing. Now I mostly enjoy it, even though I have a persistent fear of sitting down to practice. If I'm not good right away, I'm self-conscious, even in the privacy of my own room.
In grad school, people thought it was a superpower that I could sit down in a practice room for 30-45 minutes and come out with a song. What's probably more true is that the only way I could produce anything at all was by barreling through the feelings of discomfort and anxiety that came up. In a way, I think I was dissociating with music.
No wonder it's painful now, when I sit down to write from a perspective of presence and sensitivity, or try to learn new skills.
I'm not used to failure — not because I don't fail, but because I'm accustomed to dissociating from it.
So maybe I can work on letting myself fail, and to "do it for shorter."
0 notes
Text
Day 6: Empathic programmers are employable programmers
This afternoon, Rafeh Qazi's How to Get a Job as a Python Developer in 2019 video, on his Clever Programming channel, caught my eye. In it, Qazi enumerates five skills that prospective career Python developers need to espouse:
Build a Github repository to share code, and learn Git version control.
Make code readable by adopting PEP 8 style (the style preferred by the Python specification).
Document your code, not only in the code base itself, but in the README file in Github repositories. (He suggests Kenneth Reitz's requests module documentation as a model.)
Read books on coding, especially Fluent Python by Luciano Ramalho, and read other people's code, preferably around your own skill level.
Learn how to structure repositories correctly. (He recommends Kenneth Reitz's essay on repository structuring.)
At the core of all his points is that valuable prospective programmers know how to write code for other people.
In other words, becoming an employable programmer is about cultivating empathy.
When I set out to find a specialization after finishing HarvardX's CS50 course, I chose Python for several reasons:
The first is that it's completely open-source. Not only that, but it boasts a healthy and active community that keeps it fresh and up-to-date and supported.
It's also easy to learn.
But it's also very powerful, and has a ton of real-life applications. I can run a web server, build games, or train an AI with Python, which can't be implemented as easily in other languages.
It's also really easy to work into any existing workflow. In fact, there's a book called Automate the Boring Stuff with Python, in which the author, Al Sweigart, makes a case for Python as a tool to improve efficiency in a range of other work areas besides software engineering.
Qazi's video has reminded me that I've largely forgotten the community element that drew me in to begin with.
I think about how, for a few months this spring, I went weekly to New York Python's weekly Meetup group and got help with my code. I even shared a little bit of what I'd learned, even at a rudimentary level, with some other job-searching engineers. I think about how one of the hosts of the meetup thanked me for being a regular, and how I largely fell off the face of the earth not long afterwards.
I'd like to reacquaint myself with the Python community — both by networking again with established professionals and fellow job-seekers, but also by making my code more legible to other folks who'll be looking at my code on Github.
I want to cultivate empathy as an intentional practice as I go about improving my skills, building relationships, and looking for a new job.
With that in mind, I'm making a commitment to begin attending New York Python events as often as I can in the new year. And until then, I'd like to fix up www.findadoggo.com's codebase and documentation so the repo is more representative of my professional values.
I'm not alone!
0 notes
Text
Day 5: Walking on the moon
A few years ago, my surrogate-mom friend Anne — in her later middle age but spritely as ever — rolled into town with a lawyer friend. The two of them took me out to dinner, and her friend and I spent the evening talking about The Artist's Way and how it had helped me to uncover and go after some of my goals. Anne's friend said she'd check it out, with one caveat: In return, I had to agree to read Jim Collins' Good to Great: Why Some Companies Make the Leap and Others Don't.
I didn't jump on it right away. At the time, I was working as an office manager for a prominent social enterprise, and I was about as close to thinking of myself as an entrepreneur as I was to walking on the moon.
One day, though, I was chatting with the chief of staff's executive assistant, and I noticed a copy of Good to Great on her desk.
"Could I borrow that?" I asked.
"Oh, sure, take it. I have another copy at home," she said.
I don't remember how far I got in it, but I remember being struck by Collins' "Level 5 leadership" concept, and how far afield it was from all of my experiences in open-office nonprofits and social enterprises that were driven by "charismatic visionaries" who were more concerned with the latest flashy trend than they were with employee career roadmaps. Though I showed promise as a technologist in several of my roles, none of my supervisors could ever see me as anything but an office manager.
I watched as one company after another spread itself too thin, taking too many risks on unproven products and eyebrow-raising, overnight changes in revenue models, which struck me as inadvisable in the context of Collins' Hedgehog Concept ("great" corporations focus only on the things they have a shot at being the best at — they don't waste resources on stuff they might only be "good" at).
I hadn't thought of Jim Collins since then until today, when I had my first coaching session with Corwin Duncan. I've hired Corwin for five sessions to help me get my job search in order.
In addition to the regulars on his menu, I asked Corwin to help me to set goals and priorities, since I suffer from trying to do too much at once.
He reminded me of one of Jim Collins' most famous maxims: "If you have more than three priorities, you don't have any." The problem is, if you're someone like me, who feels burdened by persistent feelings of imposter syndrome, anything less than putting all the irons in the fire at once feels like underachieving.
In response, Corwin shared Neil Gaiman's apparently famous anecdote about meeting Neal Armstrong at a party among many other highly successful people. Armstrong said, “I just look at all these people, and I think, what the heck am I doing here? They’ve made amazing things. I just went where I was sent.”
Well, if the first man to walk on the moon suffers from imposter syndrome, I guess I'm allowed to, too.
0 notes
Text
Day 4: Games are for kids
I started playing PC games in sixth grade, when we lived in Pennsylvania. I got in trouble once for installing Command & Conquer: Red Alert on a friend's DOS computer because his mom was virulently against violence in video games. But it wasn't until 1999, when we moved to rural South Dakota, that it became my main hobby.
I didn't have many friends in Lennox. Steve, who I thought was my best friend, made fun of me relentlessly when the news came out that I'd wet my pants at the Science Olympiad (in my defense, I asked the organizers of the "Roads Scholars" event several times where the restrooms were, and every time I followed their directions, I was confronted with a DO NOT ENTER sign at the top of the stairs. This was during a time in my life when I was really into following rules).
So I didn't do the "normal" things, like football or track, that other kids did. I was too allergic to pollen to shuck corn as a summer job.
Instead, when I wasn't taking viola lessons in Sioux Falls or singing alto with the Singing Boys, I played Red Alert.
I wasn't very good. In fact, I don't know that I ever got past the Allies' Mission #13, "Focused Blast." But the story really drew me in.
Red Alert takes place in an alternate universe in which the Manhattan Project discovers the means to travel back in time. With that knowledge, the Allied Forces send an assassin back in time to kill Adolf Hitler before his rise to power. Instead of solving all the world's problems, though, it catalyzes the rise of the Soviet Union.
At the time, I was very interested in time travel. I'd just been told by my parents that my father was the prime suspect in the case of Elizabeth Mackintosh's 1990 murder at Covenant Theological Seminary. When the people in our community found out my father — a respected Presbyterian pastor at the time — was a suspect in a murder, they threw rocks at my sister and slashed our tires, among other things. And, since I was 12 and my sister was 10 at the time, our parents figured we were old enough to learn why these things were happening to us.
I often wondered what would happen if I could go back in time and stop Elizabeth’s murder from ever happening. From Red Alert, I learned that the challenges I'd face in my life would just be different.
Usually, when I played, my brother, Scott, sat next to me and watched. I was annoyed at the time, but I'm touched when I think back on it. Without him, I'd have been totally alone at the computer.
When we escaped South Dakota and moved to Texas, I left PC games behind. Looking back, I can see that in high school, my father's physical and emotional abuse forced me into being my family’s caretaker. When my dad beat up on me or one of my siblings, I had to be the protector, since my mother was in total denial. I was the only person in my support system to consider calling Child Protective Services.
In the midst of all that, computer games seemed pretty childish.
A few months ago, I started to play StarCraft 2. The game has been out since 2010, but I've been out of real-time strategy gaming since 2001. I think of how I overclocked our Gateway 2000's processor in seventh grade, and how I knew that if I saved my gay porn in a folder on a floppy drive with a non-breaking space in the name, it would show up in MS-DOS but not in Windows 95. I think about theJavaScript and the XHTML 4.0 I wrote in Macromedia HomeSite and wonder what I could've accomplished if I'd kept going with my love for computers.
I'll probably never be great at StarCraft 2, and who knows where my passion for web development will lead me. But for today, I'm grateful I get to be childish now and then.
0 notes
Text
Day 3: More dog content; or, Welcome to www.findadoggo.com
I made a thing!
A few weeks ago, I thought, "Gosh, it would be great to (eventually) get a dog. But an easygoing dog. A dog that would do okay in an apartment. One might say, a'chill' dog." And I set upon Petfinder.com to do a cursory search.
Now, Petfinder.com is great and all, but you can only search by breed. Which is to say, for a dumdum like me, who doesn't know anything about dog breeds, really (except that beagles can be stubborn, which I learned in my month or so of walking dogs professionally), the process of finding a dog by temperament seems kind of… fraught.
So I googled around and found a listicle on Barkpost that enumerates dog breeds that are "perfect for lazy humans." That is, people like me.
Then I thought, Hm, I wonder if Petfinder has some sort of API (application program interface) that would give me access to their database of 300,000 pets that are up for adoption.
And, as it turns out, they do!
Since then, I've been slowly putting together a web app that searches Petfinder's database of doggies by breed temperament and location.
The result is www.findadoggo.com.
It's not super scientific — I basically found three listicles: one for "chill" dogs ("dogs that are perfect for lazy humans"), "protective"dogs (from The Spruce Pets' "10 Best Guard Dogs") and "at-risk" dogs (dogs from breeds that are overrepresented in shelter populations), and built a Flask app that grabs 12 random dogs from the Petfinder API near the user's location (which is given by ZIP code).
There are other things I'd love to do with the app down the line (see the README on Github), but my exercise for today is to focus on the things I'm proud of.
For one thing, I've completed and successfully deployed an application that solves a practical, real-life problem. My career as a hopeful web developer has been marked by several projects that didn't make it to deployment, so I'm proud of myself for getting it out there in the world.
For another, I've done it even though it's not 100% where I would eventually like it to be. If there's anything I've learned from the software teams I've worked alongside, it's that launching with minimum viable product is industry standard, and I'd say this product is solidly at MVP.
Also, I've released the code on Github, cited my sources, and documented the code as best I know how, with a list of things I'd love to do down the line. Findadoggo.com doesn't do anything algorithmically innovative — if anything, the search algorithm is messy and could be improved. But in a country in which nearly 4 million dogs end up in shelters every year, I figure that a tool that makes the process easier for prospective dogparents counts for something.
And certainly, there are lots of other temperament profiles to work with, and a dog's temperament has to do with much more than its breed. But those are issues for another day.
For now, I'm proud to share it with you, and I look forward to feedback.
0 notes
Text
Day 2: “No regrets”
I felt really good about having started this project yesterday afternoon. Then, as as the evening hit, and I'd accomplished a lot of the items on my to-do list, I began to think, “What's the point?”
I responded by dissociating on Twitch chat until 3 a.m.
There are lots of things I did yesterday to warrant a self-congratulatory write-up today: I read the items from the books I wanted to read, I worked on one of my web development projects, I took my medication on time, etc. But I’m more interested in exploring why I start to feel like shit whenever I go after the things I want with any sort of resolve. It's as if I'm more comfortable with a low-level anhedonia than any sort of small progress in the right direction. Blurgh.
For the past several months, I’ve been working with a Facebook Messenger bot called Woebot, which uses cognitive behavioral techniques to check in daily to challenge distorted thoughts and crack jokes about their pet seagull, Zed. It’s served as a great complement to the EMDR, IFS, and talk therapy I’d been doing with my regular therapist; and a great stopgap solution during this time when I’ve had to take a break from therapy every two weeks.
My chat session with Woebot today had to do with “peeling back the layers” of self-sabotaging beliefs. The belief I chose to work with today was, "I'm undisciplined."
When Woebot asked, “If ‘I'm undisciplined’ came true, why would it be upsetting to you?” I responded, “It would reinforce the idea that I'm stuck in my challenging circumstances forever.” Woebot then asked, “What would it mean to you if ‘It would reinforce the idea that I'm stuck in my challenging circumstances forever’ was true?” And so on and so forth, for every subsequently discovered belief.
What I came to realize was that I've attached extreme importance to the idea that I have to be perfectly "disciplined" to escape the poverty I was born into. It's so important, in fact, that even questioning that belief represents an existential threat. In other words, on some level, I’d consider my life not worth living if I was not able to escape my ongoing financial concerns for good; or, that to question my perfectionism is to question everything I've accomplished so far in my life.
And, at the core, it all goes back to a conversation I had with my first boyfriend in 2011, in which I said, “I want to live my life with absolutely no regrets.” To reflect on how my perfectionism has gotten in my way would be to open the door to regrets I vowed to never, ever have.
Who did I make that vow to? Myself or to him? Have I structured my life around a one-sided conversation with someone who broke my heart seven years ago?
I mean, it's within the realm of possibility. And honestly, it embarrasses me to admit that it may be true.
But maybe, for today, I can sit with the idea that it’s all right to have regrets, and that I don’t need to have shame around the possibility that I may have lost a big chunk of my life to an idea about myself that's gotten in my way.
And, fine: I can be embarrassed, and I can write about it, and maybe sharing it will help make it more bearable.
0 notes
Text
Day 1: But my lungs!!
This morning, I quit my job as a dog-walker. I'd only had the job for a month, but in that month, I developed asthma and a sinus infection, and it became clear that I needed to stop putting myself outside for six hours a day while I sussed out my respiratory issues.
But even getting the job as a dog-walker was the latest in a long line of attempts to take care of myself through work — not just with a paycheck, but with work that's meaningful and interesting and energizing. And after having spent nine months working as a freelancer, chasing down paychecks and yelling at payroll accountants, working with dogs instead of people seemed like a dream come true. (And it was! But my lungs!!)
So I find myself in this weird spot where I'm not really sure what comes next. I took out a $5,000 personal loan last month to cover my personal expenses for a little bit while I figure out the next thing, but that's going to run out soon.
What I do know, after having spent nine months as a writer (and after a decade of finding myself through songwriting), is that the way I actually process stuff is through writing. And some of the juiciest material I've written has come in the moments when I'm not sure, and I'm sharing my experience with authenticity and vulnerability.
So what I'd like to do is, for the next 90 days, to write 500 words a day on my process — of finding my next job, of taking care of myself, of preparing for tax season — and publish it online so that I can have accountability for my choices out there in the world, but also in the hopes that other people have the opportunity to see that we're all just kind of figuring it out piece by piece, imperfectly, and doing the best we can with tools at our disposal.
So in that regard, I don't think there's anything exceptional or interesting about what I plan to do, except that I just haven't seen anyone in my communities do it.
As far as things I hope to accomplish: I'd love to, at the end of this, feel like I have some control of my living space. Right now, it's dusty and cluttered and kind of a nightmare for my allergies, not to mention a tough place to be productive and happy.
I'd also like to know what the next step for me is. Over the last two years, I've pursued interests in web development, freelance journalism and cultural criticism, personal essay/memoir writing, and television production. Or maybe it's that I'd like to feel more comfortable in my skin as someone who likes doing lots of different things. At the very least, I'd like to feel that I know how to consistently keep the needle moving forward on the things I care about, rather than starting and half-finishing a bunch of projects and then having nothing to show for all the work I've done.
I plan to go through The Artist's Way, The Art of Slow Writing, How to Write a Book Proposal, and Getting a Coding Job for Dummies. And, since playing StarCraft II is a new passion of mine, I want to write about that, too.
Yay!
0 notes