Şərtli dövr

Dövrlər haqqında mövzumuzun əvvəlində qeyd etmişdik ki, dövrlərin sayı əvvəlcədən məlum olduqda sayğaclı dövr (for), məlum olmadıqda isə şərtli dövr (while) operatorundan istifadə edilir.
Python dilində while şərtli dövrünün ümumi yazılış qaydası aşağıdakı kimidir:

while şərt:
    dövrün gövdəsi

Burada şərt kimi istənilən məntiqi ifadədən istifadə oluna bilər, dövrün gövdəsi isə icrası təkrarlanan ifadələr qrupudur. Şərtli dövrdə əvvəlcə verilmiş şərt yoxlanılır, əgər bu şərt ödənilirsə, dövrün gövdəsində yer alan ifadələr icra olunur; ödənilmirsə, o zaman dövr icra olunmur və idarəetmə dövrdən sonrakı növbəti instruksiyaya ötürülür. Şərtli dövrün icrası şərt ödənildikcə təkrarlanır.
İndi isə konkret misallara keçək. Əvvəlcə natural ədədlərin cəmini 100-dən böyük olmamaq şərtilə hesablayan proqram tərtib edək, ekrana ən son toplanan natural ədədi və yekun cəmi çıxaraq:

s = 0
i = 1
while s + i <= 100:
    s = s + i
    i = i + 1
print(i - 1, s)

Proqramımıza aydınlıq gətirək. Əvvəlcə biz cəm üçün nəzərdə tutduğumuz s dəyişəninə başlanğıc qiymət kimi sıfırı (0) mənimsədirik. Natural ədədlər üçün isə i dəyişənini götürüb, onun da ilkin qiymətini bir (1) veririk. Bundan sonra isə while dövrünü qurub dövr şərtini təyin edirik. Dövrün gövdəsində natural ədədləri cəmləyir və i dəyişəninin qiymətini hər dəfə bir vahid artırırıq. Bu hesablama prosesi şərt ödənildikcə davam edir. Dövr öz işini yekunlaşdırdıqdan sonra sonuncu toplanan natural ədədi və yekun cəmi ekrana çapa veririk.
Daha bir misala baxaq. Verilmiş ədədin rəqəmləri cəmini hesablayan proqram tərtib edək:

a = int(input("Ədədi daxil edin: ")) 
s = 0
while a > 0:
    b = a % 10 
    s = s + b 
    a = a // 10
print(s)

Nə baş verdi? Əvvəlcə biz istifadəçinin input() funksiyası ilə daxil etdiyi qiyməti int() funksiyası vasitəsilə tam ədəd tipinə çevirib a dəyişənində yadda saxladıq. Cəm üçün nəzərdə tutduğumuz s dəyişəninə isə başlanğıc qiymət kimi sıfırı (0) mənimsətdik. Daxil edilən ədədin rəqəmlərini tapmaq üçün onu hər dəfə 10-a qalıqlı və tam olaraq böldük və əldə edilən rəqəmi s dəyişəninin üzərinə gəldik. Bütün bunları dövrün gövdəsində həyata keçirdik, dövrün şərtini isə a>0 olaraq təyin etdik. Ən sonda isə ədədin rəqəmləri cəmini ekrana çapa verdik. Proqramı skriptdə yazıb icra edin və müxtəlif ədədlər daxil edərək nəticələri yoxlayın.

Sayğaclı dövrlərdə olduğu kimi, şərtli dövrlərdə də break, continueelse operatorlarından istifadə oluna bilər. Burada qeyd etmək lazımdır ki, while dövründə breakcontinue operatorlarının istifadəsi for dövründə olduğu kimidir. Lakin else operatorunun istifadəsi şərtli dövrdə bir qədər fərqlənir. Şərtli while dövründə else operatorundan sonra gələn ifadələr dövrün şərti ödənilmədiyi halda icra olunur. Bunu bir misal üzərində tətbiq edək.
Aşağıdakı proqram kvadratları 200-dən böyük olmayan natural ədədləri və onların kvadratlarını ekrana çıxarır. Ən sonda bu şərti pozan ilk ədəd və onun kvadratı da çapa verilir:

