Almost all files available in this repository are actually from another private repository that I've made a couple years ago, but for security reasons some files have not been ported to this public repository, and that also explains why there is just a couple commits compared to the old repository (that actually have 175 commits).
4 | -------------------------------------------------------------------------------- /Problem Solving Scripts/CNPJ_Checker.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ Nicolas Mendes - Jan 18 2022 4 | 5 | Based on https://programandoautomacao.blogspot.com/2020/10/python-uma-funcao-pythonica-para_15.html 6 | 7 | Algorithm for validating CNPJ 8 | For the CNPJ validation, the weights applied to its digits range from 2 to 11. For the CNPJ, the weights range from 2 to 9 and then we reset the weights (again at 2). And, just like for the CNPJ, the weights are applied from right to left. 9 | 10 | SAMPLE CNPJ: 46.798.277/0001-02 11 | """ 12 | 13 | import re 14 | import sys 15 | 16 | # WARNING: Disable in production! 17 | debugMode = False 18 | 19 | 20 | def logThis(message: str): 21 | """ 22 | This function is used to log messages if debug is enabled. 23 | """ 24 | if debugMode: 25 | print(f"{message}") 26 | 27 | 28 | def receitaFirstLast(): 29 | """ 30 | This function returns the sequence to discover the first of last two digits. 31 | """ 32 | return 543298765432 33 | 34 | 35 | def receitaSecondLast(): 36 | """ 37 | This function returns the sequence to discover the second of last two digits. 38 | """ 39 | return 6543298765432 40 | 41 | 42 | class CNPJ_Validator_N: 43 | """ 44 | This class is used to validate CNPJ numbers. 45 | """ 46 | 47 | def __init__(self, userCNPJ: str): 48 | """ 49 | This function is used to initialize the class. 50 | """ 51 | self.validateCNPJ(userCNPJ) 52 | 53 | validCNPJ = None 54 | partiallyValidation = None 55 | 56 | @staticmethod 57 | # Validates a CNPJ number with the easy way. 58 | def validateCNPJ(userCNPJ: str): 59 | """ 60 | This function is used to validate and clean the CNPJ number. 61 | """ 62 | # regular expression to remove any non-numeric characters, spaces, dots or dashes. 63 | userCNPJ = re.sub("[^0-9]", "", userCNPJ) 64 | logThis(userCNPJ) 65 | 66 | # Check length of CNPJ 67 | if len(userCNPJ) != 14: 68 | validCNPJ = False 69 | logThis("CNPJ is NOT valid.") 70 | return validCNPJ 71 | else: 72 | 73 | # Separate all numbers from userCNPJ into a list. 74 | userCNPJList = list(userCNPJ) 75 | # Sum every integer of the userCNPJList 76 | sumOfDigits = sum(int(i) for i in userCNPJList) 77 | sumOfDigits = str(sumOfDigits) 78 | 79 | # Get first 12 digits from userCNPJ 80 | firstTwelveDigits = userCNPJList[0:12] 81 | 82 | # Let's find the first last digit with this operation. 83 | # Multiply the last 12 numbers with "543298765432". 84 | 85 | # First digit from last section 86 | sumMaster = 0 87 | firstSequenceObj = str(receitaFirstLast()) 88 | firstSequence = [] 89 | firstSequence[:] = firstSequenceObj 90 | 91 | for cnpjNum, eachNum in zip(firstTwelveDigits, firstSequence): 92 | # logThis(f"{cnpjNum} * {eachNum}") 93 | sumMaster += int(cnpjNum) * int(eachNum) 94 | 95 | restSum = sumMaster % 11 96 | logThis(restSum) 97 | 98 | if restSum < 2: 99 | restSum = 0 100 | else: 101 | restSum = 11 - restSum 102 | 103 | # Now let's find the second last digit with this operation. 104 | # Multiply the last 13 numbers with "6543298765432". 105 | 106 | mergePartRes = str(userCNPJ[:12]) + str(restSum) 107 | mergeResList = [] 108 | mergeResList[:] = mergePartRes 109 | 110 | secondSequenceObj = str(receitaSecondLast()) 111 | secondSequence = [] 112 | secondSequence[:] = secondSequenceObj 113 | 114 | sumMasterBeta = 0 115 | for cnpjNum, eachNum in zip(mergeResList, secondSequence): 116 | # logThis(f"{cnpjNum} * {eachNum}") 117 | sumMasterBeta += int(cnpjNum) * int(eachNum) 118 | restSumBeta = sumMasterBeta % 11 119 | 120 | if restSumBeta < 2: 121 | restSumBeta = 0 122 | else: 123 | restSumBeta = 11 - restSumBeta 124 | 125 | mergePartRes = None 126 | mergePartRes = str(userCNPJ[:12]) + str(restSum) + str(restSumBeta) 127 | logThis(f"Merged result: {mergePartRes}") 128 | 129 | if mergePartRes == userCNPJ: 130 | logThis("CNPJ is valid.") 131 | validCNPJ = True 132 | return validCNPJ 133 | else: 134 | logThis("CNPJ is NOT valid.") 135 | validCNPJ = False 136 | return validCNPJ 137 | 138 | 139 | if __name__ == "__main__": 140 | """ 141 | This function is used to run the program. 142 | """ 143 | if debugMode: 144 | sampleCNPJ = "46.798.277/0001-02" 145 | CNPJ_Validator_N.validateCNPJ(sampleCNPJ) 146 | -------------------------------------------------------------------------------- /Problem Solving Scripts/CPF_Checker.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ Nicolas Mendes - Jan 18 2022 4 | 5 | Based on https://www.alura.com.br/conteudo/python-validacao-dados#:~:text=Criando%20um%20novo%20Python%20file,contr%C3%A1rio%20o%20retorno%20ser%C3%A1%20False%20 6 | 7 | Algorithm for validating CPF 8 | The CPF calculation is based on the final 2 digits. 9 | To validate, take the first 9 digits of the CPF, generate the 2 digits and save in a new CPF. 10 | Compare if the CPF sent is the same as the CPF generated. 11 | If true, the CPF is valid, otherwise invalid. 12 | 13 | * Get first digit: 14 | --- Multiply the first 9 digits of the CPF by a count regress starting from 10 and ending at 2. 15 | --- Add all the multiplication values from step 1 16 | --- Get the remainder of the division between the sum and 11 from step 2 17 | --- Subtract the result from step 3 by 11 18 | --- If the result of step 4 is greater than nine, the digit is zero, otherwise the digit is the value from step 4 19 | 20 | * Get second digit: 21 | --- Multiply the first 9 digits of the CPF, PLUS THE FIRST DIGIT, previously obtained by a countdown starting from 11 and ending in 2 22 | --- Same logic as step 2 from the first digit onwards. 23 | 24 | SAMPLE CPF: 113.314.390-35 25 | 26 | TO GET FIRST DIGIT FORM LAST SECTION: 27 | 28 | 1*10 = 10 29 | 1*9 = 9 30 | 3*8 = 24 31 | 3*7 = 21 32 | 1*6 = 6 33 | 4*5 = 20 34 | 3*4 = 12 35 | 9*3 = 27 36 | 0*2 = 0 37 | 38 | TOTAL: 10 + 9 + 24 + 21 + 6 + 20 + 12 + 27 + 0 + 0 = 129 39 | GET THE REST FROM RESULT => 11 - (129 % 11) = 3 40 | 41 | IF RESULT > 9, DIGIT IS 0, ELSE DIGIT IS RESULT. 42 | 43 | TO GET SECOND DIGIT FORM LAST SECTION: 44 | 45 | 1*11 = 11 46 | 1*10 = 10 47 | 3*9 = 27 48 | 3*8 = 21 49 | 1*7 = 7 50 | 4*6 = 18 51 | 3*5 = 15 52 | 9*4 = 36 53 | 0*3 = 0 54 | 3*2 = 6 55 | 56 | TOTAL: 11 + 10 + 27 + 21 + 7 + 18 + 15 + 36 + 0 + 6 = 151 57 | GET THE REST FROM RESULT => 151%11 = 5 58 | 59 | BONUS: 60 | 61 | If the sum pair of all 11 digits are the same, the CPF is invalid. 62 | 63 | EXAMPLE: 64 | DIGITS SUM: 1 + 1 + 3 + 3 + 1 + 4 + 3 + 9 + 0 + 3 + 5 = 33 => Is valid. 65 | 66 | """ 67 | 68 | import re 69 | 70 | # WARNING: Disable in production! 71 | debugMode = False 72 | 73 | 74 | def logThis(message): 75 | """ 76 | This function is used to log messages if debug is enabled. 77 | """ 78 | if debugMode: 79 | print(message) 80 | 81 | 82 | class CPF_Validator_N: 83 | """ 84 | This class is used to validate CPF numbers. 85 | """ 86 | 87 | def __init__(self, cpf: str): 88 | """ 89 | This function is used to initialize the class. 90 | """ 91 | self.validateCPF(cpf) 92 | 93 | validCPF = None 94 | partiallyValidation = False 95 | 96 | @staticmethod 97 | # Validates a CPF number with the easy way. 98 | def validateCPF(userCPF: str): 99 | """ 100 | This function is used to validate and clean the CPF number. 101 | """ 102 | 103 | global partiallyValidation 104 | 105 | # regular expression to remove any non-numeric characters, spaces, dots or dashes. 106 | userCPF = re.sub("[^0-9]", "", userCPF) 107 | logThis(userCPF) 108 | 109 | # Check length of CPF 110 | if len(userCPF) != 11: 111 | validCPF = False 112 | logThis("CPF is NOT valid.") 113 | return False 114 | else: 115 | 116 | # Separate all numbers from userCPF into a list. 117 | userCPFList = list(userCPF) 118 | # Sum every integer of the userCPFList 119 | sumOfDigits = sum(int(i) for i in userCPFList) 120 | sumOfDigits = str(sumOfDigits) 121 | 122 | # Get first nine digits from userCPF 123 | firstNineDigits = userCPFList[0:9] 124 | 125 | # First digit from last section 126 | sumMaster = 0 127 | for key, multiply in enumerate(range(len(firstNineDigits) + 1, 1, -1)): 128 | # logThis(f"{userCPFList[key]} * {multiply}") 129 | sumMaster += int(userCPFList[key]) * multiply 130 | # logThis(sumMaster) 131 | restSum = 11 - (sumMaster % 11) 132 | 133 | # Second Last Digit 134 | sumMasterSec = 0 135 | for key, multiply in enumerate(range(len(firstNineDigits) + 2, 1, -1)): 136 | sumMasterSec += int(userCPFList[key]) * multiply 137 | restSumSec = 11 - (sumMasterSec % 11) 138 | 139 | if restSum > 9 or restSumSec > 9: 140 | restSum = 0 141 | restSumSec = 0 142 | 143 | mergeRes = str(userCPF[:9]) + str(restSum) + str(restSumSec) 144 | logThis(f"Merged result: {mergeRes}") 145 | 146 | if mergeRes == userCPF and sumOfDigits[0] == sumOfDigits[1]: 147 | return True 148 | else: 149 | logThis(f"CPF is NOT valid.") 150 | return False 151 | 152 | 153 | if __name__ == "__main__" and debugMode == True: 154 | """ 155 | This function is used to run the program. 156 | """ 157 | if debugMode: 158 | sampleCPF = "113.314.390-35" 159 | CPF_Validator_N.validateCPF(sampleCPF) 160 | -------------------------------------------------------------------------------- /Problem Solving Scripts/CPF_Generator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ Nicolas Mendes - Jan 26 2022 4 | 5 | Based on https://www.alura.com.br/conteudo/python-validacao-dados#:~:text=Criando%20um%20novo%20Python%20file,contr%C3%A1rio%20o%20retorno%20ser%C3%A1%20False%20, https://gist.github.com/lucascnr/24c70409908a31ad253f97f9dd4c6b7c 6 | 7 | The CPF calculation is based on the final 2 digits. 8 | To validate, take the first 9 digits of the CPF, generate the 2 digits and save in a new CPF. 9 | Compare if the CPF sent is the same as the CPF generated. 10 | If true, the CPF is valid, otherwise invalid. 11 | 12 | SAMPLE CPF: 113.314.390-35 13 | """ 14 | 15 | import random 16 | from CPF_Checker import CPF_Validator_N as isThisValid 17 | 18 | # WARNING: Disable in production! 19 | debugMode = False 20 | 21 | 22 | def logThis(message): 23 | """ 24 | This function is used to log messages if debug is enabled. 25 | """ 26 | if debugMode: 27 | print(message) 28 | 29 | 30 | class CPF_GEN: 31 | """ 32 | This class is used to generate CPF numbers. 33 | """ 34 | 35 | logThis("Generating CPF...") 36 | 37 | def __init__(self): 38 | """ 39 | This function is used to initialize the class. 40 | """ 41 | self.checkCPF() 42 | 43 | @staticmethod 44 | def generateCPF(): 45 | """ 46 | This function is used to generate the CPF. 47 | """ 48 | 49 | nineDigits = None 50 | while True: 51 | nineDigits = [random.randint(0, 9) for i in range(9)] 52 | if nineDigits != nineDigits[::-1]: 53 | break 54 | 55 | for i in range(9, 11): 56 | value = sum((nineDigits[num] * ((i + 1) - num) for num in range(0, i))) 57 | digit = ((value * 10) % 11) % 10 58 | nineDigits.append(digit) 59 | 60 | # Start with random sequence between 0 and 9 61 | result = "".join(map(str, nineDigits)) 62 | logThis(f"Generated CPF: {result}") 63 | formatGenCPF = f"{result[0:3]}.{result[3:6]}.{result[6:9]}-{result[9:11]}" 64 | return formatGenCPF 65 | 66 | def checkCPF(): 67 | 68 | while ( 69 | isThisValid.validateCPF(CPF_GEN.generateCPF()) != True 70 | and isThisValid.validateCPF(CPF_GEN.generateCPF()) is not None 71 | ): 72 | CPF_GEN.checkCPF() 73 | logThis( 74 | f"CPF is invalid, generating another one..." 75 | ) 76 | else: 77 | logThis(f"CPF is valid! {CPF_GEN.generateCPF()}") 78 | return CPF_GEN.generateCPF() 79 | 80 | 81 | if __name__ == "__main__": 82 | """ 83 | This function is used to run the program. 84 | """ 85 | # CPF_GEN.checkCPF() 86 | print(CPF_GEN.checkCPF()) 87 | -------------------------------------------------------------------------------- /Problem Solving Scripts/__pycache__/CPF_Checker.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DreamDevourer/Python-Fundamentals-Study/28784bd8b8c9b92e631a3b1d4173d489ed71ec3d/Problem Solving Scripts/__pycache__/CPF_Checker.cpython-39.pyc -------------------------------------------------------------------------------- /Problem Solving Scripts/basic_investment_calc.py: -------------------------------------------------------------------------------- 1 | """ 2 | Interesting resources: 3 | https://docs.python.org/3/library/functions.html#built-in-functions 4 | https://docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex 5 | https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals 6 | https://docs.python.org/3/tutorial/introduction.html#numbers 7 | https://docs.python.org/3/tutorial/modules.html#modules 8 | """ 9 | 10 | whatCurrency = input("What currency are you using? (USD/BRL) ") 11 | incomePercentage = input("What is the income percentage per year? ") 12 | investUntil = input("See the projection until: (ex: 5) ") 13 | howMuch = input("How much do you want to invest? ") 14 | print(" ") 15 | 16 | 17 | # Calculate the income 18 | FinalIncome = float(howMuch) * (float(incomePercentage) / 100) 19 | totalIncome = float(FinalIncome) + float(howMuch) 20 | print("Your final income in " + str(investUntil) + 21 | " years is " + str(totalIncome * int(investUntil)) + " " + whatCurrency) 22 | print(" ") 23 | 24 | # Print the income each year in investUntil 25 | for eachYearIncome in range(1, int(investUntil) + 1): 26 | print("In " + str(eachYearIncome) + " year(s) you will have " + 27 | str(totalIncome * eachYearIncome) + " " + whatCurrency) 28 | -------------------------------------------------------------------------------- /Problem Solving Scripts/bonus_and_salary.py: -------------------------------------------------------------------------------- 1 | """ 2 | The employees of a company will receive a 5% salary increase and a bonus at the end of the year equivalent to 20% of the new salary. 3 | """ 4 | 5 | bonusQuantity = 5 6 | endOfYearPercentage = 20 7 | 8 | employeeSalary = float(input("Enter the employee's salary: ")) 9 | # Calculate the percentage employeeSalary with bonusQuantity 10 | bonus = employeeSalary * bonusQuantity / 100 11 | # Calculate the percentage employeeSalary with endOfYearPercentage 12 | endOfYear = employeeSalary * endOfYearPercentage / 100 13 | # Calculate the new salary 14 | newSalary = employeeSalary + bonus + endOfYear 15 | print("With the bonus it will be: ", bonus + employeeSalary) 16 | print("With the end of year it will be: ", endOfYear + employeeSalary) 17 | print("Final salary is: ", newSalary) 18 | -------------------------------------------------------------------------------- /Problem Solving Scripts/medicine_box.py: -------------------------------------------------------------------------------- 1 | """ 2 | I need to take 1.6ml of a medicine every day. A box of this medicine comes with a bottle of 20ml. 3 | """ 4 | quantityTaken = 1.6 5 | boxBottleQuantity = 20 6 | 7 | monthsToTake = input("How many months do you need to take this medicine? ") 8 | monthsToTake = int(monthsToTake) 9 | 10 | print("Ok, you will take:", quantityTaken * 30, " ml each month.") 11 | print("So... You will have to take: ", (quantityTaken * 30) 12 | * monthsToTake, " ml of medicine in total.") 13 | print("That means you will need to buy: ", 14 | int(((quantityTaken * 30) * monthsToTake) / boxBottleQuantity), " boxes of medicine.") 15 | -------------------------------------------------------------------------------- /Problem Solving Scripts/movie-food-decider/food.json: -------------------------------------------------------------------------------- 1 | { 2 | "foods": [ 3 | "Apple", 4 | "Banana", 5 | "Orange" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /Problem Solving Scripts/movie-food-decider/movie-food.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import json 4 | import sys 5 | import os 6 | import random 7 | 8 | foodDict = {} 9 | movieDict = {} 10 | 11 | currentDir = os.path.dirname(sys.argv[0]) 12 | 13 | 14 | def randomFood(): 15 | with open(f"{currentDir}/food.json", "r") as json_food: 16 | foodStored = json.load(json_food) 17 | foodDict = foodStored 18 | foodList = foodDict["foods"] 19 | randomFood = random.choice(foodList) 20 | return randomFood 21 | 22 | 23 | def randomMovie(): 24 | with open(f"{currentDir}/movies.json", "r") as json_movies: 25 | moviesStored = json.load(json_movies) 26 | movieDict = moviesStored 27 | movieList = movieDict["movies"] 28 | randomMovie = random.choice(movieList) 29 | return randomMovie 30 | 31 | 32 | class main(): 33 | userChoice = input("Would you like to eat or watch a movie? ") 34 | 35 | if userChoice == "eat" or userChoice == "food": 36 | print(randomFood()) 37 | elif userChoice == "watch" or userChoice == "movie": 38 | print(randomMovie()) 39 | else: 40 | print("Please enter eat or watch") 41 | -------------------------------------------------------------------------------- /Problem Solving Scripts/movie-food-decider/movies.json: -------------------------------------------------------------------------------- 1 | { 2 | "movies": [ 3 | "Dune", 4 | "Star Trek", 5 | "Star Wars" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /Problem Solving Scripts/price_quantity_calc.py: -------------------------------------------------------------------------------- 1 | """ 2 | Idea: 3 | A fair sells hot dog and refrigerant. 4 | Each hot dog is sold by 8 USD. 5 | Each refrigerant is sold by 5 USD. 6 | """ 7 | 8 | howManyHD = input("How many hot dogs do you want to buy? ") 9 | howManyRef = input("How many refrigerants do you want to buy? ") 10 | 11 | #Values in USD 12 | hotDogPrice = 8.0 13 | refPrice = 5.0 14 | 15 | finalHDInt = int(howManyHD) 16 | finalRefInt = int(howManyRef) 17 | 18 | print("You have to pay: $", (finalHDInt * hotDogPrice) + (finalRefInt * refPrice)) 19 | print("Thank you.") 20 | -------------------------------------------------------------------------------- /Problem Solving Scripts/q-min_jumps_array.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | we have an array {1,4,3,7,1,2,6,7,6,10} we need to reach at the end of the array 4 | and we have to do this using minimum number of jumps. 5 | 6 | So let each element in the array represent the number of steps we can move forward. 7 | So 1 means one step forward, 4 means 4 steps forward. 8 | Now starting at 1 we reach 4. So that is one jump. Now we are at 4 so we will 9 | move 4 steps forward, as we are moving 4 steps forward we compare each element with 4. 10 | Since 3<4 we will ignore it. Now 7>4, so we will store it as we will use this later. 11 | Now from 4 we hv reached 2. So that is 2 jumps. 12 | 13 | Now since 4 steps are over, we will use the 7 that we had stored and move 7- 3 14 | (the position of 7 in the array) steps. So we will reach the end of the array in 15 | total 3 jumps. 16 | """ 17 | 18 | 19 | def jumps(self): 20 | jumps = [0] * len(self.arr) 21 | jumps[0] = 1 22 | for i in range(1, len(self.arr)): 23 | for j in range(i): 24 | if self.arr[j] + j >= i: 25 | jumps[i] = max(jumps[i], jumps[j] + 1) 26 | return jumps[-1] 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |This repository is dedicated for my fundamental knowledge related to Python 3 and newer. I intend to work on this repository weekly.
4 | 5 |6 | License 7 |
8 | 9 |In this repository I study the practical application of:
12 |Advanced scripts related to daily and possible market problems solving, high use of all practical applications on each script.
39 | 40 |Scripts with focus on conversion operations, using part of practical application topics
42 | 43 |Mathematical operations scripts to calculate and/or give mathematical results.
45 | 46 |These scripts are daily general problem solving scripts, like an investment calculator, a salary bonus calculation, price per quantity, etc.
48 | 49 |Simple and direct strings scripts with minimal interaction with the user.
51 | 52 |An initiative by Dr. Angela Yu to learn Python by building 100 projects in 100 days. Learning to build websites, games, apps, plus scraping and data science.
54 | 55 | ## 🦾 100 Days Coding Challenge Pieces 56 | 57 | #### **Day 1** - Band Name Generator 58 | #### **Day 2** - Tip Calculator 59 | #### **Day 3** - Interactive Story 60 | #### **Day 4** - Rock, Paper, Scissors game 61 | #### **Day 5** - Password Generator 62 | #### **Day 6** - Reeborg Maze Solution 63 | #### **Day 7** - Hangman Game 64 | #### **Day 8** - Caesar Cipher 65 | #### **Day 9** - Silent/Secret Auction 66 | #### **Day 10** - Calculator App 67 | #### **Day 11** - Blackjack Capstone Project 68 | #### **Day 12** - Guessing Game 69 | #### **Day 13** - Debugger 70 | #### **Day 14** - Higher or Lower game 71 | #### **Day 15** - Coffee machine project 72 | #### **Day 16** - Object Oriented Programming with Coffee Machine 73 | #### **Day 17** - Object Oriented Programming with Quiz App 74 | #### **Day 18** - Turtle and GUI 75 | #### **Day 19** - Etch a Sketch with Turtle GUI 76 | #### **Day 20** - Snake Game 77 | #### **Day 21** - Advanced Snake Game 78 | #### **Day 22** - Pong Game 79 | #### **Day 23** - Turtle crossing road Game 80 | #### **Day 24** - Improved Snake Game 81 | #### **Day 25** - Work with CSV files with Pandas 82 | #### **Day 26** - List and Dictionary comprehensions with NATO phonetic alphabet 83 | #### **Day 27** - Tkinter GUI 84 | #### **Day 28** - Advanced Tkinter GUI - Pomodoro App 85 | #### **Day 29** - Tkinter GUI Password Manager 86 | #### **Day 30** - Password Manager JSON implementation 87 | #### **Day 31** - Flash card program - Frequency language dictionary 88 | #### **Day 32** - Send Emails and date/time management 89 | #### **Day 33** - API endpoints - ISS tracker 90 | #### **Day 34** - Trivia API to work with Quiz app 91 | #### **Day 35** - Authentication, SMS sender 92 | #### **Day 36** - Stock Trading News 93 | #### **Day 37** - Habit tracking app 94 | #### **Day 38** - Exercise tracking app 95 | #### **Day 39** - Cheap flight finder 96 | #### **Day 40** - Flight Club app 97 | #### **Day 41** - Basic Web Development with Python 98 | #### **Day 42** - Intermediate Web Development with Python 99 | #### **Day 43** & **Day 44** - Website Development 100 | #### **Day 45** - Web scraping with BeautifulSoup 101 | #### **Day 46** - Musical Time Machine 102 | #### **Day 47** - Automated Amazon price tracker 103 | #### **Day 48** - Game Playing Bot 104 | #### **Day 49** - LinkedIn Job Application Automation 105 | #### **Day 50** - Auto Tinder Swiping Bot 106 | #### **Day 51** - Twitter compliant bot 107 | #### **Day 52** - Instagram follower bot 108 | #### **Day 53** - Web scraping - Data entry job automation 109 | #### **Day 54** - Web Development with Flask 110 | #### **Day 55** - Parsing web elements with Flask 111 | #### **Day 56** - Website Templates 112 | #### **Day 57** - Jinja with Flask 113 | #### **Day 58** - Bootstrap 114 | #### **Day 59** - Blog Capstone 115 | #### **Day 60** - Web forms and POST with Flask 116 | #### **Day 61** - Advanced forms with Flask WT-Forms 117 | #### **Day 62** - Wifi Project 118 | #### **Day 63** - Database with SQLite 119 | #### **Day 64** - Top 10 Movies 120 | #### **Day 65** - Web Design and Development project study 121 | #### **Day 66** - RESTful API 122 | #### **Day 67** - Advanced RESTful API 123 | #### **Day 68** - Authentication with Flask 124 | #### **Day 69** - Adding users in a database 125 | #### **Day 70** - Deploy web app with Heroku 126 | #### **Day 71** - Data exploration with Pandas 127 | #### **Day 72** - Data visualization with Matplotlib 128 | #### **Day 73** - Analysis of LEGO database 129 | #### **Day 74** - Google Trends Data 130 | #### **Day 75** - Plotly Charts 131 | #### **Day 76** - Computation with NumPy 132 | #### **Day 77** - Linear Regression 133 | #### **Day 78** - Nobel Prize Analysis 134 | #### **Day 79** - Handwashing 135 | #### **Day 80** - Predict Houses Prices 136 | #### **Day 81** - Convert Strings into Morse Code 137 | #### **Day 82** - Portfolio Project Development 138 | #### **Day 83** - Professional Portfolio Project 139 | #### **Day 84** - Watermark adder (GUI) 140 | #### **Day 85** - Typing speed tester (GUI) 141 | #### **Day 86** - Game development with Godot 142 | #### **Day 87** - Cafe and Wifi Website 143 | #### **Day 88** - Web Todo List 144 | #### **Day 89** - Text Writing App 145 | #### **Day 90** - PDF to Audiobook Converter 146 | #### **Day 91** - Image Colour Palette Generator 147 | #### **Day 92** - Custom Web Scraper 148 | #### **Day 93** - Google Dinosaur Game bot 149 | #### **Day 94** - Space Invaders with Godot 150 | #### **Day 95** - Landing Page 151 | #### **Day 96** - Ecommerce website page 152 | #### **Day 97** - Custom Automation 153 | #### **Day 98** - Generate random profile pictures 154 | #### **Day 99** - Youtube channel tracker 155 | #### **Day 100** - Predict Earnings using Multivariable Regressio 156 | 157 | 158 | 159 | ## 💡 Useful Snippets and study pieces 160 | 161 |Here are some useful snippets to use daily for boosting code efficiency. Every single snippet is coming from a study script that I made from this repository.
162 | 163 |Useful for loading external assets in specific directories and subdirectories, this snippet will work on every major OS like Windows, MacOS, Linux and BSD.
165 | 166 | ```python 167 | import pathlib 168 | from pathlib import Path 169 | 170 | # Dynamic File Path Solution 171 | OUTPUT_PATH = pathlib.Path(__file__).parent.absolute() 172 | ASSETS_PATH = OUTPUT_PATH / Path("./assets") 173 | 174 | 175 | def relative_to_assets(path: str) -> Path: 176 | return ASSETS_PATH / Path(path) 177 | ``` 178 | 179 | OR 180 | 181 | ```python 182 | import pathlib 183 | import shutil 184 | from pathlib import Path 185 | 186 | # Dynamic File Path Solution 187 | THIS_PATH = pathlib.Path(__file__).parent.absolute() 188 | ASSETS_PATH = THIS_PATH / Path("aarch64") 189 | 190 | 191 | def relative_to_assets(path: str) -> Path: 192 | return ASSETS_PATH / Path(path) 193 | 194 | 195 | def relative_to_target(path: str) -> Path: 196 | return THIS_PATH / Path(path) 197 | 198 | 199 | def copy_and_overwrite(from_path, to_path): 200 | if os.path.exists(to_path): 201 | shutil.rmtree(to_path) 202 | shutil.copytree(from_path, to_path) 203 | ``` 204 | 205 |While can be used to start a script on the core part of it or to use as a logic operator.
207 | 208 | ```python 209 | while True: 210 | answer = input("Do you want to try again? (Y/n) ") 211 | if answer == 'y' or answer == 'Y' or sys.stdin.isatty(): 212 | num = int(input("Enter a number: ")) 213 | print(num2roman(num)) 214 | elif answer == 'n': 215 | break 216 | else: 217 | print("Invalid input.") 218 | ``` 219 | 220 |For loops are essential these days, there is no doubt about that. It's possible to make a huge range of logical solutions with lists, arrays and other variables.
222 | 223 | ```python 224 | for link in linksFinder: 225 | print(link.get("href")) 226 | 227 | saveFile = input( 228 | "Do you want to save this list inside a text file? (y/n) ") 229 | if saveFile == "y": 230 | with open("links.txt", "a") as file: 231 | file.write(link.get("href") + "\n") 232 | else: 233 | pass 234 | ``` 235 | 236 | 237 |Randomization is a must need thing in our code, so this is a quick snippet to random lists.
239 | 240 | ```python 241 | import random 242 | 243 | sample = ['a', 'b', 'c', 'd', 'e'] 244 | print(random.choice(sample)) 245 | 246 | # For cryptographically secure random choices (e.g., for generating a passphrase from a wordlist), use secrets.choice(): 247 | 248 | import secrets 249 | 250 | sample = ['battery', 'correct', 'horse', 'staple'] 251 | print(secrets.choice(sample)) 252 | 253 | ``` 254 | 255 |Randomization is a must need thing in our code, so this is a quick snippet to randomize dictionaries.
257 | 258 | ```python 259 | import random 260 | 261 | visualSet = {"Rock": rock, "Paper": paper, "Scissors": scissors} 262 | aiChoice = random.choice(list(visualSet.values())) 263 | 264 | """All possible ways to randomize: 265 | 266 | 'd' is the dictionary variable. 267 | 268 | A random key: 269 | random.choice(list(d.keys())) 270 | 271 | A random value: 272 | random.choice(list(d.values())) 273 | 274 | A random key and value: 275 | random.choice(list(d.items())) 276 | """ 277 | 278 | ``` 279 |If the script needs root user privileges then we need to use this snippet to call sudo.
281 | 282 | ```python 283 | import subprocess 284 | 285 | rootNeeded = subprocess.call(["/usr/bin/sudo", "/usr/bin/id"]) 286 | ``` 287 | 288 |Bytes converts an object to an immutable byte-represented object of given size and data, which is useful for writing or reading HEX values inside a file.
290 | 291 | ```python 292 | # Bytes Encode and Decode Study 293 | 294 | def writeString(): 295 | # Write a string at the end of a JPG file. 296 | with open(relative_to_assets('photo.jpg'), 'ab') as f: # ab append bytes mode 297 | f.write(b' Hidden message: test :)') # b is for bytes 298 | 299 | def readString(): 300 | # Read HEX of the JPG file. 301 | with open(relative_to_assets('photo.jpg'), 'rb') as f: # Read bytes mode 302 | jpgContent = f.read() 303 | # when FF D9 occurs. 304 | offset = jpgContent.index(bytes.fromhex('FFD9')) 305 | f.seek(offset + 2) 306 | print(f.read()) 307 | 308 | def deleteString(): 309 | # delete everything after the last FF D9 from a JPG file 310 | with open(relative_to_assets('photo.jpg'), 'r+') as f: # Read bytes mode 311 | jpgContent = f.read() 312 | offset = jpgContent.index(bytes.fromhex('FFD9')) 313 | f.seek(offset + 2) 314 | f.truncate() 315 | ``` 316 | 317 |This function returns True if a string ends with the specified suffix (case-sensitive), otherwise returns False. A tuple of string elements can also be passed to check for multiple options. For startswith we have a similar approach.
319 | 320 | ```python 321 | from pathlib import Path 322 | import pathlib 323 | files = os.listdir(ASSETS_PATH) 324 | 325 | # Interesting solution to pick specific files inside a list. 326 | for file in files: 327 | if file.endswith(".png") or file.endswith(".jpg") or file.endswith(".jpeg"): 328 | print(f"Optimizing {file}") 329 | imgOptimize = Image.open(relative_to_assets(str(file))) 330 | imgWidth, imgHeight = imgOptimize.size 331 | else: 332 | print(f"{file} is not a PNG or JPG, skipping") 333 | ``` 334 | 335 |Regular expression is a special sequence of characters that helps you match or find other strings or sets of strings, using a specialized syntax held in a pattern. Regular expressions are widely used in UNIX world.
337 | 338 | ```python 339 | import re 340 | 341 | # Regular Expression from module re; 342 | # https://docs.python.org/3/library/re.html 343 | # validate def will make sure that the remTwo var can have a "." as float 344 | 345 | 346 | def validate(string): 347 | result = re.match(r"(\+|\-)?\d+(\.\d+)?$", string) 348 | return result is not None 349 | ``` 350 | 351 |Usually when we need to call a shell script within a python script, paths tends to break and not be cross compatible between python and shell lines. So this snippet helps to solve that.
353 | 354 | ```python 355 | import os 356 | import sys 357 | 358 | # Python path. This will pick the current directory where the script is located. 359 | current_dir = os.path.dirname(sys.argv[0]) 360 | # OR 361 | current_shell_dir = os.path.dirname(os.path.abspath(__file__)) 362 | 363 | # Shell path. This will pick "current_dir" and replace any possible empty spaces with "\" and other fixes to be compatible with any unix-like Shell. 364 | 365 | fixDirPath = current_dir.replace(" ", "\\ ").replace("?", "\\?").replace("&", "\\&").replace( 366 | "(", "\\(").replace(")", "\\)").replace("*", "\\*").replace("<", "\\<").replace(">", "\\>") 367 | 368 | 369 | targetDirectory = "Sample" 370 | 371 | # Sample script usage to delete a directory using shell commands 372 | os.system(f"rm -rf {str(fixDirPath)}/{str(targetDirectory)}") 373 | ``` 374 | 375 |Input is a built-in function in Python, allows coders to receive information through the keyboard, which they can process in a Python program. This is basic and essential.
377 | 378 | ```python 379 | # Simple like that :) 380 | userString = input("Enter a text: ") 381 | print(userString[::-1]) # Reverse the string 382 | ``` 383 | 384 |Making mathematical operations inside python are easy things to do, you basically need to know the formula and the logic to implement conversion and precision operations.
386 | 387 | ```python 388 | minutes = "24.785089" 389 | print(minutes + " minutes is equal to " + 390 | str(float(minutes)/60/24/365) + " years.") 391 | ``` 392 | 393 |With a simple array, it's possible to compare ordinal numbers with strings that represents roman numbers.
395 | 396 | ```python 397 | num_map = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'), (100, 'C'), (90, 'XC'), 398 | (50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')] 399 | 400 | # Function to convert the numbers to roman values. Based on NullDev algorithm. 401 | 402 | 403 | def num2roman(num): 404 | 405 | roman = '' 406 | 407 | while num > 0: 408 | for i, r in num_map: 409 | while num >= i: 410 | roman += r 411 | num -= i 412 | 413 | return roman 414 | ``` 415 | 416 |Converting temperature units is a simple task, all that is needed is the formula of each unit.
418 | 419 | ```python 420 | # Simple formulas to convert temperature from Celsius to Fahrenheit and vice versa. 421 | fahrenheit = celsius * 9 / 5 + 32 422 | celsius = (fahrenheit - 32) * 5 / 9 423 | ``` 424 | 425 |When copying content to the user's clipboard, it's needed to import the OS module to use features like that.
427 | 428 | ```python 429 | import os 430 | nameGen = "Hello there :)" 431 | # Copy to the variable "nameGen" to the clipboard 432 | os.system(f"echo {nameGen} | pbcopy") 433 | ``` 434 | 435 |Opening external websites or applications also requires the OS module to be imported, this snippet allows the script to open almost every type of file, like Shell scripts, default applications and websites.
437 | 438 | ```python 439 | import os 440 | targetSite = "https://google.com/" 441 | os.system(f"open {targetSite}") 442 | ``` 443 | 444 | 445 |Watchdog is used to monitor events on the OS, that means that it's possible to monitor files and folders. To be more specific: Python API library and shell utilities to monitor file system events.
447 | 448 | ```python 449 | from watchdog.observers import Observer 450 | from watchdog.events import FileSystemEventHandler 451 | 452 | currentUser = "default" 453 | mainDirectory = f"/Users/{currentUser}/Downloads" 454 | jobDestinationPath = f"/Users/{currentUser}/Documents/Remotish" 455 | 456 | class MyHandler(FileSystemEventHandler): # We need to create a class with the FileSystemEventHandler 457 | 458 | # After that we need to make a function with self and event. So when anything happens to the folder it will execute the function. 459 | def on_modified(self, event): 460 | for individualFile in os.listdir(mainDirectory): 461 | os.rename(f"{mainDirectory}/{individualFile}", f"{jobDestinationPath}/{individualFile}") 462 | 463 | # Needed to monitor Watchdog 464 | eventHandler = MyHandler() 465 | observer = Observer() 466 | observer.schedule(eventHandler, mainDirectory, recursive=True) 467 | observer.start() 468 | 469 | # Needed to monitor Watchdog 470 | try: 471 | while True: 472 | time.sleep(10) 473 | except KeyboardInterrupt: 474 | observer.stop() 475 | observer.join() 476 | ``` 477 | 478 | 479 |JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. These days, JSON is mandatory. This little snippet can read a json file and output its content.
481 | 482 | ```json 483 | { 484 | "_comment": "SAMPLE JSON FILE", 485 | "username": "testABC", 486 | "password": "testDEF" 487 | } 488 | ``` 489 | 490 | ```python 491 | import json 492 | import sys 493 | import os 494 | 495 | userContent = {} 496 | current_dir = os.path.dirname(sys.argv[0]) 497 | 498 | with open(f"{current_dir}/sample-json.json", "r") as json_file: 499 | userContent = json.load(json_file) 500 | print(userContent["username"]) 501 | print(userContent["password"]) 502 | ``` 503 | 504 |This little snippet can write a json file and output its content.
506 | 507 | ```json 508 | { 509 | "_comment": "SAMPLE JSON FILE", 510 | "username": "testABC", 511 | "password": "testDEF" 512 | } 513 | ``` 514 | 515 | ```python 516 | import json 517 | import sys 518 | import os 519 | 520 | userContent = {} 521 | current_dir = os.path.dirname(sys.argv[0]) 522 | 523 | userInp = input("Enter your username: ") 524 | userInp2 = input("Enter your password: ") 525 | 526 | userContent["username"] = f"{str(userInp)}" 527 | userContent["password"] = f"{str(userInp2)}" 528 | 529 | 530 | with open(f"{current_dir}/sample-json.json", "w") as json_file: 531 | json.dump(userContent, json_file) 532 | print(f"The new username is: {str(userContent['username'])}") 533 | print(f"The new password is: {str(userContent['password'])}") 534 | ``` 535 | 536 | 537 |Here are some ways to read the API path content with a simple GET method and some extra calls.
539 | 540 | ```python 541 | import requests 542 | import json 543 | 544 | responseAPI = requests.get('https://randomfox.ca/floof') 545 | 546 | # This will return a simple status code. 547 | print(responseAPI.status_code) 548 | # This will return a string value with the contents inside the API URL. 549 | print(responseAPI.text) 550 | # Now printing json format and using as a dictionary. 551 | print(responseAPI.json()) 552 | ``` 553 | 554 | 555 |Reading values from an API can be done very easily by using the requests module and also to converting the API values into Python dictionaries using json module and function.
557 | 558 | ```python 559 | import requests 560 | import json 561 | 562 | # Getting the API url/path 563 | responseAPI = requests.get('https://randomfox.ca/floof') 564 | # Output from GET: {'image': 'https://randomfox.ca/images/13.jpg', 'link': 'https://randomfox.ca/?i=13'} 565 | generatedFoxImg = responseAPI.json() 566 | 567 | print(f"Your random fox: {generatedFoxImg['image']} \n") 568 | ``` 569 | 570 | 571 |FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints. Making GET requests are easy thing to do, just need to import the module and associate the function to a variable and start coding paths and parameters with the FastAPI Functions.
573 | 574 | ```python 575 | from fastapi import FastAPI 576 | 577 | appStudy = FastAPI() 578 | 579 | 580 | @appStudy.get("/") 581 | async def root(): 582 | return {"messageField": "Message content here."} 583 | ``` 584 | 585 |The POST method is used to request that the origin server accept the entity attached in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.
587 | 588 | ```python 589 | from fastapi import FastAPI, Path 590 | from pydantic import BaseModel 591 | 592 | appStudy = FastAPI() 593 | 594 | class Item(BaseModel): 595 | name: str 596 | price: float 597 | quantity: Optional[int] = None 598 | 599 | # This is actually the API values 600 | inventoryDict = { 601 | "1": {"name": "Bread", "price": 1.25, "quantity": "10"}, 602 | "2": {"name": "Milk", "price": 2.45, "quantity": "5"}, 603 | "3": {"name": "Eggs", "price": 3.99, "quantity": "20"}, 604 | "4": {"name": "Cheese", "price": 4.99, "quantity": "15"}, 605 | "5": {"name": "Butter", "price": 5.00, "quantity": "5"} 606 | } 607 | 608 | # Using POST method 609 | @appStudy.post("/post-item/{item_id}") 610 | def createItem(item_id: int, item: Item): 611 | # Let's create a new item id. 612 | if item_id in inventoryDict: 613 | return {"DataErr": "Item already exists"} 614 | else: 615 | inventoryDict[str(item_id)] = item 616 | return inventoryDict[str(item_id)] 617 | ``` 618 | 619 | 620 |PUT method requests for the attached entity (in the request body) to be stored into the server which hosts the supplied Request-URI. If the Request-URI refers to an already existing resource – an update operation will happen
622 | 623 | ```python 624 | from fastapi import FastAPI, Path 625 | from pydantic import BaseModel 626 | from fastapi.encoders import jsonable_encoder 627 | from typing import Optional 628 | 629 | appStudy = FastAPI() 630 | 631 | # This class is for the PUT request 632 | class updateItem(BaseModel): 633 | name: Optional[str] = None 634 | price: Optional[float] = None 635 | quantity: Optional[int] = None 636 | 637 | # This is actually the API values 638 | inventoryDict = { 639 | "1": {"name": "Bread", "price": 1.25, "quantity": "10"}, 640 | "2": {"name": "Milk", "price": 2.45, "quantity": "5"}, 641 | "3": {"name": "Eggs", "price": 3.99, "quantity": "20"}, 642 | "4": {"name": "Cheese", "price": 4.99, "quantity": "15"}, 643 | "5": {"name": "Butter", "price": 5.00, "quantity": "5"} 644 | } 645 | 646 | # PUT method 647 | @appStudy.put("/put-item/{item_id}") 648 | def createItem(item_id: int, item: Item): 649 | # Let's create a new item id. 650 | if item_id in inventoryDict: 651 | return {"DataErr": "Item already exists"} 652 | else: 653 | inventoryDict[str(item_id)] = item 654 | return inventoryDict[str(item_id)] 655 | ``` 656 | 657 | 658 |Obfuscation is the deliberate act of creating source or machine code that is difficult for humans to understand, this helps to improve security - it is far from being the ultimate security solution but is a thing to use in a non-production environment.
660 | 661 | For creating a file with the key and obfuscating it: 662 | 663 | ```python 664 | import base64 665 | import pathlib 666 | import os 667 | import re 668 | from pathlib import Path 669 | 670 | # Dynamic File Path Solution 671 | API_PATH = pathlib.Path(__file__).parent.absolute() 672 | 673 | 674 | def relative_to_assets(path: str) -> Path: 675 | return API_PATH / Path(path) 676 | 677 | userChange = input("Enter key: ").strip() 678 | 679 | # Pick userChange and encode it to base64 680 | userChange = base64.b64encode(userChange.encode('utf-8')) 681 | # Save userChange to "API" file 682 | with open(relative_to_assets('Data/security/API'), 'wb') as f: 683 | # Delete everything inside the file. 684 | f.truncate() 685 | f.write(userChange) 686 | 687 | print("DONE! You are ready to use the API!") 688 | 689 | ``` 690 | 691 |XOR Encryption is an encryption method used to encrypt data and is hard to crack by brute-force method, i.e generating random encryption keys to match with the correct one.
693 | 694 | Encrypting: 695 | 696 | ```python 697 | #! /usr/bin/env python3 698 | import base64 699 | import os 700 | import pathlib 701 | import re 702 | from pathlib import Path 703 | 704 | # Dynamic File Path Solution 705 | KEY_PATH = pathlib.Path(__file__).parent.absolute() 706 | 707 | 708 | def relative_to_assets(path: str) -> Path: 709 | return KEY_PATH / Path(path) 710 | 711 | 712 | def encryptSecurity(): 713 | # Use external script to make base64 or https://www.base64encode.org/ 714 | key = "MTMy" # up 255 715 | key = base64.b64decode(key) 716 | cleanKey = re.sub( 717 | r"[^A-Za-z0-9-]", "", key.decode("utf-8")) 718 | finalKey = int(cleanKey) 719 | 720 | loadEnc00 = open(relative_to_assets("Data/security/.KEY"), "rb") 721 | byteReaderData = loadEnc00.read() 722 | loadEnc00.close() 723 | 724 | byteReaderData = bytearray(byteReaderData) 725 | for index, value in enumerate(byteReaderData): 726 | byteReaderData[index] = value ^ finalKey 727 | 728 | Enc = open(relative_to_assets("Data/security/.KEY.nclmE"), "wb") 729 | Enc.write(byteReaderData) 730 | Enc.close() 731 | 732 | # Delete Data/security/KEY 733 | os.remove(relative_to_assets("Data/security/.KEY")) 734 | 735 | 736 | encryptSecurity() 737 | 738 | ``` 739 | 740 | Decrypting: 741 | 742 | ```python 743 | #! /usr/bin/env python3 744 | import base64 745 | import os 746 | import pathlib 747 | import re 748 | import string 749 | from pathlib import Path 750 | import signal 751 | 752 | # Dynamic File Path Solution 753 | KEY_PATH = pathlib.Path(__file__).parent.absolute() 754 | 755 | 756 | def relative_to_assets(path: str) -> Path: 757 | return KEY_PATH / Path(path) 758 | 759 | 760 | def signal_handler(sig, frame): 761 | # If the program exits then remove important files. 762 | os.remove(relative_to_assets("Data/security/.tmp/.KEY")) 763 | exit() 764 | 765 | 766 | def decryptSecurity(): 767 | # Use external script to make base64 or https://www.base64encode.org/ 768 | key = "MTMy" # up 255 769 | key = base64.b64decode(key) 770 | cleanKey = re.sub( 771 | r"[^A-Za-z0-9-]", "", key.decode("utf-8")) 772 | finalKey = int(cleanKey) 773 | 774 | loadEnc00 = open(relative_to_assets( 775 | "Data/security/.KEY.nclmE"), "rb").read() 776 | 777 | byteReader = bytearray(loadEnc00) 778 | for index, value in enumerate(byteReader): 779 | byteReader[index] = value ^ finalKey 780 | 781 | decEnc = open(relative_to_assets("Data/security/.tmp/.KEY"), "wb") 782 | decEnc.write(byteReader) 783 | 784 | 785 | try: 786 | # signal handler for "CTRL + C" 787 | signal.signal(signal.SIGINT, signal_handler) 788 | decryptSecurity() 789 | signal.pause() 790 | except: 791 | # In exeption remove important files. 792 | os.remove(relative_to_assets("Data/security/.tmp/.KEY")) 793 | 794 | ``` 795 | 796 |Logs provide developers with an extra set of eyes that are constantly looking at the flow that an application is going through.
798 | 799 | ```python 800 | 801 | import os 802 | import time 803 | import subprocess 804 | import pathlib 805 | from pathlib import Path 806 | 807 | currentVersion = "v1.0.5 - Release" 808 | pid = os.getpid() 809 | 810 | OUTPUT_PATH = pathlib.Path(__file__).parent.absolute() 811 | LOGS_PATH = OUTPUT_PATH / Path("./logs") 812 | 813 | def relative_to_logs(path: str) -> Path: 814 | """Return a path relative to the logs folder.""" 815 | return LOGS_PATH / Path(path) 816 | 817 | def get_timestamp(): 818 | """Return a unix timestamp.""" 819 | return time.time() 820 | 821 | def logRoutine(log: str, timeNeeded: bool = True): 822 | """Write strings to the log file and if debug is enabled, print it to console.""" 823 | 824 | if timeNeeded is None: 825 | timeNeeded = True 826 | 827 | debugMode = False 828 | currentTime = time.strftime("%m-%d-%Y -> %H:%M:%S") 829 | logHeader = f"""{currentVersion} 830 | =================================================== 831 | LOG FILE MADE FOR DEBUG PURPOSES 832 | made by Nicolas Mendes - September 2021 833 | ===================================================\n 834 | """ 835 | 836 | # Check if "ioc.log" exists, if not create this file. 837 | if not os.path.exists(relative_to_logs("ioc.log")): 838 | open(f"{relative_to_logs('ioc.log')}", "w+") 839 | # append logHeader to the file. 840 | with open(f"{relative_to_logs('ioc.log')}", "a") as logFile: 841 | logFile.write(logHeader) 842 | 843 | # if the first line of ioc.log is different from currentVersion 844 | with open(f"{relative_to_logs('ioc.log')}") as checkVer: 845 | firstlineVer = checkVer.readline().rstrip() 846 | if firstlineVer != currentVersion: 847 | # Delete everything inside the file and append logHeader. 848 | with open(f"{relative_to_logs('ioc.log')}", "w+") as logFile: 849 | logFile.write(logHeader) 850 | 851 | # if the file exceeds 1000 lines, delete everything and append logHeader to the file. 852 | with open(f"{relative_to_logs('ioc.log')}", "r") as logFile: 853 | if len(logFile.readlines()) > 1000: 854 | with open(f"{relative_to_logs('ioc.log')}", "w") as logFile: 855 | logFile.write(logHeader) 856 | 857 | # Append the log to the file. 858 | 859 | if timeNeeded == True: 860 | with open(f"{relative_to_logs('ioc.log')}", "a") as logFile: 861 | logFile.write(f"{currentTime} - {log}\n") 862 | else: 863 | with open(f"{relative_to_logs('ioc.log')}", "a") as logFile: 864 | logFile.write(f"{log}\n") 865 | 866 | if debugMode == True: 867 | return print(f"DEBUG LOG: {log}") 868 | 869 | logRoutine( 870 | f"\n\n[OK] ===> Python loaded. Starting new instance at PID: {pid} | UTS: {get_timestamp()}\n", 871 | False, 872 | ) 873 | 874 | ``` 875 | 876 | 877 | ## 📄 License 878 | 879 | Permissions of this strong copyleft license are conditioned on making available complete source code of licensed works and modifications, which include larger works using a licensed work, under the same license. Copyright and license notices must be preserved. Contributors provide an express grant of patent rights. 880 | 881 | | Permissions | Restrictions | Conditions 882 | | --- | --- | --- 883 | ✓ Commercial Use | × Liability | 🛈 License and Copyright Notice 884 | ✓ Modification | × Warranty | 🛈 State changes 885 | ✓ Distribution | | 🛈 Disclose source 886 | ✓ Patent Use | | 🛈 Same license 887 | ✓ Private Use 888 | -------------------------------------------------------------------------------- /String Based Scripts/basic_input.py: -------------------------------------------------------------------------------- 1 | """ 2 | Interesting resources: 3 | https://docs.python.org/3/library/functions.html#built-in-functions 4 | https://docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex 5 | https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals 6 | https://docs.python.org/3/tutorial/introduction.html#numbers 7 | https://docs.python.org/3/tutorial/modules.html#modules 8 | """ 9 | username = input("What is your name? ") 10 | print("Hello, " + username + "!") 11 | print("Tell me, how old are you?") 12 | age = input() 13 | print("You are " + age + " years old.") 14 | print("Awesome, now let me know what is your favorite number!") 15 | number = input() 16 | print("Cool, so your favorite number is " + number + ".") 17 | print("That's all, thank you.") 18 | quit() 19 | -------------------------------------------------------------------------------- /String Based Scripts/clipboard_time_defs.py: -------------------------------------------------------------------------------- 1 | """ Made by Nicolas Mendes - Sept 24 2021 2 | Script to study how to use time and clipboard. 3 | """ 4 | from datetime import date, timedelta 5 | import os 6 | 7 | namePrint = "Name Last Name" 8 | # Pick current month 9 | currentMonth = date.today().month 10 | # Pick current day 11 | currentDay = date.today().day 12 | # Randomly change between 1 and 9 mins. 13 | randomMins = int(os.urandom(1).hex(), 16) % 9 + 1 14 | hourGen = f"14:0{str(randomMins)}" 15 | targetSite = "https://discord.com/channels/XXXXX/XXXXX" 16 | print(f"The random time is: {hourGen}") 17 | 18 | 19 | def allFriday(year): 20 | d = date(year, 1, 1) # Jan 1 21 | d += timedelta(days=4 - d.weekday()) # First Friday 22 | while d.year == year: 23 | yield d 24 | d += timedelta(days=7) 25 | 26 | 27 | for dia in allFriday(2021): 28 | if dia.day == currentDay and dia.month == currentMonth: 29 | nameGen = f"{currentDay}/{currentMonth} - {namePrint}" 30 | print(nameGen) 31 | # Copy to the variable "nameGen" to the clipboard 32 | os.system(f"echo {nameGen} | pbcopy") 33 | os.system(f"open {targetSite}") 34 | -------------------------------------------------------------------------------- /String Based Scripts/downloadsOrganizer.py: -------------------------------------------------------------------------------- 1 | from watchdog.observers import Observer 2 | from watchdog.events import FileSystemEventHandler 3 | import os 4 | import time 5 | 6 | currentUser = "dreamdevourer" 7 | mainDirectory = f"/Users/{currentUser}/Downloads" 8 | 9 | jobDestinationPath = f"/Users/{currentUser}/Documents/Remotish" 10 | personalDestinationPath = f"/Users/{currentUser}/Documents/Personal" 11 | tmpPath = f"/Users/{currentUser}/Downloads/tmp" 12 | 13 | 14 | class MyHandler(FileSystemEventHandler): 15 | print("DEBUG: You are inside the MyHandler.") 16 | 17 | def on_modified(self, event): 18 | print("DEBUG: You are inside on_modified function.") 19 | for fileName in os.listdir(mainDirectory): 20 | # if the filename starts with "job_" then move it to jobDestinationPath 21 | if fileName.startswith("job_") or fileName.startswith("rem_"): 22 | print(f"{fileName} is work asset!") 23 | # move files from mainDirectory to jobDestinationPath 24 | os.rename(f"{mainDirectory}/{fileName}", 25 | f"{jobDestinationPath}/{fileName}") 26 | print(f"{fileName} moved to {jobDestinationPath}") 27 | 28 | elif fileName.startswith("per_"): 29 | print(f"{fileName} is a personal file!") 30 | # move files from mainDirectory to personalDestinationPath 31 | os.rename(f"{mainDirectory}/{fileName}", 32 | f"{personalDestinationPath}/{fileName}") 33 | print(f"{fileName} moved to {personalDestinationPath}") 34 | 35 | elif fileName.startswith("_") or fileName.startswith("tmp_") or fileName.startswith("temp_"): 36 | print(f"{fileName} is a temporary file!") 37 | # move files from mainDirectory to tmpPath 38 | os.rename(f"{mainDirectory}/{fileName}", 39 | f"{tmpPath}/{fileName}") 40 | print(f"{fileName} moved to {tmpPath}") 41 | 42 | 43 | eventHandler = MyHandler() 44 | observer = Observer() 45 | observer.schedule(eventHandler, mainDirectory, recursive=True) 46 | observer.start() 47 | 48 | try: 49 | while True: 50 | time.sleep(10) 51 | except KeyboardInterrupt: 52 | observer.stop() 53 | observer.join() 54 | -------------------------------------------------------------------------------- /String Based Scripts/hideJPG/photo copy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DreamDevourer/Python-Fundamentals-Study/28784bd8b8c9b92e631a3b1d4173d489ed71ec3d/String Based Scripts/hideJPG/photo copy.jpg -------------------------------------------------------------------------------- /String Based Scripts/hideJPG/photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DreamDevourer/Python-Fundamentals-Study/28784bd8b8c9b92e631a3b1d4173d489ed71ec3d/String Based Scripts/hideJPG/photo.jpg -------------------------------------------------------------------------------- /String Based Scripts/hide_jpg_message.py: -------------------------------------------------------------------------------- 1 | """ Made by Nicolas Mendes September 26 2021 2 | Study to understand how JPG/JPEG files work in HEX form and how to hide a string in a JPG file. 3 | Basically JPG images ALWAYS start with "FF D8 FF" and ends with "FF D9". That means we can append a string 4 | on the end of this sequence "FF D9". 5 | """ 6 | import pathlib 7 | from pathlib import Path 8 | import string 9 | 10 | 11 | """ 12 | 0xffd8: "Start of Image", 13 | 0xffe0: "Application Default Header", 14 | 0xffdb: "Quantization Table", 15 | 0xffc0: "Start of Frame", 16 | 0xffc4: "Define Huffman Table", 17 | 0xffda: "Start of Scan", 18 | 0xffd9: "End of Image" 19 | """ 20 | 21 | # Initial Setup to load assets 22 | OUTPUT_PATH = pathlib.Path(__file__).parent.absolute() 23 | ASSETS_PATH = OUTPUT_PATH / Path("./hideJPG") 24 | 25 | 26 | def relative_to_assets(path: str) -> Path: 27 | return ASSETS_PATH / Path(path) 28 | 29 | 30 | while True: 31 | 32 | def writeString(): 33 | with open(relative_to_assets('photo.jpg'), 'ab') as f: # ab append bytes mode 34 | f.write(b' Hidden message: test :)') 35 | 36 | def readString(): 37 | with open(relative_to_assets('photo.jpg'), 'rb') as f: # Read bytes mode 38 | jpgContent = f.read() 39 | # when FF D9 occurs. 40 | offset = jpgContent.index(bytes.fromhex('FFD9')) 41 | f.seek(offset + 2) 42 | print(f.read()) 43 | 44 | def deleteString(): 45 | # delete everything after the last FF D9 46 | with open(relative_to_assets('photo.jpg'), 'r+') as f: # Read bytes mode 47 | jpgContent = f.read() 48 | offset = jpgContent.index(bytes.fromhex('FFD9')) 49 | f.seek(offset + 2) 50 | f.truncate() 51 | 52 | # Check if photo.jpg exists and print it. 53 | if relative_to_assets("photo.jpg").exists(): 54 | print("Found photo.jpg") 55 | readMessage = input( 56 | "Do you want to read, write or delete a message? (r/w/d) ") 57 | if readMessage == "r": 58 | readString() 59 | if readMessage == "w": 60 | writeString() 61 | if readMessage == "d": 62 | deleteString() 63 | 64 | else: 65 | print("Could not find photo.jpg") 66 | -------------------------------------------------------------------------------- /String Based Scripts/reverse_string.py: -------------------------------------------------------------------------------- 1 | # Simple like that :) 2 | userString = input("Enter a text: ") 3 | print(userString[::-1]) 4 | --------------------------------------------------------------------------------