From 21571b3f1dee671628b0f5b5683dfd4f05c37b24 Mon Sep 17 00:00:00 2001 From: Visheratin Nikita Date: Thu, 23 Oct 2025 14:17:50 +0300 Subject: [PATCH 01/15] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B0?= =?UTF-8?q?=20=D0=B2=D0=BE=D0=B7=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=20=D0=B2=20=D1=81=D1=82=D0=B5=D0=BF=D0=B5=D0=BD=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fast_pow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fast_pow.py b/src/fast_pow.py index 1ba1dc1..942be35 100644 --- a/src/fast_pow.py +++ b/src/fast_pow.py @@ -2,5 +2,5 @@ def fastPow(number, power): result = number while power != 1: result *= result - power = power // 2 + power >>= 1 return result From 07cf8e53b9767bd4ce33059a26cf75f2ca8d914f Mon Sep 17 00:00:00 2001 From: Visheratin Nikita Date: Thu, 23 Oct 2025 14:19:15 +0300 Subject: [PATCH 02/15] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B0?= =?UTF-8?q?=20=D0=B2=D0=BE=D0=B7=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=20=D0=B2=20=D1=81=D1=82=D0=B5=D0=BF=D0=B5=D0=BD=D1=8C-2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fast_pow.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/fast_pow.py b/src/fast_pow.py index 942be35..cfbd339 100644 --- a/src/fast_pow.py +++ b/src/fast_pow.py @@ -1,6 +1,9 @@ def fastPow(number, power): - result = number - while power != 1: - result *= result + result = 1 + base = number + while power > 0: + if power % 2 == 1: + result*=base + base *= base power >>= 1 return result From f9e5b29bfea35274ad6beddbc15a4b38e0c47d40 Mon Sep 17 00:00:00 2001 From: Visheratin Nikita Date: Thu, 23 Oct 2025 14:23:12 +0300 Subject: [PATCH 03/15] =?UTF-8?q?=D0=9E=D0=B1=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=20=D1=81=D0=BB=D1=83=D1=87=D0=B0=D0=B5=D0=B2?= =?UTF-8?q?=20=D1=81=20=D0=BD=D1=83=D0=BB=D1=8F=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fast_pow.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/fast_pow.py b/src/fast_pow.py index cfbd339..2bbcd59 100644 --- a/src/fast_pow.py +++ b/src/fast_pow.py @@ -1,4 +1,11 @@ def fastPow(number, power): + if power == 0: + return 1 + if number == 0: + if power < 0: + return "0 cannot be raised to a negative power" + return 0 + result = 1 base = number while power > 0: From 99fd693e4e292ef2dc7b77279395a4924f18050c Mon Sep 17 00:00:00 2001 From: Visheratin Nikita Date: Thu, 23 Oct 2025 14:26:16 +0300 Subject: [PATCH 04/15] =?UTF-8?q?=D0=9E=D0=B1=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=20=D1=81=D0=BB=D1=83=D1=87=D0=B0=D1=8F=20?= =?UTF-8?q?=D1=81=20=D0=BE=D1=82=D1=80=D0=B8=D1=86=D0=B0=D1=82=D0=B5=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D0=BE=D0=B9=20=D1=81=D1=82=D0=B5=D0=BF=D0=B5=D0=BD?= =?UTF-8?q?=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fast_pow.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/fast_pow.py b/src/fast_pow.py index 2bbcd59..458502f 100644 --- a/src/fast_pow.py +++ b/src/fast_pow.py @@ -1,10 +1,20 @@ def fastPow(number, power): + + # нули if power == 0: return 1 if number == 0: if power < 0: return "0 cannot be raised to a negative power" return 0 + #отрицательная степень + if power < 0: + number = 1 / number + power = -power + + + + result = 1 base = number From 21f145733c0b70a810cca2e99ee4eedd6a25530d Mon Sep 17 00:00:00 2001 From: Visheratin Nikita Date: Thu, 23 Oct 2025 14:29:10 +0300 Subject: [PATCH 05/15] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BF=D0=BE=D0=BA=D0=B0=D0=B7=D0=B0=D1=82=D0=B5?= =?UTF-8?q?=D0=BB=D1=8F=20=D1=81=D1=82=D0=B5=D0=BF=D0=B5=D0=BD=D0=B8=20?= =?UTF-8?q?=D0=BD=D0=B0=20int?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fast_pow.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/fast_pow.py b/src/fast_pow.py index 458502f..3ec0e70 100644 --- a/src/fast_pow.py +++ b/src/fast_pow.py @@ -1,4 +1,7 @@ def fastPow(number, power): + #проверка степени + if not isinstance(power, int): + raise TypeError("power must be an integer") # нули if power == 0: @@ -12,7 +15,7 @@ def fastPow(number, power): number = 1 / number power = -power - + From 67458458a3a089a4b473c2c5201756c0ac960f09 Mon Sep 17 00:00:00 2001 From: Visheratin Nikita Date: Thu, 23 Oct 2025 14:30:36 +0300 Subject: [PATCH 06/15] =?UTF-8?q?=D0=97=D0=B0=D0=BC=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=80=D1=83=D1=81=D1=81=D0=BA=D1=83=D1=8E=20C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/luhn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/luhn.py b/src/luhn.py index 11d993c..69c53ca 100644 --- a/src/luhn.py +++ b/src/luhn.py @@ -1,4 +1,4 @@ -def luhnСheck(cardNumber): +def luhnCheck(cardNumber): digits = [int(d) for d in str(cardNumber) if d.isdigit()] control = digits.pop() parity = (len(digits))%2 From 715bdad09b9f30f8742a8c65f6dfca1d266daeea Mon Sep 17 00:00:00 2001 From: Visheratin Nikita Date: Thu, 23 Oct 2025 14:34:23 +0300 Subject: [PATCH 07/15] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20ValueError=20=D0=B2=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=BA=D0=B5=20=D0=BD=D1=83=D0=BB=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fast_pow.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/fast_pow.py b/src/fast_pow.py index 3ec0e70..4dcad50 100644 --- a/src/fast_pow.py +++ b/src/fast_pow.py @@ -8,17 +8,13 @@ def fastPow(number, power): return 1 if number == 0: if power < 0: - return "0 cannot be raised to a negative power" + raise ValueError("0 cannot be raised to a negative power") return 0 #отрицательная степень if power < 0: number = 1 / number power = -power - - - - result = 1 base = number while power > 0: From 68585c736945eecfa7d522afcf30f1885abe6460 Mon Sep 17 00:00:00 2001 From: Visheratin Nikita Date: Thu, 23 Oct 2025 14:41:25 +0300 Subject: [PATCH 08/15] =?UTF-8?q?=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BD=D0=B0=20snake=20case?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fast_pow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fast_pow.py b/src/fast_pow.py index 4dcad50..fbca128 100644 --- a/src/fast_pow.py +++ b/src/fast_pow.py @@ -1,4 +1,4 @@ -def fastPow(number, power): +def fast_pow(number, power): #проверка степени if not isinstance(power, int): raise TypeError("power must be an integer") From 6af4c48b967e064d1126c7f3f54a0f27a24b1b23 Mon Sep 17 00:00:00 2001 From: Visheratin Nikita Date: Thu, 23 Oct 2025 14:42:24 +0300 Subject: [PATCH 09/15] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BD=D0=B0=20snake=5Fcase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/luhn.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/luhn.py b/src/luhn.py index 69c53ca..eb7b6c3 100644 --- a/src/luhn.py +++ b/src/luhn.py @@ -1,4 +1,10 @@ -def luhnCheck(cardNumber): +def luhn_check(cardNumber): + + + + + + digits = [int(d) for d in str(cardNumber) if d.isdigit()] control = digits.pop() parity = (len(digits))%2 From 46a245df243518563e5a6cf3e97dc77d107c1d5e Mon Sep 17 00:00:00 2001 From: Visheratin Nikita Date: Thu, 23 Oct 2025 14:43:56 +0300 Subject: [PATCH 10/15] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BD=D0=B0=20=D1=81=D1=82=D1=80=D0=BE=D0=BA?= =?UTF-8?q?=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/luhn.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/luhn.py b/src/luhn.py index eb7b6c3..3b4a555 100644 --- a/src/luhn.py +++ b/src/luhn.py @@ -1,11 +1,13 @@ -def luhn_check(cardNumber): +def luhn_check(card_number): + #проверка строки + if not isinstance(card_number, str): + raise TypeError("card_number должен быть строкой") - - digits = [int(d) for d in str(cardNumber) if d.isdigit()] + digits = [int(d) for d in str(card_number) if d.isdigit()] control = digits.pop() parity = (len(digits))%2 total = 0 From a105b7e8de99aeea4c6a52554ea7d9e3507a6dfc Mon Sep 17 00:00:00 2001 From: Visheratin Nikita Date: Thu, 23 Oct 2025 14:47:44 +0300 Subject: [PATCH 11/15] ValueError --- src/luhn.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/luhn.py b/src/luhn.py index 3b4a555..61f4ca9 100644 --- a/src/luhn.py +++ b/src/luhn.py @@ -2,12 +2,17 @@ def luhn_check(card_number): #проверка строки if not isinstance(card_number, str): raise TypeError("card_number должен быть строкой") + #проверка на корректный ввод digits = [int(d) for d in str(card_number) if d.isdigit()] + + if len(digits) < 2: + raise ValueError("Как минимум 2 цифры.") + control = digits.pop() parity = (len(digits))%2 total = 0 From e366066ef75d96507ebf6f487f191f3941447286 Mon Sep 17 00:00:00 2001 From: Visheratin Nikita Date: Thu, 23 Oct 2025 15:02:06 +0300 Subject: [PATCH 12/15] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BD=D0=B0=20=D0=BA=D0=BE=D1=80=D1=80=D0=B5?= =?UTF-8?q?=D0=BA=D1=82=D0=BD=D1=8B=D0=B9=20=D0=B2=D0=B2=D0=BE=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/luhn.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/luhn.py b/src/luhn.py index 61f4ca9..8063510 100644 --- a/src/luhn.py +++ b/src/luhn.py @@ -4,9 +4,15 @@ def luhn_check(card_number): raise TypeError("card_number должен быть строкой") #проверка на корректный ввод - - - + digits = [] + #проверка на корректность ввода + for ch in card_number: + if ch.isdecimal(): + digits.append(int(ch)) + elif ch in " \t\r\n": + continue + else + raise ValueError("Кривой ввод") digits = [int(d) for d in str(card_number) if d.isdigit()] From 266c420f666cbf3ada9b952a051cfef69cecb6a4 Mon Sep 17 00:00:00 2001 From: Visheratin Nikita Date: Thu, 23 Oct 2025 15:02:23 +0300 Subject: [PATCH 13/15] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BD=D0=B0=20=D0=BA=D0=BE=D1=80=D1=80=D0=B5?= =?UTF-8?q?=D0=BA=D1=82=D0=BD=D1=8B=D0=B9=20=D0=B2=D0=B2=D0=BE=D0=B4-2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/luhn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/luhn.py b/src/luhn.py index 8063510..4e25264 100644 --- a/src/luhn.py +++ b/src/luhn.py @@ -11,7 +11,7 @@ def luhn_check(card_number): digits.append(int(ch)) elif ch in " \t\r\n": continue - else + else: raise ValueError("Кривой ввод") digits = [int(d) for d in str(card_number) if d.isdigit()] From bda1e98858436f1b9d8699ac6262dd9491af357b Mon Sep 17 00:00:00 2001 From: Visheratin Nikita Date: Thu, 23 Oct 2025 15:13:07 +0300 Subject: [PATCH 14/15] =?UTF-8?q?=D0=A2=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/test_fast_pow.py | 19 ++++++++++++++++--- test/test_luhn.py | 21 ++++++++++++++++++--- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/test/test_fast_pow.py b/test/test_fast_pow.py index 5e4aebd..5e00bfc 100644 --- a/test/test_fast_pow.py +++ b/test/test_fast_pow.py @@ -1,9 +1,22 @@ -from src.fast_pow import fastPow +from src.fast_pow import fast_pow +def test_base(): + assert fast_pow(2, 10) == 1024 + +def test_negative_base(): + assert fast_pow(-3, 3) == -27 + assert fast_pow(-3, 4) == 81 + +def test_zero_base(): + assert fast_pow(2, 0) == 1 + def test_two_power_two(): - assert fastPow(2, 2) == 4 + assert fast_pow(2, 2) == 4 +def test_negative_pow(): + assert abs(fast_pow(2, -3) - 0.125) < 1e-15 + assert abs(fast_pow(-2, -3) + 0.125) < 1e-15 def test_negative(): - assert fastPow(-1, 4) == 1 + assert fast_pow(-1, 4) == 1 diff --git a/test/test_luhn.py b/test/test_luhn.py index 1c021a2..a7397fa 100644 --- a/test/test_luhn.py +++ b/test/test_luhn.py @@ -1,9 +1,24 @@ -from src.luhn import luhnСheck +from src.luhn import luhn_check def test_good(): - assert luhnСheck("8571 2612 1234 5467") + assert luhn_check("8571 2612 1234 5467") +def test_incorrect_input(): + try: + luhn_check("7") # слишком коротко + except ValueError: + pass + else: + raise AssertionError("Ошибка недостатка цифр.") + +def test_incorrect_input_2(): + try: + luhn_check("4111 11X") + except ValueError: + pass + else: + raise AssertionError("Value error.") def test_bad(): - assert not luhnСheck("4561 2612 1234 5463") \ No newline at end of file + assert not luhn_check("4561 2612 1234 5463") \ No newline at end of file From 7486b796f608d0fd3db7edeab3c217673ed1d3af Mon Sep 17 00:00:00 2001 From: Visheratin Nikita Date: Thu, 23 Oct 2025 15:16:39 +0300 Subject: [PATCH 15/15] =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0?= =?UTF-8?q?=D0=BC=D0=BC=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main1.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/main1.py diff --git a/src/main1.py b/src/main1.py new file mode 100644 index 0000000..f8082d2 --- /dev/null +++ b/src/main1.py @@ -0,0 +1,51 @@ +def luhn_check(card_number): + #проверка строки + if not isinstance(card_number, str): + raise TypeError("card_number должен быть строкой") + #проверка на корректный ввод + + digits = [] + #проверка на корректность ввода + for ch in card_number: + if ch.isdecimal(): + digits.append(int(ch)) + elif ch in " \t\r\n": + continue + else: + raise ValueError("Кривой ввод") + + digits = [int(d) for d in str(card_number) if d.isdigit()] + + if len(digits) < 2: + raise ValueError("Как минимум 2 цифры.") + + control = digits.pop() + parity = (len(digits))%2 + total = 0 + for i in range(len(digits)): + if i % 2 == parity: + doubled = digits[i] * 2 + if doubled > 9: + doubled -= 9 + total += doubled + else: + total += digits[i] + return (total + control) % 10 == 0 + + + +def main() + print("Введите номер карты (или -1 для выхода):") + while True: + try: + line = input().strip() + except EOFError: + return 0 + except KeyboardInterrupt: + print("\nЗавершение по Ctrl-C.") + return 0 + if line == "-1": + return 0 + print("correct" if ok else "incorrect") +if __name__ == "__main__": + raise SystemExit(main()) \ No newline at end of file