❌

Normal view

There are new articles available, click to refresh the page.
Before yesterdayMain stream

HAProxy EP 8: Load Balancing with Random Load Balancing

11 September 2024 at 14:23

Load balancing distributes client requests across multiple servers to ensure high availability and reliability. One of the simplest load balancing algorithms is Random Load Balancing, which selects a backend server randomly for each client request.

Although this approach does not consider server load or other metrics, it can be effective for less critical applications or when the goal is to achieve simplicity.

What is Random Load Balancing?

Random Load Balancing assigns incoming requests to a randomly chosen server from the available pool of servers. This method is straightforward and ensures that requests are distributed in a non-deterministic manner, which may work well for environments with equally capable servers and minimal concerns about server load or state.

Step-by-Step Implementation with Docker

Step 1: Create Dockerfiles for Each Flask Application

We’ll use the same three Flask applications (app1.py, app2.py, and app3.py) as in previous examples.

Flask App 1 – (app.py)

from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
    return "Hello from Flask App 1!"

@app.route("/data")
def data():
    return "Data from Flask App 1!"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5001)


Flask App 2 – (app.py)


from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
    return "Hello from Flask App 2!"

@app.route("/data")
def data():
    return "Data from Flask App 2!"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5002)

Flask App 3 – (app.py)

from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
    return "Hello from Flask App 3!"

@app.route("/data")
def data():
    return "Data from Flask App 3!"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5003)


Step 2: Create Dockerfiles for Each Flask Application

Create Dockerfiles for each of the Flask applications:

  • Dockerfile for Flask App 1 (Dockerfile.app1):
# Use the official Python image from Docker Hub
FROM python:3.9-slim

# Set the working directory inside the container
WORKDIR /app

# Copy the application file into the container
COPY app1.py .

# Install Flask inside the container
RUN pip install Flask

# Expose the port the app runs on
EXPOSE 5001

# Run the application
CMD ["python", "app1.py"]

  • Dockerfile for Flask App 2 (Dockerfile.app2):
FROM python:3.9-slim
WORKDIR /app
COPY app2.py .
RUN pip install Flask
EXPOSE 5002
CMD ["python", "app2.py"]


  • Dockerfile for Flask App 3 (Dockerfile.app3):

FROM python:3.9-slim
WORKDIR /app
COPY app3.py .
RUN pip install Flask
EXPOSE 5003
CMD ["python", "app3.py"]

Step 3: Create a Dockerfile for HAProxy

HAProxy Configuration file,


global
    log stdout format raw local0
    daemon

defaults
    log     global
    mode    http
    option  httplog
    option  dontlognull
    timeout connect 5000ms
    timeout client  50000ms
    timeout server  50000ms

frontend http_front
    bind *:80
    default_backend servers

backend servers
    balance random
    random draw 2
    server server1 app1:5001 check
    server server2 app2:5002 check
    server server3 app3:5003 check

Explanation:

  • The balance random directive tells HAProxy to use the Random load balancing algorithm.
  • The random draw 2 setting makes HAProxy select 2 servers randomly and choose the one with the least number of connections. This adds a bit of load awareness to the random choice.
  • The server directives define the backend servers and their ports.

Step 4: Create a Dockerfile for HAProxy

Create a Dockerfile for HAProxy (Dockerfile.haproxy):

# Use the official HAProxy image from Docker Hub
FROM haproxy:latest

# Copy the custom HAProxy configuration file into the container
COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg

# Expose the port for HAProxy
EXPOSE 80


Step 5: Create a docker-compose.yml File

To manage all the containers together, create a docker-compose.yml file:


version: '3'

services:
  app1:
    build:
      context: .
      dockerfile: Dockerfile.app1
    container_name: flask_app1
    ports:
      - "5001:5001"

  app2:
    build:
      context: .
      dockerfile: Dockerfile.app2
    container_name: flask_app2
    ports:
      - "5002:5002"

  app3:
    build:
      context: .
      dockerfile: Dockerfile.app3
    container_name: flask_app3
    ports:
      - "5003:5003"

  haproxy:
    build:
      context: .
      dockerfile: Dockerfile.haproxy
    container_name: haproxy
    ports:
      - "80:80"
    depends_on:
      - app1
      - app2
      - app3

Explanation:

  • The docker-compose.yml file defines the services (app1, app2, app3, and haproxy) and their respective configurations.
  • HAProxy depends on the three Flask applications to be up and running before it starts.

Step 6: Build and Run the Docker Containers

Run the following command to build and start all the containers:


docker-compose up --build

This command builds Docker images for all three Flask apps and HAProxy, then starts them.

Step 7: Test the Load Balancer

Open your browser or use curl to make requests to the HAProxy server:

curl http://localhost/
curl http://localhost/data

Observation:

  • With Random Load Balancing, each request should randomly hit one of the three backend servers.
  • Since the selection is random, you may not see a predictable pattern; however, the requests should be evenly distributed across the servers over a large number of requests.

Conclusion

By implementing Random Load Balancing with HAProxy, we’ve demonstrated a simple way to distribute traffic across multiple servers without relying on complex metrics or state information. While this approach may not be ideal for all use cases, it can be useful in scenarios where simplicity is more valuable than fine-tuned load distribution.

HAProxy EP 1: Traffic Police for Web

9 September 2024 at 16:59

In the world of web applications, imagine you’re running a very popular pizza place. Every evening, customers line up for a delicious slice of pizza. But if your single cashier can’t handle all the orders at once, customers might get frustrated and leave.

What if you could have a system that ensures every customer gets served quickly and efficiently? Enter HAProxy, a tool that helps manage and balance the flow of web traffic so that no single server gets overwhelmed.

Here’s a straightforward guide to understanding HAProxy, installing it, and setting it up to make your web application run smoothly.

What is HAProxy?

HAProxy stands for High Availability Proxy. It’s like a traffic director for your web traffic. It takes incoming requests (like people walking into your pizza place) and decides which server (or pizza station) should handle each request. This way, no single server gets too busy, and everything runs more efficiently.

Why Use HAProxy?

  • Handles More Traffic: Distributes incoming traffic across multiple servers so no single one gets overloaded.
  • Increases Reliability: If one server fails, HAProxy directs traffic to the remaining servers.
  • Improves Performance: Ensures that users get faster responses because the load is spread out.

Installing HAProxy

