       Save your money via IT outsourcing! # PythonIntroduction

Python Introduction
This is a very brief and tentative preface for diving into Python to be skilled enough
for learning our software (OpenOpt/FuncDesigner/DerApproximator) documentation.

## Hello World example

`print('Hello World!')`

## Variables

```a = 15 # an integer
b = 80.0 # a float number
town = 'Cherkasy' # a string
language = "Ukrainian" # you can use "" for string variables creation as well as ''
d = True # a boolean value
print((type(a),type(b),type(t),type(d))) # prints (<type 'int'>, <type 'float'>, <type 'str'>, <type 'bool'>)
isinstance(a,float), isinstance(b,float), isinstance(town,str) # (False, True, True)```

## Functions

```def myFunc(a, b):
return a+b
# or a shorter way for simple cases, equivalent for MATLAB @:
myFunc = lambda a, b: a+b
# calling a function:
c = myFunc(3,4)
# some more complex examples:
def myFunc(a, b, *args); def myFunc(a, b, *args, **kwargs); lambda a, b, *args; lambda a, b, *args, **kwargs
def myFunc(a, b, c=10, *args); def myFunc(a, b, c=10, d=20, *args, **kwargs);
# args are some expected named arguments
#     correct call examples: myFunc(3, 4, 5), myFunc(3, 4), myFunc(3, 4, 5, 6, 7)
# kwargs are some expected named arguments
#     correct call examples: myFunc(3, 4, extra_arg_1=5), myFunc(3, 4), myFunc(3, 4, extra_arg_1=5, extra_arg_2=6)```

## Tuple

```d = (11,12,13,'asdf',14,15.0)
# Note - tuples are immutable types
# Common operations:
# length of a typle
len(d)
# indexation (in Python it starts from zero)
d, d
# slicing
d[0:2] # equals to (11, 12)
d[2:-1] # equals to (13, 'asdf', 14)
d[:2] # same as d[0:2], equals to (11, 12)
d[3:] # equals to ('asdf', 14, 15.0)
# contains
(15 in d, 100 in d) # returns (True, False)```

## List

List is a child class of tuple (thus all tuple methods work with lists as well); however, lists are mutable.

```d = [11,12,13,'asdf',14,15.0]
# Common operations:
d.append(16) # appends 16 to the end of the list
d + [16,17] # returns new list [11,12,13,'asdf',14,15.0, 16, 17]
d += [16,17] # in-place modification, appends [16,17] to the end of the list
d.insert(index, object) # insert object before index
d.pop([index]) # remove and return item at index (default last)
d.remove(value) # remove first occurrence of value
d.sort(cmp=None, key=None, reverse=False) # stable sort IN PLACE```

## Dictionary

Python dictionary is equivalent for C++ STL map

```d = {1:1, 2.0:4.0, 3:9}
# other ways to define the dict:
d = dict(((1,1), (2,4.0), (3,9)))
d = dict([(1,1), (2,4.0), (3,9)])
d = dict((i, i ** 2) for a in (1,2,3)) # operation a ** b means a^b
(1 in d, 2 in d, 5 in d) # returns (True, True, False)
d, d # returns (1, 9)
d.keys() # returns 1, 2.0, 3
d.items() # returns [(1, 1), (2, 4.0), (3, 9)]
d.update({4:16, 10:100}) # update a dict by another one
d = 400 # set value 400 to key 20, add this key if it was absent
len(d) # returns number of entries in the dict```

## Set

```# argument to class constructor should be a list or a tuple
d = set((1,2,3,'asdf'))
# Common operations:
d3 = d1 | d2 # union
d1.update(d2) # in-place update
# or just
d1 |= d2
# some other operations: 'clear', 'copy', 'difference', 'difference_update',
# 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset',
# 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update'```

## NumPy array

General n-dimensional array; requires Python module NumPy installed

```from numpy import *
a = array((1,2,3))
# also you may use python list:
a = array([1,2,3])
a = array(([1,2,3],[4,5,6]))
# or a constructor:
a = zeros(3) # array of length 3 filled by zeros
a = ones(3) # array of length 3 filled by ones
a = empty((4,5)) # uninitialized array of shape(4,5)
a = zeros((3,4)) # array of shape (3,4) filled by zeros
b, c = sin(a), cos(a) # some basic operations
d = b + c + 2*b*c + 15 - b ** c + log(c+4)/(b+c+5) + exp(c)
# getting norm
from numpy.linalg import norm
nd1, nd2, max_abs_nd = norm(d,1), norm(d,2), norm(d, inf)
# for matrix multiplication see numpy function dot```

## Cycles

```for i in [0,1,2,3]: print('current value %d, its double value %d' % (i, 2*i))
# It is very convenient to use range/xrange in cycles:
for i in range(n): do_something # i will have sequential values 0, 1, ..., n-1
# for big n you'd better use xrange,
# it returns iterator instead of creating whole list with possibly very big memory size
for i in xrange(n): do_something
# you can use "while" cycle as well:
elem = 100
while elem > 1.01:
elem /= 2.0
print('current element value: %f' % elem)
# you can use the following construction:
result = [func(some_variables) for elem in an_iterable_object]
# some_iterable_object can be list, tuple, set, dict
# e.g.
b = 4.0
r = [(1 + (b+a)**3) for a in (1,2,3)]
# or
s = set((1,2,3)) | set((1,2,4)) # returns set((1,2,3,4))
r = dict([(a, 1 + a**3) for a in s])```

## If-then-else

Common usage:

```if condition1:
# do something for case 1
elif condition2:
# do something for case 2
elif condition3:
# do something for case 3
#...
else:
# do something```

Shorter way for simple if-then cases, equivalent for C "?:" operator:

`a = value1 if condition else value2`

## Classes

Python has classes with all required features for Object Oriented Programming (Polymorphism, Inheritance, Encapsulation), but it's beyond our short survey, you could view this doc entry instead.

## Databases

The doc entry is recommended.

## Some more general info

• String concatenation
`'asdf' + 'qwerty' # returns 'asdfqwerty'`
• Beware of Python ^ operation - it returns "xor" instead of "power". Use ** for power.
• "a in S" requires
• O(n) operations for S being list or tuple
• O(log(n)) operations for S being set or dict
• (To be continued)