i = 1
while i ** 2 <= 200:
    print(i, i ** 2)
    i = i + 1 
else:
    print("Şərt buradan ödənmir:", i, i ** 2)

Gördüyünüz kimi, dövrün şərti ödənmədiyi halda else instruksiyasından sonra gələn ifadə icra olunur.
Sayğaclı dövrlərdə olduğu kimi, şərtli dövrlərdə də iç-içə dövrlərdən istifadə oluna bilər.
Sonda sayğaclı dövrlərlə bağlı daha bir məsələni nəzərinizə çatdırmaq istərdim. Şərtli while dövrünün ümumi yazılış qaydasından da gördüyünüz kimi, burada şərt dövrün başlanğıcında yoxlanılır. Digər proqramlaşdırma dillərində isə (məsələn : Pascal və C) iki fərqli şərtli dövr operatorlarından istifadə olunur: ön şərtlison şərtli. Bu ikisi arasındakı fərq ondan ibarətdir ki, ön şərtli dövr operatorunda şərt ödənilmədən dövr bir dəfə də olsa, icra olunmur. Amma son şərtli dövr operatorunda dövr bir dəfə icra olunur və sonda şərt yoxlanılır.
Python proqramlaşdırma dilində son şərtli dövr operatoru olmasa da, zərurət halında while instruksiyasından istifadə edərək son şərtli dövr alqoritmini emulyasiya etmək mümkündür. Bunu bir misal üzərində tətbiq edək.
Aşağıda kiçik bir oyun proqramının kodu verilmişdir. Oyunun qaydası çox sadədir. Əvvəlcə müəyyən bir aralıqda gizli bir ədəd təyin edilir və oyunçudan onu tapmaq tələb olunur. Oyunçu hər dəfə təxmin etdiyi ədədi klaviaturadan daxil edir. Bu zaman əgər oyunçunun ədədi gizli ədəddən kiçikdirsə “Yuxarı”, böyükdürsə “Aşağı” sözləri ekrana çıxır. Oyun istifadəçi gizli ədədi tapana qədər davam edir. Yekunda oyunçunu təbrik edir və gizli ədədi neçə cəhddə tapdığını ona bildiririk.

a = 45
print("1-100 arası gizli ədədi tapın") 
k = 0
while True:
    b = int(input()) 
    k = k + 1
    if b < a:
        print("Yuxarı") 
    elif b > a:
        print("Aşağı") 
    else:
        break
print("Təbriklər! Siz", k, "cəhddən tapdınız.")

Proqramdan da gördüyünüz kimi, şərtli dövrün əvvəlində verilən şərt ödənildiyinə görə (başqa cür ola da bilməz) dövrün gövdəsi icra olunur. Biz burada dövrün şərtini elə təyin etdik ki, o hər zaman ödəniləcək. Dolayısıyla dövrün şərti artıq formal xarakter daşıyır. Deməli, dövrün icrasını dayandırmaq üçün başqa bir tədbir görülməlidir. Bu isə break operatorunun istifadəsi ola bilər. Biz də oyunçunun daxil etdiyi ədəd gizli ədədin özü olacağı halda dövrün icrasını break operatoru vasitəsilə dayandırırıq.
Yuxarıdakı proqramı Python dilində olmayan son şərtli alqoritmi emulyasiya etmək məqsədilə bu cür yazdıq. Halbuki eyni proqram adi qaydada (ön şərtli) aşağıdakı kimi də yazıla bilərdi:

a = 45
print("1-100 arası gizli ədədi tapın") 
k = 0
m = True
while m:
    b = int(input()) 
    k = k + 1
    if b < a:
        print("Yuxarı") 
    elif b > a:
        print("Aşağı") 
    else:
        m = False
