OmniAICreator/Qiita-1.07M huggingface dataset:
画面遷移時に値を渡す方法

結論から書くと結果はこんな感じ。

![スクリーンショット 2021-08-30 22.23.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494487/22c6519b-4ab5-cd95-ee4e-e867001ab1cd.png)

![スクリーンショット 2021-08-30 22.24.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494487/f555649f-2678-98b0-38c0-7566fad1b88a.png)

性別とか年齢とか書いてありますけどそこは無視してください。
作るのめんどくさかったので、個人で作成してるアプリの一部をそのまま撮りました。


　
今回は別のViewControllerから、最初から存在する Main.storyboardと ViewControllerに値を渡し表示するという想定です。
　

まず別のViewControllerのプログラムはこちら。

    class 別のViewController: UIViewController {

        @IBOutlet weak var textField: UITextField!

        override func viewDidLoad() {
            super.viewDidLoad()
            
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let nextVC = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
        
            //textFieldの内容ををMain.storyboardのViewControllerの変数に代入
            nextVC.name = textField.text!
        
            present(nextVC, animated: true, completion: nil)

        }
    }

　　上記ソース↓の部分は

            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let nextVC = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController

　
　
↓ようになっている想定です。

![スクリーンショット 2021-08-30 22.27.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494487/757dba85-84df-a3d1-06a7-3385718bde1a.png)

![スクリーンショット 2021-08-30 22.28.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494487/cc3dcffc-ca59-39bb-2e4e-bfd0ea72854e.png)


そしてMain.storyboardのViewControllerのソースはこちら。

    import UIKit

    class ViewController: UIViewController {
    
        @IBOutlet weak var nameLabel: UILabel!
    
        var name = ""
    
        override func viewDidLoad() {
            super.viewDidLoad()

            nameLabel.text = name
        }
    }

　

Segueを使って値を渡す方法もありますが、案件でSegueを使って値を渡すことなんてないのでこちらのやり方で学んだ方がいいかなと。
　

参考までに。
セキュリティの話

#はじめに#
　プログラミングを学習しているとセキュリティについては必ず考えなければなりません。
今回は
・なぜセキュリティを考えなければならないのか
・主な攻撃手法とその対策
という点についてまとめていきたいと思います。


#なぜセキュリティを考えなければならないのか#
　プログラミングを勉強しているとセキュリティ対策はしっかりしましょう！という話をよく聞くと思います。結構考えるのも面倒ですし実装するのも面倒なので、えー・・・と思う方もおられるかもしれません。
　しかし、世の中には悪いことを考える人がたくさんいます。SNSでなりすまして詐欺を働いたり、データベースから情報を抜き取って悪用したり、といった感じです。自分しか使わないようなアプリならそれほど気にする必要はないかもしれませんが、多くの人が使うアプリであれば、そしてそれが個人情報やクレジットカード情報などを扱うようなものであれば十分注意する必要があります。


#主な攻撃手法とその対策#
　それでは主な攻撃手法とその対策について見ていきましょう。

##XSS(クロスサイトスクリプティング)##
　XSS(クロスサイトスクリプティング)とはユーザーからの入力があるSNSや掲示板などでHTMLタグを生成し、悪意のあるスクリプトを実行させる攻撃手法のことです。
　例えばSNSで今日の一言などを入力する際、\<h1>ひとこと\</h1>などとすると見出しタグとして認識されてしまいます。それでは、これが他のページへ遷移させるようなスクリプトであればどうでしょうか。見ていたページと全く同じサイトが表示されて、そこで個人情報の入力を求められたとしたらどうでしょうか。これがXSSという手法です。

####対策####
　対策にはいくつかありますが、その一つはエスケープ処理です。htmlspecialchars関数を用いることでユーザーから入力のあった値を出力する際、<や>などの特殊文字を通常の文字列に変換することが出来ます。まあ厳密には文字列というかHTMLエンティティというものなんですが、深く考えなくても良い気はします。
　こうすることでHTMLタグやscriptタグが実行されることなく単なる文字列として出力されるというワケです。ユーザーからの入力文字を出力する場所には全てエスケープ処理をしておきましょう！


##SQLインジェクション##
　SQLインジェクションとは、入力箇所にSQL文を直接書くことでSQLを実行してしまうという手法です。例えば、DELETE文などを入力されてしまうとどうでしょうか。データベースのデータが消されてしまう可能性があります。他にも、ECサイトの金額を書き換えられてしまったり管理者権限が乗っ取られたり別のユーザーでログインしたりといった脆弱性が挙げられます。


####対策####
　SQLインジェクション対策には、SQL文に直接入力値を入れるのではなく、プリペアードステートメントを用いて値をバインドさせるのが有効です。

```example.php
 $stmt = $dbh->prepare('INSERT INTO users SET name=?, age=?, height=?');
 $stmt->bindValue(1,'太郎',PDO::PARAM_STR);
 $stmt->bindValue(2,'18',PDO::PARAM_INT);
 $stmt->bindValue(3,'175',PDO::PARAM_INT);
 $stmt->execute();
```

このようにバインドさせることによってSQLインジェクションを防ぐことが出来ます。


##CSRF(クロスサイトリクエストフォージェリ)##
　CSRF(クロスサイトリクエストフォージェリ)とは、ログインを維持した状態でリンクを踏ませて悪意を持った罠ページにユーザーを誘導し、ユーザーが意図していないリクエストをさせる攻撃手法のことです。これにより、本来ログインしたユーザーしか発信できないリクエスト（SNS投稿など）が実行されてしまいます。


####対策####
　対策にはトークンというものを生成します。POST通信をするフォームに対してあらかじめ推測できないランダムな文字列を埋め込んでおきます。さらに、生成されたトークンをセッションに保存しておき、POST送信が行われた際にフォームのトークンと照合します。トークンが埋め込まれていなかったり、セッションに保存されている文字列と異なる場合は不正なリクエストとして処理を停止します。


#まとめ#
　このように多くの人に使われるアプリケーションでは、常に悪意に晒されていると考えた方が良いでしょう。
初学者であってもこういったセキュリティ対策は必須になってきており、今から癖をつけておく必要があります。覚えておいて損はないでしょう。
SolidityとJavaScript（Web3.js）で同様の文字列ハッシュ化（Keccak256）を行う方法



# 文字列ハッシュ化の手順
1. utf-8表現（string型）からHex表現（bytes型）に変換
2. Hex化した文字列をKeccak256変換


# Solidityの場合
```solidity
string message = "sample message";
bytes hexMessage = bytes(message); // 1
bytes32 hashedMessage = keccak256(hexMessage) // 2
```


# JavaScript (Web3.js) の場合
```js
let message = 'sample message';
let hexMessage = web3.utils.utf8ToHex(message); // 1
let hashedMessage = web3.utils.soliditySha3(hexMessage); // 2
```
Unityからプリンターを動かす

#初めに
Unityからプリンターを動かしてみたいと思い、いろいろ調べてみた


##先人
https://qiita.com/koukiwf/items/e91067e95c2a64af54d6

調べればすぐ出てくる！これは素敵！


### プラグインのエラーがとれない
https://teratail.com/questions/314305

System.Drawing.PrintingのPrintingなんて、知らないnamespaceと言われる
なるほど、ApiCompatibilityLevelをかえねーとよめね～わな。。
ということで、
１，Assetsの下にPluginsフォルダを作成
２，ApiCompatibilityLevelを.Net4.xに変える

に修正でもエラーが出続ける。。

#### プラグインのdllの行方。。
先人の『System.drawing.dll』の行方がわからず、Windows内を全検索してみたら、
結構同一ファイル名のdllが出てくる、
Pluginsフォルダを作って、Windows内で出てきたSystem.drawing.dllを入れたら
エラーは回避できた！うごけ～～！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37068/a85c2015-b207-7262-aa24-cbba5ac08675.png)

再生は出来るが、

```c#
Loading assembly failed: "Assets/Plugins/System.Drawing.dll" reason: File does not contain a valid CIL image
```

エラーーがどうしたものか。。


https://forum.unity.com/threads/using-system-drawing-image-works-but-shows-as-error.653848/

上記のkaigangamesさんの書き込み

C:\Program Files\Unity\Hub\Editor\2020.1.6f1\Editor\Data\MonoBleedingEdge\lib\mono\4.5
の下位のフォルダにあるdllを持ってきたら、エラー回避できたよ～
って書いてある、これだ！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37068/474e37b1-0c81-a042-1774-fc0c21496d03.png)

自分は、2020.3.16f1の環境で作ったていたから、上記のフォルダの『System.drawing.dll』を使ったら、
先ほどのエラーも出なくなった！


#####最後に
C#ように書いてある、プログラムはdll読み込めば、たいていの事は出来るのは楽ですね。

プログラムのデバックをするのに、プリンターがガンガン動いて紙の無駄。。

