From c93e175e5d4526c8ee10648edf27fb88bcc1e5a9 Mon Sep 17 00:00:00 2001
From: Tue Herlau <tuhe@dtu.dk>
Date: Sun, 9 Feb 2025 15:37:03 +0100
Subject: [PATCH] Tests for week 2

---
 irlc/tests/tests_week02.py                    | 245 ++++++++++++++++++
 .../ExamQuestion7FlowersStore.pkl             | Bin 0 -> 182 bytes
 .../unitgrade_data/Problem1BobsFriend.pkl     | Bin 170 -> 170 bytes
 .../unitgrade_data/Problem2BobsPolicy.pkl     | Bin 368 -> 368 bytes
 .../Problem2DeterministicDP.pkl               | Bin 0 -> 161 bytes
 .../Problem2DeterministicInventory.pkl        | Bin 0 -> 128 bytes
 .../Problem3InventoryInventoryEnvironment.pkl | Bin 323 -> 323 bytes
 .../unitgrade_data/Problem3StochasticDP.pkl   | Bin 0 -> 345 bytes
 irlc/tests/unitgrade_data/Problem4DPAgent.pkl | Bin 0 -> 121 bytes
 .../unitgrade_data/Problem4InventoryTrain.pkl | Bin 242 -> 242 bytes
 .../Problem5PacmanHardcoded.pkl               | Bin 125 -> 125 bytes
 .../Problem6ChessTournament.pkl               | Bin 197 -> 197 bytes
 12 files changed, 245 insertions(+)
 create mode 100644 irlc/tests/tests_week02.py
 create mode 100644 irlc/tests/unitgrade_data/ExamQuestion7FlowersStore.pkl
 create mode 100644 irlc/tests/unitgrade_data/Problem2DeterministicDP.pkl
 create mode 100644 irlc/tests/unitgrade_data/Problem2DeterministicInventory.pkl
 create mode 100644 irlc/tests/unitgrade_data/Problem3StochasticDP.pkl
 create mode 100644 irlc/tests/unitgrade_data/Problem4DPAgent.pkl

diff --git a/irlc/tests/tests_week02.py b/irlc/tests/tests_week02.py
new file mode 100644
index 0000000..a44d25b
--- /dev/null
+++ b/irlc/tests/tests_week02.py
@@ -0,0 +1,245 @@
+# This file may not be shared/redistributed without permission. Please read copyright notice in the git repo. If this file contains other copyright notices disregard this text.
+# from irlc.ex02.graph_traversal import pi_inc, pi_smart, pi_silly, policy_rollout, SmallGraphDP
+from collections import defaultdict
+from unitgrade import Report
+import irlc
+from unitgrade import UTestCase
+from irlc.ex02.inventory import InventoryDPModel, DP_stochastic
+from irlc.ex02.deterministic_inventory import DeterministicInventoryDPModel
+
+def gN_dp(self, env):
+    for s in sorted(self.env.S(self.env.N)):
+        self.assertLinf(self.env.gN(s))
+
+def f_dp(self, env):
+    self.assertEqualC(self.env.N)
+
+    for k in range(self.env.N):
+        for s in sorted(self.env.S(k)):
+            for a in sorted(self.env.A(s,k)):
+                from collections import defaultdict
+
+                dd_f = defaultdict(float)
+                # dd_g = defaultdict(float)
+
+                for w, pw in self.env.Pw(s,a,k).items():
+                    dd_f[(s,a, self.env.f(s,a,w,k))] += pw
+                    # dd_g[(s, a, self.env.g(s, a, w, k))] += pw
+
+                # Check transition probabilities sum to 1.
+                self.assertAlmostEqual(sum(dd_f.values()), 1, places=6)
+                # self.assertAlmostEqual(sum(dd_g.values()), 1, places=6)
+
+                for key in sorted(dd_f.keys()):
+                    self.assertEqualC(key)
+                    self.assertLinf(dd_f[key], tol=1e-7)
+
+                # for key in sorted(dd_g.keys()):
+                #     self.assertEqualC(key)
+                #     self.assertLinf(dd_g[key], tol=1e-7)
+
+def g_dp(self, env):
+    for k in range(self.env.N):
+        for s in sorted(self.env.S(k)):
+            for a in sorted(self.env.A(s, k)):
+
+                # dd_f = defaultdict(float)
+                dd_g = defaultdict(float)
+
+                for w, pw in self.env.Pw(s, a, k).items():
+                    # dd_f[(s, a, self.env.f(s, a, w, k))] += pw
+                    dd_g[(s, a, self.env.g(s, a, w, k))] += pw
+
+                # Check transition probabilities sum to 1.
+                # self.assertAlmostEqual(sum(dd_f.values()), 1, places=6)
+                self.assertAlmostEqual(sum(dd_g.values()), 1, places=6)
+
+                # for key in sorted(dd_f.keys()):
+                #     self.assertEqualC(key)
+                #     self.assertLinf(dd_f[key], tol=1e-7)
+
+                for key in sorted(dd_g.keys()):
+                    self.assertEqualC(key)
+                    self.assertLinf(dd_g[key], tol=1e-7)
+
+
+
+
+class Problem2DeterministicInventory(UTestCase):
+    @property
+    def model(self):
+        return DeterministicInventoryDPModel()
+
+    def test_Pw(self):
+        for k in range(self.model.N):
+            self.assertEqual(self.model.Pw(0, 1, k), {k+1: 1} )
+
+
+
+    # def test_f(self):
+    #     f_dp(self, self.env)
+
+    # def test_g(self):
+    #     g_dp(self, self.env)
+    #
+    # def test_gN(self):
+    #     gN_dp(self, self.env)
+
+
+class Problem3StochasticDP(UTestCase):
+    """ Inventory control """
+    def test_policy(self):
+        inv = InventoryDPModel()
+        J, pi = DP_stochastic(inv)
+
+        # Test action at time step N-1
+        self.assertEqual(pi[-1][0], 1)
+        self.assertEqual(pi[-1][1], 0)
+        self.assertEqual(pi[-1][2], 0)
+
+        # test all actions at time step N-1
+        self.assertEqualC(pi[-1])
+
+        # Test all actions at all time steps
+        self.assertEqualC(pi)
+
+    def test_J(self):
+        inv = InventoryDPModel()
+        J, pi = DP_stochastic(inv)
+
+        self.assertLinf(J[-1][0], tol=1e-8)
+        self.assertLinf(J[-1][1], tol=1e-8)
+        self.assertLinf(J[-1][2], tol=1e-8)
+        
+        for k in range(len(J)):
+            for x in [0,1,2]:
+                print("testing", J[k][x])
+                self.assertLinf(J[k][x], tol=1e-8)
+
+class Problem4DPAgent(UTestCase):
+    def test_agent(self):
+        from irlc.ex01.inventory_environment import InventoryEnvironment
+        from irlc.ex02.inventory import InventoryDPModel
+        from irlc.ex02.dp_agent import DynamicalProgrammingAgent
+        env = InventoryEnvironment(N=3)
+        inventory = InventoryDPModel(N=3)
+        agent = DynamicalProgrammingAgent(env, model=inventory)
+        s0, _ = env.reset()
+        self.assertEqualC(agent.pi(s0, 0)) # We just test the first action.
+
+
+# class DPChessMatch(UTestCase):
+#     """ Chessmatch """
+#     def test_J(self):
+#         N = 2
+#         pw = 0.45
+#         pd = 0.8
+#         cm = ChessMatch(N, pw=pw, pd=pd)
+#         J, pi = DP_stochastic(cm)
+#         self.assertLinf(J[-1][0], tol=1e-4)
+#         self.assertLinf(J[-2][0], tol=1e-4)
+#         self.assertLinf(J[0][0], tol=1e-4)
+
+
+
+
+# class SmallGraphPolicies(UTestCase):
+#     """ Test the policies in the small graph environment """
+#     def test_pi_smart(self):
+#         self.assertEqual(pi_smart(1, 0), 5)
+#
+#     def test_pi_inc(self):
+#         from irlc.ex02.graph_traversal import pi_inc, pi_smart, pi_silly
+#         for k in range(5):
+#             self.assertEqual(pi_inc(k+1, k), k+2)
+#             # self.assertEqual(pi_smart(k + 1, k), 5)
+#             # self.assertEqual(pi_smart(k + 1, k), 5)
+#
+#     def test_rollout(self):
+#         # self.assertEqual(3, 1)
+#         t = 5
+#         x0 = 1  # starting node
+#         model = SmallGraphDP(t=t)
+#
+#         self.assertEqualC(policy_rollout(model, pi_silly, x0)[0])
+#         self.assertEqualC(policy_rollout(model, pi_smart, x0)[0])
+#         self.assertEqualC(policy_rollout(model, pi_inc, x0)[0])
+
+class Problem2DeterministicDP(UTestCase):
+    def test_dp_deterministic(self):
+        model = DeterministicInventoryDPModel()
+        J, pi = DP_stochastic(model)
+
+        self.assertLinf(J[-1][0], tol=1e-5)
+        self.assertLinf(J[-1][1], tol=1e-5)
+        self.assertLinf(J[-1][2], tol=1e-5)
+
+        self.assertLinf(J[0][0], tol=1e-5)
+        self.assertLinf(J[0][1], tol=1e-5)
+        self.assertLinf(J[0][2], tol=1e-5)
+
+
+
+# class TestInventoryModel(UTestCase):
+#     @property
+#     def env(self):
+#         return InventoryDPModel()
+#
+#     def test_gN(self):
+#         gN_dp(self, self.env)
+#
+#     def test_f(self):
+#         f_dp(self, self.env)
+#
+#     def test_g(self):
+#         g_dp(self, self.env)
+
+
+
+# class TestFrozenDP(UTestCase):
+#     @property
+#     def env(self):
+#         return Gym2DPModel(gym_env=gym.make("FrozenLake-v1"))
+#
+#     def test_f(self):
+#         f_dp(self, self.env)
+#
+#     def test_g(self):
+#         g_dp(self, self.env)
+
+class ExamQuestion7FlowersStore(UTestCase):
+    def test_a_get_policy(self):
+        from irlc.ex02.flower_store import a_get_policy
+        x0 = 0
+        c = 0.5
+        N = 3
+        self.assertEqual(a_get_policy(N, c, x0), 1)
+
+    def test_b_prob_empty(self):
+        from irlc.ex02.flower_store import b_prob_one
+        x0 = 0
+        N = 3
+        self.assertAlmostEqual(b_prob_one(N, x0), 0.492, places=2)
+
+
+class Week02Tests(Report):
+    title = "Tests for week 02"
+    pack_imports = [irlc]
+    individual_imports = []
+    questions = [
+        (Problem2DeterministicInventory, 10),
+        (Problem2DeterministicDP, 10),
+        (Problem3StochasticDP, 10),
+        (Problem4DPAgent, 10),
+        (ExamQuestion7FlowersStore, 10),
+         ]
+
+
+# (SmallGraphPolicies, 10),
+# (TestInventoryModel, 10),
+# (DPChessMatch, 10),
+# (TestFrozenDP, 10),
+
+if __name__ == '__main__':
+    from unitgrade import evaluate_report_student
+    evaluate_report_student(Week02Tests() )
diff --git a/irlc/tests/unitgrade_data/ExamQuestion7FlowersStore.pkl b/irlc/tests/unitgrade_data/ExamQuestion7FlowersStore.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..3a41422a4848e047416f41a3c076329eb948029e
GIT binary patch
literal 182
zcmZo*nYx+*0&1sd^hml^B<2Q|rWTiE=I5Ea<>Z&A78M7V<QJt*>ES9)EeS1f&PgmT
zp3*j@hovMlHx<Zmx7XMKHXwtsN3aB_Gd?jsJ+&mhAU`KFxe}z34X7ivs07HYosz+r
p!PYh<g9W57tPxdTQhY&Ceo}mDZb1o1Uj_$M120U2HN>H%dH@lZKdAr!

literal 0
HcmV?d00001

diff --git a/irlc/tests/unitgrade_data/Problem1BobsFriend.pkl b/irlc/tests/unitgrade_data/Problem1BobsFriend.pkl
index 34289b45933e7cb0b5e5674272678d0a7e985f75..a86dd5b0e7c13cf8c4be0dfa949b137852788998 100644
GIT binary patch
delta 29
hcmZ3*xQcOtEt7%7M0-;v>4J%6T3q(x3}8^I2LNzg1~dQw

delta 29
icmZ3*xQcOtEtA-XiT0*UtPT^)w7BfPIxv7hsU84@Z3oE!

diff --git a/irlc/tests/unitgrade_data/Problem2BobsPolicy.pkl b/irlc/tests/unitgrade_data/Problem2BobsPolicy.pkl
index f70500921e9a5df596b27587b0c9ab8b3ee15767..72a599053dc44ab84dc195cb4ebc7c5a794c5505 100644
GIT binary patch
delta 58
zcmeys^nq!DEt6`*M0+D<IRS==tK}w65@TL4U0~vB6XvV3Mw8VT<t8yIGhffG05Tmp
MPsz<<0D@9I03%%yP5=M^

delta 58
zcmeys^nq!DEt6=&M0+D<o&yXMSIbSDB*r|s^25Z{Cd?P^xK37Ml$*q;%zSXm3Lw*w
N^TMVV3_wt-2LOC|6wd$v

diff --git a/irlc/tests/unitgrade_data/Problem2DeterministicDP.pkl b/irlc/tests/unitgrade_data/Problem2DeterministicDP.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..2602ec1f27c0a3df88b9d17b35e81725e6396148
GIT binary patch
literal 161
zcmZo*nL3RD0&1sd^oR!(<tOE&<{G)AmZTQtX69uUmt-cp1Wf7SDo!m4EpX0BEH0kX
zHl>H9Br`V^$Z)rpSpe3a!Pp~Ol3H96pHdK?f~*;&nhmHcwWtKh1X|+F0ECP{%ml>D
d-fZ41-mD;4n!%XC);1-B1!QW31K8A3JpelSGhP4y

literal 0
HcmV?d00001

diff --git a/irlc/tests/unitgrade_data/Problem2DeterministicInventory.pkl b/irlc/tests/unitgrade_data/Problem2DeterministicInventory.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..d44b5e7934fe5d42c959c37d63139bbec2712c37
GIT binary patch
literal 128
zcmZo*nOe#K0ku;!dgKC%@{@8>bB$b5OHzw+GxIWwOEQx^^U6~5O7e>;r}S_Yr<Q~k
zIOil57f)%M(!)}cnVSk^xZ6t~0GpD**u!3uT3iwzP!5u31FB0cDgiQUr(`f@u(eIe
OU;(M-Qvj<j)dK)FA1nm`

literal 0
HcmV?d00001

diff --git a/irlc/tests/unitgrade_data/Problem3InventoryInventoryEnvironment.pkl b/irlc/tests/unitgrade_data/Problem3InventoryInventoryEnvironment.pkl
index 8a114ca18a3007af260497124c33780495b358b0..bc83d14477a92bec3b5b271606c7f222766e5878 100644
GIT binary patch
delta 81
zcmX@ibeL&E0F%sxi9zkMKY|}Goy{V6U`pGRpee-}j2UcgQ!-fErnuXmJFGSFo0f9!
X^WQ5!UJ^hkkcKI^H`j>)2uk$;$Q&ZN

delta 81
zcmX@ibeL&E027bG#GrQB%f3kh5jzDAOlg}EG^IF$F@vpbN(M{Y6nFchFAFAq(^8)I
We)%!)?MMowVG7Q^KEVJ4rFsBZv>}lI

diff --git a/irlc/tests/unitgrade_data/Problem3StochasticDP.pkl b/irlc/tests/unitgrade_data/Problem3StochasticDP.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..0ecab18dfadf9378612164c8674f514ebb107561
GIT binary patch
literal 345
zcmZo*nd-;L00y;FG<rk=it>|kQge-iOY)O55{pYRlU)L)^l%lYmV_2K=Oh*vPidRd
z!%~u&n+jyO+lx7XwPrB(aF?VOm&6z3=VT^Vg4D19)utAe0GU8@y&1rSHzN=-cr$r3
zlzKD9PSHRYMCWI4r<P_gX0WwQ$zTE5W`6=^8yna*FQDle98ep8215<^W_EYroe2is
zEbb1hVAd>eR(A)sZs)0uY^vUD?hY(qqZqu|-R*xsnH=u+zaF};6RCRW&FOCc<qQa%
q_2zQ7zibQwCf?lc_8*~!@c^yk1!6v+Uw}>&ggG%oxB+BZsU84->uPWS

literal 0
HcmV?d00001

diff --git a/irlc/tests/unitgrade_data/Problem4DPAgent.pkl b/irlc/tests/unitgrade_data/Problem4DPAgent.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..59bca418024401c8a678b7ae1a25fe415ae7524e
GIT binary patch
literal 121
zcmZo*nVQD{0ku;!diVp1@{@8>b4^?V9Me<tN~ZL16{nVj7C7f578g%xo6^Hll9`(d
zWVqXlIe@igF!pejq!yRNCxX=jm9PPorWTa|71d7hX7FY#&S1=7Ynzh60@7tK1J+fl
F2LN#+Cr<zX

literal 0
HcmV?d00001

diff --git a/irlc/tests/unitgrade_data/Problem4InventoryTrain.pkl b/irlc/tests/unitgrade_data/Problem4InventoryTrain.pkl
index efd9f275aa8d0a83d557df08d6486ef4c547e5ec..a1233b45ac6edd30a990aa8a2241521ddc37c496 100644
GIT binary patch
delta 48
zcmeyw_=$0XBa`@qiOxOBx|`;{Uw%yBz?8NrK~st|7&F+~rev_RO>wv1{I`Pv2uk$;
D{Qnbc

delta 48
zcmeyw_=$0XBa?E#MCTsmrx%oN|NJL#U`pGRpee-}j2UcgQ!-fErnuX0n6-rg2uk$;
D4nh;o

diff --git a/irlc/tests/unitgrade_data/Problem5PacmanHardcoded.pkl b/irlc/tests/unitgrade_data/Problem5PacmanHardcoded.pkl
index 38874049df6b13f41b7a25f2ca24dd44aaadbe8a..aff88fcf08ef6fbc135cc403e12dce3c6e3003df 100644
GIT binary patch
delta 20
acmb=eo#4bIUNF(cfOAPp00R(|>Hz>lT?Kyt

delta 20
acmb=eo#4d8r!djQfU}Kp0Rs?}>Hz>dfCSY5

diff --git a/irlc/tests/unitgrade_data/Problem6ChessTournament.pkl b/irlc/tests/unitgrade_data/Problem6ChessTournament.pkl
index aef3d60cea9361a43ac33ec618dd55824929c86b..3dfef9dde23436f022b46f89d8dcaf29cee5dc37 100644
GIT binary patch
delta 22
dcmX@gc$9I16O*dIM3)Lq#+>sF3=9mVdH_#$21@_{

delta 22
dcmX@gc$9I16O-<ai7pkK425M03=9mVdH_}q28I9t

-- 
GitLab