概要
退屈なことはPythonにやらせようという本がある。
とてもよさげな本っぽいので、いつか読みたい。
が、今お金とか時間とかの都合でなかなか手が出せない。
どうするか考えた結果、退屈なことをPythonにやらせる為のlua
を学ぶ事にした。
なぜなら手元に本があったから。
方針としては、
- Python -> 退屈なことをする
- lua -> 退屈なことを生み出す
何言ってるかわからないかもしれないので、先に結果を出そう。
結果
結果を見てもよく分からないねコレ
一応コードは[こちら]。
言語の役割分担を考える
退屈な事が何か考えた時に、真っ先に思い浮かぶのが人間関係だ。
- 上司からの「俺のほうが経験ある」マウンティング
- チーム内での「俺のほうが知ってる」マウンティング
- よく知らない人からの「何ができるの?」マウンティング
世の中マウンティングだらけ。
つかれるよね
というわけで
- Python -> マウンティングをいなす人
- lua -> マウンティングする人
言葉で説明してもあれなので、図に書いておこう。
luaでマウンティングする
早速luaでマウンティングする人を書いてゆく。
- ストレスを持つ
- ストレスには限界がある
- 事あるごとにマウンティング
- マウンティングするとストレスが下がる
- 何もしなくてもストレスが上がる
別に個人的な意図はないがクラス名はJoushiにした。
(大事な事なのでもう一回書く。本当に個人的な意図はないです。)
ストレスを持つ
ストレスにも限界を持たせる。
Joushi = {
stress = 0,
stressThreshold = 100,
socket = nil,
}
function Joushi.new()
self = {__index = Joushi}
o = {}
return setmetatable(o, self)
end
事あるごとにマウンティング
事あるごとにを表現するのは難しい。今のところはランダムで待つ。(*1)
マウンティングはUDPで実装する。マウンティングはTCPみたいに丁寧ではないのだ。
マウンティングは5W1Hにしたがって質問形式のマウンティングを行う。
英語なのはエディタの日本語対応が面倒だったから。
function Joushi.mounting(self)
try {
function()
local socket = require("socket")
local udp = socket.udp()
udp:setsockname("127.0.0.1", 0)
udp:setpeername("127.0.0.1", 1880)
mountingText = self:getMountingText()
udp:send(mountingText)
print('Let\'s mounting!: '..mountingText )
udp:settimeout(3)
local data = udp:receive()
if data == nil then
print("he denied my conversation...")
else
print("now conversation succeed! "..data)
self.stress = self.stress - 10
end
udp:close()
end,
catch {
function(error)
print(error) -- raise errro
end
}
}
end
function utf8_from(t)
local bytearr = {}
for _, v in ipairs(t) do
local utf8byte = v < 0 and (0xff + v + 1) or v
table.insert(bytearr, string.char(utf8byte))
end
return table.concat(bytearr)
end
function Joushi.getMountingText(self)
local r = math.random(7)
if r == 1 then
-- when
return "when are you gonna apologize?"
elseif r == 2 then
-- where
return "where were you yesterday?"
elseif r == 3 then
-- who
return "who do you respect?"
elseif r == 4 then
-- what
return "what takes so much time?"
elseif r == 5 then
-- why
return "why can not you?"
elseif r == 6 then
-- how
return "how much are you?"
else
-- direct mounting
return "hey my dog!"
end
end
-- mounting toutine
co = coroutine.create(function()
local r = math.random(10)
while true do
coroutine.yield()
if r <= 0 then
joushi:mounting()
r = math.random(10)
else
r = r - 1
end
end
end)
coroutine.resume(co)
こちらをもとにtry-cacheを導入
*1: 今のところはって言っても今後手を付ける予定もない。
マウンティングするとストレスが下がる
マウンティングの成功でストレスを軽減する。
先のサンプルでnow conversation succeed
を言っているところで
self.stress = self.stress - 10
としてある部分
何もしなくてもストレスが上がる
一定間隔でストレスを上げる。
constantStress = coroutine.create(function()
local r = math.random(2)
while true do
coroutine.yield()
if r <= 0 then
joushi.stress = joushi.stress + 10
r = math.random(2)
else
r = r - 1
end
end
end)
coroutine.resume(constantStress)
呼び出してみる
最後にjoushiを呼び出して動作を確認する。死んだら終わりにする。
print('I\'m still alive.')
while true do
socket.sleep(1)
coroutine.resume(co)
coroutine.resume(constantStress)
if joushi:checkStressLimit() then
break
else
print("joushi stress: "..joushi.stress)
end
end
人のストレスには限界がある
pythonでマウンティングをいなす
マウンティングする人ができたので今度はマウンティングをいなす人を書いてゆく。特徴としては
- ストレスを持つ
- マウンティングを受けて対応するし、マウンティングされるとストレスが上がる
- 何もしなくてもストレスが上がる
ストレスを持つ
ここはシンプルにグローバルで持たせる。もちろん限界も持たせる。
上司より容量を持たせる。
stress = 0
deadStressThreshold = 400
マウンティングを受けて対応するし、マウンティングされるとストレスが上がる
ちょっと長いけどUDPで受けてストレス貯めてるだけ。
class MountingStress(threading.Thread):
def __init__(self):
super(MountingStress, self).__init__()
self.lock = threading.Lock()
self.bStop = False
def stop(self):
with self.lock:
self.bStop = True
def run(self):
global stress, deadStressThreshold
host = '127.0.0.1'
port = 1880
buffSize = 2046
while True:
with self.lock:
if self.bStop:
return
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
with closing(sock):
sock.settimeout(1.0)
sock.bind((host, port))
try:
mountText, addr = sock.recvfrom(buffSize)
print("Mount: {0}".format(mountText))
stress += 20
answer = ""
if mountText == b"when are you gonna apologize?":
stress += random.randint(20, 80)
answer = "sorry, I'm wrong human..."
elif mountText == b"where were you yesterday?":
stress += random.randint(20, 80)
answer = "sorry, was at home..."
elif mountText == b"who do you respect?":
stress += random.randint(20, 80)
answer = "just only you!I'm Happy!"
elif mountText == b"what takes so much time?":
stress += random.randint(20, 80)
answer = "sorry, my ability is missing..."
elif mountText == b"why can not you?":
stress += random.randint(20, 80)
answer = "sorry, my ability is wrong..."
elif mountText == b"how much are you?":
stress += random.randint(20, 80)
answer = "sorry, I am not worth..."
elif mountText == b"hey my dog!":
stress += random.randint(20, 80)
answer = "yes! I'm dog! your dog! I'm Happy!"
print("Answer: {0}".format(answer))
print(" - mounting stress: {0}".format(stress))
time.sleep(1)
sock.sendto(bytes(answer, 'utf-8'), addr)
except socket.timeout:
pass
except:
# stress -= 5
import traceback
traceback.print_exc()
if stress < 0:
stress = 0
if stress >= deadStressThreshold:
print("mounting stress break: {0}".format(stress))
break
何もしなくてもストレスが上がる
人なので。
class ConstantStress(threading.Thread):
def __init__(self,interval):
super(ConstantStress, self).__init__()
self.interval = interval
self.lock = threading.Lock()
self.bStop = False
def stop(self):
with self.lock:
self.bStop = True
def run(self):
global stress, deadStressThreshold
while True:
with self.lock:
if self.bStop:
return
if stress >= deadStressThreshold:
print("stress over deadline: {0}".format(stress))
break
stress = stress + 10
time.sleep(self.interval)
print("constant stress break: {0}".format(stress))
呼び出してみる
一定時間経つとちゃんとストレスで(プログラムが)終了する。
def main():
global stress, deadStressThreshold
print('I\'m still alive.')
# constant stress
constantStress = ConstantStress(1)
constantStress.start()
mountingStress = MountingStress()
mountingStress.start()
constantStress.join()
mountingStress.join()
return
if __name__ == "__main__":
main()
より人間らしく
しません。
ふりかえり
ストレスの代わりに血圧という単語を使おうとも思ったが、
リアルに傷つく方がいてはあれなのでやめた。