OmniAICreator/Qiita-1.07M huggingface dataset:
Swift よくつまずくdelegateについて

#delegateとは
Swiftを勉強しているとdelegateというのがよく出てきます。
例えば以下の例

```swift:ViewController.swift
tableView.delegate = self
tableview.dataSource = self
```
delegateを和訳すると委譲や委任らしいですが日本語の意味は理解できても、「ほぉ、それで？」と思いますよね。
てことで、どういう使われ方をしているか見ていきましょう。

##delegateの使い方
そのクラスができない処理を他のクラスに代わりにしてもらうというものなんですが、すこしコードを見てみましょう
今回はUITextViewについてです。

```swift:ViewController.swift
textView.delegate = self
```
```swift:ViewController.swift
extension ViewController: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        // textViewのtextに変更が会った時の処理
        if !textView.text.isEmpty {
            print(textView.text)
        }
    }
}
```

こんな感じでtextViewだけじゃできない処理をViewControllerに代わりにやってもらうことができます。
他にもpresentで画面を表示したりするのはViewControllerじゃないとできないので、タップして画面表示させたいときとかに使います。

##delegateを実装

delegateはprotocolで宣言します。
`: AnyObject`の部分は~~delegateをclassでしか使えなくするためらしい？？~~
`weak`を使えるようにするためらしいです。
詳しくは以下を参照してください。
>[Swift で Class-Only Protocol を定義する](https://qiita.com/lovee/items/a686e11f00b31323e683)

```swift
protocol CustomViewDelegate: AnyObject {
    public func customView()
}
```
```swift:CustomView.swift
class CustomView {
    weak var delegate: CustomViewDelegate?
    @IBOutlet var button: UIButton!
    @IBAction func button() {
        delegate.customView()
    }
}
```

delegate変数の宣言の時のweakはメモリリークを避けるためのなんたら〜らしいです。
`追記:`weakについてコメントしてくださっているのでそちらも見てください。
>[【Swift】weakやunownedなどの参照についてまとめてみた](https://qiita.com/rockname/items/b00d52c9bc49603f99a5)

#まとめ
なんやかんや書いてきましたが、Twitterとかのプロフィール画像をタップした時に相手のプロフィール画面に飛ぶ時とかにつかえるってことですね！
特定のcommit箇所まで強制復元する【git reset --hard】

まず、戻したいcommitのハッシュ値を調べる。
（調べ方についてはコマンド操作よりVSCodeの拡張機能のGit Graphを使用する方がお手軽）

例えば1ae86e0c3320c2e375d5d505f80813a6f7ba8a55と言うcommitまで戻したい場合は、下記のようにする。

```
git reset --hard 1ae86e0c3320c2e375d5d505f80813a6f7ba8a55
```

`--hard`をつけると強制的にコマンドを実行する。
Googleスプレッドシートで郵便番号から住所を表示する関数 その３

# 概要
セルに郵便番号を入力することで、住所を表示してくれる関数があったらなぁと思って書いた[プログラム](https://qiita.com/KensukeSakakibara/items/01470b28fd5ec4cf3416)が動かなくなっていたので、zipcloudさんのAPIを使って書き直してみた[プログラム](https://qiita.com/KensukeSakakibara/items/a5c4da9d62d7dcb8d665)の出来がイマイチだった。
というわけで、今回は更にzipcloudさんのAPIを使わずに自前でAPIを作成して書き直しました。

API側のサーバは無料レンタルサーバの[XFREE](https://www.xfree.ne.jp/)をお借りし、郵便番号データは郵便局本家で配布している[郵便番号データ](https://www.post.japanpost.jp/zipcode/download.html)を成形して利用しています。
API側のプログラムの中身は内緒。
サーバは完全に無料で利用させてもらっていますので性能までは求められませんが、XFREEさんが許してくれる限りこのまま放置で使いたい人が何気に使う形でいいかなぁと思っています。

# 使い方
下記をスクリプトエディタにコピペすれば関数を利用できるようになります。
`=ZIP_ADDRESS("154-0004","address1")`
みたいな感じ。

利用できるデータの種類は次の通りです。
zipcode	郵便番号
prefcode 都道府県コード
address1 都道府県名
address2 市区町村名
address3 町域名

```js
function ZIP_ADDRESS(zip,part)
{
  zip = zip.replace(/\-/g, '');
  var response = UrlFetchApp.fetch('http://zipaddress.php.xdomain.jp/search.php?v=' + zip);
  var res = JSON.parse(response.getContentText());
  if (res.status == 400) {
    return res.message;
  }

  if (res.results) {
    var address = res.results[0];
    return (address[part]) ? address[part] : "";
  } else {
    return "該当するデータがありません";
  }
}
```

ただ、いつのまにかGASのセキュリティ仕様が変わっているみたいで、外部システムのデータを読み込むときに承認が必要と言われると思います。
そんなときはこちらの記事を参考に承認すれば大丈夫です！
https://qiita.com/h-sto/items/fdde0905d0a4070d18fc
SageMaker PipelinesのOutputConfigの中身はどこを参照したらよいのか

# はじめに

SageMaker Pipelinesにおいて、前のステップのOutputを次のStepに利用する場合に、以下のように実行する。
このstep_process.properties.ProcessingOutputConfig.Outputs["train"].S3Output.S3Uriの、S3Output.S3Uriのようなプロパティは、どこに記載されているのか？

```python:pipeline_definition.py
from sagemaker.processing import ProcessingInput, ProcessingOutput
from sagemaker.workflow.steps import ProcessingStep
from sagemaker.inputs import TrainingInput
from sagemaker.workflow.steps import TrainingStep

step_process = ProcessingStep(
    name="AbaloneProcess",
    processor=sklearn_processor,
    inputs=[
      ProcessingInput(source=input_data, destination="/opt/ml/processing/input"),  
    ],
    outputs=[
        ProcessingOutput(output_name="train", source="/opt/ml/processing/train"),
        ProcessingOutput(output_name="validation", source="/opt/ml/processing/validation"),
        ProcessingOutput(output_name="test", source="/opt/ml/processing/test")
    ],
    code="abalone/preprocessing.py",
)

xgb_train = (中略)

step_train = TrainingStep(
    name="AbaloneTrain",
    estimator=xgb_train,
    inputs={
        "train": TrainingInput(
            s3_data=step_process.properties.ProcessingOutputConfig.Outputs[
                "train"
            ].S3Output.S3Uri,   ← ココ!!!!
            content_type="text/csv"
        ),
        "validation": TrainingInput(
            s3_data=step_process.properties.ProcessingOutputConfig.Outputs[
                "validation"
            ].S3Output.S3Uri,
            content_type="text/csv"
        )
    },
)
```

# 結果

ここ
https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_DescribeProcessingJob.html

```json
{
(前略)
   "ProcessingOutputConfig": { 
      "KmsKeyId": "string",
      "Outputs": [ 
         { 
            "AppManaged": boolean,
            "FeatureStoreOutput": { 
               "FeatureGroupName": "string"
            },
            "OutputName": "string",
            "S3Output": { 
               "LocalPath": "string",
               "S3UploadMode": "string",
               "S3Uri": "string"
            }
         }
      ]
   },
(後略)
}
```

こちらに記載がありました
https://docs.aws.amazon.com/sagemaker/latest/dg/build-and-manage-steps.html#build-and-manage-properties

# こっちじゃないよ

Sagemaker Python SDKのドキュメントやコード(以下)のProcessingOutputConfigには記載されていないので、混乱した。
https://sagemaker.readthedocs.io/en/stable/api/training/processing.html#sagemaker.processing.ProcessingOutput
https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/processing.py#L1079


# 感想

SageMaker Pipelines、CI/CD等のフルセットでのテンプレートが用意されている点は良いですね。
ただ、Step Functions Data Science SDKと比べ、ワークフローにLambda等を差し込めない等の自由度の低さは改善の余地がある気がしました。(自分が知らないだけ？)
Ruby on Rails カラム追加、削除の方法

## 目的
テーブルを作ったはいいけどカラムを追加したいときにやり方あってるかな？と不安になるので書いてみた。
## カラムの追加方法
ターミナルでコマンドを打ちます。

<strong>rails g migration Addカラム名Toテーブル名 カラム名:型</strong>

例えば、1つだけ増やしたい場合は、

```
　rails g migration AddNameToPosts name:string
```
複数の場合は、

```
　rails g migration AddColumnsToPosts name:string day:data
```
AddColumnsToPostsのColumnsのところはどんな名前でもOKです。

最後に、

```
　rails db:migrate
```
でOKです！

## カラムの削除方法
カラムの削除方法も書いておきます。

<strong>rails g migration Removeカラム名Fromテーブル名 カラム名:型</strong>

例えば、1つだけ減らしたい場合は、

```
 rails g migration RemoveNameFromPosts name:string
```

複数の場合は、

```
　rails g migration RemoveColumnsFromPosts name:string day:data
```
こちらもRemoveColumnsFromPostsのColumnsのところはどんな名前でもOKです。

最後に、

```
　rails db:migrate
```
でOKです！

##参考
https://qiita.com/ITmanbow/items/2bf4dfa4d9ca705b97df
とても参考になりました！
Ubuntu + Identiv Cloud 3701 FでSuicaを読み込む（下調べメモ その2）

# これはなに？

Identiv Cloud 3701 Fを使用してSuicaを読み込む努力のとりとめのないメモです。

[これ](https://qiita.com/sengoku/items/031e5372aec3c13fccb6) の続きです。

# コマンドいろいろ

## システムコードの取得

### APDU

| CLA | INS | P1 | P2 | LC |
|:-:|:-:|:-:|:-:|:-:|
| FF  | 4A  | 00  | 00  | 00  |

### レスポンス

| 1-8 | 9 | 10- |
|:-:|:-:|:-:|
| IDm(Manufacture ID)  | システムコードの数 | システムコード(2バイト)のリスト  |


手元のSuica提携カードでは、3つのシステムコードが返りました。

| システムコード | 用途? |
|:-:|:--|
| 00 03 | 交通系IC ? |
| FE 00 | 共通領域 ? |
| 86 A7 | ? |


## NFCID2の取得

システムコードとしてワイルドカード 0xff 0xff を指定すると、先頭のシステムが返る（？）

### APDU

| CLA | INS | P1 | P2 | LC | Data |   |  |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| FF  | 40  | 00  | 00  | 04  | システムコード(2バイト)  | 0x01  | タイムスロットナンバー(1バイト)[^1]  |

### レスポンス

| 1-16 | 17-18 |
|:-:|:-:|
| NFCID2  | 送信したシステムコード  |

NFCID2は8バイトじゃないのかな？

[^1]: ~~なんでもいい~~01 03 04 07 のいずれか？
** (MyXQL.Error) (1406) (ER_DATA_TOO_LONG) Data too long for columnが発生した場合に２つ確認する

## 1. Aliasを書き忘れていないか。

```
Sample |> Repo.all()
```

これを書くなら、defmodule内に下記のようなaliasを記述していなければいけない。

```
alias Project.Context.Sample
```


## 2. DBの文字コード

例えばMySQLと、クエリで文字コードが異なると発生する。
その場合、MySQLの文字コードを`utf8`にする。


MySQLの`my.cnf`の`[mysqld]`直下で`utf8`を指定する記述をします。

```
[mysqld]
## UTF 8 Settings
init-connect='SET NAMES utf8'
collation_server=utf8_unicode_ci
character_set_server=utf8
skip-character-set-client-handshake
```

確認します。

```
mysql> show variables like '%char%';
+--------------------------+--------------------------------+
| Variable_name            | Value                          |
+--------------------------+--------------------------------+
| character_set_client     | utf8                           |
| character_set_connection | utf8                           |
| character_set_database   | utf8                           |
| character_set_filesystem | binary                         |
| character_set_results    | utf8                           |
| character_set_server     | utf8                           |
| character_set_system     | utf8                           |
| character_sets_dir       | /usr/share/mysql-8.0/charsets/ |
+--------------------------+--------------------------------+
8 rows in set (0.01 sec)

```
css(styleタグ)をjavascriptで追加する

```
// styleタグを作成
var styleTag = document.createElement('style');

// styleタグに記載するcssを記入
styleTag.innerText = `
    p {
       color:red;
    }
`;

// 作成したstyleタグを挿入
document.getElementsByTagName('head')[0].insertAdjacentElement('beforeend', styleTag);
```
I tried to paste

Windows の GUI emacs で Python のコードをとりあえず見るための設定。

elpy introduction © Copyright 2014, Jorgen Schäfer Revision 4032c725.
https://elpy.readthedocs.io/en/latest/introduction.html

```lisp
;; .emacs.d/init.el

;; ===================================
;; MELPA Package Support
;; ===================================
;; Enables basic packaging support
(require 'package)

;; Adds the Melpa archive to the list of available repositories
(add-to-list 'package-archives
             '("melpa" . "http://melpa.org/packages/") t)

;; Initializes the package infrastructure
(package-initialize)

;; If there are no archived package contents, refresh them
(when (not package-archive-contents)
  (package-refresh-contents))

;; Installs packages
;;
;; myPackages contains a list of package names
(defvar myPackages
  '(better-defaults                 ;; Set up some better Emacs defaults
    elpy                            ;; Emacs Lisp Python Environment
    flycheck                        ;; On the fly syntax checking
    material-theme                  ;; Theme
    )
  )

;; Scans the list in myPackages
;; If the package listed is not already installed, install it
(mapc #'(lambda (package)
          (unless (package-installed-p package)
            (package-install package)))
      myPackages)

;; ===================================
;; Basic Customization
;; ===================================

(setq inhibit-startup-message t)    ;; Hide the startup message
(load-theme 'material t)            ;; Load material theme
(global-linum-mode t)               ;; Enable line numbers globally

;; ====================================
;; Development Setup
;; ====================================
;; Enable elpy
(elpy-enable)

;; Enable Flycheck
(when (require 'flycheck nil t)
  (setq elpy-modules (delq 'elpy-module-flymake elpy-modules))
  (add-hook 'elpy-mode-hook 'flycheck-mode))

;; User-Defined init.el ends here
```

https://youtu.be/DnPzQtIxQGg

コンパイルもできた。


Cf.
（ちょっと）貼ってみる
https://qiita.com/dauuricus/private/

Cf.
vim case （ vim の場合）
I paste this
https://qiita.com/dauuricus/private/63510e76b8af5b91f498
素のECMAScriptだけで組める関数テスト

当記事では、素のECMAScriptだけで組める関数テスト用のES Modulesを書き残しています。





## 1. ソースコード

使い方は以下の通りです。

```javascript
import {
  testFunction
} from "./original-test-tool.mjs";

// サンプル用の関数です。
const f = (a, b) => {
  return a + b;
};

// 試験を定義・実行します。
testFunction("f() の第1回試験", f, [1, 2], 3);
testFunction("f() の第2回試験", f, [3, 4], 7);
testFunction("f() の第3回試験", f, [1, 1], 999999);
testFunction("f() の第4回試験", f, [1, 1], "2");
```

実行するとコンソールにテスト結果が出力されます。

```
✔ f() の第1回試験

✔ f() の第2回試験

❌ f() の第3回試験
  想定: {Number} 999999
  実際: {Number} 2

❌ f() の第4回試験
  想定: {String} 2
  実際: {Number} 2
```

以下、全文です。

```javascript:test.mjs
/**
 * 引数で受け取った値のデータ型を返す関数です。
 * @example
 *   // "Number"
 *   getType(1);
 * 
 *   // "String"
 *   getType("Hello world.");
 * 
 *   // "Array"
 *   getType([]);
 * @param {*} value 調べる対象となる値です。
 * @returns {String} データ型は文字列で返します。
 */
const getType = (value) => {
  return Object.prototype.toString.call(value).slice(8, -1);
};

/**
 * 関数をテストする関数です。
 * テスト結果に応じて、コンソールにメッセージを出力します。
 * @example
 *   const exampleFunction = (a, b) => {
 *     return a + b;
 *   };
 * 
 *   // ✔ exampleFunction() のテスト
 *   testFunction("exampleFunction() のテスト", exampleFunction, [1, 2], 3);
 * 
 *   // ❌ exampleFunction() のテスト
 *   // 想定: {Number} 5
 *   // 実際: {Number} 3
 *   testFunction("exampleFunction() のテスト", exampleFunction, [1, 2], 5);
 * @param {String} testName テスト名・テスト概要を表す文字列を指定してください。
 * @param {Function} testFunction テスト対象となる関数です。
 * @param {Array<*>} testArguments テスト対象となる関数に渡す引数です。
 * @param {*} correctTestReturnValue 想定される正しい戻り値です。undefinedは指定できません。 
 */
const testFunction = (testName, testFunction, testArguments, correctTestReturnValue) => {

  // 第1引数から第3引数までが正常であるか確認します。
  const parameterTypes = ["String", "Function", "Array"];
  const argumentTypes = [getType(testName), getType(testFunction), getType(testArguments)];
  for (let i = 0; i < argumentTypes.length; i += 1) {
    if (argumentTypes[i] !== parameterTypes[i]) {
      throw new TypeError(`第${i + 1}引数には ${parameterTypes[i]} を指定してください。実際には ${argumentTypes[i]} が指定されています。`);
    }
  }

  // 第4引数が正常であるか確認します。
  if (getType(correctTestReturnValue) === "Undefined") {
    throw new TypeError("第4引数が指定されていないか、あるいはundefinedが指定されています。第4引数に、明示的にundefinedを指定することは許可されません。");
  }

  // 関数をテストし、その結果をコンソールに出力します。
  const testReturnValue = testFunction(...testArguments);
  if (testReturnValue === correctTestReturnValue) {
    console.log(`✔ ${testName}`);
  } else {
    console.log(`❌ ${testName}\n  想定: {${getType(correctTestReturnValue)}} ${correctTestReturnValue}\n  実際: {${getType(testReturnValue)}} ${testReturnValue}`);
  }
};

/**
 * ECMAScript環境だけで完全に動作するテスト用の関数・オブジェクトをまとめたモジュールです。
 * @author AGadget
 */
export {
  testFunction
}
```





## 2. おわりに

凄まじく単純なので実用性は無いでしょうが、これくらいのクオリティのものならば意外と作れるものですね。
コマンドの自動補完ツールな「zsh-autosuggestions」

`コマンド 予測変換` とかで検索してもなかなかピンとくる物が出てこず、ウロウロしてる時に見つけた便利なコマンド補完ツールのご紹介。

https://github.com/zsh-users/zsh-autosuggestions

インストールの手順はまずbrew install

```
brew install zsh-autosuggestions
```

そのあとに `.zshrc` に以下を追記

```
source /usr/local/share/zsh-autosuggestions/zsh-autosuggestions.zsh
```

で読み込み直したらおわり。

簡単。

![スクリーンショット 2021-01-14 12.28.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538639/cb4d0708-d9a0-aec3-3032-389e317d9bf6.png)

こんな感じで、過去に使ったコマンドをサジェストしてくれる。

便利。
【Git】コミット履歴から特定のファイルのコミット情報を全て削除


自分用のメモとして残します。


#■やり方
事前に対象ブランチをチェックアウトする。
下記のコマンドで対象ファイルを削除

```shell
git filter-branch -f --index-filter 'git rm --ignore-unmatch ファイルパス' HEAD
```

#####このままではリモートと競合するため、リモート側の対象ブランチを削除

```shell
git push origin :ブランチ名
```
#####その後ローカルブランチをコミットする。

```shell
git push origin ブランチ名
```


以上。
git grep -l 'hoge' して取得した対象ファイルをvscodeで一気に開くワンライナー

## コマンドを叩く前に必要なこと

1. vscodeのダウンロード
2. `code` のインストール

### 1. vscodeのダウンロード

vscode持ってない人はダウンロード(そもそもvscodeユーザー向けの内容だけど一応)

https://azure.microsoft.com/ja-jp/products/visual-studio-code/

### 2. `code` のインストール

この記事が参考になりそう。
便利なので入れましょう。

https://qiita.com/1natsu172/items/b951aa33451dad36bd7c

## コマンド

以下をCLIで叩く

```.sh
git grep -l 'hoge' | xargs -I % code %
```

自分はgrep結果をさらにgrepしたりしたかったので

```.sh
git grep -l 'hoge' | grep 'hoge' | xargs -I % code %
```

のようにして開いた。超便利。
これからアンドロイドプログラミングを始める方へ

AndroidStudio4.1からAndroid Kotlin Extensions Gradle プラグインが使えなくなったようです。
　　＜参考＞[Kotlin Android Extensions の未来](https://developers-jp.googleblog.com/2020/11/the-future-of-kotlin-android-extensions.html)

端的にいうと、次のようなtextView.textやfindViewById<>().textを使うコードが使えなくなります。

```kotlin.kt
radioGroup1.setOnCheckedChangeListener { group, checkedId ->
            if (group == radioGroup1) {
                textView.text = findViewById<RadioButton>(checkedId).text
            }
        }
```

　この問題は、これからアンドロイドプログラミングを勉強し始める方にとっては、大きな問題でしょう。この記事はそういった方へのアドバイスです。
　もしあなたがアンドロイドプログラミングを始めるに際し教科書を探しているなら、2021年1月14日現在でのお勧めは、金田著「[はじめてのAndroidプログラミング　“第５版”](https://www.sbcr.jp/product/4815607968/)です。
　本書は、ViewBindingの問題を解決していますし、ViewBinding上でのradioButtonの使い方も記述されています。2021年1月14日現在、ネット上にはViewBinding上でのradioButtonの使い方の解説は見つかりませんでした。
　また本書第４版でそのまま写経した際に発生していた「‘PrefernceManager’ is deprecated(非推奨）」についても改善され、AndroidX化されていますので、安心して勉強できます。詳しくは、[AndroidXライブラリの使い方](https://teratail.com/questions/292704)を参照してください。
　現在、販売されているその他の入門教科書で勉強しやすいものはいくつかありますが、それらの本を使って勉強し始めて、viewBindingに関することで不信感を覚える前に、まずこの本(第５版)で勉強を始め、第４版と比較し、コードの違いを勉強した上で、他の入門書に移ることをお勧めします。

　私個人的には、「基礎＆応用力をしっかり育成！Androidアプリ開発の教科書 Kotlin対応 なんちゃって開発者にならないための実践ハンズオン (CodeZine BOOKS)」や「はじめてのAndroidアプリ開発 第３版 AndroidStudio3対応(Java版)」が好きなので、早くViewBingdingに対応することを希望します。
【Rails6】deviseによる新規登録・ログイン時のリダイレクト先変更

#はじめに

ポートフォリオ作成中に詰まった点を備忘録として記述しています。
今回は、deviseにてユーザー新規登録・ログイン機能を実装しました。法人会員と個人会員の2種類のログインユーザーがおり、新規登録時及びログイン時には、法人or個人によって違う画面遷移にしたいと思い、リダイレクト先の変更を試みました。

deviseではデフォルトでリダイレクト先が指定されているため、deviseのコントローラーをカスタマイズする必要がありました。

#環境

Ruby on Rails'6.0.0'
Ruby'2.6.5'

#前提

deviseを使用し、ログイン機能を実装済み。

#①controllerの作成

```:ターミナル
% rails g devise:controllers companies
```

上記コマンドにより、法人側deviseのcontrollerを編集することができます。app/controllers/companies側にファイルが生成されると思います。

#②ルーティングの設定

rails routesでルーティングを確認すると、

```:ターミナル
new_company_session GET      /companies/sign_in(.:format)             devise/sessions#new
company_session POST   　　  /companies/sign_in(.:format)    　       devise/sessions#create
（省略）
new_company_registration GET      /companies/sign_up(.:format)        devise/registrations#new
```

上記のように表示されます。devise/sessionsやdevise/registrationでは、反映されないため、ルーティングでカスタマイズを行います。

```:config/routes.rb
devise_for :companies, controllers: {
    sessions:      'companies/sessions',
    registrations: 'companies/registrations'
  }
```

カスタマイズを行い、再度rails routesを行うと下記のように表記が変わると思います。

```:ターミナル
new_company_session GET      /companies/sign_in(.:format)             companies/sessions#new
company_session POST   　　  /companies/sign_in(.:format)    　       companies/sessions#create
（省略）
new_company_registration GET      /companies/sign_up(.:format)        companies/registrations#new
```

#③controllerの編集

ここから、リダイレクト先を指定するメソッドを定義します。

```ruby:app/controllers/companies/registrations_controller.rb
class Companies::RegistrationsController < Devise::RegistrationsController
  before_action :configure_sign_up_params, only: [:create]
  before_action :configure_account_update_params, only: [:update]

  def after_sign_up_path_for(_resource)
    companies_articles_path(リダイレクト先のpath)
  end
(省略)
end
```

```ruby:app/controllers/companies/sessions_controller.rb
class Companies::SessionsController < Devise::SessionsController
  before_action :configure_sign_in_params, only: [:create]

  def after_sign_in_path_for(_resource)
    companies_articles_path(リダイレクト先のpath)
  end
（省略）
end
```

上記でリダイレクト先を指定することができました！！！！
wslでgh auth loginできない時の対処

wslからgh auth login したときにうまくいかない時の対処。
以下のようメッセージが出て認証したいのにブラウザが立ち上がらない時がある。

```
 # gh auth login                                                                                                                          [11:24:22]
? What account do you want to log into? GitHub.com
- Logging into github.com
? How would you like to authenticate? Login with a web browser

! First copy your one-time code: 637D-7161
- Press Enter to open github.com in your browser...
failed to authenticate via web browser: exec: "/mnt/c/Program": stat /mnt/c/Program: no such file or directory
```
$BROWSER中身を確認すると以下。

```
 # echo $BROWSER                                                                                                                          
/mnt/c/Program Files/Google/Chrome/Application/chrome.exe
```

"Program Files"に含まれる空白のせいでパスをうまく読み取れない問題とわかるので、$BROWSERを引用符付きに変更してあげる。
私の場合は.zshrcで以下のように変更。

```
export BROWSER='"/mnt/c/Program Files/Google/Chrome/Application/chrome.exe"'
```

再度authを試すと無事ブラウザが立ち上がり認証を通すことができました。
Adobe After EffectsとPremiereProのDynamic Linkが失敗する時の対処法

## 1. After EffectsとPremiereのバージョンが違う

- After Effects 2019
- Premiere Pro 2020

という状態では失敗というか接続がそもそもできませんでした。
バージョンを合わせましょう。

## 2.バージョンアップ直後

AdobeCC上でソフトのアップデートをして、「1.」のAfter Effectsのバージョンを2019から2020にアップデートしました。

After EffectsからPremiereへの接続は出来たのですが**PremiereはAfter Effectsを認識できていない**ようで失敗しました。

## 3.アプリケーションの再起動

After Effects、Premiere共に再起動。これも試しましょう。


## 4.PCの再起動

**「3.アプリケーションの再起動」**でも失敗する場合はPCを再起動しましょう。

本当これで直るんですよね。

## 5. 問い合わせる

Adobeに問い合わせましょう。


ちなみに今回は**「4.PCの再起動」**で僕の環境は復旧しました。
Adobe Dynamic Linkは超便利なので使っていきたい機能です。

なにか1つトラブルの解決につながればと思います。


以上です。

## 環境

- After Effects 2019
- Premiere Pro 2020
- macOS Catalina 10.15.7
Jetson Nanoの初期セットアップ

会社の仕事では、Jetson Nano開発者キット(4GB版)を使用しているが、今回、自分で、2GB版を購入してみましたので、まず、手始めに、そのセットアップについて記事を書いてみました。

## 最新のJetson Nano開発者キット用のSDカードイメージをダウンロード

https://developer.nvidia.com/embedded/learn/get-started-jetson-nano-devkit#write
https://developer.nvidia.com/jetson-nano-sd-card-image

jetson-nano-4gb-jp441-sd-card-image.zip
がダウンロードされる。

## SD Card FormatterでSDカードをフォーマットする
クイックフォーマット
ボリュームラベルは空白で

昔は、Windows標準のフォーマット機能では駄目だったが、今でもそうなのか？

## Balena EtcherでSDカードイメージを書き込む

Etcherは
balenaEtcher-Portable-1.5.113.exe
をダウンロードして使用した

結構、ちょこちょこバージョンアップされているみたいなので、Portable版がお手軽な感じがする。

Etcherを起動して、
jetson-nano-4gb-jp441-sd-card-image.zip
を選択すると、
sd-blob-b01.img
が見える。

## Jetson Nanoを起動してセットアップ

普通に、起動してセットアップしてみた。
問題なく動作していると思われる。

## 予告

ひとまず、初期セットアップについて書いたが、この後、カーネルのビルド環境構築やDevice Tree更新などについても記事にする予定。
Fedora33でMS互換のL2TP/IpsecのVPNクライアントを構築

Fedora33をインストール後
testなのでrootに昇格させておく
<pre>
sudo passwd root
su

yum install -y xl2tpd NetworkManager-l2tp NetworkManager-l2tp-gnome
</pre>

Fedora33にはipsecにlibreswanが使われているようで、脆弱なアルゴリズムは排除されてしまっている。
MS互換のL2TP/IPsecでは排除されたアルゴリズムが使われているようなのでstrongswanに変更する。

<pre>
yum remove libreswan
yum install -y strongswan
</pre>

参考情報
6つのVPN
https://opensource.com/article/18/8/open-source-tools-vpn
https://www.tecmint.com/setup-l2tp-ipsec-vpn-client-in-linux/

MS AzureのL2TP設定
https://network.yamaha.com/setting/router_firewall/cloud/microsoft_azure/setup_rt

Fedora & Algorithm
https://ask.fedoraproject.org/t/cannot-connect-to-vpn/5602/42
ゼロトラスト / MDR = EPP+EDR+SOCの設計例

**「ゼロトラストはクラウドサービス（SaaS）の導入なので設計は簡単だ！」と考えている方もいると思います。
しかし、クラウドだからこそ設計で
■導入して何をしたいか？を明確にすること！
■その為に複数のクラウドをどのように組み合わせるか！
を行い、「それに合ったクラウドサービスを選択することが大切」です。
これを怠ると、後で「えっ、できると思っていたのができないの！？」といった事がおきます。
ここではそれを防ぐための設計例を説明します。**

**（関連知識）**
**ゼロトラストとは**
“米国国立標準技術研究所（NIST）の定義とその意訳**
https://qiita.com/masaaki-murakami/items/6a7f56079aa95f44119d
**ゼロトラストの基礎知識**
“セキュリティ”の為にみんなが今までやってきた事と、これからすべきことの基礎知識**
https://qiita.com/masaaki-murakami/items/28a737c373138f3773ea
**ゼロトラスト / IdaaS + CASB の設計例**
ゼロトラスト　/　“内部の情報漏洩”対策　>>> IdaaS ＋ CASB
https://qiita.com/masaaki-murakami/items/87d9bdc3fc0deb01ffcd
##“外部からの攻撃（身代金、搾取等）”対策【 PC・スマホ 】>>>「MDR = EPP + EDR + SOC」
####１．境界防御からゼロトラストにするとできる事
今回は❷について紹介します。
（MDRは概念的には”ゼロトラスト”とは異なりますが、一般的には❶❷をあわせてゼロトラストという場合が多いので、ここでは❷もゼロトラストに含めて説明します）

❶内部情報漏洩を防ぐ
❷外部からの攻撃から守る

殆どの人がアンチウィルスソフトをPC、スマホにインストールしているので自分は安全と考えていると思います。
しかし、実際にはアンチウィルスソフトが効かないファイルレス攻撃が毎年増え続け、今では攻撃の半数を超えています。これらの攻撃からPC、スマホを守るのがEDRです。
ではEDRを導入すればアンチウィルスはいらないのでしょうか？いえ、従来のアンチウィルス（＝EPP）も必要です。
新型コロナの感染対策を考えてみましょう。感染対策は
**“水際対策”＋“疑われる病状の人の検査”＋“感染者の隔離”＋“治療”**
を行っています。これはPC・スマホへの外部からの攻撃対策も同じで、EPP＋EDR＋SOCを組み合わせて導入する事が必要となります。

多少の誤解を生む説明になるかもしれませんが、分かり易く説明をすると、
**従来のEPPは、病原体であるウイルスの感染を検知して、そのウィルスを駆除する方式**で、**EDRは、発病後の症状から感染を検知する方法**をとっています。
発病後の対策なので”隔離をする”＋”駆除をする”必要があり、また重症になる前に対策をする必要があるため検知後の”隔離”＋”駆除”のスピードが大切です。
####２．機能設計
非常に厄介な事に、従来のアンチウィルスで検知できないファイルレス攻撃が増え続けており、**2019年には外部からの攻撃の半分以上がファイルレス攻撃（米国に限ってみると2019年の7割以上がファイルレス攻撃）**となっており、従来のアンチウィルスが殆ど効果がない状況になりつつあります。

何でファイルレス攻撃では検知できないのでしょうか？
**ファイルレス攻撃ではPowerShell等のWindows OSの標準機能を悪用して攻撃**をします。
Power ShellはWindows OSに標準搭載されている機能で、Windowsのほぼ全ての機能を実行することができます。Windowsを起動するとに複数のPowerShellが動作していることも少なくなく、かつその動作は「プロセス」としてメモリ上で実行されるため電源を切れば消えてしまい痕跡も残りません。
そのため、EDRでは発病後の症状から感染を検知する方法をとっています。
症状から感染を検知するため、新しい攻撃に対しても検知できるメリットがあります。
しかしあくまでも発病を検知する方法であるため、従来の感染段階で自動的に駆除をするEPPも必要となるのです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585213/4979bbc9-d40c-c575-5f1a-e5f4c5d55393.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585213/0f899aca-7574-8455-cbb1-60174786e3d0.png)
WindowsでPythonの仮想開発環境を作る

#はじめに

pythonをWindowsで使いたいな～と思って色々調べていたんですが、環境構築のところで右往左往してしまったので、備忘録としてアウトプットしておきます。VScodeでコードを書きます。

##環境
・Windows 10 Home
・Visual Studio Code

前提として、python自体がWindowsにインストールされていることを確認してください。
インストールは[こちら](https://www.python.jp/install/windows/index.html)からできます。python japanの公式ページです。

#コマンドを打っていく
Windowsの場合は、powershellを管理者として開いて、

```
Set-ExecutionPolicy RemoteSigned
```
というコマンドを打ちます。これはスクリプトの実行をローカルファイルのみ許可するというものです。他にもオプションがありますので、気になった方は[こちら](https://cheshire-wara.com/powershell/ps-cmdlets/sequrity/set-executionpolicy/)を参考にしてみてください。

その後、VScodeのターミナルで、作業をしたいディレクトリを作成し、移動します。

```
$ mkdir test
$ cd test
```

testディレクトリ直下に仮想環境を作ります。実際、詰まってしまったのはここだけなのですが、私の環境では以下の通りコマンドを打ったら素直に仮想環境に入ってくれました。

```
$ py -m venv myenv
$ myenv/Scripts/Activate.ps1
```

「myenv」は任意の文字列に変更してください。

サイトによっては、pyがpythonだったりpython3だったり、とにかくたくさんコマンドが並んでいて、打っても動かなかったり怒られたりして困っていました。

じゃあなんでpyコマンドなら動くのかと、python japanのページを眺めていたら、こんな記述がありました。

>Windows版のPythonでは、python コマンドを使うより、Pythonランチャー py がおすすめです。通常、Python をコマンドラインから実行するときには、Pythonをインストールしたディレクトリを環境変数というシステム設定に記録する必要がありますが、py は、設定をしなくとも実行できます。

pythonコマンドを使いたかったらそれぞれの環境でパスを通してくださいね、ただしpyコマンドならデフォルトで使えますよって認識で良いのかな？

とにかく上記のように入力すると、ターミナルの左側に(myenv)と表示されるはずです。これで仮想環境に入ることができました。

ちなみに仮想環境から抜けるためのコマンドは、

```
$ deactivate
```
です。


続けてVScode側の設定をする必要がありますが、既に記事にしてくださっている方がいらっしゃいましたので、[こちら](https://qiita.com/soh506/items/12a5df2d19f1c2c792fe)を参考に設定を行ってみてください。Djangoを仮想環境で動かすという内容ですが、その他フレームワークの場合でも同様の設定をすれば大丈夫だと思います。
AWS概要　ネットワーキングについて

#概要
もはや何番煎じているか分かりません。
1月から個人的に始めている未経験AWSチャレンジの一環として、CP試験に向けての個人的なメモとして記述します。

※は書き方を模索中ですが、問題を通して思った感想になります


#ネットワーキング

##Amazon　CloudFront（CDN＝コンテンツ・デリバリー・ネットワーク）
CDN＝サーバーの代わりに表示やら・負担分散してくれるサーバーたち
・ディストリビューションという単位で管理される
・オリジンサーバー　＝オリジナルコンテンツサーバー
・エッジサーバー　　＝コンテンツをキャッシュして、ユーザーへ直接配信サーバー
※ディストリビューションには独自のドメインを設定できる

##AmazonRoute53
DNS（Domain　Name　System）＝ドメインの取得ができる
Route53にもヘルスチェック機能があり、EC2に不可が検知されるとS3のソーリページに
ルーティングさせるなどの、名称通りのRouteの設定も出来ます。
 
※SSL証明書「https://」のユーザーとWebアプリ間の暗号化
1　AWS Certificate Manager(ACM)で証明書の作成
2　ELB（ロードバランサー：インターネットGWからアクセスを割り振る仕組み）に証明書を設定
3　Route53でDNSして、晴れて自分のWebアプリ感が出てくる
  
※AWSでサービスを作る場合は、公式にDNSはRoute53を使用する事とあるので、
   お仕事などでAWSに触れるならば、必ず出てくるであろう仕組みですね
ドキュメント変換ツールとしてpandocを使ってみる

# きっかけ
markdownでの作文、ドキュメント管理を今後推奨していくにあたり、既存の文書データ（pdfとかword文書など）をmarkdownに変換できるツールないかなって探してるところでpandocに行き当たったので使ってみる。今回はあくまでお試し。


# pandocについて

pandoc日本語ユーザーガイドはこちら
http://sky-y.github.io/site-pandoc-jp/users-guide/

以下引用

<details><summary>対応している入力形式は以下の通りです：</summary>
markdown
Textile （のサブセット、以下同様）
reStructuredText
HTML
LaTeX
MediaWiki markup
Haddock markup
OPML
Emacs Org-mode
DocBook</details>

<details><summary>出力形式は以下の通りです：</summary>
プレーンテキスト
markdown
reStructuredText
XHTML
HTML 5
LaTeX （beamerスライドショーを含む）
ConTeXt
RTF
OPML
DocBook
OpenDocument
ODT
Word docx
GNU Texinfo
MediaWiki markup
EPUB (v2またはv3)
FictionBook2
Textile
groff manページ
Emacs Org-Mode
AsciiDoc
InDesign ICML
HTMLスライドショー：Slidy、Slideous、DZSlides、reveal.js、S5
PDF出力（LaTeXがインストールされているシステムで使用できます）</details>



# pandocの入手方法
以下のURLから入手することができるそうです。
https://pandoc.org/installing.html
私はbrewでインストールすることができました。以下コマンド。

```
$ brew install pandoc
```

# pandocの使い方
* ターミナルで目的のファイルのディレクトリに移る。
* マニュアルに従って入力、出力の形式やファイル名を指定。必要があればオプションを添える。

例…docxファイルのtest.docxをMarkdownに変換する場合：

```
$ pandoc -f docx -t markdown test.docx
```

markdown形式の出力がターミナル上で出力されます。

# 所感
今回お試しでやってみて、あまりちゃんとはリサーチしてないのですが、以下２点つまづきポイントが。

+ pdf→markdown変換について:
pdf形式の文書をmarkdownに変換できるかなと期待してたのですが、直接は無理でした。
仕方ないので、word文書に一回置き換えてからやってみたらいけました。

+ markdownファイルへの出力について:
任意のファイルとしてmarkdownファイル（.md）への出力はトライしてみましたが、以下のエラーを吐いてしまいそこから先が未解決です。。
```couldn't unpack docx container: not enough bytes```

## 参考
『pandocでmarkdown形式ファイルからwordドキュメント(*.docx)を作成する』
https://dev.classmethod.jp/articles/pandoc_markdown_to_docx/#toc-6
WAF SITEGUARDでTracの場所を無効にする

# WAF SITEGUARDでTracの場所を無効にする

さくらのクラウドだとSITEGUARDというWAFを無料で使うことができます。
WAFがあるとセキュリティー的に安心度が増しますよね。
しかしTracのサイトにSITEGUARDを有効にすると、
Wikiの編集などができなくなってしまって不便です。
TracはIP接続元制限でセキュリティーを確保することにして、
Tracのある場所だけSITEGUARDを無効にしたい。
この設定方法です。

Apacheの設定ファイルにSiteGuard offを追加する。だと、うまくいかなかった。のでカスタム・シグネチャを使う方法です。


## カスタム・シグネチャに除外するURLを追加方法
![st1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6384/ebe7d678-e222-bdd3-2b98-d6c8c137f363.png)





![st2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6384/fa5845da-4b97-abe4-fea7-a0505cad063e.png)
![st3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6384/3daf6a59-e3d3-bb96-68ce-c92ef11b72d0.png)
![st4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6384/72fa774d-e7db-c3b8-ecd3-009b530a8008.png)
![st5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6384/1eb4a3a1-f093-da46-a963-a318fd2688d5.png)
Xojo 2019 → 2020  Webアプリの相違点   

比較対象

- Xojo 2019 r3.2
- Xojo 2020 r2.1


 Webアプリの作成においては、Xojo内部のフレームワークとして Web1.0 から Web2.0 に変化し、UI などに 2019→2020で大きな不連続がある。

書き換えについては以下にまとまっている。
「Converting Web Projects to Web Framework 2.0 Xojo Blog」
https://blog.xojo.com/2020/08/27/converting-web-projects-to-web-framework-2-0/

# 調べ方
旧メソッドなどが何に変わったかなと調べようとしても、旧のヘルプがオンラインから無くなっている。旧バージョンの Xojo IDE からのヘルプもオンラインを参照しているので詰む。
以下のように直打ちして調べる。例えばWebListBox.Cell を調べようとするときに、WebListBox.Cell という方法では調べられないので代わりに ListBox.Cell で調べる。
http://docs.xojo.com/index.php/ListBox.Cell

(2023/04/25追記：archive.org で昔のドキュメントが参照できました)
https://web.archive.org/web/20191231154651/https://docs.xojo.com/


# コントロール

廃止して代替

- msgbox → messagebox
- WebListBox.DeleteAllRows → WebListBox.RemoveAllRows
- WebListBox.ListIndex → WebListBox.SelectedRowIndex
- WebListBox.Cell → WebListBox.CellValueAt


# イベントハンドラ

かなりの削除と変更が行われている。従来はデスクトップアプリとほぼ同様のものが利用できたが、Web2.0となりWebアプリは別個のものという位置づけとなったと考えるのが良さそうだ。

## App
2019 r3.2

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/740e06d0-cb06-76e9-ccd1-bb9570da20ca.png)
2020 r2.1

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/b3eac4ac-571d-c2d5-c00b-1fc1632652d9.png)

## WebPage
2019 r3.2

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a35e6dd3-b96f-ffce-38e2-85f9cc288c1e.png)

2020 r2.1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a4059193-35bf-4918-4a35-a141f6affc40.png)

## WebTextField 

2019 r3.2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a5e3caa8-a760-d60e-1bf7-c7b0f1a29a6e.png)
2020 r2.1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c2ab5039-a15b-e9f6-7b2b-f9357980ef57.png)

# WebTimer

## Modeプロパティ -> RunModeプロパティ
 Timer1.Mode = 1 でタイマーが発動していたが、 Timer1.RunMode =  WeTimer.RunModes.Single
とする。

## Name

Xojo r3.2 以前で作成した WebTimer コントロールを Xojo 2020 r2.1 でビルドしようとするとエラー。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/6679b5b1-c447-ef33-a073-9478034479f2.png)

この場合、Timer1オブジェクトを削除して作成し直す


# KeyPressed

> idField on WebPage1 implements the event "KeyPressed," but its superclass WebTextField has already implemented the event.

と出る。

idField は WebTextField。これに KeyPressed イベントとして

```

Select Case details.KeyCode
Case details.KeyEnter
  furiganaField.text=zenhankanafix(furiganaField.text)
  取得個人()
End Select
```

となっていたのを

TextChanged
イベントに

```

  furiganaField.text=zenhankanafix(furiganaField.text)
  取得個人()
```
と書いた
# Run

MS-Windows 10 + Chrome の組み合わせだと、IDE からの実行で  http://127.0.0.1:8080/ となるはずが %22http//127.0.0.1:8080/" で呼び出され、イラッとくるバグが直っている。

# Webアプリ以外の変更点

## Timer

TimerはWebアプリではサーバで動作する。クライアントで動作させるにはWebTimerを使うことができる。



Timer.Mode → Timer.RunMode

Timer.Mode=Timer.ModeOff → Timer.RunMode=WebTimer.RunModes.Off
Timer.Mode=Timer.ModeSingle → Timer.RunMode=WebTimer.RunModes.Single
Timer.Mode=Timer.Multiple → Timer.RunMode=WebTimer.RunModes.Multiple

Timer.ModeOff の代わりに整数値 0,
Timer.ModeSingle の代わりに整数値 1,
 が使えたが、
WebTimer.RunModes の値として整数値は使えない。
【TypeScript + React Hooks】useReducerでactionの型定義をtypeの値によって変更する

# はじめに  
TypeScript + React HooksのuseReducerで、オブジェクトの配列のstateを作成したとき、
dispatch関数がtypeの値に応じて必要な引数だけを要求するようにしたくなった

つまり、reducerの引数であるactionが、
typeの値に対応したpayloadを持つように型定義したい

# 方法
型定義において、typeを`type: string;`ではなく具体値で定義する  

```typescript
interface AddAction {
  type: 'add',
  payload: {
    id: number;
    a: number;
    b: string;
  }
}
```

```typescript
interface RemoveAction {
  type: 'remove',
  payload: {
    id: number;
  }
}
```

定義したそれぞれの型を `|` でつなぐ

```typescript
const reducer = (
  state: Array<MyDataType>,
  action: AddAction | RemoveAction,
) => {
  if (action.type === 'add') {
    // addの処理
  } else if (action.type === 'remove') {
    // removeの処理
  }
}
```


# 実装例

- オブジェクトの配列であるstateについての実装例
- `users`：ユーザ情報（id, name, age）を管理するオブジェクトの配列のstate
- 新たにユーザ情報を追加する`add`と、idをもとにageを更新する`updateAge`を実装

```typescript:sample.tsx
import React, { useReducer } from 'react';

interface User {
  id: number;
  name: string;
  age: number;
  gender: string;
}

interface AddAction {
  type: 'add';
  payload: User;
}

interface UpdateAgeAction {
  type: 'updateAge';
  payload: {
    id: number;
    age: number;
  };
}

export const reducer = (
  state: Array<User>, 
  action: AddAction | UpdateAgeAction
): Array<User> => {
  if (action.type === 'add') {
    // addの処理
  } else if (action.type === 'updateAge') {
    // ageの更新処理
  }
}


const MyComponent: React.FC = () => {
  const [users, usersDispatch] = useReducer(reducer, []);

  const addUser = (newUser: User) => {
    usersDispatch({
      type: 'add',
      payload: newUser,
    }
  }
  const updateAge = (userId: number, newAge: number) => {
    usersDispatch({
      type: 'updateAge',
      payload: {
        id: userId,
        age: newAge,
      }
    }
  }
  // 以下省略
}
```
PHP学習まとめ２~データ型、条件分岐、繰り返し処理~

##データの型
データは主に以下のような型がある。

- 文字列：string
- 数値：int
- 浮動小数：float
- NULL：null
- 真偽値：true/false
- 配列：array

var_dump(変数)で変数の型を表示することができる。
変数 = (型)'~~'　で型を指定(変換)して代入もできる。

```php:例
$name = (string)'mizuno';
// $nameという変数に'mizuno'という文字列をstring型で代入
```
　
##条件分岐
####if、switch、for、while文
ifやswitch、for、whileはブロックの形で表記。
※最後にセミコロン;は要らないので注意⚠️

```php:例
if ($number === 1 || $number === 2) {
  echo 'number は 1 または 2 です。' . PHP_EOL;
} else {
  echo 'number は 1 でも 2 でもありません。' . PHP_EOL;
}

switch ($number) {
  case 1: //比較する値と:(コロン)を書く
  case 2:
    echo 'number は 1 または 2 です。' . PHP_EOL;
    break;
  default:
    echo 'number は 1 でも 2 でもありません。' . PHP_EOL;
}
```
ifとswitchの違い
ifはAじゃなかったらB、BでもなかったらC、のように順番に処理。
条件式に不等号も使える。
switchはifでいう条件式が、number === 1だったらコレとか、number === 2だったらコレと
断定できる条件が複数ある場合に、ちょうどスイッチの切り替えのように使用する条件分岐。
（Rubyでいうif case whenみたいな使い方か？）
またswitchの場合、caseとマッチした時に実行されるのは
「switchの終わり、または最初にbreak;が出てくるまで」処理が実行される。

##繰り返し処理
単純な繰り返し処理にはfor文

```php:
for($i=1; $i<=10; $i++) {
  // 〜処理内容〜を$iが10以下になるまで繰り返す
}
```
　
繰り返し処理回数を可変的にするならwhile文を使う。
while文は条件を満たしている間は繰り返す為、無限ループにならないよう終了条件の書き方に注意⚠️

```php:
$i = 10
while ($i > 0) {
  // 〜処理〜
  $i -= 1
}
```

　
条件が最初から満たしていない場合（例：$i = 0など）処理が実行されないので、
とりあえず１回は処理を行い、条件次第で実行する場合は以下のような書き方もできる。

```php:
do {
  // 〜処理〜
  $i -= 1
} while ($i > 0);  // ※最後にセミコロンを使う
```

＜ループ処理中にスキップ、停止する方法＞
スキップ：continue;
停止：break;
【Mono Depth】3D ICP Loss

<h1>Unsupervised Learning of Depth and Ego-Motion from Monocular Video Using 3D Geometric Constraints</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/2cb10b52-3db7-60e0-a690-5db9c6546327.png)


今までのLossに加えて3D ICP Lossを導入


<h1>新規性</h1>
<h2>3D ICP Loss</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/4b44702b-af92-de9c-49c2-4796c1329e8b.png)
推定したDepth Mapを3D Point Cloudに変換し、Pose Estimationで推定したTransfomation Matrixを掛ければ、前のPoint Cloudまたは、次のframeのPoint Cloudを推定できる。

ICPを使ってPoint MatchingをさせてLossを計算する。



<h1>結果</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/109cdf45-3c9b-9f2f-d94b-a7986db44300.png)
3D ICP Lossを使った方が精度が良くなっている。

<h1>結論</h1>
3D ICP Lossはかなり精度を上げるのに良さそう
ただICPのMatchingに少し時間がかかりそう

<h1>参考文献</h1>

https://arxiv.org/pdf/1802.05522.pdf
タグを付けてプッシュする

#タグ？
タグを付けてプッシュしないといけない場面がありました。

普段はソースツリーを使っているのですがやり方を調べてもよくわからず…

ということでコマンドを教わりました

タグをつける

```
git tag HogehogeTag
```

その後プッシュ

```
git push origin HogehogeTag
```


これでできました。

ソースツリーだとどうやるんだろう…
【Mono Depth】GeoNet : 動いている物体のOptical Flowも推定

<h1>GeoNet: Unsupervised Learning of Dense Depth, Optical Flow and Camera Pose</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/5e443ef0-9c2d-bfa9-2216-54b6e5078049.png)

