Compare commits

..

No commits in common. "33114f0272bcc1fafa6ce0f40d92ded908747ce3" and "63710883c8634772fadf0145899cea4a1eadc31d" have entirely different histories.

8 changed files with 210 additions and 646 deletions

View File

@ -309,7 +309,6 @@
* [Floyd Warshall](dynamic_programming/floyd_warshall.py)
* [Integer Partition](dynamic_programming/integer_partition.py)
* [Iterating Through Submasks](dynamic_programming/iterating_through_submasks.py)
* [K Means Clustering Tensorflow](dynamic_programming/k_means_clustering_tensorflow.py)
* [Knapsack](dynamic_programming/knapsack.py)
* [Longest Common Subsequence](dynamic_programming/longest_common_subsequence.py)
* [Longest Common Substring](dynamic_programming/longest_common_substring.py)
@ -686,7 +685,6 @@
* [2 Hidden Layers Neural Network](neural_network/2_hidden_layers_neural_network.py)
* [Back Propagation Neural Network](neural_network/back_propagation_neural_network.py)
* [Convolution Neural Network](neural_network/convolution_neural_network.py)
* [Input Data](neural_network/input_data.py)
* [Perceptron](neural_network/perceptron.py)
* [Simple Neural Network](neural_network/simple_neural_network.py)
@ -717,7 +715,6 @@
* [Archimedes Principle](physics/archimedes_principle.py)
* [Casimir Effect](physics/casimir_effect.py)
* [Centripetal Force](physics/centripetal_force.py)
* [Grahams Law](physics/grahams_law.py)
* [Horizontal Projectile Motion](physics/horizontal_projectile_motion.py)
* [Hubble Parameter](physics/hubble_parameter.py)
* [Ideal Gas Law](physics/ideal_gas_law.py)

View File

