Cevaplara bakmadan önce görevi kendiniz çözmeyi deneyin. Aynı sonucu veren farklı çözümler de doğrudur.

1 Başlangıç

Bağlanma, çıkışları açıp kapatma ve bekleme.
01

Simülasyona bağlan

Simülasyona bağlanan, ekrana Hello room! yazan ve bağlantıyı kapatan bir program yazın.
Önce simülasyonu başlatın, sonra programı çalıştırın. Konsolda kütüphanenin [SIM] Connected ve [SIM] Disconnected. mesajlarını da görmelisiniz.
Sonra simülasyonu kapatıp programı yeniden çalıştırın: bağlantı kurulamadığı için program hata mesajıyla bitmelidir.

Her program aynı iskeletle başlar: kütüphaneyi ekle, sim_connect() ile bağlan, işini yap, sim_disconnect() ile ayrıl.
Simülasyon açık değilse sim_connect() 1 döndürür. Bu durumda devam etmenin anlamı yoktur; program 1 koduyla biter. Bu iskeleti sonraki tüm görevlerde kullanacaksınız.

sim_connect()sim_disconnect()printf / print
#include "room.h"

int main(void) {
    if (sim_connect() != 0) return 1;   // simulation not running

    printf("Hello room!\n");

    sim_disconnect();
    return 0;
}
from room import *

if sim_connect() != 0:
    exit(1)          # simulation not running

print("Hello room!")

sim_disconnect()
02

Lambayı yak

Odadaki lambayı yakan bir program yazın. Program lambayı yaktıktan sonra bitsin.
Program bittiğinde lamba yanmaya devam ediyor mu? Gözlemleyin. Sonra lambayı elle kontrol panelindeki Lamba Kapat düğmesiyle söndürün.

lamp(LAMP_ON) paylaşılan belleğe 1 yazar; simülasyon bu değeri sürekli okur ve ışığı çizer. Program bitince bellekteki değer silinmez, bu yüzden lamba yanık kalır. Elle kontrol panelindeki düğmeler de aynı belleğe yazar.

lamp()LAMP_ON
#include "room.h"

int main(void) {
    if (sim_connect() != 0) return 1;

    lamp(LAMP_ON);      // the light appears in the room

    sim_disconnect();
    return 0;
}
from room import *

if sim_connect() != 0:
    exit(1)

lamp(LAMP_ON)       # the light appears in the room

sim_disconnect()
03

Yak, bekle, söndür

Lambayı yakın, 2 saniye bekleyin ve söndürün. Lamba simülasyonda 2 saniye yanık görünmeli, program bittiğinde sönük kalmalı.

Bilgisayar komutları çok hızlı çalıştırır. Bekleme olmadan lamba mikrosaniyeler içinde yanıp söner ve hiçbir şey göremezsiniz. Sleep(2000) / time.sleep(2) programı 2 saniye durdurur; bu sırada lamba yanık kalır.

Sleep / time.sleepLAMP_OFF
#include "room.h"

int main(void) {
    if (sim_connect() != 0) return 1;

    lamp(LAMP_ON);
    Sleep(2000);        // 2000 ms = 2 s
    lamp(LAMP_OFF);

    sim_disconnect();
    return 0;
}
from room import *
import time

if sim_connect() != 0:
    exit(1)

lamp(LAMP_ON)
time.sleep(2)       # 2 seconds
lamp(LAMP_OFF)

sim_disconnect()
04

Önce lamba, sonra klima

Şu sırayı uygulayan bir program yazın:
1. Lambayı yakın.
2. 3 saniye sonra klimayı açın (odada klimanın rüzgârı görünür).
3. 5 saniye sonra lambayı ve klimayı kapatın.
Klima açıkken sıcaklık göstergesini izleyin: yaklaşık 1 saniye sonra düşmeye başlar.

Program yukarıdan aşağıya satır satır çalışır; buna sıralı akış denir. ac(AC_ON) lambadan 3 saniye sonra çalışır çünkü önündeki Sleep(3000) bitmeden sıra ona gelmez.

ac()AC_ONsequence
#include "room.h"

int main(void) {
    if (sim_connect() != 0) return 1;

    lamp(LAMP_ON);
    Sleep(3000);
    ac(AC_ON);          // wind appears, room starts cooling
    Sleep(5000);
    lamp(LAMP_OFF);
    ac(AC_OFF);

    sim_disconnect();
    return 0;
}
from room import *
import time

if sim_connect() != 0:
    exit(1)

lamp(LAMP_ON)
time.sleep(3)
ac(AC_ON)           # wind appears, room starts cooling
time.sleep(5)
lamp(LAMP_OFF)
ac(AC_OFF)

sim_disconnect()
05

Perdeyi aç ve kapat

Perde kapalıyken (en aşağıda) başlayın. Perdeyi yukarı çalıştırın, 6 saniye bekleyin, sonra aşağı çalıştırın ve programı bitirin.
Perde en üste gelince kendiliğinden durmalı; program bittikten sonra da aşağı inmeye devam edip en altta durmalı.

curtain() perdeyi bir anda taşımaz, motoru bir yönde çalıştırır. Motor, perde uca gelene kadar döner ve uçta kendiliğinden durur. Komut bellekte kaldığı için program bittikten sonra da perde inmeye devam eder. 6 saniyelik bekleme, 4,5 saniyelik tam açılmaya yetecek kadar uzundur.

curtain()CURTAIN_UPCURTAIN_DOWN
#include "room.h"

int main(void) {
    if (sim_connect() != 0) return 1;

    curtain(CURTAIN_UP);    // motor stops by itself at the top
    Sleep(6000);
    curtain(CURTAIN_DOWN);  // keeps moving after the program ends

    sim_disconnect();
    return 0;
}
from room import *
import time

if sim_connect() != 0:
    exit(1)

curtain(CURTAIN_UP)     # motor stops by itself at the top
time.sleep(6)
curtain(CURTAIN_DOWN)   # keeps moving after the program ends

sim_disconnect()
06

Perdeyi yarıya kadar aç

Perde kapalıyken başlayın. Perdeyi 2 saniye boyunca yukarı çalıştırıp durdurun. Perde pencerenin yaklaşık yarısında kalmalı.
Sonra süreyi 1 saniye ve 3 saniye yapıp farkı gözlemleyin (her denemeden önce perdeyi Perde Aşağı düğmesiyle kapatın).

Perdenin konumunu okuyamayız ama motorun ne kadar süre çalıştığını biz belirleriz. Tam açılma yaklaşık 4,5 saniye olduğu için 2 saniye yaklaşık yarıya denk gelir. Süreyle konum ayarlamak basit ama tam hassas değildir.

CURTAIN_STOPtiming
#include "room.h"

int main(void) {
    if (sim_connect() != 0) return 1;

    curtain(CURTAIN_UP);
    Sleep(2000);            // about half of the 4.5 s full travel
    curtain(CURTAIN_STOP);

    sim_disconnect();
    return 0;
}
from room import *
import time

if sim_connect() != 0:
    exit(1)

curtain(CURTAIN_UP)
time.sleep(2)           # about half of the 4.5 s full travel
curtain(CURTAIN_STOP)

sim_disconnect()
07

Günaydın senaryosu

Perde kapalıyken başlayın. Her adımdan önce ekrana ne yapıldığını yazan bir sabah senaryosu hazırlayın:
1. Good morning! yazın, lambayı yakın, 2 saniye bekleyin.
2. Opening the curtain yazın, perdeyi yukarı çalıştırın, 5 saniye bekleyin.
3. Fresh air yazın, lambayı söndürün, klimayı açın, 3 saniye bekleyin.
4. Klimayı kapatın ve Ready for the day. yazın.

Cevap sende

Bu görevin cevabı verilmiyor. Önceki görevlerin cevaplarındaki fikirleri birleştirerek kendiniz çözün; çalışan programınız sizin cevabınızdır.

2 Temel

Sensör okuma, ekrana yazdırma ve if/else ile karar verme.
08

Sıcaklığı oku

Oda sıcaklığını bir değişkene okuyun ve ekrana Temperature: 24 C biçiminde yazın.
Programı birkaç kez çalıştırın ve yazılan değeri simülasyondaki sıcaklık göstergesiyle karşılaştırın. Sonra Klima Aç düğmesine basıp tekrar çalıştırın.

Değişken, bir değeri saklayan isimli bir kutudur. read_temp() o anki sıcaklığı döndürür, biz de onu t değişkenine koyarız. C'de %d tam sayıyı metnin içine yerleştirir; Python'da {t} aynı işi yapar. Sıcaklık sürekli değiştiği için her çalıştırmada farklı bir değer görebilirsiniz.

read_temp()variable%d / f-string
#include "room.h"

int main(void) {
    if (sim_connect() != 0) return 1;

    int t = read_temp();
    printf("Temperature: %d C\n", t);

    sim_disconnect();
    return 0;
}
from room import *

if sim_connect() != 0:
    exit(1)

t = read_temp()
print(f"Temperature: {t} C")

sim_disconnect()
09

Oda raporu

Odanın bütün değerlerini okuyup alt alta yazan bir rapor programı yazın:
Temperature: .., Lux: .., AC: .., Lamp: .., Curtain motor: ..
Elle kontrol panelinden lambayı yakın, Gün Işığını Değiştir sürgüsünü 500'e getirin, perdeyi yukarı çalıştırın ve perde hareket ederken programı çalıştırın. Rapordaki sayılar yaptığınız değişiklikleri göstermeli.

Sıcaklık ve lüks simülasyonun ölçtüğü sensör değerleridir. read_ac(), read_lamp() ve read_curtain() ise çıkışlara en son ne yazıldığını gösterir (sizin programınız veya paneldeki düğmeler). Lamba yanıyorsa 1, perde yukarı gidiyorsa 1, duruyorsa 0 görürsünüz.

read_lux()read_ac()read_lamp()read_curtain()
#include "room.h"

int main(void) {
    if (sim_connect() != 0) return 1;

    printf("Temperature:   %d C\n", read_temp());
    printf("Lux:           %d\n", read_lux());
    printf("AC:            %d\n", read_ac());
    printf("Lamp:          %d\n", read_lamp());
    printf("Curtain motor: %d\n", read_curtain());

    sim_disconnect();
    return 0;
}
from room import *

