From 83e0de83c07aaf78dffb1508e229b650cc5be290 Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Wed, 24 Jan 2024 23:29:55 +0300 Subject: [PATCH 01/24] chore-emailer --- .../chore-assignment-emailer/chore-emailer.py | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100755 projects/chore-assignment-emailer/chore-emailer.py diff --git a/projects/chore-assignment-emailer/chore-emailer.py b/projects/chore-assignment-emailer/chore-emailer.py new file mode 100755 index 00000000..99d86a2d --- /dev/null +++ b/projects/chore-assignment-emailer/chore-emailer.py @@ -0,0 +1,61 @@ +import random +import smtplib + +def emailer(chores, emails): + """emails random chores to emails + Args: + chores: list of chores + emails: list of emails to send chores + Returns: + None + """ + if not emails: + print('emails list should not be empty') + return + + if not chores: + print('chores list should not be empty') + return + + chores_dict = {} + + f = 0 # front of emails list + + while chores: + + randomChore = random.choice(chores) + chores.remove(randomChore) + email = emails[f] + chores_dict.setdefault(email, []) + chores_dict[email].append(randomChore) + + f = (f+1) % len(emails) # use list circularly + + smtpObj = smtplib.SMTP('smtp.gmail.com', 587) + smtpObj.ehlo() + + + email = input('Enter your email: ') + password = input('Enter your email password: ') + + smtpObj.starttls() + smtpObj.login(email, password) + # See https://support.google.com/accounts/answer/6010255 if (Bad Credentials Error) + + for k, v in chores_dict.items(): + c = ', '.join(v) + print('Sending email to %s...' % k) + sendmailStatus = smtpObj.sendmail(email, k, \ + 'Subject: Your Chores.\nHi There!, {} are your chores'.format(c)) + if sendmailStatus != {}: + print('There was a problem sending email to %s: %s' % (email, + sendmailStatus)) + + smtpObj.quit() + + + + + +if __name__ == "__main__": + emailer(['dishes', 'bathroom', 'vacuum', 'walk dog'], ['example@yahoo.com, example2@yahoo.com']) \ No newline at end of file From 0b999c130de1d236d45f07d7b9fd2e708fe6ebcf Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Wed, 24 Jan 2024 23:30:17 +0300 Subject: [PATCH 02/24] head or tails toss --- projects/coin-toss/coin-toss.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100755 projects/coin-toss/coin-toss.py diff --git a/projects/coin-toss/coin-toss.py b/projects/coin-toss/coin-toss.py new file mode 100755 index 00000000..6f5a1f62 --- /dev/null +++ b/projects/coin-toss/coin-toss.py @@ -0,0 +1,22 @@ +import random + +if __name__ == "__main__": + + guess = '' + options = ['tails', 'heads'] + + while guess not in ('heads', 'tails'): + print('Guess the coin toss! Enter heads or tails:') + guess = input() + + toss = random.randint(0, 1) # 0 is tails, 1 is heads + + if guess == options[toss]: + print('You got it!') + else: + print('Nope! Guess again!') + guess = input() + if guess == options[toss]: + print('You got it!') + else: + print('Nope. You are really bad at this game.') \ No newline at end of file From 33e6c367ccfa7b60b05e9916f87dac8e3dc3a700 Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Wed, 24 Jan 2024 23:31:07 +0300 Subject: [PATCH 03/24] combines list into a string of the form item1,item2,item3 --- projects/comma-code/comma-code.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100755 projects/comma-code/comma-code.py diff --git a/projects/comma-code/comma-code.py b/projects/comma-code/comma-code.py new file mode 100755 index 00000000..22b3a4a0 --- /dev/null +++ b/projects/comma-code/comma-code.py @@ -0,0 +1,21 @@ +def comma_code(items): + """ Combines list into a string of the form item1, item2, and item 3 + Args: + items (list): List of strings + + Returns: + string: list items combined into a string + """ + item_len = len(items) + + if item_len == 0: + return '' + elif item_len == 1: + return items[0] + + return ', '.join(items[:-1]) + ', and ' + items[-1] + + +if __name__ == "__main__": + spam = ['apples', 'bananas', 'tofu', 'cats'] + print(comma_code(spam)) \ No newline at end of file From f4c08e08b3faab58d0545cbf7e7304702b6ef85a Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Wed, 24 Jan 2024 23:32:32 +0300 Subject: [PATCH 04/24] invitations for specified people --- .../custom-invitations/customInvitations.py | 64 +++++++++++++++++++ projects/custom-invitations/guests.txt | 5 ++ 2 files changed, 69 insertions(+) create mode 100755 projects/custom-invitations/customInvitations.py create mode 100755 projects/custom-invitations/guests.txt diff --git a/projects/custom-invitations/customInvitations.py b/projects/custom-invitations/customInvitations.py new file mode 100755 index 00000000..17ecc627 --- /dev/null +++ b/projects/custom-invitations/customInvitations.py @@ -0,0 +1,64 @@ +import os + + +import docx +from docx.enum.text import WD_ALIGN_PARAGRAPH +from docx.shared import Pt + + +def createInvitations(txtFile, docName): + """Creates invitations based on names in txt file + Args: + txtFile (str): text file to read from + docName (str): doc file to save invitations in + """ + doc = docx.Document() + + intro = 'It would be a pleasure to have the company of' + address = 'at 11101 Memory lane on the evening of' + date = 'April 31st' + time = "at 24 O'Clock" + + with open(txtFile) as guestList: + for guest in guestList: + name = guest[:-1] + p1 = doc.add_paragraph() + p1.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER + f1 = p1.add_run(intro) + f1.font.bold = True + f1.font.italic = True + f1.font.size = Pt(13) + + p2 = doc.add_paragraph() + p2.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER + f2 = p2.add_run(name) + f2.font.bold = True + f2.font.size = Pt(15) + + p3 = doc.add_paragraph() + p3.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER + f3 = p3.add_run(address) + f3.font.bold = True + f3.font.italic = True + f3.font.size = Pt(12) + + p4 = doc.add_paragraph() + p4.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER + f4 = p4.add_run(date) + f4.font.size = Pt(12) + + p5 = doc.add_paragraph() + p5.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER + f5 = p5.add_run(time) + f5.font.bold = True + f5.font.italic = True + f5.font.size = Pt(12) + + doc.add_page_break() + + doc.save(docName) + + + +if __name__ == "__main__": + createInvitations('guests.txt', 'invitations.docx') \ No newline at end of file diff --git a/projects/custom-invitations/guests.txt b/projects/custom-invitations/guests.txt new file mode 100755 index 00000000..e7f09c79 --- /dev/null +++ b/projects/custom-invitations/guests.txt @@ -0,0 +1,5 @@ +Prof. Plum +Miss Scarlet +Col. Mustard +Al Sweigart +Robocop \ No newline at end of file From 77b9d68b3d3981ebdc3e2d78af353dee07b168c4 Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Wed, 24 Jan 2024 23:33:04 +0300 Subject: [PATCH 05/24] custom cards invitation --- projects/custom-seating-cards/Pacifico.ttf | Bin 0 -> 75568 bytes projects/custom-seating-cards/custom_cards.py | 44 ++++++++++++++++++ projects/custom-seating-cards/flower.png | Bin 0 -> 23478 bytes projects/custom-seating-cards/guests.txt | 5 ++ 4 files changed, 49 insertions(+) create mode 100755 projects/custom-seating-cards/Pacifico.ttf create mode 100755 projects/custom-seating-cards/custom_cards.py create mode 100755 projects/custom-seating-cards/flower.png create mode 100755 projects/custom-seating-cards/guests.txt diff --git a/projects/custom-seating-cards/Pacifico.ttf b/projects/custom-seating-cards/Pacifico.ttf new file mode 100755 index 0000000000000000000000000000000000000000..6d47cdc9acee83109bbbf1d444ea9a0c67ade028 GIT binary patch literal 75568 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 literal 0 HcmV?d00001 diff --git a/projects/custom-seating-cards/custom_cards.py b/projects/custom-seating-cards/custom_cards.py new file mode 100755 index 00000000..46a422bd --- /dev/null +++ b/projects/custom-seating-cards/custom_cards.py @@ -0,0 +1,44 @@ +import os + + +from PIL import Image, ImageDraw, ImageFont + +def make_cards(guestList): + """Makes custom cards for each guest + Args: + guestList (str): Path to file containing guest list + Returns: + None + """ + # make folder to store resulting images + os.makedirs('imageCards', exist_ok=True) + + # load flower image + flowerImg = Image.open('flower.png') + + # read each guest from file + with open(guestList) as file: + for line in file: + guest = line[:-1] + + # create image + card = Image.new('RGBA', (288, 360), 'white') + # add flower image + card.paste(flowerImg, (0, 0)) + + # create border around image + border = Image.new('RGBA', (291, 363), 'black') + border.paste(card, (3,3)) + + # draw guest name + draw_obj = ImageDraw.Draw(border) + card_font = ImageFont.truetype('Pacifico.ttf', 24) + draw_obj.text((120, 100), guest, fill='red', font=card_font) + + # save resulting image + imageName = '{}_card.png'.format(guest) + border.save(os.path.join('imageCards', imageName)) + + +if __name__ == "__main__": + make_cards('guests.txt') \ No newline at end of file diff --git a/projects/custom-seating-cards/flower.png b/projects/custom-seating-cards/flower.png new file mode 100755 index 0000000000000000000000000000000000000000..2db93dfcefc642c0091a9ca085c4a0d9b78fde37 GIT binary patch literal 23478 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 bj$;2`9bR4 Date: Wed, 24 Jan 2024 23:33:43 +0300 Subject: [PATCH 06/24] excel to csv file extension convertor --- projects/excel-to-csv-converter/excelToCsv.py | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100755 projects/excel-to-csv-converter/excelToCsv.py diff --git a/projects/excel-to-csv-converter/excelToCsv.py b/projects/excel-to-csv-converter/excelToCsv.py new file mode 100755 index 00000000..7abb45d8 --- /dev/null +++ b/projects/excel-to-csv-converter/excelToCsv.py @@ -0,0 +1,45 @@ +import os +import csv + + +import openpyxl + + +def excelToCsv(folder): + """converts sheets in every excel file in a folder to csv + Args: + folder (str): folder containing excel files + Returns: + None + """ + for excelFile in os.listdir(folder): + # Skip non-xlsx files, load the workbook object. + if not excelFile.endswith('xlsx'): + continue + wb = openpyxl.load_workbook(excelFile) + + for sheetName in wb.get_sheet_names(): + # Loop through every sheet in the workbook. + sheet = wb.get_sheet_by_name(sheetName) + + # Create the CSV filename from the Excel filename and sheet title. + csvFilename = excelFile.split('.')[0]+'_'+sheet.title+'.csv' + csvFileObj = open(csvFilename, 'w', newline='') + + # Create the csv.writer object for this CSV file. + csvWriter = csv.writer(csvFileObj) + + # Loop through every row in the sheet. + for rowObj in sheet.rows: + rowData = [] # append each cell to this list + # Loop through each cell in the row. + for cellObj in rowObj: + # Append each cell's data to rowData. + rowData.append(cellObj.value) + # Write the rowData list to the CSV file. + csvWriter.writerow(rowData) + + csvFileObj.close() + +if __name__ == "__main__": + excelToCsv('.') \ No newline at end of file From 63b1e34fa9d3f0769992c0957d8894a66a77bcbe Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Wed, 24 Jan 2024 23:34:38 +0300 Subject: [PATCH 07/24] requirements added --- projects/excel-to-csv-converter/requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 projects/excel-to-csv-converter/requirements.txt diff --git a/projects/excel-to-csv-converter/requirements.txt b/projects/excel-to-csv-converter/requirements.txt new file mode 100644 index 00000000..a717bf13 --- /dev/null +++ b/projects/excel-to-csv-converter/requirements.txt @@ -0,0 +1 @@ +openpyxl \ No newline at end of file From c73508da78813e1039cd80acd4f69158485d880e Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Wed, 24 Jan 2024 23:42:24 +0300 Subject: [PATCH 08/24] requirements added --- projects/custom-invitations/requirements.txt | 1 + projects/custom-seating-cards/requirements.txt | 1 + 2 files changed, 2 insertions(+) create mode 100644 projects/custom-invitations/requirements.txt create mode 100644 projects/custom-seating-cards/requirements.txt diff --git a/projects/custom-invitations/requirements.txt b/projects/custom-invitations/requirements.txt new file mode 100644 index 00000000..7a6646fe --- /dev/null +++ b/projects/custom-invitations/requirements.txt @@ -0,0 +1 @@ +docx \ No newline at end of file diff --git a/projects/custom-seating-cards/requirements.txt b/projects/custom-seating-cards/requirements.txt new file mode 100644 index 00000000..5873a222 --- /dev/null +++ b/projects/custom-seating-cards/requirements.txt @@ -0,0 +1 @@ +Pillow \ No newline at end of file From 0915d3fb032d9584f031d15e506751e2daba7db8 Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Wed, 24 Jan 2024 23:43:07 +0300 Subject: [PATCH 09/24] display how much of what a player has in inventory game --- .../fantasy-game-inventory/game-inventory.py | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100755 projects/fantasy-game-inventory/game-inventory.py diff --git a/projects/fantasy-game-inventory/game-inventory.py b/projects/fantasy-game-inventory/game-inventory.py new file mode 100755 index 00000000..afc94017 --- /dev/null +++ b/projects/fantasy-game-inventory/game-inventory.py @@ -0,0 +1,46 @@ +def displayInventory(inventory): + """ Displays how much of what a player has in inventory + + Args: + inventory (dict): Inventory containing items and their counts + + Returns: + None + """ + print("Inventory:") + item_total = 0 + + for k, v in inventory.items(): + print(v, ' ', k) + item_total += v + + print("Total number of items: " + str(item_total)) + +def addToInventory(inventory, addedItems): + """ Add Items to inventory + Args: + inventory (dict): Inventory containing items and their counts + addedItems (list): Items to add to inventory + + Returns: + updatedInventory (dict): Inventory containing updated items and their counts + """ + updatedInventory = dict(inventory) + # your code goes here + for item in addedItems: + updatedInventory.setdefault(item, 0) + updatedInventory[item] += 1 + + return updatedInventory + + + +if __name__ == "__main__": + + stuff = {'rope': 1, 'torch': 6, 'gold coin': 42, 'dagger': 1, 'arrow': 12} + displayInventory(stuff) + + inv = {'gold coin': 42, 'rope': 1} + dragonLoot = ['gold coin', 'dagger', 'gold coin', 'gold coin', 'ruby'] + inv = addToInventory(inv, dragonLoot) + displayInventory(inv) \ No newline at end of file From 73aa975bbf75116e524a3c10bbb4ff7a698091a9 Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Wed, 24 Jan 2024 23:43:46 +0300 Subject: [PATCH 10/24] fill gaps in numbering of files in folder --- projects/fill-gaps/fill_gaps.py | 88 +++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100755 projects/fill-gaps/fill_gaps.py diff --git a/projects/fill-gaps/fill_gaps.py b/projects/fill-gaps/fill_gaps.py new file mode 100755 index 00000000..203b9a64 --- /dev/null +++ b/projects/fill-gaps/fill_gaps.py @@ -0,0 +1,88 @@ +import os +import re +import shutil + +def getFilesWithPrefix(folderPath, prefix): + """get all files with a certain prefix + Args: + folderPath (str): path to folder to search + Returns: + + """ + fileRegex = re.compile(prefix+'(\d{1,})(.\w+)') + fileList = sorted( [file for file in os.listdir(folderPath) if fileRegex.match(file)] ) + return fileList + +def fillGaps(folderPath, prefix): + """fill gaps in numbering of files in folder + Args: + folderPath (str): path to folder to search + prefix (str): prefix of files to fill gap + Returns: + None + """ + fileList = getFilesWithPrefix(folderPath, prefix) # files sorted ascending order + fileRegex = re.compile(prefix+'(\d{1,})(.\w+)') + + start = int(fileRegex.search(fileList[0]).group(1)) # start with the minimum number in list + count = start # count to be incremented during checks for gaps + max_length = len(fileRegex.search(fileList[-1]).group(1)) # max length of largest number, for padding zeros + + for file in fileList: + + mo = fileRegex.search(file) + fileNum = int(mo.group(1)) + + if fileNum != count: + newFileName = prefix + '0'*(max_length-len(str(fileNum))) + str(count) + mo.group(2) + shutil.move(os.path.abspath(file), os.path.abspath(newFileName)) + + count += 1 + +def insertGaps(folderPath, prefix, index): + """insert gaps in numbering of files in folder + Args: + folderPath (str): path to folder to search + prefix (str): prefix of files to insert gap + index (int): where to insert the gap + Returns: + None + """ + + fileList = getFilesWithPrefix(folderPath, prefix) # files sorted ascending order + fileRegex = re.compile(prefix+'(\d{1,})(.\w+)') + + max_length = len(fileRegex.search(fileList[-1]).group(1)) # max length of largest number, for padding zeros + + firstIndex = int(fileRegex.search(fileList[0]).group(1)) # smallest number + lastIndex = int(fileRegex.search(fileList[-1]).group(1)) # largest number + + if index >= firstIndex and index <= lastIndex: # if gap index falls in range + + i = 0 + currIndex = firstIndex + while currIndex < index: + # loop till the file number is >= gap index + i += 1 + currIndex = int(fileRegex.search(fileList[i]).group(1)) + + if currIndex == index: # if gap index is taken, make a gap else already free + + for file in fileList[i:][::-1]: + # loop through reversed file list, to prevent overwriting results and increment file number + + mo = fileRegex.search(file) + newFileNum = int(mo.group(1)) + 1 + newFileName = prefix + '0'*(max_length-len(str(newFileNum))) + str(newFileNum) + mo.group(2) + shutil.move(os.path.abspath(file), os.path.abspath(newFileName)) + + +if __name__ == "__main__": + + with open('spam001.txt', 'w') as s1, open('spam003.txt', 'w') as s3: + s1.write('spam001') + s3.write('spam003') + + fillGaps('.', 'spam') + #insertGaps('.', 'spam', 2) + \ No newline at end of file From 62f1b57aa4eb1361866c951f0bd41935b22148b9 Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Wed, 24 Jan 2024 23:44:35 +0300 Subject: [PATCH 11/24] walks through a folder tree and searchs for exceptionally large files or folders --- projects/find-unneeded-files/find_unneeded.py | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100755 projects/find-unneeded-files/find_unneeded.py diff --git a/projects/find-unneeded-files/find_unneeded.py b/projects/find-unneeded-files/find_unneeded.py new file mode 100755 index 00000000..cf02fe96 --- /dev/null +++ b/projects/find-unneeded-files/find_unneeded.py @@ -0,0 +1,44 @@ +import os + +def findUnneeded(folderPath, rejectSize): + """walks through a folder tree and searches for exceptionally large files or folders + Args: + folderPath (str): path of folder to walk + rejectSize (int): file size in bytes to possibly delete + Returns: + None + """ + root = os.path.abspath(folderPath) + + for doc in os.listdir(root): + + docPath = os.path.join(root, doc) + + if os.path.isdir(docPath): + size = getDirSize(docPath) + else: + size = os.path.getsize(docPath) + + if size > rejectSize: + print(f'{docPath}: {size}') + +def getDirSize(start_path): + """Finds the total size of a folder and it's contents + Args: + start_path (str): path to folder + Returns: + size (int): folder size in bytes + """ + size = 0 + + for folderName, subFolder, filename in os.walk(start_path): + for file in filename: + filePath = os.path.join(folderName, file) + size += os.path.getsize(filePath) + + + return size + + +if __name__ == '__main__': + findUnneeded('..', 1000) \ No newline at end of file From 158068a63fded3e7d8f2ac71173cf1b2adbca2a2 Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Wed, 24 Jan 2024 23:45:42 +0300 Subject: [PATCH 12/24] image site finder and downloader --- .../image-site-downloader/imgur-downloader.py | 61 +++++++++++++++++++ .../image-site-downloader/requirements.txt | 1 + 2 files changed, 62 insertions(+) create mode 100755 projects/image-site-downloader/imgur-downloader.py create mode 100644 projects/image-site-downloader/requirements.txt diff --git a/projects/image-site-downloader/imgur-downloader.py b/projects/image-site-downloader/imgur-downloader.py new file mode 100755 index 00000000..66edf485 --- /dev/null +++ b/projects/image-site-downloader/imgur-downloader.py @@ -0,0 +1,61 @@ +import os +import requests +import bs4 + +def downloader(query, max_save, output_path): + """ + Args: + query (str): search query + max_save (int): max number of images to save to results + Returns: + None + """ + + # create imgur search url + searchUrl = 'https://imgur.com/search' + queryUrl = searchUrl+'?q='+query + + # set up output_path + abs_output_path = os.path.abspath(output_path) + os.makedirs(abs_output_path, exist_ok=True) + + # Make request to imgur with query + res1 = requests.get(queryUrl) + + try: + res1.raise_for_status() + + # parse res.text with bs4 to images + imugurSoup = bs4.BeautifulSoup(res1.text, 'html.parser') + images = imugurSoup.select('.image-list-link img') + + # extract number image urls + num_to_save = min(max_save, len(images)) + download_links = ['https:'+img.get('src') for img in images[:num_to_save]] + + # make requests for extracted url + for link in download_links: + + # request image link from imgur + res2 = requests.get(link) + + try: + res2.raise_for_status() + + # save to file with url base name in folder results + imgFile = open(os.path.join(abs_output_path, os.path.basename(link)), 'wb') + for chunk in res2.iter_content(100000): + imgFile.write(chunk) + imgFile.close() + + except Exception as exc: + print('There was a problem: %s' % (exc)) + + + + except Exception as exc: + print('There was a problem: %s' % (exc)) + + +if __name__ == '__main__': + downloader('messi', 10, 'results') \ No newline at end of file diff --git a/projects/image-site-downloader/requirements.txt b/projects/image-site-downloader/requirements.txt new file mode 100644 index 00000000..588cb5da --- /dev/null +++ b/projects/image-site-downloader/requirements.txt @@ -0,0 +1 @@ +bs4 \ No newline at end of file From a6452929541ec56d0d58141602dfc326e62d6265 Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Wed, 24 Jan 2024 23:46:49 +0300 Subject: [PATCH 13/24] sends message to an active slack contact --- .../active_identifier.png | Bin 0 -> 6265 bytes .../instant-messenger-bot/requirements.txt | 1 + .../instant-messenger-bot/slack_messenger.py | 49 ++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100755 projects/instant-messenger-bot/active_identifier.png create mode 100644 projects/instant-messenger-bot/requirements.txt create mode 100755 projects/instant-messenger-bot/slack_messenger.py diff --git a/projects/instant-messenger-bot/active_identifier.png b/projects/instant-messenger-bot/active_identifier.png new file mode 100755 index 0000000000000000000000000000000000000000..b55800f40a7e1037a599329b5bb2aacd7fb28f12 GIT binary patch literal 6265 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 S5d;Ib01Z`bP?fS}=>Gx3P@P@? literal 0 HcmV?d00001 diff --git a/projects/instant-messenger-bot/requirements.txt b/projects/instant-messenger-bot/requirements.txt new file mode 100644 index 00000000..cb9eb4aa --- /dev/null +++ b/projects/instant-messenger-bot/requirements.txt @@ -0,0 +1 @@ +pyautogui \ No newline at end of file diff --git a/projects/instant-messenger-bot/slack_messenger.py b/projects/instant-messenger-bot/slack_messenger.py new file mode 100755 index 00000000..179349ff --- /dev/null +++ b/projects/instant-messenger-bot/slack_messenger.py @@ -0,0 +1,49 @@ +import time + +import pyautogui + + +def send_message(contact, message): + """Sends message to an active slack contact + Args: + contact (str): contacts name on slack + message (str): message to send to friend + Returns: + None + """ + try: + print('5 seconds to navigate to slack app..') + time.sleep(5) + + # Use JumpTo slack feature + pyautogui.hotkey('command', 'k') + time.sleep(1) + # Enter contact name in search box, click enter + pyautogui.typewrite(contact) + time.sleep(1) + pyautogui.typewrite(['enter']) + time.sleep(1) + + active = pyautogui.locateOnScreen('active_identifier.png') + + if not active: + print(f'{contact} is not active, skipped contact') + return + + print('Contact is active, sending message...') + pyautogui.typewrite(['tab']) + pyautogui.typewrite(message) + pyautogui.typewrite(['enter']) + + except KeyboardInterrupt: + print('Process was cancelled..') + + +if __name__ == "__main__": + + contacts = input('Enter contact list, separated by space >> Messi Onazi John: ').split(' ') + message = input('Enter the message you wish to send out to them: ') + + for c in contacts: + contact = c.strip() + send_message(contact, message) \ No newline at end of file From a392744822b9d7f25c44344925e2f0a89b65e0b3 Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Wed, 24 Jan 2024 23:47:44 +0300 Subject: [PATCH 14/24] verifies all links within a page, prints broken links --- projects/link-verification/requirements.txt | 1 + projects/link-verification/verify_links.py | 46 +++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 projects/link-verification/requirements.txt create mode 100755 projects/link-verification/verify_links.py diff --git a/projects/link-verification/requirements.txt b/projects/link-verification/requirements.txt new file mode 100644 index 00000000..588cb5da --- /dev/null +++ b/projects/link-verification/requirements.txt @@ -0,0 +1 @@ +bs4 \ No newline at end of file diff --git a/projects/link-verification/verify_links.py b/projects/link-verification/verify_links.py new file mode 100755 index 00000000..8da4a4e1 --- /dev/null +++ b/projects/link-verification/verify_links.py @@ -0,0 +1,46 @@ +import requests +import bs4 + +def verify(url): + """verifies all links within a page, prints broken links + Args: + url (str): url of page to check + Returns: + None + """ + + res1 = requests.get(url) + + try: + res1.raise_for_status() + + soup = bs4.BeautifulSoup(res1.text, 'html.parser') + pageLinks = [link.get('href') for link in soup.select('a') if link.get('href')] + + brokenCount = 0 + goodCount = 0 + + for link in pageLinks: + + if link.startswith('http'): + res2 = requests.get(link) + + try: + + res2.raise_for_status() + print(f'Good: {link}') + goodCount += 1 + + except Exception as exc: + print(f'Broken: {link}') + brokenCount += 1 + + print(f'{goodCount} Good. {brokenCount} Broken') + + + except Exception as exc: + print('There was a problem: %s' % (exc)) + + +if __name__ == "__main__": + verify('https://automatetheboringstuff.com/chapter11/') \ No newline at end of file From 299101850341004ae379d4623a8106f71c84171b Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Wed, 24 Jan 2024 23:48:45 +0300 Subject: [PATCH 15/24] moves mouse every ten seonds to keep apps active --- projects/looking-busy/look_busy.py | 23 +++++++++++++++++++++++ projects/looking-busy/requirements.txt | 0 2 files changed, 23 insertions(+) create mode 100755 projects/looking-busy/look_busy.py create mode 100644 projects/looking-busy/requirements.txt diff --git a/projects/looking-busy/look_busy.py b/projects/looking-busy/look_busy.py new file mode 100755 index 00000000..b6111501 --- /dev/null +++ b/projects/looking-busy/look_busy.py @@ -0,0 +1,23 @@ +import time +import pyautogui + + +def make_busy(): + """Moves mouse every 10 seconds to keep apps active + Args: + None + Returns: + None + """ + print('Press CTRL-C to quit.') + try: + while True: + pyautogui.moveRel(5, 0, 0.5) + pyautogui.moveRel(-5, 0, 0.5) + time.sleep(10) + except KeyboardInterrupt: + print('Process has quit...') + + +if __name__ == "__main__": + make_busy() \ No newline at end of file diff --git a/projects/looking-busy/requirements.txt b/projects/looking-busy/requirements.txt new file mode 100644 index 00000000..e69de29b From d146699c6dcf90f7e4c4d8245a1ae1c0ff69f02f Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Wed, 24 Jan 2024 23:48:58 +0300 Subject: [PATCH 16/24] moves mouse every ten seonds to keep apps active --- projects/looking-busy/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/looking-busy/requirements.txt b/projects/looking-busy/requirements.txt index e69de29b..cb9eb4aa 100644 --- a/projects/looking-busy/requirements.txt +++ b/projects/looking-busy/requirements.txt @@ -0,0 +1 @@ +pyautogui \ No newline at end of file From fd64c0749bca2b34afa7b7850f2c76544d25d9bf Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Thu, 25 Jan 2024 00:41:02 +0300 Subject: [PATCH 17/24] lets the user add their own text anywhere in the text file --- projects/mad-libs/input.txt | 2 ++ projects/mad-libs/mad-libs.py | 27 +++++++++++++++++++++++++++ projects/mad-libs/output.txt | 2 ++ 3 files changed, 31 insertions(+) create mode 100755 projects/mad-libs/input.txt create mode 100755 projects/mad-libs/mad-libs.py create mode 100755 projects/mad-libs/output.txt diff --git a/projects/mad-libs/input.txt b/projects/mad-libs/input.txt new file mode 100755 index 00000000..fb56c0cb --- /dev/null +++ b/projects/mad-libs/input.txt @@ -0,0 +1,2 @@ +The ADJECTIVE panda walked to the NOUN and then VERB. +A nearby NOUN was unaffected by these events. \ No newline at end of file diff --git a/projects/mad-libs/mad-libs.py b/projects/mad-libs/mad-libs.py new file mode 100755 index 00000000..5b43a51f --- /dev/null +++ b/projects/mad-libs/mad-libs.py @@ -0,0 +1,27 @@ +import os +import re + +def madLibs(input_file, output_file): + """lets the user add their own text anywhere the word ADJECTIVE, NOUN, ADVERB, or VERB appears in the text file + Args: + filename (str): name of file to parse + Returns: + None + """ + regex = re.compile(r'(NOUN|ADJECTIVE|ADVERB|VERB)') + + with open(input_file, 'r') as in_file, open(output_file, 'w') as out_file: + + content = in_file.read() + + matches = regex.findall(content) + + for found in matches: + sub = input('Enter a ' + found + ': ') + content = content.replace(found, sub, 1) + + out_file.write(content) + print(content) + +if __name__ == "__main__": + madLibs('input.txt', 'output.txt') diff --git a/projects/mad-libs/output.txt b/projects/mad-libs/output.txt new file mode 100755 index 00000000..c18d4bc4 --- /dev/null +++ b/projects/mad-libs/output.txt @@ -0,0 +1,2 @@ +The a panda walked to the b and then c. +A nearby d was unaffected by these events. \ No newline at end of file From 0566267d10c5033002dd9511c52c46a5088c724f Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Tue, 30 Jan 2024 23:35:00 +0300 Subject: [PATCH 18/24] Comic scraped from xkcd website --- projects/Comics_Scraper/comicXCD_scraper.py | 123 ++++++++++++++++++++ projects/Comics_Scraper/requirements.txt | 1 + 2 files changed, 124 insertions(+) create mode 100755 projects/Comics_Scraper/comicXCD_scraper.py create mode 100644 projects/Comics_Scraper/requirements.txt diff --git a/projects/Comics_Scraper/comicXCD_scraper.py b/projects/Comics_Scraper/comicXCD_scraper.py new file mode 100755 index 00000000..8e85cf42 --- /dev/null +++ b/projects/Comics_Scraper/comicXCD_scraper.py @@ -0,0 +1,123 @@ +#! python3 +import requests, os, bs4, re + +url = 'https://xkcd.com' +#create a directory to store all the comics +os.makedirs('xkcd', exist_ok=True) + + +def imgdownloader(url): + while not url.endswith('#'): + #print out the current page + res = requests.get(url) + res.raise_for_status() #returns None as the request received is 200 which is fine, if received status is 404 there is an exception for bad request + soup = bs4.BeautifulSoup(res.text,"lxml") #r.text is the content of the response in unicode, and r.content is the content of the response in bytes. + #find the comic image on the current page + comic = soup.select('#comic img') #finds tag with comic and its sub tag img + #print(comic) + if comic == []: + #the page did not contaib a comic.. move on + print("No comic was found..") + break + else: + try: + #get the full url to the comic + comicimg = 'http:' + comic[0].get('src') #finds url from the list comic|| basically comic[0] is used as there is just single one element in list!! try print(comic) && print(comic[0]) to see for yourself.. + #check that it is actually a comic and not an interactive page + if "/comics/" in comicimg: + print('Download image %s' % comicimg) + res = requests.get(comicimg) + res.raise_for_status() + #write the image to the xkcd folder + image = open(os.path.join('xkcd', os.path.basename(comicimg)), 'wb') + for chunk in res.iter_content(10000): #default way to write requested content basically chunk is byte by byte writing + image.write(chunk) + image.close() + print('Finished') + break + else: + print("No comic was found..") + break + except requests.exceptions.MissingSchema: + print("Error in downloading img!!") + break + + +def getLatestComicNumber(url): + res=requests.get(url) + res.raise_for_status() #returns None as the request received is 200 which is fine, if received status is 404 there is an exception for bad request + soup=bs4.BeautifulSoup(res.text,"lxml") + prevLink=soup.select('a[rel="prev"]')[0] + url = 'https://xkcd.com' + prevLink.get('href') + x=re.findall('\d+',url) + x=int(x[0])+1 + #print(x) + return x; + + +#this function is basically traversing backwards, it starts from the most recent comic and goes back until n-1 n being number of pages +#as there are no prev before 1 ( :p quite obvious) +def getNextComic(soup): + prevLink=soup.select('a[rel="prev"]')[0] + url = 'https://xkcd.com' + prevLink.get('href') # gets /comic-num/ from current page prev button ..basic crawling!! + return url; + +def getSpecificComic(comic_number): #comic_number + res=url+'/'+comic_number+'/' + try: + imgdownloader(res) + except Exception as e: + print(str(e)) + + +def batchDownloader(): + url = 'https://xkcd.com' + #check to make sure it's not the first page + while not url.endswith('#'): + #print out the current page + print('Current page: %s' % url) + res = requests.get(url) + res.raise_for_status() #returns None as the request received is 200 which is fine, if received status is 400 + soup = bs4.BeautifulSoup(res.text,"lxml") #r.text is the content of the response in unicode, and r.content is the content of the response in bytes. + #find the comic image on the current page + comic = soup.select('#comic img') #finds tag with comic and its sub tag img + #print(comic) + if comic == []: + #the page did not contaib a comic.. move on + print("No comic was found..") + else: + try: + #get the full url to the comic + comicimg = 'http:' + comic[0].get('src') #finds url from the list comic|| basically comic[0] is used as there is just single one element in list!! try print(comic) && print(comic[0]) to see for yourself.. + #check that it is actually a comic and not an interactive page + if "/comics/" in comicimg: + print('Download image %s' % comicimg) + res = requests.get(comicimg) + res.raise_for_status() + #write the image to the xkcd folder + image = open(os.path.join('xkcd', os.path.basename(comicimg)), 'wb') + for chunk in res.iter_content(10000): #default way to write requested content basically chunk is byte by byte writing + image.write(chunk) + image.close() + else: + print("No comic was found..") + except requests.exceptions.MissingSchema: + url = getNextComic(soup) + continue + url=getNextComic(soup) #basically for downloading the first image + #all comics have downloaded + print('Finished') + +def main(): + x=int(input("Choose your option: \n1.Download all images\t2.Download Specific image\n")) + if x==1: + batchDownloader() + if x==2: + y=str(input("Enter any comic number between 1-"+str(getLatestComicNumber(url)))) + try: + getSpecificComic(y) + except Exception as e: + print(str(e)) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/projects/Comics_Scraper/requirements.txt b/projects/Comics_Scraper/requirements.txt new file mode 100644 index 00000000..588cb5da --- /dev/null +++ b/projects/Comics_Scraper/requirements.txt @@ -0,0 +1 @@ +bs4 \ No newline at end of file From 386e29e3992c8dc9ee82e40b49410b93aea2bbf2 Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Tue, 30 Jan 2024 23:39:35 +0300 Subject: [PATCH 19/24] text files to columns in excel worksheet --- projects/Text_to_SpreadSheet/text1.txt | 5 ++++ projects/Text_to_SpreadSheet/text2.txt | 5 ++++ projects/Text_to_SpreadSheet/text3.txt | 5 ++++ projects/Text_to_SpreadSheet/textToSheet.py | 32 +++++++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100755 projects/Text_to_SpreadSheet/text1.txt create mode 100755 projects/Text_to_SpreadSheet/text2.txt create mode 100755 projects/Text_to_SpreadSheet/text3.txt create mode 100755 projects/Text_to_SpreadSheet/textToSheet.py diff --git a/projects/Text_to_SpreadSheet/text1.txt b/projects/Text_to_SpreadSheet/text1.txt new file mode 100755 index 00000000..9ebd8106 --- /dev/null +++ b/projects/Text_to_SpreadSheet/text1.txt @@ -0,0 +1,5 @@ +text1 +tex1, 1 +tex1, 2 +text1, 3 +text1, 4 \ No newline at end of file diff --git a/projects/Text_to_SpreadSheet/text2.txt b/projects/Text_to_SpreadSheet/text2.txt new file mode 100755 index 00000000..d7abc9a3 --- /dev/null +++ b/projects/Text_to_SpreadSheet/text2.txt @@ -0,0 +1,5 @@ +text2 +text2, 1 +text2, 2 +text2, 3 +text2, 4 \ No newline at end of file diff --git a/projects/Text_to_SpreadSheet/text3.txt b/projects/Text_to_SpreadSheet/text3.txt new file mode 100755 index 00000000..fd58e36f --- /dev/null +++ b/projects/Text_to_SpreadSheet/text3.txt @@ -0,0 +1,5 @@ +text3 +text3, 1 +text3, 2 +text3, 3 +text3, 4 \ No newline at end of file diff --git a/projects/Text_to_SpreadSheet/textToSheet.py b/projects/Text_to_SpreadSheet/textToSheet.py new file mode 100755 index 00000000..1914ae13 --- /dev/null +++ b/projects/Text_to_SpreadSheet/textToSheet.py @@ -0,0 +1,32 @@ +import os +import openpyxl + + +def textToSheet(directory, filename): + """converts text files to columns in excel worksheet + Args: + directory (str): folder containing text files + filename (str): name of excel file + Returns: + None + """ + wb = openpyxl.Workbook() + wb.create_sheet(index=0, title='result') + sheet = wb.active + + colIndex = 1 + + # write text files as columns in worksheet + for file in os.listdir(): + if file.endswith('.txt'): + rowIndex = 1 + with open(file) as f: + for line in f: + sheet.cell(row=rowIndex, column=colIndex).value = line + rowIndex += 1 + colIndex += 1 + + wb.save(filename) + +if __name__ == "__main__": + textToSheet('.', 'text-to-cols.xlsx') \ No newline at end of file From b85dc7a80a2e2a12ce2d965161d8bb416eadcccc Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Tue, 30 Jan 2024 23:41:32 +0300 Subject: [PATCH 20/24] writes column date in worksheet into text files --- projects/Worksheet_to_text/sheetToTextFile.py | 26 ++++++++++++++++++ projects/Worksheet_to_text/worksheet.xlsx | Bin 0 -> 5138 bytes 2 files changed, 26 insertions(+) create mode 100755 projects/Worksheet_to_text/sheetToTextFile.py create mode 100755 projects/Worksheet_to_text/worksheet.xlsx diff --git a/projects/Worksheet_to_text/sheetToTextFile.py b/projects/Worksheet_to_text/sheetToTextFile.py new file mode 100755 index 00000000..b13aedcc --- /dev/null +++ b/projects/Worksheet_to_text/sheetToTextFile.py @@ -0,0 +1,26 @@ +import os +import openpyxl + + +def toTextFiles(filename): + """writes column data in worksheet into text files + Args: + filename (str): name of worksheet to read from + Returns: + None + """ + wb = openpyxl.load_workbook(filename) + sheet = wb.active + count = 1 + + for colObj in sheet.columns: + + with open('text-'+str(count)+'.txt', 'w') as file: + for cellObj in colObj: + file.write(cellObj.value) + + count += 1 + + +if __name__ == "__main__": + toTextFiles('worksheet.xlsx') \ No newline at end of file diff --git a/projects/Worksheet_to_text/worksheet.xlsx b/projects/Worksheet_to_text/worksheet.xlsx new file mode 100755 index 0000000000000000000000000000000000000000..78a4dd3084737110453a9a8aa2542f0b5a62b8bd GIT binary patch literal 5138 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 literal 0 HcmV?d00001 From e8f96ae530e11dd01e3261b9107608e0f2684c88 Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Tue, 30 Jan 2024 23:41:57 +0300 Subject: [PATCH 21/24] required library --- projects/Worksheet_to_text/requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 projects/Worksheet_to_text/requirements.txt diff --git a/projects/Worksheet_to_text/requirements.txt b/projects/Worksheet_to_text/requirements.txt new file mode 100644 index 00000000..a717bf13 --- /dev/null +++ b/projects/Worksheet_to_text/requirements.txt @@ -0,0 +1 @@ +openpyxl \ No newline at end of file From aed93485ac7a81afaaa06e04e77d08638f4e6227 Mon Sep 17 00:00:00 2001 From: ibra-kdbra Date: Tue, 30 Jan 2024 23:42:36 +0300 Subject: [PATCH 22/24] required library --- projects/Text_to_SpreadSheet/requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 projects/Text_to_SpreadSheet/requirements.txt diff --git a/projects/Text_to_SpreadSheet/requirements.txt b/projects/Text_to_SpreadSheet/requirements.txt new file mode 100644 index 00000000..a717bf13 --- /dev/null +++ b/projects/Text_to_SpreadSheet/requirements.txt @@ -0,0 +1 @@ +openpyxl \ No newline at end of file From 0041faa0b42f8208e1a1b6c49eac7c550cccd2ba Mon Sep 17 00:00:00 2001 From: ibra-kdbra <135609275+ibra-kdbra@users.noreply.github.com> Date: Sun, 11 Feb 2024 12:56:42 +0300 Subject: [PATCH 23/24] deleted file --- projects/mad-libs/input.txt | 2 -- projects/mad-libs/mad-libs.py | 27 --------------------------- projects/mad-libs/output.txt | 2 -- 3 files changed, 31 deletions(-) delete mode 100755 projects/mad-libs/input.txt delete mode 100755 projects/mad-libs/mad-libs.py delete mode 100755 projects/mad-libs/output.txt diff --git a/projects/mad-libs/input.txt b/projects/mad-libs/input.txt deleted file mode 100755 index fb56c0cb..00000000 --- a/projects/mad-libs/input.txt +++ /dev/null @@ -1,2 +0,0 @@ -The ADJECTIVE panda walked to the NOUN and then VERB. -A nearby NOUN was unaffected by these events. \ No newline at end of file diff --git a/projects/mad-libs/mad-libs.py b/projects/mad-libs/mad-libs.py deleted file mode 100755 index 5b43a51f..00000000 --- a/projects/mad-libs/mad-libs.py +++ /dev/null @@ -1,27 +0,0 @@ -import os -import re - -def madLibs(input_file, output_file): - """lets the user add their own text anywhere the word ADJECTIVE, NOUN, ADVERB, or VERB appears in the text file - Args: - filename (str): name of file to parse - Returns: - None - """ - regex = re.compile(r'(NOUN|ADJECTIVE|ADVERB|VERB)') - - with open(input_file, 'r') as in_file, open(output_file, 'w') as out_file: - - content = in_file.read() - - matches = regex.findall(content) - - for found in matches: - sub = input('Enter a ' + found + ': ') - content = content.replace(found, sub, 1) - - out_file.write(content) - print(content) - -if __name__ == "__main__": - madLibs('input.txt', 'output.txt') diff --git a/projects/mad-libs/output.txt b/projects/mad-libs/output.txt deleted file mode 100755 index c18d4bc4..00000000 --- a/projects/mad-libs/output.txt +++ /dev/null @@ -1,2 +0,0 @@ -The a panda walked to the b and then c. -A nearby d was unaffected by these events. \ No newline at end of file From f71f1853346a740e9d1451668e335fe2a09db510 Mon Sep 17 00:00:00 2001 From: ibra-kdbra <135609275+ibra-kdbra@users.noreply.github.com> Date: Sun, 11 Feb 2024 12:57:44 +0300 Subject: [PATCH 24/24] delete file --- projects/coin-toss/coin-toss.py | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100755 projects/coin-toss/coin-toss.py diff --git a/projects/coin-toss/coin-toss.py b/projects/coin-toss/coin-toss.py deleted file mode 100755 index 6f5a1f62..00000000 --- a/projects/coin-toss/coin-toss.py +++ /dev/null @@ -1,22 +0,0 @@ -import random - -if __name__ == "__main__": - - guess = '' - options = ['tails', 'heads'] - - while guess not in ('heads', 'tails'): - print('Guess the coin toss! Enter heads or tails:') - guess = input() - - toss = random.randint(0, 1) # 0 is tails, 1 is heads - - if guess == options[toss]: - print('You got it!') - else: - print('Nope! Guess again!') - guess = input() - if guess == options[toss]: - print('You got it!') - else: - print('Nope. You are really bad at this game.') \ No newline at end of file