From 85738299b6a6c22b8bd16612825e8ea80c8e79d2 Mon Sep 17 00:00:00 2001 From: Script Kid Date: Sun, 16 Apr 2017 16:06:07 +0200 Subject: [PATCH] Removed redundant spaces --- transcripts/05-Generators/1.txt | 130 ++++++++-------- transcripts/05-Generators/2.txt | 94 +++++------ transcripts/05-Generators/3.txt | 226 +++++++++++++-------------- transcripts/05-Generators/4.txt | 266 ++++++++++++++++---------------- transcripts/05-Generators/5.txt | 116 +++++++------- transcripts/05-Generators/6.txt | 200 ++++++++++++------------ transcripts/05-Generators/7.txt | 128 +++++++-------- transcripts/06-methods/1.txt | 44 +++--- 8 files changed, 602 insertions(+), 602 deletions(-) diff --git a/transcripts/05-Generators/1.txt b/transcripts/05-Generators/1.txt index 9d379f2..243b191 100644 --- a/transcripts/05-Generators/1.txt +++ b/transcripts/05-Generators/1.txt @@ -1,73 +1,73 @@ -
0:01 Let's talk about collections, list comprehension, +0:01 Let's talk about collections, list comprehension, 0:03 generators and generator expressions. -0:06 All of these concepts are extremely central to this idea of Pythonic code,  -0:10 many of them are very unique to Python actually.  -0:13 The first item we are going to look at is iteration.  -0:16 We saw that Python does not have a numerical "for loop",  -0:19 there is no "for(i=0; ;i++)" style loop, you literally work with sequences,  -0:24 you iterate over collections and so on.  +0:06 All of these concepts are extremely central to this idea of Pythonic code, +0:10 many of them are very unique to Python actually. +0:13 The first item we are going to look at is iteration. +0:16 We saw that Python does not have a numerical "for loop", +0:19 there is no "for(i=0; ;i++)" style loop, you literally work with sequences, +0:24 you iterate over collections and so on. 0:26 There is many built in types that work that way -0:28 such as lists and dictionaries and so on,  -0:31 but if we had our own type we defined,  -0:33 we might want to be able to iterate over it as well.  -0:35 Here is the ShoppingCart class,  +0:28 such as lists and dictionaries and so on, +0:31 but if we had our own type we defined, +0:33 we might want to be able to iterate over it as well. +0:35 Here is the ShoppingCart class, 0:38 and you can add items to it that you are going to buy later, -0:41 possibly we'd like to create an API such that you can  -0:44 iterate over the shopping cart and get the items back.  -0:46 Let's have a look over in PyCharm and see how that goes.  -0:50 So here is basically the same code and we are defining this thing  -0:53 called the cart item and it's just really a container for a name and a price,  +0:41 possibly we'd like to create an API such that you can +0:44 iterate over the shopping cart and get the items back. +0:46 Let's have a look over in PyCharm and see how that goes. +0:50 So here is basically the same code and we are defining this thing +0:53 called the cart item and it's just really a container for a name and a price, 0:57 down on line 15 here, we are going to add three items to our cart, -1:01 a guitar, a cd and an iPhone.  -1:04 What if we wanted to loop over our cart - maybe it works right now,  -1:08 let's just try, so if we want to write the code "for item in cart:",  -1:12 maybe we'll just print this out, so we'll print,  -1:16 let's do the name and we'll do the price here,  -1:19 we'll do a little format so we'll say item.name, item.price.  -1:25 And let's do a little header here, so items in your cart.  -1:28 You can see that PyCharm is warning us  -1:30 we are kind of going down a bad path here, so it's like  +1:01 a guitar, a cd and an iPhone. +1:04 What if we wanted to loop over our cart - maybe it works right now, +1:08 let's just try, so if we want to write the code "for item in cart:", +1:12 maybe we'll just print this out, so we'll print, +1:16 let's do the name and we'll do the price here, +1:19 we'll do a little format so we'll say item.name, item.price. +1:25 And let's do a little header here, so items in your cart. +1:28 You can see that PyCharm is warning us +1:30 we are kind of going down a bad path here, so it's like 1:34 "this is not going to work", but let's go ahead and give it a try, -1:35 just to see what the error is.  -1:38 Boom, ShoppingCart object is not iterable.  +1:35 just to see what the error is. +1:38 Boom, ShoppingCart object is not iterable. 1:41 Ok, so we'd like to write this code but how do we do it? -1:44 the ability to add iteration to a type is based on the Python data model  -1:47 which all the dunder methods comprise.  -1:50 So we can come up here and add this particular one,  -1:53 we can say "def __iter__" and form this method  -1:56 we have to return iterator object, which has a length and next.  -2:01 If we just want to loop over the items as they are,  -2:03 we can leverage the underlined collection class itself  -2:06 and it knows how to create one of these  -2:07 so we could just say "self.items.__iter__"  -2:12 go back down here, PyCharm is happy, that's a good sign, let's see if it works.  -2:16 Boom, items in your cart: guitar, cd, iPhone. Beautiful.  +1:44 the ability to add iteration to a type is based on the Python data model +1:47 which all the dunder methods comprise. +1:50 So we can come up here and add this particular one, +1:53 we can say "def __iter__" and form this method +1:56 we have to return iterator object, which has a length and next. +2:01 If we just want to loop over the items as they are, +2:03 we can leverage the underlined collection class itself +2:06 and it knows how to create one of these +2:07 so we could just say "self.items.__iter__" +2:12 go back down here, PyCharm is happy, that's a good sign, let's see if it works. +2:16 Boom, items in your cart: guitar, cd, iPhone. Beautiful. 2:20 What if we wanted to have a little more control than just exposing -2:24 the underline structure, or underline item here,  +2:24 the underline structure, or underline item here, 2:27 what if we wanted to say "sort these and then hand them back"? -2:31 We can come over here and we could say sorted_items = sorted  -2:36 and we could pass self.items, and we could pass a key selector,  -2:41 we could say here is a lambda that given an item is going to return item.price,  -2:46 and then we can return sorted_items.__iter__  -2:55 now you can see we have out items but sorted,  -2:57 not necessarily the same way they were stored before  -3:00 and we could even go and say I'd like the negative price here,  -3:04 so now we have the most expensive ones first.  -3:08 So you might think that this is fairly distasteful here and I don't really like it either,  -3:12 we are going to talk more later about generators,  -3:16 but if you are familiar with the yield keyword,  -3:19 we could write something like this: "for i in sorted items  -3:23 yield i", we could write this code as well,  -3:26 and this would do basically the same thing,  -3:29 it returns the generator rather than list but that's fine.  -3:33 So take your pick, we'll talk more about yield later.  -3:36 Ok, we saw that in order to add iteration to our shopping cart,  -3:40 we just need to add a __iter__ method here  -3:44 rather than just exposing the underline self.items  -3:47 we are actually exposing a sorted version of it as a generator.  -3:51 So now we come over here we add some items into it and if you want,  -3:55 we can do a for in loop over our cart point out the items as you saw  -3:58 and we can grab once we have them, the name and the price and print those out.  -4:02 So it's super easy to add custom iterations to your type  -4:05 and building on this Python data model with the dunder methods  -4:08 sometimes called magic methods is a very Pythonic thing to do.  +2:31 We can come over here and we could say sorted_items = sorted +2:36 and we could pass self.items, and we could pass a key selector, +2:41 we could say here is a lambda that given an item is going to return item.price, +2:46 and then we can return sorted_items.__iter__ +2:55 now you can see we have out items but sorted, +2:57 not necessarily the same way they were stored before +3:00 and we could even go and say I'd like the negative price here, +3:04 so now we have the most expensive ones first. +3:08 So you might think that this is fairly distasteful here and I don't really like it either, +3:12 we are going to talk more later about generators, +3:16 but if you are familiar with the yield keyword, +3:19 we could write something like this: "for i in sorted items +3:23 yield i", we could write this code as well, +3:26 and this would do basically the same thing, +3:29 it returns the generator rather than list but that's fine. +3:33 So take your pick, we'll talk more about yield later. +3:36 Ok, we saw that in order to add iteration to our shopping cart, +3:40 we just need to add a __iter__ method here +3:44 rather than just exposing the underline self.items +3:47 we are actually exposing a sorted version of it as a generator. +3:51 So now we come over here we add some items into it and if you want, +3:55 we can do a for in loop over our cart point out the items as you saw +3:58 and we can grab once we have them, the name and the price and print those out. +4:02 So it's super easy to add custom iterations to your type +4:05 and building on this Python data model with the dunder methods +4:08 sometimes called magic methods is a very Pythonic thing to do. \ No newline at end of file diff --git a/transcripts/05-Generators/2.txt b/transcripts/05-Generators/2.txt index 2936d92..6f24b63 100644 --- a/transcripts/05-Generators/2.txt +++ b/transcripts/05-Generators/2.txt @@ -1,58 +1,58 @@ -
0:01 Next, let's talk about testing for containment and various sequences +0:01 Next, let's talk about testing for containment and various sequences 0:05 If you want to look for an item in a set, -0:07  in a dictionary, in a list, those types of things,  +0:07  in a dictionary, in a list, those types of things, 0:10 and you are new to Python you might look for some kind of find 0:13 or index of type of method on the type itself. -0:17 But in Python, we have a special keyword to do this test,  -0:20 over here in PyCharm we have a list,  +0:17 But in Python, we have a special keyword to do this test, +0:20 over here in PyCharm we have a list, 0:22 a set and a dictionary and the way we test -0:24 for containment in them all the same,  -0:26 so if we'd run it, you can see we are just printing out these values  -0:29 and if you look at the numbers, you probably recognize them  -0:33 as the Fibonacci sequence up to 34 anyway  -0:36 or five here where I had to write them out,  -0:38 so what we are going to do is we are going to parse out  +0:24 for containment in them all the same, +0:26 so if we'd run it, you can see we are just printing out these values +0:29 and if you look at the numbers, you probably recognize them +0:33 as the Fibonacci sequence up to 34 anyway +0:36 or five here where I had to write them out, +0:38 so what we are going to do is we are going to parse out 0:40 a number gathered from the user, -0:42 and then we are going to test whether this is in the set.  -0:45 So, here we'll just do a few "if" tests and maybe we can do this  -0:48 as a tertiary sort of expression,  -0:51 so we can say "print" like so, so we are going to say  -0:54 we'll print out something is in the set  +0:42 and then we are going to test whether this is in the set. +0:45 So, here we'll just do a few "if" tests and maybe we can do this +0:48 as a tertiary sort of expression, +0:51 so we can say "print" like so, so we are going to say +0:54 we'll print out something is in the set 0:57 and then we'll do out "if" test, we'll say "if n is in nums_list" -1:04 and then maybe say a list here, keep the same order,  -1:07 otherwise we'll say "not in list".  -1:10 All right, so the test here is "n in nums list", all right,  -1:14 so this actually goes through and it searches the elements in it  -1:16 and it does a comparison not on index but by value,  +1:04 and then maybe say a list here, keep the same order, +1:07 otherwise we'll say "not in list". +1:10 All right, so the test here is "n in nums list", all right, +1:14 so this actually goes through and it searches the elements in it +1:16 and it does a comparison not on index but by value, 1:20 and then it'll tell you yes or no it's here, -1:22 then we could do the same thing as you'll see for the set  -1:25 and we could also do it for the dictionary.  -1:30 All right, let's run it and figure it out,  -1:32 here it says enter a number to test for the small Fibonacci set or a sequence  -1:36 and let's say well, say 21, 21 is in  the list, 21 is in the set,  -1:41 but because I was lazy and didn't write them all out, 21 is not in the dictionary;  -1:45 let's try again, how about 1, it should be in all of them yes, it's in.  -1:48 So, "if item in container", this even works for strings,  -1:54 so if we had some text here like "Why did the multithreaded chicken cross the street?"  -1:59 do you know? Well it depends on when you ask it,  -2:03 you'll always get a different answer,  +1:22 then we could do the same thing as you'll see for the set +1:25 and we could also do it for the dictionary. +1:30 All right, let's run it and figure it out, +1:32 here it says enter a number to test for the small Fibonacci set or a sequence +1:36 and let's say well, say 21, 21 is in  the list, 21 is in the set, +1:41 but because I was lazy and didn't write them all out, 21 is not in the dictionary; +1:45 let's try again, how about 1, it should be in all of them yes, it's in. +1:48 So, "if item in container", this even works for strings, +1:54 so if we had some text here like "Why did the multithreaded chicken cross the street?" +1:59 do you know? Well it depends on when you ask it, +2:03 you'll always get a different answer, 2:04 this time we are going to get "Other side to the get". -2:08 So I could ask a question word, so here we'll say  +2:08 So I could ask a question word, so here we'll say 2:14 something, we'll do this not the tertiary way, we can say something like this, 2:17 "if word in text: print" such and such is in such and such, -2:29 there, so we could say ask user for a word, they type it in,  -2:32 we can do the same in test for a string, let's try,  -2:36 first look for 7 which should not be there, now I'll look for chicken,  -2:42 chicken is in the "Why did the multithreaded chicken cross the street",  -2:45 let's try it again, this time we'll enter 2 and here we'll put a cat.  -2:51 Right, so cat I don't believe appears in here.  -2:53 Cat is not in this string.  -2:56 All right, so let's see that in a graphic,  -2:57 so here we are just going to work with dictionaries as you saw,  -2:59 it's basically the same across the three types of containers we worked with.  -3:02 Here we could try to directly index into this dictionary and say  -3:06 I want the thing with key 2 but as we saw in other examples,  -3:09 this could give us a KeyError, if it's not there,  -3:11 so we might want to do this sort of check first style  +2:29 there, so we could say ask user for a word, they type it in, +2:32 we can do the same in test for a string, let's try, +2:36 first look for 7 which should not be there, now I'll look for chicken, +2:42 chicken is in the "Why did the multithreaded chicken cross the street", +2:45 let's try it again, this time we'll enter 2 and here we'll put a cat. +2:51 Right, so cat I don't believe appears in here. +2:53 Cat is not in this string. +2:56 All right, so let's see that in a graphic, +2:57 so here we are just going to work with dictionaries as you saw, +2:59 it's basically the same across the three types of containers we worked with. +3:02 Here we could try to directly index into this dictionary and say +3:06 I want the thing with key 2 but as we saw in other examples, +3:09 this could give us a KeyError, if it's not there, +3:11 so we might want to do this sort of check first style 3:14 so we could say if 2 is in the dictionary, -3:17 then we can safely access it because we know it's not going to KeyError.  +3:17 then we can safely access it because we know it's not going to KeyError. \ No newline at end of file diff --git a/transcripts/05-Generators/3.txt b/transcripts/05-Generators/3.txt index 30b1e82..f86b8e3 100644 --- a/transcripts/05-Generators/3.txt +++ b/transcripts/05-Generators/3.txt @@ -1,125 +1,125 @@ -
0:01 When I think about idioms that are particularly Pythonic,  -0:03 slicing has got to be one of those.  -0:06 Slicing lets you take things like strings and lists and so on,  -0:09 and even much more advanced items as we'll see  -0:12 and create very concise syntax  -0:15 and very understandable syntax subsets of these items.  -0:19 So, let's go look at this in code.  -0:21 So here I have a main method, it's calling a Fibonacci function  -0:24 and it returns set of Fibonacci numbers that are less than 200,  +0:01 When I think about idioms that are particularly Pythonic, +0:03 slicing has got to be one of those. +0:06 Slicing lets you take things like strings and lists and so on, +0:09 and even much more advanced items as we'll see +0:12 and create very concise syntax +0:15 and very understandable syntax subsets of these items. +0:19 So, let's go look at this in code. +0:21 So here I have a main method, it's calling a Fibonacci function +0:24 and it returns set of Fibonacci numbers that are less than 200, 0:28 it returns these as a list, in the beginning -0:30 I just print them out so you can see what we would have to work with,  -0:33 so here are our Fibonacci numbers,  -0:35 and suppose we want the first five,  -0:38 well there is a variety of ways we could do this,  -0:40 we could do a little loop and gather them up and break out of it  -0:43 after we get to five and so on,  -0:45 but in Python, we can go to our list,  -0:48 and we can just say: "I would like to go from the zeroth item,  -0:52 up to but not including the fifth item", something like this,  -0:55 and then if I print first five, you'll see we actually get the first five.  -1:01 Now, we could write it like this,  -1:03 but Python has a lot of conventions around slicing,  -1:06 so if you are going to start at the beginning you can say just ":5"  -1:11 and it says go from the beginning to five.  -1:13 So we should get the same output, and we do.  -1:16 Down here, if we want to actually go from the second to the seventh item,  -1:19 we'll say just print it out like this, let's be clear what we mean here,  -1:23 we mean the thing at index 2 up to and including the thing at index 7.  -1:27 So we'll say 2 and that would give us just the item index 2  -1:30 or the third item up to, now for slices,  -1:33 it does not include the value put here so you want to put one higher,  -1:38 let's just verify this, ok so if we count by index 0, 1, 2 so then 2 is here,  -1:44 3, 4, 5, 6 seventh index item is 21, so we did get exactly  -1:50 what we were looking for using 2 to 8.  -1:53 We can do more interesting stuff, we can also go and get the n  -1:55 so I could say nums and I could put something here,  -2:00 we could start by saying "len of nums",  -2:02 and then this value, this is not so amazing but we could say like -3 here,  -2:08 and this will kind of work, so here we've got the last 3, great,  +0:30 I just print them out so you can see what we would have to work with, +0:33 so here are our Fibonacci numbers, +0:35 and suppose we want the first five, +0:38 well there is a variety of ways we could do this, +0:40 we could do a little loop and gather them up and break out of it +0:43 after we get to five and so on, +0:45 but in Python, we can go to our list, +0:48 and we can just say: "I would like to go from the zeroth item, +0:52 up to but not including the fifth item", something like this, +0:55 and then if I print first five, you'll see we actually get the first five. +1:01 Now, we could write it like this, +1:03 but Python has a lot of conventions around slicing, +1:06 so if you are going to start at the beginning you can say just ":5" +1:11 and it says go from the beginning to five. +1:13 So we should get the same output, and we do. +1:16 Down here, if we want to actually go from the second to the seventh item, +1:19 we'll say just print it out like this, let's be clear what we mean here, +1:23 we mean the thing at index 2 up to and including the thing at index 7. +1:27 So we'll say 2 and that would give us just the item index 2 +1:30 or the third item up to, now for slices, +1:33 it does not include the value put here so you want to put one higher, +1:38 let's just verify this, ok so if we count by index 0, 1, 2 so then 2 is here, +1:44 3, 4, 5, 6 seventh index item is 21, so we did get exactly +1:50 what we were looking for using 2 to 8. +1:53 We can do more interesting stuff, we can also go and get the n +1:55 so I could say nums and I could put something here, +2:00 we could start by saying "len of nums", +2:02 and then this value, this is not so amazing but we could say like -3 here, +2:08 and this will kind of work, so here we've got the last 3, great, 2:12 we could use our convention that I pointed out before, -2:15 that if you are at the beginning or the end,  -2:17 you can omit it, so we could write it like this,  -2:21 also still get the last three, but in true Pythonic fashion,  -2:24 we could do better than that.  -2:26 We can say we'd like to start 3 items back and then go to the end.  -2:30 Beautiful, that way we don't even care,  -2:33 have to look or know what the length is, so that's really nice.  -2:38 So let's put this under the absolutely Pythonic last 3 version.  -2:43 All of this stuff is working within memory lists  -2:45 and we could do with strings and other types as well,  -2:48 but the title was slicing collections and more,  -2:51 so how far can we take this more - well,  -2:53 this is pretty interesting - from the database,  -2:57 if we look over here in this slicing support file,  -3:01 we are not going to cover SQLAlchemy in detail in this course,  -3:04 but we've got a class that we are mapping to a SQLAlchemy database  -3:08 as an id an x,y and a value, these values I believe are between 0 and 1,  -3:13 OK and it stores this into a local slicing_db.sqlite file and it connects to it,  -3:20 we are going to import this session factory here  -3:22 to actually create a connection to the database.  -3:24 Now, if we look at the database, ok there is nothing over here, right now,  +2:15 that if you are at the beginning or the end, +2:17 you can omit it, so we could write it like this, +2:21 also still get the last three, but in true Pythonic fashion, +2:24 we could do better than that. +2:26 We can say we'd like to start 3 items back and then go to the end. +2:30 Beautiful, that way we don't even care, +2:33 have to look or know what the length is, so that's really nice. +2:38 So let's put this under the absolutely Pythonic last 3 version. +2:43 All of this stuff is working within memory lists +2:45 and we could do with strings and other types as well, +2:48 but the title was slicing collections and more, +2:51 so how far can we take this more - well, +2:53 this is pretty interesting - from the database, +2:57 if we look over here in this slicing support file, +3:01 we are not going to cover SQLAlchemy in detail in this course, +3:04 but we've got a class that we are mapping to a SQLAlchemy database +3:08 as an id an x,y and a value, these values I believe are between 0 and 1, +3:13 OK and it stores this into a local slicing_db.sqlite file and it connects to it, +3:20 we are going to import this session factory here +3:22 to actually create a connection to the database. +3:24 Now, if we look at the database, ok there is nothing over here, right now, 3:28 but if we go to our project and we drop this in here, -3:33 you can see we have all this data  -3:35 and the part that we are going to look at is this value,  -3:36 so we would like to use slicing to get the top 3 highest values  -3:40 out of this database,  -3:42 OK, so let's see how that works.  -3:45 Up at the top, we are importing session factory and measurement,  -3:49 so let's create a session I'll say session factory we'll call that,  +3:33 you can see we have all this data +3:35 and the part that we are going to look at is this value, +3:36 so we would like to use slicing to get the top 3 highest values +3:40 out of this database, +3:42 OK, so let's see how that works. +3:45 Up at the top, we are importing session factory and measurement, +3:49 so let's create a session I'll say session factory we'll call that, 3:54 and at the end let's remember to close the session, -3:58 we'll create a query here, we'll say "session.query of Measurement",  -4:07 and we want to say "filter(Measurement.value) is greater than .9",  -4:12 we are going to order by Measurement.value.desc().  -4:17 Ok, so this is great, maybe we could just come over here  -4:21 and do a ".all" to get this back as a list  -4:25 and then I could just print out the query,  +3:58 we'll create a query here, we'll say "session.query of Measurement", +4:07 and we want to say "filter(Measurement.value) is greater than .9", +4:12 we are going to order by Measurement.value.desc(). +4:17 Ok, so this is great, maybe we could just come over here +4:21 and do a ".all" to get this back as a list +4:25 and then I could just print out the query, 4:27 I am not sure it's really a query but whatever, if we run this, -4:33 you realize what are the challenges - you have to spell filter correctly,  -4:38 here we go,  -4:41 once that works, you can see we have a bunch of these back  -4:43 from the database and we could even order it.  -4:47 Let's go over here to our engine and turn on tracing,  -4:50 what this will do is this will actually show us  -4:54 the SQL commands going against our database,  -4:57 so in the end down here you can see basically "SELECT *  -5:02 FROM measurements ORDER by", you know,  +4:33 you realize what are the challenges - you have to spell filter correctly, +4:38 here we go, +4:41 once that works, you can see we have a bunch of these back +4:43 from the database and we could even order it. +4:47 Let's go over here to our engine and turn on tracing, +4:50 what this will do is this will actually show us +4:54 the SQL commands going against our database, +4:57 so in the end down here you can see basically "SELECT * +5:02 FROM measurements ORDER by", you know, 5:04 where the value is greater than .9, order by the value descending, OK. -5:08 Oops, here is the select part, so this is pretty cool,  -5:11 how does slicing have anything to do with this, all right,  +5:08 Oops, here is the select part, so this is pretty cool, +5:11 how does slicing have anything to do with this, all right, 5:14 so if let's take away this all, if I want just the top 3 measurements, 5:21 I can actually use slicing to say give me a subset of the results 5:25 from the database, -5:26 all right, so I could say something like this:  -5:30 "top 3 = " and I could say "query,  -5:33 go from the beginning up to 3" and that would give me the top 3 records,  -5:37 let's just print those out really quick, so look at this,  -5:42 SELECT * FROM table WHERE value is this,  +5:26 all right, so I could say something like this: +5:30 "top 3 = " and I could say "query, +5:33 go from the beginning up to 3" and that would give me the top 3 records, +5:37 let's just print those out really quick, so look at this, +5:42 SELECT * FROM table WHERE value is this, 5:45 ORDER BY that, LIMIT and OFFSET and the two values -5:48 we're passing are .9 for the WHERE clause  -5:52 and then 3 for the LIMIT and 0 for the OFFSET,  -5:55 so first 3 ORDER by descending, so those are going to be the top 3,  -5:58 now we could actually go a little farther and say well,  -6:00 what we are really looking for is just the measurements,  +5:48 we're passing are .9 for the WHERE clause +5:52 and then 3 for the LIMIT and 0 for the OFFSET, +5:55 so first 3 ORDER by descending, so those are going to be the top 3, +5:58 now we could actually go a little farther and say well, +6:00 what we are really looking for is just the measurements, 6:03 so I could say "m.value for m in query up to 3" -6:08 like that and then I'll actually show just the values.  -6:12 So those are the highest 3 values and you can see  -6:14 they are very high and descending, how amazing is that?  -6:17 So, the reason I took the time to do this SQLAlchemy example  -6:22 is slicing is cool and at first it feels like OK,  -6:25 this is a cool way to work with like lists and strings,  -6:28 but slicing is so much more than that,  -6:30 slicing is deeply integrated into many of the APIs and packages  -6:36 that you are going to work with, and so while this is really cool, this right here,  -6:41 this is super amazing and this really shows  -6:44 the deep power in a breath of slicing.  -6:48 So let's see this in a graphic.  -6:50 All right, so here is our numbers again that we want the values at index 2 to 7  -6:54 or we would say 2:8 remember, the last item is not included,  +6:08 like that and then I'll actually show just the values. +6:12 So those are the highest 3 values and you can see +6:14 they are very high and descending, how amazing is that? +6:17 So, the reason I took the time to do this SQLAlchemy example +6:22 is slicing is cool and at first it feels like OK, +6:25 this is a cool way to work with like lists and strings, +6:28 but slicing is so much more than that, +6:30 slicing is deeply integrated into many of the APIs and packages +6:36 that you are going to work with, and so while this is really cool, this right here, +6:41 this is super amazing and this really shows +6:44 the deep power in a breath of slicing. +6:48 So let's see this in a graphic. +6:50 All right, so here is our numbers again that we want the values at index 2 to 7 +6:54 or we would say 2:8 remember, the last item is not included, 6:57 we want the last 3, the best way to do that would be "I want to go back 3 -7:01 and then the end", so -3:end, that worked perfectly,  -7:05 we could even create a database query  -7:07 and get to say give me the top 3 measurements :3 so 0 to 3  -7:12 and you can see that actual query generator is SELECT * FROM Measurements  -7:15 WHERE measurement... da da da da LIMIT 3 OFFSET 0.  -7:19 Amazing.  +7:01 and then the end", so -3:end, that worked perfectly, +7:05 we could even create a database query +7:07 and get to say give me the top 3 measurements :3 so 0 to 3 +7:12 and you can see that actual query generator is SELECT * FROM Measurements +7:15 WHERE measurement... da da da da LIMIT 3 OFFSET 0. +7:19 Amazing. \ No newline at end of file diff --git a/transcripts/05-Generators/4.txt b/transcripts/05-Generators/4.txt index 34a422f..2506567 100644 --- a/transcripts/05-Generators/4.txt +++ b/transcripts/05-Generators/4.txt @@ -1,144 +1,144 @@ -0:01 Here is a function called classic_fibonacci  -0:03 and what you do is you pass a limit to it  -0:05 and it will compute all the Fibonacci numbers up to that limit.  -0:09 Notice we have a list called nums and it does all the work,  -0:12 fills this list up and once it's finally done, it gives you all the numbers.  -0:16 Well, what if you want the first million Fibonacci,  -0:20 what if you need the first 5 million Fibonacci numbers,  -0:23 how long will this method take to run?  -0:25 What if you don't know how many you need,  -0:27 what if you want to start looking at them and you say  -0:29 well, I am looking for the time when I am going to the Fibonacci numbers  -0:34 and the second one is a prime number  -0:37 the third one is the cube of the first one in the sequence,  -0:41 who knows when that is, you are just looking through  -0:43 and you are going to decide, oh, now it matches, now I have got enough of these.  -0:47 What if you were looking through this  -0:49 and you said I am going to ask for 5 million Fibonacci numbers  -0:52 and it was really the 5 millionth and first, right, maybe you just gave up.  -0:57 So we are going to look at a different way to write exactly the same code  -1:00 that doesn't have these limitations,  -1:02 allows the consumers to process  -1:04 as much of these actually infinite series as it needs  -1:08 and yet does this in a very much on demand, high performance way.  -1:13 This concept is called generators and it has this keyword called yield.  -1:17 So let's look at this in code.  -1:19 So, here is that same function, we can run it,  -1:22 it shows you the first few numbers in the Fibonacci sequence  -1:25 we are passing a limit here,  -1:28 we are passing a 100 so we want just the first set of Fibonacci numbers  -1:32 less than a 100.  -1:33 So this is fine, but let's see if we can do better.  -1:36 Before we move on, let's actually debug this a little bit.
 -1:39 So I am going to put a break point here,  -1:40 we are going to step into this, all right,  -1:43 so here we are and let's step into this method,  -1:46 and now we are stepping along, stepping along,  -1:48 and notice we are going through the list,  -1:50 you can see up here it actually shows you the list being built,  -1:53 it shows you the numbers so PyCharm is really cool in that sense,  -1:55 you can see the list growing, but notice we are the whole time staying here  -1:59 until we get to the limit of 100 which happens pretty soon here,  -2:03 right now, and then, we are going through them and processing  -2:07 you can "m" is the various values here.  -2:11 So that's fine for small numbers, but what like I said,  -2:15 in the beginning, what if we don't know what the upper bound is,  -2:17 or what if we have to put a really huge number here,  -2:22 what do you think happens to the memory consumption as that number grows,  -2:25 obviously we have to gather all the numbers that preceded it  -2:29 and hold them in memory all at once and then you get the answer.  -2:32 So Python has this really cool keyword called "yield",  -2:36 and let's come down here and let's call this a generator_fibonacci,  -2:41 so we are going to do a few things, that if you have seen this before,  -2:45 you know it's pretty straightforward,  -2:47 if you've not seen this, it'll probably blow your mind.  -2:49 All right, so what we are going to do is we are going to say  -2:51 instead of having this limit, we would like to work on the infinite series,  -2:56 now if I just run this code, two things will happen,  -2:59 first of all it's going to crash in a hurry, even if for some reason it wouldn't crash,  +0:01 Here is a function called classic_fibonacci +0:03 and what you do is you pass a limit to it +0:05 and it will compute all the Fibonacci numbers up to that limit. +0:09 Notice we have a list called nums and it does all the work, +0:12 fills this list up and once it's finally done, it gives you all the numbers. +0:16 Well, what if you want the first million Fibonacci, +0:20 what if you need the first 5 million Fibonacci numbers, +0:23 how long will this method take to run? +0:25 What if you don't know how many you need, +0:27 what if you want to start looking at them and you say +0:29 well, I am looking for the time when I am going to the Fibonacci numbers +0:34 and the second one is a prime number +0:37 the third one is the cube of the first one in the sequence, +0:41 who knows when that is, you are just looking through +0:43 and you are going to decide, oh, now it matches, now I have got enough of these. +0:47 What if you were looking through this +0:49 and you said I am going to ask for 5 million Fibonacci numbers +0:52 and it was really the 5 millionth and first, right, maybe you just gave up. +0:57 So we are going to look at a different way to write exactly the same code +1:00 that doesn't have these limitations, +1:02 allows the consumers to process +1:04 as much of these actually infinite series as it needs +1:08 and yet does this in a very much on demand, high performance way. +1:13 This concept is called generators and it has this keyword called yield. +1:17 So let's look at this in code. +1:19 So, here is that same function, we can run it, +1:22 it shows you the first few numbers in the Fibonacci sequence +1:25 we are passing a limit here, +1:28 we are passing a 100 so we want just the first set of Fibonacci numbers +1:32 less than a 100. +1:33 So this is fine, but let's see if we can do better. +1:36 Before we move on, let's actually debug this a little bit. +1:39 So I am going to put a break point here, +1:40 we are going to step into this, all right, +1:43 so here we are and let's step into this method, +1:46 and now we are stepping along, stepping along, +1:48 and notice we are going through the list, +1:50 you can see up here it actually shows you the list being built, +1:53 it shows you the numbers so PyCharm is really cool in that sense, +1:55 you can see the list growing, but notice we are the whole time staying here +1:59 until we get to the limit of 100 which happens pretty soon here, +2:03 right now, and then, we are going through them and processing +2:07 you can "m" is the various values here. +2:11 So that's fine for small numbers, but what like I said, +2:15 in the beginning, what if we don't know what the upper bound is, +2:17 or what if we have to put a really huge number here, +2:22 what do you think happens to the memory consumption as that number grows, +2:25 obviously we have to gather all the numbers that preceded it +2:29 and hold them in memory all at once and then you get the answer. +2:32 So Python has this really cool keyword called "yield", +2:36 and let's come down here and let's call this a generator_fibonacci, +2:41 so we are going to do a few things, that if you have seen this before, +2:45 you know it's pretty straightforward, +2:47 if you've not seen this, it'll probably blow your mind. +2:49 All right, so what we are going to do is we are going to say +2:51 instead of having this limit, we would like to work on the infinite series, +2:56 now if I just run this code, two things will happen, +2:59 first of all it's going to crash in a hurry, even if for some reason it wouldn't crash, 3:04 if we had like infinite memory, it will still never return, right, -3:07 it's just going to keep adding this infinite series  -3:10 but of course it's going to run out of memory.  -3:12 So in Python, we can do something both cleaner and better here,  -3:15 so what we can do is we can use this yield keyword,  -3:18 and yield is like return but instead of returning from the method,  -3:21 it just says hey I want to create a collection or a sequence  -3:25 and here is one of the items,  -3:26 and here is one of the items, so we'll yield current.  -3:29 So, that's cool, so that's going to actually generate - continue to yield the items,  -3:34 you might wonder well, how we ever get a value out of it, so let's go find out.  -3:41 So we are going to do this, now if I run this, it won't crash or anything,  -3:44 it will just keep spitting up numbers scrolling to the right until it kind of goes crazy,  -3:49 so this is an infinite sequence but as a consumer of the infinite sequence,  -3:56 I can decide "OK, I've had enough".  +3:07 it's just going to keep adding this infinite series +3:10 but of course it's going to run out of memory. +3:12 So in Python, we can do something both cleaner and better here, +3:15 so what we can do is we can use this yield keyword, +3:18 and yield is like return but instead of returning from the method, +3:21 it just says hey I want to create a collection or a sequence +3:25 and here is one of the items, +3:26 and here is one of the items, so we'll yield current. +3:29 So, that's cool, so that's going to actually generate - continue to yield the items, +3:34 you might wonder well, how we ever get a value out of it, so let's go find out. +3:41 So we are going to do this, now if I run this, it won't crash or anything, +3:44 it will just keep spitting up numbers scrolling to the right until it kind of goes crazy, +3:49 so this is an infinite sequence but as a consumer of the infinite sequence, +3:56 I can decide "OK, I've had enough". 3:58 So what I will say here is let's say "if m is greater than 100", -4:02 we can use the same test as we have on line 36,  -4:05 we can just break out of our loop,  +4:02 we can use the same test as we have on line 36, +4:05 we can just break out of our loop, 4:07 all right, so let's run this, we should see the same output, 4:11 we do, right, -4:12 classic and generator have the same output but if we go into debugger here,  -4:15 it's going to be all sorts of different, all right, so we step in,  -4:19 here we are in generator_fibonacci just like we were before  -4:22 and here is our "while True",  +4:12 classic and generator have the same output but if we go into debugger here, +4:15 it's going to be all sorts of different, all right, so we step in, +4:19 here we are in generator_fibonacci just like we were before +4:22 and here is our "while True", 4:24 now watch what happens as soon as we get the current, which is 1 and we say "yield", -4:27 immediately we are back here,  -4:29 we printed it and now look where we return into that loop,  -4:33 we just kind of resume the method back here, see there is this back and forth,  -4:37 I'll do this a few times, notice now we are going to jump back into this one  -4:42 and that current is 3 and next is 5,  -4:44 this is like a state machine that remembers where it left off and can be resumed,  -4:48 but even though it's an infinite sequence, we don't generate all of them,  -4:52 it's more like on demand as you pull items out of it it will compute them,  -4:56 so only as much as you pull, you have to pay in terms of computation.  -5:00 The other really cool benefit is nowhere are we adding this to a list  -5:03 so nowhere are we using basically nowhere are we storing  -5:07 more than one item at memory at a time so memory is not a problem in this situation.  +4:27 immediately we are back here, +4:29 we printed it and now look where we return into that loop, +4:33 we just kind of resume the method back here, see there is this back and forth, +4:37 I'll do this a few times, notice now we are going to jump back into this one +4:42 and that current is 3 and next is 5, +4:44 this is like a state machine that remembers where it left off and can be resumed, +4:48 but even though it's an infinite sequence, we don't generate all of them, +4:52 it's more like on demand as you pull items out of it it will compute them, +4:56 so only as much as you pull, you have to pay in terms of computation. +5:00 The other really cool benefit is nowhere are we adding this to a list +5:03 so nowhere are we using basically nowhere are we storing +5:07 more than one item at memory at a time so memory is not a problem in this situation. 5:11 So these generators are really cool and all you have to do is use the yield keyword. -5:17 If you compared against classic_fibonacci,  -5:20 not only is it better performance, more flexible,  -5:23 generates all the numbers and so on,  -5:25 it's actually shorter and once you get your mind around yield,  -5:28 it's actually easier to understand.  -5:31 So that's cool, we can also take down here,  -5:34 we can create a something like an even_generator  +5:17 If you compared against classic_fibonacci, +5:20 not only is it better performance, more flexible, +5:23 generates all the numbers and so on, +5:25 it's actually shorter and once you get your mind around yield, +5:28 it's actually easier to understand. +5:31 So that's cool, we can also take down here, +5:34 we can create a something like an even_generator 5:39 and if I were to pass some kind of set here, some kind of number generator like this, 5:45 I could say "for n in numbers, if n % 2==0" -5:52 our standard even test, we will say yield n.  -5:56 So given any set of numbers,  -5:58 whether this is a list or a generator, it doesn't matter, it doesn't care,  -6:02 it's going to pull the even ones out and then down here,  -6:04 I can define a method called even_fibonacci and we'll say something like this:  -6:11 "for n in even_generator()", and then we can give it generator_fibonacci  -6:19 and we can say "yield from this".  -6:22 So this will let us compose these things so we can actually create pipelines  -6:25 from one to the next.  -6:28 So let's run our even Fibonacci through here  -6:31 and we should get only the even numbers that are also coming  -6:34 from the Fibonacci set and remember,  -6:36 this is an infinite sequence because we are starting out  +5:52 our standard even test, we will say yield n. +5:56 So given any set of numbers, +5:58 whether this is a list or a generator, it doesn't matter, it doesn't care, +6:02 it's going to pull the even ones out and then down here, +6:04 I can define a method called even_fibonacci and we'll say something like this: +6:11 "for n in even_generator()", and then we can give it generator_fibonacci +6:19 and we can say "yield from this". +6:22 So this will let us compose these things so we can actually create pipelines +6:25 from one to the next. +6:28 So let's run our even Fibonacci through here +6:31 and we should get only the even numbers that are also coming +6:34 from the Fibonacci set and remember, +6:36 this is an infinite sequence because we are starting out 6:40 with the innermost bit, -6:41 an infinite sequence which itself is a generator  -6:45 that will take as many items are there and pass them back.  +6:41 an infinite sequence which itself is a generator +6:45 that will take as many items are there and pass them back. 6:49 But because we don't actually do the work on this part until we pull on it, -6:53 and we don't do the work on this part until we pull on it, it goes something like this,  -6:57 pull here, that means go pull this, which pulls on this, which will pull on this piece,  -7:02 one item at a time and then when we decide down here we are done, we'll break out.  -7:08 So look at this, we have the even Fibonacci numbers,  -7:11 and there is not many so 2, 8, and 144. Here they are, brilliant.  -7:17 If you want more, we can get more.  -7:20 Want up to 10 000, no problem, there they are, 10 000; up to a million,  -7:25 there they are up to a million.  +6:53 and we don't do the work on this part until we pull on it, it goes something like this, +6:57 pull here, that means go pull this, which pulls on this, which will pull on this piece, +7:02 one item at a time and then when we decide down here we are done, we'll break out. +7:08 So look at this, we have the even Fibonacci numbers, +7:11 and there is not many so 2, 8, and 144. Here they are, brilliant. +7:17 If you want more, we can get more. +7:20 Want up to 10 000, no problem, there they are, 10 000; up to a million, +7:25 there they are up to a million. 7:27 Boom, like that. -7:29 All right, so let's look at this in a graphic,  -7:32 remember, we already talked about our algorithm here,  -7:35 it's a perfect implementation of Fibonacci but it has the limitations  -7:38 where you have to say how many you want  -7:40 before you actually get a chance to look at the numbers,  -7:43 and you can't look at too many or you'll run out of memory  -7:45 if for some reason you had infinite memory, you'd run out of time.  -7:48 We can switch to a simpler version using the yield keyword  -7:52 create this as a generator and it actually does no work  -7:56 until you start pulling on the generator.  -7:59 More of what we saw that you can write multiple generators  -8:02 and compose them in a pipeline style which is really awesome  -8:05 especially in things like data science. +7:29 All right, so let's look at this in a graphic, +7:32 remember, we already talked about our algorithm here, +7:35 it's a perfect implementation of Fibonacci but it has the limitations +7:38 where you have to say how many you want +7:40 before you actually get a chance to look at the numbers, +7:43 and you can't look at too many or you'll run out of memory +7:45 if for some reason you had infinite memory, you'd run out of time. +7:48 We can switch to a simpler version using the yield keyword +7:52 create this as a generator and it actually does no work +7:56 until you start pulling on the generator. +7:59 More of what we saw that you can write multiple generators +8:02 and compose them in a pipeline style which is really awesome +8:05 especially in things like data science. \ No newline at end of file diff --git a/transcripts/05-Generators/5.txt b/transcripts/05-Generators/5.txt index f00e6bb..44c001a 100644 --- a/transcripts/05-Generators/5.txt +++ b/transcripts/05-Generators/5.txt @@ -1,66 +1,66 @@ -
0:01 So we've seen how powerful and amazing  -0:03 the yield keyword is to build these generators.  -0:05 In Python 3 there is actually a new feature that makes working with generators  -0:09 as well as recursive functions even better.  -0:14 So over here we have some code and what it's going to do is  -0:18 it's going to go to some root directory  -0:20 here I just grabbed the transcripts from my other class,  -0:23 Python Jumpstart By Building Ten Apps,  -0:26 and the transcripts are here in these demos folder,  -0:28 and we want to just process through those,  -0:31 so I've written this function called get_files() and I give it a root directory,  -0:35 and it returns using yield the generator that we can iterate over and print them out.  -0:40 So this is pretty straight forward, we are going to go to a directory,  -0:44 this will be the top level directory, and we'll say for each item I'd like to look at it,  -0:48 let's build up it's full path and ask: "is it a file,  -0:50 or is it a directory?", so if it's s file we'll say "yeah,  +0:01 So we've seen how powerful and amazing +0:03 the yield keyword is to build these generators. +0:05 In Python 3 there is actually a new feature that makes working with generators +0:09 as well as recursive functions even better. +0:14 So over here we have some code and what it's going to do is +0:18 it's going to go to some root directory +0:20 here I just grabbed the transcripts from my other class, +0:23 Python Jumpstart By Building Ten Apps, +0:26 and the transcripts are here in these demos folder, +0:28 and we want to just process through those, +0:31 so I've written this function called get_files() and I give it a root directory, +0:35 and it returns using yield the generator that we can iterate over and print them out. +0:40 So this is pretty straight forward, we are going to go to a directory, +0:44 this will be the top level directory, and we'll say for each item I'd like to look at it, +0:48 let's build up it's full path and ask: "is it a file, +0:50 or is it a directory?", so if it's s file we'll say "yeah, 0:54 I found one of the files in this directory, 0:56 here go loop over this", but if it is itself a directory, 1:00 well let's just hold off on that for a minute. -1:03 So here if I run it you can see on my Mac I have this .ds store thing  -1:07 and then I have this txt file and then that's that.  -1:11 So not many files. But it turns out there is subdirectories in here  -1:14 and maybe I want to look inside them  -1:16 if I had a function that could look inside a folder,  -1:19 and tell you what was in it, tell you the files that are in it,  -1:22 that would be awesome, I could use that right;  -1:24 well, what do I have right here, boom,  -1:27 so what we can do is we can use a concept called recursion  -1:29 and if you are used to recursion this makes perfect sense,  -1:32 but if you are not, it's quite interesting and sort of mind bending,  -1:36 so the idea is from within this function we are going to call the same function  -1:40 but with possibly, this time certainly, with different parameters,  -1:44 so we are going to work our way down the directory tree  -1:46 until there are no more subdirectories  -1:48 then we will stop calling our function but as long as there are subdirectories,  -1:51 we are going to be calling it like this,  -1:53 Now this returns a generator of files and technically  -1:56 it will return like a tree of generators, of files so how do I get the files out?  -2:02 Well, I could write this, "for f in files,  -2:05 get files" and then I could say "yield f" and so this is just the idea of recursion,  -2:11 there is no special feature here, but let's just verify it works.  -2:14 Boom, here you go, so you can see in app 10 I've got a couple of transcripts,  -2:19 in the conclusion I've got a couple of transcripts,  +1:03 So here if I run it you can see on my Mac I have this .ds store thing +1:07 and then I have this txt file and then that's that. +1:11 So not many files. But it turns out there is subdirectories in here +1:14 and maybe I want to look inside them +1:16 if I had a function that could look inside a folder, +1:19 and tell you what was in it, tell you the files that are in it, +1:22 that would be awesome, I could use that right; +1:24 well, what do I have right here, boom, +1:27 so what we can do is we can use a concept called recursion +1:29 and if you are used to recursion this makes perfect sense, +1:32 but if you are not, it's quite interesting and sort of mind bending, +1:36 so the idea is from within this function we are going to call the same function +1:40 but with possibly, this time certainly, with different parameters, +1:44 so we are going to work our way down the directory tree +1:46 until there are no more subdirectories +1:48 then we will stop calling our function but as long as there are subdirectories, +1:51 we are going to be calling it like this, +1:53 Now this returns a generator of files and technically +1:56 it will return like a tree of generators, of files so how do I get the files out? +2:02 Well, I could write this, "for f in files, +2:05 get files" and then I could say "yield f" and so this is just the idea of recursion, +2:11 there is no special feature here, but let's just verify it works. +2:14 Boom, here you go, so you can see in app 10 I've got a couple of transcripts, +2:19 in the conclusion I've got a couple of transcripts, 2:22 there is quite a few files that were in subdirectories here. Lovely. -2:25 And notice we actually are printing the directory as well,  -2:28 I'll turn that off for a minute. So those are just the files.  -2:33 So like I said, this is straight up recursion, and this is kind of not so great,  -2:38 we'd like to just say hey here are a bunch of items in a generator  +2:25 And notice we actually are printing the directory as well, +2:28 I'll turn that off for a minute. So those are just the files. +2:33 So like I said, this is straight up recursion, and this is kind of not so great, +2:38 we'd like to just say hey here are a bunch of items in a generator 2:43 and I would like to make all of those items part of my sequence, so in Python 3, -2:47 we can do this, we can say instead of just yield we can say yield from get files  -2:53 and full item and this is basically replacing that loop above  -2:57 so we can do it in kind of a inline sequence way, let's try it again,  +2:47 we can do this, we can say instead of just yield we can say yield from get files +2:53 and full item and this is basically replacing that loop above +2:57 so we can do it in kind of a inline sequence way, let's try it again, 3:00 we should get exactly the same output, 3:03 boom, we do, -3:04 beautiful, so "yield from", super helpful when you are doing recursion  -3:08 or you want to just grab a bunch of items from some kind of generator  -3:11 or set and throw them into your current set that you are trying to generate.  +3:04 beautiful, so "yield from", super helpful when you are doing recursion +3:08 or you want to just grab a bunch of items from some kind of generator +3:11 or set and throw them into your current set that you are trying to generate. 3:16 So here you can see we are calling "get items", -3:18 it's a generator because it's using the yield keyword  -3:21 and we are also calling it recursively  -3:23 and we are able to simplify that recursion using "yield from".  -3:27 So remember, this is a Python 3 only feature and in fact,  -3:29 it was introduced in Python 3.3 so it doesn't even work  -3:33 in the early versions of Python 3.  -3:35 That said, if you are working in 3.3 or above,  -3:38 it's a really cool way to simplify  generators.  +3:18 it's a generator because it's using the yield keyword +3:21 and we are also calling it recursively +3:23 and we are able to simplify that recursion using "yield from". +3:27 So remember, this is a Python 3 only feature and in fact, +3:29 it was introduced in Python 3.3 so it doesn't even work +3:33 in the early versions of Python 3. +3:35 That said, if you are working in 3.3 or above, +3:38 it's a really cool way to simplify  generators. \ No newline at end of file diff --git a/transcripts/05-Generators/6.txt b/transcripts/05-Generators/6.txt index 2ca5090..b095764 100644 --- a/transcripts/05-Generators/6.txt +++ b/transcripts/05-Generators/6.txt @@ -1,107 +1,107 @@ -
0:01 Let's continue our exploration of generators, -0:02 we saw that we can create generator functions using the yield keyword,  -0:06 we saw Python 3.3 added "yield from" to work with recursive generators  -0:11 and things like that - combining generators,  -0:14 those were all functions, so we were able to transform  +0:01 Let's continue our exploration of generators, +0:02 we saw that we can create generator functions using the yield keyword, +0:06 we saw Python 3.3 added "yield from" to work with recursive generators +0:11 and things like that - combining generators, +0:14 those were all functions, so we were able to transform 0:18 the way the function worked but what about loops, -0:21 what about things that are smaller,  -0:23 little bits of code like what we have on the screen here,  -0:26 we've got some kind of iterable set called measurements,  +0:21 what about things that are smaller, +0:23 little bits of code like what we have on the screen here, +0:26 we've got some kind of iterable set called measurements, 0:29 we want to loop over it and we want to find all the ones that have some value over 70, -0:33 we want to gather those up, so just like the drawbacks  -0:37 our Fibonacci sequence we already pass the limit had before,  -0:41 this loop has similar problem, but the yield keyword won't help us,  -0:45 so let's see what will.  -0:47 So here we have some code, we've created a named tuple,  -0:50 named Measurement, it's got an id, an x y coordinate and a value.  -0:53 So think of this like a 3 by 3 grid, here where we have numbers  -0:57 or measurements like temperature or something around there.  -1:01 So if we want to find all the locations that have some kind of high value  -1:05 or actually just look at what their measurements were,  -1:08 we could go through like this, we could write a loop,  -1:10 first we could create a list to gather the measurements,  -1:12 the high values, we loop over them, we do some kind of test and we add them up.  -1:17 All right, so that's ok, but it's not great.  -1:20 However, let's just look at the rest of the app really quickly before we are done,  -1:23 we are going to come up with this, these numbers in a variety of ways,  -1:26 we want to print them all out here,  -1:28 so if we just run it you can see here is the ones we got through the loop,  -1:31 so I am calling this c-style but it's really any procedural programming way  +0:33 we want to gather those up, so just like the drawbacks +0:37 our Fibonacci sequence we already pass the limit had before, +0:41 this loop has similar problem, but the yield keyword won't help us, +0:45 so let's see what will. +0:47 So here we have some code, we've created a named tuple, +0:50 named Measurement, it's got an id, an x y coordinate and a value. +0:53 So think of this like a 3 by 3 grid, here where we have numbers +0:57 or measurements like temperature or something around there. +1:01 So if we want to find all the locations that have some kind of high value +1:05 or actually just look at what their measurements were, +1:08 we could go through like this, we could write a loop, +1:10 first we could create a list to gather the measurements, +1:12 the high values, we loop over them, we do some kind of test and we add them up. +1:17 All right, so that's ok, but it's not great. +1:20 However, let's just look at the rest of the app really quickly before we are done, +1:23 we are going to come up with this, these numbers in a variety of ways, +1:26 we want to print them all out here, +1:28 so if we just run it you can see here is the ones we got through the loop, +1:31 so I am calling this c-style but it's really any procedural programming way 1:36 and of course this blocks while this runs, -1:38 now we can come down here we can take this code  -1:41 and we can do something a little bit different,  -1:42 we can create what's called a list comprehension,  +1:38 now we can come down here we can take this code +1:41 and we can do something a little bit different, +1:42 we can create what's called a list comprehension, 1:46 the result is going to be exactly the same, -1:48 the execution also will be basically exactly the same,  -1:50 but we can take this and more or less inline what we have here.  -1:54 Now it looks like you are going to start out and we are just going to define a list,  -1:58 but what in fact what we are going to do is we are going to define this thing  -2:00 called the comprehension that will loop over values and build up a list.  -2:04 So the first thing you put is the values that are going to go onto the list,  +1:48 the execution also will be basically exactly the same, +1:50 but we can take this and more or less inline what we have here. +1:54 Now it looks like you are going to start out and we are just going to define a list, +1:58 but what in fact what we are going to do is we are going to define this thing +2:00 called the comprehension that will loop over values and build up a list. +2:04 So the first thing you put is the values that are going to go onto the list, 2:07 you have to imagine in the next statement, -2:10 the next line you are going to have some kind of variables,  -2:12 so I am going to say "m" again and the "m" is going to have a value,  -2:15 I'll say for "m in measurements", just like above,  -2:18 and we'll say "if m.value is greater than or equal to 70",  -2:23 so high measurements are 1 to high measurements 2 are the same,  -2:27 this is more declarative, so this is pretty cool  -2:29 but they both sort of block and build this list,  -2:31 so in a lot of ways they are very similar,  -2:33 the benefit here is this can be passed as part of an expression,  -2:37 whereas this is like separate code suite that you have to stop and then run,  -2:41 you couldn't like pass this as an argument to a method,  -2:47 but like I say: This you can, you can compose them and so on.  -2:51 So let's see the results are the same, of course they are, excellent,  -2:54 so this executes and turns into a list but we talked about the generators,  -2:59 that let us only pull out the items as we pull or we iterate over the generator.  -3:05 So that's really cool, now we can do basically the same thing over here  -3:10 if you have square braces that means a list comprehension execute and return a list.  -3:14 If you have parenthesis but you put basically the same thing inside,  +2:10 the next line you are going to have some kind of variables, +2:12 so I am going to say "m" again and the "m" is going to have a value, +2:15 I'll say for "m in measurements", just like above, +2:18 and we'll say "if m.value is greater than or equal to 70", +2:23 so high measurements are 1 to high measurements 2 are the same, +2:27 this is more declarative, so this is pretty cool +2:29 but they both sort of block and build this list, +2:31 so in a lot of ways they are very similar, +2:33 the benefit here is this can be passed as part of an expression, +2:37 whereas this is like separate code suite that you have to stop and then run, +2:41 you couldn't like pass this as an argument to a method, +2:47 but like I say: This you can, you can compose them and so on. +2:51 So let's see the results are the same, of course they are, excellent, +2:54 so this executes and turns into a list but we talked about the generators, +2:59 that let us only pull out the items as we pull or we iterate over the generator. +3:05 So that's really cool, now we can do basically the same thing over here +3:10 if you have square braces that means a list comprehension execute and return a list. +3:14 If you have parenthesis but you put basically the same thing inside, 3:18 you create a generator that you can then iterate over, -3:21 this is just like writing a method with the yield keyword.  -3:25 So, if we just try to print out high measurements gen,  -3:29 you'll see that we actually just get a generator,  -3:31 not a bunch of values because they hasn't actually executed, hasn't pulled on it.  -3:36 So, in order to actually display the results we do this wrap it in a list,  -3:40 make it generate something that we can then print and then there it is,  -3:44 these list comprehensions are cool, there is other types of comprehensions as well,  -3:49 all right, the generators, the yield, and that's most interesting I suppose,  -3:53 but we can also create a dictionary suppose  -3:55 instead of just having the values, I'd like to say "given an id of a measurement,  -4:00 what is its value?", so we can come down here,  -4:03 we can do something like this, or so, but instead of just passing the value here,  -4:07 I will say "key:value", so I would say "m.id:m.value".  -4:13 Now if I run that, you can see here is the id value and id,  -4:17 here is some crazy id value is 73,  -4:20 but it is these values that you can look them up now  -4:23 by key not super helpful when you have 4 values or 5 whatever that is,  -4:27 but if you had hundreds of thousands we saw how amazing that could be,  -4:31 so this actually generates a dictionary because it's "key:value" for item in some set.  -4:37 Well, for item in some collection.  -4:39 Now we can also create just the distinct values  -4:42 if you look down here you'll notice 90 is repeated 3 times  -4:45 and if we just want to know what are the actual measurements,  -4:48 like was there a measurement of 90, was there a measurement of 73, and so on,  -4:52 the ideal structure for that would be set.  -4:56 So we can use almost the same syntax as the dictionary comprehension here,  -5:01 but instead of saying "key:value" we just put an item here,  -5:05 and if we use curly braces, and one value - not a key colon value - that becomes a set.  -5:11 And of course, the set is distinct items,  +3:21 this is just like writing a method with the yield keyword. +3:25 So, if we just try to print out high measurements gen, +3:29 you'll see that we actually just get a generator, +3:31 not a bunch of values because they hasn't actually executed, hasn't pulled on it. +3:36 So, in order to actually display the results we do this wrap it in a list, +3:40 make it generate something that we can then print and then there it is, +3:44 these list comprehensions are cool, there is other types of comprehensions as well, +3:49 all right, the generators, the yield, and that's most interesting I suppose, +3:53 but we can also create a dictionary suppose +3:55 instead of just having the values, I'd like to say "given an id of a measurement, +4:00 what is its value?", so we can come down here, +4:03 we can do something like this, or so, but instead of just passing the value here, +4:07 I will say "key:value", so I would say "m.id:m.value". +4:13 Now if I run that, you can see here is the id value and id, +4:17 here is some crazy id value is 73, +4:20 but it is these values that you can look them up now +4:23 by key not super helpful when you have 4 values or 5 whatever that is, +4:27 but if you had hundreds of thousands we saw how amazing that could be, +4:31 so this actually generates a dictionary because it's "key:value" for item in some set. +4:37 Well, for item in some collection. +4:39 Now we can also create just the distinct values +4:42 if you look down here you'll notice 90 is repeated 3 times +4:45 and if we just want to know what are the actual measurements, +4:48 like was there a measurement of 90, was there a measurement of 73, and so on, +4:52 the ideal structure for that would be set. +4:56 So we can use almost the same syntax as the dictionary comprehension here, +5:01 but instead of saying "key:value" we just put an item here, +5:05 and if we use curly braces, and one value - not a key colon value - that becomes a set. +5:11 And of course, the set is distinct items, 5:14 so here is a wide variety of ways to replace standard c-style -5:19 looping and gathering behavior into lists,  -5:25 replace it with the generators,  -5:27 replace it with dictionaries and replace it with sets,  -5:31 all of these constructs are highly Pythonic and used often  -5:35 especially when you are creating these pipelines and passing one to the next.  -5:40 All right, let's look at the core concept here, as a graphic.  -5:43 So we saw we have our direct loop style or c-procedural style code create a list,  -5:48 loop over a bunch of items, if they match some test we add them to our list.  -5:52 But, just like taking this type of algorithm and replacing it with yield  -5:56 worked really well in a function,  -5:59 we can do the same thing with loops inline using generator expressions.  -6:03 So, it's much of the same mechanics but the execution is vastly different  -6:08 so we say parenthesis for generator and then the value we want to get  -6:12 and then we loop over the item with the foreign loop  -6:15 and then we do a test with an if clause, there you have it,  -6:18 these generators are super useful, study them,  -6:21 you use them in a lot of places.  +5:19 looping and gathering behavior into lists, +5:25 replace it with the generators, +5:27 replace it with dictionaries and replace it with sets, +5:31 all of these constructs are highly Pythonic and used often +5:35 especially when you are creating these pipelines and passing one to the next. +5:40 All right, let's look at the core concept here, as a graphic. +5:43 So we saw we have our direct loop style or c-procedural style code create a list, +5:48 loop over a bunch of items, if they match some test we add them to our list. +5:52 But, just like taking this type of algorithm and replacing it with yield +5:56 worked really well in a function, +5:59 we can do the same thing with loops inline using generator expressions. +6:03 So, it's much of the same mechanics but the execution is vastly different +6:08 so we say parenthesis for generator and then the value we want to get +6:12 and then we loop over the item with the foreign loop +6:15 and then we do a test with an if clause, there you have it, +6:18 these generators are super useful, study them, +6:21 you use them in a lot of places. \ No newline at end of file diff --git a/transcripts/05-Generators/7.txt b/transcripts/05-Generators/7.txt index 350bc2f..57c18fe 100644 --- a/transcripts/05-Generators/7.txt +++ b/transcripts/05-Generators/7.txt @@ -1,72 +1,72 @@ -
0:01 Now let's look at determining how many items are in a generator.  -0:04 So if I have something like this, high measurements,  -0:06 and it's I am getting the value, looping over some collection called measurements,  -0:11 and I am doing a test, well, I actually have a really hard time  -0:15 knowing how many are in there,  -0:16 let's go look at that in PyCharm to see why.  -0:19 So this is basically the same code that we used to talk  -0:22 about generator expressions in the first place, this time,  -0:25 this is set actually, fix that, so here we have our high values,  -0:29 now if I try to print out the "len" of them, get the length,  +0:01 Now let's look at determining how many items are in a generator. +0:04 So if I have something like this, high measurements, +0:06 and it's I am getting the value, looping over some collection called measurements, +0:11 and I am doing a test, well, I actually have a really hard time +0:15 knowing how many are in there, +0:16 let's go look at that in PyCharm to see why. +0:19 So this is basically the same code that we used to talk +0:22 about generator expressions in the first place, this time, +0:25 this is set actually, fix that, so here we have our high values, +0:29 now if I try to print out the "len" of them, get the length, 0:33 you can see PyCharm is already trying to tell me I am going down a bad path, -0:36 but let's see what happens anyway.  -0:39 Boom, object or type generator has no length,  -0:42 what might be wrong with getting the length,  -0:44 well it could be infinite, and it might take forever to determine that,  -0:47 but most importantly this is not going to work, all right,  -0:50 so we are not going to do that because it crashes,  -0:53 we could do something like this, we could say "create a list and pass into it  +0:36 but let's see what happens anyway. +0:39 Boom, object or type generator has no length, +0:42 what might be wrong with getting the length, +0:44 well it could be infinite, and it might take forever to determine that, +0:47 but most importantly this is not going to work, all right, +0:50 so we are not going to do that because it crashes, +0:53 we could do something like this, we could say "create a list and pass into it 0:58 the high values in them", if you pass a collection here, -1:00 it will iterate overall the items and put it in the list and then I could print "len of list".  -1:06 However, one of the beautiful things with generators is  +1:00 it will iterate overall the items and put it in the list and then I could print "len of list". +1:06 However, one of the beautiful things with generators is 1:09 if even if there is a million items here, we only hold one in memory ever, -1:13 well if we do this, we kind of undo that,  -1:17 we now have one million of them in memory but let's just see that it works,  -1:20 ta da, 4, ok, 4, that's cool,  -1:25 so we can use a combination of some really cool things,  -1:29 so if I had something like, let me just do something simple here,  -1:32 I'll say some and say given any set of numbers I could add them up,  -1:36 so those 3 numbers should have 7, we should see 7 down here, perfect, ok,  -1:42 so we can use some to give it some kind of collection here, let me separate these  -1:50 so we can kind of isolate them, count here and we'll say "count equals this", right,  -1:55 so we could add this up using some, we could leverage this,  -1:58 along with another chained comprehension,  -2:02 so what do I want to put in here,  -2:04 for every item I see in here I would like to add one,  -2:06 because what I want to know is how many items not what is some of the values,  -2:10 so I could sum up the high values here, OK, now this actually broke,  -2:16 now this is worth knowing why did this break, so we have 4 and 0,  -2:20 obviously it should at least be 4 right, these are not 0 numbers that we saw,  -2:24 but here is the thing, unlike lists, once you run through a generator,  -2:28 it's done, you have to recreate it, so basically this,  -2:32 the fact that I did this used up the generator in a sense,  -2:36 you can only use them once, if you want to do it again you recreate it,  -2:38 if that's not going to work for you, create a list comprehension instead.  -2:42 There you go, so 375, there is not 375 items in there,  -2:46 there is 4 so what I want to do is somehow in the best,  +1:13 well if we do this, we kind of undo that, +1:17 we now have one million of them in memory but let's just see that it works, +1:20 ta da, 4, ok, 4, that's cool, +1:25 so we can use a combination of some really cool things, +1:29 so if I had something like, let me just do something simple here, +1:32 I'll say some and say given any set of numbers I could add them up, +1:36 so those 3 numbers should have 7, we should see 7 down here, perfect, ok, +1:42 so we can use some to give it some kind of collection here, let me separate these +1:50 so we can kind of isolate them, count here and we'll say "count equals this", right, +1:55 so we could add this up using some, we could leverage this, +1:58 along with another chained comprehension, +2:02 so what do I want to put in here, +2:04 for every item I see in here I would like to add one, +2:06 because what I want to know is how many items not what is some of the values, +2:10 so I could sum up the high values here, OK, now this actually broke, +2:16 now this is worth knowing why did this break, so we have 4 and 0, +2:20 obviously it should at least be 4 right, these are not 0 numbers that we saw, +2:24 but here is the thing, unlike lists, once you run through a generator, +2:28 it's done, you have to recreate it, so basically this, +2:32 the fact that I did this used up the generator in a sense, +2:36 you can only use them once, if you want to do it again you recreate it, +2:38 if that's not going to work for you, create a list comprehension instead. +2:42 There you go, so 375, there is not 375 items in there, +2:46 there is 4 so what I want to do is somehow in the best, 2:50 most efficient possible way go through this list and say -2:53 "for every time I find an item, give me one",  -2:56 so what I can do is I can create another generator,  -2:58 I can say "give me the number 1 for n in high values".  -3:03 OK, so what we are going to do is we are going to through and say  +2:53 "for every time I find an item, give me one", +2:56 so what I can do is I can create another generator, +2:58 I can say "give me the number 1 for n in high values". +3:03 OK, so what we are going to do is we are going to through and say 3:05 "every time you find a value, I don't care, I am not going to use this value", let's say 1, -3:10 and that's going to add it up, now remember,  +3:10 and that's going to add it up, now remember, 3:12 it's very Pythonic to say "if I am not going to use a value, 3:14 use this indicator say underscore", -3:17 like here is a variable that has to come out and be stored somewhere  -3:21 but by saying underscore I have no any intention of using it,  -3:24 so we should get the answer 4.  -3:26 Beautiful, so here we have our generator, you saw generators don't have a length,  -3:31 we can't use that, if we try to throw them into a list or something along those lines,  -3:35 that's not good because that undoes all the benefits of the generator,  -3:38 it loads everything in a memory all at once,  +3:17 like here is a variable that has to come out and be stored somewhere +3:21 but by saying underscore I have no any intention of using it, +3:24 so we should get the answer 4. +3:26 Beautiful, so here we have our generator, you saw generators don't have a length, +3:31 we can't use that, if we try to throw them into a list or something along those lines, +3:35 that's not good because that undoes all the benefits of the generator, +3:38 it loads everything in a memory all at once, 3:40 so we can use this cool combination of the sum method -3:44 and a chained generator expression,  -3:47 so the chained generator expression is give me one  -3:50 for every time you find an item in high measurements,  -3:52 which is itself a generator, and then if we sum up that set,  -3:55 we actually get the number of items in the generator.  -3:58 Remember, just be really careful it's used up after this,  -4:02 so if you want to run it again, you need to either recreate it  -4:06 by having the 5 lines above again,  -4:08 or turn into a list where you can reuse it over and over.  +3:44 and a chained generator expression, +3:47 so the chained generator expression is give me one +3:50 for every time you find an item in high measurements, +3:52 which is itself a generator, and then if we sum up that set, +3:55 we actually get the number of items in the generator. +3:58 Remember, just be really careful it's used up after this, +4:02 so if you want to run it again, you need to either recreate it +4:06 by having the 5 lines above again, +4:08 or turn into a list where you can reuse it over and over. \ No newline at end of file diff --git a/transcripts/06-methods/1.txt b/transcripts/06-methods/1.txt index 9e3991d..8d7472c 100644 --- a/transcripts/06-methods/1.txt +++ b/transcripts/06-methods/1.txt @@ -1,24 +1,24 @@ -
0:01 Our next category of Pythonic concepts and tips  -0:03 is going to be around functions and methods.  -0:06 Python is a multi paradigm programming language,  -0:09 we can write procedural code,  -0:10 we could write object oriented code,  -0:12 we could write functional code and with things like decorators  -0:15 we can even write aspect oriented code.  -0:17 Python's functional support is very strong,  -0:20 you'll see the functions and methods are first class symbols and citizens in Python  -0:25 and they are highly flexible and powerful.  -0:28 When you define a function or method with a def keyword,  +0:01 Our next category of Pythonic concepts and tips +0:03 is going to be around functions and methods. +0:06 Python is a multi paradigm programming language, +0:09 we can write procedural code, +0:10 we could write object-oriented code, +0:12 we could write functional code and with things like decorators +0:15 we can even write aspect-oriented code. +0:17 Python's functional support is very strong, +0:20 you'll see the functions and methods are first class symbols and citizens in Python +0:25 and they are highly flexible and powerful. +0:28 When you define a function or method with a "def" keyword, 0:32 you're really instantiating a function object and you can pass that object around -0:37 just like you can pass a number or a string or an instance of a class.  -0:41 You'll see that those function objects can even be changed at runtime  -0:45 you could dynamically add a field to a function  -0:47 just by saying function.value=something.  -0:50 Not saying that you should do that, but just considering the flexibility, right.  -0:55 Functions even allow you create things called closures  -0:57 both inline functions as well as lambda expressions,  -1:00 that's a very powerful programming technique often used in places  -1:03 like Javascript for data hiding and encapsulation.  -1:06 And finally with things like lambda expressions  +0:37 just like you can pass a number or a string or an instance of a class. +0:41 You'll see that those function objects can even be changed at runtime +0:45 you could dynamically add a field to a function +0:47 just by saying "function.value=something". +0:50 Not saying that you should do that, but just considering the flexibility, right. +0:55 Functions even allow you create things called closures, +0:57 both inline functions as well as lambda expressions, +1:00 that's a very powerful programming technique often used in places +1:03 like Javascript for data hiding and encapsulation. +1:07 And finally with things like lambda expressions 1:09 we can even define small inline methods as little bits of executable code -1:14 that we can pass around in super concise and composable ways.  +1:14 that we can pass around in super concise and composable ways. \ No newline at end of file