WEBVTT

00:00:00.001 --> 00:00:05.000
Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.

00:00:05.000 --> 00:00:09.800
This is episode 83, recorded June 20th, 2018. I'm Michael Kennedy.

00:00:09.800 --> 00:00:10.540
And I'm Brian Okken.

00:00:10.540 --> 00:00:12.000
And Brian, we have a special guest, don't we?

00:00:12.000 --> 00:00:12.600
Yes, we do.

00:00:12.600 --> 00:00:17.940
Yeah, so Chris Medina is here to join in the fun and share his perspective on things.

00:00:17.940 --> 00:00:18.820
Hey, Chris, welcome to the show.

00:00:18.820 --> 00:00:20.380
Hey, guys, how's it going? Good to be here.

00:00:20.380 --> 00:00:21.440
Yeah, it's good to have you.

00:00:21.440 --> 00:00:23.540
And I also want to say thank you to DigitalOcean.

00:00:23.540 --> 00:00:27.780
They are a major, major sponsor of the show, and they're sponsoring this one as well.

00:00:27.780 --> 00:00:32.120
I'll tell you more about them, but the short version is pythonbytes.fm/DigitalOcean.

00:00:32.120 --> 00:00:34.100
Get $100 credit for new users.

00:00:34.100 --> 00:00:39.080
Brian, speaking of new users, people learning Python, they might want to set up a server at some point.

00:00:39.080 --> 00:00:40.260
Set up a server?

00:00:40.260 --> 00:00:45.060
Well, you know, eventually, they'll have a website or something, right, once they learn to code.

00:00:45.060 --> 00:00:47.900
But you've got a really nice way for them to get started.

00:00:47.900 --> 00:00:55.140
I've always been reluctant to try to look or play with some of these beginning code editors,

00:00:55.140 --> 00:00:59.100
because part of learning how to code is learning an editor.

00:00:59.100 --> 00:01:03.200
But I'm kind of warming to the idea of some of these specialized editors.

00:01:03.200 --> 00:01:07.560
And there's one that I wasn't familiar with, which is Mu.

00:01:07.560 --> 00:01:09.180
I think it's Mu or Mu.

00:01:09.180 --> 00:01:09.840
I don't know.

00:01:09.840 --> 00:01:10.380
Emu.

00:01:10.380 --> 00:01:11.560
Code with Mu.

00:01:11.560 --> 00:01:14.000
It's got a whole bunch of people on board.

00:01:14.000 --> 00:01:15.140
If I go to the...

00:01:15.140 --> 00:01:19.680
I can't remember where it is, but there's a bunch of people working on this.

00:01:19.680 --> 00:01:23.200
And it's kind of a neat little editor that has...

00:01:23.200 --> 00:01:24.340
I was playing with it this morning.

00:01:24.340 --> 00:01:27.140
And it has some...

00:01:27.140 --> 00:01:29.580
You just open it up, and it has built-in right off the bat.

00:01:29.580 --> 00:01:36.260
It asks you if you're going to do it for Python 3, or if you're targeting, like, an Adafruit chip or a micro bit.

00:01:36.580 --> 00:01:39.580
So it has built-in targeting of those things, like, right away.

00:01:39.580 --> 00:01:41.140
And there's, like...

00:01:41.140 --> 00:01:50.740
Along the top, there's some icons for loading and saving files, running it, debugging it, popping up the REPL, interacting with the plotter.

00:01:51.140 --> 00:01:52.020
And then there's a...

00:01:52.020 --> 00:01:57.000
Even there's a theme button, so you can jump back and forth between dark theme and light theme.

00:01:57.000 --> 00:02:00.820
And it even has, like, a linter built-in where you can check things.

00:02:00.820 --> 00:02:02.280
And it's all...

00:02:02.280 --> 00:02:07.220
Like, you don't have to memorize any key sequences, or there's not really any menus around.

00:02:07.220 --> 00:02:09.260
It just is all up there.

00:02:09.260 --> 00:02:13.420
And I think this would actually be great for teaching people how to code.

00:02:13.420 --> 00:02:17.360
So I'm going to start using it for, like, demos and stuff.

00:02:17.360 --> 00:02:18.240
It's pretty cool, yeah.

00:02:18.320 --> 00:02:25.900
So as you type, basically, it pulls up both the completion for the arguments that go to a method or something,

00:02:25.900 --> 00:02:28.780
but also the documentation, like, while you're typing.

00:02:28.780 --> 00:02:31.520
So, you know, you might get annoyed with that if you know what you're doing.

00:02:31.520 --> 00:02:35.760
But if you're new, it's really cool to show you, like, hey, you can call these various things.

00:02:35.760 --> 00:02:37.100
And here's the arguments.

00:02:37.100 --> 00:02:38.040
Here's what it means.

00:02:38.040 --> 00:02:39.520
And it even has a debug.

00:02:39.520 --> 00:02:40.060
It's pretty cool.

00:02:40.060 --> 00:02:41.380
So it's a separate app?

00:02:41.380 --> 00:02:43.340
Yeah, it's a separate app.

00:02:43.340 --> 00:02:44.640
But you can...

00:02:44.640 --> 00:02:46.020
There's an installer available.

00:02:46.320 --> 00:02:47.500
So you can just...

00:02:47.500 --> 00:02:53.220
You don't even have to tell people about pip right away, because you can just install it with an installer.

00:02:53.220 --> 00:02:56.740
But you can install it with pip, because it's just a Python thing.

00:02:56.740 --> 00:02:58.240
I think it's a Qt application.

00:02:58.240 --> 00:02:59.540
I've been corrected.

00:02:59.540 --> 00:03:00.940
It's a Qt application.

00:03:00.940 --> 00:03:02.640
Oh, that's really cool.

00:03:02.640 --> 00:03:03.320
It's cute.

00:03:03.320 --> 00:03:03.720
Okay.

00:03:03.720 --> 00:03:05.300
Yeah, I installed it with pip.

00:03:05.300 --> 00:03:12.400
And then one of the things that it has in the installation instructions is instructions on how to use...

00:03:12.400 --> 00:03:17.300
So when you install it with pip, you get, like, a command line invocation to invoke it.

00:03:17.300 --> 00:03:23.180
But it recommends using another package called shortcut, which you just...

00:03:23.180 --> 00:03:27.200
If you pip install shortcut, you get shortcut moo editor, for instance.

