#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Nov 21 08:48:02 2017

@author: christianehelzel
"""

"""
Hinweis zu dieser Datei: 
Aufgrund der vielen Fehlermeldungen und der 'input'-Aufrufe, ist es viel
einfacher diese Datei als python-Datei zu studieren. Daher gibt es keine
PDF-Version
"""

#%%
import numpy as np
#%%
# Error handling

# Jeder kennt es: Fehlermeldungen in Python-Programmen

#%%
# SyntaxError
# falsche Syntax wird angezeigt
print 'Hallo, Fehlermeldung'


#%%
# ValueError 

n = int(input("n = ?"))

#%%
# mögliche Fehlerquelle: Dimensionen passen nicht
# ValueError: shapes(1,2) and (3,1) not aligned: 2 (dim 1) != 3 

v = np.array([1,0,0]).reshape(3,1)  # Spaltenvektor
u = np.array([0,1]).reshape(1,2)    # Zeilenvektor

print(u@v)

#%%
# Division durch 0:
# ZeroDivisionError: float division by zero

x = 10.
y = 0.
print(x/y)

#%%
# factorial(5.5) liefert
# RecursionError: maximum recursion depth exceeded in comparison

def factorial(n):
    print("factorial is called with n=",n)
    if n == 1:
        return 1
    else:
        res = n * factorial(n-1)
        print("intermediate result for ", n, " * factorial(" ,n-1, "): ",res)
        return res	



#%%
# Wir möchten nun selbst Programme schreiben, die eine sinnvolle 
# Fehlermeldung ausgeben. In einigen Fällen werden wir damit auch den 
# Programmabbruch verhindern.        
         
# Beispiel: Berechne den Quotienten aus zwei Zahlen

print("Berechne den Quotienten zweier Zahlen")


x = float(input("Geben Sie den Dividend ein!"))
y = float(input("Geben Sie den Divisor ein!"))
z = x/y
print("{0:f} / {1:f} = {2:f}".format(x,y,z))

#%%
def readfloat():
    while True:
        try:
            x = float(input("Geben Sie eine Zahl ein! "))
            return x
        except:
            print("Dies ist keine zulässige Eingabe. \
                  Versuchen Sie es noch einmal...")
 
          
x = readfloat()
y = readfloat()
    
try: 
    z = x/y
    print("{0:f} / {1:f} = {2:f}".format(x,y,z))
except:
    print("Bei der Berechnung von x/y ist ein Fehler aufgetreten")

#%%    
    
#%%
while True:
    try:
        x = float(input("Geben Sie den Dividend ein! "))
        break
    except ValueError:
        print("Dies ist keine zulässige Eingabe. \
                  Versuchen Sie es noch einmal...")
    
while True:
    try:
        y = float(input("Geben Sie den Divisor ein! "))
        break
    except ValueError:
        print("Dies ist keine zulässige Eingabe. \
                  Versuchen Sie es noch einmal...")

try: 
    z = x/y
    print("{0:f} / {1:f} = {2:f}".format(x,y,z))
except ZeroDivisionError:
    print("Bei der Berechnung von x/y ist ein Fehler aufgetreten")

#%%    
# Wir könne nun auch das folgende kurze Programm schreiben:

try:    
    x = float(input("Geben Sie den Dividend ein! "))
    y = float(input("Geben Sie den Divisor ein! "))
    z = x/y
    print("{0:f} / {1:f} = {2:f}".format(x,y,z))
    
except ValueError:
    print("Ihr Eingabewert ist nicht zulässig!")  
except ZeroDivisionError:
    print("Division durch Null!")
except:
    print("Ich bin ratlos...")   
    

#%% 
# Berechne die Summe der Zahlen von 1 bis n
    
# assert-Anweisung: Dient zur Abfrage von Benutzerdefinierten Einschränkungen
# assert: behaupten, erklären, feststellen, ...

     
def sum(n):
    assert int(n)-n==0, "n must be integer"
    sum = int((n+1)*n/2)
    return sum
#%%
sum(100)

#%%
sum(10.5)
