Kafayı yemek üzereydim. Otomasyon botum, dış bir API'den gelen verileri düzgün bir şekilde float'a çeviremiyordu. Her şey normal sayılarda tıkır tıkır işliyordu da, iş "1.23E-4", "5.6e+3" gibi değerlere gelince parser'ım sessiz sedasız ValueError fırlatıp duruyordu. "Bu kadar basit bir şeyi nasıl kaçırmışım?" diye kendimi yiyordum.
Hatayı Bulma Çabası
İlk başta, gelen veride gizli boşluklar, yeni satırlar (\n) veya tuhaf karakterler var sanıp saatlerimi .strip(), .replace() kombinasyonlarıyla harcadım. Loglara baktım, veri aynen şu şekilde geliyordu:
Kodumda da direkt float("1E-5") yazıp denedim, çalıştı! "O zaman sorun nerde?!" diye StackOverflow'da bile aradım, meğerse benim aptal parser'ım öyle bir şey yapıyordu ki...
Meğerse Sorun Şuradaymış
Ben, güvenlik manyağı gibi davranıp, gelen string'i float'a çevirmeden önce kendi yazdığım bir "sayı doğrulama" regex'inden geçiriyordum. Amacım sadece nokta ve rakamlardan oluşan sayıları kabul etmekti. Şaka gibi ama, regex'im şöyle bir şeydi:
Gördünüz mü? Bu desen, E veya e harfini kesinlikle kabul etmiyor! Yani "1E-5" geldiğinde, "bu geçerli bir sayı değil" deyip float çevrimini hiç denemeden hata atıyordum. Sorun float() fonksiyonunda değil, benim aşırı korumacı ve bilimsel gösterimi unutmuş kodumdaydı.
Çözüm ve Alınan Ders
Çözüm basitti: Ya regex'i düzelt, ya da direkt float() dönüşümünün try/except içinde kalmasına güven. Ben ikincisini tercih ettim. Kodu şöyle düzelttim:
Python'un kendi float parser'ı, bilimsel gösterimi zaten destekliyormuş. Gereksiz yere tekerleği yeniden icat etmeye çalışıp, kendi ayağıma sıktım. Ders: Standart kütüphaneler çoğu zaman senden daha akıllıdır, önce onlara güvenmeyi dene!
Siz de benzer bir "fazla zekalık" yapıp, basit bir şeyi kompleks hale getirdiğiniz oldu mu? Ya da bilimsel gösterimli sayıları parse ederken daha farklı/iyi bir yönteminiz var mı?
İlk başta, gelen veride gizli boşluklar, yeni satırlar (\n) veya tuhaf karakterler var sanıp saatlerimi .strip(), .replace() kombinasyonlarıyla harcadım. Loglara baktım, veri aynen şu şekilde geliyordu:
Python:
"concentration": "1E-5"
Ben, güvenlik manyağı gibi davranıp, gelen string'i float'a çevirmeden önce kendi yazdığım bir "sayı doğrulama" regex'inden geçiriyordum. Amacım sadece nokta ve rakamlardan oluşan sayıları kabul etmekti. Şaka gibi ama, regex'im şöyle bir şeydi:
Python:
import re
def is_valid_number(string):
return bool(re.match(r'^[0-9]+(\.[0-9]+)?$', string))
Çözüm basitti: Ya regex'i düzelt, ya da direkt float() dönüşümünün try/except içinde kalmasına güven. Ben ikincisini tercih ettim. Kodu şöyle düzelttim:
Python:
try:
numeric_value = float(incoming_string)
except ValueError:
# Burada artık loglayıp, varsayılan bir değer atayabilirsin.
numeric_value = 0.0
Siz de benzer bir "fazla zekalık" yapıp, basit bir şeyi kompleks hale getirdiğiniz oldu mu? Ya da bilimsel gösterimli sayıları parse ederken daha farklı/iyi bir yönteminiz var mı?