今までの推定していたRigid Flow(動かない物体のFlow)に加えて動く物体のFlowも考慮したres flowを推定する事で、最終的な画像全体のFlowを推定する事を提案した。
ついでに、forward(t->t+1) , backward(t+1->t)で両方向から推定することでOptical FlowのConsitency Check Lossを導入した。

<h1>アルゴリズム</h1>
<h2>Rigid Flowとは？</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/09f02055-d1cd-9576-f55f-f5becf70a5ab.png)
Rigid FlowはTagetと推定したSouceの対応するpixelの移動量(x,y)で定義されている。
物体が動いていないと仮定した時のFlowである。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/d9931412-9f34-a99a-09e8-75f75bec84cd.png)
当たり前だけど、Flowを使えばTarget画像からSource画像を推定できる。


<h2>ResFlowとは？</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/5edd00e3-2a5a-2db1-2670-2b806f35231e.png)

full flow = rigid flow + res flow
全体のFlow = 止まっていると仮定した時のFlow + 動いている物体の差分のFlow   


<h2>Rigid Warp LossとDepth Smoothness LossとFull Warp LossとOptical Flow Smoothness LossとForwar-Backward Consitency Loss</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/edb86633-a697-cbef-a685-ecf2691cfbab.png)
Rigid FlowをもちいたRigid Warp LossはSSIM(Sitructure Similarity)とSAD(Sum of Absolute Difference)を計算
する事で画像の類似を推定する。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/7fc85191-2ab3-4f79-e408-ac6db8298cdc.png)

Egdeを考慮したDepth Smoothness Loss

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/0b5c7c6c-c1ae-0536-7ec7-468edd3ef976.png)
Rigid FlowのLrigと同様にFull FlowのLfullも計算できる。
Depth Smoothと同じようにOptical Flow Smoothness Lfsも計算できる


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/99b3d6ae-b6cb-8949-d4c0-9400345a9633.png)

Forward-Backword Consistency Loss



<h1>結果</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/7cdca1f9-b72a-165e-2a1a-8b5c239cf188.png)
Rigid FlowよりFull Flowの方が精度がErrorが小さい事が分かる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/3e1d030b-7ac9-9cd0-5048-eef844f14022.png)
DispFlowNetSよりかなりErrorが小さい事わかる

<h1>結論</h1>
Full Flowを推定する事で精度が上がる

<h1>参考文献</h1>
GeoNet: Unsupervised Learning of Dense Depth, Optical Flow and Camera Pose
https://arxiv.org/pdf/1803.02276.pdf
An Object Context Integrated Network for Joint Learning of Depth and Optical Flow
https://www.semanticscholar.org/paper/An-Object-Context-Integrated-Network-for-Joint-of-Zhai-Xiang/dad2adf2774e575e4d33b5cb0d37f38ecbc159ae
Vim初心者用のよく使われる操作ショートキーを纏めてみました

