13. [IMPOTS] alıştırması, WEB hizmeti ile
4.2, 4.3, 8 ve 10. paragraflarda daha önce ele aldığımız [IMPOTS] alıştırmasına geri dönüyoruz.
![]() |
13.1. Sunucu
Aşağıdaki istemci-sunucu mimarisini ele alıyoruz:
![]() |
Sunucu tarafında yine üç katmanlı bir mimari kullanacağız. [dao] katmanı, 10. paragrafta SGBD ve MySQL ile birlikte kullanılan ImpotsMySQL sınıfı tarafından uygulanacaktır. [metier] katmanı, daha önce incelediğimiz [ImpotsMetier] sınıfı tarafından uygulanacaktır. Geriye sadece web hizmetini yazmak kalıyor. Bu hizmet, müşterilerinden params= evet,2,200000 biçiminde bir params parametresi alır; burada ilk öğe vergi mükellefinin evli olup olmadığını, ikinci öğe çocuk sayısını, üçüncü öğe ise yıllık maaşını belirtir.
Web hizmeti şu şekildedir (impots_web_01):
#!D:\Programlar\ActivePython\Python2.7.2\python.exe
# -*- coding=Utf-8 -*-
# Impots* sınıfları modülünün içe aktarılması
from impots import *
import cgi,cgitb,re
# hata ayıklama bilgilerinin görüntülenmesine izin verilir
cgitb.enable()
sys.stderr=sys.stdout
# ------------------------------------------------
# vergi web hizmeti
# ------------------------------------------------
# vergi hesaplaması için gerekli veriler, mysqL TABLE
# tablolarına yerleştirilmiştir. Tablonun yapısı aşağıdaki gibidir
# sınırlar decimal(10,2), coeffR decimal(6,2), coeffN decimal(10,2)
# vergi mükelleflerine ait parametreler (medeni durum, çocuk sayısı, yıllık maaş)
# müşteri tarafından params=medeni durum, çocuk sayısı, yıllık maaş biçiminde gönderilir
# sonuçlar (medeni durum, çocuk sayısı, yıllık maaş, ödenecek vergi) müşteriye geri gönderilir
# <vergi>değer</vergi> biçiminde
# veya parametreler geçersizse <hata>msg</hata> biçiminde
# sunucu, müşteriye biçimlendirilmemiş metin gönderir
print "Content-Type: text/plain\n"
# sabitlerin tanımı
USER="root"
PWD=""
HOTE="localhost"
BASE="dbimpots"
TABLE="impots"
# [metier] katmanı oluşturulur
# Python'da oturum desteği bulunmuyor gibi görünüyor
# PHP'te, iş nesnesini saklamak için bir oturum kullanılırdı
# burada, nesne her zaman veritabanındaki verilerden oluşturuluyor MySQL
# katman örneklendirme [metier]
try:
metier=ImpotsMetier(ImpotsMySQL(HOTE,USER,PWD,BASE,TABLE))
except (IOError, ImpotsError) as infos:
print ("<erreur>Une erreur s'est produite : {0}</erreur>".format(infos))
sys.exit()
# istemci tarafından sunucuya gönderilen satırı alıyoruz
params=cgi.FieldStorage().getlist('params')
# parametre yoksa hata verilir
if not params:
print "<erreur>Le parametre [params] est absent<erreur>"
sys.exit()
# params parametresini işliyoruz
items=params[0].strip().lower().split(',')
# Sadece 3 alan olmalıdır
if len(items)!=3:
print "<erreur>[%s] : nombre de parametres invalide</erreur>" % (params[0])
sys.exit()
# ilk parametre (medeni durum) "evet" veya "hayır" olmalıdır
marie=items[0].strip()
if marie!="oui" and marie != "non":
print "<erreur>[%s] : 1er parametre invalide</erreur>\n"% (params[0])
sys.exit()
# ikinci parametre (çocuk sayısı) bir tamsayı olmalıdır
match=re.match(r"^\s*(\d+)\s*$",items[1])
if not match:
print "<erreur>[%s] : 2ieme parametre invalide</erreur>\n"% (params[0])
sys.exit()
enfants=int(match.groups()[0])
# üçüncü parametre (maaş) bir tamsayı olmalıdır
match=re.match(r"^\s*(\d+)\s*$",items[2])
if not match:
print "<erreur>[%s] : 3ieme parametre invalide</erreur>\n"% (params[0])
sys.exit()
salaire=int(match.groups()[0])
# vergi hesaplanır
impot=metier.calculer(marie,enfants,salaire)
# sonuç döndürülür
print "<impot>%s</impot>\n" % (impot)
# son
Notlar:
-
- satır: impots.py dosyasındaki nesneler içe aktarılır;
-
- satır: Bir CGI betiğinin hata ayıklaması sorunlu olabilir. cgitb modülü, hata durumunda çökmenin nedenini gönderir. Bunun için standart hata çıktısını (sys.stderr) standart çıktıya (sys.stdout) yönlendirmek gerekir (10. satır);
-
- satır: Gönderilen belgenin türünü belirleyen HTTP başlığı; burada biçimlendirilmemiş bir metin söz konusudur. Web hizmeti, yanıtını tek bir metin satırı olarak geri gönderir:
- Hata varsa <erreur>message</erreur>;
- <impot>valeur</impot>; burada valeur, vergi tutarıdır.
-
- satır: [dao] ve [metier] katmanlarının oluşturulması;
- satır 44-46: oluşturma sırasında hata oluşursa, komut dosyası yanıtını gönderir ve sonlanır;
- satır 49-53: 'params' parametresi alınır. Eğer yoksa, komut dosyası yanıtını gönderir ve sonlanır;
- satır 56: 'oui,2,200000' parametresi, items dizisinde 3 alana ayrılır;
- satır 58-77: 3 alanın geçerliliği kontrol edilir. Hata varsa, komut dosyası yanıtını gönderir ve sonlanır;
-
- satır: vergi hesaplanır;
- satır 81: ve müşteriye gönderilir.
Bir web tarayıcısında şu sonuçlar elde edilir:
![]() | ![]() |
13.2. Programlanmış bir müşteri
# -*- coding=utf-8 -*-
import httplib,urllib,re
# sabitler
HOST="localhost"
URL="/cgi-bin/impots_web_01b.py"
data=("oui,2,200000","non,2,200000","oui,3,200000","non,3,200000","x,y,z,t","x,2,200000", "oui,x,200000","oui,2,x");
# bağlantı
connexion=httplib.HTTPConnection(HOST)
# takip
#connexion.set_debuglevel(1)
# sunucuya gönderilecek veriler üzerinde döngü yapılıyor
for params in data:
# parametreler sunucuya gönderilmeden önce kodlanmalıdır
parametres = urllib.urlencode({'params': params})
# isteğin gönderilmesi
connexion.request("POST",URL,parametres)
# yanıtın işlenmesi (metin satırı)
reponse=connexion.getresponse().read()
lignes=reponse.split("\n")
# metin satırı şu biçimdedir
# <impot>xxx</impot>
# veya <hata>xxx</hata>
impot=re.match(r"^<impot>(\S+)</impot>\s*$",lignes[0])
if impot:
print "params=%s, impot=%s" % (params,impot.groups()[0])
else:
erreur=re.match(r"^<erreur>(.+)</erreur>\s*$",lignes[0])
if erreur:
print "params=%s, erreur=%s" % (params,erreur.groups()[0])
else:
print lignes
# bağlantının kapatılması
connexion.close()