if sim_connect() != 0:
    exit(1)

print(f"Temperature:   {read_temp()} C")
print(f"Lux:           {read_lux()}")
print(f"AC:            {read_ac()}")
print(f"Lamp:          {read_lamp()}")
print(f"Curtain motor: {read_curtain()}")

sim_disconnect()
10

Karanlıksa lambayı yak

Dış ışığı okuyun. Değer 100 lüksten azsa lambayı yakıp Dark (.. lux): lamp on yazın; değilse lambayı söndürüp Bright (.. lux): lamp off yazın.
Deneme: Gün Işığını Değiştir sürgüsünü 50'ye getirip programı çalıştırın, sonra 800'e getirip tekrar çalıştırın.

if programın karar vermesini sağlar: koşul doğruysa ilk blok, yanlışsa else bloğu çalışır; ikisi birden asla çalışmaz. 100 lüks bir eşik değeridir; siz değiştirerek lambanın ne zaman yanacağını belirleyebilirsiniz.

if / else<
#include "room.h"

int main(void) {
    if (sim_connect() != 0) return 1;

    int lux = read_lux();
    if (lux < 100) {
        lamp(LAMP_ON);
        printf("Dark (%d lux): lamp on\n", lux);
    } else {
        lamp(LAMP_OFF);
        printf("Bright (%d lux): lamp off\n", lux);
    }

    sim_disconnect();
    return 0;
}
from room import *

if sim_connect() != 0:
    exit(1)

lux = read_lux()
if lux < 100:
    lamp(LAMP_ON)
    print(f"Dark ({lux} lux): lamp on")
else:
    lamp(LAMP_OFF)
    print(f"Bright ({lux} lux): lamp off")

sim_disconnect()
11

Sıcaksa klimayı aç

Sıcaklığı okuyun. 26 °C'den yüksekse klimayı açıp Hot (.. C): AC on yazın; değilse klimayı kapatıp Not hot (.. C): AC off yazın.
Deneme: klima kapalıyken oda birkaç saniyede ısınır; programı çalıştırın, klima açılmalı. Sonra 5 saniye bekleyin (oda soğur) ve programı tekrar çalıştırın: klima kapanmalı.

Cevap sende

Bu görevin cevabı verilmiyor. Önceki görevlerin cevaplarındaki fikirleri birleştirerek kendiniz çözün; çalışan programınız sizin cevabınızdır.
12

Perde ne yapıyor?

Perde motorunun durumunu okuyup sayı yerine yazıyla gösterin: 0 ise Curtain stopped, 1 ise Curtain moving up, 2 ise Curtain moving down, başka bir değerse Unknown value.
Deneme: perde dururken çalıştırın; sonra Perde Yukarı (veya Perde Aşağı) düğmesine basıp perde hareket ederken hemen çalıştırın.

else if zinciri koşulları yukarıdan aşağıya dener ve ilk doğru olanı çalıştırır; hiçbiri doğru değilse en sondaki else çalışır. CURTAIN_UP gibi sabitler kodu okunur yapar: c == 1 yerine c == CURTAIN_UP ne demek istediğinizi açıkça söyler. = atama, == karşılaştırmadır.

else if / elif==constants
#include "room.h"

int main(void) {
    if (sim_connect() != 0) return 1;

    int c = read_curtain();
    if (c == CURTAIN_STOP) {
        printf("Curtain stopped\n");
    } else if (c == CURTAIN_UP) {
        printf("Curtain moving up\n");
    } else if (c == CURTAIN_DOWN) {
        printf("Curtain moving down\n");
    } else {
        printf("Unknown value: %d\n", c);
    }

    sim_disconnect();
    return 0;
}
from room import *

if sim_connect() != 0:
    exit(1)

c = read_curtain()
if c == CURTAIN_STOP:
    print("Curtain stopped")
elif c == CURTAIN_UP:
    print("Curtain moving up")
elif c == CURTAIN_DOWN:
    print("Curtain moving down")
else:
    print(f"Unknown value: {c}")

sim_disconnect()
13

Boşuna yanan lamba

Lamba yanıyorsa VE dışarısı 600 lüksten aydınlıksa lambayı söndürüp Lamp was on in daylight: turned off yazın. Aksi halde hiçbir komut göndermeden Nothing to do yazın.
Deneme: Lamba Aç düğmesine basın, ışık sürgüsünü 800'e getirip programı çalıştırın (lamba sönmeli). Sonra sürgüyü 300'e getirip lambayı yakın ve tekrar çalıştırın (lamba yanık kalmalı).

Cevap sende

Bu görevin cevabı verilmiyor. Önceki görevlerin cevaplarındaki fikirleri birleştirerek kendiniz çözün; çalışan programınız sizin cevabınızdır.
14

Aynı komutu iki kez verme

Görev 11'i geliştirin: komut göndermeden önce read_ac() ile klimanın durumuna bakın.
• Sıcaklık 26 °C'den yüksekse: klima zaten açıksa AC already on, kapalıysa klimayı açıp AC turned on yazın.
• Değilse: klima zaten kapalıysa AC already off, açıksa klimayı kapatıp AC turned off yazın.
Deneme: menüden Animasyon Hızını en düşüğe alın. Oda sıcakken programı arka arkaya iki kez çalıştırın: önce AC turned on, sonra AC already on görmelisiniz.

