diff --git a/Automatic_file_backup/ReadMe.md b/Automatic_file_backup/ReadMe.md new file mode 100644 index 0000000..e0e03a3 --- /dev/null +++ b/Automatic_file_backup/ReadMe.md @@ -0,0 +1,65 @@ +# Daily Folder Backup + +A tiny Python script that automatically backs up a folder to a destination directory once a day, timestamped by date. + +## Features + +- Runs continuously in the background and triggers a backup every day at a set time +- Copies an entire folder tree using `shutil.copytree` +- Names each backup by the date it was created (e.g. `2026-07-16`), so you get one snapshot per day +- Skips silently (with a message) if a backup for that day already exists, instead of crashing + +## Requirements + +- Python 3.7+ +- [`schedule`](https://pypi.org/project/schedule/) library + +Install the dependency with: + +```bash +pip install schedule +``` + +## Configuration + +Open the script and set the two path variables at the top: + +```python +source_dir = "/path/to/folder/to/back/up" +destination_dir = "/path/to/where/backups/go" +``` + +By default, the job runs daily at `12:00` (24-hour format). To change the time, edit this line: + +```python +schedule.every().day.at("12:00").do(...) +``` + +## Usage + +Run the script and leave it running (e.g. in a terminal, `tmux`/`screen` session, or as a background service): + +```bash +python automatic_file_backup.py +``` + +Each day at the scheduled time, it will create a new folder inside `destination_dir` named after the current date, containing a full copy of `source_dir`. + +## How it works + +1. `schedule` checks every 60 seconds whether it's time to run the backup job. +2. When triggered, `copy_folder_to_directionary()` builds a destination path using today's date. +3. `shutil.copytree` recursively copies the source folder into that dated destination. +4. If a folder for that date already exists, a `FileExistsError` is caught and a message is printed instead of overwriting or crashing. + +## Limitations & ideas for contribution + +- Only one backup per day is supported (running twice in a day just logs "already exists") +- No cleanup/rotation of old backups — the destination folder will grow indefinitely +- No logging to a file, only `print` statements +- Could be extended with: + - Configurable backup retention (e.g. delete backups older than N days) + - Support for multiple source folders + - Compression (zip/tar) instead of a raw folder copy + - A config file or CLI args instead of hardcoded paths + - Proper logging via Python's `logging` module diff --git a/Automatic_file_backup/automatic_file_backup.py b/Automatic_file_backup/automatic_file_backup.py new file mode 100644 index 0000000..21c8392 --- /dev/null +++ b/Automatic_file_backup/automatic_file_backup.py @@ -0,0 +1,28 @@ +import time +import schedule +import datetime +import shutil +import os + +source_dir = "" # Set this to the folder you want to back up +destination_dir = "" # Set this to where backups should be saved + + +def copy_folder_to_directionary(source, dest): + today = datetime.date.today() + dest_dir = os.path.join(dest, str(today)) + + try: + shutil.copytree(source, dest_dir) + print(f"Folder copied to: {dest_dir}") + + except FileExistsError: + print(f"folderalready exists in {dest}") + + +schedule.every().day.at("12:00").do(lambda: copy_folder_to_directionary(source_dir, destination_dir) + ) + +while True: + schedule.run_pending() + time.sleep(60) diff --git a/Mastermnd/Readme.md b/Mastermnd/Readme.md new file mode 100644 index 0000000..e3441e6 --- /dev/null +++ b/Mastermnd/Readme.md @@ -0,0 +1,54 @@ +# Mastermind (CLI) + +A terminal implementation of the classic **Mastermind** code-breaking game. The computer generates a secret 4-color code, and you have a limited number of tries to guess it — with feedback after each guess telling you how close you are. + +## How to play + +- The computer picks a secret code of 4 colors (repeats allowed) from: `R`, `G`, `B`, `Y`, `W`, `O` (Red, Green, Blue, Yellow, White, Orange) +- You have 10 tries to guess the exact code +- After each guess, you're told: + - **Correct Positions** — how many colors are the right color _and_ in the right spot + - **Incorrect Positions** — how many colors are in your guess and in the code, but in the wrong spot +- Guess all 4 correctly to win. Run out of tries and the code is revealed. + +## Requirements + +- Python 3.6+ (no external dependencies) + +## Usage + +Run the script: + +```bash +python mastermind.py +``` + +Enter your guess as 4 space-separated colors, for example: + +``` +Guess: R G B Y +``` + +The game will validate your input (correct length, valid colors) before scoring it. + +## How it works + +- `generate_code()` builds a random 4-color secret code from `COLORS`. +- `guess_code()` reads and validates player input, looping until a valid guess (right length, valid colors) is entered. +- `check_code()` scores a guess against the code: + 1. Counts how many of each color exist in the code. + 2. First pass: counts exact matches (right color, right position), decrementing the color count as each is used. + 3. Second pass: counts color matches in the wrong position, using only colors not already claimed by an exact match — this prevents double-counting a color that only appears once in the code. +- `game()` runs the main loop: generate a code, take guesses up to `TRIES` times, and report the result. + +## Limitations & ideas for contribution + +- No support for changing code length, color set, or number of tries without editing constants directly in the source +- No hint system beyond correct/incorrect position counts +- No replay prompt — the game ends after one round +- Could be extended with: + - Command-line arguments or a config option for difficulty (code length, number of colors, tries) + - A "play again?" loop + - Colored terminal output (e.g. using `colorama`) instead of letter codes + - A guess history/board showing all previous guesses and their scores + - Unit tests for `check_code()`, especially around duplicate-color edge cases diff --git a/Mastermnd/mastermind.py b/Mastermnd/mastermind.py new file mode 100644 index 0000000..53af2dc --- /dev/null +++ b/Mastermnd/mastermind.py @@ -0,0 +1,86 @@ +import random + +COLORS = ["R", "G", "B", "Y", "W", "O"] +TRIES = 10 +CODE_LENGTH = 4 + + +def generate_code(): + code = [] + + for _ in range(CODE_LENGTH): + color = random.choice(COLORS) + code.append(color) + + return code + + +def guess_code(): + while True: + + guess = input("Guess: ").upper().split(" ") + + if len(guess) != CODE_LENGTH: + print(f"You must guess {CODE_LENGTH} colors.") + continue + + for color in guess: + if color not in COLORS: + print(f"Invalid color: {color}. Try again.") + break + + else: + break + + return guess + + +def check_code(guess, real_code): + color_counts = {} + correct_pos = 0 + incorrect_pos = 0 + + for color in real_code: + if color not in color_counts: + color_counts[color] = 0 + + color_counts[color] += 1 + + for guess_color, real_color in zip(guess, real_code): + if guess_color == real_color: + correct_pos += 1 + color_counts[guess_color] -= 1 + + for guess_color, real_color in zip(guess, real_code): + if guess_color in color_counts and color_counts[guess_color] > 0: + incorrect_pos += 1 + color_counts[guess_color] -= 1 + + return correct_pos, incorrect_pos + + +def game(): + print(f"Welcome to MASTERMIND") + print(f"You have {TRIES} to gues the code !") + print("The valid colors are", COLORS) + print("") + + code = generate_code() + + for attempts in range(1, TRIES+1): + guess = guess_code() + correct_pos, incorrect_pos = check_code(guess, code) + + if correct_pos == CODE_LENGTH: + print(f"You guessed the code in {attempts} tries!") + break + + print( + f"Correct Positions:{correct_pos} | Incorrect Positions: {incorrect_pos}") + + else: + print("You ran out of tries, the code was:", code) + + +if __name__ == "__main__": + game() diff --git a/Youtube-Downloader/Readme.md b/Youtube-Downloader/Readme.md new file mode 100644 index 0000000..78067c7 --- /dev/null +++ b/Youtube-Downloader/Readme.md @@ -0,0 +1,60 @@ +# YouTube Video Downloader + +A small Python script that downloads a YouTube video from a URL you provide, letting you pick the save folder through a native file browser dialog. + +## Features + +- Prompts for a YouTube URL directly in the terminal +- Opens a native folder-picker dialog (via `tkinter`) so you can choose where the video is saved +- Uses [`yt-dlp`](https://github.com/yt-dlp/yt-dlp) under the hood to handle the actual download, so it benefits from yt-dlp's format support and site compatibility +- Saves the file using the video's title as the filename + +## Requirements + +- Python 3.7+ +- [`yt-dlp`](https://pypi.org/project/yt-dlp/) +- `tkinter` (included with most standard Python installs; on some Linux distros you may need to install it separately, e.g. `sudo apt install python3-tk`) + +Install the dependency with: + +```bash +pip install yt-dlp +``` + +## Usage + +Run the script: + +```bash +python downloader.py +``` + +You'll be prompted to: + +1. Enter the YouTube URL you want to download +2. Choose a destination folder in the dialog that pops up + +The video will then download to that folder, named after its title. + +## How it works + +1. `open_file_dialog()` opens a folder-selection dialog using `tkinter.filedialog.askdirectory()` and returns the chosen path. +2. `download_video()` configures `yt-dlp` with an output template (`%(title)s.%(ext)s`) pointed at that folder and the `"best"` format, then downloads the video. +3. Errors during download (invalid URL, network issues, etc.) are caught and printed rather than crashing the script. + +## Limitations & ideas for contribution + +- Only supports a single video URL per run (no playlist support) +- Always downloads the `"best"` format — no option to choose resolution, audio-only, or a specific format +- No progress bar; you won't see download progress until it finishes or errors +- No URL validation before attempting the download +- Could be extended with: + - A simple GUI wrapping the whole flow (not just the folder picker) + - Format/quality selection (e.g. audio-only extraction) + - Playlist and batch URL support + - A progress hook using `yt-dlp`'s `progress_hooks` option + - Retry logic for transient network failures + +## License + +MIT (or update to match your project's license). diff --git a/Youtube-Downloader/yt_downloader.py b/Youtube-Downloader/yt_downloader.py new file mode 100644 index 0000000..eb501c9 --- /dev/null +++ b/Youtube-Downloader/yt_downloader.py @@ -0,0 +1,43 @@ + +from yt_dlp import YoutubeDL +import tkinter as tk +from tkinter import filedialog + + +def download_video(url, save_path): + try: + ydl_opts = { + "outtmpl": f"{save_path}/%(title)s.%(ext)s", + "format": "best" + } + + with YoutubeDL(ydl_opts) as ydl: + ydl.download([url]) + + print("Video downloaded successfully!") + + except Exception as e: + print("Error:", e) + + +def open_file_dialog(): + folder = filedialog.askdirectory() + + if folder: + print(f"Selected folder: {folder}") + + return folder + + +if __name__ == "__main__": + root = tk.Tk() + root.withdraw() + + video_url = input("Please enter a YouTube URL: ") + save_dir = open_file_dialog() + + if save_dir: + print("Started download................") + download_video(video_url, save_dir) + else: + print("Invalid save location.")