Brought to you by Michael and Brian - take a Talk Python course or get Brian's pytest book


Transcript #164: Use type hints to build your next CLI app

Return to episode page view on github
Recorded on Thursday, Jan 9, 2020.

00:00 Hello and welcome to Python Bytes where we deliver Python news and headlines directly to your earbuds.

00:04 This is episode 164 recorded January 9, 2020. And I'm Brian Okken.

00:10 And I'm Michael Kennedy.

00:11 And this episode is brought to you by Datadog. We'll talk more about them later.

00:16 But speaking of data, data-driven journalism.

00:19 Yeah, let's start there. So there's this project called CJ Workbench or just Workbench, something like this. And this recommendation comes to us from Michael Pawlowski. Sorry if I kind of mispronounce your name there, but thank you, Michael. And it's data-driven journalism as a service, as a platform, along with training on how to use it. Not training on journalism, but training on basically how to do data journalism. So it's a pretty cool idea.

00:48 That is neat.

00:49 Yeah. And so what you do is you can go and say, point it at, I don't know, some website and say, I want you to scrape this from the website.

00:57 And then you go and you fill in like this UI, you fill in and say, okay, now I want to filter out the empty columns.

01:03 And I want to do this and that transform and other transforms and so on.

01:07 And so it basically lets you do kind of what you might do with a Jupyter notebook, but there's no code for the journalist, which is pretty cool.

01:17 And so you might wonder, well, if there's no code, why are we talking about it?

01:21 There's all sorts of software that does interesting stuff that we don't talk about.

01:25 Well, one of the things you can do is, if you find that the built-in features are not enough, then you write a few lines of Python and you start extending it for the journalists using Python, which is a pretty cool way.

01:37 So instead of you worrying about the UI and all the basic stuff like loading CSVs and working with data frames and all that, you just say, use this, and if we gotta write a little Python code, we will.

01:45 You can use their system and just add your own little code snippets to it?

01:50 Yeah, exactly.

01:51 So if you look at the features, it has modules to scrape, clean, analyze, and visualize data.

01:55 It's got built in training, like it'll teach you how to use the feature that you've got built in.

02:01 It connects to things like social and Google drive and APIs like JSON endpoints.

02:06 I think it has recorded workflows, so it's really repeatable.

02:10 It versioning.

02:11 But finally, you can write custom modules in Python and then add them to the little drop-down module library that you can use.

02:18 Oh, that's neat.

02:19 Yeah.

02:19 Yeah.

02:20 Plus, this is all in GitHub, so that if you really want to hack the back end, you can also.

02:25 Yeah, exactly. It's open source. It's on GitHub. You can go grab it, download it, and run with it.

02:29 But they also have it online as a service. So you can decide, do you want to run your own server?

02:33 Do you want to use their public server that's in beta or whatnot?

02:37 So I covered this partly because I think it's really cool. And I also covered it because Boy, I think the world needs journalism right now.

02:44 - Yes, and yeah, more people saying, I don't know if I believe your analysis, I wanna do my own analysis on it.

02:50 - Yeah, and here you don't have to commit to a huge amount of work.

02:53 It's cool you pointed all these live sources.

02:54 Like you can point it at some website and it can like real time refresh the live data that it's scraping for your article so it can evolve over time and whatnot.

03:04 Pretty cool.

03:05 - Might have to try this, yeah.

03:06 - Yeah, nice.

03:07 Have we covered GUIs yet on this podcast?

03:09 - I think I do remember way back when, at some point, we talked about GUIs, right?

03:13 - Yeah, at least once, yeah.

03:15 - What do you got for us this time?

03:16 - Well, so here's another one, another GUI.

03:19 This one's called Remme.

03:20 The Remme comes from Remote Interface Library.

03:23 I'm not sure why it's called that.

03:25 All GUIs are essentially--

03:26 - Why is it not Rimmel?

03:27 - Rimmel, I don't know.

03:28 - No, no, it's cool.

03:29 - But Remme, a platform-independent Python GUI library for your applications.