00:03:27.200 --> 00:03:28.200
And it'll create...

00:03:28.200 --> 00:03:28.200
And it'll create...

00:03:28.200 --> 00:03:31.200
On my Mac, it created a...

00:03:31.200 --> 00:03:36.360
It just went ahead and created a shortcut in my launchpad to launch it.

00:03:36.360 --> 00:03:38.020
So I didn't...

00:03:38.020 --> 00:03:39.160
Oh, that's pretty cool.

00:03:39.160 --> 00:03:41.760
So you can attach that to any Python script.

00:03:41.760 --> 00:03:43.340
You can just launch it from there.

00:03:43.340 --> 00:03:44.440
So...

00:03:44.440 --> 00:03:44.680
Nice.

00:03:44.680 --> 00:03:45.280
Oh, but...

00:03:45.280 --> 00:03:47.260
It looks like it has different modes, too.

00:03:47.260 --> 00:03:52.800
Like, you can set it up to work for writing code for Adafruit or for Pygame or stuff like that.

00:03:52.800 --> 00:03:54.160
That looks kind of neat.

00:03:54.260 --> 00:03:56.160
Yeah, and then when it has...

00:03:56.160 --> 00:03:59.940
The built-in REPL, if you pop open the REPL, it's not just your normal REPL.

00:03:59.940 --> 00:04:04.600
It's a Jupyter notebook or Jupyter REPL, which is pretty cool.

00:04:04.600 --> 00:04:05.560
Yeah, that's really cool.

00:04:05.560 --> 00:04:06.360
I love this.

00:04:06.360 --> 00:04:07.660
Yeah, it's very neat.

00:04:07.660 --> 00:04:08.980
And there's some...

00:04:08.980 --> 00:04:14.040
Like, on the tutorials link, there's a whole bunch of tutorials that aren't quite there yet.

00:04:14.040 --> 00:04:18.300
So I'm guessing they could use some people to help out with this project.

00:04:18.300 --> 00:04:19.020
Oh, right.

00:04:19.020 --> 00:04:20.980
Yeah, and that'd be a great, easy way to get...

00:04:20.980 --> 00:04:24.180
Sort of gets your feet wet and open source is to write some tutorials.

00:04:24.180 --> 00:04:24.580
Right?

00:04:24.580 --> 00:04:29.440
You don't have too much to depend upon or you probably won't break anybody's code by writing one.

00:04:29.440 --> 00:04:29.740
Yeah.

00:04:29.740 --> 00:04:30.360
Yeah, nice.

00:04:30.360 --> 00:04:37.460
So, Chris, one of the things I find that's pretty interesting is we love to talk about super advanced topics,

00:04:37.460 --> 00:04:43.880
but a lot of times it's really what people need or want, especially if you're helping or mentoring someone else,

00:04:43.880 --> 00:04:45.600
is like some more fundamental stuff, right?

00:04:45.600 --> 00:04:52.260
Yep, I found this kind of an intro topic into how the Python parentheses system works.

00:04:52.260 --> 00:04:56.580
It's pretty interesting also for folks that come from other languages,

00:04:56.580 --> 00:05:01.700
so you can get kind of like a quick translation from one place to another and how things operate.

00:05:01.700 --> 00:05:02.660
It sounds pretty simple.

00:05:02.660 --> 00:05:04.340
I mean, it's about Python parentheses, right?

00:05:04.340 --> 00:05:07.900
The Python parentheses primer from Reuben Lerner.

00:05:07.900 --> 00:05:09.580
Shout out to him on that.

00:05:09.980 --> 00:05:15.240
But there's some pretty advanced things going on and a pretty cool feature coming at the end.

00:05:15.240 --> 00:05:15.660
Great.

00:05:15.660 --> 00:05:17.300
So, tell us about it.

00:05:17.300 --> 00:05:22.160
So, the fun stuff is it goes into all the different ways that you actually use parentheses

00:05:22.160 --> 00:05:24.900
while you're doing your Python syntax and what you can use it for.

00:05:24.900 --> 00:05:31.440
So, you get a couple of the simple topics like, you know, usually a parentheses is used in a callable,

00:05:31.440 --> 00:05:36.480
like to call a function and pass in parameters or to call a class that implements callable.

00:05:36.480 --> 00:05:42.220
Things like prioritization of operations or conditionals.

00:05:42.220 --> 00:05:44.720
You also use parentheses for making tuples.

00:05:44.720 --> 00:05:49.960
But you'll also get a little bit into generator expressions and the advantages of that.

00:05:50.420 --> 00:05:57.900
And a couple of little quirks you can use it for securing some of the indentation rules that Python has that some people kind of hate.

00:05:57.900 --> 00:06:00.420
But other people like me love.

00:06:00.420 --> 00:06:01.620
So, I'm special.

00:06:01.620 --> 00:06:04.440
You also get into square brackets and curly braces.

00:06:04.440 --> 00:06:10.700
And square brackets, which are typically used for lists and for indexing.

00:06:10.700 --> 00:06:15.440
For somebody that's new to the topic, you'll want to look at the slices section.

00:06:15.440 --> 00:06:19.820
Because slices are a pretty powerful little tool that you get out of Python.

00:06:20.400 --> 00:06:27.580
If you haven't used it before, how to get specific sections of a list or iterable.

00:06:27.580 --> 00:06:39.220
And there's also, while not in the article itself, but some of the folks that commented on the article also mentioned that some of the new type hint stuff also uses square brackets for identifying,

00:06:40.220 --> 00:06:50.400
like the variables, like the variables, like the data type of floats, the data type that it's implementing.

00:06:50.400 --> 00:06:55.460
So, if you have a list of floats, you would say list curly bracket floats when you're specifying what type it is.

00:06:55.600 --> 00:06:56.520
Yeah, that's really interesting.

00:06:56.520 --> 00:07:06.100
It's almost like generics in like C# or templates in C++ where you would say this thing takes a list of strings.

00:07:06.100 --> 00:07:07.420
You can say it's just a list.

00:07:07.420 --> 00:07:10.860
But then, like, you don't get any help on what's contained within it.

00:07:10.860 --> 00:07:15.180
But you could say, you know, import the list thing and say list square bracket int square bracket.

00:07:15.320 --> 00:07:19.460
Then it has to be a homogeneous list of ends, not just any random list, which is pretty cool.

00:07:19.460 --> 00:07:19.920
Exactly.