Cevap sende

Bu görevin cevabı verilmiyor. Önceki görevlerin cevaplarındaki fikirleri birleştirerek kendiniz çözün; çalışan programınız sizin cevabınızdır.

3 Orta

Döngüler, sürekli kontrol ve durum takibi.
15

Lambayı 5 kez yakıp söndür

Lambayı 5 kez yakıp söndürün: her seferinde 1 saniye yanık, 1 saniye sönük. Her yanışta ekrana Blink 1, Blink 2 ... Blink 5 yazın.
Kodu 5 kez kopyalamak yerine döngü kullanın.

for döngüsü içindeki blok, sayaç i 1'den 5'e kadar her değer için bir kez çalışır. Yanıp sönme sayısını değiştirmek için tek bir sayıyı değiştirmeniz yeter. Python'da range(1, 6) 1, 2, 3, 4, 5 üretir (6 dahil değildir).

for loopcounter
#include "room.h"

int main(void) {
    if (sim_connect() != 0) return 1;

    for (int i = 1; i <= 5; i++) {
        printf("Blink %d\n", i);
        lamp(LAMP_ON);
        Sleep(1000);
        lamp(LAMP_OFF);
        Sleep(1000);
    }

    sim_disconnect();
    return 0;
}
from room import *
import time

if sim_connect() != 0:
    exit(1)

for i in range(1, 6):
    print(f"Blink {i}")
    lamp(LAMP_ON)
    time.sleep(1)
    lamp(LAMP_OFF)
    time.sleep(1)

sim_disconnect()
16

Geri sayım

Perde kapalıyken başlayın. Ekrana her saniye bir sayı yazarak 10'dan 1'e geri sayın. Sayım bitince Go! yazın, lambayı yakın ve perdeyi yukarı çalıştırın.

Cevap sende

Bu görevin cevabı verilmiyor. Önceki görevlerin cevaplarındaki fikirleri birleştirerek kendiniz çözün; çalışan programınız sizin cevabınızdır.
17

En düşük ve en yüksek sıcaklık

Klima kapalıyken oda ısınsın, sonra programı çalıştırın. Program klimayı açsın, her 200 ms'de bir toplam 20 ölçüm alıp her birini 1: 44 C biçiminde yazsın. Sonunda klimayı kapatsın ve ölçümlerin en düşüğünü ve en yükseğini yazsın: Lowest: .. C, highest: .. C.

Cevap sende

Bu görevin cevabı verilmiyor. Önceki görevlerin cevaplarındaki fikirleri birleştirerek kendiniz çözün; çalışan programınız sizin cevabınızdır.
18

Perde kaç saniyede açılıyor?

Önce perdeyi aşağı çalıştırın ve motor durana kadar bekleyin (perde tamamen kapanır). Sonra perdeyi yukarı çalıştırın ve motor kendiliğinden durana kadar her 100 ms'de bir sayaç artırın. Sonunda Opened in about .. ms yazın (yaklaşık 4500 ms görmelisiniz).
Sabit bir süre beklemeyin; motorun durduğunu read_curtain() ile anlayın.

Cevap sende

Bu görevin cevabı verilmiyor. Önceki görevlerin cevaplarındaki fikirleri birleştirerek kendiniz çözün; çalışan programınız sizin cevabınızdır.
19

Otomatik gece lambası

Görev 10'u hiç bitmeyen bir döngüye koyun: her 100 ms'de dış ışığı okuyun; 100 lüksten azsa lambayı yakın, değilse söndürün.
Programı çalıştırıp ışık sürgüsünü 50 ile 500 arasında oynatın; lamba kendiliğinden yanıp sönmeli. Konsolu da izleyin: ne görüyorsunuz? Programı Ctrl+C ile durdurun.

Kontrol programları genellikle sonsuz döngüdür: oku → karar ver → uygula → biraz bekle → tekrar. 100 ms'lik bekleme işlemciyi boşuna yormaz ama değişikliklere hızlı tepki verir.
Konsolda her 100 ms'de bir [SIM] Lamp -> ... satırı akar: program lamba zaten doğru durumdayken bile komutu tekrar tekrar gönderiyor. Bunu Görev 20'de düzelteceğiz.

while (1) / while Truecontinuous controlCtrl+C
#include "room.h"

int main(void) {
    if (sim_connect() != 0) return 1;

    while (1) {                     // stop with Ctrl+C
        if (read_lux() < 100) {
            lamp(LAMP_ON);
        } else {
            lamp(LAMP_OFF);
        }
        Sleep(100);
    }

    sim_disconnect();               // not reached, see Task 29
    return 0;
}
from room import *
import time

if sim_connect() != 0:
    exit(1)

while True:                         # stop with Ctrl+C
    if read_lux() < 100:
        lamp(LAMP_ON)
    else:
        lamp(LAMP_OFF)
    time.sleep(0.1)

sim_disconnect()                    # not reached, see Task 29
20

Sadece gerektiğinde komut gönder

