君は心理学者なのか?

大学時代に心理学を専攻しなぜかプログラマになった、サイコ(心理学)プログラマかろてんの雑記。

目が覚めると、女物のパンツが、ポケットに2枚、入っていた。

※ ノンフィクション

その1

この間ものすごく酔っ払って家に帰った。

朝起きたら目線がすごく低かった。そして寒い。

どうやら昨夜(ほぼ朝)、

家につくなりすべての鎧を脱ぎ捨て、そのまま床で寝てしまったらしい。

あたりには服が散乱し、僕の肌は寒さで粟立っていた。

こういう時の感覚は独特である。

世界がふわふわ浮いている感じ。そんな世界を歩く僕もふわふわ浮いている。

ふわふわしている割に重そうに体を上げ、

「道半ば行き倒れました」みたいなメッセージ性のある置かれ方をしているジーンズを手に取り、

何気なくポケットをまさぐった。

その2

床に落ちた。

女物のパンツが2枚。

ショッキングピングとイエローだった。

その3

いったい昨夜、何があったのか。

ブラックライトを当てたら今にも光りだしそうな、蛍光色の2枚を見つめる。

昨夜、職質されたら僕はどうなっていたのだろう。

若干体温が上がってきた僕の肌が、再び粟立つ。今度は悪寒だ。

その4

部屋の隅にその2枚を投げ捨て、

何事もなかったかのように、とりあえず会社に行った。

仕事しながら記憶を辿った。霞をつかむかのように何も思い出せない。

「このまま、何ごともなかったかのように生活をしていく」

そんな選択肢が浮かぶが、

「警察が家宅捜索にくるイメージ」がその上に浮かび、

完全に上書きしていった。頭を抱えた。

記憶のない中、罪を犯した。

自分には、そうとしか思えなかった。

その5

いや。何かがおかしい。

数が、合わないのだ。

今しがた、若干記憶が戻ってきた。

そう。

昨日行った店には、男性が2人、女性が1人いたのだった。

その6

昨日いた店に問い合わせてみて、僕は安堵した。

僕は犯罪を犯していなかった。

店長「常連のおじさんが、君に女物のパンツを2枚くれた」

安堵しながら僕は思った。

「あれ?結局意味わかんねーぞ」

(つづく)

sedコマンドを使って、特定の文字列以降を削除〜ソースコードのコメントを削除したかったの〜

f:id:karoten512:20180314120142p:plain

いきさつ

sample.txtの内容は以下。

$aa = 'hoge'; // コメントだよ
$bb = 'fuga'; // コメントだよ

このファイルから、コメントだけ削除したい。

つまり、//以降だけ削除したい。

結論

sed -i '.bak' -e 's/\/\/.*//' sample.txt

解説

iオプション

これがない場合は、sedの結果を標準出力するだけ。

これがあると、sedの結果がそのままファイルに上書きされる。破壊的。

なお、-iの後にバックアップファイル用の拡張子を指定できる(macでは必須)

eオプション

正規表現を使用する時に使う。

まとめ

正規表現sedを組み合わせると本当に便利。

macにscalaをinstallして、コマンドラインからscalaを実行する

f:id:karoten512:20180310125726j:plain

いきさつ

業務でscalaを使いそうなので、とりあえずhello worldをやっておきたかった。

手順

jdkをinstallする

brew cask install java

sbtをinstallする

brew install sbt@1

scala console(名前は会っているのか?)を立ち上げ

sbt

hello world

scala> println("Hello, World!")
Hello, World!

感想

久しぶりに別の言語でhello worldしたから、気分が良い。

カレントディレクトリ以下にファイルがいくつあるか、再帰的に探索して確かめる

f:id:karoten512:20180308154247p:plain

結論

ls -lR | grep '^-' | wc -l

解説

ls -lR

lオプション…ファイルの情報を表示する

Rオプション…ディレクトリ内のファイルも表示する

grep '^-'

先頭に「-」が含まれている行を表示。

wc -l

行数をカウントする。

なおオプションを変えると、

バイト数、文字数、単語数などもカウントできるよ。

You can't specify target table '***' for update in FROM clause〜MySQLにて、サブクエリのみに適用されるエラーがある〜

f:id:karoten512:20180308112401p:plain

こういう感じのSQLを書いた

UPDATE parent
  SET name = 'hogehoge'
WHERE
  parent_id
IN
  (
      SELECT
        parent.parent_id
      FROM
        parent
      LEFT JOIN
        children as c
      ON
        parent.parent_id = c.parent_id
  );

そしたらこんなエラーが出てきた

You can't specify target table 'parent' for update in FROM clause

??

ぐぐったら公式サイトがでてきた

MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.2.10.9 サブクエリーのエラー

このエラーは、テーブルを変更し、さらにサブクエリーで同じテーブルから選択しようとする次のような場合に発生します。

へえ。

解決方法

IN句のなかのSELECTを、更に副問合せにしてしまう。

適当にtmpという名前をつける。

UPDATE parent
  SET name = 'hogehoge'
WHERE
  parent_id
IN
  (
    SELECT
      tmp.parent_id
    FROM
    (
      SELECT
        parent.parent_id
      FROM
        parent
      JOIN
        children as c
      ON
        parent.parent_id = c.parent_id
      )
    as tmp
  );

これでうごいた。

scpでリモートサーバからローカルにファイルを落とす&ローカルからリモートに転送する

f:id:karoten512:20180306214627g:plain

↑ test-serverにあるfilesディレクトリの中身を、localに落としてきているところ。

scpコマンドについて

ファイルを送信したり、受信したりすることができる。

ファイル送受信時に使用するプロトコルsshプロトコルなので安全。

また、使用帯域なども絞れるので、

他の通信を圧迫しないようにファイルの送受信をすることができる。

使用シーン

リモートホストの特定のディレクトリにある、大量のファイルを落としたい時。

ローカルで作ったシェルをリモートに置きたい時。

などなど。

使用法

リモートからローカルに落としてくる

scp [ユーザー名]@[ホスト名]:[リモートファイルパス] [ローカルファイルパス]

また、-r オプションを付けると、

ディレクトリの中のファイルを再帰的に取ってきてくれる。

ディレクトリ構造が保持されるので、便利。

scp -r [ユーザー名]@[ホスト名]:[リモートディレクトリパス] [ローカルディレクトリパス]

使用例

リモートホストにある、sshクライアントの設定ファイルを取ってくる時。

scp user@remote_host:~/.ssh/config ~/

ローカルからリモートに転送する

scp [ローカルファイルパス] [ユーザー名]@[ホスト名]:[リモートファイルパス]

ローカルファイルパスを複数指定すると、

複数個のファイルを取ってくることができるらしい。これも便利。

参考サイト

www.atmarkit.co.jp

余談

なお、scpと語感が似ているsftpというコマンドがあるが、

結構違う。

イメージとしては、ftpプロトコルsshになった感じ。安全。

リモートにログインして操作ができるので、

リモート上でファイル名を変えたり、移動させたりすることができる。

canvasで画像を表示する

いきさつ

canvasを使って画像のリサイズをしたり、

画像のくり抜きがしたかったので、まずはcanvasで画像を表示できるようにした。

手順

1. input type='file'で画像を登録できるようにする

<input type="file" id='file'>

2. fileを登録した時にイベントが発火するようにする

/** input要素の取得 */
const input = document.getElementById('file');

/** inputに画像を追加した時にイベントを受け取る */
input.addEventListener('change', function(e) {
  /** 処理 */
}

3. 処理を書く

/** inputに画像を追加した時にイベントを受け取る */
input.addEventListener('change', function(e) {

  /** File オブジェクトを読み込む */
  const file = e.currentTarget.files[0];
  const fr = new FileReader();

  fr.onload = function() {
    /** ファイルが読み込まれたあとの処理 */
    const image = new Image();
    
    /** 画像がimageタグに読み込まれた後の処理 */
    image.onload = function() {
      ctx.beginPath() ;
      ctx.drawImage(this, 50, 0, 400, 400, 0, 0, 200, 200);   
    }
    image.src = fr.result;
  }
  fr.readAsDataURL(file);
});

解説1

canvasで画像を描く際、drawImageというメソッドを用います。

drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)

imageはHTMLImageElement, HTMLCanvasElement, HTMLVideoElement のいずれかを取ることができます。

ということは、まずはHTMLImageElemenetを生成する必要があります。

解説2

const image = new Image();

でHTMLImageElemenetが生成できます。が、

Imageのsrcを指定する必要があります。

    const image = new Image();
    
    /** 画像がimageタグに読み込まれた後の処理 */
    image.onload = function() {
      ctx.beginPath() ;
      ctx.drawImage(this, 50, 0, 400, 400, 0, 0, 200, 200);   
    }
    image.src = fr.result;

こんな感じで。

fr.resultはFileReaderがFileオブジェクトを読み込んだ際の結果です。

ソースコード

jsfiddle.net