Ruby On Railsの関連WEB動画講座コースを受ける際に、エディターをVimとして使用されるケースが多かったので、Vimの勉強を始めました。操作モードなどの理解を含めて、最初は覚えて慣れるまでは大変でしたが、実際に使ってみてコーディングしてみたら意外と便利でした。

ここでは、個人的に便利だなと思ってショートキーをメモとして、残させて頂きます。これぐらい覚えれば、一般的なにコーディング操作には十分かと思います。奥が非常に深いツールのため、今後は実業務を通じて、さらに理解を深めていきたいと思います。

■カーソル移動
gg：ファイル先頭へ
G：ファイル最終行へ
L：ウインドの一番下の行へ移動
0：行頭へ
$：行末へ
w：次の単語先頭へ進む
e：次の単語末へ進む
b：前の単語先頭へ後退
ge：前の単語の末尾へ後退
15G：行移動　　＃例：15は行番号

■カーソル挿入
i：カーソルの現在位置にインサートモード
a：カーソルの右側にインサートモード
I：行頭にインサートモード
A：行末にインサートモード
o：現在行に改行して、インサートモード
cc：現在行を削除して、インサートモード

■選択
v：文字選択モードへ
SHIFT+v：行選択モードへ
ctrl＋v：ブロック選択モードへ

