У фајлу простог назива 'kod' налазе се модули, или функције јасно дефинисаног улаза, смисла и излаза за употребу из других Питонових програма. Замисао је да свака може вршити делове евентуално већег посла, али тако да се ови парчићи могу међусобно позивати, разумети и решавати задатке са што мање комуникације са вањским светом. То подразумева једну велику повезану гомилу, масу таквих.

Овде наводим само краће процедуре и то оне које користим за проверу резултата из алгебре. Све оне су у фајлу 'kod' који почиње са дефинисањем путање до његовог смештаја:

import sys
sys.path.append('D:\Python')
import kod
import math
import numpy as np
from numpy.linalg import eig

Последња три „импорта“ нису неопходна, јер их можете по потреби стављати у поједине модуле. Није сметња дуплирати их. Наставак временом није ствар „велике вештине“ програмирања каквим би нам се у почетку могао учинити, колико он доспева у домен потреба, затим маште и забаве — те последње понекад опојне попут дроге.

1. Рачун

1.1. Факторизација се постиже са 'f = kod.faktor(n, ind)', ако се тражи растављање на чиниоце (природног) броја 'n', а 'ind' је индикатор улаза/излаза. Индикатори 0 или 1 траже унос броја тастатуром, а 0 или 2 штампају листу фактора на екран. Када се штампа излаз, непотребан је 'f'.

#Faktorizacija datog broja
def faktor(n = 1, ind = 0):
    # ind = 0 - ulaz tastaturom, izlaz na ekran
    # ind = 1 - ulaz tastaturom, izlaz varijablom
    # ind = 2 - ulaz varijablom, izlaz na ekran
    # ind = 3 - ulaz varijablom, izlaz varijablom
    if ind in {0, 1}:
        n = int(input('Unesite prirodan broj: '))
    if not isinstance(n, int):
        print("Prirodan broj?")
        return
    if n < 1:
        print("Unesite pozitivan celi broj!")
        return
    broj = n
    lista = []
    while broj % 2 == 0:
        lista.append(2)
        broj = broj//2
    import math
    m = int(math.sqrt(broj))
    for x in range(3, m+1):
        while broj % x == 0:
            lista.append(x)
            broj = broj // x
    lista.append(broj)
    if ind in {0, 2}:
        print(lista)
        return
    return lista 

Тестирање програма: faktor », без параметара.

1.2. Матрице покреће 'w, v, d = kod.eigen(a, ind)'. До два улазна параметра 'a' и 'ind', са до три излазна 'v', 'p' и 'd'. Први од улазних је матрица за обраду (a = A), други је индикатор о улазу и излазу података. Први излазни параметар w = w(λ1, ..., λn) је листа својствених вредности дате матрице, други излазни је листа нормираних својствених вектора v = P(v1, ..., vn), а трећи је дијагонална матрица d = D(w). Када нема уноса, подразумевана је дијагонална матрица и индикатор нула. Индикатори 0 или 1 траже унос матрице тастатуром (ред r матрице и низ r² бројева са размаком између), а индикатор 0 или 2 даваће резултате на екрану. Када имате штампање на екран, не задајете излазне параметре.

# izračunava svojstvene veličine matrice a
def eigen(a = np.diag([1, 2, 3]), ind = 0):
    # ind = 0 - ulaz tastaturom, izlaz na ekran
    # ind = 1 - ulaz tastaturom, izlaz varijablom
    # ind = 2 - ulaz varijablom, izlaz na ekran
    # ind = 3 - ulaz varijablom, izlaz varijablom
    import math
    import numpy as np
    from numpy.linalg import eig
    if ind in {0, 1}:
        r = int(input('Red kvadratne matrice (rows of sqare matrix) = '))
        x = print('Unesite matricu, numbers with spaces in between: ')
        niz = [float(x) for x in input().split()]
        a = np.array(niz).reshape(r, r)
    dec = 14 # najviše decimala
    deta = np.linalg.det(a) # determinanta a
    deta = np.round(deta,decimals = dec) # zaokruživanje
    w,v = eig(a) # svojstvene vrednosti i vektori a
    p = np.array([v]) # pomoćna matrica p
    detp = np.linalg.det(p) # determinanta p
    detp = np.round(detp,decimals = dec) # zaokruživanje
    d = 0
    if detp != 0:
        pi = np.linalg.inv(p) # inverzna matrice P
        d = pi @ a @ p # dijagonalna, ulazne matrice A
        d = np.round(d,decimals = dec) # zaokruživanje
    if ind in {0, 2}:
        print('\nMatrica A:')
        print(a)
        print('\nDet A =', deta)
        print('\nEigenValues A =', w)
        print('EigenVectors A:') # normirani vektori
        print(v)
        print('\nPomocna matrica P :')
        print(p)
        print('\nDet P =', detp)
        if detp == 0:
            d = 0
            print('\nMatrica nema dijagonalnu!')
            return
        else:
            print('\nPomocna inverzna inv(P) :')
            print(pi)
            print('\nDijagonalna, D = inv(P)*A*P :')
            print(d)
            return
    return w, v, d

Ево и једног примера употребе овог модула — из Питоновог едитора 'Shell 3.11.0'. Прве две наредбе дефинишу путању до датотеке 'kod.py' у којој се налазе модули и функције. Трећа импортује 'kod', а у модулу је импортовање изворног Питоновог модула 'numpy', за дефинисање матричног рачуна, он се даље назива 'np'.

import sys
sys.path.append('D:\Python')
import kod
a = np.array([[0.7, 0.2, 0.1], [0.2, 0.6, 0.2], [0.1, 0.2, 0.7]]) # matrica
ind = 2
kod.eigen(a, ind)

Matrica A:
[[0.7 0.2 0.1]
 [0.2 0.6 0.2]
 [0.1 0.2 0.7]]

Det A = 0.24

EigenValues A = [1.  0.6 0.4]
EigenVectors A:
[[-5.77350269e-01 -7.07106781e-01  4.08248290e-01]
 [-5.77350269e-01 -1.58793522e-16 -8.16496581e-01]
 [-5.77350269e-01  7.07106781e-01  4.08248290e-01]]

Pomocna matrica P :
[[[-5.77350269e-01 -7.07106781e-01  4.08248290e-01]
  [-5.77350269e-01 -1.58793522e-16 -8.16496581e-01]
  [-5.77350269e-01  7.07106781e-01  4.08248290e-01]]]

Det P = [-1.]

Pomocna inverzna inv(P) :
[[[-5.77350269e-01 -5.77350269e-01 -5.77350269e-01]
  [-7.07106781e-01  1.57009246e-16  7.07106781e-01]
  [ 4.08248290e-01 -8.16496581e-01  4.08248290e-01]]]

Dijagonalna, D = inv(P)*A*P :
[[[ 1.   0.   0. ]
  [ 0.   0.6  0. ]
  [-0.  -0.   0.4]]] 

Улазни индикатор 'ind = 2' постављен је тако да нема улаза тастатуром, а да се излаз штампа на екран, па су бескорисни излазни параметри w, v и d. Објашњење дијагонализације матрице видите у наслову Спектрална теорема.

1.3. Полином дефинише једноставна функција 'p = polinm(a, x, ind)', где листом a = [an, an-1, ..., a0] задатих реалних или комплексних бројева (ak ∈ ℂ, где је k = n, n-1, ..., 1, 0) дефинишемо поједине коефицијенте полинома p(x) = anxn + ... + a1x + a0, као и њихов укупни број, тад степен n = 1, 2, 3, ... полинома. Друга варијабла је задати реалан или комплексан број x ∈ ℂ. Трећа је индикатор, 0 или 1 за унос тастатуром, 0 или 2 за штампање резултата на екран.

