Skip to content

Instantly share code, notes, and snippets.

@krlozadan
Last active January 3, 2019 00:54
Show Gist options
  • Save krlozadan/4712d58debbe565813e049af149a1511 to your computer and use it in GitHub Desktop.
Save krlozadan/4712d58debbe565813e049af149a1511 to your computer and use it in GitHub Desktop.
Python Language Basics
#######################################################################
# Python mathematical operators
2 + 2 # Sum
2 - 2 # Substraction
2 * 2 # Multiplication
2 / 2 # Division (Always returns a float)
2 // 2 # Division (Returns an int loosing the decimal part)
2 ** 2 # Power
#######################################################################
# Python data types
# The type() function will return thje type of variable or value
print(type(91)) # int
print(type(91.0)) # float
print(type('hello')) # str
print(type(True)) # bool (Notice the capital T or F for False)
# Data Structures
# Mutable (Lists and Dictionaries)
print(type([1,'2',10.9])) # list
print(type({ 'hello':'world', 'number' : 12 })) # dict
# Unmutable (Tuples and Sets)
print(type(('hello', 'world', 12 ))) # tuple
print(type({ 'hello', 'word', 12 })) # set
# Ordering, Lists and Tuples are ordered where Dictionaries and Sets aren't
# Duplication: Lists and Tuples allow having the same value repeated, dictionaries and sets won't allow that
set_duplication_example = { 2,2,2,2,2,2 }
print(set_duplication_example) # This will still be a set but will have the value {2}
#######################################################################
# Variable declaration: Variables can be redeclared or redefined dynamically, as python is not static typed. Just like JavaScript
my_string = 2
my_string = 'Hello World' # Strings can be created using single or doubel quotes
# This would work
#######################################################################
# Indexing strings
# You can use indexes to acces characters of a string
print(my_string[1]) # Indexex start at 0
# You can use reverse indexes as well, so the last character independenlty of how long the string is... will be -1
print(my_string[-1]) # This will output 'd'
# Slicing strings (substrings)
alphabet = 'abcdefg'
# Use the square brackets with a colon to indicate start and excluded ending index
# Examples:
print(alphabet[2:5]) # output: cde
print(alphabet[:5]) # output: abcde
print(alphabet[2:]) # output: cdefg
print(alphabet[:]) # output: abcdefg
print(alphabet[2:-2]) # output: cde (you can use revserve indexing)
# Step size would be the third parameter in the slicing syntax. default value is 1
print(alphabet[::]) # output: abcdefg
print(alphabet[::2]) # output: aceg
print(alphabet[2::2]) # output: ceg
# This is a nice trick to reverse a stirng
print(alphabet[::-1]) # output: gfedcba
# You can reassign list values like this
l = [1, 2, 3, 4, 5, 6]
l[2:4] = [100, 200]
print(l) # [1, 2, 100, 200, 5, 6]
#######################################################################
# String properties and methods
# String are not index assignable because they are unmutable
name = 'Sam'
# This will throa an error
# name[0] = 'P''
# You can concatenate strings using the plus sign
full_name = name + ' ' + 'Jhonson'
# You can multiply a string as well
sleeping = 'z' * 10 # zzzzzzzzzz
# String methods
full_name.upper() # This willnot modify the original string value
full_name.lower() # This willnot modify the original string value
full_name.split() # Sepparate the string per white space by default, if not... with the provided parameter
# Multiline string
multiline = """
Hello, this
is a
multiline
string that would auto-escape the ' character
"""
#######################################################################
# String interpolation (without using concatenation)
si = 'Hello, my name is {}. And I am from {}'.format(full_name, 'Mexico')
print(si)
# Another way to print strings
item = "ball"
>>> print("This is a %s" % (item))
# You can use index positions
print('The {} {} {}'.format('fox', 'brown', 'quick')) # The fox brown quick
print('The {2} {1} {0}'.format('fox', 'brown', 'quick')) # The quick brown fox
print('The {q} {b} {f}'.format(f='fox', b='brown', q='quick')) # The quick brown fox
print('The {f} {f} {f}'.format(f='fox', b='brown', q='quick')) # The fox fox fox
# The float formatiting works as follows: "{value:width.presicion f}"
# width represents the white space to the left of the point
# Precision is how many numbers you'll see to the right of the string
num = 100 / 777
print('The number is {n:1.3f}'.format(n=num))
# This is other type of string interpolation and it is only available in python 3.6 onwards
print(f'The number is {num:1.3f}')
#######################################################################
# Lists are basically arrays in other languages. They can hold anydifferent types of data at the same time
my_list = ['one', 'two', 'three']
my_list[0] # one
# You can use indexing and slicing just like strings
my_list[1:] # ['two', 'three']
# One big difference with strings is that lists are mutable
my_list[0] = 'ONE' # Will change the list
# You can also add lists
my_list + ['four', 'five'] # ['ONE', 'two', 'three', 'four', 'five']
# Some methods:
my_list.append('four') # Adds an item to the end of the list
my_list.pop() # Removes an item from the end of the list. If no index is passed, it will be the last index
# The following methods will perform the operation on the object itself
my_list.sort() # Will sort in alphabetical or numerical order.
my_list.reverse() # Will reverse the list order
#######################################################################
# You can access the values of a dictionary through its keys. The keys should always be strings
d = { 'key' : [100, 230,500], 'another_one' : 1232 }
d['key'][0] = 0
d['yet_another_key'] = 'Hello World'
d.keys() # This will show all keys as a list
d.values() # This will return a list with all the values
d.items() # This will return a list of tuples
#######################################################################
# Tuples - Unmutable. similar to lists. They are very used tom maintain data integrity
tuple_test = (1,'one',123.0) # Can have mixed types
# You can use indexing, slicing and reverse indexing
tuple_test[0] # 1
tuple_test[1:] # Returns a new tuple with the objects
t = ('a','a','b')
t.count('a') # Number of times an element is in the tuple
t.index('a') # Index of the first matching element
#######################################################################
# Sets
s = {1}
s.add(1) # This won't get added a second time
s.add(2)
s.add(2) # Will only add 2 once
# They are useful to cast a list/string and get the unique values
s = set([1,1,1,1,1,1,2,2,2,2,3,3,3,3])
print(s) # Will output {1,2,3}
s = set('mississippi')
print(s) # Will output {'s', 'i', 'p', 'm'}
#######################################################################
# None
# Is a reserved keyword used to represent a null value or not a value
n = None # So you can declare an empty variable
# None is not the same as 0, False or empty string. Although None is a falsy value
if n:
print('n - True')
elif n == 0:
print('n - 0')
elif n == False:
print('n - False')
else:
print('n - None')
# This would print None
# The best way to check if a value is None would be to use the keyword 'is'
if n is None:
print('This is none')
# This would work but is slower due to the fact that in Python every object/variable has an ID with a value assigned to it
# So in this case, Python would need to check every value instead of comparing the IDs
if n == None:
print('This is none')
#######################################################################
# IO
# Opens a file, the first parameter represents the path and name of the file.
# The second parameter are options when opening. Default: 'r' for reading only. Find more about it here: https://docs.python.org/3/library/functions.html#open
f = open('text.txt','a+')
f.write('Hello World!')
f.write('\n') # Include a new line in the text file
f.write('Hello World!\n')
f.seek(0) # Places the cursor back to the beginning. This is useful for reading again the entire file
print(f.read()) # This gives you back a single string with everything in it
f.close() # Make sure you always close the file after using it
# Another syntax which doesn't require to manually close the file
with open('text.txt','w+') as opened_file:
opened_file.write('This line was insterted with another type of syntax\n')
opened_file.seek(0)
print(opened_file.readlines())
#######################################################################
# Comparison Operators
# less than <
2 < 4 # True
# greater than >
2 > 4 # False
# equal ==
2 == 4 # False
2.0 == 2 # True (doesn't matter the type)
2 == '2' # False (does matter the type)
# not equal !=
2 != 2 # False
# less than or equal <=
2 <= 2 # True
# greater than or equal >=
2 >= 2 # True
# Chaining logical operators (In other languages would be the && or ||)
# Use the word 'and' to make two conditions to be true
1 < 2 and 3 > 2 # True
# Use the word 'or' to make at least one condition to be true
1 < 2 or 3 > 1 # True
# Use the keyword 'not' to get the opposite result from the logical operator
2 == 2 # True
not 2 == 2 # False
#######################################################################
# Control Flow
# If, Else If and Else
food = 'burger'
# Notice the colons at the end of the statement and the indentation
if food == 'sushi':
print('My favourite!!')
elif food == 'burger':
print('Ok, that was good')
else:
print('Hmm...')
# For Loops
my_list = [1,2,3,4,5]
# item_name represents the item over each loop run, in this case, each number in the list
for item_name in my_list: # This syntax is used for iterables
print(item_name) # This will out put every element in the list
# For dictionaries, the usage would be like this.
my_dict = {'one':1, 'two':2, 'three':3}
for item_key,item_value in my_dict.items():
print(item_key + ' has the value ' + str(item_value)) # This will out put every element in the list
# The previous example was using what is called "Tuple Unpacking", here's another example
tu = [(1,2,3),(4,5,6),(7,8,9)]
for item in tu:
print(item) # This returns the entire tuple
for a,b,c in tu:
print(b) # This returns only the middle values, in this case: 2,5,8
# While Loops
water_value = 0
limit = 10
while water_value < limit:
water_value += 1
print(f'The current watter level is {water_value}')
# Loops special keywords
# break: will exit the current closests enclosing loop
# continue: goes to the top of the current closests enclosing loop
# pass: This will do nothing, is used as a placeholder for empty loops and functions
for x in range(0,3):
pass #this would throw and error without the pass keyword
def test_function():
pass #this would throw and error without the pass keyword
#######################################################################
# Useful Operators
# Range Generator: creates a list of numbers, depending on the parameters
for item in range(5): # Starting 0 (default) not including 5
print(item) # This will output 0,1,2,3,4
for item in range(3,5): # Startint 3, not including 5
print(item) # This will output 3,4
for item in range(0,10,2): # Jumps every two numbers
print(item) # This will output 0,2,4,6,8
# Enumerate: Creates an index for the specified iterable and compacts them in tuples
word = 'abc'
for item in enumerate(word):
print(item) # This will output: (0,a) (1,b) (2,c)
# Zip: crestes a list of tuples by merging lists
list1 = [0,1,2]
list2 = ['a','b','c']
for item in zip(list1, list2):
print(item) # This will output: (0,a) (1,b) (2,c)
# In: check if an object is in an iterable
'x' in [1,3,4,'x'] # Will output True
# Min and Max: get minimun and maximum number in an iterable
numbers = [2,4,8,12,65,3]
min(numbers) # 2
max(numbers) # 65
# Random library
from random import shuffle
ordered_list = [1,2,3,4,5,6,7,8,9,10]
shuffle(ordered_list) # This will randomize the list, passed by reference
from random import randint
randint(0,100) # Random int between 0 and 100 (including both)
# Input: gets input from the user, it always returns a string
x = input('What is your favourite number?')
print(type(x)) # output: str
#######################################################################
# List Comprehension
# Instead of doing this to fill a list
list1 = []
word = 'hello'
for letter in word:
list1.append(letter) # ['h','e','l','l','o']
# We can use this syntax
# Produces the exact same result, considering that nothing else is wanted but to transform move each element to a list
# The first keyword, just before for... is what will be insterted upon each loop iteration
list2 = [letter for letter in word] # ['h','e','l','l','o']
list3 = ['a' for letter in word] # ['a','a','a','a','a']
list4 = [num**2 for num in range(11)] # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
list5 = [num for num in range(11) if num % 2 == 0] # [0, 2, 4, 6, 8, 10]
celcius = [0, 10, 20, 32.1]
fahrenheit = [((9/5)*temp + 32) for temp in celcius] # [32.0, 50.0, 68.0, 89.78]
# if/else
result = [x if x %2 == 0 else 'Odd' for x in range(0,11)] # [0, 'Odd', 2, 'Odd', 4, 'Odd', 6, 'Odd', 8, 'Odd', 10]
# Nested for loops
nested = [x*y for x in [2,4,6] for y in [1,100,1000]] # [2, 200, 2000, 4, 400, 4000, 6, 600, 6000]
#######################################################################
# Functions
def print_name(name='World'): # This is using a default parameter
# This is informnation about the function, you could put the doc strings
'''
Will print the provided name
'''
print('Hello ' + name)
def add(n1, n2):
'''
Adds two numbers together
'''
return n1 + n2
print_name('Carlos Adan') # Hello Carlos Adan
print_name() # Hello World
print(str(add(2,3)))
# Pig Latin exercise function (this is functional programming in practice as well, since we don't modify the original string)
def pig_latin(word):
first_letter = word[0]
if first_letter in 'aeiou':
lp_word = word + 'ay'
else:
lp_word = word[1:] + first_letter + 'ay'
return lp_word
# Multiple arguments (args and kwargs)
def get_percent(*args): # args is only a convention, it can be called whatever you want
print(args) # This will be represented as a tuple
return (sum(args)) * 0.1
def get_fav_fruit(**kwargs): # wkargs is only a convention, it can be called whatever you want
print(kwargs) # This will be represented as a dictionary
if 'fruit' in kwargs:
print('My favourite frui is {}'.format(kwargs['fruit']))
else:
print('I couldn\'t find my favourite fruit')
print(get_percent(5,10,90))
get_fav_fruit(fruit='Kiwi', veggie='Lettuce')
#######################################################################
# Lambda expressions (Anonymous functions)
# Conatrsints: it is limited to single liners
def square(num):
return num ** 2
my_list = [1,2,3,4,5]
print(list(map(square, my_list))) # [1, 4, 9, 16, 25]
# We can turn that into:
x = lambda num : num ** 2
print(list(map(x, my_list))) # [1, 4, 9, 16, 25]
# Or:
print(list(map(lambda num: num ** 2, my_list))) # [1, 4, 9, 16, 25]
#######################################################################
# Variable Scope
var = 'Global Scope' # Global Scope
x = 10
def func1():
var = 'Enclosing Scope' # Enclosing Scope
global x # This will get the variable from the global scope
x = 20 # This is changing the global variable X
name = 'Enclosing Name'
print(var)
print(x)
def func2():
var = 'This is Local' # Local Scope
x = 10 # This is again modifying the a local variable
nonlocal name # This will access the nonlocal enclosing scope
name = 'Enclosing name from local'
print(var)
print(x)
func2()
print(name)
func1()
print(var)
print(x)
# This would print out:
# Enclosing Scope
# 20
# This is Local
# 10
# Enclosing name from local
# Global Scope
# 20
#######################################################################
# Object Oriented Programming (OOP)
class Dog():
# Class Object Attributes
species = 'mammal'
# Constuctor
def __init__(self, breed, name, spots):
# This is assignment of an instance attribute
self.breed = breed
self.name = name
self.spots = spots
# Every method inm a class need to pass the parameter 'self'. Although it can be whatever name it is a convention to use self
def method_one(self):
print(self.species)
print(self.breed)
def method_two(self):
print(self.name)
# Inheritance
class Shape():
def __init__(self):
pass
def log(self):
print('I am a shape')
# Abstract method
def abstract_method(self):
raise NotImplementedError('Subclass should implement this method')
class Square(Shape):
def __init__(self):
Shape.__init__(self)
def log(self):
print('I am a square')
class Circle(Shape):
def __init__(self):
Shape.__init__(self)
def log(self):
print('I am a circle')
class Triangle(Shape):
def __init__(self):
Shape.__init__(self)
sq = Square()
c = Circle()
t = Triangle()
for shape in [sq, c, t]:
shape.log()
def log_shape(shape):
shape.log()
log_shape(sq)
log_shape(c)
log_shape(t)
# Magic / Dunder methods
class Book():
def __init__(self, name, author, pages):
self.name = name
self.author = author
self.pages = pages
# This is a special method used to return a string representation of the class
def __str__(self):
return f'{self.name} by {self.author}'
def __len__(self):
return self.pages
def __del__(self):
print(f'{self.name} is about to be deleted...')
b = Book('Python Book', 'CJ', 200)
print(b)
print(len(b))
del b # Del keyword is used to delete objects from memory
# Dir and Help
# Use dir to get a list of all the methods an object has availabe
dir("Hello") # This will give a list of the methods available for strings.
# Works the same way with custom classes
# To get information about a specific method use the help function
help("hello".format)
# This would return information about the format method of the string object
# Operator Overloading
# This helps makes use of the logical operators such as +, -, * and / to have specific functionality to an object
# Example:
class Vector2():
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, another_value):
'''
This will allow to add two vector twos or a vector and a scalar value
'''
try:
if isinstance(another_value, Vector2):
return (self.x + another_value.x, self.y + another_value.y)
elif isinstance(another_value, int) or isinstance(another_value, float):
return (self.x + another_value, self.y + another_value)
else:
raise Exception("Both operands should be of type Vector 2")
return None
except Exception as e:
print(e)
v1 = Vector2(2,2)
v2 = Vector2(5,1)
print(v1)
res = v1 - 23
if res is None:
print("There was an error")
else:
print(res)
#######################################################################
# Exception Handling
# https://docs.python.org/3/library/exceptions.html
while True:
try:
result = int(input('Please provide a number: '))
except OSError: # This is catching a specific error type
print('Whoops that is not a valid number')
continue
except: # This is catching every error type
print('Whoops that is not a valid number')
continue
else: # This will only run if there was no error
print('We finished')
break
finally: # This will run even if there was an error
print("I'm always going to run")
#######################################################################
# Decorators
# Functions as objects
def func():
print('Hello World')
func() # Output: Hello World
print(func) # Output: <function func at 0x030E07C8>
# This is because the function is an object, that means we can assign it to other variables
another_function = func
another_function() # Output: Hello World
del func
# func() # This will throw an error, because the poinert to that function was deleted. Python no longers know about "func"
another_function() # This would still work, because "another_function" is still pointing to the function "func" was pointing to
# Functions as arguments
# Since you can pass functions as arguments, a decorator is essentially adding functionality before and after the original function.
# Decorator function
def new_decorator(original_function):
def wrapper_function():
print('Some code BEFORE the original function')
original_function()
print('Some code AFTER the original function')
return wrapper_function
# Original function
def func_manual_decorator():
print('Running function to be decorated')
# First example: Manually creating a decorator
manual_decorated_func = new_decorator(func_manual_decorator)
print(manual_decorated_func) # <function new_decorator.<locals>.wrapper_function at 0x03AA9540>
manual_decorated_func()
# Second example: Using the decorator syntax
@new_decorator # This acts like an on/off switch, if you don't want the decorator, you just remove this line
def func_decorator():
print('Running function to be decorated')
print(func_decorator) # <function new_decorator.<locals>.wrapper_function at 0x03AA9540>
func_decorator()
#######################################################################
# Generators
# They serve as a way of creating a sequence of values in a memory efficient way
# Instead of doing this, because it needs to store a list with every value
def cubes(n):
result = []
for x in range(n):
result.append(x ** 3)
return result
# Do this
def gen_cubes(n):
for x in range(n):
yield x ** 3
for num in cubes(10):
print(num)
for num in gen_cubes(10):
print(num)
# Both do the same thing but the later is way more memory efficient. If you wanted the list you could cast it:
num_list = list(gen_cubes(10))
# Next Function
# next is used to get the next iteration on a iterable object
def simple_range():
for x in range(3):
yield x
sr = simple_range()
print(sr) # <generator object simple_range at 0x02E88F70>
# This means we can then get the following value using the next function
print(next(sr))
print(next(sr))
print(next(sr))
try:
print(next(sr)) # This will throw an error. As a tip, the for loop automatically catches that error to know where to stop
except:
print('End of generator')
# Iter Function
# Converts an object that might be an iterable to an iterator
iterable_string = 'hello' # Even though you can iterate over a string, it doesn't mean it is an iterator object. So the folowing line will fail
try:
print(next(iterable_string))
except Exception as e:
print(e)
# This will work
iterator_string = iter(iterable_string)
try:
print(next(iterator_string))
print(next(iterator_string))
print(next(iterator_string))
except Exception as e:
print(e)
#######################################################################
'''
Virtual environments allows to have dependencies for different projects in sepparate places
To use virtual environments you need to use pip to install 'virtualenv'
After the package has been installed, in the root directory of the project run the command:
virtualenv name_of_the_env
You can even define the python version the project uses
Make sure the environment folder doesn't get included in the version control system
After that depending on the OS you can activate the environment by:
Linuz/OSX:
source /name_of_the_env/bin/activate
Windows:
/name_of_the_env/Scripts/activate
Then you can create a requirements file with all the dependencies using
pip freeze < requirements.txt
This file can then be added to the version control. To install every dependency in a requirements.txt use:
pip install -r requirements.txt
To stop using a virtual env, use the command deactivate
'''
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment