#43 Python string theory, v2 - podcast episode cover

#43 Python string theory, v2

Sep 14, 201719 minEp. 43
--:--
--:--
Listen in podcast apps:

Episode description

Transcript

Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds. This is Python Bytes, episode 43, recorded on September 13, 2017. And I'm Michael Kennedy. And I'm Brian Okken. Hey, it's great to be with you guys. Great to be with you, Brian. We have a bunch of really cool stuff lined up. There's a few things that really surprised me and maybe even inspired me to go create this project that we were just chatting about before we hit record.

So very, very cool stuff. But before we get to it, let's just say thank you to Rollbar. Those guys are sponsoring the show. You check out their offers at pythonbytes.fm/Rollbar, and we'll get to them later. I want to talk about taking the future and sending it into the past, like Marty McFly style. What do you think? Yeah. Yeah, this popped up recently, just this last week. And I'm not sure what the impetus was, but it is Future F-Strings. It's a project.

You could just do pip install future dash F-Strings. And then you've got a little bit of a little... It isn't a library that you include. It changes the encoding. So I'll just jump to the chase. It's a back port of F-Strings, even down to Python 2.7. And I've tried it in 2.7. I haven't tried it in anything else. But it is kind of fun to be able to play with F-Strings everywhere. So I had very mixed thoughts about this when you told me about this project.

On one hand, I look at it like, you know, you're taking one of the really amazing and smooth features of Python 3.6 and making it available in legacy Python. Which is kind of like, do we really want to like encourage that sort of thing? But at the same time, I feel like this also lets you, as you're migrating your code, move to the latest, greatest syntax in Python 2.

But then when you actually make the switch, you're not going to have to go like, well, we used format because that was the best option in Python 2. But now we've got F-Strings. And so I feel like that's really cool. The other area where I think it's great is Python 3. There's plenty of people running Python 3.5. That's the default on Ubuntu right now and things like that that don't have F-Strings.

I've decided after further contemplation that this is a really cool project and I want to check it out. So tell people what F-Strings are. I mean, most people maybe know, but what's this thing, this F-String thing? Well, it's, so if you're familiar with the format part that you could be, I don't know how long ago you start using that. I think that's available in 2.7 as well. Yeah, I think so too.

In the string that you're printing, you can like leave little brackets to show where you're going to insert something. And then you say like .format and then all the things that you're going to put into the string. In F-Strings, you just put an F before the string and then within your brackets, you just put the variable name for whatever you're going to put in there. Or any expression can go in there. Right.

So you could say like F, quote, hello curly thing dot upper and like uppercase the thing just in that expression or something like that, right? Yeah. Yeah. That's really cool. Yeah. At first I was like, I don't know if I like it, but once you start using F-Strings, you can't go back. That's really one of the reasons why I like this project is because I do, I usually use Python 3.6, but there are times where I have to write some stuff in 3.5 or 2.7 or something. And I don't want to go back.

Yeah, I know. I hear you. That's great. I'm going to put a lot of tests around it, so I'm not going to rely on this yet because I don't know if it's really ready for primetime for everywhere. So I would say use caution, dip into this slowly if you're going to use it. But it's a fun thing. I'm not sure I like how it's doing it though. It's doing it in an interesting and odd way. Yeah. I don't know how else it would do it, but it's interrupting the encoding. Yeah, it installs a separate encoder.

So it extends the UTF-8, I think, the UTF-8 encoding to also do this. So if you're not using UTF-8, I don't know, maybe you could hack it to do something like you're using. Yeah, yeah, it's pretty cool. So you put like a little encoding flag at the top and you install a special encoder and off it goes. Yeah, pretty interesting. All right, so I want to stick with this Python 3.6 feature angle, even though that's bringing that stuff to other versions of Python.

