yhoiseth    /
                    paytext
                
                            | 1 | # pyre-strict  | 
            ||
| 2 | |||
| 3 | """  | 
            ||
| 4 | This module helps you work with payment texts such as  | 
            ||
| 5 | "*4321 29.06 USD 50.00 ITUNES.COM/BILL Rate: 1.0000".  | 
            ||
| 6 | """  | 
            ||
| 7 | from re import compile as compile_regex  | 
            ||
| 8 | from typing import List, Any  | 
            ||
| 9 | |||
| 10 | import iso4217parse  | 
            ||
| 11 | |||
| 12 | |||
| 13 | class PaymentText:  | 
            ||
| 14 | """  | 
            ||
| 15 | Use this class to represent your payment text.  | 
            ||
| 16 | """  | 
            ||
| 17 | parts: List[str] = []  | 
            ||
| 18 | |||
| 19 | def __init__(self, text: str) -> None:  | 
            ||
| 20 | self.parts = text.split()  | 
            ||
| 21 | |||
| 22 | def __repr__(self) -> str:  | 
            ||
| 23 | return ' '.join(self.parts)  | 
            ||
| 24 | |||
| 25 | def generalize(self) -> None:  | 
            ||
| 26 | """  | 
            ||
| 27 | Remove all parts of the strings that are specific to just this payment,  | 
            ||
| 28 | in order to have a string that is the same across different payments of  | 
            ||
| 29 | the same type (e.g. a monthly payment to Apple for iCloud storage).  | 
            ||
| 30 | |||
| 31 | :return:  | 
            ||
| 32 | """  | 
            ||
| 33 | self._clean_leading_card_number()  | 
            ||
| 34 | self._clean_leading_date()  | 
            ||
| 35 | self._clean_leading_amount_and_currency()  | 
            ||
| 36 | self._clean_trailing_exchange_rate()  | 
            ||
| 37 | self._clean_trailing_date()  | 
            ||
| 38 | self._clean_trailing_amount_and_currency()  | 
            ||
| 39 | |||
| 40 | def _clean_leading_card_number(self):  | 
            ||
| 41 |         pattern = compile_regex(r'\*\d{4}') | 
            ||
| 42 | |||
| 43 | try:  | 
            ||
| 44 | if pattern.match(self.parts[0]):  | 
            ||
| 45 | del self.parts[0]  | 
            ||
| 46 | except IndexError:  | 
            ||
| 47 | pass  | 
            ||
| 48 | |||
| 49 | def _clean_leading_date(self):  | 
            ||
| 50 |         pattern = compile_regex(r'\d{2}\.\d{2}') | 
            ||
| 51 | |||
| 52 | try:  | 
            ||
| 53 | if pattern.match(self.parts[0]):  | 
            ||
| 54 | del self.parts[0]  | 
            ||
| 55 | except IndexError:  | 
            ||
| 56 | pass  | 
            ||
| 57 | |||
| 58 | def _clean_leading_amount_and_currency(self):  | 
            ||
| 
                                                                                                    
                         0 ignored issues 
                            –
                            show
                         | 
                |||
| 59 | try:  | 
            ||
| 60 | currency: Any = iso4217parse.by_alpha3(self.parts[0])  | 
            ||
| 61 | if isinstance(currency, iso4217parse.Currency):  | 
            ||
| 62 | del self.parts[0]  | 
            ||
| 63 | del self.parts[0]  | 
            ||
| 64 | except IndexError:  | 
            ||
| 65 | pass  | 
            ||
| 66 | |||
| 67 | def _clean_trailing_exchange_rate(self):  | 
            ||
| 68 |         pattern = compile_regex(r'\d{1}\.\d{4}') | 
            ||
| 69 | |||
| 70 | try:  | 
            ||
| 71 | if pattern.match(self.parts[-1]):  | 
            ||
| 72 | del self.parts[-1]  | 
            ||
| 73 | del self.parts[-1]  | 
            ||
| 74 | except IndexError:  | 
            ||
| 75 | pass  | 
            ||
| 76 | |||
| 77 | def _clean_trailing_date(self):  | 
            ||
| 78 |         pattern = compile_regex(r'\d{2}\.\d{2}\.\d{2}') | 
            ||
| 79 | |||
| 80 | try:  | 
            ||
| 81 | if pattern.match(self.parts[-1]):  | 
            ||
| 82 | del self.parts[-1]  | 
            ||
| 83 | |||
| 84 | pattern = compile_regex(r'.+:')  | 
            ||
| 85 | |||
| 86 | if pattern.match(self.parts[-1]):  | 
            ||
| 87 | del self.parts[-1]  | 
            ||
| 88 | except IndexError:  | 
            ||
| 89 | pass  | 
            ||
| 90 | |||
| 91 | def _clean_trailing_amount_and_currency(self):  | 
            ||
| 
                                                                                                    
                         0 ignored issues 
                            –
                            show
                        The name  
                    
                                            _clean_trailing_amount_and_currency does not conform to the method naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).
                                                                                                                                                                                                        This check looks for invalid names for a range of different identifiers. You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements. If your project includes a Pylint configuration file, the settings contained in that file take precedence. To find out more about Pylint, please refer to their site.   Loading history...
                 | 
                |||
| 92 |         pattern = compile_regex(r'\d+,\d{2}') | 
            ||
| 93 | |||
| 94 | try:  | 
            ||
| 95 | if pattern.match(self.parts[-1]):  | 
            ||
| 96 | del self.parts[-1]  | 
            ||
| 97 | |||
| 98 | currency: Any = iso4217parse.by_alpha3(self.parts[-1])  | 
            ||
| 99 | if isinstance(currency, iso4217parse.Currency):  | 
            ||
| 
                                                                                                    
                         1 ignored issue 
                            –
                            show
                                    Comprehensibility
            Best Practice
    
    
    
        introduced 
                            by  
        
        
     | 
                |||
| 100 | del self.parts[-1]  | 
            ||
| 101 | except IndexError:  | 
            ||
| 102 | pass  | 
            ||
| 103 | 
This check looks for invalid names for a range of different identifiers.
You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.
If your project includes a Pylint configuration file, the settings contained in that file take precedence.
To find out more about Pylint, please refer to their site.