├── Automate The Boring Stuff with Python ├── .gitignore ├── Programs │ ├── Browser │ │ ├── controlBrowser.py │ │ ├── downloadWeb.py │ │ ├── mapIt.bat │ │ ├── mapIt.py │ │ └── parseHTML.py │ ├── Email │ │ ├── checkInbox.py │ │ └── sendEmail.py │ ├── File Operations │ │ ├── combinedminutes.pdf │ │ ├── demo.docx │ │ ├── demo2.docx │ │ ├── demo4.docx │ │ ├── meetingminutes1.pdf │ │ ├── meetingminutes2.pdf │ │ ├── readAndWritePDF.py │ │ ├── readAndWriteWordFiles.py │ │ ├── readExcel.py │ │ ├── readExcel.xlsx │ │ └── writeExcel.xlsx │ ├── GUIAutomation │ │ ├── Calc7Pic.png │ │ ├── controlKeyboard.py │ │ ├── controlMouse.py │ │ ├── screenshot.png │ │ └── screenshotsAndImageRecognition.py │ ├── Regex │ │ └── phoneAndEmail.py │ └── requirements.txt ├── README.md └── Resources │ ├── Automate the Boring Stuff with Python Book.pdf │ ├── lesson1-recap.txt │ ├── lesson10-recap.txt │ ├── lesson11-recap.txt │ ├── lesson13-recap.txt │ ├── lesson14-recap.txt │ ├── lesson15-recap.txt │ ├── lesson16-recap.txt │ ├── lesson17-recap.txt │ ├── lesson19-recap.txt │ ├── lesson2-recap.txt │ ├── lesson20-recap.txt │ ├── lesson22-recap.txt │ ├── lesson23-recap.txt │ ├── lesson24-recap.txt │ ├── lesson25-recap.txt │ ├── lesson26-recap.txt │ ├── lesson27-recap.txt │ ├── lesson28-recap.txt │ ├── lesson30-recap.txt │ ├── lesson31-recap.txt │ ├── lesson33-recap.txt │ ├── lesson35-recap.txt │ ├── lesson36-recap.txt │ ├── lesson37-recap.txt │ ├── lesson39-recap.txt │ ├── lesson4-recap.txt │ ├── lesson40-recap.txt │ ├── lesson41-recap.txt │ ├── lesson42-recap.txt │ ├── lesson43-recap.txt │ ├── lesson44-recap.txt │ ├── lesson45-recap.txt │ ├── lesson48-recap.txt │ ├── lesson49-recap.txt │ ├── lesson5-recap.txt │ ├── lesson50-recap.txt │ ├── lesson6-recap.txt │ ├── lesson7-recap.txt │ ├── lesson8-recap.txt │ └── lesson9-recap.txt ├── Coronavirus Voice Assistant ├── .gitignore ├── Part1.py ├── README.md └── main.py ├── Cowin Vaccine Notifier ├── README.md ├── notification_sound.mp3 └── script.py ├── Data Engineering Introduction ├── .gitignore ├── README.md ├── data.csv ├── index.html ├── requirements.txt └── script.py ├── Machine Learning Algorithms ├── .gitignore ├── README.md ├── final_image.png ├── requirements.txt └── script.py ├── Path-Finding-Visualizer ├── README.md ├── astar.py └── img.jpg ├── Pong ├── Pong.py ├── README.md └── bounce.wav ├── Random Movie Generator ├── .gitignore ├── README.md ├── requirements.txt └── script.py ├── Sorting Visualizer ├── .gitignore ├── algorithms.py └── visualizer.py ├── Steganography ├── Front_end │ ├── __pycache__ │ │ ├── gui.cpython-36.pyc │ │ └── gui.cpython-37.pyc │ └── gui.py ├── LSB │ ├── Audio_in_audio │ │ ├── __pycache__ │ │ │ └── aialcode.cpython-37.pyc │ │ └── aialcode.py │ ├── Image_in_audio │ │ ├── __pycache__ │ │ │ └── iialcode.cpython-37.pyc │ │ └── iialcode.py │ └── Text_in_audio │ │ ├── __pycache__ │ │ ├── tiacode.cpython-37.pyc │ │ └── tialcode.cpython-37.pyc │ │ └── tialcode.py ├── __pycache__ │ ├── imagepil.cpython-36.pyc │ └── main.cpython-36.pyc ├── config.dat ├── main.py └── res │ ├── carrierAudio.wav │ ├── secretAudio.wav │ └── secretImage.jpg ├── Sudoku Solver ├── .gitignore ├── GUI.py ├── Intro.txt └── solver.py ├── Supervised Learning ├── .gitignore ├── README.md ├── requirements.txt └── script.py └── Translator ├── .gitignore ├── README.md ├── requirements.txt └── script.py /Automate The Boring Stuff with Python/.gitignore: -------------------------------------------------------------------------------- 1 | /Programs/venv 2 | geckodriver.log -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/Browser/controlBrowser.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | 3 | browser = webdriver.Firefox() 4 | browser.get('https://automatetheboringstuff.com') 5 | ele = browser.find_element_by_css_selector( 6 | '.main > div:nth-child(1) > ul:nth-child(20) > li:nth-child(1) > a:nth-child(1)') 7 | 8 | # Click a selected CSS element 9 | ele.click() 10 | 11 | # Go forward 12 | browser.forward() 13 | 14 | # refresh browser 15 | browser.refresh() 16 | 17 | # Quit browser 18 | browser.quit() 19 | -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/Browser/downloadWeb.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | res = requests.get('https://automatetheboringstuff.com/files/rj.txt') 4 | print(res.status_code) # Get the status of the request 5 | badRes = requests.get('https://automatetheboringstuff.com/files/afwevwav.txt') 6 | print(badRes.raise_for_status()) # Get any status errors if present 7 | -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/Browser/mapIt.bat: -------------------------------------------------------------------------------- 1 | @py.exe "E:\Data\Projects\Python Projects\Automate The Boring Stuff with Python\Programs\mapIt.py" %* 2 | @pause -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/Browser/mapIt.py: -------------------------------------------------------------------------------- 1 | import pyperclip 2 | import sys 3 | import webbrowser 4 | 5 | # Either provide the address to find in the command line while running, else copy the address to the clipboard and run the program. 6 | 7 | sys.argv # ['mapIt.py', '870', 'Valencia', 'St.'] 8 | 9 | if len(sys.argv) > 1: 10 | # ['mapIt.py', '870', 'Valencia', 'St.'] => '870 Valencia St.' 11 | address = ' '.join(sys.argv[1:]) 12 | else: 13 | address = pyperclip.paste() 14 | 15 | # https://www.google.co.in/maps/place/
16 | webbrowser.open('https://www.google.co.in/maps/place/'+address) 17 | -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/Browser/parseHTML.py: -------------------------------------------------------------------------------- 1 | import bs4 2 | import requests 3 | 4 | # Check price of a product on Snapdeal 5 | 6 | 7 | def getPrice(productURL): 8 | res = requests.get(productURL) 9 | res.raise_for_status() 10 | soup = bs4.BeautifulSoup(res.text, 'html.parser') 11 | elems = soup.select('html body div#content_wrapper section#overviewBlk.pdp-section.clearfix div#productOverview.product-detail.clearfix.col-xs-24.reset-padding.favDp div.col-xs-14.right-card-zoom.reset-padding div.pdp-comp.comp-product-description.clearfix div.pdp-fash-topcenter-inner.layout div.container-fluid.reset-padding div#buyPriceBox.fashionPriceTile.row div.row.reset-margin div.col-xs-14.reset-padding.padL8 div.disp-table div.pdp-e-i-PAY-r.disp-table-cell.lfloat span.pdp-final-price') 12 | return elems[0].text.strip() 13 | 14 | 15 | price = getPrice( 16 | 'https://www.snapdeal.com/product/veirdo-100-percent-cotton-multi/633668842498#bcrumbLabelId:17') 17 | print(price) 18 | price2 = getPrice( 19 | 'https://www.snapdeal.com/product/surt-cotton-blend-blue-shirt/633090512655') 20 | print(price2) 21 | -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/Email/checkInbox.py: -------------------------------------------------------------------------------- 1 | # IMAP protocol 2 | 3 | import pyzmail 4 | import imapclient 5 | 6 | conn = imapclient.IMAPClient('imap.gmail.com', ssl=True) 7 | conn.login('name@mail.com', 'password') 8 | conn.select_folder('INBOX', readonly=True) 9 | UIDs = conn.search(['SINCE 20-AUG-2020']) 10 | print(UIDs) 11 | rawMessage = conn.fetch([47474], ['BODY[]', 'FLAGS']) 12 | message = pyzmail.PyzMessage.factory(rawMessage[47474][b'BODY[]']) 13 | message.get_subject() 14 | message.get_addresses('from') 15 | message.get_addresses('to') 16 | message.get_addresses('bcc') 17 | message.text_part 18 | message.html_part == None 19 | message.text_part.get_payload().decode('UTF-8') 20 | conn.list_folders() 21 | -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/Email/sendEmail.py: -------------------------------------------------------------------------------- 1 | # SMTP protocol 2 | 3 | import smtplib 4 | 5 | conn = smtplib.SMTP('smtp.gmail.com', 587) 6 | print(conn.ehlo()) 7 | conn.starttls() 8 | print(conn.login('sender@mail.com', 'senderPassword')) 9 | conn.sendmail('sender@mail.com', 'receiver@mail.com', 10 | 'Subject: Learning Python Automation\n\nDear Prajwal, \n\nLove yourself, Stay Strong and Keep Going! Your doing great!\n\n-Praju') 11 | conn.quit() 12 | 13 | # In gmail enable 'allow from unknown sources' option while performing this program 14 | -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/File Operations/combinedminutes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Automate The Boring Stuff with Python/Programs/File Operations/combinedminutes.pdf -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/File Operations/demo.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Automate The Boring Stuff with Python/Programs/File Operations/demo.docx -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/File Operations/demo2.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Automate The Boring Stuff with Python/Programs/File Operations/demo2.docx -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/File Operations/demo4.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Automate The Boring Stuff with Python/Programs/File Operations/demo4.docx -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/File Operations/meetingminutes1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Automate The Boring Stuff with Python/Programs/File Operations/meetingminutes1.pdf -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/File Operations/meetingminutes2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Automate The Boring Stuff with Python/Programs/File Operations/meetingminutes2.pdf -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/File Operations/readAndWritePDF.py: -------------------------------------------------------------------------------- 1 | # Using PDF from : http://autbor.com/meetingminutes1.pdf 2 | import PyPDF2 3 | 4 | pdfFile = open('meetingminutes1.pdf', 'rb') 5 | reader = PyPDF2.PdfFileReader(pdfFile) 6 | print(reader.numPages) 7 | page = reader.getPage(0) # Text on first page 8 | print(page.extractText()) 9 | 10 | 11 | pdf1File = open('meetingminutes1.pdf', 'rb') 12 | pdf2File = open('meetingminutes2.pdf', 'rb') 13 | reader1 = PyPDF2.PdfFileReader(pdf1File) 14 | reader2 = PyPDF2.PdfFileReader(pdf2File) 15 | writer = PyPDF2.PdfFileWriter() 16 | for pageNum in range(reader1.numPages): 17 | page = reader1.getPage(pageNum) 18 | writer.addPage(page) 19 | 20 | for pageNum in range(reader2.numPages): 21 | page = reader2.getPage(pageNum) 22 | writer.addPage(page) 23 | 24 | outputFile = open('combinedminutes.pdf', 'wb') 25 | writer.write(outputFile) 26 | pdf1File.close() 27 | pdf2File.close() 28 | -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/File Operations/readAndWriteWordFiles.py: -------------------------------------------------------------------------------- 1 | import docx 2 | 3 | d = docx.Document('demo.docx') 4 | print(d.paragraphs) 5 | print() 6 | print(d.paragraphs[0].text) 7 | print() 8 | p = d.paragraphs[1] 9 | print(p.runs) 10 | print(p.runs[0].text) 11 | print(p.runs[1].text) 12 | print(p.runs[2].text) 13 | p.runs[3].underline = True 14 | p.runs[3].text = "this is underlined and italic" 15 | d.save("demo2.docx") 16 | 17 | d = docx.Document() 18 | d.add_paragraph("Hello world, I am Prajwal!") 19 | d.save("demo4.docx") 20 | p = d.paragraphs[0] 21 | p.add_run('New run.') 22 | p.runs[1].bold = True 23 | d.save("demo4.docx") 24 | -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/File Operations/readExcel.py: -------------------------------------------------------------------------------- 1 | import openpyxl 2 | import os 3 | 4 | # os.chdir('C:\\Users\\praju\\') 5 | 6 | workbook = openpyxl.load_workbook('readExcel.xlsx') 7 | # print(type(workbook)) 8 | sheet = workbook.get_sheet_by_name('Sheet1') 9 | # print(type(sheet)) 10 | # print(workbook.get_sheet_names()) 11 | # print(sheet['A1']) 12 | cell1 = sheet['A1'] 13 | cell2 = sheet['B4'] 14 | print(cell1.value) 15 | print(cell2.value) 16 | print(sheet.cell(row=1, column=2).value) 17 | 18 | 19 | wb = openpyxl.Workbook() 20 | wb.get_sheet_names() 21 | sheet = wb.get_sheet_by_name('Sheet') 22 | sheet['A1'].value = 42 23 | os.chdir('E:\\DATA\\Projects\\Python Projects\\Automate The Boring Stuff with Python\\Programs') 24 | wb.save('writeExcel.xlsx') 25 | newSheet = wb.create_sheet() 26 | newSheet.title = 'Fresh Sheet' 27 | wb.create_sheet(index=0, title="Other new sheet") 28 | -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/File Operations/readExcel.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Automate The Boring Stuff with Python/Programs/File Operations/readExcel.xlsx -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/File Operations/writeExcel.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Automate The Boring Stuff with Python/Programs/File Operations/writeExcel.xlsx -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/GUIAutomation/Calc7Pic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Automate The Boring Stuff with Python/Programs/GUIAutomation/Calc7Pic.png -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/GUIAutomation/controlKeyboard.py: -------------------------------------------------------------------------------- 1 | import pyautogui 2 | 3 | pyautogui.click(100, 100) 4 | pyautogui.typewrite('Hello World', interval=0.2) 5 | pyautogui.typewrite(['a', 'b', 'left', 'left', 'X', 'Y'], interval=0.5) 6 | print(pyautogui.KEYBOARD_KEYS) 7 | pyautogui.press('f5') 8 | pyautogui.hotkey('ctrl', 's') 9 | -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/GUIAutomation/controlMouse.py: -------------------------------------------------------------------------------- 1 | import pyautogui 2 | 3 | # print(pyautogui.size()) 4 | # print(pyautogui.position()) 5 | # pyautogui.moveTo(10, 10, duration=1.5) 6 | # pyautogui.moveRel(200, 10, duration=1.5) 7 | # pyautogui.displayMousePosition() 8 | 9 | # MS Paint 10 | pyautogui.click() 11 | distance = 200 12 | while distance > 0: 13 | pyautogui.dragRel(distance, 0, duration=0.1) 14 | distance -= 25 15 | pyautogui.dragRel(0, distance, duration=0.1) 16 | pyautogui.dragRel(-distance, 0, duration=0.1) 17 | distance -= 25 18 | pyautogui.dragRel(0, -distance, duration=0.1) 19 | -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/GUIAutomation/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Automate The Boring Stuff with Python/Programs/GUIAutomation/screenshot.png -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/GUIAutomation/screenshotsAndImageRecognition.py: -------------------------------------------------------------------------------- 1 | import pyautogui 2 | 3 | # Screenshot 4 | pyautogui.screenshot("screenshot.png") 5 | 6 | # Image Recognition 7 | print(pyautogui.locateOnScreen('Calc7Pic.png')) 8 | print(pyautogui.locateCenterOnScreen('Calc7Pic.png')) 9 | print(pyautogui.moveTo((932, 336), duration=1)) 10 | pyautogui.click(932, 336) 11 | -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/Regex/phoneAndEmail.py: -------------------------------------------------------------------------------- 1 | import re 2 | import pyperclip 3 | 4 | # Create regex for phone numbers 5 | phoneRegex = re.compile(r''' 6 | # 415-555-0000, 555-0000, (415) 555-0000, 555-0000 ext 12345, ext. 12345, x12345 7 | ( 8 | ((\d\d\d) | (\(\d\d\d\)))? # area code(optional) 9 | (\s|-) # first separator 10 | \d\d\d # first 3 digits 11 | - # separator 12 | \d\d\d\d # last 4 digits 13 | (((ext(\.)?\s|x) # extension (optional) 14 | (\d{2,5})))? 15 | ) # extension number part (optional) 16 | ''', re.VERBOSE) 17 | 18 | # Create regex for email addresses 19 | emailRegex = re.compile(r''' 20 | # something@something.com 21 | 22 | [a-zA-Z0-9_.+]+ # name 23 | @ # @ 24 | [a-zA-Z0-9_.+]+ # domain name 25 | ''', re.VERBOSE) 26 | 27 | # Get the text from the clipboard 28 | text = pyperclip.paste() 29 | 30 | # Extract the email & phone number from the clipboard 31 | extractedPhone = phoneRegex.findall(text) 32 | extractedEmail = emailRegex.findall(text) 33 | 34 | allPhoneNumbers = [] 35 | for phoneNumber in extractedPhone: 36 | allPhoneNumbers.append(phoneNumber[0]) 37 | 38 | # Copy the extracted phone numbers & email to the clipboard 39 | results = '\n'.join(allPhoneNumbers) + '\n' + '\n'.join(extractedEmail) 40 | 41 | pyperclip.copy(results) 42 | -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Programs/requirements.txt: -------------------------------------------------------------------------------- 1 | beautifulsoup4==4.9.3 2 | bs4==0.0.1 3 | certifi==2020.6.20 4 | chardet==3.0.4 5 | docx==0.2.4 6 | et-xmlfile==1.0.1 7 | idna==2.10 8 | IMAPClient==2.1.0 9 | jdcal==1.4.1 10 | lxml==4.6.5 11 | MouseInfo==0.1.3 12 | openpyxl==3.0.5 13 | Pillow==8.3.2 14 | PyAutoGUI==0.9.52 15 | PyGetWindow==0.0.9 16 | PyMsgBox==1.0.8 17 | PyPDF2==1.26.0 18 | pyperclip==1.8.0 19 | PyRect==0.1.4 20 | PyScreeze==0.1.26 21 | python-docx==0.8.10 22 | PyTweening==1.0.3 23 | pyzmail36==1.0.4 24 | requests==2.24.0 25 | selenium==3.141.0 26 | six==1.15.0 27 | soupsieve==2.0.1 28 | urllib3==1.26.5 29 | -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/README.md: -------------------------------------------------------------------------------- 1 | # Automate the Boring Stuff with Python Programming 2 | 3 | This repository is home to the course resources of the very popular book and course [Automate the Boring Stuff with Python Programming](https://automatetheboringstuff.com/) by Al Sweigart. 4 | 5 | The repository contains the course notes in the `Resources` folder and all the programs can be found in the `Programs` folder. 6 | -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/Automate the Boring Stuff with Python Book.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Automate The Boring Stuff with Python/Resources/Automate the Boring Stuff with Python Book.pdf -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson1-recap.txt: -------------------------------------------------------------------------------- 1 | Explain what you are trying to do, not just what you did. 2 | If you get an error message, specify the point at which the error happens. (Including the line number.) 3 | Copy and paste the entire error message and your code to a pastebin site like pastebin.com or gist.github.com. 4 | Explain what you’ve already tried to do to solve your problem. 5 | List the version of Python you’re using. 6 | -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson10-recap.txt: -------------------------------------------------------------------------------- 1 | A scope can be thought of as an area of the source code, and as a container of variables. 2 | The global scope is code outside of all functions. Variables assigned here are global variables. 3 | Each function's code is in its own local scope. Variables assigned here are local variables. 4 | Code in the global scope cannot use any local variables. 5 | Code in a function's local scope cannot use variables in any another function's local scope. 6 | (If there is a global statement for a variable at the top of a function, that variable in that function is a global variable.) 7 | If there's an assignment statement for a variable in a function, that is a local variable. The exception is if there's a global statement for that variable; then it's a global variable. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson11-recap.txt: -------------------------------------------------------------------------------- 1 | A divide-by-zero error happens when Python divides a number by zero. 2 | Errors cause the program to crash. (This doesn't damage your computer at all. It's just that the computer doesn't know how to carry out this instruction, so it immediately stops the program by "crashing" rather than continue.) 3 | An error that happens inside a try block will cause code in the except block to execute. That code can handle the error or display a message to the user so that the program can keep going. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson13-recap.txt: -------------------------------------------------------------------------------- 1 | A list is a value that contains multiple values: [42, 3.14, ‘hello'] 2 | The values in a list are also called items. 3 | You can access items in a list with its integer index. 4 | The indexes start at 0, not 1. 5 | You can also use negative indexes: -1 refers to the last item, -2 refers to the second to last item, and so on. 6 | You can get multiple items from the list using a slice. 7 | The slice has two indexes. The new list's items start at the first index and go up to, but doesn't include, the second index. 8 | The len() function, concatenation, and replication work the same way on lists that they do with strings. 9 | You can convert a value into a list by passing it to the list() function. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson14-recap.txt: -------------------------------------------------------------------------------- 1 | A for loop technically iterates over the values in a list. 2 | The range() function returns a list-like value, which can be passed to the list() function if you need an actual list value. 3 | Variables can swap their values using multiple assignment: a, b = b, a 4 | Augmented assignment operators like += are used as shortcuts. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson15-recap.txt: -------------------------------------------------------------------------------- 1 | Methods are functions that are "called on" values. 2 | The index() list method returns the index of an item in the list. 3 | The append() list method adds a value to the end of a list. 4 | The insert() list method adds a value anywhere inside a list. 5 | The remove() list method removes an item, specified by the value, from a list. 6 | The sort() list method sorts the items in a list. 7 | The sort() method's reverse=True keyword argument can make the sort() method sort in reverse order. 8 | These list methods operate on the list "in place", rather than returning a new list value. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson16-recap.txt: -------------------------------------------------------------------------------- 1 | Strings can do a lot of the same things lists can do, but strings are immutable. 2 | Immutable values like strings and tuples cannot be modified "in place". 3 | Mutable values like lists can be modified in place. 4 | Variables don't contain lists, they contain references to lists. 5 | When passing a list argument to a function, you are actually passing a list reference. 6 | Changes made to a list in a function will affect the list outside the function. 7 | The \ line continuation character can be used to stretch Python instruction across multiple lines. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson17-recap.txt: -------------------------------------------------------------------------------- 1 | Dictionaries contain key-value pairs. Keys are like a list's indexes. 2 | Dictionaries are mutable. Variables hold references to dictionary values, not the dictionary value itself. 3 | Dictionaries are unordered. There is no "first" key-value pair in a dictionary. 4 | The keys(), values(), and items() methods will return list-like values of a dictionary's keys, vaues, and both keys and values, respectively. 5 | The get() method can return a default value if a key doesn't exist. 6 | The setdefault() method can set a value if a key doesn't exist. 7 | The pprint module's pprint() "pretty print" function can display a dictionary value cleanly. The pformat() function returns a string value of this output. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson19-recap.txt: -------------------------------------------------------------------------------- 1 | Strings are enclosed by a pair of single quotes or double quotes (as long as the same kind are used). 2 | Escape characters let you put quotes and other characters that are hard to type inside strings. 3 | Raw strings (which have the r prefix before the first quote) will literally print any backslashes in the string and ignore escape characters. 4 | Multiline strings begin and end with three quotes, and can span multiple lines. 5 | Indexes, slices, and the "in" and "not in" operators all work with strings. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson2-recap.txt: -------------------------------------------------------------------------------- 1 | An instruction that evaluates to a single value is an expression. An instruction that doesn't is a statement. 2 | IDLE is an editor. 3 | The interactive shell window has the >>> prompt. 4 | The file editor window is where you enter code for complete programs. 5 | Data types: int, float, string 6 | Strings hold text and begin and end with quotes: ‘Hello world!' 7 | Values can be stored in variables: spam = 42 8 | Variables can be used anywhere values can be used in expressions: spam + 1 -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson20-recap.txt: -------------------------------------------------------------------------------- 1 | upper() and lower() return an uppercase or lowercase string. 2 | isupper(), islower(), isalpha(), isalnum(), isdecimal(), isspace(), istitle() returns True or False if the string is that uppercase, lowercase, alphabetical letters, and so on. 3 | startswith() and endswith() also return bools. 4 | ‘,'.join([‘cat', ‘dog']) returns a string that combines the strings in the given list. 5 | ‘Hello world'.split() returns a list of strings split from the string it's called on. 6 | rjust() ,ljust(), center() returns a string padded with spaces. 7 | strip(), rstrip(), lstrip() returns a string with whitespace stripped off the sides. 8 | replace() will replace all occurrences of the first string argument with the second string argument. 9 | Pyperclip has copy() and paste() functions for getting and putting strings on the clipboard. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson22-recap.txt: -------------------------------------------------------------------------------- 1 | The shebang line tells your computer that you want to run the script using Python 3. 2 | On Windows, you can bring up the Run dialog by pressing Win+R. 3 | A batch file can save you a lot typing by running multiple commands. 4 | The batch files you'll make will look like this: 5 | @py C:\Users\Al\MyPytonScripts\hello.py %* 6 | @pause 7 | You'll need to add the MyPythonScripts folder to the PATH environment variable first. 8 | Command-line arguments can be read in the sys.argv list. (Import the sys module first.) -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson23-recap.txt: -------------------------------------------------------------------------------- 1 | Regular expressions are mini-language for specifying text patterns. Writing code to do pattern matching without regular expressions is a huge pain. 2 | Regex strings often use backslashes (like \d), so they are often written using raw strings: r'\d' 3 | \d is the regex for a numeric digit character. 4 | Import the re module first. 5 | Call the re.compile() function to create a regex object. 6 | Call the regex object's search() method to create a match object. 7 | Call the match object's group() method to get the matched string. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson24-recap.txt: -------------------------------------------------------------------------------- 1 | Groups are created in regex strings with parentheses. 2 | The first set of parentheses is group 1, the second is 2, and so on. 3 | Calling group() or group(0) returns the full matching string, group(1) returns group 1's matching string, and so on. 4 | Use \( and \) to match literal parentheses in the regex string. 5 | The | pipe can match one of many possible groups. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson25-recap.txt: -------------------------------------------------------------------------------- 1 | The ? says the group matches zero or one times. 2 | The * says the group matches zero or more times. 3 | The + says the group matches one or more times. 4 | The curly braces can match a specific number of times. 5 | The curly braces with two numbers matches a minimum and maximum number of times. 6 | Leaving out the first or second number in the curly braces says there is no minimum or maximum. 7 | "Greedy matching" matches the longest string possible, "nongreedy matching" (or "lazy matching") matches the shortest string possible. 8 | Putting a question mark after the curly braces makes it do a nongreedy/lazy match. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson26-recap.txt: -------------------------------------------------------------------------------- 1 | The regex method findall() is passed a string, and returns all matches in it, not just the first match. 2 | If the regex has 0 or 1 group, findall() returns a list of strings. 3 | If the regex has 2 or more groups, findall() returns a list of tuples of strings. 4 | \d is a shorthand character class that matches digits. \w matches "word characters" (letters, numbers, and the underscore). \s matches whitespace characters (space, tab, newline). 5 | The uppercase shorthand character classes \D, \W, and \S match charaters that are not digits, word characters, and whitespace. 6 | You can make your own character classes with square brackets: [aeiou] 7 | A ^ caret makes it a negative character class, matching anything not in the brackets: [^aeiou] -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson27-recap.txt: -------------------------------------------------------------------------------- 1 | ^ means the string must start with pattern, $ means the string must end with the pattern. Both means the entire string must match the entire pattern. 2 | The . dot is a wildcard; it matches any character except newlines. 3 | Pass re.DOTALL as the second argument to re.compile() to make the . dot match newlines as well. 4 | Pass re.I as the second argument to re.compile() to make the matching case-insensitive. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson28-recap.txt: -------------------------------------------------------------------------------- 1 | The sub() regex method will substitute matches with some other text. 2 | Using \1, \2 and so will substitute group 1, 2, etc in the regex pattern. 3 | Passing re.VERBOSE lets you add whitespace and comments to the regex string passed to re.compile(). 4 | If you want to pass multiple arguments (re.DOTALL , re.IGNORECASE, re.VERBOSE), combine them with the | bitwise operator. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson30-recap.txt: -------------------------------------------------------------------------------- 1 | Files have a name and a path. 2 | The root folder is the lowest folder. 3 | In a file path, the folders and filename are separated by backslashes on Windows and forward slashes on Linux and Mac. 4 | Use the os.path.join() function to combine folders with the correct slash. 5 | The current working directory is the oflder that any relative paths are relative to. 6 | os.getcwd() will return the current working directory. 7 | os.chdir() will change the current working directory. 8 | Absolute paths begin with the root folder, relative paths do not. 9 | The . folder represents "this folder", the .. folder represents "the parent folder". 10 | os.path.abspath() returns an absolute path form of the path passed to it. 11 | os.path.relpath() returns the relative path between two paths passed to it. 12 | os.makedirs() can make folders. 13 | os.path.getsize() returns a file's size. 14 | os.listdir() returns a list of strings of filenames. 15 | os.path.exists() returns True if the filename passed to it exists. 16 | os.path.isfile() and os.path.isdir() return True if they were passed a filename or file path. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson31-recap.txt: -------------------------------------------------------------------------------- 1 | The open() function will return a file object which has reading and writing –related methods. 2 | Pass ‘r' (or nothing) to open() to open the file in read mode. Pass ‘w' for write mode. Pass ‘a' for append mode. 3 | Opening a nonexistent filename in write or append mode will create that file. 4 | Call read() or write() to read the contents of a file or write a string to a file. 5 | Call readlines() to return a list of strings of the file's content. 6 | Call close() when you are done with the file. 7 | The shelve module can store Python values in a binary file. 8 | The shelve.open() function returns a dictionary-like shelf value. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson33-recap.txt: -------------------------------------------------------------------------------- 1 | os.unlink() will delete a file. 2 | os.rmdir() will delete a folder (but the folder must be empty). 3 | shutil.rmtree() will delete a folder and all its contents. 4 | Deleting can be dangerous, so do a "dry run" first. 5 | send2trash.send2trash() will send a file or folder to the recycling bin. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson35-recap.txt: -------------------------------------------------------------------------------- 1 | You can raise your own exceptions: raise Exception(‘This is the error message.') 2 | You can also use assertions: assert condition, ‘Error message' 3 | Assertions are for detecting programmer errors that are not meant to be recovered from. User errors should raise exceptions. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson36-recap.txt: -------------------------------------------------------------------------------- 1 | The logging module lets you display logging messages. 2 | Log messages create a "breadcrumb trail" of what your program is doing. 3 | After calling logging.basicConfig() to set up logging, call logging.debug(‘This is the message') to create a log message. 4 | When done, you can disable the log messages with logging.disable(logging.CRITICAL) 5 | Don't use print() for log messages: It's hard to remove the mall when you're done debugging. 6 | The five log levels are: DEBUG, INFO, WARNING, ERROR, and CRITICAL. 7 | You can also log to a file instead of the screen with the filename keyword argument in the logging.basicConfig() function. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson37-recap.txt: -------------------------------------------------------------------------------- 1 | The debugger is a tool that lets you execute Python code one instruction at a time and shows you the values in variables. 2 | Open the Debug Control window with Debug > Debugger before running the program. 3 | The Over button will step over the current line of code and pause on the next one. 4 | The Step button will step into a function call. 5 | The Out button will step out of the current function you are in. 6 | The Go button will continue the program until the next breakpoint or until the end of the program if there are no breakpoints. 7 | The Quit button will immediately terminate the program. 8 | Breakpoints are lines where the debugger will pause and let you choose when to continue running the program. 9 | Breakpoints can be set by right-clicking the file editor window and selecting "Set Breakpoint" -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson39-recap.txt: -------------------------------------------------------------------------------- 1 | The Requests module is a third-party module for downloading web pages and files. 2 | requests.get() returns a Response object. 3 | The raise_for_status() Response method will raise an exception if the download failed. 4 | You can save a downloaded file to your hard drive with calls to the iter_content() method. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson4-recap.txt: -------------------------------------------------------------------------------- 1 | The Boolean data type has only two values: True and False (both beginning with capital letters). 2 | Comparison operators compare two values and evaluate to a Boolean value: ==, !=, <, >, <=, >= 3 | == is a comparison operator, while = is the assignment operator for variables. 4 | Boolean operators (and, or, not) also evaluate to Boolean values. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson40-recap.txt: -------------------------------------------------------------------------------- 1 | Web pages are plaintext files formatted as HTML. 2 | HTML can be parsed with the BeautifulSoup module. 3 | BeautifulSoup is imported with the name bs4. 4 | Pass the string with the HTML to the bs4.BeautfiulSoup() function to get a Soup object. 5 | The Soup object has a select() method that can be passed a string of the CSS selector for an HTML tag. 6 | You can get a CSS selector string from the browser's developer tools by right-clicking the element and selecting Copy CSS Path. 7 | The select() method will return a list of matching Element objects. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson41-recap.txt: -------------------------------------------------------------------------------- 1 | To import selenium, you need to run: "from selenium import webdriver" (and not "import selenium"). 2 | To open the browser, run: browser = webdriver.Firefox() 3 | To send the browser to a URL, run: browser.get(‘https://inventwithpython.com') 4 | The browser.find_elements_by_css_selector() method will return a list of WebElement objects: elems = browser.find_elements_by_css_selector(‘img') 5 | WebElement objects have a "text" variable that contains the element's HTML in a string: elems[0].text 6 | The click() method will click on an element in the browser. 7 | The send_keys() method will type into a specific element in the browser. 8 | The submit() method will simulate clicking on the Submit button for a form. 9 | The browser can also be controlled with these methods: back(), forward(), refresh(), quit(). -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson42-recap.txt: -------------------------------------------------------------------------------- 1 | The OpenPyXL third-party module handles Excel spreadsheets (.xlsx files). 2 | openpyxl.load_workbook(filename) returns a Workbook object. 3 | get_sheet_names() and get_sheet_by_name() help get Worksheet objects. 4 | The square brackets in sheet[‘A1'] get Cell objects. 5 | Cell objects have a "value" member variable with the content of that cell. 6 | The cell() method also returns a Cell object from a sheet. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson43-recap.txt: -------------------------------------------------------------------------------- 1 | You can view and modify a sheet's name with its "title" member variable. 2 | Changing a cell's value is done using the square brackets, just like changing a value in a list or dictionary. 3 | Changes you make to the workbook object can be saved with the save() method. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson44-recap.txt: -------------------------------------------------------------------------------- 1 | The PyPDF2 module can read and write PDFs. 2 | Opening a PDF is done by calling open() and passing the file object to PPdfFileReader(). 3 | A Page object can be obtained from the PDF object with the getPage() method. 4 | The text from a Page object is obtained with the extractText() method, which can be imperfect. 5 | New PDFs can be made from PdfFileWriter(). 6 | New pages can be appended to a writer object with the addPage() method. 7 | Call the write() method to save its changes. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson45-recap.txt: -------------------------------------------------------------------------------- 1 | The Python-Docx third-party module can read and write .docx Word files. 2 | Open a Word file with docx.Document() 3 | Access one of the Paragraph objects from the "paragraphs" member variable, which is a list of Paragraph objects. 4 | Paragraph objects have a "text" member variable containing the text as a string value. 5 | Paragraphs are composed of "runs". The "runs" member variable of a Paragraph object contains a list of Run objects. 6 | Run objects also have a "text" member variable. 7 | Run objects have a "bold", "italic", and "underline" member variables which can be set to True or False. 8 | Paragraph and run objects have a "style" member variable that can be set to one of Word's built-in styles. 9 | Word files can be created by calling add_paragraph() and add_run() to append text content. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson48-recap.txt: -------------------------------------------------------------------------------- 1 | Controlling the mouse and keyboard is called GUI automation. 2 | The PyAutoGUI third-party module has many functions to control the mouse and keyboard. 3 | pyautogui.size() returns the screen resolution, pyautogui.position() returns the mouse position. These are returned as tuples of two integers. 4 | pyautogui.moveTo(x, y) moves the mouse to an x, y coordinate on the screen. 5 | The mouse move is instantaneous, unless you pass an int for the "duration" keyword argument. 6 | pyautogui.moveRel() moves the mouse relative to its current position. 7 | PyAutoGUI's click(), doubleClick(), rightClick(), and middleClick() click the mouse buttons. 8 | dragTo() and dragRel() will move the mouse while holding down a mouse button. 9 | If your program gets out of control, quickly move the mouse cursor to the top-left corner to stop it. 10 | There's more documentation at pyautogui.readthedocs.org. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson49-recap.txt: -------------------------------------------------------------------------------- 1 | PyAutoGUI's virtual key presses will go the window the currently has focus. 2 | typewrite() can be passed a string of characters to type. It also has an "interval" keyword argument. 3 | Passing a list of strings to typewrite() lets you use hard-to-type keyboard keys, like ‘shift' or ‘f1'. 4 | These keyboard key strings are in the pyautogui.KEYBOARD_KEYS list. 5 | pyautogui.press() will press a single key. 6 | pyautogui.hotkey() can be used for keyboard shortcuts, like Ctrl-O. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson5-recap.txt: -------------------------------------------------------------------------------- 1 | An if statement can be used to conditionally execute code, depending on whether the "if" statement's condition is True or False. 2 | An elif (that is, "else if") statement can follow an if statement. Its block executes if its condition is True and all the previous conditions have been False. 3 | An else statement comes at the end. Its block is executed if all of the previous conditions have been False. 4 | The values 0 (integer), 0.0 (float), and ‘‘ (the empty string) are considered to be "falsey" values. When used in conditions they are considered False. You can always see for yourself which values are truthy or falsey by passing them to the bool() function. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson50-recap.txt: -------------------------------------------------------------------------------- 1 | A screenshot is an image of the screen's content. 2 | The pyautogui.screenshot() will return an Image object of the screen, or you can pass it a filename to save it to a file 3 | locateOnScreen() is passed a sample image file, and returns the coordinates of where it is on the screen. 4 | locateCenterOnScreen() will return an (x, y) tuple of where the image is on the screen. 5 | Combining the keyboard/mouse/screenshot functions lets you make awesome stuff! -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson6-recap.txt: -------------------------------------------------------------------------------- 1 | When the execution reaches the end of a "while" statement's block, it jumps back to the start to re-check the condition. 2 | You can press ctrl-c to interrupt an infinite loop. This hotkey stops Python programs. 3 | A "break" statement causes the execution to immediately leave the loop, without re-check the condition. 4 | A "continue" statement causes the execution to immediate jump back to the start of the loop and re-check the condition. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson7-recap.txt: -------------------------------------------------------------------------------- 1 | A "for" loop will loop a specific number of times. 2 | The range() function can be called with one, two, or three arguments. 3 | The break and continue statements can be used in for loops just like they're used in while loops. -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson8-recap.txt: -------------------------------------------------------------------------------- 1 | You can import modules and get access to new functions. 2 | The modules that come with Python are called the standard library, but you can also install third-party modules using the pip tool. 3 | The sys.exit() function will immediately quit your program. 4 | The Pyperclip third-party module has copy() and paste() functions for reading and writing text to the clipboard(). -------------------------------------------------------------------------------- /Automate The Boring Stuff with Python/Resources/lesson9-recap.txt: -------------------------------------------------------------------------------- 1 | Functions are like a mini-program inside your program. 2 | The main point of functions is to get rid of duplicate code. 3 | The def statement defines a function. 4 | The input to functions are called arguments. The output is called the return value. 5 | The parameters are the variables in between the function's parentheses in the def statement. 6 | The return value is specified using the return statement. 7 | Every function has a return value. If your function doesn't have a return statement, the default return value is None. (Like True and False, None is written with a capital first letter.) 8 | Keyword arguments to functions are usually for optional arguments. The print() function has keyword arguments "end" and "sep". -------------------------------------------------------------------------------- /Coronavirus Voice Assistant/.gitignore: -------------------------------------------------------------------------------- 1 | config.py 2 | __pycache__ 3 | .ipynb_checkpoints -------------------------------------------------------------------------------- /Coronavirus Voice Assistant/Part1.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import json 3 | import pyttsx3 4 | import speech_recognition as sr 5 | import re 6 | 7 | API_KEY = 'YOUR_API_KEY' 8 | PROJECT_TOKEN = 'YOUR_PROJECT_TOKEN' 9 | RUN_TOKEN = 'YOUR_RUN_TOKEN' 10 | 11 | 12 | class Data: 13 | def __init__(self, api_key, project_token): 14 | self.api_key = api_key 15 | self.project_token = project_token 16 | self.params = { 17 | "api_key": self.api_key 18 | } # Set up Authentication 19 | self.data = self.get_data() # Most recent run 20 | 21 | def get_data(self): 22 | response = requests.get(f'https://www.parsehub.com/api/v2/projects/{PROJECT_TOKEN}/last_ready_run/data', params={ 23 | "api_key": API_KEY}) # Authentication for the get request 24 | data = json.loads(response.text) 25 | return data 26 | 27 | def get_total_cases(self): # Get the total coronavirus cases 28 | data = self.data['total'] 29 | for val in data: 30 | if val['name'] == "Coronavirus Cases:": 31 | return val['value'] 32 | 33 | def get_total_deaths(self): # Get the total coronavirus deaths 34 | data = self.data['total'] 35 | for val in data: 36 | if val['name'] == "Deaths:": 37 | return val['value'] 38 | return "0" 39 | 40 | # Get the details of cases and deaths in a country 41 | def get_country_data(self, country): 42 | data = self.data["country"] 43 | for val in data: 44 | if val['name'].lower() == country.lower(): 45 | return val 46 | return "0" 47 | 48 | def get_list_of_countries(self): 49 | countries = [] 50 | for country in self.data['country']: 51 | countries.append(country['name'].lower()) 52 | return countries 53 | 54 | 55 | # Voice Recognition 56 | 57 | def speak(text): # Speak 58 | engine = pyttsx3.init() # Initialise the python text to speech engine 59 | engine.say(text) 60 | engine.runAndWait() 61 | 62 | 63 | def get_audio(): # Listen 64 | r = sr.Recognizer() 65 | with sr.Microphone() as source: 66 | audio = r.listen(source) 67 | said = "" 68 | 69 | try: 70 | # Google to recognize the speech input 71 | said = r.recognize_google(audio) 72 | except Exception as e: 73 | print("Exception: ", str(e)) 74 | return said.lower() 75 | 76 | 77 | def main(): 78 | print("Started Program!") 79 | data = Data(API_KEY, PROJECT_TOKEN) 80 | country_list = list(data.get_list_of_countries()) 81 | 82 | # Look for REGEX patterns in the voice 83 | TOTAL_PATTERNS = { 84 | re.compile("[\w\s]+ total [\w\s]+ cases"): data.get_total_cases, 85 | re.compile("[\w\s]+ total cases"): data.get_total_cases, 86 | re.compile("[\w\s]+ total [\w\s]+ deaths"): data.get_total_deaths, 87 | re.compile("[\w\s]+ total deaths"): data.get_total_deaths 88 | } 89 | 90 | COUNTRY_PATTERNS = { 91 | re.compile("[\w\s]+ cases [\w\s]+"): lambda country: data.get_country_data(country)['total_cases'], 92 | re.compile("[\w\s]+ deaths [\w\s]+"): lambda country: data.get_country_data(country)['total_deaths'], 93 | re.compile("[\w\s]+ deaths [\w\s]+"): lambda country: data.get_country_data(country)['total_deaths'] 94 | } 95 | 96 | END_PHRASE = "stop" 97 | 98 | while True: 99 | print("Listening...") 100 | text = get_audio() 101 | print(text) 102 | result = None 103 | 104 | for pattern, func in COUNTRY_PATTERNS.items(): 105 | if pattern.match(text): 106 | words = set(text.split(" ")) 107 | for country in country_list: 108 | if country in words: 109 | result = func(country) 110 | break 111 | 112 | for pattern, func in TOTAL_PATTERNS.items(): 113 | if pattern.match(text): 114 | result = func() 115 | break 116 | 117 | if result: 118 | speak(result) 119 | 120 | if text.find(END_PHRASE) != -1: # Stop 121 | print("Exit") 122 | break 123 | 124 | 125 | main() 126 | -------------------------------------------------------------------------------- /Coronavirus Voice Assistant/README.md: -------------------------------------------------------------------------------- 1 | # Coronavirus Voice Assistant 2 | 3 | This app makes use of [ParseHub](https://www.parsehub.com/) which is a powerful web-scraping tool. 4 | 5 | The data is extracted from the very popular website [Worldometers](https://www.worldometers.info/coronavirus/) that provides the accurate information about the COVID19 disease worldwide. 6 | 7 | --- 8 | 9 | Steps to be followed: 10 | 11 | 1. Download [ParseHub](https://www.parsehub.com/quickstart). 12 | 2. Start a New Project and paste the link 'https://www.worldometers.info/coronavirus/'. 13 | 3. Select the items that you would like to scrape from the page and assign unique tags to each one of them. Get the data. 14 | 4. Copy the api key, project token and run token to config file and import them to your main.py file. 15 | 5. Install the requirements for this project: requests, certifi, chardet, comtypes, idna, pyttsx3, pywin32, SpeechRecognition, urllib3. 16 | 6. Run the main.py file. 17 | 18 | --- 19 | 20 | Steps to run the application: 21 | 22 | 1. Execute the command "python main.py". 23 | 2. Ask the assistant for "number of total cases", "total cases in India", etc. 24 | 3. For updating the information, say "update" and wait for a while. 25 | 4. Say "stop" to exit the application. 26 | 27 | --- 28 | 29 | Get more information about this project on [Medium](https://medium.com/@KGPrajwal/covid19-voice-assistant-63c37b1f02f9). 30 | 31 | --- 32 | 33 | ### Thank You! 34 | -------------------------------------------------------------------------------- /Coronavirus Voice Assistant/main.py: -------------------------------------------------------------------------------- 1 | import config 2 | import requests 3 | import json 4 | import pyttsx3 5 | import speech_recognition as sr 6 | import re 7 | import threading 8 | import time 9 | 10 | API_KEY = config.MY_API_KEY 11 | PROJECT_TOKEN = config.MY_PROJECT_TOKEN 12 | RUN_TOKEN = config.MY_RUN_TOKEN 13 | 14 | 15 | class Data: 16 | def __init__(self, api_key, project_token): 17 | self.api_key = api_key 18 | self.project_token = project_token 19 | self.params = { 20 | "api_key": self.api_key 21 | } # Set up Authentication 22 | self.data = self.get_data() # Most recent run 23 | 24 | def get_data(self): 25 | response = requests.get(f'https://www.parsehub.com/api/v2/projects/{PROJECT_TOKEN}/last_ready_run/data', params={ 26 | "api_key": API_KEY}) # Authentication for the get request 27 | data = json.loads(response.text) 28 | return data 29 | 30 | def get_total_cases(self): # Get the total coronavirus cases 31 | data = self.data['total'] 32 | for val in data: 33 | if val['name'] == "Coronavirus Cases:": 34 | return val['value'] 35 | 36 | def get_total_deaths(self): # Get the total coronavirus deaths 37 | data = self.data['total'] 38 | for val in data: 39 | if val['name'] == "Deaths:": 40 | return val['value'] 41 | return "0" 42 | 43 | # Get the details of cases and deaths in a country 44 | def get_country_data(self, country): 45 | data = self.data["country"] 46 | for val in data: 47 | if val['name'].lower() == country.lower(): 48 | return val 49 | return "0" 50 | 51 | def get_list_of_countries(self): 52 | countries = [] 53 | for country in self.data['country']: 54 | countries.append(country['name'].lower()) 55 | return countries 56 | 57 | def update(self): # Update the information 58 | response = requests.post( 59 | f'https://www.parsehub.com/api/v2/projects/{PROJECT_TOKEN}/run', params={"api_key": API_KEY}) 60 | 61 | def poll(): 62 | time.sleep(0.1) 63 | old_data = self.data 64 | while True: 65 | new_data = self.get_data() 66 | if new_data != old_data: # Check if old data equals new data every 5 seconds 67 | self.data = new_data # Update 68 | print("Data Updated!") 69 | break 70 | time.sleep(5) 71 | 72 | # Run the voice assistant on one thread and update the information on another 73 | t = threading.Thread(target=poll) 74 | t.start() 75 | 76 | # Voice Recognition 77 | 78 | 79 | def speak(text): # Speak 80 | engine = pyttsx3.init() # Initialise the python text to speech engine 81 | engine.say(text) 82 | engine.runAndWait() 83 | 84 | 85 | def get_audio(): # Listen 86 | r = sr.Recognizer() 87 | with sr.Microphone() as source: 88 | audio = r.listen(source) 89 | said = "" 90 | 91 | try: 92 | # Google to recognize the speech input 93 | said = r.recognize_google(audio) 94 | except Exception as e: 95 | print("Exception: ", str(e)) 96 | return said.lower() 97 | 98 | 99 | def main(): 100 | print("Started Program!") 101 | data = Data(API_KEY, PROJECT_TOKEN) 102 | country_list = list(data.get_list_of_countries()) 103 | 104 | # Look for REGEX patterns in the voice 105 | TOTAL_PATTERNS = { 106 | re.compile("[\w\s]+ total [\w\s]+ cases"): data.get_total_cases, 107 | re.compile("[\w\s]+ total cases"): data.get_total_cases, 108 | re.compile("[\w\s]+ total [\w\s]+ deaths"): data.get_total_deaths, 109 | re.compile("[\w\s]+ total deaths"): data.get_total_deaths 110 | } 111 | 112 | COUNTRY_PATTERNS = { 113 | re.compile("[\w\s]+ cases [\w\s]+"): lambda country: data.get_country_data(country)['total_cases'], 114 | re.compile("[\w\s]+ deaths [\w\s]+"): lambda country: data.get_country_data(country)['total_deaths'], 115 | re.compile("[\w\s]+ deaths [\w\s]+"): lambda country: data.get_country_data(country)['total_deaths'] 116 | } 117 | 118 | UPDATE = "update" 119 | 120 | END_PHRASE = "stop" 121 | 122 | while True: 123 | print("Listening...") 124 | text = get_audio() 125 | print(text) 126 | result = None 127 | 128 | for pattern, func in COUNTRY_PATTERNS.items(): 129 | if pattern.match(text): 130 | words = set(text.split(" ")) 131 | for country in country_list: 132 | if country in words: 133 | result = func(country) 134 | break 135 | 136 | for pattern, func in TOTAL_PATTERNS.items(): 137 | if pattern.match(text): 138 | result = func() 139 | break 140 | 141 | if text == UPDATE: 142 | result = "Data is being updated. This may take a while." 143 | data.update() 144 | 145 | if result: 146 | speak(result) 147 | 148 | if text.find(END_PHRASE) != -1: # Stop 149 | print("Exit") 150 | break 151 | 152 | 153 | main() 154 | -------------------------------------------------------------------------------- /Cowin Vaccine Notifier/README.md: -------------------------------------------------------------------------------- 1 | # Cowin Vaccine Notifier 2 | 3 | Please modify the *script.py* file to mention the age and pincode requirements. 4 | 5 | Please enter `pip install playsound` in the terminal to be able to hear a notification sound upon vaccine availability. 6 | 7 | Run the script file using `python script.py` and wait until you see information on vaccine availability on the terminal. 8 | 9 | Please login to [Cowin website](https://www.cowin.gov.in/home), verify the vaccine availability and book your appointment. 10 | 11 | 12 | **Note**: 13 | - Only useful for Indian residents to book vaccine appointments for COVID-19 14 | - The API endpoints usually keep updating and could result in incorrect information in the future. Always consider verifying the vaccine availability on the website. 15 | -------------------------------------------------------------------------------- /Cowin Vaccine Notifier/notification_sound.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Cowin Vaccine Notifier/notification_sound.mp3 -------------------------------------------------------------------------------- /Cowin Vaccine Notifier/script.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import time 3 | import json 4 | from datetime import datetime, timedelta 5 | from playsound import playsound 6 | 7 | # Please change requirements below 8 | age = 46 # Age of the person 9 | pincodes = ['560076'] # Pincode/s to search vaccine availability 10 | num_days = 2 # Number of days in the future to search for 11 | 12 | today = datetime.today() 13 | further_days = [today + timedelta(days=i) for i in range(num_days)] 14 | dates = [i.strftime("%d-%m-%Y") for i in further_days] 15 | 16 | while True: 17 | cnt = 0 18 | for pincode in pincodes: 19 | for date in dates: 20 | url = "https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/calendarByPin?pincode={}&date={}".format( 21 | pincode, date) 22 | headers = { 23 | 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36' 24 | } 25 | result = requests.get(url, headers = headers) 26 | if result.ok: 27 | response_json = result.json() 28 | flag = False 29 | if response_json['centers']: 30 | for center in response_json['centers']: 31 | for session in center['sessions']: 32 | if session['min_age_limit']<=age and session['available_capacity']>0: 33 | print('\nPincode: ' + pincode) 34 | print('\nAvailability date: ' + date) 35 | print("\nAddress: "+center['address']) 36 | print("\nCenter: "+center['name']) 37 | print("\nBlock Name: "+center['block_name']) 38 | print("\nPrice: "+center['fee_type']) 39 | print("\nAvailable capacity (Dose 1): "+str(session['available_capacity_dose1'])) 40 | print("\nAvailable capacity (Dose 2): "+str(session['available_capacity_dose2'])) 41 | print("\nVaccine Type: "+session['vaccine']) 42 | cnt+=1 43 | else: 44 | print("\nIssue with API. No response.") 45 | if cnt==0: 46 | print("\nNo vaccine slots available.") 47 | else: 48 | print("\nFound vaccine! Please find the details above!") 49 | print("\nLogin to https://www.cowin.gov.in/home -> Sign in -> Book the vaccine appointment using the details.") 50 | playsound("notification_sound.mp3") 51 | 52 | print("\n==================================\n") 53 | 54 | delay = datetime.now()+timedelta(minutes=2) 55 | while datetime.now() < delay: 56 | time.sleep(10) 57 | -------------------------------------------------------------------------------- /Data Engineering Introduction/.gitignore: -------------------------------------------------------------------------------- 1 | /venv 2 | /news/node_modules 3 | auth.py 4 | __pycache__ 5 | .ipynb_checkpoints 6 | 7 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 8 | 9 | # dependencies 10 | /node_modules 11 | /.pnp 12 | .pnp.js 13 | 14 | # testing 15 | /coverage 16 | 17 | # production 18 | /build 19 | 20 | # misc 21 | .DS_Store 22 | .env.local 23 | .env.development.local 24 | .env.test.local 25 | .env.production.local 26 | 27 | npm-debug.log* 28 | yarn-debug.log* 29 | yarn-error.log* 30 | -------------------------------------------------------------------------------- /Data Engineering Introduction/README.md: -------------------------------------------------------------------------------- 1 | # Data Engineering 101 2 | 3 | This is a simple data engineering project that extracts the top headlines from a news website that has been created and loads them into a csv file then stores it in an AWS S3 Bucket. 4 | 5 | ### Steps to use the project 6 | 7 | - Run the index.html file on the specified port. 8 | - Create a file called `auth.py` and specify the AWS credentials as follows: 9 | ``` 10 | ACCESS_KEY="" 11 | SECRET_KEY="" 12 | ``` 13 | - Install all the python packages mentioned in the `requirements.txt`. 14 | - Make sure to change the bucket name where I've used `aws-data-engineering-csv-etl-pipeline-demo`. 15 | - Run the `script.py` file. 16 | 17 | ### Result 18 | 19 | A `data.csv` file is created locally in the project directory and also it gets loaded in your AWS S3 Bucket. -------------------------------------------------------------------------------- /Data Engineering Introduction/data.csv: -------------------------------------------------------------------------------- 1 | header,summary,link 2 | -------------------------------------------------------------------------------- /Data Engineering Introduction/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Data Engineering 9 | 10 | 11 | 14 |