Görev 19'u düzeltin: lambaya sadece durumunun değişmesi gerektiğinde komut gönderin. Lamba her değiştiğinde ekrana bir kez Lux 85: lamp on veya Lux 120: lamp off yazın.
Sürgüyü oynatın: konsolda artık sadece değişiklik anlarında satır görünmeli.

want lambanın olması gereken durumudur. Sadece want şimdiki durumdan farklıysa komut gönderilir. Böylece saniyede 10 komut yerine yalnızca gerçek değişikliklerde birer komut gider. Bu "değişince gönder" kalıbını bundan sonraki bütün kontrol görevlerinde kullanacağız.

state changeread_lamp()!=
#include "room.h"

int main(void) {
    if (sim_connect() != 0) return 1;

    while (1) {                     // stop with Ctrl+C
        int lux = read_lux();
        int want = LAMP_OFF;
        if (lux < 100) want = LAMP_ON;

        if (want != read_lamp()) {  // only on change
            lamp(want);
            if (want == LAMP_ON) printf("Lux %d: lamp on\n", lux);
            else                 printf("Lux %d: lamp off\n", lux);
        }
        Sleep(100);
    }

    sim_disconnect();               // not reached, see Task 29
    return 0;
}
from room import *
import time

if sim_connect() != 0:
    exit(1)

while True:                         # stop with Ctrl+C
    lux = read_lux()
    want = LAMP_OFF
    if lux < 100:
        want = LAMP_ON

    if want != read_lamp():         # only on change
        lamp(want)
        if want == LAMP_ON:
            print(f"Lux {lux}: lamp on")
        else:
            print(f"Lux {lux}: lamp off")
    time.sleep(0.1)

sim_disconnect()                    # not reached, see Task 29
21

Basit termostat

Sürekli çalışan bir termostat yazın: her 100 ms'de sıcaklığı okuyun; 26 °C'den yüksekse klima açık, değilse kapalı olsun. Görev 20'deki gibi sadece değişiklikte komut gönderin ve 27 C: AC on / 26 C: AC off biçiminde yazın.
Çalışırken klimanın ne sıklıkla açılıp kapandığını izleyin (rahat izlemek için Animasyon Hızını düşürebilirsiniz).

Cevap sende

Bu görevin cevabı verilmiyor. Önceki görevlerin cevaplarındaki fikirleri birleştirerek kendiniz çözün; çalışan programınız sizin cevabınızdır.
22

Düğmeye basma sayacı

Elle kontrol panelindeki lamba düğmelerini bir giriş gibi kullanın. Program lambanın kaç kez yakıldığını saysın: lamba her sönükten yanığa geçtiğinde Press 1, Press 2 ... yazsın. 5. yakıştan sonra klimayı açsın, 5 presses: AC on yazsın ve bitsin.
Deneme: lamba sönükken programı başlatın, sonra Lamba Aç ve Lamba Kapat düğmelerine sırayla basın.

Sadece "lamba yanık mı?" diye bakarsak, lamba yanık kaldığı sürece her döngüde sayarız. Önceki ve şimdiki değeri karşılaştırarak yalnızca değişim anını (0'dan 1'e geçişi, "yükselen kenar") yakalarız. Döngü koşulu sayaca bağlı olduğu için 5. yakışta döngü kendiliğinden biter.

edge detectioncounterwhile
#include "room.h"

int main(void) {
    if (sim_connect() != 0) return 1;

    int presses = 0;
    int prev = read_lamp();
    printf("Press Light On / Light Off in the panel\n");

    while (presses < 5) {
        int now = read_lamp();
        if (prev == LAMP_OFF && now == LAMP_ON) {   // rising edge
            presses++;
            printf("Press %d\n", presses);
        }
        prev = now;
        Sleep(50);
    }

    ac(AC_ON);
    printf("5 presses: AC on\n");

    sim_disconnect();
    return 0;
}
from room import *
import time

if sim_connect() != 0:
    exit(1)

presses = 0
prev = read_lamp()
print("Press Light On / Light Off in the panel")

while presses < 5:
    now = read_lamp()
    if prev == LAMP_OFF and now == LAMP_ON:     # rising edge
        presses += 1
        print(f"Press {presses}")
    prev = now
    time.sleep(0.05)

ac(AC_ON)
print("5 presses: AC on")

sim_disconnect()

4 İleri

Fonksiyonlar, zamanlama, durum makineleri ve hataya dayanıklılık.
23

Kendi fonksiyonun: blink

Lambayı times kez, her seferinde ms milisaniye yanık ve ms milisaniye sönük olacak şekilde yakıp söndüren bir blink(times, ms) fonksiyonu yazın.
Ana programda önce blink(3, 200) (hızlı), 1 saniye ara, sonra blink(3, 1000) (yavaş) çağırın.

Fonksiyon, bir işe isim verip onu farklı değerlerle tekrar tekrar kullanmamızı sağlar. Parametreler (times, ms) her çağrıda farklı olabilir. Ana program artık kısa ve okunur: ne yapıldığını söylüyor, nasıl yapıldığı fonksiyonun içinde.

functionparameter
#include "room.h"

void blink(int times, int ms) {
    for (int i = 0; i < times; i++) {
        lamp(LAMP_ON);
        Sleep(ms);
        lamp(LAMP_OFF);
        Sleep(ms);
    }
}