# Definisanje i formiranje vrednosti polinoma
def polinm(a = [1, 2, 3], x = 5, ind = 0):
    # ind = 0 - ulaz tastaturom, izlaz na ekran
    # ind = 1 - ulaz tastaturom, izlaz varijablom
    # ind = 2 - ulaz varijablom, izlaz na ekran
    # ind = 3 - ulaz varijablom, izlaz varijablom
    if ind in {0, 1}:
        print('p(x) = an*x^n + ... + a1*x + a0')
        print('Unesite koeficijente a polinoma (samo razmak između): ')
        a = [float(x) for x in input().split()]
        x = float(input('Unesite varijablu x: '))    
    p = 0
    for i, n in enumerate(a):
        p = p*x + a[i]
    if ind in {0, 2}:
        print(p)
        return
    return p 

Функција се може вишеструко позивати са константним коефицијентима a и корак по корак мењаном варијаблом x одређеним интервалом, рецимо у цртању графа, или тражења нуле итерацијом.

1.4. Распоређивање 'm' случајних бројева у низ 'z = podela(p, m, ind)' према вероватноћама 'p'. Овде је p = (p1, ..., pn) низ вероватноћа (из ℝ+, који не морају бити „расподела вероватноћа“). Број понављања опита је природан број m ∈ ℕ. Индикатори 'ind' = 0 или 1 дају улаз тастатуром, а 0 и 2 излаз на екран.

# Генерисање исхода по задатој расподели вероватноћа
def podela(p = [0.3, 0.2, 0.1], m = 12, ind = 0):
    # ind = 0 - ulaz tastaturom, izlaz na ekran
    # ind = 1 - ulaz tastaturom, izlaz varijablom
    # ind = 2 - ulaz varijablom, izlaz na ekran
    # ind = 3 - ulaz varijablom, izlaz varijablom
    import random # generator slučajnih brojeva
    random.seed(a=None, version=2) # inicijalizacija
    if ind in {0, 1}:
        print('Unesite raspodelu p verovatnoća (samo razmak između): ')
        p = [float(x) for x in input().split()]
        m = int(input('Unesite broj m ponavljanja opita: '))
    d = len(p)
    y = [0]*d
    z = [0]*d
    zbir = 0 # za formiranje niza zbirova
    for j,k in enumerate(p):
        zbir = zbir + k
        y[j] = zbir 
    for i in range(m):
        b = random.random() # slučajan broj od 0 do 1
        c = b*zbir       # slučajan broj od 0 do zbir
        for j,k in enumerate(y):
            if c <= k:
                z[j] = z[j] + 1
                break
    if ind in {0, 2}:
        print('Raspodela p =', p, 'od m =', m, 'brojeva je:')
        print(z)
        return 
    return z 

На пример, програм пуштен без параметара тражи унос тастатуром и штампа резулат на екран:

import kod
kod.podela()
Unesite raspodelu p verovatnoća (samo razmak između): 
0.5 0.3 0.2
Unesite broj m ponavljanja opita: 20
Raspodela p = [0.5, 0.3, 0.2] od m = 20 brojeva je:
[11, 6, 3]

Приметите да низ бројева тастатуром треба уносити без било каквих других знакова, осим размака између бројева и евентуално децималне тачке броја. Као варијабла низ је рецимо p = [0.3, 0.2, 0.1]. Излазни бројеви укупних исхода понављања појединих опита тек статистички су пропорционални улазним вероватноћама.

Други пример, са истим вероватноћама p = [0.5, 0.3, 0.2], али већим бројем m понављања опита:

  1. m = 200, z = [94, 65, 41] → z/m = (0.475, 0.325, 0.205),
  2. m = 2000, z = [1007, 589, 404] → z/m = (0.5035, 0.2945, 0.202),
  3. m = 20000, z = [9919, 6133, 3948] → z/m = (0.49595, 0.30665, 0.1974).

Понављањем добијаћете увек друге бројеве, али са све већим m количник z/m груписаће се око p. У вези са овим погледајте и „Силу вероватноће“ (8.3)

1.5. МиниМакс покреће 's, r, k = kod.minmax(a, ind)'. До два улазна параметра 'a' и 'ind', са до три излазна 's', 'r' и 'k'. Први од улазних је матрица за обраду (a = A) типа m×n који ће сам програм препознати, други је индикатор о улазу и излазу података. Први излазни параметар s је вредност коефицијента седласте тачке (еквилибријума) дате матрице, уколико она има такву; тада су следећа два излазна параметра r и k редни број ретка и колоне нађеног места седласте тачке. Индикатори 0 или 1 траже унос матрице тастатуром. Тада се уноси ред матрице, па квадратна матрица датог реда (низ бројева са размаком између). Индикатор 0 или 2 даваће резултате на екрану. Када имате излаз на екран, не задајете излазне параметре. Кратко, популарно објашњење МиниМакс матрица погледајте у мом блогу (Equilibrium II).

# Find min row then max col in matrix
def minmax(a = np.diag([1, 2, 3]), ind = 0):
    # ind = 0 - ulaz tastaturom, izlaz na ekran
    # ind = 1 - ulaz tastaturom, izlaz varijablom
    # ind = 2 - ulaz varijablom, izlaz na ekran
    # ind = 3 - ulaz varijablom, izlaz varijablom
    import math
    import numpy as np
    if ind in {0, 1}:
        m = int(input('Redova matrice (rows of matrix) = '))
        n = int(input('Kolona matrice (cols of matrix) = '))
        x = print('Unesite matricu, numbers with spaces in between: ')
        niz = [float(x) for x in input().split()]
        a = np.array(niz).reshape(m, n)
        print('\nUneli ste:')
        print(a)
    else:
        m = a.shape[0];
        n = a.shape[1];
    n1 = max(m, n)
    if ind in {0, 2}:
        print('(rows, cols): (%2d,%2d)' % (m, n))
        print(a)
    s = r = k = 0
    # min value in row, max as col ind
    for i in range(m):
        row = a[i][0];
        col = 0;
        for j in range(1, n):
            if (row > a[i][j]):
                row = a[i][j];
                col = j;
        k = 0;
        for k in range(m):
            if (row < a[k][col]):
                break;
            k += 1;
        if (k == m):
            s = row
            r = i + 1
            k = col + 1
            if ind in {0, 2}:
                print("Saddle Point: ", s)
                print('Position: (%2d,%2d)' % (r,k))
                return True
            else:
                return s, r, k
    print('There is no saddle point.')
    return

На пример, модул МиниМакс позивимо са:

a = np.array([[8, 1, 9], [7, 2, 6], [3, 4, 5]])
kod.minmax(a, 2)

добићемо испис:

(rows, cols): ( 3, 3)
[[8 1 9]
 [7 2 6]
 [3 4 5]]
There is no saddle point.

Други пример, модул позовимо са:

a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
kod.minmax(a, 2)

добијамо испис:

(rows, cols): ( 4, 3)
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
Saddle Point:  10
Position: ( 4, 1)

Трећи пример, модул позовимо са:

a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
kod.minmax(a, 2)

добијамо испис:

(rows, cols): ( 3, 4)
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
Saddle Point:  9
Position: ( 3, 1)

Међутим, ако модул позовимо са:

a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
s, r, k = kod.minmax(a, 3)

нема аутоматског исписа, али можемо куцати и добити:

s, r, k
(9, 3, 1)

јер индикатор '3' позива чува резултат у излазним параметрима.

2. Текст