I want to talk about the fun of reinvention. So this was a really amazing presentation done by David Beasley. And it's done in the style of some of his other presentations. And in my mind, like the way technical presentations should be done. You should be up there writing code, showing how things work, not just slides and pictures and stuff, but like showing things, right? And so what he shows, though, is kind of insane and incredible. And your mind will probably explode if you see this.

You'll definitely come away with a greater appreciation for Python 3.6. So what he does is he goes and builds upon some of the new 3.6 features that are below the surface that a lot of people wouldn't even know about, like hooking into when a class gets defined. So you can basically redefine what that means and things like that. So, for example, he says, well, let's talk about type-ins. These type-ins are cool, but they don't do anything.

We can add these constraints and assertions inside of our code, and that does something, but we can't really check that in the tooling. So what if we could rewrite, create this little framework using inheritance and all sorts of other stuff that lets us add these constraints as type-ins, and then they're enforced at runtime automatically. It's pretty amazing. That's incredible, yeah.

Yeah. So whether you think it's a good idea or a bad idea to do that, the fact that you can do that is really, really cool. So you can basically set up a function, and as like a type hint constraint, you can say, and this is a positive integer between 0 and 200. And it will actually check that. It's really something. But mostly it's an amazing look inside. Yeah, it's an amazing look inside of Python 3.6, down at the low-level stuff. So, Brian, knock, knock, who's there? Yeah, I am.

Sound recognition is there. Yeah, sound recognition. So there's an interesting article called Sound Pattern Recognition with Python, and I really liked just the – I didn't know you could do this with SciPy. So there's apparently part of SciPy.io.wave file, and I'm not sure if there's other types you can do – use. But this article uses SciPy to read a WAV file and then just has it as data, like an array of numbers, and then does some math on it.

And it does – this particular one is assuming that you've got some WAV files that have NOCs in them and trying to detect where the NOCs are and how far away they are. And just some basic little logic to try to figure out, yeah, like I said, where the peaks are. I think the author noticed that you need to have some minimum values for how you tell where the peaks are and then some distance between them so you don't have, like, ringing within one peak.

I like it because it's kind of a – I think it would extend easily to do – I'd like to take it and run with it and try to do some basic oscilloscope measurements with this kind of a thing. It'd be fun. Yeah, it'd be super fun. It's really accessible. Like, the actual code to figure out the NOCs and to process the WAV file, it's really small and approachable. And to me, what I thought of when I heard this was, oh, you could build something that is actually kind of smart.

So it shows you how to identify NOCs, right? And you should be able to identify, like, a door jiggling, a key noise. You should be able to identify, like, a few of these really distinct patterns. And if you could say, like, identify, like, what does a door jiggle sound like? What does a knock? What does a doorbell? What does a key sound like? You could put a little Raspberry Pi just by your front door that says, someone's home, someone unlock the door, someone's knocking.

You know, just cool stuff. Wouldn't that be – I mean, it seems like that's a weekend project with this. It doesn't seem major. Yeah, that would be fun. You could hook it up with Twilio and get texts when somebody's knocking at your door. Right, and hook it up with a camera to take a picture of whoever's out there, see what they're doing, right? Yeah. Yeah. Send yourself a note, hey, kids came home, right? They unlock the door at 3 o'clock when school's out or whatever. That would be fun.

It sure would. All right. So I think people should take this idea and run with it. And if they do, they should send us a message. Or even better, go to pythonbytes.fm/43 and leave a comment at the bottom about what they created. Yeah, definitely. Definitely. Or even better, they could write a blog post and then email that to us, and we'll highlight it on the show. Yeah, maybe we'll even cover it. That'd be awesome. Yeah, yeah.

Cool. So before we get to the next item, which is sort of mind-blowing, I want to talk about Rollbar. You guys hear me talk about Rollbar a lot probably, but that's because they're great. Basically, if you run any sort of web app, you should have real-time error monitoring and reporting. So if something goes wrong with the website, for example, pythonbytes.fm, we'll get a notification. It could be in Slack. It could be on our phone. They don't have all the details.