■検索
/test：検索　#testはキーワード文字
n：次のヒットに移動
N：前のヒットに移動

■置換
:%s/end/END/g　##小文字endを大文字ENDで全置換する

■コピー操作
y：選択コピー
Y：行コピー
yy：行コピー
yiw：単語コピー

■行削除
・挿入モード時
CTRL＋u：行の先頭まで削除

・ノーマルモード時
dd：行をまるごと削除。カーソルが次の行へ移動
D:カーソルの位置から行末まで削除する。カーソルを一つ前へ移動
cc：行を削除してインサートモードに入る。カーソルを行の先頭へ移動
C：カーソルの位置から行末まで削除して、インサートモードに入り、カーソルを現在位置に留まる

■単語削除
D：カーソル位置から行末まで削除
C：カーソル位置から行末まで削除（その後、インサートモードに）
diw：カーソル位置の単語削除
x：１文字削除

■画面スクロール
CTRL+d：半画面進む
CTRL+u：半画面戻る
CTRL+f ：一画面進む
CTRL+b：一画面戻る

■全行選択
①GGで一番最初Sに戻す
②SHIFT＋Vで一行選択
③Gで文末まで全選択する

■その他
CTRL+r：アンドゥされた変更を元に戻す(redo)
u：操作を元に戻す(undo)
・：コマンドを繰り返す
Sourcetreeで認証エラー（認証ダイアログが出ない）の対処法


# backlogのgitからSourcetreeでCloneしたい

## 発生した問題
### Cloneできない。認証エラーになる
- Clone元のURLを入力しても、「リポジトリタイプ：ソースパス/ソースURLとして正しくありません」となる。
- その横の[詳細]を押すと「エラー: remote: Authorization required fatal: Authentication failed for ...」となっている。

### パスワードを間違えたら、認証ダイアログが出なくなってしまった
- もう一度正しいIDとパスワードを入力したいけど、認証画面が出ない
- どっかに間違えたユーザIDとパスワードが保存されてしまったのだろう


## 解決策
### 保存されてしまってる誤った認証情報を消す
- Sourcetreeのメニュー「ツール」＞ オプション ＞ 認証
- 「git保存されたパスワード」の当該URLをクリック ＞ 削除
map要素でループ処理！【SCSS】

#まずmapって何？
マップとはリストの各要素がkey&value（key1:value1）になったものです。
もう少し解像度を上げてご説明いたします。
``$map:(key1: value1,key2: value2,key3: value3);``
このようにしてmap変数を定義して**$mapの中にプロパティと値を格納**することができます。

#@ eachでループ処理
上記で簡単なmap変数の説明をしたわけですが、これらを応用してさらに使い勝手の良い物にできます。
それが**＠each文**になります。
例えば画像が上、下、右、左からスライドインする物を作る場合
＄patternという$map関数を作る。
上下左右のプロパティ値を’up’,’down’,’left’,’right’とする。
スライドインする処理をtransitionY(5px),transitionY(-5px),transitionX(5px),transitionX(-5px)とします。
そしてこれらを＠each文に入れるだけです。
`$pattern:("up":transitionY(5px),"down":transitionY(-5px)・・・);`
こちらで$map関数を定義します。
upというクラスがついた場合アクションが起きるという処理です。

