Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Upgrade #4

Merged
merged 6 commits into from
Mar 16, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fixed pylint errors
rahulranjansah committed Mar 16, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 89409e06ebf9ff6ae4f0bf09875b89e48ae3ac11
135 changes: 73 additions & 62 deletions calc.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
from sympy import *
"""
Main
"""
from sympy import Matrix, latex, pprint

# create n numbers of n*n matrix
def create_matrix(matrix_count, rows, columns):

"""
Forms n number of new matrix with "a" rows and "b" columns
"""
matrix_list = []
while matrix_count > 0:
matrix = []
@@ -29,58 +34,62 @@ def create_matrix(matrix_count, rows, columns):
return matrix_list

def validate_input():
"""
Validate input reprompts for the input if you miss inputting values
"""
while True:
try:
try:
matrix_count = int(input("No. of unique matrix undergoing operations: "))
if matrix_count > 0:
return matrix_count
else:
print("ValueError: Invalid input. Please enter a positive number.")
except ValueError:
print("ValueError: Invalid input. Please enter a positive number.")

def validate_rowcol():
"""
Validates initializing the rows and columns of matrix
No negative inputs of rows or column values
"""
while True:
try:
row = int(input("No. of rows: "))
col = int(input("No. of columns: "))
if (row > 0) and (col > 0):
return row, col
elif (row < 0) or (col < 0):
row = int(input("No. of rows: "))
col = int(input("No. of columns: "))

except ValueError:
print("Invalid Input re-enter positive value")

# sum and subtraction of matrix shape (m*n)
def add_subtract_matrix(matrix_list):

"""
Sum/Subtracts n numbers a*b matrix with same dimensions together
Additional feature for latex support
"""
matrix_num = int(input("How many matrix participates in operation? "))
latex_operation = []
# first index defines what is the dimension of matrix after operation, dimensions stays same through out
# first index defines what is the dimension of matrix after operation
first_index = int(input("Left-most matrix index: "))
first_matrix = matrix_list[first_index]

latex_operation.append(first_matrix)
# empty matrix initialize, print index on screen, and rows cols initialize
operation_sum_sub = first_matrix

for _ in range(matrix_num - 1):

for _ in range(matrix_num - 1):
index = int(input("Index of matrix to the right: "))

operation_type = input("What operation do you want to do? Add - press A or a, Subtract - press S or s:: ")
operation_type = input("What operation? Add[A] Subtract[S]:: ").upper().strip()

# check dimensions of the matrix
if (matrix_list[index].rows == first_matrix.rows) and (matrix_list[index].cols == first_matrix.cols):
if (matrix_list[index].rows == first_matrix.rows
and matrix_list[index].cols == first_matrix.cols):

if operation_type == "A" or operation_type == "a":
if operation_type == "A":
operation_sum_sub += matrix_list[index]
latex_operation.append("+")
latex_operation.append(matrix_list[index])

elif operation_type == "S" or operation_type == "s":
elif operation_type == "S":
operation_sum_sub -= matrix_list[index]
latex_operation.append("-")
latex_operation.append(matrix_list[index])
@@ -95,21 +104,22 @@ def add_subtract_matrix(matrix_list):

# dot product matrix shape (m*n)
def dot_product_matrix(matrix_list):
"""
Dot product of n numbers of a*b matrix with proper dimension
Latex based output with intermediate steps and final solution
"""
matrix_num = int(input("How many matrix participates in operation? "))

# latex print of all matrix
for matrix in matrix_list:
with open("output.txt", "a") as f:
f.write("$"+ latex(matrix) + "$\n")

with open("output.txt", "a") as f:
f.write(r"\\Using law of commutativity, we compute dot product of matrices right to left, \\")
with open("output.txt", "a", encoding="utf-8") as output_file:
output_file.write("$"+ latex(matrix) + "$\n")

# first index defines what is the dimension of matrix after operation, dimensions stays same through out
first_matrix = matrix_list[int(input("Which will be your Rightmost matrix: "))]
with open("output.txt", "a", encoding="utf-8") as output_file:
output_file.write(r"\\By law of commutativity, dot product of matrices right to left, \\")

