├── snake-game ├── main.py └── README.md ├── .gitignore ├── contact-book ├── README.md ├── rpcontacts │ ├── __init__.py │ ├── main.py │ ├── database.py │ ├── model.py │ └── views.py └── rpcontacts.py ├── speech-extraction ├── README.md ├── recognized.txt └── main.py ├── typing-speed-test ├── README.md └── main.py ├── yt-video-download ├── README.md └── main.py ├── restaurant-billing-system ├── main.py └── README.md ├── rock-papper-scissors ├── README.md └── main.py ├── requirements.txt ├── library-management-system ├── lib.jpg ├── README.md ├── ViewBooks.py ├── DeleteBook.py ├── main.py ├── AddBook.py ├── ReturnBook.py └── IssueBook.py ├── mp3-player-gui ├── README.md └── main.py ├── url-shortener ├── README.md ├── bitly.py └── cuttly.py ├── .github └── workflows │ └── codeql-analysis.yml ├── LICENSE └── README.md /snake-game/main.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | env/ 2 | -------------------------------------------------------------------------------- /contact-book/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /snake-game/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /speech-extraction/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /typing-speed-test/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /typing-speed-test/main.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /yt-video-download/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /yt-video-download/main.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /restaurant-billing-system/main.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rock-papper-scissors/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /speech-extraction/recognized.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /restaurant-billing-system/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | bitly-api==0.3 2 | certifi==2023.7.22 3 | chardet==4.0.0 4 | idna==2.10 5 | requests==2.31.0 6 | urllib3==1.26.5 7 | -------------------------------------------------------------------------------- /library-management-system/lib.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UltiRequiem/python-projects-for-intermediates/HEAD/library-management-system/lib.jpg -------------------------------------------------------------------------------- /contact-book/rpcontacts/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This module provides the rpcontacts package.""" 4 | 5 | __version__ = "0.1.0" 6 | -------------------------------------------------------------------------------- /library-management-system/README.md: -------------------------------------------------------------------------------- 1 | # Library Management System 2 | 3 | [Link](https://data-flair.training/blogs/library-management-system-python-project) 4 | -------------------------------------------------------------------------------- /mp3-player-gui/README.md: -------------------------------------------------------------------------------- 1 | # MP3 Player using Tkinter and Mutagen 2 | 3 | [Link](https://blog.devgenius.io/mp3-player-using-tkinter-and-mutagen-in-python-6fec027aeced). 4 | -------------------------------------------------------------------------------- /url-shortener/README.md: -------------------------------------------------------------------------------- 1 | # URL Shortener 2 | 3 | [Link](https://towardsdatascience.com/best-apis-for-url-shortening-using-python-2db09d1f86f0) 4 | Library Repository: [bitly/bitly-api-python](https://github.com/bitly/bitly-api-python) 5 | -------------------------------------------------------------------------------- /contact-book/rpcontacts.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # rpcontacts_project/rpcontacts.py 4 | 5 | """This module provides RP Contacts entry point script.""" 6 | 7 | from rpcontacts.main import main 8 | 9 | if __name__ == "__main__": 10 | main() 11 | -------------------------------------------------------------------------------- /url-shortener/bitly.py: -------------------------------------------------------------------------------- 1 | import bitly_api 2 | 3 | BITLY_ACCESS_TOKEN = "YOUR_ACCESS_TOKEN" 4 | ACCESS = bitly_api.Connection(access_token=BITLY_ACCESS_TOKEN) 5 | SHORT_URL = ACCESS.shorten(str(input("Introduce you larger URL: "))) 6 | 7 | if __name__ == "__main__": 8 | print(f"Short URL = {SHORT_URL['url']}") 9 | -------------------------------------------------------------------------------- /url-shortener/cuttly.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | API_KEY = "YOUR_API_KEY" 4 | URL = str(input("Introduce your larger url: ")) 5 | API_URL = f"https://cutt.ly/api/api.php?key={API_KEY}&short={URL}" 6 | DATA = requests.get(API_URL).json()["url"] 7 | 8 | if __name__ == "__main__": 9 | if DATA["status"] == 7: 10 | shortened_url = DATA["shortLink"] 11 | print("Shortened URL:", shortened_url) 12 | else: 13 | print("[!] Error Shortening URL:", DATA) 14 | -------------------------------------------------------------------------------- /speech-extraction/main.py: -------------------------------------------------------------------------------- 1 | import speech_recognition as sr 2 | import moviepy.editor as mp 3 | 4 | clip = mp.VideoFileClip(r"video_recording.mov") 5 | 6 | clip.audio.write_audiofile(r"converted.wav") 7 | 8 | r = sr.Recognizer() 9 | 10 | audio = sr.AudioFile("converted.wav") 11 | 12 | 13 | with audio as source: 14 | audio_file = r.record(source) 15 | result = r.recognize_google(audio_file) 16 | 17 | with open("recognized.txt", mode="w") as file: 18 | file.write("Recognized Speech:") 19 | file.write("\n") 20 | file.write(result) 21 | print("ready!") 22 | -------------------------------------------------------------------------------- /contact-book/rpcontacts/main.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # rpcontacts/main.py 3 | 4 | """This module provides RP Contacts application.""" 5 | 6 | import sys 7 | 8 | from PyQt5.QtWidgets import QApplication 9 | 10 | from .database import createConnection 11 | from .views import Window 12 | 13 | 14 | def main(): 15 | """RP Contacts main function.""" 16 | # Create the application 17 | app = QApplication(sys.argv) 18 | # Connect to the database before creating any window 19 | if not createConnection("contacts.sqlite"): 20 | sys.exit(1) 21 | # Create the main window if the connection succeeded 22 | win = Window() 23 | win.show() 24 | # Run the event loop 25 | sys.exit(app.exec_()) 26 | -------------------------------------------------------------------------------- /contact-book/rpcontacts/database.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # rpcontacts/database.py 3 | 4 | # Snip... 5 | from PyQt5.QtSql import QSqlDatabase, QSqlQuery 6 | 7 | 8 | def _createContactsTable(): 9 | """Create the contacts table in the database.""" 10 | createTableQuery = QSqlQuery() 11 | return createTableQuery.exec( 12 | """ 13 | CREATE TABLE IF NOT EXISTS contacts ( 14 | id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, 15 | name VARCHAR(40) NOT NULL, 16 | job VARCHAR(50), 17 | email VARCHAR(40) NOT NULL 18 | ) 19 | """ 20 | ) 21 | 22 | 23 | def createConnection(databaseName): 24 | # Snip... 25 | _createContactsTable() 26 | return True 27 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | on: 3 | push: 4 | branches: [main] 5 | pull_request: 6 | branches: [main] 7 | schedule: 8 | - cron: "35 21 * * 1" 9 | jobs: 10 | analyze: 11 | name: Analyze 12 | runs-on: ubuntu-latest 13 | permissions: 14 | actions: read 15 | contents: read 16 | security-events: write 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | language: ["python"] 21 | steps: 22 | - name: Checkout repository 23 | uses: actions/checkout@v2 24 | - name: Initialize CodeQL 25 | uses: github/codeql-action/init@v1 26 | with: 27 | languages: ${{ matrix.language }} 28 | - name: Autobuild 29 | uses: github/codeql-action/autobuild@v1 30 | - name: Perform CodeQL Analysis 31 | uses: github/codeql-action/analyze@v1 32 | -------------------------------------------------------------------------------- /rock-papper-scissors/main.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def winner(user, cpu): 5 | 6 | if (user == "Rock" and cpu == "Paper") or (user == "Paper" and cpu == "Scissor") or (user == "Scissor" and cpu == "Rock"): 7 | return "\nUser : " + user + "\nCPU : " + cpu + "\nWinner : CPU" 8 | 9 | elif(cpu == "Rock" and user == "Paper") or (cpu == "Paper" and user == "Scissor") or (cpu == "Scissor" and user == "Rock"): 10 | return "\nUser : " + user + "\nCPU : " + cpu + "\nWinner : User" 11 | 12 | elif user == cpu: 13 | return "\nUser : " + user + "\nCPU : " + cpu + "\nWinner : Draw" 14 | 15 | 16 | options = ["Rock", "Paper", "Scissor"] 17 | 18 | while True: 19 | UI = input("\nEnter Your Choice (rock, paper, scissor) : ").title() 20 | 21 | if UI not in options: 22 | continue 23 | print(winner(UI, random.choice(options))) 24 | 25 | YN = input("\nPlay Again? (yes/no) : ").lower() 26 | if YN == "no": 27 | break 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Eliaz Bobadilla 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # :snake: Python projects for Intermediates :snake: 2 | 3 |
10 | 11 | All Proyects are taken from [this Twitter thread](https://twitter.com/swastika0015/status/1403308100115861508) 12 | of [@swastika0015](https://twitter.com/swastika0015). 13 | 14 | ## List of Projects: 15 | 16 | - [MP3 Player GUI](./mp3-player-gui/) 17 | - [URL Shorter](./url-shortener/) 18 | - [Speech Extraction from Video](./speech-extraction/) 19 | - [Contact Book](./contact-book/) 20 | - [The Snake Game](./snake-game/) 21 | - [Rock Paper Scissor Game](./rock-papper-scissors/) 22 | - [Typing Speed Test](./typing-speed-test/) 23 | - [YouTube Video Downloader](./yt-video-download/) 24 | - [Restaurant Billing System](./restaurant-billing-system/) 25 | 26 | ## Previous 27 | 28 | [UltiRequiem/python-projects-for-beginners](https://github.com/UltiRequiem/python-projects-for-beginners) 29 | -------------------------------------------------------------------------------- /contact-book/rpcontacts/model.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # rpcontacts/model.py 3 | 4 | """This module provides a model to manage the contacts table.""" 5 | 6 | from PyQt5.QtCore import Qt 7 | from PyQt5.QtSql import QSqlTableModel 8 | 9 | 10 | class ContactsModel: 11 | def __init__(self): 12 | self.model = self._createModel() 13 | 14 | @staticmethod 15 | def _createModel(): 16 | """Create and set up the model.""" 17 | tableModel = QSqlTableModel() 18 | tableModel.setTable("contacts") 19 | tableModel.setEditStrategy(QSqlTableModel.OnFieldChange) 20 | tableModel.select() 21 | headers = ("ID", "Name", "Job", "Email") 22 | for columnIndex, header in enumerate(headers): 23 | tableModel.setHeaderData(columnIndex, Qt.Horizontal, header) 24 | return tableModel 25 | 26 | def addContact(self, data): 27 | """Add a contact to the database.""" 28 | rows = self.model.rowCount() 29 | self.model.insertRows(rows, 1) 30 | for column, field in enumerate(data): 31 | self.model.setData(self.model.index(rows, column + 1), field) 32 | self.model.submitAll() 33 | self.model.select() 34 | 35 | def deleteContact(self, row): 36 | """Remove a contact from the database.""" 37 | self.model.removeRow(row) 38 | self.model.submitAll() 39 | self.model.select() 40 | 41 | def clearContacts(self): 42 | """Remove all contacts in the database.""" 43 | self.model.setEditStrategy(QSqlTableModel.OnManualSubmit) 44 | self.model.removeRows(0, self.model.rowCount()) 45 | self.model.submitAll() 46 | self.model.setEditStrategy(QSqlTableModel.OnFieldChange) 47 | self.model.select() 48 | -------------------------------------------------------------------------------- /library-management-system/ViewBooks.py: -------------------------------------------------------------------------------- 1 | from tkinter import * 2 | from PIL import ImageTk, Image 3 | from tkinter import messagebox 4 | import pymysql 5 | 6 | # Add your own database name and password here to reflect in the code 7 | mypass = "root" 8 | mydatabase = "db" 9 | 10 | con = pymysql.connect( 11 | host="localhost", user="root", password=mypass, database=mydatabase 12 | ) 13 | cur = con.cursor() 14 | 15 | # Enter Table Names here 16 | bookTable = "books" 17 | 18 | 19 | def View(): 20 | 21 | root = Tk() 22 | root.title("Library") 23 | root.minsize(width=400, height=400) 24 | root.geometry("600x500") 25 | 26 | Canvas1 = Canvas(root) 27 | Canvas1.config(bg="#12a4d9") 28 | Canvas1.pack(expand=True, fill=BOTH) 29 | 30 | headingFrame1 = Frame(root, bg="#FFBB00", bd=5) 31 | headingFrame1.place(relx=0.25, rely=0.1, relwidth=0.5, relheight=0.13) 32 | 33 | headingLabel = Label( 34 | headingFrame1, text="View Books", bg="black", fg="white", font=("Courier", 15) 35 | ) 36 | headingLabel.place(relx=0, rely=0, relwidth=1, relheight=1) 37 | 38 | labelFrame = Frame(root, bg="black") 39 | labelFrame.place(relx=0.1, rely=0.3, relwidth=0.8, relheight=0.5) 40 | y = 0.25 41 | 42 | Label( 43 | labelFrame, 44 | text="%-10s%-40s%-30s%-20s" % ("BID", "Title", "Author", "Status"), 45 | bg="black", 46 | fg="white", 47 | ).place(relx=0.07, rely=0.1) 48 | Label( 49 | labelFrame, 50 | text="----------------------------------------------------------------------------", 51 | bg="black", 52 | fg="white", 53 | ).place(relx=0.05, rely=0.2) 54 | getBooks = "select * from " + bookTable 55 | try: 56 | cur.execute(getBooks) 57 | con.commit() 58 | for i in cur: 59 | Label( 60 | labelFrame, 61 | text="%-10s%-30s%-30s%-20s" % (i[0], i[1], i[2], i[3]), 62 | bg="black", 63 | fg="white", 64 | ).place(relx=0.07, rely=y) 65 | y += 0.1 66 | except: 67 | messagebox.showinfo("Failed to fetch files from database") 68 | 69 | quitBtn = Button(root, text="Quit", bg="#f7f1e3", fg="black", command=root.destroy) 70 | quitBtn.place(relx=0.4, rely=0.9, relwidth=0.18, relheight=0.08) 71 | 72 | root.mainloop() 73 | -------------------------------------------------------------------------------- /library-management-system/DeleteBook.py: -------------------------------------------------------------------------------- 1 | from tkinter import * 2 | from PIL import ImageTk, Image 3 | from tkinter import messagebox 4 | import pymysql 5 | 6 | # Add your own database name and password here to reflect in the code 7 | mypass = "root" 8 | mydatabase = "db" 9 | 10 | con = pymysql.connect( 11 | host="localhost", user="root", password=mypass, database=mydatabase 12 | ) 13 | cur = con.cursor() 14 | 15 | # Enter Table Names here 16 | issueTable = "books_issued" 17 | bookTable = "books" # Book Table 18 | 19 | 20 | def deleteBook(): 21 | 22 | bid = bookInfo1.get() 23 | 24 | deleteSql = "delete from " + bookTable + " where bid = '" + bid + "'" 25 | deleteIssue = "delete from " + issueTable + " where bid = '" + bid + "'" 26 | try: 27 | cur.execute(deleteSql) 28 | con.commit() 29 | cur.execute(deleteIssue) 30 | con.commit() 31 | messagebox.showinfo("Success", "Book Record Deleted Successfully") 32 | except: 33 | messagebox.showinfo("Please check Book ID") 34 | 35 | print(bid) 36 | 37 | bookInfo1.delete(0, END) 38 | root.destroy() 39 | 40 | 41 | def delete(): 42 | 43 | global bookInfo1, bookInfo2, bookInfo3, bookInfo4, Canvas1, con, cur, bookTable, root 44 | 45 | root = Tk() 46 | root.title("Library") 47 | root.minsize(width=400, height=400) 48 | root.geometry("600x500") 49 | 50 | Canvas1 = Canvas(root) 51 | 52 | Canvas1.config(bg="#006B38") 53 | Canvas1.pack(expand=True, fill=BOTH) 54 | 55 | headingFrame1 = Frame(root, bg="#FFBB00", bd=5) 56 | headingFrame1.place(relx=0.25, rely=0.1, relwidth=0.5, relheight=0.13) 57 | 58 | headingLabel = Label( 59 | headingFrame1, text="Delete Book", bg="black", fg="white", font=("Courier", 15) 60 | ) 61 | headingLabel.place(relx=0, rely=0, relwidth=1, relheight=1) 62 | 63 | labelFrame = Frame(root, bg="black") 64 | labelFrame.place(relx=0.1, rely=0.3, relwidth=0.8, relheight=0.5) 65 | 66 | # Book ID to Delete 67 | lb2 = Label(labelFrame, text="Book ID : ", bg="black", fg="white") 68 | lb2.place(relx=0.05, rely=0.5) 69 | 70 | bookInfo1 = Entry(labelFrame) 71 | bookInfo1.place(relx=0.3, rely=0.5, relwidth=0.62) 72 | 73 | # Submit Button 74 | SubmitBtn = Button( 75 | root, text="SUBMIT", bg="#d1ccc0", fg="black", command=deleteBook 76 | ) 77 | SubmitBtn.place(relx=0.28, rely=0.9, relwidth=0.18, relheight=0.08) 78 | 79 | quitBtn = Button(root, text="Quit", bg="#f7f1e3", fg="black", command=root.destroy) 80 | quitBtn.place(relx=0.53, rely=0.9, relwidth=0.18, relheight=0.08) 81 | 82 | root.mainloop() 83 | -------------------------------------------------------------------------------- /library-management-system/main.py: -------------------------------------------------------------------------------- 1 | from tkinter import * 2 | from PIL import ImageTk, Image 3 | import pymysql 4 | from tkinter import messagebox 5 | from AddBook import * 6 | from DeleteBook import * 7 | from ViewBooks import * 8 | from IssueBook import * 9 | from ReturnBook import * 10 | 11 | # Add your own database name and password here to reflect in the code 12 | mypass = "root" 13 | mydatabase = "db" 14 | 15 | con = pymysql.connect( 16 | host="localhost", user="root", password=mypass, database=mydatabase 17 | ) 18 | cur = con.cursor() 19 | 20 | root = Tk() 21 | root.title("Library") 22 | root.minsize(width=400, height=400) 23 | root.geometry("600x500") 24 | 25 | # Take n greater than 0.25 and less than 5 26 | same = True 27 | n = 0.25 28 | 29 | # Adding a background image 30 | background_image = Image.open("lib.jpg") 31 | [imageSizeWidth, imageSizeHeight] = background_image.size 32 | 33 | newImageSizeWidth = int(imageSizeWidth * n) 34 | if same: 35 | newImageSizeHeight = int(imageSizeHeight * n) 36 | else: 37 | newImageSizeHeight = int(imageSizeHeight / n) 38 | 39 | background_image = background_image.resize( 40 | (newImageSizeWidth, newImageSizeHeight), Image.ANTIALIAS 41 | ) 42 | img = ImageTk.PhotoImage(background_image) 43 | 44 | Canvas1 = Canvas(root) 45 | 46 | Canvas1.create_image(300, 340, image=img) 47 | Canvas1.config(bg="white", width=newImageSizeWidth, height=newImageSizeHeight) 48 | Canvas1.pack(expand=True, fill=BOTH) 49 | 50 | headingFrame1 = Frame(root, bg="#FFBB00", bd=5) 51 | headingFrame1.place(relx=0.2, rely=0.1, relwidth=0.6, relheight=0.16) 52 | 53 | headingLabel = Label( 54 | headingFrame1, 55 | text="Welcome to \n DataFlair Library", 56 | bg="black", 57 | fg="white", 58 | font=("Courier", 15), 59 | ) 60 | headingLabel.place(relx=0, rely=0, relwidth=1, relheight=1) 61 | 62 | btn1 = Button(root, text="Add Book Details", bg="black", fg="white", command=addBook) 63 | btn1.place(relx=0.28, rely=0.4, relwidth=0.45, relheight=0.1) 64 | 65 | btn2 = Button(root, text="Delete Book", bg="black", fg="white", command=delete) 66 | btn2.place(relx=0.28, rely=0.5, relwidth=0.45, relheight=0.1) 67 | 68 | btn3 = Button(root, text="View Book List", bg="black", fg="white", command=View) 69 | btn3.place(relx=0.28, rely=0.6, relwidth=0.45, relheight=0.1) 70 | 71 | btn4 = Button( 72 | root, text="Issue Book to Student", bg="black", fg="white", command=issueBook 73 | ) 74 | btn4.place(relx=0.28, rely=0.7, relwidth=0.45, relheight=0.1) 75 | 76 | btn5 = Button(root, text="Return Book", bg="black", fg="white", command=returnBook) 77 | btn5.place(relx=0.28, rely=0.8, relwidth=0.45, relheight=0.1) 78 | 79 | root.mainloop() 80 | -------------------------------------------------------------------------------- /library-management-system/AddBook.py: -------------------------------------------------------------------------------- 1 | from tkinter import * 2 | from PIL import ImageTk, Image 3 | from tkinter import messagebox 4 | import pymysql 5 | 6 | 7 | def bookRegister(): 8 | 9 | bid = bookInfo1.get() 10 | title = bookInfo2.get() 11 | author = bookInfo3.get() 12 | status = bookInfo4.get() 13 | status = status.lower() 14 | 15 | insertBooks = ( 16 | "insert into " 17 | + bookTable 18 | + " values('" 19 | + bid 20 | + "','" 21 | + title 22 | + "','" 23 | + author 24 | + "','" 25 | + status 26 | + "')" 27 | ) 28 | try: 29 | cur.execute(insertBooks) 30 | con.commit() 31 | messagebox.showinfo("Success", "Book added successfully") 32 | except: 33 | messagebox.showinfo("Error", "Can't add data into Database") 34 | 35 | print(bid) 36 | print(title) 37 | print(author) 38 | print(status) 39 | 40 | root.destroy() 41 | 42 | 43 | def addBook(): 44 | 45 | global bookInfo1, bookInfo2, bookInfo3, bookInfo4, Canvas1, con, cur, bookTable, root 46 | 47 | root = Tk() 48 | root.title("Library") 49 | root.minsize(width=400, height=400) 50 | root.geometry("600x500") 51 | 52 | # Add your own database name and password here to reflect in the code 53 | mypass = "root" 54 | mydatabase = "db" 55 | 56 | con = pymysql.connect( 57 | host="localhost", user="root", password=mypass, database=mydatabase 58 | ) 59 | cur = con.cursor() 60 | 61 | # Enter Table Names here 62 | bookTable = "books" # Book Table 63 | 64 | Canvas1 = Canvas(root) 65 | 66 | Canvas1.config(bg="#ff6e40") 67 | Canvas1.pack(expand=True, fill=BOTH) 68 | 69 | headingFrame1 = Frame(root, bg="#FFBB00", bd=5) 70 | headingFrame1.place(relx=0.25, rely=0.1, relwidth=0.5, relheight=0.13) 71 | 72 | headingLabel = Label( 73 | headingFrame1, text="Add Books", bg="black", fg="white", font=("Courier", 15) 74 | ) 75 | headingLabel.place(relx=0, rely=0, relwidth=1, relheight=1) 76 | 77 | labelFrame = Frame(root, bg="black") 78 | labelFrame.place(relx=0.1, rely=0.4, relwidth=0.8, relheight=0.4) 79 | 80 | # Book ID 81 | lb1 = Label(labelFrame, text="Book ID : ", bg="black", fg="white") 82 | lb1.place(relx=0.05, rely=0.2, relheight=0.08) 83 | 84 | bookInfo1 = Entry(labelFrame) 85 | bookInfo1.place(relx=0.3, rely=0.2, relwidth=0.62, relheight=0.08) 86 | 87 | # Title 88 | lb2 = Label(labelFrame, text="Title : ", bg="black", fg="white") 89 | lb2.place(relx=0.05, rely=0.35, relheight=0.08) 90 | 91 | bookInfo2 = Entry(labelFrame) 92 | bookInfo2.place(relx=0.3, rely=0.35, relwidth=0.62, relheight=0.08) 93 | 94 | # Book Author 95 | lb3 = Label(labelFrame, text="Author : ", bg="black", fg="white") 96 | lb3.place(relx=0.05, rely=0.50, relheight=0.08) 97 | 98 | bookInfo3 = Entry(labelFrame) 99 | bookInfo3.place(relx=0.3, rely=0.50, relwidth=0.62, relheight=0.08) 100 | 101 | # Book Status 102 | lb4 = Label(labelFrame, text="Status(Avail/issued) : ", bg="black", fg="white") 103 | lb4.place(relx=0.05, rely=0.65, relheight=0.08) 104 | 105 | bookInfo4 = Entry(labelFrame) 106 | bookInfo4.place(relx=0.3, rely=0.65, relwidth=0.62, relheight=0.08) 107 | 108 | # Submit Button 109 | SubmitBtn = Button( 110 | root, text="SUBMIT", bg="#d1ccc0", fg="black", command=bookRegister 111 | ) 112 | SubmitBtn.place(relx=0.28, rely=0.9, relwidth=0.18, relheight=0.08) 113 | 114 | quitBtn = Button(root, text="Quit", bg="#f7f1e3", fg="black", command=root.destroy) 115 | quitBtn.place(relx=0.53, rely=0.9, relwidth=0.18, relheight=0.08) 116 | 117 | root.mainloop() 118 | -------------------------------------------------------------------------------- /library-management-system/ReturnBook.py: -------------------------------------------------------------------------------- 1 | from tkinter import * 2 | from PIL import ImageTk, Image 3 | from tkinter import messagebox 4 | import pymysql 5 | 6 | # Add your own database name and password here to reflect in the code 7 | mypass = "root" 8 | mydatabase = "db" 9 | 10 | con = pymysql.connect( 11 | host="localhost", user="root", password=mypass, database=mydatabase 12 | ) 13 | cur = con.cursor() 14 | 15 | # Enter Table Names here 16 | issueTable = "books_issued" # Issue Table 17 | bookTable = "books" # Book Table 18 | 19 | 20 | allBid = [] # List To store all Book IDs 21 | 22 | 23 | def returnn(): 24 | 25 | global SubmitBtn, labelFrame, lb1, bookInfo1, quitBtn, root, Canvas1, status 26 | 27 | bid = bookInfo1.get() 28 | 29 | extractBid = "select bid from " + issueTable 30 | try: 31 | cur.execute(extractBid) 32 | con.commit() 33 | for i in cur: 34 | allBid.append(i[0]) 35 | 36 | if bid in allBid: 37 | checkAvail = ( 38 | "select status from " + bookTable + " where bid = '" + bid + "'" 39 | ) 40 | cur.execute(checkAvail) 41 | con.commit() 42 | for i in cur: 43 | check = i[0] 44 | 45 | if check == "issued": 46 | status = True 47 | else: 48 | status = False 49 | 50 | else: 51 | messagebox.showinfo("Error", "Book ID not present") 52 | except: 53 | messagebox.showinfo("Error", "Can't fetch Book IDs") 54 | 55 | issueSql = "delete from " + issueTable + " where bid = '" + bid + "'" 56 | 57 | print(bid in allBid) 58 | print(status) 59 | updateStatus = ( 60 | "update " + bookTable + " set status = 'avail' where bid = '" + bid + "'" 61 | ) 62 | try: 63 | if bid in allBid and status == True: 64 | cur.execute(issueSql) 65 | con.commit() 66 | cur.execute(updateStatus) 67 | con.commit() 68 | messagebox.showinfo("Success", "Book Returned Successfully") 69 | else: 70 | allBid.clear() 71 | messagebox.showinfo("Message", "Please check the book ID") 72 | root.destroy() 73 | return 74 | except: 75 | messagebox.showinfo("Search Error", "The value entered is wrong, Try again") 76 | 77 | allBid.clear() 78 | root.destroy() 79 | 80 | 81 | def returnBook(): 82 | 83 | global bookInfo1, SubmitBtn, quitBtn, Canvas1, con, cur, root, labelFrame, lb1 84 | 85 | root = Tk() 86 | root.title("Library") 87 | root.minsize(width=400, height=400) 88 | root.geometry("600x500") 89 | 90 | Canvas1 = Canvas(root) 91 | 92 | Canvas1.config(bg="#006B38") 93 | Canvas1.pack(expand=True, fill=BOTH) 94 | 95 | headingFrame1 = Frame(root, bg="#FFBB00", bd=5) 96 | headingFrame1.place(relx=0.25, rely=0.1, relwidth=0.5, relheight=0.13) 97 | 98 | headingLabel = Label( 99 | headingFrame1, text="Return Book", bg="black", fg="white", font=("Courier", 15) 100 | ) 101 | headingLabel.place(relx=0, rely=0, relwidth=1, relheight=1) 102 | 103 | labelFrame = Frame(root, bg="black") 104 | labelFrame.place(relx=0.1, rely=0.3, relwidth=0.8, relheight=0.5) 105 | 106 | # Book ID to Delete 107 | lb1 = Label(labelFrame, text="Book ID : ", bg="black", fg="white") 108 | lb1.place(relx=0.05, rely=0.5) 109 | 110 | bookInfo1 = Entry(labelFrame) 111 | bookInfo1.place(relx=0.3, rely=0.5, relwidth=0.62) 112 | 113 | # Submit Button 114 | SubmitBtn = Button(root, text="Return", bg="#d1ccc0", fg="black", command=returnn) 115 | SubmitBtn.place(relx=0.28, rely=0.9, relwidth=0.18, relheight=0.08) 116 | 117 | quitBtn = Button(root, text="Quit", bg="#f7f1e3", fg="black", command=root.destroy) 118 | quitBtn.place(relx=0.53, rely=0.9, relwidth=0.18, relheight=0.08) 119 | 120 | root.mainloop() 121 | -------------------------------------------------------------------------------- /library-management-system/IssueBook.py: -------------------------------------------------------------------------------- 1 | from tkinter import * 2 | from PIL import ImageTk, Image 3 | from tkinter import messagebox 4 | import pymysql 5 | 6 | # Add your own database name and password here to reflect in the code 7 | mypass = "root" 8 | mydatabase = "db" 9 | 10 | con = pymysql.connect( 11 | host="localhost", user="root", password=mypass, database=mydatabase 12 | ) 13 | cur = con.cursor() 14 | 15 | # Enter Table Names here 16 | issueTable = "books_issued" 17 | bookTable = "books" 18 | 19 | # List To store all Book IDs 20 | allBid = [] 21 | 22 | 23 | def issue(): 24 | 25 | global issueBtn, labelFrame, lb1, inf1, inf2, quitBtn, root, Canvas1, status 26 | 27 | bid = inf1.get() 28 | issueto = inf2.get() 29 | 30 | issueBtn.destroy() 31 | labelFrame.destroy() 32 | lb1.destroy() 33 | inf1.destroy() 34 | inf2.destroy() 35 | 36 | extractBid = "select bid from " + bookTable 37 | try: 38 | cur.execute(extractBid) 39 | con.commit() 40 | for i in cur: 41 | allBid.append(i[0]) 42 | 43 | if bid in allBid: 44 | checkAvail = ( 45 | "select status from " + bookTable + " where bid = '" + bid + "'" 46 | ) 47 | cur.execute(checkAvail) 48 | con.commit() 49 | for i in cur: 50 | check = i[0] 51 | 52 | if check == "avail": 53 | status = True 54 | else: 55 | status = False 56 | 57 | else: 58 | messagebox.showinfo("Error", "Book ID not present") 59 | except: 60 | messagebox.showinfo("Error", "Can't fetch Book IDs") 61 | 62 | issueSql = "insert into " + issueTable + " values ('" + bid + "','" + issueto + "')" 63 | show = "select * from " + issueTable 64 | 65 | updateStatus = ( 66 | "update " + bookTable + " set status = 'issued' where bid = '" + bid + "'" 67 | ) 68 | try: 69 | if bid in allBid and status == True: 70 | cur.execute(issueSql) 71 | con.commit() 72 | cur.execute(updateStatus) 73 | con.commit() 74 | messagebox.showinfo("Success", "Book Issued Successfully") 75 | root.destroy() 76 | else: 77 | allBid.clear() 78 | messagebox.showinfo("Message", "Book Already Issued") 79 | root.destroy() 80 | return 81 | except: 82 | messagebox.showinfo("Search Error", "The value entered is wrong, Try again") 83 | 84 | print(bid) 85 | print(issueto) 86 | 87 | allBid.clear() 88 | 89 | 90 | def issueBook(): 91 | 92 | global issueBtn, labelFrame, lb1, inf1, inf2, quitBtn, root, Canvas1, status 93 | 94 | root = Tk() 95 | root.title("Library") 96 | root.minsize(width=400, height=400) 97 | root.geometry("600x500") 98 | 99 | Canvas1 = Canvas(root) 100 | Canvas1.config(bg="#D6ED17") 101 | Canvas1.pack(expand=True, fill=BOTH) 102 | 103 | headingFrame1 = Frame(root, bg="#FFBB00", bd=5) 104 | headingFrame1.place(relx=0.25, rely=0.1, relwidth=0.5, relheight=0.13) 105 | 106 | headingLabel = Label( 107 | headingFrame1, text="Issue Book", bg="black", fg="white", font=("Courier", 15) 108 | ) 109 | headingLabel.place(relx=0, rely=0, relwidth=1, relheight=1) 110 | 111 | labelFrame = Frame(root, bg="black") 112 | labelFrame.place(relx=0.1, rely=0.3, relwidth=0.8, relheight=0.5) 113 | 114 | # Book ID 115 | lb1 = Label(labelFrame, text="Book ID : ", bg="black", fg="white") 116 | lb1.place(relx=0.05, rely=0.2) 117 | 118 | inf1 = Entry(labelFrame) 119 | inf1.place(relx=0.3, rely=0.2, relwidth=0.62) 120 | 121 | # Issued To Student name 122 | lb2 = Label(labelFrame, text="Issued To : ", bg="black", fg="white") 123 | lb2.place(relx=0.05, rely=0.4) 124 | 125 | inf2 = Entry(labelFrame) 126 | inf2.place(relx=0.3, rely=0.4, relwidth=0.62) 127 | 128 | # Issue Button 129 | issueBtn = Button(root, text="Issue", bg="#d1ccc0", fg="black", command=issue) 130 | issueBtn.place(relx=0.28, rely=0.9, relwidth=0.18, relheight=0.08) 131 | 132 | quitBtn = Button(root, text="Quit", bg="#aaa69d", fg="black", command=root.destroy) 133 | quitBtn.place(relx=0.53, rely=0.9, relwidth=0.18, relheight=0.08) 134 | 135 | root.mainloop() 136 | -------------------------------------------------------------------------------- /contact-book/rpcontacts/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This module provides views to manage the contacts table.""" 4 | 5 | from PyQt5.QtCore import Qt 6 | from PyQt5.QtWidgets import ( 7 | QAbstractItemView, 8 | QHBoxLayout, 9 | QDialog, 10 | QDialogButtonBox, 11 | QFormLayout, 12 | QLineEdit, 13 | QMessageBox, 14 | QMainWindow, 15 | QPushButton, 16 | QTableView, 17 | QVBoxLayout, 18 | QWidget, 19 | ) 20 | 21 | from .model import ContactsModel 22 | 23 | 24 | class Window(QMainWindow): 25 | """Main Window.""" 26 | 27 | def __init__(self, parent=None): 28 | """Initializer.""" 29 | # Snip... 30 | self.contactsModel = ContactsModel() 31 | self.setupUI() 32 | 33 | def setupUI(self): 34 | """Setup the main window's GUI.""" 35 | # Create the table view widget 36 | self.table = QTableView() 37 | self.table.setModel(self.contactsModel.model) 38 | self.deleteButton.clicked.connect(self.deleteContact) 39 | self.clearAllButton.clicked.connect(self.clearContacts) 40 | self.table.setSelectionBehavior(QAbstractItemView.SelectRows) 41 | self.table.resizeColumnsToContents() 42 | # Create buttons 43 | self.addButton = QPushButton("Add...") 44 | self.deleteButton = QPushButton("Delete") 45 | self.clearAllButton = QPushButton("Clear All") 46 | # Lay out the GUI 47 | layout = QVBoxLayout() 48 | layout.addWidget(self.addButton) 49 | layout.addWidget(self.deleteButton) 50 | layout.addStretch() 51 | layout.addWidget(self.clearAllButton) 52 | self.layout.addWidget(self.table) 53 | self.layout.addLayout(layout) 54 | 55 | 56 | class AddDialog(QDialog): 57 | """Add Contact dialog.""" 58 | 59 | def __init__(self, parent=None): 60 | """Initializer.""" 61 | super().__init__(parent=parent) 62 | self.setWindowTitle("Add Contact") 63 | self.layout = QVBoxLayout() 64 | self.setLayout(self.layout) 65 | self.data = None 66 | 67 | self.setupUI() 68 | 69 | def setupUI(self): 70 | """Setup the Add Contact dialog's GUI.""" 71 | # Create line edits for data fields 72 | self.nameField = QLineEdit() 73 | self.nameField.setObjectName("Name") 74 | self.addButton.clicked.connect(self.openAddDialog) 75 | self.jobField = QLineEdit() 76 | self.jobField.setObjectName("Job") 77 | self.emailField = QLineEdit() 78 | self.emailField.setObjectName("Email") 79 | # Lay out the data fields 80 | layout = QFormLayout() 81 | layout.addRow("Name:", self.nameField) 82 | layout.addRow("Job:", self.jobField) 83 | layout.addRow("Email:", self.emailField) 84 | self.layout.addLayout(layout) 85 | # Add standard buttons to the dialog and connect them 86 | self.buttonsBox = QDialogButtonBox(self) 87 | self.buttonsBox.setOrientation(Qt.Horizontal) 88 | self.buttonsBox.setStandardButtons( 89 | QDialogButtonBox.Ok | QDialogButtonBox.Cancel 90 | ) 91 | self.buttonsBox.accepted.connect(self.accept) 92 | self.buttonsBox.rejected.connect(self.reject) 93 | self.layout.addWidget(self.buttonsBox) 94 | 95 | def accept(self): 96 | """Accept the data provided through the dialog.""" 97 | self.data = [] 98 | for field in (self.nameField, self.jobField, self.emailField): 99 | if not field.text(): 100 | QMessageBox.critical( 101 | self, 102 | "Error!", 103 | f"You must provide a contact's {field.objectName()}", 104 | ) 105 | self.data = None # Reset .data 106 | return 107 | 108 | self.data.append(field.text()) 109 | 110 | if not self.data: 111 | return 112 | 113 | super().accept() 114 | 115 | def openAddDialog(self): 116 | """Open the Add Contact dialog.""" 117 | dialog = AddDialog(self) 118 | if dialog.exec() == QDialog.Accepted: 119 | self.contactsModel.addContact(dialog.data) 120 | self.table.resizeColumnsToContents() 121 | 122 | def deleteContact(self): 123 | """Delete the selected contact from the database.""" 124 | row = self.table.currentIndex().row() 125 | if row < 0: 126 | return 127 | 128 | messageBox = QMessageBox.warning( 129 | self, 130 | "Warning!", 131 | "Do you want to remove the selected contact?", 132 | QMessageBox.Ok | QMessageBox.Cancel, 133 | ) 134 | 135 | if messageBox == QMessageBox.Ok: 136 | self.contactsModel.deleteContact(row) 137 | 138 | def clearContacts(self): 139 | """Remove all contacts from the database.""" 140 | messageBox = QMessageBox.warning( 141 | self, 142 | "Warning!", 143 | "Do you want to remove all your contacts?", 144 | QMessageBox.Ok | QMessageBox.Cancel, 145 | ) 146 | 147 | if messageBox == QMessageBox.Ok: 148 | self.contactsModel.clearContacts() 149 | -------------------------------------------------------------------------------- /mp3-player-gui/main.py: -------------------------------------------------------------------------------- 1 | import tkinter 2 | from mutagen.easyid3 import EasyID3 3 | import pygame 4 | from tkinter.filedialog import askopenfilenames 5 | 6 | 7 | class FrameApp(tkinter.Frame): 8 | def __init__(self, master): 9 | super(FrameApp, self).__init__(master) 10 | 11 | self.grid() 12 | self.paused = False 13 | self.playlist = list() 14 | self.actual_song = 0 15 | 16 | self.b1 = tkinter.Button( 17 | self, 18 | text="PLAY SONG", 19 | command=self.play_music, 20 | bg="AntiqueWhite1", 21 | width=40, 22 | ) 23 | self.b1.grid(row=2, column=0) 24 | 25 | self.b2 = tkinter.Button( 26 | self, 27 | text="PREVIOUS SONG", 28 | command=self.previous_song, 29 | bg="AntiqueWhite1", 30 | width=40, 31 | ) 32 | self.b2.grid(row=4, column=0) 33 | 34 | self.b3 = tkinter.Button( 35 | self, 36 | text="PAUSE/UNPAUSE", 37 | command=self.toggle, 38 | bg="AntiqueWhite1", 39 | width=40, 40 | ) 41 | self.b3.grid(row=3, column=0) 42 | 43 | self.b4 = tkinter.Button( 44 | self, text="NEXT SONG", command=self.next_song, bg="AntiqueWhite1", width=40 45 | ) 46 | self.b4.grid(row=5, column=0) 47 | 48 | self.b5 = tkinter.Button( 49 | self, 50 | text="ADD TO PLAYLIST", 51 | command=self.add_to_list, 52 | bg="AntiqueWhite1", 53 | width=40, 54 | ) 55 | self.b5.grid(row=1, column=0) 56 | 57 | self.label1 = tkinter.Label( 58 | self, fg="Black", font=("Helvetica 12 bold italic", 10), bg="ivory2" 59 | ) 60 | self.label1.grid(row=6, column=0) 61 | 62 | self.output = tkinter.Text(self, wrap=tkinter.WORD, width=60) 63 | self.output.grid(row=8, column=0) 64 | 65 | self.SONG_END = pygame.USEREVENT + 1 66 | 67 | def add_to_list(self) -> None: 68 | """ 69 | Opens window to browse data on disk and adds selected songs to play list 70 | """ 71 | directory = askopenfilenames() 72 | for song_dir in directory: 73 | print(song_dir) 74 | self.playlist.append(song_dir) 75 | self.output.delete(0.0, tkinter.END) 76 | 77 | for key, item in enumerate(self.playlist): 78 | song = EasyID3(item) 79 | song_data = ( 80 | str(key + 1) + " : " + song["title"][0] + " - " + song["artist"][0] 81 | ) 82 | self.output.insert(tkinter.END, song_data + "\n") 83 | 84 | def song_data(self) -> str: 85 | """ 86 | Makes string of current playing song data over the text box 87 | """ 88 | song = EasyID3(self.playlist[self.actual_song]) 89 | return f"Now playing: {self.actual_song + 1}{str(song['title'])}-{str(song['artist'])}" 90 | 91 | def play_music(self) -> None: 92 | """ 93 | Loads current song, plays it, sets event on song finish 94 | """ 95 | directory = self.playlist[self.actual_song] 96 | pygame.mixer.music.load(directory) 97 | pygame.mixer.music.play(1, 0.0) 98 | pygame.mixer.music.set_endevent(self.SONG_END) 99 | self.paused = False 100 | self.label1["text"] = self.song_data() 101 | 102 | def check_music(self) -> None: 103 | """ 104 | Listens to END_MUSIC event and triggers next song to play if current 105 | song has finished 106 | """ 107 | for event in pygame.event.get(): 108 | if event.type == self.SONG_END: 109 | self.next_song() 110 | 111 | def toggle(self) -> None: 112 | """ 113 | Toggles current song 114 | """ 115 | if self.paused: 116 | pygame.mixer.music.unpause() 117 | self.paused = False 118 | elif not self.paused: 119 | pygame.mixer.music.pause() 120 | self.paused = True 121 | 122 | def get_next_song(self) -> int: 123 | """ 124 | Gets next song number on playlist 125 | """ 126 | if self.actual_song + 2 <= len(self.playlist): 127 | return self.actual_song + 1 128 | else: 129 | return 0 130 | 131 | def next_song(self) -> None: 132 | """ 133 | Plays next song 134 | """ 135 | self.actual_song = self.get_next_song() 136 | self.play_music() 137 | 138 | def get_previous_song(self) -> int: 139 | """ 140 | Gets previous song number on playlist and returns it 141 | """ 142 | if self.actual_song - 1 >= 0: 143 | return self.actual_song - 1 144 | else: 145 | return len(self.playlist) - 1 146 | 147 | def previous_song(self) -> None: 148 | """ 149 | Plays prevoius song 150 | """ 151 | self.actual_song = self.get_previous_song() 152 | self.play_music() 153 | 154 | 155 | pygame.init() 156 | window = tkinter.Tk() 157 | 158 | window.geometry("500x500") 159 | window.title("MP3 Music Player") 160 | 161 | 162 | app = FrameApp(window) 163 | 164 | if __name__ == "__main__": 165 | while True: 166 | app.check_music() 167 | app.update() 168 | --------------------------------------------------------------------------------