import timeit
import time
import numpy as np
import matplotlib.pyplot as plt
from aufg38 import LR_kompakt

# %% Daten in Datei schreiben

# open(file, mode)
# mode : 'w' schreiben (write)
#        'a' anhängen  (append)
#        'r' lesen     (read)

with open('text.txt', 'w') as f:
    f.write('hallo\n')  # 1. Zeile
    for k in range(9):  # Zeilen 2 bis 10
        f.write(f'{k} & {k**2}\n')  # \n für Zeilenumbruch

# Das with statement sorgt dafür, dass der Datenstrom 
# ordentlich geschlossen wird

# %%
# Alternativ kännte man das auch so machen

f = open('text2.txt', 'w')
try:
    f.write('hallo\n')
    for k in range(9):  # Zeilen 2 bis 10
        f.write(f'{k} & {k**2}\n')  # \n für Zeilenumbruch
finally:
    f.close()


# %% Daten aus Datei auslesen
x = np.array([])
y = np.array([])
with open('text.txt', 'r') as f:
    for i, line in enumerate(f):
        if i == 0:
            pass  # wir lassen die erste Zeile aus
        else:
            xs, ys = line.split("&")
            x = np.append(x, float(xs))
            y = np.append(y, float(ys))

plt.plot(x, y, 'ro')

# %% Daten aus Datei auslesen
x = np.array([])
y = np.array([])
with open('text.txt', 'r') as f:
    for i, line in enumerate(f):
        print(i, line)
        if i == 0:    
            pass  # wir lassen die erste Zeile aus
        else:
            xs, ys = line.split("&")
            x = np.append(x, float(xs))
            y = np.append(y, float(ys))


# %% numpy array in Binärdatei abspeichern
np.save('data', np.array(range(9)).reshape((3, 3)))
a = np.load('data.npy')
print(a)



# %%
with open('data.txt', 'w') as f:
    for k in range(3):
        f.write(f'{k} {np.sqrt(k+.5)}\n')

# wenn alle Zeilen in der Datei nur eine feste Anzahl von Zahlen enthalten
# und diese durch Leerzeichen (default) getrennt sind geht das auch einfacher
x = np.loadtxt('data.txt')
print(f'Daten in data.txt als array x=\n{x}')

x, y = np.loadtxt('data.txt', unpack=True)
print(f'spaltenweise data.txt \n x=\n{x} \n y=\n{y}')



# %%
x = np.loadtxt('text.txt', skiprows=1, delimiter='&')
print(x)



# %% Zeit-/Aufwandmessung
# Die methode timeit(stmt=pass, number=1000000) aus dem Modul timeit 
# führt den Befehl "stmt", "number" mal
# durch und gibt die dafür benötigte Zeit in Sekunden zurück

m = 5  # Anzahl der Durchläufe
zeit = timeit.timeit(stmt='time.sleep(1)', number=m)
print(f' vergangene Zeit {zeit/m} s')

# %% Aufwand LR Zerlegung
# hier wird zusätzlich ein der Befehl aus "setup" ausgeführt bevor die Zeit für  
# "stmt" gemessen wird. 

ns = np.unique(np.round(1.06**np.arange(50, 117)))
zeit = np.zeros_like(ns)

for i, n in enumerate(ns):
    n = int(n)
    zeit[i] = timeit.timeit(stmt="LR_kompakt(A, method='argmax')",
                            setup="A = np.random.rand(n, n)-.5 + 3*np.eye(n)",
                            number=m, globals=globals())

# %%
fig = plt.figure(1)
ax = fig.gca()
ax.loglog(ns, zeit, 'x')
ax.loglog(ns, 1e-9*ns**3)
ax.set_xlabel('Matrixgröße')
ax.set_ylabel('Rechenzeit (s)')
