OmniAICreator/Qiita-1.07M huggingface dataset:
【JavaScript】appendChildの使い方

# はじめに
アウトプットが苦手な自分が練習の一環として記事を書いてみる。

第四回目です。

以前にappendChild()を使用して画面にフォームを追加するコードを書いていましたが、
~~しっかり理解して使っているわけではなかった~~ので備忘録としても
JavaScriptでHTMLの要素を追加する`appendChildの使い方`について書いていきます。

※今後、新たに分かったことがあれば追記していく。

# appendChildとは
appendChild()とは特定の親ノードの子ノードリストの末尾にノードを追加するメソッドです。
※似たようなものでappend()がありますが、あちらはjQueryで書く場合に使用するようです。

# 使い方
例としてボタンを押下するとテキストボックスが追加されるコードを作成します。
サンプル画面のHTMLになります。

```html:サンプル.html
<div>
  <h2>テキストボックス追加</h2>
    <div>
      <label>ボタンを押下すると↓にテキストボックスを追加する</label>
      <div id="addTextBox">
        <input class="block" type="text" value="テキストボックス1">
      </div>   
    </div>
    <button id="addButton" onclick="addTextBox()">フィールドを追加</button>
</div>
```
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1783771/b68e4a80-fb45-e94f-4523-88b0616d8844.png)
上記の`<div id="addTextBox">`に子要素としてテキストボックスを追加するようJavaScriptを組んでいきます。

```javascript
  // 追加する要素を生成する
  var input = document.createElement('input');
  input.type = 'text';
  
  // 親要素を取得
  var parent = document.getElementById('addTextBox');
  
  // 親要素の末尾に追加する
  parent.appendChild(input);
```

ボタンを押下すると無事に新たなテキストボックスが追加されました。
![無題2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1783771/f7baa404-4da7-577f-e0a1-e645ba48f311.png)
ボタン押下でHTMLは以下のように変わっていました。

```html
<!-- 実行前 -->
<div id="addTextBox">
  <input class="block" type="text" value="テキストボックス1">
</div>   

<!-- 実行後 -->
<div id="addTextBox">
  <input class="block" type="text" value="テキストボックス1">
  <input type="text" class="block"> <!-- 追加されたテキストボックス -->
</div>
```

