diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dbf7ff341..8a88dcc07 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,7 +26,7 @@ repos: - id: black - repo: https://github.com/codespell-project/codespell - rev: v2.2.5 + rev: v2.2.6 hooks: - id: codespell additional_dependencies: diff --git a/computer_vision/cnn_classification.py.DISABLED.txt b/computer_vision/cnn_classification.py.DISABLED.txt index 9b5f8c95e..b813b7103 100644 --- a/computer_vision/cnn_classification.py.DISABLED.txt +++ b/computer_vision/cnn_classification.py.DISABLED.txt @@ -11,10 +11,10 @@ Download dataset from : https://lhncbc.nlm.nih.gov/LHC-publications/pubs/TuberculosisChestXrayImageDataSets.html 1. Download the dataset folder and create two folder training set and test set -in the parent dataste folder +in the parent dataset folder 2. Move 30-40 image from both TB positive and TB Negative folder in the test set folder -3. The labels of the iamges will be extracted from the folder name +3. The labels of the images will be extracted from the folder name the image is present in. """ diff --git a/computer_vision/mosaic_augmentation.py b/computer_vision/mosaic_augmentation.py index c150126d6..cd923dfe0 100644 --- a/computer_vision/mosaic_augmentation.py +++ b/computer_vision/mosaic_augmentation.py @@ -8,7 +8,7 @@ from string import ascii_lowercase, digits import cv2 import numpy as np -# Parrameters +# Parameters OUTPUT_SIZE = (720, 1280) # Height, Width SCALE_RANGE = (0.4, 0.6) # if height or width lower than this scale, drop it. FILTER_TINY_SCALE = 1 / 100 diff --git a/dynamic_programming/min_distance_up_bottom.py b/dynamic_programming/min_distance_up_bottom.py index 4870c7ef4..6b38a41a1 100644 --- a/dynamic_programming/min_distance_up_bottom.py +++ b/dynamic_programming/min_distance_up_bottom.py @@ -1,11 +1,8 @@ """ Author : Alexander Pantyukhin Date : October 14, 2022 -This is implementation Dynamic Programming up bottom approach -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/ +This is an implementation of the up-bottom approach to find edit distance. +The implementation was tested on Leetcode: https://leetcode.com/problems/edit-distance/ Levinstein distance Dynamic Programming: up -> down. @@ -30,10 +27,10 @@ def min_distance_up_bottom(word1: str, word2: str) -> int: @functools.cache def min_distance(index1: int, index2: int) -> int: - # if first word index is overflow - delete all from the second word + # if first word index overflows - delete all from the second word if index1 >= len_word1: return len_word2 - index2 - # if second word index is overflow - delete all from the first word + # if second word index overflows - delete all from the first word if index2 >= len_word2: return len_word1 - index1 diff = int(word1[index1] != word2[index2]) # current letters not identical diff --git a/graphs/tests/test_min_spanning_tree_prim.py b/graphs/tests/test_min_spanning_tree_prim.py index 91feab28f..66e5706da 100644 --- a/graphs/tests/test_min_spanning_tree_prim.py +++ b/graphs/tests/test_min_spanning_tree_prim.py @@ -22,12 +22,12 @@ def test_prim_successful_result(): [1, 7, 11], ] - adjancency = defaultdict(list) + adjacency = defaultdict(list) for node1, node2, cost in edges: - adjancency[node1].append([node2, cost]) - adjancency[node2].append([node1, cost]) + adjacency[node1].append([node2, cost]) + adjacency[node2].append([node1, cost]) - result = mst(adjancency) + result = mst(adjacency) expected = [ [7, 6, 1], diff --git a/hashes/sha1.py b/hashes/sha1.py index 8a03673f3..a0fa688f8 100644 --- a/hashes/sha1.py +++ b/hashes/sha1.py @@ -1,26 +1,28 @@ """ -Demonstrates implementation of SHA1 Hash function in a Python class and gives utilities -to find hash of string or hash of text from a file. +Implementation of the SHA1 hash function and gives utilities to find hash of string or +hash of text from a file. Also contains a Test class to verify that the generated hash +matches what is returned by the hashlib library + Usage: python sha1.py --string "Hello World!!" python sha1.py --file "hello_world.txt" When run without any arguments, it prints the hash of the string "Hello World!! Welcome to Cryptography" -Also contains a Test class to verify that the generated Hash is same as that -returned by the hashlib library -SHA1 hash or SHA1 sum of a string is a cryptographic function which means it is easy +SHA1 hash or SHA1 sum of a string is a cryptographic function, which means it is easy to calculate forwards but extremely difficult to calculate backwards. What this means -is, you can easily calculate the hash of a string, but it is extremely difficult to -know the original string if you have its hash. This property is useful to communicate -securely, send encrypted messages and is very useful in payment systems, blockchain -and cryptocurrency etc. -The Algorithm as described in the reference: +is you can easily calculate the hash of a string, but it is extremely difficult to know +the original string if you have its hash. This property is useful for communicating +securely, send encrypted messages and is very useful in payment systems, blockchain and +cryptocurrency etc. + +The algorithm as described in the reference: First we start with a message. The message is padded and the length of the message is added to the end. It is then split into blocks of 512 bits or 64 bytes. The blocks are then processed one at a time. Each block must be expanded and compressed. -The value after each compression is added to a 160bit buffer called the current hash -state. After the last block is processed the current hash state is returned as +The value after each compression is added to a 160-bit buffer called the current hash +state. After the last block is processed, the current hash state is returned as the final hash. + Reference: https://deadhacker.com/2006/02/21/sha-1-illustrated/ """ import argparse @@ -30,18 +32,18 @@ import struct class SHA1Hash: """ - Class to contain the entire pipeline for SHA1 Hashing Algorithm + Class to contain the entire pipeline for SHA1 hashing algorithm >>> SHA1Hash(bytes('Allan', 'utf-8')).final_hash() '872af2d8ac3d8695387e7c804bf0e02c18df9e6e' """ def __init__(self, data): """ - Inititates the variables data and h. h is a list of 5 8-digit Hexadecimal + Initiates the variables data and h. h is a list of 5 8-digit hexadecimal numbers corresponding to (1732584193, 4023233417, 2562383102, 271733878, 3285377520) respectively. We will start with this as a message digest. 0x is how you write - Hexadecimal numbers in Python + hexadecimal numbers in Python """ self.data = data self.h = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0] @@ -90,7 +92,7 @@ class SHA1Hash: For each block, the variable h that was initialized is copied to a,b,c,d,e and these 5 variables a,b,c,d,e undergo several changes. After all the blocks are processed, these 5 variables are pairwise added to h ie a to h[0], b to h[1] - and so on. This h becomes our final hash which is returned. + and so on. This h becomes our final hash which is returned. """ self.padded_data = self.padding() self.blocks = self.split_blocks() @@ -135,7 +137,7 @@ def test_sha1_hash(): def main(): """ Provides option 'string' or 'file' to take input and prints the calculated SHA1 - hash. unittest.main() has been commented because we probably don't want to run + hash. unittest.main() has been commented out because we probably don't want to run the test each time. """ # unittest.main() diff --git a/maths/pi_generator.py b/maths/pi_generator.py index dcd218aae..addd92174 100644 --- a/maths/pi_generator.py +++ b/maths/pi_generator.py @@ -3,60 +3,53 @@ def calculate_pi(limit: int) -> str: https://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80 Leibniz Formula for Pi - The Leibniz formula is the special case arctan 1 = 1/4 Pi . + The Leibniz formula is the special case arctan(1) = pi / 4. Leibniz's formula converges extremely slowly: it exhibits sublinear convergence. Convergence (https://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80#Convergence) We cannot try to prove against an interrupted, uncompleted generation. https://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80#Unusual_behaviour - The errors can in fact be predicted; - but those calculations also approach infinity for accuracy. + The errors can in fact be predicted, but those calculations also approach infinity + for accuracy. - Our output will always be a string since we can defintely store all digits in there. - For simplicity' sake, let's just compare against known values and since our outpit - is a string, we need to convert to float. + Our output will be a string so that we can definitely store all digits. >>> import math >>> float(calculate_pi(15)) == math.pi True - Since we cannot predict errors or interrupt any infinite alternating - series generation since they approach infinity, - or interrupt any alternating series, we are going to need math.isclose() + Since we cannot predict errors or interrupt any infinite alternating series + generation since they approach infinity, or interrupt any alternating series, we'll + need math.isclose() >>> math.isclose(float(calculate_pi(50)), math.pi) True - >>> math.isclose(float(calculate_pi(100)), math.pi) True - Since math.pi-constant contains only 16 digits, here some test with preknown values: + Since math.pi contains only 16 digits, here are some tests with known values: >>> calculate_pi(50) '3.14159265358979323846264338327950288419716939937510' >>> calculate_pi(80) '3.14159265358979323846264338327950288419716939937510582097494459230781640628620899' - - To apply the Leibniz formula for calculating pi, - the variables q, r, t, k, n, and l are used for the iteration process. """ + # Variables used for the iteration process q = 1 r = 0 t = 1 k = 1 n = 3 l = 3 + decimal = limit counter = 0 result = "" - """ - We will avoid using yield since we otherwise get a Generator-Object, - which we can't just compare against anything. We would have to make a list out of it - after the generation, so we will just stick to plain return logic: - """ + # We can't compare against anything if we make a generator, + # so we'll stick with plain return logic while counter != decimal + 1: if 4 * q + r - t < n * t: result += str(n) diff --git a/maths/radians.py b/maths/radians.py index 465467a3b..b8ac61cb1 100644 --- a/maths/radians.py +++ b/maths/radians.py @@ -3,7 +3,7 @@ from math import pi def radians(degree: float) -> float: """ - Coverts the given angle from degrees to radians + Converts the given angle from degrees to radians https://en.wikipedia.org/wiki/Radian >>> radians(180) @@ -16,7 +16,7 @@ def radians(degree: float) -> float: 1.9167205845401725 >>> from math import radians as math_radians - >>> all(abs(radians(i)-math_radians(i)) <= 0.00000001 for i in range(-2, 361)) + >>> all(abs(radians(i) - math_radians(i)) <= 1e-8 for i in range(-2, 361)) True """ diff --git a/maths/square_root.py b/maths/square_root.py index 2cbf14bea..4462ccb75 100644 --- a/maths/square_root.py +++ b/maths/square_root.py @@ -19,14 +19,13 @@ def get_initial_point(a: float) -> float: def square_root_iterative( - a: float, max_iter: int = 9999, tolerance: float = 0.00000000000001 + a: float, max_iter: int = 9999, tolerance: float = 1e-14 ) -> float: """ - Square root is aproximated using Newtons method. + Square root approximated using Newton's method. https://en.wikipedia.org/wiki/Newton%27s_method - >>> all(abs(square_root_iterative(i)-math.sqrt(i)) <= .00000000000001 - ... for i in range(500)) + >>> all(abs(square_root_iterative(i) - math.sqrt(i)) <= 1e-14 for i in range(500)) True >>> square_root_iterative(-1) diff --git a/neural_network/convolution_neural_network.py b/neural_network/convolution_neural_network.py index f5ec156f3..f2e88fe7b 100644 --- a/neural_network/convolution_neural_network.py +++ b/neural_network/convolution_neural_network.py @@ -2,7 +2,7 @@ - - - - - -- - - - - - - - - - - - - - - - - - - - - - - Name - - CNN - Convolution Neural Network For Photo Recognizing Goal - - Recognize Handing Writing Word Photo - Detail:Total 5 layers neural network + Detail: Total 5 layers neural network * Convolution layer * Pooling layer * Input layer layer of BP @@ -24,7 +24,7 @@ class CNN: self, conv1_get, size_p1, bp_num1, bp_num2, bp_num3, rate_w=0.2, rate_t=0.2 ): """ - :param conv1_get: [a,c,d],size, number, step of convolution kernel + :param conv1_get: [a,c,d], size, number, step of convolution kernel :param size_p1: pooling size :param bp_num1: units number of flatten layer :param bp_num2: units number of hidden layer @@ -71,7 +71,7 @@ class CNN: with open(save_path, "wb") as f: pickle.dump(model_dic, f) - print(f"Model saved: {save_path}") + print(f"Model saved: {save_path}") @classmethod def read_model(cls, model_path): @@ -210,7 +210,7 @@ class CNN: def train( self, patterns, datas_train, datas_teach, n_repeat, error_accuracy, draw_e=bool ): - # model traning + # model training print("----------------------Start Training-------------------------") print((" - - Shape: Train_Data ", np.shape(datas_train))) print((" - - Shape: Teach_Data ", np.shape(datas_teach))) diff --git a/neural_network/gan.py_tf b/neural_network/gan.py_tf index deb062c48..9c6e1c05b 100644 --- a/neural_network/gan.py_tf +++ b/neural_network/gan.py_tf @@ -158,7 +158,7 @@ if __name__ == "__main__": # G_b2 = np.random.normal(size=(784),scale=(1. / np.sqrt(784 / 2.))) *0.002 G_b7 = np.zeros(784) - # 3. For Adam Optimzier + # 3. For Adam Optimizer v1, m1 = 0, 0 v2, m2 = 0, 0 v3, m3 = 0, 0 diff --git a/other/graham_scan.py b/other/graham_scan.py index 2eadb4e56..3f11d40f1 100644 --- a/other/graham_scan.py +++ b/other/graham_scan.py @@ -1,5 +1,5 @@ """ -This is a pure Python implementation of the merge-insertion sort algorithm +This is a pure Python implementation of the Graham scan algorithm Source: https://en.wikipedia.org/wiki/Graham_scan For doctests run following command: @@ -142,8 +142,8 @@ def graham_scan(points: list[tuple[int, int]]) -> list[tuple[int, int]]: stack.append(sorted_points[0]) stack.append(sorted_points[1]) stack.append(sorted_points[2]) - # In any ways, the first 3 points line are towards left. - # Because we sort them the angle from minx, miny. + # The first 3 points lines are towards the left because we sort them by their angle + # from minx, miny. current_direction = Direction.left for i in range(3, len(sorted_points)): @@ -164,7 +164,7 @@ def graham_scan(points: list[tuple[int, int]]) -> list[tuple[int, int]]: break elif current_direction == Direction.right: # If the straight line is towards right, - # every previous points on those straigh line is not convex hull. + # every previous points on that straight line is not convex hull. stack.pop() if next_direction == Direction.right: stack.pop() diff --git a/other/linear_congruential_generator.py b/other/linear_congruential_generator.py index c016310f9..c7de15b94 100644 --- a/other/linear_congruential_generator.py +++ b/other/linear_congruential_generator.py @@ -8,9 +8,9 @@ class LinearCongruentialGenerator: A pseudorandom number generator. """ - # The default value for **seed** is the result of a function call which is not + # The default value for **seed** is the result of a function call, which is not # normally recommended and causes ruff to raise a B008 error. However, in this case, - # it is accptable because `LinearCongruentialGenerator.__init__()` will only be + # it is acceptable because `LinearCongruentialGenerator.__init__()` will only be # called once per instance and it ensures that each instance will generate a unique # sequence of numbers. diff --git a/other/password.py b/other/password.py index 9a6161af8..1ce0d5231 100644 --- a/other/password.py +++ b/other/password.py @@ -63,11 +63,12 @@ def random_characters(chars_incl, i): pass # Put your code here... -# This Will Check Whether A Given Password Is Strong Or Not -# It Follows The Rule that Length Of Password Should Be At Least 8 Characters -# And At Least 1 Lower, 1 Upper, 1 Number And 1 Special Character def is_strong_password(password: str, min_length: int = 8) -> bool: """ + This will check whether a given password is strong or not. The password must be at + least as long as the provided minimum length, and it must contain at least 1 + lowercase letter, 1 uppercase letter, 1 number and 1 special character. + >>> is_strong_password('Hwea7$2!') True >>> is_strong_password('Sh0r1') @@ -81,7 +82,6 @@ def is_strong_password(password: str, min_length: int = 8) -> bool: """ if len(password) < min_length: - # Your Password must be at least 8 characters long return False upper = any(char in ascii_uppercase for char in password) @@ -90,8 +90,6 @@ def is_strong_password(password: str, min_length: int = 8) -> bool: spec_char = any(char in punctuation for char in password) return upper and lower and num and spec_char - # Passwords should contain UPPERCASE, lowerase - # numbers, and special characters def main(): @@ -104,7 +102,7 @@ def main(): "Alternative Password generated:", alternative_password_generator(chars_incl, length), ) - print("[If you are thinking of using this passsword, You better save it.]") + print("[If you are thinking of using this password, You better save it.]") if __name__ == "__main__": diff --git a/physics/speed_of_sound.py b/physics/speed_of_sound.py index a4658366a..3fa952cdb 100644 --- a/physics/speed_of_sound.py +++ b/physics/speed_of_sound.py @@ -2,39 +2,35 @@ Title : Calculating the speed of sound Description : - The speed of sound (c) is the speed that a sound wave travels - per unit time (m/s). During propagation, the sound wave propagates - through an elastic medium. Its SI unit is meter per second (m/s). + The speed of sound (c) is the speed that a sound wave travels per unit time (m/s). + During propagation, the sound wave propagates through an elastic medium. - Only longitudinal waves can propagate in liquids and gas other then - solid where they also travel in transverse wave. The following Algo- - rithem calculates the speed of sound in fluid depanding on the bulk - module and the density of the fluid. + Sound propagates as longitudinal waves in liquids and gases and as transverse waves + in solids. This file calculates the speed of sound in a fluid based on its bulk + module and density. - Equation for calculating speed od sound in fluid: - c_fluid = (K_s*p)**0.5 + Equation for the speed of sound in a fluid: + c_fluid = sqrt(K_s / p) c_fluid: speed of sound in fluid K_s: isentropic bulk modulus p: density of fluid - - Source : https://en.wikipedia.org/wiki/Speed_of_sound """ def speed_of_sound_in_a_fluid(density: float, bulk_modulus: float) -> float: """ - This method calculates the speed of sound in fluid - - This is calculated from the other two provided values - Examples: - Example 1 --> Water 20°C: bulk_moduls= 2.15MPa, density=998kg/m³ - Example 2 --> Murcery 20°: bulk_moduls= 28.5MPa, density=13600kg/m³ + Calculates the speed of sound in a fluid from its density and bulk modulus - >>> speed_of_sound_in_a_fluid(bulk_modulus=2.15*10**9, density=998) + Examples: + Example 1 --> Water 20°C: bulk_modulus= 2.15MPa, density=998kg/m³ + Example 2 --> Mercury 20°C: bulk_modulus= 28.5MPa, density=13600kg/m³ + + >>> speed_of_sound_in_a_fluid(bulk_modulus=2.15e9, density=998) 1467.7563207952705 - >>> speed_of_sound_in_a_fluid(bulk_modulus=28.5*10**9, density=13600) + >>> speed_of_sound_in_a_fluid(bulk_modulus=28.5e9, density=13600) 1447.614670861731 """ diff --git a/project_euler/problem_035/sol1.py b/project_euler/problem_035/sol1.py index 17a4e9088..644c992ed 100644 --- a/project_euler/problem_035/sol1.py +++ b/project_euler/problem_035/sol1.py @@ -11,18 +11,18 @@ There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73 How many circular primes are there below one million? To solve this problem in an efficient manner, we will first mark all the primes -below 1 million using the Seive of Eratosthenes. Then, out of all these primes, -we will rule out the numbers which contain an even digit. After this we will +below 1 million using the Sieve of Eratosthenes. Then, out of all these primes, +we will rule out the numbers which contain an even digit. After this we will generate each circular combination of the number and check if all are prime. """ from __future__ import annotations -seive = [True] * 1000001 +sieve = [True] * 1000001 i = 2 while i * i <= 1000000: - if seive[i]: + if sieve[i]: for j in range(i * i, 1000001, i): - seive[j] = False + sieve[j] = False i += 1 @@ -36,7 +36,7 @@ def is_prime(n: int) -> bool: >>> is_prime(25363) False """ - return seive[n] + return sieve[n] def contains_an_even_digit(n: int) -> bool: diff --git a/project_euler/problem_135/sol1.py b/project_euler/problem_135/sol1.py index d71a0439c..ac91fa4e2 100644 --- a/project_euler/problem_135/sol1.py +++ b/project_euler/problem_135/sol1.py @@ -1,28 +1,22 @@ """ Project Euler Problem 135: https://projecteuler.net/problem=135 -Given the positive integers, x, y, and z, -are consecutive terms of an arithmetic progression, -the least value of the positive integer, n, -for which the equation, +Given the positive integers, x, y, and z, are consecutive terms of an arithmetic +progression, the least value of the positive integer, n, for which the equation, x2 − y2 − z2 = n, has exactly two solutions is n = 27: 342 − 272 − 202 = 122 − 92 − 62 = 27 -It turns out that n = 1155 is the least value -which has exactly ten solutions. +It turns out that n = 1155 is the least value which has exactly ten solutions. -How many values of n less than one million -have exactly ten distinct solutions? +How many values of n less than one million have exactly ten distinct solutions? -Taking x,y,z of the form a+d,a,a-d respectively, -the given equation reduces to a*(4d-a)=n. -Calculating no of solutions for every n till 1 million by fixing a -,and n must be multiple of a. -Total no of steps=n*(1/1+1/2+1/3+1/4..+1/n) -,so roughly O(nlogn) time complexity. - +Taking x, y, z of the form a + d, a, a - d respectively, the given equation reduces to +a * (4d - a) = n. +Calculating no of solutions for every n till 1 million by fixing a, and n must be a +multiple of a. Total no of steps = n * (1/1 + 1/2 + 1/3 + 1/4 + ... + 1/n), so roughly +O(nlogn) time complexity. """ @@ -42,15 +36,15 @@ def solution(limit: int = 1000000) -> int: for first_term in range(1, limit): for n in range(first_term, limit, first_term): common_difference = first_term + n / first_term - if common_difference % 4: # d must be divisble by 4 + if common_difference % 4: # d must be divisible by 4 continue else: common_difference /= 4 if ( first_term > common_difference and first_term < 4 * common_difference - ): # since x,y,z are positive integers - frequency[n] += 1 # so z>0 and a>d ,also 4d 0, a > d and 4d < a count = sum(1 for x in frequency[1:limit] if x == 10) diff --git a/project_euler/problem_493/sol1.py b/project_euler/problem_493/sol1.py index c9879a528..4d96c6c32 100644 --- a/project_euler/problem_493/sol1.py +++ b/project_euler/problem_493/sol1.py @@ -9,7 +9,7 @@ Give your answer with nine digits after the decimal point (a.bcdefghij). This combinatorial problem can be solved by decomposing the problem into the following steps: -1. Calculate the total number of possible picking cominations +1. Calculate the total number of possible picking combinations [combinations := binom_coeff(70, 20)] 2. Calculate the number of combinations with one colour missing [missing := binom_coeff(60, 20)] diff --git a/pyproject.toml b/pyproject.toml index f9091fb85..75da7a045 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -130,5 +130,5 @@ omit = [".env/*"] sort = "Cover" [tool.codespell] -ignore-words-list = "3rt,ans,crate,damon,fo,followings,hist,iff,kwanza,mater,secant,som,sur,tim,zar" +ignore-words-list = "3rt,ans,crate,damon,fo,followings,hist,iff,kwanza,manuel,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"