Effective PyCharm (2021 edition) Transcripts
Chapter: The Editor
Lecture: Working with the editor demo: Downloading RSS
0:00 Are you ready to do some cool things with our editor of course.
0:03 So we're going to work on a fun project here.
0:05 Let's go over to this podcast directory and now this is empty.
0:08 We're gonna create a new PyCharm project here,
0:12 go again. Go to PyCharm open directory or you just drag and drop on
0:17 Mac OS. We are in our empty project and it says we grabbed a
0:23 random broken interpreter for you. Let's not do that.
0:26 Let's go and add an interpreter to create a new virtual environment.
0:32 We're gonna need to install a couple things you want to make sure you have this
0:35 isolated environment. Now, one thing I always always do when I create a new
0:40 virtual environment in python is the tools that manage the packages of that environment are almost
0:47 certainly out of date. They're almost always out of date.
0:50 So for example, notice our virtual environment is activated here but I do a pip
0:55 list, going to show a couple of things and it says,
0:57 oh by the way, your version of pip is out of date.
1:01 Also your setup tools is and so is your wheels.
1:03 So something I always do is this just to make sure that we have the latest
1:13 tools to work with. We could have also done that over here in the python
1:17 packaging section, but that does it one at a time.
1:20 I'm just kind of a fan of having it done in the terminal.
1:23 We have the brand new project that we're ready to work with.
1:26 We're going to have 2 python files,
1:28 one that orchestrates the flow of the application and one that does the actual heavy lifting
1:33 the work. The first one let's call that program.
1:39 And the second one, let's call this service as it's going to go download some
1:44 stuff from the internet for us.
1:46 And because we're going to be using external packages,
1:49 we want people to be able to download this and install it and run it by
1:53 installing the things we need. We do that through a 'requirements.txt' file.
2:01 It's empty. And that's okay for now.
2:03 We're gonna start over here with our program and one of the things I like to
2:06 do is always have the highest level concept of our program right at the top and
2:11 then the functions that make that up below.
2:13 So we're gonna write a function called main over here and we'll put some stuff in
2:17 there. Maybe we're going to do something like that's something I'll print out a header
2:23 and here we'll just do a little print notice as we type a couple of things
2:28 about the editor that are really interesting Python obviously uses four spaces to indicate scope.
2:36 Right So if you indent here,
2:37 these four spaces, this print is part of the function,
2:40 not something that happens after it.
2:41 What's really awesome is as you type,
2:46 it knows if there's a colon and the next thing you're gonna do is go and
2:49 have four spaces. So that's really great.
2:51 We'll have a print statement here and let's just put little star across enter again.
2:58 Have that like this one other thing that's really amazing that I use all the time
3:03 is I actually wanna have three print lines now.
3:06 Go down and type print again.
3:08 But what's better is if I could just say I want exactly this again,
3:11 I could copy and paste it but I can hit on Mac.
3:14 OS 'cmd+d' or 'ctrl+d' on Windows or Linux and it makes another one and another
3:18 one just like that. So I'll just go put something here and we'll just keep
3:26 it nice and easy. Note,
3:28 just simple four manages eyeball it here.
3:29 Okay, so this is our little print header thing and what we need to do
3:35 is we're gonna go over to our main we want to use services or features from
3:40 our service file. So in the editor I can obviously go up here and type
3:45 import it. All sorts of good auto complete or all the built ins.
3:51 I could even import 'antigravity' which is fun but not helpful or what we could
3:55 import is our service right there.
3:57 Right. But let's imagine. I hadn't done that yet.
4:00 I just know that over in the service module there's going to be a function called
4:05 download info. Figure out what that is in a minute notice right away.
4:09 PyCharm says, well if you're going to use this thing called service there is
4:12 a braking problem. There's reds quickly as you can see the little red error up
4:17 here, the error up here and there's this light bulb and the light bulb called
4:23 a code intention. This one is not actually helping us here,
4:26 but we go over there now we get the red light bulb which shows us the
4:29 error and it says do you want to import that?
4:31 Because that's what's required for this to work?
4:34 Oh yeah, I did want to do that.
4:36 You could of course use the mouse.
4:38 But really what I normally do is like over your hit,
4:40 'Alt+enter', enter and it goes to the top.
4:44 Beautiful. Now I said I want to have this function called download info.
4:49 So the idea is we're going to go to the podcast is the talk python on
4:53 the podcast. We're going to download the rss feed and parse it and then we'll
4:58 use the service to ask questions about it.
5:00 Like what is the title of this episode?
5:02 What is the number of that episode and so on.
5:05 Will be able to ask questions about it.
5:07 But let's just go and download that information first.
5:10 I notice there's a problem right away.
5:13 It says, you know, this thing doesn't exist.
5:16 Well, guess what we alt + enter it.
5:18 It will go and create that function over on the services again.
5:22 This is part of that understanding the entire project structure,
5:25 right, I'm over here working in program and it says,
5:28 well, you need to modify service,
5:30 that module. So let's do that,
5:33 That's great. But when you go over here and focus on how this function works
5:37 for now. What we want to do is we want to go to the talk
5:41 python to me podcast and pull down the rss feed.
5:44 Let's have a quick look at that.
5:46 Over here. We've got a source version.
5:48 Just a view, source version of the Source and it is pretty opaque.
5:53 There's a lot of like embedded html and all sorts of stuff,
5:56 but I took this URL and I threw it into a visualizeer that
6:01 views xml a little bit better code beautify.
6:04 So what we got here is rss at the top and within there there's a thing
6:09 called Channel and that describes stuff about like the title and description and then there's a
6:14 bunch of items. Here's an item,
6:17 here's an item, here's an item and each item has a title.
6:21 A link here is the enclosure for the MP3 as a pub date and so
6:27 on. What we want to do is somehow download and then understand this file.
6:34 Maybe that sounds complicated and when you look at it over here it feels like it's
6:38 probably going to be complicated, but remember this is python,
6:42 it's going to be fine. Now.
6:44 Right away you can see the URL variable is creat out right here.
6:49 What does that mean? If I click on it,
6:50 I'll even get a little more info.
6:52 It says this variable is not used,
6:55 right We have a variable,
6:56 it's not used as if we had an argument like is admin or whatever.
7:01 You can also see the same type of thing.
7:03 Here's an argument, not user parameter.
7:05 Here is a local variable not used.
7:07 And generally that means something is either getting missed forgotten or you're doing stuff that no
7:12 longer makes sense and you should remove it.
7:15 But the reason it's great for us is we just haven't quite got started yet.
7:19 So now what we're gonna do is we're gonna go and use requests.
7:22 Remember over here we have no requests or Python packages,
7:28 we have no request. So we're gonna say the responses 'requests.get(url)
7:34 All right, well what's happening here?
7:37 Clearly another one of these errors so we can get some help from PyCharm.
7:42 It says, how about this?
7:44 I think request is a package on PyPI.
7:47 How about we install that and do an import requests at the top.
7:50 Yes, please do that. Fantastic.
7:54 Now why does this has requests?
7:57 Not sure. Okay, now,
7:58 what we can do also it has another warning,
7:59 it says we want to put this into the requirements.
8:02 Now sometimes it's a great idea to pin your version.
8:07 Sometimes you don't want to because this might evolve over time,
8:10 I'm just going to specify by itself.
8:11 But if this was your app,
8:12 you're maintaining it, you probably want to pin the version.
8:15 So we hit okay, here we go.
8:16 Now requests is recorded in there And it's ready to go.
8:20 So what else can we do?
8:21 We want to make sure this succeeded and requests as this cool thing that if you
8:25 don't get a 200 or a two,
8:26 a one or a redirect that then results in one of those,
8:29 it'll crash. You can say raise for status and notice all the awesome help that
8:34 we get here. All I said was dot but remember I could just type status
8:38 he says, oh, status code or raised for status,
8:41 which did you want? So that is really,
8:44 really cool and we can get down and just get the text as 'resp.text'
8:48 So now we've got to this point,
8:52 presumably we've got all this gnarly looking stuff and let's just do a quick print of
8:57 the text and see what happens.
8:59 Let's try to run this. Well,
9:00 we haven't got no run configuration so we can add configuration slowly or we can right
9:05 click and say run and get it quickly.
9:07 But when I run it it's not going to do what you expect.
9:11 Don't think this print statement won't run.
9:14 Great. Run It ran exited with code zero,
9:17 that's success. But no output what happened over here.
9:22 Unlike some languages. C++,
9:24 C# and so on.
9:26 The fact that of a main method means nothing to python.
9:28 If we don't call it explicitly,
9:31 it's not going to run. So you're probably familiar with this,
9:34 this concept at the end. So we say 'if__name = __ main',
9:43 that means this thing is being invoked directly and not imported.
9:46 So you should do the thing that you do,
9:48 which will be to run Main.
9:50 This is so common that in PyCharm they're going to help us out.
9:54 So instead of typing that if I just type main,
9:58 the thing with the parentheses at the top,
10:00 that's just auto completing the function I wrote.
10:02 But the one at the bottom,
10:03 see the great text if dunder name equals under main.
10:06 Boom, that's one of these things called a live template in PyCharm.
10:11 We also have them. So if I like a class A I want to have
10:15 a property, I could just type prop and then type name of the property without
10:20 auto complete. There there we go.
10:21 So there's all these cool live templates that are available for us and they work sometimes
10:27 in classes sometimes at the function level,
10:29 sometimes in html. Sometimes in python,
10:32 you can go over to the settings and search for live templates and then say,
10:38 well I'm interested in the ones for python,
10:40 like completing dictionary comprehension or something like that.
10:45 Okay, so very, very cool feature of the editor of these live templates and
10:50 let's just go around the main do a little cleanup.
10:53 Now when we run it. Here we go,
10:56 there's our super crazy Xml down there.
10:59 Notice how large that scroll bar goes.
11:02 So it looks like this is working.
11:04 This download is working, but we don't want to just download it.
11:08 We want to parse it and understand it again.
11:10 It sounds complicated, but because it's python,
11:13 not so much. Let's have up here at the top.
11:16 Let's have this thing called episodes.
11:18 And let's make this be a dictionary.
11:21 Right? So we're going to store by maybe having the show ID.
11:24 Or episode ID here and then information about it.
11:28 Then what kind of information do we want?
11:30 We're going to use this thing called a named 'tuple'.
11:32 We could use a class but there's so many features in the editor around named 'tuple'
11:36 I'd like to show you.
11:37 So let's have a quick look at that.
11:39 I'm going to have this type,
11:40 I'm going to call me putting this order an episode.
11:44 This will be a named tuple.
11:46 Again, I don't have to remember to import it happens automatically for us.
11:53 PyCharm also groups stuff like so this is from the standard library and this is
11:56 an external thing. So for example,
12:02 I had something else that came from the standard library.
12:05 It groups them up here and then puts the third party stuff there.
12:07 Obviously when we don't care about cache.
12:10 So here we're gonna have a named tuple and what goes in here.
12:13 So I know there's arguments. But what are they?
12:17 I can hit 'cmd+p' and it will actually show you all of the information.
12:23 That's super super helpful right now what we gotta do is say the name like episode
12:28 and then a string that has the fields.
12:31 So let's have a title link and uh date.
12:35 And also let's give it an ID.
12:37 Like an episode ID.
12:38 Okay beautiful. So this is looking really good.
12:44 That's what we want to store and want to create one of these episodes and we're
12:47 going to put it in there.
12:48 We'll look it up by it's ID.
12:51 Well how are we going to do that?
12:52 How are we going to parse all of this text apart?
12:55 What we're gonna do is going to create a dom xml document object model.
13:01 Using an elementary where does 'Elementree' come from?
13:06 I'm not sure. Let's find out.
13:08 Oh look it comes from 'xml.etree.
13:10 .ElementTree. There we go.
13:13 That's what we want. And then it has this function 'fromstring' like this text
13:19 Now, do we need this variable text over here separately?
13:23 Probably not. We could just in line that right?
13:25 We could take this and just write that there.
13:27 I could go and change the code or I could go to this and hit 'ctrl+t'
13:31 and type in line to see more about this later the refactory in support
13:36 but let's just clean that up a little bit there.
13:39 Not really returning things. Wouldn't stop there and now what we need to do is
13:42 just loop over all of the items.
13:45 Remember this means something very specific when we talk about items,
13:49 it's this thing that has the title and the link in the pub date.
13:54 Do we get the items? Well we use expats,
13:57 we go over here and we say find all,
14:01 we have the rss and then we have channel in the way of item together item
14:09 and let's just print out the length item to make sure that we're getting something here
14:14 Alright again, wait for to download 324.
14:18 Perfect. That looks like we're getting something that makes a lot of sense.
14:23 So let's go out here and just quickly loop over these and save that information.
14:28 I'm gonna want the number of the item as well as the actual episode.
14:33 So let's say idx,
14:34 item in item not the items itself but we want to turn that
14:41 into a tuple with the number and then the value.
14:44 So this would be enumerate, You can also say 'start=0' because our podcast
14:51 actually started on episode zero. Fantastic.
14:55 Now let's just go over here and create one of these episodes.
14:59 We'll say here's an episode, remember this is our named tuple what goes in here
15:04 now it shows me real quick but if I move away and I forget that I
15:08 get 'cmd+p' again, see title,
15:10 link date and ID.
15:11 Okay so the title, this would be 'item.find'.
15:17 We can just give it this and go and get the text because we got what
15:20 we find is a node we don't want the node,
15:22 we want just the value. And again we're going to do this a couple times
15:26 So 'cmd+d'. 'cmd+d'.
15:29 So on this will be the link notice the link is highlighted for the name tuple
15:34 and this is really amazing.
15:35 See and has these variables and it knows their arguments just by the fact that they're
15:39 there. That's really cool. What's the next one date would be pub date like
15:44 that And then the last one is just going to be the item and we're going
15:50 to go to our episodes and put episodes will go to the ID
15:55 Is going to be E.
15:57 Like this. Fantastic. So if we go over here we should be able to
16:05 see something if we just print on our episodes our update is having a problem and
16:10 I believe that because that's a capital D.
16:12 Let's again here we go. Look at that episode zero is actually this.
16:19 It looks like we've got it backwards doesn't it?
16:21 So we're going to need something like blend of 'items -id' there we go.
16:27 Let's try this minus one. Perfect 323.
16:36 and we go a little to the right 322.
16:42 322 Fantastic. Look at that,
16:44 we're downloading this off the internet and we've been kind of bouncing back and forth between
16:49 writing code in the future. Writing code see in the future but hopefully that felt
16:53 entirely seamless to you. A couple of things I want you to notice.
16:57 We did not go to the documentation,
16:59 we didn't go to the documentation for requests.
17:02 We didn't go to the documentation for E tree.
17:04 We didn't go and like have to look back at this when we were down here
17:09 to try to remember. Although I think I did once but that's just weird habit
17:12 I wouldn't have had to I could have just hit 'cmd+p' downside of their
17:19 and it showed me well that one was the date and so on.
17:22 Why didn't we have to do that?
17:23 That's because the editor is supporting us all along the way.
17:26 We didn't have to go to PyPI.
17:28 to realise we're going to install requests.
17:30 I just said I think I want to use requests.
17:32 It's like well that's a package.
17:34 We should probably put that in your 'requirements.txt'.
17:36 And we should import it up here and we should pip install
17:39 it. All of that stuff happened seamlessly.
17:42 This is just scratching the surface and we're going to keep going on this example.
17:46 I want to pause and kind of reflect on what we've done so far and appreciate where we are.