03:34 And yes, we've covered things like this a lot, like okay I want to just just scrap the idea of a native user interface we'll just use web user interfaces. The thing that I liked about this it's so small if there's no dependencies you do I'm not sure why they're pointing you to do a pip install from their GitHub repo but I'm guessing it's they're not really that great about updating the PyPI version because it's there also but anyway I did this this morning grabbed a just did a pip install of Remy but from their git repo and then I tried their little sample basic app and I'm like is it really this easy and yeah this is like 30 lines of code or less that to just write and if you run it just Python blip oh first of all when you pip install it it installs the package and then that's it doesn't install anything else because it's only dependent on the standard library which is cool and then you start it up and it runs a little server on your thing and it's really easy to throw buttons together and stuff. It looks pretty good enough and the code is simple enough that I thought I'd include it because there's a lot of cases where, like in an internal team, where you have, if you want to throw something together where people have access to some Python data or some Python analysis with the user interface and something like this would be cool and it's neat.

04:58 Yeah, it's pretty neat. It's like a Python only electron JS ish type of thing without the HTML part.

05:07 So you define your app and you programmatically define like I want a button here and I want to label there.

05:14 And when I click the button, I wanted to call this other Python function.

05:17 So you just write pure Python and then it turns the GUI definition into HTML, shows that in a server and then calls back to your code, something like that, which is pretty cool, right?

05:28 >> Yeah. It feels similar to working with TK back in the day.

05:34 Within the Python code, you create a label object and a button object, and then you put them in a container.

05:40 There's no packing so far that I can see, but has different types of containers that you append them, and then just throw those in a box.

05:49 Yeah, like you said, you don't have to write any of the HTML, It's just all Python code.

05:54 So yeah, for what it's worth, it's kind of simple.

05:58 - Yeah, it's a nice simple little thing and it looks pretty cool and yeah, I kind of like it.

06:02 - One of the things I was thinking about doing, sorry, was we have a switch box that's controlled through, we've got a Python thing that controls the switches and sometimes it'd be nice to be able to just see what the current setup is and just have a web page that just shows that.

06:19 It'd be really easy to write in Python, kind of hard to do, I don't want to deal with a whole user interface sort of thing, but having that, I think I could probably throw that together with this tool in like half an hour.

06:31 Yeah, and it's a proper local application, so it can look around on the system and do what it needs to do.

06:38 It doesn't need to be really a web server.

06:40 Although you can expose, I saw there's a way to tell it to listen on the network, broader interface, not just local host.

06:47 So you can expose this thing to sort of the world, for what that's worth.

06:51 I don't know if it's a good idea or not, but you could.

06:52 - Like I said, we would do it within our internal network.

06:55 So there's no malicious code flying around internally.

06:59 - Yeah, yeah.

07:00 - Yeah, anyway.

07:01 - You know, I'm starting to get excited again about Qt after Ogie Moore's presentation at the last PDX Python West meetup.

07:10 Like that looked pretty compelling actually.

07:11 - Yeah, what a slick program that was, and zippy.

07:15 - So very zippy.

07:16 Nice, speaking of slick, Datadog.

07:18 - Yeah, Python Bytes today is sponsored by Datadog, a cloud scale monitoring analytics platform that unifies metrics, logs, and distributed traces from your Python application.

07:32 The Datadog tracing client auto-instruments popular frameworks and libraries such as Django, Flask, Postgres, and AsyncIO even, so you can quickly get deep visibility into your application.

07:44 Trace requests across services boundaries with flame graphs, I like flame graphs, correlate traces with logs and metrics and plot your application architecture with the service map.

07:55 Sign up for free for a free trial at pythonbytes.fm/datadog and you'll receive a free t-shirt.

08:02 - Nice, yeah, they're doing good stuff.

08:04 Thanks, Datadog.

08:05 This next one, Brian, you wanted it, but I got it.

08:08 - Yeah, you got it first.

08:09 It's cool, I'm excited about it.

08:11 - Yeah, so there's a couple of cool libraries are building CLIs.

