Thursday, April 2, 2020

Drugi razred - Lekcija 4

5. Угнежђене петље

У овој лекцији показујемо:
  1. како раде угнежђене петље,
  2. како се користе угнежђене петље за исписивање табела са подацима, и
  3. како се обрађују подаци представљени табелама.

5.1. Петља у петљи

Када се у телу петље нађе друга петља, као у овом примеру:
print("Tablica mnozenja 5 x 5")
for i in range(5):
    print("Tablica mnozenja sa", i+1)
    ######### ovo je petlja u petlji
    for j in range(5):
        print(i+1, "*", j+1, "=", (i+1) * (j+1))

онда кажемо да је друга петља угнежђена, јер је обухваћена оном првом као у гнезду. За прву кажемо још и да је спољашња петља, док је ова друга унутрашња. Погледајмо како овај прогам ради:
In [1]:
print("Tablica mnozenja 5 x 5")
for i in range(5):
    print("Tablica mnozenja sa", i+1)
    ######### ovo je petlja u petlji
    for j in range(5):
        print(i + 1, "*", j + 1, "=", (i + 1)*(j + 1))
Tablica mnozenja 5 x 5
Tablica mnozenja sa 1
1 * 1 = 1
1 * 2 = 2
1 * 3 = 3
1 * 4 = 4
1 * 5 = 5
Tablica mnozenja sa 2
2 * 1 = 2
2 * 2 = 4
2 * 3 = 6
2 * 4 = 8
2 * 5 = 10
Tablica mnozenja sa 3
3 * 1 = 3
3 * 2 = 6
3 * 3 = 9
3 * 4 = 12
3 * 5 = 15
Tablica mnozenja sa 4
4 * 1 = 4
4 * 2 = 8
4 * 3 = 12
4 * 4 = 16
4 * 5 = 20
Tablica mnozenja sa 5
5 * 1 = 5
5 * 2 = 10
5 * 3 = 15
5 * 4 = 20
5 * 5 = 25
Угнежђене петље се природно јављају када радимо са табелама података, или са подацима који треба да буду организовани у две димензије (и хоризонтално и вертикално).
Пример. Написати програм који приказује таблицу множења 10 x 10:
*12345678910
112345678910
22468101214161820
336912151821242730
4481316202428323640
55101520253035404550
66121824303642485460
77142128354249566370
88162432404856647280
99182736455463728190
10102030405060708090100
Решење. Први покушај да се овај проблем реши би могао да изгледа овако:
In [2]:
print("Tablica mnozenja 10 x 10")
for i in range(10):
    for j in range(10):
        print((i + 1)*(j + 1))
Tablica mnozenja 10 x 10
1
2
3
4
5
6
7
8
9
10
2
4
6
8
10
12
14
16
18
20
3
6
9
12
15
18
21
24
27
30
4
8
12
16
20
24
28
32
36
40
5
10
15
20
25
30
35
40
45
50
6
12
18
24
30
36
42
48
54
60
7
14
21
28
35
42
49
56
63
70
8
16
24
32
40
48
56
64
72
80
9
18
27
36
45
54
63
72
81
90
10
20
30
40
50
60
70
80
90
100
али видимо да то није оно што смо желели. Желимо таблицу множења да испишемо као таблицу. Проблем је у томе што наредба print пређе у нови ред чим нешто испише, а ми желимо да испишемо низ бројева у једном реду пре него што пређемо у нови ред.
Наредби print можемо рећи да не прелази у нови ред тако што као опцију додамо
end = ""

Тада ће све што наредба испише бити смештено у исти ред. Када завршимо исписивање бројева који треба да буду у истом реду прелазимо у нови ред наредбом
print()

Ова наредба, заправо, ништа не испише, већ само пређе у нови ред.
In [3]:
print("Tablica mnozenja 10 x 10")
for i in range(10):
    for j in range(10):
        print((i + 1)*(j + 1), end="")
    print()
Tablica mnozenja 10 x 10
12345678910
2468101214161820
36912151821242730
481216202428323640
5101520253035404550
6121824303642485460
7142128354249566370
8162432404856647280
9182736455463728190
102030405060708090100
Сада је мало боље, али и даље далео од онога што желимо. Треба нам мали размак између бројева. То је лако додати:
In [4]:
print("Tablica mnozenja 10 x 10")
for i in range(10):
    for j in range(10):
        print((i + 1)*(j + 1), " ", end="")
    print()
Tablica mnozenja 10 x 10
1  2  3  4  5  6  7  8  9  10  
2  4  6  8  10  12  14  16  18  20  
3  6  9  12  15  18  21  24  27  30  
4  8  12  16  20  24  28  32  36  40  
5  10  15  20  25  30  35  40  45  50  
6  12  18  24  30  36  42  48  54  60  
7  14  21  28  35  42  49  56  63  70  
8  16  24  32  40  48  56  64  72  80  
9  18  27  36  45  54  63  72  81  90  
10  20  30  40  50  60  70  80  90  100  
Добили смо таблицу множења у принципу. Једини је проблем у томе што су редови и даље неуредни.
Да бисмо у таблици поравнали редове није, дакле, довољно само додати мали размак, већ треба обезбедити да сваки број буде исписан на исти број места независно од тога да ли број има једну, две или три цифре. За то ћемо користити уграђену функцију format која форматира, односно, приказује податке на посебан начин. На пример,
In [5]:
format("Python", "15")
Out[5]:
'Python         '
ће од стринга "Python" направити нови стринг "Python " који има дужину 15, а садржај је поравнат по левој ивици. С друге стране,
In [6]:
format(56, "4")
Out[6]:
'  56'
број 56 форматирати као стринг дужине 4 у коме је садржај поравнат по десној ивици.
Видимо да податак који форматирамо може dа буде и стринг и број, али други аргумент функције format који објашњава функцији како да форматира садржај увек мора бити стринг. Разлог је у томе што стринг који описује захтеве може бити веома компликован и може да садржи и симболе који нису цифре. На пример,
In [7]:
format("Python", "^15")
Out[7]:
'    Python     '
ће од стринга "Python" направити нови стринг " Python " који има дужину 15, а садржај је центриран.
Коначно, ево програма који исписује таблицу множења као табелу:
In [8]:
print("Tablica mnozenja 10 x 10")
for i in range(10):
    for j in range(10):
        print(format((i + 1)*(j + 1), "4"), end="")
    print()
Tablica mnozenja 10 x 10
   1   2   3   4   5   6   7   8   9  10
   2   4   6   8  10  12  14  16  18  20
   3   6   9  12  15  18  21  24  27  30
   4   8  12  16  20  24  28  32  36  40
   5  10  15  20  25  30  35  40  45  50
   6  12  18  24  30  36  42  48  54  60
   7  14  21  28  35  42  49  56  63  70
   8  16  24  32  40  48  56  64  72  80
   9  18  27  36  45  54  63  72  81  90
  10  20  30  40  50  60  70  80  90 100
Пример. Написати Пајтон функцију trougao_brojeva(n) која исписује следећи троугао бројева:
1
1  2
1  2  3
1  2  3  4
1  2  3  4  5

итд. Ово је пример позива функције за n = 5.
Решење.
In [9]:
def trougao_brojeva(n):
    for i in range(n + 1):
        for j in range(i):
            print(format(j+1, "4"), end="")
        print()
Да видимо како функција ради:
In [10]:
trougao_brojeva(6)
   1
   1   2
   1   2   3
   1   2   3   4
   1   2   3   4   5
   1   2   3   4   5   6
Пример. Написати Пајтон функцију trougao_brojeva_2(n) која исписује следећи троугао бројева:
 1
 2   3
 4   5   6
 7   8   9  10
11  12  13  14  15

итд. Ово је пример позива функције за n = 5. Видимо да троугао има n редова, да су дужине редова 1, 2, 3, ..., n, и да се бројеви редом уписују у табелу.
Решење.
Идеја решења је да уведемо бројач који ће садржати следећи број који треба уписати на одговарајуће место, док ће две петље само регулисати облик троугла, овако:
In [11]:
def trougao_brojeva_2(n):
    broj = 1
    for i in range(n + 1):
        for j in range(i):
            print(format(broj, "5"), end="")
            broj += 1
        print()
Да видимо како функција ради:
In [12]:
trougao_brojeva_2(6)
    1
    2    3
    4    5    6
    7    8    9   10
   11   12   13   14   15
   16   17   18   19   20   21
Пример. Наћи све бројеве са највише четири цифре који су једнаки трећем степену збира својих цифара.
Решење. Број са највише четири цифре се може записати у облику abcd, при чему је дозвољено да свака од цифара буде нула (траже се бројеви са највише четири цифре; према томе, за троцифрени број ће бити a=0).
Дакле, тражимо бројеве abcd такве да је abcd=(a+b+c+d)3. Подсетимо се још да је:abcd=1000a+100b+10c+d.Сада се програм лако пише:
In [13]:
for a in range(9):
    for b in range(9):
        for c in range(9):
            for d in range(9):
                if 1000*a + 100*b + 10*c + d == (a + b + c + d)**3:
                    print(1000*a + 100*b + 10*c + d)
0
1
512
5832

5.2. Табеле са подацима

Веома често су подаци у вези са неким проблемом представљени табелом. Рецимо, ова табела садржи податке о једној групи деце (при чему је, наравно, старост изражена у годинама, маса у килограмима, а висина у центиметрима):
ImePolStarostMasaVisina
Anaž1346160
Bojanm1452165
Vladam1347157
Gordanaž1554165
Dejanm1556163
Đorđem1345159
Elenaž1449161
Žaklinaž1552164
Zoranm1557167
Ivanaž1345158
Jasnaž1451162
Да бисмо могли машински да обрађујемо и анализирамо податке, прво их морамо представити на погодан начин.
Један једноставан начин да се то уради је да сваки ред табеле представимо једном низом, и да потом све те низове запакујемо у један велики низ, рецимо овако:
In [14]:
razred = [["Ana",     "ž", 13, 46, 160],
          ["Bojan",   "m", 14, 52, 165],
          ["Vlada",   "m", 13, 47, 157],
          ["Gordana", "ž", 15, 54, 165],
          ["Dejan",   "m", 15, 56, 163],
          ["Đorđe",   "m", 13, 45, 159],
          ["Elena",   "ž", 14, 49, 161],
          ["Žaklina", "ž", 15, 52, 164],
          ["Zoran",   "m", 15, 57, 167],
          ["Ivana",   "ž", 13, 45, 158],
          ["Jasna",   "ž", 14, 51, 162]]
Као и у већини модерних програмских језика, индекси елемената низа у Пајтону почињу од нуле, тако да
In [15]:
razred[0]
Out[15]:
['Ana', 'ž', 13, 46, 160]
даје први ред табеле,
In [16]:
razred[1]
Out[16]:
['Bojan', 'm', 14, 52, 165]
даје други ред табеле, и тако даље.
Ако желимо да видимо колико је висок Влада, написаћемо
In [17]:
razred[2][4]
Out[17]:
157
зато што се подаци о Влади налазе у трећем реду табеле (чији индекс је 2 -- индексирање почиње од нуле!), а висина се налази у том низу на петом месту (чији индекс је 4). Дакле, овај ред каже:
из табеле razred одабери прво ред са индексом 2, па из тог реда податак са индексом 4 (при томе водећи рачуна да индексирање почиње од нуле!)
Ако желимо да израчунамо просечну висину ученика у разреду учинићемо то овако:
In [18]:
br_ucenika = len(razred)
zbir = 0
for ucenik in razred:
    zbir += ucenik[4]
print("Prosecna visina je", zbir/br_ucenika)
Prosecna visina je 161.9090909090909
Ако желимо да пребројимо колико у разреду има дечака, а колико девојчица, можемо то учинити овако (имајући у виду да се информација о полу налази на другом месту у реду, чији индекс је 1):
In [19]:
br_decaka = 0
br_devojcica = 0
for ucenik in razred:
    if ucenik[1] == "m":
        br_decaka += 1
    else:
        br_devojcica += 1
