Skip to content

Commit 471bea6

Browse files
author
=
committed
Adds FlaskAPI
1 parent e450375 commit 471bea6

File tree

11 files changed

+841
-2
lines changed

11 files changed

+841
-2
lines changed

FlaskAPI/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# FlaskAPI
2+
3+
## Data Structure for Python developers
4+
5+
Working with **Data Structures** by making a **FlaskAPI**
6+
7+
### Run
8+
9+
+ ```sh
10+
pip install -r requirements.txt
11+
```
12+
13+
+ ```sh
14+
python server.py
15+
```
16+
17+
+ Run Postman to verify API calls
18+
19+
---
20+
21+
## Thanks to
22+
23+
[freeCodeCamp](https://www.freecodecamp.org)
24+
25+
### Author
26+
27+
Kumar Shanu

FlaskAPI/binary_search_tree.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
class Node:
2+
def __init__(self, data=None) -> None:
3+
"""Node to store data
4+
5+
Args:
6+
data (Any, optional): Data to be added. Defaults to None.
7+
"""
8+
self.data = data
9+
self.left = None
10+
self.right = None
11+
12+
13+
class BinarySearchTree:
14+
def __init__(self) -> None:
15+
"""BinarySearch Tree Data Structure"""
16+
self.root = None
17+
18+
def _insert_recursive(self, data, node):
19+
if data["id"] < node.data["id"]:
20+
if node.left is None:
21+
node.left = Node(data)
22+
else:
23+
self._insert_recursive(data, node.left)
24+
elif data["id"] > node.data["id"]:
25+
if node.right is None:
26+
node.right = Node(data)
27+
else:
28+
self._insert_recursive(data, node.right)
29+
else:
30+
return
31+
32+
def insert(self, data):
33+
"""Insert data in `BinarySearchTree`
34+
35+
Args:
36+
data (Any): Data to be added
37+
38+
Example:
39+
>>> bst = BinarySearchTree()
40+
>>> bst.insert({"id" : 1})
41+
>>> bst.insert({"id" : 3})
42+
>>> bst.insert({"id" : 2})
43+
>>> bst.root.data
44+
{'id': 1}
45+
"""
46+
if self.root is None:
47+
self.root = Node(data)
48+
else:
49+
self._insert_recursive(data, self.root)
50+
51+
def _search_recursive(self, blog_post_id, node):
52+
if node.left == None and node.right == None:
53+
return False
54+
if blog_post_id == node.data["id"]:
55+
return node.data
56+
57+
if blog_post_id < node.data["id"] and node.left is not None:
58+
if blog_post_id == node.left.data["id"]:
59+
return node.left.data
60+
return self._search_recursive(blog_post_id, node.left)
61+
62+
if blog_post_id > node.data["id"] and node.right is not None:
63+
if blog_post_id == node.right.data["id"]:
64+
return node.right.data
65+
return self._search_recursive(blog_post_id, node.right)
66+
return False
67+
68+
def search(self, blog_post_id):
69+
"""Search data in `BinarySearchTree`
70+
71+
Args:
72+
blog_post_id (int): id to search
73+
74+
Returns:
75+
Any: searched data
76+
77+
Example:
78+
>>> bst = BinarySearchTree()
79+
>>> bst.insert({"id" : 1})
80+
>>> bst.insert({"id" : 3})
81+
>>> bst.insert({"id" : 2})
82+
>>> bst.search(3)
83+
{'id': 3}
84+
>>> bst.search(4)
85+
False
86+
"""
87+
blog_post_id = int(blog_post_id)
88+
if self.root is None:
89+
return False
90+
return self._search_recursive(blog_post_id, self.root)

FlaskAPI/custom_q.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
class Node:
2+
def __init__(self, data=None, next_node=None) -> None:
3+
self.data = data
4+
self.next_node = next_node
5+
6+
7+
class Queue:
8+
def __init__(self) -> None:
9+
"""Queue Data Structure"""
10+
self.head = None
11+
self.tail = None
12+
13+
def enqueue(self, data):
14+
"""Insert data into `Queue`
15+
16+
Args:
17+
data (Any): data to be inserted
18+
19+
Example:
20+
>>> q = Queue()
21+
>>> q.enqueue(1)
22+
>>> q.enqueue(2)
23+
>>> q.head.data
24+
1
25+
>>> q.tail.data
26+
2
27+
"""
28+
if self.tail is None and self.head is None:
29+
self.tail = self.head = Node(data, None)
30+
return
31+
self.tail.next_node = Node(data, None)
32+
self.tail = self.tail.next_node
33+
return
34+
35+
def dequeue(self):
36+
"""remove data from `Queue`
37+
38+
Returns:
39+
Any: Queue data
40+
41+
Example:
42+
>>> q = Queue()
43+
>>> q.enqueue(1)
44+
>>> q.enqueue(2)
45+
>>> q.dequeue().data
46+
1
47+
"""
48+
if self.head is None:
49+
return None
50+
removed = self.head
51+
self.head = self.head.next_node
52+
if self.head is None:
53+
self.tail = None
54+
return removed

FlaskAPI/generate_dummy_data.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
2+
from datetime import datetime
3+
from random import randrange
4+
from sqlite3 import Connection as SQLite3Connection
5+
6+
from faker import Faker
7+
from flask import Flask
8+
from flask_sqlalchemy import SQLAlchemy
9+
from sqlalchemy import event
10+
from sqlalchemy.engine import Engine
11+
12+
import server
13+
14+
# app
15+
app = Flask(__name__)
16+
17+
# config
18+
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///sqlitedb.file"
19+
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = 0
20+
21+
# configure sqlite3 to enforce foreign key contraints
22+
23+
24+
@event.listens_for(Engine, "connect")
25+
def _set_sqlite_pragma(dbapi_connection, connection_record):
26+
if isinstance(dbapi_connection, SQLite3Connection):
27+
cursor = dbapi_connection.cursor()
28+
cursor.execute("PRAGMA foreign_keys=ON;")
29+
cursor.close()
30+
31+
32+
db = SQLAlchemy(app)
33+
now = datetime.now()
34+
35+
faker = Faker()
36+
37+
# create dummy users
38+
for i in range(200):
39+
name = faker.name()
40+
address = faker.address()
41+
phone = faker.msisdn()
42+
email = f'{name.replace(" ", "_")}@email.com'
43+
new_user = server.User(name=name, address=address,
44+
phone=phone, email=email)
45+
db.session.add(new_user)
46+
db.session.commit()
47+
48+
# create dummy blog posts
49+
for i in range(200):
50+
title = faker.sentence(5)
51+
body = faker.paragraph(190)
52+
date = faker.date_time()
53+
user_id = randrange(1, 200)
54+
55+
new_blog_post = server.BlogPost(
56+
title=title, body=body, date=date, user_id=user_id
57+
)
58+
db.session.add(new_blog_post)
59+
db.session.commit()

FlaskAPI/hash_table.py

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
class Node:
2+
"""Node to store data"""
3+
4+
def __init__(self, data=None, next_node=None) -> None:
5+
"""create a Node datatype
6+
7+
Args:
8+
data ([type], optional): data to store. Defaults to None.
9+
next_node ([type], optional): pointer to next Node. Defaults to None.
10+
11+
Example:
12+
>>> node = Node("data", None)
13+
>>> node.data
14+
'data'
15+
>>> print(node.next_node)
16+
None
17+
"""
18+
self.data = data
19+
self.next_node = next_node
20+
21+
22+
class Data:
23+
"""Store data as key, value pair"""
24+
25+
def __init__(self, key, value) -> None:
26+
"""Store data as key, value pair
27+
28+
Args:
29+
key ([type]): key
30+
value ([type]): value
31+
32+
Example:
33+
>>> d = Data("key", "val")
34+
>>> d.key
35+
'key'
36+
>>> d.value
37+
'val'
38+
"""
39+
self.key = key
40+
self.value = value
41+
42+
43+
class HashTable:
44+
"""Hash Table to store data as key,value pairs"""
45+
46+
def __init__(self, table_size) -> None:
47+
"""Hashtable
48+
49+
Args:
50+
table_size (int): size of the table
51+
52+
Example:
53+
>>> ht = HashTable(10)
54+
>>> ht.hash_table
55+
[None, None, None, None, None, None, None, None, None, None]
56+
"""
57+
self.table_size = table_size
58+
self.hash_table = [None] * table_size
59+
60+
def custom_hash(self, key):
61+
"""calculate hash for the given key (hash_function)
62+
63+
Args:
64+
key ([type]): given key
65+
66+
Returns:
67+
[type]: hashed key
68+
69+
Example:
70+
>>> ht = HashTable(5)
71+
>>> ht.custom_hash('key')
72+
1
73+
"""
74+
hash_value = 0
75+
for i in key:
76+
hash_value += ord(i)
77+
hash_value = (hash_value * ord(i)) % self.table_size
78+
return hash_value
79+
80+
def add_key_value(self, key, value):
81+
"""Adds key,value pair into `HashTable`
82+
83+
Args:
84+
key ([type]): key to store
85+
value ([type]): value to store
86+
"""
87+
hashed_key = self.custom_hash(key)
88+
if self.hash_table[hashed_key] is None:
89+
self.hash_table[hashed_key] = Node(Data(key, value), None)
90+
else:
91+
node = self.hash_table[hashed_key]
92+
while node.next_node:
93+
node = node.next_node
94+
node.next_node = Node(Data(key, value), None)
95+
96+
def get_value(self, key):
97+
"""Get value corresponde to the given `key`
98+
99+
Args:
100+
key ([type]): given key
101+
102+
Returns:
103+
Any: value for the given key
104+
"""
105+
hashed_key = self.custom_hash(key)
106+
if self.hash_table[hashed_key] is not None:
107+
node = self.hash_table[hashed_key]
108+
if node.next_node is None:
109+
return node.data.value
110+
while node.next_node:
111+
if key == node.data.key:
112+
return node.data.value
113+
node = node.next_node
114+
115+
if key == node.data.key:
116+
return node.data.value
117+
118+
return None
119+
120+
def print_table(self):
121+
"""Prints the whole `HashTable`"""
122+
print("{")
123+
for i, val in enumerate(self.hash_table):
124+
if val is not None:
125+
llist_string = ""
126+
node = val
127+
if node.next_node:
128+
while node.next_node:
129+
llist_string += (
130+
str(node.data.key) + " : " +
131+
str(node.data.value) + " --> "
132+
)
133+
node = node.next_node
134+
llist_string += (
135+
str(node.data.key) + " : " +
136+
str(node.data.value) + " --> "
137+
)
138+
print(f" [{i}] {llist_string}")
139+
else:
140+
print(f" [{i}] {val.data.key} : {val.data.value}")
141+
else:
142+
print(f" [{i}] {val}")
143+
print("}")
144+
145+
146+
if __name__ == "__main__":
147+
ht = HashTable(4)
148+
ht.add_key_value("hi", "there")
149+
ht.add_key_value("hii", "there")
150+
ht.add_key_value("hi", "there")
151+
ht.add_key_value("heyy", "there")
152+
ht.print_table()

0 commit comments

Comments
 (0)