OmniAICreator/Qiita-1.07M huggingface dataset:
perlスクリプトをシェルスクリプトやワンライナーの中にパイプで入れこむときに引数と標準入力を両方使いたい

# シェルでスクリプトやワンライナーの中にパイプでperlスクリプトを入れこむときに引数と標準入力を両方使いたい

（230825追記しました, Perl v5.26.2/v5.36.0）

## scriptの場合

### その１
`@ARGV`で引数を受け取って、`<STDIN>`演算子をつかう。

perlスクリプトで最初のほうに
```perl
my(@hikisu) = @ARGV ;
```
1行入れておけばいいだけ。


以前は、
```perl
my(@hikisu) = @ARGV ;
@ARGV = ('-');
```
として、引数を受け取ったあとに標準入力に入れ替えて<>をつかっていた。でも<STDIN>つかったほうが明示的でよい。

例えば、`test.pl`として以下
```perl:test.pl
#!/usr/bin/perl -w #適当にshebang

my(@hikisu) = @ARGV ; #最初に引数を格納しておく

print "0: $hikisu[0]\n" ;
print "1: $hikisu[1]\n" ;
print "2: $hikisu[2]\n" ;

while (<STDIN>) {
    my($line) = $_ ;
    print $line ;
}
```

以前のはこちら
```perl:test.pl
#!/usr/bin/perl -w

my(@hikisu) = @ARGV ;
@ARGV = ('-'); #引数を受け取ったあとに標準入力に入れ替えている

print "0: $hikisu[0]\n" ;
print "1: $hikisu[1]\n" ;
print "2: $hikisu[2]\n" ;

#ここで<>を使用
while (<>) {
    my($line) = $_ ;
    print $line ;
}
```

と作成して、シェルで実行すると
```shell-session
$ echo "test" | perl -w test.pl 0 1 2
0: 0
1: 1
2: 2
test
```
こうなる。あとは標準出力からまたパイプで続けていけばよい。

### その2
もしくは`-s`を使ってもよさそう
```shell-session
$ perl -help
...
...
  -s                    enable rudimentary parsing for switches after programfile
...
...
```

```test2.pl
#!/usr/bin/perl -s

our($testVar);
while(<>){s/$testVar/___/;print;}
```
こんな感じで実行する
```shell-session
$ TESTVAR=sss | echo "aaa\nbbb\nsss\nccc\n" | perl -w test2.pl -testVar=$TESTVAR
aaa
bbb
___
ccc

$
```
参照：https://stackoverflow.com/questions/507387/how-can-i-parse-command-line-switches-in-perl How can I parse command-line switches in Perl?


## one-linerの場合

`-s`を使うとできた。

引数をうしろに`-var=...`などで指定できる。
one linerで使う時は、まず`--` でsh側の変数解析をキャンセルしておかないとだいたい変なことになる。

以下のように使う。
```shell-session
$ TESTVAR=sss | echo "aaa\nbbb\nsss\nccc\n" | perl -spe 's/$testVar/___/;' -- -testVar=$TESTVAR
aaa
bbb
___
ccc

$
```


参照：https://qiita.com/joemphilips/items/45060735942a36140ad9 [小ネタ]perlワンライナーにシェル変数を渡す
参照：https://qiita.com/ymko/items/9c7dd37a7b41d1e21e84 引数"--"(Double dash)のみとは何を意味するのか
初心者によるプログラミング学習ログ 222日目

#100日チャレンジの222日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

222日目は
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>222日目<br>・youtubeみながらjavascriptでtodolist作成<br>・Bootstrap使ってLP作成<br>・vue.jsでアプリ作成講座<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1221887590099369984?ref_src=twsrc%5Etfw">January 27, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
【React Native】変更後の値を送信する関数をnavigationOptionsから実行する


### やりたかったこと
NavigationStackScreenComponentで定義した値を送信する自作関数をnavigationOptionsで持たせているヘッダーから実行し、変更後の値を送信したかった。

### 解決した方法
初回レンダリング時だけでなく、textの値が変更される度にnavigation.setParamsをするようにした。

```
React.useEffect(() => {
  navigation.setParams({ onSubmit: onSubmit });
}, [text]);
```

### 詰まった箇所
MainScreenの初回レンダリング時にnavigation.setParamsで渡した関数をヘッダーのTextButtonで受け取って設定した。
textの値を（'Foo'）に変更して実行してもアラートに表示されるtextは（’Hoge’）から変更されずに困っていた。

```
import * as React from 'react';
import { Alert } from 'react-native';
import { NavigationStackScreenComponent } from 'react-navigation-stack';

const MainScreen: NavigationStackScreenComponent = ({ navigation }) => {
  const [text, setText] = React.useState<string>('Hoge');

  // 送信する
  const _onSubmit = async () => {
    Alert.alert('送信', text);
  };

  React.useEffect(() => {
    navigation.setParams({ onSubmit: onSubmit });
  }, []);

  return (
    <>
      ~~~
    </>
  );
};

MainScreen.navigationOptions = ({ navigation }) => ({
  headerTitle: 'Main',
  headerRight: <TextButton onPress={() => {
    navigation.getParam('onSubmit')();
  } />,
});
```
Dockerでlogを削除する、ログを溜めない方法

