diff --git a/README-zh_CN.md b/README-zh_CN.md index ea24bef71..dfc934d56 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -3616,5 +3616,3 @@ where c.Customer_ID in (Select Customer_ID from cat_food); * [Cloud Slack bot](scenarios/cloud_slack_bot.md) * [Writing Jenkins Scripts](scenarios/jenkins_scripts.md) * [Writing Jenkins Pipelines](scenarios/jenkins_pipelines.md) - - \ No newline at end of file diff --git a/README.md b/README.md index dfe483f3d..f996f96bf 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ KubePrep
KubePrep
Linux Master
Linux Master
+ Sytem Design Hero
System Design Hero
diff --git a/coding/python/binary_search.py b/coding/python/binary_search.py index d1937e6e9..7a66c848a 100644 --- a/coding/python/binary_search.py +++ b/coding/python/binary_search.py @@ -1,28 +1,42 @@ #!/usr/bin/env python import random -from typing import List +from typing import List, Optional -def binary_search(arr: List[int], lb: int, ub: int, target: int) -> int: +def binary_search(arr: List[int], lb: int, ub: int, target: int) -> Optional[int]: """ A Binary Search Example which has O(log n) time complexity. """ - if lb <= ub: - mid: int = lb + (ub - lb) // 2 + while lb <= ub: + mid = lb + (ub - lb) // 2 if arr[mid] == target: return mid elif arr[mid] < target: - return binary_search(arr, mid + 1, ub, target) + lb = mid + 1 else: - return binary_search(arr, lb, mid - 1, target) - else: - return -1 + ub = mid - 1 + return -1 + + +def generate_random_list(size: int = 10, lower: int = 1, upper: int = 50) -> List[int]: + return sorted(random.randint(lower, upper) for _ in range(size)) + + +def find_target_in_list(target: int, lst: List[int]) -> int: + return binary_search(lst, 0, len(lst) - 1, target) + + +def main(): + """ + Executes the binary search algorithm with a randomly generated list. + Time Complexity: O(log n) + """ + rand_num_li = generate_random_list() + target = random.randint(1, 50) + index = find_target_in_list(target, rand_num_li) + print(f"List: {rand_num_li}\nTarget: {target}\nIndex: {index}") if __name__ == '__main__': - rand_num_li: List[int] = sorted([random.randint(1, 50) for _ in range(10)]) - target: int = random.randint(1, 50) - print("List: {}\nTarget: {}\nIndex: {}".format( - rand_num_li, target, - binary_search(rand_num_li, 0, len(rand_num_li) - 1, target))) + main() diff --git a/coding/python/merge_sort.py b/coding/python/merge_sort.py new file mode 100644 index 000000000..a92ca6bc9 --- /dev/null +++ b/coding/python/merge_sort.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python + +import random +from typing import List + + +def merge_sort(arr: List[int]) -> List[int]: + if len(arr) <= 1: + return arr + mid = len(arr) // 2 + left = merge_sort(arr[:mid]) + right = merge_sort(arr[mid:]) + return merge(left, right) + + +def merge(left: List[int], right: List[int]) -> List[int]: + merged = [] + i = j = 0 + while i < len(left) and j < len(right): + if left[i] <= right[j]: + merged.append(left[i]) + i += 1 + else: + merged.append(right[j]) + j += 1 + merged.extend(left[i:]) + merged.extend(right[j:]) + return merged + + +def generate_random_list(size: int = 10, lower: int = 1, upper: int = 100) -> List[int]: + return [random.randint(lower, upper) for _ in range(size)] + + +def main(): + """ + Executes the merge sort algorithm with a randomly generated list. + Time Complexity: O(n log n) + """ + rand_num_li = generate_random_list() + print(f"Unsorted List: {rand_num_li}") + sorted_list = merge_sort(rand_num_li) + print(f"Sorted List: {sorted_list}") + + +if __name__ == '__main__': + main() diff --git a/images/apps/system_design_hero.png b/images/apps/system_design_hero.png new file mode 100644 index 000000000..fa8c5552d Binary files /dev/null and b/images/apps/system_design_hero.png differ diff --git a/scripts/aws s3 event triggering/s3-lambda/s3-lambda.py b/scripts/aws s3 event triggering/s3-lambda/s3-lambda.py index 0fab7aa84..b28ced2db 100644 --- a/scripts/aws s3 event triggering/s3-lambda/s3-lambda.py +++ b/scripts/aws s3 event triggering/s3-lambda/s3-lambda.py @@ -1,38 +1,38 @@ import boto3 import json -def lambda_handler(event, context): - # i want to know that event thing - print(event) +def lambda_handler(event, context): + # i want to know that event thing + print(event) - # extract relevant information from the s3 event trigger - bucket_name=event['Records'][0]['s3']['bucket']['name'] - object_key=event['Records'][0]['s3']['object']['key'] + # extract relevant information from the s3 event trigger + bucket_name = event['Records'][0]['s3']['bucket']['name'] + object_key = event['Records'][0]['s3']['object']['key'] - # perform desired operations with the upload file - print(f"File '{object_key}' was uploaded to bucket '{bucket_name}'") + # perform desired operations with the uploaded file + print(f"File '{object_key}' was uploaded to bucket '{bucket_name}'") - # example: send a notification via sns - sns_client=boto3.client('sns') - topic_arn='arn:aws:sns:us-east-1::s3-lambda-sns' - sns_client.publish( - TopicArn=topic_arn, - Subject='s3 object created !!', - Message=f"File '{object_key}' was uploaded to bucket '{bucket_name}" - ) + # example: send a notification via SNS + sns_client = boto3.client('sns') + topic_arn = 'arn:aws:sns:us-east-1::s3-lambda-sns' + sns_client.publish( + TopicArn=topic_arn, + Subject='s3 object created !!', + Message=f"File '{object_key}' was uploaded to bucket '{bucket_name}'" + ) - # Example: Trigger another Lambda function - # lambda_client = boto3.client('lambda') - # target_function_name = 'my-another-lambda-function' - # lambda_client.invoke( - # FunctionName=target_function_name, - # InvocationType='Event', - # Payload=json.dumps({'bucket_name': bucket_name, 'object_key': object_key}) - # ) - # in case of queuing and other objective similar to the netflix flow of triggering + # Example: Trigger another Lambda function + # lambda_client = boto3.client('lambda') + # target_function_name = 'my-another-lambda-function' + # lambda_client.invoke( + # FunctionName=target_function_name, + # InvocationType='Event', + # Payload=json.dumps({'bucket_name': bucket_name, 'object_key': object_key}) + # ) + # in case of queuing and other objectives similar to the Netflix flow of triggering - return { - 'statusCode': 200, - 'body': json.dumps("Lambda function executed successfully !!") - } + return { + 'statusCode': 200, + 'body': json.dumps("Lambda function executed successfully !!") + } diff --git a/scripts/question_utils.py b/scripts/question_utils.py index 765ad91cb..a51fc3304 100644 --- a/scripts/question_utils.py +++ b/scripts/question_utils.py @@ -7,66 +7,50 @@ from typing import List import re -p = pathlib.Path(__file__).parent.parent.joinpath("README.md") - - -def get_file_list(): - file_list = "" - with open(p, "rb") as f: - for line in f.readlines(): - file_list += line.rstrip().decode() - return file_list - - -def get_question_list(file_list: List[str]) -> list: - file_list = re.findall("
(.*?)
", file_list) - questions_list = [] - for i in file_list: - q = re.findall(r"(.*?)", i)[0] - questions_list.append(q) - return questions_list - - -def get_answered_questions(question_list: List[str]) -> list: - t = [] - question_list = re.findall("
(.*?)
", question_list) - for i in question_list: - q = re.findall(r"(.*?)", i) - if q and q[0] == "": - continue - a = re.findall(r"(.*?)", i) - if a and a[0] == "": - continue - else: - t.append(q[0]) - return t - - -def get_answers_count() -> List: - """ - Return [answer_questions,all_questions] ,PASS complete. FAIL incomplete. - >>> get_answers_count() - [463, 463] - """ - ans_questions = get_answered_questions(get_file_list()) - len_ans_questions = len(ans_questions) - all_questions = get_question_list(get_file_list()) - len_all_questions = len(all_questions) - return [len_ans_questions, len_all_questions] +README_PATH = pathlib.Path(__file__).parent.parent / "README.md" +EXERCISES_PATH = pathlib.Path(__file__).parent.parent / "exercises" + +DETAILS_PATTERN = re.compile(r"
(.*?)
", re.DOTALL) +SUMMARY_PATTERN = re.compile(r"(.*?)", re.DOTALL) +B_PATTERN = re.compile(r"(.*?)", re.DOTALL) + + +def get_file_content() -> str: + with README_PATH.open("r", encoding="utf-8") as f: + return f.read() + + +def get_question_list(file_content: str) -> List[str]: + details = DETAILS_PATTERN.findall(file_content) + return [SUMMARY_PATTERN.search(detail).group(1) for detail in details if SUMMARY_PATTERN.search(detail)] + + +def get_answered_questions(file_content: str) -> List[str]: + details = DETAILS_PATTERN.findall(file_content) + answered = [] + for detail in details: + summary_match = SUMMARY_PATTERN.search(detail) + b_match = B_PATTERN.search(detail) + if summary_match and b_match and summary_match.group(1).strip() and b_match.group(1).strip(): + answered.append(summary_match.group(1)) + return answered + + +def get_answers_count() -> List[int]: + file_content = get_file_content() + answered = get_answered_questions(file_content) + all_questions = get_question_list(file_content) + return [len(answered), len(all_questions)] def get_challenges_count() -> int: - challenges_path = ( - pathlib.Path(__file__).parent.parent.joinpath("exercises").glob("*.md") - ) - return len(list(challenges_path)) + return len(list(EXERCISES_PATH.glob("*.md"))) -# WIP WAITING FEEDBACK -def get_random_question(question_list: List[str], with_answer=False): +def get_random_question(question_list: List[str], with_answer: bool = False) -> str: if with_answer: - return choice(get_answered_questions(question_list)) - return choice(get_question_list(question_list)) + return choice(get_answered_questions(get_file_content())) + return choice(get_question_list(get_file_content())) """Use this question_list. Unless you have already opened/worked/need the file, then don't or @@ -74,7 +58,7 @@ def get_random_question(question_list: List[str], with_answer=False): eg: #my_dir/main.py from scripts import question_utils -print(question_utils.get_answered_questions(question_utils.question_list) +print(question_utils.get_answered_questions(question_utils.get_question_list(question_utils.get_file_content())) >> 123 # noqa: E501 """ @@ -83,7 +67,3 @@ def get_random_question(question_list: List[str], with_answer=False): import doctest doctest.testmod() - # print(get_question_list(get_file_list())) - # print(get_answered_questions(get_file_list())) - # print(get_random_question(get_file_list(),True)) - # print(get_random_question(get_file_list(),False)) diff --git a/scripts/run_ci.sh b/scripts/run_ci.sh index 29e7b96c1..98dfbbbdc 100755 --- a/scripts/run_ci.sh +++ b/scripts/run_ci.sh @@ -2,14 +2,18 @@ set -euo pipefail -PROJECT_DIR="$(dirname $(readlink -f ${BASH_SOURCE[0]}))/.." +PROJECT_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/.." -MD_FILES=$(find ${PROJECT_DIR} -name "*.md" -not -path "${PROJECT_DIR}/tests/*") - -for file in ${MD_FILES[@]}; do - python ${PROJECT_DIR}/tests/syntax_lint.py ${file} > /dev/null +# Use the `-print0` option to handle spaces safely, and while-read loop: +find "${PROJECT_DIR}" \ + -name "*.md" \ + -not -path "${PROJECT_DIR}/tests/*" \ + -print0 | +while IFS= read -r -d '' file +do + python "${PROJECT_DIR}/tests/syntax_lint.py" "${file}" > /dev/null done echo "- Syntax lint tests on MD files passed successfully" -flake8 --max-line-length=100 . && echo "- PEP8 Passed" \ No newline at end of file +flake8 --max-line-length=100 . && echo "- PEP8 Passed" diff --git a/topics/ansible/README.md b/topics/ansible/README.md index e8f85ef86..315f5c8b5 100644 --- a/topics/ansible/README.md +++ b/topics/ansible/README.md @@ -421,10 +421,6 @@ def cap(self, string): What are callback plugins? What can you achieve by using callback plugins?
-
-What is Ansible Collections?
-
-
What is the difference between `include_task` and `import_task`?
@@ -530,6 +526,16 @@ It's used to rapidy develop and test Ansbile roles. Molecule can be used to tes
What are collections in Ansible?
+Ansible Collections are a way to package and distribute modules, roles, plugins, and documentation in a structured format. They help organize and distribute automation code efficiently, especially for complex environments. +
+ +
+Why Use Ansible Collections?
+ + - Modular and reusable components + - Simplifies management of custom and third-party modules + - Provides a standardized way to distribute automation content + - Helps in version control and dependency management
diff --git a/topics/argo/README.md b/topics/argo/README.md index ccafea056..8655cd86a 100644 --- a/topics/argo/README.md +++ b/topics/argo/README.md @@ -308,7 +308,9 @@ So instead of creating multiple separate applications, you have the root applica * Cluster Preparation: You would like to deploy multiple applications at once to bootstrap a Kubernetes cluster -TODO: add more :) +* Multiple environments: If deploying many versions of the same application, but with minor changes. For example, several test deployments to test different features + +* Multiple clusters: when the same application needs to be deployed across multiple K8s clusters connected to ArgoCD
@@ -507,4 +509,4 @@ It's an Analysis resource that fetches response status from Prometheus (monitori `kubectl argo rollouts get rollout SOME-APP --watch`
- \ No newline at end of file + diff --git a/topics/linux/README.md b/topics/linux/README.md index ebde22e0f..91696aae7 100644 --- a/topics/linux/README.md +++ b/topics/linux/README.md @@ -2249,6 +2249,14 @@ $OLDPWD
How to count the number of lines in a file? What about words?
+ +For these we can use `wc` command. + +1. To count the number of lines in file +```wc -l``` + +2. To count the number of words in file +```wc -w```