You know, this person went to this URL in this situation. Here's the variables they passed to the function that caused a crash, things like that. So if you want to get this for your site or application, just go to pythonbytes.fm/rollbar and check it out. So we've talked a lot about async stuff, right? Like async both on the server and on the client. It's pretty mind-blowing stuff.

But it turns out that, you know, like all changes to software, there's like cascading consequences of adopting a new model or trying something new, right? And one of the cascading changes is in many of the high-performance async processing loops. I'm thinking async.io, but also UV loop, which is a really super fast, powerful one. Things like Sanic are, I think Sanic is based upon it, the web framework and so on.

Those things are ultra fast because they rely on async.io, but async.io doesn't use threads. And so that means thread local storage doesn't have any meaning anymore when all of these like concurrent operations are running on the same thread. Okay. Right? So like if I was running a website, I might store into thread local storage like the cookies or the authentication. And then later I might ask for it back.

But that could be changed because you have a blocking.io that released the thread that somebody else then wrote their cookie to. Right? So it's kind of like crazy. And there's also in other really interesting places like decimals. Working with decimals does this. NumPy error state. Warnings.catch warnings. Profiling. Tracing. All these things use this kind of stuff. Right? But it doesn't work in this async await world. So we have a new PEP. PEP 550 that defines a new execution context.

And this is from the guys at magic.io who created UV loop. So like their motivation is really obvious. Like they want UV loop to work. And this is kind of something in the way. So the PEP adds a new generic mechanism for ensuring consistent access to non-local state in the context of out-of-order execution such as generators and coroutines. Wow. It's pretty fascinating, right? Yeah. It's very fascinating. I hadn't even realized that. I mean, you think it through, obviously, it's a problem.

But I hadn't even realized, like, oh, my gosh. Like, some of these, like, low-level things are just going to be broken. Like how, for example, state is processed in a web request. I'll be very interested to watch this and see where it goes. Yeah. So maybe it makes it into Python 3.7. Maybe not. But it's kind of cool that this is not just like, oh, we made UV work properly. But we're going to make all the Python work properly.

So they've got some really nice examples on the article we're linking to. That's really cool that they did it instead of just trying to hack their own way. Yeah. For sure. Speaking of threads and processing and all that. I often work in single-threaded or single-process sort of tasks. I really like this article called Intro to Threads and Processes in Python. It's a very accessible beginner's guide to parallel programming. And really kind of what's the difference? Where would you use threads?

Where would you use processes? And it's even got pictures with some algorithms to see to show how, like, if you're a certain kind of a job. I can't remember what the job is that he's doing. He's doing some data science project based on Amazon and trying to analyze a bunch of different stuff from space. And so he's got to run tons of algorithms and tweak them with different parameters and stuff like that.

It shows, like, basically, if you use one thread, two threads, or four threads, and then the same with processes, how it's affected with running times. And you can watch to see that things are running in parallel. Good use of little simple diagrams, too. That's cool. Yeah, the pictures were great. The rundown is, conclusion at the end is, if you're waiting on I.O. for something, threads are just fine. And if you are CPU heavy, then you want to go with multiprocessing.

Yep. Until the galectomy happens, which who knows if that will, but until then, this is definitely a good introduction to it. Yeah. And I'm actually, I'm one of the, I don't know, I think there's probably a lot of people, but having the GIL doesn't really bother me. It does simplify how you program. I don't think it's that terrible. So. Yeah. Yeah. It's, you know, it's in the extreme cases.

I think the main group of people who suffer under the GIL are those doing computational, CPU computational work. Outside of that, you're mostly okay. Okay. Yeah. So in that, like async and await and stuff like that, I'm going to expose my, unknowledge of this stuff is, so async and await, is that dealt with, with, multiple threads then?

