code wiki / _hdl_build / nx_price_hist_gate.nx
nx_price_hist_gate.nx source
↩ module page · 113 lines · 7678 B
1// nx_price_hist_gate.nx -- GATE: price history + trends (R-PRICE-R1). T1 additive series (4 dated observations,
2// earliest intact). T2 rising trend (milk +$0.22). T3 falling trend (eggs -$0.40). T4 flat (bread $0). T5 basket
3// trend = sum (-$0.18, cheaper overall) + per-item range. T6 trend page renders + ships; nx_price's pr_get_price
4// still returns the latest (backward compatible). license_tier: ORIGINAL
5import "nx_price_hist.nx"
6import "nx_publisher.nx"
7import "nx_seg_store.nx"
8import "nx_syscalls.nx"
9
10const PH_PRICE: *u8 = "knowledge/store/phist-price-"
11const PH_STAGE_FILE: *u8 = "knowledge/staging/phist/trends.html"
12const PH_LIVE_FILE: *u8 = "knowledge/publish/phist-live/trends.html"
13
14func g_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
15func g_i(v: i64) -> i64 {
16 let bb: *u8 = sys_mmap(28); var m: i64 = v
17 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
18 let t: *u8 = sys_mmap(28); var k: i64 = 0
19 if m == 0 { t[0] = 48 as u8; k = 1 }
20 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
21 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(1, bb, k); return 0
22}
23func g_exists(path: *u8) -> i64 { let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 } sys_close(fd); return 1 }
24
25func main() -> i64 {
26 g_p("=== nx_price_hist_gate (R-PRICE-R1: price history + trends) ===\n" as *u8)
27 pr_add_store(PH_PRICE, "walmart_atx" as *u8, "Walmart Supercenter" as *u8, "Walmart" as *u8, "TX-Austin" as *u8, "TX" as *u8, "receipt" as *u8)
28
29 // record a 4-week series per item
30 ph_record(PH_PRICE, "walmart_atx" as *u8, "milk" as *u8, 298, 100, "receipt" as *u8)
31 ph_record(PH_PRICE, "walmart_atx" as *u8, "milk" as *u8, 305, 107, "receipt" as *u8)
32 ph_record(PH_PRICE, "walmart_atx" as *u8, "milk" as *u8, 312, 114, "receipt" as *u8)
33 ph_record(PH_PRICE, "walmart_atx" as *u8, "milk" as *u8, 320, 121, "receipt" as *u8)
34 ph_record(PH_PRICE, "walmart_atx" as *u8, "eggs" as *u8, 280, 100, "receipt" as *u8)
35 ph_record(PH_PRICE, "walmart_atx" as *u8, "eggs" as *u8, 270, 107, "receipt" as *u8)
36 ph_record(PH_PRICE, "walmart_atx" as *u8, "eggs" as *u8, 255, 114, "receipt" as *u8)
37 ph_record(PH_PRICE, "walmart_atx" as *u8, "eggs" as *u8, 240, 121, "receipt" as *u8)
38 ph_record(PH_PRICE, "walmart_atx" as *u8, "bread" as *u8, 150, 100, "receipt" as *u8)
39 ph_record(PH_PRICE, "walmart_atx" as *u8, "bread" as *u8, 150, 114, "receipt" as *u8)
40 ph_record(PH_PRICE, "walmart_atx" as *u8, "bread" as *u8, 150, 121, "receipt" as *u8)
41
42 let items: *i64 = sys_mmap(8 * 8) as *i64
43 items[0] = "milk" as *u8 as i64; items[1] = "eggs" as *u8 as i64; items[2] = "bread" as *u8 as i64
44
45 var pass: i64 = 0
46 var tot: i64 = 0
47
48 // T1 additive series
49 let cnt: i64 = ph_count(PH_PRICE, "walmart_atx" as *u8, "milk" as *u8)
50 let first: i64 = ph_at(PH_PRICE, "walmart_atx" as *u8, "milk" as *u8, 0)
51 g_p("milk series=" as *u8); g_i(cnt); g_p(" first=" as *u8); g_i(first); g_p("\n" as *u8)
52 tot = tot + 1
53 if cnt == 4 { if first == 298 { pass = pass + 1; g_p("PASS T1 additive series: 4 dated observations, earliest (298) intact after later records\n" as *u8) } else { g_p("FAIL T1 first\n" as *u8) } } else { g_p("FAIL T1 cnt=" as *u8); g_i(cnt); g_p("\n" as *u8) }
54
55 // T2 rising
56 let mt: i64 = ph_trend(PH_PRICE, "walmart_atx" as *u8, "milk" as *u8)
57 g_p("milk trend=" as *u8); g_i(mt); g_p(" dir=" as *u8); g_i(ph_trend_dir(PH_PRICE, "walmart_atx" as *u8, "milk" as *u8)); g_p("\n" as *u8)
58 tot = tot + 1
59 if mt == 22 { if ph_trend_dir(PH_PRICE, "walmart_atx" as *u8, "milk" as *u8) == 1 { pass = pass + 1; g_p("PASS T2 rising trend: milk +$0.22 over the series (dir +1)\n" as *u8) } else { g_p("FAIL T2 dir\n" as *u8) } } else { g_p("FAIL T2 mt=" as *u8); g_i(mt); g_p("\n" as *u8) }
60
61 // T3 falling
62 let et: i64 = ph_trend(PH_PRICE, "walmart_atx" as *u8, "eggs" as *u8)
63 g_p("eggs trend=" as *u8); g_i(et); g_p(" dir=" as *u8); g_i(ph_trend_dir(PH_PRICE, "walmart_atx" as *u8, "eggs" as *u8)); g_p("\n" as *u8)
64 tot = tot + 1
65 if et == (0 - 40) { if ph_trend_dir(PH_PRICE, "walmart_atx" as *u8, "eggs" as *u8) == (0 - 1) { pass = pass + 1; g_p("PASS T3 falling trend: eggs -$0.40 (dir -1)\n" as *u8) } else { g_p("FAIL T3 dir\n" as *u8) } } else { g_p("FAIL T3 et=" as *u8); g_i(et); g_p("\n" as *u8) }
66
67 // T4 flat
68 let bt: i64 = ph_trend(PH_PRICE, "walmart_atx" as *u8, "bread" as *u8)
69 g_p("bread trend=" as *u8); g_i(bt); g_p(" dir=" as *u8); g_i(ph_trend_dir(PH_PRICE, "walmart_atx" as *u8, "bread" as *u8)); g_p("\n" as *u8)
70 tot = tot + 1
71 if bt == 0 { if ph_trend_dir(PH_PRICE, "walmart_atx" as *u8, "bread" as *u8) == 0 { pass = pass + 1; g_p("PASS T4 flat: bread $0.00 change (dir 0)\n" as *u8) } else { g_p("FAIL T4 dir\n" as *u8) } } else { g_p("FAIL T4 bt=" as *u8); g_i(bt); g_p("\n" as *u8) }
72
73 // T5 basket trend + range
74 let bask: i64 = ph_basket_trend(PH_PRICE, "walmart_atx" as *u8, items, 3)
75 let mn: i64 = ph_min(PH_PRICE, "walmart_atx" as *u8, "milk" as *u8)
76 let mx: i64 = ph_max(PH_PRICE, "walmart_atx" as *u8, "milk" as *u8)
77 g_p("basket trend=" as *u8); g_i(bask); g_p(" milk range=" as *u8); g_i(mn); g_p("-" as *u8); g_i(mx); g_p("\n" as *u8)
78 tot = tot + 1
79 var ok5: i64 = 1
80 if bask != (0 - 18) { ok5 = 0 } // +22 -40 +0
81 if mn != 298 { ok5 = 0 }
82 if mx != 320 { ok5 = 0 }
83 if ok5 == 1 { pass = pass + 1; g_p("PASS T5 basket trend -$0.18 (cheaper overall); milk range $2.98-$3.20\n" as *u8) } else { g_p("FAIL T5\n" as *u8) }
84
85 // T6 render + ship + backward compat
86 let page: *u8 = sys_mmap(65536)
87 let np: i64 = ph_render_trend(PH_PRICE, "walmart_atx" as *u8, items, 3, page)
88 let latest: i64 = pr_get_price(PH_PRICE, "walmart_atx" as *u8, "milk" as *u8)
89 g_p("page=" as *u8); g_i(np); g_p(" bytes; pr_get_price(milk)=" as *u8); g_i(latest); g_p("\n" as *u8)
90 tot = tot + 1
91 var ok6: i64 = 1
92 if latest != 320 { ok6 = 0 } // backward compat: latest observation
93 if as_has_thirdparty_js(page, np) != 0 { ok6 = 0 }
94 if as_contains(page, np, "rising" as *u8) != 1 { ok6 = 0 }
95 if as_contains(page, np, "falling" as *u8) != 1 { ok6 = 0 }
96 if as_contains(page, np, "flat" as *u8) != 1 { ok6 = 0 }
97 if as_contains(page, np, "not a prediction" as *u8) != 1 { ok6 = 0 }
98 sys_mkdir("knowledge/staging" as *u8, 0x1ed)
99 sys_mkdir("knowledge/staging/phist" as *u8, 0x1ed)
100 let sfd: i64 = sys_openat_wr(PH_STAGE_FILE, 420); if sfd >= 0 { sys_write(sfd, page, np); sys_close(sfd) }
101 pub_init()
102 sys_mkdir("knowledge/publish/phist-stage" as *u8, 0x1ed)
103 sys_mkdir("knowledge/publish/phist-live" as *u8, 0x1ed)
104 pub_submit_to("knowledge/publish/phist-queue.tsv" as *u8, PH_STAGE_FILE, "trends.html" as *u8, "nishifoodfamily" as *u8, "nishi-phist" as *u8, "internal" as *u8)
105 pub_run_full("knowledge/publish/phist-queue.tsv" as *u8, "knowledge/publish/phist-ledger.tsv" as *u8, "knowledge/publish/phist-stage" as *u8, "knowledge/publish/phist-live" as *u8, "publish:phist" as *u8)
106 if g_exists(PH_LIVE_FILE) != 1 { ok6 = 0 }
107 if ok6 == 1 { pass = pass + 1; g_p("PASS T6 trend page renders sovereign + ships; pr_get_price still returns the latest (backward compatible)\n" as *u8) } else { g_p("FAIL T6\n" as *u8) }
108
109 g_p("nx_price_hist_gate pass=" as *u8); g_i(pass); g_p("/" as *u8); g_i(tot)
110 if pass == tot { g_p(" verdict=GREEN (how prices are MOVING, from recorded dated observations -- not a prediction)\n" as *u8); return 0 }
111 g_p(" verdict=RED\n" as *u8)
112 return 1
113}