# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# + [markdown] colab_type="text" id="PscU60ffoaeU"
# # A Short Interactive Introduction to Python
#
# > This is a short introduction to Python programming for Chemists and Engineers.
# - toc: True
# - metadata_key1: Python
# - metadata_key2: Programming
# - metadata_key2: Chemistry
# -

# This Python introductions aims at readers such as chemists and engineers with some programming background. Its intention is to give you a rough overview on the key features of the Python programming language. If you are completely new to programming, you may want to check this nice introduction first https://wiki.python.org/moin/BeginnersGuide/NonProgrammers.
#
# It is also hosted on the [google colab platform](https://colab.research.google.com/drive/1_qg3wu0dtF4d5aW-R4hyMFqyY6zgm0ra) and only a web browser is needed to start it.
#
# We will discuss a bit the differences to other languages, but we will also explain or provide links for most of the concepts mentioned here, so do not worry if some of those are not yet familiar to you.
#
# ## Some key features of Python
#
# *   Python is a scripting language. (There is no compiled binary code per default)
# *   It is  procedural (i.e. you can program with classic functions, that take parameters)
# *   it is object-oriented (you can use more complex structures, that can hold several variables) 
# *   it has some functional programming features as well (e.g. lambda functions, map, reduce & filter, for more information see https://en.wikipedia.org/wiki/Functional_programming)
#
#
#
# ## What makes Python special...
#
# * Indendation is used to organize code, i.e. to define blocks of code space or tabs are used (no curly brackets, semi-colons etc, no ";" or "{}")
# *   variables can hold any type
# *   all variables are objects
# *  great support for interactive use (like in this jupyter notebook here!)
# *   Many specialized libraries, in particular scientific [libraries](#Python-Libraries) are available, where the performance intensive part is done by C/C++/Fortran and the control/IO is done via Python

# + [markdown] colab_type="text" id="gt2T1UdwtZGm"
# ## *Assignment* of a variable

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 625, "status": "ok", "timestamp": 1582631737569, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="TqIM7tthoDgH" outputId="0eec0b3e-efe7-4b74-d661-9fb0f04a0e26"
a = 1.5  # click the cell and press SHIFT+RETURN to run the code. This line is a comment 
a

# + [markdown] colab_type="text" id="C6y-JSxergP4"
# All variables are objects, use type() function to get the type. In this case: `a` is of the type "float" (short for floating point number). Comments are declared with the hashtag `#` in Python.
#
#
#
#

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 566, "status": "ok", "timestamp": 1582575877314, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="6t1Uos44oVNO" outputId="4a49d67b-4fcc-4076-de02-9c74ed2db5c1"
type(a) 

# + [markdown] colab_type="text" id="837HpOMAreUQ"
# Variables can be easily re-defined, here variable `a` becomes an integer:

# + colab={} colab_type="code" id="ABH7MxnYoYcM"
a = 1 

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 793, "status": "ok", "timestamp": 1576145793516, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="hy9RKaazsBQQ" outputId="e33203d4-e4f5-4ad3-9985-43581755887b"
type(a) 

# + [markdown] colab_type="text" id="XBwOiyo4w58O"
# The type of a variable is determined by assignment!
# There are no context prefixes like @, %, $ like in e.g. Perl
# ___
#
# ## A simple Python program
#
# Below is a very simple Python program printing something, and demonstrating some basic features. A lot of useful functionality in Python is kept in external libraries that has to be imported before use with the `import` statement. Also, functions have of course to be defined prior to use.
#
# By the way, note how identation is used to define code blocks. In Python you can use either spaces or tabs to indent your code. In Python3 mixing of tabs and spaces is not allowed, and the use of 4 consecutive spaces is recommended.

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 787, "status": "ok", "timestamp": 1576145793517, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="qrT8VK-A4hq8" outputId="4d7896f1-c7a1-4ec6-915e-9a8d16b2ea05"
# import a library
import os

# definition of a python function
def hello():
  # get current path as a string and assign it to variable
  current_dir = os.getcwd()
  # concatentate strings and print them
  print('Hello world from '+current_dir+' !')

# do not forget to call the function
hello()

# + [markdown] colab_type="text" id="NecQYFzD6dn6"
# If we were not in an interactive session, we would save this chunk of code to a file, e.g. `hello_word.py` and run that by invoking:<br>
# `python hello_word.py`<br> on the command line.
#
# ___

# + [markdown] colab_type="text" id="FMvnQhNY2Ult"
# ## `IF` statement
#
# `if` statements are pretty straightforward, there is no "THEN" and indentation helps to group the `if` and the `else` (or `elif` means `else if`) block.

