mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-11-23 21:11:08 +00:00
Replace bandit, flake8, isort, and pyupgrade with ruff (#8178)
* Replace bandit, flake8, isort, and pyupgrade with ruff * Comment on ruff rules * updating DIRECTORY.md --------- Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
This commit is contained in:
parent
adc3ccdabe
commit
c96241b5a5
10
.flake8
10
.flake8
|
@ -1,10 +0,0 @@
|
|||
[flake8]
|
||||
max-line-length = 88
|
||||
# max-complexity should be 10
|
||||
max-complexity = 19
|
||||
extend-ignore =
|
||||
# Formatting style for `black`
|
||||
# E203 is whitespace before ':'
|
||||
E203,
|
||||
# W503 is line break occurred before a binary operator
|
||||
W503
|
16
.github/workflows/ruff.yml
vendored
Normal file
16
.github/workflows/ruff.yml
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
# https://beta.ruff.rs
|
||||
name: ruff
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
ruff:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- run: pip install --user ruff
|
||||
- run: ruff --format=github .
|
|
@ -3,6 +3,7 @@ repos:
|
|||
rev: v4.4.0
|
||||
hooks:
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-toml
|
||||
- id: check-yaml
|
||||
- id: end-of-file-fixer
|
||||
types: [python]
|
||||
|
@ -14,60 +15,41 @@ repos:
|
|||
hooks:
|
||||
- id: auto-walrus
|
||||
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
rev: v0.0.255
|
||||
hooks:
|
||||
- id: ruff
|
||||
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 23.1.0
|
||||
hooks:
|
||||
- id: black
|
||||
|
||||
- repo: https://github.com/PyCQA/isort
|
||||
rev: 5.12.0
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.2.4
|
||||
hooks:
|
||||
- id: isort
|
||||
args:
|
||||
- --profile=black
|
||||
- id: codespell
|
||||
additional_dependencies:
|
||||
- tomli
|
||||
|
||||
- repo: https://github.com/tox-dev/pyproject-fmt
|
||||
rev: "0.9.2"
|
||||
hooks:
|
||||
- id: pyproject-fmt
|
||||
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: validate-filenames
|
||||
name: Validate filenames
|
||||
entry: ./scripts/validate_filenames.py
|
||||
language: script
|
||||
pass_filenames: false
|
||||
|
||||
- repo: https://github.com/abravalheri/validate-pyproject
|
||||
rev: v0.12.1
|
||||
hooks:
|
||||
- id: validate-pyproject
|
||||
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.3.1
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args:
|
||||
- --py311-plus
|
||||
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
rev: v0.0.255
|
||||
hooks:
|
||||
- id: ruff
|
||||
args:
|
||||
- --ignore=E741
|
||||
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 6.0.0
|
||||
hooks:
|
||||
- id: flake8 # See .flake8 for args
|
||||
additional_dependencies: &flake8-plugins
|
||||
- flake8-bugbear
|
||||
- flake8-builtins
|
||||
# - flake8-broken-line
|
||||
- flake8-comprehensions
|
||||
- pep8-naming
|
||||
|
||||
- repo: https://github.com/asottile/yesqa
|
||||
rev: v1.4.0
|
||||
hooks:
|
||||
- id: yesqa
|
||||
additional_dependencies:
|
||||
*flake8-plugins
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.1.1
|
||||
hooks:
|
||||
|
@ -77,25 +59,3 @@ repos:
|
|||
- --install-types # See mirrors-mypy README.md
|
||||
- --non-interactive
|
||||
additional_dependencies: [types-requests]
|
||||
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.2.4
|
||||
hooks:
|
||||
- id: codespell
|
||||
args:
|
||||
- --ignore-words-list=3rt,ans,crate,damon,fo,followings,hist,iff,kwanza,mater,secant,som,sur,tim,zar
|
||||
exclude: |
|
||||
(?x)^(
|
||||
ciphers/prehistoric_men.txt |
|
||||
strings/dictionary.txt |
|
||||
strings/words.txt |
|
||||
project_euler/problem_022/p022_names.txt
|
||||
)$
|
||||
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: validate-filenames
|
||||
name: Validate filenames
|
||||
entry: ./scripts/validate_filenames.py
|
||||
language: script
|
||||
pass_filenames: false
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from decimal import Decimal
|
||||
from math import * # noqa: F401, F403
|
||||
from math import * # noqa: F403
|
||||
|
||||
from sympy import diff
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
# Newton's Method - https://en.wikipedia.org/wiki/Newton's_method
|
||||
|
||||
from sympy import diff, lambdify, symbols
|
||||
from sympy.functions import * # noqa: F401, F403
|
||||
from sympy.functions import * # noqa: F403
|
||||
|
||||
|
||||
def newton_raphson(
|
||||
|
|
|
@ -166,7 +166,6 @@ def test_heap() -> None:
|
|||
>>> h.get_top()
|
||||
[9, -40]
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -6,13 +6,13 @@ to find edit distance.
|
|||
The aim is to demonstate up bottom approach for solving the task.
|
||||
The implementation was tested on the
|
||||
leetcode: https://leetcode.com/problems/edit-distance/
|
||||
"""
|
||||
|
||||
"""
|
||||
Levinstein distance
|
||||
Dynamic Programming: up -> down.
|
||||
"""
|
||||
|
||||
import functools
|
||||
|
||||
|
||||
def min_distance_up_bottom(word1: str, word2: str) -> int:
|
||||
"""
|
||||
|
@ -25,13 +25,10 @@ def min_distance_up_bottom(word1: str, word2: str) -> int:
|
|||
>>> min_distance_up_bottom("zooicoarchaeologist", "zoologist")
|
||||
10
|
||||
"""
|
||||
|
||||
from functools import lru_cache
|
||||
|
||||
len_word1 = len(word1)
|
||||
len_word2 = len(word2)
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
@functools.cache
|
||||
def min_distance(index1: int, index2: int) -> int:
|
||||
# if first word index is overflow - delete all from the second word
|
||||
if index1 >= len_word1:
|
||||
|
|
|
@ -22,7 +22,7 @@ Minimum Cost For Tickets
|
|||
Dynamic Programming: up -> down.
|
||||
"""
|
||||
|
||||
from functools import lru_cache
|
||||
import functools
|
||||
|
||||
|
||||
def mincost_tickets(days: list[int], costs: list[int]) -> int:
|
||||
|
@ -106,7 +106,7 @@ def mincost_tickets(days: list[int], costs: list[int]) -> int:
|
|||
|
||||
days_set = set(days)
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
@functools.cache
|
||||
def dynamic_programming(index: int) -> int:
|
||||
if index > 365:
|
||||
return 0
|
||||
|
|
|
@ -20,7 +20,7 @@ Runtime: O(n * n)
|
|||
Space: O(n)
|
||||
"""
|
||||
|
||||
from functools import lru_cache
|
||||
import functools
|
||||
from typing import Any
|
||||
|
||||
|
||||
|
@ -80,7 +80,7 @@ def word_break(string: str, words: list[str]) -> bool:
|
|||
len_string = len(string)
|
||||
|
||||
# Dynamic programming method
|
||||
@lru_cache(maxsize=None)
|
||||
@functools.cache
|
||||
def is_breakable(index: int) -> bool:
|
||||
"""
|
||||
>>> string = 'a'
|
||||
|
|
|
@ -26,7 +26,6 @@ Reference: https://deadhacker.com/2006/02/21/sha-1-illustrated/
|
|||
import argparse
|
||||
import hashlib # hashlib is only used inside the Test class
|
||||
import struct
|
||||
import unittest
|
||||
|
||||
|
||||
class SHA1Hash:
|
||||
|
@ -128,14 +127,9 @@ class SHA1Hash:
|
|||
return "%08x%08x%08x%08x%08x" % tuple(self.h)
|
||||
|
||||
|
||||
class SHA1HashTest(unittest.TestCase):
|
||||
"""
|
||||
Test class for the SHA1Hash class. Inherits the TestCase class from unittest
|
||||
"""
|
||||
|
||||
def testMatchHashes(self): # noqa: N802
|
||||
msg = bytes("Test String", "utf-8")
|
||||
self.assertEqual(SHA1Hash(msg).final_hash(), hashlib.sha1(msg).hexdigest())
|
||||
def test_sha1_hash():
|
||||
msg = b"Test String"
|
||||
assert SHA1Hash(msg).final_hash() == hashlib.sha1(msg).hexdigest() # noqa: S324
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -56,7 +56,7 @@ class SVC:
|
|||
*,
|
||||
regularization: float = np.inf,
|
||||
kernel: str = "linear",
|
||||
gamma: float = 0,
|
||||
gamma: float = 0.0,
|
||||
) -> None:
|
||||
self.regularization = regularization
|
||||
self.gamma = gamma
|
||||
|
@ -65,7 +65,7 @@ class SVC:
|
|||
elif kernel == "rbf":
|
||||
if self.gamma == 0:
|
||||
raise ValueError("rbf kernel requires gamma")
|
||||
if not (isinstance(self.gamma, float) or isinstance(self.gamma, int)):
|
||||
if not isinstance(self.gamma, (float, int)):
|
||||
raise ValueError("gamma must be float or int")
|
||||
if not self.gamma > 0:
|
||||
raise ValueError("gamma must be > 0")
|
||||
|
|
|
@ -1,5 +1,20 @@
|
|||
# Eulers Totient function finds the number of relative primes of a number n from 1 to n
|
||||
def totient(n: int) -> list:
|
||||
"""
|
||||
>>> n = 10
|
||||
>>> totient_calculation = totient(n)
|
||||
>>> for i in range(1, n):
|
||||
... print(f"{i} has {totient_calculation[i]} relative primes.")
|
||||
1 has 0 relative primes.
|
||||
2 has 1 relative primes.
|
||||
3 has 2 relative primes.
|
||||
4 has 2 relative primes.
|
||||
5 has 4 relative primes.
|
||||
6 has 2 relative primes.
|
||||
7 has 6 relative primes.
|
||||
8 has 4 relative primes.
|
||||
9 has 6 relative primes.
|
||||
"""
|
||||
is_prime = [True for i in range(n + 1)]
|
||||
totients = [i - 1 for i in range(n + 1)]
|
||||
primes = []
|
||||
|
@ -20,25 +35,6 @@ def totient(n: int) -> list:
|
|||
return totients
|
||||
|
||||
|
||||
def test_totient() -> None:
|
||||
"""
|
||||
>>> n = 10
|
||||
>>> totient_calculation = totient(n)
|
||||
>>> for i in range(1, n):
|
||||
... print(f"{i} has {totient_calculation[i]} relative primes.")
|
||||
1 has 0 relative primes.
|
||||
2 has 1 relative primes.
|
||||
3 has 2 relative primes.
|
||||
4 has 2 relative primes.
|
||||
5 has 4 relative primes.
|
||||
6 has 2 relative primes.
|
||||
7 has 6 relative primes.
|
||||
8 has 4 relative primes.
|
||||
9 has 6 relative primes.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ fib_memoization runtime: 0.0107 ms
|
|||
fib_binet runtime: 0.0174 ms
|
||||
"""
|
||||
|
||||
from functools import lru_cache
|
||||
import functools
|
||||
from math import sqrt
|
||||
from time import time
|
||||
|
||||
|
@ -110,7 +110,7 @@ def fib_recursive_cached(n: int) -> list[int]:
|
|||
Exception: n is negative
|
||||
"""
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
@functools.cache
|
||||
def fib_recursive_term(i: int) -> int:
|
||||
"""
|
||||
Calculates the i-th (0-indexed) Fibonacci number using recursion
|
||||
|
|
|
@ -14,17 +14,13 @@ class Point:
|
|||
|
||||
|
||||
def distance(a: Point, b: Point) -> float:
|
||||
return math.sqrt(abs((b.x - a.x) ** 2 + (b.y - a.y) ** 2 + (b.z - a.z) ** 2))
|
||||
|
||||
|
||||
def test_distance() -> None:
|
||||
"""
|
||||
>>> point1 = Point(2, -1, 7)
|
||||
>>> point2 = Point(1, -3, 5)
|
||||
>>> print(f"Distance from {point1} to {point2} is {distance(point1, point2)}")
|
||||
Distance from Point(2, -1, 7) to Point(1, -3, 5) is 3.0
|
||||
"""
|
||||
pass
|
||||
return math.sqrt(abs((b.x - a.x) ** 2 + (b.y - a.y) ** 2 + (b.z - a.z) ** 2))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/python3
|
||||
# ruff: noqa
|
||||
"""
|
||||
Quine:
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ Reference: https://en.wikipedia.org/wiki/Pythagorean_triple#Generating_a_triple
|
|||
|
||||
from collections import defaultdict
|
||||
from math import gcd
|
||||
from typing import DefaultDict
|
||||
|
||||
|
||||
def solution(limit: int = 1500000) -> int:
|
||||
|
@ -43,7 +42,7 @@ def solution(limit: int = 1500000) -> int:
|
|||
>>> solution(50000)
|
||||
5502
|
||||
"""
|
||||
frequencies: DefaultDict = defaultdict(int)
|
||||
frequencies: defaultdict = defaultdict(int)
|
||||
euclid_m = 2
|
||||
while 2 * euclid_m * (euclid_m + 1) <= limit:
|
||||
for euclid_n in range((euclid_m % 2) + 1, euclid_m, 2):
|
||||
|
|
|
@ -12,8 +12,57 @@ addopts = [
|
|||
omit = [".env/*"]
|
||||
sort = "Cover"
|
||||
|
||||
#[report]
|
||||
#sort = Cover
|
||||
#omit =
|
||||
# .env/*
|
||||
# backtracking/*
|
||||
[tool.codespell]
|
||||
ignore-words-list = "3rt,ans,crate,damon,fo,followings,hist,iff,kwanza,mater,secant,som,sur,tim,zar"
|
||||
skip = "./.*,*.json,ciphers/prehistoric_men.txt,project_euler/problem_022/p022_names.txt,pyproject.toml,strings/dictionary.txt,strings/words.txt"
|
||||
|
||||
[tool.ruff]
|
||||
ignore = [ # `ruff rule S101` for a description of that rule
|
||||
"B904", # B904: Within an `except` clause, raise exceptions with `raise ... from err`
|
||||
"B905", # B905: `zip()` without an explicit `strict=` parameter
|
||||
"E741", # E741: Ambiguous variable name 'l'
|
||||
"G004", # G004 Logging statement uses f-string
|
||||
"N999", # N999: Invalid module name
|
||||
"PLC1901", # PLC1901: `{}` can be simplified to `{}` as an empty string is falsey
|
||||
"PLR2004", # PLR2004: Magic value used in comparison
|
||||
"PLR5501", # PLR5501: Consider using `elif` instead of `else`
|
||||
"PLW0120", # PLW0120: `else` clause on loop without a `break` statement
|
||||
"PLW060", # PLW060: Using global for `{name}` but no assignment is done -- DO NOT FIX
|
||||
"PLW2901", # PLW2901: Redefined loop variable
|
||||
"RUF00", # RUF00: Ambiguous unicode character -- DO NOT FIX
|
||||
"RUF100", # RUF100: Unused `noqa` directive
|
||||
"S101", # S101: Use of `assert` detected -- DO NOT FIX
|
||||
"S105", # S105: Possible hardcoded password: 'password'
|
||||
"S113", # S113: Probable use of requests call without timeout
|
||||
"UP038", # UP038: Use `X | Y` in `{}` call instead of `(X, Y)` -- DO NOT FIX
|
||||
]
|
||||
select = [ # https://beta.ruff.rs/docs/rules
|
||||
"A", # A: builtins
|
||||
"B", # B: bugbear
|
||||
"C40", # C40: comprehensions
|
||||
"C90", # C90: mccabe code complexity
|
||||
"E", # E: pycodestyle errors
|
||||
"F", # F: pyflakes
|
||||
"G", # G: logging format
|
||||
"I", # I: isort
|
||||
"N", # N: pep8 naming
|
||||
"PL", # PL: pylint
|
||||
"PIE", # PIE: pie
|
||||
"PYI", # PYI: type hinting stub files
|
||||
"RUF", # RUF: ruff
|
||||
"S", # S: bandit
|
||||
"TID", # TID: tidy imports
|
||||
"UP", # UP: pyupgrade
|
||||
"W", # W: pycodestyle warnings
|
||||
"YTT", # YTT: year 2020
|
||||
]
|
||||
target-version = "py311"
|
||||
|
||||
[tool.ruff.mccabe] # DO NOT INCREASE THIS VALUE
|
||||
max-complexity = 20 # default: 10
|
||||
|
||||
[tool.ruff.pylint] # DO NOT INCREASE THESE VALUES
|
||||
max-args = 10 # default: 5
|
||||
max-branches = 20 # default: 12
|
||||
max-returns = 8 # default: 6
|
||||
max-statements = 88 # default: 50
|
||||
|
|
|
@ -104,7 +104,7 @@ class FileMerger:
|
|||
files = {}
|
||||
|
||||
for i in range(len(filenames)):
|
||||
files[i] = open(filenames[i], "r", buffer_size)
|
||||
files[i] = open(filenames[i], "r", buffer_size) # noqa: UP015
|
||||
|
||||
return files
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
wiki: https://en.wikipedia.org/wiki/Anagram
|
||||
"""
|
||||
from collections import defaultdict
|
||||
from typing import DefaultDict
|
||||
|
||||
|
||||
def check_anagrams(first_str: str, second_str: str) -> bool:
|
||||
|
@ -30,7 +29,7 @@ def check_anagrams(first_str: str, second_str: str) -> bool:
|
|||
return False
|
||||
|
||||
# Default values for count should be 0
|
||||
count: DefaultDict[str, int] = defaultdict(int)
|
||||
count: defaultdict[str, int] = defaultdict(int)
|
||||
|
||||
# For each character in input strings,
|
||||
# increment count in the corresponding
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Created by sarathkaul on 17/11/19
|
||||
# Modified by Arkadip Bhattacharya(@darkmatter18) on 20/04/2020
|
||||
from collections import defaultdict
|
||||
from typing import DefaultDict
|
||||
|
||||
|
||||
def word_occurrence(sentence: str) -> dict:
|
||||
|
@ -15,7 +14,7 @@ def word_occurrence(sentence: str) -> dict:
|
|||
>>> dict(word_occurrence("Two spaces"))
|
||||
{'Two': 1, 'spaces': 1}
|
||||
"""
|
||||
occurrence: DefaultDict[str, int] = defaultdict(int)
|
||||
occurrence: defaultdict[str, int] = defaultdict(int)
|
||||
# Creating a dictionary containing count of each word
|
||||
for word in sentence.split():
|
||||
occurrence[word] += 1
|
||||
|
|
|
@ -8,7 +8,7 @@ import os
|
|||
import requests
|
||||
|
||||
URL_BASE = "https://www.amdoren.com/api/currency.php"
|
||||
TESTING = os.getenv("CI", False)
|
||||
TESTING = os.getenv("CI", "")
|
||||
API_KEY = os.getenv("AMDOREN_API_KEY", "")
|
||||
|
||||
if not API_KEY and not TESTING:
|
||||
|
|
Loading…
Reference in New Issue
Block a user