Skip to content

Commit

Permalink
🐛 fix bug when float is 'round' 1.0 2.0 ...
Browse files Browse the repository at this point in the history
  • Loading branch information
Rezenders committed Apr 26, 2024
1 parent b52b739 commit 68fa371
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 58 deletions.
20 changes: 13 additions & 7 deletions ros_typedb/ros_typedb/ros_typedb_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

from ros_typedb.typedb_interface import MatchResultDict
from ros_typedb.typedb_interface import TypeDBInterface
from ros_typedb.typedb_interface import convert_query_type_to_py_type
from ros_typedb_msgs.msg import Attribute
from ros_typedb_msgs.msg import QueryResult
from ros_typedb_msgs.srv import Query
Expand All @@ -50,20 +51,25 @@ def set_query_result_value(
_type_dict = {
'boolean': (1, 'bool_value'),
'bool': (1, 'bool_value'),
'long': (2, 'integer_value'),
'int': (2, 'integer_value'),
'double': (3, 'double_value'),
'float': (3, 'double_value'),
'string': (4, 'string_value'),
'str': (4, 'string_value'),
'datetime': (4, 'string_value'),
'long': (2, 'integer_value', 'long'),
'int': (2, 'integer_value', 'long'),
'double': (3, 'double_value', 'double'),
'float': (3, 'double_value', 'double'),
'string': (4, 'string_value', 'string'),
'str': (4, 'string_value', 'string'),
'datetime': (4, 'string_value', 'string'),
'boolean_array': (6, 'bool_array_value'),
'long_array': (7, 'integer_array_value'),
'double_array': (8, 'double_array_value'),
'string_array': (9, 'string_array_value'),
}
if value_type in _type_dict:
_param_value.type = _type_dict[value_type][0]
try:
value = convert_query_type_to_py_type(
value=value, value_type=_type_dict[value_type][2])
except IndexError:
pass
setattr(
_param_value,
_type_dict[value_type][1],
Expand Down
106 changes: 57 additions & 49 deletions ros_typedb/ros_typedb/typedb_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,54 @@
from typing import TypedDict


def convert_query_type_to_py_type(
value_dict: Optional[dict] = None,
value: Optional[str] = None,
value_type: Optional[str] = None) -> datetime | int | str | float:
"""
Convert typedb 'value_type' to python type.
:param value: Data to be converted.
:param value_type: Data to be converted.
:param value_dict: Typedb value dict to be converted, overrides value and
value_type.
:return: Converted data.
"""
if value_dict is not None:
value_type = value_dict.get('type').get('value_type')
value = value_dict.get('value')
if value_type == 'datetime':
return datetime.fromisoformat(value)
elif value_type == 'long':
return int(value)
elif value_type == 'string':
return str(value)
elif value_type == 'double':
return float(value)
return value


def convert_py_type_to_query_type(
data: datetime | str | bool) -> str:
"""
Convert python type to string.
Convert python type to a properly formatted string to be used with
a typedb query.
:param data: Data to be converted.
:return: Converted data.
"""
if isinstance(data, str):
if len(data) > 0 and data[0] != '$':
return "'{}'".format(data)
elif isinstance(data, datetime):
return data.isoformat(timespec='milliseconds')
elif isinstance(data, bool):
return str(data).lower()
return data


def string_to_string_array(string: str) -> list[str]:
"""
Convert string to string array.
Expand Down Expand Up @@ -407,46 +455,6 @@ def get_aggregate_database(self, query: str) -> int | float | None:
return result
# Read/write database end

def convert_query_type_to_py_type(
self, data: str) -> datetime | int | str | float:
"""
Convert typedb 'value_type' to python type.
:param data: Data to be converted.
:return: Converted data.
"""
_value_type = data.get('type').get('value_type')
_value = data.get('value')
if _value_type == 'datetime':
return datetime.fromisoformat(_value)
elif _value_type == 'long':
return int(_value)
elif _value_type == 'string':
return str(_value)
elif _value_type == 'double':
return float(_value)
return _value

def convert_py_type_to_query_type(
self, data: datetime | str | bool) -> str:
"""
Convert python type to string.
Convert python type to a properly formatted string to be used with
a typedb query.
:param data: Data to be converted.
:return: Converted data.
"""
if isinstance(data, str):
if len(data) > 0 and data[0] != '$':
return "'{}'".format(data)
elif isinstance(data, datetime):
return data.isoformat(timespec='milliseconds')
elif isinstance(data, bool):
return str(data).lower()
return data

def attribute_dict_to_query(
self,
attribute_dict: dict[str, str | int | float | bool | datetime]
Expand Down Expand Up @@ -492,7 +500,7 @@ def attribute_dict_to_query(
_query += ','
_query += ' has {0} {1}'.format(
attr,
self.convert_py_type_to_query_type(v)
convert_py_type_to_query_type(v)
)
first = False
return _query
Expand Down Expand Up @@ -741,7 +749,7 @@ def create_match_query(
match_query += " ${0}_{1} isa {2},".format(
prefix, t_counter, thing[0])
match_query += " has {0} {1};".format(
thing[1], self.convert_py_type_to_query_type(thing[2]))
thing[1], convert_py_type_to_query_type(thing[2]))
prefix_list.append("{0}_{1}".format(prefix, t_counter))
t_counter += 1
return match_query, prefix_list
Expand Down Expand Up @@ -802,7 +810,7 @@ def create_relationship_query(
if attribute[0] is not None:
query += ", has {} {} ".format(
attribute[0],
self.convert_py_type_to_query_type(attribute[1])
convert_py_type_to_query_type(attribute[1])
)
query += ";"
return query
Expand Down Expand Up @@ -845,7 +853,7 @@ def insert_entity(
"""
for attribute in attribute_list:
if attribute[0] is not None:
value = self.convert_py_type_to_query_type(attribute[1])
value = convert_py_type_to_query_type(attribute[1])
query += f""", has {attribute[0]} {value} """
query += ";"
return self.insert_database(query)
Expand Down Expand Up @@ -936,7 +944,7 @@ def fetch_attribute_from_thing_raw(
match $thing isa {thing}
"""
for (key, value) in key_attr_list:
value = self.convert_py_type_to_query_type(value)
value = convert_py_type_to_query_type(value)
query += f""", has {key} {value} """
query += f"""
, has {attr} $attribute;
Expand All @@ -960,7 +968,7 @@ def fetch_attribute_from_thing(
"""
result = self.fetch_attribute_from_thing_raw(
thing, key_attr_list, attr)
return [self.convert_query_type_to_py_type(r.get('attribute'))
return [convert_query_type_to_py_type(value_dict=r.get('attribute'))
for r in result]

def delete_attribute_from_thing(
Expand All @@ -978,7 +986,7 @@ def delete_attribute_from_thing(
:param attr: attribute name to be deleted
:return: True.
"""
key_value = self.convert_py_type_to_query_type(key_value)
key_value = convert_py_type_to_query_type(key_value)
query = f"""
match $thing isa {thing},
has {key} {key_value},
Expand Down Expand Up @@ -1051,8 +1059,8 @@ def insert_attribute_in_thing(
:param attr_value: attribute value to be inserted
:return: Insert query result.
"""
key_value = self.convert_py_type_to_query_type(key_value)
attr_value = self.convert_py_type_to_query_type(attr_value)
key_value = convert_py_type_to_query_type(key_value)
attr_value = convert_py_type_to_query_type(attr_value)
query = f"""
match $thing isa {thing},
has {key} {key_value};
Expand Down
4 changes: 2 additions & 2 deletions ros_typedb/test/test_ros_typedb_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def insert_query():
has email "[email protected]",
has nickname "test",
has age 33,
has height 1.75,
has height 1.00,
has alive true,
has birth-date 1990-06-01;
$person2 isa person,
Expand Down Expand Up @@ -250,7 +250,7 @@ def test_ros_typedb_fetch_query_attribute(insert_query):
r.value.integer_value == 33:
correct_age = True
if r.name == 'height' and r.label == 'height' and \
r.value.double_value == 1.75:
r.value.double_value == 1.0:
correct_height = True
if r.name == 'alive' and r.label == 'alive' and \
r.value.bool_value is True:
Expand Down

0 comments on commit 68fa371

Please sign in to comment.