2.1. Ћирилизатор пресловљава текстове српске латинице у ћирилицу остављајући све остале знакове непромењене. Програм позивамо са 'f = kod.latcir(x, y)', са до две улазне варијабле 'x' и 'y', и са највише једном излазном 'f'. Када 'y' није наведено, или је нула или је један, онда 'input' преузима теkст унешен тастатуром, који би иначе узимао из варијабле 'x'. Када је 'y' изостављено, или је нула, или два, превод излази и на екран. У сваком случају у варијабли 'f' биће на излазу сачуван пресловљен текст у српској ћирилици, осим ако је 'f' изостављена у нареби, а одзив је штампан на екран. На крају додата је листа исправки, на пример, нетачно писано „ињекција“ у тачно „инјекција“.

# Ćirilizator, prevodi latinična slova u ćirilična
def latcir(txt = '', ind = 0):
    # Ako je ind == 0 koristi 'input' i 'print', podrazumevano
    # ind = 1 ulaz tastaturom, bez rezultata na ekranu
    # ind = 2 preuzima 'txt', a obrađeno ide i na ekran
    # ind = 3 preuzima 'txt', a obrađeno čuva (return)
    slova_srb = ['Љ','Њ','Џ','љ','њ','џ','А','Б','В','Г','Д','Ђ','Е','Ж','З',
                 'И','Ј','К','Л','М','Н','О','П','Р','С','Т','Ћ','У','Ф','Х',
                 'Ц','Ч','Ш','а','б','в','г','д','ђ','е','ж','з','и','ј','к',
                 'л','м','н','о','п','р','с','т','ћ','у','ф','х','ц','ч','ш']
    slova_cro = ['Lj','Nj','Dž','lj','nj','dž','A','B','V','B','D','Đ','E',
                 'Ž','Z','I','J','K','L','M','N','O','P','R','S','T','Ć','U',
                 'F','H','C','Č','Š','a','b','v','g','d','đ','e','ž','z','i',
                 'j','k','l','m','n','o','p','r','s','t','ć','u','f','h','c',
                 'č','š']
    if ind in {0, 1}:
        print("ĆIRILIZATOR")
        txt = input('Unesi latinični tekst: ')
    for i,x in enumerate(slova_cro):
        txt = txt.replace(slova_cro[i],slova_srb[i])
        continue
    txt = txt.replace('њекциј', 'нјекциј')
    txt = txt.replace('ИЊЕКЦИЈ', 'ИНЈЕКЦИЈ')
    txt = txt.replace('оњугациј', 'онјугациј')
    txt = txt.replace('КОЊУГАЦИЈ', 'КОНЈУГАЦИЈ')
    txt = txt.replace('оњункциј', 'онјункциј')
    txt = txt.replace('КОЊУНКЦИЈА', 'КОНЈУНКЦИЈ')
    txt = txt.replace('оњуктур', 'онјуктур')
    txt = txt.replace('КОЊУКТУР', 'КОНЈУКТУР')
    txt = txt.replace('оњунктур', 'онјунктур')
    txt = txt.replace('КОЊУНКТУР', 'КОНЈУНКТУР')
    txt = txt.replace('оњуктивитис', 'онјуктивитис')
    txt = txt.replace('КОЊУКТИВИТИС', 'КОНЈУКТИВИТИС')
    if ind in {0, 2}:
        print(txt)
        return
    return txt 

Ево једног једноставног примера употребе ове функције из Питоновог едитора IDLE Shell 3.11.0. Након 'импортовања' кода, куцана је празна (без улазних варијабли) функција 'f = kod.latcir()', која потражује ручни унос текста, а штампање превода. Додао сам знакове '(xyw)' ради провере да ли их ћирилизатор успешно игнорише.

import kod
f = kod.latcir()
ĆIRILIZATOR
Unesi latinični tekst: Džafer, konj Šarac i šaka njih ljupkih vrapčića (xyw).
Џафер, коњ Шарац и шака њих љупких врапчића (xyw).
print(txt)
Џафер, коњ Шарац и шака њих љупких врапчића (xyw). 

Затим је још једном тражено штампање излаза, сада ручно дописаном наредбом 'print(txt)', након које је рачунар потврдио да и где садржи и чува излазни текст.

Тестирање програма: latcir ».

2.2. Латинизатор пресловљава текстове српске ћирилице у латиницу остављајући све остале знакове непромењене. Програм позивамо са 'f = kod.cirlat(x, y)', са до две улазне варијабле 'x' и 'y', и са највише једном излазном 'f'. Када 'y' није наведено, или је нула или је један, онда 'input' преузима теkст унешен тастатуром, који би иначе узимао из варијабле 'x'. Када је 'y' изостављено, или је нула, или два, превод излази и на екран. У сваком случају у варијабли 'f' биће на излазу сачуван пресловљен текст у српској ћирилици, осим ако је 'f' изостављена у нареби, а одзив је штампан на екран.

# Latinizator, prevodi ćirilična slova u latinična
def cirlat(txt = '', ind = 0):
    # Ako je ind == 0 koristi 'input' i 'print', podrazumevano
    # ind = 1 ulaz tastaturom, bez rezultata na ekranu
    # ind = 2 preuzima 'txt', a obrađeno ide i na ekran
    # ind = 3 preuzima 'txt', a obrađeno čuva (return)
    azbuka_srb = ['А', 'Б', 'В', 'Г', 'Д', 'Ђ', 'Е', 'Ж', 'З', 'И', 'Ј', 'К',
                  'Л', 'Љ', 'М', 'Н', 'Њ', 'О', 'П', 'Р', 'С', 'Т', 'Ћ', 'У',
                  'Ф', 'Х', 'Ц', 'Ч', 'Џ', 'Ш', 'а', 'б', 'в', 'г', 'д', 'ђ',
                  'е', 'ж', 'з', 'и', 'ј', 'к', 'л', 'љ', 'м', 'н', 'њ', 'о',
                  'п', 'р', 'с', 'т', 'ћ', 'у', 'ф', 'х', 'ц', 'ч', 'џ', 'ш']
    azbuka_cro = ['A', 'B', 'V', 'G', 'D', 'Đ', 'E', 'Ž', 'Z', 'I', 'J', 'K',
                  'L', 'Lj', 'M', 'N', 'Nj', 'O', 'P', 'R', 'S', 'T', 'Ć', 'U',
                  'F', 'H', 'C', 'Č', 'Dž', 'Š', 'a', 'b', 'v', 'g', 'd', 'đ',
                  'e', 'ž', 'z', 'i', 'j', 'k', 'l', 'lj', 'm', 'n', 'nj', 'o',
                  'p', 'r', 's', 't', 'ć', 'u', 'f', 'h', 'c', 'č', 'dž', 'š']
    if ind in {0, 1}:
        print("ЋИРИЛИЗАТОР")
        txt = input('Унеси ћирилични текст: ')
    for i,x in enumerate(azbuka_srb):
        txt = txt.replace(azbuka_srb[i],azbuka_cro[i])
        continue
    if ind in {0, 2}:
        print(txt)
        return
    return txt 

Ево једне употребе ове функције из Питоновог едитора.

f = kod.cirlat()
ЋИРИЛИЗАТОР
Унеси ћирилични текст: Као љута џукела скочио је шакама на њих!
Kao ljuta džukela skočio je šakama na njih!
print(f)
Kao ljuta džukela skočio je šakama na njih!

Текст писан српском ћирилицом уноси се тастатуром, јер је индикатор нула, превод на латиницу се исписује на екран и памти у варијабли 'f' која се тестира накнадним писањем наредбе 'print(f)'.

Тестирање програма: cirlat ».

2.3. Ћирилизатор II преводи 26 малих и великих слова текстова енглеског алфабета у 30 из српске азбуке остављајући све остало непромењено. Програм позивамо са 'f = kod.engcir(x, y)', са до две улазне варијабле 'x' и 'y', и са највише једном излазном 'f'. Када 'y' није наведено, или је нула или је један, онда 'input' преузима теkст унешен тастатуром, који би иначе узимао из варијабле 'x'. Када 'y' недостаје, или је нула, или два, препис се штампа и на екран. У сваком случају у вредности 'f' биће на излазу сачуван пресловљен текст у српској ћирилици, осим ако је 'f' изостављена у нареби, а одзив штампан на екран.

