OmniAICreator/Qiita-1.07M huggingface dataset:
Systemdについてちゃんと勉強してみた

# はじめに

いつも仕事でCentOSのサーバ立ち上げて、データベースとかアプライアンスとか入れて動かしたいとき、
たとえばそれがPostgreSQLだったら

```sh
systemctl enable postgresql
systemctl start postgresql
```

 ってするし、Dockerデーモンなら

```sh
systemctl enable docker
systemctl start docker
```

ってする。
この「systemctl」ってコマンド、何も考えずにこれまで使ってきたが、
ちゃんと調べる機会が出てきたので、ここでちゃんとまとめておくことにする。

# 本題

## デーモンとサービス

OSで走るプロセスには、大きくわけて

* 自分で何らかのコマンドを打つことで起動するプロセスと、

* OSが立ち上がっている間ずっと起動しているプロセス

がある。
前者は、たとえば、

```sh
python hello.py
./start.sh
make install
```

が該当する。ユーザーが起動するので、<b>ユーザープロセス</b>とか言われる。
`ps`コマンドを実行すると、実行されているプロセスが確認できる。  

後者は、OS起動時にシステムによって立ち上げられ、バックグランドで動くプロセスで、これを<b>デーモン</b>と呼ぶ。
よく知られているものだとpostgresqlやmysqlなどのデータベース、httpdやnginxなどのリバースプロキシ、その他jenkinsやgithubとかのアプライアンスなどが該当する。

## systemd

systemdは、OSが起動されたときに、これらデーモンたちを立ち上げ、プロセス管理をするプロセスである。
`systemctl`というコマンドは、このsystemdにアクセスして、デーモンの起動・停止、監視などを行っている。

```sh
systemctl enable postgresql.service # PostgreSQLサーバを有効化
systemctl restart docker # Dockerデーモンを再起動
systemctl stop nginx # Nginxを停止
systemctl status sshd # SSHデーモンの状態確認
```

## ユニットファイル

　では、Systemdは、デーモンプロセスの立ち上げを要求されたとき、実際はどんなことをしているのだろう。
それは、`/etc/systemd/system/`以下にある「<b>ユニットファイル</b>」というファイルに記載されている。

たとえば、PostgreSQLのユニットファイルの中身はこうだ。

引用元: [https://www.postgresql.jp/document/11/html/server-start.html]

```
[Unit]
Description=PostgreSQL database server
Documentation=man:postgres(1)

[Service]
Type=notify
User=postgres
ExecStart=/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT
TimeoutSec=0

(後略)
```

ユニットファイルの中身はWindows Configファイル(.ini)ライクな書き方で、
実際に実行されるコマンドというのは`[Service]`セクションの中の`ExecStart`の部分だ。

```
ExecStart=/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
```

つまり、SystemdはOS起動時に`/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data`というコマンドを実行していることになる。
ちなみに、その上に`User=postgres`とある通り、このコマンドは`postgres`ユーザとして実行されている。

他にも、このユニットの前に起動されている必要のあるデーモンを指定する`After`や、デーモン専用の環境変数を指定する`Environment`などがある。
このあたりの話は、下記に詳しい。

[https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-unit_files:embed:cite]

また、`systemctl list-unit-files`で、ユニットファイルの一覧を表示できる。

# まとめ

今回は、systemdというLinuxにおいて実は重要な役割を果たしていたものについてまとめてみた。
今となってはサービスを公開するにはDockerやKubernetesを使って、コンテナやPodの単位でスケールしたり監視するのが主流となっているが、購入したアプライアンスなどをインストールするとき、物によってはこうしたsystemdの使用を強制されることがある。
そこで何かトラブルがあった際に対応できないと困るので、ちゃんと調べておくのは大事だ。
STSで作成したSpringプロジェクトのGitHub連携メモ

##はじめに
STSで作成したSpringBootプロジェクトGitHubで管理するにあたって
の連携方法を備忘録として記載。

##1,GitHubにリポジトリを作成
GitHubのnew repositoryからプロジェクト用にリポジトリを作成

<img width="1066" alt="スクリーンショット 2020-04-21 22.35.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272935/29fd7940-c002-52e5-cc96-68a48f265298.png">

##2,コミット
STSにてTeam→Commitで行う。
<img width="1440" alt="commit1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272935/dd530191-c9bd-0935-5f41-1aaebc3a1361.png">


対象のファイルをstagedに上げて、コミットメッセージを入力しcommit。
<img width="1440" alt="commit2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272935/83ebf245-2884-b268-2b92-02e16c01fea3.png">

##3,プッシュ
STSにてTeam→Push branch
リモートリポジトリの情報を入力していく。

<img width="603" alt="スクリーンショット_2020-04-21_22_54_12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272935/66904cf1-2684-e3af-c192-6c3f836f1d13.png">

<img width="612" alt="スクリーンショット_2020-04-21_22_54_30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272935/d75981ae-a5ab-a3cc-4e59-26c4cebc6f83.png">

入力後pushを押下すると作成したリモートリポジトリにpushされる。

<img width="997" alt="スクリーンショット 2020-04-21 23.08.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272935/1ba1a48c-deed-b7c4-2b61-3241d9eaf217.png">

プロジェクトをGitHubに連携出来ました〜
以上。
Go言語はerr != nilでもerrはnilである時がある

**突然ですが問題です。**
以下のコードを実行した時、"This should not be called"の文字列は出力されるでしょうか？

```golang
package main

import "fmt"

type MyError struct {
}

// implements error interface
func (MyError) Error() string {
	return "This is MyError"
}

func fn() (int, *MyError) {
	return 42, nil
}

func main() {
	result, err := fn()
	if err != nil {
		fmt.Println("This should not be called")
	}
	fmt.Println(result, err)
}
```

### 実行結果

```golang
42 <nil>
```

出てません。`fn()`はエラーnilを返しているので、`if err != nil`の中には入りません。
ここまではOKですね。

では次の例ではどうでしょうか。


```golang
package main

import "fmt"

type MyError struct {
}

// implements error interface
func (MyError) Error() string {
	return "This is MyError"
}

func fn() (int, *MyError) {
	return 42, nil
}

func main() {
	var err error
	result, err := fn()
	if err != nil {
		fmt.Println("This should not be called")
	}
	fmt.Println(result, err)
}
```

`func main()`の次の行に1行追加されているだけですが、これはどうなるでしょう？

### 実行結果

```
This should not be called
42 <nil>
```

なんと！"This should not be called"の文字列が出力されてしまいました！
ということは`err != nil`は`true`ということになります。
でもちょっとまってください。その下の出力内容は`42 <nil>`です。ということは`err`はやっぱり`nil`なのです。だから、

```golang
if err != nil {
  fmt.Printf("Error %s", err.Error())
}
```

のようなことをしていると、**直前でnilチェックをしているにも関わらずnil参照エラーでクラッシュします。**

私はこの現象に数時間悩まされました。

この例で言うところの`fn()`が返却するエラーの型を`*MyError`ではなく`error`とすると、この問題は発生しません。

```golang
package main

import "fmt"

type MyError struct {
}

// implements error interface
func (MyError) Error() string {
	return "This is MyError"
}

func fn() (int, error) { // *MyErrorではなくerror
	return 42, nil
}

func main() {
	var err error
	result, err := fn()
	if err != nil {
		fmt.Println("This should not be called")
	}
	fmt.Println(result, err)
}
```

### 実行結果

```golang
42 <nil>
```

Goの型システムの深いところまでまだ理解できていないのですが、とりあえず各関数が返却するエラーの型を`*MyError`のような独自型ではなく、`error`とするのが良さそうです。

同じハマり方をされていた先人たち

* https://qiita.com/reiki4040/items/fea51c0e7a94dd854522
* https://qiita.com/umisama/items/e215d49138e949d7f805
Hubotを使ってみた

#はじめに
この記事はなんとなくJSとかを勉強している学生がメモ代わりに書いているものです。内容は期待しないでください。

#1.仮想環境を開く
今回はUbuntuで行うのでiTerm2で仮想環境を起動する。

起動したところで
1.Virtual Box(バーチャルボックス)
2.Vagrant（ベイグラント）
という2つのソフトウェアを使った仮想環境でUbuntuを使用します。
cd ~/vagrant/ubuntu
vagrant up
vagrant ssh

Ubuntuがインストールされたディレクトリに移動。vagrant upは仮想的なPCにインストールされたUbuntuを起動するコマンドで,vagrant sshはVagrantの仮想マシンがセットされている状態でSSHに接続します。

#2.botを作る上で必要なモジュールをインストールする

```npm install -g hubot yo generator-hubot coffee-script
```
yoとはYeomanという雛形作成ツールです。
generator-hubotはHubot のためのYeomanジェネレーター(generator-hubot)です。
coffeescriptはhubotをJSで扱うために必要なためインストール。

#3.botを作る
```yo hubot --adapter=slack
```
上記した内容は```yo hubot```というコマンドでボットを作成し,それ以降はslackをアダプターとする内容です。
複数の質問に答えることができたらボットのプロジェクトが作成されます。
```Done in 秒数.
```
と出てきたら成功です。

#3.Hubotを動かすプログラムを書く
```javascript

'use strict';
module.exports = (rbot)=> {
  rbot.hear(/hello>/i, msg => {
    msg.send(`Hi`);
  });
```
1行目はJSをstrictモードで利用するための記述です。

２行目はmodule.exportsを使ってrbotという変数に値を直接格納できしています。module.exportsを使うと、指定した値を他のjsファイルから読み込んで再利用することができるようになります。少し似ているexportsとの違いはプロパティを設定せずに値を直接格納できます。記述方法は以下参照。
```module.exports.プロパティ名 = 値
```

３行目以降はモジュールの関数で,helloというワードに反応してhiと返す記述です。特定の内容に反応させるには，Robotクラスのメソッドhearやrespond(用途はほぼ同じ)を使用します。記述方法は以下参照。
```hear: (マッチさせたい正規表現, 正規表現にマッチしたときに呼び出されるコールバック関数)
```
また,チャットに発言を投稿するにはsendとreply(用途はほぼ同じ)を使います。記述方法は以下参照。
```send(`文字列`);
```
引用元(https://gihyo.jp/dev/serial/01/hubot/0004)

#4.hubotを動かしてみる
以下コマンドでボットを動かしてみて,先ほどに指定した文字列に正しく反応できたら成功です。お疲れ様でした!!!!
```bin/hubot
```


以下引用(https://gihyo.jp/dev/serial/01/hubot/0001)
###botとは
チャットツールに常駐してチャット経由でコマンドを待ち受けて実行したり，決められた条件に従ってチャットに発言してチャットの参加者に通知したりするようなプログラムのことをbotと呼びます。

###hubotとは
世の中には，開発言語やチャットツールごとにbotを作成するための様々なフレームワークが存在します。たとえば，PerlでIRCのbotを作るならikachan，WebサービスでTwitterのbotを作るならtwittbotが有名なところでしょうか。Hubotは，GitHub社が開発しMITライセンスで公開しているNode.jsでbotを作り動かすためのフレームワークです。
Hubotの大きな特徴に，様々なチャットツールに対応している点があります。たとえば，先ほど取り上げたikachanは，IRC用のbotを作るためのフレームワークであり，Twitterのbotを作る目的には使えません。一方でtwittbotはTwitter専用であり，IRC用のbotを作ることはできません。しかし，Hubotは，Hubotとチャットツールをつなぐモジュールである「Adapter」を切り替えることで様々なチャットツールに接続することができます。

###アダプターとは
Adapterは，チャットツールからRobotに誰かが入力した発言などチャットの状況を入力し，スクリプトなどによって作られた出力をチャットツールに伝える役割をします。初期状態では，シェル上でHubotと対話できるshell adapterと，Campfireというチャットツールに接続するCampfire AdapterいうAdapterが付属しています。
様々なAdapterがサードパーティーから提供されているため，大抵の場合は自分が使っているチャットツールに対応したAdapterが見つかると思います。
CakePHP上でJavascriptによるタグ機能実装

#今日やること

* tag表示（サーバからtagのデータを取得してtag一覧表示）
    * tagsを取得する

* javascriptで追加tagのデータをサーバに送信

* tagの送信が終わった後に、コールバックで（tagを再度表示）

#CakePHP2でjavascript

* jshelper（非推奨 CakePHP3からはなくなる）
* htmlヘルパーで書く方法　```HtmlHelper::script(mixed $url, mixed $options)¶
```

    * webrootにかく
    * 直接書く


#htmlヘルパー js

* ```$this->Html->scriptStart(array('inline' => false)); $this->Html->scriptEnd(array('inline' => false));```
    * javascriptだけで書くの難しいっぽい。調べ不足
* jsを外部定義する
    * javascriptだけで書けそう



#tag表示
###done
* jsでfor文を回して、データ数に応じたセレクトボックスを作成（仮データ）

```

document.write('<input type="checkbox" name="genre" value="' + value + '" id="genre_' + index + '">');
```


* json_encodeで実際のデータでタグ表示　http://maa123lq.hatenablog.com/entry/2015/10/10/191809



こんな感じで、javascriptでhtmlを書きたいときは、文字列としてwriteなので書き込む。

```
document.write('<label for="genre_' + i + '">' + tags[i] + '</label>');

```

###tagがついているものをチェック済みとして表示する

以下のように条件にマッチする場合、inputタグの表示を変えるようにした。

```
if(Object.values(selected_json).indexOf(String(i))>=0){
        document.write('<input type="checkbox" name="data[tag][]" value="' + i + '" checked="checked" id="Tag' + i + '">');
    }else{
        document.write('<input type="checkbox" name="data[tag][]" value="' + i + '" id="Tag' + i + '">');
    }
```


###学びメモ
**PHPからJavaScriptに配列を渡す**
json形式に変換した上で受け渡しをする。
   https://qiita.com/tksnino/items/c8c542f1f0a7bf9d6031

* セレクトボックスは、cakephpのformヘルパーのcreateとendの間に記述した。こうすることで、formとしてrequest->dataに保存されサーバに送ることができる。結局、formヘルパーもサーバ上でhtmlに変換されているから、htmlでクライアント側でhtmlを追加しても同じように表示できる。
* オブジェクトは、値チェックを直接することが難しそう。今回も配列になおしてindexOfで判定している。
Powershell でフォルダーを強制削除する

PC を新調し、以前までシステムドライブとして使っていた SSD を新しい PC のデータ置き場として換装しました。アプリフォルダーやシステムフォルダーはもう不要なので、エクスプローラーから削除しようとしましたが、権限の都合で拒否されます。

頻繁に遭遇したのは、 **「このフォルダーを変更するには、TrustedInstaller からアクセス許可を得る必要があります」** というエラー。
![access_denied.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8267/e9898f69-a1df-67b4-4f46-a78c4c308807.png)


これを黙らせるには、フォルダーの所有者変更と権限付与が必要です。エクスプローラー上からもできますが、削除したいフォルダが多くていちいちクリックが面倒だったので、再利用性の高い PowerShell で実行することにしました。

以下、その手順です。



手順
----

### PowerShell を起動

以下のいずれかの方法で PowerShell を **管理者権限で** 起動します。

* Windows ボタンを右クリック → "Windows PowerShell(管理者)" をクリック
* Windows キー → `Power` と入力 → PowerShell がサジェストされるので "管理者として実行" をクリック


### PowerShell を実行中のユーザーを確認

`whoami` コマンドにより、実行中ユーザーのデバイス名とユーザー名が表示されます。後で使うのでメモっておきましょう。

```powershell
PS C:\> whoami
my-pc\kei
```

上の実行例では、デバイス名は `my-pc`, ユーザー名は `kei` です。


### フォルダーの所有者変更、権限付与、削除

使うコマンドは以下の3つです。

```powershell
# 所有者変更 (Linux の chown に相当)
#  /r はサブフォルダーを含めて再帰的に処理
takeown /s <デバイス名> /u <ユーザー名> /f <削除パス> /r


# 権限変更 (chmod に相当) 
#   :F は指定ユーザーにフルコントロール権限を与えるフラグ
#   /T はサブフォルダーを含めて再帰的に処理
icacls <削除パス> /grant <ユーザー名>:F /T
  

# 削除 (rm -rf) に相当
Remove-Item <削除パス> -Recurse -Force
```

これを踏まえて、 `E:\Program Files (x86)` を削除するコマンドは以下のようになります。今回は削除対象のパスがスペースを含んでいるので、ダブルクォーテーションで囲っています。


```powershell
takeown /s my-pc /u kei /f "E:\Program Files (x86)\*.*" /r
icacls "E:\Program Files (x86)\*.*" /grant kei:F /T
Remove-Item "E:\Program Files (x86)\" -Recurse -Force
```




参考
----

* [Windows で強制的にディレクトリを削除する \- Qiita](https://qiita.com/mizutoki79/items/58d236f85b76cb7f61d8)
* [【 Remove\-Item 】コマンドレット――ファイルやフォルダを削除する：Windows PowerShell基本Tips（4） \- ＠IT](https://www.atmarkit.co.jp/ait/articles/1607/13/news026.html)
swiftでgifを表示する方法(ローカルのgif)

思ったよりだいぶ簡単だったのですが、なぜか各所で書かれてる表示方法が違いました


PodsのPodfileに

```
pod 'SwiftGifOrigin', '~> 1.7.0'
```

こいつを記載します

で、terminalからPodfileがあるディレクトリにいって

```
pod update
```

または

```
pod install
```


で、ライブラリを更新します。
そしたら今度はこれを使うわけですが

```
import SwiftGifOrigin
```

これを忘れて「あれ？インストールされてないのかな？」とpodの使い方をぐぐり直すハメになりましたww

次に

```swift
imageView.image = UIImage.gif(asset: "gif_name")
```

これで無事にgifが表示できました。

検索してよく出てくるのが

```swift
imageView.image = UIImage.gif(name: "gif_name")
```

これだと何も表示されませんでした。
多分gifを保存する場所が違ったせいなのかもしれません。
Assets.xcassetsに保存したのですが前者でなければファイルが見つかりません的なエラーが出ました。

原因は分かりませんが誰かライブラリ潜ってみてください（人任せ）
MAMPを使ったWordpressでのWEB制作方法2　初心者向け

#MAMPを使ったWordpressでのWEB制作方法2　初心者向け

前回の記事はこちら
[MAMPを使ったWordpressでのWEB制作方法1　初心者向け](https://qiita.com/fumiya0414/items/5d13d8d652beeadda779)

今回制作するのは以下のようなコーポレートサイトです
画像や文章などは簡略化してhtmlとcssでマークアップしています

##作成ページ概要
トップページ（index.html）
いわゆるトップページです。
[![Image from Gyazo](https://i.gyazo.com/abc4e08a33099ad7c83ba1f2a0074568.gif)](https://gyazo.com/abc4e08a33099ad7c83ba1f2a0074568)

記事一覧ページ（archive.html）
投稿のアーカイブ（一覧）ページです。
レイアウトは以下にします
infomation・・・リリース業務に関するお知らせのセクション
blog・・・ブログの投稿に関するセクション
※好みに合わせてカスタマイズが可能です

[![Image from Gyazo](https://i.gyazo.com/2792f9502aa53280e0f9e0ccfa243a39.png)](https://gyazo.com/2792f9502aa53280e0f9e0ccfa243a39)

お問い合わせページ(contact.html)
ユーザーからのお問い合わせページです
受信方法としてメールアドレスを設定します
[![Image from Gyazo](https://i.gyazo.com/c9d666d1fd4468b1aac26e07d8af84fc.png)](https://gyazo.com/c9d666d1fd4468b1aac26e07d8af84fc)

会社概要ページ(company.html)
固定ページです
会社の概要ページです。
[![Image from Gyazo](https://i.gyazo.com/891f8688deaf161b1ff13072e26955bf.png)](https://gyazo.com/891f8688deaf161b1ff13072e26955bf)

サービス紹介ページ(service.html)
固定ページです
サービス内容のページです。
[![Image from Gyazo](https://i.gyazo.com/3df124d3ee1d2a8c9c799345d7357d4f.gif)](https://gyazo.com/3df124d3ee1d2a8c9c799345d7357d4f)

投稿結果ページ(single.html)
リリース、業務に関するお知らせ、ブログは
同じレイアウトにして管理を簡単にします
投稿はwordpressの管理者画面からできるようにします
[![Image from Gyazo](https://i.gyazo.com/fcdaa3c86e8f9ecb9365d2aa2ec209e8.png)](https://gyazo.com/fcdaa3c86e8f9ecb9365d2aa2ec209e8)

##ディレクトリ構成
ディレクトリ構成は以下のとおりです
CSSはstyle.cssに記述をしています。今回JSは使用しません
[![Image from Gyazo](https://i.gyazo.com/925d706085da2903f4ccd4e61c262d61.png)](https://gyazo.com/925d706085da2903f4ccd4e61c262d61)

制作の段階で共通化する部分は同じレイアウトにしておきます
今回の場合はヘッダー、フッター、サイドバーは共通レイアウトです

このようにマークアップしたファイルをwordpressのテーマ化をすることで
プログラミングがわからない方でもWEBの管理ができるよう制作します

次回はMAMP内にwordpressに必要なファイルを作成していきます。

[MAMPを使ったWordpressでのWEB制作方法3　初心者向け](https://qiita.com/fumiya0414/items/4c855b29fd24a28a9538)
日本語をローマ字にする

##pykakasiをインストールする
このモジュールを使うことで日本語文字をローマ字に変換できる

```
pip install pykakasi
```

##引値をローマ字に変換する関数を作る。

```
from pykakasi import kakasi
kakasi = kakasi()
def jp2rome(text):
    kakasi.setMode("H", "a")  # Hiragana to ascii
    kakasi.setMode("K", "a")  # Katakana to ascii
    kakasi.setMode("J", "a")  # Japanese(kanji) to ascii
    kakasi.setMode("r", "Hepburn")  # Use Hepburn romanization
    conv = kakasi.getConverter()
    result = conv.do(text)
    return(result)
```
##使用例

```
jp2rome("てすと")
→'tesuto'
jp2rome("テスト")
→'tesuto'
jp2rome("試験")
→'shiken'
```
TypeScriptでローカル用とサーバ送信用の微妙に構造の異なるクラスをデコレータでいい感じに変換する。

##記事のデータ構造を表すクラスがある
```typescript
class Article {
  public title: string = '' // タイトル
  public body: string = '' // 内容
  public caretPosition: number = 0 // キャレット位置
}
```
こんな感じでの記事の「タイトル」「内容」「キャレット位置」をフィールドに持つクラスがあり、ローカルで記事の内容を保持するために利用し、APIでサーバにもそのまま送信したいとします。

##「キャレット位置」はサーバに送りたく無い
しかし、ここで`caretPosition`については、ローカルでの処理にしか使わないフィールドなのでサーバには送りたく無かったとします。
これをそのままfetchで送ってしまうと、当然のことながらサーバに対して`caretPosition`が含まれたオブジェクトが送られてしまうので、どうにかして`caretPosition`を取り除いてから送信する必要があります。

##素直なやり方
```typescript
const article = new Article()
const articleRemote = {
  title: article.title,
  body: article.body
}
// fetchにarticleRemoteを渡す
```
必要フィールドのみを詰め直す処理を別途記述するとどうでしょうか。
クラス定義とは遠い場所での処理になるため、クラス定義の変更に対して追随し忘れたりが発生しそうです。

##デコレータとメタデータを使って処理

```typescript
class Article {
  public title: string = ''
  public body: string = ''
  @LocalOnly
  public caretPosition: number = 0
}
```
こんな感じでクラス定義にサーバに送りたく無いフィールドに対してデコレータで指定できると便利です。

##デコレータを機能するようにする
では実際にLocalOnlyデコレータが機能するようにしてみましょう。
`npm install reflect-metadata`でreflect-metadataを導入しておきましょう。

```typescript
import 'reflect-metadata'

const symbolLocalOnly = Symbol('LocalOnly')

// デコレータ定義。対象フィールドにLocalOnlyのメタデータを付与する。
function LocalOnly(target: any, props: string) {
  Reflect.defineMetadata(symbolLocalOnly, true, target, props)
}

class Article {
  public title: string = ''
  public body: string = ''
  @LocalOnly
  public caretPosition: number = 0
}

// LocalOnlyフィールド削除関数(実際は再帰的にオブジェクトを辿るようにする)
function removeLocalOnly(data: any): any {
  const ret: any = {}
  Object.keys(data).forEach(key => {
    // LocalOnlyのメタデータが付与されていないものだけを処理
    if (!Reflect.hasMetadata(symbolLocalOnly, data, key)) {
      ret[key] = data[key]
    }
  })
  return ret
}
```

これにより

```typescript
const article = new Article()
const articleRemote = removeLocalOnly(article)
// fetchにarticleRemoteを渡す
```

と詰め直す処理を書かずに、クラス定義に指定をまとめることができます。

##まとめ
ローカル用とサーバ送信用の微妙に構造の異なるデータを取り扱うケースは結構あると思います。
そんな時はデコレータを利用して不要なフィールドを指定できると直感的だよというお話でした。
CERN ROOT 6.20/04 : Failed to load library libMathMore.so

# 導入

UbuntuにてCERNが配布しているROOTのBessel関数のtutorial(Bessel.C)を動作しようとしたら、出たエラーの内容と対処う方法についての説明

# 環境
- Ubuntu 18.04.4 LTS
- ROOT 6.20/04
- gcc 7.5.0
- GNU Make 4.1

# エラーの内容

ROOT installした時にあるBessel.Cを実行した際に以下のようなエラーが大量に発生。

```
$ root -x /path/to/root/tutorials/math/Bessel.C
...
Error in ... : Failed to load library /path/to/root/lib/libMathMore.so
...
```

# 解決方法

ROOT forumで解決方法を探していたところ、以下のリンクに行き着いた。
https://root-forum.cern.ch/t/failure-loading-library-libmathmore-so-for-root-gslintegrator/38597

調べてみると、GNU Scientific Library (GSL)が足りないらしい。
ということで、以下のようにしてこのLibraryをインストールした。

```
$ sudo apt-get install libgsl-dev
```

上記を実行して、再度Bessel.Cを実行すると正常に動作した。
ちなみに、Bessel.Cの説明は以下のリンクにある。（コードの中身と同じだが）
https://root.cern.ch/doc/master/Bessel_8C_source.html

# まとめ

Ubuntu 18.04.4 LTS にて ROOT 6.20/04 をインストールしたが、tutorialフォルダの中にある Bessel.C が動作しなかった。
これは GNU Scientific Library (GSL) がインストールされていないためであり、GSLをインストールすることで解決した。
herokuでDBバックアップ

herokuでDBバックアップの設定をしたかったので調べました。
めっちゃ簡単でした。

だいたいここ読めばいけます。
https://devcenter.heroku.com/articles/heroku-postgres-backups


## 手動バックアップ
https://devcenter.heroku.com/articles/heroku-postgres-backups#creating-a-backup
```sh
$ heroku pg:backups:capture --app {アプリ名}
```

## 定期バックアップ
https://devcenter.heroku.com/articles/heroku-postgres-backups#scheduling-backups

```sh
heroku pg:backups:schedule DATABASE_URL --at {タイムゾーンと時間指定} --app {アプリ名}
```

通常は定期バックアップをとっておいて、大型リリース作業前に手動でバックアップとっておくという運用になるかなと思います。
保持期限はこちらを参照ください。
https://devcenter.heroku.com/articles/heroku-postgres-backups#scheduled-backups-retention-limits

以上です。
データフレーム の扱い方

```
import pandas as pd
import numpy as np
```

### csvファイルを読み込む

```
df=pd.read_csv('〜〜〜.csv',header=None,names=('name', 'id'))
```
names=〜〜でカラム名を指定。
header=Noneで一行目をheaderと認識しないようにしている。

###データの一部を置換する

```
df=df.replace('A B', 'エー ビー')
df=df.replace('B A', 'ビー エー')
```

###dfの一つのカラムの中のテキストを分割して新たに2つのカラムにする
```
df2 = pd.concat([df, df['name'].str.split(' ', expand=True)], axis=1).drop('name', axis=1)
```

### ｄｆの複数の列を取り出す
```
df=df.loc[:,["列名","列名","列名"]]
```

###dfどうしを縦に結合する
```
df3=pd.concat([df1, df2])
```

###重複した行を削除する
```
df=df[~df.duplicated()]
```

###条件を満たす行を取り出す
```
df[df["列名"]=="~~"]
```

###dataframeをリストにする
```
df_list=df.values.tolist()
```

###列のリストをarrayにする
```
df_list=np.array(df['列名'])
```
Markdown表記法の互換性についてのメモ

Qiitaの記事作成や、GitHubのREADMEなどでも広く採用されているMarkdownですが、その表記法がサイトやソフトによって若干異なります。

[John Gruber氏が考案したMarkdown](https://daringfireball.net/projects/markdown/)はもともと、Markdown記法のテキストファイルをPerlで書かれたparserを通じてHTMLを生成するという、表記法とparserがセットになったものでした。その後、その利便性からPerl以外のparserも開発され、さらには[Pandoc](https://pandoc.org/)のようにHTMLのみならずEPUB形式など複数の形式へ出力できるものが登場しました。そして同時に新たな拡張機能と、その拡張機能を利用するための表記法が追加され、結果としてソフトごとの表記法に差異が生じるようになりました。この表記法（およびその表記法で実現する機能）の差異が、flavor、syntax extension、方言、などと呼ばれているものです。

[Markdown Community](http://markdown.github.io/)が[Markdown parser一覧](https://github.com/markdown/markdown.github.com/wiki/Implementations)を公開していますが、この一覧はあくまでparserの一覧であり、その他にも[PandocのMarkdown](https://pandoc.org/MANUAL.html#pandocs-markdown)をベースにした、ドキュメント中のRコードの実行を想定した[R Markdown](https://rmarkdown.rstudio.com/)や、[remark](https://remark.js.org/)をベースにJSXも書けるようにした[MDX](https://mdxjs.com/)などが登場しており、Markdownは今も多様化しています。

しかしそれぞれのparserでMarkdownの表記法が全く異なるというわけではなく、使用頻度の高いものは一部統一されていたりもします。例えばバックティック3つ（```` ``` ````）で囲んでコードブロックを表現するという所作はオリジナルのMarkdownではサポートされていませんが、今ではMarkdown表記法のデファクトスタンダードになっていると言えるでしょう。

ただし表記法が同じでも生成されるHTMLはparserにより異なります。parserごとのHTMLの違いは[babelmark](https://babelmark.github.io/)というサイトで見ることができます。

このような状況を受けて、表記法の標準化を目指す[CommonMark](https://commonmark.org/)が2014年に登場しました。2019年には[バージョン0.29](https://spec.commonmark.org/0.29/)が公開され、今後もアップデートされていくでしょう。Markdownによるドキュメントの管理を予定している場合、動向を注視する必要がありそうです。

（個人的には[Python-Markdown](https://python-markdown.github.io/)で採用されている[Admonition](https://python-markdown.github.io/extensions/admonition/)機能がかなり気に入っているのですが、[remark-admonitions](https://github.com/elviswolcott/remark-admonitions)では表記法が異なっていたりするので統一されないかなあと期待しています。）

#備考
この記事は[クリエイティブ・コモンズ 表示 4.0 国際 ライセンス](https://creativecommons.org/licenses/by/4.0/deed.ja)の下に提供されています。
<a rel="license" href="https://creativecommons.org/licenses/by/4.0/deed.ja"><img alt="クリエイティブ・コモンズ・ライセンス" style="border-width:0" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /></a>
IQ Bot：マッピング設定のやりかた　フォームフィールド【応用編】ラベルと値がくっついている場合

IQ Botの[フィールドのマッピングの基本編](https://qiita.com/IQBotter/items/d569254f986cfeb1155c)では、ラベルと値の青い枠のかたまりがきれいにわかれている例をとりあげました。
（青い枠のかたまりについての詳細は[こちら](https://qiita.com/IQBotter/items/1e0a36fb69393106d025)。）

ですが、帳票によっては以下のように、ラベルと値のかたまりがくっついている場合があると思います。

![くっついてたら.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/ff406c14-235a-dbaf-a6bb-03883dcfc1a1.jpeg)

このページでは、そのような場合のマッピングのしかたを紹介します。

#ラベルと値の青枠がくっついている場合の対応方法

以下のように対応します。

![ラベルと値がくっついている.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/933420dc-fa10-4f95-d891-459c2416298a.gif)

上記の動画を見てもらえればわかるかと思いますが、
値のマッピングでは「TEL：03-xxxx-xxxx」のエリア全体を囲っているにも関わらず、
抽出された結果からはラベルの「TEL：」が除外され、値だけが取得できています。

このように、**取得した値の先頭にラベルと重複する文字列がある場合は、それを除外した部分を値として抽出する**というのがIQ Botの仕様になっています。

#注意点

このやりかたが可能なのは、ラベルが取得したい文字列の**最初**にある場合のみです。

例えば「〒111-1111」のうち、ラベルとして使いたい「〒」を除外するのは上記のやりかたでできますが、「●●社御中」の「御中」を除外するのは上記のやりかたではできません。

その場合は、[ラベルなしの項目の取得方法](https://qiita.com/IQ_Bocchi/items/9082c2b262004694bada)と[カスタムロジック](https://qiita.com/IQBotter/items/1d8e7c77ad47e838476c)を組み合わせて対応するなどのやりかたが考えられます。
【LINE】既存LIFFアプリにShareTargetPickerを導入する

# はじめに
既存のLIFFアプリにShareTargetPickerを導入する方法を説明します。
GitHubは[こちら](https://github.com/yagi-eng/liff-reservation)。

## ShareTargetPickerとは？
以下が参考になります。
[Share Target Pickerがリリースされ、LIFFアプリからのメッセージ送信が大幅に強化されました。](https://engineering.linecorp.com/ja/blog/liff-share-target-picker/)

>Share Target Pickerとは、LIFFから送信先を選んでメッセージを送信することが出来る機能です。
これにより、
・トークルームやグループから開かれなかった場合でも、メッセージを送信できる
・LIFFアプリをLINE上で開いた場合だけではなく、ブラウザから開いた場合もメッセージを送信できる
・自分以外の友だちや自分が入っていないグループにもメッセージを送信させることができる
といったことが可能になります。

## サンプル
https://yagi-eng.github.io/liff-reservation-githubpages/
送信ボタンをクリックするとLINEの友だち選択画面が表示され、テキストの送信先を選択できます。

# 導入
## LINE Developersの変更
<img width="420" alt="stp.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113263/ad748d19-c68a-c29b-7f49-40979df02907.png">
シェアターゲットピッカーをオンにします。

## 実装
以下のQiita記事で作成したLIFFアプリにShareTargetPickerを導入します。
[【LIFF入門？】LIFFでLINE Offical Account（旧LINE＠）上に予約フォームを作成する](https://qiita.com/yagi_eng/items/5fd916fbaa6bafe42577)

以下のようにliff.jsを修正します。
gitのdiffは [こちら](https://github.com/yagi-eng/liff-reservation/commit/b4006f3ba55bdfdf92d21a2d1537dcba788f3387) です。
diffの方が何を追記すれば良いかわかりやすいかも。

```javascript:liff.js
$(document).ready(function () {
    var liffId = "（自分のLiffIdを入力）";
    initializeLiff(liffId);
})

function initializeLiff(liffId) {
    liff
        .init({
            liffId: liffId
        })
        .then(() => {
            if (!liff.isInClient() && !liff.isLoggedIn()) {
                window.alert("LINEアカウントにログインしてください。");
                liff.login();
            }
        })
        .catch((err) => {
            console.log('LIFF Initialization failed ', err);
        });
}

function sendMessage(text) {
    if (liff.isInClient()) {
        sendMessages(text);
    } else {
        shareTargetPicker(text);
    }
}

function sendMessages(text) {
    liff.sendMessages([{
        'type': 'text',
        'text': text
    }]).then(function () {
        liff.closeWindow();
    }).catch(function (error) {
        window.alert('Failed to send message ' + error);
    });
}

function shareTargetPicker(text) {
    liff.shareTargetPicker([{
        'type': 'text',
        'text': text
    }]).catch(function (error) {
        window.alert('Failed to send message ' + error);
    });
}
```

LINEトークから開いた場合は `sendMessages` を使ってそのトーク上にメッセージが送信されるように、LINEトーク以外から開いた場合は `shareTargetPicker` を実行するようにしました。
こうすることで、既存機能に影響なく導入することができます。

# 感想
LINE上で動作するものを作るの楽しいです。
これで仕事取れるようになるといいな。。
Vuexのmutationのメソッドをmutationのメソッドから叩こうとしてしまっていた話

# はじめに

私は最近仕事の実装でVue.jsやVuexのコードを編集することが多いです。その中で若干疑問に思い、そして解決したことについて書いていきたいと思います。

# Vuex内部でのパラメータ呼び出し

Vuexの中で定義したパラメータやメソッドを同じVuexの中で呼び出す方法が幾つもあります。

## mutationからstateを呼び出す
```javascript
var store = new Vuex.store({
  state: {
    hoge: 'fuga'
  },
  mutation: {
    piyo: function(state, val) {
      state.hoge = val;
    }
  }
});
```

## getterからstate, getterを呼び出す

```javascript
var store = new Vuex.store({
  state: {
    hoge: 'hoge',
    fuga: 'fuga'
  },
  getters: {
    getHoge: function(state) {
      return state.hoge;
    },
    getHogeAndFuga: function(state, getters) {
      return getters.getHoge() + state.fuga;
    }
  }
});
```

## actionsから諸々を呼び出す

```javascript
var store = new Vuex.store({
  state: {
    hoge: 'hoge'
  },
  mutation: {
    setHoge: function(state, val) {
      state.hoge = val;
    }
  },
  actions: {
    doubleHoge(context, val) {
      var hoge = context.state.hoge;
      context.commit('setHoge', hoge + hoge);
    }
  }
})
```

actionの中で`context.getters.someGetter()`としてgetterを呼び出したり、`context.dispatch('someAction')`としてactionを呼び出すこともできます。

# 浮かんだ疑問

実装をしていく中、二つのmutationの処理をまとめて実行したいことがありました。しかしVuexでmutationからmutationを呼び出すにはどうすれば良いのでしょうか？

## mutationからmutationを呼び出す？

```javascript
var store = new Vuex.store({
  state: {
    hoge: false,
    fuga: false,
  },
  mutation: {
    setHoge: function(state, val) {
      state.hoge = val;
    },
    setFuga: function(state, val) {
      state.fuga = val;
    },
    setHogeAndFuga: function(state, val) {
      // setHogeとsetFugaを呼び出したい
    }
  }
});
```

# 結論

結論としては、mutationからmutationを呼び出すより真っ当な手段が幾つかあるというところに落ち着きました。

## 例1. 単純な変更処理をまとめたmutationを作る

今回実装で迷った部分に関して言えば、「ある動作を行った時にフラグを立てる」という単純なものだったので、フラグを立てる処理をまとめたmutationを作ることで解決することができました。

```javascript
var store = new Vuex.store({
  state: {
    hoge: false,
    fuga: false,
  },
  mutation: {
    setHogeAndFuga: function(state, vals) {
      state.hoge = vals.hoge;
      state.fuga = vals.fuga;
    }
  }
});
```
これでVueコンポーネント内から`this.$store.commit('setHogeAndFuga', vals)`とすることで操作できるようになります。

## 例2. 複数のmutationを行うactionを作る

また、もうすこし複雑な処理を幾つかまとめて実行したいという時でも、actionsにそれら処理をまとめて実行するactionを作成することで要件を満たすことができます。

```javascript
var store = new Vuex.store({
  state: {
    // ...
  },
  mutation: {
    mutationA: function(state, val) {
      // ...
    },
    mutationB: function(state, val) {
      // ...
    }
  },
  actions: {
    someAction: function(context, param) {
      context.commit('mutationA', param.a);
      context.commit('mutationB', param.b);
    }
  }
}):
```
このようにするとVueコンポーネント内では`this.$store.dispatch('someAction', param)`とすることで操作を行うことができます。

# 最後に
Vue.jsもVuexも中々難しいですが、仕事で頻繁に扱うものなので、しっかり技術を習得していきたいと思います。
Magnific Popup(ポップアップ) 使い方メモ(youtube)

#Magnific Popup

[github](https://github.com/dimsemenov/Magnific-Popup)

```javascript
//youtube ポップアップ
$(function (){
  $('.popup-youtube').magnificPopup({//動画リンクのaタグ要素を指定
    type: 'iframe',//ここの指定で画像のポップアップなども可能！
    mainClass: 'mfp-fade',
    removalDelay: 200,
    preloader: false
  });
});
```
```html
<!-- 読み込むもの -->
<link rel="stylesheet" href="css/magnific-popup.css">
<script type="text/javascript" src="js/jquery.magnific-popup.min.js"></script>
```
```html
<!-- ポップアップさせたいyoutube動画のURLを指定したaタグ -->
<a href="youtubeのURL" class="popup-youtube"></a>
```

youtubeの動画をポップアップする前提のメモになります。
他にも画像のポップアップなど色々できるみたいです。
もっと詳しく調べたら追記したいと思います。
[CSS] JSを使わずにパララックスを実装する【3D】

スクロールしたときに背景だけスクロール速度が変わるような**パララックス**は JavaScript で実装するのが一般的ですが、**CSS で要素を 3D 空間上に配置する**方法を使えば JavaScript なしでパララックスを実装することができます。

![b.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83774/1e32f7d6-07aa-a0e2-cd0d-d06c1cb034bf.gif)

```html

<div class="container">
  <div class="background">Background (z: -800px)</div>
  <div class="content">Content (z: 0px)</div>
</div>
```

```css
.container {
  width: 100%;
  height: 100vh;
  overflow-x: hidden;
  overflow-y: auto;
  perspective: 800px;
}

.background {
  z-index: -1;
  width: 200px;
  height: 200px;
  margin: 60px auto;
  transform: translateZ(-800px) scale(2);

  background: hsl(39, 97%, 63%);
  color: white;
}

.content {
  position: relative;
  width: 320px;
  height: 640px;
  margin: 0 auto;

  background: hsl(175, 61%, 77%);
  color: white;
}
```

## 解説

### Container

まず 3D 空間の基準となるコンテナ要素を作ります。

```css
.container {
  width: 100%;
  height: 100vh;
  overflow-x: hidden;
  overflow-y: auto;
  perspective: 800px;
}
```

- ここでは 100% x 100vh
- `overflow-y: auto` でスクロールされるようにする
- **`perspective` プロパティで空間の奥行きを指定する** (`perspective: 800px` だと 800px 手前の場所から見ている感じになる)

### Background

次に背景。

```css
.background {
  width: 160px;
  height: 160px;
  margin: 80px auto;
  transform: translateZ(-800px) scale(2);

  background: hsl(39, 97%, 63%);
  color: white;
}
```

- **`translateZ` で z 軸方向の位置を指定する** (ここでは基準のコンテナより 800px 奥に配置)

z 軸方向の位置が奥に行くほど見かけ上のサイズが小さくなりますが、**`scale`** に **`(z軸方向の位置) / -(perspective) + 1`** の値を指定すると元のサイズに見せかけることができます。

## さいごに

ここで紹介したパララックスを使ってポートフォリオを作りました。

https://yarnaimo.now.sh

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Next.js + Vercel (Now) でポートフォリオ作りました👌<a href="https://t.co/N1LYdqxIFS">https://t.co/N1LYdqxIFS</a> <a href="https://t.co/g5xu0wFbsF">pic.twitter.com/g5xu0wFbsF</a></p>&mdash; やまいも (@yarnaimo) <a href="https://twitter.com/yarnaimo/status/1254795950528188416?ref_src=twsrc%5Etfw">April 27, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
IQ Bot　帳票イメージの中の青い枠は何ですか？

#IQ Botの青い枠 = SIR

IQ Botのマッピング設定画面で、帳票イメージの部分を見ると、文字が青枠で囲まれているのがわかります。
この青い枠のことを、IQ Bot用語ではSIRと呼んでいます。

何の略かは……忘れました。。。
↑System-Identified-Region だそうです。(2021.1.19追記)

SIRには、以下の意味があります。

- ①　IQ Botが文字として認識した部分がSIRの対象になる
- ②　IQ Botが意味のあるかたまりとして認識した範囲でSIRが括られる

![青枠.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/dc6dfeed-a1c8-d677-3e5d-2d69167dc7ef.jpeg)

##①IQ Botが文字として認識した部分がSIRの対象になる

上記の図では、すべての文字が青枠で囲まれていました。
つまり、すべての文字をOCRが文字と認識したために、すべての文字がSIRの対象になったということです。

ですが、次の図のように癖が強いフォント（社名のロゴなど）や、画質が粗い帳票を読み込ませた場合、文字が書いてあってもSIRが形成されない場合があります。

![くせがすごい文字.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/b39d5945-11de-dcee-0aac-f40f7e639ee6.jpeg)

特殊なフォントの文字は、青枠で囲まれていませんね。

つまり、こちらはOCRが文字として認識しなかった部分ということになります。

##②IQ Botが意味のあるかたまりとして認識した範囲でSIRが括られる

IQ Botは、SIRをどの範囲でくくったり分けたりするかを自動で判別しています。

以下のように、ひとつの四角になっている範囲が「IQ Botがひとかたまりとしてくくった単位」です。

![IQ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/7d89ba28-c32d-db02-146c-c22739d00f27.jpeg)

#SIRの制約

SIRはIQ Botが取得した結果を表示するだけの機能なので、SIRそのものをユーザーが手動でいじることはできません。

たとえば、SIRが形成されなかった範囲（＝青い枠で囲まれなかった範囲＝OCRが文字として認識しなかった範囲）を文字として後から認識させるようにしたり、SIRを手動でくっつけたり離したりすることはできません。

![青い枠の制約.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/b82e3429-a15d-374b-c6aa-5d9eeacc8932.jpeg)

上記はあくまでも**「SIRそのものを人間がいじれるか」という話で、IQ Bot全体の取得結果としてくっつけたり離したりできないよという意味ではありません。**

IQ Botを触りたての人から、「この青い枠っていじれないんですか？」という質問を何度か受けたので、改めて記事にしてみた次第です。
氏名から性別を判定する。

```
pip install nltk
```

```
import nltk
import random
from nltk import classify
from nltk import NaiveBayesClassifier as NBC
```


## データ
### 男性の名前が入ったリスト(malelist)と女性の名前が入ったリスト(femalelist)を用意する。（ローマ字）（サンプル数は揃える）（姓名のうち名のみ）
#### 例: malelist=['kazuo','kenji',・・・・]

```name.py
def feature_extraction(word):
    return {"last":word[-3:]}
#名前のうち後ろ3文字のみを取り出す関数

maleNames=[(name, "male")for name in malelist]
femaleNames = [(name, 'female')for name in femalelist]
allNames = maleNames + femaleNames #男性のリストと女性のリストをくっつける
random.shuffle(allNames) #リストの中身をシャッフル

featureData=[(feature_extraction(n),gender) for (n,gender) in allNames]
#[(後ろ三文字,性別),(後ろ三文字,性別),(後ろ三文字,性別)・・・]の形にする

genderIdentifier=NBC.train(featureData)

#精度を確かめたい場合はしたのような感じで、、
#num=7*len(featureData)//10 データの
#train_data=featureData[num:]
#test_data=featureData[:num]
#genderIdentifier=NBC.train(train_data)
```

###作ったモデルを保存する方法

```
import pickle
f = open('my_classifier.pickle', 'wb')
pickle.dump(genderIdentifier, f)
f.close()
```
###保存したモデルをロードする方法

```
import pickle
f = open('my_classifier.pickle', 'rb')
classifier = pickle.load(f)
f.close()
```


参考
-

[Save Naive Bayes Trained Classifier in NLTK](https://intellipaat.com/community/4295/save-naive-bayes-trained-classifier-in-nltk)

[Machine Learning Model - Gender Identifier with NLTK in less than 15 lines of code](https://medium.com/@vardhmanandroid2015/machine-learning-gender-identifier-with-nltk-in-less-than-15-lines-of-code-567b9138c5e7)

[Machine Learning Model - Gender Identifier with NLTK in less than 15 lines of code](https://www.youtube.com/watch?v=EbjPDbmJYCE)
【Xcode】XcodeでViewのFrameをデバッグで表示!! "Show View Frames"が超便利

## XcodeのDebugタブにあるShow View Frames

以下をクリックすると、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/d242d8f8-ded5-807f-2a86-5b9f74d5364c.png)

下記の画像、動画のように各コンポーネントのframeが表示されるようになります。

<img width="375" alt="IMG_CAB45806F13E-1.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/7131b595-8520-c5a2-0b52-d4f2855b1d64.jpeg">

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">xcodeにframe表示させる機能あるの知らなかった、、、<br><br>いつからあったの、、、 <a href="https://t.co/j4wu0UHcSP">pic.twitter.com/j4wu0UHcSP</a></p>&mdash; TeppeiKikuchi🇮🇩Flutter修行中 (@tpi29) <a href="https://twitter.com/tpi29/status/1255067788281929728?ref_src=twsrc%5Etfw">April 28, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Djangoのプロジェクト作成から初期設定をする方法

# Djangoのプロジェクトの作成から初期設定まで
Djangoでプロジェクトを作成してから初期設定を行うまでの解説を行います^_^

### 環境
Python 3.7.6
Django 3.0.5

### プロジェクトの作成
まずはプロジェクトを作成するためのディレクトリに移動します。
そこで下記のようにプロジェクトを作成します。この際にプロジェクト名は任意になりますが今回はwebprojectになります。
フォルダの中を確認するとmanage.pyが含まれていることが確認できます。

```
ChisakinoMacBook-Pro:webapp Chisaki$ django-admin startproject webproject .
ChisakinoMacBook-Pro:webapp Chisaki$ ls
manage.py	webproject
```

次に下記のようにフォルダを追加していきます。この際にもフォルダの名前は任意になりますが今回はwebappになります。

```
ChisakinoMacBook-Pro:webapp Chisaki$ python3 manage.py startapp webapp
ChisakinoMacBook-Pro:webapp Chisaki$ ls
manage.py	webapp		webproject
```

次にさらにテンプレート用にフォルダを追加します。このフォルダ名も任意になりますが今回はtemplatesになります。

```
ChisakinoMacBook-Pro:webapp Chisaki$ mkdir templates
ChisakinoMacBook-Pro:webapp Chisaki$ ls
manage.py	templates	webapp		webproject
```

初期の状態での大まかなフォルダはこのようになります^_^

### エディタでの設定
次にエディタの設定になります！setting.pyを開きます。
今回は40行目に際ほど追加したフォルダ名をここに書き入れます。webappを追記しましょう。
<img width="895" alt="スクリーンショット 2020-04-28 18.28.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587506/9d5a9e8c-3f4d-6e03-bf86-3868a88cfcae.png">

次は58行目に際ほど追加したテンプレートのフォルダを画像のように追記します。
<img width="895" alt="スクリーンショット 2020-04-28 18.30.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587506/5d284c97-9605-f2be-2978-764f2b1ca80b.png">

次はwebprojectの中にあるurls.pyに移ります。下記のように記述します。この際に2行目にincludeを追記することを忘れないようにしましょう。


```
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('webapp.urls')),
]
```

その次はwebappの直下にurls.pyを作成します。そして下記のように記述を行います。こちらのファイルは今後URLの繋ぎ合わせ使用します。

```
from django.urls import path

urlpatterns = [
    path('', ),
]
```

以上がDjangoのプロジェクト作成から初期設定をするまでの解説になります！ぜひご参考にしてください^_^
はじめてのTableViewController

##はじめに
これまでTableViewControllerを雰囲気で扱ってきたので自分用にまとめます。
手順に飛躍がないよう心がけています。

##Storyboradから作成(直感的でわかりやすい)
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/c804a6bd-0d04-6d8e-593f-8dcaeec23705.jpeg" width = "500"> <img width="400" alt="スクリーンショット 2020-04-28 17.10.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/c4364f24-2eeb-1767-1584-e1cc62ac3844.png">


ほとんど画像の通りです。

これで実行すると、画面いっぱいにセルが広がっているのではないでしょうか。

<img width="1511" alt="スクリーンショット 2020-04-28 17.19.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/6592906b-af58-9717-2cbc-3c9c860e423c.png">

UItableViewをOutlet接続します。
Outlet接続は右クリックとかControlボタンを押しながらドラッグ&ドロップでできます。
IBAction接続と間違えないようにしましょう。

```swift
override func viewDidLoad() {
        super.viewDidLoad()
        tableview.delegate = self
        tableview.dataSource = self
    }
```
上のコードを書くと、エラーが出るので素直にFixしましょう。
<img width="898" alt="スクリーンショット 2020-04-28 17.19.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/f646f63b-f0c3-593b-823d-95e278a27531.png">

Fixするとまた新たなエラーが出るので、またまた素直にFixしましょう。

<img width="817" alt="スクリーンショット 2020-04-28 17.28.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/e4c86319-442f-dc63-b1af-c50c57a01822.png">

そうすると画像のような関数(いわゆるプロトコル)が勝手に追加されます。
ここからの内容はTableViewControllerに何を書くかによって変わってきます。下以降はあくまで一例。

```swift
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel!.text = "これは第\(indexPath.row)行目です"
        return cell
    }
```

上のコードを書くと
<img width="375" alt="Simulator Screen Shot - iPhone SE (2nd generation) - 2020-04-28 at 17.38.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/b0000227-2edc-07a8-b3ee-a460ca2fd121.png">

みたいになります。

意味としてはセルの数は10個だよ。
セルのラベルはInt型のindexPath.rowにするよ。
という感じです。目的に応じて変えましょう。

##コードから作成(慣れると複雑なことまで設定できる)

```swift

import UIKit

class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
    
    var tableView: UITableView?
    override func viewDidLoad() {
        super.viewDidLoad()
        self.tableView = {
            let tableView = UITableView(frame: self.view.bounds)
            self.view.addSubview(tableView)
            tableView.delegate = self
            tableView.dataSource = self
            return tableView
        }()
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
           return 10
       }
       
       func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
        cell.textLabel?.text = "第\(indexPath.row)行目です"
        return cell
    }
}
```

先にコードを貼りました。Storyboradで行ったことはコードだけでも行うことができます。
delegateやDatasourceの設定はほとんど同じです。
viewDidLoad()でUITableVieを定義し、addSubViewしましょう。
gem hanmotoを使って静的ファイルを生成

## 静的ファイル

RailsでWebアプリケーションを作成する際に、Not Foundページやエラーページを予めhtmlとして置いておいて表示させるのが通常ですが、この場合viewのlayoutファイルなどRailsのリソースが流用できず面倒です。

## hanmoto

hanmotoを使うとlayoutファイルを使って静的ファイルを生成することができるので便利です。

## 設定

こちらの通り設定をしていきます。
https://github.com/aki77/hanmoto

```rb
# initializersにhanmoto用の設定ファイルを置きます。
config/initializers/hanmoto.rb

Hanmoto.configure do |config|
#   config.view_dir = 'public_pages' # hanmoto甩のviewファイル置き場。デフォルトは`public_pages`
#   config.layouts = {
#     html: 'public',                # 使用するlayoutファイル。通常のlayoutと使い分けたいなどに設定する。デフォルトは`public`
#   }
end
```

## ファイル用意
生成したいファイルを指定のディレクトリに置きます
例：

```sh
$ ll app/views/public_pages 
403.html.slim
404.html.slim
422.html.slim
500.html.slim
502.html.slim
503.html.slim
```


## 生成

```sh
$ rake assets:precompile
OR
$ rake hanmoto:publish
```

するとpublic配下に静的ファイルが生成されます。
便利。
スペルチェック用辞書に誤って登録した無視ワードを削除する

## はじめに
PyCharm等で結構お世話になるスペル(Typo)チェック機能ですが
誤って誤字を許可ワードとして登録してしまった為　　
辞書を編集する方法を調べたのでメモします。

## 修正方法
1. `Preferences`を開き `Editor > Spelling > Accepted Words`選択
1. 登録したワード一覧が表示されるので， 削除したいワードを選択し`-`ボタンを押す
![スクリーンショット 2020-04-28 18.17.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122764/61a1ad45-8065-fa0a-c139-44ee1541dcf2.png)

## 参考
[スペルチェック﻿ 公式ヘルプ](https://pleiades.io/help/pycharm/spellchecking.html)
Amazon SageMaker JupyterLabで行番号をデフォルト表示したい

# はじめに
Amazon SageMakerのJupyterLabで行番号をデフォルト表示する手順です。

# 参考
https://safarisp.hatenablog.com/entry/2019/02/13/221528

# 手順
1. ノートブックインスタンスを起動し、JupyterLab を開いた状態で、「Settings」→「Advanced Settings Editor」を開く

2. 「Notebook」を選択する
　左側に「System Defaults」、右側に「User Preferences」が表示される

3. 「System Defaults」の中身を「User Preferences」にコピーする

4. 右側「User Preferences」の
```"codeCellConfig": {
     "lineNumbers": false
}```
を
```"codeCellConfig": {
      "lineNumbers": true
}```
に変更する。

5. 右上のフロッピーボタン「Save User Settings」を押すと設定が保存される。

6. Notebookを開き直すと、行番号がデフォルト表示される！
（うまく反映されない場合はJupyterLab再起動もしくはノートブックインスタンスの再起動をする）

#おわりに
Amazon SageMakerのJupyterLabで行番号をデフォルト表示する手順が見つからなかったので記事にしました。

初投稿です。pythonの知識とともに語彙力も上げたいな。
【MS ACCESS】サブレポートでセットしたレポートの「読み込み時」イベントが発火しないから、「開く時」で処理。

メモとして残します。

サブレポートでセットしたレポートの**「読み込み時」（Report_Load）**イベントは発火しないようです。
表示されたら実行させたい場合、**「開く時」Report_Open**イベントに定義したほういいみたいです。

```vb
Private Sub Report_Load()
    'こいつは、サブレポートで呼び出されたときは実行されない。
    'サブレポートをクリックしてフォーカスしたときにはなぜか実行される。
End Sub

Private Sub Report_Open(Cancel As Integer)
    'こいつはサブフォームでも開いたときに実行される。
End Sub

```
CloudWatch ロググループの保持期間を一括で設定（上書き）する

過去のゴミが溜まっているので、面倒なので一括で上書き設定するスクリプト

```:bash
#!/bin/bash

for i in $(aws logs describe-log-groups | jq -r ".logGroups[].logGroupName")
do
  aws logs put-retention-policy --log-group-name $i --retention-in-days 30
  echo "complate $i"
done
```

この後、数日後に [CloudWatchの空になったロググループ削除
](https://qiita.com/mkawanee/items/c0929b7af6ea977d479b) 辺りのスクリプトを流せば、30日以上ログが出力されていないロググループのお掃除が完了する
pygameでウィンドウのみ表示されて何も表示がされない時の対処法メモ

##**pygameを用いる際の初歩的な部分の話です。**

- 自分の環境
  - 使用パソコン：MacBook Pro (Retina, 13-inch, Late 2013)
  - OS：Catalina
  - pythonのバージョン：Python 3.7.3

どうやら、macだとMojave以降のOSだとこの不具合が起こるようです。

##対処法
**pygameの開発バージョンをインストール**
ターミナルで以下のコマンドを入力しましょう。

```python
pip3 install pygame==2.0.0.dev3
```

自分はこの方法で解決しましたが、どうやらpythonのバージョンをアップデートすることによっても解決することができることがあるようです。



---

記事を書くことに慣れていません。
もしよろしければコメントなどで改善点を指摘してくださると幸いです。
Windowsに溜まったゴミを大掃除(ディスククリーンアップでは取れない)

##Windows update サービスの停止##
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495537/4fc3002c-3065-4391-3f8f-e2bf4996d8c8.png)

コマンドプロンプトを起動
```net stop wuauserv```
Windows updateサービスを停止させて・・・
C:\Windows\SoftwareDistribution\Download
このフォルダ直下にあるファイルを削除し、
```net start wuauserv```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495537/db381d20-c3ce-75c6-6f1d-07c896db53db.png)
この画面が出てきたら成功～

##WinSxSの不要なコンポーネントファイルを削除##
###不要なコンポーネントの確認###
コマンドプロンプトで以下を入力
```Dism.exe /Online /Cleanup-Image /AnalyzeComponentStore```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495537/7774831d-be97-a737-c86c-ccd29a681733.png)
ちょっと時間がかかります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495537/181c2424-9279-ebb7-1636-73c06ada2572.png)
この場合はクリーンアップ推奨されませんでしたが、
```Dism.exe /Online /Cleanup-Image /AnalyzeComponentStore```
を実行します

##DNSレゾルバのキャッシュを削除##
コマンドプロンプトで以下を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495537/7aa1173c-7cf8-b8a9-2e10-406b63e1b15b.png)
##Microsoft Storeのキャッシュを削除##
コマンドプロンプトで以下を入力
```wsreset```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495537/df22b858-5164-fb80-43f2-e71ac66f4be0.png)
Microsoft Storeアプリが立ち上がったら成功です！
BigQueryデータ基盤のテーブル参照回数を管理する

# 背景

BigQueryデータ基盤のコストを下げたい場合を想定。
データエンジニアとしては不要なテーブルを棚卸ししたい。

「この毎日更新されているデータマートは本当に必要なのか？」
「この2年前から更新されていない異常に大きなサイズのテーブルは本当に必要なのか？」

などなかなか棚卸しの判断がつかないことが多い。

前の記事([BigQueryデータ基盤のテーブル依存関係を管理する](https://qiita.com/munaita_/items/0114dad655f6ccf758bf))同様、今回もBigQueryの `INFORMATION_SCHEMA.JOBS_BY_PROJECT` を使って、過去180日にどのテーブルが何回実行されたを表すテーブルを作成する。

# やる方

以下のSQLの実行結果でテーブル作成するだけ。過去180日に実行されたBigQueryJobから、どのテーブルが何回実行されたかのテーブルを生成する。

```sql
WITH base_tables as (
SELECT
  job_id,
  creation_time,
  REGEXP_EXTRACT_ALL(query, "(?:FROM|JOIN)[\\s \\n]+`(.+?)`") as tables
FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT 
WHERE job_type = "QUERY" 
AND state = "DONE" 
)

SELECT
  SPLIT(t, ".")[OFFSET(ARRAY_LENGTH(SPLIT(t, ".")) - 1)] as table_name,
  COUNT(creation_time) as reffered_count
FROM base_tables, UNNEST(tables) as t
GROUP BY 1
ORDER BY 2 desc
```

# これで嬉しいこと

コスト削減のため削除したいテーブルがある場合、以下のようなSQLを投げると削除して良さそうなテーブルか確認できる。180日参照されていなかったら削除を検討してもいいと思う。

```SQL
SELECT * FROM reffered_count_table WHERE table_name LIKE "%the_table_name%"
```

あとは逆に、このテーブルの参照数が少ないテーブルを棚卸し対象として検討できるのも嬉しい。


# 参照
- [「DeNA データプラットフォームにおける自由と統制のバランス」](https://www.youtube.com/watch?v=S3jUEl9pEmM&feature=youtu.be&t=8860)
便利なC#メモ メッセージボックス編

#初めに
皆さんこんにちは。TheNorthFace_XDと申します。
今回からC#の細かい・簡単なことだけど便利なメモ(?)を作ります。
Qiita初心者なのでどーぞよろしくお願いします:laughing:
#メッセージボックスの表示
```csharp
MessageBox.Show("Message","Title",MessageBoxButtons.OK);
```

#MessageBoxButtons列挙体のメンバ名
OK　:arrow_right:　「OK」ボタンのみ

```csharp
MessageBox.Show("Message","Title",MessageBoxButtons.OK);
```

OKCancel　:arrow_right:　「OK」と「キャンセル」ボタン

```csharp
MessageBox.Show("Message","Title",MessageBoxButtons.OKCancel);
```
AbortRetryIgnore　:arrow_right:　「中止」・「再試行」・「無視」ボタン

```csharp
MessageBox.Show("Message","Title",MessageBoxButtons.AbortRetryIgnore);
```
※メッセージボックスの閉じるボタンが無効。

YesNoCancel　:arrow_right:　「はい」・「いいえ」・「キャンセル」ボタン

```csharp
MessageBox.Show("Message","Title",YesNoCancel);
```

YesNo　:arrow_right:　「はい」と「いいえ」ボタン

```csharp
MessageBox.Show("Message","Title",MessageBoxButtons.YesNo);
```
※メッセージボックスの閉じるボタンが無効

RetryCancel　:arrow_right:　「再試行」と「キャンセル」ボタン

```csharp
MessageBox.Show("Message","Title",MessageBoxButtons.RetryCancel);
```
#MessageBoxIcon列挙体のメンバ名

None　:arrow_right:　アイコンが無く、メッセージボックスを表示するときに一般の警告音が鳴ります。

```csharp
MessageBox.Show("Message","Title",MessageBoxIcon.None);
```
Hand / Error　:arrow_right:　赤い丸に白い×（停止マーク）が表示されます。

```csharp
MessageBox.Show("Message","Title",MessageBoxIcon.Hand);
```

```csharp
MessageBox.Show("Message","Title",MessageBoxIcon.Error);
```
※メッセージボックスを表示するときにシステムエラーの音が鳴ります。エラーメッセージを表示するときなどに使用します。

Question　:arrow_right:　丸い吹き出しに?記号。メッセージボックスを表示するときに「メッセージ（問い合わせ）」の音が鳴ります。

```csharp
MessageBox.Show("Message","Title",MessageBoxIcon.Question);
```
※現在はこのアイコンの使用が推奨されておらず、下位互換性を維持するためにのみサポートされています。

Exclamation / Warning　:arrow_right:　黄色い三角に!記号。メッセージボックスを表示するときに「メッセージ（警告）」の音が鳴る。

```csharp
MessageBox.Show("Message","Title",MessageBoxIcon.Exclamation);
```

```csharp
MessageBox.Show("Message","Title",MessageBoxIcon.Warning);
```
※ユーザーに確認をするときなどに使用する。

Asterisk / Information　:arrow_right:　丸い吹き出しに「i」

```csharp
MessageBox.Show("Message","Title",MessageBoxIcon.Asterisk);
```

```csharp
MessageBox.Show("Message","Title",MessageBoxIcon.Information);
```
※メッセージボックスを表示するときに「メッセージ（情報）」の音が鳴ります。ユーザーに情報を表示するときなどに使用する。

#MessageBoxButtons列挙体のメンバ名とMessageBoxIcon列挙体のメンバ名の併用
MessageBoxButtons列挙体のメンバ名とMessageBoxIcon列挙体のメンバ名の併用は可能です。

```csharp
MessageBox.Show("Message","Title",MessageBoxIcon.Information,MessageBoxButtons.OK);
```

#最後に
LGTM・フォローお願いします！
このページのコードを使用する際の報告・表記は必要ありません:joy::thumbsup: