Skip to content

4. Google Gemini ile üç sorunun çözümü

Ortaya çıkan üç sorunu çözmemizi sağlayan üç Gemini oturumunun ekran görüntülerini paylaşacağız. Oldukça ayrıntılı bir şekilde ele alacağız. Bu işlem tamamlandıktan sonra, test edilen diğer IA'ler için süreci tekrarlamayacağız. Bunlar da benzer şekilde çalışmaktadır. Yalnızca dikkat çeken ayrıntıları vereceğiz.

4.1. Giriş

Daha önce paylaştığımız ilk Gemini ekran görüntüsünü hatırlatmak isteriz:

 
  • [1]'te, Gemini'nin URL'i;
  • [2]'te, kullanılan Gemini sürümü;
  • [3-5]'te, Gemini'ye sorulan üç soru;

Gemini, URL [https://gemini.google.com/] adresinde bulunan bir Google ürünüdür. Yukarıdaki gibi soru-cevap oturumlarınızın geçmişine erişmek için bir hesap oluşturmanız gerekir. Ayrıca, test ettiğim diğer tüm IA'ler gibi, Gemini de soru sayınızı ve indirilen dosya sayısını sınırlamaktadır. Bu sınıra ulaşıldığında oturum sona erer ve daha sonra devam etmeniz önerilir. Oturumun ortasında durmak oldukça sinir bozucu olduğu için bir abonelik aldım. Neyse ki Gemini aboneliğinin ilk ayı ücretsiz. Bu sınırlamalara sahip diğer IA'ler, yani ChatGPT, MistralAI ve ClaudeAI için de aynısını yaptım. Bir aylık abonelik aldım, ancak bu sefer ilk ay ücretliydi. Grok’ta herhangi bir sınırla karşılaşmadım. DeepSeek herhangi bir sınır belirtmiyor, ancak bazen [Server busy] yanıtını veriyor ve oturumu sonlandırıyor. Bu, sınır koyup bunu söylememekle aynı şey.

Bundan sonra, soru-cevap oturumlarından bahsedeceğim; bunlara kısaca “oturum” diyeceğim. IA, çoğunlukla İngilizce “chat” (sohbet) veya “conversation” (konuşma) terimlerini kullanıyor.

Gemini’de soru sormak için kullanılan arayüz şöyledir:

  • [1]'te, sorunuz;
  • [2]'te, yanıtın hesaplanması için IA'i başlatan simge;
  • [3-4]'te dosya ekleyebilirsiniz;

4.2. Sorun 1

Sorun 1 için oturum şu şekildedir:

 
  • [1]'te soru;
  • [2]'te, Gemini'nin cevabının başlangıcı;

Cevabın devamı şu şekildedir:

 
 
 
 

Cevap doğrudur. Diğer beş IA de benzer bir biçimde doğru cevabı verecektir.

4.3. Sorun 2

4.3.1. Giriş

Burada, [python3-flask-2020] dersinin başlangıç problemini hatırlatıyoruz. Bu, öğrencilere TD biçiminde verilen bir metindir.

 

Yukarıdaki tablo, beyan edecek tek geliri maaşı olan bir vergi mükellefinin basitleştirilmiş durumunda verginin hesaplanmasına olanak tanır. (1) numaralı notta belirtildiği gibi, bu şekilde hesaplanan vergi, aşağıdaki üç mekanizma uygulanmadan önceki vergidir:

  • Yüksek gelirler için geçerli olan aile katsayısı tavanı;
  • Düşük gelirler için geçerli olan vergi indirimi ve muafiyeti;

Böylece vergi hesaplaması aşağıdaki adımları içerir [http://impotsurlerevenu.org/comprendre-le-calcul-de-l-impot/1217-calcul-de-l-impot-2019.php]:

 

Sadece maaşını beyan eden bir vergi mükellefinin 2019 yılına ait vergisini hesaplamaya yarayan bir program yazmayı amaçlıyoruz.

4.3.1.1. Brüt vergi hesaplaması

Brüt vergi şu şekilde hesaplanabilir:

Öncelikle vergi mükellefinin pay sayısı hesaplanır:

  • Her ebeveyn 1 pay sağlar;
  • İlk iki çocuk, her biri 1/2 pay sağlar;
  • Sonraki çocuklar ise her biri 1 pay sağlar:

Dolayısıyla pay sayısı şöyledir:

  • nbParts=1+nbEnfants*0,5+(çocuk sayısı-2)*0,5 eğer çalışan evli değilse;
  • nbParts=2+nbEnfants*0,5+(nbEnfants-2)*0,5 eğer evliyse;
  • burada nbEnfants, çalışanın çocuk sayısıdır;
  • Vergilendirilebilir gelir R=0,9*S olarak hesaplanır; burada S yıllık maaştır;
  • Aile katsayısı QF = R / nbParts olarak hesaplanır;
  • Brüt vergi I, aşağıdaki verilere göre hesaplanır (2019):
9964
0
0
27519
0,14
1394,96
73779
0,3
5798
156244
0,4
13913,69
0
0,45
20163,45

Her satırda 3 alan vardır: champ1, champ2, champ3. I vergisini hesaplamak için, QF <= alan1 olan ilk satırı arar ve bu satırdaki değerleri alırız. Örneğin, evli, iki çocuğu olan ve yıllık maaşı S 50.000 avro olan bir çalışan için:

Vergilendirilebilir gelir: R=0,9*S=45.000

Pay sayısı: nbParts=2+2*0,5=3

Aile katsayısı: QF=45.000/3=15.000

QF<=alan1 olan ilk satır şöyledir:

    27519    0.14    1394.96

I vergisi ise 0,14*R – 1394,96*nbParts=[0,14*45000-1394,96*3]=2115'e eşittir. Vergi, bir euro aşağı yuvarlanır.

Eğer ilk satırdan itibaren QF<=champ1 ilişkisi geçerliyse, vergi sıfırdır.

QF, QF<=alan1 ilişkisi hiçbir zaman doğrulanmayacak şekilde ise, son satırdaki katsayılar kullanılır. Burada:

    0    0.45    20163.45

bu da brüt vergi I=0,45*R – 20163,45*nbParts sonucunu verir.

4.3.1.2. Aile katsayısı üst sınırı

 

Aile katsayısı üst sınırı QF'in geçerli olup olmadığını belirlemek için, brüt vergi hesaplaması çocukları dikkate almadan yeniden yapılır. Yine, iki çocuğu olan ve yıllık maaşı S 50.000 avro olan evli bir çalışan için:

Vergilendirilebilir gelir: R=0,9*S=45.000

Pay sayısı: nbParts=2 (çocuklar artık hesaba katılmıyor)

Aile katsayısı: QF=45.000/2=22.500

QF<=alan1 olan ilk satır şöyledir:

    27519    0.14    1394.96

I vergisi ise 0,14*R – 1394,96*nbParts=[0,14*45000-1394,96*2]=3510'a eşittir.

Çocuklara ilişkin maksimum kazanç: 1551 * 2 = 3102 avro

Asgari vergi: 3510 – 3102 = 408 avro

Bir önceki paragrafta hesaplanan 2 paylı brüt vergi tutarı olan 2115 avro, asgari vergi tutarı olan 408 avrodan yüksek olduğundan, bu durumda aile tavanı uygulanmaz.

Genel olarak, brüt vergi, (vergi1, vergi2) aralığının üst sınırıdır; burada:

  • [impôt1]: çocuklarla birlikte hesaplanan brüt vergidir;
  • [impôt2]: çocukları dikkate almadan hesaplanan ve çocuklarla ilgili azami indirim (burada yarım pay başına 1551 avro) düşülmüş brüt vergidir;

4.3.1.3. İndirim Hesaplaması

 

Yine, iki çocuğu olan ve yıllık maaşı S 50.000 avro olan evli çalışan için:

Bir önceki adımda elde edilen brüt vergi (2115 avro), bir çift için 2627 avrodan (bekar için 1595 avrodan) daha düşüktür: dolayısıyla indirim uygulanır. İndirim, aşağıdaki hesaplama ile elde edilir:

indirim = eşik (çift = 1970 / bekar = 1196) - 0,75 * brüt vergi

indirim = 1970 - 0,75 * 2115 = 383,75 (384 avroya yuvarlanır).

Yeni brüt vergi = 2115 - 384 = 1731 avro

İndirim hesaplamasında iki kurala dikkat edilmelidir (bazı IA araçları bu konuda sorun yaşamıştır):

  • İndirim negatif olamaz;
  • İndirim, önceden hesaplanan vergiden fazla olamaz;

4.3.1.4. Vergi indiriminin hesaplanması

 

Belirli bir eşik değerin altında, önceki hesaplamalardan elde edilen brüt vergi üzerinden %20'lik bir indirim uygulanır. 2019 yılında eşik değerler şu şekildedir:

  • bekar: 21.037 avro;
  • çift: 42.074 avro; (yukarıdaki örnekte kullanılan 37.968 rakamı hatalı görünmektedir);

Bu eşik, 3.797 * (çocukların sağladığı yarım pay sayısı) tutarında artırılır.

Yine, iki çocuğu olan ve yıllık maaşı S 50.000 avro olan evli çalışan için:

  • Vergilendirilebilir geliri (45.000 avro) eşik değerinden (42.074 + 2 * 3.797) = 49.668 avro daha düşüktür;
  • Dolayısıyla, vergisinde %20’lik bir indirim hakkına sahiptir: 1731 * 0,2 = 346,2 avro (347 avroya yuvarlanır);
  • Vergi mükellefinin brüt vergisi şu şekilde hesaplanır: 1.731 - 347 = 1.384 avro;

4.3.1.5. Net vergi hesaplaması

Hesaplamamız burada sona eriyor: ödenecek net vergi 1384 avro olacaktır. Gerçekte, vergi mükellefi, özellikle kamu yararına veya genel yarara hizmet eden kuruluşlara yapılan bağışlar için başka indirimlerden de yararlanabilir.

4.3.1.6. Yüksek gelirli kişiler

Yukarıdaki örneğimiz, çalışanların çoğunu kapsamaktadır. Ancak yüksek gelirli kişilerde vergi hesaplaması farklıdır.

4.3.1.6.1. Yıllık gelirler üzerindeki %10’luk indirimin üst sınırı

Çoğu durumda, vergilendirilebilir gelir şu formülle hesaplanır: R=0,9*S; burada S, yıllık maaştır. Buna %10’luk indirim denir. Bu indirim için bir üst sınır vardır. 2019 yılında:

  • 12.502 avrodan fazla olamaz;
  • 437 avrodan az olamaz;

Çocuksuz ve evli olmayan, yıllık maaşı 200.000 avro olan bir çalışanı ele alalım:

  • %10'luk indirim 20.000 avro > 12.502 avrodur. Dolayısıyla 12.502 avroya indirilir;

4.3.1.6.2. Aile katsayısı üst sınırı

|Plafonnement du quotient familial| paragrafında belirtilen aile katsayısı üst sınırının geçerli olduğu bir durumu ele alalım. Üç çocuğu olan ve yıllık geliri 100.000 avro olan bir çift örneğini ele alalım. Hesaplama adımlarını tekrar gözden geçirelim:

  • %10’luk indirim tutarı 100.000 avro < 12.502 avrodur. Dolayısıyla vergilendirilebilir gelir R, 100.000 - 10.000 = 90.000 avrodur;
  • Çiftin nbParts değeri 2 + 0,5 × 2 + 1 = 4 paydır;
  • Dolayısıyla aile katsayısı QF = R / nbParts = 90.000 / 4 = 22.500 avrodur;
  • Çocuklu brüt vergisi I1, I1=0,14*90.000-1.394,96*4= 7.020 avrodur;
  • Çocuksuz brüt vergisi I2:
    • QF=90.000/2=45.000 avro;
    • I2=0,3*90000-5798*2=15404 avro;
  • Aile katsayısı üst sınırı kuralına göre, çocuklardan kaynaklanan kazanç (1551*4 yarım pay)=6204 avroyu aşamaz. Oysa burada bu tutar I2-I1=15404-7020= 8384 avrodur, yani 6204 avrodan fazladır;
  • Dolayısıyla brüt vergi, I3 = I2-6204 = 15.404 - 6.204 = 9.200 avro olarak yeniden hesaplanır;
  • I3 > I1 olduğundan, I3 tutarındaki vergi dikkate alınacaktır;

Bu çiftin vergi indirimi veya iskontosu olmayacak ve nihai vergisi 9200 avro olacaktır.

4.3.1.7. Resmi rakamlar

Vergi hesaplaması karmaşıktır. Belgenin tamamında, testler aşağıdaki örnekler kullanılarak yapılacaktır. Sonuçlar, |https://www3.impots.gouv.fr/simulateur/calcul_impot/2019/simplifie/index.htm| vergi idaresi simülatöründen alınmıştır:

Vergi mükellefi
Resmi sonuçlar
Belgedeki algoritmanın sonuçları
2 çocuğu olan ve yıllık geliri 55555 avro olan çift
Vergi = 2815 avro
Vergi oranı = %14
Vergi = 2.814 avro
Vergi oranı = %14
2 çocuğu olan ve yıllık geliri 50.000 avro olan çift
Vergi = 1385 avro
İndirim = 384 avro
İndirim = 346 avro
Vergi oranı = %14
Vergi = 1.384 avro
İndirim = 384 avro
İndirim = 347 avro
Vergi oranı = %14
3 çocuğu olan ve yıllık geliri 50.000 avro olan çift
Vergi = 0 avro
İndirim = 720 avro
İndirim = 0 avro
Vergi oranı = %14
Vergi = 0 avro
indirim = 720 euro
İndirim=0 euro
Vergi oranı = %14
Bekar, 2 çocuğu olan ve yıllık geliri 100.000 euro olan kişi
Vergi = 19.884 euro
indirim=0 euro
İndirim = 0 avro
Vergi oranı = %41
Vergi = 19.884 euro
Ek vergi = 4.480 euro
İndirim = 0 euro
İndirim = 0 euro
Vergi oranı = %41
Bekar, 3 çocuğu olan ve yıllık geliri 100.000 avro olan kişi
Vergi = 16.782 avro
İndirim = 0 euro
İndirim = 0 euro
Vergi oranı = %41
Vergi = 16.782 avro
Ek vergi = 7.176 avro
indirim=0 euro
İndirim = 0 euro
Vergi oranı = %41
3 çocuğu olan ve yıllık geliri 100.000 avro olan çift
Vergi = 9.200 avro
İndirim = 0 euro
İndirim = 0 euro
Vergi oranı = %30
Vergi = 9.200 avro
Ek vergi = 2180 avro
indirim=0 euro
İndirim = 0 euro
Vergi oranı = %30
5 çocuğu olan ve yıllık geliri 100.000 avro olan çift
Vergi = 4.230 avro
İndirim = 0 euro
İndirim = 0 euro
Vergi oranı = %14
Vergi = 4.230 avro
İndirim = 0 euro
İndirim=0 euro
Vergi oranı = %14
Çocuksuz bekar ve yıllık geliri 100.000 avro olan kişi
Vergi = 22.986 avro
İndirim = 0 euro
İndirim = 0 euro
Vergi oranı = %41
Vergi = 22.986 avro
Ek vergi = 0 avro
indirim=0 euro
İndirim = 0 euro
Vergi oranı = %41
2 çocuğu olan ve yıllık geliri 30.000 avro olan çift
Vergi = 0 euro
İndirim = 0 euro
İndirim = 0 euro
Vergi oranı = %0
Vergi = 0 euro
indirim = 0 euro
İndirim=0 euro
Vergi oranı = %0
Çocuksuz bekar ve yıllık geliri 200.000 avro olan kişi
Vergi = 64.211 euro
İndirim=0 euro
İndirim = 0 euro
Vergi oranı = %45
Vergi = 64.210 avro
Ek vergi = 7498 avro
indirim=0 euro
İndirim = 0 euro
Vergi oranı = %45
3 çocuğu olan ve yıllık geliri 200.000 avro olan çift
Vergi = 42.843 avro
İndirim = 0 euro
İndirim = 0 euro
Vergi oranı = %41
Vergi = 42.842 avro
Ek vergi = 17.283 avro
indirim=0 euro
İndirim = 0 euro
Vergi oranı = %41

Yukarıda, yüksek gelirli kişilerin iki nedenden dolayı ek olarak ödedikleri tutara “ek vergi” denir:

  • Yıllık gelirler üzerindeki %10'luk indirim tavanı;
  • Aile katsayısının üst sınırı;

Bu gösterge, vergi idaresinin simülatöründe yer almadığı için doğrulanamamıştır.

Belgedeki algoritmanın her seferinde doğru bir vergi tutarı verdiği görülüyor; ancak 1 avroluk bir hata payı var. Bu hata payı, yuvarlamalardan kaynaklanıyor. Tüm para tutarları bazen bir üst avroya, bazen de bir alt avroya yuvarlanıyor. Resmi kuralları bilmediğim için, belgedeki algoritmadaki tutarlar şu şekilde yuvarlanmıştır:

  • İndirimler ve iskontolar için bir üst euroya;
  • Ek ücretler ve nihai vergi için bir euro aşağı yuvarlanmıştır;

IA'ten bu vergi hesaplamasını yapmasını isteyeceğiz.

4.3.2. Gemini oturumunun yapılandırılması

Gemini’ye yöneltilen soru, iki dosya ile birlikte sunulur:

 
  • [1] dosyasında, az önce ayrıntılı olarak açıklanan hesaplama, Gemini'ye verilen bir PDF dosyasına aktarılmıştır. Gemini, bu dosyada 2018 gelirleri üzerinden 2019 vergisinin basitleştirilmiş hesaplamasına ilişkin kesin kuralları bulacaktır;
  • [2] dosyasında talimatlarımız yer almaktadır;
  • [3] dosyasında, IA dosyasını çalıştırmak için gerekli bilgiler yer almaktadır;

[instructionsAvecPDF.txt] metin dosyasındaki talimatlarımız şunlardır:

1 - Exprime-toi en français.

2 - Peux-tu générer un script Python permettant de calculer l'impôt payé par les familles en 2019 sur leurs revenus de 2018.

3 - Tu t'aideras du document PDF que j'ai joint et qui explique les calculs à faire.

4 - Tu dois faire attention aux points suivants :

- plafonnement du quotient familial. Il y a des seuils à vérifier.
- calcul de la décote dans certains cas. Il y a des seuils à vérifier.
- calcul de la réduction de 20% dans certains cas. Il y a des seuils à vérifier.
- plafonnement de l'abattement de 10% sur les revenus annuels dans certains cas.
- tu considèreras que tous les revenus sont à déclarer pour le déclarant 1 même si le couple est marié.

5 - Tu ajouteras au script généré des tests unitaires pour les cas suivants.

Dans ces tests on appelle :

adultes :nombre d'adultes du foyer fiscal
enfants : nombre d'enfants du foyer fiscal
revenus : revenus nets annuels avant impôt, ç-à-d avant le 1er calcul de l'abattement.
impot : l'impôt à payer
decote :la décote éventuelle du foyer fiscal
reduction : la réduction de 20% pour les faibles revenus

Voici les 11 tests à vérifier. Ils ont tous été vérifiés manuellement sur le simulateur officiel
du calcul de l'impôt 2019 [https://www3.impots.gouv.fr/simülatör/calcul_impot/2019/basitleştirir/index.html].
Si tu utilises ce simulateur les revenus doivent être associés au seul déclarant 1 dans le cas d'un couple, le déclarant 2 étant alors ignoré. Lorsqu'on répartit les revenus
sur deux déclarants, on n'obtient pas le même résultat.

On utilise la syntaxe (adultes, enfants, revenus) -> (impot, decote, reduction) pour dire que le script reçoit les entrées
(adultes, enfants, revenus) et produit les résultats (impot, decote, reduction)

test1 : (2,2,55555) -> (2815, 0, 0)
test2 : (2, 2, 50000) -> (1385, 384, 346)
test3 : (2,3,50000) -> (0, 720, 0)
test4: (1,2,100000) -> (19884, 0, 0)
test5: (1,3,100000) -> (16782, 0, 0)
test6 : (2, 3, 100000) -> (9200, 0, 0)
test7 : (2, 5, 100000) -> (4230, 0, 0)
test8 : (1, 0, 100000) -> (22986, 0, 0)
test9 : (2, 2, 30000) -> (0, 0, 0)
test10 : (1,0,200000) -> (64211, 0, 0)
test11  : (2, 3, 200000) -> (42843, 0, 0)

6 - Il peut y avoir des problèmes d'arrondis. Tu procèderas comme suit
- l'impôt à payer sera arrondi à l'euro inférieur,
- la décote sera arrondie à l'euro supérieur,
- la réduction de 20 % sera arrondie à l'euro supérieur.
- l'abattement de 10% sera arrondi à l'euro supérieur

Fais tous les tests unitaires à l'euro près à cause de ces éventuelles erreurs d'arrondi.
Ne cherche pas à avoir les valeurs exactes ci-dessus mais ces valeurs à 1 euro près.

7 - Evite de chercher sur internet. Le PDF que je te donne est correct.
Ne donne ton résultat que lorsque tu as passé les 11 tests unitaires avec succès.

8 - si l'un des tests échoue et que tu es bloqué, affiche ton raisonnement pour ce test
afin que je puisse t'aider.

9- Mets des commentaires détaillés dans le script que tu génères.
Mets le barème progressif dans une liste ou dictionnaire puis utilise cette liste ou dictionnaire
Mets les nombres en dur (nombres magiques) que tu utilises dans des constantes
Utilise des fonctions pour séparer les étapes du calcul.
Ecris le tout en français

9 - n'affiche pas le code généré à l'écran. Donne-moi simplement un lien pour le récupérer.
Si les tests unitaires échouent, je te donnerai les logs de l'exécution du script pour que
tu voies tes erreurs.

10 - si c'est possible, indique le temps en minutes et secondes que tu as mis pour produire
le script demandé.

Bu talimatlar, Gemini'ye yöneltilen çok sayıda sorunun sonucudur. Oldukça kısa sürede, istediğimizi elde etmek istiyorsak IA'in çok net bir şekilde tanımlanması gerektiği anlaşılır. Tüm bu deneme yanılma süreçleri nedeniyle Gemini oturumu, sınırların aşılması nedeniyle nihayetinde durduruldu. Bu talimatların devamını inceleyelim:

  • 1. satır: Konuşmanın Fransızca olması isteniyor. Bu talimat, İngilizce konuşma eğiliminde olan DeepSeek için verilmiştir;
  • 3. satır: İstediğimiz şey;
  • 5. satır: IA’e, kendisine verilen PDF’i kullanması söyleniyor;
  • Satır 7-14: Özellikle PDF olmadan 3. problem için bir dizi yararlı ipucu. Vergi hesaplamasında birkaç IA kayboldu;
  • Satır 15-44: Oluşturulan komut dosyasında yer almasını istediğimiz 11 birim testi. Komut dosyası oluşturulduğunda, bunu PyCharm'te çalıştıracağız ve 11 testin başarılı olup olmadığını göreceğiz;
  • Satır 46-53: Bu talimatlar olmasaydı, IA, tam sonuçları arayan ve başarısız olan birim testleri oluştururdu;
  • 55-56. satırlar: IA'e internete bağlanmamasını söylüyorum. En basit çözüm, PDF'i kullanmaktır;
  • 58-59. satırlar: Bu talimat, IA tarafından yerine getirilmedi. Bir testin başarısız olduğunu fark ettiğimde, bunu bir soruda açıkça belirtmek zorunda kaldım;
  • Satır 61-65: Ne tür bir Python betiği istediğimi belirtiyorum;
  • Satır 67-69: Ekranda kodun görüntülenmesi zaman aldığı için, oluşturulan betiği almak üzere bir bağlantı olmasını tercih ederdim. Çoğu IA'in bunu yapamadığı ortaya çıktı. Verilen bağlantılar çalışmıyordu;
  • 71-72. satırlar: IA'in soruyu yanıtlamak için harcadığı süreyi öğrenmek isterdim. Yalnızca Gemini bana bu bilgiyi verebildi. Diğer IA'ler ya bu talimata yanıt vermediler ya da bu talimatı anlamadıklarını gösteren uydurma rakamlar verdiler;

4.3.3. Gemini’nin cevabı

Gemini’nin ilk cevabı şöyledir:

 
  • [1-4]'te Gemini, belirli bir anda kullandığı PDF kısmına veya talimat metin dosyasına bağlantılar sağlıyor;

Devamı şu şekildedir:

 
  • [1]'te Gemini, 11 birim testini başarıyla gerçekleştirdiğini belirtir. Çoğu IA dosyası, hem 2. soruda hem de 3. soruda bunu iddia etmiştir ve genellikle oluşturulan komut dosyası yüklendiğinde çalışmamıştır. Dolayısıyla bu iddiaya şüpheyle yaklaşmak gerekir. Gemini için bu iddia doğru çıkacaktır;
  • [2]'te, çalışmadığı ortaya çıkacak bir bağlantı;
  • [3'te yalnızca Gemini gerçekçi bir yürütme süresi verdi;

Dolayısıyla [2] bağlantısı çalışmıyor. Bunu Gemini’ye bildiriyoruz:

 

Gemini'nin yanıtı:

 
  • [1]'te, Gemini tarafından oluşturulan Python betiği;

Bu betiği PyCharm dosyasına yükleyip çalıştırıyoruz:

 
  • [1] dosyasında, [gemini1], Gemini tarafından oluşturulan betiktir;

Komut dosyası çalıştırıldığında derleme hataları ortaya çıkar:


"C:\Program Files\Python313\python.exe" "C:/Program Files/JetBrains/PyCharm 2025.2.0.1/plugins/python-ce/helpers/pycharm/_jb_unittest_runner.py" --path "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\chatGPT\chatGPT1.py" 
Testing started at 17:12 ...
Launching unittests with arguments python -m unittest C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\chatGPT\chatGPT1.py in C:\Data\st-2025\dev\python\code\python-flask-2025-cours

Traceback (most recent call last):
  File "C:\Program Files\JetBrains\PyCharm 2025.2.0.1\plugins\python-ce\helpers\pycharm\_jb_unittest_runner.py", line 38, in <module>
    sys.exit(main(argv=args, module=None, testRunner=unittestpy.TeamcityTestRunner,
             ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                  buffer=not JB_DISABLE_BUFFERING))
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Program Files\Python313\Lib\unittest\main.py", line 103, in __init__
    self.parseArgs(argv)
    ~~~~~~~~~~~~~~^^^^^^
  File "C:\Program Files\Python313\Lib\unittest\main.py", line 142, in parseArgs
    self.createTests()
    ~~~~~~~~~~~~~~~~^^
  File "C:\Program Files\Python313\Lib\unittest\main.py", line 153, in createTests
    self.test = self.testLoader.loadTestsFromNames(self.testNames,
                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
                                                   self.module)
                                                   ^^^^^^^^^^^^
  File "C:\Program Files\Python313\Lib\unittest\loader.py", line 207, in loadTestsFromNames
    suites = [self.loadTestsFromName(name, module) for name in names]
              ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
  File "C:\Program Files\Python313\Lib\unittest\loader.py", line 137, in loadTestsFromName
    module = __import__(module_name)
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\chatGPT\chatGPT1.py", line 28, in <module>
    [cite_start]
     ^^^^^^^^^^
NameError: name 'cite_start' is not defined

Process finished with exit code 1

Empty suite
  • 30. satırda derleme hatası var. [cite_start], belirli bir metin biçimini oluşturmak için kullanılan bir işaretçidir;

Yukarıdaki günlükleri [logs gemini1.txt] adlı bir dosyaya kaydedip bunu Gemini'ye veriyoruz:

 

Gemini'nin yanıtı şu şekildedir:

 

PyCharm dosyasına yüklendiğinde, yeni komut dosyasının çalıştırılması tam olarak aynı hatayı veriyor. Bunu Gemini’ye, çalıştırma günlüklerini tekrar sağlayarak bildiriyoruz:

 

Gemini'nin yanıtı şöyledir:

 

Bu sefer başarılı oldu. 11 birim testi de başarılı geçti. Bunu Gemini'ye bildiriyoruz:

 

Gemini şöyle yanıtlıyor:

 

Gemini tarafından oluşturulan komut dosyası, [instructionsAvecPDF.txt] metin dosyasında verilen talimatları izledi:

# -*- coding: utf-8 -*-
"""
Script pour le calcul de l'impôt 2019 sur les revenus de 2018 en France,
basé sur les règles simplifiées fournies dans le document PDF.
"""

import math
import unittest

# --- CONSTANTES DE CALCUL POUR L'IMPÔT 2019 ---
# Tüm değerler, sağlanan PDF belgesinden alınmıştır.

# Yıllık gelirler üzerinden %10'luk indirim için üst sınırlar
PLAFOND_ABATTEMENT_10_POURCENT = 12502.0
MINIMUM_ABATTEMENT_10_POURCENT = 437.0

# 2019 gelir vergisi tablosu
# Yapı: (Gelir diliminin üst sınırı, Vergi oranı, Kişi başına indirilecek tutar)
BAREME_IMPOT_2019 = [
    {"seuil": 9964, "taux": 0.0, "deduction_par_part": 0},
    {"seuil": 27519, "taux": 0.14, "deduction_par_part": 1394.96},
    {"seuil": 73779, "taux": 0.30, "deduction_par_part": 5798},
    {"seuil": 156244, "taux": 0.41, "deduction_par_part": 13913.69},
    {"seuil": float('inf'), "taux": 0.45, "deduction_par_part": 20163.45}
]

# Aile katsayısı üst sınırı
GAIN_MAX_DEMI_PART = 1551.0  # Ek yarım pay başına azami kazanç

# İndirim eşikleri ve tutarları
SEUIL_APPLICATION_DECOTE = {"celibataire": 1595.0, "couple": 2627.0}
SEUIL_CALCUL_DECOTE = {"celibataire": 1196.0, "couple": 1970.0}

# %20 vergi indirimi için eşikler
SEUIL_BASE_REDUCTION_20 = {"celibataire": 21037.0, "couple": 42074.0}
MAJORATION_SEUIL_REDUCTION_PAR_DEMI_PART = 3797.0


def calculer_nombre_parts(adultes: int, enfants: int) -> float:
    """
    Calcule le nombre de parts fiscales du foyer.
    - Chaque parent amène 1 part.
    - Les deux premiers enfants amènent chacun 1/2 part.
    - Les enfants suivants amènent une part chacun.
    """
    if adultes not in [1, 2]:
        raise ValueError("Le nombre d'adultes doit être 1 ou 2.")

    parts = float(adultes)
    if enfants > 0:
        parts += 0.5 * min(enfants, 2)
    if enfants > 2:
        parts += 1.0 * (enfants - 2)

    return parts


def calculer_revenu_imposable(revenus: float) -> float:
    """
    Calcule le revenu net imposable après l'abattement de 10%.
    Cet abattement est plafonné.
    L'abattement est arrondi à l'euro supérieur.
    """
    abattement_calcule = revenus * 0.1
     # Vergi indirimi, asgari ve azami tutarlar arasında sınırlandırılmıştır
    abattement = min(PLAFOND_ABATTEMENT_10_POURCENT, max(MINIMUM_ABATTEMENT_10_POURCENT, abattement_calcule))

     # Soru, indirimi bir üst avroya yuvarlamayı gerektirir
    abattement_arrondi = math.ceil(abattement)

    return revenus - abattement_arrondi


def calculer_impot_brut_base(revenu_imposable: float, nombre_parts: float) -> float:
    """
    Calcule l'impôt brut selon le barème progressif.
    """
    if nombre_parts <= 0:
        return 0.0

    quotient_familial = revenu_imposable / nombre_parts

    tranche_applicable = None
    for tranche in BAREME_IMPOT_2019:
        if quotient_familial <= tranche["seuil"]:
            tranche_applicable = tranche
            break

     # QF değeri tüm eşiklerin üzerindeyse, son dilim kullanılır
    if tranche_applicable is None:
        tranche_applicable = BAREME_IMPOT_2019[-1]

     # Brüt vergi hesaplama formülü
    impot_brut = (revenu_imposable * tranche_applicable["taux"]) - (
            tranche_applicable["deduction_par_part"] * nombre_parts)

    return max(0.0, impot_brut)


def appliquer_plafonnement_qf(impot_brut_avec_enfants: float, revenu_imposable: float, adultes: int,
                              enfants: int) -> float:
    """
    Applique le plafonnement du quotient familial si nécessaire.
    L'impôt final ne peut être inférieur à l'impôt calculé sans les enfants,
    diminué d'un gain maximal par demi-part.
    """
    if enfants == 0:
        return impot_brut_avec_enfants

     # Çocukların payları hariç vergi hesaplaması
    parts_sans_enfants = calculer_nombre_parts(adultes, 0)
    impot_sans_enfants = calculer_impot_brut_base(revenu_imposable, parts_sans_enfants)

     # Çocuklarla ilgili maksimum kazanç hesaplaması
    parts_avec_enfants = calculer_nombre_parts(adultes, enfants)
    demi_parts_enfants = (parts_avec_enfants - parts_sans_enfants) * 2
    gain_maximal = demi_parts_enfants * GAIN_MAX_DEMI_PART

    impot_minimal_plafone = impot_sans_enfants - gain_maximal

     # Kesilen vergi, iki hesaplamadan en yüksek olanıdır
    return max(impot_brut_avec_enfants, impot_minimal_plafone)


def appliquer_decote(impot_avant_decote: float, adultes: int) -> tuple[float, float]:
    """
    Applique la décote si l'impôt est inférieur à certains seuils.
    La décote est arrondie à l'euro supérieur.
    """
    statut = "couple" if adultes == 2 else "celibataire"
    seuil_application = SEUIL_APPLICATION_DECOTE[statut]
    seuil_calcul = SEUIL_CALCUL_DECOTE[statut]

    decote = 0.0
     # Vergi, uygulama eşiğinin altındaysa indirim uygulanır
    if impot_avant_decote < seuil_application:
         # İndirim formülü: eşik - 0,75 * Brüt vergi
        decote_calculee = seuil_calcul - (0.75 * impot_avant_decote)

         # Bir üst avroya yuvarlanır
        decote = math.ceil(decote_calculee)

         # İndirim, negatif olamaz ve vergi tutarını aşamaz
        decote = max(0.0, min(decote, impot_avant_decote))

    impot_apres_decote = impot_avant_decote - decote
    return impot_apres_decote, decote


def appliquer_reduction_20_pourcent(impot_avant_reduction: float, revenu_imposable: float, adultes: int,
                                    enfants: int) -> tuple[float, float]:
    """
    Applique la réduction de 20% sous condition de revenus.
    La réduction est arrondie à l'euro supérieur.
    """
    statut = "couple" if adultes == 2 else "celibataire"
    seuil_base = SEUIL_BASE_REDUCTION_20[statut]

     # Eşik, çocuklarla ilgili her yarım pay için artırılır
    parts_avec_enfants = calculer_nombre_parts(adultes, enfants)
    parts_adultes = calculer_nombre_parts(adultes, 0)
    demi_parts_enfants = (parts_avec_enfants - parts_adultes) * 2
    seuil_final = seuil_base + (demi_parts_enfants * MAJORATION_SEUIL_REDUCTION_PAR_DEMI_PART)

    reduction = 0.0
     # Vergiye tabi gelir eşik değerinin altındaysa indirim uygulanır
    if revenu_imposable < seuil_final:
        reduction_calculee = impot_avant_reduction * 0.20

         # Bir üst euroya yuvarlanır
        reduction = math.ceil(reduction_calculee)

    impot_apres_reduction = impot_avant_reduction - reduction
    return max(0.0, impot_apres_reduction), reduction


def calculer_impot(adultes: int, revenus: float, enfants: int) -> dict:
    """
    Orchestre le calcul complet de l'impôt net à payer.
    """
     # Adım 1: Vergilendirilebilir gelirin hesaplanması
    revenu_imposable = calculer_revenu_imposable(revenus)

     # Adım 2: Pay sayısının hesaplanması
    nombre_parts = calculer_nombre_parts(adultes, enfants)

     # Adım 3: Brüt verginin hesaplanması
    impot_brut_initial = calculer_impot_brut_base(revenu_imposable, nombre_parts)

     # Adım 4: QF sınırının uygulanması
    impot_apres_plafonnement = appliquer_plafonnement_qf(impot_brut_initial, revenu_imposable, adultes, enfants)

     # Adım 5: İndirimin uygulanması
    impot_apres_decote, decote_calculee = appliquer_decote(impot_apres_plafonnement, adultes)

     # 6. Adım: %20’lik indirimin uygulanması
    impot_avant_arrondi_final, reduction_calculee = appliquer_reduction_20_pourcent(impot_apres_decote,
                                                                                    revenu_imposable, adultes, enfants)

     # 7. Adım: Verginin bir euro aşağıya yuvarlanması
    impot_final = math.floor(impot_avant_arrondi_final)

    return {
        "impot": impot_final,
        "decote": decote_calculee,
        "reduction": reduction_calculee
    }


# --- TESTS UNITAIRES ---
# Verilen örneklerle komut dosyasının doğrulanması
class TestCalculImpot2019(unittest.TestCase):

    def _verifier_resultat(self, adultes, enfants, revenus, impot_attendu, decote_attendue, reduction_attendue):
        """Fonction utilitaire pour exécuter un test et vérifier les résultats à 1 euro près."""
        resultat = calculer_impot(adultes=adultes, revenus=revenus, enfants=enfants)

        self.assertAlmostEqual(resultat["impot"], impot_attendu, delta=1,
                               msg=f"Test ({adultes}, {enfants}, {revenus}): Impôt attendu {impot_attendu}, obtenu {resultat['impot']}")

        self.assertAlmostEqual(resultat["decote"], decote_attendue, delta=1,
                               msg=f"Test ({adultes}, {enfants}, {revenus}): Décote attendue {decote_attendue}, obtenue {resultat['decote']}")

        self.assertAlmostEqual(resultat["reduction"], reduction_attendue, delta=1,
                               msg=f"Test ({adultes}, {enfants}, {revenus}): Réduction attendue {reduction_attendue}, obtenue {resultat['reduction']}")

    def test_cas_1(self):
        # (2, 2, 55555) -> (2815, 0, 0)
        self._verifier_resultat(2, 2, 55555, 2815, 0, 0)

    def test_cas_2(self):
        # (2, 2, 50000) -> (1385, 384, 346)
        self._verifier_resultat(2, 2, 50000, 1385, 384, 346)

    def test_cas_3(self):
        # (2, 3, 50000) -> (0, 720, 0)
        self._verifier_resultat(2, 3, 50000, 0, 720, 0)

    def test_cas_4(self):
        # (1, 2, 100000) -> (19884, 0, 0)
        self._verifier_resultat(1, 2, 100000, 19884, 0, 0)

    def test_cas_5(self):
        # (1, 3, 100000) -> (16782, 0, 0)
        self._verifier_resultat(1, 3, 100000, 16782, 0, 0)

    def test_cas_6(self):
        # (2, 3, 100000) -> (9200, 0, 0)
        self._verifier_resultat(2, 3, 100000, 9200, 0, 0)

    def test_cas_7(self):
        # (2, 5, 100000) -> (4230, 0, 0)
        self._verifier_resultat(2, 5, 100000, 4230, 0, 0)

    def test_cas_8(self):
        # (1, 0, 100000) -> (22986, 0, 0)
        self._verifier_resultat(1, 0, 100000, 22986, 0, 0)

    def test_cas_9(self):
        # (2, 2, 30000) -> (0, 0, 0)
        self._verifier_resultat(2, 2, 30000, 0, 0, 0)

    def test_cas_10(self):
        # (1, 0, 200000) -> (64211, 0, 0)
        self._verifier_resultat(1, 0, 200000, 64211, 0, 0)

    def test_cas_11(self):
        # (2, 3, 200000) -> (42843, 0, 0)
        self._verifier_resultat(2, 3, 200000, 42843, 0, 0)


if __name__ == '__main__':
    print("Exécution des tests unitaires...")
    unittest.main(argv=['first-arg-is-ignored'], exit=False)

     # Hesaplayıcının belirli bir örnek için kullanım örneği
    print("\n--- Exemple de calcul ---")
    revenus_annuels = 50000
    nombre_adultes = 2
    nombre_enfants = 2

    resultat_calcul = calculer_impot(adultes=nombre_adultes, revenus=revenus_annuels, enfants=nombre_enfants)

    print(f"Pour un couple ({nombre_adultes} adultes) avec {nombre_enfants} enfants et {revenus_annuels}€ de revenus :")
    print(f"  - Impôt à payer : {resultat_calcul['impot']}€")
    print(f"  - Montant de la décote : {resultat_calcul['decote']}€")
    print(f"  - Montant de la réduction : {resultat_calcul['reduction']}€")

Bu kodu kontrol etmedim. 11 birim testi de başarılı olduğu için, kodun "muhtemelen doğru" olduğunu düşünüyorum. Kendi kodum için bu 11 testi kontrol etmekten başka bir şey yapmadım.

4.4. Sorun 3

Sorun 3, uyulması gereken hesaplama kurallarını veren PDF dosyası artık IA dosyasına verilmediği dışında, sorun 2 ile aynıdır.

Gemini’ye yöneltilen ilk soru şöyledir:

 

[1] dosyasındaki talimatlar, aşağıdaki farklılıklar dışında Problem 2'dekiyle neredeyse aynıdır:


1 - Exprime-toi en français.

2 - Peux-tu générer un script Python permettant de calculer l'impôt payé par les familles en 2019 sur leurs revenus de 2018.

3 - Tu t'aideras des sources que tu trouveras sur internet. Dans ta réponse indique-moi ces sources.

4 - Tu dois faire attention aux points suivants :

  • [3] sorusunda, 2018 yılı gelirleri üzerinden 2019 yılı vergisinin hesaplanma kurallarını internetten bulması isteniyor. Bu, bir önceki alıştırmadan daha zor bir alıştırmadır;

Aşağıda Gemini’nin ilk cevabının sadece bazı kısımlarını veriyorum:

 
 

Tahmin edilen süre makul. Gemini'nin yanıtını uzun süre bekliyoruz.

Daha önce olduğu gibi, Gemini oluşturulan komut dosyasının indirilme bağlantısını verdi, ancak bu bağlantı çalışmıyor. Ona bunu bildiriyoruz:

 

Gemini’nin yanıtı:

 

PyCharm komut dosyasını [gemini2] adıyla yüklüyoruz:

 

Çalıştırıyoruz ve… çalışmıyor. Çalıştırma günlükleri şu şekildedir:


"C:\Program Files\Python313\python.exe" "C:/Program Files/JetBrains/PyCharm 2025.2.0.1/plugins/python-ce/helpers/pycharm/_jb_unittest_runner.py" --path "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py" 
Testing started at 17:23 ...
Launching unittests with arguments python -m unittest C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py in C:\Data\st-2025\dev\python\code\python-flask-2025-cours


Failure
Traceback (most recent call last):
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py", line 278, in test_cas_2
    self.assertAlmostEqual(impot, 1385, delta=1)
    ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 1691 != 1385 within 1 delta (306 difference)


Error
Traceback (most recent call last):
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py", line 291, in test_cas_3
    impot, _, _ = calculer_impot_final(2, 3, 50000)
                  ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py", line 187, in calculer_impot_final
    decote, impot_apres_decote = calculer_decote(impot_apres_plafonnement, adultes)
                                 ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py", line 134, in calculer_decote
    decote = seuil_decote - (impot_avant_decote * COFFICIENT_DECOTE)
                                                  ^^^^^^^^^^^^^^^^^
NameError: name 'COFFICIENT_DECOTE' is not defined. Did you mean: 'COEFFICIENT_DECOTE'?


Error
Traceback (most recent call last):
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py", line 316, in test_cas_9
    self._verifier_cas(2, 2, 30000, (0, 0, 0))
    ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py", line 216, in _verifier_cas
    impot_calcule, decote_calculee, reduction_calculee = calculer_impot_final(adultes, enfants, revenus)
                                                         ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py", line 187, in calculer_impot_final
    decote, impot_apres_decote = calculer_decote(impot_apres_plafonnement, adultes)
                                 ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py", line 134, in calculer_decote
    decote = seuil_decote - (impot_avant_decote * COFFICIENT_DECOTE)
                                                  ^^^^^^^^^^^^^^^^^
NameError: name 'COFFICIENT_DECOTE' is not defined. Did you mean: 'COEFFICIENT_DECOTE'?



Ran 11 tests in 0.038s

FAILED (failures=1, errors=2)

Process finished with exit code 1
  • 11. satırda bir test başarısız oldu;
  • 25. ve 42. satırlar: aynı derleme hatası;

Bu günlükleri bir metin dosyasına kaydedip Gemini'ye veriyoruz:

 

Gemini'nin yanıtı:

 
 

PyCharm dosyasına komut dosyasını yükleyip çalıştırıyoruz. Yine hatalar çıkıyor. Çalıştırma günlüklerini tekrar ekleyerek bunu Gemini’ye bildiriyoruz:

 

Gemini'nin yanıtı:

 
 
 

Bu yeni komut dosyasını PyCharm'e yükleyip çalıştırıyoruz. Bu sefer 11 birim testi de başarılı oluyor:

Gemini tarafından üretilen kod şöyledir:

# -*- coding: utf-8 -*-
import math
import unittest

# ==============================================================================
# CONSTANTES QZXW2HTMLCUE9VUgZQXQZXW2HTMLCSU1QT1NJVElPTgZQX DES REVENUS 2018 (PAYÉE EN 2019)
# ==============================================================================
BAREME_IMPOT_2019 = [
    {'seuil': 0, 'taux': 0.0},
    {'seuil': 9964, 'taux': 0.14},
    {'seuil': 27519, 'taux': 0.30},
    {'seuil': 73779, 'taux': 0.41},
    {'seuil': 156244, 'taux': 0.45},
]
ABATTEMENT_FORFAITAIRE_TAUX = 0.10
ABATTEMENT_FORFAITAIRE_MINIMUM = 437
ABATTEMENT_FORFAITAIRE_PLAFOND = 12502
PLAFONNEMENT_AVANTAGE_QF_DEMI_PART = 1551
SEUIL_DECOTE_CELIBATAIRE = 1196
SEUIL_DECOTE_COUPLE = 1970
COEFFICIENT_DECOTE = 0.75
TAUX_REDUCTION_20_POURCENT = 0.20
SEUIL_RFR_REDUCTION_CELIBATAIRE = 18985
SEUIL_RFR_REDUCTION_COUPLE = 37970
MAJORATION_RFR_REDUCTION_PAR_DEMI_PART = 3803


# ==============================================================================
# FONCTIONS DE CALCUL
# ==============================================================================

def calculer_nombre_parts(adultes: int, enfants: int) -> float:
    """Calcule le nombre de parts du foyer fiscal."""
    if adultes < 1: return 0
    parts = float(adultes)
    if enfants >= 1: parts += 0.5
    if enfants >= 2: parts += 0.5
    if enfants >= 3: parts += (enfants - 2) * 1.0
    return parts


def calculer_revenu_imposable(revenus_bruts: float) -> float:
    """Calcule le revenu net imposable après abattement de 10%."""
    if revenus_bruts == 0: return 0.0
    abattement = revenus_bruts * ABATTEMENT_FORFAITAIRE_TAUX
    if abattement < ABATTEMENT_FORFAITAIRE_MINIMUM: abattement = ABATTEMENT_FORFAITAIRE_MINIMUM
    if abattement > ABATTEMENT_FORFAITAIRE_PLAFOND: abattement = ABATTEMENT_FORFAITAIRE_PLAFOND
    abattement = math.ceil(abattement)
    revenu_imposable = revenus_bruts - abattement
    return revenu_imposable if revenu_imposable > 0 else 0


def calculer_impot_brut_par_tranche(revenu_imposable: float, nombre_parts: float) -> float:
    """Calcule l'impôt brut en appliquant le barème progressif."""
    if nombre_parts <= 0 or revenu_imposable <= 0: return 0.0
    quotient_familial = revenu_imposable / nombre_parts
    impot_par_part = 0.0
    for i in range(len(BAREME_IMPOT_2019)):
        tranche = BAREME_IMPOT_2019[i]
        seuil_actuel = tranche['seuil']
        taux = tranche['taux']
        if quotient_familial > seuil_actuel:
            base_imposable_tranche = 0
            if i < len(BAREME_IMPOT_2019) - 1:
                seuil_suivant = BAREME_IMPOT_2019[i + 1]['seuil']
                base_imposable_tranche = min(quotient_familial, seuil_suivant) - seuil_actuel
            else:
                base_imposable_tranche = quotient_familial - seuil_actuel
            impot_par_part += base_imposable_tranche * taux
    return impot_par_part * nombre_parts


def appliquer_plafonnement_qf(revenu_imposable: float, nombre_parts: float, adultes: int,
                              impot_brut_famille: float) -> float:
    """Applique le plafonnement des effets du quotient familial."""
    if nombre_parts <= adultes: return impot_brut_famille
    impot_base = calculer_impot_brut_par_tranche(revenu_imposable, float(adultes))
    demi_parts_enfants = (nombre_parts - adultes) * 2
    avantage_qf_max = PLAFONNEMENT_AVANTAGE_QF_DEMI_PART * demi_parts_enfants
    avantage_qf_reel = impot_base - impot_brut_famille
    if avantage_qf_reel > avantage_qf_max:
        return impot_base - avantage_qf_max
    return impot_brut_famille


def calculer_impot_final(adultes: int, enfants: int, revenus: float) -> (int, int, int):
    """Orchestre le calcul complet de l'impôt."""
    revenu_imposable = calculer_revenu_imposable(revenus)
    nombre_parts = calculer_nombre_parts(adultes, enfants)
    impot_brut = calculer_impot_brut_par_tranche(revenu_imposable, nombre_parts)
    impot_apres_plafonnement = appliquer_plafonnement_qf(revenu_imposable, nombre_parts, adultes, impot_brut)

     # CORRECTION : Vergi zaten 0 ise, indirim veya iskonto uygulanmaz.
    if impot_apres_plafonnement == 0:
        return 0, 0, 0

     # --- LOGIQUE CORRIGÉE POUR L'INTERACTION DÉCOTE / RÉDUCTION ---
    decote_calculee = 0.0
    reduction_calculee = 0.0
    impot_a_traiter = impot_apres_plafonnement

     # 1. %20 indirimden yararlanma hakkının belirlenmesi
    est_eligible_reduction = False
    if adultes >= 2:
        seuil_rfr = SEUIL_RFR_REDUCTION_COUPLE + max(0, (nombre_parts - 2) * 2) * MAJORATION_RFR_REDUCTION_PAR_DEMI_PART
    else:
        seuil_rfr = SEUIL_RFR_REDUCTION_CELIBATAIRE + max(0, (
                nombre_parts - 1) * 2) * MAJORATION_RFR_REDUCTION_PAR_DEMI_PART
    if revenu_imposable < seuil_rfr:
        est_eligible_reduction = True

     # 2. İndirimden yararlanma hakkının belirlenmesi
    seuil_decote_foyer = SEUIL_DECOTE_COUPLE if adultes >= 2 else SEUIL_DECOTE_CELIBATAIRE
    reduction_theorique = math.ceil(impot_a_traiter * TAUX_REDUCTION_20_POURCENT) if est_eligible_reduction else 0

    if (impot_a_traiter - reduction_theorique) < seuil_decote_foyer:
        decote_calculee = seuil_decote_foyer - (impot_a_traiter * COEFFICIENT_DECOTE)
        decote_calculee = math.ceil(decote_calculee)
         # CORRECTION : İade edilen indirim, iptal ettiği vergi tutarını aşamaz
        decote_calculee = min(decote_calculee, math.ceil(impot_a_traiter))
        impot_a_traiter -= decote_calculee
        impot_a_traiter = max(0.0, impot_a_traiter)

     # 3. Uygunluk varsa %20 indirimi uygulamak
    if est_eligible_reduction:
        reduction_calculee = math.ceil(impot_a_traiter * TAUX_REDUCTION_20_POURCENT)
        impot_a_traiter -= reduction_calculee
        impot_a_traiter = max(0.0, impot_a_traiter)

    impot_final = math.floor(impot_a_traiter)

    return impot_final, int(decote_calculee), int(reduction_calculee)


# ==============================================================================
# TESTS UNITAIRES
# ==============================================================================

class TestCalculImpot2019(unittest.TestCase):
    def _verifier_cas(self, adultes, enfants, revenus, attendu):
        impot_attendu, decote_attendue, reduction_attendue = attendu
        impot_calcule, decote_calculee, reduction_calculee = calculer_impot_final(adultes, enfants, revenus)
        self.assertAlmostEqual(impot_calcule, impot_attendu, delta=1, msg=f"Impôt ({impot_calcule} vs {impot_attendu})")
        self.assertAlmostEqual(decote_calculee, decote_attendue, delta=1,
                               msg=f"Décote ({decote_calculee} vs {decote_attendue})")
        self.assertAlmostEqual(reduction_calculee, reduction_attendue, delta=1,
                               msg=f"Réduction ({reduction_calculee} vs {reduction_attendue})")

    def test_cas_1(self): self._verifier_cas(2, 2, 55555, (2815, 0, 0))

    def test_cas_2(self): self._verifier_cas(2, 2, 50000, (1385, 384, 346))

    def test_cas_3(self): self._verifier_cas(2, 3, 50000, (0, 720, 0))

    def test_cas_4(self): self._verifier_cas(1, 2, 100000, (19884, 0, 0))

    def test_cas_5(self): self._verifier_cas(1, 3, 100000, (16782, 0, 0))

    def test_cas_6(self): self._verifier_cas(2, 3, 100000, (9200, 0, 0))

    def test_cas_7(self): self._verifier_cas(2, 5, 100000, (4230, 0, 0))

    def test_cas_8(self): self._verifier_cas(1, 0, 100000, (22986, 0, 0))

    def test_cas_9(self): self._verifier_cas(2, 2, 30000, (0, 0, 0))

    def test_cas_10(self): self._verifier_cas(1, 0, 200000, (64211, 0, 0))

    def test_cas_11(self): self._verifier_cas(2, 3, 200000, (42843, 0, 0))


if __name__ == '__main__':
    print("Lancement des tests unitaires pour le calcul de l'impôt 2019...")
    unittest.main(argv=['first-arg-is-ignored'], exit=False)

Yine bu kodu incelemedim. Sadece 11 testi başarıyla geçtiğini gördüm.

Ancak, özellikle vergi hesaplamasındaki özel durumlar için, Gemini’nin nasıl bir mantık izlediğini merak edebiliriz. Ona bunu soruyoruz:

 

Bu, hem %10'luk indirimin hem de aile katsayısının sınırlandırılma olasılığı bulunan yüksek gelirli bir durumdur.

Gemini’nin cevabı şu şekildedir:

 
 
 
 
 

Bu son iki ekran görüntüsü ilginçtir. Gemini, PDF'te açıklanan hesaplama yönteminden farklı bir yöntem kullanmaktadır. Bu hesaplama yöntemi internette de bulunabilir. Her iki yöntem de eşdeğerdir.

 
 
 

Açıklama, netliğiyle dikkat çekiyor. Vergi hesaplama yöntemini açıklamak için öğrencilere olduğu gibi verilebilir.

Şimdi, bu sefer düşük gelirli bir örnek ele alalım. Bu durumda, indirim ve muafiyet söz konusu olabilir:

 

Gemini’nin cevabı şöyledir:

 
 
 
 
 

Burada, Gemini'nin PDF'te bulunmayan bir kural uyguladığı görülüyor. Muhtemelen bunu internetten bulmuştur, ancak kaynak güvenilir mi?

 

Burada Gemini, bilinmeyen bir kuralı (yukarıdaki özel kural) uygulamaya devam ediyor.

 
 
 

Dolayısıyla Gemini'nin sonuçları, resmi vergi simülatörünün sonuçlarıyla örtüşüyor. Ancak PDF'te bulunmayan bir kural kullanmış. Hata nerede? PDF dosyasını ekleyerek ona şu soruyu soruyoruz:

 

Gemini’nin cevabı:

 
 
 
 

Bence Gemini haklı ve benim PDF değerim hatalı. Bunu doğrulamak için ondan bir test yapmasını istiyorum:

  • Bu testte, onun mantığı resmi vergi simülatörüyle aynı sonuçları vermelidir;
  • PDF'in mantığı ise simülatörden farklı sonuçlar verecektir;
 

Gemini'nin cevabı şöyledir:

 

Burada Gemini yanılıyor. Bu örnek üzerinde simülatörü çalıştırdım ve şu sonucu elde ettim:

 

Ancak, Gemini'nin mantığının yukarıdaki sonuçları doğru bir şekilde verdiğini göreceğiz. Devam edelim:

 
 
 
 

Pekala. Not edildi. Devam edelim:

 
 
 
 

Yani Gemini (vergi, indirim, iskonto) = (431, 325, 1296) sonucunu bulurken, benim kullandığım simülatör (431, 324, 1297) sonucunu veriyor. Yani Gemini, 1 euro farkla doğru sonuçları bulmuş ama bunun farkında değil. Ona şunu söylüyoruz:

 

Gemini şöyle yanıtlıyor:

 
 

Şimdi merak ediyoruz, Gemini düzeltilmiş bir PDF üretebilir mi:

 

Gemini'nin yanıtı:

 

Yani Gemini bana bir PDF bağlantısı vermedi, ancak bu PDF'i kendim oluşturabilmem için bir metin üretti. Burada PDF'in ekran görüntülerini paylaşmak biraz zahmetli olsa da, okuyucunun IA'in üretken yönünü görebilmesi için bunu yapıyorum:

 

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Dürüst olmak gerekirse, bu PDF belgesinde yazılanların doğru olup olmadığını kontrol etmedim. Her halükarda, bu belge bir TD için mükemmel ve birkaç saniye içinde oluşturulmuş.

Yine de, Gemini’nin kendi PDF’inin doğru olup olmadığını Gemini’ye sormalıyız. Yeni bir sohbet başlatıyoruz:

 
  • [1]'te, Gemini tarafından oluşturulan PDF'i ekledik; [Le problème selon Gemini.pdf];
  • [2]'te, [instructionsAvecPDF2.txt], [instructionsAvecPDF.txt]'teki talimatlarla aynıdır; tek fark, on ikinci bir birim testi eklenmiş olmasıdır; bu test, ilk PDF'in hatalı olduğunu ortaya çıkarmıştır:
test12 : (2, 2, 49500) -> (1297, 431, 324)

Garip bir şekilde, Gemini'nin doğru komut dosyasını oluşturması için birkaç kez deneme yapmak gerekti:

Soru 2

 

Soru 3

 

Artık birkaç kez yapıldığı gibi, oluşturulan ve PyCharm'e yüklenen komut dosyası başarısız olduğunda, Gemini'ye yürütme günlüklerinin metin dosyasını veriyoruz. Gemini bunları çok iyi anlıyor.

Soru 4

 

Soru 5

 

Soru 6 ve son

Artık Gemini tarafından oluşturulan PDF'in geçerliliğinden emin olduk. Burada verilen hesaplama kuralları doğrudur.

Şimdi diğer beş IA dosyası için de aynısını yapacağız, ancak açıklamalarımızı oldukça kısa tutacağız; şu anda lider konumda olan ChatGPT ve IA hariç. Bizi ilgilendiren, IA’in kendisine sorulan üç sorunu çözüp çözemediğidir. Nitekim, tüm bu IA’lerin arayüzleri birbirine çok benziyor ve ben bunlarla da Gemini’de yaptığım gibi işlem yaptım. Okuyucunun, kendi seçtiği IA ile Gemini diyaloglarını yeniden canlandırması önerilir.