OmniAICreator/Qiita-1.07M huggingface dataset:
2つのテーブルを１対多の関係になるようadd_referenceするとSQLite3::SQLException: Cannot add a NOT NULL column with default value NULL


「現場で使えるRuby on Rails5速習実践ガイド」を進めていて、P.169の　マイグレーションを実行すると以下のエラーが発生しました。

```shell
/taskleaf:$ bin/rails db:migrate
== 20210524174653 AddUserIdToTasks: migrating =================================
-- execute("DELETE FROM tasks;")
   -> 0.0009s
-- add_reference(:tasks, :user, {:null=>false, :index=>true})
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

SQLite3::SQLException: Cannot add a NOT NULL column with default value NULL: ALTER TABLE "tasks" ADD "user_id" integer NOT NULL
...
（省略）
```

# 試したこと

どのマイグレーションファイルまで実行されたかを確認したくて調べたところ、以下のコマンドで確認できそうでした。

`bundle exec rake db:migrate:status`

実行すると

```shell
/taskleaf:$ bundle exec rake db:migrate:status

database: /Users/{ユーザID}/workspace/runteq/genba_rails/taskleaf/db/development.sqlite3

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20210517160153  Create tasks
   up     20210521153755  Change task name not null
   up     20210521160018  Change tasks name limit30
   up     20210521172340  Create users
   up     20210521175601  Add admin to users
  down    20210524174653  Add user id to tasks

```

どうやら直近（P.169）で作成したマイグレーションファイルが実行できず、ロールバックされていそうです。

エラーログに戻ると、

```
SQLite3::SQLException: Cannot add a NOT NULL column with default value NULL: ALTER TABLE "tasks" ADD "user_id" integer NOT NULL
```

英語が目にくるのでDeepL翻訳にかけたところ

```
SQLite3::SQLException: デフォルト値がNULLのNOT NULLカラムを追加できません: ALTER TABLE "Tasks" ADD "user_id" integer NOT NULL
```

らしいです。

# 原因

書籍ではDBにPostgreSQLを指定してアプリを立ち上げていましたが、SQLiteで進めていたことが原因のようです。

> 当然である．NOT NULL な column なのに default を指定しなければ，もし行が既に存在した場合その 
column (今回は price) が NULL にならざるを得ないではないか．

> しかし PostgreSQL だとこれが通るのである．先のコマンドを以下のように変えて見ると分かる．

# 解消した方法

マイグレーションファイルを以下のように修正しました。
add_referenceを実行したあと
後からnot null制約をつける（change_column_null）ことで正常にマイグレーションが実行できました。
（コメントアウト行がエラー発生した書籍どおりのコードです。）

```ruby
class AddUserIdToTasks < ActiveRecord::Migration[5.2]
  def up
    execute 'DELETE FROM tasks;'
    # add_reference :tasks, :user, null: false, index: true
    add_reference :tasks, :user, index: true
    change_column_null :tasks, :user_id, false
  end

  def down
    remove_reference :tasks, :user, index: true
  end
end

```


# 参考資料

https://qiita.com/ka_/items/29c0f0de27c63a8a090e

https://tech-essentials.work/questions/210
Android Studioでエミュレータが起動しない

<h1>failed to install the following android sdk packages as some licences have not been accepted.</h1>

Android Studioでエミュレータを起動しようとした際に、下記のようなエラーが発生した。

```console
FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':app:compileDebugJavaWithJavac'.
> Failed to install the following Android SDK packages as some licences have not been accepted.
     build-tools;29.0.2 Android SDK Build-Tools 29.0.2
  To build this project, accept the SDK license agreements and install the missing components using the Android Studio SDK Manager.
  Alternatively, to transfer the license agreements from one workstation to another, see http://d.android.com/r/studio-ui/export-licenses.html

  Using Android SDK: /Users/username/Library/Android/sdk

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 5m 25s
Checking the license for package Android SDK Build-Tools 29.0.2 in /Users/username/Library/Android/sdk/licenses
Warning: License for package Android SDK Build-Tools 29.0.2 not accepted.
Exception: Gradle task assembleDebug failed with exit code 1
```

<h2>原因</h2>

エラー文を読むと、Android SDK (build-tools 29.0.2) のライセンスに同意していないとのこと。

あれ？もしかして…。と思い、ターミナルで下記コマンドを実行し、flutterの環境を調べてみると、以下の結果が返ってきました。

```
$ flutter doctor

--- 一部抜粋 ---

[!] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
```

やっぱりって感じでしたw

<h2>解決方法</h2>

`$ flutter doctor` を実行した際に、返ってきた以下の文を参考にすれば解決できました。

`Run flutter doctor --android-licenses to accept the SDK licenses.`

ということでターミナルを開き、以下のコマンドを実行。

```
$ flutter doctor --android-licenses
```

<h2>上記で解決できない場合</h2>

上記方法で解決できなかった場合、ターミナルでAndroidのSDKのあるディレクトリに移動して、ライセンスをAccept。

```
$ cd ~/Library/Android/sdk/tools/bin

$ ./sdkmanager --licenses
```

上記コマンドを実行後、下記の文が表示されるので、`y`を入力してEnter。

```
Review licenses that have not been accepted (y/N)？
```

上記より、Acceptされていないライセンスが順に表示されるので、
全て下記のところで `y` を入力してEnter。

```
Accept? (y/N)
```

最終的に下記の文が表示されれば完了です。

```
All SDK package licenses accepted
```
日本語配列キーボードのノートPCに英語配列キーボードを接続

#背景
在宅勤務するようになったので、自宅ではUSB接続した左右分離キーボードを使用し、打ち合わせ等で出るときにはノートPCのキーボードを使うという環境になりました。
ノートPCは社給品で当然のようにキーボードは日本語JIS配列な訳です。
外付けキーボードも日本語配列なら何の問題も無い（当初はLogicoolのK360を使用で問題なし）のですが、手の負担軽減のために左右分離キーボードを導入しようとすると、日本語配列の物って少なくて中々良い感じの物が見つかりません。
で、結局US配列のMiSTELのMD770を入手しました。
英語配列自体は昔使用していたので、OSの設定で英語キーボードにしてしまっても問題無いのですが、出来ればどちらもキーボードにの表記通りに使いたいじゃないですか。

#どうした
検索すると、レジストリエディタで個別設定したいキーボードの設定に、`KeyboardTypeOverride`と`KeyboardSubtypeOverride`を設定すれば可能との情報が多数ヒットしました。
が、それと同時にWindows10 1809以降ではこの設定が効かなくなったとも...
設定してみても確かに効かない（Windows10 20H2）。

色々と調べた結果

