From 1239c61beacd632376260d53ce85d8f06de3546b Mon Sep 17 00:00:00 2001 From: SanketDG Date: Mon, 24 Aug 2015 02:09:45 +0530 Subject: [PATCH 001/152] fix ambiguity in namedtuple in collections.rst --- collections.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/collections.rst b/collections.rst index 7fd9094..c251b62 100644 --- a/collections.rst +++ b/collections.rst @@ -199,12 +199,12 @@ sure you read the official documentation after reading this. ``namedtuple`` ^^^^^^^^^^^^^^^^^^ -You might already be acquainted with tuples. A tuple is a lightweight -object type which allows to store a sequence of immutable Python -objects. They are just like lists but have a few key differences. The -major one is that unlike lists, **you can not change a value in a -tuple**. In order to access the value in a tuple you use integer indexes -like: +You might already be acquainted with tuples. A tuple is basically +a immutable list which allows you to store a sequence of values +separated by commas. They are just like lists but have a few key +differences. The major one is that unlike lists, **you can not +reassign an item in a tuple**. In order to access the value in a +tuple you use integer indexes like: .. code:: python From 1619c1dcb7ef73e78408fd80e554fb93be4d992e Mon Sep 17 00:00:00 2001 From: Pratyush Verma Date: Mon, 24 Aug 2015 19:24:23 +0530 Subject: [PATCH 002/152] Fix broken link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6a91dd0..0b3edb1 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Table of Contents: - [\*args and \*\*kwargs](args_and_kwargs.rst) - [Debugging](debugging.rst) - [Generators](generators.rst) -- [Map & Filter](map_&_filter.rst) +- [Map & Filter](map_filter.rst) - [``set`` Data Structure](set_-_data_structure.rst) - [Ternary Operators](ternary_operators.rst) - [Decorators](decorators.rst) From 8c5459e5c9462a6dc86b2efb2f9194af5b35c9f4 Mon Sep 17 00:00:00 2001 From: Josh McCullough Date: Mon, 24 Aug 2015 11:44:51 -0400 Subject: [PATCH 003/152] Edits to for/else. --- for_-_else.rst | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/for_-_else.rst b/for_-_else.rst index da01bf6..96a1cdf 100644 --- a/for_-_else.rst +++ b/for_-_else.rst @@ -1,12 +1,11 @@ -For - Else +``for/else`` ---------- Loops are an integral part of any language. Likewise ``for`` loops are an important part of Python. However there are a few things which most -beginners do not know about them. We will discuss a few of them one by -one. +beginners do not know about them. We will discuss a few of them one-by-one. -Let's first start of by what we know. We know that we can use for loops +Let's first start off with what we know. We know that we can use ``for`` loops like this: .. code:: python @@ -19,24 +18,24 @@ like this: # Banana # Mango -That is the very basic structure of a for loop. Now let's move on to +That is the very basic structure of a ``for`` loop. Now let's move on to some of the lesser known features of ``for`` loops in Python. -``else`` clause: +``else`` Clause ^^^^^^^^^^^^^^^^^^^^ -For loops also have an ``else`` clause which most of us are unfamiliar -with. The ``else`` clause executes when the loop completes normally. -This means that the loop did not encounter any ``break``. They are -really useful once you understand where to use them. I myself came to +``for`` loops also have an ``else`` clause which most of us are unfamiliar +with. The ``else`` clause executes after the loop completes normally. +This means that the loop did not encounter a ``break`` statement. They are +really useful once you understand where to use them. I, myself, came to know about them a lot later. The common construct is to run a loop and search for an item. If the -item is found, we break the loop using ``break``. There are two +item is found, we break out of the loop using the ``break`` statement. There are two scenarios in which the loop may end. The first one is when the item is found and ``break`` is encountered. The second scenario is that the loop -ends. Now we may want to know which one of these is the reason for a -loops completion. One method is to set a flag and then check it once the +ends without encountering a ``break` statement. Now we may want to know which one of these is the reason for a +loop's completion. One method is to set a flag and then check it once the loop ends. Another is to use the ``else`` clause. This is the basic structure of a ``for/else`` loop: @@ -64,8 +63,7 @@ documentation: break It finds factors for numbers between 2 to 10. Now for the fun part. We -can add an additional ``else`` block which catches the numbers which are -prime and tells us so: +can add an additional ``else`` block which catches the numbers which have no factors and are therefore prime numbers: .. code:: python From f6681c1c8d033d7c804da9b6fb000dc83ea11406 Mon Sep 17 00:00:00 2001 From: Josh McCullough Date: Mon, 24 Aug 2015 11:56:08 -0400 Subject: [PATCH 004/152] Edits to open Function. --- open_function.rst | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/open_function.rst b/open_function.rst index bd5b702..8281b2f 100644 --- a/open_function.rst +++ b/open_function.rst @@ -1,4 +1,4 @@ -Open function +``open`` Function ------------- `open `__ opens @@ -17,10 +17,10 @@ you spot them all? If not, read on. By the end of this article, you'll know what's wrong in the above code, and, more importantly, be able to avoid these mistakes in your own code. Let's start with the basics: -The return of open is a file handle, given out from the operating system +The return value from ``open`` is a file handle, given out from the operating system to your Python application. You will want to return this file handle once you're finished with the file, if only so that your application -won't reach the limit of the number of open file handle it can have at +won't reach the limit of the number of open file handles it can have at once. Explicitly calling ``close`` closes the file handle, but only if the @@ -28,7 +28,7 @@ read was successful. If there is any error just after ``f = open(...)``, ``f.close()`` will not be called (depending on the Python interpreter, the file handle may still be returned, but that's another story). To make sure that the file gets closed whether an exception occurs or not, -pack it into a ```with`` statement: +pack it into a ``with`` statement: .. code:: python @@ -53,11 +53,11 @@ or text mode (a string of characters). In general, if the format is written by humans, it tends to be text mode. ``jpg`` image files are not generally written by humans (and are -indeed not readable to humans), and you should therefore open them in -binary mode by adding a ``b`` to the text string (if you're following +indeed not readable by humans), and you should therefore open them in +binary mode by adding a ``b`` to the mode string (if you're following the opening example, the correct mode would be ``rb``). If you open something in text mode (i.e. add a ``t``, or nothing apart from -``r/r+/w/a``), you must also know which encoding to use - for a +``r/r+/w/a``), you must also know which encoding to use. For a computer, all files are just bytes, not characters. Unfortunately, ``open`` does not allow explicit encoding specification @@ -65,16 +65,16 @@ in Python 2.x. However, the function `io.open `__ is available in both Python 2.x and 3.x (where it is an alias of ``open``), and does the right thing. You can pass in the encoding with the -``encoding`` keyword. If you don't pass in any encoding, a system- (and -Python-) specific default will be picked. You may be tempted to rely on +``encoding`` keyword. If you don't pass in any encoding, a system -- and +Python -- specific default will be picked. You may be tempted to rely on these defaults, but the defaults are often wrong, or the default -encoding cannot actually express all characters (this will happen on +encoding cannot actually express all characters in the file (this will happen often on Python 2.x and/or Windows). So go ahead and pick an encoding. ``utf-8`` is a terrific one. When you write a file, you can just pick the encoding to your liking (or the liking of the program that will eventually read your file). -How do you find out which encoding a file you read has? Well, +How do you find out which encoding a file you're reading was written in? Well, unfortunately, there is no foolproof way to detect the encoding - the same bytes can represent different, but equally valid characters in different encodings. Therefore, you must rely on metadata (for example, @@ -93,11 +93,11 @@ determines whether it's JPG (hint: These files start with the bytes jpgdata = inf.read() if jpgdata.startswith(b'\xff\xd8'): - text = u'This is a jpeg file (%d bytes long)\n' + text = u'This is a JPEG file (%d bytes long)\n' else: text = u'This is a random file (%d bytes long)\n' with io.open('summary.txt', 'w', encoding='utf-8') as outf: outf.write(text % len(jpgdata)) -I am sure that now you would use ``open`` correctly! +I am sure that now you will use ``open`` correctly! From 2bb1d0a79548b0b7343931ee8f1a438e638cdc5a Mon Sep 17 00:00:00 2001 From: Josh McCullough Date: Mon, 24 Aug 2015 12:22:00 -0400 Subject: [PATCH 005/152] Edits to Targeting Python 2 & 3. --- targeting_python_2_3.rst | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/targeting_python_2_3.rst b/targeting_python_2_3.rst index e6c779d..40f9bb1 100644 --- a/targeting_python_2_3.rst +++ b/targeting_python_2_3.rst @@ -8,7 +8,7 @@ Just imagine that you have a very popular Python module which is use by hundreds of people but not all of them have Python 2 or 3. In that case you have two choices. The first one is to distribute 2 modules, one for Python 2 and the other for Python 3. The other choice is to modify your -current code and make is compatible with both Python 2 and 3. +current code and make it compatible with both Python 2 and 3. In this section I am going to highlight some of the tricks which you can employ to make a script compatible with both of them. @@ -16,20 +16,17 @@ employ to make a script compatible with both of them. **Future imports** The first and most important method is to use ``__future__`` imports. It -allows you to import Python 3 functionality in Python 2. Here is an -example: +allows you to import Python 3 functionality in Python 2. Here are a couple +examples: -- Context managers were new in Python 2.6+. For using them in Python 2.5 - you can use: +Context managers were new in Python 2.6+. For using them in Python 2.5 you can use: .. code:: python from __future__ import with_statement -- ``print`` function - ``print`` was changed to a function in Python 3. If you want to use it -in Python 2 you can import it from ``__future__``. +in Python 2 you can import it from ``__future__``: .. code:: python @@ -42,7 +39,7 @@ in Python 2 you can import it from ``__future__``. **Dealing with module renaming** -First tell me how you import packages in your script ? Most of us do +First, tell me how you import packages in your script ? Most of us do this : .. code:: python @@ -69,31 +66,31 @@ code below : import urllib2 as urllib_request # for Python 2 So let me explain the above code a little. We are wrapping our importing -code in a try except clause. We are doing it because in Python 2 there is -no ``urllib.request`` module and will result in an ImportError. The -functionality of ``urllib.request`` is provided by ``urllib2`` module in -Python 2. So now when in Python 2 we try to import ``urllib.request`` and -get an ``ImportError`` we tell Python to import ``urllib2`` instead. +code in a ``try/except`` clause. We are doing it because in Python 2 there is +no ``urllib.request`` module so this would result in an ``ImportError``. The +functionality of ``urllib.request`` is provided by the ``urllib2`` module in +Python 2. So, when using Python 2, we try to import ``urllib.request`` and +if we get an ``ImportError`` then we tell Python to import ``urllib2`` instead. The final thing you need to know about is the ``as`` keyword. It is -mapping the imported module to ``urllib_request``. So that now all of -the Classes and methods of ``urllib2`` are available to us by +mapping the imported module to ``urllib_request``. So that all of +the classes and methods within ``urllib2`` are available to us via the alias ``urllib_request``. **Obsolete Python 2 builtins** Another thing to keep in mind is that there are 12 Python 2 builtins which have been removed from Python 3. Make sure that you don't use them -in Python 2 as well in order to make your code compatible with Python 3. -Here is a way to enforce you to abandon these 12 builtins in Python 2 as -well. +in Python 2 in order to make your code compatible with Python 3. +Here is a way to enforce that you abandon these 12 builtins in Python 2 as +well: .. code:: python from future.builtins.disabled import * Now whenever you try to use the modules which are abandoned in Python 3, -it raises a NameError like this: +it raises a ``NameError`` like this: .. code:: python @@ -105,7 +102,7 @@ it raises a NameError like this: **External standard-library backports** There are a few packages in the wild which provide Python 3 -functionality in Python 2. For instance we have: +functionality in Python 2. For instance, we have: - enum ``pip install enum34`` - singledispatch ``pip install singledispatch`` From fb91e532dfd263b808d6252c8fb6db9d8667b753 Mon Sep 17 00:00:00 2001 From: Josh McCullough Date: Mon, 24 Aug 2015 12:28:59 -0400 Subject: [PATCH 006/152] Edits to Coroutines. --- coroutines.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/coroutines.rst b/coroutines.rst index 21ad8b5..3e6f091 100644 --- a/coroutines.rst +++ b/coroutines.rst @@ -27,7 +27,7 @@ We then commonly use it in a ``for`` loop like this: It is fast and does not put a lot of pressure on memory because it **generates** the values on the fly rather then storing them in a list. -Now if we use ``yield`` in the above example more generally we get a +Now, if we use ``yield`` in the above example, more generally, we get a coroutine. Coroutines consume values which are sent to it. A very basic example would be a ``grep`` alternative in Python: @@ -41,7 +41,7 @@ example would be a ``grep`` alternative in Python: print(line) Wait! What does ``yield`` return? Well we have turned it into a -coroutine. It does not contain any value initially instead we supply it +coroutine. It does not contain any value initially, instead we supply it values externally. We supply values by using the ``.send()`` method. Here is an example: @@ -55,13 +55,13 @@ Here is an example: search.send("I love coroutines instead!") # Output: I love coroutines instead! -The sent values are accessed by yield. Why did we run ``next()``? It is -done to start the coroutine. Just like ``generators`` coroutines do not -start the function immediately. Instead they run it in response to -``__next__()`` and ``.send()`` methods. Therefore you have to run +The sent values are accessed by ``yield``. Why did we run ``next()``? It is +required in order to start the coroutine. Just like ``generators``, coroutines do not +start the function immediately. Instead they run it in response to the +``__next__()`` and ``.send()`` methods. Therefore, you have to run ``next()`` so that the execution advances to the ``yield`` expression. -We can close a coroutine by calling the ``.close()`` method. Like: +We can close a coroutine by calling the ``.close()`` method: .. code:: python From bb04df793405e679cca50a9930adf60e401ea99d Mon Sep 17 00:00:00 2001 From: Neil Basu Date: Tue, 25 Aug 2015 22:16:25 +0200 Subject: [PATCH 007/152] Update decorators.rst Added a section on passing parameters into decorators, and decorators as classes --- decorators.rst | 120 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/decorators.rst b/decorators.rst index c1abae0..2c9d33f 100644 --- a/decorators.rst +++ b/decorators.rst @@ -321,3 +321,123 @@ Logging is another area where the decorators shine. Here is an example: # Output: addition_func was called I am sure you are already thinking about some clever uses of decorators. + +Decorators with Arguments +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Come to think of it, isn't ``@wraps`` also a decorator? But, it takes an +argument like any normal function can do. So, why can't we do that too? + +This is because when you use the ``@my_decorator`` syntax, you are +applying a wrapper function with a single function as a parameter +Remember, everything in Python is an object, and this includes +functions! With that in mind, we can write a function that returns +a wrapper function. + +Nesting a Decorator Within a Function +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let's go back to our logging example, and create a wrapper which lets +us specify a logfile to output to. + +.. code:: python + + from functools import wraps + + def logit(logfile='out.log'): + def logging_decorator(func): + @wraps(func) + def wrapped_function(*args, **kwargs): + log_string = func.__name__ + " was called" + print(log_string) + # Open the logfile and append + with open(logfile, 'a') as opened_file: + # Now we log to the specified logfile + opened_file.write(log_string + '\n') + return wrapped_function + return logging_decorator + + @logit() + def myfunc1(): + pass + + myfunc1() + # Output: myfunc1 was called + # A file called out.log now exists, with the above string + + @logit(logfile='func2.log') + def myfunc2(): + pass + + myfunc2(): + pass + + myfunc2() + # Output: myfunc2 was called + # A file called func2.log now exists, with the above string + +Decorator Classes +~~~~~~~~~~~~~~~~~ + +Now we have our logit decorator in production, but when some parts +of our application are considered critical, failure might be +something that needs more immediate attention. Let's say sometimes +you want to just log to a file. Other times you want an email sent +the problem is brought to your attention, and still keep a log +for your own records. This is a case for using inheritence, but +so far we've only seen functions being used to build decorators. + +Luckily, classes can also be used to build decorators. So, let's +rebuild logit as a class instead of a function. + +.. code:: python + + class logit(object): + def __init__(self, logfile='out.log'): + self.logfile = logfile + + def __call__(self, func): + log_string = func.__name__ + " was called" + print(log_string) + # Open the logfile and append + with open(self.logfile, 'a') as opened_file: + # Now we log to the specified logfile + opened_file.write(log_string + '\n') + # Now, send a notification + self.notify() + + def notify(self): + # logit only logs, no more + pass + +This implementation has an additional advantage of being much cleaner than +the nested function approach, and wrapping a function still will use +the same syntax as before: + +.. code:: python + + @logit() + def myfunc1(): + pass + +Now, let's subclass logit to add email functionality (though this topic +will not be covered here). + +.. code:: python + + class email_logit(logit): + ''' + A logit implementation for sending emails to admins + when the function is called. + ''' + def __init__(self, email='admin@myproject.com', *args, **kwargs): + self.email = email + super(logit, self).__init__(*args, **kwargs) + + def notify(self): + # Send an email to self.email + # Will not be implemented here + pass + +From here, ``@email_logit`` works just like ``@logit`` but sends an email +to the admin in addition to logging. From 3bdb4f499d3bf2a251efef51c6d50d96d10b6032 Mon Sep 17 00:00:00 2001 From: Neil Basu Date: Thu, 27 Aug 2015 14:16:11 +0200 Subject: [PATCH 008/152] Update global_&_return.rst Removed detail stating "return a,b" is not a tuple --- global_&_return.rst | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/global_&_return.rst b/global_&_return.rst index e8dcfc0..510478f 100644 --- a/global_&_return.rst +++ b/global_&_return.rst @@ -110,7 +110,7 @@ Some try to solve this problem by *returning* a ``tuple``, ``list`` or ``dict`` print(profile_data[1]) # Output: 30 -But what many programmers don't know is that you can return two separate values as well. Let's take a look at an example so that you can better understand it: +Or by more common convention: .. code:: python @@ -119,11 +119,4 @@ But what many programmers don't know is that you can return two separate values age = 30 return name, age - name, age = profile() - print(name) - # Output: Danny - - print(age) - # Output: 30 - -This is a better way to do it along with returning ``tuples``, ``lists`` and ``dicts``. Don't use ``global`` keyword unless you know what you are doing. ``global`` might be a better option in a few cases but is not in most of them. +This is a better way to do it along with returning ``lists`` and ``dicts``. Don't use ``global`` keyword unless you know what you are doing. ``global`` might be a better option in a few cases but is not in most of them. From 425c172006dfa76cc3b494c73dcf79edadad6744 Mon Sep 17 00:00:00 2001 From: Tyler Singer-Clark Date: Thu, 27 Aug 2015 11:23:47 -0400 Subject: [PATCH 009/152] `else` clauses can be really nice thought you might want to add in this nice insight about `else` clauses in exception handling --- exceptions.rst | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/exceptions.rst b/exceptions.rst index f55f1b4..cbe752e 100644 --- a/exceptions.rst +++ b/exceptions.rst @@ -89,8 +89,11 @@ to perform clean-up after a script. Here is a simple example: ~~~~~~~~~~~~~~~~~~~ Often times we might want some code to run if **no** exception occurs. This -can easily be achieved by using an ``else`` clause. Most people don't -use it and honestly I have myself not used it widely. Here is an +can easily be achieved by using an ``else`` clause. One might ask: why, if +you only want some code to run if no exception occurs, wouldn't you simply +put that code inside the ``try``? The answer is that then any exceptions in +that code will be caught by the ``try``, and you might not want that. Most +people don't use it and honestly I have myself not used it widely. Here is an example: .. code:: python @@ -100,7 +103,10 @@ example: except Exception: print('exception') else: - print('This would only run if no exception occurs.') + # any code that should only run if no exception occurs in the try, + # but for which exceptions should NOT be caught + print('This would only run if no exception occurs. And an error here ' + 'would NOT be caught.') finally: print('This would be printed in every case.') From 4b4063cffbd592336e442afdb0313695bfbbb933 Mon Sep 17 00:00:00 2001 From: deepakkarki Date: Thu, 27 Aug 2015 21:08:07 +0530 Subject: [PATCH 010/152] added chapter on python C extensions --- python_c_extension.rst | 384 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 384 insertions(+) create mode 100644 python_c_extension.rst diff --git a/python_c_extension.rst b/python_c_extension.rst new file mode 100644 index 0000000..37f45b4 --- /dev/null +++ b/python_c_extension.rst @@ -0,0 +1,384 @@ +Python C extensions +=================== + +An interesting feature offered to developers by the CPython +implementation is the ease of interfacing C code to Python. + +There are three key methods developers use to call C functions from +their python code - ``ctypes``, ``SWIG`` and ``Python/C API``. Each +method comes with it's own merits and demerits. + +Firstly, why would you want to interface C with Python? + +A few common reasons are : + +- You want speed and you know C is about 50x faster than Python. +- Certain legacy C libraries work just as well as you want them to, so you don't want to rewrite them in python. +- Certain low level resource access - from memory to file interfaces. +- Just because you want to. + +1. CTypes +--------- + +The Python `ctypes +module `__ is probably +the most easiest way to call C functions from Python. The ctypes module +provides C compatible data types and functions to load DLLs so that +calls can be made to C shared libraries without having to modify them. +The fact that the C side needn't be touched adds to the simplicity of +this method. + +**Example** + +Simple C code to add two numbers, save it as ``add.c`` + +.. code:: c + + //sample C file to add 2 numbers - int and floats + + #include + + int add_int(int, int); + float add_float(float, float); + + int add_int(int num1, int num2){ + return num1 + num2; + } + + float add_float(float num1, float num2){ + return num1 + num2; + } + +Next compile the C file to a ``.so`` file (DLL in windows) This will +generate a adder.so file. + +.. code:: bash + + #For Linux + $ gcc -shared -Wl,-soname,adder -o adder.so -fPIC add.c + + #For Mac + $ gcc -shared -Wl,-install_name,adder.so -o adder.so -fPIC add.c + +Now in your python code - + +.. code:: python + + from ctypes import * + + #load the shared object file + adder = CDLL('./adder.so') + + #Find sum of integers + res_int = adder.add_int(4,5) + print "Sum of 4 and 5 = " + str(res_int) + + #Find sum of floats + a = c_float(5.5) + b = c_float(4.1) + + add_float = adder.add_float + add_float.restype = c_float + print "Sum of 5.5 and 4.1 = ", str(add_float(a, b)) + +And the output is as follows + +:: + + Sum of 4 and 5 = 9 + Sum of 5.5 and 4.1 = 9.60000038147 + +In this example the C file is self explanatory - it contains two +functions, one to add two integers and another to add two floats. + +In the python file, first the ctypes module is imported. Then the CDLL +function of the ctypes module is used to load the shared lib file we +created. The functions defined in the C lib is now available to us via +the ``adder`` variable. When ``adder.add_int()`` is called, internally a +call is made to the ``add_int`` C function. The ctypes interface allows +us to use native python integers and strings by default while calling +the C functions. + +For other types such as boolean or float, we have to use the correct +ctypes. This is seen while passing parameters to the +``adder.add_float()``. We first create the required c\_float types from +python decimal values, and then use them as arguments to the C code. +This method is simple and clean, but limited. For example it's not +possible to manipulate objects on the C side. + +2. SWIG +------- + +Simplified Wrapper and Interface Generator, or SWIG for short is another +way to interface C code to Python. In this method, the developer must +develop an extra interface file which is an input to SWIG (the command +line utility). + +Python developers generally don't use this method, because it is in most +cases unnecessarily complex. This is a great method when you have a +C/C++ code base, and you want to interface it to many different +languages. + +**Example** (from the `SWIG website `__ ) + +The C code, ``example.c`` that has a variety of functions and variables + +.. code:: c + + #include + double My_variable = 3.0; + + int fact(int n) { + if (n <= 1) return 1; + else return n*fact(n-1); + } + + int my_mod(int x, int y) { + return (x%y); + } + + char *get_time() + { + time_t ltime; + time(<ime); + return ctime(<ime); + } + +The interface file - this will remain the same irrespective of the +language you want to port your C code to : + +:: + + /* example.i */ + %module example + %{ + /* Put header files here or function declarations like below */ + extern double My_variable; + extern int fact(int n); + extern int my_mod(int x, int y); + extern char *get_time(); + %} + + extern double My_variable; + extern int fact(int n); + extern int my_mod(int x, int y); + extern char *get_time(); + +And now to compile it + +:: + + unix % swig -python example.i + unix % gcc -c example.c example_wrap.c \ + -I/usr/local/include/python2.1 + unix % ld -shared example.o example_wrap.o -o _example.so + +Finally, the Python output + +.. code:: python + + >>> import example + >>> example.fact(5) + 120 + >>> example.my_mod(7,3) + 1 + >>> example.get_time() + 'Sun Feb 11 23:01:07 1996' + >>> + +As we can see, SWIG achieves the same result, but requires a slightly +more involved effort. But it's worth it if you are targeting multiple +languages. + +3. Python/C API +--------------- + +The `C/Python API `__ is probably the +most widely used method - not for it's simplicity but for the fact that +you can manipulate python objects in your C code. + +This method requires your C code to be specifically written for +interfacing with Python code. All Python objects are represented as a +PyObject struct and the ``Python.h`` header file provides various +functions to manipulate it. For example if the PyObject is also a +PyListType (basically a list), then we can use the ``PyList_Size()`` +function on the struct to get the length of the list. This is equivalent +to calling ``len(list)`` in python. Most of the basic +functions/opertions that are there for native Python objects are made +available in C via the ``Python.h`` header. + +**Example** + +To write a C extension that adds all the elements in a python list. (all elements are numbers) + +Let's start with the final interface we'd like to have, here is the +python file that uses the C extension : + +.. code:: python + + #Though it looks like an ordinary python import, the addList module is implemented in C + import addList + + l = [1,2,3,4,5] + print "Sum of List - " + str(l) + " = " + str(addList.add(l)) + +The above looks like any ordinary python file, which imports and uses +another python module called ``addList``. The only difference is that +the addList module is not written in Python at all, but rather in C. + +Next we'll have a look at the C code that get's built into the +``addList`` Python module. This may seem a bit daunting at first, but +once you understand the various components that go into writing the C +file, it's pretty straight forward. + +*adder.c* + +.. code:: c + + //Python.h has all the required function definitions to manipulate the Python objects + #include + + //This is the function that is called from your python code + static PyObject* addList_add(PyObject* self, PyObject* args){ + + PyObject * listObj; + + //The input arguments come as a tuple, we parse the args to get the various variables + //In this case it's only one list variable, which will now be referenced by listObj + if (! PyArg_ParseTuple( args, "O", &listObj)) + return NULL; + + //length of the list + long length = PyList_Size(listObj); + + //iterate over all the elements + int i, sum =0; + for(i = 0; i < length; i++){ + //get an element out of the list - the element is also a python objects + PyObject* temp = PyList_GetItem(listObj, i); + //we know that object represents an integer - so convert it into C long + long elem = PyInt_AsLong(temp); + sum += elem; + } + + //value returned back to python code - another python object + //build value here converts the C long to a python integer + return Py_BuildValue("i", sum); + } + + //This is the docstring that corresponds to our 'add' function. + static char addList_docs[] = + "add( ): add all elements of the list\n"; + + /* This table contains the relavent info mapping - + , , + , + */ + static PyMethodDef addList_funcs[] = { + {"add", (PyCFunction)addList_add, METH_VARARGS, addList_docs}, + {NULL, NULL, 0, NULL} + }; + + /* + addList is the module name, and this is the initialization block of the module. + , , + */ + PyMODINIT_FUNC initaddList(void){ + Py_InitModule3("addList", addList_funcs, + "Add all ze lists"); + } + +A step by step explanation - \* The ```` file consists of all +the required types (to represent Python object types) and function +definitions (to operate on the python objects). \* Next we write the +function which we plan to call from python. Conventionally the function +names are {module-name}\_{function-name}, which in this case is +``addList_add``. More about the function later. \* Then fill in the info +table - which contains all the relevant info of the functions we desire +to have in the module. Every row corresponds to a function, with the +last one being a sentinel value (row of null elements). \* Finally the +module initialization block which is of the signature +``PyMODINIT_FUNC init{module-name}``. + +The function ``addList_add`` accepts arguments as a PyObject type struct +(args is also a tuple type - but since everything in python is an +object, we use the generic PyObject notion). The incoming arguments is +parsed (basically split the tuple into individual elements) by +``PyArg_ParseTuple()``. The first parameter is the argument variable to +be parsed. The second argument is a string that tells us how to parse +each element in the args tuple. The character in the Nth position of the +string tells us the type of the Nth element in the args tuple, example - +'i' would mean integer, 's' would mean string and 'O' would mean a +Python object. Next multiple arguments follow, these are where you would +like the ``PyArg_ParseTuple()`` function to store all the elements that +it has parsed. The number of such arguments is equal to the number of +arguments which the module function expects to receive, and positional +integrity is maintained. For example if we expected a string, integer +and a python list in that order, the function signature would be + +.. code:: c + + int n; + char *s; + PyObject* list; + PyArg_ParseTuple(args, "siO", &n, &s, &list); + +In this case we only have to extract a list object, and store it in the +variable ``listObj``. We then use the ``PyList_Size()`` function on our +list object and get the length. This is similar to how you would call +``len(list)`` in python. + +Now we loop through the list, get each element using the +``PyList_GetItem(list, index)`` function. This returns a PyObject\*. But +since we know that the Python objects are also ``PyIntType``, we just +use the ``PyInt_AsLong(PyObj *)`` function to get the required value. We +do this for every element and finally get the sum. + +The sum is converted to a python object and is returned to the Python +code with the help of ``Py_BuildValue()``. Here the "i" indicates that +the value we want to build is a python integer object. + +Now we build the C module. Save the following code as ``setup.py`` + +.. code:: python + + #build the modules + + from distutils.core import setup, Extension + + setup(name='addList', version='1.0', \ + ext_modules=[Extension('addList', ['adder.c'])]) + +and run + +.. code:: sh + + python setup.py install + +This should now build and install the C file into the python module we +desire. + +After all this hard work, we'll now test if the module works - + +.. code:: python + + #module that talks to the C code + import addList + + l = [1,2,3,4,5] + print "Sum of List - " + str(l) + " = " + str(addList.add(l)) + +And here is the output + +:: + + Sum of List - [1, 2, 3, 4, 5] = 15 + +So as you can see, we have developed our first successful C Python +extension using the Python.h API. This method does seem complex at +first, but once you get used to it it can prove to be quite useful. + +Other ways to interface C code to Python is to use an alternative and +faster build of python - `Cython `__. But Cython is +a slightly different language than the main stream python we see. Hence +that method is not covered here. From d67692b3d6706addd14751fd4daf153c5cd9218c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Fri, 28 Aug 2015 23:42:19 +0500 Subject: [PATCH 011/152] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b6f812a..9cb22ef 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ Table of Contents: - [Lambdas](lambdas.rst) - [One Liners](one_liners.rst) - [For - Else](for_-_else.rst) +- [Python C extensions](python_c_extension.rst) - [Open function](open_function.rst) - [Targeting Python 2+3](targeting_python_2_3.rst) - [Coroutines](coroutines.rst) From d299d3a0dc56a7a10aeb7dae0e393671f0c00137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Fri, 28 Aug 2015 23:45:00 +0500 Subject: [PATCH 012/152] Update index.rst --- index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/index.rst b/index.rst index fcd4d2c..9895a2d 100644 --- a/index.rst +++ b/index.rst @@ -58,6 +58,7 @@ Table of Contents lambdas one_liners for_-_else + python_c_extension open_function targeting_python_2_3 coroutines From f9542ffbf94197a5fb40f0866d1b8aecdf6983a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Fri, 28 Aug 2015 23:48:50 +0500 Subject: [PATCH 013/152] Removed numbering --- python_c_extension.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python_c_extension.rst b/python_c_extension.rst index 37f45b4..f54ba73 100644 --- a/python_c_extension.rst +++ b/python_c_extension.rst @@ -17,7 +17,7 @@ A few common reasons are : - Certain low level resource access - from memory to file interfaces. - Just because you want to. -1. CTypes +CTypes --------- The Python `ctypes @@ -106,7 +106,7 @@ python decimal values, and then use them as arguments to the C code. This method is simple and clean, but limited. For example it's not possible to manipulate objects on the C side. -2. SWIG +SWIG ------- Simplified Wrapper and Interface Generator, or SWIG for short is another @@ -190,7 +190,7 @@ As we can see, SWIG achieves the same result, but requires a slightly more involved effort. But it's worth it if you are targeting multiple languages. -3. Python/C API +Python/C API --------------- The `C/Python API `__ is probably the From 42275161be571a1ddd24513150b6678e08165995 Mon Sep 17 00:00:00 2001 From: Dominik Czarnota Date: Tue, 25 Aug 2015 22:07:31 +0200 Subject: [PATCH 014/152] Better example of __slots__magic.rst --- __slots__magic.rst | 50 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/__slots__magic.rst b/__slots__magic.rst index 3f9e5ab..f6c3407 100644 --- a/__slots__magic.rst +++ b/__slots__magic.rst @@ -19,7 +19,7 @@ of attributes. Here is an example with and without ``__slots__``: .. code:: python class MyClass(object): - def __init__(name, identifier): + def __init__(self, name, identifier): self.name = name self.identifier = identifier self.set_up() @@ -31,7 +31,7 @@ of attributes. Here is an example with and without ``__slots__``: class MyClass(object): __slots__ = ['name', 'identifier'] - def __init__(name, identifier): + def __init__(self, name, identifier): self.name = name self.identifier = identifier self.set_up() @@ -43,3 +43,49 @@ technique. On a sidenote, you might want to give PyPy a try. It does all of these optimizations by default. + + +Below you can see an example showing exact memory usage with and without ``__slots__`` done in IPython thanks to https://github.com/ianozsvald/ipython_memory_usage + +.. code:: python + + Python 3.4.3 (default, Jun 6 2015, 13:32:34) + Type "copyright", "credits" or "license" for more information. + + IPython 4.0.0 -- An enhanced Interactive Python. + ? -> Introduction and overview of IPython's features. + %quickref -> Quick reference. + help -> Python's own help system. + object? -> Details about 'object', use 'object??' for extra details. + + In [1]: import ipython_memory_usage.ipython_memory_usage as imu + + In [2]: imu.start_watching_memory() + In [2] used 0.0000 MiB RAM in 5.31s, peaked 0.00 MiB above current, total RAM usage 15.57 MiB + + In [3]: %cat slots.py + class MyClass(object): + __slots__ = ['name', 'identifier'] + def __init__(self, name, identifier): + self.name = name + self.identifier = identifier + + num = 1024*256 + x = [MyClass(1,1) for i in range(num)] + In [3] used 0.2305 MiB RAM in 0.12s, peaked 0.00 MiB above current, total RAM usage 15.80 MiB + + In [4]: from slots import * + In [4] used 9.3008 MiB RAM in 0.72s, peaked 0.00 MiB above current, total RAM usage 25.10 MiB + + In [5]: %cat noslots.py + class MyClass(object): + def __init__(self, name, identifier): + self.name = name + self.identifier = identifier + + num = 1024*256 + x = [MyClass(1,1) for i in range(num)] + In [5] used 0.1758 MiB RAM in 0.12s, peaked 0.00 MiB above current, total RAM usage 25.28 MiB + + In [6]: from noslots import * + In [6] used 22.6680 MiB RAM in 0.80s, peaked 0.00 MiB above current, total RAM usage 47.95 MiB From e3debb6dc47209f8dfbc2d5322bfc7268d5ebc42 Mon Sep 17 00:00:00 2001 From: Abdul Salim Date: Wed, 2 Sep 2015 14:50:41 -0500 Subject: [PATCH 015/152] Fix typo --- global_&_return.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global_&_return.rst b/global_&_return.rst index 510478f..e1b1f22 100644 --- a/global_&_return.rst +++ b/global_&_return.rst @@ -94,7 +94,7 @@ So what if you want to return two variables from a function instead of one? Ther **Note:**Don't try to use the above mentioned method. I repeat, don't try to use the above mentioned method! -Some try to solve this problem by *returning* a ``tuple``, ``list`` or ``dict`` with the reqired values after the function terminates. It is one way to do it and works like a charm: +Some try to solve this problem by *returning* a ``tuple``, ``list`` or ``dict`` with the required values after the function terminates. It is one way to do it and works like a charm: .. code:: python From 209595447a113dbf057b84d3cca0ad1a0f08dcfb Mon Sep 17 00:00:00 2001 From: Roman Turna Date: Thu, 3 Sep 2015 10:14:08 +0200 Subject: [PATCH 016/152] Update __slots__magic.rst Add self parametres to __init__ methods in MyClass classes. --- __slots__magic.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/__slots__magic.rst b/__slots__magic.rst index 3f9e5ab..91e793e 100644 --- a/__slots__magic.rst +++ b/__slots__magic.rst @@ -19,7 +19,7 @@ of attributes. Here is an example with and without ``__slots__``: .. code:: python class MyClass(object): - def __init__(name, identifier): + def __init__(self, name, identifier): self.name = name self.identifier = identifier self.set_up() @@ -31,7 +31,7 @@ of attributes. Here is an example with and without ``__slots__``: class MyClass(object): __slots__ = ['name', 'identifier'] - def __init__(name, identifier): + def __init__(self, name, identifier): self.name = name self.identifier = identifier self.set_up() From 1c4f258bff184bfcef4f13e991d1cdbc02f23152 Mon Sep 17 00:00:00 2001 From: Roman Turna Date: Thu, 3 Sep 2015 10:20:15 +0200 Subject: [PATCH 017/152] Update global_&_return.rst Correct one typo. --- global_&_return.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global_&_return.rst b/global_&_return.rst index 510478f..e1b1f22 100644 --- a/global_&_return.rst +++ b/global_&_return.rst @@ -94,7 +94,7 @@ So what if you want to return two variables from a function instead of one? Ther **Note:**Don't try to use the above mentioned method. I repeat, don't try to use the above mentioned method! -Some try to solve this problem by *returning* a ``tuple``, ``list`` or ``dict`` with the reqired values after the function terminates. It is one way to do it and works like a charm: +Some try to solve this problem by *returning* a ``tuple``, ``list`` or ``dict`` with the required values after the function terminates. It is one way to do it and works like a charm: .. code:: python From 59e49904a5a8bd057d766086b32d85a5db3e7609 Mon Sep 17 00:00:00 2001 From: Roman Turna Date: Thu, 3 Sep 2015 10:36:32 +0200 Subject: [PATCH 018/152] Update collections.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the "This was just a quick drive through the ``collections``…" paragraph to the end. --- collections.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/collections.rst b/collections.rst index c251b62..14803a7 100644 --- a/collections.rst +++ b/collections.rst @@ -193,9 +193,6 @@ new values: print(d) # Output: deque([0, 1, 2, 3, 4, 5, 6, 7, 8]) -This was just a quick drive through the ``collections`` module. Make -sure you read the official documentation after reading this. - ``namedtuple`` ^^^^^^^^^^^^^^^^^^ @@ -343,3 +340,6 @@ methods will get you the value for ``cat``: Species(1) Species['cat'] Species.cat + +This was just a quick drive through the ``collections`` module. Make +sure you read the official documentation after reading this. From fbe3eb0e6018e3121ddcabaea25d1f94d19ca75a Mon Sep 17 00:00:00 2001 From: Sudheer Satyanarayana Date: Sun, 6 Sep 2015 03:29:42 +0530 Subject: [PATCH 019/152] Capitalize Python. Minor grammar fixes --- decorators.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/decorators.rst b/decorators.rst index 9d4c14e..b6e38be 100644 --- a/decorators.rst +++ b/decorators.rst @@ -12,10 +12,10 @@ First, let's discuss how to write your own decorator. It is perhaps one of the most difficult concepts to grasp. We will take it one step at a time so that you can fully understand it. -Everything in python is an object: +Everything in Python is an object: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -First of all let's understand functions in python: +First of all let's understand functions in Python: .. code:: python @@ -175,7 +175,7 @@ previous decorator and make a little bit more usable program: # I am doing some boring work after executing a_function_requiring_decoration() Did you get it? We just applied the previously learned principles. This -is exactly what the decorators do in python! They wrap a function and +is exactly what the decorators do in Python! They wrap a function and modify its behaviour in one way or the another. Now you might be wondering that we did not use the @ anywhere in our code? That is just a short way of making up a decorated function. Here is how we could have From 861387d51e78eb33d724f9e7ed2a57c8163c1e40 Mon Sep 17 00:00:00 2001 From: Sudheer Satyanarayana Date: Sun, 6 Sep 2015 03:44:49 +0530 Subject: [PATCH 020/152] Fix output in comments. You probably want to show output as is. --- decorators.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/decorators.rst b/decorators.rst index b6e38be..415260b 100644 --- a/decorators.rst +++ b/decorators.rst @@ -170,9 +170,9 @@ previous decorator and make a little bit more usable program: #now a_function_requiring_decoration is wrapped by wrapTheFunction() a_function_requiring_decoration() - #outputs:I am doing some boring work before executing a_function_requiring_decoration() + #outputs:I am doing some boring work before executing a_func() # I am the function which needs some decoration to remove my foul smell - # I am doing some boring work after executing a_function_requiring_decoration() + # I am doing some boring work after executing a_func() Did you get it? We just applied the previously learned principles. This is exactly what the decorators do in Python! They wrap a function and From b418b0cbc72c82e052a92e31fd041ea7e8feb180 Mon Sep 17 00:00:00 2001 From: Markus Fischer Date: Fri, 11 Sep 2015 22:28:58 +0200 Subject: [PATCH 021/152] One ` too much I guess --- open_function.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/open_function.rst b/open_function.rst index bd5b702..f197fc2 100644 --- a/open_function.rst +++ b/open_function.rst @@ -28,7 +28,7 @@ read was successful. If there is any error just after ``f = open(...)``, ``f.close()`` will not be called (depending on the Python interpreter, the file handle may still be returned, but that's another story). To make sure that the file gets closed whether an exception occurs or not, -pack it into a ```with`` statement: +pack it into a ``with`` statement: .. code:: python From 6d3a695951b6d5dedd3467b7031933f46eaead7a Mon Sep 17 00:00:00 2001 From: vivek Date: Wed, 7 Oct 2015 16:53:58 +0100 Subject: [PATCH 022/152] Added a 't' in for_else module at line no. 75 --- for_-_else.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/for_-_else.rst b/for_-_else.rst index da01bf6..364abf5 100644 --- a/for_-_else.rst +++ b/for_-_else.rst @@ -72,7 +72,7 @@ prime and tells us so: for n in range(2, 10): for x in range(2, n): if n % x == 0: - prin( n, 'equals', x, '*', n/x) + print( n, 'equals', x, '*', n/x) break else: # loop fell through without finding a factor From f901dd329b36d81619bc459a14d25aa6090f5870 Mon Sep 17 00:00:00 2001 From: David Awad Date: Mon, 12 Oct 2015 02:26:12 -0400 Subject: [PATCH 023/152] Update generators.rst Just some small improvements to this section. --- generators.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/generators.rst b/generators.rst index 70da1a7..294c12f 100644 --- a/generators.rst +++ b/generators.rst @@ -149,11 +149,11 @@ support iteration? Let's check it out: # TypeError: str object is not an iterator Well that's not what we expected. The error says that ``str`` is not an -iterator. Well it is right! It is an iterable but not an iterator. This -means that it supports iteration but we can not directly iterate over -it. How can we then iterate over it? It's time to learn about one more +iterator. Well it's right! It's an iterable but not an iterator. This +means that it supports iteration but we can't iterate over +it directly. So how would we iterate over it? It's time to learn about one more built-in function, ``iter``. It returns an ``iterator`` object from an -iterable. Here is how we can use it: +iterable. While an ``int`` isn't an iterable, we can use it on string! .. code:: python From 7c99fa58c04702f7cd13989ad6b666fdca2d4570 Mon Sep 17 00:00:00 2001 From: David Awad Date: Thu, 15 Oct 2015 02:39:18 -0400 Subject: [PATCH 024/152] Add some information on reduce! :D It's a super useful function and usually falls right along these lines. --- map_filter.rst | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/map_filter.rst b/map_filter.rst index 0bc4187..d07c8cd 100644 --- a/map_filter.rst +++ b/map_filter.rst @@ -1,7 +1,7 @@ -Map & Filter +Map, Filter and Reduce ------------ -These are two functions which facilitate a functional approach to +These are three functions which facilitate a functional approach to programming. We will discuss them one by one and understand their use cases. @@ -60,7 +60,7 @@ of a list of inputs we can even have a list of functions! Filter ^^^^^^^^^ -As the name suggests, filter creates a list of elements for which a +As the name suggests, ``filter`` creates a list of elements for which a function returns true. Here is a short and concise example: .. code:: python @@ -75,3 +75,29 @@ The filter resembles a for loop but it is a builtin function and faster. **Note:** If map & filter do not appear beautiful to you then you can read about ``list/dict/tuple`` comprehensions. + +Reduce +^^^^^^^^^ + +``Reduce`` is a really useful function for performing some computation on +a list and returning the result. For example, if you wanted to compute +the product of a list of integers. + +So the normal way you might go about doing this task in python us using +a basic for loop. + +.. code:: python + product = 1 + list = [1, 2, 3, 4] + for num in list: + product = product * list + + # product = 24 + +Now let's try it with reduce. +.. code:: python + + from functools import reduce + product = reduce( (lambda x, y: x * y), [1, 2, 3, 4] ) + + # Output: 24 From 73b4b67c06d5b36ae912c17ebea5edd3d54623cb Mon Sep 17 00:00:00 2001 From: ssword Date: Sun, 29 Nov 2015 21:03:30 -0600 Subject: [PATCH 025/152] Fix typo in collections.rst I like cat, but in line 235, I think it should be 'type' --- collections.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collections.rst b/collections.rst index 14803a7..81f12fb 100644 --- a/collections.rst +++ b/collections.rst @@ -232,7 +232,7 @@ You can now see that we can access members of a tuple just by their name using a ``.``. Let's dissect it a little more. A named tuple has two required arguments. They are the tuple name and the tuple field\_names. In the above example our tuple name was 'Animal' and the tuple -field\_names were 'name', 'age' and 'cat'. Namedtuple makes your tuples +field\_names were 'name', 'age' and 'type'. Namedtuple makes your tuples **self-document**. You can easily understand what is going on by having a quick glance at your code. And as you are not bound to use integer indexes to access members of a tuple, it makes it more easy to maintain From 0c4e0d553b8f6ef4064d94ea841c83049795c451 Mon Sep 17 00:00:00 2001 From: ssword Date: Mon, 30 Nov 2015 01:38:35 -0600 Subject: [PATCH 026/152] Typo in coroutines.rst Typo in line 29, it should be "rather than" --- coroutines.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coroutines.rst b/coroutines.rst index 3e6f091..113cb30 100644 --- a/coroutines.rst +++ b/coroutines.rst @@ -26,7 +26,7 @@ We then commonly use it in a ``for`` loop like this: print(i) It is fast and does not put a lot of pressure on memory because it -**generates** the values on the fly rather then storing them in a list. +**generates** the values on the fly rather than storing them in a list. Now, if we use ``yield`` in the above example, more generally, we get a coroutine. Coroutines consume values which are sent to it. A very basic example would be a ``grep`` alternative in Python: From b1cc071bd1f020c47c16642458cc87ae897c79ab Mon Sep 17 00:00:00 2001 From: Saurav Sachidanand Date: Tue, 1 Dec 2015 16:21:31 +0530 Subject: [PATCH 027/152] Fixed syntax error in Section 7.6.1 In the code example in Section 7.6.1, there were two function calls to myfunc2(), and the first call was syntactically incorrect. This also caused the code example to not be syntax highlighted on the website. I fixed the error, and the code should be highlighted now. --- decorators.rst | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/decorators.rst b/decorators.rst index b7e6e12..316dc41 100644 --- a/decorators.rst +++ b/decorators.rst @@ -368,10 +368,7 @@ us specify a logfile to output to. @logit(logfile='func2.log') def myfunc2(): pass - - myfunc2(): - pass - + myfunc2() # Output: myfunc2 was called # A file called func2.log now exists, with the above string From a9762d797c2ef41518294ab6d72e0d6bd7ad3819 Mon Sep 17 00:00:00 2001 From: Saurav Sachidanand Date: Wed, 2 Dec 2015 07:57:31 +0530 Subject: [PATCH 028/152] Typo in targeting_python_2_3.rst --- targeting_python_2_3.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targeting_python_2_3.rst b/targeting_python_2_3.rst index 40f9bb1..00e08ff 100644 --- a/targeting_python_2_3.rst +++ b/targeting_python_2_3.rst @@ -4,7 +4,7 @@ Targeting Python 2+3 In a lot of cases you might want to develop programs which can be run in both Python 2+ and 3+. -Just imagine that you have a very popular Python module which is use by +Just imagine that you have a very popular Python module which is used by hundreds of people but not all of them have Python 2 or 3. In that case you have two choices. The first one is to distribute 2 modules, one for Python 2 and the other for Python 3. The other choice is to modify your From cae9b8cf2a9ed09e0c3da11c8cc835dc445378ce Mon Sep 17 00:00:00 2001 From: David Awad Date: Tue, 29 Dec 2015 15:38:04 -0500 Subject: [PATCH 029/152] Update map_filter.rst --- map_filter.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/map_filter.rst b/map_filter.rst index d07c8cd..b11cf22 100644 --- a/map_filter.rst +++ b/map_filter.rst @@ -84,13 +84,14 @@ a list and returning the result. For example, if you wanted to compute the product of a list of integers. So the normal way you might go about doing this task in python us using -a basic for loop. +a basic for loop: + .. code:: python product = 1 list = [1, 2, 3, 4] for num in list: - product = product * list + product = product * num # product = 24 From 4f80e2136bfef5b8be347b53b988cab11e8c2664 Mon Sep 17 00:00:00 2001 From: David Awad Date: Tue, 29 Dec 2015 15:39:31 -0500 Subject: [PATCH 030/152] Update map_filter.rst --- map_filter.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/map_filter.rst b/map_filter.rst index b11cf22..e0d90b0 100644 --- a/map_filter.rst +++ b/map_filter.rst @@ -95,7 +95,9 @@ a basic for loop: # product = 24 -Now let's try it with reduce. + +Now let's try it with reduce: + .. code:: python from functools import reduce From d04acd512dff053ca4776054e8f8e0ea74803851 Mon Sep 17 00:00:00 2001 From: David Awad Date: Thu, 31 Dec 2015 02:52:21 -0500 Subject: [PATCH 031/152] Update map_filter.rst --- map_filter.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/map_filter.rst b/map_filter.rst index e0d90b0..5ecea5a 100644 --- a/map_filter.rst +++ b/map_filter.rst @@ -83,7 +83,7 @@ Reduce a list and returning the result. For example, if you wanted to compute the product of a list of integers. -So the normal way you might go about doing this task in python us using +So the normal way you might go about doing this task in python is using a basic for loop: From 3a2e0cbdd5f610268a155a9993a3213ad2d5ce7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Thu, 21 Jan 2016 21:25:41 +0500 Subject: [PATCH 032/152] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9cb22ef..ec4a4bf 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Acknowledgement: - [Philipp Hagemeister](https://github.com/phihag): -He wrote the chapter on Open function and has helped me a lot along the way. Thanks Philipp! :+1: +He wrote the chapter on Open function. Thanks Philipp! :+1: License: ------- From ddb33c5476c6df102c6c87bbe3721e65062173f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Thu, 21 Jan 2016 21:51:44 +0500 Subject: [PATCH 033/152] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ec4a4bf..078e27e 100644 --- a/README.md +++ b/README.md @@ -67,3 +67,5 @@ License: ------- This book is released under the [following](http://creativecommons.org/licenses/by-nc-sa/4.0/) CC license (CC BY-NC-SA 4.0). + +If you end up using/recommending this book to someone then kindly [let me know](mailto:yasoob.khld@gmail.com). :smile: From 21be0ddc77a198cb75c1f7bb9e3b49f8f7317b52 Mon Sep 17 00:00:00 2001 From: Sriram Sundarraj Date: Fri, 18 Mar 2016 23:24:15 +0530 Subject: [PATCH 034/152] Add idomatic way to retrieve multiple return values. --- global_&_return.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/global_&_return.rst b/global_&_return.rst index e1b1f22..8f5588a 100644 --- a/global_&_return.rst +++ b/global_&_return.rst @@ -119,4 +119,10 @@ Or by more common convention: age = 30 return name, age + profile_name, profile_age = profile() + print(profile_name) + # Output: Danny + print(profile_age) + # Output: 30 + This is a better way to do it along with returning ``lists`` and ``dicts``. Don't use ``global`` keyword unless you know what you are doing. ``global`` might be a better option in a few cases but is not in most of them. From 42e9646f8c25ae71433d4095d30bd5d9992b7ef8 Mon Sep 17 00:00:00 2001 From: Benjamin Bishop Date: Sun, 20 Mar 2016 20:17:49 -0400 Subject: [PATCH 035/152] Update decorators.rst Grammatical error in 7.6.2 "Decorator Classes" --- decorators.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/decorators.rst b/decorators.rst index 316dc41..a560c5d 100644 --- a/decorators.rst +++ b/decorators.rst @@ -379,8 +379,8 @@ Decorator Classes Now we have our logit decorator in production, but when some parts of our application are considered critical, failure might be something that needs more immediate attention. Let's say sometimes -you want to just log to a file. Other times you want an email sent -the problem is brought to your attention, and still keep a log +you want to just log to a file. Other times you want an email sent, +so the problem is brought to your attention, and still keep a log for your own records. This is a case for using inheritence, but so far we've only seen functions being used to build decorators. From 5cfbd77e6c6db4d8cf9aa050b6c3ca7a5e70fece Mon Sep 17 00:00:00 2001 From: Benjamin Bishop Date: Sun, 20 Mar 2016 20:35:06 -0400 Subject: [PATCH 036/152] Update global_&_return.rst Syntax error line 39. --- global_&_return.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global_&_return.rst b/global_&_return.rst index e1b1f22..960ce13 100644 --- a/global_&_return.rst +++ b/global_&_return.rst @@ -36,7 +36,7 @@ case is ``result``. In most cases and you won't need to use the which includes the ``global`` keyword. So what that function is doing is that it is making a global variable ``result``. What does global mean here? Global variable means that we can access that variable outside the -scope of the function as well. Let me demonstrate it with an example : +scope of the function as well. Let me demonstrate it with an example: .. code:: python From dc84d6ed0613ab34a49838760241aa0a7a20da59 Mon Sep 17 00:00:00 2001 From: Benjamin Bishop Date: Sun, 20 Mar 2016 20:39:06 -0400 Subject: [PATCH 037/152] Update global_&_return.rst Syntax error lines 39 & 50. --- global_&_return.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/global_&_return.rst b/global_&_return.rst index e1b1f22..92d6c0a 100644 --- a/global_&_return.rst +++ b/global_&_return.rst @@ -36,7 +36,7 @@ case is ``result``. In most cases and you won't need to use the which includes the ``global`` keyword. So what that function is doing is that it is making a global variable ``result``. What does global mean here? Global variable means that we can access that variable outside the -scope of the function as well. Let me demonstrate it with an example : +scope of the function as well. Let me demonstrate it with an example: .. code:: python @@ -47,7 +47,7 @@ scope of the function as well. Let me demonstrate it with an example : add(2, 4) print(result) - # Oh crap we encountered an exception. Why is it so ? + # Oh crap, we encountered an exception. Why is it so? # the python interpreter is telling us that we do not # have any variable with the name of result. It is so # because the result variable is only accessible inside From d0769954e96f5c689a1a3649f8cae1a62af979de Mon Sep 17 00:00:00 2001 From: Benjamin Bishop Date: Mon, 21 Mar 2016 13:08:33 -0400 Subject: [PATCH 038/152] Update comprehensions.rst Grammatical error line 41. --- comprehensions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/comprehensions.rst b/comprehensions.rst index d4061e9..b83285a 100644 --- a/comprehensions.rst +++ b/comprehensions.rst @@ -38,7 +38,7 @@ Here is a short example: # Output: [0, 3, 6, 9, 12, 15, 18, 21, 24, 27] This can be really useful to make lists quickly. It is even preferred by -some instead of the ``filter`` function. list comprehensions really +some instead of the ``filter`` function. List comprehensions really shine when you want to supply a list to a method or function to make a new list by appending to it in each iteration of the ``for`` loop. For instance you would usually do something like this: From b11eed1a673e6dda8872cadb84a6e4ef1f745d86 Mon Sep 17 00:00:00 2001 From: Benjamin Bishop Date: Mon, 21 Mar 2016 20:59:20 -0400 Subject: [PATCH 039/152] Update python_c_extension.rst Grammatical errors lines 25, 53, 96. --- python_c_extension.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python_c_extension.rst b/python_c_extension.rst index f54ba73..852b2c6 100644 --- a/python_c_extension.rst +++ b/python_c_extension.rst @@ -22,7 +22,7 @@ CTypes The Python `ctypes module `__ is probably -the most easiest way to call C functions from Python. The ctypes module +the easiest way to call C functions from Python. The ctypes module provides C compatible data types and functions to load DLLs so that calls can be made to C shared libraries without having to modify them. The fact that the C side needn't be touched adds to the simplicity of @@ -50,7 +50,7 @@ Simple C code to add two numbers, save it as ``add.c`` } Next compile the C file to a ``.so`` file (DLL in windows) This will -generate a adder.so file. +generate an adder.so file. .. code:: bash @@ -93,7 +93,7 @@ functions, one to add two integers and another to add two floats. In the python file, first the ctypes module is imported. Then the CDLL function of the ctypes module is used to load the shared lib file we -created. The functions defined in the C lib is now available to us via +created. The functions defined in the C lib are now available to us via the ``adder`` variable. When ``adder.add_int()`` is called, internally a call is made to the ``add_int`` C function. The ctypes interface allows us to use native python integers and strings by default while calling From c2b5e709c8125aeaaffc5ea8b62a427fe139b8ef Mon Sep 17 00:00:00 2001 From: Benjamin Bishop Date: Tue, 22 Mar 2016 10:10:12 -0400 Subject: [PATCH 040/152] Update python_c_extension.rst Method arguments were not in correct order, line 324. --- python_c_extension.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_c_extension.rst b/python_c_extension.rst index f54ba73..c5deeb6 100644 --- a/python_c_extension.rst +++ b/python_c_extension.rst @@ -321,7 +321,7 @@ and a python list in that order, the function signature would be int n; char *s; PyObject* list; - PyArg_ParseTuple(args, "siO", &n, &s, &list); + PyArg_ParseTuple(args, "siO", &s, &n, &list); In this case we only have to extract a list object, and store it in the variable ``listObj``. We then use the ``PyList_Size()`` function on our From 3272fe8e5c6633c4bdca5416e2ad652b4ef10fcd Mon Sep 17 00:00:00 2001 From: Benjamin Bishop Date: Tue, 22 Mar 2016 19:41:22 -0400 Subject: [PATCH 041/152] Update context_managers.rst Grammatical errors: lines 103, 104, 107, 159, 161. --- context_managers.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/context_managers.rst b/context_managers.rst index 45b2b8d..f3ff506 100644 --- a/context_managers.rst +++ b/context_managers.rst @@ -100,11 +100,11 @@ an error is encountered. 2. It allows the ``__exit__`` method to handle the exception. 3. If ``__exit__`` returns True then the exception was gracefully handled. -4. If anything else than True is returned by ``__exit__`` method then - the exception is raised by ``with`` statement. +4. If anything else than True is returned by the ``__exit__`` method then + an exception is raised by the ``with`` statement. In our case the ``__exit__`` method returns ``None`` (when no return -statement is encountered then the method returns ``None``). Therefore, +statement is encountered then the method returns ``None``). Therefore, the ``with`` statement raises the exception. .. code:: python @@ -156,9 +156,9 @@ Let's see a basic, useless example: yield f f.close() -Okay! This way of implementing Context Managers appear to be more +Okay! This way of implementing Context Managers appears to be more intuitive and easy. However, this method requires some knowledge about -generators, yield and decorators. In this example we have not caught any +generators, yield, and decorators. In this example we have not caught any exceptions which might occur. It works in mostly the same way as the previous method. From 80623b2dea8878f87c58bf72c6d93ce1507ce4b3 Mon Sep 17 00:00:00 2001 From: Pavel Karateev Date: Wed, 23 Mar 2016 17:48:21 +0300 Subject: [PATCH 042/152] Fixes indentation --- map_filter.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/map_filter.rst b/map_filter.rst index 5ecea5a..c2a6834 100644 --- a/map_filter.rst +++ b/map_filter.rst @@ -41,9 +41,9 @@ of a list of inputs we can even have a list of functions! .. code:: python def multiply(x): - return (x*x) + return (x*x) def add(x): - return (x+x) + return (x+x) funcs = [multiply, add] for i in range(5): From 7aa909fcd8123ddb8182de8a95d5dbee42e48ef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Wed, 23 Mar 2016 20:18:11 +0500 Subject: [PATCH 043/152] Int is not iterable --- generators.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/generators.rst b/generators.rst index 294c12f..6f21763 100644 --- a/generators.rst +++ b/generators.rst @@ -157,6 +157,13 @@ iterable. While an ``int`` isn't an iterable, we can use it on string! .. code:: python + int_var = 1779 + iter(int_var) + # Output: Traceback (most recent call last): + File "", line 1, in + TypeError: 'int' object is not iterable + # This is because int is not iterable + my_string = "Yasoob" my_iter = iter(my_string) next(my_iter) From 51847371f983ae2f9d9fb3486fa4c4264522ad71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Wed, 23 Mar 2016 20:18:41 +0500 Subject: [PATCH 044/152] Forgot the comments initially --- generators.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generators.rst b/generators.rst index 6f21763..c0a4d70 100644 --- a/generators.rst +++ b/generators.rst @@ -160,8 +160,8 @@ iterable. While an ``int`` isn't an iterable, we can use it on string! int_var = 1779 iter(int_var) # Output: Traceback (most recent call last): - File "", line 1, in - TypeError: 'int' object is not iterable + # File "", line 1, in + # TypeError: 'int' object is not iterable # This is because int is not iterable my_string = "Yasoob" From f15e890dcd8482f7aabc977f7fd372437819aec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Wed, 23 Mar 2016 20:42:58 +0500 Subject: [PATCH 045/152] All translations are welcome. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 078e27e..bd695c7 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,10 @@ Acknowledgement: He wrote the chapter on Open function. Thanks Philipp! :+1: +Translation: +------------ +If you want to translate this book in any other language then kindly let [me know](mailto:yasoob.khld@gmail.com). I would love your contribution. + License: ------- From 3bc7fbe447699c12a365185ecec5f590152dae95 Mon Sep 17 00:00:00 2001 From: Paul Longtine Date: Wed, 30 Mar 2016 19:56:40 -0400 Subject: [PATCH 046/152] Double equals means equality. name == yasoob is false. --- args_and_kwargs.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/args_and_kwargs.rst b/args_and_kwargs.rst index 332ff2f..544742e 100644 --- a/args_and_kwargs.rst +++ b/args_and_kwargs.rst @@ -51,10 +51,10 @@ arguments** in a function. Here is an example to get you going with it: def greet_me(**kwargs): for key, value in kwargs.items(): - print("{0} == {1}".format(key, value)) + print("{0} = {1}".format(key, value)) >>> greet_me(name="yasoob") - name == yasoob + name = yasoob So you can see how we handled a keyworded argument list in our function. This is just the basics of \*\*kwargs and you can see how useful it is. From 168c079800d8ea857ee5f479a5c2113d61633f3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Fri, 1 Apr 2016 01:11:22 +0500 Subject: [PATCH 047/152] Add Chinese into the list of translations --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bd695c7..b9f062a 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,9 @@ He wrote the chapter on Open function. Thanks Philipp! :+1: Translation: ------------ -If you want to translate this book in any other language then kindly let [me know](mailto:yasoob.khld@gmail.com). I would love your contribution. +If you want to translate this book in any other language then kindly let [me know](mailto:yasoob.khld@gmail.com). I would love your contribution. The currently translated versions are listed below: + +- [Chinese](https://github.com/eastlakeside/interpy-zh) License: ------- From da034fd37cbeb0698630f4b7a7a79310168d25dd Mon Sep 17 00:00:00 2001 From: liuwons Date: Mon, 11 Apr 2016 15:50:37 +0800 Subject: [PATCH 048/152] Fix a syntax error in 'python_c_extension' --- python_c_extension.rst | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/python_c_extension.rst b/python_c_extension.rst index 852b2c6..5cea2e2 100644 --- a/python_c_extension.rst +++ b/python_c_extension.rst @@ -288,17 +288,12 @@ file, it's pretty straight forward. "Add all ze lists"); } -A step by step explanation - \* The ```` file consists of all -the required types (to represent Python object types) and function -definitions (to operate on the python objects). \* Next we write the -function which we plan to call from python. Conventionally the function -names are {module-name}\_{function-name}, which in this case is -``addList_add``. More about the function later. \* Then fill in the info -table - which contains all the relevant info of the functions we desire -to have in the module. Every row corresponds to a function, with the -last one being a sentinel value (row of null elements). \* Finally the -module initialization block which is of the signature -``PyMODINIT_FUNC init{module-name}``. +A step by step explanation : + +- The ```` file consists of all the required types (to represent Python object types) and function definitions (to operate on the python objects). +- Next we write the function which we plan to call from python. Conventionally the function names are {module-name}\_{function-name}, which in this case is ``addList_add``. More about the function later. +- Then fill in the info table - which contains all the relevant info of the functions we desire to have in the module. Every row corresponds to a function, with the last one being a sentinel value (row of null elements). +- Finally the module initialization block which is of the signature ``PyMODINIT_FUNC init{module-name}``. The function ``addList_add`` accepts arguments as a PyObject type struct (args is also a tuple type - but since everything in python is an From 82b6a4a11b028a13fb527e79c029a7248e9d22b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Sun, 24 Apr 2016 11:32:34 +0500 Subject: [PATCH 049/152] Added Russian into the list of translations --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b9f062a..9ba853d 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,7 @@ Translation: If you want to translate this book in any other language then kindly let [me know](mailto:yasoob.khld@gmail.com). I would love your contribution. The currently translated versions are listed below: - [Chinese](https://github.com/eastlakeside/interpy-zh) +- [Russian](https://github.com/lancelote/interpy-ru) License: ------- From 3a4bb75ac95b71274537465e4f5303cce9b9e62b Mon Sep 17 00:00:00 2001 From: Alfredo Romeu Date: Sun, 24 Apr 2016 13:17:13 +0200 Subject: [PATCH 050/152] Restructured menu in sections --- README.md | 56 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 9ba853d..bdeac01 100644 --- a/README.md +++ b/README.md @@ -25,31 +25,51 @@ Moreover, if you want to add more content to this book then kindly submit a pull Table of Contents: ------------------ -- [\*args and \*\*kwargs](args_and_kwargs.rst) -- [Debugging](debugging.rst) -- [Generators](generators.rst) -- [Map & Filter](map_filter.rst) -- [``set`` Data Structure](set_-_data_structure.rst) -- [Ternary Operators](ternary_operators.rst) -- [Decorators](decorators.rst) -- [Global & Return](global_&_return.rst) -- [Mutation](mutation.rst) -- [\_\_slots\_\_ Magic](__slots__magic.rst) +1) Programmer tools + - [Virtual Environment](virtual_environment.rst) -- [Collections](collections.rst) -- [Enumerate](enumerate.rst) +- [Debugging](debugging.rst) - [Object introspection](object_introspection.rst) -- [Comprehensions](comprehensions.rst) + +2) Syntax + - [Exceptions](exceptions.rst) -- [Lambdas](lambdas.rst) -- [One Liners](one_liners.rst) - [For - Else](for_-_else.rst) -- [Python C extensions](python_c_extension.rst) +- [Ternary Operators](ternary_operators.rst) +- [Global & Return](global_&_return.rst) - [Open function](open_function.rst) -- [Targeting Python 2+3](targeting_python_2_3.rst) +- [\*args and \*\*kwargs](args_and_kwargs.rst) +- [Context managers](context_managers.rst) + +3) Functional programming + +- [Enumerate](enumerate.rst) +- [Lambdas](lambdas.rst) +- [``set`` Data Structure](set_-_data_structure.rst) +- [Map & Filter](map_filter.rst) +- [Comprehensions](comprehensions.rst) + +4) Data structures + +- [Generators](generators.rst) - [Coroutines](coroutines.rst) + +5) Data types + +- [Collections](collections.rst) +- [Mutation](mutation.rst) +- [\_\_slots\_\_ Magic](__slots__magic.rst) + +6) Decorators + +- [What is a decorator?](decorators.rst) - [Function caching](function_caching.rst) -- [Context managers](context_managers.rst) + +7) Extras + +- [One Liners](one_liners.rst) +- [Targeting Python 2+3](targeting_python_2_3.rst) +- [Python C extensions](python_c_extension.rst) Author: ------ From 9627cf08ee7c460cfd64f2297c001f7e89294291 Mon Sep 17 00:00:00 2001 From: Pavel Karateev Date: Fri, 5 Aug 2016 10:36:42 +0300 Subject: [PATCH 051/152] Fixes #132, typo in the super() call --- decorators.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decorators.rst b/decorators.rst index 16e35b7..7bf2609 100644 --- a/decorators.rst +++ b/decorators.rst @@ -429,7 +429,7 @@ will not be covered here). ''' def __init__(self, email='admin@myproject.com', *args, **kwargs): self.email = email - super(logit, self).__init__(*args, **kwargs) + super(email_logit, self).__init__(*args, **kwargs) def notify(self): # Send an email to self.email From d858682d481a41169285086e1e1cc89342fd5c34 Mon Sep 17 00:00:00 2001 From: Akul Mehra Date: Sun, 14 Aug 2016 12:32:39 +0530 Subject: [PATCH 052/152] format dict to highlight on line 34 one_liners.rst ``dict``s to ``dict`` s --- one_liners.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/one_liners.rst b/one_liners.rst index e384bcb..1914ea6 100644 --- a/one_liners.rst +++ b/one_liners.rst @@ -31,7 +31,7 @@ repl. Here is the relevant code: my_dict = {'name': 'Yasoob', 'age': 'undefined', 'personality': 'awesome'} pprint(my_dict) -This is more effective on ``dict``s. Moreover, if you want to pretty print +This is more effective on ``dict`` s. Moreover, if you want to pretty print json quickly from a file then you can simply do: .. code:: python From 578d19bd72e40d658acc2cc45cb84a2968c5d181 Mon Sep 17 00:00:00 2001 From: Kiseok Kim Date: Tue, 18 Oct 2016 14:14:02 +0900 Subject: [PATCH 053/152] fixed pep8 error. --- map_filter.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/map_filter.rst b/map_filter.rst index c2a6834..f0add19 100644 --- a/map_filter.rst +++ b/map_filter.rst @@ -101,6 +101,6 @@ Now let's try it with reduce: .. code:: python from functools import reduce - product = reduce( (lambda x, y: x * y), [1, 2, 3, 4] ) + product = reduce((lambda x, y: x * y), [1, 2, 3, 4]) # Output: 24 From 873e7a38d66db672c22856149c6d25f6f47f3334 Mon Sep 17 00:00:00 2001 From: Kiseok Kim Date: Tue, 25 Oct 2016 15:24:27 +0900 Subject: [PATCH 054/152] fixed comparison operator. "is" to "==" --- comprehensions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/comprehensions.rst b/comprehensions.rst index b83285a..43af9cd 100644 --- a/comprehensions.rst +++ b/comprehensions.rst @@ -33,7 +33,7 @@ Here is a short example: .. code:: python - multiples = [i for i in range(30) if i % 3 is 0] + multiples = [i for i in range(30) if i % 3 == 0] print(multiples) # Output: [0, 3, 6, 9, 12, 15, 18, 21, 24, 27] From 6ce0d78f0dec04fd7cb2a271f684585d368969a6 Mon Sep 17 00:00:00 2001 From: Blithe Brandon Date: Fri, 13 Jan 2017 17:27:23 -0800 Subject: [PATCH 055/152] Make Reduce "normal way" loop code visible Code section was being omitted, due to missing blank line after ".. code:: python" --- map_filter.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/map_filter.rst b/map_filter.rst index f0add19..5e19258 100644 --- a/map_filter.rst +++ b/map_filter.rst @@ -88,6 +88,7 @@ a basic for loop: .. code:: python + product = 1 list = [1, 2, 3, 4] for num in list: From 3f81cc2261fdd538817b6e67c775889ccc78c866 Mon Sep 17 00:00:00 2001 From: inv3nt3d Date: Mon, 30 Jan 2017 22:46:46 -0500 Subject: [PATCH 056/152] Add print On line 169 print() is called on next(my_iter) so the output 'Y' is visible on the console. --- generators.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators.rst b/generators.rst index c0a4d70..f65afae 100644 --- a/generators.rst +++ b/generators.rst @@ -166,7 +166,7 @@ iterable. While an ``int`` isn't an iterable, we can use it on string! my_string = "Yasoob" my_iter = iter(my_string) - next(my_iter) + print(next(my_iter)) # Output: 'Y' Now that is much better. I am sure that you loved learning about From 3f86901754f3013634174e37579b01dcbe7d8fc2 Mon Sep 17 00:00:00 2001 From: Amine SEHILI Date: Sun, 5 Feb 2017 13:38:57 +0100 Subject: [PATCH 057/152] Add `OrderedDict` to collections.rst --- collections.rst | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/collections.rst b/collections.rst index 81f12fb..c09a3bf 100644 --- a/collections.rst +++ b/collections.rst @@ -8,6 +8,7 @@ their usefulness. The ones which we will talk about are: - ``defaultdict`` +- ``OrderedDict`` - ``counter`` - ``deque`` - ``namedtuple`` @@ -82,6 +83,42 @@ sample code: print(json.dumps(some_dict)) # Output: {"colours": {"favourite": "yellow"}} +``OrderedDict`` +^^^^^^^^^^^^^^^^^^^ + +``OrderedDict`` keeps its entries sorted as they are initially inserted. +Overwriting a value of an existing key doesn't change the position of +that key. However, deleting and reinserting an entry moves the key to +the end of the dictionary. + +**Problem:** + +.. code:: python + + colours = {"Red" : 198, "Green" : 170, "Blue" : 160} + for key, value in colours.items(): + print(key, value) + # Output: + # Green 170 + # Blue 160 + # Red 198 + # Entries are retrieved in an unpredictable order + +**Solution:** + +.. code:: python + + from collections import OrderedDict + + colours = OrderedDict([("Red", 198), ("Green", 170), ("Blue", 160)]) + for key, value in colours.items(): + print(key, value) + # Output: + # Red 198 + # Green 170 + # Blue 160 + # Insertion order is preserved + ``counter`` ^^^^^^^^^^^^^^^ From 10bac564cbdd947bdbae843f479b5b58a599743a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ara=C3=BAjo=20Miranda?= Date: Thu, 30 Mar 2017 05:57:53 -0300 Subject: [PATCH 058/152] Reworded optional argument explanation --- enumerate.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/enumerate.rst b/enumerate.rst index a087c94..06719f0 100644 --- a/enumerate.rst +++ b/enumerate.rst @@ -11,8 +11,8 @@ something and have an automatic counter. Here is an example: for counter, value in enumerate(some_list): print(counter, value) -This is not it. ``enumerate`` also accepts some optional arguments which -make it even more useful. +And there is more! ``enumerate`` also accepts an optional argument which +makes it even more useful. .. code:: python From a60a7431f97e32f4f0c68d66649c28b73f2e0bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Sat, 22 Apr 2017 14:38:26 +0500 Subject: [PATCH 059/152] It's 2017 :sparkles: --- conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.py b/conf.py index 7184904..b264a66 100644 --- a/conf.py +++ b/conf.py @@ -42,7 +42,7 @@ # General information about the project. project = u'Python Tips' -copyright = u'2015, Muhammad Yasoob Ullah Khalid' +copyright = u'2017, Muhammad Yasoob Ullah Khalid' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the From 9367c9f6a13f7885c5bfa823fed45f0120284c98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Sat, 22 Apr 2017 14:40:11 +0500 Subject: [PATCH 060/152] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index bdeac01..8a199e9 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ If you want to translate this book in any other language then kindly let [me kno - [Chinese](https://github.com/eastlakeside/interpy-zh) - [Russian](https://github.com/lancelote/interpy-ru) +- [Korean](https://github.com/DDanggle/interpy-kr) License: ------- From 5f61e818effd4065d06097b450eb764e55def97a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Sat, 22 Apr 2017 14:42:13 +0500 Subject: [PATCH 061/152] :sparkles: Portuguese --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8a199e9..2783670 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,7 @@ If you want to translate this book in any other language then kindly let [me kno - [Chinese](https://github.com/eastlakeside/interpy-zh) - [Russian](https://github.com/lancelote/interpy-ru) - [Korean](https://github.com/DDanggle/interpy-kr) +- [Portuguese](https://github.com/joanasouza/intermediatePython) License: ------- From 00a2868d67e297b24e28984b97068acf9e2a84d3 Mon Sep 17 00:00:00 2001 From: GraemeBrown Date: Fri, 2 Jun 2017 10:49:36 -0700 Subject: [PATCH 062/152] Update map_filter.rst Provided an explanation of what map() is actually doing. --- map_filter.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/map_filter.rst b/map_filter.rst index f0add19..41e6f65 100644 --- a/map_filter.rst +++ b/map_filter.rst @@ -80,8 +80,9 @@ Reduce ^^^^^^^^^ ``Reduce`` is a really useful function for performing some computation on -a list and returning the result. For example, if you wanted to compute -the product of a list of integers. +a list and returning the result. It applies a rolling computation to sequential +pairs of values in a list. For example, if you wanted to compute the product +of a list of integers. So the normal way you might go about doing this task in python is using a basic for loop: From a798ad08eba94ebc9f109fec0a649a80739da69a Mon Sep 17 00:00:00 2001 From: David Awad Date: Mon, 19 Jun 2017 11:06:22 -0400 Subject: [PATCH 063/152] add newline for code block fix rendering issue for map_filter pre_reduce example --- map_filter.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/map_filter.rst b/map_filter.rst index 41e6f65..9552cf8 100644 --- a/map_filter.rst +++ b/map_filter.rst @@ -87,8 +87,8 @@ of a list of integers. So the normal way you might go about doing this task in python is using a basic for loop: - .. code:: python + product = 1 list = [1, 2, 3, 4] for num in list: From 908b6e1ec623b5c1fedc9d8ead3674181a7412e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Tue, 14 Nov 2017 00:18:52 -0500 Subject: [PATCH 064/152] Added Codesponsor --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 2783670..dd7e703 100644 --- a/README.md +++ b/README.md @@ -98,3 +98,7 @@ License: This book is released under the [following](http://creativecommons.org/licenses/by-nc-sa/4.0/) CC license (CC BY-NC-SA 4.0). If you end up using/recommending this book to someone then kindly [let me know](mailto:yasoob.khld@gmail.com). :smile: + + + Sponsor + From 3ffcddbec5d50d72605f28829e14e2ca630c5513 Mon Sep 17 00:00:00 2001 From: yasoob Date: Tue, 14 Nov 2017 10:04:32 -0500 Subject: [PATCH 065/152] Added media.net --- _static/js/ad.js | 7 +++++++ conf.py | 10 +++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 _static/js/ad.js diff --git a/_static/js/ad.js b/_static/js/ad.js new file mode 100644 index 0000000..e6ad1df --- /dev/null +++ b/_static/js/ad.js @@ -0,0 +1,7 @@ + + diff --git a/conf.py b/conf.py index b264a66..1229c4a 100644 --- a/conf.py +++ b/conf.py @@ -217,7 +217,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'pythontips', u'Python Tips Documentation', + ('index', 'pythontips', u'Python Tips', [u'Muhammad Yasoob Ullah Khalid'], 1) ] @@ -231,7 +231,7 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'PythonTips', u'Python Tips Documentation', + ('index', 'PythonTips', u'Python Tips', u'Muhammad Yasoob Ullah Khalid', 'PythonTips', 'One line description of project.', 'Miscellaneous'), ] @@ -255,7 +255,7 @@ epub_title = u'Python Tips' epub_author = u'Muhammad Yasoob Ullah Khalid' epub_publisher = u'Muhammad Yasoob Ullah Khalid' -epub_copyright = u'2015, Muhammad Yasoob Ullah Khalid' +epub_copyright = u'2017, Muhammad Yasoob Ullah Khalid' #epub_theme = 'epub' @@ -313,3 +313,7 @@ #html_theme_path = ['_themes'] html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] html_theme = 'sphinx_rtd_theme' + + +def setup(app): + app.add_javascript("js/ad.js") From a51af2e22a5a99c8e74f7dd41a6e3b3816d868da Mon Sep 17 00:00:00 2001 From: yasoob Date: Tue, 14 Nov 2017 10:09:40 -0500 Subject: [PATCH 066/152] corrected media.net inclusion --- _static/js/ad.js | 7 ------- _templates/layout.html | 11 +++++++++++ conf.py | 2 -- 3 files changed, 11 insertions(+), 9 deletions(-) delete mode 100644 _static/js/ad.js create mode 100644 _templates/layout.html diff --git a/_static/js/ad.js b/_static/js/ad.js deleted file mode 100644 index e6ad1df..0000000 --- a/_static/js/ad.js +++ /dev/null @@ -1,7 +0,0 @@ - - diff --git a/_templates/layout.html b/_templates/layout.html new file mode 100644 index 0000000..974cfa9 --- /dev/null +++ b/_templates/layout.html @@ -0,0 +1,11 @@ +{% extends "!layout.html" %} +{% block extrahead %} + + + +{% endblock %} \ No newline at end of file diff --git a/conf.py b/conf.py index 1229c4a..04b64ff 100644 --- a/conf.py +++ b/conf.py @@ -315,5 +315,3 @@ html_theme = 'sphinx_rtd_theme' -def setup(app): - app.add_javascript("js/ad.js") From dcb69704451b0e06bd2b184587b8775d820f6f46 Mon Sep 17 00:00:00 2001 From: yasoob Date: Tue, 14 Nov 2017 10:20:52 -0500 Subject: [PATCH 067/152] improved ad display --- _static/custom.css | 6 ++++++ conf.py | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 _static/custom.css diff --git a/_static/custom.css b/_static/custom.css new file mode 100644 index 0000000..bcdeef2 --- /dev/null +++ b/_static/custom.css @@ -0,0 +1,6 @@ + +@media screen and (min-width: 1000px){ + iframe{ + margin-left: 330px; + } +} \ No newline at end of file diff --git a/conf.py b/conf.py index 04b64ff..19808a0 100644 --- a/conf.py +++ b/conf.py @@ -314,4 +314,5 @@ html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] html_theme = 'sphinx_rtd_theme' - +def setup(app): + app.add_stylesheet('custom.css') From afba29a935956904252dbb10bcdcc97f12dbb6d7 Mon Sep 17 00:00:00 2001 From: yasoob Date: Mon, 27 Nov 2017 12:59:55 -0500 Subject: [PATCH 068/152] updated ad code --- _templates/layout.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_templates/layout.html b/_templates/layout.html index 974cfa9..2f86c0c 100644 --- a/_templates/layout.html +++ b/_templates/layout.html @@ -1,5 +1,5 @@ {% extends "!layout.html" %} -{% block extrahead %} +{% block extrabody %} + + + + + {% if (theme_prev_next_buttons_location == 'top' or theme_prev_next_buttons_location == 'both') and (next or prev) %} + + {% endif %} +
+ diff --git a/_templates/layout.html b/_templates/layout.html deleted file mode 100644 index d70e38e..0000000 --- a/_templates/layout.html +++ /dev/null @@ -1,11 +0,0 @@ -{% extends "!layout.html" %} -{% block body %} - - - -{% endblock %} \ No newline at end of file From ed378360a98d4b8b3ecc99685ed6fe7a019e3df4 Mon Sep 17 00:00:00 2001 From: yasoob Date: Mon, 27 Nov 2017 13:32:54 -0500 Subject: [PATCH 071/152] removed custom.css --- conf.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/conf.py b/conf.py index 19808a0..1de0eaa 100644 --- a/conf.py +++ b/conf.py @@ -314,5 +314,3 @@ html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] html_theme = 'sphinx_rtd_theme' -def setup(app): - app.add_stylesheet('custom.css') From ad41713011f3ff491d2adde2e0939d3060fa7e70 Mon Sep 17 00:00:00 2001 From: yasoob Date: Fri, 1 Dec 2017 03:04:16 -0500 Subject: [PATCH 072/152] got rid of ads and added a note about internship --- _templates/breadcrumbs.html | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index 9661184..b07b4ad 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -26,13 +26,11 @@
- - +
+

Note

+

Hi! I am currently looking for internships for Summer 2018. If you feel like your company might have some place for me, please reach out. You can check my resume over here and if you want to get to know about my journey, you can read this article: How I got into programming

. + +
    {% block breadcrumbs %} From 79fcea3aecb7eda6033de67c488cb3061236cb99 Mon Sep 17 00:00:00 2001 From: yasoob Date: Fri, 1 Dec 2017 03:14:34 -0500 Subject: [PATCH 073/152] updated links to add google analytics --- _templates/breadcrumbs.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index b07b4ad..502acda 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -28,7 +28,7 @@

    Note

    -

    Hi! I am currently looking for internships for Summer 2018. If you feel like your company might have some place for me, please reach out. You can check my resume over here and if you want to get to know about my journey, you can read this article: How I got into programming

    . +

    Hi! I am currently looking for internships for Summer 2018. If you feel like your company might have some place for me, please reach out. You can check my resume over here and if you want to get to know about my journey, you can read this article: How I got into programming

    .
    From d6862810903649f4b75097ba30c2d857bfae98c3 Mon Sep 17 00:00:00 2001 From: Pavel Karateev Date: Tue, 5 Dec 2017 09:25:14 +0300 Subject: [PATCH 074/152] Fixes "source" command invocation example A little bit more precise this way --- virtual_environment.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virtual_environment.rst b/virtual_environment.rst index 58746ce..28b119f 100644 --- a/virtual_environment.rst +++ b/virtual_environment.rst @@ -32,7 +32,7 @@ To install it, just type this command in the shell: The most important commands are: - ``$ virtualenv myproject`` -- ``$ source bin/activate`` +- ``$ source myproject/bin/activate`` This first one makes an isolated virtualenv environment in the ``myproject`` folder and the second command activates that isolated From beb15c1ac9b4554de9f372a026f568528c029a6b Mon Sep 17 00:00:00 2001 From: Sudip Bhandari Date: Fri, 15 Dec 2017 13:03:37 +0530 Subject: [PATCH 075/152] more info on encoding and utf-8 --- open_function.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/open_function.rst b/open_function.rst index 8281b2f..3683bb3 100644 --- a/open_function.rst +++ b/open_function.rst @@ -69,8 +69,8 @@ and does the right thing. You can pass in the encoding with the Python -- specific default will be picked. You may be tempted to rely on these defaults, but the defaults are often wrong, or the default encoding cannot actually express all characters in the file (this will happen often on -Python 2.x and/or Windows). So go ahead and pick an encoding. ``utf-8`` -is a terrific one. When you write a file, you can just pick the encoding +Python 2.x and/or Windows). So go ahead and pick an encoding. Encoding is the way to instruct computers about how the numbers should be stored as bytes in memory. ``utf-8`` +is a terrific one and is supported by major browsers and programming languages. When you write a file, you can just pick the encoding to your liking (or the liking of the program that will eventually read your file). From 84cb6577f1dd08f92f7604b1e688fc2abf423500 Mon Sep 17 00:00:00 2001 From: KarlSebaL Date: Fri, 29 Dec 2017 18:46:16 +0100 Subject: [PATCH 076/152] Update python_c_extension.rst Should be all long since you compare to long and add to long:) --- python_c_extension.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_c_extension.rst b/python_c_extension.rst index 5cea2e2..204c07c 100644 --- a/python_c_extension.rst +++ b/python_c_extension.rst @@ -252,7 +252,7 @@ file, it's pretty straight forward. long length = PyList_Size(listObj); //iterate over all the elements - int i, sum =0; + long i, sum =0; for(i = 0; i < length; i++){ //get an element out of the list - the element is also a python objects PyObject* temp = PyList_GetItem(listObj, i); From 64774bc0391b4622bc8c9357cc90d84739cd7e9c Mon Sep 17 00:00:00 2001 From: knewzen <772608204@qq.com> Date: Fri, 5 Jan 2018 00:55:59 +0800 Subject: [PATCH 077/152] remove codesponsor --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index dd7e703..6d1284b 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,4 @@ This book is released under the [following](http://creativecommons.org/licenses/ If you end up using/recommending this book to someone then kindly [let me know](mailto:yasoob.khld@gmail.com). :smile: - - Sponsor - + From 75d7140908446cefb651183d87422a600dfdadd7 Mon Sep 17 00:00:00 2001 From: yasoob Date: Fri, 19 Jan 2018 02:36:40 +0500 Subject: [PATCH 078/152] freelancing --- _templates/breadcrumbs.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index 502acda..6657860 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -28,7 +28,7 @@

    Note

    -

    Hi! I am currently looking for internships for Summer 2018. If you feel like your company might have some place for me, please reach out. You can check my resume over here and if you want to get to know about my journey, you can read this article: How I got into programming

    . +

    Hi! I am currently looking for some freelance projects. If you have a project idea in mind please feel free to send me an email or check out my personal website. If you want to get to know about my journey, you can read this article: How I got into programming

    .
    From 9410a38e790feb14314d65017866aff6a27e681c Mon Sep 17 00:00:00 2001 From: Victor Shih Date: Mon, 21 May 2018 09:43:45 -0700 Subject: [PATCH 079/152] Grammar. --- context_managers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/context_managers.rst b/context_managers.rst index f3ff506..e70a3f7 100644 --- a/context_managers.rst +++ b/context_managers.rst @@ -100,7 +100,7 @@ an error is encountered. 2. It allows the ``__exit__`` method to handle the exception. 3. If ``__exit__`` returns True then the exception was gracefully handled. -4. If anything else than True is returned by the ``__exit__`` method then +4. If anything other than True is returned by the ``__exit__`` method then an exception is raised by the ``with`` statement. In our case the ``__exit__`` method returns ``None`` (when no return From 6748a9cd1bcbd2c7896466914d2fdfb2c89e6d3c Mon Sep 17 00:00:00 2001 From: Andrii Galkin Date: Tue, 29 May 2018 12:37:40 -0700 Subject: [PATCH 080/152] Update comprehensions.rst Added explanation of generator comprehensions --- comprehensions.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/comprehensions.rst b/comprehensions.rst index 43af9cd..2c09aca 100644 --- a/comprehensions.rst +++ b/comprehensions.rst @@ -9,6 +9,7 @@ comprehensions are supported in both Python 2 and Python 3: - list comprehensions - dictionary comprehensions - set comprehensions +- generator comprehensions We will discuss them one by one. Once you get the hang of using ``list`` comprehensions then you can use any of them easily. @@ -91,3 +92,17 @@ that they use braces ``{}``. Here is an example: squared = {x**2 for x in [1, 1, 2]} print(squared) # Output: {1, 4} + +``generator`` comprehensions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +They are also similar to list comprehensions. The only difference is that they don't allocate memory for the whole list but generate one item at a time, thus more memory effecient. + +.. code:: python + + multiples_gen = (i for i in range(30) if i % 3 == 0) + print(multiples_gen) + # Output: at 0x7fdaa8e407d8> + for x in multiples_gen: + print(x) + # Outputs numbers From 60362325e3517232c9dcd3160137c3ef006110c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Tue, 29 May 2018 17:01:31 -0400 Subject: [PATCH 081/152] Closes #76 --- lambdas.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lambdas.rst b/lambdas.rst index 1223dca..73328b8 100644 --- a/lambdas.rst +++ b/lambdas.rst @@ -21,7 +21,7 @@ normal functions and even behave like them. print(add(3, 5)) # Output: 8 -Here are a few useful use cases for lambdas and just a few way in which +Here are a few useful use cases for lambdas and just a few ways in which they are used in the wild: **List sorting** From 47de9c20acae0611805984f35874bbe6c5dffa8a Mon Sep 17 00:00:00 2001 From: yasoob Date: Tue, 29 May 2018 17:09:31 -0400 Subject: [PATCH 082/152] closes #88 Thanks @JoshMcCullough --- context_managers.rst | 65 ++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/context_managers.rst b/context_managers.rst index e70a3f7..45d6eb4 100644 --- a/context_managers.rst +++ b/context_managers.rst @@ -1,4 +1,4 @@ -Context managers +Context Managers ---------------- Context managers allow you to allocate and release resources precisely @@ -30,16 +30,16 @@ advantage of using a ``with`` statement is that it makes sure our file is closed without paying attention to how the nested block exits. A common use case of context managers is locking and unlocking resources -and closing opened files (as I have already showed you). +and closing opened files (as I have already shown you). -Let's see how we can implement our own Context Manager. This would allow +Let's see how we can implement our own Context Manager. This should allow us to understand exactly what's going on behind the scenes. -Implementing Context Manager as a Class: +Implementing a Context Manager as a Class: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ At the very least a context manager has an ``__enter__`` and -``__exit__`` methods defined. Let's make our own file opening Context +``__exit__`` method defined. Let's make our own file-opening Context Manager and learn the basics. .. code:: python @@ -52,7 +52,7 @@ Manager and learn the basics. def __exit__(self, type, value, traceback): self.file_obj.close() -Just by defining ``__enter__`` and ``__exit__`` methods we can use it in +Just by defining ``__enter__`` and ``__exit__`` methods we can use our new class in a ``with`` statement. Let's try: .. code:: python @@ -60,20 +60,20 @@ a ``with`` statement. Let's try: with File('demo.txt', 'w') as opened_file: opened_file.write('Hola!') -Our ``__exit__`` function accepts three arguments. They are required by +Our ``__exit__`` method accepts three arguments. They are required by every ``__exit__`` method which is a part of a Context Manager class. Let's talk about what happens under-the-hood. -1. The ``with`` statement stores the ``__exit__`` method of ``File`` +1. The ``with`` statement stores the ``__exit__`` method of the ``File`` class. -2. It calls the ``__enter__`` method of ``File`` class. -3. ``__enter__`` method opens the file and returns it. -4. the opened file handle is passed to ``opened_file``. -5. we write to the file using ``.write()`` -6. ``with`` statement calls the stored ``__exit__`` method. -7. the ``__exit__`` method closes the file. - -Handling exceptions +2. It calls the ``__enter__`` method of the ``File`` class. +3. The ``__enter__`` method opens the file and returns it. +4. The opened file handle is passed to ``opened_file``. +5. We write to the file using ``.write()``. +6. The ``with`` statement calls the stored ``__exit__`` method. +7. The ``__exit__`` method closes the file. + +Handling Exceptions ^^^^^^^^^^^^^^^^^^^ We did not talk about the ``type``, ``value`` and ``traceback`` @@ -92,20 +92,20 @@ instance: with File('demo.txt', 'w') as opened_file: opened_file.undefined_function('Hola!') -Let's list down the steps which are taken by the ``with`` statement when -an error is encountered. +Let's list the steps which are taken by the ``with`` statement when +an error is encountered: 1. It passes the type, value and traceback of the error to the ``__exit__`` method. 2. It allows the ``__exit__`` method to handle the exception. -3. If ``__exit__`` returns True then the exception was gracefully +3. If ``__exit__`` returns ``True`` then the exception was gracefully handled. -4. If anything other than True is returned by the ``__exit__`` method then - an exception is raised by the ``with`` statement. +4. If anything other than ``True`` is returned by the ``__exit__`` method then + the exception is raised by the ``with`` statement. In our case the ``__exit__`` method returns ``None`` (when no return -statement is encountered then the method returns ``None``). Therefore, the -``with`` statement raises the exception. +statement is encountered then the method returns ``None``). Therefore, +the ``with`` statement raises the exception: .. code:: python @@ -132,11 +132,11 @@ Let's try handling the exception in the ``__exit__`` method: # Output: Exception has been handled -Our ``__exit__`` method returned True, therefore no exception was raised +Our ``__exit__`` method returned ``True``, therefore no exception was raised by the ``with`` statement. -This is not the only way to implement context managers. There is another -way and we will be looking at it in this next section. +This is not the only way to implement Context Managers. There is another +way and we will be looking at it in the next section. Implementing a Context Manager as a Generator ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -156,9 +156,9 @@ Let's see a basic, useless example: yield f f.close() -Okay! This way of implementing Context Managers appears to be more +Okay! This way of implementing Context Managers appear to be more intuitive and easy. However, this method requires some knowledge about -generators, yield, and decorators. In this example we have not caught any +generators, yield and decorators. In this example we have not caught any exceptions which might occur. It works in mostly the same way as the previous method. @@ -167,11 +167,11 @@ Let's dissect this method a little. 1. Python encounters the ``yield`` keyword. Due to this it creates a generator instead of a normal function. 2. Due to the decoration, contextmanager is called with the function - name (open\_file) as it's argument. -3. The ``contextmanager`` function returns the generator wrapped by the + name (``open\_file``) as it's argument. +3. The ``contextmanager`` decorator returns the generator wrapped by the ``GeneratorContextManager`` object. 4. The ``GeneratorContextManager`` is assigned to the ``open_file`` - function. Therefore, when we later call ``open_file`` function, we + function. Therefore, when we later call the ``open_file`` function, we are actually calling the ``GeneratorContextManager`` object. So now that we know all this, we can use the newly generated Context @@ -180,5 +180,4 @@ Manager like this: .. code:: python with open_file('some_file') as f: - f.write('hola!') - + f.write('hola!') \ No newline at end of file From cea338fbe42aeb03555038c802e6c96fe4ca9bd8 Mon Sep 17 00:00:00 2001 From: yasoob Date: Tue, 29 May 2018 17:12:07 -0400 Subject: [PATCH 083/152] Closes #161 --- exceptions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exceptions.rst b/exceptions.rst index cbe752e..2b29381 100644 --- a/exceptions.rst +++ b/exceptions.rst @@ -111,7 +111,7 @@ example: print('This would be printed in every case.') # Output: I am sure no exception is going to occur! - # This would only run if no exception occurs. + # This would only run if no exception occurs. And an error here would NOT be caught # This would be printed in every case. The ``else`` clause would only run if no exception occurs and it would run From 13458e72e0e9281202fb1881c482319532b8bc03 Mon Sep 17 00:00:00 2001 From: yasoob Date: Tue, 29 May 2018 17:15:17 -0400 Subject: [PATCH 084/152] Closes #158 --- function_caching.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/function_caching.rst b/function_caching.rst index 865a866..7c06149 100644 --- a/function_caching.rst +++ b/function_caching.rst @@ -67,6 +67,8 @@ is a generic cache: fibonacci(25) +**Note:** memoize won't cache unhashable types (dict, lists, etc...) but only the immutable types. Keep that in mind when using it. + `Here `__ is a fine article by Caktus Group in which they caught a bug in Django which occurred due to ``lru_cache``. It's an interesting read. Do check it out. From 2cd38c31f338dbddffa783ff8fc904a4985e3994 Mon Sep 17 00:00:00 2001 From: yasoob Date: Tue, 29 May 2018 17:21:44 -0400 Subject: [PATCH 085/152] Closes #155 --- generators.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generators.rst b/generators.rst index f65afae..dd983c3 100644 --- a/generators.rst +++ b/generators.rst @@ -20,8 +20,8 @@ Iterable An ``iterable`` is any object in Python which has an ``__iter__`` or a ``__getitem__`` method defined which returns an **iterator** or can take -indexes (Both of these dunder methods are fully explained in a previous -chapter). In short an ``iterable`` is any object which can provide us +indexes (You can read more about them `here `_). +In short an ``iterable`` is any object which can provide us with an **iterator**. So what is an **iterator**? Iterator From 48f51479abbd0eb384117c3247c033585620d370 Mon Sep 17 00:00:00 2001 From: yasoob Date: Tue, 29 May 2018 17:36:07 -0400 Subject: [PATCH 086/152] added a more relevant example for pprint. Closes #145 --- one_liners.rst | 56 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/one_liners.rst b/one_liners.rst index 1914ea6..17dc776 100644 --- a/one_liners.rst +++ b/one_liners.rst @@ -29,9 +29,59 @@ repl. Here is the relevant code: from pprint import pprint my_dict = {'name': 'Yasoob', 'age': 'undefined', 'personality': 'awesome'} - pprint(my_dict) - -This is more effective on ``dict`` s. Moreover, if you want to pretty print + print(dir(my_dict)) + # ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] + + pprint(dir(my_dict)) + # ['__add__', + # '__class__', + # '__contains__', + # '__delattr__', + # '__delitem__', + # '__dir__', + # '__doc__', + # '__eq__', + # '__format__', + # '__ge__', + # '__getattribute__', + # '__getitem__', + # '__gt__', + # '__hash__', + # '__iadd__', + # '__imul__', + # '__init__', + # '__init_subclass__', + # '__iter__', + # '__le__', + # '__len__', + # '__lt__', + # '__mul__', + # '__ne__', + # '__new__', + # '__reduce__', + # '__reduce_ex__', + # '__repr__', + # '__reversed__', + # '__rmul__', + # '__setattr__', + # '__setitem__', + # '__sizeof__', + # '__str__', + # '__subclasshook__', + # 'append', + # 'clear', + # 'copy', + # 'count', + # 'extend', + # 'index', + # 'insert', + # 'pop', + # 'remove', + # 'reverse', + # 'sort'] + + +This is more effective on nested ``dict`` s. Moreover, if you want to pretty print json quickly from a file then you can simply do: .. code:: python From a366c8823f25b32e6f4821d3bb0d58dba360ec11 Mon Sep 17 00:00:00 2001 From: yasoob Date: Tue, 29 May 2018 17:41:05 -0400 Subject: [PATCH 087/152] Added the classes chapter to the readme. Closes #139 --- classes.rst | 4 ++-- index.rst | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/classes.rst b/classes.rst index 3e09bb2..c22aa10 100644 --- a/classes.rst +++ b/classes.rst @@ -217,6 +217,6 @@ Without the ``__getitem__`` method we would have got this error: File "", line 1, in TypeError: 'GetTest' object has no attribute '__getitem__' -Static, Class & Abstract methods -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. Static, Class & Abstract methods +.. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/index.rst b/index.rst index 9895a2d..23cb3c5 100644 --- a/index.rst +++ b/index.rst @@ -55,6 +55,7 @@ Table of Contents object_introspection comprehensions exceptions + classes lambdas one_liners for_-_else From d53b7b5286d4eddaaf16d12888bbb42892d59ef2 Mon Sep 17 00:00:00 2001 From: yasoob Date: Tue, 29 May 2018 17:43:05 -0400 Subject: [PATCH 088/152] improved the text a bit. Closes #146 --- mutation.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mutation.rst b/mutation.rst index 440222a..493579c 100644 --- a/mutation.rst +++ b/mutation.rst @@ -30,7 +30,8 @@ something like this: bar += ['bye'] print(foo) - # Output: ['hi'] + # Expected Output: ['hi'] + # Output: ['hi', 'bye'] print(bar) # Output: ['hi', 'bye'] From 4969f16bbea5753426deea809cac0fc01a12edf1 Mon Sep 17 00:00:00 2001 From: yasoob Date: Tue, 29 May 2018 17:50:36 -0400 Subject: [PATCH 089/152] improved the multi return values section. Closes #90 --- global_&_return.rst | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/global_&_return.rst b/global_&_return.rst index 2718ed5..39a75d4 100644 --- a/global_&_return.rst +++ b/global_&_return.rst @@ -125,4 +125,36 @@ Or by more common convention: print(profile_age) # Output: 30 +Keep in mind that even in the above example we are returning a tuple (despite the lack of paranthesis) and not separate multiple values. If you want to take it one step further, you can also make use of `namedtuple `_. Here is an example: + +.. code:: python + + from collections import namedtuple + def profile(): + Person = namedtuple('Person', 'name age') + return Person(name="Danny", age=31) + + # Use as namedtuple + p = profile() + print(p, type(p)) + # Person(name='Danny', age=31) + print(p.name) + # Danny + print(p.age) + #31 + + # Use as plain tuple + p = profile() + print(p[0]) + # Danny + print(p[1]) + #31 + + # Unpack it immediatly + name, age = profile() + print(name) + # Danny + print(age) + #31 + This is a better way to do it along with returning ``lists`` and ``dicts``. Don't use ``global`` keyword unless you know what you are doing. ``global`` might be a better option in a few cases but is not in most of them. From a59159fedf28a459fb9253c277e5dd2d1d432a6c Mon Sep 17 00:00:00 2001 From: Pavel Karateev Date: Sat, 2 Jun 2018 20:07:13 +0300 Subject: [PATCH 090/152] Nesting for Table of Content --- README.md | 63 ++++++++++++++++++++++--------------------------------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 6d1284b..e637e51 100644 --- a/README.md +++ b/README.md @@ -26,50 +26,37 @@ Moreover, if you want to add more content to this book then kindly submit a pull Table of Contents: ------------------ 1) Programmer tools - -- [Virtual Environment](virtual_environment.rst) -- [Debugging](debugging.rst) -- [Object introspection](object_introspection.rst) - + - [Virtual Environment](virtual_environment.rst) + - [Debugging](debugging.rst) + - [Object introspection](object_introspection.rst) 2) Syntax - -- [Exceptions](exceptions.rst) -- [For - Else](for_-_else.rst) -- [Ternary Operators](ternary_operators.rst) -- [Global & Return](global_&_return.rst) -- [Open function](open_function.rst) -- [\*args and \*\*kwargs](args_and_kwargs.rst) -- [Context managers](context_managers.rst) - + - [Exceptions](exceptions.rst) + - [For - Else](for_-_else.rst) + - [Ternary Operators](ternary_operators.rst) + - [Global & Return](global_&_return.rst) + - [Open function](open_function.rst) + - [\*args and \*\*kwargs](args_and_kwargs.rst) + - [Context managers](context_managers.rst) 3) Functional programming - -- [Enumerate](enumerate.rst) -- [Lambdas](lambdas.rst) -- [``set`` Data Structure](set_-_data_structure.rst) -- [Map & Filter](map_filter.rst) -- [Comprehensions](comprehensions.rst) - + - [Enumerate](enumerate.rst) + - [Lambdas](lambdas.rst) + - [``set`` Data Structure](set_-_data_structure.rst) + - [Map & Filter](map_filter.rst) + - [Comprehensions](comprehensions.rst) 4) Data structures - -- [Generators](generators.rst) -- [Coroutines](coroutines.rst) - + - [Generators](generators.rst) + - [Coroutines](coroutines.rst) 5) Data types - -- [Collections](collections.rst) -- [Mutation](mutation.rst) -- [\_\_slots\_\_ Magic](__slots__magic.rst) - + - [Collections](collections.rst) + - [Mutation](mutation.rst) + - [\_\_slots\_\_ Magic](__slots__magic.rst) 6) Decorators - -- [What is a decorator?](decorators.rst) -- [Function caching](function_caching.rst) - + - [What is a decorator?](decorators.rst) + - [Function caching](function_caching.rst) 7) Extras - -- [One Liners](one_liners.rst) -- [Targeting Python 2+3](targeting_python_2_3.rst) -- [Python C extensions](python_c_extension.rst) + - [One Liners](one_liners.rst) + - [Targeting Python 2+3](targeting_python_2_3.rst) + - [Python C extensions](python_c_extension.rst) Author: ------ From 14f64eee00c326beb4eb4ab596ab9231c80a1743 Mon Sep 17 00:00:00 2001 From: Pavel Karateev Date: Sat, 2 Jun 2018 20:08:19 +0300 Subject: [PATCH 091/152] Add classes to README TOC --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e637e51..043cba4 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ Table of Contents: 4) Data structures - [Generators](generators.rst) - [Coroutines](coroutines.rst) + - [Classes](classes.rst) 5) Data types - [Collections](collections.rst) - [Mutation](mutation.rst) From dc6b3fb828686c036e811d7aeaed231bc4aa58fa Mon Sep 17 00:00:00 2001 From: Nikita Penzin Date: Mon, 4 Jun 2018 18:09:54 +0300 Subject: [PATCH 092/152] Update for_-_else.rst --- for_-_else.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/for_-_else.rst b/for_-_else.rst index f072c03..9a68363 100644 --- a/for_-_else.rst +++ b/for_-_else.rst @@ -34,7 +34,7 @@ The common construct is to run a loop and search for an item. If the item is found, we break out of the loop using the ``break`` statement. There are two scenarios in which the loop may end. The first one is when the item is found and ``break`` is encountered. The second scenario is that the loop -ends without encountering a ``break` statement. Now we may want to know which one of these is the reason for a +ends without encountering a ``break`` statement. Now we may want to know which one of these is the reason for a loop's completion. One method is to set a flag and then check it once the loop ends. Another is to use the ``else`` clause. From 4813c2ec46e3992dcf84462244749b1d3ad8b74d Mon Sep 17 00:00:00 2001 From: Gabriel Date: Wed, 1 Aug 2018 20:49:05 +0300 Subject: [PATCH 093/152] Last __getitem__ example Class name and attribute correction --- classes.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes.rst b/classes.rst index c22aa10..8b0294d 100644 --- a/classes.rst +++ b/classes.rst @@ -200,8 +200,8 @@ Implementing **getitem** in a class allows its instances to use the [] def __getitem__(self,i): return self.info[i] - foo = OldClass() - foo['title'] + foo = GetTest() + foo['name'] # Output: 'Yasoob' foo['number'] From 3cae4cb2de2f6ab0ef09efa78ba26ddf81803cbf Mon Sep 17 00:00:00 2001 From: Gabriel Date: Wed, 1 Aug 2018 20:50:12 +0300 Subject: [PATCH 094/152] Name corrected in error on last __getitem__ code --- classes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes.rst b/classes.rst index 8b0294d..c233fcb 100644 --- a/classes.rst +++ b/classes.rst @@ -211,7 +211,7 @@ Without the ``__getitem__`` method we would have got this error: .. code:: python - >>> foo['title'] + >>> foo['name'] Traceback (most recent call last): File "", line 1, in From a5102f13bbc1dc2cba7bd2b374ea700b89c2b453 Mon Sep 17 00:00:00 2001 From: Ali <3050609+alikoneko@users.noreply.github.com> Date: Thu, 13 Sep 2018 13:05:52 -0400 Subject: [PATCH 095/152] Update to be inclusive (#176) * Update to be inclusive I'm named Ali. I struggle with body image, and have my entire life. Can we at least be nice and refer to a pet and maybe not body image issues. * Update ternary_operators.rst --- ternary_operators.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ternary_operators.rst b/ternary_operators.rst index d4a4e00..1d029ca 100644 --- a/ternary_operators.rst +++ b/ternary_operators.rst @@ -18,8 +18,8 @@ expressions. .. code:: python - is_fat = True - state = "fat" if is_fat else "not fat" + is_nice = True + state = "nice" if is_nice else "not nice" It allows to quickly test a condition instead of a multiline if statement. Often times it can be immensely helpful and can make your @@ -38,10 +38,10 @@ is some sample code: .. code:: python - fat = True - fitness = ("skinny", "fat")[fat] - print("Ali is ", fitness) - # Output: Ali is fat + nice = True + personality = ("mean", "nice")[nice] + print("The cat is ", personality) + # Output: The cat is nice This works simply because True == 1 and False == 0, and so can be done with lists in addition to tuples. From 50f50c6a41ca31ad28ff2565fba0cf7257ec27cd Mon Sep 17 00:00:00 2001 From: Erin Wild Date: Wed, 3 Oct 2018 12:33:22 -0400 Subject: [PATCH 096/152] Fix typos in output of getitem example (#170) --- classes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes.rst b/classes.rst index c233fcb..9163f09 100644 --- a/classes.rst +++ b/classes.rst @@ -205,7 +205,7 @@ Implementing **getitem** in a class allows its instances to use the [] # Output: 'Yasoob' foo['number'] - # Output: 36845124 + # Output: 12345812 Without the ``__getitem__`` method we would have got this error: From 779dd0dabae519828ff3a76277a319179a2fdd00 Mon Sep 17 00:00:00 2001 From: Adel Atallah <2213999+atallahade@users.noreply.github.com> Date: Sun, 28 Oct 2018 20:26:08 +0100 Subject: [PATCH 097/152] Fix minor typo (#177) Fix typo in the "Comprehensions" section. --- comprehensions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/comprehensions.rst b/comprehensions.rst index 2c09aca..fb9df30 100644 --- a/comprehensions.rst +++ b/comprehensions.rst @@ -96,7 +96,7 @@ that they use braces ``{}``. Here is an example: ``generator`` comprehensions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -They are also similar to list comprehensions. The only difference is that they don't allocate memory for the whole list but generate one item at a time, thus more memory effecient. +They are also similar to list comprehensions. The only difference is that they don't allocate memory for the whole list but generate one item at a time, thus more memory efficient. .. code:: python From 19a1942894fe5cae1c01f71e3eed7fe27e6adae4 Mon Sep 17 00:00:00 2001 From: Patrick Hilhorst Date: Sun, 28 Oct 2018 20:28:11 +0100 Subject: [PATCH 098/152] Ask for forgiveness, not for permission (#175) References: - https://docs.python.org/3/glossary.html#term-eafp - https://blogs.msdn.microsoft.com/pythonengineering/2016/06/29/idiomatic-python-eafp-versus-lbyl/ - https://docs.quantifiedcode.com/python-anti-patterns/readability/asking_for_permission_instead_of_forgiveness_when_working_with_files.html - https://jeffknupp.com/blog/2013/02/06/write-cleaner-python-use-exceptions/ --- function_caching.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/function_caching.rst b/function_caching.rst index 7c06149..7100aad 100644 --- a/function_caching.rst +++ b/function_caching.rst @@ -52,9 +52,9 @@ is a generic cache: memo = {} @wraps(function) def wrapper(*args): - if args in memo: + try: return memo[args] - else: + except KeyError: rv = function(*args) memo[args] = rv return rv From e0e55079972771d7749b08c8cb241a9a70c00c46 Mon Sep 17 00:00:00 2001 From: Michele Tonutti Date: Sun, 28 Oct 2018 20:28:47 +0100 Subject: [PATCH 099/152] Update enumerate.rst (#172) It's -> its --- enumerate.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/enumerate.rst b/enumerate.rst index 06719f0..277b679 100644 --- a/enumerate.rst +++ b/enumerate.rst @@ -1,7 +1,7 @@ Enumerate --------- -Enumerate is a built-in function of Python. It's usefulness can not be +Enumerate is a built-in function of Python. Its usefulness can not be summarized in a single line. Yet most of the newcomers and even some advanced programmers are unaware of it. It allows us to loop over something and have an automatic counter. Here is an example: From 512de0bfe7b8c98902fd47bbc9ea71da823223a5 Mon Sep 17 00:00:00 2001 From: Dale Daeyoung Seo Date: Sun, 28 Oct 2018 12:35:49 -0700 Subject: [PATCH 100/152] Fix the class name (#171) * Fix the class name `GetTest` is the right class name. * Updated the output --- classes.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/classes.rst b/classes.rst index 9163f09..9450904 100644 --- a/classes.rst +++ b/classes.rst @@ -201,6 +201,7 @@ Implementing **getitem** in a class allows its instances to use the [] return self.info[i] foo = GetTest() + foo['name'] # Output: 'Yasoob' From 0767511f239da5bb0615edd36f5c05672bb41d46 Mon Sep 17 00:00:00 2001 From: user2552 <34348170+user2552@users.noreply.github.com> Date: Sun, 28 Oct 2018 15:37:02 -0400 Subject: [PATCH 101/152] Update ternary_operators.rst (#169) change is to if to clarify the language --- ternary_operators.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ternary_operators.rst b/ternary_operators.rst index 1d029ca..0a7741e 100644 --- a/ternary_operators.rst +++ b/ternary_operators.rst @@ -12,7 +12,7 @@ expressions. .. code:: python - condition_is_true if condition else condition_is_false + condition_if_true if condition else condition_if_false **Example:** From cdcc71bd06aed33afde75b13399ffed3f10ed62f Mon Sep 17 00:00:00 2001 From: anupy Date: Mon, 29 Oct 2018 01:18:47 +0530 Subject: [PATCH 102/152] Shorthand ternary. (#165) * Shorthand ternary. * Update ternary_operators.rst * Update ternary_operators.rst * Update ternary_operators.rst * Update ternary_operators.rst --- ternary_operators.rst | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/ternary_operators.rst b/ternary_operators.rst index 0a7741e..7544d62 100644 --- a/ternary_operators.rst +++ b/ternary_operators.rst @@ -70,3 +70,34 @@ first built, then an index is found. For the if-else ternary operator, it follows the normal if-else logic tree. Thus, if one case could raise an exception based on the condition, or if either case is a computation-heavy method, using tuples is best avoided. + + +**ShortHand Ternary** + +In python there is also the shorthand ternary tag which is a shorter version of the +normal ternary operator you have seen above. + +Syntax was introduced in Python 2.5 and can be used in python 2.5 or greater. + +**Example** + +.. code:: python + + >>> True or "Some" + True + >>> + >>> False or "Some" + 'Some' + +The first statement (`True or "Some"`) will return `True` and the second statement (`False or "Some"`) will return `False`. + +This is helpful in case where you quickly want to check for the output of a function and give a useful message if the output is empty: + +.. code:: python + + >>> func_output = None + >>> msg = output or "No data returned" + >>> print(msg) + No data returned + + From a813faaffca9af342afc636e70c3ff946c7b6525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Sun, 28 Oct 2018 15:52:36 -0400 Subject: [PATCH 103/152] Update breadcrumbs.html --- _templates/breadcrumbs.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index 6657860..ddcce71 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -28,7 +28,7 @@

    Note

    -

    Hi! I am currently looking for some freelance projects. If you have a project idea in mind please feel free to send me an email or check out my personal website. If you want to get to know about my journey, you can read this article: How I got into programming

    . +

    Hi! I am currently looking for internships for summer 2019. If you work at an amazing company and feel like I would be a good addition to the team, please feel free to send me an email or check out my personal website. If you want to get to know about my journey, you can read this article: How I got into programming

    .
    From dcc0c1d8d87bec639d88277d450e5adb2572045b Mon Sep 17 00:00:00 2001 From: Jakub Pastuszuk Date: Tue, 13 Nov 2018 10:40:13 +0100 Subject: [PATCH 104/152] Update ternary_operators.rst (#179) --- ternary_operators.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ternary_operators.rst b/ternary_operators.rst index 7544d62..1436663 100644 --- a/ternary_operators.rst +++ b/ternary_operators.rst @@ -89,7 +89,7 @@ Syntax was introduced in Python 2.5 and can be used in python 2.5 or greater. >>> False or "Some" 'Some' -The first statement (`True or "Some"`) will return `True` and the second statement (`False or "Some"`) will return `False`. +The first statement (`True or "Some"`) will return `True` and the second statement (`False or "Some"`) will return `Some`. This is helpful in case where you quickly want to check for the output of a function and give a useful message if the output is empty: From 6f01688bce657d69bce112ec543285c5ccf3b125 Mon Sep 17 00:00:00 2001 From: Steven Huang Date: Fri, 16 Nov 2018 13:53:12 -0500 Subject: [PATCH 105/152] Minor wording improvements (#180) --- decorators.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/decorators.rst b/decorators.rst index 7bf2609..64cbc44 100644 --- a/decorators.rst +++ b/decorators.rst @@ -2,8 +2,8 @@ Decorators ---------- Decorators are a significant part of Python. In simple words: they are -functions which modify the functionality of another function. They help -to make our code shorter and more Pythonic. Most of the beginners do not +functions which modify the functionality of other functions. They help +to make our code shorter and more Pythonic. Most beginners do not know where to use them so I am going to share some areas where decorators can make your code more concise. From a6c6f81437b1a4419fce7f51b0e6e31baae9a92e Mon Sep 17 00:00:00 2001 From: Jakub Pastuszuk Date: Fri, 30 Nov 2018 17:04:00 +0100 Subject: [PATCH 106/152] Update classes.rst (#184) Typo fix - I believe it should be immutable here, since example operates on immutable types of class variable and in this case, there is no problem with using class variable --- classes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes.rst b/classes.rst index 9450904..4d45cf2 100644 --- a/classes.rst +++ b/classes.rst @@ -53,7 +53,7 @@ Let's take a look at an example: b.pi # Output: 50 -There are not many issues while using mutable class variables. This is +There are not many issues while using immutable class variables. This is the major reason due to which beginners do not try to learn more about this subject because everything works! If you also believe that instance and class variables can not cause any problem if used incorrectly then From 6d47c66d051b814cf04b378379a4d57ceaf8ba31 Mon Sep 17 00:00:00 2001 From: Jakub Pastuszuk Date: Fri, 30 Nov 2018 17:04:28 +0100 Subject: [PATCH 107/152] Update targeting_python_2_3.rst (#185) Corrected sentence to be more precise - targeting multiple versions of python because users do not use the same version. Currently it translates to: Not all of the users do have python 2 or python 3 (which is semantically incorrect) --- targeting_python_2_3.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targeting_python_2_3.rst b/targeting_python_2_3.rst index 00e08ff..caa0c1e 100644 --- a/targeting_python_2_3.rst +++ b/targeting_python_2_3.rst @@ -5,7 +5,7 @@ In a lot of cases you might want to develop programs which can be run in both Python 2+ and 3+. Just imagine that you have a very popular Python module which is used by -hundreds of people but not all of them have Python 2 or 3. In that case +hundreds of people but not all of them have the same version of Python (2 or 3). In that case you have two choices. The first one is to distribute 2 modules, one for Python 2 and the other for Python 3. The other choice is to modify your current code and make it compatible with both Python 2 and 3. From 49d685b0b263ef61322286a49205ac167cb104cb Mon Sep 17 00:00:00 2001 From: Jakub Pastuszuk Date: Fri, 30 Nov 2018 17:06:02 +0100 Subject: [PATCH 108/152] Update exceptions.rst (#183) It is always better to catch exception and raise it with a detailed information, difference between just raising and raising caught exception. With rising e: .. code:: python Traceback (most recent call last): File "", line 5, in File "", line 2, in FileNotFoundError: [Errno 2] No such file or directory: 'test' Just rising: .. code:: python Traceback (most recent call last): File "", line 2, in FileNotFoundError: [Errno 2] No such file or directory: 'test' --- exceptions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exceptions.rst b/exceptions.rst index 2b29381..d6fae82 100644 --- a/exceptions.rst +++ b/exceptions.rst @@ -56,9 +56,9 @@ trapping ALL exceptions: try: file = open('test.txt', 'rb') - except Exception: + except Exception as e: # Some logging if you want - raise + raise e This can be helpful when you have no idea about the exceptions which may be thrown by your program. From c20b5a8c3f2641390665b96c7225fa43ea3f72e4 Mon Sep 17 00:00:00 2001 From: Jakub Pastuszuk Date: Fri, 30 Nov 2018 17:08:09 +0100 Subject: [PATCH 109/152] Update collections.rst (#182) Provided clear programmatic example of how deque extending does pop values on the other side when maxlen limit is reached --- collections.rst | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/collections.rst b/collections.rst index c09a3bf..fa4debd 100644 --- a/collections.rst +++ b/collections.rst @@ -216,9 +216,15 @@ example so here you go: .. code:: python - d = deque(maxlen=30) + d = deque([0, 1, 2, 3, 5], maxlen=5) + print(d) + # Output: deque([0, 1, 2, 3, 5], maxlen=5) + + d.extend([6]) + print(d) + #Output: deque([1, 2, 3, 5, 6], maxlen=5) -Now whenever you insert values after 30, the leftmost value will be +Now whenever you insert values after 5, the leftmost value will be popped from the list. You can also expand the list in any direction with new values: From b0b664392470f01dd3a487e90f3c7da2103fbdc3 Mon Sep 17 00:00:00 2001 From: Jakub Pastuszuk Date: Fri, 30 Nov 2018 17:08:45 +0100 Subject: [PATCH 110/152] Update collections.rst (#181) Little change to how import is written to make it consistent with rest of examples --- collections.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collections.rst b/collections.rst index fa4debd..af0aa5c 100644 --- a/collections.rst +++ b/collections.rst @@ -68,8 +68,8 @@ share a solution using ``defaultdict``. .. code:: python - import collections - tree = lambda: collections.defaultdict(tree) + from collections import defaultdict + tree = lambda: defaultdict(tree) some_dict = tree() some_dict['colours']['favourite'] = "yellow" # Works fine From e8aa372810b6fdcc12cda39623c386fd2c043ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E8=BE=89?= Date: Sat, 1 Dec 2018 04:55:05 +0800 Subject: [PATCH 111/152] Make sure the function was called (#154) * Make sure the function was called Make sure the function was called. * fix class decorator bugs In class decorator, @decorator will call it once, and put the func into Class(func). So if wrote like this `@logit()`, it will call __call__ function. * Update decorators.rst --- decorators.rst | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/decorators.rst b/decorators.rst index 64cbc44..8e4ded2 100644 --- a/decorators.rst +++ b/decorators.rst @@ -390,18 +390,26 @@ rebuild logit as a class instead of a function. .. code:: python class logit(object): - def __init__(self, logfile='out.log'): - self.logfile = logfile + +        _logfile = 'out.log' +     + def __init__(self, func): + self.func = func - def __call__(self, func): - log_string = func.__name__ + " was called" +        def __call__(self, *args): +            log_string = self.func.__name__ + " was called" print(log_string) # Open the logfile and append - with open(self.logfile, 'a') as opened_file: +            with open(self._logfile, 'a') as opened_file: # Now we log to the specified logfile opened_file.write(log_string + '\n') # Now, send a notification self.notify() + +            # return base func +            return self.func(*args) + +             def notify(self): # logit only logs, no more @@ -412,10 +420,14 @@ the nested function approach, and wrapping a function still will use the same syntax as before: .. code:: python - - @logit() - def myfunc1(): + +    logit._logfile = 'out2.log' # if change log file +    @logit +    def myfunc1(): pass + + myfunc1() + # Output: myfunc1 was called Now, let's subclass logit to add email functionality (though this topic will not be covered here). From 05551b450557708a9e9c10e5aa8dc7ef28a421b5 Mon Sep 17 00:00:00 2001 From: Jakub Pastuszuk Date: Fri, 30 Nov 2018 21:56:55 +0100 Subject: [PATCH 112/152] Update context_managers.rst (#187) Small typo fixed --- context_managers.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/context_managers.rst b/context_managers.rst index 45d6eb4..79d944f 100644 --- a/context_managers.rst +++ b/context_managers.rst @@ -167,7 +167,7 @@ Let's dissect this method a little. 1. Python encounters the ``yield`` keyword. Due to this it creates a generator instead of a normal function. 2. Due to the decoration, contextmanager is called with the function - name (``open\_file``) as it's argument. + name (``open_file``) as it's argument. 3. The ``contextmanager`` decorator returns the generator wrapped by the ``GeneratorContextManager`` object. 4. The ``GeneratorContextManager`` is assigned to the ``open_file`` @@ -180,4 +180,4 @@ Manager like this: .. code:: python with open_file('some_file') as f: - f.write('hola!') \ No newline at end of file + f.write('hola!') From b25d0bfbd6a149de5886528d7fa8b1ffea56406b Mon Sep 17 00:00:00 2001 From: Nikita Shchypylov Date: Wed, 26 Dec 2018 21:12:32 +0200 Subject: [PATCH 113/152] Wrong variable name for shorthand ternary example (#188) --- ternary_operators.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ternary_operators.rst b/ternary_operators.rst index 1436663..7e7dec2 100644 --- a/ternary_operators.rst +++ b/ternary_operators.rst @@ -95,7 +95,7 @@ This is helpful in case where you quickly want to check for the output of a func .. code:: python - >>> func_output = None + >>> output = None >>> msg = output or "No data returned" >>> print(msg) No data returned From 77bd8327b86b5fe81f5c2713d35315d9c429f762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Fri, 4 Jan 2019 23:46:18 -0500 Subject: [PATCH 114/152] Update breadcrumbs.html --- _templates/breadcrumbs.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index ddcce71..12b4e37 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -28,7 +28,7 @@

    Note

    -

    Hi! I am currently looking for internships for summer 2019. If you work at an amazing company and feel like I would be a good addition to the team, please feel free to send me an email or check out my personal website. If you want to get to know about my journey, you can read this article: How I got into programming

    . +

    Hi! My name is Yasoob. I am the author of this book. Thank you so much to everyone who reached out with internship opportunities. I have accepted an offer and will be working in NYC in summer 2019. If you want to get to know about my journey and connect with me, you can read this article: How I got into programming

    .
    From 89af69642aef0b4dcbdedc61dff0747a0b1e27fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Fri, 4 Jan 2019 23:48:39 -0500 Subject: [PATCH 115/152] Update breadcrumbs.html --- _templates/breadcrumbs.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index 12b4e37..107905b 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -28,7 +28,7 @@

    Note

    -

    Hi! My name is Yasoob. I am the author of this book. Thank you so much to everyone who reached out with internship opportunities. I have accepted an offer and will be working in NYC in summer 2019. If you want to get to know about my journey and connect with me, you can read this article: How I got into programming

    . +

    Hi! My name is Yasoob. I am the author of this book. Thank you so much to everyone who reached out with internship opportunities. I have accepted an offer and will be working in NYC in summer 2019. If you want to get to know about my journey and connect with me, you can check out my personal website and/or read this article: How I got into programming.

    From 258f05d949528b7b233b7d06bf6f095c96137c63 Mon Sep 17 00:00:00 2001 From: hasslerb Date: Sat, 19 Jan 2019 17:18:51 -0600 Subject: [PATCH 116/152] Update comprehensions.rst (#189) Once generator types were added, the number of types of comprehensions was no longer three --- comprehensions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/comprehensions.rst b/comprehensions.rst index fb9df30..1db2a61 100644 --- a/comprehensions.rst +++ b/comprehensions.rst @@ -3,7 +3,7 @@ Comprehensions Comprehensions are a feature of Python which I would really miss if I ever have to leave it. Comprehensions are constructs that allow -sequences to be built from other sequences. Three types of +sequences to be built from other sequences. Several types of comprehensions are supported in both Python 2 and Python 3: - list comprehensions From 4c1d5af82b1458772e200794606b1847c966b551 Mon Sep 17 00:00:00 2001 From: yasoob Date: Sat, 2 Mar 2019 18:47:00 -0500 Subject: [PATCH 117/152] updated notes --- _templates/breadcrumbs.html | 2 +- index.rst | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index 107905b..4dffaf8 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -28,7 +28,7 @@

    Note

    -

    Hi! My name is Yasoob. I am the author of this book. Thank you so much to everyone who reached out with internship opportunities. I have accepted an offer and will be working in NYC in summer 2019. If you want to get to know about my journey and connect with me, you can check out my personal website and/or read this article: How I got into programming.

    +

    Hi! My name is Yasoob. I am the author of this book. If you want to get to know about my journey and connect with me, you can check out my personal website and/or read this article: How I got into programming. If you like what you are reading please consider donating. It takes time to produce quality content and donations keep me motivated 😊

    diff --git a/index.rst b/index.rst index 23cb3c5..224ae75 100644 --- a/index.rst +++ b/index.rst @@ -2,9 +2,7 @@ .. note:: - You can donate me for my hardwork if you want to by buying the donation version of Intermediate Python from `Gumroad `__. Your help would be greatly appreciated! - - You can also sign up to my `mailing list `__ so that you remain in sync with any major updates to this book or my future projects! + You can sign up to my `mailing list `__ so that you remain in sync with any major updates to this book or my future projects! Intermediate Python =================== From ad3314aa63193465b449344596d067a32ae269d6 Mon Sep 17 00:00:00 2001 From: yasoob Date: Sun, 3 Mar 2019 01:58:41 -0500 Subject: [PATCH 118/152] fixed a link --- _templates/breadcrumbs.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index 4dffaf8..6455763 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -28,7 +28,7 @@

    Note

    -

    Hi! My name is Yasoob. I am the author of this book. If you want to get to know about my journey and connect with me, you can check out my personal website and/or read this article: How I got into programming. If you like what you are reading please consider donating. It takes time to produce quality content and donations keep me motivated 😊

    +

    Hi! My name is Yasoob. I am the author of this book. If you want to get to know about my journey and connect with me, you can check out my personal website and/or read this article: How I got into programming. If you like what you are reading please consider donating. It takes time to produce quality content and donations keep me motivated 😊

    From 857b59da3c6ddb5af4626585475ac95a9e72fd88 Mon Sep 17 00:00:00 2001 From: yasoob Date: Thu, 9 May 2019 00:31:10 -0400 Subject: [PATCH 119/152] added link to nyc post --- _templates/breadcrumbs.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index 6455763..56b391a 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -28,7 +28,7 @@

    Note

    -

    Hi! My name is Yasoob. I am the author of this book. If you want to get to know about my journey and connect with me, you can check out my personal website and/or read this article: How I got into programming. If you like what you are reading please consider donating. It takes time to produce quality content and donations keep me motivated 😊

    +

    Hi! My name is Yasoob. I am the author of this book. A couple of months ago I asked you guys for help with finding an internship. You all came through. Now I need your help again. If you are from NYC please read this article and help me find a place to stay in the city. My host backed out at the last minute.

    From e4e35ff01ff418c28f3a2bbac4cdf1ea139546e8 Mon Sep 17 00:00:00 2001 From: yasoob Date: Thu, 9 May 2019 01:19:15 -0400 Subject: [PATCH 120/152] added bitly link --- _templates/breadcrumbs.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index 56b391a..4b1500e 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -28,7 +28,7 @@

    Note

    -

    Hi! My name is Yasoob. I am the author of this book. A couple of months ago I asked you guys for help with finding an internship. You all came through. Now I need your help again. If you are from NYC please read this article and help me find a place to stay in the city. My host backed out at the last minute.

    +

    Hi! My name is Yasoob. I am the author of this book. A couple of months ago I asked you guys for help with finding an internship. You all came through. Now I need your help again. If you are from NYC please read this article and help me find a place to stay in the city. My host backed out at the last minute.

    From c47a29d3ce9b3490327afdd399bc8debf770f3de Mon Sep 17 00:00:00 2001 From: Yasoob Date: Mon, 8 Jul 2019 12:55:20 -0400 Subject: [PATCH 121/152] removed sublet info --- _templates/breadcrumbs.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index 4b1500e..4992447 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -28,7 +28,7 @@

    Note

    -

    Hi! My name is Yasoob. I am the author of this book. A couple of months ago I asked you guys for help with finding an internship. You all came through. Now I need your help again. If you are from NYC please read this article and help me find a place to stay in the city. My host backed out at the last minute.

    +

    Hi! My name is Yasoob. I am the author of this book. I regularly write Python posts on Python Tips. Everything else finds its way to my personal blog. I would love it if you can give them a read. I also announce my new projects there :)

    From 8c1195efe878eea0877825c863d6c22ac8fa6b57 Mon Sep 17 00:00:00 2001 From: Ruud de Jong Date: Tue, 10 Sep 2019 11:09:15 +0200 Subject: [PATCH 122/152] Grammar fixes (#197) Added and removed some words. --- decorators.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/decorators.rst b/decorators.rst index 8e4ded2..1b83032 100644 --- a/decorators.rst +++ b/decorators.rst @@ -176,8 +176,8 @@ previous decorator and make a little bit more usable program: Did you get it? We just applied the previously learned principles. This is exactly what the decorators do in Python! They wrap a function and -modify its behaviour in one way or the another. Now you might be -wondering that we did not use the @ anywhere in our code? That is just a +modify its behaviour in one way or another. Now you might be +wondering why we did not use the @ anywhere in our code? That is just a short way of making up a decorated function. Here is how we could have run the previous code sample using @. @@ -206,9 +206,9 @@ Python. Now there is one problem with our code. If we run: # Output: wrapTheFunction That's not what we expected! Its name is -"a\_function\_requiring\_decoration". Well our function was replaced by +"a\_function\_requiring\_decoration". Well, our function was replaced by wrapTheFunction. It overrode the name and docstring of our function. -Luckily Python provides us a simple function to solve this problem and +Luckily, Python provides us a simple function to solve this problem and that is ``functools.wraps``. Let's modify our previous example to use ``functools.wraps``: @@ -263,7 +263,7 @@ decorators. Note: ``@wraps`` takes a function to be decorated and adds the functionality of copying over the function name, docstring, arguments -list, etc. This allows to access the pre-decorated function's properties +list, etc. This allows us to access the pre-decorated function's properties in the decorator. Use-cases: From 9b4892521556c7735bf4a5fca553723965de2a67 Mon Sep 17 00:00:00 2001 From: yasoob Date: Tue, 17 Sep 2019 22:34:30 +0200 Subject: [PATCH 123/152] updated link to internship search 2020 --- _templates/breadcrumbs.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index 4992447..7ab55d2 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -28,8 +28,7 @@

    Note

    -

    Hi! My name is Yasoob. I am the author of this book. I regularly write Python posts on Python Tips. Everything else finds its way to my personal blog. I would love it if you can give them a read. I also announce my new projects there :)

    - +

    Hi! My name is Yasoob. I am the author of this book. Last year you guys helped me find an internship. I am asking for your help again to find an amazing internship for summer 2020. Please read this article to find the details. Thanks! ♥️

      From f272f5bb762f69971cb22da9090feebe480e332e Mon Sep 17 00:00:00 2001 From: yasoob Date: Tue, 17 Sep 2019 22:54:32 +0200 Subject: [PATCH 124/152] added bitly url --- _templates/breadcrumbs.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index 7ab55d2..daae4c7 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -28,7 +28,7 @@

      Note

      -

      Hi! My name is Yasoob. I am the author of this book. Last year you guys helped me find an internship. I am asking for your help again to find an amazing internship for summer 2020. Please read this article to find the details. Thanks! ♥️

      +

      Hi! My name is Yasoob. I am the author of this book. Last year you guys helped me find an internship. I am asking for your help again to find an amazing internship for summer 2020. Please read this article to find the details. Thanks! ♥️

        From aa4543c7fd6eb71a8b1059ee4d2b19a2767a981a Mon Sep 17 00:00:00 2001 From: yasoob Date: Tue, 17 Sep 2019 23:38:10 +0200 Subject: [PATCH 125/152] changed the breadcrumb text slightly --- _templates/breadcrumbs.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index daae4c7..952fb30 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -28,7 +28,7 @@

        Note

        -

        Hi! My name is Yasoob. I am the author of this book. Last year you guys helped me find an internship. I am asking for your help again to find an amazing internship for summer 2020. Please read this article to find the details. Thanks! ♥️

        +

        Hi! My name is Yasoob. I am the author of this book. Last year you guys helped me find an internship. I am asking for your help again to find an amazing internship for summer 2020. If you work at an amazing company and can help me, please read this article to find the details. Thanks!

          From 5a4f9743f7631f3873c890f51cc7f183cab50926 Mon Sep 17 00:00:00 2001 From: Jonathan Dayton Date: Sat, 19 Oct 2019 10:54:19 -0500 Subject: [PATCH 126/152] Add missing period (#199) --- decorators.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decorators.rst b/decorators.rst index 1b83032..40f53ac 100644 --- a/decorators.rst +++ b/decorators.rst @@ -329,7 +329,7 @@ Come to think of it, isn't ``@wraps`` also a decorator? But, it takes an argument like any normal function can do. So, why can't we do that too? This is because when you use the ``@my_decorator`` syntax, you are -applying a wrapper function with a single function as a parameter +applying a wrapper function with a single function as a parameter. Remember, everything in Python is an object, and this includes functions! With that in mind, we can write a function that returns a wrapper function. From f2159f79981d5831a6f24eb26d7ac9abae94e296 Mon Sep 17 00:00:00 2001 From: Floris Lambrechts Date: Sat, 19 Oct 2019 17:56:38 +0200 Subject: [PATCH 127/152] Improve wording in paragraph about StopIteration (#196) "wondering that why" does not sound fluid. Also, using the word 'while' in a sentence about a `for` loop may be confusing. --- generators.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/generators.rst b/generators.rst index dd983c3..23cd1b0 100644 --- a/generators.rst +++ b/generators.rst @@ -134,10 +134,10 @@ element of a sequence. So let's test out our understanding: As we can see that after yielding all the values ``next()`` caused a ``StopIteration`` error. Basically this error informs us that all the -values have been yielded. You might be wondering that why don't we get -this error while using a ``for`` loop? Well the answer is simple. The +values have been yielded. You might be wondering why we don't get +this error when using a ``for`` loop? Well the answer is simple. The ``for`` loop automatically catches this error and stops calling -``next``. Do you know that a few built-in data types in Python also +``next``. Did you know that a few built-in data types in Python also support iteration? Let's check it out: .. code:: python From a8834dec1ec4d8602cd94bfb4e32fce236a471c9 Mon Sep 17 00:00:00 2001 From: Libbey Date: Sat, 19 Oct 2019 09:58:05 -0600 Subject: [PATCH 128/152] Add func call to Nesting a Decorator Within a Function (#192) 'Nesting a Decorator Within a Function' code does not ever actually call the func, so this commit adds execution and returns the wrapped function result when tagged with decorator. --- decorators.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/decorators.rst b/decorators.rst index 40f53ac..3389728 100644 --- a/decorators.rst +++ b/decorators.rst @@ -354,6 +354,7 @@ us specify a logfile to output to. with open(logfile, 'a') as opened_file: # Now we log to the specified logfile opened_file.write(log_string + '\n') + return func(*args, **kwargs) return wrapped_function return logging_decorator From a61e0c9b80acde5a83f3165ffac8d8ae42827a16 Mon Sep 17 00:00:00 2001 From: Chandler Zuo Date: Sat, 19 Oct 2019 11:58:51 -0400 Subject: [PATCH 129/152] Fix the contextmanager example (#190) See https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager --- context_managers.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/context_managers.rst b/context_managers.rst index 79d944f..fcff411 100644 --- a/context_managers.rst +++ b/context_managers.rst @@ -153,8 +153,10 @@ Let's see a basic, useless example: @contextmanager def open_file(name): f = open(name, 'w') - yield f - f.close() + try: + yield f + finally: + f.close() Okay! This way of implementing Context Managers appear to be more intuitive and easy. However, this method requires some knowledge about From 4a7296b6cc8a6b6387191ec84a2565a7ac6e0b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Sat, 19 Oct 2019 18:06:46 +0200 Subject: [PATCH 130/152] added breakpoint. closes #195 (#200) --- debugging.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/debugging.rst b/debugging.rst index 58af25a..678d690 100644 --- a/debugging.rst +++ b/debugging.rst @@ -58,3 +58,7 @@ function. These are just a few commands. ``pdb`` also supports post mortem. It is also a really handy function. I would highly suggest you to look at the official documentation and learn more about it. + +**Note:** + +It might seem unintuitive to use `pdb.set_trace()` if you are new to this. Fortunately, if you are using Python 3.7+ then you can simply use the `breakpoint()` [built-in function](https://docs.python.org/3/library/functions.html#breakpoint). It automatically imports `pdb` and calls `pdb.set_trace()`. \ No newline at end of file From e5fbf503b75c0881a309bd26dc7e40a3ed77c2d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Tue, 19 May 2020 17:48:13 -0400 Subject: [PATCH 131/152] Got the internship <3 --- _templates/breadcrumbs.html | 5 ----- 1 file changed, 5 deletions(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index 952fb30..a988ecd 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -26,11 +26,6 @@
          -
          -

          Note

          -

          Hi! My name is Yasoob. I am the author of this book. Last year you guys helped me find an internship. I am asking for your help again to find an amazing internship for summer 2020. If you work at an amazing company and can help me, please read this article to find the details. Thanks!

          -
          -
            {% block breadcrumbs %}
          • {{ _('Docs') }} »
          • From 42577eec02e7a356bb923c6980f819248526660a Mon Sep 17 00:00:00 2001 From: Kasonnara Date: Wed, 20 May 2020 08:25:36 +0200 Subject: [PATCH 132/152] Add additional example to ShortHand Ternary (#205) Add a more common use case (in my experience) of 'None or something' --- ternary_operators.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ternary_operators.rst b/ternary_operators.rst index 7e7dec2..18b35c6 100644 --- a/ternary_operators.rst +++ b/ternary_operators.rst @@ -100,4 +100,14 @@ This is helpful in case where you quickly want to check for the output of a func >>> print(msg) No data returned +Or as a simple way to define function parameters with dynamic default values: +.. code:: python + + >>> def my_function(real_name, optional_display_name=None): + >>> optional_display_name = optional_display_name or real_name + >>> print(optional_display_name) + >>> my_function("John") + John + >>> my_function("Mike", "anonymous123") + anonymous123 From 69d90864f9080e8771abe56874886bde2dfd2cd0 Mon Sep 17 00:00:00 2001 From: Mike Morearty Date: Tue, 19 May 2020 23:25:58 -0700 Subject: [PATCH 133/152] Grammar: Change "it's" to "its" in some places (#203) * Use "it's" for "it is" * Use "its" for the possessive --- classes.rst | 2 +- context_managers.rst | 2 +- python_c_extension.rst | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/classes.rst b/classes.rst index 4d45cf2..9485307 100644 --- a/classes.rst +++ b/classes.rst @@ -159,7 +159,7 @@ its ``__init__`` method is called. For example: # called You can see that ``__init__`` is called immediately after an instance is -created. You can also pass arguments to the class during it's +created. You can also pass arguments to the class during its initialization. Like this: .. code:: python diff --git a/context_managers.rst b/context_managers.rst index fcff411..5a0f9d0 100644 --- a/context_managers.rst +++ b/context_managers.rst @@ -169,7 +169,7 @@ Let's dissect this method a little. 1. Python encounters the ``yield`` keyword. Due to this it creates a generator instead of a normal function. 2. Due to the decoration, contextmanager is called with the function - name (``open_file``) as it's argument. + name (``open_file``) as its argument. 3. The ``contextmanager`` decorator returns the generator wrapped by the ``GeneratorContextManager`` object. 4. The ``GeneratorContextManager`` is assigned to the ``open_file`` diff --git a/python_c_extension.rst b/python_c_extension.rst index 368d60b..5f49c3b 100644 --- a/python_c_extension.rst +++ b/python_c_extension.rst @@ -6,7 +6,7 @@ implementation is the ease of interfacing C code to Python. There are three key methods developers use to call C functions from their python code - ``ctypes``, ``SWIG`` and ``Python/C API``. Each -method comes with it's own merits and demerits. +method comes with its own merits and demerits. Firstly, why would you want to interface C with Python? @@ -194,7 +194,7 @@ Python/C API --------------- The `C/Python API `__ is probably the -most widely used method - not for it's simplicity but for the fact that +most widely used method - not for its simplicity but for the fact that you can manipulate python objects in your C code. This method requires your C code to be specifically written for @@ -229,7 +229,7 @@ the addList module is not written in Python at all, but rather in C. Next we'll have a look at the C code that get's built into the ``addList`` Python module. This may seem a bit daunting at first, but once you understand the various components that go into writing the C -file, it's pretty straight forward. +file, it's pretty straightforward. *adder.c* From d26d4b5dc7886cfa0715de9bf0ec8be567f7860e Mon Sep 17 00:00:00 2001 From: Alex Loftus Date: Wed, 20 May 2020 02:26:46 -0400 Subject: [PATCH 134/152] Update debugging.rst (#201) grammar fixes --- debugging.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/debugging.rst b/debugging.rst index 678d690..5e591f8 100644 --- a/debugging.rst +++ b/debugging.rst @@ -2,14 +2,14 @@ Debugging --------- Debugging is also something which once mastered can greatly enhance your -bug hunting skills. Most of the newcomers neglect the importance of the +bug hunting skills. Most newcomers neglect the importance of the Python debugger (``pdb``). In this section I am going to tell you only a few important commands. You can learn more about it from the official documentation. -**Running from commandline** +**Running from the command line** -You can run a script from the commandline using the Python debugger. +You can run a script from the command line using the Python debugger. Here is an example: .. code:: python @@ -61,4 +61,4 @@ official documentation and learn more about it. **Note:** -It might seem unintuitive to use `pdb.set_trace()` if you are new to this. Fortunately, if you are using Python 3.7+ then you can simply use the `breakpoint()` [built-in function](https://docs.python.org/3/library/functions.html#breakpoint). It automatically imports `pdb` and calls `pdb.set_trace()`. \ No newline at end of file +It might seem unintuitive to use `pdb.set_trace()` if you are new to this. Fortunately, if you are using Python 3.7+ then you can simply use the `breakpoint()` [built-in function](https://docs.python.org/3/library/functions.html#breakpoint). It automatically imports `pdb` and calls `pdb.set_trace()`. From 490477d93df85fbd5b3c739bc00d09a6e432f51e Mon Sep 17 00:00:00 2001 From: Jason Chen <33189757+LeChn@users.noreply.github.com> Date: Mon, 1 Jun 2020 14:10:11 -0400 Subject: [PATCH 135/152] capitalization correction for Counter title (#206) * Update collections.rst * parallel sorting bug fix Python 3 zip object no longer supports .sort() AttributeError: 'zip' object has no attribute 'sort' Changed to sorted to be forward compatible --- collections.rst | 4 ++-- lambdas.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/collections.rst b/collections.rst index af0aa5c..f668ca6 100644 --- a/collections.rst +++ b/collections.rst @@ -9,7 +9,7 @@ The ones which we will talk about are: - ``defaultdict`` - ``OrderedDict`` -- ``counter`` +- ``Counter`` - ``deque`` - ``namedtuple`` - ``enum.Enum`` (outside of the module; Python 3.4+) @@ -119,7 +119,7 @@ the end of the dictionary. # Blue 160 # Insertion order is preserved -``counter`` +``Counter`` ^^^^^^^^^^^^^^^ Counter allows us to count the occurrences of a particular item. For diff --git a/lambdas.rst b/lambdas.rst index 73328b8..756e260 100644 --- a/lambdas.rst +++ b/lambdas.rst @@ -39,5 +39,5 @@ they are used in the wild: .. code:: python data = zip(list1, list2) - data.sort() + data = sorted(data) list1, list2 = map(lambda t: list(t), zip(*data)) From 05af1fb7b09d978b9ef96e0e1e01a24ad75e4b34 Mon Sep 17 00:00:00 2001 From: "cursospython.com" <65613862+cursospython@users.noreply.github.com> Date: Thu, 4 Jun 2020 20:36:21 +0200 Subject: [PATCH 136/152] Added link to Spanish translation (#207) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 043cba4..b4205fe 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ If you want to translate this book in any other language then kindly let [me kno - [Russian](https://github.com/lancelote/interpy-ru) - [Korean](https://github.com/DDanggle/interpy-kr) - [Portuguese](https://github.com/joanasouza/intermediatePython) +- [Spanish](https://github.com/cursospython/LibroPython) License: ------- From 5360f3327b7e3998bd27586e58a2534618acef8e Mon Sep 17 00:00:00 2001 From: yasoob Date: Sat, 6 Jun 2020 08:30:52 -0400 Subject: [PATCH 137/152] setting up custom privacy conscious analytics service --- _templates/breadcrumbs.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index a988ecd..a110d90 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -80,3 +80,5 @@ {% endif %}
          + + From 6d28d4f4e5d02811f29f6ae99a6d2d71d4e3874e Mon Sep 17 00:00:00 2001 From: Pablo Navarro Date: Tue, 9 Jun 2020 15:06:12 -0700 Subject: [PATCH 138/152] Update ternary_operators.rst (#208) Fix the blueprint for the ternary operator --- ternary_operators.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ternary_operators.rst b/ternary_operators.rst index 18b35c6..6f9cbbc 100644 --- a/ternary_operators.rst +++ b/ternary_operators.rst @@ -12,7 +12,7 @@ expressions. .. code:: python - condition_if_true if condition else condition_if_false + value_if_true if condition else value_if_false **Example:** From 6ed9f4542e2ec28343ac21932132c322f3af400a Mon Sep 17 00:00:00 2001 From: Yasoob Date: Thu, 11 Jun 2020 16:14:39 -0400 Subject: [PATCH 139/152] removed shynet. Too many fake views --- _templates/breadcrumbs.html | 2 -- 1 file changed, 2 deletions(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index a110d90..a988ecd 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -80,5 +80,3 @@ {% endif %}
- - From 23f165f7fcb0c28c8dffc94b18b79a9611b122bc Mon Sep 17 00:00:00 2001 From: Yasoob Date: Thu, 11 Jun 2020 16:26:20 -0400 Subject: [PATCH 140/152] maybe plausible analytics works better? --- _templates/breadcrumbs.html | 1 + 1 file changed, 1 insertion(+) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index a988ecd..247493d 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -79,4 +79,5 @@ {% endif %}
+ From e7bbb9bbe26cc9076bdb5201c1c5c5f338b70479 Mon Sep 17 00:00:00 2001 From: Steven Xu <30362574+stevestar888@users.noreply.github.com> Date: Tue, 16 Jun 2020 23:51:48 -0400 Subject: [PATCH 141/152] grammar: add an apostrophe (#209) --- args_and_kwargs.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/args_and_kwargs.rst b/args_and_kwargs.rst index 544742e..34b4758 100644 --- a/args_and_kwargs.rst +++ b/args_and_kwargs.rst @@ -6,7 +6,7 @@ figuring out the \*args and \*\*kwargs magic variables. So what are they ? First of all let me tell you that it is not necessary to write \*args or \*\*kwargs. Only the ``*`` (asterisk) is necessary. You could have also written \*var and \*\*vars. Writing \*args and \*\*kwargs is just a -convention. So now lets take a look at \*args first. +convention. So now let's take a look at \*args first. Usage of \*args ^^^^^^^^^^^^^^^ From a4d1ec1b1a2c979ca71fdff9ab50cb4fb48d1bfc Mon Sep 17 00:00:00 2001 From: Steven Xu <30362574+stevestar888@users.noreply.github.com> Date: Sat, 4 Jul 2020 20:08:37 -0400 Subject: [PATCH 142/152] add output for first example (#211) --- enumerate.rst | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/enumerate.rst b/enumerate.rst index 277b679..e765ed5 100644 --- a/enumerate.rst +++ b/enumerate.rst @@ -7,12 +7,19 @@ advanced programmers are unaware of it. It allows us to loop over something and have an automatic counter. Here is an example: .. code:: python + + my_list = ['apple', 'banana', 'grapes', 'pear'] + for counter, value in enumerate(my_list): + print counter, value - for counter, value in enumerate(some_list): - print(counter, value) + # Output: + # 0 apple + # 1 banana + # 2 grapes + # 3 pear -And there is more! ``enumerate`` also accepts an optional argument which -makes it even more useful. +And there is more! ``enumerate`` also accepts an optional argument that +allows us to specify the starting index of the counter. .. code:: python @@ -26,9 +33,9 @@ makes it even more useful. # 3 grapes # 4 pear -The optional argument allows us to tell ``enumerate`` from where to -start the index. You can also create tuples containing the index and -list item using a list. Here is an example: +An example of where the optional argument of ``enumerate``comes in handy +is creating tuples containing the index and list item using a list. Here +is an example: .. code:: python From 1593256bcd5b4d0f7ced67460b2906475a2fc31f Mon Sep 17 00:00:00 2001 From: Steven Xu <30362574+stevestar888@users.noreply.github.com> Date: Fri, 10 Jul 2020 13:55:59 -0400 Subject: [PATCH 143/152] make exception execution more specific (#212) --- exceptions.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/exceptions.rst b/exceptions.rst index d6fae82..abdb571 100644 --- a/exceptions.rst +++ b/exceptions.rst @@ -5,9 +5,11 @@ Exception handling is an art which once you master grants you immense powers. I am going to show you some of the ways in which we can handle exceptions. -In basic terminology we are aware of ``try/except`` clause. The code -which can cause an exception to occur is put in the ``try`` block and +In basic terminology we are aware of the ``try/except`` structure. The code +that can cause an exception to occur is put in the ``try`` block and the handling of the exception is implemented in the ``except`` block. +The code in the ``except`` block will only execute if the ``try`` block +runs into an exception. Here is a simple example: .. code:: python From 7ca139de480aaee0fedb8df3e3a533b7ded37eb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Sat, 11 Jul 2020 14:24:46 -0400 Subject: [PATCH 144/152] Removed Plausible --- _templates/breadcrumbs.html | 1 - 1 file changed, 1 deletion(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index 247493d..a988ecd 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -79,5 +79,4 @@ {% endif %}
- From 2002172addd3cdf3be5b39514783b3a617b2de50 Mon Sep 17 00:00:00 2001 From: oliverkoo Date: Wed, 15 Jul 2020 14:40:21 -0400 Subject: [PATCH 145/152] Update enumerate.rst (#214) add missing space --- enumerate.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/enumerate.rst b/enumerate.rst index e765ed5..3bcd2f6 100644 --- a/enumerate.rst +++ b/enumerate.rst @@ -33,7 +33,7 @@ allows us to specify the starting index of the counter. # 3 grapes # 4 pear -An example of where the optional argument of ``enumerate``comes in handy +An example of where the optional argument of ``enumerate`` comes in handy is creating tuples containing the index and list item using a list. Here is an example: From 42fec672382bc4e05d81559f6031671b1e617dee Mon Sep 17 00:00:00 2001 From: Steven Xu <30362574+stevestar888@users.noreply.github.com> Date: Mon, 20 Jul 2020 19:43:13 -0400 Subject: [PATCH 146/152] changed wording on *args (#210) * changed wording * Update args_and_kwargs.rst --- args_and_kwargs.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/args_and_kwargs.rst b/args_and_kwargs.rst index 34b4758..85ed174 100644 --- a/args_and_kwargs.rst +++ b/args_and_kwargs.rst @@ -3,7 +3,7 @@ I have come to see that most new python programmers have a hard time figuring out the \*args and \*\*kwargs magic variables. So what are they -? First of all let me tell you that it is not necessary to write \*args +? First of all, let me tell you that it is not necessary to write \*args or \*\*kwargs. Only the ``*`` (asterisk) is necessary. You could have also written \*var and \*\*vars. Writing \*args and \*\*kwargs is just a convention. So now let's take a look at \*args first. @@ -12,12 +12,11 @@ Usage of \*args ^^^^^^^^^^^^^^^ \*args and \*\*kwargs are mostly used in function definitions. \*args -and \*\*kwargs allow you to pass a variable number of arguments to a -function. What variable means here is that you do not know beforehand -how many arguments can be passed to your function by the user -so in this case you use these two keywords. \*args is used to send a -**non-keyworded** variable length argument list to the function. Here's -an example to help you get a clear idea: +and \*\*kwargs allow you to pass an unspecified number of arguments to a +function, so when writing the function definition, you do not need to +know how many arguments will be passed to your function. \*args is used to +send a **non-keyworded** variable length argument list to the function. +Here's an example to help you get a clear idea: .. code:: python From 219193a04c9d3fa52a5926467776c4ec47a5e204 Mon Sep 17 00:00:00 2001 From: Steven Xu <30362574+stevestar888@users.noreply.github.com> Date: Mon, 20 Jul 2020 19:44:07 -0400 Subject: [PATCH 147/152] add details about catching all exceptions (#213) * add details about catching all exceptions * Small grammar/wording changes --- exceptions.rst | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/exceptions.rst b/exceptions.rst index abdb571..ebeb0d5 100644 --- a/exceptions.rst +++ b/exceptions.rst @@ -62,8 +62,16 @@ trapping ALL exceptions: # Some logging if you want raise e -This can be helpful when you have no idea about the exceptions which may -be thrown by your program. +This can be helpful when you have no idea about the exceptions that may +be thrown by your program. If you are just looking to catch all execptions, +but don't actually care about what they are, you can even exclude the +``Exception as e`` part. + +Note:: catching all exceptions may have unintended consequences because catching +all exceptions may also catch the ones you want to occur; for example, in +many command-line based programs, pressing control+c will terminate the program, +but if you catch all excepts, the ``KeyboardInterrupt`` will be caught as an +exception, so pressing control+c will NOT terminate the program. ``finally`` clause ~~~~~~~~~~~~~~~~~~ From a5c450968b100561d3ce411463161f101982af61 Mon Sep 17 00:00:00 2001 From: Jordan Bonecutter <34787245+jordan-bonecutter@users.noreply.github.com> Date: Sun, 16 Aug 2020 20:33:46 -0700 Subject: [PATCH 148/152] Unnecessary #include statement (#216) No stdio functions were used in this file. --- python_c_extension.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/python_c_extension.rst b/python_c_extension.rst index 5f49c3b..f4cf5d4 100644 --- a/python_c_extension.rst +++ b/python_c_extension.rst @@ -36,8 +36,6 @@ Simple C code to add two numbers, save it as ``add.c`` //sample C file to add 2 numbers - int and floats - #include - int add_int(int, int); float add_float(float, float); From 13764ad2b2e848495b567910770e7a25dd72ea92 Mon Sep 17 00:00:00 2001 From: Yasoob Khalid Date: Thu, 20 Aug 2020 01:11:21 -0400 Subject: [PATCH 149/152] new book released --- _templates/breadcrumbs.html | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/_templates/breadcrumbs.html b/_templates/breadcrumbs.html index a988ecd..f3f3b94 100644 --- a/_templates/breadcrumbs.html +++ b/_templates/breadcrumbs.html @@ -25,7 +25,14 @@ {% endif %}
- +
+

New book released!

+

Hi! I just released the alpha version of my new book; Practical Python Projects. + Learn more about it + on my blog. In 325+ pages, I will teach you how to implement 12 end-to-end projects. + You can buy it from Feldroy.com. +

+
    {% block breadcrumbs %}
  • {{ _('Docs') }} »
  • From 0bc5da8d01ddfc766297e82dd106ff3549eac67c Mon Sep 17 00:00:00 2001 From: John <66183716+just-linux@users.noreply.github.com> Date: Mon, 14 Sep 2020 15:40:24 -0500 Subject: [PATCH 150/152] Correct minor underline build complaints (#219) * Correct minor underline build complaints * Correct minor underline build complaints, additional file --- context_managers.rst | 2 +- decorators.rst | 4 ++-- for_-_else.rst | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/context_managers.rst b/context_managers.rst index 5a0f9d0..261ebd6 100644 --- a/context_managers.rst +++ b/context_managers.rst @@ -36,7 +36,7 @@ Let's see how we can implement our own Context Manager. This should allow us to understand exactly what's going on behind the scenes. Implementing a Context Manager as a Class: -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ At the very least a context manager has an ``__enter__`` and ``__exit__`` method defined. Let's make our own file-opening Context diff --git a/decorators.rst b/decorators.rst index 3389728..30509fe 100644 --- a/decorators.rst +++ b/decorators.rst @@ -273,7 +273,7 @@ Now let's take a look at the areas where decorators really shine and their usage makes something really easy to manage. Authorization -~~~~~~~~~~~~ +~~~~~~~~~~~~~ Decorators can help to check whether someone is authorized to use an endpoint in a web application. They are extensively used in Flask web @@ -296,7 +296,7 @@ authentication: return decorated Logging -~~~~~~~~~~~~ +~~~~~~~ Logging is another area where the decorators shine. Here is an example: diff --git a/for_-_else.rst b/for_-_else.rst index 9a68363..f7fbe82 100644 --- a/for_-_else.rst +++ b/for_-_else.rst @@ -1,5 +1,5 @@ ``for/else`` ----------- +------------ Loops are an integral part of any language. Likewise ``for`` loops are an important part of Python. However there are a few things which most @@ -22,7 +22,7 @@ That is the very basic structure of a ``for`` loop. Now let's move on to some of the lesser known features of ``for`` loops in Python. ``else`` Clause -^^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^ ``for`` loops also have an ``else`` clause which most of us are unfamiliar with. The ``else`` clause executes after the loop completes normally. From 9b6262eed638dd2f5960fb959def6fe981b0b40c Mon Sep 17 00:00:00 2001 From: Keith Kong Hei Lok <70051933+LittleBigKeith@users.noreply.github.com> Date: Mon, 21 Sep 2020 01:31:31 +0800 Subject: [PATCH 151/152] Create zip.md (#218) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Create zip.md Create new file for 'zip' function * Converted to reStructured * added zip to the index Co-authored-by: M.Yasoob Ullah Khalid ☺ Co-authored-by: Yasoob Khalid --- index.rst | 1 + zip.rst | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 zip.rst diff --git a/index.rst b/index.rst index 224ae75..b45de64 100644 --- a/index.rst +++ b/index.rst @@ -50,6 +50,7 @@ Table of Contents virtual_environment collections enumerate + zip object_introspection comprehensions exceptions diff --git a/zip.rst b/zip.rst new file mode 100644 index 0000000..947fe2a --- /dev/null +++ b/zip.rst @@ -0,0 +1,71 @@ +Zip and unzip +------------- + +**Zip** + +Zip is a useful function that allows you to combine two lists easily. + +After calling zip, an iterator is returned. In order to see the content wrapped inside, we need to first convert it to a list. + +Example: + +.. code:: python + + first_name = ['Joe','Earnst','Thomas','Martin','Charles'] + + last_name = ['Schmoe','Ehlmann','Fischer','Walter','Rogan','Green'] + + age = [23, 65, 11, 36, 83] + + print(list(zip(first_name,last_name, age))) + + # Output + # + # [('Joe', 'Schmoe', 23), ('Earnst', 'Ehlmann', 65), ('Thomas', 'Fischer', 11), ('Martin', 'Walter', 36), ('Charles', 'Rogan', 83)] + +One advantage of zip is that it improves readability of for loops. + +For example, instead of needing multiple inputs, you only need one zipped list for the following for loop: + +.. code:: python + + first_name = ['Joe','Earnst','Thomas','Martin','Charles'] + last_name = ['Schmoe','Ehlmann','Fischer','Walter','Rogan','Green'] + age = [23, 65, 11, 36, 83] + + for first_name, last_name, age in zip(first_name, last_name, age): + print(f"{first_name} {last_name} is {age} years old") + + # Output + # + # Joe Schmoe is 23 years old + # Earnst Ehlmann is 65 years old + # Thomas Fischer is 11 years old + # Martin Walter is 36 years old + # Charles Rogan is 83 years old + +**Unzip** + +We can use the `zip` function to unzip a list as well. This time, we need an input of a list with an asterisk before it. + +The outputs are the separated lists. + +Example: + +.. code:: python + + full_name_list = [('Joe', 'Schmoe', 23), + ('Earnst', 'Ehlmann', 65), + ('Thomas', 'Fischer', 11), + ('Martin', 'Walter', 36), + ('Charles', 'Rogan', 83)] + + first_name, last_name, age = list(zip(*full_name_list)) + print(f"first name: {first_name}\nlast name: {last_name} \nage: {age}") + + # Output + + # first name: ('Joe', 'Earnst', 'Thomas', 'Martin', 'Charles') + # last name: ('Schmoe', 'Ehlmann', 'Fischer', 'Walter', 'Rogan') + # age: (23, 65, 11, 36, 83) + From 257709f4acb61539bf654fc6a5b72ac5e2c86ba0 Mon Sep 17 00:00:00 2001 From: absara <105458799+Abidi-S@users.noreply.github.com> Date: Fri, 18 Nov 2022 07:42:25 +0000 Subject: [PATCH 152/152] Global and Return edits (#232) * replaced "&" with "and" in article heading * fixed minor typos --- global_&_return.rst | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/global_&_return.rst b/global_&_return.rst index 39a75d4..0661752 100644 --- a/global_&_return.rst +++ b/global_&_return.rst @@ -1,9 +1,9 @@ -Global & Return +Global and Return --------------- -You might have encountered some functions written in python which have a +You might have encountered some functions written in Python which have a ``return`` keyword in the end of the function. Do you know what it does? It -is similar to return in other languages. Lets examine this little +is similar to return in other languages. Let's examine this little function: .. code:: python @@ -15,7 +15,7 @@ function: print(result) # Output: 8 -The function above takes two values as input and then output their +The function above takes two values as input and then outputs their addition. We could have also done: .. code:: python @@ -28,11 +28,11 @@ addition. We could have also done: print(result) # Output: 8 -So first lets talk about the first bit of code which involves the +So first let's talk about the first bit of code which involves the ``return`` keyword. What that function is doing is that it is assigning the value to the variable which is calling that function which in our -case is ``result``. In most cases and you won't need to use the -``global`` keyword. However lets examine the other bit of code as well +case is ``result``. In most cases you won't need to use the +``global`` keyword. However, let's examine the other bit of code as well which includes the ``global`` keyword. So what that function is doing is that it is making a global variable ``result``. What does global mean here? Global variable means that we can access that variable outside the @@ -125,11 +125,11 @@ Or by more common convention: print(profile_age) # Output: 30 -Keep in mind that even in the above example we are returning a tuple (despite the lack of paranthesis) and not separate multiple values. If you want to take it one step further, you can also make use of `namedtuple `_. Here is an example: +Keep in mind that even in the above example we are returning a tuple (despite the lack of parenthesis) and not separate multiple values. If you want to take it one step further, you can also make use of `namedtuple `_. Here is an example: .. code:: python - from collections import namedtuple + from collections import namedtuple def profile(): Person = namedtuple('Person', 'name age') return Person(name="Danny", age=31) @@ -157,4 +157,4 @@ Keep in mind that even in the above example we are returning a tuple (despite th print(age) #31 -This is a better way to do it along with returning ``lists`` and ``dicts``. Don't use ``global`` keyword unless you know what you are doing. ``global`` might be a better option in a few cases but is not in most of them. +This is a better way to do it, along with returning ``list`` and ``dict``. Don't use ``global`` keyword unless you know what you are doing. ``global`` might be a better option in a few cases but is not in most of them.