Sunday, March 29, 2026

How to Create User-defined Exceptions in Python

In this Python Exception Handling Tutorial series we'll see how to create user defined exceptions in Python which allow developers to create custom error types tailored to specific scenarios.

While Python provides a wide range of built‑in exceptions (like ValueError, TypeError, and IndexError), sometimes you as a user would want to create your own exception for a specific scenario in order to make error messages more relevant to the context. Such exceptions are called user-defined exceptions or custom exceptions. Defining your own exception makes error handling more meaningful and easier to debug.

User-defined exception in Python

To create a custom exception in Python, you simply define a new class that inherits from the built‑in Exception class (directly or indirectly).

Since your exception class is a class it can theoretically be defined to do anything any other class can do, but usually user-defined exception classes are kept simple, providing just enough information for handlers to understand the error.

As a convention, custom exception names should end with "Error", following the style of Python’s standard exceptions. This makes your code more readable and consistent with community practices.

User-defined exception Python example

Suppose you have a Python function that take age as a parameter and tells whether a person is eligible to vote or not. Voting age is 18 or more.

If person is not eligible to vote you want to raise an exception using raise statement, for this scenario you want to write a custom exception named “InvalidAgeError”.

# Custom exception
class InvalidAgeError(Exception):
  """Raised when the age provided is invalid."""
  def __init__(self, arg):
    self.msg = arg

def vote_eligibility(age):
  if age < 18:
    raise InvalidAgeError("Person not eligible to vote, age is " + str(age))
  else:
    print('Person can vote, age is', age)

# calling function
try:
  vote_eligibility(22)
  vote_eligibility(14)
except InvalidAgeError as error:
  print(error)

Output

Person can vote, age is 22
Person not eligible to vote, age is 14

Hierarchical custom exceptions

When creating a module that can raise several distinct errors, a common practice is to create a base class for exceptions defined by that module, and subclass that to create specific exception classes for different error conditions:

class Error(Exception):
  """Base class for exceptions in this module."""
  pass

class InputError(Error):
  """Exception raised for errors in the input.

  Attributes:
    expression -- input expression in which the error occurred
    message -- explanation of the error
  """

  def __init__(self, expression, message):
    self.expression = expression
    self.message = message

That's all for this topic How to Create User-defined Exceptions in Python. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Python Tutorial Page


Related Topics

  1. Python Exception Handling - try,except,finally
  2. Python assert Statement
  3. Passing Object of The Class as Parameter in Python
  4. Name Mangling in Python
  5. Strings in Python With Method Examples

You may also like-

  1. Magic Methods in Python With Examples
  2. Getting Substring in Python String
  3. Variable Length Arguments (*args), Keyword Varargs (**kwargs) in Python
  4. Python Program to Display Prime Numbers
  5. HashSet in Java With Examples
  6. Java Multithreading Interview Questions And Answers
  7. Switch-Case Statement in Java
  8. Spring Email Scheduling Example Using Quartz Scheduler

Array Rotation Java Program

Write a Java program to rotate an array to the left or right by n steps is a frequently asked Java interview question because it tests both problem-solving skills and understanding of array manipulation.

For example, if your array is– {1,2,3,4,5,6,7,8}

  • Rotating the array 2 steps to the right results in {7,8,1,2,3,4,5,6}.
  • Rotating the array 2 steps to the left gives {3,4,5,6,7,8,1,2}.

Array rotation program- Solution

This tutorial provides two efficient solutions for the Array Rotation Java Program.

  1. Using a temporary array and System.arraycopy() for faster copying. See example.
  2. Rotating elements one by one using loops, which is simple but less efficient for large arrays. See example.

Array rotation program- Using temp array

Solution using temporary array works as follows-

  1. Create a temporary array having the same length as the original array.
  2. If you have to rotate by 2 steps i.e. n=2 then copy n elements to a temporary array.
  3. Shift rest of the elements to the left or right based on rotation requirement.
  4. Copy elements from the temp array to the original array in the space created by shifting the elements.

In the program we actually copy all the elements to the temp array and then copy back to original array.

public class ArrayRotation {
  public static void main(String[] args) {
    int[] numArr={1,2,3,4,5,6,7,8};
    //rotateLeft(numArr, 4);
    rotateRight(numArr, 3);
  }
    
  private static void rotateLeft(int[] numArr, int steps){
    // create temp array
    int[] temp = new int[numArr.length];
    // copy elements to the temp array
    for(int i = 0; i < steps; i++){
      temp[(numArr.length-steps)+ i] = numArr[i];
    }
    // copy rest of the elements from the original array
    int i = 0;
    for(int j = steps; j < numArr.length; j++, i++){
      temp[i] = numArr[j];
    }
    //copy from temp to original 
    System.arraycopy(temp, 0, numArr, 0, numArr.length);    
    System.out.println("Array after left rotation- " + Arrays.toString(numArr));
  }
    
  private static void rotateRight(int[] numArr, int steps){
    // create temp array
    int[] temp = new int[numArr.length];
    // copy elements to the temp array
    for(int i = 0; i < steps; i++){
      temp[i] = numArr[(numArr.length-steps)+ i];
    }
    // copy rest of the elements from the original array
    int i = steps;
    for(int j = 0; j < numArr.length - steps; j++, i++){
      temp[i] = numArr[j];
    }
    System.out.println("Array after right rotation- " + Arrays.toString(temp));
  }
}

Output

Array after right rotation- [6, 7, 8, 1, 2, 3, 4, 5]

Time and space complexity

With this approach you need a temporary array of size n (same size as original array) so the space complexity is O(n).

Time Complexity is sum of the following actions

  • Creating the temporary array: O(n), where n is the size of the original array.
  • Copying elements into the temporary array: O(n).
  • Copying back into the original array using System.arraycopy(): O(n).

Thus the overall time complexity is O(n).

Array rotation program- using loops

This Java program for array rotation uses inner and outer for loops for shifting and copying elements.

Solution using loops works as follows-
  1. In an outer loop, copy the first element (in case of left rotation) or last element (in case of right rotation) in a temporary variable.
  2. Shift elements to the left or right as per rotation requirement in an inner loop one step at a time.
  3. Once out of inner loop copy the element stored in temp variable to its final position.
  4. Repeat the process for the total rotation steps.
public class ArrayRotation {
  public static void main(String[] args) {
    int[] numArr={1,2,3,4,5,6,7,8};
    rotateLeft(numArr, 2);
    //rotateRight(numArr, 3);
  }
    
  private static void rotateLeft(int[] numArr, int steps){
    for(int i = 0; i < steps; i++){
      // store the first element
      int temp = numArr[0];
      for(int j = 0; j < numArr.length - 1; j++){
        // shift element to the left by 1 position
        numArr[j] = numArr[j + 1];
      }
      // copy stored element to the last
      numArr[numArr.length - 1] = temp;
    }
    System.out.println("Array after left rotation- " + Arrays.toString(numArr));
  }
    
  private static void rotateRight(int[] numArr, int steps){
    for(int i = 0; i < steps; i++){
      int temp = numArr[numArr.length-1];
      for(int j = numArr.length-1; j > 0; j--){
        numArr[j] = numArr[j -1];
      }
      // copy stored element to the beginning
      numArr[0] = temp;
    }
    System.out.println("Array after right rotation- " + Arrays.toString(numArr));
  }
}

Output

Array after left rotation- [3, 4, 5, 6, 7, 8, 1, 2]

Time and space complexity

With this approach, if you need to rotate by n steps, and the array length is m, each step requires O(m) operations. So, the total number of operations = n * m. Thus the time complexity is O(n*m).

There is no extra space requirement so the space Complexity is O(1).

That's all for this topic Array Rotation Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. How to Find Common Elements Between Two Arrays Java Program
  2. Matrix Subtraction Java Program
  3. Java Lambda Expression Callable Example
  4. Producer-Consumer Java Program Using volatile
  5. Fibonacci Series Program in Java

You may also like-

  1. Difference Between Two Dates in Java
  2. How to Compile Java Program at Runtime
  3. Quick Sort Program in Java
  4. Write to a File in Java
  5. Map.Entry Interface in Java
  6. Synchronization in Java - Synchronized Method And Block
  7. Marker Interface in Java
  8. Spring Bean Life Cycle

Saturday, March 28, 2026

Support Vector Regression With Example

In this post we'll see how to use Support Vector Regression (SVR) which extends Support Vector Machine (SVM) to regression tasks. Since SVR is a regression model that means it is used for predicting continuous values where as SVM is a classification model which predicts a category or class label.

SVR is particularly useful when relationship between features and target may be non-linear or complex, when traditional linear regression struggles.

How does SVR work

Support vector regression works on the concept of hyperplane and support vectors. It also has a margin of error, called epsilon (ε). Let's try to understand these concepts.

1. Hyperplane- SVR model works by finding a function (hyperplane) that fits most data points within a defined margin of error (ε-tube).

In the case of linear relationship (Linear SVR) this hyperplane can be thought of as a straight line in 2D space.

In case of non-linear relationship this hyperplane can be thought of as existing in a higher dimensional space but in 2D space it manifests as a best fitting curved function.

2. Kernel trick- This ability of SVR to work in higher dimensional spaces is achieved by "kernel trick". A non-linear relationship is very difficult (actually impossible) to represent with a straight line. By mapping the data into a higher-dimensional feature space, the relationship may become linear in that space. That transformation is not done explicitly as it can be very expensive.

Using kernel trick this computation becomes easier, this lets SVR work in high-dimensional spaces implicitly, without ever explicitly constructing the transformed features.

Common kernel functions used in SVR are linear, polynomial, radial basis function (RBF), and sigmoid.

3. Margin of error- SVR has some tolerance for error. It gives a margin of error (ε) and data points that reside with in that margin are considered to have no error. You can think of this margin as a tube that goes on both sides of the fitted line (or curve). That tube is known as ε-insensitive tube because it makes the model insensitive to minor fluctuations.

SVR tries to fit a function such that most points lie within an ε-tube around the regression line.

4. Support vectors- These are the points that fall outside the ε-tube or lie on the edge of it. These support vectors determine the position of the hyperplane. These are the only points that influence the regression function because points falling with in the ε-tube are considered to have no error.

5. Slack Variables- Numerical values assigned to the variables representing the distance of the points outside the tube from the ε-tube. These slack variables are represented using the symbol \(\xi\).

Following images try to clarify all the above nomenclatures.

Support Vector Regression

SVR equation

In SVR there is an objective function and the goal is to minimize that function-

$$\frac{1}{2}\| w\| ^2+C\sum _{i=1}^n(\xi _i+\xi _i^*) $$

1. Here w is the weight vector which is computed from the support vectors:

$$w=\sum _{i=1}^n(\alpha _i -\alpha _i^*)x_i$$

where

  • xi are the support vectors (training points that lie outside the ε-tube)
  • \(\alpha _i, \alpha _i^*\) are Lagrange multipliers from the optimization problem

Note that Lagrange multipliers are used here in finding the maximum or minimum of a function when certain conditions (constraints) must be satisfied.

Constraints here are; for each data point (xi,yi):

$$y_i-(w\cdot x_i+b)\leq \varepsilon +\xi _i$$ $$(w\cdot x_i+b)-y_i\leq \varepsilon +\xi _i^*$$ $$\xi _i,\xi _i^*\geq 0$$

Note that in linear SVR, w is the weight vector defining the regression hyperplane.
In non-linear SVR, the kernel trick replaces direct inner products (xi, xj) with a kernel function K(xi, xj) and w is not computed explicitly.

minimizing \(\frac{1}{2}\| w\| ^2\) (norm of the weight vector) ensures the function is as flat as possible. Benefit of doing that is improved generalization of the model to new data and increased robustness against outliers.

2. \((\xi _i, \xi _i^*)\) are slack variables that measure deviations outside the ε-insensitive tube.

3. C is the regularization parameter controlling trade-off between flatness and total deviations outside the ε-insensitive tube. A large C value fits data closely which may risk overfitting, a smaller C value means simpler model which may mean risk of underfitting.

SVR tries to minimize the objective function during training. It finds the best \(w, b, \alpha _i, \alpha _i^*\) that minimize this objective function.

Once the optimized values are calculated, the regression function is defined as:

$$f(x)=\sum _{i=1}^n(\alpha _i-\alpha _i^*)K(x_i,x)+b$$

This is the actual function you use to make predictions.

Where:

  • xi = training data points
  • K(xi, x) = kernel function (linear, polynomial, RBF, etc.)
  • \(\alpha _i,\alpha _i^*\) = Lagrange multipliers from optimization
  • b = bias term

If you use a linear kernel, the equation simplifies to:

$$f(x)=w\cdot x+b$$

In case kernel is RBF (Radial Basis Function), the SVR prediction equation takes the form:

$$f(x)=\sum _{i=1}^n(\alpha _i-\alpha _i^*)\, \exp \left( -\gamma \| x-x_i\| ^2\right) +b$$

When SVR with Polynomial Kernel is used then the regression function becomes:

$$f(x)=\sum _{i=1}^n(\alpha _i-\alpha _i^*)\, (\gamma \cdot (x_i\cdot x)+r)^d+b$$

Support Vector Regression using scikit-learn Python library

Dataset used here can be downloaded from- https://www.kaggle.com/datasets/mariospirito/position-salariescsv

Goal is to predict the salary based on the position level.

In the implementation code is broken into several smaller units with some explanation in between for data pre-processing steps.

1. Importing libraries and reading CSV file

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.read_csv('./Position_Salaries.csv')

Position_Salaries.csv file is in the current directory.

2. Getting info about the data.

print(df.info())

Output


RangeIndex: 10 entries, 0 to 9
Data columns (total 3 columns):
 #   Column    Non-Null Count  	  Dtype 
---  ------    -------------- 	 ----- 
 0   Position 	10 non-null     object
 1   Level      10 non-null     int64 
 2   Salary     10 non-null     int64 

As you can see count of records is 10 only. Since dataset is already small so splitting is not done. Also, it is evident from one look at the small number of records that there are no duplicates and null values.

3. Feature and label selection

X = df.iloc[:, 1:-1]
y = df.iloc[:, -1]

Explanation- X = df.iloc[:, 1:-1]

  • : means "select all rows."
  • 1:-1 means "from column index 1 up to (but not including) the last column"

y = df.iloc[:, -1]

  • : means select all rows.
  • -1 means select the last column, uses negative indexing

"Position" column has been dropped as "level" column is also signifying the same thing in numerical values.

4.
print(X)
print(y)

On printing these two variables you can see that X is a 2D array where as y is a 1D array. Printing here just to make you understand that y may need conversion to 2D array as some of the functions need 2D array as parameter.

5. Scaling data

SVR relies on kernel functions (like RBF, polynomial) that compute distances between points. If features are on different scales, one feature can dominate the distance metric, skewing the model. So, standardizing the features is required.

With SVR target scaling is also required because the ε-insensitive tube and penalty parameter C are defined relative to the scale of y. Scaling y ensures that ε and C operate in a normalized space

from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVR
from sklearn.metrics import r2_score, mean_squared_error
scaler_X = StandardScaler()
scaler_y = StandardScaler()
X_scaled = scaler_X.fit_transform(X)
y_scaled = scaler_y.fit_transform(y.reshape(-1, 1)).ravel()

Dependent variable y needs to be changed to a 2D array for that reshape is used. Note that with reshape() one of the dimensions can be -1. In that case, the value is inferred from the length of the array. Here row is passed as -1 so NumPy will infer how many rows are needed based on array size.

ravel() is used to flatten the 2D array again. Otherwise, fit() method will give problem as that expects dependent variable to be a 1D array.

6. Fitting the model

reg = SVR(kernel='rbf')
reg.fit(X_scaled, y_scaled)

An object of class SVR is created, kernel is passed as 'rbf' which is also a default. For C and epsilon default values are used which are 1 and 0.1 respectively. Note that y_scaled was already changed to a 1D array using ravel(), if not done you'll get the following error.

A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().

7. Predicting values

First a single value is predicted.

#prediciting salary by passing level
y_pred_scaled = reg.predict(scaler_X.transform([[6]]))
# prediction will also be scaled, so need to do inverse transformation
y_pred = scaler_y.inverse_transform(y_pred_scaled.reshape(-1,1))
print("Prediction in original scale:", y_pred.ravel()) #145503.10688572

Note that X value has to be scaled as model is trained with scaled values. Also, predicted value has be inversely transformed to bring it back to original scale.

Predicting for the whole data. Since splitting is not done and there is no train and test data so X_scaled is used to predict values.

y_pred = scaler_y.inverse_transform(reg.predict(X_scaled).reshape(-1,1)).ravel()

8. Comparing test and predicted values

A dataframe is created and printed to display original and predicted values side-by-side.

df_results = pd.DataFrame({'Target':y, 'Predictions':y_pred})
print(df_results)

Output

	 Target	Predictions
0	45000	73416.856829
1	50000	78362.982831
2	60000	88372.122821
3	80000	108481.435811
4	110000	138403.075511
5	150000	178332.360333
6	200000	225797.711581
7	300000	271569.924155
8	500000	471665.638386
9	1000000	495411.293695

As you can see, model has lots of room for improvement, lack of proper data is one of the main reason here. For 1 million, prediction is way off the mark.

9. Seeing the model metrics such as R squared, mean squared error and root mean squared error.

#Metrics - R-Squared, MSE, RMSE
print("R2 score", r2_score(y, y_pred)) 
mse = mean_squared_error(y, y_pred)
print("Mean Squared Error", mse)
print("Root Mean Squared Error", np.sqrt(mse))

Output

R2 score 0.7516001070620797
Mean Squared Error 20036494264.13176
Root Mean Squared Error 141550.3241399742

10. Visualize the result

plt.scatter(X, y, color='red')
plt.plot(X, scaler_y.inverse_transform(reg.predict(X_scaled).reshape(-1,1)), color='blue')
plt.xlabel('Level')
plt.ylabel('Salary')
plt.title("SVR")
Support Vector Regression plot

That's all for this topic Support Vector Regression With Example. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Python Tutorial Page


Related Topics

  1. Simple Linear Regression With Example
  2. Multiple Linear Regression With Example
  3. Polynomial Regression With Example
  4. R-squared - Coefficient of Determination
  5. Mean Squared Error (MSE) With Python Examples

You may also like-

  1. What is LangChain - An Introduction
  2. Local, Nonlocal And Global Variables in Python
  3. Python count() method - Counting Substrings
  4. Python Functions : Returning Multiple Values
  5. Marker Interface in Java
  6. Functional Interfaces in Java
  7. Difference Between Checked And Unchecked Exceptions in Java
  8. Race Condition in Java Multi-Threading

First LangChain Program: Ask Me Anything

In this tutorial we’ll try to write few programs to connect to different LLMs using LangChain. In the post What is LangChain - An Introduction one of the points discussed was the standard interface provided by LangChain to integrate to any LLM.

Options to connect to the LLM using LangChain

There are two options to connect to the LLM using LangChain-

  • Using the init_chat_model function
  • Using the LLM specific model classes like ChatAnthropic, ChatOpenAI, ChatGoogleGenerativeAI, ChatOllama and so on.

Langchain init_chat_model function example

For the examples I am going to use OpenAI’s Gpt model, Google’s Gemini model and qwen3-32b through Groq inference provider. For another example, I’ll also use "llama3.1" through Ollama.

In the examples user's query is send to the model which responds with the answer to that query.

  • Packages needed are-

    • python-dotenv
    • langchain
    • langchain-openai
    • langchain-google-genai
    • langchain-groq
    • langchain-ollama

    You can install them individually using pip install PACKAGE_NAME or, if you are creating a Python program then you can create a requirements.txt file and put all the above mentioned external package dependencies in that file and provide that file to pip install commamd.

    pip install -r requirements.txt
    
  • Getting and setting the API key

    For using OpenAI models, Gemini models and Groq you must first obtain API key from the respective API provider. You can create an .env file in your Python project and store the generated API keys there.

    • GEMINI_API_KEY = “YOUR_GOOGLE_GEMINI_KEY”
    • GROQ_API_KEY = “YOUR_GROQ_API_KEY”
    • OPENAI_API_KEY = “YOUR_ OPENAI_API_KEY”

    This .env file can then be loaded using load_dotenv() function.

1. Connecting to Gemini

You can initialize the model by specifying the model name and optionally, the model_provider in init_chat_model() function. The temperature parameter is used to control the randomness, creativity, and determinism of the model's output.

  • Low Temperature (e.g., 0.0 to 0.3)

    Makes the model deterministic and focused. You'll get a "to the point" answer.

  • High Temperature (e.g., 0.7 to 1.0+)

    Makes the model creative and more diverse.

from langchain.chat_models import init_chat_model
from dotenv import load_dotenv

load_dotenv()
model = init_chat_model(    
  model="google_genai:gemini-3.1-flash-lite-preview",
  temperature=0.3
)
response = model.invoke("Explain Agentic AI in 5 lines")
print(response)

Output

content=[{'type': 'text', 'text': 'Agentic AI refers to autonomous systems capable of setting their own goals, breaking them 
into tasks, and executing them with minimal human intervention. Unlike traditional AI that simply responds to prompts, these 
agents use reasoning and tools to navigate complex environments. They actively monitor progress, adapt their strategies in 
real-time, and make decisions to achieve a desired outcome. Essentially, they shift the paradigm from "AI as a tool" to 
"AI as a collaborative partner" that gets work done.', 'extras': {'signature': 
'EjQKMgG+Pvb7ue1hvNYKCnERjPRv7v99o5JJsdZbRGGB3ce3fntMxKjz0D2dXa5GBv3l5myR'}}] additional_kwargs={} response_metadata=
{'finish_reason': 'STOP', 'model_name': 'gemini-3.1-flash-lite-preview', 'safety_ratings': [], 'model_provider': 'google_genai'} 
id='lc_run--019d2edb-3426-7033-a08d-d6d29fc97de5-0' tool_calls=[] invalid_tool_calls=[] usage_metadata={'input_tokens': 9, 
'output_tokens': 95, 'total_tokens': 104, 'input_token_details': {'cache_read': 0}}

As you can see response contains lot of other information along with actual content. You can extract the content part using response.content.

2. Connecting to OpenAI

from langchain.chat_models import init_chat_model
from dotenv import load_dotenv

load_dotenv()
model = init_chat_model(    
    model="gpt-5.2",
    temperature=0.3
)

response = model.invoke("Explain Agentic AI in 5 lines")
print(response.content)

3. Using qwen3-32b model through Groq

Since Groq is the model provider here so you need to explicitly mention it using model_provider parameter.

from langchain.chat_models import init_chat_model
from dotenv import load_dotenv

load_dotenv()
model = init_chat_model(    
    model="qwen/qwen3-32b",
    model_provider="groq",
    temperature=0.3
)

response = model.invoke("Explain Agentic AI in 5 lines")
print(response.content)

Configuration with init_chat_model

Above example used the fixed model initialization but you can also configure models at runtime using init_chat_model. That makes it easy to switch providers without changing code.

You need to set the following parameters for that-

  • configurable_fields: Defines which fields can be changed at runtime (e.g., 'any' for all fields, or a list like ("model", "temperature")).
  • config_prefix: If set, allows runtime configuration via config["configurable"]["{prefix}_{param}"]

in the following code initially "gpt-5.2" is selected as the model but later using the config_prefix "llama3.1" is set as the model.

from langchain.chat_models import init_chat_model
from dotenv import load_dotenv

load_dotenv()
configurable_model = init_chat_model(    
    model="gpt-5.2",
    temperature=0.3,
    configurable_fields="any", # Allows all fields to be configurable
    config_prefix="my_config" # Prefix for environment variables to override defaults
)

response = configurable_model.invoke("What is the role of GPU in the rise of AI?", 
        config={
        	"configurable": { "my_config_temperature": 0.7, # Override temperature for this invocation
                          "my_config_model": "llama3.1", # Override model for this invocation
                          "my_config_model_provider": "ollama" # Override model provider for this invocation
                        }
     	})
print(response.content)

You’ll get the output through Ollama not through GPT, because of the configuration settings.

Using Chat model classes in LangChain

LangChain provides chat model classes too for integrating with various models, enabling developers to build intelligent conversational AI applications with seamless support for OpenAI, Anthropic, Hugging Face, and other large language models.

These classes wrap various model providers, allowing developers to switch between them with minimal code changes.

Core classes for chat models are usually prefixed with Chat and imported from their integration packages, such as langchain_openai and langchain_anthropic. For example,

  • ChatOpenAI: For OpenAI models.
  • ChatAnthropic: For Anthropic models.
LangChain ChatModel Classes

Examples using Chat model classes

  1. Using qwen3-32b model through ChatGroq
  2. from langchain_groq import ChatGroq
    from dotenv import load_dotenv
    
    load_dotenv()
    model = ChatGroq(    
        model="qwen/qwen3-32b",
        temperature=0.3
    )
    
    response = model.invoke("What is the role of GPU in deep learning, explain in 5 lines?")
    print(response.content)
    
  3. Using ChatGoogleGenerativeAI to connect to Gemini
  4. from langchain_google_genai import ChatGoogleGenerativeAI
    from dotenv import load_dotenv
    
    load_dotenv()
    model = ChatGoogleGenerativeAI(    
        model="gemini-3.1-flash-lite-preview",
        temperature=0.3
    )
    
    response = model.invoke("What is the role of GPU in deep learning, explain in 5 lines?")
    print(response.content)
    

That's all for this topic First LangChain Program: Ask Me Anything. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Java is a Strongly Typed Language
  2. Primitive Data Types in Java
  3. Access Modifiers in Java - Public, Private, Protected and Default
  4. What Are JVM, JRE And JDK in Java
  5. Object Creation Using new Operator in Java

You may also like-

  1. String in Java Tutorial
  2. Array in Java
  3. Count Number of Words in a String Java Program
  4. Ternary Operator in Java With Examples
  5. Java Multithreading Interview Questions And Answers
  6. Java Exception Handling Tutorial
  7. ConcurrentHashMap in Java With Examples
  8. TreeMap in Java With Examples

Thursday, March 26, 2026

Java Variable Types With Examples

In this guide, we’ll explore the different types of variables in Java, their scopes, visibility, and practical examples to help you master the concept.

We’ll also see what is meant by declaring a variable and what is meant by initialization of a variable in Java.

Declaring and Initializing a variable in Java

In Java, every variable must be declared before use. Declaration specifies the type of the variable, which can be either a primitive data type (such as int, double, char), or having class or interface as type (reference variable).

Examples of variable declaration

int age, number; // two int variables declared

double amount; // a double variable declared

Person person; // reference type variable declared

As you see here, in the first statement two variables of type int are declared. Note that you can declare two or more variables of same type as a comma separated list.

In the third statement a variable person is declared which is of type Person. Here Person is a class.

Java 10 introduced a new feature called local variable type inference where the type of the variable is inferred from the variable initializer. A new reserved type name “var” is added in Java to define and initialize local variables, read more about var type here- Var type in Java - Local Variable Type Inference

Initialization of a variable in Java

Initialization means providing initial value of the variable. Generally, both declaration and initialization are done in a single statement.

 
int age = 30;

char grade = 'A';

But that is not necessary, you can also declare a variable first and initialize it later.

 
int age;

...... 
......
age = 50;

Variables can also be initialized using expressions:

 
double amount;

amount = 67/9;

Here amount will have the value of 67 divided by 9.

Types of variables in Java

The Java programming language defines the following kinds of variables:

  1. Instance Variables (Non-Static Fields)–Instance variables are declared inside a class but outside any method, constructor, or block, and they are not marked as static. Each object of the class gets its own copy of these variables, meaning their values are unique to each instance.

    For example, if you have a class Person and two objects of it person1 and person2 then the instance variables of these two objects will have independent values.

    public class Person {
     private String firstName;
     private String lastName;
     private int age;
     private char gender;
     public Person(String firstName, String lastName, int age, char gender){
      this.firstName = firstName;
      this.lastName = lastName;
      this.age = age;
      this.gender = gender;
     }
     
     public String getFirstName() {
      return firstName;
     }
    
     public String getLastName() {
      return lastName;
     }
    
     public int getAge() {
      return age;
     }
     public char getGender() {
      return gender;
     }
    }
    
    public class InstanceDemo {
    
     public static void main(String[] args) {
      Person person1 = new Person("Ram", "Mishra", 23, 'M');
      Person person2 = new Person("Amita", "Chopra", 21, 'F');
      
      System.out.println("Values in object person1 - " + 
        person1.getAge() + " " + person1.getFirstName() + " " + 
        person1.getLastName()+ " " + person1.getGender());
      System.out.println("Values in object person2 - " + 
        person2.getAge() + " " + person2.getFirstName() + " " + 
        person2.getLastName()+ " " + person2.getGender());
    
     }
    
    }
    

    Output

    Values in object person1 - 23 Ram Mishra M
    Values in object person2 - 21 Amita Chopra F
    

    Here you can see how using the constructor of the class, variables are initialized for both the objects and output shows that each instance of the class has its own values for the fields.

  2. Class Variables (Static Fields)- A class variable in Java is any field declared with the static modifier. As the name suggests class variable is at the class level. Unlike instance variables, there is only one copy of a static variable per class, shared across all objects. Doesn’t matter how many instances (objects) of the class you have, the class variable will have the same value. You can access class variables directly using the class name, without creating an object.

    Java class variables example

    One common use of static fields is to create a constant value that's at a class level and applicable to all created objects.

    public class Employee {
     int empId;
     String name;
     String dept;
     // static constant
     static final String COMPANY_NAME = "XYZ";
     Employee(int empId, String name, String dept){
      this.empId = empId;
      this.name = name;
      this.dept = dept;
     }
     
     public void displayData(){
      System.out.println("EmpId = " + empId + " name= " + name + " dept = " + 
      dept + " company = " + COMPANY_NAME);
     }
     public static void main(String args[]){  
      Employee emp1 = new Employee(1, "Ram", "IT");
      Employee emp2 = new Employee(2, "Krishna", "IT");
      emp1.displayData();
      emp2.displayData();
     }
    }
    

    Output

    EmpId = 1 name= Ram dept = IT company = XYZ
    EmpId = 2 name= Krishna dept = IT company = XYZ
    
  3. Local Variables– Local variables are variables declared within a method, constructor, or block. They represent the temporary state of a method and exist only during the execution of that method. Once the method finishes, the local variables are destroyed, and their values are no longer accessible.

    Scope of Local Variables

    The scope of a local variable is limited to the block of code enclosed by curly braces {} where it is declared. This means:
    • A local variable declared inside a method is accessible only within that method.
    • If you declare a variable inside a nested block (such as an if statement or loop), its scope is restricted to that block.

    One more thing to note is that you can have a local variable with the same name as class level variable in the method, with in the method the local variable will take priority.

    Java local variables example

    public class InstanceDemo {
     // class level variable
     int x = 8;
     public static void main(String[] args) {
      
      InstanceDemo id = new InstanceDemo();
      
      id.display();
      System.out.println("value of class level variable x " + id.x);
     }
     
     public void display(){
      int x = 5;  // local variable
      boolean flag = true;
      System.out.println("value of local variable x " + x);
      if (flag){
       int y = 10; // nested scope variable
       System.out.println("value of local variable y inside if " + y);
      }
      // This will cause compile-time error
      //System.out.println("value of local variable y inside if " + y); 
     }
     
    }
    

    Output

    value of local variable x 5
    value of local variable y inside if 10
    value of class level variable x 8
    

    Here you see there is a class level variable and again it the method display() there is a variable with the same name x. With in the method value of local variable x takes priority and that is printed. Once out of the method, x that is recognized is the class level variable x.

    Another thing to note is the nested scope created by the if condition with in the display() method. Scope of variable y is in between the starting and closing braces of the if condition. Once you are out of if condition y won’t be recognized. Any attempt to print value of y outside the if condition scope will result in compile-time error.

  4. Parameters- Variables passed to any method are known as parameters. Any changes made to the primitive types parameter won’t change the original value.

    Java parameters example

    public class InstanceDemo {
     public static void main(String[] args) {
      
      InstanceDemo id = new InstanceDemo();
      int x = 10;
      id.display(x);
      System.out.println("value of x after method call " + x);
     }
     
     public void display(int x){
      
      x++;
      System.out.println("value of local variable x " + x);
     }
     
    }
    

    Output

    value of local variable x 11
    value of x after method call 10
    

    Here you have a variable x that is passed to display method as an int parameter. With in the method display() value of x is changed. But that change is local only and doesn’t change the original value of x. This is because copy of a variable is passed as a method parameter.

    If an object is passed as a parameter and any of that object’s field is changed, that change will be visible in other scopes too.

That's all for this topic Java Variable Types With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Basics Tutorial Page


Related Topics

  1. Java is a Strongly Typed Language
  2. Primitive Data Types in Java
  3. Access Modifiers in Java - Public, Private, Protected and Default
  4. What Are JVM, JRE And JDK in Java
  5. Object Creation Using new Operator in Java

You may also like-

  1. String in Java Tutorial
  2. Array in Java
  3. Count Number of Words in a String Java Program
  4. Ternary Operator in Java With Examples
  5. Java Multithreading Interview Questions And Answers
  6. Java Exception Handling Tutorial
  7. ConcurrentHashMap in Java With Examples
  8. TreeMap in Java With Examples

What is LangChain - An Introduction

LangChain is an open-source framework which is designed to simplify the creation of LLM powered applications. Through its tools and APIs, it allows you to refine and customize information, making LLM generated responses more precise and contextually meaningful. For example, using LangChain you can link LLMs to external data sources and computation to enhance LLM model’s capabilities. By leveraging these capabilities, developers can build powerful AI applications like smart chatbots, advanced Q&A systems, summarization services.

LangChain Installation

LangChain framework is available as libraries in Python and JavaScript.

  • To install the LangChain package in Python you can use the following command
  • pip install -U langchain
        

    Prerequisite is Python 3.10+ installation for the LangChain version 1.2.13

  • For Typescript installation, you can use the following command
  • npm install langchain @langchain/core
        

    Prerequisite is Node.js 20+ installation for the LangChain version 1.2.13

Core components of LangChain

  1. Models

    LangChain’s standard model interfaces give you access to many different provider integrations. LangChain provides integration to nearly all the LLMs through a standard interface, including OpenAI, Anthropic, Google, to many open source models (like Meta AI’s LLaMa, Deepseek's Deepseek-LLM, Mistral) through HuggingFace, to locally downloaded LLMs through Ollama.

    Note that many LLM providers require an API key and you need to create an account in order to receive an API key.

    The simplest way to connect to any LLM is using the init_chat_model function in LangChain or you can use the LLM specific model classes like ChatAnthropic, ChatOpenAI, ChatGoogleGenerativeAI, ChatOllama and so on.

    Only thing you need is the integration package for the chosen model provider to be installed which is generally in the format langchain-LLM_PROVIDER_NAME. So, if you are using OpenAI then you need to install langchain-openai package.

    Refer this post- First LangChain Program: Ask Me Anything to see how to connect to different models programmatically using LangChain.

  2. Prompt Template

    LangChain provides a PromptTemplate class to create a prompt template- a dynamic prompt with some placeholders that can be given actual values later. There is also a ChatPromptTemplate class which acts as a prompt template for chat models.

  3. Tools

    LLMs have some limitations, firstly these models are trained up to some cutoff date and they have data up to that time only. Though many LLMs now have web browsing capability to bypass their training data cutoff. Another problem is not have domain data or company specific data.

    Langchain tools can give that functionality to agents by letting them fetch real-time data, execute code, query external databases, and take actions in the world. Under the hood, tools are callable functions with well-defined inputs and outputs that get passed to a chat model. The model decides when to invoke a tool based on the conversation context, and what input arguments to provide.

  4. Agents

    LangChain agents combine LLMs with tools to create systems that can complete complex tasks step by step. Unlike a basic application where you send a prompt and get a response from an LLM, LangChain agents can think, plan, and adapt.

    They integrate language models with tools to reason about tasks and choose the right actions.

    This allows them to iteratively work toward solutions with greater intelligence and flexibility.

  5. Chains

    As the name LangChain itself suggests, chains are the main concept of LangChain. They allow developers to link multiple components together into a single workflow. Each link in the chain can handle a specific task, from prompt formatting to retrieval and reasoning. This modular design makes it easy to build complex AI applications step by step.

    With the LangChain Expression Language (LCEL), you can define these chains declaratively, using the pipe (|) symbol to connect prompts, models, retrievers, and output parsers.

  6. Memory

    For many AI applications you may need to retain information about previous interactions. For AI agents, memory is crucial because it lets them remember previous interactions, learn from feedback, and adapt to user preferences. LangChain provides both short term memory and long term memory.

    1. Short term memory- It lets your application remember previous interactions within a single thread or conversation.
    2. Long-term memory- It lets your agent store and recall information across different conversations and sessions. Long-term memory persists across threads and can be recalled at any time.

How does LangChain work

Now, when you have some idea about the components of LangChain, let us try to understand how LangChain can actually chain together different components to create a workflow for LLM powered applications.

For example, a typical Retrieval-Augmented Generation (RAG) application may have a workflow as given below-

  1. Receive the user’s query.
  2. Reformulate the query by sending it to the LLM which rephrases the user provided query into a concise search query.
  3. Retrieve the data relevant to search query, which could involve connecting to databases, APIs, or other repositories (e.g. Confluence). LangChain provides various document loaders like PyPDFLoader, TextLoader, CSVLoader, ConfluenceLoader for integrating data from numerous sources.
  4. Pass the retrieved documents to LLM to summarize the information
  5. Pass the retrieved information, along with the original query, to an LLM to get the final answer.

That's all for this topic What is LangChain - An Introduction. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Java Program to Check Prime Number
  2. Armstrong Number or Not Java Program
  3. How to Display Pyramid Patterns in Java - Part2
  4. Java Program to Reverse a Number
  5. Swap or Exchange Two Numbers Without Using Any Temporary Variable Java Program

You may also like-

  1. Find Duplicate Elements in an Array Java Program
  2. Count Number of Times Each Character Appears in a String Java Program
  3. Check if Given String or Number is a Palindrome Java Program
  4. Polymorphism in Java
  5. Difference Between Abstract Class And Interface in Java
  6. Java Automatic Numeric Type Promotion
  7. Java Pass by Value or Pass by Reference
  8. finally Block in Java Exception Handling

Merge Sort Program in Java

In this post, we’ll explore how to implement a Merge Sort Program in Java. Merge sort is much more efficient than the simple sort algorithms like bubble sort and insertion sort, especially for large datasets. The only trade-off is that it requires an additional array along with the original array that is sorted.

How merge sort works

Merge sort works on the concept of merging two sorted arrays to create another array which is also sorted.

Now the question is how do you get those sorted arrays which are merged?

Merge Sort follows the Divide and Conquer paradigm. The algorithm repeatedly divides the input array into two halves until you get sub-arrays with a single element which is considered a sorted array.

At that point you start merging these sub-arrays, from two single element sub-arrays you create a sorted merged array of two elements. Then two such sorted sub-arrays of two elements are merged to create a sorted array of four elements and so on until you have a sorted array of all the elements.

Since array is recursively divided into two halves so this division process can be written as a recursive method where base case becomes the point when you have sub-arrays with only one element each.

Let’s try to understand with an example where we have an input array as given below.

int[] intArr = {21, 11, 33, 70, 5, 25, 65, 55};

The process of recursive calls to divide the array into halves can be explained using the following image.

merge sort in java

At this point merge process starts which merges two sorted arrays to create another sorted array, this merging process can be explained using the following image.

merge sort program java

Merge Sort Java program

In the merge sort program there is a method mergeSortRecursive which is called recursively to divide the array.

Merge method merges the two sub-arrays to create a sorted array.

public class MergeSort {
  public static void main(String[] args) {
    int[] intArr = {47, 85, 620, 3456, -7, 10, 4500, 106, -345, 1000, 67, 80, 5500, 34, 78, 782, 4, 0, 99, 190};
    MergeSort ms = new MergeSort();
    ms.mergeSortRecursive(intArr, 0, intArr.length-1);
    System.out.println("Sorted array after merge sort- ");
    for(int num : intArr){
      System.out.print(num + " ");
    }
  }
    
  private void mergeSortRecursive(int[] intArr, int lower, int upper){
    //base case
    if (lower == upper){
      return;
    }else{
      // get mid point for division of array
      int middle = (lower + upper)/2;
      
      mergeSortRecursive(intArr, lower, middle);        
      mergeSortRecursive(intArr, middle+1, upper);
      
      merge(intArr, lower, middle, upper);
    }
  }
    
  private void merge(int[] intArr, int lower, int middle, int upper){
      /** Create two temp arrays pertaining to two halves that 
       are being merged and add elements to them  */
      int subArrayOneLength = middle - lower + 1;
      int subArrayTwoLength = upper - middle;
      int[] temp1 = new int[subArrayOneLength];
      int[] temp2 = new int[subArrayTwoLength];
      for(int i = 0; i < subArrayOneLength; i++){
        temp1[i] = intArr[lower + i];
      }
      for(int j = 0; j < subArrayTwoLength; j++){
        temp2[j] = intArr[middle + 1 + j];
      }           
      int i =0;        
      int j = 0;
      // merging process, merge two temp arrays 
      while((i < subArrayOneLength) && (j < subArrayTwoLength)){
        if(temp1[i] < temp2[j]){
          intArr[lower] = temp1[i++];
        }else{
          intArr[lower] = temp2[j++];
        }
        lower++;
      }
      // If there are more elements
      while(i < subArrayOneLength){
        intArr[lower++] = temp1[i++];
      }
      while(j < subArrayTwoLength){
        intArr[lower++] = temp2[j++];
      }
  }
}

Output

Sorted array after merge sort- 
-345 -7 0 4 10 34 47 67 78 80 85 99 106 190 620 782 1000 3456 4500 5500 

Performance of merge sort

In merge sort there is subdivision of arrays and for each sub-division there is merging. Number of levels (subdivisions of array) can be calculated as– (logN + 1)

For example log of 8 base 2 is 3, so log8 + 1 = 4

Which is same as the number of halves for the array having 8 elements– 8 4 2 1.

At each level N elements are merged which makes the time complexity of merge sort as N*(logN + 1). we can discard the 1 so the time complexity of merge sort is O(N*logN).

Merge sort is not an in place sort algorithm as extra space is required. Auxiliary space required is equal to the number of elements in the original array so the space complexity of merge sort is O(N).

That's all for this topic Merge Sort Program in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Shell Sort Program in Java
  2. Radix Sort Program in Java
  3. How to Display Pyramid Patterns in Java - Part1
  4. Arrange Non-Negative Integers to Form Largest Number - Java Program
  5. Find All Permutations of a Given String Java Program

You may also like-

  1. Running Dos/Windows Commands From Java Program
  2. Find Duplicate Elements in an Array Java Program
  3. How to Display Time in AM-PM Format in Java
  4. How to Sort an ArrayList in Descending Order in Java
  5. CopyOnWriteArrayList in Java With Examples
  6. Java Reflection API Tutorial
  7. String in Java Tutorial
  8. NameNode, DataNode And Secondary NameNode in HDFS