Sayıların okunuşu 2

Daha önce sayılarıın okunuşunu veren programı geliştirmemde yardımcı olmuştunuz.Şimdi de tam tersini veren programı yapmayı denedim 1 milyona kadar sorunu hallettiğimi düşünüyorum.
İncelermisiniz devamı nasıl getirilebilir nasıl geliştirilebilir?
Sorunlarımdan biri sayılar arasında boşluk kullanmak zorunda kaldım(bunu belki biraz düşününce düzeltebilirim)
Yani Şöyle bir girdi vermek zorundayım (“iki yüz yirmi üç bin dört yüz altı”)
İkinci sorunum 1 milyona kadar kısıtlı olması

def foo(yazılış:str):
    sözlük={"bir":"1*","iki":"2*","üç":"3*","dört":"4*","beş":"5*","altı":"6*","yedi":"7*","sekiz":"8*","dokuz":"9*",
            "on":"10+","yirmi":"20+","otuz":"30+","kırk":"40+","elli":"50+","altmış":"60+","yetmiş":"70+","seksen":"80+","doksan":"90+","yüz":"100+","bin":"1000+"}
    liste=[]
    basamaklar=yazılış.split('bin')
    for j in basamaklar:

        sayı=''
        kullan=j.split()

        for i in kullan:
            if i in sözlük:
                sayı +=sözlük[i]
        if sayı!='':
            sayı=sayı.rstrip('*')
        if '+' in sayı:
            sayı=sayı.rstrip('+')
        liste.append(sayı)


    if liste[0]=='' and liste[1]=='':
        return 1000
    elif liste[0]=='':
        liste[0]='1'
    if len(liste)>1 and len(liste[0]) >0 and liste[1]=='':
        liste[1]='000'


    sonuç=[eval(i) for i in liste]


    if len(sonuç)>1 and len(str(sonuç[1]))==1:
        sonuç[1]='00'+str(sonuç[1])
    if len(sonuç)>1 and len(str(sonuç[1]))==2:
        sonuç[1]='0'+str(sonuç[1])
    istenen=''
    for i in sonuç:
        istenen+=str(i)
    return int(istenen)




print(foo('dokuz')==9)
print(foo('yüz dört bin dört')==104004)
print(foo('iki yüz doksan altı')==296)
print(foo( 'bin kırk iki')==1042)
print(foo('on iki bin iki yüz')==12200)
print(foo('kırk yedi')==47)
print(foo('yüz sekiz')==108)

Pek ilgi çekmedi neden anlayamadım kimseden cevap gelmedi :slight_smile:

Merhaba şöyle bir katkıda bulunayım, siz de bir incelersiniz belki hata olabilir mi diye

sözlük={"bir":"1*","iki":"2*","üç":"3*","dört":"4*","beş":"5*","altı":"6*","yedi":"7*","sekiz":"8*","dokuz":"9*",
            "on":"10+","yirmi":"20+","otuz":"30+","kırk":"40+","elli":"50+","altmış":"60+","yetmiş":"70+","seksen":"80+","doksan":"90+","yüz":"100+","bin":"1000+"}

def foo(yazılış:str):
    liste=[]
    basamaklar=yazılış.split('bin')
    for j in basamaklar:

        sayı=''
        kullan=j.split()

        for i in kullan:
            if i in sözlük:
                sayı +=sözlük[i]
        if sayı!='':
            sayı=sayı.rstrip('*')
        if '+' in sayı:
            sayı=sayı.rstrip('+')
        liste.append(sayı)


    if liste[0]=='' and liste[1]=='':
        return 1000
    elif liste[0]=='':
        liste[0]='1'
    if len(liste)>1 and len(liste[0]) >0 and liste[1]=='':
        liste[1]='000'


    sonuç=[eval(i) for i in liste]


    if len(sonuç)>1 and len(str(sonuç[1]))==1:
        sonuç[1]='00'+str(sonuç[1])
    if len(sonuç)>1 and len(str(sonuç[1]))==2:
        sonuç[1]='0'+str(sonuç[1])
    istenen=''
    for i in sonuç:
        istenen+=str(i)
    return int(istenen)

keys=sözlük.keys()
def ayrıştır(str):
    for j in keys:
        if j in str:
            str=str.replace(j," "+j)
    return str.lstrip()

print(foo(ayrıştır('ikiyüzikibiniki'))==202002)


1 Beğeni

Teşekkürler güzel yaklaşım böylelikle sorunlardan biri halledildi :slight_smile:

1 Beğeni

Hala yakalanıp kullanıcıya anlamlı bir şekilde ulaştırılması gereken hatalar (bug değil, exception) var ama düzgün parametreler ile birlikte doğru çalışıyor gibi:

digit = dict((j, i) for i, j in enumerate(('bir', 'iki', 'üç', 'dört', 'beş', 'altı', 'yedi', 'sekiz', 'dokuz'), 1))
digit2 = dict((j, i*10) for i, j in enumerate(('on', 'yirmi', 'otuz', 'kırk', 'elli', 'altmış', 'yetmiş', 'seksen', 'doksan'), 1))
digit3 = dict((j, 1000**i) for i, j in enumerate(('milyon', 'milyar', 'trilyon', 'katrilyon', 'kentilyon', 'sekstilyon', 'septilyon', 'oktilyon', 'nonilyon', 'desilyon', 'andesilyon', 'dodesilyon', 'tredesilyon', 'katordesilyon', 'kendesilyon', 'seksdesilyon', 'septendesilyon', 'oktodesilyon', 'novemdesilyon', 'vicintilyon', 'anvicintilyon', 'dovicintilyon', 'trevicintilyon', 'katorvicintilyon', 'kenkavicintilyon', 'sesvicintilyon', 'septemvicintilyon', 'oktovicintilyon', 'novemvicintilyon', 'tricintilyon', 'antricintilyon'), 2))

class ParserError(ValueError): pass

class Parser:

    def __init__(self, iterable):
        self.tokens = tuple(reversed(tuple(iterable)))
        self.index = 0

    def next(self):
        try:
            return self.tokens[self.index]
        except IndexError:
            return ""
        finally:
            self.index += 1

    def peek(self):
        try:
            return self.tokens[self.index]
        except IndexError:
            return ''

    def peek_next(self):
        try:
            return self.tokens[self.index+1]
        except IndexError:
            return ""
        
    def match(self, s):
        if self.peek() == s:
            self.next()
            return True
        return False

    def error(self, msg):
        index = len(self.tokens) - self.index -1
        err = ParserError("Wrong syntax at index {}: {}".format(index, msg))
        err._index = index
        raise err

    def onluk(self):
        result = 0
        if self.peek() in digit:
            result += digit[self.next()]
        if self.peek() in digit2:
            result += digit2[self.next()]
        return result

    def yüzlük(self):
        result = 0
        onluk = self.onluk()
        if self.match("yüz"):
            result = 100
            if self.peek() in digit:
                result *= digit[self.next()]
        return result + onluk

    def binlik(self):
        result = 0
        yüzlük = self.yüzlük()
        if self.match("bin"):
            result = 1000
            tmp = self.yüzlük()
            if tmp != 0:
                result *= tmp
        return result + yüzlük

    def parse(self):
        if self.match("sıfır"):
            if not self.match(""):
                self.error("Not expected 'sıfır' after '{}'.".format(self.next()))
            return 0

        result = self.binlik()

        last_tmp = 0
        while self.peek() != "":
            if self.peek() in digit3:
                current_digit3 = self.next()
                tmp = digit3[current_digit3]
                if tmp <= last_tmp:
                    self.error("Digit3 values must be in a sorted order.")
                last_tmp = tmp
            else:
                self.error("Expected a digit3.")

            yüzlük = self.yüzlük()
            if yüzlük == 0:
                self.error("Expected a proper prefix before '{}'.".format(current_digit3))
            result += tmp * yüzlük

        return result
        

def solution(s: str):
    return Parser(filter(None, s.split())).parse()

assert solution("sıfır") == 0
assert solution("iki") == 2
assert solution("yirmi yedi") == 27
assert solution("yüz üç") == 103
assert solution("iki yüz otuz altı") == 236
assert solution("bin altı yüz") == 1600
assert solution("üç milyon yüz altmış iki bin bir") == 3162001
assert solution("sekiz trilyon") == 8_000_000_000_000

Yazıyı sağdan sola parçalamak birkaç tekrar eden if’den kurtulmamızı sağlıyor.

Zaten öyle olması gerekmiyor mu?

1 Beğeni

Yazım kurallarına baktım normalde öyleymiş ama bankacılık gibi para ile ilgili işlerde bitişik yazılırmış :slight_smile:
Elinize emeğinize sağlık şimdi yazdığınız kodu inceleyeceğim

Sorununuzu çözecek bir program yapmaya başladım.Bir modül haline getirip kullanıma sunacağım.

2 Beğeni