`@each $key,$value in $pattern {.image.#{$key} {transform:$value;}`
これで$keyの値を変更するだけで処理を変更することができます。

いちいち１部分を変更したいだけでたくさんのコードを記述する処理が省けますよね。
WSL環境のRubyにて、selenium（Firefox）を利用する

# WSL環境のRubyにて、selenium（Firefox）を利用する

# 事前準備
## 必要なライブラリのインストール
## firefoxをインストール
```bash
sudo apt-get update
sudo apt-get install -y firefox
```

## firefoxのバージョンを確認
```bash
firefox --version
```

## geckodriverをインストール
https://github.com/mozilla/geckodriver/releases

```bash
wget https://github.com/mozilla/geckodriver/releases/download/v0.28.0/geckodriver-v0.28.0-linux64.tar.gz
tar zxvf geckodriver-v0.28.0-linux64.tar.gz
chmod +x geckodriver
sudo mv -f geckodriver /usr/local/share/geckodriver
sudo ln -s /usr/local/share/geckodriver /usr/local/bin/geckodriver
sudo ln -s /usr/local/share/geckodriver /usr/bin/geckodriver
```

# 動作確認

- パッケージの変更

```ruby:Gemfile 
source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem "webdriver"
gem "selenium-webdriver"
```

- パッケージの反映

