У фајлу простог назива '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 понављања опита:
- m = 200, z = [94, 65, 41] → z/m = (0.475, 0.325, 0.205),
- m = 2000, z = [1007, 589, 404] → z/m = (0.5035, 0.2945, 0.202),
- 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' позива чува резултат у излазним параметрима.
1.6. РешЈед покреће 'x = kod.resjed(a, b, ind)'. Два улазна параметра 'a' и 'b' су границе интервала у којем се тражи нула унутра задате функције, са излазним 'x', апсцисом те нуле. Индикатор 0 штампаће међурезултате, иначе неће. Тачност је задата у модулу, уз прекид петље (break).
# Rešava Jednačinu. Traži nulu funkcije fun(x), a < x < b
def resjed(a=0.1, b=0.9, ind=0):
# ind == 0 štampa međurezultate, podrazumevano
# ind = 1 ne štampa međurezultate
import math
def f12(x): # када f(x1) < 0 и f(x2) > 0
f1 = x*math.log(1-x) - (1-x)*math.log(x) # опадајућа од 0 до 1
f2 = -x*math.log(x) # од 0 растућа до 1/e па опадајућа до 1
f = f2 - f1
return f
x1 = a
x2 = b
y1 = f12(x1)
y2 = f12(x2)
k = 1
if ind == 0: print(k, x1, y1, x2, y2)
if y1*y2 > 0: print("Interval nekorektan!")
return
while (y1*y2 < 0):
x = (x1 + x2)/2
y = f12(x)
k = k + 1
if y < 0:
x1 = x
y1 = y
if y > 0:
x2 = x
y2 = y
if ind == 0: print(k, x1, y1, x2, y2)
if (k > 30) or (abs(y) < 1e-6): break
return x
Примењен је у блогу, у питању/одговору Wave in Wave.
1.7. Тријаде покреће 'a, d = kod.triads(x, y, ind)'. Два улазна параметра 'x' и 'y' су трочлани низови позитивних реалних бројева, са излазнoм матрицом 'a' и њеном детерминантом 'd'. Индикатор 0 или 1 је улаз тастатуром, иначе је само варијаблом. То је код ситуација у Similarity II за процену „количине сличности“ троуглова. Векторе нормира (1-норма) на 180° и може се користити за упоређивања било каквих позитивних тријада. Са ind ≥ 4, оригинални програм (не овај), не сортира улазне низове x и y, док улаз-излаз раде само са параметрима.
# izračunava količinu sličnosti dva trougla
def triads(r1=np.array([[90], [60], [30]]), r2=np.array([[100], [55], [25]]), 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}:
mat1 = print('Niz tri broja, sa razmakom između, x:')
niz1 = [float(mat1) for mat1 in input().split()]
r1 = np.array(niz1).reshape(3, 1)
mat2 = print('Niz tri broja, sa razmakom između, y:')
niz2 = [float(mat2) for mat2 in input().split()]
r2 = np.array(niz2).reshape(3, 1)
r1 = np.abs(r1)
r2 = np.abs(r2)
s1 = sorted(r1, reverse=True)
s2 = sorted(r2, reverse=True)
z1 = s1[0] + s1[1] + s1[2]
z2 = s2[0] + s2[1] + s2[2]
if z1*z2 == 0:
print('Null Vector Error, End')
return
x = 180*(s1/z1)
y = 180*(s2/z2)
for i in range(3):
print(i, x[i])
if x[i] == 0:
x[i] = 1
print(x)
if y[i] == 0: y[i] = 1;
jedan = np.array([[1.0, 0, 0], [0, 1.0, 0], [0, 0, 1.0]]) # jedinična matrica
a = jedan
if (x[0] ≤ y[0]) and (x[1] ≤ y[1] and x[2] > y[2]):
a[0,2] = (y[0] - x[0])/x[2]
a[1,2] = (y[1] - x[1])/x[2]
a[2,2] = y[2]/x[2]
if (x[0] ≤ y[0]) and (x[1] > y[1] and x[2] ≤ y[2]):
a[0,1] = (y[0] - x[0])/x[1]
a[1,1] = y[1]/x[1]
a[2,1] = (y[2] - x[2])/x[1]
if (x[0] > y[0]) and (x[1] ≤ y[1] and x[2] ≤ y[2]):
a[0,1] = y[0]/x[0]
a[1,1] = (y[1] - x[1])/x[0]
a[2,1] = (y[2] - x[2])/x[0]
if (x[0] > y[0]) and (x[1] > y[1] and x[2] ≤ y[2]):
a[0,0] = y[0]/x[0]
a[1,1] = y[1]/x[1]
a[2,0] = (x[0] - y[0])/x[0]
a[2,1] = (x[1] - y[1])/x[1]
if (x[0] > y[0]) and (x[1] ≤ y[1] and x[2] > y[2]):
a[0,0] = y[0]/x[0]
a[1,0] = (x[0] - y[0])/x[0]
a[1,2] = (x[2] - y[2])/x[2]
a[2,2] = y[2]/x[2]
if (x[0] ≤ y[0]) and (x[1] > y[1] and x[2] > y[2]):
a[0,1] = (x[1] - y[1])/x[1]
a[0,2] = (x[2] - y[2])/x[2]
a[1,1] = y[1]/x[1]
a[2,2] = y[2]/x[2]
d = np.linalg.det(a) # determinanta
if ind in {1, 2}:
print('Niz x =')
print(x)
print('Niz y =')
print(y)
print('Matrica A =')
print(a)
print('det(A) =', d)
return a, d
Ово израчунавање „количине сличности“ (троуглова) помиње се као друга опција у питању Similarity, или у првом примеру Triads II, а даје вредност детерминанте матрице A која пресликава нерастући трочлани низ x у трочлани низ y, дакле, који не морају бити само углови троугла. Програм, пре израчунавања детерминанте, уклања предзнаке, нуле, нормира низове на збир 180° и сортира их у опадајућем редоследу.
1.8. Пар n-углова је програм 'a, d = kod.npairs(x, y, ind)'. Два улазна параметра 'x' и 'y' су n-члани низови реалних бројева ненултог збира, са излазнoм матрицом 'a' и њеном детерминантом 'd'. Инд-икатор 0 или 1 је улаз тастатуром, иначе је варијаблом. Индикатор 0 или 2 је излаз на екран, иначе је варијаблом. То прилог одговору Polygon II за процену количине сличности многоуглова, или n-торки бројева (n > 2).
# izračunava količinu sličnosti dva n-to ugla, ili dve n-torke
def npairs(r1=np.array([[70], [120], [110], [60]]), r2=np.array([[80], [110], [100], [70]]), 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}:
niz1 = print('Uglovi mnogougla sa razmakom između, x: ')
r1 = [float(niz1) for niz1 in input().split()]
n = len(r1)
r1 = np.array(r1).reshape(n, 1)
niz2 = print('Uglovi', n, '-ugla, sa razmakom između, y:')
r2 = [float(niz2) for niz2 in input().split()]
r2 = np.array(r2).reshape(n, 1)
n = len(r1)
z1 = sum(r1)
z2 = sum(r2)
if z1*z2 != 0:
r1 = (n-2)*180*r1/z1
r2 = (n-2)*180*r2/z2
else:
print('\nZbir niza je nula!')
return
if ind in {0, 2}:
r1 = np.abs(r1)
r2 = np.abs(r2)
print('\nImamo niz x =\n', r1)
print('\nZatim niz y =\n', r2)
arr = np.identity(n, dtype = float)
det = 1
skup = set()
for i in range(n):
arr[i][i] = 1
if r1[i] > r2[i]:
skup.add(i)
m = len(skup)
if m == 0:
print('\nMatrica A =\n', arr)
print('\nDeterminanta =', det)
return arr, det
for j in skup: # kolone matrice arr
for i in range(n): # redovi matrice arr
if r1[i] > r2[i]:
arr[i][i] = r2[i]/r1[i]
else:
arr[i][j] = (r2[i]-r1[i])/(m*r1[j])
det = np.linalg.det(arr) # determinanta
if ind in {0, 2}:
print('\nMatrica A =\n', arr)
print('\nDeterminanta =', det)
return arr, det
Ово израчунавање „количине сличности“ (троуглова) помиње се као друга опција у питању Similarity, или у првом примеру Triads II, а даје вредност детерминанте матрице A која пресликава трочлани низ x у трочлани низ y, затим, који не морају бити само углови троугла. Програм npairs() је општа верзија таквог за произвољне „многоуглове“.
1.9. Корелација Пирсона је програм 'r = kod.corrpe(x, y, ind)'. Улазни параметри 'x' и 'y' су n-члани низови реалних бројева. Излаз су 'x', 'y' и тражени Пирсонов коефицијент корелације r ∈ [-1, 1]. Трећи улазни праметар 'ind' је индикатор. Када је 0 и 1 модул захтева улазе тастатуром, а 2 и 3 са варијаблом. Индикатор 0 или 2 даће излазе на екран, а 1 и 3 су излази варијаблом.
# Correlation Pearson coefficient
def corrpe(X = np.array([1, 2, 3]), Y = np.array([2, 3, 4]), 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
# ind = 4 - redundant parameter
import math
import numpy as np
if ind in {0, 1}:
X, Y, ind = kod.ucitaj()
Sum_xy = sum((X-X.mean())*(Y-Y.mean()))
Sum_x2 = sum((X-X.mean())**2)
Sum_y2 = sum((Y-Y.mean())**2)
r = Sum_xy / np.sqrt(Sum_x2 * Sum_y2)
if ind in {0, 2}:
print('\nPrvi niz:')
print(X)
print('\nDrugi niz:')
print(Y)
print('\nPearson Correlation')
print('r =', r)
return
return X, Y, r
Тестирамо овај модул, Питон програм (3.11.0), следећим позивањем:
import numpy as np
import kod
x = np.array([22, 35, 29, 34, 39, 42, 45])
y = np.array([12, 24, 17, 23, 29, 33, 36])
ind = 3
a, b, r = kod.corrpe(x, y, ind)
print('r =', r)
На излазу добијамо:
r = 0.9943382674616695
Низови a и b су улазни x и y. То је пример из блога (Boiled frog).
1.10. Линеарна регресија је програм 'r = kod.linreg(x, y, ind)'. Улазни параметри 'x' и 'y' су n-члани низови реалних бројева са излазним коефицијентом r ∈ [-1, 1]. Трећи улазни праметар 'ind', када је 0 диктираће улаз тастатуром са графом на екрану, а индикатор 2 биће улаз варијаблама. Излаз графом на екран је увек. Штампа се коефицијент детерминације, означен са r², који је квадрат Пирсоновог коефицијент корелације r. Затим, пресек a линије са ординатом и нагиб b од параметара линеарне јеначине y = a + bx. Модул, програм Python (3.11.0) је:
# Linear Regression y = a + bX
# pip install numpy pandas matplotlib scikit-learn
def linreg(X = np.array([1, 2, 3]), y = np.array([2, 3, 4]), 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
# izlaz grafa na ekran je uvek
import math
import numpy as np
# pip install numpy pandas matplotlib scikit-learn
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
if ind in {0, 1}:
X, Y, ind = ucitaj()
X = X.reshape((-1, 1))
model = LinearRegression()
model.fit(X, y)
r2 = model.score(X, y)
a = model.intercept_
b = model.coef_
# Предвиђање на основу постојећих података
y_pred = model.predict(X)
# Предвиђање на основу нових података
x_new = np.array([10, 20, 30]).reshape((-1, 1))
y_new_pred = model.predict(x_new)
if ind in {0, 2}: # ispis teksta na ekran
print(f"Коефицијент детерминације (r^2): {r2}")
#print(f"Пресек (a): {model.intercept_}")
print("Пресек (a):", a)
print(f"Нагиб (b): {model.coef_}")
print("Предвиђање нових, за X = (10, 20, 30):")
print("y =", y_new_pred)
# crtanje grafa
plt.scatter(X, y, color='blue', label='Задате тачке')
plt.plot(X, y_pred, color='red', label='Најбоља линија')
plt.xlabel('Независна варијабла x')
plt.ylabel('Зависна y = a + bx')
plt.title('Линеарна регресија')
plt.legend()
plt.show()
return r2, a, b
На пример, позивом овог модула са:
x = np.array([22, 35, 29, 34, 39, 42, 45]) y = np.array([12, 24, 17, 23, 29, 33, 36]) ind = 2 kod.linreg(x, y, ind)
добијамо следећи испис на екран:
Коефицијент детерминације (r^2): 0.9887085901386748 Пресек (a): -13.155624036979983 Нагиб (b): [1.0816641] Предвиђање нових, за X = (10, 20, 30): y = [-2.33898305 8.47765794 19.29429892]
такође и слика графа коју можете видети у мом блогу о линеарној регресији (Python program).
1.11. Учитавање n-торки бројева је програм 'x, y, ind = kod.ucitaj(X, Y, ind)'. Ако су дати улазни низови бројева 'x' и 'y' биће сведени на n-члане векторе. Трећи улазни праметар 'ind', су индикатори којима бирамо улаз-излаз екраном-параметрима. На излазу су учитани, обрађени низови. То је помоћни модул, за позивање из других:
# Učitavanje dve n-torke brojeva vektora-kolona
def ucitaj(X = np.array([1, 2, 3]), Y = np.array([2, 3, 4]), 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
# ind = 4 - redundant parameter
import numpy as np
if ind in {0, 1}:
X = print('Niz n brojeva, sa razmakom između, x:')
X = [float(X) for X in input().split()]
n = len(X)
X = np.array(X).reshape(n, 1)
Y = print('Niz', n,'brojeva, sa razmakom između, y:')
Y = [float(Y) for Y in input().split()]
n = len(Y)
Y = np.array(Y).reshape(n, 1)
# izjednačavanje dužina nizova
n = min(len(X),len(Y))
X = X[:n]
Y = Y[:n]
if ind in {0, 2}:
print('\nImate dva niza:')
print(X)
print(Y)
return X, Y, ind
На пример, позивом:
x = np.array([1.1, -2.2, +3.3, 4]) y = np.array([4.1, -5.2, 6.3]) ind = 3 a, b, c = kod.ucitaj(x, y, ind)
добија се одзив:
print(a,b,c) [ 1.1 -2.2 3.3] [ 4.1 -5.2 6.3] 3
који каже да су учитана поменута два (3-члана) низа индексом 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
Као што се види, шема паковања њих више у мање је:
и слично са осам малих слова. Избор сам тестирао на роману 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("")
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
Следи код који генерише слику десно као пример непосредног позива овог програма из 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).
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
Подразумевани прозор је (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
На пример, цртамо тачке програма 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' петље.
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()
добијам горњу слику шест Беселових функција.
3.5. Поларно граф линије. Програм polarline() је модул који црта граф линије у поларним координатама.
def polarline(): # A line plot on a polar axis
import matplotlib.pyplot as plt
import numpy as np
r = np.arange(0, 2, 0.01)
theta = 2 * np.pi * r
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
ax.plot(theta, r)
ax.set_rmax(2)
ax.set_rticks([0.5, 1, 1.5, 2]) # Less radial ticks
ax.set_rlabel_position(-22.5) # Move radial labels away from plotted line
ax.grid(True)
ax.set_title("A line plot on a polar axis", va='bottom')
plt.show()
return
Позива се са kod.polarline().
3.6. Поларно граф преламања светлости гравитацијом. Програм polarrlg() је модул који црта граф линије у поларним координатама.
def polarrlg(): # Refraction of Light by Gravity
import matplotlib.pyplot as plt
import numpy as np
theta = np.arange(0, 3, 0.01)[15:] #Produce theta variable
r = 1/(0.5*np.sin(theta) + 0.05*(1 + np.cos(2*theta)/3)) #Input polar equation
fig = plt.figure() #Make plt figure
ax = fig.add_subplot(polar=True) #Make sub-plot with attribute "polar"
#change negative r values to positive
theta = np.where(r >= 0, theta, theta + np.pi)
r = np.abs(r)
ax.plot(theta, r) #Plot function
plt.show() #Show plot
return
Позива се са kod.polarrlg(). Слика ми је послужила као подлога одговора (Metrics IV) о преламању светлости гравитацијом 30.03.2025.
3.7. Инплицитно црта два графа. Програм impct2() је модул који црта граф јединичне кружнице и њене матричне слике: f1 : x² + y² = 1 и f2 : b1x² + b2xy + b3y². Ту је Af1 = f2, при чему су коефицијенти матрице A редом a11 = 1,15, a12 = a21 = 1,05 и a22 = 1,12. Нема улазних-излазних параметара.
# Graph of two implicit functions, the unit circle and its matrix image
def impct2():
from sympy import symbols, plot_implicit, Eq
x, y = symbols('x y')
# Matrix A
a11 = 1.15
a12 = a21 = 1.05
a22 = 1.12
# Image of the unit circle by matrix A
b1 = a11**2 + a21**2 # 2.425
b2 = 2*(a11*a12 + a21*a22) # 4.767
b3 = a12**2 + a22*2 # 3.3425
f1 = plot_implicit(Eq(x**2 + y**2, 1), (x, -2, 2), (y, -2, 2), line_color='steelblue', show=False)
f2 = plot_implicit(Eq(b1*x**2 + b2*x*y + b3*y**2, 1), (x, -2, 2), (y, -2, 2), line_color='crimson', show=False)
f1.append(f2[0])
f1.show()
return
Позива се са kod.impct2(). Слика ми је послужила као подлога одговора (Scope) у одговору о 2-нормама вектора и матрице.
4. Игре
4.1. Матрица игре. Програм mgames(n, ind) је модул који креира n × n матрицу вођен индикатором ind. Ручно (ind ∈ {0, 1}) уносите било које целе бројеве, а ако је то варијаблом (n ∈ ℕ) генерише се низ насумичних целих бројева од -n до n у пољима матрице mat.
# Matrica igre nxn, unosom ili generatorom
def mgames(n=3, ind=2):
# n - red matrice i brojevi od -n do n vrednosti polja
# 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
import numpy as np
if ind not in {0, 1, 2, 3}:
print('Indikator nekorektan!')
return
# Enter a matrix row and a sequence of numbers with spaces between
if ind in {0, 1}:
n = int(input('Red kvadratne matrice (rows of sqare matrix) = '))
x = print('Unesite matricu, niz brojeva sa prazninama između: ')
#niz = [float(x) for x in input().split()]
niz = [int(x) for x in input().split()]
mat = np.array(niz).reshape(n, n)
elif ind in {2, 3}:
n2 = n*n
niz = []
for x in range(n2):
niz.append(random.randint(-n, n))
mat = np.array(niz).reshape(n, n)
if ind in {0,2}:
print('\nImate matricu:')
print(mat)
return
return mat
Позива се са m = kod.mgames(n, ind), ако је ind број 1 или 3, иначе може kod.mgames(n, ind). Један је у низу програма за тестирање тврдње у блогу (Strategies).
4.2. Игра A → B. Програм abgame(n, ind) је модул који креира n × n матрицу вођен индикатором ind. Са ind ∈ {0, 1} ручно уносите ред матрице n ∈ ℕ, а програм mgames(n, 3) генерише низ насумичних целих бројева од -n до n у пољима те матрице игре. Играч A бира ред са најмањим елементима, а играч B из њега узима највећи naj.
# A and B play the minimax strategy, mgames()
def abgame(n=3, ind=3):
# n - red matrice i brojevi od -n do n vrednosti polja
# 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
import numpy as np
if ind in {0, 1}:
n = int(input('Red kvadratne matrice (rows of sqare matrix) = '))
mat = mgames(n, 3)
if ind in {0, 2}:
print('\nMatrica:')
print(mat)
# Selects A row with the smallest maximum
red = 0
vrh = n
for i in range(n):
naj = 0
for j in range(n):
if mat[i][j] > naj:
naj = mat[i][j]
if ind in {0, 2}:
print(i+1, naj)
if vrh > naj:
red = i
vrh = naj
# Selects B largest element from the A row
naj = -n
for j in range(n):
if naj < mat[red][j]:
naj = mat[red][j]
if ind in {0, 2}:
print('Red =',red + 1, 'Naj =', naj)
return naj
Позива се са naj = kod.abgame(n, ind), ако је ind број 1 или 3, иначе може kod.mgames(n, ind) када ће се Naj (највећи број) штампати на екрану.
5. Расподеле
5.1. Случајни ход 1-дим. Програм hod1d(n, ind) је модул рађен за блог (Random Walk III, 3). Питонов програм је једноставан:
def hod1d(n=3, ind=2): #random walk 1-dim
# n - broj koraka, desno isto i levo
# 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
from math import comb
if ind in {0, 1}:
n = int(input('Broj koraka desno/levo: '))
p1 = 0.5 #verovatnoća jednog koraka, desno i levo
n2 = 2*n #koraka desno + levo
zc = 0 #zbirno kombinacija
pr = 0 #zbir svih verovatnoća
for k in range(1,n+1):
k2 = k*2
p2 = p1**k2 #verovatno dvokoraka, desno-levo
c = comb(k2,k)
pk = p2*c #verovatnoca k-tog
pr = pr + pk #zbirna verovatnoca
if ind in {0, 2}:
print(f"Koraka {k2}, verovatnoća {pk}, zbirno {pr}")
return pr
Када се позове наредбама:
n, ind = 4, 2 kod.hod1d(n, ind)
на екрану изађе:
Koraka 2, verovatnoća 0.5, zbirno 0.5 Koraka 4, verovatnoća 0.375, zbirno 0.875 Koraka 6, verovatnoća 0.3125, zbirno 1.1875 Koraka 8, verovatnoća 0.2734375, zbirno 1.4609375
Програм демонстрира понављајући (енг. recurrent) слободни ход по једној оси, за разлику од пролазног (transient) у 3-дим простору.
5.2. Случајни ход 2-дим. Програм hod2d(n, ind) други је Питонов модул за проверу враћања на полазиште слободног тетурања, сада у равни, за потребе блога (Random Walk III, 4):
def hod2d(n=3, ind=2): #random walk 2-dim
# n - broj koraka, desno isto i levo
# 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
def opcije(k, n): # kombinacije
p, n2 = 0.25, n*2
r = p**k # izbegavamo velike brojeve
for i2 in range(k+1, n+1): r = p*r*i2/(i2-k)
for i3 in range(n+1, n+k+1): r = p*r*i3/(i3-n)
for i4 in range(n+k+1, n2): r = p*r*i4/(n2-i4)
return r
if ind in {0, 1}:
n = int(input('Broj koraka desno/levo: '))
z = 0 #zbirno kombinacija * verovatnoća
for k in range(n+1): z = z + opcije(k,n)
if ind in {0, 2}: print(n*2, z)
return z
Позовимо га са:
n, ind = 18, 2 kod.hod2d(n, ind)
и добићемо испис на екран:
Koraka 36, verovatnoća 0.017440001959199807
Као и претходни, brown1(), овај модул је рађен да провери понављање (енг. recurrent) слободног хода, али не по једној оси него у равни, за разлику од пролазног (transient) у 3-дим простору. Када нам треба збир свих вероватноћа за више таквих (половичних n) путева, користимо петљу, на пример:
z = 0
for n in range (1,12):
n2 = n*2
pr = kod.hod2d(n, 3)
z = z + pr
print(f"Koraka {n2}, verovatnoća {pr}, zbirna {z}")
На екрану је испис:
Koraka 2, verovatnoća 0.375, zbirna 0.375 Koraka 4, verovatnoća 0.1640625, zbirna 0.5390625 Koraka 6, verovatnoća 0.1025390625, zbirna 0.6416015625 Koraka 8, verovatnoća 0.075836181640625, zbirna 0.717437744140625 Koraka 10, verovatnoća 0.060802459716796875, zbirna 0.7782402038574219 Koraka 12, verovatnoća 0.05094408988952637, zbirna 0.8291842937469482 Koraka 14, verovatnoća 0.043891578912734985, zbirna 0.8730758726596832 Koraka 16, verovatnoća 0.038568342570215464, zbirna 0.9116442152298987 Koraka 18, verovatnoća 0.03440004395088181, zbirna 0.9460442591807805 Koraka 20, verovatnoća 0.031045569168782094, zbirna 0.9770898283495626 Koraka 22, verovatnoća 0.028287275430102454, zbirna 1.005377103779665
Са 22 и више корака (n = 11 десно и 19 лево) овај збир вероватноћа говори о добрим шансама повратка случајне тачке на почетно место. У 2-дим равни повратак је дупло спорији него на 1-дим оси.
6. Датуми
6.1. Данашњи дан и текуће време са редним бројем дана у истој години. Модул d, b = dandan(ind) је Питон програм који налази данашњи датум (d) са тренутним временом и израчунава редни број дана (b) у текућој години. Програми су и примери за блог Dates.
def dandan(ind = 0):
# ind = 0 - izlaz na ekran datuma i broja dana
# ind = 1 - izlaz na ekran samo datuma
# ind = 2 - izlaz na ekran samo broj dana
# ind = 3 - izlaz samo varijabama datuma i broja
from datetime import datetime
danas = datetime.now() # današnji datum gggg-mm-dd hh:mm:ss
broj = danas.strftime('%j') # редни број дана у години
if ind in {0, 1}:
print("gggg-mm-dd hh:mm:ss")
print(f"Sadašnji datum i vreme su: {danas}")
if ind in {0, 2}:
print(f"Redni broj dana u godini (string): {broj}")
return danas, broj
Модул позивамо са:
ind = 0 d, b = kod.dandan(ind)
да на екрану добијемо datum и broj дана:
gggg-mm-dd hh:mm:ss Sadašnji datum i vreme su: 2026-04-08 19:07:13.547834 Redni broj dana u godini (string): 098
Прво су датум и време у формату gggg-mm-dd hh:mm:ss, а друго је редни број тог дана.
6.2. Неки дан за задати датум даје његов редни број у тој години. Модул x, y = nekdan(datum, ind) је Питон програм који користи текст (стринг) датума облика gggg-mm-dd и израчунава његов редни број, број претходних дана у датој години:
def nekdan(datum = "2026-04-08", ind=0):
# ind = 0 - ulaz tastaturom gggg-mm-dd, izlaz na ekran
# ind = 1 - ulaz tastaturom, izlaz varijablom
# ind = 2 - ulaz varijablom, izlaz na ekran
# ind = 3 - ulaz varijablom, izlaz varijablom
if ind not in {0, 1, 2, 3}:
print("Pogresan indikator!")
return datum, ind
from datetime import datetime
if ind in {0, 1}:
try:
datum = input("Unesite datum (gggg-mm-dd): ")
datum1 = datetime.strptime(datum, "%Y-%m-%d")
datum2 = datum1.date()
except ValueError:
print("Neispravan format, koristite YYYY-MM-DD.")
datum2 = datetime.now() # sada gggg-mm-dd hh:mm:ss
if ind in {2, 3}:
datum1 = datetime.strptime(datum, "%Y-%m-%d")
datum2 = datum1.date()
rbr = datum2.timetuple().tm_yday
if ind in {0, 2}:
print("Unešeni datum:", datum2, "dan:", rbr)
return datum2, rbr
Прво је датум (x) у формату gggg-mm-dd, а друго је редни број (y) тог дана те године. Са индексом 2 и 3, а са лошим форматом datum добићете само упозорење "Neispravan format, koristite YYYY-MM-DD."
6.3. Број дана између два датума даје програм d1, d2, br = kod.brdana(). Нема улазних параметара, а излазни су први датум (d1), други датум (d2) и број дана између њих (br):
def brdana(): # Definiši svoje datume, nema ulaznih parametara
from datetime import date, datetime, timedelta
date_format = "%Y-%m-%d"
date1 = input("Unesi datum (%Y-$m-$d) ili ostaje 2021-6-1: ")
if date1 == "":
date1 = '2021-6-1'
d1 = datetime.strptime(date1, date_format).date()
date2 = input("Unesi drugi (%Y-$m-$d), ili ostaje današnјi: ")
if date2 == "":
date2 = datetime.now().strftime("%Y-%m-%d")
d2 = datetime.strptime(date2, date_format).date()
br = (d2 - d1).days
return d1, d2, br # tri izlazna parametra
Позовемо ли програм са:
import kod x, y, z = kod.brdana() print(x, y, z)
на екрану добијамо:
Unesi datum (%Y-$m-$d) ili ostaje 2021-6-1: Unesi drugi (%Y-$m-$d), ili ostaje današnјi: 2021-06-01 2026-06-14 1839
Прескочен је унос датума (Enter), а данас је 14. јуни 2026. Број дана од 1. јуна 2021. до данас је 1839.
6.4. Дану (датум d1) додамо број дана (b) до датума (d2). То ради d1, d2, b = danabr(datum, broj, ind), са улазним и излазним датумима формata "gggg-mm-dd", не и унутрашњим.
def danabr(datum="1957-5-18", broj=10, ind=0):
# Dati datum1 + broj dana --> datum2
# format datuma YYYY-MM-DD
# 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
from datetime import date, timedelta
if ind in {0, 1}:
datum = input("Unesite datum (gggg-mm-dd): ")
broj = input("Unesite broj dana: ")
year, month, day = map(int, datum.split("-"))
datum1 = date(year, month, day)
broj1 = int(broj)
datum2 = datum1 + timedelta(days=broj1)
if ind in {0, 2}:
print(f"Drugi datum je: {datum2}")
return datum1, datum2, broj
Уносимо и позивамо модул:
import kod datum = "2026-3-14" broj = 15 ind = 2 x, y, z = kod.danabr(datum, broj, ind) print(x, y, z)
и добијамо на екрану:
Drugi datum je: 2026-03-29 2026-03-14 2026-03-29 15
Програм интерно ради са датумима облика date(2026, 3, 14). Када мањем датуму додамо +15 дана добијамо већи, а ако већем додамо -15 добићемо мањи датум.