OmniAICreator/Qiita-1.07M huggingface dataset:
Pepper SDK入門(7) UIスレッドとワーカースレッド

前回、アクションについて解説するなかで同期と非同期の区別が登場しました。今回はその同期と非同期について、UIスレッドとワーカースレッドの二つを主軸に見ていきます。

**同期と非同期**
Pepperではタブレットと本体でそれぞれ異なるプロセスが動いており、二つのCPU間にはUSBを経由したTCP/IPによる通信があります。 同期と非同期のどちらでアクションを実行するかは、実際に動かしてみた上での選択をお勧めします。

#1.UIスレッド 
Androidシステムからのコールバック(onCreateやOnClickListenerなど)はUIスレッド上で動作します。

```java

@Override
protected void onCreate(Bundle savedInstanceState) {
}
@Override
protected void onResume() {
}
```

タブレットからPepperに指示を出した場合、Pepperとタブレット間での通信が発生します。しかしUIスレッド上でのネットワーク通信は出来ないため、NetworkOnMainThreadExceptionがスローされてしまいます。そのため、UIスレッドからPepperに指示を出す際は非同期を使用するようにしてください。

**実践:同期と非同期**
同期:UIスレッドで呼ぶことができない

```java

// UIスレッド
Say say = SayBuilder.with(qiContext)
        .withText("こんにちは")
        .build(); // NetworkOnMainThreadExceptionがスローされる
```

```java

// UIスレッド
goTo.run(); // NetworkOnMainThreadExceptionがスローされる
```

非同期:UIスレッドで呼ぶことができる

```java

// UIスレッド
Future<say> sayBuilding = SayBuilder.with(qiContext)
        .withText("こんにちは")
        .buildAsync(); 
```

```java

// UIスレッド
goTo.async().run();
```

#2.ワーカースレッド
続いて、ワーカースレッドについて見ていきましょう。Androidのワーカースレッドは独自で管理することも可能ですが、QiSDKのライブラリに任せることもできます。

QiSDKは複数の方法により、ワーカースレッドで処理を実行させることが可能です。

**例① ロボットライフサイクル**

```java

@Override
public void onRobotFocusGained(QiContext qiContext) {
}
@Override
public void onRobotFocusLost() {
}
```

**例② Futureチェーン**

```java

future.thenConsume(future -> {
});
```

**例③ リスナー**

```java

qiContext.getHumanAwareness().addOnHumansAroundChangedListener(humans -> {
});
```

以上の例はすべて、UIスレッド上ではなくワーカースレッドで同期します。

##実践:非同期が有効なシーン
**2-1.アクションをキャンセルしたい場合**

非同期でアクションを実行する必要があります。

```java

Future<void>goToFuture = goTo.async().run();
...
goToFuture.requestCancellation();
```

**2-2.複数のアクションを同時に実行したい場合**

複数のアクションを、非同期で連続して実行する必要があります。

```java

Future<void>sayFuture = say.async().run();
Future<void>goToFuture = goTo.async().run();
```

**2-3.その他の場合**

上記の2-1、2-2に該当しない場合は、同期か非同期のいずれかでアクションを実行します。

```java

say.run();
```

もしくは

```java

Future<void> sayFuture = say.async().run();
```

**補足**
メインスレッドからPepperにアクションを実行させたい場合、非同期を使用してください。
Pepper SDK入門(2) はじめてのロボアプリ開発①

発話を行うロボアプリの開発をしながら、開発手順について説明していきたいと思います。Androidプロジェクトを作成し、ロボアプリの初期設定を行い、ActivityがPepperを操作するために必要な実装について見ていきます。



#1.プロジェクト作成
ロボアプリ開発にあたって、まず初めに標準的なAndroidプロジェクトを作成し、それにロボアプリの設定を追加します。Android StudioのFileメニューのNewからNew Projectを選択し、Androidプロジェクトを作成してください。プロジェクト作成時のTarget Android DeviceではPhone and TabletのAndroid 6.0 (Marshmallow)が選択してください。

#2.ロボアプリの初期設定
作成したAndroidプロジェクトにロボアプリの初期設定を行います。

**<手順>**
1.FileメニューのNewからRobot Applicationを選択します。
2.サポートするRobot SDKのバージョンと追加するモジュールを選び、OKをクリックしてください。
3.Sync Project with Gradle Fileボタン(下図の参照)をクリックし、プロジェクトとGradleファイルを同期させます。 
![WS000001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574697/0f5760bf-ceae-a94f-6842-d3a8be84785f.png)

**結果**
これでロボアプリの初期設定が完了しました。以下のファイルが更新されていることが確認できます。

- assetsにrobotディレクトリとrobotsdk.xmlファイルが追加されます。robotsdk.xmlファイルには、選択したRobot SDKのバージョンが含まれています。
![WS000004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574697/83d0dc38-9dc0-05fb-8340-6fd5f1977aa6.png)

- appのbuild.gradle fileのdependenciesにQiSKDのモジュールが追加されます。これにより、アプリからQiSDKが利用できるようになります。
 ![WS000005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574697/9af2cd09-3a0a-d10b-a8fd-e04cbeb1c1b3.png)

- AndroidManifest.xmlにuses-featureタグが追加されます。追加されたuses-featureタグはアプリがPepperを使用することを示しています。
![WS000003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574697/6516578f-6ce9-edbc-575c-d46bb0323e34.png)

#3.QiSDK実装とロボットのライフサイクル
ActivityからPepperを操作するために必要となる共通の実装について見ていきます。

**<手順>**
1.onCreateメソッドの中で、QiSDKにActivityを登録します。

```java

protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
  QiSDK.register(this, this);
}
```

2.onDestroyメソッドの中でActivityの登録を解除します。

```java

protected void onDestroy() {
    QiSDK.unregister(this, this);
    super.onDestroy();
}
```

※ QiSDK.unregister(this)を使用した場合は、ActivityのすべてのRobotLifecycleCallbacksの登録が解除されます。登録したままにしておくべきコールバックを解除してしまうことのないよう注意してください。

3.作成したActivityにRobotActivityを継承させます。これにより、Activityは会話の内容を画面に表示するSpeechBarを利用できるようになります。

```java
 
public class MainActivity extends RobotActivity
```

4.追加したActivityにRobotLifecycleCallbacksを実装してください。

```java

public class MainActivity extends RobotActivity implements RobotLifecycleCallbacks
```

このインターフェースはロボットフォーカスの獲得と喪失の通知を受けるためのものです。

5.onRobotFocusGained、onRobotFocusLost、onRobotFocusRefusedメソッドをオーバーライドで実装します。

```java

@Override
public void onRobotFocusGained(QiContext qiContext) {}

@Override
public void onRobotFocusLost() {}

@Override
public void onRobotFocusRefused(String reason) {}
```

onRobotFocusGainedはActivityがロボットフォーカスを獲得した時に呼ばれます。ロボットフォーカスを獲得した時、ActivityはPepperに様々な動きをさせることが出来ます。 onRobotFocusLostはActivityがロボットフォーカスを失った時に呼ばれます。ロボットフォーカスを失った時、ActivityはPepperを動かすことが出来なくなります。

**重要**
onRobotFocusGainedとonRobotFocusLostメソッドはバックグラウンドスレッドで実行されるため、UIスレッドをブロックすることはありません。
Pepper SDK入門(3) はじめてのロボアプリ開発②

Androidプロジェクトの作成及びロボアプリの初期設定を行った前回に引き続き、Pepperのエミュレータと実機でアプリを実行するために必要な手順を確認していきます。 



#1.Pepperのエミュレータ 
まずは、Pepperのエミュレータで動作確認するための方法についてです。

**<手順>**
1.エミュレータボタン![WS000003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574697/63caa825-0f6a-984b-51a3-b5e969d4d75f.png)をクリックしてください。すると、ロボットエミュレータが表示されます。
2.プロジェクトにおける実行の構成でappが選択されているか![WS000002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574697/328c4224-a649-0da9-08c1-95d63fa408d6.png)を確認し、選択されていない場合はそれを選択してください。
3.実行ボタン![WS000000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574697/6757ac63-dabf-ec00-174a-fd48fb65ce7c.png)をクリックしてください。すると、Select Deployment Targetダイアログが表示されます。
4.ダイアログからPepperのエミュレータを選択してください。アプリがエミュレータにインストールされ、Robot Viewer上のバーチャルロボットで動作確認することが出来ます。

#2.Pepperの実機 
次に、Pepperの実機で動作確認するための方法を見ていきます。