プリンターを使ったアプリゲーム作ってみようかな！
AWS CodeCommitでPRマージ時にLambda実行

## はじめに
DevOps（CICD）の一環でCode CommitのPRがマージされた時にBuild・Deployを実行させるような仕組みを構築したのでその備忘録を残す

## 仕組み
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/e1371743-42b5-acb0-c85e-f48853554ab9.png)

## Cloud Watch EventsのEventオブジェクトの中身
例えば、devブランチからmainブランチへのPRのマージを行うと以下のようなEventオブジェクトがLambda関数に渡る

```json
{
  "version": "0",
  "id": "c0931ce3-ee9f-d9f5-205c-a0ab8e3c0f9f",
  "detail-type": "CodeCommit Pull Request State Change",
  "source": "aws.codecommit",
  "account": "xxxxxxxxxxxx",
  "time": "2021-08-16T08:32:25Z",
  "region": "ap-northeast-1",
  "resources": [
    "arn:aws:codecommit:ap-northeast-1:xxxxxxxxxxxx:hoge-test"
  ],
  "detail": {
    "author": "arn:aws:iam::xxxxxxxxxxxx:user/----------",
    "callerUserArn": "arn:aws:iam::xxxxxxxxxxxx:user/----------",
    "creationDate": "Mon Aug 16 08:31:23 UTC 2021",
    "destinationCommit": "dfdaf17904c816c9826d431187b4746d21406319",
    "destinationReference": "refs/heads/main",
    "event": "pullRequestMergeStatusUpdated",
    "isMerged": "True",
    "lastModifiedDate": "Mon Aug 16 08:32:14 UTC 2021",
    "mergeOption": "FAST_FORWARD_MERGE",
    "notificationBody": "A pull request event occurred in the following AWS CodeCommit repository: hoge-test. User: arn:aws:iam::xxxxxxxxxxxx:user/----------. Event: Updated. Pull request name: 4. Additional information: The pull request merge status has been updated. The status is merged. For more information, go to the AWS CodeCommit console https://ap-northeast-1.console.aws.amazon.com/codesuite/codecommit/repositories/hoge-test/pull-requests/4?region=ap-northeast-1.",
    "pullRequestId": "4",
    "pullRequestStatus": "Closed",
    "repositoryNames": ["hoge-test"],
    "revisionId": "9dc053117e28d1da9cbb7044eddb2c6e815fc978d61183e8cb62a59997599037",
    "sourceCommit": "dced724ba1e54ef52319050306015d23a47f42d2",
    "sourceReference": "refs/heads/dev",
    "title": "test"
  }
}
```

上記のJSONの中でPRマージ時を判定するには

- "isMerged": "True"
- "event": "pullRequestMergeStatusUpdated"
- "pullRequestStatus": "Closed"

あたりのKeyで値がそれぞれ上記の値であればPRマージ時という判別が可能になる

