python & pipenv & direnv

Install pipenv:
pip install --user pipenv

Create and enter project folder:
mkdir myproject
cd myproject


Install software for your project (while in project folder):
pipenv install django

Enter pipenv shell:
pipenv shell

(bonus points)

Install direnv:
sudo dnf install direnv

Automate entering the pipenv environment (while in project folder):
echo layout pipenv >> .envrc

Now every time you enter or exit the folder you enter the pipenv environment seamlessly. 🙂

Bonus Bonus…

Check out https://kellner.io/direnv.html for advice on how to setup the environment to display in the bash prompt.

Published
Categorized as code

@dicewarebot, the solution I needed that no one asked for

A number of years ago I was trying to learn python. Random numbers have always amused me (as I was recently reminded by a twitter nod to the weird usage of spreadsheets).

A user named @context_ing tweeted: “I love finding the ways in which people use spreadsheets. Personally, I use them for mostly budgeting, workout tracking and travel planning. Here’s a few in the wild I’ve found. Would love to see more! Please share if you’ve come across any or have any yourself.”

I felt compelled to reply with my own little story. “Reminds me of a decade old excel project. A playwriting book said something like “I guess it would be a play if you cut up words from a dictionary and pulled them out one-by-one, arranging them into lines of 10 words under character names, but it wouldn’t be a very good one.” So I took the entire public domain text of Oscar Wilde’s classic and had Excel recreate the play on every reopen of the file by randomly selecting words and character names I think using a vlookup and random. The result was interesting (and likely bad theatre).”

The text in question (blasted tweet limits!) was Oscar Wilde’s The Importance of Being Earnest. The resulting play was garbage, but that random interger generation was magical. When combined with other functions it really could do wonderful things for art.

Fast forward some (10?) years and I had a different problem to deal with: I needed to seamlessly transition all staff and clients from one grouping of technology services at one company to a different group of technology services at a new and different non-profit that was going to just continue doing basically the same work for basically the same people.

To remove almost all complexity from this story: I needed passwords; lots of random, unique, and strong passwords.

I once again turned to my friend the random number generator, but this time in python rather than excel. I coded up a script that would allow me to specify the number of words I wanted, unique separator I desired, and―importantly―how many of these unique passwords I wanted to be generated in one go.

I had the program roll digital dice and lookup words from the EFF’s Diceware password list and then spit them out. People would get their passwords and privately think I was just very adept at coming up with wacky sounding passwords, but I did not deserve this misconception as random integers were to blame for everything.

Eventually I thought it would be a good idea to create a sort of Public Service Announcement on the web about the odd truth that a list of words obtained by rolling dice really can be unique.

The end result is a Twitter bot and a Mastodon bot that very frequently tweet out unique passwords they’ve generated (though you probably shouldn’t use them). More people follow on Mastodon than Twitter, and Twitter relatively frequently blocks my bot’s tweets makes me unnecessarily prove that there’s a human behind the bot to get things going again (anyone at Twitter can explain this?).

At any rate, here’s some examples embedded below. Note that I also added the Harry Potter wordlist as well. There are others for your enjoyment on EFF’s site.

Lastly, there are infinitely better versions of this if you’re looking to generate a password. I’d recommend the much more easily installed passphraseme by Micah Lee.

At any rate, I hope you enjoyed my PSA.

pandas, COVID-19, and plotting

# Import Libraries
import pandas as pd
import matplotlib

# Magic Code for Inline Display
# in Jupyter Notebook (if you're using that)
%matplotlib inline

# Create Dataframe from tables at URL for Iowa COVID-19 Testing
url = 'https://covidtracking.com/data/state/iowa/#history'
df = pd.read_html(url)

# There are multiple tables on the page,
# and they are saved in a list.
# Choose the 2nd table and rename to 'df'
df = df[1]

# Set the type for the column 'Date' as a datetime type.
df['Date'] = pd.to_datetime(df['Date'])

# Set the newly typed "Date" column as the index.
df.index = df['Date']

# Create a new dataframe from the original with only
# the 'Pending','Negative', and 'Positive' columns
iowa_testing = df[['Pending','Negative','Positive']]

# Plot this new dataframe as a stacked bar graph 
# Invert the axis so time moves forward.
iowa_testing.plot.bar(stacked=True).invert_xaxis()

It outputs something that looks like this.

hello!!! … World?

This is the original playscript I wrote for The Art of Python that took place at PyCon U.S. in 2019. I additionally performed the piece at PyCon with the directorial help of Sumana Harihareswara and the stage management work and acting performance as the Figure by Mel Chua.

There were some changes to this script for the live performance. I created slides for the event and they were displayed behind me during the performance and are presented throughout the script below as images.

The Void

(slide reads: “THE VOID”)

(the stage is empty. We can make out one person, a figure, front and center.)

Kyle

(staring, wide-eyed, excited, past the audience – beat * 3)

