From c0e81dbb7efbee65c231a122819206dad03ce7af Mon Sep 17 00:00:00 2001 From: Xceptions Date: Tue, 7 May 2024 18:27:57 +0100 Subject: [PATCH 001/442] Create README.md --- Search_Engine/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 Search_Engine/README.md diff --git a/Search_Engine/README.md b/Search_Engine/README.md new file mode 100644 index 00000000000..ab053aa7739 --- /dev/null +++ b/Search_Engine/README.md @@ -0,0 +1 @@ +Python Program to search through various documents and return the documents containing the search term From 9f1cc69ceac8b738fd15d17f040fd144a5a83652 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Tue, 7 May 2024 18:57:02 +0100 Subject: [PATCH 002/442] Create test.py --- Search_Engine/test.py | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 Search_Engine/test.py diff --git a/Search_Engine/test.py b/Search_Engine/test.py new file mode 100644 index 00000000000..d58f43e7d17 --- /dev/null +++ b/Search_Engine/test.py @@ -0,0 +1,8 @@ +documents = [ + "we should all strive to be happy", + "happiness is all you need", + "a cheerful heart is a happy one", + "no way should we be sad" +] + +search = "happy" \ No newline at end of file From cf85162e72fc5aa0e78ff68b651b9869391e21bf Mon Sep 17 00:00:00 2001 From: Xceptions Date: Wed, 8 May 2024 15:02:10 +0100 Subject: [PATCH 003/442] pushed ability to create db --- Search_Engine/backend.py | 34 ++++++++++++++++++++++++++++++++++ Search_Engine/test_data.py | 8 ++++++++ 2 files changed, 42 insertions(+) create mode 100644 Search_Engine/backend.py create mode 100644 Search_Engine/test_data.py diff --git a/Search_Engine/backend.py b/Search_Engine/backend.py new file mode 100644 index 00000000000..d3cb8df12ce --- /dev/null +++ b/Search_Engine/backend.py @@ -0,0 +1,34 @@ +import sqlite3 +import test_data + +class SearchEngine: + def __init__(self, document1): + # initialize database + conn = sqlite3.connect("searchengine.db") + cur = conn.cursor() + cur.execute("CREATE TABLE DocumentStore(id INTEGER PRIMARY KEY, document TEXT)") + cur.execute("INSERT INTO DocumentStore (document) VALUES (?)", (document1,)) + conn.commit() + res = cur.execute("SELECT * FROM DocumentStore") + print(res.fetchall()) + # self.index = test_data['documents'][:-1] + # cur = conn.execute('CREATE TABLE keyvals (key TEXT PRIMARY KEY, value TEXT)') + + def index_document(self, document): + doc_num = 1 + for word in document: + if word not in self.index: + self.index[word] = set([doc_num]) + else: + self.index.add(doc_num) + print(self.index) + + + def find_documents(self, search_term): + pass + + def _search_index(self): + pass + +if __name__ == "__main__": + SearchEngine("we should all strive to be happy") \ No newline at end of file diff --git a/Search_Engine/test_data.py b/Search_Engine/test_data.py new file mode 100644 index 00000000000..d58f43e7d17 --- /dev/null +++ b/Search_Engine/test_data.py @@ -0,0 +1,8 @@ +documents = [ + "we should all strive to be happy", + "happiness is all you need", + "a cheerful heart is a happy one", + "no way should we be sad" +] + +search = "happy" \ No newline at end of file From 1a741e7db1ae16ba880eeecefde41399e10644f8 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Wed, 8 May 2024 17:50:45 +0100 Subject: [PATCH 004/442] updated method to create tables if not exists --- Search_Engine/backend.py | 26 ++++++++++++++++++-------- Search_Engine/test.py | 8 -------- 2 files changed, 18 insertions(+), 16 deletions(-) delete mode 100644 Search_Engine/test.py diff --git a/Search_Engine/backend.py b/Search_Engine/backend.py index d3cb8df12ce..fb170aaf2ee 100644 --- a/Search_Engine/backend.py +++ b/Search_Engine/backend.py @@ -3,16 +3,26 @@ class SearchEngine: def __init__(self, document1): - # initialize database - conn = sqlite3.connect("searchengine.db") - cur = conn.cursor() - cur.execute("CREATE TABLE DocumentStore(id INTEGER PRIMARY KEY, document TEXT)") - cur.execute("INSERT INTO DocumentStore (document) VALUES (?)", (document1,)) - conn.commit() - res = cur.execute("SELECT * FROM DocumentStore") + """ + - Initialize database. + - Check if the tables exist, if not create them + """ + self.conn = sqlite3.connect("searchengine.db") + cur = self.conn.cursor() + res = cur.execute("SELECT name FROM sqlite_master WHERE name='IndexToWord'") + tables_exist = res.fetchone() + # tables_exist = res.fetchall() + if not tables_exist: + self.conn.execute("CREATE TABLE IndexToWord(id INTEGER PRIMARY KEY, document TEXT)") + self.conn.execute('CREATE TABLE WordToIndex (store TEXT)') + # self.conn.commit() + + # cur.execute("INSERT INTO DocumentStore (document) VALUES (?)", (document1,)) + # self.conn.commit() + res = cur.execute("SELECT name FROM sqlite_master") print(res.fetchall()) # self.index = test_data['documents'][:-1] - # cur = conn.execute('CREATE TABLE keyvals (key TEXT PRIMARY KEY, value TEXT)') + # def index_document(self, document): doc_num = 1 diff --git a/Search_Engine/test.py b/Search_Engine/test.py deleted file mode 100644 index d58f43e7d17..00000000000 --- a/Search_Engine/test.py +++ /dev/null @@ -1,8 +0,0 @@ -documents = [ - "we should all strive to be happy", - "happiness is all you need", - "a cheerful heart is a happy one", - "no way should we be sad" -] - -search = "happy" \ No newline at end of file From 446fd9a50d800cbe9e2be0e22fc99cf2c1ab8eb6 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Wed, 8 May 2024 18:22:29 +0100 Subject: [PATCH 005/442] added the method to add the document to the idtodoc db --- Search_Engine/backend.py | 70 ++++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 13 deletions(-) diff --git a/Search_Engine/backend.py b/Search_Engine/backend.py index fb170aaf2ee..dfb76821e01 100644 --- a/Search_Engine/backend.py +++ b/Search_Engine/backend.py @@ -2,19 +2,31 @@ import test_data class SearchEngine: - def __init__(self, document1): + """ + It works by building a reverse index store that maps + words to an id. To find the document(s) that contain + a certain search term, we then take an intersection + of the ids + """ + + def __init__(self): """ - - Initialize database. + Return - None + Input - None + ---------- + - Initialize database. we use sqlite3 - Check if the tables exist, if not create them + - maintain a class level access to the database + connection object """ self.conn = sqlite3.connect("searchengine.db") cur = self.conn.cursor() - res = cur.execute("SELECT name FROM sqlite_master WHERE name='IndexToWord'") + res = cur.execute("SELECT name FROM sqlite_master WHERE name='IdToDoc'") tables_exist = res.fetchone() # tables_exist = res.fetchall() if not tables_exist: - self.conn.execute("CREATE TABLE IndexToWord(id INTEGER PRIMARY KEY, document TEXT)") - self.conn.execute('CREATE TABLE WordToIndex (store TEXT)') + self.conn.execute("CREATE TABLE IdToDoc(id INTEGER PRIMARY KEY, document TEXT)") + self.conn.execute('CREATE TABLE WordToId (store TEXT)') # self.conn.commit() # cur.execute("INSERT INTO DocumentStore (document) VALUES (?)", (document1,)) @@ -25,13 +37,42 @@ def __init__(self, document1): # def index_document(self, document): - doc_num = 1 - for word in document: - if word not in self.index: - self.index[word] = set([doc_num]) - else: - self.index.add(doc_num) - print(self.index) + """ + Returns - + Input - str: a string of words called document + ---------- + Indexes the document. It does this by performing two + operations - add the document to the IdToDoc, then + adds the words in the document to WordToId + - takes in the document (str) + - passes the document to a method to add the document + to IdToDoc + - retrieves the id of the inserted document + - uses the id to call the method that adds the words of + the document to the index WordToId + """ + self._add_to_IdToDoc(document) + # self._add_to_WordToId(document) + # doc_num = 1 + # for word in document: + # if word not in self.index: + # self.index[word] = set([doc_num]) + # else: + # self.index.add(doc_num) + # print(self.index) + + def _add_to_IdToDoc(self, document): + """ + Returns - int: the id of the inserted document + Input - str: a string of words called `document` + --------- + - use the class-level connection object to insert the document + into the db + - retrieve and return the row id of the inserted document + """ + res = self.conn.execute("INSERT INTO IdToDoc (document) VALUES (?)", (document,)) + return res.lastrowid + def find_documents(self, search_term): @@ -41,4 +82,7 @@ def _search_index(self): pass if __name__ == "__main__": - SearchEngine("we should all strive to be happy") \ No newline at end of file + se = SearchEngine() + se.index_document("we should all strive to be happy") + se.index_document("happiness is all you need") + se.index_document("no way should we be sad") \ No newline at end of file From 4c9270c86991f172973fb855eaf0eafa5314a2e2 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Fri, 10 May 2024 01:01:07 +0100 Subject: [PATCH 006/442] updated add to idtodoc method --- Search_Engine/backend.py | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/Search_Engine/backend.py b/Search_Engine/backend.py index dfb76821e01..c0d94387690 100644 --- a/Search_Engine/backend.py +++ b/Search_Engine/backend.py @@ -1,5 +1,6 @@ import sqlite3 import test_data +import ast class SearchEngine: """ @@ -11,7 +12,7 @@ class SearchEngine: def __init__(self): """ - Return - None + Returns - None Input - None ---------- - Initialize database. we use sqlite3 @@ -20,18 +21,19 @@ def __init__(self): connection object """ self.conn = sqlite3.connect("searchengine.db") - cur = self.conn.cursor() - res = cur.execute("SELECT name FROM sqlite_master WHERE name='IdToDoc'") + self.cur = self.conn.cursor() + res = self.cur.execute("SELECT name FROM sqlite_master WHERE name='IdToDoc'") tables_exist = res.fetchone() - # tables_exist = res.fetchall() + if not tables_exist: self.conn.execute("CREATE TABLE IdToDoc(id INTEGER PRIMARY KEY, document TEXT)") - self.conn.execute('CREATE TABLE WordToId (store TEXT)') + self.conn.execute('CREATE TABLE WordToId (name TEXT, value TEXT)') + self.cur.execute("INSERT INTO WordToId VALUES (?, ?)", ("index", "{}",)) # self.conn.commit() # cur.execute("INSERT INTO DocumentStore (document) VALUES (?)", (document1,)) # self.conn.commit() - res = cur.execute("SELECT name FROM sqlite_master") + res = self.cur.execute("SELECT name FROM sqlite_master") print(res.fetchall()) # self.index = test_data['documents'][:-1] # @@ -51,15 +53,16 @@ def index_document(self, document): - uses the id to call the method that adds the words of the document to the index WordToId """ - self._add_to_IdToDoc(document) - # self._add_to_WordToId(document) - # doc_num = 1 - # for word in document: - # if word not in self.index: - # self.index[word] = set([doc_num]) - # else: - # self.index.add(doc_num) - # print(self.index) + row_id = self._add_to_IdToDoc(document) + reverse_idx = self.cur.execute("SELECT value FROM WordToId WHERE name='index'").fetchone()[0] + reverse_idx = ast.literal_eval(reverse_idx) + document = document.split() + for word in document: + if word not in reverse_idx: + reverse_idx[word] = set([row_id]) + else: + reverse_idx.add(row_id) + print(reverse_idx) def _add_to_IdToDoc(self, document): """ @@ -83,6 +86,6 @@ def _search_index(self): if __name__ == "__main__": se = SearchEngine() - se.index_document("we should all strive to be happy") + se.index_document("we should all strive to be happy and happy again") se.index_document("happiness is all you need") se.index_document("no way should we be sad") \ No newline at end of file From 170abcfba18b0f57b002a38e1225c19ff5d8deef Mon Sep 17 00:00:00 2001 From: Nitkarsh Chourasia Date: Fri, 10 May 2024 18:20:20 +0530 Subject: [PATCH 007/442] duplicates: Poor implemented programs --- TowerOfHanoi.py | 14 -------------- tower_of_hanoi.py | 43 ------------------------------------------- 2 files changed, 57 deletions(-) delete mode 100644 TowerOfHanoi.py delete mode 100644 tower_of_hanoi.py diff --git a/TowerOfHanoi.py b/TowerOfHanoi.py deleted file mode 100644 index af89032fce0..00000000000 --- a/TowerOfHanoi.py +++ /dev/null @@ -1,14 +0,0 @@ -# Recursive Python function to solve the tower of hanoi -- - -def TowerOfHanoi(n , source, destination, auxiliary): - if n==1: - print ("Move disk 1 from source",source,"to destination",destination) - return - TowerOfHanoi(n-1, source, auxiliary, destination) - print ("Move disk",n,"from source",source,"to destination",destination) - TowerOfHanoi(n-1, auxiliary, destination, source) - -# Driver code -n = 4 -TowerOfHanoi(n,'A','B','C') -# A, C, B are the name of rods diff --git a/tower_of_hanoi.py b/tower_of_hanoi.py deleted file mode 100644 index 0fbf061b96a..00000000000 --- a/tower_of_hanoi.py +++ /dev/null @@ -1,43 +0,0 @@ -"""Tower of Hanoi is a mathematical puzzle where we have three rods and n disks. The objective of the puzzle is to move - the entire stack to another rod, obeying the following simple rules: -1) Only one disk can be moved at a time. -2) Each move consists of taking the upper disk from one of the stacks and placing it on top of another stack i.e. a disk - can only be moved if it is the uppermost disk on a stack. -3) No disk may be placed on top of a smaller disk. -APPROACH: -Take an example for 2 disks : -Let rod 1 = 'SOURCE', rod 2 = 'TEMPORARY', rod 3 = 'DESTINATION'. - -Step 1 : Shift first disk from 'SOURCE' to 'TEMPORARY'. -Step 2 : Shift second disk from 'SOURCE' to 'DESTINATION'. -Step 3 : Shift first disk from 'TEMPORARY' to 'DESTINATION'. - -The pattern here is : -Shift 'n-1' disks from 'SOURCE' to 'TEMPORARY'. -Shift last disk from 'SOURCE' to 'DESTINATION'. -Shift 'n-1' disks from 'TEMPORARY' to 'DESTINATION'. -""" - - -def toh(n, s, t, d): - if n == 1: - print(s, "-->", d) - return - toh(n - 1, s, d, t) - print(s, "-->", d) - toh(n - 1, t, s, d) - - -if __name__ == "__main__": - while 1: - - n = int(input("""Enter number of disks:""")) - - if n < 0: - print("Try Again with a valid input") - continue - elif n == 0: - break - toh(n, "Source", "Temporary", "Destination") - - print("ENTER 0 TO EXIT") From 4f65a3ccc501d5336b38580c007f78f7a060539d Mon Sep 17 00:00:00 2001 From: Nitkarsh Chourasia Date: Fri, 10 May 2024 18:33:51 +0530 Subject: [PATCH 008/442] refactor: Concat output --- .../passwordGenerator.py | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 password_programs_multiple/passwordGenerator.py diff --git a/password_programs_multiple/passwordGenerator.py b/password_programs_multiple/passwordGenerator.py new file mode 100644 index 00000000000..1bde3d18051 --- /dev/null +++ b/password_programs_multiple/passwordGenerator.py @@ -0,0 +1,125 @@ +# PasswordGenerator GGearing 314 01/10/19 +# modified Prince Gangurde 4/4/2020 + +from random import randint +import pycountry + +case = randint(1, 2) +number = randint(1, 999) + +# TODO: Pick random country from it + +countries = list(pycountry.countries) +country_names = [country.name for country in countries] + +print(country_names) + +# TODO: Try to add languages, too. + +specialCharacters = ( + "!", + "@", + "#", + "$", + "%", + "/", + "?", + ":", + "<", + ">", + "|", + "&", + "*", + "-", + "=", + "+", + "_", +) + +animals = ( + "ant", + "alligator", + "baboon", + "badger", + "barb", + "bat", + "beagle", + "bear", + "beaver", + "bird", + "bison", + "bombay", + "bongo", + "booby", + "butterfly", + "bee", + "camel", + "cat", + "caterpillar", + "catfish", + "cheetah", + "chicken", + "chipmunk", + "cow", + "crab", + "deer", + "dingo", + "dodo", + "dog", + "dolphin", + "donkey", + "duck", + "eagle", + "earwig", + "elephant", + "emu", + "falcon", + "ferret", + "fish", + "flamingo", + "fly", + "fox", + "frog", + "gecko", + "gibbon", + "giraffe", + "goat", + "goose", + "gorilla", +) + +colour = ( + "red", + "orange", + "yellow", + "green", + "blue", + "indigo", + "violet", + "purple", + "magenta", + "cyan", + "pink", + "brown", + "white", + "grey", + "black", +) + +chosenanimal = animals[ + randint(0, len(animals) - 1) +] # randint will return max lenght but , tuple has index from 0 to len-1 +chosencolour = colour[randint(0, len(colour) - 1)] +chosenSpecialCharacter = specialCharacters[randint(0, len(specialCharacters) - 1)] + +if case == 1: + chosenanimal = chosenanimal.upper() + print(chosencolour + str(number) + chosenanimal + chosenSpecialCharacter) +else: + chosencolour = chosencolour.upper() + print(chosenanimal + str(number) + chosencolour + chosenSpecialCharacter) + +# Try to consolidate unify the characters. + + +# The program can be further improved. From 75ed4ffef8c915d7387037e0caaf193060db0414 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Sat, 11 May 2024 15:42:44 +0100 Subject: [PATCH 009/442] completed execute method for backend.py --- Search_Engine/backend.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Search_Engine/backend.py b/Search_Engine/backend.py index c0d94387690..5ec45b7013b 100644 --- a/Search_Engine/backend.py +++ b/Search_Engine/backend.py @@ -1,6 +1,7 @@ import sqlite3 import test_data import ast +import json class SearchEngine: """ @@ -26,8 +27,8 @@ def __init__(self): tables_exist = res.fetchone() if not tables_exist: - self.conn.execute("CREATE TABLE IdToDoc(id INTEGER PRIMARY KEY, document TEXT)") - self.conn.execute('CREATE TABLE WordToId (name TEXT, value TEXT)') + self.cur.execute("CREATE TABLE IdToDoc(id INTEGER PRIMARY KEY, document TEXT)") + self.cur.execute('CREATE TABLE WordToId (name TEXT, value TEXT)') self.cur.execute("INSERT INTO WordToId VALUES (?, ?)", ("index", "{}",)) # self.conn.commit() @@ -55,13 +56,16 @@ def index_document(self, document): """ row_id = self._add_to_IdToDoc(document) reverse_idx = self.cur.execute("SELECT value FROM WordToId WHERE name='index'").fetchone()[0] - reverse_idx = ast.literal_eval(reverse_idx) + reverse_idx = json.loads(reverse_idx) document = document.split() for word in document: if word not in reverse_idx: - reverse_idx[word] = set([row_id]) + reverse_idx[word] = [row_id] else: - reverse_idx.add(row_id) + if row_id not in reverse_idx[word]: # incase the word has already been indexed + reverse_idx[word].append(row_id) + reverse_idx = json.dumps(reverse_idx) + self.cur.execute("UPDATE WordToId SET value = (?) WHERE name='index'", (reverse_idx,)) print(reverse_idx) def _add_to_IdToDoc(self, document): @@ -73,7 +77,7 @@ def _add_to_IdToDoc(self, document): into the db - retrieve and return the row id of the inserted document """ - res = self.conn.execute("INSERT INTO IdToDoc (document) VALUES (?)", (document,)) + res = self.cur.execute("INSERT INTO IdToDoc (document) VALUES (?)", (document,)) return res.lastrowid From 4bd17e0a4db0cc38f77f1ca587413561935daac5 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Sun, 12 May 2024 18:53:30 +0100 Subject: [PATCH 010/442] added find_documents method --- Search_Engine/backend.py | 63 ++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/Search_Engine/backend.py b/Search_Engine/backend.py index 5ec45b7013b..8a539ec888c 100644 --- a/Search_Engine/backend.py +++ b/Search_Engine/backend.py @@ -22,20 +22,21 @@ def __init__(self): connection object """ self.conn = sqlite3.connect("searchengine.db") - self.cur = self.conn.cursor() - res = self.cur.execute("SELECT name FROM sqlite_master WHERE name='IdToDoc'") + cur = self.conn.cursor() + res = cur.execute("SELECT name FROM sqlite_master WHERE name='IdToDoc'") tables_exist = res.fetchone() if not tables_exist: - self.cur.execute("CREATE TABLE IdToDoc(id INTEGER PRIMARY KEY, document TEXT)") - self.cur.execute('CREATE TABLE WordToId (name TEXT, value TEXT)') - self.cur.execute("INSERT INTO WordToId VALUES (?, ?)", ("index", "{}",)) + self.conn.execute("CREATE TABLE IdToDoc(id INTEGER PRIMARY KEY, document TEXT)") + self.conn.execute('CREATE TABLE WordToId (name TEXT, value TEXT)') + cur.execute("INSERT INTO WordToId VALUES (?, ?)", ("index", "{}",)) # self.conn.commit() # cur.execute("INSERT INTO DocumentStore (document) VALUES (?)", (document1,)) # self.conn.commit() - res = self.cur.execute("SELECT name FROM sqlite_master") - print(res.fetchall()) + cur = self.conn.cursor() + res = cur.execute("SELECT name FROM sqlite_master") + # print(res.fetchall()) # self.index = test_data['documents'][:-1] # @@ -55,7 +56,8 @@ def index_document(self, document): the document to the index WordToId """ row_id = self._add_to_IdToDoc(document) - reverse_idx = self.cur.execute("SELECT value FROM WordToId WHERE name='index'").fetchone()[0] + cur = self.conn.cursor() + reverse_idx = cur.execute("SELECT value FROM WordToId WHERE name='index'").fetchone()[0] reverse_idx = json.loads(reverse_idx) document = document.split() for word in document: @@ -65,8 +67,9 @@ def index_document(self, document): if row_id not in reverse_idx[word]: # incase the word has already been indexed reverse_idx[word].append(row_id) reverse_idx = json.dumps(reverse_idx) - self.cur.execute("UPDATE WordToId SET value = (?) WHERE name='index'", (reverse_idx,)) - print(reverse_idx) + cur = self.conn.cursor() + cur.execute("UPDATE WordToId SET value = (?) WHERE name='index'", (reverse_idx,)) + # print(reverse_idx) def _add_to_IdToDoc(self, document): """ @@ -77,19 +80,47 @@ def _add_to_IdToDoc(self, document): into the db - retrieve and return the row id of the inserted document """ - res = self.cur.execute("INSERT INTO IdToDoc (document) VALUES (?)", (document,)) + cur = self.conn.cursor() + res = cur.execute("INSERT INTO IdToDoc (document) VALUES (?)", (document,)) return res.lastrowid + def find_documents(self, search_term): + cur = self.conn.cursor() + reverse_idx = cur.execute("SELECT value FROM WordToId WHERE name='index'").fetchone()[0] + reverse_idx = json.loads(reverse_idx) + search_term = search_term.split(" ") + all_docs_with_search_term = [] + for term in search_term: + if term in reverse_idx: + all_docs_with_search_term.append(reverse_idx[term]) + if not all_docs_with_search_term: # the search term does not exist + return [] - def find_documents(self, search_term): - pass + common_idx_of_docs = set(all_docs_with_search_term[0]) + for idx in all_docs_with_search_term[1:]: + common_idx_of_docs.intersection_update(idx) + + if not common_idx_of_docs: # the search term does not exist + return [] + + # print(common_idx_of_docs) + self._documents_with_idx(common_idx_of_docs) + + def _documents_with_idx(self, idxs): + cur = self.conn.cursor() + # reverse_idx = cur.execute("SELECT value FROM IdToDoc WHERE id=(?) or id=(?)", ()).fetchone()[0] + sql="SELECT value FROM IdToDoc WHERE id in ({seq})".format( + seq=','.join(['?']*len(idxs)) + ) + result = cur.execute(sql, idxs) + print(result) - def _search_index(self): - pass if __name__ == "__main__": se = SearchEngine() se.index_document("we should all strive to be happy and happy again") se.index_document("happiness is all you need") - se.index_document("no way should we be sad") \ No newline at end of file + se.index_document("no way should we be sad") + se.index_document("a cheerful heart is a happy one") + se.find_documents("happy") \ No newline at end of file From 7c05aeed527d4f4e555b0c509936f3ade120b518 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Sun, 12 May 2024 18:57:20 +0100 Subject: [PATCH 011/442] added the documents with ids method --- Search_Engine/backend.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Search_Engine/backend.py b/Search_Engine/backend.py index 8a539ec888c..e61b8aaf293 100644 --- a/Search_Engine/backend.py +++ b/Search_Engine/backend.py @@ -104,17 +104,16 @@ def find_documents(self, search_term): if not common_idx_of_docs: # the search term does not exist return [] - # print(common_idx_of_docs) - self._documents_with_idx(common_idx_of_docs) + return self._documents_with_idx(common_idx_of_docs) def _documents_with_idx(self, idxs): + idxs = list(idxs) cur = self.conn.cursor() - # reverse_idx = cur.execute("SELECT value FROM IdToDoc WHERE id=(?) or id=(?)", ()).fetchone()[0] - sql="SELECT value FROM IdToDoc WHERE id in ({seq})".format( + sql="SELECT document FROM IdToDoc WHERE id in ({seq})".format( seq=','.join(['?']*len(idxs)) - ) - result = cur.execute(sql, idxs) - print(result) + ) + result = cur.execute(sql, idxs).fetchall() + return(result) if __name__ == "__main__": From 10fa22da5b9f4973553c880af55729913b9be840 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Sun, 12 May 2024 19:16:50 +0100 Subject: [PATCH 012/442] added comment for find_documents method --- Search_Engine/backend.py | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/Search_Engine/backend.py b/Search_Engine/backend.py index e61b8aaf293..5d9c8628c83 100644 --- a/Search_Engine/backend.py +++ b/Search_Engine/backend.py @@ -30,19 +30,16 @@ def __init__(self): self.conn.execute("CREATE TABLE IdToDoc(id INTEGER PRIMARY KEY, document TEXT)") self.conn.execute('CREATE TABLE WordToId (name TEXT, value TEXT)') cur.execute("INSERT INTO WordToId VALUES (?, ?)", ("index", "{}",)) - # self.conn.commit() - # cur.execute("INSERT INTO DocumentStore (document) VALUES (?)", (document1,)) - # self.conn.commit() cur = self.conn.cursor() - res = cur.execute("SELECT name FROM sqlite_master") + # res = cur.execute("SELECT name FROM sqlite_master") # print(res.fetchall()) # self.index = test_data['documents'][:-1] # def index_document(self, document): """ - Returns - + Returns - Input - str: a string of words called document ---------- Indexes the document. It does this by performing two @@ -53,7 +50,8 @@ def index_document(self, document): to IdToDoc - retrieves the id of the inserted document - uses the id to call the method that adds the words of - the document to the index WordToId + the document to the reverse index WordToId if the word has not + already been indexed """ row_id = self._add_to_IdToDoc(document) cur = self.conn.cursor() @@ -64,12 +62,12 @@ def index_document(self, document): if word not in reverse_idx: reverse_idx[word] = [row_id] else: - if row_id not in reverse_idx[word]: # incase the word has already been indexed + if row_id not in reverse_idx[word]: reverse_idx[word].append(row_id) reverse_idx = json.dumps(reverse_idx) cur = self.conn.cursor() - cur.execute("UPDATE WordToId SET value = (?) WHERE name='index'", (reverse_idx,)) - # print(reverse_idx) + result = cur.execute("UPDATE WordToId SET value = (?) WHERE name='index'", (reverse_idx,)) + return(result) def _add_to_IdToDoc(self, document): """ @@ -85,6 +83,16 @@ def _add_to_IdToDoc(self, document): return res.lastrowid def find_documents(self, search_term): + """ + Returns - : the return value of the _find_documents_with_idx method + Input - str: a string of words called `search_term` + --------- + - retrieve the reverse index + - use the words contained in the search term to find all the idxs + that contain the word + - use idxs to call the _find_documents_with_idx method + - return the result of the called method + """ cur = self.conn.cursor() reverse_idx = cur.execute("SELECT value FROM WordToId WHERE name='index'").fetchone()[0] reverse_idx = json.loads(reverse_idx) @@ -104,9 +112,9 @@ def find_documents(self, search_term): if not common_idx_of_docs: # the search term does not exist return [] - return self._documents_with_idx(common_idx_of_docs) + return self._find_documents_with_idx(common_idx_of_docs) - def _documents_with_idx(self, idxs): + def _find_documents_with_idx(self, idxs): idxs = list(idxs) cur = self.conn.cursor() sql="SELECT document FROM IdToDoc WHERE id in ({seq})".format( @@ -119,7 +127,7 @@ def _documents_with_idx(self, idxs): if __name__ == "__main__": se = SearchEngine() se.index_document("we should all strive to be happy and happy again") - se.index_document("happiness is all you need") + print(se.index_document("happiness is all you need")) se.index_document("no way should we be sad") se.index_document("a cheerful heart is a happy one") - se.find_documents("happy") \ No newline at end of file + print(se.find_documents("happy")) \ No newline at end of file From 33d4a0211657e7aa770a70bfccade3f67e6ff77d Mon Sep 17 00:00:00 2001 From: Xceptions Date: Sun, 12 May 2024 19:20:16 +0100 Subject: [PATCH 013/442] add comment to _find_documents_with_idx method --- Search_Engine/backend.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Search_Engine/backend.py b/Search_Engine/backend.py index 5d9c8628c83..ced5632a1f7 100644 --- a/Search_Engine/backend.py +++ b/Search_Engine/backend.py @@ -115,6 +115,14 @@ def find_documents(self, search_term): return self._find_documents_with_idx(common_idx_of_docs) def _find_documents_with_idx(self, idxs): + """ + Returns - list[str]: the list of documents with the idxs + Input - list of idxs + --------- + - use the class-level connection object to retrieve the documents that + have the idx in the input list of idxs. + - retrieve and return these documents as a list + """ idxs = list(idxs) cur = self.conn.cursor() sql="SELECT document FROM IdToDoc WHERE id in ({seq})".format( From c8013416b6e958424bb64ea96b2e946fb06ada9c Mon Sep 17 00:00:00 2001 From: Xceptions Date: Sun, 12 May 2024 19:21:17 +0100 Subject: [PATCH 014/442] removed all unnecessary comments --- Search_Engine/backend.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Search_Engine/backend.py b/Search_Engine/backend.py index ced5632a1f7..52524167a09 100644 --- a/Search_Engine/backend.py +++ b/Search_Engine/backend.py @@ -31,12 +31,6 @@ def __init__(self): self.conn.execute('CREATE TABLE WordToId (name TEXT, value TEXT)') cur.execute("INSERT INTO WordToId VALUES (?, ?)", ("index", "{}",)) - cur = self.conn.cursor() - # res = cur.execute("SELECT name FROM sqlite_master") - # print(res.fetchall()) - # self.index = test_data['documents'][:-1] - # - def index_document(self, document): """ Returns - From f5a49a9d189290b3f2e1bfea01f9a4da556a7193 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 18:36:43 +0000 Subject: [PATCH 015/442] build(deps): bump solara from 1.32.1 to 1.32.2 Bumps [solara](https://github.com/widgetti/solara) from 1.32.1 to 1.32.2. - [Changelog](https://github.com/widgetti/solara/blob/master/CHANGELOG.md) - [Commits](https://github.com/widgetti/solara/compare/v1.32.1...v1.32.2) --- updated-dependencies: - dependency-name: solara dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- News_App/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/News_App/requirements.txt b/News_App/requirements.txt index 308234e5089..39898116fb8 100644 --- a/News_App/requirements.txt +++ b/News_App/requirements.txt @@ -1,4 +1,4 @@ -solara == 1.32.1 +solara == 1.32.2 Flask gunicorn ==22.0.0 simple-websocket diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index a8a736f9dba..d5b75def04e 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -74,7 +74,7 @@ xor-cipher==4.0.0 bird==0.1.2 mechanize==0.4.9 translate==3.6.1 -solara==1.32.1 +solara==1.32.2 pywhatkit==5.4 mutagen==1.47.0 Unidecode==1.3.8 From 29fa85975b16666b4d9b265f2d2ba9440da92a86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 18:36:47 +0000 Subject: [PATCH 016/442] build(deps): bump mechanize from 0.4.9 to 0.4.10 Bumps [mechanize](https://github.com/python-mechanize/mechanize) from 0.4.9 to 0.4.10. - [Changelog](https://github.com/python-mechanize/mechanize/blob/master/ChangeLog) - [Commits](https://github.com/python-mechanize/mechanize/compare/v0.4.9...v0.4.10) --- updated-dependencies: - dependency-name: mechanize dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index a8a736f9dba..f1060820276 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -72,7 +72,7 @@ tkcalendar==1.6.1 pytube==15.0.0 xor-cipher==4.0.0 bird==0.1.2 -mechanize==0.4.9 +mechanize==0.4.10 translate==3.6.1 solara==1.32.1 pywhatkit==5.4 From 8ce23be1c2c27db7b3be35b5e35921cef2b9327d Mon Sep 17 00:00:00 2001 From: Nitkarsh Chourasia Date: Tue, 14 May 2024 13:03:14 +0530 Subject: [PATCH 017/442] add: animal names get successful. --- .../animal_name_scraiper.py | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 password_programs_multiple/animal_name_scraiper.py diff --git a/password_programs_multiple/animal_name_scraiper.py b/password_programs_multiple/animal_name_scraiper.py new file mode 100644 index 00000000000..8204e90d794 --- /dev/null +++ b/password_programs_multiple/animal_name_scraiper.py @@ -0,0 +1,75 @@ +import requests +from requests import get +from bs4 import BeautifulSoup +import pandas as pd +import numpy as np +import html5lib + +# * Using html5lib as the parser is good +# * It is the most lenient parser and works as + +animals_A_to_Z_URL = "https://animalcorner.org/animal-sitemap/#" + +results = requests.get(animals_A_to_Z_URL) +# ? results and results.text ? what are these? + +# soup = BeautifulSoup(results.text, "html.parser") +# * will use html5lib as the parser +soup = BeautifulSoup(results.text, "html5lib") + +# print(soup.prettify()) + +# To store animal names +animal_name = [] + +# To store the titles of animals +animal_title = [] + +# alphabet_head = soup.find_all("div", class_="wp-block-heading") +# alphabet_head = soup.find_all("div", class_="side-container") +# * .text all it's immediate text and children +# * .string only the immediate text +# print(soup.find_all("h2", class_="wp-block-heading")) +# az_title = soup.find_all("h2", class_="wp-block-heading") +az_names = soup.find_all( + "div", class_="wp-block-column is-layout-flow wp-block-column-is-layout-flow" +) +# az_title = soup +# for title in az_title: +# # print(title.text) +# print(title.string) +# print(title.find(class_="wp-block-testing")) + +for name_div in az_names: + a_names = name_div.find_all("br") + + for elements in a_names: + # print(elements.text) + # print(elements, end="\n") + next_sibling = elements.next_sibling + # Check if the next sibling exists and if it's not a
element + while next_sibling and next_sibling.name == "br": + next_sibling = next_sibling.next_sibling + + + # Print the text content of the next sibling element + if next_sibling: + print(next_sibling.text.strip()) + + # print(name.text) + +# print(soup.h2.string) + +# for container in alphabet_head: +# print(container.text, end="\n") +# titles = container.div.div.find("h2", class_="wp-block-heading") +# title = container.find("h2", class_="wp-block-heading") +# title = container.h3.text +# print(title.text, end="\n") + +# print(container.find_all("h2", class_ = "wp-block-heading")) + + +# print(soup.get_text(), end="\p") + +# Want to write it to a file and sort and analyse it From 9d40d967b4f3c886cbbdf478a6844926b91d1350 Mon Sep 17 00:00:00 2001 From: Nitkarsh Chourasia Date: Tue, 14 May 2024 13:24:12 +0530 Subject: [PATCH 018/442] add: base file to create docs. --- repo_website/docs/README_og.md | 1061 +++++++++++++++++++++++++++++ repo_website/docs/img/favicon.ico | Bin 0 -> 15406 bytes repo_website/mkdocs.yml | 77 +++ 3 files changed, 1138 insertions(+) create mode 100644 repo_website/docs/README_og.md create mode 100644 repo_website/docs/img/favicon.ico create mode 100644 repo_website/mkdocs.yml diff --git a/repo_website/docs/README_og.md b/repo_website/docs/README_og.md new file mode 100644 index 00000000000..dd22d5ccfb3 --- /dev/null +++ b/repo_website/docs/README_og.md @@ -0,0 +1,1061 @@ +# Condensed Documentation + +Condensed python documentation on how to use python programming language. + +```python + + +# Single line comments start with a number symbol. + +""" Multiline strings can be written + using three "s, and are often used + as documentation. +""" + +#################################################### +## 1. Primitive Datatypes and Operators +#################################################### + +# You have numbers +9 # => 9 + +# Math is what you would expect +1 + 3 # => 4 +8 - 4 # => 4 +10 * 9 # => 90 +35 / 5 # => 7.0 + +# Integer division rounds down for both positive and negative numbers. +5 // 3 # => 1 +-5 // 3 # => -2 +5.0 // 3.0 # => 1.0 # works on floats too +-5.0 // 3.0 # => -2.0 + +# The result of division is always a float +10.0 / 3 # => 3.3333333333333335 + +# Modulo operation +7 % 3 # => 1 +# i % j have the same sign as j, unlike C +-7 % 3 # => 2 + +# Exponentiation (x**y, x to the yth power) +2**4 # => 16 + +# Enforce precedence with parentheses +1 + 3 * 2 # => 7 +(1 + 4) * 2 # => 10 + +# Boolean values are primitives (Note: the capitalization) +True # => True +False # => False + +# negate with not +not True # => False +not False # => True + +# Boolean Operators +# Note "and" and "or" are case-sensitive +True and False # => False +False or True # => True + +# True and False are actually 1 and 0 but with different keywords +True + True # => 2 +True * 8 # => 8 +False - 5 # => -5 + +# Comparison operators look at the numerical value of True and False +0 == False # => True +2 > True # => True +2 == True # => False +-5 != False # => True + +# None, 0, and empty strings/lists/dicts/tuples/sets all evaluate to False. +# All other values are True +bool(0) # => False +bool("") # => False +bool([]) # => False +bool({}) # => False +bool(()) # => False +bool(set()) # => False +bool(4) # => True +bool(-6) # => True + +# Using boolean logical operators on ints casts them to booleans for evaluation, +# but their non-cast value is returned. Don't mix up with bool(ints) and bitwise +# and/or (&,|) +bool(0) # => False +bool(2) # => True +0 and 2 # => 0 +bool(-5) # => True +bool(2) # => True +-5 or 0 # => -5 + +# Equality is == +1 == 1 # => True +2 == 1 # => False + +# Inequality is != +1 != 1 # => False +2 != 1 # => True + +# More comparisons +1 < 10 # => True +1 > 10 # => False +2 <= 2 # => True +2 >= 2 # => True + +# Seeing whether a value is in a range +1 < 2 and 2 < 3 # => True +2 < 3 and 3 < 2 # => False +# Chaining makes this look nicer +1 < 2 < 3 # => True +2 < 3 < 2 # => False + +# (is vs. ==) is checks if two variables refer to the same object, but == checks +# if the objects pointed to have the same values. +a = [1, 2, 3, 4] # Point a at a new list, [1, 2, 3, 4] +b = a # Point b at what a is pointing to +b is a # => True, a and b refer to the same object +b == a # => True, a's and b's objects are equal +b = [1, 2, 3, 4] # Point b at a new list, [1, 2, 3, 4] +b is a # => False, a and b do not refer to the same object +b == a # => True, a's and b's objects are equal + +# Strings are created with " or ' +"This is a string." +'This is also a string.' + +# Strings can be added too +"Hello " + "world!" # => "Hello world!" +# String literals (but not variables) can be concatenated without using '+' +"Hello " "world!" # => "Hello world!" + +# A string can be treated like a list of characters +"Hello world!"[0] # => 'H' + +# You can find the length of a string +len("This is a string") # => 16 + +# Since Python 3.6, you can use f-strings or formatted string literals. +name = "Pallavi" +f"She said her name is {name}." # => "She said her name is Pallavi." +# Any valid Python expression inside these braces is returned to the string. +f"{name} is {len(name)} characters long." # => "Nitkarsh is 8 characters long." + +# None is an object +None # => None + +# Don't use the equality "==" symbol to compare objects to None +# Use "is" instead. This checks for equality of object identity. +"etc" is None # => False +None is None # => True + +#################################################### +## 2. Variables and Collections +#################################################### + +# Python has a print function +print("I'm Nitkarsh. Nice to meet you!") # => I'm Nitkarsh. Nice to meet you! + +# By default the print function also prints out a newline at the end. +# Use the optional argument end to change the end string. +print("Hello, World", end="!") # => Hello, World! + +# Simple way to get input data from console +input_string_var = input("Enter some data: ") # Returns the data as a string + +# There are no declarations, only assignments. +# Convention is to use lower_case_with_underscores +some_var = 5 +some_var # => 5 + +# Accessing a previously unassigned variable is an exception. +# See Control Flow to learn more about exception handling. +some_unknown_var # Raises a NameError + +# if can be used as an expression +# Equivalent of C's '?:' ternary operator +"yay!" if 0 > 1 else "nay!" # => "nay!" + +# Lists store sequences +li = [] +# You can start with a prefilled list +other_li = [4, 5, 6] + +# Add stuff to the end of a list with append +li.append(1) # li is now [1] +li.append(2) # li is now [1, 2] +li.append(4) # li is now [1, 2, 4] +li.append(3) # li is now [1, 2, 4, 3] +# Remove from the end with pop +li.pop() # => 3 and li is now [1, 2, 4] +# Let's put it back +li.append(3) # li is now [1, 2, 4, 3] again. + +# Access a list like you would any array +li[0] # => 1 +# Look at the last element +li[-1] # => 3 + +# Looking out of bounds is an IndexError +li[4] # Raises an IndexError + +# You can look at ranges with slice syntax. +# The start index is included, the end index is not +# (It's a closed/open range for you mathy types.) +li[1:3] # Return list from index 1 to 3 => [2, 4] +li[2:] # Return list starting from index 2 => [4, 3] +li[:3] # Return list from beginning until index 3 => [1, 2, 4] +li[::2] # Return list selecting every second entry => [1, 4] +li[::-1] # Return list in reverse order => [3, 4, 2, 1] +# Use any combination of these to make advanced slices +# li[start:end:step] + +# Make a one layer deep copy using slices +li2 = li[:] # => li2 = [1, 2, 4, 3] but (li2 is li) will result in false. + +# Remove arbitrary elements from a list with "del" +del li[2] # li is now [1, 2, 3] + +# Remove first occurrence of a value +li.remove(2) # li is now [1, 3] +li.remove(2) # Raises a ValueError as 2 is not in the list + +# Insert an element at a specific index +li.insert(1, 2) # li is now [1, 2, 3] again + +# Get the index of the first item found matching the argument +li.index(2) # => 1 +li.index(4) # Raises a ValueError as 4 is not in the list + +# You can add lists +# Note: values for li and for other_li are not modified. +li + other_li # => [1, 2, 3, 4, 5, 6] + +# Concatenate lists with "extend()" +li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6] + +# Check for existence in a list with "in" +1 in li # => True + +# Examine the length with "len()" +len(li) # => 6 + + +# Tuples are like lists but are immutable. +tup = (1, 2, 3) +tup[0] # => 1 +tup[0] = 3 # Raises a TypeError + +# Note that a tuple of length one has to have a comma after the last element but +# tuples of other lengths, even zero, do not. +type((1)) # => +type((1,)) # => +type(()) # => + +# You can do most of the list operations on tuples too +len(tup) # => 3 +tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6) +tup[:2] # => (1, 2) +2 in tup # => True + +# You can unpack tuples (or lists) into variables +a, b, c = (1, 2, 3) # a is now 1, b is now 2 and c is now 3 +# You can also do extended unpacking +a, *b, c = (1, 2, 3, 4) # a is now 1, b is now [2, 3] and c is now 4 +# Tuples are created by default if you leave out the parentheses +d, e, f = 4, 5, 6 # tuple 4, 5, 6 is unpacked into variables d, e and f +# respectively such that d = 4, e = 5 and f = 6 +# Now look how easy it is to swap two values +e, d = d, e # d is now 5 and e is now 4 + + +# Dictionaries store mappings from keys to values +empty_dict = {} +# Here is a prefilled dictionary +filled_dict = {"one": 1, "two": 2, "three": 3} + +# Note keys for dictionaries have to be immutable types. This is to ensure that +# the key can be converted to a constant hash value for quick look-ups. +# Immutable types include ints, floats, strings, tuples. +invalid_dict = {[1,2,3]: "123"} # => Yield a TypeError: unhashable type: 'list' +valid_dict = {(1,2,3):[1,2,3]} # Values can be of any type, however. + +# Look up values with [] +filled_dict["one"] # => 1 + +# Get all keys as an iterable with "keys()". We need to wrap the call in list() +# to turn it into a list. We'll talk about those later. Note - for Python +# versions <3.7, dictionary key ordering is not guaranteed. Your results might +# not match the example below exactly. However, as of Python 3.7, dictionary +# items maintain the order at which they are inserted into the dictionary. +list(filled_dict.keys()) # => ["three", "two", "one"] in Python <3.7 +list(filled_dict.keys()) # => ["one", "two", "three"] in Python 3.7+ + + +# Get all values as an iterable with "values()". Once again we need to wrap it +# in list() to get it out of the iterable. Note - Same as above regarding key +# ordering. +list(filled_dict.values()) # => [3, 2, 1] in Python <3.7 +list(filled_dict.values()) # => [1, 2, 3] in Python 3.7+ + +# Check for existence of keys in a dictionary with "in" +"one" in filled_dict # => True +1 in filled_dict # => False + +# Looking up a non-existing key is a KeyError +filled_dict["four"] # KeyError + +# Use "get()" method to avoid the KeyError +filled_dict.get("one") # => 1 +filled_dict.get("four") # => None +# The get method supports a default argument when the value is missing +filled_dict.get("one", 4) # => 1 +filled_dict.get("four", 4) # => 4 + +# "setdefault()" inserts into a dictionary only if the given key isn't present +filled_dict.setdefault("five", 5) # filled_dict["five"] is set to 5 +filled_dict.setdefault("five", 6) # filled_dict["five"] is still 5 + +# Adding to a dictionary +filled_dict.update({"four":4}) # => {"one": 1, "two": 2, "three": 3, "four": 4} +filled_dict["four"] = 4 # another way to add to dict + +# Remove keys from a dictionary with del +del filled_dict["one"] # Removes the key "one" from filled dict + +# From Python 3.5 you can also use the additional unpacking options +{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2} +{'a': 1, **{'a': 2}} # => {'a': 2} + + + +# Sets store ... well sets +empty_set = set() +# Initialize a set with a bunch of values. +some_set = {1, 1, 2, 2, 3, 4} # some_set is now {1, 2, 3, 4} + +# Similar to keys of a dictionary, elements of a set have to be immutable. +invalid_set = {[1], 1} # => Raises a TypeError: unhashable type: 'list' +valid_set = {(1,), 1} + +# Add one more item to the set +filled_set = some_set +filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5} +# Sets do not have duplicate elements +filled_set.add(5) # it remains as before {1, 2, 3, 4, 5} + +# Do set intersection with & +other_set = {3, 4, 5, 6} +filled_set & other_set # => {3, 4, 5} + +# Do set union with | +filled_set | other_set # => {1, 2, 3, 4, 5, 6} + +# Do set difference with - +{1, 2, 3, 4} - {2, 3, 5} # => {1, 4} + +# Do set symmetric difference with ^ +{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5} + +# Check if set on the left is a superset of set on the right +{1, 2} >= {1, 2, 3} # => False + +# Check if set on the left is a subset of set on the right +{1, 2} <= {1, 2, 3} # => True + +# Check for existence in a set with in +2 in filled_set # => True +10 in filled_set # => False + +# Make a one layer deep copy +filled_set = some_set.copy() # filled_set is {1, 2, 3, 4, 5} +filled_set is some_set # => False + + +#################################################### +## 3. Control Flow and Iterables +#################################################### + +# Let's just make a variable +some_var = 5 + +# Here is an if statement. Indentation is significant in Python! +# Convention is to use four spaces, not tabs. +# This prints "some_var is smaller than 10" +if some_var > 10: + print("some_var is totally bigger than 10.") +elif some_var < 10: # This elif clause is optional. + print("some_var is smaller than 10.") +else: # This is optional too. + print("some_var is indeed 10.") + + +""" +For loops iterate over lists +prints: + dog is a mammal + cat is a mammal + mouse is a mammal +""" +for animal in ["dog", "cat", "mouse"]: + # You can use format() to interpolate formatted strings + print("{} is a mammal".format(animal)) + +""" +"range(number)" returns an iterable of numbers +from zero up to (but excluding) the given number +prints: + 0 + 1 + 2 + 3 +""" +for i in range(4): + print(i) + +""" +"range(lower, upper)" returns an iterable of numbers +from the lower number to the upper number +prints: + 4 + 5 + 6 + 7 +""" +for i in range(4, 8): + print(i) + +""" +"range(lower, upper, step)" returns an iterable of numbers +from the lower number to the upper number, while incrementing +by step. If step is not indicated, the default value is 1. +prints: + 4 + 6 +""" +for i in range(4, 8, 2): + print(i) + +""" +Loop over a list to retrieve both the index and the value of each list item: + 0 dog + 1 cat + 2 mouse +""" +animals = ["dog", "cat", "mouse"] +for i, value in enumerate(animals): + print(i, value) + +""" +While loops go until a condition is no longer met. +prints: + 0 + 1 + 2 + 3 +""" +x = 0 +while x < 4: + print(x) + x += 1 # Shorthand for x = x + 1 + +# Handle exceptions with a try/except block +try: + # Use "raise" to raise an error + raise IndexError("This is an index error") +except IndexError as e: + pass # Refrain from this, provide a recovery (next example). +except (TypeError, NameError): + pass # Multiple exceptions can be processed jointly. +else: # Optional clause to the try/except block. Must follow + # all except blocks. + print("All good!") # Runs only if the code in try raises no exceptions +finally: # Execute under all circumstances + print("We can clean up resources here") + +# Instead of try/finally to cleanup resources you can use a with statement +with open("myfile.txt") as f: + for line in f: + print(line) + +# Writing to a file +contents = {"aa": 12, "bb": 21} +with open("myfile1.txt", "w+") as file: + file.write(str(contents)) # writes a string to a file + +import json +with open("myfile2.txt", "w+") as file: + file.write(json.dumps(contents)) # writes an object to a file + +# Reading from a file +with open('myfile1.txt', "r+") as file: + contents = file.read() # reads a string from a file +print(contents) +# print: {"aa": 12, "bb": 21} + +with open('myfile2.txt', "r+") as file: + contents = json.load(file) # reads a json object from a file +print(contents) +# print: {"aa": 12, "bb": 21} + + +# Python offers a fundamental abstraction called the Iterable. +# An iterable is an object that can be treated as a sequence. +# The object returned by the range function, is an iterable. + +filled_dict = {"one": 1, "two": 2, "three": 3} +our_iterable = filled_dict.keys() +print(our_iterable) # => dict_keys(['one', 'two', 'three']). This is an object + # that implements our Iterable interface. + +# We can loop over it. +for i in our_iterable: + print(i) # Prints one, two, three + +# However we cannot address elements by index. +our_iterable[1] # Raises a TypeError + +# An iterable is an object that knows how to create an iterator. +our_iterator = iter(our_iterable) + +# Our iterator is an object that can remember the state as we traverse through +# it. We get the next object with "next()". +next(our_iterator) # => "one" + +# It maintains state as we iterate. +next(our_iterator) # => "two" +next(our_iterator) # => "three" + +# After the iterator has returned all of its data, it raises a +# StopIteration exception +next(our_iterator) # Raises StopIteration + +# We can also loop over it, in fact, "for" does this implicitly! +our_iterator = iter(our_iterable) +for i in our_iterator: + print(i) # Prints one, two, three + +# You can grab all the elements of an iterable or iterator by call of list(). +list(our_iterable) # => Returns ["one", "two", "three"] +list(our_iterator) # => Returns [] because state is saved + + +#################################################### +## 4. Functions +#################################################### + +# Use "def" to create new functions +def add(x, y): + print("x is {} and y is {}".format(x, y)) + return x + y # Return values with a return statement + +# Calling functions with parameters +add(5, 6) # => prints out "x is 5 and y is 6" and returns 11 + +# Another way to call functions is with keyword arguments +add(y=6, x=5) # Keyword arguments can arrive in any order. + +# You can define functions that take a variable number of +# positional arguments +def varargs(*args): + return args + +varargs(1, 2, 3) # => (1, 2, 3) + +# You can define functions that take a variable number of +# keyword arguments, as well +def keyword_args(**kwargs): + return kwargs + +# Let's call it to see what happens +keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"} + + +# You can do both at once, if you like +def all_the_args(*args, **kwargs): + print(args) + print(kwargs) +""" +all_the_args(1, 2, a=3, b=4) prints: + (1, 2) + {"a": 3, "b": 4} +""" + +# When calling functions, you can do the opposite of args/kwargs! +# Use * to expand tuples and use ** to expand kwargs. +args = (1, 2, 3, 4) +kwargs = {"a": 3, "b": 4} +all_the_args(*args) # equivalent: all_the_args(1, 2, 3, 4) +all_the_args(**kwargs) # equivalent: all_the_args(a=3, b=4) +all_the_args(*args, **kwargs) # equivalent: all_the_args(1, 2, 3, 4, a=3, b=4) + +# Returning multiple values (with tuple assignments) +def swap(x, y): + return y, x # Return multiple values as a tuple without the parenthesis. + # (Note: parenthesis have been excluded but can be included) + +x = 1 +y = 2 +x, y = swap(x, y) # => x = 2, y = 1 +# (x, y) = swap(x,y) # Again the use of parenthesis is optional. + +# global scope +x = 5 + +def set_x(num): + # local scope begins here + # local var x not the same as global var x + x = num # => 43 + print(x) # => 43 + +def set_global_x(num): + # global indicates that particular var lives in the global scope + global x + print(x) # => 5 + x = num # global var x is now set to 6 + print(x) # => 6 + +set_x(43) +set_global_x(6) +""" +prints: + 43 + 5 + 6 +""" + + +# Python has first class functions +def create_adder(x): + def adder(y): + return x + y + return adder + +add_10 = create_adder(10) +add_10(3) # => 13 + +# There are also anonymous functions +(lambda x: x > 2)(3) # => True +(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5 + +# There are built-in higher order functions +list(map(add_10, [1, 2, 3])) # => [11, 12, 13] +list(map(max, [1, 2, 3], [4, 2, 1])) # => [4, 2, 3] + +list(filter(lambda x: x > 5, [3, 4, 5, 6, 7])) # => [6, 7] + +# We can use list comprehensions for nice maps and filters +# List comprehension stores the output as a list (which itself may be nested). +[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13] +[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7] + +# You can construct set and dict comprehensions as well. +{x for x in 'abcddeef' if x not in 'abc'} # => {'d', 'e', 'f'} +{x: x**2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} + + +#################################################### +## 5. Modules +#################################################### + +# You can import modules +import math +print(math.sqrt(16)) # => 4.0 + +# You can get specific functions from a module +from math import ceil, floor +print(ceil(3.7)) # => 4.0 +print(floor(3.7)) # => 3.0 + +# You can import all functions from a module. +# Warning: this is not recommended +from math import * + +# You can shorten module names +import math as m +math.sqrt(16) == m.sqrt(16) # => True + +# Python modules are just ordinary Python files. You +# can write your own, and import them. The name of the +# module is the same as the name of the file. + +# You can find out which functions and attributes +# are defined in a module. +import math +dir(math) + +# If you have a Python script named math.py in the same +# folder as your current script, the file math.py will +# be loaded instead of the built-in Python module. +# This happens because the local folder has priority +# over Python's built-in libraries. + + +#################################################### +## 6. Classes +#################################################### + +# We use the "class" statement to create a class +class Human: + + # A class attribute. It is shared by all instances of this class + species = "H. sapiens" + + # Basic initializer, this is called when this class is instantiated. + # Note that the double leading and trailing underscores denote objects + # or attributes that are used by Python but that live in user-controlled + # namespaces. Methods(or objects or attributes) like: __init__, __str__, + # __repr__ etc. are called special methods (or sometimes called dunder + # methods). You should not invent such names on your own. + def __init__(self, name): + # Assign the argument to the instance's name attribute + self.name = name + + # Initialize property + self._age = 0 + + # An instance method. All methods take "self" as the first argument + def say(self, msg): + print("{name}: {message}".format(name=self.name, message=msg)) + + # Another instance method + def sing(self): + return 'yo... yo... microphone check... one two... one two...' + + # A class method is shared among all instances + # They are called with the calling class as the first argument + @classmethod + def get_species(cls): + return cls.species + + # A static method is called without a class or instance reference + @staticmethod + def grunt(): + return "*grunt*" + + # A property is just like a getter. + # It turns the method age() into a read-only attribute of the same name. + # There's no need to write trivial getters and setters in Python, though. + @property + def age(self): + return self._age + + # This allows the property to be set + @age.setter + def age(self, age): + self._age = age + + # This allows the property to be deleted + @age.deleter + def age(self): + del self._age + + +# When a Python interpreter reads a source file it executes all its code. +# This __name__ check makes sure this code block is only executed when this +# module is the main program. +if __name__ == '__main__': + # Instantiate a class + i = Human(name="Ian") + i.say("hi") # "Ian: hi" + j = Human("Joel") + j.say("hello") # "Joel: hello" + # i and j are instances of type Human; i.e., they are Human objects. + + # Call our class method + i.say(i.get_species()) # "Ian: H. sapiens" + # Change the shared attribute + Human.species = "H. neanderthalensis" + i.say(i.get_species()) # => "Ian: H. neanderthalensis" + j.say(j.get_species()) # => "Joel: H. neanderthalensis" + + # Call the static method + print(Human.grunt()) # => "*grunt*" + + # Static methods can be called by instances too + print(i.grunt()) # => "*grunt*" + + # Update the property for this instance + i.age = 42 + # Get the property + i.say(i.age) # => "Ian: 42" + j.say(j.age) # => "Joel: 0" + # Delete the property + del i.age + # i.age # => this would raise an AttributeError + + +#################################################### +## 6.1 Inheritance +#################################################### + +# Inheritance allows new child classes to be defined that inherit methods and +# variables from their parent class. + +# Using the Human class defined above as the base or parent class, we can +# define a child class, Superhero, which inherits the class variables like +# "species", "name", and "age", as well as methods, like "sing" and "grunt" +# from the Human class, but can also have its own unique properties. + +# To take advantage of modularization by file you could place the classes above +# in their own files, say, human.py + +# To import functions from other files use the following format +# from "filename-without-extension" import "function-or-class" + +from human import Human + + +# Specify the parent class(es) as parameters to the class definition +class Superhero(Human): + + # If the child class should inherit all of the parent's definitions without + # any modifications, you can just use the "pass" keyword (and nothing else) + # but in this case it is commented out to allow for a unique child class: + # pass + + # Child classes can override their parents' attributes + species = 'Superhuman' + + # Children automatically inherit their parent class's constructor including + # its arguments, but can also define additional arguments or definitions + # and override its methods such as the class constructor. + # This constructor inherits the "name" argument from the "Human" class and + # adds the "superpower" and "movie" arguments: + def __init__(self, name, movie=False, + superpowers=["super strength", "bulletproofing"]): + + # add additional class attributes: + self.fictional = True + self.movie = movie + # be aware of mutable default values, since defaults are shared + self.superpowers = superpowers + + # The "super" function lets you access the parent class's methods + # that are overridden by the child, in this case, the __init__ method. + # This calls the parent class constructor: + super().__init__(name) + + # override the sing method + def sing(self): + return 'Dun, dun, DUN!' + + # add an additional instance method + def boast(self): + for power in self.superpowers: + print("I wield the power of {pow}!".format(pow=power)) + + +if __name__ == '__main__': + sup = Superhero(name="Tick") + + # Instance type checks + if isinstance(sup, Human): + print('I am human') + if type(sup) is Superhero: + print('I am a superhero') + + # Get the Method Resolution search Order used by both getattr() and super() + # This attribute is dynamic and can be updated + print(Superhero.__mro__) # => (, + # => , ) + + # Calls parent method but uses its own class attribute + print(sup.get_species()) # => Superhuman + + # Calls overridden method + print(sup.sing()) # => Dun, dun, DUN! + + # Calls method from Human + sup.say('Spoon') # => Tick: Spoon + + # Call method that exists only in Superhero + sup.boast() # => I wield the power of super strength! + # => I wield the power of bulletproofing! + + # Inherited class attribute + sup.age = 31 + print(sup.age) # => 31 + + # Attribute that only exists within Superhero + print('Am I Oscar eligible? ' + str(sup.movie)) + +#################################################### +## 6.2 Multiple Inheritance +#################################################### + +# Another class definition +# bat.py +class Bat: + + species = 'Baty' + + def __init__(self, can_fly=True): + self.fly = can_fly + + # This class also has a say method + def say(self, msg): + msg = '... ... ...' + return msg + + # And its own method as well + def sonar(self): + return '))) ... (((' + +if __name__ == '__main__': + b = Bat() + print(b.say('hello')) + print(b.fly) + + +# And yet another class definition that inherits from Superhero and Bat +# superhero.py +from superhero import Superhero +from bat import Bat + +# Define Batman as a child that inherits from both Superhero and Bat +class Batman(Superhero, Bat): + + def __init__(self, *args, **kwargs): + # Typically to inherit attributes you have to call super: + # super(Batman, self).__init__(*args, **kwargs) + # However we are dealing with multiple inheritance here, and super() + # only works with the next base class in the MRO list. + # So instead we explicitly call __init__ for all ancestors. + # The use of *args and **kwargs allows for a clean way to pass + # arguments, with each parent "peeling a layer of the onion". + Superhero.__init__(self, 'anonymous', movie=True, + superpowers=['Wealthy'], *args, **kwargs) + Bat.__init__(self, *args, can_fly=False, **kwargs) + # override the value for the name attribute + self.name = 'Sad Affleck' + + def sing(self): + return 'nan nan nan nan nan batman!' + + +if __name__ == '__main__': + sup = Batman() + + # Get the Method Resolution search Order used by both getattr() and super(). + # This attribute is dynamic and can be updated + print(Batman.__mro__) # => (, + # => , + # => , + # => , ) + + # Calls parent method but uses its own class attribute + print(sup.get_species()) # => Superhuman + + # Calls overridden method + print(sup.sing()) # => nan nan nan nan nan batman! + + # Calls method from Human, because inheritance order matters + sup.say('I agree') # => Sad Affleck: I agree + + # Call method that exists only in 2nd ancestor + print(sup.sonar()) # => ))) ... ((( + + # Inherited class attribute + sup.age = 100 + print(sup.age) # => 100 + + # Inherited attribute from 2nd ancestor whose default value was overridden. + print('Can I fly? ' + str(sup.fly)) # => Can I fly? False + + + +#################################################### +## 7. Advanced +#################################################### + +# Generators help you make lazy code. +def double_numbers(iterable): + for i in iterable: + yield i + i + +# Generators are memory-efficient because they only load the data needed to +# process the next value in the iterable. This allows them to perform +# operations on otherwise prohibitively large value ranges. +# NOTE: `range` replaces `xrange` in Python 3. +for i in double_numbers(range(1, 900000000)): # `range` is a generator. + print(i) + if i >= 30: + break + +# Just as you can create a list comprehension, you can create generator +# comprehensions as well. +values = (-x for x in [1,2,3,4,5]) +for x in values: + print(x) # prints -1 -2 -3 -4 -5 to console/terminal + +# You can also cast a generator comprehension directly to a list. +values = (-x for x in [1,2,3,4,5]) +gen_to_list = list(values) +print(gen_to_list) # => [-1, -2, -3, -4, -5] + + +# Decorators +# In this example `beg` wraps `say`. If say_please is True then it +# will change the returned message. +from functools import wraps + + +def intro(target_function): + @wraps(target_function) + def wrapper(*args, **kwargs): + msg, say_please = target_function(*args, **kwargs) + if say_please: + return "{} {}".format(msg, "My name is Nitkarsh Chourasia.") + return msg + + return wrapper + + +@intro +def say(say_please=False): + msg = "I published this static site, here." + return msg, say_please + + +print(say()) # I published this static site, here. +print(say(say_please=True)) # I published this static site, here. My name is Nitkarsh Chourasia. + + + + + + +#################################################### +## Author's Info +#################################################### + +import webbrowser + +class Author: + def __init__(self, name: str, github_profile_url: str) -> None: + """Initialize the Author class with name and GitHub profile URL.""" + self.name = name + self.github_profile_url = github_profile_url + self.github_username = github_profile_url[19:] + + def open_github_profile(self) -> None: + """Open the author's GitHub profile in a new tab.""" + return webbrowser.open_new_tab(self.github_profile_url) + +# Create an instance of the Author class +AUTHOR = Author("Nitkarsh Chourasia", "https://github.com/NitkarshChourasia") + +# Access the encapsulated data +print(f"Author Name: {AUTHOR.name}") +print(f"Github Profile Link: {AUTHOR.github_profile_url}") +print(f"Github Username: {AUTHOR.github_username}") + +# Open the author's GitHub profile in a new tab +AUTHOR.open_github_profile() + +#################################################### + +``` diff --git a/repo_website/docs/img/favicon.ico b/repo_website/docs/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..bcc463b858bdc044062a5642d44a578cdfb01dd4 GIT binary patch literal 15406 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 literal 0 HcmV?d00001 diff --git a/repo_website/mkdocs.yml b/repo_website/mkdocs.yml new file mode 100644 index 00000000000..152bffd5931 --- /dev/null +++ b/repo_website/mkdocs.yml @@ -0,0 +1,77 @@ +site_name: Learn Python Programming Language +# site_url: https://james-willett.github.io/mkdocs-material-youtube-tutorial/ +# site_url: https://example.com/ +site_url: https://github.com/NitkarshChourasia + +nav: + - Home: README.md + - Downloads: README.md + - Music: README.md + - Assets: README.md + - About: README.md + +theme: + name: material + features: + - navigation.tabs + - navigation.sections + - toc.integrate + - navigation.top + - search.suggest + - search.highlight + - content.tabs.link + - content.code.annotation + - content.code.copy + language: en + palette: + - scheme: default + toggle: + icon: material/toggle-switch-off-outline + name: Switch to dark mode + primary: teal + accent: purple + - scheme: slate + toggle: + icon: material/toggle-switch + name: Switch to light mode + primary: teal + accent: lime +# This switch is not appearing, make it good. + +# plugins: +# - social + +extra: + social: + - icon: fontawesome/brands/github-alt + link: https://github.com/NitkarshChourasia + - icon: fontawesome/brands/twitter + link: https://twitter.com/NitkarshC + - icon: fontawesome/brands/linkedin + link: https://www.linkedin.com/in/willettjames/ # Put mine. Here. + link: https://www.linkedin.com/in/nitkarshchourasia + +markdown_extensions: + - pymdownx.highlight: + anchor_linenums: true + - pymdownx.inlinehilite + - pymdownx.snippets + - admonition + - pymdownx.arithmatex: + generic: true + - footnotes + - pymdownx.details + - pymdownx.superfences + - pymdownx.mark + - attr_list + - pymdownx.emoji: + emoji_index: !!python/name:materialx.emoji.twemoji + emoji_generator: !!python/name:materialx.emoji.to_svg + +copyright: | + + © 2023 Nitkarsh Chourasia + +# At the last ask bing how to improve it further. + +# Make it fully, and extra loaded. From 80b2e296c99ce55df14107225f3dc487f90810a5 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Tue, 14 May 2024 23:13:57 +0100 Subject: [PATCH 019/442] built structure for gui --- Search_Engine/frontend.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 Search_Engine/frontend.py diff --git a/Search_Engine/frontend.py b/Search_Engine/frontend.py new file mode 100644 index 00000000000..3e2a902dbb4 --- /dev/null +++ b/Search_Engine/frontend.py @@ -0,0 +1,34 @@ +from tkinter import * +from tkinter import messagebox + + +def add_document(): + document = add_documents_entry.get() + print(document) + +def find_term(): + term = find_term_entry.get() + print(term) + + +root = Tk() +root.title("Registration Form") +root.geometry('300x300') + +add_documents_label = Label(root, text="Add Document:") +add_documents_label.pack() +add_documents_entry = Entry(root) +add_documents_entry.pack() + +add_document_button = Button(root, text="add", command=add_document) +add_document_button.pack() + +find_term_label = Label(root, text="Input term to search:") +find_term_label.pack() +find_term_entry = Entry(root) +find_term_entry.pack() + +search_term_button = Button(root, text="search", command=find_term) +search_term_button.pack() + +root.mainloop() \ No newline at end of file From 95de021dd0ab2cb775507f21ae67f0539744f4ba Mon Sep 17 00:00:00 2001 From: Xceptions Date: Tue, 14 May 2024 23:24:18 +0100 Subject: [PATCH 020/442] brought in backend into frontend --- Search_Engine/frontend.py | 41 +++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/Search_Engine/frontend.py b/Search_Engine/frontend.py index 3e2a902dbb4..93dd7636f19 100644 --- a/Search_Engine/frontend.py +++ b/Search_Engine/frontend.py @@ -1,34 +1,37 @@ from tkinter import * from tkinter import messagebox +import backend def add_document(): document = add_documents_entry.get() - print(document) + se = backend.SearchEngine() + print(se.index_document(document)) def find_term(): term = find_term_entry.get() - print(term) + se = backend.SearchEngine() + print(se.find_documents(term)) +if __name__ == "__main__": + root = Tk() + root.title("Registration Form") + root.geometry('300x300') -root = Tk() -root.title("Registration Form") -root.geometry('300x300') + add_documents_label = Label(root, text="Add Document:") + add_documents_label.pack() + add_documents_entry = Entry(root) + add_documents_entry.pack() -add_documents_label = Label(root, text="Add Document:") -add_documents_label.pack() -add_documents_entry = Entry(root) -add_documents_entry.pack() + add_document_button = Button(root, text="add", command=add_document) + add_document_button.pack() -add_document_button = Button(root, text="add", command=add_document) -add_document_button.pack() + find_term_label = Label(root, text="Input term to search:") + find_term_label.pack() + find_term_entry = Entry(root) + find_term_entry.pack() -find_term_label = Label(root, text="Input term to search:") -find_term_label.pack() -find_term_entry = Entry(root) -find_term_entry.pack() + search_term_button = Button(root, text="search", command=find_term) + search_term_button.pack() -search_term_button = Button(root, text="search", command=find_term) -search_term_button.pack() - -root.mainloop() \ No newline at end of file + root.mainloop() \ No newline at end of file From fd1badc114b8caf2b2161129c40132ca8097539a Mon Sep 17 00:00:00 2001 From: Xceptions Date: Wed, 15 May 2024 11:49:36 +0100 Subject: [PATCH 021/442] updated readme.md --- Search_Engine/README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Search_Engine/README.md b/Search_Engine/README.md index ab053aa7739..d952a5a5888 100644 --- a/Search_Engine/README.md +++ b/Search_Engine/README.md @@ -1 +1,9 @@ -Python Program to search through various documents and return the documents containing the search term +Python Program to search through various documents and return the documents containing the search term. + +To see in action, run + +```python3 backend.py``` + +To use a gui, run + +```python3 frontend.py``` \ No newline at end of file From 8d046706b06851b21dee8493aea516442b3bfe5f Mon Sep 17 00:00:00 2001 From: Xceptions Date: Wed, 15 May 2024 11:50:01 +0100 Subject: [PATCH 022/442] changed backend to stop using global connection object --- Search_Engine/backend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Search_Engine/backend.py b/Search_Engine/backend.py index 52524167a09..c0f30173e2f 100644 --- a/Search_Engine/backend.py +++ b/Search_Engine/backend.py @@ -131,5 +131,5 @@ def _find_documents_with_idx(self, idxs): se.index_document("we should all strive to be happy and happy again") print(se.index_document("happiness is all you need")) se.index_document("no way should we be sad") - se.index_document("a cheerful heart is a happy one") + se.index_document("a cheerful heart is a happy one even in Nigeria") print(se.find_documents("happy")) \ No newline at end of file From f26a268bb69bc04ae4ed21c4421deba58bf15f66 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Wed, 15 May 2024 12:42:32 +0100 Subject: [PATCH 023/442] updated return statement of index method and added autocommit to db) --- Search_Engine/backend.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Search_Engine/backend.py b/Search_Engine/backend.py index c0f30173e2f..f716f5fa16d 100644 --- a/Search_Engine/backend.py +++ b/Search_Engine/backend.py @@ -21,7 +21,7 @@ def __init__(self): - maintain a class level access to the database connection object """ - self.conn = sqlite3.connect("searchengine.db") + self.conn = sqlite3.connect("searchengine.sqlite3", autocommit=True) cur = self.conn.cursor() res = cur.execute("SELECT name FROM sqlite_master WHERE name='IdToDoc'") tables_exist = res.fetchone() @@ -33,7 +33,7 @@ def __init__(self): def index_document(self, document): """ - Returns - + Returns - string Input - str: a string of words called document ---------- Indexes the document. It does this by performing two @@ -61,7 +61,7 @@ def index_document(self, document): reverse_idx = json.dumps(reverse_idx) cur = self.conn.cursor() result = cur.execute("UPDATE WordToId SET value = (?) WHERE name='index'", (reverse_idx,)) - return(result) + return("index successful") def _add_to_IdToDoc(self, document): """ From cd605e11b57a12152b024c620e8578ee8704fb92 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Wed, 15 May 2024 12:47:11 +0100 Subject: [PATCH 024/442] updated readme --- Search_Engine/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Search_Engine/README.md b/Search_Engine/README.md index d952a5a5888..36081b0aad8 100644 --- a/Search_Engine/README.md +++ b/Search_Engine/README.md @@ -1,6 +1,6 @@ -Python Program to search through various documents and return the documents containing the search term. +Python Program to search through various documents and return the documents containing the search term. Algorithm involves using a reverse index to store each word in each document where a document is defined by an index. To get the document that contains a search term, we simply find an intersect of all the words in the search term, and using the resulting indexes, retrieve the document(s) that contain these words -To see in action, run +To use directly, run ```python3 backend.py``` From 67c6c99ac525e0c320fd66b273b9183051a9bb4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 May 2024 18:23:30 +0000 Subject: [PATCH 025/442] build(deps): bump pytest from 7.4.4 to 8.2.0 Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.4.4 to 8.2.0. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.4.4...8.2.0) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 115746a08fe..45dc32c8297 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -97,7 +97,7 @@ newspaper==0.1.0.7 opencv-python==4.9.0.80 tensorflow==2.15.0.post1 pandas==2.2.2 -pytest==7.4.4 +pytest==8.2.0 qrcode==7.4.2 googletrans==3.0.0 slab==1.1.5 From c1e322dcf0017ef1b26617a69ac7e49e6a661751 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 May 2024 18:09:56 +0000 Subject: [PATCH 026/442] build(deps): bump matplotlib from 3.8.4 to 3.9.0 Bumps [matplotlib](https://github.com/matplotlib/matplotlib) from 3.8.4 to 3.9.0. - [Release notes](https://github.com/matplotlib/matplotlib/releases) - [Commits](https://github.com/matplotlib/matplotlib/compare/v3.8.4...v3.9.0) --- updated-dependencies: - dependency-name: matplotlib dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 45dc32c8297..9b9bc416c4e 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -86,7 +86,7 @@ fitz==0.0.1.dev2 fastapi==0.109.0 Django==5.0.5 docx==0.2.4 -matplotlib==3.8.4 +matplotlib==3.9.0 pyshorteners==1.0.1 geocoder==1.38.1 APScheduler==3.10.4 From 7b5830f317b641eef053b22542807d7201efbb29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 18:53:39 +0000 Subject: [PATCH 027/442] --- updated-dependencies: - dependency-name: seaborn dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 9b9bc416c4e..c679729ab69 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -2,7 +2,7 @@ pafy==0.5.5 aiohttp==3.9.3 fuzzywuzzy==0.18.0 hupper==1.12.1 -seaborn==0.13.1 +seaborn==0.13.2 time==1.0.0 simplegui==0.1.1 utils==1.0.2 From 00205528a4211856f9411420fdab1b58d4f68472 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 May 2024 18:26:24 +0000 Subject: [PATCH 028/442] Bump openai from 1.9.0 to 1.30.4 Bumps [openai](https://github.com/openai/openai-python) from 1.9.0 to 1.30.4. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.9.0...v1.30.4) --- updated-dependencies: - dependency-name: openai dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index c679729ab69..f1c92856896 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.9.0 +openai==1.30.4 background==0.2.1 pydantic==2.6.1 openpyxl==3.1.2 From 3ba9398b4a516ecfa783a38ead46495533ca8a9f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 May 2024 18:17:37 +0000 Subject: [PATCH 029/442] Bump ujson from 5.9.0 to 5.10.0 Bumps [ujson](https://github.com/ultrajson/ultrajson) from 5.9.0 to 5.10.0. - [Release notes](https://github.com/ultrajson/ultrajson/releases) - [Commits](https://github.com/ultrajson/ultrajson/compare/5.9.0...5.10.0) --- updated-dependencies: - dependency-name: ujson dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index f1c92856896..e58d225231b 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -23,7 +23,7 @@ Counter==1.0.0 Flask==3.0.2 selenium==4.16.0 firebase-admin==6.5.0 -ujson==5.9.0 +ujson==5.10.0 requests==2.31.0 quo==2023.5.1 PyPDF2==3.0.1 From f3c5e518e155c06c11e98b379d69d9727e8ed9a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 May 2024 18:19:27 +0000 Subject: [PATCH 030/442] Bump ccxt from 4.3.18 to 4.3.36 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.3.18 to 4.3.36. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.3.18...4.3.36) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index f1c92856896..d4fd039e88c 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.6 gTTS==2.5.0 -ccxt==4.3.18 +ccxt==4.3.36 fitz==0.0.1.dev2 fastapi==0.109.0 Django==5.0.5 From dd8db14cd8d1f01172325d87a38239a50df58452 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 May 2024 18:13:58 +0000 Subject: [PATCH 031/442] Bump thirdai from 0.7.44 to 0.8.5 Bumps thirdai from 0.7.44 to 0.8.5. --- updated-dependencies: - dependency-name: thirdai dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 0e805a43ef4..cead1800556 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -57,7 +57,7 @@ pytesseract==0.3.10 requests-mock==1.12.1 pyglet==2.0.10 urllib3==2.2.1 -thirdai==0.7.44 +thirdai==0.8.5 google-api-python-client==2.115.0 sound==0.1.0 xlwt==1.3.0 From 72968f3fb6a02696b463e85cf876b6be9549003a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 May 2024 18:14:13 +0000 Subject: [PATCH 032/442] Bump aiohttp from 3.9.3 to 3.9.5 Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.9.3 to 3.9.5. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.9.3...v3.9.5) --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- async_downloader/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/async_downloader/requirements.txt b/async_downloader/requirements.txt index 9bb22aa80c5..d395d9cf8f0 100644 --- a/async_downloader/requirements.txt +++ b/async_downloader/requirements.txt @@ -1 +1 @@ -aiohttp==3.9.3 +aiohttp==3.9.5 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 0e805a43ef4..54e97fdecc7 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -1,5 +1,5 @@ pafy==0.5.5 -aiohttp==3.9.3 +aiohttp==3.9.5 fuzzywuzzy==0.18.0 hupper==1.12.1 seaborn==0.13.2 From 826966600e331572dc9aa99efaaee00c73125d6d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 May 2024 18:17:53 +0000 Subject: [PATCH 033/442] Bump pydantic from 2.6.1 to 2.7.2 Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.6.1 to 2.7.2. - [Release notes](https://github.com/pydantic/pydantic/releases) - [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md) - [Commits](https://github.com/pydantic/pydantic/compare/v2.6.1...v2.7.2) --- updated-dependencies: - dependency-name: pydantic dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 88c244978b1..7417d2a5ca1 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -51,7 +51,7 @@ pywifi==1.1.12 patterns==0.3 openai==1.30.4 background==0.2.1 -pydantic==2.6.1 +pydantic==2.7.2 openpyxl==3.1.2 pytesseract==0.3.10 requests-mock==1.12.1 From e3b0d4fe82f17d4065d61126a23c4fb1cb230d9f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 May 2024 18:17:59 +0000 Subject: [PATCH 034/442] Bump requests from 2.31.0 to 2.32.3 Bumps [requests](https://github.com/psf/requests) from 2.31.0 to 2.32.3. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.31.0...v2.32.3) --- updated-dependencies: - dependency-name: requests dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- ImageDownloader/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ImageDownloader/requirements.txt b/ImageDownloader/requirements.txt index 2c24336eb31..d80d9fc2a3a 100644 --- a/ImageDownloader/requirements.txt +++ b/ImageDownloader/requirements.txt @@ -1 +1 @@ -requests==2.31.0 +requests==2.32.3 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 88c244978b1..bc606d5dc34 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -24,7 +24,7 @@ Flask==3.0.2 selenium==4.16.0 firebase-admin==6.5.0 ujson==5.10.0 -requests==2.31.0 +requests==2.32.3 quo==2023.5.1 PyPDF2==3.0.1 pyserial==3.5 From 1bd23703b553db2d757457761ac2729d1c27eb6b Mon Sep 17 00:00:00 2001 From: Xceptions Date: Sat, 1 Jun 2024 19:17:33 +0100 Subject: [PATCH 035/442] added train method --- AutoComplete_App/backend.py | 81 +++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 AutoComplete_App/backend.py diff --git a/AutoComplete_App/backend.py b/AutoComplete_App/backend.py new file mode 100644 index 00000000000..13b3fe3f6de --- /dev/null +++ b/AutoComplete_App/backend.py @@ -0,0 +1,81 @@ +import sqlite3 +# import test_data +# import ast +# import json + +class AutoComplete: + """ + It works by building a `WordMap` that stores words to word-follower-count + ---------------------------- + e.g. To train the following statement: + + It is not enough to just know how tools work and what they worth, + we have got to learn how to use them and to use them well. + And with all these new weapons in your arsenal, we would better + get those profits fired up + + we create the following: + { It: {is:1} + is: {not:1} + not: {enough:1} + enough: {to:1} + to: {just:1, learn:1, use:2} + just: {know:1} + . + . + profits: {fired:1} + fired: {up:1} + } + so the word completion for "to" will be "use". + For optimization, we use another store `WordPrediction` to save the + predictions for each word + """ + + def __init__(self): + """ + Returns - None + Input - None + ---------- + - Initialize database. we use sqlite3 + - Check if the tables exist, if not create them + - maintain a class level access to the database + connection object + """ + self.conn = sqlite3.connect("autocompleteDB.sqlite3", autocommit=True) + cur = self.conn.cursor() + res = cur.execute("SELECT name FROM sqlite_master WHERE name='WordMap'") + tables_exist = res.fetchone() + print(tables_exist) + + if not tables_exist: + self.conn.execute("CREATE TABLE WordMap(name TEXT, value TEXT)") + self.conn.execute('CREATE TABLE WordPrediction (name TEXT, value TEXT)') + cur.execute("INSERT INTO WordMap VALUES (?, ?)", ("wordsmap", "{}",)) + cur.execute("INSERT INTO WordPrediction VALUES (?, ?)", ("predictions", "{}",)) + + def train(self, sentence): + words_list = sentence.split(" ") + words_map = {} + for idx in range(len(words_list)-1): + curr_word, next_word = words_list[idx], words_list[idx+1] + if curr_word not in words_map: + words_map[curr_word] = {} + if next_word not in words_map[curr_word]: + words_map[curr_word][next_word] = 1 + else: + words_map[curr_word][next_word] += 1 + + print(words_map) + + +if __name__ == "__main__": + input_ = "It is not enough to just know how tools work and what they worth,\ + we have got to learn how to use them and to use them well. And with\ + all these new weapons in your arsenal, we would better get those profits fired up" + ac = AutoComplete() + print(ac.train(input_)) + # se.index_document("we should all strive to be happy and happy again") + # print(se.index_document("happiness is all you need")) + # se.index_document("no way should we be sad") + # se.index_document("a cheerful heart is a happy one even in Nigeria") + # print(se.find_documents("happy")) \ No newline at end of file From e91a13a5a8e3fcca7639b8096a87c4f1cd686ae9 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Sun, 2 Jun 2024 16:55:36 +0100 Subject: [PATCH 036/442] completed train method with comments --- AutoComplete_App/backend.py | 51 +++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/AutoComplete_App/backend.py b/AutoComplete_App/backend.py index 13b3fe3f6de..66dc9bc79c9 100644 --- a/AutoComplete_App/backend.py +++ b/AutoComplete_App/backend.py @@ -1,7 +1,7 @@ import sqlite3 # import test_data # import ast -# import json +import json class AutoComplete: """ @@ -45,7 +45,6 @@ def __init__(self): cur = self.conn.cursor() res = cur.execute("SELECT name FROM sqlite_master WHERE name='WordMap'") tables_exist = res.fetchone() - print(tables_exist) if not tables_exist: self.conn.execute("CREATE TABLE WordMap(name TEXT, value TEXT)") @@ -54,8 +53,27 @@ def __init__(self): cur.execute("INSERT INTO WordPrediction VALUES (?, ?)", ("predictions", "{}",)) def train(self, sentence): + """ + Returns - string + Input - str: a string of words called sentence + ---------- + Trains the sentence. It does this by creating a map of + current words to next words and their counts for each + time the next word appears after the current word + - takes in the sentence and splits it into a list of words + - retrieves the word map and predictions map + - creates the word map and predictions map together + - saves word map and predictions map to the database + """ + cur = self.conn.cursor() words_list = sentence.split(" ") - words_map = {} + + words_map = cur.execute("SELECT value FROM WordMap WHERE name='wordsmap'").fetchone()[0] + words_map = json.loads(words_map) + + predictions = cur.execute("SELECT value FROM WordPrediction WHERE name='predictions'").fetchone()[0] + predictions = json.loads(predictions) + for idx in range(len(words_list)-1): curr_word, next_word = words_list[idx], words_list[idx+1] if curr_word not in words_map: @@ -65,7 +83,24 @@ def train(self, sentence): else: words_map[curr_word][next_word] += 1 - print(words_map) + # checking the completion word against the next word + if curr_word not in predictions: + predictions[curr_word] = { + 'completion_word': next_word, + 'completion_count': 1 + } + else: + if words_map[curr_word][next_word] > predictions[curr_word]['completion_count']: + predictions[curr_word]['completion_word'] = next_word + predictions[curr_word]['completion_count'] = words_map[curr_word][next_word] + + words_map = json.dumps(words_map) + predictions = json.dumps(predictions) + + cur.execute("UPDATE WordMap SET value = (?) WHERE name='wordsmap'", (words_map,)) + cur.execute("UPDATE WordPrediction SET value = (?) WHERE name='predictions'", (predictions,)) + return("training complete") + if __name__ == "__main__": @@ -73,9 +108,5 @@ def train(self, sentence): we have got to learn how to use them and to use them well. And with\ all these new weapons in your arsenal, we would better get those profits fired up" ac = AutoComplete() - print(ac.train(input_)) - # se.index_document("we should all strive to be happy and happy again") - # print(se.index_document("happiness is all you need")) - # se.index_document("no way should we be sad") - # se.index_document("a cheerful heart is a happy one even in Nigeria") - # print(se.find_documents("happy")) \ No newline at end of file + ac.train(input_) + # print(ac.predict("to")) \ No newline at end of file From c55bc6af5164c1c65c843c565f1b07f299bb0810 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Sun, 2 Jun 2024 16:57:39 +0100 Subject: [PATCH 037/442] added predict method and comments --- AutoComplete_App/backend.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/AutoComplete_App/backend.py b/AutoComplete_App/backend.py index 66dc9bc79c9..47e1c7906d6 100644 --- a/AutoComplete_App/backend.py +++ b/AutoComplete_App/backend.py @@ -1,6 +1,4 @@ import sqlite3 -# import test_data -# import ast import json class AutoComplete: @@ -101,6 +99,22 @@ def train(self, sentence): cur.execute("UPDATE WordPrediction SET value = (?) WHERE name='predictions'", (predictions,)) return("training complete") + def predict(self, word): + """ + Returns - string + Input - string + ---------- + Returns the completion word of the input word + - takes in a word + - retrieves the predictions map + - returns the completion word of the input word + """ + cur = self.conn.cursor() + predictions = cur.execute("SELECT value FROM WordPrediction WHERE name='predictions'").fetchone()[0] + predictions = json.loads(predictions) + completion_word = predictions[word.lower()]['completion_word'] + return completion_word + if __name__ == "__main__": @@ -109,4 +123,4 @@ def train(self, sentence): all these new weapons in your arsenal, we would better get those profits fired up" ac = AutoComplete() ac.train(input_) - # print(ac.predict("to")) \ No newline at end of file + print(ac.predict("to")) \ No newline at end of file From f6b0c094ca727ed5d84c0ee5296484cdc6213ad4 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Sun, 2 Jun 2024 17:06:41 +0100 Subject: [PATCH 038/442] added GUI for autocomplete --- AutoComplete_App/frontend.py | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 AutoComplete_App/frontend.py diff --git a/AutoComplete_App/frontend.py b/AutoComplete_App/frontend.py new file mode 100644 index 00000000000..90e576e849e --- /dev/null +++ b/AutoComplete_App/frontend.py @@ -0,0 +1,37 @@ +from tkinter import * +from tkinter import messagebox +import backend + + +def train(): + sentence = train_entry.get() + ac = backend.AutoComplete() + ac.train(sentence) + +def predict_word(): + word = predict_word_entry.get() + ac = backend.AutoComplete() + print(ac.predict(word)) + +if __name__ == "__main__": + root = Tk() + root.title("Input note") + root.geometry('300x300') + + train_label = Label(root, text="Train") + train_label.pack() + train_entry = Entry(root) + train_entry.pack() + + train_button = Button(root, text="train", command=train) + train_button.pack() + + predict_word_label = Label(root, text="Input term to predict") + predict_word_label.pack() + predict_word_entry = Entry(root) + predict_word_entry.pack() + + predict_button = Button(root, text="predict", command=predict_word) + predict_button.pack() + + root.mainloop() \ No newline at end of file From 4bd623ddb9f0afaf3bd671adfcf9437a14423fc7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 18:42:09 +0000 Subject: [PATCH 039/442] Bump opencv-python from 4.9.0.80 to 4.10.0.82 Bumps [opencv-python](https://github.com/opencv/opencv-python) from 4.9.0.80 to 4.10.0.82. - [Release notes](https://github.com/opencv/opencv-python/releases) - [Commits](https://github.com/opencv/opencv-python/commits) --- updated-dependencies: - dependency-name: opencv-python dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Hand-Motion-Detection/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt index 9777fd9bba9..bab2de0ecea 100644 --- a/Hand-Motion-Detection/requirements.txt +++ b/Hand-Motion-Detection/requirements.txt @@ -1,3 +1,3 @@ numpy==1.26.4 -opencv_python==4.9.0.80 +opencv_python==4.10.0.82 mediapipe==0.10.9 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index c652c62b50e..00b371beb35 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -94,7 +94,7 @@ PyQRCode==1.2.1 freegames==2.5.3 pyperclip==1.8.2 newspaper==0.1.0.7 -opencv-python==4.9.0.80 +opencv-python==4.10.0.82 tensorflow==2.15.0.post1 pandas==2.2.2 pytest==8.2.0 From 29f0c120d74e01e7003c2df9abc31a507f9a0891 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 18:42:15 +0000 Subject: [PATCH 040/442] Bump ccxt from 4.3.36 to 4.3.39 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.3.36 to 4.3.39. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.3.36...4.3.39) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index c652c62b50e..b493903a112 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.6 gTTS==2.5.0 -ccxt==4.3.36 +ccxt==4.3.39 fitz==0.0.1.dev2 fastapi==0.109.0 Django==5.0.5 From d444fadf9c364ecd605475dbb48933d7cacae2c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 18:59:45 +0000 Subject: [PATCH 041/442] Bump google-api-python-client from 2.115.0 to 2.132.0 Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.115.0 to 2.132.0. - [Release notes](https://github.com/googleapis/google-api-python-client/releases) - [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.115.0...v2.132.0) --- updated-dependencies: - dependency-name: google-api-python-client dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 99bf86b5830..8964296a071 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -58,7 +58,7 @@ requests-mock==1.12.1 pyglet==2.0.10 urllib3==2.2.1 thirdai==0.8.5 -google-api-python-client==2.115.0 +google-api-python-client==2.132.0 sound==0.1.0 xlwt==1.3.0 pygame==2.5.2 From ead7a0b95d78a8eedb0b7caedfd0c7226d303d58 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 18:59:50 +0000 Subject: [PATCH 042/442] Bump pydantic from 2.7.2 to 2.7.3 Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.7.2 to 2.7.3. - [Release notes](https://github.com/pydantic/pydantic/releases) - [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md) - [Commits](https://github.com/pydantic/pydantic/compare/v2.7.2...v2.7.3) --- updated-dependencies: - dependency-name: pydantic dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 99bf86b5830..7ee3ff94498 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -51,7 +51,7 @@ pywifi==1.1.12 patterns==0.3 openai==1.30.4 background==0.2.1 -pydantic==2.7.2 +pydantic==2.7.3 openpyxl==3.1.2 pytesseract==0.3.10 requests-mock==1.12.1 From 52f5647e1e2b335ea8d6e0e935fc108d5e6167ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jun 2024 18:53:07 +0000 Subject: [PATCH 043/442] Bump yfinance from 0.2.35 to 0.2.40 Bumps [yfinance](https://github.com/ranaroussi/yfinance) from 0.2.35 to 0.2.40. - [Release notes](https://github.com/ranaroussi/yfinance/releases) - [Changelog](https://github.com/ranaroussi/yfinance/blob/main/CHANGELOG.rst) - [Commits](https://github.com/ranaroussi/yfinance/compare/0.2.35...0.2.40) --- updated-dependencies: - dependency-name: yfinance dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index a82a54527c5..c01e143b469 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -66,7 +66,7 @@ speechtotext==0.0.3 wikipedia==1.4.0 tqdm==4.66.4 Menu==3.2.2 -yfinance==0.2.35 +yfinance==0.2.40 tweepy==4.14.0 tkcalendar==1.6.1 pytube==15.0.0 From 418c7de3c869133559c369e83865252ff9b227de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jun 2024 18:53:12 +0000 Subject: [PATCH 044/442] Bump tornado from 6.4 to 6.4.1 Bumps [tornado](https://github.com/tornadoweb/tornado) from 6.4 to 6.4.1. - [Changelog](https://github.com/tornadoweb/tornado/blob/master/docs/releases.rst) - [Commits](https://github.com/tornadoweb/tornado/compare/v6.4.0...v6.4.1) --- updated-dependencies: - dependency-name: tornado dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index a82a54527c5..5b8bbf3f34a 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -37,7 +37,7 @@ xlrd==2.0.1 fpdf==1.7.2 mysql-connector-repackaged==0.3.1 word2number==1.1 -tornado==6.4 +tornado==6.4.1 obs==0.0.0 todo==0.1 oauth2client==4.1.3 From 626d074d668b8ac28a8ed78d37a5baf8b4676808 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 18:46:48 +0000 Subject: [PATCH 045/442] Bump twilio from 9.0.0 to 9.1.1 Bumps [twilio](https://github.com/twilio/twilio-python) from 9.0.0 to 9.1.1. - [Release notes](https://github.com/twilio/twilio-python/releases) - [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md) - [Commits](https://github.com/twilio/twilio-python/compare/9.0.0...9.1.1) --- updated-dependencies: - dependency-name: twilio dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 5b9dc910bfc..09ab7162bcb 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -28,7 +28,7 @@ requests==2.32.3 quo==2023.5.1 PyPDF2==3.0.1 pyserial==3.5 -twilio==9.0.0 +twilio==9.1.1 tabula==1.0.5 nltk==3.8.1 Pillow==10.2.0 From ca2420b76c19f458212974e20d8a7d93d7d0feba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 18:46:53 +0000 Subject: [PATCH 046/442] Bump openai from 1.30.4 to 1.33.0 Bumps [openai](https://github.com/openai/openai-python) from 1.30.4 to 1.33.0. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.30.4...v1.33.0) --- updated-dependencies: - dependency-name: openai dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 5b9dc910bfc..9f562616358 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.30.4 +openai==1.33.0 background==0.2.1 pydantic==2.7.3 openpyxl==3.1.2 From d54b3adaea208a79b0d1ed86ba63156d8d423d8e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 18:19:21 +0000 Subject: [PATCH 047/442] Bump pillow from 10.2.0 to 10.3.0 Bumps [pillow](https://github.com/python-pillow/Pillow) from 10.2.0 to 10.3.0. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/10.2.0...10.3.0) --- updated-dependencies: - dependency-name: pillow dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- PDF/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PDF/requirements.txt b/PDF/requirements.txt index 6018eb50919..2b5f7c99140 100644 --- a/PDF/requirements.txt +++ b/PDF/requirements.txt @@ -1,2 +1,2 @@ -Pillow==10.2.0 +Pillow==10.3.0 fpdf==1.7.2 \ No newline at end of file diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index b6b41872b2a..4096f4a5cca 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -31,7 +31,7 @@ pyserial==3.5 twilio==9.1.1 tabula==1.0.5 nltk==3.8.1 -Pillow==10.2.0 +Pillow==10.3.0 SocksiPy-branch==1.01 xlrd==2.0.1 fpdf==1.7.2 From a16248c4a172bddf77a131f7ffff61c8a0670986 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Jun 2024 18:12:52 +0000 Subject: [PATCH 048/442] Bump ccxt from 4.3.39 to 4.3.44 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.3.39 to 4.3.44. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.3.39...4.3.44) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index b6b41872b2a..df55488b92b 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.6 gTTS==2.5.0 -ccxt==4.3.39 +ccxt==4.3.44 fitz==0.0.1.dev2 fastapi==0.109.0 Django==5.0.5 From 5d8fe359044dedd0872303a63b0b5e2096984555 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Jun 2024 18:53:50 +0000 Subject: [PATCH 049/442] Bump pytest from 8.2.0 to 8.2.2 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.2.0 to 8.2.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.2.0...8.2.2) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 3ad93c4bacf..d3050f967c3 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -97,7 +97,7 @@ newspaper==0.1.0.7 opencv-python==4.10.0.82 tensorflow==2.15.0.post1 pandas==2.2.2 -pytest==8.2.0 +pytest==8.2.2 qrcode==7.4.2 googletrans==3.0.0 slab==1.1.5 From 8de9986d1764a3c2ee36e1215cf8d5adf83efc8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Jun 2024 18:53:56 +0000 Subject: [PATCH 050/442] Bump ccxt from 4.3.44 to 4.3.45 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.3.44 to 4.3.45. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.3.44...4.3.45) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 3ad93c4bacf..3be9953dabf 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.6 gTTS==2.5.0 -ccxt==4.3.44 +ccxt==4.3.45 fitz==0.0.1.dev2 fastapi==0.109.0 Django==5.0.5 From 50467ca708ec8baea40930b8688e5cb9f4e01edc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Jun 2024 18:34:33 +0000 Subject: [PATCH 051/442] Bump google-api-python-client from 2.132.0 to 2.133.0 Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.132.0 to 2.133.0. - [Release notes](https://github.com/googleapis/google-api-python-client/releases) - [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.132.0...v2.133.0) --- updated-dependencies: - dependency-name: google-api-python-client dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index a6cc7c33bb9..2499acc6ae4 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -58,7 +58,7 @@ requests-mock==1.12.1 pyglet==2.0.10 urllib3==2.2.1 thirdai==0.8.5 -google-api-python-client==2.132.0 +google-api-python-client==2.133.0 sound==0.1.0 xlwt==1.3.0 pygame==2.5.2 From 9a6e5ba244fb79106d258b73b5f512931447ee57 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Jun 2024 18:34:40 +0000 Subject: [PATCH 052/442] Bump inquirer from 3.2.4 to 3.2.5 Bumps [inquirer](https://github.com/magmax/python-inquirer) from 3.2.4 to 3.2.5. - [Release notes](https://github.com/magmax/python-inquirer/releases) - [Commits](https://github.com/magmax/python-inquirer/compare/v3.2.4...v3.2.5) --- updated-dependencies: - dependency-name: inquirer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Password Generator/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Password Generator/requirements.txt b/Password Generator/requirements.txt index d87a562b3e8..cc6316e082f 100644 --- a/Password Generator/requirements.txt +++ b/Password Generator/requirements.txt @@ -1,2 +1,2 @@ colorama==0.4.6 -inquirer==3.2.4 \ No newline at end of file +inquirer==3.2.5 \ No newline at end of file From a78f081c3d976b20f54705b9781a8d0f9993e3f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 18:12:01 +0000 Subject: [PATCH 053/442] Bump ccxt from 4.3.45 to 4.3.47 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.3.45 to 4.3.47. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.3.45...4.3.47) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 2499acc6ae4..e14b1cc88c5 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.6 gTTS==2.5.0 -ccxt==4.3.45 +ccxt==4.3.47 fitz==0.0.1.dev2 fastapi==0.109.0 Django==5.0.5 From 41cdc03fd69d38631fa672a2dc73e5d099a67d2d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 18:12:13 +0000 Subject: [PATCH 054/442] Bump protobuf from 4.25.2 to 5.27.1 Bumps [protobuf](https://github.com/protocolbuffers/protobuf) from 4.25.2 to 5.27.1. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v4.25.2...v5.27.1) --- updated-dependencies: - dependency-name: protobuf dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 2499acc6ae4..9b953a6203b 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -105,7 +105,7 @@ psutil==5.9.8 mediapipe==0.10.9 rich==13.7.1 httplib2==0.22.0 -protobuf==4.25.2 +protobuf==5.27.1 colorama==0.4.6 plyer==2.1.0 Flask-Ask==0.9.8 From 2cfa37f855fbe3c09f44732f5226edff03eba839 Mon Sep 17 00:00:00 2001 From: anxhul10 Date: Tue, 18 Jun 2024 20:02:19 +0530 Subject: [PATCH 055/442] Create convert_wind_direction_to_degrees.py added new program that convert wind direction in degree to compass direction --- convert_wind_direction_to_degrees.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 convert_wind_direction_to_degrees.py diff --git a/convert_wind_direction_to_degrees.py b/convert_wind_direction_to_degrees.py new file mode 100644 index 00000000000..cbac637f332 --- /dev/null +++ b/convert_wind_direction_to_degrees.py @@ -0,0 +1,19 @@ +def degrees_to_compass(degrees): + directions = ["N", "NE", "E", "SE", "S", "SW", "W", "NW"] + index = round(degrees / 45) % 8 + return directions[index] + +# Taking input from the user +while True: + try: + degrees = float(input("Enter the wind direction in degrees (0-359): ")) + if degrees < 0 or degrees >= 360: + raise ValueError("Degrees must be between 0 and 359") + break + except ValueError as ve: + print(f"Error: {ve}") + continue + + +compass_direction = degrees_to_compass(degrees) +print(f"{degrees} degrees is {compass_direction}") From 5ff20e990ff977a1db9fc789ca790ab89426c453 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 19:01:50 +0000 Subject: [PATCH 056/442] Bump ccxt from 4.3.47 to 4.3.48 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.3.47 to 4.3.48. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.3.47...4.3.48) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 238b76d2811..770cf581bda 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.6 gTTS==2.5.0 -ccxt==4.3.47 +ccxt==4.3.48 fitz==0.0.1.dev2 fastapi==0.109.0 Django==5.0.5 From 7849983c4563ae45d8d44454f6cdc12d7d7170b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 19:01:56 +0000 Subject: [PATCH 057/442] Bump mediapipe from 0.10.9 to 0.10.14 Bumps [mediapipe](https://github.com/google/mediapipe) from 0.10.9 to 0.10.14. - [Release notes](https://github.com/google/mediapipe/releases) - [Commits](https://github.com/google/mediapipe/compare/v0.10.9...v0.10.14) --- updated-dependencies: - dependency-name: mediapipe dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Hand-Motion-Detection/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt index bab2de0ecea..bf096a9d550 100644 --- a/Hand-Motion-Detection/requirements.txt +++ b/Hand-Motion-Detection/requirements.txt @@ -1,3 +1,3 @@ numpy==1.26.4 opencv_python==4.10.0.82 -mediapipe==0.10.9 +mediapipe==0.10.14 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 238b76d2811..b0defc65b54 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -102,7 +102,7 @@ qrcode==7.4.2 googletrans==3.0.0 slab==1.1.5 psutil==5.9.8 -mediapipe==0.10.9 +mediapipe==0.10.14 rich==13.7.1 httplib2==0.22.0 protobuf==5.27.1 From a12b87b2f567bfc6b680542af9ddb03b448f71db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jun 2024 18:52:49 +0000 Subject: [PATCH 058/442] Bump numpy from 1.26.4 to 2.0.0 Bumps [numpy](https://github.com/numpy/numpy) from 1.26.4 to 2.0.0. - [Release notes](https://github.com/numpy/numpy/releases) - [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst) - [Commits](https://github.com/numpy/numpy/compare/v1.26.4...v2.0.0) --- updated-dependencies: - dependency-name: numpy dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- Hand-Motion-Detection/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt index bf096a9d550..e1d96b190e3 100644 --- a/Hand-Motion-Detection/requirements.txt +++ b/Hand-Motion-Detection/requirements.txt @@ -1,3 +1,3 @@ -numpy==1.26.4 +numpy==2.0.0 opencv_python==4.10.0.82 mediapipe==0.10.14 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 370e49370a1..1b2d578402f 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -15,7 +15,7 @@ dictator==0.3.1 caller==0.0.2 watchdog==3.0.0 PyQt5==5.15.10 -numpy==1.26.4 +numpy==2.0.0 fileinfo==0.3.3 backend==0.2.4.1 win10toast==0.9 From bacc0f9ad6eb60175f78d117902d21ed56246ebf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jun 2024 18:52:56 +0000 Subject: [PATCH 059/442] Bump pymongo from 4.7.1 to 4.7.3 Bumps [pymongo](https://github.com/mongodb/mongo-python-driver) from 4.7.1 to 4.7.3. - [Release notes](https://github.com/mongodb/mongo-python-driver/releases) - [Changelog](https://github.com/mongodb/mongo-python-driver/blob/master/doc/changelog.rst) - [Commits](https://github.com/mongodb/mongo-python-driver/compare/4.7.1...4.7.3) --- updated-dependencies: - dependency-name: pymongo dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 370e49370a1..8377c7142c7 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -42,7 +42,7 @@ obs==0.0.0 todo==0.1 oauth2client==4.1.3 keras==3.3.3 -pymongo==4.7.1 +pymongo==4.7.3 playsound==1.3.0 pyttsx3==2.90 auto-mix-prep==0.2.0 From 1ced64316bfee0b7af3f2188870abd77ec342d8c Mon Sep 17 00:00:00 2001 From: anxhul10 Date: Thu, 20 Jun 2024 10:17:03 +0530 Subject: [PATCH 060/442] add_two_number.py --- add_two_number.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 add_two_number.py diff --git a/add_two_number.py b/add_two_number.py new file mode 100644 index 00000000000..2824d2c1872 --- /dev/null +++ b/add_two_number.py @@ -0,0 +1,17 @@ +user_input = (input("type type 'start' to run program:")).lower() + +if user_input == 'start': + is_game_running = True +else: + is_game_running = False + + +while (is_game_running): + num1 = int(input("enter number 1:")) + num2 = int(input("enter number 2:")) + num3 = num1+num2 + print(f"sum of {num1} and {num2} is {num3}") + user_input = (input("if you want to discontinue type 'stop':")).lower() + if user_input == "stop": + is_game_running = False + From c454c925047c91b658d91c337a8e2ecba92a7610 Mon Sep 17 00:00:00 2001 From: ronknight Date: Fri, 19 Jul 2024 08:57:42 -0700 Subject: [PATCH 061/442] Update GUIDE.txt --- Assembler/GUIDE.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assembler/GUIDE.txt b/Assembler/GUIDE.txt index ccb59b84cf7..8b0a3836ef5 100644 --- a/Assembler/GUIDE.txt +++ b/Assembler/GUIDE.txt @@ -67,7 +67,7 @@ int 0x80 ``` -**Important: The arithmetic commands (add, sub) works only with registers or constans. +**Important: The arithmetic commands (add, sub) works only with registers or constants. Therefore we must use the register ebx as a placeholder, above.** From 677ddea8283e89c23c8ff7d0893b960b3d33a655 Mon Sep 17 00:00:00 2001 From: ronknight Date: Fri, 19 Jul 2024 09:05:23 -0700 Subject: [PATCH 062/442] Update GUIDE.txt --- Assembler/GUIDE.txt | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Assembler/GUIDE.txt b/Assembler/GUIDE.txt index 8b0a3836ef5..fbf1b3822be 100644 --- a/Assembler/GUIDE.txt +++ b/Assembler/GUIDE.txt @@ -27,10 +27,10 @@ int 0x80 ``` -* The first line move the number 56 into register ecx. -* The second line subtract 10 from the ecx register. +* The first line move the number 56 into register ecx. +* The second line subtracts 10 from the ecx register. * The third line move the number 4 into the eax register. This is for the print-function. -* The fourt line call interrupt 0x80, thus the result will print onto console. +* The fourth line call interrupt 0x80, thus the result will print onto console. * The fifth line is a new line. This is important. **Important: close each line with a newline!** @@ -67,7 +67,7 @@ int 0x80 ``` -**Important: The arithmetic commands (add, sub) works only with registers or constants. +**Important: The arithmetic commands (add, sub) work only with registers or constants. Therefore we must use the register ebx as a placeholder, above.** @@ -79,12 +79,12 @@ Result of code, above. ### Comments available -Comments begin with ; and ends with a newline. -We noticed a comment, above. +Comments begin with ; and end with a newline. +We noticed a comment above. ### Push and Pop -Sometimes we must save the content of a register, against losing of data. +Sometimes we must save the content of a register, against losing data. Therefor we use the push and pop command. ``` @@ -92,7 +92,7 @@ push eax ``` -This line will push the content of register eax onto the stack. +This line will push the contents of register eax onto the stack. ``` pop ecx @@ -109,7 +109,7 @@ pop [register] ### Jumps -With the command **cmp** we can compare two register. +With the command **cmp** we can compare two registers. ``` cmp r0, r1 @@ -119,7 +119,7 @@ jmp l2 ``` Are the two register equal? The the command **je** is actively and jumps to label **l1** -Otherwise the command **jmp** is actively and jumps to label **l2** +Otherwise, the command **jmp** is actively and jumps to label **l2** #### Labels From 144c453e3f86523b2d57ccfe777e914b289e98cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jul 2024 18:34:12 +0000 Subject: [PATCH 063/442] Bump selenium from 4.16.0 to 4.23.0 Bumps [selenium](https://github.com/SeleniumHQ/Selenium) from 4.16.0 to 4.23.0. - [Release notes](https://github.com/SeleniumHQ/Selenium/releases) - [Commits](https://github.com/SeleniumHQ/Selenium/compare/selenium-4.16.0...selenium-4.23.0) --- updated-dependencies: - dependency-name: selenium dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index bab7905dee8..013c5003885 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -21,7 +21,7 @@ backend==0.2.4.1 win10toast==0.9 Counter==1.0.0 Flask==3.0.2 -selenium==4.16.0 +selenium==4.23.0 firebase-admin==6.5.0 ujson==5.10.0 requests==2.32.3 From efd2ba2e3c41e0d57e8ae51791e2c2e05c8e1b65 Mon Sep 17 00:00:00 2001 From: Ratnesh Kumar <142919875+16ratneshkumar@users.noreply.github.com> Date: Sat, 20 Jul 2024 11:31:38 +0530 Subject: [PATCH 064/442] Update qrcode.py --- QR_code_generator/qrcode.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/QR_code_generator/qrcode.py b/QR_code_generator/qrcode.py index 475f66e99fe..63a4b26684f 100755 --- a/QR_code_generator/qrcode.py +++ b/QR_code_generator/qrcode.py @@ -1,5 +1,6 @@ import pyqrcode, png -from pyqrcode import QRCode +# from pyqrcode import QRCode +# no need to import same library again and again # Creating QR code after given text "input" url = pyqrcode.create(input("Enter text to convert: ")) From b63aa3dc31d9cab794597ceb655cf4372dd37de3 Mon Sep 17 00:00:00 2001 From: Ratnesh Kumar <142919875+16ratneshkumar@users.noreply.github.com> Date: Tue, 23 Jul 2024 16:45:39 +0530 Subject: [PATCH 065/442] Improve & clean code --- find_cube_root.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/find_cube_root.py b/find_cube_root.py index cf315708a25..667f7fa0f2d 100644 --- a/find_cube_root.py +++ b/find_cube_root.py @@ -19,12 +19,12 @@ def cubeRoot(): cubeRoot() -cont = str(input("Would you like to continue: ")) -while cont == "yes": +cont = input("Would you like to continue: ") +while cont == "yes" or "y": cubeRoot() - cont = str(input("Would you like to continue: ")) - if cont == "no": + cont = input("Would you like to continue: ") + if cont == "no" or "n": exit() else: print("Enter a correct answer(yes or no)") - cont = str(input("Would you like to continue: ")) + cont = input("Would you like to continue: ") From de6e85cf6c54ee71dd126753e46fba1cc87450c4 Mon Sep 17 00:00:00 2001 From: Ratnesh Kumar <142919875+16ratneshkumar@users.noreply.github.com> Date: Tue, 23 Jul 2024 17:01:17 +0530 Subject: [PATCH 066/442] clean code Reduce no of loops because not any number is divisible by more than its half --- Prime_number.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Prime_number.py b/Prime_number.py index 1a345b5abe6..92800c63e83 100644 --- a/Prime_number.py +++ b/Prime_number.py @@ -23,7 +23,7 @@ def is_prime_b(n): if n == 2: return True else: - for i in range(2, n): + for i in range(2, int(n//2)+1): if n % i == 0: return False return True From 162b1dc8e008ae6b43b9a1041539689897fecc51 Mon Sep 17 00:00:00 2001 From: Ratnesh Kumar <142919875+16ratneshkumar@users.noreply.github.com> Date: Sun, 28 Jul 2024 22:44:50 +0530 Subject: [PATCH 067/442] Clean code No need for string typecasting because in python every user input is by default string --- qrcode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qrcode.py b/qrcode.py index dde9a035ac4..34bf365bfc7 100644 --- a/qrcode.py +++ b/qrcode.py @@ -3,5 +3,5 @@ # QR Code Generator query = input("Enter Content: ") # Enter Content -code = qrcode.make(str(query)) # Making the QR code +code = qrcode.make(query) # Making the QR code code.save("qrcode.png") # Saving the QR code file From cb57e4c77a35e2695ecfc6990251e45ac7f8e81c Mon Sep 17 00:00:00 2001 From: kautubh01 <146510603+kautubh01@users.noreply.github.com> Date: Mon, 29 Jul 2024 21:57:39 +0530 Subject: [PATCH 068/442] Update pixel_sort.py --- Colors/pixel_sort.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Colors/pixel_sort.py b/Colors/pixel_sort.py index 3c3c06ea616..920e034817f 100644 --- a/Colors/pixel_sort.py +++ b/Colors/pixel_sort.py @@ -43,7 +43,7 @@ def createDataSet(val=0, data=[]): # Generating colors for each row of the frame def generateColors(c_sorted, frame, row): global df, img_list - height = 25 + height = 15 img = np.zeros((height, len(c_sorted), 3), np.uint8) for x in range(0, len(c_sorted)): r, g, b = c_sorted[x][0] * 255, c_sorted[x][1] * 255, c_sorted[x][2] * 255 From 819313a5d01e8e090b41f6504806ad61b1fe6681 Mon Sep 17 00:00:00 2001 From: Ratnesh Kumar <142919875+16ratneshkumar@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:17:58 +0530 Subject: [PATCH 069/442] Add exception handling --- Calculate resistance.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/Calculate resistance.py b/Calculate resistance.py index 10c7a5ad3e2..ee6f10319a1 100644 --- a/Calculate resistance.py +++ b/Calculate resistance.py @@ -1,12 +1,16 @@ -def res(R1, R2): - sum = R1 + R2 - if (option =="series"): - return sum - else: - return (R1 * R2)/(R1 + R2) -Resistance1 = int(input("Enter R1 : ")) -Resistance2 = int(input("Enter R2 : ")) -option = str(input("Enter series or parallel :")) -print("\n") -R = res(Resistance1,Resistance2 ) -print("The total resistance is", R) +def res(R1, R2): + sum = R1 + R2 + if option =="series": + return sum + elif option =="parallel" : + return (R1 * R2)/sum + return 0 +Resistance1 = int(input("Enter R1 : ")) +Resistance2 = int(input("Enter R2 : ")) +option = input("Enter series or parallel :") +print("\n") +R = res(Resistance1,Resistance2 ) +if R==0: + print('Wrong Input!!' ) +else: + print("The total resistance is", R) From c7fa64991c9c7eecf526b1164f1f260deedfe908 Mon Sep 17 00:00:00 2001 From: Pankaj Patil Date: Fri, 2 Aug 2024 23:37:11 +0530 Subject: [PATCH 070/442] Create Trending youtube videos code added --- Trending youtube videos | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Trending youtube videos diff --git a/Trending youtube videos b/Trending youtube videos new file mode 100644 index 00000000000..a14535e4ddc --- /dev/null +++ b/Trending youtube videos @@ -0,0 +1,43 @@ +''' + Python program that uses the YouTube Data API to fetch the top 10 trending YouTube videos. +You’ll need to have an API key from Google Cloud Platform to use the YouTube Data API. + +First, install the google-api-python-client library if you haven’t already: +pip install google-api-python-client + +Replace 'YOUR_API_KEY' with your actual API key. This script will fetch and print the titles, +channels, and view counts of the top 10 trending YouTube videos in India. +You can change the regionCode to any other country code if needed. + +Then, you can use the following code: + +''' + +from googleapiclient.discovery import build + +# Replace with your own API key +API_KEY = 'YOUR_API_KEY' +YOUTUBE_API_SERVICE_NAME = 'youtube' +YOUTUBE_API_VERSION = 'v3' + +def get_trending_videos(): + youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=API_KEY) + + # Call the API to get the top 10 trending videos + request = youtube.videos().list( + part='snippet,statistics', + chart='mostPopular', + regionCode='IN', # Change this to your region code + maxResults=10 + ) + response = request.execute() + + # Print the video details + for item in response['items']: + title = item['snippet']['title'] + channel = item['snippet']['channelTitle'] + views = item['statistics']['viewCount'] + print(f'Title: {title}\nChannel: {channel}\nViews: {views}\n') + +if __name__ == '__main__': + get_trending_videos() From 9b87248747950ed49019569784a991d5908185e1 Mon Sep 17 00:00:00 2001 From: ronknight Date: Mon, 5 Aug 2024 15:16:41 -0700 Subject: [PATCH 071/442] Update CliYoutubeDownloader.py --- CliYoutubeDownloader/CliYoutubeDownloader.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CliYoutubeDownloader/CliYoutubeDownloader.py b/CliYoutubeDownloader/CliYoutubeDownloader.py index 81c35a81ad8..d155f25cf0f 100644 --- a/CliYoutubeDownloader/CliYoutubeDownloader.py +++ b/CliYoutubeDownloader/CliYoutubeDownloader.py @@ -6,7 +6,7 @@ class YouTubeDownloder: def __init__(self): - self.url = str(input("Enter the url of video : ")) + self.url = str(input("Enter the URL of video : ")) self.youtube = pytube.YouTube( self.url, on_progress_callback=YouTubeDownloder.onProgress ) @@ -28,14 +28,14 @@ def showStreams(self): self.chooseStream() def chooseStream(self): - self.choose = int(input("please select one : ")) + self.choose = int(input("Please select one : ")) self.validateChooseValue() def validateChooseValue(self): if self.choose in range(1, self.streamNo): self.getStream() else: - print("please enter a correct option on the list.") + print("Please enter a correct option on the list.") self.chooseStream() def getStream(self): @@ -49,7 +49,7 @@ def getFileSize(self): def getPermisionToContinue(self): print( - "\n title : {0} \n author : {1} \n size : {2:.2f}MB \n resolution : {3} \n fps : {4} \n ".format( + "\n Title : {0} \n Author : {1} \n Size : {2:.2f}MB \n Resolution : {3} \n FPS : {4} \n ".format( self.youtube.title, self.youtube.author, file_size, @@ -57,7 +57,7 @@ def getPermisionToContinue(self): self.stream.fps, ) ) - if input("do you want it ?(defualt = (y)es) or (n)o ") == "n": + if input("Do you want it ?(default = (y)es) or (n)o ") == "n": self.showStreams() else: self.main() @@ -69,7 +69,7 @@ def download(self): def onProgress(stream=None, chunk=None, remaining=None): file_downloaded = file_size - (remaining / 1000000) print( - f"downloading ... {file_downloaded/file_size*100:0.2f} % [{file_downloaded:.1f}MB of {file_size:.1f}MB]", + f"Downloading ... {file_downloaded/file_size*100:0.2f} % [{file_downloaded:.1f}MB of {file_size:.1f}MB]", end="\r", ) From ed3f3f4c5abe4dcf16ef836b8221dc25691d091f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 18:52:30 +0000 Subject: [PATCH 072/442] Bump django from 5.0.5 to 5.1 Bumps [django](https://github.com/django/django) from 5.0.5 to 5.1. - [Commits](https://github.com/django/django/compare/5.0.5...5.1) --- updated-dependencies: - dependency-name: django dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 013c5003885..a734052b39b 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -84,7 +84,7 @@ gTTS==2.5.0 ccxt==4.3.48 fitz==0.0.1.dev2 fastapi==0.109.0 -Django==5.0.5 +Django==5.1 docx==0.2.4 matplotlib==3.9.0 pyshorteners==1.0.1 From 80910532e8d3b051bc07cf1f454b8c8b2d161497 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Aug 2024 18:21:54 +0000 Subject: [PATCH 073/442] Bump psutil from 5.9.8 to 6.0.0 Bumps [psutil](https://github.com/giampaolo/psutil) from 5.9.8 to 6.0.0. - [Changelog](https://github.com/giampaolo/psutil/blob/master/HISTORY.rst) - [Commits](https://github.com/giampaolo/psutil/compare/release-5.9.8...release-6.0.0) --- updated-dependencies: - dependency-name: psutil dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index a734052b39b..63cb3490fb4 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -101,7 +101,7 @@ pytest==8.2.2 qrcode==7.4.2 googletrans==3.0.0 slab==1.1.5 -psutil==5.9.8 +psutil==6.0.0 mediapipe==0.10.14 rich==13.7.1 httplib2==0.22.0 From 15bbe5506f3ebffdc193ee632ae7d5a75890d4eb Mon Sep 17 00:00:00 2001 From: Ratnesh Kumar <142919875+16ratneshkumar@users.noreply.github.com> Date: Sat, 10 Aug 2024 04:59:12 +0530 Subject: [PATCH 074/442] Optimize solution --- Patterns/pattern5.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Patterns/pattern5.py b/Patterns/pattern5.py index 58f75df847b..d0c20b8afb9 100644 --- a/Patterns/pattern5.py +++ b/Patterns/pattern5.py @@ -9,11 +9,11 @@ def main(): lines = int(input("Enter the number of lines: ")) pattern(lines) -def pattern(rows): - for i in range(1, rows+1): - for j in range(i, 0, -1): - print(j, end="") - print() +def pattern(rows): + const='' + for i in range(1, rows+1): + const=str(i)+const + print(const) if __name__ == "__main__": main() From b28b36b7785233d82c95e7dc0ac240ad190de60e Mon Sep 17 00:00:00 2001 From: Ratnesh Kumar <142919875+16ratneshkumar@users.noreply.github.com> Date: Sat, 10 Aug 2024 05:02:19 +0530 Subject: [PATCH 075/442] Optimize solution --- Patterns/pattern2.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Patterns/pattern2.py b/Patterns/pattern2.py index 5e8650e3860..84093334cb0 100644 --- a/Patterns/pattern2.py +++ b/Patterns/pattern2.py @@ -13,14 +13,10 @@ def main(): pattern(lines) def pattern(lines): - for i in range(lines,0,-1): - for j in range(lines-i): - print(' ', end='') - - for j in range(2*i-1): - print('$',end='') - print() - + flag=lines + for i in range(lines): + print(" "*(i),'$'*(2*flag-1)) + flag-=1 if __name__ == "__main__": main() From cb12a3dbd7bc9426761cc92077db9bf2833e4d02 Mon Sep 17 00:00:00 2001 From: Ratnesh Kumar <142919875+16ratneshkumar@users.noreply.github.com> Date: Sat, 10 Aug 2024 05:06:27 +0530 Subject: [PATCH 076/442] Optimize solution --- Patterns/patterns.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/Patterns/patterns.py b/Patterns/patterns.py index a23b463df12..9aa70bd0883 100644 --- a/Patterns/patterns.py +++ b/Patterns/patterns.py @@ -19,21 +19,11 @@ def main(): pattern(lines) def pattern(lines): + for i in range(1,lines+1): + print("* "*i) + print() for i in range(lines): - for j in range(i+1): - print("* ", end="") - print("") - print(" ") - - for i in range(0,lines): - - for j in range(0, (2 * (i - 1)) + 1): - print(" ", end="") - - for j in range(0, lines - i): - print("*", end=" ") - - print("") + print(" "*i,"* "*(lines-i)) if __name__ == "__main__": main() From 85a3bd71c5bfe36fd2ac4937c0cdbc71727d8e0f Mon Sep 17 00:00:00 2001 From: Ratnesh Kumar <142919875+16ratneshkumar@users.noreply.github.com> Date: Sat, 10 Aug 2024 05:10:07 +0530 Subject: [PATCH 077/442] Optimize solution --- Patterns/half triangle pattern.py | 44 +++++++++++-------------------- 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/Patterns/half triangle pattern.py b/Patterns/half triangle pattern.py index 982ae8efda6..4a87b93f7c4 100644 --- a/Patterns/half triangle pattern.py +++ b/Patterns/half triangle pattern.py @@ -40,43 +40,31 @@ def main(): print("Invalid input") exit(0) -def upper_half_repeat_pattern(lines): +def upper_half_repeat_pattern(lines=5): + for column in range(1, (lines +1)): + print(f"{str(column) * column}") - t = 1 - for column in range(1, (lines +1)): - print(f"{str(t) * column}") - t += 1 -def upper_half_incremental_pattern(lines): +def lower_half_repeat_pattern(lines=5): + for length in range(lines, 0, -1): + print(f"{str(length) * length}") - for column in range(1, (lines +1)): - row = "" - for ii in range(1, column +1): - row += str(ii) - print(row) - -def lower_half_incremental_pattern(lines): +def upper_half_incremental_pattern(lines=5): + const="" + for column in range(1, (lines +1)): + const+=str(column) + print(const) - for row_length in range(lines, 0, -1): - row = "" - column = 1 - for _ in range(row_length): - column = 0 if column == 10 else column - row = f"{row}{column}" - column += 1 - print(row) +def lower_half_incremental_pattern(lines=5): + for row_length in range(lines, 0, -1): + for x in range(1,row_length+1): + print(x,end='') + print() -def lower_half_repeat_pattern(lines): - for row_length in range(lines, 0, -1): - - row = "" - for _ in range(1, row_length+1): - row += str(row_length) - print(row) if __name__ == "__main__": main() From cfe67f6281db61949c32f1ba0920e32c6e71acea Mon Sep 17 00:00:00 2001 From: Ratnesh Kumar <142919875+16ratneshkumar@users.noreply.github.com> Date: Mon, 12 Aug 2024 05:20:57 +0530 Subject: [PATCH 078/442] Clean code --- new_pattern.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/new_pattern.py b/new_pattern.py index e9ebc1c257c..6c5120eb586 100644 --- a/new_pattern.py +++ b/new_pattern.py @@ -12,14 +12,14 @@ def main(): lines = int(input("Enter no.of lines: ")) pattern(lines) -def pattern(lines): - t = 1 - for i in reversed(range(lines)): - nxt_pattern = "$"*t - pattern = "@"*(i+1) - final_pattern = pattern + " n " + nxt_pattern - print(final_pattern) - t = t +1 +def pattern(lines): + t = 1 + for i in range(lines,0,-1): + nxt_pattern = "$"*t + pattern = "@"*(i) + final_pattern = pattern + " " + nxt_pattern + print(final_pattern) + t = t +1 if __name__ == "__main__": - main() \ No newline at end of file + main() From 394f1710ffb8ab03b236eaed9e3e3df50bf8efd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 18:37:15 +0000 Subject: [PATCH 079/442] Bump watchdog from 3.0.0 to 4.0.2 Bumps [watchdog](https://github.com/gorakhargosh/watchdog) from 3.0.0 to 4.0.2. - [Release notes](https://github.com/gorakhargosh/watchdog/releases) - [Changelog](https://github.com/gorakhargosh/watchdog/blob/master/changelog.rst) - [Commits](https://github.com/gorakhargosh/watchdog/compare/v3.0.0...v4.0.2) --- updated-dependencies: - dependency-name: watchdog dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index a734052b39b..a48e7e0c7ba 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -13,7 +13,7 @@ pong==1.5 beautifulsoup4==4.12.3 dictator==0.3.1 caller==0.0.2 -watchdog==3.0.0 +watchdog==4.0.2 PyQt5==5.15.10 numpy==2.0.0 fileinfo==0.3.3 From 6485bb526b355e889e5d9fcac91e126498bb7bd6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2024 18:24:46 +0000 Subject: [PATCH 080/442] Bump pydantic from 2.7.3 to 2.8.2 Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.7.3 to 2.8.2. - [Release notes](https://github.com/pydantic/pydantic/releases) - [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md) - [Commits](https://github.com/pydantic/pydantic/compare/v2.7.3...v2.8.2) --- updated-dependencies: - dependency-name: pydantic dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4794d971136..fdf8277c8f3 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -51,7 +51,7 @@ pywifi==1.1.12 patterns==0.3 openai==1.33.0 background==0.2.1 -pydantic==2.7.3 +pydantic==2.8.2 openpyxl==3.1.2 pytesseract==0.3.10 requests-mock==1.12.1 From 398186baa89de6fdfb43f17ee31badea24f2c177 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2024 18:24:51 +0000 Subject: [PATCH 081/442] Bump selenium from 4.23.0 to 4.23.1 Bumps [selenium](https://github.com/SeleniumHQ/Selenium) from 4.23.0 to 4.23.1. - [Release notes](https://github.com/SeleniumHQ/Selenium/releases) - [Commits](https://github.com/SeleniumHQ/Selenium/commits) --- updated-dependencies: - dependency-name: selenium dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4794d971136..b3ea8db29a9 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -21,7 +21,7 @@ backend==0.2.4.1 win10toast==0.9 Counter==1.0.0 Flask==3.0.2 -selenium==4.23.0 +selenium==4.23.1 firebase-admin==6.5.0 ujson==5.10.0 requests==2.32.3 From 8a12ffc90dd81a527a45cff2a8ae7ea6e42dda5c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2024 18:24:54 +0000 Subject: [PATCH 082/442] Bump urllib3 from 2.2.1 to 2.2.2 Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.2.1 to 2.2.2. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/2.2.1...2.2.2) --- updated-dependencies: - dependency-name: urllib3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4794d971136..9627cf1c32c 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -56,7 +56,7 @@ openpyxl==3.1.2 pytesseract==0.3.10 requests-mock==1.12.1 pyglet==2.0.10 -urllib3==2.2.1 +urllib3==2.2.2 thirdai==0.8.5 google-api-python-client==2.133.0 sound==0.1.0 From a7d80295e683dbdd2623aa4f687560e7186bb1fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2024 18:26:03 +0000 Subject: [PATCH 083/442] Bump gtts from 2.5.0 to 2.5.3 Bumps [gtts](https://github.com/pndurette/gTTS) from 2.5.0 to 2.5.3. - [Release notes](https://github.com/pndurette/gTTS/releases) - [Changelog](https://github.com/pndurette/gTTS/blob/main/CHANGELOG.md) - [Commits](https://github.com/pndurette/gTTS/compare/v2.5.0...v2.5.3) --- updated-dependencies: - dependency-name: gtts dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- text_to_audio/requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4794d971136..6f156259a74 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -80,7 +80,7 @@ mutagen==1.47.0 Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.6 -gTTS==2.5.0 +gTTS==2.5.3 ccxt==4.3.48 fitz==0.0.1.dev2 fastapi==0.109.0 diff --git a/text_to_audio/requirements.txt b/text_to_audio/requirements.txt index 7d305335aac..60da1e66bcf 100644 --- a/text_to_audio/requirements.txt +++ b/text_to_audio/requirements.txt @@ -1,2 +1,2 @@ -gTTS==2.5.0 +gTTS==2.5.3 pygame==2.5.2 From 0d1d59e269500f1949387943851a9dd8cadd2dac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 18:23:37 +0000 Subject: [PATCH 084/442] Bump pytest from 8.2.2 to 8.3.2 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.2.2 to 8.3.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.2.2...8.3.2) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 3f7847a8e65..0a3a3d5bb59 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -97,7 +97,7 @@ newspaper==0.1.0.7 opencv-python==4.10.0.82 tensorflow==2.15.0.post1 pandas==2.2.2 -pytest==8.2.2 +pytest==8.3.2 qrcode==7.4.2 googletrans==3.0.0 slab==1.1.5 From 61dac730e22a710a006f1aafc1ba97563bbf7c43 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 18:23:38 +0000 Subject: [PATCH 085/442] Bump flask from 3.0.2 to 3.0.3 Bumps [flask](https://github.com/pallets/flask) from 3.0.2 to 3.0.3. - [Release notes](https://github.com/pallets/flask/releases) - [Changelog](https://github.com/pallets/flask/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/flask/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: flask dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 3f7847a8e65..ecd29e6d043 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -20,7 +20,7 @@ fileinfo==0.3.3 backend==0.2.4.1 win10toast==0.9 Counter==1.0.0 -Flask==3.0.2 +Flask==3.0.3 selenium==4.23.1 firebase-admin==6.5.0 ujson==5.10.0 From c4a64a255b0c639e1420e632c9ceb4c034a41403 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 18:23:42 +0000 Subject: [PATCH 086/442] Bump yfinance from 0.2.40 to 0.2.41 Bumps [yfinance](https://github.com/ranaroussi/yfinance) from 0.2.40 to 0.2.41. - [Release notes](https://github.com/ranaroussi/yfinance/releases) - [Changelog](https://github.com/ranaroussi/yfinance/blob/main/CHANGELOG.rst) - [Commits](https://github.com/ranaroussi/yfinance/compare/0.2.40...0.2.41) --- updated-dependencies: - dependency-name: yfinance dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 3f7847a8e65..13528930a7b 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -66,7 +66,7 @@ speechtotext==0.0.3 wikipedia==1.4.0 tqdm==4.66.4 Menu==3.2.2 -yfinance==0.2.40 +yfinance==0.2.41 tweepy==4.14.0 tkcalendar==1.6.1 pytube==15.0.0 From ba693c3d53e000fb604e53bca543b1659a5cc398 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 18:23:46 +0000 Subject: [PATCH 087/442] Bump openai from 1.33.0 to 1.42.0 Bumps [openai](https://github.com/openai/openai-python) from 1.33.0 to 1.42.0. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.33.0...v1.42.0) --- updated-dependencies: - dependency-name: openai dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 3f7847a8e65..ba61d2281f8 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.33.0 +openai==1.42.0 background==0.2.1 pydantic==2.8.2 openpyxl==3.1.2 From 4cd253e1b6a82d9cd31113e830b70397b6997cda Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 18:37:47 +0000 Subject: [PATCH 088/442] Bump pygame from 2.5.2 to 2.6.0 Bumps [pygame](https://github.com/pygame/pygame) from 2.5.2 to 2.6.0. - [Release notes](https://github.com/pygame/pygame/releases) - [Commits](https://github.com/pygame/pygame/compare/2.5.2...2.6.0) --- updated-dependencies: - dependency-name: pygame dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- text_to_audio/requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index f8f0d6614da..03a2423cd06 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -61,7 +61,7 @@ thirdai==0.8.5 google-api-python-client==2.133.0 sound==0.1.0 xlwt==1.3.0 -pygame==2.5.2 +pygame==2.6.0 speechtotext==0.0.3 wikipedia==1.4.0 tqdm==4.66.4 diff --git a/text_to_audio/requirements.txt b/text_to_audio/requirements.txt index 60da1e66bcf..a91c978b7d4 100644 --- a/text_to_audio/requirements.txt +++ b/text_to_audio/requirements.txt @@ -1,2 +1,2 @@ gTTS==2.5.3 -pygame==2.5.2 +pygame==2.6.0 From cf8e7e66c61519f79dc028d99e2afef60ce04369 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 18:37:51 +0000 Subject: [PATCH 089/442] Bump tqdm from 4.66.4 to 4.66.5 Bumps [tqdm](https://github.com/tqdm/tqdm) from 4.66.4 to 4.66.5. - [Release notes](https://github.com/tqdm/tqdm/releases) - [Commits](https://github.com/tqdm/tqdm/compare/v4.66.4...v4.66.5) --- updated-dependencies: - dependency-name: tqdm dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index f8f0d6614da..f0dacab5ed9 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -64,7 +64,7 @@ xlwt==1.3.0 pygame==2.5.2 speechtotext==0.0.3 wikipedia==1.4.0 -tqdm==4.66.4 +tqdm==4.66.5 Menu==3.2.2 yfinance==0.2.41 tweepy==4.14.0 From 69c2c1cf13c539c6aa40928e27dfae20bee96dd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 18:37:53 +0000 Subject: [PATCH 090/442] Bump keras from 3.3.3 to 3.5.0 Bumps [keras](https://github.com/keras-team/keras) from 3.3.3 to 3.5.0. - [Release notes](https://github.com/keras-team/keras/releases) - [Commits](https://github.com/keras-team/keras/compare/v3.3.3...v3.5.0) --- updated-dependencies: - dependency-name: keras dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index f8f0d6614da..b13367f4417 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -41,7 +41,7 @@ tornado==6.4.1 obs==0.0.0 todo==0.1 oauth2client==4.1.3 -keras==3.3.3 +keras==3.5.0 pymongo==4.7.3 playsound==1.3.0 pyttsx3==2.90 From 15eee776a0670028cd733a2104f001ccd28ea2b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Aug 2024 18:10:49 +0000 Subject: [PATCH 091/442] Bump matplotlib from 3.9.0 to 3.9.2 Bumps [matplotlib](https://github.com/matplotlib/matplotlib) from 3.9.0 to 3.9.2. - [Release notes](https://github.com/matplotlib/matplotlib/releases) - [Commits](https://github.com/matplotlib/matplotlib/compare/v3.9.0...v3.9.2) --- updated-dependencies: - dependency-name: matplotlib dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index c19515d9f9e..1b0c6546c63 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -86,7 +86,7 @@ fitz==0.0.1.dev2 fastapi==0.109.0 Django==5.1 docx==0.2.4 -matplotlib==3.9.0 +matplotlib==3.9.2 pyshorteners==1.0.1 geocoder==1.38.1 APScheduler==3.10.4 From 1911aacf58cd7a5d2371baaa54e265d8949f6242 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Aug 2024 18:10:53 +0000 Subject: [PATCH 092/442] Bump pytesseract from 0.3.10 to 0.3.13 Bumps [pytesseract](https://github.com/madmaze/pytesseract) from 0.3.10 to 0.3.13. - [Release notes](https://github.com/madmaze/pytesseract/releases) - [Commits](https://github.com/madmaze/pytesseract/compare/v0.3.10...v0.3.13) --- updated-dependencies: - dependency-name: pytesseract dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index c19515d9f9e..1e3831f6454 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -53,7 +53,7 @@ openai==1.42.0 background==0.2.1 pydantic==2.8.2 openpyxl==3.1.2 -pytesseract==0.3.10 +pytesseract==0.3.13 requests-mock==1.12.1 pyglet==2.0.10 urllib3==2.2.2 From 9bc02697a42ca23f368e3acf05bbcf3d15b9d574 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Aug 2024 18:11:01 +0000 Subject: [PATCH 093/442] Bump ccxt from 4.3.48 to 4.3.87 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.3.48 to 4.3.87. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.3.48...4.3.87) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index c19515d9f9e..ddd155ba662 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.6 gTTS==2.5.3 -ccxt==4.3.48 +ccxt==4.3.87 fitz==0.0.1.dev2 fastapi==0.109.0 Django==5.1 From 7b845d2d7d9bcb895959c2595670d03aa4416708 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 18:25:43 +0000 Subject: [PATCH 094/442] Bump pyqt5 from 5.15.10 to 5.15.11 Bumps [pyqt5](https://www.riverbankcomputing.com/software/pyqt/) from 5.15.10 to 5.15.11. --- updated-dependencies: - dependency-name: pyqt5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 8fc5ace8afa..b1e7bd03f0a 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -14,7 +14,7 @@ beautifulsoup4==4.12.3 dictator==0.3.1 caller==0.0.2 watchdog==4.0.2 -PyQt5==5.15.10 +PyQt5==5.15.11 numpy==2.0.0 fileinfo==0.3.3 backend==0.2.4.1 From aa285eb10ae6349e068c758b3e74fb95491d9e01 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 18:25:48 +0000 Subject: [PATCH 095/442] Bump gunicorn from 22.0.0 to 23.0.0 Bumps [gunicorn](https://github.com/benoitc/gunicorn) from 22.0.0 to 23.0.0. - [Release notes](https://github.com/benoitc/gunicorn/releases) - [Commits](https://github.com/benoitc/gunicorn/compare/22.0.0...23.0.0) --- updated-dependencies: - dependency-name: gunicorn dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- News_App/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/News_App/requirements.txt b/News_App/requirements.txt index 39898116fb8..83fab2fbda5 100644 --- a/News_App/requirements.txt +++ b/News_App/requirements.txt @@ -1,6 +1,6 @@ solara == 1.32.2 Flask -gunicorn ==22.0.0 +gunicorn ==23.0.0 simple-websocket flask-sock yfinance \ No newline at end of file From 1231c092faf576a0cbfca54805634344ef4e964f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 18:25:54 +0000 Subject: [PATCH 096/442] Bump google-api-python-client from 2.133.0 to 2.142.0 Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.133.0 to 2.142.0. - [Release notes](https://github.com/googleapis/google-api-python-client/releases) - [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.133.0...v2.142.0) --- updated-dependencies: - dependency-name: google-api-python-client dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 8fc5ace8afa..326db4f1ba6 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -58,7 +58,7 @@ requests-mock==1.12.1 pyglet==2.0.10 urllib3==2.2.2 thirdai==0.8.5 -google-api-python-client==2.133.0 +google-api-python-client==2.142.0 sound==0.1.0 xlwt==1.3.0 pygame==2.6.0 From 80a4c172094dae9dfa313e95aeb40665e60c76d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 18:45:21 +0000 Subject: [PATCH 097/442] Bump numpy from 2.0.0 to 2.1.0 Bumps [numpy](https://github.com/numpy/numpy) from 2.0.0 to 2.1.0. - [Release notes](https://github.com/numpy/numpy/releases) - [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst) - [Commits](https://github.com/numpy/numpy/compare/v2.0.0...v2.1.0) --- updated-dependencies: - dependency-name: numpy dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Hand-Motion-Detection/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt index e1d96b190e3..559078a79e0 100644 --- a/Hand-Motion-Detection/requirements.txt +++ b/Hand-Motion-Detection/requirements.txt @@ -1,3 +1,3 @@ -numpy==2.0.0 +numpy==2.1.0 opencv_python==4.10.0.82 mediapipe==0.10.14 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 45c9041916b..6091bc97104 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -15,7 +15,7 @@ dictator==0.3.1 caller==0.0.2 watchdog==4.0.2 PyQt5==5.15.11 -numpy==2.0.0 +numpy==2.1.0 fileinfo==0.3.3 backend==0.2.4.1 win10toast==0.9 From 4bccb98615ce21fd45fe6583955027a6b564c070 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 18:45:24 +0000 Subject: [PATCH 098/442] Bump pynput from 1.7.6 to 1.7.7 Bumps [pynput](https://github.com/moses-palmer/pynput) from 1.7.6 to 1.7.7. - [Changelog](https://github.com/moses-palmer/pynput/blob/master/CHANGES.rst) - [Commits](https://github.com/moses-palmer/pynput/compare/v1.7.6...v1.7.7) --- updated-dependencies: - dependency-name: pynput dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 45c9041916b..23283bc0ef3 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -79,7 +79,7 @@ pywhatkit==5.4 mutagen==1.47.0 Unidecode==1.3.8 Ball==0.2.9 -pynput==1.7.6 +pynput==1.7.7 gTTS==2.5.3 ccxt==4.3.87 fitz==0.0.1.dev2 From b90ee19a6da75b73176959bfd6df5e34429c5bf2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 18:45:26 +0000 Subject: [PATCH 099/442] Bump nltk from 3.8.1 to 3.9.1 Bumps [nltk](https://github.com/nltk/nltk) from 3.8.1 to 3.9.1. - [Changelog](https://github.com/nltk/nltk/blob/develop/ChangeLog) - [Commits](https://github.com/nltk/nltk/compare/3.8.1...3.9.1) --- updated-dependencies: - dependency-name: nltk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 45c9041916b..86f0dc68ca1 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -30,7 +30,7 @@ PyPDF2==3.0.1 pyserial==3.5 twilio==9.1.1 tabula==1.0.5 -nltk==3.8.1 +nltk==3.9.1 Pillow==10.3.0 SocksiPy-branch==1.01 xlrd==2.0.1 From 585c7afc9cb1bc37a62cd36af4e86d36c63970f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Aug 2024 18:54:53 +0000 Subject: [PATCH 100/442] Bump aiohttp from 3.9.5 to 3.10.5 Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.9.5 to 3.10.5. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.9.5...v3.10.5) --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- async_downloader/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/async_downloader/requirements.txt b/async_downloader/requirements.txt index d395d9cf8f0..882b7d9efab 100644 --- a/async_downloader/requirements.txt +++ b/async_downloader/requirements.txt @@ -1 +1 @@ -aiohttp==3.9.5 +aiohttp==3.10.5 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index b58ca35f657..603fe507051 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -1,5 +1,5 @@ pafy==0.5.5 -aiohttp==3.9.5 +aiohttp==3.10.5 fuzzywuzzy==0.18.0 hupper==1.12.1 seaborn==0.13.2 From 1d4e891d2a63c88f7cf071cd7cd9e01ab30d1946 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Aug 2024 18:55:03 +0000 Subject: [PATCH 101/442] Bump pyttsx3 from 2.90 to 2.91 Bumps [pyttsx3](https://github.com/nateshmbhat/pyttsx3) from 2.90 to 2.91. - [Release notes](https://github.com/nateshmbhat/pyttsx3/releases) - [Commits](https://github.com/nateshmbhat/pyttsx3/compare/v.2.90...v2.91) --- updated-dependencies: - dependency-name: pyttsx3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index b58ca35f657..e41d95e3109 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -44,7 +44,7 @@ oauth2client==4.1.3 keras==3.5.0 pymongo==4.7.3 playsound==1.3.0 -pyttsx3==2.90 +pyttsx3==2.91 auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 From b0dcf1196232b61b6cbc42aa424416861940abc1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 18:28:38 +0000 Subject: [PATCH 102/442] Bump thirdai from 0.8.5 to 0.9.11 Bumps thirdai from 0.8.5 to 0.9.11. --- updated-dependencies: - dependency-name: thirdai dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index b58ca35f657..25238e89b4c 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -57,7 +57,7 @@ pytesseract==0.3.13 requests-mock==1.12.1 pyglet==2.0.10 urllib3==2.2.2 -thirdai==0.8.5 +thirdai==0.9.11 google-api-python-client==2.142.0 sound==0.1.0 xlwt==1.3.0 From 8bd90be9c8f91a4825a11477c64c233410c5a107 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 18:29:41 +0000 Subject: [PATCH 103/442] Bump slab from 1.1.5 to 1.7.0 Bumps [slab](https://github.com/DrMarc/slab) from 1.1.5 to 1.7.0. - [Release notes](https://github.com/DrMarc/slab/releases) - [Commits](https://github.com/DrMarc/slab/compare/v1.1.5...v1.7.0) --- updated-dependencies: - dependency-name: slab dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index b58ca35f657..fabca5fcd1b 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -100,7 +100,7 @@ pandas==2.2.2 pytest==8.3.2 qrcode==7.4.2 googletrans==3.0.0 -slab==1.1.5 +slab==1.7.0 psutil==6.0.0 mediapipe==0.10.14 rich==13.7.1 From 24dd8d1fbacde611564e6f43813368529f86b0a8 Mon Sep 17 00:00:00 2001 From: Muhammad90Emon Date: Sun, 1 Sep 2024 20:16:13 +0000 Subject: [PATCH 104/442] Simple Calculator --- oryx-build-commands.txt | 2 ++ simple_calculator/simple_calculator.py | 49 ++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 oryx-build-commands.txt create mode 100644 simple_calculator/simple_calculator.py diff --git a/oryx-build-commands.txt b/oryx-build-commands.txt new file mode 100644 index 00000000000..d647bdf7fdf --- /dev/null +++ b/oryx-build-commands.txt @@ -0,0 +1,2 @@ +PlatformWithVersion=Python +BuildCommands=conda env create --file environment.yml --prefix ./venv --quiet diff --git a/simple_calculator/simple_calculator.py b/simple_calculator/simple_calculator.py new file mode 100644 index 00000000000..ec8a7c11b26 --- /dev/null +++ b/simple_calculator/simple_calculator.py @@ -0,0 +1,49 @@ +# Define functions for each operation +def add(x, y): + return x + y + + def subtract(x, y): + return x - y + + def multiply(x, y): + return x * y + + def divide(x, y): + return x / y + + # Display the options to the user + print("Select operation:") + print("1. Add") + print("2. Subtract") + print("3. Multiply") + print("4. Divide") + + while True: + # Take input from the user + choice = input("Enter choice (1/2/3/4): ") + + # Check if the choice is one of the four options + if choice in ('1', '2', '3', '4'): + try: + num1 = float(input("Enter first number: ")) + num2 = float(input("Enter second number: ")) + except ValueError: + print("Invalid input. Please enter a number.") + continue + + if choice == '1': + print(f"{num1} + {num2} = {add(num1, num2)}") + elif choice == '2': + print(f"{num1} - {num2} = {subtract(num1, num2)}") + elif choice == '3': + print(f"{num1} * {num2} = {multiply(num1, num2)}") + elif choice == '4': + print(f"{num1} / {num2} = {divide(num1, num2)}") + + # Check if the user wants another calculation + next_calculation = input("Do you want to perform another calculation? (yes/no): ") + if next_calculation.lower() != 'yes': + break + else: + print("Invalid input") + \ No newline at end of file From 2b1db9f767034b6e88eff086e5353eeb476bbca0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 18:58:35 +0000 Subject: [PATCH 105/442] Bump emoji from 2.11.1 to 2.12.1 Bumps [emoji](https://github.com/carpedm20/emoji) from 2.11.1 to 2.12.1. - [Release notes](https://github.com/carpedm20/emoji/releases) - [Changelog](https://github.com/carpedm20/emoji/blob/master/CHANGES.md) - [Commits](https://github.com/carpedm20/emoji/compare/v2.11.1...v2.12.1) --- updated-dependencies: - dependency-name: emoji dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 170a595ec75..2533a7d7bff 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -109,5 +109,5 @@ protobuf==5.27.1 colorama==0.4.6 plyer==2.1.0 Flask-Ask==0.9.8 -emoji==2.11.1 +emoji==2.12.1 PyAutoGUI==0.9.54 From 9531802cac14de54c53b4efc6d8cd7fe9c38d947 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 18:58:38 +0000 Subject: [PATCH 106/442] Bump yfinance from 0.2.41 to 0.2.43 Bumps [yfinance](https://github.com/ranaroussi/yfinance) from 0.2.41 to 0.2.43. - [Release notes](https://github.com/ranaroussi/yfinance/releases) - [Changelog](https://github.com/ranaroussi/yfinance/blob/main/CHANGELOG.rst) - [Commits](https://github.com/ranaroussi/yfinance/compare/0.2.41...0.2.43) --- updated-dependencies: - dependency-name: yfinance dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 170a595ec75..e916876c2a6 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -66,7 +66,7 @@ speechtotext==0.0.3 wikipedia==1.4.0 tqdm==4.66.5 Menu==3.2.2 -yfinance==0.2.41 +yfinance==0.2.43 tweepy==4.14.0 tkcalendar==1.6.1 pytube==15.0.0 From 71691d12afad829be49a4d9a2ae03a3d11c3df88 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 18:58:41 +0000 Subject: [PATCH 107/442] Bump inquirer from 3.2.5 to 3.4.0 Bumps [inquirer](https://github.com/magmax/python-inquirer) from 3.2.5 to 3.4.0. - [Release notes](https://github.com/magmax/python-inquirer/releases) - [Commits](https://github.com/magmax/python-inquirer/compare/v3.2.5...v3.4.0) --- updated-dependencies: - dependency-name: inquirer dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Password Generator/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Password Generator/requirements.txt b/Password Generator/requirements.txt index cc6316e082f..8fb084425cf 100644 --- a/Password Generator/requirements.txt +++ b/Password Generator/requirements.txt @@ -1,2 +1,2 @@ colorama==0.4.6 -inquirer==3.2.5 \ No newline at end of file +inquirer==3.4.0 \ No newline at end of file From 7db49341fddb5406df23916a7981ab2c31d4be3b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 18:27:32 +0000 Subject: [PATCH 108/442] Bump pyglet from 2.0.10 to 2.0.17 Bumps [pyglet](https://github.com/pyglet/pyglet) from 2.0.10 to 2.0.17. - [Release notes](https://github.com/pyglet/pyglet/releases) - [Changelog](https://github.com/pyglet/pyglet/blob/master/RELEASE_NOTES) - [Commits](https://github.com/pyglet/pyglet/compare/v2.0.10...v2.0.17) --- updated-dependencies: - dependency-name: pyglet dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- PongPong_Game/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PongPong_Game/requirements.txt b/PongPong_Game/requirements.txt index 555f25f9c27..7903d4bcf0a 100644 --- a/PongPong_Game/requirements.txt +++ b/PongPong_Game/requirements.txt @@ -1 +1 @@ -pyglet==2.0.10 +pyglet==2.0.17 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 55dfd6aa7ea..c837e2592c0 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -55,7 +55,7 @@ pydantic==2.8.2 openpyxl==3.1.2 pytesseract==0.3.13 requests-mock==1.12.1 -pyglet==2.0.10 +pyglet==2.0.17 urllib3==2.2.2 thirdai==0.9.11 google-api-python-client==2.142.0 From 09673af55e620054da3672b674734542af84c216 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 18:27:37 +0000 Subject: [PATCH 109/442] Bump rich from 13.7.1 to 13.8.0 Bumps [rich](https://github.com/Textualize/rich) from 13.7.1 to 13.8.0. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.7.1...v13.8.0) --- updated-dependencies: - dependency-name: rich dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 55dfd6aa7ea..edeb91e190f 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -103,7 +103,7 @@ googletrans==3.0.0 slab==1.7.0 psutil==6.0.0 mediapipe==0.10.14 -rich==13.7.1 +rich==13.8.0 httplib2==0.22.0 protobuf==5.27.1 colorama==0.4.6 From a0f6d01c13ed0f92fc27163c238f4435485f70ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 18:28:53 +0000 Subject: [PATCH 110/442] Bump opencv-python from 4.10.0.82 to 4.10.0.84 Bumps [opencv-python](https://github.com/opencv/opencv-python) from 4.10.0.82 to 4.10.0.84. - [Release notes](https://github.com/opencv/opencv-python/releases) - [Commits](https://github.com/opencv/opencv-python/commits) --- updated-dependencies: - dependency-name: opencv-python dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Hand-Motion-Detection/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt index 559078a79e0..3c3cfaa2592 100644 --- a/Hand-Motion-Detection/requirements.txt +++ b/Hand-Motion-Detection/requirements.txt @@ -1,3 +1,3 @@ numpy==2.1.0 -opencv_python==4.10.0.82 +opencv_python==4.10.0.84 mediapipe==0.10.14 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 387e76edc57..0365940427a 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -94,7 +94,7 @@ PyQRCode==1.2.1 freegames==2.5.3 pyperclip==1.8.2 newspaper==0.1.0.7 -opencv-python==4.10.0.82 +opencv-python==4.10.0.84 tensorflow==2.15.0.post1 pandas==2.2.2 pytest==8.3.2 From efe8369762a967ad2dc225b3b35b6b52f2f408ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 18:28:56 +0000 Subject: [PATCH 111/442] Bump twilio from 9.1.1 to 9.3.0 Bumps [twilio](https://github.com/twilio/twilio-python) from 9.1.1 to 9.3.0. - [Release notes](https://github.com/twilio/twilio-python/releases) - [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md) - [Commits](https://github.com/twilio/twilio-python/compare/9.1.1...9.3.0) --- updated-dependencies: - dependency-name: twilio dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 387e76edc57..5b6c32024b2 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -28,7 +28,7 @@ requests==2.32.3 quo==2023.5.1 PyPDF2==3.0.1 pyserial==3.5 -twilio==9.1.1 +twilio==9.3.0 tabula==1.0.5 nltk==3.9.1 Pillow==10.3.0 From 63107699b0800cea88ce0544a2fc73ca6c09f7a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:01:05 +0000 Subject: [PATCH 112/442] Bump solara from 1.32.2 to 1.39.0 Bumps [solara](https://github.com/widgetti/solara) from 1.32.2 to 1.39.0. - [Changelog](https://github.com/widgetti/solara/blob/master/CHANGELOG.md) - [Commits](https://github.com/widgetti/solara/compare/v1.32.2...v1.39.0) --- updated-dependencies: - dependency-name: solara dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- News_App/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/News_App/requirements.txt b/News_App/requirements.txt index 83fab2fbda5..edee84561c9 100644 --- a/News_App/requirements.txt +++ b/News_App/requirements.txt @@ -1,4 +1,4 @@ -solara == 1.32.2 +solara == 1.39.0 Flask gunicorn ==23.0.0 simple-websocket diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 8dcb0862489..bef6144b01f 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -74,7 +74,7 @@ xor-cipher==4.0.0 bird==0.1.2 mechanize==0.4.10 translate==3.6.1 -solara==1.32.2 +solara==1.39.0 pywhatkit==5.4 mutagen==1.47.0 Unidecode==1.3.8 From b849b52d7d414bcc0b4c9ab9ee57b1addfe940b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 18:36:08 +0000 Subject: [PATCH 113/442] Bump openai from 1.42.0 to 1.46.0 Bumps [openai](https://github.com/openai/openai-python) from 1.42.0 to 1.46.0. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.42.0...v1.46.0) --- updated-dependencies: - dependency-name: openai dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 8dcb0862489..6bb204521c1 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.42.0 +openai==1.46.0 background==0.2.1 pydantic==2.8.2 openpyxl==3.1.2 From 73fd13cce0a7cdbc4e4214fcdcbce0bc8705a2ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Sep 2024 18:31:54 +0000 Subject: [PATCH 114/442] Bump urllib3 from 2.2.2 to 2.2.3 Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.2.2 to 2.2.3. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/2.2.2...2.2.3) --- updated-dependencies: - dependency-name: urllib3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 10daa02dcd0..9b139c34adb 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -56,7 +56,7 @@ openpyxl==3.1.2 pytesseract==0.3.13 requests-mock==1.12.1 pyglet==2.0.17 -urllib3==2.2.2 +urllib3==2.2.3 thirdai==0.9.11 google-api-python-client==2.142.0 sound==0.1.0 From d1adab78ed6dd077804da33deed1e76fcee7147f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2024 18:36:16 +0000 Subject: [PATCH 115/442] Bump selenium from 4.23.1 to 4.25.0 Bumps [selenium](https://github.com/SeleniumHQ/Selenium) from 4.23.1 to 4.25.0. - [Release notes](https://github.com/SeleniumHQ/Selenium/releases) - [Commits](https://github.com/SeleniumHQ/Selenium/commits/selenium-4.25.0) --- updated-dependencies: - dependency-name: selenium dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 9b139c34adb..e3323730486 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -21,7 +21,7 @@ backend==0.2.4.1 win10toast==0.9 Counter==1.0.0 Flask==3.0.3 -selenium==4.23.1 +selenium==4.25.0 firebase-admin==6.5.0 ujson==5.10.0 requests==2.32.3 From dadb38665e027a4b8fff39937bbc17ffebfc2a1e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 18:57:16 +0000 Subject: [PATCH 116/442] Bump pillow from 10.3.0 to 10.4.0 Bumps [pillow](https://github.com/python-pillow/Pillow) from 10.3.0 to 10.4.0. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/10.3.0...10.4.0) --- updated-dependencies: - dependency-name: pillow dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- PDF/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PDF/requirements.txt b/PDF/requirements.txt index 2b5f7c99140..3829b46c264 100644 --- a/PDF/requirements.txt +++ b/PDF/requirements.txt @@ -1,2 +1,2 @@ -Pillow==10.3.0 +Pillow==10.4.0 fpdf==1.7.2 \ No newline at end of file diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index e3323730486..0ab385792e5 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -31,7 +31,7 @@ pyserial==3.5 twilio==9.3.0 tabula==1.0.5 nltk==3.9.1 -Pillow==10.3.0 +Pillow==10.4.0 SocksiPy-branch==1.01 xlrd==2.0.1 fpdf==1.7.2 From bcb6c702ca62bfd11bec8f5ed7db2438e95b938c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 18:58:22 +0000 Subject: [PATCH 117/442] Bump emoji from 2.12.1 to 2.13.2 Bumps [emoji](https://github.com/carpedm20/emoji) from 2.12.1 to 2.13.2. - [Release notes](https://github.com/carpedm20/emoji/releases) - [Changelog](https://github.com/carpedm20/emoji/blob/master/CHANGES.md) - [Commits](https://github.com/carpedm20/emoji/compare/v2.12.1...v2.13.2) --- updated-dependencies: - dependency-name: emoji dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 0ab385792e5..9d794271750 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -109,5 +109,5 @@ protobuf==5.27.1 colorama==0.4.6 plyer==2.1.0 Flask-Ask==0.9.8 -emoji==2.12.1 +emoji==2.13.2 PyAutoGUI==0.9.54 From c2c1aad669f42ee637efe89aea3bcc104b89d9ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 18:58:25 +0000 Subject: [PATCH 118/442] Bump watchdog from 4.0.2 to 5.0.2 Bumps [watchdog](https://github.com/gorakhargosh/watchdog) from 4.0.2 to 5.0.2. - [Release notes](https://github.com/gorakhargosh/watchdog/releases) - [Changelog](https://github.com/gorakhargosh/watchdog/blob/master/changelog.rst) - [Commits](https://github.com/gorakhargosh/watchdog/compare/v4.0.2...v5.0.2) --- updated-dependencies: - dependency-name: watchdog dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 0ab385792e5..165197e40b6 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -13,7 +13,7 @@ pong==1.5 beautifulsoup4==4.12.3 dictator==0.3.1 caller==0.0.2 -watchdog==4.0.2 +watchdog==5.0.2 PyQt5==5.15.11 numpy==2.1.0 fileinfo==0.3.3 From 38cded34c356e7f4a1942643e4aec155996286be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 19:01:08 +0000 Subject: [PATCH 119/442] Bump openai from 1.46.0 to 1.50.1 Bumps [openai](https://github.com/openai/openai-python) from 1.46.0 to 1.50.1. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.46.0...v1.50.1) --- updated-dependencies: - dependency-name: openai dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 0bc092af56f..dd143fe634e 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.46.0 +openai==1.50.1 background==0.2.1 pydantic==2.8.2 openpyxl==3.1.2 From 61aa280ab110cf1f0d1229565155cda973195fab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 19:01:12 +0000 Subject: [PATCH 120/442] Bump rich from 13.8.0 to 13.8.1 Bumps [rich](https://github.com/Textualize/rich) from 13.8.0 to 13.8.1. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.8.0...v13.8.1) --- updated-dependencies: - dependency-name: rich dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 0bc092af56f..6a5176d97eb 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -103,7 +103,7 @@ googletrans==3.0.0 slab==1.7.0 psutil==6.0.0 mediapipe==0.10.14 -rich==13.8.0 +rich==13.8.1 httplib2==0.22.0 protobuf==5.27.1 colorama==0.4.6 From 322a3b79b68c7f6c0559d7e3281c8f2e80d1ab75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 18:55:33 +0000 Subject: [PATCH 121/442] Bump openai from 1.50.1 to 1.50.2 Bumps [openai](https://github.com/openai/openai-python) from 1.50.1 to 1.50.2. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.50.1...v1.50.2) --- updated-dependencies: - dependency-name: openai dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 8693d28ddf4..7f62c886caf 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.50.1 +openai==1.50.2 background==0.2.1 pydantic==2.8.2 openpyxl==3.1.2 From 3ad7706333fcfc26f0ec36aa9f5f1ad9cc089ba6 Mon Sep 17 00:00:00 2001 From: sumankumari13 <68442008+sumankumari13@users.noreply.github.com> Date: Tue, 1 Oct 2024 01:53:38 +0530 Subject: [PATCH 122/442] Create hamming-numbers Created python code for hamming numbers --- hamming-numbers | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 hamming-numbers diff --git a/hamming-numbers b/hamming-numbers new file mode 100644 index 00000000000..c9f81deb7f6 --- /dev/null +++ b/hamming-numbers @@ -0,0 +1,51 @@ +""" +A Hamming number is a positive integer of the form 2^i*3^j*5^k, for some +non-negative integers i, j, and k. They are often referred to as regular numbers. +The first 20 Hamming numbers are: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, and 36 +""" + + +def hamming(n_element: int) -> list: + """ + This function creates an ordered list of n length as requested, and afterwards + returns the last value of the list. It must be given a positive integer. + + :param n_element: The number of elements on the list + :return: The nth element of the list + + >>> hamming(5) + [1, 2, 3, 4, 5] + >>> hamming(10) + [1, 2, 3, 4, 5, 6, 8, 9, 10, 12] + >>> hamming(15) + [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24] + """ + n_element = int(n_element) + if n_element < 1: + my_error = ValueError("a should be a positive number") + raise my_error + + hamming_list = [1] + i, j, k = (0, 0, 0) + index = 1 + while index < n_element: + while hamming_list[i] * 2 <= hamming_list[-1]: + i += 1 + while hamming_list[j] * 3 <= hamming_list[-1]: + j += 1 + while hamming_list[k] * 5 <= hamming_list[-1]: + k += 1 + hamming_list.append( + min(hamming_list[i] * 2, hamming_list[j] * 3, hamming_list[k] * 5) + ) + index += 1 + return hamming_list + + +if __name__ == "__main__": + n = input("Enter the last number (nth term) of the Hamming Number Series: ") + print("Formula of Hamming Number Series => 2^i * 3^j * 5^k") + hamming_numbers = hamming(int(n)) + print("-----------------------------------------------------") + print(f"The list with nth numbers is: {hamming_numbers}") + print("-----------------------------------------------------") From bf6ce19706523cab239dc77e5cc0e9c97e40e941 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 18:26:55 +0000 Subject: [PATCH 123/442] Bump pygame from 2.6.0 to 2.6.1 Bumps [pygame](https://github.com/pygame/pygame) from 2.6.0 to 2.6.1. - [Release notes](https://github.com/pygame/pygame/releases) - [Commits](https://github.com/pygame/pygame/compare/2.6.0...2.6.1) --- updated-dependencies: - dependency-name: pygame dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- text_to_audio/requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 7f62c886caf..e06c4d89bc3 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -61,7 +61,7 @@ thirdai==0.9.11 google-api-python-client==2.142.0 sound==0.1.0 xlwt==1.3.0 -pygame==2.6.0 +pygame==2.6.1 speechtotext==0.0.3 wikipedia==1.4.0 tqdm==4.66.5 diff --git a/text_to_audio/requirements.txt b/text_to_audio/requirements.txt index a91c978b7d4..a95f73ea805 100644 --- a/text_to_audio/requirements.txt +++ b/text_to_audio/requirements.txt @@ -1,2 +1,2 @@ gTTS==2.5.3 -pygame==2.6.0 +pygame==2.6.1 From c69d87e51f9d611a4be33ed773788a99bd874482 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 18:26:58 +0000 Subject: [PATCH 124/442] Bump pyttsx3 from 2.91 to 2.98 Bumps [pyttsx3](https://github.com/nateshmbhat/pyttsx3) from 2.91 to 2.98. - [Release notes](https://github.com/nateshmbhat/pyttsx3/releases) - [Commits](https://github.com/nateshmbhat/pyttsx3/compare/v2.91...v2.98) --- updated-dependencies: - dependency-name: pyttsx3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 7f62c886caf..cb4e2e5e034 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -44,7 +44,7 @@ oauth2client==4.1.3 keras==3.5.0 pymongo==4.7.3 playsound==1.3.0 -pyttsx3==2.91 +pyttsx3==2.98 auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 From 46b8bcc9be171a2f3cdb2fb25d836303f7048608 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Oct 2024 18:49:26 +0000 Subject: [PATCH 125/442] Bump qrcode from 7.4.2 to 8.0 Bumps [qrcode](https://github.com/lincolnloop/python-qrcode) from 7.4.2 to 8.0. - [Changelog](https://github.com/lincolnloop/python-qrcode/blob/main/CHANGES.rst) - [Commits](https://github.com/lincolnloop/python-qrcode/compare/v7.4.2...v8.0) --- updated-dependencies: - dependency-name: qrcode dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 6dbbf48cdd2..523c197fece 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -98,7 +98,7 @@ opencv-python==4.10.0.84 tensorflow==2.15.0.post1 pandas==2.2.2 pytest==8.3.2 -qrcode==7.4.2 +qrcode==8.0 googletrans==3.0.0 slab==1.7.0 psutil==6.0.0 From 46c3183c50b52f9ffb65a1d682229cd35810cc4a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Oct 2024 18:49:29 +0000 Subject: [PATCH 126/442] Bump rich from 13.8.1 to 13.9.1 Bumps [rich](https://github.com/Textualize/rich) from 13.8.1 to 13.9.1. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.8.1...v13.9.1) --- updated-dependencies: - dependency-name: rich dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 6dbbf48cdd2..0a4b078f32f 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -103,7 +103,7 @@ googletrans==3.0.0 slab==1.7.0 psutil==6.0.0 mediapipe==0.10.14 -rich==13.8.1 +rich==13.9.1 httplib2==0.22.0 protobuf==5.27.1 colorama==0.4.6 From 3d7deb73563440c603363cac269133fc9c4fd9b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 3 Oct 2024 19:03:54 +0000 Subject: [PATCH 127/442] Bump pandas from 2.2.2 to 2.2.3 Bumps [pandas](https://github.com/pandas-dev/pandas) from 2.2.2 to 2.2.3. - [Release notes](https://github.com/pandas-dev/pandas/releases) - [Commits](https://github.com/pandas-dev/pandas/compare/v2.2.2...v2.2.3) --- updated-dependencies: - dependency-name: pandas dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 669d30634d6..e05fce28be2 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -96,7 +96,7 @@ pyperclip==1.8.2 newspaper==0.1.0.7 opencv-python==4.10.0.84 tensorflow==2.15.0.post1 -pandas==2.2.2 +pandas==2.2.3 pytest==8.3.2 qrcode==8.0 googletrans==3.0.0 From a471b19798c18e386a92c9a15b1df4642dae8d25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 18:14:48 +0000 Subject: [PATCH 128/442] Bump yfinance from 0.2.43 to 0.2.44 Bumps [yfinance](https://github.com/ranaroussi/yfinance) from 0.2.43 to 0.2.44. - [Release notes](https://github.com/ranaroussi/yfinance/releases) - [Changelog](https://github.com/ranaroussi/yfinance/blob/main/CHANGELOG.rst) - [Commits](https://github.com/ranaroussi/yfinance/compare/0.2.43...0.2.44) --- updated-dependencies: - dependency-name: yfinance dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index e05fce28be2..3f72fc38bb5 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -66,7 +66,7 @@ speechtotext==0.0.3 wikipedia==1.4.0 tqdm==4.66.5 Menu==3.2.2 -yfinance==0.2.43 +yfinance==0.2.44 tweepy==4.14.0 tkcalendar==1.6.1 pytube==15.0.0 From 4367482c7f901618c6c0b761a15e06169cbbe615 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 18:14:52 +0000 Subject: [PATCH 129/442] Bump watchdog from 5.0.2 to 5.0.3 Bumps [watchdog](https://github.com/gorakhargosh/watchdog) from 5.0.2 to 5.0.3. - [Release notes](https://github.com/gorakhargosh/watchdog/releases) - [Changelog](https://github.com/gorakhargosh/watchdog/blob/master/changelog.rst) - [Commits](https://github.com/gorakhargosh/watchdog/compare/v5.0.2...v5.0.3) --- updated-dependencies: - dependency-name: watchdog dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index e05fce28be2..636d9d7c467 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -13,7 +13,7 @@ pong==1.5 beautifulsoup4==4.12.3 dictator==0.3.1 caller==0.0.2 -watchdog==5.0.2 +watchdog==5.0.3 PyQt5==5.15.11 numpy==2.1.0 fileinfo==0.3.3 From 9acbda4479a33c9ca3a11480da155ca07bf0cbb8 Mon Sep 17 00:00:00 2001 From: Soumyaditya Batabyal Date: Sat, 5 Oct 2024 14:59:25 +0530 Subject: [PATCH 130/442] Create index.py --- index.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 index.py diff --git a/index.py b/index.py new file mode 100644 index 00000000000..b89d747b62d --- /dev/null +++ b/index.py @@ -0,0 +1,16 @@ +num = 11 +#Negative numbers, 0 and 1 are not primes +if num > 1: + + # Iterate from 2 to n // 2 + for i in range(2, (num//2)+1): + + # If num is divisible by any number between + #2 and n / 2, it is not prime + if (num % i) == 0: + print(num, "is not a prime number") + break + else: + print(num, "is a prime number") +else: + print(num, "is not a prime number") From c760e555de37e30c80459258d308bb3db24578ef Mon Sep 17 00:00:00 2001 From: Nish2403 <54502741+Nish2403@users.noreply.github.com> Date: Sat, 5 Oct 2024 16:16:49 +0530 Subject: [PATCH 131/442] Update simple_calculator.py *Made the code clean. * Added lines for better understanding. * Code will run very fast, --- simple_calculator/simple_calculator.py | 98 ++++++++++++++------------ 1 file changed, 53 insertions(+), 45 deletions(-) diff --git a/simple_calculator/simple_calculator.py b/simple_calculator/simple_calculator.py index ec8a7c11b26..b84588896c4 100644 --- a/simple_calculator/simple_calculator.py +++ b/simple_calculator/simple_calculator.py @@ -2,48 +2,56 @@ def add(x, y): return x + y - def subtract(x, y): - return x - y - - def multiply(x, y): - return x * y - - def divide(x, y): - return x / y - - # Display the options to the user - print("Select operation:") - print("1. Add") - print("2. Subtract") - print("3. Multiply") - print("4. Divide") - - while True: - # Take input from the user - choice = input("Enter choice (1/2/3/4): ") - - # Check if the choice is one of the four options - if choice in ('1', '2', '3', '4'): - try: - num1 = float(input("Enter first number: ")) - num2 = float(input("Enter second number: ")) - except ValueError: - print("Invalid input. Please enter a number.") - continue - - if choice == '1': - print(f"{num1} + {num2} = {add(num1, num2)}") - elif choice == '2': - print(f"{num1} - {num2} = {subtract(num1, num2)}") - elif choice == '3': - print(f"{num1} * {num2} = {multiply(num1, num2)}") - elif choice == '4': - print(f"{num1} / {num2} = {divide(num1, num2)}") - - # Check if the user wants another calculation - next_calculation = input("Do you want to perform another calculation? (yes/no): ") - if next_calculation.lower() != 'yes': - break - else: - print("Invalid input") - \ No newline at end of file +def subtract(x, y): + return x - y + +def multiply(x, y): + return x * y + +def divide(x, y): + # Prevent division by zero + if y == 0: + return "Error: Division by zero is not allowed" + return x / y + +# Display the options to the user +def display_menu(): + print("\nSelect operation:") + print("1. Add") + print("2. Subtract") + print("3. Multiply") + print("4. Divide") + +# Main program loop +while True: + display_menu() + + # Take input from the user + choice = input("Enter choice (1/2/3/4): ") + + # Check if the choice is valid + if choice in ('1', '2', '3', '4'): + try: + num1 = float(input("Enter first number: ")) + num2 = float(input("Enter second number: ")) + except ValueError: + print("Invalid input. Please enter numeric values.") + continue + + # Perform the chosen operation + if choice == '1': + print(f"{num1} + {num2} = {add(num1, num2)}") + elif choice == '2': + print(f"{num1} - {num2} = {subtract(num1, num2)}") + elif choice == '3': + print(f"{num1} * {num2} = {multiply(num1, num2)}") + elif choice == '4': + print(f"{num1} / {num2} = {divide(num1, num2)}") + + # Check if the user wants another calculation + next_calculation = input("Do you want to perform another calculation? (yes/no): ").lower() + if next_calculation != 'yes': + print("Exiting the calculator.") + break + else: + print("Invalid input. Please select a valid operation.") From 11248167fcacb2f50e9a3255c5ef71f69e07b913 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 18:59:11 +0000 Subject: [PATCH 132/442] Bump twilio from 9.3.0 to 9.3.3 Bumps [twilio](https://github.com/twilio/twilio-python) from 9.3.0 to 9.3.3. - [Release notes](https://github.com/twilio/twilio-python/releases) - [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md) - [Commits](https://github.com/twilio/twilio-python/compare/9.3.0...9.3.3) --- updated-dependencies: - dependency-name: twilio dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index ab51fb00740..cb5c1756dc8 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -28,7 +28,7 @@ requests==2.32.3 quo==2023.5.1 PyPDF2==3.0.1 pyserial==3.5 -twilio==9.3.0 +twilio==9.3.3 tabula==1.0.5 nltk==3.9.1 Pillow==10.4.0 From 9ded90327e77bfbc8426ee9a8cc174653611c538 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 18:59:15 +0000 Subject: [PATCH 133/442] Bump keras from 3.5.0 to 3.6.0 Bumps [keras](https://github.com/keras-team/keras) from 3.5.0 to 3.6.0. - [Release notes](https://github.com/keras-team/keras/releases) - [Commits](https://github.com/keras-team/keras/compare/v3.5.0...v3.6.0) --- updated-dependencies: - dependency-name: keras dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index ab51fb00740..c62cd323b91 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -41,7 +41,7 @@ tornado==6.4.1 obs==0.0.0 todo==0.1 oauth2client==4.1.3 -keras==3.5.0 +keras==3.6.0 pymongo==4.7.3 playsound==1.3.0 pyttsx3==2.98 From d66f9be69b2a3f91eaa504d3ae820b28c4356f2f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 18:21:21 +0000 Subject: [PATCH 134/442] Bump pydantic from 2.8.2 to 2.9.2 Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.8.2 to 2.9.2. - [Release notes](https://github.com/pydantic/pydantic/releases) - [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md) - [Commits](https://github.com/pydantic/pydantic/compare/v2.8.2...v2.9.2) --- updated-dependencies: - dependency-name: pydantic dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 11a003086ef..4a6e4230b2b 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -51,7 +51,7 @@ pywifi==1.1.12 patterns==0.3 openai==1.50.2 background==0.2.1 -pydantic==2.8.2 +pydantic==2.9.2 openpyxl==3.1.2 pytesseract==0.3.13 requests-mock==1.12.1 From 8695914f47af5a0029626e0b939e8061e2fb8180 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Oct 2024 19:07:31 +0000 Subject: [PATCH 135/442] Bump aiohttp from 3.10.5 to 3.10.9 Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.10.5 to 3.10.9. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.10.5...v3.10.9) --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- async_downloader/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/async_downloader/requirements.txt b/async_downloader/requirements.txt index 882b7d9efab..05bf5329b0e 100644 --- a/async_downloader/requirements.txt +++ b/async_downloader/requirements.txt @@ -1 +1 @@ -aiohttp==3.10.5 +aiohttp==3.10.9 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4a6e4230b2b..106973c450c 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -1,5 +1,5 @@ pafy==0.5.5 -aiohttp==3.10.5 +aiohttp==3.10.9 fuzzywuzzy==0.18.0 hupper==1.12.1 seaborn==0.13.2 From 7f3ec867ea6f5aedb246628a2f0a658f6d351614 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:25:55 +0000 Subject: [PATCH 136/442] Bump django from 5.1 to 5.1.2 Bumps [django](https://github.com/django/django) from 5.1 to 5.1.2. - [Commits](https://github.com/django/django/compare/5.1...5.1.2) --- updated-dependencies: - dependency-name: django dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 106973c450c..1751c2f3cf0 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -84,7 +84,7 @@ gTTS==2.5.3 ccxt==4.3.87 fitz==0.0.1.dev2 fastapi==0.109.0 -Django==5.1 +Django==5.1.2 docx==0.2.4 matplotlib==3.9.2 pyshorteners==1.0.1 From d736673459ec74c23e92692a9067ce3c188bab3c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Oct 2024 18:25:36 +0000 Subject: [PATCH 137/442] Bump xor-cipher from 4.0.0 to 5.0.0 Bumps [xor-cipher](https://github.com/xor-cipher/xor-cipher) from 4.0.0 to 5.0.0. - [Release notes](https://github.com/xor-cipher/xor-cipher/releases) - [Changelog](https://github.com/xor-cipher/xor-cipher/blob/main/CHANGELOG.md) - [Commits](https://github.com/xor-cipher/xor-cipher/compare/v4.0.0...v5.0.0) --- updated-dependencies: - dependency-name: xor-cipher dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 1751c2f3cf0..87db4be52cc 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -70,7 +70,7 @@ yfinance==0.2.44 tweepy==4.14.0 tkcalendar==1.6.1 pytube==15.0.0 -xor-cipher==4.0.0 +xor-cipher==5.0.0 bird==0.1.2 mechanize==0.4.10 translate==3.6.1 From 5b6ee2f63e1ad1610eb31b07e200b1b206ceeaba Mon Sep 17 00:00:00 2001 From: Xceptions Date: Mon, 14 Oct 2024 15:52:40 +0100 Subject: [PATCH 138/442] finished up the backend --- QuestionAnswerVirtualAssistant/backend.py | 217 ++++++++++++++++++ .../requirements.txt | 2 + 2 files changed, 219 insertions(+) create mode 100644 QuestionAnswerVirtualAssistant/backend.py create mode 100644 QuestionAnswerVirtualAssistant/requirements.txt diff --git a/QuestionAnswerVirtualAssistant/backend.py b/QuestionAnswerVirtualAssistant/backend.py new file mode 100644 index 00000000000..d7b9ca2dd9a --- /dev/null +++ b/QuestionAnswerVirtualAssistant/backend.py @@ -0,0 +1,217 @@ +class QuesAnsVirtualAssistant: + """ + Used for question-answering + + We want a table like this + id | Question | Answer + + Programmatically represented as + { + id: {question: ..., answer: ...} + } + """ + pass + + + + + + + + + +import sqlite3 +import json +import pandas as pd +import sklearn +from sklearn.feature_extraction.text import TfidfVectorizer + +class QuestionAnswerVirtualAssistant: + """ + Used for automatic question-answering + + It works by building a reverse index store that maps + words to an id. To find the indexed questions that contain + a certain the words in the user question, we then take an + intersection of the ids, ranks the questions to pick the best fit, + then select the answer that maps to that question + """ + + def __init__(self): + """ + Returns - None + Input - None + ---------- + - Initialize database. we use sqlite3 + - Check if the tables exist, if not create them + - maintain a class level access to the database + connection object + """ + self.conn = sqlite3.connect("virtualassistant.sqlite3", autocommit=True) + cur = self.conn.cursor() + res = cur.execute("SELECT name FROM sqlite_master WHERE name='IdToQuesAns'") + tables_exist = res.fetchone() + + if not tables_exist: + self.conn.execute("CREATE TABLE IdToQuesAns(id INTEGER PRIMARY KEY, question TEXT, answer TEXT)") + self.conn.execute('CREATE TABLE WordToId (name TEXT, value TEXT)') + cur.execute("INSERT INTO WordToId VALUES (?, ?)", ("index", "{}",)) + + def index_question_answer(self, question, answer): + """ + Returns - string + Input - str: a string of words called question + ---------- + Indexes the question and answer. It does this by performing two + operations - add the question and answer to the IdToQuesAns, then + adds the words in the question to WordToId + - takes in the question and answer (str) + - passes the question and answer to a method to add them + to IdToQuesAns + - retrieves the id of the inserted ques-answer + - uses the id to call the method that adds the words of + the question to the reverse index WordToId if the word has not + already been indexed + """ + row_id = self._add_to_IdToQuesAns(question.lower(), answer.lower()) + cur = self.conn.cursor() + reverse_idx = cur.execute("SELECT value FROM WordToId WHERE name='index'").fetchone()[0] + reverse_idx = json.loads(reverse_idx) + question = question.split() + for word in question: + if word not in reverse_idx: + reverse_idx[word] = [row_id] + else: + if row_id not in reverse_idx[word]: + reverse_idx[word].append(row_id) + reverse_idx = json.dumps(reverse_idx) + cur = self.conn.cursor() + result = cur.execute("UPDATE WordToId SET value = (?) WHERE name='index'", (reverse_idx,)) + return("index successful") + + def _add_to_IdToQuesAns(self, question, answer): + """ + Returns - int: the id of the inserted document + Input - str: a string of words called `document` + --------- + - use the class-level connection object to insert the document + into the db + - retrieve and return the row id of the inserted document + """ + cur = self.conn.cursor() + res = cur.execute("INSERT INTO IdToQuesAns (question, answer) VALUES (?, ?)", (question, answer,)) + return res.lastrowid + + def find_questions(self, user_input): + """ + Returns - : the return value of the _find_questions_with_idx method + Input - str: a string of words called `user_input`, expected to be a question + --------- + - retrieve the reverse index + - use the words contained in the user input to find all the idxs + that contain the word + - use idxs to call the _find_questions_with_idx method + - return the result of the called method + """ + cur = self.conn.cursor() + reverse_idx = cur.execute("SELECT value FROM WordToId WHERE name='index'").fetchone()[0] + reverse_idx = json.loads(reverse_idx) + user_input = user_input.split(" ") + all_docs_with_user_input = [] + for term in user_input: + if term in reverse_idx: + all_docs_with_user_input.append(reverse_idx[term]) + + if not all_docs_with_user_input: # the user_input does not exist + return [] + + common_idx_of_docs = set(all_docs_with_user_input[0]) + for idx in all_docs_with_user_input[1:]: + common_idx_of_docs.intersection_update(idx) + + if not common_idx_of_docs: # the user_input does not exist + return [] + + return self._find_questions_with_idx(common_idx_of_docs) + + def _find_questions_with_idx(self, idxs): + """ + Returns - list[str]: the list of questions with the idxs + Input - list of idxs + --------- + - use the class-level connection object to retrieve the questions that + have the idx in the input list of idxs. + - retrieve and return these questions as a list + """ + idxs = list(idxs) + cur = self.conn.cursor() + sql="SELECT id, question, answer FROM IdToQuesAns WHERE id in ({seq})".format( + seq=','.join(['?']*len(idxs)) + ) + result = cur.execute(sql, idxs).fetchall() + return(result) + + def find_most_matched_question(self, user_input, corpus): + """ + Returns - list[str]: the list of [(score, most_matching_question)] + Input - user_input, and list of matching questions called corpus + --------- + - use the tfidf score to rank the questions and pick the most matching + question + """ + vectorizer = TfidfVectorizer() + tfidf_scores = vectorizer.fit_transform(corpus) + tfidf_array = pd.DataFrame(tfidf_scores.toarray(),columns=vectorizer.get_feature_names_out()) + tfidf_dict = tfidf_array.to_dict() + + user_input = user_input.split(" ") + result = [] + for idx in range(len(corpus)): + result.append([0, corpus[idx]]) + + for term in user_input: + if term in tfidf_dict: + for idx in range(len(result)): + result[idx][0] += tfidf_dict[term][idx] + return result[0] + + def provide_answer(self, user_input): + """ + Returns - str: the answer to the user_input + Input - str: user_input + --------- + - use the user_input to get the list of matching questions + - create a corpus which is a list of all matching questions + - create a question_map that maps questions to their respective answers + - use the user_input and corpus to find the most matching question + - return the answer that matches that question from the question_map + """ + matching_questions = self.find_questions(user_input) + corpus = [item[1] for item in matching_questions] + question_map = {question:answer for (id, question, answer) in matching_questions} + score, most_matching_question = self.find_most_matched_question(user_input, corpus) + return question_map[most_matching_question] + + +if __name__ == "__main__": + va = QuestionAnswerVirtualAssistant() + va.index_question_answer( + "What are the different types of competitions available on Kaggle", + "Types of Competitions Kaggle Competitions are designed to provide challenges for competitors" + ) + print( + va.index_question_answer( + "How to form, manage, and disband teams in a competition", + "Everyone that competes in a Competition does so as a team. A team is a group of one or more users" + ) + ) + va.index_question_answer( + "What is Data Leakage", + "Data Leakage is the presence of unexpected additional information in the training data" + ) + va.index_question_answer( + "How does Kaggle handle cheating", + "Cheating is not taken lightly on Kaggle. We monitor our compliance account" + ) + print(va.provide_answer("state Kaggle cheating policy")) + print(va.provide_answer("Tell me what is data leakage")) \ No newline at end of file diff --git a/QuestionAnswerVirtualAssistant/requirements.txt b/QuestionAnswerVirtualAssistant/requirements.txt new file mode 100644 index 00000000000..fb4d28890ad --- /dev/null +++ b/QuestionAnswerVirtualAssistant/requirements.txt @@ -0,0 +1,2 @@ +pandas +scikit-learn \ No newline at end of file From 75abdc437ced6900230bad5b615c465dea43f293 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Mon, 14 Oct 2024 16:09:28 +0100 Subject: [PATCH 139/442] finished up the frontend, removed wrongly left code in the backend --- QuestionAnswerVirtualAssistant/frontend.py | 41 ++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 QuestionAnswerVirtualAssistant/frontend.py diff --git a/QuestionAnswerVirtualAssistant/frontend.py b/QuestionAnswerVirtualAssistant/frontend.py new file mode 100644 index 00000000000..bc99cfebd36 --- /dev/null +++ b/QuestionAnswerVirtualAssistant/frontend.py @@ -0,0 +1,41 @@ +from tkinter import * +from tkinter import messagebox +import backend + + +def index_question_answer(): + # for this, we are separating question and answer by "_" + question_answer = index_question_answer_entry.get() + question, answer = question_answer.split("_") + print(question) + print(answer) + va = backend.QuestionAnswerVirtualAssistant() + print(va.index_question_answer(question, answer)) + +def provide_answer(): + term = provide_answer_entry.get() + va = backend.QuestionAnswerVirtualAssistant() + print(va.provide_answer(term)) + +if __name__ == "__main__": + root = Tk() + root.title("Knowledge base") + root.geometry('300x300') + + index_question_answer_label = Label(root, text="Add question:") + index_question_answer_label.pack() + index_question_answer_entry = Entry(root) + index_question_answer_entry.pack() + + index_question_answer_button = Button(root, text="add", command=index_question_answer) + index_question_answer_button.pack() + + provide_answer_label = Label(root, text="User Input:") + provide_answer_label.pack() + provide_answer_entry = Entry(root) + provide_answer_entry.pack() + + search_term_button = Button(root, text="ask", command=provide_answer) + search_term_button.pack() + + root.mainloop() \ No newline at end of file From 83b0a7fbfe0194aacff1396b611b630ed7cb6330 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Mon, 14 Oct 2024 16:11:21 +0100 Subject: [PATCH 140/442] removed wrongly left code in backend --- QuestionAnswerVirtualAssistant/backend.py | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/QuestionAnswerVirtualAssistant/backend.py b/QuestionAnswerVirtualAssistant/backend.py index d7b9ca2dd9a..3d21899a4fc 100644 --- a/QuestionAnswerVirtualAssistant/backend.py +++ b/QuestionAnswerVirtualAssistant/backend.py @@ -1,25 +1,3 @@ -class QuesAnsVirtualAssistant: - """ - Used for question-answering - - We want a table like this - id | Question | Answer - - Programmatically represented as - { - id: {question: ..., answer: ...} - } - """ - pass - - - - - - - - - import sqlite3 import json import pandas as pd From d532e27afda90f9f0db6da9ff414c5423685b582 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 18:32:36 +0000 Subject: [PATCH 141/442] Bump pymongo from 4.7.3 to 4.10.1 Bumps [pymongo](https://github.com/mongodb/mongo-python-driver) from 4.7.3 to 4.10.1. - [Release notes](https://github.com/mongodb/mongo-python-driver/releases) - [Changelog](https://github.com/mongodb/mongo-python-driver/blob/master/doc/changelog.rst) - [Commits](https://github.com/mongodb/mongo-python-driver/compare/4.7.3...4.10.1) --- updated-dependencies: - dependency-name: pymongo dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 87db4be52cc..2bb16ce8cf2 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -42,7 +42,7 @@ obs==0.0.0 todo==0.1 oauth2client==4.1.3 keras==3.6.0 -pymongo==4.7.3 +pymongo==4.10.1 playsound==1.3.0 pyttsx3==2.98 auto-mix-prep==0.2.0 From 156018fd6c49438fa575fcc2d95ffd76d1cf3a5f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 18:14:15 +0000 Subject: [PATCH 142/442] Bump openai from 1.50.2 to 1.51.2 Bumps [openai](https://github.com/openai/openai-python) from 1.50.2 to 1.51.2. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.50.2...v1.51.2) --- updated-dependencies: - dependency-name: openai dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 2bb16ce8cf2..beb9b1419ba 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.50.2 +openai==1.51.2 background==0.2.1 pydantic==2.9.2 openpyxl==3.1.2 From 9cb681db8410bb64ff9d1fa698440fbae520377b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Oct 2024 18:28:59 +0000 Subject: [PATCH 143/442] Bump google-api-python-client from 2.142.0 to 2.149.0 Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.142.0 to 2.149.0. - [Release notes](https://github.com/googleapis/google-api-python-client/releases) - [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.142.0...v2.149.0) --- updated-dependencies: - dependency-name: google-api-python-client dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index beb9b1419ba..4ddfb5297de 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -58,7 +58,7 @@ requests-mock==1.12.1 pyglet==2.0.17 urllib3==2.2.3 thirdai==0.9.11 -google-api-python-client==2.142.0 +google-api-python-client==2.149.0 sound==0.1.0 xlwt==1.3.0 pygame==2.6.1 From 2d5d7609e5b42358ed2820b57659f772ae028123 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2024 18:30:53 +0000 Subject: [PATCH 144/442] Bump pytest from 8.3.2 to 8.3.3 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.2 to 8.3.3. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.3.2...8.3.3) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4ddfb5297de..5fc2f217262 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -97,7 +97,7 @@ newspaper==0.1.0.7 opencv-python==4.10.0.84 tensorflow==2.15.0.post1 pandas==2.2.3 -pytest==8.3.2 +pytest==8.3.3 qrcode==8.0 googletrans==3.0.0 slab==1.7.0 From 275c1a89a852dc8c955c8738299c711c883fa21f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2024 18:30:56 +0000 Subject: [PATCH 145/442] Bump solara from 1.39.0 to 1.40.0 Bumps [solara](https://github.com/widgetti/solara) from 1.39.0 to 1.40.0. - [Changelog](https://github.com/widgetti/solara/blob/master/CHANGELOG.md) - [Commits](https://github.com/widgetti/solara/compare/v1.39.0...v1.40.0) --- updated-dependencies: - dependency-name: solara dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- News_App/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/News_App/requirements.txt b/News_App/requirements.txt index edee84561c9..9e40a95b321 100644 --- a/News_App/requirements.txt +++ b/News_App/requirements.txt @@ -1,4 +1,4 @@ -solara == 1.39.0 +solara == 1.40.0 Flask gunicorn ==23.0.0 simple-websocket diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4ddfb5297de..d3d9b7c119f 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -74,7 +74,7 @@ xor-cipher==5.0.0 bird==0.1.2 mechanize==0.4.10 translate==3.6.1 -solara==1.39.0 +solara==1.40.0 pywhatkit==5.4 mutagen==1.47.0 Unidecode==1.3.8 From 2f765ae9e41ce65197f00274a915925620e8102e Mon Sep 17 00:00:00 2001 From: Xceptions Date: Fri, 18 Oct 2024 23:59:05 +0100 Subject: [PATCH 146/442] added word dictionary --- Word_Dictionary/dictionary.py | 62 +++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 Word_Dictionary/dictionary.py diff --git a/Word_Dictionary/dictionary.py b/Word_Dictionary/dictionary.py new file mode 100644 index 00000000000..39f15eb47ec --- /dev/null +++ b/Word_Dictionary/dictionary.py @@ -0,0 +1,62 @@ +from typing import Dict, List + + +class Dictionary: + + def __init__(self): + self.node = {} + + def add_word(self, word: str) -> None: + node = self.node + for ltr in word: + if ltr not in node: + node[ltr] = {} + node = node[ltr] + node["is_word"] = True + + def word_exists(self, word: str) -> bool: + node = self.node + for ltr in word: + if ltr not in node: + return False + node = node[ltr] + return "is_word" in node + + def list_words_from_node(self, node: Dict, spelling: str) -> None: + if "is_word" in node: + self.words_list.append(spelling) + return + for ltr in node: + self.list_words_from_node(node[ltr], spelling+ltr) + + def print_all_words_in_dictionary(self) -> List[str]: + node = self.node + self.words_list = [] + self.list_words_from_node(node, "") + return self.words_list + + def suggest_words_starting_with(self, prefix: str) -> List[str]: + node = self.node + for ltr in prefix: + if ltr not in node: + return False + node = node[ltr] + self.words_list = [] + self.list_words_from_node(node, prefix) + return self.words_list + + + + +# Your Dictionary object will be instantiated and called as such: +obj = Dictionary() +obj.add_word("word") +obj.add_word("woke") +obj.add_word("happy") + +param_2 = obj.word_exists("word") +param_3 = obj.suggest_words_starting_with("wo") + +print(param_2) +print(param_3) +print(obj.print_all_words_in_dictionary()) \ No newline at end of file From 59115635b64d0fb8debff73ff18c9a6fbc115565 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 18:36:46 +0000 Subject: [PATCH 147/442] Bump twilio from 9.3.3 to 9.3.4 Bumps [twilio](https://github.com/twilio/twilio-python) from 9.3.3 to 9.3.4. - [Release notes](https://github.com/twilio/twilio-python/releases) - [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md) - [Commits](https://github.com/twilio/twilio-python/compare/9.3.3...9.3.4) --- updated-dependencies: - dependency-name: twilio dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index cd5be1218b2..e894bc4d81d 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -28,7 +28,7 @@ requests==2.32.3 quo==2023.5.1 PyPDF2==3.0.1 pyserial==3.5 -twilio==9.3.3 +twilio==9.3.4 tabula==1.0.5 nltk==3.9.1 Pillow==10.4.0 From 254dcd9e95f4521787f83bf15dbc151be15387d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2024 18:07:24 +0000 Subject: [PATCH 148/442] Bump pillow from 10.4.0 to 11.0.0 Bumps [pillow](https://github.com/python-pillow/Pillow) from 10.4.0 to 11.0.0. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/10.4.0...11.0.0) --- updated-dependencies: - dependency-name: pillow dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- PDF/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PDF/requirements.txt b/PDF/requirements.txt index 3829b46c264..76d05f3c672 100644 --- a/PDF/requirements.txt +++ b/PDF/requirements.txt @@ -1,2 +1,2 @@ -Pillow==10.4.0 +Pillow==11.0.0 fpdf==1.7.2 \ No newline at end of file diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index e894bc4d81d..4b7fbd9ff41 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -31,7 +31,7 @@ pyserial==3.5 twilio==9.3.4 tabula==1.0.5 nltk==3.9.1 -Pillow==10.4.0 +Pillow==11.0.0 SocksiPy-branch==1.01 xlrd==2.0.1 fpdf==1.7.2 From bfcabb4cc1e3a5cd1a14f751d7e0910bf79c1a07 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Thu, 24 Oct 2024 17:05:54 +0100 Subject: [PATCH 149/442] added the backend of the browser history --- BrowserHistory/backend.py | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 BrowserHistory/backend.py diff --git a/BrowserHistory/backend.py b/BrowserHistory/backend.py new file mode 100644 index 00000000000..20ee0005c13 --- /dev/null +++ b/BrowserHistory/backend.py @@ -0,0 +1,47 @@ +class DLL: + def __init__(self, val: str =None): + self.val = val + self.nxt = None + self.prev = None + + +class BrowserHistory: + """ + This class designs the operations of a + broswer history + """ + + def __init__(self, homepage: str): + self.head = DLL(homepage) + self.curr = self.head + + def visit(self, url: str) -> None: + url_node = DLL(url) + self.curr.nxt = url_node + url_node.prev = self.curr + + self.curr = url_node + + + def back(self, steps: int) -> str: + while steps > 0 and self.curr.prev: + self.curr = self.curr.prev + steps -= 1 + return self.curr.val + + + def forward(self, steps: int) -> str: + while steps > 0 and self.curr.nxt: + self.curr = self.curr.nxt + steps -= 1 + return self.curr.val + + +if __name__ == "__main__": + obj = BrowserHistory("google.com") + obj.visit("twitter.com") + param_2 = obj.back(1) + param_3 = obj.forward(1) + + print(param_2) + print(param_3) \ No newline at end of file From fe60f2c95a4e13ea8d3fa9b2d60eebcf9f18bd37 Mon Sep 17 00:00:00 2001 From: Xceptions Date: Thu, 24 Oct 2024 17:57:11 +0100 Subject: [PATCH 150/442] added comments to code --- BrowserHistory/backend.py | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/BrowserHistory/backend.py b/BrowserHistory/backend.py index 20ee0005c13..5eed004cbf2 100644 --- a/BrowserHistory/backend.py +++ b/BrowserHistory/backend.py @@ -1,4 +1,9 @@ class DLL: + """ + a doubly linked list that holds the current page, + next page, and previous page. + Used to enforce order in operations + """ def __init__(self, val: str =None): self.val = val self.nxt = None @@ -7,15 +12,30 @@ def __init__(self, val: str =None): class BrowserHistory: """ - This class designs the operations of a - broswer history + This class designs the operations of a browser history + + It works by using a doubly linked list to hold the urls """ def __init__(self, homepage: str): + """ + Returns - None + Input - None + ---------- + - Initialize doubly linked list which will serve as the + browser history and sets the current page + """ self.head = DLL(homepage) self.curr = self.head def visit(self, url: str) -> None: + """ + Returns - None + Input - str + ---------- + - Adds the current url to the DLL + - sets both the next and previous values + """ url_node = DLL(url) self.curr.nxt = url_node url_node.prev = self.curr @@ -24,6 +44,13 @@ def visit(self, url: str) -> None: def back(self, steps: int) -> str: + """ + Returns - str + Input - int + ---------- + - Iterates through the DLL backwards `step` number of times + - returns the appropriate value + """ while steps > 0 and self.curr.prev: self.curr = self.curr.prev steps -= 1 @@ -31,6 +58,13 @@ def back(self, steps: int) -> str: def forward(self, steps: int) -> str: + """ + Returns - str + Input - int + ---------- + - Iterates through the DLL forewards `step` number of times + - returns the appropriate value + """ while steps > 0 and self.curr.nxt: self.curr = self.curr.nxt steps -= 1 From d3003557220a7c1a5d5ee54cd61adbc22579d1a4 Mon Sep 17 00:00:00 2001 From: Ferszus Date: Sat, 26 Oct 2024 23:03:00 +0200 Subject: [PATCH 151/442] Change import statements to use only used classes --- BlackJack_game/blackjack.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BlackJack_game/blackjack.py b/BlackJack_game/blackjack.py index c1bc919e01c..275b0d7368d 100644 --- a/BlackJack_game/blackjack.py +++ b/BlackJack_game/blackjack.py @@ -1,7 +1,7 @@ # master # master # BLACK JACK - CASINO A GAME OF FORTUNE!!! -from time import * +from time import sleep # BLACK JACK - CASINO # PYTHON CODE BASE @@ -118,4 +118,4 @@ def dealer_choice(): else: dealer_choice() - break + break \ No newline at end of file From 9f626b95539c98c451a32cd53ec9088471fb2d29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 18:33:35 +0000 Subject: [PATCH 152/442] Bump twilio from 9.3.4 to 9.3.6 Bumps [twilio](https://github.com/twilio/twilio-python) from 9.3.4 to 9.3.6. - [Release notes](https://github.com/twilio/twilio-python/releases) - [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md) - [Commits](https://github.com/twilio/twilio-python/compare/9.3.4...9.3.6) --- updated-dependencies: - dependency-name: twilio dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4b7fbd9ff41..8ed01b21cfa 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -28,7 +28,7 @@ requests==2.32.3 quo==2023.5.1 PyPDF2==3.0.1 pyserial==3.5 -twilio==9.3.4 +twilio==9.3.6 tabula==1.0.5 nltk==3.9.1 Pillow==11.0.0 From 71efae40834ca890caf3314b323ca3394ef37c2a Mon Sep 17 00:00:00 2001 From: "M.V.Narasimha Rao" Date: Tue, 29 Oct 2024 21:03:32 -0500 Subject: [PATCH 153/442] adding new sorting Algoritm (dual_pivot_quicksort) --- Sorting Algorithms/dual_pivot_quicksort.py | 80 ++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 Sorting Algorithms/dual_pivot_quicksort.py diff --git a/Sorting Algorithms/dual_pivot_quicksort.py b/Sorting Algorithms/dual_pivot_quicksort.py new file mode 100644 index 00000000000..ef625d2fb13 --- /dev/null +++ b/Sorting Algorithms/dual_pivot_quicksort.py @@ -0,0 +1,80 @@ +def dual_pivot_quicksort(arr, low, high): + """ + Performs Dual-Pivot QuickSort on the input array. + + Dual-Pivot QuickSort is an optimized version of QuickSort that uses + two pivot elements to partition the array into three segments in each + recursive call. This improves performance by reducing the number of + recursive calls, making it faster on average than the single-pivot + QuickSort. + + Parameters: + arr (list): The list to be sorted. + low (int): The starting index of the segment to sort. + high (int): The ending index of the segment to sort. + + Returns: + None: Sorts the array in place. + """ + if low < high: + # Partition the array and get the two pivot indices + lp, rp = partition(arr, low, high) + # Recursively sort elements less than pivot1 + dual_pivot_quicksort(arr, low, lp - 1) + # Recursively sort elements between pivot1 and pivot2 + dual_pivot_quicksort(arr, lp + 1, rp - 1) + # Recursively sort elements greater than pivot2 + dual_pivot_quicksort(arr, rp + 1, high) + +def partition(arr, low, high): + """ + Partitions the array segment defined by low and high using two pivots. + + This function arranges elements into three sections: + - Elements less than pivot1 + - Elements between pivot1 and pivot2 + - Elements greater than pivot2 + + Parameters: + arr (list): The list to partition. + low (int): The starting index of the segment to partition. + high (int): The ending index of the segment to partition. + + Returns: + tuple: Indices of the two pivots in sorted positions (lp, rp). + """ + # Ensure the left pivot is less than or equal to the right pivot + if arr[low] > arr[high]: + arr[low], arr[high] = arr[high], arr[low] + pivot1 = arr[low] # left pivot + pivot2 = arr[high] # right pivot + + # Initialize pointers + i = low + 1 # Pointer to traverse the array + lt = low + 1 # Boundary for elements less than pivot1 + gt = high - 1 # Boundary for elements greater than pivot2 + + # Traverse and partition the array based on the two pivots + while i <= gt: + if arr[i] < pivot1: + arr[i], arr[lt] = arr[lt], arr[i] # Swap to move smaller elements to the left + lt += 1 + elif arr[i] > pivot2: + arr[i], arr[gt] = arr[gt], arr[i] # Swap to move larger elements to the right + gt -= 1 + i -= 1 # Decrement i to re-evaluate the swapped element + i += 1 + + # Place the pivots in their correct sorted positions + lt -= 1 + gt += 1 + arr[low], arr[lt] = arr[lt], arr[low] # Place pivot1 at its correct position + arr[high], arr[gt] = arr[gt], arr[high] # Place pivot2 at its correct position + + return lt, gt # Return the indices of the two pivots + +# Example usage +# Sample Test Case +arr = [24, 8, 42, 75, 29, 77, 38, 57] +dual_pivot_quicksort(arr, 0, len(arr) - 1) +print("Sorted array:", arr) From daa1d4106fd1d887301fe8b475f3c48d067e521b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Oct 2024 18:11:57 +0000 Subject: [PATCH 154/442] Bump yfinance from 0.2.44 to 0.2.48 Bumps [yfinance](https://github.com/ranaroussi/yfinance) from 0.2.44 to 0.2.48. - [Release notes](https://github.com/ranaroussi/yfinance/releases) - [Changelog](https://github.com/ranaroussi/yfinance/blob/main/CHANGELOG.rst) - [Commits](https://github.com/ranaroussi/yfinance/compare/0.2.44...0.2.48) --- updated-dependencies: - dependency-name: yfinance dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 8ed01b21cfa..aba9ad379b3 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -66,7 +66,7 @@ speechtotext==0.0.3 wikipedia==1.4.0 tqdm==4.66.5 Menu==3.2.2 -yfinance==0.2.44 +yfinance==0.2.48 tweepy==4.14.0 tkcalendar==1.6.1 pytube==15.0.0 From 592190f32d9b424ab14d53a93d1c98215a83417a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Oct 2024 18:12:00 +0000 Subject: [PATCH 155/442] Bump fastapi from 0.109.0 to 0.115.4 Bumps [fastapi](https://github.com/fastapi/fastapi) from 0.109.0 to 0.115.4. - [Release notes](https://github.com/fastapi/fastapi/releases) - [Commits](https://github.com/fastapi/fastapi/compare/0.109.0...0.115.4) --- updated-dependencies: - dependency-name: fastapi dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 8ed01b21cfa..210147be2e1 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -83,7 +83,7 @@ pynput==1.7.7 gTTS==2.5.3 ccxt==4.3.87 fitz==0.0.1.dev2 -fastapi==0.109.0 +fastapi==0.115.4 Django==5.1.2 docx==0.2.4 matplotlib==3.9.2 From 363039520fe66d1e4d12aeb58799f17a2ec28c25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 31 Oct 2024 18:10:10 +0000 Subject: [PATCH 156/442] Bump thirdai from 0.9.11 to 0.9.20 Bumps thirdai from 0.9.11 to 0.9.20. --- updated-dependencies: - dependency-name: thirdai dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 8bda1f21e4f..94f50997c49 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -57,7 +57,7 @@ pytesseract==0.3.13 requests-mock==1.12.1 pyglet==2.0.17 urllib3==2.2.3 -thirdai==0.9.11 +thirdai==0.9.20 google-api-python-client==2.149.0 sound==0.1.0 xlwt==1.3.0 From 4f5a9d4fc106de70ddc571233a885e80351bfc93 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 18:30:27 +0000 Subject: [PATCH 157/442] Bump emoji from 2.13.2 to 2.14.0 Bumps [emoji](https://github.com/carpedm20/emoji) from 2.13.2 to 2.14.0. - [Release notes](https://github.com/carpedm20/emoji/releases) - [Changelog](https://github.com/carpedm20/emoji/blob/master/CHANGES.md) - [Commits](https://github.com/carpedm20/emoji/compare/v2.13.2...v2.14.0) --- updated-dependencies: - dependency-name: emoji dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 94f50997c49..7a54fe3de21 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -109,5 +109,5 @@ protobuf==5.27.1 colorama==0.4.6 plyer==2.1.0 Flask-Ask==0.9.8 -emoji==2.13.2 +emoji==2.14.0 PyAutoGUI==0.9.54 From 719d42fe7049d50ca02516c1a7840d90c47b15e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 18:31:24 +0000 Subject: [PATCH 158/442] Bump mediapipe from 0.10.14 to 0.10.18 Bumps [mediapipe](https://github.com/google/mediapipe) from 0.10.14 to 0.10.18. - [Release notes](https://github.com/google/mediapipe/releases) - [Commits](https://github.com/google/mediapipe/commits) --- updated-dependencies: - dependency-name: mediapipe dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Hand-Motion-Detection/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt index 3c3cfaa2592..5dcb46f7945 100644 --- a/Hand-Motion-Detection/requirements.txt +++ b/Hand-Motion-Detection/requirements.txt @@ -1,3 +1,3 @@ numpy==2.1.0 opencv_python==4.10.0.84 -mediapipe==0.10.14 +mediapipe==0.10.18 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 94f50997c49..5f3d779fa17 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -102,7 +102,7 @@ qrcode==8.0 googletrans==3.0.0 slab==1.7.0 psutil==6.0.0 -mediapipe==0.10.14 +mediapipe==0.10.18 rich==13.9.1 httplib2==0.22.0 protobuf==5.27.1 From e0d7f8e1fd4903a32b9f36a3ea7970820e2a2599 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 18:23:27 +0000 Subject: [PATCH 159/442] Bump aiohttp from 3.10.9 to 3.10.10 Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.10.9 to 3.10.10. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.10.9...v3.10.10) --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- async_downloader/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/async_downloader/requirements.txt b/async_downloader/requirements.txt index 05bf5329b0e..48ebda6973e 100644 --- a/async_downloader/requirements.txt +++ b/async_downloader/requirements.txt @@ -1 +1 @@ -aiohttp==3.10.9 +aiohttp==3.10.10 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index a29a800f197..18316404be4 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -1,5 +1,5 @@ pafy==0.5.5 -aiohttp==3.10.9 +aiohttp==3.10.10 fuzzywuzzy==0.18.0 hupper==1.12.1 seaborn==0.13.2 From 7e54ea9c311aa73e8a927ddc1204a7f2e013316e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 18:23:34 +0000 Subject: [PATCH 160/442] Bump selenium from 4.25.0 to 4.26.1 Bumps [selenium](https://github.com/SeleniumHQ/Selenium) from 4.25.0 to 4.26.1. - [Release notes](https://github.com/SeleniumHQ/Selenium/releases) - [Commits](https://github.com/SeleniumHQ/Selenium/commits) --- updated-dependencies: - dependency-name: selenium dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index a29a800f197..c55d4cde003 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -21,7 +21,7 @@ backend==0.2.4.1 win10toast==0.9 Counter==1.0.0 Flask==3.0.3 -selenium==4.25.0 +selenium==4.26.1 firebase-admin==6.5.0 ujson==5.10.0 requests==2.32.3 From 52ef381c1a219081c7792cb68931504c598653d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 18:23:37 +0000 Subject: [PATCH 161/442] Bump thirdai from 0.9.20 to 0.9.21 Bumps thirdai from 0.9.20 to 0.9.21. --- updated-dependencies: - dependency-name: thirdai dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index a29a800f197..7780f195d15 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -57,7 +57,7 @@ pytesseract==0.3.13 requests-mock==1.12.1 pyglet==2.0.17 urllib3==2.2.3 -thirdai==0.9.20 +thirdai==0.9.21 google-api-python-client==2.149.0 sound==0.1.0 xlwt==1.3.0 From 0e930fb5c8778abc7aebbcf26f1ed9793e310311 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 18:48:18 +0000 Subject: [PATCH 162/442] Bump openai from 1.51.2 to 1.54.3 Bumps [openai](https://github.com/openai/openai-python) from 1.51.2 to 1.54.3. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.51.2...v1.54.3) --- updated-dependencies: - dependency-name: openai dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 77d734a8f13..687ac839ba3 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.51.2 +openai==1.54.3 background==0.2.1 pydantic==2.9.2 openpyxl==3.1.2 From 120f96ce2eb38d207494cb94e029c1b65d3969ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Nov 2024 18:48:20 +0000 Subject: [PATCH 163/442] Bump numpy from 2.1.0 to 2.1.3 Bumps [numpy](https://github.com/numpy/numpy) from 2.1.0 to 2.1.3. - [Release notes](https://github.com/numpy/numpy/releases) - [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst) - [Commits](https://github.com/numpy/numpy/compare/v2.1.0...v2.1.3) --- updated-dependencies: - dependency-name: numpy dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Hand-Motion-Detection/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt index 5dcb46f7945..6fed3df9e03 100644 --- a/Hand-Motion-Detection/requirements.txt +++ b/Hand-Motion-Detection/requirements.txt @@ -1,3 +1,3 @@ -numpy==2.1.0 +numpy==2.1.3 opencv_python==4.10.0.84 mediapipe==0.10.18 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 687ac839ba3..5fb935874cd 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -15,7 +15,7 @@ dictator==0.3.1 caller==0.0.2 watchdog==5.0.3 PyQt5==5.15.11 -numpy==2.1.0 +numpy==2.1.3 fileinfo==0.3.3 backend==0.2.4.1 win10toast==0.9 From 748fdb1d128ba6c94df190b71ddddfb822b39dc9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Nov 2024 18:48:23 +0000 Subject: [PATCH 164/442] Bump google-api-python-client from 2.149.0 to 2.151.0 Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.149.0 to 2.151.0. - [Release notes](https://github.com/googleapis/google-api-python-client/releases) - [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.149.0...v2.151.0) --- updated-dependencies: - dependency-name: google-api-python-client dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 687ac839ba3..5188fbc39b3 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -58,7 +58,7 @@ requests-mock==1.12.1 pyglet==2.0.17 urllib3==2.2.3 thirdai==0.9.21 -google-api-python-client==2.149.0 +google-api-python-client==2.151.0 sound==0.1.0 xlwt==1.3.0 pygame==2.6.1 From fbc47d72894b61f4d20ee6145b19411138853979 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 18:12:46 +0000 Subject: [PATCH 165/442] Bump ccxt from 4.3.87 to 4.4.29 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.3.87 to 4.4.29. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.3.87...4.4.29) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 5c1f636c0d3..a181341cdb5 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.7 gTTS==2.5.3 -ccxt==4.3.87 +ccxt==4.4.29 fitz==0.0.1.dev2 fastapi==0.115.4 Django==5.1.2 From 806dc1f47f787cae61ad863c1cf5cd249501b350 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 18:59:51 +0000 Subject: [PATCH 166/442] Bump watchdog from 5.0.3 to 6.0.0 Bumps [watchdog](https://github.com/gorakhargosh/watchdog) from 5.0.3 to 6.0.0. - [Release notes](https://github.com/gorakhargosh/watchdog/releases) - [Changelog](https://github.com/gorakhargosh/watchdog/blob/master/changelog.rst) - [Commits](https://github.com/gorakhargosh/watchdog/compare/v5.0.3...v6.0.0) --- updated-dependencies: - dependency-name: watchdog dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index a181341cdb5..761f0cb15f2 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -13,7 +13,7 @@ pong==1.5 beautifulsoup4==4.12.3 dictator==0.3.1 caller==0.0.2 -watchdog==5.0.3 +watchdog==6.0.0 PyQt5==5.15.11 numpy==2.1.3 fileinfo==0.3.3 From d938b70d23d13e8a7afbb97d49e3ff6572e56e9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 18:55:42 +0000 Subject: [PATCH 167/442] Bump aiohttp from 3.10.10 to 3.11.2 Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.10.10 to 3.11.2. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.10.10...v3.11.2) --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- async_downloader/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/async_downloader/requirements.txt b/async_downloader/requirements.txt index 48ebda6973e..e917ad11615 100644 --- a/async_downloader/requirements.txt +++ b/async_downloader/requirements.txt @@ -1 +1 @@ -aiohttp==3.10.10 +aiohttp==3.11.2 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 761f0cb15f2..8e23e0215c9 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -1,5 +1,5 @@ pafy==0.5.5 -aiohttp==3.10.10 +aiohttp==3.11.2 fuzzywuzzy==0.18.0 hupper==1.12.1 seaborn==0.13.2 From 471f35682ab7b2cb2b69b87241577937eda62f61 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 18:37:13 +0000 Subject: [PATCH 168/442] Bump flask from 3.0.3 to 3.1.0 Bumps [flask](https://github.com/pallets/flask) from 3.0.3 to 3.1.0. - [Release notes](https://github.com/pallets/flask/releases) - [Changelog](https://github.com/pallets/flask/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/flask/compare/3.0.3...3.1.0) --- updated-dependencies: - dependency-name: flask dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 8e23e0215c9..abdd9c57424 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -20,7 +20,7 @@ fileinfo==0.3.3 backend==0.2.4.1 win10toast==0.9 Counter==1.0.0 -Flask==3.0.3 +Flask==3.1.0 selenium==4.26.1 firebase-admin==6.5.0 ujson==5.10.0 From 00fcc167b718a45fb159312044a02d9cd1f384c4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 18:50:02 +0000 Subject: [PATCH 169/442] Bump aiohttp from 3.11.2 to 3.11.5 Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.11.2 to 3.11.5. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.11.2...v3.11.5) --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- async_downloader/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/async_downloader/requirements.txt b/async_downloader/requirements.txt index e917ad11615..76092199743 100644 --- a/async_downloader/requirements.txt +++ b/async_downloader/requirements.txt @@ -1 +1 @@ -aiohttp==3.11.2 +aiohttp==3.11.5 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index abdd9c57424..657cc7492b5 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -1,5 +1,5 @@ pafy==0.5.5 -aiohttp==3.11.2 +aiohttp==3.11.5 fuzzywuzzy==0.18.0 hupper==1.12.1 seaborn==0.13.2 From 0dcba309d84d9bb30072e50daee7e0329fac2b54 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 18:52:49 +0000 Subject: [PATCH 170/442] Bump firebase-admin from 6.5.0 to 6.6.0 Bumps [firebase-admin](https://github.com/firebase/firebase-admin-python) from 6.5.0 to 6.6.0. - [Release notes](https://github.com/firebase/firebase-admin-python/releases) - [Commits](https://github.com/firebase/firebase-admin-python/compare/v6.5.0...v6.6.0) --- updated-dependencies: - dependency-name: firebase-admin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 657cc7492b5..77c09820103 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -22,7 +22,7 @@ win10toast==0.9 Counter==1.0.0 Flask==3.1.0 selenium==4.26.1 -firebase-admin==6.5.0 +firebase-admin==6.6.0 ujson==5.10.0 requests==2.32.3 quo==2023.5.1 From d2f3238d54c7b082a5b3f3b1485eba364af34e0d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Nov 2024 18:15:21 +0000 Subject: [PATCH 171/442] Bump psutil from 6.0.0 to 6.1.0 Bumps [psutil](https://github.com/giampaolo/psutil) from 6.0.0 to 6.1.0. - [Changelog](https://github.com/giampaolo/psutil/blob/master/HISTORY.rst) - [Commits](https://github.com/giampaolo/psutil/compare/release-6.0.0...release-6.1.0) --- updated-dependencies: - dependency-name: psutil dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 77c09820103..190b852135e 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -101,7 +101,7 @@ pytest==8.3.3 qrcode==8.0 googletrans==3.0.0 slab==1.7.0 -psutil==6.0.0 +psutil==6.1.0 mediapipe==0.10.18 rich==13.9.1 httplib2==0.22.0 From 6ba6fe193ee8d33e25af2242425447a20a6dfdc3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 19:05:49 +0000 Subject: [PATCH 172/442] Bump apscheduler from 3.10.4 to 3.11.0 Bumps [apscheduler](https://github.com/agronholm/apscheduler) from 3.10.4 to 3.11.0. - [Release notes](https://github.com/agronholm/apscheduler/releases) - [Changelog](https://github.com/agronholm/apscheduler/blob/3.11.0/docs/versionhistory.rst) - [Commits](https://github.com/agronholm/apscheduler/compare/3.10.4...3.11.0) --- updated-dependencies: - dependency-name: apscheduler dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 190b852135e..e07fd8e2a3d 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -89,7 +89,7 @@ docx==0.2.4 matplotlib==3.9.2 pyshorteners==1.0.1 geocoder==1.38.1 -APScheduler==3.10.4 +APScheduler==3.11.0 PyQRCode==1.2.1 freegames==2.5.3 pyperclip==1.8.2 From a268e299d5f1c8eab0a704a5cca1302e1dac5c4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 18:39:59 +0000 Subject: [PATCH 173/442] Bump google-api-python-client from 2.151.0 to 2.154.0 Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.151.0 to 2.154.0. - [Release notes](https://github.com/googleapis/google-api-python-client/releases) - [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.151.0...v2.154.0) --- updated-dependencies: - dependency-name: google-api-python-client dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index e07fd8e2a3d..28e9242e904 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -58,7 +58,7 @@ requests-mock==1.12.1 pyglet==2.0.17 urllib3==2.2.3 thirdai==0.9.21 -google-api-python-client==2.151.0 +google-api-python-client==2.154.0 sound==0.1.0 xlwt==1.3.0 pygame==2.6.1 From d10f59b317cda9645fcab6ffab76bdcb51e1a266 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 18:56:44 +0000 Subject: [PATCH 174/442] Bump keras from 3.6.0 to 3.7.0 Bumps [keras](https://github.com/keras-team/keras) from 3.6.0 to 3.7.0. - [Release notes](https://github.com/keras-team/keras/releases) - [Commits](https://github.com/keras-team/keras/compare/v3.6.0...v3.7.0) --- updated-dependencies: - dependency-name: keras dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 28e9242e904..4dce397763d 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -41,7 +41,7 @@ tornado==6.4.1 obs==0.0.0 todo==0.1 oauth2client==4.1.3 -keras==3.6.0 +keras==3.7.0 pymongo==4.10.1 playsound==1.3.0 pyttsx3==2.98 From 5e80d047a2114dce85c38fd3caa3cb9c779330fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Nov 2024 18:54:05 +0000 Subject: [PATCH 175/442] Bump ccxt from 4.4.29 to 4.4.34 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.4.29 to 4.4.34. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.4.29...4.4.34) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4dce397763d..873f1d9ec40 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.7 gTTS==2.5.3 -ccxt==4.4.29 +ccxt==4.4.34 fitz==0.0.1.dev2 fastapi==0.115.4 Django==5.1.2 From 8a28db36f69baace57bdb612f615e255e01a8b82 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 18:43:34 +0000 Subject: [PATCH 176/442] Bump fastapi from 0.115.4 to 0.115.6 Bumps [fastapi](https://github.com/fastapi/fastapi) from 0.115.4 to 0.115.6. - [Release notes](https://github.com/fastapi/fastapi/releases) - [Commits](https://github.com/fastapi/fastapi/compare/0.115.4...0.115.6) --- updated-dependencies: - dependency-name: fastapi dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 873f1d9ec40..f8a47f378e4 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -83,7 +83,7 @@ pynput==1.7.7 gTTS==2.5.3 ccxt==4.4.34 fitz==0.0.1.dev2 -fastapi==0.115.4 +fastapi==0.115.6 Django==5.1.2 docx==0.2.4 matplotlib==3.9.2 From 94175b17e574b8cbaa7aa511860b6dc5aead1ba8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Dec 2024 18:33:51 +0000 Subject: [PATCH 177/442] Bump solara from 1.40.0 to 1.42.0 Bumps [solara](https://github.com/widgetti/solara) from 1.40.0 to 1.42.0. - [Changelog](https://github.com/widgetti/solara/blob/master/CHANGELOG.md) - [Commits](https://github.com/widgetti/solara/compare/v1.40.0...v1.42.0) --- updated-dependencies: - dependency-name: solara dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- News_App/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/News_App/requirements.txt b/News_App/requirements.txt index 9e40a95b321..a219c88721a 100644 --- a/News_App/requirements.txt +++ b/News_App/requirements.txt @@ -1,4 +1,4 @@ -solara == 1.40.0 +solara == 1.42.0 Flask gunicorn ==23.0.0 simple-websocket diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 873f1d9ec40..445d3c01a74 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -74,7 +74,7 @@ xor-cipher==5.0.0 bird==0.1.2 mechanize==0.4.10 translate==3.6.1 -solara==1.40.0 +solara==1.42.0 pywhatkit==5.4 mutagen==1.47.0 Unidecode==1.3.8 From 872a5759e4993e0db2055612f8a9b4c698326b00 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2024 18:26:26 +0000 Subject: [PATCH 178/442] Bump yfinance from 0.2.48 to 0.2.50 Bumps [yfinance](https://github.com/ranaroussi/yfinance) from 0.2.48 to 0.2.50. - [Release notes](https://github.com/ranaroussi/yfinance/releases) - [Changelog](https://github.com/ranaroussi/yfinance/blob/main/CHANGELOG.rst) - [Commits](https://github.com/ranaroussi/yfinance/compare/0.2.48...0.2.50) --- updated-dependencies: - dependency-name: yfinance dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index ce790c271a9..a08e12fc295 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -66,7 +66,7 @@ speechtotext==0.0.3 wikipedia==1.4.0 tqdm==4.66.5 Menu==3.2.2 -yfinance==0.2.48 +yfinance==0.2.50 tweepy==4.14.0 tkcalendar==1.6.1 pytube==15.0.0 From a58ece4837d3111b4f12a30906d4e12691ec106c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2024 18:26:32 +0000 Subject: [PATCH 179/442] Bump pytest from 8.3.3 to 8.3.4 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.3 to 8.3.4. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.3.3...8.3.4) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index ce790c271a9..232b9a7ee16 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -97,7 +97,7 @@ newspaper==0.1.0.7 opencv-python==4.10.0.84 tensorflow==2.15.0.post1 pandas==2.2.3 -pytest==8.3.3 +pytest==8.3.4 qrcode==8.0 googletrans==3.0.0 slab==1.7.0 From 68abf93fd065ee6fbffa82a088fb1310501fc1d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 19:08:03 +0000 Subject: [PATCH 180/442] Bump pydantic from 2.9.2 to 2.10.3 Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.9.2 to 2.10.3. - [Release notes](https://github.com/pydantic/pydantic/releases) - [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md) - [Commits](https://github.com/pydantic/pydantic/compare/v2.9.2...v2.10.3) --- updated-dependencies: - dependency-name: pydantic dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index fc70e3b9122..2e7d4d444b9 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -51,7 +51,7 @@ pywifi==1.1.12 patterns==0.3 openai==1.54.3 background==0.2.1 -pydantic==2.9.2 +pydantic==2.10.3 openpyxl==3.1.2 pytesseract==0.3.13 requests-mock==1.12.1 From 94ed278238ddece9030624ac3de961dcbdc5b33f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 19:08:08 +0000 Subject: [PATCH 181/442] Bump gtts from 2.5.3 to 2.5.4 Bumps [gtts](https://github.com/pndurette/gTTS) from 2.5.3 to 2.5.4. - [Release notes](https://github.com/pndurette/gTTS/releases) - [Changelog](https://github.com/pndurette/gTTS/blob/main/CHANGELOG.md) - [Commits](https://github.com/pndurette/gTTS/compare/v2.5.3...v2.5.4) --- updated-dependencies: - dependency-name: gtts dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- text_to_audio/requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index fc70e3b9122..37be36a34e4 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -80,7 +80,7 @@ mutagen==1.47.0 Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.7 -gTTS==2.5.3 +gTTS==2.5.4 ccxt==4.4.34 fitz==0.0.1.dev2 fastapi==0.115.6 diff --git a/text_to_audio/requirements.txt b/text_to_audio/requirements.txt index a95f73ea805..01a5c752ec0 100644 --- a/text_to_audio/requirements.txt +++ b/text_to_audio/requirements.txt @@ -1,2 +1,2 @@ -gTTS==2.5.3 +gTTS==2.5.4 pygame==2.6.1 From 4baaf527a73ae496fee4eeb072f2325378646307 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Dec 2024 18:30:57 +0000 Subject: [PATCH 182/442] Bump selenium from 4.26.1 to 4.27.1 Bumps [selenium](https://github.com/SeleniumHQ/Selenium) from 4.26.1 to 4.27.1. - [Release notes](https://github.com/SeleniumHQ/Selenium/releases) - [Commits](https://github.com/SeleniumHQ/Selenium/commits) --- updated-dependencies: - dependency-name: selenium dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 8a986815af8..6fa674e54c0 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -21,7 +21,7 @@ backend==0.2.4.1 win10toast==0.9 Counter==1.0.0 Flask==3.1.0 -selenium==4.26.1 +selenium==4.27.1 firebase-admin==6.6.0 ujson==5.10.0 requests==2.32.3 From 18bd7062ea62b9c0600eee2e6537a9f09bf52d46 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Dec 2024 18:31:01 +0000 Subject: [PATCH 183/442] Bump tornado from 6.4.1 to 6.4.2 Bumps [tornado](https://github.com/tornadoweb/tornado) from 6.4.1 to 6.4.2. - [Changelog](https://github.com/tornadoweb/tornado/blob/v6.4.2/docs/releases.rst) - [Commits](https://github.com/tornadoweb/tornado/compare/v6.4.1...v6.4.2) --- updated-dependencies: - dependency-name: tornado dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 8a986815af8..e03c06db9fb 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -37,7 +37,7 @@ xlrd==2.0.1 fpdf==1.7.2 mysql-connector-repackaged==0.3.1 word2number==1.1 -tornado==6.4.1 +tornado==6.4.2 obs==0.0.0 todo==0.1 oauth2client==4.1.3 From b8ff109338f78a41c003dfaf792806fa2824e6cf Mon Sep 17 00:00:00 2001 From: Ratnesh Kumar Date: Fri, 13 Dec 2024 12:49:47 +0530 Subject: [PATCH 184/442] add Mode Co-Authored-By: Ratnesh Kumar <142919875+16ratneshkumar@users.noreply.github.com> --- .../File handle binary/Deleting record in a binary file.py | 4 ++-- .../File handle binary read (record in non list form).py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/1 File handle/File handle binary/Deleting record in a binary file.py b/1 File handle/File handle binary/Deleting record in a binary file.py index 41a5007b86c..d3922a5afc4 100644 --- a/1 File handle/File handle binary/Deleting record in a binary file.py +++ b/1 File handle/File handle binary/Deleting record in a binary file.py @@ -3,13 +3,13 @@ def bdelete(): # Opening a file & loading it - with open("studrec.dat") as F: + with open("studrec.dat","rb") as F: stud = pickle.load(F) print(stud) # Deleting the Roll no. entered by user rno = int(input("Enter the Roll no. to be deleted: ")) - with open("studrec.dat") as F: + with open("studrec.dat","wb") as F: rec = [i for i in stud if i[0] != rno] pickle.dump(rec, F) diff --git a/1 File handle/File handle binary/File handle binary read (record in non list form).py b/1 File handle/File handle binary/File handle binary read (record in non list form).py index f37d97f0bff..bb9f127ea0b 100644 --- a/1 File handle/File handle binary/File handle binary read (record in non list form).py +++ b/1 File handle/File handle binary/File handle binary read (record in non list form).py @@ -2,7 +2,7 @@ def binary_read(): - with open("studrec.dat") as b: + with open("studrec.dat","rb") as b: stud = pickle.load(b) print(stud) From 1911cec7f9116376d6a1f8130a89131c5877f386 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 18:32:19 +0000 Subject: [PATCH 185/442] Bump twilio from 9.3.6 to 9.4.1 Bumps [twilio](https://github.com/twilio/twilio-python) from 9.3.6 to 9.4.1. - [Release notes](https://github.com/twilio/twilio-python/releases) - [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md) - [Commits](https://github.com/twilio/twilio-python/compare/9.3.6...9.4.1) --- updated-dependencies: - dependency-name: twilio dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index f585868ab6b..6f25dbf6362 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -28,7 +28,7 @@ requests==2.32.3 quo==2023.5.1 PyPDF2==3.0.1 pyserial==3.5 -twilio==9.3.6 +twilio==9.4.1 tabula==1.0.5 nltk==3.9.1 Pillow==11.0.0 From 860cee9a5509a60911b769c61f67bb58e5ab4b3d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 18:32:27 +0000 Subject: [PATCH 186/442] Bump numpy from 2.1.3 to 2.2.0 Bumps [numpy](https://github.com/numpy/numpy) from 2.1.3 to 2.2.0. - [Release notes](https://github.com/numpy/numpy/releases) - [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst) - [Commits](https://github.com/numpy/numpy/compare/v2.1.3...v2.2.0) --- updated-dependencies: - dependency-name: numpy dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Hand-Motion-Detection/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt index 6fed3df9e03..34b06d77e25 100644 --- a/Hand-Motion-Detection/requirements.txt +++ b/Hand-Motion-Detection/requirements.txt @@ -1,3 +1,3 @@ -numpy==2.1.3 +numpy==2.2.0 opencv_python==4.10.0.84 mediapipe==0.10.18 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index f585868ab6b..b9af000f6f6 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -15,7 +15,7 @@ dictator==0.3.1 caller==0.0.2 watchdog==6.0.0 PyQt5==5.15.11 -numpy==2.1.3 +numpy==2.2.0 fileinfo==0.3.3 backend==0.2.4.1 win10toast==0.9 From f08e24b876db0d3103447aa95e591b8346f33ba8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:59:30 +0000 Subject: [PATCH 187/442] Bump google-api-python-client from 2.154.0 to 2.156.0 Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.154.0 to 2.156.0. - [Release notes](https://github.com/googleapis/google-api-python-client/releases) - [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.154.0...v2.156.0) --- updated-dependencies: - dependency-name: google-api-python-client dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index f585868ab6b..a030baf973a 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -58,7 +58,7 @@ requests-mock==1.12.1 pyglet==2.0.17 urllib3==2.2.3 thirdai==0.9.21 -google-api-python-client==2.154.0 +google-api-python-client==2.156.0 sound==0.1.0 xlwt==1.3.0 pygame==2.6.1 From b3124371b712d832ba011e0624be3f08df9f69ba Mon Sep 17 00:00:00 2001 From: Kalpita Birhade <84992682+kalpitabirhade28@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:40:12 +0530 Subject: [PATCH 188/442] Create fF Improvements: Simplified output: Displays folder size in the most appropriate human-readable unit. Error handling: Checks if the provided directory exists. Readable structure: Uses helper functions for size calculation and formatting. Usability: Prints clear usage instructions when arguments are missing. --- fF | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 fF diff --git a/fF b/fF new file mode 100644 index 00000000000..2edac5d9f5d --- /dev/null +++ b/fF @@ -0,0 +1,43 @@ +# Script Name : folder_size.py +# Author : Craig Richards (Simplified by Assistant) +# Created : 19th July 2012 +# Last Modified : 19th December 2024 +# Version : 2.0.0 + +# Description : Scans a directory and subdirectories to display the total size. + +import os +import sys + +def get_folder_size(directory): + """Calculate the total size of a directory and its subdirectories.""" + total_size = 0 + for root, _, files in os.walk(directory): + for file in files: + total_size += os.path.getsize(os.path.join(root, file)) + return total_size + +def format_size(size): + """Format the size into human-readable units.""" + units = ["Bytes", "KB", "MB", "GB", "TB"] + for unit in units: + if size < 1024 or unit == units[-1]: + return f"{size:.2f} {unit}" + size /= 1024 + +def main(): + if len(sys.argv) < 2: + print("Usage: python folder_size.py ") + sys.exit(1) + + directory = sys.argv[1] + + if not os.path.exists(directory): + print(f"Error: The directory '{directory}' does not exist.") + sys.exit(1) + + folder_size = get_folder_size(directory) + print(f"Folder Size: {format_size(folder_size)}") + +if __name__ == "__main__": + main() From 6847ede6da5b08eab567866b3e78a8a47886eac1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 18:18:20 +0000 Subject: [PATCH 189/442] Bump mediapipe from 0.10.18 to 0.10.20 Bumps [mediapipe](https://github.com/google/mediapipe) from 0.10.18 to 0.10.20. - [Release notes](https://github.com/google/mediapipe/releases) - [Commits](https://github.com/google/mediapipe/compare/v0.10.18...v0.10.20) --- updated-dependencies: - dependency-name: mediapipe dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Hand-Motion-Detection/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt index 34b06d77e25..25598a6dec7 100644 --- a/Hand-Motion-Detection/requirements.txt +++ b/Hand-Motion-Detection/requirements.txt @@ -1,3 +1,3 @@ numpy==2.2.0 opencv_python==4.10.0.84 -mediapipe==0.10.18 +mediapipe==0.10.20 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 025cd9b8aed..18840d48da9 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -102,7 +102,7 @@ qrcode==8.0 googletrans==3.0.0 slab==1.7.0 psutil==6.1.0 -mediapipe==0.10.18 +mediapipe==0.10.20 rich==13.9.1 httplib2==0.22.0 protobuf==5.27.1 From 4ff57bdf18bdf4f2243a516c9592538d1bd95d78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 18:18:28 +0000 Subject: [PATCH 190/442] Bump openai from 1.54.3 to 1.58.1 Bumps [openai](https://github.com/openai/openai-python) from 1.54.3 to 1.58.1. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.54.3...v1.58.1) --- updated-dependencies: - dependency-name: openai dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 025cd9b8aed..d9c85c1e396 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.54.3 +openai==1.58.1 background==0.2.1 pydantic==2.10.3 openpyxl==3.1.2 From 3c4beaf9f62c9bd3f4e74325b02d635b536dde95 Mon Sep 17 00:00:00 2001 From: Zerubbabel <141437885+ZerubbabelT@users.noreply.github.com> Date: Sat, 21 Dec 2024 22:21:34 +0300 Subject: [PATCH 191/442] Add robust input validation for row and column inputs --- TIC_TAC_TOE/index.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/TIC_TAC_TOE/index.py b/TIC_TAC_TOE/index.py index 7e494d0e700..95245d34fe5 100644 --- a/TIC_TAC_TOE/index.py +++ b/TIC_TAC_TOE/index.py @@ -15,6 +15,17 @@ def check_winner(board, player): def is_full(board): return all(cell != " " for row in board for cell in row) +# A function that validates user input +def get_valid_input(prompt): + while True: + try: + value = int(input(prompt)) + if 0 <= value < 3: # Check if the value is within the valid range + return value + else: + print("Invalid input: Enter a number between 0 and 2.") + except ValueError: + print("Invalid input: Please enter an integer.") def main(): board = [[" " for _ in range(3)] for _ in range(3)] @@ -22,10 +33,13 @@ def main(): while True: print_board(board) - row = int(input(f"Player {player}, enter the row (0, 1, 2): ")) - col = int(input(f"Player {player}, enter the column (0, 1, 2): ")) + print(f"Player {player}'s turn:") + + # Get validated inputs + row = get_valid_input("Enter the row (0, 1, 2): ") + col = get_valid_input("Enter the column (0, 1, 2): ") - if 0 <= row < 3 and 0 <= col < 3 and board[row][col] == " ": + if board[row][col] == " ": board[row][col] = player if check_winner(board, player): @@ -40,7 +54,7 @@ def main(): player = "O" if player == "X" else "X" else: - print("Invalid move. Try again.") + print("Invalid move: That spot is already taken. Try again.") if __name__ == "__main__": main() From 45decb8902e190573ac50540fc76f0ea35679c7a Mon Sep 17 00:00:00 2001 From: samiksha gopinath Date: Sun, 22 Dec 2024 17:29:52 +0530 Subject: [PATCH 192/442] new file --- new.py | 140 +++------------------------------------------------------ 1 file changed, 6 insertions(+), 134 deletions(-) diff --git a/new.py b/new.py index 9df00e5faaa..5a5f623242c 100644 --- a/new.py +++ b/new.py @@ -1,137 +1,9 @@ -""" -a simple terminal program to find new about certain topic by web scraping site. -site used : -1. Times of India, - link : https://timesofindia.indiatimes.com/india/ -2. India's Today, - link : https://www.indiatoday.in/topic/ -""" - -import requests -from bs4 import BeautifulSoup -import webbrowser -import time - - -def Times_of_India(userInput, ua): - bold_start = "\033[1m" - bold_end = "\033[0m" - - url = "https://timesofindia.indiatimes.com/india/" - url += userInput - - res = requests.post(url, headers=ua) - soup = BeautifulSoup(res.content, "html.parser") - data = soup.find_all(class_="w_tle") - - if len(data) > 0: - print("News available :", "\N{slightly smiling face}") - if len(data) == 0: - return 0 - - for item in range(len(data)): - print(bold_start, "\033[1;32;40m \nNEWS : ", item + 1, bold_end, end=" ") - data1 = data[item].find("a") - print(bold_start, data1.get_text(), bold_end) - - bol = input("For more details ->(y) (y/n) :: ") - if bol == "y": - url += data1.get("href") - print("%s" % url) - - webbrowser.open(url) - - return len(data) - - -def india_today(userInput, ua): - bold_start = "\033[1m" - bold_end = "\033[0m" - - url = "https://www.indiatoday.in/topic/" - url += userInput - - res = requests.get(url, headers=ua) - soup = BeautifulSoup(res.content, "html.parser") - data = soup.find_all(class_="field-content") - - if len(data) > 0: - print("\nNews available : ", "\N{slightly smiling face}") - k = 0 - for i in range(len(data)): - data1 = data[i].find_all("a") - for j in range(len(data1)): - print(bold_start, "\033[1;32;40m\nNEWS ", k + 1, bold_end, end=" : ") - k += 1 - print(bold_start, data1[j].get_text(), bold_end) - bol = input("\nFor more details ->(y) (y/n) :: ") - if bol == "y" or bol == "Y": - data2 = data[i].find("a") - url = data2.get("href") - webbrowser.open(url) - - return len(data) +def hello_world(): + """ + Prints a greeting message. + """ + print("Hello, world!") if __name__ == "__main__": - import doctest - - doctest.testmod() - bold_start = "\033[1m" - bold_end = "\033[0m" - print("\033[5;31;40m") - print( - bold_start, - " HERE YOU WILL GET ALL THE NEWS JUST IN ONE SEARCH ", - bold_end, - ) - print("\n") - localtime = time.asctime(time.localtime(time.time())) - print(bold_start, localtime, bold_end) - - ua = { - "UserAgent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0" - } - print( - bold_start, - "\n\033[1;35;40m Search any news (state , city ,Country , AnyThings etc) : ", - bold_end, - end=" ", - ) - - userInput = input() - - print(bold_start, "\033[1;33;40m \n") - print("Which news channel data would you prefer") - print("1. Times of india") - print("2. India's Today", bold_end) - - say = int(input()) - - if say == 1: - length = Times_of_India(userInput, ua) - if length == 0: - print("Sorry Here No News Available", "\N{expressionless face}") - print("\n") - print( - "Would you like to go for India's Today (y/n):: ", - "\N{thinking face}", - end=" ", - ) - speak = input() - if speak == "y": - length = india_today(userInput, ua) - if length == 0: - print("Sorry No news", "\N{expressionless face}") - else: - print("\nThank you", "\U0001f600") - - elif say == 2: - length = india_today(userInput, ua) - - if length == 0: - print("Sorry No news") - else: - print("\nThank you", "\U0001f600") - else: - print("Sorry", "\N{expressionless face}") + hello_world() From 75d452ffe158584d0b4067f5c1f618f4b7639d0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 18:10:54 +0000 Subject: [PATCH 193/442] Bump ccxt from 4.4.34 to 4.4.42 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.4.34 to 4.4.42. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.4.34...4.4.42) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 015c0e4b8b7..84a222ca26e 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.7 gTTS==2.5.4 -ccxt==4.4.34 +ccxt==4.4.42 fitz==0.0.1.dev2 fastapi==0.115.6 Django==5.1.2 From a5bc3e824b66404561af9b911c020ca9b25bafa4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 18:10:58 +0000 Subject: [PATCH 194/442] Bump urllib3 from 2.2.3 to 2.3.0 Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.2.3 to 2.3.0. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/2.2.3...2.3.0) --- updated-dependencies: - dependency-name: urllib3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 015c0e4b8b7..983f6a179f7 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -56,7 +56,7 @@ openpyxl==3.1.2 pytesseract==0.3.13 requests-mock==1.12.1 pyglet==2.0.17 -urllib3==2.2.3 +urllib3==2.3.0 thirdai==0.9.21 google-api-python-client==2.156.0 sound==0.1.0 From 2a43671565ede9ce5079f45d7854974b309e0150 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Dec 2024 18:26:30 +0000 Subject: [PATCH 195/442] Bump thirdai from 0.9.21 to 0.9.25 Bumps thirdai from 0.9.21 to 0.9.25. --- updated-dependencies: - dependency-name: thirdai dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 871a4a6d8a9..9e6dab5aaf9 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -57,7 +57,7 @@ pytesseract==0.3.13 requests-mock==1.12.1 pyglet==2.0.17 urllib3==2.3.0 -thirdai==0.9.21 +thirdai==0.9.25 google-api-python-client==2.156.0 sound==0.1.0 xlwt==1.3.0 From 1b083393c68ae6674a94ad9d583e40d7653cb82d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Dec 2024 18:26:39 +0000 Subject: [PATCH 196/442] Bump yfinance from 0.2.50 to 0.2.51 Bumps [yfinance](https://github.com/ranaroussi/yfinance) from 0.2.50 to 0.2.51. - [Release notes](https://github.com/ranaroussi/yfinance/releases) - [Changelog](https://github.com/ranaroussi/yfinance/blob/main/CHANGELOG.rst) - [Commits](https://github.com/ranaroussi/yfinance/compare/0.2.50...0.2.51) --- updated-dependencies: - dependency-name: yfinance dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 871a4a6d8a9..c93438101dc 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -66,7 +66,7 @@ speechtotext==0.0.3 wikipedia==1.4.0 tqdm==4.66.5 Menu==3.2.2 -yfinance==0.2.50 +yfinance==0.2.51 tweepy==4.14.0 tkcalendar==1.6.1 pytube==15.0.0 From b170580fdda971eec310e7f125598620d1f0dee2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Dec 2024 18:10:19 +0000 Subject: [PATCH 197/442] Bump numpy from 2.2.0 to 2.2.1 Bumps [numpy](https://github.com/numpy/numpy) from 2.2.0 to 2.2.1. - [Release notes](https://github.com/numpy/numpy/releases) - [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst) - [Commits](https://github.com/numpy/numpy/compare/v2.2.0...v2.2.1) --- updated-dependencies: - dependency-name: numpy dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Hand-Motion-Detection/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt index 25598a6dec7..3ac1b2a3429 100644 --- a/Hand-Motion-Detection/requirements.txt +++ b/Hand-Motion-Detection/requirements.txt @@ -1,3 +1,3 @@ -numpy==2.2.0 +numpy==2.2.1 opencv_python==4.10.0.84 mediapipe==0.10.20 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 0a930933e5f..ef7fe674f36 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -15,7 +15,7 @@ dictator==0.3.1 caller==0.0.2 watchdog==6.0.0 PyQt5==5.15.11 -numpy==2.2.0 +numpy==2.2.1 fileinfo==0.3.3 backend==0.2.4.1 win10toast==0.9 From f9058624336a937b1947f0ea2ee861aff397634d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Dec 2024 18:10:22 +0000 Subject: [PATCH 198/442] Bump rich from 13.9.1 to 13.9.4 Bumps [rich](https://github.com/Textualize/rich) from 13.9.1 to 13.9.4. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.9.1...v13.9.4) --- updated-dependencies: - dependency-name: rich dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 0a930933e5f..f61e72be980 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -103,7 +103,7 @@ googletrans==3.0.0 slab==1.7.0 psutil==6.1.0 mediapipe==0.10.20 -rich==13.9.1 +rich==13.9.4 httplib2==0.22.0 protobuf==5.27.1 colorama==0.4.6 From 6e18f47caf83f46f075c924364ebe7caed1b81e4 Mon Sep 17 00:00:00 2001 From: Mohitha1514 <153967131+Mohitha1514@users.noreply.github.com> Date: Fri, 27 Dec 2024 13:04:18 +0530 Subject: [PATCH 199/442] Create tic tac --- AI Game/Tic-Tac-Toe-AI/tic tac | 1 + 1 file changed, 1 insertion(+) create mode 100644 AI Game/Tic-Tac-Toe-AI/tic tac diff --git a/AI Game/Tic-Tac-Toe-AI/tic tac b/AI Game/Tic-Tac-Toe-AI/tic tac new file mode 100644 index 00000000000..47a950ff8bf --- /dev/null +++ b/AI Game/Tic-Tac-Toe-AI/tic tac @@ -0,0 +1 @@ +hii From 16b2fba637233fcfcc38b716bf6b932c1950924d Mon Sep 17 00:00:00 2001 From: sravani292005 <166207685+sravani292005@users.noreply.github.com> Date: Fri, 27 Dec 2024 13:04:34 +0530 Subject: [PATCH 200/442] Create klmn --- Assembler/examples/klmn | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Assembler/examples/klmn diff --git a/Assembler/examples/klmn b/Assembler/examples/klmn new file mode 100644 index 00000000000..9c16fab3022 --- /dev/null +++ b/Assembler/examples/klmn @@ -0,0 +1,2 @@ +Assembler/examples/code2.txt +hello world From 6d548f8fc818144f1f39066c78c4b4f1d0f9cedc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Dec 2024 18:51:23 +0000 Subject: [PATCH 201/442] Bump xor-cipher from 5.0.0 to 5.0.1 Bumps [xor-cipher](https://github.com/xor-cipher/xor-cipher) from 5.0.0 to 5.0.1. - [Release notes](https://github.com/xor-cipher/xor-cipher/releases) - [Changelog](https://github.com/xor-cipher/xor-cipher/blob/main/CHANGELOG.md) - [Commits](https://github.com/xor-cipher/xor-cipher/compare/v5.0.0...v5.0.1) --- updated-dependencies: - dependency-name: xor-cipher dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 6fad5c5c290..4b0fd7cb4aa 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -70,7 +70,7 @@ yfinance==0.2.51 tweepy==4.14.0 tkcalendar==1.6.1 pytube==15.0.0 -xor-cipher==5.0.0 +xor-cipher==5.0.1 bird==0.1.2 mechanize==0.4.10 translate==3.6.1 From 2d71b1cbe5901b1577fb989dfc57d357e7bad858 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Dec 2024 18:51:28 +0000 Subject: [PATCH 202/442] Bump protobuf from 5.27.1 to 5.29.2 Bumps [protobuf](https://github.com/protocolbuffers/protobuf) from 5.27.1 to 5.29.2. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v5.27.1...v5.29.2) --- updated-dependencies: - dependency-name: protobuf dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 6fad5c5c290..0e2149ba504 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -105,7 +105,7 @@ psutil==6.1.0 mediapipe==0.10.20 rich==13.9.4 httplib2==0.22.0 -protobuf==5.27.1 +protobuf==5.29.2 colorama==0.4.6 plyer==2.1.0 Flask-Ask==0.9.8 From 8dd124fb13b45b28adc2fa009d7884e914365fc4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 18:54:11 +0000 Subject: [PATCH 203/442] Bump aiohttp from 3.11.5 to 3.11.11 --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- async_downloader/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/async_downloader/requirements.txt b/async_downloader/requirements.txt index 76092199743..eefc3748c6c 100644 --- a/async_downloader/requirements.txt +++ b/async_downloader/requirements.txt @@ -1 +1 @@ -aiohttp==3.11.5 +aiohttp==3.11.11 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index d7eb7e8deba..2cc7276ffa6 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -1,5 +1,5 @@ pafy==0.5.5 -aiohttp==3.11.5 +aiohttp==3.11.11 fuzzywuzzy==0.18.0 hupper==1.12.1 seaborn==0.13.2 From d36927a5ab8ebb3219b413197725b9561c0677d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 18:54:18 +0000 Subject: [PATCH 204/442] Bump solara from 1.42.0 to 1.43.0 Bumps [solara](https://github.com/widgetti/solara) from 1.42.0 to 1.43.0. - [Changelog](https://github.com/widgetti/solara/blob/master/CHANGELOG.md) - [Commits](https://github.com/widgetti/solara/compare/v1.42.0...v1.43.0) --- updated-dependencies: - dependency-name: solara dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- News_App/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/News_App/requirements.txt b/News_App/requirements.txt index a219c88721a..ec7e0dedb52 100644 --- a/News_App/requirements.txt +++ b/News_App/requirements.txt @@ -1,4 +1,4 @@ -solara == 1.42.0 +solara == 1.43.0 Flask gunicorn ==23.0.0 simple-websocket diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index d7eb7e8deba..1328a155ac0 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -74,7 +74,7 @@ xor-cipher==5.0.1 bird==0.1.2 mechanize==0.4.10 translate==3.6.1 -solara==1.42.0 +solara==1.43.0 pywhatkit==5.4 mutagen==1.47.0 Unidecode==1.3.8 From 317535b3a67235abd91c0d2a27ccf5861f43aa93 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Dec 2024 19:01:02 +0000 Subject: [PATCH 205/442] Bump pyglet from 2.0.17 to 2.0.20 Bumps [pyglet](https://github.com/pyglet/pyglet) from 2.0.17 to 2.0.20. - [Release notes](https://github.com/pyglet/pyglet/releases) - [Changelog](https://github.com/pyglet/pyglet/blob/master/RELEASE_NOTES) - [Commits](https://github.com/pyglet/pyglet/compare/v2.0.17...v2.0.20) --- updated-dependencies: - dependency-name: pyglet dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- PongPong_Game/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PongPong_Game/requirements.txt b/PongPong_Game/requirements.txt index 7903d4bcf0a..357442dd0e4 100644 --- a/PongPong_Game/requirements.txt +++ b/PongPong_Game/requirements.txt @@ -1 +1 @@ -pyglet==2.0.17 +pyglet==2.0.20 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 6c88bf97f35..25c20676a4b 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -55,7 +55,7 @@ pydantic==2.10.3 openpyxl==3.1.2 pytesseract==0.3.13 requests-mock==1.12.1 -pyglet==2.0.17 +pyglet==2.0.20 urllib3==2.3.0 thirdai==0.9.25 google-api-python-client==2.156.0 From af07824f1713053ad22706ca1e012cff60504e8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Dec 2024 19:01:07 +0000 Subject: [PATCH 206/442] Bump matplotlib from 3.9.2 to 3.10.0 Bumps [matplotlib](https://github.com/matplotlib/matplotlib) from 3.9.2 to 3.10.0. - [Release notes](https://github.com/matplotlib/matplotlib/releases) - [Commits](https://github.com/matplotlib/matplotlib/compare/v3.9.2...v3.10.0) --- updated-dependencies: - dependency-name: matplotlib dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 6c88bf97f35..831dc98a6f7 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -86,7 +86,7 @@ fitz==0.0.1.dev2 fastapi==0.115.6 Django==5.1.2 docx==0.2.4 -matplotlib==3.9.2 +matplotlib==3.10.0 pyshorteners==1.0.1 geocoder==1.38.1 APScheduler==3.11.0 From 733e2f2df57d00c2469c7d7a824ce514d51c5960 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jan 2025 18:53:01 +0000 Subject: [PATCH 207/442] Bump tqdm from 4.66.5 to 4.67.1 Bumps [tqdm](https://github.com/tqdm/tqdm) from 4.66.5 to 4.67.1. - [Release notes](https://github.com/tqdm/tqdm/releases) - [Commits](https://github.com/tqdm/tqdm/compare/v4.66.5...v4.67.1) --- updated-dependencies: - dependency-name: tqdm dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4afd234cc67..75f49c98377 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -64,7 +64,7 @@ xlwt==1.3.0 pygame==2.6.1 speechtotext==0.0.3 wikipedia==1.4.0 -tqdm==4.66.5 +tqdm==4.67.1 Menu==3.2.2 yfinance==0.2.51 tweepy==4.14.0 From 78fc938de8bee70ebf6b716b2c3b66479502b9fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jan 2025 18:53:07 +0000 Subject: [PATCH 208/442] Bump google-api-python-client from 2.156.0 to 2.157.0 Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.156.0 to 2.157.0. - [Release notes](https://github.com/googleapis/google-api-python-client/releases) - [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.156.0...v2.157.0) --- updated-dependencies: - dependency-name: google-api-python-client dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4afd234cc67..6f93979f537 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -58,7 +58,7 @@ requests-mock==1.12.1 pyglet==2.0.20 urllib3==2.3.0 thirdai==0.9.25 -google-api-python-client==2.156.0 +google-api-python-client==2.157.0 sound==0.1.0 xlwt==1.3.0 pygame==2.6.1 From b85bebccc6a986f24da4e9dca1a2ed77980e2c88 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 18:58:57 +0000 Subject: [PATCH 209/442] Bump openai from 1.58.1 to 1.59.3 Bumps [openai](https://github.com/openai/openai-python) from 1.58.1 to 1.59.3. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.58.1...v1.59.3) --- updated-dependencies: - dependency-name: openai dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4bd9bbfb551..0112b25dcbc 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.58.1 +openai==1.59.3 background==0.2.1 pydantic==2.10.3 openpyxl==3.1.2 From 0545222e77a3ba443854b2fb7dd432a6450764b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 18:59:03 +0000 Subject: [PATCH 210/442] Bump psutil from 6.1.0 to 6.1.1 Bumps [psutil](https://github.com/giampaolo/psutil) from 6.1.0 to 6.1.1. - [Changelog](https://github.com/giampaolo/psutil/blob/master/HISTORY.rst) - [Commits](https://github.com/giampaolo/psutil/compare/release-6.1.0...release-6.1.1) --- updated-dependencies: - dependency-name: psutil dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4bd9bbfb551..e14e179875f 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -101,7 +101,7 @@ pytest==8.3.4 qrcode==8.0 googletrans==3.0.0 slab==1.7.0 -psutil==6.1.0 +psutil==6.1.1 mediapipe==0.10.20 rich==13.9.4 httplib2==0.22.0 From 0e4acf7e70127e6c04dfe54d277cc8fcd1222903 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 18:15:12 +0000 Subject: [PATCH 211/442] Bump ccxt from 4.4.42 to 4.4.46 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.4.42 to 4.4.46. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.4.42...4.4.46) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index a851def8a0b..ba1319e7640 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.7 gTTS==2.5.4 -ccxt==4.4.42 +ccxt==4.4.46 fitz==0.0.1.dev2 fastapi==0.115.6 Django==5.1.2 From 1f4dd73d30b9868dd47fa966c31dd1f15cfbc027 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 18:15:27 +0000 Subject: [PATCH 212/442] Bump pillow from 11.0.0 to 11.1.0 Bumps [pillow](https://github.com/python-pillow/Pillow) from 11.0.0 to 11.1.0. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/11.0.0...11.1.0) --- updated-dependencies: - dependency-name: pillow dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- PDF/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PDF/requirements.txt b/PDF/requirements.txt index 76d05f3c672..f76ca036694 100644 --- a/PDF/requirements.txt +++ b/PDF/requirements.txt @@ -1,2 +1,2 @@ -Pillow==11.0.0 +Pillow==11.1.0 fpdf==1.7.2 \ No newline at end of file diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index a851def8a0b..a1a0b8d3441 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -31,7 +31,7 @@ pyserial==3.5 twilio==9.4.1 tabula==1.0.5 nltk==3.9.1 -Pillow==11.0.0 +Pillow==11.1.0 SocksiPy-branch==1.01 xlrd==2.0.1 fpdf==1.7.2 From 1bf55599952002cdf2a2e57cd37c877b3b4246b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jan 2025 19:02:21 +0000 Subject: [PATCH 213/442] Bump googletrans from 3.0.0 to 4.0.2 Bumps [googletrans](https://github.com/ssut/py-googletrans) from 3.0.0 to 4.0.2. - [Release notes](https://github.com/ssut/py-googletrans/releases) - [Commits](https://github.com/ssut/py-googletrans/commits) --- updated-dependencies: - dependency-name: googletrans dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index b7094b02971..eb1527732fd 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -99,7 +99,7 @@ tensorflow==2.15.0.post1 pandas==2.2.3 pytest==8.3.4 qrcode==8.0 -googletrans==3.0.0 +googletrans==4.0.2 slab==1.7.0 psutil==6.1.1 mediapipe==0.10.20 From 010baf81e9692845a209a5cbc5697a8584975e73 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jan 2025 19:02:27 +0000 Subject: [PATCH 214/442] Bump django from 5.1.2 to 5.1.4 Bumps [django](https://github.com/django/django) from 5.1.2 to 5.1.4. - [Commits](https://github.com/django/django/compare/5.1.2...5.1.4) --- updated-dependencies: - dependency-name: django dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index b7094b02971..78691c84f95 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -84,7 +84,7 @@ gTTS==2.5.4 ccxt==4.4.46 fitz==0.0.1.dev2 fastapi==0.115.6 -Django==5.1.2 +Django==5.1.4 docx==0.2.4 matplotlib==3.10.0 pyshorteners==1.0.1 From 2283281a0f25a910d6d0380a14a20fdb6307dad0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Jan 2025 18:08:09 +0000 Subject: [PATCH 215/442] Bump keras from 3.7.0 to 3.8.0 Bumps [keras](https://github.com/keras-team/keras) from 3.7.0 to 3.8.0. - [Release notes](https://github.com/keras-team/keras/releases) - [Commits](https://github.com/keras-team/keras/compare/v3.7.0...v3.8.0) --- updated-dependencies: - dependency-name: keras dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index b2b8d720f58..da2d06a9098 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -41,7 +41,7 @@ tornado==6.4.2 obs==0.0.0 todo==0.1 oauth2client==4.1.3 -keras==3.7.0 +keras==3.8.0 pymongo==4.10.1 playsound==1.3.0 pyttsx3==2.98 From 95346003f4876620496eb9d75dd0eabb21043bd9 Mon Sep 17 00:00:00 2001 From: Boreas Date: Fri, 10 Jan 2025 00:51:36 +0300 Subject: [PATCH 216/442] Update requirements.txt --- CliYoutubeDownloader/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CliYoutubeDownloader/requirements.txt b/CliYoutubeDownloader/requirements.txt index cd5e770101f..9a9d50658dc 100644 --- a/CliYoutubeDownloader/requirements.txt +++ b/CliYoutubeDownloader/requirements.txt @@ -1 +1 @@ -pytube +pytubefix From 3e4d766fd993642b28016b5fc8b6229888b97b1a Mon Sep 17 00:00:00 2001 From: Boreas Date: Fri, 10 Jan 2025 00:51:58 +0300 Subject: [PATCH 217/442] Update CliYoutubeDownloader.py --- CliYoutubeDownloader/CliYoutubeDownloader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CliYoutubeDownloader/CliYoutubeDownloader.py b/CliYoutubeDownloader/CliYoutubeDownloader.py index d155f25cf0f..2af607ad5ae 100644 --- a/CliYoutubeDownloader/CliYoutubeDownloader.py +++ b/CliYoutubeDownloader/CliYoutubeDownloader.py @@ -1,6 +1,6 @@ # libraraies -import pytube +import pytubefix import sys From 241ffcd96d2fc912aff5146d358a80141afb8d96 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jan 2025 18:41:06 +0000 Subject: [PATCH 218/442] Bump openai from 1.59.3 to 1.59.6 Bumps [openai](https://github.com/openai/openai-python) from 1.59.3 to 1.59.6. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.59.3...v1.59.6) --- updated-dependencies: - dependency-name: openai dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index b2b8d720f58..1df0d3e35d3 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.59.3 +openai==1.59.6 background==0.2.1 pydantic==2.10.3 openpyxl==3.1.2 From ae7ff23d6314152a6123aa04be04f84a3caa8de3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 18:07:30 +0000 Subject: [PATCH 219/442] Bump google-api-python-client from 2.157.0 to 2.158.0 Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.157.0 to 2.158.0. - [Release notes](https://github.com/googleapis/google-api-python-client/releases) - [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.157.0...v2.158.0) --- updated-dependencies: - dependency-name: google-api-python-client dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index bd5d10d7e95..6199c785e3c 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -58,7 +58,7 @@ requests-mock==1.12.1 pyglet==2.0.20 urllib3==2.3.0 thirdai==0.9.25 -google-api-python-client==2.157.0 +google-api-python-client==2.158.0 sound==0.1.0 xlwt==1.3.0 pygame==2.6.1 From 381e17c19685bb106a9c1b7011ce38ac89f2a573 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 18:07:34 +0000 Subject: [PATCH 220/442] Bump ccxt from 4.4.46 to 4.4.47 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.4.46 to 4.4.47. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.4.46...4.4.47) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index bd5d10d7e95..902e32ed0d2 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.7 gTTS==2.5.4 -ccxt==4.4.46 +ccxt==4.4.47 fitz==0.0.1.dev2 fastapi==0.115.6 Django==5.1.4 From 511a5f8230483a01c4b8fd77f783af7bd574f1d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 18:23:40 +0000 Subject: [PATCH 221/442] Bump twilio from 9.4.1 to 9.4.3 Bumps [twilio](https://github.com/twilio/twilio-python) from 9.4.1 to 9.4.3. - [Release notes](https://github.com/twilio/twilio-python/releases) - [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md) - [Commits](https://github.com/twilio/twilio-python/compare/9.4.1...9.4.3) --- updated-dependencies: - dependency-name: twilio dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 1df2cdae4b1..db35b5295b5 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -28,7 +28,7 @@ requests==2.32.3 quo==2023.5.1 PyPDF2==3.0.1 pyserial==3.5 -twilio==9.4.1 +twilio==9.4.3 tabula==1.0.5 nltk==3.9.1 Pillow==11.1.0 From 823ef49c58f00c4bfebbf44b9983424435ca0783 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 18:23:55 +0000 Subject: [PATCH 222/442] Bump django from 5.1.4 to 5.1.5 Bumps [django](https://github.com/django/django) from 5.1.4 to 5.1.5. - [Commits](https://github.com/django/django/compare/5.1.4...5.1.5) --- updated-dependencies: - dependency-name: django dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 1df2cdae4b1..37f72fc7167 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -84,7 +84,7 @@ gTTS==2.5.4 ccxt==4.4.47 fitz==0.0.1.dev2 fastapi==0.115.6 -Django==5.1.4 +Django==5.1.5 docx==0.2.4 matplotlib==3.10.0 pyshorteners==1.0.1 From 0ffdf6419268600eb01be124dd5065be88e1c75a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Jan 2025 18:27:21 +0000 Subject: [PATCH 223/442] Bump emoji from 2.14.0 to 2.14.1 Bumps [emoji](https://github.com/carpedm20/emoji) from 2.14.0 to 2.14.1. - [Release notes](https://github.com/carpedm20/emoji/releases) - [Changelog](https://github.com/carpedm20/emoji/blob/master/CHANGES.md) - [Commits](https://github.com/carpedm20/emoji/compare/v2.14.0...v2.14.1) --- updated-dependencies: - dependency-name: emoji dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index c6ed62a4928..0b6c6b5ce0e 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -109,5 +109,5 @@ protobuf==5.29.2 colorama==0.4.6 plyer==2.1.0 Flask-Ask==0.9.8 -emoji==2.14.0 +emoji==2.14.1 PyAutoGUI==0.9.54 From af0ca508faf16c585d660cddbcee02ab6368a9d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Jan 2025 18:27:26 +0000 Subject: [PATCH 224/442] Bump ccxt from 4.4.47 to 4.4.49 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.4.47 to 4.4.49. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.4.47...4.4.49) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index c6ed62a4928..8a7b34011d8 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.7 gTTS==2.5.4 -ccxt==4.4.47 +ccxt==4.4.49 fitz==0.0.1.dev2 fastapi==0.115.6 Django==5.1.5 From b7b4fa73b11f7246b51dc7c576fabe46bd4584d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 18:24:14 +0000 Subject: [PATCH 225/442] Bump protobuf from 5.29.2 to 5.29.3 Bumps [protobuf](https://github.com/protocolbuffers/protobuf) from 5.29.2 to 5.29.3. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v5.29.2...v5.29.3) --- updated-dependencies: - dependency-name: protobuf dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index d310b9bb618..6036bb9c830 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -105,7 +105,7 @@ psutil==6.1.1 mediapipe==0.10.20 rich==13.9.4 httplib2==0.22.0 -protobuf==5.29.2 +protobuf==5.29.3 colorama==0.4.6 plyer==2.1.0 Flask-Ask==0.9.8 From e715e8ea29624416d5e073fc4964e1f4ef6fd4ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 18:24:21 +0000 Subject: [PATCH 226/442] Bump pyglet from 2.0.20 to 2.1.1 Bumps [pyglet](https://github.com/pyglet/pyglet) from 2.0.20 to 2.1.1. - [Release notes](https://github.com/pyglet/pyglet/releases) - [Changelog](https://github.com/pyglet/pyglet/blob/master/RELEASE_NOTES) - [Commits](https://github.com/pyglet/pyglet/compare/v2.0.20...v2.1.1) --- updated-dependencies: - dependency-name: pyglet dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- PongPong_Game/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PongPong_Game/requirements.txt b/PongPong_Game/requirements.txt index 357442dd0e4..de35804cc81 100644 --- a/PongPong_Game/requirements.txt +++ b/PongPong_Game/requirements.txt @@ -1 +1 @@ -pyglet==2.0.20 +pyglet==2.1.1 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index d310b9bb618..8040a64a00d 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -55,7 +55,7 @@ pydantic==2.10.3 openpyxl==3.1.2 pytesseract==0.3.13 requests-mock==1.12.1 -pyglet==2.0.20 +pyglet==2.1.1 urllib3==2.3.0 thirdai==0.9.25 google-api-python-client==2.158.0 From b707619d418b05bd19a388ff6a0ffe6609c21058 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Jan 2025 18:10:59 +0000 Subject: [PATCH 227/442] Bump opencv-python from 4.10.0.84 to 4.11.0.86 Bumps [opencv-python](https://github.com/opencv/opencv-python) from 4.10.0.84 to 4.11.0.86. - [Release notes](https://github.com/opencv/opencv-python/releases) - [Commits](https://github.com/opencv/opencv-python/commits) --- updated-dependencies: - dependency-name: opencv-python dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Hand-Motion-Detection/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt index 3ac1b2a3429..23af46531b0 100644 --- a/Hand-Motion-Detection/requirements.txt +++ b/Hand-Motion-Detection/requirements.txt @@ -1,3 +1,3 @@ numpy==2.2.1 -opencv_python==4.10.0.84 +opencv_python==4.11.0.86 mediapipe==0.10.20 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 8040a64a00d..ce8e7380668 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -94,7 +94,7 @@ PyQRCode==1.2.1 freegames==2.5.3 pyperclip==1.8.2 newspaper==0.1.0.7 -opencv-python==4.10.0.84 +opencv-python==4.11.0.86 tensorflow==2.15.0.post1 pandas==2.2.3 pytest==8.3.4 From 8dd1d698823402bfb9d22efbf7c037ac5f7c9b27 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 18:24:54 +0000 Subject: [PATCH 228/442] Bump tweepy from 4.14.0 to 4.15.0 Bumps [tweepy](https://github.com/tweepy/tweepy) from 4.14.0 to 4.15.0. - [Release notes](https://github.com/tweepy/tweepy/releases) - [Changelog](https://github.com/tweepy/tweepy/blob/master/docs/changelog.md) - [Commits](https://github.com/tweepy/tweepy/compare/v4.14.0...v4.15.0) --- updated-dependencies: - dependency-name: tweepy dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index ce8e7380668..1f2c10d3246 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -67,7 +67,7 @@ wikipedia==1.4.0 tqdm==4.67.1 Menu==3.2.2 yfinance==0.2.51 -tweepy==4.14.0 +tweepy==4.15.0 tkcalendar==1.6.1 pytube==15.0.0 xor-cipher==5.0.1 From c95375c55b527a117ac9ef53acdab37ae1fd9475 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Jan 2025 18:06:20 +0000 Subject: [PATCH 229/442] Bump numpy from 2.2.1 to 2.2.2 Bumps [numpy](https://github.com/numpy/numpy) from 2.2.1 to 2.2.2. - [Release notes](https://github.com/numpy/numpy/releases) - [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst) - [Commits](https://github.com/numpy/numpy/compare/v2.2.1...v2.2.2) --- updated-dependencies: - dependency-name: numpy dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Hand-Motion-Detection/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt index 23af46531b0..5a3a516abb1 100644 --- a/Hand-Motion-Detection/requirements.txt +++ b/Hand-Motion-Detection/requirements.txt @@ -1,3 +1,3 @@ -numpy==2.2.1 +numpy==2.2.2 opencv_python==4.11.0.86 mediapipe==0.10.20 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 1f2c10d3246..c1fcd445f3f 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -15,7 +15,7 @@ dictator==0.3.1 caller==0.0.2 watchdog==6.0.0 PyQt5==5.15.11 -numpy==2.2.1 +numpy==2.2.2 fileinfo==0.3.3 backend==0.2.4.1 win10toast==0.9 From 23af3070748a519484d3ccf729d7edc21480b57c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 Jan 2025 18:40:46 +0000 Subject: [PATCH 230/442] Bump ccxt from 4.4.49 to 4.4.52 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.4.49 to 4.4.52. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.4.49...4.4.52) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index c1fcd445f3f..47a6ae39197 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.7 gTTS==2.5.4 -ccxt==4.4.49 +ccxt==4.4.52 fitz==0.0.1.dev2 fastapi==0.115.6 Django==5.1.5 From 23da936cd6caf3f652f0b94bab46155ea90b1737 Mon Sep 17 00:00:00 2001 From: dendogg Date: Mon, 3 Feb 2025 13:03:31 -0800 Subject: [PATCH 231/442] Update multicoloredline.py - Migrated from `quo` to `rich` for better terminal output and functionality. - Added **syntax-highlighted JSON** output using `rich.syntax.Syntax. - Implemented **progress bar** with animated spinner using `rich.progress.Progress. - Introduced **structured table display** with `rich.table.Table` for system metrics. - Enhanced user feedback with a **completion success message**. - Improved readability and interactivity for a better terminal experience. --- Colors/multicoloredline.py | 56 ++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/Colors/multicoloredline.py b/Colors/multicoloredline.py index 09f5361e990..fdbe1c45881 100644 --- a/Colors/multicoloredline.py +++ b/Colors/multicoloredline.py @@ -1,8 +1,54 @@ -## This script prints a multicolored line -# quo can be installed using pip - -from quo.console import Console +from rich.console import Console +from rich.syntax import Syntax +from rich.progress import Progress, SpinnerColumn, BarColumn, TextColumn +from rich.table import Table +import time +import json console = Console() -console.rule(multiclored=True) +# Fancy separator +console.rule("[bold]Welcome to Rich Terminal[/bold]", style="rainbow") + +# Define some JSON data +json_data = { + "message": "Hello, World!", + "status": "success", + "code": 200 +} + +# Print JSON with syntax highlighting +syntax = Syntax(json.dumps(json_data, indent=4), "json", theme="monokai", line_numbers=True) +console.print(syntax) + +# Simulating a progress bar +console.print("\n[bold cyan]Processing data...[/bold cyan]\n") + +with Progress( + SpinnerColumn(), + TextColumn("[progress.description]{task.description}"), + BarColumn(), + TextColumn("{task.percentage:>3.0f}%"), + console=console, +) as progress: + task = progress.add_task("[cyan]Loading...", total=100) + for _ in range(100): + time.sleep(0.02) + progress.update(task, advance=1) + +# Create a rich table +console.print("\n[bold magenta]Results Summary:[/bold magenta]\n") + +table = Table(title="System Report", show_header=True, header_style="bold cyan") +table.add_column("Metric", style="bold yellow") +table.add_column("Value", justify="right", style="bold green") + +table.add_row("CPU Usage", "12.5%") +table.add_row("Memory Usage", "68.3%") +table.add_row("Disk Space", "45.7% free") + +console.print(table) + +# Success message +console.print("\n[bold green]🎉 Process completed successfully![/bold green]\n") +console.rule(style="rainbow") From fd26eccd34a2338f6baa515c6511f94e2da1dda8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Feb 2025 18:58:51 +0000 Subject: [PATCH 232/442] Bump beautifulsoup4 from 4.12.3 to 4.13.3 Bumps [beautifulsoup4](https://www.crummy.com/software/BeautifulSoup/bs4/) from 4.12.3 to 4.13.3. --- updated-dependencies: - dependency-name: beautifulsoup4 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 47a6ae39197..7260584907b 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -10,7 +10,7 @@ Tubes==0.2.1 modules==1.0.0 pdf2docx==0.5.8 pong==1.5 -beautifulsoup4==4.12.3 +beautifulsoup4==4.13.3 dictator==0.3.1 caller==0.0.2 watchdog==6.0.0 From f0396fb14ed91b7cc99ddbff87e407e6f3fd51a4 Mon Sep 17 00:00:00 2001 From: Siddharth Mehta Date: Thu, 6 Feb 2025 01:04:06 -0500 Subject: [PATCH 233/442] Update backend.py --- BrowserHistory/backend.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/BrowserHistory/backend.py b/BrowserHistory/backend.py index 5eed004cbf2..11e7edfef91 100644 --- a/BrowserHistory/backend.py +++ b/BrowserHistory/backend.py @@ -2,7 +2,8 @@ class DLL: """ a doubly linked list that holds the current page, next page, and previous page. - Used to enforce order in operations + Used to enforce order in operations. + This is a change to the file """ def __init__(self, val: str =None): self.val = val @@ -78,4 +79,4 @@ def forward(self, steps: int) -> str: param_3 = obj.forward(1) print(param_2) - print(param_3) \ No newline at end of file + print(param_3) From 0ad2a2af5a263893f2426a1192cf7e2a5a64c6fe Mon Sep 17 00:00:00 2001 From: "devloai[bot]" <168258904+devloai[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 06:28:40 +0000 Subject: [PATCH 234/442] Optimize BrowserHistory implementation with memory management and performance improvements - Add _forward_count and _back_count to track available steps - Clear forward history in visit() to prevent memory leaks - Optimize back() and forward() with step counting - Update docstrings and improve code quality --- BrowserHistory/backend.py | 62 ++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/BrowserHistory/backend.py b/BrowserHistory/backend.py index 11e7edfef91..89df7a0da8b 100644 --- a/BrowserHistory/backend.py +++ b/BrowserHistory/backend.py @@ -3,7 +3,6 @@ class DLL: a doubly linked list that holds the current page, next page, and previous page. Used to enforce order in operations. - This is a change to the file """ def __init__(self, val: str =None): self.val = val @@ -15,19 +14,23 @@ class BrowserHistory: """ This class designs the operations of a browser history - It works by using a doubly linked list to hold the urls + It works by using a doubly linked list to hold the urls with optimized + navigation using step counters and memory management """ def __init__(self, homepage: str): """ Returns - None - Input - None + Input - str ---------- - Initialize doubly linked list which will serve as the browser history and sets the current page + - Initialize navigation counters """ - self.head = DLL(homepage) - self.curr = self.head + self._head = DLL(homepage) + self._curr = self._head + self._back_count = 0 + self._forward_count = 0 def visit(self, url: str) -> None: """ @@ -35,41 +38,58 @@ def visit(self, url: str) -> None: Input - str ---------- - Adds the current url to the DLL - - sets both the next and previous values + - Sets both the next and previous values + - Cleans up forward history to prevent memory leaks + - Resets forward count and increments back count """ - url_node = DLL(url) - self.curr.nxt = url_node - url_node.prev = self.curr + # Clear forward history to prevent memory leaks + self._curr.nxt = None + self._forward_count = 0 - self.curr = url_node + # Create and link new node + url_node = DLL(url) + self._curr.nxt = url_node + url_node.prev = self._curr + # Update current node and counts + self._curr = url_node + self._back_count += 1 def back(self, steps: int) -> str: """ Returns - str Input - int ---------- - - Iterates through the DLL backwards `step` number of times - - returns the appropriate value + - Moves backwards through history up to available steps + - Updates navigation counters + - Returns current page URL """ - while steps > 0 and self.curr.prev: - self.curr = self.curr.prev + # Only traverse available nodes + steps = min(steps, self._back_count) + while steps > 0: + self._curr = self._curr.prev steps -= 1 - return self.curr.val - + self._back_count -= 1 + self._forward_count += 1 + return self._curr.val def forward(self, steps: int) -> str: """ Returns - str Input - int ---------- - - Iterates through the DLL forewards `step` number of times - - returns the appropriate value + - Moves forward through history up to available steps + - Updates navigation counters + - Returns current page URL """ - while steps > 0 and self.curr.nxt: - self.curr = self.curr.nxt + # Only traverse available nodes + steps = min(steps, self._forward_count) + while steps > 0: + self._curr = self._curr.nxt steps -= 1 - return self.curr.val + self._forward_count -= 1 + self._back_count += 1 + return self._curr.val if __name__ == "__main__": From 4b0cff758dde9b5f213402cc12de9851f099d7ed Mon Sep 17 00:00:00 2001 From: "devloai[bot]" <168258904+devloai[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 06:36:30 +0000 Subject: [PATCH 235/442] Add unit tests for browser history functionality --- BrowserHistory/tests/test_browser_history.py | 91 ++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 BrowserHistory/tests/test_browser_history.py diff --git a/BrowserHistory/tests/test_browser_history.py b/BrowserHistory/tests/test_browser_history.py new file mode 100644 index 00000000000..829f326c238 --- /dev/null +++ b/BrowserHistory/tests/test_browser_history.py @@ -0,0 +1,91 @@ +import unittest +import sys +import os + +# Add parent directory to path to import backend +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +from backend import BrowserHistory + +class TestBrowserHistory(unittest.TestCase): + def setUp(self): + """Set up test cases""" + self.browser = BrowserHistory("homepage.com") + + def test_initialization(self): + """Test proper initialization of BrowserHistory""" + self.assertEqual(self.browser._curr.val, "homepage.com") + self.assertEqual(self.browser._back_count, 0) + self.assertEqual(self.browser._forward_count, 0) + self.assertIsNone(self.browser._curr.nxt) + self.assertIsNone(self.browser._curr.prev) + + def test_visit(self): + """Test visit functionality and forward history cleanup""" + self.browser.visit("page1.com") + self.assertEqual(self.browser._curr.val, "page1.com") + self.assertEqual(self.browser._back_count, 1) + self.assertEqual(self.browser._forward_count, 0) + + # Test forward history cleanup + self.browser.visit("page2.com") + self.browser.back(1) + self.browser.visit("page3.com") # Should clear forward history + self.assertIsNone(self.browser._curr.nxt) + self.assertEqual(self.browser._forward_count, 0) + + def test_back_navigation(self): + """Test back navigation with counter validation""" + # Setup history + self.browser.visit("page1.com") + self.browser.visit("page2.com") + + # Test normal back navigation + result = self.browser.back(1) + self.assertEqual(result, "page1.com") + self.assertEqual(self.browser._back_count, 1) + self.assertEqual(self.browser._forward_count, 1) + + # Test back with more steps than available + result = self.browser.back(5) # Should only go back 1 step + self.assertEqual(result, "homepage.com") + self.assertEqual(self.browser._back_count, 0) + self.assertEqual(self.browser._forward_count, 2) + + def test_forward_navigation(self): + """Test forward navigation with counter validation""" + # Setup history and position + self.browser.visit("page1.com") + self.browser.visit("page2.com") + self.browser.back(2) # Go back to homepage + + # Test normal forward navigation + result = self.browser.forward(1) + self.assertEqual(result, "page1.com") + self.assertEqual(self.browser._forward_count, 1) + self.assertEqual(self.browser._back_count, 1) + + # Test forward with more steps than available + result = self.browser.forward(5) # Should only go forward remaining 1 step + self.assertEqual(result, "page2.com") + self.assertEqual(self.browser._forward_count, 0) + self.assertEqual(self.browser._back_count, 2) + + def test_complex_navigation(self): + """Test complex navigation patterns""" + self.browser.visit("page1.com") + self.browser.visit("page2.com") + self.browser.visit("page3.com") + + # Back navigation + self.assertEqual(self.browser.back(2), "page1.com") + + # New visit should clear forward history + self.browser.visit("page4.com") + self.assertEqual(self.browser._forward_count, 0) + self.assertIsNone(self.browser._curr.nxt) + + # Verify we can't go forward to cleared history + self.assertEqual(self.browser.forward(1), "page4.com") + +if __name__ == '__main__': + unittest.main() \ No newline at end of file From f105beb5de58e55e26c355bded1fd47e9d6c9c74 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Feb 2025 19:02:08 +0000 Subject: [PATCH 236/442] Bump google-api-python-client from 2.158.0 to 2.160.0 Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.158.0 to 2.160.0. - [Release notes](https://github.com/googleapis/google-api-python-client/releases) - [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.158.0...v2.160.0) --- updated-dependencies: - dependency-name: google-api-python-client dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 7260584907b..7b1873d3941 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -58,7 +58,7 @@ requests-mock==1.12.1 pyglet==2.1.1 urllib3==2.3.0 thirdai==0.9.25 -google-api-python-client==2.158.0 +google-api-python-client==2.160.0 sound==0.1.0 xlwt==1.3.0 pygame==2.6.1 From 46e85b702cc1da83604af2a9df3c40c56ff87eed Mon Sep 17 00:00:00 2001 From: malak495 Date: Fri, 7 Feb 2025 22:42:03 +0100 Subject: [PATCH 237/442] Update Memory_game.py --- Memory_game.py | 179 ++++++++++++++++++++++++++++++------------------- 1 file changed, 110 insertions(+), 69 deletions(-) diff --git a/Memory_game.py b/Memory_game.py index aca7f2fe81c..47d51808fb1 100644 --- a/Memory_game.py +++ b/Memory_game.py @@ -1,71 +1,112 @@ import random +import pygame +import sys -import simplegui - - -def new_game(): - global card3, po, state, exposed, card1 - - def create(card): - while len(card) != 8: - num = random.randrange(0, 8) - if num not in card: - card.append(num) - return card - - card3 = [] - card1 = [] - card2 = [] - po = [] - card1 = create(card1) - card2 = create(card2) - card1.extend(card2) - random.shuffle(card1) - state = 0 - exposed = [] - for i in range(0, 16, 1): - exposed.insert(i, False) - - -def mouseclick(pos): - global card3, po, state, exposed, card1 - if state == 2: - if card3[0] != card3[1]: - exposed[po[0]] = False - exposed[po[1]] = False - card3 = [] - state = 0 - po = [] - ind = pos[0] // 50 - card3.append(card1[ind]) - po.append(ind) - if exposed[ind] == False and state < 2: - exposed[ind] = True - state += 1 - - -def draw(canvas): - global card1 - gap = 0 - for i in range(0, 16, 1): - if exposed[i] == False: - canvas.draw_polygon( - [[0 + gap, 0], [0 + gap, 100], [50 + gap, 100], [50 + gap, 0]], - 1, - "Black", - "Green", - ) - elif exposed[i] == True: - canvas.draw_text(str(card1[i]), [15 + gap, 65], 50, "White") - gap += 50 - - -frame = simplegui.create_frame("Memory", 800, 100) -frame.add_button("Reset", new_game) -label = frame.add_label("Turns = 0") - -frame.set_mouseclick_handler(mouseclick) -frame.set_draw_handler(draw) - -new_game() -frame.start() +# Initialisation de pygame +pygame.init() + +# Définir les couleurs +WHITE = (255, 255, 255) +PASTEL_PINK = (255, 182, 193) +PINK = (255, 105, 180) +LIGHT_PINK = (255, 182, 193) +GREY = (169, 169, 169) + +# Définir les dimensions de la fenêtre +WIDTH = 600 +HEIGHT = 600 +FPS = 30 +CARD_SIZE = 100 + +# Créer la fenêtre +screen = pygame.display.set_mode((WIDTH, HEIGHT)) +pygame.display.set_caption("Memory Game : Les Préférences de Malak") + +# Charger les polices +font = pygame.font.Font(None, 40) +font_small = pygame.font.Font(None, 30) + +# Liste des questions et réponses (préférences) +questions = [ + {"question": "Quelle est sa couleur préférée ?", "réponse": "Rose", "image": "rose.jpg"}, + {"question": "Quel est son plat préféré ?", "réponse": "Pizza", "image": "pizza.jpg"}, + {"question": "Quel est son animal préféré ?", "réponse": "Chat", "image": "chat.jpg"}, + {"question": "Quel est son film préféré ?", "réponse": "La La Land", "image": "lalaland.jpg"} +] + +# Créer les cartes avec des questions et réponses +cards = [] +for q in questions: + cards.append(q["réponse"]) + cards.append(q["réponse"]) + +# Mélanger les cartes +random.shuffle(cards) + +# Créer un dictionnaire pour les positions des cartes +card_positions = [(x * CARD_SIZE, y * CARD_SIZE) for x in range(4) for y in range(4)] + +# Fonction pour afficher le texte +def display_text(text, font, color, x, y): + text_surface = font.render(text, True, color) + screen.blit(text_surface, (x, y)) + +# Fonction pour dessiner les cartes +def draw_cards(): + for idx, pos in enumerate(card_positions): + x, y = pos + if visible[idx]: + pygame.draw.rect(screen, WHITE, pygame.Rect(x, y, CARD_SIZE, CARD_SIZE)) + display_text(cards[idx], font, PINK, x + 10, y + 30) + else: + pygame.draw.rect(screen, LIGHT_PINK, pygame.Rect(x, y, CARD_SIZE, CARD_SIZE)) + pygame.draw.rect(screen, GREY, pygame.Rect(x, y, CARD_SIZE, CARD_SIZE), 5) + +# Variables du jeu +visible = [False] * len(cards) +flipped_cards = [] +score = 0 + +# Boucle principale du jeu +running = True +while running: + screen.fill(PASTEL_PINK) + draw_cards() + display_text("Score: " + str(score), font_small, PINK, 20, 20) + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + if event.type == pygame.MOUSEBUTTONDOWN: + x, y = pygame.mouse.get_pos() + col = x // CARD_SIZE + row = y // CARD_SIZE + card_idx = row * 4 + col + + if not visible[card_idx]: + visible[card_idx] = True + flipped_cards.append(card_idx) + + if len(flipped_cards) == 2: + if cards[flipped_cards[0]] == cards[flipped_cards[1]]: + score += 1 + else: + pygame.time.delay(1000) + visible[flipped_cards[0]] = visible[flipped_cards[1]] = False + flipped_cards.clear() + + if score == len(questions): + display_text("Félicitations ! Vous êtes officiellement le plus grand fan de Malak.", font, PINK, 100, HEIGHT // 2) + display_text("Mais… Pour accéder au prix ultime (photo ultra exclusive + certificat de starlette n°1),", font_small, PINK, 30, HEIGHT // 2 + 40) + display_text("veuillez envoyer 1000$ à Malak Inc.", font_small, PINK, 150, HEIGHT // 2 + 70) + display_text("(paiement accepté en chocolat, câlins ou virement bancaire immédiat)", font_small, PINK, 100, HEIGHT // 2 + 100) + pygame.display.update() + pygame.time.delay(3000) + running = False + + pygame.display.update() + pygame.time.Clock().tick(FPS) + +# Quitter pygame +pygame.quit() +sys.exit() From 8cf2bb690d38ec3c6cc81bef799b840b261c7dab Mon Sep 17 00:00:00 2001 From: Mugen Date: Mon, 10 Feb 2025 20:50:43 +0530 Subject: [PATCH 238/442] Sorting Algorithms Contains some of the most popular sorting algorithms --- sorting_algos.py | 121 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 sorting_algos.py diff --git a/sorting_algos.py b/sorting_algos.py new file mode 100644 index 00000000000..d34169a5141 --- /dev/null +++ b/sorting_algos.py @@ -0,0 +1,121 @@ +'''Contains some of the Major Sorting Algorithm''' + +def selection_sort(arr : list) -> list: + '''TC : O(n^2) + SC : O(1)''' + n = len(arr) + for i in range( n): + for j in range(i+1 , n): + if arr[i] > arr[j]: + arr[i] , arr[j] = arr[j] , arr[i] + return arr + +def bubble_sort(arr : list) -> list: + '''TC : O(n^2) + SC : O(1)''' + n = len(arr) + flag = True + while flag: + flag = False + for i in range(1 , n): + if arr[i-1] > arr[i]: + flag = True + arr[i-1] , arr[i] = arr[i] , arr[i-1] + return arr + +def insertion_sort(arr : list) -> list: + '''TC : O(n^2) + SC : O(1)''' + n = len(arr) + for i in range(1, n): + for j in range(i , 0 , -1): + if arr[j-1] > arr[j]: + arr[j-1] , arr[j] = arr[j] , arr[j-1] + else : + break + return arr + +def merge_sort(arr : list) -> list: + '''TC : O(nlogn) + SC : O(n) for this version ... But SC can be reduced to O(1)''' + n = len(arr) + if n == 1: return arr + + m = len(arr) // 2 + L = arr[:m] + R = arr[m:] + L = merge_sort(L) + R = merge_sort(R) + l = r = 0 + + sorted_arr = [0] * n + i = 0 + + while l < len(L) and r < len(R): + if L[l] < R[r]: + sorted_arr[i] = L[l] + l += 1 + else : + sorted_arr[i] = R[r] + r += 1 + i += 1 + + while l < len(L): + sorted_arr[i] = L[l] + l += 1 + i += 1 + + while r < len(R): + sorted_arr[i] = R[r] + r += 1 + i += 1 + + return arr + +def quick_sort(arr : list) -> list: + '''TC : O(nlogn) (TC can be n^2 for SUUUper worst case i.e. If the Pivot is continuously bad) + SC : O(n) for this version ... But SC can be reduced to O(logn)''' + + if len(arr) <= 1: return arr + + piv = arr[-1] + L = [x for x in arr[:-1] if x <= piv] + R = [x for x in arr[:-1] if x > piv] + + L , R = quick_sort(L) , quick_sort(L) + + return L + [piv] + R + +def counting_sort(arr : list) -> list: + '''This Works only for Positive int's(+ve), but can be modified for Negative's also + + TC : O(n) + SC : O(n)''' + n = len(arr) + maxx = max(arr) + counts = [0] * (maxx + 1) + for x in arr: + counts[x] += 1 + + i = 0 + for c in range(maxx + 1): + while counts[c] > 0: + arr[i] = c + i += 1 + counts[c] -= 1 + return arr + +def main(): + algos = {'selection_sort' : ['TC : O(n^2)','SC : O(1)'], + 'bubble_sort' : ['TC : O(n^2)','SC : O(1)'], + 'insertion_sort' : ['TC : O(n^2)','SC : O(1)'], + 'merge_sort' : ['TC : O(n^2)','SC : O(1)'], + 'quick_sort' : ['TC : O(n^2)','SC : O(1)'], + 'counting_sort' : ['TC : O(n^2)','SC : O(1)'],} + + inp = [1 , 2 ,7 , -8 , 34 , 2 , 80 , 790 , 6] + arr = counting_sort(inp) + print('U are amazing, Keep up') + +if __name__ == '__main__': + main() \ No newline at end of file From b48638b112ce6b970b00dbf8b7804e2a744963a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 18:59:24 +0000 Subject: [PATCH 239/442] Bump aiohttp from 3.11.11 to 3.11.12 --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- async_downloader/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/async_downloader/requirements.txt b/async_downloader/requirements.txt index eefc3748c6c..f06bf02f4d5 100644 --- a/async_downloader/requirements.txt +++ b/async_downloader/requirements.txt @@ -1 +1 @@ -aiohttp==3.11.11 +aiohttp==3.11.12 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 7b1873d3941..3ddc49d3be7 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -1,5 +1,5 @@ pafy==0.5.5 -aiohttp==3.11.11 +aiohttp==3.11.12 fuzzywuzzy==0.18.0 hupper==1.12.1 seaborn==0.13.2 From 0ea90b16d7fcac663c12da34fffb9a431c978a93 Mon Sep 17 00:00:00 2001 From: Mugen Date: Tue, 11 Feb 2025 02:53:36 +0530 Subject: [PATCH 240/442] Create LinkedList all types A directory for all types of Linked Lists --- LinkedList all types | 1 + 1 file changed, 1 insertion(+) create mode 100644 LinkedList all types diff --git a/LinkedList all types b/LinkedList all types new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/LinkedList all types @@ -0,0 +1 @@ + From 49616d42374735198476c10acd510a49f5ebaa92 Mon Sep 17 00:00:00 2001 From: Mugen Date: Tue, 11 Feb 2025 03:01:45 +0530 Subject: [PATCH 241/442] Delete LinkedList all types --- LinkedList all types | 1 - 1 file changed, 1 deletion(-) delete mode 100644 LinkedList all types diff --git a/LinkedList all types b/LinkedList all types deleted file mode 100644 index 8b137891791..00000000000 --- a/LinkedList all types +++ /dev/null @@ -1 +0,0 @@ - From 6fdba651eba069652e3e1bbafdf5eaa99f1f2e51 Mon Sep 17 00:00:00 2001 From: Mugen Date: Tue, 11 Feb 2025 03:08:36 +0530 Subject: [PATCH 242/442] Create singly_linked_list.py Cotains most of the Functions of the singly linked list --- LinkedLists all Types/singly_linked_list.py | 234 ++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 LinkedLists all Types/singly_linked_list.py diff --git a/LinkedLists all Types/singly_linked_list.py b/LinkedLists all Types/singly_linked_list.py new file mode 100644 index 00000000000..abc10d897bd --- /dev/null +++ b/LinkedLists all Types/singly_linked_list.py @@ -0,0 +1,234 @@ +'''Contains Most of the Singly Linked List functions.\n +'variable_name' = singly_linked_list.LinkedList() to use this an external module.\n +'variable_name'.insert_front('element') \t,'variable_name'.insert_back('element'),\n +'variable_name'.pop_front() are some of its functions.\n +To print all of its Functions use print('variable_name'.__dir__()).\n +Note:- 'variable_name' = singly_linked_list.LinkedList() This line is Important before using any of the function. + +Author :- Mugen https://github.com/Mugendesu +''' + +class Node: + def __init__(self, val=None , next = None ): + self.data = val + self.next = next + +class LinkedList: + + def __init__(self): + self.head = self.tail = None + self.length = 0 + + def insert_front(self , data): + node = Node(data , self.head) + if self.head == None: + self.tail = node + self.head = node + self.length += 1 + + def insert_back(self , data): + node = Node(data ) + if self.head == None: + self.tail = self.head = node + self.length += 1 + else: + self.tail.next = node + self.tail = node + self.length += 1 + + def insert_values(self , data_values : list): + self.head = self.tail = None + self.length = 0 + for data in data_values: + self.insert_back(data) + + def pop_front(self): + if not self.head: + print('List is Empty!') + return + + temp = self.head + self.head = self.head.next + temp.next = None + self.length -= 1 + + def pop_back(self): + if not self.head: + print('List is Empty!') + return + + temp = self.head + while temp.next != self.tail: + temp = temp.next + self.tail = temp + temp.next = None + self.length -= 1 + + def print(self): + if self.head is None: + print('Linked List is Empty!') + return + + temp = self.head + while temp: + print(f'{temp.data} ->' , end = ' ') + temp = temp.next + print('NULL') + + def len(self): + return self.length # O(1) length calculation + # if self.head is None: + # return 0 + # count = 0 + # temp = self.head + # while temp: + # count += 1 + # temp = temp.next + # return count + + def remove_at(self , idx): + if idx < 0 or self.len() <= idx: + raise Exception('Invalid Position') + if idx == 0: + self.head = self.head.next + self.length -= 1 + return + temp = self.head + dist = 0 + while dist != idx-1: + dist += 1 + temp = temp.next + temp.next = temp.next.next + self.length -= 1 + + def insert_at(self , idx : int , data ): + if idx < 0 or self.len() < idx: + raise Exception('Invalid Position') + if idx == 0: + self.insert_front(data) + return + temp = self.head + dist = 0 + while dist != idx-1: + dist += 1 + temp = temp.next + node = Node(data , temp.next) + temp.next = node + self.length += 1 + + def insert_after_value(self , idx_data , data): + if not self.head : # For Empty List case + print('List is Empty!') + return + + if self.head.data == idx_data: # To insert after the Head Element + self.insert_at(1 , data) + return + temp = self.head + while temp: + if temp.data == idx_data: + node = Node(data , temp.next) + temp.next = node + self.length += 1 + return + temp = temp.next + print('The Element is not in the List!') + + def remove_by_value(self , idx_data): + temp = self.head + if temp.data == idx_data: + self.head = self.head.next + self.length -= 1 + temp.next = None + return + while temp.next != None: + if temp.next.data == idx_data: + temp.next = temp.next.next + self.length -= 1 + return + + temp = temp.next + print('Element is not in the List!') + + def index(self , data): + '''Returns the index of the Element''' + if not self.head : + print('List is Empty!') + return + idx = 0 + temp = self.head + while temp: + if temp.data == data: return idx + temp = temp.next + idx += 1 + print('The Element is not in the List!') + + def search(self , idx): + '''Returns the Element at the Given Index''' + if self.len() == 0 or idx >= self.len(): + raise Exception('Invalid Position') + return + temp = self.head + curr_idx = 0 + while temp: + if curr_idx == idx: + return temp.data + temp = temp.next + curr_idx += 1 + + def reverse(self): + if not self.head: + print('The List is Empty!') + return + prev = c_next = None + curr = self.head + while curr != None: + c_next = curr.next + curr.next = prev + prev = curr + curr = c_next + self.tail = self.head + self.head = prev + + def mid_element(self): + if not self.head: + print('List is Empty!') + return + slow = self.head.next + fast = self.head.next.next + while fast != None and fast.next != None: + slow = slow.next + fast = fast.next.next + return slow.data + + def __dir__(self): + funcs = ['insert_front', 'insert_back','pop_front','pop_back','print','len','length','remove_at','insert_after_value','index','search','reverse','mid_element','__dir__'] + return funcs + +def main(): + ll : Node = LinkedList() + + # # ll.insert_front(1) + # # ll.insert_front(2) + # # ll.insert_front(3) + # # ll.insert_back(0) + # ll.insert_values(['ZeroTwo' , 'Asuna' , 'Tsukasa' , 'Seras' ]) + # # ll.remove_at(3) + # ll.insert_at(2 , 'Raeliana') + # # ll.pop_front() + # ll.insert_after_value('Raeliana' , 'MaoMao') + # # print(ll.search(5)) + # ll.remove_by_value('Tsukasa') + # ll.reverse() + + # ll.print() + # print(ll.mid_element()) + # print(ll.length) + print(ll.__dir__()) + + + + + +if __name__ == '__main__': + main() From 858a1fe24b8168bb8cb0863f7b483dc684f80e65 Mon Sep 17 00:00:00 2001 From: Mugen Date: Tue, 11 Feb 2025 03:09:35 +0530 Subject: [PATCH 243/442] Add files via upload --- LinkedLists all Types/doubly_linked_list.py | 245 ++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 LinkedLists all Types/doubly_linked_list.py diff --git a/LinkedLists all Types/doubly_linked_list.py b/LinkedLists all Types/doubly_linked_list.py new file mode 100644 index 00000000000..8ca7a2f87fa --- /dev/null +++ b/LinkedLists all Types/doubly_linked_list.py @@ -0,0 +1,245 @@ +'''Contains Most of the Doubly Linked List functions.\n +'variable_name' = doubly_linked_list.DoublyLinkedList() to use this an external module.\n +'variable_name'.insert_front('element') \t,'variable_name'.insert_back('element'),\n +'variable_name'.pop_front() are some of its functions.\n +To print all of its Functions use print('variable_name'.__dir__()).\n +Note:- 'variable_name' = doubly_linked_list.DoublyLinkedList() This line is Important before using any of the function. + +Author :- Mugen https://github.com/Mugendesu +''' +class Node: + def __init__(self, val=None , next = None , prev = None): + self.data = val + self.next = next + self.prev = prev + +class DoublyLinkedList: + + def __init__(self): + self.head = self.tail = None + self.length = 0 + + def insert_front(self , data): + node = Node(data , self.head) + if self.head == None: + self.tail = node + node.prev = self.head + self.head = node + self.length += 1 + + def insert_back(self , data): + node = Node(data ,None, self.tail) + if self.head == None: + self.tail = self.head = node + self.length += 1 + else: + self.tail.next = node + self.tail = node + self.length += 1 + + def insert_values(self , data_values : list): + self.head = self.tail = None + self.length = 0 + for data in data_values: + self.insert_back(data) + + def pop_front(self): + if not self.head: + print('List is Empty!') + return + + self.head = self.head.next + self.head.prev = None + self.length -= 1 + + def pop_back(self): + if not self.head: + print('List is Empty!') + return + + temp = self.tail + self.tail = temp.prev + temp.prev = self.tail.next = None + self.length -= 1 + + def print(self): + if self.head is None: + print('Linked List is Empty!') + return + + temp = self.head + print('NULL <-' , end=' ') + while temp: + if temp.next == None: + print(f'{temp.data} ->' , end = ' ') + break + print(f'{temp.data} <=>' , end = ' ') + temp = temp.next + print('NULL') + + def len(self): + return self.length # O(1) length calculation + # if self.head is None: + # return 0 + # count = 0 + # temp = self.head + # while temp: + # count += 1 + # temp = temp.next + # return count + + def remove_at(self , idx): + if idx < 0 or self.len() <= idx: + raise Exception('Invalid Position') + if idx == 0: + self.pop_front() + return + elif idx == self.length -1: + self.pop_back() + return + temp = self.head + dist = 0 + while dist != idx-1: + dist += 1 + temp = temp.next + temp.next = temp.next.next + temp.next.prev = temp.next.prev.prev + self.length -= 1 + + def insert_at(self , idx : int , data ): + if idx < 0 or self.len() < idx: + raise Exception('Invalid Position') + if idx == 0: + self.insert_front(data) + return + elif idx == self.length: + self.insert_back(data) + return + temp = self.head + dist = 0 + while dist != idx-1: + dist += 1 + temp = temp.next + node = Node(data , temp.next , temp) + temp.next = node + self.length += 1 + + def insert_after_value(self , idx_data , data): + if not self.head : # For Empty List case + print('List is Empty!') + return + + if self.head.data == idx_data: # To insert after the Head Element + self.insert_at(1 , data) + return + temp = self.head + while temp: + if temp.data == idx_data: + node = Node(data , temp.next , temp) + temp.next = node + self.length += 1 + return + temp = temp.next + print('The Element is not in the List!') + + def remove_by_value(self , idx_data): + temp = self.head + if temp.data == idx_data: + self.pop_front() + return + elif self.tail.data == idx_data: + self.pop_back() + return + while temp: + if temp.data == idx_data: + temp.prev.next = temp.next + temp.next.prev = temp.prev + self.length -= 1 + return + if temp != None: + temp = temp.next + print("The Element is not the List!") + + def index(self , data): + '''Returns the index of the Element''' + if not self.head : + print('List is Empty!') + return + idx = 0 + temp = self.head + while temp: + if temp.data == data: return idx + temp = temp.next + idx += 1 + print('The Element is not in the List!') + + def search(self , idx): + '''Returns the Element at the Given Index''' + if self.len() == 0 or idx >= self.len(): + raise Exception('Invalid Position') + return + temp = self.head + curr_idx = 0 + while temp: + if curr_idx == idx: + return temp.data + temp = temp.next + curr_idx += 1 + + def reverse(self): + if not self.head: + print('The List is Empty!') + return + prev = c_next = None + curr = self.head + while curr != None: + c_next = curr.next + curr.next = prev + prev = curr + curr = c_next + self.tail = self.head + self.head = prev + + def mid_element(self): + if not self.head: + print('List is Empty!') + return + slow = self.head.next + fast = self.head.next.next + while fast != None and fast.next != None: + slow = slow.next + fast = fast.next.next + return slow.data + + def __dir__(self): + funcs = ['insert_front', 'insert_back','pop_front','pop_back','print','len','length','remove_at','insert_after_value','index','search','reverse','mid_element','__dir__'] + return funcs + +def main(): + ll : Node = DoublyLinkedList() + + ll.insert_front(1) + ll.insert_front(2) + ll.insert_front(3) + ll.insert_back(0) + ll.insert_values(['ZeroTwo' , 'Asuna' , 'Tsukasa' , 'Seras']) + # ll.remove_at(3) + # ll.insert_at(4 , 'Raeliana') + # ll.pop_back() + ll.insert_after_value('Asuna' , 'MaoMao') + # print(ll.search(4)) + # ll.remove_by_value('Asuna') + # ll.reverse() + # print(ll.index('ZeroTwo')) + + ll.print() + # print(ll.mid_element()) + # print(ll.length) + # print(ll.__dir__()) + + + + + +if __name__ == '__main__': + main() \ No newline at end of file From d8941ef2f712dc443c63e98c82050c9a9732dd46 Mon Sep 17 00:00:00 2001 From: Mugen Date: Wed, 12 Feb 2025 00:08:35 +0530 Subject: [PATCH 244/442] Create circular_linked_list.py --- LinkedLists all Types/circular_linked_list.py | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 LinkedLists all Types/circular_linked_list.py diff --git a/LinkedLists all Types/circular_linked_list.py b/LinkedLists all Types/circular_linked_list.py new file mode 100644 index 00000000000..85ece9c046e --- /dev/null +++ b/LinkedLists all Types/circular_linked_list.py @@ -0,0 +1,134 @@ +from turtle import mode + + +class Node : + def __init__(self , data , next = None): + self.data = data + self.next = next + +class CircularLinkedList : + def __init__(self): + self.head = self.tail = None + self.length = 0 + + def insert_at_beginning(self , data): + node = Node(data , self.head) + if self.head is None: + self.head = self.tail = node + node.next = node + self.length += 1 + return + self.head = node + self.tail.next = node + self.length += 1 + + def insert_at_end(self , data): + node = Node(data , self.head) + if self.head is None: + self.head = self.tail = node + node.next = node + self.length += 1 + return + self.tail.next = node + self.tail = node + self.length += 1 + + def len(self): + return self.length + + def pop_at_beginning(self): + if self.head is None: + print('List is Empty!') + return + self.head = self.head.next + self.tail.next = self.head + self.length -= 1 + + def pop_at_end(self): + if self.head is None: + print('List is Empty!') + return + temp = self.head + while temp: + if temp.next is self.tail: + self.tail.next = None + self.tail = temp + temp.next = self.head + self.length -= 1 + return + temp = temp.next + + def insert_values(self , arr : list): + self.head = self.tail = None + self.length = 0 + for i in arr: + self.insert_at_end(i) + + def print(self): + if self.head is None: + print('The List is Empty!') + return + temp = self.head.next + print(f'{self.head.data} ->' , end=' ') + while temp != self.head: + print(f'{temp.data} ->' , end=' ') + temp = temp.next + print(f'{self.tail.next.data}') + + def insert_at(self , idx , data): + if idx == 0: + self.insert_at_beginning(data) + return + elif idx == self.length: + self.insert_at_end(data) + return + elif 0 > idx or idx > self.length: + raise Exception('Invalid Position') + return + pos = 0 + temp = self.head + while temp: + if pos == idx - 1: + node = Node(data , temp.next) + temp.next = node + self.length += 1 + return + pos += 1 + temp = temp.next + + def remove_at(self , idx): + if 0 > idx or idx >= self.length: + raise Exception('Invalid Position') + elif idx == 0: + self.pop_at_beginning() + return + elif idx == self.length - 1: + self.pop_at_end() + return + temp = self.head + pos = 0 + while temp: + if pos == idx - 1: + temp.next = temp.next.next + self.length -= 1 + return + pos += 1 + temp = temp.next + +def main(): + ll = CircularLinkedList() + ll.insert_at_end(1) + ll.insert_at_end(4) + ll.insert_at_end(3) + ll.insert_at_beginning(2) + ll.insert_values([1 , 2, 3 ,4 ,5 ,6,53,3]) + # ll.pop_at_end() + ll.insert_at(8, 7) + # ll.remove_at(2) + ll.print() + print(f'{ll.len() = }') + + + +if __name__ == '__main__': + main() \ No newline at end of file From 389d60d118b5d61be387d4f9584f3db4b045d17e Mon Sep 17 00:00:00 2001 From: Mugen Date: Wed, 12 Feb 2025 00:12:27 +0530 Subject: [PATCH 245/442] Update circular_linked_list.py --- LinkedLists all Types/circular_linked_list.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/LinkedLists all Types/circular_linked_list.py b/LinkedLists all Types/circular_linked_list.py index 85ece9c046e..1bba861dc8b 100644 --- a/LinkedLists all Types/circular_linked_list.py +++ b/LinkedLists all Types/circular_linked_list.py @@ -1,5 +1,4 @@ -from turtle import mode - +'''Author - Mugen https://github.com/Mugendesu''' class Node : def __init__(self , data , next = None): @@ -131,4 +130,4 @@ def main(): if __name__ == '__main__': - main() \ No newline at end of file + main() From 0589a57693da461590f473376f7b3c55b9f29c86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Feb 2025 18:35:57 +0000 Subject: [PATCH 246/442] Bump solara from 1.43.0 to 1.44.0 Bumps [solara](https://github.com/widgetti/solara) from 1.43.0 to 1.44.0. - [Changelog](https://github.com/widgetti/solara/blob/master/CHANGELOG.md) - [Commits](https://github.com/widgetti/solara/compare/v1.43.0...v1.44.0) --- updated-dependencies: - dependency-name: solara dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- News_App/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/News_App/requirements.txt b/News_App/requirements.txt index ec7e0dedb52..a7150d774c4 100644 --- a/News_App/requirements.txt +++ b/News_App/requirements.txt @@ -1,4 +1,4 @@ -solara == 1.43.0 +solara == 1.44.0 Flask gunicorn ==23.0.0 simple-websocket diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 3cb5fce76b7..d2dfe852284 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -74,7 +74,7 @@ xor-cipher==5.0.1 bird==0.1.2 mechanize==0.4.10 translate==3.6.1 -solara==1.43.0 +solara==1.44.0 pywhatkit==5.4 mutagen==1.47.0 Unidecode==1.3.8 From 655e92289004edccfaef700cd57feb42a7cc9a58 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Feb 2025 18:36:01 +0000 Subject: [PATCH 247/442] Bump twilio from 9.4.3 to 9.4.5 Bumps [twilio](https://github.com/twilio/twilio-python) from 9.4.3 to 9.4.5. - [Release notes](https://github.com/twilio/twilio-python/releases) - [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md) - [Commits](https://github.com/twilio/twilio-python/compare/9.4.3...9.4.5) --- updated-dependencies: - dependency-name: twilio dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 3cb5fce76b7..2d0356cbfaf 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -28,7 +28,7 @@ requests==2.32.3 quo==2023.5.1 PyPDF2==3.0.1 pyserial==3.5 -twilio==9.4.3 +twilio==9.4.5 tabula==1.0.5 nltk==3.9.1 Pillow==11.1.0 From 378a01859c07ff73afdb1fbdea046504661cc010 Mon Sep 17 00:00:00 2001 From: Ayush Bhomia <159886655+ayushh0406@users.noreply.github.com> Date: Fri, 14 Feb 2025 19:13:04 +0530 Subject: [PATCH 248/442] Create voice.py --- voice.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 voice.py diff --git a/voice.py b/voice.py new file mode 100644 index 00000000000..b8f2a3e23c8 --- /dev/null +++ b/voice.py @@ -0,0 +1,14 @@ +from gtts import gTTS +import os + +# Define the text you want to convert to speech +text = "Hello! This is a sample text to convert to speech." + +# Create a gTTS object +tts = gTTS(text=text, lang='en') + +# Save the audio file +tts.save("output.mp3") + +# Play the audio file +os.system("start output.mp3") From 1642522708a4f71c53f3b8bdcb8a481c0872c5f1 Mon Sep 17 00:00:00 2001 From: HarshitGourlariya Date: Sat, 15 Feb 2025 12:36:56 +0530 Subject: [PATCH 249/442] Add Anonymus_textApp.py: Anonymous text messaging app using Python --- Anonymous_TextApp.py | 83 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 Anonymous_TextApp.py diff --git a/Anonymous_TextApp.py b/Anonymous_TextApp.py new file mode 100644 index 00000000000..9b3f5052e88 --- /dev/null +++ b/Anonymous_TextApp.py @@ -0,0 +1,83 @@ +import tkinter as tk +from PIL import Image, ImageTk +from twilio.rest import Client + +window = tk.Tk() +window.title("Anonymous_Text_App") +window.geometry("800x750") + +# Define global variables +body = "" +to = "" + +def message(): + global body, to + account_sid = 'Your_account_sid' # Your account sid + auth_token = 'Your_auth_token' # Your auth token + client = Client(account_sid, auth_token) + msg = client.messages.create( + from_='Twilio_number', # Twilio number + body=body, + to=to + ) + print(msg.sid) + confirmation_label.config(text="Message Sent!") + + + +try: + # Load the background image + bg_img = Image.open(r"D:\Downloads\img2.png") + + #Canvas widget + canvas = tk.Canvas(window, width=800, height=750) + canvas.pack(fill="both", expand=True) + + # background image to the Canvas + bg_photo = ImageTk.PhotoImage(bg_img) + bg_image_id = canvas.create_image(0, 0, image=bg_photo, anchor="nw") + bg_image_id = canvas.create_image(550, 250, image=bg_photo, anchor="center") + bg_image_id = canvas.create_image(1100, 250, image=bg_photo, anchor="center") + bg_image_id = canvas.create_image(1250, 250, image=bg_photo, anchor="center") + bg_image_id = canvas.create_image(250, 750, image=bg_photo, anchor="center") + bg_image_id = canvas.create_image(850, 750, image=bg_photo, anchor="center") + bg_image_id = canvas.create_image(1300, 750, image=bg_photo, anchor="center") + + + + # Foreground Image + img = Image.open(r"D:\Downloads\output-onlinepngtools.png") + photo = ImageTk.PhotoImage(img) + img_label = tk.Label(window, image=photo, anchor="w") + img_label.image = photo + img_label.place(x=10, y=20) + + # Text for number input + canvas.create_text(1050, 300, text="Enter the number starting with +[country code]", font=("Poppins", 18, "bold"), fill="black", anchor="n") + text_field_number = tk.Entry(canvas, width=17, font=("Poppins", 25, "bold"), bg="#404040", fg="white", show="*") + canvas.create_window(1100, 350, window=text_field_number, anchor="n") + + # Text for message input + canvas.create_text(1050, 450, text="Enter the Message", font=("Poppins", 18, "bold"), fill="black", anchor="n") + text_field_text = tk.Entry(canvas, width=17, font=("Poppins", 25, "bold"), bg="#404040", fg="white") + canvas.create_window(1100, 500, window=text_field_text, anchor="n") + + # label for confirmation message + confirmation_label = tk.Label(window, text="", font=("Poppins", 16), fg="green") + canvas.create_window(1100, 600, window=confirmation_label, anchor="n") + +except Exception as e: + print(f"Error loading image: {e}") + +# Function to save input and send message +def save_and_send(): + global body, to + to = str(text_field_number.get()) + body = str(text_field_text.get()) + message() + +# Button to save input and send message +save_button = tk.Button(window, text="Save and Send", command=save_and_send) +canvas.create_window(1200, 550, window=save_button, anchor='n') + +window.mainloop() \ No newline at end of file From 704cdbd845e8ae512fa1ebe534c23d65ab4e063c Mon Sep 17 00:00:00 2001 From: Ayush Bhomia <159886655+ayushh0406@users.noreply.github.com> Date: Sat, 15 Feb 2025 12:52:30 +0530 Subject: [PATCH 250/442] Update Ball.py --- PingPong/Ball.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PingPong/Ball.py b/PingPong/Ball.py index ec1a4a6768f..73961fc07f2 100644 --- a/PingPong/Ball.py +++ b/PingPong/Ball.py @@ -21,6 +21,7 @@ def drawBall(self): def doHorizontalFlip(self): self.vel[0] *= -1 + print("Github") def doVerticalFlip(self): @@ -55,4 +56,4 @@ def checkSlabCollision(self, slabPos): # slab pos = [xmin, ymin, xmax, ymax] if self.pos[0] < slabPos[0] or self.pos[0] > slabPos[2]: self.vel[0] *= -1 if self.pos[1] < slabPos[1] or self.pos[1] > slabPos[3]: - self.vel[1] *= -1 \ No newline at end of file + self.vel[1] *= -1 From 203a9b9ac892ee2d742162594ee805bb2b157550 Mon Sep 17 00:00:00 2001 From: SomdattaNag Date: Sat, 15 Feb 2025 22:38:12 +0530 Subject: [PATCH 251/442] Added text-to-speech functionality to generate voice from python code(Issue #2511) --- Python Voice Generator.py | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 Python Voice Generator.py diff --git a/Python Voice Generator.py b/Python Voice Generator.py new file mode 100644 index 00000000000..9541ccfae51 --- /dev/null +++ b/Python Voice Generator.py @@ -0,0 +1,11 @@ +#install and import google text-to-speech library gtts +from gtts import gTTS +import os +#provide user input text +text=input('enter the text: ') +#covert text into voice +voice=gTTS(text=text, lang='en') +#save the generated voice +voice.save('output.mp3') +#play the file in windows +os.system('start output.mp3') \ No newline at end of file From 8a94fd35d5f3c6a3ab0512ddef18c86916175f85 Mon Sep 17 00:00:00 2001 From: Ayush Bhomia <159886655+ayushh0406@users.noreply.github.com> Date: Sun, 16 Feb 2025 14:55:48 +0530 Subject: [PATCH 252/442] 8_puzzle.py This code defines a PuzzleState class to represent each state of the puzzle. It uses the A* search algorithm to find the shortest path from the initial state to the goal state. The Manhattan distance heuristic is used to guide the search. The solve_puzzle function returns the solution state, and the print_solution function prints the sequence of moves to solve the puzzle. --- 8_puzzle.py | 92 ++++++ Eight_Puzzle_Solver/eight_puzzle.py | 457 ---------------------------- 2 files changed, 92 insertions(+), 457 deletions(-) create mode 100644 8_puzzle.py delete mode 100644 Eight_Puzzle_Solver/eight_puzzle.py diff --git a/8_puzzle.py b/8_puzzle.py new file mode 100644 index 00000000000..630cc12dd21 --- /dev/null +++ b/8_puzzle.py @@ -0,0 +1,92 @@ +from queue import PriorityQueue + +class PuzzleState: + def __init__(self, board, goal, moves=0, previous=None): + self.board = board + self.goal = goal + self.moves = moves + self.previous = previous + + def __lt__(self, other): + return self.priority() < other.priority() + + def priority(self): + return self.moves + self.manhattan() + + def manhattan(self): + distance = 0 + for i in range(3): + for j in range(3): + if self.board[i][j] != 0: + x, y = divmod(self.board[i][j] - 1, 3) + distance += abs(x - i) + abs(y - j) + return distance + + def is_goal(self): + return self.board == self.goal + + def neighbors(self): + neighbors = [] + x, y = next((i, j) for i in range(3) for j in range(3) if self.board[i][j] == 0) + directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] + + for dx, dy in directions: + nx, ny = x + dx, y + dy + if 0 <= nx < 3 and 0 <= ny < 3: + new_board = [row[:] for row in self.board] + new_board[x][y], new_board[nx][ny] = new_board[nx][ny], new_board[x][y] + neighbors.append(PuzzleState(new_board, self.goal, self.moves + 1, self)) + + return neighbors + +def solve_puzzle(initial_board, goal_board): + initial_state = PuzzleState(initial_board, goal_board) + frontier = PriorityQueue() + frontier.put(initial_state) + explored = set() + + while not frontier.empty(): + current_state = frontier.get() + + if current_state.is_goal(): + return current_state + + explored.add(tuple(map(tuple, current_state.board))) + + for neighbor in current_state.neighbors(): + if tuple(map(tuple, neighbor.board)) not in explored: + frontier.put(neighbor) + + return None + +def print_solution(solution): + steps = [] + while solution: + steps.append(solution.board) + solution = solution.previous + steps.reverse() + + for step in steps: + for row in step: + print(' '.join(map(str, row))) + print() + +# Example usage +initial_board = [ + [1, 2, 3], + [4, 0, 5], + [7, 8, 6] +] + +goal_board = [ + [1, 2, 3], + [4, 5, 6], + [7, 8, 0] +] + +solution = solve_puzzle(initial_board, goal_board) +if solution: + print("Solution found:") + print_solution(solution) +else: + print("No solution found.") diff --git a/Eight_Puzzle_Solver/eight_puzzle.py b/Eight_Puzzle_Solver/eight_puzzle.py deleted file mode 100644 index 703df00b3e6..00000000000 --- a/Eight_Puzzle_Solver/eight_puzzle.py +++ /dev/null @@ -1,457 +0,0 @@ -# import sys -from collections import deque -from copy import deepcopy -from queue import PriorityQueue - -# import time -# from collections import Counter - - -class Node: - def __init__(self, state, depth=0, moves=None, optimizer=0): - """ - Parameters: - state: State of Puzzle - depth: Depth of State in Space Search Tree - moves: Moves List to reach this state from initial state - optimizer: Used for UCS Only - 0 - Manhattan Distance - 1 - Hamming Distance - 2 - Combination of 0 and 1 - - Returns: Node Object - """ - self.state = state - self.size = len(state) - self.depth = depth - self.optimizer = optimizer - if moves is None: - self.moves = list() - else: - self.moves = moves - - def getAvailableActions(self): - """ - Parameters: Current State - Returns: Available Actions for Current State - 0 - Left 1 - Right 2 - Top 3 - Bottom - Restrictions: state is self.size x self.size Array - """ - action = list() - for i in range(self.size): - for j in range(self.size): - if self.state[i][j] == 0: - if i > 0: - action.append(2) - if j > 0: - action.append(0) - if i < self.size - 1: - action.append(3) - if j < self.size - 1: - action.append(1) - return action - return action - - def getResultFromAction(self, action): - """ - Parameters: Current State , Action - Returns: Node with New State - Restrictions: Action will always be valid and state is self.size x self.size Array - """ - newstate = deepcopy(self.state) - newMoves = deepcopy(self.moves) - for i in range(self.size): - for j in range(self.size): - if newstate[i][j] == 0: - if action == 2: - newstate[i][j], newstate[i - 1][j] = ( - newstate[i - 1][j], - newstate[i][j], - ) - newMoves.append(2) - return Node( - newstate, - depth=self.depth + 1, - moves=newMoves, - optimizer=self.optimizer, - ) - if action == 3: - newstate[i][j], newstate[i + 1][j] = ( - newstate[i + 1][j], - newstate[i][j], - ) - newMoves.append(3) - return Node( - newstate, - depth=self.depth + 1, - moves=newMoves, - optimizer=self.optimizer, - ) - if action == 0: - newstate[i][j], newstate[i][j - 1] = ( - newstate[i][j - 1], - newstate[i][j], - ) - newMoves.append(0) - return Node( - newstate, - depth=self.depth + 1, - moves=newMoves, - optimizer=self.optimizer, - ) - if action == 1: - newstate[i][j], newstate[i][j + 1] = ( - newstate[i][j + 1], - newstate[i][j], - ) - newMoves.append(1) - return Node( - newstate, - depth=self.depth + 1, - moves=newMoves, - optimizer=self.optimizer, - ) - return None - - def isGoalState(self): - """ - Parameters: State - Returns: True if Goal State, otherwise False - Restrictions: State is self.size x self.size Array - """ - for i in range(self.size): - for j in range(self.size): - if i == j and j == self.size - 1: - continue - if self.state[i][j] != (i) * self.size + (j + 1): - return False - return True - - def getManhattanDistance(self): - """ - Parameters: State - Returns: Manhattan Distance between Current State and Goal State - Restrictions: State must be a self.size x self.size Array - """ - ans = 0 - for i in range(self.size): - for j in range(self.size): - if self.state[i][j] != 0: - ans = ( - ans - + abs((self.state[i][j] - 1) % self.size - j) - + abs((self.state[i][j] - 1) // self.size - i) - ) - - return ans - - def getHammingDistance(self): - ans = 0 - for i in range(self.size): - for j in range(self.size): - if self.state[i][j] != 0 and self.state[i][j] != i * 3 + (j + 1): - ans = ans + 1 - return ans - - def __hash__(self): - flatState = [j for sub in self.state for j in sub] - flatState = tuple(flatState) - return hash(flatState) - - def __gt__(self, other): - if self.optimizer == 0: - if self.getManhattanDistance() > other.getManhattanDistance(): - return True - else: - return False - elif self.optimizer == 1: - if self.getHammingDistance() > other.getHammingDistance(): - return True - else: - return False - elif self.optimizer == 2: - if ( - self.getHammingDistance() + self.getManhattanDistance() - > other.getHammingDistance() + self.getManhattanDistance() - ): - return True - else: - return False - return True - - def __ge__(self, other): - if self.optimizer == 0: - if self.getManhattanDistance() >= other.getManhattanDistance(): - return True - else: - return False - elif self.optimizer == 1: - if self.getHammingDistance() >= other.getHammingDistance(): - return True - else: - return False - elif self.optimizer == 2: - if ( - self.getHammingDistance() + self.getManhattanDistance() - >= other.getHammingDistance() + self.getManhattanDistance() - ): - return True - else: - return False - return True - - def __lt__(self, other): - if self.optimizer == 0: - if self.getManhattanDistance() < other.getManhattanDistance(): - return True - else: - return False - elif self.optimizer == 1: - if self.getHammingDistance() < other.getHammingDistance(): - return True - else: - return False - elif self.optimizer == 2: - if ( - self.getHammingDistance() + self.getManhattanDistance() - < other.getHammingDistance() + self.getManhattanDistance() - ): - return True - else: - return False - return True - - def __le__(self, other): - if self.optimizer == 0: - if self.getManhattanDistance() <= other.getManhattanDistance(): - return True - else: - return False - elif self.optimizer == 1: - if self.getHammingDistance() <= other.getHammingDistance(): - return True - else: - return False - elif self.optimizer == 2: - if ( - self.getHammingDistance() + self.getManhattanDistance() - <= other.getHammingDistance() + self.getManhattanDistance() - ): - return True - else: - return False - return True - - def __eq__(self, other): - if self.optimizer == 0: - if self.getManhattanDistance() == other.getManhattanDistance(): - return True - else: - return False - elif self.optimizer == 1: - if self.getHammingDistance() == other.getHammingDistance(): - return True - else: - return False - elif self.optimizer == 2: - if ( - self.getHammingDistance() + self.getManhattanDistance() - == other.getHammingDistance() + self.getManhattanDistance() - ): - return True - else: - return False - return True - - -class Solver: - def __init__(self, state): - self.state = state - - def isSolvable(self): - """ - Parameters: State - Returns: True if state is solvable, otherwise False - """ - flatState = [j for sub in self.state for j in sub] - inversions = 0 - for i in range(len(flatState) - 1): - for j in range(i + 1, len(flatState)): - if ( - flatState[i] != 0 - and flatState[j] != 0 - and flatState[i] > flatState[j] - ): - inversions = inversions + 1 - return inversions % 2 == 0 - - def breadth_first_search(self): - """ - Parameters: State - Returns: List of Moves to solve the state, otherwise None if unsolvable - """ - if self.isSolvable() == False: - return (None, None) - - closed = list() - q = deque() - q.append(Node(state=self.state, depth=0)) - while q: - node = q.popleft() - - if node.isGoalState(): - return (node.moves, len(closed)) - if node.state not in closed: - closed.append(node.state) - for action in node.getAvailableActions(): - q.append(node.getResultFromAction(action)) - - return (None, None) - - def depth_first_search(self): - """ - Parameters: State - Returns: List of Moves to solve the state, otherwise None if unsolvable - """ - if self.isSolvable() == False: - return (None, None) - closed = list() - q = list() - q.append(Node(state=self.state, depth=0)) - while q: - node = q.pop() - if node.isGoalState(): - return (node.moves, len(closed)) - if node.state not in closed: - closed.append(node.state) - for action in node.getAvailableActions(): - q.append(node.getResultFromAction(action)) - - return (None, None) - - def uniform_cost_search(self, optimizer=0): - """ - Parameters: State, Optimizer - Returns: List of Moves to solve the state, otherwise None if unsolvable - """ - if self.isSolvable() == False: - return (None, None) - closed = list() - q = PriorityQueue() - q.put(Node(state=self.state, depth=0, optimizer=optimizer)) - while q: - node = q.get() - if node.isGoalState(): - return (node.moves, len(closed)) - if node.state not in closed: - closed.append(node.state) - for action in node.getAvailableActions(): - q.put(node.getResultFromAction(action)) - - return (None, None) - - def a_star(self): - """ - Parameters: State, Optimizer - Returns: List of Moves to solve the state, otherwise None if unsolvable - """ - if self.isSolvable() == False: - return (None, None) - closed = dict() - q = PriorityQueue() - node = Node(state=self.state, depth=0) - q.put((node.getManhattanDistance(), node)) - while q: - dist, node = q.get() - closed[node] = dist - if node.isGoalState(): - return (node.moves, len(closed)) - for action in node.getAvailableActions(): - nextNode = node.getResultFromAction(action) - nextDist = nextNode.getManhattanDistance() - if ( - nextNode not in closed - or nextNode.depth + nextDist < closed[nextNode] - ): - q.put((nextNode.depth + nextDist, nextNode)) - return (None, None) - - -def toWord(action): - """ - Parameters: List of moves - Returns: Returns List of moves in Word - """ - if action == 0: - return "Left" - if action == 1: - return "Right" - if action == 2: - return "Top" - if action == 3: - return "Bottom" - - -# initialState = [[1,8,4],[3,6,0],[2,7,5]] -# # [[1,2,3],[4,5,6],[0,7,8]] -# # [[6,8,5],[2,3,4],[1,0,7]] -# # [[13,11,10,7],[6,0,15,2],[14,1,8,12],[5,3,4,9]] -# # [[8,2,3],[4,6,5],[7,8,0]] -# solver = Solver(initialState) -# print("Initial State:- {}".format(initialState)) -# n = Node(state=initialState,depth=0) - -# print('-------------------------A Star--------------------------------') -# startTime = time.time() -# moves,nodesGenerated = solver.a_star() -# endTime = time.time() -# if moves is None: -# print("Given State is Unsolvable!") -# else: -# wordMoves = list(map(toWord,moves)) -# print("Nodes Generated:- {}".format(nodesGenerated)) -# print("No. of moves:- {}".format(len(moves))) -# print("Required Moves:- {}".format(wordMoves)) -# print("Execution Time:- {:.2f} ms".format((endTime-startTime)*1000)) - - -# print('-------------------------UCS--------------------------------') -# startTime = time.time() -# moves,nodesGenerated = solver.uniform_cost_search() -# endTime = time.time() -# if moves is None: -# print("Given State is Unsolvable!") -# else: -# wordMoves = list(map(toWord,moves)) -# print("Nodes Generated:- {}".format(nodesGenerated)) -# print("No. of moves:- {}".format(len(moves))) -# print("Required Moves:- {}".format(wordMoves)) -# print("Execution Time:- {:.2f} ms".format((endTime-startTime)*1000)) - - -# print('-------------------------BFS--------------------------------') -# startTime = time.time() -# moves,nodesGenerated = (solver.breadth_first_search()) -# endTime = time.time() -# if moves is None: -# print("Given State is Unsolvable!") -# else: -# wordMoves = list(map(toWord,moves)) -# print("Nodes Generated:- {}".format(nodesGenerated)) -# print("No. of moves:- {}".format(len(moves))) -# print("Required Moves:- {}".format(wordMoves)) -# print("Execution Time:- {:.2f} ms".format((endTime-startTime)*1000)) - - -# print('-------------------------DFS--------------------------------') -# startTime = time.time() -# moves,nodesGenerated = (solver.depth_first_search()) -# endTime = time.time() -# if moves is None: -# print("Given State is Unsolvable!") -# else: -# wordMoves = list(map(toWord,moves)) -# print("Nodes Generated:- {}".format(nodesGenerated)) -# print("No. of moves:- {}".format(len(moves))) -# print("Required Moves:- {}".format(wordMoves)) -# print("Execution Time:- {:.2f} ms".format((endTime-startTime)*1000)) From 81d112089165c41614925dfa967f98a59c31a4b1 Mon Sep 17 00:00:00 2001 From: Ayush Bhomia <159886655+ayushh0406@users.noreply.github.com> Date: Sun, 16 Feb 2025 14:58:33 +0530 Subject: [PATCH 253/442] Update README.md --- Emoji Dictionary/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Emoji Dictionary/README.md b/Emoji Dictionary/README.md index bfeee397ad6..ef821174fce 100644 --- a/Emoji Dictionary/README.md +++ b/Emoji Dictionary/README.md @@ -10,6 +10,8 @@ - tkinter module - from tkinter messagebox module - emoji +- opencv + ### How this Script works : - User just need to download the file and run the emoji_dictionary.py on their local system. From e2832d780b1ce0c1ea43c224e21b5c40d1799e68 Mon Sep 17 00:00:00 2001 From: Ayush Bhomia <159886655+ayushh0406@users.noreply.github.com> Date: Sun, 16 Feb 2025 15:01:32 +0530 Subject: [PATCH 254/442] Update Flappy Bird.py --- .../Flappy Bird.py | 482 +++--------------- 1 file changed, 74 insertions(+), 408 deletions(-) diff --git a/Flappy Bird - created with tkinter/Flappy Bird.py b/Flappy Bird - created with tkinter/Flappy Bird.py index 308a7c6ea70..7dfe9564dfb 100644 --- a/Flappy Bird - created with tkinter/Flappy Bird.py +++ b/Flappy Bird - created with tkinter/Flappy Bird.py @@ -1,419 +1,85 @@ -__author__ = "Jean Loui Bernard Silva de Jesus" -__version__ = "1.0" +import pygame +import random -import os.path -from datetime import timedelta -from time import time -from tkinter import Tk, Button +# Initialize Pygame +pygame.init() -from Background import Background -from Bird import Bird -from Settings import Settings -from Tubes import Tubes +# Set up display +screen_width = 500 +screen_height = 700 +screen = pygame.display.set_mode((screen_width, screen_height)) +pygame.display.set_caption("Flappy Bird") +# Load images +bird_image = pygame.image.load("bird.png").convert_alpha() +pipe_image = pygame.image.load("pipe.png").convert_alpha() +background_image = pygame.image.load("background.png").convert_alpha() -class App(Tk, Settings): - """ - Classe principal do jogo onde tudo será executado - """ - - # Variáveis privadas e ajustes internos - __background_animation_speed = 720 - __bestScore = 0 - __bird_descend_speed = 38.4 - __buttons = [] - __playing = False - __score = 0 - __time = "%H:%M:%S" - +# Bird class +class Bird: def __init__(self): + self.image = bird_image + self.x = 50 + self.y = screen_height // 2 + self.vel = 0 + self.gravity = 1 - Tk.__init__(self) - self.setOptions() - - # Se o tamanho da largura e altura da janela forem definidos, eles serão usados no jogo. - # Caso eles tenham o valor None, o tamanho da janela será o tamanho do monitor do usuário. - - if all([self.window_width, self.window_height]): - self.__width = self.window_width - self.__height = self.window_height - else: - self.__width = self.winfo_screenwidth() - self.__height = self.winfo_screenheight() - - # Configura a janela do programa - self.title(self.window_name) - self.geometry("{}x{}".format(self.__width, self.__height)) - self.resizable(*self.window_rz) - self.attributes("-fullscreen", self.window_fullscreen) - self["bg"] = "black" - - # Verifica se existem as imagens do jogo - for file in self.images_fp: - if not os.path.exists(file): - raise FileNotFoundError( - "The following file was not found:\n{}".format(file) - ) - - # Carrega a imagem do botão para começar o jogo - self.__startButton_image = Background.getPhotoImage( - image_path=self.startButton_fp, - width=(self.__width // 100) * self.button_width, - height=(self.__height // 100) * self.button_height, - closeAfter=True, - )[0] - - # Carrega a imagem do botão para sair do jogo - self.__exitButton_image = Background.getPhotoImage( - image_path=self.exitButton_fp, - width=(self.__width // 100) * self.button_width, - height=(self.__height // 100) * self.button_height, - closeAfter=True, - )[0] - - # Carrega a imagem do título do jogo - self.__title_image = Background.getPhotoImage( - image_path=self.title_fp, - width=(self.__width // 100) * self.title_width, - height=(self.__height // 100) * self.title_height, - closeAfter=True, - )[0] - - # Carrega a imagem do placar do jogo - self.__scoreboard_image = Background.getPhotoImage( - image_path=self.scoreboard_fp, - width=(self.__width // 100) * self.scoreboard_width, - height=(self.__height // 100) * self.scoreboard_height, - closeAfter=True, - )[0] - - # Define a velocidade da animação do background com base na largura da janela - self.__background_animation_speed //= self.__width / 100 - self.__background_animation_speed = int(self.__background_animation_speed) - - # Define a velocidade de descida do pássaro com base na altura da janela - self.__bird_descend_speed //= self.__height / 100 - self.__bird_descend_speed = int(self.__bird_descend_speed) - - def changeFullscreenOption(self, event=None): - """ - Método para colocar o jogo no modo "fullscreen" ou "window" - """ - - self.window_fullscreen = not self.window_fullscreen - self.attributes("-fullscreen", self.window_fullscreen) - - def close(self, event=None): - """ - Método para fechar o jogo - """ - - # Salva a melhor pontuação do jogador antes de sair do jogo - self.saveScore() - - # Tenta interromper os processos - try: - self.__background.stop() - self.__bird.kill() - self.__tubes.stop() - finally: - quit() - - def createMenuButtons(self): - """ - Método para criar os botões de menu - """ - - # Define o tamanho do botão em porcentagem com base no tamanho da janela - width = (self.__width // 100) * self.button_width - height = (self.__height // 100) * self.button_height - - # Cria um botão para começar o jogo - startButton = Button( - self, - image=self.__startButton_image, - bd=0, - command=self.start, - cursor=self.button_cursor, - bg=self.button_bg, - activebackground=self.button_activebackground, - ) - # Coloca o botão dentro do background ( Canvas ) - self.__buttons.append( - self.__background.create_window( - (self.__width // 2) - width // 1.5, - int(self.__height / 100 * self.button_position_y), - window=startButton, - ) - ) - - # Cria um botão para sair do jogo - exitButton = Button( - self, - image=self.__exitButton_image, - bd=0, - command=self.close, - cursor=self.button_cursor, - bg=self.button_bg, - activebackground=self.button_activebackground, - ) - - # Coloca o botão dentro do background ( Canvas ) - self.__buttons.append( - self.__background.create_window( - (self.__width // 2) + width // 1.5, - int(self.__height / 100 * self.button_position_y), - window=exitButton, - ) - ) - - def createScoreBoard(self): - """ - Método para criar a imagem do placar do jogo no background - junto com as informações do jogador. - """ - - # Define a posição X e Y - x = self.__width // 2 - y = (self.__height // 100) * self.scoreboard_position_y - - # Calcula o tamanho da imagem do placar - scoreboard_w = (self.__width // 100) * self.scoreboard_width - scoreboard_h = (self.__width // 100) * self.scoreboard_height - - # Calcula a posição X e Y do texto da pontuação do último jogo - score_x = x - scoreboard_w / 100 * 60 / 2 - score_y = y + scoreboard_h / 100 * 10 / 2 - - # Calcula a posição X e Y do texto da melhor pontuação do jogador - bestScore_x = x + scoreboard_w / 100 * 35 / 2 - bestScore_y = y + scoreboard_h / 100 * 10 / 2 - - # Calcula a posição X e Y do texto do tempo de jogo - time_x = x - time_y = y + scoreboard_h / 100 * 35 / 2 - - # Define a fonte dos textos - font = (self.text_font, int(0.02196 * self.__width + 0.5)) - - # Cria a imagem do placar no background - self.__background.create_image(x, y, image=self.__scoreboard_image) - - # Cria texto para mostrar o score do último jogo - self.__background.create_text( - score_x, - score_y, - text="Score: %s" % self.__score, - fill=self.text_fill, - font=font, - ) - - # Cria texto para mostrar a melhor pontuação do jogador - self.__background.create_text( - bestScore_x, - bestScore_y, - text="Best Score: %s" % self.__bestScore, - fill=self.text_fill, - font=font, - ) - - # Cria texto para mostrar o tempo de jogo - self.__background.create_text( - time_x, - time_y, - text="Time: %s" % self.__time, - fill=self.text_fill, - font=font, - ) - - def createTitleImage(self): - """ - Método para criar a imagem do título do jogo no background - """ - - self.__background.create_image( - self.__width // 2, - (self.__height // 100) * self.title_position_y, - image=self.__title_image, - ) + def update(self): + self.vel += self.gravity + self.y += self.vel - def deleteMenuButtons(self): - """ - Método para deletar os botões de menu - """ + def flap(self): + self.vel = -10 - # Deleta cada botão criado dentro do background - for item in self.__buttons: - self.__background.delete(item) - - # Limpa a lista de botões - self.__buttons.clear() - - def gameOver(self): - """ - Método de fim de jogo - """ - - # Calcula o tempo jogado em segundos e depois o formata - self.__time = int(time() - self.__time) - self.__time = str(timedelta(seconds=self.__time)) - - # Interrompe a animação do plano de fundo e a animação dos tubos - self.__background.stop() - self.__tubes.stop() - - # Declara que o jogo não está mais em execução - self.__playing = False - - # Cria os botões inciais - self.createMenuButtons() - - # Cria image do título do jogo - self.createTitleImage() - - # Cria imagem do placar e mostra as informações do jogo passado - self.createScoreBoard() - - def increaseScore(self): - """ - Método para aumentar a pontuação do jogo atual do jogador - """ - - self.__score += 1 - if self.__score > self.__bestScore: - self.__bestScore = self.__score - - def init(self): - """ - Método para iniciar o programa em si, criando toda a parte gráfica inicial do jogo - """ - - # self.createMenuButtons() - self.loadScore() - - # Cria o plano de fundo do jogo - self.__background = Background( - self, - self.__width, - self.__height, - fp=self.background_fp, - animation_speed=self.__background_animation_speed, - ) - - # Foca o plano de fundo para que seja possível definir os eventos - self.__background.focus_force() - # Define evento para trocar o modo de janela para "fullscreen" ou "window" - self.__background.bind( - self.window_fullscreen_event, self.changeFullscreenOption - ) - # Define evento para começar o jogo - self.__background.bind(self.window_start_event, self.start) - # Define evento para sair do jogo - self.__background.bind(self.window_exit_event, self.close) - - # Define um método caso o usuário feche a janela do jogo - self.protocol("WM_DELETE_WINDOW", self.close) - - # Empacota o objeto background - self.__background.pack() - - # Cria os botões do menu do jogo - self.createMenuButtons() - - # Cria imagem do título do jogo - self.createTitleImage() - - # Cria um pássaro inicial no jogo - self.__bird = Bird( - self.__background, - self.gameOver, - self.__width, - self.__height, - fp=self.bird_fp, - event=self.bird_event, - descend_speed=self.__bird_descend_speed, - ) - - def loadScore(self): - """ - Método para carregar a pontuação do jogador - """ - - # Tenta carregar o placar do usuário - try: - file = open(self.score_fp) - self.__bestScore = int(file.read(), 2) - file.close() - - # Se não for possível, será criado um arquivo para guardar o placar - except BaseException: - file = open(self.score_fp, "w") - file.write(bin(self.__bestScore)) - file.close() - - def saveScore(self): - """ - Método para salvar a pontuação do jogador - """ - - with open(self.score_fp, "w") as file: - file.write(bin(self.__bestScore)) - - def start(self, event=None): - """ - Método para inicializar o jogo - """ - - # Este método é executado somente se o jogador não estiver já jogando - if self.__playing: - return - - # Reinicia o placar - self.__score = 0 - self.__time = time() - - # Remove os botões de menu - self.deleteMenuButtons() - - # Reinicia o background - self.__background.reset() - - # Inicializa a animação do background se True - if self.background_animation: - self.__background.run() - - # Cria um pássaro no jogo - self.__bird = Bird( - self.__background, - self.gameOver, - self.__width, - self.__height, - fp=self.bird_fp, - event=self.bird_event, - descend_speed=self.__bird_descend_speed, - ) - - # Cria tubos no jogo - self.__tubes = Tubes( - self.__background, - self.__bird, - self.increaseScore, - self.__width, - self.__height, - fp=self.tube_fp, - animation_speed=self.__background_animation_speed, - ) - - # Inicializa a animação do pássaro e dos tubos - self.__bird.start() - self.__tubes.start() + def draw(self, screen): + screen.blit(self.image, (self.x, self.y)) +# Pipe class +class Pipe: + def __init__(self): + self.image = pipe_image + self.x = screen_width + self.y = random.randint(150, screen_height - 150) + self.vel = 5 + + def update(self): + self.x -= self.vel + + def draw(self, screen): + screen.blit(self.image, (self.x, self.y)) + screen.blit(pygame.transform.flip(self.image, False, True), (self.x, self.y - screen_height)) + +def main(): + clock = pygame.time.Clock() + bird = Bird() + pipes = [Pipe()] + score = 0 + + running = True + while running: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE: + bird.flap() + + bird.update() + for pipe in pipes: + pipe.update() + if pipe.x + pipe.image.get_width() < 0: + pipes.remove(pipe) + pipes.append(Pipe()) + score += 1 + + screen.blit(background_image, (0, 0)) + bird.draw(screen) + for pipe in pipes: + pipe.draw(screen) + + pygame.display.update() + clock.tick(30) + + pygame.quit() if __name__ == "__main__": - try: - app = App() - app.init() - app.mainloop() - - except FileNotFoundError as error: - print(error) + main() From a4fe775fb338ab5a387e338c87b28db3a658dd67 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 18:46:53 +0000 Subject: [PATCH 255/442] Bump psutil from 6.1.1 to 7.0.0 Bumps [psutil](https://github.com/giampaolo/psutil) from 6.1.1 to 7.0.0. - [Changelog](https://github.com/giampaolo/psutil/blob/master/HISTORY.rst) - [Commits](https://github.com/giampaolo/psutil/compare/release-6.1.1...release-7.0.0) --- updated-dependencies: - dependency-name: psutil dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index db4749634de..44af1d0b3b5 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -101,7 +101,7 @@ pytest==8.3.4 qrcode==8.0 googletrans==4.0.2 slab==1.7.0 -psutil==6.1.1 +psutil==7.0.0 mediapipe==0.10.20 rich==13.9.4 httplib2==0.22.0 From 1ac8a566e87efd7440fe1de6383142b2dca8e47a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 18:47:00 +0000 Subject: [PATCH 256/442] Bump yfinance from 0.2.51 to 0.2.53 Bumps [yfinance](https://github.com/ranaroussi/yfinance) from 0.2.51 to 0.2.53. - [Release notes](https://github.com/ranaroussi/yfinance/releases) - [Changelog](https://github.com/ranaroussi/yfinance/blob/main/CHANGELOG.rst) - [Commits](https://github.com/ranaroussi/yfinance/compare/0.2.51...0.2.53) --- updated-dependencies: - dependency-name: yfinance dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index db4749634de..8cce566aa1d 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -66,7 +66,7 @@ speechtotext==0.0.3 wikipedia==1.4.0 tqdm==4.67.1 Menu==3.2.2 -yfinance==0.2.51 +yfinance==0.2.53 tweepy==4.15.0 tkcalendar==1.6.1 pytube==15.0.0 From b4c2caf57af2efb11a8c74a7c1871a6870c0ee99 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 18:19:21 +0000 Subject: [PATCH 257/442] Bump pymongo from 4.10.1 to 4.11.1 Bumps [pymongo](https://github.com/mongodb/mongo-python-driver) from 4.10.1 to 4.11.1. - [Release notes](https://github.com/mongodb/mongo-python-driver/releases) - [Changelog](https://github.com/mongodb/mongo-python-driver/blob/4.11.1/doc/changelog.rst) - [Commits](https://github.com/mongodb/mongo-python-driver/compare/4.10.1...4.11.1) --- updated-dependencies: - dependency-name: pymongo dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index ca05b4c1400..0b88bf150fa 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -42,7 +42,7 @@ obs==0.0.0 todo==0.1 oauth2client==4.1.3 keras==3.8.0 -pymongo==4.10.1 +pymongo==4.11.1 playsound==1.3.0 pyttsx3==2.98 auto-mix-prep==0.2.0 From 419a804e386b5fd2c001765d6d41c481290f24b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Feb 2025 18:43:43 +0000 Subject: [PATCH 258/442] Bump ccxt from 4.4.52 to 4.4.61 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.4.52 to 4.4.61. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.4.52...go/v4.4.61) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index ca05b4c1400..4b22007c615 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.7 gTTS==2.5.4 -ccxt==4.4.52 +ccxt==4.4.61 fitz==0.0.1.dev2 fastapi==0.115.6 Django==5.1.5 From 7994fa3de8480ad6c66858f886813d778a9043fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2025 18:15:09 +0000 Subject: [PATCH 259/442] Bump twilio from 9.4.5 to 9.4.6 Bumps [twilio](https://github.com/twilio/twilio-python) from 9.4.5 to 9.4.6. - [Release notes](https://github.com/twilio/twilio-python/releases) - [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md) - [Commits](https://github.com/twilio/twilio-python/compare/9.4.5...9.4.6) --- updated-dependencies: - dependency-name: twilio dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index ac4e5911956..d38ffe778e5 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -28,7 +28,7 @@ requests==2.32.3 quo==2023.5.1 PyPDF2==3.0.1 pyserial==3.5 -twilio==9.4.5 +twilio==9.4.6 tabula==1.0.5 nltk==3.9.1 Pillow==11.1.0 From c5f79c53c7ae12462a88bc363acc8c99d05d5130 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2025 18:15:19 +0000 Subject: [PATCH 260/442] Bump fastapi from 0.115.6 to 0.115.8 Bumps [fastapi](https://github.com/fastapi/fastapi) from 0.115.6 to 0.115.8. - [Release notes](https://github.com/fastapi/fastapi/releases) - [Commits](https://github.com/fastapi/fastapi/compare/0.115.6...0.115.8) --- updated-dependencies: - dependency-name: fastapi dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index ac4e5911956..97a4375ca0e 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -83,7 +83,7 @@ pynput==1.7.7 gTTS==2.5.4 ccxt==4.4.61 fitz==0.0.1.dev2 -fastapi==0.115.6 +fastapi==0.115.8 Django==5.1.5 docx==0.2.4 matplotlib==3.10.0 From 2829dbeb227da711a3cc5dd9483568dc907922dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 18:20:23 +0000 Subject: [PATCH 261/442] Bump aiohttp from 3.11.12 to 3.11.13 --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- async_downloader/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/async_downloader/requirements.txt b/async_downloader/requirements.txt index f06bf02f4d5..f817d01926f 100644 --- a/async_downloader/requirements.txt +++ b/async_downloader/requirements.txt @@ -1 +1 @@ -aiohttp==3.11.12 +aiohttp==3.11.13 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index bcf82f0c646..44b53191d2b 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -1,5 +1,5 @@ pafy==0.5.5 -aiohttp==3.11.12 +aiohttp==3.11.13 fuzzywuzzy==0.18.0 hupper==1.12.1 seaborn==0.13.2 From dab862ce3979c65550a790fbda732de836b908fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 18:20:27 +0000 Subject: [PATCH 262/442] Bump pyglet from 2.1.1 to 2.1.3 Bumps [pyglet](https://github.com/pyglet/pyglet) from 2.1.1 to 2.1.3. - [Release notes](https://github.com/pyglet/pyglet/releases) - [Changelog](https://github.com/pyglet/pyglet/blob/master/RELEASE_NOTES) - [Commits](https://github.com/pyglet/pyglet/compare/v2.1.1...v2.1.3) --- updated-dependencies: - dependency-name: pyglet dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- PongPong_Game/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PongPong_Game/requirements.txt b/PongPong_Game/requirements.txt index de35804cc81..9fa555f42d1 100644 --- a/PongPong_Game/requirements.txt +++ b/PongPong_Game/requirements.txt @@ -1 +1 @@ -pyglet==2.1.1 +pyglet==2.1.3 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index bcf82f0c646..8488bd20fdd 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -55,7 +55,7 @@ pydantic==2.10.3 openpyxl==3.1.2 pytesseract==0.3.13 requests-mock==1.12.1 -pyglet==2.1.1 +pyglet==2.1.3 urllib3==2.3.0 thirdai==0.9.25 google-api-python-client==2.160.0 From b8d26ee0bb25cdb1e4a5948f90f22d350ef343e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 18:35:39 +0000 Subject: [PATCH 263/442] Bump django from 5.1.5 to 5.1.6 Bumps [django](https://github.com/django/django) from 5.1.5 to 5.1.6. - [Commits](https://github.com/django/django/compare/5.1.5...5.1.6) --- updated-dependencies: - dependency-name: django dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 56e2e891722..21b5b1e95d9 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -84,7 +84,7 @@ gTTS==2.5.4 ccxt==4.4.61 fitz==0.0.1.dev2 fastapi==0.115.8 -Django==5.1.5 +Django==5.1.6 docx==0.2.4 matplotlib==3.10.0 pyshorteners==1.0.1 From bc46d32d6fa9bea97e3f602dfa447bc5526d68dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 18:35:53 +0000 Subject: [PATCH 264/442] Bump ccxt from 4.4.61 to 4.4.62 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.4.61 to 4.4.62. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/go/v4.4.61...v4.4.62) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 56e2e891722..780fe36efb5 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.7.7 gTTS==2.5.4 -ccxt==4.4.61 +ccxt==4.4.62 fitz==0.0.1.dev2 fastapi==0.115.8 Django==5.1.5 From b7818c53e00e29f14e7e4ce969f67d853adb7625 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 18:38:29 +0000 Subject: [PATCH 265/442] Bump google-api-python-client from 2.160.0 to 2.162.0 Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.160.0 to 2.162.0. - [Release notes](https://github.com/googleapis/google-api-python-client/releases) - [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.160.0...v2.162.0) --- updated-dependencies: - dependency-name: google-api-python-client dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 2be33250a1a..4fac8dd2fea 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -58,7 +58,7 @@ requests-mock==1.12.1 pyglet==2.1.3 urllib3==2.3.0 thirdai==0.9.25 -google-api-python-client==2.160.0 +google-api-python-client==2.162.0 sound==0.1.0 xlwt==1.3.0 pygame==2.6.1 From 208682deba2dd7fda7c81a3e06d49dfc7ee864b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 18:17:38 +0000 Subject: [PATCH 266/442] Bump openai from 1.59.6 to 1.65.2 Bumps [openai](https://github.com/openai/openai-python) from 1.59.6 to 1.65.2. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.59.6...v1.65.2) --- updated-dependencies: - dependency-name: openai dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4fac8dd2fea..a9e57d315ad 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.59.6 +openai==1.65.2 background==0.2.1 pydantic==2.10.3 openpyxl==3.1.2 From f832611b5561cae51796fd8b9c7e0f72067d9149 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 18:09:20 +0000 Subject: [PATCH 267/442] Bump pymongo from 4.11.1 to 4.11.2 Bumps [pymongo](https://github.com/mongodb/mongo-python-driver) from 4.11.1 to 4.11.2. - [Release notes](https://github.com/mongodb/mongo-python-driver/releases) - [Changelog](https://github.com/mongodb/mongo-python-driver/blob/master/doc/changelog.rst) - [Commits](https://github.com/mongodb/mongo-python-driver/compare/4.11.1...4.11.2) --- updated-dependencies: - dependency-name: pymongo dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index a9e57d315ad..8d08d53538e 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -42,7 +42,7 @@ obs==0.0.0 todo==0.1 oauth2client==4.1.3 keras==3.8.0 -pymongo==4.11.1 +pymongo==4.11.2 playsound==1.3.0 pyttsx3==2.98 auto-mix-prep==0.2.0 From 993218922f1e4bd7d71227a40988bdd279f0a388 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Mar 2025 18:59:59 +0000 Subject: [PATCH 268/442] Bump solara from 1.44.0 to 1.44.1 Bumps [solara](https://github.com/widgetti/solara) from 1.44.0 to 1.44.1. - [Changelog](https://github.com/widgetti/solara/blob/master/CHANGELOG.md) - [Commits](https://github.com/widgetti/solara/compare/v1.44.0...v1.44.1) --- updated-dependencies: - dependency-name: solara dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- News_App/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/News_App/requirements.txt b/News_App/requirements.txt index a7150d774c4..926bafe0714 100644 --- a/News_App/requirements.txt +++ b/News_App/requirements.txt @@ -1,4 +1,4 @@ -solara == 1.44.0 +solara == 1.44.1 Flask gunicorn ==23.0.0 simple-websocket diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 8d08d53538e..477ec29242d 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -74,7 +74,7 @@ xor-cipher==5.0.1 bird==0.1.2 mechanize==0.4.10 translate==3.6.1 -solara==1.44.0 +solara==1.44.1 pywhatkit==5.4 mutagen==1.47.0 Unidecode==1.3.8 From 6a6e405e4bae38f43cf78b75ee5f67c31daeb345 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Mar 2025 18:04:28 +0000 Subject: [PATCH 269/442] Bump pynput from 1.7.7 to 1.8.0 Bumps [pynput](https://github.com/moses-palmer/pynput) from 1.7.7 to 1.8.0. - [Changelog](https://github.com/moses-palmer/pynput/blob/master/CHANGES.rst) - [Commits](https://github.com/moses-palmer/pynput/compare/v1.7.7...v1.8.0) --- updated-dependencies: - dependency-name: pynput dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 477ec29242d..a7bc251b168 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -79,7 +79,7 @@ pywhatkit==5.4 mutagen==1.47.0 Unidecode==1.3.8 Ball==0.2.9 -pynput==1.7.7 +pynput==1.8.0 gTTS==2.5.4 ccxt==4.4.62 fitz==0.0.1.dev2 From 5f016ad2bc3595239ae757b31bc375eb80878625 Mon Sep 17 00:00:00 2001 From: Parsa Javanshir <79544911+parsajavanshir@users.noreply.github.com> Date: Fri, 7 Mar 2025 22:52:16 +0330 Subject: [PATCH 270/442] Fix assembler.py Fix: Bug fixes in stack management, division by zero, and string handling - Fixed stack underflow in `pop` command - Handled division by zero in `div` instruction - Validated empty files before processing - Added exception handling for return stack - Improved string assignment in `mov` instruction --- Assembler/assembler.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Assembler/assembler.py b/Assembler/assembler.py index 24a6840c1d4..0acd48b1535 100644 --- a/Assembler/assembler.py +++ b/Assembler/assembler.py @@ -996,10 +996,13 @@ def parser(): if token.token in variables: token.token = variables[token.token] else: - print("Error: undefine variable! --> " + token.token) + print(f"Error: Undefined variable {token.token}") return + elif token.t == "string": - pass + + token.token = str(token.token) + elif isinstance(token.token, float): pass elif token.token.isdigit(): @@ -1161,7 +1164,7 @@ def parser(): zeroFlag = False elif tmpToken.token == "ebx": ebx -= token.token - + # update zero flag if ebx == 0: zeroFlag = True @@ -1249,6 +1252,9 @@ def parser(): # pop register from stack match token.token: case "eax": + if len(stack) == 0: + print("Error: Stack Underflow") + return eax = stack.pop() case "ebx": ebx = stack.pop() @@ -1454,6 +1460,9 @@ def parser(): eax /= eax case "ebx": + if ebx == 0: + print("Error: Division by Zero") + return eax /= ebx case "ecx": From d5581425b27023f1744ef6db1b7b699357fea8a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 18:56:11 +0000 Subject: [PATCH 271/442] Bump pytest from 8.3.4 to 8.3.5 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.4 to 8.3.5. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.3.4...8.3.5) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index a7bc251b168..1078fc6a964 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -97,7 +97,7 @@ newspaper==0.1.0.7 opencv-python==4.11.0.86 tensorflow==2.15.0.post1 pandas==2.2.3 -pytest==8.3.4 +pytest==8.3.5 qrcode==8.0 googletrans==4.0.2 slab==1.7.0 From 35109822bc4e04afa8f8cebcad67d0a5d56a88d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 18:41:54 +0000 Subject: [PATCH 272/442] Bump numpy from 2.2.2 to 2.2.3 Bumps [numpy](https://github.com/numpy/numpy) from 2.2.2 to 2.2.3. - [Release notes](https://github.com/numpy/numpy/releases) - [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst) - [Commits](https://github.com/numpy/numpy/compare/v2.2.2...v2.2.3) --- updated-dependencies: - dependency-name: numpy dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Hand-Motion-Detection/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt index 5a3a516abb1..3b276940237 100644 --- a/Hand-Motion-Detection/requirements.txt +++ b/Hand-Motion-Detection/requirements.txt @@ -1,3 +1,3 @@ -numpy==2.2.2 +numpy==2.2.3 opencv_python==4.11.0.86 mediapipe==0.10.20 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 1078fc6a964..2d93d059546 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -15,7 +15,7 @@ dictator==0.3.1 caller==0.0.2 watchdog==6.0.0 PyQt5==5.15.11 -numpy==2.2.2 +numpy==2.2.3 fileinfo==0.3.3 backend==0.2.4.1 win10toast==0.9 From 0c3d85970b03e2e7270ff1ce4f9abd3333acbf78 Mon Sep 17 00:00:00 2001 From: Mohd Zaid Amaan Date: Wed, 12 Mar 2025 04:32:40 +0530 Subject: [PATCH 273/442] HTML to PDF done --- .gitignore | 1 + HTML_to_PDF/index.html | 221 +++++++++++++++++++++++++++++++++++++++++ HTML_to_PDF/main.py | 28 ++++++ HTML_to_PDF/output.pdf | Bin 0 -> 35589 bytes output.pdf | Bin 0 -> 1235 bytes 5 files changed, 250 insertions(+) create mode 100644 HTML_to_PDF/index.html create mode 100644 HTML_to_PDF/main.py create mode 100644 HTML_to_PDF/output.pdf create mode 100644 output.pdf diff --git a/.gitignore b/.gitignore index e2cee02848f..1f15459f4de 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ for i in string: odd+=i print(lower+upper+odd+even) +.venv # operating system-related files # file properties cache/storage on macOS diff --git a/HTML_to_PDF/index.html b/HTML_to_PDF/index.html new file mode 100644 index 00000000000..6b39d63cb2d --- /dev/null +++ b/HTML_to_PDF/index.html @@ -0,0 +1,221 @@ + + + + + + HTML to PDF Test Page + + + + + +
+ 📄 This page is created for testing HTML to PDF conversion! +
+ +
+
+

HTML to PDF Test

+ +
+
+ +
+
+

Welcome!

+

This is a test page designed to check HTML to PDF conversion.

+
+ ⚡ This section highlights that we are testing the ability to convert HTML pages into PDF format. +
+
+ +
+

About This Test

+

This page includes various HTML elements to check how they appear in the converted PDF.

+
+ +
+

Elements to Test

+
    +
  • Headings & Paragraphs
  • +
  • Navigation & Links
  • +
  • Lists & Bullet Points
  • +
  • Background Colors & Styling
  • +
  • Margins & Spacing
  • +
+
+ +
+

Need Help?

+

For any issues with the HTML to PDF conversion, contact us at: info@example.com

+
+
+ +
+

© 2025 HTML to PDF Test Page. All rights reserved.

+
+ + + diff --git a/HTML_to_PDF/main.py b/HTML_to_PDF/main.py new file mode 100644 index 00000000000..67954b0a2a9 --- /dev/null +++ b/HTML_to_PDF/main.py @@ -0,0 +1,28 @@ +import pdfkit +import os + +# Download wkhtmltopdf from https://wkhtmltopdf.org/downloads.html +# Set the path to the wkhtmltopdf executable + +wkhtmltopdf_path = r'C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe' + +# Configure pdfkit to use wkhtmltopdf +config = pdfkit.configuration(wkhtmltopdf=wkhtmltopdf_path) + +# Path of HTML and PDF files +path=os.getcwd() +htmlFile = f'{path}\\index.html' +pdfFile = f'{path}\\output.pdf' + +# Check if the HTML file exists before proceeding +if not os.path.exists(htmlFile): + print(f"HTML file does not exist at: {htmlFile}") +else: + try: + # Convert HTML to PDF + pdfkit.from_file(htmlFile, pdfFile, configuration=config) + print(f"Successfully converted HTML to PDF: {pdfFile}") + except Exception as e: + print(f"An error occurred: {e}") + + diff --git a/HTML_to_PDF/output.pdf b/HTML_to_PDF/output.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8d8f56439f2ff3a4ad005e81d786d3ad522f601a GIT binary patch literal 35589 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 T^o8Szpfgb;LdV8t7nAfK^dn9T literal 0 HcmV?d00001 From 39bc685ac013cccbff932408758099630735ca11 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Mar 2025 18:34:47 +0000 Subject: [PATCH 274/442] Bump keras from 3.8.0 to 3.9.0 Bumps [keras](https://github.com/keras-team/keras) from 3.8.0 to 3.9.0. - [Release notes](https://github.com/keras-team/keras/releases) - [Commits](https://github.com/keras-team/keras/compare/v3.8.0...v3.9.0) --- updated-dependencies: - dependency-name: keras dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 2d93d059546..27512b19620 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -41,7 +41,7 @@ tornado==6.4.2 obs==0.0.0 todo==0.1 oauth2client==4.1.3 -keras==3.8.0 +keras==3.9.0 pymongo==4.11.2 playsound==1.3.0 pyttsx3==2.98 From 8d56d81e8328f19d3cc5387d78201b86e8f248aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Mar 2025 18:35:04 +0000 Subject: [PATCH 275/442] Bump tensorflow from 2.15.0.post1 to 2.18.1 Bumps [tensorflow](https://github.com/tensorflow/tensorflow) from 2.15.0.post1 to 2.18.1. - [Release notes](https://github.com/tensorflow/tensorflow/releases) - [Changelog](https://github.com/tensorflow/tensorflow/blob/v2.18.1/RELEASE.md) - [Commits](https://github.com/tensorflow/tensorflow/commits/v2.18.1) --- updated-dependencies: - dependency-name: tensorflow dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 2d93d059546..35ccb32df95 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -95,7 +95,7 @@ freegames==2.5.3 pyperclip==1.8.2 newspaper==0.1.0.7 opencv-python==4.11.0.86 -tensorflow==2.15.0.post1 +tensorflow==2.18.1 pandas==2.2.3 pytest==8.3.5 qrcode==8.0 From 2e17a793030b18d25e7000036efdbec6ac22004d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Mar 2025 18:05:35 +0000 Subject: [PATCH 276/442] Bump openai from 1.65.2 to 1.66.3 Bumps [openai](https://github.com/openai/openai-python) from 1.65.2 to 1.66.3. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.65.2...v1.66.3) --- updated-dependencies: - dependency-name: openai dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 50d330ab2a7..3e6f40d5c71 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.65.2 +openai==1.66.3 background==0.2.1 pydantic==2.10.3 openpyxl==3.1.2 From f88113276bbff0b353ae0cc1040922ea55eda985 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Mar 2025 18:05:37 +0000 Subject: [PATCH 277/442] Bump firebase-admin from 6.6.0 to 6.7.0 Bumps [firebase-admin](https://github.com/firebase/firebase-admin-python) from 6.6.0 to 6.7.0. - [Release notes](https://github.com/firebase/firebase-admin-python/releases) - [Commits](https://github.com/firebase/firebase-admin-python/compare/v6.6.0...v6.7.0) --- updated-dependencies: - dependency-name: firebase-admin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 50d330ab2a7..459f7958df3 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -22,7 +22,7 @@ win10toast==0.9 Counter==1.0.0 Flask==3.1.0 selenium==4.27.1 -firebase-admin==6.6.0 +firebase-admin==6.7.0 ujson==5.10.0 requests==2.32.3 quo==2023.5.1 From 3fe9ea992478c7bb2ffff4d97dd16cb5969c52c2 Mon Sep 17 00:00:00 2001 From: Mohammad Sameer Date: Mon, 17 Mar 2025 12:34:18 +0530 Subject: [PATCH 278/442] "Added Pomodoro Timer made with tkinter" --- Pomodoro (tkinter).py | 208 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 Pomodoro (tkinter).py diff --git a/Pomodoro (tkinter).py b/Pomodoro (tkinter).py new file mode 100644 index 00000000000..964963c5894 --- /dev/null +++ b/Pomodoro (tkinter).py @@ -0,0 +1,208 @@ +from tkinter import * + +# ---------------------------- CONSTANTS & GLOBALS ------------------------------- # +PINK = "#e2979c" +GREEN = "#9bdeac" +FONT_NAME = "Courier" +DEFAULT_WORK_MIN = 25 +DEFAULT_BREAK_MIN = 5 + +# Background color options +bg_colors = { + "Pink": "#e2979c", + "Green": "#9bdeac", + "Blue": "#1f75fe", + "Yellow": "#ffcc00", + "Purple": "#b19cd9" +} + +# Global variables +ROUND = 1 +timer_mec = None +total_time = 0 # Total seconds for the current session +is_paused = False # Timer pause flag +remaining_time = 0 # Remaining time (in seconds) when paused +custom_work_min = DEFAULT_WORK_MIN +custom_break_min = DEFAULT_BREAK_MIN + +# ---------------------------- BACKGROUND COLOR CHANGE FUNCTION ------------------------------- # +def change_background(*args): + selected = bg_color_var.get() + new_color = bg_colors.get(selected, PINK) + window.config(bg=new_color) + canvas.config(bg=new_color) + label.config(bg=new_color) + tick_label.config(bg=new_color) + work_label.config(bg=new_color) + break_label.config(bg=new_color) + +# ---------------------------- NOTIFICATION FUNCTION ------------------------------- # +def show_notification(message): + notif = Toplevel(window) + notif.overrideredirect(True) + notif.config(bg=PINK) + + msg_label = Label(notif, text=message, font=(FONT_NAME, 12, "bold"), + bg=GREEN, fg="white", padx=10, pady=5) + msg_label.pack() + + window.update_idletasks() + wx = window.winfo_rootx() + wy = window.winfo_rooty() + wwidth = window.winfo_width() + wheight = window.winfo_height() + + notif.update_idletasks() + nwidth = notif.winfo_width() + nheight = notif.winfo_height() + + x = wx + (wwidth - nwidth) // 2 + y = wy + wheight - nheight - 10 + notif.geometry(f"+{x}+{y}") + + notif.after(3000, notif.destroy) + +# ---------------------------- TIMER FUNCTIONS ------------------------------- # +def reset_timer(): + global ROUND, timer_mec, total_time, is_paused, remaining_time + ROUND = 1 + is_paused = False + remaining_time = 0 + if timer_mec is not None: + window.after_cancel(timer_mec) + canvas.itemconfig(timer_text, text="00:00") + label.config(text="Timer") + tick_label.config(text="") + total_time = 0 + canvas.itemconfig(progress_arc, extent=0) + start_button.config(state=NORMAL) + pause_button.config(state=DISABLED) + play_button.config(state=DISABLED) + +def start_timer(): + global ROUND, total_time, is_paused + canvas.itemconfig(progress_arc, extent=0) + + if ROUND % 2 == 1: # Work session + total_time = custom_work_min * 60 + label.config(text="Work", fg=GREEN) + else: # Break session + total_time = custom_break_min * 60 + label.config(text="Break", fg=PINK) + + count_down(total_time) + start_button.config(state=DISABLED) + pause_button.config(state=NORMAL) + play_button.config(state=DISABLED) + is_paused = False + +def count_down(count): + global timer_mec, remaining_time + remaining_time = count + minutes = count // 60 + seconds = count % 60 + if seconds < 10: + seconds = f"0{seconds}" + canvas.itemconfig(timer_text, text=f"{minutes}:{seconds}") + + if total_time > 0: + progress = (total_time - count) / total_time + canvas.itemconfig(progress_arc, extent=progress * 360) + + if count > 0 and not is_paused: + timer_mec = window.after(1000, count_down, count - 1) + elif count == 0: + if ROUND % 2 == 1: + show_notification("Work session complete! Time for a break.") + else: + show_notification("Break over! Back to work.") + if ROUND % 2 == 0: + tick_label.config(text=tick_label.cget("text") + "#") + ROUND += 1 + start_timer() + +def pause_timer(): + global is_paused, timer_mec + if not is_paused: + is_paused = True + if timer_mec is not None: + window.after_cancel(timer_mec) + pause_button.config(state=DISABLED) + play_button.config(state=NORMAL) + +def resume_timer(): + global is_paused + if is_paused: + is_paused = False + count_down(remaining_time) + play_button.config(state=DISABLED) + pause_button.config(state=NORMAL) + +def set_custom_durations(): + global custom_work_min, custom_break_min + try: + work_val = int(entry_work.get()) + break_val = int(entry_break.get()) + custom_work_min = work_val + custom_break_min = break_val + canvas.itemconfig(left_custom, text=f"{custom_work_min}m") + canvas.itemconfig(right_custom, text=f"{custom_break_min}m") + except ValueError: + pass + +# ---------------------------- UI SETUP ------------------------------- # +window = Tk() +window.title("Pomodoro") +window.config(padx=100, pady=50, bg=PINK) + +# Canvas setup with increased width for spacing +canvas = Canvas(window, width=240, height=224, bg=PINK, highlightthickness=0) +timer_text = canvas.create_text(120, 112, text="00:00", font=(FONT_NAME, 35, "bold"), fill="white") +background_circle = canvas.create_arc(40, 32, 200, 192, start=0, extent=359.9, + style="arc", outline="white", width=5) +progress_arc = canvas.create_arc(40, 32, 200, 192, start=270, extent=0, + style="arc", outline="green", width=5) +# Updated positions for work and break time labels +left_custom = canvas.create_text(20, 112, text=f"{custom_work_min}m", font=(FONT_NAME, 12, "bold"), fill="white") +right_custom = canvas.create_text(220, 112, text=f"{custom_break_min}m", font=(FONT_NAME, 12, "bold"), fill="white") + +canvas.grid(column=1, row=1) + +label = Label(text="Timer", font=(FONT_NAME, 35, "bold"), bg=PINK, fg="green") +label.grid(column=1, row=0) + +start_button = Button(text="Start", command=start_timer, highlightthickness=0) +start_button.grid(column=0, row=2) + +reset_button = Button(text="Reset", command=reset_timer, highlightthickness=0) +reset_button.grid(column=2, row=2) + +pause_button = Button(text="Pause", command=pause_timer, highlightthickness=0, state=DISABLED) +pause_button.grid(column=0, row=3) + +play_button = Button(text="Play", command=resume_timer, highlightthickness=0, state=DISABLED) +play_button.grid(column=2, row=3) + +tick_label = Label(text="", font=(FONT_NAME, 15, "bold"), bg=PINK, fg="green") +tick_label.grid(column=1, row=4) + +# Custom durations (stacked vertically) +work_label = Label(text="Work (min):", font=(FONT_NAME, 12, "bold"), bg=PINK, fg="white") +work_label.grid(column=1, row=5, pady=(20, 0)) +entry_work = Entry(width=5, font=(FONT_NAME, 12)) +entry_work.grid(column=1, row=6, pady=(5, 10)) +break_label = Label(text="Break (min):", font=(FONT_NAME, 12, "bold"), bg=PINK, fg="white") +break_label.grid(column=1, row=7, pady=(5, 0)) +entry_break = Entry(width=5, font=(FONT_NAME, 12)) +entry_break.grid(column=1, row=8, pady=(5, 10)) +set_button = Button(text="Set Durations", command=set_custom_durations, font=(FONT_NAME, 12)) +set_button.grid(column=1, row=9, pady=(10, 20)) + +# OptionMenu for changing background color +bg_color_var = StringVar(window) +bg_color_var.set("Pink") +bg_option = OptionMenu(window, bg_color_var, *bg_colors.keys(), command=change_background) +bg_option.config(font=(FONT_NAME, 12)) +bg_option.grid(column=1, row=10, pady=(10, 20)) + +window.mainloop() From be0082df96896c1f3ff45df0c7804090f4e557ea Mon Sep 17 00:00:00 2001 From: Shaurya Chauhan <93973876+OP-Raaja@users.noreply.github.com> Date: Tue, 18 Mar 2025 22:29:07 +0530 Subject: [PATCH 279/442] Fix: Added missing closing quote in documentation Resolved a minor issue in the documentation where the closing quote was missing. --- 1 File handle/File handle text/question 6.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1 File handle/File handle text/question 6.py b/1 File handle/File handle text/question 6.py index a98fe3a7cfb..467ea401995 100644 --- a/1 File handle/File handle text/question 6.py +++ b/1 File handle/File handle text/question 6.py @@ -1,5 +1,5 @@ """Write a function in python to count the number of lowercase -alphabets present in a text file “happy.txt""" +alphabets present in a text file “happy.txt”""" from counter import Counter From bac1c802386c40179c63df24dddc4475e3996ec6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Mar 2025 18:42:56 +0000 Subject: [PATCH 280/442] Bump django from 5.1.6 to 5.1.7 Bumps [django](https://github.com/django/django) from 5.1.6 to 5.1.7. - [Commits](https://github.com/django/django/compare/5.1.6...5.1.7) --- updated-dependencies: - dependency-name: django dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index de73932ef2c..389dddfd253 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -84,7 +84,7 @@ gTTS==2.5.4 ccxt==4.4.62 fitz==0.0.1.dev2 fastapi==0.115.8 -Django==5.1.6 +Django==5.1.7 docx==0.2.4 matplotlib==3.10.0 pyshorteners==1.0.1 From 2212a053cb72f58d335af5c74e1260bb1fec019f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Mar 2025 18:43:15 +0000 Subject: [PATCH 281/442] Bump aiohttp from 3.11.13 to 3.11.14 --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- async_downloader/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/async_downloader/requirements.txt b/async_downloader/requirements.txt index f817d01926f..ffcb1b6959d 100644 --- a/async_downloader/requirements.txt +++ b/async_downloader/requirements.txt @@ -1 +1 @@ -aiohttp==3.11.13 +aiohttp==3.11.14 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index de73932ef2c..bfcfcf9aad0 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -1,5 +1,5 @@ pafy==0.5.5 -aiohttp==3.11.13 +aiohttp==3.11.14 fuzzywuzzy==0.18.0 hupper==1.12.1 seaborn==0.13.2 From ab939bac3b0e0d0d81df291b0d323a271855dc39 Mon Sep 17 00:00:00 2001 From: Sureshreddy7032 Date: Thu, 20 Mar 2025 11:43:03 -0400 Subject: [PATCH 282/442] Create cicd --- cicd | 1 + 1 file changed, 1 insertion(+) create mode 100644 cicd diff --git a/cicd b/cicd new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/cicd @@ -0,0 +1 @@ + From 16a28bebd477cd37e540b3aa3537109accbfe705 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 19:05:00 +0000 Subject: [PATCH 283/442] Bump yfinance from 0.2.53 to 0.2.54 Bumps [yfinance](https://github.com/ranaroussi/yfinance) from 0.2.53 to 0.2.54. - [Release notes](https://github.com/ranaroussi/yfinance/releases) - [Changelog](https://github.com/ranaroussi/yfinance/blob/main/CHANGELOG.rst) - [Commits](https://github.com/ranaroussi/yfinance/compare/0.2.53...0.2.54) --- updated-dependencies: - dependency-name: yfinance dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 1ad7ec9f852..440d8929be5 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -66,7 +66,7 @@ speechtotext==0.0.3 wikipedia==1.4.0 tqdm==4.67.1 Menu==3.2.2 -yfinance==0.2.53 +yfinance==0.2.54 tweepy==4.15.0 tkcalendar==1.6.1 pytube==15.0.0 From be71b30f6c619dc3d65f673a1670a48f60596f7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 19:05:04 +0000 Subject: [PATCH 284/442] Bump openai from 1.66.3 to 1.68.0 Bumps [openai](https://github.com/openai/openai-python) from 1.66.3 to 1.68.0. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.66.3...v1.68.0) --- updated-dependencies: - dependency-name: openai dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 1ad7ec9f852..df6ca30dd65 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.66.3 +openai==1.68.0 background==0.2.1 pydantic==2.10.3 openpyxl==3.1.2 From d51f2144c9747b02834c4784bb6098c9ead1c64a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Mar 2025 18:55:54 +0000 Subject: [PATCH 285/442] Bump selenium from 4.27.1 to 4.29.0 Bumps [selenium](https://github.com/SeleniumHQ/Selenium) from 4.27.1 to 4.29.0. - [Release notes](https://github.com/SeleniumHQ/Selenium/releases) - [Commits](https://github.com/SeleniumHQ/Selenium/commits/selenium-4.29.0) --- updated-dependencies: - dependency-name: selenium dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 07d014abdb1..4a2280b913d 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -21,7 +21,7 @@ backend==0.2.4.1 win10toast==0.9 Counter==1.0.0 Flask==3.1.0 -selenium==4.27.1 +selenium==4.29.0 firebase-admin==6.7.0 ujson==5.10.0 requests==2.32.3 From 8686f8edc8ce381650ffff8cc3c8cb0ce938e43d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Mar 2025 18:56:13 +0000 Subject: [PATCH 286/442] Bump pymongo from 4.11.2 to 4.11.3 Bumps [pymongo](https://github.com/mongodb/mongo-python-driver) from 4.11.2 to 4.11.3. - [Release notes](https://github.com/mongodb/mongo-python-driver/releases) - [Changelog](https://github.com/mongodb/mongo-python-driver/blob/4.11.3/doc/changelog.rst) - [Commits](https://github.com/mongodb/mongo-python-driver/compare/4.11.2...4.11.3) --- updated-dependencies: - dependency-name: pymongo dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 07d014abdb1..f66ba60e5f9 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -42,7 +42,7 @@ obs==0.0.0 todo==0.1 oauth2client==4.1.3 keras==3.9.0 -pymongo==4.11.2 +pymongo==4.11.3 playsound==1.3.0 pyttsx3==2.98 auto-mix-prep==0.2.0 From 42bb001ad4b6bfb8162336ffd500b3a5563f7b15 Mon Sep 17 00:00:00 2001 From: JLPURE Date: Sat, 22 Mar 2025 11:56:07 -0700 Subject: [PATCH 287/442] Create datadog-synthetics.yml --- .github/workflows/datadog-synthetics.yml | 38 ++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/workflows/datadog-synthetics.yml diff --git a/.github/workflows/datadog-synthetics.yml b/.github/workflows/datadog-synthetics.yml new file mode 100644 index 00000000000..ae3a26706d9 --- /dev/null +++ b/.github/workflows/datadog-synthetics.yml @@ -0,0 +1,38 @@ +# This workflow will trigger Datadog Synthetic tests within your Datadog organisation +# For more information on running Synthetic tests within your GitHub workflows see: https://docs.datadoghq.com/synthetics/cicd_integrations/github_actions/ + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# To get started: + +# 1. Add your Datadog API (DD_API_KEY) and Application Key (DD_APP_KEY) as secrets to your GitHub repository. For more information, see: https://docs.datadoghq.com/account_management/api-app-keys/. +# 2. Start using the action within your workflow + +name: Run Datadog Synthetic tests + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + # Run Synthetic tests within your GitHub workflow. + # For additional configuration options visit the action within the marketplace: https://github.com/marketplace/actions/datadog-synthetics-ci + - name: Run Datadog Synthetic tests + uses: DataDog/synthetics-ci-github-action@87b505388a22005bb8013481e3f73a367b9a53eb # v1.4.0 + with: + api_key: ${{secrets.DD_API_KEY}} + app_key: ${{secrets.DD_APP_KEY}} + test_search_query: 'tag:e2e-tests' #Modify this tag to suit your tagging strategy + + From 8a146841e96ceee4abbafa9cde83ac5b0d561adf Mon Sep 17 00:00:00 2001 From: Pulkit Bajaj Date: Sun, 23 Mar 2025 12:42:00 +0530 Subject: [PATCH 288/442] added new file Task1.2 --- .github/workflows/lint_python.yml | 2 +- AI Game/Tic-Tac-Toe-AI/tictactoe.py | 2 +- Task1.2.txt | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 Task1.2.txt diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml index 4fbba44f38d..b90bd664f4a 100644 --- a/.github/workflows/lint_python.yml +++ b/.github/workflows/lint_python.yml @@ -1,4 +1,4 @@ -name: lint_python +name: python on: [pull_request, push] jobs: lint_python: diff --git a/AI Game/Tic-Tac-Toe-AI/tictactoe.py b/AI Game/Tic-Tac-Toe-AI/tictactoe.py index 6157ff6efb0..0488e5acfdf 100644 --- a/AI Game/Tic-Tac-Toe-AI/tictactoe.py +++ b/AI Game/Tic-Tac-Toe-AI/tictactoe.py @@ -19,7 +19,7 @@ def minimax(board, depth, is_maximizing): return -1 if check_winner(board, 'O'): return 1 - if is_board_full(board): #if game is full, terminate + if is_board_full(board): return 0 if is_maximizing: #recursive approach that fills board with Os diff --git a/Task1.2.txt b/Task1.2.txt new file mode 100644 index 00000000000..e100a2ca4ab --- /dev/null +++ b/Task1.2.txt @@ -0,0 +1 @@ +Task 1.2 From be41df53c14e4e607a8822be57a4acad104c0480 Mon Sep 17 00:00:00 2001 From: dendogg Date: Mon, 24 Mar 2025 05:44:54 -0700 Subject: [PATCH 289/442] Updated two_num.py ### Summary Refactored the `two_sum` function to enhance clarity, improve structure, and ensure compliance with Python best practices (PEP 8). This version prioritizes intuitive logic, robust error handling, and clear documentation. ### Key Changes - **Function Renaming:** Renamed `twoSum` to `two_sum` to adhere to PEP 8 standards for function naming. - **Improved Variable Naming:** Replaced ambiguous names (`chk_map`, `compl`) with more intuitive identifiers (`seen_values`, `complement`). - **Added Type Hints:** Introduced `from typing import List, Union` to improve code clarity and provide IDE/linter support. - **Enhanced Docstring:** Expanded the docstring to include detailed function descriptions, argument explanations, and return behavior. - **Robust Return Handling:** Ensured the function explicitly returns `False` if no valid pair is found, improving clarity in edge cases. - **Improved Output Structure:** Added a `__main__` block with structured output for cleaner and more informative result display. ### Rationale These changes improve: - **Readability:** Clearer variable names and enhanced documentation make the code easier to understand for future developers (and my future self). - **Maintainability:** Improved structure provides a stronger foundation for future feature enhancements or modifications. - **Compliance:** Aligns with Python's official best practices for formatting and style (PEP 8). --- two_num.py | 69 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 19 deletions(-) diff --git a/two_num.py b/two_num.py index 5780845217f..5174457affb 100644 --- a/two_num.py +++ b/two_num.py @@ -1,26 +1,57 @@ -"""Author Anurag Kumar (mailto:anuragkumarak95@gmail.com) +""" +Author: Anurag Kumar (mailto:anuragkumarak95@gmail.com) -Given an array of integers, return indices of the two numbers -such that they add up to a specific target. -You may assume that each input would have exactly one solution, -and you may not use the same element twice. +Description: + This function finds two numbers in a given list that add up to a specified target. + It returns the indices of those two numbers. -Example: -Given nums = [2, 7, 11, 15], target = 9, -Because nums[0] + nums[1] = 2 + 7 = 9, -return [0, 1]. +Constraints: + - Each input will have exactly one solution. + - The same element cannot be used twice. +Example: + >>> two_sum([2, 7, 11, 15], 9) + [0, 1] """ +from typing import List, Union + +def two_sum(nums: List[int], target: int) -> Union[List[int], bool]: + """ + Finds indices of two numbers in 'nums' that add up to 'target'. + + Args: + nums (List[int]): List of integers. + target (int): Target sum. -def twoSum(nums, target): - chk_map = {} - for index, val in enumerate(nums): - compl = target - val - if compl in chk_map: - indices = [chk_map[compl], index] - print(indices) - return [indices] - else: - chk_map[val] = index + Returns: + List[int]: Indices of the two numbers that add up to the target. + False: If no such pair is found. + """ + # Dictionary to track seen values and their indices + seen_values = {} + + for index, value in enumerate(nums): + complement = target - value + + # Check if the complement exists in the dictionary + if complement in seen_values: + return [seen_values[complement], index] + + # Add current value to dictionary for future reference + seen_values[value] = index + + # Return False if no pair is found (explicit is better than implicit) return False + +# Example usage +if __name__ == "__main__": + example_nums = [2, 7, 11, 15] + example_target = 9 + result = two_sum(example_nums, example_target) + + # Clean, professional result display + if result: + print(f"Indices that add up to {example_target}: {result}") + else: + print(f"No combination found that adds up to {example_target}.") From 45bdaba263079a1c496f81aa143517dc50af761c Mon Sep 17 00:00:00 2001 From: dendogg Date: Mon, 24 Mar 2025 05:57:34 -0700 Subject: [PATCH 290/442] Update two_num.py refactor: improve two_sum function with enhanced error handling, type hinting, and output clarity - Replaced Union with Optional for clearer type hinting - Added input validation for empty lists and non-integer values - Improved error handling with informative exceptions - Enhanced result display to include matched values alongside indices - Applied PEP 8 style improvements for better readability --- two_num.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/two_num.py b/two_num.py index 5174457affb..45719e1ebe4 100644 --- a/two_num.py +++ b/two_num.py @@ -14,9 +14,9 @@ [0, 1] """ -from typing import List, Union +from typing import List, Optional -def two_sum(nums: List[int], target: int) -> Union[List[int], bool]: +def two_sum(nums: List[int], target: int) -> Optional[List[int]]: """ Finds indices of two numbers in 'nums' that add up to 'target'. @@ -25,33 +25,34 @@ def two_sum(nums: List[int], target: int) -> Union[List[int], bool]: target (int): Target sum. Returns: - List[int]: Indices of the two numbers that add up to the target. - False: If no such pair is found. + Optional[List[int]]: Indices of the two numbers that add up to the target, + or None if no such pair is found. """ + if len(nums) < 2: + raise ValueError("Input list must contain at least two numbers.") + + if not all(isinstance(num, int) for num in nums): + raise TypeError("All elements in the list must be integers.") + # Dictionary to track seen values and their indices seen_values = {} for index, value in enumerate(nums): complement = target - value - - # Check if the complement exists in the dictionary if complement in seen_values: return [seen_values[complement], index] - - # Add current value to dictionary for future reference seen_values[value] = index - # Return False if no pair is found (explicit is better than implicit) - return False + return None # Example usage if __name__ == "__main__": example_nums = [2, 7, 11, 15] example_target = 9 result = two_sum(example_nums, example_target) - - # Clean, professional result display + if result: - print(f"Indices that add up to {example_target}: {result}") + num1, num2 = example_nums[result[0]], example_nums[result[1]] + print(f"Indices that add up to {example_target}: {result} (Values: {num1} + {num2})") else: print(f"No combination found that adds up to {example_target}.") From 11cf9420ed3cfba12687ab1078a1259f0028f7ad Mon Sep 17 00:00:00 2001 From: Saavi Verma Date: Mon, 24 Mar 2025 23:00:52 +0530 Subject: [PATCH 291/442] Updated file in Python repository --- Colors/print_colors.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Colors/print_colors.py b/Colors/print_colors.py index edf78440a22..6aacaa9d4b4 100644 --- a/Colors/print_colors.py +++ b/Colors/print_colors.py @@ -1,6 +1,4 @@ import sys - - class colors: CYAN = "\033[36m" GREEN = "\033[32m" @@ -8,13 +6,8 @@ class colors: BLUE = "\033[34m" RED = "\033[31m" ENDC = "\033[0m" - - def printc(color, message): print(color + message + colors.ENDC) - - -# color which we print or import printc(colors.CYAN, sys.argv[1]) printc(colors.GREEN, sys.argv[1]) printc(colors.YELLOW, sys.argv[1]) From a4e5613ebf555b4dbafd3394a6bed27365fecce0 Mon Sep 17 00:00:00 2001 From: Saavi Verma Date: Mon, 24 Mar 2025 23:18:04 +0530 Subject: [PATCH 292/442] Modified example.txt in feature-branch --- example.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 example.txt diff --git a/example.txt b/example.txt new file mode 100644 index 00000000000..cb511a2b55e --- /dev/null +++ b/example.txt @@ -0,0 +1 @@ +Change from feature-branch From 81ca88560ff98e6a1b7b37ccb531e9b869521f69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 19:36:49 +0000 Subject: [PATCH 293/442] Bump yfinance from 0.2.54 to 0.2.55 Bumps [yfinance](https://github.com/ranaroussi/yfinance) from 0.2.54 to 0.2.55. - [Release notes](https://github.com/ranaroussi/yfinance/releases) - [Changelog](https://github.com/ranaroussi/yfinance/blob/main/CHANGELOG.rst) - [Commits](https://github.com/ranaroussi/yfinance/compare/0.2.54...0.2.55) --- updated-dependencies: - dependency-name: yfinance dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 32edcb888f8..3fbc91ca712 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -66,7 +66,7 @@ speechtotext==0.0.3 wikipedia==1.4.0 tqdm==4.67.1 Menu==3.2.2 -yfinance==0.2.54 +yfinance==0.2.55 tweepy==4.15.0 tkcalendar==1.6.1 pytube==15.0.0 From 194fae5cff3afd037020f7a7cc1438d660e22651 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 19:40:05 +0000 Subject: [PATCH 294/442] Bump pydantic from 2.10.3 to 2.10.6 Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.10.3 to 2.10.6. - [Release notes](https://github.com/pydantic/pydantic/releases) - [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md) - [Commits](https://github.com/pydantic/pydantic/compare/v2.10.3...v2.10.6) --- updated-dependencies: - dependency-name: pydantic dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 32edcb888f8..1a9f202fe46 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -51,7 +51,7 @@ pywifi==1.1.12 patterns==0.3 openai==1.68.0 background==0.2.1 -pydantic==2.10.3 +pydantic==2.10.6 openpyxl==3.1.2 pytesseract==0.3.13 requests-mock==1.12.1 From 65b6850e544a0658b4c0d0fa0b2613fa10a9feb0 Mon Sep 17 00:00:00 2001 From: Samridhi Gumber Date: Tue, 25 Mar 2025 17:03:23 +0530 Subject: [PATCH 295/442] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 03c280e1cba..873ea61f1b9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +#This is a new repo # My Python Eggs 🐍 😄
From e8da3e63ac7bb7e06ca42a650046fefde510c86c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Mar 2025 18:16:42 +0000 Subject: [PATCH 296/442] Bump ccxt from 4.4.62 to 4.4.70 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.4.62 to 4.4.70. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/v4.4.62...v4.4.70) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 7703c8e62cf..ad3cb5be32c 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.8.0 gTTS==2.5.4 -ccxt==4.4.62 +ccxt==4.4.70 fitz==0.0.1.dev2 fastapi==0.115.8 Django==5.1.7 From f52d0c7034ecce5394881b02b46639e929822613 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Mar 2025 18:16:46 +0000 Subject: [PATCH 297/442] Bump twilio from 9.4.6 to 9.5.1 Bumps [twilio](https://github.com/twilio/twilio-python) from 9.4.6 to 9.5.1. - [Release notes](https://github.com/twilio/twilio-python/releases) - [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md) - [Commits](https://github.com/twilio/twilio-python/compare/9.4.6...9.5.1) --- updated-dependencies: - dependency-name: twilio dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 7703c8e62cf..6f97f99abd9 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -28,7 +28,7 @@ requests==2.32.3 quo==2023.5.1 PyPDF2==3.0.1 pyserial==3.5 -twilio==9.4.6 +twilio==9.5.1 tabula==1.0.5 nltk==3.9.1 Pillow==11.1.0 From dfab4b2cd080208a2293a823c09688275f2df8c3 Mon Sep 17 00:00:00 2001 From: VanshAneja3 Date: Wed, 26 Mar 2025 17:32:25 +0530 Subject: [PATCH 298/442] Create contribution.txt --- contribution.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 contribution.txt diff --git a/contribution.txt b/contribution.txt new file mode 100644 index 00000000000..181a276c94d --- /dev/null +++ b/contribution.txt @@ -0,0 +1 @@ +Add a dark mode toggle for better UX From b4283c148a33cdd657f7f70bba7f64db2eda078a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Mar 2025 18:22:15 +0000 Subject: [PATCH 299/442] Bump protobuf from 5.29.3 to 6.30.1 Bumps [protobuf](https://github.com/protocolbuffers/protobuf) from 5.29.3 to 6.30.1. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v5.29.3...v6.30.1) --- updated-dependencies: - dependency-name: protobuf dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index d636d67031f..e5615d9db38 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -105,7 +105,7 @@ psutil==7.0.0 mediapipe==0.10.20 rich==13.9.4 httplib2==0.22.0 -protobuf==5.29.3 +protobuf==6.30.1 colorama==0.4.6 plyer==2.1.0 Flask-Ask==0.9.8 From 91139f763e630a4001b33b58cbbf5e3b9f59e98e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Mar 2025 18:22:20 +0000 Subject: [PATCH 300/442] Bump mediapipe from 0.10.20 to 0.10.21 Bumps [mediapipe](https://github.com/google/mediapipe) from 0.10.20 to 0.10.21. - [Release notes](https://github.com/google/mediapipe/releases) - [Commits](https://github.com/google/mediapipe/compare/v0.10.20...v0.10.21) --- updated-dependencies: - dependency-name: mediapipe dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Hand-Motion-Detection/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt index 3b276940237..e851a4195fe 100644 --- a/Hand-Motion-Detection/requirements.txt +++ b/Hand-Motion-Detection/requirements.txt @@ -1,3 +1,3 @@ numpy==2.2.3 opencv_python==4.11.0.86 -mediapipe==0.10.20 +mediapipe==0.10.21 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index d636d67031f..d9f2ea1f193 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -102,7 +102,7 @@ qrcode==8.0 googletrans==4.0.2 slab==1.7.0 psutil==7.0.0 -mediapipe==0.10.20 +mediapipe==0.10.21 rich==13.9.4 httplib2==0.22.0 protobuf==5.29.3 From b63efb659f84d722f386ac5942df5e6ad2a71e76 Mon Sep 17 00:00:00 2001 From: Shiksha Date: Thu, 27 Mar 2025 23:28:44 +0530 Subject: [PATCH 301/442] Update README.md --- Assembler/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Assembler/README.md b/Assembler/README.md index 25cbcafff5d..bb3f26d0f8f 100644 --- a/Assembler/README.md +++ b/Assembler/README.md @@ -1,3 +1,4 @@ +# hy your name # Python-Assembler # WE need A FREE T-SHIRT This program is a simple assembler-like (intel-syntax) interpreter language. The program is written in python 3. From b52144329f2feb92c9721fcdc2c5a4212a5d495c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Mar 2025 18:42:16 +0000 Subject: [PATCH 302/442] Bump openai from 1.68.0 to 1.69.0 Bumps [openai](https://github.com/openai/openai-python) from 1.68.0 to 1.69.0. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.68.0...v1.69.0) --- updated-dependencies: - dependency-name: openai dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 2709577efe5..754de616060 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.68.0 +openai==1.69.0 background==0.2.1 pydantic==2.10.6 openpyxl==3.1.2 From 9a3be28e32af1b1ac2e9b6f0a2a735eb6afe56d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Mar 2025 18:42:25 +0000 Subject: [PATCH 303/442] Bump pynput from 1.8.0 to 1.8.1 Bumps [pynput](https://github.com/moses-palmer/pynput) from 1.8.0 to 1.8.1. - [Changelog](https://github.com/moses-palmer/pynput/blob/master/CHANGES.rst) - [Commits](https://github.com/moses-palmer/pynput/compare/v1.8.0...v1.8.1) --- updated-dependencies: - dependency-name: pynput dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 2709577efe5..ad48956d8a8 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -79,7 +79,7 @@ pywhatkit==5.4 mutagen==1.47.0 Unidecode==1.3.8 Ball==0.2.9 -pynput==1.8.0 +pynput==1.8.1 gTTS==2.5.4 ccxt==4.4.70 fitz==0.0.1.dev2 From 9a593ca57e2b8dea88edf509cd5b7f2d10569c0c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Mar 2025 18:52:34 +0000 Subject: [PATCH 304/442] Bump thirdai from 0.9.25 to 0.9.28 Bumps thirdai from 0.9.25 to 0.9.28. --- updated-dependencies: - dependency-name: thirdai dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 2709577efe5..cd1acc796fd 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -57,7 +57,7 @@ pytesseract==0.3.13 requests-mock==1.12.1 pyglet==2.1.3 urllib3==2.3.0 -thirdai==0.9.25 +thirdai==0.9.28 google-api-python-client==2.162.0 sound==0.1.0 xlwt==1.3.0 From 4c8ef742ef90ab6f5fd9a6e5bde573be1fd8cd6c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 18:55:54 +0000 Subject: [PATCH 305/442] Bump openai from 1.69.0 to 1.70.0 Bumps [openai](https://github.com/openai/openai-python) from 1.69.0 to 1.70.0. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.69.0...v1.70.0) --- updated-dependencies: - dependency-name: openai dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 50619cc2a29..1ff130433b9 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.69.0 +openai==1.70.0 background==0.2.1 pydantic==2.10.6 openpyxl==3.1.2 From b7cb1a3d008ed1d289aeea4625a89e312c8c0184 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 18:56:06 +0000 Subject: [PATCH 306/442] Bump fastapi from 0.115.8 to 0.115.12 Bumps [fastapi](https://github.com/fastapi/fastapi) from 0.115.8 to 0.115.12. - [Release notes](https://github.com/fastapi/fastapi/releases) - [Commits](https://github.com/fastapi/fastapi/compare/0.115.8...0.115.12) --- updated-dependencies: - dependency-name: fastapi dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 50619cc2a29..aa1e342388a 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -83,7 +83,7 @@ pynput==1.8.1 gTTS==2.5.4 ccxt==4.4.70 fitz==0.0.1.dev2 -fastapi==0.115.8 +fastapi==0.115.12 Django==5.1.7 docx==0.2.4 matplotlib==3.10.0 From 50209c169b98b1e8e51452aecc6e53d670026c10 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 18:56:09 +0000 Subject: [PATCH 307/442] Bump rich from 13.9.4 to 14.0.0 Bumps [rich](https://github.com/Textualize/rich) from 13.9.4 to 14.0.0. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.9.4...v14.0.0) --- updated-dependencies: - dependency-name: rich dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 50619cc2a29..66e5f7cb2ac 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -103,7 +103,7 @@ googletrans==4.0.2 slab==1.7.0 psutil==7.0.0 mediapipe==0.10.21 -rich==13.9.4 +rich==14.0.0 httplib2==0.22.0 protobuf==6.30.1 colorama==0.4.6 From 05854c15af9ba3d98d68eed3b8d7aad9dfa7f5d4 Mon Sep 17 00:00:00 2001 From: AdityaSharma283 Date: Tue, 1 Apr 2025 20:50:20 +0530 Subject: [PATCH 308/442] Fixed bank management system issues --- bank_managment_system/backend.py | 272 +++++++++++-------------------- 1 file changed, 97 insertions(+), 175 deletions(-) diff --git a/bank_managment_system/backend.py b/bank_managment_system/backend.py index e54027cf0a6..62f9c2b36b8 100644 --- a/bank_managment_system/backend.py +++ b/bank_managment_system/backend.py @@ -1,248 +1,170 @@ import sqlite3 - -# making connection with database +# Making connection with database def connect_database(): global conn global cur conn = sqlite3.connect("bankmanaging.db") - cur = conn.cursor() cur.execute( - "create table if not exists bank (acc_no int, name text, age int, address text, balance int, account_type text, mobile_number int)" + """ + CREATE TABLE IF NOT EXISTS bank ( + acc_no INTEGER PRIMARY KEY, + name TEXT, + age INTEGER, + address TEXT, + balance INTEGER, + account_type TEXT, + mobile_number TEXT + ) + """ ) cur.execute( - "create table if not exists staff (name text, pass text,salary int, position text)" + """ + CREATE TABLE IF NOT EXISTS staff ( + name TEXT, + pass TEXT, + salary INTEGER, + position TEXT + ) + """ ) - cur.execute("create table if not exists admin (name text, pass text)") - cur.execute("insert into admin values('arpit','123')") + cur.execute("CREATE TABLE IF NOT EXISTS admin (name TEXT, pass TEXT)") + + # Only insert admin if not exists + cur.execute("SELECT COUNT(*) FROM admin") + if cur.fetchone()[0] == 0: + cur.execute("INSERT INTO admin VALUES (?, ?)", ('arpit', '123')) + conn.commit() - cur.execute("select acc_no from bank") - acc = cur.fetchall() - global acc_no - if len(acc) == 0: - acc_no = 1 - else: - acc_no = int(acc[-1][0]) + 1 + # Fetch last account number to avoid duplicate or incorrect numbering + cur.execute("SELECT acc_no FROM bank ORDER BY acc_no DESC LIMIT 1") + acc = cur.fetchone() + global acc_no + acc_no = 1 if acc is None else acc[0] + 1 -# check admin dtails in database +# Check admin details in database def check_admin(name, password): - cur.execute("select * from admin") - data = cur.fetchall() - - if data[0][0] == name and data[0][1] == password: - return True - return + cur.execute("SELECT * FROM admin WHERE name = ? AND pass = ?", (name, password)) + return cur.fetchone() is not None - -# create employee in database -def create_employee(name, password, salary, positon): - print(password) - cur.execute("insert into staff values(?,?,?,?)", (name, password, salary, positon)) +# Create employee in database +def create_employee(name, password, salary, position): + cur.execute("INSERT INTO staff VALUES (?, ?, ?, ?)", (name, password, salary, position)) conn.commit() - -# check employee details in dabase for employee login +# Check employee login details def check_employee(name, password): - print(password) - print(name) - cur.execute("select name,pass from staff") - data = cur.fetchall() - print(data) - if len(data) == 0: - return False - for i in range(len(data)): - if data[i][0] == name and data[i][1] == password: - return True - - return False - + cur.execute("SELECT 1 FROM staff WHERE name = ? AND pass = ?", (name, password)) + return cur.fetchone() is not None -# create customer details in database +# Create customer in database def create_customer(name, age, address, balance, acc_type, mobile_number): global acc_no cur.execute( - "insert into bank values(?,?,?,?,?,?,?)", - (acc_no, name, age, address, balance, acc_type, mobile_number), + "INSERT INTO bank VALUES (?, ?, ?, ?, ?, ?, ?)", + (acc_no, name, age, address, balance, acc_type, mobile_number) ) conn.commit() - acc_no = acc_no + 1 + acc_no += 1 return acc_no - 1 - -# check account in database +# Check if account number exists def check_acc_no(acc_no): - cur.execute("select acc_no from bank") - list_acc_no = cur.fetchall() - - for i in range(len(list_acc_no)): - if list_acc_no[i][0] == int(acc_no): - return True - return False - + cur.execute("SELECT 1 FROM bank WHERE acc_no = ?", (acc_no,)) + return cur.fetchone() is not None -# get all details of a particular customer from database +# Get customer details def get_details(acc_no): - cur.execute("select * from bank where acc_no=?", (acc_no)) - global detail - detail = cur.fetchall() - print(detail) - if len(detail) == 0: - return False - else: - return ( - detail[0][0], - detail[0][1], - detail[0][2], - detail[0][3], - detail[0][4], - detail[0][5], - detail[0][6], - ) - + cur.execute("SELECT * FROM bank WHERE acc_no = ?", (acc_no,)) + detail = cur.fetchone() + return detail if detail else False -# add new balance of customer in bank database +# Update customer balance def update_balance(new_money, acc_no): - cur.execute("select balance from bank where acc_no=?", (acc_no,)) - bal = cur.fetchall() - bal = bal[0][0] - new_bal = bal + int(new_money) - - cur.execute("update bank set balance=? where acc_no=?", (new_bal, acc_no)) + cur.execute("UPDATE bank SET balance = balance + ? WHERE acc_no = ?", (new_money, acc_no)) conn.commit() - -# deduct balance from customer bank database +# Deduct balance def deduct_balance(new_money, acc_no): - cur.execute("select balance from bank where acc_no=?", (acc_no,)) - bal = cur.fetchall() - bal = bal[0][0] - if bal < int(new_money): - return False - else: - new_bal = bal - int(new_money) - - cur.execute("update bank set balance=? where acc_no=?", (new_bal, acc_no)) + cur.execute("SELECT balance FROM bank WHERE acc_no = ?", (acc_no,)) + bal = cur.fetchone() + if bal and bal[0] >= new_money: + cur.execute("UPDATE bank SET balance = balance - ? WHERE acc_no = ?", (new_money, acc_no)) conn.commit() return True + return False - -# gave balance of a particular account number from database +# Get account balance def check_balance(acc_no): - cur.execute("select balance from bank where acc_no=?", (acc_no)) - bal = cur.fetchall() - return bal[0][0] + cur.execute("SELECT balance FROM bank WHERE acc_no = ?", (acc_no,)) + bal = cur.fetchone() + return bal[0] if bal else 0 - -# update_name_in_bank_table +# Update customer details def update_name_in_bank_table(new_name, acc_no): - print(new_name) - conn.execute("update bank set name='{}' where acc_no={}".format(new_name, acc_no)) + cur.execute("UPDATE bank SET name = ? WHERE acc_no = ?", (new_name, acc_no)) conn.commit() - -# update_age_in_bank_table -def update_age_in_bank_table(new_name, acc_no): - print(new_name) - conn.execute("update bank set age={} where acc_no={}".format(new_name, acc_no)) +def update_age_in_bank_table(new_age, acc_no): + cur.execute("UPDATE bank SET age = ? WHERE acc_no = ?", (new_age, acc_no)) conn.commit() - -# update_address_in_bank_table -def update_address_in_bank_table(new_name, acc_no): - print(new_name) - conn.execute( - "update bank set address='{}' where acc_no={}".format(new_name, acc_no) - ) +def update_address_in_bank_table(new_address, acc_no): + cur.execute("UPDATE bank SET address = ? WHERE acc_no = ?", (new_address, acc_no)) conn.commit() - -# list of all customers in bank +# List all customers def list_all_customers(): - cur.execute("select * from bank") - deatil = cur.fetchall() - - return deatil + cur.execute("SELECT * FROM bank") + return cur.fetchall() - -# delete account from database +# Delete account def delete_acc(acc_no): - cur.execute("delete from bank where acc_no=?", (acc_no)) + cur.execute("DELETE FROM bank WHERE acc_no = ?", (acc_no,)) conn.commit() - -# show employees detail from staff table +# Show employees def show_employees(): - cur.execute("select name, salary, position,pass from staff") - detail = cur.fetchall() - return detail - + cur.execute("SELECT name, salary, position FROM staff") + return cur.fetchall() -# return all money in bank +# Get total money in bank def all_money(): - cur.execute("select balance from bank") - bal = cur.fetchall() - print(bal) - if len(bal) == 0: - return False - else: - total = 0 - for i in bal: - total = total + i[0] - return total - - -# return a list of all employees name -def show_employees_for_update(): - cur.execute("select * from staff") - detail = cur.fetchall() - return detail + cur.execute("SELECT SUM(balance) FROM bank") + total = cur.fetchone()[0] + return total if total else 0 +# Get employee details +def show_employees_for_update(): + cur.execute("SELECT * FROM staff") + return cur.fetchall() -# update employee name from data base +# Update employee details def update_employee_name(new_name, old_name): - print(new_name, old_name) - cur.execute("update staff set name='{}' where name='{}'".format(new_name, old_name)) + cur.execute("UPDATE staff SET name = ? WHERE name = ?", (new_name, old_name)) conn.commit() - def update_employee_password(new_pass, old_name): - print(new_pass, old_name) - cur.execute("update staff set pass='{}' where name='{}'".format(new_pass, old_name)) + cur.execute("UPDATE staff SET pass = ? WHERE name = ?", (new_pass, old_name)) conn.commit() - def update_employee_salary(new_salary, old_name): - print(new_salary, old_name) - cur.execute( - "update staff set salary={} where name='{}'".format(new_salary, old_name) - ) + cur.execute("UPDATE staff SET salary = ? WHERE name = ?", (new_salary, old_name)) conn.commit() - def update_employee_position(new_pos, old_name): - print(new_pos, old_name) - cur.execute( - "update staff set position='{}' where name='{}'".format(new_pos, old_name) - ) + cur.execute("UPDATE staff SET position = ? WHERE name = ?", (new_pos, old_name)) conn.commit() - -# get name and balance from bank of a particular account number +# Get customer name and balance def get_detail(acc_no): - cur.execute("select name, balance from bank where acc_no=?", (acc_no)) - details = cur.fetchall() - return details - + cur.execute("SELECT name, balance FROM bank WHERE acc_no = ?", (acc_no,)) + return cur.fetchone() +# Check if employee exists def check_name_in_staff(name): - cur = conn.cursor() - cur.execute("select name from staff") - details = cur.fetchall() - - for i in details: - if i[0] == name: - return True - return False + cur.execute("SELECT 1 FROM staff WHERE name = ?", (name,)) + return cur.fetchone() is not Non \ No newline at end of file From d46b6cae6f27d62a2a19d92a828e24f60a58f47b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 18:24:39 +0000 Subject: [PATCH 309/442] Bump keras from 3.9.0 to 3.9.1 Bumps [keras](https://github.com/keras-team/keras) from 3.9.0 to 3.9.1. - [Release notes](https://github.com/keras-team/keras/releases) - [Commits](https://github.com/keras-team/keras/compare/v3.9.0...v3.9.1) --- updated-dependencies: - dependency-name: keras dependency-version: 3.9.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index c1d018b3624..09a0ad530f4 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -41,7 +41,7 @@ tornado==6.4.2 obs==0.0.0 todo==0.1 oauth2client==4.1.3 -keras==3.9.0 +keras==3.9.1 pymongo==4.11.3 playsound==1.3.0 pyttsx3==2.98 From f89d111bed115634f2ab7b7d908e896853d00553 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 18:25:02 +0000 Subject: [PATCH 310/442] Bump aiohttp from 3.11.14 to 3.11.15 --- updated-dependencies: - dependency-name: aiohttp dependency-version: 3.11.15 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- async_downloader/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/async_downloader/requirements.txt b/async_downloader/requirements.txt index ffcb1b6959d..196f2b5419b 100644 --- a/async_downloader/requirements.txt +++ b/async_downloader/requirements.txt @@ -1 +1 @@ -aiohttp==3.11.14 +aiohttp==3.11.15 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index c1d018b3624..83a2e8517f2 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -1,5 +1,5 @@ pafy==0.5.5 -aiohttp==3.11.14 +aiohttp==3.11.15 fuzzywuzzy==0.18.0 hupper==1.12.1 seaborn==0.13.2 From 4a9d4e3d5aaa552567d2a04a06ccddf50580c612 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 18:25:14 +0000 Subject: [PATCH 311/442] Bump protobuf from 6.30.1 to 6.30.2 Bumps [protobuf](https://github.com/protocolbuffers/protobuf) from 6.30.1 to 6.30.2. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v6.30.1...v6.30.2) --- updated-dependencies: - dependency-name: protobuf dependency-version: 6.30.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index c1d018b3624..5d9de105dc8 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -105,7 +105,7 @@ psutil==7.0.0 mediapipe==0.10.21 rich==14.0.0 httplib2==0.22.0 -protobuf==6.30.1 +protobuf==6.30.2 colorama==0.4.6 plyer==2.1.0 Flask-Ask==0.9.8 From 35a0ca75628e913389f0e9ea4cbff182ebbdfb95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 18:05:27 +0000 Subject: [PATCH 312/442] Bump selenium from 4.29.0 to 4.30.0 Bumps [selenium](https://github.com/SeleniumHQ/Selenium) from 4.29.0 to 4.30.0. - [Release notes](https://github.com/SeleniumHQ/Selenium/releases) - [Commits](https://github.com/SeleniumHQ/Selenium/compare/selenium-4.29.0...selenium-4.30.0) --- updated-dependencies: - dependency-name: selenium dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 0a11085bfd0..65d18e88b7e 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -21,7 +21,7 @@ backend==0.2.4.1 win10toast==0.9 Counter==1.0.0 Flask==3.1.0 -selenium==4.29.0 +selenium==4.30.0 firebase-admin==6.7.0 ujson==5.10.0 requests==2.32.3 From e929ac186d6eade9c7e4d88a9295e04f6f144f16 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 18:05:32 +0000 Subject: [PATCH 313/442] Bump qrcode from 8.0 to 8.1 Bumps [qrcode](https://github.com/lincolnloop/python-qrcode) from 8.0 to 8.1. - [Changelog](https://github.com/lincolnloop/python-qrcode/blob/main/CHANGES.rst) - [Commits](https://github.com/lincolnloop/python-qrcode/commits) --- updated-dependencies: - dependency-name: qrcode dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 0a11085bfd0..ccf96779ef2 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -98,7 +98,7 @@ opencv-python==4.11.0.86 tensorflow==2.18.1 pandas==2.2.3 pytest==8.3.5 -qrcode==8.0 +qrcode==8.1 googletrans==4.0.2 slab==1.7.0 psutil==7.0.0 From f2be1f6442fbc85046ffe38044333c68329e2979 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 18:48:56 +0000 Subject: [PATCH 314/442] Bump pydantic from 2.10.6 to 2.11.2 Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.10.6 to 2.11.2. - [Release notes](https://github.com/pydantic/pydantic/releases) - [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md) - [Commits](https://github.com/pydantic/pydantic/compare/v2.10.6...v2.11.2) --- updated-dependencies: - dependency-name: pydantic dependency-version: 2.11.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 0a11085bfd0..e544e923b86 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -51,7 +51,7 @@ pywifi==1.1.12 patterns==0.3 openai==1.70.0 background==0.2.1 -pydantic==2.10.6 +pydantic==2.11.2 openpyxl==3.1.2 pytesseract==0.3.13 requests-mock==1.12.1 From 34f67a95597ca1a2343f478bf47fa459ffce0c54 Mon Sep 17 00:00:00 2001 From: Pratyanj <109451378+pratyanj@users.noreply.github.com> Date: Fri, 4 Apr 2025 17:02:07 +0530 Subject: [PATCH 315/442] Change GUI TK to customtkinter I have change the normal tkinter gui with customtkinter that similar to tkinter but morden looking. --- AI Game/Tic-Tac-Toe-AI/tictactoe.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/AI Game/Tic-Tac-Toe-AI/tictactoe.py b/AI Game/Tic-Tac-Toe-AI/tictactoe.py index 0488e5acfdf..0cd5bd0dc36 100644 --- a/AI Game/Tic-Tac-Toe-AI/tictactoe.py +++ b/AI Game/Tic-Tac-Toe-AI/tictactoe.py @@ -1,7 +1,6 @@ -import tkinter as tk #provides a library of basic elements of GUI widgets from tkinter import messagebox #provides a different set of dialogues that are used to display message boxes -import random - +import customtkinter as ctk +import customtkinter as messagebox def check_winner(board, player): # Check rows, columns, and diagonals for a win for i in range(3): @@ -63,7 +62,8 @@ def best_move(board): def make_move(row, col): if board[row][col] == ' ': board[row][col] = 'X' - buttons[row][col].config(text='X') + # in tk we use the config but in customtkinter we use configure for + buttons[row][col].configure(text='X') if check_winner(board, 'X'): messagebox.showinfo("Tic-Tac-Toe", "You win!") root.quit() @@ -79,15 +79,15 @@ def make_move(row, col): def ai_move(): row, col = best_move(board) board[row][col] = 'O' - buttons[row][col].config(text='O') + buttons[row][col].configure(text='O') if check_winner(board, 'O'): messagebox.showinfo("Tic-Tac-Toe", "AI wins!") root.quit() elif is_board_full(board): messagebox.showinfo("Tic-Tac-Toe", "It's a draw!") root.quit() - -root = tk.Tk() +# change old UI code to customtkinter UI +root = ctk.CTk() root.title("Tic-Tac-Toe") board = [[' ' for _ in range(3)] for _ in range(3)] @@ -96,8 +96,8 @@ def ai_move(): for i in range(3): row_buttons = [] for j in range(3): - button = tk.Button(root, text=' ', font=('normal', 30), width=5, height=2, command=lambda row=i, col=j: make_move(row, col)) - button.grid(row=i, column=j) + button = ctk.CTkButton(root, text=' ', font=('normal', 30), width=100, height=100, command=lambda row=i, col=j: make_move(row, col)) + button.grid(row=i, column=j, padx=2, pady=2) row_buttons.append(button) buttons.append(row_buttons) From 7ead145b671a1aa0dff8611aa85d3d4e9a5d8ba3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Apr 2025 19:11:16 +0000 Subject: [PATCH 316/442] Bump google-api-python-client from 2.162.0 to 2.166.0 Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.162.0 to 2.166.0. - [Release notes](https://github.com/googleapis/google-api-python-client/releases) - [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.162.0...v2.166.0) --- updated-dependencies: - dependency-name: google-api-python-client dependency-version: 2.166.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 7df9be3aa7b..0a594ced6a5 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -58,7 +58,7 @@ requests-mock==1.12.1 pyglet==2.1.3 urllib3==2.3.0 thirdai==0.9.28 -google-api-python-client==2.162.0 +google-api-python-client==2.166.0 sound==0.1.0 xlwt==1.3.0 pygame==2.6.1 From 06048bcbb744f76ac590d37b8dbe593fe4227fda Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Apr 2025 19:11:31 +0000 Subject: [PATCH 317/442] Bump twilio from 9.5.1 to 9.5.2 Bumps [twilio](https://github.com/twilio/twilio-python) from 9.5.1 to 9.5.2. - [Release notes](https://github.com/twilio/twilio-python/releases) - [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md) - [Commits](https://github.com/twilio/twilio-python/compare/9.5.1...9.5.2) --- updated-dependencies: - dependency-name: twilio dependency-version: 9.5.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 7df9be3aa7b..4860698a3bc 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -28,7 +28,7 @@ requests==2.32.3 quo==2023.5.1 PyPDF2==3.0.1 pyserial==3.5 -twilio==9.5.1 +twilio==9.5.2 tabula==1.0.5 nltk==3.9.1 Pillow==11.1.0 From 09cf635a334b811e2501892826ae8b76e60ce4c8 Mon Sep 17 00:00:00 2001 From: Abhilash Date: Mon, 14 Apr 2025 19:57:44 +0530 Subject: [PATCH 318/442] added degree to direction logic --- compass_code.py | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 compass_code.py diff --git a/compass_code.py b/compass_code.py new file mode 100644 index 00000000000..ec0ac377ba6 --- /dev/null +++ b/compass_code.py @@ -0,0 +1,8 @@ +def degree_to_direction(deg): + directions = ["N", "NE", "E", "SE", "S", "SW", "W", "NW"] + + deg = deg% 360 + deg = int(deg//45) + print(directions[deg]) + +degree_to_direction(45) \ No newline at end of file From 659e1947e30f109a7d21db0e24d4a9b6afdfc3b2 Mon Sep 17 00:00:00 2001 From: Abhilash Date: Sun, 20 Apr 2025 20:27:20 +0530 Subject: [PATCH 319/442] Added simple calculator --- simple_calcu.py | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 simple_calcu.py diff --git a/simple_calcu.py b/simple_calcu.py new file mode 100644 index 00000000000..f31ca843ac8 --- /dev/null +++ b/simple_calcu.py @@ -0,0 +1,5 @@ +while True: + print(int(input("enter first number..")) + int(input("enter second number.."))) + q= input("press q to quit or press anu key to continue").lower() + if q==" q": + break \ No newline at end of file From 8f46e55b58ee87481c696d2bc3f13e91ebf9d596 Mon Sep 17 00:00:00 2001 From: Abhilash Date: Mon, 21 Apr 2025 19:36:43 +0530 Subject: [PATCH 320/442] Added offline text to speech --- SpeechToText.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 SpeechToText.py diff --git a/SpeechToText.py b/SpeechToText.py new file mode 100644 index 00000000000..12ee402667a --- /dev/null +++ b/SpeechToText.py @@ -0,0 +1,14 @@ +import pyttsx3 + +engine = pyttsx3.init() + +voices = engine.getProperty("voices") +for voice in voices: + print(voice.id) + print(voice.name) + +id ="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_EN-US_DAVID_11.0" +engine.setProperty("voices",id ) +engine.setProperty("rate",165) +engine.say("jarivs") # Replace string with our own text +engine.runAndWait() \ No newline at end of file From b674155097f57e21aa39ef70cd6b348483c9d650 Mon Sep 17 00:00:00 2001 From: codewithdhruba01 Date: Mon, 21 Apr 2025 21:35:19 +0530 Subject: [PATCH 321/442] Implement basic expense tracking --- Personal-Expense-Tracker/README.md | 48 +++++++++ Personal-Expense-Tracker/expense_tracker.py | 112 ++++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 Personal-Expense-Tracker/README.md create mode 100644 Personal-Expense-Tracker/expense_tracker.py diff --git a/Personal-Expense-Tracker/README.md b/Personal-Expense-Tracker/README.md new file mode 100644 index 00000000000..ee20ca81b3a --- /dev/null +++ b/Personal-Expense-Tracker/README.md @@ -0,0 +1,48 @@ +# Personal Expense Tracker CLI + +This is a basic command-line interface (CLI) application built with Python to help you track your daily expenses. It allows you to easily add your expenditures, categorize them, and view your spending patterns over different time periods. + +## Features + +* **Add New Expense:** Record new expenses by providing the amount, category (e.g., food, travel, shopping, bills), date, and an optional note. +* **View Expenses:** Display your expenses for a specific day, week, month, or all recorded expenses. +* **Filter by Category:** View expenses belonging to a particular category. +* **Data Persistence:** Your expense data is saved to a plain text file (`expenses.txt`) so it's retained between sessions. +* **Simple Command-Line Interface:** Easy-to-use text-based menu for interacting with the application. + +## Technologies Used + +* **Python:** The core programming language used for the application logic. +* **File Handling:** Used to store and retrieve expense data from a text file. +* **`datetime` module:** For handling and managing date information for expenses. + +## How to Run + +1. Make sure you have Python installed on your system. +2. Save the `expense_tracker.py` file to your local machine. +3. Open your terminal or command prompt. +4. Navigate to the directory where you saved the file using the `cd` command. +5. Run the application by executing the command: `python expense_tracker.py` + +## Basic Usage + +1. Run the script. You will see a menu with different options. +2. To add a new expense, choose option `1` and follow the prompts to enter the required information. +3. To view expenses, choose option `2` and select the desired time period (day, week, month, or all). +4. To filter expenses by category, choose option `3` and enter the category you want to view. +5. To save any new expenses (though the application automatically saves on exit as well), choose option `4`. +6. To exit the application, choose option `5`. + +## Potential Future Enhancements (Ideas for Expansion) + +* Implement a monthly budget feature with alerts. +* Add a login system for multiple users. +* Generate visual reports like pie charts for category-wise spending (using libraries like `matplotlib`). +* Incorporate voice input for adding expenses (using `speech_recognition`). +* Migrate data storage to a more structured database like SQLite. + +* Add functionality to export expense data to CSV files. + +--- + +> This simple Personal Expense Tracker provides a basic yet functional way to manage your finances from the command line. \ No newline at end of file diff --git a/Personal-Expense-Tracker/expense_tracker.py b/Personal-Expense-Tracker/expense_tracker.py new file mode 100644 index 00000000000..12d6b4a33c2 --- /dev/null +++ b/Personal-Expense-Tracker/expense_tracker.py @@ -0,0 +1,112 @@ +import datetime + +def add_expense(expenses): + amount = float(input("Enter the expense amount: ")) + category = input("Category (food, travel, shopping, bills, etc.): ") + date_str = input("Date (YYYY-MM-DD): ") + try: + date = datetime.datetime.strptime(date_str, "%Y-%m-%d").date() + except ValueError: + print("Incorrect date format. Please use YYYY-MM-DD format.") + return + note = input("(Optional) Note: ") + expenses.append({"amount": amount, "category": category, "date": date, "note": note}) + print("Expense added!") + +def view_expenses(expenses, period="all", category_filter=None): + if not expenses: + print("No expenses recorded yet.") + return + + filtered_expenses = expenses + if category_filter: + filtered_expenses = [e for e in filtered_expenses if e["category"] == category_filter] + + if period == "day": + date_str = input("Enter the date to view expenses for (YYYY-MM-DD): ") + try: + date = datetime.datetime.strptime(date_str, "%Y-%m-%d").date() + filtered_expenses = [e for e in filtered_expenses if e["date"] == date] + except ValueError: + print("Incorrect date format.") + return + elif period == "week": + date_str = input("Enter the start date of the week (YYYY-MM-DD - first day of the week): ") + try: + start_date = datetime.datetime.strptime(date_str, "%Y-%m-%d").date() + end_date = start_date + datetime.timedelta(days=6) + filtered_expenses = [e for e in filtered_expenses if start_date <= e["date"] <= end_date] + except ValueError: + print("Incorrect date format.") + return + elif period == "month": + year = input("Enter the year for the month (YYYY): ") + month = input("Enter the month (MM): ") + try: + year = int(year) + month = int(month) + filtered_expenses = [e for e in filtered_expenses if e["date"].year == year and e["date"].month == month] + except ValueError: + print("Incorrect year or month format.") + return + + if not filtered_expenses: + print("No expenses found for this period or category.") + return + + print("\n--- Expenses ---") + total_spent = 0 + for expense in filtered_expenses: + print(f"Amount: {expense['amount']}, Category: {expense['category']}, Date: {expense['date']}, Note: {expense['note']}") + total_spent += expense['amount'] + print(f"\nTotal spent: {total_spent}") + +def save_expenses(expenses, filename="expenses.txt"): + with open(filename, "w") as f: + for expense in expenses: + f.write(f"{expense['amount']},{expense['category']},{expense['date']},{expense['note']}\n") + print("Expenses saved!") + +def load_expenses(filename="expenses.txt"): + expenses = [] + try: + with open(filename, "r") as f: + for line in f: + amount, category, date_str, note = line.strip().split(',') + expenses.append({"amount": float(amount), "category": category, "date": datetime.datetime.strptime(date_str, "%Y-%m-%d").date(), "note": note}) + except FileNotFoundError: + pass + return expenses + +def main(): + expenses = load_expenses() + + while True: + print("\n--- Personal Expense Tracker ---") + print("1. Add new expense") + print("2. View expenses") + print("3. Filter by category") + print("4. Save expenses") + print("5. Exit") + + choice = input("Choose your option: ") + + if choice == '1': + add_expense(expenses) + elif choice == '2': + period = input("View expenses by (day/week/month/all): ").lower() + view_expenses(expenses, period) + elif choice == '3': + category_filter = input("Enter the category to filter by: ") + view_expenses(expenses, category_filter=category_filter) + elif choice == '4': + save_expenses(expenses) + elif choice == '5': + save_expenses(expenses) + print("Thank you!") + break + else: + print("Invalid option. Please try again.") + +if __name__ == "__main__": + main() \ No newline at end of file From 9394a6d746e2243a7f776f8ea504773216be2ae2 Mon Sep 17 00:00:00 2001 From: codewithdhruba01 Date: Mon, 21 Apr 2025 22:00:28 +0530 Subject: [PATCH 322/442] add Author in readme.md file --- Personal-Expense-Tracker/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Personal-Expense-Tracker/README.md b/Personal-Expense-Tracker/README.md index ee20ca81b3a..8c54ea4d695 100644 --- a/Personal-Expense-Tracker/README.md +++ b/Personal-Expense-Tracker/README.md @@ -45,4 +45,6 @@ This is a basic command-line interface (CLI) application built with Python to he --- -> This simple Personal Expense Tracker provides a basic yet functional way to manage your finances from the command line. \ No newline at end of file +> This simple Personal Expense Tracker provides a basic yet functional way to manage your finances from the command line. + +#### Author: Dhrubaraj Pati \ No newline at end of file From 693e08f45a7dee8534787c473024e733b669b0e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Apr 2025 18:50:35 +0000 Subject: [PATCH 323/442] Bump ccxt from 4.4.70 to 4.4.77 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.4.70 to 4.4.77. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/v4.4.70...v4.4.77) --- updated-dependencies: - dependency-name: ccxt dependency-version: 4.4.77 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 3321caaccb7..4a71ef37a8c 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.8.1 gTTS==2.5.4 -ccxt==4.4.70 +ccxt==4.4.77 fitz==0.0.1.dev2 fastapi==0.115.12 Django==5.1.7 From aedafc2317b180512ccf40ced40c77656f81f697 Mon Sep 17 00:00:00 2001 From: Abhilash Date: Wed, 23 Apr 2025 20:21:16 +0530 Subject: [PATCH 324/442] billing.py --- billing.py | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 billing.py diff --git a/billing.py b/billing.py new file mode 100644 index 00000000000..c3fff306097 --- /dev/null +++ b/billing.py @@ -0,0 +1,3 @@ +prices = [12.99, 5.49, 8.75] +total = sum(prices) +print(total) \ No newline at end of file From 1267a66784dd71f2c529d2d7a3e049a1c64bbbd1 Mon Sep 17 00:00:00 2001 From: Inbaselvan-ayyanar <141208152+Inbaselvan-ayyanar@users.noreply.github.com> Date: Fri, 25 Apr 2025 18:08:21 +0530 Subject: [PATCH 325/442] Update Crack_password.py --- Crack_password.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Crack_password.py b/Crack_password.py index b32af07afd6..6941b6236e5 100644 --- a/Crack_password.py +++ b/Crack_password.py @@ -1,11 +1,11 @@ from random import * user_pass = input("Enter your password: ") -password = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j','k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't','u','v','w', 'x', 'y', 'z',] +password = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j','k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't','u','v','w', 'x', 'y', 'z',"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"] guess = "" while (guess != user_pass): guess = "" for letter in range(len(user_pass)): - guess_letter = password[randint(0, 25)] + guess_letter = password[randint(0, 51)] guess = str(guess_letter) + str(guess) print(guess) print("Your password is",guess) From e3a1344458d5cfce692f76c0f9905db442c84171 Mon Sep 17 00:00:00 2001 From: Inbaselvan-ayyanar <141208152+Inbaselvan-ayyanar@users.noreply.github.com> Date: Fri, 25 Apr 2025 21:36:49 +0530 Subject: [PATCH 326/442] Update qrcode.py --- qrcode.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/qrcode.py b/qrcode.py index 34bf365bfc7..0b9a8d6179c 100644 --- a/qrcode.py +++ b/qrcode.py @@ -1,7 +1,15 @@ -# importing Required Modules + import qrcode +import cv2 + +qr= qrcode.QRCode(version=1, box_size=10, border=5) -# QR Code Generator -query = input("Enter Content: ") # Enter Content -code = qrcode.make(query) # Making the QR code -code.save("qrcode.png") # Saving the QR code file +data = input() +qr.add_data(data) +qr.make(fit=True) +img = qr.make_image(fill_color="blue", back_color="white") +path=data+".png" +img.save(path) +cv2.imshow("QRCode",img) +cv2.waitKey(0) +cv2.destroyAllWindows() From e3129e83e671cbab4b420051dccb1a352ba27b90 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Apr 2025 18:45:59 +0000 Subject: [PATCH 327/442] Bump beautifulsoup4 from 4.13.3 to 4.13.4 Bumps [beautifulsoup4](https://www.crummy.com/software/BeautifulSoup/bs4/) from 4.13.3 to 4.13.4. --- updated-dependencies: - dependency-name: beautifulsoup4 dependency-version: 4.13.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4a71ef37a8c..07f0f486822 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -10,7 +10,7 @@ Tubes==0.2.1 modules==1.0.0 pdf2docx==0.5.8 pong==1.5 -beautifulsoup4==4.13.3 +beautifulsoup4==4.13.4 dictator==0.3.1 caller==0.0.2 watchdog==6.0.0 From 11cadefa4267057f983f96e49e1d811c180cb987 Mon Sep 17 00:00:00 2001 From: Abhilash Date: Mon, 28 Apr 2025 22:40:13 +0530 Subject: [PATCH 328/442] square root improvement --- square_root.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 square_root.py diff --git a/square_root.py b/square_root.py new file mode 100644 index 00000000000..768340a9104 --- /dev/null +++ b/square_root.py @@ -0,0 +1,9 @@ +import math + +def square_root(number): + if number >=0: + print(f"Square root {math.sqrt(number)}") + else: + print("Cannot find square root for the negative numbers..") +while True: + square_root(int(input("enter any number"))) \ No newline at end of file From a47ee2432056a9df273640bffff152cacb5c52c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Apr 2025 19:07:30 +0000 Subject: [PATCH 329/442] Bump slab from 1.7.0 to 1.8.0 Bumps [slab](https://github.com/DrMarc/slab) from 1.7.0 to 1.8.0. - [Release notes](https://github.com/DrMarc/slab/releases) - [Commits](https://github.com/DrMarc/slab/compare/v1.7.0...v1.8.0) --- updated-dependencies: - dependency-name: slab dependency-version: 1.8.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 07f0f486822..5673da516b0 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -100,7 +100,7 @@ pandas==2.2.3 pytest==8.3.5 qrcode==8.1 googletrans==4.0.2 -slab==1.7.0 +slab==1.8.0 psutil==7.0.0 mediapipe==0.10.21 rich==14.0.0 From a674183910e692065c1dff2da8c7c307d109c0ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Apr 2025 20:14:15 +0000 Subject: [PATCH 330/442] Bump pyglet from 2.1.3 to 2.1.6 Bumps [pyglet](https://github.com/pyglet/pyglet) from 2.1.3 to 2.1.6. - [Release notes](https://github.com/pyglet/pyglet/releases) - [Changelog](https://github.com/pyglet/pyglet/blob/master/RELEASE_NOTES) - [Commits](https://github.com/pyglet/pyglet/commits) --- updated-dependencies: - dependency-name: pyglet dependency-version: 2.1.6 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- PongPong_Game/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PongPong_Game/requirements.txt b/PongPong_Game/requirements.txt index 9fa555f42d1..71000361bd6 100644 --- a/PongPong_Game/requirements.txt +++ b/PongPong_Game/requirements.txt @@ -1 +1 @@ -pyglet==2.1.3 +pyglet==2.1.6 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 07f0f486822..55034bed4fc 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -55,7 +55,7 @@ pydantic==2.11.2 openpyxl==3.1.2 pytesseract==0.3.13 requests-mock==1.12.1 -pyglet==2.1.3 +pyglet==2.1.6 urllib3==2.3.0 thirdai==0.9.28 google-api-python-client==2.166.0 From 43b6c1142c7b9a78a3731f123d783597ec8c1be6 Mon Sep 17 00:00:00 2001 From: Abhilash Date: Tue, 29 Apr 2025 22:58:13 +0530 Subject: [PATCH 331/442] Added python script for reading large files --- large_files_reading.py | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 large_files_reading.py diff --git a/large_files_reading.py b/large_files_reading.py new file mode 100644 index 00000000000..a5ce0936f8a --- /dev/null +++ b/large_files_reading.py @@ -0,0 +1,4 @@ +with open("new_project.txt", "r" , encoding="utf-8") as file: # replace "largefile.text" with your actual file name or with absoulte path +# encoding = "utf-8" is especially used when the file contains special characters.... + for f in file: + print(f.strip()) From 6886b17240e1f23ce2a5a9d8763e8d0f2a7a1875 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 18:08:48 +0000 Subject: [PATCH 332/442] Bump openai from 1.70.0 to 1.76.1 Bumps [openai](https://github.com/openai/openai-python) from 1.70.0 to 1.76.1. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.70.0...v1.76.1) --- updated-dependencies: - dependency-name: openai dependency-version: 1.76.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 5673da516b0..c03104a07db 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.70.0 +openai==1.76.1 background==0.2.1 pydantic==2.11.2 openpyxl==3.1.2 From ca315f5529ff583211d99c68ba2ae7e37b6966b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 20:22:14 +0000 Subject: [PATCH 333/442] Bump thirdai from 0.9.28 to 0.9.31 Bumps thirdai from 0.9.28 to 0.9.31. --- updated-dependencies: - dependency-name: thirdai dependency-version: 0.9.31 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index eab032be649..88001821586 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -57,7 +57,7 @@ pytesseract==0.3.13 requests-mock==1.12.1 pyglet==2.1.6 urllib3==2.3.0 -thirdai==0.9.28 +thirdai==0.9.31 google-api-python-client==2.166.0 sound==0.1.0 xlwt==1.3.0 From 08216454fa9cc13ce486c3097caceea5ac0fb52c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Apr 2025 18:36:08 +0000 Subject: [PATCH 334/442] Bump solara from 1.44.1 to 1.47.0 Bumps [solara](https://github.com/widgetti/solara) from 1.44.1 to 1.47.0. - [Changelog](https://github.com/widgetti/solara/blob/master/CHANGELOG.md) - [Commits](https://github.com/widgetti/solara/compare/v1.44.1...v1.47.0) --- updated-dependencies: - dependency-name: solara dependency-version: 1.47.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- News_App/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/News_App/requirements.txt b/News_App/requirements.txt index 926bafe0714..fd923297117 100644 --- a/News_App/requirements.txt +++ b/News_App/requirements.txt @@ -1,4 +1,4 @@ -solara == 1.44.1 +solara == 1.47.0 Flask gunicorn ==23.0.0 simple-websocket diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index eab032be649..0dcf4ab5ae1 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -74,7 +74,7 @@ xor-cipher==5.0.1 bird==0.1.2 mechanize==0.4.10 translate==3.6.1 -solara==1.44.1 +solara==1.47.0 pywhatkit==5.4 mutagen==1.47.0 Unidecode==1.3.8 From 7087453dcd2a5ff0ae621aa7602a1368175f0d17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Apr 2025 18:36:15 +0000 Subject: [PATCH 335/442] Bump ccxt from 4.4.77 to 4.4.78 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.4.77 to 4.4.78. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/v4.4.77...v4.4.78) --- updated-dependencies: - dependency-name: ccxt dependency-version: 4.4.78 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index eab032be649..76ecae38c2d 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.3.8 Ball==0.2.9 pynput==1.8.1 gTTS==2.5.4 -ccxt==4.4.77 +ccxt==4.4.78 fitz==0.0.1.dev2 fastapi==0.115.12 Django==5.1.7 From 0c3dc0e0898f5f4bfa6504d63176dcf14e07e081 Mon Sep 17 00:00:00 2001 From: ajinkya Date: Thu, 1 May 2025 06:47:58 +0530 Subject: [PATCH 336/442] Add image-watermarker app --- Image-watermarker/.gitignore | 167 +++++++++++ Image-watermarker/README.md | 98 +++++++ Image-watermarker/app.py | 332 ++++++++++++++++++++++ Image-watermarker/fonts/AkayaKanadaka.ttf | Bin 0 -> 336136 bytes Image-watermarker/fonts/DancingScript.ttf | Bin 0 -> 130480 bytes Image-watermarker/fonts/Decorative.ttf | Bin 0 -> 60700 bytes Image-watermarker/fonts/MartianMono.ttf | Bin 0 -> 146732 bytes Image-watermarker/requirements.txt | Bin 0 -> 262 bytes Image-watermarker/watermark.py | 47 +++ 9 files changed, 644 insertions(+) create mode 100644 Image-watermarker/.gitignore create mode 100644 Image-watermarker/README.md create mode 100644 Image-watermarker/app.py create mode 100644 Image-watermarker/fonts/AkayaKanadaka.ttf create mode 100644 Image-watermarker/fonts/DancingScript.ttf create mode 100644 Image-watermarker/fonts/Decorative.ttf create mode 100644 Image-watermarker/fonts/MartianMono.ttf create mode 100644 Image-watermarker/requirements.txt create mode 100644 Image-watermarker/watermark.py diff --git a/Image-watermarker/.gitignore b/Image-watermarker/.gitignore new file mode 100644 index 00000000000..3a0307001fb --- /dev/null +++ b/Image-watermarker/.gitignore @@ -0,0 +1,167 @@ +# Project-Wide +images/ +.venv + + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ \ No newline at end of file diff --git a/Image-watermarker/README.md b/Image-watermarker/README.md new file mode 100644 index 00000000000..55755407495 --- /dev/null +++ b/Image-watermarker/README.md @@ -0,0 +1,98 @@ +# Watermarking Application + +A Python-based watermarking application built using `CustomTkinter` and `PIL` that allows users to add text and logo watermarks to images. The application supports the customization of text, font, size, color, and the ability to drag and position the watermark on the image. + +## Features + +- **Text Watermark**: Add customizable text to your images. + - Select font style, size, and color. + - Drag and position the text watermark on the image. +- **Logo Watermark**: Add a logo or image as a watermark. + - Resize and position the logo watermark. + - Supports various image formats (JPG, PNG, BMP). +- **Mutual Exclusivity**: The application ensures that users can either add text or a logo as a watermark, not both simultaneously. +- **Image Saving**: Save the watermarked image in PNG format with an option to choose the file name and location. + +## Installation + +### Prerequisites + +- Python 3.6 or higher +- `PIL` (Pillow) +- `CustomTkinter` + +### Installation Steps + +1. **Clone the repository:** + + ```bash + git clone https://github.com/jinku-06/Image-Watermarking-Desktop-app.git + cd watermarking-app + ``` + +2. **Install the required packages:** + + ```bash + pip install -r requirements.txt + ``` + +3. **Run the application:** + + ```bash + python app.py + ``` + +## Usage + +1. **Load an Image**: Start by loading an image onto the canvas. +2. **Add Text Watermark**: + - Input your desired text. + - Customize the font style, size, and color. + - Drag and position the text on the image. + - Note: Adding a text watermark disables the option to add a logo. +3. **Add Logo Watermark**: + - Select and upload a logo or image to use as a watermark. + - Resize and position the logo on the image. + - Note: Adding a logo watermark disables the option to add text. +4. **Save the Image**: Once satisfied with the watermark, save the image to your desired location. + +## Project Structure + +```bash +watermarking-app/ +│ +├── fonts/ # Custom fonts directory +├── app.py # Main application file +├── watermark.py # Watermark functionality class +├── requirements.txt # Required Python packages +└── README.md # Project documentation +``` + +## Sample and look + +Below are some sample images showcasing the application work: + +UI: + +Userinterface image + +Text Watermark : + +text watermark demo image + +Logo Watermark: + +logo watermark demo image + + + + + + + + + + + + + diff --git a/Image-watermarker/app.py b/Image-watermarker/app.py new file mode 100644 index 00000000000..3a388d3b98a --- /dev/null +++ b/Image-watermarker/app.py @@ -0,0 +1,332 @@ +import customtkinter as ctk +from customtkinter import filedialog +from CTkMessagebox import CTkMessagebox +from PIL import Image, ImageTk +from watermark import Watermark +import pyglet +from tkinter import colorchooser + + +# ------------------- Create Window ----------------- +pyglet.font.add_directory("fonts") + + +window = ctk.CTk() +window.geometry("810x525") +window.title("Grenze") + +text_label = None +loaded_image = False +logo = None +img = None +user_text = None +logo_path = None +color_code = "white" +font_values = ["Decorative", "MartianMono", "DancingScript", "AkayaKanadaka"] + + +# -------------------------- LOAD IMAGE AND CHECK FILE TYPE ON IMAGE CANVAS (use Frame) -------------- +def load_image(): + global img, loaded_image, image_canvas + + file_path = filedialog.askopenfilename( + filetypes=[("Image files", "*.jpg *.jpeg *.png *.bmp")] + ) + if not file_path: + return + + img = Image.open(file_path) + max_width, max_height = 800, 600 + if img.width > max_width or img.height > max_height: + ratio = min(max_width / img.width, max_height / img.height) + resize_img = img.resize( + (int(img.width * ratio), int(img.height * ratio)), Image.Resampling.LANCZOS + ) + loaded_image = ImageTk.PhotoImage(resize_img) + + window.geometry(f"{resize_img.width + 300+30}x{resize_img.height + 50}") + image_canvas.config(width=resize_img.width, height=resize_img.height) + image_canvas.grid(row=0, column=1, padx=20, pady=20, columnspan=2) + image_canvas.create_image(0, 0, anchor="nw", image=loaded_image) + else: + loaded_image = ImageTk.PhotoImage(img) + window.geometry(f"{img.width + 300}x{img.height + 50}") + image_canvas.config(width=img.width, height=img.height) + image_canvas.grid(row=0, column=1, padx=20, pady=20, columnspan=2) + image_canvas.create_image(0, 0, anchor="nw", image=loaded_image) + + +# ------------------------------------- DRAG AND DROP FEATURE -------- + +start_x = 0 +start_y = 0 + +new_x = 0 +new_y = 0 + + +def move_logo(e): + global logo, new_x, new_y + canvas_width = image_canvas.winfo_width() + canvas_height = image_canvas.winfo_height() + label_width = image_canvas.bbox(logo)[2] - image_canvas.bbox(logo)[0] + label_height = image_canvas.bbox(logo)[3] - image_canvas.bbox(logo)[1] + + new_x = e.x + new_y = e.y + + if new_x < 0: + new_x = 0 + elif new_x + label_width > canvas_width: + new_x = canvas_width - label_width + + if new_y < 0: + new_y = 0 + elif new_y + label_height > canvas_height: + new_y = canvas_height - label_height + image_canvas.coords(logo, new_x, new_y) + + +def move_text(e): + global text_label, new_x, new_y + canvas_width = image_canvas.winfo_width() + canvas_height = image_canvas.winfo_height() + label_width = image_canvas.bbox(text_label)[2] - image_canvas.bbox(text_label)[0] + label_height = image_canvas.bbox(text_label)[3] - image_canvas.bbox(text_label)[1] + + new_x = e.x + new_y = e.y + + if new_x < 0: + new_x = 0 + elif new_x + label_width > canvas_width: + new_x = canvas_width - label_width + + if new_y < 0: + new_y = 0 + elif new_y + label_height > canvas_height: + new_y = canvas_height - label_height + image_canvas.coords(text_label, new_x, new_y) + + +def choose_color(): + global color_code + choose_color = colorchooser.askcolor(title="Choose Color") + color_code = choose_color[1] + + +# ----------------- ADD TEXT ON CANVAS----------------- + + +def add_text_on_canvas(): + global text_label, loaded_image, user_text, img, font_values + user_text = text.get() + font_key = font_style.get() + if font_key not in font_values: + CTkMessagebox( + title="Font Not Available", + message=f"{font_key} FileNotFoundError.", + ) + return + + if logo is not None: + CTkMessagebox(title="Logo Use", message="Logo is in use.") + return + + if text_label is not None: + image_canvas.delete(text_label) # Delete previous text_label + + if loaded_image: + if user_text: + selected_size = int(font_size.get()) + pyglet.font.add_file(f"fonts/{font_key}.ttf") + text_label = image_canvas.create_text( + 10, + 10, + text=user_text, + font=(font_key, selected_size), + fill=color_code, + anchor="nw", + ) + + image_canvas.tag_bind(text_label, "", move_text) + else: + CTkMessagebox(title="Error", message="Text Filed Empty.", icon="cancel") + else: + CTkMessagebox(title="Error", message="Image Not Found. Upload Image.") + + +# ----------------------TODO UPLOAD LOGO ----------- + + +def upload_logo(): + global loaded_image, logo, logo_path, text_label + + if text_label is not None: + CTkMessagebox( + title="Text In Use", message="You are using text. Can't use logo." + ) + return + + if logo is not None: + image_canvas.delete(logo) + if loaded_image: + logo_path = filedialog.askopenfilename( + filetypes=[("Image files", "*.jpg *.jpeg *.png *.bmp")], + ) + if logo_path: + logo_image = Image.open(logo_path).convert("RGBA") + resize = logo_image.resize((160, 150)) + logo_photo = ImageTk.PhotoImage(resize) + logo = image_canvas.create_image(0, 0, anchor="nw", image=logo_photo) + image_canvas.tag_bind(logo, "", move_logo) + + image_canvas.logo_photo = logo_photo + + else: + CTkMessagebox( + title="Image Field Empty", + message="Image field empty. Click on the open image button to add the image to the canvas.", + icon="cancel", + ) + + +# ---------------------------- TODO SAVE FUNCTION --------------- +watermark = Watermark() + + +def save_image(): + global text_label, loaded_image, file_path, user_text, img, new_x, new_y, logo + if loaded_image and text_label: + width, height = img.size + canvas_width = image_canvas.winfo_width() + canvas_height = image_canvas.winfo_height() + + scale_x = width / canvas_width + scale_y = height / canvas_height + + image_x = int(new_x * scale_x) - 10 + image_y = int(new_y * scale_y) - 10 + + adjusted_font_size = int(int(font_size.get()) * min(scale_x, scale_y)) + 6 + watermarked_image = watermark.add_text_watermark( + image=img, + text=user_text, + position=(image_x, image_y), + text_color=color_code, + font_style=f"fonts/{font_style.get()}.ttf", + font_size=adjusted_font_size, + ) + + watermark.save_image(watermarked_image) + + elif loaded_image and logo_path is not None: + original_image = img.convert("RGBA") + canvas_width = image_canvas.winfo_width() + canvas_height = image_canvas.winfo_height() + + logo_image = Image.open(logo_path) + logo_resized = logo_image.resize( + ( + int(original_image.width * 0.2) + 50, + int(original_image.height * 0.2), + ) + ) + + image_width, image_height = original_image.size + logo_position = ( + int(new_x * image_width / canvas_width), + int(new_y * image_height / canvas_height), + ) + + watermark.add_logo( + image=original_image, logo=logo_resized, position=logo_position + ) + + watermark.save_image(original_image) + + +# -------------------Tab View AND OPEN IMAGE----------- + +tabview = ctk.CTkTabview(window, corner_radius=10, height=400) +tabview.grid(row=0, column=0, padx=10) + + +tab_1 = tabview.add("Text Watermark") +tab_2 = tabview.add("Logo Watermark") + + +# --------------- TEXT WATERMARK TAB_1 VIEW ---------- +tab_1.grid_columnconfigure(0, weight=1) +tab_1.grid_columnconfigure(1, weight=1) + +text = ctk.CTkEntry(master=tab_1, placeholder_text="Entry Text", width=200) +text.grid(row=2, column=0, padx=20, pady=10) + + +font_style = ctk.CTkComboBox( + master=tab_1, + values=font_values, + width=200, +) +font_style.grid(row=3, column=0, pady=10) + + +font_size = ctk.CTkComboBox( + master=tab_1, + values=[ + "10", + "12", + "14", + "20", + ], + width=200, +) +font_size.grid(row=4, column=0, pady=10) +font_size.set("10") + +add_text = ctk.CTkButton( + master=tab_1, text="Add Text", width=200, command=add_text_on_canvas +) +add_text.grid(row=5, column=0, pady=10) + + +open_image = ctk.CTkButton( + master=tab_1, text="Open Image", width=200, corner_radius=10, command=load_image +) +open_image.grid(row=7, column=0, pady=10) + +open_image2 = ctk.CTkButton( + master=tab_2, text="Open Image", width=200, corner_radius=10, command=load_image +) +open_image2.grid(row=2, column=0, padx=20, pady=10) + +pick_color = ctk.CTkButton( + master=tab_1, text="Pick Color", width=200, corner_radius=10, command=choose_color +) +pick_color.grid(row=6, column=0, padx=10, pady=10) + + +# ------------- LOGO WATERMARK SESSION TAB_2 --------------- + +logo_upload = ctk.CTkButton( + master=tab_2, text="Upload Logo", width=200, corner_radius=10, command=upload_logo +) +logo_upload.grid(row=3, column=0, pady=10) + + +# ----------------- ImageFrame --------------------- +image_canvas = ctk.CTkCanvas( + width=500, + height=360, +) +image_canvas.config(bg="gray24", highlightthickness=0, borderwidth=0) +image_canvas.grid(row=0, column=1, columnspan=2) + + +# -------- SAVE BUTTON -------- + +save_image_button = ctk.CTkButton(window, text="Save Image", command=save_image) +save_image_button.grid(pady=10) + +window.mainloop() diff --git a/Image-watermarker/fonts/AkayaKanadaka.ttf b/Image-watermarker/fonts/AkayaKanadaka.ttf new file mode 100644 index 0000000000000000000000000000000000000000..01eefcc02fb492c70f933d06cd0ed9dceae17774 GIT binary patch literal 336136 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

_R^j)W8T)ky|CVW`l4 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 G;Qk+SFQR1t literal 0 HcmV?d00001 diff --git a/Image-watermarker/fonts/DancingScript.ttf b/Image-watermarker/fonts/DancingScript.ttf new file mode 100644 index 0000000000000000000000000000000000000000..af175f99b06ccaf6ac713077159ee89fa69cf3ef GIT binary patch literal 130480 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 icpu;8liT@ju>TH4CQkMkYVs* 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 z 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%0D7c!mrd`W@!_N<9}J8Ha)iFXA)CW$C**D^M?wzt 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 literal 0 HcmV?d00001 diff --git a/Image-watermarker/requirements.txt b/Image-watermarker/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..f6fcb76c9837795bf87ad9945549b5b4180344a2 GIT binary patch literal 262 zcmY+8!3x4K5JcZu@K>Y_ie5Z<_T~?0Qc7vHQZ4GwtFvo!kR_YIyv)q!z2iX3o{F31 zNUhh2o+n#PV8NO>Ga{q(yOgtbOT$HX#o*jZoUy^#B%eV{l5R}YHn&2=MyGJm>lvC&bo=F)=4RaIo`Stw**z72D literal 0 HcmV?d00001 diff --git a/Image-watermarker/watermark.py b/Image-watermarker/watermark.py new file mode 100644 index 00000000000..6968cc04c45 --- /dev/null +++ b/Image-watermarker/watermark.py @@ -0,0 +1,47 @@ +from PIL import Image, ImageDraw, ImageFont +from customtkinter import filedialog +from CTkMessagebox import CTkMessagebox +import customtkinter as ctk + + +class Watermark: + def __init__(self): + pass + + def add_text_watermark( + self, image, text, text_color, font_style, font_size, position=(0, 0) + ): + + font = ImageFont.truetype(font_style, font_size) + draw = ImageDraw.Draw(image) + draw.text(position, text, fill=text_color, font=font) + return image + + def add_logo(self, image, logo, position=(0, 0)): + if logo.mode != "RGBA": + logo = logo.convert("RGBA") + if image.mode != "RGBA": + image = image.convert("RGBA") + + if (position[0] + logo.width > image.width) or ( + position[1] + logo.height > image.height + ): + CTkMessagebox(title="Logo position", message="Logo position out of bounds.") + + image.paste(logo, position, mask=logo) + return image + + def save_image(self, image): + save_path = filedialog.asksaveasfilename( + defaultextension="*.png", + title="Save as", + filetypes=[ + ("PNG files", "*.png"), + ("All files", "*.*"), + ], + ) + if save_path: + try: + image.save(save_path) + except Exception as e: + print("Failed to save image: {e}") From 859977d01fd20bb7cbc9915db3aae13d2f568b9b Mon Sep 17 00:00:00 2001 From: ajinkya Date: Thu, 1 May 2025 07:01:16 +0530 Subject: [PATCH 337/442] delete .gitignore file --- Image-watermarker/.gitignore | 167 ----------------------------------- 1 file changed, 167 deletions(-) delete mode 100644 Image-watermarker/.gitignore diff --git a/Image-watermarker/.gitignore b/Image-watermarker/.gitignore deleted file mode 100644 index 3a0307001fb..00000000000 --- a/Image-watermarker/.gitignore +++ /dev/null @@ -1,167 +0,0 @@ -# Project-Wide -images/ -.venv - - -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ -cover/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -.pybuilder/ -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -#poetry.lock - -# pdm -# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. -#pdm.lock -# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it -# in version control. -# https://pdm.fming.dev/latest/usage/project/#working-with-version-control -.pdm.toml -.pdm-python -.pdm-build/ - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# pytype static type analyzer -.pytype/ - -# Cython debug symbols -cython_debug/ - -# PyCharm -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ \ No newline at end of file From d2e2fc57804d8d0f24272139796d1459b7e43ae8 Mon Sep 17 00:00:00 2001 From: Abhilash Date: Thu, 1 May 2025 19:22:52 +0530 Subject: [PATCH 338/442] fixing_nested_if --- multiple_comditions.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 multiple_comditions.py diff --git a/multiple_comditions.py b/multiple_comditions.py new file mode 100644 index 00000000000..68ebd1f94e5 --- /dev/null +++ b/multiple_comditions.py @@ -0,0 +1,22 @@ +while True: + try: + user = int(input("enter any number b/w 1-3\n")) + if user == 1: + print("in first if") + elif user == 2: + print("in second if") + elif user ==3: + print("in third if") + else: + print("Enter numbers b/w the range of 1-3") + except: + print("enter only digits") + + +""" +## Why we are using elif instead of nested if ? +When you have multiple conditions to check, using nested if means that if the first condition is true, the program still checks the second +if condition, even though it's already decided that the first condition worked. This makes the program do more work than necessary. +On the other hand, when you use elif, if one condition is satisfied, the program exits the rest of the conditions and doesn't continue checking. +It’s more efficient and clean, as it immediately moves to the correct option without unnecessary steps. +""" \ No newline at end of file From 808474cd298538824910174870477aa0cf2bc61b Mon Sep 17 00:00:00 2001 From: Inbaselvan-ayyanar <141208152+Inbaselvan-ayyanar@users.noreply.github.com> Date: Thu, 1 May 2025 20:03:13 +0530 Subject: [PATCH 339/442] Update gcd.py --- gcd.py | 1 + 1 file changed, 1 insertion(+) diff --git a/gcd.py b/gcd.py index 0f10da082d7..b496dca1d20 100644 --- a/gcd.py +++ b/gcd.py @@ -6,6 +6,7 @@ b = int(input("Enter number 2 (b): ")) i = 1 +gcd=-1 while i <= a and i <= b: if a % i == 0 and b % i == 0: gcd = i From 4da1d2d828026aa2eb9de304969f54aeef075aa1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 May 2025 18:29:42 +0000 Subject: [PATCH 340/442] Bump keras from 3.9.1 to 3.9.2 Bumps [keras](https://github.com/keras-team/keras) from 3.9.1 to 3.9.2. - [Release notes](https://github.com/keras-team/keras/releases) - [Commits](https://github.com/keras-team/keras/compare/v3.9.1...v3.9.2) --- updated-dependencies: - dependency-name: keras dependency-version: 3.9.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 7bd4f6628b7..3a1b69e7fe8 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -41,7 +41,7 @@ tornado==6.4.2 obs==0.0.0 todo==0.1 oauth2client==4.1.3 -keras==3.9.1 +keras==3.9.2 pymongo==4.11.3 playsound==1.3.0 pyttsx3==2.98 From f1803af406994cf4740a8e58ff68e4cedf557f2b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 May 2025 18:29:45 +0000 Subject: [PATCH 341/442] Bump pillow from 11.1.0 to 11.2.1 Bumps [pillow](https://github.com/python-pillow/Pillow) from 11.1.0 to 11.2.1. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/11.1.0...11.2.1) --- updated-dependencies: - dependency-name: pillow dependency-version: 11.2.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- PDF/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PDF/requirements.txt b/PDF/requirements.txt index f76ca036694..4a068119c0d 100644 --- a/PDF/requirements.txt +++ b/PDF/requirements.txt @@ -1,2 +1,2 @@ -Pillow==11.1.0 +Pillow==11.2.1 fpdf==1.7.2 \ No newline at end of file diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 7bd4f6628b7..0f9032d27d8 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -31,7 +31,7 @@ pyserial==3.5 twilio==9.5.2 tabula==1.0.5 nltk==3.9.1 -Pillow==11.1.0 +Pillow==11.2.1 SocksiPy-branch==1.01 xlrd==2.0.1 fpdf==1.7.2 From 1652d3d77d5fe4a950451514143713f63f7956ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 May 2025 18:29:58 +0000 Subject: [PATCH 342/442] Bump aiohttp from 3.11.15 to 3.11.18 Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.11.15 to 3.11.18. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.11.15...v3.11.18) --- updated-dependencies: - dependency-name: aiohttp dependency-version: 3.11.18 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- async_downloader/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/async_downloader/requirements.txt b/async_downloader/requirements.txt index 196f2b5419b..f316405d755 100644 --- a/async_downloader/requirements.txt +++ b/async_downloader/requirements.txt @@ -1 +1 @@ -aiohttp==3.11.15 +aiohttp==3.11.18 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 7bd4f6628b7..b4434ffca3b 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -1,5 +1,5 @@ pafy==0.5.5 -aiohttp==3.11.15 +aiohttp==3.11.18 fuzzywuzzy==0.18.0 hupper==1.12.1 seaborn==0.13.2 From 35cfb4f0d3740b178df2f3648d8582f3aa716b9c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 May 2025 18:18:48 +0000 Subject: [PATCH 343/442] Bump pydantic from 2.11.2 to 2.11.4 Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.11.2 to 2.11.4. - [Release notes](https://github.com/pydantic/pydantic/releases) - [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md) - [Commits](https://github.com/pydantic/pydantic/compare/v2.11.2...v2.11.4) --- updated-dependencies: - dependency-name: pydantic dependency-version: 2.11.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index c6117193dd2..12ac3ffccc9 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -51,7 +51,7 @@ pywifi==1.1.12 patterns==0.3 openai==1.76.1 background==0.2.1 -pydantic==2.11.2 +pydantic==2.11.4 openpyxl==3.1.2 pytesseract==0.3.13 requests-mock==1.12.1 From 177f7c79045ee637771f227a415e91ca037c7f9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 May 2025 18:18:51 +0000 Subject: [PATCH 344/442] Bump openai from 1.76.1 to 1.76.2 Bumps [openai](https://github.com/openai/openai-python) from 1.76.1 to 1.76.2. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.76.1...v1.76.2) --- updated-dependencies: - dependency-name: openai dependency-version: 1.76.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index c6117193dd2..6832f1d5f40 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.76.1 +openai==1.76.2 background==0.2.1 pydantic==2.11.2 openpyxl==3.1.2 From c78ac3aa8a2284b37bd9e0e112af8253af152684 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 May 2025 18:19:00 +0000 Subject: [PATCH 345/442] Bump qrcode from 8.1 to 8.2 Bumps [qrcode](https://github.com/lincolnloop/python-qrcode) from 8.1 to 8.2. - [Changelog](https://github.com/lincolnloop/python-qrcode/blob/main/CHANGES.rst) - [Commits](https://github.com/lincolnloop/python-qrcode/commits/v8.2) --- updated-dependencies: - dependency-name: qrcode dependency-version: '8.2' dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index c6117193dd2..10e40dfb7a8 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -98,7 +98,7 @@ opencv-python==4.11.0.86 tensorflow==2.18.1 pandas==2.2.3 pytest==8.3.5 -qrcode==8.1 +qrcode==8.2 googletrans==4.0.2 slab==1.8.0 psutil==7.0.0 From da3820953bb994f7a86d3eb0e5fbb62235690005 Mon Sep 17 00:00:00 2001 From: Abhilash Date: Sat, 3 May 2025 18:35:09 +0530 Subject: [PATCH 346/442] saving_input_into_list.py --- saving_input_into_list.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 saving_input_into_list.py diff --git a/saving_input_into_list.py b/saving_input_into_list.py new file mode 100644 index 00000000000..03caac68016 --- /dev/null +++ b/saving_input_into_list.py @@ -0,0 +1,13 @@ +ran= int(input("Enter the range of elements you want to store / insert ")) +l1=[] +for i in range(ran): + l1.append(input("Enter here ")) + +print(l1) + + +""" +program first asks the user how many values they want to enter. Then, using a loop, it lets the user enter that many values one by one. +Each entered value is saved into a list called l1. Once all the values are entered, the program prints the complete list, showing +everything the user typed. It's a beginner-friendly way to learn how to collect multiple inputs and store them for later use. +""" \ No newline at end of file From 308bbea36144f27044dca8c248a58bd2ad322470 Mon Sep 17 00:00:00 2001 From: Abhilash Date: Sun, 4 May 2025 19:16:23 +0530 Subject: [PATCH 347/442] loops.py --- loops.py | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 loops.py diff --git a/loops.py b/loops.py new file mode 100644 index 00000000000..50d4ac6ef7b --- /dev/null +++ b/loops.py @@ -0,0 +1,40 @@ +# 2 loops + +# for loop: + +""" +Syntax.. +-> "range" : starts with 0. +-> The space after the space is called as identiation, python generally identifies the block of code with the help of indentation, +indentation is generally 4 spaces / 1 tab space.. + + +for in range(): + statements you want to execute + +for in : + print() +To print the list / or any iterator items + +""" + +# 1. for with range... +for i in range(3): + print("Hello... with range") + # prints Hello 3 times.. + +# 2.for with list + +l1=[1,2,3,78,98,56,52] +for i in l1: + print("list items",i) + # prints list items one by one.... + +for i in "ABC": + print(i) + +# while loop: +i=0 +while i<=5: + print("hello.. with while") + i+=1 \ No newline at end of file From 9eb618f207185f57cd72cc283544626a8724250f Mon Sep 17 00:00:00 2001 From: Abhilash Date: Mon, 5 May 2025 19:47:21 +0530 Subject: [PATCH 348/442] added a beginner friendly billing script --- billing.py | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 billing.py diff --git a/billing.py b/billing.py new file mode 100644 index 00000000000..29b252da599 --- /dev/null +++ b/billing.py @@ -0,0 +1,68 @@ +items= {"apple":5,"soap":4,"soda":6,"pie":7,"cake":20} +total_price=0 +try : + print(""" +Press 1 for apple +Press 2 for soap +Press 3 for soda +Press 4 for pie +Press 5 for cake +Press 6 for bill""") + while True: + choice = int(input("enter your choice here..\n")) + if choice ==1: + print("Apple added to the cart") + total_price+=items["apple"] + + elif choice== 2: + print("soap added to the cart") + total_price+= items["soap"] + elif choice ==3: + print("soda added to the cart") + total_price+=items["soda"] + elif choice ==4: + print("pie added to the cart") + total_price+=items["pie"] + elif choice ==5: + print("cake added to the cart") + total_price+=items["cake"] + elif choice == 6: + print(f""" + +Total amount :{total_price} +""") + break + else: + print("Please enter the digits within the range 1-6..") +except: + print("enter only digits") + +""" +Code Explanation: +A dictionary named items is created to store product names and their corresponding prices. +Example: "apple": 5 means apple costs 5 units. + +one variable is initialized: + +total_price to keep track of the overall bill. + + +A menu is printed that shows the user what number to press for each item or to generate the final bill. + +A while True loop is started, meaning it will keep running until the user explicitly chooses to stop (by selecting "6" for the bill). + +Inside the loop: + +The user is asked to enter a number (1–6). + +Depending on their input: + +If they enter 1–5, the corresponding item is "added to the cart" and its price is added to the total_price. + +If they enter 6, the total price is printed and the loop breaks (ends). + +If they enter something outside 1–6, a warning message is shown. + +The try-except block is used to catch errors if the user enters something that's not a number (like a letter or symbol). +In that case, it simply shows: "enter only digits". +""" \ No newline at end of file From 629b914fcc1e7616238019533e15701571afaa17 Mon Sep 17 00:00:00 2001 From: Inbaselvan-ayyanar <141208152+Inbaselvan-ayyanar@users.noreply.github.com> Date: Mon, 5 May 2025 22:02:54 +0530 Subject: [PATCH 349/442] Update String_Palindrome.py more efficient --- String_Palindrome.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/String_Palindrome.py b/String_Palindrome.py index 6b8302b6477..ab4103fd863 100644 --- a/String_Palindrome.py +++ b/String_Palindrome.py @@ -1,15 +1,15 @@ # Program to check if a string is palindrome or not -my_str = 'aIbohPhoBiA' +my_str = input().strip() # make it suitable for caseless comparison my_str = my_str.casefold() # reverse the string -rev_str = reversed(my_str) +rev_str = my_str[::-1] # check if the string is equal to its reverse -if list(my_str) == list(rev_str): +if my_str == rev_str: print("The string is a palindrome.") else: print("The string is not a palindrome.") From 781b0f0f316d683ae24c762cc4d17bc6795187ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 18:28:29 +0000 Subject: [PATCH 350/442] Bump pymongo from 4.11.3 to 4.12.1 Bumps [pymongo](https://github.com/mongodb/mongo-python-driver) from 4.11.3 to 4.12.1. - [Release notes](https://github.com/mongodb/mongo-python-driver/releases) - [Changelog](https://github.com/mongodb/mongo-python-driver/blob/master/doc/changelog.rst) - [Commits](https://github.com/mongodb/mongo-python-driver/compare/4.11.3...4.12.1) --- updated-dependencies: - dependency-name: pymongo dependency-version: 4.12.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 59c0daaa421..0e34d3dd694 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -42,7 +42,7 @@ obs==0.0.0 todo==0.1 oauth2client==4.1.3 keras==3.9.2 -pymongo==4.11.3 +pymongo==4.12.1 playsound==1.3.0 pyttsx3==2.98 auto-mix-prep==0.2.0 From 934b48b1f7514bf2ceffcb1ab91c2379f4a0b71b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 18:33:03 +0000 Subject: [PATCH 351/442] Bump twilio from 9.5.2 to 9.6.0 Bumps [twilio](https://github.com/twilio/twilio-python) from 9.5.2 to 9.6.0. - [Release notes](https://github.com/twilio/twilio-python/releases) - [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md) - [Commits](https://github.com/twilio/twilio-python/compare/9.5.2...9.6.0) --- updated-dependencies: - dependency-name: twilio dependency-version: 9.6.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 59c0daaa421..ac96396dd58 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -28,7 +28,7 @@ requests==2.32.3 quo==2023.5.1 PyPDF2==3.0.1 pyserial==3.5 -twilio==9.5.2 +twilio==9.6.0 tabula==1.0.5 nltk==3.9.1 Pillow==11.2.1 From c736f80fc1602cbadeec1a11de1394e990c11ca1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 18:36:35 +0000 Subject: [PATCH 352/442] Bump selenium from 4.30.0 to 4.32.0 Bumps [selenium](https://github.com/SeleniumHQ/Selenium) from 4.30.0 to 4.32.0. - [Release notes](https://github.com/SeleniumHQ/Selenium/releases) - [Commits](https://github.com/SeleniumHQ/Selenium/compare/selenium-4.30.0...selenium-4.32.0) --- updated-dependencies: - dependency-name: selenium dependency-version: 4.32.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 59c0daaa421..29bb1235701 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -21,7 +21,7 @@ backend==0.2.4.1 win10toast==0.9 Counter==1.0.0 Flask==3.1.0 -selenium==4.30.0 +selenium==4.32.0 firebase-admin==6.7.0 ujson==5.10.0 requests==2.32.3 From 93a7c087b4cc5a21d5f93ac80180daf8bf2386dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 18:46:35 +0000 Subject: [PATCH 353/442] Bump unidecode from 1.3.8 to 1.4.0 Bumps [unidecode](https://github.com/kmike/text-unidecode) from 1.3.8 to 1.4.0. - [Release notes](https://github.com/kmike/text-unidecode/releases) - [Commits](https://github.com/kmike/text-unidecode/commits) --- updated-dependencies: - dependency-name: unidecode dependency-version: 1.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 1e6e174f6ba..6f2356af8e5 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -77,7 +77,7 @@ translate==3.6.1 solara==1.47.0 pywhatkit==5.4 mutagen==1.47.0 -Unidecode==1.3.8 +Unidecode==1.4.0 Ball==0.2.9 pynput==1.8.1 gTTS==2.5.4 From d2f2a4dac45af8554d130eadc416f2cf1aab7876 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 18:46:38 +0000 Subject: [PATCH 354/442] Bump urllib3 from 2.3.0 to 2.4.0 Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.3.0 to 2.4.0. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/2.3.0...2.4.0) --- updated-dependencies: - dependency-name: urllib3 dependency-version: 2.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 1e6e174f6ba..a93b1db3868 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -56,7 +56,7 @@ openpyxl==3.1.2 pytesseract==0.3.13 requests-mock==1.12.1 pyglet==2.1.6 -urllib3==2.3.0 +urllib3==2.4.0 thirdai==0.9.31 google-api-python-client==2.166.0 sound==0.1.0 From 51688cea2f2bec1034c848dc4030e03be40f16e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 18:46:42 +0000 Subject: [PATCH 355/442] Bump yfinance from 0.2.55 to 0.2.58 Bumps [yfinance](https://github.com/ranaroussi/yfinance) from 0.2.55 to 0.2.58. - [Release notes](https://github.com/ranaroussi/yfinance/releases) - [Changelog](https://github.com/ranaroussi/yfinance/blob/main/CHANGELOG.rst) - [Commits](https://github.com/ranaroussi/yfinance/compare/0.2.55...0.2.58) --- updated-dependencies: - dependency-name: yfinance dependency-version: 0.2.58 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 1e6e174f6ba..508316e82af 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -66,7 +66,7 @@ speechtotext==0.0.3 wikipedia==1.4.0 tqdm==4.67.1 Menu==3.2.2 -yfinance==0.2.55 +yfinance==0.2.58 tweepy==4.15.0 tkcalendar==1.6.1 pytube==15.0.0 From fb0ba5b979dbe2d48a8ff0a1cc585a1b71eddfea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 May 2025 18:23:03 +0000 Subject: [PATCH 356/442] Bump firebase-admin from 6.7.0 to 6.8.0 Bumps [firebase-admin](https://github.com/firebase/firebase-admin-python) from 6.7.0 to 6.8.0. - [Release notes](https://github.com/firebase/firebase-admin-python/releases) - [Commits](https://github.com/firebase/firebase-admin-python/compare/v6.7.0...v6.8.0) --- updated-dependencies: - dependency-name: firebase-admin dependency-version: 6.8.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index bd3d7bf8a80..d3298e84b94 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -22,7 +22,7 @@ win10toast==0.9 Counter==1.0.0 Flask==3.1.0 selenium==4.32.0 -firebase-admin==6.7.0 +firebase-admin==6.8.0 ujson==5.10.0 requests==2.32.3 quo==2023.5.1 From 69ded53941167730b3f25a1323dbc0e0ac82ec5b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 May 2025 18:23:16 +0000 Subject: [PATCH 357/442] Bump google-api-python-client from 2.166.0 to 2.169.0 Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.166.0 to 2.169.0. - [Release notes](https://github.com/googleapis/google-api-python-client/releases) - [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.166.0...v2.169.0) --- updated-dependencies: - dependency-name: google-api-python-client dependency-version: 2.169.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index bd3d7bf8a80..20926437543 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -58,7 +58,7 @@ requests-mock==1.12.1 pyglet==2.1.6 urllib3==2.4.0 thirdai==0.9.31 -google-api-python-client==2.166.0 +google-api-python-client==2.169.0 sound==0.1.0 xlwt==1.3.0 pygame==2.6.1 From 60ee0f78b8e5d3fba1e178efeee51731a1971e58 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 May 2025 18:06:40 +0000 Subject: [PATCH 358/442] Bump openai from 1.76.2 to 1.78.0 Bumps [openai](https://github.com/openai/openai-python) from 1.76.2 to 1.78.0. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.76.2...v1.78.0) --- updated-dependencies: - dependency-name: openai dependency-version: 1.78.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index bd3d7bf8a80..f921dc44578 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.76.2 +openai==1.78.0 background==0.2.1 pydantic==2.11.4 openpyxl==3.1.2 From 1ececf8f69dfc1d384943a527c439c1a68d0cb67 Mon Sep 17 00:00:00 2001 From: Abhilash Date: Fri, 9 May 2025 12:17:16 +0530 Subject: [PATCH 359/442] added scientific calculator --- scientific_cal.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 scientific_cal.py diff --git a/scientific_cal.py b/scientific_cal.py new file mode 100644 index 00000000000..9827ec8f44f --- /dev/null +++ b/scientific_cal.py @@ -0,0 +1,45 @@ +import math +while True: + print(""" + Press 1 for basic calculator + Press 2 for scientifc calculator""") + try: + cho= int(input("enter your choice here.. ")) + if cho == 1: + print(eval(input("enter the numbers with operator "))) + elif cho==2: + user = int(input(""" + Press 1 for pi calculation + press 2 for sin calculation + press 3 for exponent calculation + press 4 for tangent calculation + press 5 for square root calculation + press 6 round calculation + press 7 for absoulte value + press any other number to exit the loop. """)) + + a= float(input("enter your value here.. ")) + if user== 1: + print(f"entered value : {a} result :{math.pi*(a)}") + elif user ==2: + print(f"entered value : {a} result :{math.sin(math.radians(a))}") + + elif user == 3: + power= float(input("enter the power")) + print(f"entered value : {a} result :{a**power}") + elif user ==4: + angle_in_radians = math.radians(a) + result = math.tan(angle_in_radians) + print(f"entered value : {a} result :{result}") + elif user ==5 : + print(f"entered value : {a} result :{math.sqrt(a)}") + elif user== 6: + print(f"entered value : {a} result :{round(a)}") + elif user ==7 : + print(f"entered value : {a} result :{abs(a)}") + else: + break + except ZeroDivisionError: + print("value cannot be divided by 0") + except: + print("Enter only digits ") \ No newline at end of file From 05b4437dced520c95d9a7e68538d672840f4ab91 Mon Sep 17 00:00:00 2001 From: Abhilash Date: Sat, 10 May 2025 16:37:40 +0530 Subject: [PATCH 360/442] added a simple CSV reading script --- reading_csv.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 reading_csv.py diff --git a/reading_csv.py b/reading_csv.py new file mode 100644 index 00000000000..bc8fee6334f --- /dev/null +++ b/reading_csv.py @@ -0,0 +1,16 @@ +import pandas as pd + +# reading csv file into python +df= pd.read_csv("c:\PROJECT\Drug_Recommendation_System\drug_recommendation_system\Drugs_Review_Datasets.csv") # Replace the path with your own file path + +print(df) + +# Basic functions +print(df.info()) # Provides a short summary of the DataFrame +print(df.head()) # prints first 5 rows +print(df.tail()) # prints last 5 rows +print(df.describe()) #statistical summary of numeric columns +print(df.columns) # Returns column names +print(df.shape) # Returns the number of rows and columnsrr + +print(help(pd)) # Use help(pd) to explore and understand the available functions and attributes in the pandas (pd) lib \ No newline at end of file From 3d8841b545db0f8fe14de0b45a39ba0876f7d9df Mon Sep 17 00:00:00 2001 From: Abhilash Date: Mon, 12 May 2025 12:33:24 +0530 Subject: [PATCH 361/442] added basic csv reading script by using python --- CSV_file.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 CSV_file.py diff --git a/CSV_file.py b/CSV_file.py new file mode 100644 index 00000000000..d67e23064c4 --- /dev/null +++ b/CSV_file.py @@ -0,0 +1,14 @@ +import pandas as pd + +# loading the dataset + +df= pd.read_csv(r"c:\PROJECT\Drug_Recommendation_System\drug_recommendation_system\Drugs_Review_Datasets.csv") + +print(df) #prints Dataset +# funtions +print(df.tail()) +print(df.head()) +print(df.info()) +print(df.describe()) +print(df.column) +print(df.shape()) \ No newline at end of file From 6056ecaccfd24f69b3f4a00d1a0ffbbde095a4d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 May 2025 18:14:09 +0000 Subject: [PATCH 362/442] Bump openai from 1.78.0 to 1.78.1 Bumps [openai](https://github.com/openai/openai-python) from 1.78.0 to 1.78.1. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.78.0...v1.78.1) --- updated-dependencies: - dependency-name: openai dependency-version: 1.78.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4bac3e42f37..1922a295ead 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.78.0 +openai==1.78.1 background==0.2.1 pydantic==2.11.4 openpyxl==3.1.2 From ebeb0922590b323a169ce5b423c1a49f3114d775 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 May 2025 18:14:12 +0000 Subject: [PATCH 363/442] Bump yfinance from 0.2.58 to 0.2.61 Bumps [yfinance](https://github.com/ranaroussi/yfinance) from 0.2.58 to 0.2.61. - [Release notes](https://github.com/ranaroussi/yfinance/releases) - [Changelog](https://github.com/ranaroussi/yfinance/blob/main/CHANGELOG.rst) - [Commits](https://github.com/ranaroussi/yfinance/compare/0.2.58...0.2.61) --- updated-dependencies: - dependency-name: yfinance dependency-version: 0.2.61 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4bac3e42f37..c7290075103 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -66,7 +66,7 @@ speechtotext==0.0.3 wikipedia==1.4.0 tqdm==4.67.1 Menu==3.2.2 -yfinance==0.2.58 +yfinance==0.2.61 tweepy==4.15.0 tkcalendar==1.6.1 pytube==15.0.0 From 93fb765b5bac9ec6883a33d311a6a8949c789740 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 May 2025 18:14:23 +0000 Subject: [PATCH 364/442] Bump thirdai from 0.9.31 to 0.9.32 Bumps thirdai from 0.9.31 to 0.9.32. --- updated-dependencies: - dependency-name: thirdai dependency-version: 0.9.32 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 4bac3e42f37..61df0c469eb 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -57,7 +57,7 @@ pytesseract==0.3.13 requests-mock==1.12.1 pyglet==2.1.6 urllib3==2.4.0 -thirdai==0.9.31 +thirdai==0.9.32 google-api-python-client==2.169.0 sound==0.1.0 xlwt==1.3.0 From 9ed1c4b213c3dfd13b1f9f7cd4632bc83d7caedd Mon Sep 17 00:00:00 2001 From: Abhilash Date: Tue, 13 May 2025 16:56:50 +0530 Subject: [PATCH 365/442] added a simple palindrome python script --- string_palin.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 string_palin.py diff --git a/string_palin.py b/string_palin.py new file mode 100644 index 00000000000..1349f993c4c --- /dev/null +++ b/string_palin.py @@ -0,0 +1,20 @@ +# + +# With slicing -> Reverses the string using string[::-1] + + +string= input("enter a word to check.. ") +copy=string[::-1] +if string == copy: + print("Plaindrome") +else: + print("!") + +# Without slicing –> Reverses the string manually using a loop +reverse_string="" +for i in string: + reverse_string=i+reverse_string +if string == reverse_string: + print(reverse_string) +else: + print("!") \ No newline at end of file From 3de6f3710578001142b05e6d50e89849bb52ce9b Mon Sep 17 00:00:00 2001 From: Abhilash Date: Wed, 14 May 2025 18:36:04 +0530 Subject: [PATCH 366/442] Added simple kilometers to miles python script --- kilo_to_miles.py | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 kilo_to_miles.py diff --git a/kilo_to_miles.py b/kilo_to_miles.py new file mode 100644 index 00000000000..3d885dbf5aa --- /dev/null +++ b/kilo_to_miles.py @@ -0,0 +1,5 @@ +user= float(input("enter kilometers here.. ")) +miles= user*0.621371 +print(f"{user} kilometers equals to {miles:.2f}") + +0.621371 \ No newline at end of file From ffce8a10727693e4bf2f1841fd0a28968c4a4d38 Mon Sep 17 00:00:00 2001 From: "L. Abhilash" <160405976+LAbhilashKumar@users.noreply.github.com> Date: Wed, 14 May 2025 18:40:18 +0530 Subject: [PATCH 367/442] Update kilo_to_miles.py --- kilo_to_miles.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kilo_to_miles.py b/kilo_to_miles.py index 3d885dbf5aa..ff33cd208c5 100644 --- a/kilo_to_miles.py +++ b/kilo_to_miles.py @@ -1,5 +1,4 @@ user= float(input("enter kilometers here.. ")) miles= user*0.621371 -print(f"{user} kilometers equals to {miles:.2f}") +print(f"{user} kilometers equals to {miles:.2f} miles") -0.621371 \ No newline at end of file From dba18c9b2060460f6450cc64737a2ee3ba2f6a4f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 May 2025 18:19:33 +0000 Subject: [PATCH 368/442] Bump thirdai from 0.9.32 to 0.9.33 Bumps thirdai from 0.9.32 to 0.9.33. --- updated-dependencies: - dependency-name: thirdai dependency-version: 0.9.33 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index d018f75228c..c98aaef5cb9 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -57,7 +57,7 @@ pytesseract==0.3.13 requests-mock==1.12.1 pyglet==2.1.6 urllib3==2.4.0 -thirdai==0.9.32 +thirdai==0.9.33 google-api-python-client==2.169.0 sound==0.1.0 xlwt==1.3.0 From ef7b952e54652f1e063480e6c27aeef63fd89116 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 May 2025 18:19:42 +0000 Subject: [PATCH 369/442] Bump twilio from 9.6.0 to 9.6.1 Bumps [twilio](https://github.com/twilio/twilio-python) from 9.6.0 to 9.6.1. - [Release notes](https://github.com/twilio/twilio-python/releases) - [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md) - [Commits](https://github.com/twilio/twilio-python/compare/9.6.0...9.6.1) --- updated-dependencies: - dependency-name: twilio dependency-version: 9.6.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index d018f75228c..e47975d53dd 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -28,7 +28,7 @@ requests==2.32.3 quo==2023.5.1 PyPDF2==3.0.1 pyserial==3.5 -twilio==9.6.0 +twilio==9.6.1 tabula==1.0.5 nltk==3.9.1 Pillow==11.2.1 From 68e29def317d0e21ddf3427b7317048fbd5a89c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 May 2025 18:19:52 +0000 Subject: [PATCH 370/442] Bump flask from 3.1.0 to 3.1.1 Bumps [flask](https://github.com/pallets/flask) from 3.1.0 to 3.1.1. - [Release notes](https://github.com/pallets/flask/releases) - [Changelog](https://github.com/pallets/flask/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/flask/compare/3.1.0...3.1.1) --- updated-dependencies: - dependency-name: flask dependency-version: 3.1.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index d018f75228c..680d64136af 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -20,7 +20,7 @@ fileinfo==0.3.3 backend==0.2.4.1 win10toast==0.9 Counter==1.0.0 -Flask==3.1.0 +Flask==3.1.1 selenium==4.32.0 firebase-admin==6.8.0 ujson==5.10.0 From 0e6596d5cbdcaf18751da78e195bc014c8de02b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 May 2025 18:08:33 +0000 Subject: [PATCH 371/442] Bump ccxt from 4.4.78 to 4.4.82 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.4.78 to 4.4.82. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/v4.4.78...v4.4.82) --- updated-dependencies: - dependency-name: ccxt dependency-version: 4.4.82 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 587123c136d..b33ba6f6c6e 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.4.0 Ball==0.2.9 pynput==1.8.1 gTTS==2.5.4 -ccxt==4.4.78 +ccxt==4.4.82 fitz==0.0.1.dev2 fastapi==0.115.12 Django==5.1.7 From 7ff9fee48aeabe4a94a501f0131b9ffe8c84db8b Mon Sep 17 00:00:00 2001 From: Abhilash Date: Mon, 19 May 2025 19:30:24 +0530 Subject: [PATCH 372/442] Added a simple Task manager with basic GUI --- Todo_GUi.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 Todo_GUi.py diff --git a/Todo_GUi.py b/Todo_GUi.py new file mode 100644 index 00000000000..21dafef44e3 --- /dev/null +++ b/Todo_GUi.py @@ -0,0 +1,48 @@ +from tkinter import messagebox +import tkinter as tk + +# Function to be called when button is clicked +def add_Button(): + task=Input.get() + if task: + List.insert(tk.END,task) + Input.delete(0,tk.END) + + + +def del_Button(): + try: + task=List.curselection()[0] + List.delete(task) + except IndexError: + messagebox.showwarning("Selection Error", "Please select a task to delete.") + + + +# Create the main window +window = tk.Tk() +window.title("Task Manager") +window.geometry("500x500") +window.resizable(False,False) +window.config(bg="light grey") + +# text filed +Input=tk.Entry(window,width=50) +Input.grid(row=0,column=0,padx=20,pady=60) +Input.focus() + +# Create the button +add =tk.Button(window, text="ADD TASK", height=2, width=9, command=add_Button) +add.grid(row=0, column=1, padx=20, pady=0) + +delete=tk.Button(window,text="DELETE TASK", height=2,width=10,command=del_Button) +delete.grid(row=1,column=1) + +# creating list box +List=tk.Listbox(window,width=50,height=20) +List.grid(row=1,column=0) + + + + +window.mainloop() \ No newline at end of file From 6086527fe067a6b6c5fbdc3b84e08680fa4f45ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 May 2025 18:44:32 +0000 Subject: [PATCH 373/442] Bump openai from 1.78.1 to 1.79.0 Bumps [openai](https://github.com/openai/openai-python) from 1.78.1 to 1.79.0. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.78.1...v1.79.0) --- updated-dependencies: - dependency-name: openai dependency-version: 1.79.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index b33ba6f6c6e..9c019b450cf 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.78.1 +openai==1.79.0 background==0.2.1 pydantic==2.11.4 openpyxl==3.1.2 From 5a070f041b792d74053e4cb10502470a187cab57 Mon Sep 17 00:00:00 2001 From: Abhilash Date: Tue, 20 May 2025 19:25:36 +0530 Subject: [PATCH 374/442] Added a simple calculator python script --- basic_cal.py | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 basic_cal.py diff --git a/basic_cal.py b/basic_cal.py new file mode 100644 index 00000000000..6629ad178db --- /dev/null +++ b/basic_cal.py @@ -0,0 +1,8 @@ +while True: + try: + print(eval(input("enter digits with operator (e.g. 5+5)\n"))) + except: + print("Invalid Input, try again..") + +# Simple Calculator using eval() in Python +# This calculator takes user input like "5+5" or "10/2" and shows the result. \ No newline at end of file From 165f5874229aaf8816e45740eff9bab06886cfce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 May 2025 18:57:05 +0000 Subject: [PATCH 375/442] Bump keras from 3.9.2 to 3.10.0 Bumps [keras](https://github.com/keras-team/keras) from 3.9.2 to 3.10.0. - [Release notes](https://github.com/keras-team/keras/releases) - [Commits](https://github.com/keras-team/keras/compare/v3.9.2...v3.10.0) --- updated-dependencies: - dependency-name: keras dependency-version: 3.10.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 9c019b450cf..7e773faed9c 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -41,7 +41,7 @@ tornado==6.4.2 obs==0.0.0 todo==0.1 oauth2client==4.1.3 -keras==3.9.2 +keras==3.10.0 pymongo==4.12.1 playsound==1.3.0 pyttsx3==2.98 From 7a40cc62e2989a1347c64a4dc51b268c938c4c5e Mon Sep 17 00:00:00 2001 From: Abhilash Date: Wed, 21 May 2025 19:50:29 +0530 Subject: [PATCH 376/442] Added a simple python script to display system information --- Pc_information.py | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 Pc_information.py diff --git a/Pc_information.py b/Pc_information.py new file mode 100644 index 00000000000..3117d78bdfa --- /dev/null +++ b/Pc_information.py @@ -0,0 +1,11 @@ +import platform # built in lib + +print(f"System : {platform.system()}") # Prints type of Operating System +print(f"System name : {platform.node()}") # Prints System Name +print(f"version : {platform.release()}") # Prints System Version +# TO get the detailed version number +print(f"detailed version number : {platform.version()}") # Prints detailed version number +print(f"System architecture : {platform.machine()}") # Prints whether the system is 32-bit ot 64-bit +print(f"System processor : {platform.processor()}") # Prints CPU model + + From 6a43bbaad2cfc00dd0323f27906c5ed24d03a49a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 May 2025 18:51:47 +0000 Subject: [PATCH 377/442] Bump openai from 1.79.0 to 1.81.0 Bumps [openai](https://github.com/openai/openai-python) from 1.79.0 to 1.81.0. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.79.0...v1.81.0) --- updated-dependencies: - dependency-name: openai dependency-version: 1.81.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 9c019b450cf..3e4561e3eb7 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.79.0 +openai==1.81.0 background==0.2.1 pydantic==2.11.4 openpyxl==3.1.2 From 901457ef34ba90b7931498416710aa559fb1536c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 May 2025 18:21:46 +0000 Subject: [PATCH 378/442] Bump ccxt from 4.4.82 to 4.4.85 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.4.82 to 4.4.85. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/v4.4.82...v4.4.85) --- updated-dependencies: - dependency-name: ccxt dependency-version: 4.4.85 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 5e57ec2b961..4812ca27c0e 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.4.0 Ball==0.2.9 pynput==1.8.1 gTTS==2.5.4 -ccxt==4.4.82 +ccxt==4.4.85 fitz==0.0.1.dev2 fastapi==0.115.12 Django==5.1.7 From 8387d425bf45713e796430574192616fb3e9447c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 May 2025 18:21:55 +0000 Subject: [PATCH 379/442] Bump tornado from 6.4.2 to 6.5.1 Bumps [tornado](https://github.com/tornadoweb/tornado) from 6.4.2 to 6.5.1. - [Changelog](https://github.com/tornadoweb/tornado/blob/master/docs/releases.rst) - [Commits](https://github.com/tornadoweb/tornado/compare/v6.4.2...v6.5.1) --- updated-dependencies: - dependency-name: tornado dependency-version: 6.5.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 5e57ec2b961..c0730dc34cd 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -37,7 +37,7 @@ xlrd==2.0.1 fpdf==1.7.2 mysql-connector-repackaged==0.3.1 word2number==1.1 -tornado==6.4.2 +tornado==6.5.1 obs==0.0.0 todo==0.1 oauth2client==4.1.3 From 8b991d47aad3a585521b810cda02661d2a979bb0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 May 2025 18:38:33 +0000 Subject: [PATCH 380/442] Bump google-api-python-client from 2.169.0 to 2.170.0 Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.169.0 to 2.170.0. - [Release notes](https://github.com/googleapis/google-api-python-client/releases) - [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.169.0...v2.170.0) --- updated-dependencies: - dependency-name: google-api-python-client dependency-version: 2.170.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index eeb395d0d4d..6bfbea2d22c 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -58,7 +58,7 @@ requests-mock==1.12.1 pyglet==2.1.6 urllib3==2.4.0 thirdai==0.9.33 -google-api-python-client==2.169.0 +google-api-python-client==2.170.0 sound==0.1.0 xlwt==1.3.0 pygame==2.6.1 From dbc116997c70118c2d23f263884f56b71560c8a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 May 2025 18:07:12 +0000 Subject: [PATCH 381/442] Bump openai from 1.81.0 to 1.82.1 Bumps [openai](https://github.com/openai/openai-python) from 1.81.0 to 1.82.1. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.81.0...v1.82.1) --- updated-dependencies: - dependency-name: openai dependency-version: 1.82.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index eeb395d0d4d..732ae0c9730 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.81.0 +openai==1.82.1 background==0.2.1 pydantic==2.11.4 openpyxl==3.1.2 From 1b2dae5f0e5745a7894df31320f0d72fce60bbf9 Mon Sep 17 00:00:00 2001 From: Pratyanj <109451378+pratyanj@users.noreply.github.com> Date: Fri, 30 May 2025 09:58:16 +0530 Subject: [PATCH 382/442] QT design softer file --- bank_managment_system/untitled.ui | 862 ++++++++++++++++++++++++++++++ 1 file changed, 862 insertions(+) create mode 100644 bank_managment_system/untitled.ui diff --git a/bank_managment_system/untitled.ui b/bank_managment_system/untitled.ui new file mode 100644 index 00000000000..12c130fb4e7 --- /dev/null +++ b/bank_managment_system/untitled.ui @@ -0,0 +1,862 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + background-color: #f0f2f5; +QPushButton { + background-color: #3498db; + color: white; + font-family: 'Segoe UI'; + font-size: 16px; + font-weight: bold; + border-radius: 8px; + padding: 12px; + border: none; + } + QPushButton:hover { + background-color: #2980b9; + } + QPushButton:pressed { + background-color: #1c6ea4; + } + + + + + + + 2 + + + + + + + + background-color: #ffffff; + border-radius: 10px; + padding: 10px; + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 30 + + + + + color: #2c3e50; + padding: 10px; + + + + Bank Management system + + + + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 300 + 0 + + + + + 16 + + + + + + background-color: #ffffff; + border-radius: 15px; + padding: 20px; + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + QPushButton { + background-color: #3498db; + color: white; + font-family: 'Segoe UI'; + font-size: 16px; + font-weight: bold; + border-radius: 8px; + padding: 12px; + border: none; + } + QPushButton:hover { + background-color: #2980b9; + } + QPushButton:pressed { + background-color: #1c6ea4; + } + + + Admin + + + + + + + QPushButton { + background-color: #3498db; + color: white; + font-family: 'Segoe UI'; + font-size: 16px; + font-weight: bold; + border-radius: 8px; + padding: 12px; + border: none; + } + QPushButton:hover { + background-color: #2980b9; + } + QPushButton:pressed { + background-color: #1c6ea4; + } + + + Employee + + + + + + + QPushButton { + background-color: #3498db; + color: white; + font-family: 'Segoe UI'; + font-size: 16px; + font-weight: bold; + border-radius: 8px; + padding: 12px; + border: none; + } + QPushButton:hover { + background-color: #2980b9; + } + QPushButton:pressed { + background-color: #1c6ea4; + } + + + Exit + + + + + + + + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 340 + 210 + 261 + 231 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 20 + 20 + 75 + 23 + + + + PushButton + + + + + + + + + + + + + + background-color: #ffffff; + border-radius: 10px; + padding: 10px; + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 30 + + + + + color: #2c3e50; + padding: 10px; + + + + Employee Login + + + + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 340 + 200 + + + + + 16 + + + + + + background-color: #ffffff; + border-radius: 15px; + padding: 10px; + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + padding:7 + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 120 + 0 + + + + + 12 + 75 + true + + + + + color: #2c3e50; + + + + Name : + + + + + + + background-color: rgb(168, 168, 168); + + + + + + + + + + + + + padding:7 + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 120 + 0 + + + + + 12 + 75 + true + + + + + color: #2c3e50; + + + + Password : + + + + + + + background-color: rgb(168, 168, 168); + + + + + + + + + + + + + padding:7 + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 60 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 150 + 0 + + + + QPushButton { + background-color: #3498db; + color: white; + font-family: 'Segoe UI'; + font-size: 16px; + font-weight: bold; + border-radius: 8px; + padding: 12px; + border: none; + } + QPushButton:hover { + background-color: #2980b9; + } + QPushButton:pressed { + background-color: #1c6ea4; + } + + + Submit + + + + + + + + + + + + + + + + + + + + + background-color: #ffffff; + border-radius: 10px; + padding: 10px; + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 30 + + + + + color: #2c3e50; + padding: 10px; + + + + Admin Login + + + + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 340 + 200 + + + + + 16 + + + + + + background-color: #ffffff; + border-radius: 15px; + padding: 10px; + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + padding:7 + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 120 + 0 + + + + + 12 + 75 + true + + + + + color: #2c3e50; + + + + Name : + + + + + + + background-color: rgb(168, 168, 168); + + + + + + + + + + + + + padding:7 + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 120 + 0 + + + + + 12 + 75 + true + + + + + color: #2c3e50; + + + + Password : + + + + + + + background-color: rgb(168, 168, 168); + + + + + + + + + + + + + padding:7 + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 60 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 150 + 0 + + + + QPushButton { + background-color: #3498db; + color: white; + font-family: 'Segoe UI'; + font-size: 16px; + font-weight: bold; + border-radius: 8px; + padding: 12px; + border: none; + } + QPushButton:hover { + background-color: #2980b9; + } + QPushButton:pressed { + background-color: #1c6ea4; + } + + + Submit + + + + + + + + + + + + + + + + + + + + + + From 45cac8ba7a37d42b1f385985fc92d35fd28a3f4d Mon Sep 17 00:00:00 2001 From: Pratyanj <109451378+pratyanj@users.noreply.github.com> Date: Fri, 30 May 2025 09:58:47 +0530 Subject: [PATCH 383/442] Custom new Qt lib base forntend started --- bank_managment_system/QTFrontend.py | 271 ++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 bank_managment_system/QTFrontend.py diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py new file mode 100644 index 00000000000..97485ce791d --- /dev/null +++ b/bank_managment_system/QTFrontend.py @@ -0,0 +1,271 @@ + +from PyQt5 import QtCore, QtGui, QtWidgets +import sys +import backend + +def create_styled_frame(parent, min_size=None, style=""): + """Create a styled QFrame with optional minimum size and custom style.""" + frame = QtWidgets.QFrame(parent) + frame.setFrameShape(QtWidgets.QFrame.StyledPanel) + frame.setFrameShadow(QtWidgets.QFrame.Raised) + if min_size: + frame.setMinimumSize(QtCore.QSize(*min_size)) + frame.setStyleSheet(style) + return frame + +def create_styled_label(parent, text, font_size=12, bold=False, style="color: #2c3e50; padding: 10px;"): + """Create a styled QLabel with customizable font size and boldness.""" + label = QtWidgets.QLabel(parent) + font = QtGui.QFont("Segoe UI", font_size) + if bold: + font.setBold(True) + font.setWeight(75) + label.setFont(font) + label.setStyleSheet(style) + label.setText(text) + return label + +def create_styled_button(parent, text, min_size=None): + """Create a styled QPushButton with hover and pressed effects.""" + button = QtWidgets.QPushButton(parent) + if min_size: + button.setMinimumSize(QtCore.QSize(*min_size)) + button.setStyleSheet(""" + QPushButton { + background-color: #3498db; + color: white; + font-family: 'Segoe UI'; + font-size: 16px; + font-weight: bold; + border-radius: 8px; + padding: 12px; + border: none; + } + QPushButton:hover { + background-color: #2980b9; + } + QPushButton:pressed { + background-color: #1c6ea4; + } + """) + button.setText(text) + return button + +def create_input_field(parent, label_text, min_label_size=(120, 0)): + """Create a horizontal layout with a label and a QLineEdit.""" + frame = create_styled_frame(parent, style="padding: 7px;") + layout = QtWidgets.QHBoxLayout(frame) + layout.setContentsMargins(0, 0, 0, 0) + layout.setSpacing(0) + + label = create_styled_label(frame, label_text, font_size=12, bold=True, style="color: #2c3e50;") + if min_label_size: + label.setMinimumSize(QtCore.QSize(*min_label_size)) + + line_edit = QtWidgets.QLineEdit(frame) + line_edit.setStyleSheet("background-color: rgb(168, 168, 168);") + + layout.addWidget(label) + layout.addWidget(line_edit) + return frame, line_edit + +def create_login_page(parent ,title, name_field_text="Name :", password_field_text="Password :", submit_text="Submit",): + """Create a login page with a title, name and password fields, and a submit button.""" + page = QtWidgets.QWidget(parent) + main_layout = QtWidgets.QVBoxLayout(page) + + # Header frame with title + header_frame = create_styled_frame(page, style="background-color: #ffffff; border-radius: 10px; padding: 10px;") + header_layout = QtWidgets.QVBoxLayout(header_frame) + title_label = create_styled_label(header_frame, title, font_size=30) + header_layout.addWidget(title_label, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop) + main_layout.addWidget(header_frame, 0, QtCore.Qt.AlignTop) + + # Content frame + content_frame = create_styled_frame(page) + content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_layout = QtWidgets.QVBoxLayout(content_frame) + + # Form frame + form_frame = create_styled_frame(content_frame, min_size=(340, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") + form_layout = QtWidgets.QVBoxLayout(form_frame) + form_layout.setSpacing(20) + + # Input fields + name_frame, name_edit = create_input_field(form_frame, name_field_text) + password_frame, password_edit = create_input_field(form_frame, password_field_text) + + # Submit button + button_frame = create_styled_frame(form_frame, style="padding: 7px;") + button_layout = QtWidgets.QVBoxLayout(button_frame) + button_layout.setSpacing(60) + submit_button = create_styled_button(button_frame, submit_text, min_size=(150, 0)) + button_layout.addWidget(submit_button, 0, QtCore.Qt.AlignHCenter) + + form_layout.addWidget(name_frame) + form_layout.addWidget(password_frame) + form_layout.addWidget(button_frame) + + content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + main_layout.addWidget(content_frame) + + submit_button.clicked.connect(lambda: on_login_button_clicked(parent,name_edit, password_edit)) + + return page, name_edit, password_edit, submit_button +def on_login_button_clicked(parent,name_field, password_field): + # Get the entered name and password + name = name_field.text() + password = password_field.text() + # Check if the entered name and password are correct + if name == "" and password == "": + # Show a message box with the entered name and password + Dialog = QtWidgets.QDialog() + Dialog.setObjectName("Dialog") + Dialog.resize(317, 60) + verticalLayout = QtWidgets.QVBoxLayout(Dialog) + verticalLayout.setObjectName("verticalLayout") + label = QtWidgets.QLabel(Dialog) + label.setObjectName("label") + label.setText("Please enter both name and password") + verticalLayout.addWidget(label, 0, QtCore.Qt.AlignTop) + buttonBox = QtWidgets.QDialogButtonBox(Dialog) + buttonBox.setOrientation(QtCore.Qt.Horizontal) + buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) + buttonBox.setObjectName("buttonBox") + verticalLayout.addWidget(buttonBox) + + buttonBox.accepted.connect(Dialog.accept) # type: ignore + buttonBox.rejected.connect(lambda:rejectBTN())# type: ignore + QtCore.QMetaObject.connectSlotsByName(Dialog) + def rejectBTN(): + parent.setCurrentIndex(0) + Dialog.reject() + # Show the dialog + Dialog.exec_() + else: + print(f"Name: {name}, Password: {password}") + +def create_home_page(parent, on_admin_clicked, on_employee_clicked, on_exit_clicked): + """Create the home page with Admin, Employee, and Exit buttons.""" + page = QtWidgets.QWidget(parent) + main_layout = QtWidgets.QVBoxLayout(page) + main_layout.setContentsMargins(20, 20, 20, 20) + main_layout.setSpacing(20) + + # Header frame with title + header_frame = create_styled_frame(page, style="background-color: #ffffff; border-radius: 10px; padding: 10px;") + header_layout = QtWidgets.QVBoxLayout(header_frame) + title_label = create_styled_label(header_frame, "Bank Management System", font_size=30) + header_layout.addWidget(title_label, 0, QtCore.Qt.AlignHCenter) + main_layout.addWidget(header_frame, 0, QtCore.Qt.AlignTop) + + # Button frame + button_frame = create_styled_frame(page) + button_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + button_layout = QtWidgets.QVBoxLayout(button_frame) + + # Button container + button_container = create_styled_frame(button_frame, min_size=(300, 0), style="background-color: #ffffff; border-radius: 15px; padding: 20px;") + button_container_layout = QtWidgets.QVBoxLayout(button_container) + button_container_layout.setSpacing(15) + + # Buttons + admin_button = create_styled_button(button_container, "Admin") + employee_button = create_styled_button(button_container, "Employee") + exit_button = create_styled_button(button_container, "Exit") + exit_button.setStyleSheet(""" + QPushButton { + background-color: #e74c3c; + color: white; + font-family: 'Segoe UI'; + font-size: 16px; + font-weight: bold; + border-radius: 8px; + padding: 12px; + border: none; + } + QPushButton:hover { + background-color: #c0392b; + } + QPushButton:pressed { + background-color: #992d22; + } + """) + + button_container_layout.addWidget(admin_button) + button_container_layout.addWidget(employee_button) + button_container_layout.addWidget(exit_button) + + button_layout.addWidget(button_container, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + main_layout.addWidget(button_frame) + + # Connect button signals + admin_button.clicked.connect(on_admin_clicked) + employee_button.clicked.connect(on_employee_clicked) + exit_button.clicked.connect(on_exit_clicked) + + return page + +def setup_main_window(main_window): + """Set up the main window with a stacked widget containing home, admin, and employee pages.""" + main_window.setObjectName("MainWindow") + main_window.resize(800, 600) + main_window.setStyleSheet("background-color: #f0f2f5;") + + central_widget = QtWidgets.QWidget(main_window) + main_layout = QtWidgets.QHBoxLayout(central_widget) + + stacked_widget = QtWidgets.QStackedWidget(central_widget) + + # Create pages + def switch_to_admin(): + stacked_widget.setCurrentIndex(1) + + def switch_to_employee(): + stacked_widget.setCurrentIndex(2) + + def exit_app(): + QtWidgets.QApplication.quit() + + home_page = create_home_page(stacked_widget, switch_to_admin, switch_to_employee, exit_app) + admin_page, admin_name, admin_password, admin_submit = create_login_page(stacked_widget, "Admin Login") + result = backend.check_admin(admin_name, admin_password) + + employee_page, employee_name, employee_password, employee_submit = create_login_page(stacked_widget, "Employee Login") + + + # Add pages to stacked widget + stacked_widget.addWidget(home_page) + stacked_widget.addWidget(admin_page) + stacked_widget.addWidget(employee_page) + + main_layout.addWidget(stacked_widget) + main_window.setCentralWidget(central_widget) + + # Set initial page + stacked_widget.setCurrentIndex(0) + + return stacked_widget, { + "admin_name": admin_name, + "admin_password": admin_password, + "admin_submit": admin_submit, + "employee_name": employee_name, + "employee_password": employee_password, + "employee_submit": employee_submit + } + +def main(): + """Main function to launch the application.""" + app = QtWidgets.QApplication(sys.argv) + main_window = QtWidgets.QMainWindow() + stacked_widget, widgets = setup_main_window(main_window) + + # Example: Connect submit buttons to print input values + + + main_window.show() + sys.exit(app.exec_()) + +if __name__ == "__main__": + main() + From 2820a5400f62a5d19afd60394d66b3b9f14c96c9 Mon Sep 17 00:00:00 2001 From: Pratyanj <109451378+pratyanj@users.noreply.github.com> Date: Fri, 30 May 2025 10:46:08 +0530 Subject: [PATCH 384/442] add admin menu page --- bank_managment_system/QTFrontend.py | 61 +++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 97485ce791d..c6d67e5ccde 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -2,7 +2,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets import sys import backend - +backend.connect_database() def create_styled_frame(parent, min_size=None, style=""): """Create a styled QFrame with optional minimum size and custom style.""" frame = QtWidgets.QFrame(parent) @@ -206,6 +206,50 @@ def create_home_page(parent, on_admin_clicked, on_employee_clicked, on_exit_clic return page +def create_admin_menu_page(perent): + """Create the admin menu page with buttons for adding, deleting, and viewing accounts.""" + page = QtWidgets.QWidget(perent) + main_layout = QtWidgets.QVBoxLayout(page) + main_layout.setContentsMargins(20, 20, 20, 20) + main_layout.setSpacing(20) + + # Header frame with title + header_frame = create_styled_frame(page, style="background-color: #ffffff; border-radius: 10px; padding: 10px;") + header_layout = QtWidgets.QVBoxLayout(header_frame) + title_label = create_styled_label(header_frame, "Admin Menu", font_size=30) + header_layout.addWidget(title_label, 0, QtCore.Qt.AlignHCenter) + main_layout.addWidget(header_frame, 0, QtCore.Qt.AlignTop) + + # Button frame + button_frame = create_styled_frame(page) + button_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + button_layout = QtWidgets.QVBoxLayout(button_frame) + # Button container + button_container = create_styled_frame(button_frame, min_size=(300, 0), style="background-color: #ffffff; border-radius: 15px; padding: 20px;") + button_container_layout = QtWidgets.QVBoxLayout(button_container) + button_container_layout.setSpacing(15) + # Buttons + add_button = create_styled_button(button_container, "Add Employee") + update_employee = create_styled_button(button_container, "Update Employee") + employee_list = create_styled_button(button_container, "Employee List") + total_money = create_styled_button(button_container, "Total Money") + back_to_home = create_styled_button(button_container, "Back") + button_container_layout.addWidget(add_button) + button_container_layout.addWidget(update_employee) + button_container_layout.addWidget(employee_list) + button_container_layout.addWidget(total_money) + button_container_layout.addWidget(back_to_home) + button_layout.addWidget(button_container, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + main_layout.addWidget(button_frame) + # Connect button signals + # add_button.clicked.connect(on_add_employee_clicked) + # update_employee.clicked.connect(on_update_employee_clicked) + # employee_list.clicked.connect(on_employee_list_clicked) + # total_money.clicked.connect(on_total_money_clicked) + # back_to_home.clicked.connect(on_back_to_home_clicked) + return page + + def setup_main_window(main_window): """Set up the main window with a stacked widget containing home, admin, and employee pages.""" main_window.setObjectName("MainWindow") @@ -226,10 +270,20 @@ def switch_to_employee(): def exit_app(): QtWidgets.QApplication.quit() - + + def admin_login_menu_page(name, password): + result = backend.check_admin(name, password) + if result: + stacked_widget.setCurrentIndex(3) + else: + print("Invalid admin credentials") + home_page = create_home_page(stacked_widget, switch_to_admin, switch_to_employee, exit_app) admin_page, admin_name, admin_password, admin_submit = create_login_page(stacked_widget, "Admin Login") - result = backend.check_admin(admin_name, admin_password) + admin_submit.clicked.connect( + lambda: admin_login_menu_page(admin_name.text(), admin_password.text()) + ) + admin_menu_page = create_admin_menu_page(stacked_widget) employee_page, employee_name, employee_password, employee_submit = create_login_page(stacked_widget, "Employee Login") @@ -238,6 +292,7 @@ def exit_app(): stacked_widget.addWidget(home_page) stacked_widget.addWidget(admin_page) stacked_widget.addWidget(employee_page) + stacked_widget.addWidget(admin_menu_page) main_layout.addWidget(stacked_widget) main_window.setCentralWidget(central_widget) From 068c3f28a84c6bf1352503af52e5eb2ddcffdb59 Mon Sep 17 00:00:00 2001 From: Pratyanj <109451378+pratyanj@users.noreply.github.com> Date: Fri, 30 May 2025 12:10:46 +0530 Subject: [PATCH 385/442] change admin name and psw --- bank_managment_system/backend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bank_managment_system/backend.py b/bank_managment_system/backend.py index 62f9c2b36b8..c60dae4c4e4 100644 --- a/bank_managment_system/backend.py +++ b/bank_managment_system/backend.py @@ -35,7 +35,7 @@ def connect_database(): # Only insert admin if not exists cur.execute("SELECT COUNT(*) FROM admin") if cur.fetchone()[0] == 0: - cur.execute("INSERT INTO admin VALUES (?, ?)", ('arpit', '123')) + cur.execute("INSERT INTO admin VALUES (?, ?)", ('admin', 'admin123')) conn.commit() From 20be99f14349f8254ef62e8af2f3266577376f48 Mon Sep 17 00:00:00 2001 From: Pratyanj <109451378+pratyanj@users.noreply.github.com> Date: Fri, 30 May 2025 16:06:49 +0530 Subject: [PATCH 386/442] add pop msg notification --- bank_managment_system/QTFrontend.py | 84 +++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index c6d67e5ccde..4d8c0b63508 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -68,7 +68,91 @@ def create_input_field(parent, label_text, min_label_size=(120, 0)): layout.addWidget(label) layout.addWidget(line_edit) return frame, line_edit +def pop_up_message(parent, message: str, page: int): + """Create a popup message box with a given message.""" + dialog = QtWidgets.QDialog(parent) + dialog.setWindowTitle("Message") + dialog.setFixedSize(350, 100) + dialog.setStyleSheet("background-color: #f0f0f0;") + + layout = QtWidgets.QVBoxLayout(dialog) + layout.setSpacing(10) + layout.setContentsMargins(15, 15, 15, 15) + + label = QtWidgets.QLabel(message) + label.setStyleSheet("font-size: 12px; color: #2c3e50;") + label.setWordWrap(True) + layout.addWidget(label) + + button_box = QtWidgets.QDialogButtonBox( + QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel + ) + button_box.setStyleSheet(""" + QPushButton { + background-color: #3498db; + color: white; + border-radius: 4px; + padding: 6px 12px; + min-width: 80px; + } + QPushButton:hover { + background-color: #2980b9; + } + QPushButton:pressed { + background-color: #1c6ea4; + } + """) + layout.addWidget(button_box) + + button_box.accepted.connect(dialog.accept) + button_box.rejected.connect(lambda: reject_clicked(dialog, parent, page)) + + dialog.exec_() +def reject_clicked(dialog, parent, page): + parent.setCurrentIndex(page) + dialog.reject() + +def pop_up_message_with_only_ok(parent, message: str, page: int): + """Create a popup message box with only an OK button.""" + dialog = QtWidgets.QDialog(parent) + dialog.setWindowTitle("Message") + dialog.setFixedSize(350, 100) + dialog.setStyleSheet("background-color: #f0f0f0;") + + layout = QtWidgets.QVBoxLayout(dialog) + layout.setSpacing(10) + layout.setContentsMargins(15, 15, 15, 15) + + label = QtWidgets.QLabel(message) + label.setStyleSheet("font-size: 12px; color: #2c3e50;") + label.setWordWrap(True) + layout.addWidget(label) + + button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok) + button_box.setStyleSheet(""" + QPushButton { + background-color: #3498db; + color: white; + border-radius: 4px; + padding: 6px 12px; + min-width: 80px; + } + QPushButton:hover { + background-color: #2980b9; + } + QPushButton:pressed { + background-color: #1c6ea4; + } + """) + layout.addWidget(button_box) + + button_box.accepted.connect(lambda: accepted_clicked()) + def accepted_clicked(): + parent.setCurrentIndex(page) + dialog.close() + + dialog.exec_() def create_login_page(parent ,title, name_field_text="Name :", password_field_text="Password :", submit_text="Submit",): """Create a login page with a title, name and password fields, and a submit button.""" page = QtWidgets.QWidget(parent) From 06281a03a790be89287627febff79a2b312a1f3b Mon Sep 17 00:00:00 2001 From: Pratyanj <109451378+pratyanj@users.noreply.github.com> Date: Fri, 30 May 2025 16:07:15 +0530 Subject: [PATCH 387/442] add employe page done --- bank_managment_system/QTFrontend.py | 107 +++++++++++++++++++--------- 1 file changed, 75 insertions(+), 32 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 4d8c0b63508..38ff99ce869 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -203,29 +203,7 @@ def on_login_button_clicked(parent,name_field, password_field): # Check if the entered name and password are correct if name == "" and password == "": # Show a message box with the entered name and password - Dialog = QtWidgets.QDialog() - Dialog.setObjectName("Dialog") - Dialog.resize(317, 60) - verticalLayout = QtWidgets.QVBoxLayout(Dialog) - verticalLayout.setObjectName("verticalLayout") - label = QtWidgets.QLabel(Dialog) - label.setObjectName("label") - label.setText("Please enter both name and password") - verticalLayout.addWidget(label, 0, QtCore.Qt.AlignTop) - buttonBox = QtWidgets.QDialogButtonBox(Dialog) - buttonBox.setOrientation(QtCore.Qt.Horizontal) - buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) - buttonBox.setObjectName("buttonBox") - verticalLayout.addWidget(buttonBox) - - buttonBox.accepted.connect(Dialog.accept) # type: ignore - buttonBox.rejected.connect(lambda:rejectBTN())# type: ignore - QtCore.QMetaObject.connectSlotsByName(Dialog) - def rejectBTN(): - parent.setCurrentIndex(0) - Dialog.reject() - # Show the dialog - Dialog.exec_() + pop_up_message(parent, "Please enter your name and password.",0) else: print(f"Name: {name}, Password: {password}") @@ -331,9 +309,53 @@ def create_admin_menu_page(perent): # employee_list.clicked.connect(on_employee_list_clicked) # total_money.clicked.connect(on_total_money_clicked) # back_to_home.clicked.connect(on_back_to_home_clicked) - return page + return page,add_button,update_employee,employee_list,total_money,back_to_home - +def create_add_employe_page(parent ,title, name_field_text="Name :", password_field_text="Password :",position_fielld_text="Position :",salary_field_text="Salary :",submit_text="Submit",): + """Create a login page with a title, name and password fields, and a submit button.""" + page = QtWidgets.QWidget(parent) + main_layout = QtWidgets.QVBoxLayout(page) + + # Header frame with title + header_frame = create_styled_frame(page, style="background-color: #ffffff; border-radius: 10px; padding: 10px;") + header_layout = QtWidgets.QVBoxLayout(header_frame) + title_label = create_styled_label(header_frame, title, font_size=30) + header_layout.addWidget(title_label, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop) + main_layout.addWidget(header_frame, 0, QtCore.Qt.AlignTop) + + # Content frame + content_frame = create_styled_frame(page) + content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_layout = QtWidgets.QVBoxLayout(content_frame) + + # Form frame + form_frame = create_styled_frame(content_frame, min_size=(340, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") + form_layout = QtWidgets.QVBoxLayout(form_frame) + form_layout.setSpacing(20) + + # Input fields + name_frame, name_edit = create_input_field(form_frame, name_field_text) + password_frame, password_edit = create_input_field(form_frame, password_field_text) + salary_frame, salary_edit = create_input_field(form_frame, salary_field_text) + position_frame, position_edit = create_input_field(form_frame, position_fielld_text) + + # Submit button + button_frame = create_styled_frame(form_frame, style="padding: 7px;") + button_layout = QtWidgets.QVBoxLayout(button_frame) + button_layout.setSpacing(60) + submit_button = create_styled_button(button_frame, submit_text, min_size=(150, 0)) + button_layout.addWidget(submit_button, 0, QtCore.Qt.AlignHCenter) + + form_layout.addWidget(name_frame) + form_layout.addWidget(password_frame) + form_layout.addWidget(salary_frame) + form_layout.addWidget(position_frame) + form_layout.addWidget(button_frame) + + content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + main_layout.addWidget(content_frame) + + return page, name_edit, password_edit, salary_edit, position_edit,submit_button def setup_main_window(main_window): """Set up the main window with a stacked widget containing home, admin, and employee pages.""" main_window.setObjectName("MainWindow") @@ -360,23 +382,44 @@ def admin_login_menu_page(name, password): if result: stacked_widget.setCurrentIndex(3) else: - print("Invalid admin credentials") + print("Invalid admin credentials") + + def add_employee_form_submit(name, password, salary, position): + if ( + len(name) != 0 + and len(password) != 0 + and len(salary) != 0 + and len(position) != 0 + ): + backend.create_employee(name, password, salary, position) + pop_up_message_with_only_ok(stacked_widget,"Employee added successfully",3) + + else: + print("Please fill in all fields") + pop_up_message(stacked_widget,"Please fill in all fields",3) + home_page = create_home_page(stacked_widget, switch_to_admin, switch_to_employee, exit_app) admin_page, admin_name, admin_password, admin_submit = create_login_page(stacked_widget, "Admin Login") admin_submit.clicked.connect( lambda: admin_login_menu_page(admin_name.text(), admin_password.text()) ) - admin_menu_page = create_admin_menu_page(stacked_widget) - + admin_menu_page,add_button,update_employee,employee_list,total_money,back_to_home = create_admin_menu_page(stacked_widget) + add_button.clicked.connect(lambda:stacked_widget.setCurrentIndex(4)) + # create employee page + add_employe_page , new_employee_name, new_employee_password, new_employe_salary, new_employe_position, new_employee_submit = create_add_employe_page(stacked_widget, "Add Employee") + new_employee_submit.clicked.connect( + lambda: add_employee_form_submit(new_employee_name.text(), new_employee_password.text(), new_employe_salary.text(), new_employe_position.text()) + ) employee_page, employee_name, employee_password, employee_submit = create_login_page(stacked_widget, "Employee Login") # Add pages to stacked widget - stacked_widget.addWidget(home_page) - stacked_widget.addWidget(admin_page) - stacked_widget.addWidget(employee_page) - stacked_widget.addWidget(admin_menu_page) + stacked_widget.addWidget(home_page)#1 + stacked_widget.addWidget(admin_page)#2 + stacked_widget.addWidget(employee_page)#3 + stacked_widget.addWidget(admin_menu_page)#4 + stacked_widget.addWidget(add_employe_page)#5 main_layout.addWidget(stacked_widget) main_window.setCentralWidget(central_widget) From d285037ead956f269c707e1854727515a5ef904e Mon Sep 17 00:00:00 2001 From: Pratyanj <109451378+pratyanj@users.noreply.github.com> Date: Fri, 30 May 2025 16:07:32 +0530 Subject: [PATCH 388/442] small change --- bank_managment_system/backend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bank_managment_system/backend.py b/bank_managment_system/backend.py index c60dae4c4e4..42475416fa0 100644 --- a/bank_managment_system/backend.py +++ b/bank_managment_system/backend.py @@ -167,4 +167,4 @@ def get_detail(acc_no): # Check if employee exists def check_name_in_staff(name): cur.execute("SELECT 1 FROM staff WHERE name = ?", (name,)) - return cur.fetchone() is not Non \ No newline at end of file + return cur.fetchone() is not None \ No newline at end of file From 1a4a91927ad15b97bf23276d36bfe5bbf1f33a77 Mon Sep 17 00:00:00 2001 From: Pratyanj <109451378+pratyanj@users.noreply.github.com> Date: Fri, 30 May 2025 17:25:40 +0530 Subject: [PATCH 389/442] reduce code and improve it by reusable function block --- bank_managment_system/QTFrontend.py | 268 +++++++++++++--------------- 1 file changed, 126 insertions(+), 142 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 38ff99ce869..33f104aca31 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -68,8 +68,15 @@ def create_input_field(parent, label_text, min_label_size=(120, 0)): layout.addWidget(label) layout.addWidget(line_edit) return frame, line_edit -def pop_up_message(parent, message: str, page: int): - """Create a popup message box with a given message.""" +def show_popup_message(parent, message: str, page: int = None, show_cancel: bool = True): + """Reusable popup message box. + + Args: + parent: The parent widget. + message (str): The message to display. + page (int, optional): Page index to switch to after dialog closes. + show_cancel (bool): Whether to show the Cancel button. + """ dialog = QtWidgets.QDialog(parent) dialog.setWindowTitle("Message") dialog.setFixedSize(350, 100) @@ -84,9 +91,14 @@ def pop_up_message(parent, message: str, page: int): label.setWordWrap(True) layout.addWidget(label) - button_box = QtWidgets.QDialogButtonBox( - QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel - ) + # Decide which buttons to show + if show_cancel: + button_box = QtWidgets.QDialogButtonBox( + QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel + ) + else: + button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok) + button_box.setStyleSheet(""" QPushButton { background-color: #3498db; @@ -104,66 +116,24 @@ def pop_up_message(parent, message: str, page: int): """) layout.addWidget(button_box) - button_box.accepted.connect(dialog.accept) - button_box.rejected.connect(lambda: reject_clicked(dialog, parent, page)) - - dialog.exec_() - -def reject_clicked(dialog, parent, page): - parent.setCurrentIndex(page) - dialog.reject() - -def pop_up_message_with_only_ok(parent, message: str, page: int): - """Create a popup message box with only an OK button.""" - dialog = QtWidgets.QDialog(parent) - dialog.setWindowTitle("Message") - dialog.setFixedSize(350, 100) - dialog.setStyleSheet("background-color: #f0f0f0;") + # Connect buttons + def on_accept(): + if page is not None: + parent.setCurrentIndex(page) + dialog.accept() - layout = QtWidgets.QVBoxLayout(dialog) - layout.setSpacing(10) - layout.setContentsMargins(15, 15, 15, 15) - - label = QtWidgets.QLabel(message) - label.setStyleSheet("font-size: 12px; color: #2c3e50;") - label.setWordWrap(True) - layout.addWidget(label) - - button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok) - button_box.setStyleSheet(""" - QPushButton { - background-color: #3498db; - color: white; - border-radius: 4px; - padding: 6px 12px; - min-width: 80px; - } - QPushButton:hover { - background-color: #2980b9; - } - QPushButton:pressed { - background-color: #1c6ea4; - } - """) - layout.addWidget(button_box) + def on_reject(): + if page is not None: + parent.setCurrentIndex(page) + dialog.reject() - button_box.accepted.connect(lambda: accepted_clicked()) - def accepted_clicked(): - parent.setCurrentIndex(page) - dialog.close() + button_box.accepted.connect(on_accept) + button_box.rejected.connect(on_reject) dialog.exec_() def create_login_page(parent ,title, name_field_text="Name :", password_field_text="Password :", submit_text="Submit",): """Create a login page with a title, name and password fields, and a submit button.""" - page = QtWidgets.QWidget(parent) - main_layout = QtWidgets.QVBoxLayout(page) - - # Header frame with title - header_frame = create_styled_frame(page, style="background-color: #ffffff; border-radius: 10px; padding: 10px;") - header_layout = QtWidgets.QVBoxLayout(header_frame) - title_label = create_styled_label(header_frame, title, font_size=30) - header_layout.addWidget(title_label, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop) - main_layout.addWidget(header_frame, 0, QtCore.Qt.AlignTop) + page, main_layout = create_page_with_header(parent, "Admin Menu") # Content frame content_frame = create_styled_frame(page) @@ -203,23 +173,13 @@ def on_login_button_clicked(parent,name_field, password_field): # Check if the entered name and password are correct if name == "" and password == "": # Show a message box with the entered name and password - pop_up_message(parent, "Please enter your name and password.",0) + show_popup_message(parent, "Please enter your name and password.",0) else: print(f"Name: {name}, Password: {password}") def create_home_page(parent, on_admin_clicked, on_employee_clicked, on_exit_clicked): """Create the home page with Admin, Employee, and Exit buttons.""" - page = QtWidgets.QWidget(parent) - main_layout = QtWidgets.QVBoxLayout(page) - main_layout.setContentsMargins(20, 20, 20, 20) - main_layout.setSpacing(20) - - # Header frame with title - header_frame = create_styled_frame(page, style="background-color: #ffffff; border-radius: 10px; padding: 10px;") - header_layout = QtWidgets.QVBoxLayout(header_frame) - title_label = create_styled_label(header_frame, "Bank Management System", font_size=30) - header_layout.addWidget(title_label, 0, QtCore.Qt.AlignHCenter) - main_layout.addWidget(header_frame, 0, QtCore.Qt.AlignTop) + page, main_layout = create_page_with_header(parent, "Admin Menu") # Button frame button_frame = create_styled_frame(page) @@ -267,95 +227,78 @@ def create_home_page(parent, on_admin_clicked, on_employee_clicked, on_exit_clic exit_button.clicked.connect(on_exit_clicked) return page - -def create_admin_menu_page(perent): - """Create the admin menu page with buttons for adding, deleting, and viewing accounts.""" - page = QtWidgets.QWidget(perent) +def create_page_with_header(parent, title_text): + """Create a page with a styled header and return the page + main layout.""" + page = QtWidgets.QWidget(parent) main_layout = QtWidgets.QVBoxLayout(page) main_layout.setContentsMargins(20, 20, 20, 20) main_layout.setSpacing(20) - # Header frame with title header_frame = create_styled_frame(page, style="background-color: #ffffff; border-radius: 10px; padding: 10px;") header_layout = QtWidgets.QVBoxLayout(header_frame) - title_label = create_styled_label(header_frame, "Admin Menu", font_size=30) - header_layout.addWidget(title_label, 0, QtCore.Qt.AlignHCenter) + title_label = create_styled_label(header_frame, title_text, font_size=30) + header_layout.addWidget(title_label, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop) + main_layout.addWidget(header_frame, 0, QtCore.Qt.AlignTop) + return page, main_layout +def create_admin_menu_page(parent): + page, main_layout = create_page_with_header(parent, "Admin Menu") - # Button frame button_frame = create_styled_frame(page) button_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) button_layout = QtWidgets.QVBoxLayout(button_frame) - # Button container + button_container = create_styled_frame(button_frame, min_size=(300, 0), style="background-color: #ffffff; border-radius: 15px; padding: 20px;") button_container_layout = QtWidgets.QVBoxLayout(button_container) button_container_layout.setSpacing(15) - # Buttons - add_button = create_styled_button(button_container, "Add Employee") - update_employee = create_styled_button(button_container, "Update Employee") - employee_list = create_styled_button(button_container, "Employee List") - total_money = create_styled_button(button_container, "Total Money") - back_to_home = create_styled_button(button_container, "Back") - button_container_layout.addWidget(add_button) - button_container_layout.addWidget(update_employee) - button_container_layout.addWidget(employee_list) - button_container_layout.addWidget(total_money) - button_container_layout.addWidget(back_to_home) + + # Define button labels + button_labels = ["Add Employee", "Update Employee", "Employee List", "Total Money", "Back"] + buttons = [] + + for label in button_labels: + btn = create_styled_button(button_container, label) + button_container_layout.addWidget(btn) + buttons.append(btn) + button_layout.addWidget(button_container, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) main_layout.addWidget(button_frame) - # Connect button signals - # add_button.clicked.connect(on_add_employee_clicked) - # update_employee.clicked.connect(on_update_employee_clicked) - # employee_list.clicked.connect(on_employee_list_clicked) - # total_money.clicked.connect(on_total_money_clicked) - # back_to_home.clicked.connect(on_back_to_home_clicked) - return page,add_button,update_employee,employee_list,total_money,back_to_home - -def create_add_employe_page(parent ,title, name_field_text="Name :", password_field_text="Password :",position_fielld_text="Position :",salary_field_text="Salary :",submit_text="Submit",): - """Create a login page with a title, name and password fields, and a submit button.""" - page = QtWidgets.QWidget(parent) - main_layout = QtWidgets.QVBoxLayout(page) - - # Header frame with title - header_frame = create_styled_frame(page, style="background-color: #ffffff; border-radius: 10px; padding: 10px;") - header_layout = QtWidgets.QVBoxLayout(header_frame) - title_label = create_styled_label(header_frame, title, font_size=30) - header_layout.addWidget(title_label, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop) - main_layout.addWidget(header_frame, 0, QtCore.Qt.AlignTop) + + return page, *buttons # Unpack as add_button, update_employee, etc. + - # Content frame +def create_add_employee_page(parent, title, submit_text="Submit"): + page, main_layout = create_page_with_header(parent, title) + content_frame = create_styled_frame(page) content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) content_layout = QtWidgets.QVBoxLayout(content_frame) - - # Form frame + form_frame = create_styled_frame(content_frame, min_size=(340, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") form_layout = QtWidgets.QVBoxLayout(form_frame) form_layout.setSpacing(20) - - # Input fields - name_frame, name_edit = create_input_field(form_frame, name_field_text) - password_frame, password_edit = create_input_field(form_frame, password_field_text) - salary_frame, salary_edit = create_input_field(form_frame, salary_field_text) - position_frame, position_edit = create_input_field(form_frame, position_fielld_text) - + + # Define input fields + fields = ["Name :", "Password :", "Salary :", "Position :"] + edits = [] + + for field in fields: + field_frame, field_edit = create_input_field(form_frame, field) + form_layout.addWidget(field_frame) + edits.append(field_edit) + # Submit button button_frame = create_styled_frame(form_frame, style="padding: 7px;") button_layout = QtWidgets.QVBoxLayout(button_frame) - button_layout.setSpacing(60) submit_button = create_styled_button(button_frame, submit_text, min_size=(150, 0)) button_layout.addWidget(submit_button, 0, QtCore.Qt.AlignHCenter) - - form_layout.addWidget(name_frame) - form_layout.addWidget(password_frame) - form_layout.addWidget(salary_frame) - form_layout.addWidget(position_frame) + form_layout.addWidget(button_frame) - content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) main_layout.addWidget(content_frame) - - return page, name_edit, password_edit, salary_edit, position_edit,submit_button + + return page, *edits, submit_button # Unpack as name_edit, password_edit, etc. + def setup_main_window(main_window): """Set up the main window with a stacked widget containing home, admin, and employee pages.""" main_window.setObjectName("MainWindow") @@ -383,6 +326,7 @@ def admin_login_menu_page(name, password): stacked_widget.setCurrentIndex(3) else: print("Invalid admin credentials") + show_popup_message(stacked_widget,"Invalid admin credentials",0) def add_employee_form_submit(name, password, salary, position): if ( @@ -392,26 +336,66 @@ def add_employee_form_submit(name, password, salary, position): and len(position) != 0 ): backend.create_employee(name, password, salary, position) - pop_up_message_with_only_ok(stacked_widget,"Employee added successfully",3) + show_popup_message(stacked_widget,"Employee added successfully",3,False) else: print("Please fill in all fields") - pop_up_message(stacked_widget,"Please fill in all fields",3) + show_popup_message(stacked_widget,"Please fill in all fields",3) - home_page = create_home_page(stacked_widget, switch_to_admin, switch_to_employee, exit_app) - admin_page, admin_name, admin_password, admin_submit = create_login_page(stacked_widget, "Admin Login") + # Create Home Page + home_page = create_home_page( + stacked_widget, + switch_to_admin, + switch_to_employee, + exit_app + ) + + # Create Admin Login Page + admin_page, admin_name, admin_password, admin_submit = create_login_page( + stacked_widget, + title="Admin Login" + ) + admin_password.setEchoMode(QtWidgets.QLineEdit.Password) + admin_name.setFont(QtGui.QFont("Arial", 10)) + admin_password.setFont(QtGui.QFont("Arial", 10)) + admin_name.setPlaceholderText("Enter your name") + admin_password.setPlaceholderText("Enter your password") + admin_submit.clicked.connect( - lambda: admin_login_menu_page(admin_name.text(), admin_password.text()) + lambda: admin_login_menu_page( + admin_name.text(), + admin_password.text() + ) + ) + + # Create Admin Menu Page + admin_menu_page, add_button, update_button, list_button, money_button, back_button = create_admin_menu_page( + stacked_widget ) - admin_menu_page,add_button,update_employee,employee_list,total_money,back_to_home = create_admin_menu_page(stacked_widget) - add_button.clicked.connect(lambda:stacked_widget.setCurrentIndex(4)) - # create employee page - add_employe_page , new_employee_name, new_employee_password, new_employe_salary, new_employe_position, new_employee_submit = create_add_employe_page(stacked_widget, "Add Employee") - new_employee_submit.clicked.connect( - lambda: add_employee_form_submit(new_employee_name.text(), new_employee_password.text(), new_employe_salary.text(), new_employe_position.text()) + + add_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(4)) + + # Create Add Employee Page + add_employee_page, emp_name, emp_password, emp_salary, emp_position, emp_submit = create_add_employee_page( + stacked_widget, + title="Add Employee" + ) + + emp_submit.clicked.connect( + lambda: add_employee_form_submit( + emp_name.text(), + emp_password.text(), + emp_salary.text(), + emp_position.text() + ) + ) + + # Create Employee Login Page + employee_page, employee_name, employee_password, employee_submit = create_login_page( + stacked_widget, + title="Employee Login" ) - employee_page, employee_name, employee_password, employee_submit = create_login_page(stacked_widget, "Employee Login") # Add pages to stacked widget @@ -419,7 +403,7 @@ def add_employee_form_submit(name, password, salary, position): stacked_widget.addWidget(admin_page)#2 stacked_widget.addWidget(employee_page)#3 stacked_widget.addWidget(admin_menu_page)#4 - stacked_widget.addWidget(add_employe_page)#5 + stacked_widget.addWidget(add_employee_page)#5 main_layout.addWidget(stacked_widget) main_window.setCentralWidget(central_widget) From 4cb6b4450a4023e39fa8e97d0638dc7ec9fdcce2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 May 2025 18:47:55 +0000 Subject: [PATCH 390/442] Bump selenium from 4.32.0 to 4.33.0 Bumps [selenium](https://github.com/SeleniumHQ/Selenium) from 4.32.0 to 4.33.0. - [Release notes](https://github.com/SeleniumHQ/Selenium/releases) - [Commits](https://github.com/SeleniumHQ/Selenium/compare/selenium-4.32.0...selenium-4.33.0) --- updated-dependencies: - dependency-name: selenium dependency-version: 4.33.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 7ed373d8ef3..dcca9bc3901 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -21,7 +21,7 @@ backend==0.2.4.1 win10toast==0.9 Counter==1.0.0 Flask==3.1.1 -selenium==4.32.0 +selenium==4.33.0 firebase-admin==6.8.0 ujson==5.10.0 requests==2.32.3 From 8af0791795780387e9e717d51be1e3229001429a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 May 2025 18:48:06 +0000 Subject: [PATCH 391/442] Bump ccxt from 4.4.85 to 4.4.86 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.4.85 to 4.4.86. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/v4.4.85...v4.4.86) --- updated-dependencies: - dependency-name: ccxt dependency-version: 4.4.86 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 7ed373d8ef3..feb96fac034 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.4.0 Ball==0.2.9 pynput==1.8.1 gTTS==2.5.4 -ccxt==4.4.85 +ccxt==4.4.86 fitz==0.0.1.dev2 fastapi==0.115.12 Django==5.1.7 From aa0a6d1217358f56811cb1011bd9da98f167999e Mon Sep 17 00:00:00 2001 From: Pratyanj <109451378+pratyanj@users.noreply.github.com> Date: Sat, 31 May 2025 16:38:53 +0530 Subject: [PATCH 392/442] update employee page created --- bank_managment_system/QTFrontend.py | 87 +++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 10 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 33f104aca31..145a743749b 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -131,6 +131,31 @@ def on_reject(): button_box.rejected.connect(on_reject) dialog.exec_() +def get_employee_name(parent,name_field_text="Enter Employee Name"): + page, main_layout = create_page_with_header(parent, "Employee Data Update") + + # Content frame + content_frame = create_styled_frame(page) + content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_layout = QtWidgets.QVBoxLayout(content_frame) + # Form frame + form_frame = create_styled_frame(content_frame, min_size=(340, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") + form_layout = QtWidgets.QVBoxLayout(form_frame) + # Form fields + name_label, name_field = create_input_field(form_frame, name_field_text) + search_button = create_styled_button(form_frame, "Search", min_size=(100, 30)) + form_layout.addWidget(name_label) + form_layout.addWidget(search_button) + + search_button.clicked.connect(lambda: backend.check_name_in_staff()) + def on_search_button_clicked(): + fetch = backend.check_name_in_staff() + if fetch: + print(f"Employee data: {fetch[0]}, {fetch[1]}, {fetch[2]}, {fetch[3]},") + else: + print("Employee not found.") + + #backend.check_name_in_staff() def create_login_page(parent ,title, name_field_text="Name :", password_field_text="Password :", submit_text="Submit",): """Create a login page with a title, name and password fields, and a submit button.""" page, main_layout = create_page_with_header(parent, "Admin Menu") @@ -267,7 +292,7 @@ def create_admin_menu_page(parent): return page, *buttons # Unpack as add_button, update_employee, etc. -def create_add_employee_page(parent, title, submit_text="Submit"): +def create_add_employee_page(parent, title, submit_text="Submit",update_btn:bool=False): page, main_layout = create_page_with_header(parent, title) content_frame = create_styled_frame(page) @@ -290,15 +315,22 @@ def create_add_employee_page(parent, title, submit_text="Submit"): # Submit button button_frame = create_styled_frame(form_frame, style="padding: 7px;") button_layout = QtWidgets.QVBoxLayout(button_frame) + update_button = create_styled_button(button_frame, "Update", min_size=(150, 0)) submit_button = create_styled_button(button_frame, submit_text, min_size=(150, 0)) - button_layout.addWidget(submit_button, 0, QtCore.Qt.AlignHCenter) + if update_btn: + button_layout.addWidget(update_button, 0, QtCore.Qt.AlignHCenter) + else: + button_layout.addWidget(submit_button, 0, QtCore.Qt.AlignHCenter) + form_layout.addWidget(button_frame) content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) main_layout.addWidget(content_frame) - - return page, *edits, submit_button # Unpack as name_edit, password_edit, etc. - + if update_btn: + return page, *edits, update_button + else: + return page, *edits, submit_button # Unpack as name_edit, password_edit, etc. + def setup_main_window(main_window): """Set up the main window with a stacked widget containing home, admin, and employee pages.""" main_window.setObjectName("MainWindow") @@ -341,6 +373,31 @@ def add_employee_form_submit(name, password, salary, position): else: print("Please fill in all fields") show_popup_message(stacked_widget,"Please fill in all fields",3) + def update_employee_data(name, password, salary, position, name_to_update): + try: + cur = backend.cur + if name_to_update: + cur.execute("UPDATE staff SET Name = ? WHERE name = ?", (name, name_to_update)) + + cur.execute("UPDATE staff SET Name = ? WHERE name = ?", (password, name)) + cur.execute("UPDATE staff SET password = ? WHERE name = ?", (password, name)) + cur.execute("UPDATE staff SET salary = ? WHERE name = ?", (salary, name)) + cur.execute("UPDATE staff SET position = ? WHERE name = ?", (position, name)) + backend.conn.commit() + show_popup_message(stacked_widget,"Employee Upadate successfully",3,False) + + except: + show_popup_message(stacked_widget,"Please fill in all fields",3) + + def fetch_employee_data(name): + try: + cur = backend.cur + cur.execute("SELECT * FROM staff WHERE name = ?", (name,)) + employee_data = cur.fetchone() + return employee_data + except: + print("Error fetching employee data") + return None # Create Home Page @@ -375,13 +432,22 @@ def add_employee_form_submit(name, password, salary, position): ) add_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(4)) + update_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(5)) # Create Add Employee Page add_employee_page, emp_name, emp_password, emp_salary, emp_position, emp_submit = create_add_employee_page( stacked_widget, title="Add Employee" ) + + # Update Employee Page + update_employee_page1 = get_employee_name(stacked_widget) + # apply the update_employee_data function to the submit button + + + + # /////////////////////////// emp_submit.clicked.connect( lambda: add_employee_form_submit( emp_name.text(), @@ -399,11 +465,12 @@ def add_employee_form_submit(name, password, salary, position): # Add pages to stacked widget - stacked_widget.addWidget(home_page)#1 - stacked_widget.addWidget(admin_page)#2 - stacked_widget.addWidget(employee_page)#3 - stacked_widget.addWidget(admin_menu_page)#4 - stacked_widget.addWidget(add_employee_page)#5 + stacked_widget.addWidget(home_page)#0 + stacked_widget.addWidget(admin_page)#1 + stacked_widget.addWidget(employee_page)#2 + stacked_widget.addWidget(admin_menu_page)#3 + stacked_widget.addWidget(add_employee_page)#4 + stacked_widget.addWidget(update_employee_page1)#5 main_layout.addWidget(stacked_widget) main_window.setCentralWidget(central_widget) From 0ef17a1f083818f94d7518adf8b4ec1da9212ded Mon Sep 17 00:00:00 2001 From: Pratyanj <109451378+pratyanj@users.noreply.github.com> Date: Sat, 31 May 2025 16:40:19 +0530 Subject: [PATCH 393/442] add database in gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1f15459f4de..0f3717818e6 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ print(lower+upper+odd+even) # thumbnail cache on Windows Thumbs.db +bankmanaging.db \ No newline at end of file From a32c3d716a4b41f490f1fb440052a0e26401a310 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Jun 2025 18:48:57 +0000 Subject: [PATCH 394/442] Bump solara from 1.47.0 to 1.48.0 Bumps [solara](https://github.com/widgetti/solara) from 1.47.0 to 1.48.0. - [Changelog](https://github.com/widgetti/solara/blob/master/CHANGELOG.md) - [Commits](https://github.com/widgetti/solara/compare/v1.47.0...v1.48.0) --- updated-dependencies: - dependency-name: solara dependency-version: 1.48.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- News_App/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/News_App/requirements.txt b/News_App/requirements.txt index fd923297117..bf511c5a6fa 100644 --- a/News_App/requirements.txt +++ b/News_App/requirements.txt @@ -1,4 +1,4 @@ -solara == 1.47.0 +solara == 1.48.0 Flask gunicorn ==23.0.0 simple-websocket diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 46a9eace337..3f54e32db86 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -74,7 +74,7 @@ xor-cipher==5.0.1 bird==0.1.2 mechanize==0.4.10 translate==3.6.1 -solara==1.47.0 +solara==1.48.0 pywhatkit==5.4 mutagen==1.47.0 Unidecode==1.4.0 From a24cb1b68dbcb90dca1657ea950601999a1d6de2 Mon Sep 17 00:00:00 2001 From: Pratyanj <109451378+pratyanj@users.noreply.github.com> Date: Tue, 3 Jun 2025 15:27:24 +0530 Subject: [PATCH 395/442] employee search page done --- bank_managment_system/QTFrontend.py | 82 ++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 26 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 145a743749b..08fa1143ef5 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -131,29 +131,48 @@ def on_reject(): button_box.rejected.connect(on_reject) dialog.exec_() -def get_employee_name(parent,name_field_text="Enter Employee Name"): +def get_employee_name(parent, name_field_text="Enter Employee Name"): page, main_layout = create_page_with_header(parent, "Employee Data Update") # Content frame content_frame = create_styled_frame(page) content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) content_layout = QtWidgets.QVBoxLayout(content_frame) + # Form frame form_frame = create_styled_frame(content_frame, min_size=(340, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") form_layout = QtWidgets.QVBoxLayout(form_frame) + # Form fields name_label, name_field = create_input_field(form_frame, name_field_text) search_button = create_styled_button(form_frame, "Search", min_size=(100, 30)) form_layout.addWidget(name_label) form_layout.addWidget(search_button) + content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + main_layout.addWidget(content_frame) - search_button.clicked.connect(lambda: backend.check_name_in_staff()) def on_search_button_clicked(): - fetch = backend.check_name_in_staff() - if fetch: - print(f"Employee data: {fetch[0]}, {fetch[1]}, {fetch[2]}, {fetch[3]},") - else: - print("Employee not found.") + entered_name = name_field.text().strip() + if not entered_name: + QtWidgets.QMessageBox.warning(parent, "Input Error", "Please enter an employee name.") + return + + try: + cur = backend.cur + cur.execute("SELECT * FROM staff WHERE name = ?", (entered_name,)) + fetch = cur.fetchone() + if fetch: + QtWidgets.QMessageBox.information(parent, "Employee Found", + f"Employee data:\nID: {fetch[0]}\nName: {fetch[1]}\nDept: {fetch[2]}\nRole: {fetch[3]}") + else: + QtWidgets.QMessageBox.information(parent, "Not Found", "Employee not found.") + except Exception as e: + QtWidgets.QMessageBox.critical(parent, "Error", f"An error occurred: {str(e)}") + + search_button.clicked.connect(on_search_button_clicked) + + return page + #backend.check_name_in_staff() def create_login_page(parent ,title, name_field_text="Name :", password_field_text="Password :", submit_text="Submit",): @@ -188,19 +207,25 @@ def create_login_page(parent ,title, name_field_text="Name :", password_field_te content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) main_layout.addWidget(content_frame) - submit_button.clicked.connect(lambda: on_login_button_clicked(parent,name_edit, password_edit)) + return page, name_edit, password_edit, submit_button -def on_login_button_clicked(parent,name_field, password_field): - # Get the entered name and password - name = name_field.text() - password = password_field.text() - # Check if the entered name and password are correct - if name == "" and password == "": - # Show a message box with the entered name and password - show_popup_message(parent, "Please enter your name and password.",0) +def on_login_button_clicked(parent, name_field, password_field): + name = name_field.text().strip() + password = password_field.text().strip() + + if not name or not password: + show_popup_message(parent, "Please enter your name and password.", 0) else: - print(f"Name: {name}, Password: {password}") + try: + # Ideally, here you'd call a backend authentication check + success = backend.check_admin(name, password) + if success: + QtWidgets.QMessageBox.information(parent, "Login Successful", f"Welcome, {name}!") + else: + QtWidgets.QMessageBox.warning(parent, "Login Failed", "Incorrect name or password.") + except Exception as e: + QtWidgets.QMessageBox.critical(parent, "Error", f"An error occurred during login: {str(e)}") def create_home_page(parent, on_admin_clicked, on_employee_clicked, on_exit_clicked): """Create the home page with Admin, Employee, and Exit buttons.""" @@ -315,11 +340,11 @@ def create_add_employee_page(parent, title, submit_text="Submit",update_btn:bool # Submit button button_frame = create_styled_frame(form_frame, style="padding: 7px;") button_layout = QtWidgets.QVBoxLayout(button_frame) - update_button = create_styled_button(button_frame, "Update", min_size=(150, 0)) - submit_button = create_styled_button(button_frame, submit_text, min_size=(150, 0)) if update_btn: + update_button = create_styled_button(button_frame, "Update", min_size=(150, 0)) button_layout.addWidget(update_button, 0, QtCore.Qt.AlignHCenter) else: + submit_button = create_styled_button(button_frame, submit_text, min_size=(150, 0)) button_layout.addWidget(submit_button, 0, QtCore.Qt.AlignHCenter) @@ -353,12 +378,17 @@ def exit_app(): QtWidgets.QApplication.quit() def admin_login_menu_page(name, password): - result = backend.check_admin(name, password) - if result: - stacked_widget.setCurrentIndex(3) - else: - print("Invalid admin credentials") - show_popup_message(stacked_widget,"Invalid admin credentials",0) + try: + # Ideally, here you'd call a backend authentication check + success = backend.check_admin(name, password) + if success: + QtWidgets.QMessageBox.information(stacked_widget, "Login Successful", f"Welcome, {name}!") + stacked_widget.setCurrentIndex(3) + else: + QtWidgets.QMessageBox.warning(stacked_widget, "Login Failed", "Incorrect name or password.") + except Exception as e: + QtWidgets.QMessageBox.critical(stacked_widget, "Error", f"An error occurred during login: {str(e)}") + # show_popup_message(stacked_widget,"Invalid admin credentials",0) def add_employee_form_submit(name, password, salary, position): if ( @@ -476,7 +506,7 @@ def fetch_employee_data(name): main_window.setCentralWidget(central_widget) # Set initial page - stacked_widget.setCurrentIndex(0) + stacked_widget.setCurrentIndex(5) return stacked_widget, { "admin_name": admin_name, From 9097a289b55237886c4697e26e2e2196c6dec3b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jun 2025 18:09:54 +0000 Subject: [PATCH 396/442] Bump aiohttp from 3.11.18 to 3.12.9 --- updated-dependencies: - dependency-name: aiohttp dependency-version: 3.12.9 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- async_downloader/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/async_downloader/requirements.txt b/async_downloader/requirements.txt index f316405d755..6efd61c224a 100644 --- a/async_downloader/requirements.txt +++ b/async_downloader/requirements.txt @@ -1 +1 @@ -aiohttp==3.11.18 +aiohttp==3.12.9 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 46a9eace337..982d6473a8d 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -1,5 +1,5 @@ pafy==0.5.5 -aiohttp==3.11.18 +aiohttp==3.12.9 fuzzywuzzy==0.18.0 hupper==1.12.1 seaborn==0.13.2 From f4aaf7526bf1c7c95106ccb0396b9f17928f66f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Jun 2025 19:01:55 +0000 Subject: [PATCH 397/442] Bump google-api-python-client from 2.170.0 to 2.171.0 Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.170.0 to 2.171.0. - [Release notes](https://github.com/googleapis/google-api-python-client/releases) - [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.170.0...v2.171.0) --- updated-dependencies: - dependency-name: google-api-python-client dependency-version: 2.171.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 81891144c37..a33f365b7a2 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -58,7 +58,7 @@ requests-mock==1.12.1 pyglet==2.1.6 urllib3==2.4.0 thirdai==0.9.33 -google-api-python-client==2.170.0 +google-api-python-client==2.171.0 sound==0.1.0 xlwt==1.3.0 pygame==2.6.1 From a5ef13184b05739d9b7d5fb6fc7a67cf5e8fa078 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Jun 2025 19:02:05 +0000 Subject: [PATCH 398/442] Bump openai from 1.82.1 to 1.84.0 Bumps [openai](https://github.com/openai/openai-python) from 1.82.1 to 1.84.0. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.82.1...v1.84.0) --- updated-dependencies: - dependency-name: openai dependency-version: 1.84.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 81891144c37..57b221c63e5 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.82.1 +openai==1.84.0 background==0.2.1 pydantic==2.11.4 openpyxl==3.1.2 From 92d47d8b3fd8a443f6763394d6b219369ccf9622 Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Fri, 6 Jun 2025 11:29:34 +0530 Subject: [PATCH 399/442] bd creating error solve --- bank_managment_system/backend.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bank_managment_system/backend.py b/bank_managment_system/backend.py index 42475416fa0..7ea679863b5 100644 --- a/bank_managment_system/backend.py +++ b/bank_managment_system/backend.py @@ -1,12 +1,11 @@ import sqlite3 - +import os # Making connection with database def connect_database(): global conn global cur - conn = sqlite3.connect("bankmanaging.db") + conn = sqlite3.connect(os.path.join(os.path.dirname(__file__), "bankmanaging.db")) cur = conn.cursor() - cur.execute( """ CREATE TABLE IF NOT EXISTS bank ( From 28a792b9aa8289ae2b915cbef7afd99e798c44ea Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Fri, 6 Jun 2025 12:16:39 +0530 Subject: [PATCH 400/442] update employee data page finish --- bank_managment_system/QTFrontend.py | 113 ++++++++++++++++++++++++---- 1 file changed, 98 insertions(+), 15 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 08fa1143ef5..443276df1fe 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -3,6 +3,7 @@ import sys import backend backend.connect_database() +employee_data = None def create_styled_frame(parent, min_size=None, style=""): """Create a styled QFrame with optional minimum size and custom style.""" frame = QtWidgets.QFrame(parent) @@ -68,6 +69,7 @@ def create_input_field(parent, label_text, min_label_size=(120, 0)): layout.addWidget(label) layout.addWidget(line_edit) return frame, line_edit + def show_popup_message(parent, message: str, page: int = None, show_cancel: bool = True): """Reusable popup message box. @@ -131,6 +133,7 @@ def on_reject(): button_box.rejected.connect(on_reject) dialog.exec_() + def get_employee_name(parent, name_field_text="Enter Employee Name"): page, main_layout = create_page_with_header(parent, "Employee Data Update") @@ -152,18 +155,28 @@ def get_employee_name(parent, name_field_text="Enter Employee Name"): main_layout.addWidget(content_frame) def on_search_button_clicked(): + global employee_data entered_name = name_field.text().strip() + print(f"Entered Name: {entered_name}") if not entered_name: QtWidgets.QMessageBox.warning(parent, "Input Error", "Please enter an employee name.") return try: - cur = backend.cur - cur.execute("SELECT * FROM staff WHERE name = ?", (entered_name,)) - fetch = cur.fetchone() - if fetch: - QtWidgets.QMessageBox.information(parent, "Employee Found", - f"Employee data:\nID: {fetch[0]}\nName: {fetch[1]}\nDept: {fetch[2]}\nRole: {fetch[3]}") + employee_check = backend.check_name_in_staff(entered_name) + print(f"Employee Check: {type(employee_check)},{employee_check}") + if employee_check: + cur = backend.cur + cur.execute("SELECT * FROM staff WHERE name = ?", (entered_name,)) + employee_data = cur.fetchone() + print(f"Employee Data: {employee_data}") + parent.setCurrentIndex(6) + + # if employee_data: + # QtWidgets.QMessageBox.information(parent, "Employee Found", + # f"Employee data:\nID: {fetch[0]}\nName: {fetch[1]}\nDept: {fetch[2]}\nRole: {fetch[3]}") + + else: QtWidgets.QMessageBox.information(parent, "Not Found", "Employee not found.") except Exception as e: @@ -175,6 +188,7 @@ def on_search_button_clicked(): #backend.check_name_in_staff() + def create_login_page(parent ,title, name_field_text="Name :", password_field_text="Password :", submit_text="Submit",): """Create a login page with a title, name and password fields, and a submit button.""" page, main_layout = create_page_with_header(parent, "Admin Menu") @@ -210,6 +224,7 @@ def create_login_page(parent ,title, name_field_text="Name :", password_field_te return page, name_edit, password_edit, submit_button + def on_login_button_clicked(parent, name_field, password_field): name = name_field.text().strip() password = password_field.text().strip() @@ -277,6 +292,7 @@ def create_home_page(parent, on_admin_clicked, on_employee_clicked, on_exit_clic exit_button.clicked.connect(on_exit_clicked) return page + def create_page_with_header(parent, title_text): """Create a page with a styled header and return the page + main layout.""" page = QtWidgets.QWidget(parent) @@ -291,6 +307,7 @@ def create_page_with_header(parent, title_text): main_layout.addWidget(header_frame, 0, QtCore.Qt.AlignTop) return page, main_layout + def create_admin_menu_page(parent): page, main_layout = create_page_with_header(parent, "Admin Menu") @@ -315,7 +332,6 @@ def create_admin_menu_page(parent): main_layout.addWidget(button_frame) return page, *buttons # Unpack as add_button, update_employee, etc. - def create_add_employee_page(parent, title, submit_text="Submit",update_btn:bool=False): page, main_layout = create_page_with_header(parent, title) @@ -330,21 +346,32 @@ def create_add_employee_page(parent, title, submit_text="Submit",update_btn:bool # Define input fields fields = ["Name :", "Password :", "Salary :", "Position :"] + name_edit = None + password_edit = None + salary_edit = None + position_edit = None edits = [] - for field in fields: + for i, field in enumerate(fields): field_frame, field_edit = create_input_field(form_frame, field) form_layout.addWidget(field_frame) + if i == 0: + name_edit = field_edit + elif i == 1: + password_edit = field_edit + elif i == 2: + salary_edit = field_edit + elif i == 3: + position_edit = field_edit edits.append(field_edit) - # Submit button button_frame = create_styled_frame(form_frame, style="padding: 7px;") button_layout = QtWidgets.QVBoxLayout(button_frame) if update_btn: - update_button = create_styled_button(button_frame, "Update", min_size=(150, 0)) + update_button = create_styled_button(button_frame, "Update", min_size=(100, 50)) button_layout.addWidget(update_button, 0, QtCore.Qt.AlignHCenter) else: - submit_button = create_styled_button(button_frame, submit_text, min_size=(150, 0)) + submit_button = create_styled_button(button_frame, submit_text, min_size=(100, 50)) button_layout.addWidget(submit_button, 0, QtCore.Qt.AlignHCenter) @@ -352,9 +379,9 @@ def create_add_employee_page(parent, title, submit_text="Submit",update_btn:bool content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) main_layout.addWidget(content_frame) if update_btn: - return page, *edits, update_button + return page, name_edit, password_edit, salary_edit, position_edit, update_button else: - return page, *edits, submit_button # Unpack as name_edit, password_edit, etc. + return page, name_edit, password_edit, salary_edit, position_edit, submit_button # Unpack as name_edit, password_edit, etc. def setup_main_window(main_window): """Set up the main window with a stacked widget containing home, admin, and employee pages.""" @@ -474,10 +501,65 @@ def fetch_employee_data(name): update_employee_page1 = get_employee_name(stacked_widget) # apply the update_employee_data function to the submit button + update_employee_page2 ,update_employee_name, update_employee_password, update_employee_salary, update_employee_position,update_employee_update = create_add_employee_page(stacked_widget,"Update Employee Details",update_btn=True) + def populate_employee_data(): + global employee_data + if employee_data: + print("employee_data is not None") + update_employee_name.setText(str(employee_data[0])) # Name + update_employee_password.setText(str(employee_data[1])) # Password + update_employee_salary.setText(str(employee_data[2])) # Salary + update_employee_position.setText(str(employee_data[3])) # Position + else: + # Clear fields if no employee data is available + print("employee_data is None") + update_employee_name.clear() + update_employee_password.clear() + update_employee_salary.clear() + update_employee_position.clear() + QtWidgets.QMessageBox.warning(stacked_widget, "No Data", "No employee data available to display.") + def on_page_changed(index): + if index == 6: # update_employee_page2 is at index 6 + populate_employee_data() + + # Connect the currentChanged signal to the on_page_changed function + stacked_widget.currentChanged.connect(on_page_changed) + def update_employee_data(name, password, salary, position, name_to_update): + try: + if not name_to_update: + show_popup_message(stacked_widget, "Original employee name is missing.", 5) + return + if not (name or password or salary or position): + show_popup_message(stacked_widget, "Please fill at least one field to update.", 5) + return + if name: + backend.update_employee_name(name, name_to_update) + if password: + backend.update_employee_password(password, name_to_update) + if salary: + try: + salary = int(salary) + backend.update_employee_salary(salary, name_to_update) + except ValueError: + show_popup_message(stacked_widget, "Salary must be a valid number.", 5) + return + if position: + backend.update_employee_position(position, name_to_update) + show_popup_message(stacked_widget, "Employee updated successfully.", 3, False) + except Exception as e: + show_popup_message(stacked_widget, f"Error updating employee: {str(e)}", 5) + update_employee_update.clicked.connect( + lambda: update_employee_data( + update_employee_name.text().strip(), + update_employee_password.text().strip(), + update_employee_salary.text().strip(), + update_employee_position.text().strip(), + employee_data[0] if employee_data else "" + ) + ) + - - # /////////////////////////// emp_submit.clicked.connect( lambda: add_employee_form_submit( emp_name.text(), @@ -501,6 +583,7 @@ def fetch_employee_data(name): stacked_widget.addWidget(admin_menu_page)#3 stacked_widget.addWidget(add_employee_page)#4 stacked_widget.addWidget(update_employee_page1)#5 + stacked_widget.addWidget(update_employee_page2)#6 main_layout.addWidget(stacked_widget) main_window.setCentralWidget(central_widget) From e68f3c2c606c794add7055902a92e8b0862b117e Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Sat, 7 Jun 2025 11:04:39 +0530 Subject: [PATCH 401/442] GUI done --- Emoji Dictionary/QT_GUI.py | 53 +++++ Emoji Dictionary/QT_GUI.ui | 407 +++++++++++++++++++++++++++++++++++++ 2 files changed, 460 insertions(+) create mode 100644 Emoji Dictionary/QT_GUI.py create mode 100644 Emoji Dictionary/QT_GUI.ui diff --git a/Emoji Dictionary/QT_GUI.py b/Emoji Dictionary/QT_GUI.py new file mode 100644 index 00000000000..fc6ece76e86 --- /dev/null +++ b/Emoji Dictionary/QT_GUI.py @@ -0,0 +1,53 @@ + +# -*- coding: utf-8 -*- + +import sys +from PyQt5.QtCore import * +from PyQt5.QtGui import * +from PyQt5.QtWidgets import * +from PyQt5 import uic + +class MainWindow(QMainWindow): + def __init__(self): + super(MainWindow, self).__init__() + + # Load the UI file + uic.loadUi('Emoji Dictionary/QT_GUI.ui', self) + cells = [ + ["😀", "🥰", "😴", "🤓", "🤮", "🤬", "😨", "🤑", "😫", "😎"], + ["🐒", "🐕", "🐎", "🐪", "🐁", "🐘", "🦘", "🦈", "🐓", "🐝", "👀", "🦴", "👩🏿", "‍🤝", "🧑", "🏾", "👱🏽", "‍♀", "🎞", "🎨", "⚽"], + ["🍕", "🍗", "🍜", "☕", "🍴", "🍉", "🍓", "🌴", "🌵", "🛺", "🚲", "🛴", "🚉", "🚀", "✈", "🛰", "🚦", "🏳", "‍🌈", "🌎", "🧭"], + ["🔥", "❄", "🌟", "🌞", "🌛", "🌝", "🌧", "🧺", "🧷", "🪒", "⛲", "🗼", "🕌", "👁", "‍🗨", "💬", "™", "💯", "🔕", "💥", "❤"] + ] + + self.emoji_buttons = [] + self.emoji_layout = QGridLayout() + self.emoji_widget = QWidget() + self.emoji_widget.setLayout(self.emoji_layout) + self.frame_2.setLayout(QVBoxLayout()) + self.frame_2.layout().addWidget(self.emoji_widget) + self.emoji_widget.hide() + self.pushButton.clicked.connect(lambda: self.emoji_widget.show()) + + for row_idx, row in enumerate(cells): + for col_idx, emoji in enumerate(row): + button = QPushButton(emoji) + button.setFixedSize(40, 40) + button.setStyleSheet(""" + QPushButton { + background-color: #ffffff; + border: 1px solid #e0e0e0; + border-radius: 5px; + } + QPushButton:hover { + background-color: #f0f0f0; + } + """) + # button.clicked.connect(lambda checked, e=emoji: self.emoji_clicked(e)) + self.emoji_layout.addWidget(button, row_idx, col_idx) + self.emoji_buttons.append(button) +if __name__ == '__main__': + app = QApplication(sys.argv) + window = MainWindow() + window.show() + sys.exit(app.exec_()) diff --git a/Emoji Dictionary/QT_GUI.ui b/Emoji Dictionary/QT_GUI.ui new file mode 100644 index 00000000000..dc87c8dbc0a --- /dev/null +++ b/Emoji Dictionary/QT_GUI.ui @@ -0,0 +1,407 @@ + + + MainWindow + + + + 0 + 0 + 948 + 527 + + + + MainWindow + + + background-color: #f0f2f5; + + + + background-color: transparent; + + + + 8 + + + 10 + + + 10 + + + 10 + + + 10 + + + + + background-color: #ffffff; + border-radius: 10px; + padding: 15px; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 30 + + + + color: #1a73e8; + padding: 10px; + + + EMOJI DICTIONARY + + + Qt::AlignCenter + + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + background-color: transparent; + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 20 + + + + color: #333333; + padding: 10px; + + + Enter any Emoji you want to search... + + + + + + + background-color: #ffffff; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + -1 + + + + QLineEdit { + border: 1px solid #dcdcdc; + border-radius: 5px; + padding: 8px; + font-size: 14px; + background-color: #fafafa; + } + QLineEdit:focus { + border-color: #1a73e8; + background-color: #ffffff; + } + + + + + + + true + + + + -1 + 62 + true + + + + QPushButton { + background-color: #1a73e8; + color: white; + border-radius: 5px; + padding: 8px; + font-size: 14px; + font-weight: 500; + } + QPushButton:hover { + background-color: #1557b0; + } + QPushButton:pressed { + background-color: #104080; + } + + + Emoji Board + + + + + + + + + + background-color: transparent; + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + -1 + 62 + true + + + + QPushButton { + background-color: #34c759; + color: white; + border-radius: 5px; + padding: 8px; + font-size: 14px; + font-weight: 500; + } + QPushButton:hover { + background-color: #2ea44f; + } + QPushButton:pressed { + background-color: #26833b; + } + + + 🔍 Search + + + + + + + + -1 + 62 + true + + + + QPushButton { + background-color: #ff3b30; + color: white; + border-radius: 5px; + padding: 8px; + font-size: 14px; + font-weight: 500; + } + QPushButton:hover { + background-color: #cc2f27; + } + QPushButton:pressed { + background-color: #99231f; + } + + + 🧹 Clear + + + + + + + + + + + + + + 0 + 0 + + + + background-color: #ffffff; + border-radius: 10px; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 16 + 50 + false + + + + color: #333333; + padding-bottom: 10px; + + + Meaning... + + + + + + + + -1 + + + + QTextEdit { + border: 1px solid #dcdcdc; + border-radius: 5px; + padding: 10px; + font-size: 14px; + background-color: #fafafa; + } + QTextEdit:focus { + border-color: #1a73e8; + background-color: #ffffff; + } + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:14px; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:20pt;"><br /></p></body></html> + + + + + + + + 140 + 40 + + + + + -1 + 62 + true + + + + QPushButton { + background-color: #ff9500; + color: white; + border-radius: 5px; + padding: 10px; + font-size: 14px; + font-weight: 500; + } + QPushButton:hover { + background-color: #cc7700; + } + QPushButton:pressed { + background-color: #995900; + } + + + EXIT + + + + + + + + + + + + From 9e91388d562fc98456eb7d34bae4216ac7b9e6b8 Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Sat, 7 Jun 2025 11:14:38 +0530 Subject: [PATCH 402/442] add emoji show and hide function --- Emoji Dictionary/QT_GUI.py | 21 +- Emoji Dictionary/untitled.ui | 406 +++++++++++++++++++++++++++++++++++ 2 files changed, 421 insertions(+), 6 deletions(-) create mode 100644 Emoji Dictionary/untitled.ui diff --git a/Emoji Dictionary/QT_GUI.py b/Emoji Dictionary/QT_GUI.py index fc6ece76e86..524b02842c4 100644 --- a/Emoji Dictionary/QT_GUI.py +++ b/Emoji Dictionary/QT_GUI.py @@ -8,18 +8,24 @@ from PyQt5 import uic class MainWindow(QMainWindow): - def __init__(self): + def __init__(self): super(MainWindow, self).__init__() # Load the UI file uic.loadUi('Emoji Dictionary/QT_GUI.ui', self) cells = [ - ["😀", "🥰", "😴", "🤓", "🤮", "🤬", "😨", "🤑", "😫", "😎"], + ["🐒", "🐕", "🐎", "🐪", "🐁", "🐘", "🦘", "🦈", "🐓", "🐝", "👀", "🦴", "👩🏿", "‍🤝", "🧑", "🏾", "👱🏽", "‍♀", "🎞", "🎨", "⚽"], ["🍕", "🍗", "🍜", "☕", "🍴", "🍉", "🍓", "🌴", "🌵", "🛺", "🚲", "🛴", "🚉", "🚀", "✈", "🛰", "🚦", "🏳", "‍🌈", "🌎", "🧭"], - ["🔥", "❄", "🌟", "🌞", "🌛", "🌝", "🌧", "🧺", "🧷", "🪒", "⛲", "🗼", "🕌", "👁", "‍🗨", "💬", "™", "💯", "🔕", "💥", "❤"] + ["🔥", "❄", "🌟", "🌞", "🌛", "🌝", "🌧", "🧺", "🧷", "🪒", "⛲", "🗼", "🕌", "👁", "‍🗨", "💬", "™", "💯", "🔕", "💥", "❤"], + ["😀", "🥰", "😴", "🤓", "🤮", "🤬", "😨", "🤑", "😫", "😎"], ] - + def emoji_wight_btn(): + if self.emoji_widget.isVisible(): + self.emoji_widget.hide() + else: + self.emoji_widget.show() + self.emoji_buttons = [] self.emoji_layout = QGridLayout() self.emoji_widget = QWidget() @@ -27,12 +33,14 @@ def __init__(self): self.frame_2.setLayout(QVBoxLayout()) self.frame_2.layout().addWidget(self.emoji_widget) self.emoji_widget.hide() - self.pushButton.clicked.connect(lambda: self.emoji_widget.show()) + self.pushButton.clicked.connect(lambda:emoji_wight_btn()) + for row_idx, row in enumerate(cells): for col_idx, emoji in enumerate(row): button = QPushButton(emoji) button.setFixedSize(40, 40) + button.setFont(QFont("Arial", 20)) button.setStyleSheet(""" QPushButton { background-color: #ffffff; @@ -45,7 +53,8 @@ def __init__(self): """) # button.clicked.connect(lambda checked, e=emoji: self.emoji_clicked(e)) self.emoji_layout.addWidget(button, row_idx, col_idx) - self.emoji_buttons.append(button) + self.emoji_buttons.append(button) + if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() diff --git a/Emoji Dictionary/untitled.ui b/Emoji Dictionary/untitled.ui new file mode 100644 index 00000000000..a6753b7dd19 --- /dev/null +++ b/Emoji Dictionary/untitled.ui @@ -0,0 +1,406 @@ + + + MainWindow + + + + 0 + 0 + 948 + 527 + + + + MainWindow + + + background-color: #f0f2f5; + + + + background-color: transparent; + + + + 8 + + + 10 + + + 10 + + + 10 + + + 10 + + + + + background-color: #ffffff; + border-radius: 10px; + padding: 15px; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 30 + + + + color: #1a73e8; + padding: 10px; + + + EMOJI DICTIONARY + + + Qt::AlignCenter + + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + background-color: transparent; + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 20 + + + + color: #333333; + padding: 10px; + + + Enter any Emoji you want to search... + + + + + + + background-color: #ffffff; +border-radius: 8px; + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + -1 + + + + QLineEdit { + border: 1px solid #dcdcdc; + border-radius: 5px; + padding: 8px; + font-size: 14px; + background-color: #fafafa; + } + QLineEdit:focus { + border-color: #1a73e8; + background-color: #ffffff; + } + + + + + + + true + + + + -1 + 62 + true + + + + QPushButton { + background-color: #1a73e8; + color: white; + border-radius: 5px; + padding: 8px; + font-size: 14px; + font-weight: 500; + } + QPushButton:hover { + background-color: #1557b0; + } + QPushButton:pressed { + background-color: #104080; + } + + + Emoji Board + + + + + + + + + + background-color: transparent; + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + -1 + 62 + true + + + + QPushButton { + background-color: #34c759; + color: white; + border-radius: 5px; + padding: 8px; + font-size: 14px; + font-weight: 500; + } + QPushButton:hover { + background-color: #2ea44f; + } + QPushButton:pressed { + background-color: #26833b; + } + + + 🔍 Search + + + + + + + + -1 + 62 + true + + + + QPushButton { + background-color: #ff3b30; + color: white; + border-radius: 5px; + padding: 8px; + font-size: 14px; + font-weight: 500; + } + QPushButton:hover { + background-color: #cc2f27; + } + QPushButton:pressed { + background-color: #99231f; + } + + + 🧹 Clear + + + + + + + + + + + + + + 0 + 0 + + + + background-color: #ffffff; + border-radius: 10px; + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 16 + 50 + false + + + + color: #333333; +padding-bottom: 10px; + + + Meaning... + + + + + + + + -1 + + + + QTextEdit { + border: 1px solid #dcdcdc; + border-radius: 5px; + padding: 10px; + font-size: 14px; + background-color: #fafafa; + } + QTextEdit:focus { + border-color: #1a73e8; + background-color: #ffffff; + } + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:14px; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:20pt;"><br /></p></body></html> + + + + + + + + 140 + 40 + + + + + -1 + 62 + true + + + + QPushButton { + background-color: #ff9500; + color: white; + border-radius: 5px; + padding: 10px; + font-size: 14px; + font-weight: 500; + } + QPushButton:hover { + background-color: #cc7700; + } + QPushButton:pressed { + background-color: #995900; + } + + + EXIT + + + + + + + + + + + + From 6c5d0547c4c119e9af8750a5e4674986a1b67765 Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Sat, 7 Jun 2025 11:40:09 +0530 Subject: [PATCH 403/442] exite btn done --- Emoji Dictionary/QT_GUI.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Emoji Dictionary/QT_GUI.py b/Emoji Dictionary/QT_GUI.py index 524b02842c4..b90aab7dce4 100644 --- a/Emoji Dictionary/QT_GUI.py +++ b/Emoji Dictionary/QT_GUI.py @@ -13,6 +13,7 @@ def __init__(self): # Load the UI file uic.loadUi('Emoji Dictionary/QT_GUI.ui', self) + self.pushButton_4.clicked.connect(self.close) cells = [ ["🐒", "🐕", "🐎", "🐪", "🐁", "🐘", "🦘", "🦈", "🐓", "🐝", "👀", "🦴", "👩🏿", "‍🤝", "🧑", "🏾", "👱🏽", "‍♀", "🎞", "🎨", "⚽"], From b82068a57bacf7cfb732153f711eec367aba8747 Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Sat, 7 Jun 2025 11:40:29 +0530 Subject: [PATCH 404/442] remove box-show and small changes --- Emoji Dictionary/QT_GUI.ui | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/Emoji Dictionary/QT_GUI.ui b/Emoji Dictionary/QT_GUI.ui index dc87c8dbc0a..fd652852ed4 100644 --- a/Emoji Dictionary/QT_GUI.ui +++ b/Emoji Dictionary/QT_GUI.ui @@ -7,7 +7,7 @@ 0 0 948 - 527 + 638 @@ -41,8 +41,7 @@ background-color: #ffffff; border-radius: 10px; - padding: 15px; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); + padding: 15px; QFrame::StyledPanel @@ -147,8 +146,7 @@ background-color: #ffffff; - border-radius: 8px; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); + border-radius: 8px; QFrame::StyledPanel @@ -161,7 +159,7 @@ - -1 + 14 @@ -186,7 +184,7 @@ - -1 + 14 62 true @@ -231,7 +229,7 @@ - -1 + 14 62 true @@ -261,7 +259,7 @@ - -1 + 14 62 true @@ -303,8 +301,7 @@ background-color: #ffffff; - border-radius: 10px; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); + border-radius: 10px; QFrame::StyledPanel @@ -335,7 +332,7 @@ - -1 + 14 @@ -370,7 +367,7 @@ p, li { white-space: pre-wrap; } - -1 + 14 62 true From b6335cd5a0601ace1a5276e8ab1186ced9c2a71c Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Sat, 7 Jun 2025 11:44:38 +0530 Subject: [PATCH 405/442] change indention and add search_emoji --- Emoji Dictionary/QT_GUI.py | 88 +++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 40 deletions(-) diff --git a/Emoji Dictionary/QT_GUI.py b/Emoji Dictionary/QT_GUI.py index b90aab7dce4..711b7a71f33 100644 --- a/Emoji Dictionary/QT_GUI.py +++ b/Emoji Dictionary/QT_GUI.py @@ -9,52 +9,60 @@ class MainWindow(QMainWindow): def __init__(self): - super(MainWindow, self).__init__() + super(MainWindow, self).__init__() - # Load the UI file - uic.loadUi('Emoji Dictionary/QT_GUI.ui', self) - self.pushButton_4.clicked.connect(self.close) - cells = [ - - ["🐒", "🐕", "🐎", "🐪", "🐁", "🐘", "🦘", "🦈", "🐓", "🐝", "👀", "🦴", "👩🏿", "‍🤝", "🧑", "🏾", "👱🏽", "‍♀", "🎞", "🎨", "⚽"], - ["🍕", "🍗", "🍜", "☕", "🍴", "🍉", "🍓", "🌴", "🌵", "🛺", "🚲", "🛴", "🚉", "🚀", "✈", "🛰", "🚦", "🏳", "‍🌈", "🌎", "🧭"], - ["🔥", "❄", "🌟", "🌞", "🌛", "🌝", "🌧", "🧺", "🧷", "🪒", "⛲", "🗼", "🕌", "👁", "‍🗨", "💬", "™", "💯", "🔕", "💥", "❤"], - ["😀", "🥰", "😴", "🤓", "🤮", "🤬", "😨", "🤑", "😫", "😎"], - ] - def emoji_wight_btn(): + # Load the UI file + uic.loadUi('Emoji Dictionary/QT_GUI.ui', self) + self.pushButton_4.clicked.connect(self.close) + cells = [ + + ["🐒", "🐕", "🐎", "🐪", "🐁", "🐘", "🦘", "🦈", "🐓", "🐝", "👀", "🦴", "👩🏿", "‍🤝", "🧑", "🏾", "👱🏽", "‍♀", "🎞", "🎨", "⚽"], + ["🍕", "🍗", "🍜", "☕", "🍴", "🍉", "🍓", "🌴", "🌵", "🛺", "🚲", "🛴", "🚉", "🚀", "✈", "🛰", "🚦", "🏳", "‍🌈", "🌎", "🧭"], + ["🔥", "❄", "🌟", "🌞", "🌛", "🌝", "🌧", "🧺", "🧷", "🪒", "⛲", "🗼", "🕌", "👁", "‍🗨", "💬", "™", "💯", "🔕", "💥", "❤"], + ["😀", "🥰", "😴", "🤓", "🤮", "🤬", "😨", "🤑", "😫", "😎"], + ] + def emoji_wight_btn(): if self.emoji_widget.isVisible(): self.emoji_widget.hide() else: self.emoji_widget.show() + + def search_emoji(): + word = self.lineEdit.text() + if word == "": + self.textEdit.setText("You have entered no emoji.") + else: + means = emoji.demojize(word) + self.textEdit.setText("Meaning of Emoji : " + str(word) + "\n\n" + means) - self.emoji_buttons = [] - self.emoji_layout = QGridLayout() - self.emoji_widget = QWidget() - self.emoji_widget.setLayout(self.emoji_layout) - self.frame_2.setLayout(QVBoxLayout()) - self.frame_2.layout().addWidget(self.emoji_widget) - self.emoji_widget.hide() - self.pushButton.clicked.connect(lambda:emoji_wight_btn()) - - - for row_idx, row in enumerate(cells): - for col_idx, emoji in enumerate(row): - button = QPushButton(emoji) - button.setFixedSize(40, 40) - button.setFont(QFont("Arial", 20)) - button.setStyleSheet(""" - QPushButton { - background-color: #ffffff; - border: 1px solid #e0e0e0; - border-radius: 5px; - } - QPushButton:hover { - background-color: #f0f0f0; - } - """) - # button.clicked.connect(lambda checked, e=emoji: self.emoji_clicked(e)) - self.emoji_layout.addWidget(button, row_idx, col_idx) - self.emoji_buttons.append(button) + self.emoji_buttons = [] + self.emoji_layout = QGridLayout() + self.emoji_widget = QWidget() + self.emoji_widget.setLayout(self.emoji_layout) + self.frame_2.setLayout(QVBoxLayout()) + self.frame_2.layout().addWidget(self.emoji_widget) + self.emoji_widget.hide() + self.pushButton.clicked.connect(lambda:emoji_wight_btn()) + + + for row_idx, row in enumerate(cells): + for col_idx, emoji in enumerate(row): + button = QPushButton(emoji) + button.setFixedSize(40, 40) + button.setFont(QFont("Arial", 20)) + button.setStyleSheet(""" + QPushButton { + background-color: #ffffff; + border: 1px solid #e0e0e0; + border-radius: 5px; + } + QPushButton:hover { + background-color: #f0f0f0; + } + """) + # button.clicked.connect(lambda checked, e=emoji: self.emoji_clicked(e)) + self.emoji_layout.addWidget(button, row_idx, col_idx) + self.emoji_buttons.append(button) if __name__ == '__main__': app = QApplication(sys.argv) From 7b2330bf1257f02053c65485df6385efed26b48d Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Sat, 7 Jun 2025 12:24:44 +0530 Subject: [PATCH 406/442] all logic done --- Emoji Dictionary/QT_GUI.py | 22 +++++++++++++++++----- Emoji Dictionary/QT_GUI.ui | 25 ++++++++++++++++--------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/Emoji Dictionary/QT_GUI.py b/Emoji Dictionary/QT_GUI.py index 711b7a71f33..92e0f6d4aca 100644 --- a/Emoji Dictionary/QT_GUI.py +++ b/Emoji Dictionary/QT_GUI.py @@ -6,14 +6,18 @@ from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5 import uic +from emoji import demojize +import os class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() # Load the UI file - uic.loadUi('Emoji Dictionary/QT_GUI.ui', self) + uic.loadUi(os.path.join(os.path.dirname(__file__),'QT_GUI.ui'),self) self.pushButton_4.clicked.connect(self.close) + self.pushButton_2.clicked.connect(lambda:search_emoji()) + self.pushButton_3.clicked.connect(lambda:clear_text()) cells = [ ["🐒", "🐕", "🐎", "🐪", "🐁", "🐘", "🦘", "🦈", "🐓", "🐝", "👀", "🦴", "👩🏿", "‍🤝", "🧑", "🏾", "👱🏽", "‍♀", "🎞", "🎨", "⚽"], @@ -28,12 +32,20 @@ def emoji_wight_btn(): self.emoji_widget.show() def search_emoji(): - word = self.lineEdit.text() + word = self.lineEdit.text() + print(f"Field Text: {word}") if word == "": self.textEdit.setText("You have entered no emoji.") else: - means = emoji.demojize(word) - self.textEdit.setText("Meaning of Emoji : " + str(word) + "\n\n" + means) + means = demojize(word) + self.textEdit.setText("Meaning of Emoji : " + str(word) + "\n\n" + means.replace("::", ":\n: ")) + + def add_input_emoji(emoji): + self.lineEdit.setText(self.lineEdit.text() + emoji) + + def clear_text(): + self.lineEdit.setText("") + self.textEdit.setText("") self.emoji_buttons = [] self.emoji_layout = QGridLayout() @@ -60,7 +72,7 @@ def search_emoji(): background-color: #f0f0f0; } """) - # button.clicked.connect(lambda checked, e=emoji: self.emoji_clicked(e)) + button.clicked.connect(lambda checked, e=emoji: add_input_emoji(e)) self.emoji_layout.addWidget(button, row_idx, col_idx) self.emoji_buttons.append(button) diff --git a/Emoji Dictionary/QT_GUI.ui b/Emoji Dictionary/QT_GUI.ui index fd652852ed4..6a50a3f0071 100644 --- a/Emoji Dictionary/QT_GUI.ui +++ b/Emoji Dictionary/QT_GUI.ui @@ -6,7 +6,7 @@ 0 0 - 948 + 944 638 @@ -159,7 +159,9 @@ - 14 + -1 + 50 + false @@ -175,6 +177,9 @@ background-color: #ffffff; } + + + @@ -184,7 +189,7 @@ - 14 + -1 62 true @@ -229,7 +234,7 @@ - 14 + -1 62 true @@ -259,7 +264,7 @@ - 14 + -1 62 true @@ -332,11 +337,13 @@ - 14 + -1 - QTextEdit { + + +QTextEdit { border: 1px solid #dcdcdc; border-radius: 5px; padding: 10px; @@ -353,7 +360,7 @@ <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:14px; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:20pt;"><br /></p></body></html> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:7.8pt;"><br /></p></body></html> @@ -367,7 +374,7 @@ p, li { white-space: pre-wrap; } - 14 + -1 62 true From f9229b05b70ae2896afd1ff91daabf484d6ac615 Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Sat, 7 Jun 2025 12:29:04 +0530 Subject: [PATCH 407/442] remove part that cause warning msg --- Emoji Dictionary/QT_GUI.py | 1 - Emoji Dictionary/QT_GUI.ui | 12 ++++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Emoji Dictionary/QT_GUI.py b/Emoji Dictionary/QT_GUI.py index 92e0f6d4aca..a4dd819ccb8 100644 --- a/Emoji Dictionary/QT_GUI.py +++ b/Emoji Dictionary/QT_GUI.py @@ -51,7 +51,6 @@ def clear_text(): self.emoji_layout = QGridLayout() self.emoji_widget = QWidget() self.emoji_widget.setLayout(self.emoji_layout) - self.frame_2.setLayout(QVBoxLayout()) self.frame_2.layout().addWidget(self.emoji_widget) self.emoji_widget.hide() self.pushButton.clicked.connect(lambda:emoji_wight_btn()) diff --git a/Emoji Dictionary/QT_GUI.ui b/Emoji Dictionary/QT_GUI.ui index 6a50a3f0071..49267698e80 100644 --- a/Emoji Dictionary/QT_GUI.ui +++ b/Emoji Dictionary/QT_GUI.ui @@ -159,7 +159,7 @@ - -1 + 14 50 false @@ -189,7 +189,7 @@ - -1 + 14 62 true @@ -234,7 +234,7 @@ - -1 + 14 62 true @@ -264,7 +264,7 @@ - -1 + 14 62 true @@ -337,7 +337,7 @@ - -1 + 14 @@ -374,7 +374,7 @@ p, li { white-space: pre-wrap; } - -1 + 14 62 true From 84aa948f0b2962804eb8c2c05bcdfad18db1cf94 Mon Sep 17 00:00:00 2001 From: lighting9999 <120090117+lighting9999@users.noreply.github.com> Date: Sat, 7 Jun 2025 16:11:52 +0800 Subject: [PATCH 408/442] fix passwordGen.py --- passwordGen.py | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/passwordGen.py b/passwordGen.py index 357c14619fc..b05990decc2 100644 --- a/passwordGen.py +++ b/passwordGen.py @@ -5,25 +5,22 @@ digits = "1234567890" specialChars = "!@#$%^&*-_+=" -passLen = 10 # actual generated password length will be this length + 1 myPass = "" -for i in range(passLen): - while (len(myPass)) <= 2: - index = random.randrange(len(lChars)) - myPass = myPass + lChars[index] - myPassLen = len(myPass) - while (len(myPass)) <= 5: - index = random.randrange(len(digits)) - myPass = myPass + digits[index] - myPassLen = len(myPass) - while (len(myPass)) <= 7: - index = random.randrange(len(specialChars)) - myPass = myPass + specialChars[index] - myPassLen = len(myPass) - while (len(myPass)) <= 10: - index = random.randrange(len(uChars)) - myPass = myPass + uChars[index] - myPassLen = len(myPass) +# Generate 3 lowercase letters +for _ in range(3): + myPass += random.choice(lChars) -print(myPass) +# Generate 3 digits +for _ in range(3): + myPass += random.choice(digits) + +# Generate 2 special characters +for _ in range(2): + myPass += random.choice(specialChars) + +# Generate 2 uppercase letters +for _ in range(2): + myPass += random.choice(uChars) + +print(myPass) # Output: 10-character password (e.g. "abc123!@AB") From cecb779c09c0a36ba76f4f38c2bd868bd8233c4b Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Sat, 7 Jun 2025 17:12:11 +0530 Subject: [PATCH 409/442] update style of GUI I have change style of all component in this GUI. Now it look like modern UI --- currency converter/gui.ui | 111 ++++++++++++++++++++++++++++++++++---- 1 file changed, 101 insertions(+), 10 deletions(-) diff --git a/currency converter/gui.ui b/currency converter/gui.ui index 6c8e578fc95..a2b39c9e6a4 100644 --- a/currency converter/gui.ui +++ b/currency converter/gui.ui @@ -6,13 +6,101 @@ 0 0 - 794 - 365 + 785 + 362 MainWindow + + QMainWindow { + background-color: #2C2F33; + } + QLabel#label { + color: #FFFFFF; + font-family: 'Arial'; + font-size: 28px; + font-weight: bold; + background-color: transparent; + padding: 10px; + } + QLabel#label_2, QLabel#label_3 { + color: #7289DA; + font-family: 'Arial'; + font-size: 20px; + font-weight: normal; + background-color: transparent; + } + QComboBox { + background-color: #23272A; + color: #FFFFFF; + font-family: 'Arial'; + font-size: 16px; + border-radius: 10px; + padding: 10px; + border: 1px solid #7289DA; + } + QComboBox:hover { + border: 1px solid #677BC4; + } + QComboBox::drop-down { + border: none; + width: 20px; + } + QComboBox::down-arrow { + image: url(http://github.com/:/icons/down_arrow.png); + width: 12px; + height: 12px; + } + QComboBox QAbstractItemView { + background-color: #23272A; + color: #FFFFFF; + selection-background-color: #7289DA; + selection-color: #FFFFFF; + border: 1px solid #7289DA; + border-radius: 5px; + } + QLineEdit { + background-color: #23272A; + color: #FFFFFF; + font-family: 'Arial'; + font-size: 20px; + border-radius: 10px; + padding: 10px; + border: 1px solid #7289DA; + } + QLineEdit:hover, QLineEdit:focus { + border: 1px solid #677BC4; + } + QPushButton { + background-color: #7289DA; + color: #FFFFFF; + font-family: 'Arial'; + font-size: 16px; + font-weight: bold; + border-radius: 10px; + padding: 10px; + border: none; + } + QPushButton:hover { + background-color: #677BC4; + } + QPushButton:pressed { + background-color: #5B6EAE; + } + QLCDNumber { + background-color: #23272A; + color: #43B581; + border-radius: 10px; + border: 1px solid #7289DA; + padding: 10px; + } + QStatusBar { + background-color: #23272A; + color: #FFFFFF; + } + @@ -25,8 +113,8 @@ - Segoe Script - 24 + Arial + -1 75 true @@ -61,7 +149,7 @@ - 110 + 100 260 571 41 @@ -92,9 +180,11 @@ - Monotype Corsiva - 20 + Arial + -1 + 50 true + false @@ -112,9 +202,11 @@ - Monotype Corsiva - 20 + Arial + -1 + 50 true + false @@ -132,7 +224,6 @@ - From b5e1a1676b2c51fe7ff1f5244a09e4f8d0a2e7bf Mon Sep 17 00:00:00 2001 From: ivanho-git Date: Sun, 8 Jun 2025 00:03:25 +0530 Subject: [PATCH 410/442] Update passwordGenerator.py --- .../passwordGenerator.py | 164 +++++------------- 1 file changed, 44 insertions(+), 120 deletions(-) diff --git a/password_programs_multiple/passwordGenerator.py b/password_programs_multiple/passwordGenerator.py index 1bde3d18051..d1a76773e62 100644 --- a/password_programs_multiple/passwordGenerator.py +++ b/password_programs_multiple/passwordGenerator.py @@ -1,125 +1,49 @@ # PasswordGenerator GGearing 314 01/10/19 # modified Prince Gangurde 4/4/2020 -from random import randint +import random import pycountry -case = randint(1, 2) -number = randint(1, 999) - -# TODO: Pick random country from it - -countries = list(pycountry.countries) -country_names = [country.name for country in countries] - -print(country_names) - -# TODO: Try to add languages, too. - -specialCharacters = ( - "!", - "@", - "#", - "$", - "%", - "/", - "?", - ":", - "<", - ">", - "|", - "&", - "*", - "-", - "=", - "+", - "_", -) - -animals = ( - "ant", - "alligator", - "baboon", - "badger", - "barb", - "bat", - "beagle", - "bear", - "beaver", - "bird", - "bison", - "bombay", - "bongo", - "booby", - "butterfly", - "bee", - "camel", - "cat", - "caterpillar", - "catfish", - "cheetah", - "chicken", - "chipmunk", - "cow", - "crab", - "deer", - "dingo", - "dodo", - "dog", - "dolphin", - "donkey", - "duck", - "eagle", - "earwig", - "elephant", - "emu", - "falcon", - "ferret", - "fish", - "flamingo", - "fly", - "fox", - "frog", - "gecko", - "gibbon", - "giraffe", - "goat", - "goose", - "gorilla", -) - -colour = ( - "red", - "orange", - "yellow", - "green", - "blue", - "indigo", - "violet", - "purple", - "magenta", - "cyan", - "pink", - "brown", - "white", - "grey", - "black", -) - -chosenanimal = animals[ - randint(0, len(animals) - 1) -] # randint will return max lenght but , tuple has index from 0 to len-1 -chosencolour = colour[randint(0, len(colour) - 1)] -chosenSpecialCharacter = specialCharacters[randint(0, len(specialCharacters) - 1)] - -if case == 1: - chosenanimal = chosenanimal.upper() - print(chosencolour + str(number) + chosenanimal + chosenSpecialCharacter) -else: - chosencolour = chosencolour.upper() - print(chosenanimal + str(number) + chosencolour + chosenSpecialCharacter) - -# Try to consolidate unify the characters. - - -# The program can be further improved. +def generate_password(): + # Define characters and word sets + special_characters = list("!@#$%/?<>|&*-=+_") + + animals = ( + "ant", "alligator", "baboon", "badger", "barb", "bat", "beagle", "bear", "beaver", "bird", + "bison", "bombay", "bongo", "booby", "butterfly", "bee", "camel", "cat", "caterpillar", + "catfish", "cheetah", "chicken", "chipmunk", "cow", "crab", "deer", "dingo", "dodo", "dog", + "dolphin", "donkey", "duck", "eagle", "earwig", "elephant", "emu", "falcon", "ferret", "fish", + "flamingo", "fly", "fox", "frog", "gecko", "gibbon", "giraffe", "goat", "goose", "gorilla" + ) + + colours = ( + "red", "orange", "yellow", "green", "blue", "indigo", "violet", "purple", + "magenta", "cyan", "pink", "brown", "white", "grey", "black" + ) + + # Get random values + animal = random.choice(animals) + colour = random.choice(colours) + number = random.randint(1, 999) + special = random.choice(special_characters) + case_choice = random.choice(["upper_colour", "upper_animal"]) + + # Pick a random country and language + country = random.choice(list(pycountry.countries)).name + languages = [lang.name for lang in pycountry.languages if hasattr(lang, "name")] + language = random.choice(languages) + + # Apply casing + if case_choice == "upper_colour": + colour = colour.upper() + else: + animal = animal.upper() + + # Combine to form password + password = f"{colour}{number}{animal}{special}" + print("Generated Password:", password) + print("Based on Country:", country) + print("Language Hint:", language) + +# Run it +generate_password() From edc215d9d3295416612dbe740af32cd01224cbce Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Mon, 9 Jun 2025 12:59:22 +0530 Subject: [PATCH 411/442] show employee list part done --- bank_managment_system/QTFrontend.py | 80 +++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 443276df1fe..d114a32347b 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -382,6 +382,86 @@ def create_add_employee_page(parent, title, submit_text="Submit",update_btn:bool return page, name_edit, password_edit, salary_edit, position_edit, update_button else: return page, name_edit, password_edit, salary_edit, position_edit, submit_button # Unpack as name_edit, password_edit, etc. + +def show_employee_list_page(parent, title): + page, main_layout = create_page_with_header(parent, title) + + content_frame = create_styled_frame(page, style="background-color: #f9f9f9; border-radius: 10px; padding: 15px;") + content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_layout = QtWidgets.QVBoxLayout(content_frame) + + # Table frame + table_frame = create_styled_frame(content_frame, style="background-color: #ffffff; border-radius: 8px; padding: 10px;") + table_layout = QtWidgets.QVBoxLayout(table_frame) + table_layout.setSpacing(0) + + # Header row + header_frame = create_styled_frame(table_frame, style="background-color: #f5f5f5; ; border-radius: 8px 8px 0 0; padding: 10px;") + header_layout = QtWidgets.QHBoxLayout(header_frame) + header_layout.setContentsMargins(10, 5, 10, 5) + headers = ["Name", "Position", "Salary"] + for i, header in enumerate(headers): + header_label = QtWidgets.QLabel(header, header_frame) + header_label.setStyleSheet("font-weight: bold; font-size: 14px; color: #333333; padding: 0px; margin: 0px;") + if i == 2: # Right-align salary header + header_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) + else: + header_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) + header_layout.addWidget(header_label, 1 if i < 2 else 0) # Stretch name and position, not salary + table_layout.addWidget(header_frame) + + # Employee rows + employees = backend.show_employees_for_update() + for row, employee in enumerate(employees): + row_frame = create_styled_frame(table_frame, style=f"background-color: {'#fafafa' if row % 2 else '#ffffff'}; padding: 8px;") + row_layout = QtWidgets.QHBoxLayout(row_frame) + row_layout.setContentsMargins(10, 5, 10, 5) + + # Name + name_label = QtWidgets.QLabel(employee[0], row_frame) + name_label.setStyleSheet("font-size: 14px; color: #333333; padding: 0px; margin: 0px;") + name_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) + row_layout.addWidget(name_label, 1) + + # Position + position_label = QtWidgets.QLabel(employee[3], row_frame) + position_label.setStyleSheet("font-size: 14px; color: #333333; padding: 0px; margin: 0px;") + position_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) + row_layout.addWidget(position_label, 1) + + # Salary (formatted as currency) + salary_label = QtWidgets.QLabel(f"${float(employee[2]):,.2f}", row_frame) + salary_label.setStyleSheet("font-size: 14px; color: #333333; padding: 0px; margin: 0px;") + salary_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) + row_layout.addWidget(salary_label, 0) + + table_layout.addWidget(row_frame) + + # Add stretch to prevent rows from expanding vertically + table_layout.addStretch() + + # Back button + back_button = QtWidgets.QPushButton("Back", content_frame) + back_button.setStyleSheet(""" + QPushButton { + background-color: #6c757d; + color: white; + border: none; + border-radius: 4px; + padding: 8px 16px; + font-size: 14px; + } + QPushButton:hover { + background-color: #5a6268; + } + """) + back_button.clicked.connect(lambda: parent.setCurrentIndex(3)) + + content_layout.addWidget(table_frame) + main_layout.addWidget(back_button, alignment=QtCore.Qt.AlignLeft) + main_layout.addWidget(content_frame) + + return page def setup_main_window(main_window): """Set up the main window with a stacked widget containing home, admin, and employee pages.""" From e1a26bf457bec5325158df76ce6d81517b2bd63d Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Mon, 9 Jun 2025 13:00:06 +0530 Subject: [PATCH 412/442] small change related show employe list and other --- bank_managment_system/QTFrontend.py | 37 +++++++++++++++++++---------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index d114a32347b..30f6cd653ee 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -342,7 +342,7 @@ def create_add_employee_page(parent, title, submit_text="Submit",update_btn:bool form_frame = create_styled_frame(content_frame, min_size=(340, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") form_layout = QtWidgets.QVBoxLayout(form_frame) - form_layout.setSpacing(20) + form_layout.setSpacing(10) # Define input fields fields = ["Name :", "Password :", "Salary :", "Position :"] @@ -378,6 +378,22 @@ def create_add_employee_page(parent, title, submit_text="Submit",update_btn:bool form_layout.addWidget(button_frame) content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) main_layout.addWidget(content_frame) + back_btn = QtWidgets.QPushButton("Back", content_frame) + back_btn.setStyleSheet(""" + QPushButton { + background-color: #6c757d; + color: white; + border: none; + border-radius: 4px; + padding: 8px 16px; + font-size: 14px; + } + QPushButton:hover { + background-color: #5a6268; + } + """) + back_btn.clicked.connect(lambda: parent.setCurrentIndex(3)) + main_layout.addWidget(back_btn, 0,alignment=QtCore.Qt.AlignLeft) if update_btn: return page, name_edit, password_edit, salary_edit, position_edit, update_button else: @@ -526,15 +542,6 @@ def update_employee_data(name, password, salary, position, name_to_update): except: show_popup_message(stacked_widget,"Please fill in all fields",3) - def fetch_employee_data(name): - try: - cur = backend.cur - cur.execute("SELECT * FROM staff WHERE name = ?", (name,)) - employee_data = cur.fetchone() - return employee_data - except: - print("Error fetching employee data") - return None # Create Home Page @@ -570,7 +577,7 @@ def fetch_employee_data(name): add_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(4)) update_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(5)) - + list_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(7)) # Create Add Employee Page add_employee_page, emp_name, emp_password, emp_salary, emp_position, emp_submit = create_add_employee_page( stacked_widget, @@ -648,7 +655,9 @@ def update_employee_data(name, password, salary, position, name_to_update): emp_position.text() ) ) - + # show employee list page + employee_list_page = show_employee_list_page(stacked_widget,"Employee List") + # Create Employee Login Page employee_page, employee_name, employee_password, employee_submit = create_login_page( stacked_widget, @@ -664,12 +673,14 @@ def update_employee_data(name, password, salary, position, name_to_update): stacked_widget.addWidget(add_employee_page)#4 stacked_widget.addWidget(update_employee_page1)#5 stacked_widget.addWidget(update_employee_page2)#6 + stacked_widget.addWidget(employee_list_page)#7 + main_layout.addWidget(stacked_widget) main_window.setCentralWidget(central_widget) # Set initial page - stacked_widget.setCurrentIndex(5) + stacked_widget.setCurrentIndex(3) return stacked_widget, { "admin_name": admin_name, From f1381aa84f3a433fbb713d1e8e830241a42dcb0d Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Mon, 9 Jun 2025 18:26:59 +0530 Subject: [PATCH 413/442] add total money page in admin side --- bank_managment_system/QTFrontend.py | 38 +++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 30f6cd653ee..4253d186615 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -478,6 +478,37 @@ def show_employee_list_page(parent, title): main_layout.addWidget(content_frame) return page +def show_total_money(parent, title): + page, main_layout = create_page_with_header(parent, title) + + content_frame = create_styled_frame(page, style="background-color: #f9f9f9; border-radius: 10px; padding: 15px;") + content_layout = QtWidgets.QVBoxLayout(content_frame) + content_layout.setProperty("spacing", 10) + all = backend.all_money() + + # Total money label + total_money_label = QtWidgets.QLabel(f"Total Money: ${all}", content_frame) + total_money_label.setStyleSheet("font-size: 24px; font-weight: bold; color: #333333;") + content_layout.addWidget(total_money_label, alignment=QtCore.Qt.AlignCenter) + # Back button + back_button = QtWidgets.QPushButton("Back", content_frame) + back_button.setStyleSheet(""" + QPushButton { + background-color: #6c757d; + color: white; + border: none; + border-radius: 4px; + padding: 8px 16px; + font-size: 14px; + } + QPushButton:hover { + background-color: #5a6268; + } + """) + back_button.clicked.connect(lambda: parent.setCurrentIndex(3)) + content_layout.addWidget(back_button, alignment=QtCore.Qt.AlignCenter) + main_layout.addWidget(content_frame) + return page def setup_main_window(main_window): """Set up the main window with a stacked widget containing home, admin, and employee pages.""" @@ -578,6 +609,8 @@ def update_employee_data(name, password, salary, position, name_to_update): add_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(4)) update_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(5)) list_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(7)) + back_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(0)) + money_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(8)) # Create Add Employee Page add_employee_page, emp_name, emp_password, emp_salary, emp_position, emp_submit = create_add_employee_page( stacked_widget, @@ -645,7 +678,6 @@ def update_employee_data(name, password, salary, position, name_to_update): ) ) - emp_submit.clicked.connect( lambda: add_employee_form_submit( @@ -663,7 +695,7 @@ def update_employee_data(name, password, salary, position, name_to_update): stacked_widget, title="Employee Login" ) - + admin_total_money = show_total_money(stacked_widget,"Total Money") # Add pages to stacked widget stacked_widget.addWidget(home_page)#0 @@ -674,6 +706,8 @@ def update_employee_data(name, password, salary, position, name_to_update): stacked_widget.addWidget(update_employee_page1)#5 stacked_widget.addWidget(update_employee_page2)#6 stacked_widget.addWidget(employee_list_page)#7 + stacked_widget.addWidget(admin_total_money)#8 + main_layout.addWidget(stacked_widget) From 80adbb66a06b2c7da63a816f777ed38990eb0f85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 18:11:39 +0000 Subject: [PATCH 414/442] Bump twilio from 9.6.1 to 9.6.2 Bumps [twilio](https://github.com/twilio/twilio-python) from 9.6.1 to 9.6.2. - [Release notes](https://github.com/twilio/twilio-python/releases) - [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md) - [Commits](https://github.com/twilio/twilio-python/compare/9.6.1...9.6.2) --- updated-dependencies: - dependency-name: twilio dependency-version: 9.6.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 3127185a39a..4ab52770927 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -28,7 +28,7 @@ requests==2.32.3 quo==2023.5.1 PyPDF2==3.0.1 pyserial==3.5 -twilio==9.6.1 +twilio==9.6.2 tabula==1.0.5 nltk==3.9.1 Pillow==11.2.1 From 88725ede4293510c0fb0745b1e0a2e7169c4cd85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 18:17:40 +0000 Subject: [PATCH 415/442] Bump protobuf from 6.30.2 to 6.31.1 Bumps [protobuf](https://github.com/protocolbuffers/protobuf) from 6.30.2 to 6.31.1. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v6.30.2...v6.31.1) --- updated-dependencies: - dependency-name: protobuf dependency-version: 6.31.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 3127185a39a..e2d2632f022 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -105,7 +105,7 @@ psutil==7.0.0 mediapipe==0.10.21 rich==14.0.0 httplib2==0.22.0 -protobuf==6.30.2 +protobuf==6.31.1 colorama==0.4.6 plyer==2.1.0 Flask-Ask==0.9.8 From 2e8061834ecf19716250efdd6d6af30892ed2af5 Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Tue, 10 Jun 2025 12:35:55 +0530 Subject: [PATCH 416/442] re organize pages and name change --- bank_managment_system/QTFrontend.py | 112 ++++++++++++++++------------ 1 file changed, 66 insertions(+), 46 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 4253d186615..f83449f0d41 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -4,6 +4,20 @@ import backend backend.connect_database() employee_data = None +# Page Constants (for reference) +HOME_PAGE = 0 +ADMIN_PAGE = 1 +EMPLOYEE_PAGE = 2 +ADMIN_MENU_PAGE = 3 +ADD_EMPLOYEE_PAGE = 4 +UPDATE_EMPLOYEE_PAGE1 = 5 +UPDATE_EMPLOYEE_PAGE2 = 6 +EMPLOYEE_LIST_PAGE = 7 +ADMIN_TOTAL_MONEY = 8 +# ------------------------------------------------------------------------------------------------------------- +# === Reusable UI Component Functions === +# ------------------------------------------------------------------------------------------------------------- + def create_styled_frame(parent, min_size=None, style=""): """Create a styled QFrame with optional minimum size and custom style.""" frame = QtWidgets.QFrame(parent) @@ -133,7 +147,23 @@ def on_reject(): button_box.rejected.connect(on_reject) dialog.exec_() +# ------------------------------------------------------------------------------------------------------------- +# === Page Creation Functions == +# ------------------------------------------------------------------------------------------------------------- +def create_page_with_header(parent, title_text): + """Create a page with a styled header and return the page + main layout.""" + page = QtWidgets.QWidget(parent) + main_layout = QtWidgets.QVBoxLayout(page) + main_layout.setContentsMargins(20, 20, 20, 20) + main_layout.setSpacing(20) + header_frame = create_styled_frame(page, style="background-color: #ffffff; border-radius: 10px; padding: 10px;") + header_layout = QtWidgets.QVBoxLayout(header_frame) + title_label = create_styled_label(header_frame, title_text, font_size=30) + header_layout.addWidget(title_label, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop) + + main_layout.addWidget(header_frame, 0, QtCore.Qt.AlignTop) + return page, main_layout def get_employee_name(parent, name_field_text="Enter Employee Name"): page, main_layout = create_page_with_header(parent, "Employee Data Update") @@ -170,7 +200,7 @@ def on_search_button_clicked(): cur.execute("SELECT * FROM staff WHERE name = ?", (entered_name,)) employee_data = cur.fetchone() print(f"Employee Data: {employee_data}") - parent.setCurrentIndex(6) + parent.setCurrentIndex(UPDATE_EMPLOYEE_PAGE2) # if employee_data: # QtWidgets.QMessageBox.information(parent, "Employee Found", @@ -191,7 +221,7 @@ def on_search_button_clicked(): def create_login_page(parent ,title, name_field_text="Name :", password_field_text="Password :", submit_text="Submit",): """Create a login page with a title, name and password fields, and a submit button.""" - page, main_layout = create_page_with_header(parent, "Admin Menu") + page, main_layout = create_page_with_header(parent, title) # Content frame content_frame = create_styled_frame(page) @@ -293,21 +323,6 @@ def create_home_page(parent, on_admin_clicked, on_employee_clicked, on_exit_clic return page -def create_page_with_header(parent, title_text): - """Create a page with a styled header and return the page + main layout.""" - page = QtWidgets.QWidget(parent) - main_layout = QtWidgets.QVBoxLayout(page) - main_layout.setContentsMargins(20, 20, 20, 20) - main_layout.setSpacing(20) - - header_frame = create_styled_frame(page, style="background-color: #ffffff; border-radius: 10px; padding: 10px;") - header_layout = QtWidgets.QVBoxLayout(header_frame) - title_label = create_styled_label(header_frame, title_text, font_size=30) - header_layout.addWidget(title_label, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop) - - main_layout.addWidget(header_frame, 0, QtCore.Qt.AlignTop) - return page, main_layout - def create_admin_menu_page(parent): page, main_layout = create_page_with_header(parent, "Admin Menu") @@ -392,7 +407,7 @@ def create_add_employee_page(parent, title, submit_text="Submit",update_btn:bool background-color: #5a6268; } """) - back_btn.clicked.connect(lambda: parent.setCurrentIndex(3)) + back_btn.clicked.connect(lambda: parent.setCurrentIndex(ADMIN_MENU_PAGE)) main_layout.addWidget(back_btn, 0,alignment=QtCore.Qt.AlignLeft) if update_btn: return page, name_edit, password_edit, salary_edit, position_edit, update_button @@ -471,7 +486,7 @@ def show_employee_list_page(parent, title): background-color: #5a6268; } """) - back_button.clicked.connect(lambda: parent.setCurrentIndex(3)) + back_button.clicked.connect(lambda: parent.setCurrentIndex(ADMIN_MENU_PAGE)) content_layout.addWidget(table_frame) main_layout.addWidget(back_button, alignment=QtCore.Qt.AlignLeft) @@ -505,10 +520,14 @@ def show_total_money(parent, title): background-color: #5a6268; } """) - back_button.clicked.connect(lambda: parent.setCurrentIndex(3)) + back_button.clicked.connect(lambda: parent.setCurrentIndex(ADMIN_MENU_PAGE)) content_layout.addWidget(back_button, alignment=QtCore.Qt.AlignCenter) main_layout.addWidget(content_frame) return page + +# ------------------------------------------------------------------------------------------------------------- +# === Main Window Setup === +# ------------------------------------------------------------------------------------------------------------- def setup_main_window(main_window): """Set up the main window with a stacked widget containing home, admin, and employee pages.""" @@ -523,10 +542,10 @@ def setup_main_window(main_window): # Create pages def switch_to_admin(): - stacked_widget.setCurrentIndex(1) + stacked_widget.setCurrentIndex(ADMIN_PAGE) def switch_to_employee(): - stacked_widget.setCurrentIndex(2) + stacked_widget.setCurrentIndex(EMPLOYEE_PAGE) def exit_app(): QtWidgets.QApplication.quit() @@ -537,7 +556,7 @@ def admin_login_menu_page(name, password): success = backend.check_admin(name, password) if success: QtWidgets.QMessageBox.information(stacked_widget, "Login Successful", f"Welcome, {name}!") - stacked_widget.setCurrentIndex(3) + stacked_widget.setCurrentIndex(ADMIN_MENU_PAGE) else: QtWidgets.QMessageBox.warning(stacked_widget, "Login Failed", "Incorrect name or password.") except Exception as e: @@ -606,11 +625,11 @@ def update_employee_data(name, password, salary, position, name_to_update): stacked_widget ) - add_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(4)) - update_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(5)) - list_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(7)) - back_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(0)) - money_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(8)) + add_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(ADD_EMPLOYEE_PAGE)) + update_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(UPDATE_EMPLOYEE_PAGE)) + list_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_LIST_PAGE)) + back_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(HOME_PAGE)) + money_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(ADMIN_TOTAL_MONEY)) # Create Add Employee Page add_employee_page, emp_name, emp_password, emp_salary, emp_position, emp_submit = create_add_employee_page( stacked_widget, @@ -618,25 +637,25 @@ def update_employee_data(name, password, salary, position, name_to_update): ) # Update Employee Page - update_employee_page1 = get_employee_name(stacked_widget) + u_employee_page1 = get_employee_name(stacked_widget) # apply the update_employee_data function to the submit button - update_employee_page2 ,update_employee_name, update_employee_password, update_employee_salary, update_employee_position,update_employee_update = create_add_employee_page(stacked_widget,"Update Employee Details",update_btn=True) + u_employee_page2 ,u_employee_name, u_employee_password, u_employee_salary, u_employee_position,u_employee_update = create_add_employee_page(stacked_widget,"Update Employee Details",update_btn=True) def populate_employee_data(): global employee_data if employee_data: print("employee_data is not None") - update_employee_name.setText(str(employee_data[0])) # Name - update_employee_password.setText(str(employee_data[1])) # Password - update_employee_salary.setText(str(employee_data[2])) # Salary - update_employee_position.setText(str(employee_data[3])) # Position + u_employee_name.setText(str(employee_data[0])) # Name + u_employee_password.setText(str(employee_data[1])) # Password + u_employee_salary.setText(str(employee_data[2])) # Salary + u_employee_position.setText(str(employee_data[3])) # Position else: # Clear fields if no employee data is available print("employee_data is None") - update_employee_name.clear() - update_employee_password.clear() - update_employee_salary.clear() - update_employee_position.clear() + u_employee_name.clear() + u_employee_password.clear() + u_employee_salary.clear() + u_employee_position.clear() QtWidgets.QMessageBox.warning(stacked_widget, "No Data", "No employee data available to display.") def on_page_changed(index): if index == 6: # update_employee_page2 is at index 6 @@ -668,12 +687,12 @@ def update_employee_data(name, password, salary, position, name_to_update): show_popup_message(stacked_widget, "Employee updated successfully.", 3, False) except Exception as e: show_popup_message(stacked_widget, f"Error updating employee: {str(e)}", 5) - update_employee_update.clicked.connect( + u_employee_update.clicked.connect( lambda: update_employee_data( - update_employee_name.text().strip(), - update_employee_password.text().strip(), - update_employee_salary.text().strip(), - update_employee_position.text().strip(), + u_employee_name.text().strip(), + u_employee_password.text().strip(), + u_employee_salary.text().strip(), + u_employee_position.text().strip(), employee_data[0] if employee_data else "" ) ) @@ -703,8 +722,8 @@ def update_employee_data(name, password, salary, position, name_to_update): stacked_widget.addWidget(employee_page)#2 stacked_widget.addWidget(admin_menu_page)#3 stacked_widget.addWidget(add_employee_page)#4 - stacked_widget.addWidget(update_employee_page1)#5 - stacked_widget.addWidget(update_employee_page2)#6 + stacked_widget.addWidget(u_employee_page1)#5 + stacked_widget.addWidget(u_employee_page2)#6 stacked_widget.addWidget(employee_list_page)#7 stacked_widget.addWidget(admin_total_money)#8 @@ -714,7 +733,7 @@ def update_employee_data(name, password, salary, position, name_to_update): main_window.setCentralWidget(central_widget) # Set initial page - stacked_widget.setCurrentIndex(3) + stacked_widget.setCurrentIndex(EMPLOYEE_PAGE) return stacked_widget, { "admin_name": admin_name, @@ -736,6 +755,7 @@ def main(): main_window.show() sys.exit(app.exec_()) +# ------------------------------------------------------------------------------------------------------------- if __name__ == "__main__": main() From f846a95d5ac9e44cec2a0b851f930b4616b380ae Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Tue, 10 Jun 2025 12:39:01 +0530 Subject: [PATCH 417/442] admin side all update completed --- bank_managment_system/QTFrontend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index f83449f0d41..465de612842 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -626,7 +626,7 @@ def update_employee_data(name, password, salary, position, name_to_update): ) add_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(ADD_EMPLOYEE_PAGE)) - update_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(UPDATE_EMPLOYEE_PAGE)) + update_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(UPDATE_EMPLOYEE_PAGE1)) list_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_LIST_PAGE)) back_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(HOME_PAGE)) money_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(ADMIN_TOTAL_MONEY)) From 8c54ffa3a054c01d0dbb77252e445edceb651e64 Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Tue, 10 Jun 2025 17:28:57 +0530 Subject: [PATCH 418/442] employee menu page design --- bank_managment_system/QTFrontend.py | 50 +++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 465de612842..56103a7cd99 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -14,6 +14,7 @@ UPDATE_EMPLOYEE_PAGE2 = 6 EMPLOYEE_LIST_PAGE = 7 ADMIN_TOTAL_MONEY = 8 +EMPLOYEE_MENU_PAGE = 9 # ------------------------------------------------------------------------------------------------------------- # === Reusable UI Component Functions === # ------------------------------------------------------------------------------------------------------------- @@ -525,6 +526,31 @@ def show_total_money(parent, title): main_layout.addWidget(content_frame) return page +def create_employee_menu_page(parent, title): + page, main_layout = create_page_with_header(parent, title) + + button_frame = create_styled_frame(page) + button_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + button_layout = QtWidgets.QVBoxLayout(button_frame) + + button_container = create_styled_frame(button_frame, min_size=(300, 0), style="background-color: #ffffff; border-radius: 15px; padding: 20px;") + button_container_layout = QtWidgets.QVBoxLayout(button_container) + button_container_layout.setSpacing(15) + + # Define button labels + button_labels = ["Create Account ", "Show Details", "Add Balance", "Withdraw Money", "Chack Balanace", "Update Account", "list of all Members", "Delete Account", "Back"] + buttons = [] + + for label in button_labels: + btn:QtWidgets.QPushButton = create_styled_button(button_container, label) + button_container_layout.addWidget(btn) + buttons.append(btn) + + button_layout.addWidget(button_container, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + main_layout.addWidget(button_frame) + + return page, *buttons # Unpack as add_button, update_employee, etc. + # ------------------------------------------------------------------------------------------------------------- # === Main Window Setup === # ------------------------------------------------------------------------------------------------------------- @@ -601,7 +627,9 @@ def update_employee_data(name, password, salary, position, name_to_update): switch_to_employee, exit_app ) - + # ------------------------------------------------------------------------------------------------ + # -------------------------------------Admin panel page --------------------------------------- + # ------------------------------------------------------------------------------------------------ # Create Admin Login Page admin_page, admin_name, admin_password, admin_submit = create_login_page( stacked_widget, @@ -708,13 +736,28 @@ def update_employee_data(name, password, salary, position, name_to_update): ) # show employee list page employee_list_page = show_employee_list_page(stacked_widget,"Employee List") + admin_total_money = show_total_money(stacked_widget,"Total Money") + # ------------------------------------------------------------------------------------------------ + # -------------------------------------Employee panel page --------------------------------------- + # ------------------------------------------------------------------------------------------------ # Create Employee Login Page employee_page, employee_name, employee_password, employee_submit = create_login_page( stacked_widget, title="Employee Login" ) - admin_total_money = show_total_money(stacked_widget,"Total Money") + + employee_menu_page, E_Create_Account, E_Show_Details, E_add_Balance, E_Withdraw_Money, E_Chack_Balanace, E_Update_Account, E_list_of_all_Members, E_Delete_Account, E_Back= create_employee_menu_page(stacked_widget,"Employee Menu") + # List of all page + # E_Create_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_CREATE_ACCOUNT_PAGE)) + # E_Show_Details.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_SHOW_DETAILS_PAGE)) + # E_add_Balance.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_ADD_BALANCE_PAGE)) + # E_Withdraw_Money.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_WITHDRAW_MONEY_PAGE)) + # E_Chack_Balanace.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_CHECK_BALANCE_PAGE)) + # E_Update_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_UPDATE_ACCOUNT_PAGE)) + # E_list_of_all_Members.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_LIST_OF_ALL_MEMBERS_PAGE)) + # E_Delete_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_DELETE_ACCOUNT_PAGE)) + # E_Back.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_MENU_PAGE)) # Add pages to stacked widget stacked_widget.addWidget(home_page)#0 @@ -726,6 +769,7 @@ def update_employee_data(name, password, salary, position, name_to_update): stacked_widget.addWidget(u_employee_page2)#6 stacked_widget.addWidget(employee_list_page)#7 stacked_widget.addWidget(admin_total_money)#8 + stacked_widget.addWidget(employee_menu_page)#9 @@ -733,7 +777,7 @@ def update_employee_data(name, password, salary, position, name_to_update): main_window.setCentralWidget(central_widget) # Set initial page - stacked_widget.setCurrentIndex(EMPLOYEE_PAGE) + stacked_widget.setCurrentIndex(EMPLOYEE_MENU_PAGE) return stacked_widget, { "admin_name": admin_name, From 4071a947ad28c5ae517f3246a12ee80d4ec740ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 18:09:34 +0000 Subject: [PATCH 419/442] Bump yfinance from 0.2.61 to 0.2.62 Bumps [yfinance](https://github.com/ranaroussi/yfinance) from 0.2.61 to 0.2.62. - [Release notes](https://github.com/ranaroussi/yfinance/releases) - [Changelog](https://github.com/ranaroussi/yfinance/blob/main/CHANGELOG.rst) - [Commits](https://github.com/ranaroussi/yfinance/compare/0.2.61...0.2.62) --- updated-dependencies: - dependency-name: yfinance dependency-version: 0.2.62 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index b4f8b15d2a1..65bee3b5d8c 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -66,7 +66,7 @@ speechtotext==0.0.3 wikipedia==1.4.0 tqdm==4.67.1 Menu==3.2.2 -yfinance==0.2.61 +yfinance==0.2.62 tweepy==4.15.0 tkcalendar==1.6.1 pytube==15.0.0 From b648c9230decba62ba5e462f1bd8d8612826b4c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 18:09:39 +0000 Subject: [PATCH 420/442] Bump requests from 2.32.3 to 2.32.4 Bumps [requests](https://github.com/psf/requests) from 2.32.3 to 2.32.4. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.32.3...v2.32.4) --- updated-dependencies: - dependency-name: requests dependency-version: 2.32.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- ImageDownloader/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ImageDownloader/requirements.txt b/ImageDownloader/requirements.txt index d80d9fc2a3a..bd6f2345868 100644 --- a/ImageDownloader/requirements.txt +++ b/ImageDownloader/requirements.txt @@ -1 +1 @@ -requests==2.32.3 +requests==2.32.4 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index b4f8b15d2a1..3a7b0e5817c 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -24,7 +24,7 @@ Flask==3.1.1 selenium==4.33.0 firebase-admin==6.8.0 ujson==5.10.0 -requests==2.32.3 +requests==2.32.4 quo==2023.5.1 PyPDF2==3.0.1 pyserial==3.5 From 0592686e449a5b7eacacc6158e060c8b6dd19cfa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Jun 2025 18:12:01 +0000 Subject: [PATCH 421/442] Bump pytest from 8.3.5 to 8.4.0 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.5 to 8.4.0. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.3.5...8.4.0) --- updated-dependencies: - dependency-name: pytest dependency-version: 8.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 802171ec26a..e519cc6d7ad 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -97,7 +97,7 @@ newspaper==0.1.0.7 opencv-python==4.11.0.86 tensorflow==2.18.1 pandas==2.2.3 -pytest==8.3.5 +pytest==8.4.0 qrcode==8.2 googletrans==4.0.2 slab==1.8.0 From 83be08c51b582e31a314968e2ef0b64aab004951 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Jun 2025 18:12:15 +0000 Subject: [PATCH 422/442] Bump google-api-python-client from 2.171.0 to 2.172.0 Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.171.0 to 2.172.0. - [Release notes](https://github.com/googleapis/google-api-python-client/releases) - [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.171.0...v2.172.0) --- updated-dependencies: - dependency-name: google-api-python-client dependency-version: 2.172.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 802171ec26a..618ffee5dee 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -58,7 +58,7 @@ requests-mock==1.12.1 pyglet==2.1.6 urllib3==2.4.0 thirdai==0.9.33 -google-api-python-client==2.171.0 +google-api-python-client==2.172.0 sound==0.1.0 xlwt==1.3.0 pygame==2.6.1 From 0b07b935bec2b9ec6dba884399ee1f4fe0539b9e Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Thu, 12 Jun 2025 13:20:51 +0530 Subject: [PATCH 423/442] update show_popup_message function --- bank_managment_system/QTFrontend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 56103a7cd99..742c34ff62c 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -85,7 +85,7 @@ def create_input_field(parent, label_text, min_label_size=(120, 0)): layout.addWidget(line_edit) return frame, line_edit -def show_popup_message(parent, message: str, page: int = None, show_cancel: bool = True): +def show_popup_message(parent, message: str, page: int = None, show_cancel: bool = True,cancel_page: int = HOME_PAGE): """Reusable popup message box. Args: @@ -141,7 +141,7 @@ def on_accept(): def on_reject(): if page is not None: - parent.setCurrentIndex(page) + parent.setCurrentIndex(cancel_page) dialog.reject() button_box.accepted.connect(on_accept) From e0257c59404255aab038f44c568a48e32b533506 Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Thu, 12 Jun 2025 13:40:39 +0530 Subject: [PATCH 424/442] create bank account page done --- bank_managment_system/QTFrontend.py | 156 +++++++++++++++++++++++++++- 1 file changed, 152 insertions(+), 4 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 742c34ff62c..7fbf3ffb9d5 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -525,7 +525,8 @@ def show_total_money(parent, title): content_layout.addWidget(back_button, alignment=QtCore.Qt.AlignCenter) main_layout.addWidget(content_frame) return page - + +#-----------employees menu pages----------- def create_employee_menu_page(parent, title): page, main_layout = create_page_with_header(parent, title) @@ -550,7 +551,101 @@ def create_employee_menu_page(parent, title): main_layout.addWidget(button_frame) return page, *buttons # Unpack as add_button, update_employee, etc. + +def create_account_page(parent, title): + page, main_layout = create_page_with_header(parent, title) + + content_frame = create_styled_frame(page) + content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_layout = QtWidgets.QVBoxLayout(content_frame) + + form_frame = create_styled_frame(content_frame, min_size=(400, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") + form_layout = QtWidgets.QVBoxLayout(form_frame) + form_layout.setSpacing(3) + + # Define input fields + fields = ["Name :", "Age :", "Address","Balance :", "Mobile number :"] + edits = [] + + for i, field in enumerate(fields): + field_frame, field_edit = create_input_field(form_frame, field,min_label_size=(160, 0)) + form_layout.addWidget(field_frame) + if i == 0: + name_edit = field_edit + elif i == 1: + Age_edit = field_edit + elif i == 2: + Address_edit = field_edit + elif i == 3: + Balance_edit = field_edit + elif i == 4: + Mobile_number_edit = field_edit + edits.append(field_edit) + # Dropdown for account type + account_type_label = QtWidgets.QLabel("Account Type :", form_frame) + account_type_label.setStyleSheet("font-size: 14px; font-weight: bold; color: #333333;") + form_layout.addWidget(account_type_label) + account_type_dropdown = QtWidgets.QComboBox(form_frame) + account_type_dropdown.addItems(["Savings", "Current", "Fixed Deposit"]) + account_type_dropdown.setStyleSheet(""" + QComboBox { + padding: 5px; + border: 1px solid #ccc; + border-radius: 4px; + background-color: white; + min-width: 200px; + font-size: 14px; + } + QComboBox:hover { + border: 1px solid #999; + } + QComboBox::drop-down { + border: none; + width: 25px; + } + QComboBox::down-arrow { + width: 12px; + height: 12px; + } + QComboBox QAbstractItemView { + border: 1px solid #ccc; + background-color: white; + selection-background-color: #0078d4; + selection-color: white; + } + """) + form_layout.addWidget(account_type_dropdown) + + # Submit button + button_frame = create_styled_frame(form_frame, style="padding: 7px;") + button_layout = QtWidgets.QVBoxLayout(button_frame) + + + submit_button = create_styled_button(button_frame, "Submit", min_size=(100, 50)) + button_layout.addWidget(submit_button, 0, QtCore.Qt.AlignHCenter) + + form_layout.addWidget(button_frame) + content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + main_layout.addWidget(content_frame) + back_btn = QtWidgets.QPushButton("Back", content_frame) + back_btn.setStyleSheet(""" + QPushButton { + background-color: #6c757d; + color: white; + border: none; + border-radius: 4px; + padding: 8px 16px; + font-size: 14px; + } + QPushButton:hover { + background-color: #5a6268; + } + """) + back_btn.clicked.connect(lambda: parent.setCurrentIndex(ADMIN_MENU_PAGE)) + main_layout.addWidget(back_btn, 0,alignment=QtCore.Qt.AlignLeft) + + return page,( name_edit, Age_edit,Address_edit,Balance_edit,Mobile_number_edit, account_type_dropdown ,submit_button) # ------------------------------------------------------------------------------------------------------------- # === Main Window Setup === # ------------------------------------------------------------------------------------------------------------- @@ -746,10 +841,10 @@ def update_employee_data(name, password, salary, position, name_to_update): stacked_widget, title="Employee Login" ) - + employee_submit.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_MENU_PAGE)) employee_menu_page, E_Create_Account, E_Show_Details, E_add_Balance, E_Withdraw_Money, E_Chack_Balanace, E_Update_Account, E_list_of_all_Members, E_Delete_Account, E_Back= create_employee_menu_page(stacked_widget,"Employee Menu") # List of all page - # E_Create_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_CREATE_ACCOUNT_PAGE)) + E_Create_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_CREATE_ACCOUNT_PAGE)) # E_Show_Details.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_SHOW_DETAILS_PAGE)) # E_add_Balance.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_ADD_BALANCE_PAGE)) # E_Withdraw_Money.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_WITHDRAW_MONEY_PAGE)) @@ -759,7 +854,59 @@ def update_employee_data(name, password, salary, position, name_to_update): # E_Delete_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_DELETE_ACCOUNT_PAGE)) # E_Back.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_MENU_PAGE)) - # Add pages to stacked widget + employee_create_account_page,all_employee_menu_btn = create_account_page(stacked_widget, "Create Account") + submit_button = all_employee_menu_btn[6].clicked.connect(lambda: add_account_form_submit( + all_employee_menu_btn[0].text().strip(), + all_employee_menu_btn[1].text().strip(), + all_employee_menu_btn[2].text().strip(), + all_employee_menu_btn[3].text().strip(), + all_employee_menu_btn[5].currentText(), + all_employee_menu_btn[4].text().strip() + )) + + def add_account_form_submit(name, age, address, balance, account_type, mobile): + if ( + len(name) != 0 + and len(age) != 0 + and len(address) != 0 + and len(balance) != 0 + and len(account_type) != 0 + and len(mobile) != 0 + ): + try: + balance = int(balance) + except ValueError: + show_popup_message(stacked_widget, "Balance must be a valid number", EMPLOYEE_CREATE_ACCOUNT_PAGE) + return + if balance < 0: + show_popup_message(stacked_widget, "Balance cannot be negative",EMPLOYEE_CREATE_ACCOUNT_PAGE) + return + if account_type not in ["Savings", "Current","Fixed Deposit"]: + show_popup_message(stacked_widget, "Invalid account type", EMPLOYEE_CREATE_ACCOUNT_PAGE) + return + if len(mobile) != 10: + show_popup_message(stacked_widget, "Mobile number must be 10 digits", EMPLOYEE_CREATE_ACCOUNT_PAGE) + return + if not mobile.isdigit(): + show_popup_message(stacked_widget, "Mobile number must contain only digits", EMPLOYEE_CREATE_ACCOUNT_PAGE) + return + if not name.isalpha(): + show_popup_message(stacked_widget, "Name must contain only alphabets", EMPLOYEE_CREATE_ACCOUNT_PAGE) + return + if not age.isdigit(): + show_popup_message(stacked_widget, "Age must contain only digits", EMPLOYEE_CREATE_ACCOUNT_PAGE) + return + if int(age) < 18: + show_popup_message(stacked_widget, "Age must be greater than 18", EMPLOYEE_CREATE_ACCOUNT_PAGE) + return + if len(address) < 10: + show_popup_message(stacked_widget, "Address must be at least 10 characters long", EMPLOYEE_CREATE_ACCOUNT_PAGE) + return + backend.create_customer(name, age, address, balance, account_type, mobile) + show_popup_message(stacked_widget, "Account created successfully", EMPLOYEE_MENU_PAGE, False) + else: + show_popup_message(stacked_widget, "Please fill in all fields", EMPLOYEE_CREATE_ACCOUNT_PAGE) + # Add pages to stacked widget stacked_widget.addWidget(home_page)#0 stacked_widget.addWidget(admin_page)#1 stacked_widget.addWidget(employee_page)#2 @@ -770,6 +917,7 @@ def update_employee_data(name, password, salary, position, name_to_update): stacked_widget.addWidget(employee_list_page)#7 stacked_widget.addWidget(admin_total_money)#8 stacked_widget.addWidget(employee_menu_page)#9 + stacked_widget.addWidget(employee_create_account_page)#10 From 5631bfd872f21517b6ec8dff5b799d1dd70f6797 Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Thu, 12 Jun 2025 14:58:02 +0530 Subject: [PATCH 425/442] chnage all show pop msg page number to name --- bank_managment_system/QTFrontend.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 7fbf3ffb9d5..b7a8b190408 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -3,6 +3,7 @@ import sys import backend backend.connect_database() + employee_data = None # Page Constants (for reference) HOME_PAGE = 0 @@ -15,6 +16,7 @@ EMPLOYEE_LIST_PAGE = 7 ADMIN_TOTAL_MONEY = 8 EMPLOYEE_MENU_PAGE = 9 +EMPLOYEE_CREATE_ACCOUNT_PAGE = 10 # ------------------------------------------------------------------------------------------------------------- # === Reusable UI Component Functions === # ------------------------------------------------------------------------------------------------------------- @@ -85,7 +87,7 @@ def create_input_field(parent, label_text, min_label_size=(120, 0)): layout.addWidget(line_edit) return frame, line_edit -def show_popup_message(parent, message: str, page: int = None, show_cancel: bool = True,cancel_page: int = HOME_PAGE): +def show_popup_message(parent, message: str, page: int = None, show_cancel: bool = False,cancel_page: int = HOME_PAGE): """Reusable popup message box. Args: @@ -261,7 +263,7 @@ def on_login_button_clicked(parent, name_field, password_field): password = password_field.text().strip() if not name or not password: - show_popup_message(parent, "Please enter your name and password.", 0) + show_popup_message(parent, "Please enter your name and password.",HOME_PAGE) else: try: # Ideally, here you'd call a backend authentication check @@ -650,7 +652,7 @@ def create_account_page(parent, title): # === Main Window Setup === # ------------------------------------------------------------------------------------------------------------- -def setup_main_window(main_window): +def setup_main_window(main_window: QtWidgets.QMainWindow): """Set up the main window with a stacked widget containing home, admin, and employee pages.""" main_window.setObjectName("MainWindow") main_window.resize(800, 600) @@ -692,11 +694,11 @@ def add_employee_form_submit(name, password, salary, position): and len(position) != 0 ): backend.create_employee(name, password, salary, position) - show_popup_message(stacked_widget,"Employee added successfully",3,False) + show_popup_message(stacked_widget,"Employee added successfully",ADMIN_MENU_PAGE) else: print("Please fill in all fields") - show_popup_message(stacked_widget,"Please fill in all fields",3) + show_popup_message(stacked_widget,"Please fill in all fields",ADD_EMPLOYEE_PAGE) def update_employee_data(name, password, salary, position, name_to_update): try: cur = backend.cur @@ -708,10 +710,10 @@ def update_employee_data(name, password, salary, position, name_to_update): cur.execute("UPDATE staff SET salary = ? WHERE name = ?", (salary, name)) cur.execute("UPDATE staff SET position = ? WHERE name = ?", (position, name)) backend.conn.commit() - show_popup_message(stacked_widget,"Employee Upadate successfully",3,False) + show_popup_message(stacked_widget,"Employee Upadate successfully",UPDATE_EMPLOYEE_PAGE2) except: - show_popup_message(stacked_widget,"Please fill in all fields",3) + show_popup_message(stacked_widget,"Please fill in all fields",UPDATE_EMPLOYEE_PAGE2) @@ -789,10 +791,10 @@ def on_page_changed(index): def update_employee_data(name, password, salary, position, name_to_update): try: if not name_to_update: - show_popup_message(stacked_widget, "Original employee name is missing.", 5) + show_popup_message(stacked_widget, "Original employee name is missing.", UPDATE_EMPLOYEE_PAGE2) return if not (name or password or salary or position): - show_popup_message(stacked_widget, "Please fill at least one field to update.", 5) + show_popup_message(stacked_widget, "Please fill at least one field to update.", UPDATE_EMPLOYEE_PAGE2) return if name: backend.update_employee_name(name, name_to_update) @@ -807,9 +809,9 @@ def update_employee_data(name, password, salary, position, name_to_update): return if position: backend.update_employee_position(position, name_to_update) - show_popup_message(stacked_widget, "Employee updated successfully.", 3, False) + show_popup_message(stacked_widget, "Employee updated successfully.", ADMIN_MENU_PAGE) except Exception as e: - show_popup_message(stacked_widget, f"Error updating employee: {str(e)}", 5) + show_popup_message(stacked_widget, f"Error updating employee: {str(e)}",UPDATE_EMPLOYEE_PAGE2,show_cancel=True,cancel_page=ADMIN_MENU_PAGE) u_employee_update.clicked.connect( lambda: update_employee_data( u_employee_name.text().strip(), @@ -925,7 +927,7 @@ def add_account_form_submit(name, age, address, balance, account_type, mobile): main_window.setCentralWidget(central_widget) # Set initial page - stacked_widget.setCurrentIndex(EMPLOYEE_MENU_PAGE) + stacked_widget.setCurrentIndex(HOME_PAGE) return stacked_widget, { "admin_name": admin_name, @@ -951,4 +953,6 @@ def main(): if __name__ == "__main__": main() +# TO-DO: +# 1.refese the employee list page after add or delete or update employee From d5411c57ea2806047310f2b9c5c00ecd61218561 Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Thu, 12 Jun 2025 15:42:44 +0530 Subject: [PATCH 426/442] show user bank details --- bank_managment_system/QTFrontend.py | 35 +++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index b7a8b190408..506207d2cfb 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -648,6 +648,27 @@ def create_account_page(parent, title): main_layout.addWidget(back_btn, 0,alignment=QtCore.Qt.AlignLeft) return page,( name_edit, Age_edit,Address_edit,Balance_edit,Mobile_number_edit, account_type_dropdown ,submit_button) + +def create_show_details_page1(parent, title): + page, main_layout = create_page_with_header(parent, title) + content_frame = create_styled_frame(page) + content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_layout = QtWidgets.QVBoxLayout(content_frame) + + form_frame = create_styled_frame(content_frame, min_size=(400, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") + form_layout = QtWidgets.QVBoxLayout(form_frame) + form_layout.setSpacing(3) + # Define input fields + bannk_user = create_input_field(form_frame, "Enter Bank account Number :", min_label_size=(180, 0)) + form_layout.addWidget(bannk_user[0]) + user_account_number= bannk_user[1] + submit_button = create_styled_button(form_frame, "Submit", min_size=(100, 50)) + form_layout.addWidget(submit_button) + content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + main_layout.addWidget(content_frame) + + return page,(user_account_number,submit_button) + # ------------------------------------------------------------------------------------------------------------- # === Main Window Setup === # ------------------------------------------------------------------------------------------------------------- @@ -857,7 +878,7 @@ def update_employee_data(name, password, salary, position, name_to_update): # E_Back.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_MENU_PAGE)) employee_create_account_page,all_employee_menu_btn = create_account_page(stacked_widget, "Create Account") - submit_button = all_employee_menu_btn[6].clicked.connect(lambda: add_account_form_submit( + all_employee_menu_btn[6].clicked.connect(lambda: add_account_form_submit( all_employee_menu_btn[0].text().strip(), all_employee_menu_btn[1].text().strip(), all_employee_menu_btn[2].text().strip(), @@ -905,10 +926,19 @@ def add_account_form_submit(name, age, address, balance, account_type, mobile): show_popup_message(stacked_widget, "Address must be at least 10 characters long", EMPLOYEE_CREATE_ACCOUNT_PAGE) return backend.create_customer(name, age, address, balance, account_type, mobile) + all_employee_menu_btn[0].setText("") + all_employee_menu_btn[1].setText("") + all_employee_menu_btn[2].setText("") + all_employee_menu_btn[3].setText("") + all_employee_menu_btn[4].setText("") + all_employee_menu_btn[5].currentText(), show_popup_message(stacked_widget, "Account created successfully", EMPLOYEE_MENU_PAGE, False) else: show_popup_message(stacked_widget, "Please fill in all fields", EMPLOYEE_CREATE_ACCOUNT_PAGE) # Add pages to stacked widget + + show_bank_user_data_page1,show_bank_user_other = create_show_details_page1(stacked_widget, "Show Details") + show_bank_user_other[1].clicked.connect(lambda: print(show_bank_user_other[0].text())) stacked_widget.addWidget(home_page)#0 stacked_widget.addWidget(admin_page)#1 stacked_widget.addWidget(employee_page)#2 @@ -920,6 +950,7 @@ def add_account_form_submit(name, age, address, balance, account_type, mobile): stacked_widget.addWidget(admin_total_money)#8 stacked_widget.addWidget(employee_menu_page)#9 stacked_widget.addWidget(employee_create_account_page)#10 + stacked_widget.addWidget(show_bank_user_data_page1)#11 @@ -927,7 +958,7 @@ def add_account_form_submit(name, age, address, balance, account_type, mobile): main_window.setCentralWidget(central_widget) # Set initial page - stacked_widget.setCurrentIndex(HOME_PAGE) + stacked_widget.setCurrentIndex(11) return stacked_widget, { "admin_name": admin_name, From 3d3ff62847c6a7f4edcf4c4f313cc4694abbfe8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Jun 2025 18:22:07 +0000 Subject: [PATCH 427/442] Bump aiohttp from 3.12.9 to 3.12.12 --- updated-dependencies: - dependency-name: aiohttp dependency-version: 3.12.12 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- async_downloader/requirements.txt | 2 +- requirements_with_versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/async_downloader/requirements.txt b/async_downloader/requirements.txt index 6efd61c224a..d7fb9f5f95b 100644 --- a/async_downloader/requirements.txt +++ b/async_downloader/requirements.txt @@ -1 +1 @@ -aiohttp==3.12.9 +aiohttp==3.12.12 diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 64496f26854..4fe30fc615a 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -1,5 +1,5 @@ pafy==0.5.5 -aiohttp==3.12.9 +aiohttp==3.12.12 fuzzywuzzy==0.18.0 hupper==1.12.1 seaborn==0.13.2 From 8990c6e47657f28b2dd996fa939e1d4198d72620 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Jun 2025 18:22:15 +0000 Subject: [PATCH 428/442] Bump openai from 1.84.0 to 1.86.0 Bumps [openai](https://github.com/openai/openai-python) from 1.84.0 to 1.86.0. - [Release notes](https://github.com/openai/openai-python/releases) - [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/openai/openai-python/compare/v1.84.0...v1.86.0) --- updated-dependencies: - dependency-name: openai dependency-version: 1.86.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 64496f26854..eb289195187 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -49,7 +49,7 @@ auto-mix-prep==0.2.0 lib==4.0.0 pywifi==1.1.12 patterns==0.3 -openai==1.84.0 +openai==1.86.0 background==0.2.1 pydantic==2.11.4 openpyxl==3.1.2 From ff841d73ecf393a6c24c26a1975b192b9863dd29 Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Fri, 13 Jun 2025 11:20:31 +0530 Subject: [PATCH 429/442] show user account page done --- bank_managment_system/QTFrontend.py | 87 +++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 4 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 506207d2cfb..bd07d8128a4 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -17,6 +17,8 @@ ADMIN_TOTAL_MONEY = 8 EMPLOYEE_MENU_PAGE = 9 EMPLOYEE_CREATE_ACCOUNT_PAGE = 10 +EMPLOYEE_SHOW_DETAILS_PAGE1 = 11 +EMPLOYEE_SHOW_DETAILS_PAGE2 = 12 # ------------------------------------------------------------------------------------------------------------- # === Reusable UI Component Functions === # ------------------------------------------------------------------------------------------------------------- @@ -572,6 +574,7 @@ def create_account_page(parent, title): for i, field in enumerate(fields): field_frame, field_edit = create_input_field(form_frame, field,min_label_size=(160, 0)) form_layout.addWidget(field_frame) + field_edit.setFont(QtGui.QFont("Arial", 12)) if i == 0: name_edit = field_edit elif i == 1: @@ -644,7 +647,7 @@ def create_account_page(parent, title): background-color: #5a6268; } """) - back_btn.clicked.connect(lambda: parent.setCurrentIndex(ADMIN_MENU_PAGE)) + back_btn.clicked.connect(lambda: parent.setCurrentIndex(EMPLOYEE_MENU_PAGE)) main_layout.addWidget(back_btn, 0,alignment=QtCore.Qt.AlignLeft) return page,( name_edit, Age_edit,Address_edit,Balance_edit,Mobile_number_edit, account_type_dropdown ,submit_button) @@ -668,6 +671,61 @@ def create_show_details_page1(parent, title): main_layout.addWidget(content_frame) return page,(user_account_number,submit_button) + +def create_show_details_page2(parent, title): + page, main_layout = create_page_with_header(parent, title) + content_frame = create_styled_frame(page) + content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_layout = QtWidgets.QVBoxLayout(content_frame) + + form_frame = create_styled_frame(content_frame, min_size=(400, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") + form_layout = QtWidgets.QVBoxLayout(form_frame) + form_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + form_layout.setSpacing(3) + + # Define input fields + + labeles = ["Account No: ","Name: ", "Age:", "Address: ", "Balance: ", "Mobile Number: ", "Account Type: "] + for i in range(len(labeles)): + label_frame, input_field = create_input_field(form_frame, labeles[i], min_label_size=(180, 30)) + form_layout.addWidget(label_frame) + input_field.setReadOnly(True) + input_field.setFont(QtGui.QFont("Arial", 12)) + if i == 0: + account_no_field = input_field + elif i == 1: + name_field = input_field + elif i == 2: + age_field = input_field + elif i == 3: + address_field = input_field + elif i == 4: + balance_field = input_field + elif i == 5: + mobile_number_field = input_field + elif i == 6: + account_type_field = input_field + + exite_btn = create_styled_button(form_frame, "Exit", min_size=(100, 50)) + exite_btn.setStyleSheet(""" + QPushButton { + background-color: #6c757d; + color: white; + border: none; + border-radius: 4px; + padding: 8px 16px; + font-size: 14px; + } + QPushButton:hover { + background-color: #5a6268; + } + """) + exite_btn.clicked.connect(lambda: parent.setCurrentIndex(EMPLOYEE_MENU_PAGE)) + content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + main_layout.addWidget(content_frame) + main_layout.addWidget(exite_btn) + + return page,(account_no_field,name_field,age_field,address_field,balance_field,mobile_number_field,account_type_field,exite_btn) # ------------------------------------------------------------------------------------------------------------- # === Main Window Setup === @@ -868,7 +926,7 @@ def update_employee_data(name, password, salary, position, name_to_update): employee_menu_page, E_Create_Account, E_Show_Details, E_add_Balance, E_Withdraw_Money, E_Chack_Balanace, E_Update_Account, E_list_of_all_Members, E_Delete_Account, E_Back= create_employee_menu_page(stacked_widget,"Employee Menu") # List of all page E_Create_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_CREATE_ACCOUNT_PAGE)) - # E_Show_Details.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_SHOW_DETAILS_PAGE)) + E_Show_Details.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_SHOW_DETAILS_PAGE1)) # E_add_Balance.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_ADD_BALANCE_PAGE)) # E_Withdraw_Money.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_WITHDRAW_MONEY_PAGE)) # E_Chack_Balanace.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_CHECK_BALANCE_PAGE)) @@ -937,8 +995,28 @@ def add_account_form_submit(name, age, address, balance, account_type, mobile): show_popup_message(stacked_widget, "Please fill in all fields", EMPLOYEE_CREATE_ACCOUNT_PAGE) # Add pages to stacked widget - show_bank_user_data_page1,show_bank_user_other = create_show_details_page1(stacked_widget, "Show Details") - show_bank_user_other[1].clicked.connect(lambda: print(show_bank_user_other[0].text())) + show_bank_user_data_page1,show_bank_user_other1 = create_show_details_page1(stacked_widget, "Show Details") + show_bank_user_data_page2,show_bank_user_other2 = create_show_details_page2(stacked_widget, "Show Details") + + show_bank_user_other1[1].clicked.connect(lambda: show_bank_user_data_page1_submit_btn(int(show_bank_user_other1[0].text().strip()))) + def show_bank_user_data_page1_submit_btn(name:int): + account_data = backend.get_details(name) + if account_data: + show_bank_user_other1[0].setText("") + show_bank_user_other2[0].setText(str(account_data[0])) + show_bank_user_other2[1].setText(str(account_data[1])) + show_bank_user_other2[2].setText(str(account_data[2])) + show_bank_user_other2[3].setText(str(account_data[3])) + show_bank_user_other2[4].setText(str(account_data[4])) + show_bank_user_other2[5].setText(str(account_data[5])) + show_bank_user_other2[6].setText(str(account_data[6])) + stacked_widget.setCurrentIndex(EMPLOYEE_SHOW_DETAILS_PAGE2) + else: + show_popup_message(stacked_widget, "Account not found", EMPLOYEE_SHOW_DETAILS_PAGE1) + + + + stacked_widget.addWidget(home_page)#0 stacked_widget.addWidget(admin_page)#1 stacked_widget.addWidget(employee_page)#2 @@ -951,6 +1029,7 @@ def add_account_form_submit(name, age, address, balance, account_type, mobile): stacked_widget.addWidget(employee_menu_page)#9 stacked_widget.addWidget(employee_create_account_page)#10 stacked_widget.addWidget(show_bank_user_data_page1)#11 + stacked_widget.addWidget(show_bank_user_data_page2)#12 From 4654bf3b1d7c1f677fdd2ea1f6dcaad2ee311270 Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Fri, 13 Jun 2025 16:55:39 +0530 Subject: [PATCH 430/442] update bank balance of user --- bank_managment_system/QTFrontend.py | 122 +++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 4 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index bd07d8128a4..a519388c6b7 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -19,6 +19,10 @@ EMPLOYEE_CREATE_ACCOUNT_PAGE = 10 EMPLOYEE_SHOW_DETAILS_PAGE1 = 11 EMPLOYEE_SHOW_DETAILS_PAGE2 = 12 +EMPLOYEE_ADD_BALANCE_SEARCH = 13 +EMPLOYEE_ADD_BALANCE_PAGE = 14 + +FONT_SIZE = QtGui.QFont("Segoe UI", 12) # ------------------------------------------------------------------------------------------------------------- # === Reusable UI Component Functions === # ------------------------------------------------------------------------------------------------------------- @@ -83,7 +87,25 @@ def create_input_field(parent, label_text, min_label_size=(120, 0)): label.setMinimumSize(QtCore.QSize(*min_label_size)) line_edit = QtWidgets.QLineEdit(frame) - line_edit.setStyleSheet("background-color: rgb(168, 168, 168);") + line_edit.setStyleSheet("background-color: #f0f0f0; border: 1px solid #ccc; border-radius: 4px; padding: 8px;") + + layout.addWidget(label) + layout.addWidget(line_edit) + return frame, line_edit + +def create_input_field_V(parent, label_text, min_label_size=(120, 0)): + """Create a horizontal layout with a label and a QLineEdit.""" + frame = create_styled_frame(parent, style="padding: 7px;") + layout = QtWidgets.QVBoxLayout(frame) + layout.setContentsMargins(0, 0, 0, 0) + layout.setSpacing(0) + + label = create_styled_label(frame, label_text, font_size=12, bold=True, style="color: #2c3e50;") + if min_label_size: + label.setMinimumSize(QtCore.QSize(*min_label_size)) + + line_edit = QtWidgets.QLineEdit(frame) + line_edit.setStyleSheet("background-color: #f0f0f0; border: 1px solid #ccc; border-radius: 4px; padding: 8px;") layout.addWidget(label) layout.addWidget(line_edit) @@ -152,6 +174,28 @@ def on_reject(): button_box.rejected.connect(on_reject) dialog.exec_() + +def search_result(parent, title,label_text): + page, main_layout = create_page_with_header(parent, title) + content_frame = create_styled_frame(page) + content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_layout = QtWidgets.QVBoxLayout(content_frame) + content_layout.alignment + + form_frame = create_styled_frame(content_frame, min_size=(400, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") + form_layout = QtWidgets.QVBoxLayout(form_frame) + form_layout.setSpacing(3) + # Define input fields + user = create_input_field(form_frame, label_text, min_label_size=(180, 0)) + form_layout.addWidget(user[0]) + user_account_number= user[1] + user_account_number.setFont(QtGui.QFont("Segoe UI", 12)) + submit_button = create_styled_button(form_frame, "Submit", min_size=(100, 50)) + form_layout.addWidget(submit_button) + content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + main_layout.addWidget(content_frame) + + return page,(user_account_number,submit_button) # ------------------------------------------------------------------------------------------------------------- # === Page Creation Functions == # ------------------------------------------------------------------------------------------------------------- @@ -727,6 +771,49 @@ def create_show_details_page2(parent, title): return page,(account_no_field,name_field,age_field,address_field,balance_field,mobile_number_field,account_type_field,exite_btn) +def update_user_balance(parent, title): + page, main_layout = create_page_with_header(parent, title) + content_frame = create_styled_frame(page) + content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_layout = QtWidgets.QVBoxLayout(content_frame) + content_layout.alignment + + form_frame = create_styled_frame(content_frame, min_size=(400, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") + form_layout = QtWidgets.QVBoxLayout(form_frame) + form_layout.setSpacing(3) + # Define input fields + user = create_input_field(form_frame, "User Name: ", min_label_size=(180, 0)) + user_balance = create_input_field(form_frame, "Balance: ", min_label_size=(180, 0)) + user_update_balance = create_input_field_V(form_frame, "Add amount: ", min_label_size=(180, 0)) + + # Add input fields to the form layout + form_layout.addWidget(user[0]) + form_layout.addWidget(user_balance[0]) + form_layout.addWidget(user_update_balance[0]) + + # Store the input fields in variables + user_account_name= user[1] + user_account_name.setReadOnly(True) + user_account_name.setStyleSheet("background-color: #8a8a8a; border: 1px solid #ccc; border-radius: 4px; padding: 8px;") + user_balance_field = user_balance[1] + user_balance_field.setReadOnly(True) + user_balance_field.setStyleSheet("background-color: #8a8a8a; border: 1px solid #ccc; border-radius: 4px; padding: 8px;") + user_update_balance_field = user_update_balance[1] + user_update_balance_field.setStyleSheet("background-color: #f0f0f0; border: 1px solid #ccc; border-radius: 4px; padding: 8px;") + + + # Set the font size for the input fields + user_account_name.setFont(QtGui.QFont("Segoe UI", 12)) + user_balance_field.setFont(QtGui.QFont("Segoe UI", 12)) + user_update_balance_field.setFont(QtGui.QFont("Segoe UI", 12)) + + # Add a submit button + submit_button = create_styled_button(form_frame, "Submit", min_size=(100, 50)) + form_layout.addWidget(submit_button) + content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + main_layout.addWidget(content_frame) + + return page,(user_account_name,user_balance_field,user_update_balance_field,submit_button) # ------------------------------------------------------------------------------------------------------------- # === Main Window Setup === # ------------------------------------------------------------------------------------------------------------- @@ -927,7 +1014,7 @@ def update_employee_data(name, password, salary, position, name_to_update): # List of all page E_Create_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_CREATE_ACCOUNT_PAGE)) E_Show_Details.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_SHOW_DETAILS_PAGE1)) - # E_add_Balance.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_ADD_BALANCE_PAGE)) + E_add_Balance.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_ADD_BALANCE_SEARCH)) # E_Withdraw_Money.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_WITHDRAW_MONEY_PAGE)) # E_Chack_Balanace.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_CHECK_BALANCE_PAGE)) # E_Update_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_UPDATE_ACCOUNT_PAGE)) @@ -1014,9 +1101,34 @@ def show_bank_user_data_page1_submit_btn(name:int): else: show_popup_message(stacked_widget, "Account not found", EMPLOYEE_SHOW_DETAILS_PAGE1) + add_balance_search_page,add_balance_search_other = search_result(stacked_widget, "Add Balance","Enter Account Number: ") + add_balance_search_other[1].clicked.connect(lambda: add_balance_page_submit_btn(int(add_balance_search_other[0].text().strip()))) - + add_balance_page,add_balance_other =update_user_balance(stacked_widget, "Add Balance User Account") + add_balance_other[3].clicked.connect(lambda:update_user_account_balance(add_balance_other[2].text().strip())) + # user_account_name,user_balance_field,user_update_balance_field,submit_button + + + def add_balance_page_submit_btn(account_number:int): + check = backend.check_acc_no(account_number) + if check: + account_data = backend.get_details(account_number) + add_balance_other[0].setText(str(account_data[1])) + add_balance_other[1].setText(str(account_data[4])) + stacked_widget.setCurrentIndex(14) + return account_data + else: + show_popup_message(stacked_widget, "Account not found", EMPLOYEE_ADD_BALANCE_SEARCH,show_cancel=True,cancel_page=EMPLOYEE_MENU_PAGE) + + def update_user_account_balance(add_money:int): + account_number=int(add_balance_search_other[0].text().strip()) + backend.update_balance(add_money,account_number) + add_balance_other[0].setText("") + add_balance_other[1].setText("") + show_popup_message(stacked_widget, "Balance updated successfully", EMPLOYEE_MENU_PAGE) + add_balance_search_other[0].setText("") + stacked_widget.addWidget(home_page)#0 stacked_widget.addWidget(admin_page)#1 stacked_widget.addWidget(employee_page)#2 @@ -1030,6 +1142,8 @@ def show_bank_user_data_page1_submit_btn(name:int): stacked_widget.addWidget(employee_create_account_page)#10 stacked_widget.addWidget(show_bank_user_data_page1)#11 stacked_widget.addWidget(show_bank_user_data_page2)#12 + stacked_widget.addWidget(add_balance_search_page)#13 + stacked_widget.addWidget(add_balance_page)#14 @@ -1037,7 +1151,7 @@ def show_bank_user_data_page1_submit_btn(name:int): main_window.setCentralWidget(central_widget) # Set initial page - stacked_widget.setCurrentIndex(11) + stacked_widget.setCurrentIndex(13) return stacked_widget, { "admin_name": admin_name, From 799cedb58705f221679e0fba677c1414ccb7c9f3 Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Fri, 13 Jun 2025 17:12:01 +0530 Subject: [PATCH 431/442] update size of the font in all input field --- bank_managment_system/QTFrontend.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index a519388c6b7..cbf3c92be23 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -87,6 +87,7 @@ def create_input_field(parent, label_text, min_label_size=(120, 0)): label.setMinimumSize(QtCore.QSize(*min_label_size)) line_edit = QtWidgets.QLineEdit(frame) + line_edit.setFont(FONT_SIZE) line_edit.setStyleSheet("background-color: #f0f0f0; border: 1px solid #ccc; border-radius: 4px; padding: 8px;") layout.addWidget(label) @@ -106,6 +107,7 @@ def create_input_field_V(parent, label_text, min_label_size=(120, 0)): line_edit = QtWidgets.QLineEdit(frame) line_edit.setStyleSheet("background-color: #f0f0f0; border: 1px solid #ccc; border-radius: 4px; padding: 8px;") + line_edit.setFont(FONT_SIZE) layout.addWidget(label) layout.addWidget(line_edit) @@ -189,7 +191,7 @@ def search_result(parent, title,label_text): user = create_input_field(form_frame, label_text, min_label_size=(180, 0)) form_layout.addWidget(user[0]) user_account_number= user[1] - user_account_number.setFont(QtGui.QFont("Segoe UI", 12)) + user_account_number.setFont(FONT_SIZE) submit_button = create_styled_button(form_frame, "Submit", min_size=(100, 50)) form_layout.addWidget(submit_button) content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) @@ -803,9 +805,9 @@ def update_user_balance(parent, title): # Set the font size for the input fields - user_account_name.setFont(QtGui.QFont("Segoe UI", 12)) - user_balance_field.setFont(QtGui.QFont("Segoe UI", 12)) - user_update_balance_field.setFont(QtGui.QFont("Segoe UI", 12)) + user_account_name.setFont(FONT_SIZE) + user_balance_field.setFont(FONT_SIZE) + user_update_balance_field.setFont(FONT_SIZE) # Add a submit button submit_button = create_styled_button(form_frame, "Submit", min_size=(100, 50)) @@ -1151,7 +1153,7 @@ def update_user_account_balance(add_money:int): main_window.setCentralWidget(central_widget) # Set initial page - stacked_widget.setCurrentIndex(13) + stacked_widget.setCurrentIndex(0) return stacked_widget, { "admin_name": admin_name, From 4017befcf3bb27184c9b41d4acc0379ab8fa24c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Jun 2025 19:00:10 +0000 Subject: [PATCH 432/442] Bump firebase-admin from 6.8.0 to 6.9.0 Bumps [firebase-admin](https://github.com/firebase/firebase-admin-python) from 6.8.0 to 6.9.0. - [Release notes](https://github.com/firebase/firebase-admin-python/releases) - [Commits](https://github.com/firebase/firebase-admin-python/compare/v6.8.0...v6.9.0) --- updated-dependencies: - dependency-name: firebase-admin dependency-version: 6.9.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index cadeb76ac9c..ba420f59f34 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -22,7 +22,7 @@ win10toast==0.9 Counter==1.0.0 Flask==3.1.1 selenium==4.33.0 -firebase-admin==6.8.0 +firebase-admin==6.9.0 ujson==5.10.0 requests==2.32.4 quo==2023.5.1 From c1b9387345a0924d7f257a0a0cb103dbe7457f58 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Jun 2025 19:00:14 +0000 Subject: [PATCH 433/442] Bump xor-cipher from 5.0.1 to 5.0.2 Bumps [xor-cipher](https://github.com/GDPSApp/xor-cipher-python) from 5.0.1 to 5.0.2. - [Release notes](https://github.com/GDPSApp/xor-cipher-python/releases) - [Changelog](https://github.com/GDPSApp/xor-cipher-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/GDPSApp/xor-cipher-python/compare/v5.0.1...v5.0.2) --- updated-dependencies: - dependency-name: xor-cipher dependency-version: 5.0.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index cadeb76ac9c..80c583248a8 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -70,7 +70,7 @@ yfinance==0.2.62 tweepy==4.15.0 tkcalendar==1.6.1 pytube==15.0.0 -xor-cipher==5.0.1 +xor-cipher==5.0.2 bird==0.1.2 mechanize==0.4.10 translate==3.6.1 From 28b00598a79c2e3b4d754166abb75b4bfeb11b22 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Jun 2025 19:01:02 +0000 Subject: [PATCH 434/442] Bump pydantic from 2.11.4 to 2.11.6 Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.11.4 to 2.11.6. - [Release notes](https://github.com/pydantic/pydantic/releases) - [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md) - [Commits](https://github.com/pydantic/pydantic/compare/v2.11.4...v2.11.6) --- updated-dependencies: - dependency-name: pydantic dependency-version: 2.11.6 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index cadeb76ac9c..3247cc8ab2e 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -51,7 +51,7 @@ pywifi==1.1.12 patterns==0.3 openai==1.86.0 background==0.2.1 -pydantic==2.11.4 +pydantic==2.11.6 openpyxl==3.1.2 pytesseract==0.3.13 requests-mock==1.12.1 From da0068177c939b02f5ca627c6f4449c2f62a05cd Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Sat, 14 Jun 2025 12:34:28 +0530 Subject: [PATCH 435/442] add withdraw_money_page page working --- bank_managment_system/QTFrontend.py | 48 ++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index cbf3c92be23..9a1a54106f1 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -21,6 +21,8 @@ EMPLOYEE_SHOW_DETAILS_PAGE2 = 12 EMPLOYEE_ADD_BALANCE_SEARCH = 13 EMPLOYEE_ADD_BALANCE_PAGE = 14 +EMPLOYEE_WITHDRAW_MONEY_SEARCH = 15 +EMPLOYEE_WITHDRAW_MONEY_PAGE = 16 FONT_SIZE = QtGui.QFont("Segoe UI", 12) # ------------------------------------------------------------------------------------------------------------- @@ -773,7 +775,7 @@ def create_show_details_page2(parent, title): return page,(account_no_field,name_field,age_field,address_field,balance_field,mobile_number_field,account_type_field,exite_btn) -def update_user_balance(parent, title): +def update_user(parent, title,input_fields_label): page, main_layout = create_page_with_header(parent, title) content_frame = create_styled_frame(page) content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) @@ -786,7 +788,7 @@ def update_user_balance(parent, title): # Define input fields user = create_input_field(form_frame, "User Name: ", min_label_size=(180, 0)) user_balance = create_input_field(form_frame, "Balance: ", min_label_size=(180, 0)) - user_update_balance = create_input_field_V(form_frame, "Add amount: ", min_label_size=(180, 0)) + user_update_balance = create_input_field_V(form_frame, input_fields_label, min_label_size=(180, 0)) # Add input fields to the form layout form_layout.addWidget(user[0]) @@ -816,6 +818,7 @@ def update_user_balance(parent, title): main_layout.addWidget(content_frame) return page,(user_account_name,user_balance_field,user_update_balance_field,submit_button) + # ------------------------------------------------------------------------------------------------------------- # === Main Window Setup === # ------------------------------------------------------------------------------------------------------------- @@ -1017,7 +1020,7 @@ def update_employee_data(name, password, salary, position, name_to_update): E_Create_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_CREATE_ACCOUNT_PAGE)) E_Show_Details.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_SHOW_DETAILS_PAGE1)) E_add_Balance.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_ADD_BALANCE_SEARCH)) - # E_Withdraw_Money.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_WITHDRAW_MONEY_PAGE)) + E_Withdraw_Money.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_WITHDRAW_MONEY_SEARCH)) # E_Chack_Balanace.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_CHECK_BALANCE_PAGE)) # E_Update_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_UPDATE_ACCOUNT_PAGE)) # E_list_of_all_Members.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_LIST_OF_ALL_MEMBERS_PAGE)) @@ -1102,14 +1105,14 @@ def show_bank_user_data_page1_submit_btn(name:int): stacked_widget.setCurrentIndex(EMPLOYEE_SHOW_DETAILS_PAGE2) else: show_popup_message(stacked_widget, "Account not found", EMPLOYEE_SHOW_DETAILS_PAGE1) - + + # Add balance page add_balance_search_page,add_balance_search_other = search_result(stacked_widget, "Add Balance","Enter Account Number: ") add_balance_search_other[1].clicked.connect(lambda: add_balance_page_submit_btn(int(add_balance_search_other[0].text().strip()))) - add_balance_page,add_balance_other =update_user_balance(stacked_widget, "Add Balance User Account") + add_balance_page,add_balance_other =update_user(stacked_widget, "Add Balance User Account","Enter Ammount: ") add_balance_other[3].clicked.connect(lambda:update_user_account_balance(add_balance_other[2].text().strip())) - # user_account_name,user_balance_field,user_update_balance_field,submit_button def add_balance_page_submit_btn(account_number:int): @@ -1131,6 +1134,35 @@ def update_user_account_balance(add_money:int): show_popup_message(stacked_widget, "Balance updated successfully", EMPLOYEE_MENU_PAGE) add_balance_search_other[0].setText("") + # Withdraw money page + withdraw_money_search_page,withdraw_money_search_other = search_result(stacked_widget, "Withdraw Money","Enter Account Number: ") + withdraw_money_search_other[1].clicked.connect(lambda: withdraw_money_page_submit_btn(int(withdraw_money_search_other[0].text().strip()))) + + + withdraw_money_page,withdraw_money_other =update_user(stacked_widget, "Withdraw Money From User Account","Withdraw Amount: ") + withdraw_money_other[3].clicked.connect(lambda:update_user_account_withdraw(withdraw_money_other[2].text().strip())) + + def withdraw_money_page_submit_btn(account_number:int): + print(account_number) + check = backend.check_acc_no(account_number) + print(check) + if check: + account_data = backend.get_details(account_number) + withdraw_money_other[0].setText(str(account_data[1])) + withdraw_money_other[1].setText(str(account_data[4])) + stacked_widget.setCurrentIndex(16) + return account_data + else: + show_popup_message(stacked_widget, "Account not found", EMPLOYEE_WITHDRAW_MONEY_SEARCH,show_cancel=True,cancel_page=EMPLOYEE_MENU_PAGE) + + def update_user_account_withdraw(withdraw_money:int): + account_number=int(withdraw_money_search_other[0].text().strip()) + backend.deduct_balance(int(withdraw_money),int(account_number)) + withdraw_money_other[0].setText("") + withdraw_money_other[1].setText("") + show_popup_message(stacked_widget, "Balance updated successfully", EMPLOYEE_MENU_PAGE) + withdraw_money_search_other[0].setText("") + stacked_widget.addWidget(home_page)#0 stacked_widget.addWidget(admin_page)#1 stacked_widget.addWidget(employee_page)#2 @@ -1146,6 +1178,8 @@ def update_user_account_balance(add_money:int): stacked_widget.addWidget(show_bank_user_data_page2)#12 stacked_widget.addWidget(add_balance_search_page)#13 stacked_widget.addWidget(add_balance_page)#14 + stacked_widget.addWidget(withdraw_money_search_page)#15 + stacked_widget.addWidget(withdraw_money_page)#16 @@ -1153,7 +1187,7 @@ def update_user_account_balance(add_money:int): main_window.setCentralWidget(central_widget) # Set initial page - stacked_widget.setCurrentIndex(0) + stacked_widget.setCurrentIndex(9) return stacked_widget, { "admin_name": admin_name, From 57452c5188d771dccfa53379d2a7cdf3abf082f1 Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Sat, 14 Jun 2025 13:04:45 +0530 Subject: [PATCH 436/442] optimize add and withdraw money page --- bank_managment_system/QTFrontend.py | 136 ++++++++++++++++------------ 1 file changed, 80 insertions(+), 56 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 9a1a54106f1..50fec0612e6 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -1106,62 +1106,86 @@ def show_bank_user_data_page1_submit_btn(name:int): else: show_popup_message(stacked_widget, "Account not found", EMPLOYEE_SHOW_DETAILS_PAGE1) - # Add balance page - add_balance_search_page,add_balance_search_other = search_result(stacked_widget, "Add Balance","Enter Account Number: ") - add_balance_search_other[1].clicked.connect(lambda: add_balance_page_submit_btn(int(add_balance_search_other[0].text().strip()))) - - - add_balance_page,add_balance_other =update_user(stacked_widget, "Add Balance User Account","Enter Ammount: ") - add_balance_other[3].clicked.connect(lambda:update_user_account_balance(add_balance_other[2].text().strip())) - - - def add_balance_page_submit_btn(account_number:int): - check = backend.check_acc_no(account_number) - if check: - account_data = backend.get_details(account_number) - add_balance_other[0].setText(str(account_data[1])) - add_balance_other[1].setText(str(account_data[4])) - stacked_widget.setCurrentIndex(14) - return account_data - else: - show_popup_message(stacked_widget, "Account not found", EMPLOYEE_ADD_BALANCE_SEARCH,show_cancel=True,cancel_page=EMPLOYEE_MENU_PAGE) - - def update_user_account_balance(add_money:int): - account_number=int(add_balance_search_other[0].text().strip()) - backend.update_balance(add_money,account_number) - add_balance_other[0].setText("") - add_balance_other[1].setText("") - show_popup_message(stacked_widget, "Balance updated successfully", EMPLOYEE_MENU_PAGE) - add_balance_search_other[0].setText("") - - # Withdraw money page - withdraw_money_search_page,withdraw_money_search_other = search_result(stacked_widget, "Withdraw Money","Enter Account Number: ") - withdraw_money_search_other[1].clicked.connect(lambda: withdraw_money_page_submit_btn(int(withdraw_money_search_other[0].text().strip()))) - - - withdraw_money_page,withdraw_money_other =update_user(stacked_widget, "Withdraw Money From User Account","Withdraw Amount: ") - withdraw_money_other[3].clicked.connect(lambda:update_user_account_withdraw(withdraw_money_other[2].text().strip())) - - def withdraw_money_page_submit_btn(account_number:int): - print(account_number) - check = backend.check_acc_no(account_number) - print(check) - if check: - account_data = backend.get_details(account_number) - withdraw_money_other[0].setText(str(account_data[1])) - withdraw_money_other[1].setText(str(account_data[4])) - stacked_widget.setCurrentIndex(16) - return account_data - else: - show_popup_message(stacked_widget, "Account not found", EMPLOYEE_WITHDRAW_MONEY_SEARCH,show_cancel=True,cancel_page=EMPLOYEE_MENU_PAGE) - - def update_user_account_withdraw(withdraw_money:int): - account_number=int(withdraw_money_search_other[0].text().strip()) - backend.deduct_balance(int(withdraw_money),int(account_number)) - withdraw_money_other[0].setText("") - withdraw_money_other[1].setText("") - show_popup_message(stacked_widget, "Balance updated successfully", EMPLOYEE_MENU_PAGE) - withdraw_money_search_other[0].setText("") + def setup_balance_operation_flow( + stacked_widget, + title_search, + placeholder, + title_form, + action_button_text, + success_message, + backend_action_fn, + stacked_page_index, + search_index, + page_index + ): + # Create search UI + search_page, search_widgets = search_result(stacked_widget, title_search, placeholder) + search_input = search_widgets[0] + search_button = search_widgets[1] + + # Create update UI + form_page, form_widgets = update_user(stacked_widget, title_form, action_button_text) + name_field, balance_field, amount_field, action_button = form_widgets + + def on_search_submit(): + try: + account_number = int(search_input.text().strip()) + except ValueError: + show_popup_message(stacked_widget, "Please enter a valid account number.", search_index) + return + + if backend.check_acc_no(account_number): + account_data = backend.get_details(account_number) + name_field.setText(str(account_data[1])) + balance_field.setText(str(account_data[4])) + stacked_widget.setCurrentIndex(page_index) + else: + show_popup_message(stacked_widget, "Account not found", search_index, show_cancel=True, cancel_page=EMPLOYEE_MENU_PAGE) + + def on_action_submit(): + try: + account_number = int(search_input.text().strip()) + amount = int(amount_field.text().strip()) + backend_action_fn(amount, account_number) + name_field.setText("") + balance_field.setText("") + search_input.setText("") + show_popup_message(stacked_widget, success_message, EMPLOYEE_MENU_PAGE) + except ValueError: + show_popup_message(stacked_widget, "Enter valid numeric amount.", page_index) + + search_button.clicked.connect(on_search_submit) + action_button.clicked.connect(on_action_submit) + + return search_page, form_page + # Add Balance Flow + add_balance_search_page, add_balance_page = setup_balance_operation_flow( + stacked_widget=stacked_widget, + title_search="Add Balance", + placeholder="Enter Account Number: ", + title_form="Add Balance User Account", + action_button_text="Enter Amount: ", + success_message="Balance updated successfully", + backend_action_fn=backend.update_balance, + stacked_page_index=EMPLOYEE_ADD_BALANCE_SEARCH, + search_index=EMPLOYEE_ADD_BALANCE_SEARCH, + page_index=EMPLOYEE_ADD_BALANCE_PAGE, + ) + + # Withdraw Money Flow + withdraw_money_search_page, withdraw_money_page = setup_balance_operation_flow( + stacked_widget=stacked_widget, + title_search="Withdraw Money", + placeholder="Enter Account Number: ", + title_form="Withdraw Money From User Account", + action_button_text="Withdraw Amount: ", + success_message="Amount withdrawn successfully", + backend_action_fn=backend.deduct_balance, + stacked_page_index=EMPLOYEE_WITHDRAW_MONEY_SEARCH, + search_index=EMPLOYEE_WITHDRAW_MONEY_SEARCH, + page_index=EMPLOYEE_WITHDRAW_MONEY_PAGE, + ) + stacked_widget.addWidget(home_page)#0 stacked_widget.addWidget(admin_page)#1 From dc2e65bddbfc49a7750ae56d6c7f302fd14394df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Jun 2025 19:47:17 +0000 Subject: [PATCH 437/442] Bump pymongo from 4.12.1 to 4.13.2 Bumps [pymongo](https://github.com/mongodb/mongo-python-driver) from 4.12.1 to 4.13.2. - [Release notes](https://github.com/mongodb/mongo-python-driver/releases) - [Changelog](https://github.com/mongodb/mongo-python-driver/blob/master/doc/changelog.rst) - [Commits](https://github.com/mongodb/mongo-python-driver/compare/4.12.1...4.13.2) --- updated-dependencies: - dependency-name: pymongo dependency-version: 4.13.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 39189267917..1f89c2c71d2 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -42,7 +42,7 @@ obs==0.0.0 todo==0.1 oauth2client==4.1.3 keras==3.10.0 -pymongo==4.12.1 +pymongo==4.13.2 playsound==1.3.0 pyttsx3==2.98 auto-mix-prep==0.2.0 From 86fca1b5b67ac7417391b6c10de0b35d8cc23649 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Jun 2025 19:49:08 +0000 Subject: [PATCH 438/442] Bump yfinance from 0.2.62 to 0.2.63 Bumps [yfinance](https://github.com/ranaroussi/yfinance) from 0.2.62 to 0.2.63. - [Release notes](https://github.com/ranaroussi/yfinance/releases) - [Changelog](https://github.com/ranaroussi/yfinance/blob/main/CHANGELOG.rst) - [Commits](https://github.com/ranaroussi/yfinance/compare/0.2.62...0.2.63) --- updated-dependencies: - dependency-name: yfinance dependency-version: 0.2.63 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 39189267917..57bf5e70014 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -66,7 +66,7 @@ speechtotext==0.0.3 wikipedia==1.4.0 tqdm==4.67.1 Menu==3.2.2 -yfinance==0.2.62 +yfinance==0.2.63 tweepy==4.15.0 tkcalendar==1.6.1 pytube==15.0.0 From 83e00b47a39b57f6c0eb58c32f82785db3cf3369 Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Wed, 18 Jun 2025 11:43:53 +0530 Subject: [PATCH 439/442] check balance page added --- bank_managment_system/QTFrontend.py | 77 ++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 12 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 50fec0612e6..90c8378d27a 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -23,6 +23,8 @@ EMPLOYEE_ADD_BALANCE_PAGE = 14 EMPLOYEE_WITHDRAW_MONEY_SEARCH = 15 EMPLOYEE_WITHDRAW_MONEY_PAGE = 16 +EMPLOYEE_CHECK_BALANCE_SEARCH = 17 +EMPLOYEE_CHECK_BALANCE_PAGE = 18 FONT_SIZE = QtGui.QFont("Segoe UI", 12) # ------------------------------------------------------------------------------------------------------------- @@ -775,7 +777,7 @@ def create_show_details_page2(parent, title): return page,(account_no_field,name_field,age_field,address_field,balance_field,mobile_number_field,account_type_field,exite_btn) -def update_user(parent, title,input_fields_label): +def update_user(parent, title,input_fields_label,input_fielf:bool=True): page, main_layout = create_page_with_header(parent, title) content_frame = create_styled_frame(page) content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) @@ -788,12 +790,14 @@ def update_user(parent, title,input_fields_label): # Define input fields user = create_input_field(form_frame, "User Name: ", min_label_size=(180, 0)) user_balance = create_input_field(form_frame, "Balance: ", min_label_size=(180, 0)) - user_update_balance = create_input_field_V(form_frame, input_fields_label, min_label_size=(180, 0)) + # Add input fields to the form layout form_layout.addWidget(user[0]) form_layout.addWidget(user_balance[0]) - form_layout.addWidget(user_update_balance[0]) + if input_fielf: + user_update_balance = create_input_field_V(form_frame, input_fields_label, min_label_size=(180, 0)) + form_layout.addWidget(user_update_balance[0]) # Store the input fields in variables user_account_name= user[1] @@ -802,22 +806,42 @@ def update_user(parent, title,input_fields_label): user_balance_field = user_balance[1] user_balance_field.setReadOnly(True) user_balance_field.setStyleSheet("background-color: #8a8a8a; border: 1px solid #ccc; border-radius: 4px; padding: 8px;") - user_update_balance_field = user_update_balance[1] - user_update_balance_field.setStyleSheet("background-color: #f0f0f0; border: 1px solid #ccc; border-radius: 4px; padding: 8px;") + if input_fielf: + user_update_balance_field = user_update_balance[1] + user_update_balance_field.setStyleSheet("background-color: #f0f0f0; border: 1px solid #ccc; border-radius: 4px; padding: 8px;") # Set the font size for the input fields user_account_name.setFont(FONT_SIZE) user_balance_field.setFont(FONT_SIZE) - user_update_balance_field.setFont(FONT_SIZE) + if input_fielf: + user_update_balance_field.setFont(FONT_SIZE) # Add a submit button submit_button = create_styled_button(form_frame, "Submit", min_size=(100, 50)) form_layout.addWidget(submit_button) content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) main_layout.addWidget(content_frame) - - return page,(user_account_name,user_balance_field,user_update_balance_field,submit_button) + back_btn = create_styled_button(content_frame, "Back", min_size=(100, 50)) + back_btn.setStyleSheet(""" + QPushButton { + background-color: #6c757d; + color: white; + border: none; + border-radius: 4px; + padding: 8px 16px; + font-size: 14px; + } + QPushButton:hover { + background-color: #5a6268; + } + """) + back_btn.clicked.connect(lambda: parent.setCurrentIndex(EMPLOYEE_MENU_PAGE)) + backend + if input_fielf: + return page,(user_account_name,user_balance_field,user_update_balance_field,submit_button) + else: + return page,(user_account_name,user_balance_field,submit_button) # ------------------------------------------------------------------------------------------------------------- # === Main Window Setup === @@ -1021,7 +1045,7 @@ def update_employee_data(name, password, salary, position, name_to_update): E_Show_Details.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_SHOW_DETAILS_PAGE1)) E_add_Balance.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_ADD_BALANCE_SEARCH)) E_Withdraw_Money.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_WITHDRAW_MONEY_SEARCH)) - # E_Chack_Balanace.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_CHECK_BALANCE_PAGE)) + E_Chack_Balanace.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_CHECK_BALANCE_SEARCH)) # E_Update_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_UPDATE_ACCOUNT_PAGE)) # E_list_of_all_Members.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_LIST_OF_ALL_MEMBERS_PAGE)) # E_Delete_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_DELETE_ACCOUNT_PAGE)) @@ -1116,7 +1140,8 @@ def setup_balance_operation_flow( backend_action_fn, stacked_page_index, search_index, - page_index + page_index, + need_input=True ): # Create search UI search_page, search_widgets = search_result(stacked_widget, title_search, placeholder) @@ -1124,8 +1149,11 @@ def setup_balance_operation_flow( search_button = search_widgets[1] # Create update UI - form_page, form_widgets = update_user(stacked_widget, title_form, action_button_text) - name_field, balance_field, amount_field, action_button = form_widgets + form_page, form_widgets = update_user(stacked_widget, title_form, action_button_text,need_input) + if need_input: + name_field, balance_field, amount_field, action_button = form_widgets + else: + name_field, balance_field, action_button = form_widgets def on_search_submit(): try: @@ -1186,7 +1214,30 @@ def on_action_submit(): page_index=EMPLOYEE_WITHDRAW_MONEY_PAGE, ) + check_balance_search_page, check_balance_page = setup_balance_operation_flow( + stacked_widget=stacked_widget, + title_search="Check Balance", + placeholder="Enter Account Number: ", + title_form="Check Balance", + action_button_text="Check Balance: ", + success_message="Balance checked successfully", + backend_action_fn=backend.check_balance, + stacked_page_index=EMPLOYEE_CHECK_BALANCE_SEARCH, + search_index=EMPLOYEE_CHECK_BALANCE_SEARCH, + page_index=EMPLOYEE_CHECK_BALANCE_PAGE, + need_input = False + ) + def find_and_hide_submit_button(page): + # Find all QPushButton widgets in the page + buttons = page.findChildren(QtWidgets.QPushButton) + for button in buttons: + if button.text() == "Submit": + button.hide() + break + + find_and_hide_submit_button(check_balance_page) + stacked_widget.addWidget(home_page)#0 stacked_widget.addWidget(admin_page)#1 stacked_widget.addWidget(employee_page)#2 @@ -1204,6 +1255,8 @@ def on_action_submit(): stacked_widget.addWidget(add_balance_page)#14 stacked_widget.addWidget(withdraw_money_search_page)#15 stacked_widget.addWidget(withdraw_money_page)#16 + stacked_widget.addWidget(check_balance_search_page)#17 + stacked_widget.addWidget(check_balance_page)#18 From 133a2957f14c2fde564cc77cc6ea063d7f341e1c Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Wed, 18 Jun 2025 17:11:25 +0530 Subject: [PATCH 440/442] update user data through employee --- bank_managment_system/QTFrontend.py | 64 +++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 90c8378d27a..0e0b837fb44 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -25,6 +25,8 @@ EMPLOYEE_WITHDRAW_MONEY_PAGE = 16 EMPLOYEE_CHECK_BALANCE_SEARCH = 17 EMPLOYEE_CHECK_BALANCE_PAGE = 18 +EMPLOYEE_UPDATE_ACCOUNT_SEARCH = 19 +EMPLOYEE_UPDATE_ACCOUNT_PAGE = 20 FONT_SIZE = QtGui.QFont("Segoe UI", 12) # ------------------------------------------------------------------------------------------------------------- @@ -606,7 +608,7 @@ def create_employee_menu_page(parent, title): return page, *buttons # Unpack as add_button, update_employee, etc. -def create_account_page(parent, title): +def create_account_page(parent, title,update_btn=False): page, main_layout = create_page_with_header(parent, title) content_frame = create_styled_frame(page) @@ -675,8 +677,10 @@ def create_account_page(parent, title): button_frame = create_styled_frame(form_frame, style="padding: 7px;") button_layout = QtWidgets.QVBoxLayout(button_frame) - - submit_button = create_styled_button(button_frame, "Submit", min_size=(100, 50)) + if update_btn: + submit_button = create_styled_button(button_frame, "Update", min_size=(100, 50)) + else: + submit_button = create_styled_button(button_frame, "Submit", min_size=(100, 50)) button_layout.addWidget(submit_button, 0, QtCore.Qt.AlignHCenter) @@ -1046,7 +1050,7 @@ def update_employee_data(name, password, salary, position, name_to_update): E_add_Balance.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_ADD_BALANCE_SEARCH)) E_Withdraw_Money.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_WITHDRAW_MONEY_SEARCH)) E_Chack_Balanace.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_CHECK_BALANCE_SEARCH)) - # E_Update_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_UPDATE_ACCOUNT_PAGE)) + E_Update_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_UPDATE_ACCOUNT_SEARCH)) # E_list_of_all_Members.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_LIST_OF_ALL_MEMBERS_PAGE)) # E_Delete_Account.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_DELETE_ACCOUNT_PAGE)) # E_Back.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_MENU_PAGE)) @@ -1236,6 +1240,56 @@ def find_and_hide_submit_button(page): break find_and_hide_submit_button(check_balance_page) + + # Update Employee details + update_empolyee_search_page,update_empolyee_search_other = search_result(stacked_widget, "Update Employee Details", "Enter Employee ID: ") + update_employee_page,update_employee_other = create_account_page(stacked_widget, "Update Employee", True) + name_edit = update_employee_other[0] + Age_edit = update_employee_other[1] + Address_edit = update_employee_other[2] + Balance_edit = update_employee_other[3] + Mobile_number_edit = update_employee_other[4] + account_type_dropdown = update_employee_other[5] + # name_edit, Age_edit,Address_edit,Balance_edit,Mobile_number_edit, account_type_dropdown ,submit_button + + update_empolyee_search_other[1].clicked.connect(lambda:update_employee_search_submit()) + update_employee_other[6].clicked.connect(lambda:update_employee_submit()) + def update_employee_search_submit(): + try: + user_data = backend.get_details(int(update_empolyee_search_other[0].text().strip())) + print("Featch data: ",user_data) + name_edit.setText(str(user_data[1])) + Age_edit.setText(str(user_data[2])) + Address_edit.setText(str(user_data[3])) + Balance_edit.setText(str(user_data[4])) + Mobile_number_edit.setText(str(user_data[6])) + Balance_edit.setDisabled(True) + account_type_dropdown.setCurrentText(str(user_data[5])) + stacked_widget.setCurrentIndex(EMPLOYEE_UPDATE_ACCOUNT_PAGE) + except ValueError: + show_popup_message(stacked_widget, "Enter valid numeric employee ID.", EMPLOYEE_MENU_PAGE) + + def update_employee_submit(): + try: + user_data = backend.get_details(int(update_empolyee_search_other[0].text().strip())) + name=name_edit.text().strip() + age = int(Age_edit.text().strip()) + address = Address_edit.text().strip() + mobile_number = int(Mobile_number_edit.text().strip()) + account_type = account_type_dropdown.currentText() + print(name,age,address,mobile_number,account_type) + backend.update_name_in_bank_table(name,user_data[0]) + backend.update_age_in_bank_table(age,user_data[0]) + backend.update_address_in_bank_table(address,user_data[0]) + backend.update_address_in_bank_table(address,user_data[0]) + backend.update_mobile_number_in_bank_table(mobile_number,user_data[0]) + backend.update_acc_type_in_bank_table(account_type,user_data[0]) + + show_popup_message(stacked_widget, "Employee details updated successfully", EMPLOYEE_MENU_PAGE) + stacked_widget.setCurrentIndex(EMPLOYEE_MENU_PAGE) + except ValueError as e: + print(e) + show_popup_message(stacked_widget, "Enter valid numeric employee ID.", EMPLOYEE_MENU_PAGE) stacked_widget.addWidget(home_page)#0 @@ -1257,6 +1311,8 @@ def find_and_hide_submit_button(page): stacked_widget.addWidget(withdraw_money_page)#16 stacked_widget.addWidget(check_balance_search_page)#17 stacked_widget.addWidget(check_balance_page)#18 + stacked_widget.addWidget(update_empolyee_search_page)#19 + stacked_widget.addWidget(update_employee_page)#20 From 53939146d5a3a293c71ff6dc5db68a70a70598c0 Mon Sep 17 00:00:00 2001 From: Pratyanj Date: Wed, 18 Jun 2025 17:11:55 +0530 Subject: [PATCH 441/442] add more function related to update customer --- bank_managment_system/backend.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bank_managment_system/backend.py b/bank_managment_system/backend.py index 7ea679863b5..673df2dc430 100644 --- a/bank_managment_system/backend.py +++ b/bank_managment_system/backend.py @@ -115,6 +115,14 @@ def update_address_in_bank_table(new_address, acc_no): cur.execute("UPDATE bank SET address = ? WHERE acc_no = ?", (new_address, acc_no)) conn.commit() +def update_mobile_number_in_bank_table(new_mobile_number, acc_no): + cur.execute("UPDATE bank SET mobile_number = ? WHERE acc_no = ?", (new_mobile_number, acc_no)) + conn.commit() + +def update_acc_type_in_bank_table(new_acc_type, acc_no): + cur.execute("UPDATE bank SET account_type = ? WHERE acc_no = ?", (new_acc_type, acc_no)) + conn.commit() + # List all customers def list_all_customers(): cur.execute("SELECT * FROM bank") From cb1c5293d27c0df0c37820f636f5e6c5ad2ed2ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Jun 2025 18:06:31 +0000 Subject: [PATCH 442/442] Bump ccxt from 4.4.86 to 4.4.90 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.4.86 to 4.4.90. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/v4.4.86...v4.4.90) --- updated-dependencies: - dependency-name: ccxt dependency-version: 4.4.90 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_with_versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_with_versions.txt b/requirements_with_versions.txt index 39189267917..9e32caf6cce 100644 --- a/requirements_with_versions.txt +++ b/requirements_with_versions.txt @@ -81,7 +81,7 @@ Unidecode==1.4.0 Ball==0.2.9 pynput==1.8.1 gTTS==2.5.4 -ccxt==4.4.86 +ccxt==4.4.90 fitz==0.0.1.dev2 fastapi==0.115.12 Django==5.1.7