Completed
by Jochen
03:36
created

### _generate_ticket_code_not_in()   A

#### Complexity

 Conditions 3

#### Size

 Total Lines 11 Code Lines 8

#### Duplication

 Lines 0 Ratio 0 %

#### Code Coverage

 Tests 6 CRAP Score 3

#### Importance

 Changes 0
Metric Value
cc 3
eloc 8
nop 3
dl 0
loc 11
ccs 6
cts 6
cp 1
crap 3
rs 10
c 0
b 0
f 0
 1 `"""` 2 `byceps.services.ticketing.ticket_code_service` 3 `~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~` 4 5 `:Copyright: 2006-2020 Jochen Kupperschmidt` 6 `:License: Modified BSD, see LICENSE for details.` 7 `"""` 8 9 1 `from random import sample` 10 1 `from typing import Set` 11 12 1 `from .transfer.models import TicketCode` 13 14 15 1 `def generate_ticket_codes(quantity: int) -> Set[TicketCode]:` 16 ` """Generate a number of ticket codes."""` 17 1 ` codes: Set[TicketCode] = set()` 18 19 1 ` for _ in range(quantity):` 20 1 ` code = _generate_ticket_code_not_in(codes)` 21 1 ` codes.add(code)` 22 23 ` # Check if the correct number of codes has been generated.` 24 1 ` _verify_total_matches(codes, quantity)` 25 26 1 ` return codes` 27 28 29 1 `def _generate_ticket_code_not_in(` 30 ` codes: Set[TicketCode], *, max_attempts: int = 4` 31 `) -> TicketCode:` 32 ` """Generate ticket codes and return the first one not in the set."""` 33 1 ` for _ in range(max_attempts):` 34 1 ` code = _generate_ticket_code()` 35 1 ` if code not in codes:` 36 1 ` return code` 37 38 1 ` raise TicketCodeGenerationFailed(` 39 ` f'Could not generate unique ticket code after {max_attempts} attempts.'` 40 ` )` 41 42 43 1 `_CODE_ALPHABET = 'BCDFGHJKLMNPQRSTVWXYZ'` 44 1 `_CODE_LENGTH = 5` 45 46 47 1 `def _generate_ticket_code() -> TicketCode:` 48 ` """Generate a ticket code.` 49 50 ` Generated codes are not necessarily unique!` 51 ` """` 52 1 ` return TicketCode(''.join(sample(_CODE_ALPHABET, _CODE_LENGTH)))` 53 54 55 1 `def _verify_total_matches(` 56 ` codes: Set[TicketCode], requested_quantity: int` 57 `) -> None:` 58 ` """Verify if the number of generated codes matches the number of` 59 ` requested codes.` 60 61 ` Raise an exception if they do not match.` 62 ` """` 63 1 ` actual_quantity = len(codes)` 64 1 ` if actual_quantity != requested_quantity:` 65 ` raise TicketCodeGenerationFailed(` 66 ` f'Number of generated ticket codes ({actual_quantity}) '` 67 ` f'does not match requested amount ({requested_quantity}).'` 68 ` )` 69 70 71 1 `class TicketCodeGenerationFailed(Exception):` 72 ` """Generating one or more unique ticket codes has failed."""` 73