Hello!!!

(slide reads: “This is Kyle –”)

(beat * 3)

Hello?

(slide reads: “he’s learning the new skill of –”)

Hello?!

(Terrified / heavy breathing / beat * 1)

(slide reads: “computer programming –”)

Hello, World?

(Covers his eyes with one hand, twists away from the audience as if what he is about to do might blind him, and clicks a single finger down on an imaginary ENTER key. Bright lights up full. Beat * 3 – he peaks through his fingers.)

It worked? It worked! Ha ha! Yes! Look at that. There it is: “Hello, World!” (Hand on hips – power pose) And you thought this programming thing would be hard.

(slide reads: “but Kyle was in for – “)

(Red lights, loud, blaring sirens)

(Kyle freezes in a macabre, horrific expression and body position)

(slide reads: “– a rude awakening.”)

Not a Programmer

(slide reads: “on not being a programmer”)

Kyle

No, I’m not a programmer, I’m just better than you are at excel spreadsheets.

(click sound. beat.)

No, I’m not a programmer, I just figured out how to use this query-like syntax with your data in Google’s spreadsheets.

(click sound. beat.)

No, I’m not a programmer. It’s just a little bash script I wrote that helps me journal better from my phone, laptop, and desktop.

(click sound. beat.)

Ha! I wouldn’t say I’m a programmer, I just needed to batch download a really big list of files from a service we were using and python seemed easiest after a google search.

(beat.)

I’m sorry, what?

(beat.)

No, yeah―it did work―ran for about 80 hours straight before finishing. Lots of files.

(click sound. beat.)

Okay―fine―I’m doing some programming: but I’m not really a programmer…

Picking a Language

(slide reads: “on picking a programming language”)

Kyle

Hi. My name is Kyle and I’ve decided to become a programmer. Several blog posts, books, and twitter surveys have lead me to believe that it is of the utmost importance that I:

(the next sequence is rapid-fire)

(between each beat are quick head, body, and vocal tone adjustments)

(very short beat. matter-of-fact:)

Learn Visual Basic, because my high school teacher gave me a book one time and I can probably find that in my basement if I look hard enough.

(very short beat. sarcastic:)

Learn Bash, because it’s already installed on the self-inflicted torture device known as my Linux Desktop.

(very short beat. in jest:)

Learn emacs lisp, because you’ve already invested the time into memorizing emacs keybindings and you’ve heard it could use a good text editor.

(very short beat. whatever:)

Learn Go because people talk about it on twitter a lot and it was created by Google.

(very short beat. haughty:)

Learn COBOL because it’ll always need maintaining, and it pays the best in my geographic location.

(very short beat. overheard/whisper:)

Learn Python because it’s the “second best language at everything.”

(very short beat. honest:)

Learn Javascript because it pairs well with my graphic design background for web development.

(very short beat. snooty:)

Learn R, because it’s the best language at data analysis and graphical representation.

(very short beat. authoritative:)

Learn HTML and CSS because you can make things on the internet―oh, wait―nevermind―there’s disagreement as to whether or not these are programming languages?

(beat. drop all pretense. speak directly to audience―with pure, sincere, exasperation:)

Am I really learning programming if I just know something like “hello, world!” in 10 programming languages!?

(beat.)

… and HTML and CSS?

stack overflow

(slide reads: “submitting a question to stack overflow”)

Kyle

(Kyle appears frustrated, staring straight ahead and typing in furious bursts.)

Python. Sort. Array. Count. Items. … Search.

(beat. scrolling:)

No. No. No way! What? No.

(beat. scrolling:)

And… no.

(loud sigh. lowered head. stretch neck. he tries again:)

Python. Array. Group-by-count.

(beat.)

No… no…

(beat. tilts head:)

Sort of?

(clicks. beat.)

Oh. No. No, no, no. Not that, kind of…

(beat. types again)

SQL group by with python?

(beat. smiles/excited:)

Hey! That’s kind of it…

(face drops.)

Oh! Rude! That’s not a helpful or kind response. Do I even want to submit the question here?―mean!―I already don’t know what to ask or how to ask it and apparently that’s a reason to say that you shouldn’t even ask the question.

(beat.)

Maybe I’ll just figure it out myself…>

(a transition. Kyle is holding a rubber duck.)

I’ve heard talking to you helps…

(slide reads: “Kyle works.”)

(duck is gone. cracking knuckles and stretching:)

Done―well, an example anyway, explaining exactly what I want to do and suffers the same problem as my actual work. But I still don’t know how to solve it.

(beat.)

Submit to stack overflow? Submit?

(resolve. clicks enter confidently:)

SUB. MIT.

(transition. later:)

An answer!―that does basically what I need―and they think I asked a good question―and I got fake internet points!

(beat.)

Okay then. Maybe I can do this.

(smile.)

Meetup