# Ćirilizator II, prevodi engleskih 26 slova u 30 ćiriličnih
def engcir(txt = '', ind = 0):
    # Ako je ind == 0 koristi 'input' i 'print', podrazumevano
    # ind = 1 ulaz tastaturom, bez rezultata na ekranu
    # ind = 2 preuzima 'txt', a obrađeno ide i na ekran
    # ind = 3 preuzima 'txt', a obrađeno čuva (return)
    slova_srb = ['Љ','Њ','Џ','Ђ','Ж','Ч','Ћ','Ш',
                 'Љ','Њ','Џ','Ђ','Ж','Ч','Ћ','Ш',
                 'љ','њ','џ','ђ','ж','ч','ћ','ш','А','Б','В','Г',
                 'Д','Е','З','И','Ј','К','Л','М','Н','О','П','Р',
                 'С','Т','У','Ф','Х','Ц','а','б','в','г','д','е',
                 'з','и','ј','к','л','м','н','о','п','р','с','т',
                 'у','ф','х','ц']
    slova_eng = ['Lj','Nj','Dz','Gj','Gz','Ch','Cj','Sj',
                 'LJ','NJ','DZ','GJ','GZ','CH','CJ','SJ',
                 'lj','nj','dz','dj','gz','ch','cj','sj','A','B',
                 'V','G','D','E','Z','I','J','K','L','M','N','O',
                 'P','R','S','T','U','F','H','C','a','b','v','g',
                 'd','e','z','i','j','k','l','m','n','o','p','r',
                 's','t','u','f','h','c']
    if ind in {0, 1}:
        print("Ćirilizator II")
        txt = input('Unesi engleski tekst: ')
    for i,x in enumerate(slova_eng):
        txt = txt.replace(slova_eng[i],slova_srb[i])
        continue
    if ind in {0, 2}:
        print(txt)
        return
    return txt

Као што се види, шема паковања њих више у мање је:

'Lj' → 'Љ',   'Nj' → 'Њ',   'Dz' → 'Џ',   'Gj' → 'Ђ',   'Gz' → 'Ж',   'Ch' → 'Ч',   'Cj' → 'Ћ',   'Sj' → 'Ш'

и слично са осам малих слова. Избор сам тестирао на роману The Great Gatsby By F. Scott Fitzgerald. У том тексту парова слова 'jl', 'dz', 'gj', 'gz', 'cj' и 'sj' уопште нема, а приближно звуче у српском. Пар 'nj' је на свега 11 места, док се пар 'ch' јавља 702 пута.

На пример, покретање програма без параметара изгледа овако:

kod.engcir()
Ćirilizator II
Unesi engleski tekst: I realize now that under different circumstances that 
conversation might have been one of the crises of my life. But, because the 
offer was obviously and tactlessly for a service to be rendered, I had no 
choice except to cut him off there.

И реализе ноw тхат ундер дифферент цирцумстанцес тхат 
цонверсатион мигхт хаве беен оне оф тхе црисес оф мy лифе. Бут, бецаусе тхе оффер 
wас обвиоуслy анд тацтлесслy фор а сервице то бе рендеред, И хад но 
чоице еxцепт то цут хим офф тхере. 

Унешен је енглески текст узет са 89. стране поменутог романа. Међутим, потреба за овим програмом је у крипто-кодирању, на пример: ћирилица → алфабет → крипто-код. Ономе ко декодира и зна шифру редослед је обрнут: kripto-kod → alfabet → ćirilica, а ту је управо овај програм. Јединственост парова је само умерено корисна.

2.4. Латинизатор II пресловљава текстове српске ћирилице у енглеску латиницу остављајући остале знакове непромењене. Програм позивамо са 'f = kod.cirlat(x, y)', са до две улазне варијабле 'x' и 'y', и са највише једном излазном 'f'. Када 'y' није наведено, или је нула или је један, онда 'input' преузима теkст унешен тастатуром, који би иначе узимао из варијабле 'x'. Када је 'y' изостављено, или је нула, или два, превод излази и на екран. У сваком случају у варијабли 'f' биће на излазу сачуван пресловљен текст у српској ћирилици, осим ако је 'f' изостављена у нареби, а одзив је штампан на екран.

# Latinizator II, prevodi 30 slova srpske azbuke u 26 engleskog alfabeta
def cireng(txt = '', ind = 0):
    # Ako je ind == 0 koristi 'input' i 'print', podrazumevano
    # ind = 1 ulaz tastaturom, bez rezultata na ekranu
    # ind = 2 preuzima 'txt', a obrađeno ide i na ekran
    # ind = 3 preuzima 'txt', a obrađeno čuva (return)
    slova_srb = ['Љ','Њ','Џ','Ђ','Ж','Ч','Ћ','Ш','љ','њ','џ','ђ',
                 'ж','ч','ћ','ш','А','Б','В','Г','Д','Е','З','И',
                 'Ј','К','Л','М','Н','О','П','Р','С','Т','У','Ф',
                 'Х','Ц','а','б','в','г','д','е','з','и','ј','к',
                 'л','м','н','о','п','р','с','т','у','ф','х','ц']
    slova_eng = ['Lj','Nj','Dz','Gj','Gz','Ch','Cj','Sj','lj','nj','dz','dj',
                 'gz','ch','cj','sj','A','B','V','G','D','E','Z','I',
                 'J','K','L','M','N','O','P','R','S','T','U','F',
                 'H','C','a','b','v','g','d','e','z','i','j','k',
                 'l','m','n','o','p','r','s','t','u','f','h','c']
    if ind in {0, 1}:
        print("Latinizator II")
        txt = input('Унеси ћирилични текст: ')
    for i,x in enumerate(slova_srb):
        txt = txt.replace(slova_srb[i],slova_eng[i])
        continue
    if ind in {0, 2}:
        print(txt)
        return 
    return txt

На пример, текст из Приче о информацији (1.6. Једнакост) каскадно преведен је из азбуке у алфабет, па резултат из алфабета у азбуку:

import kod
a = 'Барабаши, амерички математичар румунско-мађарског порекла, рођ. 1967, од 2000. 
године истражује мреже. Интернет, далеководи, популарност, ток новца – примене су 
његових открића која једном утврђена постају универзална ствар.'
b = kod.cireng(a, 3)
print(b)
Barabasji, americhki matematichar rumunsko-madjarskog porekla, rodj. 1967, od 2000. 
godine istragzuje mregze. Internet, dalekovodi, popularnost, tok novca – primene su 
njegovih otkricja koja jednom utvrdjena postaju univerzalna stvar.
c = kod.engcir(b, 3)
print(c)
Барабаши, амерички математичар румунско-мађарског порекла, рођ. 1967, од 2000. 
године истражује мреже. Интернет, далеководи, популарност, ток новца – примене су 
његових открића која једном утврђена постају универзална ствар. 

Пренесете ове програме у неки Питон интерпретер (просто 'copy-paste') и тестирајте!

2.5 Виженеров код је метод шифровања текста комбиновањем Цезарових шифри. Програм старта наредба 'f = kod.vgciph(x, y, z)', са највише три улазне варијабле 'x', 'y' и 'z', и једном излазном 'f'. Прва је оригинални текст (Plaintext), друга је лозинка (Key), а трећа је индикатор. Када индикатора 'z' нема, или је нула или је један, онда 'input' преузима текст унешен тастатуром, који би се иначе преносио из варијабли 'x' и 'y'. Када је 'z' изостављено, или је нула, или два, резултат обраде излази и на екран. На излазу, у варијабли 'f', биће сачуван кодиран текст, осим ако је 'f' изостављена у нареби и резултатом штампаним на екран.