08:17 Flake is probably the most prevalent one.

08:20 We've got our pars, but people who do FastAPI, the cool new API framework, these folks have now gone, let me just double check that it's actually the same organization.

08:32 Yep.

08:33 Yes.

08:34 Good.

08:35 Yeah, they work.

08:36 Perfect.

08:37 So they've gone and created a CLI definition library like click.

08:41 And I believe it's actually based on click.

08:43 Yeah, it's based on click.

08:44 So you might wonder, well, what does it do?

08:47 The name gives you a little bit of a hint.

08:49 It's based on Python type ints.

08:51 So typer looks at the various hints.

08:54 You can say, I have a function.

08:56 It takes a name, which is name colon str, it takes a string.

09:00 And then you just use it.

09:01 And when you go run it, it'll say, hey, this thing that we ran, in order to call it, you have to specify a name, and the name has to be a string, and so on.

09:09 So it just looks at the arguments and the types of the methods you're trying to run, in the simple case at least, and it uses that.

09:15 That's pretty cool, huh?

09:16 - It's super cool.

09:17 - Yeah, and then you can grow in more complexity.

09:20 Like you can have subcommands, you can have help on all the commands, you can actually get autocomplete, you can install autocomplete in your shell, all kinds of cool stuff.

09:30 So you can create a little app, you say here's a command and here's a command, and then of course the commands are functions, those functions take arguments, the arguments have types, they can have default values, all that kind of stuff.

09:40 So you can try to run it, it'll give you help pretty much automatically, which, yeah, this really speaks to me the way this works.

09:47 I could definitely see myself using it.

09:49 - Yeah, so a really good, clean command line interface that has, if you're writing a tool with a command line interface, you're gonna want help associated with it, you're gonna want description of the different methods and what they do, but also with as little boilerplate as possible, you don't wanna clutter up your code.

10:08 And as far as I'm concerned, right now, type or wins, there's like hardly any extra overhead that you have to add to make this work other than type hits and if you're not using a main or something you have to put a little decorator on the different entry points in your program but really clean I'm totally gonna start using this. It's really nice and because it can leverage so much of the natural program itself right the argument names the fact that it has arguments the argument types like that's really helpful for it. So you can also integrate things like Colorama and Click, which is based on automatically start using color for its output if you just have Colorama around. You can also use Click completion and Typer, this is the part I was talking about, will automatically configure it to provide completion for all the shells. That's really cool. Yeah. So the one thing I was concerned about is it's based on Click and one of the things I love about Click is that it has a good testing interface.

11:07 You can write tests against your command line app as if you're writing from the command line, but you don't actually have to spawn a new subprocess to test things.

11:15 And yes, Typer has the same sort of model where you can write your tests against the interface and not have to do a subprocess.

11:23 - Oh, that's really cool.

11:24 Yeah, nice.

11:25 'Cause yeah, you don't have to start it.

11:27 Basically, shell out and see what happens, right?

11:29 Or like issue the command line directly to the shell to see what happens.

11:33 - Yeah, really good job.

11:34 Yeah, the other thing I like about this is you could say, well, we don't want the API of click.

11:39 So we're going to start from zero and rebuild our version of what this whole world looks like.

11:44 But what they did is said that we're going to build a new interface for writing against this, but on top of click.

11:50 So things like Colorama and the completion just plug in seamlessly.

11:54 I think that's a cool lesson.

11:55 Yeah, definitely.

11:56 Also, it's a smaller project for them to have to maintain too.

11:59 Yeah, exactly.

11:59 Yeah, exactly.

12:00 Cool.

12:01 All right.

12:01 This next one that you got here is from Chris Moffitt, right?

12:04 Yes, and this is actually, so I'm hoping this is completely still accurate.

12:09 I imagine it is. The interface for Matplotlib hasn't changed too awfully much. I know they've had some cool releases, but I want to talk about an article called "Effectively Using Matplotlib." And this is a 2017 article, but in the middle of the introduction, it says, "At first, I think I was a little premature in dismissing Matplotlib. To be honest, I did not quite understand it and how to use it effectively in my workflow.