# + colab={} colab_type="code" id="3i7TXaVe2SF2"
a = 3.0
if a > 2:
  print(a)
  if not (isinstance(a,int)):
    print("a is not an integer")
else:
  print("Hmm, we should never be here...")

# + [markdown] colab_type="text" id="L5d7lN8u3CsT"
# Since Python 3, the `print` statement is a proper function, in Python 2 one could do something like (i.e. without parentheses): 
#
# `print "a is not an integer"`
#
# which is no longer possible. It is strongly recommended to use Python 3 as Python 2 is no longer maintained and many external libraries have switched meanwhile competely to Python 3.
#
# Logical negation: `if not`
#
# Checking of variable type: `isinstance(variable,type)`

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 775, "status": "ok", "timestamp": 1576145793518, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="OcEzxzvlJQFY" outputId="69cd3103-ec48-4c02-dfaa-2bee0fe4da24"
isinstance(a,float)

# + [markdown] colab_type="text" id="dUxBsO5P7M3j"
# ___

# + [markdown] colab_type="text" id="P5evSBMOJvfI"
# ## `FOR` LOOPS
#
#

# + colab={"base_uri": "https://localhost:8080/", "height": 187} colab_type="code" executionInfo={"elapsed": 768, "status": "ok", "timestamp": 1576145793518, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="vKg8mhFfJ2ch" outputId="717f7c05-de20-4256-e106-75d211e90b76"
for i in range(10):
  print(i)

# + [markdown] colab_type="text" id="srN43DL9J8t4"
# The Python `range` function is somewhat special and for loops look somewhat different, than in other languages:
#
# *  **Python**: `for i in range(start=0, stop=10, step=1):`
# *  **JAVA/C**: `for (int i=0; i<10; i++) {}`
# *  **Fortran**: `do i=0,9, end do`
#
# Go on and manipulate the code above to check the effects.
#
# Looping over lists (which will be explained below) is quite simple as well:
#

# + colab={"base_uri": "https://localhost:8080/", "height": 68} colab_type="code" executionInfo={"elapsed": 764, "status": "ok", "timestamp": 1576145793519, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="qhzBIMNnKh9M" outputId="796e2c6a-63ec-401c-a318-5172f31dad71"
drugs = ['ibuprofen','paracetamol','aspirin']
for d in drugs:
  print(d)

# + [markdown] colab_type="text" id="A-8LtPqJKuY0"
# Some standard keywords are used to control behaviour inside the loop:
#
# *   **continue**: continue to next iteration of the loop
# *   **break**: leave/exit the loop
#
#

# + colab={"base_uri": "https://localhost:8080/", "height": 51} colab_type="code" executionInfo={"elapsed": 758, "status": "ok", "timestamp": 1576145793519, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="iYk7me1uKKOh" outputId="40ea6ebb-9667-4332-ffd2-0df748ab7577"
for d in drugs:
  if d=='paracetamol': continue
  print(d)

# + [markdown] colab_type="text" id="FN99_IjJ_YNY"
# ___
# ## Python Data Types
#
# | type | example | comment |
# | --- | --- | --- |
# | int | i=1 | Integer: 0,1,2,3 |
# | boolean | b=False | bolean value (True/False) |
# | float | x=0.1 | floating point number |
# | str | s = "how are you?" | String |
# | list | l = [1,2,2,50,7] | Changeable list with order |
# | set  | set([1,2,2,50,7])==set([1,2,50,7]) | Changeable set (list of unique elements) without order |
# | tuple | t = (99.9,2,3,"aspirin") | "Tuple": Unchangeable ordered list, used e.g. for returning function values  |
# | dict | d = {“hans“: 123, “peter“:344, “dirk“: 623} | Dictionary to save key/value pairs |
#
#
# The table shows the most important data types in Python. There are more specialized types e.g. https://docs.python.org/3/library/collections.html.<br>
# Some useful data types are provided by external libraries, such as `pandas` (Python for data analysis: https://pandas.pydata.org/)
#
# In general, the object oriented features in Python can be used to declare your own and special types/classes.
#
#
# ___
# ## Lists
#
# In Python a list is a collection of elements that are ordered and changeable.
#

# + colab={} colab_type="code" id="BTfP87W9DKsy"
integer_list = [10,20,0,5]
mixed_list = ["hello",1,5.0,[2,3]]


# + [markdown] colab_type="text" id="3pt4eT4XDcv_"
# List elements can themselves be a list and can contain different types.<br>
# Accessing elements in the list is done via their indices (position in the list):

