Python Bytes - #348 JavaScript in Your Python
Episode Date: August 15, 2023Topics covered in this episode: Differentiating between writing down dependencies to use packages and for packages themselves PythonMonkey Quirks of Python package versioning bear-type Extras Joke ... See the full show notes for this episode on the website at pythonbytes.fm/348
Transcript
Discussion (0)
Hello and welcome to Python Bytes where we deliver Python news and headlines directly to your earbuds.
This is episode 348 recorded August 15th, 2023.
I'm Michael Kennedy.
And I'm Brian Akin.
And Brian, this episode is brought to everybody by us.
I think you might be making a more concrete case for that than other times today.
So, but yeah, check out all of our courses, books, things like that. It genuinely
makes it possible for us to do this kind of stuff. So yeah, we love doing it, but yeah, also. Yeah.
Yeah. Also. And if you want to be part of the live show and you're not watching live now,
Tuesdays at 11, I don't buy set FM slash live all the details there, right. And let's kick it off.
What's your first item. I actually it's, I'm kind of on a packaging, a little bit of a packaging thing today.
Okay. Okay.
Brett Cannon wrote an article called differentiating between writing down dependencies
to use packages and for packages themselves. It's kind of a big title, but here's the idea.
And I've been thinking about this also. So I really, there's requirements dot text files. And those are often used for applications. And then there's, but this that was, that was really when we had like, that was either that or setup dot pi for packages. And now we have pi project dot tumble. So can't we just use that? I mean, I kind of want to, but it doesn't quite work that way.
You install dependencies with a PyProject.toml by installing your package.
And you can install it like pip install.e.
I think, Brett, yeah.
Pip install.e.
Dash e, right.
On the current directory, or you can give it a local project directory.
And you can even do optional things like optional test dependencies and stuff.
And I think when you do the dash E,
it installs your optional test dependencies also,
I'm not sure.
But, and I'm used to that,
because I do packages also,
but we still have the requirements.txt file.
There really are for different things.
So Brett talks about this a lot in here. And
looking at why there's a there's a thing called like project dependencies. And the project is
really meant for packaging, it's really meant just for pack the whole packaging system so that so
that when you when you install something, install a wheel, it knows how to get packages for it.
That's it.
It's not supposed to be for applications.
So really, that's kind of the discussion around here, around this article.
However, there's a couple ideas.
He also references back a Donald Stuffed article from 2013 about setup.py versus requirements.txt but like i said that was
setup.py that we that maybe we could do something better brett's uh consideration is maybe um maybe
we could have some standard uh uh something some other file that we could have um i personally i
have a uh i think that maybe we could expand pipe project.toml.
I really like the toml thing.
So maybe we could either have a requirements.toml
or maybe we could have like,
instead of a project section of the toml file,
maybe we could have maybe an application section.
Maybe that would work.
Yeah.
So yeah, I think like a, like a dev requirements,
even just in the pipeproject.toml
seems pretty straightforward to me.
Yeah, I mean, I run into it in other places too,
like just in a Git repo that has like a couple Python tools in it
that people can install on their own,
but they might have some requirements.
How do you list those? Do you stick them as applications?
I mean, requirements.txt is normally the thing that's used for, like, Django web applications and things like that.
So maybe requirements.txt is fine, but I think...
Perhaps.
What I have is I have, for my world, I have requirements.txt, which is, like, for the web apps and stuff.
That is what is required for the app to run.
Without that, you can't make it go.
Then I have requirements-dev.txt.
I've seen that pattern a lot.
And then to actually generate those,
I use pip tools and pip compile.
So I have requirements.in and requirements-dev.in,
and then I can auto-update all the dependencies
and keep them in sync.
That's how I do it these days.
But now even people with like a Django or,
you know,
other things are using a private private project tunnel also to,
to store like their black settings and things like that.
So,
yeah.
Yeah.
We're kind of using project tunnel,
the pipe project tunnel for more things.
And I think maybe we could extend it for this.
Anyway,
that's my hope.
Yeah. So anyway, what do you got for this. Anyway, that's my hope. Yeah.
So anyway, uh, what do you got for us?
Well, let's, let's monkey around a little bit with the Python
monkey, with the Python monkey.
That's good.
That's cute.
It is.
So this comes to us from created by will Pringle, I believe amongst others.
Let's see on the contributors here.
Um, there, yeah, there we go.
Yeah.
So a bunch of folks that work on this project, it's not super popular with only 276 stars,
but I think it might be a pretty darn interesting compatibility layer for Python.
So what do I mean by that?
So imagine I I'm, you can look at this from two perspectives, So don't scoff at one if you prefer the other.
So imagine I'm a JavaScript developer
and I've got a ton of cool JavaScript code
that not just for the web front end,
but, you know, kind of in the Node.js sense,
like a bunch of utilities or a bunch of libraries
that work and do certain things, right?
Yeah.
But I also have a Python app
and I'd like to somehow use those together.
So Python monkey is a straight way to put it.
It, it basically hosts a JavaScript, a full-on high-performance JavaScript
JIT compiled to almost native performance JavaScript engine inside of Python
through pip install.
So if I wanted to use some of the javascript code i just write my python
application and for that function or that functionality i just import the job you know
first spider monkey or python monkey and then i import the javascript files that you would use
and then you just call them like python functions. Okay. Or reverse, I'm writing a Python application
and one option to make slow loops go faster
would be to write that in Cython
and Cython is getting better with the Cython 3 release
that we discussed already in the previous episode.
But JavaScript, because this thing,
the spider monkey JavaScript engine
is the one that I believe Firefox uses,
does JIT compilation to native code. It basically is near native performance as well. So if you'd like, you could
rewrite that part in TypeScript or JavaScript and run just that section. And it uses things like
shared memory between JavaScript and Python. So if you've got like a string or a list, those are the same objects, which is pretty
crazy. Wow. At least for the strings. Okay. So let's look at some examples. There's an article
by Will and no, I will not log into Medium. You're partially evil. Okay. So here's an article by
Will here. So let's look at some code examples. Alright, so import Python monkey as PM,
and then you say PM eval and give it JavaScript code, and then boom, it runs that that's one way.
What you can do maybe is more interesting is look at this, I can say em.eval and give it an
anonymous JavaScript function. And then what comes back not evaluating it, but just the thing to
define the function in JavaScript, okay, then what comes back is an object that itself is a function.
Okay.
So that's pretty cool.
Yeah.
Like, and hold on, there's two parts of this.
So I've got a, I've created a JavaScript function that's jet compiled in spider monkey through
this eval.
And what the, I didn't say this part, what the function takes is given a function, it
will call that function passing hello world to it.
Okay.
The string hello world.
Okay.
So what you do is you get the function back as a Python function and then they pass print.
It somehow proxies the print function into the JavaScript space and then JavaScript calls the Python print, which then comes back to the console, to the terminal.
Wow. Okay. That's some deep integration, right? back to the console, to the terminal. Wow. Oh, okay.
That's some deep integration, right? That's some pretty wild stuff. Let's see,
what else can we do here? This is pretty interesting. I can say, given a JavaScript
module, like I described, I can, you know, here's an example. It has a say hello export.
Then you can just say pm.require that JavaScript module. And now you've got all the
function, all the export behavior from that JavaScript module. Right, which is cool. Yeah,
there's there's some more examples in here. The other angle that's pretty interesting,
there's two more angles that are interesting, because it uses spider monkey and spider monkey
is awesome with WebAssembly allows It allows you to run untrusted
WASM code from languages like
C, C++, and Rust.
You can now basically do
any, you can call any
WebAssembly code as well that you'd like
inside of your function.
Yeah, it supports things like
async and await, using the async and await
keywords to handle the
callback nature of JavaScript,
like the dot then type of deferreds and different things. So you can just async and await those
behaviors, right? Just await a WebAssembly call, which is pretty excellent. Yeah. So there's a
bunch of examples, some pretty cool graphics here with Spock and Captain Kirk going, my mind to your mind, my object to your dicks,
your dicks to my objects. It's pretty awesome there. Another angle that is worth considering
is this allows the entire Python data science stack to become accessible to JavaScript developers.
Right? Yeah. So if you want to use, you know, the machine learning stuff, if you want to use pandas or Polars, right, you just write your code and then,
you know, do the integration here and yeah, that's, that's pretty much it. Um, it, it
finishes with, um, some funny little pictures here of, uh, uh, Noah on the arc, got a Python
and a JavaScript, which looks like a penguin. Then it has the Python monkey. What is that?
What the heck is this?
All right.
Anyway, that's Python monkey, which is, I think, potentially interesting.
With the WebAssembly and stuff, you could potentially have, like,
every other function in your system be implemented by a different language.
I'm bored of C, C++, Rust, Go.
What else do we want to write it in?
Yeah, why not everything?
Just make sure that your application
is only maintainable by you.
Exactly.
Do you know how many compilers you need to do this?
No.
That's kind of fun to joke about,
but this does look pretty cool.
So, yeah.
Yeah, it does look pretty cool. So, yeah. Yeah, it does look pretty cool.
So, you know, congrats to the folks there.
Maybe it'll go somewhere.
We'll see.
It's pretty interesting.
I think also it's worth noting that there is somewhere in here that there's a comparison to other things.
So this apparently is not the only time such a type of creation has been attempted.
So it says there are other projects that already do JavaScript and Python,
such as JS2Py, PyV8, and Metacall.
But there's a bunch of different drawbacks or stuff.
This is why we created it, basically, in addition.
So JS2Py is implemented entirely in Python, which sounds awesome,
except, you know, V8 and SpiderMonkey compiled in native code
and run ultra fast, whereas, you know, if you you know he's running Python it probably doesn't have any of
those things right yeah pi v8 has a wrapper around Google's v8 JavaScript
engine which is great but it's just super low level you just like talk
directly to the JavaScript bits which for things for example doesn't have a
sink in a way and finally medical is ext embeddable, and interoperable,
but you've got to install a bunch of different runtimes outside of just pip install.
So anyway, people are going, but it exists.
It does, but this apparently is why it exists like this.
Yeah.
Cool.
Yeah, and John out in the audience says, I do this, but going the other way using transcript.
Okay.
Interesting.
Something new to check out.
Thanks, John.
I'll take that out.
All right.
Over to you, Brian.
Well, just one more thing.
Alvaro says, Python monkey perfect for works on my machine certification.
There is an official works on my machine certification.
I know we talked about it before.
It's glorious.
It comes with a sticker.
Power your application code.
Getting the latest version of any recent changes from other developers is purely optional and not a requirement for certification.
Launch the application.
Cause one code path in the code you're checking to be executed.
The preferred way to do this is with ad hoc manual testing.
You can omit this step if the code change is less than five lines
or if in the
developer's professional opinion, the code cannot possibly result in an error. Check your code in
diversion control. You're certified. Yeah, there we go. Two jokes in one episode. How about that?
Awesome. Well, we got a little bit more, a little more humor to add to it. So because
I thought it was a serious article. It is, it's just funny and weird.
So Seth Larson wrote quirks of Python packaging, versioning package, Python package versioning.
That's it. So we're used to, well, we're kind of getting used to the world where we all have
SemVer like 1.2.3 and for semantic versioninging but we also have calendar versioning like 2023.6.1
and then there's stuff like you can add a pre-release suffix and things like that but it
gets way weirder and fun um so uh and i have noticed this especially with github like get
github versioning sometimes people will do uh v versioning so there's v prefixes you can do
and some i guess you can pull that into your uh your python application version as well why not
um so v versions are allowed uh epic versions did you know about epic versions i just learned about
this i don't think so so it's um you can you can can have an exclamation point separating your epic from the rest of your version.
So this is, so like one bang 2.0.0 would be epic one version 2.0.0.
I got to tell you, I already had a hard time deciding when the two or when the middle zero or the last zero changes.
If I put a number in front of an exclamation point, I'm going to just lost.
Yeah.
Apparently.
Too much decision.
Too many decisions.
Apparently some systems use colons for epics, but Python chose, this is all based on Python
PEP 440.
And the, yeah, apparently we chose the bang symbol or is that's bang, right?
The exclamation point.
So, and that just kind of looks like a one.
If you did one bang one, that would be hard to tell.
Local versions.
And is you can, you can extend after you have versions,
you're going to have alpha numerics and other stuff.
Like, you know, your plus,
I don't know if the plus is part of it anyway.
So after your normal
version like 1.0.0 he has an example of plus ubuntu dash one um this gets normalized but uh
but uh and like but this is kind of nice for local it's local versions because pipey i doesn't like
it so pipey i will not let you push up local versions guy, which is probably right. Local
builds long versions. Apparently you can use the use the first 217 digits of pie and that
works fine. As is one of the digits. There's no limits case insensitivity. So yeah, okay,
that's fine. It gets normalized lower or something so that you
you know capital rc1 is the same as lowercase rc1 that's that's appropriate um so pre-release i've
seen i've actually used pre-release post i don't know if i use pre i've seen pre and i've used
post-release occasionally although it's so weird that people don't understand what's going on.
So I don't do that anymore.
But apparently pre, post, and dev
are not mutually exclusive.
You can have all three allowed in one version.
Why would you do that?
So, and yeah, no delimiters needed.
There's just a lot of fun here.
So implicit hyphens are allowed.
So this is both the serious and non serious.
Oh, implicit zeros are weird.
So you can you can if you have version 2.0.4, you can just keep adding a bunch of points
0.0.0.
And it works fine.
It resolves to 2.0.4.
That's awesome. I definitely need to advertise some version,
say just pick up 2.0.3.0.0.0.0.
Yeah. Makes it sound tough.
Yeah, I mean in releases we've had.
Anyway, totally fun articles. Thanks Seth.
Brian, do you hear that?
No.
That's the sound of a million regexes dying.
That are supposed to be scanning for the version string in your code.
Yeah.
But maybe that's why Python just has it as a string.
If you do dunder version equals, it's just a string.
Yeah. Axel asks, if you use C++ compiled code, so I guess native code that's not part of
just source-only Python, is there a way to define which compiler you use in the versioning?
Maybe that Ubuntu-type variant, that local version, but you can't publish that, right?
You can't push it to PyPI like that. But for instance, I'm not sure how this relates to the wheel naming,
the wheel download naming thing.
Yeah.
I'm sure there's some metadata you could put in there.
Like you can do dunder version.
You could just do dunder compiler and say print that out,
and it'll tell you.
But there's no standard that I can think of.
Well, there's the, there is the wheel standard.
I just don't remember where the link is.
But that's more platform based, right?
Than a compiler.
Oh, right.
It's not compiler based.
It's platform based.
I mean, the compiler's got to compile to the platform, but it doesn't say like use GCC versus LLVM, Clang, Visual Studio, whatever, right?
Right.
Yeah.
And usually I'm just doing pure Python, so I have all listed, but the wheel.
Exactly.
So.
Exactly.
All right.
Well, with all that Python monkeying around, I could just barely stand it.
Oh, dear.
How about bare type?
Nice.
The bare metal type checker.
Okay.
So people know I'm a huge fan of types, Python, type hints, and all those things.
They're super, super empowering and make the editors so much more helpful.
It means you don't have to go into the documentation and go, what does this take again?
I know it takes an args here, but is args a dictionary?
Is it a class?
Is it a string?
Is it an, what is it?
Right? Like crazy stuff like that. Right? here but is args the dictionary is it a class is it a string is it an i what is it right like crazy
stuff like that right yeah so types are awesome for conveying that information without asking
her the docs or some other place to figure it out however what python type hints annotations
generally don't do as the word hint would indicate they don't require the hint you can use tools like
mypy and mypy will say the typing looks consistent or inconsistent
But regardless of what it says when you run the code whether or not the typing is consistent long as it actually still
Semantically valid it's gonna run even if you tell the types it takes a string
But you really pass an int and it did plus to it
But you know what you pass two integers and two strings and it still worked, right?
So the runtime version of typing in Python is mostly absent, right?
Excluding things like Pydantic and a few others.
So this bare type thing is a near zero cost,
near real time, pure Python runtime type checker
that makes runtime mismatches for typing runtime errors.
Interesting.
Okay.
So you can say, this sounds like a horrible idea and I will never touch it.
Please don't, you know, install the bear.
Or you could say I come from a static language and this dynamic typing
business is freaking me out.
Can we get a little closer?
Then you can have it.
I feel like this is the kind of thing that for little projects is completely
useless, but for huge projects, it may be, it starts to become more valuable, right? Yeah. So
if you just jump right into it, you pip install bear type, and then you can do things like, uh,
import the decorator and just put a decorator onto a function that has a type annotation or hint
right there like that. So here's one that says quote Wiggum, and then it passes lines in
the type declaration says lines is a list of stir, and it returns none. Okay, so then if you just use
this function, pass it a list of strings, it just runs, right? Yeah, if however, though, you pass it
a list of bytes, which kind of look like strings, but are not strings, you get an exception that says parameter such and such and such.
Well, it's a type.
And it gives you the actual index in the list.
It says list item zero with this value is not a string
because it's a B string, which is really bytes, right?
Yeah.
It's pretty cool, right?
Yeah, it is really cool.
And I'm kind of agreeing with Alvaro said, maybe, maybe running
with the test suite. And I was thinking maybe dynamically add these somehow. Use the ver types
during development and maybe maybe take them off later if it but if it's really fast, um, yeah. Yeah. I'll, I'll comment on that in a second.
Uh, there are also validators.
There's an is an annotated validator.
If you want to be more restrictive, maybe even then you might expect it's part of
Python, but it's not a commonly known part of the type and didn't think so.
For example, I could define a new type using annotated called list of strings.
Okay.
And it says it has to be a list of strings as one part of the annotation. And then another one is, well, it has to be a non-empty set of strings is what they're trying to create here.
Okay.
So it says if it's a list with a bunch of stuff, the bunch of stuff has to be strings, but it also contests that it's not falsy, which would be the case when it's a just, you know, zero length list.
So then you can annotate with that type.
And if you call with regular somewhere, you call it with regular code is fine.
But if you call it with the empty list where it says a list of strings, it says, no, no, no, it can't be an empty list.
It has to be a non-empty list of strings. So there's like some pretty crazy things that you can do here.
Yeah. Some other stuff you can check if you'd like, but yeah, it's, I wanted to read this
introduction article here, which actually comes after all the examples. By the way, it also,
in order to run this whole bunch of times, it took 33 microseconds, which is pretty incredible.
To test this for like an array of tuples of arrays of, what is that?
A million?
You know, 33 microseconds.
So that's pretty fast, actually.
Yeah, you still want to like compare it like your entire like some workflow compared to with or without
so yep so let me read this so if people are wondering what the heck is this bear type brings
rust and c++ inspired zero cost abstractions into the lawless world of dynamic typing
dynamically typed python by enforcing type safety at the granular level of functions and methods
against type hints standardized by the Python community in O1,
non-amortized, worst case time with negligible constant factors. How about that? So if anyone
asks what bear type is, there's a good description. Yeah. Well, yeah, it's pretty cool. And then
there's a whole bunch of stuff about it. But anyway, that's bear type. It looks pretty promising
to me. Like the drawback of a lot of these think really is like, well, now you're doing a bunch of checking
for every little function call
and it's super slow.
But if it's fast enough,
that's pretty cool.
Yeah.
So a couple of comments in the chat.
Mike Felder,
doesn't Pydantic include
call validators too?
So I'm not sure how that relates.
I don't know if that's out of beta.
Last time I looked at it,
it was still in like a testing phase. It may be out though. I mean, there I don't know if that's out of beta. Last time I looked at it, it was still in a testing phase.
It may be out now.
There's a ton of work that's happened on PyDantic.
It's all been redone, so I don't know the status of that.
Maybe Mike does.
Okay.
And then also, is there a MyPy plugin that does that?
I wasn't aware that MyPy could be used at runtime.
I wasn't aware MyPy could be used at runtime either but um perhaps
yeah anyway but anyway this this looks pretty you know quite straightforward pretty useful you just
do type ins you put app bear type on it and it it makes sure that it behaves yeah so trying to do
what you were looking at sorry to do where you might want to turn it off in production but run
it in testing which is reasonable i don't see any mechanism for that. There may be. Yeah, but it's a decorator mechanism, so you could work around it if you needed to.
Well, you could just write a decorator that looks whether that setting is on or off, and
it either returns the bare type wrap thing or the direct function directly, and it would
be like zero runtime cost once it's turned off because the function is replaced with
itself.
Yeah.
Otherwise, it's replaced by the bare type decorated one, right?
So you might have to write like 10 lines of Python.
Then you've got that feature, right?
The other thing is, how much of your code
are you really going to want to throw bare type decorators around
all over the place?
Yeah, that's a good point.
Maybe just the boundary, right?
Yeah, at the API level or something.
Yeah, exactly, exactly.
Yeah, cool. Yep, anyway, there it is. and i suppose that's it for all of our items that's uh what we got lined
up for you anything else uh extras i have you want me to go first you want to save yours or yeah you
go first all right i already got my screen up anyway okay so first of all congratulations mike
father who is right here in the audience.
Yeah, and I mispronounced his last name.
Sorry.
Hopefully I got it right.
You did.
I got it right.
At Mike, the man on Twitter is the new safety and security engineer for PyPI.
That's awesome, Mike.
Thank you so much.
Cool.
Clearly an area that needs lots of attention.
So I just wanted to say welcome.
Thanks for keeping us all safe out there.
And excellent.
Yeah, I got to hang out with Mike a lot at PyCon.
So that's really pretty cool.
Yeah, super cool.
Super cool.
And then a couple of quick announcements, two conferences for people.
PackagingCon, follow up on all of your items, Brian.
PackagingCon is happening fully online. No, hold on. for people, uh, packaging con follow up on all of your items, Brian packaging con cool
is happening, uh, fully online.
Uh, no, hold on.
No, it's happening in Berlin as hybrid.
So it's in Berlin, October 26 to 28 for all things, packaging, Python, people, rust people,
et cetera.
So, um, check that out.
And the cloud builders Python conf is September 6th, 2023.
That's put together by a ukrainian
group and it's just online so people can check that out as well and speakers are they still have
a call for proposals doesn't look like it i think it's open it's already all set for the um agenda
so people can check that out it should be fun uh and on onto your big news. Okay. Well, a couple, just a couple
notes that I wanted to mention. The August release of Visual Studio Code has something I've been long
awaiting. It's an error tolerant PyTest discovery. So what does this mean? It means you've got,
and there's like some comments down here. Oh, went too far. You have to turn it on right now,
but it's just in a setting.
Apparently some people have it on by default.
Anyway, they should just turn it on, it's better.
But the gist is if you've got like errors
in some of your code, it used to just blow up.
Like let's say you've got a test suite,
but you also have like some old junk tests
off in a side directory that you don't use anymore.
If they had import errors or syntax errors or whatever, it would just blow up the whole thing and you couldn't get any tests to import.
Now it's tolerant and it just turns off the, it doesn't import those tests that have import errors.
That's great.
So you can still run the rest of the suite.
So that's good.
Be kind of still kind of cool.
There's a couple of things.
Be kind of cool if it could tell you which ones have had errors instead of just making them disappear.
So that'd be neat.
The other thing is, guys, PyTest isn't capitalized.
So you got to work on your capitalization, non-capitalization.
Anyway.
But discovery probably should be.
Oh, yeah.
Oh, yeah.
Discovery should be.
Oh, that's all right. Oh, yeah. Discovery should be. That's all right.
That's tough.
Anyway.
I'm always unsure about my capitalization.
It's so formal to capitalize everything.
It's this time of year again.
We got Python 3.12 release candidate one.
So we're in the release candidates for Python 3.12.
It's pretty exciting.
Release candidate is a big deal though, right?
We think this is the final version unless there's something gone wrong.
Yeah, it's right out of beta.
So anyway, speaking of beta, the big news for today is that I've got a Python testing with PyTest bundle course up.
And I'm super excited about it.
I'm working really hard.
However, it is in pre-release beta.
I don't know.
I made up something.
Early bird.
Early bird, sort of.
Early beta bird.
Yeah.
So what is going on?
So in the end, it's going to be actually I wrote it. I included on here is a video that is got like, welcome to the pre-release right now that's for sale is a bundle
of all that will be all three. Uh, there's two chapters ready for, um, for the primary power for
the first part. And, uh, but I'm just going to chug along and, uh, people can jump in if they
want. I'm, I'm doing it as a beta because the book itself really is better because of the beta
program that I did when I was writing the book. And I'd love to have people come in and, uh, let me know where things need a little polish and we
can, um, you know, we can fix it along the way. I also am setting up a, uh, job or not a job board,
a discussion board for people to ask questions if they get stuck. Uh, I really want to make sure
everybody's successful
in getting this up and running,
getting up and running in PyTest quickly.
So totally excited about getting this done.
Oh, one more thing.
I set up, I just launched it last night,
but for Python Bytes listeners,
you can use the coupon code Python Bytes with a Y.
So, and we'll just throw that in the show notes.
Use PythonBytes with a Y and you can get 20% discount now through the end of the 17th.
So just a few days, but that's enough time to grab it.
So cool.
Yeah.
Awesome.
Congrats on this, Brian.
This will be exciting.
And I know it's a lot of work, so.
Yeah. Good luck. Thanks. Yeah, absolutely. Congrats on this, Brian. This will be exciting. And I know it's a lot of work, so. Yeah.
Good luck.
Thanks.
Yeah, absolutely.
Oh.
You know what else is a lot of work?
And ties back to my first item, learning JavaScript.
Let's make that our joke.
Okay.
All right.
So here's a text.
It looks like a WhatsApp conversation that somebody got, unfortunately, from their apartment manager.
And, of course, it's addressed to Michael which is extra funny hello Michael your apartment has received the
second complaint noise from the apartment is the problem the dog whines
apparently you leave one home and the dog gets bored please address this the
response from Michael is hello I don't have a dog. This is me learning JavaScript. Like screaming and yelling and kicking.
Oh, dog whines.
Okay.
Yeah.
That's pretty good.
That is pretty funny.
It could be like learning all sorts of programs.
It could be learning Python, but yeah.
It feels a little extra special.
A little extra special there.
Have you got your webpack working?
Have you got your requires working?
Have you got your transpiler working have you got your requires working uh have you got your transpiler working
yet man that was me with like trying to relearn css um so first time i learned css we didn't have
all these like pre-compilers and stuff um so css is a completely different ball game now so
yeah yeah well yeah it's crazy stuff cool well, this is my joke for everyone. We've received a noise complaint.
I'm sorry.
I don't have a dog.
Awesome.
Well,
it was a fun episode.
Thanks again.
Yeah,
sure was.
See you later.
Bye.