12:34 I think that matches what my understanding of Matplotlib as well.

12:37 I mean, when I first needed to put charts or graphs or something, of course, you try Matplotlib and then you're hit in the face with the complexity of the interface.

12:47 You know you can do the simple thing simple, but how to do something a little bit more less than simple or more complex is a little daunting.

12:56 Then I went out and looked for other alternatives.

12:59 But now I think the alternatives have their issues too.

13:02 So I'm ready to go back and take a serious look at Matplotlib.

13:06 This article is a really good look at kind of understanding it and at least Chris's workflow, how to use it.

13:13 And one of the things I like is the description that one of the reasons why Matplotlib's interface might be a little confusing is because it's really got two interfaces.

13:24 It does a MATLAB-like state-based interface.

13:27 And I'm not a MATLAB user, but I know that a lot of people have come from MATLAB to Matplotlib.

13:33 And so that sort of interface is important to have that transition be easy for a lot of people.

13:39 But then there's also an object-based interface that makes a lot more sense to me.

13:44 And that's Chris's recommendation is to use the object-based interface instead.

13:49 And so now after he's gone through it a few times, and he has some recommendations.

13:55 and his recommendations are to first learn the basic Matt Plotlib terminology, specifically what is figure and axes and around those. And what's difficult for me is that those are just normal words that I think I already understand them, but I need to make sure I understand what Matt Plotlib thinks those things are. - Yeah, sometimes it's just hard to work with Matt Plotlib unless you find an example, right? A lot of times what I, my goal is to to hunt the internet for something that looks like I want, figure out if I can find the Python code that created it, and then I'm good.

14:30 - Yeah, he does have an example in this, which is kind of walks through at least one example.

14:35 But if you really want to kind of get your head around it, to start with using pandas with matplotlib.

14:41 And so, yeah, start your visualization with basic pandas plotting, and then add, if you want it more complex, try seaborn.

14:49 And then if you want to customize it a little bit more, He said use matplotlib native stuff to customize the visualization.

14:58 And I wouldn't have thought to use that workflow so that's kind of nice.

15:01 It also includes this really kind of cool handy reference that there's a little graphic that he created that has like all the different, what all the axes are and if you want to customize a certain part of a graph, what that name is within matplotlib so you know how to look it up.

15:16 And that's often the secret of programming anymore is to know what specific word to Google.

15:22 So I think that's a good thing.

15:23 - Nice, and also I want to remind folks, long time listeners of Pyillustrator.

15:30 Not really sure about the pronunciation, like illustrator, but pi for the first two words.

15:35 I'll put a link in the show notes.

15:36 And what it is, is it lets you take a basic Matplotlib plot, it launches a GUI where you customize the look and feel, and then it'll output the code that would have done that for you.

15:46 - Oh, cool.

15:46 - Yeah, we talked about that in episode 137, which is like a year ago or something.

15:50 But anyway, still good stuff.

15:52 So I put a link in there for that.

15:53 - I'm also including a link in a almost related section.

15:57 Maybe there's an article about this, but I haven't found it.

16:00 There's a Stack Overflow answer that has a little, the code you need to stick a map, generate a matplotlib graph and put it in a flask file on the fly without having to save it to a file.

16:14 - Oh yeah, like a live dashboard type thing.

16:15 That's cool.

16:16 - Yeah.

16:17 - Nice.

16:18 Speaking about doing stuff on the web, if you're using Django, there's a cool little library it'll let you do stuff in the background.

16:24 Maybe you want to do some query and update some kind of report, or you want to send out a bunch of emails or recompute some indexes or recompute some search results or something like that.

16:36 And it's going to take a little while and you don't want to just have it block on your main request.

16:42 There's a bunch of different things you could do, you could set up a separate server with like celery, or rabbit MQ or something like that.

16:49 But that's a whole nother set of servers and it just gets way more complicated.

16:53 Sometimes you want to just run it in the background just in the same process, right?