# + colab={"base_uri": "https://localhost:8080/", "height": 68} colab_type="code" executionInfo={"elapsed": 978, "status": "ok", "timestamp": 1576145793753, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="iZhXoJ7fDhGH" outputId="eaeca9f0-9584-44ae-f111-d41f27c0264d"
print(integer_list[2])
print(integer_list[1:3])
mixed_list[-1]

# + [markdown] colab_type="text" id="FxcfozF0DqVn"
# Note, how indexing starts at index 0, which is the first element in the list. <br>
# The `[1:3]` operation in the example is called slicing and is useful to get subsets of lists or arrays.<br>
# The last element of an array can be accessed with the index `-1`.<br><br>
# Manipulating and working with lists:

# + colab={"base_uri": "https://localhost:8080/", "height": 51} colab_type="code" executionInfo={"elapsed": 972, "status": "ok", "timestamp": 1576145793754, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="HbrF74d9K1i5" outputId="951723d1-8a2f-40d9-9c13-53cec6a5329d"
integer_list = [5,10,20,0,5]
integer_list.append(42)
print(len(integer_list))
integer_list



# + [markdown] colab_type="text" id="70cuqJdeLQ8m"
# Lists can be sorted:

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 966, "status": "ok", "timestamp": 1576145793755, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="X1hFl7ebLEg-" outputId="6377ffe4-7496-4945-a255-accfacfb326f"
integer_list.sort(reverse=True)
integer_list

# + [markdown] colab_type="text" id="au9B0KCSLY_O"
# Check if some element is contained within the list or find its index:

# + colab={"base_uri": "https://localhost:8080/", "height": 51} colab_type="code" executionInfo={"elapsed": 961, "status": "ok", "timestamp": 1576145793755, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="9d4zwYGoLYTt" outputId="23e8f154-aefb-472e-ed89-97fc54ca566e"
print(10 in integer_list)
print(integer_list.index(10))

# + [markdown] colab_type="text" id="3b9_w852Llmt"
# List can be turned into sets (only unique elements):
#
# > Indented block
#
#

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 956, "status": "ok", "timestamp": 1576145793755, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="YwTwMgdSLoYk" outputId="00b38e49-3ee9-4e86-ac06-f11f792e54c4"
set(integer_list)

# + [markdown] colab_type="text" id="fzrVtXdPMBVE"
# ## Dictionaries
#
# Dictionaries are very handy data types and consists of key-value pairs. They may also be called maps or associatve arrays.

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 952, "status": "ok", "timestamp": 1576145793756, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="z9qhRgL8Mlia" outputId="d9dcae20-1d54-4fed-bcd7-f61a7fc50164"
en_de = {'red':'rot', 'blue':'blau'}
en_de['black'] = 'schwarz'
en_de['cyan'] = None
en_de

# + [markdown] colab_type="text" id="r3XnkRO0Q19e"
# Dictionaries are a collection of key, e.g. 'red' and value, e.g. 'rot' pairs, where both can of course be of different types.<br> It is important to note that they maintain no specific order. For an ordered dictionary use a special type `OrderedDict` (https://docs.python.org/3/library/collections.html#collections.OrderedDict).<br><br>
# There are several ways of accessing dictionaries:
#

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 947, "status": "ok", "timestamp": 1576145793756, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="2vhfwZv6SAnJ" outputId="826daba3-7ae3-4d04-cd86-667aa3b4f31f"
en_de['red']


# + [markdown] colab_type="text" id="2yP-dtVXSHAo"
# One can easily iterated over an dictionary:

# + colab={"base_uri": "https://localhost:8080/", "height": 85} colab_type="code" executionInfo={"elapsed": 943, "status": "ok", "timestamp": 1576145793757, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="Q2YEcP-9SKkR" outputId="5b91ec05-ce87-45a0-<KEY>"
for key in en_de:
    print(key, en_de[key])

# + [markdown] colab_type="text" id="I00zPwoDSQYc"
# And they are used a lot in Python, e.g. the current environmental variables are saved in dictionary (`os.environ`):

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 939, "status": "ok", "timestamp": 1576145793758, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="1FPlx2LSSing" outputId="d50ec6ab-ab23-4bf7-cd9a-7898ae65fca0"
import os
os.environ['PATH']


# + [markdown] colab_type="text" id="9MBJ91q1UD7a"
# ## Python functions
#
# Python functions are declared with the `def` keyword followed by a function name and a parameter list. Within the parameter list default parameters can be specified:

