Python Bytes - #202 Jupyter is back in black!
Episode Date: October 9, 2020Topics covered in this episode: New in Python 3.9 jupyter-black Understanding and preventing DoS in web applications bbox-visualizer How to NEVER use lambdas. Uncommon Contributions: Making impact ...without touching the core of a library Extras Joke See the full show notes for this episode on the website at pythonbytes.fm/202
Transcript
Discussion (0)
Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.
This is episode 202, recorded September 30th, 2020.
I'm Brian Ocken.
And I'm Michael Kennedy.
Yeah, and this episode is brought to you by Datadog, so thanks Datadog.
Yeah, thank you Datadog.
It's good to have you back, Brian.
It's good to be back.
We missed you.
Yeah, I had a little bit of a heart scare, but I'm all better now.
That's good to hear we're
recording this september 30th but by the time this comes out we might have a new python so
did you know that i did not know that but i'm very excited that you're covering that first yeah so
usually there's about a week delay and that's about when python 3.9 yeah so python 3.9 there
is a the rc2 or releaseate 2 was released September 17th.
The final is scheduled for release October 5th.
Of course, you know, it's software, so things can come up.
But we're looking forward to starting using 3.9 right away.
We're linking to the changelog.
There's a lot of different lists for what is in 3.9, but I wanted to highlight a few features that I
pulled out from the changelog. The first couple I think I'm most excited about,
there's a dictionary merge and update operator. So the merge operator is just the bar. So you
can have two dictionaries and do a bar to merge them together and the bar equal for the update the update kind of means it doesn't
mean append it means like if there's new stuff add it to the other other dictionary but if there's
changes change it so i think this is just when i first read about this i thought why don't we
already have this this just seems obvious so i'm glad to have a merge operator yeah i thought this
uh there's already a way to
accomplish this with the curly bracket, star, star, dictionary, star, star, dictionary, star,
star, dictionary, which has the same effect. It's a little bit longer. I think this is for
consistency with other container objects like sets that have a pipe behavior. So it's like,
oh, you can just do it to dictionaries. Yeah, I think. That's nice. I had to read a little bit.
The next one is a remove prefix and remove suffix has been added to strings
and also added to bytes, byte array, and collections user string,
which is cool.
I'm most excited about this one.
Are you?
Yeah.
Because this actually, when you look at like the workarounds to do something,
the other workarounds are ugly.
If you just want to, it's just, I have like this string that might be at the beginning of my, of another if you just want to it's just i have like this string
that might be at the beginning of my of another string i want to remove it like if um just this
prepended stuff that happens all the time so like spaces or things like that what would you use it
for well yeah the same thing there's a lot of times there's like oh there's this string that
always starts at the beginning of this line and i just don't want it right but the trim trim start
trim and trim if you give it characters it doesn't mean remove that string it remains remove like
take each one of those characters and remove all of them until you don't run into any more of those
characters and so if one of the characters of your string happens to be the first character of the
stuff that's left it'll also get ripped yeah you just want a specific string to get
removed a set of strings right if i'm like i want this substring off the front you know if it exists
but not if it doesn't right you don't do the test and anyway it's just it cleans it up and makes it
a little more predictable okay yeah next thing is uh type annotations have a change that you can now
use the built-in collection types such such as list and dict, as generic types
instead of having to import typing
or from typing import capital list or capital dict.
I'm really excited about this.
Wait, I did get back.
I'm more excited about this than remove.
Yeah, because I'm always annoyed when I have to like,
because I'm starting to use type hinting for interfaces,
and you don't need to import anything to do that, except for if you have a list
or a dictionary or a set or something like that. And now
you don't have to do that anymore, and I'm very happy. I'm still waiting for the optional
operator, the question mark or something, rather than
capital O optional. Yeah, that'd be good.
We've talked about the peg parser before,
but the 3.9 is where the new peg parser comes in.
I don't know if it'll affect anybody, but it's neat.
Yeah, it's supposed to make extending the language
with more complicated behaviors and more nuanced syntax easier.
But it won't affect you or me probably writing code day-to-day.
I'm not going to touch that thing.
Yeah, I'm not.
I was intrigued by this.
Any valid expression can now be used as a decorator.
This is PEP 614.
I haven't quite wrapped my head around it
but I think this will change the way we use decorators
but I think we need a few tutorials to be written
for people to figure out how to use this.
So maybe we should just make decorators like a lambda expression
because I know you have later in the show some really cool uses of lambda expression so we can come back to that. Oh my gosh. written for people to figure out how to use this. So maybe we should just make decorators like a Lambda expression?
Because I know you have later in the show some really cool uses of Lambda expressions, so we can come back to that.
Oh, my gosh.
A huge Lambda expression could be a decorator.
Yeah, that'd be cool.
Or really bad.
Anyway, the other last thing I wanted to mention,
zone info is a new module that comes in, which is cool.
It has IANA time zone databases support. That's part of the standard library now. Uh, zone info is a new module that comes in, which is cool. Has I a,
in a time zone databases support.
That's part of the standard library now.
And there's a whole bunch of other stuff too.
So we're going to link to the change log and people should check that out.
Yeah. Very cool.
Exciting.
We're going to have a new Python and Python comes faster now.
It does.
I think they changed the release cycle to 12 months.
Oh yeah.
So it's a year month,
three 10 or whatever the next thing is should be out soon.
Yeah, we'll just put it on our calendar. First week in October
we should expect a new Python. That's right.
What happens in October? Halloween
and Python. And black.
Black cats. Black. Yeah, because
you want to go out into your costumes
and your scary costumes at night
when it's dark. It's no fun to do Halloween
in the day because it looks fake.
Or, maybe you just
have a jupiter notebook and you're a fan of black but you would like to format it
so mary hung sent over a cool recommendation based on some stuff we had over on talk python
so in talk python i did a auto racing episode with kane replicable and his pick for a pipey eye
package recommendation was black cell magic,
which I think we covered on the show as well.
I'm pretty sure she said,
you should check out Jupiter black and Jupiter black is kind of like the same
thing,
but instead of having to type into the cells,
you can just press,
it gives you a toolbar button you can press and off it goes.
So that looks really cool. It gives you a toolbar button and a couple of hotkey
shortcuts keyboard shortcuts to format single cells and format all the cells okay that was
gonna be my question can you just have it do the whole the whole shebang at once exactly and that's
what was it also run you can also just run instead of running black in your ci you can run J black or as a pre-commit hook or something
like that so I believe with the one
the black cell magic that I talked about
previously you had to like type it into
the notebook and it would do it
which is cool but this is more of a
and I talked about there being an extension
that would kind of do it for the whole notebook but it was
it had a huge message like this is
no longer supported so like I'm not
so sure.
So this gives you both a CLI and hotkeys for the whole notebook,
which seems cool.
Yeah, it does seem neat.
Definitely need to check that out.
Yeah, absolutely.
Quick and simple, but to me,
that's one of the huge shortcomings of Jupyter on multiple levels.
I think the auto-formatting,
like Jupyter should format that code as I type i shouldn't have to like run command line things against it to get formatted code like you know visual studio
code pycharm it gives you that support as you go you're not like spacing around tapping around
the other i really wish jupiter did better was autocomplete yeah yet yes if if you hit dot
nothing happens but if you hit tab it will come up But if you hit tab, it will come up.
And I think there's a lot of, you know, compare that to the other modern editors.
There's a lot of room to make improvements on those areas.
But, you know, this, at least having a keyboard shortcut, like reformat document, you know,
command shift B or whatever, control shift B, that seems really like a good start.
Do you know if JupyterLab has any different support?
I don't think so. I think JupyterLab just has more other UI elements,
like you have an ability to get to the terminal and do other stuff.
It's not just the notebook.
But I don't think the fundamental editor experience changed.
I could be wrong.
I don't compare them that often, but I don't think so.
I mean, if they get to that point, it wouldn't be an IDE.
It would be a JDE, right?
Jupyter Development. That's right, a JDE.
Exactly. Good one.
Alright, another cool thing is Datadog.
This episode of Python Bytes
is brought to you by Datadog.
Let me ask you a question. Do you have an
app in production that is slower than you
like? Is its performance all over the place?
Sometimes fast, sometimes slow.
Now here's an important question.
Do you know why? With Datadog
you will. You can troubleshoot your app's
performance with Datadog's end-to-end
tracing. Use the detailed flame
graphs to identify bottlenecks and latency
in that finicky app of
yours. Be the hero
that got the app back on track for
your company. Get started today with a
free trial at pythonbytes.fm
slash datadog. Awesome. Thank you, datadog. You know what's not awesome?
DDoS. Denial of service against your web app.
Yeah, so this is a couple of things I've got. Our listeners'
suggestions, and unfortunately, since I've kind of been out of
commission for a week, I forgot who suggested this. So my apologies to the listener
who brought this to their attention.
There's an article written by Jacob Kaplan Moss called Understanding and Preventing Denial of Service on Web Applications.
I saw it, but I kind of dismissed it right away because I thought it was just another, like, about all languages.
But this one is focused on Python and has some specifics on Django. So
I think it's, it starts off with a good discussion of what denial of service is,
and then sort of kind of what to do about it and how to prevent it from happening and fix things
on your, with your application. But it kind of led me down a rabbit hole and I kind of enjoyed it.
Anyway, there's one example that it lists as a hadn't i
think i've heard buff i don't remember if we've talked about it on the show which is called a
redos which is a regular expression denial of service we talked about this do you know i don't
think so but yeah there's certain types of like computationally expensive things that are not
going to match or useless or whatever you can send over to regular expressions that will cause all sorts of trouble.
And what's interesting is it says Redos bugs occur
when certain types of strings can cause improperly crafted regular expressions
to perform poorly.
And I'm talking like really poorly.
What's interesting is they're not even complicated regular expressions.
They're just like, instance a match a set
containing like a character one or more characters or zero more characters followed by another zero
or more characters followed by a b or something like that and there's like a little graphic on
one of the links on this uh page that shows how slow this is. It has to match all these different things, and it's bad.
Anyway, some languages have stuff put in place
to try to thwart this sort of a thing, but Python does not.
But we have a solution.
So this article links to another article called
Finding Python Redos Bugs at Scale Using DLint,
which I was like, DLint? What's that?
So I went and looked there.
DLint is a Flake 8 plugin, so you can check for denial of service vulnerabilities
when you're checking everything else with Flake.
Oh, that's interesting.
I'd never heard of that one.
Yeah, so I was thinking it's a security plugin, a sort of linter for Python.
And I was thinking, is there a difference between that and Bandit?
And the authors of DLint were expecting that.
So the first FAQ is, what about Bandit?
So there's a discussion about whether or not to use Bandit.
But the TLDR is, it checks for different things than Bandit.
So you can run both of them and they run perfectly fine on the same code base.
Yeah, super cool. DDoS is no
fun. Distributed DDoS, a whole lot
less fun. So
having to deal with that, I've had to deal with that before
and managed
to get ahead of it, but
if there's thousands
of computers trying to do bad stuff to your website
all at the same time from different locations,
it's not easy. You've had to do that for to your website all at the same time from different locations. It's not easy.
You've had to do that for maybe TalkPython or something?
For TalkPython training, yeah.
People, thousands of computers were trying to do all sorts of stuff at the same time.
So even things like, let's just block this IP address,
or let's put in checks that if this IP address does five bad actions we're going to block
it for an hour or a day or permanently none of that would work because it was so many different
computers or devices or whatever anyway not fun it'll definitely get your attention another thing
that'll get your attention is pictures we love pictures so show mick chow do re sent over a
project that he's working on that i think is
pretty cool so i decided to cover it it reminds me of something i'd worked on a long time ago
so he works with computer vision and now this is not just about i think this is useful beyond
computer vision which is why i'm covering it but especially for computer vision what he has to work
with a lot is there's an image and you're trying to find all the people
and maybe the bicycle or all the cars and the things the car needs to worry about if it's a
self-driving car right crosswalks lights whatever you want to put little pictures around it say the
computer vision and the ml algorithm said this is a car where is that duck over there that's not a
car right so you want to label them visually so
often what they do is they put boxes around them and they put some text to say this is a person
this is a car this is a duck and drawing those boxes with the picture with the like the label
lined up just right or affixed to the edge of the box or sort of an arrow pointing down to it or
things like that you know kind of tedious so he wrote a thing called Bbox Visualizer, which lets you just say, here's a image file, like a PNG.
And here is the coordinates of this box and the label I want you to put on it. And boom,
it draws like a nice fancy little box around the object that you talk about and puts a well-oriented label on it.
So if you're doing any sort of science stuff or image analysis where you want to put, like, here's what the computer thought is over here,
and here's what we're calling it, you know, for all sorts of analysis,
this is a handy little library.
Yeah, this is cool.
Yeah.
Not everyone's going to need it.
You don't need it for, like, a fancy web app or whatever.
But I think if you're trying to do this kind of work, here's a super simple two or three lines of code.
Put a nice bunch of bounding boxes on top of things and pictures with nice labels. That seems cool.
Yeah, I can also see lots of different student projects where they're working with images and algorithms around it
to be able to highlight a particular area that they're working
on or something like that i think uses for sure i can see a lot of science that are doing it like
we just we detected this as a star here this is a star here's the name of the star or whatever yeah
and to just sort of lump all of the drawing the box stuff into a library this is cool like it yeah
for sure you've got some nice fancy code examples like taking your
python code to the next level that tells about the next level i was debating as to what i've got a
like a devilish streak in me i think as to why i'm bringing this in this also was another listener
suggestion my apologies to whoever sent it i forget i think it's a gist, a GitHub gist, I'm pretty sure. And it's how to never use lambdas.
So I'm like just chuckling even at the name.
It starts off with a brief example showing how to rewrite a power function as a lambda.
And, you know, anybody sort of familiar with lambdas, that's kind of a common use case is
I've got a little like a single one or two argument function that I need to
pass in as an expression instead, and I can't pass in functions
so I pass in a lambda as it's kind of a bound function
sort of thing. Right, I want to do a sort on a list, and I want to sort by
all users, I want to sort by their login date, so
lambda u goes to u.loginDate.
Something super simple like that, right? That seems good.
And anybody scared of lambdas, if you look at
the initial example, that's a good
simple thing. They're not scary.
They're just basically functions without names.
But they have to be expressions.
So, first one, no problem.
But then he jumps right into
some crazy code. I'm saying he. I don't know
who wrote it. But the crazy code right away is some code with import statements. So how do you get around import statements? Well, you somehow it's using a dunder import and referencing the library you want to import as an expression passed as and the value of that passed as an argument to another lambda. And these are nested lambdas.
So right off the bat, first bad example is horrible.
So don't do that.
This is almost like a decorator lambda thing.
It's so weird.
Yeah, it starts off frightening.
And then it shows an example of a class definition.
And then how to lambify a class definition and then how to lambify a class definition as yeah so you can have a
lambda expression be an entire class definition weird and then the last example which is my
favorite is an entire working flask application as a single lambda expression it's truly horrible
stuff you should not do this but it's amusing to read about. Well, if your goals have fewer lines of code,
like one line for an entire Flask application, that's impressive.
I think it has two routes, not just one. Impressive.
Yeah, it's great. Cool.
Sometimes these, like, let's see these ideas taken to extreme are pretty interesting
and definitely that's the Lambda equivalent there.
Now, one good use case of this, I think, maybe I might get struck by lightning by suggesting this, but if you're in, if you've got a CS student and you're doing really good, you've got like 110% in the class, maybe turn in a homework assignment that's just entirely lambda expressions.
Or if you're just feeling really mischievous and you get some homework assignment you're super frustrated with,
you're like, you know what?
You're going to ask me to do something silly,
and you said, as long as it works, it counts.
You're getting this back.
Anyway, yeah, I'll probably get hate mail for
that so sorry what's not mean is contributing to oprah's source generally yeah that's not mean
that's nice yeah so alexander one of the listeners sent over an article or blog post by vincent
wanderman and it's called uncommon contributions making an impact without touching the core of a
library i think this is one of the challenges, paradoxes
that you might run into is like,
you find these libraries that are very popular
and you love them and you want to contribute to them.
Like I love Django, so I want to contribute to it.
I love Flask, I want to contribute to it.
I love requests, I want to contribute to it.
Well, guess what?
All of those things are highly polished
and they have a lot of different use cases.
It's very hard to make changes to them because any little change will have a potentially huge effect on a lot of software.
Right. And it's also just intimidating to touch the code for a large project, too.
Yeah, exactly. So here are a bunch of ideas of things that are low danger, low stress.
Probably a lot of people haven't taken advantage of them.
I'll just go through a couple
that vincent works through one of them is just providing better information so he contributed
to this project called rasa and i don't know what rasa does i forgot to check out so it's it has a
cli uh you say rasa you can say rasa dash dash version and what it would say would be like 1.2.7. Okay. That seems totally
legit. Like that feature is implemented. Right. But then, and by the way, if you look at this
article, if you open up the actual article, Brian, you'll see like each one of these has like a
beautiful, like XKCD style picture talking about the story. So for like the info one, it says
to debug this, like somebody says, Hey, Rasa is not working. Like for like the info one, it says to debug this,
like somebody says, hey, Rasa's not working.
Like, all right, well, in order for me to debug this,
you got to give me your Python version,
your operating system,
all the versions of the packages that you have.
Like, are you running out of a virtual environment,
et cetera, et cetera.
So what he did was said, all right, when you say dash dash version,
now you're going to get the version of Python,
the path to your virtual environment,
the version of related packages that Rasa depends upon, things like that.
Nice. That's easy to do. That's not a challenging, too
difficult sort of implementation there. The next one is to
set up a cron job to run tests
checking the dependencies haven't affected a package.
So I know you know about continuous integration, right?
Check in, changes come,
you're going to rerun your unit tests.
That's great, right?
But what happens if an underlying package
has an underlying dependency?
So the dependency of the dependency,
is that a grand dependency i don't know
underlying dependency has a change that potentially makes something operate differently
what is going to trigger your ci if you don't make any changes to your code there yeah right so
he actually ran into this uh scikit-lego is a package that vince works on and he discovered that it wasn't
working for some reason because scikit-learn introduced a minor but breaking change so what
he set up was a cron job with github actions to just run that once a day to say hey just in case
something which we don't know about or you know directly affects our repo we still want to run
those tests again just to
make sure like yeah things are still good yeah what do you think that's good and i also wonder
if the breaking change was that they changed what the version output produced yeah i did think about
that actually like if somewhere in there there's like a test you know someone has something that's
just test that calling that on the command line all right spell check spell check is easy oh yeah there's always spelling yeah like in code always
yeah because a lot of times the symbols we use are not proper words but i do really appreciate
things like pycharm that will they'll find misspellings inside of various things right
like if you've got a function check login and i and
inner switch it'll say login is a misspell but you know it's still or grammar checks grammar
checking people's doc strings or comments in code and stuff like that exactly so there's a nice
example in there about looking for a country i think where it was spain but spain was misspelled
or you know as a docstring
example. So that's definitely something easy to do. Just run a spell checker on the docstring.
One that I'm a real big proponent of is having better error messages.
Oh, yeah.
So it's so frustrating. Like just today, yesterday, I don't know, I was asleep. I'm
not sure exactly when I got this, but I got a message from a student taking the Excel course.
It says, hey, I tried to run cookie cutter.
Because during the Excel course, we talk about setting up a cookie cutter template that gets everyone started.
It says, I tried to run cookie cutter, and it didn't work.
Here's the message.
And it just says something about the Git clone that cookie cutter internally tries to use failed.
And it doesn't say anything about, you know, is git not installed?
Did git, what was the error from git?
Like it just, nope, it failed.
Right.
You know, just like a random, like this command failed.
Like, great.
So if there was a better error message, like we tried to do that, but you don't have permission to write where you tried to clone this thing to, or Git is not installed or something like that. They could
have gone, oh, I need to install Git, right? They would have been a much better op. So error messages.
So they work on, Vincent works on something called Whatleys and it allows for optional dependencies.
Like it has some of its functionality, but you might have to pip install what leaves bracket something else like here's TF hub.
And in order to use a certain part of that that depends on that optional dependency, you have to have that installed.
But you don't have to install it to use the library.
So you could run into this problem where you try to use a feature that doesn't have a dependency.
Yeah.
So instead of just going, none object has no attribute, whatever, right?
Or whatever's going to happen there.
Or no library such and such.
It's now the error is, in order to use convert language, you'll need to install pip install whatlies bracket tf hub.
See installation guide here.
And there's the URL.
Like that is a proper error message.
That's great.
Telling people how to fix the error.
Yeah.
And it's not that much work,
but just finding these problems,
like how many times does this appear on Stack Overflow,
rather than just let him go find it on Stack Overflow
and give the message.
So I recently added something like this to Fluent Check.
Remember when we talked, I think you brought this up,
talked about using raise from on an exception.
So you could say raise an exception but if you do
that in a catch block you get weird other issues right so by default it would say something like
during the handling of the above exception another exception occurred and that sounds like one thing
broke another but like in this library it's supposed to find errors and then report them to
you so if you use raise from it'll say the above exception was a direct cause of the following
exception which makes it sound like okay this is this is the source of the error right so just
simple changes like that are really nice get better error messages failing unit tests and i'm not
talking about going around and finding projects that have failing unit tests,
but rather if you want to make a contribution or you rather you find a bug rather than just
submitting a bug on a GitHub issue tracker saying this doesn't work.
I tried it.
And then having a long conversation about it, submit along with it, a failing, create
a PR that has a failing unit test for that issue.
Oh, that's awesome.
Yeah, right.
Just go, look, it's supposed to do this.
This fails.
If you can make this pass, I'm happy, right?
And then they can fold that into the unit test suite and so on.
And then also, finally,
there are some packages that might have names
that result in import statements that are very confusing.
So for example, if you've got a package,
and in the package, there's a So for example, if you've got a package and in
the package, there's a file.py, lowercase f, and within file.py, there's a capital file class that
those would be totally reasonable. What you can call the file is file.py, create a class in it.
Depending on how the package is set up, you could set up with, end up with something like
from package import, lowercase file, and from from package import uppercase file would both work, but obviously don't mean the same thing. So in that case, they recommend
like renaming certain files that are really meant to be used internally as an option.
Yeah. Like in the example, I don't even get what's different.
I know. I just stared at it for a while as well.
That's it for all those recommendations, but I think there's definitely some good ones in there. I like the error messages
a lot. I like the failing unit
tests as well. Those
are my two faves. Yeah, I was just even
thinking about all this stuff.
Did it talk about documentation? Not about
creating documentation. Just about the
spell checking within documentation.
Okay, well I would probably... Well,
I guess that's doc strings. That's pretty limited.
I'd add documentation to this
because projects always are lacking
or sometimes behind.
So the documentation might be great.
Somebody was really gung-ho about it for a while
and then there's been improvements,
but the new features just haven't made it
into the documentation all over the place yet.
Yeah, or tutorials.
There's no good tutorial showing this part of code.
There's maybe a quick start, but then the advanced hard stuff,
there's no examples.
Yeah, definitely.
Alright, cool. What extra you got for us?
Well, I just learned about this this morning, so
I was going to just not give a
whole big thing, but just let people
know. I saw somebody on Twitter,
of course, obviously
being really bad about referencing people, but sorry. A new thing,
as of September, early in September, there was a
collaboration between the people who do Wonder Woman
and the Smithsonian Learning Lab and NASA and Microsoft.
We're linking to an article that's Learn to Code with Wonder Woman,
Smithsonian, and NASA.
And so there's a whole bunch of ideas that there's one, there's a lot of schools that don't offer computer science education.
And also with COVID and everything, some people have kind of, that's kind of dropped off a little bit.
And people are focusing on core classes, which is probably fair.
But if you still want to have your kid learn programming, this might be a way to do it.
And this is pretty cool and looks pretty neat.
There's some Wonder Woman adventure stuff and NASA exploration.
And there's even a little bit of Minecraft in there.
It looks really fun.
And at least some of the tutorials are in there. It looks really fun. At least some of the tutorials are in Python.
I haven't checked out to see if all of them
are Python or not, but there's a lot of Python
in there. Some of them use Blocky, but some of
them, like the Super Quiz
from Wonder Woman, uses
Python. And then some of the
NASA ones, which Cecil actually called out the
NASA-Microsoft partner
ones last time, but
not the Wonder Woman one.
So yeah,
it's a mix,
but very cool.
It's neat.
Plus I got a lot.
I can't wait to see what,
see 1984.
I'm looking forward to it.
Yeah,
definitely.
I have a quick thing as well.
I'm going to be doing a presentation at IndiePi.
So virtual online,
obviously.
When is this?
This is coming up on october 13th so there i'm going to be doing a
python memory deep dive both like understanding some of the internals of python memory as well
as some optimizations that you can make to go faster and use less memory so you all can sign
up for that and check it out if you like a memory talk and you forgot the date. That's funny. Yeah, I know.
Maybe we should just have another joke.
Finish it off.
You know, I think we actually may have covered this a long time ago when it came out, but I'm not sure.
I don't remember covering it.
So it was suggested by Tim Jacobson.
Kelsey Hightower's project, NoCode.
This is a hilarious repo, but you kind of have to go look at it.
So the tagline is,
no code is the best way to write secure and reliable applications.
Write nothing, deploy nowhere.
And you highlighted that the style guide was good,
so I went and looked at that.
It says, no code style guide.
All no code programs are the same, regardless of use case.
Any code you write is a liability.
Yeah, this is beautiful the style code
a guy talks about file extensions says no code is store is not stored in files but if you must
use the dot no file extension like example main dot no there are linters built right into your
posix based system your linux systems so for, you can check by saying du-h
space main.no
and if it outputs
zero, then you have no code.
What is du?
It's like a line count, count the number of lines
of text in this file.
And then they have code
reviews. The no-code community
has adopted the following conventions
for reviewing code changes. When the code changes contains no code community has adopted the following conventions for reviewing code changes
when the code changes contains no code additions or modifications lgtm looks good to me when the
code changes include code additions or modifications cial code is a liability
they should be that code change should be rejected immediately And then the final kicker for me on this one is that there's 43,000 stars,
4,000 forks of it, which are funny.
But the thing that made me laugh
is there's 368 people watching for changes
in the no-code repository
where there's supposed to be no changes.
That's funny.
And there's 3.
Oh, it addscker support as well
2 000 issues filed against it oh my god there are what are they here for
oh yeah suspended arctic code vault contributional reconstruction aviator chain
generator keys all right no water in the water cooler is one of the issues
this is and then the contributing at the end of the readme says contributing.
You don't.
Sweet.
All right.
Well, that's a good one, Tim and Kelsey.
Nice job on that project.
Well, thanks a lot again for a lovely podcast.
Thank you for listening to Python Bytes.
Follow the show on Twitter at Python Bytes.
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 Ocken, and on behalf of myself and Michael Kennedy, thank you for
listening and sharing this podcast with your friends and colleagues.