In [10]:
#!/usr/bin/env python
def main():
print("Hello World!")
if __name__ == '__main__':
main()
__name__
or __file__
? Snake charmersAdding parameters to your script ... Your first imports and function parameters: *args, **kwargs
$ python hello_montoya.py "Hello" "My name is Iñigo Montoya" "You killed my father" "Prepare to Die"
Check out How to unicode
Brief history
ASCII (American Standard Code for Information Interexchange) 1968. English alphabet took the conversion of a letter to a digit, between 0-127. Mid 1980's computers -> 8-bit (0-255) But what happens to accents? cyrilic alphabets? French (Latin1 or ISO-8859-1) Russian (KOI8)? UNICODE Standarization with 16-bit (2^16 = 65.535 distinct values)
Definitions
Character: smallest component of text ("A", "É")
Unicode: code points: integer value usually denoted in base 16
Unicode string: Serie of code points from 0 to 0x010ffff.
Unicode scapes:
- \xhh -> \xf1 == ñ
- \uhhhh ->
- \Uhhhhhhhh
Encoding: translates a unicode string sequence of bytes
Comment -- X: Y -- (inspired by Emacs, PEP 263)
# -*- coding: latin-1 -*-
In Python 3 the default encoding: UTF-8
All strings → python3 -c 'print("buenos dias" "hyvää huomenta" """おはようございます""")'
are unicode
Namespace is designed to overcome this difficulty and is used to differentiate functions, classes, variables etc. with the same name, available in different modules.
A Python module is simply a Python source file, which can expose classes, functions and global variables. When imported from another Python source file, the file name is sometimes treated as a namespace.
__main__
is the name of the scope in which top-level code executes.
A module’s __name__
variable is set to __main__
when read from standard input, a script, or from an interactive prompt.
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
settings_module = "settings.local"
os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings_module)
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
A Python package is simply a directory of Python module(s).
__init__.py
.
The __init__.py
file is the first thing that gets executed when a package is loaded.
rocklab/ ...
spacelab/
__init__.py
manage.py
utils/
__init__.py
physics.py
multidimensional/
__init__.py
laws.py
rockets/
__init__.py
engine.py
base.py # Defines a rocket model that exposes all its functionality
Relative imports specific location of the modules to be imported are relative to the current package.
laws.py
from ..phsycis import gravity
base.py
from ..mutidimensional.laws import InterDimensionalTravel
from .engine import (Motor, turn_on_engine, turn_off_engine,
Bolt)
# Avoid the use of \ for linebreaks and use parenthesis. Lisp people will be happy
from .engine import Motor, turn_on_engine, turn_off_engine, \
Bolt
Absolute imports an import where you fully specify the location of the entities being imported.
base.py
from utils.multidimensional.laws import Infinity
from rockets.engine import Motor
Circular imports happen when you create two modules that import each other.
rockets.engine.py
from .base import bad_design_decision
# D'ouh
def inside_the_function(*params):
# avoid circular import, or ci. Is good to mention (IMAO)
from rockets.base import bad_design_decision
bad_design_decision(params)
Note for absolute imports:
from __future__ import absolute_import
Keep Reading
In [38]:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
def main(*args, **kwargs):
"""Simple main function that prints stuff"""
print(args) # args is a tuple of positional params
print(kwargs) # kwargs is a dict with keyword params
## The names are just a mere convention
if __name__ == '__main__':
main(sys.argv) # input params from the command line
In [11]:
# Immutable Objects
age = 60 # int
weight = 77.8 # float
infinite = float('inf')
name = "Rick" # basestring/str
nick_names = ("Sanchez", "Grandpa") # tuple
jobs = frozenset(("scientist", "inventor", "arms salesman", "store owner"))
# Mutable Objects
interests = ['interdimensional travel', 'nihilism', 'alcohol']
info = {
"name": name,
"last_names": last_names,
"age": age
}
redundant = set(interests)
In [12]:
# Information from objects
type(age) # int
isinstance(age, int) # True
type(infinite)
type(name)
isinstance(name, basestring)
# typve vs isinstance: type doesnt check for object subclasses
# we will discuss the type constructor later on
Out[12]:
Why immutable objects?
In [14]:
# integers
print(id(age))
age += 10
print(id(age))
age -= 10
print(id(age))
In [31]:
# Strings
print(name + ": Wubba lubba dub-dub!!")
print(name.replace("R", "r"))
print(name.upper(), name.lower())
In [33]:
# Tuples
operations = "test", # note the comma as it makes it a tuple!!! | tuple.count/index
print(id(operations))
operations += ('build', 'deploy')
print(operations, id(operations))
In [30]:
## Tuple assignment
def say(*args):
print(args)
say(range(8))
# Packing
test, build, deploy = "Always passing", "A better world", "Your mind"
# OK but use parenthesis :)
(test, build, deploy) = ("Always passing", "A better world", "Your mind")
print("Test: ", test)
print("Build: " + build)
print("Deploy: " + deploy)
In [ ]:
# Unpacking
test, build, deploy = operations
print(test, build, deploy)
# You are warned: # ERROR -- too many values to unpack
# https://docs.python.org/3.6/tutorial/controlflow.html#unpacking-argument-lists
In [ ]:
# lists
In [40]:
print(1 + 3)
print(2 ** 10)
print(5 % 3)
In [49]:
print(10 / 4) 2
from __future__ import division
print(10 / 4) 2.5 # float division
10 // 4 # in python 3 to get integer division
In [39]:
import operator
operator.add(2, 4)
operator.gt(10, 5)
Out[39]: