Prijavi problem


Obeleži sve kategorije koje odgovaraju problemu

Još detalja - opišite nam problem


Uspešno ste prijavili problem!
Status problema i sve dodatne informacije možete pratiti klikom na link.
Nažalost nismo trenutno u mogućnosti da obradimo vaš zahtev.
Molimo vas da pokušate kasnije.

Analiza i prezentacija podataka u Džupiteru

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:

* 1 2 3 4 5 6 7 8 9 10
1 1 2 3 4 5 6 7 8 9 10
2 2 4 6 8 10 12 14 16 18 20
3 3 6 9 12 15 18 21 24 27 30
4 4 8 13 16 20 24 28 32 36 40
5 5 10 15 20 25 30 35 40 45 50
6 6 12 18 24 30 36 42 48 54 60
7 7 14 21 28 35 42 49 56 63 70
8 8 16 24 32 40 48 56 64 72 80
9 9 18 27 36 45 54 63 72 81 90
10 10 20 30 40 50 60 70 80 90 100

Решење. Први покушај да се овај проблем реши би могао да изгледа овако:

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

Пример. Наћи све бројеве са највише четири цифре који су једнаки трећем степену збира својих цифара.

Решење. Број са највише четири цифре се може записати у облику $\langle abcd\rangle$, при чему је дозвољено да свака од цифара буде нула (траже се бројеви са највише четири цифре; према томе, за троцифрени број ће бити $a = 0$).

Дакле, тражимо бројеве $\langle abcd\rangle$ такве да је $\langle abcd\rangle = (a + b + c + d)^3$. Подсетимо се још да је: $$ \langle abcd\rangle = 1000 a + 100 b + 10 c + 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. Табеле са подацима

Веома често су подаци у вези са неким проблемом представљени табелом. Рецимо, ова табела садржи податке о једној групи деце (при чему је, наравно, старост изражена у годинама, маса у килограмима, а висина у центиметрима):

Ime Pol Starost Masa Visina
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 [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. Испистати таблицу сабирања за цифре десетичног система:

+ 0 1 2 3 4 5 6 7 8 9
0 0 1 2 3 4 5 6 7 8 9
1 1 2 3 4 5 6 7 8 9 10
2 2 3 4 5 6 7 8 9 10 11
3 3 4 5 6 7 8 9 10 11 12
4 4 5 6 7 8 9 10 11 12 13
5 5 6 7 8 9 10 11 12 13 14
6 6 7 8 9 10 11 12 13 14 15
7 7 8 9 10 11 12 13 14 15 16
8 8 9 10 11 12 13 14 15 16 17
9 9 10 11 12 13 14 15 16 17 18

Задатак 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, ..., $n^2$ уписује у квадрат $n \times 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. у Србији је дата у следећој табели (подаци су исказани у хиљадама тона):

Godina Kukuruz Pšenica
2008. 6.158 2.095
2009. 6.396 2.067
2010. 7.207 1.631
2011. 6.480 2.076
2012. 3.532 1.911

(а) Напиши Пајтон програм који рачуна максималну производњу кукуруза и минималну производњу пшенице у наведеном периоду.

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

Задатак 10. Ево трошкова живота једне породице током једне године, по месецима (сви износи су представљени у динарима):

Stavka Jan Feb Mar Apr Maj Jun Jul Avg Sep Okt Nov Dec
Stanarina 8.251 8.436 8.524 8.388 8.241 8.196 8.004 7.996 7.991 8.015 8.353 8.456
Struja 4.321 4.530 4.115 3.990 3.985 3.726 3.351 3.289 3.295 3.485 3.826 3.834
Telefon (fiksni) 1.425 1.538 1.623 1.489 1.521 1.485 1.491 1.399 1.467 1.531 1.410 1.385
Telefon (mobilni) 2.181 2.235 2.073 1.951 1.989 1.945 3.017 2.638 2.171 1.831 1.926 1.833
TV i internet 2.399 2.399 2.399 2.399 2.399 2.399 2.399 2.399 2.399 2.399 2.399 2.399
Prevoz 1.830 1.830 1.830 1.830 1.950 1.950 1.450 1.450 1.950 1.950 2.050 2.050
Hrana 23.250 23.780 24.019 24.117 24.389 24.571 24.736 24.951 25.111 25.389 25.531 25.923
Ostalo 4.500 3.700 5.100 3.500 2.750 4.250 7.320 8.250 3.270 4.290 3.200 8.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]
]

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