├── Set-1 ├── Problem 1.md ├── Problem 2.md └── Problem 3.md ├── Set-4 ├── Problem 4.md ├── Problem 3.md ├── Introduction.md ├── Problem 6.md ├── pre Problem 7.md ├── Problem 5.md ├── Problem 1.md ├── Problem 7.md ├── Getting started └── Problem 2.md ├── Midterm-Exam ├── Problem 4.md ├── Problem 6.md ├── Problem 5.md ├── Problem 9.md ├── Problem 8.md └── Problem 7.md ├── LICENSE ├── Set-3 ├── Problem 1.md ├── Problem 3.md ├── Problem 2.md ├── Problem 4.md └── Introduction ├── README.md ├── Week-2 └── Exercise: guess my number.md ├── Set-2 ├── Problem 2.md ├── Problem 1.md ├── Introduction.md └── Problem 3.md └── Set-5 └── Introduction.md /Set-1/Problem 1.md: -------------------------------------------------------------------------------- 1 | 2 | Assume s is a string of lower case characters. 3 | Write a program that counts up the number of vowels contained in the string s. Valid vowels are: 'a', 'e', 'i', 'o', and 'u'. 4 | For example, if s = 'azcbobobegghakl', your program should print: 5 | Number of vowels: 5 6 | 7 | ```py 8 | s = 'azcbobobegghakl' 9 | 10 | vowels = 'aeiou' 11 | vowelsCount = 0 12 | for letter in s: 13 | if letter in vowels: 14 | vowelsCount += 1 15 | print(vowelsCount) 16 | ``` 17 | -------------------------------------------------------------------------------- /Set-1/Problem 2.md: -------------------------------------------------------------------------------- 1 | Assume s is a string of lower case characters. 2 | Write a program that prints the number of times the string 'bob' occurs in s. 3 | For example, if s = 'azcbobobegghakl', then your program should print 4 | Number of times bob occurs is: 2 5 | ```python 6 | s = 'azcbobobegghbobakl' 7 | 8 | string = 'bob' 9 | stringCount = 0 10 | stringLength = len(string) 11 | sLength = len(s) 12 | 13 | for n in range (sLength-stringLength+1): 14 | partOfS = (s[n:n+stringLength]) 15 | if string == partOfS: 16 | stringCount += 1 17 | print(stringCount) 18 | ``` 19 | -------------------------------------------------------------------------------- /Set-4/Problem 4.md: -------------------------------------------------------------------------------- 1 | Hand Length 2 | 3 | 4 | We are now ready to begin writing the code that interacts with the player. We'll be implementing the playHand function. This function allows the user to play out a single hand. First, though, you'll need to implement the helper calculateHandlen function, which can be done in under five lines of code. 5 | 6 | ```py 7 | def calculateHandlen(hand): 8 | """ 9 | Returns the length (number of letters) in the current hand. 10 | 11 | hand: dictionary (string int) 12 | returns: integer 13 | """ 14 | 15 | # output initializaction 16 | output = 0 17 | 18 | # sum all dictionary items values 19 | for values in hand.values(): 20 | output += values 21 | 22 | return output 23 | ``` 24 | -------------------------------------------------------------------------------- /Midterm-Exam/Problem 4.md: -------------------------------------------------------------------------------- 1 | Implement a function called closest_power that meets the specifications below. 2 | For example, 3 | ```python 4 | closest_power(3,12) returns 2 5 | closest_power(4,12) returns 2 6 | closest_power(4,1) returns 0 7 | ``` 8 | Paste your entire function, including the definition, in the box below. Do not leave any debugging print statements. 9 | 10 | ```python 11 | def closest_power(base, num): 12 | 13 | #define spare variables 14 | exp = 0 15 | check = 0 16 | #convert to int 17 | num = int(num) 18 | 19 | while output < num: 20 | check = base ** exp 21 | beforeInc = num - base ** exp 22 | afterInc = num - base ** (exp + 1) 23 | if abs(afterInc) >= beforeInc: 24 | return exp 25 | 26 | exp += 1 27 | ``` 28 | -------------------------------------------------------------------------------- /Midterm-Exam/Problem 6.md: -------------------------------------------------------------------------------- 1 | Implement a function that meets the specifications below. 2 | ```python 3 | def deep_reverse(L): 4 | """ assumes L is a list of lists whose elements are ints 5 | Mutates L such that it reverses its elements and also 6 | reverses the order of the int elements in every element of L. 7 | It does not return anything. 8 | """ 9 | # Your code here 10 | ``` 11 | For example, if ```L = [[1, 2], [3, 4], [5, 6, 7]]``` then ```deep_reverse(L)``` mutates ```L``` to be ```[[7, 6, 5], [4, 3], [2, 1]]``` 12 | ```python 13 | def deep_reverse(L): 14 | 15 | # iterate over reversed list 16 | # reverse each item and append it at end 17 | # then cut in half and get rid of first half 18 | 19 | for i in reversed(L): 20 | i.reverse() 21 | L.append(i) 22 | L[:] = L[len(L)//2:] 23 | ``` 24 | -------------------------------------------------------------------------------- /Midterm-Exam/Problem 5.md: -------------------------------------------------------------------------------- 1 | Write a Python function that returns the sum of the pairwise products of listA and listB. You should assume that listA and listB have the same length and are two lists of integer numbers. For example, if listA = [1, 2, 3] and listB = [4, 5, 6], the dot product is ```1*4 + 2*5 + 3*6```, meaning your function should return: 32 2 | 3 | Hint: You will need to traverse both lists in parallel. 4 | 5 | This function takes in two lists of numbers and returns a number. 6 | ```py 7 | def dotProduct(listA, listB): 8 | 9 | ''' 10 | listA: a list of numbers 11 | listB: a list of numbers of the same length as listA 12 | ''' 13 | 14 | outputSum = 0 15 | 16 | # Your code here 17 | # iterate over elements and sum multiplication 18 | 19 | for i in range(len(listA)): 20 | outputSum += listA[i] * listB[i] 21 | 22 | return outputSum 23 | ``` 24 | -------------------------------------------------------------------------------- /Midterm-Exam/Problem 9.md: -------------------------------------------------------------------------------- 1 | Write a function to flatten a list. The list contains other lists, strings, or ints. For example, ```[[1,'a',['cat'],2],[[[3]],'dog'],4,5]``` is flattened into ```[1,'a','cat',2,3,'dog',4,5]``` (order matters). 2 | ```python 3 | def flatten(aList): 4 | ''' 5 | aList: a list 6 | Returns a copy of aList, which is a flattened version of aList 7 | ''' 8 | ``` 9 | 10 | 11 | _Hint: How to think about this problem_ 12 | >Recursion is extremely useful for this question. You will have to try to flatten every element of the original list. To check whether an element can be flattened, the element must be another object of type list. 13 | 14 | ```python 15 | def flatten(aList): 16 | output = [] 17 | 18 | for element in aList: 19 | if not isinstance(element, list): 20 | output.append(element) 21 | else: 22 | output.extend(flatten(element)) 23 | 24 | return output 25 | ``` 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Set-1/Problem 3.md: -------------------------------------------------------------------------------- 1 | Assume s is a string of lower case characters. 2 | 3 | Write a program that prints the longest substring of s in which the letters occur in alphabetical order. 4 | For example, if s = 'azcbobobegghakl', then your program should print 5 | Longest substring in alphabetical order is: beggh 6 | 7 | In the case of ties, print the first substring. For example, if s = 'abcbcd', then your program should print 8 | Longest substring in alphabetical order is: abc 9 | 10 | Note: This problem may be challenging. We encourage you to work smart. If you've spent more than a few hours on this problem, we suggest that you move on to a different part of the course. If you have time, come back to this problem after you've had a break and cleared your head. 11 | 12 | ```python 13 | s = 'hnzprazicauzvdovwldlvv' 14 | 15 | outputString = s[0] 16 | tempString = outputString 17 | 18 | for i in range(1, len(s)): 19 | if s[i] >= tempString[-1]: 20 | tempString += s[i] 21 | if len(tempString) > len(outputString): 22 | outputString = tempString 23 | else: 24 | tempString = s[i] 25 | 26 | print('Longest substring in alphabetical order is: ' + outputString) 27 | ``` 28 | -------------------------------------------------------------------------------- /Set-3/Problem 1.md: -------------------------------------------------------------------------------- 1 | Please read the Hangman Introduction before starting this problem. We'll start by writing 3 simple functions that will help us easily code the Hangman problem. First, implement the function isWordGuessed that takes in two parameters - a string, secretWord, and a list of letters, lettersGuessed. This function returns a boolean - True if secretWord has been guessed (ie, all the letters of secretWord are in lettersGuessed) and False otherwise. 2 | 3 | Example Usage: 4 | ``` 5 | >>> secretWord = 'apple' 6 | >>> lettersGuessed = ['e', 'i', 'k', 'p', 'r', 's'] 7 | >>> print(isWordGuessed(secretWord, lettersGuessed)) 8 | False 9 | ``` 10 | For this function, you may assume that all the letters in secretWord and lettersGuessed are lowercase. 11 | ```python 12 | def isWordGuessed(secretWord, lettersGuessed): 13 | ''' 14 | secretWord: string, the word the user is guessing 15 | lettersGuessed: list, what letters have been guessed so far 16 | returns: boolean, True if all the letters of secretWord are in lettersGuessed; 17 | False otherwise 18 | ''' 19 | # FILL IN YOUR CODE HERE... 20 | for letter in secretWord: 21 | if letter not in lettersGuessed: 22 | return False 23 | return True 24 | ``` 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rozwiązania Problemów MIT 6.00.1x - Wprowadzenie do Informatyki 2 | edX "Introduction to Computer Science and Programming Using Python" course 3 | 4 | ## Status: Projekt Edukacyjny - Zakończony 5 | 6 | To repozytorium zawiera moje rozwiązania problemów z kursu MIT "Introduction to Computer Science and Programming Using Python" realizowanego przez platformę edX w 2016-2017 roku. 7 | 8 | ### Wartość edukacyjna 9 | Projekt dokumentuje moją ścieżkę nauki podstaw programowania w Pythonie i myślenia algorytmicznego. Był fundamentem dla mojego dalszego rozwoju w kierunku analityki danych i Business Intelligence. 10 | 11 | ### Transformacja zawodowa 12 | Od tamtego czasu rozwinąłem się w Senior BI Analyst z ponad 8-letnim doświadczeniem w Tableau, SQL i obecnie Power BI. To repozytorium pokazuje początek mojej drogi programistycznej. 13 | 14 | ### Moja aktualna praca 15 | Obecnie realizuję zaawansowane projekty analityki biznesowej, koncentrując się na migracjach platformowych i kompleksowych rozwiązaniach BI: 16 | 17 | ➡️ **[Aktualne Portfolio - Senior BI Analyst Journey](https://github.com/pzoladkiewicz/senior-bi-craftsman-journey)** ⬅️ 18 | 19 | --- 20 | **Kontakt**: pzoladkiewicz@gmail.com | [LinkedIn](https://www.linkedin.com/in/pzoladkiewicz/) 21 | -------------------------------------------------------------------------------- /Midterm-Exam/Problem 8.md: -------------------------------------------------------------------------------- 1 | Implement a function that meets the specifications below. 2 | ```python 3 | def applyF_filterG(L, f, g): 4 | """ 5 | Assumes L is a list of integers 6 | Assume functions f and g are defined for you. 7 | f takes in an integer, applies a function, returns another integer 8 | g takes in an integer, applies a Boolean function, 9 | returns either True or False 10 | Mutates L such that, for each element i originally in L, L contains 11 | i if g(f(i)) returns True, and no other elements 12 | Returns the largest element in the mutated L or -1 if the list is empty 13 | """ 14 | # Your code here 15 | ``` 16 | For example, the following functions, f, g, and test code: 17 | ```python 18 | def f(i): 19 | return i + 2 20 | def g(i): 21 | return i > 5 22 | 23 | L = [0, -10, 5, 6, -4] 24 | print(applyF_filterG(L, f, g)) 25 | print(L) 26 | ``` 27 | Should print: 28 | ```python 29 | 6 30 | [5, 6] 31 | ``` 32 | For this question, you will **not be able to see the test cases we run**. This problem will test your ability to come up with your own test cases. 33 | 34 | #### Paste your function here 35 | ```python 36 | def applyF_filterG(L, f, g): 37 | tempL = L[:] 38 | for i in tempL: 39 | if not g(f(i)): 40 | L.remove(i) 41 | if len(L) > 0: 42 | return max(L) 43 | else: 44 | return -1 45 | ``` 46 | -------------------------------------------------------------------------------- /Week-2/Exercise: guess my number.md: -------------------------------------------------------------------------------- 1 | In this problem, you'll create a program that guesses a secret number! 2 | 3 | The program works as follows: you (the user) thinks of an integer between 0 (inclusive) and 100 (not inclusive). 4 | The computer makes guesses, and you give it input - is its guess too high or too low? 5 | Using bisection search, the computer will guess the user's secret number! 6 | 7 | Note: your program should use input to obtain the user's input! 8 | Be sure to handle the case when the user's input is not one of h, l, or c. 9 | 10 | When the user enters something invalid, you should print out a message to the user explaining you did not understand their input. 11 | Then, you should re-ask the question, and prompt again for input. 12 | ```python 13 | low = 0 14 | high = 100 15 | answer = '' 16 | 17 | print('Please think of a number between 0 and 100!') 18 | 19 | while answer != 'c': 20 | guess = (low + high)//2 21 | print('Is your secret number', guess, end='?') 22 | print('') 23 | answer = input("Enter 'h' to indicate the guess is too high. Enter 'l' to indicate the guess is too low. Enter 'c' to indicate I guessed correctly.") 24 | if answer not in ('lhc'): 25 | print('Sorry, I did not understand your input.') 26 | elif answer == 'l': 27 | low = guess 28 | elif answer == 'h': 29 | high = guess 30 | 31 | print('Game over. Your secret number was:', guess) 32 | ``` 33 | -------------------------------------------------------------------------------- /Set-3/Problem 3.md: -------------------------------------------------------------------------------- 1 | Printing Out all Available Letters. 2 | 3 | Next, implement the function getAvailableLetters that takes in one parameter - a list of letters, lettersGuessed. This function returns a string that is comprised of lowercase English letters - all lowercase English letters that are not in lettersGuessed. 4 | 5 | Example Usage: 6 | ``` 7 | >>> lettersGuessed = ['e', 'i', 'k', 'p', 'r', 's'] 8 | >>> print(getAvailableLetters(lettersGuessed)) 9 | abcdfghjlmnoqtuvwxyz 10 | ``` 11 | Note that this function should return the letters in alphabetical order, as in the example above. 12 | 13 | For this function, you may assume that all the letters in lettersGuessed are lowercase. 14 | 15 | Hint: You might consider using string.ascii_lowercase, which is a string comprised of all lowercase letters: 16 | ``` 17 | >>> import string 18 | >>> print(string.ascii_lowercase) 19 | abcdefghijklmnopqrstuvwxyz 20 | ``` 21 | ```python 22 | def getAvailableLetters(lettersGuessed): 23 | ''' 24 | lettersGuessed: list, what letters have been guessed so far 25 | returns: string, comprised of letters that represents what letters have not 26 | yet been guessed. 27 | ''' 28 | # FILL IN YOUR CODE HERE... 29 | 30 | #define outputStr as a all lower case alphabetical order string 31 | outputStr = string.ascii_lowercase 32 | 33 | #if letter found in output string replace it with '' 34 | for letter in lettersGuessed: 35 | outputStr = outputStr.replace(letter, '') 36 | 37 | return(outputStr) 38 | ``` 39 | -------------------------------------------------------------------------------- /Set-2/Problem 2.md: -------------------------------------------------------------------------------- 1 | Now write a program that calculates the minimum fixed monthly payment needed in order pay off a credit card balance within 12 months. By a fixed monthly payment, we mean a single number which does not change each month, but instead is a constant amount that will be paid each month. 2 | 3 | In this problem, we will not be dealing with a minimum monthly payment rate. 4 | 5 | The following variables contain values as described below: 6 | balance - the outstanding balance on the credit card 7 | annualInterestRate - annual interest rate as a decimal 8 | 9 | The program should print out one line: the lowest monthly payment that will pay off all debt in under 1 year, for example: 10 | Lowest Payment: 180 11 | 12 | **** 13 | 14 | Assume that the interest is compounded monthly according to the balance at the end of the month (after the payment for that month is made). The monthly payment must be a multiple of $10 and is the same for all months. Notice that it is possible for the balance to become negative using this payment scheme, which is okay. A summary of the required math is found below: 15 | 16 | Monthly interest rate = (Annual interest rate) / 12.0 17 | Monthly unpaid balance = (Previous balance) - (Minimum fixed monthly payment) 18 | Updated balance each month = (Monthly unpaid balance) + (Monthly interest rate x Monthly unpaid balance) 19 | 20 | ```python 21 | lowestPayment = 10 22 | 23 | def lowPay(balance, lowestPayment): 24 | for month in range(12): 25 | balance -= lowestPayment 26 | balance *= (1+(annualInterestRate/12)) 27 | return balance 28 | 29 | while (lowPay(balance, lowestPayment) > 0): 30 | lowPay(balance, lowestPayment) 31 | lowestPayment += 10 32 | 33 | print('Lowest Paymanet:', lowestPayment) 34 | ``` 35 | -------------------------------------------------------------------------------- /Set-2/Problem 1.md: -------------------------------------------------------------------------------- 1 | Paying Debt off in a Year 2 | 3 | Write a program to calculate the credit card balance after one year if a person only pays the minimum monthly payment required by the credit card company each month. 4 | 5 | The following variables contain values as described below: 6 | balance - the outstanding balance on the credit card 7 | annualInterestRate - annual interest rate as a decimal 8 | monthlyPaymentRate - minimum monthly payment rate as a decimal 9 | 10 | For each month, calculate statements on the monthly payment and remaining balance. At the end of 12 months, print out the remaining balance. Be sure to print out no more than two decimal digits of accuracy - so print 11 | 12 | Remaining balance: 813.41 13 | 14 | instead of 15 | 16 | Remaining balance: 813.4141998135 17 | 18 | **** 19 | 20 | So your program only prints out one thing: the remaining balance at the end of the year in the format: 21 | 22 | Remaining balance: 4784.0 23 | 24 | **** 25 | A summary of the required math is found below: 26 | 27 | Monthly interest rate= (Annual interest rate) / 12.0 28 | Minimum monthly payment = (Minimum monthly payment rate) x (Previous balance) 29 | Monthly unpaid balance = (Previous balance) - (Minimum monthly payment) 30 | Updated balance each month = (Monthly unpaid balance) + (Monthly interest rate x Monthly unpaid balance) 31 | 32 | ```python 33 | 34 | # Test Case 1: 35 | balance = 42 36 | annualInterestRate = 0.2 37 | monthlyPaymentRate = 0.04 38 | 39 | # Result Your Code Should Generate Below: 40 | Remaining balance: 31.38 41 | 42 | 43 | for month in range (12): 44 | balance = balance + balance * annualInterestRate / 12 45 | minimumMonthlyPayment = balance * monthlyPaymentRate 46 | monthlyUnpaidBalance = balance - minimumMonthlyPayment 47 | balance -= minimumMonthlyPayment 48 | print('Remaining balance:', round(balance,2)) 49 | ``` 50 | -------------------------------------------------------------------------------- /Set-4/Problem 3.md: -------------------------------------------------------------------------------- 1 | Valid Words 2 | ____________ 3 | 4 | At this point, we have written code to generate a random hand and display that hand to the user. We can also ask the user for a word (Python's input) and score the word (using your getWordScore). However, at this point we have not written any code to verify that a word given by a player obeys the rules of the game. A valid word is in the word list; and it is composed entirely of letters from the current hand. Implement the isValidWord function. 5 | 6 | Testing: Make sure the test_isValidWord tests pass. In addition, you will want to test your implementation by calling it multiple times on the same hand - what should the correct behavior be? Additionally, the empty string ('') is not a valid word - if you code this function correctly, you shouldn't need an additional check for this condition. 7 | 8 | ```python 9 | def isValidWord(word, hand, wordList): 10 | """ 11 | Returns True if word is in the wordList and is entirely 12 | composed of letters in the hand. Otherwise, returns False. 13 | 14 | Does not mutate hand or wordList. 15 | 16 | word: string 17 | hand: dictionary (string -> int) 18 | wordList: list of lowercase strings 19 | """ 20 | 21 | # change hand dict keys to list 22 | handLettersList = ''.join(hand.keys()) 23 | 24 | handCopy = hand.copy() 25 | 26 | # if word is not in list return false else 27 | # for each letter in word check if its in hand 28 | # and occurs at least one time 29 | # if not return false 30 | # else decrese in copy of hand letter occurence 31 | 32 | if word in wordList: 33 | for el in word: 34 | if el in handLettersList and handCopy[el] > 0: 35 | handCopy[el] -= 1 36 | else: 37 | return False 38 | return True 39 | else: 40 | return False 41 | ``` 42 | -------------------------------------------------------------------------------- /Set-4/Introduction.md: -------------------------------------------------------------------------------- 1 | In this problem set, you'll implement two versions of a wordgame! 2 | 3 | Don't be intimidated by the length of this problem set. There is a lot of reading, but it can be done with a reasonable amount of thinking and coding. It'll be helpful if you start this problem set a few days before it is due! 4 | 5 | Let's begin by describing the 6.00 wordgame: This game is a lot like Scrabble or Words With Friends, if you've played those. Letters are dealt to players, who then construct one or more words out of their letters. Each valid word receives a score, based on the length of the word and the letters in that word. 6 | 7 | The rules of the game are as follows: 8 | 9 | Dealing 10 | A player is dealt a hand of n letters chosen at random (assume n=7 for now). 11 | 12 | The player arranges the hand into as many words as they want out of the letters, using each letter at most once. 13 | 14 | Some letters may remain unused (these won't be scored). 15 | 16 | Scoring 17 | The score for the hand is the sum of the scores for each word formed. 18 | 19 | The score for a word is the sum of the points for letters in the word, multiplied by the length of the word, plus 50 points if all n letters are used on the first word created. 20 | 21 | Letters are scored as in Scrabble; A is worth 1, B is worth 3, C is worth 3, D is worth 2, E is worth 1, and so on. We have defined the dictionary SCRABBLE_LETTER_VALUES that maps each lowercase letter to its Scrabble letter value. 22 | 23 | For example, 'weed' would be worth 32 points ((4+1+1+2) for the four letters, then multiply by len('weed') to get (4+1+1+2)*4 = 32). Be sure to check that the hand actually has 1 'w', 2 'e's, and 1 'd' before scoring the word! 24 | 25 | As another example, if n=7 and you make the word 'waybill' on the first try, it would be worth 155 points (the base score for 'waybill' is (4+1+4+3+1+1+1)*7=105, plus an additional 50 point bonus for using all n letters). 26 | -------------------------------------------------------------------------------- /Set-3/Problem 2.md: -------------------------------------------------------------------------------- 1 | Next, implement the function getGuessedWord that takes in two parameters - a string, secretWord, and a list of letters, lettersGuessed. This function returns a string that is comprised of letters and underscores, based on what letters in lettersGuessed are in secretWord. This shouldn't be too different from isWordGuessed! 2 | 3 | Example Usage: 4 | ``` 5 | >>> secretWord = 'apple' 6 | >>> lettersGuessed = ['e', 'i', 'k', 'p', 'r', 's'] 7 | >>> print(getGuessedWord(secretWord, lettersGuessed)) 8 | '_ pp_ e' 9 | ``` 10 | When inserting underscores into your string, it's a good idea to add at least a space after each one, so it's clear to the user how many unguessed letters are left in the string (compare the readability of ____ with _ _ _ _ ). This is called usability - it's very important, when programming, to consider the usability of your program. If users find your program difficult to understand or operate, they won't use it! 11 | 12 | For this problem, you are free to use spacing in any way you wish - our grader will only check that the letters and underscores are in the proper order; it will not look at spacing. We do encourage you to think about usability when designing. 13 | 14 | For this function, you may assume that all the letters in secretWord and lettersGuessed are lowercase. 15 | 16 | ```python 17 | def getGuessedWord(secretWord, lettersGuessed): 18 | ''' 19 | secretWord: string, the word the user is guessing 20 | lettersGuessed: list, what letters have been guessed so far 21 | returns: string, comprised of letters and underscores that represents 22 | what letters in secretWord have been guessed so far. 23 | ''' 24 | # FILL IN YOUR CODE HERE... 25 | 26 | #define empty output string then.. 27 | outputStr = '' 28 | 29 | for letter in secretWord: 30 | 31 | #if letter is in guessed add it to output 32 | #else add underscore space 33 | 34 | if letter in lettersGuessed: 35 | outputStr += letter 36 | else: 37 | outputStr += '_ ' 38 | 39 | return outputStr 40 | ``` 41 | -------------------------------------------------------------------------------- /Set-4/Problem 6.md: -------------------------------------------------------------------------------- 1 | ###Playing a Game 2 | A game consists of playing multiple hands. We need to implement one final function to complete our word-game program. Write the code that implements the `playGame` function. You should remove the code that is currently uncommented in the `playGame` body. Read through the specification and make sure you understand what this function accomplishes. For the game, you should use the `HAND_SIZE` constant to determine the number of cards in a hand. 3 | 4 | **Testing**: Try out this implementation as if you were playing the game. Try out different values for `HAND_SIZE` with your program, and be sure that you can play the wordgame with different hand sizes by modifying only the variable `HAND_SIZE`. 5 | ```python 6 | def playGame(wordList): 7 | """ 8 | Allow the user to play an arbitrary number of hands. 9 | 10 | 1) Asks the user to input 'n' or 'r' or 'e'. 11 | * If the user inputs 'n', let the user play a new (random) hand. 12 | * If the user inputs 'r', let the user play the last hand again. 13 | * If the user inputs 'e', exit the game. 14 | * If the user inputs anything else, tell them their input was invalid. 15 | 16 | 2) When done playing the hand, repeat from step 1 17 | """ 18 | userInput = '' 19 | 20 | # flag to check if thats a first deal 21 | # 0 - first deal, 1 - played before 22 | r = 0 23 | 24 | while userInput != 'e': 25 | userInput = input('Enter n to deal a new hand, r to replay last hand, or e to end game: ') 26 | 27 | if userInput == 'n': 28 | r = 1 # set flag to 1 29 | hand = dealHand(HAND_SIZE) 30 | playHand(hand, wordList, HAND_SIZE) 31 | elif userInput == 'r': 32 | if r: # if not first deal use old hand and play again 33 | playHand(hand, wordList, HAND_SIZE) 34 | else: # otherwise alert 35 | print('You have not played a hand yet. Please play a new hand first!') 36 | elif userInput not in 'nre': 37 | print('Invalid command') 38 | ``` 39 | -------------------------------------------------------------------------------- /Set-4/pre Problem 7.md: -------------------------------------------------------------------------------- 1 | **Part B is dependent on your functions from ps4a.py, so be sure to complete ps4a.py before working on ps4b.py** 2 | 3 | Now that you have completed your word game code, you decide that you would like to enable your computer (SkyNet) to play the game (your hidden agenda is to prove once and for all that computers are inferior to human intellect!) In this part, you will be able to compare how you as a user succeed in the game compared to the computer's performance. 4 | 5 | You should look at the following two functions: compChooseWord and compPlayHand, before moving on to Problem 7 on the next page. 6 | 7 | ### compChooseWord 8 | 9 | If you follow the pseudocode for compChooseWord, you'll see that the code creates a computer player that is legal, but not always the best. Try to walk through and understand our implementation. 10 | 11 | **A Note On Runtime**: You may notice that things run a bit slowly when the computer plays. This is to be expected - the wordList has 83667 words, after all! 12 | 13 | **Test Cases to Understand the Code**: 14 | ```python 15 | >>> compChooseWord({'a': 1, 'p': 2, 's': 1, 'e': 1, 'l': 1}, wordList, 6) 16 | appels 17 | >>> compChooseWord({'a': 2, 'c': 1, 'b': 1, 't': 1}, wordList, 5) 18 | acta 19 | >>> compChooseWord({'a': 2, 'e': 2, 'i': 2, 'm': 2, 'n': 2, 't': 2}, wordList, 12) 20 | immanent 21 | >>> compChooseWord({'x': 2, 'z': 2, 'q': 2, 'n': 2, 't': 2}, wordList, 12) 22 | None 23 | ``` 24 | ### compPlayHand 25 | 26 | Now that we have the ability to let the computer choose a word, we need to set up a function to allow the computer to play a hand - in a manner very similar to Part A's playHand function. This function allows the computer to play a given hand and is very similar to the earlier version in which a user selected the word, although deciding when it is done playing a particular hand is different. 27 | 28 | **Test Cases to Understand the Code:** 29 | 30 | ```python 31 | compPlayHand({'a': 1, 'p': 2, 's': 1, 'e': 1, 'l': 1}, wordList, 6) 32 | 33 | Current Hand: a p p s e l 34 | "appels" earned 110 points. Total: 110 points 35 | Total score: 110 points. 36 | 37 | compPlayHand({'a': 2, 'c': 1, 'b': 1, 't': 1}, wordList, 5) 38 | 39 | Current Hand: a a c b t 40 | "acta" earned 24 points. Total: 24 points 41 | 42 | Current Hand: b 43 | Total score: 24 points. 44 | 45 | compPlayHand({'a': 2, 'e': 2, 'i': 2, 'm': 2, 'n': 2, 't': 2}, wordList, 12) 46 | 47 | Current Hand: a a e e i i m m n n t t 48 | "immanent" earned 96 points. Total: 96 points 49 | 50 | Current Hand: a e t i 51 | "ait" earned 9 points. Total: 105 points 52 | 53 | Current Hand: e 54 | Total score: 105 points. 55 | ``` 56 | -------------------------------------------------------------------------------- /Midterm-Exam/Problem 7.md: -------------------------------------------------------------------------------- 1 | Assume you are given two dictionaries ```d1``` and ```d2```, each with integer keys and integer values. You are also given a function ```f```, that takes in two integers, performs an unknown operation on them, and returns a value. 2 | 3 | Write a function called ```dict_interdiff``` that takes in two dictionaries (```d1``` and ```d2```). The function will return a tuple of two dictionaries: a dictionary of the intersect of ```d1``` and ```d2``` and a dictionary of the difference of ```d1``` and ```d2```, calculated as follows: 4 | 5 | * __intersect:__ The keys to the intersect dictionary are keys that are common in both ```d1``` and ```d2```. To get the values of the intersect dictionary, look at the common keys in ```d1``` and ```d2``` and apply the function f to these keys' values -- the value of the common key in ```d1``` is the first parameter to the function and the value of the common key in ```d2``` is the second parameter to the function. Do not implement f inside your dict_interdiff code -- assume it is defined outside. 6 | * __difference:__ a key-value pair in the difference dictionary is (a) every key-value pair in ```d1``` whose key appears only in ```d1``` and not in ```d2``` or (b) every key-value pair in ```d2``` whose key appears only in ```d2``` and not in ```d1```. 7 | 8 | Here are two examples: 9 | 10 | * If ```f(a, b)``` returns ```a + b``` 11 | ```d1 = {1:30, 2:20, 3:30, 5:80}``` 12 | ```d2 = {1:40, 2:50, 3:60, 4:70, 6:90}``` 13 | then ```dict_interdiff(d1, d2)``` returns ```({1: 70, 2: 70, 3: 90}, {4: 70, 5: 80, 6: 90})``` 14 | * If ```f(a, b)``` returns ```a > b``` 15 | ```d1 = {1:30, 2:20, 3:30}``` 16 | ```d2 = {1:40, 2:50, 3:60}``` 17 | then ```dict_interdiff(d1, d2)``` returns ```({1: False, 2: False, 3: False}, {})``` 18 | 19 | ```python 20 | def dict_interdiff(d1, d2): 21 | ''' 22 | d1, d2: dicts whose keys and values are integers 23 | Returns a tuple of dictionaries according to the instructions above 24 | ''' 25 | # Your code here 26 | 27 | ```python 28 | 29 | def dict_interdiff(d1, d2): 30 | 31 | #declare two empty dictionaries 32 | a = {} 33 | b = {} 34 | 35 | #get keys and assign to variables 36 | d1Keys = d1.keys() 37 | d2Keys = d2.keys() 38 | 39 | #check for intersect and difference and apply function to first one 40 | for key in d1Keys: 41 | if key in d2Keys: 42 | a[key] = f(d1[key], d2[key]) 43 | 44 | for key in d1Keys: 45 | if key not in d2Keys: 46 | b[key] = d1[key] 47 | 48 | for key in d2Keys: 49 | if key not in d1Keys: 50 | b[key] = d2[key] 51 | 52 | return (a, b) 53 | ``` 54 | -------------------------------------------------------------------------------- /Set-2/Introduction.md: -------------------------------------------------------------------------------- 1 | Each month, a credit card statement will come with the option for you to pay a minimum amount of your charge, usually 2% of the balance due. However, the credit card company earns money by charging interest on the balance that you don't pay. So even if you pay credit card payments on time, interest is still accruing on the outstanding balance. 2 | 3 | Say you've made a $5,000 purchase on a credit card with an 18% annual interest rate and a 2% minimum monthly payment rate. If you only pay the minimum monthly amount for a year, how much is the remaining balance? 4 | 5 | You can think about this in the following way. 6 | 7 | At the beginning of month 0 (when the credit card statement arrives), assume you owe an amount we will call (b for balance; subscript 0 to indicate this is the balance at month 0). 8 | 9 | Any payment you make during that month is deducted from the balance. Let's call the payment you make in month 0, . Thus, your unpaid balance for month 0, , is equal to . 10 | 11 | At the beginning of month 1, the credit card company will charge you interest on your unpaid balance. So if your annual interest rate is , then at the beginning of month 1, your new balance is your previous unpaid balance , plus the interest on this unpaid balance for the month. In algebra, this new balance would be 12 | 13 | In month 1, we will make another payment, . That payment has to cover some of the interest costs, so it does not completely go towards paying off the original charge. The balance at the beginning of month 2, , can be calculated by first calculating the unpaid balance after paying , then by adding the interest accrued: 14 | 15 | If you choose just to pay off the minimum monthly payment each month, you will see that the compound interest will dramatically reduce your ability to lower your debt. 16 | 17 | Let's look at an example. If you've got a $5,000 balance on a credit card with 18% annual interest rate, and the minimum monthly payment is 2% of the current balance, we would have the following repayment schedule if you only pay the minimum payment each month: 18 | 19 | Month Balance Minimum Payment Unpaid Balance Interest 20 | 0 5000.00 100 (= 5000 * 0.02) 4900 (= 5000 - 100) 73.50 (= 0.18/12.0 * 4900) 21 | 1 4973.50 (= 4900 + 73.50) 99.47 (= 4973.50 * 0.02) 4874.03 (= 4973.50 - 99.47) 73.11 (= 0.18/12.0 * 4874.03) 22 | 2 4947.14 (= 4874.03 + 73.11) 98.94 (= 4947.14 * 0.02) 4848.20 (= 4947.14 - 98.94) 72.72 (= 0.18/12.0 * 4848.20) 23 | You can see that a lot of your payment is going to cover interest, and if you work this through month 12, you will see that after a year, you will have paid $1165.63 and yet you will still owe $4691.11 on what was originally a $5000.00 debt. Pretty depressing! 24 | 25 | Annotate 26 | -------------------------------------------------------------------------------- /Set-4/Problem 5.md: -------------------------------------------------------------------------------- 1 | ### Playing a Hand 2 | In ps4a.py, note that in the function playHand, there is a bunch of pseudocode. This pseudocode is provided to help guide you in writing your function. Check out the Why Pseudocode? resource to learn more about the What and Why of Pseudocode before you start coding your solution. 3 | 4 | **Note**: Do **not** assume that there will always be 7 letters in a hand! The parameter n represents the size of the hand. 5 | 6 | ```python 7 | def playHand(hand, wordList, n): 8 | """ 9 | Allows the user to play the given hand, as follows: 10 | 11 | * The hand is displayed. 12 | * The user may input a word or a single period (the string ".") 13 | to indicate they're done playing 14 | * Invalid words are rejected, and a message is displayed asking 15 | the user to choose another word until they enter a valid word or "." 16 | * When a valid word is entered, it uses up letters from the hand. 17 | * After every valid word: the score for that word is displayed, 18 | the remaining letters in the hand are displayed, and the user 19 | is asked to input another word. 20 | * The sum of the word scores is displayed when the hand finishes. 21 | * The hand finishes when there are no more unused letters or the user 22 | inputs a "." 23 | 24 | hand: dictionary (string -> int) 25 | wordList: list of lowercase strings 26 | n: integer (HAND_SIZE; i.e., hand size required for additional points) 27 | 28 | """ 29 | 30 | # Keep track of the total score 31 | totalScore = 0 32 | # As long as there are still letters left in the hand: 33 | while calculateHandlen(hand) > 0: 34 | # Display the hand 35 | print('Current Hand:', end=' ') 36 | displayHand(hand) 37 | # Ask user for input 38 | word = input('Enter word, or a "." to indicate that you are finished: ') 39 | # If the input is a single period: 40 | if word == '.': 41 | # End the game (break out of the loop) 42 | break 43 | # Otherwise (the input is not a single period): 44 | else: 45 | # If the word is not valid: 46 | if not isValidWord(word, hand, wordList): 47 | # Reject invalid word (print a message followed by a blank line) 48 | print('Invalid word, please try again.') 49 | print() 50 | # Otherwise (the word is valid): 51 | else: 52 | wordScore = getWordScore(word, n) 53 | totalScore += wordScore 54 | # Tell the user how many points the word earned, and the updated total score, in one line followed by a blank line 55 | print('"' + word + '" earned ' + str(wordScore) + ' points. Total: ' + str(totalScore) + ' points', end=' ') 56 | print() 57 | # Update the hand 58 | hand = updateHand(hand, word) 59 | 60 | # Game is over (user entered a '.' or ran out of letters), so tell user the total score 61 | if word == '.': 62 | print('Goodbye! Total score: ' + str(totalScore) + ' points.') 63 | else: 64 | print('Run out of letters. Total score: ' + str(totalScore) + ' points.') 65 | ``` 66 | -------------------------------------------------------------------------------- /Set-4/Problem 1.md: -------------------------------------------------------------------------------- 1 | Word Scores 2 | 3 | The first step is to implement some code that allows us to calculate the score for a single word. The function getWordScore should accept as input a string of lowercase letters (a word) and return the integer score for that word, using the game's scoring rules. 4 | 5 | A Reminder of the Scoring Rules 6 | Scoring 7 | The score for the hand is the sum of the scores for each word formed. 8 | The score for a word is the sum of the points for letters in the word, multiplied by the length of the word, plus 50 points if all n letters are used on the first word created. 9 | Letters are scored as in Scrabble; A is worth 1, B is worth 3, C is worth 3, D is worth 2, E is worth 1, and so on. We have defined the dictionary SCRABBLE_LETTER_VALUES that maps each lowercase letter to its Scrabble letter value. 10 | For example, 'weed' would be worth 32 points ((4+1+1+2) for the four letters, then multiply by len('weed') to get (4+1+1+2)*4 = 32). Be sure to check that the hand actually has 1 'w', 2 'e's, and 1 'd' before scoring the word! 11 | As another example, if n=7 and you make the word 'waybill' on the first try, it would be worth 155 points (the base score for 'waybill' is (4+1+4+3+1+1+1)*7=105, plus an additional 50 point bonus for using all n letters). 12 | 13 | HINTS 14 | 15 | You may assume that the input word is always either a string of lowercase letters, or the empty string "". 16 | You will want to use the SCRABBLE_LETTER_VALUES dictionary defined at the top of ps4a.py. You should not change its value. 17 | Do not assume that there are always 7 letters in a hand! The parameter n is the number of letters required for a bonus score (the maximum number of letters in the hand). Our goal is to keep the code modular - if you want to try playing your word game with n=10 or n=4, you will be able to do it by simply changing the value of HAND_SIZE! 18 | Testing: If this function is implemented properly, and you run test_ps4a.py, you should see that the test_getWordScore() tests pass. Also test your implementation of getWordScore, using some reasonable English words. 19 | Fill in the code for getWordScore in ps4a.py and be sure you've passed the appropriate tests in test_ps4a.py before pasting your function definition here. 20 | ```python 21 | def getWordScore(word, n): 22 | """ 23 | Returns the score for a word. Assumes the word is a valid word. 24 | 25 | The score for a word is the sum of the points for letters in the 26 | word, multiplied by the length of the word, PLUS 50 points if all n 27 | letters are used on the first turn. 28 | 29 | Letters are scored as in Scrabble; A is worth 1, B is worth 3, C is 30 | worth 3, D is worth 2, E is worth 1, and so on (see SCRABBLE_LETTER_VALUES) 31 | 32 | word: string (lowercase letters) 33 | n: integer (HAND_SIZE; i.e., hand size required for additional points) 34 | returns: int >= 0 35 | """ 36 | # set initial value 37 | outputWordScore = 0 38 | 39 | # sum score for a word 40 | for letter in word: 41 | outputWordScore += SCRABBLE_LETTER_VALUES[letter] 42 | 43 | # multiply word score by its length 44 | # and and add 50 pts if all letters are used 45 | if len(word) == n: 46 | return outputWordScore*len(word)+50 47 | else: 48 | return outputWordScore*len(word) 49 | ``` 50 | -------------------------------------------------------------------------------- /Set-2/Problem 3.md: -------------------------------------------------------------------------------- 1 | You'll notice that in Problem 2, your monthly payment had to be a multiple of $10. Why did we make it that way? You can try running your code locally so that the payment can be any dollar and cent amount (in other words, the monthly payment is a multiple of $0.01). Does your code still work? It should, but you may notice that your code runs more slowly, especially in cases with very large balances and interest rates. (Note: when your code is running on our servers, there are limits on the amount of computing time each submission is allowed, so your observations from running this experiment on the grading system might be limited to an error message complaining about too much time taken.) 2 | 3 | Well then, how can we calculate a more accurate fixed monthly payment than we did in Problem 2 without running into the problem of slow code? We can make this program run faster using a technique introduced in lecture - bisection search! 4 | 5 | The following variables contain values as described below: 6 | balance - the outstanding balance on the credit card 7 | annualInterestRate - annual interest rate as a decimal 8 | 9 | To recap the problem: we are searching for the smallest monthly payment such that we can pay off the entire balance within a year. What is a reasonable lower bound for this payment value? $0 is the obvious anwer, but you can do better than that. If there was no interest, the debt can be paid off by monthly payments of one-twelfth of the original balance, so we must pay at least this much every month. One-twelfth of the original balance is a good lower bound. 10 | 11 | What is a good upper bound? Imagine that instead of paying monthly, we paid off the entire balance at the end of the year. What we ultimately pay must be greater than what we would've paid in monthly installments, because the interest was compounded on the balance we didn't pay off each month. So a good upper bound for the monthly payment would be one-twelfth of the balance, after having its interest compounded monthly for an entire year. 12 | 13 | In short: 14 | 15 | Monthly interest rate = (Annual interest rate) / 12.0 16 | Monthly payment lower bound = Balance / 12 17 | Monthly payment upper bound = (Balance x (1 + Monthly interest rate)12) / 12.0 18 | 19 | Write a program that uses these bounds and bisection search (for more info check out the Wikipedia page on bisection search) to find the smallest monthly payment to the cent (no more multiples of $10) such that we can pay off the debt within a year. Try it out with large inputs, and notice how fast it is (try the same large inputs in your solution to Problem 2 to compare!). Produce the same return value as you did in Problem 2. 20 | 21 | Note that if you do not use bisection search, your code will not run - your code only has 30 seconds to run on our servers. 22 | 23 | ```python 24 | epsilon = 0.01 25 | 26 | monthlyInterestRate = annualInterestRate / 12 27 | lowerBound = balance / 12 28 | upperBound = (balance * (1 + monthlyInterestRate) ** 12) / 12 29 | initialBalance = balance 30 | 31 | while abs(balance) > epsilon: 32 | balance = initialBalance 33 | lowestPayment = (upperBound - lowerBound) / 2 + lowerBound 34 | 35 | for month in range(12): 36 | balance -= lowestPayment 37 | balance *= 1 + monthlyInterestRate 38 | 39 | if balance > 0: 40 | lowerBound = lowestPayment 41 | else: 42 | upperBound = lowestPayment 43 | 44 | print("Lowest Payment:", round(lowestPayment, 2)) 45 | ``` 46 | -------------------------------------------------------------------------------- /Set-4/Problem 7.md: -------------------------------------------------------------------------------- 1 | ####You and your Computer 2 | Now that your computer can choose a word, you need to give the computer the option to play. Write the code that re-implements the ```playGame``` function. You will modify the function to behave as described below in the function's comments. As before, you should use the ```HAND_SIZE``` constant to determine the number of cards in a hand. Be sure to try out different values for ```HAND_SIZE``` with your program. 3 | ```python 4 | def playGame(wordList): 5 | """ 6 | Allow the user to play an arbitrary number of hands. 7 | 8 | 1) Asks the user to input 'n' or 'r' or 'e'. 9 | * If the user inputs 'e', immediately exit the game. 10 | * If the user inputs anything that's not 'n', 'r', or 'e', keep asking them again. 11 | 12 | 2) Asks the user to input a 'u' or a 'c'. 13 | * If the user inputs anything that's not 'c' or 'u', keep asking them again. 14 | 15 | 3) Switch functionality based on the above choices: 16 | * If the user inputted 'n', play a new (random) hand. 17 | * Else, if the user inputted 'r', play the last hand again. 18 | But if no hand was played, output "You have not played a hand yet. 19 | Please play a new hand first!" 20 | 21 | * If the user inputted 'u', let the user play the game 22 | with the selected hand, using playHand. 23 | * If the user inputted 'c', let the computer play the 24 | game with the selected hand, using compPlayHand. 25 | 26 | 4) After the computer or user has played the hand, repeat from step 1 27 | 28 | wordList: list (string) 29 | """ 30 | userInput = '' 31 | whoPlays = '' 32 | 33 | while userInput != 'e': 34 | userInput = input('Enter n to deal a new hand, r to replay last hand, or e to end game: ') 35 | 36 | if userInput == 'n': 37 | hand = dealHand(HAND_SIZE) 38 | 39 | while whoPlays != 'c' or whoPlays != 'u': 40 | whoPlays = input('Enter u to have yourself play, c to have the computer play: ') 41 | if whoPlays == 'u': 42 | playHand(hand, wordList, HAND_SIZE) 43 | break 44 | elif whoPlays == 'c': 45 | compPlayHand(hand, wordList, HAND_SIZE) 46 | break 47 | else: 48 | print('Invalid command') 49 | 50 | elif userInput == 'r': 51 | if 'hand' in locals(): # if not first play use old hand and play again 52 | # othewise print alert 53 | 54 | while whoPlays != 'c' or whoPlays != 'u': 55 | whoPlays = input('Enter u to have yourself play, c to have the computer play: ') 56 | if whoPlays == 'u': 57 | playHand(hand, wordList, HAND_SIZE) 58 | break 59 | elif whoPlays == 'c': 60 | compPlayHand(hand, wordList, HAND_SIZE) 61 | break 62 | else: 63 | print('Invalid command') 64 | 65 | else: # otherwise alert 66 | print('You have not played a hand yet. Please play a new hand first!') 67 | elif userInput not in 'nre': 68 | print('Invalid command') 69 | ``` 70 | -------------------------------------------------------------------------------- /Set-4/Getting started: -------------------------------------------------------------------------------- 1 | 1. Download and save Problem Set 4, a zip file of all the skeleton code you'll be filling in. Extract the files from the zip folder and make sure to save all the files - ps4a.py, ps4b.py, test_ps4a.py and words.txt - in the same folder. We recommend creating a folder in your Documents folder called 6001x, and inside the 6001x folder, creating a separate folder for each problem set. If you don't follow this instruction, you may end up with issues because the files for this problem set depend on one another. 2 | 3 | 2. Run the file ps4a.py, without making any modifications to it, in order to ensure that everything is set up correctly (this means, open the file in IDLE, and use the Run command to load the file into the interpreter). The code we have given you loads a list of valid words from a file and then calls the playGame function. You will implement the functions it needs in order to work. If everything is okay, after a small delay, you should see the following printed out: 4 | 5 | 6 | Loading word list from file... 7 | 83667 words loaded. 8 | playGame not yet implemented. 9 | 10 | If you see an IOError instead (e.g., "No such file or directory"), you should change the value of the WORDLIST_FILENAME constant (defined near the top of the file) to the complete pathname for the file words.txt (This will vary based on where you saved the files). 11 | 12 | For example, if you saved all the files including this words.txt in the directory "C:/Users/Ana/6001x/PS4" change the line: 13 | 14 | WORDLIST_FILENAME = "words.txt" to something like 15 | WORDLIST_FILENAME = "C:/Users/Ana/6001x/PS4/words.txt" 16 | Windows users, if you are copying the file path from Windows Explorer, you will have to change the backslashes to forward slashes. 17 | 18 | The file ps4a.py has a number of already implemented functions you can use while writing up your solution. You can ignore the code between the following comments, though you should read and understand how to use each helper function by reading the docstrings: 19 | 20 | # ----------------------------------- 21 | # Helper code 22 | # You don't need to understand this helper code, 23 | # but you will have to know how to use the functions 24 | # (so be sure to read the docstrings!) 25 | . 26 | . 27 | . 28 | # (end of helper code) 29 | # ----------------------------------- 30 | 31 | This problem set is structured so that you will write a number of modular functions and then glue them together to form the complete word playing game. Instead of waiting until the entire game is ready, you should test each function you write, individually, before moving on. This approach is known as unit testing, and it will help you debug your code. 32 | 33 | We have provided several test functions to get you started. After you've written each new function, unit test by running the file test_ps4a.py to check your work. 34 | 35 | If your code passes the unit tests you will see a SUCCESS message; otherwise you will see a FAILURE message. These tests aren't exhaustive. You will want to test your code in other ways too. 36 | 37 | Try running test_ps4a.py now (before you modify the ps4a.py skeleton). You should see that all the tests fail, because nothing has been implemented yet. 38 | 39 | These are the provided test functions: 40 | 41 | test_getWordScore() 42 | Test the getWordScore() implementation. 43 | 44 | test_updateHand() 45 | Test the updateHand() implementation. 46 | 47 | test_isValidWord() 48 | Test the isValidWord() implementation. 49 | -------------------------------------------------------------------------------- /Set-3/Problem 4.md: -------------------------------------------------------------------------------- 1 | Now you will implement the function hangman, which takes one parameter - the secretWord the user is to guess. This starts up an interactive game of Hangman between the user and the computer. Be sure you take advantage of the three helper functions, isWordGuessed, getGuessedWord, and getAvailableLetters, that you've defined in the previous part. 2 | Hints: 3 | 4 | You should start by noticing where we're using the provided functions (at the top of ps3_hangman.py) to load the words and pick a random one. Note that the functions loadWords and chooseWord should only be used on your local machine, not in the tutor. When you enter in your solution in the tutor, you only need to give your hangman function. 5 | 6 | Consider using lower() to convert user input to lower case. For example: 7 | 8 | guess = 'A' 9 | guessInLowerCase = guess.lower() 10 | 11 | Consider writing additional helper functions if you need them! 12 | 13 | There are four important pieces of information you may wish to store: 14 | secretWord: The word to guess. 15 | lettersGuessed: The letters that have been guessed so far. 16 | mistakesMade: The number of incorrect guesses made so far. 17 | availableLetters: The letters that may still be guessed. Every time a player guesses a letter, the guessed letter must be removed from availableLetters (and if they guess a letter that is not in availableLetters, you should print a message telling them they've already guessed that - so try again!). 18 | 19 | Note that if you choose to use the helper functions isWordGuessed, getGuessedWord, or getAvailableLetters, you do not need to paste your definitions in the box. We have supplied our implementations of these functions for your use in this part of the problem. If you use additional helper functions, you will need to paste those definitions here. 20 | 21 | Your function should include calls to input to get the user's guess. 22 | 23 | ________________ 24 | ```python 25 | def hangman(secretWord): 26 | ''' 27 | secretWord: string, the secret word to guess. 28 | 29 | Starts up an interactive game of Hangman. 30 | 31 | * At the start of the game, let the user know how many 32 | letters the secretWord contains. 33 | 34 | * Ask the user to supply one guess (i.e. letter) per round. 35 | 36 | * The user should receive feedback immediately after each guess 37 | about whether their guess appears in the computers word. 38 | 39 | * After each round, you should also display to the user the 40 | partially guessed word so far, as well as letters that the 41 | user has not yet guessed. 42 | 43 | Follows the other limitations detailed in the problem write-up. 44 | ''' 45 | # FILL IN YOUR CODE HERE... 46 | 47 | allowedGuesses = 8 48 | lettersGuessed = '' 49 | 50 | print('Welcome to the game, Hangman!') 51 | print('I am thinking of a word that is', len(secretWord), 'letters long.') 52 | print('-------------') 53 | 54 | while allowedGuesses > 0: 55 | print('You have', allowedGuesses, 'guesses left.') 56 | print('Available letters:', getAvailableLetters(lettersGuessed)) 57 | inputLetter = input('Please guess a letter: ') 58 | inputLetter = inputLetter.lower() 59 | 60 | if inputLetter in lettersGuessed: 61 | print("Oops! You've already guessed that letter:", getGuessedWord(secretWord, lettersGuessed)) 62 | print('-------------') 63 | elif inputLetter not in secretWord: 64 | print('Oops! That letter is not in my word:', getGuessedWord(secretWord, lettersGuessed)) 65 | print('-------------') 66 | lettersGuessed += inputLetter 67 | allowedGuesses -= 1 68 | else: 69 | lettersGuessed += inputLetter 70 | print('Good guess:', getGuessedWord(secretWord, lettersGuessed)) 71 | print('-------------') 72 | if isWordGuessed(secretWord, lettersGuessed): 73 | print('Congratulations, you won!') 74 | break 75 | 76 | if allowedGuesses == 0: 77 | print('Sorry, you ran out of guesses. The word was ' + secretWord + '.') 78 | ``` 79 | -------------------------------------------------------------------------------- /Set-3/Introduction: -------------------------------------------------------------------------------- 1 | Note: Do not be intimidated by this problem! It's actually easier than it looks. We will 'scaffold' this problem, guiding you through the creation of helper functions before you implement the actual game. 2 | 3 | For this problem, you will implement a variation of the classic wordgame Hangman. For those of you who are unfamiliar with the rules, you may read all about it here. In this problem, the second player will always be the computer, who will be picking a word at random. 4 | 5 | In this problem, you will implement a function, called hangman, that will start up and carry out an interactive Hangman game between a player and the computer. Before we get to this function, we'll first implement a few helper functions to get you going. 6 | 7 | For this problem, you will need the code files ps3_hangman.py and words.txt. Right-click on each and hit "Save Link As". Be sure to save them in same directory. Open and run the file ps3_hangman.py without making any modifications to it, in order to ensure that everything is set up correctly. By "open and run" we mean do the following: 8 | 9 | Go to your IDE. From the File menu, choose "Open". 10 | Find the file ps3_hangman.py and choose it. 11 | The template ps3_hangman.py file should now be open. Run the file. 12 | The code we have given you loads in a list of words from a file. If everything is working okay, after a small delay, you should see the following printed out: 13 | 14 | 15 | Loading word list from file... 16 | 55909 words loaded. 17 | If you see an IOError instead (e.g., "No such file or directory"), you should change the value of the WORDLIST_FILENAME constant (defined near the top of the file) to the complete pathname for the file words.txt (This will vary based on where you saved the file). Windows users, change the backslashes to forward slashes, like below. 18 | 19 | For example, if you saved ps3_hangman.py and words.txt in the directory "C:/Users/Ana/" change the line: 20 | 21 | WORDLIST_FILENAME = "words.txt" to something like 22 | 23 | WORDLIST_FILENAME = "C:/Users/Ana/words.txt" 24 | 25 | This folder will vary depending on where you saved the files. 26 | 27 | The file ps3_hangman.py has a number of already implemented functions you can use while writing up your solution. You can ignore the code between the following comments, though you should read and understand how to use each helper function by reading the docstrings: 28 | 29 | 30 | 31 | # ----------------------------------- 32 | # Helper code 33 | # You don't need to understand this helper code, 34 | # but you will have to know how to use the functions 35 | # (so be sure to read the docstrings!) 36 | . 37 | . 38 | . 39 | # (end of helper code) 40 | # ----------------------------------- 41 | 42 | You will want to do all of your coding for this problem within this file as well because you will be writing a program that depends on each function you write. 43 | 44 | Requirements 45 | 46 | Here are the requirements for your game: 47 | 48 | The computer must select a word at random from the list of available words that was provided in words.txt. The functions for loading the word list and selecting a random word have already been provided for you in ps3_hangman.py. 49 | 50 | The game must be interactive; the flow of the game should go as follows: 51 | 52 | At the start of the game, let the user know how many letters the computer's word contains. 53 | 54 | Ask the user to supply one guess (i.e. letter) per round. 55 | 56 | The user should receive feedback immediately after each guess about whether their guess appears in the computer's word. 57 | 58 | After each round, you should also display to the user the partially guessed word so far, as well as letters that the user has not yet guessed. 59 | 60 | Some additional rules of the game: 61 | A user is allowed 8 guesses. Make sure to remind the user of how many guesses s/he has left after each round. Assume that players will only ever submit one character at a time (A-Z). 62 | 63 | A user loses a guess only when s/he guesses incorrectly. 64 | 65 | If the user guesses the same letter twice, do not take away a guess - instead, print a message letting them know they've already guessed that letter and ask them to try again. 66 | 67 | The game should end when the user constructs the full word or runs out of guesses. If the player runs out of guesses (s/he "loses"), reveal the word to the user when the game ends. 68 | -------------------------------------------------------------------------------- /Set-5/Introduction.md: -------------------------------------------------------------------------------- 1 | Encryption is the process of obscuring information to make it unreadable without special knowledge. For centuries, people have devised schemes to encrypt messages - some better than others - but the advent of the computer and the Internet revolutionized the field. These days, it's hard not to encounter some sort of encryption, whether you are buying something online or logging into a shared computer system. Encryption lets you share information with other trusted people, without fear of disclosure. 2 | 3 | A cipher is an algorithm for performing encryption (and the reverse, decryption). The original information is called plaintext. After it is encrypted, it is called ciphertext. The ciphertext message contains all the information of the plaintext message, but it is not in a format readable by a human or computer without the proper mechanism to decrypt it; it should resemble random gibberish to those for whom it is not intended. 4 | 5 | A cipher usually depends on a piece of auxiliary information, called a key. The key is incorporated into the encryption process; the same plaintext encrypted with two different keys should have two different ciphertexts. Without the key, it should be difficult to decrypt the resulting ciphertext into readable plaintext. 6 | 7 | This assignment will deal with a well-known (though not very secure) encryption method called the Caesar cipher. Some vcabulary to get you started on this problem: 8 | * _Encryption_ - the process of obscuring or encoding messages to make them unreadable until they are decrypted 9 | * _Decryption_ - making encrypted messages readable again by decoding them 10 | * _Cipher_ - algorithm for performing encryption and decryption 11 | * _Plaintext_ - the original message 12 | * _Ciphertext_ - the encrypted message. Note: a ciphertext still contains all of the original message information, even if it looks like gibberish. 13 | 14 | ### The Caesar Cipher 15 | 16 | The idea of the Caesar Cipher is to pick an integer and shift every letter of your message by that integer. In other words, suppose the shift is k . Then, all instances of the i-th letter of the alphabet that appear in the plaintext should become the (i+k)-th letter of the alphabet in the ciphertext. You will need to be careful with the case in which i + k > 26 (the length of the alphabet). Here is what the whole alphabet looks like shifted three spots to the right: 17 | 18 | > Original: a b c d e f g h i j k l m n o p q r s t u v w x y z 19 | > 3-shift: d e f g h i j k l m n o p q r s t u v w x y z a b c 20 | 21 | Using the above key, we can quickly translate the message "happy" to "kdssb" (note how the 3-shifted alphabet wraps around at the end, so x -> a, y -> b, and z -> c). 22 | 23 | Note!! We are using the English alphabet for this problem - that is, the following letters in the following order: 24 | ``` 25 | >>> import string 26 | >>> print string.ascii_lowercase 27 | abcdefghijklmnopqrstuvwxyz 28 | ``` 29 | We will treat uppercase and lowercase letters individually, so that uppercase letters are always mapped to an uppercase letter, and lowercase letters are always mapped to a lowercase letter. If an uppercase letter maps to "A", then the same lowercase letter should map to "a". Punctuation and spaces should be retained and not changed. For example, a plaintext message with a comma should have a corresponding ciphertext with a comma in the same position. 30 | 31 | | plaintext | shift | ciphertext | 32 | | ----------------|-----------|------------------| 33 | | 'abcdef' | 2 | 'cdefgh' | 34 | | 'Hello, World!' | 5 | 'Mjqqt, Btwqi!' | 35 | | '' | any value | '' | 36 | 37 | We implemented for you two helper functions: ```load_words``` and ```is_word```. You may use these in your solution and you do not need to understand them completely, but should read the associated comments. You should read and understand the helper code in the rest of the file and use it to guide your solutions. 38 | 39 | ### Getting Started 40 | 41 | To get started, download the ps6.zip file. Extract it to your working directory. The files inside are: 42 | 43 | * ps6.py - a file containing three classes that you will have to implement. 44 | * words.txt - a file containing valid English words (should be in the same folder as your ps6..py file). 45 | * story.txt - a file containing an encrypted message that you will have to decode (should be in the same folder as your ps6..py file). 46 | 47 | This will be your first experience coding with classes! We will have a ```Message``` class with two subclasses ```PlaintextMessage``` and ```CiphertextMessage```. 48 | -------------------------------------------------------------------------------- /Set-4/Problem 2.md: -------------------------------------------------------------------------------- 1 | **Please read this problem entirely!!** The majority of this problem consists of learning how to read code, which is an incredibly useful and important skill. At the end, you will implement a short function. Be sure to take your time on this problem - it may seem easy, but reading someone else's code can be challenging and this is an important exercise. 2 | 3 | Representing hands 4 | 5 | A hand is the set of letters held by a player during the game. The player is initially dealt a set of random letters. For example, the player could start out with the following hand: a, q, l, m, u, i, l. In our program, a hand will be represented as a dictionary: the keys are (lowercase) letters and the values are the number of times the particular letter is repeated in that hand. For example, the above hand would be represented as: 6 | 7 | hand = {'a':1, 'q':1, 'l':2, 'm':1, 'u':1, 'i':1} 8 | 9 | Notice how the repeated letter 'l' is represented. Remember that with a dictionary, the usual way to access a value is hand['a'], where 'a' is the key we want to find. However, this only works if the key is in the dictionary; otherwise, we get a KeyError. To avoid this, we can use the call hand.get('a',0). This is the "safe" way to access a value if we are not sure the key is in the dictionary. d.get(key,default) returns the value for key if key is in the dictionary d, else default. If default is not given, it returns None, so that this method never raises a KeyError. For example: 10 | ``` 11 | >>> hand['e'] 12 | Traceback (most recent call last): 13 | File "", line 1, in 14 | KeyError: 'e' 15 | >>> hand.get('e', 0) 16 | 0 17 | ``` 18 | Converting words into dictionary representation 19 | 20 | One useful function we've defined for you is getFrequencyDict, defined near the top of ps4a.py. When given a string of letters as an input, it returns a dictionary where the keys are letters and the values are the number of times that letter is represented in the input string. For example: 21 | ``` 22 | >>> getFrequencyDict("hello") 23 | {'h': 1, 'e': 1, 'l': 2, 'o': 1} 24 | ```` 25 | As you can see, this is the same kind of dictionary we use to represent hands. 26 | Displaying a hand 27 | 28 | Given a hand represented as a dictionary, we want to display it in a user-friendly way. We have provided the implementation for this in the displayHand function. Take a few minutes right now to read through this function carefully and understand what it does and how it works. 29 | Generating a random hand 30 | 31 | The hand a player is dealt is a set of letters chosen at random. We provide you with the implementation of a function that generates this random hand, dealHand. The function takes as input a positive integer n, and returns a new object, a hand containing n lowercase letters. Again, take a few minutes (right now!) to read through this function carefully and understand what it does and how it works. 32 | Removing letters from a hand (you implement this) 33 | 34 | The player starts with a hand, a set of letters. As the player spells out words, letters from this set are used up. For example, the player could start out with the following hand: a, q, l, m, u, i, l. The player could choose to spell the word quail . This would leave the following letters in the player's hand: l, m. Your task is to implement the function updateHand, which takes in two inputs - a hand and a word (string). updateHand uses letters from the hand to spell the word, and then returns a copy of the hand, containing only the letters remaining. For example: 35 | ``` 36 | >>> hand = {'a':1, 'q':1, 'l':2, 'm':1, 'u':1, 'i':1} 37 | >>> displayHand(hand) # Implemented for you 38 | a q l l m u i 39 | >>> hand = updateHand(hand, 'quail') # You implement this function! 40 | >>> hand 41 | {'a':0, 'q':0, 'l':1, 'm':1, 'u':0, 'i':0} 42 | >>> displayHand(hand) 43 | l m 44 | ``` 45 | Implement the updateHand function. Make sure this function has no side effects: i.e., it must not mutate the hand passed in. Before pasting your function definition here, be sure you've passed the appropriate tests in test_ps4a.py. 46 | ```python 47 | def updateHand(hand, word): 48 | """ 49 | Assumes that 'hand' has all the letters in word. 50 | In other words, this assumes that however many times 51 | a letter appears in 'word', 'hand' has at least as 52 | many of that letter in it. 53 | 54 | Updates the hand: uses up the letters in the given word 55 | and returns the new hand, without those letters in it. 56 | 57 | Has no side effects: does not modify hand. 58 | 59 | word: string 60 | hand: dictionary (string -> int) 61 | returns: dictionary (string -> int) 62 | """ 63 | 64 | # copy given hand 65 | modifiedHand = hand.copy() 66 | 67 | # for each letter in word subtract it value in hand by one 68 | for letter in word: 69 | modifiedHand[letter] -= 1 70 | 71 | return modifiedHand 72 | ``` 73 | --------------------------------------------------------------------------------