diff --git a/0x01-Dice/README.md b/0x01-Dice/README.md index 1999c63..62f5ab5 100644 --- a/0x01-Dice/README.md +++ b/0x01-Dice/README.md @@ -1,9 +1,18 @@ # DICE SIMULATOR -![maxresdefault](https://github.com/victorpreston/Python-CodeNest/assets/112781610/47c94ef9-9276-40ec-8f0a-713759220723) - ## What is a dice simulator ? Dice roller is a game where user is asked to choose a value from 1 to 6 and launch the dice. The fun happens when the dice falls. +## Run +Use the main file to simulate the rolling of a dice. +`python3 main.py` + +The simulation prompts the user to play a dice. + +Type `y`- To continue to Play + `n` - To stop the play + +## Screenshot Sample +![Screenshot from 2023-07-07 21-50-45](https://github.com/victorpreston/Python-CodeNest/assets/112781610/b22fb0b7-3561-4b4d-9aa8-103106662d60) diff --git a/0x09-Shutdown/main.py b/0x09-Shutdown/main.py index ef08bc5..148c2dc 100644 --- a/0x09-Shutdown/main.py +++ b/0x09-Shutdown/main.py @@ -8,7 +8,7 @@ def systemOffRestart(): import os print("enter r for restart") print("enter s for shutdown") - print("enter any key for exot") + print("enter any key for exit") option = input("enter your option") if option == "r": diff --git a/0x17-Sudoku/README.md b/0x17-Sudoku/README.md index 7ac48df..e2aefb8 100644 --- a/0x17-Sudoku/README.md +++ b/0x17-Sudoku/README.md @@ -1,32 +1,2 @@ -# Sudoku solver -Sudoku solver using backtracking - -Basically in sudoku, we want to be able to solve a sudoku puzzle given an input like this, -which represents a sudoku board: -``` -[[x00, x01, x02, x03... x08], - [x10, x11, x12, x13... x18], - ... - [x80, x81, x82, x83... x88]] -``` -These x_rc values correspond to the value at the rth row, cth column (starting with 0-index) -These values could be empty (we will represent this with -1) - -So for example, -``` -[[-1, 1, 5, ...], - [-1, -1, -1, ...], - [ 6, -1, -1, ...] - ...] -``` -would represent a board like this: -``` - ----------- -| 1 5 | ... -| | ... -| 6 | ... - ----------- - ... -``` -Now, our goal is to solve our sudoku puzzle using Python! :D - +## Sudoku on Console +## Sudoku on GUI diff --git a/0x17-Sudoku/SudokuConsole/README.md b/0x17-Sudoku/SudokuConsole/README.md new file mode 100644 index 0000000..7ac48df --- /dev/null +++ b/0x17-Sudoku/SudokuConsole/README.md @@ -0,0 +1,32 @@ +# Sudoku solver +Sudoku solver using backtracking + +Basically in sudoku, we want to be able to solve a sudoku puzzle given an input like this, +which represents a sudoku board: +``` +[[x00, x01, x02, x03... x08], + [x10, x11, x12, x13... x18], + ... + [x80, x81, x82, x83... x88]] +``` +These x_rc values correspond to the value at the rth row, cth column (starting with 0-index) +These values could be empty (we will represent this with -1) + +So for example, +``` +[[-1, 1, 5, ...], + [-1, -1, -1, ...], + [ 6, -1, -1, ...] + ...] +``` +would represent a board like this: +``` + ----------- +| 1 5 | ... +| | ... +| 6 | ... + ----------- + ... +``` +Now, our goal is to solve our sudoku puzzle using Python! :D + diff --git a/0x17-Sudoku/sudoku.py b/0x17-Sudoku/SudokuConsole/sudoku.py similarity index 100% rename from 0x17-Sudoku/sudoku.py rename to 0x17-Sudoku/SudokuConsole/sudoku.py diff --git a/0x17-Sudoku/SudokuGui/.vs/ProjectSettings.json b/0x17-Sudoku/SudokuGui/.vs/ProjectSettings.json new file mode 100644 index 0000000..f8b4888 --- /dev/null +++ b/0x17-Sudoku/SudokuGui/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": null +} \ No newline at end of file diff --git a/0x17-Sudoku/SudokuGui/.vs/Sudoku_Solver/v16/.suo b/0x17-Sudoku/SudokuGui/.vs/Sudoku_Solver/v16/.suo new file mode 100644 index 0000000..4157b15 Binary files /dev/null and b/0x17-Sudoku/SudokuGui/.vs/Sudoku_Solver/v16/.suo differ diff --git a/0x17-Sudoku/SudokuGui/.vs/VSWorkspaceState.json b/0x17-Sudoku/SudokuGui/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..6b61141 --- /dev/null +++ b/0x17-Sudoku/SudokuGui/.vs/VSWorkspaceState.json @@ -0,0 +1,6 @@ +{ + "ExpandedNodes": [ + "" + ], + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/0x17-Sudoku/SudokuGui/.vs/slnx.sqlite b/0x17-Sudoku/SudokuGui/.vs/slnx.sqlite new file mode 100644 index 0000000..70ea63f Binary files /dev/null and b/0x17-Sudoku/SudokuGui/.vs/slnx.sqlite differ diff --git a/0x17-Sudoku/SudokuGui/README.md b/0x17-Sudoku/SudokuGui/README.md new file mode 100644 index 0000000..4d03391 --- /dev/null +++ b/0x17-Sudoku/SudokuGui/README.md @@ -0,0 +1,16 @@ +# SudokuSolver +Solve any Suduko puzzle using this solver GUI built using Python and Tkinter. +The code uses a backtracking algorithm to solve the puzzle. + +

Running the Program

