OmniAICreator/Qiita-1.07M huggingface dataset:
Atcoder 緑になりました

# はじめに
桜も散り若葉が輝く季節、皆様いかがお過ごしでしょうか。

この度、緑コーダーになりましたのでご報告いたします。
![20210425a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/e9d35924-a31c-4519-97d3-c5147ab65869.png)
# 道のり
`2019-09-28`から`2021-04-25`まで574日間、いやあ本当に才能がないですね。
![20210425b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/4d35454f-b1ed-ccd9-fda7-7c93a1dcb2af.png)
ここまで時間が掛かったのは、茶埋めにこだわり過ぎて、緑や水色Diffをやらなかったことと反省しています。
![20210425c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/8a3c2075-b3e1-b5b9-ff10-1bd48cde4267.png)
しかし、`2020-03`に茶コーダーになったときはまだ`Perl`でプログラミングしていたわけで、そこから`Ruby`に転向し`2020-05`に[Ruby 技術者認定試験 Silver に合格しました](https://qiita.com/superrino130/items/0b22c639bacc43ec9282)したり、`2020-11`に[Ruby 技術者認定試験 Gold に合格しました](https://qiita.com/superrino130/items/328854a699658ed72d30)したりとサボっていたわけではないです。
ただし、木構造とかいまだ苦手ですし、ABCの下位ではあまり出題されない動的計画法にやたらと凝ったり（[Ruby で解く AtCoder ABC 128 C 動的計画法](https://qiita.com/superrino130/items/1778ce4c4101221c0c88)/[Ruby で解く AtCoder ABC057 C 動的計画法](https://qiita.com/superrino130/items/10f89c36e03bb9cf4b8e)/[Ruby と Python で解く AtCoder ABC178 D 動的計画法](https://qiita.com/superrino130/items/2739f720c884f35a2bea)/[Ruby と Perl と Java で解く AtCoder ABC 129 C (後編) 動的計画法](https://qiita.com/superrino130/items/b9cad212d64f8bcb0eda)/[Ruby と Python で解く AtCoder ABC011 C 動的計画法](https://qiita.com/superrino130/items/9f7f10c3c18d7d98cd75)/[Ruby と Python で解く AtCoder ABC153 E 動的計画法](https://qiita.com/superrino130/items/a00e035222911da60d1e)/[Ruby で解く AtCoder Educational DP Contest D ナップサック問題](https://qiita.com/superrino130/items/b0564afdd103ef0f6a12)/[Ruby で解く AtCoder Educational DP Contest E ナップサック問題](https://qiita.com/superrino130/items/6e687b73cb788a1960c6)）、効率の悪いこともしています。
# まとめ
+ AtCoderさん　ありがとうございます
+ AtCoder Problemsさん　ありがとうございます
+ 百折不撓
+ やり方は何通りでもある
+ プログラミングを楽しもう
お名前.comとAWSでドメインとHTTPS設定

●手順1
route 53でホストゾーンを追加
ネームサーバーが表示させる
ついでにAレコードも追加する

●手順2
お名前.comのネームサーバーに
手順１で表示されたネームサーバーを設定する


●手順3
Certificate Manager
で証明書のリスクエスト

●手順4
Route 53でレコード作成して認証させる

●手順5
aws ロードバランサー側でも
証明書を追加する
nRF52840-DKを操作するための環境構築

#nRF5系のSDKを入れる
SoftDevice S140とnRF5SDKにチェックを入れ[ダウンロード](https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52840/Compatible-downloads#infotabs)。
* ソフトデバイス
    * S113
        * small BLE5(ペリフェラル、セントラル用）
    * S140
        * BLE5(ペリフェラル、セントラル用）
    * S340
        * BLE5(ペリフェラル、セントラル用)&ANT


    


# Windowsバージョン
[リンク](https://www.segger.com/downloads/embedded-studio)からSeggerEmbeddedStudioを導入する。(Nordicセミコンダクター製チップを扱うための統合開発環境。
インストール時は特に設定はなく次へと進んで終わらせる。



参考https://qiita.com/usashirou/items/7b0156170a3d636a393c
# Macバージョン

macのバージョンを選んでダウロード、[インストール](https://www.segger.com/downloads/embedded-studio)。

参考https://qiita.com/KentaHarada/items/341a0d5c9571da3aaf32

#mac(brewを使う)
[caskの使い方が新しくなっています。](https://www.mathkuro.com/mac/brew-cask-command-error/)
もともとは`brew cask install gcc-arm-embedded`を使っていたようですが、caskの使い方が新しくなり、
`brew install gcc-arm-embedded --cask`と入力してください。
参考https://gist.github.com/BryanJBryce/43f5e36475fd5cd1336136c6154b2d13
#Windows,Mac共通
nRF Connect for Desktopを[インストール](https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Connect-for-desktop/Download#infotabs)する。


nRF Connectが起動したらBLEとProgrammerのツールを入れる。

#nRF54820にソフトデバイスを書き込む。
1.nRF Connect for Desktopを起動してProgrammerをOpenする。
2.Select deviceから書き込み対象を選択する
3.先ほどダウンロードしたs140_nrf... .hexをドロップする。(DeviceDownload.zipの中にある。）
4.Writeをクリックしてソフトデバイスを書き込む。
5.Readをクリックし、nRF54820にFile memory layoutと同様のものがあるかどうかを確認する。

#サンプルプログラムのビルドと書き込み
DeviceDownload/nRF5SDF/nRF5_SDK...dde/examples/ble_peripheral/ble_app_blinky_c/hex/ble_app_blinky_c_pca10040_s140.hex　左のファイルを使う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256914/f5b33922-01ab-bbf5-eeea-7ff7d026fc29.png)
ソフトデバイスとサンプルプログラムを書き込むと上の写真のようになる。

#動作確認
nRF Connect for Desktopを起動してBluetooth Low Energyをopenする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256914/73c537c6-b071-1b34-6740-2d4af380e60b.png)
デバイスが認識されていると画像のようになる。










###### 参考文献
https://qiita.com/Kosuke_Matsui/items/5d61ce77e928b9f117cc
C++言語の基礎　第1弾：C++言語とは

# #C++言語の基礎< C++言語とは >

##はじめに
C++言語の基礎を簡単にまとめていくことで理解を深めていくことが目的である．その第1弾として，「C++言語とは」を扱う．

##環境
#####コンピュータ
|||
|:-:|:--|
|デバイス|MSI|
|プロセッサ|Intel(R) Core(TM) i5-7300HQ CPU @ 2.50GHz 2.50GHz|
|実装RAM|8.00 GB (7.89 GB 使用可能)|
|OS|Windows (Windows 10 Home, バージョン：20H2)|

####C++
|||
|:-:|:--|
|Editor|Visual Studio Code|
|Compiler|Minimalist GNU for Windows|


##C++言語の特徴
####長所
* C言語と互換性があり，ソースコードの再利用ができる

* 独自のフレームワークを必要とせず，ネイティブコードが得られる

* C言語よりもセキュリティの面が優れる

####短所
* （ほかの言語に比べて）言語仕様が複雑

* 標準ライブラリが少ない

* メモリ管理機能が存在しない

##オブジェクト指向
####オブジェクト
あらゆるものをすべて「モノ（Object）」として表現するという考え方

* **メソッド** ・・・ オブジェクトの操作部（動きを表す部分）
  
* **属性** ・・・ メソッドを制御するためのパラメータ要素
  
####クラス
* オブジェクトをインスタンスとして，大量に生産するための設計図
  
* プログラムで実際に書くものはクラスと呼ばれる

##感想
C言語についてはある程度学んでいる．しかしながら，C++言語をしっかりと勉強したことはなかった．今回はかなり大まかな情報であるが，とりあえずC++言語についての大まかな情報を念頭に置きながら，学習を進めていきたい．

##参考文献
1週間で身につくC++言語の基本　　　　　　　シフトシステム株式会社
( https://cpp-lang.sevendays-study.com/index.html ) 2021/04/25
firebase.auth().onAuthStateChangedで同期処理を行う[Nuxt/Vuex]

###awaitつければいい？
 firebase.auth().onAuthStateChangedはPromiseを返さないので前にawaitなどをつけても意味がありません。
###コード
以下のように記述すると同期処理を行ってくれました。

```javascript:store/auth.js
import firebase from "firebase";

export const actions = {

async getUserData({ state, dispatch , ... }) {
//関数をPromise化して宣言しているだけです、あとで使います↓
    function auth() {
      return new Promise(resolve => {
        firebase.auth().onAuthStateChanged(async user => {
          //awaitが使えます。引数の「user」を使った処理を書きます。
          resolve(返す値); //特にないならresolve()でok
        });
      });
    }
    //ここからが実際に実行される内容の部分です↓
    try {
      await auth(); //先程宣言した関数を使用
      //ここの処理は auth()が終わるまで実行されません
      return true;
    } catch (e) {
      console.log(e);
      return false;
    }
  },

//戻り値を使用する場合↓
let result = await dispatch("getUserData");
if(result){
//正常に実行された場合の処理
}else{
//エラー時の処理
}

```
async user => { の部分はasync function(user){ と同じです
AWS CLIでのCloudWatchアラーム作成方法

# AWSのCloudWatchについて
AWSの各サービス（EC2, S3, ELB等）に関して任意のメトリクスやログに基づいてアラートを通知したり、システムを監視をしたりできるサービス。
複数監視項目を組み合わせて、アラートをメールやSlackに通知することも可能。

# CloudWatchのアラーム作成
基本的には、[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/ConsoleAlarms.html)にしたがってGUI上で必要項目を1アラーム毎に設定していく。
⇒数個のアラームであれば問題ないが、数が多くなると手間がかかる問題

# AWS CLIから設定JSONを元にアラームを作成する方法
この問題を解決できるかつ、似たような設定のアラートを複数個設定する場合はこの方法でやると便利。

以下、設定手順を説明する。
### ①設定ファイル作成に必要なメトリクス情報を表示する。

```
aws cloudwatch list-metrics --namespace [監視対象のNameSpace]
```
ここで表示されたメトリクスの`Dimensions`をメモする。
`--metric-name 'mem_used_percent'`オプションでmetric nameでフィルタリングもできる。

### ②設定用JSONファイルを作成する。`Dimensions`欄には①でメモした物を入力する。
今回はサンプルとして「メモリ使用％が60秒の区間で90％以上に1データ点でもなった場合に場合にアラートを出す」アラームの設定ファイルを載せる。

```:設定JSONファイルサンプル
{
  "AlarmActions": [
    "arn:aws:sns:ap-east-1:~:cloudwatch_alarm-sns"  // SNSのARN
  ],
  "AlarmName": "memory-utilization-90",  // 設定したい好きなアラーム名
  "AlarmDescription": "60秒内の1データポイントのmemory-utilization >= 90",  // アラームの説明（なくても良い）
  "Namespace": "Name space",  // 監視対象のNameSpace
  "MetricName": "mem_used_percent",  // 監視対象のメトリクス（今回は使用メモリの％）
  "Dimensions": [
    {
      "Name": "ServerName",
      "Value": "Server 1"
    },
    {
      "Name": "host",
      "Value": "ip-~"
    }
  ],
  "Statistic": "Maximum",  // 今回の場合は60秒区間ごとの最大値を評価
  "Period": 60,  // 何秒間の中で条件を満たした場合にアラートを出すか
  "EvaluationPeriods": 1,  // 区間内で何データ点条件を満たした場合にアラートを出すか
  "Threshold": 90,  // 閾値
  "ComparisonOperator": "GreaterThanOrEqualToThreshold" // 今回の場合は閾値以上の場合
}
```

使用可能なパラメータに関しては[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-cw-alarm.html#cfn-cloudwatch-alarm-datapointstoalarm)を参照

### ③CLIで②で作ったJSONのパスを指定してCLI上でアラームを設定する。

```
aws cloudwatch put-metric-alarm --cli-input-json file://alarm-path.json
```

ちなみに、`--cli-input-yaml`とすればyamlでも設定ができる。

# 参考
https://bbh.bz/2019/08/29/setting-cloudwatch-alarmby-cli/
https://qiita.com/moomindani/items/aef16aa93db56b071ba3
https://hacknote.jp/archives/43635/
https://recipe.kc-cloud.jp/archives/9733
https://recipe.kc-cloud.jp/archives/9765
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/viewing_metrics_with_cloudwatch.html
https://aws.amazon.com/jp/premiumsupport/knowledge-center/cloudwatch-set-anomaly-detection-alarm/
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-usage-skeleton.html
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/quickref-cloudwatch.html
CakePHP4で作ったAPIをPostmanで確認する

# はじめに

- モックAPIを作ったが、PostmanでモックAPIのレスポンスを確認するまで めちゃくち手こずったので、まとめます

# 追記（2021年10月30日）

CakePHP のバージョンを 4.3.0 に上げ、CSRF の設定値の記載個所も 4.3.0 標準へと変更してから以下のエラーが発生するようになったため、 [#確認するための設定値](#確認するための設定値) を更新しました

`Error: CSRF token from either the request body or request headers did not match or is missing.`

CakePHP で form を render する画面を用意しておかないと、POST、PUT、DELETE は API の疎通確認できないのかな・・・

# 前提

- CakePHP --version
    - 4.1.6
- Postman --version
    - 8.2.3
- CakePHP の CSRF は有効
    - 確認に利用したリポジトリ↓

<https://github.com/q23isline/reinventing_the_wheel>

# 確認するための設定値

- Postman の Headers タブに、以下を設定することで、GET のレスポンスを確認できる

||KEY|VALUE|DESCRIPTION|
|---|---|---|---|
|✓|Cookie|PHPSESSID=xxxxxx; csrfToken=xxxxxx||

- ↑の xxxx に設定する値は、同じアプリケーション（<http://localhost>）を開き、Chrome の「デベロッパーツール」の「Application」タブのサイドメニューの「Cookie」の値

![postman_headers_setting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586387/83d5c9b7-eb9d-4998-6b36-9a58e816cc63.png)

- POST、PUT、DELETE のレスポンスを確認するには、↑に加えて Body の raw の JSON で以下の設定が必要

```JSONC
{
    // 画面の HTML を表示し、input タグの name が _csrfToken の value の値
    "_csrfToken": "xxxxxxxxx",
    // .....
}
```

![postman_body_setting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586387/56f754f7-9c3e-1ae2-6e21-1001e071caf9.png)

# おわりに

- ↑だけじゃなく、CakePHP4 で、 `$this->log()` が配列ダメになったとか、レスポンスBody の JSON パラメータ取得で `$this->request->data('exampleKey')` じゃなくて `$this->request->input('json_decode')->exampleKey` しなきゃ取れんとか、気づくまで時間がかかりました
- 参考になれば幸いです！
【iOS】App Store申請の方法

##背景
最近初めてのAppStoreへ申請までたどり着き、リリースしたので、手順をまとめてみました。

##申請手順

⓵ 本番用の証明書の発行
・Xcodeで [Preference] → [Account] で 開発用アカウントでログイン。
・該当するチームを選択して、[manage certificates]をクリック。　左下の「+」から「Apple Distribution」を選択して証明書を作成。
・Developer Center にログインして、証明書をダウンロードする。

⓶プロビジョニングファイルの作成
・Developer Centerにログイン(⓵と同じアカウント)
・[Profile] → [App Store]を選択して、[Continue]
・該当するApple IDを選択して、[Continue]]
・⓵で作成した、証明書を選択して[Continue]
・[Profile]で作成したプロビジョニングファイルを[Download]しておく。

⓷Xcodeで作成したプロビジョニングファイルを使用するように設定する
・[Project] → [Targets] → [Build Setting] → [Signing] → [Code Signing Identity]で「IOS Distribution」を選択
・[Project] → [Targets] → [General] → [Singing (Debug)] の[Provisioning file]から[Download Profile]を選択。⓶で作成したプロビジョニングファイルを選択する。

⓸アーカイブする
・Xcodeのメニューバーから、[Product] → [Archive]
・恐らく「codesignは、キーチェーンに含まれるキー"xxxx"へアクセスしようとしています。許可するには、キーチェーン"ログイン"へのパスワードを入力してください」というダイアログが出るのでパスワードを入力して、[常に許可]をクリックする。
・Organizer画面が表示される。

⓹リリース用のビルドが申請上問題がないかをチェック
・Organizer画面にて[Validate App]をクリック
・App Store Connect distribution options画面で、各ボタンのラジオボタンを選択して、[Next]をクリック。
・Select certificate and iOS App Store profiles画面にて、「Distribution certificate」で⓵で作成した証明書を選択する。
・「Select Profile」で⓶で作成したプロビジョニングファイルを選択する。
・ipaファイルが作成されるので、[Validate]をクリックすると検証が始まる。
・OrganizerのTOP画面にてアプリの「status」が「Validated」になればOK

⓺アプリをAppStoreにアップロード
・[Distribute App]をクリック。
・Select a metod of distributionにて、「App Store Conect」を選択して、[Next]をクリック
・Select a distinationにて、「Upload」を選択して[Next]をクリック
・App Store Connect distribution optionsにて、各項目を選択して[Next]をクリック
・Select certificate and iOS App Store profiles画面にて、「Distribution certificate」で⓵で作成した証明書を選択する。
・Select certificate and iOS App Store profiles画面にて、「Select Profile」で⓶で作成したプロビジョニングファイルを選択する。
・ipaファイルが作成されるので、[Upload]をクリック

⑦AppStore Connectで必要な情報を入力する。
・⓺が完了すると「App Store Connect: Version 1.0.6 (1) for アプリ名 has completed processing.」のようなメールが送信される。
・メールが来たら「App Store Connect」を開いて、iOS Appの隣の[ + ]ボタンをクリックして、今回のバージョン番号を入力する。
・以下各項目に必要な情報を記載して[提出]をクリック。(※今回は審査後に手動でリリースを選択しました。)
○アプリ名
○サブタイトル
○カテゴリ
○アプリの概要文
○プロモーション用テキスト
○アプリの価格
○アプリのレーティング
○検索のためのキーワード
○サポートURL
○プライバシーポリシーURL
○Appのプライバシー
○App Store用のアイコン
○スクリーンショット
○連絡用のメールアドレス、電話番号
○アップデート内容を説明する文
○輸出コンプライアンスの設定

⑧審査完了後リリース
・審査完了後に「now "Pending Developer Release"」がタイトルに入っているメールが送信される。(※１日で審査は完了しました。)
・上記メールが送信されたら、AppStoreConnectにログインして、リリースをクリック。
・暫くしたらAppStoreに反映されます。

##まとめ
今回は初めて、iOSアプリの開発〜リリースまでを経験しました。
大変でしたが、色々と勉強になったので良しとします！初めてリリースする方等の助けになればと思います！

参考:
○輸出コンプライアスについて
https://qiita.com/osamu1203/items/35df25d93e9d12b11222

○AppStore申請の一連の流れ
https://zenn.dev/moutend/articles/feebf0120dce6e6426fa
https://qiita.com/koji4104/items/5f4d717cba6e5223b552
テーブルのデータをビューに表示させる方法（Ruby on Rails）

#プログラミング学習のための備忘録
2021/04/25
Ruby on Railsで資産管理アプリを作成しています。
備忘録として、作成したテーブルのデータをWebページに表示させる流れをまとめました。

#コントローラを作成しよう
アクションを定義するためのコントローラとビューファイルを作成します。以下のコマンドを実行する。

```html:ターミナル
$ rails g controller dividends index
```

#テーブルに保存されたデータをビューに表示しよう
以下のステップを踏むことで、テーブルに保存されたデータをビューに表示することができる。
・コントローラのアクションで、モデルからテーブルのデータを取得する。
・受け取ったデータを変数に代入する。
・変数をビューに表示させる。

#テーブルのデータを取得する
コントローラのアクションで、モデルからテーブルのデータを取得する処理を定義する。今回は、テーブルに保存されているデータ全てを取得する。テーブルに保存されている全てのデータを取得する場合、`モデル名.all`で取得することができる。
取得したデータを`dividends`という変数に代入する。

```ruby:dividends_controller.rb
class DividendsController < ApplicationController
  def index
    @dividends = Dividend.all
  end
end
```

#ビューに表示させる
eachメソッドを用いて、取得したデータの内、nameカラムのデータを全て表示させる。

```html:index.html.erb
<div class="main posts-index">
  <div class="container">
    <% @dividends.each do |dividend| %>
      <div class="dividends-index-item">
          <div class="dividend-name">
            <%= dividend.name %>
          </div>
      </div>
    <% end %>
  </div>
</div>
```

テーブルに保存されたデータをビューに表示するための処理は以上になります。最後に、指定のURLにアクセスした時に、ビューファイルを表示させるようにルーチングを追加する。

```ruby:route.rb
Rails.application.routes.draw do
  get "/dividends/index" => "dividends#index"  

  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
```


#結果
今回は、仮のデータをコンソールで入力してみました。無事に銘柄名が表示されました！

![スクリーンショット 2021-04-25 22.42.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1382306/c69a551b-f80d-e6c7-e596-7a1f9a22549d.png)

<h1>次にやること</h1>
データを入力できるフォームを作成する！

#参考文献
[https://qiita.com/Hal_mai/items/aed97a6aba2293450a74](https://qiita.com/Hal_mai/items/aed97a6aba2293450a74)
DXにおける開発

# DXにおける開発
- DXは価値が最初から出るものではなく、仮説検証を繰り返すことによって価値を作り出してく。
- そのため、繰返し型の開発手法とそれに耐えうる開発環境、インフラ、ソフトウェアアーキテクチャが必要となる。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299677/b5cb4d80-7426-d491-69a3-fed6e7f0c193.png)

# 1. 開発方法：アジャイル
- 「あらかじめ全工程にわたる計画を立て、それを実行する」という開発プロセスではなく、開発中に発生する様々な状況の変化に対応しながら開発を進めていく手法。

- アジャイル開発では、チームを組んで「要件定義→設計→開発→テスト→リリース（運用）」といった開発工程を、1つの機能を単位とした小さいサイクルで繰り返します。このような小さいサイクルを繰り返すことで、個々の機能の開発が独立して完結するため、開発期間中の仕様変更の発生に強く、リスクを最小化させることが可能。

- この小さなサイクルの繰り返しを、アジャイル開発では「イテレーション（反復）」と呼んでいます。イテレーションは1週間から4週間ごとが一般的であり、イテレーションごとに機能をリリースすることを繰り返す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299677/ab1e31a4-268d-66bb-2096-1d9560b723f7.png)

# 2. 開発環境：DevOps
- コラボレーションツールによる情報共有や密なコミュニケーション、継続的インテグレーションツールなどによる導入・展開（デプロイ）の自動化、設定自動化ツールなどによる環境設定の自動化やコード化などがある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299677/22482795-8175-7bdb-ab29-00da2574af8f.png)

#3. インフラ：クラウド
- オンプレではシステムの拡大を行う際に、ハードウェアの手配リードタイムや構築の工数・コストがかかる。
-クラウドではプロバイダーに拡大を要求するだけで即時にコストを抑えてシステム拡大を実現することが出来る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299677/48d510a7-7b65-6fc4-a33a-fa8dbb7f2880.png)

#4. ソフトウェアアーキテクチャ（1/2）：コンテナ
- OS上のアプリケーションの動作環境を仮想的に複数に区切った単位。各コンテナはOSや他のアプリケーションのプロセスから隔離された環境に足るため、システム変更が容易で、再利用性も高くなる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299677/3899df23-082a-3910-7beb-8f7ddee585c8.png)

#4. ソフトウェアアーキテクチャ（2/2）：マイクロサービスアーキテクチャ
- 小規模かつ軽量で互いに独立した複数のサービスを組み合わせてアプリケーションを開発するもの
- マイクロサービスの導入によってアプリケーションを疎結合化し、サービスごとのデプロイ（展開）の柔軟性、拡張性を高める狙いがある。
- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299677/ddec62b4-0daa-9ca7-a03d-15865f86863d.png)
VBA フォルダの更新日時を取得 その1

```
Sub test1()
    Dim fso As FileSystemObject
    Set fso = New FileSystemObject ' インスタンス化
    
    Dim fl As Folder
    Set fl = fso.GetFolder("C:\Windows") ' フォルダを取得
    
    Dim d As Date
    
'    d = fl.DateCreated      ' 作成日時を取得
'    d = fl.DateLastAccessed ' アクセス日時を取得
    
    d = fl.DateLastModified ' 更新日時を取得
    Debug.Print (d)
    Debug.Print Hour(d) & ":" & Minute(d)
    
    ActiveSheet.Range("A1") = d
    ActiveSheet.Range("A2") = Hour(d) & ":" & Minute(d)
    
    ' 後始末
    Set fso = Nothing
End Sub
Laravel バリデーションを実装したら403エラーが帰ってきた

# 目的

- Laravelで新規のRequestクラスを作成してバリデーションを実装したら４０３エラーが返されたので何が間違えていたかメモ的にまとめる

# 原因

- Requestクラスの中の`authorize()`メソッドの戻り値がfalseのままだった。

    ```Request.php
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return false;
    }
    ```

- 「Determine if the user is authorized to make this request.」と記載されており、翻訳すると「ユーザーがこの要求を行うことを許可されているかどうかを判別します。」と説明されている。
- ユーザーからPostされたデータをバリデートしたい時は当該メソッドの戻り値をtrueに設定する必要がある。

    ```Request.php
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }
    ```

# 教えていただいた内容

- @nunulk様にコメントで教えていただきました。
- ユーザーによる要求の許可の必要がない場合authorize()メソッドを削除してしまっても良いそうです！
PF用のAWSサーバに大量のログイン試行のログがあった話


全容は[この記事](https://blog.katsubemakito.net/linux/sshd-ipaddress-check)を見てください。
めちゃくちゃ参考になります。
https://blog.katsubemakito.net/linux/sshd-ipaddress-check

Twitterでふと上の記事が流れてきて、「へぇ～ログイン攻撃ってあるんだなぁ～」と思って私も試しにコマンドを叩いてみました

```console:linux
$ sudo cat /var/log/secure | grep 'Invalid user'
```

そうしたら、めちゃくちゃ出るログイン試行の跡。ナニコレ怖い！！！！
また記事に乗っているコマンドを試してみる。

```console:linux
$ sudo cat /var/log/secure* | grep 'Invalid user' | cut -f2 -d' ' | sort | uniq -c
```

するとすると、一日1500件くらいログイン試行があるじゃないか･･･！怖いんだけど！！！
スクールのメンターさんにドキドキしながら聞きました。
私はcloud9の1つからしかログインしないので、cloud9で

```console:console
$ curl ipconfig.io
```
を入れて出てきたIPアドレスをどっかにメモ(後で入力する)
EC2→インスタンス→該当のEC2インスタンス→セキュリティー→セキュリティーグループをクリック
インバウンドルールを編集をクリック→SSHのところのソースに自分のIPアドレス/32を入力
で出来ました！

皆様もお気をつけて･･･

SSH接続についてはこちらの記事が参考になりました。
https://qiita.com/tag1216/items/5d06bad7468f731f590e
setterを書くな高校校歌

#setterを書くな高校校歌
##作詞作曲:わたくし
迷光が巡る丘の上
値を代入するためにsetterを書こうとするな
若きアプリだとあなどらず
ロジックを持つクラスはコンストラクタで値を与えなさい

```java:SetterDame.java
public class SetterDame {

    String value;
    
    //好き
    public SetterDame(String input) {
        this.value = input;
    }

    //よくない
    public setValue(String input) {
        this.value = input;
    }
}
```

大空へと今飛び立とう
Listの場合はreturn new コンストラクタで命を与えてやれ

```java:SetterDame.java
public class SetterDame {

    List<String> values;
    
    //可視性好き
    private SetterDame(List<String> input) {
        this.values = input;
    }

    //好き（staticでも良い）
    public create(List<String> input) {
        return new SetterDame(input);
    }
}
```

setterはアプリがでかくなるとマジで追えなくなるぞ
おぉ　我らがsetterを書くな高校
setterを書くな高校

#参考書籍
[現場で役立つシステム設計の原則 ～変更を楽で安全にするオブジェクト指向の実践技法～　増田亨 著（技術評論社 2017年）](https://www.amazon.co.jp/dp/B073GSDBGT/ref=cm_sw_r_tw_dp_530KW06T4AMS87RFPC3B)
[SQL] LeetCodeの無料問題集を活用して、SQLを使いこなし（1）

##Q175 Combine Two Tables
![Q175_SQL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082021/8fe79560-6ad8-14e6-dd98-c77f374fa7c9.png)


<b>左テーブル：Person
右テーブル：Address</b>

###質問：
各人のアドレスがあるかどうかに関係なく、Personテーブルの各人に次の情報（※）を提供するレポートのSQLクエリを記述します。
※FirstName, LastName, City, State

###結合の種類
1）left （outer）join：
     左テーブルの情報を全部残し、右のテーブルに対になる情報があれば表示する。

2）right（outer） join：
     右テーブルの情報を全部残し、、左のテーブルに対になる情報があれば表示する。

3）inner join：共通の部分を結合し表示する。


###説明：
質問ではアドレスがあるかどうかに関係なくと記載されていますので、
Addressのテーブルは補足情報として、Personテーブルにいる人の情報を補足すれば良いと思います。

また、二つの表を結合するので 、共通のkeyで繋ぎます。
ここで、共通のkeyはPersonIDです。

###Codeの書き方のHINT:
Select （ピックアップしたいデータ）　
From （データを全部残したいテーブル）　as A
Left join （補足情報） as B
On A.共通key=B.共通key




###Code：
```SQL:
select FirstName, LastName, City, State
from Person A
left join Address B
on A.PersonId = B.PersonId;
```

###結果：
![Q175_result.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082021/6088f0d6-1e39-cf28-6162-d84109f68abd.jpeg)
Visual Studio Codeの穴場拡張機能

<h2>Bracket Pair Colorizerって使いやすい？</h2>
Visual Studio Codeの拡張機能でBracket Pair Colorizer(Bracket Pair Colorizer2)が有名です。[]、{}、()のペアを色分けしてくれるものですが、私にはどうしてもこれが使いやすいと思えず、他になにかないかを探していました。カッコの色分けをしてくれるのですが、逆に言うと<b>色分けしかしてくれません</b>。カッコを太字で強調してくれたらより見やすいのにと思って、Bracket Pair Colorizerを色々いじってみたのですが、挫折しました。
<h2>Bracket HighlighterとScoper</h2>
そんなときに見つけたのが<a href="https://marketplace.visualstudio.com/items?itemName=Durzn.brackethighlighter">Bracket Highlighter</a>と<a href="https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.scoper">Scoper</a>でした。Bracket Highlighterはカッコだけではなく、カッコの中まで修飾してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588692/a11d07cd-0864-32b4-f17e-aabf1fd48c6a.png)

例えばこんな感じで、カッコの外側の色を落とし、カッコの内側のバックグラウンドを変えるということができます。もちろん、カッコだけを強調することこともできます。色分けだけでなく、カッコの中の書体を変えることもできます。例えばこの例のような太字以外にも、斜体やアンダーラインということもできます。

ただ、Bracket Highlighterは文字のある部分の背景色しか変更できません。これだと見栄えが悪いと思われる方もいらっしゃるかもしれません。そのときに使えるのがScoperです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588692/0d6cc818-0390-e78b-1b49-9f08df8b294b.png)

Bracket Highlighterと併用し、双方の背景色を同じ色に設定するとこのように矩形で色分けしてくれます。これでカッコの範囲がすごくわかりやすくなります。カーソルをif分に合わせると・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588692/f2686ee7-74c9-6067-b85d-534f7a4e4b04.png)

こんな感じになります。この設定は以下のとおりです。背景が#666666なのは例示のためです。これだと見にくいので私は#222222にしています。blurOutOfScopeTextというのが、スコープ外のテキストを暗くするという設定で、blurOpacityがどれだけ暗くするかの設定になります。

<b>"BracketHighlighter.backgroundColor": "#666666",</b>
"BracketHighlighter.textColor": "none",
"BracketHighlighter.textDecoration": "none",
"BracketHighlighter.highlightScopeFromText": true,
"BracketHighlighter.maxLineSearchCount": 10000,
"BracketHighlighter.blurOutOfScopeText": true,
"BracketHighlighter.blurOpacity": "0.5",
"BracketHighlighter.letterSpacing": "1px",
"BracketHighlighter.fontWeight": "bold",
"BracketHighlighter.ignoreContent": false,
"BracketHighlighter.text": null,
"scoper.overviewColor": "#aa0000",
"scoper.endColor": "#003300",
<b>"scoper.highlightColor": "#666666",</b>
"scoper.extendHighlight": true

参考になれば幸いです。
Laravel+vueでなんか作る(Laravel基礎④ ～JSON Resource編～)

当記事はUdemyの講座、[Vue 3 and Laravel: A Practical Guide with Docker](https://www.udemy.com/course/vue-laravel-admin/)を進めるにあたり、理解を深めるために記された備忘録です。

この講座はフロントエンドをVue3のSPA、バックエンドをLaravelのAPIという構成でアプリを開発するのですが、この場合、JSONを用いた両者の通信を整頓するにはシリアライズが不可欠です。というわけで今回はResourceの使い方を見ていきます。


##Resourceとは何か？
Railsでいう所のシリアライザ。
コントローラが返すJSONのフォーマットを決められる。

```php:App\Http\Resources\UserResource
public function toArray($request)
    {
        return [
            "id"=>$this->id,
            "first_name"=>$this->first_name,
            "last_name"=>$this->last_name,
            "email"=>$this->email,
        ];
    }
```
コントローラ側でインポートし、以下のように使う。

- 一つだけ返す場合

```php
return response(new UserResource($user),Response::HTTP_CREATED);
```
- 配列を返す場合

```php
return UserResource::collection(User::paginate());
```

ちなみに、関連テーブルも返せる。
たとえばUserテーブルがRoleテーブルに``belongsTo``するなら、

```php:App\Http\Resources\UserResource
public function toArray($request)
    {
        return [
            "id"=>$this->id,
            "first_name"=>$this->first_name,
            "last_name"=>$this->last_name,
            "email"=>$this->email,
            "role"=>$this->role,
        ];
    }
```
と書けば、コントローラ側で``User::with("role")->find($id)``とか書かなくても、ちゃんとRoleテーブルをJoinしてくれるのだ。

```php
    public function show($id)
    {
        $user = User::find($id);
        return new UserResource($user);
    }
```
```json:返り値をPostmanで見るとこんな感じ
{
    "data": {
        "id": 24,
        "first_name": "John",
        "last_name": "Smith",
        "email": "01@test.io",
        "role": {
            "id": 3,
            "name": "viewer"
        }
    }
}
```

ちなみに、デフォルトではResourceを噛ませた返り値は「data」内に格納される。それが嫌な人はAppServiceProvider内で以下のように設定すれば裸で返せる。

```php:App\Providers\AppServiceProvider
use Illuminate\Http\Resources\Json\JsonResource;

//　～　中　略　～
    public function boot()
    {
        JsonResource::withoutWrapping();
    }
}

```
##入れ子のResource
実はResource内の返り値に別のResourceを使うこともできる。
上記のUserテーブルがRoleテーブルに``belongsTo``する例で行けば、

```php:App\Http\Resources\UserResource
return [
            "id"=>$this->id,
            "first_name"=>$this->first_name,
            "last_name"=>$this->last_name,
            "email"=>$this->email,
            "role"=>new RoleResource($this->role)
        ];
```
と書けば、``new UserResource($user)``のroleプロパティの構造は、``RoleResource``に準ずることになる。

```bash:Postmanの返り値は例えばこんな感じ
{
    "id": 24,
    "first_name": "John",
    "last_name": "Smith",
    "email": "01@test.io",
    "role": {
        "id": 3,
        "name": "viewer"
    }
}
```

##whenLoaded()
ただし、これには一つ欠点がある。
入れ子のResourceを使った場合、コントローラで返す値が``User::with("role")->find($id);``だろうが``User::find($id);``だろうが、強制的にRoleテーブルをJOINしてクエリを行うのだ。
これを改善するには、以下のようにResourceを書き換える必要がある。

```php:App\Http\Resources\UserResource
return [
            "id"=>$this->id,
            "first_name"=>$this->first_name,
            "last_name"=>$this->last_name,
            "email"=>$this->email,
            "role"=>new RoleResource($this->whenLoaded("role"))
        ];
```
これでコントローラの記述に準じたクエリを行ってくれる。
LeetCode日本語修行12日目- [897-二分木通りがけ順をします]

###Increasing Order Search Tree
#####参考：https://leetcode.com/problems/increasing-order-search-tree/
###問題の内容:
二分木Root、Rootの一番左のノードが木の根になり、すべてのノードの左の子はNULLで、右の子を1つだけ持つように、木を順に並べ替える。
###例:
例1:
Input: root = [5,3,6,2,4,null,8,1,null,null,null,7,9]
Output: [1,null,2,null,3,null,4,null,5,null,6,null,7,null,8,null,9]

```
      5
   3     6
 2   4     8
1        7   9

```

以下に変換：

```
 1
  2
   3
    4
     5
      6
       7
        8
         9
```
例2:
Input: root = [5,1,7]
Output: [1,null,5,null,7]
**左の子はNULLで,nullで表示します**
 

###ヒント:
The number of nodes in the given tree will be in the range [1, 100].
0 <= Node.val <= 1000

---
他のやり方もありますが、イテレーションを使います。。。

```Kotlin

/**
 * Example:
 * var ti = TreeNode(5)
 * var v = ti.`val`
 * Definition for a binary tree node.
 * class TreeNode(var `val`: Int) {
 *     var left: TreeNode? = null
 *     var right: TreeNode? = null
 * }
 */
class Solution {

    fun increasingBST(root: TreeNode?): TreeNode? {
         return inorder(root,null)
    }

    fun inorder(root: TreeNode?,pre: TreeNode?): TreeNode? {
        if(root == null){
            return pre
        }

        var currentValue =  inorder(root?.left,root)
        root?.left = null
        root?.right = inorder(root?.right,pre)
        return currentValue
    }
}
```
JavaScriptリファクタリング[文字列操作]

レガシーかつ酷いJavaScriptコードを少しづつリファクタリングしてみます。

**仕様**
「atiiq no tsop tsrif」の文字列を反転等で操作して「First post on Qiita」と表示する。



##STEP 0  
何をしているか分り辛いコード。こんなコードに出会ったことのない貴方は幸せ者。

```javascript
function reverse(string) {
  const reversed = string.trim()
                         .split('')
                         .reverse()
                         .join('');
  return reversed[0].toUpperCase()
                    + reversed.substring(1, 14)
                    + reversed[14].toUpperCase() 
                    + reversed.substring(15)
                    + (reversed[reversed.length -1] = ".");

};

reverse('atiiq no tsop tsrif');

```

##STEP 1 
1. reverse関数をアロー関数に変更
2. 文字列を返す関数を用意
3. セミコロンを削除
 
```javascript
const reverse = string => string.trim()
                                .split('')
                                .reverse()
                                .join('')

const target = string => string.indexOf('qiita')
...
```

##STEP 2
1. 投稿するサービスを定数で定義
2. ピリオドを文末に追加する関数を作成
3. 完成した文字列を返す関数を作成

```javascript
const serviceName = 'qiita'
...
const target = string => string.indexOf(serviceName)
...
function reverseSentence(string) {
  const reversed = reverse(string)
  const addPeriod = string => string
                            + (string[string.length -1] = "."
  return reversed[0].toUpperCase()
                            + reversed.substring(1, target(string))
                            + reversed[target(string)].toUpperCase()
                            + reversed.substring(target(string) +1)
}
...
```

##STEP 3
1. reverseSentenceをアロー関数に
2. 完成した文字列を作成するsentence関数を作成
3. タイポを防ぐためピリオドが文末に既に存在する場合は表示しない

```javascript
...
const sentence = string => string[0].toUpperCase()
                           + string.substring(1, target(string))
                           + string[target(string)].toUpperCase()
                           + string.substring(target(string) +1)
...
const addPeriod = string => string
                           + (string[string.length -1] === "." ? "" : ".")
const reverseSentence = string => sentence(addPeriod(reverse(string)))
...
```

##Done

``` javascript
const serviceName = 'qiita'

const reverse = string => string.trim()
                                .split('')
                                .reverse()
                                .join('')

const target = string => string.indexOf(serviceName)

const sentence = string => string[0].toUpperCase()
                           + string.substring(1, target(string))
                           + string[target(string)].toUpperCase()
                           + string.substring(target(string) +1)

const addPeriod = string => string
                           + (string[string.length -1] === "." ? "" : ".")

const reverseSentence = string => sentence(addPeriod(reverse(string)))

reverseSentence('atiiq no tsop tsrif')

>"First post on Qiita"
```
  
関数名で処理を伝えるようにしました。
ラズパイで実行するGO言語プログラムのDocker開発環境（GPIOとかはわからん）

# 概要
debianのgo入ったdockerイメージ使って`Makefile`でクロスコンパイルするときの設定わたしとくと、GPIOとかは無理だけど、そこそこラズパイ用のGO開発環境にできそう。

# はじめに
ラズパイでGO言語のプログラムを動かしたいときに、sshして開発しても良いと思うけど、複数人でなにか作りたいときとかはDocker環境で開発して出来たほうが良いかなーと思う。
クロスコンパイルして、そこそこテストして、実行ファイルだけラズパイにコピーして使う感じ。

ということで、ラズパイで動くGO言語プログラムを開発するためのDockerの設定をすこし整理した。
Dockerfileもdocker-compose.ymlもいまいちわかってないけど、動いてるから良しとした。
もっと、いい感じの書き方とかいい感じの設定あれば教えてほしいです。。。

結局、ラズパイとかいいつつ、GPIOもBluetoothも使ってないので、ただのdebian環境っていう・・・。

# 方針
軽くしらべたら、それっぽいイメージ提供してる人いたけど、詳細わかんないので、使わないことにした。GPIOとかをシミュレート？エミュレート？できるなら使ってみたい気はする。
[balenalib/raspberry-pi-golang](https://hub.docker.com/r/balenalib/raspberry-pi-golang)

golangのオフィシャルなイメージはdebianっぽいので、そのまま使うことにした。
[golang](https://hub.docker.com/_/golang)

Makefileに、`env GOOS=linux GOARCH=arm GOARM=7 go build`を書いておく。自分の持ってるラズパイは`uname -a`したら、`armv7l`って書いてあったから、`GOARM=7`にした。それで動いた。

githubの環境変数を渡してあげる。

# 詳細
こんな感じ。

```yml:docker-compose.yml
version: "3"

services:
  raspi:
    build: ./raspi
    environment:
      GITHUB_USER_NAME: ${GITHUB_USER_NAME}
      GITHUB_TOKEN: ${GITHUB_TOKEN}
      GITHUB_EMAIL: ${GITHUB_EMAIL}
    volumes:
      - "raspi.repo:/repo"
      - "raspi.go:/go"
    tty: true
volumes:
  raspi.repo:
  raspi.go:
```

githubの環境変数をわたしてる。
上記ymlファイルの下に`./raspi`ってフォルダを切ってDockerfileと最初に実行してほしいスクリプトをおいてる。

```Dockerfile
FROM golang:latest

LABEL Name="raspi"
LABEL Version="1.0.0"

WORKDIR /
ADD ./init.sh init.sh

ENV GITHUB_USER_NAME=github-user-name
ENV GITHUB_TOKEN=github-token
ENV GITHUB_EMAIL=github-email

RUN apt-get update && apt-get install -y \
    less\
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/*

VOLUME /go
VOLUME /repo
WORKDIR /repo

CMD ["bash", "/init.sh"]
```

`less`できないとストレスなので入れてる。

```sh:init.sh
#!/bin/bash                                                                                                                                   
cd /

git config --global user.name ${GITHUB_USER_NAME}
git config --global user.email ${GITHUB_EMAIL}
git config --global url."https://${GITHUB_USER_NAME}:${GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/"

while :; do sleep 10; done
```

もうちょい`go install`とかしといたほうがよいのかも。
最後のsleepがないと、たちあげるとき、`exit 0`って出して死んじゃう。


```makefile:Makefile
SHELL=bash

build:
        go build

build-raspi:
        env GOOS=linux GOARCH=arm GOARM=7 go build
```

ビルドするときの設定（↑）

あとは、適当にたちあげて使ったらよさげ。

```
docker-compose -f docker-compose.yml up -d --build
```

# おわりに
それっぽく動いてる。満足。
ただ、環境変数とか、volumeのこと、いまいちわからない。
Dockerfileとdocker-compose.ymlの使い分けがいまいちわからない。
軽く検索しただけじゃ、よくわかんないので、本読むか。。。
E資格取得してからのお話（やるぞ系）

# ０. はじめに
機械学習エンジニアパダワンなるぞって話をしてから、長い時間を費やした。。。
が、ついにE資格を無事に取得できました！ので、ここで一旦アウトプットします。

https://qiita.com/haman/items/53438bceeb2f148a14f4


# １．E資格取得の話
E資格取得で必要なことは、**認定講座を受けること**。
これが非常にハードル（特に金銭的）が高いのです。。。
なんとか会社でアピールしたら認められて、受講できました。


## 学んだこと
学習したコンテンツを手法を交えて図示するとこんな感じ。
なかなかのボリュームです。手を動かせる講座だったので、飽きずに楽しめた。← **超大事！**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/1f11218a-9f48-44ea-fa61-8d94d674a31c.png)

また、機械学習ライブラリを利用しながら、学習したため、
そこそこ実務に近い感じにはなったかな？という感想です。
※E資格では機械学習ライブラリはほぼ利用しないのです…。
https://paperswithcode.com/trends
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/42135c1e-2759-11f9-06a3-759f9bc890e4.png)


## 受けてよかったこと
- AI（主にDL）の理論に対する障壁が軽減した。
 - 記事読んでも分からない用語がずらり…だから見ない。が少なくなった。
わかると楽しい ⇒ だからやると更に分かるようになる。

- お尻に火が付いた。
 - 現場：エクセルで疲弊　vs　研修：AI
 - 淡々と2017年の手法は古い手法ですからねー、っていわれる。
 - 講師は社会人3-4年目の方

- 相談相手ができた。

## 勉強時間
こんなに時間をかけたの久しぶり。
①を除いても、**120時間弱**。「時間はすべてを制す」スタンス健在。
落ちる恐怖と事前情報（AIの最高峰の試験）ゆえに、過剰にやり過ぎた感じはする。

- ① 11月中旬～12月中旬：指定カリキュラム受講（6.5時間×20日）
- ② 正月：引きこもってひたすら勉強（毎日6時間以上）
- ③ 1月～受験当日：土日に集中して勉強（1中～末さぼり気味）

![E資格勉強.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/50d4a7be-5779-2a4e-5dc7-7a7cb609da7a.jpeg)


## 学習したもの

①→②→③→④の順を１回やって、あとは①→③→④をひたすら回した。
③の黒本は3周した（＝過学習の説）。
どうしても覚えられなかったLSTMとGRUの構造は、最終週毎日手書きして友達になれた。

- ① 指定カリキュラムの理論部分／ノート：★★★★
  - まとまっているので、こちらをベースに。ノートに④情報を追記してく。
  - プログラム部分は、ほぼ見てない。今後はこちらを参考に、実装してきたい。
- ② ゼロ作①／②：★★★
  - 両方大事だけど、①の逆伝搬は特に。逆伝搬より前はさっと遠して読む程度。
- ③ 黒本（ディープラーニグE資格問題集）：★★★★
  - こんなに解説がためになるのは初めてかもしれない。
  - まんま同じ問題あり。これをやらずにE資格を受験するのは、まず選ぶ学習データを間違えてる！！
- ④ ネット記事(主にQiita)：★★★
  - 各種手法の解説記事が沢山あるので、そちらで理解深める。
  - 特に論文解説の記事などは分かりやすくなってるので、原文よりもこっち派。感謝！
- ⑤ 最近の動向（Twitter）：★
  - 時事問題もあるかもって思っていたが、最近のはなかった。


# ２．個人でこれから
**2021.4～SIGNATEやり始め。**
※kaggleと迷ったけど、SIGNATEの方が日本的UIで好き。ただそれだけ。
　フォーラム？といったディスカッションは、kaggleの方がいいのかも？

まだまだ超初心者です。でも、「Intermediate」に即日なれた！！やったね。
※やる気を起こす、こういうバッジ制度を会社でも導入したいな～。自作でもいいからこういうシステムを構築してきたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/696900c1-c863-b73c-5264-59c0e95cd32e.png)

**Raspberry Piで遊ぶ**
Raspberryのエッジコンピュータを利用した画像認識をやってみる。

https://goworkship.com/magazine/what_can_raspberrypi_do/
5分で外出先から自宅ラズパイにアクセスできるようになっちゃった話

#VPNってあるじゃん
いろいろな使いみちがありますよね。
1. セキュリティのため
2. 社内ネットワークに自宅などからアクセスするため
3. 自宅サーバーに外出先からアクセスするため

今回の記事は、3番の『自宅サーバーに外出先からアクセス』をする人におすすめできる内容です。
※まだ使って1週間ほどなので、何か間違っているところなどありましたら教えて下さい。

#経緯
私は、上の1と2のために、SoftetherのVPNサーバーを建てたことがありますが、
まあ、設定〜運用までめんどくさいんですよね。

普段、ラズパイで開発をしたりするのですが持ち運ぶのもめんどくさいし、
だけどVPNをやるのもだりーなーと思ってたところ、
私がプログラミングを始めるキッカケとなった師匠から「こんなのあるよ！」
という情報があったので、使ってみました。

#概要＆環境
・Macbook Pro (BigSur 11.2.3)
・tailscale (ver 1.6.0)
・RaspberryPi 4

→外出先から、自宅にあるRaspberryPi4へ接続できるように。

#Tailscale
説明するより使ってみたほうが速いと思います。
それくらい簡単に設定できちゃいます。

https://tailscale.com/

##PCでの設定
１. まず、右上の「Log in」から登録します。GoogleアカウントやMicrosoftアカウントだとスムーズにいけます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550844/4fd184ba-d54e-7406-38be-e1da91ab2714.png)


２. 登録＆サインインできたら、Downloadに進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550844/80b6e13c-4dcc-af25-ab8c-9164fd2980c2.png)

３. プラットフォームを選びます。
すごくないですか！！Androidも、iOSまで対応してますよ！！！
私はMacを使っているので、まずはmacOSを選択し、AppStoreからインストールしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550844/4866960e-2017-5083-8ce0-307e447fceba.png)

４. インストール完了！起動してみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550844/c51a9742-2a37-230c-9d42-bc5db788025c.png)
タスクバーに表示されました！
(Windowsの方は、タスクバー右側の上向き三角?のところに隠されてます！)
「Log in」を押すと、さっきのログイン画面に飛ばされるので、ログインしてください。

５. 接続
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550844/e481fcd5-74b5-5636-fa0c-f0d0c8828b3c.png)
「Connect」を押して、アイコンが『T』の形になってたら接続完了です！

##ラズパイでの設定
１. インストール。公式の通りに、一行ずつコマンドを打っていきます。


```ruby:RaspberryPi
sudo apt-get install apt-transport-https

curl -fsSL https://pkgs.tailscale.com/stable/raspbian/buster.gpg | sudo apt-key add -
curl -fsSL https://pkgs.tailscale.com/stable/raspbian/buster.list | sudo tee /etc/apt/sources.list.d/tailscale.list

sudo apt-get update
sudo apt-get install tailscale
```

２. tailscaleの起動

```ruby:RaspberryPi
sudo tailscale up
```
すると、「このURLにアクセスしてね！」とURLを教えられるので、
コピーしてPCで開きます。
「success」と表示されたら完了です！

#外から接続してみる
まず、tailscaleのサイトの、「Log in」から、Admin Consoleに入ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550844/d9f96761-69a7-3e85-3c39-50b9ba4b0e99.png)
情報隠しちゃいましたが、「raspberrypi」が「Connected」になっていて、IPアドレスが割り振られていたら、接続できているはずです！

PCも同様に接続しておけば、これで外出先からでもSSHでもVNCでも好きにしちゃえます。


#まとめ
こんな簡単に接続できちゃって大丈夫か！と不安になりましたが、
とにかく便利なのでしばらく使ってみようと思います。

まだ日本語での情報も少ないので、もしなにか他の使い方など見つけた方いたら、
コメントで教えて下さい。

簡単なTailscaleの紹介でした！
AWS SNS で SMS を利用するときの上限緩和で引っかかった

## AWS SNS の利用上限

AWS SNS によって SMS を送信出来ますが、デフォルトだと月々上限 $1 分までしか利用出来ないため、数件送信するだけで上限に達してしまいます。

上限に達する場合、SMS はいくら送っても送信失敗になります。
「上限に達する場合」というのは、例えば上限がデフォルトの $1 の場合、
**$1 を越えて以降の送信が失敗** ではなく、**$1 を超える場合に失敗** ということです。

私の場合、SNS の利用料金が $0.97 になった時点でそれ以降の SMS 送信がいくら送っても失敗しました。

SMS の配信ステータスは AWS コンソールの SNS の画面から確認することが出来ます。
![スクリーンショット 2021-04-25 17.51.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134710/00843c18-b221-63f5-d352-7230713c8063.png)

## 上限緩和の方法

AWS コンソールの AWS サポートから、Create Case -> Service limit increase を選択し、
Limit type で「SNS Text Messaging」を選択します。
![スクリーンショット 2021-04-25 19.04.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134710/2d767240-62d6-b307-b3e8-0f7bd9ef0c2f.png)
そうすると入力項目が色々と出てくるのでなるべく細かく入力して送信します。

返信が来るまで大体1日くらいかかると思います。

### これで上限緩和されたかと思いきや...

無事 AWS サポートから返信が来て上限緩和が通達されました。
が、相変わらず SMS 送信が失敗しまくる。
もしかして AWS SNS って送信成功率ひっくいサービスなのか??とも思いましたが、上限緩和は AWS サポートだけでなく AWS SNS の設定も必要だったようです。
![スクリーンショット 2021-04-25 19.31.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134710/9cd19ed2-0d35-1d7c-218c-c4af72b96852.png)

AWS コンソールの SNS 画面から、左側メニュー「テキストメッセージング(SMS)」
を開くと、下の方に「テキストメッセージングの優先設定」というものがあります。
デフォルトだとなんの設定もされていないので、ここを編集して「アカウントの使用制限」から何ドルまでの制限にするかを設定します。

これを行わないと、サポートの上限緩和申請が通っても $1 が上限のままなようです。
ローカルのUSDZファイルをSCNNodeとして読み込む


１回sceneにしてrootNodeを取得する。

```swift
let localURL = Bundle.main.url(forResource: "object", withExtension: "usdz", subdirectory: "art.scnassets")!
let scene = try! SCNScene(url: localURL, options: [.checkConsistency: true])
let objectNode = scene.rootNode
```

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
バッチファイルでローカルIPアドレスを変数に格納

Y子です。
今回は、ローカルIPアドレスを変数に格納してみます。
__[グローバルIPアドレスを変数に格納する](https://qiita.com/koiwaiwaiko/items/0d1848c8900adcc154f7 "バッチファイルでグローバルIPアドレスを変数に格納")__ のは以前やりましたが、ローカルIPアドレスの方が文字列加工が難しく、今回初めてやってみました。

# 概要・用途
自分のローカルIPアドレスを取得して、変数に格納します。
ログを取得したり、なんらかの自動化処理の中で、使うことを想定します。
_【[確認環境：Windows 10 Home (Bld. 19042.928)](https://qiita.com/koiwaiwaiko/items/ef2d457ae1e1a7c8b698 "Windows10のバージョンを確認・表記する")】_

# コード
## (1) FIND関数の準備
まず、Excelの`FIND`関数に相当する「[指定の文字が何文字目か調べる](https://qiita.com/koiwaiwaiko/items/69873cb9c642380b155f "バッチファイルで指定の文字が何文字目か調べる（ExcelのFIND関数相当）")処理」を使いたいので、これを独立したバッチファイルにしておき、[戻り値を利用](https://qiita.com/koiwaiwaiko/items/f4401f41dc0bc3b08642 "バッチファイルで他のバッチファイルの戻り値を利用する")できるようにします。
エラー処理は、機会があれば検討してみたいですが、今回は真面目に考えていません。

__[FIND関数を考えたとき](https://qiita.com/koiwaiwaiko/items/69873cb9c642380b155f "バッチファイルで指定の文字が何文字目か調べる（ExcelのFIND関数相当）")__ から出力が少し変わっただけですが、コードを載せておきます。
（行数多くて恥ずかしいんですよね。もうちょっとコンパクトにできたらいいんですが）

```bat:find_like_excel.bat
@echo off
rem 検索文字列, 対象, [開始位置=1]
set find_text=%~1
set within_text=%~2
set start_num=%~3

rem 位置カウンタ初期化
set charpos=0
rem 文字位置カウント（サブルーチン実行）
call :find_like_excel "%find_text%" "%within_text%" "%start_num%"

rem 結果出力
echo %charpos%
exit /b

rem ====サブルーチン====
rem 文字位置をカウントする
:find_like_excel
  setlocal

  rem 引数がない場合は終了する
  if "%~2"=="" (echo 引数がありません & pause & exit /b)

  rem 検索文字列, 対象, [開始位置=1]
  set find_text=%~1
  set within_text=%~2
  set start_num=%~3

  rem 開始位置の指定がない場合はデフォルト「1」
  if "%start_num%"=="" (set start_num=1)
  rem バッチファイルのデフォルトは「0」なので合わせる
  set /a start_num-=1

  rem 開始位置の調整
  call set within_text=%%within_text:~%start_num%%%

  rem 文字位置カウントのループ開始
  :label_find
  rem 位置カウンタ加算
  set /a charpos+=1

  rem 文字列がなくなったら終了
  if "%within_text%"=="" (
    set charpos=0
    goto :label_end
  )

  set length=0
  set str_tmp=%find_text%

  rem strlenループ開始
  :label_strlen
  rem 長さ加算
  set /a length+=1
  rem 1文字減らす
  set str_tmp=%str_tmp:~1%
  rem 文字列がなくなったら終了
  if not "%str_tmp%"=="" (goto :label_strlen)
  rem strlenループ終了

  rem 文字列が一致すれば終了
  call set str_tmp=%%within_text:~0,%length%%%
  if "%str_tmp%"=="%find_text%" (goto :label_end)

  rem 文字列がまだあれば、1文字減らしてループ
  set within_text=%within_text:~1%
  goto :label_find
  rem 文字位置カウントのループ終了

  :label_end
  endlocal && set charpos=%charpos%
exit /b
```

## (2) ipconfigコマンドの結果を加工
Windowsでネットワーク情報を知るといえば、`ipconfig`コマンドです。
これに「IPアドレスだけを出力」のようなオプションがあればいいのですが、見当たらないので、力技で実現します。

```bat:get_localip.bat
@echo off

rem ipconfigの結果から「IPv4」の行を抽出
rem (IPv4 アドレス . . . . . . . . . . . .: 192.168.x.x)
for /f "usebackq delims=" %%a in (`ipconfig^|findstr "IPv4"`) do set ipaddr=%%a

rem スペースは邪魔になるので削除
rem (IPv4アドレス............:192.168.x.x)
set ipaddr=%ipaddr: =%

rem ":"の位置を取得
for /f "usebackq" %%a in (`call find_like_excel.bat ":" %ipaddr%`) do set pos=%%a

rem ":"までを削除
call set ipaddr=%%ipaddr:~%pos%%%

echo %ipaddr%
```

```:実行結果
> get_localip.bat
192.168.x.x
```

# おわりに
[グローバルIPアドレス](https://qiita.com/koiwaiwaiko/items/0d1848c8900adcc154f7 "バッチファイルでグローバルIPアドレスを変数に格納")も取れたんだからローカルIPアドレスもね、という感じで作ってみました。
何に使えるかは正直わかりません。笑
役に立った方は用途を教えてくださると嬉しいです。

では！
ネットワーク データ伝送時間

#【ネットワーク データ伝送時間】

ネットワークの伝送時間の求め方は抑えておきたい。
ネットワークの知識は大事なので備忘録として残します。

##データ伝送時間

**伝送時間（秒）**＝ 伝送データ量（ビット）/ 回線の伝送速度（bps）× 伝送効率

問）5秒で320kビットを送れる場合のデータ伝送速度は？
答）320kビット / 5秒＝ 64kビット/秒

##伝送効率

**伝送効率**＝ 正しく受信されたデータのビット数 × 送信された総ビット数

問）1.5Mビット / 秒の伝送路を用いて、12Mバイトのデータを転送するのに必要な伝送時間は何秒？ 伝送路の伝送効率は50%とする。
答）12M × 8ビット / 1.5Mビット/秒 × 0.5 ＝ 150秒
openpyxlでexcelの読み書きを自動化…していいのかを考えよう

# 要約

Pythonで業務ファイルを操作するとき、エクセルファイルはエクセルファイルであることが処理のボトルネックになりうる。できるだけテキストファイルで処理できるようにしよう。


# 遭遇したトラブル

職場にて2つのエクセルの資料をマージすることになった。
数が少なければ最悪目で確認すればよかったが、2000ファイル以上で、各ファイルのマージする列も1万行を超えていた。

仕方がないからまず差分を取り出すために書きなれているPythonで差分比較用のスクリプトを書いたが、まる二日放置していても1ファイルの差分も完了していなかった。

# 検証

どうやら自分の想像以上にopenpyxlは遅かったし、特定条件で無限に時間を使ってしまうソフトになっているようだ。

テスト用にまずは次のコードを実行し、これをexcelで開いてxlsx形式で保存し直した。
流石にシンプルすぎるため、中身の解説は省略する。

```python:CreateTestCase.py
import random


with open("testdata_csv.csv", "w") as out_file:
    for _ in range(50000):
        out_file.write(",".join([str(random.randint(0, 1000)) for _ in range(100)]) + "\n")

```

そしてそれを次のコードで読み込ませた。あまりにも時間がかかるため、適当なところでプログラムを落とすこと。

```python:CalcTestCase.py
import openpyxl as xl
import datetime as dt


ROWS = 50000
COLS = 100
CHECK_INTERVAL = 10


def put_interval_to_csv(start: dt.datetime, end: dt.datetime, row_count, target):
    with open(f"log_{target}.csv", "a") as log_file:
        log_file.write(f"{row_count},{(end - start).seconds}.{(end - start).microseconds:06}\n")


def calc_excel():
    book = xl.load_workbook("testdata_csv.xlsx", True)
    # VBAと違い、シート番号は0スタート
    sheet = book.worksheets[0]

    start_check = dt.datetime.now()

    for row in range(ROWS):
        if not row % CHECK_INTERVAL:
            start_check = dt.datetime.now()
        row_sum = 0
        for col in range(COLS):
            row_sum += sheet.cell(row + 1, col + 1).value
        print(row_sum)
        if not row % CHECK_INTERVAL:
            end_check = dt.datetime.now()
            put_interval_to_csv(start_check, end_check, row, "excel")


def calc_csv():
    with open("testdata_csv.csv") as read_file:
        start_check = dt.datetime.now()
        for row in range(ROWS):
            cells = read_file.readline().rstrip().split(",")
            row_sum = 0
            for col in range(COLS):
                row_sum += int(cells[col])
            print(row_sum)
        end_check = dt.datetime.now()
        put_interval_to_csv(start_check, end_check, row, "csv")


if __name__ == '__main__':
    calc_csv()
    calc_excel()

```

csvとxlsx形式の両方で各業の合計数をprintしている。
ただし、xlsxでは10行ごとに速度の計測を行い、csvは全体の実行時間の速度を計測した。

# 検証結果

テキストファイルの合計の出力は、5000行全てに対して1.297秒かかっているが、csvファイルの出力は下記のような結果になった。
縦軸が**1行の処理に**かかった秒数、横軸が列である。

![処理速度.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395414/5abc884c-d45c-723b-e00e-ec4c834f22f4.png)

青い折れ線が結果で、パット見だと直線に見えるので、excelの機能で1次式の近似式を作り、数式も出力した。
この傾きだと、もし最後までやっていたらおおよそ$4.5 \times 10^7$秒、500日以上かかる計算になった。

また、COLを5に書き換えたところ、上記の処理時間のグラフの傾きが0.016とおおよそ20分の1になった。読み込んだ行が一番影響が大きそうだ。

# 回避方法

Q. エクセルファイルの操作が遅い。どうしたらしい？
A. エクセルを使わなければいい。

ということで、仕事ではエクセルファイルを一旦csvファイルに保存してから作業を行った。こちらはVBAで自動で変換させた。
AWS vs Azure vs GCP in Qiita

世はまさに大クラウド時代ですが、その中でも3大クラウドと言われるAWS、Azure、GCPのQiitaでの現状について調べてみました。まず歴史から辿るとそれぞれのサービス開始時期は以下の通りです。
AWS：2006年
Azure：2010年
GCP：2008年（GAEの開始年）
AWSのサービス開始から約15年経ち、2020年時点でのシェアは[Canalys報告書](https://www.canalys.com/newsroom/global-cloud-market-q4-2020)によると、AWS、Azure、GCPの順に32%、20%、7%となっています。[Stack Overflow Developer Survey 2020](https://insights.stackoverflow.com/survey/2020#technology-most-loved-dreaded-and-wanted-platforms)の最も好きなプラットフォームの項目でも、AWSが一番人気ですが他2つも高い人気となっています。日本ではAWSが圧倒的に広まっている印象で上記海外の調査は少し意外だったため、Qiitaでの現状を調べてみました。

##調査結果
今回は簡易的に「AWS」「Azure」「gcp」のタグがついた記事が各年で何件あるか調査しました。結果が以下です。

|     |2010|2011|2012|2013|2014|2015|2016|2017|2018|2019|2020|
|---  |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |
|AWS  |0   |1   |42  |203 |798 |1599|2265|2415|3510|5114|6664|
|Azure|0   |0   |3   |7   |59  |148 |337 |575 |743 |946 |1362|
|gcp  |0   |0   |0   |0   |6   |21  |89  |222 |575 |955 |1111|

![cloud_cnt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1051954/f7b255f3-6b23-e836-4b40-7e90f37ae91d.png)
この結果だけで判断するのは安直ですが、日本ではAWSのシェアが群を抜いていそうです。日本語の情報が圧倒的に多いことでAWSの使用が加速しているのではないでしょうか。今後の展開が楽しみです。

##調査に使用したプログラム
```qiita_cloud_count.py
from bs4 import BeautifulSoup
import matplotlib.pyplot as plt
import numpy as np
import requests
import time

# Qiitaで投稿日、タグを指定して検索し、ヒットした記事数を取得する
base_url = 'https://qiita.com/search'

tags = ['AWS', 'Azure', 'gcp']
years = range(2010, 2021)

summary = []
for tag in tags:
    temp = []
    for year in years:
        params = f'?q=tag%3A{tag}+created%3A%3E%3D{year}-01-01+created%3A%3C{year}-12-31'
        html_doc = requests.get(base_url + params)
        data = BeautifulSoup(html_doc.text, 'html.parser')
        temp.append(int(data.find('span', class_='badge').text))
        time.sleep(5) # サーバ負荷軽減用
    summary.append(temp)

data = np.array(summary)
print(data)


# 以下グラフ描画用
num_tags = data.shape[0]
num_years = data.shape[1]
index = np.arange(num_years)
fig, ax = plt.subplots()
bar_width = 0.25
alpha = 0.8
colors = ["orange", "royalblue", "gold"]

for i in range(num_tags):
	plt.bar(
		index + bar_width*i,
		data[i],
		bar_width,
        alpha=alpha,
		color=colors[i],
		label=tags[i]
		)

plt.ylabel('Counts')
plt.xticks(index + bar_width, years)
plt.legend(prop={'size' : 15},loc="upper left")
plt.savefig("cloud_cnt.png", bbox_inches = 'tight')
```