# The Vigenère cipher is a method of encrypting text 
def vgciph(txt='', key='', ind=0):
    # If ind == 0 use 'input' and 'print', by default
    # ind = 1 keyboard input, no result on screen
    # ind = 2 no keyboard, but it has screen printing
    # ind = 3 no keyboard and no screen printing
    tabula = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    if ind in {0, 1}:
        print("Vigenère Cipher, coding")
        print(tabula)
        txt = input("Plaintext: ")
        key = input("Key: ")
    kljuc = key.upper()
    poruka = txt.upper()
    n = len(poruka)
    kljuc2 = ''
    while len(kljuc2) < n:
        kljuc2 = kljuc2 + kljuc 
    tabula = tabula + tabula
    poruka2 = ''
    i = 0
    for x in poruka:
        x2 = x
        if tabula.find(x) > -1:
            x1 = kljuc2[i]
            i1 = tabula.find(x1)
            i2 = tabula.find(x)
            if (i1 != -1) and (i2 != -1):
                x2 = tabula[i1+i2]
            i = i + 1
        poruka2 = poruka2 + x2
    if ind in {0, 2}:
        print(" Plaintext: ", txt)
        print("       Key: ", key)
        print("Ciphertext: ", poruka2)
        return
    return poruka2 

2.6 Виженеров декод је дешифровање које позивамо са 'f = kod.ciphvg(x, y, z)', са највише три улазне варијабле 'x', 'y' и 'z', и евентуално једном излазном 'f'. Прва је оригинални текст (Plaintext), лозинка је друга (Key), а трећа је индикатор. Када индикатор 'z' није наведен, или је нула или је један, онда 'input' преузима текст унешен тастатуром, који би иначе узимао из варијабли 'x' и 'y'. Када је 'z' изостављено, или је нула, или два, резултат обраде излази и на екран. У варијабли 'f' биће на излазу чуван кодиран текст, осим ако је 'f' изостављена у нареби, а одзив је штампан на екран.

# The Vigenère decipher is a method of decrypting text
def ciphvg(txt='', key='', ind=0):
    # If ind == 0 use 'input' and 'print', by default
    # ind = 1 keyboard input, no result on screen
    # ind = 2 no keyboard, but it has screen printing
    # ind = 3 no keyboard and no screen printing
    tabula = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    if ind in {0, 1}:
        print("Vigenère Cipher, decoding")
        print(tabula)
        txt = input("Ciphertext: ")
        key = input("Key: ")
    kljuc = key.upper()
    poruka = txt.upper()
    n = len(poruka)
    kljuc2 = ''
    while len(kljuc2) < n:
        kljuc2 = kljuc2 + kljuc
    tabula = tabula + tabula
    poruka2 = ''
    i = 0
    for x in poruka:
        x2 = x
        if x == ' ':
            poruka2 = poruka2 + x2
            continue            
        if tabula.find(x) > -1:
            x1 = kljuc2[i]
            i1 = tabula.find(x1)
            i2 = tabula.find(x)
            if (i1 != -1) and (i2 != -1):
                x2 = tabula[i2-i1]
            i = i + 1
            poruka2 = poruka2 + x2
    if ind in {0, 2}:
        print("Ciphertext: ", txt)
        print("       Key: ", key)
        print(" Plaintext: ", poruka2)
        return
    return poruka2 

На пример, када узастопно пустимо кодирање па декодирање неког текста, тестираћемо програме:

import kod
x = 'The Vigenère cipher is well known'
y = 'ponedeljak'
ind = 3
x1 = kod.vgciph(x, y, ind)
print(x1)
IVR ZLKPWÈRO RWCLHV TB WOAZ XRRAY
x2 = kod.ciphvg(x1, y, ind)
print(x2)
THE VIGENRE CIPHER IS WELL KNOWN 

Управо је то оно што желимо, осим што у стварном раду ових програма неће бити штампања на екран између корака. Ево како то изгледа даље компоновано са ћирилизаторима:

import kod
ind = 3
x = 'Љубиша њему прави ћевапчиће.'
x1 = kod.cireng(x, ind) # превод у алфабет
print(x1)
Ljubisja njemu pravi cjevapchicje.
y = 'ponedeljak'
x2 = kod.vgciph(x1, y, ind) # Вижинеров код
print(x2)
AXHFLWUJ NTTAH TUEGR CTTJNTFLTLJO.
x3 = kod.ciphvg(x2, y, ind) # Вижинеров декод
print(x3)
LJUBISJA NJEMU PRAVI CJEVAPCHICJE
x4 = kod.engcir(x3, ind) # превод у ћирилицу
print(x4)
ЉУБИША ЊЕМУ ПРАВИ ЋЕВАПЧИЋЕ

Ова штампања на екран, наредбом 'print("bla, bla")', у стварном раду избегавамо, јер би нас смарале те силне колоне извештаја. Ми их не бисмо стизали читати, а оне би рад рачунара успоравале.

2.7 Читање наслова сајта и бројање појављивања датог текста у њему постиже 'f, g = kod.naslov(x, y, z)'. Улазне варијабле су адреса (x), текст (y) и индикатор (z), а излазне назив сајта (f) и број појављивања датог текста (g). Када је индикатор 0 или 1, адреса сајта се уноси тастатуром. Када је индикатор 0 или 2 резултат се штампа на екран. Када је индикатор 3 или већи, улаз и излаз су варијабле.

# Čita naslov datog sajta i broji pojavljivanje txt u njemu 
def naslov(url='', txt ='',  ind=0):
    # ind = 0 - ulaz tastaturom, izlaz na ekran
    # ind = 1 - ulaz tastaturom, izlaz varijablom
    # ind = 2 - ulaz varijablom, izlaz na ekran
    # ind = 3 - ulaz varijablom, izlaz varijablom
    if ind in {0, 1}:
        url = input("Unesi adresu url: ")
        txt = input("Traženi tekst: ")
    from urllib.request import urlopen
    page = urlopen(url)
    html = page.read().decode("utf-8")
    start_naziv = html.find("") + len("<title>")
    end_naziv = html.find("")
    naziv = html[start_naziv:end_naziv]
    s_telo = html.find("")  
    telo = html[s_telo:e_telo]
    n = telo.count(txt) # број појављивања txt
    naslov1 = "{0} [{1}] {2}x".format(naziv,txt,n)
    if ind in {0, 2}:
        print(naslov1)
        return 
    return naziv, n 

На пример, без варијабли пуштен програм:

import kod
kod.naslov()
Unesi adresu url: https://rvukovic.rs
Traženi tekst: Serbian
Rastko Vuković, private site [Serbian] 3x

Други пример, исто са варијаблама:

import kod
x = "https://rvukovic.rs"
y = "Serbian"
z = 3
f, g = kod.naslov(x, y, z)
f, g
('Rastko Vuković, private site', 3)

На крају је додато 'f, g' само зато да би се овде (у загради) видело шта садрже те две излазне варијабле.

2.8.1. Замена у датој датотеци (x) једног израза (y) другим (z) наредбом 'kod.zamena(x, y, z, ind)'. Када индикатора нема (или је 0 или 1) аргументи x, y и z уносе се тастатуром.

# Čita fajl 'teka' i menja 'ulaz' sa 'izlaz'
def zamena(teka='', ulaz='', izlaz='', ind = 0):
    # ind 0 ili 1 - unos tastaturom
    if ind in {0, 1}:
        teka = input("Unesi adresu datoteke: ")
        ulaz = input("Stari izraz: ")
        izlaz = input("Novi izraz: ")
    f = open(teka, "r", encoding='utf-8-sig')
    x = f.read()
    f.close()
    y = x.replace(ulaz, izlaz)
    f = open(teka, "w", encoding='utf-8-sig')
    f.write(y)
    f.close()
    return