News

15 |
16 |
17 |

Article 1 Headline

18 |

Article 1 Summary

19 |
20 |
21 |
22 |

Article 2 Headline

23 |

Article 2 Summary

24 |
25 |
26 |
27 |

Article 3 Headline

28 |

Article 3 Summary

29 |
30 |
31 |
32 |

Article 4 Headline

33 |

Article 4 Summary

34 |
35 |
36 | 37 | -------------------------------------------------------------------------------- /Data Engineering Introduction/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Data Engineering Introduction/requirements.txt -------------------------------------------------------------------------------- /Data Engineering Introduction/script.py: -------------------------------------------------------------------------------- 1 | from bs4 import BeautifulSoup 2 | import requests 3 | import csv 4 | import boto3 5 | from auth import ACCESS_KEY, SECRET_KEY 6 | 7 | # Get data from the site and store in CSV file 8 | soup = BeautifulSoup(requests.get('http://127.0.0.1:5500/').text, 'lxml') 9 | csv_file = open('data.csv', 'w', newline='') 10 | writer = csv.writer(csv_file) 11 | 12 | articles = soup.find_all('article') 13 | writer.writerow(['header', 'summary', 'link']) 14 | 15 | for article in articles: 16 | headline = article.h2.a.text 17 | summary = article.p.text 18 | link = article.h2.a["href"] 19 | writer.writerow([headline, summary, link]) 20 | 21 | csv_file.close() 22 | 23 | 24 | # Store to AWS S3 bucket 25 | client = boto3.client( 26 | 's3', 27 | aws_access_key_id=ACCESS_KEY, 28 | aws_secret_access_key=SECRET_KEY, 29 | ) 30 | 31 | client.create_bucket(Bucket='aws-data-engineering-csv-etl-pipeline-demo') 32 | with open("data.csv", "rb") as f: 33 | client.upload_fileobj(f, "aws-data-engineering-csv-etl-pipeline-demo", "data.csv") 34 | print('Task Completed Sucessfully!') -------------------------------------------------------------------------------- /Machine Learning Algorithms/.gitignore: -------------------------------------------------------------------------------- 1 | /venv -------------------------------------------------------------------------------- /Machine Learning Algorithms/README.md: -------------------------------------------------------------------------------- 1 | # Machine Learning Algorithms 2 | 3 | Some of the most important machine learning algorithms are implemented here: 4 | 5 | - K-Nearest Neighbors 6 | - Linear SVM 7 | - RBF SVM 8 | - Gaussian Process 9 | - Decision Tree 10 | - Random Forest 11 | - Neural Network 12 | - AdaBoost 13 | - Naive Bayes 14 | - Quadratic Discriminant Analysis 15 | 16 | 17 | -------------------------------------------------------------------------------- /Machine Learning Algorithms/final_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Machine Learning Algorithms/final_image.png -------------------------------------------------------------------------------- /Machine Learning Algorithms/requirements.txt: -------------------------------------------------------------------------------- 1 | certifi==2020.6.20 2 | cycler==0.10.0 3 | joblib==0.16.0 4 | kiwisolver==1.2.0 5 | matplotlib==3.3.2 6 | numpy==1.19.2 7 | Pillow==8.3.2 8 | pyparsing==2.4.7 9 | python-dateutil==2.8.1 10 | scikit-learn==0.23.2 11 | scipy==1.5.2 12 | six==1.15.0 13 | sklearn==0.0 14 | threadpoolctl==2.1.0 15 | -------------------------------------------------------------------------------- /Machine Learning Algorithms/script.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | from matplotlib.colors import ListedColormap 4 | from sklearn.model_selection import train_test_split 5 | from sklearn.preprocessing import StandardScaler 6 | from sklearn.datasets import make_moons, make_circles, make_classification 7 | from sklearn.neural_network import MLPClassifier 8 | from sklearn.neighbors import KNeighborsClassifier 9 | from sklearn.svm import SVC 10 | from sklearn.gaussian_process import GaussianProcessClassifier 11 | from sklearn.gaussian_process.kernels import RBF 12 | from sklearn.tree import DecisionTreeClassifier 13 | from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier 14 | from sklearn.naive_bayes import GaussianNB 15 | from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis 16 | 17 | h = .02 18 | names = [ 19 | "Nearest Neighbors", 20 | "Linear SVM", 21 | "RBF SVM", 22 | "Gausssian Process", 23 | "Decision Tree", 24 | "Random Forest", 25 | "Neural Network", 26 | "AdaBoost", 27 | "Naive Bayes", 28 | "Quadratic Discriminant Analysis"] 29 | 30 | classifiers = [ 31 | KNeighborsClassifier(3), 32 | SVC(kernel="linear", C=0.025), 33 | SVC(gamma=2, C=1), 34 | GaussianProcessClassifier(1.0 * RBF(1.0)), 35 | DecisionTreeClassifier(max_depth=5), 36 | RandomForestClassifier(max_depth=5, n_estimators=10, max_features=1), 37 | MLPClassifier(alpha=1, max_iter=1000), 38 | AdaBoostClassifier(), 39 | GaussianNB(), 40 | QuadraticDiscriminantAnalysis() 41 | ] 42 | 43 | 44 | X, y = make_classification( 45 | n_features=2, 46 | n_redundant=0, 47 | n_informative=2, 48 | random_state=1, 49 | n_clusters_per_class=1) 50 | 51 | rng = np.random.RandomState(2) 52 | X += 2*rng.uniform(size=X.shape) 53 | linearly_separable = (X, y) 54 | 55 | datasets = [ 56 | make_moons(noise=0.3, random_state=0), 57 | make_circles(noise=0.2, factor=0.5, random_state=1), 58 | linearly_separable 59 | ] 60 | 61 | # Iterate through the dataset 62 | figure = plt.figure(figsize=(27, 9)) 63 | i = 1 64 | for ds_cnt, ds in enumerate(datasets): 65 | X, y = ds 66 | X = StandardScaler().fit_transform(X) 67 | X_train, X_test, y_train, y_test = train_test_split( 68 | X, y, test_size=.4, random_state=42) 69 | x_min, x_max = X[:, 0].min() - .5, X[:, 0].max()+.5 70 | y_min, y_max = X[:, 1].min() - .5, X[:, 1].max()+.5 71 | xx, yy = np.meshgrid(np.arange(x_min, x_max, h), 72 | np.arange(y_min, y_max, h)) 73 | cm = plt.cm.RdBu 74 | cm_bright = ListedColormap(['#FF0000', '#0000FF']) 75 | ax = plt.subplot(len(datasets), len(classifiers)+1, i) 76 | if ds_cnt == 0: 77 | ax.set_title("Input data") 78 | ax.scatter(X_train[:, 0], X_train[:, 1], c=y_train, 79 | cmap=cm_bright, edgecolors='k') 80 | ax.scatter(X_test[:, 0], X_test[:, 1], c=y_test, 81 | cmap=cm_bright, alpha=0.6, edgecolors='k') 82 | ax.set_xlim(xx.min(), xx.max()) 83 | ax.set_ylim(yy.min(), yy.max()) 84 | ax.set_xticks(()) 85 | ax.set_yticks(()) 86 | i += 1 87 | 88 | # Iterate over the classifiers 89 | for name, clf in zip(names, classifiers): 90 | ax = plt.subplot(len(datasets), len(classifiers)+1, i) 91 | clf.fit(X_train, y_train) 92 | score = clf.score(X_test, y_test) 93 | 94 | if hasattr(clf, "decision_function"): 95 | Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) 96 | else: 97 | Z = clf.predict_proba(np.c_[xx.ravel(), yy.ravel()])[:, 1] 98 | 99 | Z = Z.reshape(xx.shape) 100 | ax.contourf(xx, yy, Z, cmap=cm, alpha=.8) 101 | ax.scatter(X_train[:, 0], X_train[:, 1], c=y_train, 102 | cmap=cm_bright, edgecolors='k') 103 | ax.scatter(X_test[:, 0], X_test[:, 1], c=y_test, 104 | cmap=cm_bright, edgecolors='k', alpha=0.6) 105 | 106 | ax.set_xlim(xx.min(), xx.max()) 107 | ax.set_ylim(yy.min(), yy.max()) 108 | ax.set_xticks(()) 109 | ax.set_yticks(()) 110 | if ds_cnt == 0: 111 | ax.set_title(name) 112 | ax.text(xx.max()-.3, yy.min()+.3, ('%.2f' % score).lstrip('0'), 113 | size=15, horizontalalignment='right') 114 | i += 1 115 | 116 | plt.tight_layout() 117 | plt.show() 118 | -------------------------------------------------------------------------------- /Path-Finding-Visualizer/README.md: -------------------------------------------------------------------------------- 1 | # A* Path Finding Algorithm 2 | 3 | 4 | 5 | An A* path finding algorithm is used to find the shortest distance between two given points on a graph. This algorithm, unlike other path-finding algorithm such as Dijkstra's algorithm doesn't brute force search for every node to find a path, but use a heuristic function that guides which path is essential for accomplishing the task. 6 | 7 | The formula used here is `F(n) = G(n) + H(n)` 8 | where, 9 | - G(n) => The G score is the shortest distance between start node to the current node. 10 | - H(n) => The H score is the heuristic the estimates the distance of end node from the start node. 11 | - F(n) => The F score is the addition of both G score and H score. 12 | 13 | Learn more about A-star path finding algorithm [here](https://en.wikipedia.org/wiki/A*_search_algorithm). -------------------------------------------------------------------------------- /Path-Finding-Visualizer/astar.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | import math 3 | from queue import PriorityQueue 4 | 5 | WIDTH = 800 6 | WIN = pygame.display.set_mode((WIDTH, WIDTH)) # Set the width of the window 7 | pygame.display.set_caption("A* Path Finding Algorithm") # Window title 8 | 9 | # Colors 10 | RED = (255, 0, 0) 11 | GREEN = (0, 255, 0) 12 | BLUE = (0, 255, 0) 13 | YELLOW = (255, 255, 0) 14 | WHITE = (255, 255, 255) 15 | BLACK = (0, 0, 0) 16 | PURPLE = (128, 0, 128) 17 | ORANGE = (255, 165, 0) 18 | GREY = (128, 128, 128) 19 | TURQUOISE = (64, 224, 208) 20 | 21 | 22 | class Node: 23 | def __init__(self, row, col, width, total_rows): 24 | self.row = row 25 | self.col = col 26 | self.x = row * width 27 | self.y = col * width 28 | self.color = WHITE 29 | self.neighbors = [] 30 | self.width = width 31 | self.total_rows = total_rows 32 | 33 | def get_pos(self): 34 | return self.row, self.col 35 | 36 | def is_closed(self): 37 | return self.color == RED 38 | 39 | def is_open(self): 40 | return self.color == GREEN 41 | 42 | def is_barrier(self): 43 | return self.color == BLACK 44 | 45 | def is_start(self): 46 | return self.color == ORANGE 47 | 48 | def is_end(self): 49 | return self.color == TURQUOISE 50 | 51 | def reset(self): 52 | self.color = WHITE 53 | 54 | def make_start(self): 55 | self.color = ORANGE 56 | 57 | def make_closed(self): 58 | self.color = RED 59 | 60 | def make_open(self): 61 | self.color = GREEN 62 | 63 | def make_barrier(self): 64 | self.color = BLACK 65 | 66 | def make_end(self): 67 | self.color = TURQUOISE 68 | 69 | def make_path(self): 70 | self.color = PURPLE 71 | 72 | def draw(self, win): 73 | pygame.draw.rect( 74 | win, self.color, (self.x, self.y, self.width, self.width)) 75 | 76 | def update_neighbors(self, grid): 77 | self.neighbors = [] 78 | if self.row < self.total_rows - 1 and not grid[self.row + 1][self.col].is_barrier(): 79 | self.neighbors.append(grid[self.row + 1][self.col]) 80 | 81 | if self.row > 0 and not grid[self.row - 1][self.col].is_barrier(): 82 | self.neighbors.append(grid[self.row - 1][self.col]) 83 | 84 | if self.col < self.total_rows - 1 and not grid[self.row][self.col + 1].is_barrier(): 85 | self.neighbors.append(grid[self.row][self.col + 1]) 86 | 87 | if self.col > 0 and not grid[self.row][self.col - 1].is_barrier(): 88 | self.neighbors.append(grid[self.row][self.col - 1]) 89 | 90 | def __lt__(self, other): 91 | return False 92 | 93 | 94 | def h(p1, p2): 95 | # Heuristic function - Manhattan distance 96 | x1, y1 = p1 97 | x2, y2 = p2 98 | return abs(x1 - x2) + abs(y1 - y2) 99 | 100 | 101 | def reconstruct_path(came_from, current, draw): 102 | while current in came_from: 103 | current = came_from[current] 104 | current.make_path() 105 | draw() 106 | 107 | 108 | def algorithm(draw, grid, start, end): 109 | # A* algorithm 110 | count = 0 111 | open_set = PriorityQueue() 112 | open_set.put((0, count, start)) 113 | came_from = {} 114 | g_score = {node: float("inf") for row in grid for node in row} 115 | g_score[start] = 0 116 | f_score = {node: float("inf") for row in grid for node in row} 117 | f_score[start] = h(start.get_pos(), end.get_pos()) 118 | 119 | open_set_hash = {start} 120 | 121 | while not open_set.empty(): 122 | for event in pygame.event.get(): 123 | if event.type == pygame.QUIT: 124 | pygame.quit() 125 | 126 | current = open_set.get()[2] 127 | open_set_hash.remove(current) 128 | 129 | if current == end: 130 | reconstruct_path(came_from, end, draw) 131 | end.make_end() 132 | return True 133 | 134 | for neighbor in current.neighbors: 135 | temp_g_score = g_score[current] + 1 136 | 137 | if temp_g_score < g_score[neighbor]: 138 | came_from[neighbor] = current 139 | g_score[neighbor] = temp_g_score 140 | f_score[neighbor] = temp_g_score + \ 141 | h(neighbor.get_pos(), end.get_pos()) 142 | if neighbor not in open_set_hash: 143 | count += 1 144 | open_set.put((f_score[neighbor], count, neighbor)) 145 | open_set_hash.add(neighbor) 146 | neighbor.make_open() 147 | 148 | draw() 149 | 150 | if current != start: 151 | current.make_closed() 152 | 153 | return False 154 | 155 | 156 | def make_grid(rows, width): 157 | grid = [] 158 | gap = width // rows 159 | for i in range(rows): 160 | grid.append([]) 161 | for j in range(rows): 162 | node = Node(i, j, gap, rows) 163 | grid[i].append(node) 164 | 165 | return grid 166 | 167 | 168 | def draw_grid(win, rows, width): 169 | gap = width // rows 170 | for i in range(rows): 171 | pygame.draw.line(win, GREY, (0, i * gap), (width, i * gap)) 172 | for j in range(rows): 173 | pygame.draw.line(win, GREY, (j * gap, 0), (j * gap, width)) 174 | 175 | 176 | def draw(win, grid, rows, width): 177 | win.fill(WHITE) 178 | 179 | for row in grid: 180 | for node in row: 181 | node.draw(win) 182 | 183 | draw_grid(win, rows, width) 184 | pygame.display.update() 185 | 186 | 187 | def get_clicked_pos(pos, rows, width): 188 | gap = width // rows 189 | y, x = pos 190 | 191 | row = y // gap 192 | col = x // gap 193 | 194 | return row, col 195 | 196 | 197 | def main(win, width): 198 | ROWS = 50 199 | grid = make_grid(ROWS, width) 200 | 201 | start = None 202 | end = None 203 | 204 | run = True 205 | while run: 206 | draw(win, grid, ROWS, width) 207 | for event in pygame.event.get(): 208 | if event.type == pygame.QUIT: 209 | run = False 210 | 211 | if pygame.mouse.get_pressed()[0]: 212 | pos = pygame.mouse.get_pos() 213 | row, col = get_clicked_pos(pos, ROWS, width) 214 | node = grid[row][col] 215 | if not start and node != end: 216 | start = node 217 | start.make_start() 218 | 219 | elif not end and node != start: 220 | end = node 221 | end.make_end() 222 | 223 | elif node != end and node != start: 224 | node.make_barrier() 225 | 226 | elif pygame.mouse.get_pressed()[2]: 227 | pos = pygame.mouse.get_pos() 228 | row, col = get_clicked_pos(pos, ROWS, width) 229 | node = grid[row][col] 230 | node.reset() 231 | if node == start: 232 | start = None 233 | elif node == end: 234 | end = None 235 | 236 | if event.type == pygame.KEYDOWN: 237 | if event.key == pygame.K_SPACE and start and end: 238 | for row in grid: 239 | for node in row: 240 | node.update_neighbors(grid) 241 | 242 | algorithm(lambda: draw(win, grid, ROWS, width), 243 | grid, start, end) 244 | 245 | if event.key == pygame.K_c: 246 | start = None 247 | end = None 248 | grid = make_grid(ROWS, width) 249 | 250 | pygame.quit() 251 | 252 | 253 | main(WIN, WIDTH) 254 | -------------------------------------------------------------------------------- /Path-Finding-Visualizer/img.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Path-Finding-Visualizer/img.jpg -------------------------------------------------------------------------------- /Pong/Pong.py: -------------------------------------------------------------------------------- 1 | # Simple Pong game 2 | 3 | import turtle # Basic Graphics module 4 | import winsound # For Sound 5 | 6 | wn = turtle.Screen() 7 | wn.title("Pong by K G Prajwal") # Window title 8 | wn.bgcolor("black") # Window background 9 | wn.setup(width=800, height=600) # Window size 10 | wn.tracer(0) # Stops window from updating - Speedup 11 | 12 | # Scoreboard 13 | score_a = 0 14 | score_b = 0 15 | 16 | # Paddle A 17 | paddle_a = turtle.Turtle() 18 | paddle_a.speed(0) # Speed of animation 19 | paddle_a.shape("square") # Set shape as square (default 20x20) 20 | paddle_a.color("white") # Set the color 21 | # Make the square into rectangle 22 | paddle_a.shapesize(stretch_wid=5, stretch_len=1) 23 | paddle_a.penup() # Don't draw continously 24 | paddle_a.goto(-350, 0) # Paddle a starts at 350, left of screen 25 | 26 | # Paddle B 27 | paddle_b = turtle.Turtle() 28 | paddle_b.speed(0) 29 | paddle_b.shape("square") 30 | paddle_b.color("white") 31 | paddle_b.shapesize(stretch_wid=5, stretch_len=1) 32 | paddle_b.penup() 33 | paddle_b.goto(350, 0) # Paddle a starts at 350, right of screen 34 | 35 | 36 | # Ball 37 | ball = turtle.Turtle() 38 | ball.speed(0) 39 | ball.shape("square") 40 | ball.color("white") 41 | ball.penup() 42 | ball.goto(0, 0) 43 | ball.dx = 0.5 44 | ball.dy = 0.5 45 | 46 | # Pen - Scoreboard 47 | pen = turtle.Turtle() 48 | pen.speed(0) 49 | pen.color('white') 50 | pen.penup() 51 | pen.hideturtle() 52 | pen.goto(0, 260) 53 | pen.write("Player A: 0 Player B: 0", align="center", 54 | font=("Courier", 24, "normal")) 55 | 56 | 57 | # Functionality 58 | def paddle_a_up(): 59 | y = paddle_a.ycor() # .ycor() return y coordinate 60 | y += 20 # Move up 61 | paddle_a.sety(y) 62 | 63 | 64 | def paddle_a_down(): 65 | y = paddle_a.ycor() 66 | y -= 20 # Move down 67 | paddle_a.sety(y) 68 | 69 | 70 | def paddle_b_up(): 71 | y = paddle_b.ycor() 72 | y += 20 73 | paddle_b.sety(y) 74 | 75 | 76 | def paddle_b_down(): 77 | y = paddle_b.ycor() 78 | y -= 20 79 | paddle_b.sety(y) 80 | 81 | 82 | # Keyboard binding 83 | wn.listen() 84 | wn.onkeypress(paddle_a_up, "w") 85 | wn.onkeypress(paddle_a_down, "s") 86 | wn.onkeypress(paddle_b_up, "Up") 87 | wn.onkeypress(paddle_b_down, "Down") 88 | 89 | 90 | # Main game loop 91 | while True: 92 | wn.update() # Update screen everytime loop runs 93 | 94 | # Move the ball 95 | ball.setx(ball.xcor() + ball.dx) 96 | ball.sety(ball.ycor() + ball.dy) 97 | 98 | # Top & Bottom Border 99 | if ball.ycor() > 290: 100 | ball.sety(290) 101 | ball.dy *= -1 # Reverse the direction of ball 102 | winsound.PlaySound("bounce.wav", winsound.SND_ASYNC) 103 | 104 | if ball.ycor() < -290: 105 | ball.sety(-290) 106 | ball.dy *= -1 107 | winsound.PlaySound("bounce.wav", winsound.SND_ASYNC) 108 | 109 | # Left & Right Border 110 | if ball.xcor() > 390: 111 | score_a += 1 112 | pen.clear() 113 | pen.write("Player A: {} Player B: {}".format(score_a, score_b), align="center", 114 | font=("Courier", 24, "normal")) # Update score 115 | ball.goto(0, 0) 116 | ball.dx *= -1 117 | 118 | if ball.xcor() < -390: 119 | score_b += 1 120 | pen.clear() 121 | pen.write("Player A: {} Player B: {}".format(score_a, score_b), align="center", 122 | font=("Courier", 24, "normal")) 123 | ball.goto(0, 0) 124 | ball.dx *= -1 125 | 126 | # Bounce of the paddle 127 | if (ball.xcor() > 340 and ball.xcor() < 350) and (ball.ycor() < paddle_b.ycor() + 40 and ball.ycor() > paddle_b.ycor() - 50): 128 | ball.setx(340) 129 | ball.dx *= -1 130 | winsound.PlaySound("bounce.wav", winsound.SND_ASYNC) 131 | 132 | if (ball.xcor() < -340 and ball.xcor() > -350) and (ball.ycor() < paddle_a.ycor() + 40 and ball.ycor() > paddle_a.ycor() - 50): 133 | ball.setx(-340) 134 | ball.dx *= -1 135 | winsound.PlaySound("bounce.wav", winsound.SND_ASYNC) 136 | -------------------------------------------------------------------------------- /Pong/README.md: -------------------------------------------------------------------------------- 1 | # PONG 2 | 3 | A simple Pong game created from the [Turtle](https://docs.python.org/3/library/turtle.html) module in python. The game consists of two players trying to bounce off a ball approaching towards their paddle. Upon missing the ball the opponent scores a point. 4 | -------------------------------------------------------------------------------- /Pong/bounce.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Pong/bounce.wav -------------------------------------------------------------------------------- /Random Movie Generator/.gitignore: -------------------------------------------------------------------------------- 1 | /venv -------------------------------------------------------------------------------- /Random Movie Generator/README.md: -------------------------------------------------------------------------------- 1 | # Random Movie Generator 2 | 3 | 4 | Bored? Don't know what to watch? 5 | 6 | Just run this python script using `python script.py`. This script selects and displays a random movie from the IMDB's top 250 movies. -------------------------------------------------------------------------------- /Random Movie Generator/requirements.txt: -------------------------------------------------------------------------------- 1 | IMDbPY==2020.9.25 2 | lxml==4.6.5 3 | SQLAlchemy==1.3.19 4 | -------------------------------------------------------------------------------- /Random Movie Generator/script.py: -------------------------------------------------------------------------------- 1 | from imdb import IMDb 2 | import random 3 | 4 | 5 | class ChooseMovie(object): 6 | def __init__(self): 7 | self.cursor = IMDb() 8 | self.top250 = self.cursor.get_top250_movies() 9 | 10 | def __repr__(self): 11 | num = int(random.randint(0, 249)) 12 | return str(f"{num}: {self.top250[num]}") 13 | 14 | 15 | if __name__ == '__main__': 16 | print(ChooseMovie()) 17 | -------------------------------------------------------------------------------- /Sorting Visualizer/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore VScode settings 2 | .vscode 3 | 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | share/python-wheels/ 27 | *.egg-info/ 28 | .installed.cfg 29 | *.egg 30 | MANIFEST 31 | 32 | # PyInstaller 33 | # Usually these files are written by a python script from a template 34 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 35 | *.manifest 36 | *.spec 37 | 38 | # Installer logs 39 | pip-log.txt 40 | pip-delete-this-directory.txt 41 | 42 | # Unit test / coverage reports 43 | htmlcov/ 44 | .tox/ 45 | .nox/ 46 | .coverage 47 | .coverage.* 48 | .cache 49 | nosetests.xml 50 | coverage.xml 51 | *.cover 52 | *.py,cover 53 | .hypothesis/ 54 | .pytest_cache/ 55 | cover/ 56 | 57 | # Translations 58 | *.mo 59 | *.pot 60 | 61 | # Django stuff: 62 | *.log 63 | local_settings.py 64 | db.sqlite3 65 | db.sqlite3-journal 66 | 67 | # Flask stuff: 68 | instance/ 69 | .webassets-cache 70 | 71 | # Scrapy stuff: 72 | .scrapy 73 | 74 | # Sphinx documentation 75 | docs/_build/ 76 | 77 | # PyBuilder 78 | .pybuilder/ 79 | target/ 80 | 81 | # Jupyter Notebook 82 | .ipynb_checkpoints 83 | 84 | # IPython 85 | profile_default/ 86 | ipython_config.py 87 | 88 | # pyenv 89 | # For a library or package, you might want to ignore these files since the code is 90 | # intended to run in multiple environments; otherwise, check them in: 91 | # .python-version 92 | 93 | # pipenv 94 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 95 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 96 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 97 | # install all needed dependencies. 98 | #Pipfile.lock 99 | 100 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 101 | __pypackages__/ 102 | 103 | # Celery stuff 104 | celerybeat-schedule 105 | celerybeat.pid 106 | 107 | # SageMath parsed files 108 | *.sage.py 109 | 110 | # Environments 111 | .env 112 | .venv 113 | env/ 114 | venv/ 115 | ENV/ 116 | env.bak/ 117 | venv.bak/ 118 | 119 | # Spyder project settings 120 | .spyderproject 121 | .spyproject 122 | 123 | # Rope project settings 124 | .ropeproject 125 | 126 | # mkdocs documentation 127 | /site 128 | 129 | # mypy 130 | .mypy_cache/ 131 | .dmypy.json 132 | dmypy.json 133 | 134 | # Pyre type checker 135 | .pyre/ 136 | 137 | # pytype static type analyzer 138 | .pytype/ 139 | 140 | # Cython debug symbols 141 | cython_debug/ -------------------------------------------------------------------------------- /Sorting Visualizer/algorithms.py: -------------------------------------------------------------------------------- 1 | import time 2 | import random 3 | from abc import ABCMeta, abstractmethod 4 | 5 | class Algorithm(metaclass=ABCMeta): 6 | def __init__(self, name): 7 | self.array = random.sample(range(512), 512) # Random array of size 512 8 | self.name = name # Get name of the variable 9 | 10 | def update_display(self, swap1=None, swap2=None): 11 | import visualizer 12 | visualizer.update(self, swap1, swap2) # pass the indexes to be swapped into the visualizer 13 | 14 | def run(self): # Start the timer and run the algorithm 15 | self.start_time = time.time() 16 | self.algorithm() 17 | time_elapsed = time.time() - self.start_time 18 | return self.array, time_elapsed 19 | 20 | @abstractmethod 21 | def algorithm(self): 22 | raise TypeError(f"Algorithm.algorithm() has not been overwritten.") 23 | 24 | 25 | class SelectionSort(Algorithm): 26 | def __init__(self): 27 | super().__init__("SelectionSort") 28 | 29 | def algorithm(self): 30 | for i in range(len(self.array)): 31 | min_idx = i 32 | for j in range(i+1, len(self.array)): 33 | if self.array[j] < self.array[min_idx]: 34 | min_idx = j 35 | self.array[i], self.array[min_idx] = self.array[min_idx], self.array[i] 36 | self.update_display(self.array[i], self.array[min_idx]) 37 | 38 | 39 | class BubbleSort(Algorithm): 40 | def __init__(self): 41 | super().__init__("BubbleSort") 42 | 43 | def algorithm(self): 44 | for i in range(len(self.array)): 45 | for j in range(len(self.array)-1-i): 46 | if self.array[j] > self.array[j+1]: 47 | self.array[j], self.array[j+1] = self.array[j+1], self.array[j] 48 | self.update_display(self.array[j], self.array[j+1]) 49 | 50 | 51 | class InsertionSort(Algorithm): 52 | def __init__(self): 53 | super().__init__("InsertionSort") 54 | 55 | def algorithm(self): 56 | for i in range(len(self.array)): 57 | cursor = self.array[i] 58 | idx = i 59 | while idx > 0 and self.array[idx-1] > cursor: 60 | self.array[idx] = self.array[idx-1] 61 | idx -= 1 62 | self.array[idx] = cursor 63 | self.update_display(self.array[idx], self.array[i]) 64 | 65 | 66 | class MergeSort(Algorithm): 67 | def __init__(self): 68 | super().__init__("MergeSort") 69 | 70 | def algorithm(self, array=[]): 71 | if array == []: 72 | array = self.array 73 | if len(array) < 2: 74 | return array 75 | mid = len(array) // 2 76 | left = self.algorithm(array[:mid]) 77 | right = self.algorithm(array[mid:]) 78 | return self.merge(left, right) 79 | 80 | def merge(self, left, right): 81 | result = [] 82 | i, j = 0, 0 83 | while i < len(left) and j < len(right): 84 | if left[i] < right[j]: 85 | result.append(left[i]) 86 | i += 1 87 | else: 88 | result.append(right[j]) 89 | j += 1 90 | self.update_display() 91 | result += left[i:] 92 | result += right[j:] 93 | self.array = result 94 | self.update_display() 95 | return result 96 | 97 | class QuickSort(Algorithm): 98 | def __init__(self): 99 | super().__init__("QuickSort") 100 | 101 | def algorithm(self, array=[], start=0, end=0): 102 | if array == []: 103 | array = self.array 104 | end = len(array) - 1 105 | if start < end: 106 | pivot = self.partition(array,start,end) 107 | self.algorithm(array,start,pivot-1) 108 | self.algorithm(array,pivot+1,end) 109 | 110 | def partition(self, array, start, end): 111 | x = array[end] 112 | i = start-1 113 | for j in range(start, end+1, 1): 114 | if array[j] <= x: 115 | i += 1 116 | if i < j: 117 | array[i], array[j] = array[j], array[i] 118 | self.update_display(array[i], array[j]) 119 | return i 120 | 121 | -------------------------------------------------------------------------------- /Sorting Visualizer/visualizer.py: -------------------------------------------------------------------------------- 1 | import algorithms 2 | import time 3 | import os 4 | import sys 5 | import pygame as pg 6 | 7 | # Set the window length and breadth 8 | # (Make sure that the breadth is equal to size of array. [512]) 9 | dimensions = (1024, 512) 10 | # List all the algorithms available in the project in dictionary and call the 11 | # necessary functions from algorithms.py 12 | algorithms = {"SelectionSort": algorithms.SelectionSort(), "BubbleSort": algorithms.BubbleSort(), "InsertionSort": algorithms.InsertionSort(), "MergeSort": algorithms.MergeSort(), "QuickSort": algorithms.QuickSort()} 13 | 14 | # Set the dimensions of the window and display it 15 | display = pg.display.set_mode(dimensions) 16 | # Fill the window with purple hue 17 | display.fill(pg.Color("#a48be0")) 18 | 19 | def check_events(): # Check if the pg window was quit 20 | for event in pg.event.get(): 21 | if event.type == pg.QUIT: 22 | pg.quit() 23 | sys.exit() 24 | 25 | 26 | def update(algorithm, swap1=None, swap2=None, display=display): 27 | # The function responsible for drawing the sorted array on each iteration 28 | display.fill(pg.Color("#a48be0")) 29 | pg.display.set_caption("Sorting Visualizer Algorithm: {} Time: {:.3f} Status: Sorting...".format(algorithm.name, time.time() - algorithm.start_time)) # Display on title bar 30 | k = int(dimensions[0]/len(algorithm.array)) 31 | for i in range(len(algorithm.array)): 32 | colour = (80, 0, 255) 33 | if swap1 == algorithm.array[i]: 34 | colour = (0,255,0) 35 | elif swap2 == algorithm.array[i]: 36 | colour = (255,0,0) 37 | # The most important step that renders the rectangles to the screen that gets sorted. 38 | # pg.draw.rect(dsiplay_window, color_of_rectangle, size_of_rectangle) 39 | pg.draw.rect(display, colour, (i*k,dimensions[1],k,-algorithm.array[i])) 40 | check_events() 41 | pg.display.update() 42 | 43 | def keep_open(algorithm, display, time): # Keep the window open until sort completion 44 | pg.display.set_caption("Sorting Visualizer Algorithm: {} Time: {:.3f} Status: Done!".format(algorithm.name, time)) 45 | while True: 46 | check_events() 47 | 48 | def main(args): 49 | # Case: user failed to choose an algorithm 50 | if len(args) < 2: 51 | print("Please select a sorting algorithm.") 52 | # Case: user requests list of algorithms 53 | elif args[1] == "list": 54 | print("Available algorithms:\n\t" + "\n\t".join(algorithms.keys())) 55 | sys.exit(0) 56 | # Case: user selected an algorithm 57 | else: 58 | try: 59 | algorithm = algorithms[args[1]] # Collect algorithm 60 | _, time_elapsed = algorithm.run() # Run algorithm and time it 61 | keep_open(algorithm, display, time_elapsed) # Display results 62 | except: 63 | print("Error.") 64 | 65 | if __name__ == "__main__": 66 | sys.argv.append("BubbleSort") 67 | main(sys.argv) 68 | -------------------------------------------------------------------------------- /Steganography/Front_end/__pycache__/gui.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Steganography/Front_end/__pycache__/gui.cpython-36.pyc -------------------------------------------------------------------------------- /Steganography/Front_end/__pycache__/gui.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Steganography/Front_end/__pycache__/gui.cpython-37.pyc -------------------------------------------------------------------------------- /Steganography/Front_end/gui.py: -------------------------------------------------------------------------------- 1 | # import openpyxl and tkinter modules 2 | import tkinter as tk 3 | from tkinter import messagebox 4 | from tkinter.filedialog import askopenfilename 5 | import os, sys, subprocess 6 | 7 | from LSB.Text_in_audio import tialcode as tial 8 | from LSB.Image_in_audio import iialcode as iial 9 | from LSB.Audio_in_audio import aialcode as aial 10 | 11 | # globally declare variable 12 | dir_path = os.path.dirname(os.path.realpath(__file__)) 13 | 14 | class GUI: 15 | 16 | def xor_strings(self, s): 17 | return "/".join(str(ord(a)^ord(b)) for a,b in zip(s,self.hash)) 18 | 19 | def __init__(self): 20 | 21 | self.root = tk.Tk() 22 | 23 | self.Carrier_Selection = "Audio" 24 | self.Carrier_Location = None 25 | self.Data_Selection = "Text" 26 | self.Data_Location = None 27 | self.Algo_Selection = "LSB" 28 | self.string_var_carrier = tk.StringVar(master=self.root) 29 | self.string_var_data = tk.StringVar(master=self.root) 30 | self.string_var_algo = tk.StringVar(master=self.root) 31 | self.string_btn_password = tk.StringVar(master=self.root) 32 | self.hash = "GBY7G7GY78HG8HNG8TJI9G3H9" 33 | 34 | # set the background colour of GUI window 35 | self.root.configure(background='#ffc0cb') 36 | 37 | # set the title of GUI window 38 | self.root.title("Steganographic Transcoder") 39 | 40 | # set the configuration of GUI window 41 | self.root.geometry("520x350") 42 | 43 | #Header row 44 | self.tk_Heading = tk.Label(self.root, font=("Comic Sans MS", 30), text="Tunnel Vision", bg="#ffc0cb") 45 | self.tk_Heading.grid(row=0, column=2, columnspan=2, sticky=tk.W+tk.E) 46 | 47 | #Carrier row 48 | self.tk_Carrier_Text = tk.Label(self.root, font=("Comic Sans MS", 25), text="Carrier:", bg="#ffc0cb") 49 | self.tk_Audio_Carrier = tk.Radiobutton ( self.root, font=("Comic Sans MS", 13), text="Audio", bg="#ffc0cb", variable=self.string_var_carrier, value="Audio", command=self.carrier_select, padx=20) 50 | self.tk_Carrier_File_Text = tk.Label(self.root, font=("Comic Sans MS", 15), text="Carrier Path:", bg="#ffc0cb") 51 | self.tk_Carrier_File_Loc_Text = tk.Text(self.root,font="25", bg="white", width=30, height=1) 52 | self.tk_Carrier_File_Button = tk.Button(self.root, font=("Comic Sans MS", 10), text="Open file", bg="#da80b1", command=self.open_carrier_file) 53 | 54 | self.tk_Carrier_Text.grid(row=1, column=1, sticky=tk.W) 55 | self.tk_Audio_Carrier.grid(row=1, column=3) 56 | self.tk_Carrier_File_Text.grid(row=2, column=1, sticky=tk.W) 57 | self.tk_Carrier_File_Loc_Text.grid(row=2, column=2, columnspan=2) 58 | self.tk_Carrier_File_Button.grid(row=2, column=4, rowspan=1, pady=10) 59 | 60 | #Data row 61 | self.tk_Data_Text = tk.Label(self.root, font=("Comic Sans MS", 25), text="Data:", bg="#ffc0cb") 62 | self.tk_Text_Data = tk.Radiobutton ( self.root, font=("Comic Sans MS", 13), text="Text", bg="#ffc0cb", variable=self.string_var_data, value="Text", command=self.data_select, padx=20) 63 | self.tk_Image_Data = tk.Radiobutton ( self.root, font=("Comic Sans MS", 13), text="Image", bg="#ffc0cb", variable=self.string_var_data, value="Image", command=self.data_select, padx=20) 64 | self.tk_Audio_Data = tk.Radiobutton ( self.root, font=("Comic Sans MS", 13), text="Audio", bg="#ffc0cb", variable=self.string_var_data, value="Audio", command=self.data_select, padx=20) 65 | self.tk_Data_File_Text = tk.Label(self.root, font=("Comic Sans MS", 15), text="Data Path:", bg="#ffc0cb") 66 | self.tk_Data_File_Loc_Text = tk.Text(self.root,font="25", bg="white", width=30, height=1) 67 | self.tk_Data_File_Button = tk.Button(self.root, font=("Comic Sans MS", 10), text="Open file", bg="#da80b1", command=self.open_data_file) 68 | 69 | self.tk_Data_Text.grid(row=3, column=1, sticky=tk.W) 70 | self.tk_Text_Data.grid(row=3, column=2) 71 | self.tk_Image_Data.grid(row=3, column=3) 72 | self.tk_Audio_Data.grid(row=3, column=4) 73 | self.tk_Data_File_Text.grid(row=4, column=1, sticky=tk.W) 74 | self.tk_Data_File_Loc_Text.grid(row=4, column=2, columnspan=2) 75 | self.tk_Data_File_Button.grid(row=4, column=4, rowspan=1, pady=10) 76 | 77 | #Algorithm row 78 | self.tk_Algo_Text = tk.Label(self.root, font="25", text="Algorithm:", bg="#ffc0cb") 79 | self.tk_Text_Algo = tk.Radiobutton ( self.root, font="25", text="LSB", bg="#ffc0cb", variable=self.string_var_algo, value="LSB", command=self.algo_select, padx=20) 80 | 81 | #Encode/Decode row: 82 | self.tk_Encode_Button = tk.Button(self.root, font=("Comic Sans MS", 10), text="Encode", bg="#da80b1", command=self.get_password_check_en) 83 | self.tk_Decode_Button = tk.Button(self.root, font=("Comic Sans MS", 10), text="Decode", bg="#da80b1", command=self.get_password_check_de) 84 | 85 | 86 | self.tk_Encode_Button.grid(row=6, column=2) 87 | self.tk_Decode_Button.grid(row=6, column=3) 88 | 89 | self.tk_main_password_btn = tk.Button(self.root, font=("Comic Sans MS", 10), textvariable=self.string_btn_password, bg="#da80b1",command=lambda: self.get_password_dialog("change password")) 90 | self.tk_main_password_btn.grid(row=7,column=2,columnspan=2,rowspan=1, pady=10, sticky=tk.W+tk.E) 91 | 92 | self.tk_Audio_Carrier.select() 93 | self.tk_Text_Data.select() 94 | self.tk_Image_Data.deselect() 95 | self.tk_Audio_Data.deselect() 96 | self.tk_Text_Algo.select() 97 | 98 | def carrier_select(self): 99 | self.Carrier_Selection = str(self.string_var_carrier.get()) 100 | print(self.Carrier_Selection) 101 | if(self.Carrier_Selection=="Audio"): 102 | self.tk_Audio_Carrier.select() 103 | 104 | def open_carrier_file(self): 105 | if self.Carrier_Selection=="Audio": 106 | self.Carrier_Location = askopenfilename(initialdir = dir_path,title = "Save file as",filetypes = (("WAV files","*.wav"),("all files","*.*"))) 107 | self.tk_Carrier_File_Loc_Text.insert(tk.INSERT, self.Carrier_Location) 108 | 109 | def data_select(self): 110 | self.Data_Selection = str(self.string_var_data.get()) 111 | print(self.Data_Selection) 112 | if self.Data_Selection=="Text": 113 | self.tk_Text_Data.select() 114 | self.tk_Image_Data.deselect() 115 | self.tk_Audio_Data.deselect() 116 | elif self.Data_Selection=="Image": 117 | self.tk_Text_Data.deselect() 118 | self.tk_Image_Data.select() 119 | self.tk_Audio_Data.deselect() 120 | else: 121 | self.tk_Text_Data.deselect() 122 | self.tk_Image_Data.deselect() 123 | self.tk_Audio_Data.select() 124 | 125 | def open_data_file(self): 126 | if self.Data_Selection == "Audio": 127 | self.Data_Location = askopenfilename(initialdir = dir_path,title = "Save file as",filetypes = (("WAV files","*.wav"),("all files","*.*"))) 128 | elif self.Data_Selection == "Image": 129 | self.Data_Location = askopenfilename(initialdir = dir_path,title = "Save file as",filetypes = (("PNG files","*.png"),("all files","*.*"))) 130 | else: 131 | pass 132 | self.tk_Data_File_Loc_Text.insert(tk.INSERT, self.Data_Location) 133 | 134 | def algo_select(self): 135 | self.Algo_Selection = str(self.string_var_algo.get()) 136 | print(self.Algo_Selection) 137 | if self.Algo_Selection=="LSB": 138 | self.tk_Text_Algo.select() 139 | 140 | def encode(self): 141 | if self.Carrier_Selection=="Audio" and self.Data_Selection=="Text" and self.Algo_Selection=="LSB": 142 | print("Inside Encode(): Audio:Text:LSB") 143 | self.Data_Location = self.tk_Data_File_Loc_Text.get("1.0", tk.END) 144 | a1 = tial.Text_in_audio_lsb(self.Carrier_Location, self.Data_Location) 145 | a1.encode() 146 | elif self.Carrier_Selection=="Audio" and self.Data_Selection=="Image" and self.Algo_Selection=="LSB": 147 | print("Inside Encode(): Audio:Image:LSB") 148 | a1 = iial.Image_in_audio_lsb(self.Carrier_Location, self.Data_Location) 149 | a1.encode() 150 | elif self.Carrier_Selection=="Audio" and self.Data_Selection=="Audio" and self.Algo_Selection=="LSB": 151 | print("Inside Encode(): Audio:Audio:LSB") 152 | a1 = aial.Audio_in_audio_lsb(self.Carrier_Location, self.Data_Location) 153 | a1.encode() 154 | 155 | def decode(self): 156 | if self.Carrier_Selection=="Audio" and self.Data_Selection=="Text" and self.Algo_Selection=="LSB": 157 | print("Inside Decode(): Audio:Text:LSB") 158 | a1 = tial.Text_in_audio_lsb("","") 159 | self.print_text_box(a1.decode(self.Carrier_Location)) 160 | elif self.Carrier_Selection=="Audio" and self.Data_Selection=="Image" and self.Algo_Selection=="LSB": 161 | print("Inside Decode(): Audio:Image:LSB") 162 | a1 = iial.Image_in_audio_lsb("","") 163 | a1.decode(self.Carrier_Location) 164 | elif self.Carrier_Selection=="Audio" and self.Data_Selection=="Audio" and self.Algo_Selection=="LSB": 165 | print("Inside Decode(): Audio:Audio:LSB") 166 | a1 = aial.Audio_in_audio_lsb("","") 167 | a1.decode(self.Carrier_Location) 168 | 169 | def print_text_box(self, string): 170 | self.top = tk.Toplevel(bg="#ffc0cb") 171 | self.top.title("Decoded text") 172 | self.top.geometry("275x175") 173 | self.tk_toplevel_text = tk.Text(self.top ,font="25", bg="white", width=25, height=7) 174 | self.tk_toplevel_text.grid(row=0, column=0) 175 | self.tk_toplevel_text.insert(tk.INSERT, string) 176 | self.top.mainloop() 177 | 178 | def check_saved_password(self): 179 | if os.path.exists("config.dat"): 180 | self.string_btn_password.set("Change password") 181 | with open("config.dat", "r") as myFile: 182 | self.saved_hash = myFile.read().split("\n")[0] 183 | return True 184 | else: 185 | self.string_btn_password.set("Enter password") 186 | self.saved_hash = None 187 | return False 188 | 189 | def save_password_dialog(self): 190 | 191 | self.top_password = tk.Toplevel(bg="#ffc0cb") 192 | self.top_password.title("Password") 193 | self.top_password.geometry("500x150") 194 | 195 | self.top_password_heading = tk.Label(self.top_password, bg = "#ffc0cb", font="35", text="Save a password to use this tool") 196 | self.top_password_heading.grid(row=0, column=1) 197 | 198 | self.top_password_label = tk.Label(self.top_password, bg="#ffc0cb", font="25", text="Enter password:") 199 | self.top_password_text = tk.Text(self.top_password , font="25", bg="white", width=25, height=1) 200 | 201 | self.top_password_label.grid(row=1, column=0) 202 | self.top_password_text.grid(row=1, column=1) 203 | 204 | self.top_retype_label = tk.Label(self.top_password,bg="#ffc0cb", font="25", text="Re-type password", pady=10) 205 | self.top_retype_text = tk.Text(self.top_password, font="25", bg="white", width=25, height=1) 206 | self.top_pass_submit_btn = tk.Button(self.top_password, font="25", bg="white", text="Submit", command=self.save_password_check) 207 | 208 | self.top_retype_label.grid(row=2, column=0) 209 | self.top_retype_text.grid(row=2, column=1) 210 | self.top_pass_submit_btn.grid(row=3, column=1) 211 | 212 | self.top_password.mainloop() 213 | 214 | def save_password_check(self): 215 | password = self.top_password_text.get("1.0", tk.END).split("\n")[0] 216 | retype = self.top_retype_text.get("1.0", tk.END).split("\n")[0] 217 | if password == retype: 218 | file = open('config.dat','w') 219 | file.write(self.xor_strings(password)) 220 | file.close() 221 | self.check_saved_password() 222 | self.top_password.destroy() 223 | 224 | def get_password_dialog(self, type): 225 | 226 | if self.check_saved_password() == False: 227 | self.save_password_dialog() 228 | return 229 | 230 | self.top_password = tk.Toplevel(bg="#ffc0cb") 231 | self.top_password.title("Password") 232 | self.top_password.geometry("500x150") 233 | 234 | self.top_password_label = tk.Label(self.top_password, bg="#ffc0cb", font="25", text="Enter password:") 235 | self.top_password_text = tk.Text(self.top_password , font="25", bg="white", width=25, height=1) 236 | 237 | self.top_password_label.grid(row=1, column=0) 238 | self.top_password_text.grid(row=1, column=1) 239 | 240 | self.top_pass_submit_btn = tk.Button(self.top_password, font="25", bg="white", text="Submit", command=lambda: self.get_password_check(type)) 241 | self.top_pass_submit_btn.grid(row=3, column=1) 242 | 243 | self.top_password.mainloop() 244 | 245 | def get_password_check(self, type): 246 | password = self.top_password_text.get("1.0", tk.END).split("\n")[0] 247 | with open("config.dat", "r") as myFile: 248 | saved_hash = myFile.read().split("\n")[0] 249 | 250 | print(self.xor_strings(password), saved_hash) 251 | print(self.xor_strings(password) == saved_hash) 252 | 253 | if self.xor_strings(password) == saved_hash: 254 | self.top_password.destroy() 255 | if type=="encode": 256 | self.encode() 257 | elif type=="decode": 258 | self.decode() 259 | else: 260 | self.save_password_dialog() 261 | self.top_password.destroy() 262 | 263 | def get_password_check_en(self): 264 | if self.check_saved_password(): 265 | self.get_password_dialog("encode") 266 | else: 267 | messagebox.showerror("Error", "You have not saved a password.") 268 | 269 | def get_password_check_de(self): 270 | if self.check_saved_password(): 271 | self.get_password_dialog("decode") 272 | else: 273 | messagebox.showerror("Error", "You have not saved a password.") 274 | 275 | def start_gui(self): 276 | 277 | self.check_saved_password() 278 | self.root.mainloop() -------------------------------------------------------------------------------- /Steganography/LSB/Audio_in_audio/__pycache__/aialcode.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Steganography/LSB/Audio_in_audio/__pycache__/aialcode.cpython-37.pyc -------------------------------------------------------------------------------- /Steganography/LSB/Audio_in_audio/aialcode.py: -------------------------------------------------------------------------------- 1 | # Wave module provides a convenient interface to the WAV sound format. 2 | import sys 3 | import wave, os 4 | import threading 5 | import numpy as np 6 | from tkinter import filedialog 7 | 8 | dir_path = os.path.dirname(os.path.realpath(__file__)) 9 | 10 | # np.set_printoptions(threshold=sys.maxsize) 11 | 12 | class Audio_in_audio_lsb: 13 | 14 | def __init__(self, carrier, data): 15 | self.carrier = carrier 16 | self.data = data 17 | 18 | def encode(self): 19 | # We will use wave package available in native Python installation to read and write .wav audio file 20 | # read wave audio file 21 | 22 | # Enter the filename and open it in read-binary mode 23 | song = wave.open(self.carrier, mode='rb') 24 | 25 | # Get number of frames 26 | # Read the frames from the input file 27 | # Convert into a list 28 | # Convert list into bytearray 29 | frame_bytes = bytearray(list(song.readframes(song.getnframes()))) 30 | 31 | # Get the secret message 32 | in_fname = self.data 33 | 34 | in_bytes = np.fromfile(in_fname, dtype = "uint8") 35 | in_bits = np.unpackbits(in_bytes) 36 | bits = list(in_bits) 37 | #print(in_bytes, "\n", in_bits) 38 | 39 | # Replace LSB of each byte of the audio data by one1 bit from the text bit array 40 | for i, bit in enumerate(bits): 41 | try: 42 | frame_bytes[i] = (frame_bytes[i] & 254) | bit 43 | except IndexError: 44 | pass 45 | 46 | # Get the modified bytes 47 | frame_modified = bytes(frame_bytes) 48 | 49 | # Write bytes to a new wave audio file 50 | with wave.open('song_embedded.wav', 'wb') as fd: 51 | fd.setparams(song.getparams()) 52 | fd.writeframes(frame_modified) 53 | song.close() 54 | 55 | def decode(self, path): 56 | # Use wave package (native to Python) for reading the received audio file 57 | # song = wave.open(filedialog.askopenfilename(initialdir = dir_path,title = "Open carrier file",filetypes = (("WAV files","*.wav"),("all files","*.*"))), mode='rb') 58 | song = wave.open(path, mode='rb') 59 | # Convert audio to byte array 60 | frame_bytes = bytearray(list(song.readframes(song.getnframes()))) 61 | 62 | # Extract the LSB of each byte 63 | extracted = [frame_bytes[i] & 1 for i in range(len(frame_bytes))] 64 | 65 | out_bits = np.array(extracted) 66 | out_bytes = np.packbits(out_bits) 67 | out_name = filedialog.asksaveasfilename(initialdir = "/",title = "Save file as",filetypes = (("WAV files","*.wav"),("all files","*.*")))+'.wav' 68 | out_bytes.tofile(out_name) 69 | os.startfile(out_name) 70 | 71 | print("Sucessfully decoded") 72 | song.close() 73 | -------------------------------------------------------------------------------- /Steganography/LSB/Image_in_audio/__pycache__/iialcode.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Steganography/LSB/Image_in_audio/__pycache__/iialcode.cpython-37.pyc -------------------------------------------------------------------------------- /Steganography/LSB/Image_in_audio/iialcode.py: -------------------------------------------------------------------------------- 1 | # Wave module provides a convenient interface to the WAV sound format. 2 | import sys 3 | import wave, os 4 | import threading 5 | import numpy as np 6 | from tkinter import filedialog 7 | 8 | dir_path = os.path.dirname(os.path.realpath(__file__)) 9 | 10 | # np.set_printoptions(threshold=sys.maxsize) 11 | 12 | class Image_in_audio_lsb: 13 | 14 | def __init__(self, carrier, data): 15 | self.carrier = carrier 16 | self.data = data 17 | 18 | def encode(self): 19 | # We will use wave package available in native Python installation to read and write .wav audio file 20 | # read wave audio file 21 | 22 | # Enter the filename and open it in read-binary mode 23 | song = wave.open(self.carrier, mode='rb') 24 | 25 | # Get number of frames 26 | # Read the frames from the input file 27 | # Convert into a list 28 | # Convert list into bytearray 29 | frame_bytes = bytearray(list(song.readframes(song.getnframes()))) 30 | 31 | # Get the secret message 32 | in_fname = self.data 33 | 34 | in_bytes = np.fromfile(in_fname, dtype = "uint8") 35 | in_bits = np.unpackbits(in_bytes) 36 | bits = list(in_bits) 37 | #print(in_bytes, "\n", in_bits) 38 | 39 | # Replace LSB of each byte of the audio data by one1 bit from the text bit array 40 | for i, bit in enumerate(bits): 41 | try: 42 | frame_bytes[i] = (frame_bytes[i] & 254) | bit 43 | except IndexError: 44 | pass 45 | 46 | # Get the modified bytes 47 | frame_modified = bytes(frame_bytes) 48 | 49 | # Write bytes to a new wave audio file 50 | with wave.open('song_embedded.wav', 'wb') as fd: 51 | fd.setparams(song.getparams()) 52 | fd.writeframes(frame_modified) 53 | song.close() 54 | 55 | def decode(self, path): 56 | # Use wave package (native to Python) for reading the received audio file 57 | # song = wave.open(filedialog.askopenfilename(initialdir = dir_path,title = "Open carrier file",filetypes = (("WAV files","*.wav"),("all files","*.*"))), mode='rb') 58 | song = wave.open(path, mode='rb') 59 | # Convert audio to byte array 60 | frame_bytes = bytearray(list(song.readframes(song.getnframes()))) 61 | 62 | # Extract the LSB of each byte 63 | extracted = [frame_bytes[i] & 1 for i in range(len(frame_bytes))] 64 | 65 | out_bits = np.array(extracted) 66 | out_bytes = np.packbits(out_bits) 67 | out_name = filedialog.asksaveasfilename(initialdir = "/",title = "Save file as",filetypes = (("PNG files","*.png"),("all files","*.*")))+'.png' 68 | out_bytes.tofile(out_name) 69 | os.startfile(out_name) 70 | 71 | print("Sucessfully decoded") 72 | song.close() 73 | return out_name -------------------------------------------------------------------------------- /Steganography/LSB/Text_in_audio/__pycache__/tiacode.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Steganography/LSB/Text_in_audio/__pycache__/tiacode.cpython-37.pyc -------------------------------------------------------------------------------- /Steganography/LSB/Text_in_audio/__pycache__/tialcode.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Steganography/LSB/Text_in_audio/__pycache__/tialcode.cpython-37.pyc -------------------------------------------------------------------------------- /Steganography/LSB/Text_in_audio/tialcode.py: -------------------------------------------------------------------------------- 1 | # Wave module provides a convenient interface to the WAV sound format. 2 | import wave, os 3 | import threading 4 | from tkinter import filedialog 5 | 6 | dir_path = os.path.dirname(os.path.realpath(__file__)) 7 | 8 | class Text_in_audio_lsb: 9 | 10 | def __init__(self, carrier, data): 11 | self.carrier = carrier 12 | self.data = data 13 | 14 | def encode(self): 15 | # We will use wave package available in native Python installation to read and write .wav audio file 16 | # read wave audio file 17 | 18 | # Enter the filename and open it in read-binary mode 19 | song = wave.open(self.carrier, mode='rb') 20 | 21 | # Get number of frames 22 | # Read the frames from the input file 23 | # Convert into a list 24 | # Convert list into bytearray 25 | frame_bytes = bytearray(list(song.readframes(song.getnframes()))) 26 | 27 | # Get the secret message 28 | string = self.data 29 | 30 | # Append dummy data to fill out rest of the bytes. 31 | # Receiver shall detect and remove these characters. 32 | string = string + int((len(frame_bytes)-(len(string)*8*8))/8) *'#' 33 | 34 | # Convert text to bit array 35 | bits = list(map(int, ''.join([bin(ord(i)).lstrip('0b').rjust(8,'0') for i in string]))) 36 | 37 | # Replace LSB of each byte of the audio data by one bit from the text bit array 38 | for i, bit in enumerate(bits): 39 | frame_bytes[i] = (frame_bytes[i] & 254) | bit 40 | 41 | # Get the modified bytes 42 | frame_modified = bytes(frame_bytes) 43 | 44 | # Write bytes to a new wave audio file 45 | with wave.open('song_embedded.wav', 'wb') as fd: 46 | fd.setparams(song.getparams()) 47 | fd.writeframes(frame_modified) 48 | song.close() 49 | 50 | def decode(self, path): 51 | # Use wave package (native to Python) for reading the received audio file 52 | # song = wave.open(filedialog.askopenfilename(initialdir = dir_path,title = "Open carrier file",filetypes = (("WAV files","*.wav"),("all files","*.*"))), mode='rb') 53 | song = wave.open(path, mode='rb') 54 | # Convert audio to byte array 55 | frame_bytes = bytearray(list(song.readframes(song.getnframes()))) 56 | 57 | # Extract the LSB of each byte 58 | extracted = [frame_bytes[i] & 1 for i in range(len(frame_bytes))] 59 | 60 | # Convert byte array back to string 61 | string = "".join(chr(int("".join(map(str,extracted[i:i+8])),2)) for i in range(0,len(extracted),8)) 62 | 63 | # Cut off the filler characters 64 | decoded = string.split("###")[0] 65 | 66 | # Print the extracted text 67 | print("Sucessfully decoded: "+decoded) 68 | song.close() 69 | return decoded -------------------------------------------------------------------------------- /Steganography/__pycache__/imagepil.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Steganography/__pycache__/imagepil.cpython-36.pyc -------------------------------------------------------------------------------- /Steganography/__pycache__/main.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Steganography/__pycache__/main.cpython-36.pyc -------------------------------------------------------------------------------- /Steganography/config.dat: -------------------------------------------------------------------------------- 1 | 51/39/42/67 -------------------------------------------------------------------------------- /Steganography/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | from Front_end import gui 3 | 4 | if __name__ == "__main__": 5 | instance = gui.GUI() 6 | instance.start_gui() -------------------------------------------------------------------------------- /Steganography/res/carrierAudio.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Steganography/res/carrierAudio.wav -------------------------------------------------------------------------------- /Steganography/res/secretAudio.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Steganography/res/secretAudio.wav -------------------------------------------------------------------------------- /Steganography/res/secretImage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Steganography/res/secretImage.jpg -------------------------------------------------------------------------------- /Sudoku Solver/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 98 | __pypackages__/ 99 | 100 | # Celery stuff 101 | celerybeat-schedule 102 | celerybeat.pid 103 | 104 | # SageMath parsed files 105 | *.sage.py 106 | 107 | # Environments 108 | .env 109 | .venv 110 | env/ 111 | venv/ 112 | ENV/ 113 | env.bak/ 114 | venv.bak/ 115 | 116 | # Spyder project settings 117 | .spyderproject 118 | .spyproject 119 | 120 | # Rope project settings 121 | .ropeproject 122 | 123 | # mkdocs documentation 124 | /site 125 | 126 | # mypy 127 | .mypy_cache/ 128 | .dmypy.json 129 | dmypy.json 130 | 131 | # Pyre type checker 132 | .pyre/ 133 | 134 | # pytype static type analyzer 135 | .pytype/ 136 | 137 | # Cython debug symbols 138 | cython_debug/ -------------------------------------------------------------------------------- /Sudoku Solver/GUI.py: -------------------------------------------------------------------------------- 1 | # Pygame is a cross-platform set of Python modules designed for writing video games. 2 | # It includes computer graphics and sound libraries designed to be used with the Python programming language 3 | import pygame 4 | import time 5 | pygame.font.init() 6 | 7 | 8 | class Grid: 9 | board = [ 10 | [0, 7, 9, 1, 3, 2, 0, 8, 5], 11 | [0, 6, 0, 5, 9, 0, 7, 0, 0], 12 | [5, 0, 8, 7, 0, 0, 2, 1, 0], 13 | [0, 0, 0, 8, 0, 0, 9, 0, 0], 14 | [7, 0, 6, 3, 4, 0, 0, 0, 0], 15 | [8, 0, 1, 2, 0, 0, 4, 0, 3], 16 | [0, 8, 7, 0, 0, 0, 3, 0, 0], 17 | [9, 0, 3, 0, 0, 0, 5, 0, 8], 18 | [2, 5, 0, 0, 0, 0, 1, 9, 0] 19 | ] # Initial state of the board 20 | 21 | def __init__(self, rows, cols, width, height, win): 22 | self.rows = rows 23 | self.cols = cols 24 | self.cubes = [[Cube(self.board[i][j], i, j, width, height) for j in range(cols)] for i in range(rows)] 25 | self.width = width 26 | self.height = height 27 | self.model = None 28 | self.update_model() 29 | self.selected = None 30 | self.win = win 31 | 32 | def update_model(self): # Change the state of the board 33 | self.model = [[self.cubes[i][j].value for j in range(self.cols)] for i in range(self.rows)] 34 | 35 | def place(self, val): # Set the permanent value 36 | row, col = self.selected 37 | if self.cubes[row][col].value == 0: 38 | self.cubes[row][col].set(val) 39 | self.update_model() 40 | 41 | if valid(self.model, val, (row,col)) and self.solve(): 42 | return True 43 | else: 44 | self.cubes[row][col].set(0) 45 | self.cubes[row][col].set_temp(0) 46 | self.update_model() 47 | return False 48 | 49 | def sketch(self, val): # Set the temporary value 50 | row, col = self.selected 51 | self.cubes[row][col].set_temp(val) 52 | 53 | def draw(self): # Draw Grid Lines 54 | gap = self.width / 9 55 | for i in range(self.rows+1): 56 | if i % 3 == 0 and i != 0: 57 | thick = 4 58 | else: 59 | thick = 1 60 | pygame.draw.line(self.win, (0,0,0), (0, i*gap), (self.width, i*gap), thick) 61 | pygame.draw.line(self.win, (0, 0, 0), (i * gap, 0), (i * gap, self.height), thick) 62 | 63 | 64 | for i in range(self.rows): 65 | for j in range(self.cols): 66 | self.cubes[i][j].draw(self.win) # Draw Cubes 67 | 68 | def select(self, row, col): # Select the box that was clicked on 69 | for i in range(self.rows): 70 | for j in range(self.cols): 71 | self.cubes[i][j].selected = False 72 | 73 | self.cubes[row][col].selected = True 74 | self.selected = (row, col) 75 | 76 | def clear(self): # Remove or replace the entered number in the box 77 | row, col = self.selected 78 | if self.cubes[row][col].value == 0: 79 | self.cubes[row][col].set_temp(0) 80 | 81 | def click(self, pos): # Return the position of the cube that was clicked 82 | if pos[0] < self.width and pos[1] < self.height: 83 | gap = self.width / 9 84 | x = pos[0] // gap 85 | y = pos[1] // gap 86 | return (int(y),int(x)) 87 | else: 88 | return None 89 | 90 | def is_finished(self): # Check if there are empty boxes in the board 91 | for i in range(self.rows): 92 | for j in range(self.cols): 93 | if self.cubes[i][j].value == 0: 94 | return False 95 | return True 96 | 97 | def solve(self): # Sudoku solver function 98 | find = find_empty(self.model) 99 | if not find: 100 | return True 101 | else: 102 | row, col = find 103 | 104 | for i in range(1, 10): 105 | if valid(self.model, i, (row, col)): 106 | self.model[row][col] = i 107 | 108 | if self.solve(): 109 | return True 110 | 111 | self.model[row][col] = 0 112 | 113 | return False 114 | 115 | def solve_gui(self): # Function to automate the solving 116 | find = find_empty(self.model) 117 | if not find: 118 | return True 119 | else: 120 | row, col = find 121 | 122 | for i in range(1, 10): 123 | if valid(self.model, i, (row, col)): 124 | self.model[row][col] = i 125 | self.cubes[row][col].set(i) 126 | self.cubes[row][col].draw_change(self.win, True) 127 | self.update_model() 128 | pygame.display.update() 129 | pygame.time.delay(100) 130 | 131 | if self.solve_gui(): 132 | return True 133 | 134 | self.model[row][col] = 0 135 | self.cubes[row][col].set(0) 136 | self.update_model() 137 | self.cubes[row][col].draw_change(self.win, False) 138 | pygame.display.update() 139 | pygame.time.delay(100) 140 | 141 | return False 142 | 143 | 144 | class Cube: # Define properties of individual cube in the board 145 | rows = 9 146 | cols = 9 147 | 148 | def __init__(self, value, row, col, width, height): 149 | self.value = value 150 | self.temp = 0 151 | self.row = row 152 | self.col = col 153 | self.width = width 154 | self.height = height 155 | self.selected = False 156 | 157 | def draw(self, win): 158 | fnt = pygame.font.SysFont("comicsans", 40) 159 | 160 | gap = self.width / 9 161 | x = self.col * gap 162 | y = self.row * gap 163 | 164 | if self.temp != 0 and self.value == 0: 165 | text = fnt.render(str(self.temp), 1, (128,128,128)) 166 | win.blit(text, (x+5, y+5)) 167 | elif not(self.value == 0): 168 | text = fnt.render(str(self.value), 1, (0, 0, 0)) 169 | win.blit(text, (x + (gap/2 - text.get_width()/2), y + (gap/2 - text.get_height()/2))) 170 | 171 | if self.selected: 172 | pygame.draw.rect(win, (255,0,0), (x,y, gap ,gap), 3) # Highlight the selected box 173 | 174 | def draw_change(self, win, g=True): 175 | fnt = pygame.font.SysFont("comicsans", 40) 176 | 177 | gap = self.width / 9 178 | x = self.col * gap 179 | y = self.row * gap 180 | 181 | pygame.draw.rect(win, (255, 255, 255), (x, y, gap, gap), 0) 182 | 183 | text = fnt.render(str(self.value), 1, (0, 0, 0)) 184 | win.blit(text, (x + (gap / 2 - text.get_width() / 2), y + (gap / 2 - text.get_height() / 2))) 185 | if g: 186 | pygame.draw.rect(win, (0, 255, 0), (x, y, gap, gap), 3) 187 | else: 188 | pygame.draw.rect(win, (255, 0, 0), (x, y, gap, gap), 3) 189 | 190 | def set(self, val): # Set permannent value 191 | self.value = val 192 | 193 | def set_temp(self, val): # Set temporary value 194 | self.temp = val 195 | 196 | 197 | def find_empty(bo): # Check for empty values 198 | for i in range(len(bo)): 199 | for j in range(len(bo[0])): 200 | if bo[i][j] == 0: 201 | return (i, j) 202 | 203 | return None 204 | 205 | 206 | def valid(bo, num, pos): # Check the validity of the number in the cube 207 | 208 | for i in range(len(bo[0])): # Check row 209 | if bo[pos[0]][i] == num and pos[1] != i: 210 | return False 211 | 212 | 213 | for i in range(len(bo)): # Check column 214 | if bo[i][pos[1]] == num and pos[0] != i: 215 | return False 216 | 217 | 218 | box_x = pos[1] // 3 219 | box_y = pos[0] // 3 220 | 221 | for i in range(box_y*3, box_y*3 + 3): # Check box 222 | for j in range(box_x * 3, box_x*3 + 3): 223 | if bo[i][j] == num and (i,j) != pos: 224 | return False 225 | 226 | return True 227 | 228 | 229 | def redraw_window(win, board, time, strikes): 230 | win.fill((255,255,255)) 231 | 232 | fnt = pygame.font.SysFont("comicsans", 40) # Draw time 233 | text = fnt.render("Time: " + format_time(time), 1, (0,0,0)) 234 | win.blit(text, (540 - 160, 560)) 235 | 236 | text = fnt.render("X " * strikes, 1, (255, 0, 0)) # Draw Strikes 237 | win.blit(text, (20, 560)) 238 | 239 | board.draw() # Draw grid and board 240 | 241 | 242 | def format_time(secs): # Compute the time 243 | sec = secs%60 244 | minute = secs//60 245 | hour = minute//60 246 | 247 | mat = " " + str(minute) + ":" + str(sec) 248 | return mat 249 | 250 | 251 | def main(): 252 | win = pygame.display.set_mode((540,600)) 253 | pygame.display.set_caption("Sudoku") # Window name 254 | board = Grid(9, 9, 540, 540, win) # Dimensions 255 | key = None 256 | run = True 257 | start = time.time() # Start the timer 258 | strikes = 0 259 | while run: 260 | 261 | play_time = round(time.time() - start) 262 | 263 | for event in pygame.event.get(): # Get keyboard events 264 | if event.type == pygame.QUIT: 265 | run = False 266 | if event.type == pygame.KEYDOWN: 267 | if event.key == pygame.K_1: 268 | key = 1 269 | if event.key == pygame.K_2: 270 | key = 2 271 | if event.key == pygame.K_3: 272 | key = 3 273 | if event.key == pygame.K_4: 274 | key = 4 275 | if event.key == pygame.K_5: 276 | key = 5 277 | if event.key == pygame.K_6: 278 | key = 6 279 | if event.key == pygame.K_7: 280 | key = 7 281 | if event.key == pygame.K_8: 282 | key = 8 283 | if event.key == pygame.K_9: 284 | key = 9 285 | if event.key == pygame.K_DELETE: 286 | board.clear() 287 | key = None 288 | 289 | if event.key == pygame.K_SPACE: # Auto solve 290 | board.solve_gui() 291 | 292 | if event.key == pygame.K_RETURN: 293 | i, j = board.selected 294 | if board.cubes[i][j].temp != 0: 295 | if board.place(board.cubes[i][j].temp): 296 | print("Success") 297 | else: 298 | print("Wrong") 299 | strikes += 1 300 | key = None 301 | 302 | if board.is_finished(): 303 | print("Game over") 304 | 305 | if event.type == pygame.MOUSEBUTTONDOWN: 306 | pos = pygame.mouse.get_pos() 307 | clicked = board.click(pos) 308 | if clicked: 309 | board.select(clicked[0], clicked[1]) 310 | key = None 311 | 312 | if board.selected and key != None: 313 | board.sketch(key) 314 | 315 | redraw_window(win, board, play_time, strikes) 316 | pygame.display.update() 317 | 318 | 319 | main() 320 | pygame.quit() -------------------------------------------------------------------------------- /Sudoku Solver/Intro.txt: -------------------------------------------------------------------------------- 1 | I will be following Backtracking Algorithm to solve this problem. 2 | 3 | The algorithm works something like this: 4 | 1. Pick empty box. 5 | 2. Try all numbers. 6 | 3. Find one that works. 7 | 4. Backtrack when the sudoku rules are broken. 8 | 5. Repeat the above steps until all the boxes are filled up. -------------------------------------------------------------------------------- /Sudoku Solver/solver.py: -------------------------------------------------------------------------------- 1 | b = [ 2 | [7,8,0,4,0,0,1,2,0], 3 | [6,0,0,0,7,5,0,0,9], 4 | [0,0,0,6,0,1,0,7,8], 5 | [0,0,7,0,4,0,2,6,0], 6 | [0,0,1,0,5,0,9,3,0], 7 | [9,0,4,0,6,0,0,0,5], 8 | [0,7,0,3,0,0,0,1,2], 9 | [1,2,0,0,0,7,4,0,0], 10 | [0,4,9,2,0,6,0,0,7] 11 | ] 12 | 13 | def solve(b): 14 | find = find_empty(b) # Check empty box 15 | if not find: 16 | return True # Final state of the board when every box is filled 17 | else: 18 | row, col = find 19 | 20 | for i in range(1,10): 21 | if valid(b, i, (row, col)): 22 | b[row][col] = i # Place the number in the board if its valid 23 | 24 | if solve(b): 25 | return True # Continue from that board state onwards 26 | 27 | b[row][col] = 0 28 | 29 | return False 30 | 31 | def valid(b, num, pos): 32 | 33 | for i in range(len(b[0])): # Check row 34 | if b[pos[0]][i] == num and pos[1] != i: # Check element in row if its equal to the number added and if its the current position being added to then ignore it 35 | return False 36 | 37 | 38 | for i in range(len(b)): # Check column 39 | if b[i][pos[1]] == num and pos[0] != i: # Check element column-wise if it equals the number added and its not the position that the new number was just added into 40 | return False 41 | 42 | box_x = pos[1] // 3 # Check 3x3 box 43 | box_y = pos[0] // 3 44 | 45 | for i in range(box_y*3, box_y*3 + 3): # Loop through the 3x3 boxes 46 | for j in range(box_x * 3, box_x*3 + 3): 47 | if b[i][j] == num and (i,j) != pos: # Check if same number exits in the 3x3 box and (i, j) was the position the new number was just added to 48 | return False 49 | 50 | return True 51 | 52 | def print_board(b): 53 | for i in range(len(b)): 54 | if i % 3 == 0 and i != 0: 55 | print("- - - - - - - - - - - - - ") # Separate sections of the board row-wise (Every 3x3 box) 56 | 57 | for j in range(len(b[0])): 58 | if j % 3 == 0 and j != 0: 59 | print(" | ", end="") # Separate sections of the board column-wise 60 | 61 | if j == 8: 62 | print(b[i][j]) 63 | else: 64 | print(str(b[i][j]) + " ", end="") 65 | 66 | 67 | def find_empty(b): 68 | for i in range(len(b)): 69 | for j in range(len(b[0])): 70 | if b[i][j] == 0: # Check if there is a 0 in each position of the box 71 | return (i, j) # Return the row and column 72 | 73 | return None 74 | 75 | print_board(b) 76 | print(" ") 77 | solve(b) 78 | print_board(b) 79 | -------------------------------------------------------------------------------- /Supervised Learning/.gitignore: -------------------------------------------------------------------------------- 1 | /venv -------------------------------------------------------------------------------- /Supervised Learning/README.md: -------------------------------------------------------------------------------- 1 | # Supervised Learning 2 | 3 | Supervised learning is a machine learning technique where we train a model on a labelled dataset. Our model learns from seen results taken from the training set and uses it to predict the outcomes of the test set. 4 | 5 | In this project the very popular [Iris dataset](https://gist.githubusercontent.com/curran/a08a1080b88344b0c8a7/raw/0e7a9b0a5d22642a06d3d5b9bcbad9890c8ee534/iris.csv) is used to identify the species of a flower based on its characteristics. 6 | -------------------------------------------------------------------------------- /Supervised Learning/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Supervised Learning/requirements.txt -------------------------------------------------------------------------------- /Supervised Learning/script.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import pandas as pd 4 | from sklearn import linear_model, preprocessing, model_selection 5 | from sklearn.neighbors import KNeighborsClassifier 6 | 7 | data = pd.read_csv( 8 | 'https://gist.githubusercontent.com/curran/a08a1080b88344b0c8a7/raw/0e7a9b0a5d22642a06d3d5b9bcbad9890c8ee534/iris.csv') 9 | 10 | # Data Pre-processing 11 | proc = preprocessing.LabelEncoder() 12 | sepal_length = proc.fit_transform(list(data["sepal_length"])) 13 | sepal_width = proc.fit_transform(list(data["sepal_width"])) 14 | petal_length = proc.fit_transform(list(data["petal_length"])) 15 | petal_width = proc.fit_transform(list(data["petal_width"])) 16 | variety = proc.fit_transform(list(data["species"])) 17 | 18 | # Prediction 19 | predict = "species" 20 | x = list(zip(sepal_length, sepal_width, petal_length, petal_width)) 21 | y = list(variety) 22 | 23 | var = ['Setosa', 'Virginica', 'Versicolor'] 24 | best = 0 25 | worst = 100 26 | 27 | for i in range(100): 28 | x_train, x_test, y_train, y_test = model_selection.train_test_split( 29 | x, y, test_size=0.9) 30 | model = KNeighborsClassifier(n_neighbors=5) 31 | model.fit(x_train, y_train) 32 | accuracy = model.score(x_test, y_test) 33 | if accuracy > best: 34 | best = accuracy 35 | elif accuracy < worst: 36 | worst = accuracy 37 | prediction = model.predict(x_test) 38 | print(f"Prediction:\t{var[prediction[i]].ljust(10)}\tActual: {var[y_test[i]].ljust(10)}\tAccuracy: {str(round(accuracy*100, 2)).ljust(5)} % \t Data: {x_test[i]}") 39 | 40 | print(f"\nHighest Accuracy: {round((100*best), 2)}%") 41 | print(f"\nLowest Accuracy: {round((100*worst), 2)}%") 42 | -------------------------------------------------------------------------------- /Translator/.gitignore: -------------------------------------------------------------------------------- 1 | /venv -------------------------------------------------------------------------------- /Translator/README.md: -------------------------------------------------------------------------------- 1 | # Translator 2 | 3 | This simple python script translates from one language to another using [googletrans](https://py-googletrans.readthedocs.io/en/latest/) python library. 4 | 5 | To use this to your convenience, feel free to change the `kn` in the python file to any language listed in the above link. -------------------------------------------------------------------------------- /Translator/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/K-G-PRAJWAL/Python-Projects/26b11bc4389e2378bc89643a08478074eb973cd5/Translator/requirements.txt -------------------------------------------------------------------------------- /Translator/script.py: -------------------------------------------------------------------------------- 1 | from tabulate import tabulate 2 | from googletrans import Translator 3 | 4 | 5 | class TranslateClass(object): 6 | def __init__(self, word, lang): 7 | self.word = word 8 | self.lang = lang 9 | self.Trans = Translator(service_urls=["translate.google.com"]) 10 | 11 | def __repr__(self): 12 | translated = self.Trans.translate(self.word, dest=self.lang).text 13 | data = [ 14 | ['Language:', "Word/Sentence"], 15 | ['English', self.word], 16 | ['Kannada', str(translated)]] 17 | table = str(tabulate(data, headers="firstrow", tablefmt="grid")) 18 | return table 19 | 20 | 21 | if __name__ == '__main__': 22 | translate = input('Enter Word/Sentence...') 23 | language = 'kn' # Translates to Kannada 24 | # language = 'hi' # Translates to Hindi 25 | # language = 'it' # Translates to Italian 26 | print(TranslateClass(translate, language)) 27 | --------------------------------------------------------------------------------