Thursday, November 23, 2023

A baby step in the wonderland of Quantum Computing...

I am of the opinion that there is no age limit for trying out new things in life.

I consider myself a perpetual student.

Today will be a memorable day for me.

I have started my journey into the world of Quantum Computing.

From almost no knowledge in college (even didn't know how to start the Basic development environment) to taking concrete steps to pick up Quantum Computing - it's a checkered journey - a lot of midnight oil is burnt - a lot of frustration, many times it became unbearable, traveled many places - but one thing always drove me - the intrinsic motivation - never did anything just for monetary gain - remained a perpetual student. I started my software journey when there was no Google. it was naturally challenging. but worth the effort...

So, here we go - my first coding in the area of Quantum Programming.

#Python libraries required for various operations
import numpy as np

#Qiskit packages used for building a quantum circuit
from qiskit import QuantumRegister, ClassicalRegister
from qiskit import QuantumCircuit

#Qiskit packages used to execute and simulate the quantum circuit
from qiskit import execute, Aer

#Qiskit packages used to visualize and analyze results
from qiskit.visualization import plot_histogram

#Create quantum register to store qubit
qreg_q = QuantumRegister(1, 'q')

#Create classical register to store the results
creg_c = ClassicalRegister(1, 'c')

#Initialize quantum circuit
circuit = QuantumCircuit(qreg_q, creg_c)

#Initialize all qubits to |0>
circuit.reset(qreg_q)

#Apply the Hadamard gate on the qubit
circuit.h(qreg_q)

#Apply measurement
circuit.measure(qreg_q, creg_c)

#Visualize the constructed circuit
circuit.draw()

# Use Aer's qasm_simulator
simulator = Aer.get_backend('qasm_simulator')

# Execute the circuit on the qasm simulator
job = execute(circuit, simulator, shots=1000)

# Grab results from the job
result = job.result()

# Returns counts
counts = result.get_counts(circuit)
print("\n Output counts:",counts)

# Plot a histogram
plot_histogram(counts)


Here is the output

Output counts: {'1': 464, '0': 536}


And here goes another simple program of a basic entangler.

Enjoy...

#Python libraries required for various operations
import numpy as np

#Qiskit packages used for building a quantum circuit
from qiskit import QuantumRegister, ClassicalRegister
from qiskit import QuantumCircuit

#Qiskit packages used to execute and simulate the quantum circuit
from qiskit import execute, Aer


#Qiskit packages used to visualize and analyze results
from qiskit.visualization import plot_histogram

qreg_q = QuantumRegister(2, 'q')
creg_c = ClassicalRegister(2, 'c')
circuit = QuantumCircuit(qreg_q, creg_c)

circuit.reset(qreg_q[0])
circuit.reset(qreg_q[1])
circuit.h(qreg_q[0])
circuit.cx(qreg_q[0], qreg_q[1])
circuit.measure(qreg_q[0], creg_c[0])
circuit.measure(qreg_q[1], creg_c[1])

#Visualize the constructed circuit
circuit.draw()

# Use Aer's qasm_simulator
simulator = Aer.get_backend('qasm_simulator')

# Execute the circuit on the qasm simulator
job = execute(circuit, simulator, shots=1000)

# Grab results from the job
result = job.result()

# Returns counts
counts = result.get_counts(circuit)
print("\n Output counts:",counts)

# Plot a histogram
plot_histogram(counts)

Here goes the output of the above piece of code

Output counts: {'00': 489, '11': 511}

To start something absolutely new is challenging yet satisfying. I am always motivated by intrinsic motivation. Hence the joy of learning is still there in me, a perpetual student…

Thursday, November 16, 2023

Engineers of Bharat - wakeup - know WhoWeAre - part II

 Here's the clarion call to all of the engineers of Bharat - embrace #Sanskrit and go back to your roots. Know your real worth.

Till to date, scientists are baffled at how the Tithis are so accurately calculated in ancient Bharat.

Read the following article.

Our Vedas were written more than 15000 years ago.

Isn't it amazing?

We were invaded by Muslims and then the British - but our only defeat has become true when an inferiority complex was injected into us.

Come ON... the Humans of Bharat...

please ... 

wake up and reclaim who you are...

Read... Read...



And see how modern scientists are struggling to calculate the Tithis given in Panjika of Bharat.
 


Through this write-up, I am requesting the Government of Bharat to embrace Sanskrit and our ancient knowledge and become a real Vishwaguru - the original, pure, unpolluted.

Reclaiming WhoWeAre...

So, the Humans of Bharat...

please wake up...

Read.... Read...

Saturday, September 2, 2023

Iterator Design Pattern in Python...

Iterator design pattern is a behavioral design pattern that lets you access the element of a complex data structure - a collection class - without the knowledge of the internal structure of the elements it is accessing.

To create an iterator in Python, there are two abstract classes from the built-in `collections` module - Iterable, and Iterator. We need to implement the

`__iter__()` method in the iterated object (collection), and the `__next__ ()` method in the iterator.

The concrete class that implements the Iterator class provides various means of different ways of iteration through the collection class.

In our example, AlphabeticalOrderIterator is such a class that has provided forward and reverse ways of iteration. In this example, the WordsCollection class represents a collection of words and implements the Iterable interface.

The source code is as follows:

from collections.abc import Iterator, Iterable
from typing import Any, List

class WordsCollection(Iterable):
def __init__(self, collection: List[Any]=[]):
self._collection = collection

def __iter__(self):
return AlphabeticalOrderIterator(self._collection)

def get_reverse_iterator(self):
return AlphabeticalOrderIterator(self._collection, True)

def add_item(self, item:Any):
self._collection.append(item)

class AlphabeticalOrderIterator(Iterator):
_position = None
_reverse = False

def __init__(self, collection : WordsCollection, reverse: bool = False):
self._collection = collection
self._reverse = reverse
self._position = -1 if self._reverse else 0

def __next__(self):
try:
value = self._collection[self._position]
self._position += -1 if self._reverse else 1
except IndexError:
raise StopIteration()

return value


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
wordsCollection = WordsCollection()
wordsCollection.add_item("Som")
wordsCollection.add_item("Reema")
wordsCollection.add_item("Ridit")

print("Forward traversal:")
print("\n".join(wordsCollection))
print("")

print("Reverse traversal:")
print("\n".join(wordsCollection.get_reverse_iterator()), end="")

If we run the above program the output will be as follows:

Forward traversal:

Som

Reema

Ridit


Reverse traversal:

Ridit

Reema

Som

 

Friday, September 1, 2023

Prototype Design Pattern in Python...

The prototype design pattern is a creational pattern.

If the creation of an object is a very costly affair and we already have a similar kind of object, instead of creating it each time we need it, we use the clone of the object that is already there.

Suppose, there is a large object with many attributes whose data we read from a database. We need to modify that data multiple times in our program. So instead of creating the object each time by reading from the database, we tend to keep a prototype object - we clone it, and then work on it.

In Python, there is a module called copy which has two methods - copy() and deepcopy(). The first one is for the shallow copy and the second one is for the deepcopy.

Here is the source code of an example of the Prototype design pattern.

from abc import ABC, abstractmethod
import copy

class Person(ABC):
def __init__(self, name):
self._name = name
def set_name(self, name):
self._name = name
def get_name(self):
return self._name
@abstractmethod
def clone(self):
pass
@abstractmethod
def display(self):
pass

class Teacher(Person):
def __init__(self, name, course):
super().__init__(name)
self._course = course
def set_course(self, course):
self._course = course
def get_course(self):
return self._course
def display(self):
print("\nTeacher's name : ", self._name, "\n")
print("\nHe teaches : ", self.get_course())

def clone(self):
return copy.deepcopy(self)

class Student(Person):
def __init__(self, name, teacher):
super().__init__(name)
self._teacher = teacher

def display(self):
print("\n Student's name : ", self.get_name())
print("\n Taught by : ", self._teacher.get_name())
print("\n Enrolled in the subject : ", self._teacher.get_course())

def clone(self):
return copy.deepcopy(self)



if __name__ == '__main__':
teacher = Teacher('Som', "Python Design Patttern")
teacherClone1 = teacher.clone()

student = Student ("Ridit", teacherClone1)

studentClone1 = student.clone()

teacherClone1.set_course("DSA")

teacherClone1.display()

studentClone1.display()



If we run the above piece of code the result will be as follows:

Teacher's name :  Som 

He teaches :  Python Design Patttern

Teacher's name :  Som 

He teaches :  DSA

Student's name :  Ridit

Taught by :  Som

Enrolled in the subject :   Python Design Patttern


As you can see, we have used deep copy here.

Sunday, August 27, 2023

Decorator Design Pattern in Python

In object-oriented programming, the decorator pattern is a design pattern that allows behavior to be added to an individual object, dynamically, without affecting the behavior of other objects from the same class.

What problems can it solve?

- Responsibilities should be added to (and removed from) an object dynamically at run-time

- A flexible alternative to subclassing for extending functionality should be provided.

The UML diagram of the example is given below:



When using subclassing, different subclasses extend a class in different ways. But an extension is bound to the class at compile-time and can't be changed at run-time.

The decorator pattern can be used to extend (decorate) the functionality of a certain object statically, or in some cases at run-time, independently of other instances of the same class.

This is achieved by designing a new Decorator class that wraps the original class. This wrapping could be achieved by the following sequence of steps:

Subclass the original Component class into a Decorator class (see UML diagram);

- In the Decorator class (SpecialistTeacher), add a Component reference as an attribute;

- In the Decorator class, pass a Component to the Decorator constructor to initialize the Component attribute;

- In the Decorator class, forward all Component methods to the Component pointer; and

- In the ConcreteDecorator class (specialistMathTeacher, specialistChemistryTeacher, etc), override any Component method(s) whose behavior needs to be modified.

This pattern is designed so that multiple decorators can be stacked on top of each other, each time adding a new functionality to the overridden method(s).

Note that decorators and the original class object share a common set of features. In the UML diagram, the doWork() and calculateSalary() methods were available in both the decorated and undecorated versions.

Here is the source code of the Decorator Design Pattern in Python:

from abc import ABC, abstractmethod

class Teacher(ABC):
@abstractmethod
def calculateSalary(self):
pass
def doWork(self):
pass

class BasicTeacher(Teacher):
def __init__(self, baseSalaryForATeacher):
self.baseSalaryForTeacher = baseSalaryForATeacher

def calculateSalary(self):
return self.baseSalaryForTeacher
def doWork(self):
pass

##Decorator
class SpecialistTeacher(Teacher):
def __init__(self, teacher):
self.teacher = teacher

def calculateSalary(self):
self.specialistTeacherBaseSalary = self.teacher.calculateSalary()
return self.specialistTeacherBaseSalary
def doWork(self):
super().doWork()
self.teacher.doWork()

class SpecialistPhysicsTeacher(SpecialistTeacher):
def __init__(self, specialistTeacher):
super().__init__(specialistTeacher)

def calculateSalary(self):
return super().calculateSalary() + 8000

def doWork(self):
super().doWork()
print("\n I am a specialist Physics Teacher. I teach Physics")


class SpecialistMathsTeacher(SpecialistTeacher):
def __init__(self, specialistTeacher):
super().__init__(specialistTeacher)

def calculateSalary(self):
return super().calculateSalary() + 10000

def doWork(self):
super().doWork()
print("\n I am a specialist Maths Teacher. I teach Maths")


class SpecialistChemistryTeacher(SpecialistTeacher):
def __init__(self, specialistTeacher):
super().__init__(specialistTeacher)

def calculateSalary(self):
return super().calculateSalary() + 7000

def doWork(self):
super().doWork()
print("\n I am a specialist Chemistry Teacher. I teach Chemistry")

# Press the green button in the gutter to run the script.
if __name__ == '__main__':
specialistPhyTeacher = SpecialistPhysicsTeacher(SpecialistTeacher(BasicTeacher(10000)))

specialistPhyTeacher.doWork()

print("\n My Salary is ", specialistPhyTeacher.calculateSalary())

specialistphymathsTeacher = SpecialistMathsTeacher(SpecialistPhysicsTeacher
                                          (SpecialistTeacher(BasicTeacher(10000))))

specialistphymathsTeacher.doWork()

print("\n My Salary is ", specialistphymathsTeacher.calculateSalary())

If we run the above program, the output will look like the following:


I am a specialist Physics Teacher. I teach Physics


My Salary is  18000


 I am a specialist Physics Teacher. I teach Physics


 I am a specialist Maths Teacher. I teach Maths


 My Salary is  28000


Friday, August 25, 2023

The Template Method Design Pattern...

 It is a behavioral design pattern. It lets us define the skeleton of an algorithm, delegating some steps to the subclasses.

There are mainly two participants in this design pattern

- AbstractClass : It defines the abstract primitive methods that the subclasses will override. It also implements a template method which define the algorithm.

- ConcreteClass : it implements the abstract primitive methods of the Abstract Class.

Let us try to understand this design pattern from an example.

Suppose we are modeling the daily activity of an engineering student in college.

All students need to sign in and sign out in a common register. So these common tasks are part of the Base class.

However, each student has to attend the classes of his own stream - maybe Electronics, Computer Science, Mechanicals, etc.

So this part of the basic activity depends on the stream of the student and constitutes part of the Concrete class.

The UML diagram of the code is as follows:



Here is the source code of the Template Method Design Pattern

from abc import ABC, abstractmethod

class EngineeringStudent(ABC):
def __init__(self):
pass
def signIn(self):
print("\n Start of the day. I need to sign in the common register")
def signOut(self):
print("\n End of the day. I need to sign out in the common register")
@abstractmethod
def attendClass(self):
pass
def activityofAStudent(self):
self.signIn()
self.attendClass()
self.signOut()

class ElectronicsStudent(EngineeringStudent):

def __init__(self):
print("\n I am an Electronics Student")

def attendClass(self):
print("\n Attend the classes in the Electronics dept")

class ComputerScienceStudent(EngineeringStudent):
def __init__(self):
print("\n I am a CS Student")
def attendClass(self):
print("\n Attend the classes in the CS dept")


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
electronicsStudent = ElectronicsStudent()
electronicsStudent.activityofAStudent()
csStudent = ComputerScienceStudent()
csStudent.activityofAStudent()

# See PyCharm help at https://www.jetbrains.com/help/pycharm/

If we run the above program, the output will be as follows:


 I am an Electronics Student


 Start of the day. I need to  sign in the common register


 Attend the classes in the Electronics dept


 End of the day. I need to sign out in the common register


 I am a CS Student


 Start of the day. I need to  sign in the common register


 Attend the classes in the CS dept


 End of the day. I need to sign out in the common register


Thursday, August 24, 2023

Memento Design Pattern in Python...

This design pattern lets you save the state of an object without revealing the implementation.

There are mainly three participants in this design pattern

- Memento: stores the internal state of the Originator object. How much state of the Originator the memento will store completely depends upon the Originator

- Originator: It creates a memento containing a snapshot of its current internal state. It also uses the Memento to restore the Original state

Caretaker: It's responsible for the memento's safekeeping.

The memento design pattern helps to implement Undo facilities for any application. Think about a word processor app - at any point in time we can undo and get back the earlier state of the document - here lies the greatness of the memento design pattern.

The UML class diagram of the Memento pattern looks like the following:




The source code for the Memento Design Pattern is as follows:

cclass Originator:
    _state = ""

def set(self, state):
print(f"Originator: Setting state to {state}")
self._state = state

def save_to_memento(self):
return self.Memento(self._state)

def restore_from_memento(self, m) :
self._state = m.get_saved_state()
print(f"Originator: State after restoring from Memento: {self._state}")

class Memento:

def __init__(self, state):
self._state = state

def get_saved_state(self):
return self._state

class Caretaker:
def __init__(self, originator):
self.originator = originator
self.saved_states = []

def saveState(self):
self.saved_states.append(self.originator.save_to_memento())

def undo(self):
if not len(self.saved_states):
return
self.originator.restore_from_memento(self.saved_states.pop())

# Press the green button in the gutter to run the script.
if __name__ == '__main__':
originator = Originator()
caretaker = Caretaker(originator)
originator.set("State1")
caretaker.saveState()
originator.set('State2')
caretaker.saveState()

originator.set("State3")
caretaker.saveState()

originator.set("State4")
caretaker.saveState()
print("\nClient: Now, let's rollback!\n")
caretaker.undo()
print("\nClient: Once more!\n")
caretaker.undo()

If we run the above lines of code, the output will be:


Originator: Setting state to State1
Originator: Setting state to State2
Originator: Setting state to State3
Originator: Setting state to State4

Client: Now, let's rollback!

Originator: State after restoring from Memento: State4

Client: Once more!

Originator: State after restoring from Memento: State3