16:57 It's easy to share data because you just pass the pointers.

16:59 So there's this thing called Django simple task.

17:03 And it allows you to run background tasks in Django three without requiring any services or workers.

17:09 Oh, cool.

17:10 Yeah, basically, the reason it has to be Django three is it's based on asyncio.

17:14 And Django 3 is the first version that uses ASGI.

17:19 And so you actually need to run it in ASGI server like UV, a corner, something like that.

17:24 So be really aware that you have to run it in its async way for this to work.

17:28 But basically, when it starts, when the web app starts, there's a queue created and some workers to listen to the queue.

17:35 And then you just go to any function when you run, you just call defer on it, and that'll kick it off in the background.

17:42 And you could do that now, like you could create a thread and just launch it as a background thread.

17:46 But one, you don't get like a thread pooling.

17:49 But the other is when it's time for the worker process to shut down, like you're doing a new deploy or something, it'll actually wait until its background work gets done before it allows you to restart it, at least in a friendly way.

18:01 So that's cool.

18:03 And you can either give it a asyncio coroutine or just a function and it delegates it either runs it or delegates it to a thread pool if it's not async, things like that.

18:12 So it's pretty cool and it's really easy to use, like ridiculously easy.

18:15 Oh, that's neat.

18:16 Yeah. So there's a simple little example I put in the show notes where it just imports the deferred operation method.

18:23 It has two tasks, one of them which uses time.sleep that requires threading, and one uses asyncIO because it's an async method, so it would run on the async event loop.

18:33 And in the view, you can just say defer one, defer method one, one, defer method two, and then do your regular work. And that kicks it off, but doesn't wait for the response. But does it in a slightly more durable, better way than just like launching threads or kicking off on on its own little background thing to go run unmonitored.

18:50 So in this example, would that nobody can see, but they will if they look at the show notes, will the HTTP response happen? And the view return before the defer tasks get run?

19:01 They might get started. But because both of them in both of them, they sleep for a second to kind kind of that's their work, right?

19:08 They're sleeping for a second.

19:09 So certainly the response would be sent back to the user before those are done.

19:15 - And this is cool interface because the two tasks, one of them's async and one is not.

19:19 And the defer call doesn't, you can't tell.

19:22 - Right, you don't have to treat it differently.

19:23 But if you can do async, great, it'll do that on the async event loop, I think.

19:28 Otherwise, it just puts it into a thread pool, which is pretty cool that you don't have to worry.

19:32 You can just kind of go, here's some background stuff.

19:35 It's IO driven, we'll do it this way, otherwise just do it that way, which is, I like it, it's nice.

19:39 - Yeah, really nice.

19:40 - Cool. - Cool, all right.

19:41 What's this last one you got for us?

19:43 - Well, so something happened recently.

19:46 I've got a handful of, I don't open source, work on open source projects really as much as I'd like to.

19:52 I'd like to work, do some more work on open source projects, but I have a few that I maintain myself, but project is in air quotes I'm doing because they're really pretty small projects and a couple of them, cards and submark, are things that I just created to help with teaching people how testing works. They're not really intended to be useful projects. And then another one was a plug-in for pytest. Actually I do use it and it's useful for me but I started getting, like in the last handful of months, I started getting pull requests and issues and stuff and I didn't know anybody was using it at all so this was surprising to me. But I wanted to highlight, I don't know, I can't believe we haven't covered this or maybe we already have. There's a website called PyPIstats.org.

20:41 Yeah, that's news to me. I hadn't heard of it.

20:44 It's just a simple interface. Now the backend might be complicated, but in the interface you just has like a little box and you plug in a Python package and it tells you what the download stats, actually quite a bit of history too of different packages. And so I used that for all of my different projects, and sure enough, Cards was downloaded like, I don't know, less than 400 times in the last month.

21:10 Submark less than 70 times in the last month.

21:13 And then pytest-check, which is a little app or a plugin that lets you have multiple failures per test but keep going during the test, that was downloaded just a little less than 20,000 times in the last month.

