Transcript #338: Scripting iOS with Python
Return to episode page view on github00:00 Hello and welcome to Python Bytes where we deliver Python news and headlines directly to your earbuds.
00:06 This is episode 338, recorded May 30th, 2023. I'm Michael Kennedy.
00:13 And I am Brian Okken.
00:14 And this episode is brought to you by us, our courses and books and things like that.
00:19 Talk to you more about that later. Also connect with us on Mastodon or all over on Fosstodon @mkennedy, @brianokken and @pythonbytes.
00:28 And we love it when people join the live show.
00:30 If you want to be part of that, you can see the next scheduled upcoming one at pythonbytes.fm/live and click that notify me and YouTube and guess what, it'll notify you when it's live.
00:40 So that's the front matter, Brian.
00:43 I think we should start it off with some basics.
00:45 What do you think?
00:46 >> Yeah, let's go back to the basics.
00:48 Basics of Python packaging.
00:50 So actually this is something near and dear to what I've been paying a lot of attention to lately is packaging and just how it's changed.
00:59 And it's kind of in the most people have switched over to pyproject.toml now.
01:03 And that's really what this is about.
01:06 So when you're packaging, especially a pure Python package, one of the things I like about this is it's not just for pure Python, but that's the easy part.
01:15 If we're using pure Python packaging, you're probably using a pyproject.toml now.
01:20 And there has been several write-ups of it, but some of them are kind of tool-centric.
01:27 So I like this write-up from Jakey, not sure, that talks about just sort of the easy, a fairly standard setup.
01:38 So it does talk about the PEPs in this article, but you don't really need to know much about that.
01:45 You can just kind of skip to how do I do it.
01:48 So using the PEPs and using pyproject.toml, you do have to specify what your build backend is.
01:59 So in the top example of this article, it talks about using flit core, and that's one I've used a lot of that.
02:07 But then what else do you put in there?
02:10 So within the rest of the pyproject.toml is mostly metadata.
02:16 You can have other stuff too, like black and everything, but for your project building, the project metadata, there's not a lot that goes in it.
02:23 I mean, it looks like a lot when you just glance, but it's really, you know, it's your name, the name of the project, the version, description of it, your author, I will point out that this is not minimal because it includes the email.
02:36 You don't have to include the email.
02:37 If you don't want to, you can just put the name.
02:40 And where your license and readme and classifiers are.
02:43 The thing, one of the things I wanna highlight is make sure you have the license.
02:47 at the very least have your license classifier listed, because that's how the license shows up on the PyPI.
02:55 So when PyPI is looking at projects, it looks at the classifier.
02:59 And then, and try to throw in which Python's required, and then any of your dependencies that you're using, and then some links.
03:07 I mean, it's really, when you just talk about it as a stream of conscious, it seems like a lot, but it's really not that much.
03:13 And you're pretty much done.
03:15 you can do a build now with this.
03:18 This is--
03:19 - I think Brian, before you move on from that, that I just noticed that I really like, if you do like a setup.py, what you've got to put is like the readme and details and the descriptions and all those kinds of things, at least a long description, you've got to actually load the file and inject the content to the file.
03:38 And here you just put the file names for like the license and for the readme and it'll just pull those in, right?
03:43 That's cool.
03:44 It is one of the things I've harassed people about before, is it's weird that the readme and license are specified completely different.
03:51 So the license has this, like, what, curly braces, and then file equals license.
03:57 Dictionary-ish.
03:58 Yeah, it's a dictionary.
03:59 Whereas the readme is just a text string with the name of the readme.
04:04 It's odd.
04:05 I think that maybe we could have it so the license could just be a string with the license file on it also.
04:11 But anyway, there's probably reasons, I'm sure.
04:16 The thing that I also want to point out is you can put as many URLs as you want in here.
04:20 You can have like this example as homepage and bug tracker.
04:23 A lot of people just list home that lists the GitHub link, but you can have your documentation and other stuff.
04:30 And all of these show up in PyPI also when you're, if you're published to PyPI.
04:35 And if you don't want to publish to PyPI, One extra is to, that Kim reminds us of, is another classifier I learned about, is private do not upload, which tells PyPI to not upload it.
04:50 So this is all great.
04:52 And a lot of this, also, if you want to watch it in video form, is covered in the sharing is caring video.
04:59 It's a talk I gave in PyCascades.
05:01 The video is now online.
05:03 We'll put a link in the show notes.
05:05 But this document or this article goes through some of the different, make sure that you understand the build step of Python-inbuild is one way to do it.
05:15 There's other ways.
05:16 But then it talks about some of the discussion around why pyproduct.toml is there instead of setup.py.
05:24 I think we're all convinced, hopefully.
05:26 But then also some choices of backends.
05:28 So this article used Flick Core to start with, but there's also Hatchling and Setup Tools and Poetry Core.
05:36 So why would you choose different ones?
05:39 And one of the, and it's 'cause there's extra features.
05:43 Some of them allow extra tags to go in there.
05:46 And the example they're using, and that's one of the reasons why I use Hatch a lot, is you can have include and exclude things to say, you know, the normal stuff that you'd probably include in a source distribution, also add the tests, for instance, or something else.
06:05 The test is one that distributors, redistributors, like Linux distros, like to have your tests in the source distribution, so throwing those in there is a good idea.
06:16 I'm not sure why they're in there by default, but anyway.
06:20 Cool discussion.
06:22 One of the things I also love is it talks about what happens if you're not just Python.
06:27 What if you have to include C?
06:29 Well, it doesn't really discuss it too much.
06:31 It just points you in the right direction.
06:32 So if you have C or C++ extension, there's a scikit-build core that you can use.
06:38 I haven't tried any of these.
06:40 If you're into Mason, you can use Mason Python.
06:44 And then also setup tool supports it.
06:46 So there's a direction for that sort of stuff.
06:49 - Yeah, straightforward.
06:51 Back to the basics, I like it.
06:53 Definitely demystifies some of that.
06:55 Henry points out in the audience, license key will likely change via PEP 649.
07:01 And currently, Flit just ignores whatever you put there.
07:04 The true classifiers are the canonical location for the license.
07:09 So just FYI.
07:10 Thanks for that, Henry.
07:11 He always has such excellent extra information, background information.
07:16 - And we're so lucky to have some smart people show up on the chat, so thank you.
07:19 - Yes, absolutely.
07:20 All right, let's talk vectors.
07:24 So I wanna talk about VEX, And this project comes to us from Oli, who open sourced this, Oli Rice.
07:31 Now, before I actually tell you about what VEX is and what it does, let's take a step back and talk about the PG vector extension for Postgres, the database.
07:42 So this is an open source, because VEX has to like build on top of this.
07:46 So this is an open source vector similarity search extension for Postgres.
07:53 So you can do things like given a bunch of points in different dimensions, this could be X, Y, it could be X, Y, Z, could be, you know, temperature and time, I don't know, right?
08:04 It could be whatever you come up with.
08:06 It'll give you the exact and approximate nearest neighbors, allow you to query that, like given some measurement, what other measurement is closest, or give me the five measurements or positions that are closest to this, gives you L2 distance, it'll do the inner product and cosine distance, So different metrics, if that makes sense.
08:25 And any language with a Postgres client can speak to it.
08:29 It's pretty cool, right?
08:30 - Yeah.
08:31 - Yeah, so let me see if I can find some examples.
08:33 So I can say, get me the nearest neighbor by L2 distance.
08:38 And it says, the way you would do that directly is you say, select star from items, order by embedding, whatever the value is, is closest to, in this case, the vector value 3, 1, 2, and then limit five, just like you do in databases, give me the first five.
08:55 So order by closest to farthest, and then just give me five, that'll give you the five nearest, right?
09:00 You could do things like sort by distance, you can find exact matches, and you can also do other database things.
09:07 Let's see, like give me like where the ID is or is not equal to some value and so on, right?
09:14 So pretty neat.
09:15 Now that's the PG vector extension just for Postgres.
09:20 So you're speaking to it in a special flavor of SQL, sort of.
09:24 In Python, you can talk to this using this thing called VEX, okay?
09:30 So with VEX, you just pip install it, and then you insert a bunch of vectors, and then you can write queries that are more API-based, I guess, not just direct SQL statements.
09:41 So you give it the vector that you want to query against, and then, you know, like how many you want back.
09:48 If there's a filter to say, I only want the ones for a certain year, right?
09:51 Filter it down and then do that query based on distance or whatever.
09:55 So pretty cool.
09:57 If people are out there doing that kind of work, I think they might find this pretty helpful.
10:01 - Yeah, very.
10:03 Oops.
10:04 - It's not something that I have exact direct use for these days, but you know, a lot of scientific or geospatial type of things seem relevant.
10:14 - Yeah, I've been spending more and more time in SQL queries lately.
10:17 So anything to help with that is good.
10:19 - Yeah, absolutely.
10:20 Now, one final thing, it says in here, it says you've gotta have, I can't remember which one talked about getting Postgres.
10:27 One of them, yeah, this one says, if you don't have a Postgres database, see some hosting options.
10:32 And if you're on Mac, I just wanna throw out there really quick, postgresapp.com.
10:36 All you do for this one is, it's super awesome.
10:39 You download it, you unzip it or un-DMG, whatever its packaging format is, and it's just a postgres.app.
10:45 You double-click it, Postgres is running.
10:47 you close it, Postgres is not running.
10:49 It auto updates itself.
10:50 Yeah, so pretty sweet.
10:52 And it's open source too.
10:53 - Cool.
10:54 - Neat.
10:55 - Yeah, yeah, very neat.
10:56 - I'll be needing that very soon.
10:58 - Yeah.
10:59 Yeah, cool, check it out.
11:00 Yeah, that one's, that's pretty nice.
11:01 Okay, now before we move on, Brian, brought to you by us, this episode is.
11:07 So I wanted to remind people to, you know, please check out the brand new TalkBython training apps.
11:12 They're rebuilt for iOS and Android.
11:14 Really think it's a cool experience for a lot of people to take it.
11:17 It has offline playback and obviously way better on the mobile and tablet type of things.
11:22 And it comes with six free courses that you can just tap on and join the free courses plus anything you might've gotten.
11:28 So check that out.
11:30 And I wanna shout out your book or what do you wanna shout out today?
11:33 - Yeah, well, time is running out, but the book is still on a promo.
11:40 So Python Testing with pytest, there is, what is the promo?
11:46 It is spring 2023, all caps, all one word, and you get 50% off.
11:52 And it's just for like today and tomorrow, I think it runs out at the end of May.
11:57 But anytime you want it, there's a 25, that's 50% off.
12:01 But if you want to sign up and get to their email list, you can get 25% off normally.
12:08 So anyway, that's a good thing.
12:11 - Excellent.
12:12 Also really quick follow up.
12:14 Henry points out that it was actually PEP 639, not 649, typo there.
12:19 - Yeah, so 639 is improved license clarity with better package metadata.
12:25 It's in draft, but hopefully there'll be, it's in draft, really?
12:30 Anyway, some changes to how you specify the license, which would be good, so.
12:36 - All right, let's talk about plagues next.
12:39 - Plagues, like locusts and grasshoppers?
12:43 - Yes, exactly.
12:45 - Nice.
12:46 - I like these kind of plugs.
12:47 These are awesome tools.
12:48 - So I've used Locust before.
12:51 I think you've used Locust for--
12:53 - I love Locust, yeah, for load testing.
12:55 So good.
12:56 - So there's a company, AlterX, maybe?
13:01 Anyway, they've introduced Grasshopper.
13:05 So it's Locust Grasshopper.
13:07 It's a open source Python library for load testing, but it's built on Locust.
13:12 So what's the difference?
13:14 So we're linking to an article that discusses the introduction and discusses why they love Locust and everything, which is great, but they have a check, like Grasshopper, what does it add?
13:28 Well, it adds a whole bunch of really cool features that you might need if you're load testing and developing a package and keeping track of your load testing over time.
13:36 So it has these extra checks in here and checks, if I get this right, are things like special validation functions, Boolean functions that can run, and you can tell different checks whether or not they're passing or failing over time, which is based on--
13:53 - I see, the document had this text in it to make sure it wasn't insane in the response or something.
14:00 - Yeah, actually I'm not quite sure, so I'd have to dig into that more.
14:03 But one of the things I really like is these custom trends, which custom trends and timing thresholds and integration with pytest, of course, that's awesome.
14:14 Time series, database integration and reporting.
14:17 This all sounds great.
14:18 One of the things I really love that's talked about in the read me a little bit more is this idea of like tagging your test suite.
14:26 So tag-based suites, so you can see your load test results based on different versions.
14:34 So if you're tagging with using version tagging on your repo, you can see what the progression is and how well your application is doing based on different load requirements.
14:45 And you can have thresholds like with this load, you need to have like 90% the speeds of things.
14:51 The other thing is some speed thresholds like you can have multiple timing little functions that have multiple time, multiple HTTP requests.
15:05 So an action that really is like a user action often is several interactions, like how fast can somebody log in or something like that, or go through the checkout.
15:15 That's going to be a multiple sequence thing.
15:18 You can time that under load and under stress, and that's a pretty cool addition.
15:23 >> Or even to load this page, we're going to, it's probably some complicated JavaScript front-end.
15:29 So it's going to call this API and that API and that API just to load this HTML page.
15:34 >> Yeah, sure.
15:34 >> So you want to treat that as like the page is loaded when these seven API calls finish, right?
15:40 Something like that.
15:41 - Yeah.
15:42 - 'Cause they're not using HTMX like they should.
15:46 Also, nice shout out to sponsor there, InfluxDB.
15:50 So, pythonbytes.fm/influxdb.
15:53 This is the time series database that it integrates into.
15:56 When I looked at this, Brian, I'm like, yeah, but Locust is pretty awesome.
15:59 Why would somebody go create another one of these for the Python world when Locust exists?
16:04 And then I read it, it's like, oh, we've extended Locust.
16:07 "Oh, and here's why," and they give some pretty good reasons.
16:09 Another trend that would be cool, I don't know if you can actually measure it here, but it talks about custom trends is one of the things you can track.
16:17 Things like CPU load and memory load on the server would be really interesting, or maybe CPU load on the database server while we're hammering the web server.
16:29 If you could pull those kinds of things in, that would be really cool.
16:33 >> Maybe you can.
16:34 Yeah, maybe it's kind of get the sense that it might be possible, but I don't let's see then. Not sure.
16:39 But very cool. Yeah, this this looks nice.
16:43 It's definitely worth checking out.
16:44 Some of the check functions, you might be able to like abuse that for that purposes too.
16:49 If while it's while your load test is running, check CPU levels and stuff like that.
16:56 I don't know. Yeah, exactly.
16:57 So anyway, neat, neat project.
17:00 Yeah, that's a good project.
17:01 So Grasshopper, right?
17:03 Yeah, oh, one of the things that that they talk about in the I wasn't clear on it because I went and look at pipey I and looked for grasshopper and I found the wrong one. So it's locust dash grasshopper. So that's the that's the GitHub repos under that. And that's what you pip install also is locust dash grasshopper. So just to be clear, - Got it.
17:25 I wonder if it's like a super set, probably.
17:29 So if I have already written a bunch of Locust tests, could I run them or how easy is it to--
17:34 - I don't know, but I imagine it's not that bad to convert.
17:38 - Yeah, it looks like the code is super similar.
17:41 So worst case, you maybe change the base class, but possibly the base class is like derived from the Locust base class that you use for your test cases or test suites.
17:50 Yeah, anyway, I haven't played with it yet, but it looks cool.
17:53 - The readme's got tons of information too.
17:55 Good job on loading up the readme with lots of examples.
17:59 - Indeed.
18:01 And before we move on, Kim says, it could possibly hook into telemetry tooling like Prometheus, which would enable metrics from other servers and stuff like that.
18:09 Yeah, that's kinda what I was talking about, but not with actually concrete ways of doing it, like Prometheus, so cool.
18:15 - Neat.
18:16 - Yeah, and I wanna talk to you about something that is near and dear to this podcast.
18:23 We talk about a lot of topics, right, Brian?
18:27 - Yeah.
18:27 - And if you go over to Python Bytes and you pick a particular episode and you scroll through here, you can see it is chock full of links.
18:37 So one of the things you might wanna do, you might wanna say, oh, I'm listening to this.
18:42 I wanna remember not all of them, but just three things that I can come back to.
18:47 And if you're on your iThing, your iPhone, iPad, et cetera, or even on your Mac, technically, if you've got an Apple Silicon Mac, you can use this thing called MemoCast.
18:59 So MemoCast was created by Daniel Engvall.
19:04 It's interesting on its own, but it's also interesting in a way to kind of script iOS with Python, which I hadn't really thought about doing.
19:13 So first of all, let me tell you about MemoCast and then you can think how this might apply to you.
19:17 So this is a small iOS app that allows you to add links heard about in a podcast as a reminder, so you can check them off your reminder list, you know, the @reminder app when you're done with them.
19:29 So check this out.
19:30 Imagine, this is reading the website, imagine you just as often as I, imagine that you just as often as I do listen to a podcast such as Python Bytes, a fantastic one.
19:40 Thank you, thank you. - Nice.
19:41 - Using Google Podcasts, walk around, you know, you're doing it while you're out and maybe busy like mowing the lawn or something, right?
19:48 And then there's some thing talked about, you wish you had more time to check out.
19:52 Thankfully, the reference in the show notes, but you'd have to look it up and go through it and copy paste and all that.
19:58 So there's a little video here, notice this.
20:02 - Nice.
20:03 - On this page.
20:04 And it shows all you gotta do is say share, go to the podcast player, say share, click memo cast, and it gives it a second, then it has a list of all the links that it's discovered in there.
20:15 Isn't that cool, Brian?
20:16 - That is neat.
20:16 - I can't really zoom that without the, I can't really zoom it without the responsive design only making it smaller.
20:22 But so how is this possible?
20:25 The thing you share it to is you don't share it directly to MemoCast.
20:28 You say run in Pythonista.
20:30 And so this is a Python script that Daniel wrote that basically you run it through Pythonista, Python 10 on iOS.
20:40 It does a guessing request or something called over to our website and parses out all the links and then turns that into a UI that you can interact with.
20:49 Cool, right?
20:49 >> That's all done on the phone then?
20:51 >> Yeah.
20:51 >> That's pretty cool.
20:52 >> Yeah, it's pretty cool.
20:54 Basically, this is an example, supports Python by StockPython and RealPython as the three supported podcasts, but you can integrate new ones if you wish.
21:03 You install it once you have Python Nista, which I think cost $10 US one time.
21:09 But then you can install it, scanning the QR code here with Python Nista, and that will download it.
21:14 then you can just turn it into a thing that you can run.
21:16 It also talks about how you add new podcasts if you want to add a different one.
21:20 But that's somewhat interesting.
21:23 I think what's more interesting is he took this Python code, and the code is right here, to build a scriptable GUI for iOS, which I think is pretty cool.
21:33 >> Yeah, that is nice. Cool.
21:35 >> So talked about, I did try to do this with Kivy and other stuff, but let me tell you the build chain and code signing and all of that is like a nightmare.
21:44 And so here you just write a Python script and just run it inside of this app that already exists.
21:48 And final bonus before I call all the time on this one, Daniel also discovered that if you're on a Mac with a Apple Silicon, then you can run Pythonista as an iOS app within macOS. So you go to the App Store, search for it on Mac, and it doesn't come up, but then you click, say, show me tablet, you know, iPad apps, and then it'll come up. And then it integrates with your your favorite IDE such as PyCharm and you can run it.
22:15 So you can develop these little things on your Mac with a proper keyboard and everything, and then just deploy it to Python and Easter on iOS.
22:24 >> Yeah, that's pretty cool.
22:25 >> So yeah, people can check that out, MemoCast.
22:28 It's cool that it's about our podcast in this way, but it's also more cool that it just shows you how to take Python and leverage Python and Easter a little bit more than maybe I realized you could, like an OS integration level.
22:40 - Yeah, I didn't know you could do that.
22:42 That's cool.
22:42 - I did not either.
22:44 - Nice.
22:45 - And I guess before we jump out of here as well, Kim points out on Android, I have some but not tons of experience with, you can run Python code with QPython should someone want to emulate this for Android.
22:57 Thanks, Kim.
22:58 - Cool.
22:58 - All right, is that all of our topics, Brian?
23:00 - That is all of our main topics, yes.
23:02 - Yes, of course, 'cause we always have extras.
23:05 - Yeah. - I'm joking.
23:06 Any extras for you, though?
23:07 - Yeah, I can kick this off.
23:09 So just a few, a shout out from, oh, who wrote this?
23:16 I'm not sure.
23:17 Hugo. - Hugo Van Kimenad.
23:20 - Wrote, "Help test Python 3.12 beta." So 3.12 is in beta.
23:25 If you are a package maintainer or just your own application, you may as well start testing to make sure that you don't have any surprises.
23:33 So this article does talk through basically how to hook up your GitHub actions so that you're testing 3.12 also.
23:42 And then whether it's the official Ubuntu latest or the Dead Snakes version, a couple of ways to do it.
23:49 And then even if you're using Travis CI still, bye, anyway, you can do that with that as well.
23:56 So that's the first.
23:58 Secondly, I wanted to say that at the Python Software Foundation blog, there is a whole bunch of new articles.
24:06 They basically wrote up, There's articles writing up all the different things that happened at the Python Language Summit.
24:13 I haven't gone through these, they're just available.
24:15 Wanted to shout that out.
24:16 It's some interesting stuff though.
24:18 - There is, I just interviewed Brett Cannon over on Talk Python about this.
24:22 He gave us a walkthrough of all the presentations and thoughts at the Language Summit.
24:28 - Okay, and then from the news from the weird, I don't have much information about this other than on the Python Package Index blog, I say, "Hey, PyPI was subpoenaed, "and this thing happened, and we complied, "and talked to lawyers, and it's weird, "but it's just odd." - Yeah.
24:47 - So how about you, any extras?
24:49 - Yeah, I wonder if this has to do with some of the malware or cryptojacking--
24:53 - Maybe.
24:54 - Stuff that was uploaded to it, and they're like, "All right, we're gonna try "to track down some of these people." There are certain places that are not allowed to say whether they received a request, and I think this is not a subpoena, this is more of a, what is it, FASA?
25:07 like the more international crime investigation laws.
25:12 So we'll have a subpoena canaries, that it'll be like the canary will be here unless we are subpoenaed, then the canary's gone.
25:19 We won't say anything, but we'll just, this bird won't be on the page or something anymore, so you can kind of know.
25:25 But yeah, it's kind of cool there, they're being transparent about that.
25:28 - Yeah, one of the--
25:29 - #transparency it says right there.
25:30 - Yeah, and one of the things that was interesting is that they got asked for addresses, including mailing and residential addresses, but they don't collect that.
25:38 They just, I mean, that information isn't saved.
25:41 So it's not there.
25:42 - Yeah, I'm sure it's a form and like we would like this information.
25:45 Well, we don't have that.
25:46 So we'll give you what we got.
25:47 - Yeah, okay.
25:49 - Nice, all right.
25:50 I got a couple of real quick ones here.
25:52 Not Python needs one.
25:54 I wrote something called, "You can ignore this post." Trying to get a lot of attention, of course.
25:58 What it actually was is I just wrote about the github.com/github/gitignore repo, which has all, like when you go to GitHub and you say create a new project, and it says do you want an ignore file, and it gives you a list.
26:13 These are all the ignore files for every language supported there, including Python, which is in here somewhere right there.
26:21 And so you can actually see what they all are.
26:24 You could even do a PR, like we really need to start ignoring, you know, if there's a new file format that's like a build output of some new pyproject.toml tooling, and it starts to, you know, it needs to be ignored, you could say do a PR against this.
26:37 So every repo on GitHub starts to adopt it.
26:39 But also if you're doing say Python and front end stuff, you could go look for node and you could select one and then copy some stuff out of another to kind of create a combined one, right?
26:51 So you're not like, well, is it node or is it Python?
26:53 I really want the ignore for.
26:55 So anyway, that article is just sort of about that, really short, people can check that out.
27:01 - I use that all the time because I'm also on GitLab and GitLab doesn't fill those out for you.
27:07 - Oh yeah, I hadn't really thought about it, but you can nab it for other purposes as well, right?
27:11 - Yeah, yeah.
27:12 - And then someone on Mastodon pointed out you can do Knox Python ignore, and I think it'll generate that file for you and uses that as the backend.
27:20 I think, I think so.
27:22 Some of the Knox and some incantation will generate an ignore file for you.
27:26 - And if we have that wrong, somebody will correct us.
27:29 - They sure will, and we appreciate it.
27:30 And speaking of incantations, are you ready for the joke?
27:33 - Yes.
27:34 Okay, so here's the joke for developers.
27:37 It says, "Careful, or you might end up summoning a demon." And it has two categories, what you do in programming and what you do in demon summoning.
27:46 So first one is, "You must know a language unspoken by mankind." Programming, check.
27:52 Demon summoning, check.
27:53 "Requires that you be exact or suffer dire consequences." Programming, check.
27:59 Demon summoning, check.
28:01 "Involves much cursing, swearing of oaths, and pleading with a higher power programming check.
28:06 (laughs)
28:07 Demon summoning check.
28:09 Another one is not understanding the true power you wield or the consequences of your actions programming check.
28:15 Demon summoning check.
28:16 The only differentiation, which I think is debatable is candles.
28:21 Do you use candles to accomplish this job?
28:23 Programming, no.
28:24 Demon summoning, yes.
28:25 And if you look over on Reddit, the comments are pretty glorious.
28:29 (laughs)
28:30 - That's funny.
28:32 Let me see if I'm finding these good ones just here.
28:35 Someone has said something like, I've been trying for hours to get this daemon to run and I just can't get it to work, that's what I'm writing on.
28:44 Well, I'm trying daemon, not daemon, right?
28:47 Of course.
28:48 - Daemon.
28:49 - And then someone else points out, you know, there actually is a candle app platform, which sounds truly demonic to me.
28:56 So let me describe, this is like a real thing, this is not a joke.
28:59 Candlescript.org, somebody created this.
29:01 Let me lay out the beautiful technologies that CandleScript combines.
29:05 Are you ready to use the new open source platform that unifies core features of XSLT, XQuery, XML schema, RelaxNG, BNF, and XQuery update and more into a single language called Candle?
29:19 No, please, no, XSLT, no.
29:23 Yeah, that sounds pretty demonic already, so I'm a little suspicious of that one.
29:27 - Yeah, and I think actual daemon summoning, probably worried about climate change and probably switching to low carbon lighting.
29:37 So probably LEDs now instead of actual candles.
29:41 - Yep, LEDs, gotta be careful about home automation.
29:44 You might complete all the check boxes.
29:47 - Yeah, I think sometimes you have to execute a child.
29:51 That's funny, child processes.
29:52 - Yeah, they both execute children, right?
29:54 I mean, that's a pretty rough one.
29:56 Kim, I believe, maybe has done enough XSLT as I have to know that it should never ever be done.
30:02 And says, "Candlescript has just triggered my PTSD." (both laughing)
30:06 - Yeah, funny.
30:08 - The battle XML days.
30:09 Well, that's it, Brian.
30:12 Great show as always.
30:13 Thank you for being here.
30:14 - Well, thank you.
30:15 - Mm-hmm.
30:16 Thanks to you everyone for listening and those of you who joined live.