├── 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 |
18 |
Article 1 Summary
19 |
20 |
21 |
22 |
23 |
Article 2 Summary
24 |
25 |
26 |
27 |
28 |
Article 3 Summary
29 |
30 |
31 |
32 |
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 |
--------------------------------------------------------------------------------