00:07:19.920 --> 00:07:26.040
I was looking through here, and down at the bottom, they're talking about some of the ways to, like, future-proof your code.

00:07:26.320 --> 00:07:31.700
So, like, you can say from Dunder future import division.

00:07:31.700 --> 00:07:35.600
And there's a proposal for braces, huh?

00:07:35.600 --> 00:07:36.120
Uh-huh.

00:07:36.120 --> 00:07:47.520
If you have a Python REPL open right now and you kind of want to try that, you'll get a neat little message of what the future will look like if you ever actually import braces.

00:07:47.520 --> 00:07:47.880
Right.

00:07:47.960 --> 00:07:56.320
So, if you can see, like, the coming braces feature, you can say from Dunder future import braces and see what support Python's probably going to be adding for braces soon.

00:07:56.320 --> 00:07:59.480
Which, you know, not everyone's typing.

00:07:59.480 --> 00:08:00.400
They're probably driving this up.

00:08:00.400 --> 00:08:06.800
So, basically, it throws a syntax exception error and says not a chance.

00:08:06.800 --> 00:08:07.940
We're never adding braces.

00:08:07.940 --> 00:08:09.420
It's beautiful.

00:08:09.420 --> 00:08:11.040
I knew about anti-gravity.

00:08:11.040 --> 00:08:12.060
We were joking about that earlier.

00:08:12.060 --> 00:08:13.940
But I did know about the import braces.

00:08:13.940 --> 00:08:14.680
That's pretty sweet.

00:08:14.880 --> 00:08:21.100
One more interesting thing to mention, obviously, goes into curly braces and how you use that as well for set comprehensions and dictionaries.

00:08:21.100 --> 00:08:24.240
The other thing to remind folks is Python 3.6+.

00:08:24.240 --> 00:08:25.860
There is f-strings.

00:08:25.860 --> 00:08:33.000
And with f-strings, you can use braces inside a string that you prefix with f.

00:08:33.000 --> 00:08:41.820
And the interpreter replaces any code that you put inside those braces, actually executes it, and replaces the result into the string.

00:08:41.820 --> 00:08:42.180
Yeah.

00:08:42.180 --> 00:08:42.860
Very nice.

00:08:42.860 --> 00:08:43.740
f-strings are great.

00:08:43.740 --> 00:08:44.700
And it's way more efficient.

00:08:44.860 --> 00:08:46.060
Fastest and the shortest.

00:08:46.060 --> 00:08:46.840
Cleanest.

00:08:46.840 --> 00:08:47.160
Very nice.

00:08:47.160 --> 00:08:52.100
So, Brian, you mentioned that Mew Editor is a Qt application.

00:08:52.100 --> 00:08:55.680
And Qt is kind of making a bit of a resurgence these days.

00:08:55.680 --> 00:08:57.740
At least I've been paying more attention to it.

00:08:57.740 --> 00:08:57.980
Yeah.

00:08:57.980 --> 00:08:58.320
Yeah.

00:08:58.320 --> 00:09:00.960
Well, it had gone through some fairly dark times.

00:09:00.960 --> 00:09:03.660
I mean, obviously, we've been on our GUI kick for a while.

00:09:03.660 --> 00:09:04.900
We're going through all these different options.

00:09:04.900 --> 00:09:06.380
And there's still tons of great options.

00:09:06.940 --> 00:09:12.880
Like, wxPython had their Phoenix release, which was sort of a rebuilding of that whole thing, which is awesome.

00:09:12.880 --> 00:09:14.100
A little while ago, we talked about that.

00:09:14.180 --> 00:09:20.420
So, the Qt company, Qt company, is the company that is behind the Qt framework.

00:09:20.420 --> 00:09:36.500
And they just announced the official release for Python for Qt, which is taking these various version mismatch, PySide 2, PyQt, all those things, and, like, rebuilding it, like, on a two-year project into a fresh, new, shiny version.

00:09:36.660 --> 00:09:38.540
So, that's pretty awesome that that's more or less out.

00:09:38.540 --> 00:09:39.420
Oh, that's exciting.

00:09:39.420 --> 00:09:42.700
We heard recent, not too long ago, that it was coming.

00:09:42.700 --> 00:09:45.000
But having it be released, wonderful.

00:09:45.000 --> 00:09:45.300
Yeah.

00:09:45.300 --> 00:09:47.920
So, if you're messing with this, it's version 5.11.

00:09:47.920 --> 00:09:53.720
And I think it's still in a tech preview in terms of the execution bits.

00:09:53.720 --> 00:09:56.380
But I suspect that this means the APIs are frozen.

00:09:56.380 --> 00:09:57.700
So, you can go and check that out.

00:09:57.700 --> 00:09:58.380
Yeah.

00:09:58.380 --> 00:10:00.000
So, it started two years ago.

00:10:00.000 --> 00:10:01.120
They've been working on this.

00:10:01.120 --> 00:10:04.720
And one thing that's really nice is the way you get it is you just pip install.

00:10:05.480 --> 00:10:10.780
And right now, it's not coming out of PyPI.org itself.

00:10:10.780 --> 00:10:11.860
It's coming out of a different place.

00:10:11.860 --> 00:10:19.200
So, they show you the command, like, to pass their particular sort of dev, their dev index URL, which I put in the show notes.

00:10:19.200 --> 00:10:20.240
So, people can check that out.

00:10:20.240 --> 00:10:24.080
So, that looks like they have their own PyPI implementation there.

00:10:24.080 --> 00:10:24.360
Yeah.

00:10:24.360 --> 00:10:25.200
Something like that, right?

00:10:25.200 --> 00:10:29.400
Like, a little bit like what you guys are doing that we talked about over on Talk Python, right, Chris?

00:10:29.400 --> 00:10:29.660
Yep.

00:10:29.660 --> 00:10:30.120
Exactly.

00:10:30.120 --> 00:10:32.480
But this one goes outside the firewall, it looks like.

00:10:32.480 --> 00:10:33.600
Nice.

00:10:34.060 --> 00:10:35.880
So, you know, I just want to give a shout out.

00:10:35.880 --> 00:10:41.860
People who are looking, waiting for Qt to become more important to get revitalized.

00:10:41.860 --> 00:10:44.980
I feel like, you know, this is the announcement we've been waiting for.

00:10:44.980 --> 00:10:47.060
Hopefully, this means lots of good things.

