Scalaアレコレ2019

Option型の変数に任意の値が入っているかどうかで処理を分岐させる

/*
 * 以下のようなcase classがあって、HogeがMasterHogeにOption型として格納される場合に、
 * HogeのメンバフィールドであるOption型のisHoge(フラグ的なもの)の値をチェックする
 */
case class MasterHoge(
  hoge: Option[Hoge] = None
) 
case class Hoge(
  isHoge: Option[Int] = None
)

// どこかでMasterHogeをインスタンス化
val masterHoge = xxxx

// foreachとcontainsを使う
masterHoge.foreach { hoge =>
      if (hoge.isHoge.contains(1)) {
        // ココに行いたい処理を書く
      }
    }

zipWithIndex()を使ってSeqのインデックスと要素にアクセスする

  val hogeSeq = Seq("a", "b", "c", "d", "e")

  hogeSeq.zipWithIndex.foreach{case(value, index) => {
    printf("${index}:${value}") // 0:a 1:b 2:c ....
  }}

groupBy()を使ってMapのListを1つのMapにまとめる

  // ↓このようなMapのListがあったとして、これを"id"をキーとしたMapにまとめたいとする
  val hogeList = List(
    Map[String, Int](
      "id" -> 1,
      "vid" -> 2,
      "value" -> 10
    ),
    Map[String, Int](
      "id" -> 2,
      "vid" -> 4,
      "value" -> 20
    ),
    Map[String, Int](
      "id" -> 1,
      "vid" -> 21,
      "value" -> 17
    ),
  )

  // "value"の降順で上記のListを並べ替えたListを作る(これは本題とは関係のない操作)
  val sortedList = hogeList.sortBy(_.get("value"))(Ordering[Option[Int]].reverse)

  val hoshiimono = sortedList.groupBy(ho => {
    ho.get("id").get
  }).map(h => {
    val list = h._2
    h._1 -> list.map(l => {
      l.get("vid").get
    })
  })

  printf(s"___ ${hosiimono} ___")
  /* 結果
     Map(2 -> List(4), 1 -> List(21, 2))
   */

処理実行元のディレクトリを取得

sys.props("usr.dir")

文字列の前後にあるダブルクォーテーションを削除

以下のような形式のJSONJSON文字列的にparseしようとしたら構文エラーとなってしまった。

"{\"hoge\":{…}…, \"hogehoge\":\"geho\"}"

最初と最後にダブルクォーテーションが入っているのが原因だったので、以下のようにして取り除いた。

// まずエスケープとして入ってしまっていたバックスラッシュを取り除く
val jsonDataWithoutEscape = StringContext treatEscapes(jsonData.toString())

// 頭と後ろのダブルクォーテーションを削除
val jsonStr = jsonDataWithoutEscape.dropWhile( _ == '"' ).reverse.dropWhile( _ == '"' ).reverse

Jacksonを用いて複数階層を掘り下げつつ不要な要素を削除する

処理の流れ
  1. Json文字列からObjectNodeを生成
  2. ObjectNodeから削除したいfieldに対してremoveを実行
  3. 返されたJsonNodeからObjectNodeを生成
  4. 階層に応じて上記02〜03を繰り返す
ソースコード
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.node.ObjectNode

val jsonStr =
"""{"A":{.....}, "child":{"B":{}, "child":{....}, ....}} // 「親→子1→子2」の3世代
""".stripMargin

val parentObjectNode = mapper.readTree(jsonStr).asInstanceOf[ObjectNode]
val child1JsonNode     = parentObjectNode.remove("child") // 戻り値としてAが返され、parentObjectNodeからchildが削除される
val child1ObjectNode  = mapper.readTree(childJsonNode.get(0).toString).asInstanceOf[ObjectNode]
val child2JsonNode     = child1ObjectNode.remove("child")

文字列を区切り文字で区切って配列にしたり等

  val moji = "hoge:hohoge, geho:gegeho"
  val arr1 = moji.split(",")
  val hoge = arr1.map ( a=> {
    val arrlast = a.split(":")
    Map(arrlast(0) -> arrlast(1))
  })
  log.info(s"### ${hoge(0)} ###")
更に文字列の中身が数値だったらInt型に、そうでなければ文字列のままにしておく処理
      val attributes = mojiretsu match {
        case Some(attr) => {
          val arr = attr.split(":")
          val value = try {
            arr(1).trim.toInt
          } catch {
            case _:NumberFormatException => arr(1).trim
          }
          Map(arr(0)->value)
        }
        case _ => Map[String, Any]()
      }