# + colab={"base_uri": "https://localhost:8080/", "height": 51} colab_type="code" executionInfo={"elapsed": 935, "status": "ok", "timestamp": 1576145793758, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="0Qn5EDjPUKnA" outputId="542b741f-121f-4f11-b10a-f9cd97598dbc"
def test_function(name='paracetamol'):
    print('There is no '+name+' left.')

test_function()
test_function('aspirin')


# + [markdown] colab_type="text" id="BWHctiBuMQGa"
# Return results of function with the `return` statement, in this case we generate a string with the function and print it later, i.e. outside the function:

# + colab={"base_uri": "https://localhost:8080/", "height": 51} colab_type="code" executionInfo={"elapsed": 931, "status": "ok", "timestamp": 1576145793759, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="EsCwE7PtMqOH" outputId="7ee6f071-965e-40fa-d822-1becbc9cedba"
def test_function(name='paracetamol'):
    answer = 'There is no '+name+' left.'
    return answer

print(test_function())
print(test_function('aspirin'))

# + [markdown] colab_type="text" id="ykjpukjnNGy_"
# Its also possible to return several return values as a tuple, e.g.<br>
# `return answer,status`
# ___
# ## Type conversion & casting
#
# Sometimes it is necessary to convert variables from one type to another, e.g. convert a `float` to an `int`, or a an `int` to an `str`. That is where conversion functions come into play. Unlike in other languages types are converted via functions, where the return value is the converted type.
#
# | function | converting from | converting to |
# | --- | --- | --- |
# | int() | string, floating point | integer |
# | float() | string, integer | floating point |
# | str() | integer, float, list, tuple, dictionary  | string |
# | list() | string, tuple, dictionary | list |
# | tuple() | string, list | tuple |
#
#
#

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 926, "status": "ok", "timestamp": 1576145793759, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="ZkkqJCBjQS_A" outputId="9c6d1fe2-6421-4b29-bc37-70b5e68cc362"
import math # not sure why one wants to do this :-)
int(math.pi)

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 922, "status": "ok", "timestamp": 1576145793760, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="TVmvcBHGQmLw" outputId="d75fc131-5ec5-49c0-ad83-73033a337e9d"
float('1.999')

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 917, "status": "ok", "timestamp": 1576145793760, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="wYGoiV59Qq6T" outputId="44660101-edd9-4d00-e64e-369cbf6b83c5"
list('paracetamol') # create a list of characters!

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 912, "status": "ok", "timestamp": 1576145793761, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="tUN5uL2zQ07v" outputId="acb10d0a-e32c-4a50-fda7-4d4782ab8bed"
list((1,2,3,6,8)) # creates a list from a tuple

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 907, "status": "ok", "timestamp": 1576145793761, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="IcKN0-xIQZxY" outputId="222a1794-8328-42f2-d925-9205b1127317"
'the answer is '+str(42) # before concatentation integer or float should be converted to string

# + [markdown] colab_type="text" id="ws8FTkslQLdL"
# Implicit (automatic) conversion takes place in Python to avoid data loss or loss in accuracy:

# + colab={"base_uri": "https://localhost:8080/", "height": 85} colab_type="code" executionInfo={"elapsed": 900, "status": "ok", "timestamp": 1576145793762, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="CpPQyGnoSB1F" outputId="9f4d3038-3223-4b73-f63f-23f14ae5cbbe"
a = 2
print(type(a))
b = 4.5
print(type(b))
c = b / a
print(type(c)) 
c


# + [markdown] colab_type="text" id="EklKMdXTTJox"
# Note, that in this example the implicit conversion avoid data loss by conversion of integer `a` to a floating point number.
# ___
# ## Object oriented progamming
#
# Object oriented programming is a huge field of its own, and we will not go into details here. Objects are kind of complex variables that themselves can contain different variables and functions. There a implemented in the code via so-called classes. In a way a class defines the behaviour of objects and specific objects are created during runtime. Classes relate to objects as types (e.g. `int`) to a specific variable (e.g. `a`). As such, in Python there is no real difference between a class and a type: Each variable is an object of a certain type/class.<br>
# New classes in Python are defined the following way:
#

# + colab={} colab_type="code" id="cDd3exDTVuDD"
class Greeting:     
        def __init__(self, name):
            self.name = name
            
        def say_hello(self):
            print('Hi '+self.name)