00:10:47.060 --> 00:10:47.920
We'll see what happens.

00:10:47.920 --> 00:10:48.380
Yeah.

00:10:48.380 --> 00:10:49.000
Pretty cool.

00:10:49.000 --> 00:10:49.320
Yeah.

00:10:49.320 --> 00:10:49.660
For sure.

00:10:49.660 --> 00:10:52.680
So, speaking of good things, DigitalOcean, they're very good.

00:10:52.680 --> 00:10:54.400
They do all sorts of awesome stuff, right?

00:10:54.400 --> 00:10:57.540
They're giving you guys tons of credit if you want to get started there.

00:10:57.880 --> 00:11:02.220
And I always try to talk about different ways we are using them in our various bits of infrastructure.

00:11:02.220 --> 00:11:03.740
And that's still true.

00:11:03.740 --> 00:11:04.220
Still are.

00:11:04.220 --> 00:11:05.000
Still enjoying that.

00:11:05.000 --> 00:11:13.280
But one of the things that they have that's really cool is when you go create a virtual machine, you can say, I want a one-click app, which really means a virtual machine configured to run something.

00:11:14.080 --> 00:11:18.680
And they recently set up a machine learning virtual machine for you.

00:11:18.680 --> 00:11:19.780
So, you can go there, create a droplet.

00:11:19.780 --> 00:11:21.360
That's their VM terminology.

00:11:21.360 --> 00:11:22.860
Click on one-click apps.

00:11:22.860 --> 00:11:24.600
Pick machine learning in AI.

00:11:24.600 --> 00:11:31.140
And you automatically get a machine with Python 3, R, Jupyter, Notebooks, SensorFlow, PyTorch, all that stuff.

00:11:31.140 --> 00:11:36.240
And you can pick, like, a CPU-optimized CPU for your virtual machine.

00:11:36.240 --> 00:11:37.660
All sorts of good stuff.

00:11:37.660 --> 00:11:41.580
So, if you want to check that out, you can do it real quick and affordably.

00:11:41.580 --> 00:11:43.660
Just play around with those tools, which is pretty awesome.

00:11:43.760 --> 00:11:49.900
So, check them out over at pythonbytes.fm/digitalocean.

00:11:49.900 --> 00:11:55.080
And like I said, if you go there and you're a new user, you'll get $100 credit, which is also pretty sweet.

00:11:55.080 --> 00:11:59.960
So, Brian, iteration is a key element of Python, right?

00:11:59.960 --> 00:12:05.940
Yeah, we often deal with lots of iteration and generators and iterators and all sorts of things.

00:12:05.940 --> 00:12:06.340
Exactly.

00:12:06.340 --> 00:12:07.160
We've got generators.

00:12:07.160 --> 00:12:13.080
Like, the primary for loop is not for I equals zero, I plus plus, but it's for thing in collection.

00:12:13.300 --> 00:12:14.100
It's beautiful, right?

00:12:14.100 --> 00:12:15.600
But it goes even deeper.

00:12:15.600 --> 00:12:19.260
Developing your own iterators and generators is a fun thing to learn about.

00:12:19.260 --> 00:12:23.120
But I have to admit that I don't often do that very much.

00:12:23.120 --> 00:12:30.760
And one of the things that I've – it's always been on my to-do list is to learn more about the iter tools module.

00:12:30.760 --> 00:12:33.540
And I've not really ever explored it too much.

00:12:33.540 --> 00:12:41.180
And real Python has a blog post called iter tools in Python 3 by example.

00:12:41.500 --> 00:12:43.220
And I really enjoyed this.

00:12:43.220 --> 00:12:49.980
It's a nice introduction as to what is the problem that iterators and generators are dealing with.

00:12:49.980 --> 00:12:59.640
And then, like, for example, it starts off with just how does zip work to take two lists and create another list with, like, each element.

00:13:00.140 --> 00:13:04.620
And then what if you need, like, not quite the same zip?

00:13:04.620 --> 00:13:06.920
What if they're not the same length and things like that?

00:13:06.920 --> 00:13:11.440
And some of the problems that can happen and why lazy evaluation is a good thing.

00:13:11.440 --> 00:13:16.240
And actually, in the discussion, it used the time function, the time shell function.

00:13:16.240 --> 00:13:23.080
I guess this is, like, a Unix-y kind of thing with a dash f, which I've never used before.

00:13:23.080 --> 00:13:25.860
And that showed the memory used also.

00:13:25.860 --> 00:13:27.200
Didn't know that was a thing.

00:13:27.200 --> 00:13:27.800
Oh, that's cool.

00:13:27.800 --> 00:13:34.500
But this example of using, like, a big example in the memory usage blew up to, like, huge.

00:13:34.500 --> 00:13:41.300
And so just talk through, like, some of the different things that are in iter tools and why that helps you.

00:13:41.300 --> 00:13:42.680
I pulled out a couple.

00:13:42.680 --> 00:13:47.420
Like, a lot of these things, if you don't know they're there, you'll just come up with it on your own.

00:13:47.420 --> 00:13:51.180
Like, doing combinatorial sets.

00:13:51.180 --> 00:13:52.220
Those are already in there.

00:13:52.220 --> 00:13:57.260
Coming up with permutations, you don't have to do, like, a random index.

00:13:57.260 --> 00:14:01.540
You can just use their iterate, the ones that are built in.

00:14:01.540 --> 00:14:08.460
I think that's a good example of, like, being fluent in Python versus being able to make the code work but not really deeply knowing it, right?

00:14:08.460 --> 00:14:15.620
Like, if somebody said, hey, I want you to take this thing and generate, like, a set of permutations, all the permutations of, say, this word or whatever, right?

00:14:15.620 --> 00:14:18.600
You might attempt to implement the fairly complicated algorithm.

00:14:18.600 --> 00:14:23.200
Or you might just call iter tools, you know, permute sort of thing, right?

00:14:23.200 --> 00:14:24.420
And then, boom, it's just there.

00:14:24.420 --> 00:14:28.240
So there's so many things like that that are just, like, at your fingertips if you just import them.

00:14:28.240 --> 00:14:28.480
Yeah.

00:14:28.560 --> 00:14:36.280
I mean, a lot of people are smart enough to, like, if you come up with all the combinations, you can just have a nested for loop and figure out how to do that.

00:14:36.280 --> 00:14:37.660
But you don't have to.

00:14:37.660 --> 00:14:38.380
It's already there.

00:14:38.380 --> 00:14:44.900
And one of the things I didn't know, there's some fun things like some fun uses of count and cycle.

00:14:44.900 --> 00:14:46.540
I didn't know about cycle.

00:14:46.540 --> 00:14:47.180
That's pretty cool.

00:14:47.180 --> 00:14:52.320
It just kind of cycles through a set and then keeps giving you more of the same.

00:14:52.680 --> 00:15:00.840
And the tutorial also talks about, in the tutorial, it's using the next function, which is for iterators.

00:15:00.840 --> 00:15:03.160
You don't have to use them in a loop.

00:15:03.160 --> 00:15:07.480
You can even just call the next function, which is kind of fun.

00:15:07.480 --> 00:15:10.120
And then something that's iSliced.

00:15:10.120 --> 00:15:11.300
I didn't know this was a thing.

00:15:11.300 --> 00:15:19.440
So if you want to take a slice of a list or a slice of some other iterator, you can do that.

00:15:19.440 --> 00:15:24.700
But if you want that to be an iterable also, this does it for you.

00:15:24.700 --> 00:15:26.900
And so there's a whole bunch of goodies in here.

00:15:26.900 --> 00:15:30.980
Yeah, one of my favorites is iSliced because, like Chris already said, slicing is awesome.

00:15:30.980 --> 00:15:35.200
But if you try to do, say, slice on a generator, it'll just go fail.

00:15:35.200 --> 00:15:37.000
Like, nope, we don't slice generators.

00:15:37.000 --> 00:15:39.880
Well, you can iSliced them, and it works just fine.

00:15:39.880 --> 00:15:40.640
It's beautiful, right?

00:15:40.640 --> 00:15:44.480
So you sort of make things sliceable that otherwise would not be.

00:15:44.480 --> 00:15:45.060
It's really great.

00:15:45.060 --> 00:15:50.640
Yeah, so this is definitely a good read to beef up on the iter tools.

00:15:51.600 --> 00:15:57.640
Yeah, I recommend everybody that writes any Python code to just go look at iter tools and all the things you can do.

00:15:57.640 --> 00:16:00.680
There's lots of stuff online, and this is a good resource.

00:16:00.680 --> 00:16:07.600
Every once in a while, every time there's an article that's something about iter tools, I always go just at least skim it.

00:16:07.600 --> 00:16:10.380
Because there's always some little magic in there.

00:16:10.380 --> 00:16:12.640
You're like, oh, I implemented that myself the other day.

00:16:12.640 --> 00:16:17.140
Let me go delete that code and actually do something that's maintained by somebody that knows something more than that.

00:16:17.260 --> 00:16:18.680
Yeah, and maybe even in C.

00:16:18.680 --> 00:16:20.940
So it's a little faster, right?

00:16:20.940 --> 00:16:21.780
Down in the internals.

00:16:21.780 --> 00:16:22.600
Nice.

00:16:22.600 --> 00:16:30.600
So speaking of sort of working with collections and iterables and things like that, Chris, I feel like your item dovetails really well in with this.

00:16:30.600 --> 00:16:30.960
Right.

00:16:31.160 --> 00:16:34.740
So the next item is about Python sets and set theory.

00:16:34.740 --> 00:16:45.600
It's a nice, also kind of a primer on how sets work in Python, how you divide them, how you work with them, and just a tiny bit on set theory.

00:16:45.600 --> 00:16:48.820
So you can build sets different ways.

00:16:48.820 --> 00:16:52.080
The most common way is by calling the set function to build an empty set.

00:16:53.360 --> 00:16:58.720
But you can also use curly braces, which we were talking about earlier, to have set comprehensions.

00:16:58.720 --> 00:17:03.580
And it's a great way of, say, deduping items in a list.

00:17:03.580 --> 00:17:14.900
So if you have a list of a bunch of integers or something like that, you can use the comprehension to iterate through the list and just grab the items that you care about, and you only get the unique items out of it.

00:17:15.080 --> 00:17:20.040
The interesting part about sets as well is that they're all of one.

00:17:20.040 --> 00:17:24.380
So when you're making a membership test, it's fast.

00:17:24.380 --> 00:17:30.060
It's considerably faster than going through, say, a list where you have to iterate through the entire list to see if the item is in it.

00:17:30.060 --> 00:17:30.600
Yeah, that's cool.

00:17:30.600 --> 00:17:32.700
I definitely like the distinct aspect.

00:17:32.700 --> 00:17:35.140
That's what I use a lot of sets for.

00:17:35.140 --> 00:17:36.240
It's like, I have all these things.

00:17:36.240 --> 00:17:37.280
There might be duplication.

00:17:37.280 --> 00:17:39.780
I just want them one of each.

00:17:39.780 --> 00:17:42.420
You know, if there's duplicate, just don't add it.

00:17:42.420 --> 00:17:42.600
Right.

00:17:42.720 --> 00:17:50.740
So you can just, like, you could even say set of some list and then, you know, just get that back as here's the distinct stuff in the list, which is great.

00:17:50.740 --> 00:17:54.120
Also, for simplifying conditionals.

00:17:54.120 --> 00:18:05.600
So you have the example, well, Python had the example, and the stuff you covered about parentheses of if item equals x or item equals y or item equals z or whatever.

00:18:05.600 --> 00:18:05.920
Right.

00:18:05.920 --> 00:18:09.120
Like that becomes like kind of a nasty multiline looking thing.

00:18:09.480 --> 00:18:14.520
Maybe a more Pythonic way of you say if x is in, you know, curly set x, y, z.

00:18:14.520 --> 00:18:14.860
Right.

00:18:14.860 --> 00:18:16.260
You can do stuff like that.

00:18:16.260 --> 00:18:22.840
It's always another point to keep in mind is sets are of immutable values.

00:18:22.840 --> 00:18:28.580
So you can't put, like, say, a normal set inside of a set.

00:18:28.580 --> 00:18:32.020
There's other value types and stuff like that.

00:18:32.020 --> 00:18:33.340
You can't just, like, stick in a set.

00:18:33.340 --> 00:18:33.680
Right.

00:18:33.720 --> 00:18:36.120
So it has to be hashable, basically same as dictionary keys.

00:18:36.120 --> 00:18:37.080
Yeah.

00:18:37.080 --> 00:18:37.680
Yeah.

