--- tags: Programming --- # Programming Concepts Programming concepts in computer science Peanuts Maintained by Peanuts Currently dedicated to CS1302 ## Python ### Iteration > Used to create loops of code > while loop & for loop For loops ``` for i in range(10): # Runs exactly 10 times, from 0 to 9 ``` ``` for i in range(2, 9): # Runs exactly 9-2 times, from 2 to 8 ``` ``` for i in range(10, 0, -1) # Runs exactly 10-0 times, from 10 to 1 ``` ``` for i in range(10, 0, -2): # Runs exactly math.ceil((10-0)/2) times, from 10 to 1 with increments of -2 ``` While loops ``` x = 0 while x < 10: # Runs exactly 10-0 times, from 0 to 9 print(x) x += 1 ``` ``` x = 0 while x <= 10: # Runs (10-0)+1 times, from 0 to 10 print(x) x += 1 ``` ``` x = 10 while x > 0: # Runs (10-0) times, from 10 to 1 print(x) x -=1 ``` ### String > Easy #### String formatting - Forcing string conversion ``` "{!s} Lmao".format(123) ``` ### Lists > A collection of values > [1, 2, 3, "test", 4, 1e10] > Lists are mutable, meaning you can extend or shrink the list in runtime #### Indices ``` test = ["I", "Really", "Wanna", "Stay", "At", "Your", "House"] ``` The index of "I" is both 0 and -7 > Negative indices means you count from the end, starting from -1 > Positive idices means you count from the start, starting from 0 #### Operations of lists ``` test = ["I", "Really", "Wanna", "Stay", "At", "Your", "House"] ``` - Append values to lists ``` test.append("123") ``` ["I", "Really", "Wanna", "Stay", "At", "Your", "House", "123"] - Removing values from lists ``` test.remove("Really") ``` ["I", "Wanna", "Stay", "At", "Your", "House"] > Only removes the first occurence - Deleting values in specified index ``` test.pop(2) ``` ["I", "Really", "Stay", "At", "Your", "House"] ``` del test[2] ``` ["I", "Really", "Stay", "At", "Your", "House"] - Finding index of a value ``` test.index("House") ``` 6 - Clearing the list ``` test.clear() ``` [] - Joining every value into a string ``` "/".join(test) ``` Output: I/Really/Wanna/Stay/At/Your/House ``` "_".join(test) ``` Output: I_Really_Wanna_Stay_At_Your_House #### List slicing ``` test = ["I", "Really", "Wanna", "Stay", "At", "Your", "House"] ``` > test[Start : End : Index increment/reduction] - Start from index ``` test = test[2:] # Ignore all values before index 2 ``` ['Wanna', 'Stay', 'At', 'Your', 'House'] - Until index ``` test = test[:2] # Ignore all values in and after index 2 ``` ['I', 'Really'] - Reverse list ``` test = test[::-1] ``` ['House', 'Your', 'At', 'Stay', 'Wanna', 'Really', 'I'] ### Tuples > Just like list, but immutable > (1, 2, 3, "test", 4, 1e10) > Being immutable means it cannot be changed after declaration > More memory efficient than lists ### Dictionaries (Hashtables) > A collection of keywords with their values > {"test": 1, 1: "test2"} is a dictionary Example ``` dictionary = {"test": 1, 1: "test2"} for key, value in dictionary.items(): print(key, value) ``` Output ``` test 1 1 test2 ``` #### Accessing values from keys ``` dictionary = {"test": 1, 1: "test2"} print(dictionary["test"]) ``` Output ``` 1 ``` ### Global > Used to reference variables globally(not defined in any function) to a function > Bascially, take and use the variable outside functions Example ``` x = 0 def globaltest(): x += 1 return x print(globaltest()) ``` > Doesn't work because x in x+=1 cannot be found inside the function ``` x = 0 def globaltest(): global x # <------- Add this x += 1 return x print(globaltest()) ``` > Works because x is taken from the outer scope into the function ### Nonlocal > Used to reference variables FROM the primary function (or outer scope) IN the secondary function in nested functions > Basically, take and use the variable inside nested functions Example ``` def nonlocaltest(): x = 0 def nonlocaltest2(): x += 1 print(x) nonlocaltest2() print(x) ``` > Doesn't work because x in the expression x += 1 cannot be found inside the function ``` def nonlocaltest(): x = 0 def nonlocaltest2(): global x # <--------- Add this x += 1 print(x) nonlocaltest2() print(x) ``` > Works because it takes x from the primary fucntion (or outer scope) and puts it into the secondary function ### Generator / Yield > Generator is basically a list > Using yield instead of return adds the value to a 'list' Example ``` def generatortest(): for i in range(10): if i % 2 != 0: # Getting all odd numbers yield i print(list(generatortest())) ``` > Returns [1, 3, 5, 7, 9] > Loop through generators just like a list ### Recursion > Calls itself repeatedly until it hits a base case Example ``` def factorial(n): a = 1 def inside(n): nonlocal a if n == 0: return a a *= n return inside(n-1) return inside(n) ``` > 9 * 8 * 7 * 6 * ... * 1 > Iteration can always be converted to recursion, and vice versa > Better than iteration when dealing with trees > Uses more memory than iteration because of overhead > Can be clearer and more readable when loops get complicated, but the other way around for simpler operations VS Iteration ``` def factorial(n): result = 1 while n > 0: result *= n n -= 1 else: return result ``` ### Decoration > Change the returned value of the function using a defined wrapper Example ``` def split_string(func): def wrapper(): result = [] result[:0] = func() return result return wrapper @split_string #Declare split_string on test() def test() return "Test" ``` > Returns ['T', 'e', 's', 't'] ### Variable arguments *args - Accepts several arguments - Returns a tuple, iterate through it like a list Example ``` def test(*args): for arg in args: print(arg, end=' ') ``` Input ``` test(2, 3, "test", 4 , "fuck") ``` Output ``` 2 3 test 4 fuck ``` **kwargs - Accepts several arguments with specified keyword - Iterate through it like a dictionary Example ``` def test(**kwargs): for key, value in kwargs.items(): print(key, value) ``` Input ``` test(test=1, idiot="david") ``` Output ``` test 1 idiot david ``` Combining both *args and **kwargs ``` def test(*args, **kwargs): # keyword arguments must be after args print(args) for key, value in kwargs.items(): print(value) ``` Input ``` test("Test", test="arse") ``` Output ``` ('Test',) arse ```