**<手順>**
1.Pepperのタブレットの設定を確認します。タブレットのホームにある設定アイコンをタップし、以下の設定を確認してください。
·開発者モードが有効になっていること
·開発者向けオプション、デバッグ、ADBも有効になっていること
2.Android studioで、接続ボタン![WS000004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574697/abfe7e7e-710d-e452-96cd-9d8eee3e0d86.png)をクリックし、Robots Browserを表示してください。
3.Use fix portとUse fixed IP/hostnameにチェックを入れ、接続先のPepperのIPアドレスを入力してください。PepperのIPアドレスはタブレットの通知バーか、胸部ボタンを一回押すことで確認できます。
4.Selectボタンをクリックしてください。すると、セキュリティの警告が表示されます。
![WS000006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574697/3e3493be-5888-7bff-4ba7-5fe1ccd6d7ea.png)
5.Pepperのパスワードを入力してください。初期パスワードはnaoです。変更している場合は管理者に確認して下さい。パスワード入力後にOKボタンをクリックすると、Robot Viewerが表示されます。
![WS000007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574697/d5492d61-39ad-1abd-d823-47a6ace428ec.png)
Pepperの実機に接続すると、同時にタブレットにもADB経由で接続されます。
6.プロジェクトにおける実行の構成でappが選択されているか![WS000002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574697/fc7d6cac-ccae-8c55-b92d-dfed24613d53.png)を確認し、 選択されていない場合はそれを選択してください。
7.実行ボタン![WS000000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574697/87e75015-b901-af38-530f-e2941f3fd94a.png)をクリックしてください。すると、Select Deployment Targetダイアログが表示されます。
![WS000008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574697/840baeb0-d4f3-ff07-8d6c-f969f3e0c72f.png)
8.Pepperのタブレットを選択してください。実機でアプリが起動します。
在宅勤務連絡をPower Automateで作ろう (with ロケーション情報)

最近では多くの会社で在宅勤務が認められるようになってきました。
とある弊社でも在宅勤務制度がスタートするのですが、原則、**「開始終了を上司に連絡する必要がある＆場所は自宅のみ」**とされています。（実家も微妙）

いちいちメールするのも面倒ですし、場所が家であることを一応何となく証明するために、Power Automate + Google MAP APIを利用して、在宅勤務連絡(申請)フローを作成しましたので紹介します。

# Flowの流れ
少し長めですので、各ステップで何をやっているかまずは概要を紹介します。
やっているのは、
モバイルのFlowボタンを押して ⇒ Google MAP APIで押した場所の住所を取得 ⇒ 上司に承認依頼を送り ⇒ OKだったらリストに記録
という流れです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/e9deb2db-ccbd-dcf9-0b6d-d5e55855901c.png)

## MAP API実行～住所取得まで
ポイントはここくらいかなと思います。以前の投稿([[TIPS] Power AutomateでHTTPを使わずにHTMLを取得する](https://qiita.com/h-nagao/items/65f498d9d4e4f1a5fa50))でも紹介しましたが、今回のGoogle MAP API実行でもこのテクニックが使えます。

むしろこれないと辛いくらい最近多用しています。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/55af368c-a70c-2d1a-19bd-a0c8979dc8e7.png)

Parse JSONすると、Resultsに住所情報(formattedAddress)が複数入っていることがわかります。
ちゃんと調べていないのですが、0番目が一番詳細な住所で、順に荒くなっていくので、うまい塩梅を見つけて使ってください。

## 承認依頼部分
あとは承認依頼するステップくらいです。ここでは勤務開始か終了かでタイトルを変更し、あとは勤務場所を詳細情報に入れています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/65fdba6f-06bb-5c6d-9da6-815c2692de40.png)

※勤務場所の部分の数式には

```
body('Parse_JSON')?['results']?[0]?['formatted_address']
```
これを入れています。[0]の部分が、住所の詳細度合いなので、必要に応じて変更してください。


#動作確認
実際に動かしてみます。下図のような形で、住所を付記した承認依頼が上司に送信されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/9fd43b60-1e86-fc80-ab41-772872b619c7.png)

承認が完了すると、SharePointに記録されるようにしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/c54f08a0-8f24-a7ab-48c5-d365ac9472cc.png)

# おわり
Power AutomateはMicrosoftのサービスですが、Microsoftのサービスに限らず、いろいろな
SaaSとつなげて必要な情報を得ることができます。
また、for Office 365なライセンスでも、OneDriveコネクタをうまく使うことで、HTTPのGETができますので、ぜひ活用してみてください！！
Pepper SDK入門(4) はじめてのロボアプリ開発③

アプリの実行についてまとめた前回の学習を踏まえ、このチュートリアルでPepperに"Hello human!"と発話させる簡単なアプリを開発していきます。

**前提条件**
Android Studio、Pepper SDK plugin、Robot SDKとその関連ツールがインストールされていること。

# 1.新規プロジェクトの開始
- HelloPepperの名称で、新しいプロジェクトを開始してください。
- Fileメニュー >New > Robot ApplicationからQiSDKの初期設定が完了していることと、ActivityにonCreateメソッドとonDestroyメソッド、及びRobotLifecycleCallbacksインターフェースが実装されていることを確かめてください。