int main(void) {
    if (sim_connect() != 0) return 1;

    blink(3, 200);      // fast
    Sleep(1000);
    blink(3, 1000);     // slow

    sim_disconnect();
    return 0;
}
from room import *
import time

def blink(times, ms):
    for i in range(times):
        lamp(LAMP_ON)
        time.sleep(ms / 1000)
        lamp(LAMP_OFF)
        time.sleep(ms / 1000)

if sim_connect() != 0:
    exit(1)

blink(3, 200)       # fast
time.sleep(1)
blink(3, 1000)      # slow

sim_disconnect()
24

Değer döndüren fonksiyon: perdeyi sona kadar götür

move_curtain(dir) fonksiyonu yazın: perdeyi verilen yönde çalıştırsın ve motor durana kadar beklesin. Motor 8 saniye içinde durursa 1 döndürsün. Durmazsa motoru durdurup 0 döndürsün (zaman aşımı).
Ana program: perdeyi kapatın ve Closed yazın, 2 saniye bekleyin, perdeyi açın; sonuç 1 ise Opened, 0 ise Timeout! yazın.
Zaman aşımını denemek için perde açılırken menüden Sim Durdur'a basın: 8 saniye sonra Timeout! görmelisiniz.

Cevap sende

Bu görevin cevabı verilmiyor. Önceki görevlerin cevaplarındaki fikirleri birleştirerek kendiniz çözün; çalışan programınız sizin cevabınızdır.
25

Histerezisli termostat

Görev 21'deki termostatı iki eşikle yazın: sıcaklık 28 °C'nin üstüne çıkınca klimayı açın, 20 °C'nin altına inince kapatın; arada hiçbir şey yapmayın. Klimanın kaç kez açıldığını sayın ve her değişiklikte 29 C: AC on (switch 3) gibi yazın.
Görev 21 ile karşılaştırın: klima ne kadar sık açılıp kapanıyor?

Cevap sende

Bu görevin cevabı verilmiyor. Önceki görevlerin cevaplarındaki fikirleri birleştirerek kendiniz çözün; çalışan programınız sizin cevabınızdır.
26

Beklemeden zamanlama

Görev 25'teki termostat her 100 ms'de çalışmaya devam etsin. Aynı döngüye bir uyarı ışığı ekleyin: perde hareket ederken lamba yarım saniyede bir durum değiştirsin (0,5 s yanık, 0,5 s sönük); perde durunca lamba sönsün.
Deneme: Perde Yukarı veya Perde Aşağı düğmesine basın. Lamba yanıp sönerken termostat da klimayı kontrol etmeye devam etmeli.
Sleep(500) kullanmayın; o zaman termostat da yarım saniye bekler.

Sleep beklerken program başka hiçbir şey yapamaz ("bloklayan" bekleme). Bunun yerine döngü hep 100 ms'de bir döner ve her iş kendi zamanının gelip gelmediğine sayaçla bakar. Böylece termostat ve uyarı ışığı aynı anda, birbirini bekletmeden çalışır. % bölümden kalanı verir: ticks % 5 0, 1, 2, 3, 4, 0, ... diye döner.

non-blocking timingtick counter% (modulo)
#include "room.h"

int main(void) {
    if (sim_connect() != 0) return 1;

    int ticks = 0;
    while (1) {                     // stop with Ctrl+C
        // job 1: thermostat (every tick)
        int t = read_temp();
        if (t > 28 && read_ac() == AC_OFF) ac(AC_ON);
        else if (t < 20 && read_ac() == AC_ON) ac(AC_OFF);

        // job 2: warning light (every 5 ticks = 0.5 s)
        if (read_curtain() != CURTAIN_STOP) {
            if (ticks % 5 == 0) {
                if (read_lamp() == LAMP_ON) lamp(LAMP_OFF);
                else                        lamp(LAMP_ON);
            }
        } else if (read_lamp() == LAMP_ON) {
            lamp(LAMP_OFF);         // curtain stopped
        }

        ticks++;
        Sleep(100);                 // one tick = 100 ms
    }

    sim_disconnect();               // not reached, see Task 29
    return 0;
}
from room import *
import time

if sim_connect() != 0:
    exit(1)

ticks = 0
while True:                         # stop with Ctrl+C
    # job 1: thermostat (every tick)
    t = read_temp()
    if t > 28 and read_ac() == AC_OFF:
        ac(AC_ON)
    elif t < 20 and read_ac() == AC_ON:
        ac(AC_OFF)

    # job 2: warning light (every 5 ticks = 0.5 s)
    if read_curtain() != CURTAIN_STOP:
        if ticks % 5 == 0:
            if read_lamp() == LAMP_ON:
                lamp(LAMP_OFF)
            else:
                lamp(LAMP_ON)
    elif read_lamp() == LAMP_ON:
        lamp(LAMP_OFF)              # curtain stopped

    ticks += 1
    time.sleep(0.1)                 # one tick = 100 ms

sim_disconnect()                    # not reached, see Task 29
27

Durum makinesiyle perde

