├── .gitignore
├── Automated_Emails
├── .idea
│ ├── .gitignore
│ ├── Automated_Emails.iml
│ ├── inspectionProfiles
│ │ └── profiles_settings.xml
│ ├── misc.xml
│ ├── modules.xml
│ └── vcs.xml
├── design.txt
├── main.py
├── news.py
└── people.xlsx
├── Calorie_Webapp
├── .idea
│ ├── .gitignore
│ ├── Calorie_Webapp.iml
│ ├── inspectionProfiles
│ │ └── profiles_settings.xml
│ ├── misc.xml
│ ├── modules.xml
│ └── vcs.xml
├── calorie.py
├── design.txt
├── main.py
├── static
│ └── main.css
├── temperature.py
└── templates
│ ├── calories_form_page.html
│ └── index.html
├── Cinema_Ticket_Booking
├── banking.db
├── cinema.db
├── design.txt
└── main.py
├── Flatmates_Bill
├── .idea
│ ├── .gitignore
│ ├── Flatmates_Bill.iml
│ ├── inspectionProfiles
│ │ └── profiles_settings.xml
│ ├── misc.xml
│ ├── modules.xml
│ └── vcs.xml
├── flatmates_bill
│ ├── files
│ │ ├── design.txt
│ │ └── house.png
│ ├── flat.py
│ ├── main.py
│ └── reports.py
├── main.py
├── static
│ ├── bill_form.css
│ ├── home.css
│ └── results.css
└── templates
│ ├── bill_form_page.html
│ ├── index.html
│ └── results.html
├── Geometry_Game
├── .idea
│ ├── .gitignore
│ ├── Geometry_Game.iml
│ ├── inspectionProfiles
│ │ └── profiles_settings.xml
│ ├── misc.xml
│ ├── modules.xml
│ └── vcs.xml
├── design.txt
└── main.py
├── Instant_Dictionary_API
├── .idea
│ ├── .gitignore
│ ├── Instant_Dictionary_API.iml
│ ├── inspectionProfiles
│ │ └── profiles_settings.xml
│ ├── misc.xml
│ ├── modules.xml
│ └── vcs.xml
├── api.py
├── data.csv
├── definition.py
├── documentation.py
└── main.py
├── Instant_Dictionary_Webapp
├── .idea
│ ├── .gitignore
│ ├── Instant_Dictionary_Webapp.iml
│ ├── inspectionProfiles
│ │ └── profiles_settings.xml
│ ├── misc.xml
│ ├── modules.xml
│ └── vcs.xml
├── data.csv
├── definition.py
├── design
│ ├── about.png
│ ├── design.txt
│ ├── dictionary.png
│ └── home.png
├── examples
│ ├── file.html
│ └── main.py
├── main.py
└── webapp
│ ├── about.py
│ ├── dictionary.py
│ ├── home.py
│ ├── layout.py
│ ├── navbar.py
│ └── page.py
├── Math_Painting
├── .idea
│ ├── .gitignore
│ ├── Math_Painting.iml
│ ├── inspectionProfiles
│ │ └── profiles_settings.xml
│ ├── misc.xml
│ ├── modules.xml
│ └── vcs.xml
├── canvas.py
├── design.txt
├── main.py
└── shapes.py
├── Photo_Searcher
├── .idea
│ ├── .gitignore
│ ├── Photo_Searcher.iml
│ ├── inspectionProfiles
│ │ └── profiles_settings.xml
│ ├── misc.xml
│ ├── modules.xml
│ └── vcs.xml
├── frontend.kv
└── main.py
├── README.md
└── Webcam_Photo_Sharer
├── .idea
├── .gitignore
├── Webcam_Photo_Sharer.iml
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
└── vcs.xml
├── design-frontend.png
├── design.txt
├── filesharer.py
├── frontend.kv
├── images
├── down.png
└── normal.png
└── main.py
/.gitignore:
--------------------------------------------------------------------------------
1 | venv
2 | __pycache__
3 |
4 | Flatmates_Bill/files/*.pdf
5 | Flatmates_Bill/flatmates_bill/files/*.pdf
6 |
7 | Math_Painting/*.png
8 |
9 | Photo_Searcher/files/*.png
10 | Photo_Searcher/files/*.jpg
11 |
12 | Webcam_Photo_Sharer/files/*.png
--------------------------------------------------------------------------------
/Automated_Emails/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/Automated_Emails/.idea/Automated_Emails.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Automated_Emails/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Automated_Emails/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Automated_Emails/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Automated_Emails/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Automated_Emails/design.txt:
--------------------------------------------------------------------------------
1 | Title: Automated Emails
2 |
3 | Description: An app that reads user names, email addresses, and interests
4 | from an Excel file and sends an email to each user with news feeds about the
5 | user's interest every morning.
6 |
7 | Objects: ExcelFile:
8 | file_path
9 | get_data()
10 | Email:
11 | sender
12 | receiver
13 | subject
14 | body
15 | send()
16 | NewsFeed:
17 | data()
18 | get()
19 |
--------------------------------------------------------------------------------
/Automated_Emails/main.py:
--------------------------------------------------------------------------------
1 | import time
2 |
3 | import yagmail
4 | import pandas
5 | from news import NewsFeed
6 | import datetime
7 |
8 |
9 | def send_email():
10 | today = datetime.datetime.now()
11 | news_feed = NewsFeed(interest=row['interest'],
12 | from_date=(today - datetime.timedelta(days=1)).strftime("%Y-%m-%d"),
13 | to_date=today.strftime("%Y-%m-%d"))
14 | email = yagmail.SMTP(user="pythonprocourse1@gmail.com",
15 | password="python_pro_course_1")
16 | email.send(to=row['email'],
17 | subject=f"Your {row['interest']} news for today!",
18 | contents=f"Hi {row['name']},\n See what's on about {row['interest']} today.\n{news_feed.get()}")
19 |
20 |
21 | while True:
22 | if datetime.datetime.now().hour == 17 and datetime.datetime.now().minute == 51:
23 | df = pandas.read_excel("people.xlsx")
24 |
25 | for index, row in df.iterrows():
26 | send_email()
27 |
28 | time.sleep(60)
29 |
--------------------------------------------------------------------------------
/Automated_Emails/news.py:
--------------------------------------------------------------------------------
1 | import requests
2 |
3 |
4 | class NewsFeed:
5 | """Representing multiple news titles and links as a single string
6 | """
7 | base_url = "https://newsapi.org/v2/everything?"
8 | api_key = "a9c14d7269894d69bc39c744037fa4ca"
9 |
10 | def __init__(self, interest, from_date, to_date, language="en"):
11 | self.language = language
12 | self.to_date = to_date
13 | self.from_date = from_date
14 | self.interest = interest
15 |
16 | def get(self):
17 | url = self._build_url()
18 |
19 | articles = self._get_articles(url)
20 |
21 | email_body = ""
22 | for article in articles:
23 | email_body += article['title'] + "\n" + article['url'] + "\n\n"
24 |
25 | return email_body
26 |
27 | def _get_articles(self, url):
28 | response = requests.get(url)
29 | content = response.json()
30 | articles = content['articles']
31 | return articles
32 |
33 | def _build_url(self):
34 | url = f"{self.base_url}qInTitle={self.interest}&from={self.from_date}&to={self.to_date}&language={self.language}&apiKey={self.api_key}"
35 | return url
36 |
37 |
38 | if __name__ == "__main__":
39 | news_feed = NewsFeed(interest="nasa", from_date="2023-10-14", to_date="2023-10-15", language="en")
40 | print(news_feed.get())
41 |
--------------------------------------------------------------------------------
/Automated_Emails/people.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pxxthik/Python-OOP-Projects/82d30e657eccc66e211f3c414645d88d3a2b80d0/Automated_Emails/people.xlsx
--------------------------------------------------------------------------------
/Calorie_Webapp/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/Calorie_Webapp/.idea/Calorie_Webapp.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Calorie_Webapp/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Calorie_Webapp/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Calorie_Webapp/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Calorie_Webapp/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Calorie_Webapp/calorie.py:
--------------------------------------------------------------------------------
1 | from temperature import Temperature
2 |
3 |
4 | class Calorie:
5 | """Represent amount of calories calculated with
6 | BMR = 10*weight + 6.25*height - 5*age - 10*temperature
7 | """
8 |
9 | def __init__(self, weight, height, age, temperature):
10 | self.temperature = temperature
11 | self.age = age
12 | self.height = height
13 | self.weight = weight
14 |
15 | def calculate(self):
16 | result = 10 * self.weight + 6.5 * self.height + 5*self.age - self.temperature * 10
17 | return result
18 |
19 |
20 | if __name__ == "__main__":
21 | temperature = Temperature(city='rome', country='italy').get()
22 | calorie = Calorie(temperature=temperature, weight=70, height=175, age=32)
23 | print(calorie.calculate())
24 |
--------------------------------------------------------------------------------
/Calorie_Webapp/design.txt:
--------------------------------------------------------------------------------
1 | Title: Calorie Calculator
2 |
3 | Description: An app that gets from the user's weight, height,
4 | age, city and country, and scrapes the temperature of the user's location,
5 | and calculates how many calories the user needs.
6 |
7 | Objects: Calorie:
8 | weight
9 | height
10 | age
11 | temperature
12 | calculate()
13 | Temperature:
14 | country
15 | city
16 | get()
--------------------------------------------------------------------------------
/Calorie_Webapp/main.py:
--------------------------------------------------------------------------------
1 | from flask.views import MethodView
2 | from wtforms import Form, StringField, SubmitField
3 | from flask import Flask, render_template, request
4 | from calorie import Calorie
5 | from temperature import Temperature
6 |
7 | app = Flask(__name__)
8 |
9 |
10 | class HomePage(MethodView):
11 |
12 | def get(self):
13 | return render_template('index.html')
14 |
15 |
16 | class CaloriesFormPage(MethodView):
17 |
18 | def get(self):
19 | calories_form = CaloriesForm()
20 |
21 | return render_template('calories_form_page.html',
22 | calories_form=calories_form)
23 |
24 | def post(self):
25 | calories_form = CaloriesForm(request.form)
26 |
27 | temperature = Temperature(country=calories_form.country.data,
28 | city=calories_form.city.data).get()
29 |
30 | calorie = Calorie(weight=float(calories_form.weight.data),
31 | height=float(calories_form.height.data),
32 | age=float(calories_form.age.data),
33 | temperature=temperature)
34 |
35 | calories = calorie.calculate()
36 |
37 | return render_template('calories_form_page.html',
38 | calories_form=calories_form,
39 | calories=calories,
40 | result=True)
41 |
42 |
43 | class CaloriesForm(Form):
44 | weight = StringField("Weight: ", default=70)
45 | height = StringField("Height: ", default=175)
46 | age = StringField("Age: ", default=32)
47 | country = StringField("Country: ", default="USA")
48 | city = StringField("City: ", default="San Francisco")
49 | button = SubmitField("Calculate")
50 |
51 |
52 | app.add_url_rule('/', view_func=HomePage.as_view("home_page"))
53 | app.add_url_rule('/calories_form', view_func=CaloriesFormPage.as_view("calories_form_page"))
54 |
55 | app.run(debug=True)
56 |
--------------------------------------------------------------------------------
/Calorie_Webapp/static/main.css:
--------------------------------------------------------------------------------
1 | h2{
2 | color: darkgrey;
3 | text-align: center;
4 | font-size: 50px;
5 | }
6 |
7 | input[type=text] {
8 | width: 100%;
9 | padding: 8px 8px;
10 | margin: 10px 0;
11 | }
12 |
13 | input[type=submit], a{
14 | width: 100%;
15 | background-color: YellowGreen;
16 | color: white;
17 | padding: 12px 12px;
18 | border: none;
19 | border-radius: 6px;
20 | cursor: pointer;
21 | text-decoration: none;
22 | }
23 |
24 | body{
25 | background-color: black;
26 | color: white;
27 | padding: 20px;
28 | }
--------------------------------------------------------------------------------
/Calorie_Webapp/temperature.py:
--------------------------------------------------------------------------------
1 | class Temperature:
2 | """
3 | Represents a temperature value extracted from the timeanddate.com/weather webpage.
4 | """
5 |
6 | def __init__(self, country, city):
7 | self.city = city
8 | self.country = country
9 |
10 | def get(self):
11 | # code for web scraping
12 |
13 | return float(18)
14 |
15 |
16 | if __name__ == "__main__":
17 | temperature = Temperature(country='usa', city='san francisco')
18 | print(temperature.get())
19 |
--------------------------------------------------------------------------------
/Calorie_Webapp/templates/calories_form_page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
9 | Calories Calculation Form
10 | Fill in the form and click the button to know how many calories you need!
11 |
12 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Calorie_Webapp/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
9 | Calories Calculation
10 | This web app is useful to calculate how many calories you should take today.
11 | Go to calculation page
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Cinema_Ticket_Booking/banking.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pxxthik/Python-OOP-Projects/82d30e657eccc66e211f3c414645d88d3a2b80d0/Cinema_Ticket_Booking/banking.db
--------------------------------------------------------------------------------
/Cinema_Ticket_Booking/cinema.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pxxthik/Python-OOP-Projects/82d30e657eccc66e211f3c414645d88d3a2b80d0/Cinema_Ticket_Booking/cinema.db
--------------------------------------------------------------------------------
/Cinema_Ticket_Booking/design.txt:
--------------------------------------------------------------------------------
1 | Title: Cinema Ticket Booking
2 |
3 | Description: An app where a user can book a cinema seat
4 | if the seat is free and if the user has balance in their card.
5 | The app generates a pdf ticket if the purchase is successful.
6 |
7 | Objects: User, Seat, Card, Ticket
8 | User:
9 | name
10 | buy(seat, card)
11 | Seat:
12 | database
13 | seat_id
14 | price
15 | availability
16 | is_free()
17 | occupy()
18 | Card:
19 | database
20 | type
21 | number
22 | cvc
23 | holder
24 | validate(price)
25 | Ticket:
26 | id
27 | user
28 | price
29 | seat
30 | to_pdf(path)
--------------------------------------------------------------------------------
/Cinema_Ticket_Booking/main.py:
--------------------------------------------------------------------------------
1 | from fpdf import FPDF
2 | import random
3 | import string
4 | import sqlite3
5 |
6 |
7 | class User:
8 | """Represents a user that can buy a cinema Seat"""
9 |
10 | def __init__(self, name):
11 | self.name = name
12 |
13 | def buy(self, seat, card):
14 | """Buys the ticket if the card is valid"""
15 | if seat.is_free():
16 | if card.validate(price=seat.get_price()):
17 | seat.occupy()
18 | ticket = Ticket(user=self, price=seat.get_price(), seat_number=seat.seat_id)
19 | ticket.to_pdf()
20 | return "Purchase Successful!"
21 | else:
22 | return "There was a problem with your card!"
23 | else:
24 | return "Seat is taken!"
25 |
26 |
27 | class Seat:
28 | """Represents a cinema seat that can be taken from a User"""
29 |
30 | database = 'cinema.db'
31 |
32 | def __init__(self, seat_id):
33 | self.seat_id = seat_id
34 |
35 | def get_price(self):
36 | """Get the price of the certain seat"""
37 | connection = sqlite3.connect(self.database)
38 | cursor = connection.cursor()
39 | cursor.execute("""
40 | SELECT "price" FROM "Seat" WHERE "seat_id" = ?
41 | """, [self.seat_id])
42 | price = cursor.fetchall()[0][0]
43 |
44 | return price
45 |
46 | def is_free(self):
47 | """Check in the database if a seat is taken or not"""
48 | connection = sqlite3.connect(self.database)
49 | cursor = connection.cursor()
50 | cursor.execute("""
51 | SELECT "taken" FROM "Seat" WHERE "seat_id" = ?
52 | """, [self.seat_id])
53 | result = cursor.fetchall()[0][0]
54 |
55 | if result == 0:
56 | return True
57 | else:
58 | return False
59 |
60 | def occupy(self):
61 | """Change value of taken in the database from 0 to 1 if seat is free"""
62 | if self.is_free():
63 | connection = sqlite3.connect(self.database)
64 | connection.execute("""
65 | UPDATE "Seat" SET "taken"=? WHERE "seat_id"=?
66 | """, [1, self.seat_id])
67 | connection.commit()
68 | connection.close()
69 |
70 |
71 | class Card:
72 | """Represents a bank card needed to finalize a seat purchase"""
73 |
74 | database = 'banking.db'
75 |
76 | def __init__(self, type, number, cvc, holder):
77 | self.holder = holder
78 | self.cvc = cvc
79 | self.number = number
80 | self.type = type
81 |
82 | def validate(self, price):
83 | """Checks if card is valid and has balance.
84 | Subtracts price from balance.
85 | """
86 | connection = sqlite3.connect(self.database)
87 | cursor = connection.cursor()
88 | cursor.execute("""
89 | SELECT "balance" FROM "Card" WHERE "number"=? and "cvc"=?
90 | """, [self.number, self.cvc])
91 | result = cursor.fetchall()
92 |
93 | if result:
94 | balance = result[0][0]
95 | if balance >= price:
96 | connection.execute("""
97 | UPDATE "Card" SET "balance"=? WHERE "number"=? and "cvc"=?
98 | """, [balance - price, self.number, self.cvc])
99 | connection.commit()
100 | connection.close()
101 | return True
102 |
103 |
104 | class Ticket:
105 | """Represents a cinema Ticket purchased by a user"""
106 |
107 | def __init__(self, user, price, seat_number):
108 | self.seat_number = seat_number
109 | self.price = price
110 | self.id = "".join([random.choice(string.ascii_letters) for i in range(8)])
111 | self.user = user
112 |
113 | def to_pdf(self):
114 | """Creates a pdf ticket"""
115 | pdf = FPDF(orientation="P", unit='pt', format='A4')
116 | pdf.add_page()
117 |
118 | pdf.set_font(family="Times", style="B", size=24)
119 | pdf.cell(w=0, h=80, txt="Your Digital Ticket", border=1, ln=1, align="C")
120 |
121 | pdf.set_font(family="Times", style="B", size=14)
122 | pdf.cell(w=100, h=25, txt="Name: ", border=1)
123 | pdf.set_font(family="Times", style="B", size=12)
124 | pdf.cell(w=0, h=25, txt=self.user.name, border=1, ln=1)
125 | pdf.cell(w=0, h=5, txt="", border=0, ln=1)
126 |
127 | pdf.set_font(family="Times", style="B", size=14)
128 | pdf.cell(w=100, h=25, txt="Ticket ID: ", border=1)
129 | pdf.set_font(family="Times", style="B", size=12)
130 | pdf.cell(w=0, h=25, txt=self.id, border=1, ln=1)
131 | pdf.cell(w=0, h=5, txt="", border=0, ln=1)
132 |
133 | pdf.set_font(family="Times", style="B", size=14)
134 | pdf.cell(w=100, h=25, txt="Price: ", border=1)
135 | pdf.set_font(family="Times", style="B", size=12)
136 | pdf.cell(w=0, h=25, txt=str(self.price), border=1, ln=1)
137 | pdf.cell(w=0, h=5, txt="", border=0, ln=1)
138 |
139 | pdf.set_font(family="Times", style="B", size=14)
140 | pdf.cell(w=100, h=25, txt="Seat No: ", border=1)
141 | pdf.set_font(family="Times", style="B", size=12)
142 | pdf.cell(w=0, h=25, txt=str(self.seat_number), border=1, ln=1)
143 | pdf.cell(w=0, h=5, txt="", border=0, ln=1)
144 |
145 | pdf.output("sample.pdf")
146 |
147 |
148 | if __name__ == "__main__":
149 | name = input("Your full name: ")
150 | seat_id = input("Preferred seat no: ")
151 | card_type = input("Your card type: ")
152 | card_number = input("Your card number: ")
153 | card_cvc = input("Your card cvc: ")
154 | card_holder = input("Card holder name: ")
155 |
156 | user = User(name=name)
157 | seat = Seat(seat_id=seat_id)
158 | card = Card(type=card_type, number=card_number, cvc=card_cvc, holder=card_holder)
159 |
160 | print(user.buy(seat=seat, card=card))
161 |
--------------------------------------------------------------------------------
/Flatmates_Bill/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/Flatmates_Bill/.idea/Flatmates_Bill.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Flatmates_Bill/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Flatmates_Bill/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Flatmates_Bill/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Flatmates_Bill/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Flatmates_Bill/flatmates_bill/files/design.txt:
--------------------------------------------------------------------------------
1 | Title: Flatmates Bill
2 |
3 | Description: An app that gets as input the amount of a bill for a particular
4 | period and the days that each of the flatmates stayed in the house for that
5 | period and returns how much each flatmate has to pay. It also generates a
6 | PDF report stating the names of the flatmates, the period and how much each
7 | of them had to pay.
8 |
9 | Objects: Bill:
10 | amount
11 | period
12 | Flatmate:
13 | name
14 | days_in_house
15 | pays(bill)
16 | PdfReport:
17 | filename
18 | generate(flatmate1, flatmate2, bill)
--------------------------------------------------------------------------------
/Flatmates_Bill/flatmates_bill/files/house.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pxxthik/Python-OOP-Projects/82d30e657eccc66e211f3c414645d88d3a2b80d0/Flatmates_Bill/flatmates_bill/files/house.png
--------------------------------------------------------------------------------
/Flatmates_Bill/flatmates_bill/flat.py:
--------------------------------------------------------------------------------
1 | class Bill:
2 | """
3 | Object that contains data about a bill, such as
4 | total amount and period of the bill.
5 | """
6 |
7 | def __init__(self, amount, period):
8 | self.amount = amount
9 | self.period = period
10 |
11 |
12 | class Flatmate:
13 | """
14 | Creates a flatmate person who lives in the flat
15 | and pays a share of the bill.
16 | """
17 |
18 | def __init__(self, name, days_in_house):
19 | self.name = name
20 | self.days_in_house = days_in_house
21 |
22 | def pays(self, bill, flatmate2):
23 | weight = self.days_in_house / (self.days_in_house + flatmate2.days_in_house)
24 | to_pay = bill.amount * weight
25 | return to_pay
26 |
--------------------------------------------------------------------------------
/Flatmates_Bill/flatmates_bill/main.py:
--------------------------------------------------------------------------------
1 | from flat import Bill, Flatmate
2 | from reports import PdfReport, FileSharer
3 |
4 | amount = float(input("Hey user, enter the bill amount: "))
5 | period = input("What is the bill period? E.g. December 2020: ")
6 |
7 | name1 = input("What is your name? ")
8 | days_in_house1 = int(input("How many days did {} stay in the house during the bill period? ".format(name1)))
9 |
10 | name2 = input("What is the name of other flatmate? ")
11 | days_in_house2 = int(input("How many days did {} stay in the house during the bill period? ".format(name2)))
12 |
13 | the_bill = Bill(amount, period)
14 | flatmate1 = Flatmate(name1, days_in_house1)
15 | flatmate2 = Flatmate(name2, days_in_house2)
16 |
17 | print(f"{flatmate1.name} pays: ", flatmate1.pays(the_bill, flatmate2))
18 | print(f"{flatmate2.name} pays: ", flatmate2.pays(the_bill, flatmate1))
19 |
20 | pdf_report = PdfReport(filename=f'{the_bill.period}.pdf')
21 | pdf_report.generate(flatmate1, flatmate2, the_bill)
22 |
23 | file_sharer = FileSharer(filepath=pdf_report.filename)
24 | print(file_sharer.share())
--------------------------------------------------------------------------------
/Flatmates_Bill/flatmates_bill/reports.py:
--------------------------------------------------------------------------------
1 | import webbrowser
2 | import os
3 |
4 | from fpdf import FPDF
5 | from filestack import Client
6 |
7 |
8 | class PdfReport:
9 | """
10 | Creates a pdf file that contains data about
11 | the flatmates such as their names, their due
12 | amounts and the period of the bill.
13 | """
14 |
15 | def __init__(self, filename):
16 | self.filename = filename
17 |
18 | def generate(self, flatmate1, flatmate2, bill):
19 | flatmate1_pay = str(round(flatmate1.pays(bill, flatmate2), 2))
20 | flatmate2_pay = str(round(flatmate2.pays(bill, flatmate1), 2))
21 |
22 | pdf = FPDF(orientation='P', unit='pt', format='A4')
23 | pdf.add_page()
24 |
25 | # Add icon
26 | pdf.image("files/house.png", w=30, h=30)
27 |
28 | # Insert title
29 | pdf.set_font(family='Times', size=24, style='B')
30 | pdf.cell(w=0, h=80, txt='Flatmates Bill', border=0, align='C', ln=1)
31 |
32 | # Insert Period label and value
33 | pdf.set_font(family='Times', size=14, style='B')
34 | pdf.cell(w=100, h=40, txt='Period:', border=0)
35 | pdf.cell(w=150, h=40, txt=bill.period, border=0, ln=1)
36 |
37 | # Insert name and due amount of the first flatmate
38 | pdf.set_font(family='Times', size=12)
39 | pdf.cell(w=100, h=25, txt=flatmate1.name, border=0)
40 | pdf.cell(w=150, h=25, txt=flatmate1_pay, border=0, ln=1)
41 |
42 | # Insert name and due amount of the second flatmate
43 | pdf.cell(w=100, h=25, txt=flatmate2.name, border=0)
44 | pdf.cell(w=150, h=25, txt=flatmate2_pay, border=0, ln=1)
45 |
46 | # Change directory to files, generates and opens the pdf
47 | os.chdir('files')
48 | pdf.output(self.filename)
49 | webbrowser.open(self.filename)
50 |
51 |
52 | class FileSharer:
53 | """
54 | Uploads the generated pdf to online and gives the link
55 | to access the pdf.
56 | """
57 |
58 | def __init__(self, filepath, api_key='Aj799wiBlScSabXEs3WqDz'):
59 | self.filepath = filepath
60 | self.api_key = api_key
61 |
62 | def share(self):
63 | client = Client(self.api_key)
64 | new_filelink = client.upload(filepath=self.filepath)
65 | return new_filelink.url
66 |
--------------------------------------------------------------------------------
/Flatmates_Bill/main.py:
--------------------------------------------------------------------------------
1 | from flask.views import MethodView
2 | from wtforms import Form, StringField, SubmitField
3 | from flask import Flask, render_template, request
4 |
5 | from flatmates_bill import flat
6 |
7 | app = Flask(__name__)
8 |
9 |
10 | class HomePage(MethodView):
11 |
12 | def get(self):
13 | return render_template('index.html')
14 |
15 |
16 | class BillFormPage(MethodView):
17 |
18 | def get(self):
19 | bill_form = BillForm()
20 | return render_template('bill_form_page.html', bill_form=bill_form)
21 |
22 |
23 | class ResultsPage(MethodView):
24 |
25 | def post(self):
26 | bill_form = BillForm(request.form)
27 |
28 | the_bill = flat.Bill(float(bill_form.amount.data), bill_form.period.data)
29 | flatmate1 = flat.Flatmate(bill_form.name1.data, float(bill_form.days_in_house1.data))
30 | flatmate2 = flat.Flatmate(bill_form.name2.data, float(bill_form.days_in_house2.data))
31 |
32 | return render_template("results.html",
33 | name1=flatmate1.name,
34 | amount1=flatmate1.pays(the_bill, flatmate2),
35 | name2=flatmate2.name,
36 | amount2=flatmate2.pays(the_bill, flatmate1))
37 |
38 |
39 | class BillForm(Form):
40 | amount = StringField("Bill Amount: ", default=100)
41 | period = StringField("Bill Period: ", default="December 2020")
42 |
43 | name1 = StringField("Name: ", default="John")
44 | days_in_house1 = StringField("Days in the house: ", default=20)
45 |
46 | name2 = StringField("Name: ", default="Marry")
47 | days_in_house2 = StringField("Days in the house: ", default=12)
48 |
49 | button = SubmitField("Calculate")
50 |
51 |
52 | app.add_url_rule('/', view_func=HomePage.as_view('home_page'))
53 | app.add_url_rule('/bill', view_func=BillFormPage.as_view('bill_form_page'))
54 | app.add_url_rule('/results', view_func=ResultsPage.as_view('result_page'))
55 |
56 | app.run(debug=True)
57 |
--------------------------------------------------------------------------------
/Flatmates_Bill/static/bill_form.css:
--------------------------------------------------------------------------------
1 | h2{
2 | color: darkgrey;
3 | text-align: center;
4 | font-size: 50px;
5 | }
6 |
7 | input[type=text]{
8 | width: 100%;
9 | padding: 8px 8px;
10 | margin: 10px 0;
11 | }
12 |
13 | input[type=submit]{
14 | width: 100%;
15 | background-color: YellowGreen;
16 | color: white;
17 | padding: 12px 12px;
18 | border: none;
19 | border-radius: 6px;
20 | cursor: pointer;
21 | }
22 |
23 | body{
24 | background-color: GhostWhite;
25 | padding: 20px;
26 | }
--------------------------------------------------------------------------------
/Flatmates_Bill/static/home.css:
--------------------------------------------------------------------------------
1 | h2{
2 | color: darkgrey;
3 | text-align: center;
4 | font-size: 50px;
5 | }
6 |
7 | body{
8 | background-color: GhostWhite;
9 | padding: 20px;
10 | }
11 |
12 | body a{
13 | width: 100%;
14 | background-color: YellowGreen;
15 | color: white;
16 | padding: 12px 12px;
17 | border: none;
18 | border-radius: 6px;
19 | text-decoration: none;
20 | }
--------------------------------------------------------------------------------
/Flatmates_Bill/static/results.css:
--------------------------------------------------------------------------------
1 | body{
2 | background-color: GhostWhite;
3 | padding: 20px;
4 | }
--------------------------------------------------------------------------------
/Flatmates_Bill/templates/bill_form_page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
9 | The Bill Form
10 | Fill in the form and click the button to get the results
11 |
30 |
31 |
--------------------------------------------------------------------------------
/Flatmates_Bill/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
9 | Flatmates bill
10 | This web app is useful to split a bill between two flatmates.
11 | Go to the bill page
12 |
13 |
--------------------------------------------------------------------------------
/Flatmates_Bill/templates/results.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
9 | {{name1}} pays: {{amount1}}
10 | {{name2}} pays: {{amount2}}
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Geometry_Game/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/Geometry_Game/.idea/Geometry_Game.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Geometry_Game/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Geometry_Game/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Geometry_Game/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Geometry_Game/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Geometry_Game/design.txt:
--------------------------------------------------------------------------------
1 | Title: Geometry Game
2 |
3 | Description: An app that generates a rectangle with random coordinates and asks user to guess any random
4 | point (x and y) and to guess the area of rectangle and tells how off the actual area of rectangle by our guess
5 | and also draw the rectangle and point in GUI.
6 |
7 | Objects: Point:
8 | x
9 | y
10 | falls_in_rectangle(Rectangle)
11 | Rectangle:
12 | point1
13 | point2
14 | area()
15 | GuiRectangle(Rectangle):
16 | draw(canvas)
17 | GuiPoint(Rectangle):
18 | draw(canvas)
--------------------------------------------------------------------------------
/Geometry_Game/main.py:
--------------------------------------------------------------------------------
1 | from random import randint
2 | import turtle
3 |
4 |
5 | class Point:
6 | """
7 | Class that contain x and y coordinates of a point and tells
8 | the point falls in given rectangle or not.
9 | """
10 |
11 | def __init__(self, x, y):
12 | self.x = x
13 | self.y = y
14 |
15 | def falls_in_rectangle(self, rectangle_area):
16 | return rectangle_area.point1.x < self.x < rectangle_area.point2.x \
17 | and rectangle_area.point1.y < self.y < rectangle_area.point2.y
18 |
19 |
20 | class Rectangle:
21 | """
22 | Class that contains lower left point (point1) and upper right
23 | (point2) of a rectangle and returns the area of rectangle.
24 | """
25 |
26 | def __init__(self, point1, point2):
27 | self.point1 = point1
28 | self.point2 = point2
29 |
30 | def area(self):
31 | return (self.point2.x - self.point1.x) * \
32 | (self.point2.y - self.point1.y)
33 |
34 |
35 | class GuiRectangle(Rectangle):
36 | """
37 | Child of Rectangle class for a GUI representation of rectangle.
38 | """
39 | def draw(self, canvas):
40 | canvas.penup()
41 | canvas.goto(self.point1.x, self.point1.y)
42 |
43 | canvas.pendown()
44 | canvas.forward(self.point2.x - self.point1.x)
45 | canvas.left(90)
46 | canvas.forward(self.point2.y - self.point1.y)
47 | canvas.left(90)
48 | canvas.forward(self.point2.x - self.point1.x)
49 | canvas.left(90)
50 | canvas.forward(self.point2.y - self.point1.y)
51 |
52 |
53 | class GuiPoint(Point):
54 | """Child of Point class for GUI representation of point"""
55 |
56 | def draw(self, canvas, size=5, color='red'):
57 | canvas.penup()
58 | canvas.goto(self.x, self.y)
59 |
60 | canvas.pendown()
61 | canvas.dot(size, color)
62 |
63 | turtle.done()
64 |
65 |
66 | # Create rectangle object
67 | rectangle = GuiRectangle(Point(randint(0, 200), randint(0, 200)),
68 | Point(randint(10, 200), randint(10, 200)))
69 |
70 | # Print rectangle coordinates
71 | print("Rectangle Coordinates: ",
72 | rectangle.point1.x, ",",
73 | rectangle.point1.y, "and",
74 | rectangle.point2.x, ",",
75 | rectangle.point2.y)
76 |
77 | # Get point and area from user
78 | user_point = GuiPoint(float(input("Guess x: ")), float(input("Guess y: ")))
79 | user_area = float(input("Guess rectangle area: "))
80 |
81 | # Print out the game result
82 | print("Your point was inside rectangle: ", user_point.falls_in_rectangle(rectangle))
83 | print("Your area was off by: ", rectangle.area() - user_area)
84 |
85 | myturtle = turtle.Turtle()
86 | rectangle.draw(myturtle)
87 | user_point.draw(myturtle)
88 |
--------------------------------------------------------------------------------
/Instant_Dictionary_API/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/Instant_Dictionary_API/.idea/Instant_Dictionary_API.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Instant_Dictionary_API/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Instant_Dictionary_API/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Instant_Dictionary_API/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Instant_Dictionary_API/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Instant_Dictionary_API/api.py:
--------------------------------------------------------------------------------
1 | import justpy as jp
2 | import definition
3 | import json
4 |
5 |
6 | class Api:
7 | """Handle requests at /api?w=word
8 | """
9 |
10 | @classmethod
11 | def serve(cls, req):
12 | wp = jp.WebPage()
13 | word = req.query_params.get('w')
14 |
15 | defined = definition.Definition(word).get()
16 | response = {
17 | "word": word,
18 | "definition": defined
19 | }
20 |
21 | wp.html = json.dumps(response)
22 | return wp
23 |
--------------------------------------------------------------------------------
/Instant_Dictionary_API/definition.py:
--------------------------------------------------------------------------------
1 | import pandas
2 |
3 |
4 | class Definition:
5 |
6 | def __init__(self, term):
7 | self.term = term
8 |
9 | def get(self):
10 | df = pandas.read_csv("data.csv")
11 | return tuple(df.loc[df['word'] == self.term]['definition'])
12 |
13 |
14 | if __name__ == "__main__":
15 | d = Definition(term='sun')
16 | print(d.get())
17 |
--------------------------------------------------------------------------------
/Instant_Dictionary_API/documentation.py:
--------------------------------------------------------------------------------
1 | import justpy as jp
2 |
3 |
4 | class Doc:
5 |
6 | def serve(self):
7 | wp = jp.WebPage()
8 |
9 | div = jp.Div(a=wp, text="Instant Dictionary API", classes="bg-gray-200 h-screen")
10 | jp.Div(a=div, text="This is about page!",
11 | classes="text-4xl m-2")
12 | jp.Div(a=div, text='Get definitions of words', classes="text-lg")
13 | jp.Hr(a=div)
14 | jp.Div(a=div, text="www.example.com/api?w=moon")
15 | jp.Hr(a=div)
16 | jp.Div(a=div, text="""
17 | {"word": "moon", "definition": ["A natural satellite of a planet.", "A month, particularly a lunar month (approximately 28 days).", "To fuss over adoringly or with great affection.", "Deliberately show ones bare ass (usually to an audience, or at a place, where this is not expected or deemed appropriate).", "To be lost in phantasies or be carried away by some internal vision, having temorarily lost (part of) contact to reality."]}
18 | """)
19 |
20 | return wp
21 |
--------------------------------------------------------------------------------
/Instant_Dictionary_API/main.py:
--------------------------------------------------------------------------------
1 | import api
2 | import documentation
3 |
4 | import justpy as jp
5 |
6 | jp.Route("/api", api.Api.serve)
7 | jp.Route("/", documentation.Doc.serve)
8 | jp.justpy()
9 |
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/.idea/Instant_Dictionary_Webapp.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/definition.py:
--------------------------------------------------------------------------------
1 | import pandas
2 |
3 |
4 | class Definition:
5 |
6 | def __init__(self, term):
7 | self.term = term
8 |
9 | def get(self):
10 | df = pandas.read_csv("data.csv")
11 | return tuple(df.loc[df['word'] == self.term]['definition'])
12 |
13 |
14 | if __name__ == "__main__":
15 | d = Definition(term='sun')
16 | print(d.get())
17 |
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/design/about.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pxxthik/Python-OOP-Projects/82d30e657eccc66e211f3c414645d88d3a2b80d0/Instant_Dictionary_Webapp/design/about.png
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/design/design.txt:
--------------------------------------------------------------------------------
1 | Title: Instant Dictionary Web App
2 | Description: A web app that lets users type in a term in a text box and returns the English definition
3 | of that term instantly as soon as the user has finished typing.
4 | The web app consists of a website with a navigation menu, a Home, Dictionary, and About page.
5 | Objects: Definition:
6 | term
7 | get()
8 | Navbar
9 | HomePage
10 | DictionaryPage
11 | AboutPage
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/design/dictionary.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pxxthik/Python-OOP-Projects/82d30e657eccc66e211f3c414645d88d3a2b80d0/Instant_Dictionary_Webapp/design/dictionary.png
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/design/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pxxthik/Python-OOP-Projects/82d30e657eccc66e211f3c414645d88d3a2b80d0/Instant_Dictionary_Webapp/design/home.png
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/examples/file.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Title
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/examples/main.py:
--------------------------------------------------------------------------------
1 | import justpy as jp
2 |
3 |
4 | @jp.SetRoute("/")
5 | def home():
6 | wp = jp.QuasarPage(tailwind=True)
7 | div = jp.Div(a=wp, classes="bg-gray-200 h-screen")
8 | div1 = jp.Div(a=div, classes="grid grid-cols-3 gap-4 p-4")
9 | in_1 = jp.Input(a=div1, placeholder="Enter first value",
10 | classes="form-input")
11 | in_2 = jp.Input(a=div1, placeholder="Enter second value",
12 | classes="form-input")
13 | d_output = jp.Div(a=div1, text="Result goes here...",
14 | classes="text-gray-600")
15 | jp.Div(a=div1, text="Another div...",
16 | classes="text-gray-600")
17 | jp.Div(a=div1, text="Yet another div...",
18 | classes="text-gray-600")
19 |
20 | div2 = jp.Div(a=div, classes="grid grid-cols-2 gap-4")
21 | jp.Button(a=div2, text="Calculate", click=sum_up, in_1=in_1, in_2=in_2,
22 | d=d_output,
23 | classes="border border-blue-500 m-2 py-1 px-4 rounded "
24 | "text-blue-600 hover:bg-red-500 hover:text-white")
25 | jp.Div(a=div2, text="Im a cool interactive div!", mouseenter=mouse_enter)
26 | return wp
27 |
28 |
29 | def sum_up(widget, msg):
30 | sum = float(widget.in_1.value) + float(widget.in_2.value)
31 | widget.d.text = sum
32 |
33 |
34 | def mouse_enter(widget, msg):
35 | widget.text = "Mouse entered"
36 |
37 |
38 | # jp.Route("/", home)
39 |
40 | jp.justpy()
41 |
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/main.py:
--------------------------------------------------------------------------------
1 | import justpy as jp
2 |
3 | from webapp.home import Home
4 | from webapp.about import About
5 | from webapp.dictionary import Dictionary
6 |
7 | jp.Route(Home.path, Home.serve)
8 | jp.Route(About.path, About.serve)
9 | jp.Route(Dictionary.path, Dictionary.serve)
10 |
11 | jp.justpy(port=8001)
12 |
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/webapp/about.py:
--------------------------------------------------------------------------------
1 | import justpy as jp
2 |
3 | from webapp import layout
4 |
5 |
6 | class About:
7 | path = "/about"
8 |
9 | def serve(self):
10 | wp = jp.QuasarPage(tailwind=True)
11 |
12 | lay = layout.DefaultLayout(a=wp)
13 | container = jp.QPageContainer(a=lay)
14 |
15 | div = jp.Div(a=container, classes="bg-gray-200 h-screen")
16 | jp.Div(a=div, text="This is about page!",
17 | classes="text-4xl m-2")
18 | jp.Div(a=div, text="""
19 | long text
20 | """, classes="text-lg")
21 |
22 | return wp
23 |
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/webapp/dictionary.py:
--------------------------------------------------------------------------------
1 | import justpy as jp
2 | import definition
3 |
4 | from webapp import layout
5 |
6 | import requests
7 |
8 |
9 | class Dictionary:
10 | path = "/dictionary"
11 |
12 | @classmethod
13 | def serve(cls, req):
14 | wp = jp.QuasarPage(tailwind=True)
15 |
16 | lay = layout.DefaultLayout(a=wp)
17 | container = jp.QPageContainer(a=lay)
18 |
19 | div = jp.Div(a=container, classes="bg-gray-200 h-screen")
20 | jp.Div(a=div, text="Instant English Dictionary!", classes="text-4xl m-2")
21 | jp.Div(a=div, text="Get the definition of any English word instantly as you type.",
22 | classes="text-lg")
23 |
24 | input_div = jp.Div(a=div, classes="grid grid-cols-2")
25 | output_div = jp.Div(a=div, classes="m-2 p-2 text-lg border-2 h-40")
26 |
27 | input_box = jp.Input(a=input_div, placeholder="Type in a word here...", output_div=output_div,
28 | classes="m-2 bg-gray-100 border-2 border-gray-200 rounded w-64 "
29 | "focus:bg-white focus:outline-none focus:border-purple-500 py-2 px-4")
30 | input_box.on('input', cls.get_definition)
31 |
32 | return wp
33 |
34 | @staticmethod
35 | def get_definition(widget, msg):
36 | req = requests.get(f"http://127.0.0.1:8000/api?w={widget.value}")
37 | data = req.json()
38 | widget.output_div.text = " ".join(data['definition'])
39 |
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/webapp/home.py:
--------------------------------------------------------------------------------
1 | import justpy as jp
2 | from webapp import layout
3 |
4 |
5 | class Home:
6 | path = "/"
7 |
8 | @classmethod
9 | def serve(cls, req):
10 | wp = jp.QuasarPage(tailwind=True)
11 |
12 | lay = layout.DefaultLayout(a=wp)
13 | container = jp.QPageContainer(a=lay)
14 |
15 | div = jp.Div(a=container, classes="bg-gray-200 h-screen p-2")
16 | jp.Div(a=div, text="This is the Home page!", classes="text-4xl m-2")
17 | jp.Div(a=div, text="""
18 | long text
19 | """, classes="text-lg")
20 |
21 | return wp
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/webapp/layout.py:
--------------------------------------------------------------------------------
1 | import justpy as jp
2 |
3 |
4 | class DefaultLayout(jp.QLayout):
5 |
6 | def __init__(self, view="hHh lpR fFf", **kwargs):
7 |
8 | super().__init__(view=view, **kwargs)
9 |
10 | header = jp.QHeader(a=self)
11 | toolbar = jp.QToolbar(a=header)
12 |
13 | drawer = jp.QDrawer(a=self, show_if_above=True, v_model="left",
14 | bordered=True)
15 | scroller = jp.QScrollArea(a=drawer, classes="fit")
16 | qlist = jp.QList(a=scroller)
17 |
18 | a_classes = "p-2 m-2 text-lg text-blue-400 hover:text-blue-700"
19 | jp.A(a=qlist, text="Home", href="/", classes=a_classes)
20 | jp.Br(a=qlist)
21 | jp.A(a=qlist, text="Dictionary", href="/dictionary", classes=a_classes)
22 | jp.Br(a=qlist)
23 | jp.A(a=qlist, text="About", href="/about", classes=a_classes)
24 | jp.Br(a=qlist)
25 |
26 | jp.QBtn(a=toolbar, dense=True, flat=True, round=True, icon="menu",
27 | click=self.move_drawer, drawer=drawer)
28 |
29 | jp.QToolbarTitle(a=toolbar, text="Instant Dictionary")
30 |
31 | @staticmethod
32 | def move_drawer(widget, msg):
33 | if widget.drawer.value:
34 | widget.drawer.value = False
35 | else:
36 | widget.drawer.value = True
37 |
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/webapp/navbar.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pxxthik/Python-OOP-Projects/82d30e657eccc66e211f3c414645d88d3a2b80d0/Instant_Dictionary_Webapp/webapp/navbar.py
--------------------------------------------------------------------------------
/Instant_Dictionary_Webapp/webapp/page.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 |
4 | class Page(ABC):
5 |
6 | @abstractmethod
7 | def serve(self):
8 | pass
9 |
--------------------------------------------------------------------------------
/Math_Painting/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/Math_Painting/.idea/Math_Painting.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Math_Painting/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Math_Painting/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Math_Painting/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Math_Painting/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Math_Painting/canvas.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from PIL import Image
3 |
4 |
5 | class Canvas:
6 | """Object where all shapes are going to be drawn"""
7 |
8 | def __init__(self, height, width, color):
9 | self.color = color
10 | self.height = height
11 | self.width = width
12 |
13 | # create a 3d numpy array of zeros
14 | self.data = np.zeros((self.height, self.width, 3), dtype=np.uint8)
15 | # change [0,0,0] with user given values for colors
16 | self.data[:] = self.color
17 |
18 | def make(self, image_path):
19 | """Converts the current array into image file"""
20 | img = Image.fromarray(self.data, 'RGB')
21 | img.save(image_path)
22 |
--------------------------------------------------------------------------------
/Math_Painting/design.txt:
--------------------------------------------------------------------------------
1 | Title: Math Painting
2 |
3 | Description: An App that lets the user provide the start coordinates of
4 | geometrical shapes such as squares and rectangles, their dimensions, and
5 | the program produces an image file canvas with the geometrical shapes
6 | drawn it.
7 |
8 | Objects: Squares:
9 | x
10 | y
11 | side
12 | color
13 | draw(canvas)
14 | Rectangle:
15 | x
16 | y
17 | width
18 | height
19 | color
20 | draw(canvas)
21 | Canvas:
22 | width
23 | height
24 | color
25 | make(image_path)
--------------------------------------------------------------------------------
/Math_Painting/main.py:
--------------------------------------------------------------------------------
1 | from canvas import Canvas
2 | from shapes import Rectangle, Square
3 |
4 | # Get canvas width and height from the user
5 | canvas_width = int(input("Enter canvas width: "))
6 | canvas_height = int(input("Enter canvas height: "))
7 |
8 | # Make a dictionary of a color codes and prompts for color
9 | colors = {"white": (255, 255, 255), "black": (0, 0, 0)}
10 | canvas_color = input("Enter canvas color (white or black): ")
11 |
12 | # Create a canvas with the user data
13 | canvas = Canvas(height=canvas_height, width=canvas_width, color=colors[canvas_color])
14 |
15 | while True:
16 | shape_type = input("What do you like to draw? Enter quit to quit. ")
17 | # Ask for rectangle data and create a rectangle if user entered 'rectangle'
18 | if shape_type.lower() == 'rectangle':
19 | rec_x = int(input("Enter x of the rectangle: "))
20 | rec_y = int(input("Enter y of the rectangle: "))
21 | rec_width = int(input("Enter the width of the rectangle: "))
22 | rec_height = int(input("Enter the height of the rectangle: "))
23 |
24 | red = int(input("How much red should the rectangle have? "))
25 | green = int(input("How much green? "))
26 | blue = int(input("How much blue? "))
27 |
28 | # Create the rectangle
29 | r1 = Rectangle(x=rec_x, y=rec_y, height=rec_height, width=rec_width, color=(red, green, blue))
30 | r1.draw(canvas)
31 |
32 | # Ask for square data and create square if user entered 'squared'
33 | elif shape_type.lower() == 'square':
34 | sqr_x = int(input("Enter x of the square: "))
35 | sqr_y = int(input("Enter y of the square: "))
36 | sqr_side = int(input("Enter the side of the square: "))
37 |
38 | red = int(input("How much red should the rectangle have? "))
39 | green = int(input("How much green? "))
40 | blue = int(input("How much blue? "))
41 |
42 | # Create the square
43 | s1 = Square(x=sqr_x, y=sqr_y, side=sqr_side, color=(red, green, blue))
44 | s1.draw(canvas)
45 |
46 | # Break the loop if user entered 'quit'
47 | elif shape_type.lower() == 'quit':
48 | break
49 |
50 | canvas.make('canvas.png')
51 |
--------------------------------------------------------------------------------
/Math_Painting/shapes.py:
--------------------------------------------------------------------------------
1 | class Rectangle:
2 | """A rectangle shape that can be drawn on a canvas object"""
3 |
4 | def __init__(self, x, y, height, width, color):
5 | self.x = x
6 | self.y = y
7 | self.height = height
8 | self.width = width
9 | self.color = color
10 |
11 | def draw(self, canvas):
12 | """Draws itself into the canvas"""
13 | # Changes a slice of the array with new values
14 | canvas.data[self.x: self.x + self.height, self.y: self.y + self.width] = self.color
15 |
16 |
17 | class Square:
18 | """A square shape that can be drawn on a canvas object"""
19 |
20 | def __init__(self, x, y, side, color):
21 | self.x = x
22 | self.y = y
23 | self.side = side
24 | self.color = color
25 |
26 | def draw(self, canvas):
27 | """Draws itself into the canvas"""
28 | # Changes a slice of the array with new values
29 | canvas.data[self.x: self.x + self.side, self.y: self.y + self.side] = self.color
30 |
--------------------------------------------------------------------------------
/Photo_Searcher/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/Photo_Searcher/.idea/Photo_Searcher.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Photo_Searcher/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Photo_Searcher/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Photo_Searcher/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Photo_Searcher/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Photo_Searcher/frontend.kv:
--------------------------------------------------------------------------------
1 | :
2 | GridLayout:
3 | cols: 1
4 | padding: 10
5 | spacing: 10
6 | Image:
7 | id: img
8 | size_hint_y: 0.8
9 | TextInput:
10 | id: user_query
11 | size_hint_y: 0.1
12 | Button:
13 | text: 'Search Image'
14 | size_hint_y: 0.1
15 | on_press: root.set_image()
16 |
17 | :
18 | FirstScreen:
19 | id: first_screen
20 | name: 'first_screen'
--------------------------------------------------------------------------------
/Photo_Searcher/main.py:
--------------------------------------------------------------------------------
1 | from kivy.app import App
2 | from kivy.uix.screenmanager import ScreenManager, Screen
3 | from kivy.lang import Builder
4 |
5 | import wikipedia
6 | import requests
7 |
8 | Builder.load_file('frontend.kv')
9 |
10 |
11 | class FirstScreen(Screen):
12 | def get_image_link(self):
13 | # Get user query from text input
14 | query = self.manager.current_screen.ids.user_query.text
15 |
16 | # Get wikipedia page and first image link
17 | page = wikipedia.page(query)
18 | image_link = page.images[0]
19 |
20 | return image_link
21 |
22 | def download_image(self):
23 | # Download the image
24 | req = requests.get(self.get_image_link())
25 | image_path = f"files/image.jpg"
26 | with open(image_path, "wb") as file:
27 | file.write(req.content)
28 |
29 | return image_path
30 |
31 | def set_image(self):
32 | # Set the image in the widget
33 | self.manager.current_screen.ids.img.source = self.download_image()
34 |
35 |
36 | class RootWidget(ScreenManager):
37 | pass
38 |
39 |
40 | class MainApp(App):
41 | def build(self):
42 | return RootWidget()
43 |
44 |
45 | MainApp().run()
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Python Object-Oriented Programming (OOP) Projects
2 |
3 | This repository contains a collection of Python projects that demonstrate the principles of Object-Oriented Programming (OOP). Each project is designed to showcase various aspects of OOP and can be used as educational resources for learning OOP in Python.
4 |
5 | ## Overview
6 |
7 | Object-Oriented Programming is a fundamental paradigm in software development. This repository provides a hands-on approach to OOP by implementing projects that cover a range of OOP concepts and techniques. Whether you are a beginner looking to learn OOP or an experienced developer wanting to reinforce your OOP skills, you'll find something valuable in these projects.
8 |
9 | ## Project List
10 |
11 | 1. **Class Inheritance**: An example of creating and using class inheritance in Python.
12 |
13 | 2. **Encapsulation**: Demonstrates the concept of encapsulation through access modifiers.
14 |
15 | 3. **Polymorphism**: Illustrates polymorphism through method overriding and dynamic method binding.
16 |
17 | 4. **Composition**: Shows how to create complex objects through composition.
18 |
19 | 5. **Abstraction**: Provides examples of abstract classes and methods.
20 |
21 | 6. **Design Patterns**: Includes examples of common design patterns implemented in Python.
22 |
23 | Each project includes detailed documentation and code explanations to aid your understanding.
24 |
25 | ## Getting Started
26 |
27 | To get started with the projects, clone this repository to your local machine:
28 |
29 | ```bash
30 | git clone https://github.com/pxxthik/Python-OOP-Projects.git
31 |
--------------------------------------------------------------------------------
/Webcam_Photo_Sharer/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/Webcam_Photo_Sharer/.idea/Webcam_Photo_Sharer.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Webcam_Photo_Sharer/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Webcam_Photo_Sharer/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Webcam_Photo_Sharer/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Webcam_Photo_Sharer/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Webcam_Photo_Sharer/design-frontend.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pxxthik/Python-OOP-Projects/82d30e657eccc66e211f3c414645d88d3a2b80d0/Webcam_Photo_Sharer/design-frontend.png
--------------------------------------------------------------------------------
/Webcam_Photo_Sharer/design.txt:
--------------------------------------------------------------------------------
1 | Title: Webcam Photo Sharer
2 |
3 | Description: An app that starts the computer webcam, lets user
4 | capture a photo and uploads the photo to the web and creates a
5 | sharable link.
6 |
7 | Objects: Webcam:
8 | start()
9 | stop()
10 | capture()
11 | FileSharer:
12 | filepath
13 | api
14 | share()
--------------------------------------------------------------------------------
/Webcam_Photo_Sharer/filesharer.py:
--------------------------------------------------------------------------------
1 | from filestack import Client
2 |
3 |
4 | class FileSharer:
5 | def __init__(self, filepath, api_key='Aj799wiBlScSabXEs3WqDz'):
6 | self.filepath = filepath
7 | self.api_key = api_key
8 |
9 | def share(self):
10 | client = Client(self.api_key)
11 | new_filelink = client.upload(filepath=self.filepath)
12 | return new_filelink.url
13 |
--------------------------------------------------------------------------------
/Webcam_Photo_Sharer/frontend.kv:
--------------------------------------------------------------------------------
1 | :
2 | GridLayout:
3 | cols: 1
4 | padding: 10
5 | spacing: 10
6 | Camera:
7 | id: camera
8 | resolution: (640, 480)
9 | play: False
10 | size_hint_y: 0.8
11 | opacity: 0
12 | Button:
13 | id: camera_button
14 | text: 'Start Camera'
15 | on_press: root.start() if root.ids.camera.play == False else root.stop()
16 | size_hint_y: 0.1
17 | background_normal: 'images/normal.png'
18 | background_down: 'images/down.png'
19 | Button:
20 | text: 'Capture'
21 | on_press: root.capture()
22 | size_hint_y: 0.1
23 | background_normal: 'images/normal.png'
24 | background_down: 'images/down.png'
25 |
26 | :
27 | GridLayout:
28 | cols: 1
29 | padding: 10
30 | spacing: 10
31 | Image:
32 | id: img
33 | size_hint_y: 0.7
34 | Button:
35 | text: 'Create sharable link'
36 | on_press: root.create_link()
37 | size_hint_y: 0.1
38 | background_normal: 'images/normal.png'
39 | background_down: 'images/down.png'
40 | Label:
41 | id: link
42 | text: ''
43 | size_hint_y: 0.1
44 | GridLayout:
45 | cols: 2
46 | size_hint_y: 0.1
47 | Button:
48 | text: 'Copy link'
49 | on_press: root.copy_link()
50 | background_normal: 'images/normal.png'
51 | background_down: 'images/down.png'
52 | Button:
53 | text: 'Open link'
54 | on_press: root.open_link()
55 | background_normal: 'images/normal.png'
56 | background_down: 'images/down.png'
57 |
58 | :
59 | canvas.before:
60 | Color:
61 | rgba: (0.9, 0.9, 0.9, 1)
62 | Rectangle:
63 | pos: self.pos
64 | size: self.size
65 | CameraScreen:
66 | id: camera_screen
67 | name: 'camera_screen'
68 | ImageScreen:
69 | id: image_screen
70 | name: 'image_screen'
--------------------------------------------------------------------------------
/Webcam_Photo_Sharer/images/down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pxxthik/Python-OOP-Projects/82d30e657eccc66e211f3c414645d88d3a2b80d0/Webcam_Photo_Sharer/images/down.png
--------------------------------------------------------------------------------
/Webcam_Photo_Sharer/images/normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pxxthik/Python-OOP-Projects/82d30e657eccc66e211f3c414645d88d3a2b80d0/Webcam_Photo_Sharer/images/normal.png
--------------------------------------------------------------------------------
/Webcam_Photo_Sharer/main.py:
--------------------------------------------------------------------------------
1 | from kivy.app import App
2 | from kivy.uix.screenmanager import ScreenManager, Screen
3 | from kivy.lang import Builder
4 | from kivy.core.clipboard import Clipboard
5 |
6 | import time
7 | import webbrowser
8 |
9 | from filesharer import FileSharer
10 |
11 | Builder.load_file("frontend.kv")
12 |
13 |
14 | class CameraScreen(Screen):
15 | def start(self):
16 | """Starts camera and changes button text"""
17 | self.ids.camera.opacity = 1
18 | self.ids.camera.play = True
19 | self.ids.camera_button.text = "Stop Camera"
20 | self.ids.camera.texture = self.ids.camera._camera.texture
21 |
22 | def stop(self):
23 | """Stops camera and changes button text"""
24 | self.ids.camera.opacity = 0
25 | self.ids.camera.play = False
26 | self.ids.camera_button.text = "Start Camera"
27 | self.ids.camera.texture = None
28 |
29 | def capture(self):
30 | """Creates a filename with the current time and captures
31 | and saves a photo image under that filename"""
32 | current_time = time.strftime('%Y%m%d-%H%M%S')
33 | self.filepath = f"files/{current_time}.png"
34 | self.ids.camera.export_to_png(self.filepath)
35 | self.manager.current = 'image_screen'
36 | self.manager.current_screen.ids.img.source = self.filepath
37 |
38 |
39 | class ImageScreen(Screen):
40 | link_message = "Create a link first"
41 |
42 | def create_link(self):
43 | """Access the photo filepath, uploads it to the web,
44 | and inserts the linkin the Label widget"""
45 | filepath = App.get_running_app().root.ids.camera_screen.filepath
46 | file_sharer = FileSharer(filepath=filepath)
47 | self.url = file_sharer.share()
48 | self.ids.link.text = self.url
49 |
50 | def copy_link(self):
51 | """Copy link to the clipboard available for pasting"""
52 | try:
53 | Clipboard.copy(self.url)
54 | except:
55 | self.ids.link.text = self.link_message
56 |
57 | def open_link(self):
58 | """Open link with default browser"""
59 | try:
60 | webbrowser.open(self.url)
61 | except:
62 | self.ids.link.text = self.link_message
63 |
64 |
65 | class RootWidget(ScreenManager):
66 | pass
67 |
68 |
69 | class MainApp(App):
70 |
71 | def build(self):
72 | return RootWidget()
73 |
74 |
75 | MainApp().run()
76 |
--------------------------------------------------------------------------------