Skip to content
This repository was archived by the owner on Apr 24, 2025. It is now read-only.

Commit 375baa8

Browse files
authored
Merge branch 'main' into ibra-kdbra
2 parents 16acfac + 650f1aa commit 375baa8

20 files changed

Lines changed: 473 additions & 76 deletions

File tree

projects/Alarm Clock/clock.py

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,56 @@
1-
# Importing the necessary modules
21
import tkinter
32
from time import strftime
43

54
# Creating the main application window
65
top = tkinter.Tk()
7-
top.title("Clock") # Setting the title of the window
6+
top.title("Dynamic Clock") # Updated title
87
top.resizable(0, 0) # Making the window non-resizable
98

109

10+
# Function to determine the time of day
11+
def get_time_of_day(hour):
12+
if 5 <= hour < 12:
13+
return "Morning"
14+
elif 12 <= hour < 18:
15+
return "Afternoon"
16+
else:
17+
return "Evening"
18+
19+
1120
# Function to update the time display
12-
def time():
13-
# Get the current time in the format HH:MM:SS AM/PM
14-
string = strftime("%H:%M:%S %p")
21+
def update_time():
22+
current_time = strftime("%H:%M:%S %p")
23+
hour = int(strftime("%H"))
24+
time_of_day = get_time_of_day(hour)
25+
26+
# Update the text of the clockTime Label with the current time and time of day
27+
clock_time.config(text=current_time + f"\nGood {time_of_day}!")
1528

16-
# Update the text of the clockTime Label with the current time
17-
clockTime.config(text=string)
29+
# Dynamically change the background color based on time of day
30+
color = (
31+
"lightblue"
32+
if time_of_day == "Morning"
33+
else "lightyellow" if time_of_day == "Afternoon" else "lightcoral"
34+
)
35+
top.configure(background=color)
1836

19-
# Schedule the time function to be called again after 1000 milliseconds (1 second)
20-
clockTime.after(1000, time)
37+
# Schedule the update_time function to be called again after 1000 milliseconds (1 second)
38+
clock_time.after(1000, update_time)
2139

2240

