OmniAICreator/Qiita-1.07M huggingface dataset:
Salesforce で手軽に組織制限を監視する

# やりたいこと
Salesforce の組織制限(オブジェクトストレージや API コール数など)が気付かない間に危険水域に達する前に定常的に監視したい

# やったこと
最終的には Chatwork に通知したかったので Salesforce CLI で組織制限を取ってきて、それを見やすいよう awk で整形して Chatwork の API を叩くだけ。最終的には以下のようなコードになった。Slack や Teams に通知したいなら curl の部分をいい感じに変えれば似たようなことができるはず。

```bash
# $CW_TOKEN, $ROOM_IDは環境変数で指定する必要あり
body="$(sfdx force:limits:api:display -u DevHub | awk '{if($2 ~/^[0-9]+$/){if($2 != $3){p=$2/$3*100;printf "%-44s %-13.2f %-11d %-11d\n",$1,p,$2,$3}}else if($1 == "NAME"){printf "%-44s %-13s %-11s %-11s\n",$1,"REMAINING(%)",$2,$3}}')"
curl -sS -X POST -H "X-ChatWorkToken: ${CW_TOKEN}" -d "body=[code]${body}[/code]" "https://api.chatwork.com/v2/rooms/${ROOM_ID}/messages"
```

上記コードを cron などで定期的に叩けばお手軽監視が完成。

# 動作結果
以下の画像のような内容が通知される。制限が一切減ってない項目に関しては監視してもあまり意味がないため通知項目から外している。バリバリに使ってる組織であればもう少しいろんな項目が表示される
![スクリーンショット 2020-06-02 0.19.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445743/1961c740-9ab4-57a8-4866-c925152730fd.png)

# 動作要件
- DevHub を有効にしている
- Salesforce CLI をインストールしている & 認証を通している
- Bash が動く

# あとがき
もっと本格的に監視をしたければ自前で Apex 組むなり、コード改良して柔軟に通知できるようにしたほうがいいと思うので参考程度にご利用ください
selectbox テスト Capybara::ElementNotFound

#前提
rspec
Capybara
導入済み

#本題
今までほとんどfill_inを使用していたためselectboxのテストを行ってみたところ下記のようなエラーにハマりました。
<code>Capybara::ElementNotFound: Unable to find field "北海道" that is not disabled</code>


・間違い

```system.article_spec.rb
select "北海道", from 1
```
・変更点

```system.article_spec.rb
select "北海道", from "article[place_id]"
```

```_form.htm
<select class="form-control" id="article_place" name="article[place_id]"><option value="">選択してください</option>
<option value="1">北海道</option>
<option value="2">青森県</option>
<option value="3">岩手県</option>
<option value="4">宮城県</option>
<option value="5">秋田県</option>
<option value="6">山形県</option>
<option value="7">福島県</option>
<option value="8">茨城県</option>
<option value="9">栃木県</option>
<option value="10">群馬県</option>
<option value="11">埼玉県</option>
             ・
             ・
             ・
```

上記で問題なくテスト成功できました。
Javascript　初めてのGSAPアニメーションの使い方　その3　Timelinemax

前回の記事はこちら