# 2.発話の実行
Pepperを発話させるために、[Say](https://qisdk.softbankrobotics.com/sdk/doc/pepper-sdk/ch4_api/conversation/reference/say.html#say)クラスを使用します。これはPepperのアクションを作成できるクラスの一つです。[Say](https://qisdk.softbankrobotics.com/sdk/doc/pepper-sdk/ch4_api/conversation/reference/say.html#say)クラスの使い方は以下の通りです。

**＜手順＞**
1. onRobotFocusGainedの中で、[SayBuilder](https://qisdk.softbankrobotics.com/sdk/doc/pepper-sdk/ch4_api/conversation/reference/say.html#say)クラスを使ってSayオブジェクトをビルドします。

```java

        Say say = SayBuilder.with(qiContext)
                .withText("Hello human!")
                .build();
```

2.発話を実行するために、作成した[Say](https://qisdk.softbankrobotics.com/sdk/doc/pepper-sdk/ch4_api/conversation/reference/say.html#say)オブジェクトのrunメソッドを呼びます。

```java

say.run();
```

3.完成したコードは下記のようになります。

```java

    @Override
    public void onRobotFocusGained(QiContext qiContext) {
        Say say = SayBuilder.with(qiContext)
            .withText("Hello human!").build();
        say.run();
    }
```

以上でPepperが発話出来るようになります。

# 3.チュートリアル
[GitHub](https://github.com/aldebaran/qisdk-tutorials/tree/master/app/src/main/java/com/softbankrobotics/qisdktutorials/ui/tutorials)に、上記と同様の発話を実行できるチュートリアルのソースコードが公開されています。ダウンロードして以下の操作を行うことで発話を確認できます。

**＜手順＞**

1. [GitHub](https://github.com/aldebaran/qisdk-tutorials/tree/master/app/src/main/java/com/softbankrobotics/qisdktutorials/ui/tutorials)からアプリをインストールし、実行してください。
2. "Hello Human"を選択してください。
【SSH】whileとの併用

#何をしたいか
複数台あるサーバーにsshで入って処理するようなスクリプトを書きたい！
サーバーのip自体はlstファイルから呼び出せるようにして管理しやすいようにしたい！
そこでこういうスクリプトを作成しました。

```server_ip.lst
192.168.10.1
```

そしてシェルはこういう感じで実装。

```ssh.sh
listfile=server_ip.lst
while read ip
do
	ssh test@ip ～～～
done < ${listfile}
```

よしよし出来た。
あとはserver_ip.lstに対象ipアドレス増やしておーわり。
設定...実行...
...
...
1サーバーしか出来ない...

#何が起きたか
~~sshを使用すると、標準入力がsshによるリモートからのものに切り替わり、~~
~~ローカルのファイルが閉じられるようです。~~**(2020/01/31にコメントを頂いて修正)**
標準入力がsshにリダイレクトされることで、
sshがローカルのファイルを標準入力で読み取りきってしまうそうです。


なので1行目しか読み込まれずループが終了するという仕組みのようです。
同じようなトラップに引っかかった方が多いようですね

#どうすればよいか
sshに対して標準入力からの読み込みを禁止にするとよい。
これにはオプションがあって「-n」をつけると良いそうです。

```(正常なやつ)ssh.sh
listfile=server_ip.lst
while read ip
do
	ssh -n test@ip ～～～
done < ${listfile}
```

これは勉強になりました。
Pepper SDK入門(9) オートノマスライフ

オートノマスライフについて、簡単な概要を説明します。



#自律モードの管理
Pepperはオートノマスライフというモードを持っており、人間の検知や追跡、音への反応や立ち位置の調整といった振る舞いを、自律して自然に行い、Pepperをより生き物らしく見せています。

#1.Autonomous abilities
Autonomous abilitiesとは、Pepperに備わる複数の自律行動の機能のことです。自律行動はPepperへ生命らしさを与えるため、移動・アニメーション・顔追跡によって構成されています。

#2.Autonomous abilitiesの管理
写真撮影など、Pepperのアニメーションの動きを完全に停止させたい場合には、Autonomous abilitiesを止める機能を使用してください。ここでは概要のみの記述ですが、詳細はまた改めて解説します。



いつもよりも短いですが、今回はここで終了です。次回はアニメーションブラウザについて見ていきます。
Vuejsで遅延読み込みしたいのにVueライブラリじゃないのを使った話

# 書いてあること

画像のみがたくさん並んでいるようなサイトで画像の遅延読み込みをするために、 [lazysizes](https://github.com/aFarkas/lazysizes) を使ったら素直に実装できたという話です。

# 実現したいこと

文章ではなく画像が主体のサイトを想像して下さい。たとえば、写真ライブラリーのようなサイトです。
画像の要件としては、レスポンシブ対応として、ある横幅より小さい場合はその横幅いっぱいで表示する、という物です。
その画像が縦にたくさん並んでいるような表示をしたいとします。

たとえば、画像の最大のサイズを横600ピクセルとする場合はこのような指定となります。

```html
<div>
  <img
    src="hoge_600.jpg"
    srcset="hoge_1200.jpg 1200w, hoge_600.jpg 600w, hoge_300.jpg 300w"
    sizes="(max-width=600px) 100vw, 600px)"
  >
</div>
<div>
  <img
    src="fuga_600.jpg"
    srcset="fuga_1200.jpg 1200w, fuga_600.jpg 600w, fuga_300.jpg 300w"
    sizes="(max-width=600px) 100vw, 600px)"
  >
</div>
<div>
  <img
    src="piyo_600.jpg"
    srcset="piyo_1200.jpg 1200w, piyo_600.jpg 600w, piyo_300.jpg 300w"
    sizes="(max-width=600px) 100vw, 600px)"
  >
</div>
```

このように画像が縦にたくさん並んでいるサイトにて画像の遅延読み込みをしたいです。

# まず Vue-lazyload を試してみた

サイト作成で Vue.js を利用していたので、まずは Vue.js のプラグインを探したところ、 [Vue-Lazyload](https://github.com/hilongjw/vue-lazyload) を見つけたので試してみました。
話が少しそれますが、今回は画像のサイズが固定でないため、img タグに対して `height` 指定をしておらず、画像の読み込み前は `img` タグの高さが0となっており、結果、すべての img タグが表示領域に入ってしまい、遅延読み込みになりませんでした。
そのため、Loading画像を用意して、画像読み込みまではその画像の高さを指定しようとしました。
その結果、Vue-Lazyload は、次の点で使いにくさがありました。

* 画像の読み込み完了するまではCSSで高さを指定しておきたかったが、画像の読み込みが始まるまでを指定できるCSSセレクタがなさそうでした。( 画像の読み込み中を指定するCSSセレクタはあった ) [参考](https://github.com/hilongjw/vue-lazyload#css-state)
* sizes に対応していない。

どちらかというと後者が致命的でした。
前者は、最初は適当なクラスなどで高さを指定しておき、読み込み後のCSSでそれを打ち消すようにしておけばなんとかなりました。
後者は、sizesが使えないのでCSSで表示幅を指定したのですが、それですと srcset の中でどの画像ファイルを使うかが、表示幅ではなくブラウザの表示幅で決まってしまい、srcset の意味が失われそうです。

# lazysizes を見つけた

Vue.js のプラグインではないのですが、 [lazysizes](https://github.com/aFarkas/lazysizes) を使うことにしました。
lazysizes は 先ほどの、Vue-Lazyload での使いにくさがありませんでした。

* 画像読み込みを始める前のCSSセレクタも指定できました。[参考](https://github.com/aFarkas/lazysizes#css-api)
* sizes も指定できます。

lazysizes を使うことで、画像が読みこまれるまでの画像にLoading画像を指定し、画像を読み込む前と画像読み込み中にLoading画像のサイズをCSS指定しておくだけで素直に実装できました。

```html
<img
  class="lazyload"
  src="loading.png"
  data-src="hoge_600.png"
  data-srcset="hoge_1200.png 1200w, hoge_600.png 600w, hoge_300.png 300w"
  sizes="(max-width: 600px) 100vw, 600px"
>
```
```scss
.lazyload, .lazyloading {
  height: 300px;
}
```

というわけで lazysizes 助かりました。ありがとうございます。
Azureを始める際に読み始めるところ　～Microsoft Learn～


Azureに関する知識をWebで体験できるコンテンツ「MS Learn」です。
その中でもエントリー向けの学習パスが以下になります。
Azureの基礎
https://docs.microsoft.com/ja-jp/learn/paths/azure-fundamentals/
 
また、上記のコンテンツの中でのおすすめコンテンツと概要です。
・コア クラウド サービス - Azure portal を使用してサービスを管理する
https://docs.microsoft.com/ja-jp/learn/modules/tour-azure-portal/index
　概要：AzureをWeb UI 「Azure Portal」の利用方法を一通り学ぶことができます。
 
・コア Cloud Services - Azure アーキテクチャとサービスの保証
https://docs.microsoft.com/ja-jp/learn/modules/explore-azure-infrastructure/index
　概要：Azureのデータセンターに関する内容が学習できます。可用性やSLA(サービスレベルアグリーメント)についても記載があります。
 
・コア Cloud Services - Azure コンピューティング オプション
https://docs.microsoft.com/ja-jp/learn/modules/intro-to-azure-compute/index
　概要：VM(コンテナ含む)、アプリケーションサーバ、サーバレスアーキテクチャなどのAzureで利用できるアプリ動作環境について学習できます。
 
・コア Cloud Services - Azure データ ストレージ オプション
https://docs.microsoft.com/ja-jp/learn/modules/intro-to-data-in-azure/index
　概要：Azureにデータを格納する際に利用できるサービスとデータストレージのセキュリティについて学習できます。
 
・コア Cloud Services - Azure ネットワーク オプション
https://docs.microsoft.com/ja-jp/learn/modules/intro-to-azure-networking/index
　概要：Azure上で利用できるネットワークインフラに関するサービスについて学習できます。
 
 
さらに、企業でクラウドサービスを利用する際に気になる項目などがまとまっています。
・Azure におけるセキュリティ、責任、信頼
https://docs.microsoft.com/ja-jp/learn/modules/intro-to-security-in-azure/index
　概要：Azure上でのセキュリティ監視とシークレット情報管理について学習できます。
 
・Azure Policy でインフラストラクチャの標準を適用して監視する
https://docs.microsoft.com/ja-jp/learn/modules/intro-to-governance/index
・Azure Resource Manager での Azure リソースの管理と整理
https://docs.microsoft.com/ja-jp/learn/modules/control-and-organize-with-azure-resource-manager/index
　概要：Azure上でのリソース操作に関するポリシーやガバナンスについて学習できます。
[Android] SpotBugsは使えないかもしれない

AndroidStudioで静的解析ツールを使用したかったので、FindBugsを導入してみたが使えなかった。

解決法を探していたところ、前回の記事に書いたSpotBugsというのが出てきたので調べてみた。
https://qiita.com/QiitaD/items/8f1a81ac71a2eb9e59be

##結論
使えないっぽい。。。というかプラグイン検索で出てこなかった。そもそも他サイトには「SpotBugs(FindBugs)」と書いてあったので、同じものなのかもしれない。

しかしEcipseでは使えるっぽい。。。

##ほかのツール
Androidプロジェクトではほかにもよく使われる静的解析ツールがあるらしい。
・PMD
・CheckStyle
etc…

https://yuki312.blogspot.com/2016/02/android-gradle.html

##感想
ツールがいろいろあるみたいなので、次回は**PMD**の導入について調査し、記事にしたい。
【公開終了】

# はじめに
Googleフォトは容量無制限で使えるので画像や動画をたくさんアップロードしている方もいると思います。

しかしGoogleフォトにはアップロードした画像や動画の直リンク（ダイレクトリンク）を取得する機能がありません。
（画像は簡単にダイレクトリンクを作る方法があって調べればでてくるけど動画の場合はなかった）

そこで、今回Googleフォトにアップロードした動画のダイレクトリンクを簡単に生成できるツールを作ってみました。

# 直リン生成ツール

リンク -> 削除済み

簡単にツールの特徴を説明してみます。

- 共有リンクを入力するだけで直リン生成できる
- リンクの有効期限なし
- 動画プレイヤーなどでそのまま動画再生できる
- 画像の直リンも生成できる


このツールの良い点は有効期限のないダイレクトリンクを作ることができる点。

例えば動画のダイレクトリンクを取得してサイトなどに埋め込んでもリンクが期限切れになると動画が再生できなくなってしまいます。

だいたいクラウドストレージ系サービスはダイレクトリンクを取得できたとしても期限切れになることが多いのでその心配がいらないのは良いところだといえます
（ただし、Googleフォトの仕様が変更されたりするとリンク切れになるかも・・・）

# 使用した言語
このツールを作るのに使用した言語は以下のとおりです

- PHP
- JavaScript
- Node.js

JavaScriptはユーザーが入力した共有リンクをPHPに渡す
PHPはNode.jsにダイレクトリンク生成をリクエストする
Node.jsはリクエストを受け取ったらGoogleフォトからダイレクトリンクを取得する

# 詳細
詳しい説明やダイレクトリンクの有効期限がない理由については以下の記事をご覧ください。
削除済み

使い方の解説なども書いてあります。
シンプルなツールですが、もしよかったら使ってみてください。
AOPとインターセプターって同じものなの？メモ

##### メモを作ったきっかけ

「AOPもインターセプターも『指定のタイミングで割り込んでくるもの』ってぼんやりした認識だけど何が違うの？」と混乱したため簡単にメモ

##### AOP

Aspect Oriented Programming(アスペクト指向プログラミング)のこと。
共通の処理を毎回書くのではなくどこかに1回書いてそれを横断的に呼び出そう！って作り

##### インターセプター

interceptは「割り込む」みたいな意味
AOPにおいて割り込んで行う処理そのもののこと


##### 結論
インターセプターはAOPの一部
クラス

```py
class Person(object):
    def __init__(self, name):
        self.name = name
    
    def say_something(self):
        print('I am {}. Hello'.format(self.name))
        self.run(3)
    
    def run(self, num):
        print('run '*num)

person = Person('Tom')
person.say_something()
```

```:実行結果
I am Tom. Hello
run run run 
```
SQL*Plusで全体の表示幅とカラムの表示幅を変更する方法

- 環境
    - SQL*Plus: Release 12.2.0.1.0 Production
    - Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production


# 全体の表示幅を変更する方法
```sql
set linesize {幅}
-- 幅を確認する
show linesize
```

## 広げてみた

```sql
-- 幅が狭くてなんだかわからない
SQL> select tablespace_name,block_size,initial_extent,next_extent,min_extents,max_extents,max_size,pct_increase,min_extlen,status,contents from dba_tablespaces;

TABLESPACE_NAME                BLOCK_SIZE INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS
------------------------------ ---------- -------------- ----------- -----------
MAX_EXTENTS   MAX_SIZE PCT_INCREASE MIN_EXTLEN STATUS    CONTENTS
----------- ---------- ------------ ---------- --------- ---------------------
SYSTEM                               8192          65536                       1
 2147483645 2147483645                   65536 ONLINE    PERMANENT
...省略...

-- デフォルトの値を確認する
SQL> show linesize
linesize 80
-- 幅を広げる
SQL> set linesize 200
-- 確認する
SQL> show linesize
linesize 200
-- もう一度検索してみると見やすくなった
SQL> select tablespace_name,block_size,initial_extent,next_extent,min_extents,max_extents,max_size,pct_increase,min_extlen,status,contents from dba_tablespaces;

TABLESPACE_NAME                BLOCK_SIZE INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS MAX_EXTENTS   MAX_SIZE PCT_INCREASE MIN_EXTLEN STATUS    CONTENTS
------------------------------ ---------- -------------- ----------- ----------- ----------- ---------- ------------ ---------- --------- ---------------------
SYSTEM                               8192          65536                       1  2147483645 2147483645                   65536 ONLINE    PERMANENT
...省略...
6行が選択されました。
```


# カラムの表示幅を変更する方法
参考 : [[SQL*Plus] SELECT結果の列幅を指定する | ORACLE逆引きノート](https://oracle.programmer-reference.com/sqlplus-column-format/)

```sql
column {カラム名} format a{幅};
```

## 狭めてみた
```sql
-- [DIRECTORY_PATH]カラムが広すぎでみずらい
SQL> select * from dba_directories;

OWNER                          DIRECTORY_NAME
------------------------------ ------------------------------
DIRECTORY_PATH
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SYS                            ORACLE_OCM_CONFIG_DIR
/opt/oracle/product/11.2/state

SYS                            DATA_PUMP_DIR
/opt/oracle/PONSUKE/dpdump/
...省略...
-- 表示幅を狭める
SQL> column directory_path format a60;
-- 見やすくなる
SQL> select * from dba_directories;

OWNER                          DIRECTORY_NAME                 DIRECTORY_PATH
------------------------------ ------------------------------ ------------------------------------------------------------
SYS                            ORACLE_OCM_CONFIG_DIR          /opt/oracle/product/11.2/state
SYS                            DATA_PUMP_DIR                  /opt/oracle/PONSUKE/dpdump/
...省略...
```
【TypeScript】toJSONメソッドでJSON.stringifyの挙動をカスタマイズする

`private`を含む3つのプロパティを持つクラス`Model`を考える。

```ts
class Model {
  constructor(
    public prop1: string,
    private prop2: string,
    public prop3: number,
  ) { }
}
```

`Model`クラスのインスタンスを`JSON.stringify`でJSON文字列化すると、実行時はJavaScriptになっており`private`であることは忘れられているので`private`なプロパティまで文字列になってしまう。

```ts
const model = new Model("value1", "value2", 3);

console.log(JSON.stringify(model));
// {"prop1":"value1","prop2":"value2","prop3":3}
```

`private`プロパティを表示しないようにするためには`Model`クラスに`toJSON`メソッドを定義する。
`toJSON`メソッドの戻り値は、`Model`クラスの代わりにJSON文字列化したい値にしておく。(文字列化した結果ではなく)

```ts
class Model {
  constructor(
    public prop1: string,
    private prop2: string,
    public prop3: number,
  ) { }

  toJSON = () => {
    return {
      prop1: this.prop1,
      prop3: this.prop3,
    }
  }

  // こうではない
  // toJSON = () => {
  //   return JSON.stringify({
  //     prop1: this.prop1,
  //     prop3: this.prop3,
  //   });
  // }
}
```

`JSON.stringify`が`toJSON`を持つオブジェクトを文字列化するときは`toJSON`で返却される値を利用してくれる。

```ts
const model = new Model("value1", "value2", 3);

console.log(JSON.stringify(model));
// {"prop1":"value1","prop3":3}
```

# 参考

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
MAMP Pro5でPHPのversion操作する方法

#私
いまいちMAMP Proに慣れていないウェブエンジニアインターン歴数ヶ月のへっぽこ

#以前同じようなタイトルでPHP versionを変更したが、おそらく今回記事にする方法の方が楽だと思います
https://qiita.com/Himekichi/items/5e95f633c8f6b597f5ac

#PHPのversionを変える手順はこんな感じ
1.MAMP Pro5の左側のサイドバーにあるPHPを選択
![スクリーンショット 2020-01-31 16.30.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524422/652cda6d-0823-e111-c2c8-03870873eb0c.png)

2.上にDefault versionがあるので、そこがPHP versionを操作できる
![スクリーンショット 2020-01-31 16.35.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524422/acf44532-f056-8ceb-e4c5-bac09e2428c0.png)

3.今私が持ってるPHP versionはこんな感じ
![スクリーンショット 2020-01-31 16.36.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524422/1511a72e-169a-9cd8-32f5-f04eb804570f.png)

4.もしもっと他のversionが欲しければ、横にある＋をおす

5.そうするとDownloadできるPHP versionが表示される
![スクリーンショット 2020-01-31 16.37.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524422/b003c7a4-e9ad-c83d-a32b-54f102e29e4c.png)

6.自由に選んでインストールボタンをおす

おしまい

参考にしたサイト
https://it-studio.jp/mamp-pro-slow/#4_PHP7
Onsen UI 2でSNSをつくったよ

#HTML5ハイブリッドアプリを最高に美しく、スムーズに。
Onsen UI 2とは，Web上でiOSやAndroidのネイティブUIと同等のUXを実現するためのCSSフレームワークです．
簡単に言うと，「アプリじゃないけど，アプリみたいに動くサイト」です．
[BootstrapではなくOnsen UIを選定した理由](https://blog.ecbeing.tech/entry/2019/08/08/113502) にメリット・デメリットがまとまっています．

#成果物
[ShiJimi](https://www.shijimi.work)
ドラマ・映画に特化したSNSを目指しました(^^♪

#環境
onsen ui 2.10.10
javascript
css

#かっこいい機能3選

###ons-lazy-repeat
大量のリストを表示する場合に，スクリーンに写っている部分だけを読み込んでくれます．
（番組一覧やツイート画面に利用しています．）
![20200131_071108000_iOS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/7a2f5322-ca88-a2d9-8cdb-ec6ee2dffcb5.png)


###ons-carousel
横方向にパネルを並べることができます．
（作品ページと分析ページをカルーセルで移動できるようにしています．）
![20200131_071117000_iOS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/7558aba0-6d5c-2e3d-24ea-57d2ae84c0ed.png)

###ons-list
シンプルなリスト．
ヘッダーやサムネイル機能もあります．
![20200131_073053000_iOS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/bd7709c5-683b-13f6-d098-fcdbd95505e4.png)



#困ってること（泣）

###表示が一瞬崩れる
要素を複雑化させるほど，発生している気がします．
この原因は，onsen.jsの読み込み中に，ons-page要素が表示されてしまうことだと睨んでいます．（かといって，head内にonsen.jsをおくと，崩れた表示になる．．．）
今の所，解決策が見つかりません．Help Me !!

###div要素のz-indexを変更しても，speed-dialより前面に表示できない
新着通知を前面に出そうとした時のエラーです．
speed-dialのz-indexが10000くらいなので，それよりも大きくすれば，全面に表示できそうなものですが．．．
現在は，ons-pageの外にdiv要素を置き，解決しています．

###iphoneだとアドレスバー・ブックマークバーが固定される
むむむ．
擬似的にスクロールアクションを起こせたら良いのですが，機能停止してるみたい．
ons-page要素がwindowを覆うようにしているので，このような自体になっているのだろう．

###長押しコピーができない
textareaでしかコピペができません．
非常に不便だ．

#おわりに
iosとandroidで自動で見た目が変わるって，すごいなぁ～
[GKE]SSL証明書を作成しIngressに追加する


# 背景

SSL証明書を作成して追記する際に留意事項があったので簡単にまとめておきます。


# 手順
基本的には公式ドキュメントの手順に沿っているのでそちらのリンクも参照してください。

https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs?hl=ja#setting_up_the_managed_certificate

大まかな手順は以下のようになります。

## ①GCPのCloudShellを開く

まずはGCPの画面上部で変更を反映したいプロジェクトを選択します。
そのプロジェクトを選択した状態でGCPのCloudShellを開いてください。
![スクリーンショット 2020-01-31 14.43.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408781/63c92067-53bc-14c9-5b6d-e497ce2b9555.png)
こちらのアイコンを選択するとページ下部にコンソール画面が表示されます。

## ②コンソール上でyamlファイルを作成し規定の内容を記載

コンソール画面が表示されたらtouchコマンドでyamlファイルを作成してください。
作成したyamlのファイルの中にこちらの内容を記載します。

```yaml:example-certificate.yaml
apiVersion: networking.gke.io/v1beta1
kind: ManagedCertificate
metadata:
  name: example-certificate
spec:
  domains:
    - example.com
```

apiVersionとkindを書き換える必要はありません。ここではmetadataのnameとspecのdomainだけを書き換えます。
nameの部分は**yamlのファイル名**、domainsは**SSL証明書を発行したいdomain**を記載します。

## ③applyコマンドで証明書を作成

yamlファイルに必要な情報を記載したらapplyコマンドでGKEに反映させましょう。
**この時同じyamlファイルが存在する場合はerrorが起こるので確認してからコマンドを打ちましょう**

```
kubectl apply -f example-certificate.yaml
```

## ④GCPで証明書の名前を確認しコピー

GCPのナビゲーションメニューからネットワークサービスに移動し、プロジェクトの証明書が確認できるページまで移動してください。
ページ上部の検索を使うのが一番早いですが、念の為具体的な移動方法も記載しておきます

ネットワークサービス　→　負荷分散　→　ページ下部の詳細設定メニュー → 証明書タブ

先ほどご紹介した③の手順まで成功していれば、一覧画面にこのような証明書が追加されてるはずです。
この**左側が証明書の名前**です。これをIngressに追加するためにコピーします。
![プロビジョニング.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408781/5692f6c4-a18f-72f6-92b6-a75d5d07d71b.png)


## ⑤Ingressのyamlファイルに追記

④の手順が終了したらGKEのServicesとIngressを選択します。
Ingressを選択したらyamlファイルを開きましょう。開いたyamlファイルの中に`ingress.kubernetes.io/ssl-cert`という項目があるので、この部分に先ほどの④でコピーした証明書の名前を貼りつけます。

![certs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408781/0605d21d-b6cc-4e58-0df4-ad9db733a5b5.png)


正常に動作しているかどうかは証明書一覧のページで確認します。
証明書のステータスがプロビジョニングの状態から**有効**になっていたらSSL証明書の追加完了です。
(Rails)resourcesの7つ道具

Railsで定義されるresources7つ。
非常に重要で覚えておくと役に立つとのことなので記載しておきます。

|  アクション名　　　　 |   どのような時に動作するか 　                 |  
|:-----------------|----------------------------------------:|
| index            |     一覧表示ページを表示するリクエストに対応して動く|        
| new              |    新規投稿ページを表示するリクエストに対応して動く |       
| create           |         データの投稿を行うリクエストに対応して動く |    
| show             |    個別詳細ページを表示するリクエストに対応して動く |         
| edit             |    投稿編集ページを表示するリクエストに対応して動く |       
| update           |          データの編集を行うリクエストに対応して動く|     
| destroy          |          データの削除を行うリクエストに対応して動く|
バッチファイルでPostgreSQLデータベースをバックアップしたい話


環境：Windows10 Pro 1909， PostgreSQL10.0

- やりたいこと

　実行するだけでdumpファイルをとりたい。

　何度実行しても問題がないようにしたい。

- 実際のバッチファイル

※　DB接続情報は実際の環境に合わせて書き換える前提

```bat
REM //戻り値
SET C_OKRET=0
SET C_NGRET=1

REM //ＤＢ接続情報
SET PGHOST=localhost
SET PGPORT=5432
SET PGDATABASE=dbname
SET PGUSER=dbuser

REM //バックアップディレクトリ設定(カレントディレクトリ)
SET BACKUP_DIR=%~dp0

REM //日付情報(バックアップディレクトリに付与する年月日時分秒を取得)
SET TMPTIME1=%TIME: =0%
SET TMPTIME2=%TMPTIME1:.=%
SET NOWTIME=%TMPTIME2::=%
SET NOW=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%_%NOWTIME:~0,6%

PUSHD %~DP0

REM //タイムスタンプのあるフォルダの作成
MKDIR %BACKUP_DIR%\%NOW%

REM //バックアップ実行
pg_dump -h %PGHOST% -U postgres -c %PGDATABASE% > %BACKUP_DIR%\%NOW%\%PGDATABASE%.dump


REM //エラー発生時はカレントディレクトリにログを出力
IF %errorlevel% neq 0 (

  ECHO %date% %time:~0,8% 実行に失敗しました  ErrorCode=%errorlevel%^
  FileName「%SQLFILE%」 >> %~DP0\psql_log.txt
  POPD
  EXIT /b %C_NGRET%

) ELSE (

  POPD
  EXIT /b %C_OKRET%

)
```

バッチファイルの終了を「EXIT /b ～」とすることで、呼び出し元へステータスを返せるように指定。

なお、返り値は数値であることに注意。
SQLAlchemyのfilterでDATE_FORMATを使用する

# はじめに
SQLAlchemyのクエリでdate_formatを使った条件文を作った際にハマったのでメモ残し。

# やり方

``` python
from sqlalchemy import func

User.query.filter(
    func.date_format(User.date, "%Y-%m-%d") == day.strftime("%Y-%m-%d")
)
```

# 終わりに
funcにはcountだったりcurrent_timestampだったりとが入っているので、困ったらドキュメント見ると解消する確率が高いと思います。

https://docs.sqlalchemy.org/en/13/core/functions.html
ImageMagickで画像のサイズ変更

#はじめに
開発環境：Mac
ImageMagickを使って画像のサイズ変更を行なってみたいと思います。

##ImageMagickとは
[ImageMagick]( https://www.imagemagick.org/script/index.php"ImageMagick")
ImageMagickを使ったWEBサービスを作成する際に、一番利用頻度が高いと思われる画像のサイズ変更です。また、コマンドラインから完全に使用されるため、1回限りの画像サイズ変更に便利です。



##手順
<details><summary>ImageMagickインストール</summary>

```com:Terminal
brew install imagemagick
```
</details>

<details><summary>画像のサイズを元のサイズの33％に変更するには、ターミナルで次のコマンドを実行します。
</summary>

```terminal:Terminal
例　convert -resize 33% flower.jpg flower-small.jpg
```
</details>

<details><summary>幅300px、高さ200pxに収まるように画像のサイズを変更するには、次のコマンドを実行します。</summary>

```terminal:Terminal
convert  <変換前の画像名>  -resize   (width)x(height)  <変換前の画像名>
例　convert before.jpg -resize 320×200 after.jpg
```
＊(width)、(height)はピクセル数を数字で指定します。
</details>



<details><summary>画像サイズの一括変換(mogrify)
 </summary>

```terminal:Terminal
mogrify   -resize   (width)x(height)  <変換前の画像名>
例　mogrify -resize 320×200 *.jpeg 
```
mogrifyを使用した場合、基本的に生成後の画像は、生成前の画像に上書きされます。

画像名を*(ワイルドカード)にすることにより、同一フォルダ内のすべての画像を一括変換することができます。
 
</details>

<details><summary>geometry,thumbnailを使用したサイズ変更
 </summary>
ImageMagickでは、-resizeの他にも画像サイズを変更することができるコマンドが用意されています。

```terminal:Terminal
convert before.jpg -geometry 30% after.jpg
```
-geometryに関しては、合わせるコマンドによって振る舞いが変わるという仕様があるため、-convert以外のコマンドと使用する際には注意が必要です。

ImageMagickでは、-resizeの他にも画像サイズを変更することができるコマンドが用意されています。

</details>


#おわりに
ImageMagickで簡単にサイズ変更ができました。
[Android] zxingでQRコード画像から読み取る

QRコードを含む画像からの読み取りを、zxing を使って行ってみました。
[ZXing Android Embedded](https://github.com/journeyapps/zxing-android-embedded)

```Java
void readQrcode(Bitmap bitmap) {
    // Bitmap のサイズを取得して、ピクセルデータを取得する
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    int[] pixels = new int[width * height];
    bitmap.getPixels(pixels, 0, width, 0, 0, width, height);

    try {
        // zxing で扱える BinaryBitmap形式に変換する
        LuminanceSource source = new RGBLuminanceSource(width, height, pixels);
        BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
        // zxing で画像データを読み込み解析する
        Reader reader = new MultiFormatReader();
        Result decodeResult = reader.decode(binaryBitmap);
        // 解析結果を取得する
        String result = decodeResult.getText();
        Log.d("readQR", result);
    } catch (Exception e) {
        Log.d("readQR", e.getLocalizedMessage());
    }
}
```
ファイルから読み込んで Bitmap を取得する部分は省略します！
[Objective-C]文字列一覧を文字列の部分検索する

「名前に検索文字列の一部でも入っていたら検索結果にだしてー」という内容。

元のコードで長ったらしー階段コードがあったので書き直す。こんな感じかなー。
Swiftならもっと簡単に書けるんだけどなー。

```objc
    
NSString* str = @"一二三四五";
NSArray* nameList = @[@"一ノ瀬",@"五十嵐",@"山田",@"二宮",@"佐藤",@"一二"];
NSMutableArray* results = @[].mutableCopy;

for (NSString* name in nameList){
    [str enumerateSubstringsInRange:NSMakeRange(0, str.length)
                            options:NSStringEnumerationByComposedCharacterSequences
                         usingBlock: ^(NSString* substring, NSRange substringRange, NSRange enclosingRange, BOOL* stop) {
        if ([name containsString:substring] && ![results containsObject:name]) {
            [results addObject:name];
            *stop = YES;
        }
    }];
}

for (NSString* result in results){
    NSLog(@"result = %@",result);
}
```
結果

```
result = 一ノ瀬
result = 五十嵐
result = 二宮
result = 一二
```
作ったアプリをGoogle Playストアに公開する方法(AndroidStudio編)

　あけましておめでとうございます！(激遅)
ようやく日記アプリが完成しました。そこで完成したアプリを公開する方法を備忘録も兼ねて紹介します。

　それと以前、[国民の祝日を表示する](https://qiita.com/ysk75/items/0d045cc744d372e984b1)のを紹介しましたが第〇月曜のところが間違っていたので修正版を後日載せておきます。

## Android Studio側でやること

　まずはアプリをアップロードするために専用のファイルを作成します。
1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534506/702cf1fd-b914-6e29-766b-fff0f77844ce.png)
BuildのGenerate Signed Bundle / APK...をクリックします。

2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534506/63c68970-f5ef-bd93-4b25-fb59511f6fa0.png)
　するとAABファイルかAPKファイルのどちらかを作成するかを聞かれます。このファイルはデジタル署名という誰が作ったのか、改竄されていないかを確認するためやソースコード、画像等アプリには欠かせない情報がまとまっています。今回は上の **Android App Bundle**(AABファイル)を選択しNextを押します。

3
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534506/796929dd-bb20-bda7-96ff-714ed56549b3.png)
　次にKey storeをどこに作るかを聞かれます。最初は何も書かれていないので **Create new...** をクリックしましょう。

4
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534506/164adf3a-3efd-4461-749d-cef2d7477634.png)
　一応画像が見えずらい場合があると思うのでこっちでも書いておきます。 **Key sotre path** はjksファイルをどの場所にどのような名前で保存するかを設定します。 **Alias** はキーの別名なのでそのアプリの分かりやすい名前を。**Validity(years)** はキーの有効期限で25年(デフォルト)以上が推奨されています。**Certificate** は上から作者名、組織単位、組織名、市町村名、都道府県名、国コードとなっており最低でも1つは入力してください。僕の場合は作者名、都道府県名、国コードは入力するようにしています。
　このキーストアはデジタル署名をするための鍵と証明書をまとめたデータとなっています。パスワード等、漏れがないよう気を付けてください。

5
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534506/69fd0233-4736-4283-3a1b-83a0ba8d0270.png)
　OKを押した後このようになると思いますので、Nextを押しましょう。

6
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534506/4e41a437-df50-d1df-9f73-2ff48bb73e26.png)
　releaseを選択してFinishを押します。

7
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534506/3f4de476-df6f-c4ec-08a9-950eb3572e10.png)
　ファイルの生成に成功するとこのような通知が来るのでlocateをクリックすることでAABファイルの作成フォルダが開かれると思います。もし、通知が消えてしまっても↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534506/a4ba5e0d-9688-3bae-4e46-4c4383c87ca5.png)
一番右下にある **Event Log** をクリックすることで通知を確認することができます。

　以上でAndroidStudio側の設定は完了です！お疲れさまでした。次回はGooglePlayConsole側の設定です。アプリのアイコン、スクリーンショット等が必要で大きさに制限があるのでそちらも含め解説していこうと思います。翌日(2020/2/1)には上げますのでよろしくお願い致します。
**(2020/2/1)追記** GooglePlayConsole編を上げました→ [作ったアプリをGoogle Playストアに公開する方法(GooglePlayConsole編)](https://qiita.com/ysk75/items/fe2e64478b295bde93e3)
Docker daemon.jsonにlog max-sizeを指定しても既存テナントには適用されない

# 概要

`daemon.json`を以下のように設定し、Dockerサービスを再起動しても既存コンテナには指定したログサイズで**自動ローテーションされない**！
なので、daemon.jsonだけを設定して安心しているといつの間にかログで圧迫死になりますので、ご注意ください！


# どうすればいいのか？

daemon.jsonを設定後に**新たに生成したコンテナのみに適用される**！

コンテナごとにログドライバーの設定が可能なので、コンテナごとに設定値が保持されているのは理解できるが、未指定の場合は、daemon.jsonに従ってほしい気持ちもあります。コンテナの再作成コストはないからこの辺は割り切りでよいかも


# 検証手順

1. daemon.jsonを設定し、サービスを再起動（`max-size:1k`）
2. nginxを起動 (`docker run -d nginx`)
3. `curl http://localhost`
4. `ls -lh /var/lib/docker/containers/<nginxのコンテナID>/<nginxのコンテナID>/<nginxのコンテナID>-json.log`のサイズを確認
5. ログサイズが`1k`になるまで、手順3を繰り返す
6. 指定した`1k`で`/var/lib/docker/containers/<nginxのコンテナID>/<nginxのコンテナID>/<nginxのコンテナID>-json.log.1`が生成されたらOK
7. daemon.jsonの`max-size:2k`に編集し、サービスを再起動
8. 停止したnginxコンテナを`docker start`する
9. 手順3、4で`1k`でローテーションしないことが確認できる（予めログを削除しても結果は変わりません）


```json:/etc/docker/daemon.json
{
    "log-driver": "json-file",
    "log-opts": {
      "max-size": "10k",
      "max-file": "2"
    }
}
```

検証環境

```shell
Server Version: 18.09.9-ce
Storage Driver: overlay2
 Backing Filesystem: xfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 894b81a4b802e4eb2a91d1ce216b8817763c29fb
runc version: 2b18fe1d885ee5083ef9f0838fee39b62d653e30
init version: fec3683
Security Options:
 seccomp
  Profile: default
Kernel Version: 4.14.154-128.181.amzn2.x86_64
Operating System: Amazon Linux 2
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 1.91GiB
Name: hogehoge
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false
```
【VBA】入力規則(Validation) エラー1004 その他の原因

『 [入力規則（Validation）の1004について] (https://qiita.com/dandelion4/items/33d849ec51424aff0814) 』と同じようにハマり、
また別の原因だったので追加メモを。

##既知の解決方法

・設定(Add)前に、Validation オブジェクトを Delete する
・シート保護を解除する (共有も？)

##その他の原因と解決例

こんな設定をしようとして...

```vb
	With Cells(3, 2).Validation
	    .Delete
	    .Add Type:=xlValidateList, _
	        AlertStyle:=xlValidAlertInformation, _
	        Formula1:="=Sheet!$B$3:$B$10"
	    .InCellDropdown = True
	    .ShowInput = False
	    .ShowError = True
	End With
```

やはり Add の箇所で、エラーになるときがある(ならないときもある)。

この場合、オプションの [数式の処理]>[R1C1 参照形式～ ]が
有効になっていると NG でした。

そっかー 参照形式(A1/R1C1)を合わせなきゃいけないのか
条件付き書式でも似たようなことになるのかしら

コード書いてるときは、作ったアイコンで頻繁に切り替えてるから
どっちでも動いてほしいところだけど

```vb
	Application.ReferenceStyle = xlA1
```

.Add の前、.Delete の前後あたりに上記を入れて強制し
解決としました。
※本当は[参照形式]の状態を調べて、分岐なり復元したほうがよい
<br>
2020.2.4 追記
@nukie_53 さんに教えてもらった方法

```vb
	.Add Type:=xlValidateList, _
		AlertStyle:=xlValidAlertInformation, _
		Formula1:=Application.ConvertFormula("=Sheet!$B$3:$B$10", _
		xlA1, Application.ReferenceStyle)
```
これなら[参照形式]の状態に合わせて渡すので、前後の処理不要。
Excelアプリケーション全体にかかるオプションを、変更せずに済むところが特によい。
Go言語のlogパッケージ

logパッケージを使用すると日付と時間とメッセージを表示させることができる。

## log.Print

- log.Print
- log.Printf
- log.Println

3種類あるが、内容的にはfmtと同じ、先頭に日付が入るだけ。

```go
package main

import("log")

func main(){
	log.Print("ログやで")
}
```

## log.Fatal

何かエラーが発生した場合にログを表示してプログラムを終了させたい場合はFatalを使用する。Fatalも3種類ある。

- Fatal
- Fatalf
- Fatalln

```go
func main(){
    r, err := ioutil.ReadFile("text.text")

	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(r)
}

// 2020/01/31 15:39:11 open text.text: The system cannot find the file specified.
```
webpacker でページごとにスタイルを分ける

こんにちは、 streampack の minsu です。
東京オリンピックが決まった時はまだまだ先だと思っていた2020年が来ましたね！あまり実感がないですが！

## はじめに
ページごとに読み込まれるcssとjsを変更したいことがあるかと思います。
RailsでWebpacker利用時にページごとにcss,jsのスタイルを分ける方法をまとめました。

作業内容は次の通りです。
・エントリポイントを複数作成する
・ページごとに対応するエントリポイントを呼び出す

また、こちらの過去の記事の環境を使っています。
[Docker + Rails + React](https://qiita.com/minsu/items/0ccbafff460e72b13d44)

## ファイル構成

### Webpackerディレクトリ構成

Webpackerのconfigを見てみると
`app/javascript` にjs,cssを
`app/javascript/packs`にエントリポイントを配置し
ビルド後のファイルは`public/packs`に格納されるようになっています。

```config/webpacker.yml
default: &default
  source_path: app/javascript
  source_entry_path: packs
  public_output_path: packs
...
```

さて現在の`app/javascript`ディレクトリのファイル構成です。

```
app/javascript                                                                                                                                     
├── components           
│   └── users
│       ├── Edit.js
│       ├── Index.js
│       ...                                                                                  
├── packs
│   └── application.js 
└── src
    ├── js
    │   └── application.js 
    └── css
        └── application.css 
```
configの通り`packs/application.js`がエントリポイントとなります。
`src`にはcss, jsファイルを、
`components`には`react-rails`gemを使っている関係でReactファイルを配置しています。

### エントリポイント

```application.js
var componentRequireContext = require.context("components", true);
var ReactRailsUJS = require("react_ujs");
ReactRailsUJS.useContext(componentRequireContext);

import "src/js/application.js";
import "src/css/application.css";
```
エントリポイントである `packs/application.js`を見てみます。
上3行の`components`ディレクトリのReactファイルをRails view側から呼び出すための`react-rails`の記述と
下2行の`src`のjs,cssファイルimportの記述があります。

ビルド後はこの情報を元にjs,cssがひとまとめのファイルとなります。
そのため、Rails側の下記コードでエントリポイントを指定する事で

```application.html.erb
<%= javascript_pack_tag 'application' %>
<%= stylesheet_pack_tag 'application' %>
```
viewからReactファイルの利用と、
`src/js/application.js`,`src/css/application.css`の読み込みを行えます。

viewからReactを利用するのに必要ですのでエントリポイント `application` は全てのページから共通で呼び出すようにします。

## エントリポイント作成
本題ですがページごとに読み込まれるcssとjsを変更したい場合を考えます。
この場合、packs/application.jsのエントリポイントにimportを追加すると全てのページに反映されてしまい都合がよくありませんので、新たにエントリポイントをして必要なページから呼び出すようにします。

```packs/users/index.js
import "src/js/index.js";
import "src/css/index.css";
```

```index.html.erb
<%= javascript_pack_tag 'users/index' %>
<%= stylesheet_pack_tag 'users/index' %>
```

上記のようなエントリポイントを作成して必要なviewなどから呼び出す事で、
必要なページでのみスタイルを反映させることができます。

### ファイル構成

```
app/javascript                                                                                                                                     
├── components           
│   └── users
│       ├── Edit.js
│       ├── Index.js
│       ...                                                                                    
├── packs
│   ├── application.js 
│   └── users
│       └── index.js
└── src
    ├── js
    │   ├── application.js 
    │   └── users
    │       └── index.js 
    └── css
        ├── application.css 
        └── users
            └── index.css
```

## 参考
https://github.com/rails/webpacker
https://github.com/reactjs/react-rails
DatadogAPMをOpencensusで活用しよう（ログとトレースの紐付け）

# はじめに

こんにちわ、すえけん([@sueken5](https://twitter.com/Sueken51))です。

この記事ではDatadogAPMのトレースにログ情報を付随させる方法を書きます。

![スクリーンショット 2020-01-31 15.42.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263369/376b276f-fff0-b1d9-4a11-a15bef15fc48.png)

このようにログとトレースを紐付けると簡単にデバックできるのでとてもおすすめです。

# 紐づけるには

datadog APMとログを紐づけるにはログにtrace_idとspan_idをつける必要があります。実際のログは次のような感じです。

```
{"level":"DEBUG","ts":"2020-01-31T15:33:52.042+0900","msg":"hello world","dd.trace_id":10034860525566454582}
```

datadogの予約語？にdd.trace_idとdd.span_idがありますのでそれにidを入れます。

# datadog用にTraceID/SpanIDを取得しよう

ここでハマったのですがTraceID/SpanIDは文字列の状態で送ってもうまくTraceIDが違い、トレースとログがくっつきません。なので次のようにします。

```go
	spanCTX := trace.FromContext(ctx).SpanContext()
	fields = append(
		fields,
		zap.Uint64("dd.trace_id", binary.BigEndian.Uint64(spanCTX.TraceID[8:])),
		zap.Uint64("dd.span_id", binary.BigEndian.Uint64(spanCTX.SpanID[:])),
	)
	l.logger.Error(msg, fields...)
```

spanContextからTraceIDをとりbinaryパッケージを使って処理します。このやり方はdatadogのexporterのTraceIDの取得のやり方を参考にしています。

```github.com/DataDog/opencensus-go-exporter-datadog/span.go
func (e *traceExporter) convertSpan(s *trace.SpanData) *ddSpan {
	startNano := s.StartTime.UnixNano()
	span := &ddSpan{
		TraceID:  binary.BigEndian.Uint64(s.SpanContext.TraceID[8:]),
		SpanID:   binary.BigEndian.Uint64(s.SpanContext.SpanID[:]),
		Name:     "opencensus",
		Resource: s.Name,
		Service:  e.opts.Service,
		Start:    startNano,
		Duration: s.EndTime.UnixNano() - startNano,
		Metrics:  map[string]float64{},
		Meta:     map[string]string{},
	}
        // 省略
}
```

この通りやるとトレースとログが紐づくようになります。

# まとめ

トレースとログが紐づくっと一気にデバックがしやすくなります。おすすめです。
緑落ちした感想と、緑落ちしないために

**※この記事は最近よく見る上質な記事とは違い、クオリティーがとても低いです。このことを念頭において、この記事を読んでください。**

たまたま水色になれてやったぜって思ってたら下のようなことになってしまったので、感想と競プロをこれからやる人にこんな経験をしないように注意喚起（？）をしたいと思います。

![Screenshot_2020-01-30 AItale - AtCoder.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438556/a761fa13-d86d-7c84-3c5b-b01d39871ea9.png)


#緑落ちした感想
これは今言ってももう遅いことなんですが、もっと頑張ってたらよかったっていう気分になっています。

#緑落ちしないために必要なこと
##コンテスト後にはちゃんと復習する
これはとても大切です。全然分からなかった問題に関しては、ちゃんと理解してから通しましょう。コンテストの後にすぐ寝てしまうという人は、明日の朝にスマホなりなんなりで確認しましょう。

##苦手な傾向の問題を解く
苦手な傾向の問題（ex.貪欲法、DP、構築…）をほったらかしにしておくと、それがコンテストで出たときに大爆死してレートを溶かしてしまうことがあります。なので、なるべく苦手な傾向の問題を解いていきましょう。また、問題が傾向ごとに分けられている[AtCoder Tags](https://atcoder-tags.herokuapp.com/)という便利なサイトがあるのでぜひ活用しましょう。

##DPから逃げない
上と似ていますが、これはDPが苦手と思っていない人でもとても大切です。JOIでもDPは結構出ます。（現に今年のJOIの4問目でもDPの問題が出ました）DPから逃げると、下の画像のようなことが起こります。（この時に出題された問題: [E - Crested Ibis vs Monster](https://atcoder.jp/contests/abc153/tasks/abc153_e)）

![Screenshot_2020-01-30 コンテスト成績証 - AtCoder.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438556/2a727fb4-2597-6855-38c4-da7d8dc56be8.png)


DPは、[Educational DP Contest](https://atcoder.jp/contests/dp)という典型中の典型のDPがたくさん収録されているコンテストがあるので、これのH、Iぐらいまでを解いて、ソラでコードが書けるようにしましょう。

##積ん読をしない
積ん読とは、本を買ったはいいものの「いつか読もう」と思ってしまい、結局その本を読まないことを指します。今、僕は螺旋本を積ん読しています。絶対にやめましょう。積ん読をしても何にも成果は得られません。ぼちぼち消化しましょう。

##ゲームにのめりこまない
特にSteamゲー（Portalとか）とアイワナ系にはまってしまうと精進の時間が無くなるので気を付けましょう。


というわけで、ダラダラと緑落ちしないための方法を書き連ねていきました。
[これ](https://www.creativ.xyz/dont-say-lazy/)も参考にしながら、ぼちぼち水色に戻ります。
npm install で permission denied

### 状況

laravelで```npm install```によりパッケージをインストールしようとしたら、permission deniedのnpm ERR!

<img width="715" alt="スクリーンショット 2020-01-31 15.18.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/12407a92-4532-c43d-e490-927a1b1181ab.png">


## 解決できなかった方法

とりあえずググって[npmでpermission deniedになった時の対処法[mac]](https://qiita.com/okohs/items/ced3c3de30af1035242d)を参考に、node_moduleを削除してもう一回やったりしても同じエラーが出続ける。


## 解決法

エラー文の、

```
npm ERR! path /Users/tagawahirotaka/Desktop/vuesplash/laravel/node_modules
```

に注目し、階層を移動。

すると、
<img width="691" alt="スクリーンショット 2020-01-31 15.18.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/8284b4c0-63de-b24d-6033-e4c463feb424.png">
権限がない！！！

```sudo chown tagawahirotaka node_modules```
で無事に解決。

と思ったが、

<img width="714" alt="スクリーンショット 2020-01-31 15.20.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/ebaae4a1-8ca5-ad29-cee8-abfe0c95dbe5.png">
もう一個のnode_module!!
<img width="686" alt="スクリーンショット 2020-01-31 15.21.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/44283abf-afb1-4e0d-f184-49be9691ffa3.png">

お前もかい！！

同じ方法で権限を与えて無事解決。

### 追記

``` sudo chown -R tagawahirotaka ~/desktop/vuesplash/laravel/node_modules```で一括変更したら早い。
MySQL Not null 制約を外したい

# Not Null を外したくなった背景
- アルバイトでCMSを触っている。
- ユーザー情報管理画面で新規登録する時、必須項目があった。
- 必要がなくなったので必須条件を外しといてくれと頼まれた。(input要素の*required*を*false*にするだけ)
- データベース側で入力値が空(null)を許容していなかったため怒られた。

＝＞ 制約変えなきゃ。

# カラムの制約の確認方法

```SQL
desc /*テーブル名*/;
```

# 解決法

```SQL
ALTER TABLE /*テーブル名*/ MODIFY COLUMN /*カラム名*/ /*型*/;
```

# 終わり
逆に not null 制約を付けたいときは

```SQL
ALTER TABLE /*テーブル名*/ MODIFY COLUMN /*カラム名*/ /*NOT NULL*/;
```
filter: drop-shadow() の影を濃くする

透過pngにもオブジェクトの形に沿ってドロップシャドウをかけてくれるdrop-shadow()関数。
ただ、ぼかしを1〜2px、影の色をblackにしても「なんかちょっと弱いな」と感じることがあったので、もっと濃くできないか調べてみた。

https://developer.mozilla.org/ja/docs/Web/CSS/filter
どうやらfilterは組み合わせて使えるらしい。

なのでdrop-shadowに更にdrop-shadowを組み合わせてみた。

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="css,result" data-user="suburbia" data-slug-hash="povXWyd" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="deepen &amp;quot;drop-shadow()&amp;quot;">
  <span>See the Pen <a href="https://codepen.io/suburbia/pen/povXWyd">
  deepen &quot;drop-shadow()&quot;</a> by 和井内 洋介 (<a href="https://codepen.io/suburbia">@suburbia</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

できた。
素晴らしい。
役に立ったヘルプサイトなど(随時更新中)

毎日とはいわないけど忘れたころに使う羽目になりそうなサイトを自分用にメモいたしました。


###git関連
(1)[【Windows資格情報削除で解決】git-pushで403エラーが出る時の解決法](https://wak-tech.com/archives/933)

(2)[Git マージコミットをrevert後に再度マージしたいけど差分が出ない時には](https://chooringo.hatenablog.com/entry/2017/03/26/225718)

(3)[CodeCommit上のリポジトリでmasterブランチへのプッシュを禁止してみる](https://dev.classmethod.jp/cloud/codecommit-deny-push-mster-branch/)

(4)[GitFlowは使わない！シンプルな「GitFeatureFlow」を紹介します](https://developers.gnavi.co.jp/entry/GitFeatureFlow/koyama)

##python関連
(1)[datetimeとjpholidayを組み合わせて、平日か土日祝日かを判定するスクリプト](https://qiita.com/hid_tanabe/items/3c5e6e85c6c65f7b38be)