OmniAICreator/Qiita-1.07M huggingface dataset:
Laravelではメール送信やSlack通知のテストが簡単だって知ってましたか？


メールやSlack通知のテストしてますか？
通知のテストはし難いのですが、Laravelではモックが充実しているので簡単にテストすることができます。

参考: https://readouble.com/laravel/6.x/ja/mocking.html

### 環境

* PHP v7.2
* Laravel v6.x
* PHPUnit v7.5

### テストする方法

以下のようにpostのテストを実行する前に Mail Facade で fake を差し込むようにしておく。
postテスト実行した後に、`assertSent()` でMailableクラスの処理が走っているかテストできます。

```php
use Illuminate\Support\Facades\Mail;

class IndexControllerTest extends TestCase
{
    public function testIndex()
    {
        Mail::fake();

        $this->post('/path/to/something/post', ['text' => 'ダミーテキスト'])->assertRedirect();

        // MessageCreatedクラスは、Mailableをextendsしたものです。実行されているべきMailableをフルパスで指定します。
        Mail::assertSent(MessageCreated::class);
    }
}
```

### おまけ

##### notificationもテストできます。
Slack通知など。
ドキュメントの `Notification Fake` のところを参照してください。
「テストをかけるよ」ということを知識として知っていないとなかなかかけないのでここで紹介だけしておきます。

##### ハマりどころ
最初、以下のように書いて動かずにハマったので共有しておきます。

```php
    public function testIndex()
    {

        $this->post('/path/to/something/post', ['text' => 'ダミーテキスト'])->assertRedirect();

        // postのテストが終わった後にfake差し込み
        Mail::fake();
        Mail::assertSent(MessageCreated::class);
    }
```

fakeを差し込むタイミングが終わった後なので意味がありません。

##### 面倒なので毎回 fake を書きたく無い場合
setUp()のなかで処理を追加しておきましょう。
毎回クラスに書いてもいいのですが、これを差し込んだ共通親クラスを作っておくともっと楽チンです。

```php

    protected function setUp(): void
    {
        parent::setUp();

        Mail::fake();
    }

```
GCP アップデート (1/17-1/23 2020)

### BigQuery: [Jan 16, 2020](https://cloud.google.com/bigquery/docs/release-notes#January_16_2020)
- [Magnitude Simba JDBCとODBCドライバのドキュメント](https://cloud.google.com/bigquery/providers/simba-drivers/)が新しくなったよ。

### Compute: [Jan 21, 2020](https://cloud.google.com/compute/docs/release-notes#january212020)
- NVIDIA Tesla T4が以下のゾーンで使えるようになったよ！
  - Tokyo: asia-northeast1-c
  - Singapore: asia-southeast1-c
  - Iowa: us-central1-f
  - Mumbai: asia-south1-a
- MIGのオートスケールの設定を一時的に無効にする機能がGAになったよ。

#### ブログから:  [Secret Manager](https://cloud.google.com/blog/products/identity-security/introducing-google-clouds-secret-manager)
- APIキーやパスワード、証明書等を管理してくれるサービス。
- KMSやBerglasとも連携可能。
- まだ日本リージョン指定できなかった。。



### ディスクレーマ
- アップデートの内容はあくまでも個人の理解していることを書いています。正しい内容はリリースノート等を確認下さい。
- リリース内容できるだけ拾うようにしているのですが、抜けていそうなリリースノートが追加するのでぜひ教えて下さい！(一覧[ここ](https://qiita.com/kenzkenz/items/ac18a359b803dbb6b490)で更新してます。)
MySQLのtimestampのデータが勝手に更新されてる

# 現象

```sql
> update users set status = 9, modified = now() where id = 1;
```

上記を叩いてきちんと更新されているか確認してみると、`modified`だけではなく`created`まで更新されてしまった。。

```sql

-- 元々のデータ
> select * from users;
*************************** 1. row ***************************
   user_id: 1
    status: 1
   created: 2015-05-26 04:01:21
  modified: 2018-03-03 05:54:54

-- 更新したデータ
> select * from users;
*************************** 1. row ***************************
   user_id: 1
    status: 9
   created: 2020-01-21 00:00:00 -- あれ、こっちまで更新されてる。。
  modified: 2020-01-21 00:00:00

```

# 原因
結論、`created`が`CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`で設定されているからでした。

```sql
> show create table users\G
*************************** 1. row ***************************
       Table: users
Create Table: CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `status` tinyint(4) NOT NULL,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
```

`CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`があるとupdate文をかけた時に自動更新されるような設定なため、勝手に`created`も更新されていたようです。
timestamp型は、デフォルトで`CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`が付いてしまうらしい？

## 無効化
下のsqlを叩いて自動更新を無効化しました。

```sql
> alter table users modify created timestamp default '1970-01-01 00:00:01'
```
文字を画像化してslackに投稿 (python slackbot)

前回(かなり前ですが)に書いたhubotの文字を画像化して投稿するスクリプトですが、
最近は、Pythonをさわる機会が多いのと、
python slackbot が使いやすいと思うので、pythonで書き直してみました

pythonだと、ImageMagicを入れなくていい代わりに、pip で Pillow を入れる必要があります

Pythonは3以降を使用しています、
環境によっては下記コマンドはpipではなく、pip3だったりします

# Pillowをインストール

```
pip install Pillow
```

# 文字を画像化してslackに投稿するスクリプト

```Python
# -*- coding: utf-8 -*
from slackbot.bot import respond_to
from slackbot.bot import listen_to
from slackbot.bot import default_reply

from PIL import Image, ImageDraw, ImageFont
import random

@respond_to('str_img\s+(.*)')
def mention_func1(message, arg1):

    spcolor = [
      'magenta',
      'orange',
      'LimeGreen',
      'blue',
      'purple',
      'OrangeRed',
      'SkyBlue',
      'LightBlue',
      'Turquoise',
      'gold'
    ]

    im = Image.new("RGB",(50,50),"white")
    fnt = ImageFont.truetype('/slackbot/plugins/cp_font.ttf', 50)
    draw = ImageDraw.Draw(im)
    text_size = draw.textsize(arg1, fnt)
    im = im.resize(text_size)
    draw = ImageDraw.Draw(im)
    draw.text((0,0), arg1, fill=random.choice(spcolor), font=fnt)
    im.save("/tmp/str_img.png")
    message.channel.upload_file(fname="/tmp/str_img.png", fpath="/tmp/str_img.png")
```

# よくわかってないところ

- 文字を追加して、文字幅分のイメージを作成するために、ImageDraw.Draw を二回してます
  - python（とくに画像関連）に詳しいわけじゃないので、他にいい書き方があれば修正します

# その他

- 画像サイズを変えるオプションを前回はつけていましたが、
slack に表示されるときに同じ大きさにされてしまうので、今回は省きました
Googleサイトを公開するまで

#注意
これは、本校生徒向けに作成したものです。
基本的には、[ここ](https://support.google.com/sites/answer/6372880?hl=ja)が公式の説明です。

#Googleサイトを公開するまでの流れ
1.画面上部の「公開」のボタンを押す
![スクリーンショット 2020-01-21 18.12.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257844/74868d5a-aec2-1559-bd8f-cfb1103beca0.png)


2.「サイトを閲覧できるユーザー」→「管理」
![スクリーンショット 2020-01-21 18.11.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257844/2f597c1d-1e29-32d7-73df-c9c5e395af70.png)


3.　→「変更」
![スクリーンショット 2020-01-21 18.11.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257844/9c52117f-a23d-901a-bfa7-069702009708.png)

4.公開設定　→「誰でも…」
![スクリーンショット 2020-01-21 18.11.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257844/f95cac17-5933-c830-16a0-12cee949e8c8.png)
GCSのファイルをBigQueryにロードするジョブをPythonで実装したメモ


# サンプルコード

```py

# sevice account の設定しないと認証エラー出ます
# export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credential

from google.cloud import bigquery
client = bigquery.Client('project')

table_ref = client.dataset('dataset').table('table$20200101') # partition指定する
    
job_config = bigquery.LoadJobConfig()
job_config.write_disposition = bigquery.WriteDisposition.WRITE_TRUNCATE # 上書き
job_config.source_format = bigquery.SourceFormat.NEWLINE_DELIMITED_JSON # JSON
# job_config.ignore_unknown_values = True #unknowsな値を許容するならコメント外す
    
uri = 'gs://bucket/path/*.gz' # ディレクトリ以下全て指定
load_job = client.load_table_from_uri(
        uri, table_ref, job_config=job_config
        )     
load_job.result()
print("Job finished.")
```

# 参考
#### [CSV データをテーブルに読み込む](https://cloud.google.com/bigquery/docs/loading-data-cloud-storage-csv?hl=ja#loading_csv_data_into_a_table)
[Java] GlassFish 5トラブルシュート記録

GlassFish 5を動かそうとして、意外にすんなりいかなかったのでトラブルシュートの記録です。

# 環境

OS: Azure上のWindows Server 2008 R2
JDK: Zulu

# トラブルシュート記録

## [解決] `asadmin`コマンドを実行するとNullPointerException

JDK 11 (Zulu 11.31.11)ではだめでした。
JDK 8 (Zulu 8.44.0.9)を使うとOKでした。

## [解決] `asadmin start-domain`するとNoClassDefFoundError例外

`asadmin start-domain`とすると、こんなエラーになりました。

```
Exception in thread "main" MultiException stack 1 of 2
java.lang.NoClassDefFoundError: com/sun/enterprise/admin/launcher/GFLauncherException
        at java.lang.Class.getDeclaredConstructors0(Native Method)
（略）
```

すみません。GlassFish 5.0使ってました。
Eclipseに移管したGlassFish 5.1を使いましょう。

https://projects.eclipse.org/projects/ee4j.glassfish

## [未解決] デプロイするとIllegalStateException

warファイルをデプロイすると、このようなエラーが出ました。

```
remote failure:
 Error occurred during deployment:
 Exception while loading the app :
 java.lang.IllegalStateException:
 ContainerBase.addChild:
 start:
 org.apache.catalina.LifecycleException:
 org.apache.catalina.LifecycleException:
 org.glassfish.jersey.server.model.ModelValidationException:
 Validation of the application resource model has failed during application initialization.
[[FATAL] No injection source found for a parameter of type public java.lang.String service.AddonFacadeREST.create(java.io.File,java.io.File,java.lang.String,javax.ws.rs.core.SecurityContext) at index 0.; source='ResourceMethod{httpMethod=PO
（略）
```

GlassFish 5あきらめました。
4.1.2を使うことにしました。快調です。
【DS】エクセル作成時のヘッダの書き方

【ポイント】
<img width="540" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/8992e4ff-38c7-f719-d1ac-5cab19b933ed.png">

ファイルコンテンツに上記のような書き方をすることでヘッダを追加できる
以降、行を追加するときは「ファイルに追加」をチェックする
【ruby on rails】button_toを使って情報を送り、paramsで受け取る方法。【いいね機能】

#button_toとは
railsでページ遷移する際、ボタン形式のリンクを作成してくれるものです。
似たようなものにlink_toがあります。

##button_toの書き方（一番簡単な例）

```html.erb
<%= button_to "ボタン表示文字",hogehoge_path%>
```
こんな感じで指定したパスに飛べます。

##button_toで情報を送りparamsで受け取る
今回はいいね機能を作成したいときの一例を紹介します

```html.erb
<%= button_to "いいね",favorites_path(@hoge.id),{params: {id:@nantoka.id}}%>
```

```favorites_controller.rb
@favorite = Favorite.new
@favorite.item_id = params[:id]
```
この書き方で、params[:id]を取得できます。
ポイントはbutton_toの第三引数に{params:{}}として、情報を引き渡すことができるということです。
簡単に使えるので、是非活用してみてください！
Macでptyhon3

#Macでptyhon3
備忘録として残しておく
##環境
MacOSのバージョン10.14.6
Pythonのバージョン2.7.10

##3系の導入 
公式pkgをDL
https://www.python.org/ftp/python/3.8.1/python-3.8.1-macosx10.9.pkg
指示通りにインストール

##デフォルトをpython3にする
```
$ echo 'alias python=python3' >> ~/.bash_profile
$ source ~/.bash_profile
```
##2.7.10はpython2として起動できるようにシンボリックリンクを貼っておく
```
$ cd /usr/local/bin
$ sudo ln -s /usr/bin/python2.7 python2
```

##動作確認
```
$ python -V
Python 3.8.1

$ python2 -V
Python 2.7.10
```
ntpq -p(chronyc sources) コマンドの見方

Linux/Unix で時刻同期のために`ntpd`や`chrony`を設定、起動してもすぐには同期されない。
同期進捗や状態を確認するには`ntpq -p`コマンドを実行する。
`chrony`の場合は`chronyc sources`と状態確認コマンドが別にある。

```console
$ ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*ntp-b2.nict.go. .NICT.           1 u    1   64  377   91.074   20.475  82.456
 LOCAL(0)        .LOCL.          10 l   57   64  377    0.000    0.000   0.001
```

指定したNTPサーバ―と同期が開始されれば、**"remote"** 列の指定サーバーに **"*"** がつく。
複数設定している場合には、同期可能なサーバーに **"+"** がつく。

| 項目   | 説明 | 
|----|---|
| refid  | 参照しているサーバーの、更に上位のNTPサーバ。|
| st     | stratum番号、サーバーが第何階層か示す。|    
| when   | 前回サーバーを参照してから経過した秒数。  <br>pollに達すれば再度参照する。|
| poll   | 参照する間隔(秒数)。|
| reach  | 過去8回の参照結果。同期したした場合1、同期しなかった場合0。 <br> 8進数で表示されており、毎回同期されると377（8進数）となる。<br>つまり11111111（2進数）。|
| delay  | ポーリングインターバルの遅延見積もり（単位：ミリ秒）|
| offset | NTPサーバとのずれ(ミリ秒)|
| jitter | NTPサーバがどのくらい正確なのかを示す指標。値が小さいほど正確。|

時刻の同期には時刻のずれを即座に修正する**step方式**と時刻の進み具合をずらしていくことで、少しずつ時刻を合わせていく**Slew方式**があり、`ntpd`や`chrony`はSlew方式になる。
そのために、`ntpq -p`コマンドで同期されるまで見守る必要がある。

もしシステムや運用的に問題がなければ`ntpdate`を実行して即座に修正することも可能。
`ntpdate`を実行するする場合は`ntpd`などは停止する必要がある。

```console
$ sudo service ntpd stop
ntpd を停止中:                                             [  OK  ]
$ ntpdate ntp.nict.jp
30 Apr 04:50:51 ntpdate[27842]: step time server 133.243.238.244 offset -6.239400 sec
$ sudo service ntpd start
ntpd を起動中:                                             [  OK  ]
```
UFTで作成した自動テストをJenkinsから実行する

UFTで作成した自動テストを、Jenkinsから定期的に実行してみます。
UFTは、同社製品の[Quality Center](https://www.microfocus.com/en-us/products/alm-quality-center/overview)と連携するのが、個人的には一番扱いやすいかなと思うのですが、今回はJenkinsで実行してみました。
プラグインをインストールしてジョブ設定して実行するだけですが、手順をまとめておきます。

# 環境
- Windows10Pro 1903 64bit
- Jenkins
- UFT one Ver 15.0

# 手順
1. プラグイン「[Micro Focus Application Automation Tools](https://wiki.jenkins.io/display/JENKINS/Micro+Focus+Application+Automation+Tools)」をインストール
2. 新規ジョブを作成
    * 実行するノードを選択
    * ビルド
        * ｢Execute Micro Focus tests from file system｣を選択
        * Testsは、テストが格納されているフォルダを指定(絶対パス)
        * 例：C:fuga\Unified Functional Testing\hoge(hoge直下にAction1とか入っています)
    * ビルド後の処理
        * ｢Publish Micro Focus tests result｣を選択
        * Report Archive modeは｢Always archive test reports｣を選択
3. Applyして保存する

ジョブの設定は終わったので、実行すれば、ビルドで指定したパスのテストが実行されます。

# ジョブを実行して起きたエラー・・・
少し内容は飛ばしてますが、以下のようなエラーが発生しました。

```
Test result: Error
Build step 'Execute Micro Focus tests from file system' changed build result to FAILURE
Recording test results
Report archiving mode is set to: ALWAYS_ARCHIVE_TEST_REPORT
artifactsDir: archive /var/jenkins_home/jobs/UFT/builds/7/archive
Finished: FAILURE
```

いろいろ原因を探してみたところ、以下と遭遇しました

```
<error message="Unable to change DCOM settings. To change it manually: run dcomcnfg.exe -&gt; My Computer -&gt; DCOM Config -&gt; QuickTest Professional Automation -&gt; Identity -&gt; and select The Interactive User. detailed error is : 許可されていない操作を実行しようとしました。" />
```

・・・、そういえばUFTインストールするときにデフォルト設定でインストールしてたな・・・。
というわけで、インストーラーを起動し、｢オートメーションスクリプトからの～｣にチェックを入れ、追加インストール。
![0.UFTインストール時.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526526/b700da02-62f1-aa84-772f-b7a1a2bd6b70.png)

その後、無事に実行されました。

# メモ
- Jenkinsは公式のdockerイメージを使ってカンタン構築しました。
RubyからQualityForward APIを利用する

[QualityForward](http://bit.ly/36sIniA)はクラウドベースのテストケース管理システムです。

Rubyは日本製、さらにRuby on Railsでの採用例も多いということもあって、多くの開発者に利用されているプログラミング言語です。サーバのみならず、ローカルコンピュータ上でCUIで使っている人も多いでしょう。

そんな中でテスト管理のデータを役立てるべく、QualityForwardのRubyライブラリを開発しはじめました。現在はプロジェクトの取得のみですが、今後バージョンアップを重ねていきます。

## インストール

コードは[goofmint/qualityforward-rb](https://github.com/goofmint/qualityforward-rb)にあります。Rubygemsからインストール可能です。

```ruby
gem 'qualityforward'
```

## 使い方

以下のように使います。まず初期化します。

```ruby
Qualityforward::Client.new 'YOUR_API_KEY'
```

プロジェクトを取得します。

```ruby
p = Qualityforward::Project.get
puts p.id # 999
```

## まとめ

Rubyスクリプトを使ってテスト結果のデータを取得したり、逆にプログラミングした内容でテストケースを自動作成するといった使い方も考えられます。今後のバージョンアップをお待ちください！

[QualityForward](http://bit.ly/36sIniA)
postgres 12 をインストールして使用できる`pg_xxxxx`コマンド

```console:環境
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.2 LTS"

$ psql -V
psql (PostgreSQL) 12.1 (Ubuntu 12.1-1.pgdg18.04+1)
```

```console
$ ls /usr/bin | grep pg_
pg_archivecleanup
pg_basebackup
pg_buildext
pg_config
pg_config.libpq-dev
pg_conftool
pg_createcluster
pg_ctlcluster
pg_dropcluster
pg_dump
pg_dumpall
pg_isready
pg_lsclusters
pg_receivewal
pg_receivexlog
pg_recvlogical
pg_renamecluster
pg_restore
pg_upgradecluster
pg_virtualenv
```
[rails] 投稿一覧にユーザー情報を表示

#始めに
今回、プロゲートと違う方法で投稿一覧でユーザー情報を表示します。

プロゲートでrailsを終えてからよく、ツイッター風アプリを作成すると思います。
そこで、プロゲートのコードをコピペすることは誰でも出来ますが、
重要なのは**理解して自分でコードを書くこと**だと思います。

他のやり方で表示することが出来たので、参考やヒントになれば嬉しいです。

###完成イメージ
<img width="563" alt="スクリーンショット 2020-01-21 17.00.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504349/3cf75a15-1052-c6ad-6df2-07623dcdc076.png">
※注：デザインは今回しません。また、分かりやすく理解してもらうために**ユーザー情報は名前だけ**にします。

#前提
・usersテーブルと投稿用のテーブル（今回はcommentsテーブル）があること。

#MVC(model/controller/view)の設定
###controller設定
```app/controllers/comments_controller.rb
class CommentsController < ApplicationController
    def index
      @comment = Comment.all.order(created_at: :desc)
    end
```
これはプロゲートでもでてきた投稿された順に上から表示しています。
###modelの設定（※ここからプロゲートと違う！）
```app/models/comment.rb
class Comment < ApplicationRecord
    belongs_to :user#追記
end
```
belongs_toとはなんぞや？って思った方いるかも知れません。
簡単に説明すると、userテーブルと投稿用のテーブル（今回はcommentsテーブル）の２つを紐付けてくれる仕組みのものです。
詳細は[こちら](https://pikawaka.com/rails/association#belongs_to%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89)！

###view設定
```app/views/comments/index.html.erb
<% @comment.each do |comment|%>
  <%= comment.user.name%>
  <%= link_to(comment.content,"/comments/#{comment.id}")%>
<% end %>
```
上記のコードの２行目の  <%= comment.user.name%>は
先程belongs_to :userと紐付けているためこのように書くことが出来ます。
もし、紐付けが出来ていなかったらエラーが出ると思います。

#最後に
今回、belongs_to を使ってuserテーブルとcommentテーブルをアソシエーションしました。

もし、何か修正点とかございましたらコメント等
恐縮ですが、宜しくおねがいします
Redmine のmysqlでAccess Deniedにはまった記録（低次元ミスでとても恥ずかしいが人柱で）

ちまたのWin Server 2008サポート切れに伴いWin Server 2016へ最新版Bitnami redmine 4.1をインストールし移行・・のため[ここ](https://qiita.com/8amjp/items/784a664aa3eac05ab03a)を参考にmysqlのテーブル削除をトライするがmysqlのログインで弾かれる。

\>mysql -u root -p
\>Access denied for user 'root'@'localhost' (using password: YES)

ググると同問題遭遇者が累々多数。
ほとんどがrootのパスワード再設定で解決のよう。
でもusing password: YESだからパスワード問題でないのでは？意図的にパスワード外すとusing password: NOって返るし。YESってことはパスワード問題でない？
でもネットにはAccess deniedでパスワード再設定以外は参考例なく1日半、調べてはトライの繰り返しで徒労に過ぎ。

まずは旧環境でダンプ取れるのがユーザがbitnamiなので-u bitnamiでやるが同じ

TCP port番号を明記してやると通るような事例もあり --port 3306明記でやるが同じ

環境変数でINSTALLDIRが必要の事例ありなかったので作成するが同じ

\-D付きでDBをbitnamiと明示してやると・・・でも同じ

ということで結局Bitnami redmineをアンインコ、再インスコして初期パスワードをセットすると問題なくログインできた

結局恥ずかしい理由は・・

初期ユーザ名設定をadminとパスワードセットしRedmineにadminで初回サインイン時にパスワード変更となりその変更したパスワードでmyselへログインしようとした、でrootのパスワード誤りが原因でした

**Redmineインストール時のパスワード必ずメモで残すべし、それがmysqlのパスワードなので・・・**

あー恥ずかしい
Wordpressの翻訳が読み込まれないと思ったときに確認すること

以下を確認して、設定が正しいかをチェックするとよい。
# 1.Plugin情報が書いてあるPHP File

``` plugin.php
<?php
/*
  Plugin Name: HogeHoge
  Description: HogeHoge
  Version: 1
  License: GPL2
  Text Domain: hoge-plugin    ← ここ
  Domain Path: /languages/
*/
?>
```

# 2. ファイルが適切な位置に保存されているか。
ファイルは以下のルールで保存されていることが期待されている。
($PLUGIN_ROOT_DIR はプラグインがインストールされているディレクトリ)

```
$PLUGIN_ROOT_DIR/$DOMAIN_PATH/$TEXT_DOMAIN-ja.mo
```

上記の設定に従うと、moファイルが以下の場所に格納されていると期待されている。

```
$PLUGIN_ROOT_DIR/languages/hoge-plugin-ja.mo
```

# 3. load_text_domain関数に渡されている引数
load_text_domain関数は第1引数が設定ファイルに書かれた Text Domain、 第2引数が false、第3引数が　moファイルが格納されているWP_PLUGIN_DIRの相対パス を入れる必要がある。
Vue.jsについて基礎的なことを少しまとめました

## vue.jsとは
- **データと表示を繋げる仕組み**です。
- MVVM(Model-View-ViewModel)という考え方を元に作られている

### MVVM(Model-View-ViewModel)とは
- Model・・・Vue内に用意したデータ
- View・・・HTMLで表示している要素
- ViewModel・・・それらをどのように繋ぐか

### MVVMの仕組みを考える際
1. データは何か
 - web上で変化する部分は何か。そのために必要なデータを考える。
2. 表示する要素は何か
 - そのデータを、HTMLのどこに、どのように表示するかを考える
3. どのように繋ぐか
 - HTMLのどこを操作された時にデータがどのように変化するかを考える


という流れで考える

**データを作って、表示する要素を用意して、繋ぎ方を決める！**


## Vue.jsの主な機能

|機能  |書式  |
|---|---|
|データをそのまま表示する  |{{データ}}|
|要素の属性をデータで指定する  |v-bind  |
|入力フォームとデータを繋げる  |v-model  |
|イベントと繋ぐ|v-on|
|条件によって表示する|v-if|
|繰り返し表示する|v-for|
|データを使って別の計算をする|computed|
|データの変化を監視する|watch|
|表示/非表示にアニメーションする|transition|
|部品にまとめる|component|

などなど・・・



## 参考図書
[動かして学ぶ！Vue.js開発入門](https://www.amazon.co.jp/%E5%8B%95%E3%81%8B%E3%81%97%E3%81%A6%E5%AD%A6%E3%81%B6%EF%BC%81Vue-js%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-%E6%A3%AE%E5%B7%A7%E5%B0%9A-ebook/dp/B07KPTGZ4C)
マルチコア対応したpigzでファイル圧縮・解凍を高速化させる

リモートにあるマシンとファイルをやり取りする…などで圧縮・解凍する場面が出てきますが、標準の `gzip` や `zip` コマンドではマルチコアに対応していません🤔
他のコアは全く使っていないのに遅い…そこで、マルチコアに対応した `pigz` を用いてファイルの圧縮・解凍を高速化させましょう。

## インストール

`yum`, `apt-get` などのパッケージマネージャーで導入できます。
ソースコードからのインストールが必要な場合は [pigzのホームページ](https://zlib.net/pigz/) から入手できます。

## 圧縮

### 1つのファイルを圧縮する

`pigz` にはファイル名を指定するオプションが無いため、 `-c` オプションで圧縮結果を標準出力に出してからリダイレクトで指定したファイルに入れます。

```bash
$ pigz --best -c db_dump.txt > single_file.gz
```

実用的な最高圧縮率で圧縮したいため `--best` のオプションを付けています。 `--best` は `-9` と同じですが、時間を犠牲にしてでも最高の圧縮を求めたい場合は `-11` まで圧縮率を指定できます。

```bash
$ man pigz
...
       -# --fast --best
              Regulate  the speed of compression using the specified digit #, where -1 or --fast indicates the fastest compression method (less compres‐
              sion) and -9 or --best indicates the slowest compression method (best compression).  -0 is no compression.  -11 gives a few percent better
              compression at a severe cost in execution time, using the zopfli algorithm by Jyrki Alakuijala.  The default is -6.
```

### ディレクトリなど複数ファイルの圧縮は `tar` でまとめてから圧縮する

`pigz` で圧縮する際にディレクトリを指定して `-r` で再帰的に圧縮しようとすると、 **指定されたファイル一つずつつに対して圧縮ファイルを作成します。** 
**`zip` コマンドの感覚でやってしまうとディレクトリ内にある元のファイルが一つずつzip置き換えられます😱**

そこで、一度 `tar` で1ファイルにまとめてからそのファイルを `pigz` で圧縮します。

```bash
$ tar c Directory | pigz --best > multiple_files.tar.gz
```


## 解凍

### `pigz` を用いた解凍について

**`pigz` ではマルチコアで解凍ができません。** …がファイルの読み書きなどは並列化されるため、結果として高速になる場合があります。

```
$ man pigz
...

       Decompression  can't  be parallelized, at least not without specially prepared deflate streams for that purpose.  As a result, pigz uses a single
       thread (the main thread) for decompression, but will create three other threads for reading, writing, and check calculation, which can  speed  up
       decompression under some circumstances.  Parallel decompression can be turned off by specifying one process ( -dp 1 or -tp 1 ).
```

1つのファイルを圧縮した場合は `-d` オプションで解凍できます。

```bash
$ pigz -d single_file.gz
```

ディレクトリなどを圧縮する前に `tar` にまとめてしまった場合は `tar` コマンドの `--use-compress-prog` オプションを使って解凍すると良いでしょう。
解凍に `pigz` を使いながらtarの展開まで自動で実行されます👍

```bash
$ tar -xvf multiple_files.tar.gz --use-compress-prog=pigz
```


### マルチコアで解凍できないというけど…🤔

ざっと解凍してみると、 `pigz` ではすべて解凍し終わるまでの時間が短くなっていることがわかります(4-coreのCPU, テキストファイル534個を圧縮した434MBのtar.gzにて)

```bash
$ time tar -xvf multiple_files.tar.gz
...
real    0m18.233s
user    0m16.780s
sys     0m4.346s

$ time tar -xvf multiple_files.tar.gz --use-compress-prog=pigz
...
real    0m9.317s
user    0m10.973s
sys     0m4.556s
```

## 参考

マルチコアでgzファイルの圧縮解凍ができるpigzの使い方 - Qiita
https://qiita.com/itukizora/items/10a9e7fffff857de374b

pigzを使ったgzip並列圧縮 - Wolfeyes Bioinformatics beta
http://yagays.github.io/blog/2012/06/15/pigz/

bzip2とgzipのParallel版、pbzip2とpigz - done is better than perfect
https://dibtp.hateblo.jp/entry/2014/07/06/004300
Laravel データベースの論理削除

## はじめに
- Laravel で データベースの論理削除を行いたい時は、ソフトデリート の機能が使用できる。
- 論理削除とは、本当にデータベースから削除するのではなく、フラグなどを立ててシステム上から見えなくすること
- Laravelでは Eloquent の機能でソフトデリートが使用できる。

## 前提
### Laravel のバージョン
```
$ php artisan -V
> Laravel Framework 5.8.16
```
### Mysql のバージョン
- mysql を使用する

```sql 
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.28    |
+-----------+
```

## 使いかた
### ①テーブルに『deleted_at』カラムを追加する

- ここでは users テーブルにソフトデリートを実装する

```sql
mysql> describe users;
+-------------------+---------------------+------+-----+---------+----------------+
| Field             | Type                | Null | Key | Default | Extra          |
+-------------------+---------------------+------+-----+---------+----------------+
| id                | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| username          | varchar(20)         | NO   | UNI | NULL    |                |
| password          | varchar(128)        | NO   |     | NULL    |                |
| created_at        | timestamp           | YES  |     | NULL    |                |
| updated_at        | timestamp           | YES  |     | NULL    |                |
| deleted_at        | timestamp           | YES  |     | NULL    |                |
+-------------------+---------------------+------+-----+---------+----------------+

```
### ②ソフトデリートを使用できるようにモデルで宣言

- モデルで宣言するだけで、`delete()`処理を実行すると`deleted_at`カラムに現在の時刻がセットされる。
- `deleted_at`カラムに現在の時刻がセットされていると、削除済み隣、クエリ結果に含まれない。

```app/Model/User.php
<?php

namespace App\Models;
use Illuminate\Database\Eloquent\SoftDeletes;

class User extends Model
{
    use SoftDeletes;
〜省略
```

### まとめ
- とても簡単にソフトデリートを有効にできた。
- ソフトデリート済みのデータのみ取得や、物理削除の方法もあるがあとで、別途調べるよお。
MeCabのコスト計算について

#はじめに
MeCabのコスト計算について勉強したのでまとめてみました。
どこか間違っていたらご指摘ください。

#MeCabの形態素解析の概要
MeCabは登録された辞書を使って形態素解析を行います。もし辞書に登録されていない単語（未知語）が出た場合、各単語のコストに基づいて分割します。そのなかで**総コストが最小のもの**を結果として出力します。

#実際にやってみる
今回はipadic-neologd辞書を用いて、架空の単語「アメリカドイツ村」がどのように形態素解析されるか確認します。

```shell

echo アメリカドイツ村|mecab -d C:\neologd -N2

アメリカ        名詞,固有名詞,地域,国,*,*,アメリカ,アメリカ,アメリカ
ドイツ  名詞,固有名詞,地域,国,*,*,ドイツ,ドイツ,ドイツ
村      名詞,接尾,地域,*,*,*,村,ムラ,ムラ
EOS

アメリカ        名詞,固有名詞,地域,国,*,*,アメリカ,アメリカ,アメリカ
ドイツ村        名詞,固有名詞,一般,*,*,*,ドイツ村,ドイツムラ,ドイツムラ
EOS
```
-dで辞書を指定し、NUMオプションで指定した数だけ候補を挙げます。
このように未知語に対して2種類の分け方が候補に挙がりました。この分け方は私たちにとっても、かなり納得のいくものではないでしょうか。

#MeCabの辞書
コストの計算に入る前に、MeCab辞書の登録方法について説明します。
辞書は、

```python
表層形,左文脈ID,右文脈ID,コスト,品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用形,活用型,原形,読み,発音
```

という形でcsvファイルとして保存してから辞書をビルドします。これをみると、
・ **左文脈ID**
・ **右文脈ID**
・ **コスト**
という見慣れない言葉が含まれています。これらがMeCabの形態素解析に用いられる情報になります。
# 生起コスト
**生起コスト**とは、ある単語自体の**現れにくさ**です。値が高いほどその単語は現れにくくなります。生起コストは先ほど登録した辞書の**コスト**の値です。それでは「アメリカドイツ村」はどのような生起コストになったのでしょうか？

```shell

echo アメリカドイツ村|mecab -F "%m,%c,\n" -d C:\neologd -N2

アメリカ, 4698,
ドイツ, 2543,
村, 8707,
EOS

アメリカ, 4698,
ドイツ村, 611,
EOS
```
%mで表層形、%cで生起コストを表示させます。
ここで一つの疑問が生まれます。総コストは明らかに2つ目の方が小さいはずなのに、出力第一候補は1つ目の結果になっています。その理由は新たなコスト、**連接コスト**の存在にあります。

#連接コスト
**連接コスト**とは、2つの単語の文脈IDの連続しにくさです。値が小さいほど連続する可能性が高くなります。文脈IDは辞書の**左文脈IDと右文脈ID**に当たります。基本的にこのIDは登録時には同じ値になっていると思われます。例えば「前後」という単語を考えます。
「前」の文脈IDは1314,「後」の文脈IDは1313です。連接コストは左文脈IDと右文脈IDの組み合わせで決められます。
組み合わせの一覧はMeCab\dic\ipadicにあるmatrix.def(またはmatrix.bin)にあります。これを見ると、

```
1314 1313 -316
1313 1314 716
```
前→後は連接コストが低い(-316)ため連続しやすく、後→前だと連接コストが高く(716)連続しにくいという結果が得られました。これも割と納得できるかと思います。
それでは「アメリカドイツ村」についても見てみましょう.

```shell

echo アメリカドイツ村|mecab  -F"%m,%phl,%phr,%c,%pc,%pn\n" -d C:\neologd -N2

アメリカ,1294,1294,4698,3746,3746
ドイツ,1294,1294,2543,-141,-3887
村,1303,1303,8707,881,1022
EOS

アメリカ,1294,1294,4698,3746,3746
ドイツ村,1288,1288,611,2614,-1132
EOS
```
MeCabコマンドをまとめると以下のようになります。

|コマンド |説明  |
|---|---|
|%m|表層形|
|%phl|左文脈ID | 
|%phr|右文脈ID|
|%c(または%pw)|生起コスト|
|%pc|連接コスト+単語生起コスト(文頭から累積)|
|%pn|連接コスト+単語生起コスト(その形態素単独, %pw+%pC)|
全てのコマンドは[こちら](https://taku910.github.io/mecab/format.html)に記載されています。
出力がわかりにくいのでこれも表にしてみます。

|表層形|左文脈ID|右文脈ID|生起コスト|連接＋生起(累積)|連接+生起(単独)|
|---|---|---|---|---|---|
|アメリカ|1294|1294|4698|3746|3746|
|ドイツ|1294|1294|2543|-141|-3887|
|村|1303|1303|8707|881|1022|
|||||||
|アメリカ|1294|1294|4698|3746|3746|
|ドイツ村|1288|1288|611|2614|-1132|
ここで注意していただきたいのは、**BOSとEOSにも文脈IDが付与されている**ということです。なので、1つ目の「アメリカ」の連接コストはmatrix.defより

```
0 1294 -952
```
となります。そのため、累積コストは4698-952=3746となります。
次に「ドイツ」を見てみましょう。左右の文脈IDが1294で連接コストは-6430とかなり小さくなります。(確かに国名が連続して続くのは珍しい...)
累積コストは(3746+2543)-6430=-141で、単独の場合は2543-6430=-3887で、計算と一致しました。
また、出力はされていませんが、EOSにも文脈IDがあるため最終チェックを行います。
文脈ID1303→0の連接コストは5、文脈ID1288→0は-919で累積コストを比べると、886と1695で1つ目の方が最小コストなので、先ほどの謎が解明できました。

#参考
[MeCabのコスト計算を理解する。](http://kento1109.hatenablog.com/entry/2018/01/24/102322)
[日本テレビ東京で学ぶMeCabのコスト計算](http://www.mwsoft.jp/programming/munou/mecab_nitteretou.html)
[日本語形態素解析の裏側を覗く！MeCab はどのように形態素解析しているか](https://techlife.cookpad.com/entry/2016/05/11/170000)
[Android] ProgressBarの使い方

##使い方
Widget.ProgressBarを追加して、表示非表示を変えるだけで良い。

・Widget.ProgressBarを追加
![スクリーンショット (12).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506451/7fb4788d-f143-2f45-99e9-e0d204c25808.png)

表示非表示の切替え

~~~java
private ProgressBar progressBar;
 // 表示
progressBar.setVisibility(android.widget.ProgressBar.VISIBLE);
// 非表示
progressBar.setVisibility(android.widget.ProgressBar.INVISIBLE);
~~~

##結果
こういうのが表示されれば成功。
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506451/513cecfb-f123-cbcb-1694-69cf492d814c.png)

##困ったところ
前回ProgressDialogを扱ったが、https://qiita.com/QiitaD/items/dc6f823e722f5556030f
API非推奨になっていた。現在はProgressBarを使うらしい。見落とさないよう気を付けて頂きたい。

##感想
ProgressDialogよりも簡単に使えた。


##参考URL
https://akira-watson.com/android/progressbar.html
【Rails】enumを使用したセレクトボックスの実装とDBへの保存

# はじめに
都道府県などのプルダウンメニューを作成する際、enumを使いました
これを使うことで都道府県などのデータをわざわざテーブルとして用意する必要がなくなります
便利だったのですが、DBへの保存の際に型が合わないなどの問題も発生したのでまとめておきます

# 環境
Ruby: 2.5.1
Rails: 5.2.4

# 実際の操作
実際の操作は以下のようになります

1. 該当カラムをinteger型で作成
2. モデルにプルダウンメニューで表示させるもの一覧を記載
3. ビューで表示させるプルダウンの記述
4. 入力したフォームの受け取り型を編集



#### 1. 該当カラムをinteger型で作成
下記の場合は都道府県です

```ruby:schema.rb
t.integer :prefecture, null: false
```
<br>
#### 2. モデルにプルダウンメニューで表示させるもの一覧を記載

```ruby:models/address.rb
enum prefecture: {
    北海道:1,青森県:2,岩手県:3,宮城県:4,秋田県:5,山形県:6,福島県:7,
    茨城県:8,栃木県:9,群馬県:10,埼玉県:11,千葉県:12,東京都:13,神奈川県:14,
    新潟県:15,富山県:16,石川県:17,福井県:18,山梨県:19,長野県:20,
    岐阜県:21,静岡県:22,愛知県:23,三重県:24,
    滋賀県:25,京都府:26,大阪府:27,兵庫県:28,奈良県:29,和歌山県:30,
    鳥取県:31,島根県:32,岡山県:33,広島県:34,山口県:35,
    徳島県:36,香川県:37,愛媛県:38,高知県:39,
    福岡県:40,佐賀県:41,長崎県:42,熊本県:43,大分県:44,宮崎県:45,鹿児島県:46,沖縄県:47
  }
```
<br>
これで表示させる準備完了
#### 3. ビューで表示させるプルダウンの記述

```ruby:address.html.haml
= form.select :prefecture, Address.prefectures.keys, {prompt: "選択してください"}, class: "prefecture-select"
```
<br>
これでプルダウンメニューとして表示することはできるようになったんですが、binding.pryでparamsの中を見てみると"北海道"として値を取得してきてしまいました。
<img width="459" alt="スクリーンショット 2020-01-20 21.34.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543133/c5654406-135e-d768-2e78-135ff2e7e036.png">

prefectureカラムはinteger型なのでこのままだとDBに登録できなくて困ります。

#### 4. 入力したフォームの受け取り型を編集
色々調べた結果、以下のようにすると対応するvalueの値を取得できることがわかりました。

```ruby:address.html.haml
= form.select :prefecture, options_for_select(Address.prefectures), {prompt: "選択してください"}, class: "prefecture-select"
```
<img width="461" alt="スクリーンショット 2020-01-20 21.32.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543133/6984e65e-9200-58fc-0abb-ba2346b23f92.png">


しかし、これだと"1"という文字列なのでまだカラムに登録できません。

form.selectにおける入力値を数値として送れないかと思いましたが、やり方がわからなかったので、受け取る側で無理矢理数値型に変換することにしました。少々かっこ悪いですが、ストロングパラメータで数値型にした後にmergeしてます。

```ruby:registrations_controller.rb
def address_params
  params.required(:address).permit(:postal_code, :city, :street, :building).merge(prefecture: params[:address][:prefecture].to_i)
end
```
<br>
これで晴れてDBへ保存できるようになりました

ただもっとスマートな方法がありそうな気がしてます

何か知ってる方いらっしゃいましたら教えていただけると嬉しいです

似たようなものにactive_hashというものがあります
gemをインストールする必要がありますが、こちらは数値型としてデータを取得できますし、ActiveRecordのメソッドも使えるみたいなので便利そうです

# 参考記事
- enumの使用
https://qiita.com/dawn_628/items/8c4293831bcccf332b9a

- active_hash
https://qiita.com/Toman1223/items/8633142312bfa886d50b
Nokogiriでタグの切り出しがうまくいかないとき名前空間の存在を忘れていませんか？

HTMLやXMLのタグをスクレイビングするときに重宝するNokogiriライブラリは、かなり機能が充実していますが、精通するまで使用するのは難しいです。

ここでは、ライブラリ使用時にハマってしまったことを備忘録としてまとめました。
簡単な使い方が載っているサイトはすぐにたくさん見つかりましたが、後述するハマりポイントが記載されているサイトはなかなか見つかりませんでした。

Nokogiriの詳しい使い方は既に多くの人が分かりやすく説明してくれていますので、そちらを参照ください。



# 一応簡単におさらい

```sample.rb
require 'nokogiri'

#①XMLファイルを読み込む
  file = Nokogiri::XML(File.read('sample.xml'))

#②XMLクラスを作成して、変数に格納する
  a = Nokogiri::XML::Builder.new(encoding: 'utf-8') do |xml|
    #要素の作成
  end

```
②の「要素の作成」については、以下のリンク先を参照すれば詳しく載っています。
https://www.rubydoc.info/gems/nokogiri/Nokogiri/XML/Builder


# はまりポイント

以下のXMLをサンプルに説明します。

```morning.xml
<head>
  <title>モーニング娘。</title>
  <team id='4期'>
     <status>石川</status>
     <status>吉澤</status>
     <status>加護</status>    
     <status>辻</status>
  </team>
</head>
```
```morning.rb
file = Nokogiri.XML(File.read(morning.xml))
```


### タグの中身だけが欲しいんだ

```morning.rb
file = Nokogiri.XML(File.read(morning.xml))
title = file.xpath('/head/title')
puts title
# > <title>モーニング娘。</title>
```

とすれば、titleタグが取得できますが、このままでは「"＜title＞モーニング娘。＜/title＞"」と出力されてしまいます。中身の「モーニング娘。」だけが欲しい時は「.text.strip」を追加してあげましょう。


```morning.rb
file = Nokogiri.XML(File.read('morning.xml'))
title = file.xpath('/head/title').text.strip
puts title
# > モーニング娘。
```



### 名前空間の存在を忘れていたら要素を取り出せない

Nokogiriで要素を切り出すためにxpathを使えばいいのですが、ここで

```ruby
a = file.xpath('/head/title')
```

とすれば、titleタグを切り出せますが、

```ruby
a = file.xpath('/head/team')
```

とすると、うまくいきません。

もし名前空間を無視して使用したい場合は

```ruby
file = Nokogiri::XML(File.read('morning.xml'))
file.remove_namespaces!
```
と、名前空間を削除しましょう。すると、

```ruby
a = file.xpath('/head/team')
```
が動いて、teamタグが取得できます。
「このサイトは安全ではありません」が沢山現れた！！

#はじめに
Windows7のサポート終了に伴い、
パソコンをWindows10に入れ替えるお客様が多く、
開発しないでパソコンのセットアップばかり最近やってます。
先日お客様に納品したパソコンで[郵便番号検索](https://www.post.japanpost.jp/zipcode/index.html)を開こうとしたら、
「このサイトは安全ではありません」
と表示されるとクレームを頂きました。

<b>＊ネットワーク関連は全くのド素人です…</b>

#現象確認
問題が発生しているPCを確認した所、
「このサイトは安全ではありません」
が表示されてました。
詳細情報を見てみると。
「DLG_FLAGS_INVALID_CA」
と表示されていました。

同じ様にGoogleなどみ表示されない。

そして現象が発生しているのは１台かと思ったら、
納品した約半数のパソコンで現象が発生…

#発生環境
OS:Windows10 Pro
ブラウザ:IE11
その他：ESET Endpoint Antivirus

#調査１日目
以下の項目について現象が発生していないPCと比べたりしました。
・インターネットセキュリティー設定
・SSL状態のクリア
・IEの設定リセット
・Edge、chromeでの動作確認
・ESET停止、アンインストール
・スマフォのテザリング接続

#調査１日目結果
上記調査を行いましたがどれも不発…
接続環境は関係なくパソコン側の問題って事だけはわかった。
あとパソコンによってはホームページ以外のhttpsのページがほぼ全滅…

#調査２日目
社内に戻り納品待ちのPCで同じ現象になってるPCを発見したので、
社内で快適に調査開始。

非推奨で表示を許可した状態で、
ふと郵便番号検索サイトの証明書を表示し、
現象が発生しない状態の証明書と比較してみると、
証明書の発行者が違う！！

発生しない方の発行者でググると、
[ルート証明書の確認](https://www.cybertrust.ne.jp/sureserver/support/faq/tech_faq09.html)
のHPにたどり着いた。

信頼されたルート証明機関を確認すると、
現象が発生してるパソコンには、
Google Trust ServicsのGlobalSignしかなく、
発生していないパソコンには、
＋してGlobalSign Root CAのGlobalSignが入っていたので、
こいつを信頼されたルート証明機関にインポートしたら現象が直った！！

#結果
何故かルート証明書が足りない？状態だったので、
GlobalSign Root CAのGlobalSignをインポートする事によって解決

#最後に
こんな現象になったのは初めてだし、
何故多発しているのかが不明なのが嫌な感じだけど、
取り合えず解決策が見つかって良かった。
【Nuxt.js】フォームを送信したらstatus code405が返ってきた

フォームを送信したらstatus code405が返ってきた時の対処メモ

### エラー文

```console
xhr.js?b50d:172 OPTIONS http://localhost:1323/v1/forms 405 (Method Not Allowed)
```
→ 意味：405 サーバーがリクエストメソッドを理解しているものの、無効にされており使用することができない

```console
input:1 Access to XMLHttpRequest at 'http://localhost:1323/v1/forms' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
```
→ 翻訳：
オリジン 'http：// localhost：3000'から 'http：// localhost：1323 / v1 / forms'にあるXMLHttpRequestへのアクセスはCORSポリシーによってブロックされています：プリフライトリクエストへの応答はアクセスコントロールチェックに合格しません：いいえ 'アクセス-Control-Allow-Origin 'ヘッダーが要求されたリソースに存在します。


### apiとnuxt-appのつなぎ込みを忘れてたので修正
- docker-compose.yamlにnetworksの設定を追加

```yaml:api/docker-compose.yaml
services: 
    // 省略

    networks: 
      - internal 
      - external 

  db: 
    // 省略

    networks: 
      - internal 

networks:
  internal:
    internal: true
  external:
    name: api_network
```
→ それでもエラーは治らない

## env.development.jsのurlの記載を修正

```javascript:env.development.js
module.exports = {
  apiBaseUrl: "http://app:1323/"    // もともと"http://localhost:1323/"としていた
}
}
```

→ エラー解消
vue.jsのインスタンスを理解したいと思ったので

vue.jsをふわっと触って動くものを作るなど学習していますが、vue.jsのインスタンスという概念についてあまり理解出来ていないようだったので調べてみました。


## まず
- vue.jsでSPAを作るには、まず、Vueインスタンスを作るところから始める
- SPAを裏で動かしている実態

```vue.js
new Vue ({インスタンスの中身})
```
または

```vue.js
var 変数名　= new Vue({ Vue インスタンスの中身})
```

という構文で書きます。


インスタンスのなかで、下記のようにずらずらっと**オプション**というものがあります

(公式の目次のスクショです。)
<img width="196" alt="スクリーンショット 2020-01-21 16.40.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486722/11a19523-e8df-61ac-bde1-18b7f3bf45b4.png">


この中で、一番上にある「data」というオプションは、「どんなデータがあるか」を指しています。

書き方は、

```vue.js
new Vue ({
  el:"#ID名",
  data:{
     プロパティ:値　　// ←データ部分
　　　プロパティ:値   // ←データ部分
    }
  })
```


という感じで書きます。

dataの「どんなデータがあるか」 の他に、

- どのHTML要素と繋がるか (el)
- どんな処理を行うのか (methods)
- どのデータを使って別の計算をするのか (computed)
- どのデータを監視するのか (watch)

などの情報を、Vueインスタンス内に書いていきます。


### 参考図書
[動かして学ぶ！Vue.js開発入門](https://www.amazon.co.jp/%E5%8B%95%E3%81%8B%E3%81%97%E3%81%A6%E5%AD%A6%E3%81%B6%EF%BC%81Vue-js%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-NEXT-ONE-%E6%A3%AE-%E5%B7%A7%E5%B0%9A/dp/4798158925)
DynamoDBで一部の属性のみを取得する（プロジェクション式）--projection-expression

テーブルからデータを読み取るには、GetItem、Query や Scan などのオペレーションを使用します。Amazon DynamoDB は、デフォルトですべての項目属性を返します。すべての属性ではなく、一部の属性のみを取得するには、プロジェクション式を使用します。



```json:key.json
{
    "Id": { "N": "123" }
}
```



まずは、`--projection-expression`　なしですべての項目を呼び出してみる。

```
$ aws dynamodb get-item \
--table-name testprojectionexpression \
--key file://key.json
 
{
    "Item": {
        "Description": {
            "S": "test"
        },
        "name": {
            "S": "sato"
        },
        "Id": {
            "N": "123"
        }
    }
}
```



`--projection-expression` で Description のみを呼び出してみる。


```
$ aws dynamodb get-item --table-name ProductCatalog \
--key file://key.json \
--projection-expression "Description"

{
    "Item": {
        "Description": {
            "S": "test"
        }
    }
}
```
docker(108)今日のdocker error: ERRO[11840] error waiting for container: EOF 

docker  動かしたまま、メモリの割り当てを変更した。

Docker for Macが路頭に迷わないようにたくさんメモリを食べられるようにする
https://blog.pinkumohikan.com/entry/increase-memory-limit-of-docker-for-mac

dockerメニューでpreferenceを選択

![docker-preference.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/126196d3-b8d6-5db1-c895-a46f830a4365.png)
]

12GBにした。

各 docker起動している窓で、

```shell-session:docker/ubuntu/bash
ERRO[11840] error waiting for container: EOF 
```
### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
[自分メモ] Macアプリのバイナリに署名するコマンド

まずアプリケーションに署名がついているかどうかを確認する。

```
codesign -dvvvv /path/to/application
```

署名するときはこう

```
codesign --deep -f -s 'Developer ID Application: シグネチャ' "/path/to/hoge.app"
```

インストーラ付きはこんな感じ

```
productbuild --component hoge.app /Applications --sign "Developer ID Installer: シグネチャ" hoge.pkg
```

一気にシェルでやってしまう
（以下メモ書きに残っているコピペでUnityでビルドしたもの相当。正直殆ど使ってないけど一応残す）

```
#!/bin/sh

codesign --deep -f -s '3rd Party Mac Developer Application: シグネチャ' --entitlements "hoge.entitlements" "/path/to/hoge.app/Contents/Frameworks/MonoEmbedRuntime/osx/libMonoPosixHelper.dylib"
codesign --deep -f -s '3rd Party Mac Developer Application: シグネチャ' --entitlements "hoge.entitlements" "/path/to/hoge.app/Contents/Frameworks/MonoEmbedRuntime/osx/libmono.0.dylib"
codesign --deep -f -s '3rd Party Mac Developer Application: シグネチャ' --entitlements "hoge.entitlements" "/path/to/hoge.app"
```
juliaと遺伝的アルゴリズムでonemax問題

最近juliaなるプログラミング言語を見つけ、面白そうだったので勉強を始めました。
今回はその一つとして遺伝的アルゴリズムでOneMax問題を最適していきます
Juliaのwiki
https://ja.wikipedia.org/wiki/Julia_(プログラミング言語)
###初期世代生成

```Julia
leng = 100
population = 100
mutationRate = 0.1
genelation = 10

function init()
    genom::Array{Int8, 2} = rand(0:1, leng, population)
    return genom
end
```
最初の世代は0と1の完全にランダムな配列で生成します。
配列の要素は0か1しか使わないので、Int8でデータ量を節約してます。
###個体の選択
```Julia
function choice(genom::Array{Int8, 2})
    X::Int64 = argmax(sum(genom, dims=2))[1]
    Y::Int64 = 0
    while true
        Y = rand(1:population)
        if Y != X
            break
        end
    end
    return genom[X, :], genom[Y, :]
end
```
この関数では、最も優秀な遺伝子Xとランダムに選択された遺伝子Yの
配列を返り値としています。Yのランダム選択部分は1:populationの配列かX番目の値を削除して、その中からランダムに選択する方法もありましたが、pop!の使い方がよく分からなかったのでこうなりました。
###交差
```Julia
function crossover(X::Array{Int8, 1}, Y::Array{Int8, 1})
    genom::Array{Int8, 1} = []
    append!(genom, X)
    append!(genom, Y)
    for i in 1:population-2
        cut = rand(2: leng-1)
        append!(genom, X[1: cut])
        append!(genom, Y[cut+1: leng])
    end
    return reshape(genom, leng * population)
end
```
交差は一点交差を使い、返り値はこの後の突然変異のためにleng * populationのサイズの一次元配列にreshapeして返します
###突然変異
```Julia
function mutation(genom::Array{Int8, 1})
    for i in 1: leng * population
        if rand() < mutationRate
            genom[i] = 1 - genom[i]
        end
    end
    return reshape(genom, leng, population)
end
```
先ほど一次配列にしたものを受け取ってfor文で全ての要素を参照していきmutationRateの確率で
1と0を反転させてます。
ここだけではないですが、もっとスマートな書き方にできそな所が多々ありますね…
もし修正やアドバイス等ありましたらコメントの程お願いします。

###main関数
```Julia
function main()
    local genom = init()
    for i in 1: genelation
        X, Y = choice(genom)
        genom = crossover(X, Y)
        genom = mutation(genom)
        println("gen: ", i)
        print("avg: ")
        println(sum(genom) / (leng * population))
        print("max: ")
        println(sum(X) / leng)
        println("")
    end
end
```
あとは作った関数を組み立てて完成です。
できあがたコードはgithubのリンクを貼っておきます↓
https://github.com/AokiMasataka/One-max/blob/master/OneMax.jl
Pytorchでモデル構築するとき、torchsummaryがマジ使える件について



#はじめに

自分でモデルを構築していて、いつも全結合層につなぐ前に「あれ、インプットの特徴量っていくつだ?」ってなります。よく`print(model)`と打つとモデルの構造は理解できるが、FeatureMapのサイズまでは確認出来ません。そこで便利なのが`torchsummary`というものです。


#torchsummaryは何者か?

簡単に言うと、`特徴マップのサイズを確認できる`ものです。

#どのようにtorchsummaryを使うか

###まずはモデルを作ります

今回は以下の簡単なモデルを作りました。
クラス分類するまでは書いていません。

畳み込み➡︎BN➡︎ReLU➡︎pooling➡︎
畳み込み➡︎BN➡︎ReLU➡︎pooling➡︎
畳み込み➡︎GlobalAveragePooling

```.py
                                                                                                                                     
import torch
import torch.nn as nn
   
class SimpleCNN(nn.Module):     
    def __init__(self):
        super(SimpleCNN,self).__init__()
 
        self.conv1 = nn.Conv2d(3,16,kernel_size=3,stride=1)
        self.bn1 = nn.BatchNorm2d(16)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d((2,2))
        self.conv2 = nn.Conv2d(16,32,kernel_size=3,stride=1)
        self.bn2 = nn.BatchNorm2d(32)
        self.conv3 = nn.Conv2d(32,64,kernel_size=3,stride=1)
        self.gap = nn.AdaptiveMaxPool2d(1)
  
    def forward(self,x):  
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x) 
        x = self.maxpool(x)
        x = self.conv2(x)
        x = self.bn2(x)
        x = self.relu(x)
        x = self.maxpool(x)
        x = self.conv3(x)
        x = self.gap(x)
   
        return x
```

###torchsummaryのインストール

```.py
pip install torchsummary
```

###torchsummary使い方

```.py
from torchsummary import summary
model = SimpleCNN()  
summary(model,(3,224,224)) # summary(model,(channels,H,W))
```
今回は、画像の入力サイズを224x224を想定して試しています。
他の解像度で試したいときは、`H`と`W`の値を変更してください。

###summaryの出力

```.py

----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Conv2d-1         [-1, 16, 222, 222]             448
       BatchNorm2d-2         [-1, 16, 222, 222]              32
              ReLU-3         [-1, 16, 222, 222]               0
         MaxPool2d-4         [-1, 16, 111, 111]               0
            Conv2d-5         [-1, 32, 109, 109]           4,640
       BatchNorm2d-6         [-1, 32, 109, 109]              64
              ReLU-7         [-1, 32, 109, 109]               0
         MaxPool2d-8           [-1, 32, 54, 54]               0
            Conv2d-9           [-1, 64, 52, 52]          18,496
AdaptiveMaxPool2d-10             [-1, 64, 1, 1]               0
================================================================
Total params: 23,680
Trainable params: 23,680
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.57
Forward/backward pass size (MB): 30.29
Params size (MB): 0.09
Estimated Total Size (MB): 30.95
----------------------------------------------------------------
```

OutputのShapeが確認で出来るのはかなり便利です。
パラメータの数もカウントしてくれるのもありがたいです。


#終わりに

torchsummary便利なので、ぜひ使って見てください。
PowershellからPythonの関数を実行（引数の渡し方）

###やりたいこと
PowershellからPythonの関数を実行したい

###ポイント
- 引数はコマンドライン引数を使用すること
- sys.argvは文字列なので数値を渡したい時はcastが必要


```python
import sys
#引数をsys.argv[n]を使用して定義する
a = sys.argv[1]
```

###サンプルコード

```Python:calc.py
def add(a, b):                   
    return a + b
```

```python:main.py
from calc import add
import sys

a = int(sys.argv[1])
b = int(sys.argv[2])

ret = add(a, b)
print(ret)
```

```powershell:test.ps
$a = 5
$b = 10
python.exe main.py $a $b
```

```powershell:結果
6
```


###つまづいたところ
・引数を渡す時にPowershellの関数に渡すようなやり方をしたため
　引数の定義エラーになった

```Python:calc.py
def add(a, b):                   
    return a + b
```

```python:main.py
from calc import add
ret = add(a, b)
print(ret)
```

```powershell:test.ps
$a = 5
$b = 10
python.exe main.py $a $b
```

```powershell:結果
NameError: name 'a' is not defined
```
[Swift,Objective-C] キーボード入力時にデフォルトで大文字になるのを解消する

## メールアドレス入力で大文字になってしまう
開発したアプリのキーボード入力しようとすると、大文字入力で始まってしまうことがよくあります。
名前（ローマ字）などでは助かる機能なのですが、メールアドレスだと見た目が気持ち悪く、開発初期段階ではログインAPIのサーバー側が綺麗に作られていないことで、大文字だとログインが通らないこともあります。
![IMG_0307.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4537/39186a77-4fa2-4f78-968a-df311b3f2986.jpeg)

### 解決方法
`autocapitalizationType` を `none` することで解決できます。
####Swift
``` loginView.swift
let mailTextField = UITextField()
mailTextField.autocapitalizationType = .none
```

#### Objective-C
``` loginView.m
UITextField *searchField = [UITextField new];
searchField.autocapitalizationType = UITextAutocapitalizationTypeNone;
```
Docker上のFlask + Nginxでコンソールにログを出力する

# 前提
本来であればflask、nginxに加えuwsgiサーバを立てるのが良いのは認識しているが、現状の構成からできることを行なった結果である。

# 背景
Docker上のFlask + Nginxのサーバを立てたのだが、Flaskのログがファイル出力のみされており、docker runを行なったプロンプトやdocker logsで確認ができない。どうにかしてできるようにしたい。

# 現状の構成
かなり省略するが、次の通り。

```dockerfile:Dockerfile
FROM centos:centos7

CMD ["/bin/bash", "./start.sh"]
```

```bash:start.sh
# !/bin/bash

uwsgi --ini=uwsgi.ini
nginx -g "daemon off;"
```

```ini:uwsgi.ini
daemonize = /var/log/uwsgi/uwsgi.log
```

上記の状態だとuwsgiプロセスがデーモン化して動作し、フォアグラウンドジョブとしてNginxが動作する。
そして、ログはdaemonizeで指定した/var/log/uwsgi/uwsgi.logに全て出力されてしまう。

# 対応
いくつか対応を試みたがうまくいかず、結果的に3番目の対応方法でうまくいった。

## flask上でコンソール出力を明示的に追加
すでにコンソール出力はされているとは思いながら、追加でコンソール出力のストリームを追加することでできないか確認。

```python
logger.addHandler(logging.StreamHandler())
```
しかし、daemonizeは標準出力されるものをファイルに流すようで、追加したストリームの内容もファイルに出力されてしまった。

## daemonizeの設定を/dev/stdout に設定
daemonizeは指定したファイルに標準出力・エラー出力を出力してくれるのだが、あえて/dev/stdoutに出力することで標準出力にできないかと試みた。
コンソール出力へはうまく出力ができたが、flaskのログローテーション機能が当該ファイルをチェックにいき、絶えずエラーメッセージが出てしまう。
ログローテーション機能を抑止する方法を探したが、見つからずに断念。

```log
uwsgi_check_logrotate()/lseek(): Illegal seek [core/logging.c line 494]
```

## ログファイルをtailで監視
起動シェル上でtailによる監視を追加。
ファイルにもコンソールにもログが出力できることを確認。start.shとuwsgi.ini両方で出力ファイルを合わせる必要があるが、とりあえずできた。

```bash:start.sh
# 追加部分
touch /var/log/uwsgi/uwsgi.log
tail -F /var/log/uwsgi/uwsgi.log > /dev/stdout &

uwsgi --ini=uwsgi.ini
nginx -g "daemon off;"
```
CloudFromation/samテンプレートでよく使う記法のメモ

#本ページについて

- マニュアルなどにも記載されているClouｄFormation/samのテンプレートの記法のうち、よく使うけれどもどうだったっけ？となりやすいものをメモします。最新の情報はマニュアルをご確認ください。
- 記述の方式は何通りか存在しますので、こちらに記載の内容”だけ”が唯一の書き方ではありません。

以下が前提です。

- yaml形式



##ImportValueとSubの組み合わせ

Importしたいエクスポート名自体をパラメータで変えたい場合

```
{'Fn::ImportValue': !Sub "hogehoge-${Parameter}"}
```


Importした値との文字列連結を行いたい場合。

```
- !Sub 
    - ${hogehoge}/hugahuga
    - hogehoge: {'Fn::ImportValue': example-export-name}
```


##参考URL
- ユーザーガイド
    - https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/Welcome.html
【PHP】三項演算子はどこで使えばいいのか？という話


三項演算子とは、if文の親戚的な何かであると耳にしたことのある人は多いかと思います。
プログラミング言語には大抵三項演算子が使える仕様になっています。
この三項演算子がしてくれる事と言えば、

１、条件式を作る
２、条件式に合致すればAの処理をする
３、条件式に合致しないのならBの処理をする

と言った事をしてくれるのです。

しかしここで疑問が幾つか湧き出ました。

**「これって、IF文と何が違うんだ？」
「具体的にどこで使うんだ？」**

ここではそんな疑問に答えていこうと思います。

~~ところで何故タイトルに【PHP】だなんて入れたんだ？と思うかも知れませんが、これは中の解説で使う言語がPHPだからで、ここでの解説は別に他の言語でも通じる話かと思います。~~

#三項演算子の使いどころは「真」「偽」で処理する時

まず簡単に言えば、if文より短く書ける場合に使う事があります。

１つの例として、if文の場合こんな感じに記述をしたとしましょう。

```php:test.php
$hoge = 1;

if($hoge === 1){
  $hoge = "1です";
}else{
  $hoge = "1ではないです";
};

echo $hoge;

```

これはつまり、
 
- $hogeに「1」を代入
- $hogeの中身が１の時には「１でした」と代入
- $hogeの中身が１以外の時は「１ではないです」と代入
- $hogeの中身を出力する

というソースコードです。

**IF文の場合、プログラムを見やすくするために、インデント(改行)はなるべく利用したいですからどうしても縦に長いコードになります。**

**そこで三項演算子の出番という訳です。**
上記と同じコードをここまで小さく表現できます。

```php:test:php
$hoge = 1;

$hoge = $hoge === 1 ? "これは１です":"これは１ではありません";
echo $hoge;

```
これが上記のコードと同じ結果を産むと言えば、効率的な書き方である事が解るかと思います。

ちなみに三項演算子とはどのような書き方なのか解説すると、

```php:説明

条件式 ? 真の場合の出力 : 偽の場合の出力;

```

**条件式に「何が”真”か？」を定義すれば、後は"?"以降の構文が出力を振り分けてくれます。**

#まとめ

**つまり、三項演算子は「真」「偽」で出力を変えたい時に、if文よりより労力をかけずにソースコードを完成させられる仕組みなのです。**


三項演算子の使い方を具体的に考え直してみると、

・正しいか間違いかの処理
・AかBのいずれかしかない処理
・ON/OFFの切り替えスイッチ的な処理
・合格か不合格か判定する処理

と言ったものに使えそうです。
Python命名規則：PEP8とリーダブルコードより

Pythonには 「[PEP8: Pythonコードのスタイルガイド](https://pep8-ja.readthedocs.io/ja/latest/)」があって、変数名や関数名などの命名規則も書いてあります。
命名規則やコーディングスタイルを合わせることで、ソースコードを読んでくれる人たち、レビューしてくれる人たちの負担を下げることができます。
PEP8の命名規則だけでなく「[リーダブルコード](https://qiita.com/search?q=tag%3Aリーダブルコード)」に書かれている命名方法も参考にしましょう。

## PEP8

| 用途 | 命名規則 |
|:-----------------|:------------------|
| 非公開 | 先頭にアンダースコアを1個つける<br>（外部からアクセス可能だけど、アクセスしないルール・約束事）<br>他言語のprotected属性に相当<br>サブクラスでオーバライドできる<br>関数・メソッド内のローカル変数は元々非公開なのでアンダースコアをつけない |
| サブクラスでの名前衝突回避 | 先頭にアンダースコアを2個つける<br>（クラス名を付与した名前で外部からアクセス可能）<br>他言語のprivate属性に相当<br>サブクラスで同じ名前をつけてもクラス毎に別々のインスタンス変数・インスタンスメソッドとして持てる |
| 特殊プロパティ、特殊メソッド | 前後にアンダースコアを2個つける<br>（言語仕様で用意されているので自分で新規定義しないこと） |
| 予約語や組込み関数名と衝突回避 | 最後にアンダースコアを1個つける |
| インスタンスメソッドの第一引数 | 常に `self` |
| クラスメソッドの第一引数 | 常に `cls` |

| 用途 | 命名規則 |
|:-----------------|:------------------|
| パッケージ<br>（ディレクトリ名） | 全て小文字の短い名前、アンダースコアは使わない |
| モジュール<br>（ファイル名） | 全て小文字の短い名前、アンダースコアで区切ってもよい |
| クラス、例外 | CapWords方式 （先頭だけ大文字の単語を繋げる、アンダースコアは使わない） |
| 関数、メソッド | 小文字のみ、必要に応じて単語をアンダースコアで区切る |
| 定数 | 大文字のみ、単語をアンダースコアで区切る<br>通常、モジュールレベル（関数の外側）に書く |
| 変数、引数 | 小文字のみ、必要に応じて単語をアンダースコアで区切る |
| 1文字変数 |  `l` (小文字のエル)、`O` (大文字のオー)、`I`(大文字のアイ) は決して使わない <br>(フォントによって数字の`1`、`0`と見分けがつかないため)|

## PEP8以外

| 用途 | 命名規則 |
|:-----------------|:------------------|
| 不使用変数 | アンダースコア1個<br> （forループや分割代入で変数が必要だけど使わない場合） |
| 1文字変数 | 1画面で見渡せる範囲（25行以内）で使い終わる一時変数に使う|

## リーダブルコード

* 単語は省略しない（慣例的に省略して使われている名前はOK）
* 名前に情報・意味を込める（flag, check では何のフラグか、何をチェックしたどんな値か分からない）
* 名前で情報を伝えてコメント不要にする（コメントにはwhatではなくwhyを書く）

など。