diff --git a/frontend/pages/user.vue b/frontend/pages/user.vue
index 10ae89e..1229240 100644
--- a/frontend/pages/user.vue
+++ b/frontend/pages/user.vue
@@ -99,6 +99,8 @@ watch(extendedUserInformation, () => {
}
})
+const toast = useToast()
+
const department = ref('')
const funfact = ref('')
const userInterests = ref
({})
@@ -136,5 +138,9 @@ const saveChanges = async () => {
team: department.value,
days: selectedDays.value
});
+
+ toast.add({title: 'Informations Saved!', icon: 'i-heroicons-check-circle'})
+
+ navigateTo('/')
};
diff --git a/frontend/public/justlogo.svg b/frontend/public/justlogo.svg
new file mode 100644
index 0000000..b38c08a
--- /dev/null
+++ b/frontend/public/justlogo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/functions/main.py b/functions/main.py
index 9443d2a..a66e9cc 100644
--- a/functions/main.py
+++ b/functions/main.py
@@ -5,6 +5,7 @@
from firebase_functions import https_fn
from firebase_admin import initialize_app
from firebase_admin import firestore
+from firebase_admin import auth
from datetime import date
from data import User, Match
from notification import notify_user_about_match, POSTMARK_API_KEY
@@ -14,12 +15,20 @@
default_app = initialize_app()
+def user_exists(uid: str):
+ try:
+ auth.get_user(uid)
+ return True
+ except:
+ print("User with ID " + uid + " does not exist")
+ return False
+
def get_all_users():
db = firestore.client()
docs = (
db.collection("users")
.stream())
- return [ User(doc.id, doc.to_dict()) for doc in docs ]
+ return [ User(doc.id, doc.to_dict()) for doc in docs if user_exists(doc.id) ]
def match_users(users: list[User]):
# this is the entrypoint for your matching code
@@ -59,7 +68,7 @@ def trigger_matching(req: https_fn.Request) -> https_fn.Response:
"id": match.user2.id,
"name": match.user2.name,
"email": match.user2.email,
- "avatarUrl": match.user1.avatarUrl or f"https://source.boringavatars.com/beam/120/{match.user2.id}?colors=264653,2a9d8f,e9c46a,f4a261,e76f51"
+ "avatarUrl": match.user2.avatarUrl or f"https://source.boringavatars.com/beam/120/{match.user2.id}?colors=264653,2a9d8f,e9c46a,f4a261,e76f51"
}
],
"date": match.date.isoformat()
@@ -78,3 +87,5 @@ def add_fake_users(req: https_fn.Request) -> https_fn.Response:
print("Adding fake users")
add_fake_firestore_users(4)
return https_fn.Response("Added 10 fake users")
+
+
diff --git a/functions/matching_users.py b/functions/matching_users.py
index f0e03cb..96f3c92 100644
--- a/functions/matching_users.py
+++ b/functions/matching_users.py
@@ -5,7 +5,7 @@
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
import collections
-from functions.data import User
+from data import User
def get_sorted_list_func(user_ids, user_preferences):
def get_sorted_list(user_index):
@@ -21,10 +21,22 @@ def check_input(user_ids, preference_matrix):
if len(user_ids) != len(preference_matrix):
raise ValueError(f"user list and matrix length do not match")
+def add_noise_to_array(arr, noise_factor):
+ if not 0 <= noise_factor <= 1:
+ raise ValueError("Noise factor should be between 0 and 1")
+ elif noise_factor == 0:
+ return arr
+ noise = np.random.uniform(0, noise_factor, arr.shape)
+ noisy_array = arr + noise
+ noisy_array = np.clip(noisy_array, 0, 1)
+ return noisy_array
+
def get_preference_lists(user_ids, preference_matrix):
check_input(user_ids, preference_matrix)
user_preferences = cosine_similarity(preference_matrix)
+ user_preferences = add_noise_to_array(user_preferences, 0) # ADJUST NOISE HERE
+
get_sorted_list = get_sorted_list_func(user_ids, user_preferences)
return [get_sorted_list(user_index) for user_index in range(len(user_ids))]
diff --git a/functions/notification.py b/functions/notification.py
index 925ab0d..9089188 100644
--- a/functions/notification.py
+++ b/functions/notification.py
@@ -23,14 +23,14 @@ def send_email_to_user(user: User, matchedWith: User):
else:
postmark = PostmarkClient(server_token=POSTMARK_API_KEY.value)
postmark.emails.send_with_template(
- From='alex@rovner.ch',
+ From='noreply@meetingmunch.com',
To=user_email,
TemplateId="33637852",
TemplateModel={
"name": user.name,
- "action_url": "https://baselhack2023-randoms.web.app/",
+ "action_url": "https://meetingmunch.com/",
"matched_with": matchedWith.name,
- "help_url": "https://baselhack2023-randoms.web.app/",
+ "help_url": "https://meetingmunch.com/",
"product_name": "MeetingMunch"
}
)
diff --git a/notebooks/playground.ipynb b/notebooks/playground.ipynb
index c7c52d2..8eaae82 100644
--- a/notebooks/playground.ipynb
+++ b/notebooks/playground.ipynb
@@ -124,8 +124,8 @@
"Requirement already satisfied: numpy>=1.17.3 in /home/noverney/miniconda3/lib/python3.10/site-packages (from scikit-learn) (1.23.5)\n",
"Collecting faker\n",
" Downloading Faker-19.12.0-py3-none-any.whl (1.7 MB)\n",
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.7/1.7 MB\u001b[0m \u001b[31m3.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n",
- "\u001b[?25hRequirement already satisfied: python-dateutil>=2.4 in /home/noverney/miniconda3/lib/python3.10/site-packages (from faker) (2.8.2)\n",
+ "\u001B[2K \u001B[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001B[0m \u001B[32m1.7/1.7 MB\u001B[0m \u001B[31m3.0 MB/s\u001B[0m eta \u001B[36m0:00:00\u001B[0m00:01\u001B[0m00:01\u001B[0m\n",
+ "\u001B[?25hRequirement already satisfied: python-dateutil>=2.4 in /home/noverney/miniconda3/lib/python3.10/site-packages (from faker) (2.8.2)\n",
"Requirement already satisfied: six>=1.5 in /home/noverney/miniconda3/lib/python3.10/site-packages (from python-dateutil>=2.4->faker) (1.16.0)\n",
"Installing collected packages: faker\n",
"Successfully installed faker-19.12.0\n"
diff --git a/notebooks/playground_roy.ipynb b/notebooks/playground_roy.ipynb
index 816f519..0e43ad9 100644
--- a/notebooks/playground_roy.ipynb
+++ b/notebooks/playground_roy.ipynb
@@ -2,13 +2,13 @@
"cells": [
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": 10,
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
- "end_time": "2023-10-29T09:57:19.110211910Z",
- "start_time": "2023-10-29T09:57:17.587060842Z"
+ "end_time": "2023-10-29T13:00:30.776457436Z",
+ "start_time": "2023-10-29T13:00:30.624446824Z"
}
},
"outputs": [],
@@ -23,13 +23,13 @@
},
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": 10,
"id": "3b50d41a9f16ce5b",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T09:57:19.112294698Z",
- "start_time": "2023-10-29T09:57:19.071128937Z"
+ "end_time": "2023-10-29T13:00:30.913607900Z",
+ "start_time": "2023-10-29T13:00:30.641597122Z"
}
},
"outputs": [],
@@ -37,13 +37,13 @@
},
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": 10,
"id": "65d0fd8af0d27c74",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T09:57:19.113036020Z",
- "start_time": "2023-10-29T09:57:19.072023045Z"
+ "end_time": "2023-10-29T13:00:30.938865031Z",
+ "start_time": "2023-10-29T13:00:30.641871248Z"
}
},
"outputs": [],
@@ -73,13 +73,13 @@
},
{
"cell_type": "code",
- "execution_count": 6,
+ "execution_count": 11,
"id": "26b37c1f39e49260",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T09:57:19.114204690Z",
- "start_time": "2023-10-29T09:57:19.072849157Z"
+ "end_time": "2023-10-29T13:00:30.982540375Z",
+ "start_time": "2023-10-29T13:00:30.649939387Z"
}
},
"outputs": [
@@ -116,13 +116,13 @@
},
{
"cell_type": "code",
- "execution_count": 7,
+ "execution_count": 12,
"id": "c317ebd2293a265e",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T09:57:19.114622405Z",
- "start_time": "2023-10-29T09:57:19.082159857Z"
+ "end_time": "2023-10-29T13:00:31.051018511Z",
+ "start_time": "2023-10-29T13:00:30.658191633Z"
}
},
"outputs": [],
@@ -152,13 +152,13 @@
},
{
"cell_type": "code",
- "execution_count": 8,
+ "execution_count": 13,
"id": "42c007d8220de103",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T09:57:19.114977334Z",
- "start_time": "2023-10-29T09:57:19.093553365Z"
+ "end_time": "2023-10-29T13:00:31.051846361Z",
+ "start_time": "2023-10-29T13:00:30.668555016Z"
}
},
"outputs": [],
@@ -193,13 +193,13 @@
},
{
"cell_type": "code",
- "execution_count": 9,
+ "execution_count": 14,
"id": "18d5b71c249a74dc",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T09:57:19.362347786Z",
- "start_time": "2023-10-29T09:57:19.101692525Z"
+ "end_time": "2023-10-29T13:00:31.190798091Z",
+ "start_time": "2023-10-29T13:00:30.677376504Z"
}
},
"outputs": [
@@ -207,7 +207,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "Elapsed time: 0.002283 seconds\n",
+ "Elapsed time: 0.001297 seconds\n",
"[[1. 0.95470327 0.63543805 0.58609427]\n",
" [0.95470327 1. 0.51663504 0.46709937]\n",
" [0.63543805 0.51663504 1. 0.97990505]\n",
@@ -241,13 +241,13 @@
},
{
"cell_type": "code",
- "execution_count": 10,
+ "execution_count": 15,
"id": "4c43837fa4f45e75",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T09:57:19.364929894Z",
- "start_time": "2023-10-29T09:57:19.149164194Z"
+ "end_time": "2023-10-29T13:00:31.417023171Z",
+ "start_time": "2023-10-29T13:00:30.688148621Z"
}
},
"outputs": [
@@ -291,13 +291,13 @@
},
{
"cell_type": "code",
- "execution_count": 11,
+ "execution_count": 16,
"id": "f5af822fe25d115",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T09:57:19.365761893Z",
- "start_time": "2023-10-29T09:57:19.150646799Z"
+ "end_time": "2023-10-29T13:00:31.784027536Z",
+ "start_time": "2023-10-29T13:00:30.695920273Z"
}
},
"outputs": [],
@@ -330,13 +330,13 @@
},
{
"cell_type": "code",
- "execution_count": 11,
+ "execution_count": 16,
"id": "5a714455fba00efa",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T09:57:19.379289936Z",
- "start_time": "2023-10-29T09:57:19.189824573Z"
+ "end_time": "2023-10-29T13:00:31.785967165Z",
+ "start_time": "2023-10-29T13:00:30.745551622Z"
}
},
"outputs": [],
@@ -359,13 +359,13 @@
},
{
"cell_type": "code",
- "execution_count": 12,
+ "execution_count": 17,
"id": "bfe55b16c578ab43",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T09:57:19.380537793Z",
- "start_time": "2023-10-29T09:57:19.191263077Z"
+ "end_time": "2023-10-29T13:00:31.786203567Z",
+ "start_time": "2023-10-29T13:00:30.745981751Z"
}
},
"outputs": [],
@@ -398,13 +398,13 @@
},
{
"cell_type": "code",
- "execution_count": 12,
+ "execution_count": 17,
"id": "8a9f14fee1d3131b",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T09:57:19.381116300Z",
- "start_time": "2023-10-29T09:57:19.192613053Z"
+ "end_time": "2023-10-29T13:00:31.786319114Z",
+ "start_time": "2023-10-29T13:00:30.746181086Z"
}
},
"outputs": [],
@@ -422,13 +422,13 @@
},
{
"cell_type": "code",
- "execution_count": 37,
+ "execution_count": 17,
"id": "7302285b5d9034d2",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T10:15:37.618197471Z",
- "start_time": "2023-10-29T10:15:37.469236159Z"
+ "end_time": "2023-10-29T13:00:31.786411524Z",
+ "start_time": "2023-10-29T13:00:30.746319288Z"
}
},
"outputs": [],
@@ -436,13 +436,13 @@
},
{
"cell_type": "code",
- "execution_count": 37,
+ "execution_count": 17,
"id": "ff595b57e15371f3",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T10:15:37.671088281Z",
- "start_time": "2023-10-29T10:15:37.521162882Z"
+ "end_time": "2023-10-29T13:00:31.786494087Z",
+ "start_time": "2023-10-29T13:00:30.746512297Z"
}
},
"outputs": [],
@@ -450,27 +450,26 @@
},
{
"cell_type": "code",
- "execution_count": 38,
+ "execution_count": 18,
"id": "a8a6628dba1b9186",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T10:15:37.672392654Z",
- "start_time": "2023-10-29T10:15:37.521768458Z"
+ "end_time": "2023-10-29T13:00:31.802702745Z",
+ "start_time": "2023-10-29T13:00:30.789412171Z"
}
},
"outputs": [
{
"ename": "ModuleNotFoundError",
- "evalue": "No module named 'firebase_admin'",
+ "evalue": "No module named 'data'",
"output_type": "error",
"traceback": [
"\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[0;31mModuleNotFoundError\u001B[0m Traceback (most recent call last)",
- "Cell \u001B[0;32mIn[38], line 1\u001B[0m\n\u001B[0;32m----> 1\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mfunctions\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mmatching_users\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m \u001B[38;5;241m*\u001B[39m\n\u001B[1;32m 4\u001B[0m user_ids \u001B[38;5;241m=\u001B[39m [\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mSnake\u001B[39m\u001B[38;5;124m'\u001B[39m,\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mPanda\u001B[39m\u001B[38;5;124m'\u001B[39m,\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mTree\u001B[39m\u001B[38;5;124m'\u001B[39m,\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mDolphin\u001B[39m\u001B[38;5;124m'\u001B[39m,\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mWater\u001B[39m\u001B[38;5;124m'\u001B[39m,\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mBasel\u001B[39m\u001B[38;5;124m'\u001B[39m,\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mTable 16\u001B[39m\u001B[38;5;124m'\u001B[39m]\n\u001B[1;32m 5\u001B[0m preference_matrix \u001B[38;5;241m=\u001B[39m np\u001B[38;5;241m.\u001B[39marray([\n\u001B[1;32m 6\u001B[0m [\u001B[38;5;241m1\u001B[39m, \u001B[38;5;241m2\u001B[39m, \u001B[38;5;241m3\u001B[39m, \u001B[38;5;241m3\u001B[39m, \u001B[38;5;241m1\u001B[39m, \u001B[38;5;241m2\u001B[39m],\n\u001B[1;32m 7\u001B[0m [\u001B[38;5;241m1\u001B[39m, \u001B[38;5;241m2\u001B[39m, \u001B[38;5;241m4\u001B[39m, \u001B[38;5;241m5\u001B[39m, \u001B[38;5;241m1\u001B[39m, \u001B[38;5;241m1\u001B[39m],\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 12\u001B[0m [\u001B[38;5;241m1\u001B[39m, \u001B[38;5;241m1\u001B[39m, \u001B[38;5;241m1\u001B[39m, \u001B[38;5;241m0\u001B[39m, \u001B[38;5;241m1\u001B[39m, \u001B[38;5;241m1\u001B[39m]\n\u001B[1;32m 13\u001B[0m ], dtype\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124muint8\u001B[39m\u001B[38;5;124m'\u001B[39m)\n",
- "File \u001B[0;32m~/DataspellProjects/randoms/functions/matching_users.py:8\u001B[0m\n\u001B[1;32m 6\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01msklearn\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mmetrics\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mpairwise\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m cosine_similarity\n\u001B[1;32m 7\u001B[0m \u001B[38;5;28;01mimport\u001B[39;00m \u001B[38;5;21;01mcollections\u001B[39;00m\n\u001B[0;32m----> 8\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mfunctions\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mdata\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m User\n\u001B[1;32m 10\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mget_sorted_list_func\u001B[39m(user_ids, user_preferences):\n\u001B[1;32m 11\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mget_sorted_list\u001B[39m(user_index):\n",
- "File \u001B[0;32m~/DataspellProjects/randoms/functions/data.py:6\u001B[0m\n\u001B[1;32m 3\u001B[0m \u001B[38;5;28;01mimport\u001B[39;00m \u001B[38;5;21;01mrandom\u001B[39;00m\n\u001B[1;32m 4\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mfaker\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m Faker\n\u001B[0;32m----> 6\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mfirebase_admin\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m firestore\n\u001B[1;32m 7\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mfirebase_admin\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m auth\n\u001B[1;32m 10\u001B[0m \u001B[38;5;28;01mclass\u001B[39;00m \u001B[38;5;21;01mUser\u001B[39;00m:\n",
- "\u001B[0;31mModuleNotFoundError\u001B[0m: No module named 'firebase_admin'"
+ "Cell \u001B[0;32mIn[18], line 1\u001B[0m\n\u001B[0;32m----> 1\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mfunctions\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mmatching_users\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m \u001B[38;5;241m*\u001B[39m\n\u001B[1;32m 4\u001B[0m user_ids \u001B[38;5;241m=\u001B[39m [\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mSnake\u001B[39m\u001B[38;5;124m'\u001B[39m,\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mPanda\u001B[39m\u001B[38;5;124m'\u001B[39m,\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mTree\u001B[39m\u001B[38;5;124m'\u001B[39m,\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mDolphin\u001B[39m\u001B[38;5;124m'\u001B[39m,\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mWater\u001B[39m\u001B[38;5;124m'\u001B[39m,\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mBasel\u001B[39m\u001B[38;5;124m'\u001B[39m,\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mTable 16\u001B[39m\u001B[38;5;124m'\u001B[39m]\n\u001B[1;32m 5\u001B[0m preference_matrix \u001B[38;5;241m=\u001B[39m np\u001B[38;5;241m.\u001B[39marray([\n\u001B[1;32m 6\u001B[0m [\u001B[38;5;241m1\u001B[39m, \u001B[38;5;241m2\u001B[39m, \u001B[38;5;241m3\u001B[39m, \u001B[38;5;241m3\u001B[39m, \u001B[38;5;241m1\u001B[39m, \u001B[38;5;241m2\u001B[39m],\n\u001B[1;32m 7\u001B[0m [\u001B[38;5;241m1\u001B[39m, \u001B[38;5;241m2\u001B[39m, \u001B[38;5;241m4\u001B[39m, \u001B[38;5;241m5\u001B[39m, \u001B[38;5;241m1\u001B[39m, \u001B[38;5;241m1\u001B[39m],\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 12\u001B[0m [\u001B[38;5;241m1\u001B[39m, \u001B[38;5;241m1\u001B[39m, \u001B[38;5;241m1\u001B[39m, \u001B[38;5;241m0\u001B[39m, \u001B[38;5;241m1\u001B[39m, \u001B[38;5;241m1\u001B[39m]\n\u001B[1;32m 13\u001B[0m ], dtype\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124muint8\u001B[39m\u001B[38;5;124m'\u001B[39m)\n",
+ "File \u001B[0;32m~/DataspellProjects/randoms/functions/matching_users.py:8\u001B[0m\n\u001B[1;32m 6\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01msklearn\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mmetrics\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mpairwise\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m cosine_similarity\n\u001B[1;32m 7\u001B[0m \u001B[38;5;28;01mimport\u001B[39;00m \u001B[38;5;21;01mcollections\u001B[39;00m\n\u001B[0;32m----> 8\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mdata\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m User\n\u001B[1;32m 10\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mget_sorted_list_func\u001B[39m(user_ids, user_preferences):\n\u001B[1;32m 11\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mget_sorted_list\u001B[39m(user_index):\n",
+ "\u001B[0;31mModuleNotFoundError\u001B[0m: No module named 'data'"
]
}
],
@@ -497,13 +496,12 @@
},
{
"cell_type": "code",
- "execution_count": 76,
+ "execution_count": null,
"id": "9a29c81b1b0669ff",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T10:22:52.995123710Z",
- "start_time": "2023-10-29T10:22:52.509889524Z"
+ "start_time": "2023-10-29T13:00:30.900982840Z"
}
},
"outputs": [],
@@ -511,108 +509,9 @@
"import json\n",
"from datetime import date\n",
"import random\n",
- "from faker import Faker\n",
- "\n",
- "class User:\n",
- " def __init__(self, id: str, doc: dict):\n",
- " self.id = id\n",
- " self.name = doc[\"name\"]\n",
- " self.preferences = doc[\"preferences\"]\n",
- " self.days = doc[\"days\"]\n",
- " self.original = doc\n",
- " self.original[\"id\"] = id\n",
- "\n",
- " def __str__(self):\n",
- " return json.dumps(self.original)\n",
- "\n",
- "def get_workdays():\n",
- " random_array = [random.choice([False, True]) for _ in range(5)]\n",
- " return [days for nr, days in enumerate(['Mon', 'Tue', 'Wed', 'Thu', 'Fri']) if random_array[nr]]\n",
- "\n",
- "\n",
- "def get_preferences():\n",
- " preference_topics = ['Sports', 'Eating', 'Board Games', 'Video Games', 'Coffee Enthusiasm', 'Tea Appreciation',\n",
- " 'Nightlife and Parties', 'Nature and Greenery', 'Books', 'Anime and Manga']\n",
- "\n",
- " score = [0]\n",
- " return {preference: random.choice(score) for preference in preference_topics}\n",
- "\n",
- "\n",
- "def create_fake_users(amount):\n",
- " fake = Faker(locale=\"en_GB\")\n",
- " return [User(i, {'name': fake.name(), 'days': get_workdays(), 'preferences': get_preferences()}) for i in\n",
- " range(amount)]\n",
- "\n",
- "\n",
- "def get_funfact(preferences):\n",
- " max_key = max(preferences, key=preferences.get)\n",
- " return 'I really like {}!'.format(max_key)\n",
- "\n",
- "def get_sorted_list_func(user_ids, user_preferences):\n",
- " def get_sorted_list(user_index):\n",
- " user_score_list = {user_ids[partner_id]:score for partner_id, score in enumerate(user_preferences[user_index]) if partner_id != user_index}\n",
- " user_score_ordered = collections.OrderedDict(sorted(user_score_list.items(), key=lambda item: item[1], reverse=True))\n",
- " return list(user_score_ordered)\n",
- " return get_sorted_list\n",
- "\n",
- "def check_input(user_ids, preference_matrix):\n",
- " user_limit = 10000\n",
- " if len(user_ids)>user_limit or len(preference_matrix)>user_limit:\n",
- " raise ValueError(f\"The user limit is {user_limit}\")\n",
- " if len(user_ids) != len(preference_matrix):\n",
- " raise ValueError(f\"user list and matrix length do not match\")\n",
- "\n",
- "def get_preference_lists(user_ids, preference_matrix):\n",
- " check_input(user_ids, preference_matrix)\n",
- "\n",
- " user_preferences = cosine_similarity(preference_matrix)\n",
- " get_sorted_list = get_sorted_list_func(user_ids, user_preferences)\n",
- " return [get_sorted_list(user_index) for user_index in range(len(user_ids))]\n",
- "\n",
- "def convert_preferences_to_matrix(users_preferences):\n",
- " # Get the list of all topics from the user preferences\n",
- " all_topics = set().union(*users_preferences)\n",
- "\n",
- " # Create a NumPy matrix from the user preferences\n",
- " pref_matrix = np.array([[user_pref.get(topic, 0) for topic in all_topics] for user_pref in users_preferences])\n",
- "\n",
- " return pref_matrix\n",
- "\n",
- "def create_matches_from_users(users: list[User]):\n",
- " # now we need to build the matrix \n",
- " names_to_player = {x.id: Player(x.id) for x in users}\n",
- " id_to_user = {x.id: x for x in users}\n",
- " # going to be unique for each user\n",
- " names = [x.id for x in users]\n",
- " pref_matrix = convert_preferences_to_matrix([x.preferences for x in users])\n",
- "\n",
- "\n",
- "\n",
- " #print(pref_matrix)\n",
- " preference_order = get_preference_lists(names, pref_matrix)\n",
- " #print(preference_order)\n",
- "\n",
- " for name,pref in zip(names,preference_order):\n",
- " player = names_to_player[name]\n",
- " player.set_prefs([names_to_player[x] for x in pref])\n",
- "\n",
- " players = [value for key,value in names_to_player.items()]\n",
- "\n",
- " matching = stable_roommates(players)\n",
- " user_tuples = []\n",
- " losers = []\n",
- "\n",
- " for match1, match2 in matching.items():\n",
- " #print(match1.name)\n",
- " if match2:\n",
- " user_tuples.append((id_to_user[match1.name], id_to_user[match2.name]))\n",
- " else:\n",
- " losers.append(id_to_user[match1.name])\n",
- "\n",
- " if len(losers) >= 2:\n",
- " user_tuples.extend(zip(losers[0::2], losers[1::2]))\n",
+ "from functions.matching_users import *\n",
+ "from functions.data import *\n",
"\n",
- " return user_tuples\n",
"\n",
"\n",
"users = create_fake_users(1000)\n",
@@ -622,7 +521,7 @@
},
{
"cell_type": "code",
- "execution_count": 77,
+ "execution_count": null,
"outputs": [],
"source": [
"# going to be unique for each user\n",
@@ -633,15 +532,14 @@
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T10:22:53.933799076Z",
- "start_time": "2023-10-29T10:22:53.007911967Z"
+ "start_time": "2023-10-29T13:00:30.945861521Z"
}
},
"id": "7e7cc451db51550c"
},
{
"cell_type": "code",
- "execution_count": 78,
+ "execution_count": null,
"outputs": [],
"source": [
"class Match:\n",
@@ -658,15 +556,14 @@
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T10:22:53.986241145Z",
- "start_time": "2023-10-29T10:22:53.944774066Z"
+ "start_time": "2023-10-29T13:00:30.946303677Z"
}
},
"id": "ff47e0ae78bb6f08"
},
{
"cell_type": "code",
- "execution_count": 79,
+ "execution_count": null,
"outputs": [],
"source": [
"previous_matches = [(1,2),(1,3),(1,4),(2,5),(6,3),(5,8),(9,8),(9,3),(2,3),(12,4),(12,3),(12,2),(12,1)]\n",
@@ -682,29 +579,27 @@
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T10:22:54.001167319Z",
- "start_time": "2023-10-29T10:22:53.961767785Z"
+ "start_time": "2023-10-29T13:00:30.946588688Z"
}
},
"id": "ebb086ce689d0fc7"
},
{
"cell_type": "code",
- "execution_count": 79,
+ "execution_count": null,
"outputs": [],
"source": [],
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T10:22:54.004682044Z",
- "start_time": "2023-10-29T10:22:53.984049416Z"
+ "start_time": "2023-10-29T13:00:30.946865468Z"
}
},
"id": "1f27ef170f38dc02"
},
{
"cell_type": "code",
- "execution_count": 80,
+ "execution_count": null,
"outputs": [],
"source": [
"return_list = remove_previous_matches(preference_order, previous_matches)\n"
@@ -712,52 +607,41 @@
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T10:22:54.415084080Z",
- "start_time": "2023-10-29T10:22:54.394193531Z"
+ "start_time": "2023-10-29T13:00:30.947137506Z"
}
},
"id": "24346cfead241aa9"
},
{
"cell_type": "code",
- "execution_count": 62,
+ "execution_count": null,
"outputs": [],
"source": [],
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T10:20:13.695231611Z",
- "start_time": "2023-10-29T10:20:13.507044642Z"
+ "start_time": "2023-10-29T13:00:30.947409511Z"
}
},
"id": "f6c02396f994b7a1"
},
{
"cell_type": "code",
- "execution_count": 62,
+ "execution_count": null,
"outputs": [],
"source": [],
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T10:20:13.695811979Z",
- "start_time": "2023-10-29T10:20:13.549595326Z"
+ "start_time": "2023-10-29T13:00:30.947953980Z"
}
},
"id": "4b43568fbe9967eb"
},
{
"cell_type": "code",
- "execution_count": 63,
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "done\n"
- ]
- }
- ],
+ "execution_count": null,
+ "outputs": [],
"source": [
"from matching.algorithms import stable_roommates\n",
"\n",
@@ -782,37 +666,22 @@
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T10:20:13.696853885Z",
- "start_time": "2023-10-29T10:20:13.550990032Z"
+ "start_time": "2023-10-29T13:00:30.948292469Z"
}
},
"id": "eb36b9313a18d88e"
},
{
"cell_type": "code",
- "execution_count": 64,
+ "execution_count": null,
"id": "37468ad06e3338a6",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2023-10-29T10:20:13.763153068Z",
- "start_time": "2023-10-29T10:20:13.559344290Z"
+ "start_time": "2023-10-29T13:00:30.948528787Z"
}
},
- "outputs": [
- {
- "ename": "ModuleNotFoundError",
- "evalue": "No module named 'firebase_admin'",
- "output_type": "error",
- "traceback": [
- "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
- "\u001B[0;31mModuleNotFoundError\u001B[0m Traceback (most recent call last)",
- "Cell \u001B[0;32mIn[64], line 1\u001B[0m\n\u001B[0;32m----> 1\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mfunctions\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mdata\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m User\n\u001B[1;32m 2\u001B[0m \u001B[38;5;66;03m# import random\u001B[39;00m\n\u001B[1;32m 3\u001B[0m \u001B[38;5;66;03m# from faker import Faker\u001B[39;00m\n\u001B[1;32m 4\u001B[0m \u001B[38;5;66;03m# \u001B[39;00m\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 23\u001B[0m \u001B[38;5;66;03m# for u in fake_users:\u001B[39;00m\n\u001B[1;32m 24\u001B[0m \u001B[38;5;66;03m# print(str(u))\u001B[39;00m\n",
- "File \u001B[0;32m~/DataspellProjects/randoms/functions/data.py:6\u001B[0m\n\u001B[1;32m 3\u001B[0m \u001B[38;5;28;01mimport\u001B[39;00m \u001B[38;5;21;01mrandom\u001B[39;00m\n\u001B[1;32m 4\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mfaker\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m Faker\n\u001B[0;32m----> 6\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mfirebase_admin\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m firestore\n\u001B[1;32m 7\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mfirebase_admin\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m auth\n\u001B[1;32m 10\u001B[0m \u001B[38;5;28;01mclass\u001B[39;00m \u001B[38;5;21;01mUser\u001B[39;00m:\n",
- "\u001B[0;31mModuleNotFoundError\u001B[0m: No module named 'firebase_admin'"
- ]
- }
- ],
+ "outputs": [],
"source": [
"\n",
"from functions.data import User\n",
@@ -845,30 +714,62 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 19,
"id": "834dfbfe0b60cb0b",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "start_time": "2023-10-29T10:20:13.636155515Z"
+ "end_time": "2023-10-29T13:00:39.548569227Z",
+ "start_time": "2023-10-29T13:00:39.177176147Z"
}
},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/home/baaaka/DataspellProjects/randoms/venv/lib/python3.10/site-packages/google/rpc/__init__.py:20: DeprecationWarning: Deprecated call to `pkg_resources.declare_namespace('google.rpc')`.\n",
+ "Implementing implicit namespace packages (as specified in PEP 420) is preferred to `pkg_resources.declare_namespace`. See https://setuptools.pypa.io/en/latest/references/keywords.html#keyword-namespace-packages\n",
+ " pkg_resources.declare_namespace(__name__)\n",
+ "/home/baaaka/DataspellProjects/randoms/venv/lib/python3.10/site-packages/pkg_resources/__init__.py:2350: DeprecationWarning: Deprecated call to `pkg_resources.declare_namespace('google')`.\n",
+ "Implementing implicit namespace packages (as specified in PEP 420) is preferred to `pkg_resources.declare_namespace`. See https://setuptools.pypa.io/en/latest/references/keywords.html#keyword-namespace-packages\n",
+ " declare_namespace(parent)\n"
+ ]
+ }
+ ],
"source": [
"from functions.data import create_fake_users"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 20,
"id": "4180d228b79f25f3",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "start_time": "2023-10-29T10:20:13.677452102Z"
+ "end_time": "2023-10-29T13:00:39.720026356Z",
+ "start_time": "2023-10-29T13:00:39.646626439Z"
}
},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{\"name\": \"Bernard Fraser\", \"days\": [\"Wed\", \"Thu\", \"Fri\"], \"preferences\": {\"Sports\": 3, \"Eating\": 0, \"Board Games\": 1, \"Video Games\": 0, \"Coffee Enthusiasm\": 4, \"Tea Appreciation\": 2, \"Nightlife and Parties\": 4, \"Nature and Greenery\": 0, \"Books\": 5, \"Anime and Manga\": 1}, \"id\": 0}\n",
+ "{\"name\": \"Miss Josephine Cooper\", \"days\": [\"Mon\"], \"preferences\": {\"Sports\": 0, \"Eating\": 3, \"Board Games\": 0, \"Video Games\": 0, \"Coffee Enthusiasm\": 0, \"Tea Appreciation\": 0, \"Nightlife and Parties\": 0, \"Nature and Greenery\": 0, \"Books\": 0, \"Anime and Manga\": 0}, \"id\": 1}\n",
+ "{\"name\": \"Mr Glenn Stevens\", \"days\": [\"Mon\", \"Tue\", \"Fri\"], \"preferences\": {\"Sports\": 4, \"Eating\": 0, \"Board Games\": 0, \"Video Games\": 0, \"Coffee Enthusiasm\": 4, \"Tea Appreciation\": 0, \"Nightlife and Parties\": 0, \"Nature and Greenery\": 1, \"Books\": 0, \"Anime and Manga\": 0}, \"id\": 2}\n",
+ "{\"name\": \"Dr Martyn Turner\", \"days\": [\"Tue\", \"Fri\"], \"preferences\": {\"Sports\": 2, \"Eating\": 0, \"Board Games\": 2, \"Video Games\": 3, \"Coffee Enthusiasm\": 1, \"Tea Appreciation\": 0, \"Nightlife and Parties\": 0, \"Nature and Greenery\": 0, \"Books\": 0, \"Anime and Manga\": 0}, \"id\": 3}\n",
+ "{\"name\": \"Kieran Lamb\", \"days\": [\"Mon\", \"Tue\", \"Thu\", \"Fri\"], \"preferences\": {\"Sports\": 0, \"Eating\": 4, \"Board Games\": 2, \"Video Games\": 0, \"Coffee Enthusiasm\": 0, \"Tea Appreciation\": 0, \"Nightlife and Parties\": 0, \"Nature and Greenery\": 3, \"Books\": 1, \"Anime and Manga\": 5}, \"id\": 4}\n",
+ "{\"name\": \"Joshua Jenkins\", \"days\": [], \"preferences\": {\"Sports\": 0, \"Eating\": 0, \"Board Games\": 2, \"Video Games\": 1, \"Coffee Enthusiasm\": 0, \"Tea Appreciation\": 0, \"Nightlife and Parties\": 0, \"Nature and Greenery\": 0, \"Books\": 0, \"Anime and Manga\": 0}, \"id\": 5}\n",
+ "{\"name\": \"George Lee-Russell\", \"days\": [\"Wed\", \"Thu\"], \"preferences\": {\"Sports\": 0, \"Eating\": 0, \"Board Games\": 0, \"Video Games\": 3, \"Coffee Enthusiasm\": 0, \"Tea Appreciation\": 0, \"Nightlife and Parties\": 0, \"Nature and Greenery\": 0, \"Books\": 4, \"Anime and Manga\": 4}, \"id\": 6}\n",
+ "{\"name\": \"Yvonne Hughes\", \"days\": [\"Tue\", \"Thu\"], \"preferences\": {\"Sports\": 0, \"Eating\": 1, \"Board Games\": 0, \"Video Games\": 5, \"Coffee Enthusiasm\": 0, \"Tea Appreciation\": 2, \"Nightlife and Parties\": 0, \"Nature and Greenery\": 1, \"Books\": 0, \"Anime and Manga\": 3}, \"id\": 7}\n",
+ "{\"name\": \"Nathan Whitehead\", \"days\": [\"Tue\", \"Thu\", \"Fri\"], \"preferences\": {\"Sports\": 0, \"Eating\": 5, \"Board Games\": 0, \"Video Games\": 0, \"Coffee Enthusiasm\": 0, \"Tea Appreciation\": 0, \"Nightlife and Parties\": 2, \"Nature and Greenery\": 0, \"Books\": 0, \"Anime and Manga\": 0}, \"id\": 8}\n",
+ "{\"name\": \"Mr Ronald Russell\", \"days\": [\"Mon\", \"Tue\", \"Thu\", \"Fri\"], \"preferences\": {\"Sports\": 0, \"Eating\": 0, \"Board Games\": 0, \"Video Games\": 1, \"Coffee Enthusiasm\": 0, \"Tea Appreciation\": 0, \"Nightlife and Parties\": 5, \"Nature and Greenery\": 3, \"Books\": 5, \"Anime and Manga\": 0}, \"id\": 9}\n"
+ ]
+ }
+ ],
"source": [
"fake_users = create_fake_users(10)\n",
"\n",
@@ -878,16 +779,173 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 24,
"id": "96ddc60b5e5f3caa",
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "start_time": "2023-10-29T10:20:13.678111526Z"
+ "end_time": "2023-10-29T13:01:01.101866800Z",
+ "start_time": "2023-10-29T13:01:01.051946418Z"
}
},
"outputs": [],
- "source": []
+ "source": [
+ "import os\n",
+ "\n",
+ "current_directory = os.getcwd()\n",
+ "\n",
+ "new_directory = '../functions'\n",
+ "\n",
+ "os.chdir(new_directory)\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "outputs": [],
+ "source": [
+ "\n",
+ "fu = create_fake_users(10)"
+ ],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "end_time": "2023-10-29T13:01:01.297109787Z",
+ "start_time": "2023-10-29T13:01:01.236676224Z"
+ }
+ },
+ "id": "e8822aa2a9202547"
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "outputs": [],
+ "source": [],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "end_time": "2023-10-29T13:02:10.748758860Z",
+ "start_time": "2023-10-29T13:02:10.728109740Z"
+ }
+ },
+ "id": "48cb3be35c2c6751"
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "outputs": [],
+ "source": [
+ "from functions.matching_users import *\n",
+ "from functions.main import match_users\n",
+ "matches = match_users(fu)"
+ ],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "end_time": "2023-10-29T13:02:11.143722060Z",
+ "start_time": "2023-10-29T13:02:11.125379096Z"
+ }
+ },
+ "id": "ced35fce634e8d68"
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 33,
+ "outputs": [],
+ "source": [
+ "# 100 96ms\n",
+ "# 1000 30 seconds\n",
+ "# 10000\n",
+ "# \\frac{x^{2.4}}{1000000}"
+ ],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "end_time": "2023-10-29T13:02:11.683758043Z",
+ "start_time": "2023-10-29T13:02:11.668115312Z"
+ }
+ },
+ "id": "5f572900f411b8a4"
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Denise Wilson || Ellie Taylor\n",
+ "Graham Collins || Mr Garry McDonald\n",
+ "Ellie Taylor || Denise Wilson\n",
+ "Kathryn Joyce || Francesca Smith-Davis\n",
+ "Patrick Lloyd || Judith Morris\n",
+ "Anthony Jones || Elliott Lewis\n",
+ "Mr Garry McDonald || Graham Collins\n",
+ "Elliott Lewis || Anthony Jones\n",
+ "Judith Morris || Patrick Lloyd\n",
+ "Francesca Smith-Davis || Kathryn Joyce\n"
+ ]
+ }
+ ],
+ "source": [
+ "for a in matches:\n",
+ " print('{} || {}'.format(a.user1.name, a.user2.name))"
+ ],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "end_time": "2023-10-29T13:02:12.042855811Z",
+ "start_time": "2023-10-29T13:02:12.027178675Z"
+ }
+ },
+ "id": "f10d96ee022b2126"
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "Denise Wilson || Kathryn Joyce\n",
+ "Graham Collins || Mr Garry McDonald\n",
+ "Ellie Taylor || Francesca Smith-Davis\n",
+ "Kathryn Joyce || Denise Wilson\n",
+ "Patrick Lloyd || Judith Morris\n",
+ "Anthony Jones || Elliott Lewis\n",
+ "Mr Garry McDonald || Graham Collins\n",
+ "Elliott Lewis || Anthony Jones\n",
+ "Judith Morris || Patrick Lloyd\n",
+ "Francesca Smith-Davis || Ellie Taylor"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "45d642571af85db"
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "outputs": [],
+ "source": [],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "start_time": "2023-10-29T13:00:30.991201554Z"
+ }
+ },
+ "id": "76ba9c59eaba58df"
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "outputs": [],
+ "source": [],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "start_time": "2023-10-29T13:00:31.037491228Z"
+ }
+ },
+ "id": "7cd1de98b8fa2451"
}
],
"metadata": {