```bash
bundle install
```

- Rubyのサンプルコード

```ruby:test.rb
require "selenium-webdriver"

opts = Selenium::WebDriver::Firefox::Options.new(args: ['--headless'])
driver = Selenium::WebDriver.for(:firefox, options: opts)

driver.navigate.to "https://google.com/"

puts driver.title

driver.quit
```

- 動作確認

```bash
ruby test.rb
```

# 参考
- Selenium WebDriverでRubyのテストを行う方法【初心者向け】
https://techacademy.jp/magazine/18704

- RubyとSeleniumでHeadless chromeを動かす on Ubuntu/Linux
https://qiita.com/meguroman/items/41ca17e7dc66d6c88c07

- 【完全版】PythonとSeleniumでブラウザを自動操作(クローリング／スクレイピング)するチートシート
https://tanuhack.com/selenium/
[Microsoft365]デスクトップ版Officeのライセンス認証が通らない

ちょっとハマった問題についてメモしておく
# 発生した問題
- ある日、会社でExcelを立ち上げたら、ライセンス認証が通らず `「ライセンスのない製品」` と表示されて使えなくなってしまった。
- 何度サインアウト→サインインしても状況は変わらず。
- ExcelだけでなくWord、PowerPointなどのOffice系が全滅。
- オンライン版は使用可能で、デスクトップ版のみ使えない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352434/f2f65357-1bf1-ac43-6602-2275d146b18d.png)

# 自分のサブスクリプション
- Microsoft365 Business Standard
    - デスクトップ版Officeが使えるやつ

# 試したこと
- サインアウト→サインインの繰り返し
    - 解決せず
- [アカウントの切り替え] から同じアカウントでサインインし直し
    - 解決せず
        - 参考：[Excel で 「現在アカウントにアクセスできません。この問題を解決するには、もう一度サインインしてください」 のアカウントエラーが表示される](https://answers.microsoft.com/ja-jp/msoffice/forum/msoffice_account-mso_windows8-mso_2013_release/excel-%E3%81%A7/cd2fd052-28ff-4fa7-a0c3-82eb58b46652, "Excel で 「現在アカウントにアクセスできません。この問題を解決するには、もう一度サインインしてください」 のアカウントエラーが表示される")
- Microsoft Support and Recovery Assistantを使用する
    - **解決！！**
        - 参考：[Microsoft 365: Microsoft サポート/回復アシスタント を使用する](https://support.microsoft.com/ja-jp/office/office-%E3%81%AE%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9%E3%81%AE%E3%81%AA%E3%81%84%E8%A3%BD%E5%93%81%E3%81%A8%E3%81%84%E3%81%86%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%A8%E3%82%A2%E3%82%AF%E3%83%86%E3%82%A3%E3%83%96%E5%8C%96%E3%81%AE%E3%82%A8%E3%83%A9%E3%83%BC-0d23d3c0-c19c-4b2f-9845-5344fedc4380#bkmk_sara, "Microsoft 365: Microsoft サポート/回復アシスタント を使用する")

# Microsoft Support and Recovery Assistantを使用して解決！
> Windows PC で Microsoft サポート/回復アシスタント を実行して、Microsoft 365 のライセンス認証の問題を特定したり修正したりできます。

以下のページを参考に、`Microsoft Support and Recovery Assistant`をインストールして、ツールの指示通りに操作を行い、解決することができた。
参考：[Microsoft 365: Microsoft サポート/回復アシスタント を使用する](https://support.microsoft.com/ja-jp/office/office-%E3%81%AE%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9%E3%81%AE%E3%81%AA%E3%81%84%E8%A3%BD%E5%93%81%E3%81%A8%E3%81%84%E3%81%86%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%A8%E3%82%A2%E3%82%AF%E3%83%86%E3%82%A3%E3%83%96%E5%8C%96%E3%81%AE%E3%82%A8%E3%83%A9%E3%83%BC-0d23d3c0-c19c-4b2f-9845-5344fedc4380#bkmk_sara, "Microsoft 365: Microsoft サポート/回復アシスタント を使用する")

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352434/eeb052a9-3f8a-d05c-c04c-61518e49e8fb.png)
↑やっと解決！

※ツールがサーバー側の資格情報をクリアしたタイミングで認証が通るようになったので、サーバー側の資格情報が原因だったのか・・・？

## インストールがブロックされる場合
私の場合はPCのセキュリティの問題でインストールがブロックされた。
> こちらの画面ですが、これはお客様のパソコンが、「インターネット上でダウンロードしたインストーラーでのインストールをブロックする」設定になっていると出てくる画面です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352434/c3cddaac-fb6c-db50-f9bb-3e8345eb30ce.png)

どうやらレジストリをイジればインストールできるらしい。
参考：[コンピューターにセキュリティ上の問題を発生させるため、管理者がこのアプリケーションをブロックしました。と出る場合の対処法](https://fx-ea-labo.com/regedit, "コンピューターにセキュリティ上の問題を発生させるため、管理者がこのアプリケーションをブロックしました。と出る場合の対処法")

# まとめ
とりあえず、Officeのライセンス認証で困ったら`Microsoft Support and Recovery Assistant`を使ってみよう！
Gradle - No Main Manifest Attribute

# Solved

**com.johnny.Main** is your program's entry point.

```gradle
...
...
...
jar {
  manifest {
    attributes(
      'Main-Class': 'com.johnny.Main'
    )
  }
}
...
...
...
```

https://stackoverflow.com/questions/43081894/gradle-output-jar-has-no-main-class/
https://stackoverflow.com/questions/32567167/gradle-no-main-manifest-attribute
【Webpack】開発モードと本番モード

指定なしだとデフォルトの本番モードで処理される。
webpack.config.js で、開発モードをデフォルトにしておく。

```webpack.config.js
module.exports = {
  mode: 'development',
  // 続く
```

package.json の "script" を以下の通り設定しておく

```package.json
  "scripts": {
    "build": "webpack",
    "build-production": "webpack --mode=production"
  },
```

開発モードと本番モード、適用したい方で webpack を実行できる。
package.json があるディレクトリで以下コマンド

* 開発モード `npm run build`
* 本番モード `npm run build-production`


## メモ

mode を設定せず、package.json でのコマンドを以下にしても全く同じで何ら支障はない

```package.json
  "scripts": {
    "build": "webpack --mode=development",
    "build-production": "webpack --mode=production"
  },
```

## 参考記事

    * [Mode | webpack](https://webpack.js.org/configuration/mode/)
WSL環境のRubyにて、selenium（Chrome）を利用する

# WSL環境のRubyにて、selenium（Chrome）を利用する

# 事前準備
## 必要なライブラリのインストール
```bash
sudo apt-get update
sudo apt-get install -y libappindicator1 fonts-liberation
```

## ヘッドレスモードを使用できるchromeをインストール
```bash
sudo apt install gdebi-core wget unzip
sudo gdebi google-chrome-stable_current_amd64.deb
```

## Chromeのバージョンを確認
```bash
google-chrome --version
```

## chromedriverのインストール
現在インストールされている google-chrome に対応する chromedriver をダウンロードする
https://sites.google.com/a/chromium.org/chromedriver/

```bash
curl -O https://chromedriver.storage.googleapis.com/87.0.4280.88/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
chmod +x chromedriver
sudo mv -f chromedriver /usr/local/share/chromedriver
sudo ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver
sudo ln -s /usr/local/share/chromedriver /usr/bin/chromedriver
```

# 動作確認

- パッケージの変更

```ruby:Gemfile 
source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem "webdriver"
gem "selenium-webdriver"
```

- パッケージの反映

```bash
bundle install
```

- Rubyのサンプルコード

```ruby:test.rb
require "selenium-webdriver"

options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--no-sandbox')

driver = Selenium::WebDriver.for(
  :chrome,
  options: options
)
driver.navigate.to "https://www.google.com/"

puts driver.title

driver.quit
```

- 動作確認

```bash
ruby test.rb
```

# 参考
- Selenium WebDriverでRubyのテストを行う方法【初心者向け】
https://techacademy.jp/magazine/18704

- RubyとSeleniumでHeadless chromeを動かす on Ubuntu/Linux
https://qiita.com/meguroman/items/41ca17e7dc66d6c88c07

- 【完全版】PythonとSeleniumでブラウザを自動操作(クローリング／スクレイピング)するチートシート
https://tanuhack.com/selenium/