Data Model

The autoreload extension is already loaded. To reload it, use:
  %reload_ext autoreload
import pandas as pd
from dataclasses import dataclass
import re
from IPython.display import display_html
def create_db():
    people = [
        {
            "firstname": "John",
            "lastname": "Doe",
            "phone": "555-1234",
            "email": "john.doe@example.com"
        },
        {
            "firstname": "Jane",
            "lastname": "Smith",
            "phone": "555-5678",
            "email": "jane.smith@example.com"
        },
        {
            "firstname": "Alice",
            "lastname": "Johnson",
            "phone": "555-8765",
            "email": "alice.johnson@example.com"
        },
        {
            "firstname": "Bob",
            "lastname": "Williams",
            "phone": "555-4321",
            "email": "bob.williams@example.com"
        },
        {
            "firstname": "Charlie",
            "lastname": "Brown",
            "phone": "555-9876",
            "email": "charlie.brown@example.com"
        },
        {
            "firstname": "Diana",
            "lastname": "Miller",
            "phone": "555-6543",
            "email": "diana.miller@example.com"
        },
        {
            "firstname": "Edward",
            "lastname": "Davis",
            "phone": "555-3456",
            "email": "edward.davis@example.com"
        },
        {
            "firstname": "Fiona",
            "lastname": "Garcia",
            "phone": "555-6789",
            "email": "fiona.garcia@example.com"
        },
        {
            "firstname": "George",
            "lastname": "Martinez",
            "phone": "555-7890",
            "email": "george.martinez@example.com"
        },
        {
            "firstname": "Hannah",
            "lastname": "Rodriguez",
            "phone": "555-8901",
            "email": "hannah.rodriguez@example.com"
        }
    ]

    # Writing the JSON data to a file
    file_path = 'contactdb.json'
    # df = pd.read_json(file_path)
    df = pd.DataFrame()
    df = df.from_dict(people)
    df['id'] = df.index
    df.to_json(file_path, orient='records')
create_db()
db = pd.read_json('contactdb.json')
db.to_dict('records')
[{'firstname': 'John',
  'lastname': 'Doe',
  'phone': '555-1234',
  'email': 'john.doe@example.com',
  'id': 0},
 {'firstname': 'Jane',
  'lastname': 'Smith',
  'phone': '555-5678',
  'email': 'jane.smith@example.com',
  'id': 1},
 {'firstname': 'Alice',
  'lastname': 'Johnson',
  'phone': '555-8765',
  'email': 'alice.johnson@example.com',
  'id': 2},
 {'firstname': 'Bob',
  'lastname': 'Williams',
  'phone': '555-4321',
  'email': 'bob.williams@example.com',
  'id': 3},
 {'firstname': 'Charlie',
  'lastname': 'Brown',
  'phone': '555-9876',
  'email': 'charlie.brown@example.com',
  'id': 4},
 {'firstname': 'Diana',
  'lastname': 'Miller',
  'phone': '555-6543',
  'email': 'diana.miller@example.com',
  'id': 5},
 {'firstname': 'Edward',
  'lastname': 'Davis',
  'phone': '555-3456',
  'email': 'edward.davis@example.com',
  'id': 6},
 {'firstname': 'Fiona',
  'lastname': 'Garcia',
  'phone': '555-6789',
  'email': 'fiona.garcia@example.com',
  'id': 7},
 {'firstname': 'George',
  'lastname': 'Martinez',
  'phone': '555-7890',
  'email': 'george.martinez@example.com',
  'id': 8},
 {'firstname': 'Hannah',
  'lastname': 'Rodriguez',
  'phone': '555-8901',
  'email': 'hannah.rodriguez@example.com',
  'id': 9}]
q = '1234'
# db[db['firstname'].str.lower().str.contains(q)]
predicate_firstname = db['firstname'].str.lower().str.contains(q.lower())
predicate_lastname = db['lastname'].str.lower().str.contains(q.lower())
predicate_phone = db['phone'].str.lower().str.contains(q.lower())
predicate_email= db['email'].str.lower().str.contains(q.lower())
db[predicate_firstname|predicate_lastname|predicate_phone|predicate_email]
firstname lastname phone email id
0 John Doe 555-1234 john.doe@example.com 0
db.columns

a={'firstname': 'Rahul',
   'lastname': 'Saraf',
    'phone':'7347399',
    'email': 'rahuketu86'}