00:18:37.680 --> 00:18:38.400
Right.

00:18:38.400 --> 00:18:39.120
So it can't change.

00:18:39.120 --> 00:18:45.220
But it's always, always interesting to remember once you've made a set that you're looking for distinct values and things like that.

00:18:45.440 --> 00:18:56.960
I always try to look through my code if there's some sort of, if I'm checking if item is in list one and also in list two, because you can always have two sets and do an intersection between them.

00:18:56.960 --> 00:18:59.540
And then you don't have to do those for loops.

00:18:59.540 --> 00:19:06.600
And the code is kind of optimized to do that for you, which I'm sure will not be all of n squared when you're writing your code.

00:19:06.600 --> 00:19:06.820
Right.

00:19:06.820 --> 00:19:07.500
Yeah, exactly.

00:19:07.500 --> 00:19:17.560
And then just to quickly look back on immutability, if you want to make a set of sets, there's also such a thing as a frozen set where the set itself is immutable.

00:19:17.560 --> 00:19:20.120
And you can stick that into a set.

00:19:20.120 --> 00:19:21.520
So stuff like that.

00:19:21.520 --> 00:19:22.340
That's very meta.

00:19:22.340 --> 00:19:23.560
Brian, do you use sets very often?

00:19:23.560 --> 00:19:29.360
I always have, like, a tutorial like this or something to look up because I forget what the operators are.

00:19:29.360 --> 00:19:35.220
Because it does have union, intersection, difference, symmetric difference, things like that.

00:19:35.740 --> 00:19:43.240
And remembering all of that stuff from your college days is good to try to make some elegant code.

00:19:43.240 --> 00:19:49.340
But it has, like, for instance, the union operator is you can just use the bar function for that.

00:19:49.340 --> 00:19:52.540
And looking up all those is a good thing.

00:19:52.540 --> 00:20:02.520
Although, since I know I have to look it up, I usually put a comment in there to tell anybody else what I'm doing to say this is a set operation going on here.

00:20:02.520 --> 00:20:03.520
Yeah, it makes sense.

00:20:03.520 --> 00:20:11.280
I feel like sometimes knowing the right data structure cannot, like, really open people's eyes or really change the way they're doing something.

00:20:11.280 --> 00:20:16.160
And sets and dictionaries definitely seem to fall into that space where, like, you don't use them that much.

00:20:16.160 --> 00:20:18.820
But when you do, you're like, whoa, that really is better.

00:20:18.820 --> 00:20:20.440
So many ways.

00:20:20.440 --> 00:20:23.580
Yeah, and it's also one of those things of, like, it's a new hammer.

00:20:23.580 --> 00:20:28.900
Try to be sure that you don't see everything as a set problem.

00:20:28.900 --> 00:20:30.880
Because everything isn't a set problem.

00:20:31.300 --> 00:20:32.000
Yeah, for sure.

00:20:32.000 --> 00:20:32.580
All right.

00:20:32.580 --> 00:20:39.800
So last item that I wanted to cover on this episode is a little bit of a look ahead, maybe to next week.

00:20:39.800 --> 00:20:45.940
But to put this on people's radar so when it launches, you can, like, do maybe a backflip or something if you've been practicing.

00:20:46.940 --> 00:20:54.540
So coming up, we just had the release of Python 3.7 Release Candidate 1, which was on June 12th.

00:20:54.540 --> 00:21:02.440
And expected or planned for June 27th, which is seven days from now, is the final release of Python 3.7 official.

00:21:02.440 --> 00:21:03.200
How about that?

00:21:03.200 --> 00:21:04.000
I'm so excited.

00:21:04.000 --> 00:21:05.860
Do you know what makes me most excited about this?

00:21:05.860 --> 00:21:07.980
There's certain things in here like, oh, okay, cool.

00:21:07.980 --> 00:21:08.800
Breakpoint.

00:21:08.800 --> 00:21:09.560
That's kind of nice.

00:21:09.760 --> 00:21:11.020
Data classes, kind of nice.

00:21:11.020 --> 00:21:17.180
But what really makes me most excited is this is the categorically fastest Python period.

00:21:17.180 --> 00:21:25.120
So all the people that say, no, we're using legacy Python because under this particular use case, it's faster than Python 3.7.

00:21:25.260 --> 00:21:27.260
And there may still be some very narrow use case.

00:21:27.260 --> 00:21:30.920
But generally speaking, this is the fastest Python period.

00:21:30.920 --> 00:21:36.140
It's much faster than Python 3, certainly up to 3.3.

00:21:36.140 --> 00:21:38.660
But it's even quite a bit faster than 3.6.

00:21:38.660 --> 00:21:51.080
So, for example, from 3.6 to 3.7, when you're calling methods, especially methods that are part of classes, not standalone functions, but, like, bound methods to classes, it's, like, 20% faster.

00:21:51.080 --> 00:21:52.560
That's a reason right there to switch.

00:21:52.720 --> 00:21:55.820
Yeah, and what's cool, like, all you got to do is just run on the new version, right?

00:21:55.820 --> 00:21:58.460
There's no, like, oh, I switched to PyPy or something.

00:21:58.460 --> 00:22:01.260
It's just I now have 3.7, so life is better.

00:22:01.260 --> 00:22:02.980
Especially if you're using a framework.

00:22:02.980 --> 00:22:03.340
Yeah.

00:22:03.340 --> 00:22:07.180
Anybody that's using a framework, remember, there's a bunch of levels of abstraction around it.

00:22:07.180 --> 00:22:08.860
So there's a bunch of function calls.

00:22:08.860 --> 00:22:09.380
Exactly.

00:22:09.380 --> 00:22:11.300
Yeah, there's tons of function calls.

00:22:11.300 --> 00:22:13.960
And so this is really, really good news.

00:22:14.440 --> 00:22:24.580
So just to run through some of the features, there's improvements to coupling that type annotations or type hints added to the system.

00:22:24.700 --> 00:22:30.600
So previously, if I wanted to say, here's a function, and it returns this type of thing, right?

00:22:30.600 --> 00:22:33.280
It returns, like, this object or some type I've defined.

00:22:33.280 --> 00:22:36.500
I have to literally import that type at the top of that file.

00:22:36.500 --> 00:22:47.420
And what that means is at import time, I pay an extra import processing that file, which I might not have otherwise loaded, potentially, or at least not right then.

