日記:撤収してsympy
日記。
目の前の問題:
柔軟な原価計算(というか利益管理)の仕組みを作りたかった。
しかし原価計算・利益管理は客先・営業毎に変なロジックが存在する(そして派生する)ため、RDBMS上でそれを網羅する不思議関数・不思議テーブルを作成・維持する事は無理ゲー。
やりたかったこと:
ユーザサイドのビジネスルールをユーザに入力してもらって、これを解く。
手続きを入力させるのではなく、ルールを入力させる。
ぶっちゃけ、STUDENT(1960年ぐらいのプログラム)みたいな事をやりたかった。
RDBMS上で単体で動く事が望ましい。
やってみたこと:
T-SQL上にSchemeに似た言語の実行系を実装、その上に数式処理プログラムを実装することを試みた。
やってみた結果:
生涯労働時間の0.1%ぐらいを投入して(そして今年のゴールデンウィーク前半を全て投入して)T-SQL上にSchemeもどきを仮実装し、それの最適化を試みた結果として、T-SQL上のインタプリタもしくはコンパイラは常識的な処理系の1/10000程度の速度しか得られず(コンパイラにしても全然速くならないんだぜ!)、実用に至らないと判断した。
あと多分合計2万行を超える。メンテできん。
結論:撤収
で、傷心を抱えつつ、Mathematicaかなーでもあいつ面倒だなーもうパーサ書く気力ないなー完全に撤収しようかなー溜まってる他の仕事したくないなーどう言訳しようかなーとかブラブラ検索してたら、驚くべき事実を発見。
python3はユニコード文字を識別子に使用可能らしい。
以下、凄くアレな原理動作確認コード。
これpythonのプログラムなんだぜ。
from sympy import *
鉄の単価_円pkg= symbols('鉄の単価_円pkg')
素線径_mm = symbols('素線径_mm')
全長_mm = symbols('全長_mm')
製品単重_gp本 = symbols('製品単重_gp本')
製品体積_mm3p本= symbols('製品体積_mm3/本')
鉄の比重_gpmm3 = symbols('鉄の比重_g/mm3')
全長と素線径と製品体積 = Eq(製品体積_mm3p本,( (素線径_mm**2)*3.14/4*(全長_mm+ 素線径_mm*1.9)))
製品体積と製品単重 = Eq(製品単重_gp本,製品体積_mm3p本*鉄の比重_gpmm3/1000)
鉄の単価設定 = Eq(鉄の単価_円pkg,130)
全長設定 = Eq(全長_mm,40)
素線径設定 = Eq(素線径_mm,2.3)
鉄の比重設定 = Eq(鉄の比重_gpmm3,7.9)
solve( (全長と素線径と製品体積,製品体積と製品単重,鉄の単価設定,全長設定,素線径設定,素線径設定,鉄の比重設定))
⇒
[{全長_mm: 40.0000000000000,
素線径_mm: 2.30000000000000,
製品体積_mm3/本: 184.253080500000,
製品単重_gp本: 1.45559933595000,
鉄の単価_円pkg: 130.000000000000,
鉄の比重_g/mm3: 7.90000000000000}]
コードが中途半端なのは許せ。これ使うこと前提で行くか。
#本当は条件式付きの関数定義とその地味な変数消去をしたかったんだけどナーナーナー
もうGWは仕事しない…いやそれは無理だが、プログラムはもう止め。
明日は温泉だ!
再帰ってすごい
酔っ払いメモ
正しい事を自分がしているということに幸せを感じると幸せは対価無しでもかなり生産できる。
一行で分かる末尾最適化
「この件この資料を基に任せた。社長に報告しといて。俺に報告要らないから。じゃ!」(逃げ去る上司)
はじめてのScheme
記念に。読むなよはずかしい。
値渡しであることが信じられなかったので処理系インストール。
値渡しだなぁ。
> "HelloWorld"
"HelloWorld"
> '()
'()
> '("HelloWorld")
'("HelloWorld")
> (define vhello "HelloWorld")
> vhello
"HelloWorld"
> (display vhello)
HelloWorld
> (define fhello ( lambda () "HelloWorld"))
> fhello
#<procedure:fhello>
> (fhello)
"HelloWorld"
> (define sayit (lambda () vhello))
> (sayit)
"HelloWorld"
> (define sayit2 (lambda (s) s))
> (sayit2 vhello)
"HelloWorld"
> (define sayit4 (lambda (s)(set! s "GoodByWorld!") s))
> (sayit4 vhello)
"GoodByWorld!"
> vhello
"HelloWorld"
> (define displayit(lambda (s) (display s)))
> (define sayit5(lambda (s l) (l s)))
> (sayit5 vhello displayit)
HelloWorld
> (define displayit2(lambda (s) (display (string-append s "!"))))
> (sayit5 vhello displayit2)
HelloWorld!
> (define sayit6(lambda (s l) (set! l displayit2)(l s)))
> (sayit6 vhello displayit)
HelloWorld!
> (sayit6 vhello displayit2)
HelloWorld!
> (sayit5 vhello displayit)
HelloWorld
???
お前大域変数変更できないの?…タバコ一本吸って気づいた。
> (define changeworld(lambda()(set! vhello "GoodByWorld!") vhello))
> (changeworld)
"GoodByWorld!"
> vhello
"GoodByWorld!"
そりゃそうだ。