# -*- coding: utf-8 -*-
"""
Created on Sun Feb 17 22:07:24 2019

@author: Márton Ispány

Python nyelvi alapok
"""

# Alapműveletek
print(1+2+3);
print((4**2-6)/(2*4));  #  +,-,*,/,**

# Változók
# egész számok
a = 10;
print(a);
print(type(a));  # integer 

# valós számok
b = 2.9+3.1;
print(b);
print(type(b));   # float

# Komplex számok
c = 2+3j; 
print(c);
print(type(c));   # complex j imaginárius egység

d = (b+c)/a;
print(d);
print(type(d));   # complex marad
print(d.real);
print(d.imag);
e = complex(3,-1);  # komplex számok másik megadási módja
print(d+e);    # két komplex szám összege
print(d/e);    # két komplex szám hányadosa
print(e.conjugate());  # komplex szám konjugáltja

# Függvények (built-in)
print(pow(2,3));   # hatvány
print(max(a,b));   # maximum
print(min(a,b));   # minimum
print(abs(c),abs(d));  # abszolút érték

# Stringek
s = "Gépi tanulás";
print(s);
print(s+' a gyakorlatban');  # konkatenáció
print(len(s));     # string hossza

a = 2;
b = 15.30;
print(s+" %1d. gyakorlat: Hétfő %6.2f" % (a,b));

# String függvények
ss = s.split();   # felbontás szavakra listába
print(ss);
s1 = ' '.join(ss);  # konkatenáció space-szel
s1 = s1.replace('tanulás','intelligencia');

# Stringek több sorban
s2 = """Gépi
tanulás""";
print(s2);
s3 = "Gépi\ntanulás";


# Listák
l=[4,5,6];
col = ['piros','kék','zöld','barna'];
print(l+col);    # két lista konkatenációja
print(col*5);    # lista replikációja

fives = range(10,100,5);
print(fives);   # Mit nyomtat ki?
print(fives[0],fives[5],fives[3:7]);

vegyes = l+col;    # tücsök és bogár együtt
print(vegyes[1],vegyes[4]);  # hivatkozás listaelem(ekre)
print(vegyes[2:5]);
print(vegyes[-2]);

# Beágyazott listák, lista a listában
l1 = [l,col,[1,2,3]];
print(l1[1]);
print(l1[1][0]);

# További műveletek listákra
print(len(l));   # lista hossza
del l1[2];   # lista egy elemének törlése 
print(l1);
ans = 5 in l;  # tartalmazás tesztelése
ans = 2 in l;

# Listák szeletelése
l = [1,2,3,4,5,11,12,13,14,15];
print(l[2:6]);   # 3-tól a 6-ik elemig
print(l[2:-2]);   # a negatív index is működik
print(l[-7:8]);   # fordítva is
print(l[:5]);     # az első 5 elem
print(l[-3:]);    # az utolsó 3 elem

# Alapvető metódusok listákra
l = [4,5,6]; 
l.append(7); l.append(7);  # új elem hozzáadása
print(l.count(7));    # egy elem előfordulási gyakorisága 
print(l.index(7));    # egy elem első előfordulási indexe
l.remove(5);    # egy elem törlése 
l.reverse();    # lista megfordítása
l.sort();   # lista rendezése

# Mutable versus immutable objektumok
l = [1,2,3,4,5,11,12,13,14,15];
l[1:3] = [8];
l[6:] = [6,7];    # lista megváltoztatható (értékadással)

s = "póniló";
print(s[:4]);
s[:4] = 'vízi';   # hibás, a stringet nem lehet így megváltoztatni
s = 'vízi'+s[4:];

# Szótárak (dictionaries)
d = {};   # üres szótár
d["NN"] = "neurális háló";
d['SVM'] = 'támaszvektor gép';
d['DT'] = 'döntési fa';
print(d);
print(d['DT']);

# Alapvető metódusok szótárakra
d1 = d.copy();    # szótár másolása
d1.clear();    # szótár összes elemének törlése
print(d.keys());   # a szótár összes kulcsa
print(d.values());   # a szótár összes értéke
print(d.items());  # a szótár összes eleme

# Tömbök (tuples) mint immutable objektumok
t = (1,2,'három',"négy");
print(t);
print(t[2]);
t[2] = 2;

# Hozzárendelés és hivatkozás objektumokra
l = [4,5,6];
l1 = l;
l1[1] = 2;   # az l1 lista 2. elemének megváltoztatása
a,b,c = 4,5,6;     # többszörös hozzárendelés

# Alapvető programozási szerkezetek
# Elágaztatás
x = 0;     # próbáld ki 3, -4 és 0 számokra
if x>0:
    print("pozitív")
elif x==0:
    print(x)
else:
    print("negatív");
    
# Ciklusok
for i in range(10):    # standard numerikus ciklus
    print(i);
    
for i in "abcdef":     # ciklus stringen
    print(i);
    
l = ['piros','kék','zöld'];
for col in l:       # ciklus listán
    print(col);
    

# Numerikus számítások Numpyban
import numpy as np;   # Numpy importálása

# Műveletek tömbökkel (array) mint Numpy objektumokkal
a = np.array([1,2,3,4,5]);
b = np.array([6,7,8,9,10]);
a1 = np.array([[1],[2],[3],[4],[5]]);
a2 = np.array([[1,2,3,4,5]]);
print(a+b);
print(b-a);
print(a*b);
print(b/a);

# Beépített konstansok
print(np.pi,np.e);

# Egyszerű műveletek tömbökkel
c = np.pi*a;
print(c);   # tömb szorzása konstanssal
print(np.sin(c));  # tömb függvénye
print(np.size(a));  # tömb mérete
print(type(a));      # típus kiírása
print(a.itemsize);  # egy tömb elem mérete byte-okban
print(np.shape(a));  # tömb mérete numpy függvénnyel
print(a.shape);     #  tömb mérete metódussal kiíratva
a1 = a.tolist();    # tömb Python listává alakítása
print(a[2]);   # tömb egy eleme

M = np.array([[3,2],[1,5],[2,6]]);  # kétdimenziós tömb
print(M.shape);
print(M[1,0]);   # kétdimenziós tömb egy eleme
print(M[2]);   # kétdimenziós tömb egy sora
M1 = M.flat;    # 2D tömb kinyújtása
M2 = np.ravel(M);  # 2D tömb kinyújtása, a kettő nem ugyanaz!
M2[5] = 10;    # módosítja az eredeti tömböt is! (mutable + ugyanarra a címre mutatnak)

# Tömbök szeletelése
print(M[1:3,1]);

# Tömbök létrehozása
first10 = np.arange(0,10,1);  # első 10 nemnegatív egész, hasonló a range-hez de nem ugyanaz!
first10b = range(0,10,1); print(first10b);print(list(first10b));
data0 = np.zeros((100,50));  # csupa 0
data1 = np.ones((50,100));   #  csupa 1
unit_matrix = np.eye((5));   #  egységmátrix
unit_matrix1 = np.identity(5);  #  egységmátrix máshogy

# Mátrixműveletek
N = np.array([[1,2],[4,7],[3,1]]);
S = M+N; S1 = np.add(M,N);
D = M-N; D1 = np.subtract(M,N);
P = M*N; P1 = np.multiply(M,N);
R = M/N; R1 = np.divide(M,N);

v = np.array([4,6]);
res = M*v;
res1 = np.multiply(M,v);
res2 = np.dot(M,v);