# サンプル
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="YzVbJab" data-user="tkshiiiir" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/tkshiiiir/pen/YzVbJab">
  </a> by tkshiiiir (<a href="https://codepen.io/tkshiiiir">@tkshiiiir</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# 参考サイト
https://developer.mozilla.org/ja/docs/Web/API/Node/appendChild

https://web-tsuku.life/add-form-appendchild/
OHHTTPStubsでHTTPリクエストのテストをする

# はじめに

[OHHTTPStubs](https://github.com/AliSoftware/OHHTTPStubs)はHTTPレスポンスのモックを作るためのライブラリとしてはよく知られていますが、HTTPリクエストのテストを行う方法について調べても具体的な方法がでてこなかったので自分なりにまとめてみました。

# リクエストのテストについて

公式のサンプルコードをみると、最初のところに`stub(condition:)`があるのがわかります。

```swift
stub(condition: isHost("mywebservice.com")) { _ in
  // Stub it with our "wsresponse.json" stub file (which is in same bundle as self)
  let stubPath = OHPathForFile("wsresponse.json", type(of: self))
  return fixture(filePath: stubPath!, headers: ["Content-Type":"application/json"])
}
```

ここの、`condition`の中にHTTPリクエストのテストを記述することができます。

サンプルにある`isHost`は、HTTPリクエストのパスのホストが`myswbservice.com`であることをチェックしています。もしそうでない場合は通信がエラーになるのでXCTestが失敗します。

# 具体的に何がテストできるのか

ここからは、Githubをよく見ないとなかなか見つからない情報です。
（README.mdで軽く触れられている程度で、ドキュメントにも載ってないです）

[OHHTTPStubsSwift.swift](https://github.com/AliSoftware/OHHTTPStubs/blob/12f19662426d0434d6c330c6974d53e2eb10ecd9/Sources/OHHTTPStubsSwift/OHHTTPStubsSwift.swift)を見ると、`condition`引数に指定できる条件の関数が定義されているのでここからテストに必要なものを探して、`&&`や`||`でつなげてください。

以下、テストできる内容のまとめです。
（何がテストできるのかについてイメージしやすいようにしているので、全ては掲載していません。詳しくはソースを御覧ください。）

- `isMethodGET`: GETメソッドかどうか
- `isAbsoluteURLString`: URLが絶対パスになっているかどうか
- `isScheme`: スキームが正しいかどうか
- `isPath`: パスが正しいかどうか
- `containsQueryParams`: クエリパラメータを含むかどうか
- `hasHeaderNamed`: ヘッダーを含むかどうか
- `hasBody`: リクエストボディが存在するかどうか
- `hasJsonBody`: JSON形式のリクエストボディの内容が期待通りの内容かどうか

# いつ使うの？

そもそも情報がない理由として、APIが正しく動作しているかどうかは、わりと実際に通信してから試したりすることが多くあまり使われるケースが少ないからだと予想しています。
特にiOSアプリの開発ですと、レスポンスの形式に関心があることが多く、リクエストのテストに目が向けられないということも一因として挙げられそうです。

特に以下のようなケースではこの機能がとても有用だと思うので、ぜひ選択肢の一つとして覚えておくと良いと思います。

- 開発初期のモックサーバーが存在しない状態での開発
- アプリ内で共通で使うAPIクライアントを作成するとき
  - 本当に正しいパスを選べているか？
  - 本当にヘッダーが正しく指定できているか？
EC2の暗号化設定について

#はじめに
EC2を暗号化する機会があったので対応方法について書いておきます。

#構築時に暗号化する場合
構築時にEBSの「暗号化」にチェックを入れて、
KMSキーを選択して(ない場合はデフォルト)作成するだけ。
![スクリーンショット 2021-08-19 18.04.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575134/c1523bc7-6179-7277-46f5-458fefd56678.png)

#既に稼働中のEC2を暗号化する場合
残念ながら既に存在するEC2を後から暗号化することは不可能。
そのため、暗号化されたAMIを使用してEC2を再作成する必要があります。

#設定方法
（１）該当のEC2のAMIを取得
（２）取得したAMIをコピーし、コピーする際にEBSの暗号化にチェックを入れる。
（KMSキーを用意していない場合は、デフォルトのものを使用する）
![スクリーンショット 2021-08-19 18.15.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575134/92785d97-b31f-471f-2232-1dc1d5e31028.png)
![スクリーンショット 2021-08-19 18.16.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575134/c86c9375-5452-62e6-f98e-976209565663.png)
↓コピーしたAMIのsnapshotが暗号化されている
![スクリーンショット 2021-08-19 18.28.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575134/dc119cb2-fcc8-fac9-7c15-50af19617f3d.png)
（３）コピーしたAMI(暗号化済み)からEC2を起動する
↓暗号化されている
![スクリーンショット 2021-08-19 18.31.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575134/0695c2f1-8ac5-9bd1-720a-d73a2c73272b.png)

ちなみに、このAMIを使用すればAutoScalingでEC2を立ち上げるときも
暗号化されたインスタンスが立ち上がります。
↓上記のAMIを使用したAutoScalingのEC2
![スクリーンショット 2021-08-19 18.42.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575134/d793d2e0-5b2f-e92e-97b3-56f3d1d81a98.png)
↓同じく暗号化されている
![スクリーンショット 2021-08-19 18.43.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575134/ebeacf98-9f6e-1249-a69d-f9e9678cd523.png)

#注意点
KMSキーをデフォルトのものを使用している場合、AMIを他アカウントに共有できません。
↓エラーになる
![スクリーンショット 2021-08-19 18.55.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575134/2feb4445-ed37-ba30-ae07-e21c456ce36f.png)
参照↓
https://aws.amazon.com/jp/premiumsupport/knowledge-center/share-encrypted-rds-snapshot-kms-key/

#終わりに
他にもEBSをコピーして、コピーする際に暗号化して、EBSを付け替えるやり方もあるみたいなので次回はそれを試してみたいと思います。

#引用
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/EBSEncryption.html
はじめてのJulia(1)：導入～インストール編

# 本稿の目的
本稿ではJuliaを学ぶ過程で調べたりした内容を備忘録的に記載していく予定。
あくまで自分用のメモなので丁寧さは皆無。どこまで続くかも未定。

# Juliaとは
[Julia公式](https://julialang.org/)

Juliaは2009年にMITの研究者達によって開発がスタートし，2012年に初公開された比較的新しい言語。
バージョン1.0が公開されたのは2018/8/8で，2021年8月20日現在の最新バージョンは1.6.2である。

Juliaの長所・短所に関する解説は以下の記事を参照。
[バイバイ Python。 ハロー Julia！](https://qiita.com/baby-degu/items/7d4e295964ebb6e92de4)

# 筆者環境
Windows10 (64bit) Inter(R) Core-i7-1165G7 @ 2.80GHz, RAM 16GB

# インストール
## Windows10
下のリンクから最新バージョンのインストールファイルをダウンロードする。Installerとportableがあるが，どちらでもよい。
https://julialang.org/downloads/

### Installerの場合
ダウンロードしたexeファイルを起動し，インストールを完了する。
途中，「Add Julia to PATH」というチェックボックスがあるが，チェックを入れると自動でパスを通してくれる。
自前でパスを通す場合は下の記載に従って行う。

### Portableの場合
ダウンロードしたZipファイルを解凍し，任意の場所に解凍した中身の`julia-(バージョン)`を置く。

### パスの通し方
1. Windowsキー + RでRunを開き，`rundll32 sysdm.cpl,EditEnvironmentVariables`と入力する。
1. User VariablesまたはSystem Variablesという項目があるはずなので，その中のVariableからPathを選ぶ。
1. 「新規」を選び，`C:\Users\(ユーザー名)\AppData\Local\Programs\Julia 1.5.3\bin`（Installerでインストールした場合）と入力する。
1. OKを押して閉じる。

## MacOS
下のリンクから最新バージョンのインストールファイル`julia-（バージョン)-mac64.dmg`をダウンロードする。MacOSの場合はWindowsと違い、インストーラーは1種類のみ。
https://julialang.org/downloads/

'julia-（バージョン)-mac64.dmg'を起動し、通常のアプリケーションのインストールと同様に`Julia-(バージョン).app`をアプリケーションフォルダに入れる。

### Terminalから起動したい場合
ターミナルを起動し、以下のコマンドを実行してシンボリックリンクを作成する。

```
rm -f /usr/local/bin/julia
ln -s /Applications/Julia-1.6.app/Contents/Resources/julia/bin/julia /usr/local/bin/julia
```

# 起動
## Windows10
コマンドプロンプトから`Julia`と入力すればJuliaが起動する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629977/611199ab-22aa-c4fd-0832-7f8af36c5863.png)

## MacOS
### 直接アプリケーションを起動する場合
通常のアプリケーションと同様に、アプリケーションフォルダに入っている`Julia-(バージョン).app`を起動する。

### ターミナルから起動する場合（上記のシンボリック作成の手順を行なっている場合）
ターミナルを開き、`julia`と入力する。
医療情報技師　情報処理編　2016

##UTP
8本の銅線を2本ずつ擦り合わせた通信ケーブルの1種
電気シールドが施されていない
電気を用いて通信する

##〇〇図まとめ

* ER図
　![34FA371E-A53B-444E-81C6-3C7B0B5EB858.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960912/6136ab64-b382-1798-5510-9d8445cc20cb.jpeg)


* ガントチャート
　![32BAE1B8-6E09-4BF9-ABCA-F8DD9E230A25.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960912/0cdccf2c-b079-5d4a-4d21-1329a0ed6b97.jpeg)

* ユースケース図
　ユースケース図は、システムで何ができるかを「ユーザー目線で」表現する図解術です。「システムを利用する人の目線で」具体的にシステムを利用する場面を想定して、視覚的に図示することがユースケース図を使う目的です。
　![CFFC269B-ACC2-46AB-9203-631F33EDA96D.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960912/ce205ceb-f3f8-490b-9d98-f86a95e24311.jpeg)

* DFD図
　データフロー図（DFD: data flow diagram）とは、情報システムを通るデータの流れを図で表したものであり、構造化システム分析・設計手法で使われる。
　![22399B6D-CC9D-4948-9AA2-F9F443192588.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960912/4d5bf8e5-b5e9-1870-27ee-2b8eb00e84c1.png)
TencentCloudの通知設定

TencentCloudでサポートセンターへ質問を投げるとアカウントに設定した電話番号へSMSが届く。
新しくTicketが作成されましたよ。みたいな。

自分の作成したTicketならいいけど他のユーザーがサポートへ問い合わせても届く。
しかも他のユーザーのチケットは自分には閲覧できない。
何を通知してるんだこの機能は。

他のユーザーのチケットもナレッジとしてはいいので閲覧したいけどそれはできないとのこと。

とりあえずSMSの通知をOFFに。

Message Center > Message Subscription > Ticket Servie Notice > Modify Message Recipicent

から自分のアカウントを削除でOK
通知を全員OFFにしたいならMessage SubscriptionでTicket Servie Noticeのチェックを外せば大丈夫そう。
SplitAppにBusyを設定するのに詰まった話

# はじめに
SAPUI5のSplitAppを使用してアプリを作成しました。
参考：[SCP Samples](https://sapui5.hana.ondemand.com/#/entity/sap.m.SplitApp/sample/sap.m.sample.SplitApp)
SplitAppに対してBusyを設定したところ、以下のようにmasterPageにBusyが表示されなかったので、その解決策を備忘録として記載します。
![busy01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486466/3288d559-0984-198c-cacd-8c2e7f9e1d6a.png)

# Busyをどう設定しようとしたのか
ViewとContorollerを以下のようにしたところ、上図のようにmasterPageにBusyが表示されませんでした。

```xml:Main.view.xml
<mvc:View controllerName="....controller.Main"
	xmlns:mvc="sap.ui.core.mvc"
    displayBlock="true"
	xmlns="sap.m">
	<Shell id="shell" appWidthLimited="false">
		<SplitApp id="SplitApp" initialDetail="detail" initialMaster="master" masterButtonText=" ">
			<detailPages>
				<Page id="detail" backgroundDesign= "Solid" ...>
				</Page>
			</detailPages>
			<masterPages>
				<Page id="master" backgroundDesign= "List" ...>
                 ...
				</Page>
			</masterPages>
		</SplitApp>
	</Shell>
</mvc:View>
```

```js:Main.controller.js
onInit: function() {
...
this.getView().byId("SplitApp").setBusy(true);
...
}
```

# 原因
SplitApp配下にある、masterPageのCSSにz-index:1が設定されていることが原因でした。
Busyや他の要素にはz-indexが設定されていないため、masterPageが一番手前に表示されてしまうようです。

# 解決策
今回はBusyの要素にz-indexを設定することで解決しました。

```css:style.css
.sapUiBlockLayer, 
.sapUiLocalBusyIndicator{
    z-index: 2;
}
```

上記の設定で、無事にBusyがView全体に表示されるようになりました。
![busy02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486466/f2e68942-a883-bac3-0dd4-263ffc9d7e76.png)

# おわりに
今回は強引な方法で解決したので、よりスマートな解決策が見つかれば、またまとめたいと思います。
DDD リポジトリとは

今日は DDD のリポジトリについてまとめます。

# リポジトリとは
リポジトリは集約の保存、取得をおこなうコンポーネントです。

ドメインによって業務ロジックを処理する際、処理対象のデータを取得したり、処理結果を保存したりする機能をドメインから隔離することで、データベースなどのストレージとのやりとりをドメインやアプリケーションから隠ぺいします。

```php
// ユーザーリポジトリのインタフェース
interface UserRepositoryInterface
{
    public function create(User $user);

    public function findById(UserId $id);

    public function edit(User $user);
}

// クライアント側
class UserGetInteractor implements UserGetUseCaseInterface
{
    private $repository;

    public function __construct(UserRepositoryInterface $repository)
    {
        $this->repository = $repository;
    }

    public function handle(UserGetInputData $inputData)
    {
        UserId $id = UserId($inputData->getId());
        $user = $this->repository->findById($id);
        :
    }
}
```

リポジトリにはインタフェースをつくり、アプリケーション側からはそのインタフェース経由でリポジトリにアクセスするようにしておくと、リポジトリの実装をかんたんに切り替えることができるようになります。

リポジトリの実装を切り替え可能にしておくと、たとえばテスト時にはデータベースを単なるメモリ上のデータにすることで、データベースの構築ができていない段階でもアプリケーションサイドのテストができるようになります。



# リポジトリは集約に対応する
リポジトリを作る際に重要なのは、どういう単位で作るのか、ということにあるとおもいます。
テーブルごとに作ったりユースケースごとに作るのではなく、基本的には集約ごとに作ります。

なぜ集約ごとにつくるのかというと、これはおそらく**「データの整合性がとれなくなる可能性を設計段階で摘み取っておく」**ということが重要だからだとおもいます。

集約というのは、ひとつ以上のオブジェクトの集合であり、トランザクションの単位となるものです。
集約にはひとつのルートが存在し、配下のオブジェクトは他の集約からは隠ぺいされ、集約を介してしかアクセスできないようにします。

集約内部のオブジェクトはルートが責任をもって管理するということになります。

このように、オブジェクトへのアクセスにある程度の制約をもうけることで、無秩序にインスタンスが生成・変更され、ソフトウェアが実現したい業務のなかではありえないデータ生成や操作が発生する可能性を減らします。

# リポジトリが細切れだと...
リポジトリが集約に対応しておらず、ひとつの集約の中に対応するリポジトリが複数存在するとどういう問題が発生するでしょうか。

考えられるのは、トランザクションが一貫性を保つように、**注意してリポジトリを利用しなくてはならなくなること**です。

集約というのは、不変条件（一貫性ルール）を強制させる範囲であり、トランザクションが完了するたびに、その集約がもつ不変条件は真である必要があります。

しかし、集約内のオブジェクトを保存するために利用するリポジトリが複数にまたがっていると、リポジトリの呼び出し方によっては不変条件に違反する可能性が発生しえます。

そのため利用するときには、それら複数のリポジトリを "正しい順序で" 呼び出したり、条件によって呼び出し方を変えるなど、注意をはらって利用する必要がでてくるとおもいます。

そのような問題を未然に防ぎ、不変条件を守るための制約として、集約に対応するリポジトリを作成する、という原則になっているのだとおもいます。
iCloud Driveのエイリアスを作成する，よく使う項目にピン留めする．

## そもそもiCloud Driveのパスは?
~/Library/Mobile\ Documents/com~apple~CloudDocs/
だそうです．
https://salumarine.com/where-is-my-icloud-drive/　
サマより．

## サイドバーにピン留め，エイリアス作成同時進行で進めます
以下のコマンドをターミナルに入力するか，自力でホームディレクトリから辿ってください

```
open ~/Library/
```

これでライブラリが開くことになりますのでMobile Documentを探して右クリック，
「エイリアスを作成」をクリックします．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670080/b33bb49c-d3af-6202-c39f-b624a1d970ba.png" width="400">

ここでサイドバーにピン留めしたい人はMobile Documentをサイドバーの好きなところにドラッグ&ドロップします．

エイリアスが作成できましたので，
デスクトップなど好きなところに移動させましょう．
名前はiCloud Driveなどにするのがおすすめです．


〜終〜
VSCode上で猫ちゃんを飼い始めました


最近癒しが欲しくてVSCode上でペットを飼い始めました。

## 飼い方

VSCodeを開いて、Ctrl + Shift + X で拡張機能開きます。
「vscode-pets」と検索。
あとはインストールするだけです。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467168/c142cd9b-2079-4146-21ae-696116e7ccec.png)

 

https://marketplace.visualstudio.com/items?itemName=tonybaloney.vscode-pets&WT.mc_id=python-17801-anthonyshaw

## ペットとじゃれ合う方法

Ctrl + Shift + P でコマンドパレット開きます。
「start pet coding session」を実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467168/63f5e1d5-92b0-26ba-05b6-67f3e4f8c425.png)

タブが開いて猫ちゃんが現れます。
マウスを動かすとじゃれ合うことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467168/69207f6d-ba12-3952-0eba-c122661bcdde.png)


## その他設定

設定の「vscode-pets」から色々設定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467168/fa346799-0be7-e327-8c09-3dc94941260e.png)

- 設定から猫ちゃん以外も飼えます
- 大きさや色も変えれます
NLTKでnltk.download('wordnet')でResource not found.となってしまう

# はじめに
ゼロから作るDeepLearning2を使って勉強会を開こうと思い、復習をしていたました。
せっかくなので付録で説明されている`wordnet`を実装していたのですが、Colabで書籍通りに動かなかったのでまとめたいと思います。

古めのライブラリで利用する人は少ないかなと思いましたが、有名な書籍かつ初心者向けということで同じく詰まる人の助けになればと思います。

# 環境
- Google Colabratory

# 問題

まず、nltkをインストールします。

```
!pip install nltk
```

その後、以下のコードを実行します。

```
import nltk
from nltk.corpus import wordnet

# carの類義語を調べる
wordnet.synsets('car')
```

すると、以下のエラーが発生します。

```
LookupError                               Traceback (most recent call last)
/usr/local/lib/python3.7/dist-packages/nltk/corpus/util.py in __load(self)
     79             except LookupError as e:
---> 80                 try: root = nltk.data.find('{}/{}'.format(self.subdir, zip_name))
     81                 except LookupError: raise e

5 frames
LookupError: 
**********************************************************************
  Resource wordnet not found.
  Please use the NLTK Downloader to obtain the resource:

  >>> import nltk
  >>> nltk.download('wordnet')
  
  Searched in:
    - '/root/nltk_data'
    - '/usr/share/nltk_data'
    - '/usr/local/share/nltk_data'
    - '/usr/lib/nltk_data'
    - '/usr/local/lib/nltk_data'
    - '/usr/nltk_data'
    - '/usr/lib/nltk_data'
**********************************************************************


During handling of the above exception, another exception occurred:

LookupError                               Traceback (most recent call last)
/usr/local/lib/python3.7/dist-packages/nltk/data.py in find(resource_name, paths)
    671     sep = '*' * 70
    672     resource_not_found = '\n%s\n%s\n%s\n' % (sep, msg, sep)
--> 673     raise LookupError(resource_not_found)
    674 
    675 

LookupError: 
**********************************************************************
  Resource wordnet not found.
  Please use the NLTK Downloader to obtain the resource:

  >>> import nltk
  >>> nltk.download('wordnet')
  
  Searched in:
    - '/root/nltk_data'
    - '/usr/share/nltk_data'
    - '/usr/local/share/nltk_data'
    - '/usr/lib/nltk_data'
    - '/usr/local/lib/nltk_data'
    - '/usr/nltk_data'
    - '/usr/lib/nltk_data'
**********************************************************************
```

wordnetの読み込むデータないようでした。
書籍通りではColabでは動作しないようです。

# 解決方法
wordnetにつかうデータをダウンロードすることで解決しました。

```
import nltk
from nltk.corpus import wordnet

# 必要なパッケージ、データ、ドキュメントのダウンロード (時間がかかる)
nltk.download('all')

wordnet.synsets('car')
```

# おわりに
おそらくダウンロードで不要なものもダウンロードしているので、うまくダウンロードの設定を変えるとよいかもしれません。('all'を変更)

私は、書籍を試すだけでしたのでallを使いました。

最近はnltkを使うこともあまりないかと思いますので、詳しくは調べておりません。わかる方いましたらコメントお願いします。
[Laravel EC2]　EC2にあるログファイルをローカルにコピーする

### サーバーからログファイルなどをコピーするコマンド

以下のコマンドではec2にデプロイしているLaravelのプロジェクトにあるログファイルをデスクトップにコピーしてます

scpコマンドは、sshを利用してリモートからファイルコピーするコマンドです

```sh
 user_name$ scp -i .ssh/ec2_key.pem
 uec2-user@ipアドレス:/var/www/projectName/storage/logs/laravel-2021-08-10.log
 ./Desktop
```
Windows10でパスを追加・編集する

# Windows10でパスを追加する
これまでに追加したパスを確認・編集したり，新規のパスを追加する方法をメモしておきます。

1. Windowsボタン+RでRunを開き，`rundll32 sysdm.cpl,EditEnvironmentVariables`と入力する。
2. User VariablesまたはSystem Variablesという項目があるはずなので，その中のVariableからPathを選ぶ。
3. 「新規」を選び，追加したいパスを入力する。
例えばJuliaのインストールの場合は`C:\Users\(ユーザー名)\AppData\Local\Programs\Julia 1.5.3\bin`のように追加する。
4. OKを押して閉じたら，パスが通っている。

# 既存のパスを編集する
上の2までは同様。「編集」を選べば編集が可能に，「削除」を選べば削除できる。
なお，「編集」の中でパス間の優先順位の変更も可能。
【WidgetKit】SceneDelegateを使用せずにウィジェットからの遷移を実装したい

##はじめに
Widget内で`Link`や`.widgetURL`を使用した場合、SceneDelegate内で処理を追加する必要があります。
AppDelegateのみで実装している場合、後からSceneDelegateを追加するのは面倒です。
そこで、なんとかAppDelegateでできないかなと模索しました。
なんとAppDelegateにUIWindowSceneDelegateを継承させて実装してあげると、なんと動いてしまいました。


##実装方法
下記の例のようにAppDelegateにUIWindowSceneDelegateを継承させて実装します。

```swift
extension AppDelegate: UIWindowSceneDelegate {
    
    @available(iOS 14.0, *)
    // App launched
     func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
         guard let _: UIWindowScene = scene as? UIWindowScene else {
            return
         }
         maybeOpenedFromWidget(urlContexts: connectionOptions.urlContexts)
     }
    
    @available(iOS 14.0, *)
     // App opened from background
     func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
         maybeOpenedFromWidget(urlContexts: URLContexts)
     }
    
    @available(iOS 14.0, *)
     private func maybeOpenedFromWidget(urlContexts: Set<UIOpenURLContext>) {
         if let _: UIOpenURLContext = urlContexts.first(where: {
            $0.url.scheme == "widget-link"
         }) {
            print("🚀 Launched from widget")
         }
     }
}
```
##最後に
AppdelegateにSceneDelegateの実装をしていいか分かりませんが、とりあえず動くので大丈夫でしょう（？）
Solana Naming Service でドメインを取得するメモ

## 背景

decentralized な管理によるドメイン名ほしい.
ENS(Ethereum Naming Service)おたかい... gas 代だけで数万円...

Solana で動くドメインサービス使ってみます.
Bonfida が主流っぽい.

その他, Decentralized DNS のまとめ

Decentralized Crypto Domain (Web 3.0)
https://www.coingecko.com/buzz/decentralized-crypto-domain-web-3

## ドメイン取得

ドメインは `.sol` になります.
ENS(Ethereum Naming Service) と違い, 一度取得したら永久的につかえます!

新規に登録する場合, オークション形式で 7 日間のオークション期間を経る必要があります.
最低 `$20` からスタート(しかし `$20` で入札はできないので, 実質 `$20.1` 程度必要). 支払いは USDC になります.

以下でオークション中のドメインを見ることができます.

https://naming.bonfida.org/#/auctions

絵文字も使えます.

いいドメイン名を予め取得しておき, あとでオークションで売るというのもできるでしょう.

## オークション終了後

オークションが終わって自分の bid で落札できた場合, 最初に storage を claim します.
ドメイン名に埋め込めるなんか情報らしい. 大体は 1KB で足りるようです.
サイズによって追加で `$SOL` がかかります.


## 注意点

Bonfida と Bonfida Token は US では使えないとあります.
日本は OK なのかな...? 

.sol ドメインは ENS(`.eth.link`) とは異なり, IPFS と連携させようにもそのままでは web サイトの URL としてはつかえません(.sol から IPFS CIS を解決するしくみがブラウザ側にないとだめ).
いずれは Brave が対応したり, `.eth.link` みたいに `.sol.link` みたいなのでできるようになるかもはしれません.

## TODO

* [x] SNS ドメイン取得したら IPFS　と連携してサイト公開までする
  * .sol -> IPFS resolve する Solana wallet あたり使わないとだめだった.
laravelで表示する文字を制限したい（はみ出た分は「...」にする。）

#概要

記事のタイトルに、表示する上での文字数制限を付けたい。
ここでは

```.php
  $post->title
```
に対して、表示する文字数を制限する。
こんな漢字

```
「昨今の少子高齢化問題について」 → 「昨今の少子高齢化...」
```

#モデル側

```Post.php
  public function strlength() {
          $str = $this->title;
          $limit = 10;

          if (mb_strlen($str) > $limit ) {
              $str = mb_substr($str, 0, $limit);
              return $str . "...";
          } else {
              return $str;
          }
  }
```

#ビュー側

```indexblade.php
:
:
    {{ $post->strlength() }}
:
:
```
測地系の変換が嫌になってきたのでメモ

様々な測地系のデータを1つの地図にプロットする必要があるのですが、泣きそうなので頭の整理のためにまとめます。
（あくまで自分用で情報の網羅性はありませんのであしからず）

# 用語の整理

### 座標系
まずこれがバラバラなのが諸悪の根源。

##### 地理座標系（度数、dgree）
いわゆる緯度経度でイメージするやつ。
`lat=35.658584 lon=139.7454316`

地球の中心からの角度で考えてる。
が、地球は楕円形なので、円として考えてる場合と楕円として補正してる場合とがある。

latが緯度、lonが経度。
latlonで覚えてるけど、関数の引数とかはlon,latになってることが多いので罠。

##### 地理座標系（度分秒、DMS）
上と同じく角度なんだけど、単位を分けたやつ。
1.5時間と書くか、1時間30分と書くかみたいな違い。
`lat=35度39分30.9秒 lon=139度44分43.55秒`
時間と同じで、60で割ると1つ上の単位になる。

やたら表記に幅がある。
`lat=35.3.30.9 lon=139.44.43.55`
`lat=35°3′30″9 lon=139°44′43″55`
`lat=35°3′30.15″ lon=139°44′43.91″`


##### 地理座標系（ミリ秒）
1つ目は度で統一してるけど、これはミリ秒で統一している。
`lat=128371073 lon=503083528`

↓の東映座標系と区別がつきにくい

##### 投影座標系（平面直角座標系）
地面を平面だと仮定して、xy座標で考えたやつ。
`-37514.940925500196,-8250.997005135643, `

でも当然地球は平面ではないので、中心からずれれば誤差が大きくなっていく。

投影座標系の一種で日本固有のものが平面直角座標系。
どこを原点にするかで規格が異なり、日本国内で19種類ある。

##### 投影座標系（UTM座標系）

投影座標系の世界基準版。
ユニバーサル横メルカトルの略。

### 測地系

緯度経度の基準点をどこにするかの規格。
これまた諸悪の根源。

##### 世界測地系（ITRF, WGS84）

ITRFが世界基準。基本はこれを使うのが良い
WGS84はアメリカの基準だけど、ITRFとほぼ同じ

##### 日本測地系（JGD2011、JGD2000）

日本基準の測地系
麻布が基準点になっている。
何度か改正されていて、JGD2000では世界測地系に準拠し、JGD2011では震災の影響を加味した補正がされた。

### CRS: Coordinate Reference System
座標参照系。
ある特定の地点を、どういうルール（座標系、測地系）で記載しているか。

### EPSG: European Petroleum Survey Group
名前の意味的にはヨーロッパの団体名だけど、だいたいはこの団体が策定したコードを指す。
数多ある座標参照系をカタログ化して、それぞれに`EPSG:4301`とか`EPSG:4326`のように番号を振ったもの。

世界測地系で度表示するのはESPG:4326ね！ みたいに決められてる。


# 変換のコード

Pythonの定番pyprojを使って測地系変換をします。

いろいろありますが、基本の変換コードは以下
```
bef = pyproj.Proj(init='EPSG:4301')
aft = pyproj.Proj(init='EPSG:4326')
transformer = pyproj.Transformer.from_proj(bef, aft)
transformer.transform(lon, lat)
```

EPSGというのが測地系のカタログみたいなものなので、元データの測地系のEPSGと変換後のEPSGがわかれば変換できます。
mopinionでフォームのアイコンが変わらないとき

手軽なフィードバックフォームを作成し埋め込めるSaaS、mopinion。

https://mopinion.com/

フォームの編集をしてSave & Publishをしたのに、フォームの中身は変われどボタンアイコンがデフォルトのままだった。プレビューではちゃんと変わってるのに。

原因はただのキャッシュのようで、以下のようにDeveloper toolsを開いてクリアしたらちゃんと反映された。

![スクリーンショット 2021-08-19 17.25.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242610/b989a267-8520-0ab3-feea-51f43058856d.png)

今回はNext.jsで使用したので、react-mopinion-formライブラリを使っていたのも関係あるかもしれない。
UbuntuのdockerでGPUを使う場合snapでインストールしてはいけない


# この記事について

この記事は筆者がUbuntu 21.04でdockerでGPUを使おうとしたときにハマった落とし穴のメモです。

# 経緯

UbuntuではSnappyというaptにかわるパッケージマネージャが用意されています（コマンドは`snap`）。
Ubuntu Server 21.04ではOSの初期インストール時にdockerやmicrok8sなどのパッケージをこのsnapでインストールできるオプションがあり、筆者はこれでdockerをインストールしていました。

その後、dockerでGPUを使うためにNVIDIA Container Toolkitをインストールしたのですが、この途中でaptからdockerをインストールしてしまったようです。
[インストールガイド](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html)に書かれている明示的なdockerインストールのコマンドは実行していないので、おそらく依存関係で勝手にインストールされたのだと推測されます。

この状態でOSを再起動すると、snap版とapt版の二種類のdockerが同時に起動してしまいます。
systemctlではそれぞれ`snap.docker.dockerd.service`と`docker.service`という名称で、`systemctl status <サービス名>`で確認するとそれぞれ異なるログが確認できます。
Dockerイメージも別々に管理されるようで、完全に別物のようです。

NVIDIA Container Toolkitの対応状況としてはapt版のdockerはGPUを使えましたが、snapのdockerでは`--gpus all`のオプションをつけるとエラーになり、コンテナを起動できませんでした。

筆者の環境では、両方起動している状態では、dockerコマンドはsnap版が優先されました。
そのため、二重起動している状態では`docker --gpus all`が失敗し、snap版dockerを停止すると成功する、という状況になります。

# 対策

snap版をサービスとして無効化する`systemctl disable snap.docker.dockerd.service`かアンインストール`snap remove docker`してapt版だけ使うようにすればGPUが使えるようになりました。
【Docker×Rails6】CSSを反映させる

Rails6ではJavaScriptのモジュールバンドラとしてWebpackが導入されていますが、
画像やCSSに関しては従来のSprocketがアセットパイプラインとして使用され、
JavaScriptのみをWebpackでコンパイルするようになっています。
そのため画像やCSSを反映させる場合は、変更作業が必要になります。


# 設定手順

## application.html.erb

<head>の内容を書き換えます。

```ruby:app/views/layouts/application.html.erb
<head>
  <title><%= full_title(yield(:title)) %></title>
  <%= csrf_meta_tags %>
  <%= csp_meta_tag %>
  <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
  # （下の行を追記）webpackがCSSを扱えるようにする
  <%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
  # JavaScriptはデフォルトでwebpacerが pack フォルダをコンパイルして出力している
  <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  <!--[if lt IE 9]>
      <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js">
      </script>
    <![endif]-->
</head>
```


## YarnでBootstrapをインストール

```
$ docker-compose exec app yarn add bootstrap jquery popper.js @fortawesome/fontawesome-free
```

インストールされたモジュールはpackage.jsonで確認できます。

# application.js



以下を追記します。

```ruby:app/javascript/packs/application.js
require("bootstrap");
require("@fortawesome/fontawesome-free");
```

## environment.js

jQueryをどこからでも呼び出せるようにする。



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

environment.plugins.append(
    'Provide',
    new webpack.ProvidePlugin({
        $: 'jquery/src/jquery',
        jQuery: 'jquery/src/jquery',
        Popper: ['popper.js', 'default']
    })
)

module.exports = environment
```


## CSS



以下追記

```ruby:app/javascript/stylesheets/application.scss(※新規作成すること)
@import '@fortawesome/fontawesome-free/scss/fontawesome';
@import 'bootstrap/scss/bootstrap';
```



## application.js



以下を追記します。


```ruby:app/javascript/packs/application.js
import '@fortawesome/fontawesome-free/js/all';
import "../stylesheets/application.scss";
```




最後に、docker-compose restartを実行してブラウザで確認

```
$ docker-compose restart
```

無事にCSSが反映されました！



▼参考にさせていただいた記事

https://qiita.com/naokit-dev/items/30bf299cb0d785f9fb2f

https://techracho.bpsinc.jp/hachi8833/2021_05_06/83678

https://qiita.com/msy-naka/items/dba5e880c501ca0d5d92
[Django + React.Typescript]でChatBotSNSを作成し、AWSで公開

# 1.背景
前職で社内新規事業起案をした際に
新しいビジネスモデルをとして、ChatBotSNSを提案。
踏み込んだことない奴があれこれ言うのは良くないな。
自作してみないと。と思って始めた。
独学&超初学者なので9ヶ月もかかった。。。

# 2.重要
・自分用の備忘録。
・内容を詳細に全て細かく把握し切れていない。
・ここでは参考文献を並べる。
・詳しくはBLOGで紹介

【詳細】
    →→→[BLOGのリンク](https://uuroco.com/?page_id=23)

【作成したwebSNSアプリ】
    →→→[UUROCO](https://uuroco.jp)
維持費用の負担が増えると閉鎖する可能性あり。

# 3.参考文献etc.
●　ChatBot AI 関連
→[『Pythonプログラミングパーフェクトマスター』](https://www.shuwasystem.co.jp/book/9784798063676.html)
（単行本:秀和システム様）

●　SPA 関連
①フロントエンド・バックエンド②デプロイ
→①[『[Instagramクローン編] React Hooks + Django Restframework』](https://www.udemy.com/course/instagram-react-hooks-django-restframework/)

→②[『[JIRA編]React Hooks/TypeScript + Django REST APIで作るオリジナルJIRA』](https://www.udemy.com/course/jirareact-hookstypescript-django-rest-apijira/)
「Section 4: [おまけ] DRF ディプロイ AWS EC2」を参考
（Udemy:Kazu.T樣）
compileSdk・minSdk・targetSdkの違い(Android)

## はじめに

`compileSdkVersion` ・ `minSdkVersion` ・ `targetSdkVersion` の違いがいつもわからなくなるため、まとめることにします。

## 注意

ここからは末尾の `Version` を省略します。

## 各プロパティの違い

各プロパティの違いを紹介します。

### compileSdk

> compileSdkVersion specifies the Android API level Gradle should use to compile your app. This means your app can use the API features included in this API level and lower.
> 
> compileSdkVersionは、Gradleがアプリをコンパイルする際に使用するAndroid APIレベルを指定します。これは、アプリがこのAPIレベル以下に含まれるAPI機能を使用できることを意味します。

引用: https://developer.android.com/studio/build

要はコンパイルに使うSDKバージョンです。
新しい機能を使えるようにするため、基本的には現時点での最新を指定します。

### minSdk

> Defines the minimum API level required to run the app.
> 
> アプリの実行に必要な最低限のAPIレベルを定義します。

引用: https://developer.android.com/studio/build

要はアプリの最低OSバージョンです。
古いOSをサポートする場合、こちらの値を小さくします。

### targetSdk

> Specifies the API level used to test the app.
> 
> アプリのテストに使用するAPIレベルを指定します。

引用: https://developer.android.com/studio/build

公式ドキュメントの説明のみだとわからなかったのですが、Twitterで教えていただきました。

https://twitter.com/niusounds/status/1428264647501615104?s=20

要はアプリを動作させるAPIレベルを指定します。
`compileSdk` と同じく基本的には現時点での最新を指定すればいいですが、例えばAndroid 12（APIレベル `31` ）対応が完了していない場合、 `targetSdk` を `30` に指定すればAndroid 12でも11のように振る舞う、ということです。

## おわりに

公式ドキュメントのコメントを読むだけではあまりわかりませんでしたが、何となく理解することはできました。

## 参考リンク

- [Configure your build  |  Android Developers](https://developer.android.com/studio/build)
半二重のコリジョンと全二重のフロー制御

---
### 概要

**「スイッチハブだとコリジョンが発生しない」**という説明に、**「そうなの!?」**と思っていたので、そのまとめ。

---
### 結論

**スイッチハブだとコリジョンは発生しないが、再送が必要になるフロー制御は発生する。**

つまり、
半二重な世界のリピータハブでは**「コリジョン検知/再送」**と呼んでいたのが、全二重が標準のスイッチハブの世界では、より広範な意味の**「もう少しゆっくり(通信速度を落して)送って」**とかも意味として含まれるようになったので、**「フロー制御」**と呼ばれるようになっている。
・・・・ということだと思う。

そもそも**半二重**の時代から**コリジョン検出**とかとは呼ばずに**フロー制御**と呼んでもよかったのかもしれない。

---
### 半二重と全二重

- 送信と受信が同時に行えないのが、**半二重**
- 送信と受信が同時に行えるのが、**全二重**

#### 半二重

![han20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182822/e17ef48a-ef02-501c-79ec-86fb8fd47211.png)

#### 全二重

![zen20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182822/c0ac9120-d9de-48b4-9cb3-7c2f9a62ac5b.png)

---
### 4芯と8芯

- 4芯は、半二重のみ
- 8芯は、全二重も可能。全二重対応

リピータハブ全盛の時代の時は、全二重である必要性はなかったので、4芯のLANケーブルでもよかった。

---
### 余談

[LANケーブルを交換したら回線速度が倍どころじゃない速度になった話](https://note.com/shirasagiojisan/n/n1f83ffc3e4fe)

「4芯のケーブル(半二重のみ)」を「8芯のケーブル(全二重可能)」にとり替えれば、そりゃそうなるわなぁ～。という話。

私も20世紀末の大学生時代の頃は、10Mbpsのリピータハブ全盛で、研究室のネットワークとかに4芯のケーブルはありましたよ。
・・・今は見ないけど・・・

---
### リピータハブと、スイッチハブ

リピータハブは、通信できるチャンネルは一つだけど、スイッチの場合は複数の機器で同時に通信ができる。

#### リピータハブ

![reperter0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182822/c3a02640-d254-844c-15e7-f6c5b9a78231.png)


#### スイッチングハブ

![switch0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182822/5854fc81-2ed5-63c7-72e5-127ba803d8f4.png)

リピータハブは、**半二重**のような性格を持っている

---
### CSMA/CD(Carrier Sense Multiple Access/Collision Detection[搬送波感知多重アクセス/衝突検出])、コリジョン検出


昔のイーサネットは、半二重通信が前提となっており、同時に通信が発生した場合、それを検知して再送する仕組みが必要になる。

それが**「CSMA/CD」**

仕組みは単純で、

- **(コリジョン|衝突|混線)**を検知したら、送信を即時停止して、しばらく(ランダムな時間)待機して再送する

だけ。 

---
### CSMA/CDとリピータハブ

![hub11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182822/82f7d50b-a4ff-a57a-bfac-529b6d7f26d8.png)

リピータハブは、コリジョンを検出したら、全てのポートにジャム信号を送信する

送信中に、ジャム信号を受信したら、送信を即時停止して、しばらく待機してから再送する

ちなみに4芯なら、**ジャム信号を受信する**というより、**混線するので混線が検知**される。

---
### CSMA/CDとジャム信号

32bitらしい。

---
### スイッチングハブでコリジョンが発生する場合(フロー制御)

![switch2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182822/a9202a31-d1bd-4cae-afc2-cd8a1cd3b27d.png)

まぁ、**コリジョン**ではなくて、**フロー制御**なんだけどねぇ～...

![hub10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182822/29a40e53-517b-250c-cf22-736b75049bf0.png)

1:1の場合でも、例えば、1GBps→スイッチ→100Mbpsというような接続形態でもフロー制御は必要になるでしよう。

まぁ、**コリジョン**ではなくて、**フロー制御**なんだけどねぇ～...

---
### スイッチングハブでは、コリジョンとは呼ばずにフロー制御と呼ぶ

単純に**(コリジョン|衝突|混線)**というよりは、**通信帯域がいっぱい**になっているだけなので、通信速度を落してもらうとかで対処できるので、**フロー制御**と呼ばれる方が適切でしょう。

ということで、**スイッチングハブでは、コリジョンは起きないがフロー制御は起きる。**ということ。

---
### フロー制御のフレーム

使われるのは、PAUSEフレーム。

- 宛先はマルチキャストアドレス : 01-80-C2-00-00-01
- MAC制御タイプ(フレームタイプ) : 0x8808
- MAC制御命令コード(PAUSE命令) : 0x0001

---
### 参考

- [CSMA/CD - wikipedia](https://ja.wikipedia.org/wiki/CSMA/CD)
- [詳説 イーサネット 第2版](https://www.amazon.co.jp/dp/4873117178)
- [詳解TCP/IP〈Vol.1〉プロトコル](https://www.amazon.co.jp/dp/4894713209)
- [LANケーブルを交換したら回線速度が倍どころじゃない速度になった話](https://note.com/shirasagiojisan/n/n1f83ffc3e4fe)

---
### 以上
{laravel} ルーティング（web.php）の書き方

GET：ページを「取得」するためのリクエスト
POST：情報を「送信」するためのリクエス

画面表示のために必要なパラメーターは「GET」
例）表示したい商品や動画のID、ページ番号など

URLを直接入力や、お気に入りからのアクセス、ページ内のリンクをクリックした場合は、基本的にGET方式でリクエストが送られる。

GETの弱点：URL上にパラメーターが丸見えになってしまう
→個人情報やパスワードがURL上に記載されてしまうのはまずい

ユーザーが画面に入力して送信するパラメーターは「POST」
例）ログインIDや個人情報など

パラメータをURLにくっつけずにサーバーに送る方式。お問い合わせフォーム、注文入力画面など、画面から情報を入力して「送信ボタン」を押すようなタイプの画面は基本的にこのPOST方式。


#まず基本形

https://codelikes.com/laravel-routing-summary/

書き方が二つある。

例えば、https://xxx
といったサイトがあった場合を考える。
https://xxx/login
にアクセスされた場合は、ログイン画面（login.blade.php）を表示するとする。

```web.php
// (1)
Route::get('/login', function () {
    return view('login');
});
```


第１引数にURLを記載して
第２引数に行う処理を書きます。

①get：表示
②post：データー渡し

getはリソースを表現するもので、postは処理を行うもの

・getメソッドのものはviewが必要なので、getはちゃんとリンクがひらけるかの確認

redirect：指定したURLに飛ぶ
view：指定したview(blade.php)を表示




↓コントローラーのメソッドを使いたい時

```web.php
// (2)
Route::HTTP動詞(’ビュー’,’コントローラー名@メソッド名’)
```

**①HTTP動詞の指定**

get：表示
post：データー渡し

**②ビューの指定**
URLのパス

**③コントローラーの関数を指定（コントローラーでそのページでしたい処理を書く）**

#覚えたら楽なこと
スラッシュ（/）がついている分に関しては、URLを表している。（？）

#疑問
(1)の場合postにすることはあるのか、redirectをする意味がわからない


#名前付きルート
ルーティングに名前を付ける事ができます。名前をつけると、設定したルート名のみを指定し処理を書けば良くなるので便利です。

```web.php
Route::get('sample', 'SampleController@index')->name('sample');
```
エックスサーバーのコマンドラインで `php` だけで特定のバージョンのPHPを実行できるようにする

# コントロールパネルからバージョンを設定してもコマンドラインには反映されない

エックスサーバーはコントロールパネルからPHPのバージョンを設定しても、コマンドラインで`php`とだけで実行すると5系で実行されてしまう。
例えば、コントロールパネルからはPHP7.4を指定してある状態だが、以下のようになる。

```sh
$ php -v
PHP 5.4.16 (cli) (built: Nov  1 2019 16:04:20)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
```

## とりあえずの回避策

`whereis php` を実行すると分かる通り、`/usr/bin/` や `/opt/` の中にPHPバージョンごとの実行ファイルが存在する。
そのため、以下のようにすれば任意のバージョンで実行できる。

```sh
$ /usr/bin/php7.4 -v
PHP 7.4.13 (cli) (built: Dec  6 2020 21:19:47) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
```

※ちなみに、`/usr/bin/` のPHPは `/opt/php-x.x.x/bin/php` へのシンボリックリンクである。

なので、Cron等でPHPをバッチ処理する場合などはこの方法で設定するケースをよく見かける。

**めんどくさくない？**

# それ、シンボリックリンクと.bashrcで回避できるよ

エックスサーバーにcomposerを導入したことがある人はこの時点で解決策が見えているかもしれないが、つまりそういうこと。

## 手順1. 適当なディレクトリにシンボリックリンクを作成
今回は /home/ユーザー名/opt/bin/php というシンボリックリンクを作成する

```sh
$ mkdir ~/opt
$ mkdir ~/opt/bin
$ cd ~/opt/bin
$ ln -s /opt/php-7.4/bin/php php
```

## 手順2. .bashrcを編集
上記のパスを.bashrcに登録する

```sh
vi ~/.bashrc

以下を追記
export PATH=$HOME/opt/bin:$PATH
```

## 手順3. 再度SSHでログインし、バージョンを確認

```sh
$ php -v
PHP 7.4.13 (cli) (built: Dec  6 2020 21:19:47) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
```

以上。

上記の方法だと `/opt/bin/` に入れたファイルがコマンドとして認識されるため、自前でインストールしたプログラム（composerなど）も登録することができる。
色と英数字

今あなたが見ているWebページでは色を表現するために
カラーコードを使用しています。

カラーコードとは、#の後に6桁の英数字を入力することで、
文字や背景色を指定することができる。

赤なら#ff0000
青なら#0000ff
緑なら#008000

のように記述することで、色が表現できる。

また、カラーコード以外で
「red」、「blue」、「green」
と直接色の指定が可能である。
![HTML - Google Chrome 2021_08_18 21_24_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580200/66de11bf-1567-87b5-a77b-670829d7f5a9.png)



![_無題 - メモ帳 2021_08_18 21_08_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580200/0feaf8d9-a01b-c256-49f0-c1f88ffee7ab.png)
【Docker×Rails6】solidusを使ってECサイトを構築する（開発編）

この記事は、下記記事の続きになります。

https://qiita.com/asami___t/items/44a77464b57503ea78db

# gemをインストールする。

```ruby:Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
# gem "rails"
gem 'solidus'
gem 'solidus_auth_devise'
```

'solidus'をrequireすると、以下がまとめてインストールされます。個別にインストールすることも可能なよう。
solidus_core
solidus_api
solidus_frontend
solidus_backend
solidus_sample

# docker-compose buildの実行

```ruby:ターミナル
$ docker-compose build
```

docker環境の場合、通常は上記コマンドでbundle installができるはずなんですが、何故かできなかったため、下記実行。

```ruby:ターミナル
$ docker-compose exec app bundle install
```

# solidus用に必要なものをインストールする

```ruby:ターミナル
①　$ docker-compose exec app bundle exec rails generate spree:install

②　$ docker-compose exec app bundle exec rails generate solidus:auth:install

③　$ docker-compose exec app bundle exec rails railties:install:migrations

④　$ docker-compose exec app bundle exec rails db:migrate
```

しかし、①を実行すると下記エラー発生。。。

```ruby:エラー文
Running via Spring preloader in process 279
Could not find generator 'spree:install'.
Run `bin/rails generate --help` for more options.
```

## 試してみたこと

### １．rubyのバージョン変更
2.7.1→2.7.2に変更したら上手くいったという記事を見て試してみましたが、駄目でした。。

### ２．キャッシュクリア

```
docker-compose exec app rm -rf tmp/cache/bootsnap-compile-cache
docker-compose exec app rm -rf tmp/cache/bootsnap-load-path-cache
docker-compose exec app bundle clean --force
```

こちらも変化なし。


# ①のエラーの解決策

```
$ docker-compose exec app bundle exec rails generate spree:install
```

ではなくて・・・・・

```
$ docker-compose exec app bundle exec rails g solidus:install
```

と実行したら成功しました！！

エラー文に、「Run `bin/rails generate --help` for more options.」
つまりhelpオプションをつけて実行してみて。と書かれていたので試してみましたが、すぐ解決したので、まずはエラー文に忠実に従ってみるのがいいということが、良く分かりました(^_^;)

```
**************************************************
We added the following line to your application's config/routes.rb file:

    mount Spree::Core::Engine, at: '/'
**************************************************
Solidus has been installed successfully. You're all ready to go!

Enjoy!
```

# 最終的に
デザインが反映されませんでした。。。
もしかするとrails6以降Webpackerでの管理になったが関係しているかも。。。
この記事を見ていただいた方は、rails6以前のバージョンで行うことをおすすめします。


![スクリーンショット 2021-08-19 16.01.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985164/15036848-d385-52c2-23cf-c46920469818.png)


![スクリーンショット 2021-08-19 16.01.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985164/9c788f7c-88fe-d8de-4c28-a793e7ec2007.png)


▼参考にさせていただいた記事

https://qiita.com/ARTS_papa/items/1ee6b6434b9bb75c5d01
EC2にRDP接続できなくなった時の対応方法

# はじめに
EC2のWindows Serverを使用している場合、RDPで接続して設定やらなんやらすると思いますが、一つ設定を間違えるとRDP接続ができなくなることがあります。

Windows Serverにはファイアウォール機能としてWindows Defenderファイアウォールがあります。

EC2でシステムを構築しているのであればSGでポート単位で通信が制御できますし、個別にウイルス対策ソフトがインストールされているのであれば、Windows Defenderファイアウォール機能は必要ない状況が出てきます。

その場合は機能自体を無効化することがあると思いますが、今回はその操作を間違えてRDP接続ができなくなってしまいました。
その対応方法を書いていきます。

# 事象
サーバーマネージャーから手動で各ネットワークのファイアウォールを無効した状態にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/143781df-0d46-f641-9b9b-fdda3b6f59ff.png)

この状態から間違えて画面の一番上にある「設定の復元」を押下してしまったところ、RDP接続が切れて再接続ができない状態になってしまいました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/89527f1d-3167-fdc2-f90b-d1fbefcfce4f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/be913b95-279e-f3f1-eb94-2e465a8a09b6.png)

# 対応
以下の記事を参考に、SSMオートメーションドキュメントのAWSSupport-TroubleshootRDPを使用して、SSM経由でファイアウォールを無効化しました。
https://dev.classmethod.jp/articles/disable-nla-with-awssupport-troubleshootrdp/

## 手順
まずはAWS Systems Managerダッシュボードに移動し、変更管理の自動化を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/191ad9e3-0549-6766-425f-eaacd9e0b324.png)

表示された画面のオートメーションの実行を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/6b13c43e-c8e8-e2d1-ba35-aa9c390a7912.png)

真ん中の検索欄で「AWSSupport-TroubleshootRDP」を検索し、1つだけドキュメントが表示されることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/b8192ef3-8832-fb6f-a121-80a920c4b9a9.png)

ドキュメントを選択し、次へを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/e6fa7353-b241-5dbc-f140-09140423d62c.png)

詳細パラメータの入力画面に遷移するので、まずはシンプルな実行を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/12f36fc8-b5ec-d5a4-4e8e-2b673e846425.png)

入力パラメータの「インタラクティブなインスタンスピッカーを表示する」を選択し、表示されたEC2インスタンスを選択します。
※RDP接続できなくなったEC2であること
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/7e530c2d-c89b-6ca4-86db-2bf67fd3f3d3.png)

パラメータが複数ありますが、このうちFirewallの設定だけをCheckからDisableに変更します。
それ以外は何も変更しません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/a8efb270-2d6d-8f42-8c62-c17cc245e911.png)

最後に実行を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/07534999-3fab-9a54-7c3a-c5ed33204fa7.png)

設定した内容がすぐに実行されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/18ace535-9781-0591-ef21-87f7a4681f86.png)

表示された画面でどこまで実行中と実行結果がわかるようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/be3c434c-c61f-6400-c924-d2478a9e6711.png)

全体的なステータスが成功になっていればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/631e0042-cba0-7882-a69f-84d5003a619b.png)

そのあとにRDP接続を実施したところ問題なくログインでき、ファイアウォールは全て無効化されていることが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/1ec8f934-967c-cddf-dfc0-5259630a4e3a.png)

# おわりに
RDP接続ができなくなると結構焦りますが、一つ一つ確認しながら対応すると解決することがあるので、諦めずに方法を探してみましょう。
お名前.comのレンタルサーバーからNetlifyに移行した時のMXレコード設定


#初めに
お手持ちのドメインをNetlifyに設定する方法はたくさん記事があるので省略。
今回書くのはNetlifyにネームサーバーを設定すると、お名前.comのメールが受信できなくなった時にやったことです。

#NetlifyにMXレコードを追加する。
Netlifyのトップページから`Domains`をクリック
![ドメイン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975119/665266b0-de15-fc08-c83f-3e95e2101882.png)

ドメインを選択後、DNS settingsの`Add new record`をクリック
![screenshot-app.netlify.com-2021.08.19-15_13_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975119/4eece938-6b71-7572-79b2-e6a49019310d.png)

そして参考画像のように入力
![screenshot-app.netlify.com-2021.08.19-15_17_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975119/1303c54c-8f68-83bb-2719-80d6f4dd1d03.png)

valueは各々違うので要確認。

##Valueの確認方法
お名前.comはmxレコードを公開していない(?)みたいなのでネームサーバーを移行する前にnslookupでmxを確認した。

###手順
コマンドプロンプトを開き以下のように叩くと確認できた。

```console:コマンドプロンプト
C:\Users\hogehoge>nslookup
> set type=mx
> set timeout=20
> ドメイン.
> ドメイン名 MX preference = 10, mail exchanger = mx〇〇.gmoserver.jp
```

以下引用
>コマンド プロンプトで「nslookup」と入力し、Enter キーを押します。このコマンドによって、Nslookup セッションが開きます。

>「set type=mx」と入力し、Enter キーを押します。

>「set timeout=20」と入力し、Enter キーを押します。既定では、Windows DNS サーバーの再帰的な DNS クエリのタイムアウト制限は 15 秒です。

>MX レコードを特定するドメインの名前を入力します。たとえば、fabrikam.com ドメインの MX レコードを特定するには、「fabrikam.com.」と入力して Enter キーを押します。

 >注意
>末尾のピリオド (   .   ) は、FQDN を示します。 末尾にピリオドを使用することで、ネットワークで構成されている既定の DNS サフィックスが、意図に反してドメイン名に追加されることを防ぎます。

#最後に
反映されるまで結構時間がかかるのでメールがこなくて焦ったが、しばらく待つとしっかりと受信できるようになった。
nslookupで確認できない場合はお名前.comのコントロールパネルのサーバー情報から`pop**.gmoserver.jp`や`smtp**.gmoserver.jp`の後ろの数字をValueに記載するといけるかも？
HEROKUをdockerで使用し、webサービスをデプロイするまでの流れ

備忘録的に残しておく。
ここではherokuへの登録は済んでいる前提で進めていく。
また今回は省略しているがコマンドを実行する際にアプリ名を求められる事がある。
その際は以下を追加してコマンドを実行する。

```
--app アプリ名

//例
$ heroku container:push web --app アプリ名
```

###目的のフォルダーに移動し、heorkuにログインする
```
$ heroku login
```

###herokuのコンテナーにログインする
```
$ heroku container:login
```

###ファイル、ディレクトリーに対する実行権限を付与する
```
$ heroku chmod +x ディレクトリ名
```

###heroku上にアプリを作成する
```
$ heroku create 
```

###herokuの環境変数を確認
```
$ heroku config | grep CLEARDB_DATABASE_URL
```
このコマンドで以下のような環境変数の表示が行われる

```
CLEARDB_DATABASE_URL: mysql://[ユーザー名]:[パスワード]@[ホスト名]/[データベース名]?reconnect=true
```

###herokuの環境変数を設定
```
$ heroku config:set [環境変数名]=[登録する値]
```

###イメージをビルドし、herokuのコンテナーレジストリにプッシュする
```
$ heroku container:push web
```

###先ほどプッシュしたイメージをアプリにリリースする
```
$ heroku container:release web
```

###サイトを開く
```
$ heroku open
```
FastAPIのリモートデバッグ設定（VSCode、debugpy）

# 記載内容
FastAPIについて、VSCodeとdebugpyを使ったリモートデバッグ方法を記載します。

FastAPIは下記のように起動します。これでどうやって、main.pyにリモートデバッガーを接続できるのか迷ったので、記録を残します。

https://fastapi.tiangolo.com/ja/

```
uvicorn main:app --reload
```

# FastAPIの起動方法

単純にuvicornをモジュールとして実行する形で、main.pyをリモートデバッグできました。


```
python -m debugpy --listen 0.0.0.0:5678 --wait-for-client -m uvicorn main:app --reload
```

# VSCodeのlaunch.jsonの設定

通常通り設定すればOKです。


```json
{
    "version": "0.1.0",
    "configurations": [
        {
            "name": "FastAPI Remote Debug",
            "type": "python",
            "request": "attach",
            "port": 5678,
            "host": "localhost",
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}",
                    "remoteRoot": "/hogehoge"
                }
            ]
        }
    ]
}
```
GAS 基礎編③　メモ

ドットインストールでGASの勉強をしています。
自分用にコードをメモ。

## Googleフォームと連携する

```javascript
function sendTask(e) {
  MailApp.sendEmail('hoge@gmail.com', 'タスクが追加されました', e.namedValues['Task']);
}
```

上記とは別に、トリガーを設定する。
* 実行する関数　→sendTask
* イベントのソース →スプレッドシート
* イベントの種類　→フォーム送信時

とすると、タスクに自動追加されメールが届く！

## Web上で公開

```javascript
function doGet() {
  var template = HtmlService.createHtmlOutputFromFile('index');
  return template.evaluate()
}
```
## TaskをWEB上で公開

```html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <h1><?= title ?></h1>
    <ul>
      <? for (var i = 0; i < tasks.length; i++) { ?>
       <li><?= tasks[i] ?></li>
      <? } ?>
    </ul>
  </body>