21:28 So clearly that one's more, and that's the reason why I'm having more people trying to tell me what's wrong with it.

21:34 So I guess I have to start maintaining.

21:37 - Yeah, this is a super cool interface.

21:39 You get all kinds of graphs and ability to slice it by dates and whatnot.

21:43 And yeah, I like it.

21:45 - And there's also a top 20, so you can look at like really, what are the top 20 packages on PyPI?

21:51 And that's why I say that mine are small peanuts because at the most it's like 19,000 a month, but the top 20 all get over 1.3 million downloads per day.

22:02 - Wow, yeah, and you can look at the trends.

22:05 That's pretty interesting.

22:06 There's probably some cool stuff to go through here.

22:09 And I guess if you were trying to do predictive stuff or analytics, there's probably a lot of things to be done here.

22:15 - Yeah, definitely.

22:16 Also, just occasionally, I'm just, the top 20 I like because I was, occasionally I'm curious about that.

22:22 I'm like, what are the top packages on PyPI?

22:25 What are people using?

22:26 - Yeah, they weren't what I expected.

22:28 I mean, some of the ones I obviously expected were, but I think right now, urllib was the top top, and I didn't expect that.

22:35 So, urllib 3 specifically.

22:38 But yeah.

22:39 - It must be used by a whole bunch of other stuff.

22:41 Like 6, I don't think people are specifically downloading 6, it's the 2 or 3.

22:46 - Yeah, no, I think request uses both of those, and certify, and that hits the top four.

22:51 So, Python dateutil is a good one up there.

22:54 Bodo Core, pretty interesting.

22:56 I use Bodo 3, which depends on Bodo 4, but it kind of makes me frustrated 'cause Bodo 3 won't use the latest version of Bodo Core, but it's all made by the same people.

23:07 Anyway, there's a bunch of interesting stuff up here.

23:10 Yeah, I think I'm gonna have to look at this some more.

23:12 - pip is in the top 20.

23:13 - Nice, gotta get started somewhere.

23:17 - Yeah.

23:18 - All right, well, that's it for all of our main items.

23:19 What you got for the extras?

23:20 - Well, I wanted to actually just ask for some help.

23:23 The last episode we put out was a live recording of the January Python PDX West meetup.

23:30 Actually not the entire meetup, but just a--

23:32 - Newsflash, in case people haven't been paying attention, they're near Portland, there's a second Python meetup which runs out in Hillsboro.

23:40 Much better for West side folks.

23:42 So yeah, you put that together, good job.

23:43 - Yeah, and one of the things that we wanted to do with this one was to, I got this from a lot of people, and in the tech community, well, the West side has a lot of like high tech stuff that are, there's a lot of people coming from other languages to Python.

23:56 And so they might not be beginner programmers, but they're beginners at Python.

24:01 We've had this before people saying some beginner friendly content per at least one topic per meetup so that people aren't lost with everything.

24:10 And yeah, we kind of forgot this this last time, but I enjoyed the topics.

24:14 I'd like to hear from other people as to what sort of topics would be good at a meetup for Python beginner friendly.

24:20 and just let us know, I think that'd be cool.

24:22 - Yeah, well it's easy to get super into focusing on what's the most latest, coolest, hottest thing, but there's a lot of folks who really just appreciate setting the ground, a good foundation, and so yeah, I think that's a good topic.

24:36 - Yeah, and one of the things I'd like to do is possibly get a list of those sorts of things so that we can try to ask people to put together something.

24:44 Like at one of the meetups I did, just describing how pip and virtual environment work and how to use those.

24:53 And there's a lot of basic stuff that people don't even think about, maybe, that they should talk about.

24:58 And it'd be good to hear more.

25:00 I also wanna try to get other people to do it because you and I could probably do those sorts of beginner-friendly ones.

25:05 It'd be fun to have other speakers too.

25:07 - Yeah, absolutely.

25:08 It would be very fun.

25:09 If people are willing to get to Portland on a Tuesday evening, then they can come give a presentation.

25:15 - Yeah.

