diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.js index 6823027..114e694 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.js @@ -20,7 +20,12 @@ const pythonSidebar = [ {text: 'Collections', link: '/python/advanced/collections'}, {text: 'Dates', link: '/python/advanced/dates'}, {text: 'Debugging', link: '/python/advanced/debugging'}, - + {text: 'Files', link: '/python/advanced/files'}, + {text: 'Math', link: '/python/advanced/math'}, + {text: 'Regex', link: '/python/advanced/regex'}, + {text: 'Testing', link: '/python/advanced/tests'}, + {text: 'Timing', link: '/python/advanced/timing'}, + {text: 'Zipping', link: '/python/advanced/zip'} ] } ] diff --git a/docs/python/advanced/files.md b/docs/python/advanced/files.md new file mode 100644 index 0000000..5353a7f --- /dev/null +++ b/docs/python/advanced/files.md @@ -0,0 +1,33 @@ +# Files + +## Creating/writing to a file +```python +# Using with will automatically close the file +with f as open('test.txt', 'w+'): + f.write("Testing 1,2,3...") +``` + +## Reading directories +```python +import os +print(os.getcwd()) # Returns working directory (where you run python command from) +print(os.listdir()) # Returns everything in current dir +print(os.listdir('../some_path')) + +# You can also 'walk' a directory to get a tuple of directory info for each entry +for folder,sub_folders,files in os.walk(os.getcwd() + "/src"): + print(f"Currently looking at {folder}") + print(f"Subfolders are {sub_folders}") + print(f"Files in this dir are {files}") +``` + +## Moving files +```python +import shutil +shutil.move('test.txt', '../dest'); +``` + +## Deleting files +```python +os.unlink('test.txt') +``` \ No newline at end of file diff --git a/docs/python/advanced/math.md b/docs/python/advanced/math.md new file mode 100644 index 0000000..d67ff43 --- /dev/null +++ b/docs/python/advanced/math.md @@ -0,0 +1,45 @@ +# Math + +Math functions in python do not edit the arguments, they return values. + +```python +import math + +value = 4.35 +print(math.floor(value)) # 4 +print(math.ceil(value)) # 5 + +# Round does as you'd expect, except in cases of .5 it goes to the even number +print(round(4.5)) # 4 +print(round(5.5)) # 6 + +print(math.pi) +print(math.e) +print(math.inf) +print(math.nan) + +radians = math.sin(10) # returns radians +degrees = math.degrees(radians) +radians = math.radians(degrees) +``` + +## Random numbers +```python +import random + +rand = random.randint(0,100) + +# Use seed to always get same random values +random.seed(42) +rand = random.randint(0,100) # Should always get the same value every run +print(rand) + +mylist = list(range(0,20)) +print(random.choice(mylist)) + +print(random.choices(population=mylist, k=10)) # Chooses 5 items with replacement, aka the same element can be picked multiple times +print(random.sample(population=mylist, k=10)) # Chooses items without replacement, meaning you can only pick one element once + +random.shuffle(mylist) # Shuffles list in place +print(mylist) +``` \ No newline at end of file diff --git a/docs/python/advanced/regex.md b/docs/python/advanced/regex.md new file mode 100644 index 0000000..366c812 --- /dev/null +++ b/docs/python/advanced/regex.md @@ -0,0 +1,71 @@ +# Regex + +## Basic finding + +```python +import re + +text = "The agent's phone number is 407-444-1234. Call soon!" + +pattern = "phone" + +match = re.search(pattern, text) # Returns first match, None if not found +print(match.span()) # (12,17) - location of word +print(match.start() + match.end()) # 29 - sum + +text = "one one two two three" + +matches = re.findall('one', text) +print(matches) # ['one', 'one'] - List of matches, just the text though + +# Iterate through matches +for match in re.finditer('one', text): + # Returns match objects + print(match.span()) + print(match.group()) # Returns actual text +``` + +## Character identifiers and Quantifiers +| Identifier | Meaning | +| --------- | ------------- | +| \d | Digit (123) | +| \d | Digit (123) | +| \D | Not digit (AbC) | +| \w | Alphanumeric (number, letter, some special characters) | +| \W | Not alphanumeric (symbols, +=-*) | +| \s | Whitespace | +| \S | Not whitespace | +| . | Wildcard (any character) | + +| Quantifier | Meaning | +| --------- | ------------- | +| + | Occurs one or more | +| \{n} | Occurs exactly n times | +| \{s,e} | Occurs s to e times | +| \{n,} | Occurs n or more | +| * | Occurs zero or more | +| ? | Occurs once or none (basically optional letter/number) | + +```python +text = "The agent's phone number is 407-444-1234. Call soon!" +phone = re.search(r'\d{3}-\d{3}-\d{4}', text) +print(phone.group()) # 407-444-1234 + +# Grouping regex +phone_pattern = re.compile(r'(\d{3})-(\d{3})-(\d{4})') +phone = re.search(phone_pattern, text) +print(phone.group(1)) # 407 - INDEX STARTS AT 1 + +# OR, pipe operator +re.search(r'cat|dog', 'The cat is here') + +# Wildcard, . +print(re.findall(r'.at', 'The cat in the hat sat there.')) # ['cat', 'hat', 'sat'] + +# Starts with, ^ +print(re.findall(r'^T.*', 'The cat in the hat sat there.')) # ['The cat in the hat sat there.'] + +#ends with, $ +print(re.findall(r'\d$', 'The number is 2')) # ['2'] + +``` \ No newline at end of file diff --git a/docs/python/advanced/tests.md b/docs/python/advanced/tests.md new file mode 100644 index 0000000..af10cb7 --- /dev/null +++ b/docs/python/advanced/tests.md @@ -0,0 +1,31 @@ +# Testing + +## Basic file format +```python +import unittest + +class MyTest(unittest.TestCase): + + def test_one(self): + self.assertEqual(1,1) + +if __name__ == '__main__': + unittest.main() +``` + +## Assertions + +| Assertion | Logic | +| --------- | ------------- | +| assertEqual(a, b) | a == b | +| assertNotEqual(a, b) | a != b | +| assertTrue(x) | bool(x) is True | +| assertFalse(x) | bool(x) is False | +| assertIs(a, b) | a is b | +| assertIsNot(a, b) | a is not b | +| assertIsNone(x) | x is None | +| assertIsNotNone(x) | x is not None | +| assertIn(a, b) | a in b | +| assertNotIn(a, b) | a not in b | +| assertIsInstance(a, b) | isinstance(a, b) | +| assertNotIsInstance(a, b) | not isinstance(a, b) | \ No newline at end of file diff --git a/docs/python/advanced/timing.md b/docs/python/advanced/timing.md new file mode 100644 index 0000000..ab3b990 --- /dev/null +++ b/docs/python/advanced/timing.md @@ -0,0 +1,40 @@ +# Timing + +```python +def func_one(n): + return [str(num) for num in range(n)] + +def func_two(n): + return list(map(str,range(n))) + +import time + +# Get start time +start_time = time.time() + +# Run code +result = func_one(10000) + +# Get end time, compare +end_time = time.time() + +# In seconds, only precise to about 0.01s +elapsed_time = end_time - start_time + +print(f'Elapsed time: {elapsed_time}') + +# For more precise, use timeit +import timeit + +stmt = ''' +func_one(100) +''' + +setup = ''' +def func_one(n): + return [str(num) for num in range(n)] +''' + +print(f'Timeit time: {timeit.timeit(stmt, setup,number=100000)}') + +``` \ No newline at end of file diff --git a/docs/python/advanced/zip.md b/docs/python/advanced/zip.md new file mode 100644 index 0000000..904ac46 --- /dev/null +++ b/docs/python/advanced/zip.md @@ -0,0 +1,39 @@ +# Zipping + +```python +f = open('file1.txt', 'w+') +f.write('One file') +f.close() + +f = open('file2.txt', 'w+') +f.write('Two file') +f.close() + +import zipfile + +comp_file = zipfile.ZipFile('comp_file.zip','w') +comp_file.write('file1.txt', compress_type=zipfile.ZIP_DEFLATED) +comp_file.write('file2.txt', compress_type=zipfile.ZIP_DEFLATED) +comp_file.close() + +zip_obj = zipfile.ZipFile('comp_file.zip', 'r') +zip_obj.extractall('extracted_content') +zip_obj.close() + + +import os +import shutil + +dir_to_zip = os.getcwd() + '\\extracted_content' +output_filename = 'example' + +shutil.make_archive(output_filename, 'zip', dir_to_zip) +shutil.unpack_archive('example.zip', 'final_unzip', 'zip') + +os.unlink('file1.txt') +os.unlink('file2.txt') +os.unlink('comp_file.zip') +os.unlink('example.zip') +shutil.rmtree('extracted_content') +shutil.rmtree('final_unzip') +``` \ No newline at end of file