</html>
```

```javascript
function sendTask(e) {
  MailApp.sendEmail('hoge@gmail.com', 'タスクが追加されました', e.namedValues['Task']);
}

function doGet() {
  var template = HtmlService.createTemplateFromFile('index');

  template.title = 'MyTaskApp';
  template.tasks = getTasts();



  return template.evaluate()
}

function getTasts() {
  var sheet = SpreadsheetApp.getActiveSheet();
  return sheet.getRange(2, 2, sheet.getLastRow() - 1, 1).getValues();
}
```

## Task追加フォームへのリンクを付ける

```html
<p>→ <a href="https://docs.google.com/hoge/viewform">タスク追加用フォームへのリンク</a></p>
```

## Taskアプリの完成！

```javascript
function sendTask(e) {
  MailApp.sendEmail('hoge@gmail.com', 'タスクが追加されました', e.namedValues['Task']);
}

function doGet() {
  var template = HtmlService.createTemplateFromFile('index');

  template.title = 'MyTaskApp';
  template.tasks = getTasts();



  return template.evaluate()
}

function getTasks() {
  var sheet = SpreadsheetApp.getActiveSheet();
  return sheet.getRange(2, 2, sheet.getLastRow() - 1, 1).getValues();
}

function sendReport() {
  var to = 'hoge@gmail.com';
  var subject = 'タスク一覧';
  var url = 'https://script.google.com/macros/s/hoge/exec';
  var body = getTasks().join('\n') + '\n\n' + url;
  
  MailApp.sendEmail(to, subject, body);
}
```

#### これで、タスクのレポートがgmailに届くようになりましたッ
CURL を Windows 環境でスタティックライブラリとしてビルドする

# はじめに

CURL を複数環境で使用する機会があったのでソースコードからビルドする事にしたので備忘録として残しておきます。

# 環境構築
## インストールが必要なもの
- Visual Studio
    - バージョンは特に気にしていません。記事を執筆した時点では Visual Studio 2022 preview 3 を使用しています。
- nmake
    - Visual Studio 同梱されているものを使用します。
    - 『ツール > コマンドライン > 開発者コマンドプロンプト』で nmake のパスが通ります。
- Perl
    - [Strawberry Perl](https://strawberryperl.com/) を使用 ([ActivePerl](https://www.activestate.com/products/perl/downloads/) でも使用できると思います)
    - コマンドプロンプトで参照できるように PATH に追加 (例：C:\Strawbeery\perl\bin)
        - Perl を利用するのは一部ですので Perl (command line) を使用しても問題ありません。

## 必要なライブラリ
- OpenSSL
[OpenSSL](https://www.openssl.org/) は [Github](https://github.com/openssl/openssl) からダウンロード

# ライブラリのビルド
## OpenSSL のビルド

```shell
# OpenSSL を解凍したディレクトリ直下で実行