@ -18,61 +18,60 @@ def gen_gaussian_kernel(k_size, sigma):
return g
def suppress_non_maximum(image_shape, gradient_direction, sobel_grad):
def canny(image, threshold_low=15, threshold_high=30, weak=128, strong=255):
image_row, image_col = image.shape[0], image.shape[1]
# gaussian_filter
gaussian_out = img_convolve(image, gen_gaussian_kernel(9, sigma=1.4))
# get the gradient and degree by sobel_filter
sobel_grad, sobel_theta = sobel_filter(gaussian_out)
gradient_direction = np.rad2deg(sobel_theta)
gradient_direction += PI
dst = np.zeros((image_row, image_col))
"""
Non-maximum suppression. If the edge strength of the current pixel is the largest
compared to the other pixels in the mask with the same direction, the value will be
preserved. Otherwise, the value will be suppressed.
"""
destination = np.zeros(image_shape)
for row in range(1, image_shape[0] - 1):
for col in range(1, image_shape[1] - 1):
for row in range(1, image_row - 1):
for col in range(1, image_col - 1):
direction = gradient_direction[row, col]
if (
0 <= direction < PI / 8
0 <= direction < 22.5
or 15 * PI / 8 <= direction <= 2 * PI
or 7 * PI / 8 <= direction <= 9 * PI / 8
):
w = sobel_grad[row, col - 1]
e = sobel_grad[row, col + 1]
if sobel_grad[row, col] >= w and sobel_grad[row, col] >= e:
destination[row, col] = sobel_grad[row, col]
dst[row, col] = sobel_grad[row, col]
elif (
PI / 8 <= direction < 3 * PI / 8
or 9 * PI / 8 <= direction < 11 * PI / 8
elif (PI / 8 <= direction < 3 * PI / 8) or (
9 * PI / 8 <= direction < 11 * PI / 8
):
sw = sobel_grad[row + 1, col - 1]
ne = sobel_grad[row - 1, col + 1]
if sobel_grad[row, col] >= sw and sobel_grad[row, col] >= ne:
destination[row, col] = sobel_grad[row, col]
dst[row, col] = sobel_grad[row, col]
elif (
3 * PI / 8 <= direction < 5 * PI / 8
or 11 * PI / 8 <= direction < 13 * PI / 8
elif (3 * PI / 8 <= direction < 5 * PI / 8) or (
11 * PI / 8 <= direction < 13 * PI / 8
):
n = sobel_grad[row - 1, col]
s = sobel_grad[row + 1, col]
if sobel_grad[row, col] >= n and sobel_grad[row, col] >= s:
destination[row, col] = sobel_grad[row, col]
dst[row, col] = sobel_grad[row, col]
elif (
5 * PI / 8 <= direction < 7 * PI / 8
or 13 * PI / 8 <= direction < 15 * PI / 8
elif (5 * PI / 8 <= direction < 7 * PI / 8) or (
13 * PI / 8 <= direction < 15 * PI / 8
):
nw = sobel_grad[row - 1, col - 1]
se = sobel_grad[row + 1, col + 1]
if sobel_grad[row, col] >= nw and sobel_grad[row, col] >= se:
destination[row, col] = sobel_grad[row, col]
dst[row, col] = sobel_grad[row, col]
return destination
def detect_high_low_threshold(
image_shape, destination, threshold_low, threshold_high, weak, strong
):
"""
High-Low threshold detection. If an edge pixels gradient value is higher
than the high threshold value, it is marked as a strong edge pixel. If an
@ -81,63 +80,43 @@ def detect_high_low_threshold(
an edge pixel's value is smaller than the low threshold value, it will be
suppressed.
"""
for row in range(1, image_shape[0] - 1):
for col in range(1, image_shape[1] - 1):
if destination[row, col] >= threshold_high:
destination[row, col] = strong
elif destination[row, col] <= threshold_low:
destination[row, col] = 0
if dst[row, col] >= threshold_high:
dst[row, col] = strong
elif dst[row, col] <= threshold_low:
dst[row, col] = 0
else:
destination[row, col] = weak
dst[row, col] = weak
def track_edge(image_shape, destination, weak, strong):
"""
Edge tracking. Usually a weak edge pixel caused from true edges will be connected
to a strong edge pixel while noise responses are unconnected. As long as there is
one strong edge pixel that is involved in its 8-connected neighborhood, that weak
edge point can be identified as one that should be preserved.
"""
for row in range(1, image_shape[0]):
for col in range(1, image_shape[1]):
if destination[row, col] == weak:
for row in range(1, image_row):
for col in range(1, image_col):
if dst[row, col] == weak:
if 255 in (
destination[row, col + 1],
destination[row, col - 1],
destination[row - 1, col],
destination[row + 1, col],
destination[row - 1, col - 1],
destination[row + 1, col - 1],
destination[row - 1, col + 1],
destination[row + 1, col + 1],
dst[row, col + 1],
dst[row, col - 1],
dst[row - 1, col],
dst[row + 1, col],
dst[row - 1, col - 1],
dst[row + 1, col - 1],
dst[row - 1, col + 1],
dst[row + 1, col + 1],
):
destination[row, col] = strong
dst[row, col] = strong
else:
destination[row, col] = 0
dst[row, col] = 0
def canny(image, threshold_low=15, threshold_high=30, weak=128, strong=255):
# gaussian_filter
gaussian_out = img_convolve(image, gen_gaussian_kernel(9, sigma=1.4))
# get the gradient and degree by sobel_filter
sobel_grad, sobel_theta = sobel_filter(gaussian_out)
gradient_direction = PI + np.rad2deg(sobel_theta)
destination = suppress_non_maximum(image.shape, gradient_direction, sobel_grad)
detect_high_low_threshold(
image.shape, destination, threshold_low, threshold_high, weak, strong
)
track_edge(image.shape, destination, weak, strong)
return destination
return dst
if __name__ == "__main__":
# read original image in gray mode
lena = cv2.imread(r"../image_data/lena.jpg", 0)
# canny edge detection
canny_destination = canny(lena)
cv2.imshow("canny", canny_destination)
canny_dst = canny(lena)
cv2.imshow("canny", canny_dst)
cv2.waitKey(0)

View File

@ -1,35 +1,33 @@
from pathlib import Path
import numpy as np
from PIL import Image
def rgb_to_gray(rgb: np.ndarray) -> np.ndarray:
def rgb2gray(rgb: np.array) -> np.array:
"""
Return gray image from rgb image
>>> rgb_to_gray(np.array([[[127, 255, 0]]]))
>>> rgb2gray(np.array([[[127, 255, 0]]]))
array([[187.6453]])
>>> rgb_to_gray(np.array([[[0, 0, 0]]]))
>>> rgb2gray(np.array([[[0, 0, 0]]]))
array([[0.]])
>>> rgb_to_gray(np.array([[[2, 4, 1]]]))
>>> rgb2gray(np.array([[[2, 4, 1]]]))
array([[3.0598]])
>>> rgb_to_gray(np.array([[[26, 255, 14], [5, 147, 20], [1, 200, 0]]]))
>>> rgb2gray(np.array([[[26, 255, 14], [5, 147, 20], [1, 200, 0]]]))
array([[159.0524, 90.0635, 117.6989]])
"""
r, g, b = rgb[:, :, 0], rgb[:, :, 1], rgb[:, :, 2]
return 0.2989 * r + 0.5870 * g + 0.1140 * b
def gray_to_binary(gray: np.ndarray) -> np.ndarray:
def gray2binary(gray: np.array) -> np.array:
"""
Return binary image from gray image
>>> gray_to_binary(np.array([[127, 255, 0]]))
>>> gray2binary(np.array([[127, 255, 0]]))
array([[False, True, False]])
>>> gray_to_binary(np.array([[0]]))
>>> gray2binary(np.array([[0]]))
array([[False]])
>>> gray_to_binary(np.array([[26.2409, 4.9315, 1.4729]]))
>>> gray2binary(np.array([[26.2409, 4.9315, 1.4729]]))
array([[False, False, False]])
>>> gray_to_binary(np.array([[26, 255, 14], [5, 147, 20], [1, 200, 0]]))
>>> gray2binary(np.array([[26, 255, 14], [5, 147, 20], [1, 200, 0]]))
array([[False, True, False],
[False, True, False],
[False, True, False]])
@ -37,7 +35,7 @@ def gray_to_binary(gray: np.ndarray) -> np.ndarray:
return (gray > 127) & (gray <= 255)
def dilation(image: np.ndarray, kernel: np.ndarray) -> np.ndarray:
def dilation(image: np.array, kernel: np.array) -> np.array:
"""
Return dilated image
>>> dilation(np.array([[True, False, True]]), np.array([[0, 1, 0]]))
@ -63,13 +61,14 @@ def dilation(image: np.ndarray, kernel: np.ndarray) -> np.ndarray:
return output
if __name__ == "__main__":
# read original image
lena_path = Path(__file__).resolve().parent / "image_data" / "lena.jpg"
lena = np.array(Image.open(lena_path))
# kernel to be applied
structuring_element = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]])
output = dilation(gray_to_binary(rgb_to_gray(lena)), structuring_element)
if __name__ == "__main__":
# read original image
image = np.array(Image.open(r"..\image_data\lena.jpg"))
output = dilation(gray2binary(rgb2gray(image)), structuring_element)
# Save the output image
pil_img = Image.fromarray(output).convert("RGB")
pil_img.save("result_dilation.png")