print("Decaka ima", br_decaka)
print("Devojcica ima", br_devojcica)
Decaka ima 5
Devojcica ima 6
Ево како можемо одредити највишу девојчицу:
In [20]:
# ne znamo koja devojcica je najvisa, pa stavljamo prazan string u ime
ime = ""
# ne znamo nista o njenoj visini, pa stavljamo vrednost koja je manja od svake razumne vrednosti
visina = 0
for ucenik in razred:
    if ucenik[1] == "ž" and ucenik[4] > visina:
        ime = ucenik[0]
print("Najvisa devojcica je", ime)
Najvisa devojcica je Jasna

5.3. Задаци

Задатак 1. Испистати таблицу сабирања за цифре десетичног система:
+0123456789
00123456789
112345678910
2234567891011
33456789101112
445678910111213
5567891011121314
66789101112131415
778910111213141516
8891011121314151617
99101112131415161718
Задатак 2. Написати функцију spec_trougao(n) која исписује првих n редова следећег троугла бројева:
(а)
1
1 1
1 1 1
1 1 1 1

(б)
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1

(в!)
1
2  3  2
3  4  5  4  3
4  5  6  7  6  5  4
5  6  7  8  9  8  7  6  5
Задатак 3. Написати функцију zmijasto(n) која бројеве 1, 2, 3, ..., n2 уписује у квадрат n×n "змијасто". На пример, за n = 5 функција исписује
 1   2   3   4   5
10   9   8   7   6
11  12  13  14  15
20  19  18  17  16
21  22  23  24  25
Задатак 4. Наћи све бројеве са највише четири цифре који су једнаки
(а) квадрату збира својих цифара;
(б) четвртом степену збира својих цифара.
Задатак 5*. Наћи сва могућа дешифровања следећег сабирања:
АВ + ... + АВ = ЛАВ

где са десне стране имамо најмање два сабирка. Наравно, истим словима одговарају исте цифре, а различитим словима различите. При томе цифре А и Л не смеју да буду 0.
Задатак 6*. Наћи сва могућа дешифровања следећег сабирања:
ЛАВ + ... + ЛАВ = МРАВ

где са десне стране имамо најмање два сабирка. Наравно, истим словима одговарају исте цифре, а различитим словима различите. При томе цифре Л и М не смеју да буду 0.
Задатак 7. Дати су подаци о ученицима једног разреда:
In [21]:
razred = [["Ana",     "ž", 13, 46, 160],
          ["Bojan",   "m", 14, 52, 165],
          ["Vlada",   "m", 13, 47, 157],
          ["Gordana", "ž", 15, 54, 165],
          ["Dejan",   "m", 15, 56, 163],
          ["Đorđe",   "m", 13, 45, 159],
          ["Elena",   "ž", 14, 49, 161],
          ["Žaklina", "ž", 15, 52, 164],
          ["Zoran",   "m", 15, 57, 167],
          ["Ivana",   "ž", 13, 45, 158],
          ["Jasna",   "ž", 14, 51, 162]]
Написати Пајтон програм који одређује
(а) ко је најлакши у разреду;
(б) ко је налјакши дечак у разреду.
Задатак 8. У следећој табели су дати подаци о националним парковима Србије. За сваки национални парк је наведено његово име, површина у хектарима и година оснивања:
In [22]:
nac_parkovi = [["Fruška gora", 25393, 1960],
               ["Đerdap",      64000, 1974],
               ["Tara",        22000, 1981],
               ["Kopaonik",    11810, 1981],
               ["Šar-planina", 39000, 1985]]