print("Təbriklər! Siz", k, "cəhddən tapdınız.")

Proqramın hər iki variantını skriptdə yazın və gizli ədədi təyin edərək dostunuzla oynayın.

Sayğaclı dövr

Python dilində for sayğaclı dövrünün ümumi yazılış qaydası aşağıdakı kimidir:

for parametr in ardıcıllıq: 
    dövrün gövdəsi

Burada parametr dövrün idarəetmə dəyişəni, ardıcıllıq sətir, siyahı, kortej və s. kimi tiplərdə olan qiymətlər çoxluğu, dövrün gövdəsi isə icrası təkrarlanan ifadələr qrupudur. Sayğaclı dövrdə parametr ardıcıllıqdakı bütün qiymətləri bir-bir alır və dövrün gövdəsi də onların sayı qədər icra olunur.
İndi isə konkret misallara keçək. Əvvəlcə verilmiş sözün hərflərini tək-tək ekranda çap edən proqram tərtib edək:

>>> for c in "Python": 
        print(c)

P
y
t
h
o
n 
>>>

Burada dövrün parametri olan c dəyişəni “Python” ardıcıllığının bütün qiymətlərini alır və dövrün gövdəsi olan print(c) funksiyası indiki halda 6 dəfə (ardıcıllığın elementlərinin sayı qədər) icra olunur.
Başqa bir misala keçək. Siyahıda verilmiş ədədlərin kvadratlarını hesablayan proqram tərtib edək:

>>> n = [11, 22, 33, 44, 55] 
>>> for i in n:
        m = i**2 
        print(m)

121
484
1089
1936
3025
>>>

Gördüyünüz kimi dövrün gövdəsi ifadələr qrupundan da ibarət ola bilər. Necə ki, biz burada dövrün gövdəsində iki ifadədən (m = i**2 print(m)) istifadə etdik.
Mövzunun əvvəlində qeyd etmişdik ki, sayğaclı dövrdə istifadə olunan ardıcıllıq həm də kortej tipində qiymətlər çoxluğu ola bilər. Gəlin bir misalda da bunu tətbiq edək. Kortejdə verilmiş həqiqi ədədlərin iki mislini hesablayan proqram tərtib edək:

>>> for i in (3.21, 4.63, 8.75): 
        print(i * 2)

6.42 
9.26 
17.5 
>>>

İndi isə birdən yüzədək [1…100] ədədlərin cəmini hesablayan proqram tərtib edək. Əlbəttə, burada n(n+1)/2 düsturunu tətbiq etməklə bu cəmi hesablaya bilərik. Lakin gəlin dövrlərdən istifadə edərək məsələnin həllinə çalışaq. Bu halda biz gərək 1-dən 100-dək ədədlər ardıcıllığından istifadə edək. Bu isə uzun yazılışına görə əlverişsizdir. Bəs nə etməli?

range()

Belə hallarda ədədi silsiləni generasiya edən range() funksiyası göydəndüşmə olur. Bu funksiyanın aşağıdakı yazılış variantları var:

range(n);0-dan n-ə qədər ədədlər verir
(n daxil deyil);
range(n, m)n-dən m-ə qədər ədədlər verir
(n daxil, m daxil deyil)
range(n, m, k)n-dən m-ə qədər k addımla ədədlər verir
(n daxil, m daxil deyil)

Biz də range() funksiyasından istifadə etməklə birdən yüzədək [1…100] ədədlərin cəmini hesablayan proqram tərtib edə bilərik:

>>> s = 0
>>> for i in range(1, 101):
        s = s + i

>>> print(s) 
5050
>>>