25:16 One more thing I want to do a shout out to Pi Cascades 2020.

25:19 I can't remember when that, it's in February coming up.

25:21 - February, I believe, I believe it's like 8th and 9th.

25:25 Let me double check.

25:26 It is February 8th and 9th in Portland, Eastside.

25:29 - Wonderful.

25:30 So people should get tickets so they could come.

25:32 And if you haven't bought your ticket yet, check the show notes because we've got a discount code for 10% off.

25:37 - Yeah, absolutely.

25:38 Yeah, it's right there at the bottom.

25:39 I don't really have anything this week for extras to share, but one thing that did come out that caught my attention yesterday that I think I might as well just throw out that's kind of cool is Firefox 72 is out and it has come with anti-fingerprinting which is pretty exciting.

25:56 So I don't know how many people are aware, I don't know if you're aware Brian, that even with ad blockers and blocking like tracking cookies and stuff, there's all these weird things that you can do to figure out, actually it's that same person, right?

26:09 Like you can ask what are all the installed fonts and what version of OS do you have?

26:15 And here's a canvas thing.

26:17 Let's run some stuff on there and try to detect weird CPU cycles and other kinds.

26:22 There's all these weird things you can do in browsers and pretty much uniquely identify everyone running a web browser.

26:28 - Oh, that's lame.

26:30 - Even without cookies, yeah.

26:31 So Firefox is trying to fight back against that.

26:33 So I think that's pretty awesome and worth checking out.

26:36 I'll actually link to Ars Technica article about it.

26:38 - Okay, cool.

26:39 - Yep, well, I guess that leaves us with a joke, doesn't it?

26:42 - Yeah.

26:43 - The last time we did a joke about describing different software programming jobs, this one, you're gonna have to imagine that people who are fans of various programming languages are in like a literature course and they have to write an essay, okay?

26:58 - Okay.

26:59 - Okay, have you pulled up the picture?

27:00 - Yes, I'm already laughing.

27:01 - All right, cool.

27:02 So basically there's professor looking person with glasses trying to read like a paper, a physical paper, and a student looking at it, getting the feedback from the professor.

27:12 This is important because at the end it gets interesting with the pictures.

27:16 So for Python it says, "This is plagiarism.

27:19 You can't just import essay." For Java it says, "I'm two pages in and I have no idea what you're saying." Pretty appropriate.

27:29 Yeah.

27:30 Assembly, "Do you really have to redefine every word in the English language?" With C it says, "This is great, but you forgot to add a null terminator.

27:39 Now I'm just reading garbage." (laughing)

27:43 I don't really know if I understand the C++ one, but it says, "I asked for one copy, not 400, "and the professor's buried in books." - Oh, I don't get that either, but--

27:51 - Yeah, Unix shell, this one's pretty good.

27:53 I don't have permission to read this.

27:55 LaTeX, which you often use to describe scientific papers and super elaborate mathematical formulas, says, "Your paper makes no sense to me, "but it's the most beautiful thing I've ever laid eyes on." - And the final one is the HTML programmer.

28:11 And instead of holding a paper, the professor's holding a pot.

28:16 And they just say, "This is a flower pot." That's it.

28:21 - I don't get it, but it's funny.

28:23 - Yeah, I don't either.

28:25 All right, so anyway, I thought that was pretty fun.

28:27 Y'all can check it out.

28:28 The comic is linked in there, but it was pretty fun.

28:30 You can't just import essay.

28:31 This is plagiarism.

28:32 - All right, well, thanks a lot, Michael.

28:35 - Yeah, you bet.

28:36 Thanks, Brian.

28:37 Good to be here.

28:38 listening to Python Bytes, follow the show on Twitter @pythonbytes, that's Python Bytes as in B-Y-T-E-S, and get the full show notes at pythonbytes.fm. If you have a news item you want featured, just visit pythonbytes.fm and send it our way. We're always on the lookout for sharing something cool. This is Brian Okken, and on behalf of myself and Michael Kennedy, thank you for listening and sharing this podcast with your friends and colleagues.

Back to show page