00:22:47.660 --> 00:22:52.740
The other one is circular dependencies are super annoying in that.

00:22:52.740 --> 00:22:59.360
Like, so, for example, I've got, like, a repository class, and it returns some kind of object, right?

00:22:59.360 --> 00:23:01.900
But that object, when it's defined, has to know about the repository.

00:23:01.900 --> 00:23:04.780
So it says it returned, like, it uses this somewhere else.

00:23:04.780 --> 00:23:10.000
Like, that basically will fail and break the import because it's circular, right?

00:23:10.000 --> 00:23:21.180
So with this new thing, this change is instead of actually evaluating these type hints and having to import them, it's just evaluated as if you had typed them as strings.

00:23:21.180 --> 00:23:25.800
So they're not actually evaluating the true types when you do type annotations.

00:23:25.800 --> 00:23:27.120
So that gives you more flexibility.

00:23:27.120 --> 00:23:29.120
The circular dependencies are a problem, and it's faster.

00:23:29.120 --> 00:23:29.500
Yeah.

00:23:29.500 --> 00:23:30.140
That's neat.

00:23:30.140 --> 00:23:37.720
Yeah, the type annotations thing that makes me the most crazy is I have a class, and it's got, like, some function that returns an instance of itself.

00:23:38.200 --> 00:23:45.840
You can't say that in the previous type hints as concrete types because you can't say the name of the class until it's fully defined.

00:23:45.840 --> 00:23:49.920
But you're halfway through the class trying to say, this method returns one of me, you know?

00:23:49.920 --> 00:23:56.180
You can get around it by putting quotes, but that's effectively, like, what this does without the syntax to put in the quotes.

00:23:56.180 --> 00:23:57.340
So it looks more natural.

00:23:57.340 --> 00:23:59.520
So you can do that now with the 3-side?

00:23:59.520 --> 00:24:03.840
Yeah, but you have to put quotes, and you have to, like, say the name out exactly as a string.

00:24:03.840 --> 00:24:04.420
Oh, okay.

00:24:04.420 --> 00:24:04.880
Yeah, yeah.

00:24:04.880 --> 00:24:06.020
Let's take a look at that.

00:24:06.020 --> 00:24:06.640
Yeah, it's pretty cool.

00:24:07.140 --> 00:24:09.900
All right, you also have data classes, which are really nice.

00:24:09.900 --> 00:24:11.200
They're kind of like tuples.

00:24:11.200 --> 00:24:17.260
They have a lot of interesting hashing and equality operators on them as well as representation ones.

00:24:17.260 --> 00:24:21.460
They can be frozen, so they can be mutable or immutable, all sorts of things.

00:24:21.460 --> 00:24:26.460
So kind of like enumeration, name tuple, tuple, it's stuff all brought together.

00:24:26.640 --> 00:24:35.780
It's sort of a derivative of the attrs project, but they decided not to move attrs into the framework because it's evolving quickly, and they don't want to, like, freeze it.

00:24:35.780 --> 00:24:37.720
So data classes, kind of the same thing.

00:24:37.720 --> 00:24:45.540
I just want to point out that data classes has a back port for 3.6, so you can go ahead and start using those in 3.6 as long as you pip install them first.

00:24:45.540 --> 00:24:46.540
Yeah, how do I get that?

00:24:46.540 --> 00:24:47.920
Pip install data classes?

00:24:47.920 --> 00:24:49.320
Pip install data classes.

00:24:49.560 --> 00:24:50.620
Oh, that's pretty killer.

00:24:50.620 --> 00:24:51.480
I didn't know about that.

00:24:51.480 --> 00:24:55.800
All right, so there's a new breakpoint function, which we talked about.

00:24:55.800 --> 00:24:58.760
We don't use that much because, like, if you just fire a PyCharm, who cares?

00:24:58.760 --> 00:25:02.560
But there's some pretty interesting – it's got to be clicking the gutters.

00:25:03.060 --> 00:25:09.540
But there's actually some pretty interesting ways to, like, say, hook a remote debugger to your code, things like that.

00:25:09.540 --> 00:25:11.040
There's really interesting stuff going on there.

00:25:11.040 --> 00:25:12.060
AsyncIO got better.

00:25:12.060 --> 00:25:13.560
Chris, you should be happy about that.

00:25:13.560 --> 00:25:14.540
Did you see these?

00:25:14.540 --> 00:25:15.980
Some of this is pretty cool.

00:25:15.980 --> 00:25:16.820
Tell me about it.

00:25:16.820 --> 00:25:28.160
This asyncIO run function is a way of running a coroutine from synchronous code, which, I mean, that existed before, but you had to do, like, 50 million things to set your stuff up correctly and make sure you didn't break other –

00:25:28.160 --> 00:25:31.900
You just call run, and it will internally, like, create the loop and do it for you?

00:25:31.900 --> 00:25:32.260
Yep.

00:25:32.260 --> 00:25:34.360
Just call run, starts coroutine.

00:25:34.360 --> 00:25:35.880
Oh, that is sweet.

00:25:35.880 --> 00:25:40.080
It starts an event loop, runs your coroutine, and closes the event loop at the end.

00:25:40.080 --> 00:25:42.100
So you're going to have to be careful when you use this.

00:25:42.100 --> 00:25:42.880
This is pretty cool.

00:25:42.880 --> 00:25:48.500
And there's some of the task management stuff that's also a little bit better.

00:25:48.500 --> 00:25:49.380
So this is pretty cool.

00:25:49.380 --> 00:25:52.140
I'll have to – maybe I'll write a post on this.

00:25:52.140 --> 00:25:52.900
Yeah, that's awesome.

00:25:52.900 --> 00:25:53.700
Yeah, definitely cool.

00:25:53.700 --> 00:25:56.860
Another one that's really nice is the time module.

00:25:57.380 --> 00:26:05.460
And a bunch of other functions, as well, have become more accurate, especially over long durations, and they've taken on nanosecond resolution.

00:26:05.460 --> 00:26:14.980
So you can import time and say time – you just call time, and it will give you a floating point value of the number of seconds since the epoch, like 1970.

00:26:16.120 --> 00:26:23.260
But this – you can also now in 3.7 say time underscore ns, and it will give you the nanoseconds as an integer.

00:26:23.260 --> 00:26:30.100
And because it's an integer, not a float, that means there's no drift or anything in sort of the floating point operations.

