Livesense Advent Caelendar 2015 12日目担当の@sion_cojpです。
振り返り・・・
前はインフラエンジニアとして働いており、ムカついたときは上司のターミナルに汽車を走らせてました。
今はWebアプリエンジニアとして部署異動し、APIを開発しております。
この記事をご覧になっている、そこのあなた。
仕事中にこんなことはありませんか?
部署異動したけど、やっぱり上司から無理な依頼をされた。ちくしょう。。。
わかります。その気持ち。ええ。
せっかく異動したんだから、高い寿司とかおごってくれてもいいのに。。
でも異動出来た事には感謝しないとです。社会って複雑ですよね。
#そんな上司の作業中のターミナル(端末)にマトリックスを走らせてやりましょう!!
まずは準備。
①上司が作業しているホストを探そう
何かしらの方法でげっとします。(鬼門)
またまた私は上司のモニターを後ろからこっそり覗いてやりました。
のんびりPHPのレガシーコードと格闘してるわ。
馬鹿め。
上司が開発しているサーバ情報をげっと。
②マトリックスを流すプログラムを書く。
適当に作る。
MATRIX_ANGRY_CHARS に怒りの気持ちをぶつけましょう。
プログラムを流すと分かりますが、怒りの部分はバレないようになってるので安心してください。
MATRIX_THANKS_CHARS には感謝の気持ちを入れましょう。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import locale
import time
import curses
import sys, string
import random
import struct
locale.setlocale(locale.LC_ALL, '')
encoding = locale.getpreferredencoding()
########################################################################
# const
MIN_SPEED = 1
MAX_SPEED = 2
MATRIX_ANGRY_CHARS = "遅刻連絡くらいメールじゃなくてチャットでいいじゃん 波動拳打ち込みたい ほぼ逝きかけました"
MATRIX_THANKS_CHARS = "THANKS DEAR TAKU !!!"
MATRIX_COLOR_WORD = 46
MATRIX_COLOR_BACK = 232
########################################################################
class FallingChar(object):
matrixchr = list(MATRIX_ANGRY_CHARS)
normal_attr = curses.A_NORMAL
highlight_attr = curses.A_REVERSE
def __init__(self, width, MIN_SPEED, MAX_SPEED):
self.x = 0
self.y = 0
self.speed = 1
self.char = ' '
self.reset(width, MIN_SPEED, MAX_SPEED)
def reset(self, width, MIN_SPEED, MAX_SPEED):
self.char = random.choice(FallingChar.matrixchr).encode(encoding)
self.x = random.randint(1, width - 1)
self.y = 0
self.speed = random.randint(MIN_SPEED, MAX_SPEED)
def tick(self, scr):
height, width = scr.getmaxyx()
self.out_of_screen_reset(width, height)
scr.addstr(self.y, self.x, self.char, curses.color_pair(1))
self.char = random.choice(FallingChar.matrixchr).encode(encoding)
self.y += 1
if not self.out_of_screen_reset(width, height):
scr.addstr(self.y, self.x, self.char, curses.A_REVERSE)
def out_of_screen_reset(self, width, height):
if self.x > width-2:
self.reset(width, MIN_SPEED, MAX_SPEED)
return True
if self.y > height-2:
self.reset(width, MIN_SPEED, MAX_SPEED)
return True
return False
def rand():
a = 1
while True:
a ^= (a << 1);
a ^= (a >> 135);
a ^= (a << 104);
yield a
r = rand()
def randint(_min, _max):
n = r.next()
return (n % (_max - _min)) + _min
def color():
curses.start_color()
curses.init_pair(1, MATRIX_COLOR_WORD, MATRIX_COLOR_BACK)
curses.curs_set(0)
curses.noecho()
def main():
scr = curses.initscr()
scr.nodelay(1)
color()
height, width = scr.getmaxyx()
lines = []
for i in range(8):
l = FallingChar(width, MIN_SPEED, MAX_SPEED)
lines.append(l)
scr.refresh()
while True:
for line in lines:
line.tick(scr)
for i in range(30):
x = randint(0, width-1)
y = randint(0, height-1)
scr.addstr(y, x, ' ')
scr.refresh()
time.sleep(0.04)
def last_main():
curses.endwin()
curses.curs_set(1)
curses.reset_shell_mode()
curses.echo()
screen = curses.initscr()
color()
lastchr = string.join(list(MATRIX_THANKS_CHARS), " ")
last_height, last_width = screen.getmaxyx()
start_width = last_width/2 - len(lastchr)/2
for i in range(last_height/2):
screen.clear()
screen.addstr(i, start_width, lastchr, curses.color_pair(1))
screen.refresh()
time.sleep(0.2)
screen.getch()
curses.endwin()
try:
main()
except KeyboardInterrupt:
try:
last_main()
except KeyboardInterrupt:
curses.endwin()
curses.curs_set(1)
curses.reset_shell_mode()
curses.echo()
テストで走らせてみよう
$ python /tmp/matrix_curses.py
よし。
④上司のターミナルにマトリックスを走らせよう!
$ w
私の上司、takuが/dev/pts/○○ だと言う事が判明。
すかさずコマンド投入。
$ python /tmp/matrix_curses.py > /dev/pts/○○
次に、自分が満足したり、上司の怒りがマックスになったところで、ctrl + cを押す。
THANKS DEAR TAKU!!!
### 達成。本当にありがとうございました。
⑤最後に
障害時など、大事なときはダメ。絶対。
決して怒らない、ユーモアたっぷりで温厚で優しい上司にやってね!