2341
# Creating a Label widget to display the time
24-
clockTime = tkinter.Label(
42+
clock_time = tkinter.Label(
2543
top,
2644
font=("courier new", 40),
2745
background="black",
2846
foreground="white",
2947
)
3048

3149
# Position the Label widget in the center of the window
32-
clockTime.pack(anchor="center")
50+
clock_time.pack(anchor="center")
3351

34-
# Call the time function to start updating the time display
35-
time()
52+
# Call the update_time function to start updating the time display
53+
update_time()
3654

3755
# Start the Tkinter main event loop
3856
top.mainloop()

projects/Coin Flip/coinflip.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,17 @@ def toss_coin():
99

1010
def main():
1111
while True:
12+
flag = False # Declaring a variable which will be used afterwards to break out of 2 nested while loops
13+
# at the same time
1214
# Clears the shell/terminal (where all the text is)
1315
os.system("cls")
1416

1517
answer = input("Pick a side for the coin toss (heads/tails): ")
1618

1719
# Input validation
1820
if answer.lower() not in ["heads", "tails"]:
19-
print("Invalid input. Please enter 'heads' or 'tails'.")
21+
# removed the print statement here because its not required since the while loop clears
22+
# the statement anyways
2023
continue
2124

2225
result = toss_coin()
@@ -29,8 +32,17 @@ def main():
2932
print("OOF. Better luck next time.")
3033

3134
# Ask the user if they want to play again
32-
answer_y = input("Wanna play again? (yes/no): ")
33-
if answer_y.lower() != "yes":
35+
while True:
36+
answer_y = input("Wanna play again? (yes/no): ")
37+
if answer_y.lower() == "no":
38+
flag = True
39+
break
40+
elif answer_y.lower() == "yes":
41+
break # if answer_y is "yes" then break out of only the innermost while loop and start the game again
42+
else:
43+
continue
44+
45+
if flag: # Checking if the flag variable is True
3446
break
3547

3648

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
SECRET_KEY = "https://github.com/AmitM0287"
2+
ENCRYPT_KEY_LEN = 7
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# CustomEncryptionDecryption
2+
# Overview
3+
CustomEncryptionDecryption is a simple Python program that allows users to encrypt and decrypt their data or text using a SECRET_KEY and CIPHER_TEXT. This program provides a basic and customizable encryption and decryption mechanism for securing sensitive information.
4+
5+
# Prerequisites
6+
Before running the program, ensure you have Python installed on your system. Additionally, make sure to have the required dependencies by running:
7+
8+
# bash
9+
# Copy code
10+
pip install -r requirements.txt
11+
12+
# Getting Started
13+
Clone the Repository:
14+
15+
# bash
16+
# Copy code
17+
git clone https://github.com/Mrinank-Bhowmick/python-beginner-projects.git
18+
cd projects/CustomEncryptionDecryption
19+
20+
# Create Environment File:
21+
Make a copy of the .env.example file and rename it to .env. Edit the .env file to set your desired SECRET_KEY and CIPHER_TEXT values.
22+
23+
# Install Dependencies:
24+
Install the required dependencies by running:
25+
26+
# bash
27+
# Copy code
28+
pip install -r requirements.txt
29+
30+
# Run the Program:
31+
Execute the following command to start the program:
32+
33+
# bash
34+
# Copy code
35+
python script.py
36+
37+
# Usage
38+
Upon running the program, you will be prompted to choose between encryption and decryption. Enter the necessary details, and the program will perform the requested operation using the provided SECRET_KEY and CIPHER_TEXT.
39+
40+
# Contributing
41+
If you'd like to contribute to this project, please follow these steps:
42+
43+
a. Fork the repository
44+
b. Create a new branch for your feature or bug fix
45+
c. Make your changes and commit them
46+
d. Push your changes to your fork
47+
e. Submit a pull request
48+
49+
Thank you for contributing!
50+
51+
# License
52+
This project is licensed under the MIT License.
53+
54+
# Acknowledgements
55+
Special thanks to all contributors and users of CustomEncryptionDecryption!
56+
57+
Thank you for using this program. If you have any issues or questions, feel free to open an issue or contact me.
58+
59+
Happy encrypting and decrypting! 🚀

projects/CustomEncryptionDecryption/__init__.py

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ZXlKaGJHY2lPaUpJVXpJMU5pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SmhJam9pYWxaWVFqVXhWU0lzSW1JaU9pSXpNemQ1Y0VaRElpd2lZeUk2SW1aSFlVeEdjbTRpTENKa0lqb2liVE5FVG1SR2JDSXNJbVVpT2lJeFMybENTbkYzSWl3aVppSTZJakkzTldaS2JrSWlMQ0puSWpvaWFqSTJSVE5CTkNJc0ltZ2lPaUpwVEdFM1FqVlRJaXdpYVNJNklsaHVTelZwUm5JaUxDSnFJam9pTmtWbE1rYzFXaUlzSW1zaU9pSnFZVk5DUkhaMElpd2liQ0k2SWxFMk9WRkRRVFVpTENKdElqb2lZamQ1VFdFeVdTSXNJbTRpT2lJMU9URTJWV1V5SWl3aWJ5STZJbEJ4YVdabmR6SWlMQ0p3SWpvaU1HYzVhbkF5VmlJc0luRWlPaUp1ZG5OU1kzUXdJaXdpY2lJNkltSTFTek5rTTFjaUxDSnpJam9pZEVWSWMxaHNkaUlzSW5RaU9pSjNkMFpNU25ob0lpd2lkU0k2SW5wUU1ISnRXVzhpTENKMklqb2lNR3BHWTBjMk5DSXNJbmNpT2lKR05rSjVXVFJySWl3aWVDSTZJbVpIUWtKT2FXOGlMQ0o1SWpvaU0wZDNPWFkzYUNJc0lub2lPaUpDTURkWWVYWkRJaXdpUVNJNklrVjZTMHRuTXpraUxDSkNJam9pTVRKRlpXNDNUaUlzSWtNaU9pSkJXVGRHUjNveUlpd2lSQ0k2SW1GUVV6VkZjRllpTENKRklqb2liVTE1VkU1cVJDSXNJa1lpT2lKMFoxSXhOVEZUSWl3aVJ5STZJalpLVjB0QmRqQWlMQ0pJSWpvaVptWXdPR0Z2UVNJc0lra2lPaUk1UmxwTVFUTkRJaXdpU2lJNkltVk1ablIzZWxBaUxDSkxJam9pTVRKcmNUSjZPQ0lzSWt3aU9pSmpiV2hYTlRFd0lpd2lUU0k2SW5FNFprSjFaRUVpTENKT0lqb2lWbXN5TnpaMVpTSXNJazhpT2lJeE0wTnNiWE0zSWl3aVVDSTZJbGxrU21JMk9XMGlMQ0pSSWpvaVpFVnVOa3BoWnlJc0lsSWlPaUprUldOeVptRjRJaXdpVXlJNklqTlhSMDQyTTFZaUxDSlVJam9pWlROcGFXTnJUU0lzSWxVaU9pSnNVRVV6V0dZMElpd2lWaUk2SW5nNFJEY3hibE1pTENKWElqb2lORFZtWmtsVlppSXNJbGdpT2lKbFVUTjNOMk5pSWl3aVdTSTZJakEyTkdaMk1YZ2lMQ0phSWpvaVNUVkdOMVZZV2lJc0lqQWlPaUppWlZJek9FRlNJaXdpTVNJNklrSlBORGM1TkVNaUxDSXlJam9pTmtSc09EWlBWeUlzSWpNaU9pSkJNSEpIUTBoVUlpd2lOQ0k2SWxKSlJHUXlaVEFpTENJMUlqb2lRVEl4WVhZellTSXNJallpT2lJNFIyZ3hPRXRoSWl3aU55STZJbVJtUW5rMFQyUWlMQ0k0SWpvaU9EQnNOME0yYnlJc0lqa2lPaUpVY0ZRMU16Y3hJaXdpSVNJNklscG1kbE5DWVRJaUxDSmNJaUk2SWpaR2FFbzNWVTRpTENJaklqb2llRmcyU3pRMFNDSXNJaVFpT2lKYU1WaGhhVEp5SWl3aUpTSTZJbFJoVHpaSVEyUWlMQ0ltSWpvaU1YaDRUMkpETUNJc0lpY2lPaUl3T0RNNVZGZzFJaXdpS0NJNklucDBVRGxCVERRaUxDSXBJam9pYVdNMU5qTlBlU0lzSWlvaU9pSjFWV1ExTnpGd0lpd2lLeUk2SW01UGRqTkxWbU1pTENJc0lqb2lUVXRFTUd4Qk9DSXNJaTBpT2lKMU16RmtUVE5FSWl3aUxpSTZJalZ5VlVJeGVuSWlMQ0l2SWpvaWJXdFNlRE4yY2lJc0lqb2lPaUkyWkVveFdYQTRJaXdpT3lJNklrZEtZVVV4U21JaUxDSThJam9pWmpObGFUUndkeUlzSWowaU9pSmFTMjlEVnpaVklpd2lQaUk2SW5OdVJuVldRVklpTENJX0lqb2lkR1l3TjNCaWN5SXNJa0FpT2lKNGRHMUZaRzVLSWl3aVd5STZJbUZVUm1Zd04yMGlMQ0pjWENJNklqUklTM2MwY0U4aUxDSmRJam9pZURBNFFrUXhaU0lzSWw0aU9pSklOSE5QTlUwMUlpd2lYeUk2SWpObFFUTm9OVEVpTENKZ0lqb2lPRFptZFVWME1pSXNJbnNpT2lJMWJUVXhRemhPSWl3aWZDSTZJaloxZFdoRmVFNGlMQ0o5SWpvaVZEaHNaVTh6T0NJc0luNGlPaUl3WmpWQ1l6STNJaXdpSUNJNklsSTJVMFUwWkdZaUxDSmNkQ0k2SWt3elRFazJlbW9pTENKY2JpSTZJbTA1UW1KbU1qTWlMQ0pjY2lJNkltNVVSREIzWlVRaUxDSmNkVEF3TUdJaU9pSllOVFpLUkZJeElpd2lYR1lpT2lKc1IzbHNiVFZFSW4wLkZZcTgyTUx3NXNqLTFqTXp6aXVKQUg3cnpWUTAyTDEzOHEtVnF1LTlyekE=
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
PyJWT==2.8.0
2+
python-dotenv==1.0.0
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import string
2+
import random
3+
import jwt
4+
import base64
5+
import os
6+
from dotenv import load_dotenv
7+
load_dotenv()
8+
9+
10+
class CustomEncrDecr:
11+
def __init__(self) -> None:
12+
self.__SECRET_KEY = str(os.getenv('SECRET_KEY'))
13+
self.__ENDE_KEY_LEN = int(os.getenv('ENDE_KEY_LEN'))
14+
self.__keyStore = privateKeyStore(self.__ENDE_KEY_LEN)
15+
16+
def _encryptText(self, text) -> str:
17+
encryptedText = ''
18+
for char in text:
19+
val = self.__keyStore._getCipherEStore().get(char)
20+
encryptedText += char if val is None else val
21+
encryptedText = base64.b64encode(encryptedText.encode('utf-8')).decode('utf-8')
22+
return encryptedText
23+
24+
def _decryptText(self, encryptedText) -> str:
25+
decryptedText = ''
26+
encryptedText = base64.b64decode(encryptedText.encode('utf-8')).decode('utf-8')
27+
for idx in range(0, len(encryptedText), self.__ENDE_KEY_LEN):
28+
st = encryptedText[idx: idx + self.__ENDE_KEY_LEN]
29+
val = self.__keyStore._getCipherDStore().get(st)
30+
decryptedText += st if val is None else val
31+
return decryptedText
32+
33+
def _generateCipherText(self) -> str:
34+
self.__keyStore._generateCipherEStore()
35+
self.__keyStore._generateCipherDStore()
36+
dataString = jwt.encode(self.__keyStore._getCipherEStore(), self.__SECRET_KEY, algorithm='HS256')
37+
cipherText = base64.b64encode(dataString.encode('utf-8')).decode('utf-8')
38+
with open('cipher_text.txt', 'w') as file:
39+
file.write(str(cipherText).strip())
40+
41+
def _verifyCipherText(self, cipherText='') -> None:
42+
dataString = base64.b64decode(cipherText.encode('utf-8')).decode('utf-8')
43+
cipherEstore = jwt.decode(dataString, self.__SECRET_KEY, algorithms=['HS256'])
44+
self.__keyStore._setCipherEStote(cipherEstore)
45+
self.__keyStore._generateCipherDStore()
46+
47+
48+
class privateKeyStore:
49+
def __init__(self, CIPHER_KEY) -> None:
50+
self.__CIPHER_ESTORE = {}
51+
self.__CIPHER_DSTORE = {}
52+
self.__ENDE_KEY_LEN = CIPHER_KEY
53+
54+
def _getCipherEStore(self) -> dict:
55+
return self.__CIPHER_ESTORE
56+
57+
def _getCipherDStore(self) -> dict:
58+
return self.__CIPHER_DSTORE
59+
60+
def _setCipherEStote(self, cipherEstore) -> None:
61+
self.__CIPHER_ESTORE = cipherEstore
62+
63+
def _generateCipherDStore(self) -> dict:
64+
for k, v in self.__CIPHER_ESTORE.items():
65+
self.__CIPHER_DSTORE[v] = k
66+
67+
def _generateCipherEStore(self) -> dict:
68+
for char in string.ascii_letters + string.digits + string.punctuation + string.whitespace:
69+
self.__CIPHER_ESTORE[char] = self.__generateSecureText()
70+
71+
def __generateSecureText(self) -> str:
72+
return ''.join(random.choices(string.ascii_letters + string.digits + string.hexdigits + string.octdigits, k=self.__ENDE_KEY_LEN))
73+
74+
75+
if __name__ == '__main__':
76+
print('\nWelcome to Custom Encryption & Decryption Program!')
77+
customEncrDecr = CustomEncrDecr()
78+
exitFlag = False
79+
while(not exitFlag):
80+
userOption = input('\n\nDo you already have a CIPHER TEXT ? \n\ta. Press \'c\' to continue with the default CIPHER TEXT \n\tb. Press \'y\' if you already have a CIPHER TEXT \n\tc. Press \'g\' to generate a CIPHER TEXT \n\td. Press \'r\' to report a BUG \n\nYou have chosen: ')
81+
match userOption:
82+
case 'y':
83+
print('\nPlease add the CIPHER TEXT into the \'cipher_text.txt\' file! then start the program!\n')
84+
exit()
85+
case 'g':
86+
customEncrDecr._generateCipherText()
87+
print('\nYour CIPHER TEXT has been generated successfully! and added into the \'cipher_text.txt\' file!')
88+
exitFlag = True
89+
case 'c':
90+
try:
91+
with open('cipher_text.txt', 'r') as file:
92+
cipherText = str(file.read()).strip()
93+
customEncrDecr._verifyCipherText(cipherText)
94+
exitFlag = True
95+
except Exception as exc:
96+
print("\n\n", exc)
97+
exitFlag = False
98+
print('\nCIPHER TEXT is INVALID! Make sure you have added a valid CIPHER TEXT inside the \'cipher_text.txt\' file!')
99+
case 'r':
100+
print('\nPlease send me a detail email at \'amitmanna0287@gmail.com\'. Keep the subject as \'BUG: Custom Encryption & Decryption Program\'. \n\nTo follow me use below social accounts: \n\ta. LinkedIn: https://www.linkedin.com/in/amitm0287/ \n\tb. GitHub: https://github.com/AmitM0287 \n\nThank you for time! Have a good day :)\n')
101+
exit()
102+
case _:
103+
print('\nPlease choose a valid option next time!')
104+
exitFlag = False
105+
while(not exitFlag):
106+
userOption = input('\n\nPlease choose one option from below: \n\ta. Press \'e\' to ENCRYPT a TEXT \n\tb. Press \'d\' to DECRYPT a ENCRYPTED TEXT \n\tc. Press \'q\' to QUIT the program ? \n\nYou have chosen: ')
107+
match userOption:
108+
case 'e':
109+
text = input('\nPlease enter your text : ')
110+
print('\nYour ENCRYPTED TEXT text is: ', customEncrDecr._encryptText(text), '\n')
111+
case 'd':
112+
try:
113+
_encryptedText = input('\nPlease enter your ENCRYPTED TEXT : ')
114+
print('\nYour DECRYPTED TEXT is: ', customEncrDecr._decryptText(_encryptedText))
115+
except Exception as exc:
116+
print('\nENCRYPTED TEXT is INVALID! Make sure you are using the same CIPHER TEXT which you used at the time of ENCRYPTION!')
117+
case 'q':
118+
print('\nThanks for using custom encryption & decryption program! Have great day :)\n')
119+
exit()
120+
case _:
121+
print('\nPlease choose a valid option next time!')
122+
exitFlag = False if input('\nDo you want to continue to the program ? \n\ta. Press \'c\' to continue! \n\tb. Press \'any other key\' to quit the program! \n\nYou have chosen: ') == 'c' else True

projects/Discord Bot/main.py

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,89 @@
11
# build a simple discord bot
22

33
import discord
4+
from discord.ext import commands # importing commands module from discord extensions
45
import os
56
import random
67

78
token = "Your Token Here"
89

910
bot = discord.bot(comand_prefix="!")
1011

12+
# The list below is a list that contains all the responses the bot can randomly choose from for the "ask" command
13+
# Scroll down to see the "ask" command's functionality
14+
15+
responses_list = [
16+
"It is certain",
17+
"It is decidedly so",
18+
"Without a doubt",
19+
"Yes, definitely",
20+
"You may rely on it",
21+
"As I see it, yes",
22+
"Most likely",
23+
"Outlook good",
24+
"Yes",
25+
"Signs point to yes",
26+
"Reply hazy try again",
27+
"Ask again later",
28+
"Better not tell you now",
29+
"Cannot predict now",
30+
"Concentrate and ask again",
31+
"Don't count on it",
32+
"My reply is no",
33+
"My sources say no",
34+
"Outlook not so good",
35+
"Very doubtful",
36+
]
37+
1138

1239
@bot.event
1340
async def on_ready():
1441
print("Bot is ready")
1542

1643

1744
@bot.event
18-
async def on_message(message):
45+
async def on_message(message: discord.Message):
1946
if message.author == bot.user:
2047
return
2148

2249
if message.content.startswith("!hello"):
23-
await message.channel.send("Hello!")
50+
await message.channel.send(f"Hello {message.author.mention}!")
51+
return
2452

2553
if message.content.startswith("!random"):
2654
await message.channel.send(random.randint(1, 100))
2755

2856

57+
# adding a "@bot.command" decorator which creates a command for the discord bot which can be then invoked by the user
58+
# "aliases" parameter inside the "@bot.command" decorator makes it so that the user can use different names to call
59+
# that particular command
60+
61+
62+
@bot.command(aliases=["ASK", "Ask"])
63+
async def ask(ctx: commands.Context, *, question: str):
64+
65+
# Note:- If we don't put a ( * ) before the question paramter, the bot will only take the first word from the user
66+
# input. For example: Running the command like this:- "!ask how are you?"
67+
# The bot will read that command as:- "how"
68+
69+
await ctx.reply(
70+
f"{ctx.author.mention} asks: **{question}**\nMy reply: **{random.choice(responses_list)}**"
71+
)
72+
73+
74+
# There's one last thing to do now.. which is handling error. As we can see, the "ask" commands needs a question
75+
# parameter.. but what if the user just uses the command and never provide the bot with the question parameter?
76+
# This situation will throw an error called "MissingRequiredArgument". In order to avoid this, we can locally
77+
# create a error handler for this "ask" command. You can also use a try and except block to catch the error.
78+
79+
80+
@ask.error
81+
async def ask_error(ctx: commands.Context, error):
82+
if isinstance(error, commands.MissingRequiredArgument):
83+
await ctx.reply("You didn't provide me with a question!")
84+
85+
86+
# the above error handler checks specifically for the error "MissingRequiredArgument". If the command encounters with
87+
# this error, the bot will just reply to the user's message with the sentence pasted above in the error handler
88+
2989
bot.run(token)

0 commit comments

Comments
 (0)