148
132

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

LivesenseAdvent Calendar 2015

Day 12

上司のターミナルにマトリックスを走らせよう!

Last updated at Posted at 2015-12-12

Livesense Advent Caelendar 2015 12日目担当の@sion_cojpです。

振り返り・・・

前はインフラエンジニアとして働いており、ムカついたときは上司のターミナルに汽車を走らせてました。
今はWebアプリエンジニアとして部署異動し、APIを開発しております。

この記事をご覧になっている、そこのあなた。

仕事中にこんなことはありませんか?


部署異動したけど、やっぱり上司から無理な依頼をされた。ちくしょう。。。

わかります。その気持ち。ええ。
せっかく異動したんだから、高い寿司とかおごってくれてもいいのに。。
でも異動出来た事には感謝しないとです。社会って複雑ですよね。






#そんな上司の作業中のターミナル(端末)にマトリックスを走らせてやりましょう!!






まずは準備。


①上司が作業しているホストを探そう

何かしらの方法でげっとします。(鬼門)
またまた私は上司のモニターを後ろからこっそり覗いてやりました。




のんびりPHPのレガシーコードと格闘してるわ。

馬鹿め。

上司が開発しているサーバ情報をげっと。

②マトリックスを流すプログラムを書く。

適当に作る。
MATRIX_ANGRY_CHARS に怒りの気持ちをぶつけましょう。
プログラムを流すと分かりますが、怒りの部分はバレないようになってるので安心してください。

MATRIX_THANKS_CHARS には感謝の気持ちを入れましょう。

matrix_curses.py
#!/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/○○






mymovie1.gif



次に、自分が満足したり、上司の怒りがマックスになったところで、ctrl + cを押す。



mymovie2.gif



THANKS DEAR TAKU!!!

### 達成。本当にありがとうございました。

⑤最後に

障害時など、大事なときはダメ。絶対。
決して怒らない、ユーモアたっぷりで温厚で優しい上司にやってね!

148
132
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
148
132

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?