Here’s how you can install HAProxy on a Linux system:

  1. Open a Terminal: You’ll need to access your command line interface to install HAProxy.
  2. Install HAProxy: Type the following command and hit enter

sudo apt-get update
sudo apt-get install haproxy

3. Check Installation: Once installed, you can verify that HAProxy is running by typing


sudo systemctl status haproxy

This command shows you the current status of HAProxy, ensuring it’s up and running.

Configuring HAProxy

HAProxy’s configuration file is where you set up how it should handle incoming traffic. This file is usually located at /etc/haproxy/haproxy.cfg. Let’s break down the main parts of this configuration file,

1. The global Section

The global section is like setting the rules for the entire pizza place. It defines general settings for HAProxy itself, such as how it should operate, what kind of logging it should use, and what resources it needs. Here’s an example of what you might see in the global section


global
    log /dev/log local0
    log /dev/log local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660
    user haproxy
    group haproxy
    daemon

Let’s break it down line by line:

  • log /dev/log local0: This line tells HAProxy to send log messages to the system log at /dev/log and to use the local0 logging facility. Logs help you keep track of what’s happening with HAProxy.
  • log /dev/log local1 notice: Similar to the previous line, but it uses the local1 logging facility and sets the log level to notice, which is a type of log message indicating important events.
  • chroot /var/lib/haproxy: This line tells HAProxy to run in a restricted area of the file system (/var/lib/haproxy). It’s a security measure to limit access to the rest of the system.
  • stats socket /run/haproxy/admin.sock mode 660: This sets up a special socket (a kind of communication endpoint) for administrative commands. The mode 660 part defines the permissions for this socket, allowing specific users to manage HAProxy.
  • user haproxy: Specifies that HAProxy should run as the user haproxy. Running as a specific user helps with security.
  • group haproxy: Similar to the user directive, this specifies that HAProxy should run under the haproxy group.
  • daemon: This tells HAProxy to run as a background service, rather than tying up a terminal window.

2. The defaults Section

The defaults section sets up default settings for HAProxy’s operation and is like defining standard procedures for the pizza place. It applies default configurations to both the frontend and backend sections unless overridden. Here’s an example of a defaults section


defaults
    log     global
    option  httplog
    option  dontlognull
    timeout connect 5000ms
    timeout client  50000ms
    timeout server  50000ms

Here’s what each line means:

  • log global: Tells HAProxy to use the logging settings defined in the global section for logging.
  • option httplog: Enables HTTP-specific logging. This means HAProxy will log details about HTTP requests and responses, which helps with troubleshooting and monitoring.
  • option dontlognull: Prevents logging of connections that don’t generate any data (null connections). This keeps the logs cleaner and more relevant.
  • timeout connect 5000ms: Sets the maximum time HAProxy will wait when trying to connect to a backend server to 5000 milliseconds (5 seconds). If the connection takes longer, it will be aborted.
  • timeout client 50000ms: Defines the maximum time HAProxy will wait for data from the client to 50000 milliseconds (50 seconds). If the client doesn’t send data within this time, the connection will be closed.
  • timeout server 50000ms: Similar to timeout client, but it sets the maximum time to wait for data from the server to 50000 milliseconds (50 seconds).

3. Frontend Section

The frontend section defines how HAProxy listens for incoming requests. Think of it as the entrance to your pizza place.


frontend http_front
    bind *:80
    default_backend http_back
  • frontend http_front: This is a name for your frontend configuration.
  • bind *:80: Tells HAProxy to listen for traffic on port 80 (the standard port for web traffic).
  • default_backend http_back: Specifies where the traffic should be sent (to the backend section).

4. Backend Section

The backend section describes where the traffic should be directed. Think of it as the different pizza stations where orders are processed.


backend http_back
    balance roundrobin
    server app1 192.168.1.2:5000 check
    server app2 192.168.1.3:5000 check
    server app3 192.168.1.4:5000 check
  • backend http_back: This is a name for your backend configuration.
  • balance roundrobin: Distributes traffic evenly across servers.
  • server app1 192.168.1.2:5000 check: Specifies a server (app1) at IP address 192.168.1.2 on port 5000. The check option ensures HAProxy checks if the server is healthy before sending traffic to it.
  • server app2 and server app3: Additional servers to handle traffic.

Testing Your Configuration

After setting up your configuration, you’ll need to restart HAProxy to apply the changes:


sudo systemctl restart haproxy

To check if everything is working, you can use a web browser or a tool like curl to send requests to HAProxy and see if it correctly distributes them across your servers.

Mastering Request Retrying in Python with Tenacity: A Developer’s Journey

7 September 2024 at 01:49

Meet Jafer, a talented developer (self boast) working at a fast growing tech company. His team is building an innovative app that fetches data from multiple third-party APIs in realtime to provide users with up-to-date information.

Everything is going smoothly until one day, a spike in traffic causes their app to face a wave of β€œHTTP 500” and β€œTimeout” errors. Requests start failing left and right, and users are left staring at the dreaded β€œData Unavailable” message.

Jafer realizes that he needs a way to make their app more resilient against these unpredictable network hiccups. That’s when he discovers Tenacity a powerful Python library designed to help developers handle retries gracefully.

Join Jafer as he dives into Tenacity and learns how to turn his app from fragile to robust with just a few lines of code!

Step 0: Mock FLASK Api

from flask import Flask, jsonify, make_response
import random
import time

app = Flask(__name__)

# Scenario 1: Random server errors
@app.route('/random_error', methods=['GET'])
def random_error():
    if random.choice([True, False]):
        return make_response(jsonify({"error": "Server error"}), 500)  # Simulate a 500 error randomly
    return jsonify({"message": "Success"})

# Scenario 2: Timeouts
@app.route('/timeout', methods=['GET'])
def timeout():
    time.sleep(5)  # Simulate a long delay that can cause a timeout
    return jsonify({"message": "Delayed response"})

# Scenario 3: 404 Not Found error
@app.route('/not_found', methods=['GET'])
def not_found():
    return make_response(jsonify({"error": "Not found"}), 404)

# Scenario 4: Rate-limiting (simulated with a fixed chance)
@app.route('/rate_limit', methods=['GET'])
def rate_limit():
    if random.randint(1, 10) <= 3:  # 30% chance to simulate rate limiting
        return make_response(jsonify({"error": "Rate limit exceeded"}), 429)
    return jsonify({"message": "Success"})

# Scenario 5: Empty response
@app.route('/empty_response', methods=['GET'])
def empty_response():
    if random.choice([True, False]):
        return make_response("", 204)  # Simulate an empty response with 204 No Content
    return jsonify({"message": "Success"})

if __name__ == '__main__':
    app.run(host='localhost', port=5000, debug=True)

To run the Flask app, use the command,

python mock_server.py

Step 1: Introducing Tenacity

Jafer decides to start with the basics. He knows that Tenacity will allow him to retry failed requests without cluttering his codebase with complex loops and error handling. So, he installs the library,

pip install tenacity

With Tenacity ready, Jafer decides to tackle his first problem, retrying a request that fails due to server errors.

Step 2: Retrying on Exceptions

He writes a simple function that fetches data from an API and wraps it with Tenacity’s @retry decorator

import requests
import logging
from tenacity import before_log, after_log
from tenacity import retry, stop_after_attempt, wait_fixed

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

@retry(stop=stop_after_attempt(3),
        wait=wait_fixed(2),
        before=before_log(logger, logging.INFO),
        after=after_log(logger, logging.INFO))
def fetch_random_error():
    response = requests.get('http://localhost:5000/random_error')
    response.raise_for_status()  # Raises an HTTPError for 4xx/5xx responses
    return response.json()
 
if __name__ == '__main__':
    try:
        data = fetch_random_error()
        print("Data fetched successfully:", data)
    except Exception as e:
        print("Failed to fetch data:", str(e))

This code will attempt the request up to 3 times, waiting 2 seconds between each try. Jafer feels confident that this will handle the occasional hiccup. However, he soon realizes that he needs more control over which exceptions trigger a retry.

Step 3: Handling Specific Exceptions

Jafer’s app sometimes receives a β€œ404 Not Found” error, which should not be retried because the resource doesn’t exist. He modifies the retry logic to handle only certain exceptions,

import requests
import logging
from tenacity import before_log, after_log
from requests.exceptions import HTTPError, Timeout
from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_fixed
 

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

@retry(stop=stop_after_attempt(3),
        wait=wait_fixed(2),
        retry=retry_if_exception_type((HTTPError, Timeout)),
        before=before_log(logger, logging.INFO),
        after=after_log(logger, logging.INFO))
def fetch_data():
    response = requests.get('http://localhost:5000/timeout', timeout=2)  # Set a short timeout to simulate failure
    response.raise_for_status()
    return response.json()

if __name__ == '__main__':
    try:
        data = fetch_data()
        print("Data fetched successfully:", data)
    except Exception as e:
        print("Failed to fetch data:", str(e))

Now, the function retries only on HTTPError or Timeout, avoiding unnecessary retries for a β€œ404” error. Jafer’s app is starting to feel more resilient!

Step 4: Implementing Exponential Backoff

A few days later, the team notices that they’re still getting rate-limited by some APIs. Jafer recalls the concept of exponential backoff a strategy where the wait time between retries increases exponentially, reducing the load on the server and preventing further rate limiting.

He decides to implement it,

import requests
import logging
from tenacity import before_log, after_log
from tenacity import retry, stop_after_attempt, wait_exponential

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


@retry(stop=stop_after_attempt(5),
       wait=wait_exponential(multiplier=1, min=2, max=10),
       before=before_log(logger, logging.INFO),
       after=after_log(logger, logging.INFO))
def fetch_rate_limit():
    response = requests.get('http://localhost:5000/rate_limit')
    response.raise_for_status()
    return response.json()
 
if __name__ == '__main__':
    try:
        data = fetch_rate_limit()
        print("Data fetched successfully:", data)
    except Exception as e:
        print("Failed to fetch data:", str(e))

With this code, the wait time starts at 2 seconds and doubles with each retry, up to a maximum of 10 seconds. Jafer’s app is now much less likely to be rate-limited!

Step 5: Retrying Based on Return Values

Jafer encounters another issue: some APIs occasionally return an empty response (204 No Content). These cases should also trigger a retry. Tenacity makes this easy with the retry_if_result feature,

import requests
import logging
from tenacity import before_log, after_log

from tenacity import retry, stop_after_attempt, retry_if_result

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
  

@retry(retry=retry_if_result(lambda x: x is None), stop=stop_after_attempt(3), before=before_log(logger, logging.INFO),
       after=after_log(logger, logging.INFO))
def fetch_empty_response():
    response = requests.get('http://localhost:5000/empty_response')
    if response.status_code == 204:
        return None  # Simulate an empty response
    response.raise_for_status()
    return response.json()
 
if __name__ == '__main__':
    try:
        data = fetch_empty_response()
        print("Data fetched successfully:", data)
    except Exception as e:
        print("Failed to fetch data:", str(e))

Now, the function retries when it receives an empty response, ensuring that users get the data they need.

Step 6: Combining Multiple Retry Conditions

But Jafer isn’t done yet. Some situations require combining multiple conditions. He wants to retry on HTTPError, Timeout, or a None return value. With Tenacity’s retry_any feature, he can do just that,

import requests
import logging
from tenacity import before_log, after_log

from requests.exceptions import HTTPError, Timeout
from tenacity import retry_any, retry, retry_if_exception_type, retry_if_result, stop_after_attempt
 
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

@retry(retry=retry_any(retry_if_exception_type((HTTPError, Timeout)), retry_if_result(lambda x: x is None)), stop=stop_after_attempt(3), before=before_log(logger, logging.INFO),
       after=after_log(logger, logging.INFO))
def fetch_data():
    response = requests.get("http://localhost:5000/timeout")
    if response.status_code == 204:
        return None
    response.raise_for_status()
    return response.json()

if __name__ == '__main__':
    try:
        data = fetch_data()
        print("Data fetched successfully:", data)
    except Exception as e:
        print("Failed to fetch data:", str(e))

This approach covers all his bases, making the app even more resilient!

Step 7: Logging and Tracking Retries

As the app scales, Jafer wants to keep an eye on how often retries happen and why. He decides to add logging,

import logging
import requests
from tenacity import before_log, after_log
from tenacity import retry, stop_after_attempt, wait_fixed

 
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
 
@retry(stop=stop_after_attempt(2), wait=wait_fixed(2),
       before=before_log(logger, logging.INFO),
       after=after_log(logger, logging.INFO))
def fetch_data():
    response = requests.get("http://localhost:5000/timeout", timeout=2)
    response.raise_for_status()
    return response.json()

if __name__ == '__main__':
    try:
        data = fetch_data()
        print("Data fetched successfully:", data)
    except Exception as e:
        print("Failed to fetch data:", str(e))

This logs messages before and after each retry attempt, giving Jafer full visibility into the retry process. Now, he can monitor the app’s behavior in production and quickly spot any patterns or issues.

The Happy Ending

With Tenacity, Jafer has transformed his app into a resilient powerhouse that gracefully handles intermittent failures. Users are happy, the servers are humming along smoothly, and Jafer’s team has more time to work on new features rather than firefighting network errors.

By mastering Tenacity, Jafer has learned that handling network failures gracefully can turn a fragile app into a robust and reliable one. Whether it’s dealing with flaky APIs, network blips, or rate limits, Tenacity is his go-to tool for retrying operations in Python.

So, the next time your app faces unpredictable network challenges, remember Jafer’s story and give Tenacity a try you might just save the day!

Strings in python programming

4 September 2024 at 16:24

string in programming
a="Hello"
b="Avinash"
print(a,b)
a="My name is Avinash"
print(a)
a="""My name is Avinash.I am come to keeramangalam,str(age(19)"""
print(a)
a="Avinash"
print(a[4])
a="Avinash"
print(len(a))
txt="The best beauitiful in india"
print("India" in txt)

modify string

a="Hello world"
print(a.upper())

lower case

a="Hello world"
print(a.lower())

replace string

a="Helllo world"
print(a.replace("h","r"))

strip string

a="Hello world"
print(a.strip())

string concentrated

a="Hello"
b="Avinash"
c=(a+b)
print(c)

add two values

a="Hello"
b="world"
print(a+""+b)
age=10
txt=f"My name is Avinash,Iam{age}"
print(txt)

o/p
Hello Avinash
My name is Avinash
My name is Avinash.I am come to keeramangalam,str(age(19)
a
7
False
HELLO WORLD
hello world
Helllo world
Hello world
HelloAvinash
Helloworld
My name is Avinash,Iam10

Data type in python

3 September 2024 at 15:22

Build in datatype
text type:string
Numeric type:int, float,complex
sequence type:List,Tuple,range
mapping type:Dictionary
set type:set,frozenset
Boolean type:bool
binary type:bytes,bytearray,memory view
none type:none type
program
a="Avinash"
print(type(a))
b=45
print(type(b))
c=5.0
print(type(c))
d=5+8
print(type(d))
e=["pencil","box","scale"]
print(type(e))
f=("Apple","orange","banana")
print(type(f))
for i in range(5,9):
print(i)
g=True
print(type(g))
h=False
print(type(h))
i={}
print(type(i))
j={5,7,8,99}
print(type(j))
o/p






5
6
7
8



Datatype in python

3 September 2024 at 01:38

Build in datatype
text type:string
Numeric type:int, float,complex
sequence type:List,Tuple,range
mapping type:Dictionary
set type:set,frozenset
Boolean type:bool
binary type:bytes,bytearray,memory view
none type:none type
program
a="Avinash"
print(type(a))
b=45
print(type(b))
c=5.0
print(type(c))
d=5+8
print(type(d))
e=["pencil","box","scale"]
print(type(e))
f=("Apple","orange","banana")
print(type(f))
for i in range(5,9):
print(i)
g=True
print(type(g))
h=False
print(type(h))
i={}
print(type(i))
j={5,7,8,99}
print(type(j))

o/p






5
6
7
8



Windows | command lines |

1 September 2024 at 16:37
Go forward : cd path\to\folder 
Go backward : cd ../..
Show lists of files and directories : dir
Show lists of files and directories with hidden files also : dir /a
Clearing screen : cls
Show specific type of files: dir *.png | dir *.jpg
Help for a specific command: ipconfig /? | cls /?
Create a new directory : mkdir myDir | mkdir path\to
Remove or delete directories: if your directory is empty rmdir myDir else rmdir /S myDir
Changing drivers : C: | D:
Show path variables: path
Show available drive names: wmic logicaldisk get name
Change color: color 0B | color 90 or back to default just use color
Creating a file : echo somecontent > file.txt
Deleting file: del filename.ext
Reading contents of a file: type file.ext\
Override to a file : echo newcontent > samefile.ext
Appending to a file : echo appendingcontent >> samefile.ext
Copying files: copy test.txt mydir
Introduction to Command Prompt:

The command line in Windows is also known as Command Prompt or CMD.

On Mac and Linux systems, it's called Terminal.

Image description

To open Command Prompt, follow these steps: Open Start, search for 'Command Prompt', and select it.

Alternatively, you can click the keyboard shortcut (Windows + R), type 'cmd', and press Enter.

Image description

Image description

The first line will indicate the version we are using and the current file location by default.

Image description

Right-click on the top title bar, and the Properties screen will appear. From there,

Image description

Image description

To move from one directory to another, use the cd command followed by the folder name.

For example, to move to the 'Desktop' directory from C:\user\ranjith, type cd desktop.

C:\user> ranjith >
Cd space desktop 

To go to the 'python' folder inside 'Desktop', type cd desktop\python.

C:\user> ranjith >
Cd desktop > python

To return to the parent directory, use cd ... For example, if you are in C:\user\ranjith\desktop\python and want to go back two levels to

C:\user\ranjith, 
type cd ..\.. 

To navigate directly to a specific directory in one line, you can provide the full path.

For example, to go directly to C:\user\ranjith\desktop\python,

you can type cd 

C:\user\ranjith\desktop\python.

Image description
To list files and directories :

use the dir command.

For example, C:\user\ranjith> dir

will show the files, folders, free space, and storage details in the current directory.

Image description

To view the contents of a specific folder, use dir followed by the folder path.

 For example, C:\user\ranjith>dir 

Image description

Image description

Desktop\Python will display all files and folders in the Python folder on the Desktop.

Image description

To view hidden or system files, you can use the dir /a command.

 For example,

 C:\user\ranjith>dir /a

will display all files, including hidden and system files.

Image description

To clear the command prompt screen, use the cls command.

For example, 

C:\user\ranjith> cls 

Image description
will clear the screen and remove previous command outputs.

Opening Files and Viewing History:

To list files of a specific type in a directory, use the dir command with a filter.

For example, 

C:\user\ranjith>dir *.png will list all PNG 

Image description

image files in the current directory.

To open a specific file, enter its filename.

Image description

For instance,

C:\user\ranjith\python>binary_search.png would open the binary_search.png file.

Image description

To navigate through your command history, use the Up and Down arrow keys. Pressing the Up arrow key will cycle through previous commands, while the Down arrow key will move forward through the commands.


To get help on a command, use the /? option.

Image description

For example,

C:\user\ranjith>ipconfig /? will show help for the ipconfig command.

Creating and Removing Folders:

To create a new folder, use the mkdir command followed by the folder name.

For example,

C:\user\ranjith>python>mkdir temp will create a folder named temp.

Image description

Image description
To remove a folder, use the rmdir command followed by the folder name.

For example,

C:\user\ranjith>python>rmdir temp will delete the temp folder.

Image description
Note that the rm command is used for files in some systems, but in Command Prompt, you use del for files and rmdir for directories.

Creating and removing directories:

To create a directory, use the command mkdir txt. 
To remove a directory and its contents, use rmdir /s txt.

This will delete all files and subfolders in the directory as well as the directory itself.

Image description

Use Ctrl + Left Arrow to move the cursor to the beginning of the line and Ctrl + Right Arrow to move it to the end. 

Image description

Image description

To check the version, use var.

Image description

 To start multiple command boxes, use Start.

Image description

Image description

To exit, use Exit.

Image description


Drives and Color Commands:

To list all drives, use: wmic logicaldisk get name. This will show all available drives.

c:\user> ranjith > 
wmic logicaldisk get name

Image description

To switch to a different drive, type the drive letter followed by a colon (e.g., E:).

C:\user> ranjith >  E:

To list files in the current drive, use: dir.

E :\> dir

To view hidden files, use: dir /a.

E :\> dir /a

Image description

To see a directory tree, use: tree.

Image description

E :\> tree 

Changing Text and Background Colors:

E :\> color /?

Image description

Image description

To change the color of text and background, use: color /? to see help options.

For example, color a changes the text color to green.

Image description

E :\> color
E :\> color a

color fc sets a bright white background (if 'f' is not given, it defaults to black) and changes text color to bright red.

Image description

E :\> color fc

Image description

These commands help manage files and customize the appearance of your command prompt

File Attributes:

To view file attributes and get help, use: attrib /?.

Image description

C:\user> ranjith >  YouTube > attrib /? 

Image description
To see the attributes of a file, use: attrib sample.txt.

Image description

Image description

C:\user> ranjith >  Desktop >youtube >
attrib sample. txt

Replace sample.txt with your file name.
To add the "hidden" attribute to a file, use: attrib +h sample.txt.

Image description

C:\user> ranjith >  Desktop >youtube >
attrib +h sample. txt 

To remove the "hidden" attribute, use: attrib -h sample.txt.

Image description

Image description

C:\user> ranjith >  Desktop >youtube >
attrib +r - h sample. txt

Deleting and Creating Files:

To delete a file, use: del sample.txt.

Image description

C:\user> ranjith >  Desktop >youtube >
del sample. txt

del - delete <FileName >

To create a new file, use: echo. > sample.txt. This creates an empty file.

Image description

C:\Users\mrkis\Desktop\Youtube>
echo > sample.txt

To write text to a file, use: echo Kishore > sample.txt. This writes "Kishore" to the file.

Image description

Image description

C:\Users\mrkis\Desktop\Youtube>
echo Kishore > sample.txt

Image description

Image description

C:\Users\mrkis\Desktop\Youtube>
type sample.txt

To view the contents of the file, use: type sample.txt.
Appending Text to Files:

Image description

C:\Users\mrkis\Desktop\Youtube>echo hello>sample.txt

To add text to the end of a file without overwriting existing content, use: echo world >> sample.txt.

C:\Users\mrkis\Desktop\Youtube>type sample.txt

This will add "world" to the end of sample.txt.

Image description

To see the updated content, use: type sample.txt.
Copying Files:

To copy a file to another location or with a new name, use: copy sample.txt test2.txt. This copies sample.txt to a new file named test2.txt in the same directory. If you want to specify a different directory, provide the path instead of just the filename.

Image description

Image description

C:\Users\mrkis\Desktop\Youtube>
copy sample.txt test2

This guide helps with managing file attributes, performing file operations, and

Copying Files Between Disks:

To copy a file from one disk to another, use: copy sample.txt E:. This copies sample.txt from the current location to the E: drive.
Using XCOPY for Copying Directories:

To copy files and directories, including subdirectories, use: xcopy test1 test2 /s. This copies test1 (which can be a file or directory) to test2, including all subfolders and files.
Moving Files:

C:\Users\mrkis\Desktop\Youtube>
copy sample.txt e:
E - another disk

To move files from one location to another, use: move test1 test2. This command moves test1 to test2. If test2 is a folder, test1 will be moved into it. If test2 is a file name, test1 will be renamed to test2.
In summary:

C:\Users\mrkis\Desktop\Youtube>
xcopy test1 test2 /s
copy sample.txt test2
Sample. txt - endha file ah copy seiya vendum. 

S - sub files

copy source destination copies files.
xcopy source destination /s copies files and directories, including subdirectories.
move source destination moves files or renames them

Image description

Image description
Image description

js | Functions |

31 August 2024 at 16:16

Functions

Functions are pieces of code that we can reuse again and again in our code

Function Declaration - JavaScript Hoisting

syntax:
function functionName( ){

// code block

}

functionName()  //calling function
Example:
function msg( ){

console.log("Hii...Hello");

}

msg()  //calling function
//msg()
output:

Hii...Hello
//Hii...Hello

A function declaration defines a named function.It's hoisted,
meaning you can call it before it's defined.

Calling the function:
HOSTING
msg()  // valid  HOSTING
function msg( ){

console.log("Hii...Hello");


}
output:

Hii...Hello

Function Parameters and Arguments

syntax:

                        //input 
function functionName( parameter ){

// code block   //output

}

functionName( arguments)  //calling function

Functions can take parameters, which act as placeholders for the values
that will be passed to the function.The passing value is called an argument.

function msg( name ){

console.log("Hii...Hello" + name);

}

msg( "ranjith") ;
msg( "kumar") ;


output:

Hii...Hello ranjith
multiple parameters
function msg( name ,age){

console.log("Hii", + name +" my age"+age);

}

msg( "ranjith",25) ;
msg( "kumar",20) ;

Default Parameter

function printer(color){

console.log("print document in ${color} color");

}

//printer("blue") 
printer("blue") 
output:

document coloe blue color
//red override
function printer(color="black"){

console.log("print document in ${color} color");

}

//printer("red") 
printer( ) 
output:

//document coloe red color

document coloe black color

 Function with Return Type
function add( a,b){
     return a+b;

}

 let sum = add(10,20); //variable vechu assign panni print pannrom
 console.log(sum);  //30

 //console.log(add(10,20);   check pls
 Function Expression
A function expression defines a function inside an expression.
It's not hoisted, so you can't call it before it's defined.
syntax:

    variable      keyword
let functionName=function ( ){

   //code block

}

functionName()   // calling function

Ex:

           //don't change 
 let msg = function( ){   // function() indha typelaa kandippa irukkanum

 console.log("good morning");

}

msg( ) ;  //good morning 
With Argument
//msg( "ranjith") ;   // exp not hositing

let msg = function( name ){

console.log("good morning ${name}");

}

msg( "ranjith") ;  //good morning ranjith
Function Expression with Return Type
let mul = function (a,b){
   return a*b;

};

let result = mul( 5,2 ){
console.log(result); //10

 //console.log(mul(4,7));
 Arrow Function
 Arrow functions provide a concise syntax and do not bind their own 'this'. They are not hoisted.
 syntax:


    variable      keyword
let functionName=( ) =>{

   //code block

}

functionName()   // calling function

Example:
let evening = ( ) =>{

 console.log("good evening everyone");

}

evening ()   // good evening everyone 
With Argument
//not hoisting
let evening = ( name ) =>{

 console.log("good evening " + name);

}

evening ("ajith")   // good evening ajith
 Arrow Function with Return Type


 let sub =( a,b ) =>{
    return a - b ;
 };

  console.log( sub(10,6); // 4
Shorter Way
let sub =(a,b) => a-b;

console.log(sub(10,6)); //4
Function Calling Other Function
                       //ranjith
 function welcomeShopper(name){

 console.log(" welcome ${name} ! enjoy yoyr shopping experience")

}              //ranjith
    function main(name){

   // welcomeShopper(name); // direct calling
                   //ranjith
   let ShopperName-name;  // variableassign and after calling
                   //ranjith
   welcomeShopper(ShopperName); // calling top welcomeshopper

  };

  main("ranjith")  // welcome ranjith ! enjoy your.....
Anonymous Functions: Later on Course on Arrays
serTimeout(() => {

   console.log(" anonymous function executed");

 },2000 // 2sec delay  

 output: anonymous function executed
Scope of variables will on functions and loops
var: Function scoped.
Ex:
function demo(){
    var a =20;
    console.log(a); 

  }
demo();
console.log(a)  //error function outside calling
let: Block scoped.
const: Block scoped.
 Ex:

 function demo(){
     var a =20;
     console.log(a); 

   if (true){

   var x = "var";
   let y = "let";
   const z = ""const;     /// block scop

   console.log(x);
   console.log(y);    // all working good ...if block
   console.log(z);

  }
   console.log(x); // outer block code run successfully  (var)   
   console.log(y);   // error  (let)
   console.log(z);   // error not defienfd  (const)

 demo();

console.log(a)

Js | Truthy & Falsy |

31 August 2024 at 09:48

Truthy and Falsy Values:

in Javascript, truthy and falsy values are used to determine whether a value evaluate to true or false in a boolean
context.this concept is crucial for controlling the flow of your program using conditions like if statement.

Falsy Values: 0," ",null,NaN,false,undefined 
console.log(Boolean(0)); //false
console.log(Boolean(undefined)); //false

console.log(Boolean(' '));  //empty false

console.log(Boolean(null)); //false

console.log(Boolean(NaN)); //false not a number

console.log(Boolean(false)); //false

Truthy Values: any value that is not Falsy :

console.log(Boolean(1)); //true
console.log(Boolean(1833933)); //true
console.log(Boolean(-1)); //true
console.log(Boolean("hello")); //true
console.log(Boolean(1)); //true
console.log(Boolean([])); //true empty array
console.log(Boolean({})); //true empty object
console.log(function (){}); //true
Example:
           t     f
let cash =255  //0 ; 
    //conditions false  statement block not run
if (cash){
  console.log("you can buy burger with drink"); 
}else{
   console.log("you can buy burger"); 
}else{
   console.log("you don't have money"); 
}
let a;
console.log(a); //false
output:
undefined 
let a = 10;
console.log(a); //true
let a = null;
console.log(a); //false

Js | Decision Making: | if | if Else | Else if |

31 August 2024 at 09:15

Decision Making: if, if...else, else if


Decision making or control flow in programmming is the way we coontrol the execution
of code based on certain conditions.this allows the program to make choicces and execute diff code paths.

Example 1: if statement
syntax:
if (condition){

  //code block 

}

Example:

             f    f   t
let temp =  #24  #25  25;


if (temp>=25);
{

console.log("it is hot outside");

} 

Example 2: if...else statement

syntax:

if (condition){

  //code block 

}
else{

   //code block 

}
Example 1:
if (temp>=25);

{

console.log("it is hot outside");

}
else{

console.log("it is cold outside");

}
Example 2:
let isRaining= #true false;

if (isRaning);
{

console.log("take an umbrella");

}
else{

console.log(" you don't need an umbrella");

}
Example 3: else if statement
syntax:
if (condition){

  //code block 

}
else if(condition){

   //code block 

}
else{

   //code block 

}
Example:
let time=14;

if (time<12){

console.log("good morning"); 

}
else if(time<18){

 console.log("good afternoon");  

}
else{

 console.log("good evening");  

}
Example 4: Nested if statements
Variables
let age= 16;
let iswithparents=true;
let idproof=true;
Decision logic

if (age>=18);{

  if(idproof);
    console.log("you can visit the mall and can able to watch the movie"); 
  } else{
     console.log("you can visit te mall"); 
  }
}else{
     if(iswithparents);
        console.log("you can visit the play area"); 
  } else{
     console.log("you are not allowed in the play are"); 
  }

}
Example:
let day=1;

if(day===1){
  console.log("monday"); 
}
else if(day===2){
  console.log("thuesday"); 
}
else if(day===3){
  console.log("wenday"); 
}
else if(day===4){
  console.log("thuesday"); 
}
else if(day===5){
  console.log("friday"); 
}
else{
console.log("in valid"); 
}
Switch Statement
syntax:
switch(vale){
  case 1:
     //code block  
      break;
  case 2:    
    //code block  
       break;
  case 3:
      //code block  
       break;
  Default:
      //code block  
       break;
}
Exmple1:
let day=3;

switch(day){

  case 1:
      console.log("monday"); 
      break;
  case 2:
      console.log("thuesday"); 
      break;
  case 3:
      console.log("wensday"); 
      break;
  case 4:
      console.log("thresday"); 
      break;
  case 5:
      console.log("friday"); 
      break;
   default:
      console.log("invalid"); 
}

output:

wensday
Exmple2:
let choice='tea';

switch(choice){

   case 'coffee':
      console.log("you choose coffee monday"); 
      break;
   case 'tea':
      console.log(" you choose tea thuesday"); 
      break;
    case 'water':
      console.log(" you choose water thuesday"); 
      break;
    default:
      console.log("invalid"); 
}

output:

you choose tea 
Ternary Operator
short hand if else
let isadmin =true;

/*if(isadmin){
  console.log("am  admin");
}
else{
   console.log("am  user");
} */
                 true        .
let userrole = isadmin ? " am admin ":" am user ";
console.log(userrole);

let mark=60;
     var        cond      if       else
let result = mark>=30 ? " pass ":" fail ";
              //true
//let result = 25>=30 ? " pass ":" fail ";

console.log(result); 

output:

pass

Js | DataTypes |

30 August 2024 at 18:13

Datatypes

  • Javascript is Dynamic Typing

  • Primitive and Object Type

Primitive Data Types:

1.Number - Represents both integer and floating-point numbers.

let age=10;  #equal two apram enna num,str,bool ex...automatic convert pannikum enna datatype nu.
console.log(age);
console.log(typeof age); 

output:
10
number
age="25";
console.log(age);
console.log(typeof age); 

output:
string

float number:

let price=19.99;
console.log(price);
console.log(typeof price); 

output:
19.999
number

2.String - Represents a sequence of characters.

let greeting="Hello World.!"
console.log(greeting);
console.log(typeof greeting); 

output:
string

3.Boolean - Represents a logical entity and can have two values: true or false.

let isActive=true;
console.log( isActive);
console.log(typeof  isActive);
let isActive=false;
console.log( isActive);
console.log(typeof  isActive); 

4.Undefined - A variable that has been declared but not assigned a value.

let name;  #Error undefined
console.log( a);
console.log(typeof a); 

5.Null - Represents the intentional absence of any object value.

let name-null:
console.log(name);
console.log(typeof name); 

6.Symbol - Represents a unique and immutable value, often used as object property keys.

let unique=symbol("key"); #custom symbol
console.log(unique);
console.log(typeof unique); 

output:
symbol("key")

7.BigInt - Represents whole numbers larger than 2^53 - 1 (the largest number JavaScript can reliably represent with the Number type).


let largeNumber=BigInt(68690356789000833);
let largeNumber=68690356789000833n; #using the n notation

console.log( largeNumber);
console.log(typeof largeNumber); 

output:
68690356789000833n

Non-Primitive Data Types

1.Object

Represents a collection of properties, each consisting of a key (usually a string)
and a value (which can be any data type, including another object.

let person={

  name-'ranjith'.
  age=25,
  isEmployed=true;
}

console.log( person); //total laa print agum
console.log( person .name);  // name only
console.log( person .age);  // age only
console.log( person .isEmployed);

console.log(typeof  person); 

2.Array

A special type of object used for storing ordered collections of values.

let number=[1,2,5,4,8];
console.log( number);

let mixdata=[1,'2',true,false,null,[1,2,'5',"str"] ,undefined ];
console.log( mixdata);

3.Function

A special type of object that is callable and can perform an action.

function invite( ){
   console.log( "you are invitd");
}
invite()
**4.Date - A built-in object for handling dates and times.**

let now- new Date;
console.log( now);

outut:
date wed jul 24 2024 09.00:51 Gmt( indian stamdard)

Basic of python

29 August 2024 at 15:53

python
Basic of python
The python is the develop in the author: Guido van rossum in 1991
The python is interperters and compiler language
The python difference in interperters and compiler
interper:
It excutes a program line by line
It is a slow process
It does not generate any form of output
It takes less utilized of cpu
compiler:
It translates a program on a single run
It is fast process
It generate output in the form of .excuted
It is utilized cpu more

Js | Variable & Values |

29 August 2024 at 13:15

Jscript print :

console.log("Hello World ");

Variables & Values

Image description

Image description

  • The var keyword was used in all JavaScript code from 1995 to 2015.

  • The let and const keywords were added to JavaScript in 2015.

  • The var keyword should only be used in code written for older browsers.

Java script identifiers :

  • All JavaScript variables must be identified with unique names.

  • These unique names are called identifiers.

  • Identifiers can be short names (like x and y) or more descriptive names (age, sum, totalVolume).

  • The general rules for constructing names for variables (unique identifiers) are:

  • Names can contain letters, digits, underscores, and dollar signs.

Names must begin with a letter.

Names can also begin with $ and (but we will not use it in this tutorial).

Names are case sensitive (y and Y are different variables).

Reserved words (like JavaScript keywords) cannot be used as names.

What is Good?

- let and const have block scope.

- let and const can not be redeclared.

- let and const must be declared before use.

- let and const does not bind to this.

- let and const are not hoisted.

What is Not Good?

- var does not have to be declared.

- var is hoisted.

- var binds to this.

Declare var variable :

var a; #Error undefined 

Initialize the variable :

var a = 10;

Redeclaration allowed :

var a = 100;
console.log(a);

Output :
100

Declare let variable :

let b;

Initialize the variable :

let b = 10;

Redeclaration is not allowed :

let b =100; 

Reassignment is allowed :

b = 200;
console.log(b);

cons must Declare & initialize 1st line :

const PI=31415 ;
//fixed Value Called Constant
console.log (PI);

Reassignment is not allowed :

const c = 1;
c = 2;
console.log(c);

Naming conventions :

correct way :

Correct camel Case convention :
let userName = 'John'; 
Underscore is not recommended but valid :

let user_Name ='Max'; 
start from Underscore :

let _userName ='Doe'; 

start from dollar symbol :

let $userName='Evo' ; 

string concatenate :

console.log('Welcome + userName);
console.log("Hi + userName);
console.log('Bye + userName);

Incorrect variable names :

Invalid: variable names cannot start with a number

let 5date= 5;

Resrved keywords (Functions):

let new = "data";
let function = 20;

Symbols in variable names :

let #function = 'data'; 
let @function = 'data';
let John&Jane = 'Friends'; 

let $function = 'data';  
#this one is correct

Scope of variables will on functions & loops :

var: Function scoped.
let: Block scoped.
const: Block scoped 

Selection Sort

18 August 2024 at 05:59

The selection sort algorithm sorts an array by iteratively finding the minimum (for ascending order) / maximum (for descending order) element from the unsorted part and putting it at the beginning of the array.

The algorithm will be considering two subarrays in a given array.

  1. The subarray which is already sorted.
  2. Remaining subarray which is unsorted.

In every iteration of selection sort, the minimum element (considering ascending order)/ the maximum element (considering descending order) from the unsorted subarray is picked and moved to the sorted subarray. The movement is the process of swapping the minimum element with the current element.

How selection sort works ?

We will see the implementation of sorting in ascending order.

Consider the array : 29,10,14,37,14

First Iteration

Initially the val of min_index is 0. The element at the min_index is 29.

Then we can iterate over the rest of the array to find if there are any element which are minimum than the element at min_index.

first pass - selection sort

By iterating, we found 10 is the minimum element present in the array. Thus, replace 29 with 10. After one iteration 10, which happens to be the least value in the array, tends to appear in the first position of the sorted list.

after first pass - selection sort

Second Iteration

Now the value of min_index will be incremented by 1. So now it will be min_index = 1 . Then we can iterate over the rest of the array to find if the there are any element which are minimum than the element at min_index.

second pass

By iterating, we found 14 is the minimum element present in the array. Thus, swap 29 with 14.

image.png

Third Iteration

We can repeat the same process till the entire array is sorted.

Now the value of min_index will be incremented by 1. So now it will be min_index = 2 . Then we can iterate over the rest of the array to find if the there are any element which are minimum than the element at min_index.

third pass

By iterating, we found 14 is the minimum element present in the array. Thus, swap 29 with 14.

after third pass

Fourth Iteration

Now the value of min_index will be incremented by 3. So now it will be min_index = 3 . Then we can iterate over the rest of the array to find if the there are any element which are minimum than the element at min_index.

fourth pass

By iterating, we found 29 is the minimum element present in the array. Thus, swap 29 with 37.

after fourth pass

Its Done.

After 4th iteration, the entire array is sorted.

selection sort completed

So we can define the approach like,

  • Initialize minimum value(min_index) to location 0
  • Traverse the array to find the minimum element in the array
  • While traversing if any element smaller than min_index is found then swap both the values.
  • Then, increment min_index to point to next element
  • Repeat until array is sorted

Code


def selection_sort(array, size):
    
    for itr in range(size):
        min_index = itr
        for ctr in range(itr + 1, size):
            if array[ctr] < array[min_index]:
                min_index = ctr
        array[itr], array[min_index] = array[min_index], array[itr]
 
arr = [29,10,14,37,14]
size = len(arr)
selection_sort(arr, size)

print(arr)

Complexity analysis

Time Complexity

The sort complexity is used to express the number of execution times it takes to sort the list. The implementation has two loops. The outer loop which picks the values one by one from the list is executed n times where n is the total number of values in the list. The inner loop, which compares the value from the outer loop with the rest of the values, is also executed n times where n is the total number of elements in the list.

Therefore, the number of executions is (n * n), which can also be expressed as O(n2).

  1. Worst case – this is where the list provided is in descending order. The algorithm performs the maximum number of executions which is expressed as [Big-O] O(n2)
  2. Best case – this occurs when the provided list is already sorted. The algorithm performs the minimum number of executions which is expressed as [Big-Omega] Ξ©(n2)
  3. Average case – this occurs when the list is in random order. The average complexity is expressed as [Big-theta] Θ(n2)
Time Complexity - selection sort

Space Complexity

Since selection sort is an inplace sorting algorithm, it has a space complexity of O(1) as it requires one temporal variable used for swapping values.

Is Selection sort algorithm stable ?

The default implementation is not stable. However it can be made stable. But it can be achived using stable selection sort.

Is Selection Sort Algorithm in-place?

Yes, it does not require extra space.

When to use selection sort ?

  1. Selection sort can be good at checking if everything is already sorted πŸ˜‚.
  2. It is also good to use when memory space is limited. This is because unlike other sorting algorithms, selection sort doesn’t go around swapping things until the very end, resulting in less temporary storage space used.
  3. When a simple sorting implementation is desired
  4. When the array to be sorted is relatively small

When to avoid selection sort ?

  1. The array to be sorted has a large number of elements
  2. The array is nearly sorted
  3. You want a faster run time and memory is not a concern.

Summary

  1. Selection sort is an in-place comparison algorithm that is used to sort a random list into an ordered list. It has a time complexity of O(n2)
  2. The list is divided into two sections, sorted and unsorted. The minimum value is picked from the unsorted section and placed into the sorted section.
  3. This thing is repeated until all items have been sorted.
  4. The time complexity measures the number of steps required to sort the list.
  5. The worst-case time complexity happens when the list is in descending order. It has a time complexity of [Big-O] O(n2)
  6. The best-case time complexity happens when the list is already in ascending order. It has a time complexity of [Big-Omega] O(n2)
  7. The average-case time complexity happens when the list is in random order. It has a time complexity of [Big-theta] O(n2)
  8. The selection sort is best used when you have a small list of items to sort, the cost of swapping values does not matter, and checking of all the values is mandatory.
  9. The selection sort does not perform well on huge lists

Bonus Section

For the bigger array, how selection sort will work with insertion sort ?

The size of the array involved is rarely of much consequence. The real question is the speed of comparison vs. copying. The time a selection sort will win is when a comparison is a lot faster than copying. Just for example, let’s assume two fields: a single int as a key, and another megabyte of data attached to it. In such a case, comparisons involve only that single int, so it’s really fast, but copying involves the entire megabyte, so it’s almost certainly quite a bit slower.

Since the selection sort does a lot of comparisons, but relatively few copies, this sort of situation will favor it.

❌
❌