- [ULE4JIS](https://www.vector.co.jp/soft/winnt/util/se476294.html)([GitHub](https://github.com/dezz/ULE4JIS))
- [alt-ime-ahk](https://github.com/karakaram/alt-ime-ahk)

の2つを導入することで快適な環境を入手出来ました。
両方共スタートアップに入れて自動起動するようにしておき、必要に応じてタスクトレイから有効/無効を切り替えています。

素晴らしいソフトウェアをありがとうございます
ワークスペースに修正が残っている場合に-dirtyが付加されたコミット番号を取得するgitコマンド

# 結論
下記コマンドを実行する

```bash
git describe --always --abbrev=40 --dirty
```
これは [Git command to get HEAD SHA1 with "-dirty" suffix if workspace is not clean - Stack Overflow](https://stackoverflow.com/questions/21017300/git-command-to-get-head-sha1-with-dirty-suffix-if-workspace-is-not-clean/21017394#21017394) に書いていた内容です。

# 不明点
`--match=NeVeRmAtCh` の意味。
Sequel で like 検索をする時に String に cast する方法

ruby の Sequel gem を利用して like 検索をする際には、検索のワードが String である必要があります。そのため、もし値が id カラム（Serial）に格納されている場合は下記のように Sequel.cast します。

```ruby:
id = 1
DB.where(Sequel.like(Sequel.cast(:id, String), "%#{id}%")).all
```

このようにすれば%で囲っているので部分一致検索になります。
ポイントは値を cast するのではなくカラムをcastすると記載するようです。
いろいろ探しましたが明快なものがなかったので、記事にしました。
【jQuery】フォームからフォーカスが外れたら値を整形する

### 環境

Rails 6
jQuery

## Solve

![test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189781/724890d9-5ab8-a760-2cf4-a86335c502dc.gif)


* フォーカスが外れたら前後の空白を削除して全角空白を半角空白へ置換
* フォーカスが外れたら小文字のアルファベットを大文字に変換

utilに書いた共通メソッドをincludeしてview側で必要なものだけ呼び出せます。
引数はid等セレクタを渡します。複数可。

```util.js
// 名前空間
var myUtil = {

  /**
   * フォーカスが外れたら前後の空白を削除して全角空白を半角空白へ置換
   * @param selectors {String} 文字列形式のセレクタ
   */
  trimBlank: function(selectors) {
    $(selectors).focusout(function(e) {
      var oriStr = $(this).val().replace(/　/g, " ");
      $(this).val($.trim(oriStr));
    });
  },

  /**
   * フォーカスが外れたら小文字のアルファベットを大文字に変換
   * @param selectors {String} 文字列形式のセレクタ
   */
  convertUppercase: function(selectors) {
    $(selectors).focusout(function(e) {
      var oriStr = $(this).val();
      $(this).val(oriStr.toUpperCase());
    });
  },

}

window.myUtil = myUtil;
```

```application.js
require('./custom/util')
```

```_xxx_form.html
<script>
  // 共通メソッド呼び出し
  $(function(){
    myUtil.trimBlank('#mail, #name');
    myUtil.convertUppercase('#name-en');
  });
</script>
```
3rd Party Cookieに依存しない（ポストCookie）広告配信環境の構築とGAM（Google Ad Manager）の連携

# はじめに
- この記事はインティメート・マージャ―で提供している pmt.js を利用して 3rd Party Cookie に依存しないでターゲティング広告を打つための方法を記載しています。

# 3rd Party Cookie に依存しないって何？
- Apple の ITP や Google Chrome の仕様変更の影響で、今後 3rd Party Cookie を使った広告配信が全デバイス的に難しくなっていきます。
- 3rd Party Cookie を使った広告が減ると、広告の表示単価が下がり、メディアさんの広告収入が減ってしまうことが予想されます。メディア運営をしている会社や広告収益をえて成り立っている会社にとっては死活問題となります。
- そう言った背景の中、Privacy Sandbox の FLoC を中心とした人を特定しないでターゲティング広告を打つ仕組みが世の中に提供され始めております。本記事では pmt.js という弊社が提供するブラウザ保有者の属性推定用 JavaScript を利用しターゲティング広告を打つ仕組みをまとめています。

# やりたいこと
- ブラウザに付与されている属性情報を取得できるようになる
- GAM（Google Ad Manager）に属性情報を連携して、属性に合わせた広告やPMPを設定できるようになる
 
# 導入方法

## サイト側の初期設定

- 利用する機能の選択が可能です。必要となる機能をご指定ください。
    - 属性情報の取得
    - GAM への属性情報の自動連携
 
- 弊社から提供させて頂いた pmt.js を `<head>` の可能な限り上部に設置します。

    
```html
<script type="text/javascript" src="https://dmp.im-apps.net/pms/＊＊＊＊＊/pmt.js"></script>
```

- デベロッパーツールを利用し、弊社から指定する Session Storage にデータが格納されていることを確認します。

## 属性情報の利用

- 特定のグローバル変数に、指定された属性情報がセットされます。取得した属性情報を各種ツールに連携してご利用頂くことができます。
    - リクエストされた環境を元にブラウザに蓄積されたデータを利用し、最適な値をセットしております。

- 属性情報を活用するには、IDと属性名の対応表が必要になります。弊社担当までお問い合わせください。


## GAMへの属性情報の連携と配信設定

- pmt.js を設置すると googletag.pubads().setTargeting() を使用してページレベルのターゲティングを設定します。 
これにより、GAM の Key-Value に属性情報が連携されます。

- https://admanager.google.com にログインする

- 新しくオーダーを作成し、属性情報に対応する　Key-Value　の情報を申し込み情報 / プロポーザル申し込み情報に設定する（例は男性を連携した場合の設定）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1560575/219daa37-ef3c-dcfd-d15e-a2d2a61b4492.png)

- 対象となる申し込み情報 / プロポーザル申し込み情報に配信をしたいクリエイティブを設定する

- 配信の優先度については純広告 / PMP / フィラーなどの差し込みたいレベルに合わせて配信設定をする

# こちらのサービスを試してみたい方は

- インティメート・マージャーの[ポストCookieソリューション問い合わせ窓口](https://lp.intimatemerger.com) へお問い合わせください。
- ビジネス要件などにつきましては、お問い合わせいただいたタイミングでご相談させてください。
[docker + laravel(PHP)] GETパラメータが取得できない

##環境
laravel 8.x
php 8.0

##問題
dockerのlaravel環境にて開発中にGETパラメータが取得できない問題に遭遇しました。以下を例に問題を示します。

```php
<a href="{{ route('foo', ['bar' => 'baz']) }}">foo</a>
```
このように、barという名前でbazを渡すようにしました。しかし、実際にrequestの中身を確認すると、

```php:dd($request)抜粋
  +request: Symfony\Component\HttpFoundation\InputBag {#51 ▼
    #parameters: []
  }
```
値が渡されていません！

##原因
試しにMAMPで再現してみたところこちらでは正常に動作しました。ということはdockerに問題がありそうですね。

##解決
nginxの`default.conf`に以下の記述を`location / {}`内に追加してください。

```nginx
try_files $uri $uri/ /index.php?$query_string;
```

コピペをお勧めします。私はindex.phpの後ろの?をつけ忘れていたため、長い間苦しみました......

追加したら、nginxの再起動を忘れずに！

これで元に戻りました！

```php
  +request: Symfony\Component\HttpFoundation\InputBag {#51 ▼
    #parameters: array:1 [▼
      "foo" => "baz"
    ]
  }
```
【メモ】scikit-learnのモデル名取得方法

* 製造業出身のデータサイエンティストがお送りする記事
* 今回はメモとして、scikit-learnのモデル名を取得方法を残しておきます。

##はじめに
今回、scikit-learnのモデル名を取得する方法を少し苦労して探したので、メモとして残しておきます。

##scikit-learnのモデル名取得方法
下記で簡単にモデル名を取得できました。

```php
# ライブラリーのインポート
from sklearn.linear_model import Ridge

# Ridge回帰
model = Ridge()
clf = model.fit(X_train, y_train)
print(clf.__class__.__name__)
```
【初心者でもわかる】マウスカーソルを好きな画像に変える方法

# どうも7noteです。pcのマウスカーソルを好きな画像に変えましょう。

マウスカーソルといえば↗︎こんな形の矢印が一般的ですが、ちょこっとソースを書くだけでこのカーソルを好きな画像にする事ができます。

![icon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/1db50982-4cd5-dae4-e41a-e5db081b2ddf.png)


## マウスカーソルを好きな画像にする方法

```index.html
<div id="cursor"><img src="sample.png" alt=""></div>  <!-- imgタグを設定 -->
```

```style.css
body {
  cursor: none;  /*本物のカーソルを非表示に*/
}

#cursor{
  position: fixed;     /* 絶対位置になるように指定 */
  z-index: 2;          /* 重なり順を上に指定。他の要素に合わせて数字を大きくしてください。 */
  pointer-events: none;/*【重要】マウス直下に常に画像があるので、全てをクリックできなくなる。noneにして対応*/
}
```

```script.js
$(function(){

  var cursor=$("#cursor");                // カーソルになる要素を指定
  $(document).on("mousemove",function(e){ // マウスカーソルが動いた時に実行
    var x=e.clientX;                      // カーソルの横座標を取得
    var y=e.clientY;                      // カーソルの縦座標を取得

    //  取得した座標をCSSに反映させる
    cursor.css({
      "top":y+"px",
      "left":x+"px"
    });
  });

});
```

## 解説

まずはCSSを使ってデフォルトのカーソルを非表示にしてしまいます。

JavaScriptを使い、カーソルの位置を常時取得しつづけます。
その取得している位置に用意した画像を配置することで、まるで画像がカーソルかのように自由に動かすことができるようになります。


## まとめ

スマホが普及しているので、カーソルの画像を変えられたとて、需要は少ないかと思います。

しかし、qiitaのようにパソコンからのアクセスが中心になっているサイトもまだまだありますので、使い方次第では面白い使い方ができるかも。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
【AWS】プレイスメントグループを完全に理解する

#プログラミング勉強日記
2021年5月28日
[以前の記事](https://qiita.com/mzmz__02/items/50ef91a89c4d4897fa0d)で簡単にどんなものかを紹介したが、今日はプレイスメントグループについてきちんと理解する。

#プレイスメントグループとは
　複数のインスタンスを論理的にグループ化して、パフォーマンスの向上・耐障害性を高める機能のこと。クラスタープレイスメントグループ、パーティションプレイスメントグループ、スプレッドプレイスメントグループの3つの種類がある。

　クラスタープレイスメントグループは主にパフォーマンスを向上させるためのもので、パーティションプレイスメントグループとスプレッドプレイスメントグループが耐障害性を高めるもの。
　クラスタープレイスメントグループは、1つのAZ内のインスタンスを複数のグループにまとめる。パーティションプレイスメントグループはインスタンスをグループにまとめるときに、いくつかのパーティションに分ける。(9台のインスタンスを3つのパーティションに分けるような感じ)スプレッドプレイスメントグループは、パーティションと同様にセグメント分けする。1台につき1つのセグメントを割り当てる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/13495ea2-f259-c275-2806-527ddb65baf7.png)


#プレイスメントグループのタイプ

##クラスタープレイスメントグループ
　一般的に使われるもので、単一AZ内のインスタンスを論理的にグループ化したインスタンスのプレイスメントグループ。
　同じリージョン内の複数のVPCにまたがることができる。グループ内のインスタンスは、TCP/IPトラフィックのフロー当たりのスループット上限が高くなって、ネットワークの帯域幅が上がる。これによって、インスタンス間通信を向上できる。そのため、インスタンス間通信のパフォーマンスを上げたい場合に選択する。
他にも、低いネットワークレイテンシー、高いネットワークスループットを実現するアプリ向けの構成になっている。


##パーティションプレイスメントグループ
　障害に対応するためのプレイスメントグループで、グループをパーティションと呼ばれる論理的なセグメントに分割する。
　それぞれのパーティションが一連のラックという単位で構成される。プレイスメントグループ内のパーティション同士は同じラックを共有しない。ラックを分割することで、アプリないのでハードウェア障害によって影響を与えないようにできる。

##スプレッドプレイスメントグループ
　それぞれ独自のネットワーク、電源がある異なるラックに1つ1つのインスタンスを分割する。(パーティションプレイスメントグループは、グループ内に複数のインスタンスをラック内に分ける)
　1つのAZ内のスプレッドプレイスメントグループに配置された7つのインスタンスは7つの異なるラックに配置される。互いに分離して保持できるのでそれぞれのインスタンスを独自に構成したいときに使う。これによって、インスタンスが同じラックを共有するときに発生する可能性のある同時障害のリスクを減らせる。

#プレイスメントグループの利用
　プレイスメントグループは利用できるインスタンスタイプが制限されていることもある。
　クラスタープレイスメントグループはTシリーズは対応していない。(インスタンスファミリーについては[こちらの記事](https://qiita.com/mzmz__02/items/98ee6092dae6576b8b1a)で触れている)

　クラスタープレイスメントグループに対応したインスタンスの表

| インスタンスファミリー | インスタンスタイプ |
|:--:|:--:|
| 汎用 | A1 M4 M5 M5a M5ad M5d M5dn M5n |
| コンピューティングの最適化 | C3 C4 C5 C5d C5n cc.28xlarge
| メモリ最適化 | cr1.8xlarge R3 R4 R5 R5a R5ad R5d R5dn R5n X1 X1e z1d |
| ストレージの最適化 | D2 H1 hs1.xlarge I2 I3 I3en |
| 高速コンピューティング | F1 G2 G3 G4dn P2 P3 P3dn |
【PHP】課題14-15ジャンケンゲーム

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954863/69330fa5-764d-b36b-39f2-c11fc00eb414.png)


１・画面のレイアウトは画像の通り
２・ユーザーはグー・チョキ・パーのいずれかをラジオボタンで入力する
３・ユーザーの手がsubmitされたら、ユーザーの手を表示する
４・ユーザーの手がsubmitされたら、コンピュータの手をグー・チョキ・パーからランダムに選択し、表示する
５・ユーザーの手がsubmitされたら、じゃんけんの勝敗を判定し、出力する



```PHP
<?php
// じゃんけんの手を配列に代入
$hands = ['グー', 'チョキ', 'パー'];

// プレイヤーの手がPOSTされたら
if (isset($_POST['hand'])) {
    // プレイヤーの手を代入
    $playerHand = $_POST['hand'];

    // PCの手をランダムで選択
    $key = array_rand($hands);
    $pcHand = $hands[$key];

    // 勝敗を判定
    if ($playerHand == $pcHand) {
        $result ='あいこ';
    } elseif ($playerHand == 'グー' && $pcHand == 'チョキ') {
        $result = '勝ち';
    } elseif ($playerHand == 'チョキ' && $pcHand == 'パー') {
        $result = '勝ち';
    } elseif ($playerHand == 'パー' && $pcHand == 'グー') {
        $result = '勝ち';
    } else {
        $result = '負け';
    }
}

?>

<!DOCTYPE html>
<html lang="ja">
<head>
    <title>じゃんけん</title>
</head>
<body>

  <h1>じゃんけん勝負</h1>

  <?php if($_SERVER['REQUEST_METHOD'] === 'POST'){ ?>   
  <dl>
    <dt>自分：<?php echo $playerHand;  ?> </dt>
    <dt>相手：<?php echo $pcHand;  ?></dt>
    <dt>結果：<?php echo $result;  ?></dt>
  </dl>

  <?php
  }

  ?>

  <form method="post">
      <label> グー <input type="radio" name="hand" value="グー" required ></label>
      <label>チョキ <input type="radio" name="hand" value="チョキ" required ></label>
      <label>パー <input type="radio" name="hand"  value="パー" required ></label>
      <input style="display:block;" type="submit"  value="勝負">

  </form>

  <?php if($_SERVER['REQUEST_METHOD'] === 'POST'){ ?>   

  <p><a href="rock_paper_scissors.php">初画面</a></p>
  <?php
  }

  ?>

</div>
</body>
</html>
```
【超初心者向け】Azure ADとは？簡単な使い方も


# Azure ADとは
クラウドサービスのアカウントに対して一括管理が可能で、どこからでも安全に認証できる仕組みを提供するサービス。


# 4つの機能
Azure ADとは何なのか。
主な4つの機能を簡単に解説していきます。


## (1)ディレクトリサービス機能
・ユーザーもデバイスもAzure ADでまとめて管理できる。
・ユーザーはどこからでもAzure ADにサインインして様々なリソースにSSOでアクセス可能。
・業務で使用するクラウドアプリケーションをAzure ADと統合してリソースへのアクセス制御をAzure ADでまとめて管理できる。


## (2)ID管理機能
・ユーザーのリスクポリシーで怪しいユーザーアクションを対策できる。
・サインインのリスクポリシーで怪しいサインインアクションを対策できる。
・多要素認証での登録でアカウントの脆弱性を対策できる。

## (3)アプリケーションアクセス管理機能
・Azure ADにアクセス後、どのアプリケーションが利用可能かを判定する認可機能。

## (4)オンプレミスAD統合機能
・オンプレミスADドメインからAzure ADへ、ディレクトリ情報とユーザーのパスワード情報の同期が可能。

# Azure AD使い方
ここからはAzure Active Directoryの使い方をいくつかに絞って解説していきます。

## (1)削除したユーザーを復元する
誤ってユーザーを削除したら一大事です。そのユーザーは、Azure ADと連携しているシステムやPCにログインできなくなります。
しかし、Azure ADでは削除から30日以内ならユーザーを復元する機能があります。
管理画面の【ユーザー】をクリックすると『削除されたユーザー』という項目があるので、そこから復元可能です。

## (2)グループに特定のユーザーを自動追加する
Azure AD上では『グループ』を作成できます。特定のグループに所属するユーザーをまとめて、他のシステムと連携してシングルサインオンを許可するなど使い勝手のいい機能です。
また、このグループへのメンバー追加方法は手動で追加する方法と、自動で追加される方法があります。自動で追加される方法は『動的ユーザー』と『動的デバイス』に分けられます。動的ユーザーでは、特定の条件を設定して、それを満たすユーザーが自動でグループに追加されます。一方、動的デバイスでは、特定の条件を設定して、それを満たすデバイスが自動でグループに追加されます。
動的ユーザーでメンバーを追加する方法は、グループ作成時の【メンバーシップの種類】で『動的ユーザー』を選択し、【動的クエリ】の追加で条件を設定します。
振り返り・KPTで優先的に考えた方がいいこと

表題のような「チーム」開発を進めていく上で、気になるのは(規約に関してやスクラム自身に関する)意識や認識のずれ。

スクラム開発では、「仕組み」として「振り返り」や「レトロスペクティブ」が用意されています。
「仕組み」の上では、それによって意識や認識のずれを埋める機会になります。

しかしながら皆様の経験上....その仕組みを回していくだけで十分でしたか?
人と人が理解する上で、「仕組み」だけでそれが実現できたことはありましたか？

この仕組みに向き合う上で、優先的に考えないといけないことがあると筆者は考えます。

それは「自分」を優先的に考えるということかと思います(自省)と言い直すこともできそうです。

逆のパターンを先に提示します。
もし全員が「他のメンバー」を軸に課題を考えたらこの仕組みを回せば回すほど、不満や怒りをためることになるのです。

具体的には...(例えばKPTで)
「ソースレビューをしない人がいる」
という不満があったとします。
この時点で他のメンバーを軸に考え始めています。

ではここで、「自分」を優先的に考えたらどうなるでしょうか。
まず「ソースレビューをしない人がいる」という「不満」は

1. 「ソースレビュー」がチームの負担ではないかという疑問になります
2. 「自分」がチームがすべきソースレビューのうち、どれくらいを負担できたかを振り返ることができます
3. 負担できなかったものとの割合を照合できます
4. チームに提示すべきは「自分」が負担できたレビューとできなかったもの。これくらい(の割合で)できなかった負担があるが、「自分は」さらに負担できるだろうか？

といった提示の仕方ができるようになります。

(発言者とは)逆のメンバーの立場になればわかるのですが
「ソースレビューをしない人がいる」

と発言するメンバーと

「「ソースレビュー」がチームの負担ではないか?
「自分」がチームがすべきソースレビューのうち、何割を負担できました。何割負担できませんでした。負担できなかった何割はそのまま(チームメンバーとして)私が負担することができそうですか？」

と発言するメンバー

どちらが具体性に富み、
協力するのに容易でしょうか？

前者という人も中にはいるかもしれませんが
それは筆者とは開発スタイルが違うだけのことかもしれません(笑)

ここで言いたいのは
振り返りやレトロスペクティブという仕組みを「利用」する上で
「自分」を優先的に省みる姿勢が揃っていると
仕組みを存分に活用できる。

そんな風に利用してみてはいかがでしょうか？
Composerインストール済みなのにcomposer: Command not foundになる時の解決方法。


Composerインストール済みなのにcomposer: Command not foundの解決できたのでメモ。


作ったWebサイトにTwitter認証させたいなと思い作業を進めました。
Twitter認証はこちらの記事を参考にさせていただきました。

https://php-junkie.net/framework/laravel/socialite/

サーバーはさくらのレンタルサーバーを使っています。

<br>
ローカル環境では問題なく動いたので、さくらのサーバーにアップしました。
が、ローカルに入れたSocialiteは動きません。Class Socialite Not foundです。

composerはローカルにインストールしててもアップされないので再度Tera Term上でコマンドを叩く必要があります。


```
composer require laravel/socialite
```
https://laravel.com/docs/8.x/socialite


composer: Command not found。
え？

<br>

```
php composer.phar
```
 
![Screenshot (551).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635968/3afddaa8-a999-10df-639a-e7569bb54e23.png)


あまり詳しくはないのでよくわからないのですが、composerは問題なく入っているようです。

```
composer -v
```

composer: Command not found。
え？

```
composer --version
```

composer: Command not found。
え？

何が問題なのかわからず、ググりました。
解決方法。
{プロジェクト名}のディレクトリ上で

```
php /home/{アカウント名}/{プロジェクト名}/composer.phar require laravel/socialite
```
<br>

![Screenshot (553).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635968/a5c313d7-63d0-a14a-1978-959f9d40567c.png)

解決できました。
strapiの自作プラグインを左メニューに表示させる方法

# はじめに

strapiはポストwordpressとして非常に期待しているのですが、日本語の資料が少ないので苦労しており、少しでも参考になればと思います。

今回は、自作したプラグインを管理ページに表示させようとしたところ、`yarn develop`と`yarn start`で起動した場合にプラグインが表示されない問題が発生したので解決方法を記載しています。


# 動作環境

- Mac: MacBookPro macOS Big Sur 11.3.1
- node: v12.18.3
- yarn: 1.22.10
- Strapi v3.6.2

現象を再現するために新規にプロジェクトを作成します。

``` terminal
$ yarn create strapi-app my-project --quickstart
```

適当にadminユーザーを作成してログインします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132299/31adde26-a533-14fa-c27b-318afcd1f038.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132299/d86a3f24-26f5-793a-1bf2-0e05a769467c.png)




以下のコマンドからプラグインを追加します。

``` terminal
cd my-project/
yarn strapi generate:plugin qiitaPlugin
```

もう一度起動します。(デフォルトで1337ポートで起動します。)

``` terminal
yarn develop
```

以下のように`PLUGINS`の中に自作したプラグインが表示されません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132299/9cedf111-e85d-13bb-a523-46da4ac77121.png)

一方、8000番ポートで起動する`--watch-admin`オプションをつけた場合はプラグインの項目が表示されてます。

``` terminal
yarn develop --watch-admin
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132299/15b29d58-34eb-a14e-14bf-de69f50d747e.png)

このプラグインの項目を1337ポートで起動した場合でも表示したいと思います。

# 解決方法

解決方法は簡単で、プラグイン追加後に`build`を行えば解決しました。

``` terminal
$ yarn strapi build
$ yarn develop
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132299/88f3f11b-e1c8-5005-b9cc-ec4e9ed1b669.png)

# まとめ

まだstrapiを完全に理解してませんが、誰かの助けになれば幸いです。
【AWS】ELB 5XXs で HTTP 5XXs をカウントしない理由

## 経緯
下記の記事でロードバランサーのモニタリング画面で確認できる「ELB 5XXs」と「HTTP 5XXs」がそれぞれ何を示しているのか調べました。

https://qiita.com/sasa_muku/items/218bf0447afa3fd8c03e

結論としては、次の通りでした。

* ELB 5XXs
    * ロードバランサーが返す 5XXエラーがカウントされる
* HTTP 5XXs
    * ターゲットが返す 5XXエラーがカウントされる

ここでさらなる疑問が生まれます。

**「ターゲットとロードバランサーのステータスコードってどうマッピングされているんだろう？」**

「まぁ、普通に、ターゲットが返したコードをロードバランサーがそのまま返すんやろな」（← 後から振り返ると正解だった）
![image-cw-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619762/29ea0858-2576-79bb-5a29-214222580eea.png)

ところが、以降で示すような状況に遭遇し、「あれ？違うかも。分からん。」となってしまいました。

## ターゲットが500を返すのにロードバランサは返さない？
ターゲットが500を大量に返すトラブルがあったときの、「HTTP 5XXs」と「ELB 5XXs」のスクショです。

トラブルが発生したのは16:18で、「HTTP 5XXs」にメトリクスが大量にカウントされています。
![target_status_5XX.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619762/f227c275-ef72-7ddb-8e3d-2f9fa306864f.png)

一方、「ELB 5XXs」にはメトリクスがカウントされていませんでした。（17:47にちょろっと出ているのは別件）
![elb_status_5XX.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619762/0b38c831-184c-594b-7437-86ae4967506e.png)

「なんで ALB は500返していないんだろう？ 逆に何を返しているんだ？」と当然疑問に思います。

そこで、Athena で ALB アクセスログを確認します。
ログでは「elb_status_code」と「target_status_code」の両方のカラムに500が刻まれています。
![image-athena-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619762/72613a63-85b8-1938-d1a5-1e4001988bad.png)

つまり、ALBはターゲットから受け取ったコードをちゃんとクライアントに返している。
ということは、CloudWatchメトリクスでカウントしていないのが謎になる。

## 結論
サポートに聞いたところ次のような回答でした。

「ALBはたしかにターゲットと同じ500を返すけど、それはメトリクスにカウントされません。なぜなら、ターゲットが返した応答コードはカウント対象外だからです。ドキュメントに書いてるやろ、ほれ」（意訳）

HTTPCode_ELB_5XX_Count
> ロードバランサーから送信される HTTP 5XX サーバーエラーコードの数。この数には、ターゲットによって生成される応答コードは含まれません。

HTTPCode_Target_5XX_Count
> ターゲットによって生成された HTTP 応答コードの数。これには、ロードバランサーによって生成される応答コードは含まれません。

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html


## つまりこういうこと

![image-cw-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619762/7118de80-9847-8b8c-9054-42cbd2e4c44c.png)

![image-cw-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619762/e0e7f1e3-d7e3-2378-f30f-17b11bb9e005.png)

## まとめ
たしかに、ターゲットが返す応答コードもALBのメトリクスとしてカウントしてしまうと、
**どこで問題が起こっているのかひと目で分からなくなってしまいますもんね。**
それが、ALBでターゲットの500をカウントしていない理由なんだと思います。
言われてみれば納得の仕様でした。

## 参考
https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-troubleshooting.html#http-502-issues

↑ ALBのエラーコードとその原因がまとめられていて勉強になりました。
AWS Kinesis


#Kinesis
ストリーミングデータをリアルタイムで処理できるサービスです。
Kinesis を利用すると、機械学習、分析、その他のアプリケーションに用いる動画、音声、アプリケーションログ、ウェブサイトのクリックストリーム、IoT テレメトリーデータなどさまざまなデータをリアルタイムで取り込む事が出来ます。
　**・Kinesis Video Streams**
　**・Kinesis Data Streams**
　**・Kinesis Data Firehose**
　**・Kinesis Data Analytics**

もし週末にまとめてデータをS3に送る設定の際に、
データレコードはKinesisストリームに加えられてから**デフォルトで24時間以内までアクセスできるように設定されています。**現行のアーキテクチャ構成では、ストリームデータは処理のために週末にS3に送信されます。そのためS3に即時に送信していないため24時間超過したデータはアクセスできず、全てのデータが送られていない状況が発生してしまっている可能性が高いです。

##Kinesis Data Firehose
ストリーミングデータをデータレイクやデータストア、分析ツールに配信するサービスです。ストリーミングデータをキャプチャして変換しつつ、S3、Redshift、Elasticsearch Serviceにロードします。**DynamoDBに配信することはできません。**

##Kinesis Data Streams
特別なニーズに合わせてストリーミングデータを処理または分析するカスタムアプリケーションを構築できます。
Kinesis アプリケーションは複数のアプリケーションインスタンスを持つことができ、KCLワーカーは各アプリケーションインスタンスに対応する処理ユニットです。レコードプロセッサは、Kinesis Data Streamsのシャードからのデータを処理する処理ユニットです。1 つのワーカーは 1 つまたは複数のレコードプロセッサにマッピングされます。1 つのレコードプロセッサは 1 つのシャードに対応し、そのシャードからのデータレコードを処理します。
Raspberry PiにAK-020と一緒に別のUSBデバイスを一緒に指したらSORACOM通信できなくなった

以下のようにMODBUS-RTUのUSBアダプタと一緒にAK-020を一緒に指したら、SORACOMに繋がらなくなりました。（以下の画像で緑が点灯していますがネットワークは繋がっていません）

<img width="200" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116068/6598c681-8fbf-c303-f30f-dab774bd61e9.png">


そこは流石SORACOMのドキュメントは新設で、こんな情報を見つけました。

https://soracom.zendesk.com/hc/ja/articles/360042108971-AK-020-%E3%81%A8%E4%BB%96%E3%81%AE-USB-%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%82%92-Raspberry-Pi-%E3%81%AB%E5%8F%96%E3%82%8A%E4%BB%98%E3%81%91%E3%82%8B%E3%81%A8-AK-020-%E3%81%8C%E8%AA%8D%E8%AD%98%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84

# まずは情報通りに実施
書かれていた内容は、以下の処理を `rc.local` の `exit 0` の前に入れるというものです。

```sh
sleep 10s  
sudo modprobe -r ftdi_sio  
sudo modprobe -r usbserial  
sudo modprobe usbserial vendor=0x15eb product=0x7d0e  
sudo modprobe ftdi_sio  
sudo ifdown wwan0  
sudo ifup wwan0
```

打ってみると以下のエラーが出ました。 `usbserial` が利用中でremoveできないようです。

```sh
$ sudo modprobe -r usbserial
modprobe: FATAL: Module usbserial is in use.
```

`rmmod` でもremoveできません。ただ `cp210x` に使われているということがわかりました。この `cp210x` というのはModbus-RTUのUSBアダプタのことです。

```
$ sudo rmmod usbserial
rmmod: ERROR: Module usbserial is in use by: cp210x
```

`lsmod` でも確認しておきます。間違い無さそうです。

```sh
$ sudo lsmod | grep usbserial
usbserial              36864  1 cp210x
```

# 対応

以下のように先に `cp210x` を外すことで、 `usbserial` も外せます。

```sh
$ sudo modprobe -r cp210x
$ sudo modprobe -r usbserial
```

SORACOMの記事から少しだけ修正して、 `/etc/rc.local` の `exit 0` 前に以下のように書き込んで上手くいくようになりました。

```sh
sleep 10s  
sudo modprobe -r cp210x  
sudo modprobe -r ftdi_sio  
sudo modprobe -r usbserial  
sudo modprobe usbserial vendor=0x15eb product=0x7d0e  
sudo modprobe ftdi_sio  
sudo ifdown wwan0
sudo ifup wwan0
sudo modprobe cp210x
```
EC2のsshdを停止したときの挙動

## 概要
今更だが、EC2インスタンスのsshdを停止した時にログアウトされるのか？を確認してみた。

## 前提
CentOS 7

## 結論
```sudo systemctl stop sshd```

ログアウトされない。
exitでログアウトして、sshしようとするとエラーとなる。

この場合の復旧作業は、EC2インスタンスを再起動するか、SSMエージェントがインストールされていればセッションマネージャーでログイン後に、sshdを起動する。
Azureメモ

とりあえずキーワードだけ

https://docs.microsoft.com/ja-jp/azure/app-service/web-sites-integrate-with-vnet

Appservice→Vnet統合
SQLDB→プライベートリンク

AppServciceにWEBSITE_VNET_ROUTE_ALL：1の設定をした場合、東日本のPaaS、パブリック接続サービスに接続できなくなる。
その場合の対処法として、Vnet統合のサブネットにサービスエンドポイントで必要なサービスの許可をする
Object.keys()の型がstring[]になる問題の対策（キャスト使わない版）

キャストは使わずにやりたい。ほどほどにtype safeにしたい

## TL;DR;

`Object.keys()`使わずに`for in`を使う

## 例

```ts
const obj = {
  FOO: "foo",
  BAR: "bar",
  BAZ: "baz",
};

let key: keyof typeof obj;
for (key in obj) {
  const value = obj[key];
  // 
}
```

## （参考）キャスト使ってもOKなら....

```ts

const keys = Object.keys(obj) as (keyof typeof obj)[];
keys.forEach((key) => {
  const value = obj[key];
  //   
});
```
Nuxt.js【this.$nuxt.$loading.start is not a function 】エラーの対処法

Nuxt.jsにて、

```
this.$nuxt.$loading.start is not a function 
```

上記エラーの対処法になります。

## mountedで【this.$nuxt.$loading.start】を使用するとエラーがでる

```vue
<script>
export default {
  mounted() {
    this.$nuxt.$loading.start()

    setTimeout(() => this.$nuxt.$loading.finish(), 500)
  }
}
</script>
```
上記のように、 mountedで`this.$nuxt.$loading.start`を使用すると`this.$nuxt.$loading.start is not a function `のエラーがでます。

##  this.$nextTickを使うことで解決

```vue
<script>
export default {
  mounted() {
    this.$nextTick(() => {
      this.$nuxt.$loading.start()

      setTimeout(() => this.$nuxt.$loading.finish(), 500)
    })
  }
}
</script>
```

上記のように`this.$nextTick`を使用することでエラーが解消できました。
`this.$nextTick`は、DOMを更新後、その更新済みのDOMに対して何らかの処理をすることが可能です。
Vue2系でオブジェクトの双方向データバインディング

Vue2系でカスタムコンポーネントにて親子間の双方向データバインディングを実装する際の備忘録

前提として親子間のデータ受け渡しは、親→子の際にはProps、子から親へはemitで単方向で渡すことが前提になっており、親から渡された値を子コンポーネントにて直接編集してはいけない。

ただし実はオブジェクトを渡した際にはエラーを出さずに直接変更できたりする。(非推奨)

# ズルするパターン

```vue:Child.vue
<template>
  <div>
    <v-text-field v-model="form.someText1" label="field1"></v-text-field>
    <v-text-field v-model="form.someText2" label="field2"></v-text-field>
  </div>
</template>

<script>
export default {
  name: 'Child',
  props: {
    form: {
      type: Object,
      default: () => ({
        someText1: '',
        someText2: '',
      }),
    },
  },
}
</script>

```

```vue:Parent.vue
<template>
  <div>
    <Child :form="form" />
  </div>
</template>

<script>
export default {
  name: 'Parent',
  data:() => ({
    form: {
      someText1: '',
      someText2: '',
    },
  }),
}
</script>

```
上記でも動かないことはないけれど今回はちゃんとやるケースを下記に記載する。

# きちんとやるパターン

```vue:Child.vue
<template>
  <div>
    <v-text-field v-model="someText1" label="field1"></v-text-field>
    <v-text-field v-model="someText2" label="field2"></v-text-field>
  </div>
</template>

<script>
export default {
  name: 'Child',
  props: {
    value: {
      type: Object,
      default: () => ({
        someText1: '',
        someText2: '',
      }),
    },
  },
  computed: {
    someText1: {
      get() {
        return this.value.someText1
      },
      set(v) {
        const Obj = JSON.parse(JSON.stringify(this.value)) // deep copy
        Obj.someText1 = v
        this.$emit('input', Obj)
      },
    },
    someText2: {
      get() {
        return this.value.someText2
      },
      set(v) {
        const Obj = JSON.parse(JSON.stringify(this.value))
        Obj.someText2 = v
        this.$emit('input', Obj)
      },
    },
  }
}
</script>

```

```vue:Parent.vue
<template>
  <div>
    <Child v-model="form" />
  </div>
</template>

<script>
export default {
  name: 'Parent',
  data:() => ({
    form: {
      someText1: '',
      someText2: '',
    },
  }),
}
</script>

```

参照
[【Vue.js 再入門】 v-model を正しく理解して親子間コンポーネントのデータ伝播をマスターする
](https://qiita.com/toshifumiimanishi/items/07c8e96eb6f8e50c5e27)
Raspberry Pi Pico便利メモ

Raspberry pi Pico で困ったことをその度にメモします。
#Picoのソースコードを自動起動

Thonnyのsave asをえらんでRaspberry Pi Pico を選択し、main.pyのファイル名で保存すると、次回リセット時に自動起動する。

#Thonnyで外部ライブラリを読み込み

デフォルトではToolが表示されない。

Thonnyー＞preference->GeneralでUIモードにしてsimpleからregularを選択する。

Toolから外部ライブラリを選択しインストールする。

#USB抜き差しなしでパソコンに認識させる。

リセットピンをローにして、BOOTSELを押しつづけ、リセットをハイにして（内部プルアップしている）、BOOTSELを最後に離す。

#サンプルコードのサイトがどこだかわからない。

micropythonのサンプルコード

https://github.com/raspberrypi/pico-micropython-examples

C＋＋環境のサンプルコード　cmakeをつかってビルドする。

https://github.com/raspberrypi/pico-examples

#C++での開発環境構築

Mac環境でサンプルコードのLチカをビルドする例

ARMのGCCコンパイラをインストールするためパッケージマネージャのHomwbrewインストールします。

```
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

更新します。

```
$brew update
$brew update
```

ビルド自動化ツールcmakeインストールします。

```
$brew install cmake
```

公式ArmMbedのツールチェーンをインストールします。

```
$brew tap ArmMbed/homebrew-formulae
```

コンパイラインストールする。

```
$brew install arm-none-eabi-gcc
```

ARM用コンパイラ動作確認します。

```
$arm-none-eabi-gcc -v


gcc version 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599] (GNU Tools for Arm Embedded Processors 9-2019-q4-major) 


```

makeコマンド確認します。

```
$make -v

GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

```



```
$cd ~
```

```
$mkdir pico
```

```
$cd pico
```

SDKをダウンロードします。

```
$git clone -b master https://github.com/raspberrypi/pico-sdk.git
```

```
$cd pico-sdk
```

SDKをアップデートします。

```
$git submodule update --init
```

```
$cd ..
```

サンプルをダウンロードします。

```
$git clone -b master https://github.com/raspberrypi/pico-examples.git
```

```
$cd pico-examples
```

実行ファイルのディレクトリを作成します。

```
$mkdir build
```

```
$cd build
```

SDKのパスを設定します。

```
$export PICO_SDK_PATH=../../pico-sdk
```

cmake実行します。

```
$cmake ..
```

```
$cd blink
```

ビルド実行します。

```
$make
```

elf,bin,hex,uf2ファイルが生成され、
blink.uf2ファイルをPicoのドライブにコピーするだけで実行できます。

うまくいかないときは、homebrewから入れ直しました。


#リンク

RP2040に関するサイト
https://www.raspberrypi.org/documentation/rp2040/getting-started/
[Android]初めての公式ドキュメント

#対象者
ドキュメントを読みたい人
ドキュメントを読もうとしても英語の羅列でなんの情報かが分からないという人
#構成について
みんな大好きAlertDialogのドキュメントを元に解説していきます。

https://developer.android.com/reference/android/app/AlertDialog

#AlertDialog
###public class AlertDialog extends Dialog implements DialogInterface
これは、クラスの定義です。
Dialogクラスを継承し、DialogInterfaceを実装していることがわかりますね。

###java.lang.Object
   ↳	android.app.Dialog
 	   ↳	android.app.AlertDialog

これは、継承の家系図的なものがパッケージまで書かれています。
###Known direct subclasses
これは、AlertDialogのサブクラスについて紹介されています。
###A subclass of Dialog that can display one, two or three buttons. If you only want to display a String in this dialog box, use the setMessage() method. If you want to display a more complex view, look up the FrameLayout called "custom" and add your view to it:〜
この細かく書かれている部分がAlertDialogについての詳細です。
何をするクラスなのかが、書いてあります。

#Summary
続いて、概要（メンバについての）です。
###Nested classes
これは、内部で定義しているクラスについて書かれています。
ここでは、AlertDialog.Builderクラスが定義されているみたいです。
裏のコードを見ると・・、確かにある。

```java:AlertDialog.java
    public static class Builder {
        private final AlertController.AlertParams P;
        private final int mTheme;
```
※（コード内の抜粋です）

###Constants
これは、定数です。
今回のは、API23から非推奨になっているみたいですが。。

###Inherited constants
継承しているクラスの定数です。
またまた、非推奨に・・（例として悪いかったですね）

###Protected constructors
こちらは、AlertDialogで定義されている、protectedのアクセス修飾子のついたコンストラクタです。
protectedは、継承関係にあるもの同士であれば、アクセスできます。
定義の仕方と、それがなんなのか？と、引数について書かれています。

###Public methods
こちらは、クラス内で定義されたメソッドです。
構成は、コンストラクタとほとんど同じです。
加えて、返り値の詳細まで書かれています。

#終わりに
こんな感じです。
気になることがあれば、質問&ツッコミお待ちしていおります！
ちゃんと読めば、これ以上に質の高い情報ない！って思えますよ！
PleasanterとExcelを接続してみた


# はじめに
"脱Excel"が騒がれる昨今ですが、なんだかんだExcelって便利ですよね。
ということで、"脱Excel"を掲げる[Pleasanter](https://pleasanter.org/)とExcelをAPIで接続してみました。
# やること
ExcelVBAからAPI発行して、Pleasanterに接続、情報を取得してExcelに展開します。
# 準備
#### ExcelVBA
VBAでJSONを扱うため、[VBA-JSON](https://github.com/VBA-tools/VBA-JSON)のライブラリをインポート
（その他の方法でもJSONを扱えるようにしておけばOKのはず）


#### PleasanterのAPI
APIの利用方法は以下マニュアルを参照してください。
https://pleasanter.org/manual?category=2100

#### 読み込み対象となるPleasanterのレコード
読み込み用に以下にようなテーブルを用意しました。これを取得しExcelに展開します。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/fecf5b68-5892-2113-0684-26a1ce87cf16.png)



# VBAの実装
実装サンプル、特定のシートで実行します。
（APIキーや、サイトIDは適宜設定してください）

```vb
Dim jsonRequest As Object
Dim parseResponse As Object
Dim httpRequest As Object

'---------------------------------
'　リクエストパラメータを生成
'---------------------------------

Set jsonRequest = New Dictionary

'JSONデータをDictionaryオブジェクトに設定
'-->JSONのパラメータはマニュアル参照
jsonRequest.Add "ApiVersion", "1.1"
jsonRequest.Add "ApiKey", "XXXXXXXXXX..."
jsonRequest.Add "View", New Dictionary
jsonRequest("View").Add "ColumnFilterHash", New Dictionary

'ClassAが「こ」と「き」のレコードを抽出対象と設定
jsonRequest("View")("ColumnFilterHash").Add "ClassA", "[""こ"",""き""]"
 
'HTTPヘッダ部を生成（これもマニュアル参照）
Set httpRequest = CreateObject("msxml2.xmlhttp")
httpRequest.Open "POST", "http://localhost/pleasanter/api/items/{サイトID}/get", False
httpRequest.setRequestHeader "Content-Type", "application/json;charset=utf-8"


'---------------------------------
'　リクエスト発行
'---------------------------------
'パラメータをJSONにコンバート（VBA-JSON）してからsend
httpRequest.send JsonConverter.ConvertToJson(jsonRequest)


'---------------------------------
'　レスポンスを編集
'---------------------------------

'レスポンスをパース（VBA-JSON）
Set parseResponse = JsonConverter.ParseJson(httpRequest.responseText)

'取得件数0件のとき
If parseResponse("Response")("Data").Count <= 0 Then
    Exit Sub
End If

i = 1
For Each responseData In parseResponse("Response")("Data")
     
     '取得できた値をセルへ転記（→Title、ClassA、ClassB、ClassC）
     Worksheets(ActiveSheet.Name).Cells(i, 1).Value = responseData("Title")
     Worksheets(ActiveSheet.Name).Cells(i, 2).Value = responseData("ClassHash")("ClassA")
     Worksheets(ActiveSheet.Name).Cells(i, 3).Value = responseData("ClassHash")("ClassB")
     Worksheets(ActiveSheet.Name).Cells(i, 4).Value = responseData("ClassHash")("ClassC")
     i = i + 1
Next

```
# 実行結果
条件のとおりレコードが取得できました。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/79c0e633-ce27-97c0-7f1c-7162a467f142.png)

# あとは
Excelに取り込んでしまえば、関数を使って計算したり集計したり自由自在です。
各種パラメータも、セルから設定できるようにVBAで仕込むこともできます。
計算した結果を、Pleasanterに登録するなんてこともできるはずです。
CentOS7のIPアドレス/デフォルトゲートウェイ/DNSサーバの再設定

# CentOS7のIPアドレス/デフォルトゲートウェイ/DNSサーバの再設定
## 環境
* VMware Workstation 16 Player
* CentOS7

## デバイス確認
```
[root@localhost ~]# nmcli device
DEVICE       TYPE      STATE      CONNECTION
eth0         ethernet  connected  ens33
lo           loopback  unmanaged  --
```

## 設定変更(nmcli ～)
```
# 固定IPv4アドレス設定
[root@localhost ~]# nmcli connection modify ens33 ipv4.addresses 192.168.0.100

# デフォルトゲートウェイ設定
[root@localhost ~]# nmcli connection modify ens33 ipv4.gateway 192.168.0.1

# 参照する DNS設定
[root@localhost ~]# nmcli connection modify ens33 ipv4.dns 192.168.0.1

# インターフェースを再起動して設定を反映
[root@localhost ~]# nmcli connection down ens33; nmcli connection up ens33
```
## 設定後確認
```
# 設定確認
[root@localhost ~]# nmcli device show ens33
GENERAL.DEVICE:                 ens33
GENERAL.TYPE:                   ethernet
GENERAL.HWADDR:                 00:0C:29:CD:9C:2D
GENERAL.MTU:                    1500
GENERAL.STATE:                  100 (connected)
GENERAL.CONNECTION:             ens33
GENERAL.CON-PATH:               /org/freedesktop/NetworkManager/ActiveConnection/2
WIRED-PROPERTIES.CARRIER:       on
IP4.ADDRESS[1]:                 192.168.0.100/24
IP4.GATAWAY:                    192.168.0.1
IP4.ROUTE[1]:                   dst = 192.168.0.0/24, nh = 0.0.0.0, mt = 100
IP4.DNS[1]:                     192.168.0.1


# 接続確認
[root@localhost ~]# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:cd:9c:2d brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.100/24 brd 192.168.0.255scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fecd:9c2d/64 scope link
       valid_lft forever preferred_lft forever
```
【Python】PythonでPowerShellのコマンドを利用する

# はじめに

Windowsでより強い権限を持った操作をコマンドを利用して行う時はWindows PowerShellを利用する場合があるが、これはPythonで普段利用する`subprocess`ライブラリではサポートされていない。当記事では、PythonでWindows PowerShellのコマンドを利用する方法について簡単に解説する。

# 実装

PowerShellのコマンドは先ほども述べたように、`subprocess`では利用できないので、ビルトインの`os.system`を利用する。

```python
os.system("powershell -Command 実行したいPowerShellコマンド")
```

このようにすることでPowerShellコマンドを実行することができる。具体的な例については下記で示している。

## 実装例1 - 日時の取得

現在時刻を取得するPowerShellコマンドを実行

```python
os.system("powershell -Command Get-Date")
```

```terminal:実行結果
2021年5月28日 19:44:54
```

## 実装例2 - タスク登録

Windowsのタスクスケジューラーにタスクを登録するPowerShellコマンドを実行

```python
def register_task(task_name, batch_path):
    ps_cmd = f"schtasks /create /tn {task_name} /tr {batch_path} /sc onlogon /delay 0000:30 /rl highest"
    os.system(f"powershell -Command {ps_cmd}")

if __name__ == "__main__":
    register_task("test-task", r"C:\Users\~~~\~~~.bat")
```

```terminal:実行結果
成功: スケジュール タスク "test-task" は正しく作成されました。
```

PowerShellコマンドの詳細については解説を省略するが、一応これで任意のバッチファイル(フルパス指定)をログオン時に起動するというタスクを登録することができる。

### 注意点

上記の例も含め、一部の権限が必要なPowerShellコマンドを実行する場合は、スクリプトを**管理者権限**で実行する必要がある。
[m1]asdfでバージョン管理を行なったpythonを使うまで[mac]

https://qiita.com/sugo/items/eb69fad41ffe753dd489

これに続きpython編

https://github.com/danhper/asdf-python

# 前提

- asdfインストール済み
    - 未インストールの場合、冒頭のnodejsの記事を参照してasdfを導入する

# 環境

- MacBook Air (M1, 2020)

# python

## 準備

```
% asdf plugin-add python
```

## 最新安定板の確認/インストール

```
% asdf latest python
3.9.5
% asdf install python latest
```

## インストールしてあるバージョンの一覧確認

```
% asdf list
nodejs
  16.2.0
python
  3.9.5
```

nodeもすでにインストール済みなのでこんな表示になってる

```
% asdf list python
  3.9.5
```

## とりあえずのプライマリバージョン設定

```
% asdf global python 3.9.5
```

## 有効なバージョンの確認

```
% asdf current
nodejs          16.2.0          /Users/ユーザー名/.tool-versions
python          3.9.5           /Users/ユーザー名/.tool-versions
% asdf current python
python          3.9.5           /Users/ユーザー名/.tool-versions
% cat ~/.tool-versions
nodejs 16.2.0
python 3.9.5
% python -V
Python 2.7.16
```

**これである**

```
% python -V
Python 2.7.16
```

## 現状のpythonの確認

```
% python -V
Python 2.7.16
% where python
/Users/ユーザー名/.asdf/shims/python
/usr/bin/python
% asdf which python
/Users/ユーザー名/.asdf/installs/python/3.9.5/bin/python
```

## pythonの再設定

https://asdf-vm.com/#/core-commands

> % asdf reshim [name] [version]
> Recreate shims for version of a package

```
% asdf reshim python
% python -V
Python 3.9.5
% python2 -V
Python 2.7.16
% python3 -V
Python 3.9.5
```

## 適当にファイル作って実行してみる

```
% touch test.py
```

```python:test.py
import sys
major = sys.version_info.major
minor = sys.version_info.minor
micro = sys.version_info.micro
output = "hello [Python {}.{}.{}] world".format(major, minor, micro)
print(output)
```

```
% python test.py
hello [Python 3.9.5] world
% python2 test.py
hello [Python 2.7.16] world
% python3 test.py
hello [Python 3.9.5] world
```
HOW TO USE THE LAW OF SINES CALCULATOR?

HOW TO USE THE LAW OF SINES CALCULATOR?
Sines calculator is a really nice calculator and this will help you a lot. This tool is a web-based tool that can be used from anywhere. This calculator works on every device, you can use this tool on a desktop and even on a smartphone. This tool is made for students and any individual who want to use this tool. Find Law Of Sines Calculator on Taskvio.
<a href="https://taskvio.com/maths/trigonometry-calculators/law-of-sines-calculator/" title="100's of bots" target="_blank">Law Of Sines Calculator</a>

Anyone from anywhere can use this tool and this tool can be used from anywhere around the whole world. This tool is really quick that can help your problem really quick. Even if you don't know about this tool you can use this tool and it will solve your problem so you just have to input the number here and you will be good to go.
Or you can have the knowledge about it from our little small Article.            
what is Sines?
The law of sines states that the proportion between the length of a side of a triangle to the sine of the opposite angle is equal for each side:
a / sin(α) = b / sin(β) = c / sin(γ)
This ratio is also equal to the diameter of the triangle's circumcircle (circle circumscribed on this triangle).
Note that you can use this law for any triangle, also for one that isn't a right triangle.
Law of sines application
You can transform the law of sines formulas to solve some problems of triangulation (solving a triangle). You can use them to find:
1.	The remaining sides of a triangle, knowing two angles and one side.
2.	The third side of a triangle, knowing two sides and one of the non-enclosed angles. In some cases (ambiguous cases) there may be two solutions to the same triangle. If the following conditions are fulfilled, your triangle may be an ambiguous case:
•	You only know the angle α and sides a and c;
•	Angle α is acute (α < 90°);
•	a is shorter than c (a < c);
•	a is longer than the altitude h from angle β, where h = c * sin(α) (a > c * sin(α)).
You can also combine these equations with the law of cosines to solve all other problems involving triangles.
How to use the sines calculator?
To use this tool you don’t have to worry too much about this. It's really a simple calculator and this tool is really easy to use. It also has a very simple interface. And to use this tool you just have to follow some steps that’s all you have to do.
So to use this tool you just have to follow some very simple steps and that's all you have to do to use this tool.
Now as you can see on your desktop you have this tool that can be really nice and in this tool, you have some boxes where you can fill out the value of your problem.
Please enter your value in the text box and also cross-check it so that you won't get the wrong answer.
After that, you just have to simply click on the calculate button which is below the text box so that you will get the answer.
Tips: you should bookmark this tool so that you can use it later and you don't even have to search for this tool again.
a.__spreadArray is not a function, is what ?

#  😨 問題発見
 
行けるやろ、と TypeScript を 3.9 -> 4.2 に上げました。トランスパイルするだけだし、バグるわけねーよね。とか期待して。そして...

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315145/95761b8f-0aee-c05b-8384-4c8dc540bdc9.png)

というエラー出ちゃったわけですよ。なんすかね、`.__spreadArray` って。

# 😋 解決方法

`.__spreadArray` をググると、以下のようなツイートが見つかる。合法的に業務中に twitter に入って内容を見てみる。`tslib` 、なるほどね。`package.json` にないわw

https://twitter.com/nakamu_wip/status/1379097644165865473

というわけで、お決まりのあのコマンド実行します

```bash
$ yarn add -D tslib
```

tsconfig も、tslib を読み込めるように変更が必要っぽいです。

```tsconfig.json
{
  "compilerOptions": {
    /* Visit https://aka.ms/tsconfig.json to read more about this file */
    // ...

    "importHelpers": true,                 /* Import emit helpers from 'tslib'. */
    "moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */

    // ...
  }
}
```

という感じで解決しました。そして `__spreadArray` なのですが、これは tslib に含められている関数みたいです。(https://www.typescriptlang.org/tsconfig#importHelpers)

配列の分割代入を関数として定義している模様、なのでその関数を注入しないとだめみたいです。
Ruby 問題⑦  末尾の2文字だけ取り出す

#はじめに

とうとうプログラミングスクール卒業の日となりました。

少し寂しいですがまだスタートラインにも立ってないので学習を続けます！

#問題

対象の文字列から末尾にある2文字を取得し、それらを3回数繰り返して出力するプログラムを実装して下さい。

```
#出力例
extra_end('nice') → 'cecece'
extra_end('abc') → 'bcbcbc'
extra_end('she') → 'hehehe'
```


#ヒント

雛形は下記になります

```.rb
def extra_end(str)
  # 処理
end

# 呼び出し例
extra_end('tokyo') 
```

・ sliceメソッドを使います。
配列や文字列から指定した要素を取り出すことができるメソッドです。

公式ドキュメント

https://docs.ruby-lang.org/ja/latest/method/String/i/slice=21.html


```.rb
def extra_end(str)
  char_num = str.length
  right2 = str.slice(char_num - 2, 2)
  puts right2 * 3
end

extra_end('tokyo') 
```

まずは仮引数に今回の場合は'tokyo'が入ります。

char_numには仮引数で渡した文字列の文字数を知りたいので　.length を使います。

```.rb
def extra_end(str)
  char_num = str.length
  puts char_num
end

extra_end('tokyo') 

=>5
```

このように数字が返り値として返ってきます。

そして文字を抜き出すために、　sliceメソッドを使います。

```
.slice( 開始位置, 終了位置(省略可能) )
```
後ろの2文字を取り出したいので

```.rb
str.slice(char_num - 2, 2)
#char_numには数字なので5 - 2がされてます。なので開始は3文字目から2文字とるという記述になります。
```

あとは3掛けて同じ文字を3つ出す事が出来ます！
ffmpeg でタイトルを埋め込み

#ffmpeg でタイトルを埋め込む為の忘備録
aac とか m4a とか mp4 な音声ファイルに対応

```shell
ffmpeg -i 音声ファイルネーム \
        -metadata title="しほティファイ 20210529放送分 JOGU-FM" \
        -c copy \
       出力ファイルネーム
```
【覚書】ts-node で Node.js のバッチを書く

TypeScript でバッチを書いたり簡易サーバー立てたりしたいと思ったけど、
あんまり余計なものを入れないでやりたいので、その方法を調べた。

# 基本

まず ts-node を入れる。

```
npm i typescript ts-node @types/node
```

tsconfig.json はこうする。

```json
{
  "compilerOptions": {
    "module": "ESNext"
  }
}
```

package.json は以下の内容を追記する。
`--experimental-loader=ts-node/esm` することで ts-node 経由で実行され、
`--es-module-specifier-resolution=node` することで import 時の拡張子省略が許容される。

こうしないと、`ERR_UNKNOWN_FILE_EXTENSION` だの `ERR_MODULE_NOT_FOUND` だの
`ERR_UNSUPPORTED_DIR_IMPORT` だの言われる。

```json
{
  "scripts": {
    "start": "node --experimental-loader=ts-node/esm --es-module-specifier-resolution=node path/to/index.ts"
  }
}
```

## `Cannot use import statement outside a module` 対策

`Cannot use import statement outside a module` と怒られたら、
package.json に `{ "type": "modules" }` を追記する。

もしルートの package.json に`"type": "modules"` を書きたくない場合は、
作業ディレクトリを分けて、その中に `{ "type": "modules" }` とだけ書いた package.json を置けばいい。

```
./
+- package.json (書き換えたくない)
`- path/to/
   +- index.ts
   `- package.json (これを追加する)
```

# ホットリロードに対応する

nodemon を入れる。

```
npm i nodemon
```

以下の serve を追記する。

```json
{
  "scripts": {
    "serve": "nodemon -x \"npm start\" -w path/to/**/* -e ts,json"
  }
}
```

これで `path/to/**/*` の ts, json ファイルが変更された時、npm start が実行される。

# まとめ

```
npm i typescript ts-node @types/node nodemon
```

```json
{
  "type": "module",
  "scripts": {
    "start": "node --experimental-loader=ts-node/esm --es-module-specifier-resolution=node path/to/index.ts",
    "watch": "nodemon -x \"npm start\" -w path/to/**/* -e ts,json"
  }
}
```

```json
{
  "compilerOptions": {
    "module": "ESNext"
  }
}
```
ffmpeg でジャケット(サムネイル)を aac とかに

#ffmpeg でジャケットのサムネイルを埋め込む為の忘備録
aac とか m4a とか mp4 な音声ファイルに対応

```shell
ffmpeg -i 音声ファイルネーム \
        -i サムネイル画像ファイルネーム \
        -map 0:a \
        -map 1:v \
        -c copy \
        -disposition:1 attached_pic \
        出力ファイルネーム
```