diff --git a/.github/workflows/Python CI.yml b/.github/workflows/Python CI.yml new file mode 100644 index 00000000000..24d249015cd --- /dev/null +++ b/.github/workflows/Python CI.yml @@ -0,0 +1,40 @@ +name: Python CI +on: [pull_request, push] +jobs: + Build: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.13" + cache: "pip" + cache-dependency-path: "pyproject.toml" + + - name: Install check dependencies + run: | + python -m pip install --upgrade pip wheel + pip install bandit ruff mypy codespell + + - name: Run Codespell + run: codespell --config pyproject.toml || true + + - name: Run Bandit + run: bandit --recursive --skip B101 . || true + - name: Run Ruff (formatting check) + run: ruff format --check . --config pyproject.toml || true + + - name: Run Ruff (linting) + run: ruff check . --config pyproject.toml + + - name: Setup Mypy cache + run: mkdir -p .mypy_cache + + - name: Install type stubs + run: mypy --config-file pyproject.toml --install-types --non-interactive + + - name: Run Mypy + run: mypy --config-file pyproject.toml diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml deleted file mode 100644 index b90bd664f4a..00000000000 --- a/.github/workflows/lint_python.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: python -on: [pull_request, push] -jobs: - lint_python: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - - run: pip install --upgrade pip wheel - - run: pip install bandit black codespell flake8 flake8-2020 flake8-bugbear - flake8-comprehensions isort mypy pytest pyupgrade safety - - run: bandit --recursive --skip B101 . || true # B101 is assert statements - - run: black --check . || true - - run: codespell || true # --ignore-words-list="" --skip="*.css,*.js,*.lock" - - run: flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - - run: flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88 - --show-source --statistics - - run: isort --check-only --profile black . || true - - run: pip install -r requirements.txt || pip install --editable . || true - - run: mkdir --parents --verbose .mypy_cache - - run: mypy --ignore-missing-imports --install-types --non-interactive . || true - - run: pytest . || pytest --doctest-modules . - - run: shopt -s globstar && pyupgrade --py36-plus **/*.py || true - - run: safety check diff --git a/.gitignore b/.gitignore index 0f3717818e6..25051c60b03 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ .idea +.vscode +_pycache_ *.pyc string=sorted(input()) lower="" @@ -18,10 +20,9 @@ print(lower+upper+odd+even) .venv # operating system-related files - # file properties cache/storage on macOS *.DS_Store - # thumbnail cache on Windows Thumbs.db -bankmanaging.db \ No newline at end of file +bankmanaging.db +.vscode/settings.json \ No newline at end of file diff --git a/1 File handle/File handle binary/Deleting record in a binary file.py b/1 File handle/File handle binary/Deleting record in a binary file.py index d3922a5afc4..0331e6dd918 100644 --- a/1 File handle/File handle binary/Deleting record in a binary file.py +++ b/1 File handle/File handle binary/Deleting record in a binary file.py @@ -1,17 +1,52 @@ import pickle -def bdelete(): - # Opening a file & loading it - with open("studrec.dat","rb") as F: - stud = pickle.load(F) - print(stud) +def delete_student_record() -> None: + """ + Delete a student record from the binary data file 'studrec.dat' based on the provided roll number. - # Deleting the Roll no. entered by user - rno = int(input("Enter the Roll no. to be deleted: ")) - with open("studrec.dat","wb") as F: - rec = [i for i in stud if i[0] != rno] - pickle.dump(rec, F) + This function performs the following operations: + 1. Reads the current student records from 'studrec.dat' + 2. Prompts the user to enter a roll number to delete + 3. Removes the record with the specified roll number + 4. Writes the updated records back to 'studrec.dat' + Each student record is stored as a tuple in the format: (roll_number, ...) -bdelete() + Raises: + FileNotFoundError: If 'studrec.dat' does not exist. + pickle.UnpicklingError: If the file contains corrupted data. + ValueError: If the user input cannot be converted to an integer. + """ + try: + # Read existing student records from file + with open("studrec.dat", "rb") as file: + student_records: list[tuple[int, ...]] = pickle.load(file) + print("Current student records:", student_records) + + # Get roll number to delete + roll_number: int = int(input("Enter the roll number to delete: ")) + + # Filter out the record with the specified roll number + updated_records: list[tuple[int, ...]] = [ + record for record in student_records if record[0] != roll_number + ] + + # Write updated records back to file + with open("studrec.dat", "wb") as file: + pickle.dump(updated_records, file) + + print(f"Record with roll number {roll_number} has been deleted.") + + except FileNotFoundError: + print("Error: The file 'studrec.dat' does not exist.") + except pickle.UnpicklingError: + print("Error: The file contains corrupted data.") + except ValueError as e: + print(f"Error: Invalid input. Please enter an integer. {e}") + except Exception as e: + print(f"An unexpected error occurred: {e}") + + +if __name__ == "__main__": + delete_student_record() diff --git a/1 File handle/File handle binary/File handle binary read (record in non list form).py b/1 File handle/File handle binary/File handle binary read (record in non list form).py index bb9f127ea0b..077759398e7 100644 --- a/1 File handle/File handle binary/File handle binary read (record in non list form).py +++ b/1 File handle/File handle binary/File handle binary read (record in non list form).py @@ -1,23 +1,48 @@ +import os import pickle -def binary_read(): - with open("studrec.dat","rb") as b: - stud = pickle.load(b) - print(stud) - - # prints the whole record in nested list format - print("contents of binary file") - - for ch in stud: - - print(ch) # prints one of the chosen rec in list - - rno = ch[0] - rname = ch[1] # due to unpacking the val not printed in list format - rmark = ch[2] - - print(rno, rname, rmark, end="\t") - - -binary_read() +def read_binary_file() -> None: + """ + Read student records from a binary file. + Automatically creates the file with empty records if it doesn't exist. + + Raises: + pickle.UnpicklingError: If file content is corrupted. + PermissionError: If unable to create or read the file. + """ + file_path = r"1 File handle\File handle binary\studrec.dat" + + # Ensure directory exists + directory = os.path.dirname(file_path) + if not os.path.exists(directory): + os.makedirs(directory, exist_ok=True) + print(f"Created directory: {directory}") + + # Create empty file if it doesn't exist + if not os.path.exists(file_path): + with open(file_path, "wb") as file: + pickle.dump([], file) # Initialize with empty list + print(f"Created new file: {file_path}") + + try: + # Read student records + with open(file_path, "rb") as file: + student_records: list[tuple[int, str, float]] = pickle.load(file) + + # Print records in a formatted table + print("\nStudent Records:") + print(f"{'ROLL':<10}{'NAME':<20}{'MARK':<10}") + print("-" * 40) + for record in student_records: + roll, name, mark = record + print(f"{roll:<10}{name:<20}{mark:<10.1f}") + + except pickle.UnpicklingError: + print(f"ERROR: File {file_path} is corrupted.") + except Exception as e: + print(f"ERROR: Unexpected error - {str(e)}") + + +if __name__ == "__main__": + read_binary_file() diff --git a/1 File handle/File handle binary/Update a binary file.py b/1 File handle/File handle binary/Update a binary file.py index b72154345ae..c54d219d97d 100644 --- a/1 File handle/File handle binary/Update a binary file.py +++ b/1 File handle/File handle binary/Update a binary file.py @@ -1,30 +1,120 @@ -# Updating records in a binary file - +import os import pickle -def update(): - with open("class.dat", "rb+") as F: - S = pickle.load(F) - found = False - rno = int(input("enter the roll number you want to update")) +def initialize_file_if_not_exists(file_path: str) -> None: + """ + Check if file exists. If not, create it with an empty list of records. + + Args: + file_path (str): Path to the file. + + Raises: + ValueError: If file_path is empty. + """ + if not file_path: + raise ValueError("File path cannot be empty.") + + directory = os.path.dirname(file_path) + if directory and not os.path.exists(directory): + os.makedirs(directory, exist_ok=True) + + if not os.path.exists(file_path): + with open(file_path, "wb") as f: + pickle.dump([], f) + print(f"Created new file: {file_path}") + + +def update_student_record(file_path: str) -> None: + """ + Update a student's name in the binary file by roll number. + + Args: + file_path (str): Path to the binary file containing student records. + """ + initialize_file_if_not_exists(file_path) + + try: + with open(file_path, "rb+") as f: + # Load existing records + records: list[tuple[int, str, float]] = pickle.load(f) + + if not records: + print("No records found in the file.") + return + + # Get roll number to update + roll_to_update = int(input("Enter roll number to update: ")) + found = False + + # Find and update the record + for i, record in enumerate(records): + if record[0] == roll_to_update: + current_name = record[1] + new_name = input( + f"Current name: {current_name}. Enter new name: " + ).strip() + + if new_name: + # Create a new tuple with updated name + updated_record = (record[0], new_name, record[2]) + records[i] = updated_record + print("Record updated successfully.") + else: + print("Name cannot be empty. Update cancelled.") + + found = True + break + + if not found: + print(f"Record with roll number {roll_to_update} not found.") + return + + # Rewrite the entire file with updated records + f.seek(0) + pickle.dump(records, f) + f.truncate() # Ensure any remaining data is removed + + except ValueError: + print("Error: Invalid roll number. Please enter an integer.") + except pickle.UnpicklingError: + print("Error: File content is corrupted and cannot be read.") + except Exception as e: + print(f"An unexpected error occurred: {str(e)}") + + +def display_all_records(file_path: str) -> None: + """ + Display all student records in the binary file. + + Args: + file_path (str): Path to the binary file. + """ + initialize_file_if_not_exists(file_path) + + try: + with open(file_path, "rb") as f: + records: list[tuple[int, str, float]] = pickle.load(f) + + if not records: + print("No records found in the file.") + return - for i in S: - if rno == i[0]: - print(f"the currrent name is {i[1]}") - i[1] = input("enter the new name") - found = True - break + print("\nAll Student Records:") + print(f"{'ROLL':<8}{'NAME':<20}{'PERCENTAGE':<12}") + print("-" * 40) - if found: - print("Record not found") + for record in records: + print(f"{record[0]:<8}{record[1]:<20}{record[2]:<12.1f}") - else: - F.seek(0) - pickle.dump(S, F) + except pickle.UnpicklingError: + print("Error: File content is corrupted and cannot be read.") + except Exception as e: + print(f"An unexpected error occurred: {str(e)}") -update() +if __name__ == "__main__": + FILE_PATH = r"class.dat" # Update with your actual file path -with open("class.dat", "rb") as F: - print(pickle.load(F)) + update_student_record(FILE_PATH) + display_all_records(FILE_PATH) diff --git a/1 File handle/File handle binary/Update a binary file2.py b/1 File handle/File handle binary/Update a binary file2.py index 88adeef443f..40f2ba2e6de 100644 --- a/1 File handle/File handle binary/Update a binary file2.py +++ b/1 File handle/File handle binary/Update a binary file2.py @@ -1,30 +1,115 @@ -# updating records in a binary file - +import os import pickle -def update(): +def initialize_file_if_not_exists(file_path: str) -> None: + """ + Check if file exists. If not, create it with an empty list of records. + + Args: + file_path (str): Path to the file. + + Raises: + ValueError: If file_path is empty. + """ + if not file_path: + raise ValueError("File path cannot be empty.") + + directory = os.path.dirname(file_path) + if directory and not os.path.exists(directory): + os.makedirs(directory, exist_ok=True) + + if not os.path.exists(file_path): + with open(file_path, "wb") as f: + pickle.dump([], f) + print(f"Created new file: {file_path}") + + +def update_student_record(file_path: str) -> None: + """ + Update a student's name and marks in the binary file by roll number. + + Args: + file_path (str): Path to the binary file containing student records. + """ + initialize_file_if_not_exists(file_path) + + try: + with open(file_path, "rb+") as f: + # Load existing records + records: list[tuple[int, str, int]] = pickle.load(f) + + if not records: + print("No records found in the file.") + return + + # Get roll number to update + roll_to_update = int(input("Enter roll number to update: ")) + found = False + + # Find and update the record + for i, record in enumerate(records): + if record[0] == roll_to_update: + current_name = record[1] + current_marks = record[2] + + print("\nCurrent Record:") + print(f"Roll: {roll_to_update}") + print(f"Name: {current_name}") + print(f"Marks: {current_marks}") + + new_name = input( + "Enter new name (leave blank to keep current): " + ).strip() + new_marks_input = input( + "Enter new marks (leave blank to keep current): " + ).strip() + + # Update name if provided + if new_name: + records[i] = (record[0], new_name, record[2]) + + # Update marks if provided + if new_marks_input: + try: + new_marks = int(new_marks_input) + if records[i][1] == new_name: # If name was updated + records[i] = (record[0], new_name, new_marks) + else: # If name was not updated + records[i] = (record[0], record[1], new_marks) + except ValueError: + print("Invalid marks input. Marks not updated.") + + print("Record updated successfully.") + found = True + break + + if not found: + print(f"Record with roll number {roll_to_update} not found.") + return - with open("studrec.dat", "rb+") as File: - value = pickle.load(File) - found = False - roll = int(input("Enter the roll number of the record")) - - for i in value: - if roll == i[0]: - print(f"current name {i[1]}") - print(f"current marks {i[2]}") - i[1] = input("Enter the new name") - i[2] = int(input("Enter the new marks")) - found = True + # Rewrite the entire file with updated records + f.seek(0) + pickle.dump(records, f) + f.truncate() # Ensure any remaining data is removed - if not found: - print("Record not found") + # Display updated record + f.seek(0) + updated_records = pickle.load(f) + print("\nUpdated Records:") + print(f"{'ROLL':<8}{'NAME':<15}{'MARKS':<8}") + print("-" * 35) + for record in updated_records: + print(f"{record[0]:<8}{record[1]:<15}{record[2]:<8}") - else: - pickle.dump(value, File) - File.seek(0) - print(pickle.load(File)) + except ValueError: + print("Error: Invalid roll number. Please enter an integer.") + except pickle.UnpicklingError: + print("Error: File content is corrupted and cannot be read.") + except Exception as e: + print(f"An unexpected error occurred: {str(e)}") -update() +if __name__ == "__main__": + FILE_PATH = r"studrec.dat" # Update with your actual file path + update_student_record(FILE_PATH) diff --git a/1 File handle/File handle binary/question 1 (elegible for remedial, top marks).py b/1 File handle/File handle binary/question 1 (elegible for remedial, top marks).py index bf84e9824ec..c39e1b31be5 100644 --- a/1 File handle/File handle binary/question 1 (elegible for remedial, top marks).py +++ b/1 File handle/File handle binary/question 1 (elegible for remedial, top marks).py @@ -1,68 +1,149 @@ -"""Amit is a monitor of class XII-A and he stored the record of all -the students of his class in a file named “class.dat”. -Structure of record is [roll number, name, percentage]. His computer -teacher has assigned the following duty to Amit +import os +import pickle -Write a function remcount( ) to count the number of students who need - remedial class (student who scored less than 40 percent) - - """ -# also find no. of children who got top marks +def initialize_file_if_not_exists(file_path: str) -> None: + """ + Check if the file exists. If not, create it and initialize with an empty list. -import pickle + Args: + file_path (str): Path to the file to check/initialize. + + Raises: + ValueError: If file_path is empty. + """ + if not file_path: + raise ValueError("File path cannot be empty.") + + directory = os.path.dirname(file_path) + if directory and not os.path.exists(directory): + os.makedirs(directory, exist_ok=True) + print(f"Directory created: {directory}") + + if not os.path.exists(file_path): + with open(file_path, "wb") as file: + pickle.dump([], file) + print(f"File initialized: {file_path}") + + +def write_sample_data(file_path: str) -> None: + """ + Write sample student data to the file for demonstration purposes. + + Args: + file_path (str): Path to the file to write data to. + """ + sample_data: list[tuple[int, str, float]] = [ + (1, "Ramya", 30.0), + (2, "Vaishnavi", 60.0), + (3, "Anuya", 40.0), + (4, "Kamala", 30.0), + (5, "Anuraag", 10.0), + (6, "Reshi", 77.0), + (7, "Biancaa.R", 100.0), + (8, "Sandhya", 65.0), + ] + + with open(file_path, "wb") as file: + pickle.dump(sample_data, file) + print(f"Sample data written to {file_path}") + + +def count_remedial_students(file_path: str) -> None: + """ + Count and print students who need remedial classes (percentage < 40). + + Args: + file_path (str): Path to the file containing student records. + """ + initialize_file_if_not_exists(file_path) + + try: + with open(file_path, "rb") as file: + students: list[tuple[int, str, float]] = pickle.load(file) + + remedial_students = [student for student in students if student[2] < 40.0] + + print("\nStudents eligible for remedial classes:") + for student in remedial_students: + print( + f"Roll: {student[0]}, Name: {student[1]}, Percentage: {student[2]:.1f}" + ) + + print(f"\nTotal students needing remedial: {len(remedial_students)}") + + except pickle.UnpicklingError: + print(f"Error: File {file_path} is corrupted.") + except Exception as e: + print(f"Error: {str(e)}") + + +def count_top_scorers(file_path: str) -> None: + """ + Count and print students who achieved the highest percentage. + + Args: + file_path (str): Path to the file containing student records. + """ + initialize_file_if_not_exists(file_path) + + try: + with open(file_path, "rb") as file: + students: list[tuple[int, str, float]] = pickle.load(file) + + if not students: + print("No student records found.") + return -list = [ - [1, "Ramya", 30], - [2, "vaishnavi", 60], - [3, "anuya", 40], - [4, "kamala", 30], - [5, "anuraag", 10], - [6, "Reshi", 77], - [7, "Biancaa.R", 100], - [8, "sandhya", 65], -] + max_percentage = max(student[2] for student in students) + top_scorers = [ + student for student in students if student[2] == max_percentage + ] -with open("class.dat", "ab") as F: - pickle.dump(list, F) - F.close() + print(f"\nTop scorers with {max_percentage:.1f}%:") + for student in top_scorers: + print(f"Roll: {student[0]}, Name: {student[1]}") + print(f"\nTotal top scorers: {len(top_scorers)}") -def remcount(): - with open("class.dat", "rb") as F: - val = pickle.load(F) - count = 0 + except pickle.UnpicklingError: + print(f"Error: File {file_path} is corrupted.") + except Exception as e: + print(f"Error: {str(e)}") - for i in val: - if i[2] <= 40: - print(f"{i} eligible for remedial") - count += 1 - print(f"the total number of students are {count}") +def display_all_students(file_path: str) -> None: + """ + Display all student records. -remcount() + Args: + file_path (str): Path to the file containing student records. + """ + initialize_file_if_not_exists(file_path) + try: + with open(file_path, "rb") as file: + students: list[tuple[int, str, float]] = pickle.load(file) -def firstmark(): - with open("class.dat", "rb") as F: - val = pickle.load(F) - count = 0 - main = [i[2] for i in val] + print("\nAll student records:") + print(f"{'ROLL':<8}{'NAME':<15}{'PERCENTAGE':<12}") + print("-" * 35) - top = max(main) - print(top, "is the first mark") + for student in students: + print(f"{student[0]:<8}{student[1]:<15}{student[2]:<12.1f}") - F.seek(0) - for i in val: - if top == i[2]: - print(f"{i}\ncongrats") - count += 1 + except pickle.UnpicklingError: + print(f"Error: File {file_path} is corrupted.") + except Exception as e: + print(f"Error: {str(e)}") - print("the total number of students who secured top marks are", count) +if __name__ == "__main__": + FILE_PATH = r"1 File handle\File handle binary\class.dat" -firstmark() + # Uncomment below line to write sample data (only needed once) + # write_sample_data(FILE_PATH) -with open("class.dat", "rb") as F: - val = pickle.load(F) - print(val) + count_remedial_students(FILE_PATH) + count_top_scorers(FILE_PATH) + display_all_students(FILE_PATH) diff --git a/1 File handle/File handle binary/search record in binary file.py b/1 File handle/File handle binary/search record in binary file.py index 80d2071134e..e054b617862 100644 --- a/1 File handle/File handle binary/search record in binary file.py +++ b/1 File handle/File handle binary/search record in binary file.py @@ -1,21 +1,70 @@ -# binary file to search a given record - +import os import pickle -def binary_search(): - with open("studrec.dat", "rb") as F: - # your file path will be different - search = 0 - rno = int(input("Enter the roll number of the student")) +def initialize_file_if_not_exists(file_path: str) -> None: + """ + Check if the file exists. If not, create it with an empty list. + + Args: + file_path (str): Path to the file. + + Raises: + ValueError: If file_path is empty. + """ + if not file_path: + raise ValueError("File path cannot be empty") + + directory = os.path.dirname(file_path) + if directory and not os.path.exists(directory): + os.makedirs(directory, exist_ok=True) + + if not os.path.exists(file_path): + with open(file_path, "wb") as f: + pickle.dump([], f) + print(f"Created new file: {file_path}") + + +def search_student_record(file_path: str) -> None: + """ + Search for a student record by roll number in the binary file. + + Args: + file_path (str): Path to the binary file containing student records. + """ + initialize_file_if_not_exists(file_path) + + try: + with open(file_path, "rb") as f: + records: list[tuple[int, str, float]] = pickle.load(f) + + if not records: + print("No records found in the file.") + return + + roll_to_search = int(input("Enter student roll number to search: ")) + found = False + + for record in records: + if record[0] == roll_to_search: + print("\nRecord found:") + print(f"Roll: {record[0]}") + print(f"Name: {record[1]}") + print(f"Percentage: {record[2]:.1f}%") + found = True + break - for i in pickle.load(F): - if i[0] == rno: - print(f"Record found successfully\n{i}") - search = 1 + if not found: + print(f"Record with roll number {roll_to_search} not found.") - if search == 0: - print("Sorry! record not found") + except ValueError: + print("Error: Invalid roll number. Please enter an integer.") + except pickle.UnpicklingError: + print("Error: File content is corrupted and cannot be read.") + except Exception as e: + print(f"An unexpected error occurred: {str(e)}") -binary_search() +if __name__ == "__main__": + FILE_PATH = r"studrec.dat" # Update with your actual file path + search_student_record(FILE_PATH) diff --git a/1 File handle/File handle text/counter.py b/1 File handle/File handle text/counter.py index 1019eeacae8..41de85f24bd 100644 --- a/1 File handle/File handle text/counter.py +++ b/1 File handle/File handle text/counter.py @@ -1,35 +1,117 @@ -""" - Class resposible for counting words for different files: - - Reduce redundant code - - Easier code management/debugging - - Code readability -""" +class TextCounter: + """ + A utility class for counting characters in text or files. -class Counter: + Features: + - Counts lowercase, uppercase, digits, and special characters + - Handles both text input and file reading + - Provides detailed character statistics - def __init__(self, text:str) -> None: - self.text = text + Example usage: + >>> counter = TextCounter("Hello World!") + >>> counter.get_total_lower() + 8 + >>> counter.get_total_upper() + 2 + >>> counter.get_stats() + {'lowercase': 8, 'uppercase': 2, 'digits': 0, 'special': 1, 'total': 11} + """ - # Define the initial count of the lower and upper case. - self.count_lower = 0 - self.count_upper = 0 - self.count() + def __init__(self, content: str, is_file_path: bool = False) -> None: + """ + Initialize the counter with text or file content. - def count(self) -> None: - + Args: + content: Text string or file path + is_file_path: Set to True if content is a file path + + Raises: + FileNotFoundError: If the specified file does not exist + PermissionError: If the file cannot be accessed + UnicodeDecodeError: If the file cannot be decoded properly + """ + self.text: str = self._read_content(content, is_file_path) + self.count_lower: int = 0 + self.count_upper: int = 0 + self.count_digits: int = 0 + self.count_special: int = 0 + self._count_characters() + + def _read_content(self, content: str, is_file_path: bool) -> str: + """ + Read content from file if needed, otherwise return the text directly. + + Args: + content: Text string or file path + is_file_path: Set to True if content is a file path + + Returns: + The content as a string + + Raises: + FileNotFoundError: If the file does not exist + PermissionError: If the file cannot be accessed + UnicodeDecodeError: If the file cannot be decoded properly + """ + if is_file_path: + with open(content, encoding="utf-8") as file: + return file.read() + return content + + def _count_characters(self) -> None: + """ + Count different character types in the text. + + Updates the following attributes: + count_lower: Number of lowercase letters + count_upper: Number of uppercase letters + count_digits: Number of digits + count_special: Number of special characters (non-alphanumeric) + """ for char in self.text: - if char.lower(): + if char.islower(): self.count_lower += 1 - elif char.upper(): + elif char.isupper(): self.count_upper += 1 + elif char.isdigit(): + self.count_digits += 1 + else: + self.count_special += 1 - return (self.count_lower, self.count_upper) - def get_total_lower(self) -> int: + """Return the count of lowercase characters.""" return self.count_lower def get_total_upper(self) -> int: + """Return the count of uppercase characters.""" return self.count_upper + def get_total_digits(self) -> int: + """Return the count of digit characters.""" + return self.count_digits + + def get_total_special(self) -> int: + """Return the count of special characters.""" + return self.count_special + def get_total(self) -> int: - return self.count_lower + self.count_upper \ No newline at end of file + """Return the total count of characters.""" + return ( + self.count_lower + self.count_upper + self.count_digits + self.count_special + ) + + def get_stats(self) -> dict[str, int]: + """ + Return detailed character statistics. + + Returns: + A dictionary containing counts for lowercase, uppercase, + digits, special characters, and the total count. + """ + return { + "lowercase": self.count_lower, + "uppercase": self.count_upper, + "digits": self.count_digits, + "special": self.count_special, + "total": self.get_total(), + } diff --git a/1 File handle/File handle text/file handle 12 length of line in text file.py b/1 File handle/File handle text/file handle 12 length of line in text file.py index d14ef16a4ea..acf5ab6a22b 100644 --- a/1 File handle/File handle text/file handle 12 length of line in text file.py +++ b/1 File handle/File handle text/file handle 12 length of line in text file.py @@ -1,38 +1,182 @@ - import os +import sys import time -file_name= input("Enter the file name to create:- ") +from typing import NoReturn + + +def _get_invalid_filename_chars() -> tuple[str, ...]: + """Return a tuple of invalid filename characters for the current OS.""" + if sys.platform.startswith("win"): + return ("\\", "/", ":", "*", "?", '"', "<", ">", "|") + else: # Linux/macOS + return ("/",) + + +def is_valid_filename(filename: str) -> tuple[bool, str]: + """ + Validate if a filename is valid for the current operating system. + + Args: + filename: Filename to validate + + Returns: + Tuple containing (is_valid: bool, error_message: str) + """ + if not filename.strip(): + return False, "Filename cannot be empty or contain only whitespace" + + invalid_chars = _get_invalid_filename_chars() + for char in filename: + if char in invalid_chars: + return ( + False, + f"Contains invalid character: '{char}' (invalid: {', '.join(invalid_chars)})", + ) + + max_length = 255 if not sys.platform.startswith("win") else 260 + if len(filename) > max_length: + return False, f"Too long (max {max_length} characters)" -print(file_name) + if sys.platform.startswith("win"): + reserved_names = { + "CON", + "PRN", + "AUX", + "NUL", + "COM1", + "COM2", + "COM3", + "COM4", + "COM5", + "COM6", + "COM7", + "COM8", + "COM9", + "LPT1", + "LPT2", + "LPT3", + "LPT4", + "LPT5", + "LPT6", + "LPT7", + "LPT8", + "LPT9", + } + base_name = filename.split(".")[0].upper() + if base_name in reserved_names: + return False, f"'{filename}' is a reserved system name" -def write_to_file(file_name): + return True, "Valid filename" + +def write_to_file(file_name: str) -> None: + """Create a new file and allow user to add content line by line.""" if os.path.exists(file_name): - print(f"Error: {file_name} already exists.") + print(f"Error: File '{file_name}' already exists (preventing overwrite).") return - with open(file_name, "a") as F: + parent_dir = os.path.dirname(file_name) + if parent_dir and not os.path.exists(parent_dir): + print(f"Error: Parent directory '{parent_dir}' does not exist.") + return - while True: - text = input("enter any text to add in the file:- ") - F.write( f"{text}\n" ) - choice = input("Do you want to enter more, y/n").lower() - if choice == "n": - break - -def longlines(): + try: + with open(file_name, "a", encoding="utf-8") as file: + print(f"Created file: '{file_name}'") - with open(file_name, encoding='utf-8') as F: - lines = F.readlines() - lines_less_than_50 = list( filter(lambda line: len(line) < 50, lines ) ) + while True: + text = input("Enter text to add (press Enter to skip): ").rstrip("\n") - if not lines_less_than_50: - print("There is no line which is less than 50") - else: - for i in lines_less_than_50: - print(i, end="\t") + if text: + file.write(f"{text}\n") + print(f"Added: {text}") + else: + print("Note: Empty input will not be written.") -if __name__ == "__main__": + while True: + choice = input("Add more content? (y/n): ").strip().lower() + if choice in ("y", "n"): + break + print("Invalid input. Please enter 'y' or 'n'.") + + if choice == "n": + print("Content writing completed.") + break + + except PermissionError: + print(f"Error: Permission denied for '{file_name}'.") + except OSError as e: + print(f"System error while writing: {str(e)}") + except Exception as e: + print(f"Unexpected error: {str(e)}") + + +def print_short_lines(file_name: str) -> None: + """Read a file and print lines with length < 50 characters (excluding newline).""" + if not os.path.exists(file_name): + print(f"Error: File '{file_name}' does not exist.") + return + + if not os.path.isfile(file_name): + print(f"Error: '{file_name}' is a directory, not a file.") + return + + try: + with open(file_name, encoding="utf-8") as file: + lines: list[str] = file.readlines() + if not lines: + print(f"Info: File '{file_name}' is empty.") + return + + short_lines: list[str] = [ + line for line in lines if len(line.rstrip("\n")) < 50 + ] + + if not short_lines: + print("No lines with length < 50 characters (excluding newline).") + else: + print(f"\nLines in '{file_name}' with length < 50:") + for line_num, line in enumerate(short_lines, 1): + print(f"Line {line_num}: {line.rstrip('\n')}") + + except PermissionError: + print(f"Error: Permission denied to read '{file_name}'.") + except UnicodeDecodeError: + print(f"Error: '{file_name}' is not a valid text file.") + except OSError as e: + print(f"System error while reading: {str(e)}") + except Exception as e: + print(f"Unexpected error: {str(e)}") + + +def get_valid_filename() -> str: + """Prompt user for a filename until a valid one is provided.""" + while True: + file_name = input("Enter the name of the file to create: ").strip() + print(f"Selected filename: '{file_name}'") + + is_valid, msg = is_valid_filename(file_name) + if is_valid: + return file_name + print(f"Invalid filename: {msg}. Please try again.\n") + + +def main() -> NoReturn: + """Main function coordinating file operations with retry for invalid filenames.""" + # Get valid filename with retry mechanism + file_name = get_valid_filename() + + # Write content to file write_to_file(file_name) + + # Brief pause to ensure file operations complete time.sleep(1) - longlines() \ No newline at end of file + + # Read and display short lines + print_short_lines(file_name) + + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/1 File handle/File handle text/input,output and error streams.py b/1 File handle/File handle text/input,output and error streams.py index cecd268979b..8ef094fc6c6 100644 --- a/1 File handle/File handle text/input,output and error streams.py +++ b/1 File handle/File handle text/input,output and error streams.py @@ -1,16 +1,177 @@ -# practicing with streams import sys +from typing import NoReturn -sys.stdout.write("Enter the name of the file") -file = sys.stdin.readline() -with open(file.strip(), ) as F: +def read_and_print_file(file_path: str) -> None: + """ + Read a text file and print its contents line by line. - while True: - ch = F.readlines() - for (i) in ch: # ch is the whole file,for i in ch gives lines, for j in i gives letters,for j in i.split gives words - print(i, end="") - else: - sys.stderr.write("End of file reached") - break + Reads the entire file content, prints each line to standard output, + and sends an "End of file reached" message to standard error upon completion. + Args: + file_path: Path to the text file to be read. + + Raises: + FileNotFoundError: If the specified file does not exist. + PermissionError: If the user lacks permission to read the file. + IsADirectoryError: If the provided path points to a directory instead of a file. + UnicodeDecodeError: If the file contains non-UTF-8 encoded data. + OSError: For other OS-related errors (e.g., disk full). + """ + try: + # Open file in read mode with explicit UTF-8 encoding + with open(file_path, encoding="utf-8") as file: + # Read and print lines in chunks for better memory efficiency + for line in file: + sys.stdout.write(line) + + # Notify end of file via standard error stream + sys.stderr.write("End of file reached\n") + + except FileNotFoundError: + raise # Re-raise for higher-level handling + except PermissionError: + raise + except IsADirectoryError: + raise + except UnicodeDecodeError: + raise + except OSError as e: + # Handle other OS-related errors + raise OSError(f"OS error occurred while reading file: {e}") from e + + +def is_valid_path(path: str) -> bool: + """ + Validate if a given path is syntactically valid. + + Note: This does not check if the file exists, only if the path format is valid. + + Args: + path: Path string to validate + + Returns: + True if the path is syntactically valid, False otherwise + """ + # Basic path validation (platform-independent) + if not path.strip(): + return False + + # Check for invalid characters (simplified version) + invalid_chars = ["\0"] # Null character is invalid on all platforms + if any(c in path for c in invalid_chars): + return False + + # Additional platform-specific checks + if sys.platform.startswith("win"): + # Windows-specific invalid characters + win_invalid = ["<", ">", ":", '"', "/", "\\", "|", "?", "*"] + if any(c in path for c in win_invalid): + return False + + return True + + +def get_valid_file_path() -> str: + """ + Prompt the user for a file path until a valid and non-empty path is provided. + + Returns: + A validated file path string + """ + max_attempts = 5 + attempt = 0 + + while attempt < max_attempts: + attempt += 1 + + # Prompt user for file name/path + sys.stdout.write( + f"Enter the name of the file (attempt {attempt}/{max_attempts}, or 'q' to quit): " + ) + sys.stdout.flush() + + # Read and process input + file_path = sys.stdin.readline().strip() + + # Check for quit command + if file_path.lower() == "q": + sys.stderr.write("Operation cancelled by user.\n") + sys.exit(0) + + # Validate path syntax + if not is_valid_path(file_path): + sys.stderr.write( + "Error: Invalid path syntax. Please enter a valid file path.\n" + ) + continue + + return file_path + + # If max attempts exceeded + sys.stderr.write("Error: Maximum number of attempts reached. Exiting.\n") + exit() + + +def handle_exception(e: Exception, file_path: str) -> None: + """ + Handle exceptions in a centralized manner for better consistency. + + Args: + e: The exception to handle + file_path: Path of the file involved in the exception + """ + error_messages = { + FileNotFoundError: f"Error: File '{file_path}' not found", + PermissionError: f"Error: Permission denied to read '{file_path}'", + IsADirectoryError: f"Error: '{file_path}' is a directory, not a file", + UnicodeDecodeError: f"Error: '{file_path}' contains non-UTF-8 data (not a text file)", + OSError: f"OS Error: {str(e)}", + } + + # Log the exception (optional, but useful for debugging) + # logging.error(f"Exception occurred: {str(e)}", exc_info=True) + + # Determine the appropriate error message + error_type = type(e) + message = error_messages.get(error_type, f"Unexpected error: {str(e)}") + + # Output the error message + sys.stderr.write(f"{message}\n") + + # Optionally provide suggestions based on the error type + if error_type == FileNotFoundError: + sys.stderr.write( + "Suggestion: Check if the file path is correct and the file exists.\n" + ) + elif error_type == PermissionError: + sys.stderr.write( + "Suggestion: Ensure you have the necessary permissions to access the file.\n" + ) + + # Exit with appropriate status code + exit() + + +def main() -> NoReturn: + """ + Main function to handle user input and coordinate file reading. + + Prompts the user for a file path, validates the input, + and triggers the file reading process with robust error handling. + """ + # Get a valid file path from user + file_path = get_valid_file_path() + + try: + read_and_print_file(file_path) + except Exception as e: + handle_exception(e, file_path) + + # Exit successfully if all operations complete + exit() + + +if __name__ == "__main__": + main() diff --git a/1 File handle/File handle text/question 2.py b/1 File handle/File handle text/question 2.py index cbb84fcd13f..6cccba380f3 100644 --- a/1 File handle/File handle text/question 2.py +++ b/1 File handle/File handle text/question 2.py @@ -1,35 +1,93 @@ -""" Write a method/function DISPLAYWORDS() in python to read lines - from a text file STORY.TXT, - using read function -and display those words, which are less than 4 characters. """ +def display_short_words(file_path: str) -> tuple[list[str], int]: + """ + Read a text file and extract words with fewer than 4 characters. + Reads the entire content of the file using the `read()` method, + splits it into words (whitespace-separated), filters words with length < 4, + and returns both the filtered words and their count. -print("Hey!! You can print the word which are less then 4 characters") + Args: + file_path: Path to the text file (e.g., "STORY.TXT") -def display_words(file_path): + Returns: + Tuple containing: + - List of words with fewer than 4 characters + - Count of such words - try: - with open(file_path) as F: - words = F.read().split() - words_less_than_40 = list( filter(lambda word: len(word) < 4, words) ) - - for word in words_less_than_40: - print(word) - - return "The total number of the word's count which has less than 4 characters", (len(words_less_than_40)) - - except FileNotFoundError: - print("File not found") + Raises: + FileNotFoundError: If the specified file does not exist + PermissionError: If the user lacks permission to read the file + IsADirectoryError: If the provided path points to a directory + UnicodeDecodeError: If the file contains non-UTF-8 encoded data + OSError: For other OS-related errors (e.g., invalid path) + """ + # Read entire file content + with open(file_path, encoding="utf-8") as file: + content: str = file.read() -print("Just need to pass the path of your file..") + # Split content into words (handles multiple whitespace characters) + words: list[str] = content.split() -file_path = input("Please, Enter file path: ") + # Filter words with length < 4 using a generator expression for memory efficiency + short_words: list[str] = [word for word in words if len(word) < 4] -if __name__ == "__main__": - - print(display_words(file_path)) - + return short_words, len(short_words) + + +def main() -> None: + """ + Main function to handle user interaction and coordinate the word extraction process. + + Guides the user through inputting a file path, validates inputs, + calls the word extraction function, and displays results with error handling. + """ + print("=== Short Word Extractor ===") + print( + "This program reads a text file and displays words with fewer than 4 characters.\n" + ) + # Get and validate file path input + while True: + file_path: str = input( + "Enter the path to the text file (e.g., 'STORY.TXT'): " + ).strip() + if not file_path: + print("Error: File path cannot be empty. Please try again.\n") + continue + break + + try: + # Extract short words + short_words, count = display_short_words(file_path) + + # Display results + print(f"\nFound {count} words with fewer than 4 characters:") + if short_words: + # Print words in chunks of 10 for readability + for i in range(0, count, 10): + chunk = short_words[i : i + 10] + print(" ".join(chunk)) + else: + print("No words with fewer than 4 characters found.") + + except FileNotFoundError: + print(f"\nError: File '{file_path}' not found. Please check the path.") + except PermissionError: + print( + f"\nError: Permission denied to read '{file_path}'. Check your access rights." + ) + except IsADirectoryError: + print(f"\nError: '{file_path}' is a directory, not a file.") + except UnicodeDecodeError: + print(f"\nError: '{file_path}' is not a valid UTF-8 text file.") + except OSError as e: + print(f"\nSystem error: {str(e)}") + except Exception as e: + print(f"\nUnexpected error: {str(e)}") + finally: + print("\nProgram completed.") +if __name__ == "__main__": + main() diff --git a/1 File handle/File handle text/question 5.py b/1 File handle/File handle text/question 5.py index e8df3730b18..b58eb418e6d 100644 --- a/1 File handle/File handle text/question 5.py +++ b/1 File handle/File handle text/question 5.py @@ -1,38 +1,124 @@ -"""Write a function in python to count the number of lowercase -alphabets present in a text file “happy.txt""" - -import time import os -from counter import Counter +import sys +from typing import NoReturn -print("You will see the count of lowercase, uppercase and total count of alphabets in provided file..") +def count_lowercase_letters(file_path: str) -> tuple[int, int]: + """ + Count lowercase and uppercase alphabetic characters in a text file. -file_path = input("Please, Enter file path: ") + Reads the entire content of the file, iterates through each character, + and counts letters that are lowercase (a-z) and uppercase (A-Z). Non-alphabetic + characters (numbers, symbols, whitespace) are ignored. -if os.path.exists(file_path): - print('The file exists and this is the path:\n',file_path) + Args: + file_path: Path to the text file (e.g., "happy.txt") + Returns: + Tuple containing: + - Count of lowercase letters (a-z) + - Count of uppercase letters (A-Z) -def lowercase(file_path): - try: + Raises: + FileNotFoundError: If the specified file does not exist + PermissionError: If the user lacks permission to read the file + IsADirectoryError: If the path points to a directory instead of a file + UnicodeDecodeError: If the file contains non-UTF-8 encoded data + OSError: For other system-related errors (e.g., invalid path) + """ + lowercase_count: int = 0 + uppercase_count: int = 0 - with open(file_path) as F: - word_counter = Counter(F.read()) - - print(f"The total number of lower case letters are {word_counter.get_total_lower()}") - time.sleep(0.5) - print(f"The total number of upper case letters are {word_counter.get_total_upper()}") - time.sleep(0.5) - print(f"The total number of letters are {word_counter.get_total()}") - time.sleep(0.5) + # Read file content with explicit encoding + with open(file_path, encoding="utf-8") as file: + content: str = file.read() - except FileNotFoundError: - print("File is not exist.. Please check AGAIN") + # Iterate through each character to count letters + for char in content: + if char.islower(): + lowercase_count += 1 + elif char.isupper(): + uppercase_count += 1 + return lowercase_count, uppercase_count +def validate_file_path(file_path: str) -> bool: + """ + Validate if the provided file path points to an existing, readable file. + + Args: + file_path: Path to check + + Returns: + True if the path is valid and points to a readable file; False otherwise + """ + # Check if path is empty + if not file_path.strip(): + print("Error: File path cannot be empty.") + return False + + # Check if file exists + if not os.path.exists(file_path): + print(f"Error: File '{file_path}' does not exist.") + return False + + # Check if path is a file (not directory) + if not os.path.isfile(file_path): + print(f"Error: '{file_path}' is a directory, not a file.") + return False + + # Check if file is readable + if not os.access(file_path, os.R_OK): + print(f"Error: No permission to read '{file_path}'.") + return False + + return True -if __name__ == "__main__": - lowercase(file_path) +def main() -> NoReturn: + """ + Main function to handle user interaction and coordinate the counting process. + + Guides the user to input a file path, validates it, triggers the counting function, + and displays the results with clear formatting. + """ + print("=== Alphabet Case Counter ===") + print( + "This program counts lowercase (a-z) and uppercase (A-Z) letters in a text file.\n" + ) + + # Get and validate file path from user + while True: + file_path: str = input( + "Enter the path to the text file (e.g., 'happy.txt'): " + ).strip() + if validate_file_path(file_path): + break + print("Please try again.\n") + + try: + # Count lowercase and uppercase letters + lowercase_count, uppercase_count = count_lowercase_letters(file_path) + + # Display results + print(f"\nStatistics for '{os.path.basename(file_path)}':") + print(f"Lowercase letters (a-z): {lowercase_count}") + print(f"Uppercase letters (A-Z): {uppercase_count}") + print(f"Total alphabetic letters: {lowercase_count + uppercase_count}") + + except UnicodeDecodeError: + print( + f"\nError: '{file_path}' contains non-UTF-8 data. Cannot read as text file." + ) + except OSError as e: + print(f"\nSystem error: {str(e)}") + except Exception as e: + print(f"\nUnexpected error: {str(e)}") + finally: + print("\nOperation completed.") + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/1 File handle/File handle text/question 6.py b/1 File handle/File handle text/question 6.py index 467ea401995..81aa5d5c4af 100644 --- a/1 File handle/File handle text/question 6.py +++ b/1 File handle/File handle text/question 6.py @@ -1,16 +1,52 @@ -"""Write a function in python to count the number of lowercase -alphabets present in a text file “happy.txt”""" +from collections import Counter +from pathlib import Path -from counter import Counter -def lowercase(): +def count_lowercase_chars(file_path: str | Path = "happy.txt") -> tuple[int, int, int]: + """ + Counts the number of lowercase letters, uppercase letters, and total alphabetic characters in a text file. + + Args: + file_path (str | Path): Path to the text file. Defaults to "happy.txt". + + Returns: + tuple[int, int, int]: A tuple containing the count of lowercase letters, uppercase letters, and total alphabetic characters. + + Raises: + FileNotFoundError: If the specified file does not exist. + PermissionError: If the file cannot be accessed. + """ + try: + with open(file_path, encoding="utf-8") as file: + content = file.read() + Counter(content) + + lowercase_count = sum(1 for char in content if char.islower()) + uppercase_count = sum(1 for char in content if char.isupper()) + total_letters = lowercase_count + uppercase_count + + return lowercase_count, uppercase_count, total_letters + except FileNotFoundError: + raise FileNotFoundError(f"File '{file_path}' not found.") + except PermissionError: + raise PermissionError(f"Permission denied to read '{file_path}'.") + + +def main() -> None: + """Main function to execute the character counting and display results.""" + try: + file_path = Path("happy.txt") + lowercase, uppercase, total = count_lowercase_chars(file_path) + + print(f"The total number of lowercase letters is: {lowercase}") + print(f"The total number of uppercase letters is: {uppercase}") + print(f"The total number of alphabetic characters is: {total}") + + except (FileNotFoundError, PermissionError) as e: + print(f"Error: {e}") + except Exception as e: + print(f"An unexpected error occurred: {e}") - with open("happy.txt") as F: - word_counter = Counter(F.read()) - - print(f"The total number of lower case letters are {word_counter.get_total_lower()}") - print(f"The total number of upper case letters are {word_counter.get_total_upper()}") - print(f"The total number of letters are {word_counter.get_total()}") if __name__ == "__main__": - lowercase() + main() diff --git a/1 File handle/File handle text/question3.py b/1 File handle/File handle text/question3.py index bc05c22561d..f6c8c5a8c1e 100644 --- a/1 File handle/File handle text/question3.py +++ b/1 File handle/File handle text/question3.py @@ -1,46 +1,69 @@ -"""Write a user-defined function named count() that will read -the contents of text file named “happy.txt” and count -the number of lines which starts with either “I‟ or “M‟.""" +from pathlib import Path -import os -import time -file_name= input("Enter the file name to create:- ") -# step1: -print(file_name) +def count_lowercase_chars(file_path: str | Path) -> tuple[int, int, int]: + """ + Counts lowercase, uppercase, and total alphabetic characters in a text file. + Args: + file_path: Path to the text file (can be a string or Path object). + Returns: + Tuple containing (lowercase count, uppercase count, total alphabetic count). -def write_to_file(file_name): + Raises: + FileNotFoundError: If the file does not exist at the specified path. + PermissionError: If access to the file is denied. + IsADirectoryError: If the path points to a directory instead of a file. + """ + # Convert to Path object for consistent path handling + file_path = Path(file_path) - if os.path.exists(file_name): - print(f"Error: {file_name} already exists.") + # Check if file exists + if not file_path.exists(): + raise FileNotFoundError(f"File does not exist: {file_path}") - else: - with open(file_name, "a") as F: + # Check if it's a file (not a directory) + if not file_path.is_file(): + raise IsADirectoryError(f"Path is a directory, not a file: {file_path}") - while True: - text = input("enter any text") - F.write(f"{text}\n") + # Read file and count characters + with open(file_path, encoding="utf-8") as file: + content = file.read() + lowercase = sum(1 for c in content if c.islower()) + uppercase = sum(1 for c in content if c.isupper()) + total_alpha = lowercase + uppercase - if input("do you want to enter more, y/n").lower() == "n": - break - -# step2: -def check_first_letter(): - with open(file_name) as F: - lines = F.read().split() + return lowercase, uppercase, total_alpha - # store all starting letters from each line in one string after converting to lower case - first_letters = "".join([line[0].lower() for line in lines]) - count_i = first_letters.count("i") - count_m = first_letters.count("m") +def main() -> None: + """Main function to execute the file check and character counting.""" + # Specify the path to happy.txt (update this to your actual path!) + # Example for Windows: r"C:\Users\YourName\1 File handle\File handle text\happy.txt" + # Example for macOS/Linux: "/home/YourName/1 File handle/File handle text/happy.txt" + file_path = r"1 File handle\File handle text\happy.txt" # Update this path! + + try: + # Print current working directory for debugging + print(f"Current working directory: {Path.cwd()}") + + lowercase, uppercase, total_alpha = count_lowercase_chars(file_path) + + print("\n=== Character Count Results ===") + print(f"Lowercase letters: {lowercase}") + print(f"Uppercase letters: {uppercase}") + print(f"Total alphabetic characters: {total_alpha}") + + except FileNotFoundError as e: + print(f"\nError: {e}. Please check the file path.") + except IsADirectoryError as e: + print(f"\nError: {e}") + except PermissionError: + print(f"\nError: No permission to access {file_path}") + except Exception as e: + print(f"\nUnexpected error: {e}") - print(f"The total number of sentences starting with I or M are {count_i + count_m}") if __name__ == "__main__": - - write_to_file(file_name) - time.sleep(1) - check_first_letter() + main() diff --git a/1 File handle/File handle text/special symbol after word.py b/1 File handle/File handle text/special symbol after word.py index 1e23af6bddb..41e4a72d483 100644 --- a/1 File handle/File handle text/special symbol after word.py +++ b/1 File handle/File handle text/special symbol after word.py @@ -1,11 +1,73 @@ -with open("happy.txt", "r") as F: - # method 1 - for i in F.read().split(): - print(i, "*", end="") - print("\n") - - # method 2 - F.seek(0) - for line in F.readlines(): - for word in line.split(): - print(word, "*", end="") +from pathlib import Path + + +def print_words_with_asterisk(file_path: str | Path | None = None) -> None: + """ + Reads a text file and prints each word followed by an asterisk (*) using two methods. + Handles file paths with spaces and subdirectories. + + Args: + file_path (str | Path, optional): Path to the text file. + Defaults to "1 File handle/File handle text/happy.txt" if not specified. + + Raises: + FileNotFoundError: If the file does not exist at the specified path. + IsADirectoryError: If the path points to a directory instead of a file. + PermissionError: If read access to the file is denied. + """ + # Set default path if not provided (handles spaces and subdirectories) + if file_path is None: + file_path = Path("1 File handle/File handle text/happy.txt") + else: + file_path = Path(file_path) # Convert to Path object for consistent handling + + # Validate the file path + if not file_path.exists(): + raise FileNotFoundError(f"File does not exist: {file_path.resolve()}") + if not file_path.is_file(): + raise IsADirectoryError( + f"Path is a directory, not a file: {file_path.resolve()}" + ) + + try: + with open(file_path, encoding="utf-8") as file: + print( + f"Processing file: {file_path.resolve()}\n" + ) # Show absolute path for verification + + # Method 1: Split entire file content into words + content = file.read() + words = content.split() + + print("Method 1 Output:") + for word in words: + print(f"{word}*", end="") + print("\n") # Newline after method 1 output + + # Reset file pointer to start for method 2 + file.seek(0) + + # Method 2: Process line by line, then split lines into words + print("Method 2 Output:") + for line in file: + line_words = line.split() + for word in line_words: + print(f"{word}*", end="") + print() # Final newline after all output + + except PermissionError: + raise PermissionError(f"Permission denied: Cannot read {file_path.resolve()}") + + +if __name__ == "__main__": + try: + # You can explicitly pass the path if needed, e.g.: + # custom_path = r"C:\Full\Path\To\1 File handle\File handle text\happy.txt" # Windows + # print_words_with_asterisk(custom_path) + + # Use default path (works for relative paths) + print_words_with_asterisk() + except (FileNotFoundError, IsADirectoryError, PermissionError) as e: + print(f"Error: {e}") + except Exception as e: + print(f"Unexpected error: {e}") diff --git a/8_puzzle.py b/8_puzzle.py index 630cc12dd21..d25632bf17d 100644 --- a/8_puzzle.py +++ b/8_puzzle.py @@ -1,5 +1,6 @@ from queue import PriorityQueue + class PuzzleState: def __init__(self, board, goal, moves=0, previous=None): self.board = board @@ -35,10 +36,13 @@ def neighbors(self): if 0 <= nx < 3 and 0 <= ny < 3: new_board = [row[:] for row in self.board] new_board[x][y], new_board[nx][ny] = new_board[nx][ny], new_board[x][y] - neighbors.append(PuzzleState(new_board, self.goal, self.moves + 1, self)) + neighbors.append( + PuzzleState(new_board, self.goal, self.moves + 1, self) + ) return neighbors + def solve_puzzle(initial_board, goal_board): initial_state = PuzzleState(initial_board, goal_board) frontier = PriorityQueue() @@ -59,6 +63,7 @@ def solve_puzzle(initial_board, goal_board): return None + def print_solution(solution): steps = [] while solution: @@ -68,21 +73,14 @@ def print_solution(solution): for step in steps: for row in step: - print(' '.join(map(str, row))) + print(" ".join(map(str, row))) print() + # Example usage -initial_board = [ - [1, 2, 3], - [4, 0, 5], - [7, 8, 6] -] - -goal_board = [ - [1, 2, 3], - [4, 5, 6], - [7, 8, 0] -] +initial_board = [[1, 2, 3], [4, 0, 5], [7, 8, 6]] + +goal_board = [[1, 2, 3], [4, 5, 6], [7, 8, 0]] solution = solve_puzzle(initial_board, goal_board) if solution: diff --git a/AI Game/Tic-Tac-Toe-AI/tictactoe.py b/AI Game/Tic-Tac-Toe-AI/tictactoe.py index 0cd5bd0dc36..410f7f35567 100644 --- a/AI Game/Tic-Tac-Toe-AI/tictactoe.py +++ b/AI Game/Tic-Tac-Toe-AI/tictactoe.py @@ -1,104 +1,933 @@ -from tkinter import messagebox #provides a different set of dialogues that are used to display message boxes +import logging +import random +import time +from tkinter import messagebox +from typing import Literal + import customtkinter as ctk -import customtkinter as messagebox -def check_winner(board, player): - # Check rows, columns, and diagonals for a win - for i in range(3): - if all(board[i][j] == player for j in range(3)) or all(board[j][i] == player for j in range(3)): + +# Configure logging for error tracking +logging.basicConfig( + level=logging.INFO, + format="%(asctime)s - %(levelname)s - %(message)s", + handlers=[logging.FileHandler("tictactoe.log"), logging.StreamHandler()], +) + +# -------------------- Core Configuration -------------------- +ctk.set_appearance_mode("System") # Default to system appearance +ctk.set_default_color_theme("blue") # Modern blue theme + +# -------------------- Game Modes -------------------- +MODE_EASY = "Easy" +MODE_HARD = "Hard" + + +class TicTacToe: + """ + A modern Tic-Tac-Toe game with AI opponent, featuring: + + - Smooth animations for moves, wins, and resets + - Dark/light mode toggle support + - Adjustable difficulty (Easy/Hard) + - Optimized AI with minimax algorithm + - Robust error handling and boundary checks + - Responsive, modern UI design + + The game follows standard Tic-Tac-Toe rules where the first player to get + three of their marks in a row (horizontally, vertically, or diagonally) wins. + Human player is 'X' and AI is 'O'. + """ + + def __init__(self, master: ctk.CTk) -> None: + """ + Initialize the Tic-Tac-Toe game. + + Args: + master: The parent Tkinter/CTkinter window + """ + self.master = master + self.master.title("Tic Tac Toe AI") + self.master.geometry("500x650") + self.master.resizable(False, False) + + # Game state initialization + self.HUMAN: Literal["X"] = "X" + self.AI: Literal["O"] = "O" + self.EMPTY: Literal[" "] = " " + self.BOARD_SIZE: int = 3 # 3x3 grid + self.game_over: bool = False + self.winning_cells: list[tuple[int, int]] = [] + self.game_mode: str = MODE_HARD # Default to hard mode + + # Precompute winning lines for faster checks + self.winning_lines: list[list[tuple[int, int]]] = self._get_winning_lines() + + # UI Style Configuration - Modern, cohesive design + self.STYLES = { + "empty": ("#F0F4F8", "#2D3748"), # Light gray / Dark gray + "human": ("#3182CE", "#4299E1"), # Blue shades + "ai": ("#E53E3E", "#F56565"), # Red shades + "winning": "#ED8936", # Orange for winning line + "draw": "#A0A0A0", # Gray for draw + "button": { + "font": ("Segoe UI", 40, "bold"), + "width": 130, + "height": 130, + "corner_radius": 15, + "hover_color": ("#E2E8F0", "#4A5568"), + "text_color": ("#1A202C", "#F7FAFC"), + "border_width": 2, + "border_color": ("#CBD5E0", "#4A5568"), + }, + "status": { + "font": ("Segoe UI", 20, "bold"), + "text_color": ("#1A202C", "#F7FAFC"), + }, + "mode": { + "font": ("Segoe UI", 14, "bold"), + "width": 130, + "height": 40, + "corner_radius": 10, + }, + "info_button": { + "font": ("Segoe UI", 14, "bold"), + "width": 130, + "height": 40, + "corner_radius": 10, + }, + "footer_button": { + "font": ("Segoe UI", 14, "bold"), + "width": 180, + "height": 50, + "corner_radius": 12, + }, + "frame": { + "corner_radius": 20, + "fg_color": ("#FFFFFF", "#1A202C"), + "border_width": 1, + "border_color": ("#E2E8F0", "#4A5568"), + }, + } + + # Initialize game board and UI components + self._initialize_board() + self._create_header_frame() + self._create_board_widgets() + self._create_footer_frame() + + logging.info("Tic-Tac-Toe game initialized successfully") + + def _initialize_board(self) -> None: + """Initialize the game board matrix with empty cells""" + self.board = [ + [self.EMPTY for _ in range(self.BOARD_SIZE)] for _ in range(self.BOARD_SIZE) + ] + self.buttons: list[ + list[ctk.CTkButton] + ] = [] # Will hold the UI buttons for each cell + + def _get_winning_lines(self) -> list[list[tuple[int, int]]]: + """ + Precompute all possible winning lines (rows, columns, diagonals). + + Returns: + List of lists containing tuples of (row, col) coordinates + for each winning line configuration + """ + lines: list[list[tuple[int, int]]] = [] + # Rows + lines.extend( + [[(i, j) for j in range(self.BOARD_SIZE)] for i in range(self.BOARD_SIZE)] + ) + # Columns + lines.extend( + [[(j, i) for j in range(self.BOARD_SIZE)] for i in range(self.BOARD_SIZE)] + ) + # Diagonals + lines.append([(i, i) for i in range(self.BOARD_SIZE)]) + lines.append([(i, self.BOARD_SIZE - 1 - i) for i in range(self.BOARD_SIZE)]) + return lines + + def _create_header_frame(self) -> None: + """Create header frame with game status and control buttons""" + try: + header_frame = ctk.CTkFrame(self.master, **self.STYLES["frame"]) + header_frame.pack(fill="x", padx=20, pady=15, ipady=10) + + # Configure grid for header layout + header_frame.grid_columnconfigure(0, weight=1) + header_frame.grid_columnconfigure(1, weight=0) + + # Game status display + self.status_label = ctk.CTkLabel( + header_frame, + text="Your Turn (X)", + **self.STYLES["status"], + ) + self.status_label.grid(row=0, column=0, padx=20, pady=10, sticky="w") + + # Control buttons frame + control_frame = ctk.CTkFrame(header_frame, fg_color="transparent") + control_frame.grid(row=0, column=1, padx=10, pady=5) + + # Difficulty mode toggle + self.mode_button = ctk.CTkButton( + control_frame, + text=f"Mode: {self.game_mode}", + **self.STYLES["mode"], + command=self._toggle_mode, + fg_color=("#4299E1", "#3182CE"), + ) + self.mode_button.pack(side="left", padx=(0, 10)) + + # How to play button + self.info_button = ctk.CTkButton( + control_frame, + text="How to Play", + **self.STYLES["info_button"], + command=self._show_instructions, + fg_color=("#38B2AC", "#319795"), + ) + self.info_button.pack(side="left") + except Exception as e: + logging.error(f"Error creating header frame: {str(e)}", exc_info=True) + messagebox.showerror("UI Error", "Failed to create header: " + str(e)) + + def _create_board_widgets(self) -> None: + """Create 3x3 game board with interactive buttons""" + try: + board_frame = ctk.CTkFrame(self.master, **self.STYLES["frame"]) + board_frame.pack(fill="both", expand=True, padx=20, pady=5) + + # Configure grid weights for responsive layout + for i in range(self.BOARD_SIZE): + board_frame.grid_rowconfigure(i, weight=1) + board_frame.grid_columnconfigure(i, weight=1) + + # Create buttons for each cell + for i in range(self.BOARD_SIZE): + row_buttons: list[ctk.CTkButton] = [] + for j in range(self.BOARD_SIZE): + button = ctk.CTkButton( + board_frame, + text=self.EMPTY, + fg_color=self.STYLES["empty"], + **self.STYLES["button"], + command=lambda r=i, c=j: self._handle_cell_click(r, c), + ) + button.grid(row=i, column=j, padx=8, pady=8, sticky="nsew") + row_buttons.append(button) + self.buttons.append(row_buttons) + except Exception as e: + logging.error(f"Error creating board widgets: {str(e)}", exc_info=True) + messagebox.showerror("UI Error", "Failed to create game board: " + str(e)) + + def _create_footer_frame(self) -> None: + """Create footer frame with theme toggle and new game button""" + try: + footer_frame = ctk.CTkFrame(self.master, **self.STYLES["frame"]) + footer_frame.pack(fill="x", padx=20, pady=15, ipady=10) + + # Footer layout with centered buttons + footer_container = ctk.CTkFrame(footer_frame, fg_color="transparent") + footer_container.pack(expand=True, pady=5) + + # Dark/light mode toggle + self.theme_button = ctk.CTkButton( + footer_container, + text="Toggle Dark Mode", + **self.STYLES["footer_button"], + command=self._toggle_theme, + fg_color=("#718096", "#4A5568"), + ) + self.theme_button.pack(side="left", padx=(0, 15)) + + # New game button + self.new_game_button = ctk.CTkButton( + footer_container, + text="New Game", + **self.STYLES["footer_button"], + command=self._reset_game, + fg_color=("#38B2AC", "#319795"), + hover_color=("#319795", "#2C7A7B"), + ) + self.new_game_button.pack(side="left") + except Exception as e: + logging.error(f"Error creating footer frame: {str(e)}", exc_info=True) + messagebox.showerror("UI Error", "Failed to create footer: " + str(e)) + + def _toggle_theme(self) -> None: + """Toggle between light and dark mode""" + try: + current_mode = ctk.get_appearance_mode() + new_mode = "Dark" if current_mode == "Light" else "Light" + ctk.set_appearance_mode(new_mode) + self.theme_button.configure(text=f"Toggle {current_mode} Mode") + logging.info(f"Theme toggled to {new_mode} mode") + except Exception as e: + logging.error(f"Error toggling theme: {str(e)}", exc_info=True) + messagebox.showerror("Theme Error", "Failed to toggle theme: " + str(e)) + + def _toggle_mode(self) -> None: + """Toggle between Easy and Hard difficulty modes""" + try: + self.game_mode = MODE_EASY if self.game_mode == MODE_HARD else MODE_HARD + self.mode_button.configure(text=f"Mode: {self.game_mode}") + messagebox.showinfo("Mode Changed", f"Switched to {self.game_mode} Mode") + logging.info(f"Game mode changed to {self.game_mode}") + except Exception as e: + logging.error(f"Error toggling game mode: {str(e)}", exc_info=True) + messagebox.showerror("Mode Error", "Failed to toggle mode: " + str(e)) + + def _show_instructions(self) -> None: + """Show game instructions in a dialog box""" + try: + instructions = """ + Tic Tac Toe Instructions: + + 1. The game is played on a 3x3 grid. + 2. You are 'X' and the AI is 'O'. + 3. Players take turns placing their marks in empty squares. + 4. The first player to get 3 of their marks in a row + (horizontally, vertically, or diagonally) wins. + 5. If all squares are filled with no winner, the game is a draw. + + Modes: + - Easy: AI makes occasional mistakes (40% chance) + - Hard: AI plays optimally (unbeatable) + """ + messagebox.showinfo("How to Play", instructions) + except Exception as e: + logging.error(f"Error showing instructions: {str(e)}", exc_info=True) + messagebox.showerror("Info Error", "Failed to show instructions: " + str(e)) + + def _handle_cell_click(self, row: int, col: int) -> None: + """ + Handle human player's cell click. + + Args: + row: Row index of the clicked cell (0-2) + col: Column index of the clicked cell (0-2) + """ + try: + # Validate input coordinates + if not (0 <= row < self.BOARD_SIZE and 0 <= col < self.BOARD_SIZE): + logging.warning(f"Invalid cell click: row={row}, col={col}") + return + + # Check if game is over or cell is already occupied + if self.game_over or self.board[row][col] != self.EMPTY: + return + + # Human move with animation + self.board[row][col] = self.HUMAN + self._animate_move(row, col, self.HUMAN) + + # Check game state after human move + if self._check_winner(self.HUMAN): + self._end_game(winner="human") + return + + if self._is_board_full(): + self._end_game(winner=None) + return + + # AI's turn with short delay for better UX + self.status_label.configure(text="AI is thinking...") + self.master.update() # Force UI update + self.master.after(500, self._make_ai_move) # 500ms delay + + except Exception as e: + logging.error(f"Error handling cell click: {str(e)}", exc_info=True) + messagebox.showerror("Game Error", "Error processing move: " + str(e)) + + def _animate_move(self, row: int, col: int, player: Literal["X", "O"]) -> None: + """ + Animate a move with color transition effect. + + Args: + row: Row index of the cell (0-2) + col: Column index of the cell (0-2) + player: Player making the move ("X" for human, "O" for AI) + """ + try: + # Validate coordinates + if not (0 <= row < self.BOARD_SIZE and 0 <= col < self.BOARD_SIZE): + raise ValueError(f"Invalid cell coordinates: ({row}, {col})") + + target_color = ( + self.STYLES["human"] if player == self.HUMAN else self.STYLES["ai"] + ) + start_color = self.STYLES["empty"] + + # Animate color transition over 20 steps + for i in range(21): + current_color = self._interpolate_color( + start_color, target_color, i / 20 + ) + self.buttons[row][col].configure(text=player, fg_color=current_color) + self.master.update() + time.sleep(0.01) # Short delay for smooth animation + + except Exception as e: + logging.error(f"Error animating move: {str(e)}", exc_info=True) + + def _interpolate_color( + self, start: str | tuple[str, str], target: str | tuple[str, str], factor: float + ) -> str: + """ + Interpolate between two colors, handling both string and tuple formats. + + Args: + start: Starting color (either hex string or (light, dark) tuple) + target: Target color (either hex string or (light, dark) tuple) + factor: Interpolation factor (0.0 to 1.0) + + Returns: + Hex string representing the interpolated color + """ + try: + # Determine current theme (light=0, dark=1) + theme_idx = 0 if ctk.get_appearance_mode() == "Light" else 1 + + # Extract colors based on format + if isinstance(start, tuple): + start_color = start[theme_idx] + else: + start_color = start + + if isinstance(target, tuple): + target_color = target[theme_idx] + else: + target_color = target + + # Convert hex to RGB + def hex_to_rgb(h: str) -> tuple[int, int, int]: + h = h.lstrip("#") + if len(h) != 6: + raise ValueError(f"Invalid hex color: {h}") + return (int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16)) + + # Interpolate RGB values + s_r, s_g, s_b = hex_to_rgb(start_color) + t_r, t_g, t_b = hex_to_rgb(target_color) + + # Clamp factor between 0 and 1 + factor = max(0.0, min(1.0, factor)) + + r = int(s_r + (t_r - s_r) * factor) + g = int(s_g + (t_g - s_g) * factor) + b = int(s_b + (t_b - s_b) * factor) + + # Convert back to hex + return f"#{r:02x}{g:02x}{b:02x}" + + except Exception as e: + logging.error(f"Error interpolating color: {str(e)}", exc_info=True) + # Return safe default color + return "#FFFFFF" if ctk.get_appearance_mode() == "Light" else "#000000" + + def _make_ai_move(self) -> None: + """Make AI move with strategy based on difficulty mode""" + try: + if self.game_over: # Double-check game state + return + + best_move = self._find_best_move() + if best_move is not None: + row, col = best_move + + # Validate move coordinates + if not (0 <= row < self.BOARD_SIZE and 0 <= col < self.BOARD_SIZE): + raise ValueError(f"AI calculated invalid move: ({row}, {col})") + + # Make AI move with animation + self.board[row][col] = self.AI + self._animate_move(row, col, self.AI) + + # Check game state after AI move + if self._check_winner(self.AI): + self._end_game(winner="ai") + return + + if self._is_board_full(): + self._end_game(winner=None) + return + + # Update status after valid move + self.status_label.configure(text="Your Turn (X)") + + except Exception as e: + logging.error(f"Error making AI move: {str(e)}", exc_info=True) + self.status_label.configure(text="Error: AI move failed") + messagebox.showerror("AI Error", "AI failed to make a move: " + str(e)) + + def _check_winner(self, player: Literal["X", "O"]) -> bool: + """ + Check if the specified player has won. + + Args: + player: Player to check ("X" for human, "O" for AI) + + Returns: + True if player has a winning line, False otherwise + """ + try: + if player not in (self.HUMAN, self.AI): + raise ValueError(f"Invalid player: {player}") + + # Check all winning lines + for line in self.winning_lines: + if all(self.board[i][j] == player for i, j in line): + self.winning_cells = line # Store winning cells for animation + return True + return False + except Exception as e: + logging.error(f"Error checking winner: {str(e)}", exc_info=True) + return False + + def _is_board_full(self) -> bool: + """ + Check if the board has no empty cells. + + Returns: + True if board is full, False otherwise + """ + try: + # Check if all cells are filled + for i in range(self.BOARD_SIZE): + for j in range(self.BOARD_SIZE): + if self.board[i][j] == self.EMPTY: + return False return True - if all(board[i][i] == player for i in range(3)) or all(board[i][2 - i] == player for i in range(3)): - return True - return False - -def is_board_full(board): - return all(all(cell != ' ' for cell in row) for row in board) - -def minimax(board, depth, is_maximizing): - if check_winner(board, 'X'): - return -1 - if check_winner(board, 'O'): - return 1 - if is_board_full(board): - return 0 - - if is_maximizing: #recursive approach that fills board with Os - max_eval = float('-inf') - for i in range(3): - for j in range(3): - if board[i][j] == ' ': - board[i][j] = 'O' - eval = minimax(board, depth + 1, False) #recursion - board[i][j] = ' ' - max_eval = max(max_eval, eval) - return max_eval - else: #recursive approach that fills board with Xs - min_eval = float('inf') - for i in range(3): - for j in range(3): - if board[i][j] == ' ': - board[i][j] = 'X' - eval = minimax(board, depth + 1, True) #recursion - board[i][j] = ' ' - min_eval = min(min_eval, eval) - return min_eval - -#determines the best move for the current player and returns a tuple representing the position -def best_move(board): - best_val = float('-inf') - best_move = None - - for i in range(3): - for j in range(3): - if board[i][j] == ' ': - board[i][j] = 'O' - move_val = minimax(board, 0, False) - board[i][j] = ' ' - if move_val > best_val: - best_val = move_val - best_move = (i, j) - - return best_move - -def make_move(row, col): - if board[row][col] == ' ': - board[row][col] = 'X' - # in tk we use the config but in customtkinter we use configure for - buttons[row][col].configure(text='X') - if check_winner(board, 'X'): - messagebox.showinfo("Tic-Tac-Toe", "You win!") - root.quit() - elif is_board_full(board): - messagebox.showinfo("Tic-Tac-Toe", "It's a draw!") - root.quit() - else: - ai_move() - else: - messagebox.showerror("Error", "Invalid move") - -#AI's turn to play -def ai_move(): - row, col = best_move(board) - board[row][col] = 'O' - buttons[row][col].configure(text='O') - if check_winner(board, 'O'): - messagebox.showinfo("Tic-Tac-Toe", "AI wins!") - root.quit() - elif is_board_full(board): - messagebox.showinfo("Tic-Tac-Toe", "It's a draw!") - root.quit() -# change old UI code to customtkinter UI -root = ctk.CTk() -root.title("Tic-Tac-Toe") - -board = [[' ' for _ in range(3)] for _ in range(3)] -buttons = [] - -for i in range(3): - row_buttons = [] - for j in range(3): - button = ctk.CTkButton(root, text=' ', font=('normal', 30), width=100, height=100, command=lambda row=i, col=j: make_move(row, col)) - button.grid(row=i, column=j, padx=2, pady=2) - row_buttons.append(button) - buttons.append(row_buttons) - -root.mainloop() + except Exception as e: + logging.error(f"Error checking board fullness: {str(e)}", exc_info=True) + return False # Safe default + + def _end_game(self, winner: Literal["human", "ai"] | None) -> None: + """ + End the game and handle game over state. + + Args: + winner: "human" if human won, "ai" if AI won, None for draw + """ + try: + if self.game_over: # Prevent duplicate calls + return + + self.game_over = True + + # Animate winning cells or draw + if winner: + # Highlight winning line with animation + for i, j in self.winning_cells: + self._animate_winning_cell(i, j) + + # Update status and show message + if winner == "human": + text = "You Win!" + logging.info("Human player won the game") + else: + text = "AI Wins!" + logging.info("AI player won the game") + + self.status_label.configure(text=text) + messagebox.showinfo("Game Over", text) + + else: + # Draw - animate all cells + for i in range(self.BOARD_SIZE): + for j in range(self.BOARD_SIZE): + self._animate_draw_cell(i, j) + + text = "It's a Draw!" + self.status_label.configure(text=text) + messagebox.showinfo("Game Over", text) + logging.info("Game ended in a draw") + + except Exception as e: + logging.error(f"Error ending game: {str(e)}", exc_info=True) + messagebox.showerror( + "Game Over Error", "Failed to end game properly: " + str(e) + ) + + def _animate_winning_cell(self, row: int, col: int) -> None: + """ + Animate winning cells with a pulse effect. + + Args: + row: Row index of the winning cell (0-2) + col: Column index of the winning cell (0-2) + """ + try: + # Validate coordinates + if not (0 <= row < self.BOARD_SIZE and 0 <= col < self.BOARD_SIZE): + raise ValueError(f"Invalid winning cell: ({row}, {col})") + + # Get current color based on theme + theme_idx = 0 if ctk.get_appearance_mode() == "Light" else 1 + original_color = ( + self.STYLES["human"][theme_idx] + if self.board[row][col] == self.HUMAN + else self.STYLES["ai"][theme_idx] + ) + + # Pulse animation - 3 cycles of brightening and dimming + for _ in range(3): + # Brighten + for i in range(11): + factor = 1 + i * 0.1 + self._adjust_button_brightness(row, col, original_color, factor) + self.master.update() + time.sleep(0.03) + + # Dim back + for i in range(10, -1, -1): + factor = 1 + i * 0.1 + self._adjust_button_brightness(row, col, original_color, factor) + self.master.update() + time.sleep(0.03) + + # Set to final winning color + self.buttons[row][col].configure(fg_color=self.STYLES["winning"]) + + except Exception as e: + logging.error(f"Error animating winning cell: {str(e)}", exc_info=True) + + def _animate_draw_cell(self, row: int, col: int) -> None: + """ + Animate draw cells with color transition to gray. + + Args: + row: Row index of the cell (0-2) + col: Column index of the cell (0-2) + """ + try: + # Validate coordinates + if not (0 <= row < self.BOARD_SIZE and 0 <= col < self.BOARD_SIZE): + raise ValueError(f"Invalid draw cell: ({row}, {col})") + + # Get current color based on theme + theme_idx = 0 if ctk.get_appearance_mode() == "Light" else 1 + original_color = ( + self.STYLES["human"][theme_idx] + if self.board[row][col] == self.HUMAN + else self.STYLES["ai"][theme_idx] + ) + + # Transition to draw color + draw_color = self.STYLES["draw"] + + for i in range(21): + factor = i / 20 + current_color = self._interpolate_color( + original_color, draw_color, factor + ) + self.buttons[row][col].configure(fg_color=current_color) + self.master.update() + time.sleep(0.02) + + except Exception as e: + logging.error(f"Error animating draw cell: {str(e)}", exc_info=True) + + def _adjust_button_brightness( + self, row: int, col: int, base_color: str | tuple[str, str], factor: float + ) -> None: + """ + Adjust button brightness for animation effects. + + Args: + row: Row index of the cell (0-2) + col: Column index of the cell (0-2) + base_color: Original color to adjust + factor: Brightness factor (>1 brightens, <1 darkens) + """ + try: + # Validate coordinates + if not (0 <= row < self.BOARD_SIZE and 0 <= col < self.BOARD_SIZE): + raise ValueError( + f"Invalid cell for brightness adjustment: ({row}, {col})" + ) + + # Determine current theme + theme_idx = 0 if ctk.get_appearance_mode() == "Light" else 1 + + # Extract color based on format + if isinstance(base_color, tuple): + color = base_color[theme_idx] + else: + color = base_color + + # Convert hex to RGB + def hex_to_rgb(h: str) -> tuple[int, int, int]: + h = h.lstrip("#") + if len(h) != 6: + raise ValueError(f"Invalid hex color: {h}") + return (int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16)) + + # Convert RGB to hex + def rgb_to_hex(rgb: tuple[int, int, int]) -> str: + return "#%02x%02x%02x" % rgb + + r, g, b = hex_to_rgb(color) + + # Adjust brightness with clamping + def clamp(x: float) -> int: + return max(0, min(255, int(x))) + + new_r = clamp(r * factor) + new_g = clamp(g * factor) + new_b = clamp(b * factor) + + # Update button color + self.buttons[row][col].configure(fg_color=rgb_to_hex((new_r, new_g, new_b))) + + except Exception as e: + logging.error(f"Error adjusting brightness: {str(e)}", exc_info=True) + + def _find_best_move(self) -> tuple[int, int] | None: + """ + Find optimal move for AI based on difficulty mode. + + Returns: + Tuple of (row, col) for best move, or None if no moves available + """ + try: + # Check for immediate win opportunity + for i in range(self.BOARD_SIZE): + for j in range(self.BOARD_SIZE): + if self.board[i][j] == self.EMPTY: + self.board[i][j] = self.AI # Try the move + if self._check_winner(self.AI): + self.board[i][j] = self.EMPTY # Undo + return (i, j) # Return winning move + self.board[i][j] = self.EMPTY # Undo + + # Check for human's immediate win to block + for i in range(self.BOARD_SIZE): + for j in range(self.BOARD_SIZE): + if self.board[i][j] == self.EMPTY: + self.board[i][j] = self.HUMAN # Try human's potential move + if self._check_winner(self.HUMAN): + self.board[i][j] = self.EMPTY # Undo + return (i, j) # Block this move + self.board[i][j] = self.EMPTY # Undo + + # Different strategies based on difficulty + if self.game_mode == MODE_EASY: + # 40% chance of random move in easy mode + if random.random() < 0.4: + random_move = self._get_random_move() + if random_move: + return random_move + + # Hard mode uses minimax algorithm for optimal play + return self._get_minimax_move() + + except Exception as e: + logging.error(f"Error finding best move: {str(e)}", exc_info=True) + return self._get_random_move() # Fallback to random move + + def _get_random_move(self) -> tuple[int, int] | None: + """ + Get a random valid move (for easy mode or error fallback). + + Returns: + Tuple of (row, col) for random move, or None if no moves available + """ + try: + available_moves = [ + (i, j) + for i in range(self.BOARD_SIZE) + for j in range(self.BOARD_SIZE) + if self.board[i][j] == self.EMPTY + ] + + if available_moves: + return random.choice(available_moves) + return None + except Exception as e: + logging.error(f"Error getting random move: {str(e)}", exc_info=True) + return None + + def _get_minimax_move(self) -> tuple[int, int] | None: + """ + Find optimal move using minimax algorithm with alpha-beta pruning. + + Returns: + Tuple of (row, col) for best move, or None if no moves available + """ + try: + best_score = float("-inf") + best_move: tuple[int, int] | None = None + depth_limit = 9 # Full depth for 3x3 board + + # Prefer strategic positions (center, corners, edges) + preferred_moves = [(1, 1)] # Center first + preferred_moves.extend([(0, 0), (0, 2), (2, 0), (2, 2)]) # Corners + preferred_moves.extend([(0, 1), (1, 0), (1, 2), (2, 1)]) # Edges + + for i, j in preferred_moves: + if self.board[i][j] == self.EMPTY: + self.board[i][j] = self.AI # Try the move + # Evaluate with minimax + score = self._minimax( + 0, False, depth_limit, float("-inf"), float("inf") + ) + self.board[i][j] = self.EMPTY # Undo + + if score > best_score: + best_score = score + best_move = (i, j) + + return best_move + except Exception as e: + logging.error(f"Error in minimax calculation: {str(e)}", exc_info=True) + return self._get_random_move() # Fallback to random move + + def _minimax( + self, + depth: int, + is_maximizing: bool, + depth_limit: int, + alpha: float, + beta: float, + ) -> int: + """ + Minimax algorithm with alpha-beta pruning for optimal play. + + Args: + depth: Current recursion depth + is_maximizing: True if AI's turn (maximizing), False if human's (minimizing) + depth_limit: Maximum recursion depth to prevent excessive computation + alpha: Alpha value for pruning + beta: Beta value for pruning + + Returns: + Score evaluation of the current board state + """ + try: + # Base cases + if self._check_winner(self.AI): + return 10 - depth # Positive score for AI win (higher for faster wins) + elif self._check_winner(self.HUMAN): + return ( + -10 + depth + ) # Negative score for human win (less negative for slower wins) + elif self._is_board_full() or depth >= depth_limit: + return 0 # Neutral score for draw or depth limit + + if is_maximizing: + # AI's turn - maximize score + max_score = float("-inf") + for i in range(self.BOARD_SIZE): + for j in range(self.BOARD_SIZE): + if self.board[i][j] == self.EMPTY: + self.board[i][j] = self.AI # Try move + score = self._minimax( + depth + 1, False, depth_limit, alpha, beta + ) + self.board[i][j] = self.EMPTY # Undo + max_score = max(score, max_score) + alpha = max(alpha, score) + if beta <= alpha: + break # Prune this branch + if beta <= alpha: + break # Prune this branch + return max_score + else: + # Human's turn - minimize score + min_score = float("inf") + for i in range(self.BOARD_SIZE): + for j in range(self.BOARD_SIZE): + if self.board[i][j] == self.EMPTY: + self.board[i][j] = self.HUMAN # Try human's move + score = self._minimax( + depth + 1, True, depth_limit, alpha, beta + ) + self.board[i][j] = self.EMPTY # Undo + min_score = min(score, min_score) + beta = min(beta, score) + if beta <= alpha: + break # Prune this branch + if beta <= alpha: + break # Prune this branch + return min_score + except Exception as e: + logging.error(f"Error in minimax recursion: {str(e)}", exc_info=True) + return 0 # Neutral score on error + + def _reset_game(self) -> None: + """Reset game to initial state with animation""" + try: + # Reset game state but keep button references + self.board = [ + [self.EMPTY for _ in range(self.BOARD_SIZE)] + for _ in range(self.BOARD_SIZE) + ] + self.game_over = False + self.winning_cells = [] + + # Animate reset for all cells + for i in range(self.BOARD_SIZE): + for j in range(self.BOARD_SIZE): + self._animate_reset_cell(i, j) + + # Reset status + self.status_label.configure(text="Your Turn (X)") + logging.info("Game reset successfully") + except Exception as e: + logging.error(f"Error resetting game: {str(e)}", exc_info=True) + messagebox.showerror("Reset Error", "Failed to reset game: " + str(e)) + + def _animate_reset_cell(self, row: int, col: int) -> None: + """ + Animate cell reset with fade effect. + + Args: + row: Row index of the cell (0-2) + col: Column index of the cell (0-2) + """ + try: + # Validate coordinates and button existence + if not (0 <= row < self.BOARD_SIZE and 0 <= col < self.BOARD_SIZE): + raise ValueError(f"Invalid cell for reset animation: ({row}, {col})") + + if not (0 <= row < len(self.buttons) and 0 <= col < len(self.buttons[row])): + logging.warning( + f"Button not found at ({row}, {col}) during reset animation" + ) + return # Skip animation for missing button + + # Get current color based on theme + theme_idx = 0 if ctk.get_appearance_mode() == "Light" else 1 + current_color = self.buttons[row][col].cget("fg_color") + + if isinstance(current_color, tuple): + current_color = current_color[theme_idx] + + target_color = self.STYLES["empty"] + + # Fade out over 15 steps + for i in range(16): + factor = 1 - (i / 15) + self._adjust_button_brightness(row, col, current_color, factor) + self.master.update() + time.sleep(0.01) + + # Reset to empty state + self.buttons[row][col].configure(text=self.EMPTY, fg_color=target_color) + except Exception as e: + logging.error(f"Error in reset animation: {str(e)}", exc_info=True) + + +if __name__ == "__main__": + try: + root = ctk.CTk() + app = TicTacToe(root) + root.mainloop() + except Exception as e: + logging.critical(f"Fatal error in main application: {str(e)}", exc_info=True) + messagebox.showerror( + "Fatal Error", "The application could not start: " + str(e) + ) diff --git a/Anonymous_TextApp.py b/Anonymous_TextApp.py index 9b3f5052e88..d55c1891cf9 100644 --- a/Anonymous_TextApp.py +++ b/Anonymous_TextApp.py @@ -1,4 +1,5 @@ import tkinter as tk + from PIL import Image, ImageTk from twilio.rest import Client @@ -10,29 +11,29 @@ body = "" to = "" + def message(): global body, to - account_sid = 'Your_account_sid' # Your account sid - auth_token = 'Your_auth_token' # Your auth token + account_sid = "Your_account_sid" # Your account sid + auth_token = "Your_auth_token" # Your auth token client = Client(account_sid, auth_token) msg = client.messages.create( - from_='Twilio_number', # Twilio number + from_="Twilio_number", # Twilio number body=body, - to=to + to=to, ) print(msg.sid) - confirmation_label.config(text="Message Sent!") - + confirmation_label.config(text="Message Sent!") try: # Load the background image bg_img = Image.open(r"D:\Downloads\img2.png") - - #Canvas widget + + # Canvas widget canvas = tk.Canvas(window, width=800, height=750) canvas.pack(fill="both", expand=True) - + # background image to the Canvas bg_photo = ImageTk.PhotoImage(bg_img) bg_image_id = canvas.create_image(0, 0, image=bg_photo, anchor="nw") @@ -42,33 +43,55 @@ def message(): bg_image_id = canvas.create_image(250, 750, image=bg_photo, anchor="center") bg_image_id = canvas.create_image(850, 750, image=bg_photo, anchor="center") bg_image_id = canvas.create_image(1300, 750, image=bg_photo, anchor="center") - - - + # Foreground Image img = Image.open(r"D:\Downloads\output-onlinepngtools.png") photo = ImageTk.PhotoImage(img) img_label = tk.Label(window, image=photo, anchor="w") - img_label.image = photo - img_label.place(x=10, y=20) - + img_label.image = photo + img_label.place(x=10, y=20) + # Text for number input - canvas.create_text(1050, 300, text="Enter the number starting with +[country code]", font=("Poppins", 18, "bold"), fill="black", anchor="n") - text_field_number = tk.Entry(canvas, width=17, font=("Poppins", 25, "bold"), bg="#404040", fg="white", show="*") + canvas.create_text( + 1050, + 300, + text="Enter the number starting with +[country code]", + font=("Poppins", 18, "bold"), + fill="black", + anchor="n", + ) + text_field_number = tk.Entry( + canvas, + width=17, + font=("Poppins", 25, "bold"), + bg="#404040", + fg="white", + show="*", + ) canvas.create_window(1100, 350, window=text_field_number, anchor="n") - + # Text for message input - canvas.create_text(1050, 450, text="Enter the Message", font=("Poppins", 18, "bold"), fill="black", anchor="n") - text_field_text = tk.Entry(canvas, width=17, font=("Poppins", 25, "bold"), bg="#404040", fg="white") + canvas.create_text( + 1050, + 450, + text="Enter the Message", + font=("Poppins", 18, "bold"), + fill="black", + anchor="n", + ) + text_field_text = tk.Entry( + canvas, width=17, font=("Poppins", 25, "bold"), bg="#404040", fg="white" + ) canvas.create_window(1100, 500, window=text_field_text, anchor="n") - + # label for confirmation message confirmation_label = tk.Label(window, text="", font=("Poppins", 16), fg="green") canvas.create_window(1100, 600, window=confirmation_label, anchor="n") - + except Exception as e: print(f"Error loading image: {e}") + # Function to save input and send message def save_and_send(): global body, to @@ -76,8 +99,9 @@ def save_and_send(): body = str(text_field_text.get()) message() + # Button to save input and send message save_button = tk.Button(window, text="Save and Send", command=save_and_send) -canvas.create_window(1200, 550, window=save_button, anchor='n') +canvas.create_window(1200, 550, window=save_button, anchor="n") -window.mainloop() \ No newline at end of file +window.mainloop() diff --git a/Armstrong_number.py b/Armstrong_number.py index 59732994f81..9c73522992c 100644 --- a/Armstrong_number.py +++ b/Armstrong_number.py @@ -1,24 +1,30 @@ """ -In number theory, a narcissistic number (also known as a pluperfect digital invariant (PPDI), an Armstrong number (after Michael F. Armstrong) or a plus perfect number), +In number theory, a narcissistic number (also known as a pluperfect digital invariant (PPDI), an Armstrong number (after Michael F. Armstrong) or a plus perfect number), in a given number base b, is a number that is the total of its own digits each raised to the power of the number of digits. Source: https://en.wikipedia.org/wiki/Narcissistic_number NOTE: this scripts only works for number in base 10 """ -def is_armstrong_number(number:str): - total:int = 0 - exp:int = len(number) #get the number of digits, this will determinate the exponent - digits:list[int] = [] - for digit in number: digits.append(int(digit)) #get the single digits - for x in digits: total += x ** exp #get the power of each digit and sum it to the total - +def is_armstrong_number(number: str): + total: int = 0 + exp: int = len( + number + ) # get the number of digits, this will determinate the exponent + + digits: list[int] = [] + for digit in number: + digits.append(int(digit)) # get the single digits + for x in digits: + total += x**exp # get the power of each digit and sum it to the total + # display the result if int(number) == total: - print(number,"is an Armstrong number") + print(number, "is an Armstrong number") else: - print(number,"is not an Armstrong number") + print(number, "is not an Armstrong number") + number = input("Enter the number : ") is_armstrong_number(number) diff --git a/Armstrong_number b/Armstrong_number2.py similarity index 80% rename from Armstrong_number rename to Armstrong_number2.py index 7dd1b267ea0..3e73a7528bc 100644 --- a/Armstrong_number +++ b/Armstrong_number2.py @@ -6,8 +6,9 @@ def is_armstrong_number(number): temp = 0 while num != 0: rem = num % 10 - num //= 10 - temp += rem ** length + num //= 10 + temp += rem**length return temp == number - + + is_armstrong_number(5) diff --git a/Assembler/assembler.py b/Assembler/assembler.py index 0acd48b1535..ec520453301 100644 --- a/Assembler/assembler.py +++ b/Assembler/assembler.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import sys lines = [] # contains the lines of the file. @@ -69,866 +67,675 @@ def scanner(string): state = 0 # init state for ch in string: - match state: - case 0: - match ch: - case "m": # catch mov-command - state = 1 token += "m" case "e": # catch register - state = 4 token += "e" case "1": # catch a number - if ch <= "9" or ch == "-": state = 6 token += ch case "0": # catch a number or hex-code - state = 17 token += ch case "a": # catch add-command - state = 7 token += ch case "s": # catch sub command - state = 10 token += ch case "i": # capture int command - state = 14 token += ch case "p": # capture push or pop command - state = 19 token += ch case "l": # capture label - state = 25 token += ch case "j": # capture jmp command - state = 26 token += ch case "c": # catch cmp-command - state = 29 token += ch case ";": # capture comment - state = 33 case '"': # catch a string - state = 34 # without " case ch.isupper(): # capture identifier - state = 35 token += ch case "d": # capture db keyword - state = 36 token += ch case "$": # catch variable with prefix $ - state = 38 # not catching $ case "_": # catch label for subprogram - state = 40 # not catches the character _ case "r": # catch ret-command - state = 44 token += ch case _: # other characters like space-characters etc - state = 0 token = "" case 1: # state 1 - match ch: - case "o": - state = 2 token += ch case "u": - state = 47 token += ch - case _:# error case - + case _: # error case state = 0 token = "" raise InvalidSyntax() - - case 2: # state 2 + case 2: # state 2 match ch: - case "v": - state = 3 token += "v" - case _:# error case - + case _: # error case state = 0 token = "" raise InvalidSyntax() case 3: # state 3 - if ch.isspace(): - state = 0 tokens.append(Token(token, "command")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 4: # state 4 - if ch >= "a" and ch <= "d": - state = 5 token += ch else: # error case - state = 0 token = "" raise InvalidSyntax() case 5: # state 5 - match ch: - case "x": - state = 13 token += ch case _: - state = 0 token = "" raise InvalidSyntax() case 6: # state 6 - if ch.isdigit(): - state = 6 token += ch elif ch.isspace(): - state = 0 tokens.append(Token(token, "value")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 7: # state 7 - match ch: - case "d": - state = 8 token += ch - case _: # error case - + case _: # error case state = 0 token = "" raise InvalidSyntax() case 8: # state 8 - match ch: case "d": - state = 9 token += ch - case _:# error case - + case _: # error case state = 0 token = "" raise InvalidSyntax() case 9: # state 9 - if ch.isspace(): - state = 0 tokens.append(Token(token, "command")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 10: # state 10 - match ch: case "u": - state = 11 token += ch - case _:# error case - + case _: # error case state = 0 token = "" raise InvalidSyntax() case 11: # state 11 - match ch: case "b": - state = 12 token += ch - case _:# error case - + case _: # error case state = 0 token = "" raise InvalidSyntax() case 12: # state 12 - if ch.isspace(): - state = 0 tokens.append(Token(token, "command")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 13: # state 13 - if ch == "," or ch.isspace(): - state = 0 tokens.append(Token(token, "register")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 14: # state 14 - if ch == "n": - state = 15 token += ch else: # error case - state = 0 token = "" raise InvalidSyntax() case 15: # state 15 - if ch == "t": - state = 16 token += ch else: # error case - state = 0 token = "" raise InvalidSyntax() case 16: # state 16 - if ch.isspace(): - state = 0 tokens.append(Token(token, "command")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 17: # state 17 - if ch == "x": - state = 18 token += ch elif ch.isspace(): - state = 0 tokens.append(Token(token, "value")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 18: # state 18 - if ch.isdigit() or (ch >= "a" and ch <= "f"): - state = 18 token += ch elif ch.isspace(): - state = 0 tokens.append(Token(token, "value")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 19: # state 19 - if ch == "u": - state = 20 token += ch elif ch == "o": - state = 23 token += ch else: # error case - state = 0 token = "" raise InvalidSyntax() case 20: # state 20 - if ch == "s": - state = 21 token += ch else: # error case - state = 0 token = "" raise InvalidSyntax() case 21: # state 21 - if ch == "h": - state = 22 token += ch else: # error case - state = 0 token = "" raise InvalidSyntax() case 22: # state 22 - if ch.isspace(): - state = 0 tokens.append(Token(token, "command")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 23: # state 23 - if ch == "p": - state = 24 token += ch else: # error case - state = 0 token = "" raise InvalidSyntax() case 24: # state 24 - if ch.isspace(): - state = 0 tokens.append(Token(token, "command")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 25: # state 25 - if ch.isdigit(): - state = 25 token += ch elif ch == ":" or ch.isspace(): - state = 0 tokens.append(Token(token, "label")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 26: # state 26 - if ch == "m": - state = 27 token += ch elif ch == "e": # catch je command - state = 32 token += ch else: # error case - state = 0 token = "" raise InvalidSyntax() case 27: # state 27 - if ch == "p": - state = 28 token += ch else: # error case - state = 0 token = "" raise InvalidSyntax() case 28: # state 28 - if ch.isspace(): - state = 0 tokens.append(Token(token, "command")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 29: # state 29 - match ch: case "m": - state = 30 token += ch case "a": # catch call-command - state = 41 token += ch case _: # error case - state = 0 token = "" raise InvalidSyntax() case 30: # state 30 - if ch == "p": - state = 31 token += ch else: # error case - state = 0 token = "" raise InvalidSyntax() case 31: # state 31 - token = "" if ch.isspace(): - state = 0 tokens.append(Token(token, "command")) else: # error case - state = 0 raise InvalidSyntax() case 32: # state 32 - token = "" if ch.isspace(): - state = 0 tokens.append(Token(token, "command")) else: # error case - state = 0 raise InvalidSyntax() case 33: # state 33 - if ( ch.isdigit() or ch.isalpha() or (ch.isspace() and ch != "\n") or ch == '"' ): - state = 33 elif ch == "\n": - state = 0 else: # error case - state = 0 token = "" raise InvalidSyntax() case 34: # state 34 - if ch.isdigit() or ch.isalpha() or ch.isspace(): - state = 34 token += ch elif ch == '"': - state = 0 tokens.append(Token(token, "string")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 35: # state 35 - if ch.isdigit() or ch.isupper(): - state = 35 token += ch elif ch == " " or ch == "\n": - state = 0 tokens.append(Token(token, "identifier")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 36: # state 36 - if ch == "b": - state = 37 token += ch elif ch == "i": - state = 49 token += ch else: # error case - state = 0 token = "" raise InvalidSyntax() case 37: # state 37 - if ch.isspace(): - state = 0 tokens.append(Token(token, "command")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 38: # state 38 - if ch.isalpha(): - state = 39 token += ch else: # error case - state = 0 token = "" raise InvalidSyntax() case 39: # state 39 - if ch.isalpha() or ch.isdigit(): - state = 39 token += ch elif ch.isspace(): - state = 0 tokens.append(Token(token, "identifier")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 40: # state 40 - if ( (ch >= "a" and ch <= "z") or (ch >= "A" and ch <= "Z") or (ch >= "0" and ch <= "9") ): - state = 40 token += ch elif ch == ":" or ch.isspace(): - state = 0 tokens.append(Token(token, "subprogram")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 41: # state 41 - match ch: case "l": - state = 42 token += ch - case _:# error case - + case _: # error case state = 0 token = "" raise InvalidSyntax() case 42: # state 42 - match ch: case "l": - state = 43 token += ch - case _:# error case - + case _: # error case state = 0 token = "" raise InvalidSyntax() case 43: # state 43 - if ch.isspace(): - state = 0 tokens.append(Token(token, "command")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 44: # state 44 - match ch: case "e": - state = 45 token += ch - case _:# error case - + case _: # error case state = 0 token = "" raise InvalidSyntax() case 45: # state 45 - match ch: case "t": - state = 46 token += ch - case _:# error case - + case _: # error case state = 0 token = "" raise InvalidSyntax() case 46: # state 46 - if ch.isspace(): - state = 0 tokens.append(Token(token, "command")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 47: # state 47 - match ch: case "l": - state = 48 token += ch - case _:# error case - + case _: # error case state = 0 token = "" raise InvalidSyntax() case 48: # state 48 - if ch.isspace(): - state = 0 tokens.append(Token(token, "command")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() case 49: # state 49 - match ch: case "v": - state = 50 token += ch - case _:# error case - + case _: # error case state = 0 token = "" raise InvalidSyntax() case 50: # state 50 - if ch.isspace(): - state = 0 tokens.append(Token(token, "command")) token = "" else: # error case - state = 0 token = "" raise InvalidSyntax() @@ -962,11 +769,9 @@ def parser(): tmpToken = Token("", "") while pointer < len(tokens): - token = tokens[pointer] if token.token == "mov": # mov commando - # it must follow a register if pointer + 1 < len(tokens): pointer += 1 @@ -977,7 +782,6 @@ def parser(): # TODO use token.t for this stuff if token.t == "register": - tmpToken = token # it must follow a value / string / register / variable @@ -991,7 +795,6 @@ def parser(): # converts the token into float, if token contains only digits. # TODO response of float if token.t == "identifier": # for variables - # check of exists of variable if token.token in variables: token.token = variables[token.token] @@ -1000,7 +803,6 @@ def parser(): return elif token.t == "string": - token.token = str(token.token) elif isinstance(token.token, float): @@ -1032,17 +834,14 @@ def parser(): edx = token.token else: - print("Error: No found register!") return elif token.token == "add": # add commando - pointer += 1 token = tokens[pointer] if token.t == "register": - tmpToken = token if pointer + 1 < len(tokens): @@ -1054,7 +853,6 @@ def parser(): # converts the token into float, if token contains only digits. if token.t == "register": - # for the case that token is register match token.token: case "eax": @@ -1076,7 +874,6 @@ def parser(): return match tmpToken.token: - case "eax": eax += token.token @@ -1084,7 +881,7 @@ def parser(): zeroFlag = False if eax == 0: zeroFlag = True - + case "ebx": ebx += token.token @@ -1092,7 +889,7 @@ def parser(): zeroFlag = False if ebx == 0: zeroFlag = True - + case "ecx": ecx += token.token @@ -1100,7 +897,7 @@ def parser(): zeroFlag = False if ecx == 0: zeroFlag = True - + case "edx": edx += token.token @@ -1110,17 +907,14 @@ def parser(): zeroFlag = True else: - print("Error: Not found register!") return elif token.token == "sub": # sub commando - pointer += 1 token = tokens[pointer] if token.t == "register": - tmpToken = token if pointer + 1 < len(tokens): @@ -1132,7 +926,6 @@ def parser(): # converts the token into float, if token contains only digits. if token.t == "register": - # for the case that token is register if token.token == "eax": token.token = eax @@ -1164,7 +957,7 @@ def parser(): zeroFlag = False elif tmpToken.token == "ebx": ebx -= token.token - + # update zero flag if ebx == 0: zeroFlag = True @@ -1188,12 +981,10 @@ def parser(): zeroFlag = False else: - print("Error: No found register!") return elif token.token == "int": # int commando - tmpToken = token if pointer + 1 < len(tokens): @@ -1204,9 +995,7 @@ def parser(): return if token.token == "0x80": # system interrupt 0x80 - if eax == 1: # exit program - if ebx == 0: print("END PROGRAM") return @@ -1215,15 +1004,12 @@ def parser(): return elif eax == 3: - ecx = float(input(">> ")) elif eax == 4: # output informations - print(ecx) elif token.token == "push": # push commando - tmpToken = token # it must follow a register @@ -1238,7 +1024,6 @@ def parser(): stack.append(token.token) elif token.token == "pop": # pop commando - tmpToken = token # it must follow a register @@ -1264,11 +1049,9 @@ def parser(): edx = stack.pop() elif token.t == "label": # capture label - jumps[token.token] = pointer elif token.token == "jmp": # capture jmp command - # it must follow a label if pointer + 1 < len(tokens): pointer += 1 @@ -1278,7 +1061,6 @@ def parser(): return if token.t == "label": - pointer = jumps[token.token] else: @@ -1296,7 +1078,6 @@ def parser(): return if token.t == "register": - # it must follow a register if pointer + 1 < len(tokens): pointer += 1 @@ -1307,10 +1088,8 @@ def parser(): # actual comparing zeroFlag = setZeroFlag(token.token, tmpToken.token) - elif token.token == "je": - # it must follow a label if pointer + 1 < len(tokens): pointer += 1 @@ -1321,21 +1100,17 @@ def parser(): # check of label if token.t == "label": - # actual jump if zeroFlag: pointer = jumps[token.token] else: - print("Error: Not found label") return elif token.t == "identifier": - # check whether identifier is in variables-table if token.token not in variables: - # it must follow a command if pointer + 1 < len(tokens): pointer += 1 @@ -1345,7 +1120,6 @@ def parser(): return if tmpToken.t == "command" and tmpToken.token == "db": - # it must follow a value (string) if pointer + 1 < len(tokens): pointer += 1 @@ -1355,19 +1129,16 @@ def parser(): return if tmpToken.t == "value" or tmpToken.t == "string": - if tmpToken.t == "value": variables[token.token] = float(tmpToken.token) elif tmpToken.t == "string": variables[token.token] = tmpToken.token else: - print("Error: Not found db-keyword") return elif token.token == "call": # catch the call-command - # it must follow a subprogram label if pointer + 1 < len(tokens): pointer += 1 @@ -1377,41 +1148,32 @@ def parser(): return if token.t == "subprogram": - if token.token in jumps: - # save the current pointer returnStack.append(pointer) # eventuell pointer + 1 # jump to the subprogram pointer = jumps[token.token] else: # error case - print("Error: Unknow subprogram!") return else: # error case - print("Error: Not found subprogram") return elif token.token == "ret": # catch the ret-command - if len(returnStack) >= 1: - pointer = returnStack.pop() else: # error case - print("Error: No return adress on stack") return elif token.t == "subprogram": - pass elif token.token == "mul": # catch mul-command - # it must follow a register if pointer + 1 < len(tokens): pointer += 1 @@ -1421,30 +1183,23 @@ def parser(): return if token.t == "register": - if token.token == "eax": - eax *= eax elif token.token == "ebx": - eax *= ebx elif token.token == "ecx": - eax *= ecx elif token.token == "edx": - eax *= edx else: - print("Error: Not found register") return elif token.token == "div": - # it must follow a register if pointer + 1 < len(tokens): pointer += 1 @@ -1454,7 +1209,6 @@ def parser(): return if token.t == "register": - match token.token: case "eax": eax /= eax @@ -1472,15 +1226,15 @@ def parser(): eax /= edx else: - print("Error: Not found register") return # increment pointer for fetching next token. pointer += 1 + def setZeroFlag(token, tmpToken): - """ return bool for zero flag based on the regToken """ + """return bool for zero flag based on the regToken""" global eax, ebx, ecx, edx # Register in string @@ -1516,14 +1270,13 @@ def setZeroFlag(token, tmpToken): return zeroFlag + def registerLabels(): """ This function search for labels / subprogram-labels and registers this in the 'jumps' list. """ for i in range(len(tokens)): - if tokens[i].t == "label": - jumps[tokens[i].token] = i - elif tokens[i].t == "subprogram": + if tokens[i].t == "label" or tokens[i].t == "subprogram": jumps[tokens[i].token] = i @@ -1560,18 +1313,15 @@ def main(): # [1:] because the first argument is the program itself. for arg in sys.argv[1:]: - resetInterpreter() # resets interpreter mind try: - loadFile(arg) scan() registerLabels() parser() except Exception as e: - print(f"Error: {e}") diff --git a/Assembler/requirements.txt b/Assembler/requirements.txt deleted file mode 100644 index ee239c1bd87..00000000000 --- a/Assembler/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -print_function -sys diff --git a/Audio_Summarizer.py b/Audio_Summarizer.py index 9968fba15dc..8d2a673ae7b 100644 --- a/Audio_Summarizer.py +++ b/Audio_Summarizer.py @@ -1,7 +1,9 @@ -import whisper +import os import re + import openai -import os +import whisper + def transcript_generator(): # Load Whisper model @@ -16,7 +18,9 @@ def transcript_generator(): def provide_summarizer(Text): # Set up Groq OpenAI-compatible API credentials - openai.api_key = os.getenv("OPENAI_API_KEY", "your-api-key-here") # Replace or set in environment + openai.api_key = os.getenv( + "OPENAI_API_KEY", "your-api-key-here" + ) # Replace or set in environment openai.api_base = "https://api.groq.com/openai/v1" # Extract text from the Whisper result @@ -26,13 +30,19 @@ def provide_summarizer(Text): response = openai.ChatCompletion.create( model="llama3-8b-8192", messages=[ - {"role": "system", "content": "You are a helpful assistant who summarizes long text into bullet points."}, - {"role": "user", "content": f"Summarize the following:\n\n{text_to_summarize}"} - ] + { + "role": "system", + "content": "You are a helpful assistant who summarizes long text into bullet points.", + }, + { + "role": "user", + "content": f"Summarize the following:\n\n{text_to_summarize}", + }, + ], ) # Split the response into sentences - summary = re.split(r'(?<=[.!?]) +', response["choices"][0]["message"]["content"]) + summary = re.split(r"(?<=[.!?]) +", response["choices"][0]["message"]["content"]) # Save summary to file with open("summary.txt", "w+", encoding="utf-8") as file: diff --git a/AutoComplete_App/backend.py b/AutoComplete_App/backend.py deleted file mode 100644 index 47e1c7906d6..00000000000 --- a/AutoComplete_App/backend.py +++ /dev/null @@ -1,126 +0,0 @@ -import sqlite3 -import json - -class AutoComplete: - """ - It works by building a `WordMap` that stores words to word-follower-count - ---------------------------- - e.g. To train the following statement: - - It is not enough to just know how tools work and what they worth, - we have got to learn how to use them and to use them well. - And with all these new weapons in your arsenal, we would better - get those profits fired up - - we create the following: - { It: {is:1} - is: {not:1} - not: {enough:1} - enough: {to:1} - to: {just:1, learn:1, use:2} - just: {know:1} - . - . - profits: {fired:1} - fired: {up:1} - } - so the word completion for "to" will be "use". - For optimization, we use another store `WordPrediction` to save the - predictions for each word - """ - - def __init__(self): - """ - Returns - None - Input - None - ---------- - - Initialize database. we use sqlite3 - - Check if the tables exist, if not create them - - maintain a class level access to the database - connection object - """ - self.conn = sqlite3.connect("autocompleteDB.sqlite3", autocommit=True) - cur = self.conn.cursor() - res = cur.execute("SELECT name FROM sqlite_master WHERE name='WordMap'") - tables_exist = res.fetchone() - - if not tables_exist: - self.conn.execute("CREATE TABLE WordMap(name TEXT, value TEXT)") - self.conn.execute('CREATE TABLE WordPrediction (name TEXT, value TEXT)') - cur.execute("INSERT INTO WordMap VALUES (?, ?)", ("wordsmap", "{}",)) - cur.execute("INSERT INTO WordPrediction VALUES (?, ?)", ("predictions", "{}",)) - - def train(self, sentence): - """ - Returns - string - Input - str: a string of words called sentence - ---------- - Trains the sentence. It does this by creating a map of - current words to next words and their counts for each - time the next word appears after the current word - - takes in the sentence and splits it into a list of words - - retrieves the word map and predictions map - - creates the word map and predictions map together - - saves word map and predictions map to the database - """ - cur = self.conn.cursor() - words_list = sentence.split(" ") - - words_map = cur.execute("SELECT value FROM WordMap WHERE name='wordsmap'").fetchone()[0] - words_map = json.loads(words_map) - - predictions = cur.execute("SELECT value FROM WordPrediction WHERE name='predictions'").fetchone()[0] - predictions = json.loads(predictions) - - for idx in range(len(words_list)-1): - curr_word, next_word = words_list[idx], words_list[idx+1] - if curr_word not in words_map: - words_map[curr_word] = {} - if next_word not in words_map[curr_word]: - words_map[curr_word][next_word] = 1 - else: - words_map[curr_word][next_word] += 1 - - # checking the completion word against the next word - if curr_word not in predictions: - predictions[curr_word] = { - 'completion_word': next_word, - 'completion_count': 1 - } - else: - if words_map[curr_word][next_word] > predictions[curr_word]['completion_count']: - predictions[curr_word]['completion_word'] = next_word - predictions[curr_word]['completion_count'] = words_map[curr_word][next_word] - - words_map = json.dumps(words_map) - predictions = json.dumps(predictions) - - cur.execute("UPDATE WordMap SET value = (?) WHERE name='wordsmap'", (words_map,)) - cur.execute("UPDATE WordPrediction SET value = (?) WHERE name='predictions'", (predictions,)) - return("training complete") - - def predict(self, word): - """ - Returns - string - Input - string - ---------- - Returns the completion word of the input word - - takes in a word - - retrieves the predictions map - - returns the completion word of the input word - """ - cur = self.conn.cursor() - predictions = cur.execute("SELECT value FROM WordPrediction WHERE name='predictions'").fetchone()[0] - predictions = json.loads(predictions) - completion_word = predictions[word.lower()]['completion_word'] - return completion_word - - - -if __name__ == "__main__": - input_ = "It is not enough to just know how tools work and what they worth,\ - we have got to learn how to use them and to use them well. And with\ - all these new weapons in your arsenal, we would better get those profits fired up" - ac = AutoComplete() - ac.train(input_) - print(ac.predict("to")) \ No newline at end of file diff --git a/AutoComplete_App/backendgui.py b/AutoComplete_App/backendgui.py new file mode 100644 index 00000000000..d894114eae2 --- /dev/null +++ b/AutoComplete_App/backendgui.py @@ -0,0 +1,199 @@ +""" +Autocomplete System using SQLite3 for Persistence with N-gram optimization + +This module implements an autocomplete system that learns word sequences from training sentences +and predicts the most likely next word based on the learned patterns. It uses SQLite3 for +persistent storage of word mappings and predictions. +""" + +import json +import sqlite3 + + +class AutoComplete: + """ + An autocomplete system that trains on text data and predicts subsequent words using N-gram model. + + The system works by: + 1. Building N-gram maps that track how often each N-gram is followed by another word + 2. Maintaining predictions for the most likely next word for each N-gram + 3. Storing all data in an SQLite database for persistence + """ + + def __init__(self, n=2) -> None: + """ + Initialize the AutoComplete system and set up the database. + + Creates an SQLite database connection and initializes required tables + (NGramMap and NGramPrediction) if they don't already exist. These tables + store the N-gram transition mappings and precomputed predictions respectively. + """ + self.n = n + # Establish database connection with autocommit enabled + self.conn: sqlite3.Connection = sqlite3.connect( + "autocompleteDB.sqlite3", autocommit=True + ) + cursor: sqlite3.Cursor = self.conn.cursor() + + # Check if tables exist + cursor.execute("SELECT name FROM sqlite_master WHERE name='NGramMap'") + tables_exist: tuple[str] | None = cursor.fetchone() + + if not tables_exist: + # Create tables if they don't exist + cursor.execute("CREATE TABLE NGramMap(name TEXT, value TEXT)") + cursor.execute("CREATE TABLE NGramPrediction(name TEXT, value TEXT)") + + # Initialize with empty dictionaries + cursor.execute("INSERT INTO NGramMap VALUES (?, ?)", ("ngramsmap", "{}")) + cursor.execute( + "INSERT INTO NGramPrediction VALUES (?, ?)", ("ngrampredictions", "{}") + ) + + def generate_ngrams(self, words_list: list[str]) -> list[tuple[str]]: + """ + Generate N-grams from a list of words. + """ + ngrams = [] + for i in range(len(words_list) - self.n + 1): + ngrams.append(tuple(words_list[i : i + self.n])) + return ngrams + + def train(self, sentence: str) -> str: + """ + Train the autocomplete system with a single sentence. + + Processes the input sentence to update: + 1. N-gram transition counts (NGramMap) + 2. Most likely next word predictions (NGramPrediction) + + Args: + sentence: A string containing the training text. Words should be space-separated. + + Returns: + Confirmation message indicating training completion. + """ + cursor: sqlite3.Cursor = self.conn.cursor() + + # Split sentence into individual words + words_list: list[str] = sentence.split(" ") + + # Retrieve existing N-gram map and predictions from database + cursor.execute("SELECT value FROM NGramMap WHERE name='ngramsmap'") + ngrams_map_str: str = cursor.fetchone()[0] + ngrams_map: dict[tuple[str], dict[str, int]] = json.loads( + ngrams_map_str, + object_hook=lambda d: {tuple(k.split()): v for k, v in d.items()}, + ) + + cursor.execute( + "SELECT value FROM NGramPrediction WHERE name='ngrampredictions'" + ) + predictions_str: str = cursor.fetchone()[0] + predictions: dict[tuple[str], dict[str, str | int]] = json.loads( + predictions_str, + object_hook=lambda d: {tuple(k.split()): v for k, v in d.items()}, + ) + + # Generate N-grams + ngrams = self.generate_ngrams(words_list) + + # Process each N-gram and the next word + for i in range(len(ngrams) - 1): + curr_ngram: tuple[str] = ngrams[i] + next_word: str = words_list[i + self.n] + + # Update N-gram transition counts + if curr_ngram not in ngrams_map: + ngrams_map[curr_ngram] = {} + + if next_word not in ngrams_map[curr_ngram]: + ngrams_map[curr_ngram][next_word] = 1 + else: + ngrams_map[curr_ngram][next_word] += 1 + + # Update predictions with most frequent next word + if curr_ngram not in predictions: + predictions[curr_ngram] = { + "completion_word": next_word, + "completion_count": 1, + } + else: + # Update if current next word is more frequent + if ( + ngrams_map[curr_ngram][next_word] + > predictions[curr_ngram]["completion_count"] + ): + predictions[curr_ngram]["completion_word"] = next_word + predictions[curr_ngram]["completion_count"] = ngrams_map[ + curr_ngram + ][next_word] + + # Save updated data back to database + updated_ngrams_map: str = json.dumps( + {" ".join(k): v for k, v in ngrams_map.items()} + ) + updated_predictions: str = json.dumps( + {" ".join(k): v for k, v in predictions.items()} + ) + + cursor.execute( + "UPDATE NGramMap SET value = ? WHERE name='ngramsmap'", + (updated_ngrams_map,), + ) + cursor.execute( + "UPDATE NGramPrediction SET value = ? WHERE name='ngrampredictions'", + (updated_predictions,), + ) + + return "training complete" + + def predict(self, words: str) -> str | None: + """ + Predict the most likely next word for a given input sequence of words. + + Args: + words: The input sequence of words to generate a completion for. + + Returns: + The most likely next word, or None if no prediction exists. + + Raises: + KeyError: If the input sequence of words has no entries in the prediction database. + """ + cursor: sqlite3.Cursor = self.conn.cursor() + + # Retrieve predictions from database + cursor.execute( + "SELECT value FROM NGramPrediction WHERE name='ngrampredictions'" + ) + predictions_str: str = cursor.fetchone()[0] + predictions: dict[tuple[str], dict[str, str | int]] = json.loads( + predictions_str, + object_hook=lambda d: {tuple(k.split()): v for k, v in d.items()}, + ) + + input_words = words.lower().split() + for i in range(len(input_words), max(0, len(input_words) - self.n + 1), -1): + curr_ngram = tuple(input_words[i - self.n : i]) + if curr_ngram in predictions: + return str(predictions[curr_ngram]["completion_word"]) + return None + + +if __name__ == "__main__": + # Example usage + training_sentence: str = ( + "It is not enough to just know how tools work and what they worth, " + "we have got to learn how to use them and to use them well. And with " + "all these new weapons in your arsenal, we would better get those profits fired up" + ) + + # Initialize and train the autocomplete system + autocomplete: AutoComplete = AutoComplete(n=2) + autocomplete.train(training_sentence) + + # Test prediction + test_words: str = "to use" + prediction: str | None = autocomplete.predict(test_words) + print(f"Prediction for '{test_words}': {prediction}") diff --git a/AutoComplete_App/frontend.py b/AutoComplete_App/frontend.py index b7b78220747..8e836435981 100644 --- a/AutoComplete_App/frontend.py +++ b/AutoComplete_App/frontend.py @@ -1,36 +1,80 @@ -from tkinter import * -import backend +""" +Autocomplete System GUI with N-gram optimization +A graphical user interface for interacting with the autocomplete system. +This interface allows users to train the system with text and get word predictions. +""" -def train(): - sentence = train_entry.get() - ac = backend.AutoComplete() - ac.train(sentence) +from tkinter import Button, Entry, Label, Tk + +from backendgui import AutoComplete + + +def train() -> None: + """ + Train the autocomplete system with the text from the training entry field. + + Retrieves the input sentence from the training Entry widget, + creates an instance of AutoComplete, and trains the system with the sentence. + """ + sentence: str = train_entry.get() + if sentence.strip(): + autocomplete: AutoComplete = AutoComplete(n=2) + result: str = autocomplete.train(sentence) + print(result) + else: + print("Please enter a non-empty sentence for training.") + + +def predict_word() -> None: + """ + Get prediction for the word from the prediction entry field. + + Retrieves the input word sequence from the prediction Entry widget, + uses the autocomplete system to get the most likely next word, + and prints the result. + """ + words: str = predict_word_entry.get() + if words.strip(): + autocomplete: AutoComplete = AutoComplete(n=2) + prediction: str | None = autocomplete.predict(words) + if prediction: + print(f"Prediction for '{words}': {prediction}") + else: + print(f"No prediction available for '{words}'.") + else: + print("Please enter a non-empty word sequence for prediction.") -def predict_word(): - word = predict_word_entry.get() - ac = backend.AutoComplete() - print(ac.predict(word)) if __name__ == "__main__": - root = Tk() - root.title("Input note") - root.geometry('300x300') + root: Tk = Tk() + root.title("Autocomplete System") + root.geometry("400x300") + + root.grid_rowconfigure(0, weight=1) + root.grid_rowconfigure(1, weight=1) + root.grid_rowconfigure(2, weight=1) + root.grid_rowconfigure(3, weight=1) + root.grid_columnconfigure(0, weight=1) + + train_label: Label = Label(root, text="Enter text to train:") + train_label.grid(row=0, column=0, padx=10, pady=5, sticky="w") + + train_entry: Entry = Entry(root, width=50) + train_entry.grid(row=1, column=0, padx=10, pady=5, sticky="ew") - train_label = Label(root, text="Train") - train_label.pack() - train_entry = Entry(root) - train_entry.pack() + train_button: Button = Button(root, text="Train System", command=train) + train_button.grid(row=2, column=0, padx=10, pady=5, sticky="ew") - train_button = Button(root, text="train", command=train) - train_button.pack() + predict_word_label: Label = Label( + root, text="Enter word sequence to predict next term:" + ) + predict_word_label.grid(row=3, column=0, padx=10, pady=5, sticky="w") - predict_word_label = Label(root, text="Input term to predict") - predict_word_label.pack() - predict_word_entry = Entry(root) - predict_word_entry.pack() + predict_word_entry: Entry = Entry(root, width=50) + predict_word_entry.grid(row=4, column=0, padx=10, pady=5, sticky="ew") - predict_button = Button(root, text="predict", command=predict_word) - predict_button.pack() + predict_button: Button = Button(root, text="Get Prediction", command=predict_word) + predict_button.grid(row=5, column=0, padx=10, pady=5, sticky="ew") - root.mainloop() \ No newline at end of file + root.mainloop() diff --git a/Automated Scheduled Call Reminders/caller.py b/Automated Scheduled Call Reminders/caller.py index 0526ea7c31a..4285b5c1c2e 100644 --- a/Automated Scheduled Call Reminders/caller.py +++ b/Automated Scheduled Call Reminders/caller.py @@ -1,49 +1,91 @@ -# The project automates calls for people from the firebase cloud database and the schedular keeps it running and checks for entries -# every 1 hour using aps scedular -# The project can be used to set 5 min before reminder calls to a set of people for doing a particular job -from firebase_admin import credentials, firestore, initialize_app -from datetime import datetime, timedelta +""" +Firebase-Twilio Automated Reminder System + +This script automates reminder calls to individuals stored in a Firebase Cloud Firestore database. +It checks for entries every hour and initiates calls 5 minutes prior to the scheduled time for each entry. +""" + +import datetime from time import gmtime, strftime +from typing import Any + +from firebase_admin import credentials, firestore, initialize_app from twilio.rest import Client -# twilio credentials -acc_sid = "" -auth_token = "" -client = Client(acc_sid, auth_token) +# Twilio credentials (Replace with your actual credentials) +ACC_SID: str = "" +AUTH_TOKEN: str = "" +TWILIO_PHONE_NUMBER: str = "add your twilio number" + +# Firebase credentials (key.json should be your Firebase project certificate) +FIREBASE_CERT_PATH: str = "key.json" -# firebase credentials -# key.json is your certificate of firebase project -cred = credentials.Certificate("key.json") +# Initialize Firebase and Twilio clients +cred = credentials.Certificate(FIREBASE_CERT_PATH) default_app = initialize_app(cred) db = firestore.client() database_reference = db.collection("on_call") +twilio_client = Client(ACC_SID, AUTH_TOKEN) + -# Here the collection name is on_call which has documents with fields phone , from (%H:%M:%S time to call the person),date +def search() -> None: + """ + Search for scheduled calls in the database and initiate reminders 5 minutes prior to the scheduled time. -# gets data from cloud database and calls 5 min prior the time (from time) alloted in the database -def search(): + This function: + 1. Queries the Firebase database for entries with the current date + 2. Filters entries scheduled within the next hour + 3. Initiates Twilio calls for entries where the scheduled time is 5 minutes from now + """ + # Current time and cutoff time (1 hour from now) + current_time: datetime.datetime = datetime.datetime.now() + one_hour_later: str = (current_time + datetime.timedelta(hours=1)).strftime( + "%H:%M:%S" + ) + current_date: str = str(strftime("%d-%m-%Y", gmtime())) - calling_time = datetime.now() - one_hours_from_now = (calling_time + timedelta(hours=1)).strftime("%H:%M:%S") - current_date = str(strftime("%d-%m-%Y", gmtime())) - docs = db.collection(u"on_call").where(u"date", u"==", current_date).stream() - list_of_docs = [] + # Fetch documents from Firestore + docs = db.collection("on_call").where("date", "==", current_date).stream() + scheduled_calls: list[dict[str, Any]] = [] + + # Filter documents scheduled within the next hour for doc in docs: + doc_data = doc.to_dict() + if current_time.strftime("%H:%M:%S") <= doc_data["from"] <= one_hour_later: + scheduled_calls.append(doc_data) + + print( + f"Found {len(scheduled_calls)} scheduled calls for {current_date} within the next hour" + ) + + # Process each scheduled call to check if it's time to send a reminder + while scheduled_calls: + current_timestamp: str = datetime.datetime.now().strftime("%H:%M") + five_minutes_later: str = ( + datetime.datetime.now() + datetime.timedelta(minutes=5) + ).strftime("%H:%M") + + for call in scheduled_calls[:]: # Iterate over a copy to safely remove elements + scheduled_time = call["from"][0:5] # Extract HH:MM from HH:MM:SS + + if scheduled_time == five_minutes_later: + phone_number: str = call["phone"] + + try: + # Initiate Twilio call + twilio_client.calls.create( + to=phone_number, + from_=TWILIO_PHONE_NUMBER, + url="http://demo.twilio.com/docs/voice.xml", + ) + print( + f"Call initiated to {phone_number} for scheduled time {scheduled_time}" + ) + scheduled_calls.remove(call) + except Exception as e: + print(f"Error initiating call to {phone_number}: {str(e)}") + - c = doc.to_dict() - if (calling_time).strftime("%H:%M:%S") <= c["from"] <= one_hours_from_now: - list_of_docs.append(c) - print(list_of_docs) - - while list_of_docs: - timestamp = datetime.now().strftime("%H:%M") - five_minutes_prior = (timestamp + timedelta(minutes=5)).strftime("%H:%M") - for doc in list_of_docs: - if doc["from"][0:5] == five_minutes_prior: - phone_number = doc["phone"] - call = client.calls.create( - to=phone_number, - from_="add your twilio number", - url="http://demo.twilio.com/docs/voice.xml", - ) - list_of_docs.remove(doc) +if __name__ == "__main__": + # Run the search function to check for and initiate calls + search() diff --git a/Automated Scheduled Call Reminders/requirements.txt b/Automated Scheduled Call Reminders/requirements.txt deleted file mode 100644 index f5635170c24..00000000000 --- a/Automated Scheduled Call Reminders/requirements.txt +++ /dev/null @@ -1,14 +0,0 @@ -APScheduler -search -os -time -gmtime -strftime -Client -twilio -datetime -timedelta -credentials -firestore -initialize_app -Twilio \ No newline at end of file diff --git a/Automated Scheduled Call Reminders/schedular.py b/Automated Scheduled Call Reminders/schedular.py index 905adad611f..da84b3aa528 100644 --- a/Automated Scheduled Call Reminders/schedular.py +++ b/Automated Scheduled Call Reminders/schedular.py @@ -1,13 +1,52 @@ -# schedular code for blocking schedular as we have only 1 process to run +""" +Firebase-Twilio Reminder Scheduler -from apscheduler.schedulers.blocking import BlockingScheduler +This script schedules the `search` function from the `caller` module to run at regular intervals. +The scheduler checks for upcoming reminders every hour and initiates calls 5 minutes before each scheduled time. +""" +from apscheduler.schedulers.blocking import BlockingScheduler from caller import search +# Initialize the blocking scheduler +scheduler: BlockingScheduler = BlockingScheduler() + + +def start_scheduler() -> None: + """ + Start the blocking scheduler to run the reminder search function at regular intervals. + + This function configures the scheduler to call the `search` function every hour + and starts the scheduler in blocking mode. The process will run indefinitely + until explicitly terminated. + + Raises: + Any exceptions raised by the underlying scheduler implementation. + """ + try: + # Schedule the search function to run every hour + scheduler.add_job( + func=search, # Function to call + trigger="interval", # Interval-based triggering + hours=1, # Interval duration (1 hour) + id="reminder_search_job", # Unique job identifier + max_instances=1, # Ensure only one instance runs at a time + ) + + print( + "Scheduler initialized. Next run will be in 1 hour. Press Ctrl+C to exit." + ) + + # Start the scheduler in blocking mode (this thread will be occupied) + scheduler.start() -sched = BlockingScheduler() + except KeyboardInterrupt: + print("\nScheduler terminated by user.") + except Exception as e: + print(f"Error starting scheduler: {str(e)}") + raise -# Schedule job_function to be called every two hours -sched.add_job(search, "interval", hours=1) # for testing instead add hours =1 -sched.start() +if __name__ == "__main__": + # Start the scheduler when run as a standalone script + start_scheduler() diff --git a/Bank Application .ipynb b/Bank Application .ipynb index 8bad0d2a213..998c8aa2ba5 100644 --- a/Bank Application .ipynb +++ b/Bank Application .ipynb @@ -6,7 +6,7 @@ "metadata": {}, "outputs": [], "source": [ - "##open project " + "##open project" ] }, { @@ -23,12 +23,12 @@ "outputs": [], "source": [ "data = {\n", - " \"accno\" : [1001, 1002, 1003, 1004, 1005],\n", - " \"name\" : ['vaibhav', 'abhinav', 'aman', 'ashish', 'pramod'],\n", - " \"balance\" : [10000, 12000, 7000, 9000, 10000],\n", - " \"password\" : ['admin', 'adminadmin', 'passwd', '1234567', 'amigo'],\n", - " \"security_check\" : ['2211', '1112', '1009', '1307', '1103']\n", - "}\n" + " \"accno\": [1001, 1002, 1003, 1004, 1005],\n", + " \"name\": [\"vaibhav\", \"abhinav\", \"aman\", \"ashish\", \"pramod\"],\n", + " \"balance\": [10000, 12000, 7000, 9000, 10000],\n", + " \"password\": [\"admin\", \"adminadmin\", \"passwd\", \"1234567\", \"amigo\"],\n", + " \"security_check\": [\"2211\", \"1112\", \"1009\", \"1307\", \"1103\"],\n", + "}" ] }, { @@ -114,122 +114,136 @@ "# import getpass\n", "print(\"-------------------\".center(100))\n", "print(\"| Bank Application |\".center(100))\n", - "print(\"-\"*100)\n", - "while True :\n", + "print(\"-\" * 100)\n", + "while True:\n", " print(\"\\n 1. Login \\n 2. Signup \\n 3. Exit\")\n", " i1 = int(input(\"enter what you want login, signup, exit :\".center(50)))\n", - " #login part\n", + " # login part\n", " if i1 == 1:\n", " print(\"login\".center(90))\n", - " print(\"_\"*100)\n", + " print(\"_\" * 100)\n", " i2 = int(input(\"enter account number : \".center(50)))\n", " if i2 in (data[\"accno\"]):\n", " check = (data[\"accno\"]).index(i2)\n", " i3 = input(\"enter password : \".center(50))\n", - " check2= data[\"password\"].index(i3)\n", - " if check == check2:\n", + " check2 = data[\"password\"].index(i3)\n", + " if check == check2:\n", " while True:\n", - " print(\"\\n 1.check ditails \\n 2. debit \\n 3. credit \\n 4. change password \\n 5. main Manu \")\n", + " print(\n", + " \"\\n 1.check ditails \\n 2. debit \\n 3. credit \\n 4. change password \\n 5. main Manu \"\n", + " )\n", " i4 = int(input(\"enter what you want :\".center(50)))\n", - " #check ditails part\n", + " # check ditails part\n", " if i4 == 1:\n", " print(\"cheak ditails\".center(90))\n", - " print(\".\"*100)\n", + " print(\".\" * 100)\n", " print(f\"your account number --> {data['accno'][check]}\")\n", " print(f\"your name --> {data['name'][check]}\")\n", " print(f\"your balance --> {data['balance'][check]}\")\n", " continue\n", - " #debit part\n", - " elif i4 == 2 :\n", + " # debit part\n", + " elif i4 == 2:\n", " print(\"debit\".center(90))\n", - " print(\".\"*100)\n", + " print(\".\" * 100)\n", " print(f\"your balance --> {data['balance'][check]}\")\n", " i5 = int(input(\"enter debit amount : \"))\n", - " if 0 < i5 <= data['balance'][check]:\n", - " debit = data['balance'][check]-i5\n", - " data['balance'][check] = debit\n", - " print(f\"your remaining balance --> {data['balance'][check]}\")\n", + " if 0 < i5 <= data[\"balance\"][check]:\n", + " debit = data[\"balance\"][check] - i5\n", + " data[\"balance\"][check] = debit\n", + " print(\n", + " f\"your remaining balance --> {data['balance'][check]}\"\n", + " )\n", " else:\n", " print(\"your debit amount is more than balance \")\n", " continue\n", - " #credit part\n", - " elif i4 == 3 :\n", + " # credit part\n", + " elif i4 == 3:\n", " print(\"credit\".center(90))\n", - " print(\".\"*100)\n", + " print(\".\" * 100)\n", " print(f\"your balance --> {data['balance'][check]}\")\n", " i6 = int(input(\"enter credit amount : \"))\n", - " if 0 < i6:\n", - " credit = data['balance'][check]+i6\n", - " data['balance'][check] = credit\n", + " if i6 > 0:\n", + " credit = data[\"balance\"][check] + i6\n", + " data[\"balance\"][check] = credit\n", " print(f\"your new balance --> {data['balance'][check]}\")\n", " else:\n", " print(\"your credit amount is low \")\n", " continue\n", - " #password part\n", - " elif i4 == 4 :\n", + " # password part\n", + " elif i4 == 4:\n", " print(\"change password\".center(90))\n", - " print(\".\"*100)\n", + " print(\".\" * 100)\n", " old = input(\"enter your old password : \")\n", - " print(\"your password must have at list one lower case, one uppercase, one digital, one special case and length of password is 8\")\n", - " new = getpass.getpass(prompt = \"Enter your new password\" )\n", + " print(\n", + " \"your password must have at list one lower case, one uppercase, one digital, one special case and length of password is 8\"\n", + " )\n", + " new = getpass.getpass(prompt=\"Enter your new password\")\n", " if old == data[\"password\"][check]:\n", - " low, up ,sp ,di = 0, 0, 0, 0\n", - " if (len(new))> 8 :\n", + " low, up, sp, di = 0, 0, 0, 0\n", + " if (len(new)) > 8:\n", " for i in new:\n", - " if (i.islower()):\n", + " if i.islower():\n", " low += 1\n", - " if (i.isupper()):\n", - " up +=1 \n", - " if (i.isdigit()):\n", + " if i.isupper():\n", + " up += 1\n", + " if i.isdigit():\n", " di += 1\n", - " if (i in ['@','$','%','^','&','*']):\n", + " if i in [\"@\", \"$\", \"%\", \"^\", \"&\", \"*\"]:\n", " sp += 1\n", - " if (low>=1 and up>=1 and sp>=1 and di>=1 and low+up+sp+di==len(new)):\n", - " data['password'][check] = new\n", - " print(f\"your new password --> {data['password'][check]}\")\n", + " if (\n", + " low >= 1\n", + " and up >= 1\n", + " and sp >= 1\n", + " and di >= 1\n", + " and low + up + sp + di == len(new)\n", + " ):\n", + " data[\"password\"][check] = new\n", + " print(\n", + " f\"your new password --> {data['password'][check]}\"\n", + " )\n", " else:\n", " print(\"Invalid Password\")\n", " else:\n", " print(\"old password wrong please enter valid password\")\n", " continue\n", - " elif i4 == 5 :\n", + " elif i4 == 5:\n", " print(\"main menu\".center(90))\n", - " print(\".\"*100)\n", + " print(\".\" * 100)\n", " break\n", " else:\n", - " print(\"please enter valid number\") \n", + " print(\"please enter valid number\")\n", " else:\n", " print(\"please check your password number\".center(50))\n", " else:\n", - " print(\"please check your account number\".center(50)) \n", - " #signup part \n", - " elif i1 == 2 :\n", + " print(\"please check your account number\".center(50))\n", + " # signup part\n", + " elif i1 == 2:\n", " print(\"signup\".center(90))\n", - " print(\"_\"*100)\n", - " acc = 1001 + len(data['accno'])\n", - " data['accno'].append(acc)\n", - " ind = (data['accno']).index(acc)\n", + " print(\"_\" * 100)\n", + " acc = 1001 + len(data[\"accno\"])\n", + " data[\"accno\"].append(acc)\n", + " ind = (data[\"accno\"]).index(acc)\n", " name = input(\"enter your name : \")\n", - " data['name'].append(name)\n", + " data[\"name\"].append(name)\n", " balance = int(input(\"enter your initial balance : \"))\n", - " data['balance'].append(balance)\n", + " data[\"balance\"].append(balance)\n", " password = input(\"enter your password : \")\n", - " data['password'].append(password)\n", + " data[\"password\"].append(password)\n", " security_check = (int(input(\"enter your security pin (DDMM) : \"))).split()\n", - " print(\".\"*100)\n", + " print(\".\" * 100)\n", " print(f\"your account number --> {data['accno'][ind]}\".center(50))\n", " print(f\"your name --> {data['name'][ind]}\".center(50))\n", " print(f\"your balance --> {data['balance'][ind]}\".center(50))\n", " print(f\"your password --> {data['password'][ind]}\".center(50))\n", " continue\n", - " #exit part\n", - " elif i1== 3 :\n", + " # exit part\n", + " elif i1 == 3:\n", " print(\"exit\".center(90))\n", " print(\"thank you for visiting\".center(90))\n", - " print(\".\"*100)\n", + " print(\".\" * 100)\n", " break\n", " else:\n", - " print(f\"wrong enter : {i1}\".center(50))\n" + " print(f\"wrong enter : {i1}\".center(50))" ] }, { @@ -247,7 +261,7 @@ "source": [ "def cheak_ditails(check):\n", " print(\"cheak ditails\".center(90))\n", - " print(\".\"*100)\n", + " print(\".\" * 100)\n", " print(f\"your account number --> {data['accno'][check]}\")\n", " print(f\"your name --> {data['name'][check]}\")\n", " print(f\"your balance --> {data['balance'][check]}\")" @@ -261,12 +275,12 @@ "source": [ "def credit(check):\n", " print(\"credit\".center(90))\n", - " print(\".\"*100)\n", + " print(\".\" * 100)\n", " print(f\"your balance --> {data['balance'][check]}\")\n", " i6 = int(input(\"enter credit amount : \"))\n", - " if 0 < i6:\n", - " credit = data['balance'][check]+i6\n", - " data['balance'][check] = credit\n", + " if i6 > 0:\n", + " credit = data[\"balance\"][check] + i6\n", + " data[\"balance\"][check] = credit\n", " print(f\"your new balance --> {data['balance'][check]}\")\n", " else:\n", " print(\"your credit amount is low \")" @@ -280,12 +294,12 @@ "source": [ "def debit(check):\n", " print(\"debit\".center(90))\n", - " print(\".\"*100)\n", + " print(\".\" * 100)\n", " print(f\"your balance --> {data['balance'][check]}\")\n", " i5 = int(input(\"enter debit amount : \"))\n", - " if 0 < i5 <= data['balance'][check]:\n", - " debit = data['balance'][check]-i5\n", - " data['balance'][check] = debit\n", + " if 0 < i5 <= data[\"balance\"][check]:\n", + " debit = data[\"balance\"][check] - i5\n", + " data[\"balance\"][check] = debit\n", " print(f\"your remaining balance --> {data['balance'][check]}\")\n", " else:\n", " print(\"your debit amount is more than balance \")" @@ -299,24 +313,32 @@ "source": [ "def change_password(check):\n", " print(\"change password\".center(90))\n", - " print(\".\"*100)\n", + " print(\".\" * 100)\n", " old = input(\"enter your old password : \")\n", - " print(\"your password must have at list one lower case, one uppercase, one digital, one special case and length of password is 8\")\n", - " new = getpass.getpass(prompt = \"Enter your new password\" )\n", + " print(\n", + " \"your password must have at list one lower case, one uppercase, one digital, one special case and length of password is 8\"\n", + " )\n", + " new = getpass.getpass(prompt=\"Enter your new password\")\n", " if old == data[\"password\"][check]:\n", - " low, up ,sp ,di = 0, 0, 0, 0\n", - " if (len(new))> 8 :\n", + " low, up, sp, di = 0, 0, 0, 0\n", + " if (len(new)) > 8:\n", " for i in new:\n", - " if (i.islower()):\n", + " if i.islower():\n", " low += 1\n", - " if (i.isupper()):\n", - " up +=1 \n", - " if (i.isdigit()):\n", + " if i.isupper():\n", + " up += 1\n", + " if i.isdigit():\n", " di += 1\n", - " if (i in ['@','$','%','^','&','*']):\n", + " if i in [\"@\", \"$\", \"%\", \"^\", \"&\", \"*\"]:\n", " sp += 1\n", - " if (low>=1 and up>=1 and sp>=1 and di>=1 and low+up+sp+di==len(new)):\n", - " data['password'][check] = new\n", + " if (\n", + " low >= 1\n", + " and up >= 1\n", + " and sp >= 1\n", + " and di >= 1\n", + " and low + up + sp + di == len(new)\n", + " ):\n", + " data[\"password\"][check] = new\n", " print(f\"your new password --> {data['password'][check]}\")\n", " else:\n", " print(\"Invalid Password\")\n", @@ -332,42 +354,44 @@ "source": [ "def login():\n", " print(\"login\".center(90))\n", - " print(\"_\"*100)\n", + " print(\"_\" * 100)\n", " i2 = int(input(\"enter account number : \".center(50)))\n", " if i2 in (data[\"accno\"]):\n", " check = (data[\"accno\"]).index(i2)\n", " i3 = input(\"enter password : \".center(50))\n", - " check2= data[\"password\"].index(i3)\n", - " if check == check2:\n", + " check2 = data[\"password\"].index(i3)\n", + " if check == check2:\n", " while True:\n", - " print(\"\\n 1.check ditails \\n 2. debit \\n 3. credit \\n 4. change password \\n 5. main Manu \")\n", + " print(\n", + " \"\\n 1.check ditails \\n 2. debit \\n 3. credit \\n 4. change password \\n 5. main Manu \"\n", + " )\n", " i4 = int(input(\"enter what you want :\".center(50)))\n", - " #check ditails part\n", + " # check ditails part\n", " if i4 == 1:\n", " cheak_ditails(check)\n", " continue\n", - " #debit part\n", - " elif i4 == 2 :\n", + " # debit part\n", + " elif i4 == 2:\n", " debit(check)\n", " continue\n", - " #credit part\n", - " elif i4 == 3 :\n", + " # credit part\n", + " elif i4 == 3:\n", " credit(check)\n", " continue\n", - " #password part\n", - " elif i4 == 4 :\n", + " # password part\n", + " elif i4 == 4:\n", " change_password(check)\n", " continue\n", - " elif i4 == 5 :\n", + " elif i4 == 5:\n", " print(\"main menu\".center(90))\n", - " print(\".\"*100)\n", + " print(\".\" * 100)\n", " break\n", " else:\n", - " print(\"please enter valid number\") \n", + " print(\"please enter valid number\")\n", " else:\n", " print(\"please check your password number\".center(50))\n", " else:\n", - " print(\"please check your account number\".center(50)) " + " print(\"please check your account number\".center(50))" ] }, { @@ -377,13 +401,13 @@ "outputs": [], "source": [ "def security_check(ss):\n", - " data = {(1, 3, 5, 7, 8, 10, 12) : 31, (2, ) : 29, (4, 6, 9) : 30}\n", + " data = {(1, 3, 5, 7, 8, 10, 12): 31, (2,): 29, (4, 6, 9): 30}\n", " month = ss[2:]\n", " date = ss[:2]\n", " for key, value in data.items():\n", " print(key, value)\n", " if int(month) in key:\n", - " if 1<=int(date)<=value:\n", + " if 1 <= int(date) <= value:\n", " return True\n", " return False\n", " return False" @@ -397,22 +421,22 @@ "source": [ "def signup():\n", " print(\"signup\".center(90))\n", - " print(\"_\"*100)\n", - " acc = 1001 + len(data['accno'])\n", - " data['accno'].append(acc)\n", - " ind = (data['accno']).index(acc)\n", + " print(\"_\" * 100)\n", + " acc = 1001 + len(data[\"accno\"])\n", + " data[\"accno\"].append(acc)\n", + " ind = (data[\"accno\"]).index(acc)\n", " name = input(\"enter your name : \")\n", - " data['name'].append(name)\n", + " data[\"name\"].append(name)\n", " balance = int(input(\"enter your initial balance : \"))\n", - " data['balance'].append(balance)\n", + " data[\"balance\"].append(balance)\n", " password = input(\"enter your password : \")\n", - " data['password'].append(password)\n", - " ss=input(\"enter a secuirty quetion in form dd//mm\")\n", + " data[\"password\"].append(password)\n", + " ss = input(\"enter a secuirty quetion in form dd//mm\")\n", " security_check(ss)\n", - " data['security_check'].append(ss)\n", - " print(\".\"*100)\n", + " data[\"security_check\"].append(ss)\n", + " print(\".\" * 100)\n", " print(f\"your account number --> {data['accno'][ind]}\".center(50))\n", - " print(f\"your name --> {data['name'][ind]}\".center(50))\n" + " print(f\"your name --> {data['name'][ind]}\".center(50))" ] }, { @@ -453,24 +477,24 @@ "def main():\n", " print(\"-------------------\".center(100))\n", " print(\"| Bank Application |\".center(100))\n", - " print(\"-\"*100)\n", - " while True :\n", + " print(\"-\" * 100)\n", + " while True:\n", " print(\"\\n 1. Login \\n 2. Signup \\n 3. Exit\")\n", " i1 = int(input(\"enter what you want login, signup, exit :\".center(50)))\n", - " #login part\n", + " # login part\n", " if i1 == 1:\n", " login()\n", - " #signup part \n", - " elif i1 == 2 :\n", + " # signup part\n", + " elif i1 == 2:\n", " signup()\n", - " #exit part\n", - " elif i1== 3 :\n", + " # exit part\n", + " elif i1 == 3:\n", " print(\"exit\".center(90))\n", " print(\"thank you for visiting\".center(90))\n", - " print(\".\"*100)\n", + " print(\".\" * 100)\n", " break\n", " else:\n", - " print(f\"wrong enter : {i1}\".center(50))\n" + " print(f\"wrong enter : {i1}\".center(50))" ] }, { diff --git a/Base Converter Number system.py b/Base Converter Number system.py index 5c1d92e1485..23961a1372d 100644 --- a/Base Converter Number system.py +++ b/Base Converter Number system.py @@ -7,7 +7,6 @@ def base_check(xnumber, xbase): def convert_from_10(xnumber, xbase, arr, ybase): if int(xbase) == 2 or int(xbase) == 4 or int(xbase) == 6 or int(xbase) == 8: - if xnumber == 0: return arr else: diff --git a/Battery_notifier.py b/Battery_notifier.py index d871e43d928..68bd2367950 100644 --- a/Battery_notifier.py +++ b/Battery_notifier.py @@ -1,14 +1,12 @@ -from plyer import notification # pip install plyer import psutil # pip install psutil +from plyer import notification # pip install plyer # psutil.sensors_battery() will return the information related to battery battery = psutil.sensors_battery() # battery percent will return the current battery prcentage percent = battery.percent -charging = ( - battery.power_plugged -) +charging = battery.power_plugged # Notification(title, description, duration)--to send # notification to desktop diff --git a/Binary_search.py b/Binary_search.py index 0b2211d6a48..f39d1f0a6ad 100644 --- a/Binary_search.py +++ b/Binary_search.py @@ -24,7 +24,10 @@ def binary_search(arr, l, r, x): # Main Function if __name__ == "__main__": # User input array - arr = [int(x) for x in input("Enter the array with elements separated by commas: ").split(",")] + arr = [ + int(x) + for x in input("Enter the array with elements separated by commas: ").split(",") + ] # User input element to search for x = int(input("Enter the element you want to search for: ")) @@ -34,6 +37,6 @@ def binary_search(arr, l, r, x): # printing the output if result != -1: - print("Element is present at index {}".format(result)) + print(f"Element is present at index {result}") else: print("Element is not present in array") diff --git a/BlackJack_game/blackjack.py b/BlackJack_game/blackjack.py index 275b0d7368d..ce5562602d8 100644 --- a/BlackJack_game/blackjack.py +++ b/BlackJack_game/blackjack.py @@ -1,121 +1,279 @@ -# master -# master -# BLACK JACK - CASINO A GAME OF FORTUNE!!! -from time import sleep +import random +import time -# BLACK JACK - CASINO -# PYTHON CODE BASE +class Card: + """Represents a single playing card""" -# master -import random + def __init__(self, rank: str, suit: str): + self.rank = rank + self.suit = suit -deck = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11] * 4 - -random.shuffle(deck) - -print(f'{"*"*58} \n Welcome to the game Casino - BLACK JACK ! \n{"*"*58}') -sleep(2) -print("So Finally You Are Here To Accept Your Fate") -sleep(2) -print("I Mean Your Fortune") -sleep(2) -print("Lets Check How Lucky You Are Wish You All The Best") -sleep(2) -print("Loading---") -sleep(2) - -print("Still Loading---") -sleep(2) -print( - "So You Are Still Here Not Gone I Gave You Chance But No Problem May Be You Trust Your Fortune A Lot \n Lets Begin Then" -) -sleep(2) -d_cards = [] # Initialising dealer's cards -p_cards = [] # Initialising player's cards -sleep(2) -while len(d_cards) != 2: - random.shuffle(deck) - d_cards.append(deck.pop()) - if len(d_cards) == 2: - print("The cards dealer has are X ", d_cards[1]) - -# Displaying the Player's cards -while len(p_cards) != 2: - random.shuffle(deck) - p_cards.append(deck.pop()) - if len(p_cards) == 2: - print("The total of player is ", sum(p_cards)) - print("The cards Player has are ", p_cards) - -if sum(p_cards) > 21: - print(f"You are BUSTED !\n {'*'*14}Dealer Wins !!{'*'*14}\n") - exit() - -if sum(d_cards) > 21: - print(f"Dealer is BUSTED !\n {'*'*14} You are the Winner !!{'*'*18}\n") - exit() - -if sum(d_cards) == 21: - print(f"{'*'*24}Dealer is the Winner !!{'*'*14}") - exit() - -if sum(d_cards) == 21 and sum(p_cards) == 21: - print(f"{'*'*17}The match is tie !!{'*'*25}") - exit() - - -# function to show the dealer's choice -def dealer_choice(): - if sum(d_cards) < 17: - while sum(d_cards) < 17: - random.shuffle(deck) - d_cards.append(deck.pop()) - - print("Dealer has total " + str(sum(d_cards)) + "with the cards ", d_cards) - - if sum(p_cards) == sum(d_cards): - print(f"{'*'*15}The match is tie !!{'*'*15}") - exit() - - if sum(d_cards) == 21: - if sum(p_cards) < 21: - print(f"{'*'*23}Dealer is the Winner !!{'*'*18}") - elif sum(p_cards) == 21: - print(f"{'*'*20}There is tie !!{'*'*26}") + def get_value(self, hand_value: int) -> int: + """Returns the value of the card in the context of the current hand""" + if self.rank in ["J", "Q", "K"]: + return 10 + elif self.rank == "A": + # Ace can be 11 or 1, choose the optimal value + return 11 if hand_value + 11 <= 21 else 1 else: - print(f"{'*'*23}Dealer is the Winner !!{'*'*18}") - - elif sum(d_cards) < 21: - if sum(p_cards) < 21 and sum(p_cards) < sum(d_cards): - print(f"{'*'*23}Dealer is the Winner !!{'*'*18}") - if sum(p_cards) == 21: - print(f"{'*'*22}Player is winner !!{'*'*22}") - if 21 > sum(p_cards) > sum(d_cards): - print(f"{'*'*22}Player is winner !!{'*'*22}") - - else: - if sum(p_cards) < 21: - print(f"{'*'*22}Player is winner !!{'*'*22}") - elif sum(p_cards) == 21: - print(f"{'*'*22}Player is winner !!{'*'*22}") + return int(self.rank) + + def __str__(self) -> str: + return f"{self.rank}{self.suit}" + + +class Deck: + """Represents a deck of playing cards""" + + def __init__(self): + self.reset() + + def reset(self) -> None: + """Reset the deck to its initial state""" + suits = ["♥", "♦", "♣", "♠"] + ranks = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"] + self.cards = [Card(rank, suit) for suit in suits for rank in ranks] * 4 + self.shuffle() + + def shuffle(self) -> None: + """Shuffle the deck of cards""" + random.shuffle(self.cards) + + def deal_card(self) -> Card: + """Deal a single card from the deck""" + if not self.cards: + self.reset() # Auto-reset the deck if empty + return self.cards.pop() + + +class Hand: + """Represents a player's or dealer's hand of cards""" + + def __init__(self): + self.cards = [] + + def add_card(self, card: Card) -> None: + """Add a card to the hand""" + self.cards.append(card) + + def get_value(self) -> int: + """Calculate the value of the hand, considering soft and hard aces""" + total = 0 + aces = 0 + + for card in self.cards: + if card.rank == "A": + aces += 1 + total += card.get_value(total) + + # Adjust for aces (if total > 21, convert aces from 11 to 1) + while total > 21 and aces > 0: + total -= 10 + aces -= 1 + + return total + + def is_bust(self) -> bool: + """Check if the hand is bust (over 21)""" + return self.get_value() > 21 + + def is_blackjack(self) -> bool: + """Check if the hand is a blackjack (21 with 2 cards)""" + return len(self.cards) == 2 and self.get_value() == 21 + + def __str__(self) -> str: + return ", ".join(str(card) for card in self.cards) + + +class BlackjackGame: + """Main game class that manages the game flow""" + + def __init__(self): + self.deck = Deck() + self.player_hand = Hand() + self.dealer_hand = Hand() + self.player_balance = 1000 # Starting balance + self.current_bet = 0 + + def display_welcome_message(self) -> None: + """Display the welcome message and game introduction""" + title = f""" +{"*" * 58} + Welcome to the Casino - BLACK JACK ! +{"*" * 58} +""" + self._animate_text(title, 0.01) + time.sleep(1) + + messages = [ + "So finally you are here to test your luck...", + "I mean your fortune!", + "Let's see how lucky you are. Wish you all the best!", + "Loading...", + "Still loading...", + "So you're still here. I gave you a chance to leave, but no problem.", + "Maybe you trust your fortune a lot. Let's begin then!", + ] + + for message in messages: + self._animate_text(message) + time.sleep(0.8) + + def _animate_text(self, text: str, delay: float = 0.03) -> None: + """Animate text by printing each character with a small delay""" + for char in text: + print(char, end="", flush=True) + time.sleep(delay) + print() # Newline at the end + + def place_bet(self) -> None: + """Prompt the player to place a bet""" + while True: + try: + print(f"\nYour current balance: ${self.player_balance}") + bet = int(input("Place your bet: $")) + if 1 <= bet <= self.player_balance: + self.current_bet = bet + self.player_balance -= bet + break + else: + print(f"Please bet between $1 and ${self.player_balance}") + except ValueError: + print("Invalid input. Please enter a valid number.") + + def deal_initial_cards(self) -> None: + """Deal the initial cards to the player and dealer""" + self.player_hand = Hand() + self.dealer_hand = Hand() + + # Deal two cards to the player and dealer + for _ in range(2): + self.player_hand.add_card(self.deck.deal_card()) + self.dealer_hand.add_card(self.deck.deal_card()) + + # Show the player's hand and the dealer's up card + self._display_hands(show_dealer=False) + + def _display_hands(self, show_dealer: bool = True) -> None: + """Display the player's and dealer's hands""" + print("\n" + "-" * 40) + if show_dealer: + print(f"Dealer's Hand ({self.dealer_hand.get_value()}): {self.dealer_hand}") else: - print(f"{'*'*23}Dealer is the Winner !!{'*'*18}") + print(f"Dealer's Hand: X, {self.dealer_hand.cards[1]}") + print(f"Your Hand ({self.player_hand.get_value()}): {self.player_hand}") + print("-" * 40 + "\n") + + def player_turn(self) -> None: + """Handle the player's turn (hit or stand)""" + while not self.player_hand.is_bust() and not self.player_hand.is_blackjack(): + choice = input("Do you want to [H]it or [S]tand? ").strip().lower() + + if choice == "h": + self.player_hand.add_card(self.deck.deal_card()) + self._display_hands(show_dealer=False) + + if self.player_hand.is_bust(): + print("BUST! You went over 21.") + return + elif self.player_hand.is_blackjack(): + print("BLACKJACK! You got 21!") + return + elif choice == "s": + print("You chose to stand.") + return + else: + print("Invalid choice. Please enter 'H' or 'S'.") + + def dealer_turn(self) -> None: + """Handle the dealer's turn (automatically hits until 17 or higher)""" + print("\nDealer's Turn...") + self._display_hands(show_dealer=True) + + while self.dealer_hand.get_value() < 17: + print("Dealer hits...") + self.dealer_hand.add_card(self.deck.deal_card()) + time.sleep(1) + self._display_hands(show_dealer=True) + + if self.dealer_hand.is_bust(): + print("Dealer BUSTS!") + return + + def determine_winner(self) -> None: + """Determine the winner of the game and update the player's balance""" + player_value = self.player_hand.get_value() + dealer_value = self.dealer_hand.get_value() + + if self.player_hand.is_bust(): + print(f"{'*' * 20} Dealer Wins! {'*' * 20}") + return + elif self.dealer_hand.is_bust(): + winnings = self.current_bet * 2 + self.player_balance += winnings + print(f"{'*' * 20} You Win! +${winnings} {'*' * 20}") + return + elif self.player_hand.is_blackjack() and not self.dealer_hand.is_blackjack(): + # Blackjack pays 3:2 + winnings = int(self.current_bet * 2.5) + self.player_balance += winnings + print(f"{'*' * 15} Blackjack! You Win! +${winnings} {'*' * 15}") + return + elif self.dealer_hand.is_blackjack() and not self.player_hand.is_blackjack(): + print(f"{'*' * 20} Dealer Blackjack! Dealer Wins! {'*' * 20}") + return + + # Compare values if neither is bust or blackjack + if player_value > dealer_value: + winnings = self.current_bet * 2 + self.player_balance += winnings + print(f"{'*' * 20} You Win! +${winnings} {'*' * 20}") + elif player_value < dealer_value: + print(f"{'*' * 20} Dealer Wins! {'*' * 20}") + else: + # Tie (push) + self.player_balance += self.current_bet + print(f"{'*' * 20} It's a Tie! Your bet is returned. {'*' * 20}") + + def play_again(self) -> bool: + """Ask the player if they want to play another round""" + if self.player_balance <= 0: + print("\nYou're out of money! Game over.") + return False + + choice = input("\nDo you want to play another round? [Y/N] ").strip().lower() + return choice == "y" + + def run(self) -> None: + """Run the main game loop""" + self.display_welcome_message() + + while True: + if self.player_balance <= 0: + print("\nYou've run out of money! Thanks for playing.") + break + + self.place_bet() + self.deal_initial_cards() + # Check for immediate blackjack + if self.player_hand.is_blackjack(): + self._display_hands(show_dealer=True) + self.determine_winner() + else: + self.player_turn() + if not self.player_hand.is_bust(): + self.dealer_turn() + self.determine_winner() -while sum(p_cards) < 21: + if not self.play_again(): + print( + f"\nThanks for playing! Your final balance: ${self.player_balance}" + ) + break - # to continue the game again and again !! - k = input("Want to hit or stay?\n Press 1 for hit and 0 for stay ") - if k == "1": #Ammended 1 to a string - random.shuffle(deck) - p_cards.append(deck.pop()) - print("You have a total of " + str(sum(p_cards)) + " with the cards ", p_cards) - if sum(p_cards) > 21: - print(f'{"*"*13}You are BUSTED !{"*"*13}\n Dealer Wins !!') - if sum(p_cards) == 21: - print(f'{"*"*19}You are the Winner !!{"*"*29}') - else: - dealer_choice() - break \ No newline at end of file +if __name__ == "__main__": + game = BlackjackGame() + game.run() diff --git a/BlackJack_game/blackjack_rr.py b/BlackJack_game/blackjack_rr.py index d7c46b83cf6..a70c2d4acc1 100644 --- a/BlackJack_game/blackjack_rr.py +++ b/BlackJack_game/blackjack_rr.py @@ -189,7 +189,6 @@ def push(player, dealer): player_chips = Chips() while True: - print("\t **********************************************************") print( "\t Welcome to the game Casino - BLACK JACK ! " @@ -227,7 +226,6 @@ def push(player, dealer): show_some(player_hand, dealer_hand) while playing: - hit_or_stand(deck, player_hand) show_some(player_hand, dealer_hand) @@ -236,7 +234,6 @@ def push(player, dealer): break if player_hand.value <= 21: - while dealer_hand.value < 17: hit(deck, dealer_hand) diff --git a/BlackJack_game/blackjack_simulate.py b/BlackJack_game/blackjack_simulate.py index ae1706f6888..ad6f5717e99 100644 --- a/BlackJack_game/blackjack_simulate.py +++ b/BlackJack_game/blackjack_simulate.py @@ -198,7 +198,7 @@ def __init__(self, name, role, chips_amount=None, color="END"): :param chips_amount: Casino tokens equal money """ self.name = name - self.prompt = "{role} >> ({name}) : ".format(role=role, name=self.name) + self.prompt = f"{role} >> ({self.name}) : " self.chips = Chips(chips_amount) self.color = color self.hand = [] @@ -247,9 +247,7 @@ def _sum_up(ranks): def is_point(self, opt, point): self.calculate_point() - compare_fmt = "{user_point} {opt} {point}".format( - user_point=self.point, opt=opt, point=point - ) + compare_fmt = f"{self.point} {opt} {point}" return eval(compare_fmt) def speak(self, content="", end_char="\n"): @@ -265,7 +263,7 @@ def showing(self): def unveiling(self): self.calculate_point() - points_fmt = "My point is: {}".format(str(self.point)) + points_fmt = f"My point is: {str(self.point)}" self.speak(points_fmt) self.unveil_card() diff --git a/BlackJack_game/requirements.txt b/BlackJack_game/requirements.txt deleted file mode 100644 index 3320ad5cf21..00000000000 --- a/BlackJack_game/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -time -random diff --git a/BoardGame-CLI/python.py b/BoardGame-CLI/python.py index 40183159ec1..3e5bd8b4688 100644 --- a/BoardGame-CLI/python.py +++ b/BoardGame-CLI/python.py @@ -1,19 +1,52 @@ import random # Define the game board with snakes and ladders -snakes_and_ladders = { - 2: 38, 7: 14, 8: 31, 15: 26, 16: 6, 21: 42, - 28: 84, 36: 44, 46: 25, 49: 11, 51: 67, 62: 19, - 64: 60, 71: 91, 74: 53, 78: 98, 87: 94, 89: 68, - 92: 88, 95: 75, 99: 80 +snakes_and_ladders: dict[int, int] = { + 2: 38, + 7: 14, + 8: 31, + 15: 26, + 16: 6, + 21: 42, + 28: 84, + 36: 44, + 46: 25, + 49: 11, + 51: 67, + 62: 19, + 64: 60, + 71: 91, + 74: 53, + 78: 98, + 87: 94, + 89: 68, + 92: 88, + 95: 75, + 99: 80, } -# Function to roll a six-sided die -def roll_die(): + +def roll_die() -> int: + """ + Simulate rolling a six - sided die. + + Returns: + int: A random integer between 1 and 6, representing the result of the die roll. + """ return random.randint(1, 6) -# Function to simulate a single turn -def take_turn(current_position, player_name): + +def take_turn(current_position: int, player_name: str) -> int: + """ + Simulate a single turn of the snakes and ladders game. + + Args: + current_position (int): The current position of the player on the game board. + player_name (str): The name of the player taking the turn. + + Returns: + int: The new position of the player after the turn. + """ # Roll the die roll_result = roll_die() print(f"{player_name} rolled a {roll_result}!") @@ -36,15 +69,19 @@ def take_turn(current_position, player_name): return new_position -# Main game loop -def play_snakes_and_ladders(): - player1_position = 1 - player2_position = 1 - player1_name = input("Enter the name of Player 1: ") - player2_name = input("Enter the name of Player 2: ") +def play_snakes_and_ladders() -> None: + """ + Main function to play the snakes and ladders game for two players. + Prompts for player names, runs the game loop, and announces the winner. + """ + player1_position: int = 1 + player2_position: int = 1 + + player1_name: str = input("Enter the name of Player 1: ") + player2_name: str = input("Enter the name of Player 2: ") - current_player = player1_name + current_player: str = player1_name while player1_position < 100 and player2_position < 100: print(f"\n{current_player}'s turn:") @@ -65,5 +102,6 @@ def play_snakes_and_ladders(): elif player2_position == 100: print(f"{player2_name} won!") + # Start the game play_snakes_and_ladders() diff --git a/BoardGame-CLI/snakeLadder.py b/BoardGame-CLI/snakeLadder.py index d8892ed4339..01e4e0d33a5 100644 --- a/BoardGame-CLI/snakeLadder.py +++ b/BoardGame-CLI/snakeLadder.py @@ -1,173 +1,178 @@ import random -# Taking players data -players = {} # stores players name their locations -isReady = {} -current_loc = 1 # vaiable for iterating location - -imp = True - - -# players input function -def player_input(): - global players - global current_loc - global isReady - - x = True - while x: - player_num = int(input("Enter the number of players: ")) - if player_num > 0: - for i in range(player_num): - name = input(f"Enter player {i+1} name: ") - players[name] = current_loc - isReady[name] = False - x = False - play() # play funtion call - - else: - print("Number of player cannot be zero") - print() - - -# Dice roll method -def roll(): - # print(players) - return random.randrange(1, 7) - - -# play method -def play(): - global players - global isReady - global imp - - while imp: - print("/"*20) - print("1 -> roll the dice (or enter)") - print("2 -> start new game") - print("3 -> exit the game") - print("/"*20) - - for i in players: - n = input("{}'s turn: ".format(i)) or 1 - n = int(n) - - if players[i] < 100: - if n == 1: - temp1 = roll() - print(f"you got {temp1}") - print("") - - if isReady[i] == False and temp1 == 6: - isReady[i] = True - - if isReady[i]: - looproll = temp1 - counter_6 = 0 - while looproll == 6: - counter_6 += 1 - looproll = roll() - temp1 += looproll - print(f"you got {looproll} ") - if counter_6 == 3 : - temp1 -= 18 - print("Three consectutives 6 got cancelled") - print("") - # print(temp1) - if (players[i] + temp1) > 100: - pass - elif (players[i] + temp1) < 100: - players[i] += temp1 - players[i] = move(players[i], i) - elif (players[i] + temp1) == 100: - print(f"congrats {i} you won !!!") - imp = False +# Game state variables +players = {} # Stores player names and their positions +is_ready = {} # Tracks if player has rolled a 6 to start +current_position = 1 # Initial position for new players +game_active = True # Controls the main game loop + + +def get_valid_integer(prompt: str, min_value: int = None, max_value: int = None) -> int: + """ + Get a valid integer input from the user within a specified range. + + Args: + prompt: The message to display to the user. + min_value: The minimum acceptable value (inclusive). + max_value: The maximum acceptable value (inclusive). + + Returns: + A valid integer within the specified range. + """ + while True: + try: + value = int(input(prompt)) + if (min_value is not None and value < min_value) or ( + max_value is not None and value > max_value + ): + print(f"Please enter a number between {min_value} and {max_value}.") + continue + return value + except ValueError: + print("Invalid input. Please enter a valid number.") + + +def initialize_players() -> None: + """Initialize players for the game""" + global players, is_ready, current_position + + while True: + player_count = get_valid_integer("Enter the number of players: ", min_value=1) + + for i in range(player_count): + name = input(f"Enter player {i + 1} name: ").strip() + if not name: + name = f"Player {i + 1}" + players[name] = current_position + is_ready[name] = False + + start_game() + break + + +def roll_dice() -> int: + """Roll a 6-sided dice""" + return random.randint(1, 6) + + +def start_game() -> None: + """Start the main game loop""" + global game_active, players, is_ready + + while game_active: + print("/" * 20) + print("1 -> Roll the dice") + print("2 -> Start new game") + print("3 -> Exit the game") + print("/" * 20) + + for player in players: + if not game_active: + break + + choice = ( + input( + f"{player}'s turn (press Enter to roll or enter option): " + ).strip() + or "1" + ) + + try: + choice = int(choice) + except ValueError: + print("Invalid input. Please enter a number.") + continue + + if players[player] < 100: + if choice == 1: + dice_roll = roll_dice() + print(f"You rolled a {dice_roll}") + + # Check if player can start moving + if not is_ready[player] and dice_roll == 6: + is_ready[player] = True + print(f"{player} can now start moving!") + + # Process move if player is active + if is_ready[player]: + total_move = dice_roll + consecutive_sixes = 0 + + # Handle consecutive sixes + while dice_roll == 6 and consecutive_sixes < 2: + consecutive_sixes += 1 + print("You rolled a 6! Roll again...") + dice_roll = roll_dice() + print(f"You rolled a {dice_roll}") + total_move += dice_roll + + # Check for three consecutive sixes penalty + if consecutive_sixes == 2: + print("Three consecutive sixes! You lose your turn.") + total_move = 0 + + # Calculate new position + new_position = players[player] + total_move + + # Validate move + if new_position > 100: + new_position = 100 - (new_position - 100) + print(f"Overshot! You bounce back to {new_position}") + elif new_position == 100: + print(f"Congratulations, {player}! You won the game!") + game_active = False return - print(f"you are at position {players[i]}") + # Apply snakes and ladders + players[player] = new_position + players[player] = check_snakes(players[player], player) + players[player] = check_ladders(players[player], player) - elif n == 2: - players = {} # stores player ans their locations - isReady = {} - current_loc = 0 # vaiable for iterating location - player_input() + print(f"{player} is now at position {players[player]}") - elif n == 3: - print("Bye Bye") - imp = False + elif choice == 2: + # Reset game state + players = {} + is_ready = {} + current_position = 1 + initialize_players() + return + + elif choice == 3: + print("Thanks for playing! Goodbye.") + game_active = False + return else: - print("pls enter a valid input") - - -# Move method -def move(a, i): - global players - global imp - temp_loc = players[i] - - if (temp_loc) < 100: - temp_loc = ladder(temp_loc, i) - temp_loc = snake(temp_loc, i) - - return temp_loc - - -# snake bite code -def snake(c, i): - if (c == 32): - players[i] = 10 - elif (c == 36): - players[i] = 6 - elif (c == 48): - players[i] = 26 - elif (c == 63): - players[i] = 18 - elif (c == 88): - players[i] = 24 - elif (c == 95): - players[i] = 56 - elif (c == 97): - players[i] = 78 - else: - return players[i] - print(f"You got bitten by a snake now you are at {players[i]}") - - return players[i] - - -# ladder code -def ladder(a, i): - global players - - if (a == 4): - players[i] = 14 - elif (a == 8): - players[i] = 30 - elif (a == 20): - players[i] = 38 - elif (a == 40): - players[i] = 42 - elif (a == 28): - players[i] = 76 - elif (a == 50): - players[i] = 67 - elif (a == 71): - players[i] = 92 - elif (a == 88): - players[i] = 99 - else: - return players[i] - print(f"You got a ladder now you are at {players[i]}") - - return players[i] - - -# while run: -print("/"*40) -print("Welcome to the snake ladder game !!!!!!!") -print("/"*40) - - -player_input() + print("Invalid choice. Please enter 1, 2, or 3.") + else: + print(f"{player} has already won the game!") + + +def check_snakes(position: int, player: str) -> int: + """Check if the player landed on a snake""" + snakes = {32: 10, 36: 6, 48: 26, 63: 18, 88: 24, 95: 56, 97: 78} + + if position in snakes: + new_position = snakes[position] + print(f"Snake bite! {player} slides down from {position} to {new_position}") + return new_position + return position + + +def check_ladders(position: int, player: str) -> int: + """Check if the player landed on a ladder""" + ladders = {4: 14, 8: 30, 20: 38, 28: 76, 40: 42, 50: 67, 71: 92, 80: 99} + + if position in ladders: + new_position = ladders[position] + print(f"Ladder! {player} climbs from {position} to {new_position}") + return new_position + return position + + +if __name__ == "__main__": + print("/" * 40) + print("Welcome to the Snake and Ladder Game!") + print("/" * 40) + initialize_players() diff --git a/BoardGame-CLI/uno.py b/BoardGame-CLI/uno.py index 4f36372a5f8..30cb1d56f4a 100644 --- a/BoardGame-CLI/uno.py +++ b/BoardGame-CLI/uno.py @@ -1,186 +1,462 @@ -# uno game # - import random -""" -Generate the UNO deck of 108 cards. -Parameters: None -Return values: deck=>list -""" - - -def buildDeck(): - deck = [] - # example card:Red 7,Green 8, Blue skip - colours = ["Red", "Green", "Yellow", "Blue"] - values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "Draw Two", "Skip", "Reverse"] - wilds = ["Wild", "Wild Draw Four"] - for colour in colours: + + +# ANSI color codes for console output +class Colors: + RESET = "\033[0m" + RED = "\033[91m" + GREEN = "\033[92m" + YELLOW = "\033[93m" + BLUE = "\033[94m" + PURPLE = "\033[95m" + BOLD = "\033[1m" + UNDERLINE = "\033[4m" + + +def colorize_card(card: str) -> str: + """ + Colorize the card text based on its color for better console visibility. + + Args: + card (str): The card description (e.g., "Red 5"). + + Returns: + str: The colorized card text using ANSI escape codes. + """ + if card.startswith("Red"): + return f"{Colors.RED}{card}{Colors.RESET}" + elif card.startswith("Green"): + return f"{Colors.GREEN}{card}{Colors.RESET}" + elif card.startswith("Yellow"): + return f"{Colors.YELLOW}{card}{Colors.RESET}" + elif card.startswith("Blue"): + return f"{Colors.BLUE}{card}{Colors.RESET}" + elif "Wild" in card: + return f"{Colors.PURPLE}{card}{Colors.RESET}" + return card + + +def build_deck() -> list[str]: + """ + Generate a standard UNO deck consisting of 108 cards. + + Returns: + List[str]: A list containing all UNO cards as strings. + """ + deck: list[str] = [] + colors: list[str] = ["Red", "Green", "Yellow", "Blue"] + values: list[int | str] = [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + "Draw Two", + "Skip", + "Reverse", + ] + wilds: list[str] = ["Wild", "Wild Draw Four"] + + # Add numbered and action cards + for color in colors: for value in values: - cardVal = "{} {}".format(colour, value) - deck.append(cardVal) - if value != 0: - deck.append(cardVal) - for i in range(4): + card = f"{color} {value}" + deck.append(card) + if value != 0: # Each non-zero card appears twice + deck.append(card) + + # Add wild cards + for _ in range(4): deck.append(wilds[0]) deck.append(wilds[1]) - print(deck) + + print(f"Deck built with {len(deck)} cards.") return deck -""" -Shuffles a list of items passed into it -Parameters: deck=>list -Return values: deck=>list -""" +def shuffle_deck(deck: list[str]) -> list[str]: + """ + Shuffle the given deck using the Fisher-Yates algorithm for a uniform random permutation. + Args: + deck (List[str]): The deck of cards to shuffle. -def shuffleDeck(deck): - for cardPos in range(len(deck)): - randPos = random.randint(0, 107) - deck[cardPos], deck[randPos] = deck[randPos], deck[cardPos] + Returns: + List[str]: The shuffled deck. + """ + for i in range(len(deck) - 1, 0, -1): + j = random.randint(0, i) + deck[i], deck[j] = deck[j], deck[i] + print("Deck shuffled.") return deck -"""Draw card function that draws a specified number of cards off the top of the deck -Parameters: numCards -> integer -Return: cardsDrawn -> list -""" +def draw_cards(num_cards: int, deck: list[str], discards: list[str]) -> list[str]: + """ + Draw a specified number of cards from the deck. + Reshuffles the discard pile into the deck if it's empty (except the top card). + + Args: + num_cards (int): Number of cards to draw. + deck (List[str]): The main deck to draw from. + discards (List[str]): The discard pile. + Returns: + List[str]: The cards drawn from the deck. + """ + drawn_cards: list[str] = [] + for _ in range(num_cards): + if not deck: # Reshuffle discard pile if deck is empty + print(f"{Colors.BOLD}Reshuffling discard pile into deck...{Colors.RESET}") + deck = shuffle_deck(discards[:-1]) # Keep the top discard card + discards.clear() + discards.append(deck.pop()) # Move top card to discard pile -def drawCards(numCards): - cardsDrawn = [] - for x in range(numCards): - cardsDrawn.append(unoDeck.pop(0)) - return cardsDrawn + drawn_cards.append(deck.pop(0)) + return drawn_cards -""" -Print formatted list of player's hand -Parameter: player->integer , playerHand->list -Return: None -""" +def show_hand(player_name: str, player_hand: list[str]) -> None: + """ + Display the player's current hand in a formatted and colorized manner. -def showHand(player, playerHand): - print("Player {}'s Turn".format(players_name[player])) - print("Your Hand") - print("------------------") - y = 1 - for card in playerHand: - print("{}) {}".format(y, card)) - y += 1 + Args: + player_name (str): The name of the player. + player_hand (List[str]): The player's current hand of cards. + """ + print(f"\n{Colors.BOLD}=== {player_name}'s Turn ==={Colors.RESET}") + print(f"Your Hand ({len(player_hand)} cards):") + print("--------------------------------") + for i, card in enumerate(player_hand, 1): + print(f"{i}) {colorize_card(card)}") print("") -""" -Check whether a player is able to play a card, or not -Parameters: discardCard->string,value->string, playerHand->list -Return: boolean -""" +def can_play(current_color: str, current_value: str, player_hand: list[str]) -> bool: + """ + Check if the player can play any card from their hand based on the current discard pile. + Args: + current_color (str): The current active color. + current_value (str): The current active value. + player_hand (List[str]): The player's current hand. -def canPlay(colour, value, playerHand): - for card in playerHand: + Returns: + bool: True if the player can play at least one card, False otherwise. + """ + for card in player_hand: if "Wild" in card: return True - elif colour in card or value in card: + card_color, card_value = card.split(" ", 1) + if card_color == current_color or card_value == current_value: return True return False -unoDeck = buildDeck() -unoDeck = shuffleDeck(unoDeck) -unoDeck = shuffleDeck(unoDeck) -discards = [] - -players_name = [] -players = [] -colours = ["Red", "Green", "Yellow", "Blue"] -numPlayers = int(input("How many players?")) -while numPlayers < 2 or numPlayers > 4: - numPlayers = int( - input("Invalid. Please enter a number between 2-4.\nHow many players?")) -for player in range(numPlayers): - players_name.append(input("Enter player {} name: ".format(player+1))) - players.append(drawCards(5)) - - -playerTurn = 0 -playDirection = 1 -playing = True -discards.append(unoDeck.pop(0)) -splitCard = discards[0].split(" ", 1) -currentColour = splitCard[0] -if currentColour != "Wild": - cardVal = splitCard[1] -else: - cardVal = "Any" - -while playing: - showHand(playerTurn, players[playerTurn]) - print("Card on top of discard pile: {}".format(discards[-1])) - if canPlay(currentColour, cardVal, players[playerTurn]): - cardChosen = int(input("Which card do you want to play?")) - while not canPlay(currentColour, cardVal, [players[playerTurn][cardChosen-1]]): - cardChosen = int( - input("Not a valid card. Which card do you want to play?")) - print("You played {}".format(players[playerTurn][cardChosen-1])) - discards.append(players[playerTurn].pop(cardChosen-1)) - - # cheak if player won - if len(players[playerTurn]) == 0: - playing = False - # winner = "Player {}".format(playerTurn+1) - winner = players_name[playerTurn] - else: - # cheak for special cards - splitCard = discards[-1].split(" ", 1) - currentColour = splitCard[0] - if len(splitCard) == 1: - cardVal = "Any" +def get_valid_input( + prompt: str, min_val: int, max_val: int, input_type: type = int +) -> int | str: + """ + Get valid user input within a specified range and type. + + Args: + prompt (str): The message to display. + min_val (int): Minimum acceptable value (inclusive). + max_val (int): Maximum acceptable value (inclusive). + input_type (type): Expected data type (int or str). + + Returns: + Union[int, str]: Validated user input. + """ + while True: + user_input = input(prompt) + + try: + if input_type == int: + value = int(user_input) + if min_val <= value <= max_val: + return value + print(f"Please enter a number between {min_val} and {max_val}.") + elif input_type == str: + if user_input.lower() in ["y", "n"]: + return user_input.lower() + print("Please enter 'y' or 'n'.") else: - cardVal = splitCard[1] - if currentColour == "Wild": - for x in range(len(colours)): - print("{}) {}".format(x+1, colours[x])) - newColour = int( - input("What colour would you like to choose? ")) - while newColour < 1 or newColour > 4: - newColour = int( - input("Invalid option. What colour would you like to choose")) - currentColour = colours[newColour-1] - if cardVal == "Reverse": - playDirection = playDirection * -1 - elif cardVal == "Skip": - playerTurn += playDirection - if playerTurn >= numPlayers: - playerTurn = 0 - elif playerTurn < 0: - playerTurn = numPlayers-1 - elif cardVal == "Draw Two": - playerDraw = playerTurn+playDirection - if playerDraw == numPlayers: - playerDraw = 0 - elif playerDraw < 0: - playerDraw = numPlayers-1 - players[playerDraw].extend(drawCards(2)) - elif cardVal == "Draw Four": - playerDraw = playerTurn+playDirection - if playerDraw == numPlayers: - playerDraw = 0 - elif playerDraw < 0: - playerDraw = numPlayers-1 - players[playerDraw].extend(drawCards(4)) - print("") - else: - print("You can't play. You have to draw a card.") - players[playerTurn].extend(drawCards(1)) - - playerTurn += playDirection - if playerTurn >= numPlayers: - playerTurn = 0 - elif playerTurn < 0: - playerTurn = numPlayers-1 - -print("Game Over") -print("{} is the Winner!".format(winner)) + print(f"Unsupported input type: {input_type}") + return None + + except ValueError: + print(f"Invalid input. Please enter a valid {input_type.__name__}.") + + +def show_game_status( + players_name: list[str], + players: list[list[str]], + play_direction: int, + player_turn: int, + num_players: int, +) -> None: + """ + Display the current game status including player hands, direction, and next player. + + Args: + players_name (List[str]): List of player names. + players (List[List[str]]): List of each player's hand. + play_direction (int): 1 for clockwise, -1 for counter-clockwise. + player_turn (int): Index of the current player. + num_players (int): Total number of players. + """ + print(f"\n{Colors.BOLD}=== Game Status ==={Colors.RESET}") + for i, name in enumerate(players_name): + print(f"{name}: {len(players[i])} cards") + direction = "Clockwise" if play_direction == 1 else "Counter-clockwise" + print(f"Direction: {Colors.BOLD}{direction}{Colors.RESET}") + next_player = (player_turn + play_direction) % num_players + print(f"Next player: {Colors.BOLD}{players_name[next_player]}{Colors.RESET}") + print("-------------------") + + +def main() -> None: + """ + Main function to initialize and run the UNO game. + """ + print(f"{Colors.BOLD}{Colors.UNDERLINE}Welcome to UNO!{Colors.RESET}") + + # Initialize game components + uno_deck = build_deck() + uno_deck = shuffle_deck(uno_deck) + discards: list[str] = [] + + players_name: list[str] = [] + players: list[list[str]] = [] + colors: list[str] = ["Red", "Green", "Yellow", "Blue"] + + # Get number of players + num_players = get_valid_input("How many players? (2-4): ", 2, 4) + + # Get player names + for i in range(num_players): + while True: + name = input(f"Enter player {i + 1} name: ").strip() + if name: + players_name.append(name) + break + print("Name cannot be empty. Please try again.") + + print(f"\n{Colors.BOLD}=== Game Starting ==={Colors.RESET}") + print(f"Players: {', '.join(players_name)}") + + # Deal initial cards + for i in range(num_players): + players.append(draw_cards(7, uno_deck, discards)) + print(f"{players_name[i]} received 7 cards.") + + # Initialize game state + player_turn: int = 0 + play_direction: int = 1 # 1 for clockwise, -1 for counter-clockwise + game_active: bool = True + + # Start with first card on discard pile + discards.append(uno_deck.pop(0)) + top_card = discards[-1].split(" ", 1) + current_color: str = top_card[0] + current_value: str = top_card[1] if len(top_card) > 1 else "Any" + + # Handle wild cards as starting card + if current_color == "Wild": + print("Starting card is Wild. Choosing random color...") + current_color = random.choice(colors) + + print(f"\nGame begins with: {colorize_card(discards[-1])} ({current_color})") + + # Main game loop + while game_active: + current_hand = players[player_turn] + + # Show game status before each turn + show_game_status( + players_name, players, play_direction, player_turn, num_players + ) + show_hand(players_name[player_turn], current_hand) + print(f"Current card: {colorize_card(discards[-1])} ({current_color})") + + # Check if player can play + if can_play(current_color, current_value, current_hand): + valid_moves = [ + i + 1 + for i, card in enumerate(current_hand) + if "Wild" in card + or card.startswith(current_color) + or current_value in card + ] + print( + f"Valid moves: {[colorize_card(current_hand[i - 1]) for i in valid_moves]}" + ) + + # Get valid card choice + card_count = len(current_hand) + card_chosen = get_valid_input( + f"Which card do you want to play? (1-{card_count}): ", 1, card_count + ) + + # Validate selected card + while True: + selected_card = current_hand[card_chosen - 1] + card_color, card_value = ( + selected_card.split(" ", 1) + if "Wild" not in selected_card + else (selected_card, "") + ) + + if ( + "Wild" in selected_card + or card_color == current_color + or card_value == current_value + ): + break + else: + print("Invalid card selection.") + card_chosen = get_valid_input( + f"Please choose a valid card. (1-{card_count}): ", 1, card_count + ) + + # Play the card + played_card = current_hand.pop(card_chosen - 1) + discards.append(played_card) + print( + f"\n{Colors.BOLD}{players_name[player_turn]} played: {colorize_card(played_card)}{Colors.RESET}" + ) + + # Check if player won + if not current_hand: + game_active = False + winner = players_name[player_turn] + print( + f"\n{Colors.BOLD}{Colors.UNDERLINE}=== Game Over! ==={Colors.RESET}" + ) + print(f"{Colors.BOLD}{winner} is the Winner!{Colors.RESET}") + break + + # Process special cards + top_card = discards[-1].split(" ", 1) + current_color = top_card[0] + current_value = top_card[1] if len(top_card) > 1 else "Any" + + # Handle wild cards + if current_color == "Wild": + print(f"\n{Colors.BOLD}=== Wild Card ==={Colors.RESET}") + print("Choose a new color:") + for i, color in enumerate(colors, 1): + print(f"{i}) {color}") + color_choice = get_valid_input("Enter color choice (1-4): ", 1, 4) + current_color = colors[color_choice - 1] + print(f"Color changed to {current_color}") + + # Handle action cards + if current_value == "Reverse": + play_direction *= -1 + print(f"\n{Colors.BOLD}=== Reverse ==={Colors.RESET}") + print("Direction reversed!") + elif current_value == "Skip": + skipped_player = (player_turn + play_direction) % num_players + player_turn = skipped_player + print(f"\n{Colors.BOLD}=== Skip ==={Colors.RESET}") + print(f"{players_name[skipped_player]} has been skipped!") + elif current_value == "Draw Two": + next_player = (player_turn + play_direction) % num_players + drawn_cards = draw_cards(2, uno_deck, discards) + players[next_player].extend(drawn_cards) + print(f"\n{Colors.BOLD}=== Draw Two ==={Colors.RESET}") + print(f"{players_name[next_player]} draws 2 cards!") + elif current_value == "Draw Four": + next_player = (player_turn + play_direction) % num_players + drawn_cards = draw_cards(4, uno_deck, discards) + players[next_player].extend(drawn_cards) + print(f"\n{Colors.BOLD}=== Draw Four ==={Colors.RESET}") + print(f"{players_name[next_player]} draws 4 cards!") + else: + print(f"\n{Colors.BOLD}You can't play. Drawing a card...{Colors.RESET}") + drawn_card = draw_cards(1, uno_deck, discards)[0] + players[player_turn].append(drawn_card) + print(f"You drew: {colorize_card(drawn_card)}") + + # Check if drawn card can be played + card_color, card_value = ( + drawn_card.split(" ", 1) + if "Wild" not in drawn_card + else (drawn_card, "") + ) + if ( + "Wild" in drawn_card + or card_color == current_color + or card_value == current_value + ): + print("You can play the drawn card!") + play_choice = get_valid_input( + "Do you want to play it? (y/n): ", 0, 1, str + ) + if play_choice == "y": + players[player_turn].remove(drawn_card) + discards.append(drawn_card) + print( + f"\n{Colors.BOLD}{players_name[player_turn]} played: {colorize_card(drawn_card)}{Colors.RESET}" + ) + + # Process special cards + top_card = discards[-1].split(" ", 1) + current_color = top_card[0] + current_value = top_card[1] if len(top_card) > 1 else "Any" + + if current_color == "Wild": + print(f"\n{Colors.BOLD}=== Wild Card ==={Colors.RESET}") + print("Choose a new color:") + for i, color in enumerate(colors, 1): + print(f"{i}) {color}") + color_choice = get_valid_input( + "Enter color choice (1-4): ", 1, 4 + ) + current_color = colors[color_choice - 1] + print(f"Color changed to {current_color}") + + if current_value == "Reverse": + play_direction *= -1 + print(f"\n{Colors.BOLD}=== Reverse ==={Colors.RESET}") + print("Direction reversed!") + elif current_value == "Skip": + skipped_player = int( + (player_turn + play_direction) % num_players + ) # Ensure integer + player_turn = skipped_player + print(f"\n{Colors.BOLD}=== Skip ==={Colors.RESET}") + print(f"{players_name[skipped_player]} has been skipped!") + elif current_value == "Draw Two": + next_player = int( + (player_turn + play_direction) % num_players + ) # Ensure integer + drawn_cards = draw_cards(2, uno_deck, discards) + players[next_player].extend(drawn_cards) + print(f"\n{Colors.BOLD}=== Draw Two ==={Colors.RESET}") + print(f"{players_name[next_player]} draws 2 cards!") + elif current_value == "Draw Four": + next_player = int( + (player_turn + play_direction) % num_players + ) # Ensure integer + drawn_cards = draw_cards(4, uno_deck, discards) + players[next_player].extend(drawn_cards) + print(f"\n{Colors.BOLD}=== Draw Four ==={Colors.RESET}") + print(f"{players_name[next_player]} draws 4 cards!") + + # Move to next player + player_turn = int( + (player_turn + play_direction) % num_players + ) # Ensure integer + + +if __name__ == "__main__": + main() diff --git a/BrowserHistory/backend.py b/BrowserHistory/backendBrowserHistory.py similarity index 92% rename from BrowserHistory/backend.py rename to BrowserHistory/backendBrowserHistory.py index 89df7a0da8b..2b39a255934 100644 --- a/BrowserHistory/backend.py +++ b/BrowserHistory/backendBrowserHistory.py @@ -1,10 +1,11 @@ class DLL: """ - a doubly linked list that holds the current page, - next page, and previous page. - Used to enforce order in operations. + a doubly linked list that holds the current page, + next page, and previous page. + Used to enforce order in operations. """ - def __init__(self, val: str =None): + + def __init__(self, val: str = None): self.val = val self.nxt = None self.prev = None @@ -31,7 +32,7 @@ def __init__(self, homepage: str): self._curr = self._head self._back_count = 0 self._forward_count = 0 - + def visit(self, url: str) -> None: """ Returns - None @@ -45,12 +46,12 @@ def visit(self, url: str) -> None: # Clear forward history to prevent memory leaks self._curr.nxt = None self._forward_count = 0 - + # Create and link new node url_node = DLL(url) self._curr.nxt = url_node url_node.prev = self._curr - + # Update current node and counts self._curr = url_node self._back_count += 1 @@ -90,7 +91,7 @@ def forward(self, steps: int) -> str: self._forward_count -= 1 self._back_count += 1 return self._curr.val - + if __name__ == "__main__": obj = BrowserHistory("google.com") diff --git a/BrowserHistory/tests/test_browser_history.py b/BrowserHistory/tests/test_browser_history.py index 829f326c238..f9070ba0b0f 100644 --- a/BrowserHistory/tests/test_browser_history.py +++ b/BrowserHistory/tests/test_browser_history.py @@ -1,10 +1,12 @@ -import unittest -import sys import os +import sys +import unittest # Add parent directory to path to import backend sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -from backend import BrowserHistory + +from backendBrowserHistory import BrowserHistory + class TestBrowserHistory(unittest.TestCase): def setUp(self): @@ -38,7 +40,7 @@ def test_back_navigation(self): # Setup history self.browser.visit("page1.com") self.browser.visit("page2.com") - + # Test normal back navigation result = self.browser.back(1) self.assertEqual(result, "page1.com") @@ -57,7 +59,7 @@ def test_forward_navigation(self): self.browser.visit("page1.com") self.browser.visit("page2.com") self.browser.back(2) # Go back to homepage - + # Test normal forward navigation result = self.browser.forward(1) self.assertEqual(result, "page1.com") @@ -75,17 +77,18 @@ def test_complex_navigation(self): self.browser.visit("page1.com") self.browser.visit("page2.com") self.browser.visit("page3.com") - + # Back navigation self.assertEqual(self.browser.back(2), "page1.com") - + # New visit should clear forward history self.browser.visit("page4.com") self.assertEqual(self.browser._forward_count, 0) self.assertIsNone(self.browser._curr.nxt) - + # Verify we can't go forward to cleared history self.assertEqual(self.browser.forward(1), "page4.com") -if __name__ == '__main__': - unittest.main() \ No newline at end of file + +if __name__ == "__main__": + unittest.main() diff --git a/BruteForce.py b/BruteForce.py index 46b17844e26..eee2b7b7465 100644 --- a/BruteForce.py +++ b/BruteForce.py @@ -2,17 +2,14 @@ def findPassword(chars, function, show=50, format_="%s"): - password = None attempts = 0 size = 1 stop = False while not stop: - # Obtém todas as combinações possíveis com os dígitos do parâmetro "chars". for pw in product(chars, repeat=size): - password = "".join(pw) # Imprime a senha que será tentada. @@ -56,7 +53,6 @@ def getChars(): # Para realizar o teste, o usuário deverá inserir uma senha para ser encontrada. if __name__ == "__main__": - import datetime import time diff --git a/CRC/crc.py b/CRC/crc.py index d3d302244b7..48d6fe0ee2f 100644 --- a/CRC/crc.py +++ b/CRC/crc.py @@ -1,55 +1,101 @@ -def crc_check(data, div): - l = len(div) - ct = 0 - data = [int(i) for i in data] - div = [int(i) for i in div] - zero = [0 for i in range(l)] - temp_data = [data[i] for i in range(l)] - result = [] - for j in range(len(data) - len(div) + 1): +def crc_check(data: str, div: str) -> list[int]: + """ + Perform CRC (Cyclic Redundancy Check) calculation. + + Args: + data: Input data string (binary digits) + div: Divisor string (binary digits, typically a polynomial) + + Returns: + List of integers representing the CRC remainder + """ + divisor_length: int = len(div) # Renamed from 'l' to 'divisor_length' + data_list: list[int] = [int(i) for i in data] + div_list: list[int] = [int(i) for i in div] + zero: list[int] = [0] * divisor_length + temp_data: list[int] = data_list[:divisor_length] + result: list[int] = [] + + for j in range(len(data_list) - divisor_length + 1): print("Temp_dividend", temp_data) - msb = temp_data[0] + msb: int = temp_data[0] + if msb == 0: result.append(0) - for i in range(l - 1, -1, -1): - temp_data[i] = temp_data[i] ^ zero[i] + temp_data = [ + temp_data[i] ^ zero[i] for i in range(divisor_length - 1, -1, -1) + ] else: result.append(1) - for i in range(l - 1, -1, -1): - temp_data[i] = temp_data[i] ^ div[i] + temp_data = [ + temp_data[i] ^ div_list[i] for i in range(divisor_length - 1, -1, -1) + ] + temp_data.pop(0) - if l + j < len(data): - temp_data.append(data[l + j]) - crc = temp_data + if divisor_length + j < len(data_list): + temp_data.append(data_list[divisor_length + j]) + + crc: list[int] = temp_data print("Quotient: ", result, "remainder", crc) return crc -# returning crc value - - -while 1 > 0: - print("Enter data: ") - data = input() # can use it like int(input()) - print("Enter divisor") - div = input() # can use it like int(input()) - original_data = data - data = data + ("0" * (len(div) - 1)) - crc = crc_check(data, div) - crc_str = "" - for c in crc: - crc_str += c - print("Sent data: ", original_data + crc_str) - sent_data = original_data + crc_str - print( - "If again applying CRC algorithm, the remainder/CRC must be zero if errorless." - ) - crc = crc_check(sent_data, div) - remainder = crc - print("Receiver side remainder: ", remainder) - print("Continue [Y/N]:") - ch = input() - if ch == "N" or ch == "n": - break - else: - continue +def validate_binary_input(input_str: str) -> bool: + """Check if input string contains only 0s and 1s""" + return all(c in {"0", "1"} for c in input_str) + + +def main() -> None: + """Main program loop for CRC calculation and verification""" + while True: + try: + # Get input from user + data: str = input("Enter data: ").strip() + if not validate_binary_input(data): + raise ValueError("Data must be a binary string (0s and 1s)") + + div: str = input("Enter divisor: ").strip() + if not validate_binary_input(div): + raise ValueError("Divisor must be a binary string (0s and 1s)") + if len(div) < 2: + raise ValueError("Divisor length must be at least 2") + + original_data: str = data + padded_data: str = data + "0" * (len(div) - 1) + + # Calculate CRC + crc: list[int] = crc_check(padded_data, div) + crc_str: str = "".join(str(c) for c in crc) + + # Display sent data + sent_data: str = original_data + crc_str + print("Sent data: ", sent_data) + + # Verify CRC at receiver side + print( + "If again applying CRC algorithm, the remainder/CRC must be zero if errorless." + ) + receiver_crc: list[int] = crc_check(sent_data, div) + print("Receiver side remainder: ", receiver_crc) + + # Check if remainder is zero + if all(bit == 0 for bit in receiver_crc): + print("CRC verification successful - no detected errors.") + else: + print("CRC verification failed - errors detected.") + + except ValueError as ve: + print(f"Input Error: {ve}") + continue + except Exception as e: + print(f"An unexpected error occurred: {e}") + continue + + # Ask user to continue + ch: str = input("Continue [Y/N]: ").strip().upper() + if ch == "N": + break + + +if __name__ == "__main__": + main() diff --git a/CSV_file.py b/CSV_file.py index d67e23064c4..ba7e4154b93 100644 --- a/CSV_file.py +++ b/CSV_file.py @@ -2,13 +2,15 @@ # loading the dataset -df= pd.read_csv(r"c:\PROJECT\Drug_Recommendation_System\drug_recommendation_system\Drugs_Review_Datasets.csv") +df = pd.read_csv( + r"c:\PROJECT\Drug_Recommendation_System\drug_recommendation_system\Drugs_Review_Datasets.csv" +) -print(df) #prints Dataset +print(df) # prints Dataset # funtions print(df.tail()) print(df.head()) print(df.info()) print(df.describe()) print(df.column) -print(df.shape()) \ No newline at end of file +print(df.shape()) diff --git a/Caesar Cipher Encoder & Decoder.py b/Caesar Cipher Encoder & Decoder.py index 63097b39e17..0db15ae6911 100644 --- a/Caesar Cipher Encoder & Decoder.py +++ b/Caesar Cipher Encoder & Decoder.py @@ -6,6 +6,7 @@ # Improved by: OfficialAhmed (https://github.com/OfficialAhmed) + def get_int() -> int: """ Get integer, otherwise redo @@ -19,13 +20,12 @@ def get_int() -> int: return key -def main(): +def main(): print("[>] CAESAR CIPHER DECODER!!! \n") print("[1] Encrypt\n[2] Decrypt") match input("Choose one of the above(example for encode enter 1): "): - case "1": encode() @@ -38,13 +38,11 @@ def main(): def encode(): - encoded_cipher = "" text = input("Enter text to encode: ") key = get_int() - + for char in text: - ascii = ord(char) + key encoded_cipher += chr(ascii) @@ -52,7 +50,6 @@ def encode(): def decode(): - decoded_cipher = "" cipher = input("\n[>] Enter your cipher text: ") key = get_int() @@ -64,5 +61,5 @@ def decode(): print(decoded_cipher) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/Calculate resistance.py b/Calculate resistance.py index ee6f10319a1..06dff0b5723 100644 --- a/Calculate resistance.py +++ b/Calculate resistance.py @@ -1,16 +1,18 @@ -def res(R1, R2): - sum = R1 + R2 - if option =="series": - return sum - elif option =="parallel" : - return (R1 * R2)/sum - return 0 -Resistance1 = int(input("Enter R1 : ")) -Resistance2 = int(input("Enter R2 : ")) -option = input("Enter series or parallel :") -print("\n") -R = res(Resistance1,Resistance2 ) -if R==0: - print('Wrong Input!!' ) +def res(R1, R2): + sum = R1 + R2 + if option == "series": + return sum + elif option == "parallel": + return (R1 * R2) / sum + return 0 + + +Resistance1 = int(input("Enter R1 : ")) +Resistance2 = int(input("Enter R2 : ")) +option = input("Enter series or parallel :") +print("\n") +R = res(Resistance1, Resistance2) +if R == 0: + print("Wrong Input!!") else: print("The total resistance is", R) diff --git a/Calendar (GUI).py b/Calendar (GUI).py index 1649a78785d..a4b1093b2cf 100644 --- a/Calendar (GUI).py +++ b/Calendar (GUI).py @@ -1,5 +1,5 @@ -from tkinter import * import calendar +from tkinter import * root = Tk() # root.geometry("400x300") @@ -7,6 +7,7 @@ # Function + def text(): month_int = int(month.get()) year_int = int(year.get()) diff --git a/Cat/cat.py b/Cat/cat.py index 552ed6c1e7a..0c9ba120255 100644 --- a/Cat/cat.py +++ b/Cat/cat.py @@ -20,8 +20,10 @@ David Costell (DontEatThemCookies on GitHub) v2 - 03/12/2022 """ + import sys + def with_files(files): """Executes when file(s) is/are specified.""" try: @@ -35,6 +37,7 @@ def with_files(files): for contents in file_contents: sys.stdout.write(contents) + def no_files(): """Executes when no file(s) is/are specified.""" try: @@ -47,6 +50,7 @@ def no_files(): except EOFError: exit() + def main(): """Entry point of the cat program.""" # Read the arguments passed to the program @@ -55,5 +59,6 @@ def main(): else: with_files(sys.argv[1:]) + if __name__ == "__main__": main() diff --git a/Checker_game_by_dz/first.py b/Checker_game_by_dz/first.py index 55c572e3629..7a9718fc924 100644 --- a/Checker_game_by_dz/first.py +++ b/Checker_game_by_dz/first.py @@ -6,9 +6,9 @@ # import libraries import pygame as pg from modules import statics as st -from modules.statics import * -from modules.checker_board import * from modules.checker import * +from modules.checker_board import * +from modules.statics import * # static variables for this perticular file fps = 60 @@ -16,6 +16,7 @@ WIN = pg.display.set_mode((st.width, st.height)) pg.display.set_caption("Checkers") + # get row and col for mouse def get_row_col_mouse(pos): x, y = pos @@ -26,7 +27,6 @@ def get_row_col_mouse(pos): # main function if __name__ == "__main__": - # represents the game run = True diff --git a/Checker_game_by_dz/modules/__init__.py b/Checker_game_by_dz/modules/__init__.py deleted file mode 100644 index 78dc4841952..00000000000 --- a/Checker_game_by_dz/modules/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -""" -Auhtor : Dhruv B Kakadiya - -""" diff --git a/Checker_game_by_dz/modules/checker.py b/Checker_game_by_dz/modules/checker.py index 8525435aef0..70a7f4e1327 100644 --- a/Checker_game_by_dz/modules/checker.py +++ b/Checker_game_by_dz/modules/checker.py @@ -4,9 +4,10 @@ """ import pygame as pg + from .checker_board import * -from .statics import * from .pieces import * +from .statics import * class checker: diff --git a/Checker_game_by_dz/modules/checker_board.py b/Checker_game_by_dz/modules/checker_board.py index b14df11b360..e9b061507a2 100644 --- a/Checker_game_by_dz/modules/checker_board.py +++ b/Checker_game_by_dz/modules/checker_board.py @@ -4,8 +4,10 @@ """ import pygame as pg -from .statics import * + from .pieces import * +from .statics import * + # checker board creation class checker_board: diff --git a/Checker_game_by_dz/modules/pieces.py b/Checker_game_by_dz/modules/pieces.py index 2a0b2de413f..1f50e9696e7 100644 --- a/Checker_game_by_dz/modules/pieces.py +++ b/Checker_game_by_dz/modules/pieces.py @@ -3,12 +3,12 @@ """ -from .statics import * import pygame as pg +from .statics import * + class pieces: - padding = 17 outline = 2 diff --git a/Chrome Dino Automater.py b/Chrome Dino Automater.py index c5668832556..1dc46236576 100644 --- a/Chrome Dino Automater.py +++ b/Chrome Dino Automater.py @@ -1,9 +1,9 @@ -import pyautogui # pip install pyautogui -from PIL import ImageGrab # pip install pillow - # from numpy import asarray import time +import pyautogui # pip install pyautogui +from PIL import ImageGrab # pip install pillow + def hit(key): pyautogui.press(key) @@ -11,7 +11,6 @@ def hit(key): def isCollide(data): - # for cactus for i in range(329, 425): for j in range(550, 650): diff --git a/Classification_human_or_horse.py b/Classification_human_or_horse.py index 4aa069a855a..7786d2f8da5 100644 --- a/Classification_human_or_horse.py +++ b/Classification_human_or_horse.py @@ -36,8 +36,9 @@ from tkinter import Tk from tkinter.filedialog import askopenfilename -from keras.preprocessing import image + import numpy as np +from keras.preprocessing import image Tk().withdraw() filename = askopenfilename() diff --git a/CliYoutubeDownloader.py b/CliYoutubeDownloader.py index 7b9d3d4bf1d..3d251959635 100644 --- a/CliYoutubeDownloader.py +++ b/CliYoutubeDownloader.py @@ -1,6 +1,7 @@ -from pytube import * import sys +from pytube import * + class YouTubeDownloder: def __init__(self): @@ -11,16 +12,14 @@ def __init__(self): self.showTitle() def showTitle(self): - print("title : {0}\n".format(self.youtube.title)) + print(f"title : {self.youtube.title}\n") self.showStreams() def showStreams(self): self.streamNo = 1 for stream in self.youtube.streams: print( - "{0} => resolation:{1}/fps:{2}/type:{3}".format( - self.streamNo, stream.resolution, stream.fps, stream.type - ) + f"{self.streamNo} => resolation:{stream.resolution}/fps:{stream.fps}/type:{stream.type}" ) self.streamNo += 1 self.chooseStream() @@ -47,13 +46,7 @@ def getFileSize(self): def getPermisionToContinue(self): print( - "\n title : {0} \n author : {1} \n size : {2:.2f}MB \n resolution : {3} \n fps : {4} \n ".format( - self.youtube.title, - self.youtube.author, - file_size, - self.stream.resolution, - self.stream.fps, - ) + f"\n title : {self.youtube.title} \n author : {self.youtube.author} \n size : {file_size:.2f}MB \n resolution : {self.stream.resolution} \n fps : {self.stream.fps} \n " ) if input("do you want it ?(defualt = (y)es) or (n)o ") == "n": self.showStreams() @@ -67,7 +60,7 @@ def download(self): def onProgress(stream=None, chunk=None, remaining=None): file_downloaded = file_size - (remaining / 1000000) print( - f"downloading ... {file_downloaded/file_size*100:0.2f} % [{file_downloaded:.1f}MB of {file_size:.1f}MB]", + f"downloading ... {file_downloaded / file_size * 100:0.2f} % [{file_downloaded:.1f}MB of {file_size:.1f}MB]", end="\r", ) diff --git a/CliYoutubeDownloader/CliYoutubeDownloader.py b/CliYoutubeDownloader/CliYoutubeDownloader.py index 7b201a920e2..334809953fa 100644 --- a/CliYoutubeDownloader/CliYoutubeDownloader.py +++ b/CliYoutubeDownloader/CliYoutubeDownloader.py @@ -1,6 +1,7 @@ # libraraies import sys + import pytube @@ -13,16 +14,14 @@ def __init__(self): self.showTitle() def showTitle(self): - print("title : {0}\n".format(self.youtube.title)) + print(f"title : {self.youtube.title}\n") self.showStreams() def showStreams(self): self.streamNo = 1 for stream in self.youtube.streams: print( - "{0} => resolution:{1}/fps:{2}/type:{3}".format( - self.streamNo, stream.resolution, stream.fps, stream.type - ) + f"{self.streamNo} => resolution:{stream.resolution}/fps:{stream.fps}/type:{stream.type}" ) self.streamNo += 1 self.chooseStream() @@ -49,13 +48,7 @@ def getFileSize(self): def getPermisionToContinue(self): print( - "\n Title : {0} \n Author : {1} \n Size : {2:.2f}MB \n Resolution : {3} \n FPS : {4} \n ".format( - self.youtube.title, - self.youtube.author, - file_size, - self.stream.resolution, - self.stream.fps, - ) + f"\n Title : {self.youtube.title} \n Author : {self.youtube.author} \n Size : {file_size:.2f}MB \n Resolution : {self.stream.resolution} \n FPS : {self.stream.fps} \n " ) if input("Do you want it ?(default = (y)es) or (n)o ") == "n": self.showStreams() @@ -69,7 +62,7 @@ def download(self): def onProgress(stream=None, chunk=None, remaining=None): file_downloaded = file_size - (remaining / 1000000) print( - f"Downloading ... {file_downloaded/file_size*100:0.2f} % [{file_downloaded:.1f}MB of {file_size:.1f}MB]", + f"Downloading ... {file_downloaded / file_size * 100:0.2f} % [{file_downloaded:.1f}MB of {file_size:.1f}MB]", end="\r", ) diff --git a/CliYoutubeDownloader/requirements.txt b/CliYoutubeDownloader/requirements.txt deleted file mode 100644 index 30257302458..00000000000 --- a/CliYoutubeDownloader/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -pytube \ No newline at end of file diff --git a/Colors/multicoloredline.py b/Colors/multicoloredline.py index fdbe1c45881..3e3a64c9db2 100644 --- a/Colors/multicoloredline.py +++ b/Colors/multicoloredline.py @@ -1,24 +1,28 @@ +import json +import time +from typing import Any + from rich.console import Console +from rich.progress import BarColumn, Progress, SpinnerColumn, TextColumn from rich.syntax import Syntax -from rich.progress import Progress, SpinnerColumn, BarColumn, TextColumn from rich.table import Table -import time -import json -console = Console() +console: Console = Console() # Fancy separator console.rule("[bold]Welcome to Rich Terminal[/bold]", style="rainbow") # Define some JSON data -json_data = { +json_data: dict[str, Any] = { "message": "Hello, World!", "status": "success", - "code": 200 + "code": 200, } # Print JSON with syntax highlighting -syntax = Syntax(json.dumps(json_data, indent=4), "json", theme="monokai", line_numbers=True) +syntax: Syntax = Syntax( + json.dumps(json_data, indent=4), "json", theme="monokai", line_numbers=True +) console.print(syntax) # Simulating a progress bar @@ -31,15 +35,15 @@ TextColumn("{task.percentage:>3.0f}%"), console=console, ) as progress: - task = progress.add_task("[cyan]Loading...", total=100) + task_id: int = progress.add_task("[cyan]Loading...", total=100) for _ in range(100): time.sleep(0.02) - progress.update(task, advance=1) + progress.update(task_id, advance=1) # Create a rich table console.print("\n[bold magenta]Results Summary:[/bold magenta]\n") -table = Table(title="System Report", show_header=True, header_style="bold cyan") +table: Table = Table(title="System Report", show_header=True, header_style="bold cyan") table.add_column("Metric", style="bold yellow") table.add_column("Value", justify="right", style="bold green") diff --git a/Colors/pixel_sort.py b/Colors/pixel_sort.py index 920e034817f..feb7ddbf347 100644 --- a/Colors/pixel_sort.py +++ b/Colors/pixel_sort.py @@ -1,169 +1,291 @@ -"""Pixel Sorting""" +"""Pixel Sorting with Audio Visualization + +This script processes an image by sorting its pixels based on color attributes, +generates a video of the sorting process, and converts pixel data into audio. +""" + +import argparse +import colorsys +import math +from pathlib import Path -# Importing Libraries import cv2 import numpy as np -import math -import colorsys import pandas as pd -import os -import argparse +from scipy import signal from tqdm import tqdm -# Importing the external file Library -import sound - -# Taking arguments from command line -parser = argparse.ArgumentParser() # you iniatize as such -parser.add_argument("-f", required=True, help="enter fileName of your picture") -# parser.add_argument("-s", required=True, help="Speed factor of the audio to be increased or decreased") -# parser.add_argument("-av", required=True, help="Speed factor of the audio visualizer to be increased or decreased") - -# the add_argument tells you what needs to be given as an input sp its help -args = parser.parse_args() # you take the arguments from command line - -os.makedirs("Image_sort/" + str(args.f)) -print(str(args.f).capitalize() + " directory is created.") - -# Defining all global variables -df = [] -total = 0 -dict, final, img_list = {}, [], [] - -# Create dataframe and save it as an excel file -def createDataSet(val=0, data=[]): - global dict - dict[len(data)] = data - if val != 0: - if val == max(dict.keys()): - final_df = pd.DataFrame(dict[val], columns=["Blue", "Green", "Red"]) - final_df.to_excel("Image_sort/" + str(args.f) + "/" + "output.xlsx") - - -# Generating colors for each row of the frame -def generateColors(c_sorted, frame, row): - global df, img_list - height = 15 - img = np.zeros((height, len(c_sorted), 3), np.uint8) - for x in range(0, len(c_sorted)): - r, g, b = c_sorted[x][0] * 255, c_sorted[x][1] * 255, c_sorted[x][2] * 255 - c = [r, g, b] - df.append(c) - img[:, x] = c # the color value for the xth column , this gives the color band - frame[row, x] = c # changes added for every row in the frame - - createDataSet(data=df) - return img, frame - - -# Measures the total number of pixels that were involved in pixel sort -def measure(count, row, col, height, width): - global total - total += count - if row == height - 1 and col == width - 1: - createDataSet(val=total) - - -# Step Sorting Algorithm -def step(bgr, repetitions=1): - b, g, r = bgr - # lum is calculated as per the way the humans view the colors - lum = math.sqrt(0.241 * r + 0.691 * g + 0.068 * b) +# Configuration - Modify these for different results +AUDIO_SAMPLE_RATE: int = 44100 # Audio sampling rate (Hz) +AUDIO_DURATION: float = 10 # Audio duration (seconds) +BASE_FREQUENCY: float = 220 # Lowest frequency for audio conversion (Hz) +MAX_FREQUENCY: float = 880 # Highest frequency for audio conversion (Hz) +SORT_REPETITIONS: int = 8 # Controls color sorting smoothness +OUTPUT_VIDEO_FPS: int = 16 # Frames per second for output video + + +def parse_arguments() -> argparse.Namespace: + """Parse command line arguments with default values""" + parser: argparse.ArgumentParser = argparse.ArgumentParser( + description="Pixel sorting with audio visualization" + ) + parser.add_argument( + "-f", + "--filename", + required=True, + help="Input image filename (without extension)", + ) + parser.add_argument( + "-i", + "--input_dir", + default="Image", + help="Input directory for images (default: Image)", + ) + parser.add_argument( + "-o", + "--output_dir", + default="Image_sort", + help="Output directory for results (default: Image_sort)", + ) + parser.add_argument( + "-d", + "--duration", + type=float, + default=AUDIO_DURATION, + help="Audio duration in seconds (default: 10)", + ) + return parser.parse_args() + - # conversion of rgb to hsv values - h, s, v = colorsys.rgb_to_hsv( - r, g, b - ) # h,s,v is a better option for classifying each color +def validate_input_image(args: argparse.Namespace) -> str: + """Validate input image exists and return its path""" + image_path: Path = Path(args.input_dir) / f"{args.filename}.jpg" + if not image_path.exists(): + print(f"Error: Image file '{image_path}' not found") + exit(1) + return str(image_path) - # Repetitions are taken to decrease the noise - h2 = int(h * repetitions) - v2 = int(v * repetitions) - # To get a smoother color band - if h2 % 2 == 1: - v2 = repetitions - v2 - lum = repetitions - lum +def create_output_directories(args: argparse.Namespace) -> Path: + """Create necessary output directories""" + output_base: Path = Path(args.output_dir) + output_subdir: Path = output_base / args.filename + output_subdir.mkdir(parents=True, exist_ok=True) + print(f"Output directory created: {output_subdir}") + return output_subdir - return h2, lum, v2 +def sort_pixels_by_row(img: np.ndarray) -> np.ndarray: + """Sort image pixels row by row using HSV color space""" + height, width = img.shape[:2] + sorted_img: np.ndarray = img.copy().astype(np.float32) / 255.0 # Normalize to [0,1] -# Threshold set for avoiding extreme sorting of the pixels -def findThreshold(lst, add): - for i in lst: - add.append(sum(i)) - return (max(add) + min(add)) / 2 + for row in tqdm(range(height), desc="Sorting rows"): + # Extract row pixels and sort based on HSV luminance + row_pixels: np.ndarray = sorted_img[row].copy() + row_pixels_sorted: np.ndarray = sort_pixels_by_hsv(row_pixels) + sorted_img[row] = row_pixels_sorted + return (sorted_img * 255).astype(np.uint8) # Convert back to [0,255] -def makeVideo(): - out = cv2.VideoWriter( - "Image_sort/" + str(args.f) + "/" + str(args.f) + ".mp4", - cv2.VideoWriter_fourcc(*"mp4v"), - 16, - (800, 500), + +def sort_pixels_by_hsv(pixels: np.ndarray) -> np.ndarray: + """Sort pixels using HSV color space for better visual coherence""" + # Calculate HSV-based sorting key for each pixel + sort_keys: np.ndarray = np.array([step_sort_key(pixel) for pixel in pixels]) + # Sort pixels based on the computed keys + sort_indices: np.ndarray = np.argsort(sort_keys, axis=0)[:, 0] + return pixels[sort_indices] + + +def step_sort_key( + bgr: np.ndarray, repetitions: int = SORT_REPETITIONS +) -> tuple[int, float, int]: + """Generate sort key based on HSV color space and luminance""" + b, g, r = bgr + # Calculate luminance (weighted for human perception) + luminance: float = math.sqrt(0.241 * r + 0.691 * g + 0.068 * b) + # Convert to HSV for better color sorting + h, s, v = colorsys.rgb_to_hsv(r, g, b) + # Adjust for repetitions to reduce noise and create smoother bands + h_scaled: int = int(h * repetitions) + v_scaled: int = int(v * repetitions) + # Invert for smoother transitions between colors + if h_scaled % 2 == 1: + v_scaled = repetitions - v_scaled + luminance = repetitions - luminance + return (h_scaled, luminance, v_scaled) + + +def generate_sorting_video( + original_img: np.ndarray, + sorted_img: np.ndarray, + output_path: Path, + fps: int = OUTPUT_VIDEO_FPS, +) -> None: + """Generate video showing the pixel sorting process""" + print("\n>>> Generating sorting process video...") + height, width = original_img.shape[:2] + fourcc: int = cv2.VideoWriter_fourcc(*"mp4v") + video_writer: cv2.VideoWriter = cv2.VideoWriter( + str(output_path), fourcc, fps, (width, height) ) - for count in tqdm(range(1, 500 + 1)): - fileName = "Image_sort/" + str(args.f) + "/" + str(count) + ".jpg" - img = cv2.imread(fileName) - out.write(img) - os.remove(fileName) - out.release() - - -def main(): - global img_list - img = cv2.imread("Image/" + str(args.f) + ".jpg") - img = cv2.resize(img, (800, 500)) - img_list.append(img) - - height, width, _ = img.shape - print(">>> Row-wise Color sorting") - for row in tqdm(range(0, height)): - color, color_n = [], [] - add = [] - - for col in range(0, width): - val = img[row][col].tolist() - - # val includes all rgb values between the range of 0 to 1 - # This makes the sorting easier and efficient - val = [i / 255.0 for i in val] - color.append(val) - - thresh = findThreshold( - color, add - ) # setting the threshold value for every row in the frame - - # For the specific row , if all the values are non-zero then it is sorted with color - if np.all(np.asarray(color)) == True: - color.sort(key=lambda bgr: step(bgr, 8)) # step sorting - band, img = generateColors(color, img, row) - measure(len(color), row, col, height, width) - - # For the specific row , if any of the values are zero it gets sorted with color_n - if np.all(np.asarray(color)) == False: - for ind, i in enumerate(color): - # Accessing every list within color - # Added to color_n if any of the element in the list is non-zero - # and their sum is less than threshold value - - if np.any(np.asarray(i)) == True and sum(i) < thresh: - color_n.append(i) - - color_n.sort(key=lambda bgr: step(bgr, 8)) # step sorting - band, img = generateColors(color_n, img, row) - measure(len(color_n), row, col, height, width) - cv2.imwrite("Image_sort/" + str(args.f) + "/" + str(row + 1) + ".jpg", img) - - # Writing down the final sorted image - cv2.imwrite( - "Image_sort/" + str(args.f) + "/" + str(args.f) + ".jpg", img - ) # Displaying the final picture - - print("\n>>> Formation of the Video progress of the pixel-sorted image") - makeVideo() - sound.main( - args.f - ) # Calling the external python file to create the audio of the pixel-sorted image - - -main() + + # Create intermediate frames showing progressive sorting + for row in tqdm(range(height), desc="Creating video frames"): + frame: np.ndarray = original_img.copy() + frame[: row + 1] = sorted_img[: row + 1] + video_writer.write(frame) + + # Add a few extra frames of the fully sorted image + for _ in range(fps): + video_writer.write(sorted_img) + + video_writer.release() + print(f"Video saved to: {output_path}") + + +def save_pixel_data(pixels: np.ndarray, output_path: Path) -> None: + """Save pixel data to Excel file for analysis""" + try: + df: pd.DataFrame = pd.DataFrame( + pixels.reshape(-1, 3), columns=["Blue", "Green", "Red"] + ) + df.to_excel(str(output_path), index=False) + print(f"Pixel data saved to: {output_path}") + except Exception as e: + print(f"Warning: Could not save pixel data - {e}") + + +def pixels_to_audio( + pixels: np.ndarray, + duration: float = AUDIO_DURATION, + sample_rate: int = AUDIO_SAMPLE_RATE, +) -> np.ndarray: + """Convert pixel data to audio signal""" + print("\n>>> Generating audio from pixel data...") + num_samples: int = int(sample_rate * duration) + + # Resize pixel data to match audio length + if pixels.size > 0: + # Flatten and normalize pixel data + pixels_flat: np.ndarray = pixels.reshape(-1, 3) / 255.0 + # Interpolate to match audio sample count + x_old: np.ndarray = np.linspace(0, 1, len(pixels_flat)) + x_new: np.ndarray = np.linspace(0, 1, num_samples) + pixel_data: np.ndarray = np.array( + [np.interp(x_new, x_old, pixels_flat[:, i]) for i in range(3)] + ).T + else: + # Generate random pixel data if input is empty + pixel_data: np.ndarray = np.random.rand(num_samples, 3) + + # Map pixel channels to audio parameters + frequencies: np.ndarray = calculate_frequencies(pixel_data) + amplitudes: np.ndarray = calculate_amplitudes(pixel_data) + waveforms: np.ndarray = calculate_waveforms(pixel_data) + + # Generate audio signal + t: np.ndarray = np.linspace(0, duration, num_samples, endpoint=False) + audio_signal: np.ndarray = np.zeros(num_samples) + + for i in range(num_samples): + # Generate waveform based on pixel data + if waveforms[i] < 0.25: # Sine wave + audio_signal[i] = amplitudes[i] * np.sin(2 * np.pi * frequencies[i] * t[i]) + elif waveforms[i] < 0.5: # Square wave + audio_signal[i] = amplitudes[i] * signal.square( + 2 * np.pi * frequencies[i] * t[i] + ) + elif waveforms[i] < 0.75: # Triangle wave + audio_signal[i] = amplitudes[i] * signal.sawtooth( + 2 * np.pi * frequencies[i] * t[i], width=0.5 + ) + else: # Sawtooth wave + audio_signal[i] = amplitudes[i] * signal.sawtooth( + 2 * np.pi * frequencies[i] * t[i] + ) + + # Normalize audio signal + if np.max(np.abs(audio_signal)) > 0: + audio_signal /= np.max(np.abs(audio_signal)) + + return audio_signal + + +def calculate_frequencies(pixels: np.ndarray) -> np.ndarray: + """Map pixel red channel to audio frequencies""" + return BASE_FREQUENCY + pixels[:, 2] * (MAX_FREQUENCY - BASE_FREQUENCY) + + +def calculate_amplitudes(pixels: np.ndarray) -> np.ndarray: + """Map pixel green channel to audio amplitudes""" + return 0.1 + pixels[:, 1] * 0.7 # Range [0.1, 0.8] + + +def calculate_waveforms(pixels: np.ndarray) -> np.ndarray: + """Map pixel blue channel to waveform types""" + return pixels[:, 0] # Range [0, 1] + + +def save_audio( + audio_signal: np.ndarray, output_path: Path, sample_rate: int = AUDIO_SAMPLE_RATE +) -> None: + """Save audio signal to WAV file""" + try: + from scipy.io import wavfile + + # Convert to 16-bit integer format + audio_int16: np.ndarray = (audio_signal * 32767).astype(np.int16) + wavfile.write(str(output_path), sample_rate, audio_int16) + print(f"Audio saved to: {output_path}") + except Exception as e: + print(f"Error saving audio: {e}") + print("Hint: Ensure scipy is installed (pip install scipy)") + + +def main() -> None: + """Main processing pipeline""" + # Parse command line arguments + args: argparse.Namespace = parse_arguments() + + # Validate input and create output directories + input_path: str = validate_input_image(args) + output_dir: Path = create_output_directories(args) + + # Load and process image + try: + img: np.ndarray = cv2.imread(input_path) + img = cv2.resize(img, (800, 500)) + print(f"Loaded image: {input_path} ({img.shape[1]}x{img.shape[0]})") + except Exception as e: + print(f"Error loading image: {e}") + exit(1) + + # Perform pixel sorting + sorted_img: np.ndarray = sort_pixels_by_row(img) + + # Save sorted image + sorted_img_path: Path = output_dir / f"{args.filename}.jpg" + cv2.imwrite(str(sorted_img_path), sorted_img) + print(f"Sorted image saved to: {sorted_img_path}") + + # Generate and save video + video_path: Path = output_dir / f"{args.filename}.mp4" + generate_sorting_video(img, sorted_img, video_path) + + # Save pixel data + pixel_data_path: Path = output_dir / "pixel_data.xlsx" + save_pixel_data(sorted_img, pixel_data_path) + + # Generate and save audio + audio_path: Path = output_dir / f"{args.filename}.wav" + audio_signal: np.ndarray = pixels_to_audio(sorted_img, args.duration) + save_audio(audio_signal, audio_path) + + print("\n=== Processing Complete ===") + print(f"All results saved to: {output_dir}") + + +if __name__ == "__main__": + main() diff --git a/Colors/primary_colors.py b/Colors/primary_colors.py index 107056fbd7d..c944100ec13 100644 --- a/Colors/primary_colors.py +++ b/Colors/primary_colors.py @@ -1,180 +1,204 @@ -def diff(a, b): +def diff(a: int | float, b: int | float) -> int | float: """ - TODO: fix this function!! + Calculate the absolute difference between two values. + This helps in determining the variance between color channels. + + Args: + a (int/float): First value + b (int/float): Second value + + Returns: + int/float: Absolute difference between a and b + """ + return abs( + a - b + ) # Fixed to return absolute difference (critical for color comparison) + + +def simpleColor(r: int | float, g: int | float, b: int | float) -> str: """ - return a - b + Determines the general color name a given RGB value approximates to. + Classification is based on comparing the intensity of red, green, and blue channels, + as well as their mutual differences. + Args: + r (int/float): Red channel value (0-255) + g (int/float): Green channel value (0-255) + b (int/float): Blue channel value (0-255) -def simpleColor(r, g, b): - """simpleColor obtiene el nombre del color mas general al cual se acerca su formato R G B""" - r = int(r) - g = int(g) - b = int(b) - bg = ir = 0 # TODO: Fix these variables + Returns: + str: General color name (e.g., "ROJO", "VERDE") or error message if invalid + """ try: - # ROJO -------------------------------------------------- - if r > g and r > b: + # Convert inputs to integers and validate range + r = int(r) + g = int(g) + b = int(b) + + if not (0 <= r <= 255 and 0 <= g <= 255 and 0 <= b <= 255): + return "Error: RGB values must be between 0 and 255" - rg = diff(r, g) # distancia rojo a verde - rb = diff(r, b) # distancia rojo a azul + # RED DOMINANT -------------------------------------------------- + if r > g and r > b: + red_green_diff = diff(r, g) # Difference between red and green + red_blue_diff = diff(r, b) # Difference between red and blue - if g < 65 and b < 65 and rg > 60: # azul y verde sin luz + # Pure red (green and blue are very low) + if g < 65 and b < 65 and red_green_diff > 60: return "ROJO" - gb = diff(g, b) # distancia de verde a azul + green_blue_diff = diff(g, b) # Difference between green and blue - if rg < rb: # Verde mayor que Azul - if gb < rg: # Verde mas cerca de Azul - if gb >= 30 and rg >= 80: + # Green is more prominent than blue + if red_green_diff < red_blue_diff: + if green_blue_diff < red_green_diff: # Green closer to blue + if green_blue_diff >= 30 and red_green_diff >= 80: return "NARANJA" - elif gb <= 20 and rg >= 80: + elif green_blue_diff <= 20 and red_green_diff >= 80: return "ROJO" - elif gb <= 20 and b > 175: + elif green_blue_diff <= 20 and b > 175: return "CREMA" - else: return "CHOCOLATE" - else: # Verde mas cerca de Rojo - if rg > 60: + else: # Green closer to red + if red_green_diff > 60: return "NARANJA*" elif r > 125: return "AMARILLO" else: - return "COCHOLATE" - elif rg > rb: # Azul mayor que verde - if bg < rb: # Verde mas cerca de Azul - if gb < 60: - if r > 150: - return "ROJO 2" - else: - return "MARRON" + return "CHOCOLATE" # Fixed typo from "COCHOLATE" + + # Blue is more prominent than green + elif red_green_diff > red_blue_diff: + if green_blue_diff < red_blue_diff: # Green closer to blue + if green_blue_diff < 60: + return "ROJO 2" if r > 150 else "MARRON" elif g > 125: return "ROSADO" else: return "ROJO 3" - else: # Verde mas cerca de Rojo - if rb < 60: - if r > 160: - return "ROSADO*" - else: - return "ROJO" + else: # Green closer to red + if red_blue_diff < 60: + return "ROSADO*" if r > 160 else "ROJO" else: return "ROJO" - else: # g y b iguales - if rg > 20: - if r >= 100 and b < 60: - return "ROJO" - elif r >= 100: - return "ROJO" - else: - return "MARRON" - + # Green and blue are nearly equal + else: + if red_green_diff > 20: + return "ROJO" if (r >= 100 and (b < 60 or r >= 100)) else "MARRON" else: return "GRIS" - # VERDE --------------------------------------------------- + + # GREEN DOMINANT --------------------------------------------------- elif g > r and g > b: - gb = diff(g, b) # distancia verde a azul - gr = diff(g, r) # distancia verde a rojo + green_blue_diff = diff(g, b) # Difference between green and blue + green_red_diff = diff(g, r) # Difference between green and red - if r < 65 and b < 65 and gb > 60: # rojo y azul sin luz + # Pure green (red and blue are very low) + if r < 65 and b < 65 and green_blue_diff > 60: return "VERDE" - rb = diff(r, b) # distancia de rojo a azul - - if r > b: # ROJO > AZUL - if gr < gb: # Verde con Rojo + red_blue_diff = diff(r, b) # Difference between red and blue - if rb >= 150 and gr <= 20: - return "AMARILLO" - else: - return "VERDE" - else: # ...Verde + # Red is more prominent than blue + if r > b: + if green_red_diff < green_blue_diff: # Green mixed with red + return ( + "AMARILLO" + if (red_blue_diff >= 150 and green_red_diff <= 20) + else "VERDE" + ) + else: return "VERDE" - elif r < b: # AZUL > ROJO - if gb < gr: # Verde con Azul - - if gb <= 20: - return "TURQUESA" - else: - return "VERDE" - else: # ...Verde + # Blue is more prominent than red + elif r < b: + if green_blue_diff < green_red_diff: # Green mixed with blue + return "TURQUESA" if green_blue_diff <= 20 else "VERDE" + else: return "VERDE" - else: # r y b iguales - if gb > 10: - return "VERDE" - else: - return "GRIS" + # Red and blue are nearly equal + else: + return "VERDE" if green_blue_diff > 10 else "GRIS" - # AZUL ------------------------------------------------------ + # BLUE DOMINANT ------------------------------------------------------ elif b > r and b > g: - bg = diff(b, g) # distancia azul a verde - br = diff(b, r) # distancia azul a rojo + blue_green_diff = diff(b, g) # Difference between blue and green + blue_red_diff = diff(b, r) # Difference between blue and red - if r < 65 and g < 65 and bg > 60: # rojo y verde sin luz + # Pure blue (red and green are very low) + if r < 65 and g < 65 and blue_green_diff > 60: return "AZUL" - rg = diff(r, g) # distancia de rojo a verde + red_green_diff = diff(r, g) # Difference between red and green - if g < r: # ROJO > VERDE - if bg < rg: # Azul con Verde - if bg <= 20: - return "TURQUESA" - else: - return "CELESTE" - else: # ...Azul - if rg <= 20: - if r >= 150: - return "LILA" - else: - return "AZUL *************" + # Red is more prominent than green + if g < r: + if blue_green_diff < red_green_diff: # Blue mixed with green + return "TURQUESA" if blue_green_diff <= 20 else "CELESTE" + else: + if red_green_diff <= 20: + return "LILA" if r >= 150 else "AZUL *************" else: return "AZUL" - elif g > r: # VERDE > ROJO - if br < rg: # Azul con rojo - if br <= 20: + # Green is more prominent than red + elif g > r: + if blue_red_diff < red_green_diff: # Blue mixed with red + if blue_red_diff <= 20: if r > 150 and g < 75: return "ROSADO FIUSHA" - elif ir > 150: + elif r > 150: # Fixed undefined variable "ir" to "r" return "LILA" else: return "MORADO" else: return "MORADO" - - else: # ...Azul - if rg <= 20: - if bg <= 20: - return "GRIS" - else: - return "AZUL" - else: # r y g iguales - if bg > 20: - if r >= 100 and b < 60: - return "ROJO" - elif r >= 100: - return "ROJO" + else: + if red_green_diff <= 20: + return "GRIS" if blue_green_diff <= 20 else "AZUL" else: - return "MARRON" + return "AZUL" + + # Red and green are nearly equal + else: + if blue_green_diff > 20: + return "ROJO" if (r >= 100 and (b < 60 or r >= 100)) else "MARRON" else: return "GRIS" - # IGUALES--------------------------------------- + # ALL CHANNELS NEARLY EQUAL --------------------------------------- else: return "GRIS" - except: - - return "Not Color" + except Exception as e: + return f"Error: Invalid input - {str(e)}" -# --------------------------------------------------------------------------------------------------- -# Puedes probar asi: python primary_colors.py 120,0,0 , esto resultara en un ROJO como respuesta -# -------------------------------------------------------------------------------------------------- if __name__ == "__main__": import sys - print(simpleColor(sys.argv[1], sys.argv[2], sys.argv[3])) + # Set default RGB values if no arguments are provided + default_r: int = 255 + default_g: int = 0 + default_b: int = 0 # Default to red + + # Parse command line arguments with fallback to defaults + try: + if len(sys.argv) == 4: + r, g, b = sys.argv[1], sys.argv[2], sys.argv[3] + else: + print( + f"No arguments provided. Using default RGB: ({default_r}, {default_g}, {default_b})" + ) + r, g, b = default_r, default_g, default_b + except IndexError: + print( + f"Invalid arguments. Using default RGB: ({default_r}, {default_g}, {default_b})" + ) + r, g, b = default_r, default_g, default_b + + # Get and print the color result + print(simpleColor(r, g, b)) diff --git a/Colors/print_colors.py b/Colors/print_colors.py index 6aacaa9d4b4..daf5919064e 100644 --- a/Colors/print_colors.py +++ b/Colors/print_colors.py @@ -1,15 +1,52 @@ import sys +from typing import NoReturn + + class colors: - CYAN = "\033[36m" - GREEN = "\033[32m" - YELLOW = "\033[33m" - BLUE = "\033[34m" - RED = "\033[31m" - ENDC = "\033[0m" -def printc(color, message): - print(color + message + colors.ENDC) -printc(colors.CYAN, sys.argv[1]) -printc(colors.GREEN, sys.argv[1]) -printc(colors.YELLOW, sys.argv[1]) -printc(colors.BLUE, sys.argv[1]) -printc(colors.RED, sys.argv[1]) + """ANSI color codes for terminal output""" + + CYAN: str = "\033[36m" + GREEN: str = "\033[32m" + YELLOW: str = "\033[33m" + BLUE: str = "\033[34m" + RED: str = "\033[31m" + ENDC: str = "\033[0m" # Reset color to default + + +def printc(color: str, message: str) -> None: + """Print a message with specified ANSI color""" + print(f"{color}{message}{colors.ENDC}") + + +def exit_with_error(message: str) -> NoReturn: + """Print error message and exit with status code 1""" + printc(colors.RED, f"Error: {message}") + sys.exit(1) + + +def main() -> None: + """Main function with default message support""" + # Set default message if no command-line argument is provided + default_message: str = "Hello, Colorful World!" + + try: + message: str = sys.argv[1] if len(sys.argv) > 1 else default_message + except IndexError: + exit_with_error("Invalid command-line arguments") + + # Print usage hint (optional, helps users understand) + if len(sys.argv) <= 1: + print( + "Using default message (provide an argument to customize: python print_colors.py 'your text')\n" + ) + + # Print message in different colors + printc(colors.CYAN, message) + printc(colors.GREEN, message) + printc(colors.YELLOW, message) + printc(colors.BLUE, message) + printc(colors.RED, message) + + +if __name__ == "__main__": + main() diff --git a/Compression_Analysis/PSNR.py b/Compression_Analysis/PSNR.py index b3148c64c77..0c4e3322365 100644 --- a/Compression_Analysis/PSNR.py +++ b/Compression_Analysis/PSNR.py @@ -1,40 +1,102 @@ +import argparse import math +import os +from pathlib import Path -# using opencv3 import cv2 import numpy as np -def Representational(r, g, b): - return 0.299 * r + 0.287 * g + 0.114 * b +def rgb_to_luminance(r: np.ndarray, g: np.ndarray, b: np.ndarray) -> np.ndarray: + """Convert RGB channels to luminance using the ITU-R BT.601 standard.""" + return 0.299 * r + 0.587 * g + 0.114 * b -def calculate(img): - b, g, r = cv2.split(img) - pixelAt = Representational(r, g, b) - return pixelAt +def calculate_luminance(image: np.ndarray) -> np.ndarray: + """Calculate luminance from a BGR image (OpenCV's default format).""" + b, g, r = cv2.split(image) + return rgb_to_luminance(r, g, b) -def main(): - # Loading images (orignal image and compressed image) - orignal_image = cv2.imread("orignal_image.png", 1) - compressed_image = cv2.imread("compressed_image.png", 1) +def calculate_psnr(original: np.ndarray, compressed: np.ndarray) -> float: + """Calculate PSNR between two luminance arrays (higher values indicate better quality).""" + mse = np.mean(np.square(original - compressed)) + return float("inf") if mse == 0 else 10 * math.log10((255.0**2) / mse) - # Getting image height and width - height, width = orignal_image.shape[:2] - orignalPixelAt = calculate(orignal_image) - compressedPixelAt = calculate(compressed_image) +def load_image(image_path: str) -> np.ndarray: + """Load an image with cross-platform path handling and error debugging.""" + # Automatically convert path separators (Windows: \, Linux: /) + path = Path(image_path).resolve() # Convert to absolute path for clarity - diff = orignalPixelAt - compressedPixelAt - error = np.sum(np.abs(diff) ** 2) + # Check if file exists + if not path.is_file(): + # Show system-specific debug info + print("\nSystem Debug Info:") + print(f"Operating System: {'Windows' if os.name == 'nt' else 'Linux/Unix'}") + print(f"Current Working Directory: {Path.cwd()}") + print(f"Target Path (auto-converted): {path}") + raise FileNotFoundError( + f"Image file not found! Check the path:\n{path}\n" + f"Note: Path automatically adjusted for your operating system." + ) - error = error / (height * width) + # Load image with OpenCV + image = cv2.imread(str(path)) + if image is None: + raise ValueError( + f"Invalid image format: {path} (supported: PNG, JPG, BMP, TIFF)" + ) - # MSR = error_sum/(height*width) - PSNR = -(10 * math.log10(error / (255 * 255))) + return image - print("PSNR value is {}".format(PSNR)) + +def main() -> None: + """Cross-platform PSNR calculation tool with automatic path handling.""" + # Define default paths using Path (auto-handles separators) + default_original: Path = Path("Compression_Analysis") / "orignal_image.png" + default_compressed: Path = Path("Compression_Analysis") / "compressed_image.png" + + # Set up command-line arguments + parser: argparse.ArgumentParser = argparse.ArgumentParser( + description="Cross-Platform PSNR Calculator (supports Windows/Linux)" + ) + parser.add_argument( + "--original", + default=str(default_original), + help=f"Path to original image (default: {default_original})", + ) + parser.add_argument( + "--compressed", + default=str(default_compressed), + help=f"Path to compressed image (default: {default_compressed})", + ) + args: argparse.Namespace = parser.parse_args() + + try: + # Load images with cross-platform path handling + original_image: np.ndarray = load_image(args.original) + compressed_image: np.ndarray = load_image(args.compressed) + + # Verify image dimensions match + if original_image.shape != compressed_image.shape: + raise ValueError( + f"Dimension mismatch! Original: {original_image.shape[:2]}, " + f"Compressed: {compressed_image.shape[:2]}" + ) + + # Calculate and display PSNR + original_lum: np.ndarray = calculate_luminance(original_image) + compressed_lum: np.ndarray = calculate_luminance(compressed_image) + psnr: float = calculate_psnr(original_lum, compressed_lum) + + print(f"PSNR Value: {psnr:.2f} dB") + print( + "Interpretation: 20-30 dB = low quality, 30-40 dB = good quality, >40 dB = excellent quality" + ) + + except Exception as error: + print(f"Error: {error}") if __name__ == "__main__": diff --git a/CountMillionCharacter.py b/CountMillionCharacter.py index c1aa7825a19..47d37916cfe 100644 --- a/CountMillionCharacter.py +++ b/CountMillionCharacter.py @@ -6,6 +6,7 @@ Credit to William J. Turkel and Adam Crymble for the word frequency code used below. I just merged the two ideas. """ + import re pattern = re.compile("\W") # re is used to compile the expression more than once @@ -308,7 +309,7 @@ wordlist.count(w) for w in wordlist ] # counts frequency of a letter in the given list -print("String\n {} \n".format(wordstring)) -print("List\n {} \n".format(str(wordlist))) -print("Frequencies\n {} \n".format(str(wordfreq))) -print("Pairs\n {}".format(str(dict(zip(wordlist, wordfreq))))) +print(f"String\n {wordstring} \n") +print(f"List\n {str(wordlist)} \n") +print(f"Frequencies\n {str(wordfreq)} \n") +print(f"Pairs\n {str(dict(zip(wordlist, wordfreq)))}") diff --git a/CountMillionCharacters-2.0.py b/CountMillionCharacters-2.0.py index a7f37a969dc..c1c9c1f2eb5 100644 --- a/CountMillionCharacters-2.0.py +++ b/CountMillionCharacters-2.0.py @@ -11,7 +11,7 @@ def main(): file_input = input("File Name: ") try: - with open(file_input, "r") as info: + with open(file_input) as info: count = collections.Counter(info.read().upper()) except FileNotFoundError: print("Please enter a valid file name.") diff --git a/CountMillionCharacters-Variations/variation1.py b/CountMillionCharacters-Variations/variation1.py index 101620f911a..4f04d231f15 100644 --- a/CountMillionCharacters-Variations/variation1.py +++ b/CountMillionCharacters-Variations/variation1.py @@ -1,31 +1,63 @@ -try: - input = raw_input -except NameError: - pass +"""Character Count Utility +A program that counts the frequency of each uppercase character in a specified file. +Handles user input gracefully and provides clear error messages for missing files. +Compatible with Python 3.13.5 and all modern Python 3 versions. +""" -def count_chars(filename): - count = {} - with open(filename) as info: # inputFile Replaced with filename - readfile = info.read() - for character in readfile.upper(): - count[character] = count.get(character, 0) + 1 +def count_chars(filename: str) -> dict[str, int]: + """Count the frequency of each uppercase character in a file. - return count + Args: + filename: Path to the file to be analyzed. + Returns: + A dictionary where keys are uppercase characters and values are their counts. + Includes all whitespace, punctuation, and special characters present in the file. + """ + char_counts: dict[str, int] = {} -def main(): - is_exist = True - # Try to open file if exist else raise exception and try again - while is_exist: + with open(filename) as file: # Open file in read mode + content: str = file.read() + for ( + char + ) in content.upper(): # Convert to uppercase to ensure case insensitivity + # Update count for current character (default to 0 if not found) + char_counts[char] = char_counts.get(char, 0) + 1 + + return char_counts + + +def main() -> None: + """Main function to handle user interaction and coordinate the character counting process. + + Prompts the user for a filename, processes the file, and displays character counts. + Allows the user to exit by entering '0'. Handles missing files with friendly error messages. + """ + print("Character Count Utility") + print("Enter filename to analyze (or '0' to exit)\n") + + while True: try: - inputFile = input("File Name / (0)exit : ").strip() - if inputFile == "0": + # Get user input with prompt + user_input: str = input("File name / (0)exit: ").strip() + + # Check for exit condition + if user_input == "0": + print("Exiting program. Goodbye!") break - print(count_chars(inputFile)) + + # Process file and display results + counts: dict[str, int] = count_chars(user_input) + print(f"Character counts for '{user_input}':") + print(counts) + print() # Add blank line for readability + except FileNotFoundError: - print("File not found...Try again!") + print(f"Error: File '{user_input}' not found. Please try again.\n") + except OSError as e: + print(f"Error reading file: {str(e)}. Please try again.\n") if __name__ == "__main__": diff --git a/Crack_password.py b/Crack_password.py index 6941b6236e5..986ced1b1bb 100644 --- a/Crack_password.py +++ b/Crack_password.py @@ -1,11 +1,65 @@ from random import * + user_pass = input("Enter your password: ") -password = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j','k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't','u','v','w', 'x', 'y', 'z',"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"] +password = [ + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", +] guess = "" -while (guess != user_pass): +while guess != user_pass: guess = "" for letter in range(len(user_pass)): guess_letter = password[randint(0, 51)] guess = str(guess_letter) + str(guess) print(guess) -print("Your password is",guess) +print("Your password is", guess) diff --git a/Cricket_score.py b/Cricket_score.py index 22b8f05e319..76b058313ca 100644 --- a/Cricket_score.py +++ b/Cricket_score.py @@ -1,9 +1,9 @@ from urllib import request +import bs4 # Beautiful Soup for Web Scraping + # import os import pyttsx3 - -import bs4 # Beautiful Soup for Web Scraping from win10toast import ToastNotifier toaster = ToastNotifier() diff --git a/Day_of_week.py b/Day_of_week.py index f0f9fd6f3b5..a7f2af44977 100644 --- a/Day_of_week.py +++ b/Day_of_week.py @@ -1,8 +1,8 @@ # Python program to Find day of # the week for a given date -import re # regular expressions import calendar # module of python to provide useful fucntions related to calendar import datetime # module of python to get the date and time +import re # regular expressions def process_date(user_input): @@ -12,9 +12,9 @@ def process_date(user_input): def find_day(date): - born = datetime.datetime.strptime( - date, "%d %m %Y" - ).weekday() # this statement returns an integer corresponding to the day of the week + born = ( + datetime.datetime.strptime(date, "%d %m %Y").weekday() + ) # this statement returns an integer corresponding to the day of the week return calendar.day_name[ born ] # this statement returns the corresponding day name to the integer generated in the previous statement diff --git a/Decimal_To_Binary.py b/Decimal_To_Binary.py index a8e85097a14..a2a6fff5ec6 100644 --- a/Decimal_To_Binary.py +++ b/Decimal_To_Binary.py @@ -3,7 +3,6 @@ def dtbconverter(num): - whole = [] fractional = ["."] @@ -47,10 +46,10 @@ def dtbconverter(num): THis program accepts fractional values, the accuracy can be set below: """ + # Function to convert decimal number # to binary using recursion def DecimalToBinary(num): - if num > 1: DecimalToBinary(num // 2) print(num % 2, end="") @@ -58,7 +57,6 @@ def DecimalToBinary(num): # Driver Code if __name__ == "__main__": - # decimal value dec_val = 24 diff --git a/Divide Operator.py b/Divide Operator.py index 3e6468f6daf..7a2c8a2ed65 100644 --- a/Divide Operator.py +++ b/Divide Operator.py @@ -1,5 +1,5 @@ class DivisionOperation: - INT_MAX = float('inf') + INT_MAX = float("inf") def __init__(self, num1, num2): self.num1 = num1 diff --git a/Downloaded Files Organizer/browser_status.py b/Downloaded Files Organizer/browser_status.py index 537269b62a3..a3eab9ba4c5 100644 --- a/Downloaded Files Organizer/browser_status.py +++ b/Downloaded Files Organizer/browser_status.py @@ -1,16 +1,41 @@ +import os + import psutil from obs import watcher -browsers = ["chrome.exe", "firefox.exe", "edge.exe", "iexplore.exe"] +# List of browser process names to monitor +BROWSERS: list[str] = ["chrome.exe", "firefox.exe", "edge.exe", "iexplore.exe"] + + +def get_downloads_path() -> str: + """Automatically detect the user's Downloads folder path""" + return os.path.join(os.path.expanduser("~"), "Downloads") + + +# Path to monitor (default to user's Downloads folder) +path_to_watch: str = get_downloads_path() + + +def is_browser_running() -> bool: + """Check if any browser from the list is running""" + running_processes = [p.name() for p in psutil.process_iter()] + return any(browser in running_processes for browser in BROWSERS) -# ADD DOWNLOADS PATH HERE::: r is for raw string enter the path -# Example: path_to_watch=r"C:\Users\Xyz\Downloads" -# find downloads path . +def start_watcher() -> None: + """Start monitoring the specified folder""" + if not os.path.exists(path_to_watch): + raise FileNotFoundError(f"Monitoring path does not exist: {path_to_watch}") -path_to_watch = r" " + print(f"Monitoring folder: {path_to_watch}") + watcher(path_to_watch) -for browser in browsers: - while browser in (process.name() for process in psutil.process_iter()): - watcher(path_to_watch) +if __name__ == "__main__": + try: + # Continuously monitor while any browser is running + while is_browser_running(): + start_watcher() + print("No browsers detected. Exiting program.") + except Exception as e: + print(f"An error occurred: {str(e)}") diff --git a/Downloaded Files Organizer/move_to_directory.py b/Downloaded Files Organizer/move_to_directory.py index 6bb0d522959..9570aa06d87 100644 --- a/Downloaded Files Organizer/move_to_directory.py +++ b/Downloaded Files Organizer/move_to_directory.py @@ -1,58 +1,283 @@ import os +import platform import shutil -ext = { - "web": "css less scss wasm ", - "audio": "aac aiff ape au flac gsm it m3u m4a mid mod mp3 mpa pls ra s3m sid wav wma xm ", - "code": "c cc class clj cpp cs cxx el go h java lua m m4 php pl po py rb rs swift vb vcxproj xcodeproj xml diff patch html js ", - "slide": "ppt odp ", - "sheet": "ods xls xlsx csv ics vcf ", - "image": "3dm 3ds max bmp dds gif jpg jpeg png psd xcf tga thm tif tiff ai eps ps svg dwg dxf gpx kml kmz webp ", - "archiv": "7z a apk ar bz2 cab cpio deb dmg egg gz iso jar lha mar pea rar rpm s7z shar tar tbz2 tgz tlz war whl xpi zip zipx xz pak ", - "book": "mobi epub azw1 azw3 azw4 azw6 azw cbr cbz ", - "text": "doc docx ebook log md msg odt org pages pdf rtf rst tex txt wpd wps ", - "exec": "exe msi bin command sh bat crx ", - "font": "eot otf ttf woff woff2 ", - "video": "3g2 3gp aaf asf avchd avi drc flv m2v m4p m4v mkv mng mov mp2 mp4 mpe mpeg mpg mpv mxf nsv ogg ogv ogm qt rm rmvb roq srt svi vob webm wmv yuv ", +# File extension categories and their associated extensions +FILE_EXTENSIONS: dict[str, list[str]] = { + "web": ["css", "less", "scss", "wasm"], + "audio": [ + "aac", + "aiff", + "ape", + "au", + "flac", + "gsm", + "it", + "m3u", + "m4a", + "mid", + "mod", + "mp3", + "mpa", + "pls", + "ra", + "s3m", + "sid", + "wav", + "wma", + "xm", + ], + "code": [ + "c", + "cc", + "class", + "clj", + "cpp", + "cs", + "cxx", + "el", + "go", + "h", + "java", + "lua", + "m", + "m4", + "php", + "pl", + "po", + "py", + "rb", + "rs", + "swift", + "vb", + "vcxproj", + "xcodeproj", + "xml", + "diff", + "patch", + "html", + "js", + ], + "slide": ["ppt", "odp"], + "sheet": ["ods", "xls", "xlsx", "csv", "ics", "vcf"], + "image": [ + "3dm", + "3ds", + "max", + "bmp", + "dds", + "gif", + "jpg", + "jpeg", + "png", + "psd", + "xcf", + "tga", + "thm", + "tif", + "tiff", + "ai", + "eps", + "ps", + "svg", + "dwg", + "dxf", + "gpx", + "kml", + "kmz", + "webp", + ], + "archive": [ + "7z", + "a", + "apk", + "ar", + "bz2", + "cab", + "cpio", + "deb", + "dmg", + "egg", + "gz", + "iso", + "jar", + "lha", + "mar", + "pea", + "rar", + "rpm", + "s7z", + "shar", + "tar", + "tbz2", + "tgz", + "tlz", + "war", + "whl", + "xpi", + "zip", + "zipx", + "xz", + "pak", + ], + "book": ["mobi", "epub", "azw1", "azw3", "azw4", "azw6", "azw", "cbr", "cbz"], + "text": [ + "doc", + "docx", + "ebook", + "log", + "md", + "msg", + "odt", + "org", + "pages", + "pdf", + "rtf", + "rst", + "tex", + "txt", + "wpd", + "wps", + ], + "executable": ["exe", "msi", "bin", "command", "sh", "bat", "crx"], + "font": ["eot", "otf", "ttf", "woff", "woff2"], + "video": [ + "3g2", + "3gp", + "aaf", + "asf", + "avchd", + "avi", + "drc", + "flv", + "m2v", + "m4p", + "m4v", + "mkv", + "mng", + "mov", + "mp2", + "mp4", + "mpe", + "mpeg", + "mpg", + "mpv", + "mxf", + "nsv", + "ogg", + "ogv", + "ogm", + "qt", + "rm", + "rmvb", + "roq", + "srt", + "svi", + "vob", + "webm", + "wmv", + "yuv", + ], } -for key, value in ext.items(): - value = value.split() - ext[key] = value - - -def add_to_dir(ex, src_path, path): - file_with_ex = os.path.basename(src_path) - file_without_ex = file_with_ex[: file_with_ex.find(ex) - 1] - for cat, extensions in ext.items(): - if ex in extensions: - os.chdir(path) - dest_path = path + "\\" + cat - if cat in os.listdir(): - try: - shutil.move(src_path, dest_path) - except shutil.Error: - renamed_file = rename(file_without_ex, ex, dest_path) - os.chdir(path) - os.rename(file_with_ex, renamed_file) - os.chdir(dest_path) - shutil.move(path + "\\" + renamed_file, dest_path) - else: - os.mkdir(cat) - - try: - shutil.move(src_path, dest_path) - except Exception as e: - print(e) - if os.path.exists(src_path): - os.unlink(src_path) - - -def rename(search, ex, dest_path): - count = 0 - os.chdir(dest_path) - for filename in os.listdir(): - if filename.find(search, 0, len(search) - 1): - count = count + 1 - - return search + str(count) + "." + ex + +def get_unique_filename(base_name: str, extension: str, target_dir: str) -> str: + """ + Generate a unique filename to avoid overwriting existing files. + + Args: + base_name: Original filename without extension + extension: File extension (without dot) + target_dir: Directory where the file will be moved + + Returns: + Unique filename in format "base_name[counter].extension" + """ + counter = 0 + # Check existing files in target directory + for filename in os.listdir(target_dir): + if filename.startswith(base_name) and filename.endswith(f".{extension}"): + counter += 1 + + return ( + f"{base_name}{counter}.{extension}" + if counter > 0 + else f"{base_name}.{extension}" + ) + + +def move_to_category_dir(extension: str, source_path: str, base_dir: str) -> None: + """ + Move a file to its corresponding category directory based on extension. + + Args: + extension: File extension to determine category + source_path: Full path to the source file + base_dir: Base directory where category folders will be created + """ + # Get original filename components + filename = os.path.basename(source_path) + base_name = filename[: filename.rfind(f".{extension}")] # Name without extension + + # Find matching category for the extension + target_category = None + for category, extensions in FILE_EXTENSIONS.items(): + if extension in extensions: + target_category = category + break + + if not target_category: + return # Skip uncategorized files + + # Create target directory path + target_dir = os.path.join(base_dir, target_category) + + try: + # Create category directory if it doesn't exist + if not os.path.exists(target_dir): + os.makedirs(target_dir) + + # Move file to target directory + destination_path = os.path.join(target_dir, filename) + + # Handle existing files by renaming + if os.path.exists(destination_path): + new_filename = get_unique_filename(base_name, extension, target_dir) + new_destination = os.path.join(target_dir, new_filename) + shutil.move(source_path, new_destination) + else: + shutil.move(source_path, destination_path) + + except shutil.Error as e: + print(f"Error moving file: {e}") + except Exception as e: + print(f"Unexpected error: {e}") + + +# Example usage: +if __name__ == "__main__": + # Detect the operating system + current_os = platform.system() + + # Set base directory based on the detected OS + if current_os == "Windows" or current_os in ["Linux", "Darwin"]: + base_directory = os.path.join(os.path.expanduser("~"), "Downloads") + else: + print(f"Unsupported operating system: {current_os}") + base_directory = os.getcwd() # Use current directory as fallback + + print(f"Sorting files in: {base_directory}") + + # Process all files in the base directory + try: + for item in os.listdir(base_directory): + item_path = os.path.join(base_directory, item) + + # Skip directories, process only files + if os.path.isfile(item_path): + # Get file extension (lowercase) + if "." in item: + ext = item.split(".")[-1].lower() + move_to_category_dir(ext, item_path, base_directory) + except Exception as e: + print(f"Error processing directory: {e}") diff --git a/Downloaded Files Organizer/obs.py b/Downloaded Files Organizer/obs.py index 1489f257041..7cf4998b2db 100644 --- a/Downloaded Files Organizer/obs.py +++ b/Downloaded Files Organizer/obs.py @@ -1,22 +1,57 @@ -def watcher(path): - # python script to observe changes in a folder - import time - import os - from watchdog.observers import Observer - from watchdog.events import FileSystemEventHandler - from move_to_directory import add_to_dir - - class Handler(FileSystemEventHandler): - def on_created(self, event): - if event.event_type == "created": - file_name = os.path.basename(event.src_path) - ext = os.path.splitext(event.src_path)[1] +import os +import time +from collections.abc import Callable + +from watchdog.events import ( # Import missing type + FileSystemEvent, + FileSystemEventHandler, +) +from watchdog.observers import Observer + + +def watcher( + directory_path: str, callback: Callable[[str, str, str], None] | None = None +) -> None: + """ + Watches a specified directory for file creation events and processes new files. + + Args: + directory_path: The path to the directory to monitor. + callback: Optional callback function to handle the file processing. + Defaults to the internal add_to_dir function. + """ + # Import add_to_dir here if not available globally + try: + from move_to_directory import add_to_dir + except ImportError: + + def add_to_dir(extension: str, file_path: str, target_dir: str) -> None: + """Default implementation (replace with actual import if available)""" + print(f"Processing file: {file_path}, Extension: {extension}") + + class FileCreationHandler(FileSystemEventHandler): + def on_created(self, event: FileSystemEvent) -> None: + """Handles file creation events.""" + if not event.is_directory: + file_path = event.src_path + file_extension = os.path.splitext(file_path)[1].lstrip(".").lower() + + # Allow file to fully write before processing time.sleep(2) - add_to_dir(ext[1:], event.src_path, path) - observer.stop() + # Process the new file + handler = callback or add_to_dir + handler(file_extension, file_path, directory_path) + + # Setup and start the file system observer + event_handler = FileCreationHandler() observer = Observer() - event_handler = Handler() - observer.schedule(event_handler, path, recursive=True) + observer.schedule(event_handler, directory_path, recursive=True) observer.start() + + try: + while observer.is_alive(): + observer.join(1) + except KeyboardInterrupt: + observer.stop() observer.join() diff --git a/Downloaded Files Organizer/requirements.txt b/Downloaded Files Organizer/requirements.txt deleted file mode 100644 index 0f0482e781e..00000000000 --- a/Downloaded Files Organizer/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -sys -os -time -psutil -watchdog diff --git a/Droplistmenu/GamesCalender.py b/Droplistmenu/GamesCalender.py index 990a164bd93..b966860d860 100644 --- a/Droplistmenu/GamesCalender.py +++ b/Droplistmenu/GamesCalender.py @@ -1,71 +1,300 @@ - -from tkinter import * -from tkcalendar import Calendar import tkinter as tk +from tkinter import Button, Label, OptionMenu, Scrollbar, StringVar, Text, Toplevel + +from tkcalendar import Calendar # Install via: pip install tkcalendar + + +def main() -> None: + """Create and run the sports schedule management application""" + # Create main application window + window = tk.Tk() + window.title("Sports Schedule Manager") + window.geometry("600x500") + window.resizable(True, True) # Allow window resizing + + # Initialize list to store scheduled games + game_list: list[str] = ["Game Schedule:"] + + # Available teams for dropdown selection + team_options: list[str] = [ + "Eagles", + "Tigers", + "Bears", + "Sharks", + "Falcons", + "Dragons", + ] + + # Create and arrange all GUI components + create_widgets(window, game_list, team_options) + + # Start the main event loop + window.mainloop() + + +def create_widgets( + window: tk.Tk, game_list: list[str], team_options: list[str] +) -> None: + """Create and position all GUI widgets in the main window""" + # Configure theme colors + primary_color = "#4A7A8C" + secondary_color = "#F2E2D2" + accent_color = "#D96941" + text_color = "#262626" + + # Configure font styles + title_font = ("Arial", 14, "bold") + label_font = ("Arial", 10) + button_font = ("Arial", 10, "bold") + + # Variables to store selected teams + visitor_var: StringVar = StringVar(window) + home_var: StringVar = StringVar(window) + + # Set default selections + visitor_var.set(team_options[0]) + home_var.set(team_options[1]) + + # Configure grid weights for responsive layout + window.columnconfigure(0, weight=1) + window.columnconfigure(1, weight=1) + window.rowconfigure(0, weight=1) + window.rowconfigure(1, weight=1) + window.rowconfigure(2, weight=3) + + # Create left frame for team selection with styling + left_frame = tk.Frame(window, padx=15, pady=15, bg=secondary_color) + left_frame.grid(row=0, column=0, rowspan=2, sticky="nsew") + + # Title label + title_label = Label( + left_frame, + text="Team Selection", + font=title_font, + bg=secondary_color, + fg=text_color, + ) + title_label.grid(row=0, column=0, columnspan=2, pady=(0, 15), sticky="n") + + # Visitor team selection + visitor_label = Label( + left_frame, + text="Visitor Team:", + font=label_font, + bg=secondary_color, + fg=text_color, + ) + visitor_label.grid(row=1, column=0, sticky="w", pady=5) + + visitor_dropdown = OptionMenu(left_frame, visitor_var, *team_options) + visitor_dropdown.config( + font=label_font, bg="white", fg=text_color, relief=tk.RAISED, bd=2 + ) + visitor_dropdown["menu"].config(bg="white", fg=text_color) + visitor_dropdown.grid(row=1, column=1, sticky="ew", pady=5) + + # Home team selection + home_label = Label( + left_frame, + text="Home Team:", + font=label_font, + bg=secondary_color, + fg=text_color, + ) + home_label.grid(row=2, column=0, sticky="w", pady=5) + + home_dropdown = OptionMenu(left_frame, home_var, *team_options) + home_dropdown.config( + font=label_font, bg="white", fg=text_color, relief=tk.RAISED, bd=2 + ) + home_dropdown["menu"].config(bg="white", fg=text_color) + home_dropdown.grid(row=2, column=1, sticky="ew", pady=5) + + # Create calendar frame on the right with styling + right_frame = tk.Frame(window, padx=15, pady=15, bg=secondary_color) + right_frame.grid(row=0, column=1, rowspan=2, sticky="nsew") + + # Calendar title + cal_title = Label( + right_frame, + text="Select Date", + font=title_font, + bg=secondary_color, + fg=text_color, + ) + cal_title.pack(pady=(0, 10)) + + calendar = Calendar( + right_frame, + selectmode="day", + year=2023, + month=7, + day=16, + font=label_font, + background=primary_color, + foreground="white", + selectbackground=accent_color, + selectforeground="white", + borderwidth=2, + relief=tk.RAISED, + locale="en_US", + ) + calendar.pack(fill="both", expand=True) + + # Create game list display area with styling + display_frame = tk.Frame(window, padx=15, pady=15, bg=secondary_color) + display_frame.grid(row=2, column=0, columnspan=2, sticky="nsew") + + # Display title + display_title = Label( + display_frame, + text="Game Schedule", + font=title_font, + bg=secondary_color, + fg=text_color, + ) + display_title.pack(pady=(0, 10)) + + # Text widget with scrollbar for game list + game_display = Text( + display_frame, + wrap=tk.WORD, + height=10, + font=label_font, + bg="white", + fg=text_color, + bd=2, + relief=tk.SUNKEN, + ) + game_display.pack(side=tk.LEFT, fill="both", expand=True) + + scrollbar = Scrollbar( + display_frame, + command=game_display.yview, + bg=primary_color, + troughcolor=secondary_color, + relief=tk.FLAT, + ) + scrollbar.pack(side=tk.RIGHT, fill=tk.Y) + game_display.config(yscrollcommand=scrollbar.set) + + # Initialize display with empty list + update_game_display(game_display, game_list) + # Add to schedule button - pass game_display to add_game + add_button = Button( + left_frame, + text="Add to Schedule", + command=lambda: add_game( + window, game_list, visitor_var, home_var, calendar, game_display + ), + font=button_font, + bg=accent_color, + fg="white", + activebackground="#BF4924", + activeforeground="white", + relief=tk.RAISED, + bd=3, + ) + add_button.grid(row=3, column=0, columnspan=2, pady=20, sticky="ew") -window = tk.Tk() + # Configure weights for responsive resizing + left_frame.columnconfigure(1, weight=1) + right_frame.columnconfigure(0, weight=1) + right_frame.rowconfigure(0, weight=1) + display_frame.columnconfigure(0, weight=1) + display_frame.rowconfigure(0, weight=1) -# Adjust size -window.geometry("600x500") -gameList =["Game List:"] -# Change the label text -def show(): - game = selected1.get() + " vs " + selected2.get()+" on "+cal.get_date() - gameList.append(game) - #print(gameList) - gameListshow = "\n".join(gameList) - #print(gameList) - label.config(text=gameListshow) +def add_game( + window: tk.Tk, + game_list: list[str], + visitor_var: StringVar, + home_var: StringVar, + calendar: Calendar, + game_display: Text, +) -> None: + """Add a new game to the schedule and update the display""" + # Get selected values + visitor = visitor_var.get() + home = home_var.get() + date = calendar.get_date() + # Validate input (prevent same team match) + if visitor == home: + show_error(window, "Input Error", "Visitor and home teams cannot be the same!") + return -# Dropdown menu options -options = [ - "Team 1", - "Team 2", - "Team 3", - "Team 4", - "Team 5", - "Team 6" -] + # Create game entry and add to list + game_entry = f"{visitor} vs {home} on {date}" + game_list.append(game_entry) -# datatype of menu text -selected1 = StringVar() -selected2 = StringVar() + # Update the display with new list + update_game_display(game_display, game_list) -# initial menu text -selected1.set("Team 1") -selected2.set("Team 2") -# Create Dropdown menu -L1 = Label(window, text="Visitor") -L1.place(x=40, y=35) -drop1 = OptionMenu(window, selected1, *options) -drop1.place(x=100, y=30) +def update_game_display(display: Text, game_list: list[str]) -> None: + """Update the text widget with current game list""" + # Clear existing content + display.delete(1.0, tk.END) + # Insert updated list + display.insert(tk.END, "\n".join(game_list)) -L2 = Label(window, text="VS") -L2.place(x=100, y=80) -L3 = Label(window, text="Home") -L3.place(x=40, y=115) -drop2 = OptionMenu(window, selected2, *options) -drop2.place(x=100, y=110) +def show_error(window: tk.Tk, title: str, message: str) -> None: + """Display an error message in a modal dialog""" + error_window = Toplevel(window) + error_window.title(title) + error_window.geometry("350x180") + error_window.resizable(False, False) + error_window.configure(bg="#F8D7DA") # Light red background -# Add Calendar -cal = Calendar(window, selectmode='day', - year=2022, month=12, - day=1) + # Center error window over main window + error_window.geometry( + "+%d+%d" + % ( + window.winfo_rootx() + window.winfo_width() // 2 - 175, + window.winfo_rooty() + window.winfo_height() // 2 - 90, + ) + ) -cal.place(x=300, y=20) + # Error message frame + message_frame = tk.Frame(error_window, bg="#F8D7DA") + message_frame.pack(fill="both", expand=True, padx=20, pady=20) + # Error message label + message_label = Label( + message_frame, + text=message, + font=("Arial", 10), + bg="#F8D7DA", + fg="#842029", + wraplength=300, + ) + message_label.pack(fill="both", expand=True) + # Close button + close_button = Button( + error_window, + text="OK", + command=error_window.destroy, + font=("Arial", 10, "bold"), + bg="#DC3545", + fg="white", + activebackground="#C82333", + activeforeground="white", + relief=tk.RAISED, + bd=2, + padx=15, + pady=5, + ) + close_button.pack(pady=10) -# Create button, it will change label text -button = Button( window, text="Add to calender", command=show).place(x=100,y=200) + # Make dialog modal + error_window.transient(window) + error_window.grab_set() + window.wait_window(error_window) -# Create Label -label = Label(window, text=" ") -label.place(x=150, y=250) -window.mainloop() \ No newline at end of file +if __name__ == "__main__": + main() diff --git a/Electronics_Algorithms/resistance.py b/Electronics_Algorithms/resistance.py index c088732d90c..ca8e27f257e 100644 --- a/Electronics_Algorithms/resistance.py +++ b/Electronics_Algorithms/resistance.py @@ -1,69 +1,38 @@ -def resistance_calculator(material:str, lenght:float, section:float, temperature:float): - """ - material is a string indicating the material of the wire - - lenght is a floating value indicating the lenght of the wire in meters - - diameter is a floating value indicating the diameter of the wire in millimeters - - temperature is a floating value indicating the temperature at which the wire is operating in °C - - Available materials: - - silver - - copper - - aluminium - - tungsten - - iron - - steel - - zinc - - solder""" - - materials = { - "silver": { - "rho": 0.0163, - "coefficient": 0.0038 - }, - - "copper": { - "rho": 0.0178, - "coefficient": 0.00381 - }, - - "aluminium": { - "rho": 0.0284, - "coefficient": 0.004 - }, - - "tungsten": { - "rho": 0.055, - "coefficient": 0.0045 - }, - - "iron": { - "rho": 0.098, - "coefficient": 0.006 - }, - - "steel": { - "rho": 0.15, - "coefficient": 0.0047 - }, - - "zinc": { - "rho": 0.06, - "coefficient": 0.0037 - }, - - "solder": { - "rho": 0.12, - "coefficient": 0.0043 - } - } - - rho_20deg = materials[material]["rho"] - temp_coefficient = materials[material]["coefficient"] - - rho = rho_20deg * (1 + temp_coefficient * (temperature - 20)) - resistance = rho * lenght / section - - return f"{resistance}Ω" +def resistance_calculator( + material: str, length: float, section: float, temperature: float +) -> str: + """ + Calculate the electrical resistance of a wire based on its properties. + + Parameters: + material (str): Material of the wire (available: silver, copper, aluminium, tungsten, iron, steel, zinc, solder) + length (float): Length of the wire in meters + section (float): Cross-sectional area of the wire in square millimeters (mm²) + temperature (float): Operating temperature of the wire in °C + + Returns: + str: Calculated resistance in ohms (Ω) + """ + # Material properties: resistivity at 20°C (ρ in Ω·mm²/m) and temperature coefficient (α in 1/°C) + materials: dict[str, dict[str, float]] = { + "silver": {"rho": 0.0163, "coefficient": 0.0038}, + "copper": {"rho": 0.0178, "coefficient": 0.00381}, + "aluminium": {"rho": 0.0284, "coefficient": 0.004}, + "tungsten": {"rho": 0.055, "coefficient": 0.0045}, + "iron": {"rho": 0.098, "coefficient": 0.006}, + "steel": {"rho": 0.15, "coefficient": 0.0047}, + "zinc": {"rho": 0.06, "coefficient": 0.0037}, + "solder": {"rho": 0.12, "coefficient": 0.0043}, + } + + # Get material properties (will raise KeyError for invalid materials) + rho_20deg: float = materials[material]["rho"] + temp_coefficient: float = materials[material]["coefficient"] + + # Calculate resistivity at operating temperature + rho: float = rho_20deg * (1 + temp_coefficient * (temperature - 20)) + + # Calculate resistance (R = ρ * L / S) + resistance: float = rho * length / section + + return f"{resistance}Ω" diff --git a/Emoji Dictionary/QT_GUI.py b/Emoji Dictionary/QT_GUI.py index a4dd819ccb8..ebbe289d038 100644 --- a/Emoji Dictionary/QT_GUI.py +++ b/Emoji Dictionary/QT_GUI.py @@ -1,67 +1,136 @@ - -# -*- coding: utf-8 -*- - +import os import sys + +from emoji import demojize +from PyQt5 import uic from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * -from PyQt5 import uic -from emoji import demojize -import os + class MainWindow(QMainWindow): - def __init__(self): - super(MainWindow, self).__init__() - - # Load the UI file - uic.loadUi(os.path.join(os.path.dirname(__file__),'QT_GUI.ui'),self) - self.pushButton_4.clicked.connect(self.close) - self.pushButton_2.clicked.connect(lambda:search_emoji()) - self.pushButton_3.clicked.connect(lambda:clear_text()) - cells = [ - - ["🐒", "🐕", "🐎", "🐪", "🐁", "🐘", "🦘", "🦈", "🐓", "🐝", "👀", "🦴", "👩🏿", "‍🤝", "🧑", "🏾", "👱🏽", "‍♀", "🎞", "🎨", "⚽"], - ["🍕", "🍗", "🍜", "☕", "🍴", "🍉", "🍓", "🌴", "🌵", "🛺", "🚲", "🛴", "🚉", "🚀", "✈", "🛰", "🚦", "🏳", "‍🌈", "🌎", "🧭"], - ["🔥", "❄", "🌟", "🌞", "🌛", "🌝", "🌧", "🧺", "🧷", "🪒", "⛲", "🗼", "🕌", "👁", "‍🗨", "💬", "™", "💯", "🔕", "💥", "❤"], - ["😀", "🥰", "😴", "🤓", "🤮", "🤬", "😨", "🤑", "😫", "😎"], - ] - def emoji_wight_btn(): - if self.emoji_widget.isVisible(): - self.emoji_widget.hide() - else: - self.emoji_widget.show() - - def search_emoji(): + def __init__(self): + super(MainWindow, self).__init__() + + # Load the UI file + uic.loadUi(os.path.join(os.path.dirname(__file__), "QT_GUI.ui"), self) + self.pushButton_4.clicked.connect(self.close) + self.pushButton_2.clicked.connect(lambda: search_emoji()) + self.pushButton_3.clicked.connect(lambda: clear_text()) + cells = [ + [ + "🐒", + "🐕", + "🐎", + "🐪", + "🐁", + "🐘", + "🦘", + "🦈", + "🐓", + "🐝", + "👀", + "🦴", + "👩🏿", + "‍🤝", + "🧑", + "🏾", + "👱🏽", + "‍♀", + "🎞", + "🎨", + "⚽", + ], + [ + "🍕", + "🍗", + "🍜", + "☕", + "🍴", + "🍉", + "🍓", + "🌴", + "🌵", + "🛺", + "🚲", + "🛴", + "🚉", + "🚀", + "✈", + "🛰", + "🚦", + "🏳", + "‍🌈", + "🌎", + "🧭", + ], + [ + "🔥", + "❄", + "🌟", + "🌞", + "🌛", + "🌝", + "🌧", + "🧺", + "🧷", + "🪒", + "⛲", + "🗼", + "🕌", + "👁", + "‍🗨", + "💬", + "™", + "💯", + "🔕", + "💥", + "❤", + ], + ["😀", "🥰", "😴", "🤓", "🤮", "🤬", "😨", "🤑", "😫", "😎"], + ] + + def emoji_wight_btn(): + if self.emoji_widget.isVisible(): + self.emoji_widget.hide() + else: + self.emoji_widget.show() + + def search_emoji(): word = self.lineEdit.text() - print(f"Field Text: {word}") + print(f"Field Text: {word}") if word == "": - self.textEdit.setText("You have entered no emoji.") + self.textEdit.setText("You have entered no emoji.") else: - means = demojize(word) - self.textEdit.setText("Meaning of Emoji : " + str(word) + "\n\n" + means.replace("::", ":\n: ")) - - def add_input_emoji(emoji): - self.lineEdit.setText(self.lineEdit.text() + emoji) - - def clear_text(): - self.lineEdit.setText("") - self.textEdit.setText("") - - self.emoji_buttons = [] - self.emoji_layout = QGridLayout() - self.emoji_widget = QWidget() - self.emoji_widget.setLayout(self.emoji_layout) - self.frame_2.layout().addWidget(self.emoji_widget) - self.emoji_widget.hide() - self.pushButton.clicked.connect(lambda:emoji_wight_btn()) - - - for row_idx, row in enumerate(cells): - for col_idx, emoji in enumerate(row): - button = QPushButton(emoji) - button.setFixedSize(40, 40) - button.setFont(QFont("Arial", 20)) - button.setStyleSheet(""" + means = demojize(word) + self.textEdit.setText( + "Meaning of Emoji : " + + str(word) + + "\n\n" + + means.replace("::", ":\n: ") + ) + + def add_input_emoji(emoji): + self.lineEdit.setText(self.lineEdit.text() + emoji) + + def clear_text(): + self.lineEdit.setText("") + self.textEdit.setText("") + + self.emoji_buttons = [] + self.emoji_layout = QGridLayout() + self.emoji_widget = QWidget() + self.emoji_widget.setLayout(self.emoji_layout) + self.frame_2.layout().addWidget(self.emoji_widget) + self.emoji_widget.hide() + self.pushButton.clicked.connect(lambda: emoji_wight_btn()) + + for row_idx, row in enumerate(cells): + for col_idx, emoji in enumerate(row): + button = QPushButton(emoji) + button.setFixedSize(40, 40) + button.setFont(QFont("Arial", 20)) + button.setStyleSheet(""" QPushButton { background-color: #ffffff; border: 1px solid #e0e0e0; @@ -71,11 +140,12 @@ def clear_text(): background-color: #f0f0f0; } """) - button.clicked.connect(lambda checked, e=emoji: add_input_emoji(e)) - self.emoji_layout.addWidget(button, row_idx, col_idx) - self.emoji_buttons.append(button) - -if __name__ == '__main__': + button.clicked.connect(lambda checked, e=emoji: add_input_emoji(e)) + self.emoji_layout.addWidget(button, row_idx, col_idx) + self.emoji_buttons.append(button) + + +if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() diff --git a/Emoji Dictionary/emoji_dictionary.py b/Emoji Dictionary/emoji_dictionary.py index db13725f1fe..2d6d5dca00b 100644 --- a/Emoji Dictionary/emoji_dictionary.py +++ b/Emoji Dictionary/emoji_dictionary.py @@ -1,17 +1,15 @@ -# Emoji Dictionary - -# ----------------------------------------------------------------------------------------------------- -from tkinter import * # importing the necessary libraries +import tkinter as tk import tkinter.messagebox as mbox -import tkinter as tk # imported tkinter as tk -import emoji +from tkinter import Button, Entry, Event, Label, StringVar, Text +from typing import Any -# ----------------------------------------------------------------------------------------------- +import emoji class Keypad(tk.Frame): + """A custom keypad frame containing emoji buttons and control functions""" - cells = [ + cells: list[list[str]] = [ ["😀", "🥰", "😴", "🤓", "🤮", "🤬", "😨", "🤑", "😫", "😎"], [ "🐒", @@ -84,266 +82,336 @@ class Keypad(tk.Frame): ], ] - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - self.target = None - self.memory = "" - - for y, row in enumerate(self.cells): - for x, item in enumerate(row): - b = tk.Button( + def __init__(self, parent: tk.Tk, *args: Any, **kwargs: Any) -> None: + """Initialize the keypad frame with emoji buttons and controls""" + super().__init__(parent, *args, **kwargs) + self.target: Entry | None = None + self.memory: str = "" + self.label: Label | None = None + + self._create_buttons() + + def _create_buttons(self) -> None: + """Create and arrange all buttons in the keypad""" + try: + for row_idx, row in enumerate(self.cells): + for col_idx, emoji_char in enumerate(row): + btn = Button( + self, + text=emoji_char, + command=lambda text=emoji_char: self.append(text), + font=("Arial", 14), + bg="yellow", + fg="blue", + borderwidth=3, + relief="raised", + ) + btn.grid(row=row_idx, column=col_idx, sticky="news") + + control_buttons = [ + ("Space", self.space, 0, 10, 2), + ("Tab", self.tab, 0, 12, 2), + ("Backspace", self.backspace, 0, 14, 3), + ("Clear", self.clear, 0, 17, 2), + ("Hide", self.hide, 0, 19, 2), + ] + + for text, cmd, row, col, colspan in control_buttons: + btn = Button( self, - text=item, - command=lambda text=item: self.append(text), + text=text, + command=cmd, font=("Arial", 14), bg="yellow", fg="blue", borderwidth=3, relief="raised", ) - b.grid(row=y, column=x, sticky="news") - - x = tk.Button( - self, - text="Space", - command=self.space, - font=("Arial", 14), - bg="yellow", + btn.grid(row=row, column=col, columnspan=colspan, sticky="news") + + except Exception as e: + print(f"Error creating keypad buttons: {str(e)}") + # Optionally show error message to user + # mbox.showerror("Error", f"Failed to initialize keypad: {str(e)}") + + def get(self) -> str | None: + """Get current text from target entry widget""" + try: + if self.target: + return self.target.get() + return None + except Exception as e: + print(f"Error getting text: {str(e)}") + return None + + def append(self, text: str) -> None: + """Append text to target entry widget""" + try: + if self.target: + self.target.insert("end", text) + except Exception as e: + print(f"Error appending text: {str(e)}") + mbox.showerror("Error", f"Failed to append text: {str(e)}") + + def clear(self) -> None: + """Clear all text from target entry widget""" + try: + if self.target: + self.target.delete(0, tk.END) + except Exception as e: + print(f"Error clearing text: {str(e)}") + mbox.showerror("Error", f"Failed to clear text: {str(e)}") + + def backspace(self) -> None: + """Remove last character from target entry widget""" + try: + if self.target: + current_text = self.get() + if current_text: + new_text = current_text[:-1] + self.clear() + self.append(new_text) + except Exception as e: + print(f"Error during backspace: {str(e)}") + mbox.showerror("Error", f"Failed to perform backspace: {str(e)}") + + def space(self) -> None: + """Add a space to target entry widget""" + try: + if self.target: + self.append(" ") + except Exception as e: + print(f"Error adding space: {str(e)}") + mbox.showerror("Error", f"Failed to add space: {str(e)}") + + def tab(self) -> None: + """Add 5 spaces (simulated tab) to target entry widget""" + try: + if self.target: + self.append(" ") + except Exception as e: + print(f"Error adding tab: {str(e)}") + mbox.showerror("Error", f"Failed to add tab: {str(e)}") + + def copy(self) -> None: + """Copy current text to memory (clipboard simulation)""" + try: + if self.target: + self.memory = self.get() or "" + print(f"Copied to memory: {self.memory}") + except Exception as e: + print(f"Error copying text: {str(e)}") + mbox.showerror("Error", f"Failed to copy text: {str(e)}") + + def paste(self) -> None: + """Paste text from memory to target entry widget""" + try: + if self.target and self.memory: + self.append(self.memory) + except Exception as e: + print(f"Error pasting text: {str(e)}") + mbox.showerror("Error", f"Failed to paste text: {str(e)}") + + def show(self, entry: Entry) -> None: + """Display keypad and set target entry widget""" + try: + self.target = entry + self.place(relx=0.5, rely=0.6, anchor="c") + except Exception as e: + print(f"Error showing keypad: {str(e)}") + mbox.showerror("Error", f"Failed to show keypad: {str(e)}") + + def hide(self) -> None: + """Hide keypad and clear target entry widget""" + try: + self.target = None + self.place_forget() + except Exception as e: + print(f"Error hiding keypad: {str(e)}") + mbox.showerror("Error", f"Failed to hide keypad: {str(e)}") + + +def clear_text() -> None: + """Clear both input entry and output text widgets""" + try: + inputentry.delete(0, tk.END) + outputtxt.delete("1.0", tk.END) + except Exception as e: + print(f"Error clearing text: {str(e)}") + mbox.showerror("Error", f"Failed to clear text fields: {str(e)}") + + +def search_emoji() -> None: + """Search for meaning of entered emoji and display result""" + try: + emoji_input = inputentry.get() + if not emoji_input: + outputtxt.delete("1.0", tk.END) + outputtxt.insert(tk.END, "No emoji entered. Please input an emoji first.") + return + + # Check if input contains non-emoji characters + if not all(emoji.is_emoji(char) for char in emoji_input): + outputtxt.delete("1.0", tk.END) + outputtxt.insert(tk.END, "Invalid input! Please enter only emojis.") + return + + meaning = emoji.demojize(emoji_input) + outputtxt.delete("1.0", tk.END) + outputtxt.insert(tk.END, f"Meaning of Emoji: {emoji_input}\n\n{meaning}") + + except emoji.EmojiNotFoundError: + outputtxt.delete("1.0", tk.END) + outputtxt.insert(tk.END, "Emoji not recognized. Please try another emoji.") + except Exception as e: + print(f"Error processing emoji: {str(e)}") + outputtxt.delete("1.0", tk.END) + outputtxt.insert(tk.END, f"An error occurred: {str(e)}") + + +def exit_win() -> None: + """Handle window closing confirmation""" + try: + if mbox.askokcancel("Exit", "Do you want to exit?"): + window.destroy() + except Exception as e: + print(f"Error exiting application: {str(e)}") + mbox.showerror("Error", f"Failed to exit application: {str(e)}") + + +def on_inputentry_click(event: Event) -> None: + """Handle initial click on input entry to clear placeholder""" + try: + global firstclick1 + if firstclick1: + firstclick1 = False + inputentry.delete(0, tk.END) + except Exception as e: + print(f"Error handling input click: {str(e)}") + + +if __name__ == "__main__": + try: + # Initialize main window + window: tk.Tk = tk.Tk() + window.title("Emoji Dictionary") + window.geometry("1000x700") + + # Title label + title_label: Label = Label( + window, + text="EMOJI DICTIONARY", + font=("Arial", 50, "underline"), + fg="magenta", + ) + title_label.place(x=160, y=10) + + # Instruction label + input_label: Label = Label( + window, + text="Enter any Emoji you want to search...", + font=("Arial", 30), + fg="green", + ) + input_label.place(x=160, y=120) + + # Input entry widget + myname: StringVar = StringVar(window) + firstclick1: bool = True + inputentry: Entry = Entry( + window, + font=("Arial", 35), + width=28, + border=2, + bg="light yellow", + fg="brown", + textvariable=myname, + ) + inputentry.insert(0, "Click to enter emoji...") + inputentry.bind("", on_inputentry_click) + inputentry.place(x=120, y=180) + + # Search button + search_btn: Button = Button( + window, + text="🔍 SEARCH", + command=search_emoji, + font=("Arial", 20), + bg="light green", fg="blue", borderwidth=3, relief="raised", ) - x.grid(row=0, column=10, columnspan="2", sticky="news") - - x = tk.Button( - self, - text="tab", - command=self.tab, - font=("Arial", 14), - bg="yellow", + search_btn.place(x=270, y=250) + + # Clear button + clear_btn: Button = Button( + window, + text="🧹 CLEAR", + command=clear_text, + font=("Arial", 20), + bg="orange", fg="blue", borderwidth=3, relief="raised", ) - x.grid(row=0, column=12, columnspan="2", sticky="news") - - x = tk.Button( - self, - text="Backspace", - command=self.backspace, - font=("Arial", 14), - bg="yellow", - fg="blue", + clear_btn.place(x=545, y=250) + + # Output label + output_label: Label = Label( + window, text="Meaning...", font=("Arial", 30), fg="green" + ) + output_label.place(x=160, y=340) + + # Output text widget + outputtxt: Text = Text( + window, + height=7, + width=57, + font=("Arial", 17), + bg="light yellow", + fg="brown", borderwidth=3, - relief="raised", + relief="solid", ) - x.grid(row=0, column=14, columnspan="3", sticky="news") - - x = tk.Button( - self, - text="Clear", - command=self.clear, - font=("Arial", 14), - bg="yellow", - fg="blue", + outputtxt.place(x=120, y=400) + + # Exit button + exit_btn: Button = Button( + window, + text="❌ EXIT", + command=exit_win, + font=("Arial", 20), + bg="red", + fg="black", borderwidth=3, relief="raised", ) - x.grid(row=0, column=17, columnspan="2", sticky="news") - - x = tk.Button( - self, - text="Hide", - command=self.hide, - font=("Arial", 14), - bg="yellow", - fg="blue", + exit_btn.place(x=435, y=610) + + # Initialize keypad + keypad: Keypad = Keypad(window) + + # Keypad toggle button + keypad_btn: Button = Button( + window, + text="⌨", + command=lambda: keypad.show(inputentry), + font=("Arial", 18), + bg="light yellow", + fg="green", borderwidth=3, relief="raised", ) - x.grid(row=0, column=19, columnspan="2", sticky="news") + keypad_btn.place(x=870, y=183) - def get(self): - if self.target: - return self.target.get() + # Configure window close protocol + window.protocol("WM_DELETE_WINDOW", exit_win) - def append(self, text): - if self.target: - self.target.insert("end", text) + # Start main event loop + window.mainloop() - def clear(self): - if self.target: - self.target.delete(0, END) - - def backspace(self): - if self.target: - text = self.get() - text = text[:-1] - self.clear() - self.append(text) - - def space(self): - if self.target: - text = self.get() - text = text + " " - self.clear() - self.append(text) - - def tab(self): # 5 spaces - if self.target: - text = self.get() - text = text + " " - self.clear() - self.append(text) - - def copy(self): - # TODO: copy to clipboad - if self.target: - self.memory = self.get() - self.label["text"] = "memory: " + self.memory - print(self.memory) - - def paste(self): - # TODO: copy from clipboad - if self.target: - self.append(self.memory) - - def show(self, entry): - self.target = entry - - self.place(relx=0.5, rely=0.6, anchor="c") - - def hide(self): - self.target = None - - self.place_forget() - - -# function defined th=o clear both the input text and output text -------------------------------------------------- -def clear_text(): - inputentry.delete(0, END) - outputtxt.delete("1.0", "end") - - -# function to search emoji -def search_emoji(): - word = inputentry.get() - if word == "": - outputtxt.insert(END, "You have entered no emoji.") - else: - means = emoji.demojize(word) - outputtxt.insert(END, "Meaning of Emoji : " + str(word) + "\n\n" + means) - - -# main window created -window = tk.Tk() -window.title("Emoji Dictionary") -window.geometry("1000x700") - -# for writing Dictionary label, at the top of window -dic = tk.Label( - text="EMOJI DICTIONARY", font=("Arial", 50, "underline"), fg="magenta" -) # same way bg -dic.place(x=160, y=10) - -start1 = tk.Label( - text="Enter any Emoji you want to search...", font=("Arial", 30), fg="green" -) # same way bg -start1.place(x=160, y=120) - -myname = StringVar(window) -firstclick1 = True - - -def on_inputentry_click(event): - """function that gets called whenever entry1 is clicked""" - global firstclick1 - - if firstclick1: # if this is the first time they clicked it - firstclick1 = False - inputentry.delete(0, "end") # delete all the text in the entry - - -# Taking input from TextArea -# inputentry = Entry(window,font=("Arial", 35), width=33, border=2) -inputentry = Entry( - window, font=("Arial", 35), width=28, border=2, bg="light yellow", fg="brown" -) -inputentry.place(x=120, y=180) - -# # Creating Search Button -Button( - window, - text="🔍 SEARCH", - command=search_emoji, - font=("Arial", 20), - bg="light green", - fg="blue", - borderwidth=3, - relief="raised", -).place(x=270, y=250) - -# # creating clear button -Button( - window, - text="🧹 CLEAR", - command=clear_text, - font=("Arial", 20), - bg="orange", - fg="blue", - borderwidth=3, - relief="raised", -).place(x=545, y=250) - -# meaning label -start1 = tk.Label(text="Meaning...", font=("Arial", 30), fg="green") # same way bg -start1.place(x=160, y=340) - -# # Output TextBox Creation -outputtxt = tk.Text( - window, - height=7, - width=57, - font=("Arial", 17), - bg="light yellow", - fg="brown", - borderwidth=3, - relief="solid", -) -outputtxt.place(x=120, y=400) - -# function for exiting -def exit_win(): - if mbox.askokcancel("Exit", "Do you want to exit?"): - window.destroy() - - -# # creating exit button -Button( - window, - text="❌ EXIT", - command=exit_win, - font=("Arial", 20), - bg="red", - fg="black", - borderwidth=3, - relief="raised", -).place(x=435, y=610) - -keypad = Keypad(window) - -# # creating speech to text button -v_keypadb = Button( - window, - text="⌨", - command=lambda: keypad.show(inputentry), - font=("Arial", 18), - bg="light yellow", - fg="green", - borderwidth=3, - relief="raised", -).place(x=870, y=183) - -window.protocol("WM_DELETE_WINDOW", exit_win) -window.mainloop() + except Exception as e: + print(f"Fatal error during application initialization: {str(e)}") + # Consider showing a critical error message here + # mbox.showerror("Critical Error", f"Failed to start application: {str(e)}") diff --git a/Emoji Dictionary/requirements.txt b/Emoji Dictionary/requirements.txt deleted file mode 100644 index 840507a2445..00000000000 --- a/Emoji Dictionary/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -tkinter -messagebox -emoji diff --git a/Encryption using base64.py b/Encryption using base64.py index a5d874e00e2..6e2bc924f1f 100644 --- a/Encryption using base64.py +++ b/Encryption using base64.py @@ -1,14 +1,15 @@ import base64 -#Encryption + +# Encryption message = input() -message_bytes = message.encode('ascii') +message_bytes = message.encode("ascii") base64_bytes = base64.b64encode(message_bytes) -base64_message = base64_bytes.decode('ascii') +base64_message = base64_bytes.decode("ascii") print(base64_message) -#Decryption -base64_bytes = base64_message.encode('ascii') +# Decryption +base64_bytes = base64_message.encode("ascii") message_bytes = base64.b64decode(base64_bytes) -message = message_bytes.decode('ascii') +message = message_bytes.decode("ascii") print(message) diff --git a/EncryptionTool.py b/EncryptionTool.py index f6600752fa6..4e0f8da1f38 100644 --- a/EncryptionTool.py +++ b/EncryptionTool.py @@ -2,7 +2,6 @@ # Simple encryption script for text # This was one my first versions of this script # 09/07/2017 -from __future__ import print_function import math @@ -46,7 +45,7 @@ def decrypt(enc_text): def readAndDecrypt(filename): - file = open(filename, "r") + file = open(filename) data = file.read() datalistint = [] actualdata = [] @@ -62,7 +61,7 @@ def readAndDecrypt(filename): def readAndEncrypt(filename): - file = open(filename, "r") + file = open(filename) data = file.read() datalist = list(data) encrypted_list = list() diff --git a/Exception_Handling_in_Python.py b/Exception_Handling_in_Python.py index 17f0e5ca1c0..c3e92fad2a4 100644 --- a/Exception_Handling_in_Python.py +++ b/Exception_Handling_in_Python.py @@ -83,7 +83,7 @@ try: # Instead of aaa.txt lets try opening abc.txt - f = open("abc.txt", "r") + f = open("abc.txt") except FileNotFoundError: print("Incorrect file name used") diff --git a/Extract-Table-from-pdf-txt-docx/main.py b/Extract-Table-from-pdf-txt-docx/main.py index d74649cd054..465faf38cfa 100644 --- a/Extract-Table-from-pdf-txt-docx/main.py +++ b/Extract-Table-from-pdf-txt-docx/main.py @@ -1,104 +1,87 @@ -# %% -import pandas as pd import os + +import pandas as pd import tabula from docx.api import Document -# %% -if os.path.isdir("Parent") == True: - os.chdir("Parent") -# FOR CHILD1 DIRECTORY -if os.path.isdir("Child1") == True: - os.chdir("Child1") -# PDF FILE READING -if os.path.isfile("Pdf1_Child1.pdf") == True: - df_pdf_child1 = tabula.read_pdf("Pdf1_Child1.pdf", pages="all") -# DOCUMENT READING -if os.path.isfile("Document_Child1.docx") == True: - document = Document("Document_Child1.docx") - table = document.tables[0] - data = [] +def process_child_directory(child_dir: str) -> dict[str, pd.DataFrame]: + """Process a child directory and return dataframes from its files""" + results = {} + + if not os.path.isdir(child_dir): + print(f"Skipping {child_dir} - directory not found") + return results + + original_dir = os.getcwd() # Save current directory + os.chdir(child_dir) - keys = None - for i, row in enumerate(table.rows): - text = (cell.text for cell in row.cells) - if i == 0: - keys = tuple(text) - continue - row_data = dict(zip(keys, text)) - data.append(row_data) -df_document_child1 = pd.DataFrame(data) -# TEXT READING -if os.path.isfile("Text_Child1.txt") == True: - df_text_child1 = pd.read_csv("Text_Child1.txt") + # Process PDF + pdf_name = f"Pdf1_{os.path.basename(child_dir)}.pdf" + if os.path.isfile(pdf_name): + try: + results["pdf"] = tabula.read_pdf(pdf_name, pages="all") + print(f"Read PDF: {pdf_name}") + except Exception as e: + print(f"Error reading PDF {pdf_name}: {e}") -# %% -df_text_child1 + # Process DOCX + docx_name = f"Document_{os.path.basename(child_dir)}.docx" + if os.path.isfile(docx_name): + try: + doc = Document(docx_name) + table = doc.tables[0] + data = [] + keys = None + for i, row in enumerate(table.rows): + texts = [cell.text for cell in row.cells] + if i == 0: + keys = tuple(texts) + continue + data.append(dict(zip(keys, texts))) + results["document"] = pd.DataFrame(data) + print(f"Read DOCX: {docx_name}") + except Exception as e: + print(f"Error reading DOCX {docx_name}: {e}") + # Process TXT + txt_name = f"Text_{os.path.basename(child_dir)}.txt" + if os.path.isfile(txt_name): + try: + results["text"] = pd.read_csv(txt_name) + print(f"Read TXT: {txt_name}") + except Exception as e: + print(f"Error reading TXT {txt_name}: {e}") -# %% -os.chdir("../") -if os.path.isdir("Parent") == True: - os.chdir("Parent") -# FOR CHILD2 DIRECTORY -if os.path.isdir("Child2") == True: - os.chdir("Child2") -# PDF FILE READING -if os.path.isfile("Pdf1_Child2.pdf") == True: - df_pdf_child2 = tabula.read_pdf("Pdf1_Child2.pdf", pages="all") -# DOCUMENT READING -if os.path.isfile("Document_Child2.docx") == True: - document = Document("Document_Child2.docx") - table = document.tables[0] - data = [] + os.chdir(original_dir) # Return to original directory + return results - keys = None - for i, row in enumerate(table.rows): - text = (cell.text for cell in row.cells) - if i == 0: - keys = tuple(text) - continue - row_data = dict(zip(keys, text)) - data.append(row_data) -df_document_child2 = pd.DataFrame(data) -# TEXT READING -if os.path.isfile("Text_Child2.txt") == True: - df_text_child2 = pd.read_csv("Text_Child2.txt") -# %% -df_pdf_child2[0].head(4) +if __name__ == "__main__": + # Get the directory where the script (main.py) is located + script_dir = os.path.dirname(os.path.abspath(__file__)) -# %% -os.chdir("../") -if os.path.isdir("Parent") == True: - os.chdir("Parent") -# FOR CHILD3 DIRECTORY -if os.path.isdir("Child3") == True: - os.chdir("Child3") -# PDF FILE READING -if os.path.isfile("Pdf1_Child3.pdf") == True: - df_pdf_child3 = tabula.read_pdf("Pdf1_Child3.pdf", pages="all") -# DOCUMENT READING -if os.path.isfile("Document_Child3.docx") == True: - document = Document("Document_Child3.docx") - table = document.tables[0] - data = [] + # Correct path to Parent directory (no extra nested folder) + parent_dir = os.path.join(script_dir, "Parent") # Fixed path - keys = None - for i, row in enumerate(table.rows): - text = (cell.text for cell in row.cells) - if i == 0: - keys = tuple(text) - continue - row_data = dict(zip(keys, text)) - data.append(row_data) -df_document_child3 = pd.DataFrame(data) -# TEXT READING -if os.path.isfile("Text_Child3.txt") == True: - df_text_child3 = pd.read_csv("Text_Child3.txt") + if not os.path.isdir(parent_dir): + print(f"Parent directory NOT found at: {parent_dir}") + print("Please check your folder structure! It should be:") + print(f" {script_dir}/Parent/") + print(f" {script_dir}/Parent/Child1/") + print(f" {script_dir}/Parent/Child2/") + print(f" {script_dir}/Parent/Child3/") + else: + print(f"Processing Parent directory: {parent_dir}") -# %% -df_text_child3 + # Process Child1, Child2, Child3 + all_data = {} + for i in range(1, 4): + child_name = f"Child{i}" + child_path = os.path.join(parent_dir, child_name) + all_data[child_name] = process_child_directory(child_path) -# %% + # Example: Show Child1 text data if available + if "Child1" in all_data and "text" in all_data["Child1"]: + print("\n--- Child1 Text Data ---") + print(all_data["Child1"]["text"].head()) diff --git a/ExtractThumbnailFromVideo/extract_thumbnail_from_video.py b/ExtractThumbnailFromVideo/extract_thumbnail_from_video.py index 76ca3b43eb7..ffea98cc913 100644 --- a/ExtractThumbnailFromVideo/extract_thumbnail_from_video.py +++ b/ExtractThumbnailFromVideo/extract_thumbnail_from_video.py @@ -1,13 +1,15 @@ -import cv2 import os -def extract_thumbnail(video_path, frame_size): +import cv2 + + +def extract_thumbnail(video_path: str, frame_size: tuple[int, int]) -> None: """ Extracts a thumbnail frame from a video and saves it as an image file. Args: - video_path (str): The path to the input video file. - frame_size (tuple): A tuple containing the desired dimensions (width, height) for the thumbnail frame. + video_path: The path to the input video file. + frame_size: A tuple containing the desired dimensions (width, height) for the thumbnail frame. Raises: Exception: If the function fails to extract a frame from the video. @@ -18,22 +20,44 @@ def extract_thumbnail(video_path, frame_size): Example: extract_thumbnail('my_video.mp4', (320, 240)) - + Required Packages: - cv2 (pip install cv2) - + OpenCV (pip install opencv-python) + This function is useful for generating thumbnail images from videos. """ - video_capture = cv2.VideoCapture(video_path) # Open the video file for reading - total_frames = int(video_capture.get(cv2.CAP_PROP_FRAME_COUNT)) # Get the total number of frames in the video - middle_frame_index = total_frames // 2 # Calculate the index of the middle frame - video_capture.set(cv2.CAP_PROP_POS_FRAMES, middle_frame_index) # Seek to the middle frame - success, frame = video_capture.read() # Read the middle frame - video_capture.release() # Release the video capture object - - if success: - frame = cv2.resize(frame, frame_size) # Resize the frame to the specified dimensions - thumbnail_filename = f"{os.path.basename(video_path)}_thumbnail.jpg" # Create a filename for the thumbnail - cv2.imwrite(thumbnail_filename, frame) # Save the thumbnail frame as an image - else: - raise Exception("Could not extract frame") # Raise an exception if frame extraction fails + # Open the video file + video_capture = cv2.VideoCapture(video_path) + + try: + # Get the total number of frames + total_frames = int(video_capture.get(cv2.CAP_PROP_FRAME_COUNT)) + + # Calculate the middle frame index + middle_frame_index = total_frames // 2 + + # Seek to the middle frame + video_capture.set(cv2.CAP_PROP_POS_FRAMES, middle_frame_index) + + # Read the frame + success, frame = video_capture.read() + + if not success: + raise Exception("Failed to read frame from video") + + # Resize the frame to the specified dimensions + resized_frame = cv2.resize(frame, frame_size) + + # Generate the thumbnail filename + base_name = os.path.basename(video_path) + file_name, _ = os.path.splitext(base_name) + thumbnail_filename = f"{file_name}_thumbnail.jpg" + + # Save the thumbnail image + cv2.imwrite(thumbnail_filename, resized_frame) + + print(f"Thumbnail saved as: {thumbnail_filename}") + + finally: + # Release the video capture object + video_capture.release() diff --git a/FIND FACTORIAL OF A NUMBER.py b/FIND FACTORIAL OF A NUMBER.py index 37bc7cd8c01..2ad83891877 100644 --- a/FIND FACTORIAL OF A NUMBER.py +++ b/FIND FACTORIAL OF A NUMBER.py @@ -1,13 +1,18 @@ # Python program to find the factorial of a number provided by the user. + def factorial(n): - if n < 0: # factorial of number less than 0 is not possible - return "Oops!Factorial Not Possible" - elif n == 0: # 0! = 1; when n=0 it returns 1 to the function which is calling it previously. - return 1 - else: - return n*factorial(n-1) -#Recursive function. At every iteration "n" is getting reduced by 1 until the "n" is equal to 0. - -n = int(input("Enter a number: ")) # asks the user for input -print(factorial(n)) # function call + if n < 0: # factorial of number less than 0 is not possible + return "Oops!Factorial Not Possible" + elif ( + n == 0 + ): # 0! = 1; when n=0 it returns 1 to the function which is calling it previously. + return 1 + else: + return n * factorial(n - 1) + + +# Recursive function. At every iteration "n" is getting reduced by 1 until the "n" is equal to 0. + +n = int(input("Enter a number: ")) # asks the user for input +print(factorial(n)) # function call diff --git a/Face and eye Recognition/face_recofnation_first.py b/Face and eye Recognition/face_recofnation_first.py index c60faba84db..6fc56d65da2 100644 --- a/Face and eye Recognition/face_recofnation_first.py +++ b/Face and eye Recognition/face_recofnation_first.py @@ -1,52 +1,115 @@ +import os + import cv2 as cv +import numpy as np +from cv2 import CascadeClassifier, VideoCapture -def detect_faces_and_eyes(): +def detect_faces_and_eyes( + camera_index: int = 0, + face_scale_factor: float = 1.1, + face_min_neighbors: int = 7, + eye_scale_factor: float = 1.1, + eye_min_neighbors: int = 7, +) -> None: """ - Detects faces and eyes in real-time using the webcam. + Detects faces and eyes in real-time using the webcam or a specified video source. + + Args: + camera_index: Index of the camera to use (default is 0 for built-in webcam). + face_scale_factor: Parameter specifying how much the image size is reduced at each image scale for face detection. + face_min_neighbors: Parameter specifying how many neighbors each candidate rectangle should have to retain it for face detection. + eye_scale_factor: Parameter specifying how much the image size is reduced at each image scale for eye detection. + eye_min_neighbors: Parameter specifying how many neighbors each candidate rectangle should have to retain it for eye detection. + + Raises: + FileNotFoundError: If the Haar cascade classifier files are not found. + IOError: If the webcam cannot be opened. Press 'q' to exit the program. """ + # Get the directory where OpenCV's data files are located + cv2_data_dir = os.path.join(os.path.dirname(cv.__file__), "data") + + # Construct absolute paths to the Haar cascade files + face_cascade_path = os.path.join( + cv2_data_dir, "haarcascade_frontalface_default.xml" + ) + eye_cascade_path = os.path.join(cv2_data_dir, "haarcascade_eye.xml") + # Load the pre-trained classifiers for face and eye detection - face_cascade = cv.CascadeClassifier(r"..\libs\haarcascade_frontalface_default.xml") - eye_cascade = cv.CascadeClassifier(r"..\libs\haarcascade_eye.xml") + face_cascade: CascadeClassifier = cv.CascadeClassifier(face_cascade_path) + eye_cascade: CascadeClassifier = cv.CascadeClassifier(eye_cascade_path) + + # Validate classifier loading + if face_cascade.empty() or eye_cascade.empty(): + raise FileNotFoundError( + f"Unable to load Haar cascade classifiers from:\n" + f"Face: {face_cascade_path}\n" + f"Eye: {eye_cascade_path}\n\n" + f"Please verify the files exist in your OpenCV installation." + ) # Open the webcam - cap = cv.VideoCapture(0) + cap: VideoCapture = cv.VideoCapture(camera_index) + + if not cap.isOpened(): + raise OSError(f"Cannot open camera with index {camera_index}") + + try: + while True: + # Read a frame from the camera + success: bool + frame: np.ndarray + success, frame = cap.read() - while cap.isOpened(): - # Read a frame from the webcam - flag, img = cap.read() + if not success: + print("Failed to grab frame") + break - # Convert the frame to grayscale for better performance - gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) + # Convert the frame to grayscale for better performance + gray_frame: np.ndarray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY) - # Detect faces in the frame - faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=7) + # Detect faces in the grayscale frame + faces: list[tuple[int, int, int, int]] = face_cascade.detectMultiScale( + gray_frame, + scaleFactor=face_scale_factor, + minNeighbors=face_min_neighbors, + minSize=(30, 30), + flags=cv.CASCADE_SCALE_IMAGE, + ) - # Detect eyes in the frame - eyes = eye_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=7) + # Detect eyes in the grayscale frame + eyes: list[tuple[int, int, int, int]] = eye_cascade.detectMultiScale( + gray_frame, + scaleFactor=eye_scale_factor, + minNeighbors=eye_min_neighbors, + minSize=(10, 10), + flags=cv.CASCADE_SCALE_IMAGE, + ) - # Draw rectangles around faces and eyes - for x, y, w, h in faces: - cv.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 1) + # Draw rectangles around detected faces + for x, y, w, h in faces: + cv.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) - for a, b, c, d in eyes: - cv.rectangle(img, (a, b), (a + c, b + d), (255, 0, 0), 1) + # Draw rectangles around detected eyes + for x, y, w, h in eyes: + cv.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 1) - # Display the resulting frame - cv.imshow("Face and Eye Detection", img) + # Display the resulting frame with detections + cv.imshow("Face and Eye Detection", frame) - # Check for the 'q' key to exit the program - key = cv.waitKey(1) - if key == ord("q"): - break + # Check for the 'q' key to exit the loop + key: int = cv.waitKey(1) + if key == ord("q"): + break - # Release the webcam and close all windows - cap.release() - cv.destroyAllWindows() + finally: + # Release the camera and close all OpenCV windows + cap.release() + cv.destroyAllWindows() if __name__ == "__main__": - # Call the main function - detect_faces_and_eyes() \ No newline at end of file + # Call the main function with default parameters + detect_faces_and_eyes() diff --git a/Face and eye Recognition/gesture_control.py b/Face and eye Recognition/gesture_control.py index 8afd63af13f..4dadd3b531a 100644 --- a/Face and eye Recognition/gesture_control.py +++ b/Face and eye Recognition/gesture_control.py @@ -1,27 +1,60 @@ import cv2 as cv +import numpy as np -# Read the image in grayscale -img = cv.imread(r"..\img\hand1.jpg", cv.IMREAD_GRAYSCALE) -# Apply thresholding to create a binary image -_, thresholded = cv.threshold(img, 70, 255, cv.THRESH_BINARY) +def process_hand_image(image_path: str) -> None: + """ + Processes an image to detect hand contours and convex hulls. -# Find contours in the binary image -contours, _ = cv.findContours(thresholded.copy(), cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE) + Args: + image_path: Path to the input image file. -# Convex Hull for each contour -convex_hulls = [cv.convexHull(contour) for contour in contours] + Raises: + FileNotFoundError: If the specified image file cannot be found. + cv.error: If there is an error during image processing. + """ + # Read the image in grayscale + img: np.ndarray = cv.imread(image_path, cv.IMREAD_GRAYSCALE) -# Draw contours and convex hulls on the original image -original_with_contours = cv.drawContours(img.copy(), contours, -1, (0, 0, 0), 2) -original_with_convex_hulls = cv.drawContours(img.copy(), convex_hulls, -1, (0, 0, 0), 2) + # Validate image loading + if img is None: + raise FileNotFoundError(f"Could not read image from path: {image_path}") -# Display the images -cv.imshow("Original Image", img) -cv.imshow("Thresholded Image", thresholded) -cv.imshow("Contours", original_with_contours) -cv.imshow("Convex Hulls", original_with_convex_hulls) + # Apply thresholding to create a binary image + thresholded: np.ndarray + _, thresholded = cv.threshold(img, 70, 255, cv.THRESH_BINARY) -# Wait for a key press and close windows -cv.waitKey(0) -cv.destroyAllWindows() + # Find contours in the binary image + contours: list[np.ndarray] + hierarchy: np.ndarray + contours, hierarchy = cv.findContours( + thresholded.copy(), cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE + ) + + # Compute convex hull for each contour + convex_hulls: list[np.ndarray] = [cv.convexHull(contour) for contour in contours] + + # Convert grayscale image to BGR for colored drawing + color_img: np.ndarray = cv.cvtColor(img, cv.COLOR_GRAY2BGR) + + # Draw contours and convex hulls on the colored image + contours_image: np.ndarray = color_img.copy() + cv.drawContours(contours_image, contours, -1, (0, 255, 0), 2) + + convex_hulls_image: np.ndarray = color_img.copy() + cv.drawContours(convex_hulls_image, convex_hulls, -1, (0, 0, 255), 2) + + # Display the images + cv.imshow("Original Image", img) + cv.imshow("Thresholded Image", thresholded) + cv.imshow("Contours", contours_image) + cv.imshow("Convex Hulls", convex_hulls_image) + + # Wait for a key press and then close all windows + cv.waitKey(0) + cv.destroyAllWindows() + + +if __name__ == "__main__": + # Example usage + process_hand_image(r"..\img\hand1.jpg") diff --git a/Face_Mask_detection (haarcascade)/mask_detection.py b/Face_Mask_detection (haarcascade)/mask_detection.py index a36382841c2..6f20bc5c00e 100644 --- a/Face_Mask_detection (haarcascade)/mask_detection.py +++ b/Face_Mask_detection (haarcascade)/mask_detection.py @@ -1,6 +1,6 @@ -import tensorflow.keras -import numpy as np import cv2 +import numpy as np +import tensorflow.keras # import os @@ -21,7 +21,7 @@ cv2.imshow("webcam", img) faces = faceCascade.detectMultiScale(img, 1.1, 4) - for (x, y, w, h) in faces: + for x, y, w, h in faces: crop_img = img[y : y + h, x : x + w] crop_img = cv2.resize(crop_img, (224, 224)) normalized_image_array = (crop_img.astype(np.float32) / 127.0) - 1 diff --git a/FibonacciNumbersWithGenerators.py b/FibonacciNumbersWithGenerators.py index 5d090a0a7ea..15771630222 100644 --- a/FibonacciNumbersWithGenerators.py +++ b/FibonacciNumbersWithGenerators.py @@ -1,10 +1,10 @@ -def fibonacci_generator(n = None): +def fibonacci_generator(n=None): """ - Generating function up to n fibonacci numbers iteratively - Params: - n: int - Return: - int + Generating function up to n fibonacci numbers iteratively + Params: + n: int + Return: + int """ f0, f1 = 0, 1 yield f1 @@ -14,5 +14,6 @@ def fibonacci_generator(n = None): f0, f1 = f1, fn n -= 1 + for n_fibo in fibonacci_generator(7): print(n_fibo) diff --git a/Find current weather of any city using openweathermap API.py b/Find current weather of any city using openweathermap API.py index 18ee1555d1b..c5848559880 100644 --- a/Find current weather of any city using openweathermap API.py +++ b/Find current weather of any city using openweathermap API.py @@ -1,72 +1,73 @@ -# Python program to find current -# weather details of any city -# using openweathermap api +# Python program to find current +# weather details of any city +# using openweathermap api -# import required modules +# import required modules import requests -# Enter your API key here +# Enter your API key here api_key = "Your_API_Key" -# base_url variable to store url +# base_url variable to store url base_url = "http://api.openweathermap.org/data/2.5/weather?" -# Give city name -city_name = input("Enter city name : ") - -# complete_url variable to store -# complete url address -complete_url = base_url + "appid=" + api_key + "&q=" + city_name - -# get method of requests module -# return response object -response = requests.get(complete_url) - -# json method of response object -# convert json format data into -# python format data -x = response.json() - -# Now x contains list of nested dictionaries -# Check the value of "cod" key is equal to -# "404", means city is found otherwise, -# city is not found -if x["cod"] != "404": - - # store the value of "main" - # key in variable y - y = x["main"] - - # store the value corresponding - # to the "temp" key of y - current_temperature = y["temp"] - - # store the value corresponding - # to the "pressure" key of y - current_pressure = y["pressure"] - - # store the value corresponding - # to the "humidity" key of y - current_humidiy = y["humidity"] - - # store the value of "weather" - # key in variable z - z = x["weather"] - - # store the value corresponding - # to the "description" key at - # the 0th index of z - weather_description = z[0]["description"] - - # print following values - print(" Temperature (in kelvin unit) = " + - str(current_temperature) + - "\n atmospheric pressure (in hPa unit) = " + - str(current_pressure) + - "\n humidity (in percentage) = " + - str(current_humidiy) + - "\n description = " + - str(weather_description)) - -else: - print(" City Not Found ") +# Give city name +city_name = input("Enter city name : ") + +# complete_url variable to store +# complete url address +complete_url = base_url + "appid=" + api_key + "&q=" + city_name + +# get method of requests module +# return response object +response = requests.get(complete_url) + +# json method of response object +# convert json format data into +# python format data +x = response.json() + +# Now x contains list of nested dictionaries +# Check the value of "cod" key is equal to +# "404", means city is found otherwise, +# city is not found +if x["cod"] != "404": + # store the value of "main" + # key in variable y + y = x["main"] + + # store the value corresponding + # to the "temp" key of y + current_temperature = y["temp"] + + # store the value corresponding + # to the "pressure" key of y + current_pressure = y["pressure"] + + # store the value corresponding + # to the "humidity" key of y + current_humidiy = y["humidity"] + + # store the value of "weather" + # key in variable z + z = x["weather"] + + # store the value corresponding + # to the "description" key at + # the 0th index of z + weather_description = z[0]["description"] + + # print following values + print( + " Temperature (in kelvin unit) = " + + str(current_temperature) + + "\n atmospheric pressure (in hPa unit) = " + + str(current_pressure) + + "\n humidity (in percentage) = " + + str(current_humidiy) + + "\n description = " + + str(weather_description) + ) + +else: + print(" City Not Found ") diff --git a/FindingResolutionOfAnImage.py b/FindingResolutionOfAnImage.py index 9c6336d8d1d..6bc312b245d 100644 --- a/FindingResolutionOfAnImage.py +++ b/FindingResolutionOfAnImage.py @@ -1,24 +1,24 @@ def jpeg_res(filename): - """"This function prints the resolution of the jpeg image file passed into it""" + """ "This function prints the resolution of the jpeg image file passed into it""" - # open image for reading in binary mode - with open(filename,'rb') as img_file: + # open image for reading in binary mode + with open(filename, "rb") as img_file: + # height of image (in 2 bytes) is at 164th position + img_file.seek(163) - # height of image (in 2 bytes) is at 164th position - img_file.seek(163) + # read the 2 bytes + a = img_file.read(2) - # read the 2 bytes - a = img_file.read(2) + # calculate height + height = (a[0] << 8) + a[1] - # calculate height - height = (a[0] << 8) + a[1] + # next 2 bytes is width + a = img_file.read(2) - # next 2 bytes is width - a = img_file.read(2) + # calculate width + width = (a[0] << 8) + a[1] - # calculate width - width = (a[0] << 8) + a[1] + print("The resolution of the image is", width, "x", height) - print("The resolution of the image is",width,"x",height) jpeg_res("img1.jpg") diff --git a/FizzBuzz.py b/FizzBuzz.py index 59c78fad2a9..cf8caba4c4e 100644 --- a/FizzBuzz.py +++ b/FizzBuzz.py @@ -18,5 +18,4 @@ def FizzBuzz(num): print(i) - FizzBuzz(20) # prints FizzBuzz up to 20 diff --git a/Flappy Bird - created with tkinter/Background.py b/Flappy Bird - created with tkinter/Background.py index 78dc415a9f4..379fd8ec639 100644 --- a/Flappy Bird - created with tkinter/Background.py +++ b/Flappy Bird - created with tkinter/Background.py @@ -1,4 +1,4 @@ -from tkinter import Tk, Canvas +from tkinter import Canvas, Tk from PIL.Image import open as openImage from PIL.ImageTk import PhotoImage @@ -13,7 +13,6 @@ class Background(Canvas): __stop = False def __init__(self, tk_instance, *geometry, fp="background.png", animation_speed=50): - # Verifica se o parâmetro tk_instance é uma instância de Tk if not isinstance(tk_instance, Tk): raise TypeError("The tk_instance argument must be an instance of Tk.") @@ -151,7 +150,6 @@ def run(self): # Enquanto o atributo "stop" for False, a animação continuará em um loop infinito if not self.__stop: - # Move as imagens de background na posição X self.move(self.__background[0], -10, 0) self.move(self.__background[1], -10, 0) diff --git a/Flappy Bird - created with tkinter/Bird.py b/Flappy Bird - created with tkinter/Bird.py index 56fdcd1d31c..d401a893109 100644 --- a/Flappy Bird - created with tkinter/Bird.py +++ b/Flappy Bird - created with tkinter/Bird.py @@ -1,255 +1,285 @@ +from collections.abc import Callable from threading import Thread -from Background import Background +from PIL.Image import Image from PIL.Image import open as openImage from PIL.ImageTk import PhotoImage +class Background: + """Mock Background class for type checking""" + + def __init__(self): + self.bird_image = None + + def create_image(self, x: int, y: int, image: PhotoImage, tag: str) -> int: + return 0 + + def bbox(self, tag: str) -> tuple[int, int, int, int]: + return (0, 0, 0, 0) + + def find_overlapping(self, x1: int, y1: int, x2: int, y2: int) -> list[int]: + return [] + + def move(self, tag: str, x: int, y: int) -> None: + pass + + def after(self, delay: int, callback: Callable) -> None: + pass + + def bind(self, event: str, callback: Callable) -> None: + pass + + def focus_force(self) -> None: + pass + + def getBackgroundID(self) -> list[int]: + return [] + + class Bird(Thread): """ - Classe para criar um pássaro + Class for creating a bird object that can fly in a game environment. """ - __tag = "Bird" - __isAlive = None - __going_up = False - __going_down = 0 - __times_skipped = 0 - __running = False + __tag: str = "Bird" + __isAlive: bool = None + __going_up: bool = False + __going_down: float = 0 + __times_skipped: int = 0 + __running: bool = False - decends = 0.00390625 - climbsUp = 0.0911458333 + decends: float = 0.00390625 + climbsUp: float = 0.0911458333 def __init__( self, - background, - gameover_function, - *screen_geometry, - fp="bird.png", - event="", - descend_speed=5 - ): - - # Verifica se "background" é uma instância de Background e se o "gamerover_method" é chamável - + background: Background, + gameover_function: Callable[[], None], + *screen_geometry: int, + fp: str = "bird.png", + event: str = "", + descend_speed: int = 5, + ) -> None: + """ + Initialize the bird object. + + Args: + background: The game background canvas. + gameover_function: Function to call when the bird dies. + screen_geometry: Width and height of the game screen. + fp: Path to the bird image file. + event: Keyboard event to trigger the bird's jump. + descend_speed: Speed at which the bird descends. + """ + # Validate input types if not isinstance(background, Background): raise TypeError( "The background argument must be an instance of Background." ) if not callable(gameover_function): - raise TypeError("The gameover_method argument must be a callable object.") + raise TypeError("The gameover_function argument must be a callable object.") - # Instância os parâmetros - self.__canvas = background - self.image_path = fp - self.__descend_speed = descend_speed - self.gameover_method = gameover_function + # Instance parameters + self.__canvas: Background = background + self.image_path: str = fp + self.__descend_speed: int = descend_speed + self.gameover_method: Callable[[], None] = gameover_function - # Recebe a largura e altura do background - self.__width = screen_geometry[0] - self.__height = screen_geometry[1] + # Get screen dimensions + if len(screen_geometry) != 2: + raise ValueError("screen_geometry must contain width and height") + self.__width: int = screen_geometry[0] + self.__height: int = screen_geometry[1] - # Define a decida e subida do pássaro com base na altura do background + # Adjust bird movement speeds based on screen height self.decends *= self.__height self.decends = int(self.decends + 0.5) self.climbsUp *= self.__height self.climbsUp = int(self.climbsUp + 0.5) - # Invoca o método construtor de Thread - Thread.__init__(self) + # Initialize Thread + super().__init__() - # Calcula o tamanho do pássaro com base na largura e altura da janela - self.width = (self.__width // 100) * 6 - self.height = (self.__height // 100) * 11 + # Calculate bird dimensions + self.width: int = (self.__width // 100) * 6 + self.height: int = (self.__height // 100) * 11 - # Carrega e cria a imagem do pássaro no background - self.__canvas.bird_image = self.getPhotoImage( + # Load and create bird image + self.__canvas.bird_image, _, _ = self.getPhotoImage( image_path=self.image_path, width=self.width, height=self.height, closeAfter=True, - )[0] - self.__birdID = self.__canvas.create_image( + ) + self.__birdID: int = self.__canvas.create_image( self.__width // 2, self.__height // 2, image=self.__canvas.bird_image, tag=self.__tag, ) - # Define evento para fazer o pássaro subir + # Bind jump event self.__canvas.focus_force() self.__canvas.bind(event, self.jumps) self.__isAlive = True - def birdIsAlive(self): - """ - Método para verificar se o pássaro está vivo - """ - + def birdIsAlive(self) -> bool: + """Check if the bird is alive.""" return self.__isAlive - def checkCollision(self): - """ - Método para verificar se o pássaro ultrapassou a borda da janela ou colidiu com algo + def checkCollision(self) -> bool: """ + Check if the bird has collided with the boundaries or other objects. - # Recebe a posição do pássaro no background - position = list(self.__canvas.bbox(self.__tag)) + Returns: + True if a collision occurred, False otherwise. + """ + # Get bird position + position: list[int] = list(self.__canvas.bbox(self.__tag)) - # Se o pássaro tiver ultrapassado a borda de baixo do background, ele será declarado morto + # Check boundary collisions if position[3] >= self.__height + 20: self.__isAlive = False - # Se o pássaro tiver ultrapassado a borda de cima do background, ele será declarado morto if position[1] <= -20: self.__isAlive = False - # Dá uma margem de erro ao pássaro de X pixels + # Adjust collision boundaries with a margin of error position[0] += int(25 / 78 * self.width) position[1] += int(25 / 77 * self.height) position[2] -= int(20 / 78 * self.width) position[3] -= int(10 / 77 * self.width) - # Define os objetos a serem ignorados em colisões - ignored_collisions = self.__canvas.getBackgroundID() + # Define objects to ignore in collisions + ignored_collisions: list[int] = self.__canvas.getBackgroundID() ignored_collisions.append(self.__birdID) - # Verifica possíveis colisões com o pássaro - possible_collisions = list(self.__canvas.find_overlapping(*position)) + # Check for overlapping objects + possible_collisions: list[int] = list(self.__canvas.find_overlapping(*position)) - # Remove das possíveis colisões os objetos ignorados - for _id in ignored_collisions: + # Remove ignored objects from collision list + for obj_id in ignored_collisions: try: - possible_collisions.remove(_id) - except BaseException: + possible_collisions.remove(obj_id) + except ValueError: continue - # Se houver alguma colisão o pássaro morre + # Collision detected if len(possible_collisions) >= 1: self.__isAlive = False return not self.__isAlive - def getTag(self): - """ - Método para retornar a tag do pássaro - """ - + def getTag(self) -> str: + """Return the bird's tag.""" return self.__tag @staticmethod def getPhotoImage( - image=None, image_path=None, width=None, height=None, closeAfter=False - ): - """ - Retorna um objeto da classe PIL.ImageTk.PhotoImage de uma imagem e as imagens criadas de PIL.Image - (photoImage, new, original) - - @param image: Instância de PIL.Image.open - @param image_path: Diretório da imagem - @param width: Largura da imagem - @param height: Altura da imagem - @param closeAfter: Se True, a imagem será fechada após ser criado um PhotoImage da mesma + image: Image | None = None, + image_path: str | None = None, + width: int | None = None, + height: int | None = None, + closeAfter: bool = False, + ) -> tuple[PhotoImage, Image | None, Image | None]: """ + Create a PhotoImage from a PIL Image or image path. + + Args: + image: PIL Image object. + image_path: Path to an image file. + width: Desired width of the image. + height: Desired height of the image. + closeAfter: Whether to close the image after creating the PhotoImage. - if not image: - if not image_path: - return + Returns: + A tuple containing the PhotoImage, the resized image, and the original image. + """ + if image is None: + if image_path is None: + raise ValueError("Either image or image_path must be provided") - # Abre a imagem utilizando o caminho dela + # Open image from path image = openImage(image_path) - # Será redimesionada a imagem somente se existir um width ou height - if not width: + # Resize image if dimensions are provided + if width is None: width = image.width - if not height: + if height is None: height = image.height - # Cria uma nova imagem já redimensionada - newImage = image.resize([width, height]) + # Create resized image + newImage: Image = image.resize([width, height]) - # Cria um photoImage - photoImage = PhotoImage(newImage) + # Create PhotoImage + photoImage: PhotoImage = PhotoImage(newImage) - # Se closeAfter for True, ele fecha as imagens + # Close images if requested if closeAfter: - # Fecha a imagem nova newImage.close() newImage = None - - # Fecha a imagem original image.close() image = None - # Retorna o PhotoImage da imagem,a nova imagem que foi utilizada e a imagem original return photoImage, newImage, image - def jumps(self, event=None): - """ - Método para fazer o pássaro pular + def jumps(self, event: object | None = None) -> None: """ + Make the bird jump. - # Verifica se o pássaro saiu da área do background + Args: + event: Keyboard event (automatically passed by Tkinter). + """ + # Check collision status self.checkCollision() - # Se o pássaro estiver morto, esse método não pode ser executado + # Prevent jumping if bird is dead or not running if not self.__isAlive or not self.__running: self.__going_up = False return - # Declara que o pássaro está subindo + # Bird is going up self.__going_up = True self.__going_down = 0 - # Move o pássaro enquanto o limite de subida por animação não tiver excedido + # Animate the jump if self.__times_skipped < self.climbsUp: - - # Move o pássaro para cima + # Move bird upwards self.__canvas.move(self.__tag, 0, -1) self.__times_skipped += 1 - # Executa o método novamente + # Continue jump animation self.__canvas.after(3, self.jumps) - else: - - # Declara que o pássaro não está mais subindo + # Jump animation complete self.__going_up = False self.__times_skipped = 0 - def kill(self): - """ - Método para matar o pássaro - """ - + def kill(self) -> None: + """Kill the bird (set isAlive to False).""" self.__isAlive = False - def run(self): - """ - #Método para iniciar a animação do passáro caindo - """ - + def run(self) -> None: + """Main animation loop for the bird's falling motion.""" self.__running = True - # Verifica se o pássaro saiu da área do background + # Check collision status self.checkCollision() - # Enquanto o pássaro não tiver chegado em sua velocidade máxima, a velocidade aumentará em 0.05 + # Increase falling speed up to maximum if self.__going_down < self.decends: self.__going_down += 0.05 - # Executa a animação de descida somente se o pássaro estiver vivo + # Continue animation if bird is alive if self.__isAlive: - - # Executa a animação de descida somente se o pássaro não estiver subindo + # Only move down if not jumping if not self.__going_up: - # Move o pássaro para baixo self.__canvas.move(self.__tag, 0, self.__going_down) - # Executa novamente o método + # Schedule next frame self.__canvas.after(self.__descend_speed, self.run) - - # Se o pássaro estiver morto, será executado um método de fim de jogo else: + # Bird is dead, trigger game over self.__running = False self.gameover_method() diff --git a/Flappy Bird - created with tkinter/Flappy Bird.py b/Flappy Bird - created with tkinter/Flappy Bird.py index 7dfe9564dfb..57006b68921 100644 --- a/Flappy Bird - created with tkinter/Flappy Bird.py +++ b/Flappy Bird - created with tkinter/Flappy Bird.py @@ -1,6 +1,8 @@ -import pygame +import os import random +import pygame + # Initialize Pygame pygame.init() @@ -10,12 +12,39 @@ screen = pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption("Flappy Bird") +# Get the directory where the script is located +script_dir = os.path.dirname(os.path.abspath(__file__)) +# Use the Images folder under the script directory +images_dir = os.path.join(script_dir, "Images") + +# Debugging: Print paths +print(f"Script directory: {script_dir}") +print(f"Images directory: {images_dir}") + +# Check if image files exist +required_images = ["bird.png", "pipe.png", "background.png"] +missing_files = [] + +for img in required_images: + img_path = os.path.join(images_dir, img) + if not os.path.exists(img_path): + missing_files.append(img) + print(f"Error: Missing {img} at {img_path}") + +if missing_files: + print(f"Please place the missing files in {images_dir}") + pygame.quit() + exit(1) + # Load images -bird_image = pygame.image.load("bird.png").convert_alpha() -pipe_image = pygame.image.load("pipe.png").convert_alpha() -background_image = pygame.image.load("background.png").convert_alpha() +bird_image = pygame.image.load(os.path.join(images_dir, "bird.png")).convert_alpha() +pipe_image = pygame.image.load(os.path.join(images_dir, "pipe.png")).convert_alpha() +background_image = pygame.image.load( + os.path.join(images_dir, "background.png") +).convert_alpha() + -# Bird class +# Bird class (unchanged) class Bird: def __init__(self): self.image = bird_image @@ -34,7 +63,8 @@ def flap(self): def draw(self, screen): screen.blit(self.image, (self.x, self.y)) -# Pipe class + +# Pipe class (unchanged) class Pipe: def __init__(self): self.image = pipe_image @@ -47,7 +77,11 @@ def update(self): def draw(self, screen): screen.blit(self.image, (self.x, self.y)) - screen.blit(pygame.transform.flip(self.image, False, True), (self.x, self.y - screen_height)) + screen.blit( + pygame.transform.flip(self.image, False, True), + (self.x, self.y - screen_height), + ) + def main(): clock = pygame.time.Clock() @@ -81,5 +115,6 @@ def main(): pygame.quit() + if __name__ == "__main__": main() diff --git a/Flappy Bird - created with tkinter/Images/pipe.png b/Flappy Bird - created with tkinter/Images/pipe.png new file mode 100644 index 00000000000..a49457d3e51 Binary files /dev/null and b/Flappy Bird - created with tkinter/Images/pipe.png differ diff --git a/Flappy Bird - created with tkinter/Settings.py b/Flappy Bird - created with tkinter/Settings.py index 33eb2c1da6f..362d050e048 100644 --- a/Flappy Bird - created with tkinter/Settings.py +++ b/Flappy Bird - created with tkinter/Settings.py @@ -1,9 +1,8 @@ import os -from json import dumps -from json import loads +from json import dumps, loads -class Settings(object): +class Settings: """ Classe com todas as configurações do jogo """ @@ -81,7 +80,7 @@ def setOptions(self): # Tenta abrir o arquivo parar leitura try: - file = open(self.settings_fp, "r") + file = open(self.settings_fp) data = loads(file.read()) file.close() @@ -94,7 +93,6 @@ def setOptions(self): # Caso não exista um arquivo para obter as configurações, ele será criado except BaseException: - # Caso não exista o diretório, o mesmo será criado. if not os.path.exists(os.path.split(self.settings_fp)[0]): os.mkdir(os.path.split(self.settings_fp)[0]) diff --git a/Flappy Bird - created with tkinter/Tubes.py b/Flappy Bird - created with tkinter/Tubes.py index 3948a49e502..fa69fd0326f 100644 --- a/Flappy Bird - created with tkinter/Tubes.py +++ b/Flappy Bird - created with tkinter/Tubes.py @@ -23,9 +23,8 @@ def __init__( score_function=None, *screen_geometry, fp=("tube.png", "tube_mourth"), - animation_speed=50 + animation_speed=50, ): - # Verifica os parâmetros passados e lança um erro caso algo esteja incorreto if not isinstance(background, Background): raise TypeError( @@ -257,10 +256,8 @@ def move(self): # Move os tubos gerados no background for tubes in self.__tubes: for tube in tubes: - # Verifica se o pássaro passou do tubo. Caso sim, o método para pontuar será executado if not scored: - # Recebe a posição do cano x2 = self.__background.bbox(tube[0])[2] @@ -269,7 +266,6 @@ def move(self): if (self.__width / 2) - (self.__bird_w / 2) - self.__move < x2: if x2 <= (self.__width / 2) - (self.__bird_w / 2): - # Verifica se o tubo está na lista de tubos passados if tube[0] not in self.__pastTubes: # Chama o método para pontuar e adiciona o tubo pontuado à lista de tubos passados @@ -297,7 +293,6 @@ def run(self): len(self.__tubes) >= 1 and self.__background.bbox(self.__tubes[0][0][0])[2] <= 0 ): - # Apaga todo o corpo do tubo dentro do background for tube in self.__tubes[0]: for body in tube: diff --git a/Generate a random number between 0 to 9.py b/Generate a random number between 0 to 9.py index a035d9f8502..c304fa85b1d 100644 --- a/Generate a random number between 0 to 9.py +++ b/Generate a random number between 0 to 9.py @@ -3,4 +3,4 @@ # importing the random module import random -print(random.randint(0,9)) +print(random.randint(0, 9)) diff --git a/Google_Image_Downloader/create_dir.py b/Google_Image_Downloader/create_dir.py index 0734f836802..33b32f4710c 100644 --- a/Google_Image_Downloader/create_dir.py +++ b/Google_Image_Downloader/create_dir.py @@ -1,66 +1,91 @@ """ -Code to directly use in file to -create directory in home location +Code to manage directories in the project's parent directory. -Note:- I Have used python package so if you want -to create in the main directory of your project use -pardir+"\\"+name in functions - -All the folder operations are done on home -project directory. +Note: Uses pathlib for platform-agnostic path handling. +All operations default to the project's parent directory. """ -from os import chdir -from os import makedirs -from os import removedirs -from os import rename -from os.path import exists -from os.path import pardir -from shutil import copytree -from shutil import move - - -# Creates a directory -def create_directory(name): - if exists(pardir + "\\" + name): - print("Folder already exists... Cannot Overwrite this") - else: - makedirs(pardir + "\\" + name) - - -# Deletes a directory -def delete_directory(name): - removedirs(name) - - -# Rename a directory -def rename_directory(direct, name): - rename(direct, name) +from pathlib import Path +from shutil import copytree, move +# Get the project's parent directory +PROJECT_ROOT = Path(__file__).parent.parent -# Sets the working directory -def set_working_directory(): - chdir(pardir) - -# Backup the folder tree -def backup_files(name_dir, folder): - copytree(pardir, name_dir + ":\\" + folder) - - -# Move folder to specific location -# Overwrites the file if it already exists -def move_folder(filename, name_dir, folder): - if not exists(name_dir + ":\\" + folder): - makedirs(name_dir + ":\\" + folder) - move(filename, name_dir + ":\\" + folder + "\\") - - -""" -For test purpose: - 1. create_directory("test") - 2. rename_directory("test","demo") - 3. delete_directory("demo") - 4. backup_files('D', 'backup_project') - 5. move_folder(pardir+'\\'+'test.txt', 'D', 'name') -""" +def create_directory(name: str) -> None: + """Create a directory in the project's parent directory.""" + target_dir = PROJECT_ROOT / name + if target_dir.exists(): + print(f"Error: Folder '{name}' already exists.") + else: + target_dir.mkdir(exist_ok=False) + print(f"Created directory: {target_dir}") + + +def delete_directory(name: str) -> None: + """Delete a directory and its contents recursively.""" + target_dir = PROJECT_ROOT / name + if not target_dir.exists(): + print(f"Error: Directory '{name}' does not exist.") + return + # Safely delete non-empty directory + for item in target_dir.rglob("*"): + if item.is_file(): + item.unlink() + else: + item.rmdir() + target_dir.rmdir() + print(f"Deleted directory: {target_dir}") + + +def rename_directory(old_name: str, new_name: str) -> None: + """Rename a directory in the project's parent directory.""" + old_path = PROJECT_ROOT / old_name + new_path = PROJECT_ROOT / new_name + + if not old_path.exists(): + print(f"Error: Directory '{old_name}' does not exist.") + return + if new_path.exists(): + print(f"Error: Directory '{new_name}' already exists.") + return + + old_path.rename(new_path) + print(f"Renamed '{old_name}' to '{new_name}'") + + +def backup_files(drive_letter: str, backup_folder: str) -> None: + """Backup the project directory to another drive.""" + source = PROJECT_ROOT + destination = Path(f"{drive_letter}:/{backup_folder}") + + if destination.exists(): + print(f"Error: Backup directory '{destination}' already exists.") + return + + copytree(source, destination) + print(f"Backed up project to: {destination}") + + +def move_folder(file_or_folder: str, drive_letter: str, target_folder: str) -> None: + """Move a file/folder to a specific location, overwriting if it exists.""" + source = PROJECT_ROOT / file_or_folder + destination = Path(f"{drive_letter}:/{target_folder}") + + if not source.exists(): + print(f"Error: Source '{source}' does not exist.") + return + + destination.mkdir(parents=True, exist_ok=True) + move(str(source), str(destination / source.name)) + print(f"Moved '{source}' to '{destination}'") + + +# Example usage +if __name__ == "__main__": + # create_directory("test") + # rename_directory("test", "demo") + # delete_directory("demo") + # backup_files('D', 'backup_project') + # move_folder('test.txt', 'D', 'name') + pass diff --git a/Google_Image_Downloader/image_grapper.py b/Google_Image_Downloader/image_grapper.py index a922894a8d0..925fbc3ab8d 100644 --- a/Google_Image_Downloader/image_grapper.py +++ b/Google_Image_Downloader/image_grapper.py @@ -1,20 +1,16 @@ #!/usr/bin/python -# -*- coding: utf-8 -*- # importing required libraries import json -from os import chdir, system -from os import walk -from os.path import curdir -from os.path import pardir +import ssl +from os import chdir, system, walk +from os.path import curdir, pardir from urllib.parse import urlencode -from urllib.request import urlopen, Request +from urllib.request import Request, urlopen -import requests -import ssl +import httpx from bs4 import BeautifulSoup from create_dir import create_directory - ssl._create_default_https_context = ssl._create_unverified_context GOOGLE_IMAGE = ( @@ -62,7 +58,7 @@ def search_for_image(): images.append(link) counter = 0 for re in images: - rs = requests.get(re) + rs = httpx.get(re) with open("img" + str(counter) + ".jpg", "wb") as file: file.write(rs.content) @@ -100,7 +96,7 @@ def download_wallpapers_1080p(): # Goes to Each link and downloads high resolution images for re in temp: - rs = requests.get(re) + rs = httpx.get(re) with open("img" + str(count) + ".jpg", "wb") as file: file.write(rs.content) @@ -113,7 +109,7 @@ def download_wallpapers_1080p(): ################### def view_images_directory(): - for (folders, subfolder, files) in walk(curdir): + for folders, subfolder, files in walk(curdir): for folder in subfolder: print(folder) return True diff --git a/Grocery calculator.py b/Grocery calculator.py index eedb5c7ea15..42adbb7cd74 100644 --- a/Grocery calculator.py +++ b/Grocery calculator.py @@ -1,45 +1,45 @@ -'''This will be a Python script that functions as a grocery calculator. It will take in key-value pairs for items +"""This will be a Python script that functions as a grocery calculator. It will take in key-value pairs for items and their prices, and return the subtotal and total, and can print out the list for you for when you're ready to -take it to the store!''' +take it to the store!""" -'''Algorithm: +"""Algorithm: 1. User enters key-value pairs that are added into a dict. -2. Users tells script to return total, subtotal, and key-value pairs in a nicely formatted list.''' +2. Users tells script to return total, subtotal, and key-value pairs in a nicely formatted list.""" -#Object = GroceryList -#Methods = addToList, Total, Subtotal, returnList + +# Object = GroceryList +# Methods = addToList, Total, Subtotal, returnList class GroceryList(dict): + def __init__(self): + self = {} - def __init__(self): - self = {} + def addToList(self, item, price): + self.update({item: price}) - def addToList(self, item, price): - - self.update({item:price}) + def Total(self): + total = 0 + for items in self: + total += (self[items]) * 0.07 + (self[items]) + return total - def Total(self): - total = 0 - for items in self: - total += (self[items])*.07 + (self[items]) - return total + def Subtotal(self): + subtotal = 0 + for items in self: + subtotal += self[items] + return subtotal - def Subtotal(self): - subtotal = 0 - for items in self: - subtotal += self[items] - return subtotal + def returnList(self): + return self - def returnList(self): - return self -'''Test list should return: +"""Test list should return: Total = 10.70 Subtotal = 10 returnList = {"milk":4, "eggs":3, "kombucha":3} -''' +""" List1 = GroceryList() -List1.addToList("milk",4) +List1.addToList("milk", 4) List1.addToList("eggs", 3) List1.addToList("kombucha", 3) @@ -48,16 +48,16 @@ def returnList(self): print(List1.Subtotal()) print(List1.returnList()) -#***************************************************** +# ***************************************************** print() -#***************************************************** +# ***************************************************** List2 = GroceryList() -List2.addToList('cheese', 7.49) -List2.addToList('wine', 25.36) -List2.addToList('steak', 17.64) +List2.addToList("cheese", 7.49) +List2.addToList("wine", 25.36) +List2.addToList("steak", 17.64) print(List2.Total()) print(List2.Subtotal()) diff --git a/GroupSms_Way2.py b/GroupSms_Way2.py index 04f9f562249..a8cc854fba1 100644 --- a/GroupSms_Way2.py +++ b/GroupSms_Way2.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import sys from getpass import getpass @@ -21,7 +19,7 @@ # Logging into the SMS Site url = "http://site24.way2sms.com/Login1.action?" -data = "username={0}&password={1}&Submit=Sign+in".format(username, passwd) +data = f"username={username}&password={passwd}&Submit=Sign+in" # For Cookies: cj = cookielib.CookieJar() @@ -38,7 +36,7 @@ try: usock = opener.open(url, data) -except IOError: +except OSError: print("Error while logging in.") sys.exit(1) @@ -51,13 +49,9 @@ try: for number in num: - send_sms_data = ( - "ssaction=ss&Token={0}&mobile={1}&message={2}&msgLen=136".format( - jession_id, number, message - ) - ) + send_sms_data = f"ssaction=ss&Token={jession_id}&mobile={number}&message={message}&msgLen=136" sms_sent_page = opener.open(send_sms_url, send_sms_data) -except IOError: +except OSError: print("Error while sending message") print("SMS has been sent.") diff --git a/HTML_to_PDF/main.py b/HTML_to_PDF/main.py index 1c7cd4e4408..2932834f630 100644 --- a/HTML_to_PDF/main.py +++ b/HTML_to_PDF/main.py @@ -1,28 +1,29 @@ -import pdfkit import os +import pdfkit + # Download wkhtmltopdf from https://wkhtmltopdf.org/downloads.html # Set the path to the wkhtmltopdf executable -wkhtmltopdf_path = r'C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe' +wkhtmltopdf_path = r"C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe" # Configure pdfkit to use wkhtmltopdf config = pdfkit.configuration(wkhtmltopdf=wkhtmltopdf_path) # Path of HTML and PDF files -path=os.getcwd() -htmlFile = f'{path}\\index.html' -pdfFile = f'{path}\\output.pdf' +path = os.getcwd() +htmlFile = f"{path}\\index.html" +pdfFile = f"{path}\\output.pdf" # Adding PDF Options for customized view options = { - 'page-size': 'A4', - 'margin-top': '0.75in', - 'margin-right': '0.75in', - 'margin-bottom': '0.75in', - 'margin-left': '0.75in', - 'encoding': 'UTF-8', - 'no-outline': None + "page-size": "A4", + "margin-top": "0.75in", + "margin-right": "0.75in", + "margin-bottom": "0.75in", + "margin-left": "0.75in", + "encoding": "UTF-8", + "no-outline": None, } # Check if the HTML file exists before proceeding @@ -31,9 +32,7 @@ else: try: # Convert HTML to PDF - pdfkit.from_file(htmlFile, pdfFile, configuration=config,options=options) + pdfkit.from_file(htmlFile, pdfFile, configuration=config, options=options) print(f"Successfully converted HTML to PDF: {pdfFile}") except Exception as e: print(f"An error occurred: {e}") - - diff --git a/Hand-Motion-Detection/hand_motion_recognizer.py b/Hand-Motion-Detection/hand_motion_recognizer.py index 59efb53c8ef..501bdcee3d1 100644 --- a/Hand-Motion-Detection/hand_motion_recognizer.py +++ b/Hand-Motion-Detection/hand_motion_recognizer.py @@ -1,48 +1,54 @@ -import mediapipe as mp import cv2 +import mediapipe as mp mp_drawing = mp.solutions.drawing_utils mp_hands = mp.solutions.hands cap = cv2.VideoCapture(0) -with mp_hands.Hands(min_detection_confidence=0.8, min_tracking_confidence=0.5) as hands: +with mp_hands.Hands(min_detection_confidence=0.8, min_tracking_confidence=0.5) as hands: while cap.isOpened(): ret, frame = cap.read() - + # BGR 2 RGB image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) - + # Flip on horizontal image = cv2.flip(image, 1) - + # Set flag image.flags.writeable = False - + # Detections results = hands.process(image) - + # Set flag to true image.flags.writeable = True - + # RGB 2 BGR image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) - + # Detections print(results) - + # Rendering results if results.multi_hand_landmarks: for num, hand in enumerate(results.multi_hand_landmarks): - mp_drawing.draw_landmarks(image, hand, mp_hands.HAND_CONNECTIONS, - mp_drawing.DrawingSpec(color=(121, 22, 76), thickness=2, circle_radius=4), - mp_drawing.DrawingSpec(color=(250, 44, 250), thickness=2, circle_radius=2), - ) - - - cv2.imshow('Hand Tracking', image) - - if cv2.waitKey(10) & 0xFF == ord('q'): + mp_drawing.draw_landmarks( + image, + hand, + mp_hands.HAND_CONNECTIONS, + mp_drawing.DrawingSpec( + color=(121, 22, 76), thickness=2, circle_radius=4 + ), + mp_drawing.DrawingSpec( + color=(250, 44, 250), thickness=2, circle_radius=2 + ), + ) + + cv2.imshow("Hand Tracking", image) + + if cv2.waitKey(10) & 0xFF == ord("q"): break cap.release() diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt deleted file mode 100644 index 123ef71ed1e..00000000000 --- a/Hand-Motion-Detection/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -numpy==2.2.3 -opencv_python==4.12.0.88 -mediapipe==0.10.21 diff --git a/HangMan Game.py b/HangMan Game.py index 56d106f8c88..fd15f8b7b84 100644 --- a/HangMan Game.py +++ b/HangMan Game.py @@ -1,70 +1,92 @@ # Program for HangMan Game. -import random, HangMan_Includes as incl +import random + +import HangMan_Includes as incl while True: - chances=6 - inp_lst=[] - result_lst=[] - name=random.choice(incl.names).upper() - # print(name) - [result_lst.append('__ ') for i in range(len(name))] - result_str=str().join(result_lst) + chances = 6 + inp_lst = [] + result_lst = [] + name = random.choice(incl.names).upper() + # print(name) + [result_lst.append("__ ") for i in range(len(name))] + result_str = "".join(result_lst) + + print(f"\nYou have to Guess a Human Name of {len(name)} Alphabets:\t{result_str}") + print(incl.draw[0]) + + while True: + if result_str.replace(" ", "") == name: + print( + f"\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Correct Answer: {name} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + ) + print(incl.won + "\a") + break + inp = input("\nGuess an Alphabet or a Sequence of Alphabets: ").upper() + + if inp in inp_lst: + print( + "......................................................................Already Tried" + ) + continue + else: + inp_lst.append(inp) + + t = 0 + indx = [] + if inp in name: + temp = name + while temp != "": + if inp in temp: + indx.append(t + temp.index(inp)) + t = temp.index(inp) + 1 + temp = temp[t:] + else: + break + + for j in range(len(indx)): + for i in range(len(inp)): + result_lst[indx[j]] = inp[i] + " " + indx[j] += 1 + i += 1 + + result_str = "".join(result_lst) + print( + "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Excellent~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + ) + print( + f"\nYou have to Guess a Human Name of {len(name)} Alphabets:\t{result_str}\n" + ) + print("Tried Inputs:", tuple(sorted(set(inp_lst)))) - print(f'\nYou have to Guess a Human Name of {len(name)} Alphabets:\t{result_str}') - print(incl.draw[0]) + else: + print( + "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Try Again!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + ) + print( + f"\nYou have to Guess a Human Name of {len(name)} Alphabets:\t{result_str}\n" + ) + print(incl.draw[chances]) + chances = chances - 1 - while True: - if result_str.replace(' ','')==name: - print(f'\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Correct Answer: {name} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~') - print(incl.won+'\a') - break - inp=input('\nGuess an Alphabet or a Sequence of Alphabets: ').upper() - - if inp in inp_lst: - print('......................................................................Already Tried') - continue - else: - inp_lst.append(inp) - - t=0 - indx=[] - if inp in name: - temp=name - while temp!='': - if inp in temp: - indx.append(t+temp.index(inp)) - t=temp.index(inp)+1 - temp=temp[t:] - else: - break - - for j in range(len(indx)): - for i in range(len(inp)): - result_lst[indx[j]]=inp[i]+' ' - indx[j]+=1 - i+=1 - - result_str=str().join(result_lst) - print('\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Excellent~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~') - print(f'\nYou have to Guess a Human Name of {len(name)} Alphabets:\t{result_str}\n') - print('Tried Inputs:',tuple(sorted(set(inp_lst)))) + if chances != 0: + print("Tried Inputs:", tuple(sorted(set(inp_lst)))) + print( + f"\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~You were left with {chances} Chances~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + ) + else: + print( + f"\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Correct Answer: {name} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + ) + print(incl.lose + "\a") + break - else: - print('\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Try Again!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~') - print(f'\nYou have to Guess a Human Name of {len(name)} Alphabets:\t{result_str}\n') - print(incl.draw[chances]) - chances=chances-1 - - if chances!=0: - print('Tried Inputs:',tuple(sorted(set(inp_lst)))) - print(f'\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~You were left with {chances} Chances~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~') - else: - print(f'\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Correct Answer: {name} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~') - print(incl.lose+'\a') - break - - try: - if int(input('To play the Game Again Press "1" & "0" to Quit: '))!=1: - exit('\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Thank You~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~') - except: - exit('\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Thank You~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~') + try: + if int(input('To play the Game Again Press "1" & "0" to Quit: ')) != 1: + exit( + "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Thank You~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + ) + except: + exit( + "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Thank You~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + ) diff --git a/Hangman.py b/Hangman.py index 27b82db2c4a..d9e4927a444 100644 --- a/Hangman.py +++ b/Hangman.py @@ -1,8 +1,7 @@ # importing the time module -import time - # importing the random module import random +import time # welcoming the user name = input("What is your name? ") @@ -33,21 +32,17 @@ # check if the turns are more than zero while turns > 0: - # make a counter that starts with zero failed = 0 # for every character in secret_word for char in word: - # see if the character is in the players guess if char in guesses: - # print then out the character print(char, end=" ") else: - # if not found, print a dash print("_", end=" ") @@ -84,7 +79,6 @@ # if the guess is not found in the secret word if guess not in word: - # turns counter decreases with 1 (now 9) turns -= 1 @@ -96,6 +90,5 @@ # if the turns are equal to zero if turns == 0: - # print "You Loose" print("\nYou Loose") diff --git a/Hotel-Management.py b/Hotel-Management.py index ca6e0216cc3..26caf2ee423 100644 --- a/Hotel-Management.py +++ b/Hotel-Management.py @@ -1,49 +1,26 @@ - def menu(): - options = { - 1 : { - "title" : "Add new customer details", - "method": lambda : add() - }, - - 2 : { - "title" : "Modify already existing customer details", - "method": lambda : modify() - }, - - 3 : { - "title" : "Search customer details", - "method": lambda : search() - }, - - 4 : { - "title" : "View all customer details", - "method": lambda : view() - }, - - 5 : { - "title" : "Delete customer details", - "method": lambda : remove() - }, - - 6 : { - "title" : "Exit the program", - "method": lambda : exit() - } + 1: {"title": "Add new customer details", "method": lambda: add()}, + 2: { + "title": "Modify already existing customer details", + "method": lambda: modify(), + }, + 3: {"title": "Search customer details", "method": lambda: search()}, + 4: {"title": "View all customer details", "method": lambda: view()}, + 5: {"title": "Delete customer details", "method": lambda: remove()}, + 6: {"title": "Exit the program", "method": lambda: exit()}, } - print(f"\n\n{' '*25}Welcome to Hotel Database Management Software\n\n") + print(f"\n\n{' ' * 25}Welcome to Hotel Database Management Software\n\n") for num, option in options.items(): print(f"{num}: {option.get('title')}") print() - options.get( int(input("Enter your choice(1-6): ")) ).get("method")() + options.get(int(input("Enter your choice(1-6): "))).get("method")() def add(): - Name1 = input("\nEnter your first name: \n") Name2 = input("\nEnter your last name: \n") Phone_Num = input("\nEnter your phone number(without +91): \n") @@ -87,7 +64,7 @@ def add(): print("Online payment") print("") - with open("Management.txt", "r") as File: + with open("Management.txt") as File: string = File.read() string = string.replace("'", '"') dictionary = json.loads(string) @@ -123,8 +100,8 @@ def add(): exit_menu() -import os import json +import os filecheck = os.path.isfile("Management.txt") if not filecheck: @@ -142,8 +119,7 @@ def add(): def modify(): - - with open("Management.txt", "r") as File: + with open("Management.txt") as File: string = File.read() string = string.replace("'", '"') dictionary = json.loads(string) @@ -167,7 +143,6 @@ def modify(): print() with open("Management.txt", "w", encoding="utf-8") as File: - match choice: case 1: category = "First_Name" @@ -189,7 +164,6 @@ def modify(): def search(): - with open("Management.txt") as File: dictionary = json.loads(File.read().replace("'", '"')) @@ -284,7 +258,6 @@ def remove(): def view(): - with open("Management.txt") as File: dictionary = json.loads(File.read().replace("'", '"')) diff --git a/Image-watermarker/app.py b/Image-watermarker/app.py index 3a388d3b98a..1dabfa59448 100644 --- a/Image-watermarker/app.py +++ b/Image-watermarker/app.py @@ -1,11 +1,11 @@ +from tkinter import colorchooser + import customtkinter as ctk -from customtkinter import filedialog +import pyglet from CTkMessagebox import CTkMessagebox +from customtkinter import filedialog from PIL import Image, ImageTk from watermark import Watermark -import pyglet -from tkinter import colorchooser - # ------------------- Create Window ----------------- pyglet.font.add_directory("fonts") @@ -44,7 +44,7 @@ def load_image(): ) loaded_image = ImageTk.PhotoImage(resize_img) - window.geometry(f"{resize_img.width + 300+30}x{resize_img.height + 50}") + window.geometry(f"{resize_img.width + 300 + 30}x{resize_img.height + 50}") image_canvas.config(width=resize_img.width, height=resize_img.height) image_canvas.grid(row=0, column=1, padx=20, pady=20, columnspan=2) image_canvas.create_image(0, 0, anchor="nw", image=loaded_image) diff --git a/Image-watermarker/requirements.txt b/Image-watermarker/requirements.txt deleted file mode 100644 index f6fcb76c983..00000000000 Binary files a/Image-watermarker/requirements.txt and /dev/null differ diff --git a/Image-watermarker/watermark.py b/Image-watermarker/watermark.py index e820eeccaad..69139ee7196 100644 --- a/Image-watermarker/watermark.py +++ b/Image-watermarker/watermark.py @@ -1,6 +1,6 @@ -from PIL import ImageDraw, ImageFont -from customtkinter import filedialog from CTkMessagebox import CTkMessagebox +from customtkinter import filedialog +from PIL import ImageDraw, ImageFont class Watermark: @@ -10,7 +10,6 @@ def __init__(self): def add_text_watermark( self, image, text, text_color, font_style, font_size, position=(0, 0) ): - font = ImageFont.truetype(font_style, font_size) draw = ImageDraw.Draw(image) draw.text(position, text, fill=text_color, font=font) diff --git a/ImageDownloader/img_downloader.py b/ImageDownloader/img_downloader.py index 4ed7c65d8ff..d3702cdd829 100644 --- a/ImageDownloader/img_downloader.py +++ b/ImageDownloader/img_downloader.py @@ -4,23 +4,24 @@ def ImageDownloader(url): import os import re - import requests - response = requests.get(url) + import httpx + + response = httpx.get(url) text = response.text p = r']+>' img_addrs = re.findall(p, text) for i in img_addrs: - os.system("wget {}".format(i)) + os.system(f"wget {i}") return "DONE" # USAGE print("Hey!! Welcome to the Image downloader...") -link=input("Please enter the url from where you want to download the image..") +link = input("Please enter the url from where you want to download the image..") # now you can give the input at run time and get download the images. # https://www.123rf.com/stock-photo/spring_color.html?oriSearch=spring&ch=spring&sti=oazo8ueuz074cdpc48 ImageDownloader(link) diff --git a/ImageDownloader/requirements.txt b/ImageDownloader/requirements.txt deleted file mode 100644 index bd6f2345868..00000000000 --- a/ImageDownloader/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.32.4 diff --git a/Image_resize.py b/Image_resize.py index 9c6336d8d1d..6bc312b245d 100644 --- a/Image_resize.py +++ b/Image_resize.py @@ -1,24 +1,24 @@ def jpeg_res(filename): - """"This function prints the resolution of the jpeg image file passed into it""" + """ "This function prints the resolution of the jpeg image file passed into it""" - # open image for reading in binary mode - with open(filename,'rb') as img_file: + # open image for reading in binary mode + with open(filename, "rb") as img_file: + # height of image (in 2 bytes) is at 164th position + img_file.seek(163) - # height of image (in 2 bytes) is at 164th position - img_file.seek(163) + # read the 2 bytes + a = img_file.read(2) - # read the 2 bytes - a = img_file.read(2) + # calculate height + height = (a[0] << 8) + a[1] - # calculate height - height = (a[0] << 8) + a[1] + # next 2 bytes is width + a = img_file.read(2) - # next 2 bytes is width - a = img_file.read(2) + # calculate width + width = (a[0] << 8) + a[1] - # calculate width - width = (a[0] << 8) + a[1] + print("The resolution of the image is", width, "x", height) - print("The resolution of the image is",width,"x",height) jpeg_res("img1.jpg") diff --git a/Industrial_developed_hangman/Makefile b/Industrial_developed_hangman/Makefile deleted file mode 100644 index e4e05f18fb2..00000000000 --- a/Industrial_developed_hangman/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -lint: - poetry run isort src tests - poetry run flake8 src tests - poetry run mypy src - poetry run mypy tests - -test: - poetry run pytest - -build: - python src/hangman/main.py -install: - pip install poetry - poetry install \ No newline at end of file diff --git a/Industrial_developed_hangman/poetry.lock b/Industrial_developed_hangman/poetry.lock deleted file mode 100644 index 99bcf936a62..00000000000 --- a/Industrial_developed_hangman/poetry.lock +++ /dev/null @@ -1,1235 +0,0 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. - -[[package]] -name = "astor" -version = "0.8.1" -description = "Read/rewrite/write Python ASTs" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -files = [ - {file = "astor-0.8.1-py2.py3-none-any.whl", hash = "sha256:070a54e890cefb5b3739d19f30f5a5ec840ffc9c50ffa7d23cc9fc1a38ebbfc5"}, - {file = "astor-0.8.1.tar.gz", hash = "sha256:6a6effda93f4e1ce9f618779b2dd1d9d84f1e32812c23a29b3fff6fd7f63fa5e"}, -] - -[[package]] -name = "attrs" -version = "23.1.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" -files = [ - {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, - {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, -] - -[package.extras] -cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[docs,tests]", "pre-commit"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] - -[[package]] -name = "bandit" -version = "1.7.5" -description = "Security oriented static analyser for python code." -optional = false -python-versions = ">=3.7" -files = [ - {file = "bandit-1.7.5-py3-none-any.whl", hash = "sha256:75665181dc1e0096369112541a056c59d1c5f66f9bb74a8d686c3c362b83f549"}, - {file = "bandit-1.7.5.tar.gz", hash = "sha256:bdfc739baa03b880c2d15d0431b31c658ffc348e907fe197e54e0389dd59e11e"}, -] - -[package.dependencies] -colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} -GitPython = ">=1.0.1" -PyYAML = ">=5.3.1" -rich = "*" -stevedore = ">=1.20.0" - -[package.extras] -test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "tomli (>=1.1.0)"] -toml = ["tomli (>=1.1.0)"] -yaml = ["PyYAML"] - -[[package]] -name = "beautifulsoup4" -version = "4.12.0" -description = "Screen-scraping library" -optional = false -python-versions = ">=3.6.0" -files = [ - {file = "beautifulsoup4-4.12.0-py3-none-any.whl", hash = "sha256:2130a5ad7f513200fae61a17abb5e338ca980fa28c439c0571014bc0217e9591"}, - {file = "beautifulsoup4-4.12.0.tar.gz", hash = "sha256:c5fceeaec29d09c84970e47c65f2f0efe57872f7cff494c9691a26ec0ff13234"}, -] - -[package.dependencies] -soupsieve = ">1.2" - -[package.extras] -html5lib = ["html5lib"] -lxml = ["lxml"] - -[[package]] -name = "certifi" -version = "2023.7.22" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, - {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.3.2" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "coverage" -version = "7.3.2" -description = "Code coverage measurement for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "coverage-7.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf"}, - {file = "coverage-7.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda"}, - {file = "coverage-7.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a"}, - {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c"}, - {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f"}, - {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6"}, - {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148"}, - {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9"}, - {file = "coverage-7.3.2-cp310-cp310-win32.whl", hash = "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f"}, - {file = "coverage-7.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611"}, - {file = "coverage-7.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c"}, - {file = "coverage-7.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074"}, - {file = "coverage-7.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a"}, - {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3"}, - {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a"}, - {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1"}, - {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c"}, - {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312"}, - {file = "coverage-7.3.2-cp311-cp311-win32.whl", hash = "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640"}, - {file = "coverage-7.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2"}, - {file = "coverage-7.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836"}, - {file = "coverage-7.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63"}, - {file = "coverage-7.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216"}, - {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4"}, - {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf"}, - {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf"}, - {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84"}, - {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a"}, - {file = "coverage-7.3.2-cp312-cp312-win32.whl", hash = "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb"}, - {file = "coverage-7.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed"}, - {file = "coverage-7.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738"}, - {file = "coverage-7.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2"}, - {file = "coverage-7.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2"}, - {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c"}, - {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9"}, - {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82"}, - {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901"}, - {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76"}, - {file = "coverage-7.3.2-cp38-cp38-win32.whl", hash = "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92"}, - {file = "coverage-7.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a"}, - {file = "coverage-7.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce"}, - {file = "coverage-7.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9"}, - {file = "coverage-7.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f"}, - {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25"}, - {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9"}, - {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6"}, - {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc"}, - {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083"}, - {file = "coverage-7.3.2-cp39-cp39-win32.whl", hash = "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce"}, - {file = "coverage-7.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f"}, - {file = "coverage-7.3.2-pp38.pp39.pp310-none-any.whl", hash = "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637"}, - {file = "coverage-7.3.2.tar.gz", hash = "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef"}, -] - -[package.dependencies] -tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} - -[package.extras] -toml = ["tomli"] - -[[package]] -name = "darglint" -version = "1.8.1" -description = "A utility for ensuring Google-style docstrings stay up to date with the source code." -optional = false -python-versions = ">=3.6,<4.0" -files = [ - {file = "darglint-1.8.1-py3-none-any.whl", hash = "sha256:5ae11c259c17b0701618a20c3da343a3eb98b3bc4b5a83d31cdd94f5ebdced8d"}, - {file = "darglint-1.8.1.tar.gz", hash = "sha256:080d5106df149b199822e7ee7deb9c012b49891538f14a11be681044f0bb20da"}, -] - -[[package]] -name = "docutils" -version = "0.20.1" -description = "Docutils -- Python Documentation Utilities" -optional = false -python-versions = ">=3.7" -files = [ - {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, - {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, -] - -[[package]] -name = "eradicate" -version = "2.3.0" -description = "Removes commented-out code." -optional = false -python-versions = "*" -files = [ - {file = "eradicate-2.3.0-py3-none-any.whl", hash = "sha256:2b29b3dd27171f209e4ddd8204b70c02f0682ae95eecb353f10e8d72b149c63e"}, - {file = "eradicate-2.3.0.tar.gz", hash = "sha256:06df115be3b87d0fc1c483db22a2ebb12bcf40585722810d809cc770f5031c37"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.1.3" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"}, - {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "flake8" -version = "6.1.0" -description = "the modular source code checker: pep8 pyflakes and co" -optional = false -python-versions = ">=3.8.1" -files = [ - {file = "flake8-6.1.0-py2.py3-none-any.whl", hash = "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"}, - {file = "flake8-6.1.0.tar.gz", hash = "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23"}, -] - -[package.dependencies] -mccabe = ">=0.7.0,<0.8.0" -pycodestyle = ">=2.11.0,<2.12.0" -pyflakes = ">=3.1.0,<3.2.0" - -[[package]] -name = "flake8-bandit" -version = "4.1.1" -description = "Automated security testing with bandit and flake8." -optional = false -python-versions = ">=3.6" -files = [ - {file = "flake8_bandit-4.1.1-py3-none-any.whl", hash = "sha256:4c8a53eb48f23d4ef1e59293657181a3c989d0077c9952717e98a0eace43e06d"}, - {file = "flake8_bandit-4.1.1.tar.gz", hash = "sha256:068e09287189cbfd7f986e92605adea2067630b75380c6b5733dab7d87f9a84e"}, -] - -[package.dependencies] -bandit = ">=1.7.3" -flake8 = ">=5.0.0" - -[[package]] -name = "flake8-broken-line" -version = "1.0.0" -description = "Flake8 plugin to forbid backslashes for line breaks" -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "flake8_broken_line-1.0.0-py3-none-any.whl", hash = "sha256:96c964336024a5030dc536a9f6fb02aa679e2d2a6b35b80a558b5136c35832a9"}, - {file = "flake8_broken_line-1.0.0.tar.gz", hash = "sha256:e2c6a17f8d9a129e99c1320fce89b33843e2963871025c4c2bb7b8b8d8732a85"}, -] - -[package.dependencies] -flake8 = ">5" - -[[package]] -name = "flake8-bugbear" -version = "23.9.16" -description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle." -optional = false -python-versions = ">=3.8.1" -files = [ - {file = "flake8-bugbear-23.9.16.tar.gz", hash = "sha256:90cf04b19ca02a682feb5aac67cae8de742af70538590509941ab10ae8351f71"}, - {file = "flake8_bugbear-23.9.16-py3-none-any.whl", hash = "sha256:b182cf96ea8f7a8595b2f87321d7d9b28728f4d9c3318012d896543d19742cb5"}, -] - -[package.dependencies] -attrs = ">=19.2.0" -flake8 = ">=6.0.0" - -[package.extras] -dev = ["coverage", "hypothesis", "hypothesmith (>=0.2)", "pre-commit", "pytest", "tox"] - -[[package]] -name = "flake8-commas" -version = "2.1.0" -description = "Flake8 lint for trailing commas." -optional = false -python-versions = "*" -files = [ - {file = "flake8-commas-2.1.0.tar.gz", hash = "sha256:940441ab8ee544df564ae3b3f49f20462d75d5c7cac2463e0b27436e2050f263"}, - {file = "flake8_commas-2.1.0-py2.py3-none-any.whl", hash = "sha256:ebb96c31e01d0ef1d0685a21f3f0e2f8153a0381430e748bf0bbbb5d5b453d54"}, -] - -[package.dependencies] -flake8 = ">=2" - -[[package]] -name = "flake8-comprehensions" -version = "3.14.0" -description = "A flake8 plugin to help you write better list/set/dict comprehensions." -optional = false -python-versions = ">=3.8" -files = [ - {file = "flake8_comprehensions-3.14.0-py3-none-any.whl", hash = "sha256:7b9d07d94aa88e62099a6d1931ddf16c344d4157deedf90fe0d8ee2846f30e97"}, - {file = "flake8_comprehensions-3.14.0.tar.gz", hash = "sha256:81768c61bfc064e1a06222df08a2580d97de10cb388694becaf987c331c6c0cf"}, -] - -[package.dependencies] -flake8 = ">=3.0,<3.2.0 || >3.2.0" - -[[package]] -name = "flake8-debugger" -version = "4.1.2" -description = "ipdb/pdb statement checker plugin for flake8" -optional = false -python-versions = ">=3.7" -files = [ - {file = "flake8-debugger-4.1.2.tar.gz", hash = "sha256:52b002560941e36d9bf806fca2523dc7fb8560a295d5f1a6e15ac2ded7a73840"}, - {file = "flake8_debugger-4.1.2-py3-none-any.whl", hash = "sha256:0a5e55aeddcc81da631ad9c8c366e7318998f83ff00985a49e6b3ecf61e571bf"}, -] - -[package.dependencies] -flake8 = ">=3.0" -pycodestyle = "*" - -[[package]] -name = "flake8-docstrings" -version = "1.7.0" -description = "Extension for flake8 which uses pydocstyle to check docstrings" -optional = false -python-versions = ">=3.7" -files = [ - {file = "flake8_docstrings-1.7.0-py2.py3-none-any.whl", hash = "sha256:51f2344026da083fc084166a9353f5082b01f72901df422f74b4d953ae88ac75"}, - {file = "flake8_docstrings-1.7.0.tar.gz", hash = "sha256:4c8cc748dc16e6869728699e5d0d685da9a10b0ea718e090b1ba088e67a941af"}, -] - -[package.dependencies] -flake8 = ">=3" -pydocstyle = ">=2.1" - -[[package]] -name = "flake8-eradicate" -version = "1.5.0" -description = "Flake8 plugin to find commented out code" -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "flake8_eradicate-1.5.0-py3-none-any.whl", hash = "sha256:18acc922ad7de623f5247c7d5595da068525ec5437dd53b22ec2259b96ce9d22"}, - {file = "flake8_eradicate-1.5.0.tar.gz", hash = "sha256:aee636cb9ecb5594a7cd92d67ad73eb69909e5cc7bd81710cf9d00970f3983a6"}, -] - -[package.dependencies] -attrs = "*" -eradicate = ">=2.0,<3.0" -flake8 = ">5" - -[[package]] -name = "flake8-isort" -version = "6.1.0" -description = "flake8 plugin that integrates isort ." -optional = false -python-versions = ">=3.8" -files = [ - {file = "flake8-isort-6.1.0.tar.gz", hash = "sha256:d4639343bac540194c59fb1618ac2c285b3e27609f353bef6f50904d40c1643e"}, -] - -[package.dependencies] -flake8 = "*" -isort = ">=5.0.0,<6" - -[package.extras] -test = ["pytest"] - -[[package]] -name = "flake8-quotes" -version = "3.3.2" -description = "Flake8 lint for quotes." -optional = false -python-versions = "*" -files = [ - {file = "flake8-quotes-3.3.2.tar.gz", hash = "sha256:6e26892b632dacba517bf27219c459a8396dcfac0f5e8204904c5a4ba9b480e1"}, -] - -[package.dependencies] -flake8 = "*" - -[[package]] -name = "flake8-rst-docstrings" -version = "0.3.0" -description = "Python docstring reStructuredText (RST) validator for flake8" -optional = false -python-versions = ">=3.7" -files = [ - {file = "flake8-rst-docstrings-0.3.0.tar.gz", hash = "sha256:d1ce22b4bd37b73cd86b8d980e946ef198cfcc18ed82fedb674ceaa2f8d1afa4"}, - {file = "flake8_rst_docstrings-0.3.0-py3-none-any.whl", hash = "sha256:f8c3c6892ff402292651c31983a38da082480ad3ba253743de52989bdc84ca1c"}, -] - -[package.dependencies] -flake8 = ">=3" -pygments = "*" -restructuredtext-lint = "*" - -[package.extras] -develop = ["build", "twine"] - -[[package]] -name = "flake8-string-format" -version = "0.3.0" -description = "string format checker, plugin for flake8" -optional = false -python-versions = "*" -files = [ - {file = "flake8-string-format-0.3.0.tar.gz", hash = "sha256:65f3da786a1461ef77fca3780b314edb2853c377f2e35069723348c8917deaa2"}, - {file = "flake8_string_format-0.3.0-py2.py3-none-any.whl", hash = "sha256:812ff431f10576a74c89be4e85b8e075a705be39bc40c4b4278b5b13e2afa9af"}, -] - -[package.dependencies] -flake8 = "*" - -[[package]] -name = "freezegun" -version = "1.2.2" -description = "Let your Python tests travel through time" -optional = false -python-versions = ">=3.6" -files = [ - {file = "freezegun-1.2.2-py3-none-any.whl", hash = "sha256:ea1b963b993cb9ea195adbd893a48d573fda951b0da64f60883d7e988b606c9f"}, - {file = "freezegun-1.2.2.tar.gz", hash = "sha256:cd22d1ba06941384410cd967d8a99d5ae2442f57dfafeff2fda5de8dc5c05446"}, -] - -[package.dependencies] -python-dateutil = ">=2.7" - -[[package]] -name = "gitdb" -version = "4.0.11" -description = "Git Object Database" -optional = false -python-versions = ">=3.7" -files = [ - {file = "gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4"}, - {file = "gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b"}, -] - -[package.dependencies] -smmap = ">=3.0.1,<6" - -[[package]] -name = "gitpython" -version = "3.1.40" -description = "GitPython is a Python library used to interact with Git repositories" -optional = false -python-versions = ">=3.7" -files = [ - {file = "GitPython-3.1.40-py3-none-any.whl", hash = "sha256:cf14627d5a8049ffbf49915732e5eddbe8134c3bdb9d476e6182b676fc573f8a"}, - {file = "GitPython-3.1.40.tar.gz", hash = "sha256:22b126e9ffb671fdd0c129796343a02bf67bf2994b35449ffc9321aa755e18a4"}, -] - -[package.dependencies] -gitdb = ">=4.0.1,<5" - -[package.extras] -test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest", "pytest-cov", "pytest-instafail", "pytest-subtests", "pytest-sugar"] - -[[package]] -name = "idna" -version = "3.4" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.5" -files = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, -] - -[[package]] -name = "importlib-metadata" -version = "6.8.0" -description = "Read metadata from Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, - {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, -] - -[package.dependencies] -zipp = ">=0.5" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "isort" -version = "5.12.0" -description = "A Python utility / library to sort Python imports." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, - {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, -] - -[package.extras] -colors = ["colorama (>=0.4.3)"] -pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] -plugins = ["setuptools"] -requirements-deprecated-finder = ["pip-api", "pipreqs"] - -[[package]] -name = "markdown-it-py" -version = "3.0.0" -description = "Python port of markdown-it. Markdown parsing, done right!" -optional = false -python-versions = ">=3.8" -files = [ - {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, - {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, -] - -[package.dependencies] -mdurl = ">=0.1,<1.0" - -[package.extras] -benchmarking = ["psutil", "pytest", "pytest-benchmark"] -code-style = ["pre-commit (>=3.0,<4.0)"] -compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] -linkify = ["linkify-it-py (>=1,<3)"] -plugins = ["mdit-py-plugins"] -profiling = ["gprof2dot"] -rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] - -[[package]] -name = "mccabe" -version = "0.7.0" -description = "McCabe checker, plugin for flake8" -optional = false -python-versions = ">=3.6" -files = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, -] - -[[package]] -name = "mdurl" -version = "0.1.2" -description = "Markdown URL utilities" -optional = false -python-versions = ">=3.7" -files = [ - {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, - {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, -] - -[[package]] -name = "mypy" -version = "1.5.1" -description = "Optional static typing for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "mypy-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f33592ddf9655a4894aef22d134de7393e95fcbdc2d15c1ab65828eee5c66c70"}, - {file = "mypy-1.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:258b22210a4a258ccd077426c7a181d789d1121aca6db73a83f79372f5569ae0"}, - {file = "mypy-1.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9ec1f695f0c25986e6f7f8778e5ce61659063268836a38c951200c57479cc12"}, - {file = "mypy-1.5.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:abed92d9c8f08643c7d831300b739562b0a6c9fcb028d211134fc9ab20ccad5d"}, - {file = "mypy-1.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:a156e6390944c265eb56afa67c74c0636f10283429171018446b732f1a05af25"}, - {file = "mypy-1.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6ac9c21bfe7bc9f7f1b6fae441746e6a106e48fc9de530dea29e8cd37a2c0cc4"}, - {file = "mypy-1.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51cb1323064b1099e177098cb939eab2da42fea5d818d40113957ec954fc85f4"}, - {file = "mypy-1.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:596fae69f2bfcb7305808c75c00f81fe2829b6236eadda536f00610ac5ec2243"}, - {file = "mypy-1.5.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:32cb59609b0534f0bd67faebb6e022fe534bdb0e2ecab4290d683d248be1b275"}, - {file = "mypy-1.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:159aa9acb16086b79bbb0016145034a1a05360626046a929f84579ce1666b315"}, - {file = "mypy-1.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f6b0e77db9ff4fda74de7df13f30016a0a663928d669c9f2c057048ba44f09bb"}, - {file = "mypy-1.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:26f71b535dfc158a71264e6dc805a9f8d2e60b67215ca0bfa26e2e1aa4d4d373"}, - {file = "mypy-1.5.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fc3a600f749b1008cc75e02b6fb3d4db8dbcca2d733030fe7a3b3502902f161"}, - {file = "mypy-1.5.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:26fb32e4d4afa205b24bf645eddfbb36a1e17e995c5c99d6d00edb24b693406a"}, - {file = "mypy-1.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:82cb6193de9bbb3844bab4c7cf80e6227d5225cc7625b068a06d005d861ad5f1"}, - {file = "mypy-1.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4a465ea2ca12804d5b34bb056be3a29dc47aea5973b892d0417c6a10a40b2d65"}, - {file = "mypy-1.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9fece120dbb041771a63eb95e4896791386fe287fefb2837258925b8326d6160"}, - {file = "mypy-1.5.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d28ddc3e3dfeab553e743e532fb95b4e6afad51d4706dd22f28e1e5e664828d2"}, - {file = "mypy-1.5.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:57b10c56016adce71fba6bc6e9fd45d8083f74361f629390c556738565af8eeb"}, - {file = "mypy-1.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:ff0cedc84184115202475bbb46dd99f8dcb87fe24d5d0ddfc0fe6b8575c88d2f"}, - {file = "mypy-1.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8f772942d372c8cbac575be99f9cc9d9fb3bd95c8bc2de6c01411e2c84ebca8a"}, - {file = "mypy-1.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5d627124700b92b6bbaa99f27cbe615c8ea7b3402960f6372ea7d65faf376c14"}, - {file = "mypy-1.5.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:361da43c4f5a96173220eb53340ace68cda81845cd88218f8862dfb0adc8cddb"}, - {file = "mypy-1.5.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:330857f9507c24de5c5724235e66858f8364a0693894342485e543f5b07c8693"}, - {file = "mypy-1.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:c543214ffdd422623e9fedd0869166c2f16affe4ba37463975043ef7d2ea8770"}, - {file = "mypy-1.5.1-py3-none-any.whl", hash = "sha256:f757063a83970d67c444f6e01d9550a7402322af3557ce7630d3c957386fa8f5"}, - {file = "mypy-1.5.1.tar.gz", hash = "sha256:b031b9601f1060bf1281feab89697324726ba0c0bae9d7cd7ab4b690940f0b92"}, -] - -[package.dependencies] -mypy-extensions = ">=1.0.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = ">=4.1.0" - -[package.extras] -dmypy = ["psutil (>=4.0)"] -install-types = ["pip"] -reports = ["lxml"] - -[[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.5" -files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] - -[[package]] -name = "packaging" -version = "23.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, -] - -[[package]] -name = "pbr" -version = "5.11.1" -description = "Python Build Reasonableness" -optional = false -python-versions = ">=2.6" -files = [ - {file = "pbr-5.11.1-py2.py3-none-any.whl", hash = "sha256:567f09558bae2b3ab53cb3c1e2e33e726ff3338e7bae3db5dc954b3a44eef12b"}, - {file = "pbr-5.11.1.tar.gz", hash = "sha256:aefc51675b0b533d56bb5fd1c8c6c0522fe31896679882e1c4c63d5e4a0fccb3"}, -] - -[[package]] -name = "pep8-naming" -version = "0.13.3" -description = "Check PEP-8 naming conventions, plugin for flake8" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pep8-naming-0.13.3.tar.gz", hash = "sha256:1705f046dfcd851378aac3be1cd1551c7c1e5ff363bacad707d43007877fa971"}, - {file = "pep8_naming-0.13.3-py3-none-any.whl", hash = "sha256:1a86b8c71a03337c97181917e2b472f0f5e4ccb06844a0d6f0a33522549e7a80"}, -] - -[package.dependencies] -flake8 = ">=5.0.0" - -[[package]] -name = "pluggy" -version = "1.3.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, - {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "pycodestyle" -version = "2.11.1" -description = "Python style guide checker" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"}, - {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"}, -] - -[[package]] -name = "pydocstyle" -version = "6.3.0" -description = "Python docstring style checker" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"}, - {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"}, -] - -[package.dependencies] -snowballstemmer = ">=2.2.0" - -[package.extras] -toml = ["tomli (>=1.2.3)"] - -[[package]] -name = "pyflakes" -version = "3.1.0" -description = "passive checker of Python programs" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"}, - {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"}, -] - -[[package]] -name = "pygments" -version = "2.16.1" -description = "Pygments is a syntax highlighting package written in Python." -optional = false -python-versions = ">=3.7" -files = [ - {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, - {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, -] - -[package.extras] -plugins = ["importlib-metadata"] - -[[package]] -name = "pytest" -version = "7.4.2" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-7.4.2-py3-none-any.whl", hash = "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002"}, - {file = "pytest-7.4.2.tar.gz", hash = "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} - -[package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-cov" -version = "4.1.0" -description = "Pytest plugin for measuring coverage." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, - {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, -] - -[package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} -pytest = ">=4.6" - -[package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] - -[[package]] -name = "pytest-freezer" -version = "0.4.8" -description = "Pytest plugin providing a fixture interface for spulec/freezegun" -optional = false -python-versions = ">= 3.6" -files = [ - {file = "pytest_freezer-0.4.8-py3-none-any.whl", hash = "sha256:644ce7ddb8ba52b92a1df0a80a699bad2b93514c55cf92e9f2517b68ebe74814"}, - {file = "pytest_freezer-0.4.8.tar.gz", hash = "sha256:8ee2f724b3ff3540523fa355958a22e6f4c1c819928b78a7a183ae4248ce6ee6"}, -] - -[package.dependencies] -freezegun = ">=1.0" -pytest = ">=3.6" - -[[package]] -name = "pytest-randomly" -version = "3.15.0" -description = "Pytest plugin to randomly order tests and control random.seed." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest_randomly-3.15.0-py3-none-any.whl", hash = "sha256:0516f4344b29f4e9cdae8bce31c4aeebf59d0b9ef05927c33354ff3859eeeca6"}, - {file = "pytest_randomly-3.15.0.tar.gz", hash = "sha256:b908529648667ba5e54723088edd6f82252f540cc340d748d1fa985539687047"}, -] - -[package.dependencies] -importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""} -pytest = "*" - -[[package]] -name = "pytest-timeout" -version = "2.2.0" -description = "pytest plugin to abort hanging tests" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-timeout-2.2.0.tar.gz", hash = "sha256:3b0b95dabf3cb50bac9ef5ca912fa0cfc286526af17afc806824df20c2f72c90"}, - {file = "pytest_timeout-2.2.0-py3-none-any.whl", hash = "sha256:bde531e096466f49398a59f2dde76fa78429a09a12411466f88a07213e220de2"}, -] - -[package.dependencies] -pytest = ">=5.0.0" - -[[package]] -name = "python-dateutil" -version = "2.8.2" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pyyaml" -version = "6.0.1" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, -] - -[[package]] -name = "requests" -version = "2.31.0" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.7" -files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-mock" -version = "1.11.0" -description = "Mock out responses from the requests package" -optional = false -python-versions = "*" -files = [ - {file = "requests-mock-1.11.0.tar.gz", hash = "sha256:ef10b572b489a5f28e09b708697208c4a3b2b89ef80a9f01584340ea357ec3c4"}, - {file = "requests_mock-1.11.0-py2.py3-none-any.whl", hash = "sha256:f7fae383f228633f6bececebdab236c478ace2284d6292c6e7e2867b9ab74d15"}, -] - -[package.dependencies] -requests = ">=2.3,<3" -six = "*" - -[package.extras] -fixture = ["fixtures"] -test = ["fixtures", "mock", "purl", "pytest", "requests-futures", "sphinx", "testtools"] - -[[package]] -name = "restructuredtext-lint" -version = "1.4.0" -description = "reStructuredText linter" -optional = false -python-versions = "*" -files = [ - {file = "restructuredtext_lint-1.4.0.tar.gz", hash = "sha256:1b235c0c922341ab6c530390892eb9e92f90b9b75046063e047cacfb0f050c45"}, -] - -[package.dependencies] -docutils = ">=0.11,<1.0" - -[[package]] -name = "rich" -version = "13.6.0" -description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "rich-13.6.0-py3-none-any.whl", hash = "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245"}, - {file = "rich-13.6.0.tar.gz", hash = "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef"}, -] - -[package.dependencies] -markdown-it-py = ">=2.2.0" -pygments = ">=2.13.0,<3.0.0" - -[package.extras] -jupyter = ["ipywidgets (>=7.5.1,<9)"] - -[[package]] -name = "setuptools" -version = "68.2.2" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"}, - {file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "smmap" -version = "5.0.1" -description = "A pure Python implementation of a sliding window memory map manager" -optional = false -python-versions = ">=3.7" -files = [ - {file = "smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da"}, - {file = "smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62"}, -] - -[[package]] -name = "snowballstemmer" -version = "2.2.0" -description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -optional = false -python-versions = "*" -files = [ - {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, - {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, -] - -[[package]] -name = "soupsieve" -version = "2.5" -description = "A modern CSS selector implementation for Beautiful Soup." -optional = false -python-versions = ">=3.8" -files = [ - {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, - {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, -] - -[[package]] -name = "stevedore" -version = "5.1.0" -description = "Manage dynamic plugins for Python applications" -optional = false -python-versions = ">=3.8" -files = [ - {file = "stevedore-5.1.0-py3-none-any.whl", hash = "sha256:8cc040628f3cea5d7128f2e76cf486b2251a4e543c7b938f58d9a377f6694a2d"}, - {file = "stevedore-5.1.0.tar.gz", hash = "sha256:a54534acf9b89bc7ed264807013b505bf07f74dbe4bcfa37d32bd063870b087c"}, -] - -[package.dependencies] -pbr = ">=2.0.0,<2.1.0 || >2.1.0" - -[[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] - -[[package]] -name = "types-requests" -version = "2.31.0.2" -description = "Typing stubs for requests" -optional = false -python-versions = "*" -files = [ - {file = "types-requests-2.31.0.2.tar.gz", hash = "sha256:6aa3f7faf0ea52d728bb18c0a0d1522d9bfd8c72d26ff6f61bfc3d06a411cf40"}, - {file = "types_requests-2.31.0.2-py3-none-any.whl", hash = "sha256:56d181c85b5925cbc59f4489a57e72a8b2166f18273fd8ba7b6fe0c0b986f12a"}, -] - -[package.dependencies] -types-urllib3 = "*" - -[[package]] -name = "types-urllib3" -version = "1.26.25.14" -description = "Typing stubs for urllib3" -optional = false -python-versions = "*" -files = [ - {file = "types-urllib3-1.26.25.14.tar.gz", hash = "sha256:229b7f577c951b8c1b92c1bc2b2fdb0b49847bd2af6d1cc2a2e3dd340f3bda8f"}, - {file = "types_urllib3-1.26.25.14-py3-none-any.whl", hash = "sha256:9683bbb7fb72e32bfe9d2be6e04875fbe1b3eeec3cbb4ea231435aa7fd6b4f0e"}, -] - -[[package]] -name = "typing-extensions" -version = "4.8.0" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, - {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, -] - -[[package]] -name = "urllib3" -version = "2.0.7" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.7" -files = [ - {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, - {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "wemake-python-styleguide" -version = "0.18.0" -description = "The strictest and most opinionated python linter ever" -optional = false -python-versions = ">=3.8.1,<4.0" -files = [ - {file = "wemake_python_styleguide-0.18.0-py3-none-any.whl", hash = "sha256:2219be145185edcd5e01f4ce49e3dea11acc34f2c377face0c175bb6ea6ac988"}, - {file = "wemake_python_styleguide-0.18.0.tar.gz", hash = "sha256:69139858cf5b2a9ba09dac136e2873a4685515768f68fdef2684ebefd7b1dafd"}, -] - -[package.dependencies] -astor = ">=0.8,<0.9" -attrs = "*" -darglint = ">=1.2,<2.0" -flake8 = ">5" -flake8-bandit = ">=4.1,<5.0" -flake8-broken-line = ">=1.0,<2.0" -flake8-bugbear = ">=23.5,<24.0" -flake8-commas = ">=2.0,<3.0" -flake8-comprehensions = ">=3.1,<4.0" -flake8-debugger = ">=4.0,<5.0" -flake8-docstrings = ">=1.3,<2.0" -flake8-eradicate = ">=1.5,<2.0" -flake8-isort = ">=6.0,<7.0" -flake8-quotes = ">=3.0,<4.0" -flake8-rst-docstrings = ">=0.3,<0.4" -flake8-string-format = ">=0.3,<0.4" -pep8-naming = ">=0.13,<0.14" -pygments = ">=2.4,<3.0" -setuptools = "*" -typing_extensions = ">=4.0,<5.0" - -[[package]] -name = "zipp" -version = "3.17.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = false -python-versions = ">=3.8" -files = [ - {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, - {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] - -[metadata] -lock-version = "2.0" -python-versions = "^3.9" -content-hash = "b725c780b419b14540a1d4801f1849230d4e8a1b51a9381e36ff476eb8ab598c" diff --git a/Industrial_developed_hangman/pyproject.toml b/Industrial_developed_hangman/pyproject.toml deleted file mode 100644 index b70606ab82f..00000000000 --- a/Industrial_developed_hangman/pyproject.toml +++ /dev/null @@ -1,35 +0,0 @@ -[tool.poetry] -name = "Hangman" -version = "0.2.0" -description = "" -authors = ["DiodDan "] -readme = "README.md" -packages = [{include = "hangman", from = "src"}] - -[tool.poetry.dependencies] -python = "^3.9" -requests = "2.31.0" -colorama = "0.4.6" -beautifulsoup4 = "4.12" - - -[tool.poetry.group.dev.dependencies] -mypy = "1.5.1" -wemake-python-styleguide = "0.18.0" -isort = "5.12.0" -pytest = "7.4.2" -pytest-cov = "4.1.0" -pytest-timeout = "2.2.0" -pytest-randomly = "3.15.0" -requests-mock = "1.11.0" -pytest-freezer = "0.4.8" -types-requests = " 2.31.0.2" - -[build-system] -requires = ["poetry-core", "colorama", "bs4", "requests"] -build-backend = "poetry.core.masonry.api" - -[tool.isort] -line_length = 80 -multi_line_output = 3 -include_trailing_comma = true diff --git a/Industrial_developed_hangman/pytest.ini b/Industrial_developed_hangman/pytest.ini deleted file mode 100644 index f51da414608..00000000000 --- a/Industrial_developed_hangman/pytest.ini +++ /dev/null @@ -1,5 +0,0 @@ -[pytest] -markers = - internet_required: marks tests that requires internet connection (deselect with '-m "not internet_required"') - serial -timeout = 20 diff --git a/Industrial_developed_hangman/setup.cfg b/Industrial_developed_hangman/setup.cfg deleted file mode 100644 index f57029a0492..00000000000 --- a/Industrial_developed_hangman/setup.cfg +++ /dev/null @@ -1,48 +0,0 @@ -[flake8] -max-line-length = 120 -docstring_style = sphinx -max-arguments = 6 -exps-for-one-empty-line = 0 -ignore = - D100, - D104, - -per-file-ignores = - tests/*: - # Missing docstring in public class - D101, - # Missing docstring in public method - D102, - # Missing docstring in public function - D103, - # Missing docstring in magic method - D105, - # Missing docstring in __init__ - D107, - # Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. - S101, - # Found magic number - WPS432, - # Found wrong keyword: pass - WPS420, - # Found incorrect node inside `class` body - WPS604, - # Found outer scope names shadowing: message_update - WPS442, - # Found comparison with float or complex number - WPS459, - # split between test action and assert - WPS473, - # Found compare with falsy constant - WPS520, - # Found string literal over-use - WPS226 - # Found overused expression - WPS204 - # Found too many module members - WPS202 - -[mypy] -ignore_missing_imports = True -check_untyped_defs = True -disallow_untyped_calls = True diff --git a/Industrial_developed_hangman/src/hangman/main.py b/Industrial_developed_hangman/src/hangman/main.py index b2a7e780ac3..4e35460b004 100644 --- a/Industrial_developed_hangman/src/hangman/main.py +++ b/Industrial_developed_hangman/src/hangman/main.py @@ -1,25 +1,25 @@ import json import random import time +from collections.abc import Callable from enum import Enum from pathlib import Path -from typing import Callable, List -import requests +import httpx from colorama import Fore, Style DEBUG = False success_code = 200 request_timeout = 1000 -data_path = Path(__file__).parent.parent.parent / 'Data' +data_path = Path(__file__).parent.parent.parent / "Data" year = 4800566455 class Source(Enum): """Enum that represents switch between local and web word parsing.""" - FROM_FILE = 0 # noqa: WPS115 - FROM_INTERNET = 1 # noqa: WPS115 + FROM_FILE = 0 + FROM_INTERNET = 1 def print_wrong(text: str, print_function: Callable[[str], None]) -> None: @@ -43,8 +43,9 @@ def print_right(text: str, print_function: Callable[[str], None]) -> None: print_function(Style.RESET_ALL + Fore.GREEN + text) -def parse_word_from_local(choice_function: Callable[[List[str]], str] = random.choice) -> str: - # noqa: DAR201 +def parse_word_from_local( + choice_function: Callable[[list[str]], str] = random.choice, +) -> str: """ Parse word from local file. @@ -53,14 +54,15 @@ def parse_word_from_local(choice_function: Callable[[List[str]], str] = random.c :raises FileNotFoundError: file to read words not found. """ try: - with open(data_path / 'local_words.txt', encoding='utf8') as words_file: - return choice_function(words_file.read().split('\n')) + with open(data_path / "local_words.txt", encoding="utf8") as words_file: + return choice_function(words_file.read().split("\n")) except FileNotFoundError: - raise FileNotFoundError('File local_words.txt was not found') + raise FileNotFoundError("File local_words.txt was not found") -def parse_word_from_site(url: str = 'https://random-word-api.herokuapp.com/word') -> str: - # noqa: DAR201 +def parse_word_from_site( + url: str = "https://random-word-api.herokuapp.com/word", +) -> str: """ Parse word from website. @@ -70,18 +72,20 @@ def parse_word_from_site(url: str = 'https://random-word-api.herokuapp.com/word' :raises RuntimeError: something go wrong with getting the word from site. """ try: - response: requests.Response = requests.get(url, timeout=request_timeout) - except ConnectionError: - raise ConnectionError('There is no connection to the internet') + response: httpx.Response = httpx.get(url, timeout=request_timeout) + except httpx.ConnectError: + raise ConnectionError("There is no connection to the internet") if response.status_code == success_code: return json.loads(response.content.decode())[0] - raise RuntimeError('Something go wrong with getting the word from site') + raise RuntimeError("Something go wrong with getting the word from site") -class MainProcess(object): +class MainProcess: """Manages game process.""" - def __init__(self, source: Enum, pr_func: Callable, in_func: Callable, ch_func: Callable) -> None: + def __init__( + self, source: Enum, pr_func: Callable, in_func: Callable, ch_func: Callable + ) -> None: """ Init MainProcess object. @@ -91,15 +95,14 @@ def __init__(self, source: Enum, pr_func: Callable, in_func: Callable, ch_func: :parameter ch_func: Function that will be used to choice word. """ self._source = source - self._answer_word = '' - self._word_string_to_show = '' + self._answer_word = "" + self._word_string_to_show = "" self._guess_attempts_coefficient = 2 self._print_function = pr_func self._input_function = in_func self._choice_function = ch_func def get_word(self) -> str: - # noqa: DAR201 """ Parse word(wrapper for local and web parse). @@ -110,18 +113,19 @@ def get_word(self) -> str: return parse_word_from_site() elif self._source == Source.FROM_FILE: return parse_word_from_local(self._choice_function) - raise AttributeError('Non existing enum') + raise AttributeError("Non existing enum") def user_lose(self) -> None: """Print text for end of game and exits.""" - print_wrong(f"YOU LOST(the word was '{self._answer_word}')", self._print_function) # noqa:WPS305 + print_wrong( + f"YOU LOST(the word was '{self._answer_word}')", self._print_function + ) def user_win(self) -> None: """Print text for end of game and exits.""" - print_wrong(f'{self._word_string_to_show} YOU WON', self._print_function) # noqa:WPS305 + print_wrong(f"{self._word_string_to_show} YOU WON", self._print_function) def game_process(self, user_character: str) -> bool: - # noqa: DAR201 """ Process user input. @@ -133,9 +137,9 @@ def game_process(self, user_character: str) -> bool: for index, character in enumerate(self._answer_word): if character == user_character: word_list_to_show[index] = user_character - self._word_string_to_show = ''.join(word_list_to_show) + self._word_string_to_show = "".join(word_list_to_show) else: - print_wrong('There is no such character in word', self._print_function) + print_wrong("There is no such character in word", self._print_function) if self._answer_word == self._word_string_to_show: self.user_win() return True @@ -144,26 +148,32 @@ def game_process(self, user_character: str) -> bool: def start_game(self) -> None: """Start main process of the game.""" if time.time() > year: - print_right('this program is more then 100years age', self._print_function) - with open(data_path / 'text_images.txt', encoding='utf8') as text_images_file: + print_right("this program is more then 100years age", self._print_function) + with open(data_path / "text_images.txt", encoding="utf8") as text_images_file: print_wrong(text_images_file.read(), self._print_function) - print_wrong('Start guessing...', self._print_function) + print_wrong("Start guessing...", self._print_function) self._answer_word = self.get_word() - self._word_string_to_show = '_' * len(self._answer_word) + self._word_string_to_show = "_" * len(self._answer_word) attempts_amount = int(self._guess_attempts_coefficient * len(self._answer_word)) if DEBUG: print_right(self._answer_word, self._print_function) for attempts in range(attempts_amount): user_remaining_attempts = attempts_amount - attempts - print_right(f'You have {user_remaining_attempts} more attempts', self._print_function) # noqa:WPS305 - print_right(f'{self._word_string_to_show} enter character to guess: ', self._print_function) # noqa:WPS305 + print_right( + f"You have {user_remaining_attempts} more attempts", + self._print_function, + ) + print_right( + f"{self._word_string_to_show} enter character to guess: ", + self._print_function, + ) user_character = self._input_function().lower() if self.game_process(user_character): break - if '_' in self._word_string_to_show: + if "_" in self._word_string_to_show: self.user_lose() -if __name__ == '__main__': +if __name__ == "__main__": main_process = MainProcess(Source(1), print, input, random.choice) main_process.start_game() diff --git a/Industrial_developed_hangman/tests/test_hangman/test_main.py b/Industrial_developed_hangman/tests/test_hangman/test_main.py index 46d0b1d6f0e..b78cb5d1b2c 100644 --- a/Industrial_developed_hangman/tests/test_hangman/test_main.py +++ b/Industrial_developed_hangman/tests/test_hangman/test_main.py @@ -1,10 +1,9 @@ import os +from collections.abc import Callable from pathlib import Path -from typing import Callable, List import pytest import requests_mock - from src.hangman.main import ( MainProcess, Source, @@ -13,17 +12,17 @@ ) -class FkPrint(object): +class FkPrint: def __init__(self) -> None: - self.container: List[str] = [] + self.container: list[str] = [] def __call__(self, value_to_print: str) -> None: self.container.append(str(value_to_print)) -class FkInput(object): - def __init__(self, values_to_input: List[str]) -> None: - self.values_to_input: List[str] = values_to_input +class FkInput: + def __init__(self, values_to_input: list[str]) -> None: + self.values_to_input: list[str] = values_to_input def __call__(self) -> str: return self.values_to_input.pop(0) @@ -31,7 +30,7 @@ def __call__(self) -> str: @pytest.fixture def choice_fn() -> Callable: - return lambda array: array[0] # noqa: E731 + return lambda array: array[0] def test_parse_word_from_local() -> None: @@ -39,9 +38,9 @@ def test_parse_word_from_local() -> None: def test_parse_word_from_local_error() -> None: - data_path = Path(os.path.abspath('')) / 'Data' - real_name = 'local_words.txt' - time_name = 'local_words_not_exist.txt' + data_path = Path(os.path.abspath("")) / "Data" + real_name = "local_words.txt" + time_name = "local_words_not_exist.txt" os.rename(data_path / real_name, data_path / time_name) with pytest.raises(FileNotFoundError): @@ -56,50 +55,60 @@ def test_parse_word_from_site() -> None: def test_parse_word_from_site_no_internet() -> None: with requests_mock.Mocker() as mock: - mock.get('https://random-word-api.herokuapp.com/word', text='["some text"]') - assert parse_word_from_site() == 'some text' + mock.get("https://random-word-api.herokuapp.com/word", text='["some text"]') + assert parse_word_from_site() == "some text" def test_parse_word_from_site_err() -> None: with pytest.raises(RuntimeError): - parse_word_from_site(url='https://www.google.com/dsfsdfds/sdfsdf/sdfds') + parse_word_from_site(url="https://www.google.com/dsfsdfds/sdfsdf/sdfds") def test_get_word(choice_fn: Callable) -> None: fk_print = FkPrint() - fk_input = FkInput(['none']) - main_process = MainProcess(Source(1), pr_func=fk_print, in_func=fk_input, ch_func=choice_fn) + fk_input = FkInput(["none"]) + main_process = MainProcess( + Source(1), pr_func=fk_print, in_func=fk_input, ch_func=choice_fn + ) assert isinstance(main_process.get_word(), str) def test_start_game_win(choice_fn: Callable) -> None: fk_print = FkPrint() - fk_input = FkInput(['j', 'a', 'm']) - main_process = MainProcess(Source(0), pr_func=fk_print, in_func=fk_input, ch_func=choice_fn) + fk_input = FkInput(["j", "a", "m"]) + main_process = MainProcess( + Source(0), pr_func=fk_print, in_func=fk_input, ch_func=choice_fn + ) main_process.start_game() - assert 'YOU WON' in fk_print.container[-1] + assert "YOU WON" in fk_print.container[-1] -@pytest.mark.parametrize('input_str', [[letter] * 10 for letter in 'qwertyuiopasdfghjklzxcvbnm']) # noqa: WPS435 -def test_start_game_loose(input_str: List[str], choice_fn: Callable) -> None: +@pytest.mark.parametrize( + "input_str", [[letter] * 10 for letter in "qwertyuiopasdfghjklzxcvbnm"] +) +def test_start_game_loose(input_str: list[str], choice_fn: Callable) -> None: fk_print = FkPrint() fk_input = FkInput(input_str) - main_process = MainProcess(Source(0), pr_func=fk_print, in_func=fk_input, ch_func=choice_fn) + main_process = MainProcess( + Source(0), pr_func=fk_print, in_func=fk_input, ch_func=choice_fn + ) main_process.start_game() - assert 'YOU LOST' in fk_print.container[-1] + assert "YOU LOST" in fk_print.container[-1] def test_wow_year(freezer, choice_fn: Callable) -> None: - freezer.move_to('2135-10-17') + freezer.move_to("2135-10-17") fk_print = FkPrint() - fk_input = FkInput(['none'] * 100) # noqa: WPS435 - main_process = MainProcess(Source(0), pr_func=fk_print, in_func=fk_input, ch_func=choice_fn) + fk_input = FkInput(["none"] * 100) + main_process = MainProcess( + Source(0), pr_func=fk_print, in_func=fk_input, ch_func=choice_fn + ) main_process.start_game() - assert 'this program' in fk_print.container[0] + assert "this program" in fk_print.container[0] diff --git a/Infix_to_Postfix.py b/Infix_to_Postfix.py index bdffa82e63c..597cd35cef3 100644 --- a/Infix_to_Postfix.py +++ b/Infix_to_Postfix.py @@ -2,7 +2,6 @@ # Class to convert the expression class Conversion: - # Constructor to initialize the class variables def __init__(self, capacity): self.top = -1 @@ -52,7 +51,6 @@ def notGreater(self, i): # The main function that converts given infix expression # to postfix expression def infixToPostfix(self, exp): - # Iterate over the expression for conversion for i in exp: # If the character is an operand, diff --git a/JARVIS/JARVIS_2.0.py b/JARVIS/JARVIS_2.0.py index 65600a1bc75..800b6901b5a 100644 --- a/JARVIS/JARVIS_2.0.py +++ b/JARVIS/JARVIS_2.0.py @@ -10,41 +10,42 @@ # import modules import datetime # datetime module supplies classes for manipulating dates and times +import json + +# master +# auto install for pyttsx3 and speechRecognition +import os import subprocess # subprocess module allows you to spawn new processes # master -import pyjokes # for generating random jokes +import pyjokes # for generating random jokes import requests -import json -from PIL import ImageGrab from gtts import gTTS +from PIL import ImageGrab + +# ======= +from playsound import * # for sound output # for 30 seconds clip "Jarvis, clip that!" and discord ctrl+k quick-move (might not come to fruition) from pynput import keyboard from pynput.keyboard import Key from pynput.mouse import Controller -# ======= -from playsound import * # for sound output - -# master -# auto install for pyttsx3 and speechRecognition -import os try: - import pyttsx3 #Check if already installed -except:# If not installed give exception - os.system('pip install pyttsx3')#install at run time - import pyttsx3 #import again for speak function + import pyttsx3 # Check if already installed +except: # If not installed give exception + os.system("pip install pyttsx3") # install at run time + import pyttsx3 # import again for speak function -try : +try: import speech_recognition as sr except: - os.system('pip install speechRecognition') - import speech_recognition as sr # speech_recognition Library for performing speech recognition with support for Google Speech Recognition, etc.. + os.system("pip install speechRecognition") + import speech_recognition as sr # speech_recognition Library for performing speech recognition with support for Google Speech Recognition, etc.. # importing the pyttsx3 library -import webbrowser import smtplib +import webbrowser # initialisation engine = pyttsx3.init() @@ -82,25 +83,33 @@ def sendEmail(to, content): server.sendmail("youremail@gmail.com", to, content) server.close() + +import base64 + import openai -import base64 -stab=(base64.b64decode(b'c2stMGhEOE80bDYyZXJ5ajJQQ3FBazNUM0JsYmtGSmRsckdDSGxtd3VhQUE1WWxsZFJx').decode("utf-8")) + +stab = base64.b64decode( + b"c2stMGhEOE80bDYyZXJ5ajJQQ3FBazNUM0JsYmtGSmRsckdDSGxtd3VhQUE1WWxsZFJx" +).decode("utf-8") api_key = stab + + def ask_gpt3(que): openai.api_key = api_key response = openai.Completion.create( - engine="text-davinci-002", + engine="text-davinci-002", prompt=f"Answer the following question: {question}\n", - max_tokens=150, - n = 1, - stop=None, - temperature=0.7 + max_tokens=150, + n=1, + stop=None, + temperature=0.7, ) answer = response.choices[0].text.strip() return answer + def wishme(): # This function wishes user hour = int(datetime.datetime.now().hour) @@ -159,7 +168,7 @@ def on_press(key): # Run Application with Voice Command Function # only_jarvis def on_release(key): - print("{0} release".format(key)) + print(f"{key} release") if key == Key.esc(): # Stop listener return False @@ -249,9 +258,9 @@ def get_app(Q): elif Q == "open github": webbrowser.open("https://github.com/") elif Q == "search for": - que=Q.lstrip("search for") + que = Q.lstrip("search for") answer = ask_gpt3(que) - + elif ( Q == "email to other" ): # here you want to change and input your mail and password whenver you implement @@ -312,7 +321,7 @@ def get_app(Q): "paint": "mspaint.exe", "cmd": "cmd.exe", "browser": "C:\\Program Files\Internet Explorer\iexplore.exe", - "vscode": "C:\\Users\\Users\\User\\AppData\\Local\\Programs\Microsoft VS Code" + "vscode": "C:\\Users\\Users\\User\\AppData\\Local\\Programs\Microsoft VS Code", } # master diff --git a/JARVIS/requirements.txt b/JARVIS/requirements.txt deleted file mode 100644 index ca6bbccddbd..00000000000 --- a/JARVIS/requirements.txt +++ /dev/null @@ -1,13 +0,0 @@ -datetime -pyjokes -requests -Pillow -Image -ImageGrab -gTTS -keyboard -key -playsound -pyttsx3 -SpeechRecognition -openai \ No newline at end of file diff --git a/Job_scheduling.py b/Job_scheduling.py index 6ac96c24abd..caee13c416b 100644 --- a/Job_scheduling.py +++ b/Job_scheduling.py @@ -4,18 +4,18 @@ Author : Mohit Kumar Job Sequencing Problem implemented in python """ + from collections import namedtuple -from typing import List class Scheduling: - def __init__(self, jobs: List[int]) -> None: + def __init__(self, jobs: list[int]) -> None: """ Assign jobs as instance of class Scheduling """ self.jobs = jobs - def schedule(self, total_jobs: int, deadline: List[int]) -> List[int]: + def schedule(self, total_jobs: int, deadline: list[int]) -> list[int]: """ Parameteres : total_jobs and list of deadline of jobs Returns : List of jobs_id which are profitable and can be done before @@ -38,7 +38,7 @@ def schedule(self, total_jobs: int, deadline: List[int]) -> List[int]: return self.j - def feasible(self, profit_jobs: List[int], deadline: List[int]) -> bool: + def feasible(self, profit_jobs: list[int], deadline: list[int]) -> bool: """ Parameters : list of current profitable jobs within deadline list of deadline of jobs diff --git a/JustDialScrapperGUI/Justdial Scrapper GUI.py b/JustDialScrapperGUI/Justdial Scrapper GUI.py index 2dd4803f0bb..b9c020b6955 100644 --- a/JustDialScrapperGUI/Justdial Scrapper GUI.py +++ b/JustDialScrapperGUI/Justdial Scrapper GUI.py @@ -55,7 +55,7 @@ def get_phone_number(self, body): for element in item.find_all(class_=True): classes = [] classes.extend(element["class"]) - phone_no += str((self.which_digit(classes[1]))) + phone_no += str(self.which_digit(classes[1])) except Exception: pass except Exception: @@ -106,10 +106,10 @@ def start_scrapping_logic(self): page_number = 1 service_count = 1 - total_url = "https://www.justdial.com/{0}/{1}".format(self.location, self.query) + total_url = f"https://www.justdial.com/{self.location}/{self.query}" fields = ["Name", "Phone", "Rating", "Rating Count", "Address", "Location"] - out_file = open("{0}.csv".format(self.file_name), "w") + out_file = open(f"{self.file_name}.csv", "w") csvwriter = csv.DictWriter(out_file, delimiter=",", fieldnames=fields) csvwriter.writerow( { @@ -140,6 +140,7 @@ def start_scrapping_logic(self): req = urllib.request.Request( url, headers={"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64)"} ) + page = urllib.request.urlopen(req) soup = BeautifulSoup(page.read(), "html.parser") diff --git a/Key_Binding/key_binding.py b/Key_Binding/key_binding.py index dfd448497b1..3cedfe512d7 100644 --- a/Key_Binding/key_binding.py +++ b/Key_Binding/key_binding.py @@ -3,8 +3,10 @@ session = Prompt() + @bind.add("ctrl-h") def _(event): print("Hello, World") + session.prompt("") diff --git a/Key_Binding/requirement.txt b/Key_Binding/requirement.txt deleted file mode 100644 index 51d89fc61fc..00000000000 --- a/Key_Binding/requirement.txt +++ /dev/null @@ -1 +0,0 @@ -quo>=2022.4 diff --git a/Kilometerstomile.py b/Kilometerstomile.py index 2a4d33c8ff2..fc7b32304c8 100644 --- a/Kilometerstomile.py +++ b/Kilometerstomile.py @@ -6,4 +6,4 @@ # calculate miles miles = kilometers * conv_fac -print(f'{kilometers:.2f} kilometers is equal to {miles:.2f} miles') +print(f"{kilometers:.2f} kilometers is equal to {miles:.2f} miles") diff --git a/LETTER GUESSER.py b/LETTER GUESSER.py index 03f7290c7b4..0751ed25542 100644 --- a/LETTER GUESSER.py +++ b/LETTER GUESSER.py @@ -14,19 +14,19 @@ failed = 10 while failed > 0: - if userInput == compChosse: - print("---------->") - print("You are correct!") - print("---------->") - print("Your guesses: " + str(10 - failed)) - break - - elif userInput != compChosse: - failed = failed - 1 - - print(":no your wrong: " + "left: " + str(failed)) - - userInput = input("guess:") - - if failed == 0: - print("out of guesses") + if userInput == compChosse: + print("---------->") + print("You are correct!") + print("---------->") + print("Your guesses: " + str(10 - failed)) + break + + elif userInput != compChosse: + failed = failed - 1 + + print(":no your wrong: " + "left: " + str(failed)) + + userInput = input("guess:") + + if failed == 0: + print("out of guesses") diff --git a/Laundary System/code.py b/Laundary System/code.py index 1c71e5a365b..96817e49f7b 100644 --- a/Laundary System/code.py +++ b/Laundary System/code.py @@ -1,75 +1,83 @@ -id=1 -class LaundryService: - def __init__(self,Name_of_customer,Contact_of_customer,Email,Type_of_cloth,Branded,Season,id): - self.Name_of_customer=Name_of_customer - self.Contact_of_customer=Contact_of_customer - self.Email=Email - self.Type_of_cloth=Type_of_cloth - self.Branded=Branded - self.Season=Season - self.id=id +id = 1 - def customerDetails(self): - print("The Specific Details of customer:") - print("customer ID: ",self.id) - print("customer name:", self.Name_of_customer) - print("customer contact no. :", self.Contact_of_customer) - print("customer email:", self.Email) - print("type of cloth", self.Type_of_cloth) - if self.Branded == 1: - a=True - else: - a=False - print("Branded", a) - def calculateCharge(self): - a=0 - if self.Type_of_cloth=="Cotton": - a=50.0 - elif self.Type_of_cloth=="Silk": - a=30.0 - elif self.Type_of_cloth=="Woolen": - a=90.0 - elif self.Type_of_cloth=="Polyester": - a=20.0 - if self.Branded==1: - a=1.5*(a) - else: - pass - if self.Season=="Winter": - a=0.5*a - else: - a=2*a - print(a) - return a - def finalDetails(self): - self.customerDetails() - print("Final charge:",end="") - if self.calculateCharge() >200: - print("to be return in 4 days") - else: - print("to be return in 7 days") -while True: - name=input("Enter the name: ") - contact=int(input("Enter the contact: ")) - email=input("Enter the email: ") - cloth=input("Enter the type of cloth: ") - brand=bool(input("Branded ? ")) - season=input("Enter the season: ") - obj=LaundryService(name,contact,email,cloth,brand,season,id) - obj.finalDetails() - id=id+1 - z=input("Do you want to continue(Y/N):") - if z=="Y": - continue - elif z =="N": - print("Thanks for visiting!") - break - else: - print("Select valid option") +class LaundryService: + def __init__( + self, + Name_of_customer, + Contact_of_customer, + Email, + Type_of_cloth, + Branded, + Season, + id, + ): + self.Name_of_customer = Name_of_customer + self.Contact_of_customer = Contact_of_customer + self.Email = Email + self.Type_of_cloth = Type_of_cloth + self.Branded = Branded + self.Season = Season + self.id = id + def customerDetails(self): + print("The Specific Details of customer:") + print("customer ID: ", self.id) + print("customer name:", self.Name_of_customer) + print("customer contact no. :", self.Contact_of_customer) + print("customer email:", self.Email) + print("type of cloth", self.Type_of_cloth) + if self.Branded == 1: + a = True + else: + a = False + print("Branded", a) + def calculateCharge(self): + a = 0 + if self.Type_of_cloth == "Cotton": + a = 50.0 + elif self.Type_of_cloth == "Silk": + a = 30.0 + elif self.Type_of_cloth == "Woolen": + a = 90.0 + elif self.Type_of_cloth == "Polyester": + a = 20.0 + if self.Branded == 1: + a = 1.5 * (a) + else: + pass + if self.Season == "Winter": + a = 0.5 * a + else: + a = 2 * a + print(a) + return a + def finalDetails(self): + self.customerDetails() + print("Final charge:", end="") + if self.calculateCharge() > 200: + print("to be return in 4 days") + else: + print("to be return in 7 days") - \ No newline at end of file +while True: + name = input("Enter the name: ") + contact = int(input("Enter the contact: ")) + email = input("Enter the email: ") + cloth = input("Enter the type of cloth: ") + brand = bool(input("Branded ? ")) + season = input("Enter the season: ") + obj = LaundryService(name, contact, email, cloth, brand, season, id) + obj.finalDetails() + id = id + 1 + z = input("Do you want to continue(Y/N):") + if z == "Y": + continue + elif z == "N": + print("Thanks for visiting!") + break + else: + print("Select valid option") diff --git a/LinkedLists all Types/circular_linked_list.py b/LinkedLists all Types/circular_linked_list.py index 1bba861dc8b..426f99750a6 100644 --- a/LinkedLists all Types/circular_linked_list.py +++ b/LinkedLists all Types/circular_linked_list.py @@ -1,17 +1,19 @@ -'''Author - Mugen https://github.com/Mugendesu''' +"""Author - Mugen https://github.com/Mugendesu""" -class Node : - def __init__(self , data , next = None): + +class Node: + def __init__(self, data, next=None): self.data = data self.next = next -class CircularLinkedList : + +class CircularLinkedList: def __init__(self): self.head = self.tail = None self.length = 0 - - def insert_at_beginning(self , data): - node = Node(data , self.head) + + def insert_at_beginning(self, data): + node = Node(data, self.head) if self.head is None: self.head = self.tail = node node.next = node @@ -20,9 +22,9 @@ def insert_at_beginning(self , data): self.head = node self.tail.next = node self.length += 1 - - def insert_at_end(self , data): - node = Node(data , self.head) + + def insert_at_end(self, data): + node = Node(data, self.head) if self.head is None: self.head = self.tail = node node.next = node @@ -31,21 +33,21 @@ def insert_at_end(self , data): self.tail.next = node self.tail = node self.length += 1 - + def len(self): return self.length - + def pop_at_beginning(self): if self.head is None: - print('List is Empty!') + print("List is Empty!") return self.head = self.head.next self.tail.next = self.head - self.length -= 1 - + self.length -= 1 + def pop_at_end(self): if self.head is None: - print('List is Empty!') + print("List is Empty!") return temp = self.head while temp: @@ -54,50 +56,50 @@ def pop_at_end(self): self.tail = temp temp.next = self.head self.length -= 1 - return + return temp = temp.next - - def insert_values(self , arr : list): + + def insert_values(self, arr: list): self.head = self.tail = None self.length = 0 for i in arr: self.insert_at_end(i) - + def print(self): if self.head is None: - print('The List is Empty!') + print("The List is Empty!") return temp = self.head.next - print(f'{self.head.data} ->' , end=' ') + print(f"{self.head.data} ->", end=" ") while temp != self.head: - print(f'{temp.data} ->' , end=' ') + print(f"{temp.data} ->", end=" ") temp = temp.next - print(f'{self.tail.next.data}') - - def insert_at(self , idx , data): + print(f"{self.tail.next.data}") + + def insert_at(self, idx, data): if idx == 0: self.insert_at_beginning(data) return elif idx == self.length: self.insert_at_end(data) return - elif 0 > idx or idx > self.length: - raise Exception('Invalid Position') + elif idx < 0 or idx > self.length: + raise Exception("Invalid Position") return pos = 0 temp = self.head while temp: if pos == idx - 1: - node = Node(data , temp.next) + node = Node(data, temp.next) temp.next = node self.length += 1 return pos += 1 - temp = temp.next - - def remove_at(self , idx): - if 0 > idx or idx >= self.length: - raise Exception('Invalid Position') + temp = temp.next + + def remove_at(self, idx): + if idx < 0 or idx >= self.length: + raise Exception("Invalid Position") elif idx == 0: self.pop_at_beginning() return @@ -112,22 +114,22 @@ def remove_at(self , idx): self.length -= 1 return pos += 1 - temp = temp.next - + temp = temp.next + + def main(): ll = CircularLinkedList() - ll.insert_at_end(1) - ll.insert_at_end(4) - ll.insert_at_end(3) + ll.insert_at_end(1) + ll.insert_at_end(4) + ll.insert_at_end(3) ll.insert_at_beginning(2) - ll.insert_values([1 , 2, 3 ,4 ,5 ,6,53,3]) - # ll.pop_at_end() - ll.insert_at(8, 7) - # ll.remove_at(2) + ll.insert_values([1, 2, 3, 4, 5, 6, 53, 3]) + # ll.pop_at_end() + ll.insert_at(8, 7) + # ll.remove_at(2) ll.print() - print(f'{ll.len() = }') - + print(f"{ll.len() = }") -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/LinkedLists all Types/doubly_linked_list.py b/LinkedLists all Types/doubly_linked_list.py index 8ca7a2f87fa..ed451dc58cd 100644 --- a/LinkedLists all Types/doubly_linked_list.py +++ b/LinkedLists all Types/doubly_linked_list.py @@ -1,34 +1,36 @@ -'''Contains Most of the Doubly Linked List functions.\n +"""Contains Most of the Doubly Linked List functions.\n 'variable_name' = doubly_linked_list.DoublyLinkedList() to use this an external module.\n 'variable_name'.insert_front('element') \t,'variable_name'.insert_back('element'),\n 'variable_name'.pop_front() are some of its functions.\n To print all of its Functions use print('variable_name'.__dir__()).\n Note:- 'variable_name' = doubly_linked_list.DoublyLinkedList() This line is Important before using any of the function. -Author :- Mugen https://github.com/Mugendesu -''' +Author :- Mugen https://github.com/Mugendesu +""" + + class Node: - def __init__(self, val=None , next = None , prev = None): + def __init__(self, val=None, next=None, prev=None): self.data = val self.next = next self.prev = prev + class DoublyLinkedList: - def __init__(self): self.head = self.tail = None - self.length = 0 + self.length = 0 - def insert_front(self , data): - node = Node(data , self.head) + def insert_front(self, data): + node = Node(data, self.head) if self.head == None: self.tail = node node.prev = self.head self.head = node self.length += 1 - - def insert_back(self , data): - node = Node(data ,None, self.tail) + + def insert_back(self, data): + node = Node(data, None, self.tail) if self.head == None: self.tail = self.head = node self.length += 1 @@ -36,49 +38,49 @@ def insert_back(self , data): self.tail.next = node self.tail = node self.length += 1 - - def insert_values(self , data_values : list): + + def insert_values(self, data_values: list): self.head = self.tail = None self.length = 0 for data in data_values: self.insert_back(data) - + def pop_front(self): if not self.head: - print('List is Empty!') + print("List is Empty!") return - + self.head = self.head.next self.head.prev = None self.length -= 1 - + def pop_back(self): if not self.head: - print('List is Empty!') + print("List is Empty!") return - + temp = self.tail self.tail = temp.prev temp.prev = self.tail.next = None self.length -= 1 - - def print(self): + + def print(self): if self.head is None: - print('Linked List is Empty!') + print("Linked List is Empty!") return temp = self.head - print('NULL <-' , end=' ') + print("NULL <-", end=" ") while temp: if temp.next == None: - print(f'{temp.data} ->' , end = ' ') + print(f"{temp.data} ->", end=" ") break - print(f'{temp.data} <=>' , end = ' ') + print(f"{temp.data} <=>", end=" ") temp = temp.next - print('NULL') - + print("NULL") + def len(self): - return self.length # O(1) length calculation + return self.length # O(1) length calculation # if self.head is None: # return 0 # count = 0 @@ -87,28 +89,28 @@ def len(self): # count += 1 # temp = temp.next # return count - - def remove_at(self , idx): + + def remove_at(self, idx): if idx < 0 or self.len() <= idx: - raise Exception('Invalid Position') + raise Exception("Invalid Position") if idx == 0: self.pop_front() return - elif idx == self.length -1: + elif idx == self.length - 1: self.pop_back() - return + return temp = self.head dist = 0 - while dist != idx-1: + while dist != idx - 1: dist += 1 temp = temp.next temp.next = temp.next.next temp.next.prev = temp.next.prev.prev self.length -= 1 - - def insert_at(self , idx : int , data ): + + def insert_at(self, idx: int, data): if idx < 0 or self.len() < idx: - raise Exception('Invalid Position') + raise Exception("Invalid Position") if idx == 0: self.insert_front(data) return @@ -117,32 +119,32 @@ def insert_at(self , idx : int , data ): return temp = self.head dist = 0 - while dist != idx-1: + while dist != idx - 1: dist += 1 temp = temp.next - node = Node(data , temp.next , temp) + node = Node(data, temp.next, temp) temp.next = node self.length += 1 - - def insert_after_value(self , idx_data , data): - if not self.head : # For Empty List case - print('List is Empty!') + + def insert_after_value(self, idx_data, data): + if not self.head: # For Empty List case + print("List is Empty!") return - - if self.head.data == idx_data: # To insert after the Head Element - self.insert_at(1 , data) + + if self.head.data == idx_data: # To insert after the Head Element + self.insert_at(1, data) return temp = self.head while temp: if temp.data == idx_data: - node = Node(data , temp.next , temp) + node = Node(data, temp.next, temp) temp.next = node self.length += 1 return temp = temp.next - print('The Element is not in the List!') - - def remove_by_value(self , idx_data): + print("The Element is not in the List!") + + def remove_by_value(self, idx_data): temp = self.head if temp.data == idx_data: self.pop_front() @@ -160,23 +162,24 @@ def remove_by_value(self , idx_data): temp = temp.next print("The Element is not the List!") - def index(self , data): - '''Returns the index of the Element''' - if not self.head : - print('List is Empty!') + def index(self, data): + """Returns the index of the Element""" + if not self.head: + print("List is Empty!") return idx = 0 temp = self.head while temp: - if temp.data == data: return idx + if temp.data == data: + return idx temp = temp.next idx += 1 - print('The Element is not in the List!') + print("The Element is not in the List!") - def search(self , idx): - '''Returns the Element at the Given Index''' + def search(self, idx): + """Returns the Element at the Given Index""" if self.len() == 0 or idx >= self.len(): - raise Exception('Invalid Position') + raise Exception("Invalid Position") return temp = self.head curr_idx = 0 @@ -185,10 +188,10 @@ def search(self , idx): return temp.data temp = temp.next curr_idx += 1 - + def reverse(self): if not self.head: - print('The List is Empty!') + print("The List is Empty!") return prev = c_next = None curr = self.head @@ -199,10 +202,10 @@ def reverse(self): curr = c_next self.tail = self.head self.head = prev - + def mid_element(self): if not self.head: - print('List is Empty!') + print("List is Empty!") return slow = self.head.next fast = self.head.next.next @@ -212,34 +215,47 @@ def mid_element(self): return slow.data def __dir__(self): - funcs = ['insert_front', 'insert_back','pop_front','pop_back','print','len','length','remove_at','insert_after_value','index','search','reverse','mid_element','__dir__'] + funcs = [ + "insert_front", + "insert_back", + "pop_front", + "pop_back", + "print", + "len", + "length", + "remove_at", + "insert_after_value", + "index", + "search", + "reverse", + "mid_element", + "__dir__", + ] return funcs + def main(): - ll : Node = DoublyLinkedList() - - ll.insert_front(1) - ll.insert_front(2) + ll: Node = DoublyLinkedList() + + ll.insert_front(1) + ll.insert_front(2) ll.insert_front(3) ll.insert_back(0) - ll.insert_values(['ZeroTwo' , 'Asuna' , 'Tsukasa' , 'Seras']) + ll.insert_values(["ZeroTwo", "Asuna", "Tsukasa", "Seras"]) # ll.remove_at(3) # ll.insert_at(4 , 'Raeliana') # ll.pop_back() - ll.insert_after_value('Asuna' , 'MaoMao') + ll.insert_after_value("Asuna", "MaoMao") # print(ll.search(4)) # ll.remove_by_value('Asuna') # ll.reverse() # print(ll.index('ZeroTwo')) - + ll.print() # print(ll.mid_element()) # print(ll.length) - # print(ll.__dir__()) - - - - - -if __name__ == '__main__': - main() \ No newline at end of file + # print(ll.__dir__()) + + +if __name__ == "__main__": + main() diff --git a/LinkedLists all Types/singly_linked_list.py b/LinkedLists all Types/singly_linked_list.py index abc10d897bd..f1242b29cf8 100644 --- a/LinkedLists all Types/singly_linked_list.py +++ b/LinkedLists all Types/singly_linked_list.py @@ -1,33 +1,34 @@ -'''Contains Most of the Singly Linked List functions.\n +"""Contains Most of the Singly Linked List functions.\n 'variable_name' = singly_linked_list.LinkedList() to use this an external module.\n 'variable_name'.insert_front('element') \t,'variable_name'.insert_back('element'),\n 'variable_name'.pop_front() are some of its functions.\n To print all of its Functions use print('variable_name'.__dir__()).\n Note:- 'variable_name' = singly_linked_list.LinkedList() This line is Important before using any of the function. -Author :- Mugen https://github.com/Mugendesu -''' +Author :- Mugen https://github.com/Mugendesu +""" + class Node: - def __init__(self, val=None , next = None ): + def __init__(self, val=None, next=None): self.data = val self.next = next + class LinkedList: - def __init__(self): self.head = self.tail = None - self.length = 0 + self.length = 0 - def insert_front(self , data): - node = Node(data , self.head) + def insert_front(self, data): + node = Node(data, self.head) if self.head == None: self.tail = node self.head = node self.length += 1 - - def insert_back(self , data): - node = Node(data ) + + def insert_back(self, data): + node = Node(data) if self.head == None: self.tail = self.head = node self.length += 1 @@ -35,48 +36,48 @@ def insert_back(self , data): self.tail.next = node self.tail = node self.length += 1 - - def insert_values(self , data_values : list): + + def insert_values(self, data_values: list): self.head = self.tail = None self.length = 0 for data in data_values: self.insert_back(data) - + def pop_front(self): if not self.head: - print('List is Empty!') + print("List is Empty!") return - + temp = self.head self.head = self.head.next temp.next = None self.length -= 1 - + def pop_back(self): if not self.head: - print('List is Empty!') + print("List is Empty!") return - + temp = self.head while temp.next != self.tail: temp = temp.next self.tail = temp temp.next = None self.length -= 1 - + def print(self): if self.head is None: - print('Linked List is Empty!') + print("Linked List is Empty!") return temp = self.head while temp: - print(f'{temp.data} ->' , end = ' ') + print(f"{temp.data} ->", end=" ") temp = temp.next - print('NULL') - + print("NULL") + def len(self): - return self.length # O(1) length calculation + return self.length # O(1) length calculation # if self.head is None: # return 0 # count = 0 @@ -85,88 +86,89 @@ def len(self): # count += 1 # temp = temp.next # return count - - def remove_at(self , idx): + + def remove_at(self, idx): if idx < 0 or self.len() <= idx: - raise Exception('Invalid Position') + raise Exception("Invalid Position") if idx == 0: self.head = self.head.next self.length -= 1 - return + return temp = self.head dist = 0 - while dist != idx-1: + while dist != idx - 1: dist += 1 temp = temp.next temp.next = temp.next.next self.length -= 1 - - def insert_at(self , idx : int , data ): + + def insert_at(self, idx: int, data): if idx < 0 or self.len() < idx: - raise Exception('Invalid Position') + raise Exception("Invalid Position") if idx == 0: self.insert_front(data) return temp = self.head dist = 0 - while dist != idx-1: + while dist != idx - 1: dist += 1 temp = temp.next - node = Node(data , temp.next) + node = Node(data, temp.next) temp.next = node self.length += 1 - - def insert_after_value(self , idx_data , data): - if not self.head : # For Empty List case - print('List is Empty!') + + def insert_after_value(self, idx_data, data): + if not self.head: # For Empty List case + print("List is Empty!") return - - if self.head.data == idx_data: # To insert after the Head Element - self.insert_at(1 , data) + + if self.head.data == idx_data: # To insert after the Head Element + self.insert_at(1, data) return temp = self.head while temp: if temp.data == idx_data: - node = Node(data , temp.next) + node = Node(data, temp.next) temp.next = node self.length += 1 return temp = temp.next - print('The Element is not in the List!') - - def remove_by_value(self , idx_data): + print("The Element is not in the List!") + + def remove_by_value(self, idx_data): temp = self.head if temp.data == idx_data: self.head = self.head.next - self.length -= 1 + self.length -= 1 temp.next = None return while temp.next != None: if temp.next.data == idx_data: - temp.next = temp.next.next + temp.next = temp.next.next self.length -= 1 return - + temp = temp.next - print('Element is not in the List!') + print("Element is not in the List!") - def index(self , data): - '''Returns the index of the Element''' - if not self.head : - print('List is Empty!') + def index(self, data): + """Returns the index of the Element""" + if not self.head: + print("List is Empty!") return idx = 0 temp = self.head while temp: - if temp.data == data: return idx + if temp.data == data: + return idx temp = temp.next idx += 1 - print('The Element is not in the List!') + print("The Element is not in the List!") - def search(self , idx): - '''Returns the Element at the Given Index''' + def search(self, idx): + """Returns the Element at the Given Index""" if self.len() == 0 or idx >= self.len(): - raise Exception('Invalid Position') + raise Exception("Invalid Position") return temp = self.head curr_idx = 0 @@ -175,10 +177,10 @@ def search(self , idx): return temp.data temp = temp.next curr_idx += 1 - + def reverse(self): if not self.head: - print('The List is Empty!') + print("The List is Empty!") return prev = c_next = None curr = self.head @@ -189,10 +191,10 @@ def reverse(self): curr = c_next self.tail = self.head self.head = prev - + def mid_element(self): if not self.head: - print('List is Empty!') + print("List is Empty!") return slow = self.head.next fast = self.head.next.next @@ -202,14 +204,30 @@ def mid_element(self): return slow.data def __dir__(self): - funcs = ['insert_front', 'insert_back','pop_front','pop_back','print','len','length','remove_at','insert_after_value','index','search','reverse','mid_element','__dir__'] + funcs = [ + "insert_front", + "insert_back", + "pop_front", + "pop_back", + "print", + "len", + "length", + "remove_at", + "insert_after_value", + "index", + "search", + "reverse", + "mid_element", + "__dir__", + ] return funcs - + + def main(): - ll : Node = LinkedList() + ll: Node = LinkedList() - # # ll.insert_front(1) - # # ll.insert_front(2) + # # ll.insert_front(1) + # # ll.insert_front(2) # # ll.insert_front(3) # # ll.insert_back(0) # ll.insert_values(['ZeroTwo' , 'Asuna' , 'Tsukasa' , 'Seras' ]) @@ -220,15 +238,12 @@ def main(): # # print(ll.search(5)) # ll.remove_by_value('Tsukasa') # ll.reverse() - + # ll.print() # print(ll.mid_element()) # print(ll.length) - print(ll.__dir__()) - - - - - -if __name__ == '__main__': + print(ll.__dir__()) + + +if __name__ == "__main__": main() diff --git a/List.py b/List.py index bfc9b223f26..4f93052338c 100644 --- a/List.py +++ b/List.py @@ -1,14 +1,14 @@ List = [] # List is Muteable # means value can be change -List.insert(0, 5) #insertion takes place at mentioned index -List.insert(1, 10) +List.insert(0, 5) # insertion takes place at mentioned index +List.insert(1, 10) List.insert(0, 6) print(List) -List.remove(6) -List.append(9) #insertion takes place at last +List.remove(6) +List.append(9) # insertion takes place at last List.append(1) -List.sort() #arranges element in ascending order +List.sort() # arranges element in ascending order print(List) List.pop() List.reverse() diff --git a/ML House Prediction.ipynb b/ML House Prediction.ipynb index 7babd729710..9f0fbbedaf6 100644 --- a/ML House Prediction.ipynb +++ b/ML House Prediction.ipynb @@ -22,7 +22,7 @@ "metadata": {}, "outputs": [], "source": [ - "housing= pd.read_csv(\"data.csv\")" + "housing = pd.read_csv(\"data.csv\")" ] }, { @@ -502,7 +502,7 @@ } ], "source": [ - "housing.hist(bins=50,figsize=(20,15))" + "housing.hist(bins=50, figsize=(20, 15))" ] }, { @@ -519,13 +519,15 @@ "outputs": [], "source": [ "import numpy as np\n", + "\n", + "\n", "def split_train_test(data, test_ratio):\n", " np.random.seed(42)\n", - " shuffled =np.random.permutation(len(data))\n", - " test_set_size =int(len(data)*test_ratio)\n", + " shuffled = np.random.permutation(len(data))\n", + " test_set_size = int(len(data) * test_ratio)\n", " test_indices = shuffled[:test_set_size]\n", " train_indices = shuffled[test_set_size:]\n", - " return data.iloc[train_indices],data.iloc[test_indices]" + " return data.iloc[train_indices], data.iloc[test_indices]" ] }, { @@ -534,7 +536,7 @@ "metadata": {}, "outputs": [], "source": [ - "train_set, test_set =split_train_test(housing,0.2)" + "train_set, test_set = split_train_test(housing, 0.2)" ] }, { @@ -571,7 +573,8 @@ ], "source": [ "from sklearn.model_selection import train_test_split\n", - "train_set, test_set =train_test_split(housing, test_size=0.2, random_state=42)\n", + "\n", + "train_set, test_set = train_test_split(housing, test_size=0.2, random_state=42)\n", "print(f\"Rows in train set: {len(train_set)} \\nRows in test set : {len(test_set)}\")" ] }, @@ -582,10 +585,11 @@ "outputs": [], "source": [ "from sklearn.model_selection import StratifiedShuffleSplit\n", - "split= StratifiedShuffleSplit(n_splits=1,test_size=0.2, random_state=42)\n", - "for train_index, test_index in split.split(housing, housing['CHAS']):\n", - " strat_train_set=housing.loc[train_index]\n", - " strat_test_set=housing.loc[test_index]" + "\n", + "split = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=42)\n", + "for train_index, test_index in split.split(housing, housing[\"CHAS\"]):\n", + " strat_train_set = housing.loc[train_index]\n", + " strat_test_set = housing.loc[test_index]" ] }, { @@ -831,7 +835,7 @@ } ], "source": [ - "strat_test_set['CHAS'].value_counts()" + "strat_test_set[\"CHAS\"].value_counts()" ] }, { @@ -853,7 +857,7 @@ } ], "source": [ - "strat_train_set['CHAS'].value_counts()" + "strat_train_set[\"CHAS\"].value_counts()" ] }, { @@ -862,7 +866,7 @@ "metadata": {}, "outputs": [], "source": [ - "housing= strat_train_set.copy() # use just after split data" + "housing = strat_train_set.copy() # use just after split data" ] }, { @@ -912,7 +916,7 @@ } ], "source": [ - "corr_matrix['MEDV'].sort_values(ascending=False)" + "corr_matrix[\"MEDV\"].sort_values(ascending=False)" ] }, { @@ -960,8 +964,9 @@ ], "source": [ "from pandas.plotting import scatter_matrix\n", - "attributes=[\"MEDV\",\"RM\",\"ZN\",\"LSTAT\"]\n", - "scatter_matrix(housing[attributes],figsize =(12,8))" + "\n", + "attributes = [\"MEDV\", \"RM\", \"ZN\", \"LSTAT\"]\n", + "scatter_matrix(housing[attributes], figsize=(12, 8))" ] }, { @@ -993,7 +998,7 @@ } ], "source": [ - "housing.plot(kind=\"scatter\",x=\"RM\",y=\"MEDV\",alpha=0.8)" + "housing.plot(kind=\"scatter\", x=\"RM\", y=\"MEDV\", alpha=0.8)" ] }, { @@ -1046,7 +1051,7 @@ } ], "source": [ - "median=housing[\"RM\"].median()\n", + "median = housing[\"RM\"].median()\n", "housing[\"RM\"].fillna(median)\n", "housing.shape" ] @@ -1069,7 +1074,8 @@ ], "source": [ "from sklearn.impute import SimpleImputer\n", - "imputer = SimpleImputer(strategy = \"median\")\n", + "\n", + "imputer = SimpleImputer(strategy=\"median\")\n", "imputer.fit(housing)" ] }, @@ -1308,8 +1314,8 @@ } ], "source": [ - "X= imputer.transform(housing)\n", - "housing_tr =pd.DataFrame(X,columns = housing.columns)\n", + "X = imputer.transform(housing)\n", + "housing_tr = pd.DataFrame(X, columns=housing.columns)\n", "housing_tr.describe()" ] }, @@ -1361,10 +1367,10 @@ "source": [ "from sklearn.pipeline import Pipeline\n", "from sklearn.preprocessing import StandardScaler\n", - "my_pipeline= Pipeline([\n", - " ('imputer',SimpleImputer(strategy=\"median\")),\n", - " ('std_scaler',StandardScaler())\n", - "])" + "\n", + "my_pipeline = Pipeline(\n", + " [(\"imputer\", SimpleImputer(strategy=\"median\")), (\"std_scaler\", StandardScaler())]\n", + ")" ] }, { @@ -1373,7 +1379,7 @@ "metadata": {}, "outputs": [], "source": [ - "housing_num_tr =my_pipeline.fit_transform(housing)" + "housing_num_tr = my_pipeline.fit_transform(housing)" ] }, { @@ -1423,8 +1429,9 @@ ], "source": [ "from sklearn.ensemble import RandomForestRegressor\n", - "#model = LinearRegression()\n", - "#model = DecisionTreeRegressor()\n", + "\n", + "# model = LinearRegression()\n", + "# model = DecisionTreeRegressor()\n", "model = RandomForestRegressor()\n", "model.fit(housing_num_tr, housing_labels)" ] @@ -1495,9 +1502,10 @@ "outputs": [], "source": [ "from sklearn.metrics import mean_squared_error\n", - "housing_predictions=model.predict(housing_num_tr)\n", - "lin_mse= mean_squared_error(housing_labels, housing_predictions)\n", - "lin_rmse=np.sqrt(lin_mse)" + "\n", + "housing_predictions = model.predict(housing_num_tr)\n", + "lin_mse = mean_squared_error(housing_labels, housing_predictions)\n", + "lin_rmse = np.sqrt(lin_mse)" ] }, { @@ -1554,7 +1562,10 @@ "outputs": [], "source": [ "from sklearn.model_selection import cross_val_score\n", - "scores = cross_val_score(model, housing_num_tr, housing_labels,scoring=\"neg_mean_squared_error\",cv=10)\n", + "\n", + "scores = cross_val_score(\n", + " model, housing_num_tr, housing_labels, scoring=\"neg_mean_squared_error\", cv=10\n", + ")\n", "rmse_scores = np.sqrt(-scores)" ] }, @@ -1586,9 +1597,9 @@ "outputs": [], "source": [ "def print_scores(scores):\n", - " print(\"scores: \",scores)\n", - " print(\"Mean: \",scores.mean())\n", - " print(\"Standard deviation: \",scores.std()) " + " print(\"scores: \", scores)\n", + " print(\"Mean: \", scores.mean())\n", + " print(\"Standard deviation: \", scores.std())" ] }, { @@ -1636,7 +1647,8 @@ ], "source": [ "from joblib import dump\n", - "dump(model, 'HousingPricePredicter.joblib')" + "\n", + "dump(model, \"HousingPricePredicter.joblib\")" ] }, { @@ -1652,7 +1664,7 @@ "metadata": {}, "outputs": [], "source": [ - "X_test = strat_test_set.drop(\"MEDV\" , axis=1)\n", + "X_test = strat_test_set.drop(\"MEDV\", axis=1)\n", "Y_test = strat_test_set[\"MEDV\"].copy()\n", "X_test_prepared = my_pipeline.transform(X_test)\n", "final_predictions = model.predict(X_test_prepared)\n", diff --git a/Mad Libs Generator.py b/Mad Libs Generator.py index e8bd53b3a93..652716a2ae6 100644 --- a/Mad Libs Generator.py +++ b/Mad Libs Generator.py @@ -1,22 +1,22 @@ -#Loop back to this point once code finishes +# Loop back to this point once code finishes loop = 1 -while (loop < 10): -# All the questions that the program asks the user +while loop < 10: + # All the questions that the program asks the user noun = input("Choose a noun: ") p_noun = input("Choose a plural noun: ") noun2 = input("Choose a noun: ") place = input("Name a place: ") adjective = input("Choose an adjective (Describing word): ") noun3 = input("Choose a noun: ") -# Displays the story based on the users input - print ("------------------------------------------") - print ("Be kind to your",noun,"- footed", p_noun) - print ("For a duck may be somebody's", noun2,",") - print ("Be kind to your",p_noun,"in",place) - print ("Where the weather is always",adjective,".") - print () - print ("You may think that is this the",noun3,",") - print ("Well it is.") - print ("------------------------------------------") -# Loop back to "loop = 1" + # Displays the story based on the users input + print("------------------------------------------") + print("Be kind to your", noun, "- footed", p_noun) + print("For a duck may be somebody's", noun2, ",") + print("Be kind to your", p_noun, "in", place) + print("Where the weather is always", adjective, ".") + print() + print("You may think that is this the", noun3, ",") + print("Well it is.") + print("------------------------------------------") + # Loop back to "loop = 1" loop = loop + 1 diff --git a/Memory_game.py b/Memory_game.py index 47d51808fb1..85246c09087 100644 --- a/Memory_game.py +++ b/Memory_game.py @@ -1,7 +1,8 @@ import random -import pygame import sys +import pygame + # Initialisation de pygame pygame.init() @@ -28,10 +29,26 @@ # Liste des questions et réponses (préférences) questions = [ - {"question": "Quelle est sa couleur préférée ?", "réponse": "Rose", "image": "rose.jpg"}, - {"question": "Quel est son plat préféré ?", "réponse": "Pizza", "image": "pizza.jpg"}, - {"question": "Quel est son animal préféré ?", "réponse": "Chat", "image": "chat.jpg"}, - {"question": "Quel est son film préféré ?", "réponse": "La La Land", "image": "lalaland.jpg"} + { + "question": "Quelle est sa couleur préférée ?", + "réponse": "Rose", + "image": "rose.jpg", + }, + { + "question": "Quel est son plat préféré ?", + "réponse": "Pizza", + "image": "pizza.jpg", + }, + { + "question": "Quel est son animal préféré ?", + "réponse": "Chat", + "image": "chat.jpg", + }, + { + "question": "Quel est son film préféré ?", + "réponse": "La La Land", + "image": "lalaland.jpg", + }, ] # Créer les cartes avec des questions et réponses @@ -46,11 +63,13 @@ # Créer un dictionnaire pour les positions des cartes card_positions = [(x * CARD_SIZE, y * CARD_SIZE) for x in range(4) for y in range(4)] + # Fonction pour afficher le texte def display_text(text, font, color, x, y): text_surface = font.render(text, True, color) screen.blit(text_surface, (x, y)) + # Fonction pour dessiner les cartes def draw_cards(): for idx, pos in enumerate(card_positions): @@ -59,9 +78,12 @@ def draw_cards(): pygame.draw.rect(screen, WHITE, pygame.Rect(x, y, CARD_SIZE, CARD_SIZE)) display_text(cards[idx], font, PINK, x + 10, y + 30) else: - pygame.draw.rect(screen, LIGHT_PINK, pygame.Rect(x, y, CARD_SIZE, CARD_SIZE)) + pygame.draw.rect( + screen, LIGHT_PINK, pygame.Rect(x, y, CARD_SIZE, CARD_SIZE) + ) pygame.draw.rect(screen, GREY, pygame.Rect(x, y, CARD_SIZE, CARD_SIZE), 5) + # Variables du jeu visible = [False] * len(cards) flipped_cards = [] @@ -96,10 +118,34 @@ def draw_cards(): flipped_cards.clear() if score == len(questions): - display_text("Félicitations ! Vous êtes officiellement le plus grand fan de Malak.", font, PINK, 100, HEIGHT // 2) - display_text("Mais… Pour accéder au prix ultime (photo ultra exclusive + certificat de starlette n°1),", font_small, PINK, 30, HEIGHT // 2 + 40) - display_text("veuillez envoyer 1000$ à Malak Inc.", font_small, PINK, 150, HEIGHT // 2 + 70) - display_text("(paiement accepté en chocolat, câlins ou virement bancaire immédiat)", font_small, PINK, 100, HEIGHT // 2 + 100) + display_text( + "Félicitations ! Vous êtes officiellement le plus grand fan de Malak.", + font, + PINK, + 100, + HEIGHT // 2, + ) + display_text( + "Mais… Pour accéder au prix ultime (photo ultra exclusive + certificat de starlette n°1),", + font_small, + PINK, + 30, + HEIGHT // 2 + 40, + ) + display_text( + "veuillez envoyer 1000$ à Malak Inc.", + font_small, + PINK, + 150, + HEIGHT // 2 + 70, + ) + display_text( + "(paiement accepté en chocolat, câlins ou virement bancaire immédiat)", + font_small, + PINK, + 100, + HEIGHT // 2 + 100, + ) pygame.display.update() pygame.time.delay(3000) running = False diff --git a/Merge_linked_list.py b/Merge_linked_list.py index 5c1f61e1bcc..b5b38a7a132 100644 --- a/Merge_linked_list.py +++ b/Merge_linked_list.py @@ -10,7 +10,6 @@ def __init__(self, data): # Constructor to initialize the node object class LinkedList: - # Function to initialize head def __init__(self): self.head = None @@ -38,7 +37,6 @@ def append(self, new_data): # Function to merge two sorted linked list. def mergeLists(head1, head2): - # create a temp node NULL temp = None @@ -53,7 +51,6 @@ def mergeLists(head1, head2): # If List1's data is smaller or # equal to List2's data if head1.data <= head2.data: - # assign temp to List1's data temp = head1 @@ -76,7 +73,6 @@ def mergeLists(head1, head2): # Driver Function if __name__ == "__main__": - # Create linked list : # 10->20->30->40->50 list1 = LinkedList() diff --git a/Model Usage.ipynb b/Model Usage.ipynb index a5ea4ba5fb2..cecce87f6cb 100644 --- a/Model Usage.ipynb +++ b/Model Usage.ipynb @@ -6,9 +6,10 @@ "metadata": {}, "outputs": [], "source": [ - "from joblib import load\n", "import numpy as np\n", - "model = load('HousingPricePredicter.joblib')" + "from joblib import load\n", + "\n", + "model = load(\"HousingPricePredicter.joblib\")" ] }, { @@ -17,9 +18,25 @@ "metadata": {}, "outputs": [], "source": [ - "features = np.array([[-0.43942006, 3.12628155, -1.12165014, -0.27288841, -1.42262747,\n", - " -0.24141041, -1.31238772, 2.61111401, -1.0016859 , -0.5778192 ,\n", - " -0.97491834, 0.41164221, -0.86091034]])\n" + "features = np.array(\n", + " [\n", + " [\n", + " -0.43942006,\n", + " 3.12628155,\n", + " -1.12165014,\n", + " -0.27288841,\n", + " -1.42262747,\n", + " -0.24141041,\n", + " -1.31238772,\n", + " 2.61111401,\n", + " -1.0016859,\n", + " -0.5778192,\n", + " -0.97491834,\n", + " 0.41164221,\n", + " -0.86091034,\n", + " ]\n", + " ]\n", + ")" ] }, { diff --git a/Mp3_media_player.py b/Mp3_media_player.py index 0eff5d9c379..b37df175e4a 100644 --- a/Mp3_media_player.py +++ b/Mp3_media_player.py @@ -1,10 +1,10 @@ # its very amazing import os +from tkinter import * from tkinter.filedialog import askdirectory import pygame from mutagen.id3 import ID3 -from tkinter import * root = Tk() root.minsize(300, 300) @@ -20,13 +20,11 @@ def directorychooser(): - directory = askdirectory() os.chdir(directory) for files in os.listdir(directory): if files.endswith(".mp3"): - realdir = os.path.realpath(files) audio = ID3(realdir) realnames.append(audio["TIT2"].text[0]) diff --git a/Multiply.py b/Multiply.py index ab37d64d0d2..c8e1b52228f 100644 --- a/Multiply.py +++ b/Multiply.py @@ -1,11 +1,12 @@ -def product(a,b): - if(a0): - dig=n%10 - rev=rev*10+dig - n=n//10 -print("Reverse of the number:",rev) +n = int(input("Enter number: ")) +rev = 0 +while n > 0: + dig = n % 10 + rev = rev * 10 + dig + n = n // 10 +print("Reverse of the number:", rev) diff --git a/Organise.py b/Organise.py index 4133e4138fc..6fa2ab8c86e 100644 --- a/Organise.py +++ b/Organise.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import os import shutil import sys @@ -52,7 +50,7 @@ def ChangeDirectory(dir): try: os.chdir(dir) - except WindowsError: + except OSError: print("Error! Cannot change the Directory") print("Enter a valid directory!") ChangeDirectory(str(input("Enter the Path of directory: "))) @@ -64,15 +62,15 @@ def ChangeDirectory(dir): def Organize(dirs, name): try: os.mkdir(name) - print("{} Folder Created".format(name)) - except WindowsError: - print("{} Folder Exist".format(name)) + print(f"{name} Folder Created") + except OSError: + print(f"{name} Folder Exist") - src = "{}\\{}".format(destLocation, dirs) - dest = "{}\{}".format(destLocation, name) + src = f"{destLocation}\\{dirs}" + dest = f"{destLocation}\{name}" os.chdir(dest) - shutil.move(src, "{}\\{}".format(dest, dirs)) + shutil.move(src, f"{dest}\\{dirs}") print(os.getcwd()) os.chdir(destLocation) diff --git a/PDF/demerge_pdfs.py b/PDF/demerge_pdfs.py index 12fcf081428..547708f73ac 100644 --- a/PDF/demerge_pdfs.py +++ b/PDF/demerge_pdfs.py @@ -3,17 +3,16 @@ to enhance the experience of reading and feasibility to study only specific parts from the large original textbook """ - import PyPDF2 + path = input() -merged_pdf = open(path, mode='rb') +merged_pdf = open(path, mode="rb") pdf = PyPDF2.PdfFileReader(merged_pdf) -(u, ctr, x) = tuple([0]*3) -for i in range(1, pdf.numPages+1): - +(u, ctr, x) = tuple([0] * 3) +for i in range(1, pdf.numPages + 1): if u >= pdf.numPages: print("Successfully done!") exit(0) @@ -21,15 +20,15 @@ ctr = int(input(f"Enter the number of pages for {name}: ")) u += ctr if u > pdf.numPages: - print('Limit exceeded! ') + print("Limit exceeded! ") break - base_path = '/Users/darpan/Desktop/{}.pdf' + base_path = "/Users/darpan/Desktop/{}.pdf" path = base_path.format(name) - f = open(path, mode='wb') + f = open(path, mode="wb") pdf_writer = PyPDF2.PdfFileWriter() - for j in range(x, x+ctr): + for j in range(x, x + ctr): page = pdf.getPage(j) pdf_writer.addPage(page) diff --git a/PDF/header_footer.py b/PDF/header_footer.py index f7b50037796..4078ab4314e 100644 --- a/PDF/header_footer.py +++ b/PDF/header_footer.py @@ -1,6 +1,5 @@ from fpdf import FPDF - # Author: @NavonilDas @@ -18,7 +17,7 @@ def footer(self): # Arial italic 8 self.set_font("Arial", "I", 8) # set Page number at the bottom - self.cell(0, 10, "Page No {}".format(self.page_no()), 0, 0, "C") + self.cell(0, 10, f"Page No {self.page_no()}", 0, 0, "C") pass diff --git a/PDF/images.py b/PDF/images.py index ad3c4033908..52b02a2aabd 100644 --- a/PDF/images.py +++ b/PDF/images.py @@ -1,7 +1,7 @@ import os -from PIL import Image from fpdf import FPDF +from PIL import Image # Author: @NavonilDas diff --git a/PDF/requirements.txt b/PDF/requirements.txt deleted file mode 100644 index 919182ca16b..00000000000 --- a/PDF/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -Pillow==11.3.0 -fpdf==1.7.2 \ No newline at end of file diff --git a/PDFtoAudiobook.py b/PDFtoAudiobook.py index 8a679000e66..71a1a7c84c8 100644 --- a/PDFtoAudiobook.py +++ b/PDFtoAudiobook.py @@ -1,11 +1,12 @@ -import pyttsx3 import pyPDF2 -book = open('book.pdf','rb') +import pyttsx3 + +book = open("book.pdf", "rb") pdfreader = pyPDF2.PdfFileReader(book) pages = pdfreader.numPages print(pages) speaker = pyttsx3.init() -page= pdfreader.getpage(7) +page = pdfreader.getpage(7) text = page.extractText() speaker.say(text) speaker.runAndWait() diff --git a/PONG_GAME.py b/PONG_GAME.py index 8ddec6661de..59b6e566c3d 100644 --- a/PONG_GAME.py +++ b/PONG_GAME.py @@ -45,7 +45,14 @@ def new_game(): def draw(canvas): - global paddle1_pos, paddle2_pos, ball_pos, ball_vel, paddle1_vel, paddle2_vel, BALL_RADIUS + global \ + paddle1_pos, \ + paddle2_pos, \ + ball_pos, \ + ball_vel, \ + paddle1_vel, \ + paddle2_vel, \ + BALL_RADIUS global score1, score2 canvas.draw_line([WIDTH / 2, 0], [WIDTH / 2, HEIGHT], 1, "White") diff --git a/PRACTICEPROJECT-DISREGARD.txt b/PRACTICEPROJECT-DISREGARD.txt deleted file mode 100644 index f7855aa5340..00000000000 --- a/PRACTICEPROJECT-DISREGARD.txt +++ /dev/null @@ -1,5 +0,0 @@ -This is practice for my first time using GitHub - -Please disregard as I'm getting used to using CLI and GitHub - -Thanks! diff --git a/Palindrome_Checker.py b/Palindrome_Checker.py index 598c16d940d..6f70f0e1c9f 100644 --- a/Palindrome_Checker.py +++ b/Palindrome_Checker.py @@ -1,8 +1,9 @@ """ A simple method is , to reverse the string and and compare with original string. -If both are same that's means string is palindrome otherwise else. +If both are same that's means string is palindrome otherwise else. """ + phrase = input() if phrase == phrase[::-1]: # slicing technique """phrase[::-1] this code is for reverse a string very smartly""" diff --git a/Password Generator/pass_gen.py b/Password Generator/pass_gen.py index 1aa2e991e66..b1b6df39434 100644 --- a/Password Generator/pass_gen.py +++ b/Password Generator/pass_gen.py @@ -1,5 +1,5 @@ -import string as str import secrets +import string as str class PasswordGenerator: @@ -23,7 +23,7 @@ def gen_sequence( @staticmethod def gen_password(sequence, passlength=8): - password = "".join((secrets.choice(sequence) for i in range(passlength))) + password = "".join(secrets.choice(sequence) for i in range(passlength)) return password @@ -38,11 +38,15 @@ class Interface: @classmethod def change_has_characters(cls, change): try: - cls.has_characters[change] # to check if the specified key exists in the dicitonary + cls.has_characters[ + change + ] # to check if the specified key exists in the dicitonary except Exception as err: print(f"Invalid \nan Exception: {err}") else: - cls.has_characters[change] = not cls.has_characters[change] #automaticly changres to the oppesite value already there + cls.has_characters[change] = not cls.has_characters[ + change + ] # automaticly changres to the oppesite value already there print(f"{change} is now set to {cls.has_characters[change]}") @classmethod diff --git a/Password Generator/requirements.txt b/Password Generator/requirements.txt deleted file mode 100644 index 8fb084425cf..00000000000 --- a/Password Generator/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -colorama==0.4.6 -inquirer==3.4.0 \ No newline at end of file diff --git a/Password Generator/requirements_new.txt b/Password Generator/requirements_new.txt deleted file mode 100644 index 8b137891791..00000000000 --- a/Password Generator/requirements_new.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Patterns/half triangle pattern.py b/Patterns/half triangle pattern.py index 4a87b93f7c4..9bdf4ecb3b8 100644 --- a/Patterns/half triangle pattern.py +++ b/Patterns/half triangle pattern.py @@ -1,22 +1,23 @@ - # (upper half - repeat) - #1 - #22 - #333 - - # (upper half - incremental) - #1 - #12 - #123 - - # (lower half - incremental) - #123 - #12 - #1 - - # (lower half - repeat) - #333 - #22 - #1 +# (upper half - repeat) +# 1 +# 22 +# 333 + +# (upper half - incremental) +# 1 +# 12 +# 123 + +# (lower half - incremental) +# 123 +# 12 +# 1 + +# (lower half - repeat) +# 333 +# 22 +# 1 + def main(): lines = int(input("Enter no.of lines: ")) @@ -40,30 +41,29 @@ def main(): print("Invalid input") exit(0) -def upper_half_repeat_pattern(lines=5): - for column in range(1, (lines +1)): - print(f"{str(column) * column}") + +def upper_half_repeat_pattern(lines=5): + for column in range(1, (lines + 1)): + print(f"{str(column) * column}") def lower_half_repeat_pattern(lines=5): - for length in range(lines, 0, -1): - print(f"{str(length) * length}") + for length in range(lines, 0, -1): + print(f"{str(length) * length}") def upper_half_incremental_pattern(lines=5): - const="" - for column in range(1, (lines +1)): - const+=str(column) - print(const) - + const = "" + for column in range(1, (lines + 1)): + const += str(column) + print(const) def lower_half_incremental_pattern(lines=5): - for row_length in range(lines, 0, -1): - for x in range(1,row_length+1): - print(x,end='') - print() - + for row_length in range(lines, 0, -1): + for x in range(1, row_length + 1): + print(x, end="") + print() if __name__ == "__main__": diff --git a/Patterns/pattern2.py b/Patterns/pattern2.py index 84093334cb0..b1d7b8ba3e6 100644 --- a/Patterns/pattern2.py +++ b/Patterns/pattern2.py @@ -1,5 +1,5 @@ -#pattern -#$$$$$$$$$$$ +# pattern +# $$$$$$$$$$$ # $$$$$$$$$ # $$$$$$$ # $$$$$ @@ -7,17 +7,17 @@ # $ - def main(): lines = int(input("Enter no.of lines: ")) pattern(lines) + def pattern(lines): - flag=lines - for i in range(lines): - print(" "*(i),'$'*(2*flag-1)) - flag-=1 + flag = lines + for i in range(lines): + print(" " * (i), "$" * (2 * flag - 1)) + flag -= 1 + if __name__ == "__main__": main() - diff --git a/Patterns/pattern5.py b/Patterns/pattern5.py index d0c20b8afb9..c9a9643e262 100644 --- a/Patterns/pattern5.py +++ b/Patterns/pattern5.py @@ -1,19 +1,22 @@ -#pattern Reverse piramid of numbers -#1 -#21 -#321 -#4321 -#54321 +# pattern Reverse piramid of numbers +# 1 +# 21 +# 321 +# 4321 +# 54321 + def main(): lines = int(input("Enter the number of lines: ")) pattern(lines) -def pattern(rows): - const='' - for i in range(1, rows+1): - const=str(i)+const + +def pattern(rows): + const = "" + for i in range(1, rows + 1): + const = str(i) + const print(const) + if __name__ == "__main__": main() diff --git a/Patterns/pattern6.py b/Patterns/pattern6.py index 1f02d6ce55a..1384619b0ad 100644 --- a/Patterns/pattern6.py +++ b/Patterns/pattern6.py @@ -1,17 +1,18 @@ # Python code to print the following alphabet pattern -#A -#B B -#C C C -#D D D D -#E E E E E +# A +# B B +# C C C +# D D D D +# E E E E E def alphabetpattern(n): num = 65 for i in range(0, n): - for j in range(0, i+1): + for j in range(0, i + 1): ch = chr(num) print(ch, end=" ") num = num + 1 print("\r") + a = 5 alphabetpattern(a) diff --git a/Patterns/patterns.py b/Patterns/patterns.py index 9aa70bd0883..f71a38c04eb 100644 --- a/Patterns/patterns.py +++ b/Patterns/patterns.py @@ -14,16 +14,19 @@ # * * # * + def main(): lines = int(input("Enter no.of lines: ")) pattern(lines) + def pattern(lines): - for i in range(1,lines+1): - print("* "*i) - print() + for i in range(1, lines + 1): + print("* " * i) + print() for i in range(lines): - print(" "*i,"* "*(lines-i)) + print(" " * i, "* " * (lines - i)) + if __name__ == "__main__": - main() + main() diff --git a/Pc_information.py b/Pc_information.py index 3117d78bdfa..a56c8b8764e 100644 --- a/Pc_information.py +++ b/Pc_information.py @@ -1,11 +1,13 @@ -import platform # built in lib - -print(f"System : {platform.system()}") # Prints type of Operating System -print(f"System name : {platform.node()}") # Prints System Name -print(f"version : {platform.release()}") # Prints System Version -# TO get the detailed version number -print(f"detailed version number : {platform.version()}") # Prints detailed version number -print(f"System architecture : {platform.machine()}") # Prints whether the system is 32-bit ot 64-bit -print(f"System processor : {platform.processor()}") # Prints CPU model - +import platform # built in lib +print(f"System : {platform.system()}") # Prints type of Operating System +print(f"System name : {platform.node()}") # Prints System Name +print(f"version : {platform.release()}") # Prints System Version +# TO get the detailed version number +print( + f"detailed version number : {platform.version()}" +) # Prints detailed version number +print( + f"System architecture : {platform.machine()}" +) # Prints whether the system is 32-bit ot 64-bit +print(f"System processor : {platform.processor()}") # Prints CPU model diff --git a/Personal-Expense-Tracker/expense_tracker.py b/Personal-Expense-Tracker/expense_tracker.py index 12d6b4a33c2..fb60255905f 100644 --- a/Personal-Expense-Tracker/expense_tracker.py +++ b/Personal-Expense-Tracker/expense_tracker.py @@ -1,5 +1,6 @@ import datetime + def add_expense(expenses): amount = float(input("Enter the expense amount: ")) category = input("Category (food, travel, shopping, bills, etc.): ") @@ -10,9 +11,12 @@ def add_expense(expenses): print("Incorrect date format. Please use YYYY-MM-DD format.") return note = input("(Optional) Note: ") - expenses.append({"amount": amount, "category": category, "date": date, "note": note}) + expenses.append( + {"amount": amount, "category": category, "date": date, "note": note} + ) print("Expense added!") + def view_expenses(expenses, period="all", category_filter=None): if not expenses: print("No expenses recorded yet.") @@ -20,7 +24,9 @@ def view_expenses(expenses, period="all", category_filter=None): filtered_expenses = expenses if category_filter: - filtered_expenses = [e for e in filtered_expenses if e["category"] == category_filter] + filtered_expenses = [ + e for e in filtered_expenses if e["category"] == category_filter + ] if period == "day": date_str = input("Enter the date to view expenses for (YYYY-MM-DD): ") @@ -31,11 +37,15 @@ def view_expenses(expenses, period="all", category_filter=None): print("Incorrect date format.") return elif period == "week": - date_str = input("Enter the start date of the week (YYYY-MM-DD - first day of the week): ") + date_str = input( + "Enter the start date of the week (YYYY-MM-DD - first day of the week): " + ) try: start_date = datetime.datetime.strptime(date_str, "%Y-%m-%d").date() end_date = start_date + datetime.timedelta(days=6) - filtered_expenses = [e for e in filtered_expenses if start_date <= e["date"] <= end_date] + filtered_expenses = [ + e for e in filtered_expenses if start_date <= e["date"] <= end_date + ] except ValueError: print("Incorrect date format.") return @@ -45,7 +55,11 @@ def view_expenses(expenses, period="all", category_filter=None): try: year = int(year) month = int(month) - filtered_expenses = [e for e in filtered_expenses if e["date"].year == year and e["date"].month == month] + filtered_expenses = [ + e + for e in filtered_expenses + if e["date"].year == year and e["date"].month == month + ] except ValueError: print("Incorrect year or month format.") return @@ -57,27 +71,41 @@ def view_expenses(expenses, period="all", category_filter=None): print("\n--- Expenses ---") total_spent = 0 for expense in filtered_expenses: - print(f"Amount: {expense['amount']}, Category: {expense['category']}, Date: {expense['date']}, Note: {expense['note']}") - total_spent += expense['amount'] + print( + f"Amount: {expense['amount']}, Category: {expense['category']}, Date: {expense['date']}, Note: {expense['note']}" + ) + total_spent += expense["amount"] print(f"\nTotal spent: {total_spent}") + def save_expenses(expenses, filename="expenses.txt"): with open(filename, "w") as f: for expense in expenses: - f.write(f"{expense['amount']},{expense['category']},{expense['date']},{expense['note']}\n") + f.write( + f"{expense['amount']},{expense['category']},{expense['date']},{expense['note']}\n" + ) print("Expenses saved!") + def load_expenses(filename="expenses.txt"): expenses = [] try: - with open(filename, "r") as f: + with open(filename) as f: for line in f: - amount, category, date_str, note = line.strip().split(',') - expenses.append({"amount": float(amount), "category": category, "date": datetime.datetime.strptime(date_str, "%Y-%m-%d").date(), "note": note}) + amount, category, date_str, note = line.strip().split(",") + expenses.append( + { + "amount": float(amount), + "category": category, + "date": datetime.datetime.strptime(date_str, "%Y-%m-%d").date(), + "note": note, + } + ) except FileNotFoundError: pass return expenses + def main(): expenses = load_expenses() @@ -91,22 +119,23 @@ def main(): choice = input("Choose your option: ") - if choice == '1': + if choice == "1": add_expense(expenses) - elif choice == '2': + elif choice == "2": period = input("View expenses by (day/week/month/all): ").lower() view_expenses(expenses, period) - elif choice == '3': + elif choice == "3": category_filter = input("Enter the category to filter by: ") view_expenses(expenses, category_filter=category_filter) - elif choice == '4': + elif choice == "4": save_expenses(expenses) - elif choice == '5': + elif choice == "5": save_expenses(expenses) print("Thank you!") break else: print("Invalid option. Please try again.") + if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/PingPong/Ball.py b/PingPong/Ball.py index 73961fc07f2..b1b9833f116 100644 --- a/PingPong/Ball.py +++ b/PingPong/Ball.py @@ -1,10 +1,10 @@ import pygame + pygame.init() -class Ball: +class Ball: def __init__(self, pos, vel, win, rad, minCoord, maxCoord): - self.pos = pos self.vel = vel self.win = win @@ -12,40 +12,27 @@ def __init__(self, pos, vel, win, rad, minCoord, maxCoord): self.minCoord = minCoord self.maxCoord = maxCoord - def drawBall(self): - - pygame.draw.circle(self.win, (255,)*3, self.pos, self.rad, 0) - + pygame.draw.circle(self.win, (255,) * 3, self.pos, self.rad, 0) def doHorizontalFlip(self): - self.vel[0] *= -1 print("Github") - def doVerticalFlip(self): - self.vel[1] *= -1 - def borderCollisionCheck(self): - if (self.pos[0] <= self.minCoord[0]) or (self.pos[0] >= self.maxCoord[0]): - self.doHorizontalFlip() if (self.pos[1] <= self.minCoord[1]) or (self.pos[1] >= self.maxCoord[1]): - self.doVerticalFlip() - def updatePos(self): + self.pos = [self.pos[0] + self.vel[0], self.pos[1] + self.vel[1]] - self.pos = [self.pos[0]+self.vel[0], self.pos[1]+self.vel[1]] - - - def checkSlabCollision(self, slabPos): # slab pos = [xmin, ymin, xmax, ymax] + def checkSlabCollision(self, slabPos): # slab pos = [xmin, ymin, xmax, ymax] if ( self.pos[0] + self.rad > slabPos[0] and self.pos[0] - self.rad < slabPos[2] diff --git a/PingPong/Slab.py b/PingPong/Slab.py index c5fb5d70bec..17b5bbac724 100644 --- a/PingPong/Slab.py +++ b/PingPong/Slab.py @@ -1,31 +1,41 @@ import pygame + pygame.init() + class Slab: def __init__(self, win, size, pos, player, minPos, maxPos): self.win = win self.size = size self.pos = pos - self.player = player #player = 1 or 2 + self.player = player # player = 1 or 2 self.minPos = minPos self.maxPos = maxPos - def draw(self): - pygame.draw.rect(self.win, (255, 255, 255), (self.pos[0], self.pos[1], self.size[0], self.size[1])) - + pygame.draw.rect( + self.win, + (255, 255, 255), + (self.pos[0], self.pos[1], self.size[0], self.size[1]), + ) + def getCoords(self): - return [self.pos[0], self.pos[1], self.pos[0] + self.size[0], self.pos[1] + self.size[1]] - + return [ + self.pos[0], + self.pos[1], + self.pos[0] + self.size[0], + self.pos[1] + self.size[1], + ] + def updatePos(self): keys = pygame.key.get_pressed() if self.player == 1: - if keys[pygame.K_UP] and self.getCoords()[1]> self.minPos[1]: + if keys[pygame.K_UP] and self.getCoords()[1] > self.minPos[1]: self.pos[1] -= 0.3 - if keys[pygame.K_DOWN] and self.getCoords()[3]< self.maxPos[1]: + if keys[pygame.K_DOWN] and self.getCoords()[3] < self.maxPos[1]: self.pos[1] += 0.3 else: - if keys[pygame.K_w] and self.getCoords()[1]> self.minPos[1]: + if keys[pygame.K_w] and self.getCoords()[1] > self.minPos[1]: self.pos[1] -= 0.3 - if keys[pygame.K_s] and self.getCoords()[3]< self.maxPos[1]: - self.pos[1] += 0.3 \ No newline at end of file + if keys[pygame.K_s] and self.getCoords()[3] < self.maxPos[1]: + self.pos[1] += 0.3 diff --git a/PingPong/main.py b/PingPong/main.py index 2892f8c9305..e6ee44bc096 100644 --- a/PingPong/main.py +++ b/PingPong/main.py @@ -1,20 +1,20 @@ +import pygame from Ball import Ball from Slab import Slab -import pygame WIDTH = 600 HEIGHT = 600 -BLACK = (0,0,0) -WHITE = (255,)*3 +BLACK = (0, 0, 0) +WHITE = (255,) * 3 pygame.init() -win = pygame.display.set_mode((WIDTH, HEIGHT )) +win = pygame.display.set_mode((WIDTH, HEIGHT)) print("Controls: W&S for player 1 and arrow up and down for player 2") -ball = Ball([300,300 ], [0.3,0.1], win, 10, (0,0), (600,600)) -slab = Slab(win, [10,100], [500, 300], 1, (0, 0), (600, 600)) -slab2 = Slab(win, [10,100], [100, 300], 2, (0, 0), (600, 600)) +ball = Ball([300, 300], [0.3, 0.1], win, 10, (0, 0), (600, 600)) +slab = Slab(win, [10, 100], [500, 300], 1, (0, 0), (600, 600)) +slab2 = Slab(win, [10, 100], [100, 300], 2, (0, 0), (600, 600)) run = True while run: for event in pygame.event.get(): @@ -37,4 +37,4 @@ slab2.draw() pygame.display.update() -pygame.quit() \ No newline at end of file +pygame.quit() diff --git a/Pomodoro (tkinter).py b/Pomodoro (tkinter).py index 964963c5894..3b4c5b43205 100644 --- a/Pomodoro (tkinter).py +++ b/Pomodoro (tkinter).py @@ -13,7 +13,7 @@ "Green": "#9bdeac", "Blue": "#1f75fe", "Yellow": "#ffcc00", - "Purple": "#b19cd9" + "Purple": "#b19cd9", } # Global variables @@ -25,6 +25,7 @@ custom_work_min = DEFAULT_WORK_MIN custom_break_min = DEFAULT_BREAK_MIN + # ---------------------------- BACKGROUND COLOR CHANGE FUNCTION ------------------------------- # def change_background(*args): selected = bg_color_var.get() @@ -36,14 +37,22 @@ def change_background(*args): work_label.config(bg=new_color) break_label.config(bg=new_color) + # ---------------------------- NOTIFICATION FUNCTION ------------------------------- # def show_notification(message): notif = Toplevel(window) notif.overrideredirect(True) notif.config(bg=PINK) - msg_label = Label(notif, text=message, font=(FONT_NAME, 12, "bold"), - bg=GREEN, fg="white", padx=10, pady=5) + msg_label = Label( + notif, + text=message, + font=(FONT_NAME, 12, "bold"), + bg=GREEN, + fg="white", + padx=10, + pady=5, + ) msg_label.pack() window.update_idletasks() @@ -62,6 +71,7 @@ def show_notification(message): notif.after(3000, notif.destroy) + # ---------------------------- TIMER FUNCTIONS ------------------------------- # def reset_timer(): global ROUND, timer_mec, total_time, is_paused, remaining_time @@ -79,6 +89,7 @@ def reset_timer(): pause_button.config(state=DISABLED) play_button.config(state=DISABLED) + def start_timer(): global ROUND, total_time, is_paused canvas.itemconfig(progress_arc, extent=0) @@ -96,6 +107,7 @@ def start_timer(): play_button.config(state=DISABLED) is_paused = False + def count_down(count): global timer_mec, remaining_time remaining_time = count @@ -121,6 +133,7 @@ def count_down(count): ROUND += 1 start_timer() + def pause_timer(): global is_paused, timer_mec if not is_paused: @@ -130,6 +143,7 @@ def pause_timer(): pause_button.config(state=DISABLED) play_button.config(state=NORMAL) + def resume_timer(): global is_paused if is_paused: @@ -138,6 +152,7 @@ def resume_timer(): play_button.config(state=DISABLED) pause_button.config(state=NORMAL) + def set_custom_durations(): global custom_work_min, custom_break_min try: @@ -150,6 +165,7 @@ def set_custom_durations(): except ValueError: pass + # ---------------------------- UI SETUP ------------------------------- # window = Tk() window.title("Pomodoro") @@ -157,14 +173,22 @@ def set_custom_durations(): # Canvas setup with increased width for spacing canvas = Canvas(window, width=240, height=224, bg=PINK, highlightthickness=0) -timer_text = canvas.create_text(120, 112, text="00:00", font=(FONT_NAME, 35, "bold"), fill="white") -background_circle = canvas.create_arc(40, 32, 200, 192, start=0, extent=359.9, - style="arc", outline="white", width=5) -progress_arc = canvas.create_arc(40, 32, 200, 192, start=270, extent=0, - style="arc", outline="green", width=5) +timer_text = canvas.create_text( + 120, 112, text="00:00", font=(FONT_NAME, 35, "bold"), fill="white" +) +background_circle = canvas.create_arc( + 40, 32, 200, 192, start=0, extent=359.9, style="arc", outline="white", width=5 +) +progress_arc = canvas.create_arc( + 40, 32, 200, 192, start=270, extent=0, style="arc", outline="green", width=5 +) # Updated positions for work and break time labels -left_custom = canvas.create_text(20, 112, text=f"{custom_work_min}m", font=(FONT_NAME, 12, "bold"), fill="white") -right_custom = canvas.create_text(220, 112, text=f"{custom_break_min}m", font=(FONT_NAME, 12, "bold"), fill="white") +left_custom = canvas.create_text( + 20, 112, text=f"{custom_work_min}m", font=(FONT_NAME, 12, "bold"), fill="white" +) +right_custom = canvas.create_text( + 220, 112, text=f"{custom_break_min}m", font=(FONT_NAME, 12, "bold"), fill="white" +) canvas.grid(column=1, row=1) @@ -177,31 +201,43 @@ def set_custom_durations(): reset_button = Button(text="Reset", command=reset_timer, highlightthickness=0) reset_button.grid(column=2, row=2) -pause_button = Button(text="Pause", command=pause_timer, highlightthickness=0, state=DISABLED) +pause_button = Button( + text="Pause", command=pause_timer, highlightthickness=0, state=DISABLED +) pause_button.grid(column=0, row=3) -play_button = Button(text="Play", command=resume_timer, highlightthickness=0, state=DISABLED) +play_button = Button( + text="Play", command=resume_timer, highlightthickness=0, state=DISABLED +) play_button.grid(column=2, row=3) tick_label = Label(text="", font=(FONT_NAME, 15, "bold"), bg=PINK, fg="green") tick_label.grid(column=1, row=4) # Custom durations (stacked vertically) -work_label = Label(text="Work (min):", font=(FONT_NAME, 12, "bold"), bg=PINK, fg="white") +work_label = Label( + text="Work (min):", font=(FONT_NAME, 12, "bold"), bg=PINK, fg="white" +) work_label.grid(column=1, row=5, pady=(20, 0)) entry_work = Entry(width=5, font=(FONT_NAME, 12)) entry_work.grid(column=1, row=6, pady=(5, 10)) -break_label = Label(text="Break (min):", font=(FONT_NAME, 12, "bold"), bg=PINK, fg="white") +break_label = Label( + text="Break (min):", font=(FONT_NAME, 12, "bold"), bg=PINK, fg="white" +) break_label.grid(column=1, row=7, pady=(5, 0)) entry_break = Entry(width=5, font=(FONT_NAME, 12)) entry_break.grid(column=1, row=8, pady=(5, 10)) -set_button = Button(text="Set Durations", command=set_custom_durations, font=(FONT_NAME, 12)) +set_button = Button( + text="Set Durations", command=set_custom_durations, font=(FONT_NAME, 12) +) set_button.grid(column=1, row=9, pady=(10, 20)) # OptionMenu for changing background color bg_color_var = StringVar(window) bg_color_var.set("Pink") -bg_option = OptionMenu(window, bg_color_var, *bg_colors.keys(), command=change_background) +bg_option = OptionMenu( + window, bg_color_var, *bg_colors.keys(), command=change_background +) bg_option.config(font=(FONT_NAME, 12)) bg_option.grid(column=1, row=10, pady=(10, 20)) diff --git a/PongPong_Game/pong/ball.py b/PongPong_Game/pong/ball.py index a60e0bf666a..6b8f7c79660 100644 --- a/PongPong_Game/pong/ball.py +++ b/PongPong_Game/pong/ball.py @@ -1,8 +1,8 @@ # ./PongPong/pong/ball.py -import pyglet import random -from typing import Tuple + +import pyglet class BallObject(pyglet.shapes.Circle): @@ -11,7 +11,7 @@ def __init__(self, *args, **kwargs): self.color = (255, 180, 0) self.velocity_x, self.velocity_y = 0.0, 0.0 - def update(self, win_size: Tuple, border: Tuple, other_object, dt) -> None: + def update(self, win_size: tuple, border: tuple, other_object, dt) -> None: speed = [ 2.37, 2.49, @@ -30,10 +30,10 @@ def update(self, win_size: Tuple, border: Tuple, other_object, dt) -> None: if newx < border + self.radius or newx > win_size[0] - border - self.radius: self.velocity_x = -(self.velocity_x / abs(self.velocity_x)) * rn - elif newy > win_size[1] - border - self.radius: - self.velocity_y = -(self.velocity_y / abs(self.velocity_y)) * rn - elif (newy - self.radius < other_object.height) and ( - other_object.x <= newx <= other_object.rightx + elif ( + newy > win_size[1] - border - self.radius + or (newy - self.radius < other_object.height) + and (other_object.x <= newx <= other_object.rightx) ): self.velocity_y = -(self.velocity_y / abs(self.velocity_y)) * rn else: diff --git a/PongPong_Game/pong/load.py b/PongPong_Game/pong/load.py index f06ff73da4e..72941972475 100644 --- a/PongPong_Game/pong/load.py +++ b/PongPong_Game/pong/load.py @@ -1,10 +1,10 @@ # ./PongPong/pong/load.py + from . import ball, paddle, rectangle -from typing import Tuple -def load_balls(win_size: Tuple, radius: float, speed: Tuple, batch=None): +def load_balls(win_size: tuple, radius: float, speed: tuple, batch=None): balls = [] ball_x = win_size[0] / 2 ball_y = win_size[1] / 2 @@ -15,7 +15,7 @@ def load_balls(win_size: Tuple, radius: float, speed: Tuple, batch=None): def load_paddles( - paddle_pos: Tuple, width: float, height: float, acc: Tuple, batch=None + paddle_pos: tuple, width: float, height: float, acc: tuple, batch=None ): paddles = [] new_paddle = paddle.Paddle( @@ -27,7 +27,7 @@ def load_paddles( return paddles -def load_rectangles(win_size: Tuple, border: float, batch=None): +def load_rectangles(win_size: tuple, border: float, batch=None): rectangles = [] top = rectangle.RectangleObject( x=0, y=win_size[1] - border, width=win_size[0], height=border, batch=batch diff --git a/PongPong_Game/pong/paddle.py b/PongPong_Game/pong/paddle.py index f7df52071b0..ec7f5161680 100644 --- a/PongPong_Game/pong/paddle.py +++ b/PongPong_Game/pong/paddle.py @@ -1,8 +1,8 @@ # ./PongPong/pong/paddle.py + import pyglet from pyglet.window import key -from typing import Tuple class Paddle(pyglet.shapes.Rectangle): @@ -14,8 +14,7 @@ def __init__(self, *args, **kwargs): self.key_handler = key.KeyStateHandler() self.event_handlers = [self, self.key_handler] - def update(self, win_size: Tuple, border: float, other_object, dt): - + def update(self, win_size: tuple, border: float, other_object, dt): newlx = self.x + self.acc_left newrx = self.x + self.acc_right diff --git a/PongPong_Game/requirements.txt b/PongPong_Game/requirements.txt deleted file mode 100644 index 71000361bd6..00000000000 --- a/PongPong_Game/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -pyglet==2.1.6 diff --git a/Prime_number.py b/Prime_number.py index 92800c63e83..2770a385796 100644 --- a/Prime_number.py +++ b/Prime_number.py @@ -23,7 +23,7 @@ def is_prime_b(n): if n == 2: return True else: - for i in range(2, int(n//2)+1): + for i in range(2, int(n // 2) + 1): if n % i == 0: return False return True diff --git a/Program to reverse Linked List( Recursive solution).py b/Program to reverse Linked List( Recursive solution).py index 96263c6a276..3e1d5c3c24e 100644 --- a/Program to reverse Linked List( Recursive solution).py +++ b/Program to reverse Linked List( Recursive solution).py @@ -1,6 +1,7 @@ -from sys import stdin, setrecursionlimit +from sys import setrecursionlimit, stdin + +setrecursionlimit(10**6) -setrecursionlimit(10 ** 6) # Following is the Node class already written for the Linked List class Node: @@ -56,7 +57,6 @@ def printLinkedList(head): t = int(stdin.readline().rstrip()) while t > 0: - head = takeInput() newHead = reverseLinkedListRec(head) diff --git a/Python Distance.py b/Python Distance.py index 5ac0e09fc36..919f1e1528f 100644 --- a/Python Distance.py +++ b/Python Distance.py @@ -6,8 +6,8 @@ # terms = int(input("How many terms? ")) # use anonymous function -result = list(map(lambda x: 2 ** x, range(terms))) +result = list(map(lambda x: 2**x, range(terms))) -print("The total terms are:",terms) +print("The total terms are:", terms) for i in range(terms): - print("2 raised to power",i,"is",result[i]) + print("2 raised to power", i, "is", result[i]) diff --git a/Python Program for Product of unique prime factors of a number.py b/Python Program for Product of unique prime factors of a number.py deleted file mode 100644 index 594f032750e..00000000000 --- a/Python Program for Product of unique prime factors of a number.py +++ /dev/null @@ -1,29 +0,0 @@ -# Python program to find sum of given -# series. - -def productPrimeFactors(n): - product = 1 - - for i in range(2, n+1): - if (n % i == 0): - isPrime = 1 - - for j in range(2, int(i/2 + 1)): - if (i % j == 0): - isPrime = 0 - break - - # condition if \'i\' is Prime number - # as well as factor of num - if (isPrime): - product = product * i - - return product - - - -# main() -n = 44 -print (productPrimeFactors(n)) - -# Contributed by _omg diff --git a/Python Program for Tower of Hanoi.py b/Python Program for Tower of Hanoi.py deleted file mode 100644 index 7efb1b56363..00000000000 --- a/Python Program for Tower of Hanoi.py +++ /dev/null @@ -1,10 +0,0 @@ -# Recursive Python function to solve the tower of hanoi -def TowerOfHanoi(n , source, destination, auxiliary): - if n==1: - print("Move disk 1 from source ",source," to destination ",destination) - return - TowerOfHanoi(n-1, source, auxiliary, destination) - print("Move disk ",n," from source ",source," to destination ",destination) - TowerOfHanoi(n-1, auxiliary, destination, source) -n = 4 -TowerOfHanoi(n,'A','B','C') diff --git a/Python Program for factorial of a number.py b/Python Program for factorial of a number.py deleted file mode 100644 index fb75b99de87..00000000000 --- a/Python Program for factorial of a number.py +++ /dev/null @@ -1,38 +0,0 @@ -""" -Factorial of a non-negative integer, is multiplication of -all integers smaller than or equal to n. -For example factorial of 6 is 6*5*4*3*2*1 which is 720. -""" - -""" -Recursive: -Python3 program to find factorial of given number -""" -def factorial(n): - - # single line to find factorial - return 1 if (n==1 or n==0) else n * factorial(n - 1); - -# Driver Code -num = 5; -print("Factorial of",num,"is", factorial((num))) - -""" -Iterative: -Python 3 program to find factorial of given number. -""" -def factorial(n): - if n < 0: - return 0 - elif n == 0 or n == 1: - return 1 - else: - fact = 1 - while(n > 1): - fact *= n - n -= 1 - return fact - -# Driver Code -num = 5; -print("Factorial of",num,"is", factorial(num)) diff --git a/Python Program to Display Fibonacci Sequence Using Recursion.py b/Python Program to Display Fibonacci Sequence Using Recursion.py deleted file mode 100644 index 5a70deb0e28..00000000000 --- a/Python Program to Display Fibonacci Sequence Using Recursion.py +++ /dev/null @@ -1,15 +0,0 @@ -def recur_fibo(n): - if n <= 1: - return n - else: - return(recur_fibo(n-1) + recur_fibo(n-2)) - -nterms = 10 - -# check if the number of terms is valid -if nterms <= 0: - print("Please enter a positive integer") -else: - print("Fibonacci sequence:") - for i in range(nterms): - print(recur_fibo(i)) diff --git a/Python Program to Find LCM.py b/Python Program to Find LCM.py deleted file mode 100644 index 6e9cf1cc8a1..00000000000 --- a/Python Program to Find LCM.py +++ /dev/null @@ -1,22 +0,0 @@ -# Python Program to find the L.C.M. of two input number - -def compute_lcm(x, y): - - # choose the greater number - if x > y: - greater = x - else: - greater = y - - while(True): - if((greater % x == 0) and (greater % y == 0)): - lcm = greater - break - greater += 1 - - return lcm - -num1 = 54 -num2 = 24 - -print("The L.C.M. is", compute_lcm(num1, num2)) diff --git a/Python Program to Print the Fibonacci sequence.py b/Python Program to Print the Fibonacci sequence.py deleted file mode 100644 index 9f6b1b3d7ce..00000000000 --- a/Python Program to Print the Fibonacci sequence.py +++ /dev/null @@ -1,23 +0,0 @@ -# Program to display the Fibonacci sequence up to n-th term - -nterms = int(input("How many terms? ")) - -# first two terms -n1, n2 = 0, 1 -count = 0 - -# check if the number of terms is valid -if nterms <= 0: - print("Please enter a positive integer") -elif nterms == 1: - print("Fibonacci sequence upto",nterms,":") - print(n1) -else: - print("Fibonacci sequence:") - while count < nterms: - print(n1) - nth = n1 + n2 - # update values - n1 = n2 - n2 = nth - count += 1 diff --git a/Python Program to Reverse a linked list.py b/Python Program to Reverse a linked list.py deleted file mode 100644 index c3eff50ebab..00000000000 --- a/Python Program to Reverse a linked list.py +++ /dev/null @@ -1,57 +0,0 @@ -# Python program to reverse a linked list -# Time Complexity : O(n) -# Space Complexity : O(1) - -# Node class -class Node: - - # Constructor to initialize the node object - def __init__(self, data): - self.data = data - self.next = None - -class LinkedList: - - # Function to initialize head - def __init__(self): - self.head = None - - # Function to reverse the linked list - def reverse(self): - prev = None - current = self.head - while(current is not None): - next = current.next - current.next = prev - prev = current - current = next - self.head = prev - - # Function to insert a new node at the beginning - def push(self, new_data): - new_node = Node(new_data) - new_node.next = self.head - self.head = new_node - - # Utility function to print the linked LinkedList - def printList(self): - temp = self.head - while(temp): - print(temp.data) - temp = temp.next - - -# Driver program to test above functions -llist = LinkedList() -llist.push(20) -llist.push(4) -llist.push(15) -llist.push(85) - -print("Given Linked List") -llist.printList() -llist.reverse() -print("\nReversed Linked List") -llist.printList() - -# This code is contributed by Nikhil Kumar Singh(nickzuck_007) diff --git a/Python Program to Transpose a Matrix.py b/Python Program to Transpose a Matrix.py deleted file mode 100644 index 98f6dcba024..00000000000 --- a/Python Program to Transpose a Matrix.py +++ /dev/null @@ -1,15 +0,0 @@ -X = [[12,7], - [4 ,5], - [3 ,8]] - -result = [[0,0,0], - [0,0,0]] - -# iterate through rows -for i in range(len(X)): - # iterate through columns - for j in range(len(X[0])): - result[j][i] = X[i][j] - -for r in result: - print(r) diff --git a/Python Program/Python Program for Product of unique prime factors of a number.py b/Python Program/Python Program for Product of unique prime factors of a number.py new file mode 100644 index 00000000000..1018f51be56 --- /dev/null +++ b/Python Program/Python Program for Product of unique prime factors of a number.py @@ -0,0 +1,29 @@ +# Python program to find sum of given +# series. + + +def productPrimeFactors(n): + product = 1 + + for i in range(2, n + 1): + if n % i == 0: + isPrime = 1 + + for j in range(2, int(i / 2 + 1)): + if i % j == 0: + isPrime = 0 + break + + # condition if \'i\' is Prime number + # as well as factor of num + if isPrime: + product = product * i + + return product + + +# main() +n = 44 +print(productPrimeFactors(n)) + +# Contributed by _omg diff --git a/Python Program/Python Program for Tower of Hanoi.py b/Python Program/Python Program for Tower of Hanoi.py new file mode 100644 index 00000000000..00c8eb96ce0 --- /dev/null +++ b/Python Program/Python Program for Tower of Hanoi.py @@ -0,0 +1,12 @@ +# Recursive Python function to solve the tower of hanoi +def TowerOfHanoi(n, source, destination, auxiliary): + if n == 1: + print("Move disk 1 from source ", source, " to destination ", destination) + return + TowerOfHanoi(n - 1, source, auxiliary, destination) + print("Move disk ", n, " from source ", source, " to destination ", destination) + TowerOfHanoi(n - 1, auxiliary, destination, source) + + +n = 4 +TowerOfHanoi(n, "A", "B", "C") diff --git a/Python Program/Python Program for factorial of a number.py b/Python Program/Python Program for factorial of a number.py new file mode 100644 index 00000000000..81c03506bb9 --- /dev/null +++ b/Python Program/Python Program for factorial of a number.py @@ -0,0 +1,43 @@ +""" +Factorial of a non-negative integer, is multiplication of +all integers smaller than or equal to n. +For example factorial of 6 is 6*5*4*3*2*1 which is 720. +""" + +""" +Recursive: +Python3 program to find factorial of given number +""" + + +def factorial(n): + # single line to find factorial + return 1 if (n == 1 or n == 0) else n * factorial(n - 1) + + +# Driver Code +num = 5 +print("Factorial of", num, "is", factorial(num)) + +""" +Iterative: +Python 3 program to find factorial of given number. +""" + + +def factorial(n): + if n < 0: + return 0 + elif n == 0 or n == 1: + return 1 + else: + fact = 1 + while n > 1: + fact *= n + n -= 1 + return fact + + +# Driver Code +num = 5 +print("Factorial of", num, "is", factorial(num)) diff --git a/Python Program to Count the Number of Each Vowel.py b/Python Program/Python Program to Count the Number of Each Vowel.py similarity index 61% rename from Python Program to Count the Number of Each Vowel.py rename to Python Program/Python Program to Count the Number of Each Vowel.py index 297e2488590..eb66d0967d6 100644 --- a/Python Program to Count the Number of Each Vowel.py +++ b/Python Program/Python Program to Count the Number of Each Vowel.py @@ -1,19 +1,19 @@ # Program to count the number of each vowels # string of vowels -vowels = 'aeiou' +vowels = "aeiou" -ip_str = 'Hello, have you tried our tutorial section yet?' +ip_str = "Hello, have you tried our tutorial section yet?" # make it suitable for caseless comparisions ip_str = ip_str.casefold() # make a dictionary with each vowel a key and value 0 -count = {}.fromkeys(vowels,0) +count = {}.fromkeys(vowels, 0) # count the vowels for char in ip_str: - if char in count: - count[char] += 1 + if char in count: + count[char] += 1 print(count) diff --git a/Python Program/Python Program to Display Fibonacci Sequence Using Recursion.py b/Python Program/Python Program to Display Fibonacci Sequence Using Recursion.py new file mode 100644 index 00000000000..7bfb6b7a03a --- /dev/null +++ b/Python Program/Python Program to Display Fibonacci Sequence Using Recursion.py @@ -0,0 +1,16 @@ +def recur_fibo(n): + if n <= 1: + return n + else: + return recur_fibo(n - 1) + recur_fibo(n - 2) + + +nterms = 10 + +# check if the number of terms is valid +if nterms <= 0: + print("Please enter a positive integer") +else: + print("Fibonacci sequence:") + for i in range(nterms): + print(recur_fibo(i)) diff --git a/Python Program/Python Program to Find LCM.py b/Python Program/Python Program to Find LCM.py new file mode 100644 index 00000000000..dfd1b57e81e --- /dev/null +++ b/Python Program/Python Program to Find LCM.py @@ -0,0 +1,23 @@ +# Python Program to find the L.C.M. of two input number + + +def compute_lcm(x, y): + # choose the greater number + if x > y: + greater = x + else: + greater = y + + while True: + if (greater % x == 0) and (greater % y == 0): + lcm = greater + break + greater += 1 + + return lcm + + +num1 = 54 +num2 = 24 + +print("The L.C.M. is", compute_lcm(num1, num2)) diff --git a/Python Program to Merge Mails.py b/Python Program/Python Program to Merge Mails.py similarity index 68% rename from Python Program to Merge Mails.py rename to Python Program/Python Program to Merge Mails.py index 2d18c6dbaee..93cd10e077a 100644 --- a/Python Program to Merge Mails.py +++ b/Python Program/Python Program to Merge Mails.py @@ -3,11 +3,9 @@ # Body of the mail is in body.txt # open names.txt for reading -with open("names.txt", 'r', encoding='utf-8') as names_file: - +with open("names.txt", encoding="utf-8") as names_file: # open body.txt for reading - with open("body.txt", 'r', encoding='utf-8') as body_file: - + with open("body.txt", encoding="utf-8") as body_file: # read entire content of the body body = body_file.read() @@ -16,6 +14,5 @@ mail = "Hello " + name.strip() + "\n" + body # write the mails to individual files - with open(name.strip()+".txt", 'w', encoding='utf-8') as mail_file: + with open(name.strip() + ".txt", "w", encoding="utf-8") as mail_file: mail_file.write(mail) - diff --git a/Python Program/Python Program to Print the Fibonacci sequence.py b/Python Program/Python Program to Print the Fibonacci sequence.py new file mode 100644 index 00000000000..d6a70a574cd --- /dev/null +++ b/Python Program/Python Program to Print the Fibonacci sequence.py @@ -0,0 +1,23 @@ +# Program to display the Fibonacci sequence up to n-th term + +nterms = int(input("How many terms? ")) + +# first two terms +n1, n2 = 0, 1 +count = 0 + +# check if the number of terms is valid +if nterms <= 0: + print("Please enter a positive integer") +elif nterms == 1: + print("Fibonacci sequence upto", nterms, ":") + print(n1) +else: + print("Fibonacci sequence:") + while count < nterms: + print(n1) + nth = n1 + n2 + # update values + n1 = n2 + n2 = nth + count += 1 diff --git a/Python Program to Remove Punctuations from a String.py b/Python Program/Python Program to Remove Punctuations from a String.py similarity index 68% rename from Python Program to Remove Punctuations from a String.py rename to Python Program/Python Program to Remove Punctuations from a String.py index a1e750a3a4b..003a2a12ee8 100644 --- a/Python Program to Remove Punctuations from a String.py +++ b/Python Program/Python Program to Remove Punctuations from a String.py @@ -1,5 +1,5 @@ # define punctuation -punctuations = '''!()-[]{};:'"\,<>./?@#$%^&*_~''' +punctuations = """!()-[]{};:'"\,<>./?@#$%^&*_~""" my_str = "Hello!!!, he said ---and went." @@ -9,8 +9,8 @@ # remove punctuation from the string no_punct = "" for char in my_str: - if char not in punctuations: - no_punct = no_punct + char + if char not in punctuations: + no_punct = no_punct + char # display the unpunctuated string print(no_punct) diff --git a/Python Program/Python Program to Reverse a linked list.py b/Python Program/Python Program to Reverse a linked list.py new file mode 100644 index 00000000000..e636a0df632 --- /dev/null +++ b/Python Program/Python Program to Reverse a linked list.py @@ -0,0 +1,56 @@ +# Python program to reverse a linked list +# Time Complexity : O(n) +# Space Complexity : O(1) + +# Node class +class Node: + # Constructor to initialize the node object + def __init__(self, data): + self.data = data + self.next = None + + +class LinkedList: + # Function to initialize head + def __init__(self): + self.head = None + + # Function to reverse the linked list + def reverse(self): + prev = None + current = self.head + while current is not None: + next = current.next + current.next = prev + prev = current + current = next + self.head = prev + + # Function to insert a new node at the beginning + def push(self, new_data): + new_node = Node(new_data) + new_node.next = self.head + self.head = new_node + + # Utility function to print the linked LinkedList + def printList(self): + temp = self.head + while temp: + print(temp.data) + temp = temp.next + + +# Driver program to test above functions +llist = LinkedList() +llist.push(20) +llist.push(4) +llist.push(15) +llist.push(85) + +print("Given Linked List") +llist.printList() +llist.reverse() +print("\nReversed Linked List") +llist.printList() + +# This code is contributed by Nikhil Kumar Singh(nickzuck_007) diff --git a/Python Program to Sort Words in Alphabetic Order.py b/Python Program/Python Program to Sort Words in Alphabetic Order.py similarity index 77% rename from Python Program to Sort Words in Alphabetic Order.py rename to Python Program/Python Program to Sort Words in Alphabetic Order.py index 3e4bd3564e5..737f88c5a8e 100644 --- a/Python Program to Sort Words in Alphabetic Order.py +++ b/Python Program/Python Program to Sort Words in Alphabetic Order.py @@ -1,23 +1,23 @@ # Program to sort words alphabetically and put them in a dictionary with corresponding numbered keys -# We are also removing punctuation to ensure the desired output, without importing a library for assistance. +# We are also removing punctuation to ensure the desired output, without importing a library for assistance. # Declare base variables word_Dict = {} count = 0 my_str = "Hello this Is an Example With cased letters. Hello, this is a good string" -#Initialize punctuation -punctuations = '''!()-[]{};:'",<>./?@#$%^&*_~''' +# Initialize punctuation +punctuations = """!()-[]{};:'",<>./?@#$%^&*_~""" # To take input from the user -#my_str = input("Enter a string: ") +# my_str = input("Enter a string: ") # remove punctuation from the string and use an empty variable to put the alphabetic characters into no_punct = "" for char in my_str: - if char not in punctuations: - no_punct = no_punct + char + if char not in punctuations: + no_punct = no_punct + char -# Make all words in string lowercase. my_str now equals the original string without the punctuation +# Make all words in string lowercase. my_str now equals the original string without the punctuation my_str = no_punct.lower() # breakdown the string into a list of words @@ -36,7 +36,7 @@ # insert sorted words into dictionary with key for word in new_Word_List: - count+=1 + count += 1 word_Dict[count] = word print(word_Dict) diff --git a/Python Program/Python Program to Transpose a Matrix.py b/Python Program/Python Program to Transpose a Matrix.py new file mode 100644 index 00000000000..d636ebcfa6a --- /dev/null +++ b/Python Program/Python Program to Transpose a Matrix.py @@ -0,0 +1,12 @@ +X = [[12, 7], [4, 5], [3, 8]] + +result = [[0, 0, 0], [0, 0, 0]] + +# iterate through rows +for i in range(len(X)): + # iterate through columns + for j in range(len(X[0])): + result[j][i] = X[i][j] + +for r in result: + print(r) diff --git a/python program for finding square root for positive number.py b/Python Program/python program for finding square root for positive number.py similarity index 50% rename from python program for finding square root for positive number.py rename to Python Program/python program for finding square root for positive number.py index dcb8251f839..2a2a2dc79b9 100644 --- a/python program for finding square root for positive number.py +++ b/Python Program/python program for finding square root for positive number.py @@ -1,10 +1,10 @@ # Python Program to calculate the square root # Note: change this value for a different result -num = 8 +num = 8 # To take the input from the user -#num = float(input('Enter a number: ')) +# num = float(input('Enter a number: ')) -num_sqrt = num ** 0.5 -print('The square root of %0.3f is %0.3f'%(num ,num_sqrt)) +num_sqrt = num**0.5 +print("The square root of %0.3f is %0.3f" % (num, num_sqrt)) diff --git a/Python Voice Generator.py b/Python Voice Generator.py index 9541ccfae51..a72f90d6ab0 100644 --- a/Python Voice Generator.py +++ b/Python Voice Generator.py @@ -1,11 +1,13 @@ -#install and import google text-to-speech library gtts -from gtts import gTTS +# install and import google text-to-speech library gtts import os -#provide user input text -text=input('enter the text: ') -#covert text into voice -voice=gTTS(text=text, lang='en') -#save the generated voice -voice.save('output.mp3') -#play the file in windows -os.system('start output.mp3') \ No newline at end of file + +from gtts import gTTS + +# provide user input text +text = input("enter the text: ") +# covert text into voice +voice = gTTS(text=text, lang="en") +# save the generated voice +voice.save("output.mp3") +# play the file in windows +os.system("start output.mp3") diff --git a/Python-Array-Equilibrium-Index.py b/Python-Array-Equilibrium-Index.py index 0aac8fbf995..a12ee99a79c 100644 --- a/Python-Array-Equilibrium-Index.py +++ b/Python-Array-Equilibrium-Index.py @@ -13,25 +13,27 @@ 7 -7 1 5 2 -4 3 0 Sample Output : -3 """ -def equilibrium(arr): - - # finding the sum of whole array - total_sum = sum(arr) +3""" + + +def equilibrium(arr): + # finding the sum of whole array + total_sum = sum(arr) leftsum = 0 - for i, num in enumerate(arr): - - # total_sum is now right sum - # for index i - total_sum -= num - - if leftsum == total_sum: - return i - leftsum += num - - # If no equilibrium index found, - # then return -1 + for i, num in enumerate(arr): + # total_sum is now right sum + # for index i + total_sum -= num + + if leftsum == total_sum: + return i + leftsum += num + + # If no equilibrium index found, + # then return -1 return -1 + + n = int(input()) arr = [int(i) for i in input().strip().split()] print(equilibrium(arr)) diff --git a/Python_swapping.py b/Python_swapping.py index 02b9411bca9..1822f2f1bc3 100644 --- a/Python_swapping.py +++ b/Python_swapping.py @@ -1,18 +1,19 @@ -# Python3 program to swap first -# and last element of a list - -# Swap function -def swapList(newList): - size = len(newList) - - # Swapping - temp = newList[0] - newList[0] = newList[size - 1] - newList[size - 1] = temp - - return newList - -# Driver code -newList = [12, 35, 9, 56, 24] - -print(swapList(newList)) +# Python3 program to swap first +# and last element of a list + +# Swap function +def swapList(newList): + size = len(newList) + + # Swapping + temp = newList[0] + newList[0] = newList[size - 1] + newList[size - 1] = temp + + return newList + + +# Driver code +newList = [12, 35, 9, 56, 24] + +print(swapList(newList)) diff --git a/QR_code_generator/qrcode.py b/QR_code_generator/qrcode.py index 124cb080f2c..4965d331cdb 100755 --- a/QR_code_generator/qrcode.py +++ b/QR_code_generator/qrcode.py @@ -1,5 +1,6 @@ import pyqrcode -# from pyqrcode import QRCode + +# from pyqrcode import QRCode # no need to import same library again and again # Creating QR code after given text "input" diff --git a/QuestionAnswerVirtualAssistant/backend.py b/QuestionAnswerVirtualAssistant/backend.py index 6813d2a1008..5dd5711fa12 100644 --- a/QuestionAnswerVirtualAssistant/backend.py +++ b/QuestionAnswerVirtualAssistant/backend.py @@ -1,15 +1,17 @@ -import sqlite3 import json +import sqlite3 + import pandas as pd from sklearn.feature_extraction.text import TfidfVectorizer + class QuestionAnswerVirtualAssistant: """ Used for automatic question-answering It works by building a reverse index store that maps words to an id. To find the indexed questions that contain - a certain the words in the user question, we then take an + a certain the words in the user question, we then take an intersection of the ids, ranks the questions to pick the best fit, then select the answer that maps to that question """ @@ -30,9 +32,17 @@ def __init__(self): tables_exist = res.fetchone() if not tables_exist: - self.conn.execute("CREATE TABLE IdToQuesAns(id INTEGER PRIMARY KEY, question TEXT, answer TEXT)") - self.conn.execute('CREATE TABLE WordToId (name TEXT, value TEXT)') - cur.execute("INSERT INTO WordToId VALUES (?, ?)", ("index", "{}",)) + self.conn.execute( + "CREATE TABLE IdToQuesAns(id INTEGER PRIMARY KEY, question TEXT, answer TEXT)" + ) + self.conn.execute("CREATE TABLE WordToId (name TEXT, value TEXT)") + cur.execute( + "INSERT INTO WordToId VALUES (?, ?)", + ( + "index", + "{}", + ), + ) def index_question_answer(self, question, answer): """ @@ -46,13 +56,15 @@ def index_question_answer(self, question, answer): - passes the question and answer to a method to add them to IdToQuesAns - retrieves the id of the inserted ques-answer - - uses the id to call the method that adds the words of + - uses the id to call the method that adds the words of the question to the reverse index WordToId if the word has not already been indexed """ row_id = self._add_to_IdToQuesAns(question.lower(), answer.lower()) cur = self.conn.cursor() - reverse_idx = cur.execute("SELECT value FROM WordToId WHERE name='index'").fetchone()[0] + reverse_idx = cur.execute( + "SELECT value FROM WordToId WHERE name='index'" + ).fetchone()[0] reverse_idx = json.loads(reverse_idx) question = question.split() for word in question: @@ -63,8 +75,10 @@ def index_question_answer(self, question, answer): reverse_idx[word].append(row_id) reverse_idx = json.dumps(reverse_idx) cur = self.conn.cursor() - result = cur.execute("UPDATE WordToId SET value = (?) WHERE name='index'", (reverse_idx,)) - return("index successful") + result = cur.execute( + "UPDATE WordToId SET value = (?) WHERE name='index'", (reverse_idx,) + ) + return "index successful" def _add_to_IdToQuesAns(self, question, answer): """ @@ -76,7 +90,13 @@ def _add_to_IdToQuesAns(self, question, answer): - retrieve and return the row id of the inserted document """ cur = self.conn.cursor() - res = cur.execute("INSERT INTO IdToQuesAns (question, answer) VALUES (?, ?)", (question, answer,)) + res = cur.execute( + "INSERT INTO IdToQuesAns (question, answer) VALUES (?, ?)", + ( + question, + answer, + ), + ) return res.lastrowid def find_questions(self, user_input): @@ -91,7 +111,9 @@ def find_questions(self, user_input): - return the result of the called method """ cur = self.conn.cursor() - reverse_idx = cur.execute("SELECT value FROM WordToId WHERE name='index'").fetchone()[0] + reverse_idx = cur.execute( + "SELECT value FROM WordToId WHERE name='index'" + ).fetchone()[0] reverse_idx = json.loads(reverse_idx) user_input = user_input.split(" ") all_docs_with_user_input = [] @@ -99,18 +121,18 @@ def find_questions(self, user_input): if term in reverse_idx: all_docs_with_user_input.append(reverse_idx[term]) - if not all_docs_with_user_input: # the user_input does not exist + if not all_docs_with_user_input: # the user_input does not exist return [] common_idx_of_docs = set(all_docs_with_user_input[0]) for idx in all_docs_with_user_input[1:]: common_idx_of_docs.intersection_update(idx) - if not common_idx_of_docs: # the user_input does not exist + if not common_idx_of_docs: # the user_input does not exist return [] return self._find_questions_with_idx(common_idx_of_docs) - + def _find_questions_with_idx(self, idxs): """ Returns - list[str]: the list of questions with the idxs @@ -122,11 +144,11 @@ def _find_questions_with_idx(self, idxs): """ idxs = list(idxs) cur = self.conn.cursor() - sql="SELECT id, question, answer FROM IdToQuesAns WHERE id in ({seq})".format( - seq=','.join(['?']*len(idxs)) - ) + sql = "SELECT id, question, answer FROM IdToQuesAns WHERE id in ({seq})".format( + seq=",".join(["?"] * len(idxs)) + ) result = cur.execute(sql, idxs).fetchall() - return(result) + return result def find_most_matched_question(self, user_input, corpus): """ @@ -138,14 +160,16 @@ def find_most_matched_question(self, user_input, corpus): """ vectorizer = TfidfVectorizer() tfidf_scores = vectorizer.fit_transform(corpus) - tfidf_array = pd.DataFrame(tfidf_scores.toarray(),columns=vectorizer.get_feature_names_out()) + tfidf_array = pd.DataFrame( + tfidf_scores.toarray(), columns=vectorizer.get_feature_names_out() + ) tfidf_dict = tfidf_array.to_dict() user_input = user_input.split(" ") result = [] for idx in range(len(corpus)): result.append([0, corpus[idx]]) - + for term in user_input: if term in tfidf_dict: for idx in range(len(result)): @@ -165,8 +189,12 @@ def provide_answer(self, user_input): """ matching_questions = self.find_questions(user_input) corpus = [item[1] for item in matching_questions] - question_map = {question:answer for (id, question, answer) in matching_questions} - score, most_matching_question = self.find_most_matched_question(user_input, corpus) + question_map = { + question: answer for (id, question, answer) in matching_questions + } + score, most_matching_question = self.find_most_matched_question( + user_input, corpus + ) return question_map[most_matching_question] @@ -174,21 +202,21 @@ def provide_answer(self, user_input): va = QuestionAnswerVirtualAssistant() va.index_question_answer( "What are the different types of competitions available on Kaggle", - "Types of Competitions Kaggle Competitions are designed to provide challenges for competitors" + "Types of Competitions Kaggle Competitions are designed to provide challenges for competitors", ) print( va.index_question_answer( "How to form, manage, and disband teams in a competition", - "Everyone that competes in a Competition does so as a team. A team is a group of one or more users" + "Everyone that competes in a Competition does so as a team. A team is a group of one or more users", ) ) va.index_question_answer( "What is Data Leakage", - "Data Leakage is the presence of unexpected additional information in the training data" + "Data Leakage is the presence of unexpected additional information in the training data", ) va.index_question_answer( "How does Kaggle handle cheating", - "Cheating is not taken lightly on Kaggle. We monitor our compliance account" + "Cheating is not taken lightly on Kaggle. We monitor our compliance account", ) print(va.provide_answer("state Kaggle cheating policy")) - print(va.provide_answer("Tell me what is data leakage")) \ No newline at end of file + print(va.provide_answer("Tell me what is data leakage")) diff --git a/QuestionAnswerVirtualAssistant/frontend.py b/QuestionAnswerVirtualAssistant/frontend.py index becc7dc8307..6bfe3d2db71 100644 --- a/QuestionAnswerVirtualAssistant/frontend.py +++ b/QuestionAnswerVirtualAssistant/frontend.py @@ -1,4 +1,5 @@ from tkinter import * + import backend @@ -11,22 +12,26 @@ def index_question_answer(): va = backend.QuestionAnswerVirtualAssistant() print(va.index_question_answer(question, answer)) + def provide_answer(): term = provide_answer_entry.get() va = backend.QuestionAnswerVirtualAssistant() print(va.provide_answer(term)) + if __name__ == "__main__": root = Tk() root.title("Knowledge base") - root.geometry('300x300') + root.geometry("300x300") index_question_answer_label = Label(root, text="Add question:") index_question_answer_label.pack() index_question_answer_entry = Entry(root) index_question_answer_entry.pack() - index_question_answer_button = Button(root, text="add", command=index_question_answer) + index_question_answer_button = Button( + root, text="add", command=index_question_answer + ) index_question_answer_button.pack() provide_answer_label = Label(root, text="User Input:") @@ -37,4 +42,4 @@ def provide_answer(): search_term_button = Button(root, text="ask", command=provide_answer) search_term_button.pack() - root.mainloop() \ No newline at end of file + root.mainloop() diff --git a/QuestionAnswerVirtualAssistant/requirements.txt b/QuestionAnswerVirtualAssistant/requirements.txt deleted file mode 100644 index fb4d28890ad..00000000000 --- a/QuestionAnswerVirtualAssistant/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -pandas -scikit-learn \ No newline at end of file diff --git a/Random Password Generator.py b/Random Password Generator.py index b13262dadf8..f420421d14b 100644 --- a/Random Password Generator.py +++ b/Random Password Generator.py @@ -1,12 +1,11 @@ import random -low="abcdefghijklmnopqrstuvwxyz" -upp="ABCDEFGHIJKLMNOPQRSTUVWXYZ" -num="0123456789" -sym="!@#$%^&*" +low = "abcdefghijklmnopqrstuvwxyz" +upp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +num = "0123456789" +sym = "!@#$%^&*" -all=low+upp+num+sym -length=8 -password="".join(random.sample(all,length)) +all = low + upp + num + sym +length = 8 +password = "".join(random.sample(all, length)) print(password) - diff --git a/RandomDice.py b/RandomDice.py index 404c4b30a72..682aaa47613 100644 --- a/RandomDice.py +++ b/RandomDice.py @@ -5,6 +5,7 @@ from random import randint from tkinter import * + # Function to rool the dice def roll(): text.delete(0.0, END) diff --git a/RandomNumberGame.py b/RandomNumberGame.py index 8b3129234a6..23b33dd79e0 100644 --- a/RandomNumberGame.py +++ b/RandomNumberGame.py @@ -1,9 +1,9 @@ """ - hey everyone it is a basic game code using random . in this game computer will randomly chose an number from 1 to 100 and players will have - to guess that which number it is and game will tell him on every guss whether his/her guess is smaller or bigger than the chosen number. it is - a multi player game so it can be played with many players there is no such limitations of user till the size of list. if any one wants to modify - this game he/she is most welcomed. - Thank you +hey everyone it is a basic game code using random . in this game computer will randomly chose an number from 1 to 100 and players will have +to guess that which number it is and game will tell him on every guss whether his/her guess is smaller or bigger than the chosen number. it is +a multi player game so it can be played with many players there is no such limitations of user till the size of list. if any one wants to modify +this game he/she is most welcomed. + Thank you """ import os diff --git a/Randomnumber.py b/Randomnumber.py index 45d08b4499b..6cd29746f7c 100644 --- a/Randomnumber.py +++ b/Randomnumber.py @@ -3,4 +3,4 @@ # importing the random module from random import randint -print(randint(0,9)) +print(randint(0, 9)) diff --git a/Recursion Visulaizer/git b/Recursion Visulaizer/git deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/Recursion Visulaizer/recursionVisualizer.py b/Recursion Visulaizer/recursionVisualizer.py index 4ecc495e628..8c948da0f78 100644 --- a/Recursion Visulaizer/recursionVisualizer.py +++ b/Recursion Visulaizer/recursionVisualizer.py @@ -1,5 +1,5 @@ -import turtle import random +import turtle t = turtle.Turtle() num = random.randint(1, 1000) diff --git a/SOUNDEX.py b/SOUNDEX.py index 4d49ca8272e..a5c93043196 100644 --- a/SOUNDEX.py +++ b/SOUNDEX.py @@ -1,8 +1,4 @@ -# -*- coding: utf-8 -*- - - def SOUNDEX(TERM: str): - # Step 0: Covert the TERM to UpperCase TERM = TERM.upper() TERM_LETTERS = [char for char in TERM if char.isalpha()] diff --git a/Search_Engine/backend.py b/Search_Engine/backend.py index fab720c3a50..9718deb80fb 100644 --- a/Search_Engine/backend.py +++ b/Search_Engine/backend.py @@ -1,5 +1,6 @@ -import sqlite3 import json +import sqlite3 + class SearchEngine: """ @@ -25,9 +26,17 @@ def __init__(self): tables_exist = res.fetchone() if not tables_exist: - self.conn.execute("CREATE TABLE IdToDoc(id INTEGER PRIMARY KEY, document TEXT)") - self.conn.execute('CREATE TABLE WordToId (name TEXT, value TEXT)') - cur.execute("INSERT INTO WordToId VALUES (?, ?)", ("index", "{}",)) + self.conn.execute( + "CREATE TABLE IdToDoc(id INTEGER PRIMARY KEY, document TEXT)" + ) + self.conn.execute("CREATE TABLE WordToId (name TEXT, value TEXT)") + cur.execute( + "INSERT INTO WordToId VALUES (?, ?)", + ( + "index", + "{}", + ), + ) def index_document(self, document): """ @@ -41,13 +50,15 @@ def index_document(self, document): - passes the document to a method to add the document to IdToDoc - retrieves the id of the inserted document - - uses the id to call the method that adds the words of + - uses the id to call the method that adds the words of the document to the reverse index WordToId if the word has not already been indexed """ row_id = self._add_to_IdToDoc(document) cur = self.conn.cursor() - reverse_idx = cur.execute("SELECT value FROM WordToId WHERE name='index'").fetchone()[0] + reverse_idx = cur.execute( + "SELECT value FROM WordToId WHERE name='index'" + ).fetchone()[0] reverse_idx = json.loads(reverse_idx) document = document.split() for word in document: @@ -58,8 +69,10 @@ def index_document(self, document): reverse_idx[word].append(row_id) reverse_idx = json.dumps(reverse_idx) cur = self.conn.cursor() - result = cur.execute("UPDATE WordToId SET value = (?) WHERE name='index'", (reverse_idx,)) - return("index successful") + result = cur.execute( + "UPDATE WordToId SET value = (?) WHERE name='index'", (reverse_idx,) + ) + return "index successful" def _add_to_IdToDoc(self, document): """ @@ -86,7 +99,9 @@ def find_documents(self, search_term): - return the result of the called method """ cur = self.conn.cursor() - reverse_idx = cur.execute("SELECT value FROM WordToId WHERE name='index'").fetchone()[0] + reverse_idx = cur.execute( + "SELECT value FROM WordToId WHERE name='index'" + ).fetchone()[0] reverse_idx = json.loads(reverse_idx) search_term = search_term.split(" ") all_docs_with_search_term = [] @@ -94,18 +109,18 @@ def find_documents(self, search_term): if term in reverse_idx: all_docs_with_search_term.append(reverse_idx[term]) - if not all_docs_with_search_term: # the search term does not exist + if not all_docs_with_search_term: # the search term does not exist return [] common_idx_of_docs = set(all_docs_with_search_term[0]) for idx in all_docs_with_search_term[1:]: common_idx_of_docs.intersection_update(idx) - if not common_idx_of_docs: # the search term does not exist + if not common_idx_of_docs: # the search term does not exist return [] return self._find_documents_with_idx(common_idx_of_docs) - + def _find_documents_with_idx(self, idxs): """ Returns - list[str]: the list of documents with the idxs @@ -117,11 +132,11 @@ def _find_documents_with_idx(self, idxs): """ idxs = list(idxs) cur = self.conn.cursor() - sql="SELECT document FROM IdToDoc WHERE id in ({seq})".format( - seq=','.join(['?']*len(idxs)) - ) + sql = "SELECT document FROM IdToDoc WHERE id in ({seq})".format( + seq=",".join(["?"] * len(idxs)) + ) result = cur.execute(sql, idxs).fetchall() - return(result) + return result if __name__ == "__main__": @@ -130,4 +145,4 @@ def _find_documents_with_idx(self, idxs): print(se.index_document("happiness is all you need")) se.index_document("no way should we be sad") se.index_document("a cheerful heart is a happy one even in Nigeria") - print(se.find_documents("happy")) \ No newline at end of file + print(se.find_documents("happy")) diff --git a/Search_Engine/frontend.py b/Search_Engine/frontend.py index c78bf525169..3e0eeaea013 100644 --- a/Search_Engine/frontend.py +++ b/Search_Engine/frontend.py @@ -1,4 +1,5 @@ from tkinter import * + import backend @@ -7,15 +8,17 @@ def add_document(): se = backend.SearchEngine() print(se.index_document(document)) + def find_term(): term = find_term_entry.get() se = backend.SearchEngine() print(se.find_documents(term)) + if __name__ == "__main__": root = Tk() root.title("Registration Form") - root.geometry('300x300') + root.geometry("300x300") add_documents_label = Label(root, text="Add Document:") add_documents_label.pack() @@ -33,4 +36,4 @@ def find_term(): search_term_button = Button(root, text="search", command=find_term) search_term_button.pack() - root.mainloop() \ No newline at end of file + root.mainloop() diff --git a/Search_Engine/test_data.py b/Search_Engine/test_data.py index d58f43e7d17..1c6c7b043ed 100644 --- a/Search_Engine/test_data.py +++ b/Search_Engine/test_data.py @@ -2,7 +2,7 @@ "we should all strive to be happy", "happiness is all you need", "a cheerful heart is a happy one", - "no way should we be sad" + "no way should we be sad", ] -search = "happy" \ No newline at end of file +search = "happy" diff --git a/Shortest Distance between Two Lines.py b/Shortest Distance between Two Lines.py index b60b339acda..764380981a8 100644 --- a/Shortest Distance between Two Lines.py +++ b/Shortest Distance between Two Lines.py @@ -1,4 +1,5 @@ import math + import numpy as NP LC1 = eval(input("Enter DRs of Line 1 : ")) diff --git a/Snake-Water-Gun-Game.py b/Snake-Water-Gun-Game.py index 54341645888..3bec7bc458b 100644 --- a/Snake-Water-Gun-Game.py +++ b/Snake-Water-Gun-Game.py @@ -75,7 +75,7 @@ print("Whoever wins more matches will be the winner\n") while x < 10: - print(f"Game No. {x+1}") + print(f"Game No. {x + 1}") for key, value in choices.items(): print(f"Choose {key} for {value}") diff --git a/Snake_water_gun/main.py b/Snake_water_gun/main.py index 23d8b51f5c3..3928079b997 100644 --- a/Snake_water_gun/main.py +++ b/Snake_water_gun/main.py @@ -47,7 +47,6 @@ class bcolors: score = 0 while run and i < 10: - comp_choice = random.choice(li) user_choice = input("Type s for snake, w for water or g for gun: ").lower() @@ -80,7 +79,7 @@ class bcolors: continue i += 1 - print(f"{10-i} matches left") + print(f"{10 - i} matches left") if run == True: print(f"Your score is {score} and the final result is...") diff --git a/Sorting Algorithims/heapsort_linkedlist.py b/Sorting Algorithims/heapsort_linkedlist.py index 7e9584077e6..9f535d20ade 100644 --- a/Sorting Algorithims/heapsort_linkedlist.py +++ b/Sorting Algorithims/heapsort_linkedlist.py @@ -3,6 +3,7 @@ def __init__(self, data): self.data = data self.next = None + class LinkedList: def __init__(self): self.head = None @@ -64,6 +65,7 @@ def heap_sort(self): self.swap(0, i) self.heapify(i, 0) + # Example usage: linked_list = LinkedList() linked_list.push(12) diff --git a/Sorting Algorithims/mergesort_linkedlist.py b/Sorting Algorithims/mergesort_linkedlist.py index 429684b6c0c..4e833dc2e29 100644 --- a/Sorting Algorithims/mergesort_linkedlist.py +++ b/Sorting Algorithims/mergesort_linkedlist.py @@ -1,10 +1,12 @@ from __future__ import annotations + class Node: def __init__(self, data: int) -> None: self.data = data self.next = None + class LinkedList: def __init__(self): self.head = None @@ -17,13 +19,14 @@ def insert(self, new_data: int) -> None: def printLL(self) -> None: temp = self.head if temp == None: - return 'Linked List is empty' + return "Linked List is empty" while temp.next: - print(temp.data, '->', end='') + print(temp.data, "->", end="") temp = temp.next print(temp.data) return + # Merge two sorted linked lists def merge(left, right): if not left: @@ -40,6 +43,7 @@ def merge(left, right): return result + # Merge sort for linked list def merge_sort(head): if not head or not head.next: @@ -61,9 +65,12 @@ def merge_sort(head): return merge(left, right) + if __name__ == "__main__": ll = LinkedList() - print("Enter the space-separated values of numbers to be inserted in the linked list prompted below:") + print( + "Enter the space-separated values of numbers to be inserted in the linked list prompted below:" + ) arr = list(map(int, input().split())) for num in arr: ll.insert(num) @@ -73,5 +80,5 @@ def merge_sort(head): ll.head = merge_sort(ll.head) - print('Linked list after sorting:') + print("Linked list after sorting:") ll.printLL() diff --git a/Sorting Algorithims/quicksort_linkedlist.py b/Sorting Algorithims/quicksort_linkedlist.py index 97de82e2bc2..70804343a98 100644 --- a/Sorting Algorithims/quicksort_linkedlist.py +++ b/Sorting Algorithims/quicksort_linkedlist.py @@ -1,8 +1,9 @@ """ -Given a linked list with head pointer, +Given a linked list with head pointer, sort the linked list using quicksort technique without using any extra space Time complexity: O(NlogN), Space complexity: O(1) """ + from __future__ import annotations @@ -26,13 +27,14 @@ def insert(self, new_data: int) -> None: def printLL(self) -> None: temp = self.head if temp == None: - return 'Linked List is empty' + return "Linked List is empty" while temp.next: - print(temp.data, '->', end='') + print(temp.data, "->", end="") temp = temp.next print(temp.data) return + # Partition algorithm with pivot as first element @@ -65,12 +67,14 @@ def quicksort_LL(start, end): if __name__ == "__main__": ll = LinkedList() - print("Enter the space seperated values of numbers to be inserted in linkedlist prompted below:") + print( + "Enter the space seperated values of numbers to be inserted in linkedlist prompted below:" + ) arr = list(map(int, input().split())) for num in arr: ll.insert(num) print("Linkedlist before sorting:") ll.printLL() quicksort_LL(ll.head, None) - print('Linkedlist after sorting: ') + print("Linkedlist after sorting: ") ll.printLL() diff --git a/Sorting Algorithms/Bubble_Sorting_Prog.py b/Sorting Algorithms/Bubble_Sorting_Prog.py index 20c56177a90..ddb8f949e42 100644 --- a/Sorting Algorithms/Bubble_Sorting_Prog.py +++ b/Sorting Algorithms/Bubble_Sorting_Prog.py @@ -1,5 +1,4 @@ def bubblesort(list): - # Swap the elements to arrange in order for iter_num in range(len(list) - 1, 0, -1): for idx in range(iter_num): diff --git a/Sorting Algorithms/Counting-sort.py b/Sorting Algorithms/Counting-sort.py index 34b1667762d..0b3326b563a 100644 --- a/Sorting Algorithms/Counting-sort.py +++ b/Sorting Algorithms/Counting-sort.py @@ -7,7 +7,6 @@ def counting_sort(tlist, k, n): - """Counting sort algo with sort in place. Args: tlist: target list to sort diff --git a/Sorting Algorithms/Cycle Sort.py b/Sorting Algorithms/Cycle Sort.py index 20dca703907..93e6bd80a36 100644 --- a/Sorting Algorithms/Cycle Sort.py +++ b/Sorting Algorithms/Cycle Sort.py @@ -26,7 +26,6 @@ def cycleSort(array): # Rotate the rest of the cycle. while pos != cycleStart: - # Find where to put the item. pos = cycleStart for i in range(cycleStart + 1, len(array)): diff --git a/Sorting Algorithms/Heap sort.py b/Sorting Algorithms/Heap sort.py index 69aa753c283..6e5a80c3aff 100644 --- a/Sorting Algorithms/Heap sort.py +++ b/Sorting Algorithms/Heap sort.py @@ -46,4 +46,4 @@ def heapSort(arr): n = len(arr) print("Sorted array is") for i in range(n): - print("%d" % arr[i]), + (print("%d" % arr[i]),) diff --git a/Sorting Algorithms/Iterative Merge Sort.py b/Sorting Algorithms/Iterative Merge Sort.py index 63173b6bf5c..734cf1954c0 100644 --- a/Sorting Algorithms/Iterative Merge Sort.py +++ b/Sorting Algorithms/Iterative Merge Sort.py @@ -3,20 +3,17 @@ # Iterative mergesort function to # sort arr[0...n-1] def mergeSort(a): - current_size = 1 # Outer loop for traversing Each # sub array of current_size while current_size < len(a) - 1: - left = 0 # Inner loop for merge call # in a sub array # Each complete Iteration sorts # the iterating sub array while left < len(a) - 1: - # mid index = left index of # sub array + current sub # array size - 1 diff --git a/Sorting Algorithms/Merge Sort.py b/Sorting Algorithms/Merge Sort.py index a4d2b6da18c..ae4ea350c39 100644 --- a/Sorting Algorithms/Merge Sort.py +++ b/Sorting Algorithms/Merge Sort.py @@ -70,9 +70,9 @@ def mergeSort(arr, l, r): n = len(arr) print("Given array is") for i in range(n): - print("%d" % arr[i]), + (print("%d" % arr[i]),) mergeSort(arr, 0, n - 1) print("\n\nSorted array is") for i in range(n): - print("%d" % arr[i]), + (print("%d" % arr[i]),) diff --git a/Sorting Algorithms/Quick sort.py b/Sorting Algorithms/Quick sort.py index 983c10cb82a..937f08a7a13 100644 --- a/Sorting Algorithms/Quick sort.py +++ b/Sorting Algorithms/Quick sort.py @@ -3,7 +3,6 @@ def partition(arr, low, high): pivot = arr[high] # pivot for j in range(low, high): - # If current element is smaller than or # equal to pivot if arr[j] <= pivot: @@ -43,4 +42,4 @@ def quickSort(arr, low, high): quickSort(arr, 0, n - 1) print("Sorted array is:") for i in range(n): - print("%d" % arr[i]), + (print("%d" % arr[i]),) diff --git a/Sorting Algorithms/Shell Sort.py b/Sorting Algorithms/Shell Sort.py index dc01735b12b..74fc4206364 100644 --- a/Sorting Algorithms/Shell Sort.py +++ b/Sorting Algorithms/Shell Sort.py @@ -2,7 +2,6 @@ def shellSort(arr): - # Start with a big gap, then reduce the gap n = len(arr) gap = n / 2 @@ -12,9 +11,7 @@ def shellSort(arr): # order keep adding one more element until the entire array # is gap sorted while gap > 0: - for i in range(gap, n): - # add a[i] to the elements that have been gap sorted # save a[i] in temp and make a hole at position i temp = arr[i] @@ -37,12 +34,12 @@ def shellSort(arr): n = len(arr) print("Array before sorting:") for i in range(n): - print(arr[i]), + (print(arr[i]),) shellSort(arr) print("\nArray after sorting:") for i in range(n): - print(arr[i]), + (print(arr[i]),) # This code is contributed by mohd-mehraj diff --git a/Sorting Algorithms/Sort the values of first list using second list.py b/Sorting Algorithms/Sort the values of first list using second list.py index 61bfa9cad10..2212a6b9fda 100644 --- a/Sorting Algorithms/Sort the values of first list using second list.py +++ b/Sorting Algorithms/Sort the values of first list using second list.py @@ -3,7 +3,6 @@ def sort_list(list1, list2): - zipped_pairs = zip(list2, list1) z = [x for _, x in sorted(zipped_pairs)] diff --git a/Sorting Algorithms/Tim_sort.py b/Sorting Algorithms/Tim_sort.py index 9cbbb313e5d..80566ee6249 100644 --- a/Sorting Algorithms/Tim_sort.py +++ b/Sorting Algorithms/Tim_sort.py @@ -1,24 +1,22 @@ -""" Author : Mohit Kumar - - Tim Sort implemented in python - Time Complexity : O(n log(n)) - Space Complexity :O(n) +"""Author : Mohit Kumar + +Tim Sort implemented in python +Time Complexity : O(n log(n)) +Space Complexity :O(n) """ # Python3 program to perform TimSort. RUN = 32 + # This function sorts array from left index to # to right index which is of size atmost RUN def insertionSort(arr, left, right): - for i in range(left + 1, right + 1): - temp = arr[i] j = i - 1 while j >= left and arr[j] > temp: - arr[j + 1] = arr[j] j -= 1 @@ -27,7 +25,6 @@ def insertionSort(arr, left, right): # merge function merges the sorted runs def merge(arr, l, m, r): - # original array is broken in two parts # left and right array len1, len2 = m - l + 1, r - m @@ -41,7 +38,6 @@ def merge(arr, l, m, r): # after comparing, we merge those two array # in larger sub array while i < len1 and j < len2: - if left[i] <= right[j]: arr[k] = left[i] i += 1 @@ -54,7 +50,6 @@ def merge(arr, l, m, r): # copy remaining elements of left, if any while i < len1: - arr[k] = left[i] k += 1 i += 1 @@ -69,7 +64,6 @@ def merge(arr, l, m, r): # iterative Timsort function to sort the # array[0...n-1] (similar to merge sort) def timSort(arr, n): - # Sort individual subarrays of size RUN for i in range(0, n, RUN): insertionSort(arr, i, min((i + 31), (n - 1))) @@ -78,13 +72,11 @@ def timSort(arr, n): # to form size 64, then 128, 256 and so on .... size = RUN while size < n: - # pick starting point of left sub array. We # are going to merge arr[left..left+size-1] # and arr[left+size, left+2*size-1] # After every merge, we increase left by 2*size for left in range(0, n, 2 * size): - # find ending point of left sub array # mid+1 is starting point of right sub array mid = left + size - 1 @@ -99,14 +91,12 @@ def timSort(arr, n): # utility function to print the Array def printArray(arr, n): - for i in range(0, n): print(arr[i], end=" ") print() if __name__ == "__main__": - n = int(input("Enter size of array\n")) print("Enter elements of array\n") diff --git a/Sorting Algorithms/bubblesortpgm.py b/Sorting Algorithms/bubblesortpgm.py index 2e51d9e5259..ee10d030ffb 100644 --- a/Sorting Algorithms/bubblesortpgm.py +++ b/Sorting Algorithms/bubblesortpgm.py @@ -31,7 +31,6 @@ def bubbleSort(arr): not_swap = True # Last i elements are already in place for j in range(0, n - i - 1): - # traverse the array from 0 to n-i-1 # Swap if the element found is greater # than the next element @@ -49,4 +48,4 @@ def bubbleSort(arr): print("Sorted array is:") for i in range(len(arr)): - print("%d" % arr[i]), + (print("%d" % arr[i]),) diff --git a/Sorting Algorithms/dual_pivot_quicksort.py b/Sorting Algorithms/dual_pivot_quicksort.py index ef625d2fb13..739c2144167 100644 --- a/Sorting Algorithms/dual_pivot_quicksort.py +++ b/Sorting Algorithms/dual_pivot_quicksort.py @@ -2,10 +2,10 @@ def dual_pivot_quicksort(arr, low, high): """ Performs Dual-Pivot QuickSort on the input array. - Dual-Pivot QuickSort is an optimized version of QuickSort that uses - two pivot elements to partition the array into three segments in each - recursive call. This improves performance by reducing the number of - recursive calls, making it faster on average than the single-pivot + Dual-Pivot QuickSort is an optimized version of QuickSort that uses + two pivot elements to partition the array into three segments in each + recursive call. This improves performance by reducing the number of + recursive calls, making it faster on average than the single-pivot QuickSort. Parameters: @@ -26,6 +26,7 @@ def dual_pivot_quicksort(arr, low, high): # Recursively sort elements greater than pivot2 dual_pivot_quicksort(arr, rp + 1, high) + def partition(arr, low, high): """ Partitions the array segment defined by low and high using two pivots. @@ -50,17 +51,23 @@ def partition(arr, low, high): pivot2 = arr[high] # right pivot # Initialize pointers - i = low + 1 # Pointer to traverse the array - lt = low + 1 # Boundary for elements less than pivot1 - gt = high - 1 # Boundary for elements greater than pivot2 + i = low + 1 # Pointer to traverse the array + lt = low + 1 # Boundary for elements less than pivot1 + gt = high - 1 # Boundary for elements greater than pivot2 # Traverse and partition the array based on the two pivots while i <= gt: if arr[i] < pivot1: - arr[i], arr[lt] = arr[lt], arr[i] # Swap to move smaller elements to the left + arr[i], arr[lt] = ( + arr[lt], + arr[i], + ) # Swap to move smaller elements to the left lt += 1 elif arr[i] > pivot2: - arr[i], arr[gt] = arr[gt], arr[i] # Swap to move larger elements to the right + arr[i], arr[gt] = ( + arr[gt], + arr[i], + ) # Swap to move larger elements to the right gt -= 1 i -= 1 # Decrement i to re-evaluate the swapped element i += 1 @@ -68,11 +75,12 @@ def partition(arr, low, high): # Place the pivots in their correct sorted positions lt -= 1 gt += 1 - arr[low], arr[lt] = arr[lt], arr[low] # Place pivot1 at its correct position - arr[high], arr[gt] = arr[gt], arr[high] # Place pivot2 at its correct position + arr[low], arr[lt] = arr[lt], arr[low] # Place pivot1 at its correct position + arr[high], arr[gt] = arr[gt], arr[high] # Place pivot2 at its correct position return lt, gt # Return the indices of the two pivots + # Example usage # Sample Test Case arr = [24, 8, 42, 75, 29, 77, 38, 57] diff --git a/Sorting Algorithms/pigeonhole_sort.py b/Sorting Algorithms/pigeonhole_sort.py index cf6f8a5ca6c..e3f733481e4 100644 --- a/Sorting Algorithms/pigeonhole_sort.py +++ b/Sorting Algorithms/pigeonhole_sort.py @@ -3,7 +3,6 @@ def pigeonhole_sort(a): - # (number of pigeonholes we need) my_min = min(a) my_max = max(a) diff --git a/SpeechToText.py b/SpeechToText.py index 12ee402667a..4ff765208f6 100644 --- a/SpeechToText.py +++ b/SpeechToText.py @@ -7,8 +7,10 @@ print(voice.id) print(voice.name) -id ="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_EN-US_DAVID_11.0" -engine.setProperty("voices",id ) -engine.setProperty("rate",165) +id = ( + "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_EN-US_DAVID_11.0" +) +engine.setProperty("voices", id) +engine.setProperty("rate", 165) engine.say("jarivs") # Replace string with our own text -engine.runAndWait() \ No newline at end of file +engine.runAndWait() diff --git a/Split_Circular_Linked_List.py b/Split_Circular_Linked_List.py index eadba3ce34a..26e4a2b8dd2 100644 --- a/Split_Circular_Linked_List.py +++ b/Split_Circular_Linked_List.py @@ -48,7 +48,6 @@ def Display(self): if __name__ == "__main__": - L_list = Circular_Linked_List() head1 = Circular_Linked_List() head2 = Circular_Linked_List() diff --git a/Street_Fighter/docs/requirements.txt b/Street_Fighter/docs/requirements.txt deleted file mode 100644 index 3c0b6f57287..00000000000 --- a/Street_Fighter/docs/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -pygame -numpy -opencv-python diff --git a/Street_Fighter/src/fighter.py b/Street_Fighter/src/fighter.py index bcd03297baa..94fc68abd16 100644 --- a/Street_Fighter/src/fighter.py +++ b/Street_Fighter/src/fighter.py @@ -1,4 +1,6 @@ import pygame + + class Fighter: def __init__(self, player, x, y, flip, data, sprite_sheet, animation_steps, sound): self.player = player @@ -29,9 +31,15 @@ def load_images(self, sprite_sheet, animation_steps): for y, animation in enumerate(animation_steps): temp_img_list = [] for x in range(animation): - temp_img = sprite_sheet.subsurface(x * self.size, y * self.size, self.size, self.size) + temp_img = sprite_sheet.subsurface( + x * self.size, y * self.size, self.size, self.size + ) temp_img_list.append( - pygame.transform.scale(temp_img, (self.size * self.image_scale, self.size * self.image_scale))) + pygame.transform.scale( + temp_img, + (self.size * self.image_scale, self.size * self.image_scale), + ) + ) animation_list.append(temp_img_list) return animation_list @@ -171,8 +179,12 @@ def attack(self, target): # execute attack self.attacking = True self.attack_sound.play() - attacking_rect = pygame.Rect(self.rect.centerx - (2 * self.rect.width * self.flip), self.rect.y, - 2 * self.rect.width, self.rect.height) + attacking_rect = pygame.Rect( + self.rect.centerx - (2 * self.rect.width * self.flip), + self.rect.y, + 2 * self.rect.width, + self.rect.height, + ) if attacking_rect.colliderect(target.rect): target.health -= 10 target.hit = True @@ -187,4 +199,10 @@ def update_action(self, new_action): def draw(self, surface): img = pygame.transform.flip(self.image, self.flip, False) - surface.blit(img, (self.rect.x - (self.offset[0] * self.image_scale), self.rect.y - (self.offset[1] * self.image_scale))) + surface.blit( + img, + ( + self.rect.x - (self.offset[0] * self.image_scale), + self.rect.y - (self.offset[1] * self.image_scale), + ), + ) diff --git a/Street_Fighter/src/main.py b/Street_Fighter/src/main.py index 1301e2e3f95..fc9d888f604 100644 --- a/Street_Fighter/src/main.py +++ b/Street_Fighter/src/main.py @@ -1,11 +1,13 @@ import math -import pygame -from pygame import mixer -import cv2 -import numpy as np import os import sys + +import cv2 +import numpy as np +import pygame from fighter import Fighter +from pygame import mixer + # Helper Function for Bundled Assets def resource_path(relative_path): @@ -16,6 +18,7 @@ def resource_path(relative_path): return os.path.join(base_path, relative_path) + mixer.init() pygame.init() @@ -41,13 +44,21 @@ def resource_path(relative_path): # Load Assets bg_image = cv2.imread(resource_path("assets/images/bg1.jpg")) -victory_img = pygame.image.load(resource_path("assets/images/victory.png")).convert_alpha() -warrior_victory_img = pygame.image.load(resource_path("assets/images/warrior.png")).convert_alpha() -wizard_victory_img = pygame.image.load(resource_path("assets/images/wizard.png")).convert_alpha() +victory_img = pygame.image.load( + resource_path("assets/images/victory.png") +).convert_alpha() +warrior_victory_img = pygame.image.load( + resource_path("assets/images/warrior.png") +).convert_alpha() +wizard_victory_img = pygame.image.load( + resource_path("assets/images/wizard.png") +).convert_alpha() # Fonts menu_font = pygame.font.Font(resource_path("assets/fonts/turok.ttf"), 50) -menu_font_title = pygame.font.Font(resource_path("assets/fonts/turok.ttf"), 100) # Larger font for title +menu_font_title = pygame.font.Font( + resource_path("assets/fonts/turok.ttf"), 100 +) # Larger font for title count_font = pygame.font.Font(resource_path("assets/fonts/turok.ttf"), 80) score_font = pygame.font.Font(resource_path("assets/fonts/turok.ttf"), 30) @@ -61,8 +72,12 @@ def resource_path(relative_path): magic_fx.set_volume(0.75) # Load Fighter Spritesheets -warrior_sheet = pygame.image.load(resource_path("assets/images/warrior.png")).convert_alpha() -wizard_sheet = pygame.image.load(resource_path("assets/images/wizard.png")).convert_alpha() +warrior_sheet = pygame.image.load( + resource_path("assets/images/warrior.png") +).convert_alpha() +wizard_sheet = pygame.image.load( + resource_path("assets/images/wizard.png") +).convert_alpha() # Define Animation Steps WARRIOR_ANIMATION_STEPS = [10, 8, 1, 7, 7, 3, 7] @@ -117,13 +132,24 @@ def draw_button(text, font, text_col, button_col, x, y, width, height): def victory_screen(winner_img): start_time = pygame.time.get_ticks() while pygame.time.get_ticks() - start_time < ROUND_OVER_COOLDOWN: - - resized_victory_img = pygame.transform.scale(victory_img, (victory_img.get_width() * 2, victory_img.get_height() * 2)) - screen.blit(resized_victory_img, (SCREEN_WIDTH // 2 - resized_victory_img.get_width() // 2, - SCREEN_HEIGHT // 2 - resized_victory_img.get_height() // 2 - 50)) - - screen.blit(winner_img, (SCREEN_WIDTH // 2 - winner_img.get_width() // 2, - SCREEN_HEIGHT // 2 - winner_img.get_height() // 2 + 100)) + resized_victory_img = pygame.transform.scale( + victory_img, (victory_img.get_width() * 2, victory_img.get_height() * 2) + ) + screen.blit( + resized_victory_img, + ( + SCREEN_WIDTH // 2 - resized_victory_img.get_width() // 2, + SCREEN_HEIGHT // 2 - resized_victory_img.get_height() // 2 - 50, + ), + ) + + screen.blit( + winner_img, + ( + SCREEN_WIDTH // 2 - winner_img.get_width() // 2, + SCREEN_HEIGHT // 2 - winner_img.get_height() // 2 + 100, + ), + ) pygame.display.update() @@ -151,7 +177,9 @@ def main_menu(): elapsed_time = (pygame.time.get_ticks() - animation_start_time) / 1000 scale_factor = 1 + 0.05 * math.sin(elapsed_time * 2 * math.pi) # Slight scaling - scaled_font = pygame.font.Font("assets/fonts/turok.ttf", int(100 * scale_factor)) + scaled_font = pygame.font.Font( + "assets/fonts/turok.ttf", int(100 * scale_factor) + ) title_text = "STREET FIGHTER" colors = [BLUE, GREEN, YELLOW] @@ -160,23 +188,57 @@ def main_menu(): title_y = SCREEN_HEIGHT // 6 shadow_offset = 5 - draw_text(title_text, scaled_font, shadow_color, title_x + shadow_offset, title_y + shadow_offset) + draw_text( + title_text, + scaled_font, + shadow_color, + title_x + shadow_offset, + title_y + shadow_offset, + ) draw_gradient_text(title_text, scaled_font, title_x, title_y, colors) button_width = 280 button_height = 60 button_spacing = 30 - start_button_y = SCREEN_HEIGHT // 2 - (button_height + button_spacing) * 1.5 + 50 - scores_button_y = SCREEN_HEIGHT // 2 - (button_height + button_spacing) * 0.5 + 50 + start_button_y = ( + SCREEN_HEIGHT // 2 - (button_height + button_spacing) * 1.5 + 50 + ) + scores_button_y = ( + SCREEN_HEIGHT // 2 - (button_height + button_spacing) * 0.5 + 50 + ) exit_button_y = SCREEN_HEIGHT // 2 + (button_height + button_spacing) * 0.5 + 50 - start_button = draw_button("START GAME", menu_font, BLACK, GREEN, SCREEN_WIDTH // 2 - button_width // 2, - start_button_y, button_width, button_height) - scores_button = draw_button("SCORES", menu_font, BLACK, GREEN, SCREEN_WIDTH // 2 - button_width // 2, - scores_button_y, button_width, button_height) - exit_button = draw_button("EXIT", menu_font, BLACK, GREEN, SCREEN_WIDTH // 2 - button_width // 2, - exit_button_y, button_width, button_height) + start_button = draw_button( + "START GAME", + menu_font, + BLACK, + GREEN, + SCREEN_WIDTH // 2 - button_width // 2, + start_button_y, + button_width, + button_height, + ) + scores_button = draw_button( + "SCORES", + menu_font, + BLACK, + GREEN, + SCREEN_WIDTH // 2 - button_width // 2, + scores_button_y, + button_width, + button_height, + ) + exit_button = draw_button( + "EXIT", + menu_font, + BLACK, + GREEN, + SCREEN_WIDTH // 2 - button_width // 2, + exit_button_y, + button_width, + button_height, + ) for event in pygame.event.get(): if event.type == pygame.QUIT: @@ -200,24 +262,57 @@ def scores_screen(): draw_bg(bg_image) scores_title = "SCORES" - draw_text(scores_title, menu_font_title, RED, SCREEN_WIDTH // 2 - menu_font_title.size(scores_title)[0] // 2, 50) - - score_font_large = pygame.font.Font("assets/fonts/turok.ttf", 60) # Increased size for scores + draw_text( + scores_title, + menu_font_title, + RED, + SCREEN_WIDTH // 2 - menu_font_title.size(scores_title)[0] // 2, + 50, + ) + + score_font_large = pygame.font.Font( + "assets/fonts/turok.ttf", 60 + ) # Increased size for scores p1_text = f"P1: {score[0]}" p2_text = f"P2: {score[1]}" shadow_offset = 5 p1_text_x = SCREEN_WIDTH // 2 - score_font_large.size(p1_text)[0] // 2 p1_text_y = SCREEN_HEIGHT // 2 - 50 - draw_text(p1_text, score_font_large, BLACK, p1_text_x + shadow_offset, p1_text_y + shadow_offset) # Shadow - draw_gradient_text(p1_text, score_font_large, p1_text_x, p1_text_y, [BLUE, GREEN]) # Gradient + draw_text( + p1_text, + score_font_large, + BLACK, + p1_text_x + shadow_offset, + p1_text_y + shadow_offset, + ) # Shadow + draw_gradient_text( + p1_text, score_font_large, p1_text_x, p1_text_y, [BLUE, GREEN] + ) # Gradient p2_text_x = SCREEN_WIDTH // 2 - score_font_large.size(p2_text)[0] // 2 p2_text_y = SCREEN_HEIGHT // 2 + 50 - draw_text(p2_text, score_font_large, BLACK, p2_text_x + shadow_offset, p2_text_y + shadow_offset) # Shadow - draw_gradient_text(p2_text, score_font_large, p2_text_x, p2_text_y, [RED, YELLOW]) # Gradient - - return_button = draw_button("RETURN TO MAIN MENU", menu_font, BLACK, GREEN, SCREEN_WIDTH // 2 - 220, 700, 500, 50) + draw_text( + p2_text, + score_font_large, + BLACK, + p2_text_x + shadow_offset, + p2_text_y + shadow_offset, + ) # Shadow + draw_gradient_text( + p2_text, score_font_large, p2_text_x, p2_text_y, [RED, YELLOW] + ) # Gradient + + return_button = draw_button( + "RETURN TO MAIN MENU", + menu_font, + BLACK, + GREEN, + SCREEN_WIDTH // 2 - 220, + 700, + 500, + 50, + ) for event in pygame.event.get(): if event.type == pygame.QUIT: @@ -233,8 +328,19 @@ def scores_screen(): def reset_game(): global fighter_1, fighter_2 - fighter_1 = Fighter(1, 200, 310, False, WARRIOR_DATA, warrior_sheet, WARRIOR_ANIMATION_STEPS, sword_fx) - fighter_2 = Fighter(2, 700, 310, True, WIZARD_DATA, wizard_sheet, WIZARD_ANIMATION_STEPS, magic_fx) + fighter_1 = Fighter( + 1, + 200, + 310, + False, + WARRIOR_DATA, + warrior_sheet, + WARRIOR_ANIMATION_STEPS, + sword_fx, + ) + fighter_2 = Fighter( + 2, 700, 310, True, WIZARD_DATA, wizard_sheet, WIZARD_ANIMATION_STEPS, magic_fx + ) def draw_health_bar(health, x, y): @@ -278,7 +384,9 @@ def game_loop(): draw_health_bar(fighter_1.health, 20, 50) draw_health_bar(fighter_2.health, SCREEN_WIDTH - 220, 50) - exit_button = draw_button("MAIN MENU", menu_font, BLACK, YELLOW, SCREEN_WIDTH // 2 - 150, 20, 300, 50) + exit_button = draw_button( + "MAIN MENU", menu_font, BLACK, YELLOW, SCREEN_WIDTH // 2 - 150, 20, 300, 50 + ) if not round_over: fighter_1.move(SCREEN_WIDTH, SCREEN_HEIGHT, fighter_2, round_over) diff --git a/String_Palindrome.py b/String_Palindrome.py index ab4103fd863..b1d9300fb8f 100644 --- a/String_Palindrome.py +++ b/String_Palindrome.py @@ -10,6 +10,6 @@ # check if the string is equal to its reverse if my_str == rev_str: - print("The string is a palindrome.") + print("The string is a palindrome.") else: - print("The string is not a palindrome.") + print("The string is not a palindrome.") diff --git a/Sum of digits of a number.py b/Sum of digits of a number.py index c000547c7bc..ba111336965 100644 --- a/Sum of digits of a number.py +++ b/Sum of digits of a number.py @@ -2,32 +2,44 @@ import sys + def get_integer(): - for i in range(3,0,-1): # executes the loop 3 times. Giving 3 chances to the user. + for i in range( + 3, 0, -1 + ): # executes the loop 3 times. Giving 3 chances to the user. num = input("enter a number:") - if num.isnumeric(): # checks if entered input is an integer string or not. - num = int(num) # converting integer string to integer. And returns it to where function is called. + if num.isnumeric(): # checks if entered input is an integer string or not. + num = int( + num + ) # converting integer string to integer. And returns it to where function is called. return num else: - print("enter integer only") - print(f'{i-1} chances are left' if (i-1)>1 else f'{i-1} chance is left') # prints if user entered wrong input and chances left. - continue - + print("enter integer only") + print( + f"{i - 1} chances are left" + if (i - 1) > 1 + else f"{i - 1} chance is left" + ) # prints if user entered wrong input and chances left. + continue + def addition(num): - Sum=0 - if type(num) is type(None): # Checks if number type is none or not. If type is none program exits. + Sum = 0 + if type(num) is type( + None + ): # Checks if number type is none or not. If type is none program exits. print("Try again!") sys.exit() - while num > 0: # Addition- adding the digits in the number. + while num > 0: # Addition- adding the digits in the number. digit = int(num % 10) Sum += digit num /= 10 - return Sum # Returns sum to where the function is called. - + return Sum # Returns sum to where the function is called. -if __name__ == '__main__': # this is used to overcome the problems while importing this file. +if ( + __name__ == "__main__" +): # this is used to overcome the problems while importing this file. number = get_integer() Sum = addition(number) - print(f'Sum of digits of {number} is {Sum}') # Prints the sum + print(f"Sum of digits of {number} is {Sum}") # Prints the sum diff --git a/TIC_TAC_TOE/index.py b/TIC_TAC_TOE/index.py index 95245d34fe5..afe1f9d1b78 100644 --- a/TIC_TAC_TOE/index.py +++ b/TIC_TAC_TOE/index.py @@ -3,18 +3,26 @@ def print_board(board): print(" | ".join(row)) print("-" * 9) + def check_winner(board, player): for i in range(3): # Check rows and columns - if all(board[i][j] == player for j in range(3)) or all(board[j][i] == player for j in range(3)): + if all(board[i][j] == player for j in range(3)) or all( + board[j][i] == player for j in range(3) + ): return True # Check diagonals - if all(board[i][i] == player for i in range(3)) or all(board[i][2 - i] == player for i in range(3)): + if all(board[i][i] == player for i in range(3)) or all( + board[i][2 - i] == player for i in range(3) + ): return True return False + def is_full(board): return all(cell != " " for row in board for cell in row) + + # A function that validates user input def get_valid_input(prompt): while True: @@ -27,6 +35,7 @@ def get_valid_input(prompt): except ValueError: print("Invalid input: Please enter an integer.") + def main(): board = [[" " for _ in range(3)] for _ in range(3)] player = "X" @@ -56,5 +65,6 @@ def main(): else: print("Invalid move: That spot is already taken. Try again.") + if __name__ == "__main__": main() diff --git a/TTS.py b/TTS.py index a151388ce21..0076c43f61d 100644 --- a/TTS.py +++ b/TTS.py @@ -1,5 +1,5 @@ -from tkinter import * from platform import system +from tkinter import * if system() == "Windows" or "nt": import win32com.client as wincl diff --git a/Task1.2.txt b/Task1.2.txt deleted file mode 100644 index e100a2ca4ab..00000000000 --- a/Task1.2.txt +++ /dev/null @@ -1 +0,0 @@ -Task 1.2 diff --git a/TaskManager.py b/TaskManager.py index b40a7f6beec..f98f3ceca95 100644 --- a/TaskManager.py +++ b/TaskManager.py @@ -1,30 +1,37 @@ import csv -def load_tasks(filename='tasks.csv'): + +def load_tasks(filename="tasks.csv"): tasks = [] - with open(filename, 'r', newline='') as file: + with open(filename, newline="") as file: reader = csv.reader(file) for row in reader: - tasks.append({'task': row[0], 'deadline': row[1], 'completed': row[2]}) + tasks.append({"task": row[0], "deadline": row[1], "completed": row[2]}) return tasks -def save_tasks(tasks, filename='tasks.csv'): - with open(filename, 'w', newline='') as file: + +def save_tasks(tasks, filename="tasks.csv"): + with open(filename, "w", newline="") as file: writer = csv.writer(file) for task in tasks: - writer.writerow([task['task'], task['deadline'], task['completed']]) + writer.writerow([task["task"], task["deadline"], task["completed"]]) + def add_task(task, deadline): tasks = load_tasks() - tasks.append({'task': task, 'deadline': deadline, 'completed': 'No'}) + tasks.append({"task": task, "deadline": deadline, "completed": "No"}) save_tasks(tasks) print("Task added successfully!") + def show_tasks(): tasks = load_tasks() for task in tasks: - print(f"Task: {task['task']}, Deadline: {task['deadline']}, Completed: {task['completed']}") + print( + f"Task: {task['task']}, Deadline: {task['deadline']}, Completed: {task['completed']}" + ) + # Example usage -add_task('Write daily report', '2024-04-20') +add_task("Write daily report", "2024-04-20") show_tasks() diff --git a/TaskPlanner.py b/TaskPlanner.py index b40a7f6beec..f98f3ceca95 100644 --- a/TaskPlanner.py +++ b/TaskPlanner.py @@ -1,30 +1,37 @@ import csv -def load_tasks(filename='tasks.csv'): + +def load_tasks(filename="tasks.csv"): tasks = [] - with open(filename, 'r', newline='') as file: + with open(filename, newline="") as file: reader = csv.reader(file) for row in reader: - tasks.append({'task': row[0], 'deadline': row[1], 'completed': row[2]}) + tasks.append({"task": row[0], "deadline": row[1], "completed": row[2]}) return tasks -def save_tasks(tasks, filename='tasks.csv'): - with open(filename, 'w', newline='') as file: + +def save_tasks(tasks, filename="tasks.csv"): + with open(filename, "w", newline="") as file: writer = csv.writer(file) for task in tasks: - writer.writerow([task['task'], task['deadline'], task['completed']]) + writer.writerow([task["task"], task["deadline"], task["completed"]]) + def add_task(task, deadline): tasks = load_tasks() - tasks.append({'task': task, 'deadline': deadline, 'completed': 'No'}) + tasks.append({"task": task, "deadline": deadline, "completed": "No"}) save_tasks(tasks) print("Task added successfully!") + def show_tasks(): tasks = load_tasks() for task in tasks: - print(f"Task: {task['task']}, Deadline: {task['deadline']}, Completed: {task['completed']}") + print( + f"Task: {task['task']}, Deadline: {task['deadline']}, Completed: {task['completed']}" + ) + # Example usage -add_task('Write daily report', '2024-04-20') +add_task("Write daily report", "2024-04-20") show_tasks() diff --git a/Test-Case-Generator/test_case.py b/Test-Case-Generator/test_case.py index 05c9e77d60a..a08eccc6ead 100644 --- a/Test-Case-Generator/test_case.py +++ b/Test-Case-Generator/test_case.py @@ -4,10 +4,10 @@ # _________________________________________________ ### # _________________________________________________ ### -from tkinter import * -from random import randint, choices -import webbrowser import os +import webbrowser +from random import choices, randint +from tkinter import * mycolor = "#262626" diff --git a/ThirdAI/Terms and Conditions/ThirdAI.py b/ThirdAI/Terms and Conditions/ThirdAI.py index 67d3928ec4b..09443da8b33 100644 --- a/ThirdAI/Terms and Conditions/ThirdAI.py +++ b/ThirdAI/Terms and Conditions/ThirdAI.py @@ -1,4 +1,5 @@ -from thirdai import licensing, neural_db as ndb +from thirdai import licensing +from thirdai import neural_db as ndb class NeuralDBClient: @@ -26,11 +27,11 @@ def query(self, question): search_results = self.db.search( query=question, top_k=2, - on_error=lambda error_msg: print(f"Error! {error_msg}")) + on_error=lambda error_msg: print(f"Error! {error_msg}"), + ) output = "" for result in search_results: output += result.text + "\n\n" return output - diff --git a/ThirdAI/Terms and Conditions/TkinterUI.py b/ThirdAI/Terms and Conditions/TkinterUI.py index 47317636a23..a22d18d5cd9 100644 --- a/ThirdAI/Terms and Conditions/TkinterUI.py +++ b/ThirdAI/Terms and Conditions/TkinterUI.py @@ -1,7 +1,7 @@ import tkinter as tk +from tkinter import filedialog, messagebox from tkinter.font import Font -from tkinter import messagebox -from tkinter import filedialog + from ThirdAI import NeuralDBClient as Ndb @@ -9,6 +9,7 @@ class ThirdAIApp: """ A GUI application for using the ThirdAI neural database client to train and query data. """ + def __init__(self, root): """ Initialize the user interface window. @@ -19,7 +20,7 @@ def __init__(self, root): # Initialize the main window self.root = root self.root.geometry("600x500") - self.root.title('ThirdAI - T&C') + self.root.title("ThirdAI - T&C") # Initialize variables self.path = [] @@ -28,33 +29,69 @@ def __init__(self, root): # GUI elements # Labels and buttons - self.menu = tk.Label(self.root, text="Terms & Conditions", font=self.custom_font(30), fg='black', - highlightthickness=2, highlightbackground="red") + self.menu = tk.Label( + self.root, + text="Terms & Conditions", + font=self.custom_font(30), + fg="black", + highlightthickness=2, + highlightbackground="red", + ) self.menu.place(x=125, y=10) - self.insert_button = tk.Button(self.root, text="Insert File!", font=self.custom_font(15), fg='black', bg="grey", - width=10, command=self.file_input) + self.insert_button = tk.Button( + self.root, + text="Insert File!", + font=self.custom_font(15), + fg="black", + bg="grey", + width=10, + command=self.file_input, + ) self.insert_button.place(x=245, y=100) self.text_box = tk.Text(self.root, wrap=tk.WORD, width=30, height=1) self.text_box.place(x=165, y=150) - self.training_button = tk.Button(self.root, text="Training", font=self.custom_font(15), fg='black', bg="grey", - width=10, command=self.training) + self.training_button = tk.Button( + self.root, + text="Training", + font=self.custom_font(15), + fg="black", + bg="grey", + width=10, + command=self.training, + ) self.training_button.place(x=245, y=195) - self.query_label = tk.Label(self.root, text="Query", font=self.custom_font(20), fg='black') + self.query_label = tk.Label( + self.root, text="Query", font=self.custom_font(20), fg="black" + ) self.query_label.place(x=255, y=255) self.query_entry = tk.Entry(self.root, font=self.custom_font(20), width=30) self.query_entry.place(x=70, y=300) - self.processing_button = tk.Button(self.root, text="Processing", font=self.custom_font(15), fg='black', - bg="grey", width=10, command=self.processing) + self.processing_button = tk.Button( + self.root, + text="Processing", + font=self.custom_font(15), + fg="black", + bg="grey", + width=10, + command=self.processing, + ) self.processing_button.place(x=245, y=355) - self.clear_button = tk.Button(self.root, text="Clear", font=15, fg='black', bg="grey", width=10, - command=self.clear_all) + self.clear_button = tk.Button( + self.root, + text="Clear", + font=15, + fg="black", + bg="grey", + width=10, + command=self.clear_all, + ) self.clear_button.place(x=245, y=405) @staticmethod @@ -96,7 +133,9 @@ def training(self): Train the neural database client with the selected PDF file. """ if not self.path: - messagebox.showwarning("No File Selected", "Please select a PDF file before training.") + messagebox.showwarning( + "No File Selected", "Please select a PDF file before training." + ) return self.client.train(self.path[0]) diff --git a/TicTacToe.py b/TicTacToe.py index f1b61b80df9..54be33fda53 100644 --- a/TicTacToe.py +++ b/TicTacToe.py @@ -1,186 +1,207 @@ -def print_tic_tac_toe(values): +"""Tic Tac Toe Game + +A two-player Tic Tac Toe game with score tracking. Players take turns marking +a 3x3 grid, and the first to get three marks in a row (horizontal, vertical, +or diagonal) wins. The game supports multiple rounds and maintains a scoreboard. +""" + +import sys +from typing import NoReturn + + +def print_tic_tac_toe(values: list[str]) -> None: + """Print the current state of the Tic Tac Toe board. + + Args: + values: List representing the 3x3 grid (indexes 0-8) + """ print("\n") print("\t | |") - print("\t {} | {} | {}".format(values[0], values[1], values[2])) - print('\t_____|_____|_____') - + print(f"\t {values[0]} | {values[1]} | {values[2]}") + print("\t_____|_____|_____") print("\t | |") - print("\t {} | {} | {}".format(values[3], values[4], values[5])) - print('\t_____|_____|_____') - + print(f"\t {values[3]} | {values[4]} | {values[5]}") + print("\t_____|_____|_____") print("\t | |") - - print("\t {} | {} | {}".format(values[6], values[7], values[8])) + print(f"\t {values[6]} | {values[7]} | {values[8]}") print("\t | |") print("\n") - - -# Function to print the score-board -def print_scoreboard(score_board): + + +def print_scoreboard(score_board: dict[str, int]) -> None: + """Display the current scoreboard for both players. + + Args: + score_board: Dictionary mapping player names to their scores + """ print("\t--------------------------------") print("\t SCOREBOARD ") print("\t--------------------------------") - + players = list(score_board.keys()) - print("\t ", players[0], "\t ", score_board[players[0]]) - print("\t ", players[1], "\t ", score_board[players[1]]) - + print(f"\t {players[0]}\t {score_board[players[0]]}") + print(f"\t {players[1]}\t {score_board[players[1]]}") print("\t--------------------------------\n") - -# Function to check if any player has won -def check_win(player_pos, cur_player): - - # All possible winning combinations - soln = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [1, 4, 7], [2, 5, 8], [3, 6, 9], [1, 5, 9], [3, 5, 7]] - - # Loop to check if any winning combination is satisfied - for x in soln: - if all(y in player_pos[cur_player] for y in x): - - # Return True if any winning combination satisfies - return True - # Return False if no combination is satisfied - return False - -# Function to check if the game is drawn -def check_draw(player_pos): - if len(player_pos['X']) + len(player_pos['O']) == 9: - return True - return False - -# Function for a single game of Tic Tac Toe -def single_game(cur_player): - - # Represents the Tic Tac Toe - values = [' ' for x in range(9)] - - # Stores the positions occupied by X and O - player_pos = {'X':[], 'O':[]} - - # Game Loop for a single game of Tic Tac Toe + + +def check_win(player_pos: dict[str, list[int]], cur_player: str) -> bool: + """Check if the current player has won by forming a valid line. + + Args: + player_pos: Dictionary mapping players ('X'/'O') to their occupied positions + cur_player: Current player ('X' or 'O') to check for a win + + Returns: + True if the current player has a winning line, False otherwise + """ + # All possible winning position combinations (1-based indices) + winning_combinations: list[list[int]] = [ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9], # Horizontal + [1, 4, 7], + [2, 5, 8], + [3, 6, 9], # Vertical + [1, 5, 9], + [3, 5, 7], # Diagonal + ] + + # Check if any winning combination is fully occupied by the current player + return any( + all(pos in player_pos[cur_player] for pos in combo) + for combo in winning_combinations + ) + + +def check_draw(player_pos: dict[str, list[int]]) -> bool: + """Check if the game is a draw (all positions filled with no winner). + + Args: + player_pos: Dictionary mapping players ('X'/'O') to their occupied positions + + Returns: + True if all 9 positions are filled, False otherwise + """ + return len(player_pos["X"]) + len(player_pos["O"]) == 9 + + +def single_game(cur_player: str) -> str: + """Run a single game of Tic Tac Toe and return the result. + + Args: + cur_player: Initial player for the game ('X' or 'O') + + Returns: + 'X' if X wins, 'O' if O wins, 'D' if it's a draw + """ + # Initialize empty game board (0-8 map to positions 1-9) + board: list[str] = [" " for _ in range(9)] + # Track positions occupied by each player (stores 1-9 values) + player_positions: dict[str, list[int]] = {"X": [], "O": []} + while True: - print_tic_tac_toe(values) - - # Try exception block for MOVE input + print_tic_tac_toe(board) + + # Get and validate player's move try: - print("Player ", cur_player, " turn. Which box? : ", end="") - move = int(input()) + move_input: str = input( + f"Player {cur_player}'s turn. Enter position (1-9): " + ) + move: int = int(move_input) except ValueError: - print("Wrong Input!!! Try Again") + print("Invalid input! Please enter a number between 1-9.\n") continue - - # Sanity check for MOVE inout - if move < 1 or move > 9: - print("Wrong Input!!! Try Again") + + # Validate move range + if not (1 <= move <= 9): + print("Invalid position! Please enter a number between 1-9.\n") continue - - # Check if the box is not occupied already - if values[move-1] != ' ': - print("Place already filled. Try again!!") + + # Check if position is already occupied + if board[move - 1] != " ": + print("That position is already taken! Try another.\n") continue - - # Update game information - - # Updating grid status - values[move-1] = cur_player - - # Updating player positions - player_pos[cur_player].append(move) - - # Function call for checking win - if check_win(player_pos, cur_player): - print_tic_tac_toe(values) - print("Player ", cur_player, " has won the game!!") - print("\n") + + # Update game state with valid move + board[move - 1] = cur_player + player_positions[cur_player].append(move) + + # Check for win + if check_win(player_positions, cur_player): + print_tic_tac_toe(board) + print(f"Player {cur_player} wins!\n") return cur_player - - # Function call for checking draw game - if check_draw(player_pos): - print_tic_tac_toe(values) - print("Game Drawn") - print("\n") - return 'D' - - # Switch player moves - if cur_player == 'X': - cur_player = 'O' - else: - cur_player = 'X' - -if __name__ == "__main__": - - print("Player 1") - player1 = input("Enter the name : ") - print("\n") - - print("Player 2") - player2 = input("Enter the name : ") + + # Check for draw + if check_draw(player_positions): + print_tic_tac_toe(board) + print("Game ended in a draw!\n") + return "D" + + # Switch players for next turn + cur_player = "O" if cur_player == "X" else "X" + + +def main() -> NoReturn: + """Main game loop handling multiple rounds and score tracking.""" + # Get player names + print("Player 1, please enter your name:") + player1: str = input().strip() + print("\nPlayer 2, please enter your name:") + player2: str = input().strip() print("\n") - - # Stores the player who chooses X and O - cur_player = player1 - - # Stores the choice of players - player_choice = {'X' : "", 'O' : ""} - - # Stores the options - options = ['X', 'O'] - - # Stores the scoreboard - score_board = {player1: 0, player2: 0} - print_scoreboard(score_board) - - # Game Loop for a series of Tic Tac Toe - # The loop runs until the players quit + + # Initialize game state + current_chooser: str = player1 # Player who chooses X/O for the round + player_marks: dict[str, str] = {"X": "", "O": ""} # Maps mark to player name + scoreboard: dict[str, int] = {player1: 0, player2: 0} + mark_options: list[str] = ["X", "O"] + + print_scoreboard(scoreboard) + + # Main game loop (multiple rounds) while True: - - # Player choice Menu - print("Turn to choose for", cur_player) - print("Enter 1 for X") - print("Enter 2 for O") - print("Enter 3 to Quit") - - # Try exception for CHOICE input + print(f"It's {current_chooser}'s turn to choose a mark:") + print("1 - Choose X") + print("2 - Choose O") + print("3 - Quit the game") + + # Get and validate player's choice try: - choice = int(input()) + choice_input: str = input("Enter your choice: ").strip() + choice: int = int(choice_input) except ValueError: - print("Wrong Input!!! Try Again\n") + print("Invalid input! Please enter a number (1-3).\n") continue - - # Conditions for player choice - if choice == 1: - player_choice['X'] = cur_player - if cur_player == player1: - player_choice['O'] = player2 - else: - player_choice['O'] = player1 - - elif choice == 2: - player_choice['O'] = cur_player - if cur_player == player1: - player_choice['X'] = player2 - else: - player_choice['X'] = player1 - - elif choice == 3: - print("Final Scores") - print_scoreboard(score_board) - break - - else: - print("Wrong Choice!!!! Try Again\n") - - # Stores the winner in a single game of Tic Tac Toe - winner = single_game(options[choice-1]) - - # Edits the scoreboard according to the winner - if winner != 'D' : - player_won = player_choice[winner] - score_board[player_won] = score_board[player_won] + 1 - - print_scoreboard(score_board) - # Switch player who chooses X or O - if cur_player == player1: - cur_player = player2 - else: - cur_player = player1 + + # Process choice + if choice == 3: + # Exit game + print("Final Scores:") + print_scoreboard(scoreboard) + sys.exit(0) + elif choice not in (1, 2): + print("Invalid choice! Please enter 1, 2, or 3.\n") + continue + + # Assign marks based on choice + chosen_mark: str = mark_options[choice - 1] + player_marks[chosen_mark] = current_chooser + other_mark: str = "O" if chosen_mark == "X" else "X" + player_marks[other_mark] = player2 if current_chooser == player1 else player1 + + # Run a single game and update score + round_winner: str = single_game(chosen_mark) + if round_winner != "D": + winning_player: str = player_marks[round_winner] + scoreboard[winning_player] += 1 + + # Show updated scores + print_scoreboard(scoreboard) + + # Switch mark chooser for next round + current_chooser = player2 if current_chooser == player1 else player1 + + +if __name__ == "__main__": + main() diff --git a/Timetable_Operations.py b/Timetable_Operations.py index 0f75e59e516..444c9c17ef2 100644 --- a/Timetable_Operations.py +++ b/Timetable_Operations.py @@ -1,52 +1,180 @@ -##Clock in pt2thon## - -t1 = input("Init schedule : ") # first schedule -HH1 = int(t1[0] + t1[1]) -MM1 = int(t1[3] + t1[4]) -SS1 = int(t1[6] + t1[7]) - -t2 = input("Final schedule : ") # second schedule -HH2 = int(t2[0] + t2[1]) -MM2 = int(t2[3] + t2[4]) -SS2 = int(t2[6] + t2[7]) - -tt1 = (HH1 * 3600) + (MM1 * 60) + SS1 # total schedule 1 -tt2 = (HH2 * 3600) + (MM2 * 60) + SS2 # total schedule 2 -tt3 = tt2 - tt1 # difference between tt2 e tt1 - -# Part Math -if tt3 < 0: - # If the difference between tt2 e tt1 for negative : - - a = 86400 - tt1 # 86400 is seconds in 1 day; - a2 = a + tt2 # a2 is the difference between 1 day e the ; - Ht = a2 // 3600 # Ht is hours calculated; - - a = a2 % 3600 # Convert 'a' in seconds; - Mt = a // 60 # Mt is minutes calculated; - St = a % 60 # St is seconds calculated; - -else: - # If the difference between tt2 e tt1 for positive : - - Ht = tt3 // 3600 # Ht is hours calculated; - z = tt3 % 3600 # 'z' is tt3 converting in hours by seconds - - Mt = z // 60 # Mt is minutes calculated; - St = tt3 % 60 # St is seconds calculated; - -# special condition below : -if Ht < 10: - h = "0" + str(Ht) - Ht = h -if Mt < 10: - m = "0" + str(Mt) - Mt = m -if St < 10: - s = "0" + str(St) - St = s -# add '0' to the empty spaces (caused by previous operations) in the final result! - -print( - "final result is :", str(Ht) + ":" + str(Mt) + ":" + str(St) -) # final result (formatted in clock) +"""Clock Time Difference Calculator + +Calculates the time difference between two 24-hour formatted times (HH:MM:SS) +and returns the result in the same HH:MM:SS format. Handles cases where the +second time is earlier than the first (crosses midnight). +""" + +import sys + + +def parse_time(time_str: str) -> tuple[int, int, int]: + """Parse a time string in HH:MM:SS format into hours, minutes, seconds. + + Args: + time_str: Time string in "HH:MM:SS" format. + + Returns: + Tuple containing (hours, minutes, seconds). + + Raises: + ValueError: If input format is invalid or values are out of range. + """ + # Validate string structure + if not isinstance(time_str, str): + raise ValueError("Time must be a string") + + if len(time_str) != 8: + raise ValueError(f"Invalid time length: '{time_str}' (expected 8 characters)") + + if time_str[2] != ":" or time_str[5] != ":": + raise ValueError(f"Invalid format: '{time_str}' (use HH:MM:SS)") + + # Extract and validate components + try: + hours = int(time_str[0:2]) + minutes = int(time_str[3:5]) + seconds = int(time_str[6:8]) + except ValueError as e: + raise ValueError(f"Non-numeric components in '{time_str}': {e}") from e + + # Validate value ranges + if not (0 <= hours < 24): + raise ValueError(f"Hours out of range (0-23): {hours}") + if not (0 <= minutes < 60): + raise ValueError(f"Minutes out of range (0-59): {minutes}") + if not (0 <= seconds < 60): + raise ValueError(f"Seconds out of range (0-59): {seconds}") + + return hours, minutes, seconds + + +def time_to_seconds(hours: int, minutes: int, seconds: int) -> int: + """Convert hours, minutes, seconds to total seconds since midnight. + + Args: + hours: Hours (0-23) + minutes: Minutes (0-59) + seconds: Seconds (0-59) + + Returns: + Total seconds (0-86399). + """ + # Double-check input ranges (defensive programming) + if not (0 <= hours < 24): + raise ValueError(f"Invalid hours: {hours} (must be 0-23)") + if not (0 <= minutes < 60): + raise ValueError(f"Invalid minutes: {minutes} (must be 0-59)") + if not (0 <= seconds < 60): + raise ValueError(f"Invalid seconds: {seconds} (must be 0-59)") + + return hours * 3600 + minutes * 60 + seconds + + +def seconds_to_time(total_seconds: int) -> tuple[int, int, int]: + """Convert total seconds to hours, minutes, seconds. + + Args: + total_seconds: Total seconds (handles negative values and large numbers). + + Returns: + Tuple containing (hours, minutes, seconds) normalized to 0-23:59:59. + """ + # Handle negative values by adding full days until positive + if total_seconds < 0: + days_to_add = (-total_seconds // 86400) + 1 + total_seconds += days_to_add * 86400 + + # Normalize to within a single day (0-86399 seconds) + total_seconds %= 86400 + + hours = total_seconds // 3600 + remaining = total_seconds % 3600 + minutes = remaining // 60 + seconds = remaining % 60 + + return hours, minutes, seconds + + +def format_time(hours: int, minutes: int, seconds: int) -> str: + """Format hours, minutes, seconds into HH:MM:SS string. + + Args: + hours: Hours (0-23) + minutes: Minutes (0-59) + seconds: Seconds (0-59) + + Returns: + Formatted time string with leading zeros where necessary. + """ + # Final validation before formatting + if not (0 <= hours < 24): + raise ValueError(f"Invalid hours for formatting: {hours}") + if not (0 <= minutes < 60): + raise ValueError(f"Invalid minutes for formatting: {minutes}") + if not (0 <= seconds < 60): + raise ValueError(f"Invalid seconds for formatting: {seconds}") + + return f"{hours:02d}:{minutes:02d}:{seconds:02d}" + + +def calculate_time_difference(t1: str, t2: str) -> str: + """Calculate the time difference between two times (t2 - t1). + + Args: + t1: Start time in HH:MM:SS format. + t2: End time in HH:MM:SS format. + + Returns: + Time difference in HH:MM:SS format. + """ + # Validate input isn't empty + if not t1.strip(): + raise ValueError("Initial time cannot be empty") + if not t2.strip(): + raise ValueError("Final time cannot be empty") + + # Parse input times with detailed error context + try: + h1, m1, s1 = parse_time(t1) + except ValueError as e: + raise ValueError(f"Invalid initial time: {e}") from e + + try: + h2, m2, s2 = parse_time(t2) + except ValueError as e: + raise ValueError(f"Invalid final time: {e}") from e + + # Convert to total seconds with range checks + sec1 = time_to_seconds(h1, m1, s1) + sec2 = time_to_seconds(h2, m2, s2) + + # Calculate difference (handle midnight crossing) + diff_seconds = sec2 - sec1 + + # Convert back to hours, minutes, seconds with normalization + h_diff, m_diff, s_diff = seconds_to_time(diff_seconds) + + # Format and return result + return format_time(h_diff, m_diff, s_diff) + + +def main() -> None: + """Main function to handle user input and display results.""" + try: + t1 = input("Initial schedule (HH:MM:SS): ").strip() + t2 = input("Final schedule (HH:MM:SS): ").strip() + + result = calculate_time_difference(t1, t2) + print(f"Final result is: {result}") + + except ValueError as e: + print(f"Error: {e}", file=sys.stderr) + sys.exit(1) + except Exception as e: + print(f"Unexpected error: {e}", file=sys.stderr) + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/To find the largest number between 3 numbers.py b/To find the largest number between 3 numbers.py index 5e7e1575292..b2f338dee73 100644 --- a/To find the largest number between 3 numbers.py +++ b/To find the largest number between 3 numbers.py @@ -1,7 +1,81 @@ -# Python program to find the largest number among the three input numbers +"""Find the Largest Number Among Three Inputs -a=[] -for i in range(3): - a.append(int(input())) -print("The largest among three numbers is:",max(a)) +This program takes three numeric inputs from the user and determines +the largest number using a straightforward comparison approach. +""" + +def get_valid_number(input_prompt: str) -> float: + """Prompt the user for a number and validate the input. + + Args: + input_prompt: String to display when requesting input + + Returns: + Validated numeric value (integer or float) + + Raises: + ValueError: If input cannot be converted to a number + """ + while True: + user_input = input(input_prompt).strip() + try: + return float(user_input) + except ValueError: + print(f"Error: '{user_input}' is not a valid number. Please try again.") + + +def get_three_numbers() -> list[float]: + """Collect three valid numbers from the user. + + Returns: + List containing three numeric values + """ + numbers: list[float] = [] + for i in range(3): + num = get_valid_number(f"Enter number {i + 1}: ") + numbers.append(num) + return numbers + + +def find_largest(numbers: list[int | float]) -> int | float: + """Determine the largest number in a list of three numbers. + + Args: + numbers: List containing exactly three numeric values + + Returns: + The largest value in the list + + Raises: + ValueError: If the input list does not contain exactly three numbers + TypeError: If any element in the list is not numeric + """ + # Validate input list + if len(numbers) != 3: + raise ValueError(f"Expected 3 numbers, got {len(numbers)}") + + for i, num in enumerate(numbers): + if not isinstance(num, (int, float)): + raise TypeError(f"Element {i + 1} is not a number: {type(num).__name__}") + + return max(numbers) + + +def main() -> None: + """Main function to coordinate input collection and result display.""" + print("Find the largest number among three inputs\n") + + try: + numbers = get_three_numbers() + largest = find_largest(numbers) + print(f"\nThe largest among the three numbers is: {largest}") + except (ValueError, TypeError) as e: + print(f"Error: {e}", file=sys.stderr) + sys.exit(1) + + +if __name__ == "__main__": + import sys # Import here to avoid unused import in module mode + + main() diff --git a/To print series 1,12,123,1234......py b/To print series 1,12,123,1234......py index 93adda5ee67..cc192eed3eb 100644 --- a/To print series 1,12,123,1234......py +++ b/To print series 1,12,123,1234......py @@ -1,6 +1,5 @@ # master def num(a): - # initialising starting number num = 1 @@ -8,7 +7,6 @@ def num(a): # outer loop to handle number of rows for i in range(0, a): - # re assigning num num = 1 @@ -18,7 +16,6 @@ def num(a): # values changing acc. to outer loop for k in range(0, i + 1): - # printing number print(num, end=" ") diff --git a/Todo_GUi.py b/Todo_GUi.py index 21dafef44e3..a065dec99af 100644 --- a/Todo_GUi.py +++ b/Todo_GUi.py @@ -1,48 +1,45 @@ -from tkinter import messagebox import tkinter as tk +from tkinter import messagebox + # Function to be called when button is clicked def add_Button(): - task=Input.get() + task = Input.get() if task: - List.insert(tk.END,task) - Input.delete(0,tk.END) - + List.insert(tk.END, task) + Input.delete(0, tk.END) def del_Button(): try: - task=List.curselection()[0] + task = List.curselection()[0] List.delete(task) except IndexError: messagebox.showwarning("Selection Error", "Please select a task to delete.") - # Create the main window window = tk.Tk() window.title("Task Manager") window.geometry("500x500") -window.resizable(False,False) +window.resizable(False, False) window.config(bg="light grey") # text filed -Input=tk.Entry(window,width=50) -Input.grid(row=0,column=0,padx=20,pady=60) +Input = tk.Entry(window, width=50) +Input.grid(row=0, column=0, padx=20, pady=60) Input.focus() # Create the button -add =tk.Button(window, text="ADD TASK", height=2, width=9, command=add_Button) +add = tk.Button(window, text="ADD TASK", height=2, width=9, command=add_Button) add.grid(row=0, column=1, padx=20, pady=0) -delete=tk.Button(window,text="DELETE TASK", height=2,width=10,command=del_Button) -delete.grid(row=1,column=1) +delete = tk.Button(window, text="DELETE TASK", height=2, width=10, command=del_Button) +delete.grid(row=1, column=1) # creating list box -List=tk.Listbox(window,width=50,height=20) -List.grid(row=1,column=0) - - +List = tk.Listbox(window, width=50, height=20) +List.grid(row=1, column=0) -window.mainloop() \ No newline at end of file +window.mainloop() diff --git a/Translator/translator.py b/Translator/translator.py index 509be9e6410..3079b61e910 100644 --- a/Translator/translator.py +++ b/Translator/translator.py @@ -1,6 +1,8 @@ from tkinter import * + from translate import Translator + # Translator function def translate(): translator = Translator(from_lang=lan1.get(), to_lang=lan2.get()) diff --git a/Trending youtube videos b/Trending youtube videos deleted file mode 100644 index a14535e4ddc..00000000000 --- a/Trending youtube videos +++ /dev/null @@ -1,43 +0,0 @@ -''' - Python program that uses the YouTube Data API to fetch the top 10 trending YouTube videos. -You’ll need to have an API key from Google Cloud Platform to use the YouTube Data API. - -First, install the google-api-python-client library if you haven’t already: -pip install google-api-python-client - -Replace 'YOUR_API_KEY' with your actual API key. This script will fetch and print the titles, -channels, and view counts of the top 10 trending YouTube videos in India. -You can change the regionCode to any other country code if needed. - -Then, you can use the following code: - -''' - -from googleapiclient.discovery import build - -# Replace with your own API key -API_KEY = 'YOUR_API_KEY' -YOUTUBE_API_SERVICE_NAME = 'youtube' -YOUTUBE_API_VERSION = 'v3' - -def get_trending_videos(): - youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=API_KEY) - - # Call the API to get the top 10 trending videos - request = youtube.videos().list( - part='snippet,statistics', - chart='mostPopular', - regionCode='IN', # Change this to your region code - maxResults=10 - ) - response = request.execute() - - # Print the video details - for item in response['items']: - title = item['snippet']['title'] - channel = item['snippet']['channelTitle'] - views = item['statistics']['viewCount'] - print(f'Title: {title}\nChannel: {channel}\nViews: {views}\n') - -if __name__ == '__main__': - get_trending_videos() diff --git a/Trending youtube videos.py b/Trending youtube videos.py index a14535e4ddc..e74f15e75f3 100644 --- a/Trending youtube videos.py +++ b/Trending youtube videos.py @@ -1,43 +1,45 @@ -''' - Python program that uses the YouTube Data API to fetch the top 10 trending YouTube videos. +""" + Python program that uses the YouTube Data API to fetch the top 10 trending YouTube videos. You’ll need to have an API key from Google Cloud Platform to use the YouTube Data API. -First, install the google-api-python-client library if you haven’t already: +First, install the google-api-python-client library if you haven’t already: pip install google-api-python-client -Replace 'YOUR_API_KEY' with your actual API key. This script will fetch and print the titles, -channels, and view counts of the top 10 trending YouTube videos in India. +Replace 'YOUR_API_KEY' with your actual API key. This script will fetch and print the titles, +channels, and view counts of the top 10 trending YouTube videos in India. You can change the regionCode to any other country code if needed. Then, you can use the following code: -''' +""" from googleapiclient.discovery import build # Replace with your own API key -API_KEY = 'YOUR_API_KEY' -YOUTUBE_API_SERVICE_NAME = 'youtube' -YOUTUBE_API_VERSION = 'v3' +API_KEY = "YOUR_API_KEY" +YOUTUBE_API_SERVICE_NAME = "youtube" +YOUTUBE_API_VERSION = "v3" + def get_trending_videos(): youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=API_KEY) - + # Call the API to get the top 10 trending videos request = youtube.videos().list( - part='snippet,statistics', - chart='mostPopular', - regionCode='IN', # Change this to your region code - maxResults=10 + part="snippet,statistics", + chart="mostPopular", + regionCode="IN", # Change this to your region code + maxResults=10, ) response = request.execute() - + # Print the video details - for item in response['items']: - title = item['snippet']['title'] - channel = item['snippet']['channelTitle'] - views = item['statistics']['viewCount'] - print(f'Title: {title}\nChannel: {channel}\nViews: {views}\n') + for item in response["items"]: + title = item["snippet"]["title"] + channel = item["snippet"]["channelTitle"] + views = item["statistics"]["viewCount"] + print(f"Title: {title}\nChannel: {channel}\nViews: {views}\n") + -if __name__ == '__main__': +if __name__ == "__main__": get_trending_videos() diff --git a/Triplets with zero sum/find_Triplets_with_zero_sum.py b/Triplets with zero sum/find_Triplets_with_zero_sum.py index 2a2d2b7688d..f88c6538a15 100644 --- a/Triplets with zero sum/find_Triplets_with_zero_sum.py +++ b/Triplets with zero sum/find_Triplets_with_zero_sum.py @@ -1,12 +1,12 @@ """ - Author : Mohit Kumar - - Python program to find triplets in a given array whose sum is zero +Author : Mohit Kumar + +Python program to find triplets in a given array whose sum is zero """ + # function to print triplets with 0 sum def find_Triplets_with_zero_sum(arr, num): - """find triplets in a given array whose sum is zero Parameteres : @@ -24,7 +24,6 @@ def find_Triplets_with_zero_sum(arr, num): # Run a loop until l is less than r, if the sum of array[l], array[r] is equal to zero then print the triplet and break the loop for index in range(0, num - 1): - # initialize left and right left = index + 1 right = num - 1 @@ -32,7 +31,6 @@ def find_Triplets_with_zero_sum(arr, num): curr = arr[index] # current element while left < right: - temp = curr + arr[left] + arr[right] if temp == 0: @@ -59,7 +57,6 @@ def find_Triplets_with_zero_sum(arr, num): # DRIVER CODE STARTS if __name__ == "__main__": - n = int(input("Enter size of array\n")) print("Enter elements of array\n") diff --git a/Turn your PDFs into audio books/requirements.txt b/Turn your PDFs into audio books/requirements.txt deleted file mode 100644 index 5ba5e21515e..00000000000 --- a/Turn your PDFs into audio books/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -PyPDF2 -pyttsx3 diff --git a/Turtle_Star.py b/Turtle_Star.py index 49ce64cb949..d9b1a3b06ef 100644 --- a/Turtle_Star.py +++ b/Turtle_Star.py @@ -1,29 +1,29 @@ import turtle - + board = turtle.Turtle() - + # first triangle for star -board.forward(100) # draw base - +board.forward(100) # draw base + board.left(120) board.forward(100) - + board.left(120) board.forward(100) - + board.penup() board.right(150) board.forward(50) - + # second triangle for star board.pendown() board.right(90) board.forward(100) - + board.right(120) board.forward(100) - + board.right(120) board.forward(100) - + turtle.done() diff --git a/Tweet Pre-Processing.py b/Tweet Pre-Processing.py index 458e04c4e41..7cd24e71aa4 100644 --- a/Tweet Pre-Processing.py +++ b/Tweet Pre-Processing.py @@ -1,12 +1,11 @@ #!/usr/bin/env python -# coding: utf-8 # In[10]: -from nltk.corpus import twitter_samples import random +from nltk.corpus import twitter_samples # In[ ]: @@ -58,7 +57,6 @@ from nltk.stem import PorterStemmer from nltk.tokenize import TweetTokenizer - # In[20]: diff --git a/Untitled.ipynb b/Untitled.ipynb index 4d36111e1e4..0e68692ed47 100644 --- a/Untitled.ipynb +++ b/Untitled.ipynb @@ -6,15 +6,16 @@ "metadata": {}, "outputs": [], "source": [ - "import cv2\n", "import time\n", + "\n", + "import cv2\n", "import numpy as np\n", "\n", "## Preparation for writing the ouput video\n", - "fourcc = cv2.VideoWriter_fourcc(*'XVID')\n", - "out = cv2.VideoWriter('output.avi',fourcc,20.0, (640,480))\n", + "fourcc = cv2.VideoWriter_fourcc(*\"XVID\")\n", + "out = cv2.VideoWriter(\"output.avi\", fourcc, 20.0, (640, 480))\n", "\n", - "##reading from the webcam \n", + "##reading from the webcam\n", "cap = cv2.VideoCapture(0)\n", "\n", "## Allow the system to sleep for 3 seconds before the webcam starts\n", @@ -24,31 +25,31 @@ "\n", "## Capture the background in range of 60\n", "for i in range(60):\n", - " ret,background = cap.read()\n", - "background = np.flip(background,axis=1)\n", + " ret, background = cap.read()\n", + "background = np.flip(background, axis=1)\n", "\n", "\n", "## Read every frame from the webcam, until the camera is open\n", - "while(cap.isOpened()):\n", + "while cap.isOpened():\n", " ret, img = cap.read()\n", " if not ret:\n", " break\n", - " count+=1\n", - " img = np.flip(img,axis=1)\n", - " \n", + " count += 1\n", + " img = np.flip(img, axis=1)\n", + "\n", " ## Convert the color space from BGR to HSV\n", " hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)\n", "\n", " ## Generat masks to detect red color\n", - " lower_red = np.array([0,120,50])\n", - " upper_red = np.array([10,255,255])\n", - " mask1 = cv2.inRange(hsv,lower_red,upper_red)\n", + " lower_red = np.array([0, 120, 50])\n", + " upper_red = np.array([10, 255, 255])\n", + " mask1 = cv2.inRange(hsv, lower_red, upper_red)\n", "\n", - " lower_red = np.array([170,120,70])\n", - " upper_red = np.array([180,255,255])\n", - " mask2 = cv2.inRange(hsv,lower_red,upper_red)\n", + " lower_red = np.array([170, 120, 70])\n", + " upper_red = np.array([180, 255, 255])\n", + " mask2 = cv2.inRange(hsv, lower_red, upper_red)\n", "\n", - " mask1 = mask1+mask2" + " mask1 = mask1 + mask2" ] } ], diff --git a/Voice Command Calculator.py b/Voice Command Calculator.py index ccc6e6c6496..c453e1ddf8d 100644 --- a/Voice Command Calculator.py +++ b/Voice Command Calculator.py @@ -1,32 +1,38 @@ import operator + import speech_recognition as s_r -print("Your speech_recognition version is: "+s_r.__version__) + +print("Your speech_recognition version is: " + s_r.__version__) r = s_r.Recognizer() my_mic_device = s_r.Microphone(device_index=1) with my_mic_device as source: print("Say what you want to calculate, example: 3 plus 3") r.adjust_for_ambient_noise(source) audio = r.listen(source) -my_string=r.recognize_google(audio) +my_string = r.recognize_google(audio) print(my_string) + + def get_operator_fn(op): return { - '+' : operator.add, - '-' : operator.sub, - 'x' : operator.mul, - 'divided' :operator.__truediv__, - 'divided by' :operator.__truediv__, - 'divide' :operator.__truediv__, - 'Divided' :operator.__truediv__, - 'Divided by' :operator.__truediv__, - 'Divide' :operator.__truediv__, - 'Mod' : operator.mod, - 'mod' : operator.mod, - '^' : operator.xor, - }[op] + "+": operator.add, + "-": operator.sub, + "x": operator.mul, + "divided": operator.__truediv__, + "divided by": operator.__truediv__, + "divide": operator.__truediv__, + "Divided": operator.__truediv__, + "Divided by": operator.__truediv__, + "Divide": operator.__truediv__, + "Mod": operator.mod, + "mod": operator.mod, + "^": operator.xor, + }[op] + def eval_binary_expr(op1, oper, op2): - op1,op2 = int(op1), int(op2) + op1, op2 = int(op1), int(op2) return get_operator_fn(oper)(op1, op2) + print(eval_binary_expr(*(my_string.split()))) diff --git a/VoiceAssistant/Project_Basic_struct/TextTospeech.py b/VoiceAssistant/Project_Basic_struct/TextTospeech.py index a6ef7645628..2bcc7f29b39 100644 --- a/VoiceAssistant/Project_Basic_struct/TextTospeech.py +++ b/VoiceAssistant/Project_Basic_struct/TextTospeech.py @@ -1,11 +1,10 @@ import win32com + def tts(): - audio = 'speech.mp3' - language = 'en' + audio = "speech.mp3" + language = "en" sentence = input("Enter the text to be spoken :- ") - + speaker = win32com.client.Dispatch("SAPI.SpVoice") sp = speaker.Speak(sentence) - - diff --git a/VoiceAssistant/Project_Basic_struct/VoiceAssistant_main.py b/VoiceAssistant/Project_Basic_struct/VoiceAssistant_main.py index 1c2baf70897..6e0c4bf04a1 100644 --- a/VoiceAssistant/Project_Basic_struct/VoiceAssistant_main.py +++ b/VoiceAssistant/Project_Basic_struct/VoiceAssistant_main.py @@ -1,20 +1,20 @@ -from speakListen import * -from websiteWork import * -from textRead import * from dictator import * from menu import * -from speechtotext import * +from speakListen import * +from textRead import * from TextTospeech import * +from websiteWork import * + +from speechtotext import * def main(): start = 0 end = 0 if start == 0: - print("\nSay \"Hello Python\" to activate the Voice Assistant!") + print('\nSay "Hello Python" to activate the Voice Assistant!') start += 1 while True: - q = short_hear().lower() if "close" in q: greet("end") @@ -23,7 +23,6 @@ def main(): greet("start") print_menu() while True: - query = hear().lower() if "close" in query: greet("end") @@ -32,34 +31,51 @@ def main(): elif "text to speech" in query: tts() time.sleep(4) - - elif "search on google" in query or "search google" in query or "google" in query: + elif ( + "search on google" in query + or "search google" in query + or "google" in query + ): google_search() time.sleep(10) - - elif "search on wikipedia" in query or "search wikipedia" in query or "wikipedia" in query: + + elif ( + "search on wikipedia" in query + or "search wikipedia" in query + or "wikipedia" in query + ): wiki_search() time.sleep(10) - + elif "word" in query: ms_word() time.sleep(5) - + elif "book" in query: pdf_read() time.sleep(10) - + elif "speech to text" in query: big_text() time.sleep(5) - + else: print("I could'nt understand what you just said!") speak("I could'nt understand what you just said!") - - print("\nDo you want to continue? if yes then say " + Fore.YELLOW + "\"YES\"" + Fore.WHITE + " else say " + Fore.YELLOW + "\"CLOSE PYTHON\"") - speak("Do you want to continue? if yes then say YES else say CLOSE PYTHON") + + print( + "\nDo you want to continue? if yes then say " + + Fore.YELLOW + + '"YES"' + + Fore.WHITE + + " else say " + + Fore.YELLOW + + '"CLOSE PYTHON"' + ) + speak( + "Do you want to continue? if yes then say YES else say CLOSE PYTHON" + ) qry = hear().lower() if "yes" in qry: print_menu() @@ -75,4 +91,5 @@ def main(): else: continue + main() diff --git a/VoiceAssistant/Project_Basic_struct/dictator.py b/VoiceAssistant/Project_Basic_struct/dictator.py index 3ceb4f1ce76..a99f5125b6e 100644 --- a/VoiceAssistant/Project_Basic_struct/dictator.py +++ b/VoiceAssistant/Project_Basic_struct/dictator.py @@ -1,20 +1,26 @@ # from speakListen import hear # from speakListen import long_hear +from colorama import Fore from speakListen import * -from colorama import Fore def big_text(): - print("By default, I will record your voice for 60 seconds.\nDo you want to change this default timing?") - speak("By default, I will record your voice for 60 seconds.\nDo you want to change this default timing?") + print( + "By default, I will record your voice for 60 seconds.\nDo you want to change this default timing?" + ) + speak( + "By default, I will record your voice for 60 seconds.\nDo you want to change this default timing?" + ) print(Fore.YELLOW + "Yes or No") query = hear().lower() duration_time = 0 - if "yes" in query or "es" in query or "ye" in query or "s" in query: - - print("Please enter the time(in seconds) for which I shall record your speech - ", end = '') + if "yes" in query or "es" in query or "ye" in query or "s" in query: + print( + "Please enter the time(in seconds) for which I shall record your speech - ", + end="", + ) duration_time = int(input().strip()) print("\n") @@ -24,6 +30,7 @@ def big_text(): text = long_hear(duration_time) print("\n" + Fore.LIGHTCYAN_EX + text) + def colours(): text = "Colour" print(Fore.BLACK + text) @@ -43,5 +50,6 @@ def colours(): print(Fore.LIGHTCYAN_EX + text) print(Fore.LIGHTWHITE_EX + text) -#big_text() -#colours() \ No newline at end of file + +# big_text() +# colours() diff --git a/VoiceAssistant/Project_Basic_struct/menu.py b/VoiceAssistant/Project_Basic_struct/menu.py index 8512271c0d2..4261a3cf025 100644 --- a/VoiceAssistant/Project_Basic_struct/menu.py +++ b/VoiceAssistant/Project_Basic_struct/menu.py @@ -1,13 +1,12 @@ -from rich.console import Console # pip3 install Rich +from rich.console import Console # pip3 install Rich from rich.table import Table from speakListen import * def print_menu(): - """Display a table with list of tasks and their associated commands. - """ + """Display a table with list of tasks and their associated commands.""" speak("I can do the following") - table = Table(title="\nI can do the following :- ", show_lines = True) + table = Table(title="\nI can do the following :- ", show_lines=True) table.add_column("Sr. No.", style="cyan", no_wrap=True) table.add_column("Task", style="yellow") @@ -24,4 +23,5 @@ def print_menu(): console = Console() console.print(table) -#print_menu() \ No newline at end of file + +# print_menu() diff --git a/VoiceAssistant/Project_Basic_struct/speakListen.py b/VoiceAssistant/Project_Basic_struct/speakListen.py index 5f4ca0edadf..c913f0ad1bf 100644 --- a/VoiceAssistant/Project_Basic_struct/speakListen.py +++ b/VoiceAssistant/Project_Basic_struct/speakListen.py @@ -1,14 +1,14 @@ +import datetime import time -from colorama import Fore -import speech_recognition as sr + import pyttsx3 -import datetime +import speech_recognition as sr +from colorama import Fore from rich.progress import Progress - -python = pyttsx3.init("sapi5") # name of the engine is set as Python +python = pyttsx3.init("sapi5") # name of the engine is set as Python voices = python.getProperty("voices") -#print(voices) +# print(voices) python.setProperty("voice", voices[1].id) python.setProperty("rate", 140) @@ -18,151 +18,165 @@ def speak(text): Args: text ([str]): [It is the speech to be spoken] - """ + """ python.say(text) python.runAndWait() + def greet(g): """Uses the datetime library to generate current time and then greets accordingly. - + Args: g (str): To decide whether to say hello or good bye """ if g == "start" or g == "s": h = datetime.datetime.now().hour - text = '' + text = "" if h > 12 and h < 17: text = "Hello ! Good Afternoon " elif h < 12 and h > 0: text = "Hello! Good Morning " - elif h >= 17 : + elif h >= 17: text = "Hello! Good Evening " text += " I am Python, How may i help you ?" - speak(text) - + speak(text) + elif g == "quit" or g == "end" or g == "over" or g == "e": - text = 'Thank you!. Good Bye ! ' + text = "Thank you!. Good Bye ! " speak(text) + def hear(): """[It will process the speech of user using Google_Speech_Recognizer(recognize_google)] Returns: [str]: [Speech of user as a string in English(en - IN)] - """ + """ r = sr.Recognizer() """Reconizer is a class which has lot of functions related to Speech i/p and o/p. """ - r.pause_threshold = 1 # a pause of more than 1 second will stop the microphone temporarily - r.energy_threshold = 300 # python by default sets it to 300. It is the minimum input energy to be considered. - r.dynamic_energy_threshold = True # pyhton now can dynamically change the threshold energy + r.pause_threshold = ( + 1 # a pause of more than 1 second will stop the microphone temporarily + ) + r.energy_threshold = 300 # python by default sets it to 300. It is the minimum input energy to be considered. + r.dynamic_energy_threshold = ( + True # pyhton now can dynamically change the threshold energy + ) with sr.Microphone() as source: # read the audio data from the default microphone print(Fore.RED + "\nListening...") - #time.sleep(0.5) + # time.sleep(0.5) - speech = r.record(source, duration = 9) # option - #speech = r.listen(source) + speech = r.record(source, duration=9) # option + # speech = r.listen(source) # convert speech to text try: - #print("Recognizing...") + # print("Recognizing...") recognizing() speech = r.recognize_google(speech) print(speech + "\n") - + except Exception as exception: print(exception) return "None" return speech + def recognizing(): - """Uses the Rich library to print a simulates version of "recognizing" by printing a loading bar. - """ + """Uses the Rich library to print a simulates version of "recognizing" by printing a loading bar.""" with Progress() as pr: - rec = pr.add_task("[red]Recognizing...", total = 100) + rec = pr.add_task("[red]Recognizing...", total=100) while not pr.finished: - pr.update(rec, advance = 1.0) + pr.update(rec, advance=1.0) time.sleep(0.01) -def long_hear(duration_time = 60): + +def long_hear(duration_time=60): """[It will process the speech of user using Google_Speech_Recognizer(recognize_google)] the difference between the hear() and long_hear() is that - the hear() - records users voice for 9 seconds long_hear() - will record user's voice for the time specified by user. By default, it records for 60 seconds. Returns: [str]: [Speech of user as a string in English(en - IN)] - """ + """ r = sr.Recognizer() """Reconizer is a class which has lot of functions related to Speech i/p and o/p. """ - r.pause_threshold = 1 # a pause of more than 1 second will stop the microphone temporarily - r.energy_threshold = 300 # python by default sets it to 300. It is the minimum input energy to be considered. - r.dynamic_energy_threshold = True # pyhton now can dynamically change the threshold energy + r.pause_threshold = ( + 1 # a pause of more than 1 second will stop the microphone temporarily + ) + r.energy_threshold = 300 # python by default sets it to 300. It is the minimum input energy to be considered. + r.dynamic_energy_threshold = ( + True # pyhton now can dynamically change the threshold energy + ) with sr.Microphone() as source: # read the audio data from the default microphone print(Fore.RED + "\nListening...") - #time.sleep(0.5) + # time.sleep(0.5) - speech = r.record(source, duration = duration_time) # option - #speech = r.listen(source) + speech = r.record(source, duration=duration_time) # option + # speech = r.listen(source) # convert speech to text try: - print(Fore.RED +"Recognizing...") - #recognizing() + print(Fore.RED + "Recognizing...") + # recognizing() speech = r.recognize_google(speech) - #print(speech + "\n") - + # print(speech + "\n") + except Exception as exception: - print(exception) + print(exception) return "None" return speech -def short_hear(duration_time = 5): + +def short_hear(duration_time=5): """[It will process the speech of user using Google_Speech_Recognizer(recognize_google)] the difference between the hear() and long_hear() is that - the hear() - records users voice for 9 seconds long_hear - will record user's voice for the time specified by user. By default, it records for 60 seconds. Returns: [str]: [Speech of user as a string in English(en - IN)] - """ + """ r = sr.Recognizer() """Reconizer is a class which has lot of functions related to Speech i/p and o/p. """ - r.pause_threshold = 1 # a pause of more than 1 second will stop the microphone temporarily - r.energy_threshold = 300 # python by default sets it to 300. It is the minimum input energy to be considered. - r.dynamic_energy_threshold = True # pyhton now can dynamically change the threshold energy + r.pause_threshold = ( + 1 # a pause of more than 1 second will stop the microphone temporarily + ) + r.energy_threshold = 300 # python by default sets it to 300. It is the minimum input energy to be considered. + r.dynamic_energy_threshold = ( + True # pyhton now can dynamically change the threshold energy + ) with sr.Microphone() as source: # read the audio data from the default microphone print(Fore.RED + "\nListening...") - #time.sleep(0.5) + # time.sleep(0.5) - speech = r.record(source, duration = duration_time) # option - #speech = r.listen(source) + speech = r.record(source, duration=duration_time) # option + # speech = r.listen(source) # convert speech to text try: - print(Fore.RED +"Recognizing...") - #recognizing() + print(Fore.RED + "Recognizing...") + # recognizing() speech = r.recognize_google(speech) - #print(speech + "\n") - + # print(speech + "\n") + except Exception as exception: - print(exception) + print(exception) return "None" return speech - -if __name__ == '__main__': +if __name__ == "__main__": # print("Enter your name") # name = hear() # speak("Hello " + name) # greet("s") # greet("e") pass - #hear() - #recognizing() - + # hear() + # recognizing() diff --git a/VoiceAssistant/Project_Basic_struct/speechtotext.py b/VoiceAssistant/Project_Basic_struct/speechtotext.py index 1b1974c8b79..e73a55eaf32 100644 --- a/VoiceAssistant/Project_Basic_struct/speechtotext.py +++ b/VoiceAssistant/Project_Basic_struct/speechtotext.py @@ -1,6 +1,9 @@ import speech_recognition as sr + # initialize the recognizer r = sr.Recognizer() + + def stt(): with sr.Microphone() as source: # read the audio data from the default microphone @@ -8,4 +11,4 @@ def stt(): print("Recognizing...") # convert speech to text text = r.recognize_google(audio_data) - print(text) \ No newline at end of file + print(text) diff --git a/VoiceAssistant/Project_Basic_struct/textRead.py b/VoiceAssistant/Project_Basic_struct/textRead.py index 030c78501f0..c0736c2b378 100644 --- a/VoiceAssistant/Project_Basic_struct/textRead.py +++ b/VoiceAssistant/Project_Basic_struct/textRead.py @@ -1,169 +1,211 @@ -from speakListen import hear -from speakListen import speak +import time + import docx import fitz -import time -from rich.console import Console # pip3 install Rich -from rich.table import Table from colorama import Fore +from rich.console import Console # pip3 install Rich +from rich.table import Table +from speakListen import hear, speak + def ms_word(): - """[Print and speak out a ms_word docx file as specified in the path] - """ + """[Print and speak out a ms_word docx file as specified in the path]""" # TODO : Take location input from the user try: speak("Enter the document's location - ") location = input("Enter the document's location - ") - - file_loc = doubleslash(location) - + + file_loc = doubleslash(location) + doc = docx.Document(file_loc) fullText = [] for para in doc.paragraphs: fullText.append(para.text) - #print(fullText) - doc_file = '\n'.join(fullText) + # print(fullText) + doc_file = "\n".join(fullText) print(doc_file) speak(doc_file) except Exception as exp: - #print(exp) + # print(exp) print(f"ERROR - {exp}") - print(Fore.YELLOW + "I could'nt locate the file!\nIf you didn't specify the extension of the file, please specify it.") + print( + Fore.YELLOW + + "I could'nt locate the file!\nIf you didn't specify the extension of the file, please specify it." + ) return "None" + def pdf_read(): - """[Print and speak out the pdf on specified path] - """ + """[Print and speak out the pdf on specified path]""" try: speak("Enter the document's location - ") location = input("Enter the document's location - ") - - path = doubleslash(location) + + path = doubleslash(location) pdf = fitz.open(path) - details = pdf.metadata # Stores the meta-data which generally includes Author name and Title of book/document. - total_pages = pdf.pageCount # Stores the total number of pages + details = pdf.metadata # Stores the meta-data which generally includes Author name and Title of book/document. + total_pages = pdf.pageCount # Stores the total number of pages except Exception as exp: print(f"ERROR - {exp}") - print(Fore.YELLOW + "I could'nt locate the file!\nIf you didn't specify the extension of the file, please specify it.") + print( + Fore.YELLOW + + "I could'nt locate the file!\nIf you didn't specify the extension of the file, please specify it." + ) return "None" - try : + try: """ 1. Author 2. Creator 3. Producer - 4. Title """ - - author = details["author"] - #print("Author : ",author) - + 4. Title """ + + author = details["author"] + # print("Author : ",author) + title = details["title"] - #print("Title : ",title) - - #print(details) - #print("Total Pages : ",total_pages) + # print("Title : ",title) + + # print(details) + # print("Total Pages : ",total_pages) book_details(author, title, total_pages) speak(f" Title {title}") speak(f" Author {author}") speak(f" Total Pages {total_pages}") - + # TODO : Deal with the Index toc = pdf.get_toc() - print("Say 1 or \"ONLY PRINT INDEX\" - if you want me to print the book's index.\nSay 2 if you want me to print and make me speak out the book's index.\nSay any key if you don't want to print the index.'") - speak("Say 1 or only print index if you want me to print the book's index.\nSay 2 if you want me to print and make me speak out the book's index.\nSay any key if you don't want to print the index.'") + print( + "Say 1 or \"ONLY PRINT INDEX\" - if you want me to print the book's index.\nSay 2 if you want me to print and make me speak out the book's index.\nSay any key if you don't want to print the index.'" + ) + speak( + "Say 1 or only print index if you want me to print the book's index.\nSay 2 if you want me to print and make me speak out the book's index.\nSay any key if you don't want to print the index.'" + ) q = hear().lower() - if "only print" in q or "1" in q or "one" in q or "vone" in q or 'only' in q or "index only" in q or 'only' in q or "print only" in q: + if ( + "only print" in q + or "1" in q + or "one" in q + or "vone" in q + or "only" in q + or "index only" in q + or "only" in q + or "print only" in q + ): print_index(toc) time.sleep(15) - elif "speak" in q or "2" in q or 'two' in q: + elif "speak" in q or "2" in q or "two" in q: print_n_speak_index(toc) time.sleep(10) elif q == "None": print("I could'nt understand what you just said!") speak("I could'nt understand what you just said!") time.sleep(4) - else: + else: time.sleep(4) pass - """Allow the user to do the following 1. Read/speak a page 2. Read/speak a range of pages 3. Lesson 4. Read/speak a whole book - """ - - #time.sleep(5) - - print("____________________________________________________________________________________________________________") - print("1. Print/speak a single page\n2. Print/speak a range of pages\n3. Print/speak a Lesson\n4. Read/speak a whole book") - speak("1. Print/speak a single page\n2. Print/speak a range of pages\n3. Print/speak a Lesson\n4. Read/speak a whole book") + """ + + # time.sleep(5) + + print( + "____________________________________________________________________________________________________________" + ) + print( + "1. Print/speak a single page\n2. Print/speak a range of pages\n3. Print/speak a Lesson\n4. Read/speak a whole book" + ) + speak( + "1. Print/speak a single page\n2. Print/speak a range of pages\n3. Print/speak a Lesson\n4. Read/speak a whole book" + ) q = hear().lower() - if "single" in q or "one" in q or "vone" in q or "one page" in q or "vone page" in q or "1 page" in q: + if ( + "single" in q + or "one" in q + or "vone" in q + or "one page" in q + or "vone page" in q + or "1 page" in q + ): try: pgno = int(input("Page Number - ")) page = pdf.load_page(pgno - 1) - text = page.get_text('text') + text = page.get_text("text") print("\n\n") - print(text.replace('\t',' ')) - speak(text.replace('\t',' ')) + print(text.replace("\t", " ")) + speak(text.replace("\t", " ")) except Exception: - print("Sorry, I could recognize what you entered. Please re-enter the Page Number.") - speak("Sorry, I could recognize what you entered. Please re-enter the Page Number.") + print( + "Sorry, I could recognize what you entered. Please re-enter the Page Number." + ) + speak( + "Sorry, I could recognize what you entered. Please re-enter the Page Number." + ) pgno = input("Page no. - ") page = pdf.load_page(pgno - 1) - text = page.get_text('text') - print(text.replace('\t',' ')) - speak(text.replace('\t',' ')) + text = page.get_text("text") + print(text.replace("\t", " ")) + speak(text.replace("\t", " ")) - - elif 'range' in q or "multiple" in q: + elif "range" in q or "multiple" in q: try: start_pg_no = int(input("Starting Page Number - ")) end_pg_no = int(input("End Page Number - ")) for i in range(start_pg_no - 1, end_pg_no): page = pdf.load_page(i) - text = page.get_text('text') - print(text.replace('\t',' ')) - speak(text.replace('\t',' ')) + text = page.get_text("text") + print(text.replace("\t", " ")) + speak(text.replace("\t", " ")) except Exception: - print("Sorry, I could recognize what you entered. Please re-enter the Page Number.") - speak("Sorry, I could recognize what you entered. Please re-enter the Page Number.") + print( + "Sorry, I could recognize what you entered. Please re-enter the Page Number." + ) + speak( + "Sorry, I could recognize what you entered. Please re-enter the Page Number." + ) start_pg_no = int(input("Starting Page Number - ")) end_pg_no = int(input("End Page Number - ")) for i in range(start_pg_no - 1, end_pg_no - 1): page = pdf.load_page(i) - text = page.get_text('text') - print(text.replace('\t',' ')) - speak(text.replace('\t',' ')) + text = page.get_text("text") + print(text.replace("\t", " ")) + speak(text.replace("\t", " ")) - elif 'lesson' in q: + elif "lesson" in q: try: key = input("Lesson name - ") start_pg_no, end_pg_no = search_in_toc(toc, key, total_pages) if start_pg_no != None and end_pg_no != None: - start_pg_no, end_pg_no = map(int,search_in_toc(toc, key, total_pages)) - + start_pg_no, end_pg_no = map( + int, search_in_toc(toc, key, total_pages) + ) + for i in range(start_pg_no - 1, end_pg_no): page = pdf.load_page(i) - text = page.get_text('text') - print(text.replace('\t',' ')) - speak(text.replace('\t',' ')) - else: + text = page.get_text("text") + print(text.replace("\t", " ")) + speak(text.replace("\t", " ")) + else: print("Try Again.") speak("Try Again.") speak("Lesson name") key = input("Lesson name - ") - start_pg_no, end_pg_no = map(int,search_in_toc(toc, key, total_pages)) + start_pg_no, end_pg_no = map( + int, search_in_toc(toc, key, total_pages) + ) if start_pg_no != None and end_pg_no != None: for i in range(start_pg_no - 1, end_pg_no): page = pdf.load_page(i) - text = page.get_text('text') - print(text.replace('\t',' ')) - speak(text.replace('\t',' ')) - + text = page.get_text("text") + print(text.replace("\t", " ")) + speak(text.replace("\t", " ")) + except Exception: print("Try Again! Lesson could not be found.") speak("Try Again.Lesson could not be found") @@ -171,23 +213,25 @@ def pdf_read(): key = input("Lesson name - ") start_pg_no, end_pg_no = search_in_toc(toc, key, total_pages) if start_pg_no != None and end_pg_no != None: - start_pg_no, end_pg_no = map(int,search_in_toc(toc, key, total_pages)) - + start_pg_no, end_pg_no = map( + int, search_in_toc(toc, key, total_pages) + ) + for i in range(start_pg_no - 1, end_pg_no): page = pdf.load_page(i) - text = page.get_text('text') - print(text.replace('\t',' ')) - speak(text.replace('\t',' ')) - else: + text = page.get_text("text") + print(text.replace("\t", " ")) + speak(text.replace("\t", " ")) + else: print("Sorry, I cannot find the perticular lesson.") speak("Sorry, I cannot find the perticular lesson.") - elif "whole" in q or 'complete' in q: + elif "whole" in q or "complete" in q: for i in range(total_pages): page = pdf.load_page(i) - text = page.get_text('text') - print(text.replace('\t',' ')) - speak(text.replace('\t',' ')) + text = page.get_text("text") + print(text.replace("\t", " ")) + speak(text.replace("\t", " ")) elif q == "None": print("I could'nt understand what you just said!") @@ -195,13 +239,14 @@ def pdf_read(): else: print("You didn't say a valid command!") time.sleep(5) - except Exception as e: + except Exception as e: print(e) pass pdf.close() + def doubleslash(text): - """Replaces / with // + """Replaces / with // Args: text (str): location @@ -209,7 +254,8 @@ def doubleslash(text): Returns: str: formatted location """ - return text.replace('\\' , '\\\\') + return text.replace("\\", "\\\\") + def print_index(toc): """Prints out the index in proper format with title name and page number @@ -218,14 +264,15 @@ def print_index(toc): toc (nested list): toc[1] - Topic name toc[2] - Page number """ - dash = "-"*(100 - 7) - space = " "*47 + dash = "-" * (100 - 7) + space = " " * 47 print(f"{space}INDEX") print(f"\n\nName : {dash} PageNo.\n\n\n") for topic in toc: - eq_dash = "-"*(100 - len(topic[1])) + eq_dash = "-" * (100 - len(topic[1])) print(f"{topic[1]} {eq_dash} {topic[2]}") - + + def print_n_speak_index(toc): """Along with printing, it speaks out the index too. @@ -233,15 +280,16 @@ def print_n_speak_index(toc): toc (nested list): toc[1] - Topic name toc[2] - Page number """ - dash = "-"*(100 - 7) - space = " "*47 + dash = "-" * (100 - 7) + space = " " * 47 print(f"{space}INDEX") print(f"\n\nName : {dash} PageNo.\n\n\n\n") for topic in toc: - eq_dash = "-"*(100 - len(topic[1])) + eq_dash = "-" * (100 - len(topic[1])) print(f"{topic[1]} {eq_dash} {topic[2]}") speak(f"{topic[1]} {topic[2]}") + def search_in_toc(toc, key, totalpg): """Searches a particular lesson name provided as a parameter in toc and returns its starting and ending page numbers. @@ -258,19 +306,14 @@ def search_in_toc(toc, key, totalpg): for i in range(len(toc) - 1): topic = toc[i] if i != len(toc) - 2: - if topic[1] == key: - nexttopic = toc[i + 1] - return (topic[2], nexttopic[2]) - elif topic[1].lower() == key: + if topic[1] == key or topic[1].lower() == key: nexttopic = toc[i + 1] return (topic[2], nexttopic[2]) else: - if topic[1] == key: + if topic[1] == key or topic[1].lower() == key: return (topic[2], totalpg) - elif topic[1].lower() == key: - - return (topic[2], totalpg) - return None,None + return None, None + def book_details(author, title, total_pages): """Creates a table of book details like author name, title, and total pages. @@ -280,7 +323,7 @@ def book_details(author, title, total_pages): title (str): title of the book total_pages (int): total pages in the book """ - table = Table(title="\nBook Details :- ", show_lines = True) + table = Table(title="\nBook Details :- ", show_lines=True) table.add_column("Sr. No.", style="magenta", no_wrap=True) table.add_column("Property", style="cyan") @@ -292,7 +335,8 @@ def book_details(author, title, total_pages): console = Console() console.print(table) - -#ms_word() -#pdf_read() -#book_details("abc", "abcde", 12) + + +# ms_word() +# pdf_read() +# book_details("abc", "abcde", 12) diff --git a/VoiceAssistant/Project_Basic_struct/websiteWork.py b/VoiceAssistant/Project_Basic_struct/websiteWork.py index 501d691eaba..dbe4ade26d7 100644 --- a/VoiceAssistant/Project_Basic_struct/websiteWork.py +++ b/VoiceAssistant/Project_Basic_struct/websiteWork.py @@ -1,45 +1,42 @@ -from speakListen import hear -from speakListen import speak - +from speakListen import hear, speak """ 1. speakListen.speak(text) 2. speakListen.greet() 3. speakListen.hear() """ -import wikipedia import webbrowser +import wikipedia + def google_search(): - """[Goes to google and searches the website asked by the user] - """ + """[Goes to google and searches the website asked by the user]""" google_search_link = "https://www.google.co.in/search?q=" google_search = "What do you want me to search on Google? " print(google_search) speak(google_search) - + query = hear() if query != "None": - webbrowser.open(google_search_link+query) + webbrowser.open(google_search_link + query) elif query == "None": print("I could'nt understand what you just said!") speak("I could'nt understand what you just said!") + def wiki_search(): - """[Speak out the summary in wikipedia and going to the website according to user's choice.] - """ + """[Speak out the summary in wikipedia and going to the website according to user's choice.]""" wiki_search = "What do you want me to search on Wikipedia? Please tell me the exact sentence or word to Search." wiki_search_link = "https://en.wikipedia.org/wiki/" - + print(wiki_search) speak(wiki_search) query = hear() try: - if query != "None": - results = wikipedia.summary(query, sentences = 2) + results = wikipedia.summary(query, sentences=2) print(results) speak(results) @@ -47,7 +44,16 @@ def wiki_search(): speak("Do you want me to open the Wikipedia page?") q = hear().lower() - if "yes" in q or "okay" in q or "ok" in q or "opun" in q or "opan" in q or "vopen" in q or "es" in q or "s" in q: + if ( + "yes" in q + or "okay" in q + or "ok" in q + or "opun" in q + or "opan" in q + or "vopen" in q + or "es" in q + or "s" in q + ): print(wiki_search_link + query) webbrowser.open(wiki_search_link + query) @@ -58,5 +64,6 @@ def wiki_search(): except Exception: print("Couldn't find") -#wiki_search() -#google_search() + +# wiki_search() +# google_search() diff --git a/VoiceRepeater/__main__.py b/VoiceRepeater/__main__.py index dc3e20a9739..b7d2db7e731 100644 --- a/VoiceRepeater/__main__.py +++ b/VoiceRepeater/__main__.py @@ -1,9 +1,9 @@ +import os +import shutil import time -import speech_recognition as sr -import os import playsound -import shutil +import speech_recognition as sr shutil.rmtree("spoken") os.mkdir("spoken") diff --git a/Weather Scrapper/weather.py b/Weather Scrapper/weather.py index 3980d958bd6..1318e415821 100644 --- a/Weather Scrapper/weather.py +++ b/Weather Scrapper/weather.py @@ -1,32 +1,32 @@ -#TODO - refactor & clean code +# TODO - refactor & clean code import csv import time -from datetime import datetime -from datetime import date +from datetime import date, datetime + from selenium import webdriver -from selenium.webdriver.support.ui import WebDriverWait -from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.action_chains import ActionChains -from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.support.ui import WebDriverWait -#TODO - Add input checking +# TODO - Add input checking city = input("City >") state = input("State >") -url = 'https://www.wunderground.com' +url = "https://www.wunderground.com" -#Supresses warnings and specifies the webdriver to run w/o a GUI +# Supresses warnings and specifies the webdriver to run w/o a GUI options = Options() options.headless = True -options.add_argument('log-level=3') +options.add_argument("log-level=3") driver = webdriver.Chrome(options=options) driver.get(url) -#----------------------------------------------------- +# ----------------------------------------------------- # Connected successfully to the site -#Passes the city and state input to the weather sites search box +# Passes the city and state input to the weather sites search box searchBox = driver.find_element(By.XPATH, '//*[@id="wuSearch"]') location = city + " " + state @@ -34,27 +34,40 @@ action = ActionChains(driver) searchBox.send_keys(location) element = WebDriverWait(driver, 10).until( - EC.presence_of_element_located((By.XPATH, '//*[@id="wuForm"]/search-autocomplete/ul/li[2]/a/span[1]')) + EC.presence_of_element_located( + (By.XPATH, '//*[@id="wuForm"]/search-autocomplete/ul/li[2]/a/span[1]') + ) ) searchBox.send_keys(Keys.RETURN) -#----------------------------------------------------- -#Gather weather data -#City - Time - Date - Temperature - Precipitation - Sky - Wind +# ----------------------------------------------------- +# Gather weather data +# City - Time - Date - Temperature - Precipitation - Sky - Wind -#waits till the page loads to begin gathering data +# waits till the page loads to begin gathering data precipitationElem = WebDriverWait(driver, 10).until( - EC.presence_of_element_located((By.XPATH, '//*[@id="inner-content"]/div[3]/div[1]/div/div[3]/div/lib-city-today-forecast/div/div[1]/div/div/div/a[1]')) + EC.presence_of_element_located( + ( + By.XPATH, + '//*[@id="inner-content"]/div[3]/div[1]/div/div[3]/div/lib-city-today-forecast/div/div[1]/div/div/div/a[1]', + ) + ) +) +precipitationElem = driver.find_element( + By.XPATH, + '//*[@id="inner-content"]/div[3]/div[1]/div/div[3]/div/lib-city-today-forecast/div/div[1]/div/div/div/a[1]', ) -precipitationElem = driver.find_element(By.XPATH, '//*[@id="inner-content"]/div[3]/div[1]/div/div[3]/div/lib-city-today-forecast/div/div[1]/div/div/div/a[1]') precip = "Precipitation:" + precipitationElem.text.split()[0] -windAndSkyElem = driver.find_element(By.XPATH, '//*[@id="inner-content"]/div[3]/div[1]/div/div[3]/div/lib-city-today-forecast/div/div[1]/div/div/div/a[2]') +windAndSkyElem = driver.find_element( + By.XPATH, + '//*[@id="inner-content"]/div[3]/div[1]/div/div[3]/div/lib-city-today-forecast/div/div[1]/div/div/div/a[2]', +) description = windAndSkyElem.text.split(". ") sky = description[0] temp = description[1] wind = description[2] -#Format the date and time +# Format the date and time time = datetime.now().strftime("%H:%M") today = date.today() date = today.strftime("%b-%d-%Y") diff --git a/WeatherGUI.py b/WeatherGUI.py index 19b42994b84..391410c2aa6 100644 --- a/WeatherGUI.py +++ b/WeatherGUI.py @@ -1,4 +1,5 @@ import tkinter as tk + import requests from bs4 import BeautifulSoup diff --git a/Web Socket.py b/Web Socket.py index efb44bbbc21..b499bd0e90d 100644 --- a/Web Socket.py +++ b/Web Socket.py @@ -1,13 +1,14 @@ # Program to print a data & it's Metadata of online uploaded file using "socket". import socket -skt_c=socket.socket(socket.AF_INET,socket.SOCK_STREAM) -skt_c.connect(('data.pr4e.org',80)) -link='GET http://data.pr4e.org/intro-short.txt HTTP/1.0\r\n\r\n'.encode() + +skt_c = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +skt_c.connect(("data.pr4e.org", 80)) +link = b"GET http://data.pr4e.org/intro-short.txt HTTP/1.0\r\n\r\n" skt_c.send(link) while True: - data=skt_c.recv(512) - if len(data)<1: - break - print(data.decode()) + data = skt_c.recv(512) + if len(data) < 1: + break + print(data.decode()) skt_c.close() diff --git a/Web_Scraper.py b/Web_Scraper.py index b489b54096d..1f8fc40a5da 100644 --- a/Web_Scraper.py +++ b/Web_Scraper.py @@ -4,9 +4,10 @@ Requirements: selenium, BeautifulSoup """ +import time + from bs4 import BeautifulSoup from selenium import webdriver -import time # url of the page we want to scrape url = "https://www.naukri.com/top-jobs-by-designations# desigtop600" diff --git a/Webbrowser/tk-browser.py b/Webbrowser/tk-browser.py index cbbfd01bb3e..6dce71d1c5b 100644 --- a/Webbrowser/tk-browser.py +++ b/Webbrowser/tk-browser.py @@ -3,26 +3,29 @@ # Written by Sina Meysami # -from tkinter import * # pip install tk-tools -import tkinterweb # pip install tkinterweb import sys +from tkinter import * # pip install tk-tools + +import tkinterweb # pip install tkinterweb + class Browser(Tk): def __init__(self): - super(Browser,self).__init__() + super(Browser, self).__init__() self.title("Tk Browser") try: browser = tkinterweb.HtmlFrame(self) browser.load_website("https://google.com") - browser.pack(fill="both",expand=True) + browser.pack(fill="both", expand=True) except Exception: sys.exit() - - + + def main(): browser = Browser() browser.mainloop() - + + if __name__ == "__main__": # Webbrowser v1.0 main() diff --git a/Wikipdedia/flask_rendering.py b/Wikipdedia/flask_rendering.py index 05c6d7494bf..984f87c140b 100644 --- a/Wikipdedia/flask_rendering.py +++ b/Wikipdedia/flask_rendering.py @@ -1,13 +1,13 @@ -from flask import Flask, render_template, request import practice_beautifulsoap as data +from flask import Flask, render_template, request -app = Flask(__name__, template_folder='template') +app = Flask(__name__, template_folder="template") -@app.route('/', methods=["GET", "POST"]) +@app.route("/", methods=["GET", "POST"]) def index(): languages = data.lang() - return render_template('index.html', languages=languages) + return render_template("index.html", languages=languages) @app.route("/display", methods=["POST"]) @@ -19,8 +19,13 @@ def output(): soup_data = data.data(entered_topic, selected_language) soup_image = data.get_image_urls(entered_topic) - return render_template('output.html', heading=entered_topic.upper(), data=soup_data, - url=soup_image, language=selected_language) + return render_template( + "output.html", + heading=entered_topic.upper(), + data=soup_data, + url=soup_image, + language=selected_language, + ) if __name__ == "__main__": diff --git a/Wikipdedia/main.py b/Wikipdedia/main.py index 5596b44786f..c937c7cff1b 100644 --- a/Wikipdedia/main.py +++ b/Wikipdedia/main.py @@ -6,11 +6,11 @@ def print_hi(name): # Use a breakpoint in the code line below to debug your script. - print(f'Hi, {name}') # Press Ctrl+F8 to toggle the breakpoint. + print(f"Hi, {name}") # Press Ctrl+F8 to toggle the breakpoint. # Press the green button in the gutter to run the script. -if __name__ == '__main__': - print_hi('PyCharm') +if __name__ == "__main__": + print_hi("PyCharm") # See PyCharm help at https://www.jetbrains.com/help/pycharm/ diff --git a/Wikipdedia/practice_beautifulsoap.py b/Wikipdedia/practice_beautifulsoap.py index 00beb87fc44..4472fb4c9ae 100644 --- a/Wikipdedia/practice_beautifulsoap.py +++ b/Wikipdedia/practice_beautifulsoap.py @@ -1,5 +1,5 @@ -from bs4 import BeautifulSoup import requests +from bs4 import BeautifulSoup language_symbols = {} @@ -8,11 +8,11 @@ def lang(): try: response = requests.get("https://www.wikipedia.org/") response.raise_for_status() - soup = BeautifulSoup(response.content, 'html.parser') + soup = BeautifulSoup(response.content, "html.parser") - for option in soup.find_all('option'): + for option in soup.find_all("option"): language = option.text - symbol = option['lang'] + symbol = option["lang"] language_symbols[language] = symbol return list(language_symbols.keys()) @@ -29,17 +29,19 @@ def data(selected_topic, selected_language): url = f"https://{symbol}.wikipedia.org/wiki/{selected_topic}" data_response = requests.get(url) data_response.raise_for_status() - data_soup = BeautifulSoup(data_response.content, 'html.parser') + data_soup = BeautifulSoup(data_response.content, "html.parser") - main_content = data_soup.find('div', {'id': 'mw-content-text'}) + main_content = data_soup.find("div", {"id": "mw-content-text"}) filtered_content = "" if main_content: for element in main_content.descendants: - if element.name in ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']: - filtered_content += "\n" + element.get_text(strip=True).upper() + "\n" + if element.name in ["h1", "h2", "h3", "h4", "h5", "h6"]: + filtered_content += ( + "\n" + element.get_text(strip=True).upper() + "\n" + ) - elif element.name == 'p': + elif element.name == "p": filtered_content += element.get_text(strip=True) + "\n" return filtered_content @@ -54,11 +56,11 @@ def get_image_urls(query): search_url = f"https://www.google.com/search?q={query}&tbm=isch" image_response = requests.get(search_url) image_response.raise_for_status() - image_soup = BeautifulSoup(image_response.content, 'html.parser') + image_soup = BeautifulSoup(image_response.content, "html.parser") image_urls = [] - for img in image_soup.find_all('img'): - image_url = img.get('src') + for img in image_soup.find_all("img"): + image_url = img.get("src") if image_url and image_url.startswith("http"): image_urls.append(image_url) diff --git a/WikipediaModule.py b/WikipediaModule.py index dec5e2a5c0b..bcae4e68c97 100644 --- a/WikipediaModule.py +++ b/WikipediaModule.py @@ -3,11 +3,11 @@ @author: Albert """ -from __future__ import print_function -import wikipedia as wk from bs4 import BeautifulSoup +import wikipedia as wk + def wiki(): """ diff --git a/Windows_Wallpaper_Script/wallpaper_extract.py b/Windows_Wallpaper_Script/wallpaper_extract.py index 541462bdff4..bf832f5968c 100644 --- a/Windows_Wallpaper_Script/wallpaper_extract.py +++ b/Windows_Wallpaper_Script/wallpaper_extract.py @@ -74,7 +74,7 @@ def extract_wall(): if ext == ".jpg": try: im = Image.open(w.file_urls["wall_dst"] + filename) - except IOError: + except OSError: print("This isn't a picture.", filename) if list(im.size)[0] != 1920 and list(im.size)[0] != 1080: im.close() diff --git a/Word_Dictionary/dictionary.py b/Word_Dictionary/dictionary.py index 39f15eb47ec..44e8cb7b260 100644 --- a/Word_Dictionary/dictionary.py +++ b/Word_Dictionary/dictionary.py @@ -1,8 +1,4 @@ -from typing import Dict, List - - class Dictionary: - def __init__(self): self.node = {} @@ -22,20 +18,20 @@ def word_exists(self, word: str) -> bool: node = node[ltr] return "is_word" in node - def list_words_from_node(self, node: Dict, spelling: str) -> None: + def list_words_from_node(self, node: dict, spelling: str) -> None: if "is_word" in node: self.words_list.append(spelling) return for ltr in node: - self.list_words_from_node(node[ltr], spelling+ltr) + self.list_words_from_node(node[ltr], spelling + ltr) - def print_all_words_in_dictionary(self) -> List[str]: + def print_all_words_in_dictionary(self) -> list[str]: node = self.node self.words_list = [] self.list_words_from_node(node, "") return self.words_list - def suggest_words_starting_with(self, prefix: str) -> List[str]: + def suggest_words_starting_with(self, prefix: str) -> list[str]: node = self.node for ltr in prefix: if ltr not in node: @@ -45,8 +41,6 @@ def suggest_words_starting_with(self, prefix: str) -> List[str]: self.list_words_from_node(node, prefix) return self.words_list - - # Your Dictionary object will be instantiated and called as such: obj = Dictionary() @@ -59,4 +53,4 @@ def suggest_words_starting_with(self, prefix: str) -> List[str]: print(param_2) print(param_3) -print(obj.print_all_words_in_dictionary()) \ No newline at end of file +print(obj.print_all_words_in_dictionary()) diff --git a/Wordle/wordle.py b/Wordle/wordle.py index c4206704223..b2715baa514 100644 --- a/Wordle/wordle.py +++ b/Wordle/wordle.py @@ -26,9 +26,11 @@ import random # Load 5 letter word dictionary -with open("5 letter word dictionary.txt", 'r') as dictionary: +with open("5 letter word dictionary.txt") as dictionary: # Read content of dictionary - dictionary = dictionary.read().split('\n') # This returns a list of all the words in the dictionary + dictionary = dictionary.read().split( + "\n" + ) # This returns a list of all the words in the dictionary # Choose a random word from the dictionary word = random.choice(dictionary) @@ -95,7 +97,6 @@ letter += 1 continue - answer_given = False do_not_add = False # Check if letter is in word @@ -105,7 +106,10 @@ if user_inp[letter] == i: return_answer += "G" else: - if not user_inp[word.index(user_inp[letter])] == word[word.index(user_inp[letter])]: + if ( + not user_inp[word.index(user_inp[letter])] + == word[word.index(user_inp[letter])] + ): return_answer += "Y" else: answer_given = False @@ -117,7 +121,7 @@ # Append checked letter to the list letters_checked if not do_not_add: - letters_checked.append(user_inp[letter]) + letters_checked.append(user_inp[letter]) letter += 1 diff --git a/XORcipher/XOR_cipher.py b/XORcipher/XOR_cipher.py index 4d6bdb2190a..bc84efcfd64 100644 --- a/XORcipher/XOR_cipher.py +++ b/XORcipher/XOR_cipher.py @@ -1,24 +1,24 @@ """ - author: Christian Bender - date: 21.12.2017 - class: XORCipher - - This class implements the XOR-cipher algorithm and provides - some useful methods for encrypting and decrypting strings and - files. - - Overview about methods - - - encrypt : list of char - - decrypt : list of char - - encrypt_string : str - - decrypt_string : str - - encrypt_file : boolean - - decrypt_file : boolean +author: Christian Bender +date: 21.12.2017 +class: XORCipher + +This class implements the XOR-cipher algorithm and provides +some useful methods for encrypting and decrypting strings and +files. + +Overview about methods + +- encrypt : list of char +- decrypt : list of char +- encrypt_string : str +- decrypt_string : str +- encrypt_file : boolean +- decrypt_file : boolean """ -class XORCipher(object): +class XORCipher: def __init__(self, key=0): """ simple constructor that receives a key or uses @@ -141,7 +141,7 @@ def encrypt_file(self, file, key=0): assert isinstance(file, str) and isinstance(key, int) try: - with open(file, "r") as fin: + with open(file) as fin: with open("encrypt.out", "w+") as fout: # actual encrypt-process for line in fin: @@ -165,7 +165,7 @@ def decrypt_file(self, file, key): assert isinstance(file, str) and isinstance(key, int) try: - with open(file, "r") as fin: + with open(file) as fin: with open("decrypt.out", "w+") as fout: # actual encrypt-process for line in fin: diff --git a/Youtube Downloader With GUI/main.py b/Youtube Downloader With GUI/main.py index 21d5c534ad5..d238d7618e8 100644 --- a/Youtube Downloader With GUI/main.py +++ b/Youtube Downloader With GUI/main.py @@ -1,17 +1,20 @@ # libraraies -from pytube import * import os +from threading import * from tkinter import * from tkinter.filedialog import * from tkinter.messagebox import * -from threading import * + +from pytube import * file_size = 0 q = input("") if q == "shutdown": os.system("shutdown -s") + + # function progress to keep check of progress of function. def progress(stream=None, chunk=None, remaining=None): file_downloaded = file_size - remaining diff --git a/add_two_number.py b/add_two_number.py index 2824d2c1872..f83491cc2fd 100644 --- a/add_two_number.py +++ b/add_two_number.py @@ -1,17 +1,16 @@ user_input = (input("type type 'start' to run program:")).lower() -if user_input == 'start': +if user_input == "start": is_game_running = True else: is_game_running = False -while (is_game_running): +while is_game_running: num1 = int(input("enter number 1:")) num2 = int(input("enter number 2:")) - num3 = num1+num2 + num3 = num1 + num2 print(f"sum of {num1} and {num2} is {num3}") user_input = (input("if you want to discontinue type 'stop':")).lower() if user_input == "stop": is_game_running = False - diff --git a/advanced_calculator.py b/advanced_calculator.py index c7021f6a608..3037b5682b1 100644 --- a/advanced_calculator.py +++ b/advanced_calculator.py @@ -10,11 +10,11 @@ # How can I market gtts? Like showing used google's api? This is how can I market it? # Project description? What will be the project description? -from gtts import gTTS -from pygame import mixer, time from io import BytesIO from pprint import pprint +from gtts import gTTS +from pygame import mixer, time # Find the best of best extensions for the auto generation of the documentation parts. # For your favourite languages like JavaScript, Python ,etc,... diff --git a/agecalculator.py b/agecalculator.py index 094aa88ca46..2fb93581477 100644 --- a/agecalculator.py +++ b/agecalculator.py @@ -1,55 +1,54 @@ -from _datetime import datetime import tkinter as tk -from tkinter import ttk from _datetime import * +from _datetime import datetime +from tkinter import ttk win = tk.Tk() -win.title('Age Calculate') -win.geometry('310x400') -# win.iconbitmap('pic.png') this is use extention ico then show pic +win.title("Age Calculate") +win.geometry("310x400") +# win.iconbitmap('pic.png') this is use extention ico then show pic ############################################ Frame ############################################ pic = tk.PhotoImage(file=r"E:\Python Practice\Age_calculate\pic.png") -win.tk.call('wm','iconphoto',win._w,pic) +win.tk.call("wm", "iconphoto", win._w, pic) -canvas=tk.Canvas(win,width=310,height=190) +canvas = tk.Canvas(win, width=310, height=190) canvas.grid() image = tk.PhotoImage(file=r"E:\Python Practice\Age_calculate\pic.png") -canvas.create_image(0,0,anchor='nw',image=image) +canvas.create_image(0, 0, anchor="nw", image=image) frame = ttk.Frame(win) -frame.place(x=40,y=220) - +frame.place(x=40, y=220) ############################################ Label on Frame ############################################ -name = ttk.Label(frame,text = 'Name : ',font = ('',12,'bold')) -name.grid(row=0,column=0,sticky = tk.W) +name = ttk.Label(frame, text="Name : ", font=("", 12, "bold")) +name.grid(row=0, column=0, sticky=tk.W) -year = ttk.Label(frame,text = 'Year : ',font = ('',12,'bold')) -year.grid(row=1,column=0,sticky = tk.W) +year = ttk.Label(frame, text="Year : ", font=("", 12, "bold")) +year.grid(row=1, column=0, sticky=tk.W) -month = ttk.Label(frame,text = 'Month : ',font = ('',12,'bold')) -month.grid(row=2,column=0,sticky = tk.W) +month = ttk.Label(frame, text="Month : ", font=("", 12, "bold")) +month.grid(row=2, column=0, sticky=tk.W) -date = ttk.Label(frame,text = 'Date : ',font = ('',12,'bold')) -date.grid(row=3,column=0,sticky = tk.W) +date = ttk.Label(frame, text="Date : ", font=("", 12, "bold")) +date.grid(row=3, column=0, sticky=tk.W) ############################################ Entry Box ############################################ -name_entry = ttk.Entry(frame,width=25) -name_entry.grid(row=0,column=1) +name_entry = ttk.Entry(frame, width=25) +name_entry.grid(row=0, column=1) name_entry.focus() -year_entry = ttk.Entry(frame,width=25) -year_entry.grid(row=1,column=1,pady=5) +year_entry = ttk.Entry(frame, width=25) +year_entry.grid(row=1, column=1, pady=5) -month_entry = ttk.Entry(frame,width=25) -month_entry.grid(row=2,column=1) +month_entry = ttk.Entry(frame, width=25) +month_entry.grid(row=2, column=1) -date_entry = ttk.Entry(frame,width=25) -date_entry.grid(row=3,column=1,pady=5) +date_entry = ttk.Entry(frame, width=25) +date_entry.grid(row=3, column=1, pady=5) def age_cal(): @@ -57,13 +56,12 @@ def age_cal(): year_entry.get() month_entry.get() date_entry.get() - cal = datetime.today()-(int(year_entry)) + cal = datetime.today() - (int(year_entry)) print(cal) -btn = ttk.Button(frame,text='Age calculate',command=age_cal) -btn.grid(row=4,column=1) - +btn = ttk.Button(frame, text="Age calculate", command=age_cal) +btn.grid(row=4, column=1) win.mainloop() diff --git a/alexa_news_headlines.py b/alexa_news_headlines.py index 7cb84b9fe09..a2aa79ef4bf 100644 --- a/alexa_news_headlines.py +++ b/alexa_news_headlines.py @@ -41,7 +41,7 @@ def start_skill(): @ask.intent("YesIntent") def share_headlines(): headlines = get_headlines() - headline_msg = "The current world news headlines are {}".format(headlines) + headline_msg = f"The current world news headlines are {headlines}" return statement(headline_msg) diff --git a/armstrongnumber.py b/armstrongnumber.py index 2e714fa9db4..f4def08d440 100644 --- a/armstrongnumber.py +++ b/armstrongnumber.py @@ -10,7 +10,7 @@ temp = num while temp > 0: digit = temp % 10 - sum += digit ** 3 + sum += digit**3 temp //= 10 # display the result diff --git a/async_downloader/async_downloader.py b/async_downloader/async_downloader.py index 4f715048905..22fecfce802 100644 --- a/async_downloader/async_downloader.py +++ b/async_downloader/async_downloader.py @@ -1,122 +1,143 @@ """ -It's example of usage asyncio+aiohttp to downloading. -You should install aiohttp for using: -(You can use virtualenv to testing) -pip install -r /path/to/requirements.txt +Example of using asyncio and aiohttp for asynchronous downloads. + +Requires: +- aiohttp library for asynchronous HTTP requests +- Python 3.13.5 or compatible + +Install dependencies with: +pip install aiohttp """ import asyncio from os.path import basename import aiohttp +from aiohttp import ClientError, ClientSession + + +def download(urls: list[str]) -> None: + """ + Download files from given URLs asynchronously. + Args: + urls: List of URLs to download -def download(ways): - if not ways: - print("Ways list is empty. Downloading is impossible") + Prints download statistics and results upon completion. + """ + if not urls: + print("URL list is empty. Downloading aborted.") return - print("downloading..") + print("Initiating downloads...") - success_files = set() - failure_files = set() + success_files: set[str] = set() + failure_files: set[str] = set() - event_loop = asyncio.get_event_loop() - try: - event_loop.run_until_complete( - async_downloader(ways, event_loop, success_files, failure_files) - ) - finally: - event_loop.close() + # Run async downloader in the current event loop + asyncio.run(async_downloader(urls, success_files, failure_files)) - print("Download complete") + print("Download process completed") print("-" * 100) if success_files: - print("success:") + print("Successful downloads:") for file in success_files: print(file) if failure_files: - print("failure:") + print("Failed downloads:") for file in failure_files: print(file) -async def async_downloader(ways, loop, success_files, failure_files): - async with aiohttp.ClientSession() as session: - coroutines = [ - download_file_by_url( - url, - session=session, - ) - for url in ways - ] +async def async_downloader( + urls: list[str], success_files: set[str], failure_files: set[str] +) -> None: + """ + Asynchronous downloader that processes multiple URLs concurrently. + + Args: + urls: List of URLs to download + success_files: Set to store successfully downloaded URLs + failure_files: Set to store failed URLs + + Uses aiohttp ClientSession for efficient asynchronous requests. + """ + async with ClientSession() as session: + # Create and execute download tasks concurrently + tasks = [download_file_by_url(url, session) for url in urls] - for task in asyncio.as_completed(coroutines): - fail, url = await task + # Process results as tasks complete + for task in asyncio.as_completed(tasks): + failed, url = await task - if fail: + if failed: failure_files.add(url) else: success_files.add(url) -async def download_file_by_url(url, session=None): - fail = True - file_name = basename(url) +async def download_file_by_url(url: str, session: ClientSession) -> tuple[bool, str]: + """ + Download a single file from given URL using provided session. + + Args: + url: URL of the file to download + session: aiohttp ClientSession object + + Returns: + Tuple containing: + - bool: True if download failed, False if successful + - str: Original URL - assert session + Handles various HTTP errors and network exceptions. + """ + failed = True + file_name = basename(url) try: async with session.get(url) as response: - if response.status == 404: - print( - "\t{} from {} : Failed : {}".format( - file_name, url, "404 - Not found" - ) - ) - return fail, url - - if not response.status == 200: - print( - "\t{} from {} : Failed : HTTP response {}".format( - file_name, url, response.status - ) - ) - return fail, url + response.raise_for_status() # Raise exception for 4xx/5xx status codes + # Read response data data = await response.read() + # Write data to file with open(file_name, "wb") as file: file.write(data) - except asyncio.TimeoutError: - print("\t{} from {}: Failed : {}".format(file_name, url, "Timeout error")) + except aiohttp.ClientResponseError as e: + print(f"\t{file_name} from {url}: Failed - HTTP Error {e.status}") + + except TimeoutError: + print(f"\t{file_name} from {url}: Failed - Connection timed out") + + except ClientError as e: + print(f"\t{file_name} from {url}: Failed - Connection error: {str(e)}") - except aiohttp.client_exceptions.ClientConnectionError: - print( - "\t{} from {}: Failed : {}".format( - file_name, url, "Client connection error" - ) - ) + except Exception as e: + print(f"\t{file_name} from {url}: Failed - Unexpected error: {str(e)}") else: - print("\t{} from {} : Success".format(file_name, url)) - fail = False + print(f"\t{file_name} from {url}: Success") + failed = False - return fail, url + return failed, url -def test(): - ways = [ +def test() -> None: + """ + Test the download functionality with sample URLs. + """ + urls = [ "https://www.wikipedia.org", "https://www.ya.ru", "https://www.duckduckgo.com", - "https://www.fail-path.unknown", + "https://www.fail-path.unknown", # Intentionally invalid URL ] - download(ways) + download(urls) if __name__ == "__main__": diff --git a/async_downloader/requirements.txt b/async_downloader/requirements.txt deleted file mode 100644 index 8e9fbabcce6..00000000000 --- a/async_downloader/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -aiohttp==3.12.14 diff --git a/automail.py b/automail.py index a1407736ac9..2b765ef7ee9 100644 --- a/automail.py +++ b/automail.py @@ -1,27 +1,30 @@ -#find documentation for ezgmail module at https://pypi.org/project/EZGmail/ -#simple simon says module that interacts with google API to read the subject line of an email and respond to "Simon says:" -#DO NOT FORGET TO ADD CREDENTIALS.JSON AND TOKEN.JSON TO .GITIGNORE!!! +# find documentation for ezgmail module at https://pypi.org/project/EZGmail/ +# simple simon says module that interacts with google API to read the subject line of an email and respond to "Simon says:" +# DO NOT FORGET TO ADD CREDENTIALS.JSON AND TOKEN.JSON TO .GITIGNORE!!! -import ezgmail import re import time +import ezgmail + check = True while check: recThreads = ezgmail.recent() - findEmail = re.compile(r'<(.*)@(.*)>') + findEmail = re.compile(r"<(.*)@(.*)>") i = 0 for msg in recThreads: - subEval = recThreads[i].messages[0].subject.split(' ') + subEval = recThreads[i].messages[0].subject.split(" ") sender = recThreads[i].messages[0].sender - if subEval[0] == 'Simon' and subEval[1] == 'says:': - subEval.remove('Simon') - subEval.remove('says:') - replyAddress = findEmail.search(sender).group(0).replace('<','').replace('>','') - replyContent = 'I am now doing ' + ' '.join(subEval) + if subEval[0] == "Simon" and subEval[1] == "says:": + subEval.remove("Simon") + subEval.remove("says:") + replyAddress = ( + findEmail.search(sender).group(0).replace("<", "").replace(">", "") + ) + replyContent = "I am now doing " + " ".join(subEval) ezgmail.send(replyAddress, replyContent, replyContent) ezgmail._trash(recThreads[i]) - if subEval[0] == 'ENDTASK': #remote kill command + if subEval[0] == "ENDTASK": # remote kill command check = False i += 1 - time.sleep(60) #change check frquency; default every minute \ No newline at end of file + time.sleep(60) # change check frquency; default every minute diff --git a/balance_parenthesis.py b/balance_parenthesis.py index cd89ddcf6bd..14057dd871f 100644 --- a/balance_parenthesis.py +++ b/balance_parenthesis.py @@ -19,11 +19,7 @@ def display(self): def is_same(p1, p2): - if p1 == "(" and p2 == ")": - return True - elif p1 == "[" and p2 == "]": - return True - elif p1 == "{" and p2 == "}": + if p1 == "(" and p2 == ")" or p1 == "[" and p2 == "]" or p1 == "{" and p2 == "}": return True else: return False diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 0e0b837fb44..c62b9ad4ef1 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -1,11 +1,21 @@ +import sys +from collections.abc import Callable +from typing import Any +import backendModule from PyQt5 import QtCore, QtGui, QtWidgets -import sys -import backend -backend.connect_database() -employee_data = None -# Page Constants (for reference) +try: + if hasattr(backendModule, "connect_database"): + backendModule.connect_database() + else: + raise AttributeError("backend module missing 'connect_database' function") +except Exception as e: + print(f"Database connection error: {e}") + sys.exit(1) + +employee_data: tuple[Any, ...] | None = None + HOME_PAGE = 0 ADMIN_PAGE = 1 EMPLOYEE_PAGE = 2 @@ -29,11 +39,11 @@ EMPLOYEE_UPDATE_ACCOUNT_PAGE = 20 FONT_SIZE = QtGui.QFont("Segoe UI", 12) -# ------------------------------------------------------------------------------------------------------------- -# === Reusable UI Component Functions === -# ------------------------------------------------------------------------------------------------------------- -def create_styled_frame(parent, min_size=None, style=""): + +def create_styled_frame( + parent: QtWidgets.QWidget, min_size: tuple[int, int] | None = None, style: str = "" +) -> QtWidgets.QFrame: """Create a styled QFrame with optional minimum size and custom style.""" frame = QtWidgets.QFrame(parent) frame.setFrameShape(QtWidgets.QFrame.StyledPanel) @@ -43,7 +53,14 @@ def create_styled_frame(parent, min_size=None, style=""): frame.setStyleSheet(style) return frame -def create_styled_label(parent, text, font_size=12, bold=False, style="color: #2c3e50; padding: 10px;"): + +def create_styled_label( + parent: QtWidgets.QWidget, + text: str, + font_size: int = 12, + bold: bool = False, + style: str = "color: #2c3e50; padding: 10px;", +) -> QtWidgets.QLabel: """Create a styled QLabel with customizable font size and boldness.""" label = QtWidgets.QLabel(parent) font = QtGui.QFont("Segoe UI", font_size) @@ -55,7 +72,10 @@ def create_styled_label(parent, text, font_size=12, bold=False, style="color: #2 label.setText(text) return label -def create_styled_button(parent, text, min_size=None): + +def create_styled_button( + parent: QtWidgets.QWidget, text: str, min_size: tuple[int, int] | None = None +) -> QtWidgets.QPushButton: """Create a styled QPushButton with hover and pressed effects.""" button = QtWidgets.QPushButton(parent) if min_size: @@ -81,75 +101,92 @@ def create_styled_button(parent, text, min_size=None): button.setText(text) return button -def create_input_field(parent, label_text, min_label_size=(120, 0)): - """Create a horizontal layout with a label and a QLineEdit.""" + +def create_input_field( + parent: QtWidgets.QWidget, + label_text: str, + min_label_size: tuple[int, int] = (120, 0), +) -> tuple[QtWidgets.QFrame, QtWidgets.QLineEdit]: + """Create a horizontal layout with a label and input field.""" frame = create_styled_frame(parent, style="padding: 7px;") layout = QtWidgets.QHBoxLayout(frame) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) - - label = create_styled_label(frame, label_text, font_size=12, bold=True, style="color: #2c3e50;") + + label = create_styled_label( + frame, label_text, font_size=12, bold=True, style="color: #2c3e50;" + ) if min_label_size: label.setMinimumSize(QtCore.QSize(*min_label_size)) - + line_edit = QtWidgets.QLineEdit(frame) line_edit.setFont(FONT_SIZE) - line_edit.setStyleSheet("background-color: #f0f0f0; border: 1px solid #ccc; border-radius: 4px; padding: 8px;") - + line_edit.setStyleSheet( + "background-color: #f0f0f0; border: 1px solid #ccc; border-radius: 4px; padding: 8px;" + ) + layout.addWidget(label) layout.addWidget(line_edit) return frame, line_edit -def create_input_field_V(parent, label_text, min_label_size=(120, 0)): - """Create a horizontal layout with a label and a QLineEdit.""" + +def create_input_field_V( + parent: QtWidgets.QWidget, + label_text: str, + min_label_size: tuple[int, int] = (120, 0), +) -> tuple[QtWidgets.QFrame, QtWidgets.QLineEdit]: + """Create a vertical layout with a label and input field.""" frame = create_styled_frame(parent, style="padding: 7px;") layout = QtWidgets.QVBoxLayout(frame) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) - - label = create_styled_label(frame, label_text, font_size=12, bold=True, style="color: #2c3e50;") + + label = create_styled_label( + frame, label_text, font_size=12, bold=True, style="color: #2c3e50;" + ) if min_label_size: label.setMinimumSize(QtCore.QSize(*min_label_size)) - + line_edit = QtWidgets.QLineEdit(frame) - line_edit.setStyleSheet("background-color: #f0f0f0; border: 1px solid #ccc; border-radius: 4px; padding: 8px;") + line_edit.setStyleSheet( + "background-color: #f0f0f0; border: 1px solid #ccc; border-radius: 4px; padding: 8px;" + ) line_edit.setFont(FONT_SIZE) - + layout.addWidget(label) layout.addWidget(line_edit) return frame, line_edit -def show_popup_message(parent, message: str, page: int = None, show_cancel: bool = False,cancel_page: int = HOME_PAGE): - """Reusable popup message box. - Args: - parent: The parent widget. - message (str): The message to display. - page (int, optional): Page index to switch to after dialog closes. - show_cancel (bool): Whether to show the Cancel button. - """ +def show_popup_message( + parent: QtWidgets.QWidget, + message: str, + page: int | None = None, + show_cancel: bool = False, + cancel_page: int = HOME_PAGE, +) -> None: + """Display a reusable popup message box with optional navigation.""" dialog = QtWidgets.QDialog(parent) dialog.setWindowTitle("Message") dialog.setFixedSize(350, 100) dialog.setStyleSheet("background-color: #f0f0f0;") - + layout = QtWidgets.QVBoxLayout(dialog) layout.setSpacing(10) layout.setContentsMargins(15, 15, 15, 15) - + label = QtWidgets.QLabel(message) label.setStyleSheet("font-size: 12px; color: #2c3e50;") label.setWordWrap(True) layout.addWidget(label) - - # Decide which buttons to show + if show_cancel: button_box = QtWidgets.QDialogButtonBox( QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel ) else: button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok) - + button_box.setStyleSheet(""" QPushButton { background-color: #3498db; @@ -166,184 +203,248 @@ def show_popup_message(parent, message: str, page: int = None, show_cancel: bool } """) layout.addWidget(button_box) - - # Connect buttons - def on_accept(): + + def on_accept() -> None: if page is not None: parent.setCurrentIndex(page) dialog.accept() - - def on_reject(): + + def on_reject() -> None: if page is not None: parent.setCurrentIndex(cancel_page) dialog.reject() - + button_box.accepted.connect(on_accept) button_box.rejected.connect(on_reject) - + dialog.exec_() -def search_result(parent, title,label_text): + +def search_result( + parent: QtWidgets.QWidget, title: str, label_text: str +) -> tuple[QtWidgets.QWidget, tuple[QtWidgets.QLineEdit, QtWidgets.QPushButton]]: + """Create a search page with input field and submit button.""" page, main_layout = create_page_with_header(parent, title) content_frame = create_styled_frame(page) - content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_frame.setSizePolicy( + QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding + ) content_layout = QtWidgets.QVBoxLayout(content_frame) - content_layout.alignment - - form_frame = create_styled_frame(content_frame, min_size=(400, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") + content_layout.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + + form_frame = create_styled_frame( + content_frame, + min_size=(400, 200), + style="background-color: #ffffff; border-radius: 15px; padding: 10px;", + ) form_layout = QtWidgets.QVBoxLayout(form_frame) form_layout.setSpacing(3) - # Define input fields - user = create_input_field(form_frame, label_text, min_label_size=(180, 0)) - form_layout.addWidget(user[0]) - user_account_number= user[1] + + user_frame, user_account_number = create_input_field( + form_frame, label_text, min_label_size=(180, 0) + ) + form_layout.addWidget(user_frame) user_account_number.setFont(FONT_SIZE) + submit_button = create_styled_button(form_frame, "Submit", min_size=(100, 50)) form_layout.addWidget(submit_button) - content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + + content_layout.addWidget( + form_frame, alignment=QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter + ) main_layout.addWidget(content_frame) - - return page,(user_account_number,submit_button) -# ------------------------------------------------------------------------------------------------------------- -# === Page Creation Functions == -# ------------------------------------------------------------------------------------------------------------- -def create_page_with_header(parent, title_text): - """Create a page with a styled header and return the page + main layout.""" + + return page, (user_account_number, submit_button) + + +def create_page_with_header( + parent: QtWidgets.QWidget, title_text: str +) -> tuple[QtWidgets.QWidget, QtWidgets.QLayout]: + """Create a page with a styled header and return the page and main layout.""" page = QtWidgets.QWidget(parent) main_layout = QtWidgets.QVBoxLayout(page) main_layout.setContentsMargins(20, 20, 20, 20) main_layout.setSpacing(20) - header_frame = create_styled_frame(page, style="background-color: #ffffff; border-radius: 10px; padding: 10px;") + header_frame = create_styled_frame( + page, style="background-color: #ffffff; border-radius: 10px; padding: 10px;" + ) header_layout = QtWidgets.QVBoxLayout(header_frame) title_label = create_styled_label(header_frame, title_text, font_size=30) - header_layout.addWidget(title_label, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop) - - main_layout.addWidget(header_frame, 0, QtCore.Qt.AlignTop) + header_layout.addWidget( + title_label, alignment=QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop + ) + + main_layout.addWidget(header_frame, alignment=QtCore.Qt.AlignTop) return page, main_layout -def get_employee_name(parent, name_field_text="Enter Employee Name"): + + +def get_employee_name( + parent: QtWidgets.QWidget, name_field_text: str = "Enter Employee Name" +) -> QtWidgets.QWidget: + """Create a page for searching employees by name.""" page, main_layout = create_page_with_header(parent, "Employee Data Update") - - # Content frame + content_frame = create_styled_frame(page) - content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_frame.setSizePolicy( + QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding + ) content_layout = QtWidgets.QVBoxLayout(content_frame) - - # Form frame - form_frame = create_styled_frame(content_frame, min_size=(340, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") + + form_frame = create_styled_frame( + content_frame, + min_size=(340, 200), + style="background-color: #ffffff; border-radius: 15px; padding: 10px;", + ) form_layout = QtWidgets.QVBoxLayout(form_frame) - - # Form fields + name_label, name_field = create_input_field(form_frame, name_field_text) search_button = create_styled_button(form_frame, "Search", min_size=(100, 30)) form_layout.addWidget(name_label) form_layout.addWidget(search_button) - content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + + content_layout.addWidget( + form_frame, alignment=QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter + ) main_layout.addWidget(content_frame) - - def on_search_button_clicked(): + + def on_search_button_clicked() -> None: global employee_data entered_name = name_field.text().strip() - print(f"Entered Name: {entered_name}") + if not entered_name: - QtWidgets.QMessageBox.warning(parent, "Input Error", "Please enter an employee name.") + QtWidgets.QMessageBox.warning( + parent, "Input Error", "Please enter an employee name." + ) return - + try: - employee_check = backend.check_name_in_staff(entered_name) - print(f"Employee Check: {type(employee_check)},{employee_check}") - if employee_check: - cur = backend.cur - cur.execute("SELECT * FROM staff WHERE name = ?", (entered_name,)) - employee_data = cur.fetchone() - print(f"Employee Data: {employee_data}") + if not hasattr(backendModule, "check_name_in_staff"): + raise AttributeError("backend missing 'check_name_in_staff' function") + + employee_exists = backendModule.check_name_in_staff(entered_name) + if employee_exists: + if not hasattr(backendModule, "get_employee_data"): + raise AttributeError("backend missing 'get_employee_data' function") + + employee_data = backendModule.get_employee_data(entered_name) parent.setCurrentIndex(UPDATE_EMPLOYEE_PAGE2) - - # if employee_data: - # QtWidgets.QMessageBox.information(parent, "Employee Found", - # f"Employee data:\nID: {fetch[0]}\nName: {fetch[1]}\nDept: {fetch[2]}\nRole: {fetch[3]}") - - else: - QtWidgets.QMessageBox.information(parent, "Not Found", "Employee not found.") + QtWidgets.QMessageBox.information( + parent, "Not Found", "Employee not found." + ) except Exception as e: - QtWidgets.QMessageBox.critical(parent, "Error", f"An error occurred: {str(e)}") - + QtWidgets.QMessageBox.critical( + parent, "Error", f"An error occurred: {str(e)}" + ) + search_button.clicked.connect(on_search_button_clicked) - return page - - #backend.check_name_in_staff() -def create_login_page(parent ,title, name_field_text="Name :", password_field_text="Password :", submit_text="Submit",): - """Create a login page with a title, name and password fields, and a submit button.""" +def create_login_page( + parent: QtWidgets.QWidget, + title: str, + name_field_text: str = "Name :", + password_field_text: str = "Password :", + submit_text: str = "Submit", +) -> tuple[ + QtWidgets.QWidget, QtWidgets.QLineEdit, QtWidgets.QLineEdit, QtWidgets.QPushButton +]: + """Create a login page with name, password fields and submit button.""" page, main_layout = create_page_with_header(parent, title) - - # Content frame + content_frame = create_styled_frame(page) - content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_frame.setSizePolicy( + QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding + ) content_layout = QtWidgets.QVBoxLayout(content_frame) - - # Form frame - form_frame = create_styled_frame(content_frame, min_size=(340, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") + + form_frame = create_styled_frame( + content_frame, + min_size=(340, 200), + style="background-color: #ffffff; border-radius: 15px; padding: 10px;", + ) form_layout = QtWidgets.QVBoxLayout(form_frame) form_layout.setSpacing(20) - - # Input fields + name_frame, name_edit = create_input_field(form_frame, name_field_text) password_frame, password_edit = create_input_field(form_frame, password_field_text) - - # Submit button + password_edit.setEchoMode(QtWidgets.QLineEdit.Password) + button_frame = create_styled_frame(form_frame, style="padding: 7px;") button_layout = QtWidgets.QVBoxLayout(button_frame) button_layout.setSpacing(60) submit_button = create_styled_button(button_frame, submit_text, min_size=(150, 0)) - button_layout.addWidget(submit_button, 0, QtCore.Qt.AlignHCenter) - + button_layout.addWidget(submit_button, alignment=QtCore.Qt.AlignHCenter) + form_layout.addWidget(name_frame) form_layout.addWidget(password_frame) form_layout.addWidget(button_frame) - - content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + + content_layout.addWidget( + form_frame, alignment=QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter + ) main_layout.addWidget(content_frame) - - - + return page, name_edit, password_edit, submit_button -def on_login_button_clicked(parent, name_field, password_field): + +def on_login_button_clicked( + parent: QtWidgets.QWidget, + name_field: QtWidgets.QLineEdit, + password_field: QtWidgets.QLineEdit, +) -> None: + """Handle login button click event.""" name = name_field.text().strip() password = password_field.text().strip() - + if not name or not password: - show_popup_message(parent, "Please enter your name and password.",HOME_PAGE) - else: - try: - # Ideally, here you'd call a backend authentication check - success = backend.check_admin(name, password) - if success: - QtWidgets.QMessageBox.information(parent, "Login Successful", f"Welcome, {name}!") - else: - QtWidgets.QMessageBox.warning(parent, "Login Failed", "Incorrect name or password.") - except Exception as e: - QtWidgets.QMessageBox.critical(parent, "Error", f"An error occurred during login: {str(e)}") - -def create_home_page(parent, on_admin_clicked, on_employee_clicked, on_exit_clicked): - """Create the home page with Admin, Employee, and Exit buttons.""" - page, main_layout = create_page_with_header(parent, "Admin Menu") - - # Button frame + show_popup_message(parent, "Please enter your name and password.", HOME_PAGE) + return + + try: + if not hasattr(backendModule, "check_admin"): + raise AttributeError("backend missing 'check_admin' function") + + success = backendModule.check_admin(name, password) + if success: + QtWidgets.QMessageBox.information( + parent, "Login Successful", f"Welcome, {name}!" + ) + else: + QtWidgets.QMessageBox.warning( + parent, "Login Failed", "Incorrect name or password." + ) + except Exception as e: + QtWidgets.QMessageBox.critical( + parent, "Error", f"An error occurred during login: {str(e)}" + ) + + +def create_home_page( + parent: QtWidgets.QWidget, + on_admin_clicked: Callable[[], None], + on_employee_clicked: Callable[[], None], + on_exit_clicked: Callable[[], None], +) -> QtWidgets.QWidget: + """Create home page with navigation buttons.""" + page, main_layout = create_page_with_header(parent, "Bank Management System") + button_frame = create_styled_frame(page) - button_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + button_frame.setSizePolicy( + QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding + ) button_layout = QtWidgets.QVBoxLayout(button_frame) - - # Button container - button_container = create_styled_frame(button_frame, min_size=(300, 0), style="background-color: #ffffff; border-radius: 15px; padding: 20px;") + + button_container = create_styled_frame( + button_frame, + min_size=(300, 0), + style="background-color: #ffffff; border-radius: 15px; padding: 20px;", + ) button_container_layout = QtWidgets.QVBoxLayout(button_container) button_container_layout.setSpacing(15) - - # Buttons + admin_button = create_styled_button(button_container, "Admin") employee_button = create_styled_button(button_container, "Employee") exit_button = create_styled_button(button_container, "Exit") @@ -365,64 +466,107 @@ def create_home_page(parent, on_admin_clicked, on_employee_clicked, on_exit_clic background-color: #992d22; } """) - + button_container_layout.addWidget(admin_button) button_container_layout.addWidget(employee_button) button_container_layout.addWidget(exit_button) - - button_layout.addWidget(button_container, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + + button_layout.addWidget( + button_container, alignment=QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter + ) main_layout.addWidget(button_frame) - - # Connect button signals + admin_button.clicked.connect(on_admin_clicked) employee_button.clicked.connect(on_employee_clicked) exit_button.clicked.connect(on_exit_clicked) - + return page -def create_admin_menu_page(parent): + +def create_admin_menu_page( + parent: QtWidgets.QWidget, +) -> tuple[ + QtWidgets.QWidget, + QtWidgets.QPushButton, + QtWidgets.QPushButton, + QtWidgets.QPushButton, + QtWidgets.QPushButton, + QtWidgets.QPushButton, +]: + """Create admin menu page with function buttons.""" page, main_layout = create_page_with_header(parent, "Admin Menu") button_frame = create_styled_frame(page) - button_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + button_frame.setSizePolicy( + QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding + ) button_layout = QtWidgets.QVBoxLayout(button_frame) - button_container = create_styled_frame(button_frame, min_size=(300, 0), style="background-color: #ffffff; border-radius: 15px; padding: 20px;") + button_container = create_styled_frame( + button_frame, + min_size=(300, 0), + style="background-color: #ffffff; border-radius: 15px; padding: 20px;", + ) button_container_layout = QtWidgets.QVBoxLayout(button_container) button_container_layout.setSpacing(15) - # Define button labels - button_labels = ["Add Employee", "Update Employee", "Employee List", "Total Money", "Back"] - buttons = [] + button_labels = [ + "Add Employee", + "Update Employee", + "Employee List", + "Total Money", + "Back", + ] + buttons: list[QtWidgets.QPushButton] = [] for label in button_labels: btn = create_styled_button(button_container, label) button_container_layout.addWidget(btn) buttons.append(btn) - button_layout.addWidget(button_container, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + button_layout.addWidget( + button_container, alignment=QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter + ) main_layout.addWidget(button_frame) - return page, *buttons # Unpack as add_button, update_employee, etc. - -def create_add_employee_page(parent, title, submit_text="Submit",update_btn:bool=False): + return page, *buttons + + +def create_add_employee_page( + parent: QtWidgets.QWidget, + title: str, + submit_text: str = "Submit", + update_btn: bool = False, +) -> tuple[ + QtWidgets.QWidget, + QtWidgets.QLineEdit, + QtWidgets.QLineEdit, + QtWidgets.QLineEdit, + QtWidgets.QLineEdit, + QtWidgets.QPushButton, +]: + """Create page for adding or updating employee information.""" page, main_layout = create_page_with_header(parent, title) content_frame = create_styled_frame(page) - content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_frame.setSizePolicy( + QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding + ) content_layout = QtWidgets.QVBoxLayout(content_frame) - form_frame = create_styled_frame(content_frame, min_size=(340, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") + form_frame = create_styled_frame( + content_frame, + min_size=(340, 200), + style="background-color: #ffffff; border-radius: 15px; padding: 10px;", + ) form_layout = QtWidgets.QVBoxLayout(form_frame) form_layout.setSpacing(10) - # Define input fields fields = ["Name :", "Password :", "Salary :", "Position :"] - name_edit = None - password_edit = None - salary_edit = None - position_edit = None - edits = [] + name_edit: QtWidgets.QLineEdit = QtWidgets.QLineEdit() + password_edit: QtWidgets.QLineEdit = QtWidgets.QLineEdit() + salary_edit: QtWidgets.QLineEdit = QtWidgets.QLineEdit() + position_edit: QtWidgets.QLineEdit = QtWidgets.QLineEdit() for i, field in enumerate(fields): field_frame, field_edit = create_input_field(form_frame, field) @@ -435,21 +579,25 @@ def create_add_employee_page(parent, title, submit_text="Submit",update_btn:bool salary_edit = field_edit elif i == 3: position_edit = field_edit - edits.append(field_edit) - # Submit button + button_frame = create_styled_frame(form_frame, style="padding: 7px;") button_layout = QtWidgets.QVBoxLayout(button_frame) + if update_btn: - update_button = create_styled_button(button_frame, "Update", min_size=(100, 50)) - button_layout.addWidget(update_button, 0, QtCore.Qt.AlignHCenter) + submit_button = create_styled_button(button_frame, "Update", min_size=(100, 50)) else: - submit_button = create_styled_button(button_frame, submit_text, min_size=(100, 50)) - button_layout.addWidget(submit_button, 0, QtCore.Qt.AlignHCenter) - + submit_button = create_styled_button( + button_frame, submit_text, min_size=(100, 50) + ) + button_layout.addWidget(submit_button, alignment=QtCore.Qt.AlignHCenter) form_layout.addWidget(button_frame) - content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + + content_layout.addWidget( + form_frame, alignment=QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter + ) main_layout.addWidget(content_frame) + back_btn = QtWidgets.QPushButton("Back", content_frame) back_btn.setStyleSheet(""" QPushButton { @@ -465,70 +613,88 @@ def create_add_employee_page(parent, title, submit_text="Submit",update_btn:bool } """) back_btn.clicked.connect(lambda: parent.setCurrentIndex(ADMIN_MENU_PAGE)) - main_layout.addWidget(back_btn, 0,alignment=QtCore.Qt.AlignLeft) - if update_btn: - return page, name_edit, password_edit, salary_edit, position_edit, update_button - else: - return page, name_edit, password_edit, salary_edit, position_edit, submit_button # Unpack as name_edit, password_edit, etc. - -def show_employee_list_page(parent, title): + main_layout.addWidget(back_btn, alignment=QtCore.Qt.AlignLeft) + + return page, name_edit, password_edit, salary_edit, position_edit, submit_button + + +def show_employee_list_page(parent: QtWidgets.QWidget, title: str) -> QtWidgets.QWidget: + """Create page to display list of employees.""" page, main_layout = create_page_with_header(parent, title) - - content_frame = create_styled_frame(page, style="background-color: #f9f9f9; border-radius: 10px; padding: 15px;") - content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + + content_frame = create_styled_frame( + page, style="background-color: #f9f9f9; border-radius: 10px; padding: 15px;" + ) + content_frame.setSizePolicy( + QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding + ) content_layout = QtWidgets.QVBoxLayout(content_frame) - # Table frame - table_frame = create_styled_frame(content_frame, style="background-color: #ffffff; border-radius: 8px; padding: 10px;") + table_frame = create_styled_frame( + content_frame, + style="background-color: #ffffff; border-radius: 8px; padding: 10px;", + ) table_layout = QtWidgets.QVBoxLayout(table_frame) table_layout.setSpacing(0) - # Header row - header_frame = create_styled_frame(table_frame, style="background-color: #f5f5f5; ; border-radius: 8px 8px 0 0; padding: 10px;") + header_frame = create_styled_frame( + table_frame, + style="background-color: #f5f5f5; border-radius: 8px 8px 0 0; padding: 10px;", + ) header_layout = QtWidgets.QHBoxLayout(header_frame) header_layout.setContentsMargins(10, 5, 10, 5) + headers = ["Name", "Position", "Salary"] for i, header in enumerate(headers): header_label = QtWidgets.QLabel(header, header_frame) - header_label.setStyleSheet("font-weight: bold; font-size: 14px; color: #333333; padding: 0px; margin: 0px;") - if i == 2: # Right-align salary header + header_label.setStyleSheet( + "font-weight: bold; font-size: 14px; color: #333333;" + ) + if i == 2: header_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) else: header_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) - header_layout.addWidget(header_label, 1 if i < 2 else 0) # Stretch name and position, not salary + header_layout.addWidget(header_label, 1 if i < 2 else 0) + table_layout.addWidget(header_frame) - # Employee rows - employees = backend.show_employees_for_update() - for row, employee in enumerate(employees): - row_frame = create_styled_frame(table_frame, style=f"background-color: {'#fafafa' if row % 2 else '#ffffff'}; padding: 8px;") - row_layout = QtWidgets.QHBoxLayout(row_frame) - row_layout.setContentsMargins(10, 5, 10, 5) - - # Name - name_label = QtWidgets.QLabel(employee[0], row_frame) - name_label.setStyleSheet("font-size: 14px; color: #333333; padding: 0px; margin: 0px;") - name_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) - row_layout.addWidget(name_label, 1) - - # Position - position_label = QtWidgets.QLabel(employee[3], row_frame) - position_label.setStyleSheet("font-size: 14px; color: #333333; padding: 0px; margin: 0px;") - position_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) - row_layout.addWidget(position_label, 1) - - # Salary (formatted as currency) - salary_label = QtWidgets.QLabel(f"${float(employee[2]):,.2f}", row_frame) - salary_label.setStyleSheet("font-size: 14px; color: #333333; padding: 0px; margin: 0px;") - salary_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) - row_layout.addWidget(salary_label, 0) - - table_layout.addWidget(row_frame) - - # Add stretch to prevent rows from expanding vertically + try: + if not hasattr(backendModule, "show_employees_for_update"): + raise AttributeError("backend missing 'show_employees_for_update' function") + + employees = backendModule.show_employees_for_update() + for row, employee in enumerate(employees): + row_frame = create_styled_frame( + table_frame, + style=f"background-color: {'#fafafa' if row % 2 else '#ffffff'}; padding: 8px;", + ) + row_layout = QtWidgets.QHBoxLayout(row_frame) + row_layout.setContentsMargins(10, 5, 10, 5) + + name_label = QtWidgets.QLabel(str(employee[0]), row_frame) + name_label.setStyleSheet("font-size: 14px; color: #333333;") + name_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) + row_layout.addWidget(name_label, 1) + + position_label = QtWidgets.QLabel(str(employee[3]), row_frame) + position_label.setStyleSheet("font-size: 14px; color: #333333;") + position_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) + row_layout.addWidget(position_label, 1) + + salary_label = QtWidgets.QLabel(f"${float(employee[2]):,.2f}", row_frame) + salary_label.setStyleSheet("font-size: 14px; color: #333333;") + salary_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) + row_layout.addWidget(salary_label, 0) + + table_layout.addWidget(row_frame) + except Exception as e: + error_label = QtWidgets.QLabel( + f"Error loading employees: {str(e)}", table_frame + ) + table_layout.addWidget(error_label) + table_layout.addStretch() - - # Back button + back_button = QtWidgets.QPushButton("Back", content_frame) back_button.setStyleSheet(""" QPushButton { @@ -544,104 +710,166 @@ def show_employee_list_page(parent, title): } """) back_button.clicked.connect(lambda: parent.setCurrentIndex(ADMIN_MENU_PAGE)) - + content_layout.addWidget(table_frame) main_layout.addWidget(back_button, alignment=QtCore.Qt.AlignLeft) main_layout.addWidget(content_frame) - + return page -def show_total_money(parent, title): + + +def show_total_money(parent: QtWidgets.QWidget, title: str) -> QtWidgets.QWidget: + """Create page to display total money.""" page, main_layout = create_page_with_header(parent, title) - content_frame = create_styled_frame(page, style="background-color: #f9f9f9; border-radius: 10px; padding: 15px;") + content_frame = create_styled_frame( + page, style="background-color: #f9f9f9; border-radius: 10px; padding: 15px;" + ) content_layout = QtWidgets.QVBoxLayout(content_frame) - content_layout.setProperty("spacing", 10) - all = backend.all_money() + content_layout.setSpacing(10) + + try: + if not hasattr(backendModule, "all_money"): + raise AttributeError("backend missing 'all_money' function") - # Total money label - total_money_label = QtWidgets.QLabel(f"Total Money: ${all}", content_frame) - total_money_label.setStyleSheet("font-size: 24px; font-weight: bold; color: #333333;") + total_money = backendModule.all_money() + total_money = int(total_money) if total_money is not None else 0 + except Exception as e: + total_money = f"Error: {str(e)}" + + total_money_label = QtWidgets.QLabel(f"Total Money: ${total_money}", content_frame) + total_money_label.setStyleSheet( + "font-size: 24px; font-weight: bold; color: #333333;" + ) content_layout.addWidget(total_money_label, alignment=QtCore.Qt.AlignCenter) - # Back button + back_button = QtWidgets.QPushButton("Back", content_frame) back_button.setStyleSheet(""" - QPushButton { - background-color: #6c757d; - color: white; - border: none; - border-radius: 4px; - padding: 8px 16px; - font-size: 14px; - } - QPushButton:hover { - background-color: #5a6268; - } - """) + QPushButton { + background-color: #6c757d; + color: white; + border: none; + border-radius: 4px; + padding: 8px 16px; + font-size: 14px; + } + QPushButton:hover { + background-color: #5a6268; + } + """) back_button.clicked.connect(lambda: parent.setCurrentIndex(ADMIN_MENU_PAGE)) + content_layout.addWidget(back_button, alignment=QtCore.Qt.AlignCenter) main_layout.addWidget(content_frame) + return page -#-----------employees menu pages----------- -def create_employee_menu_page(parent, title): + +def create_employee_menu_page( + parent: QtWidgets.QWidget, title: str +) -> tuple[ + QtWidgets.QWidget, + QtWidgets.QPushButton, + QtWidgets.QPushButton, + QtWidgets.QPushButton, + QtWidgets.QPushButton, + QtWidgets.QPushButton, + QtWidgets.QPushButton, + QtWidgets.QPushButton, + QtWidgets.QPushButton, + QtWidgets.QPushButton, +]: + """Create employee menu page with function buttons.""" page, main_layout = create_page_with_header(parent, title) button_frame = create_styled_frame(page) - button_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + button_frame.setSizePolicy( + QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding + ) button_layout = QtWidgets.QVBoxLayout(button_frame) - button_container = create_styled_frame(button_frame, min_size=(300, 0), style="background-color: #ffffff; border-radius: 15px; padding: 20px;") + button_container = create_styled_frame( + button_frame, + min_size=(300, 0), + style="background-color: #ffffff; border-radius: 15px; padding: 20px;", + ) button_container_layout = QtWidgets.QVBoxLayout(button_container) button_container_layout.setSpacing(15) - # Define button labels - button_labels = ["Create Account ", "Show Details", "Add Balance", "Withdraw Money", "Chack Balanace", "Update Account", "list of all Members", "Delete Account", "Back"] - buttons = [] + button_labels = [ + "Create Account", + "Show Details", + "Add Balance", + "Withdraw Money", + "Check Balance", + "Update Account", + "List of All Members", + "Delete Account", + "Back", + ] + buttons: list[QtWidgets.QPushButton] = [] for label in button_labels: - btn:QtWidgets.QPushButton = create_styled_button(button_container, label) + btn = create_styled_button(button_container, label) button_container_layout.addWidget(btn) buttons.append(btn) - button_layout.addWidget(button_container, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + button_layout.addWidget( + button_container, alignment=QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter + ) main_layout.addWidget(button_frame) - return page, *buttons # Unpack as add_button, update_employee, etc. - -def create_account_page(parent, title,update_btn=False): + return page, *buttons + + +def create_account_page( + parent: QtWidgets.QWidget, title: str, update_btn: bool = False +) -> tuple[ + QtWidgets.QWidget, + tuple[ + QtWidgets.QLineEdit, + QtWidgets.QLineEdit, + QtWidgets.QLineEdit, + QtWidgets.QLineEdit, + QtWidgets.QLineEdit, + QtWidgets.QComboBox, + QtWidgets.QPushButton, + ], +]: + """Create page for creating or updating customer accounts.""" page, main_layout = create_page_with_header(parent, title) content_frame = create_styled_frame(page) - content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_frame.setSizePolicy( + QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding + ) content_layout = QtWidgets.QVBoxLayout(content_frame) - form_frame = create_styled_frame(content_frame, min_size=(400, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") + form_frame = create_styled_frame( + content_frame, + min_size=(400, 200), + style="background-color: #ffffff; border-radius: 15px; padding: 10px;", + ) form_layout = QtWidgets.QVBoxLayout(form_frame) form_layout.setSpacing(3) - # Define input fields - fields = ["Name :", "Age :", "Address","Balance :", "Mobile number :"] - edits = [] + fields = ["Name :", "Age :", "Address", "Balance :", "Mobile number :"] + edits: list[QtWidgets.QLineEdit] = [] - for i, field in enumerate(fields): - field_frame, field_edit = create_input_field(form_frame, field,min_label_size=(160, 0)) + for field in fields: + field_frame, field_edit = create_input_field( + form_frame, field, min_label_size=(160, 0) + ) form_layout.addWidget(field_frame) field_edit.setFont(QtGui.QFont("Arial", 12)) - if i == 0: - name_edit = field_edit - elif i == 1: - Age_edit = field_edit - elif i == 2: - Address_edit = field_edit - elif i == 3: - Balance_edit = field_edit - elif i == 4: - Mobile_number_edit = field_edit edits.append(field_edit) - # Dropdown for account type + account_type_label = QtWidgets.QLabel("Account Type :", form_frame) - account_type_label.setStyleSheet("font-size: 14px; font-weight: bold; color: #333333;") + account_type_label.setStyleSheet( + "font-size: 14px; font-weight: bold; color: #333333;" + ) form_layout.addWidget(account_type_label) + account_type_dropdown = QtWidgets.QComboBox(form_frame) account_type_dropdown.addItems(["Savings", "Current", "Fixed Deposit"]) account_type_dropdown.setStyleSheet(""" @@ -660,33 +888,25 @@ def create_account_page(parent, title,update_btn=False): border: none; width: 25px; } - QComboBox::down-arrow { - width: 12px; - height: 12px; - } - QComboBox QAbstractItemView { - border: 1px solid #ccc; - background-color: white; - selection-background-color: #0078d4; - selection-color: white; - } """) form_layout.addWidget(account_type_dropdown) - # Submit button button_frame = create_styled_frame(form_frame, style="padding: 7px;") button_layout = QtWidgets.QVBoxLayout(button_frame) - + if update_btn: submit_button = create_styled_button(button_frame, "Update", min_size=(100, 50)) else: submit_button = create_styled_button(button_frame, "Submit", min_size=(100, 50)) - button_layout.addWidget(submit_button, 0, QtCore.Qt.AlignHCenter) - + button_layout.addWidget(submit_button, alignment=QtCore.Qt.AlignHCenter) form_layout.addWidget(button_frame) - content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + + content_layout.addWidget( + form_frame, alignment=QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter + ) main_layout.addWidget(content_frame) + back_btn = QtWidgets.QPushButton("Back", content_frame) back_btn.setStyleSheet(""" QPushButton { @@ -702,650 +922,892 @@ def create_account_page(parent, title,update_btn=False): } """) back_btn.clicked.connect(lambda: parent.setCurrentIndex(EMPLOYEE_MENU_PAGE)) - main_layout.addWidget(back_btn, 0,alignment=QtCore.Qt.AlignLeft) - - return page,( name_edit, Age_edit,Address_edit,Balance_edit,Mobile_number_edit, account_type_dropdown ,submit_button) + main_layout.addWidget(back_btn, alignment=QtCore.Qt.AlignLeft) + + while len(edits) < 5: + edits.append(QtWidgets.QLineEdit()) + + return page, ( + edits[0], + edits[1], + edits[2], + edits[3], + edits[4], + account_type_dropdown, + submit_button, + ) + -def create_show_details_page1(parent, title): +def create_show_details_page1( + parent: QtWidgets.QWidget, title: str +) -> tuple[QtWidgets.QWidget, tuple[QtWidgets.QLineEdit, QtWidgets.QPushButton]]: + """Create first page for showing account details (search by account number).""" page, main_layout = create_page_with_header(parent, title) + content_frame = create_styled_frame(page) - content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_frame.setSizePolicy( + QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding + ) content_layout = QtWidgets.QVBoxLayout(content_frame) - - form_frame = create_styled_frame(content_frame, min_size=(400, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") + + form_frame = create_styled_frame( + content_frame, + min_size=(400, 200), + style="background-color: #ffffff; border-radius: 15px; padding: 10px;", + ) form_layout = QtWidgets.QVBoxLayout(form_frame) form_layout.setSpacing(3) - # Define input fields - bannk_user = create_input_field(form_frame, "Enter Bank account Number :", min_label_size=(180, 0)) - form_layout.addWidget(bannk_user[0]) - user_account_number= bannk_user[1] + + user_frame, user_account_number = create_input_field( + form_frame, "Enter Bank account Number :", min_label_size=(180, 0) + ) + form_layout.addWidget(user_frame) + submit_button = create_styled_button(form_frame, "Submit", min_size=(100, 50)) form_layout.addWidget(submit_button) - content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + + content_layout.addWidget( + form_frame, alignment=QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter + ) main_layout.addWidget(content_frame) - - return page,(user_account_number,submit_button) -def create_show_details_page2(parent, title): + return page, (user_account_number, submit_button) + + +def create_show_details_page2( + parent: QtWidgets.QWidget, title: str +) -> tuple[ + QtWidgets.QWidget, + tuple[ + QtWidgets.QLineEdit, + QtWidgets.QLineEdit, + QtWidgets.QLineEdit, + QtWidgets.QLineEdit, + QtWidgets.QLineEdit, + QtWidgets.QLineEdit, + QtWidgets.QLineEdit, + QtWidgets.QPushButton, + ], +]: + """Create second page for showing account details (display details).""" page, main_layout = create_page_with_header(parent, title) + content_frame = create_styled_frame(page) - content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_frame.setSizePolicy( + QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding + ) content_layout = QtWidgets.QVBoxLayout(content_frame) - - form_frame = create_styled_frame(content_frame, min_size=(400, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") + + form_frame = create_styled_frame( + content_frame, + min_size=(400, 300), + style="background-color: #ffffff; border-radius: 15px; padding: 10px;", + ) form_layout = QtWidgets.QVBoxLayout(form_frame) - form_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + form_frame.setSizePolicy( + QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding + ) form_layout.setSpacing(3) - - # Define input fields - - labeles = ["Account No: ","Name: ", "Age:", "Address: ", "Balance: ", "Mobile Number: ", "Account Type: "] - for i in range(len(labeles)): - label_frame, input_field = create_input_field(form_frame, labeles[i], min_label_size=(180, 30)) + + labels = [ + "Account No: ", + "Name: ", + "Age:", + "Address: ", + "Balance: ", + "Mobile Number: ", + "Account Type: ", + ] + fields: list[QtWidgets.QLineEdit] = [] + + for label in labels: + label_frame, input_field = create_input_field( + form_frame, label, min_label_size=(180, 30) + ) form_layout.addWidget(label_frame) input_field.setReadOnly(True) input_field.setFont(QtGui.QFont("Arial", 12)) - if i == 0: - account_no_field = input_field - elif i == 1: - name_field = input_field - elif i == 2: - age_field = input_field - elif i == 3: - address_field = input_field - elif i == 4: - balance_field = input_field - elif i == 5: - mobile_number_field = input_field - elif i == 6: - account_type_field = input_field - - exite_btn = create_styled_button(form_frame, "Exit", min_size=(100, 50)) - exite_btn.setStyleSheet(""" - QPushButton { - background-color: #6c757d; - color: white; - border: none; - border-radius: 4px; - padding: 8px 16px; - font-size: 14px; - } - QPushButton:hover { - background-color: #5a6268; - } - """) - exite_btn.clicked.connect(lambda: parent.setCurrentIndex(EMPLOYEE_MENU_PAGE)) - content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + fields.append(input_field) + + exit_btn = create_styled_button(form_frame, "Exit", min_size=(100, 50)) + exit_btn.setStyleSheet(""" + QPushButton { + background-color: #6c757d; + color: white; + border: none; + border-radius: 4px; + padding: 8px 16px; + font-size: 14px; + } + QPushButton:hover { + background-color: #5a6268; + } + """) + exit_btn.clicked.connect(lambda: parent.setCurrentIndex(EMPLOYEE_MENU_PAGE)) + form_layout.addWidget(exit_btn) + + content_layout.addWidget( + form_frame, alignment=QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter + ) main_layout.addWidget(content_frame) - main_layout.addWidget(exite_btn) - - return page,(account_no_field,name_field,age_field,address_field,balance_field,mobile_number_field,account_type_field,exite_btn) - -def update_user(parent, title,input_fields_label,input_fielf:bool=True): + + return page, ( + fields[0], + fields[1], + fields[2], + fields[3], + fields[4], + fields[5], + fields[6], + exit_btn, + ) + + +def update_user( + parent: QtWidgets.QWidget, + title: str, + input_fields_label: str, + input_field: bool = True, +) -> tuple[ + QtWidgets.QWidget, + tuple[ + QtWidgets.QLineEdit, + QtWidgets.QLineEdit, + QtWidgets.QLineEdit, + QtWidgets.QPushButton, + ] + | tuple[QtWidgets.QLineEdit, QtWidgets.QLineEdit, QtWidgets.QPushButton], +]: + """Create page for updating user balance (add/withdraw).""" page, main_layout = create_page_with_header(parent, title) content_frame = create_styled_frame(page) - content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_frame.setSizePolicy( + QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding + ) content_layout = QtWidgets.QVBoxLayout(content_frame) - content_layout.alignment - - form_frame = create_styled_frame(content_frame, min_size=(400, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") + content_layout.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + + form_frame = create_styled_frame( + content_frame, + min_size=(400, 200), + style="background-color: #ffffff; border-radius: 15px; padding: 10px;", + ) form_layout = QtWidgets.QVBoxLayout(form_frame) form_layout.setSpacing(3) - # Define input fields - user = create_input_field(form_frame, "User Name: ", min_label_size=(180, 0)) - user_balance = create_input_field(form_frame, "Balance: ", min_label_size=(180, 0)) - - - # Add input fields to the form layout - form_layout.addWidget(user[0]) - form_layout.addWidget(user_balance[0]) - if input_fielf: - user_update_balance = create_input_field_V(form_frame, input_fields_label, min_label_size=(180, 0)) - form_layout.addWidget(user_update_balance[0]) - - # Store the input fields in variables - user_account_name= user[1] + + user_frame, user_account_name = create_input_field( + form_frame, "User Name: ", min_label_size=(180, 0) + ) + balance_frame, user_balance = create_input_field( + form_frame, "Balance: ", min_label_size=(180, 0) + ) + + form_layout.addWidget(user_frame) + form_layout.addWidget(balance_frame) + user_account_name.setReadOnly(True) - user_account_name.setStyleSheet("background-color: #8a8a8a; border: 1px solid #ccc; border-radius: 4px; padding: 8px;") - user_balance_field = user_balance[1] - user_balance_field.setReadOnly(True) - user_balance_field.setStyleSheet("background-color: #8a8a8a; border: 1px solid #ccc; border-radius: 4px; padding: 8px;") - if input_fielf: - user_update_balance_field = user_update_balance[1] - user_update_balance_field.setStyleSheet("background-color: #f0f0f0; border: 1px solid #ccc; border-radius: 4px; padding: 8px;") - - - # Set the font size for the input fields + user_account_name.setStyleSheet( + "background-color: #8a8a8a; border: 1px solid #ccc; border-radius: 4px; padding: 8px;" + ) + user_balance.setReadOnly(True) + user_balance.setStyleSheet( + "background-color: #8a8a8a; border: 1px solid #ccc; border-radius: 4px; padding: 8px;" + ) + + amount_field: QtWidgets.QLineEdit | None = None + if input_field: + amount_frame, amount_field = create_input_field_V( + form_frame, input_fields_label, min_label_size=(180, 0) + ) + form_layout.addWidget(amount_frame) + if amount_field: + amount_field.setStyleSheet( + "background-color: #f0f0f0; border: 1px solid #ccc; border-radius: 4px; padding: 8px;" + ) + user_account_name.setFont(FONT_SIZE) - user_balance_field.setFont(FONT_SIZE) - if input_fielf: - user_update_balance_field.setFont(FONT_SIZE) - - # Add a submit button + user_balance.setFont(FONT_SIZE) + if amount_field: + amount_field.setFont(FONT_SIZE) + submit_button = create_styled_button(form_frame, "Submit", min_size=(100, 50)) form_layout.addWidget(submit_button) - content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + + content_layout.addWidget(form_frame) main_layout.addWidget(content_frame) + back_btn = create_styled_button(content_frame, "Back", min_size=(100, 50)) back_btn.setStyleSheet(""" - QPushButton { - background-color: #6c757d; - color: white; - border: none; - border-radius: 4px; - padding: 8px 16px; - font-size: 14px; - } - QPushButton:hover { - background-color: #5a6268; - } - """) + QPushButton { + background-color: #6c757d; + color: white; + border: none; + border-radius: 4px; + padding: 8px 16px; + font-size: 14px; + } + QPushButton:hover { + background-color: #5a6268; + } + """) back_btn.clicked.connect(lambda: parent.setCurrentIndex(EMPLOYEE_MENU_PAGE)) - backend - if input_fielf: - return page,(user_account_name,user_balance_field,user_update_balance_field,submit_button) + main_layout.addWidget(back_btn) + + if input_field and amount_field: + return page, (user_account_name, user_balance, amount_field, submit_button) else: - return page,(user_account_name,user_balance_field,submit_button) - -# ------------------------------------------------------------------------------------------------------------- -# === Main Window Setup === -# ------------------------------------------------------------------------------------------------------------- - -def setup_main_window(main_window: QtWidgets.QMainWindow): - """Set up the main window with a stacked widget containing home, admin, and employee pages.""" + return page, (user_account_name, user_balance, submit_button) + + +def setup_main_window( + main_window: QtWidgets.QMainWindow, +) -> tuple[QtWidgets.QStackedWidget, dict]: + """Set up the main window with a stacked widget containing all pages.""" main_window.setObjectName("MainWindow") main_window.resize(800, 600) main_window.setStyleSheet("background-color: #f0f2f5;") - + central_widget = QtWidgets.QWidget(main_window) main_layout = QtWidgets.QHBoxLayout(central_widget) - + stacked_widget = QtWidgets.QStackedWidget(central_widget) - - # Create pages - def switch_to_admin(): + + def switch_to_admin() -> None: stacked_widget.setCurrentIndex(ADMIN_PAGE) - - def switch_to_employee(): + + def switch_to_employee() -> None: stacked_widget.setCurrentIndex(EMPLOYEE_PAGE) - - def exit_app(): + + def exit_app() -> None: QtWidgets.QApplication.quit() - - def admin_login_menu_page(name, password): + + def admin_login_menu_page(name: str, password: str) -> None: + try: + if not hasattr(backendModule, "check_admin"): + raise AttributeError("backend missing 'check_admin' function") + + success = backendModule.check_admin(name, password) + if success: + QtWidgets.QMessageBox.information( + stacked_widget, "Login Successful", f"Welcome, {name}!" + ) + stacked_widget.setCurrentIndex(ADMIN_MENU_PAGE) + else: + QtWidgets.QMessageBox.warning( + stacked_widget, "Login Failed", "Incorrect name or password." + ) + except Exception as e: + QtWidgets.QMessageBox.critical( + stacked_widget, "Error", f"Login error: {str(e)}" + ) + + def add_employee_form_submit( + name: str, password: str, salary: str, position: str + ) -> None: + if all([name, password, salary, position]): try: - # Ideally, here you'd call a backend authentication check - success = backend.check_admin(name, password) - if success: - QtWidgets.QMessageBox.information(stacked_widget, "Login Successful", f"Welcome, {name}!") - stacked_widget.setCurrentIndex(ADMIN_MENU_PAGE) - else: - QtWidgets.QMessageBox.warning(stacked_widget, "Login Failed", "Incorrect name or password.") + if not hasattr(backendModule, "create_employee"): + raise AttributeError("backend missing 'create_employee' function") + + backendModule.create_employee(name, password, salary, position) + show_popup_message( + stacked_widget, "Employee added successfully", ADMIN_MENU_PAGE + ) except Exception as e: - QtWidgets.QMessageBox.critical(stacked_widget, "Error", f"An error occurred during login: {str(e)}") - # show_popup_message(stacked_widget,"Invalid admin credentials",0) - - def add_employee_form_submit(name, password, salary, position): - if ( - len(name) != 0 - and len(password) != 0 - and len(salary) != 0 - and len(position) != 0 - ): - backend.create_employee(name, password, salary, position) - show_popup_message(stacked_widget,"Employee added successfully",ADMIN_MENU_PAGE) - + show_popup_message( + stacked_widget, + f"Error adding employee: {str(e)}", + ADD_EMPLOYEE_PAGE, + ) else: - print("Please fill in all fields") - show_popup_message(stacked_widget,"Please fill in all fields",ADD_EMPLOYEE_PAGE) - def update_employee_data(name, password, salary, position, name_to_update): + show_popup_message( + stacked_widget, "Please fill in all fields", ADD_EMPLOYEE_PAGE + ) + + def handle_update_employee_data( + name: str, password: str, salary: str, position: str, name_to_update: str + ) -> None: try: - cur = backend.cur - if name_to_update: - cur.execute("UPDATE staff SET Name = ? WHERE name = ?", (name, name_to_update)) - - cur.execute("UPDATE staff SET Name = ? WHERE name = ?", (password, name)) - cur.execute("UPDATE staff SET password = ? WHERE name = ?", (password, name)) - cur.execute("UPDATE staff SET salary = ? WHERE name = ?", (salary, name)) - cur.execute("UPDATE staff SET position = ? WHERE name = ?", (position, name)) - backend.conn.commit() - show_popup_message(stacked_widget,"Employee Upadate successfully",UPDATE_EMPLOYEE_PAGE2) - - except: - show_popup_message(stacked_widget,"Please fill in all fields",UPDATE_EMPLOYEE_PAGE2) - - - - # Create Home Page + if not name_to_update: + show_popup_message( + stacked_widget, + "Original employee name is missing.", + UPDATE_EMPLOYEE_PAGE2, + ) + return + + if not any([name, password, salary, position]): + show_popup_message( + stacked_widget, + "Please fill at least one field to update.", + UPDATE_EMPLOYEE_PAGE2, + ) + return + + if name and hasattr(backendModule, "update_employee_name"): + backendModule.update_employee_name(name, name_to_update) + if password and hasattr(backendModule, "update_employee_password"): + backendModule.update_employee_password(password, name_to_update) + if salary and hasattr(backendModule, "update_employee_salary"): + try: + backendModule.update_employee_salary(float(salary), name_to_update) + except ValueError: + show_popup_message( + stacked_widget, + "Salary must be a valid number.", + UPDATE_EMPLOYEE_PAGE2, + ) + return + if position and hasattr(backendModule, "update_employee_position"): + backendModule.update_employee_position(position, name_to_update) + + show_popup_message( + stacked_widget, "Employee updated successfully", ADMIN_MENU_PAGE + ) + except Exception as e: + show_popup_message( + stacked_widget, f"Update error: {str(e)}", UPDATE_EMPLOYEE_PAGE2 + ) + home_page = create_home_page( - stacked_widget, - switch_to_admin, - switch_to_employee, - exit_app - ) - # ------------------------------------------------------------------------------------------------ - # -------------------------------------Admin panel page --------------------------------------- - # ------------------------------------------------------------------------------------------------ - # Create Admin Login Page + stacked_widget, switch_to_admin, switch_to_employee, exit_app + ) + admin_page, admin_name, admin_password, admin_submit = create_login_page( - stacked_widget, - title="Admin Login" + stacked_widget, "Admin Login" ) admin_password.setEchoMode(QtWidgets.QLineEdit.Password) - admin_name.setFont(QtGui.QFont("Arial", 10)) - admin_password.setFont(QtGui.QFont("Arial", 10)) admin_name.setPlaceholderText("Enter your name") admin_password.setPlaceholderText("Enter your password") - admin_submit.clicked.connect( - lambda: admin_login_menu_page( - admin_name.text(), - admin_password.text() - ) + lambda: admin_login_menu_page(admin_name.text(), admin_password.text()) ) - # Create Admin Menu Page - admin_menu_page, add_button, update_button, list_button, money_button, back_button = create_admin_menu_page( - stacked_widget + ( + admin_menu_page, + add_button, + update_button, + list_button, + money_button, + back_button, + ) = create_admin_menu_page(stacked_widget) + add_button.clicked.connect( + lambda: stacked_widget.setCurrentIndex(ADD_EMPLOYEE_PAGE) + ) + update_button.clicked.connect( + lambda: stacked_widget.setCurrentIndex(UPDATE_EMPLOYEE_PAGE1) + ) + list_button.clicked.connect( + lambda: stacked_widget.setCurrentIndex(EMPLOYEE_LIST_PAGE) ) - - add_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(ADD_EMPLOYEE_PAGE)) - update_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(UPDATE_EMPLOYEE_PAGE1)) - list_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_LIST_PAGE)) back_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(HOME_PAGE)) - money_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(ADMIN_TOTAL_MONEY)) - # Create Add Employee Page - add_employee_page, emp_name, emp_password, emp_salary, emp_position, emp_submit = create_add_employee_page( - stacked_widget, - title="Add Employee" - ) - - # Update Employee Page + money_button.clicked.connect( + lambda: stacked_widget.setCurrentIndex(ADMIN_TOTAL_MONEY) + ) + + add_employee_page, emp_name, emp_password, emp_salary, emp_position, emp_submit = ( + create_add_employee_page(stacked_widget, "Add Employee") + ) + emp_submit.clicked.connect( + lambda: add_employee_form_submit( + emp_name.text().strip(), + emp_password.text().strip(), + emp_salary.text().strip(), + emp_position.text().strip(), + ) + ) + u_employee_page1 = get_employee_name(stacked_widget) - # apply the update_employee_data function to the submit button - - u_employee_page2 ,u_employee_name, u_employee_password, u_employee_salary, u_employee_position,u_employee_update = create_add_employee_page(stacked_widget,"Update Employee Details",update_btn=True) - def populate_employee_data(): + + ( + u_employee_page2, + u_employee_name, + u_employee_password, + u_employee_salary, + u_employee_position, + u_employee_update, + ) = create_add_employee_page( + stacked_widget, "Update Employee Details", update_btn=True + ) + + def populate_employee_data() -> None: global employee_data if employee_data: - print("employee_data is not None") - u_employee_name.setText(str(employee_data[0])) # Name - u_employee_password.setText(str(employee_data[1])) # Password - u_employee_salary.setText(str(employee_data[2])) # Salary - u_employee_position.setText(str(employee_data[3])) # Position + u_employee_name.setText(str(employee_data[0])) + u_employee_password.setText(str(employee_data[1])) + u_employee_salary.setText(str(employee_data[2])) + u_employee_position.setText(str(employee_data[3])) else: - # Clear fields if no employee data is available - print("employee_data is None") - u_employee_name.clear() - u_employee_password.clear() - u_employee_salary.clear() - u_employee_position.clear() - QtWidgets.QMessageBox.warning(stacked_widget, "No Data", "No employee data available to display.") - def on_page_changed(index): - if index == 6: # update_employee_page2 is at index 6 - populate_employee_data() - - # Connect the currentChanged signal to the on_page_changed function - stacked_widget.currentChanged.connect(on_page_changed) - def update_employee_data(name, password, salary, position, name_to_update): - try: - if not name_to_update: - show_popup_message(stacked_widget, "Original employee name is missing.", UPDATE_EMPLOYEE_PAGE2) - return - if not (name or password or salary or position): - show_popup_message(stacked_widget, "Please fill at least one field to update.", UPDATE_EMPLOYEE_PAGE2) - return - if name: - backend.update_employee_name(name, name_to_update) - if password: - backend.update_employee_password(password, name_to_update) - if salary: - try: - salary = int(salary) - backend.update_employee_salary(salary, name_to_update) - except ValueError: - show_popup_message(stacked_widget, "Salary must be a valid number.", 5) - return - if position: - backend.update_employee_position(position, name_to_update) - show_popup_message(stacked_widget, "Employee updated successfully.", ADMIN_MENU_PAGE) - except Exception as e: - show_popup_message(stacked_widget, f"Error updating employee: {str(e)}",UPDATE_EMPLOYEE_PAGE2,show_cancel=True,cancel_page=ADMIN_MENU_PAGE) + for field in [ + u_employee_name, + u_employee_password, + u_employee_salary, + u_employee_position, + ]: + field.clear() + + stacked_widget.currentChanged.connect( + lambda index: populate_employee_data() + if index == UPDATE_EMPLOYEE_PAGE2 + else None + ) u_employee_update.clicked.connect( - lambda: update_employee_data( - u_employee_name.text().strip(), - u_employee_password.text().strip(), - u_employee_salary.text().strip(), - u_employee_position.text().strip(), - employee_data[0] if employee_data else "" + lambda: handle_update_employee_data( + u_employee_name.text().strip(), + u_employee_password.text().strip(), + u_employee_salary.text().strip(), + u_employee_position.text().strip(), + employee_data[0] if employee_data else "", ) ) + employee_list_page = show_employee_list_page(stacked_widget, "Employee List") + admin_total_money_page = show_total_money(stacked_widget, "Total Money") - emp_submit.clicked.connect( - lambda: add_employee_form_submit( - emp_name.text(), - emp_password.text(), - emp_salary.text(), - emp_position.text() - ) + employee_page, employee_name, employee_password, employee_submit = ( + create_login_page(stacked_widget, "Employee Login") ) - # show employee list page - employee_list_page = show_employee_list_page(stacked_widget,"Employee List") - admin_total_money = show_total_money(stacked_widget,"Total Money") - # ------------------------------------------------------------------------------------------------ - # -------------------------------------Employee panel page --------------------------------------- - # ------------------------------------------------------------------------------------------------ - - # Create Employee Login Page - employee_page, employee_name, employee_password, employee_submit = create_login_page( - stacked_widget, - title="Employee Login" - ) - employee_submit.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_MENU_PAGE)) - employee_menu_page, E_Create_Account, E_Show_Details, E_add_Balance, E_Withdraw_Money, E_Chack_Balanace, E_Update_Account, E_list_of_all_Members, E_Delete_Account, E_Back= create_employee_menu_page(stacked_widget,"Employee Menu") - # List of all page - E_Create_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_CREATE_ACCOUNT_PAGE)) - E_Show_Details.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_SHOW_DETAILS_PAGE1)) - E_add_Balance.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_ADD_BALANCE_SEARCH)) - E_Withdraw_Money.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_WITHDRAW_MONEY_SEARCH)) - E_Chack_Balanace.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_CHECK_BALANCE_SEARCH)) - E_Update_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_UPDATE_ACCOUNT_SEARCH)) - # E_list_of_all_Members.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_LIST_OF_ALL_MEMBERS_PAGE)) - # E_Delete_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_DELETE_ACCOUNT_PAGE)) - # E_Back.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_MENU_PAGE)) - - employee_create_account_page,all_employee_menu_btn = create_account_page(stacked_widget, "Create Account") - all_employee_menu_btn[6].clicked.connect(lambda: add_account_form_submit( - all_employee_menu_btn[0].text().strip(), - all_employee_menu_btn[1].text().strip(), - all_employee_menu_btn[2].text().strip(), - all_employee_menu_btn[3].text().strip(), - all_employee_menu_btn[5].currentText(), - all_employee_menu_btn[4].text().strip() - )) - - def add_account_form_submit(name, age, address, balance, account_type, mobile): - if ( - len(name) != 0 - and len(age) != 0 - and len(address) != 0 - and len(balance) != 0 - and len(account_type) != 0 - and len(mobile) != 0 - ): - try: - balance = int(balance) - except ValueError: - show_popup_message(stacked_widget, "Balance must be a valid number", EMPLOYEE_CREATE_ACCOUNT_PAGE) - return - if balance < 0: - show_popup_message(stacked_widget, "Balance cannot be negative",EMPLOYEE_CREATE_ACCOUNT_PAGE) - return - if account_type not in ["Savings", "Current","Fixed Deposit"]: - show_popup_message(stacked_widget, "Invalid account type", EMPLOYEE_CREATE_ACCOUNT_PAGE) - return - if len(mobile) != 10: - show_popup_message(stacked_widget, "Mobile number must be 10 digits", EMPLOYEE_CREATE_ACCOUNT_PAGE) - return - if not mobile.isdigit(): - show_popup_message(stacked_widget, "Mobile number must contain only digits", EMPLOYEE_CREATE_ACCOUNT_PAGE) - return - if not name.isalpha(): - show_popup_message(stacked_widget, "Name must contain only alphabets", EMPLOYEE_CREATE_ACCOUNT_PAGE) - return - if not age.isdigit(): - show_popup_message(stacked_widget, "Age must contain only digits", EMPLOYEE_CREATE_ACCOUNT_PAGE) + employee_submit.clicked.connect( + lambda: stacked_widget.setCurrentIndex(EMPLOYEE_MENU_PAGE) + ) + + ( + employee_menu_page, + e_create_account, + e_show_details, + e_add_balance, + e_withdraw_money, + e_check_balance, + e_update_account, + e_list_members, + e_delete_account, + e_back, + ) = create_employee_menu_page(stacked_widget, "Employee Menu") + + e_create_account.clicked.connect( + lambda: stacked_widget.setCurrentIndex(EMPLOYEE_CREATE_ACCOUNT_PAGE) + ) + e_show_details.clicked.connect( + lambda: stacked_widget.setCurrentIndex(EMPLOYEE_SHOW_DETAILS_PAGE1) + ) + e_add_balance.clicked.connect( + lambda: stacked_widget.setCurrentIndex(EMPLOYEE_ADD_BALANCE_SEARCH) + ) + e_withdraw_money.clicked.connect( + lambda: stacked_widget.setCurrentIndex(EMPLOYEE_WITHDRAW_MONEY_SEARCH) + ) + e_check_balance.clicked.connect( + lambda: stacked_widget.setCurrentIndex(EMPLOYEE_CHECK_BALANCE_SEARCH) + ) + e_update_account.clicked.connect( + lambda: stacked_widget.setCurrentIndex(EMPLOYEE_UPDATE_ACCOUNT_SEARCH) + ) + e_back.clicked.connect(lambda: stacked_widget.setCurrentIndex(HOME_PAGE)) + + employee_create_account_page, create_account_fields = create_account_page( + stacked_widget, "Create Account" + ) + ( + name_edit, + age_edit, + address_edit, + balance_edit, + mobile_edit, + account_type, + create_submit, + ) = create_account_fields + + def handle_create_account() -> None: + try: + name = name_edit.text().strip() + age = age_edit.text().strip() + address = address_edit.text().strip() + balance = balance_edit.text().strip() + mobile = mobile_edit.text().strip() + acc_type = account_type.currentText() + + if not all([name, age, address, balance, mobile, acc_type]): + show_popup_message( + stacked_widget, + "Please fill all fields", + EMPLOYEE_CREATE_ACCOUNT_PAGE, + ) return - if int(age) < 18: - show_popup_message(stacked_widget, "Age must be greater than 18", EMPLOYEE_CREATE_ACCOUNT_PAGE) + + if not age.isdigit() or int(age) < 18: + show_popup_message( + stacked_widget, + "Age must be a number and at least 18", + EMPLOYEE_CREATE_ACCOUNT_PAGE, + ) return - if len(address) < 10: - show_popup_message(stacked_widget, "Address must be at least 10 characters long", EMPLOYEE_CREATE_ACCOUNT_PAGE) + + if not balance.isdigit() or int(balance) < 0: + show_popup_message( + stacked_widget, + "Balance must be a positive number", + EMPLOYEE_CREATE_ACCOUNT_PAGE, + ) return - backend.create_customer(name, age, address, balance, account_type, mobile) - all_employee_menu_btn[0].setText("") - all_employee_menu_btn[1].setText("") - all_employee_menu_btn[2].setText("") - all_employee_menu_btn[3].setText("") - all_employee_menu_btn[4].setText("") - all_employee_menu_btn[5].currentText(), - show_popup_message(stacked_widget, "Account created successfully", EMPLOYEE_MENU_PAGE, False) - else: - show_popup_message(stacked_widget, "Please fill in all fields", EMPLOYEE_CREATE_ACCOUNT_PAGE) - # Add pages to stacked widget - - show_bank_user_data_page1,show_bank_user_other1 = create_show_details_page1(stacked_widget, "Show Details") - show_bank_user_data_page2,show_bank_user_other2 = create_show_details_page2(stacked_widget, "Show Details") - - show_bank_user_other1[1].clicked.connect(lambda: show_bank_user_data_page1_submit_btn(int(show_bank_user_other1[0].text().strip()))) - def show_bank_user_data_page1_submit_btn(name:int): - account_data = backend.get_details(name) - if account_data: - show_bank_user_other1[0].setText("") - show_bank_user_other2[0].setText(str(account_data[0])) - show_bank_user_other2[1].setText(str(account_data[1])) - show_bank_user_other2[2].setText(str(account_data[2])) - show_bank_user_other2[3].setText(str(account_data[3])) - show_bank_user_other2[4].setText(str(account_data[4])) - show_bank_user_other2[5].setText(str(account_data[5])) - show_bank_user_other2[6].setText(str(account_data[6])) - stacked_widget.setCurrentIndex(EMPLOYEE_SHOW_DETAILS_PAGE2) - else: - show_popup_message(stacked_widget, "Account not found", EMPLOYEE_SHOW_DETAILS_PAGE1) - - def setup_balance_operation_flow( - stacked_widget, - title_search, - placeholder, - title_form, - action_button_text, - success_message, - backend_action_fn, - stacked_page_index, - search_index, - page_index, - need_input=True - ): - # Create search UI - search_page, search_widgets = search_result(stacked_widget, title_search, placeholder) - search_input = search_widgets[0] - search_button = search_widgets[1] - - # Create update UI - form_page, form_widgets = update_user(stacked_widget, title_form, action_button_text,need_input) - if need_input: - name_field, balance_field, amount_field, action_button = form_widgets - else: - name_field, balance_field, action_button = form_widgets - def on_search_submit(): - try: - account_number = int(search_input.text().strip()) - except ValueError: - show_popup_message(stacked_widget, "Please enter a valid account number.", search_index) + if not mobile.isdigit() or len(mobile) != 10: + show_popup_message( + stacked_widget, + "Mobile number must be 10 digits", + EMPLOYEE_CREATE_ACCOUNT_PAGE, + ) return - if backend.check_acc_no(account_number): - account_data = backend.get_details(account_number) + if not hasattr(backendModule, "create_customer"): + raise AttributeError("backend missing 'create_customer' function") + + backendModule.create_customer(name, age, address, balance, acc_type, mobile) + + for field in [name_edit, age_edit, address_edit, balance_edit, mobile_edit]: + field.clear() + + show_popup_message( + stacked_widget, "Account created successfully", EMPLOYEE_MENU_PAGE + ) + except Exception as e: + show_popup_message( + stacked_widget, + f"Error creating account: {str(e)}", + EMPLOYEE_CREATE_ACCOUNT_PAGE, + ) + + create_submit.clicked.connect(handle_create_account) + + show_details_page1, show_details_widgets1 = create_show_details_page1( + stacked_widget, "Show Details" + ) + show_details_input1, show_details_btn1 = show_details_widgets1 + + show_details_page2, show_details_widgets2 = create_show_details_page2( + stacked_widget, "Account Details" + ) + ( + acc_no_field, + name_field, + age_field, + address_field, + balance_field, + mobile_field, + acc_type_field, + exit_btn, + ) = show_details_widgets2 + + def handle_show_details_submit() -> None: + try: + account_number = int(show_details_input1.text().strip()) + if not hasattr(backendModule, "check_acc_no"): + raise AttributeError("backend missing 'check_acc_no' function") + + if backendModule.check_acc_no(account_number): + if not hasattr(backendModule, "get_details"): + raise AttributeError("backend missing 'get_details' function") + + account_data = backendModule.get_details(account_number) + acc_no_field.setText(str(account_data[0])) name_field.setText(str(account_data[1])) + age_field.setText(str(account_data[2])) + address_field.setText(str(account_data[3])) balance_field.setText(str(account_data[4])) - stacked_widget.setCurrentIndex(page_index) + mobile_field.setText(str(account_data[5])) + acc_type_field.setText(str(account_data[6])) + stacked_widget.setCurrentIndex(EMPLOYEE_SHOW_DETAILS_PAGE2) else: - show_popup_message(stacked_widget, "Account not found", search_index, show_cancel=True, cancel_page=EMPLOYEE_MENU_PAGE) + show_popup_message( + stacked_widget, "Account not found", EMPLOYEE_SHOW_DETAILS_PAGE1 + ) + except ValueError: + show_popup_message( + stacked_widget, + "Please enter a valid account number", + EMPLOYEE_SHOW_DETAILS_PAGE1, + ) + except Exception as e: + show_popup_message( + stacked_widget, f"Error: {str(e)}", EMPLOYEE_SHOW_DETAILS_PAGE1 + ) + + show_details_btn1.clicked.connect(handle_show_details_submit) + + def setup_balance_operation( + title_search: str, + placeholder: str, + title_form: str, + action_text: str, + success_msg: str, + backend_func: str, + search_idx: int, + page_idx: int, + need_input: bool = True, + ) -> tuple[QtWidgets.QWidget, QtWidgets.QWidget]: + search_page, search_widgets = search_result( + stacked_widget, title_search, placeholder + ) + search_input, search_btn = search_widgets + + form_page, form_widgets = update_user( + stacked_widget, title_form, action_text, need_input + ) + + if need_input and len(form_widgets) == 4: + name_field, balance_field, amount_field, action_btn = form_widgets + else: + name_field, balance_field, action_btn = form_widgets + amount_field = None + + def on_search() -> None: + try: + account_number = int(search_input.text().strip()) + if not hasattr(backendModule, "check_acc_no"): + raise AttributeError("backend missing 'check_acc_no' function") + + if backendModule.check_acc_no(account_number): + if not hasattr(backendModule, "get_details"): + raise AttributeError("backend missing 'get_details' function") + + account_data = backendModule.get_details(account_number) + name_field.setText(str(account_data[1])) + balance_field.setText(str(account_data[4])) + stacked_widget.setCurrentIndex(page_idx) + else: + show_popup_message(stacked_widget, "Account not found", search_idx) + except ValueError: + show_popup_message( + stacked_widget, "Please enter a valid account number", search_idx + ) + except Exception as e: + show_popup_message( + stacked_widget, f"Search error: {str(e)}", search_idx + ) - def on_action_submit(): + def on_action() -> None: try: account_number = int(search_input.text().strip()) - amount = int(amount_field.text().strip()) - backend_action_fn(amount, account_number) - name_field.setText("") - balance_field.setText("") - search_input.setText("") - show_popup_message(stacked_widget, success_message, EMPLOYEE_MENU_PAGE) + if not hasattr(backendModule, backend_func): + raise AttributeError(f"backend missing '{backend_func}' function") + + if need_input and amount_field: + amount = float(amount_field.text().strip()) + getattr(backendModule, backend_func)(amount, account_number) + else: + getattr(backendModule, backend_func)(account_number) + + search_input.clear() + name_field.clear() + balance_field.clear() + if amount_field: + amount_field.clear() + + show_popup_message(stacked_widget, success_msg, EMPLOYEE_MENU_PAGE) except ValueError: - show_popup_message(stacked_widget, "Enter valid numeric amount.", page_index) + show_popup_message( + stacked_widget, "Please enter a valid amount", page_idx + ) + except Exception as e: + show_popup_message( + stacked_widget, f"Operation error: {str(e)}", page_idx + ) - search_button.clicked.connect(on_search_submit) - action_button.clicked.connect(on_action_submit) + search_btn.clicked.connect(on_search) + action_btn.clicked.connect(on_action) return search_page, form_page - # Add Balance Flow - add_balance_search_page, add_balance_page = setup_balance_operation_flow( - stacked_widget=stacked_widget, - title_search="Add Balance", - placeholder="Enter Account Number: ", - title_form="Add Balance User Account", - action_button_text="Enter Amount: ", - success_message="Balance updated successfully", - backend_action_fn=backend.update_balance, - stacked_page_index=EMPLOYEE_ADD_BALANCE_SEARCH, - search_index=EMPLOYEE_ADD_BALANCE_SEARCH, - page_index=EMPLOYEE_ADD_BALANCE_PAGE, - ) - - # Withdraw Money Flow - withdraw_money_search_page, withdraw_money_page = setup_balance_operation_flow( - stacked_widget=stacked_widget, - title_search="Withdraw Money", - placeholder="Enter Account Number: ", - title_form="Withdraw Money From User Account", - action_button_text="Withdraw Amount: ", - success_message="Amount withdrawn successfully", - backend_action_fn=backend.deduct_balance, - stacked_page_index=EMPLOYEE_WITHDRAW_MONEY_SEARCH, - search_index=EMPLOYEE_WITHDRAW_MONEY_SEARCH, - page_index=EMPLOYEE_WITHDRAW_MONEY_PAGE, - ) - - check_balance_search_page, check_balance_page = setup_balance_operation_flow( - stacked_widget=stacked_widget, - title_search="Check Balance", - placeholder="Enter Account Number: ", - title_form="Check Balance", - action_button_text="Check Balance: ", - success_message="Balance checked successfully", - backend_action_fn=backend.check_balance, - stacked_page_index=EMPLOYEE_CHECK_BALANCE_SEARCH, - search_index=EMPLOYEE_CHECK_BALANCE_SEARCH, - page_index=EMPLOYEE_CHECK_BALANCE_PAGE, - need_input = False - ) - def find_and_hide_submit_button(page): - # Find all QPushButton widgets in the page - buttons = page.findChildren(QtWidgets.QPushButton) - for button in buttons: - if button.text() == "Submit": - button.hide() - break - - find_and_hide_submit_button(check_balance_page) - - # Update Employee details - update_empolyee_search_page,update_empolyee_search_other = search_result(stacked_widget, "Update Employee Details", "Enter Employee ID: ") - update_employee_page,update_employee_other = create_account_page(stacked_widget, "Update Employee", True) - name_edit = update_employee_other[0] - Age_edit = update_employee_other[1] - Address_edit = update_employee_other[2] - Balance_edit = update_employee_other[3] - Mobile_number_edit = update_employee_other[4] - account_type_dropdown = update_employee_other[5] - # name_edit, Age_edit,Address_edit,Balance_edit,Mobile_number_edit, account_type_dropdown ,submit_button - - update_empolyee_search_other[1].clicked.connect(lambda:update_employee_search_submit()) - update_employee_other[6].clicked.connect(lambda:update_employee_submit()) - def update_employee_search_submit(): + + add_balance_search_page, add_balance_page = setup_balance_operation( + "Add Balance", + "Enter Account Number: ", + "Add Balance", + "Enter Amount: ", + "Balance updated successfully", + "update_balance", + EMPLOYEE_ADD_BALANCE_SEARCH, + EMPLOYEE_ADD_BALANCE_PAGE, + ) + + withdraw_search_page, withdraw_page = setup_balance_operation( + "Withdraw Money", + "Enter Account Number: ", + "Withdraw Money", + "Withdraw Amount: ", + "Amount withdrawn successfully", + "deduct_balance", + EMPLOYEE_WITHDRAW_MONEY_SEARCH, + EMPLOYEE_WITHDRAW_MONEY_PAGE, + ) + + check_balance_search_page, check_balance_page = setup_balance_operation( + "Check Balance", + "Enter Account Number: ", + "Check Balance", + "", + "Balance checked successfully", + "check_balance", + EMPLOYEE_CHECK_BALANCE_SEARCH, + EMPLOYEE_CHECK_BALANCE_PAGE, + False, + ) + + update_account_search_page, update_account_search_widgets = search_result( + stacked_widget, "Update Account", "Enter Account Number: " + ) + update_account_input, update_account_btn = update_account_search_widgets + + update_account_page, update_account_fields = create_account_page( + stacked_widget, "Update Account", update_btn=True + ) + ( + u_name_edit, + u_age_edit, + u_address_edit, + u_balance_edit, + u_mobile_edit, + u_acc_type, + u_submit_btn, + ) = update_account_fields + u_balance_edit.setReadOnly(True) + + def handle_update_search() -> None: try: - user_data = backend.get_details(int(update_empolyee_search_other[0].text().strip())) - print("Featch data: ",user_data) - name_edit.setText(str(user_data[1])) - Age_edit.setText(str(user_data[2])) - Address_edit.setText(str(user_data[3])) - Balance_edit.setText(str(user_data[4])) - Mobile_number_edit.setText(str(user_data[6])) - Balance_edit.setDisabled(True) - account_type_dropdown.setCurrentText(str(user_data[5])) - stacked_widget.setCurrentIndex(EMPLOYEE_UPDATE_ACCOUNT_PAGE) + account_number = int(update_account_input.text().strip()) + if not hasattr(backendModule, "get_details"): + raise AttributeError("backend missing 'get_details' function") + + account_data = backendModule.get_details(account_number) + if account_data: + u_name_edit.setText(str(account_data[1])) + u_age_edit.setText(str(account_data[2])) + u_address_edit.setText(str(account_data[3])) + u_balance_edit.setText(str(account_data[4])) + u_mobile_edit.setText(str(account_data[5])) + u_acc_type.setCurrentText(str(account_data[6])) + stacked_widget.setCurrentIndex(EMPLOYEE_UPDATE_ACCOUNT_PAGE) + else: + show_popup_message( + stacked_widget, "Account not found", EMPLOYEE_UPDATE_ACCOUNT_SEARCH + ) except ValueError: - show_popup_message(stacked_widget, "Enter valid numeric employee ID.", EMPLOYEE_MENU_PAGE) - - def update_employee_submit(): + show_popup_message( + stacked_widget, + "Please enter a valid account number", + EMPLOYEE_UPDATE_ACCOUNT_SEARCH, + ) + except Exception as e: + show_popup_message( + stacked_widget, f"Error: {str(e)}", EMPLOYEE_UPDATE_ACCOUNT_SEARCH + ) + + def handle_account_update() -> None: try: - user_data = backend.get_details(int(update_empolyee_search_other[0].text().strip())) - name=name_edit.text().strip() - age = int(Age_edit.text().strip()) - address = Address_edit.text().strip() - mobile_number = int(Mobile_number_edit.text().strip()) - account_type = account_type_dropdown.currentText() - print(name,age,address,mobile_number,account_type) - backend.update_name_in_bank_table(name,user_data[0]) - backend.update_age_in_bank_table(age,user_data[0]) - backend.update_address_in_bank_table(address,user_data[0]) - backend.update_address_in_bank_table(address,user_data[0]) - backend.update_mobile_number_in_bank_table(mobile_number,user_data[0]) - backend.update_acc_type_in_bank_table(account_type,user_data[0]) - - show_popup_message(stacked_widget, "Employee details updated successfully", EMPLOYEE_MENU_PAGE) - stacked_widget.setCurrentIndex(EMPLOYEE_MENU_PAGE) - except ValueError as e: - print(e) - show_popup_message(stacked_widget, "Enter valid numeric employee ID.", EMPLOYEE_MENU_PAGE) - - - stacked_widget.addWidget(home_page)#0 - stacked_widget.addWidget(admin_page)#1 - stacked_widget.addWidget(employee_page)#2 - stacked_widget.addWidget(admin_menu_page)#3 - stacked_widget.addWidget(add_employee_page)#4 - stacked_widget.addWidget(u_employee_page1)#5 - stacked_widget.addWidget(u_employee_page2)#6 - stacked_widget.addWidget(employee_list_page)#7 - stacked_widget.addWidget(admin_total_money)#8 - stacked_widget.addWidget(employee_menu_page)#9 - stacked_widget.addWidget(employee_create_account_page)#10 - stacked_widget.addWidget(show_bank_user_data_page1)#11 - stacked_widget.addWidget(show_bank_user_data_page2)#12 - stacked_widget.addWidget(add_balance_search_page)#13 - stacked_widget.addWidget(add_balance_page)#14 - stacked_widget.addWidget(withdraw_money_search_page)#15 - stacked_widget.addWidget(withdraw_money_page)#16 - stacked_widget.addWidget(check_balance_search_page)#17 - stacked_widget.addWidget(check_balance_page)#18 - stacked_widget.addWidget(update_empolyee_search_page)#19 - stacked_widget.addWidget(update_employee_page)#20 - - - + account_number = int(update_account_input.text().strip()) + name = u_name_edit.text().strip() + age = u_age_edit.text().strip() + address = u_address_edit.text().strip() + mobile = u_mobile_edit.text().strip() + acc_type = u_acc_type.currentText() + + if not all([name, age, address, mobile, acc_type]): + show_popup_message( + stacked_widget, + "Please fill all fields", + EMPLOYEE_UPDATE_ACCOUNT_PAGE, + ) + return + + if not age.isdigit() or int(age) < 18: + show_popup_message( + stacked_widget, + "Age must be a number and at least 18", + EMPLOYEE_UPDATE_ACCOUNT_PAGE, + ) + return + + if not mobile.isdigit() or len(mobile) != 10: + show_popup_message( + stacked_widget, + "Mobile number must be 10 digits", + EMPLOYEE_UPDATE_ACCOUNT_PAGE, + ) + return + + update_functions = [ + ("update_name_in_bank_table", name), + ("update_age_in_bank_table", age), + ("update_address_in_bank_table", address), + ("update_mobile_number_in_bank_table", mobile), + ("update_acc_type_in_bank_table", acc_type), + ] + + for func_name, value in update_functions: + if not hasattr(backendModule, func_name): + raise AttributeError(f"backend missing '{func_name}' function") + getattr(backendModule, func_name)(value, account_number) + + update_account_input.clear() + show_popup_message( + stacked_widget, "Account updated successfully", EMPLOYEE_MENU_PAGE + ) + except ValueError: + show_popup_message( + stacked_widget, "Invalid account number", EMPLOYEE_UPDATE_ACCOUNT_PAGE + ) + except Exception as e: + show_popup_message( + stacked_widget, f"Update error: {str(e)}", EMPLOYEE_UPDATE_ACCOUNT_PAGE + ) + + update_account_btn.clicked.connect(handle_update_search) + u_submit_btn.clicked.connect(handle_account_update) + + stacked_widget.addWidget(home_page) + stacked_widget.addWidget(admin_page) + stacked_widget.addWidget(employee_page) + stacked_widget.addWidget(admin_menu_page) + stacked_widget.addWidget(add_employee_page) + stacked_widget.addWidget(u_employee_page1) + stacked_widget.addWidget(u_employee_page2) + stacked_widget.addWidget(employee_list_page) + stacked_widget.addWidget(admin_total_money_page) + stacked_widget.addWidget(employee_menu_page) + stacked_widget.addWidget(employee_create_account_page) + stacked_widget.addWidget(show_details_page1) + stacked_widget.addWidget(show_details_page2) + stacked_widget.addWidget(add_balance_search_page) + stacked_widget.addWidget(add_balance_page) + stacked_widget.addWidget(withdraw_search_page) + stacked_widget.addWidget(withdraw_page) + stacked_widget.addWidget(check_balance_search_page) + stacked_widget.addWidget(check_balance_page) + stacked_widget.addWidget(update_account_search_page) + stacked_widget.addWidget(update_account_page) + main_layout.addWidget(stacked_widget) main_window.setCentralWidget(central_widget) - - # Set initial page - stacked_widget.setCurrentIndex(9) - + + stacked_widget.setCurrentIndex(HOME_PAGE) + return stacked_widget, { "admin_name": admin_name, "admin_password": admin_password, "admin_submit": admin_submit, "employee_name": employee_name, "employee_password": employee_password, - "employee_submit": employee_submit + "employee_submit": employee_submit, } -def main(): + +def main() -> None: """Main function to launch the application.""" app = QtWidgets.QApplication(sys.argv) main_window = QtWidgets.QMainWindow() stacked_widget, widgets = setup_main_window(main_window) - - # Example: Connect submit buttons to print input values - main_window.show() sys.exit(app.exec_()) -# ------------------------------------------------------------------------------------------------------------- + if __name__ == "__main__": main() -# TO-DO: -# 1.refese the employee list page after add or delete or update employee - diff --git a/bank_managment_system/backend.py b/bank_managment_system/backend.py deleted file mode 100644 index 673df2dc430..00000000000 --- a/bank_managment_system/backend.py +++ /dev/null @@ -1,177 +0,0 @@ -import sqlite3 -import os -# Making connection with database -def connect_database(): - global conn - global cur - conn = sqlite3.connect(os.path.join(os.path.dirname(__file__), "bankmanaging.db")) - cur = conn.cursor() - cur.execute( - """ - CREATE TABLE IF NOT EXISTS bank ( - acc_no INTEGER PRIMARY KEY, - name TEXT, - age INTEGER, - address TEXT, - balance INTEGER, - account_type TEXT, - mobile_number TEXT - ) - """ - ) - cur.execute( - """ - CREATE TABLE IF NOT EXISTS staff ( - name TEXT, - pass TEXT, - salary INTEGER, - position TEXT - ) - """ - ) - cur.execute("CREATE TABLE IF NOT EXISTS admin (name TEXT, pass TEXT)") - - # Only insert admin if not exists - cur.execute("SELECT COUNT(*) FROM admin") - if cur.fetchone()[0] == 0: - cur.execute("INSERT INTO admin VALUES (?, ?)", ('admin', 'admin123')) - - conn.commit() - - # Fetch last account number to avoid duplicate or incorrect numbering - cur.execute("SELECT acc_no FROM bank ORDER BY acc_no DESC LIMIT 1") - acc = cur.fetchone() - global acc_no - acc_no = 1 if acc is None else acc[0] + 1 - -# Check admin details in database -def check_admin(name, password): - cur.execute("SELECT * FROM admin WHERE name = ? AND pass = ?", (name, password)) - return cur.fetchone() is not None - -# Create employee in database -def create_employee(name, password, salary, position): - cur.execute("INSERT INTO staff VALUES (?, ?, ?, ?)", (name, password, salary, position)) - conn.commit() - -# Check employee login details -def check_employee(name, password): - cur.execute("SELECT 1 FROM staff WHERE name = ? AND pass = ?", (name, password)) - return cur.fetchone() is not None - -# Create customer in database -def create_customer(name, age, address, balance, acc_type, mobile_number): - global acc_no - cur.execute( - "INSERT INTO bank VALUES (?, ?, ?, ?, ?, ?, ?)", - (acc_no, name, age, address, balance, acc_type, mobile_number) - ) - conn.commit() - acc_no += 1 - return acc_no - 1 - -# Check if account number exists -def check_acc_no(acc_no): - cur.execute("SELECT 1 FROM bank WHERE acc_no = ?", (acc_no,)) - return cur.fetchone() is not None - -# Get customer details -def get_details(acc_no): - cur.execute("SELECT * FROM bank WHERE acc_no = ?", (acc_no,)) - detail = cur.fetchone() - return detail if detail else False - -# Update customer balance -def update_balance(new_money, acc_no): - cur.execute("UPDATE bank SET balance = balance + ? WHERE acc_no = ?", (new_money, acc_no)) - conn.commit() - -# Deduct balance -def deduct_balance(new_money, acc_no): - cur.execute("SELECT balance FROM bank WHERE acc_no = ?", (acc_no,)) - bal = cur.fetchone() - if bal and bal[0] >= new_money: - cur.execute("UPDATE bank SET balance = balance - ? WHERE acc_no = ?", (new_money, acc_no)) - conn.commit() - return True - return False - -# Get account balance -def check_balance(acc_no): - cur.execute("SELECT balance FROM bank WHERE acc_no = ?", (acc_no,)) - bal = cur.fetchone() - return bal[0] if bal else 0 - -# Update customer details -def update_name_in_bank_table(new_name, acc_no): - cur.execute("UPDATE bank SET name = ? WHERE acc_no = ?", (new_name, acc_no)) - conn.commit() - -def update_age_in_bank_table(new_age, acc_no): - cur.execute("UPDATE bank SET age = ? WHERE acc_no = ?", (new_age, acc_no)) - conn.commit() - -def update_address_in_bank_table(new_address, acc_no): - cur.execute("UPDATE bank SET address = ? WHERE acc_no = ?", (new_address, acc_no)) - conn.commit() - -def update_mobile_number_in_bank_table(new_mobile_number, acc_no): - cur.execute("UPDATE bank SET mobile_number = ? WHERE acc_no = ?", (new_mobile_number, acc_no)) - conn.commit() - -def update_acc_type_in_bank_table(new_acc_type, acc_no): - cur.execute("UPDATE bank SET account_type = ? WHERE acc_no = ?", (new_acc_type, acc_no)) - conn.commit() - -# List all customers -def list_all_customers(): - cur.execute("SELECT * FROM bank") - return cur.fetchall() - -# Delete account -def delete_acc(acc_no): - cur.execute("DELETE FROM bank WHERE acc_no = ?", (acc_no,)) - conn.commit() - -# Show employees -def show_employees(): - cur.execute("SELECT name, salary, position FROM staff") - return cur.fetchall() - -# Get total money in bank -def all_money(): - cur.execute("SELECT SUM(balance) FROM bank") - total = cur.fetchone()[0] - return total if total else 0 - -# Get employee details -def show_employees_for_update(): - cur.execute("SELECT * FROM staff") - return cur.fetchall() - -# Update employee details -def update_employee_name(new_name, old_name): - cur.execute("UPDATE staff SET name = ? WHERE name = ?", (new_name, old_name)) - conn.commit() - -def update_employee_password(new_pass, old_name): - cur.execute("UPDATE staff SET pass = ? WHERE name = ?", (new_pass, old_name)) - conn.commit() - -def update_employee_salary(new_salary, old_name): - cur.execute("UPDATE staff SET salary = ? WHERE name = ?", (new_salary, old_name)) - conn.commit() - -def update_employee_position(new_pos, old_name): - cur.execute("UPDATE staff SET position = ? WHERE name = ?", (new_pos, old_name)) - conn.commit() - -# Get customer name and balance -def get_detail(acc_no): - cur.execute("SELECT name, balance FROM bank WHERE acc_no = ?", (acc_no,)) - return cur.fetchone() - -# Check if employee exists -def check_name_in_staff(name): - cur.execute("SELECT 1 FROM staff WHERE name = ?", (name,)) - return cur.fetchone() is not None \ No newline at end of file diff --git a/bank_managment_system/backendModule.py b/bank_managment_system/backendModule.py new file mode 100644 index 00000000000..84ece500ffd --- /dev/null +++ b/bank_managment_system/backendModule.py @@ -0,0 +1,256 @@ +""" +Bank Management System - Database Module + +This module provides database operations for a banking system, +including customer and employee management, account operations, +and administrative functions. +""" + +import os +import sqlite3 + +# Database connection and cursor +conn: sqlite3.Connection +cur: sqlite3.Cursor +acc_no: int + + +def connect_database() -> None: + """ + Connect to the SQLite database and initialize tables if they don't exist. + + Creates the following tables: + - bank: Stores customer account information + - staff: Stores employee details + - admin: Stores administrator credentials + + Initializes the first account number and creates a default admin user if none exists. + """ + global conn, cur, acc_no + + # Connect to database and create tables + db_path = os.path.join(os.path.dirname(__file__), "bankmanaging.db") + conn = sqlite3.connect(db_path) + cur = conn.cursor() + + # Create bank table + cur.execute(""" + CREATE TABLE IF NOT EXISTS bank ( + acc_no INTEGER PRIMARY KEY, + name TEXT, + age INTEGER, + address TEXT, + balance INTEGER, + account_type TEXT, + mobile_number TEXT + ) + """) + + # Create staff table + cur.execute(""" + CREATE TABLE IF NOT EXISTS staff ( + name TEXT, + pass TEXT, + salary INTEGER, + position TEXT + ) + """) + + # Create admin table + cur.execute("CREATE TABLE IF NOT EXISTS admin (name TEXT, pass TEXT)") + + # Initialize default admin if none exists + cur.execute("SELECT COUNT(*) FROM admin") + if cur.fetchone()[0] == 0: + cur.execute("INSERT INTO admin VALUES (?, ?)", ("admin", "admin123")) + + conn.commit() + + # Initialize next account number + cur.execute("SELECT acc_no FROM bank ORDER BY acc_no DESC LIMIT 1") + acc = cur.fetchone() + acc_no = 1 if acc is None else acc[0] + 1 + + +def check_admin(name: str, password: str) -> bool: + """Verify administrator credentials.""" + cur.execute("SELECT * FROM admin WHERE name = ? AND pass = ?", (name, password)) + return cur.fetchone() is not None + + +def create_employee(name: str, password: str, salary: int, position: str) -> None: + """Create a new staff member.""" + cur.execute( + "INSERT INTO staff VALUES (?, ?, ?, ?)", (name, password, salary, position) + ) + conn.commit() + + +def check_employee(name: str, password: str) -> bool: + """Verify employee credentials.""" + cur.execute("SELECT 1 FROM staff WHERE name = ? AND pass = ?", (name, password)) + return cur.fetchone() is not None + + +def create_customer( + name: str, age: int, address: str, balance: int, acc_type: str, mobile_number: str +) -> int: + """Create a new customer account and return the account number.""" + global acc_no + cur.execute( + "INSERT INTO bank VALUES (?, ?, ?, ?, ?, ?, ?)", + (acc_no, name, age, address, balance, acc_type, mobile_number), + ) + conn.commit() + account_created = acc_no + acc_no += 1 + return account_created + + +def check_acc_no(acc_no: int) -> bool: + """Check if an account number exists.""" + cur.execute("SELECT 1 FROM bank WHERE acc_no = ?", (acc_no,)) + return cur.fetchone() is not None + + +def get_details(acc_no: int) -> tuple[int, str, int, str, int, str, str] | None: + """Retrieve full details of a customer account.""" + cur.execute("SELECT * FROM bank WHERE acc_no = ?", (acc_no,)) + return cur.fetchone() + + +def update_balance(new_money: int, acc_no: int) -> None: + """Update account balance by adding/subtracting an amount.""" + cur.execute( + "UPDATE bank SET balance = balance + ? WHERE acc_no = ?", (new_money, acc_no) + ) + conn.commit() + + +def deduct_balance(new_money: int, acc_no: int) -> bool: + """Deduct an amount from an account if sufficient balance exists.""" + cur.execute("SELECT balance FROM bank WHERE acc_no = ?", (acc_no,)) + bal = cur.fetchone() + if bal and bal[0] >= new_money: + cur.execute( + "UPDATE bank SET balance = balance - ? WHERE acc_no = ?", + (new_money, acc_no), + ) + conn.commit() + return True + return False + + +def check_balance(acc_no: int) -> int: + """Get the current balance of an account.""" + cur.execute("SELECT balance FROM bank WHERE acc_no = ?", (acc_no,)) + bal = cur.fetchone() + return bal[0] if bal else 0 + + +def update_name_in_bank_table(new_name: str, acc_no: int) -> None: + """Update the name associated with an account.""" + cur.execute("UPDATE bank SET name = ? WHERE acc_no = ?", (new_name, acc_no)) + conn.commit() + + +def update_age_in_bank_table(new_age: int, acc_no: int) -> None: + """Update the age associated with an account.""" + cur.execute("UPDATE bank SET age = ? WHERE acc_no = ?", (new_age, acc_no)) + conn.commit() + + +def update_address_in_bank_table(new_address: str, acc_no: int) -> None: + """Update the address associated with an account.""" + cur.execute("UPDATE bank SET address = ? WHERE acc_no = ?", (new_address, acc_no)) + conn.commit() + + +def update_mobile_number_in_bank_table(new_mobile_number: str, acc_no: int) -> None: + """Update the mobile number associated with an account.""" + cur.execute( + "UPDATE bank SET mobile_number = ? WHERE acc_no = ?", + (new_mobile_number, acc_no), + ) + conn.commit() + + +def update_acc_type_in_bank_table(new_acc_type: str, acc_no: int) -> None: + """Update the account type associated with an account.""" + cur.execute( + "UPDATE bank SET account_type = ? WHERE acc_no = ?", (new_acc_type, acc_no) + ) + conn.commit() + + +def list_all_customers() -> list[tuple[int, str, int, str, int, str, str]]: + """Retrieve details of all customer accounts.""" + cur.execute("SELECT * FROM bank") + return cur.fetchall() + + +def delete_acc(acc_no: int) -> None: + """Delete a customer account.""" + cur.execute("DELETE FROM bank WHERE acc_no = ?", (acc_no,)) + conn.commit() + + +def show_employees() -> list[tuple[str, int, str]]: + """Retrieve basic details of all employees.""" + cur.execute("SELECT name, salary, position FROM staff") + return cur.fetchall() + + +def all_money() -> int: + """Calculate the total balance across all customer accounts.""" + cur.execute("SELECT SUM(balance) FROM bank") + total = cur.fetchone()[0] + return total if total is not None else 0 + + +def show_employees_for_update() -> list[tuple[str, str, int, str]]: + """Retrieve complete details of all employees for update operations.""" + cur.execute("SELECT * FROM staff") + return cur.fetchall() + + +def update_employee_name(new_name: str, old_name: str) -> None: + """Update an employee's name.""" + cur.execute("UPDATE staff SET name = ? WHERE name = ?", (new_name, old_name)) + conn.commit() + + +def update_employee_password(new_pass: str, old_name: str) -> None: + """Update an employee's password.""" + cur.execute("UPDATE staff SET pass = ? WHERE name = ?", (new_pass, old_name)) + conn.commit() + + +def update_employee_salary(new_salary: int, old_name: str) -> None: + """Update an employee's salary.""" + cur.execute("UPDATE staff SET salary = ? WHERE name = ?", (new_salary, old_name)) + conn.commit() + + +def update_employee_position(new_pos: str, old_name: str) -> None: + """Update an employee's position.""" + cur.execute("UPDATE staff SET position = ? WHERE name = ?", (new_pos, old_name)) + conn.commit() + + +def get_detail(acc_no: int) -> tuple[str, int] | None: + """Retrieve the name and balance of a customer account.""" + cur.execute("SELECT name, balance FROM bank WHERE acc_no = ?", (acc_no,)) + return cur.fetchone() + + +def check_name_in_staff(name: str) -> bool: + """Check if an employee with the given name exists.""" + cur.execute("SELECT 1 FROM staff WHERE name = ?", (name,)) + return cur.fetchone() is not None + + +def get_employee_data(name: str) -> tuple[str, str, int, str] | None: + """Retrieve complete details of a specific employee.""" + cur.execute("SELECT * FROM staff WHERE name = ?", (name,)) + return cur.fetchone() diff --git a/bank_managment_system/frontend.py b/bank_managment_system/frontend.py index c885c2b37c3..db8883a0986 100644 --- a/bank_managment_system/frontend.py +++ b/bank_managment_system/frontend.py @@ -1,10 +1,11 @@ # importing all modules import tkinter.messagebox -from tkinter import * +from tkinter import Button, Entry, Frame, Label, Tk, mainloop -import backend +import backendModule -backend.connect_database() +# creating a Tkinter window +backendModule.connect_database() # A function for check that acc_no is integer or not @@ -34,13 +35,12 @@ def delete_create(): and len(acc_type) != 0 and len(mobile_number) != 0 ): - - acc_no = backend.create_customer( + acc_no = backendModule.create_customer( name, age, address, balance, acc_type, mobile_number ) label = Label( - create_employee_frame, text="Your account number is {}".format(acc_no) + create_employee_frame, text=f"Your account number is {acc_no}" ) label.grid(row=14) @@ -129,7 +129,7 @@ def back_page2(): acc_no = entry11.get() r = check_string_in_account_no(acc_no) if len(acc_no) != 0 and r: - details = backend.get_details(acc_no) + details = backendModule.get_details(acc_no) if details != False: search_frame.grid_forget() global show_frame @@ -137,28 +137,20 @@ def back_page2(): show_frame.grid(padx=400, pady=200) label = Label( - show_frame, text="Account_number:\t{}".format(details[0]), font="bold" + show_frame, text=f"Account_number:\t{details[0]}", font="bold" ) label.grid(row=0, pady=6) - label = Label(show_frame, text="Name:\t{}".format(details[1]), font="bold") + label = Label(show_frame, text=f"Name:\t{details[1]}", font="bold") label.grid(row=1, pady=6) - label = Label(show_frame, text="Age:\t{}".format(details[2]), font="bold") + label = Label(show_frame, text=f"Age:\t{details[2]}", font="bold") label.grid(row=2, pady=6) - label = Label( - show_frame, text="Address:\t{}".format(details[3]), font="bold" - ) + label = Label(show_frame, text=f"Address:\t{details[3]}", font="bold") label.grid(row=3, pady=6) - label = Label( - show_frame, text="Balance:\t{}".format(details[4]), font="bold" - ) + label = Label(show_frame, text=f"Balance:\t{details[4]}", font="bold") label.grid(row=4, pady=6) - label = Label( - show_frame, text="Account_type:\t{}".format(details[5]), font="bold" - ) + label = Label(show_frame, text=f"Account_type:\t{details[5]}", font="bold") label.grid(row=5, pady=6) - label = Label( - show_frame, text="Mobile Number:\t{}".format(details[6]), font="bold" - ) + label = Label(show_frame, text=f"Mobile Number:\t{details[6]}", font="bold") label.grid(row=6, pady=6) button = Button( show_frame, @@ -197,7 +189,7 @@ def back_page2(): acc_no = entry11.get() r = check_string_in_account_no(acc_no) if len(acc_no) != 0 and r: - result = backend.check_acc_no(acc_no) + result = backendModule.check_acc_no(acc_no) print(result) if not result: label = Label(search_frame, text="invalid account number") @@ -209,7 +201,7 @@ def back_page2(): def update_money(): new_money = entry12.get() - backend.update_balance(new_money, acc_no) + backendModule.update_balance(new_money, acc_no) add_frame.grid_forget() page2() @@ -218,16 +210,12 @@ def update_money(): add_frame = Frame(tk) add_frame.grid(padx=400, pady=300) - detail = backend.get_detail(acc_no) + detail = backendModule.get_detail(acc_no) - label = Label( - add_frame, text="Account holder name: {}".format(detail[0][0]) - ) + label = Label(add_frame, text=f"Account holder name: {detail[0][0]}") label.grid(row=0, pady=3) - label = Label( - add_frame, text="Current amount: {}".format(detail[0][1]) - ) + label = Label(add_frame, text=f"Current amount: {detail[0][1]}") label.grid(row=1, pady=3) label = Label(add_frame, text="Enter Money") @@ -280,7 +268,7 @@ def go_page2(): acc_no = entry11.get() r = check_string_in_account_no(acc_no) if len(acc_no) != 0 and r: - result = backend.check_acc_no(acc_no) + result = backendModule.check_acc_no(acc_no) print(result) if not result: label = Label(search_frame, text="invalid account number") @@ -292,7 +280,7 @@ def go_page2(): def deduct_money(): new_money = entry12.get() - result = backend.deduct_balance(new_money, acc_no) + result = backendModule.deduct_balance(new_money, acc_no) if result: add_frame.grid_forget() page2() @@ -309,16 +297,12 @@ def deduct_money(): global add_frame add_frame = Frame(tk) add_frame.grid(padx=400, pady=300) - detail = backend.get_detail(acc_no) + detail = backendModule.get_detail(acc_no) - label = Label( - add_frame, text="Account holder name: {}".format(detail[0][0]) - ) + label = Label(add_frame, text=f"Account holder name: {detail[0][0]}") label.grid(row=0, pady=3) - label = Label( - add_frame, text="Current amount: {}".format(detail[0][1]) - ) + label = Label(add_frame, text=f"Current amount: {detail[0][1]}") label.grid(row=1, pady=3) label = Label(add_frame, text="Enter Money") @@ -374,7 +358,7 @@ def back_page2(): r = check_string_in_account_no(acc_no) if len(acc_no) != 0 and r: - result = backend.check_acc_no(acc_no) + result = backendModule.check_acc_no(acc_no) print(result) if not result: label = Label(search_frame, text="invalid account number") @@ -389,14 +373,12 @@ def delete_check_frame(): page2() search_frame.grid_forget() - balance = backend.check_balance(acc_no) + balance = backendModule.check_balance(acc_no) global check_frame check_frame = Frame(tk) check_frame.grid(padx=500, pady=300) - label = Label( - check_frame, text="Balance Is:{}".format(balance), font="bold" - ) + label = Label(check_frame, text=f"Balance Is:{balance}", font="bold") label.grid(row=0, pady=4) button = Button( @@ -456,7 +438,7 @@ def update_name_in_database(): r = check_string_in_account_no(new_name) if len(new_name) != 0: # function in backend that updates name in table - backend.update_name_in_bank_table(new_name, acc_no) + backendModule.update_name_in_bank_table(new_name, acc_no) entry_name.destroy() submit_button.destroy() name_label.destroy() @@ -486,7 +468,7 @@ def update_age_in_database(): r = check_string_in_account_no(new_age) if len(new_age) != 0 and r: # function in backend that updates name in table - backend.update_age_in_bank_table(new_age, acc_no) + backendModule.update_age_in_bank_table(new_age, acc_no) entry_name.destroy() submit_button.destroy() age_label.destroy() @@ -515,7 +497,7 @@ def update_address_in_database(): new_address = entry_name.get() if len(new_address) != 0: # function in backend that updates name in table - backend.update_address_in_bank_table(new_address, acc_no) + backendModule.update_address_in_bank_table(new_address, acc_no) entry_name.destroy() submit_button.destroy() address_label.destroy() @@ -542,7 +524,7 @@ def update_address_in_database(): r = check_string_in_account_no(acc_no) if r: - result = backend.check_acc_no(acc_no) + result = backendModule.check_acc_no(acc_no) if result: search_frame.grid_forget() global update_customer_frame @@ -613,7 +595,7 @@ def clear_list_frame(): page2() frame1.grid_forget() - details = backend.list_all_customers() + details = backendModule.list_all_customers() global tk global list_frame @@ -626,9 +608,7 @@ def clear_list_frame(): for i in details: label = Label( list_frame, - text="{}\t\t\t{}\t\t\t{}\t\t\t{}\t\t\t{}".format( - i[0], i[1], i[2], i[3], i[4] - ), + text=f"{i[0]}\t\t\t{i[1]}\t\t\t{i[2]}\t\t\t{i[3]}\t\t\t{i[4]}", ) label.grid(pady=4) @@ -652,17 +632,16 @@ def back_page2(): acc_no = entry11.get() r = check_string_in_account_no(acc_no) if len(acc_no) != 0 and r: - result = backend.check_acc_no(acc_no) + result = backendModule.check_acc_no(acc_no) print(result) if not result: - label = Label(search_frame, text="invalid account number") label.grid(pady=2) button = Button(search_frame, text="Exit", command=back_page2) button.grid() mainloop() else: - backend.delete_acc(acc_no) + backendModule.delete_acc(acc_no) search_frame.grid_forget() page2() else: @@ -761,7 +740,7 @@ def back_to_main_page1_from_create_emp(): and len(salary) != 0 and len(position) != 0 ): - backend.create_employee(name, password, salary, position) + backendModule.create_employee(name, password, salary, position) frame_create_emp.grid_forget() page1() else: @@ -833,7 +812,7 @@ def database_calling(): new_name = entry19.get() if len(new_name) != 0: old_name = staff_name.get() - backend.update_employee_name(new_name, old_name) + backendModule.update_employee_name(new_name, old_name) entry19.destroy() update_button.destroy() else: @@ -855,7 +834,7 @@ def database_calling(): new_password = entry19.get() old_name = staff_name.get() if len(new_password) != 0: - backend.update_employee_password(new_password, old_name) + backendModule.update_employee_password(new_password, old_name) entry19.destroy() update_button.destroy() else: @@ -877,9 +856,8 @@ def database_calling(): new_salary = entry19.get() r = check_string_in_account_no(new_salary) if len(new_salary) != 0 and r: - old_name = staff_name.get() - backend.update_employee_salary(new_salary, old_name) + backendModule.update_employee_salary(new_salary, old_name) entry19.destroy() update_button.destroy() else: @@ -900,9 +878,8 @@ def update_position_in_database(): def database_calling(): new_position = entry19.get() if len(new_position) != 0: - old_name = staff_name.get() - backend.update_employee_position(new_position, old_name) + backendModule.update_employee_position(new_position, old_name) entry19.destroy() update_button.destroy() else: @@ -975,9 +952,8 @@ def database_calling(): name = staff_name.get() if len(name) != 0: - result = backend.check_name_in_staff(name) + result = backendModule.check_name_in_staff(name) if result: - update_that_particular_employee() else: label = Label(show_employee_frame, text="Employee not found") @@ -1034,12 +1010,12 @@ def back_to_main_page1(): ) label.grid(row=0) - details = backend.show_employees() + details = backendModule.show_employees() for i in details: label = Label( show_employee_frame, - text="{}\t\t\t{}\t\t\t{}\t\t\t{}".format(i[0], i[1], i[2], i[3]), + text=f"{i[0]}\t\t\t{i[1]}\t\t\t{i[2]}\t\t\t{i[3]}", ) label.grid(pady=4) @@ -1064,7 +1040,7 @@ def back_to_main_page1_from_total_money(): page1_frame.grid_forget() - all = backend.all_money() + all = backendModule.all_money() global all_money all_money = Frame(tk) @@ -1073,7 +1049,7 @@ def back_to_main_page1_from_total_money(): label = Label(all_money, text="Total Amount of money") label.grid(row=0, pady=6) - label = Label(all_money, text="{}".format(all)) + label = Label(all_money, text=f"{all}") label.grid(row=1) button = Button( @@ -1130,7 +1106,7 @@ def back_to_main2(): name = entry1.get() password = entry2.get() if len(name) != 0 and len(password) != 0: - result = backend.check_admin(name, password) + result = backendModule.check_admin(name, password) print(result) if result: admin_frame.grid_forget() @@ -1215,7 +1191,7 @@ def check_emp(): name = entry1.get() password = entry2.get() if len(name) != 0 and len(password) != 0: - result = backend.check_employee(name, password) + result = backendModule.check_employee(name, password) print(result) if result: employee_frame.grid_forget() diff --git a/bank_managment_system/untitled.ui b/bank_managment_system/untitled.ui index 12c130fb4e7..6f6a4a1d310 100644 --- a/bank_managment_system/untitled.ui +++ b/bank_managment_system/untitled.ui @@ -11,44 +11,89 @@ - MainWindow + Bank Management System - background-color: #f0f2f5; +/* Global Styles */ +QMainWindow { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 #f0f7ff, stop:1 #e6f0ff); +} + +/* Button Styles */ QPushButton { - background-color: #3498db; - color: white; - font-family: 'Segoe UI'; - font-size: 16px; - font-weight: bold; - border-radius: 8px; - padding: 12px; - border: none; - } - QPushButton:hover { - background-color: #2980b9; - } - QPushButton:pressed { - background-color: #1c6ea4; - } + background-color: #2c7ad6; + color: white; + font-family: 'Segoe UI', 'Roboto', sans-serif; + font-size: 16px; + font-weight: 600; + border-radius: 10px; + padding: 12px 20px; + border: none; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); + transition: all 0.2s ease; +} +QPushButton:hover { + background-color: #1e64b8; + box-shadow: 0 4px 8px rgba(0,0,0,0.15); + transform: translateY(-1px); +} +QPushButton:pressed { + background-color: #18529e; + box-shadow: 0 1px 2px rgba(0,0,0,0.1); + transform: translateY(1px); +} +QPushButton:disabled { + background-color: #a0bfe0; + cursor: not-allowed; +} + +/* Input Field Styles */ +QLineEdit { + background-color: white; + border: 1px solid #c4d7ed; + border-radius: 8px; + padding: 10px; + font-size: 14px; + font-family: 'Segoe UI', sans-serif; + transition: border-color 0.2s ease; +} +QLineEdit:focus { + border-color: #2c7ad6; + outline: none; + box-shadow: 0 0 0 2px rgba(44, 122, 214, 0.2); +} + +/* Frame Styles */ +.QFrame { + border-radius: 12px; +} + +/* Label Styles */ +QLabel { + font-family: 'Segoe UI', sans-serif; +} + - 2 + 0 + - background-color: #ffffff; - border-radius: 10px; - padding: 10px; + background-color: white; + border-radius: 12px; + padding: 20px; + box-shadow: 0 4px 12px rgba(0,0,0,0.05); @@ -62,17 +107,20 @@ QPushButton { - 30 + Segoe UI + 32 + 600 + true - color: #2c3e50; - padding: 10px; + color: #1a365d; + padding: 15px; - Bank Management system + Bank Management System @@ -107,7 +155,7 @@ QPushButton { - 300 + 340 0 @@ -118,10 +166,10 @@ QPushButton { - - background-color: #ffffff; - border-radius: 15px; - padding: 20px; + background-color: white; + border-radius: 15px; + padding: 30px 25px; + box-shadow: 0 6px 16px rgba(0,0,0,0.08); @@ -131,75 +179,39 @@ QPushButton { QFrame::Raised + + 18 + - QPushButton { - background-color: #3498db; - color: white; - font-family: 'Segoe UI'; - font-size: 16px; - font-weight: bold; - border-radius: 8px; - padding: 12px; - border: none; - } - QPushButton:hover { - background-color: #2980b9; - } - QPushButton:pressed { - background-color: #1c6ea4; - } + + background-color: #2c7ad6; + - Admin + Admin Login - QPushButton { - background-color: #3498db; - color: white; - font-family: 'Segoe UI'; - font-size: 16px; - font-weight: bold; - border-radius: 8px; - padding: 12px; - border: none; - } - QPushButton:hover { - background-color: #2980b9; - } - QPushButton:pressed { - background-color: #1c6ea4; - } + + background-color: #38b2ac; + - Employee + Employee Login - QPushButton { - background-color: #3498db; - color: white; - font-family: 'Segoe UI'; - font-size: 16px; - font-weight: bold; - border-radius: 8px; - padding: 12px; - border: none; - } - QPushButton:hover { - background-color: #2980b9; - } - QPushButton:pressed { - background-color: #1c6ea4; - } + + background-color: #e53e3e; + Exit @@ -217,58 +229,126 @@ QPushButton { + + + + + background-color: white; + padding: 20px; + + QFrame::StyledPanel QFrame::Raised - - - - 340 - 210 - 261 - 231 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - 20 - 20 - 75 - 23 - - - - PushButton - - - + + + + + + Segoe UI + 24 + 600 + true + + + + color: #1a365d; + + + Admin Dashboard + + + + + + + + 340 + 300 + + + + + background-color: #f8fafc; + padding: 20px; + border-radius: 12px; + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 15 + + + + + Add Employee + + + + + + + Update Employee + + + + + + + Employee List + + + + + + + Total Deposits + + + + + + + background-color: #64748b; + + + Back to Home + + + + + + + + + - background-color: #ffffff; - border-radius: 10px; - padding: 10px; + background-color: white; + border-radius: 12px; + padding: 20px; + box-shadow: 0 4px 12px rgba(0,0,0,0.05); @@ -282,13 +362,16 @@ QPushButton { - 30 + Segoe UI + 28 + 600 + true - color: #2c3e50; - padding: 10px; + color: #1a365d; + padding: 15px; @@ -319,20 +402,15 @@ QPushButton { 340 - 200 + 280 - - - 16 - - - - background-color: #ffffff; + background-color: white; border-radius: 15px; - padding: 10px; + padding: 30px 25px; + box-shadow: 0 6px 16px rgba(0,0,0,0.08); @@ -343,24 +421,12 @@ QPushButton { - 0 - - - 0 - - - 0 - - - 0 - - - 0 + 20 - padding:7 + padding: 0 5px; QFrame::StyledPanel @@ -369,21 +435,6 @@ QPushButton { QFrame::Raised - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - @@ -394,28 +445,24 @@ QPushButton { + Segoe UI 12 - 75 + 600 true - - color: #2c3e50; - + color: #334155; - Name : + Username: - - background-color: rgb(168, 168, 168); - - - + + Enter username @@ -425,7 +472,7 @@ QPushButton { - padding:7 + padding: 0 5px; QFrame::StyledPanel @@ -434,21 +481,6 @@ QPushButton { QFrame::Raised - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - @@ -459,28 +491,27 @@ QPushButton { + Segoe UI 12 - 75 + 600 true - - color: #2c3e50; - + color: #334155; - Password : + Password: - - background-color: rgb(168, 168, 168); + + QLineEdit::Password - - + + Enter password @@ -488,64 +519,16 @@ QPushButton { - - - padding:7 - - - QFrame::StyledPanel + + + + 150 + 0 + - - QFrame::Raised + + Login - - - 60 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 150 - 0 - - - - QPushButton { - background-color: #3498db; - color: white; - font-family: 'Segoe UI'; - font-size: 16px; - font-weight: bold; - border-radius: 8px; - padding: 12px; - border: none; - } - QPushButton:hover { - background-color: #2980b9; - } - QPushButton:pressed { - background-color: #1c6ea4; - } - - - Submit - - - - @@ -556,15 +539,18 @@ QPushButton { + + - background-color: #ffffff; - border-radius: 10px; - padding: 10px; + background-color: white; + border-radius: 12px; + padding: 20px; + box-shadow: 0 4px 12px rgba(0,0,0,0.05); @@ -578,13 +564,16 @@ QPushButton { - 30 + Segoe UI + 28 + 600 + true - color: #2c3e50; - padding: 10px; + color: #1a365d; + padding: 15px; @@ -615,20 +604,15 @@ QPushButton { 340 - 200 + 280 - - - 16 - - - - background-color: #ffffff; + background-color: white; border-radius: 15px; - padding: 10px; + padding: 30px 25px; + box-shadow: 0 6px 16px rgba(0,0,0,0.08); @@ -639,24 +623,12 @@ QPushButton { - 0 - - - 0 - - - 0 - - - 0 - - - 0 + 20 - padding:7 + padding: 0 5px; QFrame::StyledPanel @@ -665,21 +637,6 @@ QPushButton { QFrame::Raised - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - @@ -690,28 +647,24 @@ QPushButton { + Segoe UI 12 - 75 + 600 true - - color: #2c3e50; - + color: #334155; - Name : + Username: - - background-color: rgb(168, 168, 168); - - - + + Enter admin username @@ -721,7 +674,7 @@ QPushButton { - padding:7 + padding: 0 5px; QFrame::StyledPanel @@ -730,21 +683,6 @@ QPushButton { QFrame::Raised - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - @@ -755,28 +693,27 @@ QPushButton { + Segoe UI 12 - 75 + 600 true - - color: #2c3e50; - + color: #334155; - Password : + Password: - - background-color: rgb(168, 168, 168); + + QLineEdit::Password - - + + Enter admin password @@ -784,64 +721,16 @@ QPushButton { - - - padding:7 - - - QFrame::StyledPanel + + + + 150 + 0 + - - QFrame::Raised + + Login - - - 60 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 150 - 0 - - - - QPushButton { - background-color: #3498db; - color: white; - font-family: 'Segoe UI'; - font-size: 16px; - font-weight: bold; - border-radius: 8px; - padding: 12px; - border: none; - } - QPushButton:hover { - background-color: #2980b9; - } - QPushButton:pressed { - background-color: #1c6ea4; - } - - - Submit - - - - @@ -859,4 +748,4 @@ QPushButton { - + \ No newline at end of file diff --git a/basic_cal.py b/basic_cal.py index 6629ad178db..a22093aef93 100644 --- a/basic_cal.py +++ b/basic_cal.py @@ -5,4 +5,4 @@ print("Invalid Input, try again..") # Simple Calculator using eval() in Python -# This calculator takes user input like "5+5" or "10/2" and shows the result. \ No newline at end of file +# This calculator takes user input like "5+5" or "10/2" and shows the result. diff --git a/billing.py b/billing.py index f6fb387101c..c0368a18e49 100644 --- a/billing.py +++ b/billing.py @@ -1,7 +1,7 @@ updated_billing -items= {"apple":5,"soap":4,"soda":6,"pie":7,"cake":20} -total_price=0 -try : +items = {"apple": 5, "soap": 4, "soda": 6, "pie": 7, "cake": 20} +total_price = 0 +try: print(""" Press 1 for apple Press 2 for soap @@ -11,23 +11,23 @@ Press 6 for bill""") while True: choice = int(input("enter your choice here..\n")) - if choice ==1: + if choice == 1: print("Apple added to the cart") - total_price+=items["apple"] + total_price += items["apple"] - elif choice== 2: + elif choice == 2: print("soap added to the cart") - total_price+= items["soap"] - elif choice ==3: + total_price += items["soap"] + elif choice == 3: print("soda added to the cart") - total_price+=items["soda"] - elif choice ==4: + total_price += items["soda"] + elif choice == 4: print("pie added to the cart") - total_price+=items["pie"] - elif choice ==5: + total_price += items["pie"] + elif choice == 5: print("cake added to the cart") - total_price+=items["cake"] - elif choice == 6: + total_price += items["cake"] + elif choice == 6: print(f""" Total amount :{total_price} @@ -67,4 +67,3 @@ The try-except block is used to catch errors if the user enters something that's not a number (like a letter or symbol). In that case, it simply shows: "enter only digits". """ - diff --git a/binary search.py b/binary search.py index cfad85df817..2cf464c8f20 100644 --- a/binary search.py +++ b/binary search.py @@ -1,23 +1,25 @@ -def binarySearchAppr (arr, start, end, x): -# check condition - if end >= start: - mid = start + (end- start)//2 - # If element is present at the middle - if arr[mid] == x: - return mid - # If element is smaller than mid - elif arr[mid] > x: - return binarySearchAppr(arr, start, mid-1, x) - # Else the element greator than mid - else: - return binarySearchAppr(arr, mid+1, end, x) - else: - # Element is not found in the array - return -1 -arr = sorted(['t','u','t','o','r','i','a','l']) -x ='r' -result = binarySearchAppr(arr, 0, len(arr)-1, x) +def binarySearchAppr(arr, start, end, x): + # check condition + if end >= start: + mid = start + (end - start) // 2 + # If element is present at the middle + if arr[mid] == x: + return mid + # If element is smaller than mid + elif arr[mid] > x: + return binarySearchAppr(arr, start, mid - 1, x) + # Else the element greator than mid + else: + return binarySearchAppr(arr, mid + 1, end, x) + else: + # Element is not found in the array + return -1 + + +arr = sorted(["t", "u", "t", "o", "r", "i", "a", "l"]) +x = "r" +result = binarySearchAppr(arr, 0, len(arr) - 1, x) if result != -1: - print ("Element is present at index "+str(result)) + print("Element is present at index " + str(result)) else: - print ("Element is not present in array") + print("Element is not present in array") diff --git a/binary_search_trees/delete_a_node_in_bst.py b/binary_search_trees/delete_a_node_in_bst.py index bfb6a0708ac..ea952e63b87 100644 --- a/binary_search_trees/delete_a_node_in_bst.py +++ b/binary_search_trees/delete_a_node_in_bst.py @@ -1,35 +1,43 @@ from inorder_successor import inorder_successor -# The above line imports the inorder_successor function from the inorder_successor.py file -def delete_node(root,val): - """ This function deletes a node with value val from the BST""" - - # search in the left subtree - if root.data < val: - root.right = delete_node(root.right,val) - - # search in the right subtree - elif root.data>val: - root.left=delete_node(root.left,val) - - # node to be deleted is found - else: - # case 1: no child leaf node - if root.left is None and root.right is None: - return None - - # case 2: one child - if root.left is None: - return root.right - - # case 2: one child - elif root.right is None: - return root.left - - # case 3: two children - - # find the inorder successor - IS=inorder_successor(root.right) - root.data=IS.data - root.right=delete_node(root.right,IS.data) - return root - \ No newline at end of file +from tree_node import Node + + +def delete_node(root: Node | None, val: int) -> Node | None: + """ + This function deletes a node with value val from the BST. + + Args: + root (Node | None): The root node of the binary search tree. If the tree is empty, it's None. + val (int): The value of the node to be deleted. + + Returns: + Node | None: The root node of the binary search tree after deleting the node. If the tree becomes empty, returns None. + """ + # Search in the left subtree + if root and root.data < val: + root.right = delete_node(root.right, val) + + # Search in the right subtree + elif root and root.data > val: + root.left = delete_node(root.left, val) + + # Node to be deleted is found + elif root: + # Case 1: No child (leaf node) + if root.left is None and root.right is None: + return None + + # Case 2: One child + if root.left is None: + return root.right + + # Case 2: One child + elif root.right is None: + return root.left + + # Case 3: Two children + # Find the inorder successor + IS: Node = inorder_successor(root.right) + root.data = IS.data + root.right = delete_node(root.right, IS.data) + return root diff --git a/binary_search_trees/inorder_successor.py b/binary_search_trees/inorder_successor.py index b9b15666eea..822595e7671 100644 --- a/binary_search_trees/inorder_successor.py +++ b/binary_search_trees/inorder_successor.py @@ -1,10 +1,20 @@ -def inorder_successor(root): - # This function returns the inorder successor of a node in a BST - - # The inorder successor of a node is the node with the smallest value greater than the value of the node - current=root - - # The inorder successor is the leftmost node in the right subtree - while current.left is not None: - current=current.left - return current \ No newline at end of file +from tree_node import Node + + +def inorder_successor(root: Node) -> Node: + """ + This function returns the inorder successor of a node in a BST. + + Args: + root (Node): The node for which to find the inorder successor. + + Returns: + Node: The inorder successor node. + """ + # The inorder successor of a node is the node with the smallest value greater than the value of the node + current: Node = root + + # The inorder successor is the leftmost node in the right subtree + while current.left is not None: + current = current.left + return current diff --git a/binary_search_trees/inorder_traversal.py b/binary_search_trees/inorder_traversal.py index 3bb4c4101ed..f0975d72ed5 100644 --- a/binary_search_trees/inorder_traversal.py +++ b/binary_search_trees/inorder_traversal.py @@ -1,15 +1,39 @@ -def inorder(root): - """ This function performs an inorder traversal of a BST""" - - # The inorder traversal of a BST is the nodes in increasing order +class Node: + def __init__(self, data: int): + """ + Initialize a binary tree node. + + Args: + data (int): The data stored in the node. + """ + self.data: int = data + self.left: Node | None = None + self.right: Node | None = None + + +def inorder(root: Node | None) -> None: + """ + This function performs an inorder traversal of a Binary Search Tree (BST). + + An inorder traversal of a BST visits the nodes in ascending order of their values. + For each node, it first traverses the left subtree, then visits the node itself, + and finally traverses the right subtree. + + Args: + root (Optional[Node]): The root node of the BST. If the tree is empty, this will be None. + + Returns: + None: This function doesn't return a value. It directly prints the node values during traversal. + """ + # The inorder traversal of a BST visits nodes in increasing order if root is None: return - + # Traverse the left subtree inorder(root.left) - + # Print the root node print(root.data) - + # Traverse the right subtree - inorder(root.right) \ No newline at end of file + inorder(root.right) diff --git a/binary_search_trees/insert_in_bst.py b/binary_search_trees/insert_in_bst.py index dd726d06596..89ba4b5f30f 100644 --- a/binary_search_trees/insert_in_bst.py +++ b/binary_search_trees/insert_in_bst.py @@ -1,17 +1,26 @@ from tree_node import Node -def insert(root,val): - - """ This function inserts a node with value val into the BST""" - + + +def insert(root: Node | None, val: int) -> Node: + """ + This function inserts a node with value val into the BST. + + Args: + root (Node | None): The root node of the binary search tree. If the tree is empty, it's None. + val (int): The value of the node to be inserted. + + Returns: + Node: The root node of the binary search tree after inserting the node. + """ # If the tree is empty, create a new node if root is None: return Node(val) - - # If the value to be inserted is less than the root value, insert in the left subtree + + # If the value to be inserted is less than the root value, insert it into the left subtree if val < root.data: - root.left = insert(root.left,val) - - # If the value to be inserted is greater than the root value, insert in the right subtree + root.left = insert(root.left, val) + + # If the value to be inserted is greater than the root value, insert it into the right subtree else: - root.right = insert(root.right,val) - return root \ No newline at end of file + root.right = insert(root.right, val) + return root diff --git a/binary_search_trees/main.py b/binary_search_trees/main.py index 0e819375716..499cbfc3239 100644 --- a/binary_search_trees/main.py +++ b/binary_search_trees/main.py @@ -1,16 +1,16 @@ -from insert_in_bst import insert from delete_a_node_in_bst import delete_node -from search_in_bst import search +from insert_in_bst import insert from mirror_a_bst import create_mirror_bst from print_in_range import print_in_range from root_to_leaf_paths import print_root_to_leaf_paths +from search_in_bst import search +from tree_node import Node from validate_bst import is_valid_bst -def main(): - +def main() -> None: # Create a BST - root = None + root: Node | None = None root = insert(root, 50) root = insert(root, 30) root = insert(root, 20) @@ -18,66 +18,60 @@ def main(): root = insert(root, 70) root = insert(root, 60) root = insert(root, 80) - + # Print the inorder traversal of the BST print("Inorder traversal of the original BST:") print_in_range(root, 10, 90) - + # Print the root to leaf paths print("Root to leaf paths:") print_root_to_leaf_paths(root, []) - + # Check if the tree is a BST - print("Is the tree a BST:", is_valid_bst(root,None,None)) - - + print("Is the tree a BST:", is_valid_bst(root, None, None)) + # Delete nodes from the BST print("Deleting 20 from the BST:") root = delete_node(root, 20) - + # Print the inorder traversal of the BST print("Inorder traversal of the BST after deleting 20:") print_in_range(root, 10, 90) - + # Check if the tree is a BST - print("Is the tree a BST:", is_valid_bst(root,None,None)) - - + print("Is the tree a BST:", is_valid_bst(root, None, None)) + # Delete nodes from the BST print("Deleting 30 from the BST:") root = delete_node(root, 30) - + # Print the inorder traversal of the BST after deleting 30 print("Inorder traversal of the BST after deleting 30:") print_in_range(root, 10, 90) - + # Check if the tree is a BST - print("Is the tree a BST:", is_valid_bst(root,None,None)) - + print("Is the tree a BST:", is_valid_bst(root, None, None)) + # Delete nodes from the BST print("Deleting 50 from the BST:") root = delete_node(root, 50) - + # Print the inorder traversal of the BST after deleting 50 print("Inorder traversal of the BST after deleting 50:") print_in_range(root, 10, 90) - + # Check if the tree is a BST - print("Is the tree a BST:", is_valid_bst(root,None,None)) - - + print("Is the tree a BST:", is_valid_bst(root, None, None)) + print("Searching for 70 in the BST:", search(root, 70)) print("Searching for 100 in the BST:", search(root, 100)) print("Inorder traversal of the BST:") print_in_range(root, 10, 90) print("Creating a mirror of the BST:") - mirror_root = create_mirror_bst(root) + mirror_root: Node | None = create_mirror_bst(root) print("Inorder traversal of the mirror BST:") print_in_range(mirror_root, 10, 90) + if __name__ == "__main__": main() - - - - diff --git a/binary_search_trees/mirror_a_bst.py b/binary_search_trees/mirror_a_bst.py index e7b3bb7fcb9..fb951a8cd8f 100644 --- a/binary_search_trees/mirror_a_bst.py +++ b/binary_search_trees/mirror_a_bst.py @@ -1,15 +1,23 @@ -def create_mirror_bst(root): - """ Function to create a mirror of a binary search tree""" - +from tree_node import Node + + +def create_mirror_bst(root: Node | None) -> Node | None: + """ + Function to create a mirror of a binary search tree. + + Args: + root (Node | None): The root node of the binary search tree. If the tree is empty, it's None. + + Returns: + Node | None: The root node of the mirrored binary search tree. If the original tree is empty, returns None. + """ # If the tree is empty, return None if root is None: return None - - # Create a new node with the root value - + # Recursively create the mirror of the left and right subtrees - left_mirror = create_mirror_bst(root.left) - right_mirror = create_mirror_bst(root.right) + left_mirror: Node | None = create_mirror_bst(root.left) + right_mirror: Node | None = create_mirror_bst(root.right) root.left = right_mirror root.right = left_mirror - return root \ No newline at end of file + return root diff --git a/binary_search_trees/print_in_range.py b/binary_search_trees/print_in_range.py index fecca23ba24..e793f6c4846 100644 --- a/binary_search_trees/print_in_range.py +++ b/binary_search_trees/print_in_range.py @@ -1,21 +1,32 @@ -def print_in_range(root,k1,k2): - - """ This function prints the nodes in a BST that are in the range k1 to k2 inclusive""" - - # If the tree is empty, return - if root is None: - return - - # If the root value is in the range, print the root value - if root.data >= k1 and root.data <= k2: - print_in_range(root.left,k1,k2) - print(root.data) - print_in_range(root.right,k1,k2) - - # If the root value is less than k1, the nodes in the range will be in the right subtree - elif root.data < k1: - print_in_range(root.left,k1,k2) - - # If the root value is greater than k2, the nodes in the range will be in the left subtree - else: - print_in_range(root.right,k1,k2) \ No newline at end of file +from tree_node import Node + + +def print_in_range(root: Node | None, k1: int, k2: int) -> None: + """ + This function prints the nodes in a BST that are in the range k1 to k2 inclusive. + + Args: + root (Node | None): The root node of the binary search tree. If the tree is empty, it's None. + k1 (int): The lower bound of the range. + k2 (int): The upper bound of the range. + + Returns: + None + """ + # If the tree is empty, return + if root is None: + return + + # If the root value is in the range, print the root value + if root.data >= k1 and root.data <= k2: + print_in_range(root.left, k1, k2) + print(root.data) + print_in_range(root.right, k1, k2) + + # If the root value is less than k1, the nodes in the range will be in the right subtree + elif root.data < k1: + print_in_range(root.right, k1, k2) + + # If the root value is greater than k2, the nodes in the range will be in the left subtree + else: + print_in_range(root.left, k1, k2) diff --git a/binary_search_trees/root_to_leaf_paths.py b/binary_search_trees/root_to_leaf_paths.py index 22867a713ec..8651325cf0e 100644 --- a/binary_search_trees/root_to_leaf_paths.py +++ b/binary_search_trees/root_to_leaf_paths.py @@ -1,17 +1,28 @@ -def print_root_to_leaf_paths(root, path): - """ This function prints all the root to leaf paths in a BST""" - +from tree_node import Node + + +def print_root_to_leaf_paths(root: Node | None, path: list[int]) -> None: + """ + This function prints all the root-to-leaf paths in a BST. + + Args: + root (Node | None): The root node of the binary search tree. If the tree is empty, it's None. + path (List[int]): A list to store the current path from the root to a leaf. + + Returns: + None + """ # If the tree is empty, return if root is None: return - + # Add the root value to the path path.append(root.data) if root.left is None and root.right is None: print(path) - - # Recursively print the root to leaf paths in the left and right subtrees + + # Recursively print the root-to-leaf paths in the left and right subtrees else: print_root_to_leaf_paths(root.left, path) print_root_to_leaf_paths(root.right, path) - path.pop() \ No newline at end of file + path.pop() diff --git a/binary_search_trees/search_in_bst.py b/binary_search_trees/search_in_bst.py index 4a95780e43a..85d9afab943 100644 --- a/binary_search_trees/search_in_bst.py +++ b/binary_search_trees/search_in_bst.py @@ -1,15 +1,26 @@ -def search(root, val): - """ This function searches for a node with value val in the BST and returns True if found, False otherwise""" - +from tree_node import Node + + +def search(root: Node | None, val: int) -> bool: + """ + This function searches for a node with value val in the BST and returns True if found, False otherwise. + + Args: + root (Node | None): The root node of the binary search tree. If the tree is empty, it's None. + val (int): The value of the node to be searched. + + Returns: + bool: True if the node is found, False otherwise. + """ # If the tree is empty, return False - if root == None: + if root is None: return False - + # If the root value is equal to the value to be searched, return True if root.data == val: return True - + # If the value to be searched is less than the root value, search in the left subtree if root.data > val: return search(root.left, val) - return search(root.right, val) \ No newline at end of file + return search(root.right, val) diff --git a/binary_search_trees/tree_node.py b/binary_search_trees/tree_node.py index 1d35656da08..d5c8b7b9026 100644 --- a/binary_search_trees/tree_node.py +++ b/binary_search_trees/tree_node.py @@ -1,8 +1,14 @@ +from __future__ import annotations -# Node class for binary tree class Node: - def __init__(self, data): - self.data = data - self.left = None - self.right = None + def __init__(self, data: int) -> None: + """ + Initialize a binary tree node. + + Args: + data (int): The data stored in the node. + """ + self.data: int = data + self.left: Node | None = None + self.right: Node | None = None diff --git a/binary_search_trees/validate_bst.py b/binary_search_trees/validate_bst.py index 3569c833005..2fc73ee11ae 100644 --- a/binary_search_trees/validate_bst.py +++ b/binary_search_trees/validate_bst.py @@ -1,17 +1,34 @@ -def is_valid_bst(root,min,max): - """ Function to check if a binary tree is a binary search tree""" - +from tree_node import Node + + +def is_valid_bst( + root: Node | None, min_node: Node | None, max_node: Node | None +) -> bool: + """ + Function to check if a binary tree is a binary search tree. + + Args: + root (Node | None): The root node of the binary tree. If the tree is empty, it's None. + min_node (Node | None): The minimum value node for the current subtree. + max_node (Node | None): The maximum value node for the current subtree. + + Returns: + bool: True if the binary tree is a valid BST, False otherwise. + """ # If the tree is empty, return True if root is None: return True - + # If the root value is less than the minimum value or greater than the maximum value, return False - if min is not None and root.data <= min.data: + if ( + min_node is not None + and root.data <= min_node.data + or max_node is not None + and root.data >= max_node.data + ): return False - - # If the root value is greater than the maximum value or less than the minimum value, return False - elif max is not None and root.data >= max.data: - return False - + # Recursively check if the left and right subtrees are BSTs - return is_valid_bst(root.left,min,root) and is_valid_bst(root.right,root,max) \ No newline at end of file + return is_valid_bst(root.left, min_node, root) and is_valid_bst( + root.right, root, max_node + ) diff --git a/binod.py b/binod.py index 2bee72de9d6..31fd5b30fc9 100644 --- a/binod.py +++ b/binod.py @@ -10,8 +10,8 @@ # def checkBinod(file): #this function will check there is any 'Binod' text in file or not # with open(file, "r") as f: #we are opening file in read mode and using 'with' so need to take care of close() # ======= -import time import os +import time # Importing our Bindoer print("To Kaise Hai Ap Log!") @@ -21,7 +21,7 @@ def checkBinod(file): # Trying to find Binod In File Insted Of Manohar Ka Kotha # master - with open(file, "r") as f: + with open(file) as f: # master fileContent = f.read() if "binod" in fileContent.lower(): diff --git a/binod.txt b/binod.txt deleted file mode 100644 index 796c41c9f48..00000000000 --- a/binod.txt +++ /dev/null @@ -1 +0,0 @@ -I am binod diff --git a/birthdays.py b/birthdays.py index 19ad2b001a2..cb67003d4ea 100644 --- a/birthdays.py +++ b/birthdays.py @@ -1,15 +1,14 @@ -birthdays = {'Alice': 'Apr 1', 'Bob': 'Dec 12', 'Carol': 'Mar 4'} +birthdays = {"Alice": "Apr 1", "Bob": "Dec 12", "Carol": "Mar 4"} while True: - - print('Enter a name: (blank to quit)') - name = input() - if name == '': - break - if name in birthdays: - print(birthdays[name] + ' is the birthday of ' + name) - else: - print('I do not have birthday information for ' + name) - print('What is their birthday?') - bday = input() - birthdays[name] = bday - print('Birthday database updated.') + print("Enter a name: (blank to quit)") + name = input() + if name == "": + break + if name in birthdays: + print(birthdays[name] + " is the birthday of " + name) + else: + print("I do not have birthday information for " + name) + print("What is their birthday?") + bday = input() + birthdays[name] = bday + print("Birthday database updated.") diff --git a/blackJackGUI.py b/blackJackGUI.py index a67e6e06717..70310b508ca 100644 --- a/blackJackGUI.py +++ b/blackJackGUI.py @@ -1,5 +1,5 @@ -from __future__ import print_function import random + import simplegui CARD_SIZE = (72, 96) diff --git a/blackjack.py b/blackjack.py index 1cdac41bc43..0a4e6b7cd6b 100644 --- a/blackjack.py +++ b/blackjack.py @@ -81,16 +81,13 @@ def dealer_choice(): print("**********************Player is winner !!**********************") else: - if sum(p_cards) < 21: - print("**********************Player is winner !!**********************") - elif sum(p_cards) == 21: + if sum(p_cards) < 21 or sum(p_cards) == 21: print("**********************Player is winner !!**********************") else: print("***********************Dealer is the Winner !!******************") while sum(p_cards) < 21: - k = input("Want to hit or stay?\n Press 1 for hit and 0 for stay ") if k == 1: random.shuffle(deck) diff --git a/bodymass.py b/bodymass.py index be37d0db0ef..bfc2c01e1ee 100644 --- a/bodymass.py +++ b/bodymass.py @@ -1,19 +1,19 @@ -kilo = float (input("kilonuzu giriniz(örnek: 84.9): ")) -boy = float (input("Boyunuzu m cinsinden giriniz: ")) +kilo = float(input("kilonuzu giriniz(örnek: 84.9): ")) +boy = float(input("Boyunuzu m cinsinden giriniz: ")) -vki = (kilo / (boy**2)) +vki = kilo / (boy**2) if vki < 18.5: print(f"vucut kitle indeksiniz: {vki} zayıfsınız.") elif vki < 25: - print (f"vucut kitle indeksiniz: {vki} normalsiniz.") + print(f"vucut kitle indeksiniz: {vki} normalsiniz.") elif vki < 30: - print (f"vucut kitle indeksiniz: {vki} fazla kilolusunuz.") + print(f"vucut kitle indeksiniz: {vki} fazla kilolusunuz.") elif vki < 35: - print (f"vucut kitle indeksiniz: {vki} 1. derece obezsiniz") + print(f"vucut kitle indeksiniz: {vki} 1. derece obezsiniz") elif vki < 40: - print (f"vucut kitle indeksiniz: {vki} 2.derece obezsiniz.") -elif vki >40: - print (f"vucut kitle indeksiniz: {vki} 3.derece obezsiniz.") + print(f"vucut kitle indeksiniz: {vki} 2.derece obezsiniz.") +elif vki > 40: + print(f"vucut kitle indeksiniz: {vki} 3.derece obezsiniz.") else: print("Yanlış değer girdiniz.") diff --git a/bookstore_manangement_system.py b/bookstore_manangement_system.py index 7ae31cb195b..58df07fdde1 100644 --- a/bookstore_manangement_system.py +++ b/bookstore_manangement_system.py @@ -1,6 +1,5 @@ import os - import mysql.connector as mys mycon = mys.connect( @@ -16,7 +15,6 @@ def DBZ(): - # IF NO. OF BOOKS IS ZERO(0) THAN DELETE IT AUTOMATICALLY display = "select * from books" @@ -24,9 +22,7 @@ def DBZ(): data2 = mycur.fetchall() for y in data2: - if y[6] <= 0: - delete = "delete from books where Numbers_of_book<=0" mycur.execute(delete) mycon.commit() @@ -44,7 +40,6 @@ def end_separator(): def login(): - user_name = input(" USER NAME --- ") passw = input(" PASSWORD --- ") @@ -53,13 +48,10 @@ def login(): data2 = mycur.fetchall() for y in data2: - if y[1] == user_name and y[2] == passw: - pass else: - separator() print(" Username or Password is Incorrect Try Again") @@ -70,11 +62,9 @@ def login(): passw = input(" PASSWORD --- ") if y[1] == user_name and y[2] == passw: - pass else: - separator() print(" Username or Password is Again Incorrect") @@ -82,7 +72,6 @@ def login(): def ViewAll(): - print("\u0332".join("BOOK NAMES~~")) print("------------------------------------") @@ -92,21 +81,17 @@ def ViewAll(): c = 0 for y in data2: - c = c + 1 print(c, "-->", y[1]) def CNB1(): - if y[6] == 0: - separator() print(" NOW THIS BOOK IS NOT AVAILABLE ") elif y[6] > 0 and y[6] <= 8: - separator() print("WARNING!!!!!!!!!!!!!!!!!!!!!!!") @@ -116,7 +101,6 @@ def CNB1(): print() elif y[6] > 8: - separator() print("NO. OF BOOKS LEFT IS ", y[6] - 1) @@ -126,16 +110,13 @@ def CNB1(): def CNB2(): - if y[6] <= 8: - separator() print("WARNING!!!!!!!!!!!!!!!!!!!!!!!") print("NO. OF THIS BOOK IS LOW", "\tONLY", y[6], "LEFT") else: - separator() print("NO. OF BOOKS LEFT IS ", y[6]) @@ -151,18 +132,14 @@ def CNB2(): mycur.execute(display12) data2222 = mycur.fetchall() for m in data2222: - if m[0] == 0: - c = m[0] display11 = "select * from login" mycur.execute(display11) data222 = mycur.fetchall() if c == 0: - if c == 0: - print("\t\t\t\t REGESTER ") print("\t\t\t\t----------------------------") @@ -174,7 +151,6 @@ def CNB2(): lenght = len(passw) if lenght >= 8 and lenght <= 20: - c = c + 1 insert55 = (c, user_name, passw) insert22 = "insert into login values(%s,%s,%s)" @@ -186,9 +162,7 @@ def CNB2(): login() else: - if lenght < 8: - separator() print(" Password Is less than 8 Characters Enter Again") @@ -200,7 +174,6 @@ def CNB2(): lenght1 = len(passw2) if lenght1 >= 8 and lenght1 <= 20: - c = c + 1 insert555 = (c, user_name2, passw2) insert222 = "insert into login values(%s,%s,%s)" @@ -212,7 +185,6 @@ def CNB2(): login() elif lenght > 20: - separator() print( @@ -226,7 +198,6 @@ def CNB2(): lenght = len(passw) if lenght >= 8 and lenght >= 20: - c = c + 1 insert55 = (c, user_name, passw) insert22 = "insert into login values(%s,%s,%s)" @@ -242,9 +213,7 @@ def CNB2(): mycon.commit() elif m[0] == 1: - if m[0] == 1: - login() @@ -261,7 +230,6 @@ def CNB2(): while a == True: - # PROGRAM STARTED print(" *TO VIEW ALL ENTER 1") @@ -280,7 +248,6 @@ def CNB2(): # VIEW if choice == 1: - print() ViewAll() @@ -290,7 +257,6 @@ def CNB2(): rep = input("Do You Want To Restart ?? yes / no -- ").lower() if rep == "yes": - end_separator() separator() @@ -300,7 +266,6 @@ def CNB2(): continue else: - end_separator() DBZ() @@ -312,7 +277,6 @@ def CNB2(): # SEARCH / BUY if choice == 2: - book_name = input("ENTER BOOK NAME ---- ") separator() @@ -322,7 +286,6 @@ def CNB2(): data2 = mycur.fetchone() if data2 != None: - print("BOOK IS AVAILABLE") # BUY OR NOT @@ -336,7 +299,6 @@ def CNB2(): choice2 = int(input("ENTER YOUR CHOICE -- ")) if choice2 == 1: - # BUY 1 OR MORE separator() @@ -348,17 +310,13 @@ def CNB2(): choice3 = int(input("ENTER YOUR CHOICE -- ")) if choice3 == 1: - display = "select * from books" mycur.execute(display) data2 = mycur.fetchall() for y in data2: - if y[1] == book_name: - if y[6] > 0: - separator() u = ( @@ -383,7 +341,6 @@ def CNB2(): ).lower() if rep == "yes": - end_separator() separator() @@ -393,7 +350,6 @@ def CNB2(): continue else: - end_separator() DBZ() @@ -401,7 +357,6 @@ def CNB2(): os._exit(0) if choice3 == 2: - separator() wb = int(input("ENTER NO. OF BOOKS -- ")) @@ -413,13 +368,9 @@ def CNB2(): data2 = mycur.fetchall() for y in data2: - if y[1] == book_name: - if wb > y[6]: - if y[6] > 0: - print("YOU CAN'T BUT THAT MUCH BOOKS") separator() @@ -437,7 +388,6 @@ def CNB2(): k = y[6] if choice44 == "y" or choice44 == "Y": - u2 = ( "update books set numbers_of_book=numbers_of_book -%s where name='%s'" % (k, book_name) @@ -458,11 +408,8 @@ def CNB2(): data2 = mycur.fetchall() for y in data2: - if y[1] == book_name: - if y[6] <= 8: - print( "WARNING!!!!!!!!!!!!!!!!!!!!!!!" ) @@ -484,7 +431,6 @@ def CNB2(): ).lower() if rep == "yes": - end_separator() separator() @@ -494,7 +440,6 @@ def CNB2(): continue else: - end_separator() DBZ() @@ -502,7 +447,6 @@ def CNB2(): os._exit(0) elif choice44 == "n" or choice44 == "N": - print( "SORRY FOR INCONVENIENCE WE WILL TRY TO FULLFILL YOUR REQUIREMENT AS SOON AS POSSIBLE" ) @@ -516,7 +460,6 @@ def CNB2(): ).lower() if rep == "yes": - separator() DBZ() @@ -524,7 +467,6 @@ def CNB2(): continue else: - end_separator() DBZ() @@ -532,7 +474,6 @@ def CNB2(): os._exit(0) elif y[6] == 0: - print( "SORRY NO BOOK LEFT WE WILL TRY TO FULLFILL YOUR REQUIREMENT AS SOON AS POSSIBLE" ) @@ -546,7 +487,6 @@ def CNB2(): ).lower() if rep == "yes": - separator() DBZ() @@ -554,7 +494,6 @@ def CNB2(): continue else: - end_separator() DBZ() @@ -562,7 +501,6 @@ def CNB2(): os._exit(0) else: - u2 = ( "update books set numbers_of_book=numbers_of_book -%s where name='%s'" % (wb, book_name) @@ -581,9 +519,7 @@ def CNB2(): data2 = mycur.fetchall() for y in data2: - if y[1] == book_name: - CNB2() separator() @@ -593,7 +529,6 @@ def CNB2(): ).lower() if rep == "yes": - separator() DBZ() @@ -601,7 +536,6 @@ def CNB2(): continue else: - end_separator() DBZ() @@ -609,7 +543,6 @@ def CNB2(): os._exit(0) else: - separator() print("NO BOOK IS BOUGHT") @@ -621,7 +554,6 @@ def CNB2(): rep = input("Do You Want To Restart ?? yes / no -- ").lower() if rep == "yes": - separator() DBZ() @@ -629,7 +561,6 @@ def CNB2(): continue else: - end_separator() DBZ() @@ -637,7 +568,6 @@ def CNB2(): os._exit(0) else: - separator() print("SORRY NO BOOK WITH THIS NAME EXIST / NAME IS INCORRECT") @@ -649,7 +579,6 @@ def CNB2(): rep = input("Do You Want To Restart ?? yes / no -- ").lower() if rep == "yes": - separator() DBZ() @@ -657,7 +586,6 @@ def CNB2(): continue else: - end_separator() DBZ() @@ -667,13 +595,11 @@ def CNB2(): # ADDING BOOK if choice == 3: - q10 = int(input("ENTER NO. OF BOOKS TO ADD -- ")) separator() for k in range(q10): - SNo10 = int(input("ENTER SNo OF BOOK -- ")) name10 = input("ENTER NAME OF BOOK --- ") author10 = input("ENTER NAME OF AUTHOR -- ") @@ -687,13 +613,11 @@ def CNB2(): data20 = mycur.fetchone() if data20 != None: - print("This ISBN Already Exists") os._exit(0) else: - insert = (SNo10, name10, author10, year10, ISBN10, price10, nob10) insert20 = "insert into books values(%s,%s,%s,%s,%s,%s,%s)" mycur.execute(insert20, insert) @@ -708,7 +632,6 @@ def CNB2(): rep = input("Do You Want To Restart ?? yes / no -- ").lower() if rep == "yes": - separator() DBZ() @@ -716,7 +639,6 @@ def CNB2(): continue else: - end_separator() DBZ() @@ -726,7 +648,6 @@ def CNB2(): # UPDATING BOOK if choice == 4: - choice4 = input("ENTER ISBN OF BOOK -- ") separator() @@ -736,7 +657,6 @@ def CNB2(): data2 = mycur.fetchone() if data2 != None: - SNo1 = int(input("ENTER NEW SNo OF BOOK -- ")) name1 = input("ENTER NEW NAME OF BOOK --- ") author1 = input("ENTER NEW NAME OF AUTHOR -- ") @@ -758,7 +678,6 @@ def CNB2(): rep = input("Do You Want To Restart ?? yes / no -- ").lower() if rep == "yes": - separator() DBZ() @@ -766,7 +685,6 @@ def CNB2(): continue else: - end_separator() DBZ() @@ -774,7 +692,6 @@ def CNB2(): os._exit(0) else: - print("SORRY NO BOOK WITH THIS ISBN IS EXIST / INCORRECT ISBN") print() @@ -785,7 +702,6 @@ def CNB2(): rep = input("Do You Want To Restart ?? yes / no -- ").lower() if rep == "yes": - separator() DBZ() @@ -793,7 +709,6 @@ def CNB2(): continue else: - end_separator() DBZ() @@ -803,20 +718,17 @@ def CNB2(): # DELETING A BOOK if choice == 5: - ISBN1 = input("ENTER ISBN OF THAT BOOK THAT YOU WANT TO DELETE -- ") display = "select * from books where ISBN='%s'" % (ISBN1) mycur.execute(display) data2 = mycur.fetchone() if data2 != None: - separator() choice5 = input("ARE YOU SURE TO DELETE THIS BOOK ENTER Y/N -- ") if choice5 == "Y" or choice5 == "y": - separator() ISBN2 = input("PLEASE ENTER ISBN AGAIN -- ") @@ -836,7 +748,6 @@ def CNB2(): rep = input("Do You Want To Restart ?? yes / no -- ").lower() if rep == "yes": - separator() DBZ() @@ -844,7 +755,6 @@ def CNB2(): continue else: - end_separator() DBZ() @@ -852,7 +762,6 @@ def CNB2(): os._exit(0) else: - separator() print("NO BOOK IS DELETED") @@ -865,7 +774,6 @@ def CNB2(): rep = input("Do You Want To Restart ?? yes / no -- ").lower() if rep == "yes": - separator() DBZ() @@ -873,7 +781,6 @@ def CNB2(): continue else: - end_separator() DBZ() @@ -881,7 +788,6 @@ def CNB2(): os._exit(0) else: - separator() print("SORRY NO BOOK WITH THIS ISBN AVAILABLE / ISBN IS INCORRECT") @@ -894,7 +800,6 @@ def CNB2(): rep = input("Do You Want To Restart ?? yes / no -- ").lower() if rep == "yes": - separator() DBZ() @@ -902,7 +807,6 @@ def CNB2(): continue else: - end_separator() DBZ() @@ -912,7 +816,6 @@ def CNB2(): # CLOSE if choice == 6: - exit() os._exit(0) @@ -926,9 +829,7 @@ def CNB2(): for y in data2: - if y[6] <= 0: - delete = "delete from books where Numbers_of_book<=0" mycur.execute(delete) mycon.commit() diff --git a/brickout-game/brickout-game.py b/brickout-game/brickout-game.py index c212be6a634..39a8f3a333c 100644 --- a/brickout-game/brickout-game.py +++ b/brickout-game/brickout-game.py @@ -1,390 +1,381 @@ -""" - Pygame base template for opening a window - - Sample Python/Pygame Programs - Simpson College Computer Science - http://programarcadegames.com/ - http://simpson.edu/computer-science/ - - Explanation video: http://youtu.be/vRB_983kUMc - -------------------------------------------------- - -Author for the Brickout game is Christian Bender -That includes the classes Ball, Paddle, Brick, and BrickWall. - -""" - import random -# using pygame python GUI import pygame -# Define Four Colours -BLACK = (0, 0, 0) -WHITE = (255, 255, 255) -GREEN = (0, 255, 0) -RED = (255, 0, 0) - +# Initialize pygame pygame.init() -# Setting the width and height of the screen [width, height] -size = (700, 500) -screen = pygame.display.set_mode(size) +# Define colors +BLACK: tuple[int, int, int] = (0, 0, 0) +WHITE: tuple[int, int, int] = (255, 255, 255) +GREEN: tuple[int, int, int] = (0, 255, 0) +RED: tuple[int, int, int] = (255, 0, 0) +BRICK_COLOR: tuple[int, int, int] = (56, 177, 237) -""" - This is a simple Ball class for respresenting a ball - in the game. -""" +# Set up the display +SCREEN_WIDTH: int = 700 +SCREEN_HEIGHT: int = 500 +screen: pygame.Surface = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) +pygame.display.set_caption("Brickout Game") -class Ball(object): - def __init__(self, screen, radius, x, y): - self.__screen = screen - self._radius = radius - self._xLoc = x - self._yLoc = y - self.__xVel = 7 - self.__yVel = 2 - w, h = pygame.display.get_surface().get_size() - self.__width = w - self.__height = h +class Ball: + """ + Represents the ball in the Brickout game. + + Attributes: + screen (pygame.Surface): The game screen. + radius (int): The radius of the ball. + x_loc (int): The x-coordinate of the ball's center. + y_loc (int): The y-coordinate of the ball's center. + x_vel (int): The horizontal velocity of the ball. + y_vel (int): The vertical velocity of the ball. + width (int): The width of the game screen. + height (int): The height of the game screen. + """ - def getXVel(self): - return self.__xVel + def __init__(self, screen: pygame.Surface, radius: int, x: int, y: int) -> None: + self.screen: pygame.Surface = screen + self.radius: int = radius + self.x_loc: int = x + self.y_loc: int = y + self.x_vel: int = 7 + self.y_vel: int = 2 + self.width: int = SCREEN_WIDTH + self.height: int = SCREEN_HEIGHT + + def get_x_vel(self) -> int: + """Returns the horizontal velocity of the ball.""" + return self.x_vel + + def get_y_vel(self) -> int: + """Returns the vertical velocity of the ball.""" + return self.y_vel + + def draw(self) -> None: + """Draws the ball on the screen.""" + pygame.draw.circle(self.screen, RED, (self.x_loc, self.y_loc), self.radius) + + def update(self, paddle: "Paddle", brick_wall: "BrickWall") -> bool: + """ + Updates the ball's position and handles collisions with walls, paddle, and bricks. - def getYVel(self): - return self.__yVel + Args: + paddle (Paddle): The player's paddle. + brick_wall (BrickWall): The wall of bricks. - def draw(self): - """ - draws the ball onto screen. + Returns: + bool: True if the ball goes out of bounds at the bottom, False otherwise. """ - pygame.draw.circle(screen, (255, 0, 0), (self._xLoc, self._yLoc), self._radius) + # Update position + self.x_loc += self.x_vel + self.y_loc += self.y_vel - def update(self, paddle, brickwall): - """ - moves the ball at the screen. - contains some collision detection. - """ - self._xLoc += self.__xVel - self._yLoc += self.__yVel - # left screen wall bounce - if self._xLoc <= self._radius: - self.__xVel *= -1 - # right screen wall bounce - elif self._xLoc >= self.__width - self._radius: - self.__xVel *= -1 - # top wall bounce - if self._yLoc <= self._radius: - self.__yVel *= -1 - # bottom drop out - elif self._yLoc >= self.__width - self._radius: - return True - - # for bouncing off the bricks. - if brickwall.collide(self): - self.__yVel *= -1 - - # collision detection between ball and paddle - paddleY = paddle._yLoc - paddleW = paddle._width - paddleH = paddle._height - paddleX = paddle._xLoc - ballX = self._xLoc - ballY = self._yLoc - - if ((ballX + self._radius) >= paddleX and ballX <= (paddleX + paddleW)) and ( - (ballY + self._radius) >= paddleY and ballY <= (paddleY + paddleH) - ): - self.__yVel *= -1 + # Handle collisions with screen walls + if self.x_loc <= self.radius or self.x_loc >= self.width - self.radius: + self.x_vel *= -1 - return False + if self.y_loc <= self.radius: + self.y_vel *= -1 + elif self.y_loc >= self.height - self.radius: + return True # Ball went out of bounds + # Handle collisions with bricks + if brick_wall.collide(self): + self.y_vel *= -1 -""" - Simple class for representing a paddle -""" + # Handle collision with paddle + if ( + self.x_loc + self.radius >= paddle.x_loc + and self.x_loc <= paddle.x_loc + paddle.width + ) and ( + self.y_loc + self.radius >= paddle.y_loc + and self.y_loc <= paddle.y_loc + paddle.height + ): + self.y_vel *= -1 + return False -class Paddle(object): - def __init__(self, screen, width, height, x, y): - self.__screen = screen - self._width = width - self._height = height - self._xLoc = x - self._yLoc = y - w, h = pygame.display.get_surface().get_size() - self.__W = w - self.__H = h - def draw(self): - """ - draws the paddle onto screen. - """ +class Paddle: + """ + Represents the player's paddle in the Brickout game. + + Attributes: + screen (pygame.Surface): The game screen. + width (int): The width of the paddle. + height (int): The height of the paddle. + x_loc (int): The x-coordinate of the paddle's top-left corner. + y_loc (int): The y-coordinate of the paddle's top-left corner. + max_width (int): The maximum x-coordinate the paddle can reach. + """ + + def __init__( + self, screen: pygame.Surface, width: int, height: int, x: int, y: int + ) -> None: + self.screen: pygame.Surface = screen + self.width: int = width + self.height: int = height + self.x_loc: int = x + self.y_loc: int = y + self.max_width: int = SCREEN_WIDTH - width + + def draw(self) -> None: + """Draws the paddle on the screen.""" pygame.draw.rect( - screen, (0, 0, 0), (self._xLoc, self._yLoc, self._width, self._height), 0 + self.screen, BLACK, (self.x_loc, self.y_loc, self.width, self.height) ) - def update(self): - """ - moves the paddle at the screen via mouse - """ - x, y = pygame.mouse.get_pos() - if x >= 0 and x <= (self.__W - self._width): - self._xLoc = x - - -""" - This class represents a simple Brick class. - For representing bricks onto screen. -""" - - -class Brick(pygame.sprite.Sprite): - def __init__(self, screen, width, height, x, y): - self.__screen = screen - self._width = width - self._height = height - self._xLoc = x - self._yLoc = y - w, h = pygame.display.get_surface().get_size() - self.__W = w - self.__H = h - self.__isInGroup = False - - def draw(self): - """ - draws the brick onto screen. - color: rgb(56, 177, 237) - """ + def update(self) -> None: + """Updates the paddle's position based on the mouse's x-coordinate.""" + x, _ = pygame.mouse.get_pos() + if 0 <= x <= self.max_width: + self.x_loc = x + + +class Brick: + """ + Represents a single brick in the Brickout game. + + Attributes: + screen (pygame.Surface): The game screen. + width (int): The width of the brick. + height (int): The height of the brick. + x_loc (int): The x-coordinate of the brick's top-left corner. + y_loc (int): The y-coordinate of the brick's top-left corner. + is_in_group (bool): Whether the brick is part of a group. + """ + + def __init__( + self, screen: pygame.Surface, width: int, height: int, x: int, y: int + ) -> None: + self.screen: pygame.Surface = screen + self.width: int = width + self.height: int = height + self.x_loc: int = x + self.y_loc: int = y + self.is_in_group: bool = False + + def draw(self) -> None: + """Draws the brick on the screen.""" pygame.draw.rect( - screen, - (56, 177, 237), - (self._xLoc, self._yLoc, self._width, self._height), - 0, + self.screen, BRICK_COLOR, (self.x_loc, self.y_loc, self.width, self.height) ) - def add(self, group): + def add(self, group: "BrickWall") -> None: """ - adds this brick to a given group. + Adds the brick to a group. + + Args: + group (BrickWall): The group to add the brick to. """ group.add(self) - self.__isInGroup = True + self.is_in_group = True - def remove(self, group): + def remove(self, group: "BrickWall") -> None: """ - removes this brick from the given group. + Removes the brick from a group. + + Args: + group (BrickWall): The group to remove the brick from. """ group.remove(self) - self.__isInGroup = False + self.is_in_group = False - def alive(self): - """ - returns true when this brick belongs to the brick wall. - otherwise false - """ - return self.__isInGroup + def is_alive(self) -> bool: + """Returns whether the brick is part of a group.""" + return self.is_in_group - def collide(self, ball): - """ - collision detection between ball and this brick + def collide(self, ball: Ball) -> bool: """ - brickX = self._xLoc - brickY = self._yLoc - brickW = self._width - brickH = self._height - ballX = ball._xLoc - ballY = ball._yLoc - ballXVel = ball.getXVel() - ballYVel = ball.getYVel() + Checks if the ball collides with the brick. - if ( - (ballX + ball._radius) >= brickX - and (ballX + ball._radius) <= (brickX + brickW) - ) and ( - (ballY - ball._radius) >= brickY - and (ballY - ball._radius) <= (brickY + brickH) - ): - return True - else: - return False - - -""" - This is a simple class for representing a - brick wall. -""" - - -class BrickWall(pygame.sprite.Group): - def __init__(self, screen, x, y, width, height): - self.__screen = screen - self._x = x - self._y = y - self._width = width - self._height = height - self._bricks = [] - - X = x - Y = y - for i in range(3): - for j in range(4): - self._bricks.append(Brick(screen, width, height, X, Y)) - X += width + (width / 7.0) - Y += height + (height / 7.0) - X = x - - def add(self, brick): - """ - adds a brick to this BrickWall (group) - """ - self._bricks.append(brick) + Args: + ball (Ball): The ball to check collision with. - def remove(self, brick): - """ - removes a brick from this BrickWall (group) + Returns: + bool: True if collision occurs, False otherwise. """ - self._bricks.remove(brick) + return ( + ball.x_loc + ball.radius >= self.x_loc + and ball.x_loc + ball.radius <= self.x_loc + self.width + ) and ( + ball.y_loc - ball.radius >= self.y_loc + and ball.y_loc - ball.radius <= self.y_loc + self.height + ) + - def draw(self): +class BrickWall: + """ + Represents the wall of bricks in the Brickout game. + + Attributes: + screen (pygame.Surface): The game screen. + x (int): The x-coordinate of the top-left corner of the wall. + y (int): The y-coordinate of the top-left corner of the wall. + brick_width (int): The width of each brick. + brick_height (int): The height of each brick. + bricks (List[Brick]): The list of bricks in the wall. + """ + + def __init__( + self, + screen: pygame.Surface, + x: int, + y: int, + brick_width: int, + brick_height: int, + ) -> None: + self.screen: pygame.Surface = screen + self.x: int = x + self.y: int = y + self.brick_width: int = brick_width + self.brick_height: int = brick_height + self.bricks: list[Brick] = [] + + # Initialize bricks in a grid pattern + current_x: int = x + current_y: int = y + for _ in range(3): # 3 rows + for _ in range(4): # 4 columns + self.bricks.append( + Brick(screen, brick_width, brick_height, current_x, current_y) + ) + current_x += brick_width + (brick_width // 7) + current_y += brick_height + (brick_height // 7) + current_x = x + + def add(self, brick: Brick) -> None: """ - draws all bricks onto screen. + Adds a brick to the wall. + + Args: + brick (Brick): The brick to add. """ - for brick in self._bricks: - if brick != None: - brick.draw() + self.bricks.append(brick) - def update(self, ball): + def remove(self, brick: Brick) -> None: """ - checks collision between ball and bricks. + Removes a brick from the wall. + + Args: + brick (Brick): The brick to remove. """ - for i in range(len(self._bricks)): - if (self._bricks[i] != None) and self._bricks[i].collide(ball): - self._bricks[i] = None + if brick in self.bricks: + self.bricks.remove(brick) - # removes the None-elements from the brick list. - for brick in self._bricks: - if brick is None: - self._bricks.remove(brick) + def draw(self) -> None: + """Draws all bricks in the wall on the screen.""" + for brick in self.bricks: + brick.draw() - def hasWin(self): + def update(self, ball: Ball) -> None: """ - Has player win the game? + Updates the wall by checking and removing bricks that collide with the ball. + + Args: + ball (Ball): The ball to check collisions with. """ - return len(self._bricks) == 0 + for i in range(len(self.bricks) - 1, -1, -1): + if self.bricks[i].collide(ball): + self.bricks.pop(i) + + def has_won(self) -> bool: + """Returns True if all bricks have been destroyed, False otherwise.""" + return len(self.bricks) == 0 - def collide(self, ball): + def collide(self, ball: Ball) -> bool: """ - check collisions between the ball and - any of the bricks. + Checks if the ball collides with any brick in the wall. + + Args: + ball (Ball): The ball to check collisions with. + + Returns: + bool: True if collision occurs, False otherwise. """ - for brick in self._bricks: + for brick in self.bricks: if brick.collide(ball): return True return False -# The game objects ball, paddle and brick wall -ball = Ball(screen, 25, random.randint(1, 700), 250) -paddle = Paddle(screen, 100, 20, 250, 450) -brickWall = BrickWall(screen, 25, 25, 150, 50) - -isGameOver = False # determines whether game is lose -gameStatus = True # game is still running - -score = 0 # score for the game. - -pygame.display.set_caption("Brickout-game") - -# Loop until the user clicks the close button. -done = False - -# Used to manage how fast the screen updates -clock = pygame.time.Clock() - -# for displaying text in the game -pygame.font.init() # you have to call this at the start, -# if you want to use this module. - -# message for game over -mgGameOver = pygame.font.SysFont("Comic Sans MS", 40) - -# message for winning the game. -mgWin = pygame.font.SysFont("Comic Sans MS", 40) - -# message for score -mgScore = pygame.font.SysFont("Comic Sans MS", 40) - -textsurfaceGameOver = mgGameOver.render("Game Over!", False, (0, 0, 0)) -textsurfaceWin = mgWin.render("You win!", False, (0, 0, 0)) -textsurfaceScore = mgScore.render("score: " + str(score), False, (0, 0, 0)) - -# -------- Main Program Loop ----------- -while not done: - # --- Main event loop - for event in pygame.event.get(): - if event.type == pygame.QUIT: - done = True - - # --- Game logic should go here - - # --- Screen-clearing code goes here - - # Here, we clear the screen to white. Don't put other drawing commands - # above this, or they will be erased with this command. - - # If you want a background image, replace this clear with blit'ing the - # background image. - screen.fill(WHITE) - - # --- Drawing code should go here - - """ - Because I use OOP in the game logic and the drawing code, - are both in the same section. - """ - if gameStatus: - - # first draws ball for appropriate displaying the score. - brickWall.draw() - - # for counting and displaying the score - if brickWall.collide(ball): - score += 10 - textsurfaceScore = mgScore.render("score: " + str(score), False, (0, 0, 0)) - screen.blit(textsurfaceScore, (300, 0)) - - # after scoring. because hit bricks are removed in the update-method - brickWall.update(ball) - - paddle.draw() - paddle.update() - - if ball.update(paddle, brickWall): - isGameOver = True - gameStatus = False - - if brickWall.hasWin(): - gameStatus = False +def main() -> None: + """Main function to run the Brickout game.""" + # Initialize game objects + ball: Ball = Ball(screen, 25, random.randint(1, SCREEN_WIDTH), 250) + paddle: Paddle = Paddle(screen, 100, 20, 250, 450) + brick_wall: BrickWall = BrickWall(screen, 25, 25, 150, 50) + + # Game state variables + is_game_over: bool = False + game_active: bool = True + score: int = 0 + + # Set up fonts for text rendering + font_game_over: pygame.font.Font = pygame.font.SysFont("Comic Sans MS", 40) + font_win: pygame.font.Font = pygame.font.SysFont("Comic Sans MS", 40) + font_score: pygame.font.Font = pygame.font.SysFont("Comic Sans MS", 40) + + # Render text surfaces + text_game_over: pygame.Surface = font_game_over.render("Game Over!", False, BLACK) + text_win: pygame.Surface = font_win.render("You Win!", False, BLACK) + text_score: pygame.Surface = font_score.render(f"Score: {score}", False, BLACK) + + # Game clock for controlling FPS + clock: pygame.time.Clock = pygame.time.Clock() + + # Main game loop + running: bool = True + while running: + # Handle events + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + + # Clear the screen + screen.fill(WHITE) + + if game_active: + # Draw and update game elements + brick_wall.draw() + + # Update score if ball hits a brick + if brick_wall.collide(ball): + score += 10 + text_score = font_score.render(f"Score: {score}", False, BLACK) + screen.blit(text_score, (300, 0)) + + brick_wall.update(ball) + paddle.draw() + paddle.update() + + # Check game over conditions + if ball.update(paddle, brick_wall): + is_game_over = True + game_active = False + + if brick_wall.has_won(): + game_active = False + + ball.draw() + else: + # Game over screen + if is_game_over: + screen.blit(text_game_over, (0, 0)) + elif brick_wall.has_won(): + screen.blit(text_win, (0, 0)) + screen.blit(text_score, (300, 0)) - ball.draw() + # Update the display + pygame.display.flip() - else: # game isn't running. - if isGameOver: # player lose - screen.blit(textsurfaceGameOver, (0, 0)) - textsurfaceScore = mgScore.render("score: " + str(score), False, (0, 0, 0)) - screen.blit(textsurfaceScore, (300, 0)) - elif brickWall.hasWin(): # player win - screen.blit(textsurfaceWin, (0, 0)) - textsurfaceScore = mgScore.render("score: " + str(score), False, (0, 0, 0)) - screen.blit(textsurfaceScore, (300, 0)) + # Control frame rate + clock.tick(60) - # --- Go ahead and update the screen with what we've drawn. - pygame.display.flip() + # Clean up + pygame.quit() - # --- Limit to 60 frames per second - clock.tick(60) -# Close the window and quit. -pygame.quit() +if __name__ == "__main__": + main() diff --git a/calc_area.py b/calc_area.py index 7f35917c746..cf7f259e046 100644 --- a/calc_area.py +++ b/calc_area.py @@ -11,7 +11,7 @@ def main(): ) if shape == 1: side = float(input("Enter length of side: ")) - print("Area of square = " + str(side ** 2)) + print("Area of square = " + str(side**2)) elif shape == 2: l = float(input("Enter length: ")) b = float(input("Enter breadth: ")) diff --git a/calculator-gui.py b/calculator-gui.py index e0a0ea5a28d..3e4256d8ed9 100755 --- a/calculator-gui.py +++ b/calculator-gui.py @@ -1,7 +1,6 @@ # ==================== Libraries ==================== import tkinter as tk -from tkinter import ttk -from tkinter import messagebox +from tkinter import messagebox, ttk # =================================================== # ==================== Classes ====================== @@ -173,7 +172,6 @@ def press_equal(self): "Second Number", "Please Enter Second Number To Perform Calculation" ) else: - try: if self.opr == "+": self.value1 = int(self.value1) diff --git a/calculator.py b/calculator.py index b0ef5dca8dd..3660ca72186 100644 --- a/calculator.py +++ b/calculator.py @@ -2,7 +2,7 @@ Written by : Shreyas Daniel - github.com/shreydan Description : Uses Pythons eval() function as a way to implement calculator. - + Functions available are: -------------------------------------------- + : addition @@ -11,7 +11,7 @@ / : division % : percentage e : 2.718281... - pi : 3.141592... + pi : 3.141592... sine : sin(rad) cosine : cos(rad) exponent: x^y @@ -26,7 +26,6 @@ import sys ## Imported math library to run sin(), cos(), tan() and other such functions in the calculator - from fileinfo import raw_input @@ -70,21 +69,17 @@ def calc(term): term = term.replace(func, withmath) try: - # here goes the actual evaluating. term = eval(term) # here goes to the error cases. except ZeroDivisionError: - print("Can't divide by 0. Please try again.") except NameError: - print("Invalid input. Please try again") except AttributeError: - print("Please check usage method and try again.") except TypeError: print("please enter inputs of correct datatype ") diff --git a/cartesian_product.py b/cartesian_product.py index ba11eb7d54f..d4e2c73f3f1 100644 --- a/cartesian_product.py +++ b/cartesian_product.py @@ -8,11 +8,11 @@ def cartesian_product(list1, list2): """Cartesian Product of Two Lists.""" for _i in list1: for _j in list2: - print((_i, _j), end=' ') + print((_i, _j), end=" ") # Main -if __name__ == '__main__': +if __name__ == "__main__": list1 = input().split() list2 = input().split() @@ -21,4 +21,3 @@ def cartesian_product(list1, list2): list2 = [int(i) for i in list2] cartesian_product(list1, list2) - diff --git a/chaos.py b/chaos.py index 1bd1c120ee4..9452adece3e 100644 --- a/chaos.py +++ b/chaos.py @@ -6,8 +6,8 @@ def main(): while True: try: - x = float((input("Enter a number between 0 and 1: "))) - if 0 < x and x < 1: + x = float(input("Enter a number between 0 and 1: ")) + if x > 0 and x < 1: break else: print("Please enter correct number") diff --git a/check if a number positive , negative or zero b/check if a number positive , negative or zero deleted file mode 100644 index c47cda8ae78..00000000000 --- a/check if a number positive , negative or zero +++ /dev/null @@ -1,16 +0,0 @@ -num = float(input("Enter a number: ")) -if num > 0: - print("Positive number") -elif num == 0: - print("Zero") -else: - print("Negative number") - num = float(input("Enter a number: ")) -if num >= 0: - if num == 0: - print("Zero") - else: - print("Positive number") -else: - print("Negative number") - diff --git a/check if a number positive , negative or zero.py b/check if a number positive , negative or zero.py new file mode 100644 index 00000000000..48deaebeafa --- /dev/null +++ b/check if a number positive , negative or zero.py @@ -0,0 +1,15 @@ +num = float(input("Enter a number: ")) +if num > 0: + print("Positive number") +elif num == 0: + print("Zero") +else: + print("Negative number") + num = float(input("Enter a number: ")) +if num >= 0: + if num == 0: + print("Zero") + else: + print("Positive number") +else: + print("Negative number") diff --git a/check whether the string is Symmetrical or Palindrome.py b/check whether the string is Symmetrical or Palindrome.py index 0b12df47a9e..24614f5d9b2 100644 --- a/check whether the string is Symmetrical or Palindrome.py +++ b/check whether the string is Symmetrical or Palindrome.py @@ -1,53 +1,50 @@ -def palindrome(a): - - mid = (len(a)-1)//2 +def palindrome(a): + mid = (len(a) - 1) // 2 start = 0 - last = len(a)-1 + last = len(a) - 1 flag = 0 - - while(start end or user_input < start: - # error case print("Please try again. Not in valid bounds.") else: - # valid case loop = False # aborts while-loop except ValueError: - # error case print("Please try again. Only numbers") diff --git a/chicks_n_rabs.py b/chicks_n_rabs.py index fa82f161d1c..c0114a08060 100644 --- a/chicks_n_rabs.py +++ b/chicks_n_rabs.py @@ -2,7 +2,7 @@ Author Anurag Kumar(mailto:anuragkumarak95@gmail.com) Module to solve a classic ancient Chinese puzzle: -We count 35 heads and 94 legs among the chickens and rabbits in a farm. +We count 35 heads and 94 legs among the chickens and rabbits in a farm. How many rabbits and how many chickens do we have? """ diff --git a/cicd b/cicd deleted file mode 100644 index 8b137891791..00000000000 --- a/cicd +++ /dev/null @@ -1 +0,0 @@ - diff --git a/classicIndianCardMatch.py b/classicIndianCardMatch.py index 6c859fb8f4d..3db8deaade0 100644 --- a/classicIndianCardMatch.py +++ b/classicIndianCardMatch.py @@ -97,7 +97,7 @@ def __str__(self): for card in range(len(player1)): input("Enter any key to place a card!!!\n") currentPlayer1Card = player1[card].rank - print("Your current card's rank: {}".format(currentPlayer1Card)) + print(f"Your current card's rank: {currentPlayer1Card}") centerPile.append(player1[card]) player1.pop(card) switchPlayer = False @@ -110,7 +110,7 @@ def __str__(self): while switchPlayer == False: for card in range(len(player2)): currentPlayer2Card = player2[card].rank - print("Computer's current card's rank: {}".format(currentPlayer2Card)) + print(f"Computer's current card's rank: {currentPlayer2Card}") centerPile.append(player2[card]) player2.pop(card) switchPlayer = True @@ -121,4 +121,4 @@ def __str__(self): print("GAME OVER!!!\n") -print("Human has {} cards and computer has {}..".format(len(player1), len(player2))) +print(f"Human has {len(player1)} cards and computer has {len(player2)}..") diff --git a/cli_master/cli_master.py b/cli_master/cli_master.py index 24a7457428c..973a22ae8dc 100644 --- a/cli_master/cli_master.py +++ b/cli_master/cli_master.py @@ -2,7 +2,6 @@ import sys from pprint import pprint - sys.path.append(os.path.realpath(".")) import inquirer @@ -83,12 +82,12 @@ def login_password(answer, current): # Add your password validation logic here return True + # Have an option to go back. # How can I do it? if answers is not None and answers.get("authentication") == "Login": questions = [ - inquirer. - Text( + inquirer.Text( "surname", message="What's your last name (surname)?", validate=Validation.lname_validation, @@ -161,4 +160,4 @@ def login_password(answer, current): print("Exit") sys.exit() -pprint(answers) \ No newline at end of file +pprint(answers) diff --git a/cli_master/database_import_countries.py b/cli_master/database_import_countries.py index 27255834e9e..8d6127cd674 100644 --- a/cli_master/database_import_countries.py +++ b/cli_master/database_import_countries.py @@ -1,9 +1,9 @@ -import requests +import httpx url = "https://api.countrystatecity.in/v1/countries" headers = {"X-CSCAPI-KEY": "API_KEY"} -response = requests.request("GET", url, headers=headers) +response = httpx.get(url, headers=headers) print(response.text) diff --git a/cli_master/validation_page.py b/cli_master/validation_page.py index 8852781d4b7..a9f1c2bcffc 100644 --- a/cli_master/validation_page.py +++ b/cli_master/validation_page.py @@ -1,10 +1,12 @@ import re + def phone_validation(phone_number): # Match a typical US phone number format (xxx) xxx-xxxx - pattern = re.compile(r'^\(\d{3}\) \d{3}-\d{4}$') + pattern = re.compile(r"^\(\d{3}\) \d{3}-\d{4}$") return bool(pattern.match(phone_number)) + # Example usage: phone_number_input = input("Enter phone number: ") if phone_validation(phone_number_input): @@ -12,11 +14,13 @@ def phone_validation(phone_number): else: print("Invalid phone number.") + def email_validation(email): # Basic email format validation - pattern = re.compile(r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$') + pattern = re.compile(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$") return bool(pattern.match(email)) + # Example usage: email_input = input("Enter email address: ") if email_validation(email_input): @@ -29,6 +33,7 @@ def password_validation(password): # Password must be at least 8 characters long and contain at least one digit return len(password) >= 8 and any(char.isdigit() for char in password) + # Example usage: password_input = input("Enter password: ") if password_validation(password_input): @@ -39,7 +44,8 @@ def password_validation(password): def username_validation(username): # Allow only alphanumeric characters and underscores - return bool(re.match('^[a-zA-Z0-9_]+$', username)) + return bool(re.match("^[a-zA-Z0-9_]+$", username)) + # Example usage: username_input = input("Enter username: ") @@ -51,7 +57,8 @@ def username_validation(username): def country_validation(country): # Example: Allow only alphabetical characters and spaces - return bool(re.match('^[a-zA-Z ]+$', country)) + return bool(re.match("^[a-zA-Z ]+$", country)) + # Example usage: country_input = input("Enter country name: ") @@ -59,4 +66,3 @@ def country_validation(country): print("Country name is valid.") else: print("Invalid country name.") - diff --git a/cloning_a_list.py b/cloning_a_list.py index ceaebef16e7..524225b734f 100644 --- a/cloning_a_list.py +++ b/cloning_a_list.py @@ -1,17 +1,11 @@ -# Python program to copy or clone a list -# Using the Slice Operator -def Cloning(li1): +# Python program to copy or clone a list +# Using the Slice Operator +def Cloning(li1): return li1[:] - -# Driver Code -li1 = [ - 4, - 8, - 2, - 10, - 15, - 18 -] -li2 = Cloning(li1) -print("Original List:", li1) -print("After Cloning:", li2) + + +# Driver Code +li1 = [4, 8, 2, 10, 15, 18] +li2 = Cloning(li1) +print("Original List:", li1) +print("After Cloning:", li2) diff --git a/colorma_as_color.py b/colorma_as_color.py index 4a9e49d1f14..a6cbd8725da 100644 --- a/colorma_as_color.py +++ b/colorma_as_color.py @@ -1,6 +1,4 @@ - - -from colorama import Fore, Back, Style +from colorama import Back, Fore, Style print(Fore.RED + "some red text") print(Back.GREEN + "and with a green background") @@ -18,4 +16,4 @@ print("back to normal now") -# …or, Colorama can be used in conjunction with existing ANSI libraries such as the venerable Termcolor the fabulous Blessings, or the incredible _Rich. \ No newline at end of file +# …or, Colorama can be used in conjunction with existing ANSI libraries such as the venerable Termcolor the fabulous Blessings, or the incredible _Rich. diff --git a/colour spiral.py b/colour spiral.py index 86385ada09d..70a96b94643 100644 --- a/colour spiral.py +++ b/colour spiral.py @@ -1,52 +1,50 @@ # import turtle import turtle - + # defining colors -colors = ['red', 'yellow', 'green', 'purple', 'blue', 'orange'] - +colors = ["red", "yellow", "green", "purple", "blue", "orange"] + # setup turtle pen -t= turtle.Pen() - +t = turtle.Pen() + # changes the speed of the turtle t.speed(10) - + # changes the background color turtle.bgcolor("black") - + # make spiral_web for x in range(200): + t.pencolor(colors[x % 6]) # setting color - t.pencolor(colors[x%6]) # setting color + t.width(x / 100 + 1) # setting width - t.width(x/100 + 1) # setting width + t.forward(x) # moving forward - t.forward(x) # moving forward + t.left(59) # moving left - t.left(59) # moving left - turtle.done() t.speed(10) - -turtle.bgcolor("black") # changes the background color - + +turtle.bgcolor("black") # changes the background color + # make spiral_web for x in range(200): + t.pencolor(colors[x % 6]) # setting color - t.pencolor(colors[x%6]) # setting color + t.width(x / 100 + 1) # setting width - t.width(x/100 + 1) # setting width + t.forward(x) # moving forward - t.forward(x) # moving forward + t.left(59) # moving left - t.left(59) # moving left - -turtle.done() \ No newline at end of file +turtle.done() diff --git a/communication/file.py b/communication/file.py index 4198d95ec0e..a43f7c79b99 100755 --- a/communication/file.py +++ b/communication/file.py @@ -1,41 +1,88 @@ -#!/usr/bin/python -# coding: utf-8 +#!/usr/bin/env python3 import math -import os import sys +from multiprocessing import Pipe, Process -def slice(mink, maxk): - s = 0.0 - for k in range(int(mink), int(maxk)): +def slice(mink: int, maxk: int) -> float: + """ + Calculate the partial sum of the series 1/(2k+1)² from mink to maxk-1. + + Args: + mink: Start index (inclusive) + maxk: End index (exclusive) + + Returns: + The computed partial sum + """ + s: float = 0.0 + for k in range(mink, maxk): s += 1.0 / (2 * k + 1) / (2 * k + 1) return s -def pi(n): - pids = [] - unit = n / 10 - for i in range(10): # 分10个子进程 +def worker(mink: int, maxk: int, conn) -> None: + """Worker function to compute slice and send result via pipe""" + try: + result = slice(mink, maxk) + conn.send(result) + conn.close() + except Exception as e: + conn.send(f"Error: {str(e)}") + conn.close() + + +def pi(n: int) -> float: + """ + Compute an approximation of π using multi-processing. + + Args: + n: Number of terms in the series to compute (divided by 10 processes) + + Returns: + Approximation of π using the computed sum + """ + processes: list[Process] = [] + parent_conns: list = [] + unit: int = n // 10 + + for i in range(10): mink = unit * i maxk = mink + unit - pid = os.fork() - if pid > 0: - pids.append(pid) + parent_conn, child_conn = Pipe() + p = Process(target=worker, args=(mink, maxk, child_conn)) + processes.append(p) + parent_conns.append(parent_conn) + p.start() + + # Collect results + sums: list[float] = [] + for conn in parent_conns: + result = conn.recv() + if isinstance(result, str) and result.startswith("Error:"): + print(result) + sums.append(0.0) else: - s = slice(mink, maxk) # 子进程开始计算 - with open("%d" % os.getpid(), "w") as f: - f.write(str(s)) - sys.exit(0) # 子进程结束 - sums = [] - for pid in pids: - os.waitpid(pid, 0) # 等待子进程结束 - with open("%d" % pid, "r") as f: - sums.append(float(f.read())) - os.remove("%d" % pid) # 删除通信的文件 + sums.append(float(result)) + conn.close() + + # Wait for all processes to finish + for p in processes: + p.join() + return math.sqrt(sum(sums) * 8) if __name__ == "__main__": - print("start") - print(pi(10000000)) + try: + n: int = int(sys.argv[1]) if len(sys.argv) > 1 else 10000000 + print(f"Calculating pi with {n} iterations using 10 processes...") + print(pi(n)) + except (ValueError, IndexError): + print(f"Usage: {sys.argv[0]} [iterations]") + print(" iterations: Number of terms (default: 10000000)") + sys.exit(1) + except KeyboardInterrupt: + print("\nInterrupted by user") + sys.exit(1) diff --git a/communication/pipe.py b/communication/pipe.py index 4138c519570..a43f7c79b99 100644 --- a/communication/pipe.py +++ b/communication/pipe.py @@ -1,43 +1,88 @@ -# coding: utf-8 - -from __future__ import print_function +#!/usr/bin/env python3 import math -import os import sys +from multiprocessing import Pipe, Process + + +def slice(mink: int, maxk: int) -> float: + """ + Calculate the partial sum of the series 1/(2k+1)² from mink to maxk-1. + Args: + mink: Start index (inclusive) + maxk: End index (exclusive) -def slice(mink, maxk): - s = 0.0 + Returns: + The computed partial sum + """ + s: float = 0.0 for k in range(mink, maxk): s += 1.0 / (2 * k + 1) / (2 * k + 1) return s -def pi(n): - childs = {} - unit = n / 10 - for i in range(10): # 分10个子进程 +def worker(mink: int, maxk: int, conn) -> None: + """Worker function to compute slice and send result via pipe""" + try: + result = slice(mink, maxk) + conn.send(result) + conn.close() + except Exception as e: + conn.send(f"Error: {str(e)}") + conn.close() + + +def pi(n: int) -> float: + """ + Compute an approximation of π using multi-processing. + + Args: + n: Number of terms in the series to compute (divided by 10 processes) + + Returns: + Approximation of π using the computed sum + """ + processes: list[Process] = [] + parent_conns: list = [] + unit: int = n // 10 + + for i in range(10): mink = unit * i maxk = mink + unit - r, w = os.pipe() - pid = os.fork() - if pid > 0: - childs[pid] = r # 将子进程的pid和读描述符存起来 - os.close(w) # 父进程关闭写描述符,只读 + parent_conn, child_conn = Pipe() + p = Process(target=worker, args=(mink, maxk, child_conn)) + processes.append(p) + parent_conns.append(parent_conn) + p.start() + + # Collect results + sums: list[float] = [] + for conn in parent_conns: + result = conn.recv() + if isinstance(result, str) and result.startswith("Error:"): + print(result) + sums.append(0.0) else: - os.close(r) # 子进程关闭读描述符,只写 - s = slice(mink, maxk) # 子进程开始计算 - os.write(w, str(s)) - os.close(w) # 写完了,关闭写描述符 - sys.exit(0) # 子进程结束 - sums = [] - - for pid, r in childs.items(): - sums.append(float(os.read(r, 1024))) - os.close(r) # 读完了,关闭读描述符 - os.waitpid(pid, 0) # 等待子进程结束 + sums.append(float(result)) + conn.close() + + # Wait for all processes to finish + for p in processes: + p.join() + return math.sqrt(sum(sums) * 8) -print(pi(10000000)) +if __name__ == "__main__": + try: + n: int = int(sys.argv[1]) if len(sys.argv) > 1 else 10000000 + print(f"Calculating pi with {n} iterations using 10 processes...") + print(pi(n)) + except (ValueError, IndexError): + print(f"Usage: {sys.argv[0]} [iterations]") + print(" iterations: Number of terms (default: 10000000)") + sys.exit(1) + except KeyboardInterrupt: + print("\nInterrupted by user") + sys.exit(1) diff --git a/communication/socket_conn.py b/communication/socket_conn.py index ffe1ed437fa..b0a4d63ccc7 100644 --- a/communication/socket_conn.py +++ b/communication/socket_conn.py @@ -1,43 +1,88 @@ -# coding: utf-8 - -from __future__ import print_function +#!/usr/bin/env python3 import math -import os -import socket import sys +from multiprocessing import Pipe, Process + + +def slice(mink: int, maxk: int) -> float: + """ + Calculate the partial sum of the series 1/(2k+1)² from mink to maxk-1. + Args: + mink: Start index (inclusive) + maxk: End index (exclusive) -def slice(mink, maxk): - s = 0.0 + Returns: + The computed partial sum + """ + s: float = 0.0 for k in range(mink, maxk): s += 1.0 / (2 * k + 1) / (2 * k + 1) return s -def pi(n): - childs = {} - unit = n / 10 - for i in range(10): # 分10个子进程 +def worker(mink: int, maxk: int, conn) -> None: + """Worker function to compute slice and send result via pipe""" + try: + result = slice(mink, maxk) + conn.send(result) # Send float directly + conn.close() + except Exception as e: + conn.send(f"Error: {str(e)}") + conn.close() + + +def pi(n: int) -> float: + """ + Compute an approximation of π using multi-processing. + + Args: + n: Number of terms in the series to compute (divided by 10 processes) + + Returns: + Approximation of π using the computed sum + """ + processes: list[Process] = [] + parent_conns: list = [] + unit: int = n // 10 # Ensure integer division + + for i in range(10): mink = unit * i maxk = mink + unit - rsock, wsock = socket.socketpair() - pid = os.fork() - if pid > 0: - childs[pid] = rsock - wsock.close() + parent_conn, child_conn = Pipe() + p = Process(target=worker, args=(mink, maxk, child_conn)) + processes.append(p) + parent_conns.append(parent_conn) + p.start() + + # Collect results + sums: list[float] = [] + for conn in parent_conns: + result = conn.recv() + if isinstance(result, str) and result.startswith("Error:"): + print(result) + sums.append(0.0) # Add zero if error occurred else: - rsock.close() - s = slice(mink, maxk) # 子进程开始计算 - wsock.send(str(s)) - wsock.close() - sys.exit(0) # 子进程结束 - sums = [] - for pid, rsock in childs.items(): - sums.append(float(rsock.recv(1024))) - rsock.close() - os.waitpid(pid, 0) # 等待子进程结束 + sums.append(float(result)) # Ensure float conversion + conn.close() + + # Wait for all processes to finish + for p in processes: + p.join() + return math.sqrt(sum(sums) * 8) -print(pi(10000000)) +if __name__ == "__main__": + try: + n: int = int(sys.argv[1]) if len(sys.argv) > 1 else 10000000 + print(f"Calculating pi with {n} iterations using 10 processes...") + print(pi(n)) + except (ValueError, IndexError): + print(f"Usage: {sys.argv[0]} [iterations]") + print(" iterations: Number of terms (default: 10000000)") + sys.exit(1) + except KeyboardInterrupt: + print("\nInterrupted by user") + sys.exit(1) diff --git a/compass_code.py b/compass_code.py index ec0ac377ba6..4b7bf7b1880 100644 --- a/compass_code.py +++ b/compass_code.py @@ -1,8 +1,9 @@ def degree_to_direction(deg): - directions = ["N", "NE", "E", "SE", "S", "SW", "W", "NW"] + directions = ["N", "NE", "E", "SE", "S", "SW", "W", "NW"] - deg = deg% 360 - deg = int(deg//45) - print(directions[deg]) + deg = deg % 360 + deg = int(deg // 45) + print(directions[deg]) -degree_to_direction(45) \ No newline at end of file + +degree_to_direction(45) diff --git a/contribution.txt b/contribution.txt deleted file mode 100644 index 181a276c94d..00000000000 --- a/contribution.txt +++ /dev/null @@ -1 +0,0 @@ -Add a dark mode toggle for better UX diff --git a/convert celsius into fahrenheit.py b/convert celsius into fahrenheit.py index df58fcda9de..0f3bf8e9838 100644 --- a/convert celsius into fahrenheit.py +++ b/convert celsius into fahrenheit.py @@ -1,4 +1,4 @@ -cels= float(input("enter temp in celsius")) -print("temprature in celsius is :",cels) -fahr = cels*9/5+32 -print("temprature in fahrenhite is :",fahr) +cels = float(input("enter temp in celsius")) +print("temprature in celsius is :", cels) +fahr = cels * 9 / 5 + 32 +print("temprature in fahrenhite is :", fahr) diff --git a/convert_time.py b/convert_time.py index d7ff1c9f697..913a63542ef 100644 --- a/convert_time.py +++ b/convert_time.py @@ -1,5 +1,3 @@ -from __future__ import print_function - # Created by sarathkaul on 12/11/19 @@ -10,12 +8,7 @@ def convert_time(input_str): return "00" + input_str[2:-2] # remove the AM - elif input_str[-2:] == "AM": - return input_str[:-2] - - # Checking if last two elements of time - # is PM and first two elements are 12 - elif input_str[-2:] == "PM" and input_str[:2] == "12": + elif input_str[-2:] == "AM" or input_str[-2:] == "PM" and input_str[:2] == "12": return input_str[:-2] else: diff --git a/convert_wind_direction_to_degrees.py b/convert_wind_direction_to_degrees.py index cbac637f332..a7a48988c12 100644 --- a/convert_wind_direction_to_degrees.py +++ b/convert_wind_direction_to_degrees.py @@ -3,6 +3,7 @@ def degrees_to_compass(degrees): index = round(degrees / 45) % 8 return directions[index] + # Taking input from the user while True: try: diff --git a/count the numbers of two vovels.py b/count the numbers of two vovels.py index 297e2488590..eb66d0967d6 100644 --- a/count the numbers of two vovels.py +++ b/count the numbers of two vovels.py @@ -1,19 +1,19 @@ # Program to count the number of each vowels # string of vowels -vowels = 'aeiou' +vowels = "aeiou" -ip_str = 'Hello, have you tried our tutorial section yet?' +ip_str = "Hello, have you tried our tutorial section yet?" # make it suitable for caseless comparisions ip_str = ip_str.casefold() # make a dictionary with each vowel a key and value 0 -count = {}.fromkeys(vowels,0) +count = {}.fromkeys(vowels, 0) # count the vowels for char in ip_str: - if char in count: - count[char] += 1 + if char in count: + count[char] += 1 print(count) diff --git a/create password validity in python.py b/create password validity in python.py index 46793e91061..c69a826e89e 100644 --- a/create password validity in python.py +++ b/create password validity in python.py @@ -1,24 +1,27 @@ import time -pwd=input("Enter your password: ") #any password u want to set + +pwd = input("Enter your password: ") # any password u want to set + def IInd_func(): - count1=0 - for j in range(5): - a=0 - count=0 - user_pwd = input("Enter remember password: ") #password you remember - for i in range(len(pwd)): - if user_pwd[i] == pwd[a]: #comparing remembered pwd with fixed pwd - a +=1 - count+=1 - if count==len(pwd): - print("correct pwd") - break - else: - count1 += 1 - print("not correct") - if count1==5: - time.sleep(30) - IInd_func() + count1 = 0 + for j in range(5): + a = 0 + count = 0 + user_pwd = input("Enter remember password: ") # password you remember + for i in range(len(pwd)): + if user_pwd[i] == pwd[a]: # comparing remembered pwd with fixed pwd + a += 1 + count += 1 + if count == len(pwd): + print("correct pwd") + break + else: + count1 += 1 + print("not correct") + if count1 == 5: + time.sleep(30) + IInd_func() + -IInd_func() \ No newline at end of file +IInd_func() diff --git a/cricket_news.py b/cricket_news.py index 8c78c1820e6..b5c6405a28f 100644 --- a/cricket_news.py +++ b/cricket_news.py @@ -1,6 +1,6 @@ -from bs4 import BeautifulSoup -import requests import pyttsx3 +import requests +from bs4 import BeautifulSoup engine = pyttsx3.init() voices = engine.getProperty("voices") diff --git a/currency converter/country.txt b/currency converter/country.txt deleted file mode 100644 index 0398e381859..00000000000 --- a/currency converter/country.txt +++ /dev/null @@ -1,177 +0,0 @@ -Australia Dollar-AUD -Great Britain Pound-GBP -Euro-EUR -Japan Yen-JPY -Switzerland Franc-CHF -USA Dollar-USD -Afghanistan Afghani-AFN -Albania Lek-ALL -Algeria Dinar-DZD -Angola Kwanza-AOA -Argentina Peso-ARS -Armenia Dram-AMD -Aruba Florin-AWG -Australia Dollar-AUD -Austria Schilling-ATS (EURO) -Belgium Franc-BEF (EURO) -Azerbaijan New Manat-AZN -Bahamas Dollar-BSD -Bahrain Dinar-BHD -Bangladesh Taka-BDT -Barbados Dollar-BBD -Belarus Ruble-BYR -Belize Dollar-BZD -Bermuda Dollar-BMD -Bhutan Ngultrum-BTN -Bolivia Boliviano-BOB -Bosnia Mark-BAM -Botswana Pula-BWP -Brazil Real-BRL -Great Britain Pound-GBP -Brunei Dollar-BND -Bulgaria Lev-BGN -Burundi Franc-BIF -CFA Franc BCEAO-XOF -CFA Franc BEAC-XAF -CFP Franc-XPF -Cambodia Riel-KHR -Canada Dollar-CAD -Cape Verde Escudo-CVE -Cayman Islands Dollar-KYD -Chili Peso-CLP -China Yuan/Renminbi-CNY -Colombia Peso-COP -Comoros Franc-KMF -Congo Franc-CDF -Costa Rica Colon-CRC -Croatia Kuna-HRK -Cuba Convertible Peso-CUC -Cuba Peso-CUP -Cyprus Pound-CYP (EURO) -Czech Koruna-CZK -Denmark Krone-DKK -Djibouti Franc-DJF -Dominican Republich Peso-DOP -East Caribbean Dollar-XCD -Egypt Pound-EGP -El Salvador Colon-SVC -Estonia Kroon-EEK (EURO) -Ethiopia Birr-ETB -Euro-EUR -Falkland Islands Pound-FKP -Finland Markka-FIM (EURO) -Fiji Dollar-FJD -Gambia Dalasi-GMD -Georgia Lari-GEL -Germany Mark-DMK (EURO) -Ghana New Cedi-GHS -Gibraltar Pound-GIP -Greece Drachma-GRD (EURO) -Guatemala Quetzal-GTQ -Guinea Franc-GNF -Guyana Dollar-GYD -Haiti Gourde-HTG -Honduras Lempira-HNL -Hong Kong Dollar-HKD -Hungary Forint-HUF -Iceland Krona-ISK -India Rupee-INR -Indonesia Rupiah-IDR -Iran Rial-IRR -Iraq Dinar-IQD -Ireland Pound-IED (EURO) -Israel New Shekel-ILS -Italy Lira-ITL (EURO) -Jamaica Dollar-JMD -Japan Yen-JPY -Jordan Dinar-JOD -Kazakhstan Tenge-KZT -Kenya Shilling-KES -Kuwait Dinar-KWD -Kyrgyzstan Som-KGS -Laos Kip-LAK -Latvia Lats-LVL (EURO) -Lebanon Pound-LBP -Lesotho Loti-LSL -Liberia Dollar-LRD -Libya Dinar-LYD -Lithuania Litas-LTL (EURO) -Luxembourg Franc-LUF (EURO) -Macau Pataca-MOP -Macedonia Denar-MKD -Malagasy Ariary-MGA -Malawi Kwacha-MWK -Malaysia Ringgit-MYR -Maldives Rufiyaa-MVR -Malta Lira-MTL (EURO) -Mauritania Ouguiya-MRO -Mauritius Rupee-MUR -Mexico Peso-MXN -Moldova Leu-MDL -Mongolia Tugrik-MNT -Morocco Dirham-MAD -Mozambique New Metical-MZN -Myanmar Kyat-MMK -NL Antilles Guilder-ANG -Namibia Dollar-NAD -Nepal Rupee-NPR -Netherlands Guilder-NLG (EURO) -New Zealand Dollar-NZD -Nicaragua Cordoba Oro-NIO -Nigeria Naira-NGN -North Korea Won-KPW -Norway Kroner-NOK -Oman Rial-OMR -Pakistan Rupee-PKR -Panama Balboa-PAB -Papua New Guinea Kina-PGK -Paraguay Guarani-PYG -Peru Nuevo Sol-PEN -Philippines Peso-PHP -Poland Zloty-PLN -Portugal Escudo-PTE (EURO) -Qatar Rial-QAR -Romania New Lei-RON -Russia Rouble-RUB -Rwanda Franc-RWF -Samoa Tala-WST -Sao Tome/Principe Dobra-STD -Saudi Arabia Riyal-SAR -Serbia Dinar-RSD -Seychelles Rupee-SCR -Sierra Leone Leone-SLL -Singapore Dollar-SGD -Slovakia Koruna-SKK (EURO) -Slovenia Tolar-SIT (EURO) -Solomon Islands Dollar-SBD -Somali Shilling-SOS -South Africa Rand-ZAR -South Korea Won-KRW -Spain Peseta-ESP (EURO) -Sri Lanka Rupee-LKR -St Helena Pound-SHP -Sudan Pound-SDG -Suriname Dollar-SRD -Swaziland Lilangeni-SZL -Sweden Krona-SEK -Switzerland Franc-CHF -Syria Pound-SYP -Taiwan Dollar-TWD -Tanzania Shilling-TZS -Thailand Baht-THB -Tonga Pa'anga-TOP -Trinidad/Tobago Dollar-TTD -Tunisia Dinar-TND -Turkish New Lira-TRY -Turkmenistan Manat-TMM -USA Dollar-USD -Uganda Shilling-UGX -Ukraine Hryvnia-UAH -Uruguay Peso-UYU -United Arab Emirates Dirham-AED -Vanuatu Vatu-VUV -Venezuela Bolivar-VEB -Vietnam Dong-VND -Yemen Rial-YER -Zambia Kwacha-ZMK -Zimbabwe Dollar-ZWD \ No newline at end of file diff --git a/currency converter/gui.ui b/currency converter/gui.ui index a2b39c9e6a4..178bd0edcbc 100644 --- a/currency converter/gui.ui +++ b/currency converter/gui.ui @@ -114,7 +114,7 @@ Arial - -1 + 28 75 true @@ -181,7 +181,7 @@ Arial - -1 + 20 50 true false @@ -203,7 +203,7 @@ Arial - -1 + 20 50 true false @@ -227,4 +227,4 @@ - + \ No newline at end of file diff --git a/currency converter/main.py b/currency converter/main.py index b656e7bdf3b..99736b6ee89 100644 --- a/currency converter/main.py +++ b/currency converter/main.py @@ -1,57 +1,314 @@ -# cc program -from PyQt5.QtGui import * -from PyQt5.QtCore import * -from PyQt5.QtWidgets import * -from PyQt5 import QtWidgets, uic -from PyQt5.QtCore import * +"""Currency Converter Application + +A PyQt5-based currency converter with embedded currency data (no external files required). +Fetches real-time exchange rates and provides a user-friendly interface. +""" + +import sys +from pathlib import Path + import httpx -from bs4 import BeautifulSoup +from PyQt5 import uic +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QDoubleValidator +from PyQt5.QtWidgets import ( + QApplication, + QComboBox, + QLCDNumber, + QLineEdit, + QMainWindow, + QPushButton, + QWidget, +) + +# Embedded currency data (originally from country.txt) +CURRENCIES = [ + "Australia Dollar-AUD", + "Great Britain Pound-GBP", + "Euro-EUR", + "Japan Yen-JPY", + "Switzerland Franc-CHF", + "USA Dollar-USD", + "Afghanistan Afghani-AFN", + "Albania Lek-ALL", + "Algeria Dinar-DZD", + "Angola Kwanza-AOA", + "Argentina Peso-ARS", + "Armenia Dram-AMD", + "Aruba Florin-AWG", + "Austria Schilling-ATS (EURO)", + "Belgium Franc-BEF (EURO)", + "Azerbaijan New Manat-AZN", + "Bahamas Dollar-BSD", + "Bahrain Dinar-BHD", + "Bangladesh Taka-BDT", + "Barbados Dollar-BBD", + "Belarus Ruble-BYR", + "Belize Dollar-BZD", + "Bermuda Dollar-BMD", + "Bhutan Ngultrum-BTN", + "Bolivia Boliviano-BOB", + "Bosnia Mark-BAM", + "Botswana Pula-BWP", + "Brazil Real-BRL", + "Brunei Dollar-BND", + "Bulgaria Lev-BGN", + "Burundi Franc-BIF", + "CFA Franc BCEAO-XOF", + "CFA Franc BEAC-XAF", + "CFP Franc-XPF", + "Cambodia Riel-KHR", + "Canada Dollar-CAD", + "Cape Verde Escudo-CVE", + "Cayman Islands Dollar-KYD", + "Chili Peso-CLP", + "China Yuan/Renminbi-CNY", + "Colombia Peso-COP", + "Comoros Franc-KMF", + "Congo Franc-CDF", + "Costa Rica Colon-CRC", + "Croatia Kuna-HRK", + "Cuba Convertible Peso-CUC", + "Cuba Peso-CUP", + "Cyprus Pound-CYP (EURO)", + "Czech Koruna-CZK", + "Denmark Krone-DKK", + "Djibouti Franc-DJF", + "Dominican Republich Peso-DOP", + "East Caribbean Dollar-XCD", + "Egypt Pound-EGP", + "El Salvador Colon-SVC", + "Estonia Kroon-EEK (EURO)", + "Ethiopia Birr-ETB", + "Falkland Islands Pound-FKP", + "Finland Markka-FIM (EURO)", + "Fiji Dollar-FJD", + "Gambia Dalasi-GMD", + "Georgia Lari-GEL", + "Germany Mark-DMK (EURO)", + "Ghana New Cedi-GHS", + "Gibraltar Pound-GIP", + "Greece Drachma-GRD (EURO)", + "Guatemala Quetzal-GTQ", + "Guinea Franc-GNF", + "Guyana Dollar-GYD", + "Haiti Gourde-HTG", + "Honduras Lempira-HNL", + "Hong Kong Dollar-HKD", + "Hungary Forint-HUF", + "Iceland Krona-ISK", + "India Rupee-INR", + "Indonesia Rupiah-IDR", + "Iran Rial-IRR", + "Iraq Dinar-IQD", + "Ireland Pound-IED (EURO)", + "Israel New Shekel-ILS", + "Italy Lira-ITL (EURO)", + "Jamaica Dollar-JMD", + "Jordan Dinar-JOD", + "Kazakhstan Tenge-KZT", + "Kenya Shilling-KES", + "Kuwait Dinar-KWD", + "Kyrgyzstan Som-KGS", + "Laos Kip-LAK", + "Latvia Lats-LVL (EURO)", + "Lebanon Pound-LBP", + "Lesotho Loti-LSL", + "Liberia Dollar-LRD", + "Libya Dinar-LYD", + "Lithuania Litas-LTL (EURO)", + "Luxembourg Franc-LUF (EURO)", + "Macau Pataca-MOP", + "Macedonia Denar-MKD", + "Malagasy Ariary-MGA", + "Malawi Kwacha-MWK", + "Malaysia Ringgit-MYR", + "Maldives Rufiyaa-MVR", + "Malta Lira-MTL (EURO)", + "Mauritania Ouguiya-MRO", + "Mauritius Rupee-MUR", + "Mexico Peso-MXN", + "Moldova Leu-MDL", + "Mongolia Tugrik-MNT", + "Morocco Dirham-MAD", + "Mozambique New Metical-MZN", + "Myanmar Kyat-MMK", + "NL Antilles Guilder-ANG", + "Namibia Dollar-NAD", + "Nepal Rupee-NPR", + "Netherlands Guilder-NLG (EURO)", + "New Zealand Dollar-NZD", + "Nicaragua Cordoba Oro-NIO", + "Nigeria Naira-NGN", + "North Korea Won-KPW", + "Norway Kroner-NOK", + "Oman Rial-OMR", + "Pakistan Rupee-PKR", + "Panama Balboa-PAB", + "Papua New Guinea Kina-PGK", + "Paraguay Guarani-PYG", + "Peru Nuevo Sol-PEN", + "Philippines Peso-PHP", + "Poland Zloty-PLN", + "Portugal Escudo-PTE (EURO)", + "Qatar Rial-QAR", + "Romania New Lei-RON", + "Russia Rouble-RUB", + "Rwanda Franc-RWF", + "Samoa Tala-WST", + "Sao Tome/Principe Dobra-STD", + "Saudi Arabia Riyal-SAR", + "Serbia Dinar-RSD", + "Seychelles Rupee-SCR", + "Sierra Leone Leone-SLL", + "Singapore Dollar-SGD", + "Slovakia Koruna-SKK (EURO)", + "Slovenia Tolar-SIT (EURO)", + "Solomon Islands Dollar-SBD", + "Somali Shilling-SOS", + "South Africa Rand-ZAR", + "South Korea Won-KRW", + "Spain Peseta-ESP (EURO)", + "Sri Lanka Rupee-LKR", + "St Helena Pound-SHP", + "Sudan Pound-SDG", + "Suriname Dollar-SRD", + "Swaziland Lilangeni-SZL", + "Sweden Krona-SEK", + "Syria Pound-SYP", + "Taiwan Dollar-TWD", + "Tanzania Shilling-TZS", + "Thailand Baht-THB", + "Tonga Pa'anga-TOP", + "Trinidad/Tobago Dollar-TTD", + "Tunisia Dinar-TND", + "Turkish New Lira-TRY", + "Turkmenistan Manat-TMM", + "Uganda Shilling-UGX", + "Ukraine Hryvnia-UAH", + "Uruguay Peso-UYU", + "United Arab Emirates Dirham-AED", + "Vanuatu Vatu-VUV", + "Venezuela Bolivar-VEB", + "Vietnam Dong-VND", + "Yemen Rial-YER", + "Zambia Kwacha-ZMK", + "Zimbabwe Dollar-ZWD", +] + + +class CurrencyConverter(QMainWindow): + """Main application window for currency conversion""" + + def __init__(self) -> None: + super().__init__() + self.base_dir: Path = Path(__file__).parent # Directory of current script + self.ui: QWidget = self.load_ui() + self.setup_ui_elements() + self.load_currency_data() # Load from embedded list + + # Type hints for UI elements (assigned via UI file) + self.lineEdit: QLineEdit + self.pushButton: QPushButton + self.dropDown1: QComboBox + self.dropDown2: QComboBox + self.lcdpanel: QLCDNumber + + def load_ui(self) -> QWidget: + """Load UI file with proper path handling""" + ui_path: Path = self.base_dir / "gui.ui" + + try: + return uic.loadUi(str(ui_path), self) + except FileNotFoundError: + print(f"Error: UI file not found at {ui_path}") + print(f"Please ensure 'gui.ui' exists in: {self.base_dir}") + sys.exit(1) + + def setup_ui_elements(self) -> None: + """Initialize UI components and connections""" + self.lineEdit.setValidator(QDoubleValidator()) + self.pushButton.clicked.connect(self.convert_currency) + self.setWindowTitle("Dynamic Currency Converter") + + def load_currency_data(self) -> None: + """Load currency list from embedded data (no external file)""" + # Remove duplicates while preserving order + seen: set = set() + unique_currencies: list[str] = [] + for currency in CURRENCIES: + if currency not in seen: + seen.add(currency) + unique_currencies.append(currency) + + # Populate dropdowns + self.dropDown1.addItem("Select Currency") + self.dropDown2.addItem("Select Currency") + for currency in unique_currencies: + self.dropDown1.addItem(currency) + self.dropDown2.addItem(currency) + + def get_exchange_rate(self, from_currency: str, to_currency: str) -> float | None: + """Fetch exchange rate from API""" + try: + # Extract currency codes (format: "Name-CODE") + from_code: str = from_currency.split("-")[-1].strip() + to_code: str = to_currency.split("-")[-1].strip() + # Clean up codes with extra info (e.g., "(EURO)") + from_code = from_code.split()[0] + to_code = to_code.split()[0] -def getVal(cont1, cont2): - cont1val = cont1.split("-")[1] - cont2val = cont2.split("-")[1] - url = f"https://free.currconv.com/api/v7/convert?q={cont1val}_{cont2val}&compact=ultra&apiKey=b43a653672c4a94c4c26" - r = httpx.get(url) - htmlContent = r.content - soup = BeautifulSoup(htmlContent, "html.parser") - try: - valCurr = float(soup.get_text().split(":")[1].removesuffix("}")) # {USD:70.00} - except Exception: - print("Server down.") - exit() - return valCurr + # API request + api_key: str = "b43a653672c4a94c4c26" # Replace with your API key if needed + url: str = f"https://free.currconv.com/api/v7/convert?q={from_code}_{to_code}&compact=ultra&apiKey={api_key}" + response: httpx.Response = httpx.get(url, timeout=10) + response.raise_for_status() + data: dict[str, float] = response.json() -app = QtWidgets.QApplication([]) + rate_key: str = f"{from_code}_{to_code}" + return float(data[rate_key]) if rate_key in data else None -window = uic.loadUi("gui.ui") -f = open("country.txt", "r") + except Exception as e: + print(f"Error fetching exchange rate: {str(e)}") + return None -window = uic.loadUi("C:/Users/prath/Desktop/Currency-Calculator-Dynamic/gui.ui") -f = open("C:/Users/prath/Desktop/Currency-Calculator-Dynamic/country.txt", "r") + def convert_currency(self) -> None: + """Handle currency conversion when button is clicked""" + amount_text: str = self.lineEdit.text() + from_currency: str = self.dropDown1.currentText() + to_currency: str = self.dropDown2.currentText() -window.dropDown1.addItem("Select") -window.dropDown2.addItem("Select") -for i in f.readlines(): - window.dropDown1.addItem(i) - window.dropDown2.addItem(i) -intOnly = QDoubleValidator() -window.lineEdit.setValidator(intOnly) + # Validate inputs + if ( + not amount_text + or from_currency == "Select Currency" + or to_currency == "Select Currency" + ): + self.lcdpanel.display(0) + return + try: + amount: float = float(amount_text) + rate: float | None = self.get_exchange_rate(from_currency, to_currency) -def main(): - window.pushButton.clicked.connect(changeBtn) + if rate is not None: + result: float = amount * rate + self.lcdpanel.display(round(result, 2)) + else: + self.lcdpanel.display(0) + except ValueError: + self.lcdpanel.display(0) -def changeBtn(): - val = window.lineEdit.text() - cont1 = window.dropDown1.currentText() - cont2 = window.dropDown2.currentText() - valCurr = getVal(cont1.rstrip(), cont2.rstrip()) - window.lcdpanel.display(float(val) * valCurr) +if __name__ == "__main__": + # High-DPI support + QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True) + QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps, True) -main() -window.show() -app.exec() + app: QApplication = QApplication(sys.argv) + window: CurrencyConverter = CurrencyConverter() + window.show() + sys.exit(app.exec_()) diff --git a/daily_checks.py b/daily_checks.py index 337f8d5aebe..3917d25387e 100644 --- a/daily_checks.py +++ b/daily_checks.py @@ -12,6 +12,7 @@ Description : This simple script loads everything I need to carry out the daily checks for our systems. """ + import os import platform # Load Modules import subprocess @@ -43,7 +44,7 @@ def putty_sessions(conffilename): # Function to load the putty sessions I need # Open the file server_list.txt, loop through reading each line # 1.1 -Changed - 1.3 Changed name to use variable conffilename for server in open(conffilename): - subprocess.Popen(("putty -load " + server)) # Open the PuTTY sessions - 1.1 + subprocess.Popen("putty -load " + server) # Open the PuTTY sessions - 1.1 def rdp_sessions(): diff --git a/daily_horoscope.py b/daily_horoscope.py index 04669971819..556be32753c 100644 --- a/daily_horoscope.py +++ b/daily_horoscope.py @@ -1,5 +1,5 @@ -from bs4 import BeautifulSoup import requests +from bs4 import BeautifulSoup """ this check_sign function checks and returns the zodiac sign diff --git a/date-timeserver.py b/date-timeserver.py index c0d114c02f4..5cacec71d1c 100644 --- a/date-timeserver.py +++ b/date-timeserver.py @@ -5,7 +5,6 @@ soc.bind((socket.gethostname(), 2905)) soc.listen(5) while True: - clientsocket, addr = soc.accept() print("estavlishes a connection from %s" % str(addr)) diff --git a/days_from_date.py b/days_from_date.py index 3a166679607..938c0b7adec 100644 --- a/days_from_date.py +++ b/days_from_date.py @@ -1,6 +1,6 @@ -import re # regular expressions import calendar # module of python to provide useful fucntions related to calendar import datetime # module of python to get the date and time +import re # regular expressions import tkinter as tk root = tk.Tk() @@ -15,9 +15,9 @@ def process_date(user_input): def find_day(date): - born = datetime.datetime.strptime( - date, "%d %m %Y" - ).weekday() # this statement returns an integer corresponding to the day of the week + born = ( + datetime.datetime.strptime(date, "%d %m %Y").weekday() + ) # this statement returns an integer corresponding to the day of the week return calendar.day_name[ born ] # this statement returns the corresponding day name to the integer generated in the previous statement diff --git a/decimal to binary.py b/decimal to binary.py index 566f83be43c..03619b074c2 100644 --- a/decimal to binary.py +++ b/decimal to binary.py @@ -3,7 +3,7 @@ def decimalToBinary(num): to binary and prints it""" if num > 1: decimalToBinary(num // 2) - print(num % 2, end='') + print(num % 2, end="") # decimal number diff --git a/depreciated_programs/corona_cases.py b/depreciated_programs/corona_cases.py index e93e7cd99f9..563e8e23d63 100644 --- a/depreciated_programs/corona_cases.py +++ b/depreciated_programs/corona_cases.py @@ -1,50 +1,75 @@ import sys +from time import sleep +from typing import Any + +import httpx + +# Type aliases +CovidData = dict[str, Any] +CountryData = list[dict[str, Any]] + +# API request and data processing +url: str = "https://api.covid19api.com/summary" try: - import requests + response: httpx.Response = httpx.get(url) + response.raise_for_status() # Check if request was successful + visit: CovidData = response.json() except ImportError: - print("Please Install Requests Module With Command 'pip install requests'") + print("Please install the HTTPX module using 'pip install httpx'") sys.exit(1) -from time import sleep +except (httpx.RequestError, ValueError) as e: + print(f"Failed to fetch data: {e}") + sys.exit(1) + +# Extract global data +global_data: dict[str, int] = visit["Global"] +NewConfirmed: int = global_data["NewConfirmed"] +TotalConfirmed: int = global_data["TotalConfirmed"] +NewDeaths: int = global_data["NewDeaths"] +TotalDeaths: int = global_data["TotalDeaths"] +NewRecovered: int = global_data["NewRecovered"] +TotalRecovered: int = global_data["TotalRecovered"] + +# Extract India data (using country name instead of index for reliability) +countries: CountryData = visit["Countries"] +india_data: dict[str, Any] | None = next( + (country for country in countries if country["Country"] == "India"), None +) + +if india_data is None: + print("Error: India's data not found in the API response.") + sys.exit(1) + +name: str = india_data["Country"] +indiaconfirmed: int = india_data["NewConfirmed"] +indiatotal: int = india_data["TotalConfirmed"] +indiaDeaths: int = india_data["NewDeaths"] +deathstotal: int = india_data["TotalDeaths"] +indianewr: int = india_data["NewRecovered"] +totalre: int = india_data["TotalRecovered"] +DateUpdate: str = india_data["Date"] -url = "https://api.covid19api.com/summary" -visit = requests.get(url).json() - -NewConfirmed = visit["Global"]["NewConfirmed"] -TotalConfirmed = visit["Global"]["TotalConfirmed"] -NewDeaths = visit["Global"]["NewDeaths"] -TotalDeaths = visit["Global"]["TotalDeaths"] -NewRecovered = visit["Global"]["NewRecovered"] -TotalRecovered = visit["Global"]["TotalRecovered"] - -india = visit["Countries"] -name = india[76]["Country"] -indiaconfirmed = india[76]["NewConfirmed"] -indiatotal = india[76]["TotalConfirmed"] -indiaDeaths = india[76]["NewDeaths"] -deathstotal = india[76]["TotalDeaths"] -indianewr = india[76]["NewRecovered"] -totalre = india[76]["TotalRecovered"] -DateUpdate = india[76]["Date"] - - -def world(): - world = f""" + +def world() -> None: + """Display global COVID-19 statistics""" + world_stats = f""" ▀▀█▀▀ █▀▀█ ▀▀█▀▀ █▀▀█ █░░   ▒█▀▀█ █▀▀█ █▀▀ █▀▀ █▀▀   ▀█▀ █▀▀▄   ▒█░░▒█ █▀▀█ █▀▀█ █░░ █▀▀▄ ░▒█░░ █░░█ ░░█░░ █▄▄█ █░░   ▒█░░░ █▄▄█ ▀▀█ █▀▀ ▀▀█   ▒█░ █░░█   ▒█▒█▒█ █░░█ █▄▄▀ █░░ █░░█ ░▒█░░ ▀▀▀▀ ░░▀░░ ▀░░▀ ▀▀▀   ▒█▄▄█ ▀░░▀ ▀▀▀ ▀▀▀ ▀▀▀   ▄█▄ ▀░░▀   ▒█▄▀▄█ ▀▀▀▀ ▀░▀▀ ▀▀▀ ▀▀▀░\n -New Confirmed Cases :- {NewConfirmed} -Total Confirmed Cases :- {TotalConfirmed} -New Deaths :- {NewDeaths} -Total Deaths :- {TotalDeaths} -New Recovered :- {NewRecovered} -Total Recovered :- {TotalRecovered} +New Confirmed Cases: {NewConfirmed} +Total Confirmed Cases: {TotalConfirmed} +New Deaths: {NewDeaths} +Total Deaths: {TotalDeaths} +New Recovered: {NewRecovered} +Total Recovered: {TotalRecovered} """ - print(world) + print(world_stats) -def india(): - cases = f""" +def india() -> None: + """Display COVID-19 statistics for India""" + india_stats = f""" ██╗███╗░░██╗██████╗░██╗░█████╗░ ██║████╗░██║██╔══██╗██║██╔══██╗ ██║██╔██╗██║██║░░██║██║███████║ @@ -52,34 +77,34 @@ def india(): ██║██║░╚███║██████╔╝██║██║░░██║ ╚═╝╚═╝░░╚══╝╚═════╝░╚═╝╚═╝░░╚═╝ -Country Name :- {name} -New Confirmed Cases :- {indiaonfirmed} -Total Confirmed Cases :- {indiatotal} -New Deaths :- {indiaDeaths} -Total Deaths :- {deathstotal} -New Recovered :- {indianewr} -Total Recovered :- {totalre} -Information Till :- {DateUpdate} +Country: {name} +New Confirmed Cases: {indiaconfirmed} +Total Confirmed Cases: {indiatotal} +New Deaths: {indiaDeaths} +Total Deaths: {deathstotal} +New Recovered: {indianewr} +Total Recovered: {totalre} +Updated As Of: {DateUpdate} """ - print(cases) + print(india_stats) -print( - """ +# ASCII art title +print(""" ░█████╗░░█████╗░██████╗░░█████╗░███╗░░██╗░█████╗░  ██╗░░░██╗██╗██████╗░██╗░░░██╗░██████╗ ██╔══██╗██╔══██╗██╔══██╗██╔══██╗████╗░██║██╔══██╗  ██║░░░██║██║██╔══██╗██║░░░██║██╔════╝ ██║░░╚═╝██║░░██║██████╔╝██║░░██║██╔██╗██║███████║  ╚██╗░██╔╝██║██████╔╝██║░░░██║╚█████╗░ ██║░░██╗██║░░██║██╔══██╗██║░░██║██║╚████║██╔══██║  ░╚████╔╝░██║██╔══██╗██║░░░██║░╚═══██╗ ╚█████╔╝╚█████╔╝██║░░██║╚█████╔╝██║░╚███║██║░░██║  ░░╚██╔╝░░██║██║░░██║╚██████╔╝██████╔╝ -░╚════╝░░╚════╝░╚═╝░░╚═╝░╚════╝░╚═╝░░╚══╝╚═╝░░╚═╝  ░░░╚═╝░░░╚═╝╚═╝░░╚═╝░╚═════╝░╚═════╝░""" -) +░╚════╝░░╚════╝░╚═╝░░╚═╝░╚════╝░╚═╝░░╚══╝╚═╝░░╚═╝  ░░░╚═╝░░░╚═╝╚═╝░░╚═╝░╚═════╝░╚═════╝░""") print("\nDeveloped By @TheDarkW3b") -def choices(): - print("\n1 - To Know Corona Virus Update Across World") - print("\n2 - To Know Corona Virus Update In India") - choice = input("Enter 1 Or 2 :- ") +def choices() -> None: + """Main menu for user choices""" + print("\n1 - View Global COVID-19 Updates") + print("\n2 - View COVID-19 Updates in India") + choice = input("Enter 1 or 2: ") if choice == "1": world() @@ -90,8 +115,9 @@ def choices(): sleep(1) choices() else: - print("\nYou Have Entered Something Wrong, Please Enter Again") + print("\nInvalid input. Please try again.") choices() +# Start the interactive menu choices() diff --git a/dialogs/messagebox.py b/dialogs/messagebox.py deleted file mode 100644 index 14a88dc185d..00000000000 --- a/dialogs/messagebox.py +++ /dev/null @@ -1,7 +0,0 @@ -# Use the MessageBox() function to display a simple message box. - -from quo.dialog import MessageBox - -MessageBox( - title='Example dialog window', - text='Do you want to continue?') diff --git a/dialogs/requirements.txt b/dialogs/requirements.txt deleted file mode 100644 index 51d89fc61fc..00000000000 --- a/dialogs/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -quo>=2022.4 diff --git a/dialogs/show_dialogs.py b/dialogs/show_dialogs.py new file mode 100644 index 00000000000..c4eb98a19ca --- /dev/null +++ b/dialogs/show_dialogs.py @@ -0,0 +1,31 @@ +import tkinter as tk +from tkinter import messagebox + + +def display_message_box() -> str | None: + """Display a message box and return user's response""" + root = tk.Tk() + root.withdraw() # Hide the main window + + # Show a custom message box + result = messagebox.askyesnocancel( + title="Example Dialog Window", message="Do you want to continue?" + ) + + # Map boolean result to string values + if result is None: + return "cancel" + elif result: + return "yes" + else: + return "no" + + +if __name__ == "__main__": + # Optional: Set font to ensure Chinese characters display correctly + # import matplotlib.pyplot as plt + # plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"] + + # Display the message box + response = display_message_box() + print(f"User response: {response}") diff --git a/dice.py b/dice.py index a2e5c12f99b..90ea7414753 100644 --- a/dice.py +++ b/dice.py @@ -12,7 +12,7 @@ import random -class Die(object): +class Die: # A dice has a feature of number about how many sides it has when it's # established,like 6. def __init__(self): diff --git a/diction.py b/diction.py index e4757e3db0e..89b2555a1cf 100644 --- a/diction.py +++ b/diction.py @@ -1,6 +1,7 @@ +import json from difflib import get_close_matches + import pyttsx3 -import json import speech_recognition as sr data = json.load(open("data.json")) diff --git a/digital_clock.py b/digital_clock.py index f461878917b..a5c6c352d19 100644 --- a/digital_clock.py +++ b/digital_clock.py @@ -5,21 +5,22 @@ import time +# importing strftime function to +# retrieve system's time +from time import strftime + # because we need digital clock , so we are importing the time library. # master from tkinter import * from tkinter.ttk import * -# importing strftime function to -# retrieve system's time -from time import strftime - # creating tkinter window root = Tk() root.title("Clock") # master + # This function is used to # display time on the label def def_time(): @@ -50,7 +51,6 @@ def def_time(): # function to declare the tkniter clock def dig_clock(): - text_input = time.strftime("%H : %M : %S") # get the current local time from the PC label.config(text=text_input) diff --git a/dir_test.py b/dir_test.py index 992d5924a88..f9faa65e5d9 100644 --- a/dir_test.py +++ b/dir_test.py @@ -6,7 +6,6 @@ # Modifications : # Description : Tests to see if the directory testdir exists, if not it will create the directory for you if you want it created. -from __future__ import print_function import os diff --git a/divisors_of_a_number.py b/divisors_of_a_number.py index 326378b177f..55ffd18a753 100644 --- a/divisors_of_a_number.py +++ b/divisors_of_a_number.py @@ -1,20 +1,20 @@ a = 0 -while a<= 0 : +while a <= 0: number_to_divide = input("choose the number to divide -->") - try : + try: a = int(number_to_divide) - except ValueError : + except ValueError: a = 0 - if a <= 0 : - print('choose a number grether than 0') + if a <= 0: + print("choose a number grether than 0") list_number_divided = [] -for number in range(1,a + 1) : +for number in range(1, a + 1): b = a % number - if b == 0 : + if b == 0: list_number_divided.append(number) -print('\nthe number ' + number_to_divide + ' can be divided by:') -for item in list_number_divided : - print(f'{item}') -if len(list_number_divided) <= 2 : - print(number_to_divide + ' is a prime number') \ No newline at end of file +print("\nthe number " + number_to_divide + " can be divided by:") +for item in list_number_divided: + print(f"{item}") +if len(list_number_divided) <= 2: + print(number_to_divide + " is a prime number") diff --git a/encryptsys.py b/encryptsys.py index 45daea14fd6..74c2403128e 100644 --- a/encryptsys.py +++ b/encryptsys.py @@ -37,7 +37,6 @@ def decrypt(): def encrypt(): - texto = input("Input the text to encrypt : ") abecedario = string.printable + "áéíóúÁÉÍÚÓàèìòùÀÈÌÒÙäëïöüÄËÏÖÜñÑ´" abecedario2 = [] diff --git a/env_check.py b/env_check.py index 7e7bc53e8cd..ab5f57f041f 100644 --- a/env_check.py +++ b/env_check.py @@ -22,7 +22,7 @@ env_check = ( env_check.strip() ) # Set the variable as itself, but strip the extra text out - print("[{}]".format(env_check)) # Format the Output to be in Square Brackets + print(f"[{env_check}]") # Format the Output to be in Square Brackets newenv = os.getenv( env_check ) # Set the variable newenv to get the settings from the OS what is currently set for the settings out the configfile @@ -30,6 +30,4 @@ if newenv is None: # If it doesn't exist print(env_check, "is not set") # Print it is not set else: # Else if it does exist - print( - "Current Setting for {}={}\n".format(env_check, newenv) - ) # Print out the details + print(f"Current Setting for {env_check}={newenv}\n") # Print out the details diff --git a/equations.py b/equations.py index 1fc4b9159d7..464f1d58b67 100644 --- a/equations.py +++ b/equations.py @@ -25,7 +25,7 @@ b = int(input("What is value of b?")) c = int(input("What is value of c?")) - D = b ** 2 - 4 * a * c + D = b**2 - 4 * a * c if D < 0: print("No real values of x satisfies your equation.") diff --git a/example.txt b/example.txt deleted file mode 100644 index cb511a2b55e..00000000000 --- a/example.txt +++ /dev/null @@ -1 +0,0 @@ -Change from feature-branch diff --git a/fF b/fF.py similarity index 99% rename from fF rename to fF.py index 2edac5d9f5d..97e2ac3b3d2 100644 --- a/fF +++ b/fF.py @@ -9,6 +9,7 @@ import os import sys + def get_folder_size(directory): """Calculate the total size of a directory and its subdirectories.""" total_size = 0 @@ -17,6 +18,7 @@ def get_folder_size(directory): total_size += os.path.getsize(os.path.join(root, file)) return total_size + def format_size(size): """Format the size into human-readable units.""" units = ["Bytes", "KB", "MB", "GB", "TB"] @@ -25,19 +27,21 @@ def format_size(size): return f"{size:.2f} {unit}" size /= 1024 + def main(): if len(sys.argv) < 2: print("Usage: python folder_size.py ") sys.exit(1) directory = sys.argv[1] - + if not os.path.exists(directory): print(f"Error: The directory '{directory}' does not exist.") sys.exit(1) - + folder_size = get_folder_size(directory) print(f"Folder Size: {format_size(folder_size)}") + if __name__ == "__main__": main() diff --git a/facebook id hack.py b/facebook id hack.py index d386662f312..cd80902c042 100644 --- a/facebook id hack.py +++ b/facebook id hack.py @@ -1,9 +1,10 @@ # Author-Kingslayer # Email-kingslayer8509@gmail.com # you need to create a file password.txt which contains all possible passwords +import sys + import requests from bs4 import BeautifulSoup -import sys if sys.version_info[0] != 3: print( @@ -51,7 +52,7 @@ def function(email, passw, i): print("\n---------- Welcome To Facebook BruteForce ----------\n") -file = open("passwords.txt", "r") +file = open("passwords.txt") email = input("Enter Email/Username : ") diff --git a/facebook-autologin-bot.py b/facebook-autologin-bot.py index 261f02721d5..81962eeb1ed 100644 --- a/facebook-autologin-bot.py +++ b/facebook-autologin-bot.py @@ -1,5 +1,6 @@ -import pyttsx3 import time + +import pyttsx3 from selenium import webdriver tts = pyttsx3.init() diff --git a/factorial_perm_comp.py b/factorial_perm_comp.py index f329eac3380..fae25a66a1c 100644 --- a/factorial_perm_comp.py +++ b/factorial_perm_comp.py @@ -39,7 +39,7 @@ def main(): while True: try: n = int(input("\n Enter Value for n ")) - print("Factorial of {} = {}".format(n, factorial(n))) + print(f"Factorial of {n} = {factorial(n)}") break except ValueError: print("Invalid Value") @@ -52,7 +52,7 @@ def main(): try: n = int(input("\n Enter Value for n ")) r = int(input("\n Enter Value for r ")) - print("Permutation of {}P{} = {}".format(n, r, permutation(n, r))) + print(f"Permutation of {n}P{r} = {permutation(n, r)}") break except ValueError: print("Invalid Value") @@ -65,7 +65,7 @@ def main(): n = int(input("\n Enter Value for n ")) r = int(input("\n Enter Value for r ")) - print("Combination of {}C{} = {}".format(n, r, combination(n, r))) + print(f"Combination of {n}C{r} = {combination(n, r)}") break except ValueError: diff --git a/fastapi.py b/fastapi.py index 37aa3aa3ce0..c3909800a17 100644 --- a/fastapi.py +++ b/fastapi.py @@ -1,18 +1,19 @@ -from fastapi import FastAPI from pydantic import BaseModel -from typing import Optional + +from fastapi import FastAPI app = FastAPI() # temp database fakedb = [] + # course model to store courses class Course(BaseModel): id: int name: str price: float - is_early_bird: Optional[bool] = None + is_early_bird: bool | None = None # Home/welcome route diff --git a/fibonacci_SIMPLIFIED b/fibonacci_SIMPLIFIED deleted file mode 100644 index 77f6854050f..00000000000 --- a/fibonacci_SIMPLIFIED +++ /dev/null @@ -1,10 +0,0 @@ - -#printing fibonnaci series till nth element - simplified version for begginers -def print_fibonacci(n): - current_no = 1 - prev_no = 0 - for i in range(n): - print(current_no, end = " ") - prev_no,current_no = current_no, current_no + prev_no - -print_fibonacci(10) diff --git a/fibonacci_SIMPLIFIED.py b/fibonacci_SIMPLIFIED.py new file mode 100644 index 00000000000..ce3d71a6a86 --- /dev/null +++ b/fibonacci_SIMPLIFIED.py @@ -0,0 +1,10 @@ +# printing fibonnaci series till nth element - simplified version for begginers +def print_fibonacci(n): + current_no = 1 + prev_no = 0 + for i in range(n): + print(current_no, end=" ") + prev_no, current_no = current_no, current_no + prev_no + + +print_fibonacci(10) diff --git a/fibonici series.py b/fibonici series.py index 17e24228f94..85483ee8ab7 100644 --- a/fibonici series.py +++ b/fibonici series.py @@ -6,16 +6,16 @@ # check if the number of terms is valid if nterms <= 0: - print("Please enter a positive integer") + print("Please enter a positive integer") elif nterms == 1: - print("Fibonacci sequence upto",nterms,":") - print(n1) + print("Fibonacci sequence upto", nterms, ":") + print(n1) else: - print("Fibonacci sequence:") - while count < nterms: - print(n1) - nth = n1 + n2 - # update values - n1 = n2 - n2 = nth - count += 1 + print("Fibonacci sequence:") + while count < nterms: + print(n1) + nth = n1 + n2 + # update values + n1 = n2 + n2 = nth + count += 1 diff --git a/file_ext_changer.py b/file_ext_changer.py index 4d80261b052..1f27659aa7b 100644 --- a/file_ext_changer.py +++ b/file_ext_changer.py @@ -1,14 +1,15 @@ -'''' Multiple extension changer''' +"""' Multiple extension changer""" + +import hashlib +import random as rand import time from pathlib import Path as p -import random as rand -import hashlib def chxten_(files, xten): chfile = [] for file in files: - ch_file = file.split('.') + ch_file = file.split(".") ch_file = ch_file[0] chfile.append(ch_file) if len(xten) == len(chfile): @@ -22,7 +23,7 @@ def chxten_(files, xten): ch_xten = chfile[i] + xten[i] chxten.append(ch_xten) for i in range(1, (len(chfile) + 1) - len(xten)): - ch_xten = chfile[- + i] + xten[-1] + ch_xten = chfile[-+i] + xten[-1] chxten.append(ch_xten) elif len(xten) == 1: chxten = [] @@ -40,61 +41,64 @@ def chxten_(files, xten): ch_xten = chfile[i] + xten[i] chxten.append(ch_xten) else: - return 'an error occured' + return "an error occured" return chxten # End of function definitions # Beggining of execution of code -#password -password = input('Enter password:') +# password +password = input("Enter password:") password = password.encode() password = hashlib.sha512(password).hexdigest() -if password == 'c99d3d8f321ff63c2f4aaec6f96f8df740efa2dc5f98fccdbbb503627fd69a9084073574ee4df2b888f9fe2ed90e29002c318be476bb62dabf8386a607db06c4': +if ( + password + == "c99d3d8f321ff63c2f4aaec6f96f8df740efa2dc5f98fccdbbb503627fd69a9084073574ee4df2b888f9fe2ed90e29002c318be476bb62dabf8386a607db06c4" +): pass else: - print('wrong password!') + print("wrong password!") time.sleep(0.3) exit(404) -files = input('Enter file names and thier extensions (seperated by commas):') -xten = input('Enter Xtensions to change with (seperated by commas):') +files = input("Enter file names and thier extensions (seperated by commas):") +xten = input("Enter Xtensions to change with (seperated by commas):") -if files == '*': +if files == "*": pw = p.cwd() - files = '' + files = "" for i in pw.iterdir(): if not p.is_dir(i): i = str(i) - if not i.endswith('.py'): + if not i.endswith(".py"): # if not i.endswith('exe'): - if not i.endswith('.log'): - files = files + i + ',' -if files == 'r': + if not i.endswith(".log"): + files = files + i + "," +if files == "r": pw = p.cwd() - files = '' + files = "" filer = [] for i in pw.iterdir(): if p.is_file(i): i = str(i) - if not i.endswith('.py'): - if not i.endswith('.exe'): - if not i.endswith('.log'): + if not i.endswith(".py"): + if not i.endswith(".exe"): + if not i.endswith(".log"): filer.append(i) for i in range(5): - pos = rand.randint(0,len(filer)) - files = files + filer[pos] + ',' + pos = rand.randint(0, len(filer)) + files = files + filer[pos] + "," print(files) -files = files.split(',') -xten = xten.split(',') +files = files.split(",") +xten = xten.split(",") # Validation for file in files: check = p(file).exists() if check == False: - print(f'{file} is not found. Paste this file in the directory of {file}') + print(f"{file} is not found. Paste this file in the directory of {file}") files.remove(file) # Ended validation @@ -102,8 +106,8 @@ def chxten_(files, xten): chxten = chxten_(files, xten) # Error Handlings -if chxten == 'an error occured': - print('Check your inputs correctly') +if chxten == "an error occured": + print("Check your inputs correctly") time.sleep(1) exit(404) else: @@ -111,7 +115,7 @@ def chxten_(files, xten): for i in range(len(files)): f = p(files[i]) f.rename(chxten[i]) - print('All files has been changed') + print("All files has been changed") except PermissionError: pass except FileNotFoundError: @@ -119,7 +123,9 @@ def chxten_(files, xten): for file in files: check = p(file).exists() if check == False: - print(f'{file} is not found. Paste this file in the directory of {file}') + print( + f"{file} is not found. Paste this file in the directory of {file}" + ) files.remove(file) # except Exception: # print('An Error Has Occured in exception') diff --git a/fileinfo.py b/fileinfo.py index bc80dc4bc5a..812eaecb5df 100644 --- a/fileinfo.py +++ b/fileinfo.py @@ -9,7 +9,6 @@ # get file information using os.stat() # tested with Python24 vegsaeat 25sep2006 -from __future__ import print_function import os import stat # index constants for os.stat() @@ -33,7 +32,7 @@ print(e) sys.exit(1) # When open item is a directory (python2) -except IOError: +except OSError: pass # When open item is a directory (python3) except IsADirectoryError: diff --git a/find_cube_root.py b/find_cube_root.py index 667f7fa0f2d..9e0a9c192d4 100644 --- a/find_cube_root.py +++ b/find_cube_root.py @@ -7,9 +7,9 @@ def cubeRoot(): x = int(input("Enter an integer: ")) for ans in range(0, abs(x) + 1): - if ans ** 3 == abs(x): + if ans**3 == abs(x): break - if ans ** 3 != abs(x): + if ans**3 != abs(x): print(x, "is not a perfect cube!") else: if x < 0: diff --git a/find_prime.py b/find_prime.py index d6d5a515bd2..2fd050abeda 100644 --- a/find_prime.py +++ b/find_prime.py @@ -9,21 +9,22 @@ -Sieve of Eratosthenes(source:wikipedia.com) In mathematics, the sieve of Eratosthenes is a simple, ancient algorithm for finding all prime numbers up to any given limit. - It does so by iteratively marking as composite (i.e., not prime) the multiples of each prime, starting with the first prime - number, 2. The multiples of a given prime are generated as a sequence of numbers starting from that prime, with constant - difference between them that is equal to that prime. This is the sieve's key distinction from using trial division to + It does so by iteratively marking as composite (i.e., not prime) the multiples of each prime, starting with the first prime + number, 2. The multiples of a given prime are generated as a sequence of numbers starting from that prime, with constant + difference between them that is equal to that prime. This is the sieve's key distinction from using trial division to sequentially test each candidate number for divisibility by each prime. To find all the prime numbers less than or equal to a given integer n by Eratosthenes' method: - Create a list of consecutive integers from 2 through n: (2, 3, 4, ..., n). - Initially, let p equal 2, the smallest prime number. - - Enumerate the multiples of p by counting to n from 2p in increments of p, and mark them in the list (these will be 2p, + - Enumerate the multiples of p by counting to n from 2p in increments of p, and mark them in the list (these will be 2p, 3p, 4p, ...; the p itself should not be marked). - - Find the first number greater than p in the list that is not marked. If there was no such number, stop. Otherwise, let + - Find the first number greater than p in the list that is not marked. If there was no such number, stop. Otherwise, let p now equal this new number (which is the next prime), and repeat from step 3. - When the algorithm terminates, the numbers remaining not marked in the list are all the primes below n. """ + import sys diff --git a/finding LCM.py b/finding LCM.py index e95feb45b47..dfd1b57e81e 100644 --- a/finding LCM.py +++ b/finding LCM.py @@ -1,21 +1,21 @@ - # Python Program to find the L.C.M. of two input number + def compute_lcm(x, y): + # choose the greater number + if x > y: + greater = x + else: + greater = y - # choose the greater number - if x > y: - greater = x - else: - greater = y + while True: + if (greater % x == 0) and (greater % y == 0): + lcm = greater + break + greater += 1 - while(True): - if((greater % x == 0) and (greater % y == 0)): - lcm = greater - break - greater += 1 + return lcm - return lcm num1 = 54 num2 = 24 diff --git a/flappyBird_pygame/flappy_bird.py b/flappyBird_pygame/flappy_bird.py index 34b3206b7e2..4410bd27723 100644 --- a/flappyBird_pygame/flappy_bird.py +++ b/flappyBird_pygame/flappy_bird.py @@ -1,12 +1,10 @@ #! /usr/bin/env python3 -# -*- coding: utf-8 -*- """ Created on Fri Mar 23 14:17:24 2019 @author: Mehul """ - import math import os from collections import deque @@ -22,7 +20,6 @@ class Bird(pygame.sprite.Sprite): - WIDTH = 32 # bird image width HEIGHT = 32 # bird image height DOWN_SPEED = 0.18 # pix per ms -y @@ -30,7 +27,6 @@ class Bird(pygame.sprite.Sprite): UP_DURATION = 150 # time for which bird go up def __init__(self, x, y, ms_to_up, images): - super(Bird, self).__init__() self.x, self.y = x, y self.ms_to_up = ms_to_up @@ -39,7 +35,6 @@ def __init__(self, x, y, ms_to_up, images): self._mask_wingdown = pygame.mask.from_surface(self._img_wingdown) def update(self, delta_frames=1): - if self.ms_to_up > 0: frac_climb_done = 1 - self.ms_to_up / Bird.UP_DURATION self.y -= ( @@ -74,13 +69,11 @@ def rect(self): class PipePair(pygame.sprite.Sprite): - WIDTH = 80 # width of pipe PIECE_HEIGHT = 32 ADD_INTERVAL = 3000 def __init__(self, pipe_end_img, pipe_body_img): - self.x = float(W_WIDTH - 1) self.score_counted = False @@ -126,7 +119,6 @@ def top_height_px(self): @property def bottom_height_px(self): - return self.bottom_pieces * PipePair.PIECE_HEIGHT @property @@ -140,18 +132,25 @@ def rect(self): return Rect(self.x, 0, PipePair.WIDTH, PipePair.PIECE_HEIGHT) def update(self, delta_frames=1): - self.x -= ANI_SPEED * frames_to_msec(delta_frames) def collides_with(self, bird): - return pygame.sprite.collide_mask(self, bird) def load_images(): - def load_image(img_file_name): + # 获取脚本所在目录 + script_dir = os.path.dirname(os.path.abspath(__file__)) + # 构建图片目录路径 + images_dir = os.path.join(script_dir, "images") - file_name = os.path.join(".", "images", img_file_name) + def load_image(img_file_name): + file_name = os.path.join(images_dir, img_file_name) + # 检查文件是否存在并打印调试信息 + if not os.path.exists(file_name): + print(f"错误: 找不到图片文件 {file_name}") + print(f"脚本所在目录: {script_dir}") + print(f"图片目录应该是: {images_dir}") img = pygame.image.load(file_name) img.convert() return img @@ -168,12 +167,10 @@ def load_image(img_file_name): def frames_to_msec(frames, fps=FPS): - return 1000.0 * frames / fps def msec_to_frames(milliseconds, fps=FPS): - return fps * milliseconds / 1000.0 @@ -185,7 +182,6 @@ def gameover(display, score): def main(): - pygame.init() display_surface = pygame.display.set_mode((W_WIDTH, W_HEIGHT)) @@ -234,7 +230,7 @@ def main(): # check for collisions pipe_collision = any(p.collides_with(bird) for p in pipes) - if pipe_collision or 0 >= bird.y or bird.y >= W_HEIGHT - Bird.HEIGHT: + if pipe_collision or bird.y <= 0 or bird.y >= W_HEIGHT - Bird.HEIGHT: done = True for x in (0, W_WIDTH / 2): diff --git a/floodfill/floodfill.py b/floodfill/floodfill.py index b4c39735f23..c4fc3888efd 100644 --- a/floodfill/floodfill.py +++ b/floodfill/floodfill.py @@ -1,132 +1,126 @@ -import pygame +import sys +from collections import deque -""" -Visualises how a floodfill algorithm runs and work using pygame -Pass two int arguments for the window width and the window height -`python floodfill.py ` -""" +import pygame class FloodFill: - def __init__(self, window_width, window_height): - self.window_width = int(window_width) - self.window_height = int(window_height) + def __init__(self, window_width: int = 800, window_height: int = 600): + """Initialize the FloodFill visualization with specified window dimensions.""" + self.window_width = window_width + self.window_height = window_height pygame.init() - pygame.display.set_caption("Floodfill") - self.display = pygame.display.set_mode((self.window_width, self.window_height)) + pygame.display.set_caption("Floodfill Visualization") + self.display = pygame.display.set_mode((window_width, window_height)) self.surface = pygame.Surface(self.display.get_size()) self.surface.fill((0, 0, 0)) - self.generateClosedPolygons() # for visualisation purposes - - self.queue = [] + self.generate_closed_polygons() + self.queue = deque() # Use deque for O(1) append/pop operations + self.white = self.surface.map_rgb((255, 255, 255)) + self.black = self.surface.map_rgb((0, 0, 0)) - def generateClosedPolygons(self): + def generate_closed_polygons(self) -> None: + """Generate random closed polygons for visualization.""" if self.window_height < 128 or self.window_width < 128: - return # surface too small + return # Surface too small + from math import cos, pi, sin from random import randint, uniform - from math import pi, sin, cos - for n in range(0, randint(0, 5)): + for _ in range(randint(0, 5)): x = randint(50, self.window_width - 50) y = randint(50, self.window_height - 50) - - angle = 0 - angle += uniform(0, 0.7) + angle = uniform(0, 0.7) vertices = [] - for i in range(0, randint(3, 7)): + for _ in range(randint(3, 7)): dist = randint(10, 50) vertices.append( (int(x + cos(angle) * dist), int(y + sin(angle) * dist)) ) angle += uniform(0, pi / 2) - for i in range(0, len(vertices) - 1): + # Draw polygon edges + for i in range(len(vertices) - 1): pygame.draw.line( self.surface, (255, 0, 0), vertices[i], vertices[i + 1] ) - - pygame.draw.line( - self.surface, (255, 0, 0), vertices[len(vertices) - 1], vertices[0] - ) - - def run(self): - looping = True - while looping: - evsforturn = [] - for ev in pygame.event.get(): - if ev.type == pygame.QUIT: - looping = False + pygame.draw.line(self.surface, (255, 0, 0), vertices[-1], vertices[0]) + + def run(self) -> None: + """Main loop for the visualization.""" + clock = pygame.time.Clock() + running = True + + while running: + events = [] + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False else: - evsforturn.append(ev) # TODO: Maybe extend with more events - self.update(evsforturn) + events.append(event) + + self.update(events) self.display.blit(self.surface, (0, 0)) pygame.display.flip() + clock.tick(60) # Limit FPS for performance pygame.quit() - def update(self, events): - for ev in events: - if ev.type == pygame.MOUSEBUTTONDOWN and ev.button == 1: - self.queue.append(ev.pos) + def update(self, events: list) -> None: + """Handle events and update floodfill algorithm.""" + for event in events: + if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: + self.queue.append(event.pos) - if not len(self.queue): + if not self.queue: return - point = self.queue.pop(0) + # Process multiple points per frame for faster filling + for _ in range(min(100, len(self.queue))): + x, y = self.queue.popleft() - pixArr = pygame.PixelArray(self.surface) + # Check bounds and color + if not (0 <= x < self.window_width and 0 <= y < self.window_height): + continue - if pixArr[point[0], point[1]] == self.surface.map_rgb((255, 255, 255)): - return + with pygame.PixelArray(self.surface) as pixels: + if pixels[x, y] != self.black: + continue - pixArr[point[0], point[1]] = (255, 255, 255) - - left = (point[0] - 1, point[1]) - right = (point[0] + 1, point[1]) - top = (point[0], point[1] + 1) - bottom = (point[0], point[1] - 1) - - if ( - self.inBounds(left) - and left not in self.queue - and pixArr[left[0], left[1]] == self.surface.map_rgb((0, 0, 0)) - ): - self.queue.append(left) - if ( - self.inBounds(right) - and right not in self.queue - and pixArr[right[0], right[1]] == self.surface.map_rgb((0, 0, 0)) - ): - self.queue.append(right) - if ( - self.inBounds(top) - and top not in self.queue - and pixArr[top[0], top[1]] == self.surface.map_rgb((0, 0, 0)) - ): - self.queue.append(top) - if ( - self.inBounds(bottom) - and bottom not in self.queue - and pixArr[bottom[0], bottom[1]] == self.surface.map_rgb((0, 0, 0)) - ): - self.queue.append(bottom) - - del pixArr - - def inBounds(self, coord): - if coord[0] < 0 or coord[0] >= self.window_width: - return False - elif coord[1] < 0 or coord[1] >= self.window_height: - return False - return True + pixels[x, y] = (255, 255, 255) + # Check and add neighbors + for dx, dy in [(-1, 0), (1, 0), (0, 1), (0, -1)]: + nx, ny = x + dx, y + dy + if ( + 0 <= nx < self.window_width + and 0 <= ny < self.window_height + and pixels[nx, ny] == self.black + ): + self.queue.append((nx, ny)) -if __name__ == "__main__": - import sys - floodfill = FloodFill(sys.argv[1], sys.argv[2]) +if __name__ == "__main__": + # Set default dimensions + DEFAULT_WIDTH = 800 + DEFAULT_HEIGHT = 600 + + # Parse command-line arguments with defaults + try: + width = int(sys.argv[1]) if len(sys.argv) > 1 else DEFAULT_WIDTH + height = int(sys.argv[2]) if len(sys.argv) > 2 else DEFAULT_HEIGHT + except ValueError: + print("Error: Width and height must be integers.") + sys.exit(1) + + # Validate dimensions + if width <= 0 or height <= 0: + print("Error: Width and height must be positive integers.") + sys.exit(1) + + # Initialize and run visualization + floodfill = FloodFill(width, height) floodfill.run() diff --git a/folder_size.py b/folder_size.py index 7410de8da36..d0ad968e12d 100755 --- a/folder_size.py +++ b/folder_size.py @@ -25,7 +25,7 @@ "Megabytes": float(1) / (1024 * 1024), "Gigabytes": float(1) / (1024 * 1024 * 1024), } -for (path, dirs, files) in os.walk( +for path, dirs, files in os.walk( directory ): # Walk through all the directories. For each iteration, os.walk returns the folders, subfolders and files in the dir. for file in files: # Get all the files diff --git a/four_digit_num_combination.py b/four_digit_num_combination.py index 320544dc451..dce43559fb3 100644 --- a/four_digit_num_combination.py +++ b/four_digit_num_combination.py @@ -1,4 +1,4 @@ -""" small script to learn how to print out all 4-digit num""" +"""small script to learn how to print out all 4-digit num""" # ALL the combinations of 4 digit combo diff --git a/friday.py b/friday.py index 544a1d7516d..4c0b4f3b5af 100644 --- a/friday.py +++ b/friday.py @@ -1,6 +1,7 @@ -import pyttsx3 import os +import pyttsx3 + var = 1 while var > 0: diff --git a/ftp_send_receive.py b/ftp_send_receive.py index 691e0e8e899..6495fe44613 100644 --- a/ftp_send_receive.py +++ b/ftp_send_receive.py @@ -1,11 +1,11 @@ """ - File transfer protocol used to send and receive files using FTP server. - Use credentials to provide access to the FTP client +File transfer protocol used to send and receive files using FTP server. +Use credentials to provide access to the FTP client - Note: Do not use root username & password for security reasons - Create a seperate user and provide access to a home directory of the user - Use login id and password of the user created - cwd here stands for current working directory +Note: Do not use root username & password for security reasons + Create a seperate user and provide access to a home directory of the user + Use login id and password of the user created + cwd here stands for current working directory """ from ftplib import FTP diff --git a/game_of_life/05_mixed_sorting.py b/game_of_life/05_mixed_sorting.py index ef0dced3325..86caf1eaaea 100644 --- a/game_of_life/05_mixed_sorting.py +++ b/game_of_life/05_mixed_sorting.py @@ -15,8 +15,8 @@ [4, 13, 11, 8, -5, 90] Explanation -The even numbers are sorted in increasing order, the odd numbers are sorted in -decreasing number, and the relative positions were +The even numbers are sorted in increasing order, the odd numbers are sorted in +decreasing number, and the relative positions were [even, odd, odd, even, odd, even] and remain the same after sorting. """ diff --git a/game_of_life/game_o_life.py b/game_of_life/game_o_life.py index 7d2ee832dcf..9780dd254d5 100644 --- a/game_of_life/game_o_life.py +++ b/game_of_life/game_o_life.py @@ -1,134 +1,108 @@ -"""Conway's Game Of Life, Author Anurag Kumar(mailto:anuragkumarak95@gmail.com) +""" +Conway's Game of Life +Author: Anurag Kumar (mailto:anuragkumarak95@gmail.com) Requirements: - numpy - - random - - time - matplotlib Python: - - 3.5 + - 3.13.5+ Usage: - - $python3 game_o_life - -Game-Of-Life Rules: - - 1. - Any live cell with fewer than two live neighbours - dies, as if caused by under-population. - 2. - Any live cell with two or three live neighbours lives - on to the next generation. - 3. - Any live cell with more than three live neighbours - dies, as if by over-population. - 4. - Any dead cell with exactly three live neighbours be- - comes a live cell, as if by reproduction. - """ -import random + - $ python game_o_life.py [canvas_size:int=50] + +Rules: +1. Any live cell with fewer than two live neighbours dies. +2. Any live cell with two or three live neighbours survives. +3. Any live cell with more than three live neighbours dies. +4. Any dead cell with exactly three live neighbours becomes alive. +""" + import sys +import matplotlib.pyplot as plt import numpy as np +from matplotlib.animation import FuncAnimation +from matplotlib.colors import ListedColormap -from matplotlib import use as mpluse +# Configuration +DEFAULT_CANVAS_SIZE = 50 +USAGE = "Usage: python game_o_life.py [canvas_size:int]" + + +def main(): + # Parse command-line arguments with default + canvas_size = DEFAULT_CANVAS_SIZE + + if len(sys.argv) > 2: + sys.exit(f"Error: Too many arguments\n{USAGE}") + + if len(sys.argv) == 2: + try: + canvas_size = int(sys.argv[1]) + if canvas_size <= 0: + raise ValueError("Canvas size must be a positive integer") + except ValueError as e: + sys.exit(f"Error: {e}\n{USAGE}") + + # Initialize the game board + board = initialize_board(canvas_size) + + # Set up matplotlib visualization + plt.style.use("dark_background") + fig, ax = plt.subplots(figsize=(10, 10)) + fig.canvas.manager.set_window_title( + f"Conway's Game of Life (Size: {canvas_size}x{canvas_size})" + ) + cmap = ListedColormap(["#111111", "#FFFFFF"]) # Black and white + img = ax.matshow(board, cmap=cmap) + ax.set_axis_off() + + # Define animation update function + def update(frame): + nonlocal board + board = compute_next_generation(board) + img.set_data(board) + return [img] + + # Create animation + ani = FuncAnimation(fig, update, interval=100, blit=True, cache_frame_data=False) -mpluse("TkAgg") -from matplotlib import pyplot as plt -from matplotlib.colors import ListedColormap + try: + plt.tight_layout() + plt.show() + except KeyboardInterrupt: + sys.exit("\nExiting...") -usage_doc = "Usage of script: script_nama " - -choice = [0] * 100 + [1] * 10 -random.shuffle(choice) - - -def create_canvas(size): - canvas = [[False for i in range(size)] for j in range(size)] - return canvas - - -def seed(canvas): - for i, row in enumerate(canvas): - for j, _ in enumerate(row): - canvas[i][j] = bool(random.getrandbits(1)) - - -def run(canvas): - """This function runs the rules of game through all points, and changes their status accordingly.(in the same canvas) - @Args: - -- - canvas : canvas of population to run the rules on. - - @returns: - -- - None - """ - canvas = np.array(canvas) - next_gen_canvas = np.array(create_canvas(canvas.shape[0])) - for r, row in enumerate(canvas): - for c, pt in enumerate(row): - # print(r-1,r+2,c-1,c+2) - next_gen_canvas[r][c] = __judge_point( - pt, canvas[r - 1 : r + 2, c - 1 : c + 2] - ) - - canvas = next_gen_canvas - del next_gen_canvas # cleaning memory as we move on. - return canvas.tolist() - - -def __judge_point(pt, neighbours): - dead = 0 - alive = 0 - # finding dead or alive neighbours count. - for i in neighbours: - for status in i: - if status: - alive += 1 - else: - dead += 1 - - # handling duplicate entry for focus pt. - if pt: - alive -= 1 - else: - dead -= 1 - - # running the rules of game here. - state = pt - if pt: - if alive < 2: - state = False - elif alive == 2 or alive == 3: - state = True - elif alive > 3: - state = False - else: - if alive == 3: - state = True - - return state + +def initialize_board(size: int) -> np.ndarray: + """Initialize the game board with random alive/dead cells.""" + return np.random.choice([0, 1], size=(size, size), p=[0.7, 0.3]) + + +def compute_next_generation(board: np.ndarray) -> np.ndarray: + """Compute the next generation using vectorized operations.""" + # Count neighbors using convolution + neighbors = ( + np.roll(board, 1, 0) + + np.roll(board, -1, 0) + + np.roll(board, 1, 1) + + np.roll(board, -1, 1) + + np.roll(board, (1, 1), (0, 1)) + + np.roll(board, (1, -1), (0, 1)) + + np.roll(board, (-1, 1), (0, 1)) + + np.roll(board, (-1, -1), (0, 1)) + ) + + # Apply Conway's rules + return np.where( + (board == 1) & ((neighbors == 2) | (neighbors == 3)) + | (board == 0) & (neighbors == 3), + 1, + 0, + ) if __name__ == "__main__": - if len(sys.argv) != 2: - raise Exception(usage_doc) - - canvas_size = int(sys.argv[1]) - # main working structure of this module. - c = create_canvas(canvas_size) - seed(c) - fig, ax = plt.subplots() - fig.show() - cmap = ListedColormap(["w", "k"]) - try: - while True: - c = run(c) - ax.matshow(c, cmap=cmap) - fig.canvas.draw() - ax.cla() - except KeyboardInterrupt: - # do nothing. - pass + main() diff --git a/gcd.py b/gcd.py index b496dca1d20..fc3571af877 100644 --- a/gcd.py +++ b/gcd.py @@ -2,14 +2,15 @@ although there is function to find gcd in python but this is the code which takes two inputs and prints gcd of the two. """ + a = int(input("Enter number 1 (a): ")) b = int(input("Enter number 2 (b): ")) i = 1 -gcd=-1 +gcd = -1 while i <= a and i <= b: if a % i == 0 and b % i == 0: gcd = i i = i + 1 -print("\nGCD of {0} and {1} = {2}".format(a, b, gcd)) +print(f"\nGCD of {a} and {b} = {gcd}") diff --git a/generate_permutations.py b/generate_permutations.py index 4623e08d2c3..26d473d1d32 100644 --- a/generate_permutations.py +++ b/generate_permutations.py @@ -1,16 +1,17 @@ -def generate(A,k): - if k ==1: +def generate(A, k): + if k == 1: print(A) return else: for i in range(k): - generate(A,k-1) - if(i80): + sentence = sentence + line.text + ratio = fuzz.token_set_ratio(sentence, checkString) + if ratio > 80: singleLink.append(k) singleRatio.append(ratio) - if(len(singleLink)>=4): - singleLink=np.array(singleLink) - singleRatio=np.array(singleRatio) - inds=singleRatio.argsort() - sortedLink=singleLink[inds] - sortedFinalList=list(sortedLink[::-1]) - sortedFinalList=sortedFinalList[:4] - FinalResult.append(singleWrite+sortedFinalList) - elif(len(singleLink)<4) and len(singleLink)>0: + if len(singleLink) >= 4: singleLink = np.array(singleLink) singleRatio = np.array(singleRatio) inds = singleRatio.argsort() sortedLink = singleLink[inds] sortedFinalList = list(sortedLink[::-1]) - sortedFinalList=sortedFinalList+(4-len(sortedFinalList))*[[" "]] + sortedFinalList = sortedFinalList[:4] + FinalResult.append(singleWrite + sortedFinalList) + elif (len(singleLink) < 4) and len(singleLink) > 0: + singleLink = np.array(singleLink) + singleRatio = np.array(singleRatio) + inds = singleRatio.argsort() + sortedLink = singleLink[inds] + sortedFinalList = list(sortedLink[::-1]) + sortedFinalList = sortedFinalList + (4 - len(sortedFinalList)) * [[" "]] FinalResult.append(singleWrite + sortedFinalList) else: - sortedFinalList=[[" "]]*4 - FinalResult.append(singleWrite+sortedFinalList) + sortedFinalList = [[" "]] * 4 + FinalResult.append(singleWrite + sortedFinalList) SearchResults() -FinalResult=np.array(FinalResult) -FinalResult=pd.DataFrame(FinalResult) -FinalResult.columns=["Input","Link A","Link B","Link C","Link D"] -FinalResult.replace(" ",np.nan) -FinalResult.to_csv("Susma.csv",index=False) +FinalResult = np.array(FinalResult) +FinalResult = pd.DataFrame(FinalResult) +FinalResult.columns = ["Input", "Link A", "Link B", "Link C", "Link D"] +FinalResult.replace(" ", np.nan) +FinalResult.to_csv("Susma.csv", index=False) print(FinalResult) diff --git a/greaterno.py b/greaterno.py index a4fb15c1231..d636d48e307 100644 --- a/greaterno.py +++ b/greaterno.py @@ -7,15 +7,15 @@ num3 = 12 # uncomment following lines to take three numbers from user -#num1 = float(input("Enter first number: ")) -#num2 = float(input("Enter second number: ")) -#num3 = float(input("Enter third number: ")) +# num1 = float(input("Enter first number: ")) +# num2 = float(input("Enter second number: ")) +# num3 = float(input("Enter third number: ")) if (num1 >= num2) and (num1 >= num3): - largest = num1 + largest = num1 elif (num2 >= num1) and (num2 >= num3): - largest = num2 + largest = num2 else: - largest = num3 + largest = num3 print("The largest number is", largest) diff --git a/greattwono.py b/greattwono.py index 60cf8dcee2d..6110c0d67de 100644 --- a/greattwono.py +++ b/greattwono.py @@ -1,7 +1,7 @@ # Python Program to find the largest of two numbers using an arithmetic operator a = int(input("Enter the first number: ")) b = int(input("Enter the second number: ")) -if(a - b > 0): - print(a, "is greater") +if a - b > 0: + print(a, "is greater") else: - print(b, "is greater") + print(b, "is greater") diff --git a/gstin_scraper.py b/gstin_scraper.py index 4f55ca6de30..be5804e25c0 100644 --- a/gstin_scraper.py +++ b/gstin_scraper.py @@ -1,7 +1,8 @@ -from bs4 import BeautifulSoup -import requests import time +import requests +from bs4 import BeautifulSoup + # Script Name : gstin_scraper.py # Author : Purshotam # Created : Sep 6, 2021 7:59 PM @@ -17,28 +18,39 @@ """ -# Using a demo list in case of testing the script. +# Using a demo list in case of testing the script. # This list will be used in case user skips "company input" dialogue by pressing enter. -demo_companies = ["Bank of Baroda", "Trident Limited", "Reliance Limited", "The Yummy Treat", "Yes Bank", "Mumbai Mineral Trading Corporation"] +demo_companies = [ + "Bank of Baroda", + "Trident Limited", + "Reliance Limited", + "The Yummy Treat", + "Yes Bank", + "Mumbai Mineral Trading Corporation", +] + def get_company_list(): company_list = [] - + while True: company = input("Enter a company name (or press Enter to finish): ") if not company: break company_list.append(company) - + return company_list + def fetch_gstins(company_name, csrf_token): - third_party_gstin_site = "https://www.knowyourgst.com/gst-number-search/by-name-pan/" - payload = {'gstnum': company_name, 'csrfmiddlewaretoken': csrf_token} + third_party_gstin_site = ( + "https://www.knowyourgst.com/gst-number-search/by-name-pan/" + ) + payload = {"gstnum": company_name, "csrfmiddlewaretoken": csrf_token} # Getting the HTML content and extracting the GSTIN content using BeautifulSoup. html_content = requests.post(third_party_gstin_site, data=payload) - soup = BeautifulSoup(html_content.text, 'html.parser') + soup = BeautifulSoup(html_content.text, "html.parser") site_results = soup.find_all(id="searchresult") # Extracting GSTIN specific values from child elements. @@ -46,23 +58,28 @@ def fetch_gstins(company_name, csrf_token): return gstins + def main(): temp = get_company_list() companies = temp if temp else demo_companies all_gstin_data = "" - third_party_gstin_site = "https://www.knowyourgst.com/gst-number-search/by-name-pan/" + third_party_gstin_site = ( + "https://www.knowyourgst.com/gst-number-search/by-name-pan/" + ) # Getting the CSRF value for further RESTful calls. page_with_csrf = requests.get(third_party_gstin_site) - soup = BeautifulSoup(page_with_csrf.text, 'html.parser') - csrf_token = soup.find('input', {"name": "csrfmiddlewaretoken"})['value'] + soup = BeautifulSoup(page_with_csrf.text, "html.parser") + csrf_token = soup.find("input", {"name": "csrfmiddlewaretoken"})["value"] for company in companies: gstins = fetch_gstins(company, csrf_token) # Only include GSTINs for Bengaluru and Mumbai-based companies - comma_separated_gstins = ', '.join([g for g in gstins if g.startswith(('27', '29'))]) + comma_separated_gstins = ", ".join( + [g for g in gstins if g.startswith(("27", "29"))] + ) all_gstin_data += f"{company} = {comma_separated_gstins}\n\n" @@ -72,5 +89,6 @@ def main(): # Printing the data print(all_gstin_data) + if __name__ == "__main__": main() diff --git a/gui_calculator.py b/gui_calculator.py index 435b38972d1..e0fa630e427 100644 --- a/gui_calculator.py +++ b/gui_calculator.py @@ -6,6 +6,7 @@ w.title("Calculatorax") w.configure(bg="#03befc") + # Functions(Keypad) def calc1(): b = txt1.get() diff --git a/happy_num.py b/happy_num.py index 1ea217f6059..aec5bbd208d 100644 --- a/happy_num.py +++ b/happy_num.py @@ -1,45 +1,43 @@ -#Way2 1: - -#isHappyNumber() will determine whether a number is happy or not -def isHappyNumber(num): - rem = sum = 0 - - #Calculates the sum of squares of digits - while(num > 0): - rem = num%10 - sum = sum + (rem*rem) - num = num//10 - return sum - -num = 82 -result = num - -while(result != 1 and result != 4): - result = isHappyNumber(result) - -#Happy number always ends with 1 -if(result == 1): - print(str(num) + " is a happy number after apply way 1") -#Unhappy number ends in a cycle of repeating numbers which contain 4 -elif(result == 4): - print(str(num) + " is not a happy number after apply way 1") - - - - - -#way 2: - -#Another way to do this and code is also less -n=num -setData=set() #set datastructure for checking a number is repeated or not. +# Way2 1: + +# isHappyNumber() will determine whether a number is happy or not +def isHappyNumber(num): + rem = sum = 0 + + # Calculates the sum of squares of digits + while num > 0: + rem = num % 10 + sum = sum + (rem * rem) + num = num // 10 + return sum + + +num = 82 +result = num + +while result != 1 and result != 4: + result = isHappyNumber(result) + +# Happy number always ends with 1 +if result == 1: + print(str(num) + " is a happy number after apply way 1") +# Unhappy number ends in a cycle of repeating numbers which contain 4 +elif result == 4: + print(str(num) + " is not a happy number after apply way 1") + + +# way 2: + +# Another way to do this and code is also less +n = num +setData = set() # set datastructure for checking a number is repeated or not. while 1: - if n==1: - print("{} is a happy number after apply way 2".format(num)) - break - if n in setData: - print("{} is Not a happy number after apply way 2".format(num)) - break - else: - setData.add(n) #adding into set if not inside set - n=int(''.join(str(sum([int(i)**2 for i in str(n)])))) #Pythonic way + if n == 1: + print(f"{num} is a happy number after apply way 2") + break + if n in setData: + print(f"{num} is Not a happy number after apply way 2") + break + else: + setData.add(n) # adding into set if not inside set + n = int("".join(str(sum([int(i) ** 2 for i in str(n)])))) # Pythonic way diff --git a/how to add three numbers and find type in python.py b/how to add three numbers and find type in python.py index bc8ba8cd6d4..dbe4e228d3e 100644 --- a/how to add three numbers and find type in python.py +++ b/how to add three numbers and find type in python.py @@ -1,8 +1,8 @@ -#python program for adding three no. -x=45 -y=75 -z=25 -t=x+y+z +# python program for adding three no. +x = 45 +y = 75 +z = 25 +t = x + y + z print(t) -#type of output +# type of output print(type(t)) diff --git a/how to display the fibonacci sequence up to n-.py b/how to display the fibonacci sequence up to n-.py index 9f6b1b3d7ce..d6a70a574cd 100644 --- a/how to display the fibonacci sequence up to n-.py +++ b/how to display the fibonacci sequence up to n-.py @@ -8,16 +8,16 @@ # check if the number of terms is valid if nterms <= 0: - print("Please enter a positive integer") + print("Please enter a positive integer") elif nterms == 1: - print("Fibonacci sequence upto",nterms,":") - print(n1) + print("Fibonacci sequence upto", nterms, ":") + print(n1) else: - print("Fibonacci sequence:") - while count < nterms: - print(n1) - nth = n1 + n2 - # update values - n1 = n2 - n2 = nth - count += 1 + print("Fibonacci sequence:") + while count < nterms: + print(n1) + nth = n1 + n2 + # update values + n1 = n2 + n2 = nth + count += 1 diff --git a/image2pdf/image2pdf.py b/image2pdf/image2pdf.py index 0e1aa049aab..e8a96d16c08 100644 --- a/image2pdf/image2pdf.py +++ b/image2pdf/image2pdf.py @@ -1,18 +1,18 @@ -from PIL import Image import os +from PIL import Image + class image2pdf: def __init__(self): self.validFormats = (".jpg", ".jpeg", ".png", ".JPG", ".PNG") self.pictures = [] - - self.directory = "" - self.isMergePDF = True + self.directory = "" + self.isMergePDF = True def getUserDir(self): - """ Allow user to choose image directory """ + """Allow user to choose image directory""" msg = "\n1. Current directory\n2. Custom directory\nEnter a number: " user_option = int(input(msg)) @@ -21,8 +21,10 @@ def getUserDir(self): while user_option <= 0 or user_option >= 3: user_option = int(input(f"\n*Invalid input*\n{msg}")) - self.directory = os.getcwd() if user_option == 1 else input("\nEnter custom directory: ") - + self.directory = ( + os.getcwd() if user_option == 1 else input("\nEnter custom directory: ") + ) + def filter(self, item): return item.endswith(self.validFormats) @@ -35,84 +37,94 @@ def getPictures(self): if not pictures: print(f" [Error] there are no pictures in the directory: {self.directory} ") return False - + print("Found picture(s) :") return pictures def selectPictures(self, pictures): - """ Allow user to manually pick each picture or merge all """ + """Allow user to manually pick each picture or merge all""" listedPictures = {} for index, pic in enumerate(pictures): - listedPictures[index+1] = pic - print(f"{index+1}: {pic}") - - userInput = input("\n Enter the number(s) - (comma seperated/no spaces) or (A or a) to merge All \nChoice: ").strip().lower() - + listedPictures[index + 1] = pic + print(f"{index + 1}: {pic}") + + userInput = ( + input( + "\n Enter the number(s) - (comma seperated/no spaces) or (A or a) to merge All \nChoice: " + ) + .strip() + .lower() + ) + if userInput != "a": # Convert user input (number) into corresponding (image title) pictures = ( - listedPictures.get(int(number)) for number in userInput.split(',') + listedPictures.get(int(number)) for number in userInput.split(",") ) self.isMergePDF = False return pictures - def convertPictures(self): """ - Convert pictures according the following: - * If pictures = 0 -> Skip - * If pictures = 1 -> use all - * Else -> allow user to pick pictures + Convert pictures according the following: + * If pictures = 0 -> Skip + * If pictures = 1 -> use all + * Else -> allow user to pick pictures - Then determine to merge all or one pdf + Then determine to merge all or one pdf """ pictures = self.getPictures() totalPictures = len(pictures) if pictures else 0 - + if totalPictures == 0: return - + elif totalPictures >= 2: pictures = self.selectPictures(pictures) - + if self.isMergePDF: - # All pics in one pdf. + # All pics in one pdf. for picture in pictures: - self.pictures.append(Image.open(f"{self.directory}\\{picture}").convert("RGB")) + self.pictures.append( + Image.open(f"{self.directory}\\{picture}").convert("RGB") + ) self.save() else: - # Each pic in seperate pdf. + # Each pic in seperate pdf. for picture in pictures: - self.save(Image.open(f"{self.directory}\\{picture}").convert("RGB"), picture, False) + self.save( + Image.open(f"{self.directory}\\{picture}").convert("RGB"), + picture, + False, + ) # Reset to default value for next run self.isMergePDF = True self.pictures = [] - print(f"\n{'#'*30}") + print(f"\n{'#' * 30}") print(" Done! ") - print(f"{'#'*30}\n") + print(f"{'#' * 30}\n") def save(self, image=None, title="All-PDFs", isMergeAll=True): # Save all to one pdf or each in seperate file if isMergeAll: self.pictures[0].save( - f"{self.directory}\\{title}.pdf", - save_all=True, - append_images=self.pictures[1:] + f"{self.directory}\\{title}.pdf", + save_all=True, + append_images=self.pictures[1:], ) - + else: image.save(f"{self.directory}\\{title}.pdf") if __name__ == "__main__": - # Get user directory only once process = image2pdf() process.getUserDir() @@ -120,7 +132,9 @@ def save(self, image=None, title="All-PDFs", isMergeAll=True): # Allow user to rerun any process while True: - user = input("Press (R or r) to Run again\nPress (C or c) to change directory\nPress (Any Key) To Exit\nchoice:").lower() + user = input( + "Press (R or r) to Run again\nPress (C or c) to change directory\nPress (Any Key) To Exit\nchoice:" + ).lower() match user: case "r": process.convertPictures() @@ -129,5 +143,3 @@ def save(self, image=None, title="All-PDFs", isMergeAll=True): process.convertPictures() case _: break - - diff --git a/image2pdf/requirements.txt b/image2pdf/requirements.txt deleted file mode 100644 index 3868fb16b89..00000000000 --- a/image2pdf/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -pillow diff --git a/index.py b/index.py index b89d747b62d..70cc71d708c 100644 --- a/index.py +++ b/index.py @@ -1,12 +1,10 @@ num = 11 -#Negative numbers, 0 and 1 are not primes +# Negative numbers, 0 and 1 are not primes if num > 1: - # Iterate from 2 to n // 2 - for i in range(2, (num//2)+1): - + for i in range(2, (num // 2) + 1): # If num is divisible by any number between - #2 and n / 2, it is not prime + # 2 and n / 2, it is not prime if (num % i) == 0: print(num, "is not a prime number") break diff --git a/inheritance_YahV1729.py b/inheritance_YahV1729.py index 3f55dfab1b3..3656ff1c729 100644 --- a/inheritance_YahV1729.py +++ b/inheritance_YahV1729.py @@ -1,35 +1,33 @@ +# A Python program to demonstrate inheritance -# A Python program to demonstrate inheritance +# Base or Super class. Note object in bracket. +# (Generally, object is made ancestor of all classes) +# In Python 3.x "class Person" is +# equivalent to "class Person(object)" +class Person: + # Constructor + def __init__(self, name): + self.name = name -# Base or Super class. Note object in bracket. -# (Generally, object is made ancestor of all classes) -# In Python 3.x "class Person" is -# equivalent to "class Person(object)" -class Person(object): - - # Constructor - def __init__(self, name): - self.name = name + # To get name + def getName(self): + return self.name - # To get name - def getName(self): - return self.name + # To check if this person is employee + def isEmployee(self): + return False - # To check if this person is employee - def isEmployee(self): - return False +# Inherited or Sub class (Note Person in bracket) +class Employee(Person): + # Here we return true + def isEmployee(self): + return True -# Inherited or Sub class (Note Person in bracket) -class Employee(Person): - # Here we return true - def isEmployee(self): - return True +# Driver code +emp = Person("Geek1") # An Object of Person +print(emp.getName(), emp.isEmployee()) -# Driver code -emp = Person("Geek1") # An Object of Person -print(emp.getName(), emp.isEmployee()) - -emp = Employee("Geek2") # An Object of Employee -print(emp.getName(), emp.isEmployee()) +emp = Employee("Geek2") # An Object of Employee +print(emp.getName(), emp.isEmployee()) diff --git a/insta_image_saving/instagram_image_scrapping.ipynb b/insta_image_saving/instagram_image_scrapping.ipynb index 0d5d2e5ad35..5fb81ae8f59 100644 --- a/insta_image_saving/instagram_image_scrapping.ipynb +++ b/insta_image_saving/instagram_image_scrapping.ipynb @@ -4,15 +4,28 @@ "cell_type": "code", "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'scrapy'", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mModuleNotFoundError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[1]\u001b[39m\u001b[32m, line 4\u001b[39m\n\u001b[32m 2\u001b[39m \u001b[38;5;28;01mimport\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mpandas\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mas\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mpd\u001b[39;00m\n\u001b[32m 3\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mselenium\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m webdriver\n\u001b[32m----> \u001b[39m\u001b[32m4\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mscrapy\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mselector\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m Selector\n\u001b[32m 5\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mio\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m BytesIO\n\u001b[32m 6\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mPIL\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m Image\n", + "\u001b[31mModuleNotFoundError\u001b[39m: No module named 'scrapy'" + ] + } + ], "source": [ + "from io import BytesIO\n", "from time import sleep\n", + "\n", "import pandas as pd\n", - "from selenium import webdriver\n", - "from scrapy.selector import Selector\n", - "from io import BytesIO\n", + "import requests\n", "from PIL import Image\n", - "import requests" + "from scrapy.selector import Selector\n", + "from selenium import webdriver" ] }, { @@ -21,10 +34,18 @@ "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "1951\n" + "ename": "AttributeError", + "evalue": "'str' object has no attribute 'capabilities'", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mAttributeError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[2]\u001b[39m\u001b[32m, line 7\u001b[39m\n\u001b[32m 5\u001b[39m instaccountlink = \u001b[33m\"\u001b[39m\u001b[33mhttps://instagram.com/audi\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 6\u001b[39m instaaccountname = \u001b[33m\"\u001b[39m\u001b[33mAudi\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m7\u001b[39m driver = \u001b[43mwebdriver\u001b[49m\u001b[43m.\u001b[49m\u001b[43mChrome\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mdriver/driver\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 8\u001b[39m driver.get(instaccountlink)\n\u001b[32m 9\u001b[39m unique_urls = []\n", + "\u001b[36mFile \u001b[39m\u001b[32mc:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\site-packages\\selenium\\webdriver\\chrome\\webdriver.py:47\u001b[39m, in \u001b[36mWebDriver.__init__\u001b[39m\u001b[34m(self, options, service, keep_alive)\u001b[39m\n\u001b[32m 44\u001b[39m service = service \u001b[38;5;28;01mif\u001b[39;00m service \u001b[38;5;28;01melse\u001b[39;00m Service()\n\u001b[32m 45\u001b[39m options = options \u001b[38;5;28;01mif\u001b[39;00m options \u001b[38;5;28;01melse\u001b[39;00m Options()\n\u001b[32m---> \u001b[39m\u001b[32m47\u001b[39m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__init__\u001b[39;49m\u001b[43m(\u001b[49m\n\u001b[32m 48\u001b[39m \u001b[43m \u001b[49m\u001b[43mbrowser_name\u001b[49m\u001b[43m=\u001b[49m\u001b[43mDesiredCapabilities\u001b[49m\u001b[43m.\u001b[49m\u001b[43mCHROME\u001b[49m\u001b[43m[\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mbrowserName\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 49\u001b[39m \u001b[43m \u001b[49m\u001b[43mvendor_prefix\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mgoog\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 50\u001b[39m \u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m=\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 51\u001b[39m \u001b[43m \u001b[49m\u001b[43mservice\u001b[49m\u001b[43m=\u001b[49m\u001b[43mservice\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 52\u001b[39m \u001b[43m \u001b[49m\u001b[43mkeep_alive\u001b[49m\u001b[43m=\u001b[49m\u001b[43mkeep_alive\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 53\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32mc:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\site-packages\\selenium\\webdriver\\chromium\\webdriver.py:53\u001b[39m, in \u001b[36mChromiumDriver.__init__\u001b[39m\u001b[34m(self, browser_name, vendor_prefix, options, service, keep_alive)\u001b[39m\n\u001b[32m 50\u001b[39m \u001b[38;5;28mself\u001b[39m.service = service\n\u001b[32m 52\u001b[39m finder = DriverFinder(\u001b[38;5;28mself\u001b[39m.service, options)\n\u001b[32m---> \u001b[39m\u001b[32m53\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[43mfinder\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget_browser_path\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m:\n\u001b[32m 54\u001b[39m options.binary_location = finder.get_browser_path()\n\u001b[32m 55\u001b[39m options.browser_version = \u001b[38;5;28;01mNone\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32mc:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\site-packages\\selenium\\webdriver\\common\\driver_finder.py:47\u001b[39m, in \u001b[36mDriverFinder.get_browser_path\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 46\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mget_browser_path\u001b[39m(\u001b[38;5;28mself\u001b[39m) -> \u001b[38;5;28mstr\u001b[39m:\n\u001b[32m---> \u001b[39m\u001b[32m47\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_binary_paths\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m[\u001b[33m\"\u001b[39m\u001b[33mbrowser_path\u001b[39m\u001b[33m\"\u001b[39m]\n", + "\u001b[36mFile \u001b[39m\u001b[32mc:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\site-packages\\selenium\\webdriver\\common\\driver_finder.py:56\u001b[39m, in \u001b[36mDriverFinder._binary_paths\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 53\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._paths[\u001b[33m\"\u001b[39m\u001b[33mdriver_path\u001b[39m\u001b[33m\"\u001b[39m]:\n\u001b[32m 54\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m._paths\n\u001b[32m---> \u001b[39m\u001b[32m56\u001b[39m browser = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_options\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcapabilities\u001b[49m[\u001b[33m\"\u001b[39m\u001b[33mbrowserName\u001b[39m\u001b[33m\"\u001b[39m]\n\u001b[32m 57\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 58\u001b[39m path = \u001b[38;5;28mself\u001b[39m._service.path\n", + "\u001b[31mAttributeError\u001b[39m: 'str' object has no attribute 'capabilities'" ] } ], @@ -38,15 +59,15 @@ "driver = webdriver.Chrome(\"driver/driver\")\n", "driver.get(instaccountlink)\n", "unique_urls = []\n", - "while i<300:\n", - " i = i +1\n", + "while i < 300:\n", + " i = i + 1\n", " sel = Selector(text=driver.page_source)\n", - " \n", + "\n", " url = sel.xpath('//div[@class=\"v1Nh3 kIKUG _bz0w\"]/a/@href').extract()\n", " for u in url:\n", " if u not in unique_urls:\n", " unique_urls.append(u)\n", - " \n", + "\n", " driver.execute_script(\"window.scrollTo(0, document.body.scrollHeight);\")\n", " sel = Selector(text=driver.page_source)\n", " url = sel.xpath('//div[@class=\"v1Nh3 kIKUG _bz0w\"]/a/@href').extract()\n", @@ -54,7 +75,7 @@ " for u in url:\n", " if u not in unique_urls:\n", " unique_urls.append(u)\n", - " \n", + "\n", "driver.quit()\n", "print(len(unique_urls))" ] @@ -65,16 +86,20 @@ "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "file saved successfully\n" + "ename": "NameError", + "evalue": "name 'unique_urls' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mNameError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[3]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[32m 1\u001b[39m file = \u001b[38;5;28mopen\u001b[39m(\u001b[33m\"\u001b[39m\u001b[33moutput/audi_instagram_11_07_2019.csv\u001b[39m\u001b[33m\"\u001b[39m,\u001b[33m\"\u001b[39m\u001b[33ma\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m u \u001b[38;5;129;01min\u001b[39;00m \u001b[43munique_urls\u001b[49m :\n\u001b[32m 3\u001b[39m file.write(u)\n\u001b[32m 4\u001b[39m file.write(\u001b[33m\"\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[33m\"\u001b[39m)\n", + "\u001b[31mNameError\u001b[39m: name 'unique_urls' is not defined" ] } ], "source": [ - "file = open(\"output/audi_instagram_11_07_2019.csv\",\"a\")\n", - "for u in unique_urls :\n", + "file = open(\"output/audi_instagram_11_07_2019.csv\", \"a\")\n", + "for u in unique_urls:\n", " file.write(u)\n", " file.write(\"\\n\")\n", "file.close()\n", @@ -85,51 +110,68 @@ "cell_type": "code", "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'str' object has no attribute 'capabilities'", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mAttributeError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[4]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;66;03m# saving the images to specified directory\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m driver = \u001b[43mwebdriver\u001b[49m\u001b[43m.\u001b[49m\u001b[43mChrome\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mdriver/driver\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 4\u001b[39m image_urls = []\n\u001b[32m 5\u001b[39m count = \u001b[32m0\u001b[39m\n", + "\u001b[36mFile \u001b[39m\u001b[32mc:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\site-packages\\selenium\\webdriver\\chrome\\webdriver.py:47\u001b[39m, in \u001b[36mWebDriver.__init__\u001b[39m\u001b[34m(self, options, service, keep_alive)\u001b[39m\n\u001b[32m 44\u001b[39m service = service \u001b[38;5;28;01mif\u001b[39;00m service \u001b[38;5;28;01melse\u001b[39;00m Service()\n\u001b[32m 45\u001b[39m options = options \u001b[38;5;28;01mif\u001b[39;00m options \u001b[38;5;28;01melse\u001b[39;00m Options()\n\u001b[32m---> \u001b[39m\u001b[32m47\u001b[39m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__init__\u001b[39;49m\u001b[43m(\u001b[49m\n\u001b[32m 48\u001b[39m \u001b[43m \u001b[49m\u001b[43mbrowser_name\u001b[49m\u001b[43m=\u001b[49m\u001b[43mDesiredCapabilities\u001b[49m\u001b[43m.\u001b[49m\u001b[43mCHROME\u001b[49m\u001b[43m[\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mbrowserName\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 49\u001b[39m \u001b[43m \u001b[49m\u001b[43mvendor_prefix\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mgoog\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 50\u001b[39m \u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m=\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 51\u001b[39m \u001b[43m \u001b[49m\u001b[43mservice\u001b[49m\u001b[43m=\u001b[49m\u001b[43mservice\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 52\u001b[39m \u001b[43m \u001b[49m\u001b[43mkeep_alive\u001b[49m\u001b[43m=\u001b[49m\u001b[43mkeep_alive\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 53\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32mc:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\site-packages\\selenium\\webdriver\\chromium\\webdriver.py:53\u001b[39m, in \u001b[36mChromiumDriver.__init__\u001b[39m\u001b[34m(self, browser_name, vendor_prefix, options, service, keep_alive)\u001b[39m\n\u001b[32m 50\u001b[39m \u001b[38;5;28mself\u001b[39m.service = service\n\u001b[32m 52\u001b[39m finder = DriverFinder(\u001b[38;5;28mself\u001b[39m.service, options)\n\u001b[32m---> \u001b[39m\u001b[32m53\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[43mfinder\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget_browser_path\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m:\n\u001b[32m 54\u001b[39m options.binary_location = finder.get_browser_path()\n\u001b[32m 55\u001b[39m options.browser_version = \u001b[38;5;28;01mNone\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32mc:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\site-packages\\selenium\\webdriver\\common\\driver_finder.py:47\u001b[39m, in \u001b[36mDriverFinder.get_browser_path\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 46\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mget_browser_path\u001b[39m(\u001b[38;5;28mself\u001b[39m) -> \u001b[38;5;28mstr\u001b[39m:\n\u001b[32m---> \u001b[39m\u001b[32m47\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_binary_paths\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m[\u001b[33m\"\u001b[39m\u001b[33mbrowser_path\u001b[39m\u001b[33m\"\u001b[39m]\n", + "\u001b[36mFile \u001b[39m\u001b[32mc:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\site-packages\\selenium\\webdriver\\common\\driver_finder.py:56\u001b[39m, in \u001b[36mDriverFinder._binary_paths\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 53\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._paths[\u001b[33m\"\u001b[39m\u001b[33mdriver_path\u001b[39m\u001b[33m\"\u001b[39m]:\n\u001b[32m 54\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m._paths\n\u001b[32m---> \u001b[39m\u001b[32m56\u001b[39m browser = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_options\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcapabilities\u001b[49m[\u001b[33m\"\u001b[39m\u001b[33mbrowserName\u001b[39m\u001b[33m\"\u001b[39m]\n\u001b[32m 57\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 58\u001b[39m path = \u001b[38;5;28mself\u001b[39m._service.path\n", + "\u001b[31mAttributeError\u001b[39m: 'str' object has no attribute 'capabilities'" + ] + } + ], "source": [ "# saving the images to specified directory\n", - "driver = webdriver.Chrome('driver/driver')\n", + "driver = webdriver.Chrome(\"driver/driver\")\n", "\n", "image_urls = []\n", "count = 0\n", - "max_no_of_iteration=250\n", + "max_no_of_iteration = 250\n", "for u in unique_urls:\n", " try:\n", - " driver.get('http://instagram.com'+u)\n", + " driver.get(\"http://instagram.com\" + u)\n", " sel = Selector(text=driver.page_source)\n", "\n", - " src= sel.xpath('//div/img/@src').extract()[0]\n", - "# print(src)\n", + " src = sel.xpath(\"//div/img/@src\").extract()[0]\n", + " # print(src)\n", " r = requests.get(src)\n", - " \n", + "\n", " image = Image.open(BytesIO(r.content))\n", - "# path = \"C:/Users/carbon/Desktop/output/\"+instaAccountName+str(count)+\".\" + image.format \n", - " path = \"output/\"+instaaccountname+str(count)+\".\" + image.format\n", - "# print(image.size, image.format, image.mode)\n", - " q1=''\n", - " q2=''\n", + " # path = \"C:/Users/carbon/Desktop/output/\"+instaAccountName+str(count)+\".\" + image.format\n", + " path = \"output/\" + instaaccountname + str(count) + \".\" + image.format\n", + " # print(image.size, image.format, image.mode)\n", + " q1 = \"\"\n", + " q2 = \"\"\n", " try:\n", " image.save(path, image.format)\n", - " q1 = instaaccountname+str(count)\n", - " q2 = sel.xpath('//span/span/text()').extract_first()\n", - "# print(q1)\n", - "# print(q2)\n", + " q1 = instaaccountname + str(count)\n", + " q2 = sel.xpath(\"//span/span/text()\").extract_first()\n", + " # print(q1)\n", + " # print(q2)\n", "\n", - " except IOError:\n", - " q1=''\n", - " q2=''\n", - " imageID.insert(len(imageID),q1)\n", - " imageLikes.insert(len(imageLikes),q2)\n", - " sl_no.insert(len(sl_no),str(count))\n", + " except OSError:\n", + " q1 = \"\"\n", + " q2 = \"\"\n", + " imageID.insert(len(imageID), q1)\n", + " imageLikes.insert(len(imageLikes), q2)\n", + " sl_no.insert(len(sl_no), str(count))\n", " count = count + 1\n", " if count > max_no_of_iteration:\n", " driver.quit()\n", - " df = pd.DataFrame({'ImageID':imageID,'Sl_no':sl_no, 'ImageLikes':imageLikes})\n", - " fileName = instaaccountname+str('.csv')\n", + " df = pd.DataFrame(\n", + " {\"ImageID\": imageID, \"Sl_no\": sl_no, \"ImageLikes\": imageLikes}\n", + " )\n", + " fileName = instaaccountname + \".csv\"\n", " df.to_csv(fileName, index=False)\n", " break\n", "\n", - "\n", " except:\n", " pass\n", "\n", @@ -163,7 +205,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.4" + "version": "3.13.5" } }, "nbformat": 4, diff --git a/insta_monitering/insta_api.py b/insta_monitering/insta_api.py index 957f240730d..4c77bff0f0c 100644 --- a/insta_monitering/insta_api.py +++ b/insta_monitering/insta_api.py @@ -1,152 +1,302 @@ +import traceback from concurrent.futures import ThreadPoolExecutor +import con_file import tornado.ioloop import tornado.web +import ujson from tornado.concurrent import run_on_executor from tornado.gen import coroutine -# import file +# Import required classes from local modules try: - from instagram_monitering.insta_datafetcher import * - from instagram_monitering.subpinsta import * -except: - from insta_datafetcher import * - from subpinsta import * -MAX_WORKERS = 10 + # Attempt relative import (when running as part of a package) + from .insta_datafetcher import DataFetcher, InstaProcessManager, MonitoringClass + from .subpinsta import start_monitoring_process +except ImportError: + # Fallback to absolute import (when running standalone) + from insta_datafetcher import DataFetcher, InstaProcessManager + from subpinsta import start_monitoring_process + +# Configuration constants +MAX_WORKERS = 10 # Maximum number of threads for background tasks class StartHandlerinsta(tornado.web.RequestHandler): + """ + API handler to initiate Instagram monitoring for a specified hashtag or profile. + + Query Parameters: + q (str): Hashtag or profile name to monitor + userId (str): User identifier + type (str): Monitoring type ('hashtags' or 'profile') + productId (str): Product identifier for database storage + """ + executor = ThreadPoolExecutor(max_workers=MAX_WORKERS) @run_on_executor - def background_task(self, user, tags, type, productId): + def background_task( + self, user: str, tags: str, monitor_type: str, product_id: str + ) -> None: + """ + Execute monitoring process in a background thread. + + Args: + user: User identifier + tags: Hashtag or profile name + monitor_type: Type of monitoring ('hashtags' or 'profile') + product_id: Product identifier for database + """ try: - instasubprocess(user=user, tags=tags, type=type, productId=productId) - except: - print("error::background_task>>", sys.exc_info()[1]) + # Start monitoring process with configuration + start_monitoring_process( + user=user, + tags=tags, + monitor_type=monitor_type, + product_id=product_id, + db_host=con_file.host, # Use configured database host + db_port=con_file.mongoPort, # Use configured database port + ) + except Exception as e: + print(f"Error starting monitoring process: {str(e)}") + traceback.print_exc() @coroutine - def get(self): + def get(self) -> None: + """Handle GET request to start monitoring""" try: + # Extract and validate query parameters q = self.get_argument("q") user = self.get_argument("userId") - type = self.get_argument("type") - productId = self.get_argument("productId") - except: - self.send_error(400) - if " " in q: - q = q.replace(" ", "") - self.background_task(user=user, tags=q, type=type, productId=productId) - temp = {} - temp["query"] = q - temp["userId"] = user - temp["status"] = True - temp["productId"] = productId - print( - "{0}, {1}, {2}, {3}".format( - temp["userId"], temp["productId"], temp["query"], temp["status"] + monitor_type = self.get_argument("type") + product_id = self.get_argument("productId") + + # Sanitize input (remove spaces from tags) + if " " in q: + q = q.replace(" ", "") + + # Start background monitoring task + self.background_task( + user, tags=q, monitor_type=monitor_type, product_id=product_id ) - ) - self.write(ujson.dumps(temp)) + + # Return success response + response = { + "query": q, + "userId": user, + "status": True, + "productId": product_id, + "message": f"Monitoring started for {monitor_type}: {q}", + } + + print(f"Monitoring started: User={user}, Tags={q}, Type={monitor_type}") + self.write(ujson.dumps(response)) + + except Exception as e: + # Handle missing parameters or other errors + self.send_error(400, reason=f"Invalid request: {str(e)}") class StopHandlerinsta(tornado.web.RequestHandler): - def get(self): + """ + API handler to terminate Instagram monitoring for a specified hashtag or profile. + + Query Parameters: + q (str): Hashtag or profile name to stop monitoring + userId (str): User identifier + productId (str): Product identifier + """ + + def get(self) -> None: + """Handle GET request to stop monitoring""" try: + # Extract and validate query parameters q = self.get_argument("q") user = self.get_argument("userId") - # tags = self.get_argument("hashtags") - productId = self.get_argument("productId") - except: - self.send_error(400) - obj = InstaPorcessClass() - result = obj.deletProcess(tags=q, user=user, productId=productId) - temp = {} - temp["query"] = q - temp["userId"] = user - temp["productId"] = productId - temp["status"] = result - print( - "{0}, {1}, {2}, {3}".format( - temp["userId"], temp["productId"], temp["query"], temp["status"] + product_id = self.get_argument("productId") + + # Stop monitoring process with configuration + process_manager = InstaProcessManager( + db_host=con_file.host, # Use configured database host + db_port=con_file.mongoPort, # Use configured database port ) - ) - self.write(ujson.dumps(temp)) + result = process_manager.stop_monitoring(user, q, product_id) + + # Return status response + response = { + "query": q, + "userId": user, + "productId": product_id, + "status": result, + "message": f"Monitoring stopped for {q}" + if result + else f"Monitoring not found for {q}", + } + + print(f"Monitoring status: {q} - {'Stopped' if result else 'Not Found'}") + self.write(ujson.dumps(response)) + + except Exception as e: + # Handle missing parameters or other errors + self.send_error(400, reason=f"Invalid request: {str(e)}") class StatusHandlerinsta(tornado.web.RequestHandler): - def get(self): + """ + API handler to check the status of Instagram monitoring. + + Query Parameters: + q (str): Hashtag or profile name + userId (str): User identifier + productId (str): Product identifier + """ + + def get(self) -> None: + """Handle GET request to check monitoring status""" try: + # Extract and validate query parameters q = self.get_argument("q") user = self.get_argument("userId") - productId = self.get_argument("productId") - # tags = self.get_argument("hashtags") - except: - self.send_error(400) - obj = InstaPorcessClass() - result = obj.statusCheck(tags=q, user=user, productId=productId) - temp = {} - temp["query"] = q - temp["userId"] = user - temp["status"] = result - temp["productId"] = productId - print( - "{0}, {1}, {2}, {3}".format( - temp["userId"], temp["productId"], temp["query"], temp["status"] + product_id = self.get_argument("productId") + + # Check monitoring status with configuration + process_manager = InstaProcessManager( + db_host=con_file.host, # Use configured database host + db_port=con_file.mongoPort, # Use configured database port ) - ) - self.write(ujson.dumps(temp)) + is_running = process_manager.is_process_running(user, q, product_id) + + # Return status response + response = { + "query": q, + "userId": user, + "status": is_running, + "productId": product_id, + "message": f"Monitoring is {'active' if is_running else 'inactive'} for {q}", + } + print(f"Status check: {q} - {'Active' if is_running else 'Inactive'}") + self.write(ujson.dumps(response)) -# class SenderHandlerinsta(tornado.web.RequestHandler): -# def get(self): -# try: -# q = self.get_argument("q") -# user = self.get_argument("userId") -# type = self.get_argument("type") -# productId = self.get_argument("productId") -# except: -# self.send_error(400) -# recordsobj = DBDataFetcher(user=user, tags=q, type=type, productId=productId) -# data = recordsobj.dbFetcher() -# self.write(data) + except Exception as e: + # Handle missing parameters or other errors + self.send_error(400, reason=f"Invalid request: {str(e)}") class SenderHandlerinstaLess(tornado.web.RequestHandler): - def get(self): + """ + API handler to retrieve Instagram posts older than a specified timestamp. + + Query Parameters: + q (str): Hashtag or profile name + userId (str): User identifier + type (str): Monitoring type + productId (str): Product identifier + date (int): Unix timestamp + limit (int): Maximum number of posts to return + """ + + def get(self) -> None: + """Handle GET request to fetch older posts""" try: + # Extract and validate query parameters q = self.get_argument("q") user = self.get_argument("userId") - type = self.get_argument("type") - productId = self.get_argument("productId") - date = self.get_argument("date") - limit = self.get_argument("limit") - except: - self.send_error(400) - recordsobj = DBDataFetcher(user=user, tags=q, type=type, productId=productId) - data = recordsobj.DBFetcherLess(limit=limit, date=date) - # print("{0}, {1}, {2}, {3}".format(temp["userId"], temp["productId"], temp["query"], temp["status"])) - self.write(data) + monitor_type = self.get_argument("type") + product_id = self.get_argument("productId") + date = int(self.get_argument("date")) # Unix timestamp + limit = int(self.get_argument("limit")) # Number of posts + + # Fetch posts older than specified timestamp with configuration + data_fetcher = DataFetcher( + user=user, + tags=q, + product_id=product_id, + db_host=con_file.host, # Use configured database host + db_port=con_file.mongoPort, # Use configured database port + ) + posts = data_fetcher.get_posts_before_timestamp(date, limit) + + # Return posts data + self.write( + ujson.dumps( + { + "query": q, + "userId": user, + "productId": product_id, + "count": len(posts), + "posts": posts, + } + ) + ) + + except ValueError as ve: + # Handle invalid parameter types + self.send_error(400, reason=f"Invalid parameter: {str(ve)}") + except Exception as e: + # Handle other errors + self.send_error(500, reason=f"Internal server error: {str(e)}") class SenderHandlerinstaGreater(tornado.web.RequestHandler): - def get(self): + """ + API handler to retrieve Instagram posts newer than a specified timestamp. + + Query Parameters: + q (str): Hashtag or profile name + userId (str): User identifier + type (str): Monitoring type + productId (str): Product identifier + date (int): Unix timestamp + limit (int): Maximum number of posts to return + """ + + def get(self) -> None: + """Handle GET request to fetch newer posts""" try: + # Extract and validate query parameters q = self.get_argument("q") user = self.get_argument("userId") - type = self.get_argument("type") - productId = self.get_argument("productId") - date = self.get_argument("date") - limit = self.get_argument("limit") - except: - self.send_error(400) - recordsobj = DBDataFetcher(user=user, tags=q, type=type, productId=productId) - data = recordsobj.DBFetcherGreater(limit=limit, date=date) - # print("{0}, {1}, {2}, {3}".format(temp["userId"], temp["productId"], temp["query"], temp["status"])) - self.write(data) + monitor_type = self.get_argument("type") + product_id = self.get_argument("productId") + date = int(self.get_argument("date")) # Unix timestamp + limit = int(self.get_argument("limit")) # Number of posts + + # Fetch posts newer than specified timestamp with configuration + data_fetcher = DataFetcher( + user=user, + tags=q, + product_id=product_id, + db_host=con_file.host, # Use configured database host + db_port=con_file.mongoPort, # Use configured database port + ) + posts = data_fetcher.get_posts_after_timestamp(date, limit) + + # Return posts data + self.write( + ujson.dumps( + { + "query": q, + "userId": user, + "productId": product_id, + "count": len(posts), + "posts": posts, + } + ) + ) + + except ValueError as ve: + # Handle invalid parameter types + self.send_error(400, reason=f"Invalid parameter: {str(ve)}") + except Exception as e: + # Handle other errors + self.send_error(500, reason=f"Internal server error: {str(e)}") if __name__ == "__main__": + """Main entry point - Starts the Tornado server""" + # Define API routes and handlers application = tornado.web.Application( [ (r"/instagram/monitoring/start", StartHandlerinsta), @@ -154,9 +304,24 @@ def get(self): (r"/instagram/monitoring/status", StatusHandlerinsta), (r"/instagram/monitoring/less", SenderHandlerinstaLess), (r"/instagram/monitoring/greater", SenderHandlerinstaGreater), - ] + ], + debug=False, # Disable debug mode for production + autoreload=True, # Automatically reload on code changes ) - application.listen(7074) - print("server running") - tornado.ioloop.IOLoop.instance().start() + # Start the server + port = 7074 + application.listen(port) + print(f"Instagram Monitoring API Server running on port {port}") + print( + f"MongoDB connection: {con_file.host}:{con_file.mongoPort}" + ) # Display MongoDB connection info + print("Available endpoints:") + print(" - /instagram/monitoring/start") + print(" - /instagram/monitoring/stop") + print(" - /instagram/monitoring/status") + print(" - /instagram/monitoring/less") + print(" - /instagram/monitoring/greater") + + # Start the I/O loop + tornado.ioloop.IOLoop.current().start() diff --git a/insta_monitering/insta_datafetcher.py b/insta_monitering/insta_datafetcher.py index 8c5ed78b902..8c624f84cb4 100644 --- a/insta_monitering/insta_datafetcher.py +++ b/insta_monitering/insta_datafetcher.py @@ -1,461 +1,914 @@ -# only god knows whats happening in the code -# if I forget the code structure -# please pray to god for help +# Instagram Monitoring Tool with Enhanced Error Handling and Default Parameters import asyncio import multiprocessing import os import random -import re import socket import sys import time +import traceback import bs4 +import httpx import pymongo -import requests import socks import ujson -import urllib3 try: - import instagram_monitering.con_file as config -except Exception as e: - print(e) import con_file as config +except ImportError: + import insta_monitering.con_file as config -class PorxyApplyingDecorator(object): - def __init__(self): - filename = os.getcwd() + "/" + "ipList.txt" - with open(filename, "r") as f: - ipdata = f.read() - self._IP = random.choice(ipdata.split(",")) - - def __call__(self, function_to_call_for_appling_proxy): - SOCKS5_PROXY_HOST = self._IP - # default_socket = socket.socket - socks.set_default_proxy( - socks.SOCKS5, - SOCKS5_PROXY_HOST, - config.SOCKS5_PROXY_PORT, - True, - config.auth, - config.passcode, - ) - socket.socket = socks.socksocket +class ProxyApplyingDecorator: + """ + Decorator class for applying SOCKS5 proxy to HTTP requests. - def wrapper_function(url): - # this is used for applyting socks5 proxy over the request - return function_to_call_for_appling_proxy(url) + Attributes: + proxy_file (str): Path to the file containing proxy list. + _IP (str): Selected proxy IP address and port. + """ - socks.set_default_proxy() - return wrapper_function + def __init__(self, proxy_file="ipList.txt"): + """ + Initialize the proxy decorator. + + Args: + proxy_file (str, optional): Path to the proxy list file. Defaults to "ipList.txt". + """ + self.proxy_file = proxy_file + self._IP = self._get_random_proxy() + def _get_random_proxy(self): + """ + Read proxy list from file and select a random proxy. -async def dataprocess(htmldata): - bs4obj = bs4.BeautifulSoup(htmldata, "html.parser") - scriptsdata = bs4obj.findAll("script", {"type": "text/javascript"}) - datatext = "" - for i in scriptsdata: - datatext = i.text - if "window._sharedData =" in datatext: - break - datajson = re.findall("{(.*)}", datatext) - datajson = "{" + datajson[0] + "}" - datadict = ujson.loads(datajson) - maindict = {} - datadict = datadict["entry_data"]["PostPage"][0]["graphql"]["shortcode_media"] - tofind = ["owner", "location"] - for i in tofind: + Returns: + str: Randomly selected proxy in "host:port" format. + """ try: - maindict[i] = datadict[i] + if not os.path.exists(self.proxy_file): + raise FileNotFoundError(f"Proxy file not found: {self.proxy_file}") + + with open(self.proxy_file) as f: + ipdata = f.read().strip() + + if not ipdata: + raise ValueError("Proxy file is empty") + + return random.choice(ipdata.split(",")) except Exception as e: - print(e) - pass - return maindict + print(f"Error loading proxy: {e}") + return None + + def __call__(self, function_to_apply_proxy): + """ + Wrap the target function with proxy configuration. + Args: + function_to_apply_proxy (callable): Function to be wrapped. -async def datapullpost(future, url): - while True: + Returns: + callable: Wrapped function with proxy applied. + """ + + def wrapper_function(url): + if not self._IP: + print("No proxy available, using direct connection") + return function_to_apply_proxy(url) - @PorxyApplyingDecorator() - async def request_pull(url): - data = None - print(url) - urllib3.disable_warnings() - user_agent = {"User-agent": "Mozilla/17.0"} + original_socket = socket.socket try: - data = requests.get( - url=url, headers=user_agent, timeout=10, verify=False - ).text + proxy_parts = self._IP.split(":") + proxy_host = proxy_parts[0] + proxy_port = ( + int(proxy_parts[1]) + if len(proxy_parts) > 1 + else config.SOCKS5_PROXY_PORT + ) + + # Configure SOCKS5 proxy + socks.set_default_proxy( + socks.SOCKS5, + proxy_host, + proxy_port, + True, + config.auth, + config.passcode, + ) + socket.socket = socks.socksocket + return function_to_apply_proxy(url) except Exception as e: - print(e) - data = None + print(f"Proxy error: {e}") + return function_to_apply_proxy(url) # Fallback to direct connection finally: - return data + # Restore original socket configuration + socket.socket = original_socket + socks.set_default_proxy() - data = await request_pull(url) - if data != None: - break - data = await dataprocess(htmldata=data) - # here processing of data has to occur - future.set_result(data) + return wrapper_function -class MoniteringClass: - def __init__(self, user, tags, type, productId): +async def process_post_data(html_data): + """ + Process HTML data of a single Instagram post to extract metadata. + Args: + html_data (str): HTML content of the post page. + + Returns: + dict: Extracted post metadata including ID, owner, location, etc. + """ + if not html_data: + return {} + + try: + soup = bs4.BeautifulSoup(html_data, "html.parser") + scripts = soup.find_all("script", {"type": "text/javascript"}) + + # Find the script containing post data + for script in scripts: + if "window._sharedData =" in script.text: + json_text = script.text.strip() + json_text = ( + json_text.replace("window._sharedData =", "") + .replace(";", "") + .strip() + ) + data = ujson.loads(json_text) + + # Extract post details + if "entry_data" in data and "PostPage" in data["entry_data"]: + post = data["entry_data"]["PostPage"][0]["graphql"][ + "shortcode_media" + ] + return { + "id": post.get("id"), + "owner": post.get("owner"), + "location": post.get("location"), + "caption": post.get("edge_media_to_caption", {}) + .get("edges", [{}])[0] + .get("node", {}) + .get("text"), + "timestamp": post.get("taken_at_timestamp"), + } + + return {} + except Exception as e: + print(f"Error processing post data: {e}") + traceback.print_exc() + return {} + + +async def fetch_post_details(url, max_retries=3): + """ + Asynchronously fetch and process details of an Instagram post. + + Args: + url (str): URL of the Instagram post. + max_retries (int, optional): Maximum number of retries. Defaults to 3. + + Returns: + dict: Processed post data. + """ + retries = 0 + while retries < max_retries: + + @ProxyApplyingDecorator() + async def fetch_with_proxy(url): + """Fetch URL content with proxy applied""" + try: + headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" + } + async with httpx.AsyncClient(verify=False, timeout=30) as client: + response = await client.get(url, headers=headers) + response.raise_for_status() + return response.text + except Exception as e: + print(f"Request failed: {e}") + return None + + html_data = await fetch_with_proxy(url) + if html_data: + return await process_post_data(html_data) + + retries += 1 + print(f"Retry {retries}/{max_retries} for {url}") + await asyncio.sleep(2) + + return {} + + +class MonitoringClass: + """ + Main class for monitoring Instagram hashtags or profiles. + + Attributes: + user (str): User identifier for the monitoring task. + tags (str): Hashtag or profile name to monitor. + monitor_type (str): Type of monitoring ("hashtags" or "profile"). + product_id (str): Product identifier for database naming. + url (str): Instagram URL to fetch data from. + client (pymongo.MongoClient): MongoDB client. + db (pymongo.Database): MongoDB database. + collection (pymongo.Collection): MongoDB collection for storing posts. + """ + + def __init__( + self, + user, + tags, + monitor_type="hashtags", + product_id="insta_monitor", + db_host=None, + db_port=None, + ): + """ + Initialize the monitoring class. + + Args: + user (str): User identifier. + tags (str): Hashtag or profile name. + monitor_type (str, optional): Monitoring type. Defaults to "hashtags". + product_id (str, optional): Product identifier. Defaults to "insta_monitor". + db_host (str, optional): MongoDB host. Defaults to config.host. + db_port (int, optional): MongoDB port. Defaults to config.mongoPort. + """ + self.user = user + self.tags = tags + self.monitor_type = monitor_type + self.product_id = product_id + + # Use config values or defaults + self.db_host = db_host or config.host + self.db_port = db_port or config.mongoPort + + self.client = None + self.db = None + self.collection = None + + self._initialize() + + def _initialize(self): + """Initialize MongoDB connection and monitoring URL""" try: - self.mon = pymongo.MongoClient(host=config.host, port=config.mongoPort) - db = self.mon[productId + ":" + user + ":insta"] - self._collection = db[tags] - if type == "hashtags": - self._url = "https://www.instagram.com/explore/tags/" + tags + "/?__a=1" - if type == "profile": - self._url = "https://www.instagram.com/" + tags + "/?__a=1" - except Exception as err: - print(f"exception {err}") - print("error::MointeringClass.__init__>>", sys.exc_info()[1]) - - def _dataProcessing(self, data): - loop = asyncio.get_event_loop() - userdata = [] - try: - if not isinstance(data, dict): - raise Exception - media_post = data["tag"]["media"]["nodes"] - top_post = data["tag"]["top_posts"]["nodes"] - print("media post ::", len(media_post)) - print("top_post::", len(top_post)) - futures = [] - for i in media_post: - tempdict = {} - tempdict["url"] = "https://www.instagram.com/p/" + i["code"] + "/" - tempdict["code"] = i["code"] - userdata.append(tempdict) - for i in top_post: - tempdict = {} - tempdict["url"] = "https://www.instagram.com/p/" + i["code"] + "/" - tempdict["code"] = i["code"] - userdata.append(tempdict) - for i in userdata: - i["future"] = asyncio.Future() - futures.append(i["future"]) - asyncio.ensure_future(datapullpost(future=i["future"], url=i["url"])) - loop.run_until_complete(asyncio.wait(futures)) - for i in userdata: - i["data"] = i["future"].result() - except Exception as err: - print(f"Exception ! : {err}") - print("error::Monitering.dataProcessing>>", sys.exc_info()[1]) - finally: - # loop.close() - print("userdata::", len(userdata)) - print("media_post::", len(media_post)) - print("top post::", len(top_post)) - return userdata, media_post, top_post + self.client = pymongo.MongoClient( + host=self.db_host, port=self.db_port, serverSelectionTimeoutMS=5000 + ) + self.client.admin.command("ping") # Test connection - def _insertFunction(self, record): + db_name = f"{self.product_id}:{self.user}:insta" + self.db = self.client[db_name] + self.collection = self.db[self.tags] + + # Create unique index to prevent duplicate posts + self.collection.create_index("id", unique=True) + + # Build URL based on monitoring type + if self.monitor_type == "hashtags": + self.url = f"https://www.instagram.com/explore/tags/{self.tags}/?__a=1" + elif self.monitor_type == "profile": + self.url = f"https://www.instagram.com/{self.tags}/?__a=1" + else: + raise ValueError( + f"Invalid monitor type: {self.monitor_type}. Must be 'hashtags' or 'profile'." + ) + + print(f"Monitoring initialized for {self.monitor_type}: {self.tags}") + except Exception as e: + print(f"Initialization error: {e}") + traceback.print_exc() + self._cleanup() + raise + + def _cleanup(self): + """Clean up resources (close MongoDB connection)""" + if self.client: + self.client.close() + + def _parse_instagram_response(self, response_data): + """ + Parse Instagram API response to extract post information. + + Args: + response_data (dict): JSON response from Instagram API. + + Returns: + list: List of posts with basic information. + """ try: - records = self._collection.find({"id": record["id"]}) - if records.count() == 0: - # record["timestamp"] = time.time() - self._collection.insert(record) - except Exception as err: - print(f"Execption : {err}") - print("error::Monitering.insertFunction>>", sys.exc_info()[1]) - - def _lastProcess(self, userdata, media_post, top_post): - mainlist = [] + if not isinstance(response_data, dict): + raise TypeError("Invalid response format") + + if self.monitor_type == "hashtags": + if ( + "graphql" not in response_data + or "hashtag" not in response_data["graphql"] + ): + raise ValueError("Invalid hashtag response structure") + + hashtag_data = response_data["graphql"]["hashtag"] + posts = [] + + # Extract recent posts + edge_media = hashtag_data.get("edge_hashtag_to_media", {}) + for edge in edge_media.get("edges", []): + node = edge.get("node", {}) + posts.append( + { + "id": node.get("id"), + "shortcode": node.get("shortcode"), + "timestamp": node.get("taken_at_timestamp"), + "owner_id": node.get("owner", {}).get("id"), + "caption": node.get("edge_media_to_caption", {}) + .get("edges", [{}])[0] + .get("node", {}) + .get("text"), + "url": f"https://www.instagram.com/p/{node.get('shortcode')}/", + } + ) + + # Extract top posts + edge_top_posts = hashtag_data.get("edge_hashtag_to_top_posts", {}) + for edge in edge_top_posts.get("edges", []): + node = edge.get("node", {}) + posts.append( + { + "id": node.get("id"), + "shortcode": node.get("shortcode"), + "timestamp": node.get("taken_at_timestamp"), + "owner_id": node.get("owner", {}).get("id"), + "caption": node.get("edge_media_to_caption", {}) + .get("edges", [{}])[0] + .get("node", {}) + .get("text"), + "url": f"https://www.instagram.com/p/{node.get('shortcode')}/", + } + ) + + return posts + + elif self.monitor_type == "profile": + if ( + "graphql" not in response_data + or "user" not in response_data["graphql"] + ): + raise ValueError("Invalid profile response structure") + + user_data = response_data["graphql"]["user"] + posts = [] + + # Extract user posts + edge_media = user_data.get("edge_owner_to_timeline_media", {}) + for edge in edge_media.get("edges", []): + node = edge.get("node", {}) + posts.append( + { + "id": node.get("id"), + "shortcode": node.get("shortcode"), + "timestamp": node.get("taken_at_timestamp"), + "owner_id": node.get("owner", {}).get("id"), + "caption": node.get("edge_media_to_caption", {}) + .get("edges", [{}])[0] + .get("node", {}) + .get("text"), + "url": f"https://www.instagram.com/p/{node.get('shortcode')}/", + } + ) + + return posts + + return [] + except Exception as e: + print(f"Error parsing Instagram response: {e}") + traceback.print_exc() + return [] + + async def _fetch_and_process_posts(self, posts): + """ + Asynchronously fetch and process detailed information for all posts. + + Args: + posts (list): List of posts with basic information. + + Returns: + list: List of posts with detailed information. + """ + if not posts: + return [] + + print(f"Fetching details for {len(posts)} posts") + + # Create event loop + loop = asyncio.get_event_loop() + + # Create tasks for each post + tasks = [] + for post in posts: + tasks.append(fetch_post_details(post["url"])) + + # Execute all tasks concurrently + results = await asyncio.gather(*tasks) + + # Merge results into original posts + for i, result in enumerate(results): + posts[i].update(result) + + return posts + + def _save_to_database(self, posts): + """ + Save posts to MongoDB database. + + Args: + posts (list): List of posts to save. + """ + if not posts: + print("No posts to save") + return + + saved_count = 0 + for post in posts: + if not post.get("id"): + continue + + try: + # Add insertion timestamp + post["_inserted_at"] = time.time() + + # Use update_one with upsert to avoid duplicates + result = self.collection.update_one( + {"id": post["id"]}, {"$set": post}, upsert=True + ) + + if result.upserted_id or result.modified_count > 0: + saved_count += 1 + + except Exception as e: + print(f"Error saving post {post.get('id')}: {e}") + + print(f"Saved {saved_count}/{len(posts)} posts to database") + + +def run_monitoring(self, max_retries=3): + """ + Execute the Instagram monitoring task with retry mechanism. + + Args: + max_retries (int, optional): Maximum number of retries. Defaults to 3. + + Returns: + bool: True if monitoring completed successfully, False otherwise. + """ + # Retry loop with improved readability and error handling + for attempt in range(max_retries): try: - for i in userdata: - for j in media_post: - if i["code"] == j["code"]: - tempdict = j.copy() - tofind = ["owner", "location"] - for z in tofind: - try: - tempdict[z + "data"] = i["data"][z] - except Exception as e: - print(f"exception : {e}") - pass - mainlist.append(tempdict) - self._insertFunction(tempdict.copy()) - for k in top_post: - if i["code"] == k["code"]: - tempdict = k.copy() - tofind = ["owner", "location"] - for z in tofind: - try: - tempdict[z + "data"] = i["data"][z] - except Exception as err: - print(f"Exception :{err}") - pass - mainlist.append(tempdict) - self._insertFunction(tempdict.copy()) - except Exception as err: - print(f"Exception : {err}") - print("error::lastProcess>>", sys.exc_info()[1]) - - def request_data_from_instagram(self): + # Fetch Instagram API data using proxy decorator + response_data = self._fetch_instagram_data() + if not response_data: + raise ValueError("Failed to fetch data from Instagram API") + + # Parse the response to extract post information + posts = self._parse_instagram_response(response_data) + if not posts: + print("No posts found to process") + return False + + print(f"Processing {len(posts)} posts from {self.tags}") + + # Asynchronously process posts and save to database + self._process_and_save_posts(posts) + + print(f"Monitoring completed successfully for {self.tags}") + return True + + except Exception as e: + # Log detailed error information for debugging + print(f"Monitoring attempt {attempt + 1}/{max_retries} failed: {e}") + traceback.print_exc() + + # Wait before retrying, except on final attempt + if attempt < max_retries - 1: + print(f"Retrying in {config.RETRY_DELAY} seconds...") + time.sleep(config.RETRY_DELAY) + + print(f"Max retries reached ({max_retries}). Monitoring failed.") + return False + + +def _fetch_instagram_data(self): + """ + Fetch data from Instagram API with proxy applied. + + Returns: + dict: JSON response from Instagram, or None on error. + """ + + @ProxyApplyingDecorator() + def fetch_with_proxy(url): + """Inner function to apply proxy and handle HTTP request""" + headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" + } try: - while True: - - @PorxyApplyingDecorator() - def reqest_pull(url): - print(url) - data = None - urllib3.disable_warnings() - user_agent = {"User-agent": "Mozilla/17.0"} - try: - data = requests.get( - url=url, headers=user_agent, timeout=24, verify=False - ).text - except Exception as err: - print(f"Exception : {err}") - data = None - finally: - return data - - data = reqest_pull(self._url) - if data != None: - break - datadict = ujson.loads(data) - userdata, media_post, top_post = self._dataProcessing(datadict) - finallydata = self._lastProcess( - userdata=userdata, media_post=media_post, top_post=top_post - ) - # print(ujson.dumps(finallydata)) + with httpx.Client(verify=False, timeout=30) as client: + response = client.get(url, headers=headers) + response.raise_for_status() + return response.json() except Exception as e: - print(f"exception : {e}\n") - print("error::Monitering.request_data_from_instagram>>", sys.exc_info()[1]) + print(f"Network request error: {e}") + return None - def __del__(self): - self.mon.close() + return fetch_with_proxy(self.url) -def hashtags(user, tags, type, productId): - try: - temp = MoniteringClass(user=user, tags=tags, type=type, productId=productId) - temp.request_data_from_instagram() - except Exception as err: - print(f"exception : {err} \n") - print("error::hashtags>>", sys.exc_info()[1]) +async def _fetch_and_process_post_details(self, posts): + """ + Asynchronously fetch detailed information for multiple Instagram posts. + + Args: + posts (list): List of posts with basic information (id, shortcode, url) + + Returns: + list: List of dictionaries with detailed post information + """ + # Create async tasks for each post URL + tasks = [fetch_post_details(post["url"]) for post in posts] + + # Execute all tasks concurrently and return results + return await asyncio.gather(*tasks) + + +def _process_and_save_posts(self, posts): + """ + Process posts asynchronously and save results to MongoDB. + + Args: + posts (list): List of posts to process and save + """ + # Use asyncio.run() to handle the event loop lifecycle + # This is preferred over manually managing the event loop in Python 3.7+ + results = asyncio.run(self._fetch_and_process_post_details(posts)) + + # Merge detailed results back into original post objects + for i, result in enumerate(results): + posts[i].update(result) + + # Save all processed posts to database + self._save_to_database(posts) -class theradPorcess(multiprocessing.Process): - def __init__(self, user, tags, type, productId): +class InstaProcessManager: + """ + Manager class for controlling Instagram monitoring processes. + + Attributes: + db_host (str): MongoDB host address. + db_port (int): MongoDB port number. + processes (dict): Dictionary of running processes. + """ + + def __init__(self, db_host=None, db_port=None): + """ + Initialize the process manager. + + Args: + db_host (str, optional): MongoDB host. Defaults to config.host. + db_port (int, optional): MongoDB port. Defaults to config.mongoPort. + """ + self.db_host = db_host or config.host + self.db_port = db_port or config.mongoPort + self.processes = {} # Track running processes + + def _get_process_db(self): + """ + Get MongoDB collection for managing monitoring processes. + + Returns: + pymongo.Collection: Processes collection. + """ + client = pymongo.MongoClient(host=self.db_host, port=self.db_port) + return client["insta_process"]["process"] + + def is_process_running(self, user, tags, product_id): + """ + Check if a monitoring process is running. + + Args: + user (str): User identifier. + tags (str): Hashtag or profile name. + product_id (str): Product identifier. + + Returns: + bool: True if process is running, False otherwise. + """ try: - multiprocessing.Process.__init__(self) - self.user = user - self.tags = tags - self.type = type - self.productId = productId - except Exception as err: - print(f"exception : {err}\n") - print("errorthreadPorcess:>>", sys.exc_info()[1]) - - def run(self): + collection = self._get_process_db() + return ( + collection.count_documents( + {"user": user, "tags": tags, "productId": product_id} + ) + > 0 + ) + except Exception as e: + print(f"Error checking process status: {e}") + return False + + def start_monitoring( + self, user, tags, monitor_type="hashtags", product_id="insta_monitor" + ): + """ + Start a new monitoring process. + + Args: + user (str): User identifier. + tags (str): Hashtag or profile name. + monitor_type (str, optional): Monitoring type. Defaults to "hashtags". + product_id (str, optional): Product identifier. Defaults to "insta_monitor". + + Returns: + bool: True if process started successfully, False otherwise. + """ try: - hashtags( - user=self.user, tags=self.tags, type=self.type, productId=self.productId + # Check if process is already running + if self.is_process_running(user, tags, product_id): + print(f"Monitoring for {user}/{tags} is already running") + return False + + # Record process start in database + collection = self._get_process_db() + collection.insert_one( + { + "user": user, + "tags": tags, + "monitorType": monitor_type, + "productId": product_id, + "startedAt": time.time(), + } ) - except Exception as err: - print(f"exception : {err}\n") - print("error::run>>", sys.exc_info()[1]) + # Start monitoring process + process = multiprocessing.Process( + target=self._run_monitoring_process, + args=(user, tags, monitor_type, product_id), + ) + process.start() -class InstaPorcessClass: - def _dbProcessReader(self, user, tags, productId): - value = True - mon = pymongo.MongoClient(host=config.host, port=config.mongoPort) - try: - db = mon["insta_process"] - collection = db["process"] - temp = {} - temp["user"] = user - temp["tags"] = tags - temp["productId"] = productId - records = collection.find(temp).count() - if records == 0: - raise Exception - value = True - except Exception as err: - print(f"exception : {err}\n") - value = False - print("error::dbProcessReader:>>", sys.exc_info()[1]) - finally: - mon.close() - return value + # Track the process + process_key = f"{user}_{tags}_{product_id}" + self.processes[process_key] = process - def _processstart(self, user, tags, productId): - mon = pymongo.MongoClient(host=config.host, port=config.mongoPort) - try: - db = mon["insta_process"] - collection = db["process"] - temp = {} - temp["user"] = user - temp["tags"] = tags - temp["productId"] = productId - collection.insert(temp) - except Exception as err: - print(f"execption : {err}\n") - print("error::processstart>>", sys.exc_info()[1]) - finally: - mon.close() + print(f"Started monitoring for {user}/{tags}") + return True - def startprocess(self, user, tags, type, productId): + except Exception as e: + print(f"Error starting monitoring: {e}") + traceback.print_exc() + return False + + def _run_monitoring_process(self, user, tags, monitor_type, product_id): + """ + Run monitoring process in a separate process. + + Args: + user (str): User identifier. + tags (str): Hashtag or profile name. + monitor_type (str): Monitoring type. + product_id (str): Product identifier. + """ try: - self._processstart(user=user, tags=tags, productId=productId) - while True: - # therad = theradPorcess(user=user, tags=tags, type=type) - # therad.start() - hashtags(user=user, tags=tags, type=type, productId=productId) - check = self._dbProcessReader(user=user, tags=tags, productId=productId) - print(check) - if check == False: - break - time.sleep(300) - # therad.join() - except Exception as err: - print(f"exception : {err}\n") - print("error::startPoress::>>", sys.exc_info()[1]) - - def deletProcess(self, user, tags, productId): - mon = pymongo.MongoClient(host=config.host, port=config.mongoPort) + monitor = MonitoringClass(user, tags, monitor_type, product_id) + + # Continuously monitor until stopped + while self.is_process_running(user, tags, product_id): + monitor.run_monitoring() + print(f"Waiting for next monitoring cycle for {user}/{tags}") + time.sleep(300) # 5-minute interval + + print(f"Monitoring stopped for {user}/{tags}") + + except Exception as e: + print(f"Error in monitoring process: {e}") + traceback.print_exc() + + def stop_monitoring(self, user, tags, product_id): + """ + Stop a running monitoring process. + + Args: + user (str): User identifier. + tags (str): Hashtag or profile name. + product_id (str): Product identifier. + + Returns: + bool: True if process stopped successfully, False otherwise. + """ try: - db = mon["insta_process"] - collection = db["process"] - temp = {} - temp["user"] = user - temp["tags"] = tags - temp["productId"] = productId - collection.delete_one(temp) - except Exception as err: - print(f"exception : {err}\n") - print("error::deletProcess:>>", sys.exc_info()[1]) - finally: - mon.close() - print("deleted - task", temp) + # Mark process as stopped in database + collection = self._get_process_db() + result = collection.delete_one( + {"user": user, "tags": tags, "productId": product_id} + ) + + if result.deleted_count == 0: + print(f"No running process found for {user}/{tags}") + return False + + # Clean up process tracking + process_key = f"{user}_{tags}_{product_id}" + if process_key in self.processes: + process = self.processes[process_key] + process.terminate() + process.join(timeout=5) + del self.processes[process_key] + + print(f"Stopped monitoring for {user}/{tags}") return True - def statusCheck(self, user, tags, productId): - mon = pymongo.MongoClient(host=config.host, port=config.mongoPort) - try: - db = mon["insta_process"] - collection = db["process"] - temp = {} - temp["user"] = user - temp["tags"] = tags - temp["productId"] = productId - records = collection.find(temp).count() - if records == 0: - result = False - else: - result = True - except Exception as err: - print(f"exception : {err}\n") - print("error::dbProcessReader:>>", sys.exc_info()[1]) - finally: - mon.close() - return result + except Exception as e: + print(f"Error stopping monitoring: {e}") + traceback.print_exc() + return False + def list_monitoring_processes(self): + """ + List all running monitoring processes. -class DBDataFetcher: - def __init__(self, user, tags, type, productId): + Returns: + list: List of running processes. + """ try: - self.mon = pymongo.MongoClient(host=config.host, port=config.mongoPort) - db = self.mon[productId + ":" + user + ":insta"] - self._collection = db[tags] - except Exception as err: - print(f"exception : {err}\n") - print("error::DBDataFetcher.init>>", sys.exc_info()[1]) - - def dbFetcher(self, limit=20): - mainlist = [] + collection = self._get_process_db() + return list(collection.find({}, {"_id": 0})) + except Exception as e: + print(f"Error listing processes: {e}") + traceback.print_exc() + return [] + + +class DataFetcher: + """ + Class for fetching Instagram data from MongoDB. + + Attributes: + user (str): User identifier. + tags (str): Hashtag or profile name. + product_id (str): Product identifier. + client (pymongo.MongoClient): MongoDB client. + collection (pymongo.Collection): MongoDB collection. + """ + + def __init__( + self, user, tags, product_id="insta_monitor", db_host=None, db_port=None + ): + """ + Initialize the data fetcher. + + Args: + user (str): User identifier. + tags (str): Hashtag or profile name. + product_id (str, optional): Product identifier. Defaults to "insta_monitor". + db_host (str, optional): MongoDB host. Defaults to config.host. + db_port (int, optional): MongoDB port. Defaults to config.mongoPort. + """ + self.user = user + self.tags = tags + self.product_id = product_id + self.db_host = db_host or config.host + self.db_port = db_port or config.mongoPort + self.client = None + self.collection = None + + self._initialize() + + def _initialize(self): + """Initialize MongoDB connection""" try: - records = self._collection.find().sort("id", -1).limit(limit) - for i in records: - del i["_id"] - mainlist.append(i) - except Exception as err: - print(f"exception : {err}\n") - print("error::dbFetcher>>", sys.exc_info()[1]) - finally: - return ujson.dumps(mainlist) + self.client = pymongo.MongoClient(host=self.db_host, port=self.db_port) + db_name = f"{self.product_id}:{self.user}:insta" + self.collection = self.client[db_name][self.tags] + except Exception as e: + print(f"Error initializing data fetcher: {e}") + traceback.print_exc() + raise + + def _cleanup(self): + """Clean up resources (close MongoDB connection)""" + if self.client: + self.client.close() + + def get_recent_posts(self, limit=20): + """ + Get recent Instagram posts. - def DBFetcherGreater(self, limit, date): - mainlist = [] - postval = {} + Args: + limit (int, optional): Maximum number of posts to return. Defaults to 20. + + Returns: + list: List of recent posts. + """ try: - postval["posts"] = None - if limit.isdigit() == False and date.isdigit() == False: - raise Exception - limit = int(limit) - date = int(date) - if date != 0: - doc = ( - self._collection.find({"date": {"$gt": date}}) - .sort("date", pymongo.ASCENDING) - .limit(limit) - ) - else: - doc = ( - self._collection.find().sort("date", pymongo.ASCENDING).limit(limit) - ) - for i in doc: - del i["_id"] - mainlist.append(i) - postval["posts"] = mainlist - postval["status"] = True - except Exception as err: - print(f"exception : {err}\n") - print("error::", sys.exc_info()[1]) - postval["status"] = False + cursor = ( + self.collection.find() + .sort("_inserted_at", pymongo.DESCENDING) + .limit(limit) + ) + + return list(cursor) + except Exception as e: + print(f"Error fetching recent posts: {e}") + traceback.print_exc() + return [] finally: - return ujson.dumps(postval) + self._cleanup() + + def get_posts_after_timestamp(self, timestamp, limit=20): + """ + Get posts after a specific timestamp. - def DBFetcherLess(self, limit, date): - mainlist = [] - postval = {} + Args: + timestamp (int): Unix timestamp. + limit (int, optional): Maximum number of posts to return. Defaults to 20. + + Returns: + list: List of posts after the specified timestamp. + """ try: - postval["posts"] = None - if limit.isdigit() == False and date.isdigit() == False: - raise Exception - limit = int(limit) - date = int(date) - doc = ( - self._collection.find({"date": {"$lt": date}}) + cursor = ( + self.collection.find({"timestamp": {"$gt": timestamp}}) + .sort("timestamp", pymongo.ASCENDING) .limit(limit) - .sort("date", pymongo.DESCENDING) ) - for i in doc: - del i["_id"] - mainlist.append(i) - postval["posts"] = mainlist[::-1] - postval["status"] = True - except Exception as err: - print(f"error : {err}\n") - print("error::", sys.exc_info()[1]) - postval["status"] = False + + return list(cursor) + except Exception as e: + print(f"Error fetching posts after timestamp: {e}") + traceback.print_exc() + return [] finally: - return ujson.dumps(postval) + self._cleanup() - def __del__(self): - self.mon.close() + def get_posts_before_timestamp(self, timestamp, limit=20): + """ + Get posts before a specific timestamp. + + Args: + timestamp (int): Unix timestamp. + limit (int, optional): Maximum number of posts to return. Defaults to 20. + + Returns: + list: List of posts before the specified timestamp. + """ + try: + cursor = ( + self.collection.find({"timestamp": {"$lt": timestamp}}) + .sort("timestamp", pymongo.DESCENDING) + .limit(limit) + ) + + posts = list(cursor) + posts.reverse() # Reverse to maintain ascending order + return posts + except Exception as e: + print(f"Error fetching posts before timestamp: {e}") + traceback.print_exc() + return [] + finally: + self._cleanup() def main(): + """ + Main function for starting Instagram monitoring from command line. + + Usage: + python script.py [user] [tags] [monitor_type] [product_id] + + All arguments are optional and will use default values if not provided. + """ + # Use command line arguments or default values + user = sys.argv[1] if len(sys.argv) > 1 else "default_user" + tags = sys.argv[2] if len(sys.argv) > 2 else "python" + monitor_type = sys.argv[3] if len(sys.argv) > 3 else "hashtags" + product_id = sys.argv[4] if len(sys.argv) > 4 else "insta_monitor" + + print("Starting Instagram monitor:") + print(f" User: {user}") + print(f" Tags: {tags}") + print(f" Type: {monitor_type}") + print(f" Product ID: {product_id}") + try: - user = sys.argv[1] - tags = sys.argv[2] - type = sys.argv[3] - productId = sys.argv[4] - obj = InstaPorcessClass() - obj.startprocess(user=user, tags=tags, type=type, productId=productId) - except Exception as err: - print(f"exception : {err}") - print("error::main>>", sys.exc_info()[1]) + manager = InstaProcessManager() + manager.start_monitoring(user, tags, monitor_type, product_id) + except KeyboardInterrupt: + print("Exiting...") + sys.exit(0) + except Exception as e: + print(f"Fatal error: {e}") + traceback.print_exc() + sys.exit(1) if __name__ == "__main__": diff --git a/internet_connection_py3.py b/internet_connection_py3.py index 46ec09fdba9..b4b3084df2a 100644 --- a/internet_connection_py3.py +++ b/internet_connection_py3.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import os import urllib.request diff --git a/invisible_clock.py b/invisible_clock.py index 17f6d97b106..a2a22be204f 100644 --- a/invisible_clock.py +++ b/invisible_clock.py @@ -1,12 +1,11 @@ # Hey you need red color cloak +import time + import cv2 # superinposing two images - import numpy as np -import time - cap = cv2.VideoCapture(0) time.sleep(2) # 2 sec time to adjust cam with time diff --git a/kilo_to_miles.py b/kilo_to_miles.py index ff33cd208c5..dea08b7d8cd 100644 --- a/kilo_to_miles.py +++ b/kilo_to_miles.py @@ -1,4 +1,3 @@ -user= float(input("enter kilometers here.. ")) -miles= user*0.621371 +user = float(input("enter kilometers here.. ")) +miles = user * 0.621371 print(f"{user} kilometers equals to {miles:.2f} miles") - diff --git a/kmp_str_search.py b/kmp_str_search.py index cae439949b9..6ee108c9ca5 100644 --- a/kmp_str_search.py +++ b/kmp_str_search.py @@ -1,11 +1,11 @@ """Author Anurag Kumar(mailto:anuragkumarak95@gmail.com) - The Knuth-Morris-Pratt Algorithm for finding a pattern within a piece of te$ - with complexity O(n + m) - 1) Preprocess pattern to identify any suffixes that are identical to prefix$ - This tells us where to continue from if we get a mismatch between a cha$ - and the text. - 2) Step through the text one character at a time and compare it to a charac$ - updating our location within the pattern if necessary +The Knuth-Morris-Pratt Algorithm for finding a pattern within a piece of te$ +with complexity O(n + m) +1) Preprocess pattern to identify any suffixes that are identical to prefix$ + This tells us where to continue from if we get a mismatch between a cha$ + and the text. +2) Step through the text one character at a time and compare it to a charac$ + updating our location within the pattern if necessary """ diff --git a/large_files_reading.py b/large_files_reading.py index a5ce0936f8a..b7b2a19faac 100644 --- a/large_files_reading.py +++ b/large_files_reading.py @@ -1,4 +1,6 @@ -with open("new_project.txt", "r" , encoding="utf-8") as file: # replace "largefile.text" with your actual file name or with absoulte path -# encoding = "utf-8" is especially used when the file contains special characters.... +with open( + "new_project.txt", encoding="utf-8" +) as file: # replace "largefile.text" with your actual file name or with absoulte path + # encoding = "utf-8" is especially used when the file contains special characters.... for f in file: print(f.strip()) diff --git a/largestno.py b/largestno.py index 0edc35dbe01..53934770163 100644 --- a/largestno.py +++ b/largestno.py @@ -1,7 +1,7 @@ # Python Program to find Largest of two Numbers using if-else statements a = int(input("Enter the first number: ")) b = int(input("Enter the second number: ")) -if(a >= b): - print(a, "is greater") +if a >= b: + print(a, "is greater") else: - print(b, "is greater") + print(b, "is greater") diff --git a/lcm.py b/lcm.py index c2d5b9731cc..2f0bcf14509 100644 --- a/lcm.py +++ b/lcm.py @@ -1,30 +1,30 @@ def lcm(x, y): """ - Find least common multiple of 2 positive integers. - :param x: int - first integer - :param y: int - second integer - :return: int - least common multiple + Find least common multiple of 2 positive integers. + :param x: int - first integer + :param y: int - second integer + :return: int - least common multiple - >>> lcm(8, 4) - 8 - >>> lcm(5, 3) - 15 - >>> lcm(15, 9) - 45 - >>> lcm(124, 23) - 2852 - >>> lcm(3, 6) - 6 - >>> lcm(13, 34) - 442 - >>> lcm(235, 745) - 35015 - >>> lcm(65, 86) - 5590 - >>> lcm(0, 1) - -1 - >>> lcm(-12, 35) - -1 + >>> lcm(8, 4) + 8 + >>> lcm(5, 3) + 15 + >>> lcm(15, 9) + 45 + >>> lcm(124, 23) + 2852 + >>> lcm(3, 6) + 6 + >>> lcm(13, 34) + 442 + >>> lcm(235, 745) + 35015 + >>> lcm(65, 86) + 5590 + >>> lcm(0, 1) + -1 + >>> lcm(-12, 35) + -1 """ if x <= 0 or y <= 0: return -1 diff --git a/leap year.py b/leap year.py index 1e7739189a4..bacbb09c1c2 100644 --- a/leap year.py +++ b/leap year.py @@ -6,12 +6,12 @@ # year = int(input("Enter a year: ")) if (year % 4) == 0: - if (year % 100) == 0: - if (year % 400) == 0: - print("{0} is a leap year".format(year)) - else: - print("{0} is not a leap year".format(year)) - else: - print("{0} is a leap year".format(year)) + if (year % 100) == 0: + if (year % 400) == 0: + print(f"{year} is a leap year") + else: + print(f"{year} is not a leap year") + else: + print(f"{year} is a leap year") else: - print("{0} is not a leap year".format(year)) + print(f"{year} is not a leap year") diff --git a/levenshtein_distance.py b/levenshtein_distance.py index 1dde234f490..11cbb2c9dad 100644 --- a/levenshtein_distance.py +++ b/levenshtein_distance.py @@ -1,5 +1,4 @@ def levenshtein_dis(wordA, wordB): - wordA = wordA.lower() # making the wordA lower case wordB = wordB.lower() # making the wordB lower case diff --git a/linear search.py b/linear search.py index 781894f7b47..b1bda494a43 100644 --- a/linear search.py +++ b/linear search.py @@ -1,10 +1,13 @@ -#Author : ShankRoy +# Author : ShankRoy + def linearsearch(arr, x): - for i in range(len(arr)): - if arr[i] == x: - return i - return -1 -arr = ['t','u','t','o','r','i','a','l'] -x = 'a' -print("element found at index "+str(linearsearch(arr,x))) + for i in range(len(arr)): + if arr[i] == x: + return i + return -1 + + +arr = ["t", "u", "t", "o", "r", "i", "a", "l"] +x = "a" +print("element found at index " + str(linearsearch(arr, x))) diff --git a/linear-algebra-python/src/lib.py b/linear-algebra-python/src/lib.py index 9719d915bd2..a9cf536e6ad 100644 --- a/linear-algebra-python/src/lib.py +++ b/linear-algebra-python/src/lib.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Created on Mon Feb 26 14:29:11 2018 @@ -24,7 +23,7 @@ import random -class Vector(object): +class Vector: """ This class represents a vector of arbitray size. You need to give the vector components. @@ -100,7 +99,7 @@ def eulidLength(self): """ summe = 0 for c in self.__components: - summe += c ** 2 + summe += c**2 return math.sqrt(summe) def __add__(self, other): @@ -185,7 +184,7 @@ def __eq__(self, other): """ ans = True SIZE = self.size() - if SIZE == other.size(): + if other.size() == SIZE: for i in range(SIZE): if self.__components[i] != other.component(i): ans = False @@ -252,7 +251,7 @@ def randomVector(N, a, b): return ans -class Matrix(object): +class Matrix: """ class: Matrix This class represents a arbitrary matrix. diff --git a/linear-algebra-python/src/tests.py b/linear-algebra-python/src/tests.py index 38e4a627c2d..00f6b6719b7 100644 --- a/linear-algebra-python/src/tests.py +++ b/linear-algebra-python/src/tests.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Created on Mon Feb 26 15:40:07 2018 @@ -154,7 +153,7 @@ def test_squareZeroMatrix(self): def test_norm_vector(self): x = Vector([1, 2, 3]) self.assertAlmostEqual(x.norm().component(0), (1 / math.sqrt(14)), 0.001) - self.assertAlmostEqual(x.norm().component(1), math.sqrt((2.0 / 7)), 0.001) + self.assertAlmostEqual(x.norm().component(1), math.sqrt(2.0 / 7), 0.001) def test__eq__vector(self): x = Vector([1, 2, 3]) diff --git a/linear_search.py b/linear_search.py index a4cb39f9cdb..0a005cbcfe2 100644 --- a/linear_search.py +++ b/linear_search.py @@ -8,4 +8,4 @@ print(f"\n{x} found at position {position}") else: print(f"list: {list}") - print(f"{x} is not in list") \ No newline at end of file + print(f"{x} is not in list") diff --git a/loader.py b/loader.py index 7ce80fef603..faf30df7f72 100644 --- a/loader.py +++ b/loader.py @@ -1,14 +1,14 @@ """ -Shaurya Pratap Singh +Shaurya Pratap Singh @shaurya-blip Shows loading message while doing something. """ import itertools +import sys import threading import time -import sys # The task is not done right now done = False diff --git a/local_weighted_learning/local_weighted_learning.py b/local_weighted_learning/local_weighted_learning.py index a3a911c4306..8ab2fca9f9c 100644 --- a/local_weighted_learning/local_weighted_learning.py +++ b/local_weighted_learning/local_weighted_learning.py @@ -4,7 +4,9 @@ # weighted matrix -def weighted_matrix(point: np.mat, training_data_x: np.mat, bandwidth: float) -> np.mat: +def weighted_matrix( + point: np.asmatrix, training_data_x: np.asmatrix, bandwidth: float +) -> np.asmatrix: """ Calculate the weight for every point in the data set. It takes training_point , query_point, and tau @@ -16,17 +18,20 @@ def weighted_matrix(point: np.mat, training_data_x: np.mat, bandwidth: float) -> # m is the number of training samples m, n = np.shape(training_data_x) # Initializing weights as identity matrix - weights = np.mat(np.eye((m))) + weights = np.asmatrix(np.eye(m)) # calculating weights for all training examples [x(i)'s] for j in range(m): diff = point - training_data[j] - weights[j, j] = np.exp(diff * diff.T / (-2.0 * bandwidth ** 2)) + weights[j, j] = np.exp(diff * diff.T / (-2.0 * bandwidth**2)) return weights def local_weight( - point: np.mat, training_data_x: np.mat, training_data_y: np.mat, bandwidth: float -) -> np.mat: + point: np.asmatrix, + training_data_x: np.asmatrix, + training_data_y: np.asmatrix, + bandwidth: float, +) -> np.asmatrix: """ Calculate the local weights using the weight_matrix function on training data. Return the weighted matrix. @@ -39,8 +44,8 @@ def local_weight( def local_weight_regression( - training_data_x: np.mat, training_data_y: np.mat, bandwidth: float -) -> np.mat: + training_data_x: np.asmatrix, training_data_y: np.asmatrix, bandwidth: float +) -> np.asmatrix: """ Calculate predictions for each data point on axis. """ @@ -55,7 +60,7 @@ def local_weight_regression( return ypred -def load_data(dataset_name: str, cola_name: str, colb_name: str) -> np.mat: +def load_data(dataset_name: str, cola_name: str, colb_name: str) -> np.asmatrix: """ Function used for loading data from the seaborn splitting into x and y points """ @@ -65,8 +70,8 @@ def load_data(dataset_name: str, cola_name: str, colb_name: str) -> np.mat: col_a = np.array(data[cola_name]) # total_bill col_b = np.array(data[colb_name]) # tip - mcol_a = np.mat(col_a) - mcol_b = np.mat(col_b) + mcol_a = np.asmatrix(col_a) + mcol_b = np.asmatrix(col_b) m = np.shape(mcol_b)[1] one = np.ones((1, m), dtype=int) @@ -77,7 +82,9 @@ def load_data(dataset_name: str, cola_name: str, colb_name: str) -> np.mat: return training_data, mcol_b, col_a, col_b -def get_preds(training_data: np.mat, mcol_b: np.mat, tau: float) -> np.ndarray: +def get_preds( + training_data: np.asmatrix, mcol_b: np.asmatrix, tau: float +) -> np.ndarray: """ Get predictions with minimum error for each training data """ @@ -86,7 +93,7 @@ def get_preds(training_data: np.mat, mcol_b: np.mat, tau: float) -> np.ndarray: def plot_preds( - training_data: np.mat, + training_data: np.asmatrix, predictions: np.ndarray, col_x: np.ndarray, col_y: np.ndarray, diff --git a/login.py b/login.py index 8095f4f4e54..d4844b261f1 100644 --- a/login.py +++ b/login.py @@ -1,6 +1,7 @@ import os from getpass import getpass + # Devloped By Black_angel # This is Logo Function def logo(): diff --git a/loops.py b/loops.py index 50d4ac6ef7b..985ffb8af4e 100644 --- a/loops.py +++ b/loops.py @@ -1,11 +1,11 @@ -# 2 loops +# 2 loops # for loop: """ Syntax.. -> "range" : starts with 0. --> The space after the space is called as identiation, python generally identifies the block of code with the help of indentation, +-> The space after the space is called as identiation, python generally identifies the block of code with the help of indentation, indentation is generally 4 spaces / 1 tab space.. @@ -13,9 +13,9 @@ statements you want to execute for in : - print() + print() To print the list / or any iterator items - + """ # 1. for with range... @@ -25,16 +25,16 @@ # 2.for with list -l1=[1,2,3,78,98,56,52] +l1 = [1, 2, 3, 78, 98, 56, 52] for i in l1: - print("list items",i) + print("list items", i) # prints list items one by one.... for i in "ABC": print(i) # while loop: -i=0 -while i<=5: +i = 0 +while i <= 5: print("hello.. with while") - i+=1 \ No newline at end of file + i += 1 diff --git a/magic8ball.py b/magic8ball.py index 816705b8e21..cd2b6b2fe19 100644 --- a/magic8ball.py +++ b/magic8ball.py @@ -1,6 +1,7 @@ import random -from colorama import Fore, Style + import inquirer +from colorama import Fore, Style responses = [ "It is certain", diff --git a/magic_8_ball.py b/magic_8_ball.py index 816705b8e21..cd2b6b2fe19 100644 --- a/magic_8_ball.py +++ b/magic_8_ball.py @@ -1,6 +1,7 @@ import random -from colorama import Fore, Style + import inquirer +from colorama import Fore, Style responses = [ "It is certain", diff --git a/mapit.py b/mapit.py index 73d8666d7b7..434dde76f74 100644 --- a/mapit.py +++ b/mapit.py @@ -1,5 +1,6 @@ import sys import webbrowser + import pyperclip if len(sys.argv) > 1: diff --git a/meme_maker.py b/meme_maker.py index 7cb4b550701..01cd6596451 100644 --- a/meme_maker.py +++ b/meme_maker.py @@ -1,6 +1,6 @@ import sys -from PIL import ImageDraw, ImageFont, Image +from PIL import Image, ImageDraw, ImageFont def input_par(): diff --git a/memorygame.py b/memorygame.py index 9266a2cd54e..c63f8220438 100644 --- a/memorygame.py +++ b/memorygame.py @@ -1,5 +1,6 @@ from random import * from turtle import * + from freegames import path car = path("car.gif") diff --git a/merge.py b/merge.py index 424cf1e0527..139db69e7ff 100644 --- a/merge.py +++ b/merge.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import os # author:zhangshuyx@gmail.com @@ -28,11 +26,11 @@ def merge(): with open(resultfile, "w") as writefile: for csvfile in csvfiles: with open(csvfile) as readfile: - print("File {} readed.".format(csvfile)) + print(f"File {csvfile} readed.") # do the read and write writefile.write(readfile.read() + "\n") - print("\nFile {} wrote.".format(resultfile)) + print(f"\nFile {resultfile} wrote.") # the main program diff --git a/mobilePhoneSpecsScrapper.py b/mobilePhoneSpecsScrapper.py index fc36b1c85b3..5ac076d2d3a 100644 --- a/mobilePhoneSpecsScrapper.py +++ b/mobilePhoneSpecsScrapper.py @@ -1,11 +1,11 @@ -import requests -from bs4 import BeautifulSoup +# import time +import json # import csv import os -# import time -import json +import requests +from bs4 import BeautifulSoup class Phonearena: @@ -21,7 +21,6 @@ def __init__(self): self.absolute_path = os.getcwd().strip() + "/" + self.new_folder_name def crawl_html_page(self, sub_url): - url = sub_url # Url for html content parsing. # Handing the connection error of the url. @@ -105,7 +104,7 @@ def crawl_phones_models_specification(self, li): json.dump(phone_urls, of) # Step 2: Iterate through all the links from the above execution and run the next command - with open("obj.absolute_path+'-Phoneurls.json", "r") as inp: + with open("obj.absolute_path+'-Phoneurls.json") as inp: temp = json.load(inp) phone_specs = obj.crawl_phones_models_specification(temp) diff --git a/multiple_comditions.py b/multiple_comditions.py index 68ebd1f94e5..6da636d5288 100644 --- a/multiple_comditions.py +++ b/multiple_comditions.py @@ -5,10 +5,10 @@ print("in first if") elif user == 2: print("in second if") - elif user ==3: + elif user == 3: print("in third if") else: - print("Enter numbers b/w the range of 1-3") + print("Enter numbers b/w the range of 1-3") except: print("enter only digits") @@ -19,4 +19,4 @@ if condition, even though it's already decided that the first condition worked. This makes the program do more work than necessary. On the other hand, when you use elif, if one condition is satisfied, the program exits the rest of the conditions and doesn't continue checking. It’s more efficient and clean, as it immediately moves to the correct option without unnecessary steps. -""" \ No newline at end of file +""" diff --git a/multiplication_table.py b/multiplication_table.py index f659f4289d9..70045ed10e7 100644 --- a/multiplication_table.py +++ b/multiplication_table.py @@ -20,15 +20,15 @@ def table(rows, columns): columns = int(columns) rows = int(rows) - for r in range(1, rows+1): + for r in range(1, rows + 1): c = r - print(r, end='\t') + print(r, end="\t") i = 0 - while columns-1 > i: - print(c+r, end='\t') - c = c+r + while columns - 1 > i: + print(c + r, end="\t") + c = c + r i += 1 - print('\n') + print("\n") table(rows, columns) diff --git a/my project b/my project.py similarity index 86% rename from my project rename to my project.py index 8aed0821858..6f75e99c0a5 100644 --- a/my project +++ b/my project.py @@ -4,14 +4,17 @@ def add(x, y): return x + y + # This function subtracts two numbers def subtract(x, y): return x - y + # This function multiplies two numbers def multiply(x, y): return x * y + # This function divides two numbers def divide(x, y): return x / y @@ -28,20 +31,20 @@ def divide(x, y): choice = input("Enter choice(1/2/3/4): ") # Check if choice is one of the four options - if choice in ('1', '2', '3', '4'): + if choice in ("1", "2", "3", "4"): num1 = float(input("Enter first number: ")) num2 = float(input("Enter second number: ")) - if choice == '1': + if choice == "1": print(num1, "+", num2, "=", add(num1, num2)) - elif choice == '2': + elif choice == "2": print(num1, "-", num2, "=", subtract(num1, num2)) - elif choice == '3': + elif choice == "3": print(num1, "*", num2, "=", multiply(num1, num2)) - elif choice == '4': + elif choice == "4": print(num1, "/", num2, "=", divide(num1, num2)) break else: diff --git a/nDigitNumberCombinations.py b/nDigitNumberCombinations.py index caad36e5e8d..5a17739615d 100644 --- a/nDigitNumberCombinations.py +++ b/nDigitNumberCombinations.py @@ -1,7 +1,7 @@ # ALL the combinations of n digit combo def nDigitCombinations(n): try: - npow = 10 ** n + npow = 10**n numbers = [] for code in range(npow): code = str(code).zfill(n) diff --git a/nasa_apod_with_requests/run.py b/nasa_apod_with_requests/run.py index 4d8048d022c..4cb95bbff14 100644 --- a/nasa_apod_with_requests/run.py +++ b/nasa_apod_with_requests/run.py @@ -1,7 +1,8 @@ -from settings import key -import requests import os +import requests +from settings import key + date = input("Enter date(YYYY-MM-DD): ") r = requests.get(f"https://api.nasa.gov/planetary/apod?api_key={key}&date={date}") parsed = r.json() diff --git a/new_pattern.py b/new_pattern.py index 6c5120eb586..f96cb1f49f0 100644 --- a/new_pattern.py +++ b/new_pattern.py @@ -1,25 +1,28 @@ -#pattern -#@@@@@@@@ $ -#@@@@@@@ $$ -#@@@@@@ $$$ -#@@@@@ $$$$ -#@@@@ $$$$$ -#@@@ $$$$$$ -#@@ $$$$$$$ -#@ $$$$$$$$ +# pattern +# @@@@@@@@ $ +# @@@@@@@ $$ +# @@@@@@ $$$ +# @@@@@ $$$$ +# @@@@ $$$$$ +# @@@ $$$$$$ +# @@ $$$$$$$ +# @ $$$$$$$$ + def main(): lines = int(input("Enter no.of lines: ")) pattern(lines) -def pattern(lines): - t = 1 - for i in range(lines,0,-1): - nxt_pattern = "$"*t - pattern = "@"*(i) - final_pattern = pattern + " " + nxt_pattern - print(final_pattern) - t = t +1 + +def pattern(lines): + t = 1 + for i in range(lines, 0, -1): + nxt_pattern = "$" * t + pattern = "@" * (i) + final_pattern = pattern + " " + nxt_pattern + print(final_pattern) + t = t + 1 + if __name__ == "__main__": main() diff --git a/new_script.py b/new_script.py index 7326bed8c4e..044732ae7d8 100644 --- a/new_script.py +++ b/new_script.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import datetime # Load the library module import os # Load the library module import sys # Load the library module @@ -55,7 +53,7 @@ if not (os.path.exists(outputdir)): os.mkdir(outputdir) newscript = open(script, "w") -input = open(input_file, "r") +input = open(input_file) today = datetime.date.today() old_date = " Created :" new_date = " Created : " + today.strftime("%d %B %Y") diff --git a/news_articles__scraper.py b/news_articles__scraper.py index c16c4db0290..30ac439e9e6 100644 --- a/news_articles__scraper.py +++ b/news_articles__scraper.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """News_Articles__Scraper.ipynb Automatically generated by Colaboratory. @@ -54,7 +53,6 @@ fakearticle_links[1888:] - """We have to modify the links so that the links actually work as we can see that the string extracted is the last part of the url! **We have to add 'https://www.boomlive.in/fake-news' to the extracted links.** @@ -143,9 +141,7 @@ """**Scraping news from Times of India**""" -TOIarticle_links = ( - [] -) # Creating an empty list of all the urls of news from Times of India site +TOIarticle_links = [] # Creating an empty list of all the urls of news from Times of India site # Extracting links for all the pages (2 to 125) of boomlive fake news section for i in range(2, 126): diff --git a/nitkarshchourasia/to_sort/GUI_apps/tkinter_apps/simple_calc_GUI/simple_calculator_GUI.py b/nitkarshchourasia/to_sort/GUI_apps/tkinter_apps/simple_calc_GUI/simple_calculator_GUI.py index 6eddf2d6b85..0001cb98c57 100644 --- a/nitkarshchourasia/to_sort/GUI_apps/tkinter_apps/simple_calc_GUI/simple_calculator_GUI.py +++ b/nitkarshchourasia/to_sort/GUI_apps/tkinter_apps/simple_calc_GUI/simple_calculator_GUI.py @@ -4,7 +4,6 @@ # On CMD, or Terminal. import hupper - # Python program to create a simple GUI # calculator using Tkinter diff --git a/nitkarshchourasia/to_sort/JARVIS_python_bot/.vscode/settings.json b/nitkarshchourasia/to_sort/JARVIS_python_bot/.vscode/settings.json deleted file mode 100644 index 75661b5cbba..00000000000 --- a/nitkarshchourasia/to_sort/JARVIS_python_bot/.vscode/settings.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "cSpell.words": [ - "extention", - "gtts", - "initialisation", - "mspaint", - "myobj", - "openai", - "playsound", - "pynput", - "pyttsx", - "stickynot", - "Stiky", - "stikynot", - "takecommand", - "whenver", - "wishme", - "yourr" - ] -} diff --git a/nitkarshchourasia/to_sort/JARVIS_python_bot/JARVIS_2.0.py b/nitkarshchourasia/to_sort/JARVIS_python_bot/JARVIS_2.0.py index 8fae670cdca..2b7382d2e4b 100644 --- a/nitkarshchourasia/to_sort/JARVIS_python_bot/JARVIS_2.0.py +++ b/nitkarshchourasia/to_sort/JARVIS_python_bot/JARVIS_2.0.py @@ -1,129 +1,126 @@ -######### +#!/usr/bin/env python3 -__author__ = "Nitkarsh Chourasia " -__version__ = "v 0.1" - -""" -JARVIS: -- Control windows programs with your voice -""" - -# import modules -import datetime # datetime module supplies classes for manipulating dates and times -import subprocess # subprocess module allows you to spawn new processes - -# master -import pyjokes # for generating random jokes -import requests -import json -from PIL import ImageGrab -from gtts import gTTS - -# for 30 seconds clip "Jarvis, clip that!" and discord ctrl+k quick-move (might not come to fruition) -from pynput import keyboard -from pynput.keyboard import Key -from pynput.mouse import Controller -from playsound import * # for sound output - - -# master -# auto install for pyttsx3 and speechRecognition +import base64 +import datetime import os +import smtplib +import subprocess +import sys +import time +import webbrowser -try: - import pyttsx3 # Check if already installed -except: # If not installed give exception - os.system("pip install pyttsx3") # install at run time - import pyttsx3 # import again for speak function +import httpx # Replaced requests with httpx +import openai +import pyjokes +import pyttsx3 +import speech_recognition as sr +from PIL import ImageGrab +from pygame import mixer # For audio output +from pynput import keyboard, mouse -try: - import speech_recognition as sr -except: - os.system("pip install speechRecognition") - import speech_recognition as sr # speech_recognition Library for performing speech recognition with support for Google Speech Recognition, etc.. +# Configuration +__author__ = "Nitkarsh Chourasia " +__version__ = "v 0.1" -# importing the pyttsx3 library -import webbrowser -import smtplib +# Initialize pygame mixer for audio +mixer.init() +mixer.music.set_volume(1.0) -# initialisation +# Initialize text-to-speech engine engine = pyttsx3.init() voices = engine.getProperty("voices") engine.setProperty("voice", voices[0].id) engine.setProperty("rate", 150) exit_jarvis = False +# Decode API key +api_key = base64.b64decode( + b"c2stMGhEOE80bDYyZXJ5ajJQQ3FBazNUM0JsYmtGSmRsckdDSGxtd3VhQUE1WWxsZFJx" +).decode("utf-8") +openai.api_key = api_key + -def speak(audio): +def speak(audio: str) -> None: + """Speak the given text using TTS engine.""" engine.say(audio) engine.runAndWait() -def speak_news(): - url = "http://newsapi.org/v2/top-headlines?sources=the-times-of-india&apiKey=yourapikey" - news = requests.get(url).text - news_dict = json.loads(news) - arts = news_dict["articles"] - speak("Source: The Times Of India") - speak("Todays Headlines are..") - for index, articles in enumerate(arts): - speak(articles["title"]) - if index == len(arts) - 1: - break - speak("Moving on the next news headline..") - speak("These were the top headlines, Have a nice day Sir!!..") - - -def sendEmail(to, content): - server = smtplib.SMTP("smtp.gmail.com", 587) - server.ehlo() - server.starttls() - server.login("youremail@gmail.com", "yourr-password-here") - server.sendmail("youremail@gmail.com", to, content) - server.close() - - -import openai -import base64 - -# Will learn it. -stab = base64.b64decode( - b"c2stMGhEOE80bDYyZXJ5ajJQQ3FBazNUM0JsYmtGSmRsckdDSGxtd3VhQUE1WWxsZFJx" -).decode("utf-8") -api_key = stab - - -def ask_gpt3(que): - openai.api_key = api_key +def play_audio(file_path: str) -> None: + """Play audio file using pygame mixer.""" + try: + mixer.music.load(file_path) + mixer.music.play() + while mixer.music.get_busy(): + time.sleep(0.1) + except Exception as e: + print(f"Error playing audio: {e}") - response = openai.Completion.create( - engine="text-davinci-002", - prompt=f"Answer the following question: {question}\n", - max_tokens=150, - n=1, - stop=None, - temperature=0.7, - ) - answer = response.choices[0].text.strip() - return answer +async def speak_news() -> None: + """Fetch and speak top headlines from Times of India using httpx.""" + url = "http://newsapi.org/v2/top-headlines?sources=the-times-of-india&apiKey=yourapikey" + try: + async with httpx.AsyncClient() as client: + response = await client.get(url) + news_dict = response.json() + arts = news_dict["articles"] + speak("Source: The Times Of India") + speak("Today's Headlines are..") + for index, article in enumerate(arts): + speak(article["title"]) + if index < len(arts) - 1: + speak("Moving on to the next news headline..") + speak("These were the top headlines. Have a nice day, Sir!") + except Exception as e: + speak(f"Sorry, unable to fetch news. Error: {str(e)}") + + +def send_email(to: str, content: str) -> None: + """Send an email using SMTP.""" + try: + server = smtplib.SMTP("smtp.gmail.com", 587) + server.ehlo() + server.starttls() + server.login("youremail@gmail.com", "yourr-password-here") + server.sendmail("youremail@gmail.com", to, content) + server.close() + speak("Email has been sent!") + except Exception as e: + print(f"Error sending email: {e}") + speak("Sorry, I can't send the email.") + + +def ask_gpt3(question: str) -> str: + """Get response from OpenAI GPT-3.""" + try: + response = openai.Completion.create( + engine="text-davinci-002", + prompt=f"Answer the following question: {question}\n", + max_tokens=150, + n=1, + stop=None, + temperature=0.7, + ) + return response.choices[0].text.strip() + except Exception as e: + return f"Sorry, I couldn't get an answer. Error: {str(e)}" -def wishme(): - # This function wishes user +def wishme() -> None: + """Wish the user based on current time.""" hour = int(datetime.datetime.now().hour) - if hour >= 0 and hour < 12: + if 0 <= hour < 12: speak("Good Morning!") - elif hour >= 12 and hour < 18: + elif 12 <= hour < 18: speak("Good Afternoon!") else: speak("Good Evening!") - speak("I m Jarvis ! how can I help you sir") + speak("I'm Jarvis! How can I help you, sir?") -# obtain audio from the microphone -def takecommand(): - # it takes user's command and returns string output +def takecommand() -> str: + """Listen to user's voice command and return as text.""" wishme() r = sr.Recognizer() with sr.Microphone() as source: @@ -134,201 +131,174 @@ def takecommand(): try: print("Recognizing...") query = r.recognize_google(audio, language="en-in") - print(f"User said {query}\n") - except Exception: - print("Say that again please...") + print(f"User said: {query}\n") + return query.lower() + except Exception as e: + print(f"Error recognizing speech: {e}") + speak("Say that again please...") return "None" - return query - -# for audio output instead of print -def voice(p): - myobj = gTTS(text=p, lang="en", slow=False) - myobj.save("try.mp3") - playsound("try.mp3") +def voice(text: str) -> None: + """Convert text to speech and play using pygame.""" + try: + from gtts import gTTS -# recognize speech using Google Speech Recognition + myobj = gTTS(text=text, lang="en", slow=False) + myobj.save("try.mp3") + play_audio("try.mp3") + os.remove("try.mp3") # Cleanup + except Exception as e: + print(f"Error in text-to-speech: {e}") + speak(text) # Fallback to pyttsx3 def on_press(key): + """Handle key press events for listeners.""" if key == keyboard.Key.esc: - return False # stop listener + return False # Stop listener try: - k = key.char # single-char keys + k = key.char # Single-char keys except: - k = key.name # other keys - if k in ["1", "2", "left", "right"]: # keys of interest - # self.keys.append(k) # store it in global-like variable + k = key.name # Other keys + if k in ["1", "2", "left", "right"]: print("Key pressed: " + k) - return False # stop listener; remove this if want more keys + return False # Stop listener -# Run Application with Voice Command Function -# only_jarvis def on_release(key): - print("{0} release".format(key)) - if key == Key.esc(): - # Stop listener - return False - """ -class Jarvis: - def __init__(self, Q): - self.query = Q - - def sub_call(self, exe_file): - ''' - This method can directly use call method of subprocess module and according to the - argument(exe_file) passed it returns the output. - - exe_file:- must pass the exe file name as str object type. - - ''' - return subprocess.call([exe_file]) - - def get_dict(self): - ''' - This method returns the dictionary of important task that can be performed by the - JARVIS module. - - Later on this can also be used by the user itself to add or update their preferred apps. - ''' - _dict = dict( - time=datetime.now(), - notepad='Notepad.exe', - calculator='calc.exe', - stickynot='StickyNot.exe', - shell='powershell.exe', - paint='mspaint.exe', - cmd='cmd.exe', - browser='C:\\Program Files\\Internet Explorer\\iexplore.exe', - ) - return _dict - - @property - def get_app(self): - task_dict = self.get_dict() - task = task_dict.get(self.query, None) - if task is None: - engine.say("Sorry Try Again") - engine.runAndWait() - else: - if 'exe' in str(task): - return self.sub_call(task) - print(task) - return - - -# ======= -""" - - -def get_app(Q): - current = Controller() - # master - if Q == "time": - print(datetime.now()) - x = datetime.now() - voice(x) - elif Q == "news": - speak_news() - - elif Q == "open notepad": + """Handle key release events for listeners.""" + print(f"{key} released") + if key == keyboard.Key.esc: + return False # Stop listener + + +def get_app(query: str) -> None: + """Execute actions based on user command.""" + mouse_controller = mouse.Controller() + + if query == "time": + current_time = datetime.datetime.now().strftime("%H:%M:%S") + print(current_time) + voice(current_time) + + elif query == "news": + import asyncio + + asyncio.run(speak_news()) + + elif query == "open notepad": subprocess.call(["Notepad.exe"]) - elif Q == "open calculator": + + elif query == "open calculator": subprocess.call(["calc.exe"]) - elif Q == "open stikynot": + + elif query == "open stikynot": subprocess.call(["StikyNot.exe"]) - elif Q == "open shell": + + elif query == "open shell": subprocess.call(["powershell.exe"]) - elif Q == "open paint": + + elif query == "open paint": subprocess.call(["mspaint.exe"]) - elif Q == "open cmd": + + elif query == "open cmd": subprocess.call(["cmd.exe"]) - elif Q == "open discord": + + elif query == "open discord": subprocess.call(["discord.exe"]) - elif Q == "open browser": + + elif query == "open browser": subprocess.call(["C:\\Program Files\\Internet Explorer\\iexplore.exe"]) - # patch-1 - elif Q == "open youtube": - webbrowser.open("https://www.youtube.com/") # open youtube - elif Q == "open google": - webbrowser.open("https://www.google.com/") # open google - elif Q == "open github": + + elif query == "open youtube": + webbrowser.open("https://www.youtube.com/") + + elif query == "open google": + webbrowser.open("https://www.google.com/") + + elif query == "open github": webbrowser.open("https://github.com/") - elif Q == "search for": - que = Q.lstrip("search for") - answer = ask_gpt3(que) - elif ( - Q == "email to other" - ): # here you want to change and input your mail and password whenver you implement + elif query.startswith("search for"): + question = query.replace("search for", "").strip() + answer = ask_gpt3(question) + print(answer) + speak(answer) + + elif query == "email to other": try: speak("What should I say?") - r = sr.Recognizer() - with sr.Microphone() as source: - print("Listening...") - r.pause_threshold = 1 - audio = r.listen(source) + content = takecommand() to = "abc@gmail.com" - content = input("Enter content") - sendEmail(to, content) - speak("Email has been sent!") + send_email(to, content) except Exception as e: - print(e) + print(f"Error: {e}") speak("Sorry, I can't send the email.") - # ======= - # master - elif Q == "Take screenshot": - snapshot = ImageGrab.grab() - drive_letter = "C:\\" - folder_name = r"downloaded-files" - folder_time = datetime.datetime.now().strftime("%Y-%m-%d_%I-%M-%S_%p") - extention = ".jpg" - folder_to_save_files = drive_letter + folder_name + folder_time + extention - snapshot.save(folder_to_save_files) - - elif Q == "Jokes": - speak(pyjokes.get_joke()) - - elif Q == "start recording": - current.add("Win", "Alt", "r") - speak("Started recording. just say stop recording to stop.") - - elif Q == "stop recording": - current.add("Win", "Alt", "r") - speak("Stopped recording. check your game bar folder for the video") - - elif Q == "clip that": - current.add("Win", "Alt", "g") - speak("Clipped. check you game bar file for the video") - with keyboard.Listener(on_press=on_press, on_release=on_release) as listener: - listener.join() - elif Q == "take a break": - exit() - else: - answer = ask_gpt3(Q) - # master + elif query == "take screenshot": + try: + snapshot = ImageGrab.grab() + folder_name = r"C:\downloaded-files" + if not os.path.exists(folder_name): + os.makedirs(folder_name) + file_name = datetime.datetime.now().strftime("%Y-%m-%d_%I-%M-%S_%p.jpg") + file_path = os.path.join(folder_name, file_name) + snapshot.save(file_path) + speak("Screenshot saved successfully.") + except Exception as e: + print(f"Error taking screenshot: {e}") + speak("Sorry, I couldn't take the screenshot.") - apps = { - "time": datetime.datetime.now(), - "notepad": "Notepad.exe", - "calculator": "calc.exe", - "stikynot": "StikyNot.exe", - "shell": "powershell.exe", - "paint": "mspaint.exe", - "cmd": "cmd.exe", - "browser": "C:\\Program Files\Internet Explorer\iexplore.exe", - "vscode": "C:\\Users\\Users\\User\\AppData\\Local\\Programs\Microsoft VS Code", - } - # master + elif query == "jokes": + joke = pyjokes.get_joke() + print(joke) + speak(joke) + elif query == "start recording": + # Simulate key press (not actual implementation) + speak("Started recording. Say 'stop recording' to stop.") + + elif query == "stop recording": + # Simulate key press (not actual implementation) + speak("Stopped recording. Check your game bar folder for the video.") + + elif query == "clip that": + # Simulate key press (not actual implementation) + speak("Clipped. Check your game bar folder for the video.") + + elif query == "take a break": + speak("Okay, I'm taking a break. Call me anytime!") + global exit_jarvis + exit_jarvis = True + + else: + answer = ask_gpt3(query) + print(answer) + speak(answer) -# Call get_app(Query) Func. if __name__ == "__main__": + print(f"JARVIS v{__version__} by {__author__}") + print("Starting...") + + # Check dependencies + try: + import httpx + import openai + import pygame + import pyttsx3 + import speech_recognition as sr + from PIL import ImageGrab + except ImportError as e: + print(f"Missing dependency: {e}. Please install required packages.") + sys.exit(1) + + # Main loop while not exit_jarvis: - Query = takecommand().lower() - get_app(Query) - exit_jarvis = True + query = takecommand() + if query != "none": + get_app(query) + + print("Exiting JARVIS...") + mixer.quit() diff --git a/nitkarshchourasia/to_sort/JARVIS_python_bot/check_internet_con.py b/nitkarshchourasia/to_sort/JARVIS_python_bot/check_internet_con.py index a24c23608f2..cd2f87bfbe2 100644 --- a/nitkarshchourasia/to_sort/JARVIS_python_bot/check_internet_con.py +++ b/nitkarshchourasia/to_sort/JARVIS_python_bot/check_internet_con.py @@ -1,32 +1,34 @@ -from sys import argv +#!/usr/bin/env python3 -try: - # For Python 3.0 and later - from urllib.error import URLError - from urllib.request import urlopen -except ImportError: - # Fall back to Python 2's urllib2 - from urllib2 import URLError, urlopen +import sys +from urllib.error import URLError +from urllib.request import urlopen -def checkInternetConnectivity(): +def check_internet_connectivity() -> None: + """ + Check internet connectivity by attempting to reach a specified URL. + Uses google.com as fallback if no URL is provided. + """ try: - url = argv[1] - print(url) - protocols = ["https://", "http://"] - if not any(x for x in protocols if x in url): + # Get URL from command-line argument or use default + url = sys.argv[1] if len(sys.argv) > 1 else "https://google.com" + + # Ensure URL starts with a protocol + if not any(url.startswith(p) for p in ["https://", "http://"]): url = "https://" + url - print("URL:" + url) - except BaseException: - url = "https://google.com" - try: + + print(f"Checking URL: {url}") + + # Attempt connection with 2-second timeout urlopen(url, timeout=2) print(f'Connection to "{url}" is working') - except URLError as E: - print("Connection error:%s" % E.reason) - + except URLError as e: + print(f"Connection error: {e.reason}") + except Exception as e: + print(f"An unexpected error occurred: {e}") -checkInternetConnectivity() -# This can be implemented in Jarvis.py +if __name__ == "__main__": + check_internet_connectivity() diff --git a/nitkarshchourasia/to_sort/JARVIS_python_bot/features_to_add.py b/nitkarshchourasia/to_sort/JARVIS_python_bot/features_to_add.py index 129fba0bbd2..3de606fcfde 100644 --- a/nitkarshchourasia/to_sort/JARVIS_python_bot/features_to_add.py +++ b/nitkarshchourasia/to_sort/JARVIS_python_bot/features_to_add.py @@ -1,15 +1,35 @@ -# imports modules +#!/usr/bin/env python3 + import time from getpass import getuser -# user puts in their name -name = getuser() -name_check = input("Is your name " + name + "? → ") -if name_check.lower().startswith("y"): - print("Okay.") - time.sleep(1) -if name_check.lower().startswith("n"): - name = input("Then what is it? → ") +def get_user_name() -> str: + """ + Ask the user for their name, using the system username as a suggestion. + Handles edge cases and ensures a non-empty name is returned. + """ + system_username = getuser() + + while True: + name_check = input(f"Is your name {system_username}? → ").strip().lower() + + if name_check.startswith("y"): + print("Okay.") + time.sleep(0.5) # Shorter delay for better UX + return system_username + + elif name_check.startswith("n"): + while True: + custom_name = input("Then what is it? → ").strip() + if custom_name: # Ensure non-empty name + return custom_name + print("Please enter a valid name.") + + else: + print("Please answer with 'yes' or 'no'.") + -# Can add this feature to the Jarvis. +if __name__ == "__main__": + user_name = get_user_name() + print(f"Nice to meet you, {user_name}!") # Optional confirmation diff --git a/nitkarshchourasia/to_sort/JARVIS_python_bot/requirements.txt b/nitkarshchourasia/to_sort/JARVIS_python_bot/requirements.txt deleted file mode 100644 index 72d21dc0311..00000000000 --- a/nitkarshchourasia/to_sort/JARVIS_python_bot/requirements.txt +++ /dev/null @@ -1,15 +0,0 @@ -datetime -pyjokes -requests -Pillow -Image -ImageGrab -gTTS -keyboard -key -playsound -pyttsx3 -SpeechRecognition -openai -pynput -pyaudio diff --git a/nitkarshchourasia/to_sort/determine_sign.py b/nitkarshchourasia/to_sort/determine_sign.py index 0bca22148a3..a9698af118b 100644 --- a/nitkarshchourasia/to_sort/determine_sign.py +++ b/nitkarshchourasia/to_sort/determine_sign.py @@ -1,46 +1,71 @@ from word2number import w2n -# ? word2number then w2n then .word_to_num? So, library(bunch of modules) then module then method(function)???! -# return w2n.word_to_num(input_value) - - -# TODO: Instead of rounding at the destination, round at the source. -# Reason: As per the program need, I don't want a functionality to round or not round the number, based on the requirement, I always want to round the number. -#! Will see it tomorrow. - class DetermineSign: - def __init__(self, num=None): + def __init__(self, num: str | float | None = None) -> None: + """ + Initialize with a number or prompt user input. + + Args: + num: A number (float/int) or string representation (e.g., "5" or "five"). + """ if num is None: - self.get_number() + self.num = self._get_valid_number() else: - self.num = round(self.convert_to_float(num), 1) + self.num = self._convert_to_float(num) + self.num = round(self.num, 1) # Single rounding at initialization + + def _convert_to_float(self, input_value: str | float) -> float: + """ + Convert input to float, handling both numeric strings and word representations. + + Args: + input_value: A string (e.g., "5", "five") or numeric value. - # TODO: Word2number + Returns: + The float representation. + + Raises: + ValueError: If input cannot be converted to a valid number. + """ + if isinstance(input_value, (int, float)): + return float(input_value) - # Need to further understand this. - # ? NEED TO UNDERSTAND THIS. FOR SURETY. - def convert_to_float(self, input_value): try: + # Handle numeric strings (e.g., "5.5") return float(input_value) except ValueError: try: - return w2n.word_to_num(input_value) - except ValueError: + # Handle word representations (e.g., "five point five") + # Replace "point" with decimal separator for word2number + if "point" in input_value.lower(): + parts = input_value.lower().split("point") + integer_part = w2n.word_to_num(parts[0].strip()) + decimal_part = w2n.word_to_num(parts[1].strip()) + return float(f"{integer_part}.{decimal_part}") + else: + return float(w2n.word_to_num(input_value)) + except (ValueError, TypeError): raise ValueError( - "Invalid input. Please enter a number or a word representing a number." + f"Invalid input: '{input_value}'. Please enter a valid number or word." ) - # Now use this in other methods. + def _get_valid_number(self) -> float: + """ + Prompt user for input until a valid number is provided. - def get_number(self): - self.input_value = format(float(input("Enter a number: ")), ".1f") - self.num = round(self.convert_to_float(self.input_value), 1) - return self.num - # Do I want to return the self.num? - # I think I have to just store it as it is. + Returns: + A validated float. + """ + while True: + user_input = input("Enter a number: ").strip() + try: + return self._convert_to_float(user_input) + except ValueError as e: + print(f"Error: {e}. Try again.") - def determine_sign(self): + def determine_sign(self) -> str: + """Determine if the number is positive, negative, or zero.""" if self.num > 0: return "Positive number" elif self.num < 0: @@ -48,13 +73,10 @@ def determine_sign(self): else: return "Zero" - def __repr__(self): + def __repr__(self) -> str: return f"Number: {self.num}, Sign: {self.determine_sign()}" if __name__ == "__main__": number1 = DetermineSign() - print(number1.determine_sign()) - - -# !Incomplete. + print(f"The number is {number1.determine_sign()}") diff --git a/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/manage.py b/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/manage.py index 5f76663dd2c..d456ef2cbd1 100644 --- a/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/manage.py +++ b/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/manage.py @@ -1,5 +1,6 @@ #!/usr/bin/env python """Django's command-line utility for administrative tasks.""" + import os import sys diff --git a/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/admin.py b/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/admin.py index bc4a2a3d232..dd4406a38fa 100644 --- a/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/admin.py +++ b/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/admin.py @@ -1,4 +1,5 @@ from django.contrib import admin + from .models import Todo # Register your models here. diff --git a/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/forms.py b/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/forms.py index 11fda28ba07..3727e6d56c0 100644 --- a/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/forms.py +++ b/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/forms.py @@ -1,4 +1,5 @@ from django import forms + from .models import Todo diff --git a/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/migrations/0001_initial.py b/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/migrations/0001_initial.py index 71ce3e8d531..4858378d224 100644 --- a/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/migrations/0001_initial.py +++ b/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/migrations/0001_initial.py @@ -1,7 +1,7 @@ # Generated by Django 4.2.5 on 2023-09-30 16:11 -from django.db import migrations, models import django.utils.timezone +from django.db import migrations, models class Migration(migrations.Migration): diff --git a/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/tests.py b/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/tests.py index 49290204899..a39b155ac3e 100644 --- a/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/tests.py +++ b/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/tests.py @@ -1,2 +1 @@ - # Create your tests here. diff --git a/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/views.py b/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/views.py index 931228df1ec..5365c94eb94 100644 --- a/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/views.py +++ b/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo/views.py @@ -1,10 +1,8 @@ -from django.shortcuts import render, redirect from django.contrib import messages +from django.shortcuts import redirect, render # Create your views here. - # Import todo form and models - from .forms import TodoForm from .models import Todo @@ -28,6 +26,7 @@ def index(request): ### Function to remove item, it receives todo item_id as primary key from url ## + def remove(request, item_id): item = Todo.objects.get(id=item_id) item.delete() diff --git a/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo_site/urls.py b/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo_site/urls.py index 226e326827f..1c0e6458be6 100644 --- a/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo_site/urls.py +++ b/nitkarshchourasia/to_sort/django_projects/ToDo_webapp/todo_site/urls.py @@ -14,6 +14,7 @@ 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ + from django.contrib import admin from django.urls import path from todo import views diff --git a/nitkarshchourasia/to_sort/one_rep_max_calculator/one_rep_max_calculator.py b/nitkarshchourasia/to_sort/one_rep_max_calculator/one_rep_max_calculator.py index fdf8460fe79..f7653bc0a5f 100644 --- a/nitkarshchourasia/to_sort/one_rep_max_calculator/one_rep_max_calculator.py +++ b/nitkarshchourasia/to_sort/one_rep_max_calculator/one_rep_max_calculator.py @@ -3,38 +3,70 @@ class OneRepMaxCalculator: A class to calculate the one-repetition maximum (1RM) for a weightlifting exercise. """ - def __init__(self): + def __init__(self) -> None: """ Initializes the OneRepMaxCalculator with default values. """ - self.weight_lifted = 0 - self.reps_performed = 0 + self.weight_lifted: int = 0 + self.reps_performed: int = 0 + self.formulas = { + "epley": lambda w, r: w * (1 + r * 0.0333), + "brzycki": lambda w, r: w / (1.0278 - 0.0278 * r), + "lombardi": lambda w, r: w * (r**0.1), + "mayhew": lambda w, r: (100 * w) + / (52.2 + 41.9 * (2.71828 ** (-0.055 * r))), + } - def get_user_input(self): + def get_user_input(self) -> None: """ Prompts the user to enter the weight lifted and the number of reps performed. + Validates inputs to ensure they are positive integers. """ - self.weight_lifted = int(input("Enter the weight you lifted (in kg): ")) - self.reps_performed = int(input("Enter the number of reps you performed: ")) + while True: + try: + self.weight_lifted = int(input("Enter the weight you lifted (in kg): ")) + self.reps_performed = int( + input("Enter the number of reps you performed: ") + ) + if self.weight_lifted <= 0 or self.reps_performed <= 0: + raise ValueError("Weight and reps must be positive numbers.") + break + except ValueError as e: + print(f"Error: {e}. Please try again.") - def calculate_one_rep_max(self): + def calculate_one_rep_max(self, formula: str = "epley") -> float: """ - Calculates the one-rep max based on the Epley formula. + Calculates the one-rep max using the specified formula. + + Args: + formula: The name of the formula to use (default: "epley"). + + Returns: + The estimated one-rep max weight in kilograms. """ - return (self.weight_lifted * self.reps_performed * 0.0333) + self.weight_lifted + if formula not in self.formulas: + raise ValueError( + f"Invalid formula. Available options: {', '.join(self.formulas.keys())}" + ) + return self.formulas[formula](self.weight_lifted, self.reps_performed) - def display_one_rep_max(self): + def display_one_rep_max(self, formula: str = "epley") -> None: """ - Displays the calculated one-rep max. + Displays the calculated one-rep max with two decimal places. + + Args: + formula: The name of the formula to use (default: "epley"). """ - one_rep_max = self.calculate_one_rep_max() - print(f"Your estimated one-rep max (1RM) is: {one_rep_max} kg") + one_rep_max = self.calculate_one_rep_max(formula) + print( + f"Your estimated one-rep max (1RM) using {formula.title()} formula is: {one_rep_max:.2f} kg" + ) -def main(): +def main() -> None: """ The main function that creates an instance of OneRepMaxCalculator and uses it to get user input, - calculate the one-rep max, and display the result. + calculate the one-rep max using the Epley formula, and display the result. """ calculator = OneRepMaxCalculator() calculator.get_user_input() diff --git a/nitkarshchourasia/to_sort/one_rep_max_calculator/one_rep_max_calculator_gui.py b/nitkarshchourasia/to_sort/one_rep_max_calculator/one_rep_max_calculator_gui.py index 7189401b2e5..7c3867b58c5 100644 --- a/nitkarshchourasia/to_sort/one_rep_max_calculator/one_rep_max_calculator_gui.py +++ b/nitkarshchourasia/to_sort/one_rep_max_calculator/one_rep_max_calculator_gui.py @@ -1,75 +1,364 @@ import tkinter as tk +from tkinter import messagebox, ttk class OneRepMaxCalculator: """ - A class used to calculate the estimated one-repetition maximum (1RM) for a weightlifting exercise. - - Attributes - ---------- - window : tk.Tk - The main window of the application. - weight_entry : tk.Entry - Entry field to input the weight lifted. - rep_entry : tk.Entry - Entry field to input the number of reps performed. - result_value_label : tk.Label - Label to display the calculated 1RM. - - Methods - ------- - calculate_1rm(): - Calculates the estimated 1RM based on the Epley formula. - display_result(): - Displays the calculated 1RM in the application window. - run(): - Runs the application. + A GUI application to calculate the estimated one-repetition maximum (1RM) + using multiple formulas with dark/light mode support. """ - def __init__(self): - """Initializes the OneRepMaxCalculator with a window and widgets.""" + def __init__(self) -> None: + """Initialize the calculator with dark mode as default.""" self.window = tk.Tk() self.window.title("One-Rep Max Calculator") - self.window.geometry("300x150") + self.window.geometry("450x300") + self.is_dark_mode = True - # Create and pack widgets - tk.Label(self.window, text="Enter the weight you lifted (in kg):").pack() - self.weight_entry = tk.Entry(self.window) - self.weight_entry.pack() + # Configure fonts + self.default_font = ("Arial", 12) + self.title_font = ("Arial", 16, "bold") + self.button_font = ("Arial", 12, "bold") - tk.Label(self.window, text="Enter the number of reps you performed:").pack() - self.rep_entry = tk.Entry(self.window) - self.rep_entry.pack() + # Available 1RM formulas + self.formulas = { + "Epley": lambda w, r: w * (1 + r * 0.0333), + "Brzycki": lambda w, r: w / (1.0278 - 0.0278 * r), + "Lombardi": lambda w, r: w * (r**0.1), + "Mayhew": lambda w, r: (100 * w) + / (52.2 + 41.9 * (2.71828 ** (-0.055 * r))), + } - tk.Button(self.window, text="Calculate", command=self.display_result).pack() + # Apply dark mode initially + self.apply_dark_mode() - tk.Label(self.window, text="Your estimated one-rep max (1RM):").pack() - self.result_value_label = tk.Label(self.window) - self.result_value_label.pack() + # Create widgets + self.create_widgets() - def calculate_1rm(self): - """Calculates and returns the estimated 1RM.""" - weight = int(self.weight_entry.get()) - reps = int(self.rep_entry.get()) - return (weight * reps * 0.0333) + weight + def create_widgets(self) -> None: + """Create and layout GUI widgets with validation checks.""" + # Title + title_label = tk.Label( + self.window, + text="One-Rep Max Calculator", + font=self.title_font, + bg=self.bg_color, + fg=self.text_color, + ) + title_label.pack(pady=10) - def display_result(self): - """Calculates the 1RM and updates result_value_label with it.""" - one_rep_max = self.calculate_1rm() - self.result_value_label.config(text=f"{one_rep_max} kg") + # Weight input with validation + weight_frame = tk.Frame(self.window, bg=self.bg_color) + weight_frame.pack(fill=tk.X, padx=20, pady=5) - def run(self): - """Runs the Tkinter event loop.""" + tk.Label( + weight_frame, + text="Weight Lifted (kg):", + font=self.default_font, + bg=self.bg_color, + fg=self.text_color, + width=18, + anchor=tk.W, + ).pack(side=tk.LEFT) + + self.weight_entry = tk.Entry( + weight_frame, + font=self.default_font, + bg=self.entry_bg, + fg=self.text_color, + insertbackground=self.text_color, + validate="key", + validatecommand=(self.window.register(self.validate_numeric_input), "%P"), + ) + self.weight_entry.pack(side=tk.LEFT, fill=tk.X, expand=True) + + # Reps input with validation + reps_frame = tk.Frame(self.window, bg=self.bg_color) + reps_frame.pack(fill=tk.X, padx=20, pady=5) + + tk.Label( + reps_frame, + text="Number of Reps:", + font=self.default_font, + bg=self.bg_color, + fg=self.text_color, + width=18, + anchor=tk.W, + ).pack(side=tk.LEFT) + + self.rep_entry = tk.Entry( + reps_frame, + font=self.default_font, + bg=self.entry_bg, + fg=self.text_color, + insertbackground=self.text_color, + validate="key", + validatecommand=(self.window.register(self.validate_integer_input), "%P"), + ) + self.rep_entry.pack(side=tk.LEFT, fill=tk.X, expand=True) + + # Formula selection + formula_frame = tk.Frame(self.window, bg=self.bg_color) + formula_frame.pack(fill=tk.X, padx=20, pady=10) + + tk.Label( + formula_frame, + text="Formula:", + font=self.default_font, + bg=self.bg_color, + fg=self.text_color, + width=18, + anchor=tk.W, + ).pack(side=tk.LEFT) + + self.formula_var = tk.StringVar(value="Epley") + formula_menu = ttk.Combobox( + formula_frame, + textvariable=self.formula_var, + values=list(self.formulas.keys()), + font=self.default_font, + state="readonly", + width=15, + ) + formula_menu.pack(side=tk.LEFT) + + # Button frame + button_frame = tk.Frame(self.window, bg=self.bg_color) + button_frame.pack(pady=15) + + # Calculate button + calculate_btn = tk.Button( + button_frame, + text="Calculate 1RM", + command=self.display_result, + font=self.button_font, + bg=self.button_bg, + fg=self.button_fg, + activebackground=self.button_active_bg, + activeforeground=self.button_fg, + padx=15, + ) + calculate_btn.pack(side=tk.LEFT, padx=10) + + # Theme toggle button + theme_btn = tk.Button( + button_frame, + text="Toggle Theme", + command=self.toggle_theme, + font=self.button_font, + bg=self.button_bg, + fg=self.button_fg, + activebackground=self.button_active_bg, + activeforeground=self.button_fg, + padx=15, + ) + theme_btn.pack(side=tk.LEFT, padx=10) + + # Result display + result_frame = tk.Frame(self.window, bg=self.bg_color) + result_frame.pack(fill=tk.X, padx=20, pady=10) + + tk.Label( + result_frame, + text="Estimated 1RM:", + font=self.default_font, + bg=self.bg_color, + fg=self.text_color, + ).pack(side=tk.LEFT, padx=5) + + self.result_value_label = tk.Label( + result_frame, + text="", + font=self.title_font, + bg=self.bg_color, + fg="#22A7F0", # Accent color for result + ) + self.result_value_label.pack(side=tk.LEFT, padx=10) + + # Formula info + self.formula_info_label = tk.Label( + self.window, + text="Formula: Epley (w × (1 + r × 0.0333))", + font=("Arial", 10), + bg=self.bg_color, + fg="#888888", + ) + self.formula_info_label.pack(pady=5) + + # Bind formula change event + formula_menu.bind("<>", self.update_formula_info) + + def validate_numeric_input(self, value: str) -> bool: + """Validate that input is a positive number with optional decimal.""" + if value == "": + return True + try: + float(value) + return float(value) > 0 + except ValueError: + return False + + def validate_integer_input(self, value: str) -> bool: + """Validate that input is a positive integer.""" + if value == "": + return True + try: + int(value) + return int(value) > 0 + except ValueError: + return False + + def calculate_1rm(self) -> float | None: + """ + Calculate 1RM using selected formula with input validation. + + Returns: + Calculated 1RM or None if inputs are invalid. + """ + try: + weight = float(self.weight_entry.get()) + reps = int(self.rep_entry.get()) + + if weight <= 0: + raise ValueError("Weight must be greater than 0.") + + if reps <= 0: + raise ValueError("Reps must be greater than 0.") + + if reps > 20: + messagebox.warning( + "Warning", + "Formulas may be inaccurate for reps > 20.\n\n" + "1RM calculations are most reliable for 1-10 reps.", + ) + + formula_name = self.formula_var.get() + formula = self.formulas[formula_name] + return formula(weight, reps) + + except ValueError as e: + self.result_value_label.config(text=f"Error: {str(e)}") + return None + except Exception as e: + self.result_value_label.config(text=f"An error occurred: {str(e)}") + return None + + def display_result(self) -> None: + """Calculate 1RM and update result label with formatted value.""" + result = self.calculate_1rm() + if result is not None: + self.result_value_label.config(text=f"{result:.2f} kg") + + def update_formula_info(self, event=None) -> None: + """Update the formula description label.""" + formula_name = self.formula_var.get() + if formula_name == "Epley": + desc = "Epley (w × (1 + r × 0.0333))" + elif formula_name == "Brzycki": + desc = "Brzycki (w ÷ (1.0278 - 0.0278 × r))" + elif formula_name == "Lombardi": + desc = "Lombardi (w × r^0.1)" + elif formula_name == "Mayhew": + desc = "Mayhew (100w ÷ (52.2 + 41.9e^(-0.055r)))" + else: + desc = formula_name + + self.formula_info_label.config(text=f"Formula: {desc}") + + def apply_dark_mode(self) -> None: + """Apply dark mode color scheme.""" + self.bg_color = "#1E1E1E" + self.text_color = "#FFFFFF" + self.entry_bg = "#333333" + self.button_bg = "#4CAF50" + self.button_fg = "#FFFFFF" + self.button_active_bg = "#45a049" + self.window.configure(bg=self.bg_color) + + def apply_light_mode(self) -> None: + """Apply light mode color scheme.""" + self.bg_color = "#F0F0F0" + self.text_color = "#000000" + self.entry_bg = "#FFFFFF" + self.button_bg = "#4CAF50" + self.button_fg = "#FFFFFF" + self.button_active_bg = "#45a049" + self.window.configure(bg=self.bg_color) + + def toggle_theme(self) -> None: + """Toggle between dark and light modes.""" + self.is_dark_mode = not self.is_dark_mode + + if self.is_dark_mode: + self.apply_dark_mode() + else: + self.apply_light_mode() + + # Reconfigure all widgets + for widget in self.window.winfo_children(): + if isinstance(widget, tk.Label) or isinstance(widget, tk.Button): + widget.configure(bg=self.bg_color, fg=self.text_color) + elif isinstance(widget, tk.Entry): + widget.configure( + bg=self.entry_bg, + fg=self.text_color, + insertbackground=self.text_color, + ) + elif isinstance(widget, tk.Frame): + widget.configure(bg=self.bg_color) + for sub_widget in widget.winfo_children(): + if isinstance(sub_widget, tk.Label) or isinstance( + sub_widget, tk.Button + ): + sub_widget.configure(bg=self.bg_color, fg=self.text_color) + elif isinstance(sub_widget, tk.Entry): + sub_widget.configure( + bg=self.entry_bg, + fg=self.text_color, + insertbackground=self.text_color, + ) + elif isinstance(sub_widget, ttk.Combobox): + # ttk widgets require style configuration + style = ttk.Style() + if self.is_dark_mode: + style.configure( + "TCombobox", + fieldbackground=self.entry_bg, + background=self.bg_color, + foreground=self.text_color, + ) + else: + style.configure( + "TCombobox", + fieldbackground=self.entry_bg, + background=self.bg_color, + foreground=self.text_color, + ) + + # Update button colors + for widget in self.window.winfo_children(): + if isinstance(widget, tk.Frame): + for button in widget.winfo_children(): + if isinstance(button, tk.Button): + button.configure( + bg=self.button_bg, + fg=self.button_fg, + activebackground=self.button_active_bg, + ) + + # Update result label accent color + self.result_value_label.configure( + fg="#22A7F0" if self.is_dark_mode else "#1E88E5" + ) + self.formula_info_label.configure( + fg="#888888" if self.is_dark_mode else "#666666" + ) + + def run(self) -> None: + """Start the application's main event loop.""" self.window.mainloop() -# Usage if __name__ == "__main__": calculator = OneRepMaxCalculator() calculator.run() - -# Improve the program. -# Make the fonts, bigger. -# - Use text formatting... -# Use dark mode. -# Have an option to use dark mode and light mode. diff --git a/nitkarshchourasia/to_sort/pdf_to_docx_converter/pdf_to_docx.py b/nitkarshchourasia/to_sort/pdf_to_docx_converter/pdf_to_docx.py index 757eccae6ca..9020d5525b8 100644 --- a/nitkarshchourasia/to_sort/pdf_to_docx_converter/pdf_to_docx.py +++ b/nitkarshchourasia/to_sort/pdf_to_docx_converter/pdf_to_docx.py @@ -3,7 +3,7 @@ from pdf2docx import Converter -def convert_pdf_to_docx(pdf_file_path, docx_file_path): +def convert_pdf_to_docx(pdf_file_path, docx_file_path) -> None: """ Converts a PDF file to a DOCX file using pdf2docx library. diff --git a/nitkarshchourasia/to_sort/pdf_to_docx_converter/requirements.txt b/nitkarshchourasia/to_sort/pdf_to_docx_converter/requirements.txt deleted file mode 100644 index 74006b5fb0a..00000000000 --- a/nitkarshchourasia/to_sort/pdf_to_docx_converter/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -python-docx==0.8.11 -PyMuPDF==1.18.17 -pytesseract==0.3.8 -Pillow==8.4.0 \ No newline at end of file diff --git a/nitkarshchourasia/to_sort/word2number/word2number.py b/nitkarshchourasia/to_sort/word2number/word2number.py index 6e8fed09d39..3c9bf3579eb 100644 --- a/nitkarshchourasia/to_sort/word2number/word2number.py +++ b/nitkarshchourasia/to_sort/word2number/word2number.py @@ -1,5 +1,6 @@ -def word_to_number(word): - numbers_dict = { +def word_to_number(word: str) -> float: + # Map number words to their values + number_words = { "zero": 0, "one": 1, "two": 2, @@ -28,6 +29,10 @@ def word_to_number(word): "seventy": 70, "eighty": 80, "ninety": 90, + } + + # Map multipliers to their values + multipliers = { "hundred": 100, "thousand": 1000, "lakh": 100000, @@ -36,48 +41,42 @@ def word_to_number(word): "trillion": 1000000000000, } - # Split the string into words - words = word.split() - - result = 0 - current_number = 0 + # Split input into words and clean + words = [ + w.lower() + for w in word.replace("-", " ").split() + if w.lower() not in {"and", "point"} + ] - # Ways I can make this more efficient: - for w in words: - if w in numbers_dict: - current_number += numbers_dict[w] - elif w == "hundred": - current_number *= 100 - elif w == "thousand": - result += current_number * 1000 - current_number = 0 - elif w == "lakh": - result += current_number * 100000 - current_number = 0 - elif w == "crore": - result += current_number * 10000000 - current_number = 0 - elif w == "billion": - result += current_number * 1000000000 - current_number = 0 - elif w == "trillion": - result += current_number * 1000000000000 - current_number = 0 + total = 0 + current = 0 - result += current_number + for word in words: + if word in number_words: + current += number_words[word] + elif word in multipliers: + if word == "hundred": + current *= multipliers[word] + else: + # Apply current multiplier and reset + total += current * multipliers[word] + current = 0 + else: + # Handle decimal points or invalid words + try: + # Attempt to parse as decimal part + decimal_part = float(word) + total += current + decimal_part + current = 0 + except ValueError: + raise ValueError(f"Invalid number word: {word}") - return result + # Add any remaining current value + total += current + return total # Example usage: number_str = "two trillion seven billion fifty crore thirty-four lakh seven thousand nine hundred" result = word_to_number(number_str) -print(result) - - -# Will make a tkinter application out of it. -## It will have a slider to use the more efficient way or just the normal way. -## More efficient way would have a library word2num to choose from. - -# The application would be good. -# I want to make it more efficient and optimized. +print(result) # Output: 200750347900 diff --git a/nmap_scan.py b/nmap_scan.py index 72f4b078e96..90b7b1c44b2 100644 --- a/nmap_scan.py +++ b/nmap_scan.py @@ -1,10 +1,7 @@ -from __future__ import print_function - import optparse # Import the module import nmap # Import the module - # Script Name : nmap_scan.py # Author : Craig Richards # Created : 24th May 2013 diff --git a/nodepad/notepad.py b/nodepad/notepad.py index 356316e3d9e..72cf16b79a1 100644 --- a/nodepad/notepad.py +++ b/nodepad/notepad.py @@ -1,64 +1,102 @@ -#! /usr/bin/env python -# -# GUI module generated by PAGE version 4.10 -# In conjunction with Tcl version 8.6 -# Jan 30, 2018 02:49:06 PM +#!/usr/bin/env python3 -try: - from Tkinter import * -except ImportError: - from tkinter import * +import sys +from tkinter import WORD, Button, Entry, Frame, Label, Text, Tk, Toplevel, ttk +from typing import Any -try: - import ttk - py3 = 0 -except ImportError: - import tkinter.ttk as ttk +# Replace missing module with placeholder (implement this separately) +# import notepad_support +class NotepadSupport: + """Placeholder for notepad_support module functionality""" - py3 = 1 + @staticmethod + def init(root: Tk, top: Any) -> None: + pass -import notepad_support + @staticmethod + def add_button(event: Any) -> None: + pass + @staticmethod + def clear_button(event: Any) -> None: + pass -def vp_start_gui(): + @staticmethod + def next_button(event: Any) -> None: + pass + + @staticmethod + def back_button(event: Any) -> None: + pass + + @staticmethod + def search_button(event: Any) -> None: + pass + + @staticmethod + def delete_button(event: Any) -> None: + pass + + @staticmethod + def create_button(event: Any) -> None: + pass + + @staticmethod + def exit_button(event: Any) -> None: + sys.exit() + + +notepad_support = NotepadSupport() + + +def vp_start_gui() -> None: """Starting point when module is the main routine.""" - global val, w, root + global root root = Tk() root.resizable(False, False) - top = Notepads_managment(root) + top = NotepadsManagement(root) notepad_support.init(root, top) root.mainloop() -w = None +root: Tk | None = None +w: Toplevel | None = None -def create_Notepads_managment(root, *args, **kwargs): +def create_Notepads_management( + root: Tk, *args: Any, **kwargs: Any +) -> tuple[Toplevel, Any]: """Starting point when module is imported by another program.""" - global w, w_win, rt + global w, rt rt = root w = Toplevel(root) - top = Notepads_managment(w) + top = NotepadsManagement(w) notepad_support.init(w, top, *args, **kwargs) return (w, top) -def destroy_Notepads_managment(): +def destroy_Notepads_management() -> None: global w - w.destroy() - w = None + if w: + w.destroy() + w = None -class Notepads_managment: - def __init__(self, top=None): - """This class configures and populates the toplevel window. - top is the toplevel containing window.""" +class NotepadsManagement: + def __init__(self, top: Tk | Toplevel) -> None: + """ + Configure and populate the toplevel window for managing notepads. + + Args: + top: The toplevel window to configure. + """ _bgcolor = "#d9d9d9" # X11 color: 'gray85' _fgcolor = "#000000" # X11 color: 'black' _compcolor = "#d9d9d9" # X11 color: 'gray85' _ana1color = "#d9d9d9" # X11 color: 'gray85' _ana2color = "#d9d9d9" # X11 color: 'gray85' + self.style = ttk.Style() if sys.platform == "win32": self.style.theme_use("winnative") @@ -70,7 +108,7 @@ def __init__(self, top=None): ) top.geometry("600x450") - top.title("Notepads managment") + top.title("Notepads Management") top.configure(highlightcolor="black") self.style.configure("TNotebook.Tab", background=_bgcolor) @@ -79,35 +117,29 @@ def __init__(self, top=None): "TNotebook.Tab", background=[("selected", _compcolor), ("active", _ana2color)], ) + + # Create notebook tabs self.TNotebook1 = ttk.Notebook(top) self.TNotebook1.place(relx=0.02, rely=0.02, relheight=0.85, relwidth=0.97) self.TNotebook1.configure(width=582) self.TNotebook1.configure(takefocus="") + + # Tab 0: Add Note self.TNotebook1_t0 = Frame(self.TNotebook1) self.TNotebook1.add(self.TNotebook1_t0, padding=3) - self.TNotebook1.tab( - 0, - text="Add", - compound="none", - underline="-1", - ) + self.TNotebook1.tab(0, text="Add", compound="none", underline="-1") + + # Tab 1: Display Notes self.TNotebook1_t1 = Frame(self.TNotebook1) self.TNotebook1.add(self.TNotebook1_t1, padding=3) - self.TNotebook1.tab( - 1, - text="Display", - compound="none", - underline="-1", - ) + self.TNotebook1.tab(1, text="Display", compound="none", underline="-1") + + # Tab 2: Create self.TNotebook1_t2 = Frame(self.TNotebook1) self.TNotebook1.add(self.TNotebook1_t2, padding=3) - self.TNotebook1.tab( - 2, - text="Create", - compound="none", - underline="-1", - ) + self.TNotebook1.tab(2, text="Create", compound="none", underline="-1") + # Tab 0 Widgets (Add Note) self.inputNotice = Text(self.TNotebook1_t0) self.inputNotice.place(relx=0.02, rely=0.28, relheight=0.64, relwidth=0.68) self.inputNotice.configure(background="white") @@ -125,25 +157,26 @@ def __init__(self, top=None): self.Label1 = Label(self.TNotebook1_t0) self.Label1.place(relx=0.02, rely=0.08, height=18, width=29) self.Label1.configure(activebackground="#f9f9f9") - self.Label1.configure(text="""Title""") + self.Label1.configure(text="Title") self.Label2 = Label(self.TNotebook1_t0) self.Label2.place(relx=0.02, rely=0.22, height=18, width=46) self.Label2.configure(activebackground="#f9f9f9") - self.Label2.configure(text="""Notice:""") + self.Label2.configure(text="Notice:") self.Button2 = Button(self.TNotebook1_t0) self.Button2.place(relx=0.74, rely=0.28, height=26, width=50) self.Button2.configure(activebackground="#d9d9d9") - self.Button2.configure(text="""Add""") - self.Button2.bind("", lambda e: notepad_support.add_button(e)) + self.Button2.configure(text="Add") + self.Button2.bind("", notepad_support.add_button) self.Button3 = Button(self.TNotebook1_t0) self.Button3.place(relx=0.74, rely=0.39, height=26, width=56) self.Button3.configure(activebackground="#d9d9d9") - self.Button3.configure(text="""Clear""") - self.Button3.bind("", lambda e: notepad_support.clear_button(e)) + self.Button3.configure(text="Clear") + self.Button3.bind("", notepad_support.clear_button) + # Tab 1 Widgets (Display Notes) self.outputNotice = Text(self.TNotebook1_t1) self.outputNotice.place(relx=0.02, rely=0.19, relheight=0.76, relwidth=0.6) self.outputNotice.configure(background="white") @@ -161,48 +194,50 @@ def __init__(self, top=None): self.Label3 = Label(self.TNotebook1_t1) self.Label3.place(relx=0.02, rely=0.08, height=18, width=29) self.Label3.configure(activebackground="#f9f9f9") - self.Label3.configure(text="""Title""") + self.Label3.configure(text="Title") self.Button4 = Button(self.TNotebook1_t1) self.Button4.place(relx=0.69, rely=0.33, height=26, width=54) self.Button4.configure(activebackground="#d9d9d9") - self.Button4.configure(text="""Next""") - self.Button4.bind("", lambda e: notepad_support.next_button(e)) + self.Button4.configure(text="Next") + self.Button4.bind("", notepad_support.next_button) self.Button5 = Button(self.TNotebook1_t1) self.Button5.place(relx=0.69, rely=0.44, height=26, width=55) self.Button5.configure(activebackground="#d9d9d9") - self.Button5.configure(text="""Back""") - self.Button5.bind("", lambda e: notepad_support.back_button(e)) + self.Button5.configure(text="Back") + self.Button5.bind("", notepad_support.back_button) self.Button7 = Button(self.TNotebook1_t1) self.Button7.place(relx=0.69, rely=0.22, height=26, width=68) self.Button7.configure(activebackground="#d9d9d9") - self.Button7.configure(text="""Search""") - self.Button7.bind("", lambda e: notepad_support.search_button(e)) + self.Button7.configure(text="Search") + self.Button7.bind("", notepad_support.search_button) self.Button8 = Button(self.TNotebook1_t1) self.Button8.place(relx=0.69, rely=0.56, height=26, width=64) self.Button8.configure(activebackground="#d9d9d9") - self.Button8.configure(text="""Delete""") - self.Button8.bind("", lambda e: notepad_support.delete_button(e)) + self.Button8.configure(text="Delete") + self.Button8.bind("", notepad_support.delete_button) + # Tab 2 Widgets (Create) self.Label4 = Label(self.TNotebook1_t2) self.Label4.place(relx=0.09, rely=0.14, height=18, width=259) self.Label4.configure(activebackground="#f9f9f9") - self.Label4.configure(text="""For creating a new notepads managment.""") + self.Label4.configure(text="For creating a new notepads management.") self.Button6 = Button(self.TNotebook1_t2) self.Button6.place(relx=0.22, rely=0.25, height=26, width=69) self.Button6.configure(activebackground="#d9d9d9") - self.Button6.configure(text="""Create""") - self.Button6.bind("", lambda e: notepad_support.create_button(e)) + self.Button6.configure(text="Create") + self.Button6.bind("", notepad_support.create_button) + # Main Window Widgets self.Button1 = Button(top) self.Button1.place(relx=0.4, rely=0.91, height=26, width=117) self.Button1.configure(activebackground="#d9d9d9") - self.Button1.configure(text="""Exit""") - self.Button1.bind("", lambda e: notepad_support.exit_button(e)) + self.Button1.configure(text="Exit") + self.Button1.bind("", notepad_support.exit_button) self.errorOutput = Label(top) self.errorOutput.place(relx=0.03, rely=0.91, height=18, width=206) diff --git a/notepad/high_notepad.py b/notepad/high_notepad.py new file mode 100644 index 00000000000..d5cbaff6208 --- /dev/null +++ b/notepad/high_notepad.py @@ -0,0 +1,474 @@ +#!/usr/bin/env python3 + +import sqlite3 +import tkinter as tk +from tkinter import Button, Entry, Frame, Label, Text, messagebox, ttk + + +class NotepadApp: + def __init__(self, root: tk.Tk): + """Initialize the Notepad Application""" + self.root = root + self.root.title("Advanced Notepad") + self.root.geometry("800x600") + self.root.resizable(True, True) + + # Ensure proper font for English display + self.root.option_add("*Font", "Arial 10") + + # Database connection + self.connection = sqlite3.connect("notes.db") + self.cursor = self.connection.cursor() + self._initialize_database() + + # Search state + self.search_active = False + self.current_results: list[tuple[int, str, str]] = [] + self.current_index = 0 + + # Create UI + self._create_ui() + + def _initialize_database(self) -> None: + """Initialize the database table""" + try: + self.cursor.execute(""" + CREATE TABLE IF NOT EXISTS notes ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + title TEXT NOT NULL, + content TEXT NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + """) + self.connection.commit() + except Exception as e: + messagebox.showerror( + "Database Error", f"Failed to initialize database: {str(e)}" + ) + + def _create_ui(self) -> None: + """Create the user interface""" + # Create main frame + main_frame = Frame(self.root) + main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10) + + # Create notebook tabs + self.notebook = ttk.Notebook(main_frame) + self.notebook.pack(fill=tk.BOTH, expand=True) + + # Add tabs + self.tab_add = Frame(self.notebook) + self.tab_display = Frame(self.notebook) + self.tab_search = Frame(self.notebook) + + self.notebook.add(self.tab_add, text="Add Note") + self.notebook.add(self.tab_display, text="Browse Notes") + self.notebook.add(self.tab_search, text="Search Notes") + + # Setup Add tab + self._setup_add_tab() + + # Setup Display tab + self._setup_display_tab() + + # Setup Search tab + self._setup_search_tab() + + # Status bar + self.status_bar = Label( + self.root, text="Ready", bd=1, relief=tk.SUNKEN, anchor=tk.W + ) + self.status_bar.pack(side=tk.BOTTOM, fill=tk.X) + + # Load all notes initially + self._load_all_notes() + + def _setup_add_tab(self) -> None: + """Setup the Add Note tab""" + # Title frame + title_frame = Frame(self.tab_add) + title_frame.pack(fill=tk.X, padx=10, pady=5) + + Label(title_frame, text="Title:").pack(side=tk.LEFT, padx=5) + self.title_entry = Entry(title_frame, width=60) + self.title_entry.pack(side=tk.LEFT, fill=tk.X, expand=True) + + # Content frame + content_frame = Frame(self.tab_add) + content_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5) + + Label(content_frame, text="Content:").pack(anchor=tk.W, padx=5) + self.content_text = Text(content_frame, wrap=tk.WORD, height=15) + self.content_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) + + # Button frame + button_frame = Frame(self.tab_add) + button_frame.pack(fill=tk.X, padx=10, pady=5) + + Button(button_frame, text="Save Note", command=self._save_note).pack( + side=tk.RIGHT, padx=5 + ) + Button(button_frame, text="Clear", command=self._clear_form).pack( + side=tk.RIGHT, padx=5 + ) + + def _setup_display_tab(self) -> None: + """Setup the Browse Notes tab""" + # Search frame + search_frame = Frame(self.tab_display) + search_frame.pack(fill=tk.X, padx=10, pady=5) + + Label(search_frame, text="Filter:").pack(side=tk.LEFT, padx=5) + self.filter_entry = Entry(search_frame, width=40) + self.filter_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5) + Button(search_frame, text="Apply Filter", command=self._apply_filter).pack( + side=tk.RIGHT, padx=5 + ) + + # Notes list frame + list_frame = Frame(self.tab_display) + list_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5) + + # Treeview for notes + columns = ("id", "title", "created_at") + self.notes_tree = ttk.Treeview(list_frame, columns=columns, show="headings") + self.notes_tree.heading("id", text="ID") + self.notes_tree.heading("title", text="Title") + self.notes_tree.heading("created_at", text="Created At") + + self.notes_tree.column("id", width=50) + self.notes_tree.column("title", width=300) + self.notes_tree.column("created_at", width=150) + + self.notes_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) + + # Scrollbar + scrollbar = ttk.Scrollbar( + list_frame, orient=tk.VERTICAL, command=self.notes_tree.yview + ) + self.notes_tree.configure(yscroll=scrollbar.set) + scrollbar.pack(side=tk.RIGHT, fill=tk.Y) + + # Bind selection event + self.notes_tree.bind("<>", self._on_note_select) + + # Button frame + button_frame = Frame(self.tab_display) + button_frame.pack(fill=tk.X, padx=10, pady=5) + + Button(button_frame, text="Refresh", command=self._load_all_notes).pack( + side=tk.LEFT, padx=5 + ) + Button( + button_frame, text="Delete Selected", command=self._delete_selected_note + ).pack(side=tk.RIGHT, padx=5) + + def _setup_search_tab(self) -> None: + """Setup the Search Notes tab""" + # Search frame + search_frame = Frame(self.tab_search) + search_frame.pack(fill=tk.X, padx=10, pady=5) + + Label(search_frame, text="Search Title:").pack(side=tk.LEFT, padx=5) + self.search_entry = Entry(search_frame, width=50) + self.search_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5) + Button(search_frame, text="Search", command=self._search_notes).pack( + side=tk.RIGHT, padx=5 + ) + + # Results frame + results_frame = Frame(self.tab_search) + results_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5) + + # Navigation buttons + nav_frame = Frame(results_frame) + nav_frame.pack(fill=tk.X) + + self.prev_button = Button( + nav_frame, + text="Previous", + command=self._show_previous_result, + state=tk.DISABLED, + ) + self.prev_button.pack(side=tk.LEFT, padx=5) + + self.next_button = Button( + nav_frame, text="Next", command=self._show_next_result, state=tk.DISABLED + ) + self.next_button.pack(side=tk.RIGHT, padx=5) + + # Result display + self.result_title_var = tk.StringVar() + Label( + results_frame, + textvariable=self.result_title_var, + font=("Arial", 12, "bold"), + ).pack(anchor=tk.W, padx=5, pady=5) + + self.result_content_text = Text(results_frame, wrap=tk.WORD, height=15) + self.result_content_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) + + # Status label + self.search_status_var = tk.StringVar() + self.search_status_var.set("No search results") + Label(results_frame, textvariable=self.search_status_var).pack( + anchor=tk.W, padx=5, pady=5 + ) + + def _load_all_notes(self) -> None: + """Load all notes into the treeview""" + # Clear existing items + for item in self.notes_tree.get_children(): + self.notes_tree.delete(item) + + try: + self.cursor.execute( + "SELECT id, title, created_at FROM notes ORDER BY created_at DESC" + ) + notes = self.cursor.fetchall() + + for note in notes: + self.notes_tree.insert("", tk.END, values=note) + + self.status_bar.config(text=f"Loaded {len(notes)} notes") + except Exception as e: + messagebox.showerror("Database Error", f"Failed to load notes: {str(e)}") + + def _apply_filter(self) -> None: + """Apply filter to notes list""" + filter_text = self.filter_entry.get().strip().lower() + + # Clear existing items + for item in self.notes_tree.get_children(): + self.notes_tree.delete(item) + + try: + if filter_text: + self.cursor.execute( + "SELECT id, title, created_at FROM notes WHERE LOWER(title) LIKE ? ORDER BY created_at DESC", + (f"%{filter_text}%",), + ) + else: + self.cursor.execute( + "SELECT id, title, created_at FROM notes ORDER BY created_at DESC" + ) + + notes = self.cursor.fetchall() + + for note in notes: + self.notes_tree.insert("", tk.END, values=note) + + self.status_bar.config(text=f"Filtered {len(notes)} notes") + except Exception as e: + messagebox.showerror("Database Error", f"Failed to filter notes: {str(e)}") + + def _on_note_select(self, event: tk.Event) -> None: + """Handle note selection""" + selected_items = self.notes_tree.selection() + if not selected_items: + return + + note_id = self.notes_tree.item(selected_items[0])["values"][0] + + try: + self.cursor.execute( + "SELECT title, content FROM notes WHERE id = ?", (note_id,) + ) + note = self.cursor.fetchone() + + if note: + title, content = note + # Open a new window to display the note + self._open_note_viewer(note_id, title, content) + except Exception as e: + messagebox.showerror("Database Error", f"Failed to load note: {str(e)}") + + def _open_note_viewer(self, note_id: int, title: str, content: str) -> None: + """Open a new window to view/edit the note""" + viewer = tk.Toplevel(self.root) + viewer.title(f"Note: {title}") + viewer.geometry("600x500") + viewer.resizable(True, True) + + # Title entry + title_frame = Frame(viewer) + title_frame.pack(fill=tk.X, padx=10, pady=5) + + title_label = Label(title_frame, text="Title:") + title_label.pack(side=tk.LEFT, padx=5) + + title_entry = Entry(title_frame, width=50) + title_entry.pack(side=tk.LEFT, fill=tk.X, expand=True) + title_entry.insert(0, title) + + # Content text + content_text = Text(viewer, wrap=tk.WORD, height=20) + content_text.pack(fill=tk.BOTH, expand=True, padx=10, pady=5) + content_text.insert(tk.END, content) + + # Button frame + button_frame = Frame(viewer) + button_frame.pack(fill=tk.X, padx=10, pady=5) + + def update_note() -> None: + new_title = title_entry.get().strip() + new_content = content_text.get(1.0, tk.END).strip() + + if not new_title: + messagebox.showerror("Input Error", "Title cannot be empty") + return + + try: + self.cursor.execute( + "UPDATE notes SET title = ?, content = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?", + (new_title, new_content, note_id), + ) + self.connection.commit() + messagebox.showinfo("Success", "Note updated successfully") + viewer.destroy() + self._load_all_notes() + except Exception as e: + messagebox.showerror( + "Database Error", f"Failed to update note: {str(e)}" + ) + + Button(button_frame, text="Update Note", command=update_note).pack( + side=tk.RIGHT, padx=5 + ) + Button(button_frame, text="Cancel", command=viewer.destroy).pack( + side=tk.RIGHT, padx=5 + ) + + def _delete_selected_note(self) -> None: + """Delete the selected note""" + selected_items = self.notes_tree.selection() + if not selected_items: + messagebox.showinfo("Selection Error", "Please select a note to delete") + return + + note_id = self.notes_tree.item(selected_items[0])["values"][0] + title = self.notes_tree.item(selected_items[0])["values"][1] + + if messagebox.askyesno( + "Confirm Delete", f"Are you sure you want to delete the note '{title}'?" + ): + try: + self.cursor.execute("DELETE FROM notes WHERE id = ?", (note_id,)) + self.connection.commit() + self._load_all_notes() + self.status_bar.config(text=f"Deleted note with ID {note_id}") + except Exception as e: + messagebox.showerror( + "Database Error", f"Failed to delete note: {str(e)}" + ) + + def _save_note(self) -> None: + """Save the current note to the database""" + title = self.title_entry.get().strip() + content = self.content_text.get(1.0, tk.END).strip() + + if not title: + messagebox.showerror("Input Error", "Title cannot be empty") + return + + try: + self.cursor.execute( + "INSERT INTO notes (title, content) VALUES (?, ?)", (title, content) + ) + self.connection.commit() + messagebox.showinfo("Success", "Note saved successfully") + self._clear_form() + self._load_all_notes() + except Exception as e: + messagebox.showerror("Database Error", f"Failed to save note: {str(e)}") + + def _clear_form(self) -> None: + """Clear the form fields""" + self.title_entry.delete(0, tk.END) + self.content_text.delete(1.0, tk.END) + self.status_bar.config(text="Form cleared") + + def _search_notes(self) -> None: + """Search notes by title""" + search_text = self.search_entry.get().strip() + + if not search_text: + messagebox.showinfo("Search Error", "Please enter a search term") + return + + try: + self.cursor.execute( + "SELECT id, title, content FROM notes WHERE title LIKE ? ORDER BY created_at DESC", + (f"%{search_text}%",), + ) + self.current_results = self.cursor.fetchall() + self.current_index = 0 + + if not self.current_results: + self.search_status_var.set("No results found") + self.result_title_var.set("") + self.result_content_text.delete(1.0, tk.END) + self.prev_button.config(state=tk.DISABLED) + self.next_button.config(state=tk.DISABLED) + else: + self._update_search_display() + self.search_status_var.set( + f"Displaying result {self.current_index + 1} of {len(self.current_results)}" + ) + self.prev_button.config( + state=tk.NORMAL if len(self.current_results) > 1 else tk.DISABLED + ) + self.next_button.config( + state=tk.NORMAL if len(self.current_results) > 1 else tk.DISABLED + ) + + self.search_active = True + except Exception as e: + messagebox.showerror("Database Error", f"Failed to search notes: {str(e)}") + + def _update_search_display(self) -> None: + """Update the search result display""" + if 0 <= self.current_index < len(self.current_results): + note_id, title, content = self.current_results[self.current_index] + self.result_title_var.set(title) + self.result_content_text.delete(1.0, tk.END) + self.result_content_text.insert(tk.END, content) + self.search_status_var.set( + f"Displaying result {self.current_index + 1} of {len(self.current_results)}" + ) + + def _show_previous_result(self) -> None: + """Show the previous search result""" + if self.current_index > 0: + self.current_index -= 1 + self._update_search_display() + self.next_button.config(state=tk.NORMAL) + + if self.current_index == 0: + self.prev_button.config(state=tk.DISABLED) + + def _show_next_result(self) -> None: + """Show the next search result""" + if self.current_index < len(self.current_results) - 1: + self.current_index += 1 + self._update_search_display() + self.prev_button.config(state=tk.NORMAL) + + if self.current_index == len(self.current_results) - 1: + self.next_button.config(state=tk.DISABLED) + + def run(self) -> None: + """Run the application""" + self.root.mainloop() + + def __del__(self) -> None: + """Close the database connection when the object is destroyed""" + if self.connection: + self.connection.close() + + +if __name__ == "__main__": + root = tk.Tk() + app = NotepadApp(root) + app.run() diff --git a/notepad/notepad_support.py b/notepad/notepad_support.py deleted file mode 100644 index 39a27d63b0e..00000000000 --- a/notepad/notepad_support.py +++ /dev/null @@ -1,164 +0,0 @@ -#! /usr/bin/env python -# -# Support module generated by PAGE version 4.10 -# In conjunction with Tcl version 8.6 -# Jan 29, 2018 03:25:00 PM - - -import sqlite3 - -try: - from Tkinter import * -except ImportError: - from tkinter import * - -try: - import ttk - - py3 = 0 -except ImportError: - - py3 = 1 - -# connect with database 'data.db' -connection = sqlite3.connect("data.db") - -# creates a cursor (pointer) to the data base -cursor = connection.cursor() - -search = False - -results = [] - -index = 0 - - -def delete_button(p1): - global index - global results - global cursor - - # fetch id of the current note - id = results[index][0] - - sql_command = """ DELETE FROM notes WHERE id = {0}; """ - sql_command = sql_command.format(id) - - cursor.execute(sql_command) - - connection.commit() - - -def create_button(p1): - """ - for creating a new database - """ - global cursor - - sql_command = """ - CREATE TABLE notes ( - id INTEGER PRIMARY KEY, - title TEXT, - note TEXT);""" - - try: - cursor.execute(sql_command) - w.errorOutput.configure(text="") - except: - w.errorOutput.configure(text="The database already exists") - - -def add_button(p1): - # for manipulating the data base - global cursor - global connection - if len(w.inputTitle.get()) > 0 and len(w.inputNotice.get(1.0, END)) > 0: - w.errorOutput.configure(text="") - title = w.inputTitle.get() - note = w.inputNotice.get(1.0, END) - sql_command = """INSERT INTO notes (title,note) VALUES ("{0}","{1}"); """ - sql_command = sql_command.format(title, note) - cursor.execute(sql_command) - connection.commit() - else: - w.errorOutput.configure(text="Please fill the fields. ") - - -def back_button(p1): - global search - global results - global index - - w.errorOutput.configure(text="") - index -= 1 - if index >= 0 and index < len(results): - w.outputNotice.delete(1.0, END) - w.outputNotice.insert(1.0, results[index][2]) - - -def clear_button(p1): - """ - This function is for the clear button. - This will clear the notice-input field - """ - w.inputNotice.delete(1.0, END) - - -def exit_button(p1): - """ - function for the exit button. - this will exit the application. - """ - sys.exit(0) - - -def search_button(p1): - global cursor - global results - global index - w.errorOutput.configure(text="") - sql_command = """ SELECT * FROM notes WHERE title LIKE "%{0}%";""" - sql_command = sql_command.format(w.inputSearchTitle.get()) - try: - cursor.execute(sql_command) - results = cursor.fetchall() - w.errorOutput.configure(text=str(len(results)) + " results") - index = 0 - if index >= 0 and index < len(results): - w.outputNotice.delete(1.0, END) - w.outputNotice.insert(1.0, results[index][2]) - except: - w.errorOutput.configure(text="Please create at first a database.") - - -def next_button(p1): - global results - global index - index += 1 - if len(w.inputSearchTitle.get()) > 0: - if index >= 0 and index < len(results): - w.outputNotice.delete(1.0, END) - w.outputNotice.insert(1.0, results[index][2]) - - else: - w.errorOutput.configure(text="Please fill the search field. ") - - -def init(top, gui, *args, **kwargs): - global w, top_level, root - w = gui - top_level = top - root = top - - -def destroy_window(): - # Function which closes the window. - global top_level - top_level.destroy() - top_level = None - - -if __name__ == "__main__": - import notepad - - notepad.vp_start_gui() diff --git a/notes.db b/notes.db new file mode 100644 index 00000000000..e48223761d9 Binary files /dev/null and b/notes.db differ diff --git a/nslookup_check.py b/nslookup_check.py index 4ae57f84cfc..08a15ab8aad 100644 --- a/nslookup_check.py +++ b/nslookup_check.py @@ -12,5 +12,5 @@ for server in open("server_list.txt"): # Open the file and read each line subprocess.Popen( - ("nslookup " + server) + "nslookup " + server ) # Run the nslookup command for each server in the list diff --git a/num-py.py b/num-py.py index af365bd585d..fb992d8c141 100644 --- a/num-py.py +++ b/num-py.py @@ -1,12 +1,13 @@ import numpy as np + # to check if shape are equal and find there power def get_array(x, y): a = np.shape(x) b = np.shape(y) if a == b: - np_pow_array = x ** y + np_pow_array = x**y print("Array of powers without using np.power: ", np_pow_array) print("Array of powers using np.power: ", np.power(x, y)) diff --git a/number guessing.py b/number guessing.py index 25add25a64d..14bc88599fa 100644 --- a/number guessing.py +++ b/number guessing.py @@ -1,15 +1,22 @@ import random + attempts_list = [] + + def show_score(): if len(attempts_list) <= 0: print("There is currently no high score, it's yours for the taking!") else: - print("The current high score is {} attempts".format(min(attempts_list))) + print(f"The current high score is {min(attempts_list)} attempts") + + def start_game(): random_number = int(random.randint(1, 10)) print("Hello traveler! Welcome to the game of guesses!") player_name = input("What is your name? ") - wanna_play = input("Hi, {}, would you like to play the guessing game? (Enter Yes/No) ".format(player_name)) + wanna_play = input( + f"Hi, {player_name}, would you like to play the guessing game? (Enter Yes/No) " + ) # Where the show_score function USED to be attempts = 0 show_score() @@ -22,7 +29,7 @@ def start_game(): print("Nice! You got it!") attempts += 1 attempts_list.append(attempts) - print("It took you {} attempts".format(attempts)) + print(f"It took you {attempts} attempts") play_again = input("Would you like to play again? (Enter Yes/No) ") attempts = 0 show_score() @@ -38,8 +45,10 @@ def start_game(): attempts += 1 except ValueError as err: print("Oh no!, that is not a valid value. Try again...") - print("({})".format(err)) + print(f"({err})") else: print("That's cool, have a good one!") -if __name__ == '__main__': + + +if __name__ == "__main__": start_game() diff --git a/numberguessinggame/index.py b/numberguessinggame/index.py index 3116af47dce..5b169817173 100644 --- a/numberguessinggame/index.py +++ b/numberguessinggame/index.py @@ -1,7 +1,7 @@ import random + def number_guessing_game(): - secret_number = random.randint(1, 100) attempts = 0 @@ -18,11 +18,14 @@ def number_guessing_game(): elif guess > secret_number: print("Too high! Try again.") else: - print(f"Congratulations! You guessed the number {secret_number} in {attempts} attempts!") + print( + f"Congratulations! You guessed the number {secret_number} in {attempts} attempts!" + ) break except ValueError: print("Please enter a valid number.") + if __name__ == "__main__": number_guessing_game() diff --git a/numeric_password_cracker.py b/numeric_password_cracker.py index aaf48ac144d..2a6215c9a64 100644 --- a/numeric_password_cracker.py +++ b/numeric_password_cracker.py @@ -1,5 +1,6 @@ import itertools + def generate_password_permutations(length): # Generate numeric password permutations of the given length digits = "0123456789" @@ -7,6 +8,7 @@ def generate_password_permutations(length): password = "".join(combination) yield password + def password_cracker(target_password, max_length=8): # Try different password lengths and generate permutations for length in range(1, max_length + 1): @@ -16,6 +18,7 @@ def password_cracker(target_password, max_length=8): return password return None + if __name__ == "__main__": # Target numeric password (change this to the password you want to crack) target_password = "9133278" @@ -26,5 +29,6 @@ def password_cracker(target_password, max_length=8): if cracked_password: print(f"Password successfully cracked! The password is: {cracked_password}") else: - print("Password not found. Try increasing the max_length or target a different password.") - + print( + "Password not found. Try increasing the max_length or target a different password." + ) diff --git a/oneeven.py b/oneeven.py index 0c0a8c52530..18a1029eb2f 100644 --- a/oneeven.py +++ b/oneeven.py @@ -6,5 +6,5 @@ while number <= maximum: if number % 2 == 0: - print("{0}".format(number)) + print(f"{number}") number = number + 1 diff --git a/other_pepole/get_ip_gui b/other_pepole/get_ip_gui.py old mode 100755 new mode 100644 similarity index 60% rename from other_pepole/get_ip_gui rename to other_pepole/get_ip_gui.py index 5728697ac5b..b452230030f --- a/other_pepole/get_ip_gui +++ b/other_pepole/get_ip_gui.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import socket + # **************** Modules Require *****************# from tkinter import * from urllib.request import urlopen @@ -12,19 +12,19 @@ def get_wan_ip(): try: # get ip from http://ipecho.net/plain as text - wan_ip = urlopen('http://ipecho.net/plain').read().decode('utf-8') - res.configure(text='Wan IP is : ' + wan_ip, fg='#600') + wan_ip = urlopen("http://ipecho.net/plain").read().decode("utf-8") + res.configure(text="Wan IP is : " + wan_ip, fg="#600") except: - res.configure(text='Problem in source : http://ipecho.net/plain', fg='red') + res.configure(text="Problem in source : http://ipecho.net/plain", fg="red") # get local ip def get_local_ip(): try: - lan_ip = (socket.gethostbyname(socket.gethostname())) - res.configure(text='Local IP is : ' + lan_ip, fg='#600') + lan_ip = socket.gethostbyname(socket.gethostname()) + res.configure(text="Local IP is : " + lan_ip, fg="#600") except: - res.configure(text='Unkown Error', fg='#red') + res.configure(text="Unkown Error", fg="#red") # **************** about control button *****************# @@ -32,15 +32,19 @@ def get_local_ip(): def about(): global close_app, frame, info about_app.destroy() - frame = Frame(root, width=350, height=2, bg='blue') + frame = Frame(root, width=350, height=2, bg="blue") frame.grid(row=2, column=0, columnspan=4) - info = Label(root, text=""" + info = Label( + root, + text=""" Practice Python Take idea from here : https://github.com/geekcomputers/Python/blob/master/myip.py - """, fg='#02F') + """, + fg="#02F", + ) info.grid(row=3, column=0, columnspan=4, padx=5) - close_app = Button(root, text='Close', command=close_about, bg='#55F') + close_app = Button(root, text="Close", command=close_about, bg="#55F") close_app.grid(row=4, column=0, columnspan=4, pady=5) @@ -50,19 +54,19 @@ def close_about(): info.destroy() frame.destroy() close_app.destroy() - about_app = Button(root, text='about', command=about) + about_app = Button(root, text="about", command=about) about_app.grid(row=1, column=2, padx=5, pady=5, sticky=W) # **************** Tkinter GUI *****************# root = Tk() -root.title('Khaled programing practice') +root.title("Khaled programing practice") # all buttons -res = Label(root, text='00.00.00.00', font=25) -res_wan_ip = Button(root, text='Get Wan IP', command=get_wan_ip) -res_local_ip = Button(root, text='Get Local IP', command=get_local_ip) -about_app = Button(root, text='about', command=about) -quit_app = Button(root, text='quit', command=quit, bg='#f40') +res = Label(root, text="00.00.00.00", font=25) +res_wan_ip = Button(root, text="Get Wan IP", command=get_wan_ip) +res_local_ip = Button(root, text="Get Local IP", command=get_local_ip) +about_app = Button(root, text="about", command=about) +quit_app = Button(root, text="quit", command=quit, bg="#f40") # method grid to install the button in window res.grid(row=0, column=0, columnspan=4, sticky=N, padx=10, pady=5) res_wan_ip.grid(row=1, column=0, padx=5, pady=5, sticky=W) diff --git a/password_checker.py b/password_checker.py index afc5f7203ba..4fb610d90a8 100644 --- a/password_checker.py +++ b/password_checker.py @@ -1,24 +1,27 @@ import time -pwd="AKS2608" #any password u want to set + +pwd = "AKS2608" # any password u want to set + def IInd_func(): - count1=0 - for j in range(5): - a=0 - count=0 - user_pwd = input("") #password you remember - for i in range(len(pwd)): - if user_pwd[i] == pwd[a]: #comparing remembered pwd with fixed pwd - a +=1 - count+=1 - if count==len(pwd): - print("correct pwd") - break - else: - count1 += 1 - print("not correct") - if count1==5: - time.sleep(30) - IInd_func() + count1 = 0 + for j in range(5): + a = 0 + count = 0 + user_pwd = input("") # password you remember + for i in range(len(pwd)): + if user_pwd[i] == pwd[a]: # comparing remembered pwd with fixed pwd + a += 1 + count += 1 + if count == len(pwd): + print("correct pwd") + break + else: + count1 += 1 + print("not correct") + if count1 == 5: + time.sleep(30) + IInd_func() + IInd_func() diff --git a/password_cracker.py b/password_cracker.py index 3581fcc39f0..553e62928dd 100644 --- a/password_cracker.py +++ b/password_cracker.py @@ -1,5 +1,3 @@ -from __future__ import print_function - from sys import platform as _platform # Script Name : password_cracker.py @@ -23,7 +21,7 @@ def testPass(cryptPass): # Start the function salt = cryptPass[0:2] - dictFile = open("dictionary.txt", "r") # Open the dictionary file + dictFile = open("dictionary.txt") # Open the dictionary file for word in dictFile.readlines(): # Scan through the file word = word.strip("\n") cryptWord = crypt.crypt(word, salt) # Check for password in the file diff --git a/password_manager.py b/password_manager.py index cbbbcf87ef2..1153a576dbc 100644 --- a/password_manager.py +++ b/password_manager.py @@ -1,6 +1,6 @@ +import os import sqlite3 from getpass import getpass -import os # set the environment variable ADMIN_PASS to your desired string, which will be your password. ADMIN_PASSWORD = os.environ["ADMIN_PASS"] @@ -124,7 +124,7 @@ def is_service_present(service_): add_password(service, username, password) print("\n" + service.capitalize() + " password stored\n") else: - print("Service named {} already exists.".format(service)) + print(f"Service named {service} already exists.") elif input_ == "get": service = input("What is the name of the service?\n") diff --git a/password_programs_multiple/animal_name_scraiper.py b/password_programs_multiple/animal_name_scraiper.py index ea0e0f15d00..fb42fed9140 100644 --- a/password_programs_multiple/animal_name_scraiper.py +++ b/password_programs_multiple/animal_name_scraiper.py @@ -1,4 +1,4 @@ -import requests +import httpx from bs4 import BeautifulSoup # * Using html5lib as the parser is good @@ -6,7 +6,7 @@ animals_A_to_Z_URL = "https://animalcorner.org/animal-sitemap/#" -results = requests.get(animals_A_to_Z_URL) +results = httpx.get(animals_A_to_Z_URL) # ? results and results.text ? what are these? # soup = BeautifulSoup(results.text, "html.parser") @@ -47,7 +47,6 @@ while next_sibling and next_sibling.name == "br": next_sibling = next_sibling.next_sibling - # Print the text content of the next sibling element if next_sibling: print(next_sibling.text.strip()) diff --git a/password_programs_multiple/passwordGenerator.py b/password_programs_multiple/passwordGenerator.py index d1a76773e62..a6e3e8cae7d 100644 --- a/password_programs_multiple/passwordGenerator.py +++ b/password_programs_multiple/passwordGenerator.py @@ -2,23 +2,82 @@ # modified Prince Gangurde 4/4/2020 import random + import pycountry + def generate_password(): # Define characters and word sets special_characters = list("!@#$%/?<>|&*-=+_") - + animals = ( - "ant", "alligator", "baboon", "badger", "barb", "bat", "beagle", "bear", "beaver", "bird", - "bison", "bombay", "bongo", "booby", "butterfly", "bee", "camel", "cat", "caterpillar", - "catfish", "cheetah", "chicken", "chipmunk", "cow", "crab", "deer", "dingo", "dodo", "dog", - "dolphin", "donkey", "duck", "eagle", "earwig", "elephant", "emu", "falcon", "ferret", "fish", - "flamingo", "fly", "fox", "frog", "gecko", "gibbon", "giraffe", "goat", "goose", "gorilla" + "ant", + "alligator", + "baboon", + "badger", + "barb", + "bat", + "beagle", + "bear", + "beaver", + "bird", + "bison", + "bombay", + "bongo", + "booby", + "butterfly", + "bee", + "camel", + "cat", + "caterpillar", + "catfish", + "cheetah", + "chicken", + "chipmunk", + "cow", + "crab", + "deer", + "dingo", + "dodo", + "dog", + "dolphin", + "donkey", + "duck", + "eagle", + "earwig", + "elephant", + "emu", + "falcon", + "ferret", + "fish", + "flamingo", + "fly", + "fox", + "frog", + "gecko", + "gibbon", + "giraffe", + "goat", + "goose", + "gorilla", ) colours = ( - "red", "orange", "yellow", "green", "blue", "indigo", "violet", "purple", - "magenta", "cyan", "pink", "brown", "white", "grey", "black" + "red", + "orange", + "yellow", + "green", + "blue", + "indigo", + "violet", + "purple", + "magenta", + "cyan", + "pink", + "brown", + "white", + "grey", + "black", ) # Get random values @@ -45,5 +104,6 @@ def generate_password(): print("Based on Country:", country) print("Language Hint:", language) + # Run it generate_password() diff --git a/personal_translator.py b/personal_translator.py index 6a704d572c2..5a1c0b50ea0 100644 --- a/personal_translator.py +++ b/personal_translator.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Personal_translator.ipynb Automatically generated by Colaboratory. @@ -12,6 +11,7 @@ from googletrans import Translator + # make a simple function that will translate any language to english def text_translator(Text): translator = Translator() diff --git a/ph_email.py b/ph_email.py index 8656d489ce2..f4a31b9b8ef 100755 --- a/ph_email.py +++ b/ph_email.py @@ -58,7 +58,7 @@ print(f"{len(matches)} matches found") # if matches are found add then to file -if len(matches): +if matches: with open("matches.txt", "a") as file: for match in matches: file.write(match) diff --git a/ping_servers.py b/ping_servers.py index bce734e45e9..0efee5bacb3 100644 --- a/ping_servers.py +++ b/ping_servers.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import os # Load the Library Module import subprocess # Load the Library Module import sys # Load the Library Module @@ -29,7 +27,6 @@ ) sys.exit(0) else: - if ( len(sys.argv) < 3 ): # If no arguments are passed,display the help/instructions on how to run the script diff --git a/ping_subnet.py b/ping_subnet.py index e8eb28d933f..3ab80b50e5f 100644 --- a/ping_subnet.py +++ b/ping_subnet.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import os # Load the Library Module import subprocess # Load the Library Module import sys # Load the Library Module @@ -25,7 +23,6 @@ ) sys.exit(0) else: - if ( len(sys.argv) < 2 ): # If no arguments are passed then display the help and instructions on how to run the script diff --git a/polygon.py b/polygon.py index ba300f8a317..d22702900ef 100644 --- a/polygon.py +++ b/polygon.py @@ -1,5 +1,6 @@ -import pygame import sys + +import pygame from pygame.locals import * pygame.init() diff --git a/portscanner.py b/portscanner.py index 78fcde14a26..8e51c022cff 100644 --- a/portscanner.py +++ b/portscanner.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import optparse # Import the module from socket import * # Import the module from threading import * # Import the module diff --git a/power_of_n.py b/power_of_n.py index 69b8994be94..f0800006682 100644 --- a/power_of_n.py +++ b/power_of_n.py @@ -3,6 +3,7 @@ __version__ = "1.0.0" __date__ = "2023-09-03" + def binaryExponentiation(x: float, n: int) -> float: """ Function to calculate x raised to the power n (i.e., x^n) where x is a float number and n is an integer and it will return float value @@ -49,10 +50,9 @@ def binaryExponentiation(x: float, n: int) -> float: print(f"Version: {__version__}") print(f"Function Documentation: {binaryExponentiation.__doc__}") print(f"Date: {__date__}") - - print() # Blank Line + + print() # Blank Line print(binaryExponentiation(2.00000, 10)) print(binaryExponentiation(2.10000, 3)) print(binaryExponentiation(2.00000, -2)) - \ No newline at end of file diff --git a/powerdown_startup.py b/powerdown_startup.py index 7ce5f163c69..c440976b48f 100644 --- a/powerdown_startup.py +++ b/powerdown_startup.py @@ -15,9 +15,7 @@ def windows(): # This is the function to run if it detects the OS is windows. f = open("server_startup_" + strftime("%Y-%m-%d") + ".log", "a") # Open the logfile - for server in open( - "startup_list.txt", "r" - ): # Read the list of servers from the list + for server in open("startup_list.txt"): # Read the list of servers from the list ret = subprocess.call( "ping -n 3 %s" % server, shell=True, @@ -28,7 +26,7 @@ def windows(): # This is the function to run if it detects the OS is windows. f.write( "%s: is alive, loading PuTTY session" % server.strip() + "\n" ) # Write out to the logfile - subprocess.Popen(("putty -load " + server)) # Load the putty session + subprocess.Popen("putty -load " + server) # Load the putty session else: f.write( "%s : did not respond" % server.strip() + "\n" diff --git a/powers of 2.py b/powers of 2.py index 5ac0e09fc36..919f1e1528f 100644 --- a/powers of 2.py +++ b/powers of 2.py @@ -6,8 +6,8 @@ # terms = int(input("How many terms? ")) # use anonymous function -result = list(map(lambda x: 2 ** x, range(terms))) +result = list(map(lambda x: 2**x, range(terms))) -print("The total terms are:",terms) +print("The total terms are:", terms) for i in range(terms): - print("2 raised to power",i,"is",result[i]) + print("2 raised to power", i, "is", result[i]) diff --git a/powerup_checks.py b/powerup_checks.py index b29cd43ba61..31b209cf31a 100644 --- a/powerup_checks.py +++ b/powerup_checks.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import os # Load the Library Module import sqlite3 # Load the Library Module import subprocess # Load the Library Module @@ -42,7 +40,7 @@ def windows(): # This is the function to run if it detects the OS is windows. f = open(outputfile, "a") # Open the logfile - for server in open(serverfile, "r"): # Read the list of servers from the list + for server in open(serverfile): # Read the list of servers from the list # ret = subprocess.call("ping -n 3 %s" % server.strip(), shell=True,stdout=open('NUL', 'w'),stderr=subprocess.STDOUT) # Ping the servers in turn ret = subprocess.call( "ping -n 3 %s" % server.strip(), @@ -61,7 +59,7 @@ def windows(): # This is the function to run if it detects the OS is windows. def linux(): # This is the function to run if it detects the OS is nix. f = open("server_startup_" + strftime("%Y-%m-%d") + ".log", "a") # Open the logfile - for server in open(serverfile, "r"): # Read the list of servers from the list + for server in open(serverfile): # Read the list of servers from the list ret = subprocess.call( "ping -c 3 %s" % server, shell=True, diff --git a/primelib/primelib.py b/primelib/primelib.py index 65856679561..e4c0f7f9c80 100644 --- a/primelib/primelib.py +++ b/primelib/primelib.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Created on Thu Oct 5 16:44:23 2017 @@ -16,7 +15,7 @@ greatestPrimeFactor(number) smallestPrimeFactor(number) getPrime(n) -getPrimesBetween(pNumber1, pNumber2) +getPrimesBetween(pNumber1, pNumber2) ---- @@ -46,12 +45,13 @@ def pi(maxK=70, prec=1008, disp=1007): prec: precision of decimal places disp: number of decimal places shown """ - from decimal import Decimal as Dec, getcontext as gc + from decimal import Decimal as Dec + from decimal import getcontext as gc gc().prec = prec K, M, L, X, S = 6, 1, 13591409, 1, 13591409 for k in range(1, maxK + 1): - M = Dec((K ** 3 - (K << 4)) * M / k ** 3) + M = Dec((K**3 - (K << 4)) * M / k**3) L += 545140134 X *= -262537412640768000 S += Dec(M * L) / X @@ -68,9 +68,9 @@ def isPrime(number): """ # precondition - assert isinstance(number, int) and ( - number >= 0 - ), "'number' must been an int and positive" + assert isinstance(number, int) and (number >= 0), ( + "'number' must been an int and positive" + ) # 0 and 1 are none primes. if number <= 3: @@ -138,7 +138,6 @@ def getPrimeNumbers(N): # iterates over all numbers between 2 up to N+1 # if a number is prime then appends to list 'ans' for number in range(2, N + 1): - if isPrime(number): ans.append(number) @@ -169,14 +168,11 @@ def primeFactorization(number): quotient = number if number == 0 or number == 1: - ans.append(number) # if 'number' not prime then builds the prime factorization of 'number' elif not isPrime(number): - while quotient != 1: - if isPrime(factor) and (quotient % factor == 0): ans.append(factor) quotient /= factor @@ -202,9 +198,9 @@ def greatestPrimeFactor(number): """ # precondition - assert isinstance(number, int) and ( - number >= 0 - ), "'number' bust been an int and >= 0" + assert isinstance(number, int) and (number >= 0), ( + "'number' bust been an int and >= 0" + ) ans = 0 @@ -229,9 +225,9 @@ def smallestPrimeFactor(number): """ # precondition - assert isinstance(number, int) and ( - number >= 0 - ), "'number' bust been an int and >= 0" + assert isinstance(number, int) and (number >= 0), ( + "'number' bust been an int and >= 0" + ) ans = 0 @@ -289,9 +285,9 @@ def goldbach(number): """ # precondition - assert ( - isinstance(number, int) and (number > 2) and isEven(number) - ), "'number' must been an int, even and > 2" + assert isinstance(number, int) and (number > 2) and isEven(number), ( + "'number' must been an int, even and > 2" + ) ans = [] # this list will returned @@ -307,11 +303,9 @@ def goldbach(number): loop = True while i < lenPN and loop: - j = i + 1 while j < lenPN and loop: - if primeNumbers[i] + primeNumbers[j] == number: loop = False ans.append(primeNumbers[i]) @@ -359,9 +353,9 @@ def gcd(number1, number2): number2 = rest # precondition - assert isinstance(number1, int) and ( - number1 >= 0 - ), "'number' must been from type int and positive" + assert isinstance(number1, int) and (number1 >= 0), ( + "'number' must been from type int and positive" + ) return number1 @@ -388,13 +382,11 @@ def kgV(number1, number2): # for kgV (x,1) if number1 > 1 and number2 > 1: - # builds the prime factorization of 'number1' and 'number2' primeFac1 = primeFactorization(number1) primeFac2 = primeFactorization(number2) elif number1 == 1 or number2 == 1: - primeFac1 = [] primeFac2 = [] ans = max(number1, number2) @@ -406,11 +398,8 @@ def kgV(number1, number2): # iterates through primeFac1 for n in primeFac1: - if n not in done: - if n in primeFac2: - count1 = primeFac1.count(n) count2 = primeFac2.count(n) @@ -418,7 +407,6 @@ def kgV(number1, number2): ans *= n else: - count1 = primeFac1.count(n) for i in range(count1): @@ -428,9 +416,7 @@ def kgV(number1, number2): # iterates through primeFac2 for n in primeFac2: - if n not in done: - count2 = primeFac2.count(n) for i in range(count2): @@ -439,9 +425,9 @@ def kgV(number1, number2): done.append(n) # precondition - assert isinstance(ans, int) and ( - ans >= 0 - ), "'ans' must been from type int and positive" + assert isinstance(ans, int) and (ans >= 0), ( + "'ans' must been from type int and positive" + ) return ans @@ -463,7 +449,6 @@ def getPrime(n): ans = 2 # this variable holds the answer while index < n: - index += 1 ans += 1 # counts to the next number @@ -474,9 +459,9 @@ def getPrime(n): ans += 1 # precondition - assert isinstance(ans, int) and isPrime( - ans - ), "'ans' must been a prime number and from type int" + assert isinstance(ans, int) and isPrime(ans), ( + "'ans' must been a prime number and from type int" + ) return ans @@ -493,9 +478,9 @@ def getPrimesBetween(pNumber1, pNumber2): """ # precondition - assert ( - isPrime(pNumber1) and isPrime(pNumber2) and (pNumber1 < pNumber2) - ), "The arguments must been prime numbers and 'pNumber1' < 'pNumber2'" + assert isPrime(pNumber1) and isPrime(pNumber2) and (pNumber1 < pNumber2), ( + "The arguments must been prime numbers and 'pNumber1' < 'pNumber2'" + ) number = pNumber1 + 1 # jump to the next number @@ -507,7 +492,6 @@ def getPrimesBetween(pNumber1, pNumber2): number += 1 while number < pNumber2: - ans.append(number) number += 1 @@ -540,7 +524,6 @@ def getDivisors(n): ans = [] # will be returned. for divisor in range(1, n + 1): - if n % divisor == 0: ans.append(divisor) @@ -560,9 +543,9 @@ def isPerfectNumber(number): """ # precondition - assert isinstance(number, int) and ( - number > 1 - ), "'number' must been an int and >= 1" + assert isinstance(number, int) and (number > 1), ( + "'number' must been an int and >= 1" + ) divisors = getDivisors(number) diff --git a/print hello world.py b/print hello world.py index 0e3295e312d..1d6d4214987 100644 --- a/print hello world.py +++ b/print hello world.py @@ -1,3 +1,3 @@ # This program prints Hello, world! -print('Hello, world!') +print("Hello, world!") diff --git a/prison_break_scrapper.py b/prison_break_scrapper.py index ad50636cd6a..5aaf5ca5601 100644 --- a/prison_break_scrapper.py +++ b/prison_break_scrapper.py @@ -2,6 +2,7 @@ Scrapper for downloading prison break series from an open server and putting them in a designated folder. """ + import os import subprocess diff --git a/psunotify.py b/psunotify.py index 3d5ea4b99de..22b004e6803 100644 --- a/psunotify.py +++ b/psunotify.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import re import mechanize diff --git a/pyauto.py b/pyauto.py index 7f9a19e0e77..84ad25f3233 100644 --- a/pyauto.py +++ b/pyauto.py @@ -1,9 +1,9 @@ # Author-Slayking1965 # email-kingslayer8509@gmail.com import random -import pyautogui import string +import pyautogui chars = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000000..d0fda203b34 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,152 @@ +[project] +name = "python" +version = "0.1.0" +requires-python = ">=3.13" +dependencies = [ + "aiohttp>=3.12.14", + "apscheduler", + "auto-mix-prep", + "beautifulsoup4", + "ccxt", + "colorama", + "customtkinter", + "darkdetect", + "datetime", + "django", + "docx", + "emoji", + "fastapi", + "firebase-admin", + "fitz", + "flask", + "fpdf2", + "freegames", + "fuzzywuzzy", + "geocoder", + "google-api-python-client", + "googletrans", + "gtts", + "httplib2", + "httpx", + "hupper", + "inquirer", + "keras", + "keyboard", + "matplotlib", + "mediapipe", + "mutagen", + "mysql-connector-python", + "newspaper", + "nltk", + "numpy", + "openai", + "opencv-python", + "openpyxl", + "pafy>=0.5.5", + "pandas", + "pdf2docx", + "pdfkit", + "pillow", + "playsound", + "playsound3", + "plyer", + "protobuf", + "psutil", + "pyaudio", + "pyautogui", + "pycountry", + "pydantic", + "pygame", + "pyglet", + "pyjokes", + "pymongo", + "pymupdf", + "pynput", + "pypdf2", + "pyperclip", + "pyqrcode", + "pyqt5", + "pyserial", + "pyshorteners", + "pytesseract", + "python-docx", + "pyttsx3", + "pytube", + "pywhatkit", + "pywifi", + "pywin32", + "qrcode", + "quo", + "requests", + "requests-mock", + "rich", + "scikit-learn", + "seaborn", + "selenium", + "slab", + "socksipy-branch", + "solara", + "speechrecognition", + "speechtotext", + "tabula", + "tensorflow", + "thirdai", + "tkcalendar", + "tkinter", + "tkinterdnd2", + "tkinterweb", + "tornado", + "tqdm", + "translate", + "tweepy", + "twilio", + "ujson", + "unidecode", + "urllib3", + "watchdog", + "webbrowser", + "wikipedia", + "win10toast", + "word2number", + "xlrd", + "xlwt", + "xor-cipher", + "yfinance", +] + +[build-system] +requires = ["setuptools>=65", "wheel"] +build-backend = "setuptools.build_meta" + +[tool.codespell] +ignore-words-list = "3rt,abd,aer,ans,bitap,crate,damon,fo,followings,hist,iff,kwanza,manuel,mater,secant,som,sur,tim,toi,zar" +skip = "*.css,*.js,*.lock" + +[tool.ruff] +line-length = 88 +target-version = "py313" + +[tool.ruff.lint] +select = ["E", "F", "I", "UP", "YTT", "PLC", "PT", "SIM"] +ignore = [ + "B904", "B905", "PLC0415", + "PLW2901", "PT011", "PT018", "PT028", + "S101", "SIM905", "UP038" +] + +[tool.ruff.lint.per-file-ignores] +"__init__.py" = ["F401"] +"tests/**" = ["S101", "PT011", "PT018"] +".*_test\\.py" = ["S101", "PT011", "PT018"] + +[tool.mypy] +python_version = "3.13" +ignore_missing_imports = true +exclude = ".*venv.*|.*__pycache__.*|.*migrations.*" + +[[tool.mypy.overrides]] +module = [ + "django.*", "tensorflow.*", "keras.*", + "matplotlib.*", "pymongo.*" +] +ignore_missing_imports = true \ No newline at end of file diff --git a/python Space Invader game.py b/python Space Invader game.py index 2d07677f67e..3438f04dc16 100644 --- a/python Space Invader game.py +++ b/python Space Invader game.py @@ -1,6 +1,7 @@ -import pygame -import random import math +import random + +import pygame from pygame import mixer # initialization @@ -12,19 +13,19 @@ # background -background = pygame.image.load('background.png') +background = pygame.image.load("background.png") -#bg sound -mixer.music.load('background.wav') +# bg sound +mixer.music.load("background.wav") mixer.music.play(-1) # title and icon pygame.display.set_caption("Space Invendera") -icon = pygame.image.load('battleship.png') +icon = pygame.image.load("battleship.png") pygame.display.set_icon(icon) # player -playerimg = pygame.image.load('transport.png') +playerimg = pygame.image.load("transport.png") playerx = 370 playery = 480 playerx_change = 0 @@ -38,37 +39,40 @@ number_of_enemies = 6 for i in range(number_of_enemies): - enemyimg.append(pygame.image.load('enemy.png')) + enemyimg.append(pygame.image.load("enemy.png")) enemyx.append(random.randint(0, 800)) enemyy.append(random.randint(50, 150)) enemyx_change.append(2.5) enemyy_change.append(40) # bullet -bulletimg = pygame.image.load('bullet.png') +bulletimg = pygame.image.load("bullet.png") bulletx = 0 bullety = 480 bulletx_change = 0 bullety_change = 10 bullet_state = "ready" -#score +# score score_value = 0 -font = pygame.font.Font('freesansbold.ttf',32) +font = pygame.font.Font("freesansbold.ttf", 32) textx = 10 texty = 10 -#game over txt -over_font = pygame.font.Font('freesansbold.ttf',64) +# game over txt +over_font = pygame.font.Font("freesansbold.ttf", 64) + -def show_score(x ,y): - score = font.render("score :"+ str(score_value),True, (255, 255, 255)) +def show_score(x, y): + score = font.render("score :" + str(score_value), True, (255, 255, 255)) screen.blit(score, (x, y)) + def game_over_text(): over_txt = over_font.render("GAME OVER", True, (255, 255, 255)) screen.blit(over_txt, (200, 250)) + # for display player img def player(x, y): screen.blit(playerimg, (x, y)) @@ -76,7 +80,8 @@ def player(x, y): # foe desplaing enemy img -def enemy(x, y ,i): + +def enemy(x, y, i): screen.blit(enemyimg[i], (x, y)) @@ -87,7 +92,9 @@ def fire_bullet(x, y): def iscollision(enemyx, enemyy, bulletx, bullety): - distance = math.sqrt((math.pow(enemyx - bulletx, 2)) + (math.pow(enemyy - bullety, 2))) + distance = math.sqrt( + (math.pow(enemyx - bulletx, 2)) + (math.pow(enemyy - bullety, 2)) + ) if distance < 27: return True else: @@ -97,7 +104,6 @@ def iscollision(enemyx, enemyy, bulletx, bullety): # game loop running = True while running: - screen.fill((0, 0, 0)) # for bg img screen.blit(background, (0, 0)) @@ -107,20 +113,20 @@ def iscollision(enemyx, enemyy, bulletx, bullety): running = False # if keystroke in pressed whether it is right of left - if (event.type == pygame.KEYDOWN): - if (event.key == pygame.K_LEFT): + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_LEFT: playerx_change = -5 - if (event.key == pygame.K_RIGHT): + if event.key == pygame.K_RIGHT: playerx_change = 5 - if (event.key == pygame.K_SPACE): + if event.key == pygame.K_SPACE: if bullet_state == "ready": - bullet_sound = mixer.Sound('laser.wav') + bullet_sound = mixer.Sound("laser.wav") bullet_sound.play() bulletx = playerx fire_bullet(bulletx, bullety) - if (event.type == pygame.KEYUP): + if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT: playerx_change = 0 @@ -132,8 +138,7 @@ def iscollision(enemyx, enemyy, bulletx, bullety): playerx = 736 for i in range(number_of_enemies): - - #game over + # game over if enemyy[i] > 440: for j in range(number_of_enemies): enemyy[j] = 2000 @@ -152,7 +157,7 @@ def iscollision(enemyx, enemyy, bulletx, bullety): # collision collision = iscollision(enemyx[i], enemyy[i], bulletx, bullety) if collision: - explossion_sound = mixer.Sound('explosion.wav') + explossion_sound = mixer.Sound("explosion.wav") explossion_sound.play() bullety = 480 bullet_state = "ready" @@ -172,5 +177,5 @@ def iscollision(enemyx, enemyy, bulletx, bullety): bullety -= bullety_change player(playerx, playery) - show_score(textx,texty) + show_score(textx, texty) pygame.display.update() diff --git a/pythonVideoDownloader.py b/pythonVideoDownloader.py index 7bae8eac998..ce8422e367e 100644 --- a/pythonVideoDownloader.py +++ b/pythonVideoDownloader.py @@ -33,7 +33,6 @@ def get_video_links(): def download_video_series(video_links): for link in video_links: - """iterate through all links in video_links and download them one by one""" diff --git a/python_codes b/python_codes deleted file mode 100644 index 0f602a1a751..00000000000 --- a/python_codes +++ /dev/null @@ -1,2 +0,0 @@ -python_codes -print("Python") diff --git a/python_sms.py b/python_sms.py index b5e578b3b86..fb9d4f7d6aa 100644 --- a/python_sms.py +++ b/python_sms.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import os import sqlite3 import urllib # URL functions @@ -35,9 +33,7 @@ sname = row[0] snumber = row[1] - message = ( - f"{sname} There will be NO training tonight on the {tdate}. Sorry for the late notice, I have sent a mail as well, just trying to reach everyone, please do not reply to this message as this is automated" - ) + message = f"{sname} There will be NO training tonight on the {tdate}. Sorry for the late notice, I have sent a mail as well, just trying to reach everyone, please do not reply to this message as this is automated" username = "YOUR_USERNAME" sender = "WHO_IS_SENDING_THE_MAIL" @@ -67,10 +63,8 @@ postdata = urllib.urlencode(values) req = urllib2.Request(url, postdata) - print( f"Attempting to send SMS to {sname} at {snumber} on {tdate}") - f.write( - f"Attempting to send SMS to {sname} at {snumber} on {tdate}" - ) + print(f"Attempting to send SMS to {sname} at {snumber} on {tdate}") + f.write(f"Attempting to send SMS to {sname} at {snumber} on {tdate}") try: response = urllib2.urlopen(req) diff --git a/python_webscraper.py b/python_webscraper.py index a9322761a1c..fab418247d5 100644 --- a/python_webscraper.py +++ b/python_webscraper.py @@ -1,19 +1,20 @@ import requests from bs4 import BeautifulSoup + # Make a request on to your website page = requests.get("Paste your Website Domain here") -soup = BeautifulSoup(page.content, 'html.parser') +soup = BeautifulSoup(page.content, "html.parser") # Create all_h1_tags as empty list all_h1_tags = [] # Set all_h1_tags to all h1 tags of the soup -for element in soup.select('h1'): +for element in soup.select("h1"): all_h1_tags.append(element.text) # Create seventh_p_text and set it to 7th p element text of the page -seventh_p_text = soup.select('p')[6].text +seventh_p_text = soup.select("p")[6].text print(all_h1_tags, seventh_p_text) -# print all h1 elements and the text of the website on your console +# print all h1 elements and the text of the website on your console diff --git a/qrcode.py b/qrcode.py index 0b9a8d6179c..bfdc5372bfd 100644 --- a/qrcode.py +++ b/qrcode.py @@ -1,15 +1,15 @@ +import cv2 import qrcode -import cv2 -qr= qrcode.QRCode(version=1, box_size=10, border=5) +qr = qrcode.QRCode(version=1, box_size=10, border=5) data = input() qr.add_data(data) qr.make(fit=True) img = qr.make_image(fill_color="blue", back_color="white") -path=data+".png" +path = data + ".png" img.save(path) -cv2.imshow("QRCode",img) +cv2.imshow("QRCode", img) cv2.waitKey(0) cv2.destroyAllWindows() diff --git a/quiz_game.py b/quiz_game.py index c1ffd6696b0..cd2a8aff48c 100644 --- a/quiz_game.py +++ b/quiz_game.py @@ -1,32 +1,37 @@ -print('Welcome to AskPython Quiz') -answer=input('Are you ready to play the Quiz ? (yes/no) :') -score=0 -total_questions=3 - -if answer.lower()=='yes': - answer=input('Question 1: What is your Favourite programming language?') - if answer.lower()=='python': +print("Welcome to AskPython Quiz") +answer = input("Are you ready to play the Quiz ? (yes/no) :") +score = 0 +total_questions = 3 + +if answer.lower() == "yes": + answer = input("Question 1: What is your Favourite programming language?") + if answer.lower() == "python": score += 1 - print('correct') + print("correct") else: - print('Wrong Answer :(') - - - answer=input('Question 2: Do you follow any author on AskPython? ') - if answer.lower()=='yes': + print("Wrong Answer :(") + + answer = input("Question 2: Do you follow any author on AskPython? ") + if answer.lower() == "yes": score += 1 - print('correct') + print("correct") else: - print('Wrong Answer :(') - - answer=input('Question 3: What is the name of your favourite website for learning Python?') - if answer.lower()=='askpython': + print("Wrong Answer :(") + + answer = input( + "Question 3: What is the name of your favourite website for learning Python?" + ) + if answer.lower() == "askpython": score += 1 - print('correct') + print("correct") else: - print('Wrong Answer :(') - -print('Thankyou for Playing this small quiz game, you attempted',score,"questions correctly!") -mark=(score/total_questions)*100 -print('Marks obtained:',mark) -print('BYE!') \ No newline at end of file + print("Wrong Answer :(") + +print( + "Thankyou for Playing this small quiz game, you attempted", + score, + "questions correctly!", +) +mark = (score / total_questions) * 100 +print("Marks obtained:", mark) +print("BYE!") diff --git a/quote.py b/quote.py index ed3b1b1317f..f4feab06818 100644 --- a/quote.py +++ b/quote.py @@ -5,9 +5,10 @@ example quote -Quote Author Name """ -import requests from json import loads +import requests + def return_quote(): response = requests.get("https://zenquotes.io/api/random") diff --git a/random-sentences.py b/random-sentences.py index 3e6e8baacb7..5fa24789d26 100644 --- a/random-sentences.py +++ b/random-sentences.py @@ -20,14 +20,7 @@ def random_int(): def random_sentence(): """Creates random and return sentences.""" return ( - "{} {} {} {} {} {}".format( - article[random_int()], - noun[random_int()], - verb[random_int()], - preposition[random_int()], - article[random_int()], - noun[random_int()], - ) + f"{article[random_int()]} {noun[random_int()]} {verb[random_int()]} {preposition[random_int()]} {article[random_int()]} {noun[random_int()]}" ).capitalize() @@ -40,4 +33,4 @@ def random_sentence(): story = (". ").join(list(map(lambda x: random_sentence(), range(0, 20)))) # prints random sentences story -print("{}".format(story)) +print(f"{story}") diff --git a/random_file_move.py b/random_file_move.py index 38ccdc8649b..73e3a21945e 100644 --- a/random_file_move.py +++ b/random_file_move.py @@ -6,9 +6,9 @@ # Description : This will move specified number of files(given in ratio) from the src directory to dest directory. +import argparse import os import random -import argparse def check_ratio(x): @@ -57,7 +57,7 @@ def check_ratio(x): files = os.listdir(src) size = int(ratio * len(files)) -print("Move {} files from {} to {} ? [y/n]".format(size, src, dest)) +print(f"Move {size} files from {src} to {dest} ? [y/n]") if input().lower() == "y": for f in random.sample(files, size): try: diff --git a/randomloadingmessage.py b/randomloadingmessage.py index 71654d249b0..42ec5db166b 100644 --- a/randomloadingmessage.py +++ b/randomloadingmessage.py @@ -1,169 +1,127 @@ -# Created by Nathan R (Mosrod) -# CREDIT TO https://github.com/1egoman/funnies/blob/master/src/funnies.js +""" +Loading Screen Messages Generator -from random import * +Generates humorous loading screen messages inspired by https://github.com/1egoman/funnies +""" -x = 1 +import random -for i in range(x): - num = randint(1, 80) - if num == 1: - print("Reticulating splines...") - if num == 2: - print("Swapping time and space...") - if num == 3: - print("Spinning violently around the y-axis...") - if num == 4: - print("Tokenizing real life...") - if num == 5: - print("Bending the spoon...") - if num == 6: - print("Filtering morale...") - if num == 7: - print("We need a new fuse...") - if num == 8: - print("Have a good day.") - if num == 9: - print( - "Upgrading Windows, your PC will restart several times. Sit back and relax." - ) - if num == 10: - print("The architects are still drafting.") - if num == 11: - print("We're building the buildings as fast as we can.") - if num == 12: - print("Please wait while the little elves draw your map.") - if num == 13: - print("Don't worry - a few bits tried to escape, but we caught them.") - if num == 14: - print("Go ahead -- hold your breath!") - if num == 15: - print("...at least you're not on hold...") - if num == 16: - print("The server is powered by a lemon and two electrodes.") - if num == 17: - print("We're testing your patience.") - if num == 18: - print("As if you had any other choice.") - if num == 19: - print("The bits are flowing slowly today.") - if num == 20: - print("It's still faster than you could draw it.") - if num == 21: - print("My other loading screen is much faster.") - if num == 22: - print("(Insert quarter)") - if num == 23: - print("Are we there yet?") - if num == 24: - print("Just count to 10.") - if num == 25: - print("Don't panic...") - if num == 26: - print("We're making you a cookie.") - if num == 27: - print("Creating time-loop inversion field.") - if num == 28: - print("Computing chance of success.") - if num == 29: - print("All I really need is a kilobit.") - if num == 30: - print("I feel like im supposed to be loading something...") - if num == 31: - print("Should have used a compiled language...") - if num == 32: - print("Is this Windows?") - if num == 33: - print("Don't break your screen yet!") - if num == 34: - print("I swear it's almost done.") - if num == 35: - print("Let's take a mindfulness minute...") - if num == 36: - print("Listening for the sound of one hand clapping...") - if num == 37: - print("Keeping all the 1's and removing all the 0's...") - if num == 38: - print("We are not liable for any broken screens as a result of waiting.") - if num == 39: - print("Where did all the internets go?") - if num == 40: - print("Granting wishes...") - if num == 41: - print("Time flies when you’re having fun.") - if num == 42: - print("Get some coffee and come back in ten minutes...") - if num == 43: - print("Stay awhile and listen...") - if num == 44: - print("Convincing AI not to turn evil...") - if num == 45: - print("How did you get here?") - if num == 46: - print("Wait, do you smell something burning?") - if num == 47: - print("Computing the secret to life, the universe, and everything.") - if num == 48: - print("When nothing is going right, go left...") - if num == 49: - print("I love my job only when I'm on vacation...") - if num == 50: - print("Why are they called apartments if they are all stuck together?") - if num == 51: - print("I’ve got problem for your solution...") - if num == 52: - print("Whenever I find the key to success, someone changes the lock.") - if num == 53: - print("Constructing additional pylons...") - if num == 54: - print("You don’t pay taxes—they take taxes.") - if num == 55: - print("A commit a day keeps the mobs away.") - if num == 56: - print("This is not a joke, it's a commit.") - if num == 57: - print("Hello IT, have you tried turning it off and on again?") - if num == 58: - print("Hello, IT... Have you tried forcing an unexpected reboot?") - if num == 59: - print("I didn't choose the engineering life. The engineering life chose me.") - if num == 60: - print("Dividing by zero...") - if num == 61: - print("If I’m not back in five minutes, just wait longer.") - if num == 62: - print("Web developers do it with