Skip to content

Latest commit

 

History

History
325 lines (228 loc) · 11.8 KB

readme.md

File metadata and controls

325 lines (228 loc) · 11.8 KB

Buy me a coffee!

If this was useful to you, buy me a coffee to make my day!

Buy Me A Coffee

Interactive Python from Browsers

Python reference

Python3 interpreter on a Mac

Functional Programming with Python

Naveens-MacBook-Pro:~ navkar$ python3
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 26 2018, 23:26:24) 
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 4+4
8
>>> print("Hello")
Hello
>>> exit()

What does if __name__== "__main__" do?

Consider the following lines of code...

Foo.py

print __name__
if __name__ == '__main__':
    print 'XXXX'

File foo.py can be used in the following two ways...

imported in another file :

import foo

In this case __name__ is foo, the code section does not execute and will not print XXXX.

executed directly :

python foo.py
  • When it is executed directly, __name__ is same as __main__ and the code in that section executes and prints XXXX
  • One can write various unit tests within the same module.

List comprehensions

list-comprehensions

Syntax : result = [transform iteration filter ]

Creates a new list with the lengths of each of the items

fruits = ['apple', 'mango', 'kiwi', 'watermelon', 'pear']
list_len=[len(item) for item in fruits]
In [1]: list_len
Out[1]: [5, 5, 4, 10, 4]

Find fruits starting with letter 'a' in the list of fruits and create a new list

fruits = ['apple', 'mango', 'kiwi', 'watermelon', 'pear']
find_apple = [item for item in list if item.startswith('a')]

Generator Expression

  • A Generator object is an iterator, whose values are created at the time of accessing them.
  • A generator can be obtained either from a generator expression or a generator function.
x = [6, 3, 1]
g = (i**2 for i in x)  # generator expression
print(next(g))         # -> 36

Generator functions

improve-your-python-yield-and-generators

What does __init__ do?

  • Set multiple attributes, at once, by defining the initializer method, __init__ , inside the class.
  • This method is called by default, during an object creation.
  • It takes values passed inside the parenthesis, during an object creation, as it's arguments.
  • It also takes self as the first argument, which refers to the current object.
'This is known as a docstring'
class Person:
    'Initialises two attributes of a person.'
    def __init__(self, fname, lname):
        self.fname = fname
        self.lname = lname

p1 = Person('George', 'Smith')   
print(p1.fname, '-', p1.lname)           # -> 'George - Smith'

Inheritance

  • In Python, every class uses inheritance and is inherited from object by default.
class Person:
    def __init__(self, fname, lname):
        self.fname = fname
        self.lname = lname

class Employee(Person):
    all_employees = []

    def __init__(self, fname, lname, empid):
        Person.__init__(self, fname, lname)
        self.empid = empid
        Employee.all_employees.append(self)
  • In above example, Employee class utilises __init__ method of parent class Person, to create the object.

Magic command %save - saves the previous list of commands in a file

%save sample_script.py 1-6

Magic command %more - view the contents of a file

%show sample_script.py

Magic command %hist - history of commands

%hist

What is the input of a cell magic method ?

  • Python code written in multiple lines of a single cell.

Which of the following statement retreives names of all builtin module names?

  • The compiled-in module names are in sys.builtin_module_names

Which of the following statement retreives names of all builtin objects?

  • A dictionary of key-value pairs: __builtins__.__dict__
  • The objects: __builtins__.__dict__.values()

What does __doc__ do?

  • The print(__doc__) command simply re-uses that documentation string to write it to your terminal each time you run the script, and any other python tool (like the interactive interpreter help() function, for example) can introspect that same value.
  • Each class or a method definition can have an optional first line, known as docstring.
  • Once documented, you can load the script into an interactive interpreter and run help command on the class.

pass keyword

In Python we use the "pass" keyword (a statement) to indicate that nothing happens—the function, class or loop is empty. With pass, we indicate a "null" block. Pass can be placed on the same line, or on a separate line. Pass can be used to quickly add things that are unimplemented.

Operator overloading

Operator overloading

Metaclass in python

metaclasses-in-python

A metaclass is the class of a class. Like a class defines how an instance of the class behaves, a metaclass defines how a class behaves. A class is an instance of a metaclass.

While in Python you can use arbitrary callables for metaclasses (like Jerub shows), the more useful approach is actually to make it an actual class itself.

type is the usual metaclass in Python. In case you're wondering, yes, type is itself a class, and it is its own type. You won't be able to recreate something like type purely in Python, but Python cheats a little. To create your own metaclass in Python you really just want to subclass type.

A metaclass is most commonly used as a class-factory. Like you create an instance of the class by calling the class, Python creates a new class (when it executes the 'class' statement) by calling the metaclass. Combined with the normal init and new methods, metaclasses therefore allow you to do 'extra things' when creating a class, like registering the new class with some registry, or even replace the class with something else entirely.

When the class statement is executed, Python first executes the body of the class statement as a normal block of code. The resulting namespace (a dict) holds the attributes of the class-to-be. The metaclass is determined by looking at the baseclasses of the class-to-be (metaclasses are inherited), at the metaclass attribute of the class-to-be (if any) or the metaclass global variable. The metaclass is then called with the name, bases and attributes of the class to instantiate it.

However, metaclasses actually define the type of a class, not just a factory for it, so you can do much more with them. You can, for instance, define normal methods on the metaclass. These metaclass-methods are like classmethods, in that they can be called on the class without an instance, but they are also not like classmethods in that they cannot be called on an instance of the class. type.subclasses() is an example of a method on the type metaclass. You can also define the normal 'magic' methods, like add, iter and getattr, to implement or change how the class behaves.

def make_hook(f):
    """Decorator to turn 'foo' method into '__foo__'"""
    f.is_hook = 1
    return f

class MyType(type):
    def __new__(mcls, name, bases, attrs):

        if name.startswith('None'):
            return None

        # Go over attributes and see if they should be renamed.
        newattrs = {}
        for attrname, attrvalue in attrs.iteritems():
            if getattr(attrvalue, 'is_hook', 0):
                newattrs['__%s__' % attrname] = attrvalue
            else:
                newattrs[attrname] = attrvalue

        return super(MyType, mcls).__new__(mcls, name, bases, newattrs)

    def __init__(self, name, bases, attrs):
        super(MyType, self).__init__(name, bases, attrs)

        # classregistry.register(self, self.interfaces)
        print "Would register class %s now." % self

    def __add__(self, other):
        class AutoClass(self, other):
            pass
        return AutoClass
        # Alternatively, to autogenerate the classname as well as the class:
        # return type(self.__name__ + other.__name__, (self, other), {})

    def unregister(self):
        # classregistry.unregister(self)
        print "Would unregister class %s now." % self

class MyObject:
    __metaclass__ = MyType


class NoneSample(MyObject):
    pass

# Will print "NoneType None"
print type(NoneSample), repr(NoneSample)

class Example(MyObject):
    def __init__(self, value):
        self.value = value
    @make_hook
    def add(self, other):
        return self.__class__(self.value + other.value)

# Will unregister the class
Example.unregister()

inst = Example(10)
# Will fail with an AttributeError
#inst.unregister()

print inst + inst
class Sibling(MyObject):
    pass

ExampleSibling = Example + Sibling
# ExampleSibling is now a subclass of both Example and Sibling (with no
# content of its own) although it will believe it's called 'AutoClass'
print ExampleSibling
print ExampleSibling.__mro__

What does __future__ do?

Put simply, the __future__ statement forces Python interpreters to use newer features of the language.

__future__ is a pseudo-module which programmers can use to enable new language features which are not compatible with the current interpreter. For example, the expression 11/4 currently evaluates to 2. If the module in which it is executed had enabled true division by executing:

from __future__ import division

the expression 11/4 would evaluate to 2.75. By importing the __future__ module and evaluating its variables, you can see when a new feature was first added to the language and when it will become the default:

  >>> import __future__
  >>> __future__.division
  _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)

Sample code to print squares in a number range

n=1
p=20

result=[]
index=0

for x in range(n,p+1):
    for y in range(x,p+1):
        sum = x + y
        sub = y - x
        #print ("x="+ str(x) + " y=" + str(y) + " x+y=" + str(sum))
        #print ("y="+ str(y) + " x=" + str(x) + " y-x=" + str(sub))
        x1 = sum**0.5
        x2 = sub**0.5
        temp1 = int(x1)
        temp2 = int(x2)
        if x1 == temp1 and x2 == temp2 and not (x == y):
            result.append((x,y))

print ("Pairs: " + str(result))