На пример, фајл 'teka.txt' садржи текст: "Бацамо фер-новчић док не падне писмо и писмо, писмо два пута узастопно." Мењамо улазну реч "писмо" са "глава":

import kod
x = "teka.txt"
y = "писмо"
z = "глава"
ind = 3
kod.zamena(x, y, z, ind)

Нема накнадних извештаја, али у фајлу 'teka.txt' даље је текст: "Бацамо фер-новчић док не падне глава и глава, глава два пута узастопно." Са програмским петљама (For, While, if) овај програмчић користим за измене рецимо адреса у низу других програма када реорганизујем странице на интернету. Следећи код је део тог пакета.

2.8.2. Замене у листи датотека (x) једног израза (y) другим (z) наредбом 'kod.zamene(x, y, z, ind)'. Када индикатора нема (или је 0 или 1) аргументи x, y и z уносе се тастатуром.

# Čita listu fajlova 'teka' i u svakoj menja 'ulaz' sa 'izlaz'
def zamene(lista=[], ulaz='', izlaz='', ind = 0):
    # ind 0 ili 1 - unos tastaturom
    # ind = 1 - ulaz tastaturom, bez izlaza na ekran
    if ind in {0, 1}:
        teka = input("Unesi listu datoteka: ")
        ulaz = input("Stari izraz: ")
        izlaz = input("Novi izraz: ")
    for teka in lista:
        f = open(teka, "r", encoding='utf-8-sig')
        x = f.read()
        f.close()
        y = x.replace(ulaz, izlaz)
        f = open(teka, "w", encoding='utf-8-sig')
        f.write(y)
        f.close()
    return

Програме 'zamena()' и 'zamene()' згодније је у пакету позивати из следећег програма 'zameni()', који ће „разумети“ шта хоћете и тихо извршити прави избор.

2.8.3. Смене у једној или у листи датотека (x) једног израза (y) другим (z) ради 'kod.zameni(x, y, z, ind)'. Када индикатора нема (или је 0 или 1) аргументи x, y и z уносе се тастатуром. Програм сам препознаје да ли сте навели само једну датотеку или листу датотека и бира одговарајући наставак.

# Čita fajl (ili listu) 'teka' i menja 'ulaz' sa 'izlaz' (u svakoj)
def zameni(teka='', ulaz='', izlaz='', ind = 0):
    # ind = 0 - ulaz tastaturom, izlaz na ekran
    # ind = 1 - ulaz tastaturom, izlaz varijablom
    # ind = 2 - ulaz varijablom, izlaz na ekran
    # ind = 3 - ulaz varijablom, izlaz varijablom
    if isinstance(teka, str):
        kod.zamena(teka, ulaz, izlaz, 3)
    elif isinstance(teka, list):
        kod.zamene(teka, ulaz, izlaz, 3)
    else:
        print("Imenujte jednu, ili listu datoteka!")
    return

На пример, низ наредби:

x = ['teka1.txt', 'teka2.txt', 'teka3.txt']
y = "писмо"
z = "глава"
ind = 3
kod.zameni(x, y, z, ind)

у свакој о три датотеке листе x, са текстом "Бацамо фер-новчић док не падне писмо и писмо, писмо два пута узастопно." извршиће смену "писмо" --> "глава", тако да у њима остаје текст "Бацамо фер-новчић док не падне глава и глава, глава два пута узастопно."

2.9.1. Налази слова текста датог фајла и азбуку. То ради програм 'n, a = kod.slova(x, y)'. Прва улазна варијабла (x) је назив датотеке, друга (y) је индикатор. Прва излазна је укупни број слова текста (n), а друга је кориштена азбука (a). Индикатори 0 или 1 траже унос назива датотеке тастатуром, а 0 или 2 штампаће укупни број слова, број слова азбуке и азбуку на екран. Излазне варијабле наводимо када је индикатор 1, 3 или већи, иначе не. Осетљиво место (предност или мана) програма је скуп 'preko' који одваја прекобројна слова, која не желимо задржати у азбуци а могла би се појављивати у тексту.

# Broji i odvaja slova teksta iz fajla
def slova(fajl = 'teka.txt', ind=0):
    # ind = 0 - ulaz tastaturom, izlaz na ekran
    # ind = 1 - ulaz tastaturom, izlaz varijablom
    # ind = 2 - ulaz varijablom, izlaz na ekran
    # ind = 3 - ulaz varijablom, izlaz varijablom
    if ind in {0, 1}:
        print('Broji i odvaja slova teksta')
        fajl = input('Unesi adresu fajla: ')
    f = open(fajl, 'r', encoding='utf-8-sig')
    tekst = f.read()
    f.close()
    n = len(tekst)
    aset = set()
    for i,x in enumerate(tekst):
        tset = aset.add(x)
    preko = {'\n', ' ', '!', "'", ',', '-', '.', ':', ';', '?', '«', '»', '—',
             '–', '…'}
    taman = aset - preko
    azbuka = sorted(taman)
    if ind in {0, 2}:
        print(n, 'slova teksta')
        m = len(taman)
        print(m, 'slova azbuke:')
        print(azbuka)
        return
    return n, azbuka 

На пример, у датотеци 'andric.txt' смештен је одломак из романа „На Дрини ћуприја“. Програм креће без параметара:

import kod
kod.slova()
Broji i odvaja slova teksta
Unesi adresu fajla: andric.txt
6616 slova teksta
47 slova azbuke:
['Ј', 'А', 'Б', 'В', 'Д', 'З', 'И', 'К', 'М', 'Н', 'О', 'Р', 'С', 'Т', 'У',
 'Ц', 'Ш', 'а', 'б', 'в', 'г', 'д', 'е', 'ж', 'з', 'и', 'к', 'л', 'м', 'н',
 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'ђ', 'ј', 'љ', 'њ',
 'ћ', 'џ']

Као што видимо, аутор текста (Иво Андрић) је у датом исечку са укупно 6616 слова, укључујући и помоћне ознаке попут интерпукције, употребљавао свега 47 (од 60 великих и малих) слова српске азбуке.

Други пример, у датотеци 'selimovic.txt' су прва четири одломка из романа „Тврђава“:

import kod
x = 'selimovic.txt'
ind = 0
kod.slova(x, 2)
9624 slova teksta
56 slova azbuke:
['1', '2', '3', '4', 'A', 'B', 'C', 'D', 'E', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 
'O', 'P', 'R', 'S', 'T', 'U', 'V', 'Z', 'a', 'b', 'c', 'd', 'e', 'g', 'h', 'i', 'j', 
'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 't', 'u', 'v', 'z', 'â', 'Ć', 'ć', 'Č', 'č', 
'đ', 'Š', 'š', 'Ž', 'ž']

Азбука садржи и прва четири броја из наслова одломака, па и акцентовано (â), али у 9624 слова текста аутор (Меша Селимовић) опет нема ('F' и 'f') свих великих и малих слова латинице. Иначе, програм је део пакета за статистичку анализу текстова, каква је рађена у Letter Frequency.

2.9.2. Фреквенцију слова израчунава програм 'm, c = kod.rates(x, y)'. Прва улазна варијабла (x) назив је датотеке, друга (y) је индикатор. Прва излазна (m) је број свих слова, сада само азбуке, датог текста. Друга излазна c = (ak, bk) је листа парова, слова азбуке (a) са бројем појављивања појединог (b) у датом тексту, пореданих по опадајућем броју. Индикатори 0 или 1 траже унос назива датотеке тастатуром, а индикатори 0 или 2 штампаће број m и листу c на екран. Са индикатором 0 или 2 не наводимо излазне варијабле.

