Communication between processes using Pipe

A pipe can have only two endpoints. Hence, it is preferred over queue when only two-way communication is required.

import multiprocessing


def sender(conn: multiprocessing.connection.Connection, msgs: list):
    """
    function to send messages to other end of pipe
    """
    for msg in msgs:
        conn.send(msg)
        print("Sent the message: {}".format(msg))
    conn.close()


def receiver(conn: multiprocessing.connection.Connection):
    """
    function to print the messages received from other
    end of pipe
    """
    while 1:
        msg = conn.recv()
        if msg == "END":
            break
        print("Received the message: {}".format(msg))


if __name__ == "__main__":
    # messages to be sent
    msgs = ["hello", "hey", "hru?", "END"]

    # creating a pipe
    parent_conn, child_conn = multiprocessing.Pipe()

    # creating new processes
    p1 = multiprocessing.Process(target=sender, args=(parent_conn, msgs))
    p2 = multiprocessing.Process(target=receiver, args=(child_conn,))

    # running processes
    p1.start()
    p2.start()

    # wait until processes finish
    p1.join()
    p2.join()

References
https://www.geeksforgeeks.org/multiprocessing-python-set-2/

Communication between processes using Queue

A simple way to communicate between process with multiprocessing is to use a Queue to pass messages back and forth. Any Python object can pass through a Queue.

import multiprocessing


def square_list(mylist: list, q: multiprocessing.Queue):
    """
    function to square a given list
    """
    # append squares of mylist to queue
    for num in mylist:
        q.put(num * num)


def print_queue(q: multiprocessing.Queue):
    """
    function to print queue elements
    """
    print("Queue elements:")
    while not q.empty():
        print(q.get())
    print("Queue is now empty!")


if __name__ == "__main__":
    # input list
    mylist = [1, 2, 3, 4]

    # creating multiprocessing Queue
    q = multiprocessing.Queue()

    # creating new processes
    p1 = multiprocessing.Process(target=square_list, args=(mylist, q))
    p2 = multiprocessing.Process(target=print_queue, args=(q,))

    # running process p1 to square list
    p1.start()
    p1.join()

    # running process p2 to get queue elements
    p2.start()
    p2.join()

References
https://www.geeksforgeeks.org/multiprocessing-python-set-2/

Sharing data between processes using Shared memory

multiprocessing module provides Array and Value objects to share data between processes.
Array: a ctypes array allocated from shared memory.
Value: a ctypes object allocated from shared memory.

import multiprocessing 

def square_list(mylist, result, square_sum): 
  """ 
  function to square a given list 
  """
  # append squares of mylist to result array 
  for idx, num in enumerate(mylist): 
    result[idx] = num * num 

  # square_sum value 
  square_sum.value = sum(result) 

  # print result Array 
  print("Result(in process p1): {}".format(result[:])) 

  # print square_sum Value 
  print("Sum of squares(in process p1): {}".format(square_sum.value)) 

if __name__ == "__main__": 
  # input list 
  mylist = [1,2,3,4] 

  # creating Array of int data type with space for 4 integers 
  result = multiprocessing.Array('i', 4) 

  # creating Value of int data type 
  square_sum = multiprocessing.Value('i') 

  # creating new process 
  p1 = multiprocessing.Process(target=square_list, args=(mylist, result, square_sum)) 

  # starting process 
  p1.start() 

  # wait until process is finished 
  p1.join() 

  # print result array 
  print("Result(in main program): {}".format(result[:])) 

  # print square_sum Value 
  print("Sum of squares(in main program): {}".format(square_sum.value)) 

References
https://www.geeksforgeeks.org/multiprocessing-python-set-2/

Multiprocessing in Python

import multiprocessing
from multiprocessing.spawn import freeze_support

def print1():
    print("Print1")


def print2(num1):
    print("Print2 : {0}".format(num1))


def print3(num1, num2):
    print("Print3 : {0}, {1}".format(num1, num2))


if __name__ == '__main__':
    # Run code for process object if this in not the main process
    freeze_support()

    # creating processes
    p1 = multiprocessing.Process(target=print1)
    p2 = multiprocessing.Process(target=print2, args=(10,))
    p3 = multiprocessing.Process(target=print3, args=(10, 20,))

    # starting processes
    p1.start()
    p2.start()
    p3.start()

    # wait until processes are finished
    p1.join()
    p2.join()
    p3.join()

References
https://www.geeksforgeeks.org/multiprocessing-python-set-1/
https://stackoverflow.com/questions/8804830/python-multiprocessing-picklingerror-cant-pickle-type-function

Working with QTableWidget on PySide

def createTable(self):
   # Create table
    self.tableWidget = QTableWidget()
    self.tableWidget.setRowCount(4)
    self.tableWidget.setColumnCount(2)
    self.tableWidget.setItem(0,0, QTableWidgetItem("Cell (1,1)"))
    self.tableWidget.setItem(0,1, QTableWidgetItem("Cell (1,2)"))
    self.tableWidget.setItem(1,0, QTableWidgetItem("Cell (2,1)"))
    self.tableWidget.setItem(1,1, QTableWidgetItem("Cell (2,2)"))
    self.tableWidget.setItem(2,0, QTableWidgetItem("Cell (3,1)"))
    self.tableWidget.setItem(2,1, QTableWidgetItem("Cell (3,2)"))
    self.tableWidget.setItem(3,0, QTableWidgetItem("Cell (4,1)"))
    self.tableWidget.setItem(3,1, QTableWidgetItem("Cell (4,2)"))
    self.tableWidget.move(0,0)

    # table selection change
    self.tableWidget.doubleClicked.connect(self.on_click)

@pyqtSlot()
def on_click(self):
    print("\n")
    for currentQTableWidgetItem in self.tableWidget.selectedItems():
        print(currentQTableWidgetItem.row(), currentQTableWidgetItem.column(), currentQTableWidgetItem.text())

References
https://pythonspot.com/pyqt5-table/

Delete Data in Python SQLite

def delete_task(conn, id):
    """
    Delete a task by task id
    :param conn:  Connection to the SQLite database
    :param id: id of the task
    :return:
    """
    sql = 'DELETE FROM tasks WHERE id=?'
    cur = conn.cursor()
    cur.execute(sql, (id,))
    conn.commit()
def delete_all_tasks(conn):
    """
    Delete all rows in the tasks table
    :param conn: Connection to the SQLite database
    :return:
    """
    sql = 'DELETE FROM tasks'
    cur = conn.cursor()
    cur.execute(sql)
    conn.commit()

References
https://www.sqlitetutorial.net/sqlite-python/delete/