Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

qr_code_frame_calc branch: code review + tests #294

Merged
merged 3 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/krux/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,8 @@ def capture_qr_code_loop(self, callback):

parser.parse(data)

if parser.parsed_count() > prev_parsed_count:
prev_parsed_count = parser.parsed_count()
if parser.processed_parts_count() > prev_parsed_count:
prev_parsed_count = parser.processed_parts_count()
new_part = True

if parser.is_complete():
Expand Down
2 changes: 1 addition & 1 deletion src/krux/pages/addresses.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def list_address_type(self, addr_type=0):
self.ctx.display.clear()
self.ctx.display.draw_centered_text(loading_txt % (num_checked + 1))

pos_str = str(num_checked + 1) + ". "
pos_str = str(num_checked + 1) + "." + " " # thin space
tadeubas marked this conversation as resolved.
Show resolved Hide resolved
qr_title = pos_str + addr
items.append(
(
Expand Down
20 changes: 12 additions & 8 deletions src/krux/qr.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,14 @@ def parsed_count(self):
if self.decoder.fountain_decoder.expected_part_indexes is None:
return 1 if self.decoder.result is not None else 0
completion_pct = self.decoder.estimated_percent_complete()
return math.ceil(completion_pct * self.total_count())
return math.ceil(completion_pct * self.total_count() / 2) + len(
self.decoder.fountain_decoder.received_part_indexes
)
return len(self.parts)

def processed_parts_count(self):
if self.format == FORMAT_UR:
return self.decoder.fountain_decoder.processed_parts_count
return len(self.parts)

def total_count(self):
Expand All @@ -88,7 +95,7 @@ def total_count(self):
# Single-part URs have no expected part indexes
if self.decoder.fountain_decoder.expected_part_indexes is None:
return 1
return self.decoder.expected_part_count()
return self.decoder.expected_part_count() * 2
tadeubas marked this conversation as resolved.
Show resolved Hide resolved
return self.total

def parse(self, data):
Expand Down Expand Up @@ -185,10 +192,9 @@ def max_qr_bytes(max_width):
max_width -= 2 # Subtract frame width
qr_version = (max_width - 17) // 4
try:
capacity = QR_CAPACITY[qr_version - 1]
return QR_CAPACITY[qr_version - 1]
except:
capacity = QR_CAPACITY[-1]
return capacity
return QR_CAPACITY[-1]


def find_min_num_parts(data, max_width, qr_format):
Expand Down Expand Up @@ -217,9 +223,7 @@ def find_min_num_parts(data, max_width, qr_format):
num_parts = (data_length + qr_capacity - 1) // qr_capacity
# For UR, part size will be the input for "max_fragment_len"
part_size = len(data.cbor) // num_parts
part_size = max(
part_size, UR_MIN_FRAGMENT_LENGTH
)
part_size = max(part_size, UR_MIN_FRAGMENT_LENGTH)
else:
raise ValueError("Invalid format type")
return num_parts, part_size
Expand Down
3 changes: 3 additions & 0 deletions tests/shared_mocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ def total_count(self):
def parsed_count(self):
return len(self.parts)

def processed_parts_count(self):
return self.parsed_count()

def parse(self, part):
if part not in self.parts:
self.parts.append(part)
Expand Down
28 changes: 24 additions & 4 deletions tests/test_qr.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ def test_parser(mocker, m5stickv, tdata):
(FORMAT_UR, tdata.TEST_PARTS_FORMAT_SINGLEPART_UR),
(FORMAT_UR, tdata.TEST_PARTS_FORMAT_MULTIPART_UR),
]
num = 0
for case in cases:
print("case: ", num)
num += 1
fmt = case[0]
parts = case[1]

Expand All @@ -89,7 +92,10 @@ def test_parser(mocker, m5stickv, tdata):

assert parser.format == fmt

assert parser.total_count() == len(parts)
if num == 4:
assert parser.total_count() == len(parts) * 2
else:
assert parser.total_count() == len(parts)
if parser.format == FORMAT_UR:
assert parser.parsed_count() > 0
else:
Expand All @@ -103,7 +109,11 @@ def test_parser(mocker, m5stickv, tdata):
# Re-parse the first part to test that redundant parts are ignored
parser.parse(parts[0])

assert parser.total_count() == len(parts)
if num == 4:
assert parser.total_count() == len(parts) * 2
else:
assert parser.total_count() == len(parts)

if parser.format == FORMAT_UR:
assert parser.parsed_count() > 0
else:
Expand Down Expand Up @@ -135,7 +145,7 @@ def test_to_qr_codes(mocker, m5stickv, tdata):
for case in cases:
mocker.patch(
"krux.display.lcd",
new=mocker.MagicMock(width=mocker.MagicMock(return_value=case[2]))
new=mocker.MagicMock(width=mocker.MagicMock(return_value=case[2])),
)
display = Display()
qr_data_width = display.qr_data_width()
Expand All @@ -154,7 +164,7 @@ def test_to_qr_codes(mocker, m5stickv, tdata):
if i == total - 1:
break
except Exception as e:
print("Error:",e)
print("Error:", e)
break
i += 1
assert len(codes) == expected_parts
Expand All @@ -168,3 +178,13 @@ def test_detect_plaintext_qr(mocker, m5stickv):
)

detect_format(PLAINTEXT_QR_DATA)


def test_find_min_num_parts(m5stickv):
from krux.qr import find_min_num_parts

with pytest.raises(ValueError) as raised_ex:
find_min_num_parts("", 10, "format unknown")

assert raised_ex.type is ValueError
assert raised_ex.value.args[0] == "Invalid format type"
Loading