a['id'] = len(db)
# db.loc[len(db)] = 
a
db.loc[len(db), a.keys()] = a.values()
class ContactErrors:
    firstname:str = None
    lastname:str = None
    phone:str = None
    email:str = None
# c = ContactErrors()
# Regular expression pattern for validating email
email_regex = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
phone_regex =  r'^(?:\d{7,}|\d{1,}-\d{1,}-?\d{5,}|\d+-\d{7,}|\d{3}-\d{4})$'
# Function to validate email
def validate_email(email):
    if re.match(email_regex, email): return True
    else: return False
def check_duplicates(elem, ls):
   return elem in ls
# Function to validate phone number
def validate_phone_number(phone_number):
    if re.match(phone_regex, phone_number): return True
    else: return False
# Example usage
phone_numbers = ["555-1234", "917347306788", "7237424", "123-456", "123-456-7890", "123--456", "123-45"]
for number in phone_numbers:
    if validate_phone_number(number):
        print(f"{number}: Valid phone number")
    else:
        print(f"{number}: Invalid phone number")
555-1234: Valid phone number
917347306788: Valid phone number
7237424: Valid phone number
123-456: Invalid phone number
123-456-7890: Invalid phone number
123--456: Invalid phone number
123-45: Invalid phone number
# Example usage
email = "example@example.com"
email = "rahuketu"
if validate_email(email):
    print("Valid email")
else:
    print("Invalid email")
Invalid email
class Contacts(object):
    def __init__(self) -> None:
        self.refresh()

    def search(self, q):
        predicate_firstname = self.db['firstname'].str.lower().str.contains(q.lower())
        predicate_lastname = self.db['lastname'].str.lower().str.contains(q.lower())
        predicate_phone = self.db['phone'].str.lower().str.contains(q.lower())
        predicate_email= self.db['email'].str.lower().str.contains(q.lower())
        filter_df = self.db[predicate_firstname|predicate_lastname|predicate_phone|predicate_email]
        return filter_df.to_dict('records')
    
    def refresh(self):
        self.file_path = 'contactdb.json'
        self.db = pd.read_json(self.file_path)

    def all(self):
        return self.db.to_dict('records')
    
    def get(self, id):
        contact = self.db[self.db['id']==id]
        return contact.to_dict('records')[0]
    

    def add_or_edit(self, id, firstname, lastname, phone, email):
        a={'firstname': firstname,
           'lastname': lastname,
           'phone':phone,
           'email': email,
           'id': id}
        id_idx = None
        # print("id is None" if id is None else "id is ok")
        if id is None: id_idx = self.db['id'].max()+1; a['id'] = id_idx
        else: id_idx = self.db[self.db['id']==id].index
        # print(id_idx)
        self.db.loc[id_idx, a.keys()] = a.values()
        # print(self.db.tail(1))
        self.db.to_json(self.file_path, orient='records')
        self.refresh()

    def delete(self, id):
        id_idx = self.db[self.db['id']==id].index
        self.db.drop(index=id_idx, inplace=True, errors='raise')
        self.db.to_json(self.file_path, orient='records')
        self.refresh()

    def get_emails(self):
        return self.db['email'].tolist()
@dataclass
class Contact:
    firstname:str=None
    lastname:str=None
    phone:str=None
    email:str=None
    id: int =None
    errors:ContactErrors = ContactErrors()
    is_valid:bool=True

    def from_contacts_dict(self, c):
        self.firstname = c['firstname']
        self.lastname = c['lastname']
        self.phone = c['phone']
        self.email = c['email']
        self.id = c['id']
        self.check_valid(duplicate_ok=True)

    def check_valid(self, duplicate_ok=False):
        self.is_valid = True
        if self.firstname is None or self.firstname == "":
            self.is_valid = False
            self.errors.firstname = "Firstname is empty"
        
        if self.lastname is None or self.lastname == "":
            self.is_valid = False
            self.errors.lastname = "Lastname is empty"
        
        if self.phone is None or self.phone == "":
            self.is_valid = False
            self.errors.phone= "Phone is empty"
        elif not validate_phone_number(self.phone):
            self.is_valid = False
            self.errors.phone= "Format phone not correct"
        else: pass

        if self.email is None or self.email == "":
            self.is_valid = False
            self.errors.email= "Email is empty"
        elif not validate_email(self.email):
            self.is_valid = False
            self.errors.email= "Format email not correct"
        elif not duplicate_ok:
            if check_duplicates(self.email, Contacts().get_emails()):
                self.is_valid = False
                self.errors.email= "Duplicated email"
        else: pass

    def commit(self, duplicate_ok=True):
        self.check_valid(duplicate_ok=duplicate_ok)
        if not self.is_valid: return False
        else:
            db = Contacts()
            print("None" if self.id is None else "ok")
            db.add_or_edit(id=self.id,
                    firstname = self.firstname, 
                    lastname = self.lastname, 
                    phone=self.phone, 
                    email=self.email)
            return True

    def __repr__(self) -> str:
        a= [[self.firstname, self.errors.firstname],
            [self.lastname, self.errors.lastname],
            [self.phone, self.errors.phone],
            [self.email, self.errors.email],
            [self.is_valid, ""]]
        return f"Contact{str(a)}"