# 64bit 版
# prefix はインストール先を指定するが絶対パスの必要がある
# NASM は使用しない、スタティックライブラリで構成
perl Configure VC-WIN64A --prefix=%CD%\x64 --openssldir=%CD%\ssl no-asm no-shared
# OpenSSL のビルド
nmake
# OpenSSL のテスト (かなり長い30分以上かかった)
nmake test
# OpenSSL のインストール (--prefix で指定したフォルダにコピーされる)
nmake install
```

※```no-asm``` を指定せずにビルドすると AES で最適化されたアセンブラを使用できるっぽいが ```NASM``` を Windows 環境にインストールする手順が非常にややこしかったのでアセンブラ最適化は使用せずにビルドします。

上記のビルドが完了すると OpenSSL を解凍したディレクトリ直下に ```x64``` または ```x86``` というディレクトリが作成され以下のようなディレクトリ配置が行われます。

```
x64 ┬─ bin
    ├─ html
    ├─ include
    │  └ openssl
    └─ lib
       └ libssl.lib
```

## CURL のビルド

```shell
# CURL を解凍したディレクトリ直下で実行

# 構成をビルド
buildconf.bat
cd winbiuld

# 64bit 版
# VS2022 => vc=17, VS2019 => vc=16
nmake /f Makefile.vc mode=static RTLIBCFG=static vc=17 MACHINE=x64
```

# ライブラリの使用

Visual Studio の『プロパティ > リンカー > 入力 > 追加の依存ファイル』で以下のファイルを追加する。

- Ws2_32.lib
- crypt32.lib
- Wldap32.lib
- Normaliz.lib
- libcurl_a.lib
- libssl.lib

# さいごに

CURL のビルドでハマったのは OpenSSL で NASM を使おうとしたときです。
NASM のビルドが思った以上に面倒＆分からない事が多すぎて断念しました。