# 概要
こんにちは、はにおかさい([@haniokasai](https://twitter.com/haniokasai) )です。
自分のサーバーで容量が足りなくなってしまい、dockerのログをどかそうと思いました。
ログを消す・溜めない方法を調べました。

# 環境
- Ubuntu 18.04 on XFS
- docker
    - overlayfs on XFS
    - 19.03.5

# すでにあるログを削除
## 特定のコンテナのログを消す
コンテナ名（ID）を入力し、そのログパスを取得。そこに無を流し込めばログが消えます。

```bash
echo "" > $(docker inspect --format='{{.LogPath}}' コンテナ名orコンテナID)
```
## 全コンテナのログを消す
forでコンテナ名（ID）を回します。

```bash
#削除対象の確認
for CONTID in $(docker ps -qa); do echo $(docker inspect --format='{{.LogPath}}' $CONTID ); done
#実際の削除
for CONTID in $(docker ps -qa); do echo "" > $(docker inspect --format='{{.LogPath}}' $CONTID ); done
```

たまに、空白のコンテナidが入り込んで

```
bash: $(docker inspect --format='{{.LogPath}}' $CONTID ): ambiguous redirect
```
となりますが、無視して問題ありません（条件分けする理由もないだろう。）

# ログ溜めない方法
**新たなコンテナ**でログを溜めない方法は以下のものです。

はじめに、serviceを編集します。

```
vi /lib/systemd/system/docker.service
```

ExecStartを編集すればよい。
- max-fileは保管をする世代の数
- maz-sizeは最大サイズ
 
```
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --log-opt max-size=10m --log-opt max-file=1
```

こんなかんじ

```conf
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
BindsTo=containerd.service
After=network-online.target firewalld.service containerd.service
Wants=network-online.target
Requires=docker.socket

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --log-opt max-size=10m --log-opt max-file=1
ExecReload=/bin/kill -s HUP $MAINPID
(以下略）                        
```

systemctlとdockerをリロードします。

```bash
systemctl daemon-reload
systemctl reload docker
```


# Ref
https://stackoverflow.com/questions/42510002/how-to-clear-the-logs-properly-for-a-docker-container
https://www.unix.com/shell-programming-and-scripting/173276-how-loop-through-space-separated-values.html
DOMContentLoadedからturbolinks:loadへ変更

[Action Cableの設定でつまずいたこと](https://qiita.com/kazama0119/items/755e8ff6f77aafb830d7)でうまくいかない処理があったので、追記します。
ご指摘やアドバイスがありましたらコメントよろしくお願いします。

##行いたいこと
チャットアプリ機能を実装する際に私が参考にしてきた記事ではページ遷移はなく、トップページでチャットのみを行うような記事でした。

今回作成したかったものは、各ページからチャットルームにページ遷移を行いその中でチャットを行うというものです。


##できなかったこと
他のページからチャットページへ移動した後にチャットの送信ができなくなっているということでした。
(チャットページでリロードを行うとできました。)

結論から言いますと、以下の部分のコードが作動しないということでした。
1行目の`document.addEventListener 'DOMContentLoaded', ->`はページの
[こちら](https://noumenon-th.net/programming/2017/06/11/domcontentloaded/)で説明されているようにDOMツリーの構築が完了後に動き出すということだったため、1度処理されればページの遷移を行っても問題ないと思っていました。

```chatroom.coffee
document.addEventListener 'DOMContentLoaded', ->
  input = document.getElementById('chat_input') 
  data_user = input.getAttribute("data_user")
  data_room = input.getAttribute("data_room")
  button = document.getElementById('chat_button')
  button.addEventListener 'click', ->
    content = input.value
    App.chatroom.speak(content, data_user, data_room)
    input.value = ''
    return
  return
```

##解決方法

以下1行目のように`'DOMContentLoaded'`を`turbolinks:load`に変更することによって
DOMツリーの構築が完了後に動き出すということから、ページの読み込み時に処理をするように変わり解決しました。

また、遷移先のページで input に何も入っていない(chat_inputというidがない)状態だと`Uncaught TypeError: Cannot read property ' getAttribute' of undefined`というメッセージがコンソールに現れるのでif文で回避するようにしました。

```chatroom.coffee
document.addEventListener 'turbolinks:load', -> #修正部分
  input = document.getElementById('chat_input') 
  if input? #修正部分
    data_user = input.getAttribute("data_user")
    data_room = input.getAttribute("data_room")
    button = document.getElementById('chat_button')
    button.addEventListener 'click', ->
      content = input.value
      App.chatroom.speak(content, data_user, data_room)
      input.value = ''
      return
    return
```

##関連記事
・[Action Cableの設定でつまずいたこと](https://qiita.com/kazama0119/items/755e8ff6f77aafb830d7)
・[Action Cableへのidの受け渡し](https://qiita.com/kazama0119/items/02c5c3a354ba82399362)
Laravel で認証機能を実装する

# 概要
本記事では、ログインした時のみ表示させたい！という画面に認証機能をつけてあげる方法を記述します。

## 実際に書いてみる
認証機能、、うっ、、となってしまうかもしれませんが実はこれはとっても簡単で、認証機能をもたせたい画面のルーティングの記述を下のようにするだけです。

```php:web.php
Route::get('/', 'PiyoController@index')->middleware('auth');
```
これだけ。
上記を記述することによって、アクセスした際にログイン画面にリダイレクトされるかと思います。

## 解説
Laravelではあらかじめ'auth'というミドルウェアが準備されており、これだけの記述で済みます。
このミドルウェアについての記述は`app/Http/Kernel.php`にあります。
$routeMiddleware の先頭に`auth`があるのがわかると思います。(さらに深追いすることもできますが割愛します。)
![スクリーンショット 2020-01-28 19.55.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238466/bc427461-ee7c-753e-7ebd-0addae241d29.png)
MacOS CatalinaでUnityがインストールできなかったときに試したこと

## はじめに
初めてMacOSにふれた時にUnityのインストールでつまづいた話です。
もし同じような方がいましたら参考にしていただければ。
## 環境
MacOS Catalina ver 10.15.2
UnityHub ver 2.2.2
## 問題
UnityHubからUnityEditorをインストールしようとすると...
<img width="789" alt="スクリーンショット 2020-01-28 18.59.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534178/c72ff5f4-54cd-6df2-d460-c55c3ba62495.png">
最初の画面に戻る。
<img width="789" alt="スクリーンショット 2020-01-28 18.48.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534178/73779d2d-ebf3-8505-7749-cf821d350842.png">
***
UnityHubを経由せず直接インストーラからインストールしてもエラーがでて出来ませんでした。
https://answers.unity.com/questions/1676587/unity-installer-installer-cant-install-unity3d-on.html
## 試したこと
1 OSのアップデート
MacOSのバージョンを更新しました。
初めて起動した時は最新のものにしておきましょう。
<img width="662" alt="スクリーンショット 2020-01-28 19.38.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534178/04501a61-a133-f00c-1c44-a1533e9e9404.png">
2 再起動
再起動です。

3 UnityHubの再インストール
自分はこれで解決しました。
Macではソフトを完全にアンインストールするために[AppCleaner](https://freemacsoft.net/appcleaner/)というソフトを使います。
このとき、UnityHubを**アプリケーションフォルダ**に移します
MacOSではソフトはアプリケーションフォルダに入ってないと動きません。
また、[マウント](https://kotobank.jp/word/%E3%83%9E%E3%82%A6%E3%83%B3%E3%83%88-8977)されたものでなくソフト本体を入れます。
<img width="456" alt="スクリーンショット 2020-01-28 19.05.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534178/d92d10ea-7951-d927-2b2c-d3e62828c8a9.png">
## おわりに
とても初歩的なことでしたが少しずつ慣れていきます。
間違い等あればご指摘くださいませ。
【初心者】Java　練習問題後の気を付ける点／継承／抽象メソッド【備忘録２６】

##Java練習（オブジェクト指向）
###カプセル化
「private」でインスタンスフィールドを書いた際に
ゲッターで書き漏れる事があり、エラーが発生したので
癖づけて書くように気を付ける。

###printData
・指示がなくても、自分から出力用のインスタンスメソッドを
書けるようにする。誰が見ても見やすい書き方を心がけていきたい。

・privateで書いた後、Main.javaで出力するのではなく
printDataで出力をまとめる場合は、同じクラス内なので、getNameなどでなく
this.nameなどで書くと、簡潔に書けるので覚えておく。

##Java学習
###継承
今までの演習で２つのクラスを使って進めたりしていたが
クラス内でコードの重複するところがあった。
修正・改善がしにくくなってしまうので重複は避けるべき。

その際、１つのクラスの内容を引き継ぐ方法がとれる。
これを継承という。

元になるクラスを「スーパークラス」と呼び
継承される側のクラスを「サブクラス」と呼ぶ。

###継承する方法
サブクラスにて、初めに定義する際に

```java
class サブクラス名 extends スーパークラス名{...
```

というような形で書く。

```java
class Vehicle{
 ...
 public void setName(String name){...
 }
 public void setColor(String color){...
 }
}

//Main.javaにて
class Main{
 public static void main(String[]args){
  Car car = new Car();
  car.setName("フェラーリ");
  car.setColor("赤");
...
}
}
```

実際にメソッドを呼び出す際などは上記のようにして書く。(一例)

###サブクラスをカスタマイズする
今までで使用していたCarクラスの燃料部分(fuel)は他のクラスにはない
独自の物なので、Carクラスにてカスタマイズを行わなければならない。

```java
class Car extends Vehicle{
 private int fuel = 50;
 public int getFuel(){
  return this.fuel;
 }
```

実際に呼び出す際はcar.getFuel();で呼び出す。
(vehicle.getFuel();ではエラーが出る)

###super()
スーパークラスのコンストラクタをサブクラスで呼び出す方法
【例１】

```java
//スーパークラス
class Vehicle{
 Vehicle(){
  System.out.println("スーパークラスです");
 }

//Carクラス
class Car extends Vehicle{
 Car(){
 super();
 }
}

//Mainクラス
class Main{
 public static void main(String[]args){
  Car car = new Car();
  ...
 }
}
```
上記で、出力は「スーパークラスです」となる。
【例２】

```java
//スーパークラスにて、まずコンストラクタを定義。
class Vehicle{
 private String name; ...

 Vehicle(String name,String color){
  this.name = name;
  this.color = color;
 }

//Carクラスのコンストラクタ／スーパークラスのコンストラクタを呼び出す
class Car extends Vehicle{
 Car(String name,String color){
  super(name,color); //引数を渡し忘れないようにする。
 }
}
```

###protected
スーパークラス、サブクラスを使う際
今までと同じようにprivateを使っているフィールドに関しては
サブクラスからのアクセスがそのままでは出来ない。
ゲッター・セッターを使っていたが、[protected]を用いると
サブクラスとクラス内からのアクセスが可能になる。

・public　　→どこからでもアクセス可能
・private　 →そのクラスからのみアクセス可能
・protected →そのクラスとサブクラスからアクセス可能

###抽象メソッド
今まで、乗り物のスーパークラスで車や自転車のサブクラスを
まとめていたが、中身がそれぞれ違う(例えばrunクラス)メソッドがある際は
抽象メソッドを使う。

```java
class Vehicle{ ..
 abstract public void run(int distance);
//ここで抽象メソッドを定義する。そのあとの処理は書かない！

```

その後、各サブクラスで、上書き必須。
※抽象メソッドを持つクラスは「抽象クラス」となるため
クラス名の前に「abstract」を付ける必要がある。

##今後
抽象メソッドなど実際に書いていないので、理解が浅い気がする。
一度Javaの総復習をして、ページとして作れたらと思います。
諸事情でPHPも早急に触った方が良い状況なので、その前にPHPの学習に一度移る。
tag-itでタグの文字数チェック・カンマ「,」区切りの文字列から自動で分割させたい

タグ入力プラグインのtag-itを利用して、
カンマ「,」区切りの文字列を入力フォームに入れたときに
自動でタグを分割するようにしました。
また、タグは最大10個までで1つのタグの文字数は100文字の制限を付けました。

※jQueryを使っています
※前提としてnpmで必要なパッケージをインストールしています

```js
/**
 * タグの入力フォームをコントロールする
 * @return なし
 */
$(function() {
  const $tagFrom = $('#tagForm');
  $tagFrom.tagit({
    tagLimit: 10, //タグの最大個数
    placeholderText: 'タグを追加してください',
    preprocessTag: function (val) {
      if (!val) {
        return '';
      }
      // 文字列を分割してタグ表示
      const tagList = val.split(',');
      if (tagList.length > 1) {
        for (let tagKey in tagList) {
          let tagValue = tagList[tagKey];
          // 100文字以上のタグは削除
          if (tagValue.length <= 100) {
            $tagFrom.tagit('createTag', tagValue);
          }
        }
        return '';
      } else {
        // 100文字以上のタグは削除
        if (val.length <= 100) {
          return val;
        } else {
          return '';
        }
      }
    }
  });
});
```

HTMLは以下の通り

```
<input type="text" id="tagForm" />
```

必要なnpmパッケージ（バージョンは現在最新）

```
    "jquery-tagit": "^1.0.1",
    "jquery-ui": "^1.12.1",
    "tag-it": "^2.0.0"
```
参考文献：
https://kotaeta.com/56812856
[初学者]simple calendarを日本語化 rails

#概要
表題の通り、simple calendarを日本語化します。
結論から言うと、今回　**i18n**　という英語を日本語に変えるgemを使用します。

恐らく、私を含め初学者はsimple calendarを日本語にする時に
i18nが紐づいてでてきにくいのではないかと思い記事にしました。
（実際、私はこれを機に初めてi18nというgemを初めて知りました。）


###完成イメージ
<img width="630" alt="スクリーンショット 2020-01-28 19.42.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504349/254793e1-d28c-90b6-c6b2-4095b669d3a8.png">
曜日が英語表記だったのが日本語表記に！
###目的
- i18nの理解
- simplecalendarの日本語化

#環境
- ruby 2.5.6
- rails 5.2.3

#前提
- simple calendarを導入済とする。
（導入方法は[こちら](https://qiita.com/mikaku/items/0971442a7308dc669122)）
[公式サイト](https://github.com/excid3/simple_calendar)

#i18nの導入
こちらの記事↓の３（18nの複数ロケールファイルが読み込まれるようpathを通す）まですすめてください。
[[初学者]Railsのi18nによる日本語化対応](https://qiita.com/shimadama/items/7e5c3d75c9a9f51abdd5)

#2つのファイル作成

**app/config/locales**に下記のように２つのファイルを作成します。
1.ja.yml
2.model.ja.yml
<img width="173" alt="スクリーンショット 2020-01-28 15.39.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504349/964d6d51-9891-4b87-d96a-2c158cc5ff83.png">



#ファイルの内容

```app/config/locales/ja.yml
---
ja:
  date:
    abbr_day_names:
      - 日
      - 月
      - 火
      - 水
      - 木
      - 金
      - 土
    abbr_month_names:
      -
      - 1月
      - 2月
      - 3月
      - 4月
      - 5月
      - 6月
      - 7月
      - 8月
      - 9月
      - 10月
      - 11月
      - 12月
    day_names:
      - 日曜日
      - 月曜日
      - 火曜日
      - 水曜日
      - 木曜日
      - 金曜日
      - 土曜日
    formats:
      default: "%Y/%m/%d"
      long: "%Y年%m月%d日(%a)"
      short: "%m/%d"
    month_names:
      -
      - 1月
      - 2月
      - 3月
      - 4月
      - 5月
      - 6月
      - 7月
      - 8月
      - 9月
      - 10月
      - 11月
      - 12月

  time:
    am: 午前
    formats:
      default: "%Y年%m月%d日(%a) %H時%M分%S秒 %z"
      long: "%Y/%m/%d %H:%M"
      short: "%m/%d %H:%M"
    pm: 午後

```


このように辞書みたいに登録された英語が日本になります。

```app/config/locales/model.ja.yml
ja:
  activerecord:
    models:
      user: ユーザー # view側： User.model_name.human => "ユーザ" / t("activerecord.models.user")と同じ
      board: 掲示板
    attributes:
      user:
        id: ID
        first_name: 名前 # view側： User.human_attribute_name :name => "名前" /　t("activerecord.attributes.user.name")と同じ
        last_name: 姓
        email: メールアドレス
        file: プロフィール画像
        crypted_password: パスワード
        created_at: 作成日
        updated_at: 更新日

```
これでカレンダーが日本語表記になりました！！



#最後に
railsでのシンプルカレンダーを調べると関連記事が少なく感じました。
特に導入時の記事はあるもののカスタマイズの記事が少ないです。
なので、これからカスタマイズ編も記事にしていけたらと思います。

まだまだ勉強不足なところがありますので、
アップデートできた知識は追加で記載していきます。

もし、何か修正点とかございましたらコメント等
恐縮ですが、宜しくおねがいします。
Elasticsearchコンテナを起動しても、数秒後には【Exit 78】で停止状態になる

#はじめに
※修正などがあればコメント欄に書いていただけると嬉しいです！

# 症状

DockerでElasticsearchを起動しても、落ちるため`No alive nodes found in your cluster`が出てElasticsearchとつなげることができなかった。

```
// 起動
$ docker-compose up -d elasticsearch

// 確認
$ docker ps -a
CONTAINER ID        IMAGE           COMMAND                  CREATED             STATUS              PORTS                      NAMES
xxxxxxxxx        elasticsearch   "/usr/local/bin/dock…"      5secounds        Up 5secounds         0.0.0.0:9200->9200/tcp       elasticsearch_1

// ログを確認
$ docker-compose logs elasticsearch

// エラー箇所（部分抽出）
[1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

```


#原因

単に、「elasticsearchのプロセスが使用するメモリが[65530]だと少なすぎるから[262144]まで増やしなさい！」と怒っている...

```
[1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
```

#解消法

```
// メモリマップ領域の増加
sudo sysctl -w vm.max_map_count=262144
```

これで動くはず！ぜひお試しあれ！ (*´∀`)♪


#参考
このissueがかなり参考になりました。ありがとうございます！
https://github.com/laradock/laradock/issues/1699
Android C/C++ でアクセスできるストレージのメモ

## 背景

主に開発時に, Android + C/C++ で fopen, std::ifstream などで実機上のファイルの読み書きをしたい.

SDK level 28 でコンパイルし, Android 10(Pixel4) で確認しています.

## `/sdcard`, `/storage/emulated/0`

Android M から, `/sdcard` へは Toast などでユーザから同意取得(or Android 設定で対応)になりました.
Permission を取得していればアクセスできます.

https://stackoverflow.com/questions/33162152/storage-permission-error-in-marshmallow

JAVA でいくらかコード記述を書く必要があります.

開発時であれば, adb で設定することもできます.

https://github.com/TilesOrganization/support/wiki/How-to-use-ADB-to-grant-permissions
https://stackoverflow.com/questions/46658643/android-grant-permissions-through-adb

PC(ホスト)でこの領域にあるファイルをやりとりするには, adb push/pull を使います(adb sync も使えるはず)

## `/data/local/tmp`

permission 不要で読み書きできました.

PC(ホスト)でこの領域にあるファイルをやりとりするには, adb push/pull を使います(adb sync も使えるはず)

adb shell ではそのままではファイルは ls で出てこないので注意です
ファイル容量に制限があるかもしれません.

## `/data/user/0/com.example.yourapp`(アプリ固有ストレージ)

`/data/user/0/<appid>` も permission 不要で読み書きできました.
(`/user/0` はマルチユーザを考慮したパスなので, `/data/data/<appid>` でもアクセスできるはず)

PC(ホスト)でこの領域にあるファイルをやりとりするには, いったん `adb shell run-as com.example.yourapp cp ...` で /sdcard or /data/local/tmp を介してファイル転送をする必要があります.

`adb exec-out run-as ...` で, アプリ固有フォルダから PC 上の stdout に読み出しはできます. 

https://qiita.com/misoca12/items/644b6cb02e1168718e58

`adb exec-in run-as` は exec-in と run-as を組み合わせることができませんでしたのでダメでした.

ファイル容量に制限があるかもしれません.


## APK の asset folder(読み込みのみ)

https://stackoverflow.com/questions/13317387/how-to-get-file-in-assets-from-android-ndk

AAssetManager を使います. Android の構造上しかたがないですがめんどいですね...
コンテキストは JNI あたりを介して Java のレイヤーから取得する必要があります.

基本的にはシェーダファイルや, アプリからしか読めないファイルを置く場所です.

加筆: 優秀な Android 開発若人さまから, fopen, fread をエミュレートする方法をお教えいただきました. ありがとうございます. 詳細はコメントを参照ください. 

## 相対パス

`fopen("muda")`, `fopen("./muda")` のようなファイルパスは(storage permission を取得したとしても)アクセス不可でした.

## Android 10 以降

https://github.com/termux/termux-packages/wiki/Termux-and-Android-10

実行権限などに制限があります. いずれ `/data/local/tmp` の読み書きも制限されてしまうかもしれません...

## まとめ

デバッグ用にちょっとしたファイルを読み書きしたいのであれば, `/data/local/tmp` を使うのがよいと思われます.
GolangでAPI使ってSMS送信

##SMSとは
ショートメッセージサービスですね。
二段階認証や本人確認などで最近よく使われます。


```Go
package main

import (
	"net/http"
	"net/url"
	"log"
	"fmt"
)

func main(){
	value := url.Values{}
	value.Set("from","Nexmo")
	value.Add("text","Hello from Nexmo dayoneeee")
	value.Add("to",TO_NUMBER)
	value.Add("api_key",API_KEY)
	value.Add("api_secret",API_SECRET)
	resp, err := http.PostForm("https://rest.nexmo.com/sms/json",value)
	if err != nil{
		log.Fatal(err)
	}
	buffer := make([]byte,1024)
	respLen,_ := resp.Body.Read(buffer)
	body := string(buffer[:respLen])
	fmt.Println(body)
	fmt.Println(resp.Status)
	defer resp.Body.Close()
}
```
今回使ったAPIは特にエンコーディングする必要はなかったので
PostFormを使ってリクエストを作成しました。
API_KEYとFrom,Toが必須となっており、
URLのjsonをxmlなどに変えるとレスポンスで指定したものが返ってきます。

##おしまい
curlを使うとこんな感じだよというサンプルもあるので分かりやすかった。
詳しくはここに書いてある。[Nexmo](https://developer.nexmo.com/api/sms)

```cmd
curl -X "POST" "https://rest.nexmo.com/sms/json" \
  -d "from=AcmeInc" \
  -d "text=A text message sent using the Nexmo SMS API" \
  -d "to=$TO_NUMBER" \
  -d "api_key=$NEXMO_API_KEY" \
  -d "api_secret=$NEXMO_API_SECRET"
```
【nuxt】middlewareについて

# 概要
- ページを表示する前に色々チェックできる
- 外部JSに定義できるので、チェックロジックを共通化しやすい
  - ページ固有のロジックとして持たせる書き方も可能 

# middlewareを設定する
## `/middleware` 配下にJSファイルを作る

```js:sampleMiddleware.js
export default function (context) {
 // do something
}
```

## ページまたはレイアウトファイルに下記のような一文を追加

```js:page.vue

export default {
  middleware: 'sampleMiddleware'
}
```

配列で指定すれば、複数指定も可能

```js:page.vue

export default {
  middleware: ['sampleMiddleware', 'checkUser']
}
```

# 基本
> ミドルウェアは第一引数として コンテキスト を受け取ります

とある通り、第一引数にいろんな情報が入ったオブジェクトが入っている。

```js
export default function (context) {
 console.log(context) // { store:..., params..., }
}
```

基本的にはcontextを使わず、引数の分割代入を使って、必要なデータだけを受け取って使う。

```js
export default function ({ store, params }) {
  const id = params.id
  const data = store.dispatch(...)
}
```

# ユースケース
## vuexのstoreを使いたい
storeに入っている。

```js
export default function ({ store }) {
  const data = store.dispatch(...)
}
```

## ルーティング情報を使いたい（$route.params）
paramsに入っている。

```js
export default function ({ params }) {
  const id = params.id
}
```

## リダイレクトしたい
redirectというメソッドが用意されている。

このメソッドを何らかのアラートを出した後のコールバック関数として使うこともできるが、
その場合、ページ側のロジックも実行されてしまう。
リダイレクトは即座に実行し、アラートは表示するだけ（OKを押したら閉じるのみ）にした方がよさそうである。

```js
// 問答無用でログイン画面に飛ばす悪のコード
export default function ({ redirect }) {
  return redirect('/login')
}
```

## async await 使いたい
async functionにすればOK

```js
import dataApi from 'dataApi'

export default async function ({store, params, redirect}) {
  try {
    const res = await dataApi.get(params.id)
    ...

  } catch(e) {
    ...
  }
}
```

## export defaultに直接処理を書かず、別途定義したい
変数名はファイル名と違うものにする必要あり。export方法を間違えてもエラーとなる。

```js
const check = ({store, params, redirect}) => {
  const offerId = params.id
  ...
}

export default check
```

こう書くとうまく行かない。unknown middlewareエラーになる。
なお、この書き方で変数名をファイル名と揃えた場合、 already defined エラーになる

```js
// unknown middlewareエラー or already defined エラーになる
export default {
  check
}
```

# ドキュメント
- [ルーティング#ミドルウェア](https://ja.nuxtjs.org/guide/routing/#%E3%83%9F%E3%83%89%E3%83%AB%E3%82%A6%E3%82%A7%E3%82%A2)
- [API: middleware プロパティ](https://ja.nuxtjs.org/api/pages-middleware/)
pcl_rosを使ってrosbag->pcdファイル変換 → 大量のpcdファイルが作成されてしまったのでpcd結合パッケージを作成

# 動機

rosbagにより記録した`PointCloud2`をpcdファイルに保存したい！
↓
pcl_rosならrosbag→pcdの変換が直接できるらしい(参考：[[ROS] sensor_msgs::PointCloud2をpcdファイルで入出力するときのメモ](https://qiita.com/kenichi-hamaguchi/items/23b5777118824d578fe4))
↓
やってみる
↓
ひとつのbagファイルから大量のpcdファイルが生成
↓
楽しくない…

そこで，pcd結合パッケージを作ってみました．
GitHub: [join_pcd](https://github.com/kazuki21057/join_pcd)

本記事では，pcl_rosによるbag->pcd変換方法と，作成したパッケージの概要および使い方を紹介します．

# pcl_rosを使用したrosbag→pcd変換方法

まずはpcl_rosを使用して，bagファイルをpcdファイルに直接変換します．使用するツールはpcl_rosの`bag_to_pcd`です．
使い方は下記．

```
$ rosrun pcl_ros bag_to_pcd <input file>.bag <topic name of PointCloud2> <output directory path> [<target frame >]
```

例えば，カレントディレクトリ内にある`hoge.bag`から`/points`トピックをpcdファイルに変換するときは次のようになります．

```
$ rosrun pcl_ros bag_to_pcd hoge.bag /points .
```

上記の方法でpcdファイルは作成できたのですが，なぜか出力ファイルが1つではなく，大量に生成されてしまいました．（サイズが0のトピックが来るとendだと認識されてしまうのかもしれません）

# pcd結合パッケージ作成

細切れpcdファイルを大量に所有していても何も楽しくないので，pcdパッケージを結合するパッケージを作ってみました．（リポジトリは[こちら](https://github.com/kazuki21057/join_pcd)）

本記事では，簡単なパッケージ概要と使い方を紹介します．

## パッケージ概要

作成したパッケージは，指定ディレクトリ内の指定pcdファイルを結合し，同じディレクトリに出力するだけのパッケージです．
pcdの読み込みおよび結合は[ここ](http://virtuemarket-lab.blogspot.com/2015/02/blog-post_25.html)を参考にしました．

動作環境としては，次の2点さえ合致していれば問題ないと思います．
- OS: Ubuntu
- C++11以上

## 使い方

### インストール方法

clone & make のみです．

```
$ git clone https://github.com/kazuki21057/join_pcd.git
$ cd join_pcd
$ mkdir build 
$ cd build
$ cmake ..
$ make
```

### 使い方

join_pcdがあるディレクトリパスを`JOIN_PCD_PATH`としたとき，下記コマンドで使用できます．

```
$ JOIN_PCD_PATH/build/join_pcd -i <input file name 1> <input file name 2> ... -o <output file name>
```

指定キーワード（`-i`, `-o`）の後に，それぞれの情報を入力します．
引数の指定順番はバラバラで問題ありません．また、パス指定は絶対/相対どちらでも可能です。  
指定キーワードの説明は下記．

- -i: 結合したいpcdファイル名
    - 拡張子の有無は関係ありません．
    - ”\*”または”\*.pcd”を指定した場合は，指定ディレクトリ内にあるすべてのpcdファイルを入力とします．
- -o: 結合後の出力pcdファイル名
    - 拡張子の有無は関係ありません．
    
たとえば，カレントディレクトリ内にある`a.pcd`, `b.pcd`を結合し，`c.pcd`を作成したい場合は次のようになります．

```
$ JOIN_PCD_PATH/build/join_pcd -i a.pcd b.pcd -o c.pcd
```

また，今回のように大量にpcdファイルが生成されてしまった場合，ディレクトリ内にある全てのpcdファイルを結合するには次のようにします．

```
$ JOIN_PCD_PATH/build/join_pcd -i * -o c.pcd
```

# まとめ

pcd結合よりもC++でファイル操作するほうが面倒でした．[pythonでもpcl使えるっぽい](https://github.com/strawlab/python-pcl)し，pythonで実装すればよかったかもです．

# 参考

- [[ROS] sensor_msgs::PointCloud2をpcdファイルで入出力するときのメモ](https://qiita.com/kenichi-hamaguchi/items/23b5777118824d578fe4)
- [２つの点郡データを１つに統合する](http://virtuemarket-lab.blogspot.com/2015/02/blog-post_25.html)
android で puredata を利用する

#pd-for-android
公式のinstall手順に沿ってインストールします。

[pd-for-android](https://github.com/libpd/pd-for-android)のgithubからリポジトリをCloneします。



```
1. Clone this repository
2. Go to the repository folder: cd pd-for-android
3. Initialize and update the git submodules: git submodule update --init --recursive
4. Assemble the release: ./gradlew PdCore:assembleRelease (Note: Windows users should run gradlew)
5. Now you have your PdCore .aar file in the folder PdCore/build/outputs/aar
```

無事、aarファイルが作成できましたら、Android Studioのプロジェクトを立ち上げ、aarファイルをimportします。
`File > New Import Module`でaarファイルを指定してください。

最後に、Project Structureでaarファイルのバージョンに合わせて指定すれば完了です。

```
dependencies {
    compile(name:'pd-core-*.*.*-SNAPSHOT', ext:'aar')
}
```


##考えられるエラー

> Warning: License for package Android SDK Platform ** not accepted.

Android SDKのバージョンが古いと `git submodules: git submodule update --init --recursive` のときにpackege Liceseがないと言われます。
Android Studioを立ち上げて、必要とするAndroid SDKをInstallしましょう。
Unity/PUN2 による RequestOwnership() で OnOwnershipRequest コールバックが呼ばれない！？ときにチェックすること

## 悩んでいたこと

タイトルの通り。
Unity/PUN2(Photon)によるリアルタイム通信を実装していて、ネットワークオブジェクトの所有権の操作をしていました。

PUN2で始めるオンラインゲーム開発入門【その５】
https://connect.unity.com/p/pun2deshi-meruonraingemukai-fa-ru-men-sono5

PhotonView.RequestOwnership()すればいいよ、ということはわかったのですが、どうしてもコールバックの OnOwnershipRequest() が呼ばれずに悩んでいました。

## 何が原因だったか
これを書いていませんでした。。。
`PhotonNetwork.AddCallbackTarget(this);`
IPunOwnershipCallbacks を実装したオブジェクトをコールバックに登録するコードを書く必要がありました。。。

これ、API リファレンス以外のところに書かれてなくない！？
（公式のチュートリアルにすら書いてない）

このフォーラムの投稿から見つけました。。。

PUN v2 Ownership Callbacks
https://forum.photonengine.com/discussion/13494/pun-v2-ownership-callbacks

同じことで悩んでいる人が１分でも早く解決にたどり着けるよう、記事にしておこうと思い立った次第です。

## まとめ - OnOwnershipRequest コールバックを使いたい場合のネットワークオブジェクトの所有権移譲の実装方法

1. 権限移譲の対象にしたいネットワークオブジェクトの PhotonView の所有権オプションを Request にする。
2. IPunOwnershipCallbacks インターフェースを実装したスクリプトを作り、OnOwnershipRequest, OnOwnershipTransfer コールバックを実装する
3. そのオブジェクトを Photon のコールバックに登録するため、`PhotonNetwork.AddCallbackTarget(this)`する。そのスクリプトが MonoBehaviour を継承しているなら、OnEnable() でやるのが吉。（this は IPunOwnershipCallbacks を実装したオブジェクト）
4. そのスクリプトをゲームオブジェクトにアタッチする。（使いたいシーンで）
5. 所有権を要求したいタイミングで、そのオブジェクトの PhotonView.RequestOwnership() を呼ぶ。


ちなみに、コールバック登録を解除したい場合は`PhotonNetwork.RemoveCallbackTarget(this)`です。MonoBehaviour なら OnDisable() で。

### 参考
こういうスクリプトを書いてゲームオブジェクトにアタッチしておくと動きます。

```CSharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;

public class PunCallback : MonoBehaviour, IPunOwnershipCallbacks
{
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

    }

    void OnEnable() {
        PhotonNetwork.AddCallbackTarget(this);
    }

    void OnDisable() {
        PhotonNetwork.RemoveCallbackTarget(this);
    }

    // 所有権のリクエストが行われた時に呼ばれるコールバック
    void IPunOwnershipCallbacks.OnOwnershipRequest(PhotonView targetView, Player requestingPlayer)
    {
        // 自身が所有権を持つインスタンスで所有権のリクエストが行われたら、常に許可して所有権を移譲する
        if (targetView.IsMine)
        {
            bool acceptsRequest = true;
            if (acceptsRequest)
            {
                targetView.TransferOwnership(requestingPlayer);
            }
            else
            {
                // リクエストを拒否する場合は、何もしない
            }
        }
    }

    // 所有権の移譲が行われた時に呼ばれるコールバック
    void IPunOwnershipCallbacks.OnOwnershipTransfered(PhotonView targetView, Player previousOwner)
    {
        string id = targetView.ViewID.ToString();
        string p1 = previousOwner.NickName;
        string p2 = targetView.Owner.NickName;
        Debug.Log($"ViewID {id} の所有権が {p1} から {p2} に移譲されました");
    }
}
```
Q20.ユーザーフォームを利用するには？

今回はユーザーフォームの利用について取り扱って行きます。

ユーザフォームとは自分でオリジナルのGUIをデザインして作成できる機能です。
実際に使ってみないとぴんとこないと思うので、これから徐々に取り上げていこうと思います。

今回は手始めに、ラベルを配置して、お決まりの"Hello World"を表示させてみます。



では、早速ユーザーフォームを使ってみましょう。
いつもどおりVBEを開いたら、下記のように挿入からユーザーフォームを選択します。

![Q20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/13d25655-5a49-1c21-14b0-46863af01cc3.png)


すると、ユーザーフォームを編集する画面が出力されます。


![Q20-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/1a42c497-d0dd-f89d-c0f5-9858a9b78058.png)



ツールボックスにいろいろなパーツがあるのが分かりますね。
これらのパーツを組み合わせたり、コードを組んだりしながら、
ユーザーフォームを作っていきます。


今回は、ラベルという部品を使って、マクロからラベルの値を変更するというものを
作っていきましょう。


以下のようにラベルを選択して、ユーザーフォームに配置していきます。

![Q20-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/a2f98d3b-f258-db69-b39a-7c7e7f7cca23.png)



あとは、マクロからラベルの値を変更して、ユーザーフォームを呼び出します。
モジュールにマクロを記述していきます。



###■回答
```VB
Sub Q20_Answer()
    UserForm1.Label1.Caption = "Hello World"
    UserForm1.Show
End Sub
```


###■解説
ラベルに表示する文字列を変更するには、Captionプロパティに値を入れる必要があります。
今回はHelloWorldを入れています。

そして、ユーザーフォームを表示するには.showというメソッドから呼び出します。

マクロを実行した結果は以下の通りです。

![Q20-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/76c2fb53-d7a3-f740-1277-0703b7aa8c7b.png)



無事、ユーザーフォームを表示させることができました。
プロパティをいじれば、文字の色や大きさなどいろいろ変えることができます。
【Heroku】NuxtプロジェクトをHerokuでデプロイするだけの話

作ったNuxtアプリケーションをHerokuでデプロイしてみた

## デプロイ方法
heroku-cliを導入する

```
$ brew install heroku/brew/heroku
```

Herokuにログインする

```
$ heroku login
```


ログイン用のブラウザが立ち上がります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544264/deb9948b-2fea-83a6-8836-1fbe858bdc9c.png)


package.jsonやnuxt.config.jsと同じ階層に`Procfile`を作成

```
$ touch Procfile
```

```:Procfile
web: npm start
```

>Procfileとは
>Herokuのプラットフォーム上にあるWebアプリがどのようなコマンドで実行されるのかを記述するファイルのこと。Webアプリを動かす指示書みたいなやつ。

masterブランチの場合はmasterにpushする

```
$ git push heroku master
```

master以外のブランチの場合はmasterにpushされるようにする
(sampleブランチをmasterにpushする場合)

```
$ git push heroku sample:master
```

URLが発行されるので、そこにアクセスすればOK
Vagrant 起動～仮想マシンに接続～Networkmanagerまで

# 備忘録である
こんにちは！初めまして！いらっしゃいませ。
今記事は、プログラム学習中、エンジニア初心者向け（著者自身。。。)に、備忘録として残します。参考になれば幸甚至極！

##環境
- windows10
- virtulbox6.0.16
- vagrant2.2.6
- Centos7


##目的
- [ ] vagrantの起動からindex.htmlの表示までのおさらい。
- [ ] Networkmanagerをインストールしてnmcliコマンドを使えるようにする。

#開始
- httpdのインストール
- 
```
vagrant ssh
sudo yum -y install httpd
sudo service httpd start
sudo chkconfig httpd on
sudo systemctl stop firewalld
```
これで、下拵え完了。
続いて、index.htmlを表示する。

```
cd /var/www/html
sudo vi index.html
cat index.html
vagrant reload
```
1. viでhtmlファイルの編集をする。時に、Hello htmlを表示させる。
viエディタの使いかたは、
＠pe-ta様の投稿が詳しい→[Link](https://qiita.com/pe-ta/items/0510bee10bcfd88afeee"Link")
2. ```cat index.html ```で、編集内容を確認できる。
3. vagrant reloadをし、完了したらブラウザに192.168.33.10と打って、Hello htmlとでたらOK!!

- Networkmanagerのインストール
-
nmcliコマンドを使用するために必要になる。
```vagrant ssh
sudo yum -y install Networkmanager```
Networkmanagerのインストールが完了したら、起動させていく。

```
　# systemctl start NetworkManager
  # systemctl enable NetworkManager
  # systemctl is-active NetworkManager
```
三つ目がactiveとなればOK!
これで、nmcliコマンドが使える。このコマンドでdeviceの設定などが可能になる。powershellではなくPuTTyなどのツールで仮想サーバーをつなげたい時は、nmcliコマンドで設定が要る。その方法はQiitaにもいくつか記事が投稿されているのでそちらをどうぞ♪

###後記
さくっとおさらいをしてみました。ドットインストールで開発環境を揃えた方は、OSをバージョンアップしたりすると、このあたりは自分でやらないといけないので苦労されるはず。。。開発環境の準備だけで挫折してしまいそうですが、慣れてしまうと楽しいです。最後までご覧頂き、ありがとうございました。
シンボリックリンクでJenkinsのworkspaceパスを変更する

## はじめに

以前のJenkinsでは`[Jenkinsの管理]->[システムの設定]->[高度な設定]->[ワークスペース・ルートディレクトリ]`という設定があったみたいなのですが、ver. 2.204.1では確認できなかったためシンボリックリンクで対応をしました。簡単に書き残したいと思います。

参考: [Jenkinsで容量が圧迫されるときの対処法 - Qiita](https://qiita.com/kuro123/items/bfb1bc699ecba0aa2406)

## 環境

- Windows 10 Home
- Jenkins: ver. 2.204.1

## 手順


作業中は念のためJenkinsを停止しておいた方が良いと思います。Jenkinsをmsi経由でインストールした場合はウィンドウズメニューから「サービス」を検索し、Jenkinsを停止してください。

![aaaaaaキャプチャ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55365/201bac95-5c79-345b-76ee-193e0b39e0e7.png)

次に、既存のワークスペースを置き換えるため、フォルダの削除もしくはファイル名の変更を行っておいてください。

ではシンボリックリンクを作成していきます。Jenkinsのデフォルトでシステムディレクトリ上に作成されていると思うので、管理者権限でコマンドプロンプトを起動してください。`mklink`というコマンドを使います。

```.bat
> C:\WINDOWS\system32>mklink
シンボリック リンクを作成します。

MKLINK [[/D] | [/H] | [/J]] リンク ターゲット

        /D          ディレクトリのシンボリック リンクを作成します。既定では、
                    ファイルのシンボリック リンクが作成されます。
        /H          シンボリック リンクではなく、ハード リンクを作成します。
        /J          ディレクトリ ジャンクションを作成します。
        リンク      新しいシンボリック リンク名を指定します。
        ターゲット  新しいリンクが参照するパス (相対または絶対)
                    を指定します。

C:\WINDOWS\system32>mklink /D "C:\Program Files (x86)\Jenkins\workspace" E:\Jenkins\workspace
```

構文に従って新しいworkspaceのパスを指定してください。無事作成されるとショートカットと同じアイコンが表示されます。（ショートカットとは異なります）

![fasdfasdfasdfasd.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55365/ed6c023b-2416-8e96-abf4-9b7307098a87.png)

参考: [Windowsでシンボリックリンクを作る ｜ Developers.IO](https://dev.classmethod.jp/etc/make_windows_symbolic_link/)

あとは先ほどのサービスからJenkinsを起動してあげると今までと同じように実行できることが確認できると思います。

## 最後に

環境変数で変更する方法などもありますが、この方法だと動かなくなるリスクが少なくて良いと思いました（感想）
ローカルサーバの立ち上げについて

#目的
macのlocalhostで作成したファイルにアクセス

#環境
macOS Mojave 10.14.6

#Apacheの起動と停止
ローカルサーバの起動と停止と再起動

```ruby:ターミナル
$ sudo apachectl start         #起動
$ sudo apachectl stop          #停止　
$ sudo apachectl restart       #再起動
```
Apacheを起動して`http://localhost/`をブラウザで開き、**It works!**と表示されていれば起動しています。もしくは、ターミナルで

```ruby:ターミナル
$ ps aux | grep httpd
```

```ruby:ターミナル
*********    19999   0.0  0.0  4487512    864 s002  S+   12:36AM   0:00.01 grep httpd
```

こんな風になっていたら停止状態で、これ以外に色々出ていたら起動状態


#ユーザーのディレクトリを有効にする
次に作成したページを確認するためにディレクトリを有効にする。
##ディレクトリの作成

```
$ mkdir ~/sites
```
の中にhtmlファイルやjsファイルを放り込んでおく


次に以下のコマンドをターミナルで入力

```ruby:ターミナル
$ sudo vi /etc/apache2/httpd.conf
```

以下二つのコメントアウトを外す

```ruby:ターミナル
LoadModule userdir_module libexec/apache2/mod_userdir.so

Include /private/etc/apache2/extra/httpd-userdir.conf
```

次に

```ruby:ターミナル
$ sudo vi /etc/apache2/extra/httpd-userdir.conf
```

を開き以下の行のコメントアウトを外す

```
Include /private/etc/apache2/users/*.conf
```

#ユーザー設定のファイルの作成
`{username}`のところを自分のユーザーネームに置き換えましょう

```
$ sudo vim /etc/apache2/users/{username}.conf
```

```
<Directory "/Users/ユーザ名/Sites/">
AllowOverride All
Options Indexes MultiViews
Options +FollowSymLinks
Require all granted
</Directory>
```

準備は整ったので、`http://localhost/~ユーザー名/index.html`にアクセスして、指定したファイルが表示されていれば完了です。

#補足
自分の場合、最後にローカルサーバーが立ち上がらないエラーになってしまったので記録しておく。

色々試してみるうち

```
netstat -ant | grep httpd
```

や

```
$ /var/log/apache2/error_log
-bash: /var/log/apache2/error_log: Permission denied
```
をしたあと、
これで発見↓

```
$ sudo apachectl configtest
AH00526: Syntax error on line 510 of /private/etc/apache2/httpd.conf:
User takes one argument, Effective user id for this server
```

原因は色々なサイトを参考にしているうちに、`$ sudo vi /etc/apache2/httpd.conf`でいらんところをコメントアウト外していたみたいなので戻す。

#まとめ
色々なサイトを参照しているうちにやはり間違った情報や、自分の環境に合わないやり方などもあるので、結局は一次ソースが一番。
AWS S3へのアップロードでSignatureDoesNotMatchにハマった話

#はじめに
S3に画像ファイルをアップロードする対応を行った際、403ステータスにハマったので記事にします。
#前提
開発言語・・・VBScript
送信方式・・・HttpRequest
送信ファイル種別・・・jpg
#現象
・Httpステータスが403で返ってくる（SignatureDoesNotMatch）

#原因究明
`疑ったことその１`
・権限がない？またはACL掛かってる？
　　→権限はある
　　→ACLも掛かってない

`疑ったことその２`
・レスポンスをよく見てみると、以下が返ってきている
・アクセスキーまたはシークレットアクセスキーが間違っている？
　　→間違っていない

```ruby:Error
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
```
`疑ったことその３`
・ハッシュ化の部分か文字コードがおかしい？
　　→きちんとハッシュ化されている
　　→文字コードもUTF-8

`疑ったことその４`
・Signatureの構築内容をもう一度確認する

```ruby:Upload_To_S3
Dim stringToSign : stringToSign = Replace("PUT\n\n" & contetType & _
				                  "\n\nx-amz-acl:public-read" & _
				                  "\nx-amz-date:" & timestamp & _
				                  "\n/"& bucket_name & "/" & target_directory,_
				                  "\n", vbLf)
```
・target_directoryに続くファイル名が付いてない
　　→これ

#原因
・Signatureの内容不備による認証エラー

#まとめ
・エラーコードが403だったので、とにかく権限周りを気にしていた
・不備のある認証情報でアクセスしてきたら、AWSは権限不足と判断する（AWS側の立場だとそうするも納得）
NativeActivity で .so の android_main を呼ぶときの注意点

https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/

https://developer.android.com/ndk/samples/sample_na

を参考にします.

NativeActivity を使う場合, AndroidManifest.xml で,

https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/android/app/src/main/AndroidManifest.xml


```
            <meta-data android:name="android.app.lib_name"
                android:value="native-lib" />
```

として, .so を meta-data に追加しておかないと. .so の `android_main` を見つけてくれず, `FATAL EXCEPTION: main` エラーが出ますので注意です!
(AppCompatActivity などを使う場合は設定不要)

## permission 関連

Storage permission の要求(Java layer)も NativeActivity でできました.
ただ, Java onCreate と並行して `android_main` が呼ばれてしまうようなので, JNI で permission の状態を Java へクエリできる仕組みが必要になります.

## TODO

* [ ] Scopded directory access https://developer.android.com/training/articles/scoped-directory-access あたりを調べる(C++ レイヤで permission check しないで, `/data/local/tmp` やら app 限定ストレージでファイル読み書きできる方法を調べる)
検定手法のまとめ

#t検定
##1変量のとき
標本平均がある値と有意差があるかどうかを調べる。
##2変量のとき
2種類の標本平均に有意差があるかを調べる。ただ、2変量に対応関係があるかどうかで手法が少し異なる。詳細は下のリンクを参照のこと
[statsモジュールの関数](https://qiita.com/kanamae879123/items/ec1226fc6d0ba789ae65)

#分散分析
3つ以上の水準間の平均値に差があるかどうかを検定する。
F比を求めた後に、そこからp値を計算する。
母集団分布が等分散正規分布であると仮定すると、F比の標本分布(F分布）はすでに明らかであるため、F分布の累積分布を用いる事によって、p値を得られる。

##F比
F比が大きいと、誤差に比べて効果の影響が大きいと判断される。

```math
F比=\frac{効果の分散の大きさ}{誤差の分散の大きさ}
```
効果の大きさとはバイオリンプロット同士の距離。群間変動と呼ぶ。
誤差の大きさとはバイオリンプロットの大きさ。郡内変動と呼ぶ。


#χ二乗検定
分割表に対するデータの独立性を検定する。

1.　観測度数と期待度数の差を求める。ここで、期待度数はすべて5以上であることが求められる。
以下が期待度数と観測度数の差を表したχ二乗統計量である。

```math
\chi^2=\sum_{i=1}^{m}\sum_{j=1}^{n}\frac{(O_{ij}-E_{ij})^2}{E_{ij}}
```
上の式はデータ部分のみの分割表がm行n列としている。
Oが観測度数で、Eが期待度数である。

2.p値を求める。<br>
χ二乗統計量の標本分布は、自由度１のχ二乗分布に漸近的に従うと証明されているため、χ二乗分布の累積分布関数　を利用して、p値を求めることができる。


##参考ページ
https://qiita.com/kanamae879123/items/ec1226fc6d0ba789ae65
https://qiita.com/kanamae879123/items/2502258737a7d8e181c6
Vue I18nを使って多言語サイトを作成する

[Vue I18n](https://github.com/kazupon/vue-i18n)を使って英語・日本語の対応のサイトを作成しましたので、簡単に使い方を紹介します。

## インストール

```
npm install vue-i18n
```

2020年1月28日現在でのバージョンは`v8.15.3`です。

## ディレクトリ構成

global.jsonはサイト全体で使用するサイト名や、ヘッダーメニューなどのテキストです。
errors.jsonはバリデーションエラー時の汎用メッセージを置いています。エラーメッセージを使わないコンポーネントもあるので、globalと分けています。
components、containersの各コンポーネントに対して1ロケールファイルを用意しています。

```
.
├── main.ts
├── components
│   └── Hello.vue
├── containers
│   └── Hello.vue
└── locale
    ├── global.json // グローバルのロケールメッセージ
    ├── errors.json // コンポーネントの共有ロケールメッセージ 
    ├── components
    │    └── hello.json
    └── containers
         └── hello.json
```


## コード例

``` main.ts
import Vuei18n from 'vue-i18n';

Vue.use(Vuei18n);
const i18n = new Vuei18n({
  locale: "ja",
  messages,
});

new Vue({
  i18n,
  render: (h) => {
    return h(App);
  },
}).$mount('#app');
```

``` global.json
{
    "ja":{
        "title": "きーた",
        "menu": {
            "home": "ホーム",
            "about": "XXXについて",
        }
    },
    "en":{
        "title": "Qiita",
        "menu": {
            "home": "HOME",
            "about": "About",
        }
    }
}
```

``` hello.json
{
    "ja":{
        "title": "きーた",
    },
    "en":{
        "title": "Qiita",
    }
}
```

``` errors.json
{
  ja: {
    errors: {
      notFound: "{msg}が見つかりませんでした"
    }
  }
  en: {
    errors: {
      notFound: "{msg} is not found"
    }
  }
}
```

``` hello.json
{
  ja: {
    message: {
      hello: "こんにちは、世界"
    }
  }
  en: {
    message: {
      hello: "hello world"
    }
  }
}
```

``` Hello.vue
<template>
  <div>
    <h1>{{ $t("title") }}</h1>
    <p>{{ $t("message.hello") }}</p>
    <p>{{ $t("error.notFound", { msg: "XXX" }) }}</p>
  </div>
</template>

<script lang="ts">
import Vue from 'vue';
import sharedMessages from '@/locale/errors.json';
import messages from '@/locale/components/hello.json';

export default Vue.extend({
  name: 'Hello',
  props: {
    ...
  },
  data() {
    ...
  },
  i18n: {
    messages,
    sharedMessages,
  },
});
</script>
```

## グローバル以外の共通メッセージ

グローバルメッセージであればどこからでも参照可能ですが、エラーメッセージのような全コンポーネントから参照が必要のないメッセージは `sharedMessages` を使います。

## カスタムブロック

単一ファイルコンポーネントの場合はカスタムブロックで管理することもできます。
https://kazupon.github.io/vue-i18n/guide/sfc.html#basic-usage

``` XXX.vue
<i18n>
{
  "en": {
    "hello": "hello world!"
  },
  "ja": {
    "hello": "こんにちは、世界！"
  }
}
</i18n>
```

## さいごに

ディレクトリ構成、グローバルロケール・共通ロケール・ローカルロケールについて紹介されてる記事は見当たらなかったので、この記事が参考になれば幸いです。
【AWS ECS】タスク実行時のキャパシティープロバイダーを設定する【2019/01】

# 困ったこと
ECSのタスクを実行しようとしたらこんなエラーが出た。
<img width="999" alt="スクリーンショット 2020-01-26 18.08.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473251/afc20652-60ce-4fa4-6662-2bbec9004569.png">
> 選択したクラスターのキャパシティープロバイダー戦略に、クラスターキャパシティープロバイダーが含まれていません。

なんのこっちゃ。。。

今回はいろいろ試行錯誤して発見した解決法をご紹介します。

# 解決法

## Auto Scaling でインスタンスを保護する
クラスターの設定に**キャパシティープロバイダー**というタグがあるので**作成**ボタンを押します。
<img width="1018" alt="スクリーンショット 2020-01-26 18.09.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473251/b779f8f8-ecf8-4ece-115d-b214fdde5883.png">

ただしいきなり作成しようとすると、下記のように怒られます。
エラーメッセージを読むとこんなことが書かれています。

> 
キャパシティプロバイダーの終了保護設定が無効です。キャパシティプロバイダーの終了保護を有効にするには、Auto Scaling グループに有効なスケールからのインスタンス保護が必要です。

<img width="1022" alt="スクリーンショット 2020-01-26 18.09.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473251/3354a793-bd73-6abe-052d-21b602ff2015.png">

Auto Scaling グループというものの設定を変えれば良さそうですね。
上の矢印のリンクからAuto Scaling グループのページに飛べるので移動しましょう。

<img width="1055" alt="スクリーンショット 2020-01-26 18.11.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473251/06af69b1-4d18-6b2c-6f02-acf8da3ad0b8.png">
上記のページに行くとクラスター作成時に自動作成されたAuto Scaling グループがあるので、**操作**→**編集**を押して下記のようにインスタンスの保護を設定して保存します。
<img width="684" alt="スクリーンショット 2020-01-26 18.10.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473251/823e175f-e03d-ecfb-320e-df2cb9b38797.png">

ただし、なぜかこれだけだとダメみたいで、追加で設定が必要です。
矢印のところから新しいコンソール画面に飛びます。
<img width="1055" alt="スクリーンショット 2020-01-26 18.11.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473251/49dbe69f-5c09-ca51-0374-fe127fbc24b2.png">

下の画面に飛びますので**Instance management**タグから先程と同じAuto Scaling グループを選択肢、アクションから**スケールイン保護を設定**を選択します。
（画像では文字がグレーアウトされていますが、これはすでに設定されている状態だからです。まだこの設定をしていなければ黒くなっているはずです。）
<img width="915" alt="スクリーンショット 2020-01-26 18.13.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473251/67fcc9f6-5bff-acd8-2387-8e4370051a0f.png">

## クラスターからキャパシティープロバイダーを作成する
先程のキャパシティープロバイダー作成画面に行きましょう。今度は以下のエラーは表示されないはずです。
<img width="1022" alt="スクリーンショット 2020-01-26 18.09.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473251/f3da791d-c681-2989-412b-6ae1b00c6001.png">
次にクラスター最初の画面に戻って右上の**クラスターの更新**ボタンから、今作成したキャパシティープロバイダーを選択して更新します。
<img width="1020" alt="スクリーンショット 2020-01-26 18.15.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473251/4d2eb5dc-3a4e-4534-29e2-028d325100f8.png">
 ↓↓↓↓↓
<img width="1016" alt="スクリーンショット 2020-01-26 18.15.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473251/0f9b4a3d-3357-70c7-22f6-6f5843952580.png">

## タスクを実行する
一番最初のところに戻ってタスクを実行しましょう！
今度は正常に作成されるはずです。
<img width="1016" alt="スクリーンショット 2020-01-26 18.16.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473251/2295c0ef-5ef2-9f09-b136-298ffcae070b.png">
GitHubのOrganizationのコミットアクティビティを可視化する

## これは何
あるGitHub Organizationの去年1年間のコミット数を、週単位で集計してグラフにする方法。
忙しかった時期とかが見えて面白いかもしれん。

リポジトリのアクティビティはInsightsから簡単に見れるが、Organization単位のInsightsは[GitHub Enterprise Cloudでしか見れないらしい](https://help.github.com/ja/github/setting-up-and-managing-organizations-and-teams/viewing-insights-for-your-organization)ので、Pythonでサクッと書いてみた。


## 例
こんな感じのグラフが得られるぞい。x軸が週、y軸がコミット数。
![activity.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130232/3abf3834-b33a-35b0-d42b-e67b294ed858.png)


## やり方
依存パッケージを入れて↓のコードを実行するだけ。ローカルで普通に実行してもよし、jupyter notebookでもよし、[Colaboratory](https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja)でもよし。

GitHub APIの仕様的に初回の実行はかなり遅い。

```python
import isoweek
import datetime
import matplotlib.pyplot as plt
from github import Github
from operator import add

# See: https://pygithub.readthedocs.io/en/latest/introduction.html
g = Github("{ユーザー名}", "{パスワード}")
# For GitHub Enterprise
# g = Github(base_url="https://{hostname}/api/v3", login_or_token="{access_token}")

weeks = isoweek.Week.last_week_of_year(datetime.datetime.now().year - 1).week
stat = [0] * weeks

for repo in g.get_organization("{organization名}").get_repos():        
    activity = repo.get_stats_commit_activity()
    if activity is not None:
        activity_per_week = [x.total for x in activity]
        stats = list(map(add, stat, activity_per_week))
    
x = list(range(weeks))
plt.bar(x, stats, width=1.0)
plt.show()
```

:point_right: [Gist](https://gist.github.com/tinoji/b335a3d68a83805320fbed8320a8c541)


## 補足
ちょっと修正すれば日単位にもできるゾ。`total`を取っているところを変えればいいはず。
参考: [GitHub Statistics API](https://developer.github.com/v3/repos/statistics/)

コミット数じゃなくて、`Code frequency`的な感じで差分のLOCまで分かると面白そうなので、誰かやってほしい。
RailsのLEFT OUTER JOINにAND条件を追加する

# TL;DR
## `includes`文ない時
```rb
Book.joins(
  <<~SQL
    LEFT OUTER JOIN `reviews` ON `reviews`.`book_id` = `books`.`id` \
    AND `reviews`.`approved` IS NOT NULL
  SQL
).where.not(bookmarks: { id: nil }).order("`reviews`.`created_at` DESC").distinct

=> Book Load (1.5ms)  SELECT DISTINCT `books`.* FROM `books` LEFT OUTER JOIN `reviews` ON `reviews`.`book_id` = `books`.`id` AND `reviews`.`approved` IS NOT NULL WHERE `bookmarks`.`id` IS NOT NULL ORDER BY `bookmarks`.`created_at` DESC

```

## `includes`文ある時
こうすれば、`reviews`を何らかの処理をしたい時、２度ロードしなくて良いです。

```rb
Book.includes(:reviews)
  .joins("LEFT OUTER JOIN `reviews` ON `reviews`.`book_id` = `books`.`id` AND `reviews`.`approved` IS NOT NULL")
  .where.not(bookmarks: { id: nil }).order( "reviews`.`created_at` DESC").distinct
=> Book Load (1.5ms)  SELECT DISTINCT `books`.* FROM `books` LEFT OUTER JOIN `reviews` ON `reviews`.`book_id` = `books`.`id` AND `reviews`.`approved` IS NOT NULL WHERE `bookmarks`.`id` IS NOT NULL ORDER BY `bookmarks`.`created_at` DESC
Review Load (0.3ms)  SELECT `reviews`.* FROM `reviews` WHERE `reviews`.`book_id` IN (5, 9)
```

# 詳細
## 解説
*`Book`というモデルがあり、それに`Review`が投稿されていて、`Review`には承認Flag`approved`があります。`Book`を抽出したいが、承認された`Review`の投稿日`created_at`順で並びたいです*

## Models

```book.rb
class Book < ApplicationRecord
  has_many :reviews
end
```

```review.rb
class Review < ApplicationRecord
  belongs_to :book
  # `approved`というColumnで承認Flagを保持
end
```

## Methods to SQL

### `INNER JOIN`

```rb
Book.joins(:reviews)

=> Book Load (1.0ms)  SELECT  `books`.* FROM `books` INNER JOIN `reviews` ON `reviews`.`book_id` = `books`.`id`
```

### 単純の`LEFT OUTER JOIN`

```rb
Book.left_joins(:reviews)

=> Book Load (1.0ms)  SELECT  `books`.* FROM `books` LEFT OUTER JOIN `reviews` ON `reviews`.`book_id` = `books`.`id`
```

### `LEFT OUTER JOIN ??? AND ???`

```rb
Book.joins("LEFT OUTER JOIN `reviews` ON `reviews`.`book_id` = `books`.`id` AND `reviews`.`approved` IS NOT NULL")

=> Book Load (1.5ms)  SELECT `books`.* FROM `books` LEFT OUTER JOIN `reviews` ON `reviews`.`book_id` = `books`.`id` AND `reviews`.`approved` IS NOT NULL
```

### 上記仕様の実装例
```rb
Book.joins(
  <<~SQL
    LEFT OUTER JOIN `reviews` ON `reviews`.`book_id` = `books`.`id` \
    AND `reviews`.`approved` IS NOT NULL
  SQL
).where.not(bookmarks: { id: nil }).order('`reviews`.`created_at` DESC').distinct

=> Book Load (1.5ms)  SELECT DISTINCT `books`.* FROM `books` LEFT OUTER JOIN `reviews` ON `reviews`.`book_id` = `books`.`id` AND `reviews`.`approved` IS NOT NULL WHERE `bookmarks`.`id` IS NOT NULL ORDER BY `bookmarks`.`created_at` DESC
```

# 参考
- [**Railsガイド** 12.1.1 SQLフラグメント文字列を使用する](https://railsguides.jp/active_record_querying.html#joins)
- [Railsで複数条件のLEFT JOINをかくには](https://ja.stackoverflow.com/questions/41037/rails%E3%81%A7%E8%A4%87%E6%95%B0%E6%9D%A1%E4%BB%B6%E3%81%AEleft-join%E3%82%92%E3%81%8B%E3%81%8F%E3%81%AB%E3%81%AF)
- [Rails における内部結合、外部結合まとめ](https://qiita.com/yuyasat/items/c2ad37b5a24a58ee3d30)