create_db()
c = Contact(firstname='Rahul', lastname='Saraf', phone='555-1200', email='rahuketu@gmail.com')
c.check_valid(duplicate_ok=False)
c.commit(duplicate_ok=False)
# c.id
None
True
validate_email(c.email)

duplicate_ok=False

check_duplicates(c.email, Contacts().get_emails())
True
Contacts().get_emails()
['john.doe@example.com',
 'jane.smith@example.com',
 'alice.johnson@example.com',
 'bob.williams@example.com',
 'charlie.brown@example.com',
 'diana.miller@example.com',
 'edward.davis@example.com',
 'fiona.garcia@example.com',
 'george.martinez@example.com',
 'hannah.rodriguez@example.com',
 'rahuketu@gmail.com']
Contact()
Contact[[None, None], [None, None], [None, None], [None, None], [True, '']]
c_set = Contacts()
c_dict = c_set.get(0)
c_dict
c = Contact()
c.from_contacts_dict(c_dict)
c.phone = '555-1001'
c.commit()
ok
True
# new_vals = [2, 'Alice', 'Johnson', '555-8767', 'alice.johnson@example.com']
# c.edit(*new_vals)
# c.get(2)
c = Contacts()
a_dict = c.db.loc[0].to_dict(); a_dict
# a_dict.pop('id', None); a_dict
c.delete(0)

c.add_or_edit(*list(a_dict.values()))
c.all()
[{'firstname': 'Jane',
  'lastname': 'Smith',
  'phone': '555-5678',
  'email': 'jane.smith@example.com',
  'id': 1},
 {'firstname': 'Alice',
  'lastname': 'Johnson',
  'phone': '555-8765',
  'email': 'alice.johnson@example.com',
  'id': 2},
 {'firstname': 'Bob',
  'lastname': 'Williams',
  'phone': '555-4321',
  'email': 'bob.williams@example.com',
  'id': 3},
 {'firstname': 'Charlie',
  'lastname': 'Brown',
  'phone': '555-9876',
  'email': 'charlie.brown@example.com',
  'id': 4},
 {'firstname': 'Diana',
  'lastname': 'Miller',
  'phone': '555-6543',
  'email': 'diana.miller@example.com',
  'id': 5},
 {'firstname': 'Edward',
  'lastname': 'Davis',
  'phone': '555-3456',
  'email': 'edward.davis@example.com',
  'id': 6},
 {'firstname': 'Fiona',
  'lastname': 'Garcia',
  'phone': '555-6789',
  'email': 'fiona.garcia@example.com',
  'id': 7},
 {'firstname': 'George',
  'lastname': 'Martinez',
  'phone': '555-7890',
  'email': 'george.martinez@example.com',
  'id': 8},
 {'firstname': 'Hannah',
  'lastname': 'Rodriguez',
  'phone': '555-8901',
  'email': 'hannah.rodriguez@example.com',
  'id': 9},
 {'firstname': 'Rahul',
  'lastname': 'Saraf',
  'phone': '555-1200',
  'email': 'rahuketu@gmail.com',
  'id': 10}]
df = Contacts().db
df = df[df['id']==1].to_dict('records')[0]; df
{'firstname': 'Jane',
 'lastname': 'Smith',
 'phone': '555-5678',
 'email': 'jane.smith@example.com',
 'id': 1}
Contacts().get(2)
{'firstname': 'Alice',
 'lastname': 'Johnson',
 'phone': '555-8765',
 'email': 'alice.johnson@example.com',
 'id': 2}
from nbdev.export import nb_export
nb_export("00_datamodel.ipynb", lib_path=".", name='datamodel')