+There are two ways to run the program. + +* The first of which involves using the GUI. Begin by importing gui.py into your IDE of choice. Then run the program and a window will appear. +* Input your chosen Sudoku puzzle into the cells of the window. Leave any empty cells blank. Then simply click `solve` to complete the puzzle or `clear` to clear the puzzle. + +Alternatively, you can run the program without a GUI using the `solver.py` script. Simply import the script into your IDE of choice. Then fill out the 2D board vector at the top of the file. + +Fill in empty cells with a zero. After filling in the board vector, you can run the program. The output will be printed to the console. +## Screenshot +![Screenshot from 2023-07-09 16-01-17](https://github.com/victorpreston/Python-CodeNest/assets/112781610/d56d7904-32db-4da3-8335-101a96de6e82) + diff --git a/0x17-Sudoku/SudokuGui/__pycache__/solver.cpython-38.pyc b/0x17-Sudoku/SudokuGui/__pycache__/solver.cpython-38.pyc new file mode 100644 index 0000000..16ccb87 Binary files /dev/null and b/0x17-Sudoku/SudokuGui/__pycache__/solver.cpython-38.pyc differ diff --git a/0x17-Sudoku/SudokuGui/gui.py b/0x17-Sudoku/SudokuGui/gui.py new file mode 100644 index 0000000..9164736 --- /dev/null +++ b/0x17-Sudoku/SudokuGui/gui.py @@ -0,0 +1,147 @@ +''' +GUI which allows you to solve any Sudoku puzzle. + +The GUI has been created using Tkinter and a backtracking algorithm has been used. +''' + +from tkinter import * + +root = Tk() +root.geometry('330x370') + +# Sudoku solver class +class SudokuSolver(): + + def __init__(self): + self.setZero() + self.solve() + + # Set the empty cells to 0 (i.e. the cells you have not filled in) + def setZero(self): + for i in range(9): + for j in range(9): + if filledBoard[i][j].get() not in ['1','2','3','4','5','6','7','8','9']: + filledBoard[i][j].set(0) + + # Solve using backtracking + def solve(self): + # Find next empty cell + findEmpty = self.emptyCell() + + if not findEmpty: + return True + else: + row, column = findEmpty + + for i in range(1,10): + if self.isValid(i, (row, column)): + filledBoard[row][column].set(i) + + if self.solve(): + return True + + filledBoard[row][column].set(0) + + return False + + # Check row, column and subgrid(3x3 square) to see if number can be placed in cell + def isValid (self, num, pos): + # Check Row + for i in range(9): + if filledBoard[pos[0]][i].get() == str(num): + return False + # Check Column + for i in range(9): + if filledBoard[i][pos[1]].get() == str(num): + return False + + # Check Sub Grid + row = pos[0] // 3 + column = pos[1] // 3 + + for i in range(row * 3, (row * 3) + 3): + for j in range(column * 3, (column * 3) + 3): + if filledBoard[i][j].get() == str(num): + return False + return True + + # Find empty cells, defined as cells filled with a zero + def emptyCell(self): + for row in range(9): + for column in range(9): + if filledBoard[row][column].get() == '0': + return (row,column) + return None + +# GUI class +class Interface(): + def __init__(self, window): + self.window = window + window.title("Sudoku Solver") + + font = ('Arial', 20) + color = 'white' + + # Create solve and clear button and link them to Solve and Clear methods + solve = Button(window, text = 'Solve', command = self.Solve) + solve.grid(column=3,row=20) + clear = Button(window, text = 'Clear', command = self.Clear) + clear.grid(column = 5,row=20) + + # Initialise empty 2D list + self.board = [] + for row in range(9): + self.board += [["","","","","","","","",""]] + + for row in range(9): + for col in range(9): + # Change color of cells depending on position in grid + if (row < 3 or row > 5) and (col < 3 or col > 5): + color = 'white' + elif (row >= 3 and row < 6) and (col >=3 and col < 6): + color = 'white' + else: + color = 'grey' + + # Make each cell of grid a entry box and store each user entry into the filledBoard 2D list + self.board[row][col] = Entry(window, width = 2, font = font, bg = color, cursor = 'arrow', borderwidth = 2, + highlightcolor = 'yellow', highlightthickness = 0, highlightbackground = 'black', + textvariable = filledBoard[row][col]) + self.board[row][col].bind('', self.gridChecker) # Link to better understand binding statements: https://www.python-course.eu/tkinter_events_binds.php#:~:text=Tkinter%20provides%20a%20mechanism%20to,and%20methods%20to%20an%20event.&text=If%20the%20defined%20event%20occurs,describing%20the%20event. + self.board[row][col].bind('', self.gridChecker) + self.board[row][col].grid(row = row, column = col) + + # Function to check if user enters a value which is not an int between 1 and 9 (valid numbers in Sudoku game). + # If entry is not valid, clear value + def gridChecker(self, event): + for row in range(9): + for col in range(9): + if filledBoard[row][col].get() not in ['1','2','3','4','5','6','7','8','9']: + filledBoard[row][col].set('') + + # Call Sudoku solver class (called by solve button) + def Solve(self): + SudokuSolver() + + # Function to clear board (called by clear button) + def Clear(self): + for row in range(9): + for col in range(9): + filledBoard[row][col].set('') + +# Global 2D list which saved in the values the user enters on the GUI +# Each value in the 2D list is set as a StringVar(), a class in Tkinter +# which allows you to save values users enter into the Entry widget +filledBoard = [] +for row in range(9): + filledBoard += [["","","","","","","","",""]] +for row in range(9): + for col in range(9): + filledBoard[row][col] = StringVar(root) + +# Main Loop +Interface(root) +root.mainloop() + + + diff --git a/0x17-Sudoku/SudokuGui/solver.py b/0x17-Sudoku/SudokuGui/solver.py new file mode 100644 index 0000000..fed28fc --- /dev/null +++ b/0x17-Sudoku/SudokuGui/solver.py @@ -0,0 +1,66 @@ +import numpy as np +board = [ + [5,3,0,0,7,0,0,0,0], + [6,0,0,1,9,5,0,0,0], + [0,9,8,0,0,0,0,6,0], + [8,0,0,0,6,0,0,0,3], + [4,0,0,8,0,3,0,0,1], + [7,0,0,0,2,0,0,0,6], + [0,6,0,0,0,0,2,8,0], + [0,0,0,4,1,9,0,0,5], + [0,0,0,0,8,0,0,7,9] +] + +def solve(board): + # Find next empty cell + findEmpty = emptyCell(board) + + if not findEmpty: + return True # Board is filled + else: + row, column = findEmpty + + for i in range(1,10): + if isValid(board, i, (row, column)): + board[row][column] = i + + if solve(board): + return True + + board[row][column] = 0 + + return False + + +def isValid (board, num, pos): + # Check Row + for i in range(9): + if num == board[pos[0]][i]: + return False + # Check Column + for i in range(9): + if num == board[i][pos[1]]: + return False + + # Check Sub Grid + row = pos[0] // 3 + column = pos[1] // 3 + + for i in range(row * 3, (row * 3) + 3): + for j in range(column * 3, (column * 3) + 3): + if num == board[i][j]: + return False + return True + +def emptyCell(board): + for row in range(9): + for column in range(9): + if board[row][column] == 0: + return (row,column) + return None + +def printBoard(board): + print(np.matrix(board)) + + + \ No newline at end of file diff --git a/0x20-AutomatedMailing/README.md b/0x20-AutomatedMailing/README.md index 2a71403..cf0c6f5 100644 --- a/0x20-AutomatedMailing/README.md +++ b/0x20-AutomatedMailing/README.md @@ -1,10 +1,10 @@ # Automated Mailing -## 🛠️ Description +## Description This code helps automate the process of sending mail to large audience.It takes email addresses stored in the CSV file. -## ⚙️ Languages or Frameworks Used +## Languages or Frameworks Used Modules required are `os` , `email.mime` , `smtplib` , `pandas`. @@ -12,13 +12,9 @@ These are listed in `requirements.txt` . USe the below command to install these ```pip install requirements.txt``` -## 🌟 How to run +## How to run - Update the `from_addr` and `pd.read_csv("filepath")` - Assign `email` with your email-id & `password` with your e-mail password. - Run script - -## 🤖 Author - -[Pradhyuman Arora](https://github.com/pradhyumanarora) diff --git a/0x21TextEditor/README.md b/0x21TextEditor/README.md new file mode 100644 index 0000000..fe3ef01 --- /dev/null +++ b/0x21TextEditor/README.md @@ -0,0 +1,28 @@ +# About +This is a text editor written in python using the PyQt5 library + +# Features +- Change text size +- Make text bold +- Make text italic +- Underline text +- Copy Paste and Cut text +- Redo and Undo actions +- Save the file in PDF format + +## Install the Dependencies + +To use this first you need to make sure, Python3 is installed in your system. +To install Python3 in your system you may checkout Python's official downloads [page](https://www.python.org/downloads/). + +Then you need to install the PyQt5 module by running the following command in your terminal: + +```bash +pip install PyQt5 +``` + +## Screenshot, this is the screenshot of the editor: + +![Screenshot from 2023-07-07 21-37-23](https://github.com/victorpreston/Python-CodeNest/assets/112781610/2c8106b2-b149-46d1-af19-e31e97f4df47) + + diff --git a/0x21TextEditor/Sample.jpg b/0x21TextEditor/Sample.jpg new file mode 100644 index 0000000..4604558 Binary files /dev/null and b/0x21TextEditor/Sample.jpg differ diff --git a/0x21TextEditor/bold.png b/0x21TextEditor/bold.png new file mode 100644 index 0000000..33a54ff Binary files /dev/null and b/0x21TextEditor/bold.png differ diff --git a/0x21TextEditor/copy.png b/0x21TextEditor/copy.png new file mode 100644 index 0000000..bfd39f2 Binary files /dev/null and b/0x21TextEditor/copy.png differ diff --git a/0x21TextEditor/cut.png b/0x21TextEditor/cut.png new file mode 100644 index 0000000..54f62f4 Binary files /dev/null and b/0x21TextEditor/cut.png differ diff --git a/0x21TextEditor/italic.png b/0x21TextEditor/italic.png new file mode 100644 index 0000000..13bb48f Binary files /dev/null and b/0x21TextEditor/italic.png differ diff --git a/0x21TextEditor/main.py b/0x21TextEditor/main.py new file mode 100644 index 0000000..e0559f4 --- /dev/null +++ b/0x21TextEditor/main.py @@ -0,0 +1,113 @@ +from typing import Text +from PyQt5.QtGui import QFont, QIcon +from PyQt5.QtWidgets import * +import sys +from PyQt5.QtPrintSupport import * + + +class Text_Editor(QMainWindow): + def __init__(self): + super(Text_Editor, self).__init__() + self.editor = QTextEdit() + self.editor.setFontPointSize(21) + self.setCentralWidget(self.editor) + self.font_size_box = QSpinBox() + self.showMaximized() + self.setWindowTitle("Text Editor") + self.create_toolbar() + self.create_menu_bar() + + def create_menu_bar(self): + menu_bar = QMenuBar() + file_menu = QMenu("File", self) + menu_bar.addMenu(file_menu) + + save_as_pdf_action = QAction("Save as PDF", self) + save_as_pdf_action.triggered.connect(self.save_as_pdf) + file_menu.addAction(save_as_pdf_action) + + self.setMenuBar(menu_bar) + + def create_toolbar(self): + + tool_bar = QToolBar() + undo_action = QAction(QIcon("undo.png"), "undo", self) + undo_action.triggered.connect(self.editor.undo) + tool_bar.addAction(undo_action) + self.addToolBar(tool_bar) + + redo_action = QAction(QIcon("redo.png"), "redo", self) + redo_action.triggered.connect(self.editor.redo) + tool_bar.addAction(redo_action) + + tool_bar.addSeparator() + tool_bar.addSeparator() + + cut_action = QAction(QIcon("cut.png"), "cut", self) + cut_action.triggered.connect(self.editor.cut) + tool_bar.addAction(cut_action) + + copy_action = QAction(QIcon("copy.png"), "copy", self) + copy_action.triggered.connect(self.editor.copy) + tool_bar.addAction(copy_action) + + paste_action = QAction(QIcon("paste.png"), "paste", self) + paste_action.triggered.connect(self.editor.paste) + tool_bar.addAction(paste_action) + + tool_bar.addSeparator() + tool_bar.addSeparator() + + self.font_size_box.setValue(20) + self.font_size_box.valueChanged.connect(self.set_font_size) + tool_bar.addWidget(self.font_size_box) + + tool_bar.addSeparator() + + # bold + bold_action = QAction(QIcon("bold.png"), 'Bold', self) + bold_action.triggered.connect(self.bold_text) + tool_bar.addAction(bold_action) + + underline_action = QAction(QIcon("underline.png"), 'Underline', self) + underline_action.triggered.connect(self.underline_text) + tool_bar.addAction(underline_action) + + italic_action = QAction(QIcon("italic.png"), 'Italic', self) + italic_action.triggered.connect(self.italic_text) + tool_bar.addAction(italic_action) + + # separator + tool_bar.addSeparator() + + def italic_text(self): + state = self.editor.fontItalic() + self.editor.setFontItalic(not(state)) + + def underline_text(self): + state = self.editor.fontUnderline() + self.editor.setFontUnderline(not(state)) + + def bold_text(self): + if self.editor.fontWeight() != QFont.Bold: + self.editor.setFontWeight(QFont.Bold) + return + self.editor.setFontWeight(QFont.Normal) + + def set_font_size(self): + value = self.font_size_box.value() + self.editor.setFontPointSize(value) + + def save_as_pdf(self): + file_path, _ = QFileDialog.getSaveFileName( + self, "Export PDF", None, "PDF Files (*.pdf)") + printer = QPrinter(QPrinter.HighResolution) + printer.setOutputFormat(QPrinter.PdfFormat) + printer.setOutputFileName(file_path) + self.editor.document().print_(printer) + + +app = QApplication(sys.argv) +window = Text_Editor() +window.show() +sys.exit(app.exec_()) diff --git a/0x21TextEditor/paste.png b/0x21TextEditor/paste.png new file mode 100644 index 0000000..f7765db Binary files /dev/null and b/0x21TextEditor/paste.png differ diff --git a/0x21TextEditor/redo.png b/0x21TextEditor/redo.png new file mode 100644 index 0000000..1d0c011 Binary files /dev/null and b/0x21TextEditor/redo.png differ diff --git a/0x21TextEditor/underline.png b/0x21TextEditor/underline.png new file mode 100644 index 0000000..4e8ff2a Binary files /dev/null and b/0x21TextEditor/underline.png differ diff --git a/0x21TextEditor/undo.png b/0x21TextEditor/undo.png new file mode 100644 index 0000000..2de5718 Binary files /dev/null and b/0x21TextEditor/undo.png differ diff --git a/0x22-YouTubeViewer/pythonVideo.py b/0x22-YouTubeViewer/pythonVideo.py new file mode 100644 index 0000000..396a048 --- /dev/null +++ b/0x22-YouTubeViewer/pythonVideo.py @@ -0,0 +1,11 @@ +import vlc + +import pafy + +url = "https://www.youtube.com/watch?v=LA9tjiiAvN0&pp=ygUjcGFydGl0aWlvbmluZyBzdG9yYWdlIG9uIHdpbmRvd3MgMTE%3D" + +video = pafy.new(url) +best = video.getbest() +media = vlc.MediaPlayer(best.url) + +media.play() \ No newline at end of file diff --git a/0x23-WebCloner/README.md b/0x23-WebCloner/README.md new file mode 100644 index 0000000..8961393 --- /dev/null +++ b/0x23-WebCloner/README.md @@ -0,0 +1,12 @@ +Website cloner | Python +Website cloner is CLI tool to download website using python requests library. + +Modules + 1. os + 2. sys + 3. requests +How to Run + +``` +python website_cloner.py +``` \ No newline at end of file diff --git a/0x23-WebCloner/webcloner.py b/0x23-WebCloner/webcloner.py new file mode 100644 index 0000000..9775ad7 --- /dev/null +++ b/0x23-WebCloner/webcloner.py @@ -0,0 +1,69 @@ +import os +import sys +import requests +from bs4 import BeautifulSoup +from urllib.parse import urljoin, urlparse + +class CloneWebsite: + def __init__(self, website_url): + self.website_url = website_url + self.domain_name = urlparse(website_url).netloc + self.visited_urls = set() + + def get_full_url(self, path): + return urljoin(self.website_url, path) + + def valid_url(self, url): + return urlparse(url).netloc == self.domain_name + + def save_content(self, url, path): + try: + response = requests.get(url, stream=True) + if response.status_code == 200: + os.makedirs(os.path.dirname(path), exist_ok=True) + with open(path, 'wb') as file: + for chunk in response.iter_content(chunk_size=8192): + file.write(chunk) + except Exception as e: + print(f"Error saving {url}: {e}") + + def crawl_website(self, url=None): + if url is None: + url = self.website_url + + if url in self.visited_urls: + return + self.visited_urls.add(url) + + try: + response = requests.get(url) + if response.status_code != 200: + return + except Exception as e: + print(f"Error accessing {url}: {e}") + return + + soup = BeautifulSoup(response.text, 'html.parser') + + # Save the current page + path = urlparse(url).path + if not path.endswith('.html'): + path = os.path.join(path, 'index.html') + self.save_content(url, os.path.join(self.domain_name, path.lstrip('/'))) + + # Extract and save all linked resources + for tag, attribute in [('img', 'src'), ('script', 'src'), ('link', 'href'), ('a', 'href')]: + for resource in soup.find_all(tag): + if attribute in resource.attrs: + resource_url = self.get_full_url(resource[attribute]) + if self.valid_url(resource_url): + file_path = os.path.join(self.domain_name, urlparse(resource_url).path.lstrip('/')) + if resource_url.endswith('.html'): + self.crawl_website(resource_url) + else: + self.save_content(resource_url, file_path) + +if __name__ == "__main__": + website_url = sys.argv[1] + clone = CloneWebsite(website_url) + clone.crawl_website() \ No newline at end of file diff --git a/0x24-Chess_Game/ChessEngine.py b/0x24-Chess_Game/ChessEngine.py new file mode 100644 index 0000000..3355cc8 --- /dev/null +++ b/0x24-Chess_Game/ChessEngine.py @@ -0,0 +1,222 @@ + +class GameState: + + def __init__(self): + self.board = [ + ["bR", "bN", "bB", "bQ", "bK", "bB", "bN", "bR"], + ["bp", "bp", "bp", "bp", "bp", "bp", "bp", "bp"], + ["--", "--", "--", "--", "--", "--", "--", "--"], + ["--", "--", "--", "--", "--", "--", "--", "--"], + ["--", "--", "--", "--", "--", "--", "--", "--"], + ["--", "--", "--", "--", "--", "--", "--", "--"], + ["wp", "wp", "wp", "wp", "wp", "wp", "wp", "wp"], + ["wR", "wN", "wB", "wQ", "wK", "wB", "wN", "wR"]] + self.moveFunctions = {'p': self.getPawnMoves, 'R': self.getRookMoves, 'N': self.getKnightMoves, + 'B': self.getBishopMoves, 'Q': self.getQueenMoves, 'K': self.getKingMoves} + self.whiteToMove = True, + self.moveLog = [] + self.whiteKingLocation = (7, 4) + self.blackKingLocation = (0, 4) + self.checkMate = False + self.staleMate = False + + def makeMove(self, move): + self.board[move.startRow][move.startCol] = "--" + self.board[move.endRow][move.endCol] = move.pieceMoved + self.moveLog.append(move) + self.whiteToMove = not self.whiteToMove + if move.pieceMoved == "wK": + self.whiteKingLocation = (move.endRow, move.endCol) + elif move.pieceMoved == "bK": + self.blackKingLocation = (move.endRow, move.endCol) + + if move.isPawnPromotion: + self.board[move.endRow][move.endCol] = move.pieceMoved[0] + "Q" + + + def undoMove(self): + if len(self.moveLog) != 0: + move = self.moveLog.pop() + self.board[move.startRow][move.startCol] = move.pieceMoved + self.board[move.endRow][move.endCol] = move.pieceCaptured + self.whiteToMove = not self.whiteToMove + if move.pieceMoved == "wK": + self.whiteKingLocation = (move.startRow, move.startCol) + if move.pieceMoved == "bK": + self.blackKingLocation = (move.startRow, move.startCol) + """ + All move considering checks + """ + def getValidMoves(self): + moves = self.getAllPossibleMoves() + for i in range(len(moves)-1, -1, -1): + self.makeMove(moves[i]) + self.whiteToMove = not self.whiteToMove + if self.inCheck(): + moves.remove(moves[i]) + self.whiteToMove = not self.whiteToMove + self.undoMove() + if len(moves) == 0: + if self.inCheck(): + self.checkMate = True + else: + self.staleMate = True + else: + self.checkMate = False + self.staleMate = False + + return moves + + def inCheck(self): + if self.whiteToMove: + return self.squareUnderAttack(self.whiteKingLocation[0], self.whiteKingLocation[1]) + else: + return self.squareUnderAttack(self.blackKingLocation[0], self.blackKingLocation[1]) + + def squareUnderAttack(self, r, c): + self.whiteToMove = not self.whiteToMove + oppMoves = self.getAllPossibleMoves() + self.whiteToMove = not self.whiteToMove + for move in oppMoves: + if move.endRow == r and move.endCol == c: + return True + return False + + + + + """ + All move without considering checks + """ + def getAllPossibleMoves(self): + moves = [] + for r in range(len(self.board)): + for c in range(len(self.board[r])): + turn = self.board[r][c][0] # b or w based on turn + if(turn == 'w' and self.whiteToMove) or (turn == 'b' and not self.whiteToMove): + piece = self.board[r][c][1] + self.moveFunctions[piece](r,c, moves) + return moves + + + def getPawnMoves(self, r, c, moves): + if self.whiteToMove: + if self.board[r-1][c] == "--": + moves.append(Move((r, c),(r-1, c), self.board)) + if r == 6 and self.board[r-2][c] == "--": + moves.append(Move((r, c),(r-2, c), self.board)) + if c-1 >= 0: + if self.board[r-1][c-1][0] == 'b': + moves.append(Move((r, c),(r-1, c-1), self.board)) + if c+1 <= 7: + if self.board[r-1][c+1][0] == 'b': + moves.append(Move((r, c),(r-1, c+1), self.board)) + + else: + if self.board[r+1][c] == "--": + moves.append(Move((r, c),(r+1, c), self.board)) + if r == 1 and self.board[r+2][c] == "--": + moves.append(Move((r, c),(r+2, c), self.board)) + if c-1 >= 0: + if self.board[r+1][c-1][0] == 'w': + moves.append(Move((r, c),(r+1, c-1), self.board)) + if c+1 <= 7: + if self.board[r+1][c+1][0] == 'w': + moves.append(Move((r, c),(r+1, c+1), self.board)) + + def getRookMoves(self, r, c, moves): + directions = ((-1, 0), (0, -1), (1, 0), (0, 1)) + enemyColor = "b" if self.whiteToMove else "w" + for d in directions: + for i in range(1, 8): + endRow = r + d[0] * i + endCol = c + d[1] * i + if 0 <= endRow < 8 and 0 <= endCol < 8: + endPiece = self.board[endRow][endCol] + if endPiece == "--": + moves.append(Move((r,c), (endRow, endCol), self.board)) + elif endPiece[0] == enemyColor: + moves.append(Move((r,c), (endRow, endCol), self.board)) + break + else: + break + else: + break + + def getKnightMoves(self, r,c,moves): + knightMoves = ((-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2), (2, -1), (2,1)) + allyColor = "w" if self.whiteToMove else "b" + for m in knightMoves: + endRow = r + m[0] + endCol = c + m[1] + if 0 <= endRow < 8 and 0 <= endCol < 8: + endPiece = self.board[endRow][endCol] + if endPiece[0] != allyColor: + moves.append(Move((r,c), (endRow, endCol), self.board)) + + def getBishopMoves(self, r,c,moves): + directions = ((-1, -1), (-1, 1), (1, -1), (1, 1)) + enemyColor = "b" if self.whiteToMove else "w" + for d in directions: + for i in range(1, 8): + endRow = r + d[0] * i + endCol = c + d[1] * i + if 0 <= endRow < 8 and 0 <= endCol < 8: + endPiece = self.board[endRow][endCol] + if endPiece == "--": + moves.append(Move((r,c), (endRow, endCol), self.board)) + elif endPiece[0] == enemyColor: + moves.append(Move((r,c), (endRow, endCol), self.board)) + break + else: + break + else: + break + + def getQueenMoves(self, r,c,moves): + self.getRookMoves(r, c, moves) + self.getBishopMoves(r, c, moves) + + def getKingMoves(self, r,c,moves): + kingMoves = ((-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1,1) ) + allyColor = "w" if self.whiteToMove else "b" + for i in range(8): + endRow = r + kingMoves[i][0] + endCol = c + kingMoves[i][1] + if 0 <= endRow < 8 and 0 <= endCol < 8: + endPiece = self.board[endRow][endCol] + if endPiece[0] != allyColor: + moves.append(Move((r,c), (endRow, endCol), self.board)) +class Move(): + + ranksToRow = {"1": 7, "2": 6, "3": 5, "4": 4, + "5": 3, "6": 2, "7": 1, "8": 0} + rowsToRanks = {v: k for k, v in ranksToRow.items()} + filesToCols = {"a": 0, "b": 1, "c": 2, "d": 3, + "e": 4, "f": 5, "g": 6, "h": 7} + colsToFiles = {v: k for k, v in filesToCols.items()} + + def __init__(self, startSq, endSq, board): + self.startRow = startSq[0] + self.startCol = startSq[1] + self.endRow = endSq[0] + self.endCol = endSq[1] + self.pieceMoved = board[self.startRow][self.startCol] + self.pieceCaptured = board[self.endRow][self.endCol] + self.isPawnPromotion = False + if (self.pieceMoved == 'wp' and self.endRow == 0) or (self.pieceMoved == 'bp' and self.endRow == 7): + self.isPawnPromotion = True + self.moveID = self.startRow * 1000 + self.startCol * 100 + self.endRow * 10 + self.endCol + + def __eq__(self, other): + if isinstance(other, Move): + return self.moveID == other.moveID + return False + + + def getChessNotation(self): + return self.getRankFile(self.startRow, self.startCol) + self.getRankFile(self.endRow, self.endCol) + + def getRankFile(self, r, c): + return self.colsToFiles[c] + self.rowsToRanks[r] + diff --git a/0x24-Chess_Game/ChessGame.py b/0x24-Chess_Game/ChessGame.py new file mode 100644 index 0000000..5a36191 --- /dev/null +++ b/0x24-Chess_Game/ChessGame.py @@ -0,0 +1,152 @@ +import pygame as p +import ChessEngine + +WIDTH = HEIGHT = 512 +DIMENSIONS = 8 +SQ_SIZE = HEIGHT// DIMENSIONS +MAX_FPS = 15 +IMAGES = {} + +def loadImages(): + pieces = ['wp', 'wR', 'wN', 'wB', 'wQ', 'wK', 'bp', 'bR', 'bN', 'bB', 'bQ', 'bK' ] + for piece in pieces: + IMAGES[piece] = p.transform.scale(p.image.load("images/" + piece + ".png"), (SQ_SIZE, SQ_SIZE)) + +def main(): + p.init() + screen = p.display.set_mode((WIDTH, HEIGHT)) + clock = p.time.Clock() + screen.fill(p.Color("white")) + gs = ChessEngine.GameState() + validMoves = gs.getValidMoves() + moveMade = False + animate = False + loadImages() + running = True + sqSelected = () + playerClicks = [] + gameOver = False + while running: + for e in p.event.get(): + if e.type == p.QUIT: + running = False + elif e.type == p.MOUSEBUTTONDOWN: + if not gameOver: + location = p.mouse.get_pos() + col = location[0]//SQ_SIZE + row = location[1]//SQ_SIZE + if sqSelected == (row, col): + sqSelected = () + playerClicks = [] + else: + sqSelected = (row, col) + playerClicks.append(sqSelected) + if len(playerClicks) == 1 and (gs.board[row][col] == "--"): + sqSelected = () + playerClicks = [] + if len(playerClicks) == 2: + move = ChessEngine.Move(playerClicks[0], playerClicks[1], gs.board) + for i in range(len(validMoves)): + if move == validMoves[i]: + gs.makeMove(move) + moveMade = True + animate = True + sqSelected = () + playerClicks = [] + if not moveMade: + playerClicks = [sqSelected] + elif e.type == p.KEYDOWN: + if e.key == p.K_z: + gs.undoMove() + moveMade = True + animate = False + if e.key == p.K_r: + gs = ChessEngine.GameState() + validMoves = gs.getValidMoves() + sqSelected = () + playerClicks = [] + moveMade = False + animate = False + if moveMade: + if animate: + animatedMoves(gs.moveLog[-1], screen, gs.board,clock) + validMoves = gs.getValidMoves() + moveMade = False + animate = False + drawGameState(screen, gs, validMoves, sqSelected) + if gs.checkMate: + gameOver = True + if gs.whiteToMove: + drawText(screen, 'Black wins by checkmate') + else: + drawText(screen, 'White wins by checkmate') + elif gs.staleMate: + gameOver =True + drawText(screen, 'Stalemate'); + clock.tick(MAX_FPS) + p.display.flip() + +def highlightSquares(screen, gs, validMoves, sqSelected): + if sqSelected != (): + r, c = sqSelected + if gs.board[r][c][0] == ('w' if gs.whiteToMove else 'b'): + s = p.Surface((SQ_SIZE, SQ_SIZE)) + s.set_alpha(100) + s.fill(p.Color('blue')) + screen.blit(s, (c*SQ_SIZE, r*SQ_SIZE)) + s.fill(p.Color("yellow")) + for moves in validMoves: + if moves.startRow == r and moves.startCol == c: + screen.blit(s, (SQ_SIZE*moves.endCol, SQ_SIZE*moves.endRow)) + +def drawGameState(screen, gs, validMoves, sqSelected): + drawBoard(screen) + highlightSquares(screen, gs, validMoves, sqSelected) + drawPieces(screen, gs.board) + +def drawBoard(screen): + global colors + colors = [p.Color("white"), p.Color("grey")] + for r in range(DIMENSIONS): + for c in range(DIMENSIONS): + color = colors[(r+c) % 2] + p.draw.rect(screen, color, p.Rect(c*SQ_SIZE, r*SQ_SIZE, SQ_SIZE, SQ_SIZE)) + +def drawPieces(screen, board): + for r in range(DIMENSIONS): + for c in range(DIMENSIONS): + piece = board[r][c] + if piece != "--": + screen.blit(IMAGES[piece], p.Rect(c*SQ_SIZE, r*SQ_SIZE, SQ_SIZE, SQ_SIZE)) + +def animatedMoves(move, screen,board, clock): + global colors + dR = move.endRow - move.startRow + dC = move.endCol - move.startCol + framesPerSquare = 5 + frameCount = (abs(dR) + abs(dC)) * framesPerSquare + for frame in range(frameCount + 1): + r,c =((move.startRow + dR*frame/frameCount, move.startCol + dC*frame/frameCount)) + drawBoard(screen) + drawPieces(screen, board) + color = colors[(move.endRow + move.endCol)%2] + endSquare = p.Rect(move.endCol*SQ_SIZE, move.endRow*SQ_SIZE, SQ_SIZE, SQ_SIZE) + p.draw.rect(screen, color, endSquare) + if move.pieceCaptured != "--": + screen.blit(IMAGES[move.pieceCaptured], endSquare) + + screen.blit(IMAGES[move.pieceMoved], p.Rect(c*SQ_SIZE, r*SQ_SIZE, SQ_SIZE, SQ_SIZE)) + p.display.flip() + clock.tick(60) + +def drawText(screen, text): + font = p.font.SysFont("Helvitca", 32, True, False) + textObject = font.render(text, True, p.Color('Gray')) + textLocation = p.Rect(0, 0, WIDTH, HEIGHT).move(WIDTH/2 - textObject.get_width()/2, HEIGHT/2 - textObject.get_height()/2) + screen.blit(textObject, textLocation) + textObject = font.render(text, True, p.Color("Black")) + screen.blit(textObject, textLocation.move(2,2)) + + +if __name__ == "__main__": + main() diff --git a/0x24-Chess_Game/README.md b/0x24-Chess_Game/README.md new file mode 100644 index 0000000..9a91ca0 --- /dev/null +++ b/0x24-Chess_Game/README.md @@ -0,0 +1,26 @@ +# Chess Game + +## 🛠️ Description +A simple chess game that you can play with your friend. + +## ⚙️ Languages or Frameworks Used +This game is created in python programming language. +Modules : pygame + +## 🌟 How to runHow to run the script +Running this game is pretty straight forward. + +```sh +pip install -r requirements.txt +``` + +```sh +python ChessGame.py +``` + +## 📺 Demo +

