Skip to content

Commit efa4a05

Browse files
authored
Merge pull request #34 from OUDON/refactor/refactor-compute-costs-method
refactor: Split `SegmentOptimizer#_compute_costs` into three methods
2 parents 91995b7 + 7da5834 commit efa4a05

File tree

1 file changed

+54
-23
lines changed

1 file changed

+54
-23
lines changed

src/rmqrcode/segments.py

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -107,36 +107,67 @@ def _compute_costs(self, data):
107107
if not encoders[new_mode].is_valid_characters(data[n]):
108108
continue
109109

110-
encoder_class = encoders[new_mode]
111-
character_count_indicator_length = self.qr_version["character_count_indicator_length"][
112-
encoder_class
113-
]
114110
if new_mode == mode:
115-
# Keep the mode
116-
if encoder_class == encoder.NumericEncoder:
117-
new_length = (unfilled_length + 1) % 3
118-
cost = 4 if unfilled_length == 0 else 3
119-
elif encoder_class == encoder.AlphanumericEncoder:
120-
new_length = (unfilled_length + 1) % 2
121-
cost = 6 if unfilled_length == 0 else 5
122-
elif encoder_class == encoder.ByteEncoder:
123-
new_length = 0
124-
cost = 8 * len(data[n].encode("utf-8"))
125-
elif encoder_class == encoder.KanjiEncoder:
126-
new_length = 0
127-
cost = 13
111+
cost, new_length = self._compute_new_state_without_mode_changing(
112+
data[n], new_mode, unfilled_length
113+
)
128114
else:
129-
# Change the mode
130-
if encoder_class in [encoder.NumericEncoder, encoder.AlphanumericEncoder]:
131-
new_length = 1
132-
elif encoder_class in [encoder.ByteEncoder, encoder.KanjiEncoder]:
133-
new_length = 0
134-
cost = encoders[new_mode].length(data[n], character_count_indicator_length)
115+
cost, new_length = self._compute_new_state_with_mode_changing(
116+
data[n], new_mode, unfilled_length
117+
)
135118

136119
if self.dp[n][mode][unfilled_length] + cost < self.dp[n + 1][new_mode][new_length]:
137120
self.dp[n + 1][new_mode][new_length] = self.dp[n][mode][unfilled_length] + cost
138121
self.parents[n + 1][new_mode][new_length] = (n, mode, unfilled_length)
139122

123+
def _compute_new_state_without_mode_changing(self, character, new_mode, unfilled_length):
124+
"""Computes the new state values without mode changing.
125+
126+
Args:
127+
character (str): The current character. Assume this as one length string.
128+
new_mode (int): The state of the new mode.
129+
unfilled_length (int): The state of the current unfilled_length.
130+
131+
Returns:
132+
tuple: (cost, new_length).
133+
134+
"""
135+
encoder_class = encoders[new_mode]
136+
if encoder_class == encoder.NumericEncoder:
137+
new_length = (unfilled_length + 1) % 3
138+
cost = 4 if unfilled_length == 0 else 3
139+
elif encoder_class == encoder.AlphanumericEncoder:
140+
new_length = (unfilled_length + 1) % 2
141+
cost = 6 if unfilled_length == 0 else 5
142+
elif encoder_class == encoder.ByteEncoder:
143+
new_length = 0
144+
cost = 8 * len(character.encode("utf-8"))
145+
elif encoder_class == encoder.KanjiEncoder:
146+
new_length = 0
147+
cost = 13
148+
return (cost, new_length)
149+
150+
def _compute_new_state_with_mode_changing(self, character, new_mode, unfilled_length):
151+
"""Computes the new state values with mode changing.
152+
153+
Args:
154+
character (str): The current character. Assume this as one length string.
155+
new_mode (int): The state of the new mode.
156+
unfilled_length (int): The state of the current unfilled_length.
157+
158+
Returns:
159+
tuple: (cost, new_length).
160+
161+
"""
162+
encoder_class = encoders[new_mode]
163+
character_count_indicator_length = self.qr_version["character_count_indicator_length"][encoder_class]
164+
if encoder_class in [encoder.NumericEncoder, encoder.AlphanumericEncoder]:
165+
new_length = 1
166+
elif encoder_class in [encoder.ByteEncoder, encoder.KanjiEncoder]:
167+
new_length = 0
168+
cost = encoder_class.length(character, character_count_indicator_length)
169+
return (cost, new_length)
170+
140171
def _find_best(self, data):
141172
"""Find the index which has the minimum costs.
142173

0 commit comments

Comments
 (0)