Skip to content

Commit

Permalink
Add non_generic method to Feature.Set and is_applicable method to Fea…
Browse files Browse the repository at this point in the history
…ture.Aspect. Update Feature.Profile get method to call by aspect instead of aspect.alias and set default return values to feature set with not_applicable value.

PiperOrigin-RevId: 656374768
  • Loading branch information
isingoo authored and copybara-github committed Jul 26, 2024
1 parent c4b8c85 commit 2681f3e
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 6 deletions.
44 changes: 38 additions & 6 deletions nisaba/scripts/natural_translit/utils/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,13 @@ def has_feature(self, value: 'Feature.Aspect.VALUES'):
return True
return any(value in feature.parent_list for feature in self)

def non_generic(self, alias: str = '') -> 'Feature.Set':
"""Returns a copy of set without aspect.any and aspect.n_a features."""
return Feature.Set([
feature for feature in self
if feature != feature.aspect.any and feature != feature.aspect.n_a
], alias=(alias if alias else self.alias + '_non_generic'))

class ValueListType(enum.Enum):
EQUIDISTANT = 0
LINEAR = 1
Expand Down Expand Up @@ -368,8 +375,10 @@ def distance(
return Feature.ERROR_DISTANCE
delta = self._items.index(values2) - self._items.index(values1)
match self.list_type:
case Feature.ValueListType.EQUIDISTANT: return self.step
case Feature.ValueListType.LINEAR: return delta * self.step
case Feature.ValueListType.EQUIDISTANT:
return self.step
case Feature.ValueListType.LINEAR:
return delta * self.step
case Feature.ValueListType.CYCLIC:
return min(delta, len(self) - delta) * self.step
return Feature.ERROR_DISTANCE
Expand Down Expand Up @@ -591,6 +600,13 @@ def has_feature(self, value: 'VALUES') -> bool:
"""Checks if the given value or one of its children is in this aspect."""
return value.is_in(self)

def is_applicable(self, profile: 'Feature.Profile') -> bool:
"""Checks if this aspect is applicable to the given profile."""
return (
profile.inventory == self.inventory
and self.n_a not in profile.get(self)
)

class Inventory(inventory.Inventory):
"""An inventory of Aspects and their contrastive features.
Expand Down Expand Up @@ -683,7 +699,7 @@ def __init__(
alias: The alias of the feature profile.
*features: Features to be added to the profile.
unspecified_aspect_n_a: If true, the default value for an aspect is
n_a (not available) instead of any.
n_a (not_applicable) instead of any.
"""
super().__init__(alias)
self.inventory = feature_inventory
Expand All @@ -703,6 +719,22 @@ def __str__(self):
text += '}\n'
return text

def get(self, aspect: 'Feature.Aspect') -> 'Feature.Set':
"""Gets the value set for the given aspect."""
return super().get(
aspect.alias,
Feature.Set(
aspect.n_a,
alias='%s_%s'
% (
'missing'
if aspect.inventory == self.inventory
else aspect.inventory.alias,
aspect.alias,
),
),
)

def copy_and_update(
self, alias: str,
*updates: 'Feature.ITERABLE'
Expand Down Expand Up @@ -744,7 +776,7 @@ def copy_and_update(
new = Feature.Profile(self.inventory, alias, *self)
update_dict = Feature.Set.aspect_dict(*updates)
for aspect, value in update_dict.items():
new.get(aspect.alias).update(value)
new.get(aspect).update(value)
return new

def compare(
Expand Down Expand Up @@ -779,8 +811,8 @@ def compare(
headers = ['aspect', self.text, p.text, 'distance']
table = []
for aspect in aspects:
item1 = self.get(aspect.alias)
item2 = p.get(aspect.alias)
item1 = self.get(aspect)
item2 = p.get(aspect)
dist = item1.distance(item2)
total_dist += dist
max_dist += aspect.max_dist
Expand Down
17 changes: 17 additions & 0 deletions nisaba/scripts/natural_translit/utils/feature_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,12 @@ def test_has_feature(self):
self.assertTrue(_R.room2.has_feature(_R.door.cls))
self.AssertNotHasFeature(_R.room2, _R.door.open)

def test_set_non_generic(self):
non_generic = f.Set(
_R.warmth.cold, _R.lighting.n_a, _R.color.any, alias='set1'
).non_generic()
self.AssertStrEqual(non_generic, 'set1_non_generic: {cold}')

def test_max_dist(self):
self.assertEqual(_R.warmth.max_dist, 3.00)

Expand Down Expand Up @@ -373,6 +379,17 @@ def test_profile_default_value_n_a(self):
'}\n',
)

def test_profile_aspect_applicable(self):
self.assertTrue(_R.color.is_applicable(_R.room1))
self.assertFalse(_R.color.is_applicable(_R.room2))
self.assertFalse(_R.color.is_applicable(_A.cat))

def test_profile_get(self):
self.AssertStrEqual(_R.room1.get(_R.warmth), 'warmth: {cold}')
self.AssertStrEqual(
_R.room1.get(_A.size), 'animal_features_size: {not_applicable}'
)

def test_profile_compare_all(self):
self.assertEqual(
_R.room1.comparison_table(_R.room2),
Expand Down

0 comments on commit 2681f3e

Please sign in to comment.