Proqramımıza aydınlıq gətirək. Əvvəlcə cəm üçün nəzərdə tutduğumuz s dəyişəninə başlanğıc qiymət kimi sıfırı (0) mənimsədirik. Bundan sonra sayğaclı dövr işə düşür. Dövrün parametri ardıcıllığa daxil olan 1-dən 100-dək qiymətləri tək-tək qəbul edir və onlar hər dəfə s dəyişəni ilə toplanır. Bu hesablama prosesi dövrün idarəetmə dəyişəni ardıcıllığın son qiymətini alıb, onu ümumi cəmin üzərinə gəldikdən sonra yekunlaşır. Lap axırda yekun nəticə ekrana çapa verilir.
Burada range() funksiyası ilə bağlı onu da qeyd etmək yerinə düşər ki, əgər for sayğaclı dövründə bu funksiyanın range(n, m) variantından istifadə olunursa, onda m parametri n-dən hər zaman böyük olmalıdır (m>n), əks halda, for dövrü bir dəfə də icra olunmayacaq.
İndi də 2-dən 10-dək cüt ədədləri ekrana çıxaran proqram tərtib edək:

>>> for i in range(2, 11, 2): 
        print(i)

2
4
6
8 
10 
>>>

Bəs 1-dən 10-dək tək ədədləri ekrana çıxarmaq istəsək, necə? Bu proqramı da siz tərtib edin.
Sonda bir məsələni də nəzərinizə çatdırmaq istərdim. Biz sayğaclı dövrdə azalan ardıcıllığı təşkil etmək istəyiriksə, o zaman range(n, m, -k) variantından (n>m şərtilə) istifadə etməliyik. Məsələn: deyək ki, 10-dan 1-dək ədədləri ekrana çapa vermək tələb olunur. Bu proqram aşağıdakı kimi olacaq:

>>> for i in range(10, 0, -1): 
        print(i)

10
9
8
7 
6
5
4
3
2
1 
>>>

Dövri alqoritmlərin təşkilində break, continue, else operatorlarından istifadə olunması bizə əlavə imkanlar verir. Bu operatorları misallar üzərində nəzərdən keçirək.

break

Bu operator çağırıldığı zaman dövrün icrası vaxtından əvvəl dayandırılır. Təcrübədə break operatorunu tətbiq etmək üçün bir misal həll edək.
Bildiyiniz kimi, bizim istifadə etdiyimiz hazırkı əlifba latın qrafikalıdır. ISO əsas latın əlifbasının yalnız bir hərfi (w) bizim əlifbada yoxdur. İndi elə bir proqram tərtib edək ki, verilmiş sözün bütün hərflərini bir-bir yoxlayaraq “yad” hərfin (w) olub-olmadığını müəyyənləşdirsin.
Sözdə ilk w hərfi tapılarsa, axtarış dayandırılsın və ekrana müvafiq məlumat çıxarılsın:

s = input("Sözü daxil edin: ") 
m = True
for c in s:
    if c == 'w':
    print("w hərfi əlifbamızda yoxdur.") 
    m = False
    break
if m:
    print("w hərfinə rast gəlinmədi.")

Nə baş verdi? Əvvəlcə biz istifadəçinin klaviaturadan daxil etdiyi sözü s dəyişənində yadda saxladıq. Sonra irəlidə bizə lazım olacaq m dəyişəninə başlanğıc qiymət kimi True mənimsətdik. Daha sonra dövr quruldu və dövrün parametri (c) ardıcıllığa daxil olan bütün qiymətləri (daxil edilən sözün bütün hərflərini) tək-tək qəbul etdi. Dövrün gövdəsində isə parametrin aldığı qiymətin w olub-olmadığını yoxladıq. Bu zaman şərt ödənilirsə, yəni verilmiş sözdə belə bir hərfə rast gəlinirsə, onda ekrana müvafiq məlumat çıxarılır və m dəyişəninə False qiyməti mənimsədilir. Ardınca isə break operatoru ilə dövrün bundan sonrakı icrası dayandırılır. Nəhayət, lap sonda m dəyişəninin qiymətini yoxlayırıq. Bu qiymət True olaraq qalıbsa, deməli, sözdə w hərfinə rast gəlinməyib. Elədirsə, ekrana bu haqda məlumat çıxarırıq. Proqramı skriptdə yazıb icra edin və müxtəlif sözlər daxil edərək nəticələri yoxlayın.