# + [markdown] colab_type="text" id="8zXMpfkhWAiP"
# This code has created the `class` Greeting with its function `say_hello`. `__init__` defines the so called constructor, which is called when the object is created. Object variable are saved using `self` keyword.<br>
# Objects can be created and its function be called:
#

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 1088, "status": "ok", "timestamp": 1576145793959, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="oDoU7Or8WrK2" outputId="47c7f7b5-0353-4584-b3d2-f272d256a71f"
x1 = Greeting('Greta')
x1.say_hello()

# + [markdown] colab_type="text" id="Dfc6-upPXEXo"
# Object variables can be accessed directly:

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 1083, "status": "ok", "timestamp": 1576145793960, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="NZEB0f2EXB8f" outputId="64fd222c-6d6e-4944-8623-f20247dc1174"
x1.name

# + [markdown] colab_type="text" id="Cil9qC-TXOcF"
# ## Import statements in Python
#
# Python comes with a lot of useful libraries. Some are contained in a default installation, some have to be installed with tools like `pip` or `conda`. The most conveniant way to install new packages/libraries in particular for scientific purposes is to use an installation like Anaconda (https://www.anaconda.com/).
#
# Once a library is available it can be imported with an `import` statement. Import the whole library:
#
#

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 1078, "status": "ok", "timestamp": 1576145793961, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="YxrzEC23YWtA" outputId="89d46e7c-20e5-4ffa-a7de-c0b900240ac2"
import math
print(math.cos(math.pi))

# + [markdown] colab_type="text" id="09dBGtkaYc3M"
# Import a module or function from a library:
#
#

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 1072, "status": "ok", "timestamp": 1576145793961, "user": {"displayName": "<NAME>", "photoUrl": "", "userId": "06846131955017515958"}, "user_tz": -60} id="MXR28IudYogH" outputId="07799bc2-b109-4e9e-df02-88dd93451254"
from math import cos, pi
print(cos(pi))

# + [markdown] colab_type="text" id="yCTL6o0yYuc2"
# Import and use an acronym for use:

# + colab={} colab_type="code" id="kw056Vq8Y1kp"
import numpy as np
array = np.asarray([1.0,2.0,1.0])

# + [markdown] colab_type="text" id="IH2fWU0pZkgh"
# ___
# <a id='libraries'></a>
# ## Python Libraries
#
# There a lot of useful Python libraries available. Some of those have been established a kind of standard for scientific applications:
#
# *   NumPy: Array & matrices & linear algebra (https://numpy.org/)
# *   SciPy: Numerical routines for integration, optimization, statistics etc. (https://www.scipy.org/scipylib/index.html)
# *   matplotlib: a Python 2D plotting library which produces publication quality figures( https://matplotlib.org/)
# *   scitkit-learn: machine learning in Python (https://scikit-learn.org/stable/)
# *   Pandas: data structures ("dataframes") and data analysis tool (https://pandas.pydata.org/)
#
# For chemistry related applications:
#
# *   RDKit: open-source cheminformatics (https://www.rdkit.org/)
# *   ASE: setting up, manipulating, running, visualizing and analyzing atomistic simulations (https://wiki.fysik.dtu.dk/ase/)
# *   PySCF: collection of electronic structure programs (https://sunqm.github.io/pyscf/)
#
#

# + [markdown] colab_type="text" id="nwtZ4HZfcSTQ"
# ___
# ## Editors and development environments
#
# If Python code is not written interactively within the browser, as for example for larger projects, there are different editors and environments available to write Python code:
#
# * vi(m): text editor contained in most linux distributions
# * Kate (Linux): handy text editor, highlighting for many different languages
# * NotePad++ (Windows):  https://notepad-plus-plus.org/
# * Spyder:  Integrated development environment (IDE), shipped with anaconda (https://www.spyder-ide.org/)
# * PyCharm:  Powerful IDE, particular for python (http://www.jetbrains.com/pycharm)
# * PyDev: Plugin for Eclipse IDE, i.e. auch für Java & C/C++ (https://www.pydev.org/download.html)
#
# ___
#

# + [markdown] colab_type="text" id="dwrBShEcg-5x"
# ## Python - Advanced topics & concepts
#
# A lot of interesting and useful stuff has been left out in this short introduction due to the sake of brevity. There is a lot more to Python, here a just a few keywords to look up:
#
# *   Exceptions
# *   List comprehensions
# *   Lambda expressions
# *   Logging
# *   Multiprocessing & multithreading
# *   JIT compiler (http://numba.pydata.org/)
#
# Python tutorials:
# *  Google Python introduction (https://developers.google.com/edu/python/)
# * Scientific Python introduction (https://scipy-lectures.org/intro/)
#
#

StarcoderdataJupyterScriptsDedupFiltered