Skip to content

Commit 189feb4

Browse files
committed
Add function point for ending markov chain
continue-fn function parameter is used to supply a function, which controls if the chain is continuing or if it has reached end. Reason for this is to enable different kinds of chains, for example those that may contain nil elements or other falsey items.
1 parent ccd8410 commit 189feb4

File tree

2 files changed

+13
-11
lines changed

2 files changed

+13
-11
lines changed

src/pyherc/markov.hy

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@
2323
(require pyherc.macros)
2424
(import random)
2525

26-
(defn chain-factory [start-elements elements]
26+
(defn chain-factory [start-elements elements continue-fn]
2727
"create factory function that can create markov chain instances"
2828
(fn []
2929
"create generator for chain"
3030
(defn select-next-element [elements-list]
3131
"select element"
32-
(let [[high (max (list-comp upper [#t(element lower upper) elements-list]))]
32+
(let [[high (max (list-comp upper [#t (element lower upper) elements-list]))]
3333
[value (.randint random 0 high)]
34-
[matches (list-comp element [#t(element lower upper) elements-list]
34+
[matches (list-comp element [#t (element lower upper) elements-list]
3535
(> lower value upper))]]
3636
(if matches
3737
(first (.choice random matches))
@@ -42,9 +42,7 @@
4242
(yield current-element)
4343
(while running
4444
(setv next-elements (get elements current-element))
45-
(if next-elements
46-
(setv current-element (select-next-element next-elements))
47-
(setv running false))
45+
(setv current-element (select-next-element next-elements))
46+
(setv running (continue-fn current-element))
4847
(when (not running) (break))
4948
(yield current-element))))
50-

src/pyherc/test/unit/test_markov.hy

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030

3131
(background infinite-foo-chain
3232
[factory (chain-factory :start-elements [#t("foo" 1 100)]
33-
:elements {"foo" [#t("foo" 1 100)]})]
33+
:elements {"foo" [#t("foo" 1 100)]}
34+
:continue-fn (fn [item] true))]
3435
[chain (factory)])
3536

3637
(fact "first element of chain can be read"
@@ -45,7 +46,8 @@
4546

4647
(background one-element-chain
4748
[factory (chain-factory :start-elements [#t("foo" 1 100)]
48-
:elements {"foo" []})]
49+
:elements {"foo" [#t(nil 1 100)]}
50+
:continue-fn (fn [item] (not (is item nil))))]
4951
[chain (factory)])
5052

5153
(fact "one element markov chain contains only one element"
@@ -58,7 +60,8 @@
5860
(background flip-flop-chain
5961
[factory (chain-factory :start-elements [#t("flip" 1 100)]
6062
:elements {"flip" [#t("flop" 1 100)]
61-
"flop" [#t("flip" 1 100)]})]
63+
"flop" [#t("flip" 1 100)]}
64+
:continue-fn (fn [item] true))]
6265
[chain (factory)])
6366

6467
(fact "markov chain can switch between states"
@@ -76,7 +79,8 @@
7679
"bar" [#t("foo" 1 50)
7780
#t("baz" 51 100)]
7881
"baz" [#t("foo" 1 50)
79-
#t("bar" 51 100)]})]
82+
#t("bar" 51 100)]}
83+
:continue-fn (fn [item] true))]
8084
[chain (factory)])
8185

8286
(fact "markov chain can have multiple transitions from single element"

0 commit comments

Comments
 (0)