Herkese Merhaba,
Bir süredir yazmaya çalıştığım kodu sonunda tamamlayabildim.
Yapmak istediğim şey;
Kullanıcı tarafından girilen Ondalıklı sayıyı, Kesirli hale dönüştüren program yazmaktı.
Örneğin kullanıcı 0.75 değerini girdiğinde program bu sayının karşılığı olan 3 / 4 çıktısını sunacak.
Hâlâ acemi bir kullanıcı olduğumu bilerek kodu yorumlar mısınız?
kodu geliştirme yönünde ne yapabilirim?
sağlıcakla kalın.
'''
Created on Fri Apr 16 21:10:17 2021
@author: Mustafa Halil ( https://github.com/mhalil _ https://twitter.com/AcikKaynakci )
Belirtilen Ondalıklı sayıyı, Kesirli hale dönüştüren program.
Örnek çıktılar;
0.75 sayısının kesirli gösterimi: 3 / 4
1.25 sayısının kesirli gösterimi: 5 / 4
'''
sayi = float(input("Kesirli halini görmek istediğiniz ondalıklı sayıyı yazın:"))
bol = str(sayi).split('.') # girilen sayıyı tamsayı ve ondalık kısma böl, liste halinde tut
ts = int(bol[0]) # sayının tamsayı kısmı
ond = int(bol[1]) # sayının ondalık kısmı
ond_uzn = len(str(ond)) # ondalık kısmın basamak sayısı
pay = int(str(ts) + str(ond)) # pay sayı değeri
pyd = 10 ** ond_uzn # payda sayı değeri
def carpan(sayi): # belirtilen sayı değerini çarpanlara ayırıp liste halinde geri döndüren fonksiyon.
lst = [1]
bolen = 2
for i in range(1,sayi):
if sayi % bolen == 0:
sayi /= bolen
lst.append(bolen)
else:
bolen += 1
return lst
def carp(liste): # belirtilen liste içerisindeki tüm değerleri çarpıp sunuç döndüren fonksiyon. (liste içerisi sadece sayıdan oluşmalı)
sonuc = 1
if liste == []:
sonuc = 1
else:
for i in liste:
sonuc *= i
return sonuc
pay_carpan = carpan(pay) # pay sayı değerini çarpanlarına ayır, listele
payda_carpan = carpan(pyd) # payda sayı değerini çarpanlarına ayır, listele
def sil(a, l1, l2): # 2 liste (l1 ve l2) içerisindeki ortak sayı değerini (a) silen fonksiyon.
if ((a in l1) and (a in l2)):
l1.remove(a)
l2.remove(a)
index = 0
while index <= len(pay_carpan): # index değeri, pay değerinin çarpanları sayısından küçük eşit olduğu sürece döngüyü çalıştır.
try:
a = pay_carpan[index] # pay'ın tek çarpanlar değeri
if a in payda_carpan: # eğer pay'ın çarpan değeri payda çarpan listesinde varsa ...
sil(a, pay_carpan, payda_carpan) # ortak çarpan değerini sil
else: # değilse
index +=1 # pay çarpan listesindeki sonraki sayıya geçmek için index değerini 1 artır.
except IndexError: # IndexError hatası alırsak ...
break # döngüyü sonlandır / bitir.
print(sayi, "sayısının kesirli gösterimi:", carp(pay_carpan),"/", carp(payda_carpan)) # pay çarpanlarındaki değerlerle, payda çarpanlarındaki değerleri (her iki listedeki ortak değerler silindikten sonra) kendi içerisinde çarp ve sonuç olarak ekrana yazdır.
Bütün çarpanları bulup işlem yapmanıza gerek yok, EBOB’u daha kolay hesaplayabilirsiniz:
def ebob(x, y):
while y:
r = x
x = y
y = r % y
return x
def çevir(tam, kesir):
payda = 10 ** len(kesir)
kesir = int(kesir)
bölen = ebob(kesir, payda)
payda //= bölen
kesir //= bölen
tam = int(tam) * payda
pay = kesir + tam
return f"{pay}/{payda}"
tam, kesir = input().split(".")
print(çevir(tam, kesir))
Standart kütüphane ile de işlem çok daha kolay bir şekilde yapılabilir:
from decimal import Decimal
print("{}/{}".format(*Decimal(input()).as_integer_ratio()))
zira eğer liste boşsa for hiç dönmez ve başta yazdığınız sonuc = 1’den dolayı fonksiyon yine 1 döndürür. Bir de if liste == [] yerine if not liste’yi tercih edebilirsiniz daha “pythonik” olsun diye, elinize sağlık
çok mantıklı,
yazdığınız kodları anlamam biraz vakit aldı ama anladım.
yazdığım kodlarda ebob’u oluşturan sayılarla tek tek uğraşmışım. resmen alememlik yapıyormuşum
çok teşekkür ederim, ufkum açıldı.
Kesirli halini görmek istediğiniz ondalıklı sayıyı yazın:0.001
0.001 sayısının kesirli gösterimi: 1 / 10
Kesirli halini görmek istediğiniz ondalıklı sayıyı yazın:.00005
Traceback (most recent call last):
File “a.py”, line 17, in
ts = int(bol[0]) # sayının tamsayı kısmı
ValueError: invalid literal for int() with base 10: ‘5e-05’
Kesirli halini görmek istediğiniz ondalıklı sayıyı yazın:.9999999999
Kesirli halini görmek istediğiniz ondalıklı sayıyı yazın:.99999999999999999999999999
1.0 sayısının kesirli gösterimi: 1 / 1
Kesirli halini görmek istediğiniz ondalıklı sayıyı yazın:1.1000000000001
Test case’leri ekleyebilirsin. Su halde kodda degisiklik yapmak cok zor, cunku her degisiklikten sonra 2-3 dakika test etmek gerekiyor (veya test etmeyip hatali kod uretiyoruz, yukaridaki orneklerdeki gibi)
Illa unittest kullanmana gerek yok, ufak programlarda alt alta assert’ler de isi goruyor:
Cevabınız için teşekkür ederim.
Bu kodu yazmama neden olan şey;
tweeter’da takip ettiğim bir kullanıcının sorduğu soruları çözmek için kod yazmak ve python pratiği yapmak idi.
Ancak python ile matematik sorularını çözen kod yazdığımda çıkan sonuçlar her zaman float oluyordu.
Şıklar kesirli sayılardan oluştuğu için direkt cevabı bulamıyordum, tek tek şıklardaki kesirli değerleri ondalıklı sayıya çevirmem gerekiyordu.
Yazdığım Kodlar hatalı ancak şimdilik doğru şıkkı bulabiliyorum
assetr ve test konularını araştıracağım, tektat teşekkürler.