2017-12-08 2 views
0

Ich schreibe Python-Code, der einen REST-Endpunkt testet wissenschaftliche Zahlen aus einem DB und validieren, dass das wissenschaftliche Format von der Datenbank im richtigen JSON wissenschaftlichen Zahlenformat zurückgegeben wird.Wissenschaftliche Notation und Konvertierungen von DB-Ausgabe in JSON in Python

Das Problem, das ich habe, ist, dass einige wissenschaftliche Zahlen konvertiert werden. Zum Beispiel konvertiert der JSON-Lader das e in Großbuchstaben und einige Werte werden in Ganzzahlen umgewandelt. Hier ist ein Beispielcode. Der Code tut nicht genau das, was ich mache, da Sie das DB-Backend nicht haben werden.

import json 
import decimal 

class DecimalEncoder(json.JSONEncoder): 
    def default(self, o): 
    if isinstance(o, decimal.Decimal): 
     print 'In here: ' + str(o) 
     return str(o) 
    return super(DecimalEncoder, self).default(o) 

class JSONUtils: 
    def __init__(self, response): 
     self.response = response 
     self.jsonData = None 
     self.LoadData() 

    # print 'jsonData: ' + json.dumps(self.jsonData, cls=DecimalEncoder, indent=2) 

    def GetData(self): 
     return self.jsonData   

    def GetAsStr(self): 
     return json.dumps(self.GetData(), cls=DecimalEncoder) 

    def LoadData (self): 
     if (self.jsonData == None): 
      if (type(self.response) == str or type(self.response) == unicode): 
       print '****type1' 
       self.jsonData = json.loads(self.response, parse_float=decimal.Decimal) 
      elif (type(self.response) == dict): 
       print '****type2' 
       dump = json.dumps(self.response, cls=DecimalEncoder) 
       self.jsonData = json.loads(dump, parse_float=decimal.Decimal) 

    def GetJSONChunk(self, path): 
     returnValue = '' 
     curPath  = '' 
     try: 
      if (type(path) == str): 
       returnValue = self.jsonData[path] 
      elif (type(path) == list): 
       temp = '' 
       firstTime = True 
       for curPath in path: 
        if firstTime == True: 
         temp = self.jsonData[curPath] 
         firstTime = False 
        else: 
         temp = temp[curPath] 
       returnValue = temp 
      else: 
       print 'Unknown type in GetJSONChunk: ' + unicode(type(path)) 
     except KeyError as err: 
      ti.DBG_OUT('JSON chunk doesn\'t have value: ' + unicode(path)) 
      returnValue = self.kNoNode 
     except IndexError as err: 
      ti.DBG_OUT('Index does not exist: ' + unicode(curPath)) 
      returnValue = self.kInvalidIndex 

     return returnValue 

info = { "fldName":1.47e-10 } # converts to 1.47e-10 (e to E) 
# info = { "fldName":1.47e10 } # convers to 14700000000.0 
# info = { "fldName":1.47e+10 } # convers to 14700000000.0 
# info = { "fldName":1.47E+10 } # convers to 14700000000.0 
# info = { "fldName":123456789} # example shows larger # support 
print 'info: ' + str (info) 
myJSON = JSONUtils(info) 
print 'type: ' + str(myJSON.jsonData) 
print 'myJSON: ' + myJSON.GetAsStr() 
value = myJSON.GetJSONChunk ('fldName') 
print 'Type: ' + str(type(value)) 
print value 

Was ich tun muss, ist das DB-Ergebnis mit einem erwarteten Wert zu vergleichen. Gibt es eine Möglichkeit, NUR wissenschaftliche Zahlen zu identifizieren? NOT doubles/decimal values ​​und gibt diese als Strings zurück. Wie Sie sehen können, versuche ich bereits, Doubles zu schützen, die zurückgegeben werden, um sicherzustellen, dass sie die Kriterien/Fähigkeiten der Backend-Datenbank erfüllen. Das können 20 oder mehr Ziffern links oder rechts von der Dezimalstelle sein.

Die tatsächlichen Ergebnisse werden durch jede der Codezeilen dokumentiert, die mit # info beginnen.

Antwort

0

Ich bin nicht ganz klar auf Ihre Frage, also wenn dies weit weg von der Basis ist lass es mich wissen.

Ich denke, dass es einige Verwirrung zwischen wie Python eine Zahl gegenüber dem tatsächlichen Wert der Zahl sein kann.

Zum Beispiel kann ich die Zahl 1000 als schreiben:

>>> 1000 
1000.0 
>>> 1E3 
1000.0 
>>> 10E2 
1000.0 
>>> 1e3 
1000.0 
>>> 1e+3 
1000.0 

Das sind alles verschiedene Darstellungen der Zahl, aber sie sind alle numerisch äquivalent. JSON ist ähnlich flexibel; Alle obigen Darstellungen sind auch in JSON gültig.

In ähnlicher Weise kann ich schreiben:

10000000000000000000000000000.0 

Aber die print Anweisung wird angezeigt als:

1e+28 

Aber es ist immer noch die gleiche Zahl. Es wurde in keiner Weise "umgewandelt". Python verwendet die E-Notation, sobald Ihre Nummer >= 1E16 ist.

Also, wenn ich JSON erhalten, die wie folgt aussieht:

{ 
    "val1": 1e+3, 
    "val2": 1e+20 
} 

Die Ausgabe der folgenden Optionen:

values = json.loads('{"val1": 1e+3, "val2": 1e+20}') 
for k, v in values.items(): 
    print(k, '=', v) 

sein würde:

val1 = 1000.0 
val2 = 1e+20 
+0

Ich weiß, dass Sie Zahlen darstellen als Integer oder die gleiche Zahl in wissenschaftlicher Notation. Ich teste die wissenschaftlichen Werte aus der Datenbank und überprüfe sie auf ihre Richtigkeit. IOW: Stellt die Datenbank die Nummer/wissenschaftliche Nummer korrekt dar? Ich möchte nicht, dass die Werte trotzdem ausgegeben werden. Was passiert, ist, dass die Datenbank einen gültigen wissenschaftlichen Wert zurückgibt und die Ausführung des JSON-Ladevorgangs bewirkt, dass der Wert übersetzt wird. Ja ... zu einer gültigen wissenschaftlichen Darstellung, aber ich brauche den ursprünglichen Wert und nicht den Munged Value. Irgendwelche Ideen würden sehr geschätzt werden. – Keith

Verwandte Themen