continue

Bu operator çağırıldıqda dövr gövdəsinin qalan ifadələrini adlayaraq dövrün növbəti addımını başladır. Operatorun işləmə prinsipini aşağıdakı misal üzərində nəzərdən keçirək.
Elə bir proqram tərtib edək ki, verilən cümlənin bütün simvollarını boşluqları nəzərə almadan ekrana çıxarsın:

s = input("Cümləni daxil edin: ") 
for c in s:
    if c == ' ': 
        continue
    print(c)

Bu proqramı yazıb icra edəndə görəcəksiniz ki, boşluqlara rast gəldikdə onlar ekrana çıxmır. Bunun səbəbi continue operatorudur, məhz ondan sonrakı ifadələr icra olunmadan dövr növbəti addımına keçir.

else

Dövr operatorları ilə bir yerdə istifadə olunan daha bir operator isə else instruksiyasıdır. Sayğaclı dövrdə else istifadə edildikdə dövr öz işini bitirdiyi zaman else operatorundan sonra gələn ifadələr icra olunur.
Aşağıdakı nümunəyə nəzər yetirək:

for i in range(1, 5):
    print(i, end = " ")
else:
    print("\nDövr bitdi.")

Bu proqramda dövr beş dəfə icra olunur, ekranda 1-dən 5-ə qədər ədədlər çap edilir. Dövr öz işini yekunlaşdırdıqdan sonra isə ekrana “Dövr bitdi” məlumatı çıxarılır.
Bir məsələni də xüsusi qeyd etmək lazımdır ki, əgər dövr daxilində break operatoru icra olunursa, o zaman else operatorundan sonra gələn ifadələr icra olunmayacaq. Başqa sözlə desək, else operatorundan sonra gələn ifadələr yalnız dövr öz işini normal yekunlaşdırdığı təqdirdə icra olunur. Bir misal üzərində bunu tətbiq edək.
Yuxarıda verilmiş sözdə w hərfinin olub-olmadığını müəyyən edən proqram yazmışdıq. Həmin proqramda məntiq tipində əlavə bir m dəyişəni də götürmüşdük. Bunu ona görə etmişdik ki, dövrün icrasının normal (qırılmadan) yekunlaşıb-yekunlaşmadığını m dəyişəninin qiymətinə əsasən yoxlaya bilək. Artıq else operatorundan istifadə etməklə bunu daha asan yolla aydınlaşdıra bilərik:

s = input("Sözü daxil edin: ") 
for c in s:
    if c == 'w':
        print("w hərfi əlifbamızda yoxdur.")
        break 
else:
    print("w hərfinə rast gəlinmədi.")

Burada diqqət edin ki, else operatoru if deyil, for instruksiyasına bağlıdır. Ona görə də, biz onu if deyil, for operatorunun cərgəsində yazdıq. Proqramı skriptdə yazıb icra edin və müxtəlif sözlər daxil edərək nəticələri yoxlayın.

Dövr Operatorları

Buraya qədər yazdığımız proqramlarda biz xəttibudaqlanma alqoritmlərindən istifadə etdik. Bundan başqa, proqramlaşdırmada dövri alqoritmlərdən də istifadə olunur. Əgər bir proqram daxilində müəyyən əməliyyatları ardıcıl şəkildə təkrarlamaq lazım gəlirsə, biz bu zaman dövr operatorlarına müraciət edirik. Dövr operatorları icrası təkrarlanan eyni proqram kodlarını dəfələrlə yazmaqdan bizi azad edir.

Python proqramlaşdırma dilində iki növ dövr operatoru nəzərdə tutulmuşdur. Əgər təkrarlanmaların sayı daha öncədən məlumdursa, sayğaclı dövr (for), məlum deyilsə, şərtli dövr (while) operatorundan istifadə olunur.