Keynote by Brandon Rhodes

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Please, where can I find train.txt? I want it so badly, and Google will not enlighten me.

👍︎︎ 5 👤︎︎ u/moose_ponderer 📅︎︎ Jan 15 2018 🗫︎ replies

A great presentation

👍︎︎ 6 👤︎︎ u/Nicksil 📅︎︎ Jan 14 2018 🗫︎ replies

I hope it utilize unicode boxes and 256bit true color in terminals nowadays. You can use ffmpeg to stream real videos I think.

👍︎︎ 3 👤︎︎ u/lambdaq 📅︎︎ Jan 15 2018 🗫︎ replies

I am a simple man. I see Brandon Rhodes in the title and I up-vote.

👍︎︎ 7 👤︎︎ u/dranzerfu 📅︎︎ Jan 14 2018 🗫︎ replies

Neat project and a good talk, but I think it would be better to replace the tuples with a class called Cell or something. Passing around a tuple with that much data to so many functions in it is a named code smell: “primitive obsession”.

👍︎︎ 1 👤︎︎ u/earthboundkid 📅︎︎ Jan 15 2018 🗫︎ replies
Captions
the last time I had dinner with our first keynote speaker it was a dark and stormy evening in Columbus Ohio where myself and Sam and our speaker saw a procession of police vehicles doing handbrake turns into a parking lot outside our chosen restaurant we never did find out what happened that night but I digress what that evening had in common with most other times I've met Brandon is hearing a wonderful collection of stories and amazing insights about Python it's unplugged that one yeah sorry amazing insights about Python and when it came time to choosing our first keynote speaker it was an obvious choice for all of us on the team and we're really glad he agreed to come along here here to share the joy of Python with you please make him welcome Brandon Rhodes [Applause] all right the screens working now right this is known as an ASCII art animation it is made of nothing but characters that you can print to the screen colors that you can display on it every block that you see is exactly the size of a character in this terminal window this is a terminal you're looking at that I've used to create an animation and I'm here to talk about that to talk about animating with ASCII or an analysis of the code behind my pike on 2017 talked at the inaugural North Bay Python I'm Brandon Rhodes by the way the Wi-Fi password I figured out after he said it is I think Python 2017 I was sitting there thinking what version of Python is too is 207 1 I I had no idea so my Python 2017 talk on the new features that have been added to the Python dictionary used ASCII animation to just give you a small taste of that I was in a terminal screen and I would run it and be able to show how when you insert keys into a Python dictionary they the first few are probably going to fit just fine according to the last few bits in their bit pattern but then if you add one that tries to use the same bit pattern it is going to collide with the key that's already there and have to be put in the backup location and I thought I mean we call them collisions shouldn't they look like collisions and and so that was the the idea behind using animation in my 2017 dictionary talk I wanted things to visibly collide so people then asked me how did you do it how did you make these seamless animations in skee and so I thought that they deserved an answer and that's the purpose of this talk and the answer is I did it badly and so I'd like to explain that first a little bit about my philosophies as a speaker some guardrails that I tend to put around my talks first I always have a / timer slide that tells me based on how many seconds are left till I need to finish the presentation divided by the number of slides that are left I always have a timer that tells me well you know you can only spend 15 seconds on this slide before you're eating into the time of the remaining slides because all I have here is a terminal screen to help me with this I have an assistant that will be called in whenever I hit that time limit and that will begin to destroy the current slide so that I have to stop speaking about it the so there it goes so that's how I'm going to try to rein myself in and not turn each slide into a lecture a second thing I do in designing talks is I try to do something with the tools I'm using to constrain my design space for example in most of my normal presentations going back to 22 2002 my very early talks at PyCon I write them in restructured text about the only tools I have available are to make a paragraph to make a bullet list or to make a block of code and I have to somehow come up with a way to communicate all my ideas just from turning those elements into HTML and applying some custom CSS so doing an ASCII animation presentation kind of fit the same mold it gave me a limited set of tools a Python script a terminal window in the Ubuntu mono font that prevented me from sitting and playing with the font all day or kerning two characters to get them just right by taking that option away I don't spend all my time fiddling with pixel-by-pixel detail I guess I fiddled with character by character detail instead which is a lot faster there's a lot of fewer characters than there are pixels third I try to go with very brief slides this is a famous made famous by Lawrence Lessig a decade or two ago the idea is that short slides are less distracting for the audience like right now you're listening to me rather than reading ahead to my next few bullet points aren't you because you don't see them until I advance short sides keep you on track if each slide is essentially just sentence you've got to stay it'll be easy to stick with it they also decrease the load on your memory as a presenter easier for the audience and easier for you the speaker so I always try to go with very short slides if I discover during practice of my presentation that a slide has two ideas inside that the slide is making me say one thing and then remember and say another I split it into two this presentation has 129 slides for example each of which are a simple idea that I say and move on past no big lectures that I have to give forth and finally use a big font how big is this font it is the biggest terminal font that still fits the code on slide 86 literally so lay out your talk and then just increase the use small code samples and increase the font size until the largest slide barely fits the screen I'm often just stunned by the fonts that people think I can see from the back row so those are my basic guardrails a per slide timer so I keep moving constrain the design space by using very limited tools that I have to work with in brief slides that each have one idea unless it's a recap slide before and use the biggest font I possibly can so all of this worked very very well with this idea of having the presentation in a terminal window so I went to PI con 2017 and I gave the talk I wrote my own ASCII animation live very because frankly I couldn't understand the others on pipe I did find a few ASCII animation libraries and I looked at how they worked and I'm like I can't understand how to make my animation how to write it in this framework I'll save time by writing my own I did get the talk done so there's two kinds of challenges that I had to dig into in order to get it done technical and architectural and I'm going to tackle them in that order which is also the order the ones I did pretty well and the ones I did less well so it'll be a good order for the story the technical ones we can breeze through the technical challenges were as follows I wanted to have in the middle of this animation I wanted to be listening for keystrokes and have forward slide backwards slide and repeat the current slide if I wanted to show the animation again all there at my fingertips is actions that I could run but in this loop that's running the animation and printing stuff to the screen of course if you say keystroke is just not standard in read one character what happens the animation stops and waits for you to hit a key and the animation would freeze if I ask for a character if I went in check to see if a character had been typed alright I knew my way around this I went and consulted the documentation and I used the Select call from the identically named to select module in the standard library to check whether there were any characters waiting before potentially blocking myself trying to read them so that cop got past the problem of sistent standard n dot read wanting to freeze my animation I could go read the character only if I was sure I had typed one but my program then it was now running the animation wasn't frozen anymore but it couldn't see my keystrokes until I pressed enter why was it ignoring my keystrokes until I hit Enter well this gets into a little bit about how your Mac OS or Linux machine thinks about the terminal you might think that your process connected up to a raw device that lets you write characters to the screen and listen for characters from the keyboard but it's a lie in between your process your program and the terminal is something called a term IOT's driver the term iOS driver is the source of many lies and deceptions it's designed for the days when terminals were very simple devices teletype sitting in Bell Telephone laboratories the kind of settings are designed to help programs operate on those old terminals the term is setting x' we're about to look at are not controlled thank goodness by writing special sequences you don't write some bytes and have the term eyeless driver wake up and think that those are settings because what if you needed to write those characters to the terminal term IOT's gets out of the way in that respect by having you use an out-of-band not in the right call system call to set its attributes you can go learn about all of those attributes and all of those settings by running man termios or you can do it from the command line run s TTY which is short for set TTY settings - a for all and you will see all of the settings that a modern Mac OS Darwin or Linux machine has available all of which can edit the data going out to the terminal or the keystrokes coming back before you ever get a chance to see them several of these settings were fighting me as I tried to write my animation library here are a few here are the ones I had to adjust first I have a driver between you and the terminal well this brings up the topic of the first setting that I want to talk about in the middle of that big man page is something called Oh phurba meaning a prefix meaning this is an output setting newline carriage return this sets up the rule that when you output a newline the term we'll actually get sent two characters carriage return is a character it's a single byte character that when you send it to the terminal moves the cursor from wherever it is back over to the left margin it is a favorite of people writing ASCII progress bars all you have to do is carriage return write your progress bar carriage return write it again and you get what looks like a single line that doesn't scroll everything off the screen that changes each time you write it its friend carriage returns friend is called line feed it strictly speaking it just moves the cursor straight down it stays in the same column but moves from one row to the next one you can see this in fact I'll bet many of you have seen this before as follows now for simplicity UNIX files only put a line feed at the end of each line so when you run PS a sample program just to use it as an example here something interesting happens it looks like each line ends with a carriage return moving back to the left margin and a line feed moving down but it's a lie PS is only pudding it's a UNIX program it's only outputting line feeds at the end of each line and then oh and then so I guess the challenge is can I finish before it's finished destroying the the slide so PS is simply putting a bear newline character at the end of each line and the terminal driver is the one adding in those carriage returns we can see this as follows run s TTY - for off Oh in LCR and then run PS again have any of you ever been in a terminal window where you ran a normal command like LS and the output suddenly stair-stepped strangely down the screen the reason is that this is the truth in truth PS only asks to move to the next line and it relies on the default terminal settings to get it back to the left margin that's a so then that's a that's probably the most famous setting that people run into the most often but some others are further down on the man page there's an echo setting that is on by default everything you type is echo to type the letter R it'll just appear on the screen whether the program you're using wants it to or not and term iOS like all good tools includes a built-in text editor right all tools need built-in text editors that's turned on by default so the that text editor is called canonical mode controlled by the eye cannon setting I will do a short demo the normally if you type cat and start typing a line of text cat has not yet received any input at this point why because the eye can an editor is reading my keystrokes echo is on so I'm getting them sent back to me and it's not until you hit Enter that the term iOS line editor concludes that you're done and all at once sends those characters to cat which then presents them back if is TTY turn off canonical mode in run cat again you will now see that and that you know everything my backspace characters everything else are going straight through to cat because though the text editor is off the the illusion is gone and cat is having to deal with my raw keystrokes as I type them the only crazier thing I could do would be to turn off echo cat enter hello world I hit backspace enter control C PS LS PWD bash has never actually been echoing those characters back to you it just leaves the term iOS driver in the default mode where it echos the characters for it so these settings the fact that the lion editor is on by default and the characters are echoed by default is agreed for you know the programs like oh and I'm going to show you a normal program now I'm gonna run a special command called reset reset is utter magic it sets echo back to the default it sets I it sets all of the settings of not only the terminal but the term iOS driver back to the default gets you back to normal so I can show you that for very simple programs like the desktop calculator six-six add them in print it's an RPN calculator built into UNIX it doesn't have to know about line editing or back spaces or anything it just leaves the terminal and its default state and a line editor is automatically sitting in front of it so it made small programs very easy to write that needed to work at the terminal reset command I just showed you might for most of you really be the most useful takeaway from this entire from from this entire keynote and so I will highlight what I believe might be the most useful sentence or pair of sentences in the entire UNIX documentation not that they ever tell you where to go find it so I will quote from demand page to reset this is useful after a program die is leaving a terminal in an abnormal state note you may have to type line feed reset line feed the line feed character is normally ctrl J to get the terminal to work as carriage return may no longer work in the abnormal state you're probably used to being able to hit enter to end the line that's because of a terminal setting that can get messed up control J is really the thing that will get you to the next line so I needed to turn those off and this is great fun you get to like go into 80s or retro mode because these settings are each a bit - and 8r are powers of two that define two bits that we need to turn on or off in the big word of bits that is the term IOT's settings so we have to get the output flags by using a standard library module called termios and then we can get those flags and them using the vertical bar with the echo bit and you can see that that fourth bit gets turned on to turn it off only time you ever get to use the squiggle in Python I've never found another use for this the little squiggle though the tilde operator gets a word and flips all of the ones and zeros so we now have a zero where we want to turn a bit off we use and to get the bit turned off in the settings it works great it's fun and it's like this 80s moment in the middle of your programming day so those are the settings and the things I had to be careful of in the termios driver things like echo things like canonical mode what then did I have to learn about the state of the terminal which is also a stateful appliance which changes as you use it to talk to the terminal and to change its settings you have to use ansi escape codes these are an indie in band signal this is in the middle of sending characters you throw in some special character sequences but don't get printed to the screen they instead change the terminals state this fact that these are in band signals that they that they're in the same stream of characters you're outputting lead to an interesting hobby people used to have they would share animations with their friends as plain text files because a text file can have printable characters in it it can also have these especial escape codes let's go back to our little standard 80 by 24 window apologize for the small font but this animation happens to be that size my father worked at Bell Labs and back in the early 80s right at this time of year what is this a 2nd of December I think right at this time of year people would start sending back and forth to each other a little file called train dot txt I see someone who's very excited are you ready so imagine you're at Bell Labs it's 1982 someone sends you this text file and you say cat train dot txt all wasn't that great what went wrong well that stream of text characters has no timing information inside of it there is not on most terminals a way to say wait one second and then continue processing so unfortunately on a modern terminal we don't get to see the animation unless we write a program that prints out a file at 1,200 baud it's it's it's a very it's it's just a little loop that pauses between each byte here is what it would have looked like on a 1200 baud terminal on someone's desk at Bell Labs the flashes are where it's ringing the terminal bell to make a ding ding sound is it here it's gonna ding again ding ding now I'm going to run less on this file to let us see the truth behind it unless is not it is it less is a smart program it is not going to let the animations start moving the cursor all over the screen less is going to use I think reverse video to show me where special escape codes are and so you can see that at the top is the email headers oh I'm sorry this was 87 that this was last sent from one person to another and you can see here all of these escape codes all of these special characters that aren't the 96-95 printable ASCII characters but are drawn from that first 32 remember always that man ascii if you spell it correctly will get up a table that lets you remember how many 32 the 32 first character codes are all special ones that means something to the terminal and this is a text file that because all of these instructions to the terminal are in band are just bytes in your data stream you can store them to the file and watch them decades later if i'm a one for one moment doubt the UNIX system how many other animations from 1987 can you still play the design they did has very very great longevity so train dot txt these are in bands signals that you just write like any other normal character but they do things they move the cursor around of things like that so I could have used a big terminal library to introspect the kind of terminal I had and write the codes for me but I don't know I'm not that kind of guy I just did it this way I just said look there's like five things I need to do is all I need to know how to hide the cursor show the cursor why because notice how annoying it is we're gonna watch train again watch because the Train animation is constantly sending the cursor all over the place to draw the little train engine and to make the lights on the tree blink notice that there's all these little ghostly cursors do you see there's this little like little all these little cursors like following the Train down the track that's because this was not written by someone who knew to turn those cursors off before displaying it at least when I was preparing for my Python app I can talk I thought the cursor was really distracting having it flicker everywhere so I am used hide cursor in a reset hide cursor to hide it show cursor turns it back on when the program exits the only other things I needed we're go to origin because I just go to the upper left corner and just print as many characters as there are characters on the screen and it just fills up each row with the slide I want to display and then I need to set the foreground and back how a background color when I want part of the slide to be a different color the eye I did all that inside of a try finally so that if my program crashed I mean I think it did once as I was editing it it would set I wouldn't have to type reset if I set the echo and I can and in show cursor back to normal and always set your colors back it is no fun to have it die when the color is white on white and then you can't see the trace back the next technical thing that I had to tackle was the fact that there the talk was about the difference in dictionaries between different versions of Python now understand this animation program was actually creating dictionaries live and drawing them on the screen so from one slide to the next I might need to change versions of Python so that it would change features and behavior so I used a UNIX superpower called exact it is a call that replaces a process the one making the call with a new one without leaving a dangling parent process hanging around waiting here is my favorite shelled Z shall I run PS okay my current my shell is currently process 70 807 let us if I ran been - if I just said bin - then 70 807 would now be the CSH process a parent process waiting on bash to complete but I know I'm not going to use the SH again in this session so let's exact bin - I'm now inside of bash and it has become process 78 oh seven you're giving your slot in the process table - another process without leaving a parent dangling up behind you this is very important if during a slide deck you might restart Python 128 times as I'm doing here running as so there's several versions of it that are is a bit of a confusing thing I found exact vpe was was one that worked pretty well for me in the OS module all I had to do was find what version of Python I wanted to run for the next slide I was advancing to and then invoking the oh I hit repeat instead of forward the here we are we've moved forward this meant that each of my slides could run under a different version of Python and it also meant I got rid of the need for auto reload I didn't need to have I didn't need to stop and restart every time I edited my slide deck program because I was automatically be starting every time I moved to another slide it was really convenient it even wound up helping me with dictionary stability one problem is as I moved into the more modern versions of Python the dictionaries looked different every time I ran because of the randomization they do and and it's very hard to build narratives around dictionaries when you don't know when the keys will finally collide at first this was very inconvenient I had to because that's something that can only be said at startup you can't adjust it later I would just have to exit with an error if I forgot to set that environment variable when I ran my slide deck every day when I'd sit down to work on it I'd have to run it twice to remember that well what's not realized I could use exec I just put an if statement at the top that says well if the environment variable I needed to be started with wasn't there when I started let's just react myself exact same program exact same arguments but throw in the environment variable so that Brandon doesn't have to remember to it was really helpful so those were the technical challenges and though several of them snagged me for a few minutes as I had to relearn how terminals worked I got through them fairly well we will now talk about my architectural issues how can I store the screen now this is I started off pretty well this part survived how can I store the screen to allow random-access modification since if I made just a big long string that holds all of the rows of characters it's difficult to edit so I decided to make what I call the canvas I was drawing on which is a list of characters starts out as spaces one for every position on the screen starting in the upper left and you know going in the same order I'll need to print them in down all the rows to the bottom and then two corresponding lists of foreground and background colors if I want to write to this because lists are mutable I can simply use pythons on the bottom three lines here really beautiful range assignment operator - given that the another part of the program wants to scroll some text on to this canvas at positions X and why all I need to do is I can just say we'll set characters I 3 J 2 though characters from that text and then go in and set the foreground and background colors as well when I was ready to print it to the screen easy and this part again survived and worked just fine you this is essentially just for each character yield the character and then the caller will empty string dot join this all together into a single bundle of text that it can write so that the frames appear is quickly and a solid piece as possible but I also whenever the color changes between one character and the next need to yield the special code to the terminal that will change so that if I've gone through some characters that are black I then need to change and send that signal so the next few will be red or whatever but I only those who remember those escape codes you saw a minute ago are kind of big so I only output them if the I can't just reuse the color of the previous character that all worked great the problem came when I had to tackle the question how do I write animations using scrawl I first thought of it like this well animations unfold through time an effect might last for a second or two or three as I animate a Python dictionary and those seconds are made up of individual frames 30 I think I think I wound up going with 60 per second and and because that's a typical refresh rate for a monitor like this so smooth as possible 60 per second how can I go ahead and plan out which effects will be happening during which frames well I like data structures and I thought I'll just build a data structure I will before hitting go I will study the current slide and I will go through and I will set up for each frame the animations that it should call but things that need to appear on the slide for it to appear but then I can just do a loop starting at the first one call the first list of functions on a canvas second list of functions and for each of those print slide to the screen here's a sample animation so we have an example to talk about beautiful is better than ugly each one fading in over exactly one second I'll run it again so that's a sample animation that I can now use to kind of show you how this worked as I wrote a routine called fade in you give it the script that it's going to add itself to a start time a duration and the x and y location and the text that you want it to display all it's got to do is go add some kind of function or callable to the correct frames in that list of slides to get itself scheduled so that as the animation proceeds those will appear this was my first try at getting animation working so we need to write fade in it needs to build some kind of cobble that it can stick into all of these pre scheduled frames well where I going to get one of those from Python has essentially two best clap best of class ways of doing this one is a bound method you create a class and you give it's a knit method all the information about the animation it will be doing and it then has to store away all of the relevant information that will be needed during the animation itself self dot duration equals duration and so forth and then it can get its method called self dot draw and go add it to the correct frames in the script what is self dot draw it is the actual caller of scroll that is going to be writing self dot string to the canvas itself dot X&Y having consulted you know the current time T that's also passed in to figure out whether we're now at the point where we should be all the way black or still partially gray and that would work however there's an option I always enjoy better which is a closure self goes away all of those assignment statements go away and you use the magic this was added to Python in the 2000s you use the magic of the fact that if you save away an inner function like the draw here that's inside a fade in it for free will remember what duration XY and string were back when it was defined so here I'm appending a plane draw function that inner function to the script where I want it to be called and later without needing self and an instance attribute references it'll be able to get to the information it needs there are two disadvantages that I will go ahead and say despite my assistant to having a class one on a class instance if you want to go back later and look at what duration and X&Y were from outside you can do it with a closure there's no easy way to having been returned that draw function to go ask it what it thinks x and y are you also can't modify it x y and string are just fixed here they can never be edited later now in this application I was never planning on going back and introspecting this fade animation or trying to change its X&Y but in applications where you need to a class instance is really the best thing closures are great when you just want an inner function with a memory that isn't going to forget things but that you don't need to go into respect or modify later so that worked pretty well I got a first few words to fade in and appear on the screen they looked kind of like professional slides this was going pretty well then I ran into a problem as soon as I reached the next level of complexity what if the text isn't fixed like the word beautiful what if it is generated by another column like something that knows how to draw a big Python dictionary so if the slide if the material I want to fade in is produced by another draw another animation routine one kind of stock my draw routine is called with T in canvas and I know that I'm going to have to call that other animation with tea and canvas but that other animation it's just gonna go draw to the canvas without asking me I won't know which information on the canvas was drawn by it and should be affected by my fade and what information might already have been there from other components drawing to the page I thought for a moment what if I just monkey patch scroll and then I fought I thought no monkey patching is software bankruptcy monkey patching means that things have gotten as bad as they can possibly get so I wasn't ready to give up so I thought through what is my problem my problem is that animations aren't composable these little things I'm writing that draw can't be stacked or layered I looked at the code again and made a crucial observation canvas that I'm passing to every single animation is never actually touched by enough by an intermediate effect like fade in and so I thought what if I switch up passing a noun the canvas and instead pass the verb because a bottom level draw routine it never goes in and indexes the canvas directly it always goes through scroll because that's more convenient so why does it need to know about the canvas object why am I even passing that what if I pivoted to making these animation routines simpler where they know a bit less about the way the framework is structured what if I just give them the scroll routine that they are supposed to use and don't let them touch the canvas yet that was the big win that let me finish this out and get a talk ready for PyCon 2017 back in May because this changed one little change from a noun to a verb gave composability when I am called it's time to draw a slide 50 and so draw is called with 50 comma and a a presumably the scroll routine that will really write to the canvas I call the next animation down with a different scroll routine that applies a fade to each piece of text that's displayed all of a sudden I'm in control of what that subordinate routine does and can make its output be a a I can adjust its output in any way that I want having a function inside of a function inside of a function seemed a little bit much but it was time to finish the slides up and attend the conference so that's the formal library was in when I presented at PyCon 2017 which is why I haven't shown it to anyone so many wrapper functions functions inside of functions so after PyCon and in preparation for this talk I wanted to think about that disaster and what had led to it so let's review fade in this animation layered on top of another one needs to have an inner function that itself needs to have an inner function and the draw dictionary and you know it has a subordinate one draw item that draws one item of the dictionary they also if they are going to be intercepting and using a lower-level drawing tool also have to have their own version of scrawl so let's to see why trace where the data goes do you ever do this with your program sit down and draw a picture and trace where the information goes the order here is that first we call fade in and it gets its dot draw and goes and puts it into the script then as we run through the animation every frame is gonna call draw with a different value T it is going to call draw a dict it is going to call draw item which thinks it's calling the real scroll function scroll function but is really calling the inner scroll function of draw dictionary that calls what it thinks is the real draw scroll real scroll function that writes on the real canvas but it's not it's the one from fade-in that then really gets to draw on the canvas now let's look at the data so this worked let me say this worked but I wasn't happy so let's look at that picture and think about the data that's passing as draw calls dictionary draw calls dictionary calls draw dictionary calls draw item like nothing much is changing all what we're doing is passing the current time all the way down without even modifying it the current frame number the interesting thing happens on the way back we start with an XY a string in some colors and that changes at each level as it's passed up it's almost like hiding inside of this horrible set of inner functions is a system for producing tuples and then applying simple filters to the values in the tuples can and this is how this presentation is written can we write an ASCII art library that's kind of a good parts version of the one that I just described here is a no scrawl solution I've restructured to explicitly defer drawing to later now that previous one when the innermost you know and one called what it thought was the scroll function I was implicitly secretly deferring it I wasn't letting it draw to the canvas I was going to go through some other steps first but let's make that explicit let's make it explicit that we're going to wait and not draw these things until the end so I'm going to define a frame that we're gonna you know one of these frames of the animation it is no longer a canvas it is simply going from the point of view of the drawing routines it's going to be a list of tuples that each describe a piece of text to be drawn using the parameters we're familiar an animation is simply going to be a generator that builds and returns these lists this is composable and I will show you how with four simple calls I can run that beautiful is better than ugly animation each of them fading in over one second here we go to send her a piece of text I don't have to go write on a canvas now all I have to do is yield a list of tuples and somewhere out there the my caller the ASCII animation framework will go due to the drawing for me so I just given the length of the text I figure out where to Center it and all I have to do I'm a little infinite animation that's going to sit there and make the text display until I move the frame the slide forward to the next one all I have to do is yield up for each frame that little tuple over and over and over again simple easy to write no inner functions no callbacks okay fade in is more complicated because it needs to edit what another animation produces so it does this it produces given its duration the list of levels zero through one that it's going to apply to the two fading the background color to the foreground one it then for each frame it's given for each list of tuples it's gonna turn around and return or yield I should say its own list of tuples where each of the incoming tuples is edited to give it a different foreground color done if we want several animations running simultaneously we can use zip which remember will just sit there and run a bunch of generators simultaneously returning to us all of their outputs that correspond to each other what everyone thinks should be on the first frame the second frame the third frame if I want to combine them all I have to do is loop over all of those lists making a single list of tuples to send back up to the animation engine and this is how the animation looks line 1 line 2 in line 3 are very simple primitive centering zuv three pieces of text at different Y values I first okay animation is running now I first yield from fade in which is going to fade in is going to return one seconds worth of line one fading from nothing into visibility on the screen I then yield another seconds worth of animation where lying one is now fully visible and line two is fading in finally for one second I fade in line three and end by having all three lines fully visible and here it is running switching things around and foregrounding the data and for grounding the fact that each of these animators is returning something that other animators have the right to edit and change in filter before it gets handed back for drawing on the canvas was the key to making this a framework I was happy with that I might even open-source tomorrow or something so all the challenges I faced technical challenges I would give myself an a I did an okay job back in May setting the term IOT's values to get it where my animation could run but that design was at best a c-minus I mean as I mean functions inside of functions inside of functions but the problem is you see that there's this ugliness there but you have a talk dude so sometimes you have to get something like right I got it to the point where it was barely composable we saw you know that sometimes you just have to get something to the point where it at least is sufficient and just run with it but part of the reason for my giving talking about this in a keynote is it finally let me go back and do this right my why a c- because and this is very important to be thinking about my code wound up more complicated then the problem it was trying to solve this seems to happen to us so often but it can be so difficult and take months sometimes to see the transform that will get us out of that situation and let us reduce the complexity of the code down to something more roughly approximating you know I'm trying to put characters on the screen need it to be this hard in conclusion you can give the talk the clean architecture at PyCon Ireland three years ago in 2014 and still struggle to produce code that is shaped enough like its data I'm Brandon Rhodes thank you very much [Applause] thank you very much Brandon [Applause] okay so
Info
Channel: North Bay Python
Views: 6,002
Rating: 4.8857141 out of 5
Keywords: nbpy, nbpy17, BrandonRhodes
Id: rrMnmLyYjU8
Channel Id: undefined
Length: 49min 47sec (2987 seconds)
Published: Fri Dec 08 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.