<jupyter_start><jupyter_text>IntroductionThis course is meant to provide a very gentle introduction to the `python` scientific ecosystem. We will try to cover as much as humanly possible within the timespan of **2 hours**. It is essentially a warm-up before the upcoming [machine learning bootcamps](http://www.datascience-paris-saclay.fr/en/site/newsView/5) for those who would like to adopt `python` as their daily data hacking toolbox.** What is in this coure ** - an introduction to python syntax, - an overview of the scientific libraries, - using the IPython Notebook - plotting within the notebook, - and a basic introduction to the machine library scikit-learn.** What this course is not about ** - an introduction to object oriented programming - detailed expertise in scientific python libraries - a machine learning practical course (come to thursday's bootcamp for that)  References- [An *excellent* python tutorial](http://learnpythonthehardway.org/book/) Table of Contents  IPython Notebook  Python syntax A comment is line preceded by a ``<jupyter_code># Here is a comment<jupyter_output><empty_output><jupyter_text>Numbers Variables are declared without mentioning their type  Numbers<jupyter_code>i = 5  # a is an integer
x = 2.0  # x is a float<jupyter_output><empty_output><jupyter_text>Caveats<jupyter_code>5. / 2
5 / 2
5. // 2  # floor division operator<jupyter_output><empty_output><jupyter_text>Strings Strings can be declared with two different ways (actually four...)<jupyter_code>s1 = 'This is a string.'

s2 = '''This is a mult-line string.
        Awesome if I want to replace Microsoft Word by Python...
        or simply to document my code directly within ;)
     '''

s3 = "I'm using a double quotes to delimit the string, otherwise, I'd have to \"escape\" it with a \ ."
print(s1)
print(s2)
print(s3)<jupyter_output>This is a string.
This is a mult-line string.
        Awesome if I want to replace Microsoft Word by Python...
        or simply to document my code directly within ;)
     
I'm using a double quotes to delimit the string, otherwise, I'd have to "escape" it with a \ .<jupyter_text>You can know the type of a variable by calling the `type()` function, it comes out-of-box functions with your `python` interpreter. Many other functions are provided as we will see. We call them the **built-in** functions.<jupyter_code>print(type(i))
print(type(x))
print(type(s1))<jupyter_output><type 'int'>
<type 'float'>
<type 'str'><jupyter_text>TipVariables can be assigned all at onces, which allows to do swapping pretty elegantly<jupyter_code>a, b = 1, 's'
print(a, b)
a, b = b, a
print(a, b)
c = d = 'multiple assignment'
b += 10  # no b++ nor ++b in python<jupyter_output><empty_output><jupyter_text>IndentationWhere C-like languages use curly brackets to delimit blocs of code, coditional statements, loops etc., `python` uses the code indentation.<jupyter_code>i = 0
while i < 5:
    if i == 2:
        print('Two!')
    else:
        print(i)
    i += 1<jupyter_output>0
1
Two!
3
4<jupyter_text>Functions<jupyter_code>def my_func(argument):
    """ This comment is called a docstring.
    Placed right after the function signature,
    it serves as a documentation for the function."""

    # the indentation is crucial
    print(argument)
my_func('hey you!')
my_func(argument='out there in the cold')
def my_func_2(argument='default argument'):
    print(argument)
my_func_2()
def my_func_3(a, b=10, c=20):
    print(sum((a, b, c)))
my_func_3(1)       # 1 + 10 + 20
my_func_3(1, 2)    # 1 + 2 + 20
my_func_3(1, 2, 3) # 1 + 2 + 3<jupyter_output>31
23
6<jupyter_text>Data structures- lists- dictionaries<jupyter_code>my_list = [1, 2, 3]
def my_func_4(*args):
    print(sum(*args))
my_func_4(my_list)
my_func_3(*my_list)
my_dict = {'a': 1, 'b': 2, 'c': 3}
my_func_3(**my_dict)
def my_func_5(**kwargs):
    values = kwargs.values()
    print(sum(values))
my_func_5(**my_dict)<jupyter_output>6<jupyter_text>The standard signature for functions is commonly<jupyter_code>def func(pos_arg_1, pos_arg_2, named_arg_1='default arg 1', named_arg_2='default arg 2', *args, **kwargs):
    pass<jupyter_output><empty_output><jupyter_text>Data structures (most commonly used) operations<jupyter_code>my_list.append('four')
