Skip to content

Commit

Permalink
testing
Browse files Browse the repository at this point in the history
  • Loading branch information
mhewedy committed May 21, 2024
1 parent 4d034ad commit 196234d
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 92 deletions.
17 changes: 11 additions & 6 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import food
import util
from util import UserSelector
from selection import UserSelector

bot = BotApp()
userSelector = UserSelector()
Expand All @@ -37,7 +37,7 @@ async def capture():
asyncio.create_task(capture()) # noinspection PyTypeChecker


@bot.command(name="add", desc="إضافة طلبك (فقط إذا لم يتم إضافته بشكل تلقائي)")
@bot.command(name="add", desc="إضافة طلبك")
async def add_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
order = " ".join(context.args)
if not order:
Expand All @@ -52,11 +52,14 @@ async def add_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
@bot.command(name="delete", desc="مسح طلبك")
async def delete_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
user = util.current_user(update)
for (msg_id, u), _ in list(orders.items()):
not_found = True
for (msg_id, u), o in list(orders.items()):
if user == u:
not_found = False
del orders[(msg_id, u)]
await update.message.reply_text(f'تم مسح طلبك "{o}" بنجاح')

await update.message.reply_text('تمت مسح طلبك بنجاح')
if not_found: await update.message.reply_text('لا توجد طلبات')


@bot.command(name="list", desc="عرض الطلبات")
Expand All @@ -83,9 +86,11 @@ async def clear_command(update: Update, context: ContextTypes.DEFAULT_TYPE):

global orders
orders = {}
if context.args == "+selection_history":
msg = "تم مسح جميع الطلبات بنجاح"
if "+selection_history" in context.args:
msg += " و تم مسح جميع اختيارات المستخدمين أيضا"
userSelector.clear_history()
await update.message.reply_text("تم مسح جميع الطلبات بنجاح")
await update.message.reply_text(msg)


@bot.command(name="ping", desc="اختبار البوت")
Expand Down
74 changes: 74 additions & 0 deletions selection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import json
import logging
import os
import random
from abc import abstractmethod, ABC


class HistoryManager(ABC):
def __init__(self):
self.history = []

@abstractmethod
def load_history(self):
pass

def save_history(self, h):
self.history = h


class InMemoryHistoryManager(HistoryManager):
def load_history(self):
pass


class FileSystemHistoryManager(HistoryManager):
def __init__(self, file_path='~/.lunchy/history.json'):
super().__init__()
self.file_path = os.path.expanduser(file_path)
self.load_history()

def load_history(self):
directory = os.path.dirname(self.file_path)
if directory and not os.path.exists(directory):
os.makedirs(directory)

if os.path.exists(self.file_path):
with open(self.file_path, 'r') as file:
self.history = json.load(file)
else:
self.history = []
self.save_history(self.history)

def save_history(self, h):
super().save_history(h)
with open(self.file_path, 'w') as file:
json.dump(self.history, file)


class UserSelector:
def __init__(self, exclude_gap=0, history_manager=FileSystemHistoryManager()):
self.exclude_gap = exclude_gap
self.history_manager = history_manager

def select(self, users):
if not users:
raise ValueError('users list should not be empty')

uniq_len = len(list(set(users)))
excluded_users = self.history_manager.history[
len(self.history_manager.history) -
(uniq_len - 1 if uniq_len <= self.exclude_gap else self.exclude_gap):
]
selected = random.choice(users)

if selected in excluded_users:
logging.warning(f'{selected} was in excluded history: {excluded_users}, re-selecting...')
return self.select(users)
else:
logging.info(f'users: {users}, selected user is: {selected}')
self.history_manager.save_history((self.history_manager.history + [selected])[-10:])
return selected

def clear_history(self):
self.history_manager.save_history([])
48 changes: 36 additions & 12 deletions test_util.py → test_selection.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
import unittest

from util import UserSelector
from selection import UserSelector


class TestUserSelector(unittest.TestCase):
Expand Down Expand Up @@ -32,7 +32,7 @@ def test_select_single_user(self):
self.assertEqual(selected, "Alice")

def test_select_non_excluded_from_2_users_with_2_selection_gap(self):
selector = UserSelector(selection_gap=2)
selector = UserSelector(exclude_gap=2)
users = ["Alice", "Bob", "Bob", "Bob", "Bob"]
selector.history_manager.history = ["Alice", "Bob", "Alice"]

Expand All @@ -42,7 +42,7 @@ def test_select_non_excluded_from_2_users_with_2_selection_gap(self):
self.assertEqual(selected, expected_selection)

def test_select_non_excluded_3_users_with_2_selection_gap(self):
selector = UserSelector(selection_gap=2)
selector = UserSelector(exclude_gap=2)
users = ["Alice", "Alice", "Bob", "Bob", "Charlie", "Charlie", "Charlie"]
selector.history_manager.history = ["Alice", "Bob", "Charlie"]

Expand All @@ -52,17 +52,17 @@ def test_select_non_excluded_3_users_with_2_selection_gap(self):
self.assertEqual(selected, expected_selection)

def test_select_non_excluded_from_2_users_with_0_selection_gap(self):
selector = UserSelector(selection_gap=0)
selector = UserSelector(exclude_gap=0)
users = ["Alice", "Bob", "Bob", "Bob", "Bob"]
selector.history_manager.history = ["Alice", "Bob", "Alice"]

selected = selector.select(users)
self.assertIn(selected, ["Alice", "Bob"])

def test_select_non_excluded_3_users_with_0_selection_gap(self):
def test_select_non_excluded_3_users_with_0_selection_gap__(self):
count = 0
for _ in range(0, 100):
selector = UserSelector(selection_gap=0)
selector = UserSelector(exclude_gap=0)
users = ["Alice", "Alice", "Bob", "Bob", "Charlie", "Charlie", "Charlie"]
selector.history_manager.history = ["Alice", "Bob", "Charlie"]
selected = selector.select(users)
Expand All @@ -71,10 +71,22 @@ def test_select_non_excluded_3_users_with_0_selection_gap(self):

self.assertGreater(count, 0)

def test_select_non_excluded_3_users_with_0_selection_gap_2(self):
def test_select_non_excluded_3_users_with_1_selection_gap__(self):
count = 0
for _ in range(0, 100):
selector = UserSelector(selection_gap=2)
selector = UserSelector(exclude_gap=2)
users = ["Alice", "Alice", "Bob", "Bob", "Charlie", "Charlie", "Charlie"]
selector.history_manager.history = ["Alice", "Bob", "Charlie"]
selected = selector.select(users)
if selected in ["Charlie"]:
count += 1

self.assertEqual(count, 0)

def test_select_non_excluded_3_users_with_2_selection_gap__(self):
count = 0
for _ in range(0, 100):
selector = UserSelector(exclude_gap=2)
users = ["Alice", "Alice", "Bob", "Bob", "Charlie", "Charlie", "Charlie"]
selector.history_manager.history = ["Alice", "Bob", "Charlie"]
selected = selector.select(users)
Expand All @@ -83,8 +95,20 @@ def test_select_non_excluded_3_users_with_0_selection_gap_2(self):

self.assertEqual(count, 0)

def test_select_non_excluded_3_users_with_3_selection_gap__(self):
count = 0
for _ in range(0, 100):
selector = UserSelector(exclude_gap=3)
users = ["Alice", "Alice", "Bob", "Bob", "Charlie", "Charlie", "Charlie", "Dave"]
selector.history_manager.history = ["Alice", "Bob", "Charlie"]
selected = selector.select(users)
if selected in ["Alice", "Bob", "Charlie"]:
count += 1

self.assertEqual(count, 0)

def test_select_non_excluded_3_users_with_ids(self):
selector = UserSelector(selection_gap=2)
selector = UserSelector(exclude_gap=2)
users = [(1, "Alice"), (1, "Alice"), (2, "Bob"), (2, "Bob"), (3, "Charlie"), (3, "Charlie"), (3, "Charlie")]
selector.history_manager.history = [(1, "Alice"), (2, "Bob"), (3, "Charlie")]

Expand All @@ -95,21 +119,21 @@ def test_select_non_excluded_3_users_with_ids(self):

def test_select_never_picks_last_n_from_history(self):
for _ in range(100):
selector = UserSelector(selection_gap=2)
selector = UserSelector(exclude_gap=2)
users = \
["Alice", "Alice", "Bob", "Bob", "Charlie", "Charlie", "Charlie", "Diana", "Diana", "David", "David"]
selector.history_manager.history = ["Alice", "Bob", "Charlie", "Diana"]
selected = selector.select(users)
self.assertIn(selected, ["Alice", "Bob", "David"])

def test_history_maintenance(self):
selector = UserSelector(selection_gap=2)
selector = UserSelector(exclude_gap=2)
users = ["Alice", "Bob", "Charlie", "Diana"]
selections = []
for _ in range(100):
selected = selector.select(users)
selections.append(selected)
self.assertEqual(selector.history_manager.history, selections[-selector.selection_gap:])
self.assertEqual(selector.history_manager.history, selections[-10:])


if __name__ == "__main__":
Expand Down
74 changes: 0 additions & 74 deletions util.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import json
import logging
import os
import random
import time
from abc import abstractmethod, ABC
from typing import Any
from typing import Callable

Expand Down Expand Up @@ -38,76 +34,6 @@ async def is_admin(update: Update, context: ContextTypes.DEFAULT_TYPE) -> bool:
return False


class HistoryManager(ABC):
def __init__(self):
self.history = []

@abstractmethod
def load_history(self):
pass

def save_history(self, h):
self.history = h


class InMemoryHistoryManager(HistoryManager):
def load_history(self):
pass


class FileSystemHistoryManager(HistoryManager):
def __init__(self, file_path=None):
super().__init__()
if file_path is None:
file_path = os.path.expanduser('~/.lunchy/history.json')
self.file_path = file_path
self.load_history()

def load_history(self):
directory = os.path.dirname(self.file_path)
if directory and not os.path.exists(directory):
os.makedirs(directory)

if os.path.exists(self.file_path):
with open(self.file_path, 'r') as file:
self.history = json.load(file)
else:
self.history = []
self.save_history(self.history)

def save_history(self, h):
with open(self.file_path, 'w') as file:
json.dump(self.history, file)


class UserSelector:
def __init__(self, selection_gap=0, history_manager=InMemoryHistoryManager()):
self.selection_gap = selection_gap
self.history_manager = history_manager

def select(self, users):
if not users:
raise ValueError('users list should not be empty')

uniq_len = len(list(set(users)))
excluded_users = self.history_manager.history[
len(self.history_manager.history) -
(uniq_len - 1 if uniq_len <= self.selection_gap else self.selection_gap):
]
selected = random.choice(users)

if selected in excluded_users:
logging.warning(f'{selected} was in excluded history: {excluded_users}, re-selecting...')
return self.select(users)
else:
logging.info(f'users: {users}, selected user is: {selected}')
self.history_manager.save_history((self.history_manager.history + [selected])[-2:])
return selected

def clear_history(self):
self.history_manager.save_history([])


def get_congrats_msg():
return random.choice([
"صاحب الحظ السعيد اليوم هو",
Expand Down

0 comments on commit 196234d

Please sign in to comment.