[Javascript　初めてのGSAPアニメーションの使い方　その2　Tween.from/Jqueryとの併用](https://qiita.com/fumiya0414/items/c88c098d7a7d4dacbe45)

#Timelinemax

```html
    <div class="row row1">
      <div class="column col1">
        <p>パネル 1 (.circle)</p>
        <div class="circle shape"></div>
      </div>
      <div class="column col2">
        <p>パネル 2 (.square)</p>
        <div class="square shape"></div>
      </div>
      <div class="column col3">
        <p>パネル 3 (.rectangle)</p>
        <div class="rectangle shape"></div>
      </div>
    </div>
```

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

上記のようなhtｍｌをTweenMax.toで動かしてみます。

```javascript
TweenMax.to('.circle', 1, {x: 100});
TweenMax.to('.square', 1, {x: 100, delay: 1});
TweenMax.to('.rectangle', 1, {x: 100, delay: 2});
```

[![Image from Gyazo](https://i.gyazo.com/d4d348e219ca5a52fb7846e493695508.gif)](https://gyazo.com/d4d348e219ca5a52fb7846e493695508)

パネル１→３に向かってアニメーションをコントロールしていますが
秒数指定では要素が増えるほど記述が煩雑になります。

そこでTimelineMaxを使用してアニメーションの順番をコントロールします。

```javascript
const tlAnimation = new TimelineMax(); //tlAnimationというタイムラインを作成

tlAnimation.to('.circle', 2, { x: 100 })
.to('.square', 0.5, { x:100 })
.to('.rectangle', 1, { x:100 });

```

上記のようにタイムラインを作成して取得した要素を.チェーンでつなぐことによってdelayの指定をすることなくアニメーションの順番を指定できます。

順番を指定しているのでアニメーションの時間にも影響を受けません。

実行結果
[![Image from Gyazo](https://i.gyazo.com/d76b60910c31f8c80c2cb2bdef1348c1.gif)](https://gyazo.com/d76b60910c31f8c80c2cb2bdef1348c1)

次回はeasingの設定です。

[Javascript　初めてのGSAPアニメーションの使い方　その4　easing設定](https://qiita.com/fumiya0414/items/a0cc791c96f56472ca5a)
Emacsの環境を整える

# cmake-modeの導入
`CMakeLists.txt`のファイルに色がつかなかったので, 下記リンクを参考に`.emacs`ファイルを編集.
https://oimokihujin.hatenablog.com/entry/2014/06/13/115955

```emacs-lisp:.emacs
(require 'cmake-mode); Add cmake listfile names to the mode list.
(setq auto-mode-alist
	  (append
	   '(("CMakeLists\\.txt\\'" . cmake-mode))
	   '(("\\.cmake\\'" . cmake-mode))
	   auto-mode-alist))
```
これで, `CMakeLists.txt`に色がつくようになって見やすくなった.
FizzBuzz問題をシェルプログラムで作成してみる

#はじめに
Bashプログラミングの小ネタとして作成しました。
とある事情で急ピッチで記事を書いています。
ちなみに今回第3弾となります。

##FizzBuzzとは
FizzBuzzに関しては[こちら](https://ja.wikipedia.org/wiki/Fizz_Buzz)を確認ください。
1から順にカウントアップし、

- 3で割り切れるときは「Fizz」を表示
- 5で割り切れるときは「Buzz」を表示
- 両方で割り切れるときは「FizzBuzz」を表示

といったことをします。

###ソース
```bash
#!/bin/bash

echo -n "Please input number => "
read num

for i in $(seq 1 ${num})
do
  if (( $i % 3 == 0 && $i % 5 == 0 ))
  then
    echo "FizzBuzz"
  else if (( $i % 3 == 0))
    then
      echo "Fizz"
    else if (( $i % 5 == 0 ))
      then
        echo "Buzz"
      else
      echo $i
      fi
    fi
  fi
  sleep 1
done
```

###実行結果
```
$ ./fizzbuzz.sh
Please input number => 15
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
```

#終わりに
[3の倍数と3の文字列があるときにahoになるプログラム](https://qiita.com/saito_now/items/8e27142e162de60d6cf8)を応用させれば作れますね。

このプログラムを作成することで


- アルゴリズム
- 条件式
- 条件演算子
- readコマンド

が理解できました。
docker上のphpコンテナでcomposer installしたら、メモリ不足で落ちた話

## はじめに
docker上でlaravelの開発していて、必要なライブラリをcomposerでインストールしようとしたら下記のエラーが出て詰まった、、、:sweat_smile:

↓<font color="Red">エラーメッセージ</font>

```
Using version ^4.3 for laravel/socialite
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)

Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes) in phar:///usr/bin/composer.phar/src/Composer/DependencyResolver/Solver.php on line 223

```

## 原因調査
コンテナに入って、以下のコマンドを実行

```

$ php -r 'phpinfo();' | grep memory_limit

$ memory_limit => 128M => 128M
```

確かにデフォルトのphpのメモリが少ない、、、

ちなみに -r は <?php を略したもので、
コマンドライン上でphpのプログラムを実行するためのオプションです！

↓参照元　phpコマンドのオプション
https://www.php.net/manual/ja/features.commandline.options.php


## 対処方法

- phpのコンテナのdockerファイルに以下を追加
  
  ```Docker:php/Dockerfile
　COPY php.ini /usr/local/etc/php/ 
  ```
- php.iniをdockerファイルのディレクトリに作成

  ```php:php/php.ini
  memory_limit = -1
  ```

&emsp;-1は上限なしという意味

- コンテナを再起動し中に入ってメモリを確認する
  
  ```
  $ php -r 'phpinfo();' | grep memory_limit           
  $ memory_limit => -1 => -1
  ```
&emsp;php.iniの設定に切り替わってる〜！
&emsp;ナイスですね〜〜〜:thumbsup:と全裸の監督から聞こえてきそうです！

## 結果
もう一度composer installしたら、、、

```php
Package manifest generated successfully
```

無事インストールできました！マーベラス！
Mac Logicool option Flow 端末間コピーアンドペーストでエラーが出た話

# 目的

- Logicool option に対応した一部デバイスで使用できるFlow機能で端末間コピーアンドペーストに失敗する問題を解決したのでまとめる

# 実施環境

- ハードウェア環境(メインPC)

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ハードウェア環境(サブPC)

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.3) |
| ハードウェア | MacBook Pro (16-inch ,2019) |
| プロセッサ | 2.6 GHz 6コアIntel Core i7 |
| メモリ | 16 GB 2667 MHz DDR4 |
| グラフィックス | AMD Radeon Pro 5300M 4 GB Intel UHD Graphics 630 1536 MB |

- 使用入力デバイス

| 項目 | 情報 |
| --- | --- |
| Logicool MX ERGO | [MX ERGO](https://www.logicool.co.jp/ja-jp/product/mx-ergo-wireless-trackball-mouse?crid=7) |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| Logicool option バージョン | 8.20.233 | 2020/06/01の最新版をメインPC サブPC両方にインストール |

# 前提情報

- 先に記載したメインPCとサブPCをLogicool Flowで接続した。
- サブPCのテキスト情報を使用入力デバイスで選択後コピーを行った。
- メインPCにマウスカーソルを移動してコピー内容のペーストを行った。

# エラー内容

- メインPCに下記のエラーメッセージがポップアップとして表示された。
    - 「貼り付けアクションに失敗しました。コピー&貼り付けを再試行してください」
    
    <img width="349" alt="スクリーンショット 2020-06-01 9.54.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/b3cb103f-55d6-8559-0721-0937998f3cff.png">

- エラーメッセージ通り、何度コピーと貼り付けを再試行しても同じメッセージが出力されて正常に貼り付けを行うことができない。

# 原因

- apple系のデバイスの機能「Handoff」とLogicool Flowの機能が競合してしまっていた。
    - [Handoff を使ってほかのデバイスで作業を続ける](https://support.apple.com/ja-jp/HT209455)

# 解決策

1. サブPCにて設定画面の「一般」を開く。

    <img width="668" alt="システム環境設定.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/f2efc34a-ca28-fdf5-ab95-cc62849dabb3.png">

1. 「このMacとiCloudデバイス間でのHandoffを許可」のチェックマークを外す。

    <img width="668" alt="一般.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/0f95f1a6-01d2-001a-884a-56f200fd1fff.png">

1. メインPCにてLogicool optionを一旦閉じて再度起動させる。
1. Logicool Flowでコピーアンドペーストを試してみる。
SQLのJOIN



# LRFT JOIN（= LEFT OUTER JOIN）

```
select * from tableA
left join tabelB on tableA.id = tableB.A_id
where tableB is null
```
tableAに（leftに)レコードがあればtabeBになくても取得対象となる。


# RIGHT JOIN（= RGIHT OUTER JOIN）

```
select * from tableA
right join tabelB on tableA.id = tableB.A_id
where tableB is null
```

tableBに（rightに）レコードがあればtableAにレコードがなくても取得対象となる。
なのでこのwhere句は意味がない。

`left join` と `right join` は SQL分の位置が変わっただけ、
`right join` は `left join` で書き換えることができる。（逆も書き換え可能）


# INNER JOIN

```
select * from tableA
join tabelB on tableA.id = tableB.A_id
where tableB is null
```

where句関係なくそもそも tableAにもtableBにも存在するレコードしか取得対象とならない（なのでこのwhere句は意味がない） 


#JOINのアルゴリズム

[[SQL実践入門]結合のアルゴリズム Nested Loops, Hash, Sort Merge - SIS Lab](https://www.meganii.com/blog/2015/06/01/how-to-move-join-nestedloops-hash-sortmerge/)

- Nested Loop Join(NLJ)
    - １行ずつループして処理する
- Hash Join
    - 一度に前件を読み込んで処理する
- Sort Join
    - 全件をソートして上から順に比較する


MySqlはNLJしかサポートしていない。
PostgerSQLは３種類をサポートしている。

# JOINの問題点

JOINの回数が増えると急激に重くなる

- テーブルA、B、CをJOINした場合
AとB、AとC、BとC

- テーブルA、B、C、DをJOINした場合
AとB、AとC、AとD、BとC、BとD、CとD

- 100行と100行のJOIN
10,000行のテーブルスキャン相当

- 10,000行と10,000行のJOIN
1,000,000,000行のテーブルスキャン相当

### JOINを高速にするための工夫

- INDEXを貼る

- [実例で学ぶ、JOIN (NLJ) が遅くなる理屈と対処法 - Qiita](https://qiita.com/yuku_t/items/208be188eef17699c7a5)

# 参考
[失敗から学ぶRDBの正しい歩き方 (Software Design plus) | 曽根 壮大 |本 | 通販 | Amazon](https://www.amazon.co.jp/%E5%A4%B1%E6%95%97%E3%81%8B%E3%82%89%E5%AD%A6%E3%81%B6RDB%E3%81%AE%E6%AD%A3%E3%81%97%E3%81%84%E6%AD%A9%E3%81%8D%E6%96%B9-Software-Design-plus-%E6%9B%BD%E6%A0%B9/dp/4297104083)
富豪的プログラミング

FizzBizz　のEXCEL VBA　でコメントにつけた下記のプログラムに、非効率という指摘を受けたのだけど、
これって、[富豪的プログラミング](http://www.pitecan.com/fugo.html)なんだよね。
昔の愛読書であったbitで読んだ気がしたので検索したら、やはり bit 29(1), 36-37, 1997　だったよ。

```vb
Function FizzBuzz(Optional N = 100, Optional S = "")
    ReDim S(1 To N, 1 To 1)
    For I = 1 To N
        S(I, 1) = I
        If I Mod 3 = 0 Then S(I, 1) = "Fizz"
        If I Mod 5 = 0 Then S(I, 1) = "Buzz"
        If I Mod 15 = 0 Then S(I, 1) = "FizzBuzz"
    Next I
    FizzBuzz = S
End Function
```
TDPC O 文字列

##問題
https://atcoder.jp/contests/tdpc/tasks/tdpc_string
##見た感じ
まず見た感じでは、文字の多さ順に並べて、先に一番文字数の多いやつを並べてから、そこに足していけばいいやと思って、$dp[i]:ソートしたi文字目まで並べたときの場合の数$てな感じで、適当にdpすればいいやと思った。
けど、挿入の仕方にもいろいろあって、連続する部分が増えてしまうような挿入の仕方もあるし、連続する部分を消していくような挿入の仕方もある。
さらに、i色目まで使ったところでは連続するところがあっても、最後になくなれば、その並べ方もカウントすることを考えると、dpの条件を緩めてもっと広いものを数えないといけないので、$dp[i][j]::i文字目まで使ってj個連続する境界がある場合の数$として計算すればよさそうだと思った。
このdpを計算するにあたって、dp[i][j]にi+1番目の文字cを足すときを考えないといけなくて、jこの境界のうちl個をこの文字cの塊で埋めて、すでに並んでいる文字の個数をcount個とするとcを挿入したときに最後連続する境界の数が一つに定まらない。
これにかなり悩んだ末、ちょっとのぞき見すると、なるほどcをグループ分けしてk個に分けるとすると、最後の連続する境界の数が、j-l+freq[i]-kと一つに定まる。
##解法
上の場合分けでdpを配るdpの形式で計算した。
##ソースコード
```c++
const int N_MAX=270;
int freq[26],n;
mint dp[26][N_MAX];
combination c(N_MAX);//c(i,j)=i_C_j

mint solve(){
    int count;
    sort(freq,freq+26,greater<int>());
    count=freq[0];
    mint x;//int%mod
    dp[0][count-1]=1;
    rep1(i,25){
        if(freq[i]==0){
            for(int j=max(count-i,0);j>=0;j--){
                dp[i][j]=dp[i-1][j];
            }
            continue;
        }
        for(int j=max(count-i,0);j>=0;j--){
            rep1(k,freq[i]){
                rep(l,min(k,j)+1){
                    x=dp[i-1][j];
                    x*=c(j,l);
                    x*=c(count-j+1,k-l);
                    x*=c(freq[i]-1,k-1);
                    dp[i][j-l+freq[i]-k]+=x;
                }
            }
        }
        count+=freq[i];
    }
    return dp[25][0];
    
}

int main(){
    int x,y;
    //入力
    rep(i,26){
        cin >> freq[i] ;
        n+=freq[i];
    }
    //処理
    auto ans=solve();
    //出力
    cout << ans <<endl;
}
```
##振り返り
場合分けをさらに細かくすることで、計算できるようにするのはむつかしいのう
C++/socket サンプル


# 概要
windows/c++ は最近使われてなく、検索するとpythonばっかりヒットするのでメモ。

# [動作確認済み](https://www.geekpage.jp/programming/winsock/tcp-client-with-err.php)

# コピペserver

```

#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>

#define PORT 50007
//const char* host = "172.0.0.1";


//https://www.geekpage.jp/programming/winsock/tcp-3.php
int
main()
{
	WSADATA wsaData;
	SOCKET sock0;
	struct sockaddr_in addr;
	struct sockaddr_in client;
	int len;
	SOCKET sock;
	int n;

	if ( WSAStartup( MAKEWORD( 2, 0 ), &wsaData ) != 0 ) {
		return 1;
	}

	sock0 = socket( AF_INET, SOCK_STREAM, 0 );
	if ( sock0 == INVALID_SOCKET ) {
		printf( "socket : %d\n", WSAGetLastError() );
		return 1;
	}

	addr.sin_family = AF_INET;
	addr.sin_port = htons( PORT );
	addr.sin_addr.S_un.S_addr = INADDR_ANY;

	if ( bind( sock0, (struct sockaddr *)&addr, sizeof( addr ) ) != 0 ) {
		printf( "bind : %d\n", WSAGetLastError() );
		return 1;
	}

	if ( listen( sock0, 5 ) != 0 ) {
		printf( "listen : %d\n", WSAGetLastError() );
		return 1;
	}

	while ( 1 ) {
		len = sizeof( client );
		sock = accept( sock0, (struct sockaddr *)&client, &len );
		if ( sock == INVALID_SOCKET ) {
			printf( "accept : %d\n", WSAGetLastError() );
			break;
		}

		n = send( sock, "HELLO", 5, 0 );
		if ( n < 1 ) {
			printf( "send : %d\n", WSAGetLastError() );
			break;
		}

		closesocket( sock );
	}

	WSACleanup();

	return 0;
}

```

#　client

```
#include <stdio.h>
#include <winsock2.h>

int
main(int argc, char *argv[])
{
 WSADATA wsaData;
 struct sockaddr_in server;
 SOCKET sock;
 char buf[32];
 char *deststr;
 unsigned int **addrptr;

 if (argc != 2) {
	 printf("Usage : %s dest\n", argv[0]);
	 return 1;
 }
 deststr = argv[1];

 if (WSAStartup(MAKEWORD(2,0), &wsaData) != 0) {
	 printf("WSAStartup failed\n");
	 return 1;
 }

 sock = socket(AF_INET, SOCK_STREAM, 0);
 if (sock == INVALID_SOCKET) {
	 printf("socket : %d\n", WSAGetLastError());
	 return 1;
 }

 server.sin_family = AF_INET;
 server.sin_port = htons(12345);

 server.sin_addr.S_un.S_addr = inet_addr(deststr);
 if (server.sin_addr.S_un.S_addr == 0xffffffff) {
	 struct hostent *host;

	 host = gethostbyname(deststr);
	 if (host == NULL) {
		 if (WSAGetLastError() == WSAHOST_NOT_FOUND) {
			 printf("host not found : %s\n", deststr);
		 }
		 return 1;
	 }

	 addrptr = (unsigned int **)host->h_addr_list;

	 while (*addrptr != NULL) {
		 server.sin_addr.S_un.S_addr = *(*addrptr);

		 // connect()が成功したらloopを抜けます
		 if (connect(sock,
				(struct sockaddr *)&server,
				sizeof(server)) == 0) {
			break;
		 }

		 addrptr++;
		 // connectが失敗したら次のアドレスで試します
	 }

	 // connectが全て失敗した場合
	 if (*addrptr == NULL) {
		 printf("connect : %d\n", WSAGetLastError());
		 return 1;
	 }
 } else {
	 // inet_addr()が成功したとき

	 // connectが失敗したらエラーを表示して終了
	 if (connect(sock,
                     (struct sockaddr *)&server,
                     sizeof(server)) != 0) {
		 printf("connect : %d\n", WSAGetLastError());
		 return 1;
	 }
 }

 memset(buf, 0, sizeof(buf));
 int n = recv(sock, buf, sizeof(buf), 0);
 if (n < 0) {
	 printf("recv : %d\n", WSAGetLastError());
	 return 1;
 }

 printf("%d, %s\n", n, buf);

 closesocket(sock);

 WSACleanup();

 return 0;
}

```
iTunesAPIを使ってiTunesメディアからリンクを見つけ出す

# 大まかな処理内容
## ショートカット側
1.テキストもしくはURLが渡される
 →StoreIDが含んでいるかチェック、含んでいたらScriptableに渡す

```
{
   "how2": "lookup",
   "id": "< StoreID >"
}
```
2.iTunesメディアが渡される
 →タイトル名、アルバム名、アーティスト名、メディアタイプを取得してScriptableに渡す

```
{
   "how2": "search",
   "title": "< タイトル >",
   "album": "< アルバム >",
   "artist": "< アーティスト >",
   "mediatype": "< メディアタイプ >"
}
```
3.何も渡されない
 →エラー通知
## Scriptable側
### how2 == lookup
`https://itunes.apple.com/lookup?id=<StoreID>&country=jp&lang=ja_jp`
にGETリクエスト。
json貰ったらスクリプトを終了して出力。終わり！
### how2 == search
`https://iTunes.apple.com/search?term=<タイトル> <アルバム> <アーティスト>&media=<メディアタイプ>&country=jp&lang=ja_jp`
にGETリクエスト。
jsonを貰ったら、findメゾットで`trackName`,`collectoonName`,`artistName`が`<タイトル>`,`<アルバム>`,`<アーティスト>`と一致する要素を見つける。
見つかった要素を(さぞlookupしたからのように)フォーマットして、スクリプトを終了して出力。おしまい！

# ショートカット
![6E17D475-EC1C-45E3-B41C-E391136437F2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561438/17f70241-6dc5-1022-a728-b5509d0ba7cf.jpeg)

# スクリプト
```JavaScript:Musica.js
const INPUT = JSON.parse(args.plainTexts[0]);
const HOWTO= INPUT.how2;
const LIMIT = String(30);
const COUNTRY = 'jp';
const LANG = 'ja_jp';
const BASEURL = 'https://itunes.apple.com/' + HOWTO;

if (HOWTO == 'lookup') {
  let id = INPUT.id;
  let url = BASEURL +
           '?id=' + id +
           '&country=' + COUNTRY +
           '&lang=' + LANG;
  Pasteboard.copy(url) // debug
  let req = new Request(url);
  let response = await req.loadJSON();
  Script.setShortcutOutput(response);
  Script.complete();
 
} else if (HOWTO == 'search') {
  let title = INPUT.title;
  let album = INPUT.album;
  let artist = INPUT.artist;
  let mediatype = INPUT.mediatype;
  let term = [
               title,
               album,
               artist
             ].join(' ')
  let query = '?term=' +
              encodeURIComponent(term) +
              '&media=' + mediatype +
              '&country=' + COUNTRY +
              '&lang=' + LANG +
              '&limit=' + LIMIT;
  let url = BASEURL + query;
  Pasteboard.copy(url) // debug
  let req = new Request(url);
  let response = await req.loadJSON();
  let rslts = response.results
  let found = rslts.find(function(rslts) {
    return rslts.artistName == artist && rslts.trackCensoredName
  });

  if (found != null) {
    let formatted = {
                      "resultCount": 1,
                      "results": [
                        found
                      ]
                    };
// await QuickLook.present(found)
    Script.setShortcutOutput(formatted);
    Script.complete();
    
  } else {
    Script.setShortcutOutput('formatted is null')
    Script.complete();
  };
  
} else {
  console.error('HOWTO isn’t lookup or search');
  Script.complete();

};
```

半年間ずっとこいつと格闘した証です。とりあえず足跡が残せてよかった…
【xcode】swift5 BGMを流したまま効果音を鳴らす

##やりたいこと
BGMを流したまま効果音を再生する

##ソースコード
音声のファイル名：bgm.mp3と　button.mp3

```
import UIKit
import AVFoundation

class ViewController: UIViewController {
    var player0:AVAudioPlayer?
    var player1:AVAudioPlayer?
   
   override func viewDidLoad() {
       super.viewDidLoad()

　　　　// 再生する音声ファイルを指定する
       let url = Bundle.main.bundleURL.appendingPathComponent("bgm.mp3")
       do {
           try player0 = AVAudioPlayer(contentsOf: url)
       } catch {
           print("Error")
       }
       player0!.play()
       //音声をループさせる
       player0!.numberOfLoops = -1}

//ボタンを押したら効果音がなるように設定
@IBAction func playSound(sender: AnyObject) {
         // 再生する音声ファイルを指定する
        let soundURL = Bundle.main.url(forResource: "button", withExtension: "mp3")
         do {
　　　　　　　　player1 = try AVAudioPlayer(contentsOf: soundURL!)
             player1?.play()
         } catch {
             print("error...")
         }
     }
}
```

##まとめ
音を同時に再生しようとすると片方の音が止まってしまう問題に約１時間もハマってしまいました。
色々調べた結果【作るAVAudioPlayerのインスタンスの数だけ音楽再生関数を作る必要がある】とのことで上記のようなコードに至りました。
意外とシンプルだった。出来た時めっちゃ嬉しかったです。笑

初心者なので上記のコードがベストなのかはわからないのですがとりあえず動いたから良いと言うことで。笑
より良い同時再生方法があればご教授いただけると嬉しいです。
reactでシューティングゲーム

canvasの勉強をするために本に載ってたシューティングゲームの写経をした。
ただ、写経するだけではつまらないので、以下のように変更しながら学習をした。

**技術スタック**
`フレームワークなし、js` → `React + Redux Toolkit + Redux Saga + TypeScript`

**設計**
`継承のみ活用` → `継承、DIを活用`

https://github.com/pokotyan/shooting-game-react
<img width="727" alt="スクリーンショット 2020-06-01 22.34.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/9dd0934d-7865-d257-5f06-0e2d7abd00bd.png">
[ここ](https://relaxed-northcutt-99b679.netlify.app/)で実際に遊べる。（PCのみ）


コード書いてて感じたのはcanvasでゲームを作るときに、reactやreduxとかのフレームワークはいらないなと感じた。ただ複雑になってるだけのように感じる。[reactとcanvasは相性悪い](https://qiita.com/muijp/items/2524b3b898c802a6b97e)みたいな記事も作ってる最中に見かけたりした。

あと、[Redux Toolkit](https://redux-toolkit.js.org/) が結構いい感じだった。`createSlice` でreducerとactionの両方が自動で作られるのは楽。ただ、ミドルウェアはthunkしか対応してなくて、sagaを使うためにはちょっとガチャガチャしないといけないのがめんどかった。
plt.close() だけではメモリが解放されない場合がある

# 追記2

こちらの記事に汎用的な対処法が記載されています。
[matplotlib.pyplot のメモリリークの対処法 - Qiita](https://qiita.com/Masahiro_T/items/037c118c9dd26450f8c8)

# 注意（追記1）

本記事で紹介する実験では、``plt.clf() → plt.close()``とすればメモリが解放されるという結果になりました。しかし、``plt``の使い方によっては、``plt.clf() → plt.close()``としてもメモリが解放されない場合がある事が後に判明しました。そのため、当記事は``plt``におけるメモリ解放の挙動を理解するに当たっての参考として利用いただければと思います。

なお、事例としては、``plt.tight_layout()``や``plt.savefig()``をするとメモリが解放されない様です。この場合、もしJupyter上で実行しているのではれば、別のセルで``gc.collect()``をする事で、kernelを再起動せずに大半のメモリを解放できる事を筆者は確認しています。（一方、同じセルで``plt.clf() → plt.close()``をした直後に``gc.collect()``をした場合は、メモリは解放されていませんでした。）

# 要約

```python
# NG
# メモリが解放されない
plt.close()

# OK
# メモリが解放される
plt.clf()
plt.close()

# NG
# 順番を逆にするとメモリが解放されない
# plt.close() で figure を閉じると、描画内容を clear 出来なくなるからだろう。
plt.close()
plt.clf()
```

# 経緯

一度に数千枚のグラフを描画していた所、out of memory エラーが出てしまいました。　毎回``plt.close()``をしていたので何故だろうと思い以下の実験方法で調べました。その結果、``plt.close()``だけではメモリが解放されない事が分かりました。そして、``plt.clf() → plt.close()``とすればメモリが解放される事が分かりました。

# 実験方法

メモリサイズが大きいグラフを10回連続でプロットします。
各プロット終了時のメモリ使用量を記録しておき、プロット回数とメモリ使用量の関係を調べます。
この手順を以下の4パターンで行います。

||後処理の方法|
|:--|:--|
|パターン1|plt.clf()|
|パターン2|plt.clf() → plt.close()|
|パターン3|plt.close()|
|パターン4|plt.close() → plt.clf()|

ただし、**パターンごとに毎回 kernel を restart します。** メモリ使用量のベースラインを揃えるためです。

これを行うコードは以下の通りです。

```python
import matplotlib.pyplot as plt
import numpy as np
import psutil

mem_ary = []

# 10回プロットする
for i in range(10):
    
    # メモリサイズが大きいグラフを描画
    x = np.arange(1e7)
    y = np.arange(1e7)
    plt.plot(x, y)
    
    # ===================================================
    # 以下のパターン1からパターン4のいずれか1つを実行する
    # 残りはコメントアウトする
    # ===================================================

    # パターン1
    plt.clf()
    
    # パターン2
    plt.clf()
    plt.close()
    
    # パターン3
    plt.close()
    
    # パターン4
    plt.close()
    plt.clf

    # ===================================================

    # メモリ使用量を記録
    mem = psutil.virtual_memory().used / 1e9
    mem = round(mem, 1)
    mem_ary.append(mem)
```

# 結果と結論

結果をグラフにまとめると次の様になりました。

<img width="766" alt="スクリーンショット 2020-06-01 午後11.38.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178570/8296621a-2f69-8153-e333-faf2521e0cf2.png">


``plt.clf() → plt.close()``だけ、メモリ使用量が増加していません。従って、``plt.clf() → plt.close()``とするべき事が分かります。

また、順番を逆にして``plt.close() → plt.clf()``とするとメモリが解放されなくなっています。注意した方がいいでしょう。原因は、おそらく``plt.close()``で figure を閉じると、描画内容を clear 出来なくなるからだと思います。（参考：[plt.close()の公式DOC](https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.close)、[plt.clf()の公式DOC](https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.close)）

# バージョン

matplotlib：3.2.1
c# posgre 接続 createdb

```c#:Program.cs

using System;
using Npgsql;

namespace db02
{
    class Program
    {
        static void Main(string[] args){

        //接続文字列
        NpgsqlConnection conn = new NpgsqlConnection("Server=localhost;Port=5432;User ID=postgres;Database=postgres;Password=Chatdb01;Enlist=true");

            conn.Open();
            try {
                NpgsqlCommand command = new NpgsqlCommand("DROP DATABASE IF EXISTS test01", conn);
                command.ExecuteNonQuery();
                command = new NpgsqlCommand("CREATE DATABASE test01", conn);
                command.ExecuteNonQuery();
                string comment = "'Test Database " + DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss") + "'";
                command = new NpgsqlCommand("COMMENT ON DATABASE test01 IS " + comment, conn);
                command.ExecuteNonQuery();
            } finally {
                conn.Close();
            }

            conn = new NpgsqlConnection("Server=localhost;Port=5432;User ID=postgres;Database=test01;Password=Chatdb01;Enlist=true");
            conn.Open();
            try {
                NpgsqlCommand command = new NpgsqlCommand("select version()", conn);
                command.ExecuteNonQuery();
                var serverversion = (String)command.ExecuteScalar();
                Console.WriteLine("PostgreSQL server version: {0}", serverversion);
            } finally {
            conn.Close();
            }
        }
    }
}
```
Windows10にGit環境を構築してみた

# Sourcetreeをインストール
　Windows10でバージョン管理が必要となったので、簡単にGitも一緒にインストール出来る
[Sourcetree](https://www.sourcetreeapp.com) をインストールしてみた。
　(いろいろ躓いたので、自分用のメモとして残したものです。)

## スタートメニューにSourcetreeがいない！
　インストールして動作確認が終わり、再度、アプリを起動しようとすると、スタートメニューにSourcetreeがいない。
Windows初心者なので、少し焦りましたが、以下の場所にありました。(隠しファイルの中です。)

```
C:\Users\username\AppData\Local\SourceTree\SourceTree.exe
```
　ショートカットを作って、以下に移動します。(これも隠しファイルの中です。)

```
C:\ProgramData\Microsoft\Windows\Start Menu\Programs
```
　ちなみに、このフォルダに直接ショートカットを作成する事は出来ません。

## コマンドプロンプトでGitが使えない？
　次にコマンドプロンプトで`git —-version`を入力してみるとエラーになりました。pathを設定してあげないといけないらしい。SourcetreeのGitは以下の場所にありました。

```
C:\Users\username\AppData\Local\Atlassian\SourceTree\git_local\bin\git.exe
```
　同じ場所にあったbash.exeでGitのバージョンを確認してみると2.24.1でした。(2020.6.1時点)
　Gitの脆弱性が明らかになっておりバージョンアップが必要でした。(CVE-2020-5260)

# Windows10にGitをインストール
　今後のことも考えて本家からGitをインストールすることにします。(最初からこうすれば良かった。疲れた。)

　標準の設定でGitをインストール。ただし、Macからも使いたいので、テキストファイルの改行のスタイル設定だけCheckout as-is, commit Unix-style line endings:(“input”)を選択しました。

　この後、Sourcetreeの「ツール」メニューの「オプション」から「git」タブを選択して「Use System Git」ボタンで切り替えておきました。

　もっと良いやり方があると思いますが、これでしばらく動かしていこうと思います。

# WindowsでのGitアップデート方法
　コマンドプロンプト(またはgit bashかPowerShell)を起動して以下のコマンドを入力します。

```
$ git update-git-for-windows
```
　これは簡単！(なお、2.13以前は使えないようです。)
c# posgre 接続 select



```c#


using System;
using Npgsql;

namespace db01
{
    class Program
    {
        static void Main(string[] args){
            //接続文字列
            NpgsqlConnection conn = new NpgsqlConnection("Server=localhost;Port=5432;User ID=postgres;Database=postgres;Password=Chatdb01;Enlist=true");
            //PostgreSQLへ接続
            conn.Open();


            NpgsqlCommand cmd = new NpgsqlCommand("select version()", conn);
            var serverversion = (String)cmd.ExecuteScalar();

            Console.WriteLine("PostgreSQL server version: {0}", serverversion);
            conn.Close();
        }
    }
}
```
【Python】Udemy 画像判定AIアプリ開発 Part1 


pipでflickrapiをインストールしようとしたらエラーが出力

##環境
Windows10
python3.7.6
Anaconda

##内容
pipでflickrapiをインストールする為，下記コマンドを入力

```
(tf140) C:\Users\ユーザー名>pip install flickrapi
```

エラーが発生

```
ERROR: Exception:
Traceback (most recent call last):
  File "C:\python\envs\tf140\lib\site-packages\pip\_vendor\urllib3\response.py", line 425, in _error_catcher
    yield
  File "C:\python\envs\tf140\lib\site-packages\pip\_vendor\urllib3\response.py", line 507, in read
                              ～～省略～～
    raise ReadTimeoutError(self._pool, None, "Read timed out.")
pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out.
```

調べてみたら，「Read timed out」普通に読み込みが長すぎて，エラーが出力されたっぽい。

##対応と結果
下記コマンドを投入

```
pip --default-timeout=100 install flickrapi
```

タイムアウトになるまでの時間（デフォルト値）を100秒に変更みたいな感じかな、、、、？

上手くいきました:relaxed:
ゼロから始めるLeetCode Day43「5. Longest Palindromic Substring」

#概要
海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

その対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイト。

せっかくだし人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day42「2. Add Two Numbers」](https://qiita.com/KueharX/items/4c2734a5d0b5db87f1b3)

今はTop 100 Liked QuestionsのMediumを解いています。
Easyは全て解いたので気になる方は目次の方へどうぞ。

[Twitter](https://twitter.com/kueharx)やってます。

# 問題
[5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/)

難易度はMedium。
Top 100 Liked Questionsからの抜粋です。

文字列である`s`が与えられるのでその文字列の中で最も長い回文（どちらから読んでも同じになる）を探し出すようなアルゴリズムを設計してください。


>Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.

>Input: "cbbd"
Output: "bb"

以前解いた、
[ゼロから始めるLeetCode Day30「234. Palindrome Linked List」](https://qiita.com/KueharX/items/73ec43d8c4f6da343fcd)
こちらに似ていますが、前回はあくまで与えられた連結リストが回文であるかをチェックするだけであったのに対し、今回は文字列でその中から最長のものを抽出するというものに変わっており、少し複雑になっています。

# 解法

とはいえ、回文の問題のオーソドックスな考え方は前回のような要素をひっくり返した物を舐めていくものと元々の要素を比較し、仮に一致するのであれば比較を続け、そうでなければそれらの文字列を用意した文字列に保存しておく、というものでしょう。

例えば、例として与えられている`"babad"`であれば、

`babad`
と
`dabab`
を前から一緒に舐めていき、一致する一つ目の`a`から二つ目の`a`までを元々保存してある文字列の長さと比べ、要素が長い方を残すようにし、最後にその文字列を返せば解けそうです。
問題はその要素の舐め方をどのように設定するかですが、反転はスライスの[::-1]で簡単に実装できます。
なので、O(N^2)にはなりますが、for文を二つ回すという荒技で解いてみましょう。

```Python
class Solution:
    def longestPalindrome(self, s: str) -> str:
        if not s:
            return ""
        for i in range(len(s),0,-1):
            for j in range(len(s)-i+1):
                if s[j:i+j] == s[j:i+j][::-1]:
                    return s[j:i+j]
# Runtime: 4884 ms, faster than 25.37% of Python3 online submissions for Longest Palindromic Substring.
# Memory Usage: 13.7 MB, less than 22.69% of Python3 online submissions for Longest Palindromic Substring.
```
流石に遅いですね・・・

めちゃくちゃ速い回答例としては、以下のようなものがありました。

```Python
class Solution(object):
    def longestPalindrome(self, s: str) -> str:
        if len(s) < 2:
            return s
        start = 0
        maxLen = 1
        i = 0

        while i < len(s):
            l = i
            r = i
            while r < len(s) - 1 and s[r] == s[r+1]:
                r += 1
            i = r + 1
            while r < len(s)-1 and l > 0 and s[r+1] == s[l-1]:
                l -= 1
                r += 1
            if maxLen < r - l + 1:
                start = l
                maxLen = r - l + 1
        return s[start: start + maxLen]
# Runtime: 116 ms, faster than 95.05% of Python3 online submissions for Longest Palindromic Substring.
# Memory Usage: 13.8 MB, less than 22.69% of Python3 online submissions for Longest Palindromic Substring.
```
>https://leetcode.com/problems/longest-palindromic-substring/discuss/410963/Python-beats-93-solution-with-illustrations

スッゲェ速い！！！！！
勉強すべきことは尽きませんね。とても良いです。

では今回はここまで。お疲れ様でした。
Ruby の Range で ("b".."aa") が使えなかった件について

## 背景

### 事の発端

1. [Kinx](https://qiita.com/Kray-G/items/ca08b6fb40d15dd0ec76) では Ruby と同じように文字列の Range をサポートしたが、"z" の次は "aa" なので、単純に辞書順ではない `<=>` 演算子を定義してました。
2. で、普通にソートすると、当然辞書順にはなりません。（文字列長いほうが大きいと判断されるため）
3. で、そういえば Ruby は辞書順ですね、文字列のソート。**なんか変だな**。

> [注] Kinx って何?
> 最初の動機 ⇒ [こちらをご覧ください](https://qiita.com/Kray-G/items/ca08b6fb40d15dd0ec76)
> リポジトリ ⇒ [こちらをご覧ください](https://github.com/Kray-G/kinx)


### 確認してみた

1. irb で `"b" <=> "aa"` やってみよう、

    ```irb
    irb(main):001:0> "b" <=> "aa"
    => 1
    irb(main):002:0>
    ```

2. **おゃ？！**
3. では Range では？試しに `"a".."c"` を表示すると。

    ```irb
    irb(main):002:0> a = "a".."c"
    => "a".."c"
    irb(main):003:0> a.each {|e| p e }
    "a"
    "b"
    "c"
    => "a".."c"
    ```

5. ちゃんと列挙されます。では疑惑の `"b".."aa"` は?

    ```irb
    irb(main):004:0> a = "b".."aa"
    => "b".."aa"
    irb(main):005:0> a.each {|e| p e }
    => "b".."aa"
    ```

5. なんと、`"b".."aa"` は使えないのか...

## 結論

### 私の気持ち

やっぱり `"b".."aa"` も **動いてほしい** よね。`"b"` の次は `"c"` で、そのまま `"z"` まで進んだ後に `"aa"` で終了してほしいなーと思いましたが、他の方はどうなんでしょう。

### 実際に行ったこと

なので、[最新のリポジトリ](https://github.com/Kray-G/kinx)（0.8.1 には入ってません）では以下のように修正しましたよ。

1. 文字列の `<=>` 演算子は辞書順に戻した。
2. `class Range` の `<=>` の部分は文字列だけ特別扱いにして `"b".."aa"` も使えるようにした。
    * `"b", "c", "d", ..., "z", "aa"` になる。

## おわりに

ということで、ここ（＝文字に対する Range の仕様）は Ruby と仕様が違います。何か問題があればお知らせください。

まあ、こんな特殊な条件ではあまり使わないので、誰も困ってなさそうですが。だから別にどっちでもいいと言えばどっちでもいいかもしれません。細かい話でした。

Ruby 的にはどうなんでしょうね。想定内なのか、想定外なのか。意図してなのか、そうでないのか。まあ定義が明確で、定義に従った動作なので、こういうもの＝仕様、ってことで落ち着きそうですが。

ではまた、次回。
iOSアプリ　ノッチ判定

##はじめに
アプリ完成間際、ノッチの存在に気付き実装しました。
忘れがちなので、気をつけたいです。

##やりたいこと

iPhoneX以降、ノッチが出現したことにより、画面上部ぎりぎりに配置すると、
ノッチと被ってしまい画面上に表示されなくなってしまいます。
なので、ノッチがあるかないかを判定して、<br>
ノッチがある場合　→　ノッチ分(44pixel)ずらす
ノッチがない場合　→　画面上部ギリギリに配置<br>

という方法をとることにしました。

##実装

```view.swift
class view: UIViewController {
  let text = UILabel()

  override func viewDidLoad() {
     
     //safeAreaの値を取得します。
     let safeAreaInsets = UIApplication.shared.keyWindow?.safeAreaInsets.left

     super.viewDidLoad()
     
     //safeAreaの値が44.0以上であれば、ノッチがあるので、x位置をずらします。
     if(safeAreaInsets! >= 44.0){
         text.frame =  CGRect(x:50,y:width/2, width:self.view.frame.height,height: 50)
     }
     //ノッチがない場合の処理
     else{
         text.frame =  CGRect(x:10,y:width/2, width:self.view.frame.height,height: 50)
     }
 }
```

ノッチの値が44なので、今回は50ずらしました。
JekyllでパーマリンクにFront Matterのカスタム変数を使う方法

「Front Matterのカスタム変数をパーマリンクに使いたい！」ので、使えるようにしてみたという記事です。https://mekurun.com/ を作るのに使っています。

## 背景
Jekyll で生成する記事のURLは、`_config.yml` の設定や Front Matter での直接の指定でカスタマイズできます。以下で軽く説明しますが、詳しくは、公式ガイドの [Permalinks | Jekyll](https://jekyllrb.com/docs/permalinks/) を参照ください。[日本語版](http://jekyllrb-ja.github.io/docs/permalinks/)

### `_config.yml` で記事のURLを設定する方法
```yml:_config.yml
permalink: /:categories/:title
```
`_config.yml` で、上記のような指定をすることで、全ポストのURLを一定のルールで決めることができます。しかし、事前に用意された Placeholder(置換用変数) しか使えません。
([組み込みフォーマット](http://jekyllrb-ja.github.io/docs/permalinks/#%E7%B5%84%E3%81%BF%E8%BE%BC%E3%81%BF%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88)などの説明はここでは割愛します)

### Front Matter で記事のURLを設定する方法
[Front Matter](http://jekyllrb-ja.github.io/docs/front-matter/) とは、ファイルの最初に3つのダッシュで挟まれたYAMLで、このブロックがあると Jekyllさんはファイルをいい感じに処理してくれます。記事のタイトルやカテゴリーなどを設定するのに使ったことがある方も多いでしょう。

```yml:about.md
---
permalink: /about/
---
```

この方法は柔軟に好きなパーマリンクを設定できますが、一定のルールで複数のページのパーマリンクを設定するのには向いていません。

## 本題 (`_plugins` を使ってパーマリンクをカスタムする方法)

しかし、「Front Matterのカスタム変数をパーマリンクに使いたい！」という場合にはどちらも向いていません。そこで、`_plugins` を使ってパーマリンクをカスタムする方法の登場です。
今回はこんな記事たち↓があるとします。デフォルトの変数の他に、`author` という変数を使っていますね。この著者猫さんの名前をパーマリンクに含めるのが目標です。

```md:2020-06-01-test.md
---
layout: post
title: "テスト記事だにゃー"
date: 2020-06-01 11:14:26 +0900
categories: cat
author: toraneko
---
```
1. まず、サイトのrootディレクトリ直下に `_plugins` というディレクトリを作ります。  
2. 適当な名前の.rbファイルを作ります。ここでは `jekyll_change_permalinks.rb` にしてみました。  
3. 中身を書きます。

```rb:jekyll_change_permalinks.rb
module Jekyll
  class PermalinkRewriter < Generator # Generatorクラスを継承してあげます
    safe true
    priority :low # プラグインがロードされる順位を決めてあげます

    def generate(site) # ジェネレータはこのメソッドを使います
      site.posts.each do |item|
        @author = item.data['author'] # Front Matter の変数はこれで取得できます
        unless @author.nil? # nilじゃないかな？チェック
          item.data['permalink'] = "/:categories/#{@author}/:title/"
        end
      end
    end
  end
end
```

`/cat/toraneko/test/` で、先程の記事が見られるようになりました！

## まとめ
「Front Matterのカスタム変数をパーマリンクに使いたい！」というときはこんな方法があるよ！という紹介でした(´∀｀*)

それぞれに長所と短所があるので、目的にぴったりな方法を見つけると良さそうです💭
### 比較
| 方法 |ルールがある  |カスタム変数を使える  |
|---|---|---|---|
|_config.ymlを使う方法  |○  |✗  |
|Front Matterで直指定  |✗  |✗  |
| _pluginsを使う方法 |○  |○  |

## 参考
[Your first plugin | Jekyll • Simple, blog-aware, static sites](https://jekyllrb.com/docs/plugins/your-first-plugin/)
[Generators | Jekyll • Simple, blog-aware, static sites](https://jekyllrb.com/docs/plugins/generators/)
[Permalinks | Jekyll • Simple, blog-aware, static sites](https://jekyllrb.com/docs/permalinks/)
[What are the steps to getting this 'custom' permalink scheme in Jekyll?](https://stackoverflow.com/questions/16235601/what-are-the-steps-to-getting-this-custom-permalink-scheme-in-jekyll)
[Search · class PermalinkRewriter < Generator](https://github.com/search?q=class+PermalinkRewriter+%3C+Generator&ref=reposearch&type=Code&utf8=%E2%9C%93
)
Javaのクラスメソッド

###クラスメソッド
クラスに属するメソッドのことです。
クラスメソッドの定義は、「public static 戻り値の型 メソッド名()」です。
クラスメソッドはインスタンスを生成しない状態でも呼び出せます。
クラス名の頭文字は大文字です。
【例】Personクラスとします

```Person.java
class Person {
  public static 戻り値の型 メソッド名() {
    // メソッドの処理
  }
}
```
【例】

```Main.java
class Main {
  public static void main(String[] args) {

    〜省略〜

    Person.printCount();
  }
}
```

```Person.java
class Person {
  public static int count = 0;

   〜省略〜

  public static void printCount() {
    System.out.println("合計は" + count + "です");
  }
}
```
Ansibleと変数と時々jinja2 

## はじめに
Ansibleのtemplatesで使用される、jinja2はAnsibleのYAMLファイル内でも使用できます。

## 例

jinja2の表記を使用したい箇所を`{{  }}`で囲むだけです。
また、別の変数も`{{  }}`内で参照することができます。

```yaml:playbook.yml
- hosts: localhost
  connection: local
  vars:
    file_path: /path/to/file
    file_name: "{{ file_path.split('/')[-1] }}"
    dir_name: "{{ file_path.split('/')[-2] }}"
  tasks:
    - name: "print file_path"
      debug:
        msg: var={{ file_path }} # var=/path/to/file

    - name: "print file_name"
      debug:
        msg: var={{ file_name }} # var=file

    - name: "print dir_name"
      debug:
        msg: var={{ dir_name }} # var=to
```

利用できる場所に指定はありません。
例えば、変数定義であれば`vars/main.yml`, `group_vars/`, `host_vars/`などで利用可能です。

## 終わりに
上記の使い方はちょっとアレですが。。。
変数定義で上手に利用すると変更があった際に、修正箇所が少なくできます。
stateを直接参照しないシンプルなVuexサイクル

# Vuexとは？
Vue.jsアプリケーションにおける状態管理パターンライブラリです。

コンポーネント間のデータや関数の受け渡しには、propsやemitを使いますが、Vuexは全てのコンポーネントのための集中型のStoreになります。
propsやemitだけでデータの受け渡しをするのは、バケツリレーに似ていて、vueファイルに何度も同じコードを書く必要があったり、無駄にロジックが発生します。

# Vueコンポーネント層とVuexはどう繋がるのか？
今回の記事のタイトルは**「stateを直接参照しないシンプルなVuexサイクル」**です。
Vueコンポーネント層からStore内のstateにアクセスするためには

- **store.state**や**mapState**を使ってstateを直接する方法
- **store.getters**や**mapGetters**を用いて、取得する方法

があります。

ただ、Stateの変更をどこからでも直接、自由に変更、取得可能だと、全コンポーネント共通で参照可能なStateの秩序を保つことが出来ません。
そのため、公式ドキュメントにも掲載されている以下の図の通り、VuexのライフサイクルをルールとしてStateを変更、取得します。

![vuex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253605/f08ee396-e5d0-4b3d-e6dc-3929fe62529b.png)

stateの変更はMutationsが行い、vueコンポーネント層からはgetterを使用してStateの値を取得します。
そのMutaitionsはVueコンポーネント層から呼ばれるActionsによって実行されます

話がややこしくなってきたのでもう少し詳細にしてみます。
Vue.jsやNuxt.jsとVuexを使ってStateを管理したい。
そんなときに登場してくるのは **Actions** **Mutaitions** **State** **Getters** この4つです。

# Vuex それぞれの役割
今回は、Firestoreに保存されているItemsを取得し、それをVuexのStateに格納して、コンポーネント層で使用する例を挙げます。
`store/items`以下に
- state.js
- action.js
- mutaition.js
- getter.js

を準備します。

## State
Stateでは初期値を格納します。
基本的には配列が入る想定であれば**[]**、文字列を想定すれば**''**を初期値にします。
state.jsを用意して以下のように記述すると

```js
export const state = () => {
  allItems: []
} 
```

stateの初期値はから配列になります。

## Getters
GettersではStateの値をコンポーネント層で取得する際に使います。
例えば、Stateに格納されている**allItems**を取得するなら以下のようにして

```js
export const getters = {
  getAllItems: state => state. allItems
}
```

vueコンポーネントからは

```js
computed: {
  allItems() {
    return this.$store.getters['items/getAllItems']
  }
}
```
のようにして取得できます。

ただこのままだと、allItemsは空配列なのでMutaitionsからStateを更新します。

## Mutations
Actionsを定義する前に、Mutationsを用意します。

```js
export const mutations = () => {
  setAllItems(state, items) {
    state.allItems = items
  }
}
```
setAllItemsという関数を作ります。
第1引数は値を変更するstateで、第2引数はActionsからもらうitemsとなります。
そのitemsをStateのallItemsの代入することでStateを更新できます。

## Actions
次にVueコンポーネント層からActionsを呼ぶ必要があるので定義します。

```js
export const actions = () => {
  async fetch({ commit }) {
    const docs = await Firestore.collection('items').get()
    const items = docs.map(doc => doc.data())
    commit('setAllItems', items)
  },
}
```

commit関数の第1引数にMutaitionsの実行したい関数を文字列で指定し、第2引数にFirestoreから取得したitemsを指定します。

コンポーネント層でからは以下のようにActionsを呼ぶことが出来ます。

```js 
fetch({store}) {
  store.dispatch('items/fetchAllItems')
}
```

# 所感
今回は**State** **Getters** **Mutations** **Actions**の順で実装しましたが、どこから実装するのかに問題はありません。
名称からどんな役割があってどこからどんなふうに呼び出せば良いのか覚えるまでに時間がかかるかもしれませんが、使っていくうちに分かってきます。

ちなみに[menta](https://menta.work/invite/jpypIpqn1EFEaDOe)というコーチングサービスでVue.jsを中心にメンターをしています。
もう少し詳しい内容を聞きたい方や、Vue.jsの勉強に行き詰まっている方など、ぜひ[menta](https://menta.work/invite/jpypIpqn1EFEaDOe)で**watsuyo_2**にメッセージをしてください！


# 参考 
[Vuex とは何か？](https://vuex.vuejs.org/ja/)
RubyとPython間のプロセス間通信を行う(POSIX メッセージキュー)

# 概要

rubyとpythonのdaemon間でデータの受け渡しをredis(Pub/Sub)[^Streams]を使って考えていたら、プロセス間通信(POSIX IPC)使ったほうが手軽だよと天の声が聞こえたので試してみました。

なお、今回はraspberry pi上で動かすので、電源問題のためにもプロセス数は可能な限り減らす作戦で検討しています。

[^Streams]: redis5からPub/Sub機能よりもより信頼性の高い[Streams](https://redis.io/topics/streams-intro)という機能が増えています。

# POSIX メッセージキューとは

[POSIX](https://ja.wikipedia.org/wiki/POSIX)のシステムコール／ライブラリ関数を通じて利用できる、プロセス間通信の一つ。非同期型通信プロトコルで、誤解を恐れずにいえばRabbitMQなどのメッセージングミドルウェアの超簡易版のようなもの。POSIX準拠なので簡素なAPIでお手軽に利用できます。

詳しくは以下をご参照ください。

https://linuxjm.osdn.jp/html/LDP_man-pages/man7/mq_overview.7.html

# システム全体

- OS: Raspbian GNU/Linux 10 (buster)
- ruby: ruby 2.5.7p206 (2019-10-01 revision 67816) [armv7l-linux-eabihf]
  - 利用ライブラリ: posix-mqueue
    - https://github.com/sirupsen/posix-mqueue
- python: Python 2.7.16
  - 利用ライブラリ: posix_ipc
    -  https://pypi.org/project/posix_ipc/

# Ruby側の実装（送信側）

どっちが送信／受信でもよいのですが、今回はRubyを送信側としてみました。
利用ライブラリは[posix-mqueue](https://github.com/sirupsen/posix-mqueue)を利用させていただきました。
めっちゃシンプル。

```Ruby
require 'posix/mqueue'
require 'json'

def main
  m = POSIX::Mqueue.new("/whatever", msgsize: 8192, maxmsg: 10)
  10.times do |i|
    m.send({ messsage: "hello python world #{i}" }.to_json)
    sleep 1
  end
  m.send ({ message: 'end'}.to_json)
ensure
  m.unlink if m
end

if __FILE__ == $PROGRAM_NAME
  main
end
```

# Python側の実装（受信側）

こちらも恐ろしくシンプルです。
利用ライブラリは[posix_ipc](https://pypi.org/project/posix_ipc/)

```Python
# -*- coding: utf-8 -*-
import time
import posix_ipc
import json

def main () :
    mq = posix_ipc.MessageQueue("/whatever", posix_ipc.O_CREAT)
    while True:
        data = mq.receive()
        j = json.loads(data[0]) # ->  (message, priority)のタプルで戻ってくる
        print j
        if j.get('message') == "end":
            break

if __name__ == "__main__" : 
    main()
```

# 結果

想定通りPython側で出力されました！

```
$ python main.py 
{u'messsage': u'hello python world 0'}
{u'messsage': u'hello python world 1'}
{u'messsage': u'hello python world 2'}
{u'messsage': u'hello python world 3'}
{u'messsage': u'hello python world 4'}
{u'messsage': u'hello python world 5'}
{u'messsage': u'hello python world 6'}
{u'messsage': u'hello python world 7'}
{u'messsage': u'hello python world 8'}
{u'messsage': u'hello python world 9'}
{u'message': u'end'}
```
簡単なソースですが一応githubにも上げておきました。
https://github.com/y-amadatsu/posix-mq-with-raspberry-pi-os


# 余談

ちなみにPOSIX メッセージを使うとメッセージQueueが `/dev/mqueue` 配下に表示されます。マウントして `ls` や `rm` で操作することも可能です。このあたりはすごくUNIX！って感じ:relaxed:

```
cat /dev/mqueue/whatever 
QSIZE:350        NOTIFY:0     SIGNO:0     NOTIFY_PID:0     
```
phpredisインストール時に、PHPの設定でひさしぶりにハマったのでメモ

```
PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/local/src/phpredis/modules/redis.so' (tried: /usr/local/src/phpredis/modules/redis.so (/usr/local/src/phpredis/modules/redis.so: undefined symbol: php_json_decode_ex), /usr/lib64/php/modules//usr/local/src/phpredis/modules/redis.so.so (/usr/lib64/php/modules//usr/local/src/phpredis/modules/redis.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
```

こんなエラーを見かけたら、ポイントは `php_json_decode_ex`

これは、jsonをパースするモジュールより前にロードしようとして失敗しているということ。

`/etc/php.d` の中に、適当なファイル（アルファベット順でjson.iniより後に読み込まれるようなファイル名）を作って `extension=redis.so` と書けば解決。

参考：https://github.com/phpredis/phpredis/issues/1589#issuecomment-508646809
外部からLinuxを操作する方法　手順

#【学習環境】
Redhot系:CentOS
SSH接続用ソフト：TeraTerm
仮想マシン：VirtualBox

#【概要】
SSHで仮想ローカルLinuxにアクセスする方法

TeraTermを使ってLinuxにアクセスする場合、
外部からアクセスする許可をしなければいけない。

「CentOS のネットワーク設定をする」

###【手順】
1.ユーザー権限をrootにする
2.ネットワーク設定用のファイルを編集する
3.ネットワーク設定を行う
4.TeraTeamで接続


【詳細】
###１．ユーザー権限をrootにする
$su - を実行する（su と - の間はスペース）

```Linux:root権限コマンド
$su -
```
passwordを聞かれる。
password はホストユーザー（ログイン画面）にログインするためのパスワードを入力する
ここでうまく root ユーザーになると
コマンド命令を待つ記号（＄）が　＃　に変わる。
![スクリーンショット (418).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614211/58f0891b-3e5f-0124-c559-37e89a3407e9.png)



###２.ネットワーク設定用のファイルを編集する
以下のコマンドを入力してEnterではなくTab押す。

```
# vi /etc/sysconfig/network-scripts/
```

すると２パターンの画面表示が出るのでそれぞれに対応した
パターンで進んでください。
（Tabキーは次の入力候補を示してくれるコマンド）
※詳細はWebで検索

ーーーーーーーーーーーーーーーーーーーーーーーーーー
【パターン１】
![スクリーンショット (423).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614211/6cc4f152-8ddf-0e0c-ccf8-f3a893f6adb8.png)

上記のパターンの場合、ifcfg-○○ と ifcfg-lo を探して
ifcfg-○○ の方を　# vi /etc/sysconfig/network-scriprs/の後に記述

```
# vi /etc/sysconfig/network-scriprs/ifcfg-○○
```

上記のように記入したらEnterを押して【編集手順】に移ってください。
ーーーーーーーーーーーーーーーーーーーーーーーーーー

【パターン２】
![スクリーンショット (424).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614211/a33744de-c268-7e5a-8a24-4440649a7c78.png)

上記のように記入したらEnterを押して【編集手順】に移ってください。
ーーーーーーーーーーーーーーーーーーーーーーーーーー
【編集手順】
今回編集するファイルは　ifcfg-○○　のファイルです。
ちなみに○○は外部と接続するためのネットワークインターフェースの設定ファイル名です。人によって変わるので気にしなくて大丈夫です。
![スクリーンショット (426).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614211/a9e40972-366e-d64f-0d46-8cfd5fe53bb1.png)

以上の画面が出てきたら、以下の手順を踏んでください。
1. 　iキーを押して入力モードにする
2.　一番下のONBOOT= no を　yes に変更する
3.　Ctrl + C （もしくは Esc）で入力モード解除
4.　:wq コマンドで編集を保存して終了

###３.ネットワーク設定をする

画面の右上にある「仮想マシン」＞「ファイル」を選択

「ネットワーク」＞「高度」＞「ポートフォーディング」

設定を追加していく。
ホストポート：３３３３
ゲストポート：２２（SSHで接続するポート番号）
※覚えやすい番号なら何でも構いません。

設定が終わったら再起動する

```
# reboot
```


### 4.TeraTeamで接続

TeraTeamを起動

![スクリーンショット (427).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614211/0f9e667b-65eb-7bbb-c4ce-32f16de8076e.png)

Host:127.0.0.1:3333
TCP post# : 22

ネットワーク設定で追加した数字を設定

![スクリーンショット (428).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614211/1b38d056-ef96-e99f-087c-e2b3e30a6709.png)

Continue を選択

![スクリーンショット (429).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614211/fe7a152d-f267-a135-3144-d3e69c3e5cd6.png)

「User name」 と　「Passphrase」を追加したら
OKを選択
（※「User name」と「Passphrase」作成したホストのユーザー名とパスワード）

以上になります。
素因数分解の良問！ABC052/ARC067 Factor of Factorial を解いてみた！

こんばんは、Ruteです。
久々に<font color = "#FF0000"><b>良問</font>を解いた気がします。
今回はABC052/ARC067 C - Factors of Factorialについて、私がどのようにACしたのかを解説したいと思います！(コードはPython3です)
# ABC052(ARC067) C問題
https://atcoder.jp/contests/abc052/tasks/arc067_a?lang=ja

### 問題概要:
整数$N$が与えられます。$N!$の正の約数を$10^9+7$で割ったあまりを求めて下さい。
制約:
$1≦N≦10^3$

### 解法:
$10^3!$は、計算すると$2568$桁程度の整数になります。これを愚直に素因数分解していっても良いのですが、間違いなく<font color = "#FFCC00">実行時間超過(TLE)</font>になりそうです。

ここで、$N! = 1×2×3×... N$であることに着目すると、1からNまでのそれぞれを素因数分解した結果を合わせたリストを作成すれば、$N!$の素因数のすべてをまとめたリストが作成できそうです。

素因数分解のアルゴリズムについてまとめてみます。
#### 素因数分解のアルゴリズム
(素因数分解したい数を$n$とします)

```素因数分解.py
import math
def factorization(n):
    i = 2
    factors = []
    while i <= math.floor(math.sqrt(n)):
        print(i,n)
        if n%i == 0:
            factors.append(i)
            n //= i
        else:
            i += 1
    if n > 1:
        factors.append(n)
    return factors
```
1.i=2とします。
2.素因数のリストとして、factorを空のリストで定義します。
2.iが$ \lfloor \sqrt{n} \rfloor$を下回るまで以下のループを行います。
・$n$がiで割り切れるならiは素因数だからiをfactorに挿入し、$n$をiで割った商とする。
・$n$がiで割り切れないなら、iを+1する。
ループが終了した後、n > 1 なら、nは素因数になるからfactorに挿入します。
これで、factorが、$n$の素因数を示したリストになりました。

#### ACしたコード
```D.py
import math
#素因数分解
def prime_factorization(n):
    i = 2
    factors = []
    while i <= math.floor(n**0.5):
        if n%i == 0:
            factors.append(i)
            n //= i
        else:
            i += 1
    if n>1:
        factors.append(n)
    return factors
N = int(input())
ls = []
#コーナーケース
if N == 1:
    print(1)
else:
    for i in range(1,N+1):
      #1~Nの、それぞれで素因数分解した結果を1つのリストにする。
        ls.extend(prime_factorization(i))
    ls.sort()
    ans = 1 # ansはN!の約数の個数
    now = 1 # nowは現在の連続数
    now_2 = 0 #now_2は現在参照対象の数
    for i in range(len(ls)):
        if i == 0:
            now_2 = ls[i]
        else:
            if ls[i] == now_2:
                now += 1
            else:
                ans *= (now+1)
                now = 1
                now_2 = ls[i]
    ans *= (now+1)
    print(ans%(10**9+7))

```
https://atcoder.jp/contests/arc067/submissions/13929338

おおよそのアルゴリズムとしては、
1. $N$を入力
2. $N$が1ならば1を出力し(コーナーケース)、そうでなければ3に移る
3. $1$から$N$までの素因数をまとめたリストを1つのリストlsにする。
4. lsをソートする
5. lsの各要素について、以下のループを行う
・ls[i]が前のlsと同じなら、連続数を1増やす
・ls[i]が前のlsと異なるなら、ansに(連続数+1)を乗算する。連続数を1にする
6. ans%$(10^9+7)$を出力してAC !
<font color = "#FF0000">(かなり大雑把な説明ですみません.... )</font>


昨日、素因数分解が話題になっていたのですが、今日の[よるかつ](https://kenkoooo.com/atcoder/#/contest/show/d96c6984-f20d-492a-b445-39345c08b5f9)で出題されたのがこの問題で、素因数分解をするという発想に気づいて解くことが出来たので良かったです！

ここまでの記事を見て、解法が良かった！分かりやすかった！等と思った方は「LGTM」ボタンを押して頂けると嬉しいです！

以上、ABC052/ARC067 C - Factors of Factorialの解説でした！
Homebrewでdjangoプロジェクトを作る際の便利コマンドメモ

cd /Users/yamorijakarta/Desktop/kanban/
pipenv run python manage.py runserver
→プロジェクトのディレクトリでやらないとダメ。”manage.py”ファイルがあるディレクトリ

仮想環境を起動する時
source [newenvname]/bin/activate
メモ

### 偶数か奇数か

```
puts "数字入れて"
n = gets.to_i

if n.even?
 puts "偶数です"
else n.odd?
  puts "奇数です"
end  
```

### to_i　to_s
* to_iメソッドが文字→数値
* to_sメソッドが数値→文字

getsは文字列で保存する。
数値に変換するため→gets.to_i


### each_with_index

```
fruits=[“りんご”, “メロン”, “イチゴ”]

fruits.each_with_index do |fruit, i|
puts “#{i+1}番目の要素は#{fruit}です。”
end
【結果】
1番目の要素はりんごです。
2番目の要素はメロンです。
3番目の要素はイチゴです。
```


### 未コミットの変更を引き継ぎつつブランチを変更する
http://vatscy.github.io/blog/2014/03/30/git-branch-stash/