my_list  # note that the list is a heterogenous container
my_list[0]
my_list[:2]
my_list[1:3]
my_list[-1]<jupyter_output><empty_output><jupyter_text>Ex. Display the last two elements of the list without explicitely mentioning the total lenght of the list.<jupyter_code>my_list.extend([5, 6, 7])
my_list
my_list[1:5:2]<jupyter_output><empty_output><jupyter_text>One very handy and expressive way to create lists is to use **list comprehensions**<jupyter_code>my_list_comprehension = [i**2 for i in range(10)]
my_list_comprehension
my_dict.keys()
my_dict.values()
my_dict.items()
my_dict.update({'c': 3})
my_dict
my_dict['c']
my_dict['f']  # wrap it in a print to see the return value
my_dict.get('f')  # wrap it in a print to see the return value<jupyter_output>None<jupyter_text>The `get()` method accepts a second argument, check it out by pressing **`shift + tab`** when the cursor is over it. What you see is actually the docstring of the method (hence the importance of writing these little peaces of comments).<jupyter_code>'f' in my_dict<jupyter_output><empty_output><jupyter_text>Uncovered here- Dict comprehension- Sets- Tuples   Classes and objects<jupyter_code>class MyClass:
    """ Class docstring """
    my_class_attribute = "I'm shared among all the instances."
    
    def __init__(self):
        """ Constructor """    
        self.my_instance_attribtue = None
my_object = MyClass()  # constructor with no arguments<jupyter_output><empty_output><jupyter_text>The Python scientific environment  Numpy<jupyter_code>import numpy as np<jupyter_output><empty_output><jupyter_text>Meet the `ndarray` class<jupyter_code>a = np.arange(20)
a, type(a)
a.reshape(5, 4)
a = a.reshape(5, 2, 2)
a
a.dtype
b = np.array([0.1, 0.2, 0.3])
b.dtype
b.astype(np.complex)
a.shape, b.shape
print(a.ndim)
print(b.ndim)<jupyter_output>3
1<jupyter_text>Array creation<jupyter_code>np.zeros( (4, 6) )
np.zeros_like(a)
np.ones(10)<jupyter_output><empty_output><jupyter_text>Basic operations<jupyter_code>c = np.arange(10).reshape(2, -1)
c
c + 10
c**2
np.sin(c)
d = np.arange(10, 15)
d
print('{} + {} = \n\n{}'.format(c, d, c+d)) 
c > 6
c[c > 6]
c = c.T
c
c[ [1, 3, 4] ]
A = np.array( [[10  , 20],
               [30  , 40]] )
B = np.array( [[1   , 0.5],
               [1./3, 0.25]] )
A * B  # elementwise product
np.dot(A, B)  # matrix product<jupyter_output><empty_output><jupyter_text>Copies and views, for lists and arrays<jupyter_code>list_1 = range(10)
list_1
list_2 = list_1
id(list_1), id(list_2)
list_1 is list_2
list_1 = list_2[:]
id(list_1), id(list_2)
# equivalently...
list_1 is list_2
array_1 = np.arange(10)
array_2 = array_1
array_2 is array_1
array_2 = array_1[:]
array_2 is array_1
array_2[-1] = 100
array_1
array_2 = array_1.view()
array_2 is array_1
array_2.base is array_1<jupyter_output><empty_output><jupyter_text>If you want a **deep copy**, use the `.copy()` method.For a more comprehensive introduction to `numpy`, you can read [the official tutorial](http://wiki.scipy.org/Tentative_NumPy_Tutorial).  Plotting  Scikit-learn<jupyter_code>from sklearn import datasets
from sklearn.ensemble import AdaBoostClassifier
digits = datasets.load_digits()
X, y = digits.data, digits.target
clf = AdaBoostClassifier(n_estimators=100)
clf.fit(X, y)
clf.score(X, y)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11703958691910499, 'fraction_numerical': 0.025023169601482854, 'mean_word_length': 4.8969555035128804, 'pattern_counts': {'":': 0, '<': 82, '<?xml version=': 0, '>': 83, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '21', 'dir': 'jupyter-structured-clean-dedup', 'id': '132177', 'license': 'BSD-2-Clause', 'n_tokens_mistral': 2796, 'n_tokens_neox': 2664, 'n_words': 818, 'path': 'python_prebootcamp_tuto.ipynb', 'repo_name': 'Djabbz/PythonTuto', 'size': '7553'}