# initialize rightmost matrix
initialize_product = first_matrix
# first index defines what is the dimension of matrix after operation
initialize_product = matrix_list[int(input("Which will be your Rightmost matrix: "))]

# intermediate method print
for _ in range(matrix_num-1):
@@ -119,53 +129,58 @@ def dot_product_matrix(matrix_list):
# intermediate steps
steps = ["="]
outer_product = initialize_product.T
_, c = outer_product.shape
n = c
_, symbol_count = outer_product.shape
outer_product = outer_product.tolist()
i = 0

for element in outer_product:
for atom, column in zip(element, range(matrix_list[index].cols)):
step = str(latex(atom)) + str(latex(matrix_list[index].col(column)))
steps.append(step)
# print((step))
i += 1
if i % n != 0:
if i % symbol_count != 0:
steps.append("+")
else:
steps.append("\hspace{0.5cm}")
steps.append("\\hspace{0.5cm}")
print()

# check dimensions of the matrix

if (matrix_list[index].cols == initialize_product.rows):
if matrix_list[index].cols == initialize_product.rows:
initialize_product = matrix_list[index]*(initialize_product)
else:
print("Dimension out of range")

for _ in steps:
with open("output.txt", "a") as f:
f.write("\n$" + str(_) + "$")
for _ in steps:
with open("output.txt", "a", encoding="utf-8") as output_file:
output_file.write("\n$" + str(_) + "$")

print(steps)

return initialize_product

def operations():
while True:
operation_key = input("Operation key Product -> P and Sum/Subtract -> S: ")
"""
Choose matrix summation or product
"""
while True:
operation_key = input("Operation key Product or Sum/Subtract [P/S]: ").upper().strip()

if (operation_key == "S") or (operation_key == "P"):
if (operation_key in ["S", "P"]):
return operation_key
else:
operation_key = input("Operation key Product -> P and Sum/Subtract -> S: ")



def main():
# initialize new .txt file to be copied in LaTeX, future development targets user input to ask if "a" or "w"
with open("output.txt", "w") as f:
f.write("")
"""
Calling and Printing all the functions
"""
# initialize new .txt file for LaTeX, future development targets user input to ask if "a" or "w"
with open("output.txt", "w", encoding="utf-8") as output_file:
output_file.write("")

# validate user values
validated_count = validate_input()
validated_rows, validated_columns = validate_rowcol()
validated_rows, validated_columns = validate_rowcol()

matrix_list = create_matrix(validated_count, validated_rows, validated_columns)

@@ -174,30 +189,26 @@ def main():
pprint(en_matrix)

operation_key = operations()
# what operation do you want to do?

if operation_key == "P":
# intermediate steps here
...
# intermediate steps
product = dot_product_matrix(matrix_list)
pprint(product)
# latex_dot_product(matrix_list)
with open("output.txt", "a") as f:
f.write("\n\n$="+ latex(product) + "$")
with open("output.txt", "a", encoding="utf-8") as output_file:
output_file.write("\n\n$="+ latex(product) + "$")

elif operation_key == "S":
sum_sub, latex_operation = add_subtract_matrix(matrix_list)
pprint(sum_sub)
for matrix in latex_operation:
with open("output.txt", "a") as f:
f.write("$"+ latex(matrix) + "$")
with open("output.txt", "a") as f:
f.write("\n\n$="+ latex(sum_sub) + "$")
with open("output.txt", "a", encoding="utf-8") as output_file:
output_file.write("$"+ latex(matrix) + "$")
with open("output.txt", "a", encoding="utf-8") as output_file:
output_file.write("\n\n$="+ latex(sum_sub) + "$")

else:
print("Error in input")

if __name__ == "__main__":
main()



21 changes: 12 additions & 9 deletions output.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
$\left[\begin{matrix}1 & 2\\3 & 4\end{matrix}\right]$
$\left[\begin{matrix}1 & 3\\5 & 6\end{matrix}\right]$
\\Using law of commutativity, we compute dot product of matrices right to left, \\

$\left[\begin{matrix}2 & 3\\4 & 3\\5 & 2\end{matrix}\right]$
$\left[\begin{matrix}4 & 5 & 6\\4 & 3 & 2\end{matrix}\right]$
\\By law of commutativity, dot product of matrices right to left, \\
$=$
$1\left[\begin{matrix}1\\5\end{matrix}\right]$
$2\left[\begin{matrix}4\\4\end{matrix}\right]$
$+$
$4\left[\begin{matrix}5\\3\end{matrix}\right]$
$+$
$3\left[\begin{matrix}3\\6\end{matrix}\right]$
$5\left[\begin{matrix}6\\2\end{matrix}\right]$
$\hspace{0.5cm}$
$2\left[\begin{matrix}1\\5\end{matrix}\right]$
$3\left[\begin{matrix}4\\4\end{matrix}\right]$
$+$
$3\left[\begin{matrix}5\\3\end{matrix}\right]$
$+$
$4\left[\begin{matrix}3\\6\end{matrix}\right]$
$2\left[\begin{matrix}6\\2\end{matrix}\right]$
$\hspace{0.5cm}$

$=\left[\begin{matrix}10 & 14\\23 & 34\end{matrix}\right]$
$=\left[\begin{matrix}58 & 39\\30 & 25\end{matrix}\right]$
40 changes: 32 additions & 8 deletions test_calc/test_calc.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,51 @@
"""
Unit testing
"""
# standard imports
import pytest
import os, sys
from sympy import Matrix
import os
from unittest.mock import patch
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
import sys
import pytest
from sympy import Matrix

# local import

# local importi
from calc import create_matrix, add_subtract_matrix, dot_product_matrix

sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))

# passing the mocked input in the decorator itself to define second matrix
@pytest.mark.parametrize("test_input,expected", [(["1","2","2","3","3","4","3","2","1","2","2","3","3","4"], [Matrix([[1,2], [2,3], [3,4]]), Matrix([[1,2], [2,3], [3,4]])])])
@pytest.mark.parametrize("test_input,expected",
[(["1","2","2","3","3","4","3","2","1","2","2","3","3","4"],
[Matrix([[1,2], [2,3], [3,4]]), Matrix([[1,2], [2,3], [3,4]])])])
def test_create_matrix(test_input, expected):
"""
Unit testing creating_matrix
"""
with patch("builtins.input", side_effect=test_input):
assert create_matrix(2, 3, 2) == expected

@pytest.mark.parametrize("test_input,expected", [(["1","3","4","2","2","2","1","4","5","2","2","0","1"], Matrix([[17,11],[13,19]]))])
@pytest.mark.parametrize("test_input,expected",
[(["1","3","4","2","2","2","1","4","5","2","2","0","1"],
Matrix([[17,11],[13,19]]))])
def test_dot_product_matrix(test_input,expected):
"""
Unit testing of dot_product_matrix
"""
with patch("builtins.input", side_effect=test_input):
matrix = create_matrix(2,2,2)
assert dot_product_matrix(matrix) == expected

@pytest.mark.parametrize("test_input,expected", [(["1","2","3","4","5","6","2","3","1","2","3","4","5","6","2","0","1","A"], (Matrix([[2,4,6],[8,10,12]]), [Matrix([[1,2,3],[4,5,6]]), "+", Matrix([[1,2,3],[4,5,6]])]))])
@pytest.mark.parametrize("test_input,expected",
[(["1","2","3","4","5","6","2","3","1","2","3",
"4","5","6","2","0","1","A"],
(Matrix([[2,4,6],[8,10,12]]),
[Matrix([[1,2,3],[4,5,6]]), "+",
Matrix([[1,2,3],[4,5,6]])]))])
def test_add_subtract_matrix(test_input,expected):
"""
Unit testing of add subtract matrix
"""
with patch("builtins.input", side_effect=test_input):
matrix = create_matrix(2,2,3)
assert add_subtract_matrix(matrix) == expected