Напиши Пајтон програм који рачуна просечну површину националног парка (у хектарима), и укупну површину коју заузимају национални паркови у Србији (у квадратним километрима; 1 квадратни километар = 100 хектара).
Задатак 9. Производња кукуруза и пшенице у периоду 2008-2012. у Србији је дата у следећој табели (подаци су исказани у хиљадама тона):
GodinaKukuruzPšenica
2008.6.1582.095
2009.6.3962.067
2010.7.2071.631
2011.6.4802.076
2012.3.5321.911
(а) Напиши Пајтон програм који рачуна максималну производњу кукуруза и минималну производњу пшенице у наведеном периоду.
(б) Напиши Пајтон програм који рачуна просечну годишњу производњу кукуруза за наведени период, као и за колико се разликовала производња пшенице у најбољој и најлошијој години наведеног периода (у хиљадама тона).
Задатак 10. Ево трошкова живота једне породице током једне године, по месецима (сви износи су представљени у динарима):
StavkaJanFebMarAprMajJunJulAvgSepOktNovDec
Stanarina8.2518.4368.5248.3888.2418.1968.0047.9967.9918.0158.3538.456
Struja4.3214.5304.1153.9903.9853.7263.3513.2893.2953.4853.8263.834
Telefon (fiksni)1.4251.5381.6231.4891.5211.4851.4911.3991.4671.5311.4101.385
Telefon (mobilni)2.1812.2352.0731.9511.9891.9453.0172.6382.1711.8311.9261.833
TV i internet2.3992.3992.3992.3992.3992.3992.3992.3992.3992.3992.3992.399
Prevoz1.8301.8301.8301.8301.9501.9501.4501.4501.9501.9502.0502.050
Hrana23.25023.78024.01924.11724.38924.57124.73624.95125.11125.38925.53125.923
Ostalo4.5003.7005.1003.5002.7504.2507.3208.2503.2704.2903.2008.390
У ћелији испод су исти подаци представљени табелом:
In [23]:
troskovi = [
  ["Stanarina", 8251, 8436, 8524, 8388, 8241, 8196, 8004, 7996, 7991, 8015, 8353, 8456],
  ["Struja", 4321, 4530, 4115, 3990, 3985, 3726, 3351, 3289, 3295, 3485, 3826, 3834],
  ["Telefon (fiksni)", 1425, 1538, 1623, 1489, 1521, 1485, 1491, 1399, 1467, 1531, 1410, 1385],
  ["Telefon (mobilni)", 2181, 2235, 2073, 1951, 1989, 1945, 3017, 2638, 2171, 1831, 1926, 1833],
  ["TV i internet", 2399, 2399, 2399, 2399, 2399, 2399, 2399, 2399, 2399, 2399, 2399, 2399 ],
  ["Prevoz", 1830, 1830, 1830, 1830, 1950, 1950, 1450, 1450, 1950, 1950, 2050, 2050],
  ["Hrana", 23250, 23780, 24019, 24117, 24389, 24571, 24736, 24951, 25111, 25389, 25531, 25923],
  ["Ostalo", 4500, 3700, 5100, 3500, 2750, 4250, 7320, 8250, 3270, 4290, 3200, 8390]
]
Напиши Пајтон програм који рачуна укупне трошкове ове породице по месецима (колико је породица укупно потрошила у јануару, колико у фебруару итд).


Urađeni zadaci:

1.
def trougao_brojeva(n):
    for i in range(n + 1):
         for j in range(i):
             print(format(j+1, "4"), end="")
         print()
print(trougao_brojeva(6))


2.
def trougao_brojeva_2(n):
    broj = 1
    for i in range(n + 1):
        for j in range(i):
            print(format(broj, "5"), end="")
            broj += 1
        print()
print(trougao_brojeva_2(5))


3.
razred = [["Ana",     "ž", 13, 46, 160],
          ["Bojan",   "m", 14, 52, 165],
          ["Vlada",   "m", 13, 47, 157],
          ["Gordana", "ž", 15, 54, 165],
          ["Dejan",   "m", 15, 56, 163],
          ["Đorđe",   "m", 13, 45, 159],
          ["Elena",   "ž", 14, 49, 161],
          ["Žaklina", "ž", 15, 52, 164],
          ["Zoran",   "m", 15, 57, 167],
          ["Ivana",   "ž", 13, 45, 158],
          ["Jasna",   "ž", 14, 51, 162]]
br_ucenika = len(razred)
zbir = 0
for ucenik in razred:
    zbir += ucenik[4]
print("Prosecna visina je", zbir/br_ucenika)

No comments:

Post a Comment

Prvi Razred                                               Drugi razred