買って良かったもの2018

ヘアドライヤー

ノビー(Nobby) ヘアドライヤー NB1903 ブラック

ノビー(Nobby) ヘアドライヤー NB1903 ブラック

  • 発売日: 2015/03/03
  • メディア: ヘルスケア&ケア用品
美容院御用達で風力強めで乾かしやすい。大きいのがネック。


メッシュスリッポン

裸足で履いても通気性が高いので蒸れにくい。

無線Wi-Fiルータ

[asin:B0763RCQ2J:detail]

コレ以前に使っていたのはAirMacExpressでちょいちょい切断されていたが、コレに替えてからは全く切断しなくなった。

nasne

nasne 1TBモデル (CUHJ-15004)

nasne 1TBモデル (CUHJ-15004)

  • 発売日: 2016/12/08
  • メディア: Video Game

iPhoneで遠隔からでも録画できるので、テレビ番組の見逃しを気にすることがなくなった。

アパガードロイヤル

アパガードロイヤル 135g

アパガードロイヤル 135g

  • メディア: ヘルスケア&ケア用品
「これは歯医者さんじゃないと白くデキません」と言われた歯が白くなりつつある。


ワインオープナー

ワインのコルク栓がアッサリ抜けるようになった。

fish諸々

Macで使用可能になるまで

インストール
$ brew install fish
使用するシェルをfishに変更
  • fishの場所を確認
$ which fish

/usr/local/bin/fish
  • /etc/shells を開いて、/usr/local/bin/fishを追加して保存
$ sudo vim /etc/shells
  • シェル変更コマンドを実行
$ chsh -s /usr/local/bin/fish

ターミナルを立ち上げ直すとシェルがfishに変わっている。

エイリアス設定

設定ファイルを新規作成。

$ vim .config/fish/config.fish
編集後、以下を実行
$ source .config/fish/config.fish


以下は設定ファイルの中身の例(SSH接続情報を登録したい場合)。

alias mychuno_check="ssh -i /Users/mychuno/.ssh/id_rsa -p ポート番号 mychuno@接続先IPアドレス"

サブコマンドを実行する

  • 実行したいサブコマンドをカッコで囲む
# 例えば環境変数にサブコマンドをセットしたい場合
set -x HCHUNO_SERVICES (cat hchuno-services.json | sed 's/;/\\\;/')

# ちなみに bash だと以下のようにバッククォートで囲む
export HCHUNO_SERVICES=`cat hchuno-services.json | sed 's/;/\\\;/'`

Gitアレコレ

リモートブランチをローカルにチェックアウトする

手順
  1. git fetch origin リモートブランチ名
  2. git checkout リモートブランチ名
$ git fetch origin 20180905_remote_branch
From <Gitのリモートリポジトリ名>
 * branch            20180905_remote_branch -> FETCH_HEAD

$ git checkout 20180905_remote_branch
Branch '20180905_remote_branch' set up to track remote branch '20180905_remote_branch' from 'origin'.
Switched to a new branch '20180905_remote_branch'

$ git branch
* 20180905_remote_branch
  master

git submodule

submodule側のブランチを切り替え、そのブランチを参照元のブランチで見るように切り替える
// 参照元
$ git stash

modified:   base/app/submodule

$ cd base/app/submodule

submoduleのブランチを切り替えて、参照元に戻る

$ git stash

modified:   base/app/submodule (new commits)

$ git add base/app/submodule

$ git commit 

// 以降は通常のコミットのフローと同じ

git mergeに失敗

最新のmasterを現在の開発ブランチ(こちらも最新で全てのファイルがcommit済み)にmergeしようとしたら怒られた。

Please commit your changes or stash them before you merge.
Aborting

とあるファイルがマージできないと言われていたのだが、git stashした後にgit mergeを試みたら上手く行った…

DockerコンテナにDjangoを入れて起動してみた

概要

そろそろDockerを触ってみたいと思ったのと、どうせ触るならPythonやらDjangoも使ってみようと…ということで軽く試してみました。

  • 今回触れたもの一覧
    • Dockerイメージ(CentOS)
    • Python3.6
    • Django2.1
    • Django REST Framework2.0.0
    • MySQL5.7

Dockerコンテナ起動まで


Dockerイメージ(CentOS)をPullしてくる

docker pull centos


適当なIPを指定してDockerコンテナ(CentOS)を起動しつつログイン

docker run -it -p 8000:8000 centos /bin/bash

PythonDjangoのインストール


Python3系インストールのためのリポジトリをインストール

yum install -y https://centos7.iuscommunity.org/ius-release.rpm


Python3.6をサーチしてみる

yum search python36


Python3.6と関連するものをインストール

yum install -y python36u python36u-devel python36u-libs


"python3"と打てばPythonコマンドが有効になるよう、シンボリックリンクを張る

ln -s /usr/bin/python3.6 /usr/bin/python3


pipをインストール

yum install -y python36u-pip


インストールされたpipのバージョンが古いのでアップグレードする

/usr/bin/pip3.6 install --upgrade pip


DjangoDjango REST Framework、Django-Filterをインストール

pip install django
pip install djangorestframework
pip install django-filter

Djangoのプロジェクトとアプリを作成し、起動


Djangoがインストールされたディレクトリに移動

cd /usr/local/bin/


Djangoのプロジェクトを作成

django-admin.py startproject myprj


プロジェクトのルートディレクトリに移動

cd myprj


アプリを作成

python3 manage.py startapp myapp


マイグレーションを実行

python3 manage.py migrate


アプリを起動してみる

python3 manage.py runserver 0.0.0.0:8000


アプリ起動用のスクリプトを作っておく

vim /usr/local/bin/init.sh
python3 /usr/bin/myprj/manage.py runserver 0.0.0.0:8000
while true ; do
    /usr/bin/fish
done

MySQL5.7のインストール


インストール用リポジトリのインストール後、インストール実行

rpm -ivh http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm

yum -y install mysql-community-server


MySQLのrootユーザーのパスワードを確認

cat /var/log/mysqld.log |grep password
→パスワードが表示されるのでコピー等しておく


MySQLのセキュリティ設定を行う

mysql_secure_installation
※先程確認したパスワードと、新しいパスワード入力を求められる


root以外のユーザーを作成

grant all privileges on *.* to hoge@localhost identified by '任意のパスワード' with grant option;

flush privileges;


データベースを作成

create database myapp_db;

Django側のMySQL関連設定

PyMySQLのインストール

pip install PyMySQL


manage.pyにPyMySQLの設定を追記

vim manage.py
import pymysql
pymysql.install_as_MySQLdb()


settings.pyにMySQLの情報を追記

vim settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME':'myapp_db',
        'USER':'hoge',
        'PASSWORD':'hogeのパスワード',
        'HOST':'localhost',
        'PORT':'3306',
        'OPTIONS': {
            'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
        },
        'TEST': {
            'NAME': 'test_sample'
        }
    }
}


マイグレーション実行

python3 manage.py makemigrations
python3 manage.py migrate


Ctrl+p,Ctrl+qでコンテナから抜けた後、コンテナをDockerイメージとして保存

#起動中のコンテナのコンテナIDを確認
docker ps
#コミットして保存
docker commit コンテナID mychuno_myapp


Dockerコンテナを止める

docker stop コンテナID

ホストからDockerコンテナを立ち上げた後、アプリを起動

Docker起動後にMySQLも起動

  • 先程保存したDockerイメージを用いる
  • -vオプションでホストの任意のディレクトリにバックアップできるようにしておく
docker run -it -p 8000:8000 -v /Users/hchuno/projects/docker_myapp/mychuno:/usr/local/bin/myprj_bk --privileged mychuno_myapp /sbin/init


Dockerコンテナにログインしてアプリを起動

docker ps

docker exec -it CONTAINER_ID /usr/local/bin/init.sh /bin/bash

PCの時限シャットダウン

「まだ社内に居ると周囲に思わせたままコッソリ帰りたい」というニーズがあって 興味を持って調べてみた。

Windows


コマンドプロンプトで以下を入力すると10分後に自動シャットダウンが走る。

shutdown -s -t 600

コメントをアラート表示させたい場合は、

shutdown -s -c "既に退社済みぢゃ!" -t 600

自動シャットダウンが実行される前に止めたい場合は、

shutdown -a

Mac

ターミナルでコマンドを入力すると実現可能。

時限設定

12分後に終了したい場合

sudo shutdown -h +5

時刻指定

7時31分に終了したい場合

sudo shutdown -h 07:31

2018年2月5日20時00分に終了したい場合

sudo shutdown -h 1802052000