<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Package Installation
At the console, within the cs207project directory, you can use
python 
pip install -e .
or equivalently
python
python setup.py install
At this point, four subpackages will be available to you
Step1:  Using the Red-Black Tree
Below is a function that will allow us to visualize our tree (copied from CS207 Fall 2016 lecture notes). 
Next, we create a tree, add a few nodes to it, and retrieve their contents.
Step2:  Multithreadedness
<ASSISTANT_TASK:>
Python Code:
import timeseries, TimeseriesDB, Similarity
import cs207rbtree.RedBlackTree as Database
dir(Database)
Explanation: Package Installation
At the console, within the cs207project directory, you can use
python 
pip install -e .
or equivalently
python
python setup.py install
At this point, four subpackages will be available to you:
1. timeseries
2. TimeseriesDB
3. Similarity
4. cs207rbtree
End of explanation
demoDB = Database.connect("/tmp/test1.dbdb")
demoDB.set("rahul",    81)
demoDB.set("pavlos",   20)
demoDB.set("sarah",    29)
demoDB.set("courtney", 11)
demoDB.set("andrew",   12)
demoDB.set("laura",    81)
demoDB.get("sarah")
demoDB.get("laura")
Explanation: Using the Red-Black Tree
Below is a function that will allow us to visualize our tree (copied from CS207 Fall 2016 lecture notes). 
Next, we create a tree, add a few nodes to it, and retrieve their contents.
End of explanation
from cs207rbtree import RedBlackTree
from threading import Thread
from pytest import raises
import portalocker
import os 
def thread_function(num):
    print("FIRST FUN")
    db = RedBlackTree.connect("/tmp/test6.dbdb")
    db.set("kobe", "baby"+str(num))
    print("1")
    db.set("rahul", "veryyoung"+str(num))
    print("2")
    db.set("pavlos", "stillyoung"+str(num))
    print("3")
    db.set("andy", "old"+str(num))
    print("4")
    db.set("lisa", "ancient"+str(num))   
    print("5")
    db.commit()
    print("6")
def thread_function2():
    db = RedBlackTree.connect("/tmp/test6.dbdb")
    for i in ["kobe","rahul","pavlos","andy","lisa"]:
        print("SECOND FUNC")
        with raises(KeyError):
            print("FAILED")
            print(db.get(i))
   
os.remove('/tmp/test6.dbdb')
t1 = Thread(target=thread_function, args=([1]))
t2 = Thread(target=thread_function2)#, args=(2)) 
t1.start()
t2.start()
print("DONE")
        
import time
def thread_function():
    print("THREAD 1")
    db = RedBlackTree.connect("/tmp/test6.dbdb")
    db.set("Laura", "Ware")
    time.sleep(200)
    print("THREAD ONE DONE SLEEPING")
    db.commit()
    print("COMMITED RESULTS")
    
def thread_function2():
    print("THREAD 2")
    db2 = RedBlackTree.connect("/tmp/test6.dbdb")
    with raises(KeyError):
        print(db2.get('Laura'))
    print("THERE")
    time.sleep(10)
    print("THREAD TWO DONE SLEEPING")
    print(db2.get('Laura'))
    
os.remove('/tmp/test6.dbdb')
#t1 = Thread(target=thread_function)
#t2 = Thread(target=thread_function2)
#t1.start()
#t2.start()
import multiprocessing
p = multiprocessing.Process(target=thread_function) 
p2 = multiprocessing.Process(target=thread_function2) 
p.start()
p2.start()
print("I AM DONE")
#db = RedBlackTree.connect("/tmp/test6.dbdb")
#db.set("Laura", "Ware")
#print("HERE")
#db2 = RedBlackTree.connect("/tmp/test6.dbdb")
#print(db2.get("Laura"))
#print("HERE")
os.remove('/tmp/test6.dbdb')
db = RedBlackTree.connect("/tmp/test6.dbdb")
db.set("Laura", "Ware")
print("HERE")
db2 = RedBlackTree.connect("/tmp/test6.dbdb")
#print("CONNECTED")
with raises(KeyError):
    print(db2.get("Laura"))
db.commit()
print(db2.get("Laura"))
print("HERE")
db.close()
db2.close()
from portalocker.utils import Lock
from portalocker import *
alock = Lock("/tmp/test6.dbdb", timeout=5)
#with assertRaises(Exception): #LockException
    #print("HERE")
alock.acquire()
print("DONE")
from TimeseriesDB.MessageFormatting import *
import importlib
import unittest
from pytest import raises
import numpy as np
from TimeseriesDB.tsdb_error import *
from TimeseriesDB import DatabaseServer
from TimeseriesDB.MessageFormatting import * #Deserializer
from Similarity.find_most_similar import find_most_similiar, sanity_check
from TimeseriesDB.simsearch_init import initialize_simsearch_parameters
from socketserver import BaseRequestHandler, ThreadingTCPServer, TCPServer
from timeseries.ArrayTimeSeries import ArrayTimeSeries as ts
import threading
from socket import socket, AF_INET, SOCK_STREAM
import sys
from scipy.stats import norm
import multiprocessing
def query_1():
    #function to compute simsearch
    print("QUERY1")
    s = socket(AF_INET, SOCK_STREAM)
    s.connect(('localhost', 20000))
    d2 = {'op':'simsearch_id','id':12,'n_closest':2,'courtesy':'please'}
    s2 = serialize(json.dumps(d2))        
    s.send(s2)
    msg = s.recv(8192)
    ds = Deserializer()
    ds.append(msg)
    ds.ready()
    response = ds.deserialize()
    print(response)
    s.close()
    
def query_2():
    #function to return timeseries from id
    print("QUERY2")
    s = socket(AF_INET, SOCK_STREAM)
    s.connect(('localhost', 20000))
    d2 = {'op':'TSfromID','id':12,'courtesy':'please'}
    s2 = serialize(json.dumps(d2))        
    s.send(s2)
    msg = s.recv(8192)
    ds = Deserializer()
    ds.append(msg)
    ds.ready()
    response = ds.deserialize()
    print(response)
    s.close()
TCPServer.allow_reuse_address = True
serv = TCPServer(('', 20000), DatabaseServer)
serv.data = initialize_simsearch_parameters()
serv.deserializer = Deserializer()        
serv_thread = threading.Thread(target=serv.serve_forever)
serv_thread.setDaemon(True)
serv_thread.start()     
p = multiprocessing.Process(target=query_1) 
p2 = multiprocessing.Process(target=query_2) 
p.start()
p2.start()    
serv.socket.close()
serv.server_close()
print("DONE")
Explanation: Multithreadedness
End of explanation
<END_TASK>