From ca96d396a4b27b5af5d685e6f6e6c6f71b8467f8 Mon Sep 17 00:00:00 2001 From: Yana Kalsina Date: Mon, 15 Dec 2025 15:16:55 +0300 Subject: [PATCH 1/4] Add solution for walker task --- src/Walker/Walker_class.py | 75 ++++++++++++++++++++++++++++++++++ tests/test_for_walker_class.py | 20 +++++++++ 2 files changed, 95 insertions(+) create mode 100644 src/Walker/Walker_class.py create mode 100644 tests/test_for_walker_class.py diff --git a/src/Walker/Walker_class.py b/src/Walker/Walker_class.py new file mode 100644 index 0000000..e5de202 --- /dev/null +++ b/src/Walker/Walker_class.py @@ -0,0 +1,75 @@ +import random +import math + +class Walker: + def __init__(self, events_and_prob): + + if not events_and_prob: + raise ValueError("Переданный список пустой") + self.events_and_prob = events_and_prob + self.probability_check() + self.quantity_of_lines = len(self.events_and_prob) + self.overage_prob = 1 / self.quantity_of_lines + + self.donors = [] + self.recipients = [] + self.table = [None] * self.quantity_of_lines + + for i in range(len(self.events_and_prob)): + # список вида [...["событие", нужная вероятность, имеющаяся]...] + if self.events_and_prob[i][1] <= self.overage_prob: + self.events_and_prob[i].append(self.overage_prob) + self.donors.append(self.events_and_prob[i]) + else: + self.events_and_prob[i].append(self.overage_prob) + self.recipients.append(self.events_and_prob[i]) + self.build_table() + + def probability_check(self): + i = 0 + for el in self.events_and_prob: + i += el[1] + if i != 1: + raise ValueError("Вероятности в сумме не дают 1!") + + + def build_table(self): + i = 0 + while self.donors and self.recipients: + donor = self.donors.pop() + recipient = self.recipients.pop() + + donor_event, donor_needed_prob, donor_current_prob = donor + recipient_event, recipient_needed_prob, recipient_current_prob = recipient + + donor_can_give = donor_current_prob - donor_needed_prob + + recipient_current_prob += donor_can_give + + + recipient[2] = recipient_current_prob + if recipient_needed_prob >= recipient_current_prob: + self.recipients.append(recipient) + else: + self.donors.append(recipient) + + barrier = self.overage_prob * i + (self.overage_prob - donor_can_give) + + self.table[i] = [donor_event, recipient_event, barrier] + i += 1 + self.table[-1] = [recipient_event, 0, 1] + + + def printall(self): + for i in range(len(self.table)): + print(self.table[i]) + + + def get_random(self): + random_number = random.random() + line = math.floor(random_number * self.quantity_of_lines) + line = self.table[line] + rational_part = random_number - int(random_number) + if rational_part < line[2]: + return line[0] + return line[1] diff --git a/tests/test_for_walker_class.py b/tests/test_for_walker_class.py new file mode 100644 index 0000000..7bd553b --- /dev/null +++ b/tests/test_for_walker_class.py @@ -0,0 +1,20 @@ +from src.Walker.Walker_class import Walker +import pytest + + +def test_1_prob_occasion(): + walker_scheme = Walker([["A", 1], ["D", 0]]) + assert(walker_scheme.get_random() == "A") + +def test_error(): + with pytest.raises(ValueError, match="Вероятности в сумме не дают 1!"): + walker_scheme = Walker([["A", 0], ["D", 0]]) + +def test_usual_occasion(): + a = Walker([["A", 0.24], ["D", 0.11], ["E", 0.34], ["C", 0.28], ["B", 0.03]]) + print(a.events_and_prob) + +def test_empty_list(): + with pytest.raises(ValueError, match="Переданный список пустой"): + walker_scheme = Walker([]) + From e3b26ee415db12305ed48851851525e765f108e6 Mon Sep 17 00:00:00 2001 From: Yana Kalsina Date: Mon, 15 Dec 2025 15:20:58 +0300 Subject: [PATCH 2/4] used ruff --- src/Walker/Walker_class.py | 6 +----- tests/test_for_walker_class.py | 10 ++++++---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Walker/Walker_class.py b/src/Walker/Walker_class.py index e5de202..c0c67b9 100644 --- a/src/Walker/Walker_class.py +++ b/src/Walker/Walker_class.py @@ -1,9 +1,9 @@ import random import math + class Walker: def __init__(self, events_and_prob): - if not events_and_prob: raise ValueError("Переданный список пустой") self.events_and_prob = events_and_prob @@ -32,7 +32,6 @@ def probability_check(self): if i != 1: raise ValueError("Вероятности в сумме не дают 1!") - def build_table(self): i = 0 while self.donors and self.recipients: @@ -46,7 +45,6 @@ def build_table(self): recipient_current_prob += donor_can_give - recipient[2] = recipient_current_prob if recipient_needed_prob >= recipient_current_prob: self.recipients.append(recipient) @@ -59,12 +57,10 @@ def build_table(self): i += 1 self.table[-1] = [recipient_event, 0, 1] - def printall(self): for i in range(len(self.table)): print(self.table[i]) - def get_random(self): random_number = random.random() line = math.floor(random_number * self.quantity_of_lines) diff --git a/tests/test_for_walker_class.py b/tests/test_for_walker_class.py index 7bd553b..b19a7e0 100644 --- a/tests/test_for_walker_class.py +++ b/tests/test_for_walker_class.py @@ -4,17 +4,19 @@ def test_1_prob_occasion(): walker_scheme = Walker([["A", 1], ["D", 0]]) - assert(walker_scheme.get_random() == "A") + assert walker_scheme.get_random() == "A" + def test_error(): with pytest.raises(ValueError, match="Вероятности в сумме не дают 1!"): - walker_scheme = Walker([["A", 0], ["D", 0]]) + Walker([["A", 0], ["D", 0]]) + def test_usual_occasion(): a = Walker([["A", 0.24], ["D", 0.11], ["E", 0.34], ["C", 0.28], ["B", 0.03]]) print(a.events_and_prob) + def test_empty_list(): with pytest.raises(ValueError, match="Переданный список пустой"): - walker_scheme = Walker([]) - + Walker([]) From e78ec5876a19a4b393d9a16a1bf772961a7f75bf Mon Sep 17 00:00:00 2001 From: Yana Kalsina Date: Mon, 15 Dec 2025 15:26:26 +0300 Subject: [PATCH 3/4] Remove one test --- tests/test_for_walker_class.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/test_for_walker_class.py b/tests/test_for_walker_class.py index b19a7e0..2c077f6 100644 --- a/tests/test_for_walker_class.py +++ b/tests/test_for_walker_class.py @@ -12,11 +12,6 @@ def test_error(): Walker([["A", 0], ["D", 0]]) -def test_usual_occasion(): - a = Walker([["A", 0.24], ["D", 0.11], ["E", 0.34], ["C", 0.28], ["B", 0.03]]) - print(a.events_and_prob) - - def test_empty_list(): with pytest.raises(ValueError, match="Переданный список пустой"): Walker([]) From c1249e56ccce1ec92e90435f2dad986bf1082bdd Mon Sep 17 00:00:00 2001 From: Yana Kalsina Date: Mon, 15 Dec 2025 15:29:04 +0300 Subject: [PATCH 4/4] Add one test --- tests/test_for_walker_class.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_for_walker_class.py b/tests/test_for_walker_class.py index 2c077f6..6ef69a3 100644 --- a/tests/test_for_walker_class.py +++ b/tests/test_for_walker_class.py @@ -15,3 +15,8 @@ def test_error(): def test_empty_list(): with pytest.raises(ValueError, match="Переданный список пустой"): Walker([]) + + +def test_error_sum_under_one(): + with pytest.raises(ValueError, match="Вероятности в сумме не дают 1!"): + Walker([["A", 0.5], ["D", 0.4]]) \ No newline at end of file