(slide reads: “on going to a meetup”)

Kyle

(hands in pockets. kicking dirt. retelling:)

So, I was sick of trying to learn things on my own―by myself, in my basement―and I found a meetup online. It was at a chain soup and sandwich place on a Saturday.

(beat.)

I clicked “attending” and went.

(miming what’s described.)

I got my laptop charged up, threw it in my laptop bag along with a notebook, a pen, and my charger, and slung it over my shoulder and headed in.

(beat.)

I guess I didn’t know what I was expecting? When I walked in and scanned the room looking for more than like four college students with their laptops open over coffee. There they were―I think. Play it cool!

(beat. walking:)

I headed to the counter and ordered a coffee―maybe I’d get thirsty―and walked up: “Is this the python group?”

(uncomfortable smile, holding breath and upright―more uncomfortable long beat…)

It was. That’s what it felt like―forever. They were nice. Young. Old. Macs, Linuxes, and Windows. Qwerty, Colemak, and Dvorak. Gnome and i3. Emacs and Vim and VSCode and Sublime. Working in finance, consulting, healthcare, insurance, startups, and going to college.

(beat.)

They were just people.

(beat.)

I didn’t learn much about programming that day―I did learn that there are real people in real life who care about some of the things I do.

(beat.)

I needed to reach out to more of them.

(break fourth wall. wink.)

Sending an email to a stranger in tech.

(slide reads: “on sending an email to a stranger in tech”)

Kyle

(straight to audience. single light.)

(like an awkward introduction at a job interview. exasperated:)

Hi. I’m Kyle. I’m new here. I want to get better at this technology thing. Can you help me? You seem like you could help me.

(beat.)

’cause I need a lot of help.

(ding sound. beat. overly formal:)

Hello. My name is Kyle R. Conway. I have a PhD … in Fine Arts … and you do art … and so do I … but you also do tech things … tech things with art. I would like to do what you do. May I join you?

(extends hand for handshake. beat. wide eyes. beat. more intense.)

(ding sound. beat. casual:)

Hey, tech blogger. I really liked your post about unpackaged fonts with permissive licenses. I think that’s really cool.

(ding sound. beat. rapid-fire round. cheeky:)

Howdy!

(ding sound. beat. Irish:)

Dia duit!

(ding sound. beat. concerned:)

I promise I’m not a creepy stranger.

(ding sound. beat. intense:)

I. Am. Your. Biggest. Fan.

(gong sound. rubbing eyes. honest:)

This is never going to work.

(quick fade. slide reads: “Kyle’s actual first email to a stranger in tech.”)

Thu, Mar 17, 2011 at 11:36 PM>
Máirín,
Would the “Nina” font meet the criteria for inclusion?
http://www.archive.org/details/NinaPaleyFonts
Thanks,
KYLE

(slide reads: “Thanks for writing back, Máirín”)

The Figure and the Void.

Figure

(A figure stands alone in the darkness.)

(The figure shouts with naive confidence into the void a single word:)

“Hello!!!”

(and… waits…)

(The figure finishes the phrase―now a question:)

“World?”

(figure stands awkwardly, concerned, awaitang a response with growing insecurity.)

(slide reads, slowly, word-by-word: “what. can. you. do. to. make. this. journey. easier. for. others?)

(slide reads: “end”. )

(ding sound.)

Rolling Dice in Python

The below rolls dice in python.  I’ve long loved python for dice-rolling―having created a now defunct twitterbot and a mastodon bot―it was nice to write this up briefly as I’m working on re-re-re-learning python.

#!/usr/bin/python3 
from random import randint 
 
total_dice = int(input('How many dice? ')) 
dice_val = int(input("How many sides? ")) 
 
rolls = [] 
high_roll = 0 
low_roll = 0 
 
for i in range(total_dice): 
 roll = randint(1, dice_val) 
 rolls.append(roll) 
 
nums = len(rolls) 
 
print("") 
print("Roll #\tRoll") 
print("------------------") 
 
for i in range(nums): 
 print("#" + str(i+1) + ":\t" + str(rolls[i])) 
 
 
print("------------------") 
print("Highest: " + str(max(rolls))) 
print("Lowest: " + str(min(rolls))) 
print("------------------") 
print("TOTAL: " + str(sum(rolls)))

Output looks like the below:

How many dice? 20 
How many sides? 20

Roll # Roll 
------------------ 
#1: 8 
#2: 6 
#3: 18 
#4: 7 
#5: 14 
#6: 7 
#7: 6 
#8: 12 
#9: 2 
#10: 10 
#11: 2 
#12: 13 
#13: 3 
#14: 10 
#15: 20 
#16: 5 
#17: 6 
#18: 19 
#19: 1 
#20: 15 
------------------ 
Highest: 20 
Lowest: 1 
------------------ 
TOTAL: 184

Wonderful fun.

Published
Categorized as code Tagged