No, it's all one thread, but it has a mechanism to say, anytime you hit blocking I.O., go put this part of the code to sleep and allow it to run another, another task, another thing until it hits blocking I.O. And the idea is like most of the time you're waiting on databases or networks or something like that. And then you wake up for a second, you do a little processing and then you go back to wait on another network or database or web service.

And as long as that's the kind of stuff you're waiting on, the GIL is not a problem because it gets released. But if you're like trying to compute pi with a, you know, power series or something, something like that, then it would just, it would stop. And the async wouldn't help you with that. Yeah. I just wanted to, so the async and await is going to use, it's going to be in the same sort of a family as when threads would be good for you. Yes. Yeah. It's in exactly this similar spot.

Yeah. But just more efficiently. So let's talk about another low level thing. And I found this, I think it maybe even was recommended by a listener, some low level part of it. And then I found the whole, whole thing. One of the problems that we can have when we're doing unit testing is working with files, right? That can be a serious pain.

Yeah. Yeah. And if you want to save your files to like say user storage, or you want to process different types of files, like zip files, regular, regular files, these are all sorts of pains that you have to deal with. But there's this really cool project called alternative file systems for Python that makes this all seamless. So the idea is you can work with files and directories in like zip archives, in memory, on the cloud, or just as easy as if they're on your hard drive.

So they give some examples in this project saying you could write your code now just with open, you know, such and such as fin and start working with it. And then you decide what that open means. Does that open mean normal files? Does that open mean something on S3? Things like that. You can unit test your code. You can just have in-memory files, but open reads and writes to those in-memory files.

You can upload your files to like S3 or OneDrive or something like that by just writing to that folder, you know, in that file system and all sorts of stuff like that. Yeah. So the, like the memory file system or the temporary file system that they have would be great for like parallelizing tests and things like that. Right. It keeps it all separate and isolated. So some of the back ends they have is they have application data.

This is like the special user data locations in various operating systems. They have Amazon S3 file systems. They have FTP memory. Let's see what else. That's pretty cool. They've got zip for reading and writing zip files. And they also have like SSH file systems for writing to remote servers, all kinds of stuff. And even tar files. Good old tar files. Good old tar files. Yeah. You can just whiff open on those babies.

Yeah. So this is really pretty interesting and I haven't tried it yet, but it looks, it looks quite promising and it's extensible. So you can add more of these back ends if that makes sense for you. That's awesome. I actually think this is pretty fun. I got to play with this. Yeah. Yeah. Yeah. Me too. So definitely check that out. And Brian, that's it for our six items for the week. That's incredible that we've already done. So. I know these are, they're all fun and all interesting.

I really enjoyed researching them this week. So what else are you up to? I got an interesting email this morning saying that they've taken off the beta off of the Python testing with pytest on the Pragmatic website. And you can order the book now and it's supposed to ship next Monday. That is awesome. Congratulations. Yeah. Thanks. So that is what I've been thinking about. I bet. Nice. I've been thinking about switch. Well, I have been too as of this afternoon.

So. I'm working on a project that would add the switch statement to the Python language without extending it. Just like a class that you can basically use. But it's a pretty clever use of like defining blocks and stuff. And I think it might be interesting. I'll put a link to a gist or a GitHub repo or something for you at the end of the show notes. And you guys let us know. I really do want feedback on that because I want to try to nail this.

And I think if we could get it into something, we could stick on PyPI or have you do the work actually. Pip install switch. There you go. That might be a thing. Don't do that. Yeah. Don't do that. Switch laying. Who knows? But yeah, I think it would be a really cool feature if we could make it work for the language without actually changing the language because it's already flexible enough. Yeah. Cool. Cool. All right. Well, thanks for everything, Brian. And good to talk with everyone.

Thank you for listening to Python Bytes. Follow the show on Twitter via 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. On behalf of myself and Brian Okken, this is Michael Kennedy. Thank you for listening and sharing this podcast with your friends and colleagues.

Transcript source: Provided by creator in RSS feed: download file