00:26:30.100 --> 00:26:32.720
It's like truly the nanoseconds, which is awesome.

00:26:32.720 --> 00:26:33.020
Yep.

00:26:33.020 --> 00:26:33.400
All right.

00:26:33.400 --> 00:26:34.440
And finally, I just want to close out.

00:26:34.440 --> 00:26:37.460
Give it like – what would Python Bytes show be without?

00:26:37.460 --> 00:26:38.840
A shout-out to Anthony Shaw.

00:26:38.840 --> 00:26:39.340
Right, Brian?

00:26:39.880 --> 00:26:41.520
Yeah, he's been a part of the show a lot.

00:26:41.520 --> 00:26:42.920
For sure.

00:26:42.920 --> 00:26:49.400
So he actually did a brand-new course on Pluralsight called What's New in Python 3.7.

00:26:49.400 --> 00:26:51.300
So I put a link to his course there as well.

00:26:51.360 --> 00:26:56.640
And actually, it's only about an hour long, but it goes really in-depth into like the advantages or all these various things.

00:26:56.640 --> 00:26:57.820
So quite cool.

00:26:57.820 --> 00:27:02.540
If that's easy for you to check out, go ahead and drop over there and check out Anthony's course.

00:27:02.540 --> 00:27:03.140
Very nice.

00:27:03.140 --> 00:27:05.960
Yeah, so I'm really excited for when this ships.

00:27:05.960 --> 00:27:07.380
I think it's going to be great.

00:27:07.380 --> 00:27:12.880
There always seems to be like some latency on the Linux distributions and stuff before I can really make use of it.

00:27:12.880 --> 00:27:15.960
But, you know, pretty soon I'll be happy to be running this.

00:27:15.960 --> 00:27:16.540
Yeah, definitely.

00:27:16.540 --> 00:27:16.900
Yeah.

00:27:16.900 --> 00:27:19.100
Do you guys have any extra news that you want to cover?

00:27:19.100 --> 00:27:20.700
That's it for our official items.

00:27:20.940 --> 00:27:29.820
I've been doing a lot of going back, went through all of the code that was in the pytest book to make sure it's 3.7 compatible,

00:27:29.820 --> 00:27:33.160
which I was happy to find out that it's fine.

00:27:33.160 --> 00:27:33.980
Nice.

00:27:33.980 --> 00:27:34.780
So that's good.

00:27:34.780 --> 00:27:35.480
Yeah, very cool.

00:27:35.480 --> 00:27:40.380
I saw this really cool tutorial series about Mongo.

00:27:40.380 --> 00:27:42.260
Do you know anything about this?

00:27:42.260 --> 00:27:45.660
I may have spent an incredible amount of time working on this project.

00:27:45.660 --> 00:27:50.520
Yeah, so I did a three-part, three-hour webcast series in partnership with Mongo.

00:27:50.520 --> 00:28:05.280
And basically from concept to actually deploying it on DigitalOcean, actually, I rebuilt the PyPI.org website in MongoDB and then published it to the internet, which I then deleted.

00:28:05.280 --> 00:28:07.860
So I don't have to pay to keep it running because there's a real one.

00:28:07.860 --> 00:28:09.640
But yeah, there's like it's recorded.

00:28:09.640 --> 00:28:10.560
People can go check it out.

00:28:10.560 --> 00:28:11.620
You got the link in the show notes.

00:28:11.620 --> 00:28:12.120
So that's awesome.

00:28:12.120 --> 00:28:12.520
Yeah.

00:28:12.740 --> 00:28:13.060
Nice.

00:28:13.060 --> 00:28:14.120
It looks pretty fun.

00:28:14.120 --> 00:28:14.360
Yeah.

00:28:14.360 --> 00:28:14.580
Yeah.

00:28:14.580 --> 00:28:15.180
Thanks for the shout-out.

00:28:15.180 --> 00:28:17.160
Chris, anything you want to let people know about while you're here?

00:28:17.160 --> 00:28:17.640
Nope.

00:28:17.640 --> 00:28:18.600
I don't really have anything new.

00:28:18.600 --> 00:28:25.620
Maybe just keep an eye out for a few new posts coming up and try to step past in my new blog.

00:28:25.620 --> 00:28:26.800
Awesome.

00:28:26.800 --> 00:28:27.060
Yeah.

00:28:27.060 --> 00:28:29.680
There might be one about this asyncio.run, huh?

00:28:29.680 --> 00:28:30.180
Yeah.

00:28:30.180 --> 00:28:31.280
Awesome.

00:28:31.280 --> 00:28:32.000
Yeah, you called it out.

00:28:32.000 --> 00:28:33.040
You got to write it now.

00:28:33.040 --> 00:28:34.000
So, yeah.

00:28:34.380 --> 00:28:36.100
Remember, the internet is written in ink.

00:28:36.100 --> 00:28:38.360
And so this is permanent now.

00:28:38.360 --> 00:28:44.320
My next post was going to be about one of my modules, which uses asyncio a bunch.

00:28:44.320 --> 00:28:50.680
So maybe I'm going to go back and experiment with 3.7 and what changes I would have to do there to write it up.

00:28:50.680 --> 00:28:52.200
So this is pretty cool.

00:28:52.200 --> 00:28:52.760
Yeah, awesome.

00:28:52.760 --> 00:28:54.440
Well, Chris, thanks for being on the show.

00:28:54.440 --> 00:28:55.780
And Brian, thank you as always.

00:28:55.780 --> 00:28:56.380
Yeah, thank you.

00:28:56.380 --> 00:28:56.940
Thanks for having me.

00:28:56.940 --> 00:28:59.660
Thank you for listening to Python Bytes.

00:28:59.660 --> 00:29:02.240
Follow the show on Twitter via at Python Bytes.

00:29:02.360 --> 00:29:05.120
That's Python Bytes as in B-Y-T-E-S.

00:29:05.120 --> 00:29:08.560
And get the full show notes at pythonbytes.fm.

00:29:08.560 --> 00:29:12.880
If you have a news item you want featured, just visit pythonbytes.fm and send it our way.

00:29:12.880 --> 00:29:15.580
We're always on the lookout for sharing something cool.

00:29:15.580 --> 00:29:18.980
On behalf of myself and Brian Okken, this is Michael Kennedy.

00:29:18.980 --> 00:29:22.600
Thank you for listening and sharing this podcast with your friends and colleagues.