・参考：[pullRequestMergeStatusUpdated イベント](https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/monitoring-events.html#pullRequestMergeStatusUpdated)

## Lambdaをトリガーする設定
以下の記事を参照

- [Cloud Watch Eventの設定方法](https://qiita.com/yuta-katayama-23/items/333ecee007e1f398abf4#cloud-watch-event%E3%81%AE%E8%A8%AD%E5%AE%9A%E6%96%B9%E6%B3%95)

## Lambdaの実装
以下の記事の内容を参照（LambdaでEventオブジェクトを受け取る部分の実装は全く同じで`event.detail.・・・`のようにして、`isMerged`や`event`、`pullRequestStatus`といったキーの値を取得する）

- [Code CommitにpushされたらコミットのリンクをBacklogに記載を自動化](https://qiita.com/yuta-katayama-23/items/333ecee007e1f398abf4)
GASでスプシのキーワードから検索結果のスクショを保存

<h1>GASでスプシのキーワードから検索結果のスクショを保存</h1>
<span>情報が少ないGASの実装例をメモ程度に残します。
<p>概要、キーワードと日付が並べられたスプシに対して以下のスクリプトを実行すると、明日の日付と隣り合わせになっているキーワードについて設定した関連ワードとOR検索をして、一覧のページをフルスクリーンでスクリーンショットを撮り、指定したGoogleDriveに保存するもの。

<h2>1. 実装したコード</h2>

    function myFunction() {
      var spreadsheet = SpreadsheetApp.openByUrl('スプシのURL');
      var sheet = spreadsheet.getSheetByName('シート1'); // 検索ワード記載シート
      var lastrow = sheet.getLastRow(); // 最後の行番号
      var searchWords = sheet.getRange("A2:A"+lastrow).getValues();
      var searchDates = sheet.getRange("B2:B"+lastrow).getValues();

      var apiKey ="アクセスキー";//APIFLESHのアクセスキー
      var folderId ="ID"; // ここに保存先GoogleドライブID

      var date = new Date();
      date.setDate(date.getDate() + 1); //明日の日付
      var tomorrow = Utilities.formatDate(date, 'Asia/Tokyo', 'YYYY/MM/dd');
      var today = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'YYYY/MM/dd');

      for(let i = 0; i<lastrow-1; i++) {
        if(typeof searchDates[i][0] == typeof new Date()){
        Logger.log(Utilities.formatDate(searchDates[i][0], 'Asia/Tokyo', 'YYYY/MM/dd'));
        if(Utilities.formatDate(searchDates[i][0], 'Asia/Tokyo', 'YYYY/MM/dd') == today){
          // 検索結果取得
          var displayNum = 30; // 検索数
          var url = "https://www.google.com/search?hl=ja&as_q="+searchWords[i][0]+"&as_epq=&as_oq=関連キーワード&num="+displayNum;
          var encodeUrl = url.replace(/[^*+.-9A-Z_a-z-]/g,function(s){
            var c=s.charCodeAt(0);
            return (c<16?"%0"+c.toString(16):c<128?"%"+c.toString(16):c<2048?"%"+(c>>6|192).toString(16)+"%"+(c&63|128).toString(16):"%"+(c>>12|224).toString(16)+"%"+(c>>6&63|128).toString(16)+"%"+(c&63|128).toString(16)).toUpperCase()
          });
          var requestUrl = "https://api.apiflash.com/v1/urltoimage?access_key="+apiKey+"&full_page=true&url="+encodeUrl;
          Logger.log(url);
          Logger.log(requestUrl);
          try {
            var response =UrlFetchApp.fetch(requestUrl).getContentText(); // ここで1回リクエストを送って画像を作らせる
            Utilities.sleep(1000 * 20); // 画像出来上がるまで1分待機
        
            var image = UrlFetchApp.fetch(requestUrl).getBlob(); // ここで画像DL
            var folder = DriveApp.getFolderById(folderId);
            folder.createFile(image).setName(today+"_"+searchWords[i][0]);//日付で画像の名前を付ける
          } catch (e) {
            Logger.log("取得エラー");
          }
        }
      }
    }
<h2>2. 詳細</h2>
1. ページ全体のスクリーンショットを撮るのに<a href="https://apiflash.com/">API</a>を使用しているが、無料プランで登録しており、月に100枚の制限がある。100枚以上の場合には他のAPIやメソッドを検討する(調べた限りではなさそう)、又は有料のプランに切り替える必要がある。
redpenインストールメモ

###RedPenとは

仕様書や設計書、手順書、マニュアル等作成時、誤字脱字、表現揺れなど修正、確認に手間かかりますよね。RedPenはそういった文書校正をするためのオープンソースのツールです。

###動作環境
・CentOS8
・RedPen 1.10.4
・JAVA8(1.8)

###インストール方法

###JAVAのインストール
稼働にはJava 1.8.以上が必要です。

OpenJDKの例
・インストール	
　`yum install java-1.8.0-openjdk`

・環境変数の設定
　export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.302.b08-0.el8_4.x86_64
　export PATH=\$PATH\$:\$JAVA_HOME\$/bin
　export CLASSPATH=\$JAVA_HOME\$/lib

###Redpen
 redpen-1.10.4.tar.gz　をダウンロード	
 https://github.com/redpen-cc/redpen/releases/

 解凍	
 `tar xvf redpen-1.10.4.tar.gz`

 PGのディレクトリを作成	
 `mkdir -p /usr/local/redpen`

 ファイルを移動	
 `mv redpen-distribution-1.10.4 /usr/local/redpen`

 環境変数追加	
`export PATH=\$PATH\$:/usr/local/redpen/bin`

●Webサーバ動作確認

 サーバ起動
 `java -jar  /usr/local/redpen/bin/redpen-server.war`

　ブラウザからアクセス	
　`http://localhost:8080/`

###		
参考		
	redpen公式TOP	
		https://redpen.cc/
	redpen公式マニュアル	
		http://redpen.cc/docs/latest/index_ja.html
	PG本体	
		https://github.com/redpen-cc/redpen/releases/
	作者のqiita	
		https://qiita.com/takahi-i
	作者の記事：RedPenを使って技術文書を手軽に校正しよう	
		https://gihyo.jp/lifestyle/serial/01/redpen/0001?page=1

・その他		
	RedPenとPandocでドキュメント作りの手間を省こう	
		https://qiita.com/t_nakayama0714/items/ddac69c4a29d45392961
	東北ギーク	
		http://tech.respect-pal.jp/try-redpen/

###
2021/8/30 作成
[jQuery]position fixedしたものをフェードインさせた(Rails)

# はじめに
本日、私自身railsにてjQueryを初めて学習したため、アウトプットいたします。

# jQueryの導入方法
以下参照です。
[Rails6でのjQuery導入方法](https://qiita.com/tatsuhiko-nakayama/items/b2f0c77e794ca8c9bd74)
爆速で使用できるので、こちらにも記載しておきます。

`①ターミナルにて`

```
% yarn add jquery
```

`②Webpackの設定`

```config/webpack/environment.js
const { environment } = require('@rails/webpacker')

const webpack = require('webpack')
environment.plugins.prepend('Provide',
    new webpack.ProvidePlugin({
        $: 'jquery/src/jquery',
        jQuery: 'jquery/src/jquery'
    })
)

module.exports = environment
```

`③ application.jsの設定`

```javascript/packs/application.js
//中略

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
// 追記
require('jquery') ←ここです。

//中略
```

これで使えます。

# フェードインさせたコード

```js
  $(function() {
    $('.menu-bar').hide();
    $(window).scroll(function () {
      if ($(this).scrollTop() > 120){
        $('.menu-bar').fadeIn()
      }else{
        $('.menu-bar').fadeOut();
      }
    });
  });
```

アプリケーションでメニューバーを付けてます。
`scrollTop() > 120`にて
一番スタートの画面が120pxスクロールしたら、フェードイン
それ以外はフェードアウトという仕様です。

# 終わりに
jQueryがすごく便利で楽しく、
オリジナルアプリそっちのけで遊んでいたら時間がたくさん経過していました。

また、YouTubeで丁寧に解説している方もおりますので、
是非こちらも参照ください。
[jQuery入門 #1 jQueryの概要とjQueryを使うための準備をしよう](https://www.youtube.com/watch?v=vH3T6dylBME&list=PLHPBV1ZN8yuITCM4CG4wu7Q143jNmslaz&index=1)

明日も頑張ります！！
Pythonのモジュールとライブラリとパッケージの違い

何度も同じことを調べているので覚書として書きます。


##モジュールとライブラリとパッケージの関係性
モジュールとは、クラスや関数を用いて実行したい内容を記述したPythonのファイル（.py）のこと。
モジュールをいくつか集めてまとめたものがパッケージ。
ライブラリとは、いくつかのパッケージをまとめて一つのライブラリとしてインストールできるようにしたもの。

また関数、モジュール、パッケージ自体を総称してライブラリと言うこともある（←これがややこしくする原因）。

つまり、関係性は以下の通り。
クラスや関数 < モジュール < ライブラリ < パッケージ

##ライブラリは2種類ある
#####1, 標準ライブラリ
標準ライブラリはPythonに付属している。組み込み関数とそれ以外に分けることができる。
組み込み関数は、以下の通り。

```Python
abs(), delattr(), hash(), memoryview(), set(), all(), dict(), help(), min(), setattr(), any(), dir(), hex(), next(), slice(), ascii(), divmod(), id(), object(), sorted(), bin(), enumerate(), input(), oct(), staticmethod(), bool(), eval(), int(), open(), str(), breakpoint(), exec(), isinstance(), ord(), sum(), bytearray(), filter(), issubclass(), pow(), super(), bytes(), float(), iter(), print(), tuple(), callable(), format(), len(), property(), type(), chr(), frozenset(), list(), range(), vars(), classmethod(), getattr(), locals(), repr(), zip(), compile(), globals(), map(), reversed(), __import__(), complex(), hasattr(), max(), round()
```
上記の組み込み関数以外の標準ライブラリはimport文で読み込む必要がある。
例えばcsv、osなど。

>詳細は公式HPへ
>https://docs.python.org/ja/3/library/index.html

#####2, 外部ライブラリ
外部ライブラリを利用する場合はpipを利用してライブラリをインストールする。
インストールしたライブラリは事前にimport文で読み込みが必要。
例えば、NumPy、Matplotlib、Pandasなど。
>Pythonの外部ライブラリの一覧は、PYPI（Python Package Index）へ
>https://pypi.org/


###参考
https://ai-inter1.com/python-module_package_library/
Dockerで簡単にApacheを立ち上げる

# 設定ファイルを作成

``` docker-compose.yml
version: '3.3'

services:
  httpd:
    image: httpd:2.4
    ports:
      - '80:80'
    volumes:
      - ./htdocs:/usr/local/apache2/htdocs
      - ./conf:/usr/local/apache2/conf
```

```index.html
<html>
<body>
<h1>Test Container</h1>
</body>
</html>
```

httpd.confをwindowsから操作できるようにコンテナからコピーをする。

```
docker run --rm --name httpd -d httpd:2.4
docker cp httpd:/usr/local/apache2/conf/ conf
docker rm -f httpd
```

# ディレクトリ構成

```
C:.
│  docker-compose.yml
│
├─conf
│  │  httpd.conf
│  │  magic
│  │  mime.types
│  │
│  ├─extra
│
└─htdocs
        index.html
```

# 実行

```
docker-compose up
```
Next.jsのISRを理解する

# 目的
Next.jsのISRはどのような動作をするのかを、正しく理解したい！

# ISRとは
ISR(Incremental Static Regeneration)とは、SSGを利用しながらも、一定時間ごとにデータの再取得を行い、HTMLを再生成する手法のことを指します。

# ISGとの違い
ISRを調べていると、ISGという単語が一緒に出てくることがあります。

ISG（Incremental Static Generation）とは、Dynamic Routesのページにアクセスした際に、オンデマンドでページ生成を行う手法のことを指していたようです。
この単語は公式ドキュメントには現在明確には記載されている箇所はありません（おそらく…）。ドキュメント内に貼られている[サンプルサイト](https://static-tweet.vercel.app/)を確認すると、ISGに関する記載が少しだけ残っています。

Dynamic RoutesのキーがツイートIDなどの場合、パターンが膨大すぎてそれらを事前にビルドすることは不可能なので、アクセスがあったタイミングで生成を行う必要があります。そのような場合にISGは有効です。
これは`getStaticPaths`の中の`fallback: true`もしくは`fallback: 'blocking'`オプションを設定することで実現できます。
（fallbackオプションの違いは[この記事](https://qiita.com/thesugar/items/7e27a0f459d5981ed16e#getstaticpaths-%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%95%E3%82%A9%E3%83%BC%E3%83%AB%E3%83%90%E3%83%83%E3%82%AF%E3%81%AE%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF)がわかりやすいと思います。）

ISG(fallback)はDynamic Routesのページにアクセスした際の挙動を設定するもので、ISR(revalidate)は、ページ再生成の間隔を設定するものとなります。SSGとSSRのような二者択一的なアプローチではないので、そこは正しく理解をしたいです。
(`fallback:false`,`fallback:true`,`fallback:'blocking'`いずれも、ISRを有効にすることは可能です。)

現在はISRという概念に、fallbackオプションも含有されたような位置付けになっているようです。（[Vercel – Incremental Static Regeneration - Vercel Documentation](https://vercel.com/docs/next.js/incremental-static-regeneration)）

# ISRの用途
ISRを有効にしたとしても、`revalidate`で設定した秒数が経過するまでは、古い情報が返されることになるので、常に最新の情報を表示する必要があるシステムには向いていません。
またウェブメディアのような、ユーザー生成のコンテンツではなく、更新頻度もそこまで多くないシステムであれば、通常のSSGで事足りてしまうでしょう。

そんなことを考えると、意外とISRの出番って無いのでは？と思いましたが、プログラマ向け情報共有サービスのZennではISRを採用していた実績があるようです。（[Next.jsのISRで動的コンテンツをキャッシュするときの戦略](https://zenn.dev/catnose99/articles/8bed46fb271e44)）

ユーザー生成でコンテンツ更新がそこそこの頻度であるものの、必ずしも最新であることは求められないシステムになるかと思うので、まさにISRがフィットする事例だと思います。

※インフラをVercelからGCPへ移行した関係で、現在はISRは使用していないようです。

# サンプルサイト

https://isr-sample.vercel.app/

今回ISRの挙動をわかりやすくするため、サンプルサイトを作成してみました。このサイトを見てもらえれば、ISRの挙動が理解できると思います。

再生成までの時間は20秒で設定しているので、次にHTMLが生成されるのは、「HTML created time」の20秒後以降にアクセスしたタイミングとなります。
その際ファイルの再生成は行われますが、レスポンスは再生成前の古いHTMLが返ってくる点がポイントです。
また、再生成もサーバーサイドで処理を行う必要があるため、完了までには若干の時間を要します。再生成完了までは、アクセスしても古いHTMLが返ってくるので注意したいです。

# サンプルコード
上記サイトは同時アクセスされている場合、挙動がわかりづらくなります。その場合は以下ソースコードをクローンして、ローカルで実行していただくとわかりやすいかと思います。

`yarn dev`で起動するとSSRで動作してしまうので、`yarn build`→`yarn start`を利用してください。

https://github.com/Sinhalite/isr-sample
n進数について　[n進数のかけ算・わり算]

#n進数のかけ算・わり算

n進数のかけ算・わり算には**<font color="red">シフト演算</font>**を使う

###シフト演算とは

ビット列を左右どちらかにずらす操作のこと

#論理シフト

シフト演算には論理シフトというものがあり、符号を考慮せず、ずらすこと


**例）**

![スクリーンショット 2021-08-30 20.41.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1803385/0d6bdfd1-7871-8deb-9a39-7b9a3962a29e.png)

このような10進数があるとすると

####かけ算



![スクリーンショット 2021-08-30 21.30.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1803385/8ba94854-17b6-9f94-e1db-b4b0827f13fe.png)



左に２桁シフトするということは10の２乗をかければ表すことができる

####わり算
![スクリーンショット 2021-08-30 21.29.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1803385/5ba5ab0b-e295-2f3d-5408-606c48143530.png)

右に２桁シフトするということは1/10の２乗をかければ表すことができる


##法則

左にn桁シフト　　→  10のn乗かける
右にn桁シフト　　→1/10のn乗かける


**<font color="red">これは２進数でも一緒</font>**
#2進数のかけ算・わり算

####かけ算

![スクリーンショット 2021-08-30 20.38.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1803385/ff4b63e1-05d3-1e0c-1132-d094c7389db7.png)

####わり算


![スクリーンショット 2021-08-30 20.45.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1803385/0278342d-740f-ab0a-2f7c-760ebe386cb6.png)

**注意**

それぞれ注意点があるがどんな意味があるかというと・・・

![スクリーンショット 2021-08-30 20.49.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1803385/5ce91bd3-a7f9-9bfc-5b74-997780c5e3ec.png)

![スクリーンショット 2021-08-30 20.50.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1803385/9b9270f9-8622-8808-b346-81c741dc64eb.png)

#算術シフト

シフト演算には算術シフトというものもあり、符号を考慮して、ずらすこと

**例）**
![スクリーンショット 2021-08-30 20.55.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1803385/7bfbe268-cd04-51a7-dfa5-64f53a2f9fc8.png)

このような２進数があるとすると



####かけ算
![スクリーンショット 2021-08-30 21.21.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1803385/2163fa51-9fa2-9be0-f35c-c00e2ae7793c.png)


####わり算


![スクリーンショット 2021-08-30 21.27.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1803385/b3b8f146-25e5-3c2a-a5fb-e8717e5d2c26.png)



>参考書籍
>>きたみりゅうじ　『キタミ式　イラストIT塾　基本情報技術者　令和０３年』 技術評論社 2020年
SonarQube を Web App for Containers だけで動かす

## 概要

Docker Compose (Preview) を使うことでデータの消失を防ぎ、さらにストレージを使わないことでコストを抑えます。 Plan B2 でサクサク動作します。

注意点として SQL Database などのストレージを組み合わせたほうが App Service の拡張が難しい小さなストレージにも心配することなく SonarQube のアップデートにも対応できます。コストを使えるならその構成のほうがよいです。あくまでスモールスタート用です。

### docker-compose.yml

```yaml
version: "3"

services:
  sonarqube:
    image: sonarqube:8.9-community
    ports:
      - "9000:9000"
    networks:
      - sonarnet
    volumes:
      - sonarqube_data:/opt/sonarqube/data
      - sonarqube_extensions:/opt/sonarqube/extensions
      - sonarqube_logs:/opt/sonarqube/logs
      - sonarqube_temp:/opt/sonarqube/temp

networks:
  sonarnet:
    driver: bridge

volumes:
  sonarqube_data:
  sonarqube_extensions:
  sonarqube_logs:
  sonarqube_temp:
```

### Web App for Container

このサンプルは Azure Portal での設定方法になります。

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

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

起動後に少し経過してから `https://<YOUE_APP_NAME>.azurewebsites.net
` にアクセスすると SonarQube が実行されています。

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

## 参考文献

- [SonarSource/docker-sonarqube: SonarQube in Docker](https://github.com/SonarSource/docker-sonarqube)
- VM and SQL Database の場合: [Setup SonarQube Server on Azure VM | Azure DevOps Hands-on-Labs](https://www.azuredevopslabs.com/labs/vstsextend/sonarqube/sonarqube-arm/)
- Azure Container Instance の場合: [Managing technical debt with SonarQube and Azure DevOps | Azure DevOps Hands-on-Labs](https://azuredevopslabs.com/labs/vstsextend/sonarqube/)
  - ※ ACI のインスタンスを再起動すると SonarQube の構成は消えます
【未経験】約40時間でAWS-SAAに合格した話

# 概要
本日、AWS-SAA試験に合格いたしましたので、特に未経験から合格を目指している方に向けて、過程を以下に記そうと思います。
本記事の流れです。
・背景
・用意したもの
・学習法
・合格を重視した場合のコツ
・受験の流れ

# 背景
筆者のスペックを少々↓
・教育学部卒の小学校教員（24）
・業界未経験
・React Nativeでの開発経験あり
・バックエンド・インフラの開発経験無し
エンジニアへの転職を目指しており、個性が出る資格を取得したいと考えていました。
そんな折、AWSを用いた開発を主軸としている企業に魅力を感じることに気づき、学習を始めました。

# 用意したもの

◯Udemyの映像教材
これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（SAA-C02試験対応版） https://www.udemy.com/share/101XFi3@hmJAa2N4rCOzUa-RF5FjG7sAt8OFgeMgS6uV35YOq26b7hD7wlwnQs3NHoJELkXXOA==/

◯書籍
AWS認定資格試験テキスト AWS認定ソリューションアーキテクト - アソシエイト 改訂第2版
https://www.amazon.co.jp/dp/4815607389/ref=cm_sw_em_r_mt_dp_3MJ5SFS32RAY0AD4QJR8 

◯待ち時間を有効活用するためのもの
VSCode, 志望企業のブログ

# 学習法
###1.Udemy講座(動画):26~27時間
こちらの講座では、講師の方が丁寧にゆっくりとお話をしてくださっているので、1.25倍速にします。
これにより、動画時間が約32時間→25.5時間になります。
ハンズオンでは、AutoScaling実施やDB作成等で待ち時間が生じることがしばしばあります。
その時間で上記の書籍をチラ見するか、コーディングするか、何か時間を上手く使えるものを用意してください。
ハンズオンはしておくに越したことはないですが、時間がなければ作業している動画を見るだけでもOKです。
※EC2は起動時間が長いほど課金されるので、できるだけ早く講座を修了してインスタンスを終了しましょう。私はまったりやったので3000円ほどかかりました。

###2.Udemy講座(模試): 5~6時間
上記の講座には最後に模試が3回分付属しています。ここでは2回分取り組みました。
この模試は、解答後に問題領域ごとの正答率や解説を提示してくれます。
誤答した問題だけでなく、勘で当たった問題も各選択肢の解説をしっかりと読み込みましょう。
後述しますが、私はこのパートが最重要だと認識しています。

###3.書籍: 3~4時間
上記で取り組んだ模試の内容を中心に復習をしましょう。講座とは違った方が書いているので、表現の違いが理解に繋がったりします。これに関しては、Udemy講座の方で概要は1度押さえているので、通読しなくても大丈夫です。

###4.模試: 3時間
上記2.と同様に取り組んでください。ここで8割取れていれば安心です。あとは合格するだけ！

#合格を重視した場合のコツ
どういった試験でも通じることだと思いますが、問題のパターンを身につけてください。
模試を解いて、問題文と解説をじっくり読んでいるとパターンが掴めてきます。
具体例を書いてみます。

###Q.高パフォーマンスのEBSストレージ
コスト効率を重視→スループット最適化
パフォーマンスを重視→プロビジョンドIOPS

###Q.S3のパフォーマンスを最大化するには
プリフィックスで日付命名を実施する

---
この辺りは1体1で暗記できると思いますが、不具合の原因を想定して対策を立てる問題が私含め、未経験の方には慣れが必要だと感じました。例えば
###Q.EC2インスタンスにインターネットからアクセスできない

こういった問題は条件によって正解が異なってくるので深い理解が必要です。

---
入念に勉強しておくとよいサービス
VPC, IAM, EC2, S3, DB, ELB, AutoScaling Route53, Lambda, SQS, SNS
意外と盲点
WAF(セキュリティ周り), EFS

#受験の流れ
最後に、受験の流れを紹介します。
###1.試験のスケジューリング
まずは、AWS認定アカウントを作成します(AWSアカウントとは別です)。
ログインして、試験をスケジューリングします。
試験形態はどれでもいいですが、オンラインかつ日本語対応のPearson Vueがオススメです。
支払い方法を登録して、試験日時を確定します。
###2.試験当日
受験する部屋のデスク周りを整理します。
それから身分証明証を用意します。
それらの写真を試験監督に送り、OKが出れば試験開始です。
###3.試験
基本は消去法です。各選択肢のどこが違うのかをまず比較します。
残り時間を確認しつつ、怪しいものは右上の後で見直すボタンでマークして次に進みましょう。
試験中、使用しているソフトの挙動がおかしい場合は試験監督に合図をすれば対応してくれます。
慌てなくて大丈夫です。
###4.試験後
試験を完了すると、その瞬間に合否が表示されます。
覚悟を決めてから完了ボタンを押してください。
合格していれば、後ほどメールで合格を示すバッジが届きます。
合否に関わらず、数日後に具体的なスコアレポートが届きます。

#終わり
合格して舞い上がったテンションで書いているので、わかりづらいところがありましたら、ご指摘ください。
これからAWS資格取得を目指す方の一助になりましたら幸いです。
【Laravel】テーブル作成後にカラムを追加したい場合

#はじめに
テーブル（マイグレーションファイル）を作成した後に、カラムを追加したくなるときってありますよね。
私は、Laravelを学習し始めた頃、既に作成しているマイグレーションファイルにカラムを追加して、もう１回`php artisan migrate`すればいいんじゃないのって思っていました。
しかし、それでは`rollback`するときに、downメソッドによりテーブルが削除されてしまうので、それまでにテーブルに格納していたデータがなくなってしまいます。
そこで、以下の方法でカラムを追加していきます。
#カラムの追加方法
ターミナルもしくはコマンドプロンプトを起動し、

```
php artisan make:migration --table=[テーブル名] [マイグレーションファイル名]
```
を実行してマイグレーションファイルを追加します。
追加したマイグレーションファイルにカラムを追記して、`php artisan migrate`を実行すると、カラムを追加することができます。

#マイグレーションファイルのupメソッドの記述
・テーブル作成用

```php:作業日時_create_users_table.php
public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->text('name');
        $table->timestamps();
    });
}
```

・カラム追加用

```php:作業日時_users_add_columns.php
public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->text("mail")->nullable();
    });
}
```
【Rails】 投稿とユーザーの紐付け（メモ）

#　目標

* 投稿とユーザーの紐付け

#　環境

* Rails: 6.1.3 
* ruby: 3.0.0
* mac: OS


# 前提
* 投稿機能実装済み

# 実装
### 1.`post`テーブルに`user_id`カラムを追加
 
```ruby:ターミナル
$rails g migration AddUserIdToPosts user:references
```

```ruby
class AddUserIdToPosts < ActiveRecord::Migration[6.1]
  def change
    add_reference :posts, :user, null: false, foreign_key: true
  end
end
```

```ruby:ターミナル
$rails db:migrtate
```

### 2.モデルに`has_many`と`belongs_to`を記述
ユーザーは投稿が複数持てるので　`has_many`

```ruby:app/models/user.rb
class User < ApplicationRecord
  has_many :posts
```
 １つの投稿に対して１ユーザーなので`belongs_to`

```ruby:app/models/post.rb
class Post < ApplicationRecord
  belongs_to :user
```

### 3.　`post`コントローラー記述

```ruby:app/controllers/posts_controller.rb
class PostsController < ApplicationController
    
  def index
      @posts = User.posts
  end

  def show
      @post = User.posts.find(params[:id])
  end
  def create
      @post = User.posts.build(post_params)
      @post.save
      redirect_to root_url
  end
```
```ruby:app/controllers/users_controller.rb
class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
    @posts = @user.posts
  end

```

###4.ビュー記述
 投稿詳細ページでユーザー名を表示する。

```erb:app/views/posts/show.html.erb
<h1>投稿詳細ページ</h1>
<p><%= @post.user.name %></p>
<ｐ>内容：<%= @post.content %></ｐ>
```

ユーザー詳細ページに投稿を表示する。

```erb:app/views/users/show.html.erb
 <% @posts.each do |post| %>
          <hr>
          <p>投稿内容: <%=post.content %></p>
        <% end %>
```

これでユーザーとの紐付きができました。
基本的なことですが備忘録として残しておきます。
[Ruby] indexメソッド

##はじめに
indexメソッドという便利なメソッドを見つけたので記事に残しておきます。

##indexメソッド
indexメソッドはある要素が配列のどこにあるか調べる際に便利です。

例えば3が配列のどこにあるか知りたい場合

```ruby
array = [3, 2, 4, 1]
array.index(3)
=> 0
```

上記のように引数にどこにあるか調べたい要素を渡すと、インデックス数で配列のどこの位置にあるかを教えてくれます。

インデックス数で示されるので3は0で返ってきます。
【WordPress】カスタムフィールドを追加する

# WordPressおけるカスタムフィールドの役割
WPにおいて「投稿」にはタイトル、本文、カテゴリーなどのデフォルト項目があるが、サイトによってはこれ以外に欲しい項目が出てくる。
例えば自社製品の値段などは、本文に直接記載するよりカスタムフィールドを利用してフォームから入力できるようにしておいた方が、後から見た目を変えたり、価格順に並びかえたりすることが容易である。

# カスタムフィールドの挿入(プラグイン)
カスタムフィールドはプラグインの「Advanced Custom Fields（アドバンスド・カスタム・フィールド）」を使って簡単に追加できる。

管理画面の`プラグイン＞新規追加`から、Advanced Custom Fieldsを追加し、有効化する
![スクリーンショット 2021-08-30 20.14.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205283/56071bf4-e5cc-f1d4-79ea-d8bcf369ac06.png)

メニュー画面にカスタムフィールドの項目が追加されている
![スクリーンショット 2021-08-30 20.14.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205283/6405213f-65e2-0edf-94a8-296e03592632.png)

あとは、`新規追加＞フィールドグループを新規追加`でカスタムフィールドを追加する。

# 追加されたカスタムフィールドの表示コード
基本的には以下のような感じ、サブタイトルを表示させたい場合。]

the_field()でカスタムフィールド内の`sub-title`が存在するかを調べ、存在するようならdivタグで表示するようにしている。

```php
<?php if(get_field('sub-title')): ?>
  <div class="sub-title"><?php the_field('sub-title'); ?></div>
<?php endif; ?>
```
M5Stack Core2 で描画

次のような描画をします。
![IMG_20210830_200128.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/24659c81-dd45-c405-e556-d551061e19a1.jpeg)

```text:display01/display01.ino
// ---------------------------------------------------------------
/*
	display01.ino

					Aug/30/2021
*/
// ---------------------------------------------------------------
#include <M5Core2.h>

// ---------------------------------------------------------------
void setup() {
	M5.begin();
	M5.Lcd.setBrightness(32);
	M5.Lcd.fillScreen(WHITE);
	delay(200);

	draw_five_circles();
	delay(500);
}						 


// ---------------------------------------------------------------
void draw_five_circles()
{
	int tt = 200;
	draw_circle_proc(60,120,BLUE);
	delay(tt);
	draw_circle_proc(160,120,BLACK);
	delay(tt);
	draw_circle_proc(260,120,RED);
	delay(tt);
	draw_circle_proc(110,170,YELLOW);
	delay(tt);
	draw_circle_proc(210,170,GREEN);
	delay(tt);
}

// ---------------------------------------------------------------
void draw_circle_proc(int xpos,int ypos,uint16_t color)
{
	for (int it=0; it< 10; it++)
		{
		int rr = 41 + it;
		M5.Lcd.drawCircle(xpos, ypos, rr, color);
		}
}

// ---------------------------------------------------------------
void loop()
{
	M5.Lcd.setTextColor(MAGENTA);
	M5.Lcd.setTextSize(5);
	M5.Lcd.clear(WHITE);
	draw_five_circles();
	M5.Lcd.drawString("TOKYO 2020",15,10,1);
	delay(3000);
	M5.Lcd.clear(WHITE);
	draw_five_circles();
	M5.Lcd.drawString("PARIS 2024",15,10,1);
	delay(3000);
}

// ---------------------------------------------------------------
```


Arduino IDE 2.3.4 を使いました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/829f2b0b-e715-46b2-8012-4d7ef23e8db7.png)
Rails tutorial　第6版　第1章学習メモ

第1章

ゼロからデプロイまで
ブラウザで動かせる開発環境であるAWS Cloud9(https://aws.amazon.com/jp/cloud9/)を用いる。

Cloud9管理ページでCreate environment（訳：環境作成）をクリック

Nameには適当な環境名を入力、その下の枠description（訳：説明）には必要があれば入力する。

Environment settingsページのPlatformはUbuntu Serverを選択しNext Step

Create environmentで作成完了

しばらくすると、クラウドIDEの初期画面に移る。

右側上にある設定（ネジアイコン）でインデントに２つスペースを使うことが常識なようなので、セッティングする。保存ボタンはないので、２つにしたら再び設定ボタンをクリックすればよい。

1.2.2 Railsをインストールする

Rubyドキュメントをスキップする設定を.gemrcファイルに追加するコマンド

ubuntu:~/environmet $の後に下記コマンドを入力しエンター（$は自動入力なので、それ以降）

$ echo "gem: --no-document" >> ~/.gemrc

Railsをインストールするには、RubyGemsが提供するgemコマンドを使う。

バージョンを指定してRailsをインストールする

ubuntu:~/environmet $の後に下記コマンドを入力しエンター（１０秒程度でできた）

$ gem install rails -v 6.0.3

インストールできているかどうか確認するには下記コマンド
$ rails -v


JavaScriptソフトウェアの依存関係を管理するYarnというプログラムもインストールする。（これも１０秒もかかんない）

$ source <(curl -sL https://cdn.learnenough.com/yarn_install)

もし警告メッセージが出てインストールできない場合は、下記コマンドでもOK。

$ yarn install --check-files

アプリケーションの作成
rails newを実行

$ rails \_6.0.3\_ new hello_app←作成するアプリ名、自由に決めたら良い

ここまででアプリ作成前までの準備は完了するはず。第3章　ほぼ静的なページの作成へ飛び、前回進まなくなってしまった第7章　ユーザー登録までを記録していく。

逆戻り

第3章でHerokuへプッシュするときに、Herokuをインストールしてなかったのでインストールする


クラウドIDE上でHerokuをインストールするコマンド

`$ source <(curl -sL https://cdn.learnenough.com/heroku_install)`（５秒ほどで完了）

できてるか確認は下記コマンド

`$ heroku --version`

herokuコマンドでHerokuユーザー登録時に使ったメールアドレスとパスワードを入力してログインする、--interactiveオプションを使うとherokuコマンドでブラウザを開かないようにできる。

`$ heroku login --interactive`

::: note
$ heroku: Enter your login credentials
Email:（メールアドレスを入れてエンター）
Password: （パスワードを入れてエンター***で表示される）

:::

Herokuに新しいアプリケーションを作成する

`$ heroku login create`

:::note

Creating app... done, ⬢ polar-mountain-55653
https://（作成されたアプリ名）.herokuapp.com/ | https://git.heroku.com/（作成されたアプリ名）.git

:::

でHeroku上に作成される。
[PHP]json_decodeで返される値の扱い方

PHPのjson_decode()について忘備録。
第二引数に指定した値によって型が変わる。

```php
json_decode($json, true); //返される型は連想配列形式
json_decode($json, false); //返される型はobject形式
json_decode($json); //JSON_OBJECT_AS_ARRAYが設定されているかどうかによって決まる
```

https://www.php.net/manual/ja/function.json-decode.php

## 連想配列形式

第二引数がtrueの場合、型は連想配列。

```php
$json = '{"foo":1,"bar":2,"foo-bar":3}';

$result = json_decode($json, true);

echo(gettype($result)); // array
```

中の値を取り出す場合は配列のキーを指定して呼び出す。

```php
$result["foo"];
```

## オブジェクト形式

第二引数がfalseの場合、型はobject(stdClass)。


```php
$json = '{"foo":1,"bar":2,"foo-bar":3}';

$result = json_decode($json, false);

echo(gettype($result)); // object
```

中の値を取り出す場合はオブジェクトプロパティを呼び出す。

```php
$result->foo;

// PHPの命名規約では使えないハイフンなどの文字を含む要素にアクセスするには、要素名を波括弧とアポストロフィで囲む
$result->{'foo-bar'};
```
Pythonではじめる機械学習 part5

# 前回の内容
[Pythonではじめる機械学習 part4](https://qiita.com/yuto_suzuki/items/97f158451990dca1bb58)

# 教師あり学習① 概要
前回まではアイリスのクラス分類ということで、大量のアイリスデータを元に、野生のアイリスを推測するモデルの構築をしてきた。
これはいわゆる、教師あり学習という枠の機械学習である。
ここからは、教師あり学習についてさらに踏み込んでまとめていく。

### 教師あり学習とは？
ある入力に対して、特定の出力を予測したいケースの時に、入力と出力のペアがすでに入手可能である場合に用いられるパターンである。
一般的に、教師あり学習で学習させる際はかなりの工数がかかるが、ひとたび学習が終われば、その労力に見合った働きをしてくれる。

### クラス分類と回帰について
教師あり学習で解く問題は大きく分けて、クラス分類と回帰に分類できる。
クラス分類とは、予め定めておいたいくつかのクラスに新しいデータを分類すること。
一方、回帰とは、連続値を予測する際に用いられる。（こちらわかりづらいので後程詳細に）

### クラス分類の種類
回帰に突っ込む前に、まずはクラス分類について。
クラス分類は、その中でも２クラス分類と他クラス分類に分けられる。
これは単純で、分類するクラスラベルが2つ（ＹｅｓかＮｏか）か、3つ以上かの違いだけである。

### 回帰について
これがパッと見わかりづらい。
回帰とクラス分類を見分ける際は、その期待値がある程度大雑把でも問題ないかが一つの基準点になりそうだ。
例えば、住所・年齢・性別データから、年収を予測するような場合は、答えが1000万円でも、1000万1円でも、予測値としてはどちらでもよい。
これは回帰問題と分類することができる。
逆に、多クラス問題は、固定したクラスのどれかには必ず属さなければならないので、間違いがあると精度に大きく響くことになる。

#教師あり学習①　所感
初見の状態だと、回帰が分かりづらかった印象がありました。
ただ、クラス分類と対比することで、理解が深まりました。
機械学習で解決する問題としては、どちらもよくあるパターンだと感じたので、ここは自分の中で納得がいくように理解しておく。

# 次回記事
Pythonではじめる機械学習 part6(準備中)
AWS lambdaを時間指定で１回だけ実行する方法

# はじめに
私はaws初心者です。lambdaで困ったことがあったからメモとして残します。

# やりたいこと
lambda functionを時間指定で１回だけ実行したい

想定しているケース
・ あるイベントがまとまったページを監視して、新しいイベントが登録されたらイベントが開催される１日前にLINEで通知する。

この場合だと、
Lambda①：スクレイピング→Lambda②の時間予約(新しいイベントの１日前）
（イベント情報も渡す）
Lambda②：関数①から受け取った情報をLINEに送信

# どうしたか
使ったもの：Lambda、EventBridge

> 補足
EventBridgeは**定期実行**とかをしてくれるらしい。この定期実行の規則をルールと呼ぶ。


```python:Lambda①
import boto3

client = boto3.client('events')

event_name = "ルールの名前"
description = "ルールの説明"
event_time = "cron(* * * * ? *)" #実行したい時間を満たすようにする（*を全部指定してあげるとミスがない）
lambda_id = 'lambda functionを識別するためのID'
lambda_arn = 'lambda②のArn'
lambda_name = "ambda②の関数名"

def register():
	# ルールを追加
	response = client.put_rule(
		Name=event_name,
		ScheduleExpression= event_time,
		EventPattern='',
		State='DISABLED',
		Description=description)

	# 実行したい関数を登録
	d = {
		"name": event_name,
		"text": "lambda②で送りたいテキスト"
	}
	response = client.put_targets(
		Rule=event_name,
		Targets=[
			{
				'Id': lambda_id,
				'Arn':  lambda_arn,
				"Input": json.dumps(d)
			}
		]
	)

	# ルールの有効化
	response = client.enable_rule(
		Name=event_name
	)

	# 初回は許可を与えないと実行してくれない
	#lclient = boto3.client("lambda")
	#response = lclient.add_permission(
	#	FunctionName=lambda_name,
	#	StatementId="1",
	#	Action='lambda:InvokeFunction',
	#	Principal='events.amazonaws.com',
	#)

```

```python:Lambda②
import boto3

def delete_rule(d):
	client = boto3.client('events')
	lambda_id = 'lambda functionを識別するためのID' #lambda①と同じにする

	# 定期実行の関数（自分自身）をターゲットから外す
	res = client.remove_targets(
		Rule=d["name"],
		Ids = [
			lambda_id
		]
	)

	# ルールそのものを削除する
	res = client.delete_rule(
		Name=d["name"]
	)
	return res

def send(d):
	# d["text"]を送信

def lambda_handler(event, context):
	delete_rule(event)
	r = send(event)
```

Lambda①で実行したい時間をcronで満たすようにルールを設定して、
Lambda②が実行するときにそのルールを削除するというやり方でやりました。

もっといい方法があれば是非お願いします。
【Rails】取得したenumの値とモデルのenumを比較する方法

取得したenumの値とモデルのenumを比較することができず、詰まったので、同じ轍は踏まないように情報共有したいと思います。


## 準備
User.rbでenumを設定

```ruby
enum sex: {
  # 無回答
  no_answer: 0,
  # 男性
  male: 1,
  # 女性
  female: 2,
}
```

rails console

```ruby
# enumを確認
User.sexes
=> {"no_answer"=>0, "male"=>1, "female"=>2}
User.sexes[:male]
=>1

# インスタンスを取得
user = User.find(4)

# インスタンスのenumを確認
user.sex
=>"male"
```


## 詰まったこと
enumの比較ができない・・・
### 実現したいこと
「インスタンスのsexがmaleであるとき」の条件式が作りたい。
### 試したこと
```ruby
user.sex == User.sexes[:male]
=> false
```
・・・できない。
それもそのはず

```ruby
user.sex
=>"male"
User.sexes[:male]
=>1
```
enumのkeyとvalueが逆ならいいのに・・・
じゃあこうしてやれ

```ruby
user.sex == User.sexes.invert[0]
=> true
```
結果うまくいったが、0がマジックナンバーみたいで、値の意味がわからない。リファクタリング必至。

### 解決策
```ruby
User.sexes[:male] == User.sexes[user.sex]
```
osを作る その7

#概要

osを作る。
freertosを使ってみた。
arduino unoでlcd keypadに、A0の値を表示してみた。

#サンプルコード

```

#include "Arduino_FreeRTOS.h"
#include "queue.h"
#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

QueueHandle_t integerQueue;

void TaskAnalogRead(void * pvParameters) {
	(void) pvParameters;
	for ( ; ; )
	{
		int sensorValue = analogRead(A0);
		xQueueSend(integerQueue, &sensorValue, portMAX_DELAY);
		vTaskDelay(1);
	}
}
void TaskLcd(void * pvParameters) {
	(void) pvParameters;
	lcd.begin(16, 2);
	lcd.setCursor(0, 0);
	lcd.print("Push the buttons");
	lcd.setCursor(6, 1);
	lcd.print("A0");
	int valueFromQueue = 0;
	for ( ; ; )
	{
		if (xQueueReceive(integerQueue, &valueFromQueue, portMAX_DELAY) == pdPASS)
		{
			lcd.setCursor(10, 1);
			lcd.print(valueFromQueue);
			lcd.print("mV    ");
		}
	}
}
void TaskBlink(void * pvParameters) {
	(void) pvParameters;
	pinMode(LED_BUILTIN, OUTPUT);
	for ( ; ; )
	{
		digitalWrite(LED_BUILTIN, HIGH);
		vTaskDelay( 250 / portTICK_PERIOD_MS );
		digitalWrite(LED_BUILTIN, LOW);
		vTaskDelay( 250 / portTICK_PERIOD_MS );
	}
}
void setup() {
	integerQueue = xQueueCreate(10,sizeof(int));
	if (integerQueue != NULL)
	{
		xTaskCreate(TaskLcd, "Lcd", 128, NULL, 2, NULL);
		xTaskCreate(TaskAnalogRead, "AnalogRead", 128, NULL, 1, NULL);
	}
	xTaskCreate(TaskBlink, "link", 128, NULL, 0, NULL);
}
void loop() {
}





```


以上。
Sequel ProからSequel Aceに乗り換えた

Sequel Proが以前からよく落ちるのと2019年から開発が止まっているのでSequel Aceに乗り換えました。
ssh接続がProとちょっと異なっていたのでメモ

公開鍵やらconfigやらknown_hostsやらを登録しないといけないらしく
下記の設定で接続できた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1705850/67c3c707-afe0-4641-980d-6ba9b93d9a1d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1705850/0548288d-6e09-9da3-9e02-1fbd68dd6c8d.png)

~~なんかちょっと触ったけど落ちる時は落ちる気がする~~
スピン変数の積の線形表現

2つのスピン変数$s_1 s_2$ の積の線形表現を考えます.

```math
y = s_1 s_2 \quad (s_1, s_2 \in \{-1, 1\})
```

結論から言うと, 下記のようになります.

```math 
\left\{
\begin{array}{ll}
y \leq \ \ \  s_1 - s_2 + 1 \\
y \leq -      s_1 + s_2 + 1 \\
y \geq \ \ \  s_1 + s_2 - 1 \\
y \geq -      s_1 - s_2 - 1\\
y \in \mathbb{Z}
\end{array}
\right.
```

### 証明

| $s_1$ | $s_2$ | $y \leq s_1-s_2+1$ | $y \leq -s_1+s_2+1$ | $y \geq s_1+s_2-1$ | $y \geq -s_1-s_2-1$ | $y \in \mathbb{Z}$  |
| ----- | ----- | ----------- | ------------ | ----------- | ------------ | ---- |
| 1     | 1     | $y \leq 1 $ | $y \leq 1 $  | $y \geq 1 $ | $y \geq -3$  | 1    |
| 1     | -1    | $y \leq 3 $ | $y \leq -1$  | $y \geq -1$ | $y \geq -1$  | -1   |
| -1    | 1     | $y \leq -1$ | $y \leq 3 $  | $y \geq -1$ | $y \geq -1$  | -1   |
| -1    | -1    | $y \leq 1 $ | $y \leq 1 $  | $y \geq -3$ | $y \geq 1 $  | 1    |


### 導出

$(x_1, x_2, y)$がとりうる組み合わせ
$(1, 1, 1), (1, -1, -1), (-1, 1, -1), (-1, -1, 1)$ の整数点を含み,
$(1, 1, \mathbb{Z}\setminus \\{1\\}), (1, -1, \mathbb{Z}\setminus \\{-1\\}), (-1, 1, \mathbb{Z}\setminus \\{-1\\}), (-1, -1, \mathbb{Z}\setminus \\{1\\})$を含まない
凸領域を生成する, ここで$(1, 1, \mathbb{Z}\setminus \\{1\\})$ は $\\{(1,1,y); y \in \mathbb{Z} \setminus \\{1\\}\\}$を表します.


### バイナリ変数の積からの導出

よく知られた

```math
z = b_1 b_2 \quad (b_1, b_2 \in \{0, 1\})
```

バイナリ変数の積の線形表現

```math 
\left\{
\begin{array}{ll}
z \leq b_1 \\
z \leq b_2 \\
z \geq b_1+b_2-1 \\
z \in \{0, 1\}\\
\end{array}
\right.
```

を用いた導出も可能です. この場合, $z \in \\{0, 1\\}$を$z \geq 0$に置き換えておくのがミソで,


```math
\begin{align}
y &= s_1 s_2 \\
  &= 4\left(\frac{1+s_1}{2}\right)\left(\frac{1+s_2}{2}\right) - \left(s_1+s_2+1\right)
\end{align}
```


ここで

```math
z := \left(\frac{1+s_1}{2}\right)\left(\frac{1+s_2}{2}\right)
```

に対して, 右辺はバイナリ変数の積になっているので, 上記の制約群で線形化したのち

```math
y = 4 z - (s_1+s_2+1) \iff z = \frac{1}{4}\left(y + \left( s_1+s_2+1 \right)\right)
```

を用いて$y$について整理すると最初の制約群が出てきます.



## スピン変数とバイナリ変数の積

ちなみに

```math
y = s b \quad (s \in \{-1, 1\}, b \in \{0, 1\})
```

は


```math 
\left\{
\begin{array}{ll}
y \leq b \\
y \leq s-b+1 \\
y \geq s+b-1\\
y \geq -b\\
y \in \mathbb{Z}
\end{array}
\right.
```

となります.
ドッペルゲンガードメイン とは

## 勉強前イメージ

同じドメインがいくつかある・・・？

## 調査

### ドッペルゲンガードメインとは

有名なドメインにそっくりのドメイン名のことで、
自分とそっくりな人の姿を自分で見る幻覚の一種のことであるドッペルゲンガーから呼ばれるようになった。
タイプミスなどでドッペルゲンガードメインを使ったフィッシングサイトに誘導するというのが典型的な攻撃例である。

### ドッペルゲンガードメインの例

例えば正しいドメイン名が `example.com` だとすると
ドッペルゲンガードメインだと `exampla.com` などパッと見でにたようなドメインがあげられます。
また、 `gmail.com` だとすると、 `gmai.com` がドッペルゲンガードメインになります。

### ドッペルゲンガードメインでのインシデントの例

- ドメインのタイポで第三者にメールを送ってしまった
- フィッシングメール

誤送信での情報漏えい対策も必要で、
情報レベルが高いものについては添付ファイルへのパスワードや
ファイル送信サービスを使うことで可能性を減らすことが出来ます。

## 勉強後イメージ

初めて知った言葉。
でもよくあるよね、、、amazan.comからメール来たりね。
気をつけないといけないですね。

## 参考

- [あなたも狙われている？　古くて新しい攻撃手法「ドッペルゲンガードメイン」とは](https://atmarkit.itmedia.co.jp/ait/articles/2106/04/news021.html)
- [第42回 ドッペルゲンガードメインにご注意下さい](https://www.lrm.co.jp/blog/2021/06/22/%E7%AC%AC42%E5%9B%9E-%E3%83%89%E3%83%83%E3%83%9A%E3%83%AB%E3%82%B2%E3%83%B3%E3%82%AC%E3%83%BC%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%81%AB%E3%81%94%E6%B3%A8%E6%84%8F%E4%B8%8B%E3%81%95%E3%81%84/)
CodeシリーズとLambdaを利用したデータファイルの自動登録

# 背景
サービスを提供している場合、マスタデータの登録ってついてまわりますよね
この作業ってトイルに分類されるものだと思っています
自動化できる部分は自動化したいものです

幸いなことに、AWS環境には、CodePipelineやLambdaと自動化への環境は整えられています
細かい作り込みは必要となりましたが、自動化そのものは実現できましたので、ご参考になりましたら

# 実装関係
## 使ったサービスやコマンド

* CodePipeline
* CodeCommit
* CodeBuild
* git
* SSM(ParameterStore)
* S3
* Lambda

### CodeCommit

ポイントは1つだけです
出力アーティファクト形式に「完全クローン」を選択してください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6748/79855b7d-f71c-dbc4-080a-eba821086fb4.png)


### CodeBuild
細かい技術の組み合わせとなっています
ポイントとそれに関する説明をしていきます

#### 登録用データファイルの作成
`git archive`コマンドでgitで管理しているファイルをzip形式で出力できます
`git diff`コマンドで特定のCommit間のファイルを特定できます
この2つのコマンドで、前回CommitとHEADの間のファイルをzipファイルに出力できます

```buildspec.yml.sh
git archive [ブランチ] `git diff --name-only ${PRE_COMMIT} HEAD --diff-filter=AM` -o ${FILENAME} --worktree-attributes
```

`PRE_COMMIT`はSSMのパラメータストアに保持するようにしました
下のコマンドで取得しています

```buildspec.yml.sh
PRE_COMMIT=$(aws ssm get-parameter --name [パラメータストア名] | jq ".Parameter.Value" | sed -e "s/\"//g")
```
apiの戻り値のJSONからjqでパラメータストアの値を取得し、sedコマンドでダブルコーテーションを除去しています

`--worktree-attributes` は、.gitattributesに記載したgit archiveに含めたくないファイルを反映してくれるオプションです

```dot.gitattributes
buildspec.yml export-ignore
script/ export-ignore
```

後は、ファイルをS3に上げて

```buildspec.yml.sh
aws s3 cp ${FILENAME} s3://${S3_BUCKET}/${S3_KEY}
```

最新のcommit番号をパラメータストアに更新し直して、Codeシリーズのタスクは完了です
なお、`--overwrite`オプションがないとエラーになります

```buildspec.yml.sh
- NOW_COMMIT=$(git rev-parse HEAD)
- aws ssm put-parameter --name [パラメータストア名] --value ${NOW_COMMIT} --overwrite
```

#### 対象のファイルがなかったら
commitするのはデータファイルばかりではないので、登録対象のファイルがない場合もあります
マスタデータの登録を行うLambdaでの対応も出来ますが、無駄にS3にファイルを上げたりLambdaを実行したりするのは嫌だったので、
[CodeBuildのbuildspec.ymlにまつわるexitいろいろ](https://zenn.dev/faycute/articles/cde8ddcbced9a2) を参考に下のshellファイルで処理を止めるようにしました
Dai@FastLabel さん、ありがとうございます

```count_target_file.sh
#!/bin/sh
CNT=$(git diff --name-only ${PRE_COMMIT} HEAD --diff-filter=AM -- data | wc -l)
echo $CNT
if [ $CNT -eq 0 ]; then
  exit 1
fi
```
対象となるマスターファイルはdataディレクトリに置く運用になっています
commitされたファイルをdataディレクトリのものに絞って、その件数が0かどうかで判定するようにしました

#### Lambdaの起動
後は、S3のPUTイベントで、Lambdaを起動して、LambdaでDynamoDBに登録すれば完了です
Lambdaの処理内容は、Qiitaを読むレベルの方には蛇足になりますので、2点だけ述べておきます

#### エイリアスを付与したLambdaを実行
開発、ステージング、本番と環境を別に設けているケースがほとんどだと思います
環境ごとに同じLambdaを用意するのは無駄なコストになりますので、devやstg、prdといったエイリアスをつけて
環境を識別するようにしました

```lambda.py
Stage = context.invoked_function_arn.split(":")[-1]
```
#### unzip先はディレクトリ
S3にアップロードしたファイルはzipファイルなので当然解凍しますが、解凍先のパラメータをファイルと思い込んでいまして、無駄に時間を費やしました
下のpythonコードの最後の行のunzip_dirのところですね
同じ轍を踏みませんように

```lambda.py
   with zipfile.ZipFile(zip_file, "r") as z:
        for f_name in z.namelist():
            if f_name.endswith(".csv") or f_name.endswith(".json"):
                z.extract(f_name, unzip_dir)
```

# 終わりに
まだ本格的な運用が始まっていないこと、私がshellをあまり書いたことがないことから、不具合やもっと効率の良い書き方もあると思います
ですが、現時点ではやりたかったことを実現できましたので、Qiitaでシェアすることにしました

皆様のトイル撲滅の一助になりましたら
paygent決済システム導入(PHP編2)

#趣向
PHPでpaygent決済システム導入を導入機会が
あったためゆらりと述べていこうと思います。


#PHP編1の続き
このページではペイジェントオンライン(試験環境)へのアクセスまでの流れを説明します。
ペイジェントオンラインはクライアント証明書をインストールしなければアクセスできません。

試験環境接続キットの中にある、pfxファイルを開きます。
押下するとパスワードを聞かれるため、入力。

![スクリーンショット 2021-08-30 18.35.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/843952/9fb7755d-6e11-6b2c-b8e2-49bfc08d713b.png)


証明書を追加する。
キーチェーンはログインにする。
![スクリーンショット 2021-08-30 18.36.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/843952/5f5d17ce-a88e-2bc9-a0c8-5a2eb65030ef.png)


アプリケーションのキーチェーンアクセスを使用して先ほどインストールした証明書があればOKです。

あとはペイジェントオンラインにアクセスして各自パスワードを設定してください！
IntelliJでファイルの保存時にコード整形を実行する方法

```
訳あってIntelliJの最新版をクリーンインストールすることになった。
表題の設定を施そうとしたところ、以前より簡単に設定できるようになっていたので、その方法をメモ。
```

# 設定方法
1. `⌘ + ,`で環境設定ダイアログを開く
1. `ツール` > `保存時のアクション`
1. 「コードの整形」項目にチェックを入れる
![スクリーンショット 2021-08-30 18.17.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102123/78141add-083c-7898-ddca-319e821abbbc.png)

* 後述した以前の設定方法よりはるかに手順が少なくて楽。

# 以前に設定していた方法

## マクロの作成
1. `編集` > `マクロ` > `マクロの記録を開始`
1. `⌘ + ⌥ + L`でコードを整形
1. `⌘ + S`でファイルの保存
1. `編集` > `マクロ` > `マクロの記録を停止`
1. マクロに名前をつけて保存（Format and Save Fileとした）

## ショートカットを設定
1. `⌘ + ,`で環境設定ダイアログを開く
1. `キーマップ` > `マクロ` > `Format and Save File`を右クリック
1. `キーボードショートカットの追加`
1. 任意のショートカットを登録
進化戦略のプロシージャ

Twitterの広告にシュタインズゲートが流れてきたので
お？っと心惹かれ paizaで電脳言語のオルダーソンループ挑戦したけど
進化戦略のプロシージャは問題文がわかりにくすぎるだろこれ、
二度もしくってイラッとしたわ

競プロやったことないんで
はじめinput() の使い方からしてWhat?って感じだったわ

```Python
# coding: utf-8
# 自分の得意な言語で
# Let's チャレンジ！！
import sys
n,m = input().split()

#if n == m:
#    print('Yes')
#    sys.exit()

act_dict = {}
for i in range(int(m)):
    k,v = input().split()
    act_dict[int(k)] = int(v)

stay_home = {}
for k,v in act_dict.items():
    if k in stay_home or k == v: # 同じ部屋には移動可能
        continue
    idx = k
    while idx in act_dict:
        nxt = act_dict[idx]
        if nxt in stay_home:
            break
        if nxt == k:
            print('Yes')
            sys.exit()
        stay_home[nxt] = True
        idx = nxt

print('No')
```