# Frekvencije (rates) slova u tekstu datog fajla
def rates(fajl = 'teka.txt', ind=0):
    # ind = 0 - ulaz tastaturom, izlaz na ekran
    # ind = 1 - ulaz tastaturom, izlaz varijablom
    # ind = 2 - ulaz varijablom, izlaz na ekran
    # ind = 3 - ulaz varijablom, izlaz varijablom):
    if ind in {0, 1}:
        print('Израчунава фреквенцију слова текста')
        fajl = input('Adresa fajla sa tekstom: ')
    n, a = kod.slova(fajl, 3) # formira azbuku a
    n1 = len(a) # broj slova azbuke a
    b = [0]*n1 # druga koordinata za frekvenciju slova
    f = open(fajl, 'r', encoding='utf-8-sig')
    tekst = f.read()
    f.close()
    m = 0 # мерач, brojaч свих појављивања слова азбуке
    for i, x in enumerate(a): # formira frekvenciju slova
        b[i] = tekst.count(x)
        m = m + b[i]
    # sortira frekvencije (druga kooridata) unatraške
    c = list(zip(a, b)) # udružuje slova sa frekvencijom
    c.sort(key=lambda row: (row[1]), reverse=True) 
    if ind in {0, 2}:
        print(m, c)
        return
    return m, c 

На пример, исти текст у претходној датотеци 'andric.txt' сада позивамо ради бројања појављивања појединих слова тамо пронађене азбуке:

import kod
x = 'andric.txt'
ind = 0
kod.rates(x, 2)
5284 [('а', 579), ('е', 564), ('о', 526), ('и', 459), ('н', 288), ('у', 274), 
('с', 257), ('р', 224), ('д', 221), ('т', 217), ('к', 196), ('в', 177), 
('л', 177), ('м', 169), ('ј', 162), ('п', 140), ('г', 110), ('б', 92), 
('з', 90), ('ч', 54), ('ш', 49), ('њ', 38), ('х', 34), ('ц', 29), ('ћ', 29), 
('ж', 26), ('љ', 26), ('ђ', 16), ('Т', 8), ('Н', 7), ('И', 6), ('О', 6), 
('Д', 5), ('С', 5), ('К', 4), ('З', 3), ('А', 2), ('В', 2), ('М', 2), 
('Ц', 2), ('ф', 2), ('џ', 2), ('Ј', 1), ('Б', 1), ('Р', 1), ('У', 1), 
('Ш', 1)] 

Први излазни број (5284) је број свих слова нађене азбуке, за којим следе поредана по учесталости та слова. Очекивано, самогласници су водећи, најчешћи, а 'Ш' најређе од присутних. Има још неколико слова српске азбуке — која се у том Андрићевом одломку уопште не појављују.

Други пример је други текст у претходној датотеци 'selimovic.txt', сада ради бројања појављивања појединих слова тамошње азбуке (латиничне):

import kod
x = 'selimovic.txt'
ind = 0
kod.rates(x, 2)
7455 [('a', 831), ('i', 754), ('o', 705), ('e', 667), ('n', 417), ('s', 375), 
('j', 359), ('m', 333), ('u', 309), ('t', 305), ('r', 277), ('v', 266), ('d', 253), 
('l', 231), ('k', 220), ('p', 154), ('b', 145), ('g', 113), ('z', 107), ('š', 100), 
('ž', 63), ('ć', 55), ('č', 54), ('h', 53), ('c', 42), ('N', 32), ('I', 30), 
('A', 23), ('đ', 19), ('S', 18), ('M', 16), ('J', 13), ('Z', 12), ('D', 10), 
('E', 9), ('K', 9), ('P', 8), ('H', 7), ('O', 7), ('T', 7), ('R', 6), ('U', 6), 
('Š', 6), ('B', 5), ('L', 5), ('Ž', 4), ('V', 3), ('C', 2), ('â', 2), ('Č', 2), 
('1', 1), ('2', 1), ('3', 1), ('4', 1), ('G', 1), ('Ć', 1)] 

На 7455 места слова ове азбуке текста најчешће се појављују самогласници малих слова, а најређа су велика слова 'G' и 'Ć', што се тиче уопште присутних.

Узмемо ли неког трећег писца, Достојевског или Фицџералда на њиховом матерњем језику и зависно од дела, добијаћемо другачије азбуке са другачијим фреквенцијама слова. Међутим, корелација тако извучених „случајних низова“ може бити велика због једнаке дубље природе њихових језика. Проверимо то!

2.9.3. Корелацију слова припрема и израчунава програм 'r, b1, b2 = kod.korel(x, y, z)'. Прва и друга улазна варијабла (x и y) су називи датотека са текстом, а трећа (z) је индикатор. Прва излазна (r) је корелација нађених и издвојених низова (b1 и b2). Индикатори 0 или 1 траже унос назива датотеке тастатуром, а индикатори 0 или 2 штампаће корелацију r и листе b1 b2 на екран. Са индикатором 0 или 2 не наводимо излазне варијабле.

# Izdvaja frekvencije slova dva teksta i izračunava korelaciju
def korel(x1='teka1.txt', x2='teka2.txt', ind=0):
    # ind = 0 - ulaz tastaturom, izlaz na ekran
    # ind = 1 - ulaz tastaturom, izlaz varijablom
    # ind = 2 - ulaz varijablom, izlaz na ekran
    # ind = 3 - ulaz varijablom, izlaz varijablom
    if ind in {0, 1}:
        print('Издваја фреквенције слова два теста')
        x1 = input('Adresa fajla 1 sa tekstom: ')
        x2 = input('Adresa fajla 2 sa tekstom2: ')
    m1, c1 = kod.rates(x1, 3)
    m2, c2 = kod.rates(x2, 3)
    l1 = len(c1)
    l2 = len(c2)
    l = min(l1, l2) # Izjednačavanje dužina nizova
    c1 = c1[:l] # Odseca rep (opadajućeg) niza
    c2 = c2[:l]
    d1 = [] 
    d2 = []
    # Iz 2D lista izdvaja 1D nizove
    for k in c1: d1.append(k[1]) 
    for k in c2: d2.append(k[1])
    r = np.corrcoef(d1, d2) # korelacija
    if ind in {0, 2}:
        print('Korelacija: ')
        print(r)
        print('Frekvencije azbuke 1:')
        print(d1)
        print('Frekvencije azbuke 2:')
        print(d2)
        return 
    return r, d1, d2 

Претходна два текста, Андрића и Селимовића, позивам за тестирање овог програма:

import kod
x1 = 'teka1.txt'
x2 = 'teka2.txt'
ind = 2
kod.korel(x1, x2, ind)
Korelacija: 
[[1.         0.99822777]
 [0.99822777 1.        ]]
Frekvencije azbuke 1:
[579, 564, 526, 459, 288, 274, 257, 224, 221, 217, 196, 177, 177, 169, 162, 140, 110, 
92, 90, 54, 49, 38, 34, 29, 29, 26, 26, 16, 8, 7, 6, 6, 5, 5, 4, 3, 2, 2, 2, 2, 2, 2, 
1, 1, 1, 1, 1]
Frekvencije azbuke 2:
[831, 754, 705, 667, 417, 375, 359, 333, 309, 305, 277, 266, 253, 231, 220, 154, 145, 
113, 107, 100, 63, 55, 54, 53, 42, 30, 26, 19, 15, 13, 13, 11, 9, 8, 6, 6, 6, 6, 6, 
5, 5, 4, 4, 3, 2, 2, 2]

Матрица корелације на главној дијагонали има корелацију првог низа са првим и другог са другим, а те су максималне 1. На споредног дијагонали су узајамне корелације, такође веома велике 0.9982, што је очекивано због једнаке дубље природе језика Андрића и Селимовића — упркос разлика азбука и тема.

3. Слике

3.1. Скица графикона настаје наредбом 'kod.skica(x, y, z)'. Подразумеване вредности и њихов смисао види се из листинга програма.

# Skica, grafikon 2D linijom, tačkama, ili stupcima
def skica(x = [20, 21, 22, 23], y = [90, 110, 120, 100], ind = 0):
    from matplotlib import pyplot as plt
    # x, y koordinate, ind - određuje način crtanja
    match ind:
        case 0: plt.bar(x,y) # stupci
        case 1: plt.hist(x, y) # histogram
        case 2: plt.plot(x,y) # izlomljena linija
        case 3: plt.scatter(x, y) # nepovezane tačke
        case 4: plt.plot(x,y,'o') # kružići
        case _: ind = 9
    plt.show() # funkcija crta grafikon
    return ind 
grafikon

Следи код који генерише слику десно као пример непосредног позива овог програма из IDLE едитора. Подразумевани су ind нула и наведени (x, y), парови координата.

import sys
sys.path.append('D:\Python')
import kod
kod.skica()

На слици десно је графикон. Он се добије неуношењем x, y или z вредности, варијабли. Иначе:

x = [5, 2, 9, 4, 7] # X-axis values
y = [6, 5, 8, 4, 2] # Y-axis values

примери су листа (одговарајућих парова) координата које можемо прво дефинисати, затим позвати програм наведеном наредбом. А индикатор 'z' одредиће методом 'case' избор графикона, односно начин цртања.

Други пример графикона добија се слично, са новим параметрима. Резултат је слика лево, хистограм (ind = 1) фреквенција старости сто особа (x = 100) груписаних у десет интервала (bins, y = 10).

grafikon
import kod
x = [1, 1, 2, 3, 3, 5, 7, 8, 9, 10,
     10, 11, 11, 13, 13, 15, 16, 17, 18, 18,
     18, 19, 20, 21, 21, 23, 24, 24, 25, 25,
     25, 25, 26, 26, 26, 27, 27, 27, 27, 27,
     29, 30, 30, 31, 33, 34, 34, 34, 35, 36,
     36, 37, 37, 38, 38, 39, 40, 41, 41, 42,
     43, 44, 45, 45, 46, 47, 48, 48, 49, 50,
     51, 52, 53, 54, 55, 55, 56, 57, 58, 60,
     61, 63, 64, 65, 66, 68, 70, 71, 72, 74,
     75, 77, 81, 83, 84, 87, 89, 90, 90, 91
     ]
y = 10
ind = 1
kod.skica(x, y, ind)

Рецимо, када овде ставимо варијаблу 'ind = 5' за непостојећи 'case', а функцију позовемо са 'f = kod.skica(x, y, ind)', на излазу биће f = 9. Тако сазнајемо да ли се и шта цртало.

3.2. Граф функције цртамо програмима попут датог 'graf(a, b, c, d)', где улазни параметри дефинишу исечак апсцисе, интервал реалних бројева (a, b), односно домен функције, и кодомен (c, d), вредности ординате. Тај правоугаоник је прозор кроз који видимо координатни систем.

# Graf, crta grafove funkcija
def graf(x1=0, x2=4, y1=-2, y2=2):
    import math
    import numpy as np
    import matplotlib.pyplot as plt
    x = np.linspace(x1, x2, 100) # domen, rezolucija
    f1 = x**3 - 6*x**2 +11*x - 6 # funkcije, kubna i prava
    f2 = x - 1
    fig, ax = plt.subplots()
    ax.plot(x, f1)
    ax.plot(x, f2)
    ax.set_xlim(x1, x2)
    ax.set_ylim(y1, y2)
    ax = plt.gca() # koordinatne ose
    ax.spines['top'].set_color('none')
    ax.spines['bottom'].set_position('zero')
    ax.spines['left'].set_position('zero')
    ax.spines['right'].set_color('none')
    plt.show()
    return 
graf funkcija

Подразумевани прозор је (0, 4, -2, 2), који можете мењати као и две наведене функције f1 и f2, кубну параболу (в. Нуле полинома, 12. пример) и праву (y = x - 1), чији број и врсте бирајте по жељи. Блок којим дефинишем координатне осе један је прост избор, од бројних могућности (Plot Axis Spines).

Када покренете функцију 'kod.graf()', овакву без параметара, излази граф као на слици десно.

Приметићете да су програми који цртају графове „екстравертна бића“, не тако „интровертна“ попут компјутера који нешто „мозгају“ сами за себе, али је добро имати и овакве без излазних параметара. Имам их мноштво у резерви и често их користим, иако волим да они раде самостално.

3.3. Граф тачака, црвених и плавих редом, два дата низа црта програм 'tacke(x, y , z)', где улазни параметри 'x' и 'y' дефинишу први и други низ, а трећи 'z' је индикатор. Ако је индикатор број 0 или 1 два низа у угластим заградама бројева одвојених запетама уносимо тастатуром, а иначе их задајемо раније варијаблама.

# Crta tačke, crvene i plave, dva niza u OXY ravni
def tacke(x=[1,2,3], y=[3,2,1], ind=0):
    # ind = 0 ili 1 - ulaz tastaturom, izlaz na ekran
    # ind = 2 ili više - ulaz varijablama, izlaz na ekran
    if ind in {0, 1}:
        print('Црта тачке два низа у OXY равни')
        x = input('Први низ бројева: ')
        y = input('Други низ бројева: ')
    import math
    import numpy as np
    import matplotlib.pyplot as plt
    lx = len(x)
    ly = len(y)
    for i in range(lx):
        plt.plot(i,x[i], marker='2', color='r')
    for i in range(ly):
        plt.plot(i,y[i], marker='1', color='b')
    plt.show()
    return 
graf funkcija

На пример, цртамо тачке програма 2.9.3. Корелација слова, у том примеру нађене.

import kod
x = 'teka1.txt'
y = 'teka2.txt'
ind = 3
r, x, y = kod.korel(x, y, ind)
kod.tacke(x, y, 2)

Резултат је слика лево. Прва тека садржи горе поменути текст Иве Андрића, друга текст Меше Селимовића. Програм 'korel()' извукао је азбуке тих текстова сортиране по броју појављивања слова и одсекао реп дужег да би њихове низове изједначио по дужини за потребе израчунавања корелације. Међутим, ти низови (x и y), другим уносима података, могу бити различитих дужина (lx и ly) приликом цртања и зато су у две одвојене 'for' петље.

graf funkcija

3.4. Графови Беселових функција $J_k(x)$. Унесите програм copy/paste и модификујте га по потреби. Овде је шест графова првих Беселових функција прве врсте k ∈ {0, 1, 2, 3, 4, 5} и апсцисе x ∈ (0, 10).

# Crta Beselove funkcije prve vrste y = J_k(x)
def besel(x=[1,2,3], y=[1,2,3], ind=2):
    # ind = 0 ili 1 - ulaz tastaturom, izlaz na ekran
    # ind = 2 ili više - ulaz varijablama, izlaz na ekran
    if ind in {0, 1}:
        print('Црта тачке два низа у OXY равни')
        x = input('Први низ бројева: ')
        y = input('Други низ бројева: ')
    from matplotlib import pyplot as plt
    from scipy.special import jv
    if ind > 1:
        x = []
        for i in range(100):
            a = i/10
            x.append(a)
        for k in range(6):
            y = []
            for j in x:
                b = jv(k, j)
                y.append(b)
            plt.plot(x, y)
        plt.show()
    return

Позивом модула са:

import kod
kod.besel()

добијам горњу слику шест Беселових функција.

4. наслов

.

5. наслов

.