Skip to content

Commit 3d7ba92

Browse files
authored
Update PasswordGenerator.py (#395)
* Update PasswordGenerator.py * Update With these enhancements, the application will offer greater flexibility, functionality, and a better user experience. * update Now the user can specify how many profiles they want to generate and the user is prompted to decide whether they want to save the profiles to a file.
1 parent 5e4c7b5 commit 3d7ba92

File tree

4 files changed

+254
-83
lines changed

4 files changed

+254
-83
lines changed

Expense Tracker/Expense Tracker.db

12 KB
Binary file not shown.

Expense Tracker/expense.py

+101
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,59 @@ def remove_all_expenses():
5757
else:
5858
tb.showinfo('Ok then', 'The task was aborted and no expense was deleted!')
5959

60+
def search_expenses(search_term):
61+
"""
62+
Search and display expenses based on a search term in any column.
63+
"""
64+
global table
65+
table.delete(*table.get_children())
66+
67+
query = f"""
68+
SELECT * FROM ExpenseTracker WHERE
69+
Date LIKE ? OR
70+
Payee LIKE ? OR
71+
Description LIKE ? OR
72+
Amount LIKE ? OR
73+
ModeOfPayment LIKE ?;
74+
"""
75+
search_param = f"%{search_term}%"
76+
results = connector.execute(query, (search_param,) * 5)
77+
78+
for data in results.fetchall():
79+
table.insert('', END, values=data)
80+
81+
82+
def filter_expenses_by_date(date_from, date_to):
83+
"""
84+
Filter and display expenses based on a date range.
85+
"""
86+
global table
87+
table.delete(*table.get_children())
88+
89+
query = """
90+
SELECT * FROM ExpenseTracker WHERE Date BETWEEN ? AND ?;
91+
"""
92+
results = connector.execute(query, (date_from, date_to))
93+
94+
for data in results.fetchall():
95+
table.insert('', END, values=data)
96+
97+
98+
def sort_expenses(column, order):
99+
"""
100+
Sort expenses by a column in ascending or descending order.
101+
"""
102+
global table
103+
table.delete(*table.get_children())
104+
105+
query = f"SELECT * FROM ExpenseTracker ORDER BY {column} {order};"
106+
results = connector.execute(query)
107+
108+
for data in results.fetchall():
109+
table.insert('', END, values=data)
110+
111+
112+
60113
def add_another_expense():
61114
global date, payee, Desc, amnt, MoP
62115
global connector
@@ -160,6 +213,54 @@ def expense_to_words_before_adding():
160213

161214
Button(buttons_frame, text='Delete All Expenses', font=btn_font, width=25, bg=hlb_btn_bg, command=remove_all_expenses).place(x=640, y=5)
162215

216+
import csv
217+
from tkinter.filedialog import asksaveasfilename
218+
219+
220+
def export_to_csv():
221+
"""
222+
Export the table data to a CSV file.
223+
"""
224+
data = connector.execute('SELECT * FROM ExpenseTracker').fetchall()
225+
if not data:
226+
tb.showerror("Export Failed", "No expenses to export!")
227+
return
228+
229+
save_file_path = asksaveasfilename(
230+
defaultextension=".csv",
231+
filetypes=[("CSV files", "*.csv"), ("All files", "*.*")],
232+
title="Save As"
233+
)
234+
235+
if save_file_path:
236+
with open(save_file_path, mode='w', newline='') as file:
237+
writer = csv.writer(file)
238+
# Write the header
239+
writer.writerow(['ID', 'Date', 'Payee', 'Description', 'Amount', 'Mode of Payment'])
240+
# Write the data
241+
writer.writerows(data)
242+
243+
tb.showinfo("Export Successful", f"Expenses exported to {save_file_path}")
244+
245+
246+
filter_frame = Frame(root, bg="light gray")
247+
filter_frame.place(x=10, y=500, width=1165, height=35)
248+
249+
Label(filter_frame, text="Date From:", font=("Georgia", 10), bg="light gray").place(x=10, y=5)
250+
date_from = DateEntry(filter_frame, date=datetime.datetime.now().date(), width=10)
251+
date_from.place(x=90, y=5)
252+
253+
Label(filter_frame, text="Date To:", font=("Georgia", 10), bg="light gray").place(x=200, y=5)
254+
date_to = DateEntry(filter_frame, date=datetime.datetime.now().date(), width=10)
255+
date_to.place(x=270, y=5)
256+
257+
Button(filter_frame, text="Filter", font=('Gill Sans MT', 10), width=10, bg=hlb_btn_bg,
258+
command=lambda: filter_expenses_by_date(date_from.get_date(), date_to.get_date())).place(x=400, y=3)
259+
260+
Button(filter_frame, text="Export to CSV", font=('Gill Sans MT', 10), width=15, bg=hlb_btn_bg,
261+
command=export_to_csv).place(x=500, y=3)
262+
263+
163264
# Treeview Frame
164265
table = ttk.Treeview(tree_frame, selectmode=BROWSE, columns=('ID', 'Date', 'Payee', 'Description', 'Amount', 'Mode of Payment'))
165266

Fake Profile/FakeProfile.py

+99-20
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,101 @@
11
from faker import Faker
2+
from typing import List
3+
import json
4+
5+
# Initialize Faker with multiple locales
26
fake = Faker(['it_IT', 'en_US', 'ja_JP'])
3-
print("### ALL faker Attribute")
4-
print(dir(fake))
5-
6-
profile = """
7-
### Faker Profile ###
8-
Name : {}
9-
Email : {}
10-
Social Security number (SSN) : {}
11-
Address : {}
12-
Location : {}, {}
13-
URL : {}
14-
""".format(fake.name(),
15-
fake.email(),
16-
fake.ssn(),
17-
fake.address(),
18-
fake.latitude(), fake.longitude(),
19-
fake.url()
20-
)
21-
22-
print(profile)
7+
8+
9+
def generate_fake_profiles(num_profiles: int) -> List[dict]:
10+
"""
11+
Generate a list of fake profiles.
12+
13+
Args:
14+
num_profiles (int): Number of profiles to generate.
15+
16+
Returns:
17+
List[dict]: A list of dictionaries where each represents a profile.
18+
"""
19+
profiles = []
20+
for _ in range(num_profiles):
21+
profile = {
22+
"Locale": fake.locales,
23+
"Name": fake.name(),
24+
"Email": fake.email(),
25+
"SSN": fake.ssn(),
26+
"Address": fake.address(),
27+
"Latitude": fake.latitude(),
28+
"Longitude": fake.longitude(),
29+
"URL": fake.url()
30+
}
31+
profiles.append(profile)
32+
return profiles
33+
34+
35+
def display_profiles(profiles: List[dict]):
36+
"""
37+
Display the generated profiles in a formatted way.
38+
39+
Args:
40+
profiles (List[dict]): A list of profiles to print.
41+
"""
42+
for index, profile in enumerate(profiles, start=1):
43+
print(f"\n### Faker Profile {index} ###")
44+
print(f"Locale : {', '.join(profile['Locale'])}")
45+
print(f"Name : {profile['Name']}")
46+
print(f"Email : {profile['Email']}")
47+
print(f"Social Security number (SSN) : {profile['SSN']}")
48+
print(f"Address : {profile['Address']}")
49+
print(f"Location : ({profile['Latitude']}, {profile['Longitude']})")
50+
print(f"URL : {profile['URL']}")
51+
print("-" * 40)
52+
53+
54+
def save_profiles_to_file(profiles: List[dict], filename: str) -> None:
55+
"""
56+
Save the list of profiles to a file in JSON format.
57+
58+
Args:
59+
profiles (List[dict]): The list of profiles to save.
60+
filename (str): The name of the output file.
61+
"""
62+
try:
63+
with open(filename, "w") as file:
64+
json.dump(profiles, file, indent=4)
65+
print(f"\nProfiles successfully saved to {filename}")
66+
except Exception as e:
67+
print(f"Error while saving profiles to file: {e}")
68+
69+
70+
def main():
71+
"""
72+
Main function to handle user interaction and workflow.
73+
"""
74+
print("\n### Faker Profile Generator ###")
75+
try:
76+
num_profiles = int(input("Enter the number of profiles to generate: "))
77+
if num_profiles < 1:
78+
raise ValueError("Number of profiles must be greater than 0.")
79+
80+
# Generate fake profiles
81+
profiles = generate_fake_profiles(num_profiles)
82+
83+
# Display profiles
84+
display_profiles(profiles)
85+
86+
# Save to file
87+
save_option = input("Do you want to save the profiles to a file? (y/n): ").strip().lower()
88+
if save_option == "y":
89+
filename = input("Enter filename (e.g., profiles.json): ").strip()
90+
save_profiles_to_file(profiles, filename)
91+
92+
print("\nProcess completed successfully!")
93+
except ValueError as ve:
94+
print(f"Invalid input: {ve}")
95+
except Exception as e:
96+
print(f"An unexpected error occurred: {e}")
97+
98+
99+
# Run the script
100+
if __name__ == "__main__":
101+
main()
+54-63
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,87 @@
11
import random as rr
22
import string as ss
33

4-
5-
6-
"""
7-
ASCII
8-
A -> Z : 65 -> 90
9-
a -> z : 97 -> 122
10-
"""
11-
124
characters = ['@', '#', '$', '%', '&', '?']
135

146

15-
pass_len = int(input('How lengthy do you want your password to be : '))
7+
def generate_password(pass_len):
8+
# Initialize counters
9+
total_nums = 0
10+
total_symbols = 0
11+
total_cap = 0
12+
total_low = 0
1613

17-
tempy, tempz = 0, 0
18-
tempx = rr.randint(2, pass_len-1) # alphabets
14+
# Ensure at least one of each type
15+
tempx = rr.randint(2, max(2, pass_len - 2)) # at least 2 letters
16+
remaining = pass_len - tempx
1917

20-
if tempx != pass_len:
21-
tempy = rr.randint(1, (pass_len - tempx - 1)) # numbers
18+
tempy = rr.randint(1, max(1, remaining - 1)) # at least 1 number
19+
remaining -= tempy
2220
total_nums = tempy
2321

24-
if (tempx + tempy) != pass_len:
25-
tempz = rr.randint(1, (pass_len-(tempx+tempy))) # special characters
22+
tempz = remaining # rest goes to special characters
2623
total_symbols = tempz
2724

28-
# password : empty string for now
29-
pass_word = ''
30-
31-
# adding alphabets
32-
33-
while tempx:
34-
x = tempx
35-
num_cap = rr.randint(0, x)
36-
num_low = x-num_cap
25+
# Generate password
26+
pass_word = ''
3727

28+
# Add alphabets
29+
num_cap = rr.randint(1, tempx - 1) # at least 1 uppercase
30+
num_low = tempx - num_cap # rest lowercase
3831
total_cap = num_cap
3932
total_low = num_low
4033

41-
# capitals in password :
42-
while num_cap:
43-
temp = chr(rr.randint(65, 90))
44-
pass_word = pass_word + str(temp)
45-
num_cap -= 1
46-
47-
# lower-case in password :
48-
while num_low:
49-
temp = chr(rr.randint(97, 122))
50-
pass_word = pass_word + str(temp)
51-
num_low -= 1
52-
53-
break
54-
55-
# adding numbers to the password
56-
while tempy:
57-
temp = (rr.randint(0, 9))
58-
pass_word = pass_word + str(temp)
59-
tempy -= 1
60-
61-
# adding special characters to the password
62-
while tempz:
63-
temp = rr.randint(0, len(characters)-1)
64-
pass_word = pass_word + characters[temp]
65-
tempz -= 1
66-
67-
#shuffles the string
34+
# Add capitals
35+
pass_word += ''.join(chr(rr.randint(65, 90)) for _ in range(num_cap))
36+
37+
# Add lowercase
38+
pass_word += ''.join(chr(rr.randint(97, 122)) for _ in range(num_low))
39+
40+
# Add numbers
41+
pass_word += ''.join(str(rr.randint(0, 9)) for _ in range(tempy))
42+
43+
# Add special characters
44+
pass_word += ''.join(rr.choice(characters) for _ in range(tempz))
45+
46+
return pass_word, total_cap, total_low, total_nums, total_symbols
47+
48+
6849
def shuffle_(alpha):
6950
str_temp = list(alpha)
7051
rr.shuffle(str_temp)
71-
alpha = ''.join(str_temp)
72-
return alpha
52+
return ''.join(str_temp)
53+
7354

74-
#adds colour to the text
7555
def colored(r, g, b, text):
7656
return "\033[38;2;{};{};{}m{} \033[38;2;255;255;255m".format(r, g, b, text)
7757

78-
final_pass =colored(200,200,50, (shuffle_(shuffle_(shuffle_(pass_word)))))
7958

59+
def main():
60+
pass_len = int(input('How lengthy do you want your password to be : '))
8061

81-
# result & summary
82-
result = """
83-
Generate Password Summary :
62+
if pass_len < 4:
63+
print("Password length must be at least 4 characters")
64+
return
8465

85-
Charactor Uppercase : {0}
86-
Charactor Lowercase : {1}
66+
pass_word, total_cap, total_low, total_nums, total_symbols = generate_password(pass_len)
67+
68+
# Shuffle multiple times
69+
final_pass = colored(200, 200, 50, shuffle_(shuffle_(shuffle_(pass_word))))
70+
71+
result = """
72+
Generate Password Summary:
73+
74+
Character Uppercase : {0}
75+
Character Lowercase : {1}
8776
Numbers : {2}
8877
Symbols : {3}
8978
90-
Your computer generated password is :
79+
Your computer generated password is:
9180
{4}
9281
""".format(total_cap, total_low, total_nums, total_symbols, final_pass)
9382

94-
print(result)
83+
print(result)
84+
9585

96-
# print(f"\nYour computer generated password is : {final_pass}\n\n")
86+
if __name__ == "__main__":
87+
main()

0 commit comments

Comments
 (0)