Perdeyi gün ışığına göre otomatik kontrol edin. Perdenin dört durumu olsun: CLOSED, OPENING, OPEN, CLOSING.
• Başlangıçta perdeyi tamamen kapatın (Görev 24'teki fonksiyon) ve CLOSED durumundan başlayın.
• CLOSED iken lüks 600'ün üstüne çıkarsa perdeyi yukarı çalıştırın → OPENING.
• OPENING iken motor durursa → OPEN.
• OPEN iken lüks 300'ün altına inerse perdeyi aşağı çalıştırın → CLOSING.
• CLOSING iken motor durursa → CLOSED.
Her durum değişikliğinde yeni durumun adını yazın. Deneme: ışık sürgüsünü 800 ile 100 arasında oynatın.

Cevap sende

Bu görevin cevabı verilmiyor. Önceki görevlerin cevaplarındaki fikirleri birleştirerek kendiniz çözün; çalışan programınız sizin cevabınızdır.
28

Sağlam bağlantı ve kendi kendini test

Simülasyon henüz açık değilse programın hemen pes etmesi yerine bağlanmayı 10 kez, 1 saniye arayla denemesini sağlayın (Attempt 1/10 failed...). 10 denemede de bağlanamazsa Could not connect, giving up. yazıp 1 koduyla bitsin.
Bağlandıktan sonra kısa bir kendi kendini test yapsın: lambayı ve klimayı açsın, 200 ms beklesin, read_lamp() ve read_ac() ile komutların gerçekten yazıldığını kontrol edip Lamp OK / Lamp FAILED ve AC OK / AC FAILED yazsın. Sonra ikisini de kapatıp bağlantıyı kapatsın.
Deneme: önce programı çalıştırın, birkaç saniye sonra simülasyonu başlatın.

Sağlam bir program hataları öngörür: simülasyon geç açılabilir, bir komut yerine ulaşmayabilir. Yeniden deneme geçici sorunları tolere eder, sınırlı deneme sayısı ise sonsuza kadar beklemeyi önler. Çıkış kodu (0 başarı, 1 hata) programı başka programların veya betiklerin de anlayabileceği şekilde bitirir. Komut sonrası durumu geri okumak, komutun gerçekten uygulandığını doğrular.

robustnessretryreturn codeself test
#include "room.h"

int connect_retry(int tries) {
    for (int i = 1; i <= tries; i++) {
        if (sim_connect() == 0) return 0;
        printf("Attempt %d/%d failed, retrying in 1 s\n", i, tries);
        Sleep(1000);
    }
    return 1;
}

int main(void) {
    if (connect_retry(10) != 0) {
        printf("Could not connect, giving up.\n");
        return 1;
    }

    lamp(LAMP_ON);
    ac(AC_ON);
    Sleep(200);
    if (read_lamp() == LAMP_ON) printf("Lamp OK\n");
    else                        printf("Lamp FAILED\n");
    if (read_ac() == AC_ON)     printf("AC OK\n");
    else                        printf("AC FAILED\n");

    lamp(LAMP_OFF);
    ac(AC_OFF);
    sim_disconnect();
    return 0;
}
from room import *
import time

def connect_retry(tries):
    for i in range(1, tries + 1):
        if sim_connect() == 0:
            return 0
        print(f"Attempt {i}/{tries} failed, retrying in 1 s")
        time.sleep(1)
    return 1

if connect_retry(10) != 0:
    print("Could not connect, giving up.")
    exit(1)

lamp(LAMP_ON)
ac(AC_ON)
time.sleep(0.2)
print("Lamp OK" if read_lamp() == LAMP_ON else "Lamp FAILED")
print("AC OK" if read_ac() == AC_ON else "AC FAILED")

lamp(LAMP_OFF)
ac(AC_OFF)
sim_disconnect()
29

Ctrl+C ile temiz kapanış

Şimdiye kadar sonsuz döngülü programları Ctrl+C ile kestik; lamba, klima ve perde o anki durumda kaldı ve sim_disconnect() hiç çalışmadı. Görev 20'deki gece lambasını öyle değiştirin ki Ctrl+C'ye basıldığında döngüden düzgünce çıksın, lambayı ve klimayı kapatsın, perdeyi durdursun, sim_disconnect() çağırsın ve Bye! yazsın.

Ctrl+C programa bir kesme sinyali gönderir. Python bunu KeyboardInterrupt hatası olarak fırlatır; biz yakalayıp temizlik koduna geçeriz. C'de sinyal fonksiyonu sadece bir bayrağı değiştirir, döngü bir sonraki turda bayrağı görüp kendiliğinden biter. Böylece program her durumda odayı güvenli bir durumda bırakır. Bundan sonraki projelerde bu kalıbı kullanacağız.

Ctrl+Csignal / KeyboardInterruptcleanup
#include "room.h"
#include <signal.h>

static volatile sig_atomic_t running = 1;

static void on_ctrl_c(int sig) {
    (void)sig;
    running = 0;                    // only set a flag here
}

int main(void) {
    if (sim_connect() != 0) return 1;
    signal(SIGINT, on_ctrl_c);

    while (running) {
        int want = LAMP_OFF;
        if (read_lux() < 100) want = LAMP_ON;
        if (want != read_lamp()) lamp(want);
        Sleep(100);
    }

    // cleanup: leave the room in a safe state
    lamp(LAMP_OFF);
    ac(AC_OFF);
    curtain(CURTAIN_STOP);
    sim_disconnect();
    printf("Bye!\n");
    return 0;
}
from room import *
import time

if sim_connect() != 0:
    exit(1)

try:
    while True:
        want = LAMP_OFF
        if read_lux() < 100:
            want = LAMP_ON
        if want != read_lamp():
            lamp(want)
        time.sleep(0.1)
except KeyboardInterrupt:           # Ctrl+C
    pass

# cleanup: leave the room in a safe state
lamp(LAMP_OFF)
ac(AC_OFF)
curtain(CURTAIN_STOP)
sim_disconnect()
print("Bye!")

5 Proje

Her şeyi birleştiren tam sistemler.
30

Akıllı oda

Odayı tamamen otomatik yöneten bir program yazın. Her alt sistem kendi fonksiyonunda olsun ve hepsi aynı 100 ms'lik döngüde çalışsın:
• Lamba: dış ışık 100 lüksten azsa yanık, değilse sönük.
• Klima: 28 °C üstünde aç, 20 °C altında kapat (Görev 25).
• Perde: Görev 27'deki durum makinesi (600 lüks üstünde aç, 300 lüks altında kapat).
• Komutlar sadece değişiklikte gönderilsin ve her değişiklik ekrana yazılsın.
• Ctrl+C ile temiz kapanış (Görev 29).
Deneme: ışık sürgüsünü 50, 400, 800 ve tekrar 50 yapın; her adımda lambanın ve perdenin ne yaptığını izleyin. Ya da bekleyin: dış ışık zaten kendiliğinden değişir.

Cevap sende

Bu görevin cevabı verilmiyor. Önceki görevlerin cevaplarındaki fikirleri birleştirerek kendiniz çözün; çalışan programınız sizin cevabınızdır.
31

Enerji sayacı

Hiçbir şeyi kontrol etmeyen, sadece izleyen bir enerji sayacı yazın. Lambayı ve klimayı elle kontrol panelinden (veya aynı anda çalışan başka bir programla) açıp kapatın; sayaç şunları ölçsün:
• lambanın ve klimanın toplam kaç saniye açık kaldığı,
• klimanın kaç kez açıldığı.
Her 5 saniyede bir Lamp 12.3 s, AC 4.0 s, AC started 2 times gibi bir satır yazsın. Ctrl+C ile çıkınca enerji tüketimini hesaplasın: lamba 60 W, klima 1500 W. Enerji (Wh) = güç (W) × süre (s) / 3600. Örnek: Energy: lamp 0.21 Wh, AC 1.67 Wh.

Cevap sende

Bu görevin cevabı verilmiyor. Önceki görevlerin cevaplarındaki fikirleri birleştirerek kendiniz çözün; çalışan programınız sizin cevabınızdır.
32

Elle kontrol önceliği

Otomatik sistemler kullanıcıyı dinlemelidir. Lamba (100 lüks altında yanık) ve klima (28/20 °C histerezis) otomatik çalışsın. Ama kullanıcı elle kontrol panelinden lambanın veya klimanın durumunu değiştirirse, program o cihaza 30 saniye boyunca dokunmasın ve Lamp: manual for 30 s (veya AC: ...) yazsın. 30 saniye dolunca Lamp: back to automatic yazıp otomatiğe dönsün. Ctrl+C ile temiz kapanış olsun.
Deneme: ışık sürgüsünü 50'ye getirin (lamba yanar), sonra Lamba Kapat'a basın: lamba 30 saniye sönük kalmalı, sonra yeniden yanmalı.

Cevap sende

Bu görevin cevabı verilmiyor. Önceki görevlerin cevaplarındaki fikirleri birleştirerek kendiniz çözün; çalışan programınız sizin cevabınızdır.
33

Bir günün döngüsü

Odanın bir gününü yöneten bir durum makinesi yazın. Durumlar: NIGHT, DAY, EVENING.
• Başlangıç: lüks 300 veya üstündeyse perdeyi tamamen açıp DAY, değilse tamamen kapatıp NIGHT durumundan başlayın.
• NIGHT → lüks 300'ün üstüne çıkınca sabah rutini: Good morning! yazın, lambayı hızlıca 3 kez yakıp söndürün (300 ms), perdeyi adım adım açın (1 s yukarı, 2 s bekle, 1 s yukarı, 2 s bekle, sonra sonuna kadar), DAY durumuna geçin.
• DAY → lüks 100'ün altına inince: Good evening! yazın, perdeyi aşağı çalıştırın, lambayı yakın, EVENING durumuna geçin.
• EVENING → 10 saniye sonra lambayı söndürün, Good night! yazın, NIGHT durumuna geçin. Bu 10 saniye beklenirken döngü bloklanmasın (tick sayacı).
• Ctrl+C ile temiz kapanış.
Deneme: ışık sürgüsüyle günü hızlandırın (50 → 500 → 50) ya da yaklaşık 3 dakika bekleyip kendiliğinden değişen gün ışığını izleyin.

Cevap sende

Bu görevin cevabı verilmiyor. Önceki görevlerin cevaplarındaki fikirleri birleştirerek kendiniz çözün; çalışan programınız sizin cevabınızdır.