View File

@ -1,10 +1,9 @@
from random import shuffle
import tensorflow as tf
from random import shuffle
from numpy import array
def tf_k_means_cluster(vectors, noofclusters):
def TFKMeansCluster(vectors, noofclusters):
"""
K-Means Clustering using TensorFlow.
'vectors' should be a n*k 2-D NumPy array, where n is the number
@ -31,6 +30,7 @@ def tf_k_means_cluster(vectors, noofclusters):
graph = tf.Graph()
with graph.as_default():
# SESSION OF COMPUTATION
sess = tf.Session()
@ -95,7 +95,8 @@ def tf_k_means_cluster(vectors, noofclusters):
# iterations. To keep things simple, we will only do a set number of
# iterations, instead of using a Stopping Criterion.
noofiterations = 100
for _ in range(noofiterations):
for iteration_n in range(noofiterations):
##EXPECTATION STEP
##Based on the centroid locations till last iteration, compute
##the _expected_ centroid assignments.

View File

@ -1,223 +1,91 @@
"""
The MD5 algorithm is a hash function that's commonly used as a checksum to
detect data corruption. The algorithm works by processing a given message in
blocks of 512 bits, padding the message as needed. It uses the blocks to operate
a 128-bit state and performs a total of 64 such operations. Note that all values
are little-endian, so inputs are converted as needed.
Although MD5 was used as a cryptographic hash function in the past, it's since
been cracked, so it shouldn't be used for security purposes.
For more info, see https://en.wikipedia.org/wiki/MD5
"""
from collections.abc import Generator
from math import sin
import math
def to_little_endian(string_32: bytes) -> bytes:
"""
Converts the given string to little-endian in groups of 8 chars.
def rearrange(bit_string_32):
"""[summary]
Regroups the given binary string.
Arguments:
string_32 {[string]} -- [32-char string]
bitString32 {[string]} -- [32 bit binary]
Raises:
ValueError -- [input is not 32 char]
ValueError -- [if the given string not are 32 bit binary string]
Returns:
32-char little-endian string
>>> to_little_endian(b'1234567890abcdfghijklmnopqrstuvw')
b'pqrstuvwhijklmno90abcdfg12345678'
>>> to_little_endian(b'1234567890')
Traceback (most recent call last):
...
ValueError: Input must be of length 32
[string] -- [32 bit binary string]
>>> rearrange('1234567890abcdfghijklmnopqrstuvw')
'pqrstuvwhijklmno90abcdfg12345678'
"""
if len(string_32) != 32:
raise ValueError("Input must be of length 32")
little_endian = b""
if len(bit_string_32) != 32:
raise ValueError("Need length 32")
new_string = ""
for i in [3, 2, 1, 0]:
little_endian += string_32[8 * i : 8 * i + 8]
return little_endian
new_string += bit_string_32[8 * i : 8 * i + 8]
return new_string
def reformat_hex(i: int) -> bytes:
"""
Converts the given non-negative integer to hex string.
Example: Suppose the input is the following:
i = 1234
The input is 0x000004d2 in hex, so the little-endian hex string is
"d2040000".
def reformat_hex(i):
"""[summary]
Converts the given integer into 8-digit hex number.
Arguments:
i {[int]} -- [integer]
Raises:
ValueError -- [input is negative]
Returns:
8-char little-endian hex string
>>> reformat_hex(1234)
b'd2040000'
>>> reformat_hex(666)
b'9a020000'
>>> reformat_hex(0)
b'00000000'
>>> reformat_hex(1234567890)
b'd2029649'
>>> reformat_hex(1234567890987654321)
b'b11c6cb1'
>>> reformat_hex(-1)
Traceback (most recent call last):
...
ValueError: Input must be non-negative
'9a020000'
"""
if i < 0:
raise ValueError("Input must be non-negative")
hex_rep = format(i, "08x")[-8:]
little_endian_hex = b""
hexrep = format(i, "08x")
thing = ""
for i in [3, 2, 1, 0]:
little_endian_hex += hex_rep[2 * i : 2 * i + 2].encode("utf-8")
return little_endian_hex
thing += hexrep[2 * i : 2 * i + 2]
return thing
def preprocess(message: bytes) -> bytes:
"""
Preprocesses the message string:
- Convert message to bit string
- Pad bit string to a multiple of 512 chars:
- Append a 1
- Append 0's until length = 448 (mod 512)
- Append length of original message (64 chars)
Example: Suppose the input is the following:
message = "a"
The message bit string is "01100001", which is 8 bits long. Thus, the
bit string needs 439 bits of padding so that
(bit_string + "1" + padding) = 448 (mod 512).
The message length is "000010000...0" in 64-bit little-endian binary.
The combined bit string is then 512 bits long.
def pad(bit_string):
"""[summary]
Fills up the binary string to a 512 bit binary string
Arguments:
message {[string]} -- [message string]
bitString {[string]} -- [binary string]
Returns:
processed bit string padded to a multiple of 512 chars
>>> preprocess(b"a") == (b"01100001" + b"1" +
... (b"0" * 439) + b"00001000" + (b"0" * 56))
True
>>> preprocess(b"") == b"1" + (b"0" * 447) + (b"0" * 64)
True
[string] -- [binary string]
"""
bit_string = b""
for char in message:
bit_string += format(char, "08b").encode("utf-8")
start_len = format(len(bit_string), "064b").encode("utf-8")
# Pad bit_string to a multiple of 512 chars
bit_string += b"1"
start_length = len(bit_string)
bit_string += "1"
while len(bit_string) % 512 != 448:
bit_string += b"0"
bit_string += to_little_endian(start_len[32:]) + to_little_endian(start_len[:32])
bit_string += "0"
last_part = format(start_length, "064b")
bit_string += rearrange(last_part[32:]) + rearrange(last_part[:32])
return bit_string
def get_block_words(bit_string: bytes) -> Generator[list[int], None, None]:
"""
Splits bit string into blocks of 512 chars and yields each block as a list
of 32-bit words
Example: Suppose the input is the following:
bit_string =
"000000000...0" + # 0x00 (32 bits, padded to the right)
"000000010...0" + # 0x01 (32 bits, padded to the right)
"000000100...0" + # 0x02 (32 bits, padded to the right)
"000000110...0" + # 0x03 (32 bits, padded to the right)
...
"000011110...0" # 0x0a (32 bits, padded to the right)
Then len(bit_string) == 512, so there'll be 1 block. The block is split
into 32-bit words, and each word is converted to little endian. The
first word is interpreted as 0 in decimal, the second word is
interpreted as 1 in decimal, etc.
Thus, block_words == [[0, 1, 2, 3, ..., 15]].
def get_block(bit_string):
"""[summary]
Iterator:
Returns by each call a list of length 16 with the 32 bit
integer blocks.
Arguments:
bit_string {[string]} -- [bit string with multiple of 512 as length]
Raises:
ValueError -- [length of bit string isn't multiple of 512]
Yields:
a list of 16 32-bit words
>>> test_string = ("".join(format(n << 24, "032b") for n in range(16))
... .encode("utf-8"))
>>> list(get_block_words(test_string))
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]]
>>> list(get_block_words(test_string * 4)) == [list(range(16))] * 4
True
>>> list(get_block_words(b"1" * 512)) == [[4294967295] * 16]
True
>>> list(get_block_words(b""))
[]
>>> list(get_block_words(b"1111"))
Traceback (most recent call last):
...
ValueError: Input must have length that's a multiple of 512
bit_string {[string]} -- [binary string >= 512]
"""
if len(bit_string) % 512 != 0:
raise ValueError("Input must have length that's a multiple of 512")
for pos in range(0, len(bit_string), 512):
block = bit_string[pos : pos + 512]
block_words = []
for i in range(0, 512, 32):
block_words.append(int(to_little_endian(block[i : i + 32]), 2))
yield block_words
curr_pos = 0
while curr_pos < len(bit_string):
curr_part = bit_string[curr_pos : curr_pos + 512]
my_splits = []
for i in range(16):
my_splits.append(int(rearrange(curr_part[32 * i : 32 * i + 32]), 2))
yield my_splits
curr_pos += 512
def not_32(i: int) -> int:
def not32(i):
"""
Perform bitwise NOT on given int.
Arguments:
i {[int]} -- [given int]
Raises:
ValueError -- [input is negative]
Returns:
Result of bitwise NOT on i
>>> not_32(34)
>>> not32(34)
4294967261
>>> not_32(1234)
4294966061
>>> not_32(4294966061)
1234
>>> not_32(0)
4294967295
>>> not_32(1)
4294967294
>>> not_32(-1)
Traceback (most recent call last):
...
ValueError: Input must be non-negative
"""
if i < 0:
raise ValueError("Input must be non-negative")
i_str = format(i, "032b")
new_str = ""
for c in i_str:
@ -225,114 +93,35 @@ def not_32(i: int) -> int:
return int(new_str, 2)
def sum_32(a: int, b: int) -> int:
"""
Add two numbers as 32-bit ints.
Arguments:
a {[int]} -- [first given int]
b {[int]} -- [second given int]
Returns:
(a + b) as an unsigned 32-bit int
>>> sum_32(1, 1)
2
>>> sum_32(2, 3)
5
>>> sum_32(0, 0)
0
>>> sum_32(-1, -1)
4294967294
>>> sum_32(4294967295, 1)
0
"""
def sum32(a, b):
return (a + b) % 2**32
def left_rotate_32(i: int, shift: int) -> int:
"""
Rotate the bits of a given int left by a given amount.
def leftrot32(i, s):
return (i << s) ^ (i >> (32 - s))
def md5me(test_string):
"""[summary]
Returns a 32-bit hash code of the string 'testString'
Arguments:
i {[int]} -- [given int]
shift {[int]} -- [shift amount]
Raises:
ValueError -- [either given int or shift is negative]
Returns:
`i` rotated to the left by `shift` bits
>>> left_rotate_32(1234, 1)
2468
>>> left_rotate_32(1111, 4)
17776
>>> left_rotate_32(2147483648, 1)
1
>>> left_rotate_32(2147483648, 3)
4
>>> left_rotate_32(4294967295, 4)
4294967295
>>> left_rotate_32(1234, 0)
1234
>>> left_rotate_32(0, 0)
0
>>> left_rotate_32(-1, 0)
Traceback (most recent call last):
...
ValueError: Input must be non-negative
>>> left_rotate_32(0, -1)
Traceback (most recent call last):
...
ValueError: Shift must be non-negative
"""
if i < 0:
raise ValueError("Input must be non-negative")
if shift < 0:
raise ValueError("Shift must be non-negative")
return ((i << shift) ^ (i >> (32 - shift))) % 2**32
def md5_me(message: bytes) -> bytes:
"""
Returns the 32-char MD5 hash of a given message.
Reference: https://en.wikipedia.org/wiki/MD5#Algorithm
Arguments:
message {[string]} -- [message]
Returns:
32-char MD5 hash string
>>> md5_me(b"")
b'd41d8cd98f00b204e9800998ecf8427e'
>>> md5_me(b"The quick brown fox jumps over the lazy dog")
b'9e107d9d372bb6826bd81d3542a419d6'
>>> md5_me(b"The quick brown fox jumps over the lazy dog.")
b'e4d909c290d0fb1ca068ffaddf22cbd0'
>>> import hashlib
>>> from string import ascii_letters
>>> msgs = [b"", ascii_letters.encode("utf-8"), "Üñîçø∂é".encode("utf-8"),
... b"The quick brown fox jumps over the lazy dog."]
>>> all(md5_me(msg) == hashlib.md5(msg).hexdigest().encode("utf-8") for msg in msgs)
True
testString {[string]} -- [message]
"""
# Convert to bit string, add padding and append message length
bit_string = preprocess(message)
bs = ""
for i in test_string:
bs += format(ord(i), "08b")
bs = pad(bs)
added_consts = [int(2**32 * abs(sin(i + 1))) for i in range(64)]
tvals = [int(2**32 * abs(math.sin(i + 1))) for i in range(64)]
# Starting states
a0 = 0x67452301
b0 = 0xEFCDAB89
c0 = 0x98BADCFE
d0 = 0x10325476
shift_amounts = [
s = [
7,
12,
17,
@ -399,46 +188,51 @@ def md5_me(message: bytes) -> bytes:
21,
]
# Process bit string in chunks, each with 16 32-char words
for block_words in get_block_words(bit_string):
for m in get_block(bs):
a = a0
b = b0
c = c0
d = d0
# Hash current chunk
for i in range(64):
if i <= 15:
# f = (b & c) | (not_32(b) & d) # Alternate definition for f
# f = (B & C) | (not32(B) & D)
f = d ^ (b & (c ^ d))
g = i
elif i <= 31:
# f = (d & b) | (not_32(d) & c) # Alternate definition for f
# f = (D & B) | (not32(D) & C)
f = c ^ (d & (b ^ c))
g = (5 * i + 1) % 16
elif i <= 47:
f = b ^ c ^ d
g = (3 * i + 5) % 16
else:
f = c ^ (b | not_32(d))
f = c ^ (b | not32(d))
g = (7 * i) % 16
f = (f + a + added_consts[i] + block_words[g]) % 2**32
a = d
dtemp = d
d = c
c = b
b = sum_32(b, left_rotate_32(f, shift_amounts[i]))
# Add hashed chunk to running total
a0 = sum_32(a0, a)
b0 = sum_32(b0, b)
c0 = sum_32(c0, c)
d0 = sum_32(d0, d)
b = sum32(b, leftrot32((a + f + tvals[i] + m[g]) % 2**32, s[i]))
a = dtemp
a0 = sum32(a0, a)
b0 = sum32(b0, b)
c0 = sum32(c0, c)
d0 = sum32(d0, d)
digest = reformat_hex(a0) + reformat_hex(b0) + reformat_hex(c0) + reformat_hex(d0)
return digest
def test():
assert md5me("") == "d41d8cd98f00b204e9800998ecf8427e"
assert (
md5me("The quick brown fox jumps over the lazy dog")
== "9e107d9d372bb6826bd81d3542a419d6"
)
print("Success.")
if __name__ == "__main__":
test()
import doctest
doctest.testmod()

View File

@ -21,10 +21,13 @@ This module and all its submodules are deprecated.
import collections
import gzip
import os
import urllib
import numpy
from tensorflow.python.framework import dtypes, random_seed
from six.moves import urllib
from six.moves import xrange # pylint: disable=redefined-builtin
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import random_seed
from tensorflow.python.platform import gfile
from tensorflow.python.util.deprecation import deprecated
@ -203,8 +206,8 @@ class _DataSet:
else:
fake_label = 0
return (
[fake_image for _ in range(batch_size)],
[fake_label for _ in range(batch_size)],
[fake_image for _ in xrange(batch_size)],
[fake_label for _ in xrange(batch_size)],
)
start = self._index_in_epoch
# Shuffle for the first epoch
@ -259,7 +262,7 @@ def _maybe_download(filename, work_directory, source_url):
gfile.MakeDirs(work_directory)
filepath = os.path.join(work_directory, filename)
if not gfile.Exists(filepath):
urllib.request.urlretrieve(source_url, filepath) # noqa: S310
urllib.request.urlretrieve(source_url, filepath)
with gfile.GFile(filepath) as f:
size = f.size()
print("Successfully downloaded", filename, size, "bytes.")
@ -325,8 +328,7 @@ def read_data_sets(
if not 0 <= validation_size <= len(train_images):
raise ValueError(
f"Validation size should be between 0 and {len(train_images)}. "
f"Received: {validation_size}."
f"Validation size should be between 0 and {len(train_images)}. Received: {validation_size}."
)
validation_images = train_images[:validation_size]
@ -334,7 +336,7 @@ def read_data_sets(
train_images = train_images[validation_size:]
train_labels = train_labels[validation_size:]
options = {"dtype": dtype, "reshape": reshape, "seed": seed}
options = dict(dtype=dtype, reshape=reshape, seed=seed)
train = _DataSet(train_images, train_labels, **options)
validation = _DataSet(validation_images, validation_labels, **options)

View File

@ -1,208 +0,0 @@
"""
Title: Graham's Law of Effusion
Description: Graham's law of effusion states that the rate of effusion of a gas is
inversely proportional to the square root of the molar mass of its particles:
r1/r2 = sqrt(m2/m1)
r1 = Rate of effusion for the first gas.
r2 = Rate of effusion for the second gas.
m1 = Molar mass of the first gas.
m2 = Molar mass of the second gas.
(Description adapted from https://en.wikipedia.org/wiki/Graham%27s_law)
"""
from math import pow, sqrt
def validate(*values: float) -> bool:
"""
Input Parameters:
-----------------
effusion_rate_1: Effustion rate of first gas (m^2/s, mm^2/s, etc.)
effusion_rate_2: Effustion rate of second gas (m^2/s, mm^2/s, etc.)
molar_mass_1: Molar mass of the first gas (g/mol, kg/kmol, etc.)
molar_mass_2: Molar mass of the second gas (g/mol, kg/kmol, etc.)
Returns:
--------
>>> validate(2.016, 4.002)
True
>>> validate(-2.016, 4.002)
False
>>> validate()
False
"""
result = len(values) > 0 and all(value > 0.0 for value in values)
return result
def effusion_ratio(molar_mass_1: float, molar_mass_2: float) -> float | ValueError:
"""
Input Parameters:
-----------------
molar_mass_1: Molar mass of the first gas (g/mol, kg/kmol, etc.)
molar_mass_2: Molar mass of the second gas (g/mol, kg/kmol, etc.)
Returns:
--------
>>> effusion_ratio(2.016, 4.002)
1.408943
>>> effusion_ratio(-2.016, 4.002)
ValueError('Input Error: Molar mass values must greater than 0.')
>>> effusion_ratio(2.016)
Traceback (most recent call last):
...
TypeError: effusion_ratio() missing 1 required positional argument: 'molar_mass_2'
"""
return (
round(sqrt(molar_mass_2 / molar_mass_1), 6)
if validate(molar_mass_1, molar_mass_2)
else ValueError("Input Error: Molar mass values must greater than 0.")
)
def first_effusion_rate(
effusion_rate: float, molar_mass_1: float, molar_mass_2: float
) -> float | ValueError:
"""
Input Parameters:
-----------------
effusion_rate: Effustion rate of second gas (m^2/s, mm^2/s, etc.)
molar_mass_1: Molar mass of the first gas (g/mol, kg/kmol, etc.)
molar_mass_2: Molar mass of the second gas (g/mol, kg/kmol, etc.)
Returns:
--------
>>> first_effusion_rate(1, 2.016, 4.002)
1.408943
>>> first_effusion_rate(-1, 2.016, 4.002)
ValueError('Input Error: Molar mass and effusion rate values must greater than 0.')
>>> first_effusion_rate(1)
Traceback (most recent call last):
...
TypeError: first_effusion_rate() missing 2 required positional arguments: \
'molar_mass_1' and 'molar_mass_2'
>>> first_effusion_rate(1, 2.016)
Traceback (most recent call last):
...
TypeError: first_effusion_rate() missing 1 required positional argument: \
'molar_mass_2'
"""
return (
round(effusion_rate * sqrt(molar_mass_2 / molar_mass_1), 6)
if validate(effusion_rate, molar_mass_1, molar_mass_2)
else ValueError(
"Input Error: Molar mass and effusion rate values must greater than 0."
)
)
def second_effusion_rate(
effusion_rate: float, molar_mass_1: float, molar_mass_2: float
) -> float | ValueError:
"""
Input Parameters:
-----------------
effusion_rate: Effustion rate of second gas (m^2/s, mm^2/s, etc.)
molar_mass_1: Molar mass of the first gas (g/mol, kg/kmol, etc.)
molar_mass_2: Molar mass of the second gas (g/mol, kg/kmol, etc.)
Returns:
--------
>>> second_effusion_rate(1, 2.016, 4.002)
0.709752
>>> second_effusion_rate(-1, 2.016, 4.002)
ValueError('Input Error: Molar mass and effusion rate values must greater than 0.')
>>> second_effusion_rate(1)
Traceback (most recent call last):
...
TypeError: second_effusion_rate() missing 2 required positional arguments: \
'molar_mass_1' and 'molar_mass_2'
>>> second_effusion_rate(1, 2.016)
Traceback (most recent call last):
...
TypeError: second_effusion_rate() missing 1 required positional argument: \
'molar_mass_2'
"""
return (
round(effusion_rate / sqrt(molar_mass_2 / molar_mass_1), 6)
if validate(effusion_rate, molar_mass_1, molar_mass_2)
else ValueError(
"Input Error: Molar mass and effusion rate values must greater than 0."
)
)
def first_molar_mass(
molar_mass: float, effusion_rate_1: float, effusion_rate_2: float
) -> float | ValueError:
"""
Input Parameters:
-----------------
molar_mass: Molar mass of the first gas (g/mol, kg/kmol, etc.)
effusion_rate_1: Effustion rate of first gas (m^2/s, mm^2/s, etc.)
effusion_rate_2: Effustion rate of second gas (m^2/s, mm^2/s, etc.)
Returns:
--------
>>> first_molar_mass(2, 1.408943, 0.709752)
0.507524
>>> first_molar_mass(-1, 2.016, 4.002)
ValueError('Input Error: Molar mass and effusion rate values must greater than 0.')
>>> first_molar_mass(1)
Traceback (most recent call last):
...
TypeError: first_molar_mass() missing 2 required positional arguments: \
'effusion_rate_1' and 'effusion_rate_2'
>>> first_molar_mass(1, 2.016)
Traceback (most recent call last):
...
TypeError: first_molar_mass() missing 1 required positional argument: \
'effusion_rate_2'
"""
return (
round(molar_mass / pow(effusion_rate_1 / effusion_rate_2, 2), 6)
if validate(molar_mass, effusion_rate_1, effusion_rate_2)
else ValueError(
"Input Error: Molar mass and effusion rate values must greater than 0."
)
)
def second_molar_mass(
molar_mass: float, effusion_rate_1: float, effusion_rate_2: float
) -> float | ValueError:
"""
Input Parameters:
-----------------
molar_mass: Molar mass of the first gas (g/mol, kg/kmol, etc.)
effusion_rate_1: Effustion rate of first gas (m^2/s, mm^2/s, etc.)
effusion_rate_2: Effustion rate of second gas (m^2/s, mm^2/s, etc.)
Returns:
--------
>>> second_molar_mass(2, 1.408943, 0.709752)
1.970351
>>> second_molar_mass(-2, 1.408943, 0.709752)
ValueError('Input Error: Molar mass and effusion rate values must greater than 0.')
>>> second_molar_mass(1)
Traceback (most recent call last):
...
TypeError: second_molar_mass() missing 2 required positional arguments: \
'effusion_rate_1' and 'effusion_rate_2'
>>> second_molar_mass(1, 2.016)
Traceback (most recent call last):
...
TypeError: second_molar_mass() missing 1 required positional argument: \
'effusion_rate_2'
"""
return (
round(pow(effusion_rate_1 / effusion_rate_2, 2) / molar_mass, 6)
if validate(molar_mass, effusion_rate_1, effusion_rate_2)
else ValueError(
"Input Error: Molar mass and effusion rate values must greater than 0."
)
)

View File

@ -15,7 +15,7 @@ scikit-fuzzy
scikit-learn
statsmodels
sympy
tensorflow
tensorflow; python_version < "3.11"
texttable
tweepy
xgboost