+![alt text] + +## *Author Name* +[Abhi Bhullar](https://github.com/userabhibhullar) \ No newline at end of file diff --git a/0x24-Chess_Game/images/bB.png b/0x24-Chess_Game/images/bB.png new file mode 100644 index 0000000..453cb32 Binary files /dev/null and b/0x24-Chess_Game/images/bB.png differ diff --git a/0x24-Chess_Game/images/bK.png b/0x24-Chess_Game/images/bK.png new file mode 100644 index 0000000..225f869 Binary files /dev/null and b/0x24-Chess_Game/images/bK.png differ diff --git a/0x24-Chess_Game/images/bN.png b/0x24-Chess_Game/images/bN.png new file mode 100644 index 0000000..8e3d04e Binary files /dev/null and b/0x24-Chess_Game/images/bN.png differ diff --git a/0x24-Chess_Game/images/bQ.png b/0x24-Chess_Game/images/bQ.png new file mode 100644 index 0000000..0d94a1c Binary files /dev/null and b/0x24-Chess_Game/images/bQ.png differ diff --git a/0x24-Chess_Game/images/bR.png b/0x24-Chess_Game/images/bR.png new file mode 100644 index 0000000..b9748e8 Binary files /dev/null and b/0x24-Chess_Game/images/bR.png differ diff --git a/0x24-Chess_Game/images/bp.png b/0x24-Chess_Game/images/bp.png new file mode 100644 index 0000000..c432d38 Binary files /dev/null and b/0x24-Chess_Game/images/bp.png differ diff --git a/0x24-Chess_Game/images/wB.png b/0x24-Chess_Game/images/wB.png new file mode 100644 index 0000000..26dae01 Binary files /dev/null and b/0x24-Chess_Game/images/wB.png differ diff --git a/0x24-Chess_Game/images/wK.png b/0x24-Chess_Game/images/wK.png new file mode 100644 index 0000000..d734164 Binary files /dev/null and b/0x24-Chess_Game/images/wK.png differ diff --git a/0x24-Chess_Game/images/wN.png b/0x24-Chess_Game/images/wN.png new file mode 100644 index 0000000..2d716b1 Binary files /dev/null and b/0x24-Chess_Game/images/wN.png differ diff --git a/0x24-Chess_Game/images/wQ.png b/0x24-Chess_Game/images/wQ.png new file mode 100644 index 0000000..a4fe68c Binary files /dev/null and b/0x24-Chess_Game/images/wQ.png differ diff --git a/0x24-Chess_Game/images/wR.png b/0x24-Chess_Game/images/wR.png new file mode 100644 index 0000000..a805de4 Binary files /dev/null and b/0x24-Chess_Game/images/wR.png differ diff --git a/0x24-Chess_Game/images/wp.png b/0x24-Chess_Game/images/wp.png new file mode 100644 index 0000000..e98fae2 Binary files /dev/null and b/0x24-Chess_Game/images/wp.png differ diff --git a/0x24-Chess_Game/requirements.txt b/0x24-Chess_Game/requirements.txt new file mode 100644 index 0000000..247ea34 --- /dev/null +++ b/0x24-Chess_Game/requirements.txt @@ -0,0 +1 @@ +pygame==2.4.0 diff --git a/0x25-QuizMaster/README.md b/0x25-QuizMaster/README.md new file mode 100644 index 0000000..d0969d7 --- /dev/null +++ b/0x25-QuizMaster/README.md @@ -0,0 +1,17 @@ +# Trivia Quiz Application + +This is a Python application that retrieves trivia questions from the Open Trivia Database API and presents them to the user in a quiz format. + +## Features + +- Fetch trivia questions from the Open Trivia Database API. +- Display questions and multiple-choice answers to the user. +- Allow the user to input their answers and keep track of the score. + +## Prerequisites + +- Python 3.x installed on your system. +- Install the `requests` library if not already installed: + ```bash + pip install requests + diff --git a/0x25-QuizMaster/answer_quiz.py b/0x25-QuizMaster/answer_quiz.py new file mode 100644 index 0000000..489c1ac --- /dev/null +++ b/0x25-QuizMaster/answer_quiz.py @@ -0,0 +1,109 @@ +import requests +import random +import html + +def get_questions(amount: int, category: int) -> dict: + """ + Retrieves trivia questions from the Open Trivia Database API. + + Args: + amount (int): Number of questions to retrieve (maximum 50). + category (int): Category ID of the questions. + + Returns: + dict: Dictionary containing the retrieved trivia questions. + """ + url = f'https://opentdb.com/api.php?amount={amount}&category={category}' + response = requests.get(url).json() + return response + +def shuffle_choices(choices: list) -> list: + """ + Shuffles the order of choices for a trivia question. + + Args: + choices (list): List of choices for a trivia question. + + Returns: + list: Shuffled list of choices. + """ + random.shuffle(choices) + return choices + +def get_user_response(num_choices: int) -> int: + while True: + try: + response = int(input('Enter your answer: ')) + if 1 <= response <= num_choices: + return response + else: + print('Invalid input. Please enter a number between 1 and', num_choices) + except ValueError: + print('Invalid input. Please enter a valid integer.') + +def display_choices(choices: list) -> None: + """ + Displays the choices for a trivia question with index numbers. + + Args: + choices (list): List of choices for a trivia question. + + Returns: + int: Index of the user's response. + """ + num_choices = len(choices) + for index, choice in enumerate(choices, start=1): + formatted_choice = f"{index}. {html.unescape(choice)}" + print(formatted_choice) + return get_user_response(num_choices) + +def get_user_input() -> int: + """ + Gets the number of questions the user wants to attempt. + + Returns: + int: Number of questions chosen by the user. + """ + while True: + try: + user_input = int(input('How many questions would you like to attempt (1-50): ')) + if 1 <= user_input <= 50: + return user_input + else: + print('Invalid input. Please enter a number between 1 and 50.') + except ValueError: + print('Invalid input. Please enter a valid integer.') + +def main(): + """ + Main function to run the trivia quiz application. + """ + score = 0 # Initialize score + try: + num_questions = get_user_input() + trivia_data = get_questions(num_questions, 18) # Category ID 9 corresponds to General Knowledge + questions = trivia_data.get('results') + + for question_data in questions: + question = html.unescape(question_data.get('question')) + correct_answer = html.unescape(question_data.get('correct_answer')) + incorrect_answers = [html.unescape(answer) for answer in question_data.get('incorrect_answers')] + incorrect_answers.append(correct_answer) + shuffled_choices = shuffle_choices(incorrect_answers) + + print(question) + user_response_index = display_choices(shuffled_choices) - 1 # Adjusting index to start from 0 + user_response = shuffled_choices[user_response_index] + if user_response == correct_answer: + score += 1 # Increment score for correct answer + print('Congratulations! Your answer is correct.\n') + else: + print(f'Sorry, the correct answer is: {correct_answer}\n') + + except requests.exceptions.RequestException as e: + print(f"Error: {e}. Please check your internet connection.") + finally: + print(f'Your final score is: {score}/{num_questions}') # Display final score + +if __name__ == "__main__": + main() diff --git a/Dice-Simulator/README.md b/Dice-Simulator/README.md new file mode 100644 index 0000000..ddb2baa --- /dev/null +++ b/Dice-Simulator/README.md @@ -0,0 +1,2 @@ +# Dice-Simulator + diff --git a/Dice-Simulator/img/five.png b/Dice-Simulator/img/five.png new file mode 100644 index 0000000..620c791 Binary files /dev/null and b/Dice-Simulator/img/five.png differ diff --git a/Dice-Simulator/img/four.png b/Dice-Simulator/img/four.png new file mode 100644 index 0000000..ee6cdee Binary files /dev/null and b/Dice-Simulator/img/four.png differ diff --git a/Dice-Simulator/img/one.png b/Dice-Simulator/img/one.png new file mode 100644 index 0000000..ab4d240 Binary files /dev/null and b/Dice-Simulator/img/one.png differ diff --git a/Dice-Simulator/img/six.png b/Dice-Simulator/img/six.png new file mode 100644 index 0000000..7951926 Binary files /dev/null and b/Dice-Simulator/img/six.png differ diff --git a/Dice-Simulator/img/three.png b/Dice-Simulator/img/three.png new file mode 100644 index 0000000..c174095 Binary files /dev/null and b/Dice-Simulator/img/three.png differ diff --git a/Dice-Simulator/img/two.png b/Dice-Simulator/img/two.png new file mode 100644 index 0000000..2e8fc64 Binary files /dev/null and b/Dice-Simulator/img/two.png differ diff --git a/Dice-Simulator/main.py b/Dice-Simulator/main.py new file mode 100644 index 0000000..d1ee205 --- /dev/null +++ b/Dice-Simulator/main.py @@ -0,0 +1,20 @@ +import customtkinter +from PIL import Image +import random + +img = ["one", "two", "three", "four", "five", "six"] +def button_callback(): + choice = random.choice(img) + my_image = customtkinter.CTkImage(light_image=Image.open("img\\"+choice+".png"),size=(100, 100)) + image_label = customtkinter.CTkLabel(app, image=my_image, text="") + image_label.grid(row=1, column=0, padx=20, pady=20) + +app = customtkinter.CTk() +app.title("Dice Roll") +app.geometry("350x200") +app.grid_columnconfigure(0, weight=1) + +button = customtkinter.CTkButton(app, text="Roll", command=button_callback) +button.grid(row=0, column=0, padx=20, pady=20) + +app.mainloop() \ No newline at end of file diff --git a/JSON-to-CSV/README.md b/JSON-to-CSV/README.md new file mode 100644 index 0000000..2cbab3f --- /dev/null +++ b/JSON-to-CSV/README.md @@ -0,0 +1,2 @@ +# JSON to CSV + JSON to CSV Converter diff --git a/JSON-to-CSV/json2csv.py b/JSON-to-CSV/json2csv.py new file mode 100644 index 0000000..92b2538 --- /dev/null +++ b/JSON-to-CSV/json2csv.py @@ -0,0 +1,52 @@ +import json +import csv +import os + +print("\nWelcome to the JSON to CSV converter") + +class Converter: + + def converter(self, json_file_path, csv_file_name): + global data + if json_file_path == 1: + try: + with open(json_file_path, 'r') as f1: + data = json.load(f1) + except: + print("File not found") + print("Try creating a new json file") + return + + if json_file_path == 2: + f = open("input.json",'x') + f.close() + file = "notepad input.json" + os.system(file) + f1 = open("input.json",'r') + data = json.load(f1) + + f2 = open(csv_file_name, 'w', newline="") + writer_object = csv.writer(f2) + writer_object.writerow(data[0].keys()) + + for row in data: + writer_object.writerow(row.values()) + f2.close() + + choice = input("Do you want open the converted file? (y/n): ") + while choice not in ['y','n']: + print("Invalid choice") + choice = input("Do you want open the converted file? (y/n): ") + if choice == 'y': + os.system(f'start "excel" {csv_file_name}') + +json2csv = Converter() + +json_file_path = int(input(""" +Press (1) to Open an existing json file +Press (2) to Create a new json file and Enter your data +Choose any one: """)) + +csv_file_name = input("Name your CSV file: ")+".csv" + +json2csv.converter(json_file_path, csv_file_name) \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ae0f4cb --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Victor Preston + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Memory Game Python/README.md b/Memory Game Python/README.md new file mode 100644 index 0000000..26dbf4a --- /dev/null +++ b/Memory Game Python/README.md @@ -0,0 +1,34 @@ +### + +# Memory Game Python Script Breakdown + +## 1. Importing Necessary Modules +- **random**: for generating random numbers. +- **tabulate**: for formatting the grid display. +- **os**: for clearing the console. + +## 2. Defining Global Variables +- **values**: a dictionary mapping letters to their corresponding indices in the grid. +- **temp_found**: a list to store the numbers temporarily found during each turn. +- **user_values**: a list to store the user's input for each turn. +- **user_choices**: a list to keep track of the tiles already uncovered by the user. +- **progress**: a boolean flag to indicate whether the game is still in progress. +- **competed**: a boolean flag to indicate whether the game has been completed. + +## 3. Taking User Input for the Grid Size +- The user is prompted to enter a choice for the grid size (e.g., 2 for a 2x2 grid, 4 for a 4x4 grid). +- The input is validated to ensure it is an even number. + +## 4. Defining Functions +- **game_elements(num)**: a function that generates the grid elements. It creates a list of random numbers and shuffles them to create pairs. +- **game_process(num)**: a function that handles the game logic. It displays the grid, prompts the user for input, and updates the grid based on the user's choices. It also checks for matches and updates the game status accordingly. + +## 5. The Main Game Loop +- The main list is populated with the grid elements using the `game_elements` function. +- The `game_process` function is called to start the game. +- After each game, the user is prompted to choose whether to play again. +- If the user chooses to quit, the loop breaks. + +**Overall, the selected code provides a complete implementation of the memory game with user interaction and grid display.** + +### diff --git a/Memory Game Python/main.py b/Memory Game Python/main.py new file mode 100644 index 0000000..2939a70 --- /dev/null +++ b/Memory Game Python/main.py @@ -0,0 +1,151 @@ +import random +import os + +values = {'a' : 0, 'b' : 1, 'c' : 2, 'd' : 3, 'e' : 4, 'f' : 5, 'g' : 6, 'h' : 7} +table_heading = {65:"A", 66:"B", 67:"C", 68:"D", 69:"E", 70:"F", 71:"G", 72:"H"} +temp_found = [] +user_values = [] +user_choices = [] +progress = True +competed = False + +def game_elements(num): + + lst = [] + while len(lst) < num: + row = [] + while len(row) < num: + random_number = random.randint(65,73) + if random_number not in row: + row.append(chr(random_number)) + lst.append(row) + element = row.copy() + random.shuffle(element) + lst.append(element) + return lst + +def game_process(num): + global user_values + global temp_found + global competed + + def game_table(list_with_spaces): + char_count = 65 + if user_choice_data == 2: + print(" 0 1 ") + print(" |---------|---------|") + for i in range(2): + print(f"{table_heading[char_count]} | {list_with_spaces[i][0]} | {list_with_spaces[i][1]} |") + print(" |---------|---------|") + char_count += 1 + + if user_choice_data == 4: + print(" 0 1 2 3 ") + print(" |---------|---------|---------|---------|") + for i in range(4): + print(f"{table_heading[char_count]} | {list_with_spaces[i][0]} | {list_with_spaces[i][1]} | {list_with_spaces[i][2]} | {list_with_spaces[i][3]} |") + print(" |---------|---------|---------|---------|") + char_count += 1 + + if user_choice_data == 6: + print(" 0 1 2 3 4 5 ") + print(" |-------|-------|-------|-------|-------|-------|") + for i in range(6): + print(f"{table_heading[char_count]} | {list_with_spaces[i][0]} | {list_with_spaces[i][1]} | {list_with_spaces[i][2]} | {list_with_spaces[i][3]} | {list_with_spaces[i][4]} | {list_with_spaces[i][5]} |") + print(" |-------|-------|-------|-------|-------|-------|") + char_count += 1 + + if user_choice_data == 8: + print(" 0 1 2 3 4 5 6 7 ") + print(" |-------|-------|-------|-------|-------|-------|-------|-------|") + for i in range(8): + print(f"{table_heading[char_count]} | {list_with_spaces[i][0]} | {list_with_spaces[i][1]} | {list_with_spaces[i][2]} | {list_with_spaces[i][3]} | {list_with_spaces[i][4]} | {list_with_spaces[i][5]} | {list_with_spaces[i][6]} | {list_with_spaces[i][7]} |") + print(" |-------|-------|-------|-------|-------|-------|-------|-------|") + char_count += 1 + + list_with_spaces = [[' ' for _ in sublist] for sublist in main] + while progress: + os.system('cls') + game_table(list_with_spaces) + + trial = 0 + for i in range(2): + if len(user_choices) == (num**2): + competed = True + break + + opn = input("\nEnter the tile to uncover: ") + while opn in user_choices: + print("\n===========>>>You have already completed this tile!") + opn = input("\nEnter the new tile to uncover: ") + user_values.append(opn) + + index_1 = values[opn[0]] + index_2 = int(opn[1]) + + temp_found.append(main[index_1][index_2]) + + list_with_spaces[index_1][index_2] = main[index_1][index_2] + game_table(list_with_spaces) + + trial += 1 + if trial == 2: + user_input = input("\n===========>>> Press (Enter) to Continue: ") + trial = 0 + + if competed: + print("\n===========>>> You Won! <<<===========") + break + elif temp_found[0] == temp_found[1]: + for i in range(2): + user_choices.append(user_values[i]) + index_1 = values[user_values[i][0]] + index_2 = int(user_values[i][1]) + list_with_spaces[index_1][index_2] = "✔️" + user_values = [] + temp_found = [] + else: + for i in range(2): + index_1 = values[user_values[i][0]] + index_2 = int(user_values[i][1]) + list_with_spaces[index_1][index_2] = " " + user_values = [] + temp_found = [] +while True: + user_choice_data = input(""" +For '2x2' enter "EASY" +For '4x4' enter "MEDIUM" +For '6x6' enter "HARD" +For '8x8' enter "EXTREME" + +Enter your choice: """).lower() + + while user_choice_data not in ["easy", "medium", "hard", "extreme"]: + os.system("cls") + user_choice_data = input(""" +For '2x2' enter "EASY" +For '4x4' enter "MEDIUM" +For '6x6' enter "HARD" +For '8x8' enter "EXTREME" + +Enter your choice: """).lower() + + if user_choice_data == "easy": + user_choice_data = 2 + if user_choice_data == "medium": + user_choice_data = 4 + if user_choice_data == "hard": + user_choice_data = 6 + if user_choice_data == "extreme": + user_choice_data = 8 + main = game_elements(user_choice_data) + process = game_process(user_choice_data) + + choice = input("Do you want to play the game again? (y/n): ").lower() + + while choice not in ["y", "n"]: + print("\n Invalid choice") + choice = input("Do you want to play the game again? (y/n): ") + + if choice == "n": + break \ No newline at end of file diff --git a/OOP Example/main.py b/OOP Example/main.py new file mode 100644 index 0000000..ad30b5b --- /dev/null +++ b/OOP Example/main.py @@ -0,0 +1,20 @@ +# Class Creation +class Person: + # Initialization function (when you create an object this named initialization) + def __init__(self,name,age): + # changing objects attributes to arguments that we enter when calling an class to create an object + self.name = name + self.age = age + + # String function that returns a string that will be returned if you will print class + # Without __str__(): <__main__.Person object at 0x000001AC025E7230> + # With __str__(): + def __str__(self): + return f'Name: {self.name}. Age: {self.age}' + +# Creating an object using class +p = Person("John",21) # you can change the values and create some other methods in class +print(p) + +# Output: +# Name: John. Age: 21 diff --git a/PDF summrazation/main.py b/PDF summrazation/main.py new file mode 100644 index 0000000..5f7d744 --- /dev/null +++ b/PDF summrazation/main.py @@ -0,0 +1,118 @@ +import tkinter as tk +from tkinter import filedialog, scrolledtext, messagebox, simpledialog, font +from tkinter import PhotoImage # Import PhotoImage for handling images +import torch +from transformers import T5Tokenizer, T5ForConditionalGeneration +from pdfminer.high_level import extract_text +import requests +from io import BytesIO +from fpdf import FPDF # Import FPDF for PDF generation + +model = T5ForConditionalGeneration.from_pretrained('t5-small') +tokenizer = T5Tokenizer.from_pretrained('t5-small') +device = torch.device('cpu') + +def pdf_to_text(pdf_path): + try: + text = extract_text(pdf_path) + return text + except Exception as e: + print(f"Error extracting text from PDF: {e}") + return None + +def summarize_text(text): + preprocess_text = text.strip().replace("\n", " ") + t5_prepared_text = "summarize: " + preprocess_text + tokenized_text = tokenizer.encode(t5_prepared_text, return_tensors="pt").to(device) + summary_ids = model.generate(tokenized_text, + num_beams=4, + no_repeat_ngram_size=2, + min_length=30, + max_length=100, + early_stopping=True) + output = tokenizer.decode(summary_ids[0], skip_special_tokens=True) + return output + +def download_pdf(url): + try: + response = requests.get(url) + response.raise_for_status() + return BytesIO(response.content) + except requests.RequestException as e: + messagebox.showerror("Download Error", f"Failed to download PDF: {e}") + return None + +def select_files(): + file_paths = filedialog.askopenfilenames(filetypes=[("PDF files", "*.pdf")]) + if file_paths: + summaries = [summarize_text(pdf_to_text(pdf_file)) for pdf_file in file_paths if + pdf_to_text(pdf_file) is not None] + output_text.delete('1.0', tk.END) + output_text.insert(tk.END, "\n\n".join(summaries)) + messagebox.showinfo("Completion", "Summarization completed!") + else: + messagebox.showinfo("No Files", "No PDF files were selected.") + +def fetch_from_url(): + url = simpledialog.askstring("Enter URL", "Please enter the PDF URL:") + if url: + pdf_file = download_pdf(url) + if pdf_file: + summary = summarize_text(pdf_to_text(pdf_file)) + output_text.delete('1.0', tk.END) + output_text.insert(tk.END, summary) + messagebox.showinfo("Completion", "Summarization completed!") + +def save_summary_as_pdf(): + text_to_save = output_text.get('1.0', tk.END) + if not text_to_save.strip(): + messagebox.showerror("No Data", "There is no summary to save.") + return + + file_path = filedialog.asksaveasfilename(defaultextension=".pdf", filetypes=[("PDF files", "*.pdf")]) + if file_path: + pdf = FPDF() + pdf.add_page() + + # Calculate center position for logo and title + logo_x = (pdf.w - 30) / 2 # Centering logo horizontally + pdf.image("p.png", x=logo_x, y=10, w=30) + pdf.ln(28) + # Add header title centered + pdf.set_font("Arial", size=12) + pdf.cell(0, 10, "MGM's College Of Engineering", ln=True, align='C') + + # Add line separator + pdf.set_line_width(0.5) + pdf.line(10, 50, pdf.w - 10, 50) + + # Add summary text + pdf.set_font("Arial", size=10) + pdf.multi_cell(0, 10, text_to_save) + + pdf.output(file_path) + + messagebox.showinfo("Saved as PDF", "The summary has been saved as PDF!") + +app = tk.Tk() +app.title("PDF Summarizer") +app.geometry("800x600") +app.config(bg="light blue") +customFont = font.Font(family="Helvetica", size=12) + +btn_load = tk.Button(app, text="Load PDFs", command=select_files, font=customFont, bg="navy", fg="white", padx=10, + pady=5) +btn_load.pack(pady=10) + +btn_fetch = tk.Button(app, text="Fetch PDF from URL", command=fetch_from_url, font=customFont, bg="navy", fg="white", + padx=10, pady=5) +btn_fetch.pack(pady=10) + +btn_save_pdf = tk.Button(app, text="Save Summary as PDF", command=save_summary_as_pdf, font=customFont, bg="navy", + fg="white", padx=10, pady=5) +btn_save_pdf.pack(pady=10) + +output_text = scrolledtext.ScrolledText(app, width=70, height=20, font=customFont, padx=10, pady=10, wrap=tk.WORD) +output_text.pack(pady=20) + +app.mainloop() diff --git a/PDF summrazation/p.png b/PDF summrazation/p.png new file mode 100644 index 0000000..6c493e0 Binary files /dev/null and b/PDF summrazation/p.png differ diff --git a/Quiz-Creator/quiz.py b/Quiz-Creator/quiz.py new file mode 100644 index 0000000..2a4f770 --- /dev/null +++ b/Quiz-Creator/quiz.py @@ -0,0 +1,19 @@ +import os +class QuizCreation: + def process(self, question, choices, answer, question_number=""): + choices_dict = {'a':1, 'b':2, 'c':3, 'd':4} + with open("sample.txt", "a") as f: + f.write(f"\nQUESTION {question_number}:- "+question) + f.write("\n") + count = 65 + for i in range(len(choices)): + f.write(f"({chr(count)}) "+choices[i]) + f.write("\n") + count += 1 + f.write(f"Answer :- ({answer.upper()}) "+choices[choices_dict[answer]-1]) + f.write("\n") + + def open_file(self): + os.startfile("sample.txt") + +Quiz = QuizCreation() \ No newline at end of file diff --git a/Quiz-Creator/sample.py b/Quiz-Creator/sample.py new file mode 100644 index 0000000..19a8a3b --- /dev/null +++ b/Quiz-Creator/sample.py @@ -0,0 +1,7 @@ +from quiz import Quiz + +Quiz.process(question="Entomology is the science that studies", + choices=["Behavior of human beings", "Insects", "The origin and history of technical and scientific terms", "The formation of rocks"], + answer="b") + +Quiz.open_file() \ No newline at end of file diff --git a/Quiz-Creator/sample.txt b/Quiz-Creator/sample.txt new file mode 100644 index 0000000..d57ef88 --- /dev/null +++ b/Quiz-Creator/sample.txt @@ -0,0 +1,7 @@ + +QUESTION :- Entomology is the science that studies +(A) Behavior of human beings +(B) Insects +(C) The origin and history of technical and scientific terms +(D) The formation of rocks +Answer :- (B) Insects diff --git a/README.md b/README.md index cbd7a24..0d7712d 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,61 @@ -# Python-CodeNest -![1](https://github.com/victorpreston/Python-CodeNest/assets/112781610/dec8d192-a010-48c6-902b-3c4bd991150d) +# PyProjects ## Description - Unlock your coding potential with my personally crafted Python projects. Level up your skills now by diving in and exploring the fruits of my python coding journey + >Unlock your coding potential with crafted Python projects. Level up your skills now by diving in and exploring the python coding journey - Here in this repository, you will find a set of python projects from simple to complex - most of time working in the console and sometime with GUI. + >Here in this repository, you will find a set of python projects from simple to complex + >most of time working in the console and sometime with GUI. ## Projects list -* [1.Dice simulator](https://github.com/victorpreston/Python-CodeNest/tree/master/0x01-Dice) -* [2.Dictionary](https://github.com/victorpreston/Python-CodeNest/tree/master/0x02-Dictionary) -* [3.Hanging man](https://github.com/victorpreston/Python-CodeNest/tree/master/0x03-HangingMan) -* [4.TicTacToe](https://github.com/victorpreston/Python-CodeNest/tree/master/0x04-TicTacToe) -* [5.Conditionals](https://github.com/victorpreston/Python-CodeNest/tree/master/0x05-Conditional) -* [6.Decrements](https://github.com/victorpreston/Python-CodeNest/tree/master/0x06-Decrement) -* [7.Face detection](https://github.com/victorpreston/Python-CodeNest/tree/master/0x07-Face_detection) -* [8.Password generator](https://github.com/victorpreston/Python-CodeNest/tree/master/0x08-Passcode-generator) -* [9.Shutdown](https://github.com/victorpreston/Python-CodeNest/tree/master/0x09-Shutdown) -* [10.Simple browser](https://github.com/victorpreston/Python-CodeNest/tree/master/0x10-Simple-browser) -* [11.Text to speech](https://github.com/victorpreston/Python-CodeNest/tree/master/0x11-Text-to-Speech) -* [12.Weather-finder](https://github.com/victorpreston/Python-CodeNest/tree/master/0x12-Weather-finder) -* [13.Web server](https://github.com/victorpreston/Python-CodeNest/tree/master/0x13-Web_server) -* [14.Shuffle](https://github.com/victorpreston/Python-CodeNest/tree/master/0x14-Shuffle) -* [15.Audio-Book](https://github.com/victorpreston/Python-CodeNest/tree/master/0x15-Audio-Book) -* [16.QR-Generator](https://github.com/victorpreston/Python-CodeNest/tree/master/0x16-QR-Generator) -* [17.Sudoku](https://github.com/victorpreston/Python-CodeNest/tree/master/0x17-Sudoku) -* [18.Url-Web Scrapper](https://github.com/victorpreston/Python-CodeNest/tree/master/0x18-Url-Web-Scraper) -* [19.PhoneTracker](https://github.com/victorpreston/Python-CodeNest/tree/master/0x19-Phone-Tracker) +| Number | Directory | +|--------|------| +| 1 | [Dice simulator](./0x01-Dice) | +| 2 | [Dictionary](./0x02-Dictionary) | +| 3 | [Hanging man](./0x03-HangingMan) | +| 4 | [TicTacToe](./0x04-TicTacToe) | +| 5 | [Conditionals](./0x05-Conditional) | +| 6 | [Decrements](./0x06-Decrement) | +| 7 | [Face detection](./0x07-Face_detection) | +| 8 | [Password generator](./0x08-Passcode-generator) | +| 9 | [Shutdown](./0x09-Shutdown) | +| 10 | [Simple browser](./0x10-Simple-browser) | +| 11 | [Text to speech](./0x11-Text-to-Speech) | +| 12 | [Weather finder](./0x12-Weather-finder) | +| 13 | [Web server](./0x13-Web_server) | +| 14 | [Shuffle](./0x14-Shuffle) | +| 15 | [Audio Book](./0x15-Audio-Book) | +| 16 | [QR Generator](./0x16-QR-Generator) | +| 17 | [Sudoku](./0x17-Sudoku) | +| 18 | [URL Web Scrapper](./0x18-Url-Web-Scraper) | +| 19 | [Phone Tracker](./0x19-Phone-Tracker) | +| 20 | [Automated Mailing](./0x20-AutomatedMailing) | +| 21 | [Text Editor](./0x21TextEditor) | +| 22 | [YouTube Viewer](./0x22-YouTubeViewer) | +| 21 | [Web Cloner](./0x23-WebCloner) | +| 24 | [Chess Game](./0x24-Chess_Game) | +| 25 | [Quiz Master](./0x25-QuizMaster) | +| 26 | [Dice-Simulator](./Dice-Simulator) | +| 27 | [JSON-to-CSV](./JSON-to-CSV) | +| 28 | [Memory Game Python](./Memory-Game-Python) | +| 29 | [Quiz-Creator](./Quiz-Creator) | +| 28 | [Memory-Game-Python](./Memory%20Game%20Python) | + + + ## User Guide - Do you want to try these projects? Just clone the current repository and type the following commands in individual folder: - - -open in terminal - - python3 - - And it's all done ! + > Do you want to try these projects? Just clone the current repository and type the following commands in individual folder: +```groovy + open in terminal + python3 + And it's all done ! +``` ## Contributors Guide - If you want to help me improve the repository, you can fork the project and add your own features or updates then pull request and add me as reviewer - When you find out error, don't hesitate to correct it . + > If you want to help me improve the repository, you can fork the project and add your own features or updates then pull request and add me as reviewer + > When you find out error, don't hesitate to correct it . ```mermaid flowchart LR Star[Star the Repository]-->Fork @@ -50,6 +66,25 @@ flowchart LR ``` + +## Contributors + + + + + + + + + + + + + + + + +
Victor Preston
Victor Preston

💻
dayoonasanya
Adedayo Onasanya

💻
Atughara John
Atughara John

💻
levoski1
Ugwoke Levi

💻
Manavalan
Manavalan

💻
P0Saurabh
P0Saurabh

💻
wCupped
wCupped
💻
-### Enjoy python! +### Enjoy python!