---
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
```