Skip to content

Commit

Permalink
[polish] Code style fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
co-andrey-l committed Apr 30, 2024
1 parent 0fe6d7b commit 91ce923
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 20 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/pylint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10"]
python-version: ["3.9"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
Expand All @@ -17,7 +17,8 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install python-telegram-bot==12.8
pip install pylint
- name: Analysing the code with pylint
run: |
pylint $(git ls-files '*.py')
pylint $(git ls-files '*.py')
32 changes: 23 additions & 9 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
""""Module providing receiving requests from users in a telegram bot."""

import datetime
import os
import random
Expand All @@ -6,14 +8,16 @@
from pinfl_utilities_parser import PinflUtilitiesParser


def start(update, context):
def start(update, context): # pylint: disable=unused-argument
"""Handling the start function."""
update.message.reply_text(
"Привет! Отправь мне PINFL для анализа и я скажу валидный он или нет.\n"
"Тут все честно, я не сохраняю никаких данных о тебе или о том, что ты пишешь."
)


def echo(update, context):
def echo(update, context): # pylint: disable=unused-argument
"""Handling the pinfl check function."""
pinfl_text = update.message.text.strip()

if pinfl_text.isdigit() and len(pinfl_text) >= 14:
Expand All @@ -27,40 +31,50 @@ def echo(update, context):
response += "- Неправильная дата.\n"
if not parser.validate_check_digit():
correct_check_digit = parser.calculate_check_digit()
response += f"- Неправильная контрольная цифра. Правильная контрольная цифра: {correct_check_digit}\n"
response += (
"- Неправильная контрольная цифра. "
f"Правильная контрольная цифра: {correct_check_digit}\n"
)
if not parser.validate_area_code():
response += "- Неправильный код региона.\n"
if not parser.validate_citizen_serial_number():
response += "- Неправильный серийный номер гражданина.\n"
else:
response = "Неверный PINFL. Проверьте, что он содержит только цифры и имеет длину не менее 14 символов."
response = (
"Неверный PINFL. Проверьте, что он содержит только "
"цифры и имеет длину не менее 14 символов."
)

update.message.reply_text(response)


def generate_pinfl(update, context):
def generate_pinfl(update, context): # pylint: disable=unused-argument
"""Handling the generate function."""
generator = PinflUtilitiesGenerator()
gender = random.choice(["male", "female"])
birth_date = datetime.date(
random.randint(1900, 2005), random.randint(1, 12), random.randint(1, 28)
)
pinfl = generator.generate_pinfl(gender, birth_date)
formatted_birth_date = birth_date.strftime("%d %B\(%m\) %Y")
pinfl = generator.generate(gender, birth_date)
formatted_birth_date = birth_date.strftime("%d %B\\(%m\\) %Y")
update.message.reply_text(
f"```{pinfl}```\nДата рожденья: {formatted_birth_date}\nГендер: \#{gender}",
f"```{pinfl}```\nДата рожденья: {formatted_birth_date}\nГендер: \\#{gender}",
parse_mode="MarkdownV2",
)


def main():
"""Point of entry."""

token = os.environ.get("TELEGRAM_BOT_TOKEN")
updater = Updater(token, use_context=True)
dp = updater.dispatcher

dp.add_handler(CommandHandler("start", start))
dp.add_handler(CommandHandler("generate_pinfl", generate_pinfl))
dp.add_handler(MessageHandler(Filters.text & ~Filters.command, echo))

print(f"bot launched successfully")
print("Bot launched successfully")

updater.start_polling()

Expand Down
32 changes: 23 additions & 9 deletions pinfl_utilities_generator.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
"""Random PINFL generation module."""

import random
import datetime


class PinflUtilitiesGenerator:
def generate_pinfl(self, gender, birth_date):
century = str(self.gender_date_index(gender, birth_date))
"""Random PINFL generation."""

def generate(self, gender, birth_date):
"""PINFL generation function."""

century = str(self._gender_date_index(gender, birth_date))

month = str(birth_date.month).zfill(2)
day = str(birth_date.day).zfill(2)
decade = str(birth_date.year % 100)

area_code = str(random.randint(1, 999)).zfill(3)
serial_number = str(random.randint(1, 999)).zfill(3)
pinfl_digits = [

digits = [
str(digit)
for digit in century + day + month + decade + area_code + serial_number
]
check_digit = self._calculate_check_digit(pinfl_digits)
return "".join(pinfl_digits) + str(check_digit)

def gender_date_index(self, gender, birth_date):
check_digit = self._calculate_check_digit(digits)
return "".join(digits) + str(check_digit)

def generate_pinfl(self, gender, birth_date):
"""Generate PINFL."""

return self.generate(gender, birth_date)

def _gender_date_index(self, gender, birth_date):
gender_shift_number = 1 if gender == "female" else 0
return (birth_date.year // 100) - 17 + gender_shift_number

def _calculate_check_digit(self, pinfl_digits):
def _calculate_check_digit(self, digits):
weight_func = [7, 3, 1, 7, 3, 1, 7, 3, 1, 7, 3, 1, 7]
sum_digits = sum(
int(digit) * weight for digit, weight in zip(pinfl_digits, weight_func)
int(digit) * weight for digit, weight in zip(digits, weight_func)
)
return sum_digits % 10
23 changes: 23 additions & 0 deletions pinfl_utilities_parser.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
"""Utilities for parsing PINFL (Personal Identification Number for Individual Taxpayer)"""

from collections import namedtuple
from datetime import date


class PinflUtilitiesParser:
"""Class for parsing PINFL"""

WEIGHT_FUNC = [7, 3, 1, 7, 3, 1, 7, 3, 1, 7, 3, 1, 7]
BEGINNING_CENTURY = 17

Expand All @@ -23,54 +27,67 @@ class PinflUtilitiesParser:
)

def __init__(self, value):
"""Initialize PinflUtilitiesParser with PINFL value."""
self.value = "".join(filter(str.isdigit, str(value)))

@property
def century_and_gender(self):
"""Extract century and gender from the PINFL."""
return int(self.value[0])

@property
def gender(self):
"""Determine gender based on PINFL."""
return "male" if self.century_and_gender % 2 == 1 else "female"

@property
def century(self):
"""Calculate century from PINFL."""
return (((self.century_and_gender + 1) // 2) + self.BEGINNING_CENTURY) * 100

@property
def decade(self):
"""Extract decade from PINFL."""
return int(self.value[5:7])

@property
def year(self):
"""Calculate year from PINFL."""
return self.century + self.decade

@property
def month(self):
"""Extract month from PINFL."""
return int(self.value[3:5])

@property
def day(self):
"""Extract day from PINFL."""
return int(self.value[1:3])

@property
def birth_date(self):
"""Calculate birth date from PINFL."""
return date(self.year, self.month, self.day) if self.is_valid_date() else None

@property
def area_code(self):
"""Extract area code from PINFL."""
return self.value[7:10]

@property
def citizen_serial_number(self):
"""Extract citizen serial number from PINFL."""
return self.value[10:13]

@property
def check_digit(self):
"""Extract check digit from PINFL."""
return int(self.value[13])

@property
def parts(self):
"""Get the parts of the PINFL."""
return self.Parts(
area_code=self.area_code,
check_digit=self.check_digit,
Expand All @@ -85,6 +102,7 @@ def parts(self):
)

def is_valid(self):
"""Check if the PINFL is valid."""
return len(self.value) == 14 and (
self.is_valid_date()
and self.validate_check_digit()
Expand All @@ -93,22 +111,27 @@ def is_valid(self):
)

def is_valid_date(self):
"""Check if the birth date in the PINFL is valid."""
try:
date(self.year, self.month, self.day)
return True
except ValueError:
return False

def validate_check_digit(self):
"""Validate the check digit of the PINFL."""
return self.check_digit == self.calculate_check_digit()

def validate_area_code(self):
"""Validate the area code of the PINFL."""
return int(self.area_code) != 0

def validate_citizen_serial_number(self):
"""Validate the citizen serial number of the PINFL."""
return int(self.citizen_serial_number) != 0

def calculate_check_digit(self):
"""Calculate the check digit of the PINFL."""
pinfl_numbers = list(map(int, self.value))
return (
sum(
Expand Down

0 comments on commit 91ce923

Please sign in to comment.