OmniAICreator/Qiita-1.07M huggingface dataset:
javascript・jQueryでES6のアロー関数を使ったときの引数について

アロー関数を使ったときによく引数を忘れるため、自分用のメモとして記事にしました。





##forEachメソッドの引数
###配列の場合
```javascript:javascript
const array1 = ['a', 'b', 'c'];
array1.forEach((element) => { 
console.log(element);
});
//結果
// "a"
// "b"
// "c"
```

###連想配列の場合
```javascript:javascript
const hoge = ['key0':'value0','key1':'value1','key2':'value2'];
Object.keys(hoge).forEach((key)=>{
 console.log(key);
})
//結果
// "key0"
// "key1"
// "key2"
```

##eachメソッドの引数
```html:html
<ul>
 <li>テキスト1</li>
 <li>テキスト2</li>
 <li>テキスト3</li>
</ul>
```

```javascript:jQuery
$('ul li').each((index, element) => {
  console.log(index); // 0~2の数字
  console.log(element); // liのエレメント情報
});
```

##addEventListener
```html:html
<button>ボタン</button>
```

```javascript:jQuery
document.querySelector('button').addEventListener('click',(event) => {
  console.log(event.currentTarget); // buttonのエレメント情報
});
```

##onメソッド
```html:html
<button>ボタン</button>
```

```javascript:jQuery
$('button').on('click',(event) => {
  console.log(event.currentTarget); // buttonのエレメント情報
});
```
Vue3でFontAwesomeを使ってみた

今回紹介するのはvue3でのFontAwesomeの利用方法です。
Vue3という新しいバージョンがリリースされてからまだ間も無く、参考記事がほとんどなかったため、
Vue3でFontAwesomeを利用するのに少し苦労しました。
皆さんの参考になれば幸いです。

#FontAwesomeのインストール

作成したprojectに移動してインストールします。
この時注意が必要なのはvue-fontawesomeをインストールする際に末尾に@prereleaseを入れないとvue3では動きません。

```
$ npm install --save @fortawesome/fontawesome-svg-core

#アイコンをインストール
$ npm install --save @fortawesome/free-solid-svg-icons

#Vue3で使用するためにインストール
$ npm install --save @fortawesome/vue-fontawesome@prerelease
```

アイコンは下記タイプがあります。必要に応じてインストールしてください。
・Solid : 内塗り
・Regular : 線（内塗りの逆）
・Light : 細い線（有料プランのみ）
・Brands : ロゴ等

```
$ npm install --save @fortawesome/free-regular-svg-icons
$ npm install --save @fortawesome/free-brands-svg-icons
$ npm install --save @fortawesome/pro-regular-svg-icons
```

#main.jsに追加
Vueで使えるようにFontAwesomeをインポートします。
使いたいアイコンごとにインポートしてライブラリに追加します。

```javascript:main.js
import { createApp } from 'vue'
import App from './App.vue'
import './index.css'
//ここから追加
import { library } from '@fortawesome/fontawesome-svg-core'
import { faLeaf } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'

library.add(faLeaf)
//ここまで追加

var app = createApp(App)
//コンポーネントの追加
app.component('fa', FontAwesomeIcon )
app.mount('#app')
```

#アイコンを使用
faタグを追加して、アイコン名を指定します。

```html:src/components/fontAwesome.vue
<template>
    <div>
        <fa icon="leaf" />
    </div>
</template>
```
#SolidではなくBlandsのアイコンを使用する場合

Solidではなく、Blandsのアイコンを使用する場合はタグの書き方が少し違います。

まずはBlandsのアイコンをインストール

```
$ npm install --save @fortawesome/free-brands-svg-icons
```

main.jsは上記と同様に追記。

```javascript:main.js
import { faFacebook } from '@fortawesome/free-brands-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'

library.add(faFacebook)
```

Brandsのアイコンの使用する際、prefixを指定する必要があります。

```html:src/components/fontAwesome.vue
<template>
    <div>
        <fa :icon="{ prefix: 'fab', iconName: 'facebook' }" />
    </div>
</template>
```

#参考
[リンク]https://www.npmjs.com/package/@fortawesome/vue-fontawesome
[リンク]https://qiita.com/kurararara/items/d76776a7dc2d763a068b


もし何か指摘事項等ありましたら、コメントして頂ければ幸いです。
PHP記述の基本

Udemyで学んだPHPの内容をここに記載します。

初心者が学んだ内容なので、誤りがあればご指摘いただければ幸いです。（ただし、優しく指摘をお願いします。）

PHPの記述方法の基本
<pre>
<?php
//ここにコードを書く
?>
</pre>
expo eject後にAndroidが起動しない

```sh
$ expo eject
```

実行後、なぜかAndroidで起動しなくなった。

![chrome-android-buzzvideo-stop-error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42540/982b38ad-b7e1-a401-d71a-afffaa12a9fa.png)

## 原因
差分を順に確認してみると、

```
android/app/src/main/res/drawable/splashscreen_image.png
```

を削除すると起動することがわかった。

## 解消法
この場合、

`android/app/src/main/res/drawable-*` という名前の各ディレクトリへ `splashscreen_image.png` をコピーすれば治る。

## より詳細に
どうやら原因はAndroidバージョンに合ったディレクトリ（ `drawable-*` ）内にスプラッシュ画像が必要なのに、存在していないから。らしい。

まず、各画像はクオリティに合わせて以下のようなディレクトリに分けられている。

* `android/app/src/main/res/drawable-xhdpi/`
* `android/app/src/main/res/drawable-xxhdpi/`
* `android/app/src/main/res/drawable-xxxhdpi/`

が `expo eject` 直後、 `splashscreen_image.png` は
`android/app/src/main/res/drawable/` にしか存在していない。

最近のAndroidバージョンではハイクオリティな画像を参照しようとして `android/app/src/main/res/drawable-xxhdpi/` 内の画像を参照しようとするので、そこに求めている画像がないとクラッシュの原因となる。
らしい。

cf. https://stackoverflow.com/questions/40835514/android-canvas-drawing-too-large-bitmap/41635904#41635904

公式ドキュメントにも乗っていなかったので結構詰まった。。。
以上。
Salesforce Platform Developer I：AuraとLWCの実現方法差異

# Aura
## MVCC動作モデル
**• Model：** SObject（標準またカスタムオブジェクト）
**• View：**  Component Markup（Component、Style）
**• Controller：** JavaScript Controller（AuraのController、Helper）
**• Controller：** Apex Controller（clsファイル、抽出データ条件追加また、エラー処理追加したい場合作成要）
具体的なソースは下記リンク参照

https://qiita.com/xuwenzhen/items/a5c8be8caba4f6a4ddd0

## Aura構成
**• Component** :HTMLをベースにLightningタグをマークアップ
**• Controller** :JavaScriptでアクションを記述
**• Helper** :JavaScriptで横断的なビジネスロジックを記述
**• Style** :コンポーネントのCSSを定義
**• Documentation** :コンポーネントの使用方法を定義
**• Renderer** :レンダリングフェーズにおける特殊な挙動を定義
**• Design** :アプリケーションビルダーでの設定項目を定義
**• SVG** :アプリケーションビルダー上のアイコンを定義
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/610acf4f-e336-9375-d19a-887b90cb9d51.png)

ファイル名：大小文字区分しない。

# LWC
## LWC構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/92dccc9f-889f-8d97-19a9-d6910ec0cc9a.png)
ファイル名：ファイル名頭文字は小文字、
クラス声明：頭文字は大文字
## 上下階層関係
①.tile: 個々の品目を表示します。
②.list: タイルを配置します。
③.detail: タイルがクリックされると品目の詳細を表示します (作成した bikeCard に類似)。
④.selector: すべてのコンポーネントが含まれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/b8b7754c-52e2-0e36-8318-3c98291a7cb9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/07502d9c-4ad0-1988-e354-cdb67b33b8ab.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/522ef384-9a31-307a-24c9-9d99dfda4f7e.png)
おうちハッカソン2に出場して3日間でReact/Djangoで計算ゲームを作った話

外出出来ないGWなので、ハッカソンデビューしてみました。
3日間で作り切ることで自身の成長にもなり、
参加者の皆さんの開発への姿勢やプロダクト、技術のレベルの高さを体感でき非常に勉強になりました。

自分@tanosugi の簡単なプロフィールは

* 昔Visual C++使ってバイトしてたが暫くプログラミングを離れていた
* 個人開発をしてみたくなり、1年前からUdemyでReact、Django、AWS等を勉強
* ポートフォリオを一つ作成中で8割出来たところ

という感じです。

# おうちハッカソン2
* 期間は3日間で、チームで作るもよし、個人で作るもよし、勉強会するもよし、最後の発表会で各自10分間で成果を共有しました。昨年に続き二回目の開催なのでおうちハッカソン2です。

* テーマ：みんなで楽しめる何か
* スケジュール：
5/3 10:00  自由に開発開始、発表会まではSlackで開発状況を自由につぶやく
5/5 17:00  発表会、投票して賞を発表
5/5 20:00  懇親会

https://connpass.com/event/211876/

# 作成したもの：計算ゲーム
* 足し算、引き算、掛け算、割り算のどれかを選び、10問回答するという非常に単純なゲームです。
* Webアプリですが、スマホのサイズに合うように作ってあり、PCでもスマホでもブラウザで遊べます。
* 対戦ありを選ぶと登録、対戦IDの共有を経て対戦が始まります。対戦中は相手の進捗(何問終わったか)も表示されます。

* Demo（音が出ます）: http://calcgame.s3-website-ap-northeast-1.amazonaws.com/
Github：https://github.com/tanosugi/calcgame

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639092/ff1f04dd-f59c-9c48-6895-c06b824d3d62.png)

### 作成目的
* 楽しみながら子供が勉強できるものを作成したい
* プログラミングを勉強すれば何が作れるかを子供に理解してもらう
* 計算ゲームで対戦できるものが少ないので、自分で作ろう
* 公園や友達とのLine ビデオ通話でも子供同士が対戦できるのでは
* 1台のスマホを2人で操作する対戦アプリ、コンピューターと対戦するアプリはあるが通信対戦するアプリは見当たらない

### 使用技術
* FrontendはReact/Typescript, Material UI, react router等を使いました。
* BackendはDjango、仮想環境はpoetry、データベースはdocker上でPostgreSQLを使いました。
* FrontendとBackendの間はGraphqlで通信しています。
* デプロイはAWS CLI経由、S3とEC2に置きました。EC2上で開発しコード管理はGithubです。
* CIは開発期間3日間なので無しです。簡単なシェルスクリプトを走らせるとデプロイできるようにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639092/c945f237-7bd2-e5d8-0ab1-4e39ab4d2b4d.png)


# 作成スケジュール
* 3日間ずっと作っていた感じです。
* 期限が区切らた環境で必死に目指したものを作り切ったので3日間で成長した実感があります。去年は5日間だったようですが、自分としては3日間がちょうどよい期間でした。

* 1日目 午前：大まかなデザインとデータ構造を設計
1日目 午後-夜：バックエンドを作成
* 2日目 午前-夜：フロントエンド
* 3日目 午前-16:00：フロントエンドとバックエンドの繋ぎこみ
3日目 16:00-17:00：発表原稿準備
3日目 17:00  発表会、投票して賞を発表
3日目 20:00  懇親会

###1日目午前を終えて大会参加者つぶやき用のSlackに投稿したデザインとデータ構造
![計算ゲームのデザインのスクリーンショット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639092/4e7f37ec-557b-9b93-f699-8cbe45bcffd6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639092/c25beb75-0178-adb6-ad03-0b2f7a3e80d7.png)





# 参加して得られたもの
* 参加者の皆さんの発表を聞き自分もまだまだ勉強しなくてはと思いました。
私はこの1年で学んだ一番得意分野の言語のみを使ったのですが、普段と違う技術に挑戦しながら3日間でプロダクトまでもっていったグループも多かったのは驚きでした。
* 音声入力チャット、自然言語処理、ブラックジョークの入ったゲーム、2年かけて制作中の本格ゲームアプリ、と非常に幅広いテーマ、様々な技術で面白かったです。

* 私が作成した計算ゲームの相手の進捗(今何問終わったか)の表示は「Graphql経由、Django経由、SQLに自分の進捗を置きに行って、それをゲーム番号をキーに相手の進捗を取り出す」という方法を取りました。
永続化する必要もなく短時間で通信するので、少し邪道だったようです。
一般的には「WebSocket使うかWebRTCでP2P」を使うというのを発表時に教えていただきました。

* 懇親会では、「宣言的UIでないUIとは何か」、「ハッカソンでテストを書くべきか」、「コードフォーマッタはローカルとCIのどちらで走らせるか」、「ホームページ作成を請け負うなら適正な単価は」等を話せたのも、普段独学で進めている自分としては非常に楽しい時間でした。

* ご一緒させていただいた皆様、ありがとうございました。
rails 6.1.3.2の` ActionView::Template::Error: Please use symbols for polymorphic route arguments.`が発生する理由と対処

rails 6.1.3.2以降で`ActionView::Template::Error: Please use symbols for polymorphic route arguments.`場合の原因と対処について

# 原因
脆弱性[CVE-2021-22885](https://github.com/advisories/GHSA-hjg4-8q5f-x6fm)の対応の影響で既存のソースコードでrails 6.1.3.2, 6.0.3.7, 5.2.4.6, 5.2.6にバージョンアップすると既存のコードで`ActionView::Template::Error: Please use symbols for polymorphic route arguments.`が発生する可能性があります。

# 脆弱性対応について

[CVE-2021-22885](https://github.com/advisories/GHSA-hjg4-8q5f-x6fm)のセキュリティーパッチです。

`redirect_to`や`polymorphic_url`など動的にURLを生成するヘルパーメソッドで意図しないURLが作成される可能性があり脆弱性になるとの事です。

See: https://weblog.rubyonrails.org/2021/5/5/Rails-versions-6-1-3-2-6-0-3-7-5-2-4-6-and-5-2-6-have-been-released/

## 脆弱性に対するrailsの対応
`polymorphic_url`の引数`record_or_hash_or_array`にStringのArrayを渡すような実装があると例外`ActionView::Template::Error: Please use symbols for polymorphic route arguments.`を発生させる様になりました。

```ruby
def handle_list(list)
  record_list = list.dup
  record      = record_list.pop

  args = []

  route = record_list.map do |parent|
    case parent
    when Symbol
      parent.to_s
    when String
      raise(ArgumentError, "Please use symbols for polymorphic route arguments.")
    when Class
      args << parent
      parent.model_name.singular_route_key
    else
      args << parent.to_model
      parent.to_model.model_name.singular_route_key
    end
  end
```
See: https://github.com/rails/rails/blob/c4c21a9f8d7c9c8ca6570bdb82d64e2dc860e62c/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb#L284-L303


## 修正PR
https://github.com/rails/rails/commit/c4c21a9f8d7c9c8ca6570bdb82d64e2dc860e62c

# 影響
`polymorphic_url`は`form_with`などたくさんのメソッドの内部で使用されているので例えば以下のようなroutingがあった場合に、

```ruby:config/routes.rb
namespace :admin do
  resources :users
end
#=> /admin/users/
```

このパスに対して`form_with`ヘルパーを使用する場合に`model`引数の配列に文字列型を指定するとエラーが発生します。

```
<%= form_with model: ['admin', user] do |f| %>
#=> ActionView::Template::Error: Please use symbols for polymorphic route arguments.
```

# 対処方法

上記の例の場合は`model`引数の配列に指定していた文字列をシンボル変更します。

```diff
- <%= form_with model: ['admin', user] do |f| %>
+ <%= form_with model: [:admin, user] do |f| %>
```
Vuetify - ディープセレクタと v-select の余分な空白

# やりたいこと

* Vuetify でディープセレクタを使う
* v-select の余分な空白を削除する

## サンプル

```vue:sample.vue
<template>
  <v-select class="select-input-none" />
</template>

<style scoped>
.select-input-none >>> .v-select__selections input {
  width: 0;
}
</style>
```

# ディープセレクタとは

https://vue-loader-v14.vuejs.org/ja/features/scoped-css.html

公式の説明を見ても、Webアプリ開発初心者の私としてはちんぷんかんぷん
親から子のスタイルを上書きするのは何となく理解できるけども...
ネットで調べながら半日以上かかって、やっと理解できた。

## 覚え方

`親コンポーネントに適用するスタイル名` >>> `上書きしたい子タグのスタイル名`

名前をこんな感じにしてCSSを設定すると、後半で指定したスタイルを上書きでるよう。
サンプルで言うと「`select-input-none`を適用したコンポーネント以下のタグ」で
「`v-select__selections`が適用されたタグの子の`input`タグのスタイル」を上書きするイメージ。

## Scss

[Scss](https://qiita.com/nchhujimiyama/items/8a6aad5abead39d1352a) を使うとこんな感じ (2021/05/08 追記)

```vue:sample_scss.vue
<template>
  <v-select />
</template>

<style lang="scss" scoped>
::v-deep .v-select__selections {
  input {
    display: none;
  }
}
</style>
```

（親コンポーネントのクラス指定をしなくてもいけた）

# v-select の余分な空白

![適用前](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/765818/b719acf6-d030-0987-0c87-6cbb27d56dd4.png "適用前")

数字1文字だけ表示して詰めたいのに、デフォルトだと謎の空白がある...
ネットで調べると、[英語のサイト](https://github.com/vuetifyjs/vuetify/issues/6275#issuecomment-546621371) がヒット！

`.v-select__selections input { display: none }`

これを設定するといいらしい。
ただ、実際に  設定しまうと、キーボードの上下入力ができなくなる。
なので、`display: none`ではなく`width: 0`を設定するのが吉。[（って書いてある）](https://github.com/vuetifyjs/vuetify/issues/6275#issuecomment-580956741)

![修正後](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/765818/54fd9ada-cd01-3965-cad2-ebfacc962f8c.png "修正後")

やったね:v:
手軽にMicrosoft Build of OpenJDKを触る方法

2021年4月6日にMicrosoftがOpenJDKをビルドして提供するという発表がありました。以下、主な情報です。

Bruno Borgesさんによる記事「[Announcing Preview of Microsoft Build of OpenJDK](https://devblogs.microsoft.com/java/announcing-preview-of-microsoft-build-of-openjdk/
)」
![スクリーンショット 2021-05-06 23.47.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/e7adad6d-ccba-1007-5ef7-6efe0cad9daa.png)

「[Microsoft Build of OpenJDK](https://www.microsoft.com/openjdk)」のページ

![スクリーンショット 2021-05-06 23.48.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/0617d497-7f1f-5cf8-6449-584938ab7201.png)

Microsoft Build of OpenJDKを試すには、上記のページからJDKをダウンロードしてインストールする他、AzureのCloud Shellを使う方法があります。現時点ではDockerイメージが提供されていないため、Cloud Shellを使うのが一番手軽な気がします。


以下動画のようにデフォルトでインストールされています。mavenも入っているので（前から入ってましたっけ...？）簡単なプログラムであればCloud Shell上でも作れそうです。もちろんJShellも動くので、ちょっとした学習で使う分には（インストールの手間もかからず）便利だと思います。

![ezgif-1-4b56669d319f.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/0085a71b-1f2a-98be-cb38-c03e6c72d714.gif)
繰り返し処理

# each()
- 繰り返し処理を記述する関数



# HTML要素に対しての構文
```php
HTML要素.each(function(index, element) {
    //繰り返し処理を記述する
})
```
```php
$('li').each(function(index, element) {
    console.log(index + ': ' + $(element).text());
}) // 0: サンプル１
   // 1: サンプル２
   // 2: サンプル３
```
# 配列に対しての構文
```php
HTML要素.each(function(index, value) {
    //繰り返し処理を記述する
})
```
```php
const array = [4,7,1,8,5];
$.each(array, function(index, value) {
    console.log(index + ': ' + value);
}) // 0: 4
   // 1: 7
   // 2: 1
   // 3: 8
   // 4: 5
```
# オブジェクトに対しての構文
```php
$.each(obj, function(property, value) {
    console.log(property + ': ' + value);
})
```
Exiting because of an unresolved conflict. 解決方法

今回はターミナルでプッシュができない事態が発生し、その解決方法として色々なコマンドを叩いていたのですが、その中で`git merge origin/main`を叩いた際に`Exiting because of an unresolved conflict.`が発生したので、その解決方法をご紹介します！

#エラー内容

```
$ git merge origin/main
error: Merging is not possible because you have unmerged files.
hint: Fix them up in the work tree, and then use 'git add/rm <file>'
hint: as appropriate to mark resolution and make a commit.
fatal: Exiting because of an unresolved conflict.
```

どうやらコンフリクト起きているみたいです。
`コンフリクト`：「衝突」の意味で、ファイル上で「自分の作業」と「他人の作業」が重複してしまっている状態のことです。

#解決手順
解決までの手順は以下の通りです！
1.`git log --oneline --graph --all`でブランチの一覧を取得し確認
2.`git status`で現在の状態確認
3.表示された赤字で指摘されているファイルをadd、commit
4.再度`git status`で赤字が消えたことを確認
5.コミットしたファイルをpush

###1.ブランチの一覧取得
`git log --oneline --graph --all`を叩くと、下記の`cafb650`部分でブランチが枝分かれしてしまっているのが確認できます。

```
$ git log --oneline --graph --all
* 9bf9dc2 (HEAD -> main) [add] デザイン実装
| * cafb650 (origin/main, origin/HEAD) [add] デザイン実装
|/  
* b831743 [add] 在庫登録の項目追加
* 60ebefa [add] 在庫検索機能のコントローラ追加
* df3a0dc [remove] 在庫一覧表示のテンプレートファイルを削除
* 060eeaf [add] 在庫検索機能を追加
* c37030a [fix] 在庫の編集内容確認画面にアクセスできない不具合の修正
```

###2.git statusで状態確認
`git status`を叩いたら、何かのメッセージとパスが表示されましたね。
今回赤字で表示されたのが、`Unmerged paths:`の下に表示された2つのパスです！

この最初のメッセージでは、`ブランチが分岐しています。一つ一つ異なるコミットが存在しています。`と書いてあり、下の指摘されたパスは、`マージされていないパス`として赤字で表示されています。

```
$ git status
//ブランチが分岐していると指摘されている
On branch main
Your branch and 'origin/main' have diverged,
and have 1 and 1 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

//マージされていないパスがある
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

//マージされていないパスが赤字で表示
Unmerged paths:
  (use "git add <file>..." to mark resolution)
	both modified:   resources/views/stock/list.blade.php
	both modified:   resources/views/stock/search.blade.php
```

###3.マージされていないパスをインデックスに追加・コミットする
では、マージされていないと赤字で指摘されたパスを`git add パス`でインデックスに追加します。
次に`git commit -m 'コミットメッセージ`でコミットします。

###4.再度git statusで状態確認
コミットまで完了したら再度`git status`で状態を確認します。
すると、今回は赤字が消えているのが確認できるかと思います！
そして、`mainブランチは最新です`というメッセージも表示されました。

```
$ git status
On branch main
Your branch is up to date with 'origin/main'.
```

###4.コミットしたファイルをリモートリポジトリに反映
最後に`git push origin main`でリモートリポジトリにプッシュして反映させます。
無事プッシュまで完了したので解決できました！


参考サイト
https://tea-programming.blogspot.com/2020/03/gitfatal-exiting-because-of-unresolved.html
GitHub Actionsで呼び出すPythonコード上で環境変数（Github Secrets）を使う方法

# やりたいこと
- GitHub ActionsのワークフローでPythonコードを呼び出す
- Public Repositoryなので、アクセストークン等をSecretsに隠したい

# 結論
※Secretsへの登録は多くの記事で紹介されていると思うので検索してみてください。

## ワークフロー側
```
- name: Run XXXXX.py # Pythonファイルの実行
        env:
          API_KEY: ${{ secrets.API_KEY }} # secretsに登録した環境変数
        run:
          python python/XXX.py # pythonフォルダに格納したXXX.pyを実行
```

## pythonコード側
```
import os
# secretsに登録した環境変数の呼び出し
API_KEY = os.environ.get("API_KEY ")
```

調べてもなかなか見つからなかったので、、、
誰かの助けになりましたら幸いです。
Qiitaの使い方

# Qiitaの使い方
Qiitaに記事を書く上で便利な機能やマークダウン記法に関することをまとめる。

## マークダウン
[Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
3Dキャラクターを追従するカメラとカメラアングルに応じた移動をする

https://www.youtube.com/watch?v=4HpC--2iowE
の動画をもとに三人称視点のカメラ移動、キャラクター移動を再現。
transformでの移動はObiropeがうまく動かないのでRigidBodyで移動させる必要があり対応させた。
//
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class move : MonoBehaviour
{
    Rigidbody rb;
    public float speed = 15.0f;
    public float turnSmoothTime = 0.1f;
    float turnSmoothVelocity;
    public Transform cam;
    public float jumpSpeed = 15.0f;
    // Start is called before the first frame update
    void Start()
    {
        rb = this.GetComponent<Rigidbody>();
    }
    void Update()
    {
        float x = Input.GetAxisRaw("Horizontal");
        float z = Input.GetAxisRaw("Vertical");
        Vector3 direction = new Vector3(x, 0f, z).normalized;
        rb.AddForce(direction * speed);
        float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
        float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
        rb.MoveRotation(Quaternion.Euler(0f, angle, 0f));
        Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
    }
}

・最後のAddForceにTime.deltaTimeをかけたらダメ

https://www.f-sp.com/entry/2017/09/06/181854
document.get~~~の違い

JavaScriptからHTML要素を変更したい時、まずその要素を取得すると思います。

しかしその要素を取得する方法は``getElementById``や``getElementsByClassName``など様々な方法があります。しかし、それらは若干返すものが異なり、いざ操作しようと思ったときに困ることがしばしばあります。

今回は、DOMで要素を取得したときに返す値についてまとめていきます。

## 1つ目 Elementオブジェクト

これが返ってくるものは
- ``getElementById``
- ``querySelector``
などがあります。

例えばこんなHTMLがあったとします。

```html
<body>
 <h1 id="title">タイトル</h1>
    <ul>
      <li class="list">リスト1</li>
      <li class="list">リスト2</li>
      <li class="list">リスト3</li>
   </ul>
</body>
```

そのHTML要素を取得するためのJSファイルがあるとします。

```js
console.log(document.getElementById("title"));
// => <h1 id="title">タイトル</h1>
console.log(document.querySelector("li"));
// => <li class="list">リスト1</li>
```

実際に取得するとこのように表示されます。これはHTMLオブジェクトであり、変数などに渡してあげればそのまま``addEventListner``などでイベント処理を書くことも可能です。

getElementByIdはIdを取得するがIdは一意のため、QuerySelectorは該当する1番目の要素を返すためこれが成り立ちます。

## 2つ目 HTMLコレクション

これが返ってくるものは
- ``getElementsByClassName``
- ``getElementsByTagName``
などがあります。

試しに``getElementsByClassName``で要素を取得してみます。(HTMLファイルは最初の物を参照します)

```js
console.log(document.getElementsByClassName("list")); 
//=> HTMLCollection {0: HTMLLIElement, 1: HTMLLIElement, 2: HTMLLIElement, length: 3, item: ƒ item()…}
```


HTMLコレクションを簡単に言うと要素の集合体です。この中に該当する要素が入っています。(今回だと``list``クラスを持つものです。)

このコレクションから要素を取得するにはindexやidなどで取得することが出来ます。

```js
console.log(document.getElementsByClassName("list")[0]); //=> <li class="list">リスト1</li>
console.log(document.getElementsByClassName("list")["middle"]); //=> <li class="list" id="middle">リスト2</li>
```

このように配列のようなHTMLコレクションから指定すればHTMLオブジェクトとして取り出すことが出来、イベント処理などが出来るようになります。

## 3つ目 NodeListコレクション

これが返ってくるのは
- ``querySelectorAll``
が主なメソッドです。

```js
console.log(document.querySelectorAll("li"));
//=>NodeList {0: HTMLLIElement, 1: HTMLLIElement, 2: HTMLLIElement, entries: ƒ entries(), keys: ƒ keys()…}
```

NodeListはHTMLコレクションとほぼ変わりません。強いて上げるならHTMLコレクションは動的でありNodeListコレクションは静的であることが挙げられます。複雑なDOM操作をしない限りそこまで気にする必要もないと思います。

## 結局どれで取得するのがいいの？

現状一番ベターなのは``getElementById``だと思います。最後に紹介した``querySelectorAll``などは非常に高機能ですが、その分低速になりやすいです。

逆に``getElementById``などは一意のIdを取得するのでとても高速です。

以上の事から対応できる範囲でgetElement.ByIdで処理して、それではきついような高度な取得をしたいときには``querySelector``などを使うのがオススメです。
readyイベント関数 （jQuery）

# $(function(){ })
- ブラウザがhead内のscriptを読み込んだとき、ブラウザはいったん予約状態になり、HTMLを最後まで読んだ後にjQueryを実行するようになる
- エラーを避けることができる


```php
$(function() {
//htmlがロードしたときに実行する処理
});
```

# 同義の記法
```php
$(document).ready(function{
 //処理
});
```
gitのエラー　error: remote origin already existsの解決方法

# エラー内容と解決方法
作成したアプリを自分のgitアカウントのリモートリポジトリにaddしようとしたところ、

```
$ git remote add origin https://github.com/gitアカウント/リポジトリ名.git
 error: remote origin already exists.
```
と表示され、うまくいかない。
[こちらの記事](https://qiita.com/hatorijobs/items/1cae1946656ece954c63)を参考にして、すでに存在しているリポジトリを削除し、再度addを行うと、うまくできました。
すでに存在しているリポジトリを削除するコマンドは以下の通り。

```
$ git remote rm origin
```
これで既存のリポジトリを削除して、再度addすることで、うまくいきました。
AWS console ログイン 簡単（ルートユーザーではなくIAMユーザーで入る）



メールアドレスでログイン

![2021-05-06_22h48_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501846/21e675e8-a05e-fa14-fe55-109b65c00ff3.png)

毎回セキュリティチェックで文字を入力する

![2021-05-06_22h48_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501846/67aa3ed7-d46b-bcaf-0e20-a841621fbfe0.png)

AWS console ログイン 面倒
簡単にしたい。

---

結論：IAMユーザーを作る。

アカウントID、ユーザー名、パスワードだけでログインできる。

![2021-05-06_22h54_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501846/ba0a5bd2-fa3a-8093-52ef-b32c68fc3cf3.png)

制限かかったアカウントなのでは？
全部使えるアカウントが欲しい

ポリシーで「AdministratorAccess」をチェック
※公式の5.-d.より


詳しいことは

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/getting-started_create-admin-group.html

https://www.pokete.com/aws/iam-basic
WPF-DataGridのヘッダーへのバインドはちょっと仕掛けが必要

 DataGridは要素の宣言のところにアイテムソースを記述する。
ヘッダーをバインドしたい先がDataGridのアイテムソースの下にいない場合、DataContextからのパスを指定しないといけない。
しかし、なぜか普通にはDataContextまで辿れない。この議論は下記サイトにあるが、結論としてDataContextを参照する為のプロキシを用意してリソースディクショナリに入れておかないといけない。
https://stackoverflow.com/questions/7711275/bind-datagrid-column-visibility-mvvm

```xml
        <Grid.Resources>
            <FrameworkElement x:Key="proxyElement" />
        </Grid.Resources>
        <ContentControl Visibility="Collapsed" Content="{StaticResource proxyElement}" />
        <DataGrid ItemsSource="{Binding DataList}" AutoGenerateColumns="False">
            ～　省略　～
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="{Binding Path=DataContext.Data.Value, Source={StaticResource proxyElement}}">
            ～　省略　～
            </DataGrid.Columns>
        </DataGrid>


```
DBにインデックスを貼るとどれくらい速くなるのか

インデックスはDBの高速化に有効であるという記事はいくつも見つかるが、どの程度速くなるのかという記事はあまり見かけなかったので検証してみた。

## 実験設定
今回は以下の単純なテーブルを用意した。

```
CREATE TABLE test(id integer primary key, value integer);
```

`value`が0~1000までの乱数のレコードを10^9個insertし、`value=100`のレコードの個数を検索するのにかかる時間を測定する。

## PCスペック
MacBook Air (Retina, 13インチ, 2020)
プロセッサ 1.1 GHz クアッドコアIntel Core i5
メモリ 16 GB 3733 MHz LPDDR4X
macOS Big Sur バージョン 11.4

## 手順
### DBの準備<br>
今回は準備が簡単なSQLiteを利用した。

```
> brew install sqlite3
> sqlite3 test.db
sqlite > create table test(id integer primary key, value integer);
```
### データの挿入<br>
データを手入力するのは面倒なのでJavaを使う。
DBドライバの依存を追加する必要があるのでgradleを利用した。

```build.gradle
dependencies {
    implementation group:'org.xerial', name:'sqlite-jdbc', version:'3.34.0'
}
```

ソースコードは以下の通り。

```Main.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Main {
    public static void main(final String[] args) {
        final int numOfValues = 100_000; // SQLiteのバルクインサートは10^5程度が限界らしい
        final String url = "jdbc:sqlite:/path/to/test.db";
        final String sql = new StringBuilder("insert into test(value) values")
            .append(Stream.generate(() -> "(?)")
                .limit(numOfValues)
                .collect(Collectors.joining(",")))
            .append(";")
            .toString();
        final Random random = new Random();
        try (final Connection connection = DriverManager.getConnection(url);
             final PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
            for (int i = 0; i < 10_000; i++) {
                for (int j = 1; j <= numOfValues; j++) {
                    preparedStatement.setInt(j, random.nextInt(1000)); //0~1000の乱数を生成する
                }
                preparedStatement.executeUpdate();
            }
        } catch (final SQLException e) {
            e.printStackTrace();
        }
    }
}
```

上を実行することで10^9個のレコードがDBに保存される。

```
sqlite > select count(*) from test;
1000000000
```

### 時間計測
SQLiteでは以下のコマンドを実行することで、それ以降のクエリの実行時間を測定できる。

```
sqlite > .timer on
```

まずは普通にクエリを投げる。

```
sqlite > select count(*) from test where value=100;
```

次にインデックスを貼ってからクエリを投げる。

```
sqlite > create index valueindex on test(value);
sqlite > select count(*) from test where value=100;
```

## 結果
インデックスを貼る前

```
sqlite> select count(*) from test where value=100;
999415
Run Time: real 153.334 user 80.279714 sys 17.292470
```

インデックスを貼った後

```
sqlite> select count(*) from test where value=100;
999415
Run Time: real 0.104 user 0.059074 sys 0.013650
```

153秒から0.1と大幅に実行速度が削減されたことが確認できた。
ちなみに、インデックスを貼るのに

```
sqlite> create index valueindex on test(value);
Run Time: real 2155.104 user 876.969727 sys 207.597416
```

と30分以上の時間がかかったため、クエリに絡まないカラムにインデックスを貼るのは時間の無駄であることも確認できた。

## その他
ソースコードは[こちら](https://github.com/T45K/DB_index_trial)
WPF-XPSドキュメントをマージする方法

xpsファイルをマージして一つにする方法。備忘録として
参考記事：https://stackoverflow.com/questions/10672456/merging-xps-documents-make-last-one-duplicate

```csharp
public void DoMerge(List<string> mergedFiles)
{
    // ソースドキュメントの準備
    List<XpsDocument> sourceXps = new List<XpsDocument>();

    foreach (var f in mergedFiles)
    {
        sourceXps.Add(new XpsDocument(f, FileAccess.Read));
    }

    // 出力先
    var name = destinationPath;
    if (File.Exists(name))
    {
        File.Delete(name);
    }
    XpsDocument destXps = new XpsDocument(name, System.IO.FileAccess.ReadWrite);

    // ライター
    XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(destXps);
    FixedDocumentSequence seq = new FixedDocumentSequence();

    // マージ
    foreach (XpsDocument doc in sourceXps)
    {
        FixedDocumentSequence sourceSeq = doc.GetFixedDocumentSequence();

        foreach (DocumentReference dr in sourceSeq.References)
        {
            DocumentReference newDr = new DocumentReference();
            newDr.Source = dr.Source;
            (newDr as System.Windows.Markup.IUriContext).BaseUri = (dr as System.Windows.Markup.IUriContext).BaseUri;
            FixedDocument fd = newDr.GetDocument(true);
            newDr.SetDocument(fd);
            seq.References.Add(newDr);
        }
    }

    // 終了処理
    writer.Write(seq);
    destXps.Close();
}
```
【React】状態管理比較 ~ Redux VS Apollo Client (GraphQL) ~

現場で開発しているモバイルアプリ(React Native)では、ReduxではなくApollo Clientで状態管理を行っています。

それぞれの使い方は知っているものの、正直各特長を理解した上で使い分けができているわけではありませんでした。
わからないままにしておくのはプロとして失格なので、いまさらで恥ずかしいのですが自分用に整理しました。

#Redux
以下がReduxにおけるデータフローです。
![スクリーンショット 2021-05-06 21.11.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/26912b40-d51b-487a-c9da-eccaaa4f5228.png)

ReduxではStoreで状態を一元管理することで、コンポーネント間で整合性のとれたデータを共有することができる(Single source of truth)のが特長といわれています。
しかし、実際これはローカルデータに限った話で、非同期でバックエンドのAPI呼び出しを行う場合にはReduxのMiddleware(thunk, saga)を利用する必要があります。
また、何か一つ処理を追加するたびにaction-creatorとreducerを追加しなければならないので、コードが複雑化してしまうこともあります。

コンポーネントがDBからとってきたデータを表示するまでの流れが初見では結構複雑です。
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/708f14e5-9f7a-be32-e33a-69d84e4d07be.png)
https://ncoughlin.com/posts/react-redux-asnychronous-actions-thunk/

#Apollo Client
一方、以下がApollo Clientにおけるデータフローです。
![スクリーンショット 2021-05-06 21.11.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/a74fc4b9-83ee-a976-3709-1f90064d0d18.png)

コンポーネントからapollo requestを行うと、まずはresolverでキャッシュにデータがあるかを判断します。
キャッシュにデータがあればそのままpropsとしてコンポーネントに渡し、データがなければQueryまたはMutationをGraphQLサーバに対して発行します。
このようにして取得したデータは、キャッシュされた後にpropsとしてコンポーネントに渡されます。

ここまでのデータの流れをみると「ああそうなんだ〜」で終わってしまうのですが、Apollo Clientの強みは、なんといっても**ローカルデータをキャッシュ内部に保持し、それをAPIデータと同時に取得することができる点**にあります。

https://apollographql-jp.com/tutorial/local-state/

ローカルデータの取得/更新については、クライアント側にSchemaとQuery/Mutationを定義することで、APIデータの取得と同様に行うことができます。
ローカルとAPIのQuery/Mutationは織り交ぜて使うことができるので、クライアント側のコードは「どこにどんなデータがあるか」を知る必要がなくなり、単純にQuery/Mutationを発行するだけとなります。

このように、**Apollo ClientはReduxよりシンプルに「Single source of truth」を実現することができます。**

#参考資料

https://www.s-arcana.co.jp/blog/2020/02/20/4364

https://developers.relationsgroup.co.jp/entry/2020/06/10/144733

https://qiita.com/seya/items/26c8a0dc549a10efcdf8

https://medium.com/@ingridf/what-redux-thunk-is-how-to-install-it-and-how-it-works-b67b815d2672

https://ncoughlin.com/posts/react-redux-asnychronous-actions-thunk/

https://qiita.com/official-events/b9ad63394fa2635dfca9
【Rails】本番環境でのコンパイル時、Node.jsで困った話

#環境
Ruby 3.0.1
Rails 6.1.3
Amazon Linux 2 AMI

#エラー
AWSにアプリをデプロイしようとしていた時、

```
 bundle exec rake assets:precompile RAILS_ENV=production
```
でプリコンパイルを行った際、何やら長文のエラーが起きました。
よく読んでみると何やら原因らしきものを発見

```
error /var/www/rails/myapp/node_modules/node-sass: Command failed.
```

#原因
どうやら最新のバージョンのNode.jsではnode-sassは非推奨のようです。

https://qiita.com/n0bisuke/items/123a69ba5940f11404aa

とりあえずでNode.jsをインストールしたため、最新バージョンがインストールされていました。

```
$ nvm install node
Downloading and installing node v16.1.0...
```

```
$ node -v
v16.1.0
```

#解決方法
Node.jsのバージョンを下げることで解決しました。

https://nodejs.org/ja/

バージョンは、公式サイトでも推奨版とされている`14.16.1`

##手順

```
$ nvm ls-remote
```
で変更可能なバージョンを確認

```
$ nvm install 14.16.1
Downloading and installing node v14.16.1...
Downloading https://nodejs.org/dist/v14.16.1/node-v14.16.1-linux-x64.tar.xz...
############################################################################################################################## 100.0%
Computing checksum with sha256sum
Checksums matched!
Now using node v14.16.1 (npm v6.14.12)
```

```
$ nvm use 14.16.1
Now using node v14.16.1 (npm v6.14.12)
```

で変更完了！

```
$ bundle exec rake assets:precompile RAILS_ENV=production
Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install
Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install
Yarn not installed. Please download and install Yarn from https://yarnpkg.com/lang/en/docs/install/
Exiting!
```

無事、プリコンパイルが完了しました！
if文におけるans == 0はなぜ上手くいくのか？(今日のPython Day6)

## 0. はじめに
　「そろそろ寝ようかな？」と思っていざ寝ようとしたら記事を投稿することを忘れていることに気づき、慌てて記事投稿しました。危ない、危ない。
>
　毎日1問、Pythonの問題を出題します。出題範囲は特に定めていませんがはじめの1ヶ月くらいは『入門Python3　第2版』の第1～11章までのことが分かれば解ける問題にしたいと思います。「こういう問題を作って欲しい」などのリクエストがございましたら初心者ながら頑張って作問します。また「別解を思いついた」、「間違えを見つけた」などがありましたら遠慮なくコメント欄にて教えて下さい。記事を執筆している当人もこの記事を読んでくださった方も新たなことを学ぶことができるので。

##1. 問題
　以下のプログラムにおいて入力値が0の場合、最初のif文が実行される。しかし明示的にブール値Falseとされていなくても整数のゼロ(0)のBool値はFalseである。なぜ0はFalseとみなされるのにinput()関数が受け取る値が0のとき、きちんと最初のif文が実行されるのだろうか。その理由を説明しなさい。

```python
print("pythonが楽しいと思う人は1を、楽しくないと思う人は0を入力してください。")
ans = int(input()) 
if ans == 0:
    print("私も！")
elif ans == 1:
    print("そいういときもあるよ")
else:
    print("正しい数を入力してください")
```

##2. 解答
　整数0のブール値ではなく条件式であるans == 0のブール値をif文は確認しているから。

##3. ヒント
　if文は何のブール値を判断して条件分岐をしているのでしょうか？ちなみにブール値とはTrueかFalseのことです。

##4. 解説
　今回の説明問題は今日の授業中にふと疑問に思ったことをそのまま問題として出題しました。if文がチェックしているのはif文のすぐ次に書かれている条件式です。つまり変数ansの値が0かどうかをif文は判断しているのであって「0」がTrueかFalseかを判断しているわけではありません。「なんでこんなことで自分は1時間も引っかかったのだろうか」と記事を執筆している今は思うのですが、問題文のようにカタカナと専門用語多めで説明されると引っ掛かってしまった人もいるのではないでしょうか？

##5. ans == Falseならどうなるか？ (発展編)
　さて、ここからは発展編です。では次の場合、整数の0を入力するとどうなるでしょうか？

```python
print("pythonが楽しいと思う人は1を、楽しくないと思う人は0を入力してください。")
ans = bool(input())
if ans == False:
    print("私も！")
# 以下省略
```

　今回もうまくいくかと思いきや、「私も！」とは表示されずうまくいきません。理由はわかりますか？答えは「inputで入力された整数0は文字列の0に変換されるから」です。整数の0や浮動小数点0.0はそれ自身がFalseとみなされるのですが、文字列の0は単なる文字なのでTrueと見なされます。そのためif文の左辺「変数ansのブール値はTrue：、右辺は「False」となりif文は実行されません。

```python
print("pythonが楽しいと思う人は1を、楽しくないと思う人は0を入力してください。")
ans = bool(input()) 
print(type(ans)) # ->文字列の0と認識されるのでTrue
if ans == False:
    print("私も！")
# 以下省略
```

もう1つ事例を考えてみましょう。次の場合、0を入力するとどうなるでしょうか？

```python
print("pythonが楽しいと思う人は1を、楽しくないと思う人は0を入力してください。")
ans = bool(int(input()))
print(ans)
if ans == False:
    print("私も！")
# 以下省略
```
　
　今回は「私も！」と表示されうまくいきました。上手く言ったのは入力値を整数に変えてからブール値を求めたからです。

##6. まとめ
~~・if文はその後に書かれた条件式のブール値を確認して処理する。~~
→・「if文自体が bool関数を使って True か False を判断してくれる」

コメント欄にて教えていただいたのでまとめを変更しました。
@shiracamus様、本当にありがとうございます！



##7. おまけトーク
　この疑問を思いついたのは授業中なのですが、その授業はPythonに関する授業じゃなかったんですよ。何の授業だったと思いますか？

・・・

　実は古代ローマ史の授業でした。はい。最後まで読んでいただき本当にありがとうございます。

##参考文献
[「Bill Lubanovic著『入門Python3 第2版』(オライリー・ジャパン、ISBN978-4-87311-932-8)](https://www.amazon.co.jp/E5-85-A5-E9-96-80-Python-E7-AC-AC2-E7-89-88-Bill-Lubanovic-dp-4873119324/dp/4873119324/ref=dp_ob_title_bk)
【rails】seeds 作成時の "NoMethodError: undefined method `テーブル名1' for #<テーブル名2:0x000055f5fcc6c580> エラーの解決

# エラー原因

結論からいうと、`has_many :テーブル名`を書いていないからエラーが起こりました。

# エラー状況
下記のような状態で、`rails db:seed`を実行したところ、
`NoMethodError: undefined method 'products' for #<User:0x000055f5fcc6c580>`が発生。

```
user = User.create!(
  last_name: "山田",
  first_name: "太郎",
  email: "user1@example.com",
  password: "password",
)

product = user.products.create!(
  product_name: "りんご",
  description: "新鮮なりんごです",
  user_id: user1.id,
)

実行結果 : エラー発生
`NoMethodError: undefined method 'products' for #<User:0x000055f5fcc6c580>`
```

# 解決
models/user.rb に下記のように書くことで解決。

```
has_many :products, dependent: :destroy
```

テーブル同士の関連付けが出来ていなかった為、エラーしていました。
[AWS_10]EC2インスタンス起動〜SSH接続

##環境
MacBook Pro (13-inch, 2016, Four Thunderbolt 3 Ports)
macOS 11.3.1（20E241）

##最終的な構成
![構成図_AWS01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758644/3ee36263-a09b-caa8-d779-af6fa582d066.png)

##流れ
1. VPCの作成
1. サブネットの作成
1. EC2の作成
1. インターネットゲートウェイの作成
1. ルートテーブルの設定
1. SSH接続

##VPCの作成
マネジメントコンソールでVPCを検索し、`VPC　＞　VPC作成`をクリックする。
　VPC名：　MyVPC(適当)
　IPv4 CIDRブロック:　10.0.0.0/21

##サブネットの作成
マネジメントコンソールでVPCを検索し、`サブネット　＞　サブネットを作成`をクリックする。
　サブネット名：　PublicSubnet1(適当)
　VPC:　MyVPC
　IPv4 CIDRブロック:　10.0.0.0/24

　サブネット名：PrivateSubnet1(適当)
　VPC:　MyVPC
　IPv4 CIDRブロック:　10.0.2.0/24

##EC2の作成
1.マネジメントコンソールでEC2を検索し、`インスタンス　＞　インスタンスを起動`をクリックする。（各ステップでは、`確認と作成`ではなく、`次のステップへ`をクリックする。）
  ステップ1
　　AMI:　Amazon Linux 2 AMI (HVM), SSD Volume Type
　ステップ2
　　インスタンスタイプ：　t2.micro
　ステップ3
　　ネットワーク: MyVPC
　　サブネット:　PrivateSubnet1
　　自動割り当てパブリック IP:　有効
　ステップ4
　　ストレージ:　汎用SSD 8GB
　ステップ5
　　タグキー：　Name
　　タグ値：　WebServer1(適当)
　ステップ6
　　セキュリティグループ名：　Web-SG-1(適当）
　　セキュリティグループ説明：　Web-SG-1（適当）

|タイプ |プロトコル |ポート範囲 |ソース |説明 |
|---|---|---|---|---|
|SSH |TCP|22|カスタム 0.0.0.0/0|(デフォルト)|
|HTTP  |TCP|80|カスタム 0.0.0.0/0, ::/0 | |



2.以上を設定して、`起動`をクリックして、設定のサマリを確認する。
3.新しいキーペアを作成する。
　キーペア名: Mykeypair(適当)
4.キーペアのダウンロード
5.`起動`をクリックする。
6.インスタンスで`WebServer1`が起動していることを確認する。

##インターネットゲートウェイの作成
1.マネジメントコンソールでVPCを検索し、`インターネットゲートウェイ　＞　インターネットゲートウェイの作成`をクリックする。
名前タグ：　My-internet-GW(適当)

2.インターネットゲートウェイの作成をクリックする。
3.`VPCヘアタッチ`をクリックする。
4.アタッチするVPCを選択して`インターネットゲートウェイのアタッチ`をクリックする。

##ルートテーブルの設定
1.マネジメントコンソールでVPCを検索し、`サブネット　＞　(作成したパブリックサブネット)　＞ルートテーブル　＞　ルートテーブル: rtb-xxxxxxxxxxxxxxxx　＞　ルート　＞　ルートの編集　＞　ルートの追加`をクリックする。
送信先：　0.0.0.0/0
ターゲット：　作成したインターネットゲートウェイ（InternetGatewayを選択すると候補が出てくる）

2.`ルートの保存`をクリックする。

##SSH接続
1.ターミナルを起動する。
2.ダウンロードしたキーファイルの権限を確認する。
　ls -l
3.400になっていなければ変更する
　chmod 400 Mykeypair.pem
4.ssh接続する。
  ssh -i Mykeypair.pem ec2-user@[インスタンスのパブリック IPv4 アドレス]
【TypeScript】npmでパッケージをインストールする

<!-- ================================================ -->
#概要
<!-- ================================================ -->
VSCode で、npm（node package manager）を使用してTypeScript でサードパーティライブラリをインストールする場合、3つのシチュエーションがあります。

* TypeScript をサポートしているパッケージ
* JavaScript のみサポートしていて、型定義ファイルが配布されているパッケージ
* JavaScript のみサポートしていて、型定義ファイルが配布されていないパッケージ

このシチュエーションごとに、どのように TypeScript でインストールするかまとめました。

---
この記事は、以下のコースの受講に伴って、備忘録として書いています。詳しく知りたい方は、是非受講してみてください。

https://www.udemy.com/share/103e4OAEYdcVlbTX4D/

<!-- ================================================ -->
#環境
<!-- ================================================ -->
* Windows10
* TypeScript 4.2.4
* VSCode

<!-- ================================================ -->
#シチュエーションごとのインストール
<!-- ================================================ -->
VSCode や Node.js（npm）は、あらかじめインストールします。

まず、VSCodeで対象のプロジェクトを開いて、ターミナルで以下を実行します。

```package.jsonの生成
npm init -y
```

###TypeScript をサポートしているパッケージ
これが一番簡単です。
ここでは、**class-validator**というパッケージをインストールしてみます。

```
npm install --save class-validator
```

そうすると、プロジェクト内の`node_modules`に、`class-validator`が追加されます。
中を見ると、typesフォルダにtsファイルのソースがあることがわかります。**.d.ts** で終わるファイルは、型定義をしたファイルです。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358498/24a42d3f-4c79-4244-0e05-5a1d1afe995c.png)

このように型定義ファイルがパッケージ内に含まれていれば、パッケージ本体をインストールするだけでプロジェクトで使用できるようになります。


###JavaScript のみサポートしていて、型定義ファイルが配布されているパッケージ
サードパーティライブラリで、型定義ファイルが含まれていないケースも多いです。その場合、別に型定義ファイルをインストールする必要があります。

ここでは、**jQuery**というパッケージをインストールしてみます。

```:パッケージ
npm install --save jquery

```
```:型定義ファイル
npm install --save-dev @types/jquery

```

ここで、`--save-dev`としているのは、型定義ファイルが開発時にしか必要ないからです。（最終的にtsファイルは、jsファイルにコンパイルされるため）
このように、開発時にしか依存しないパッケージは、`--save-dev`としてインストールします。

また、`google map sdk`のように、npm でパッケージとして配布されていないもの（html の script タグでしか読み込めないライブラリ）も、型定義ファイルは配布されている場合があります。

```html:html
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap&libraries=&v=weekly" async></script>
```

```:型定義ファイル
npm install --save-dev @types/googlemaps
```

####型定義ファイルの検索方法
型定義ファイルを探す場合は、ブラウザで「types jquery」のように検索すると出てきます。


###JavaScript のみサポートしていて、型定義ファイルが配布されていないパッケージ

あまりないケースのようですが、この場合は [アンビエント宣言(declare キーワード)](https://typescript-jp.gitbook.io/deep-dive/type-system/intro) を使用して、パッケージから読み込んだ変数の型を一時的に、`any型`としてしまう対応方法があります。
ただし、TypeScript の恩恵を受けられないので最後の手段です。

また別の対応方法もあるようです。
[TypeScript で型定義ファイル( d.ts )がないときの対処法](https://qiita.com/Nossa/items/726cc3e67527e896ed1e)

<!-- ================================================ -->
#参考
<!-- ================================================ -->
* [TypeScript で型定義ファイル( d.ts )がないときの対処法](https://qiita.com/Nossa/items/726cc3e67527e896ed1e)
ユーザ登録機能の実装（deviseを使用して説明）ビュー作成〜

##ビューの作成##
deviseインストールからuserモデル作成までは下記の記事にて書かせていただきました。

https://qiita.com/N396184501/items/e91b41dd8e6f46d39995

今回はビューの作成を行います。

deviseでログイン機能を実装すると、ログイン/サインアップ画面が自動的に生成されます。
しかし、ビューはファイルは生成されていません。
なので、コマンドでビューファイルを生成します。

```ターミナル　.
rails g devise:views
```

ビューファイルが生成されました。
サインアップのビュー
app/views/devise/registrations/new.html.erb 

ログインのビュー
app/views/devise/sessions/new.html.erb

##コントローラーについて##

ビューファイルができ、前記事でモデルを作成し、ルーティングの自動で生成される事を確認しました。
残るはコントローラーです。

deviseのコントローラーはGem内に記述されているため、編集することができません。
そのため、applicationコントローラーで記述します。
applicationコントローラーはコントローラー内での頂点です。全てはここから始まります。（言い切ってはいけない）

全てのコントローラーの1行目には下記が記述されています。

```controller.rb
class HogeController < ApplicationController
```

applicationコントローラーでストロングパラメーターを設定します。

```app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  private
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname, :birth_day])
  end
end
```

1つづつ確認していきます

```.rb
before_action :configure_permitted_parameters, if: :devise_controller?
```
before_actionで全てのコントローラーの前に動き、またif: :devise_contoroller?でdeviseにまつわる事が起きたときに作動します。


```rb
private
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname, :birth_day])
  end
end
```
deviseにおけるストロングパラメーターです。deviseの「ログイン」「新規登録」などのリクエストからパラメーターを取得できます。

このメソッドとpermitメソッドを組み合わせることにより、deviseに定義されているストロングパラメーターに対し、追加したカラムも含めることができます。(email,passwordはすでに定義されているため)
Windows7を安全に運用し、かつファイル共有サーバにする方法

# Windows7を安全に運用し、かつファイル共有サーバにする方法
サポート切れのWindows7をどうにかして使いたい。
そこで、スペックのあまり要らないファイル共有サーバとしての使うことにした。
「セキュリティ上危険だ」「まだ甘い」などご意見があればコメントへお願いしたい。
（セキュリティにかかわることなので、忌憚ない意見をお願い致します）
サポート切れのOSを使い続けることはどうしてもリスクが伴うため、真似をする際は自己責任でお願いする。当方は一切の責任を持たない。

## 環境（構成完成図）
- ルータ（最新のセキュリティパッチを適用、ファイアウォール設定もしている）
    - PC1（最新のセキュリティパッチを適用しているOSを搭載。インターネットに接続）
    - PC2 (問題のサポート切れWindows7。自宅内LANに繋ぐ）
        - 外付けHDD
    
## 方針
 1. Windows7はWAN（インターネット）から切り離す
 2. 使わないときはLANケーブルを抜き、当該電源を切る
 3. もしものために接続ログをきちんと取る。
 4. ファイル共有サーバを介して入手したファイルはセキュリティ検査をかける
 
## ①Windows7をWAN（インターネット）から切り離す

サポート切れOSはセキュリティの面で非常に脆弱である。インターネットを介した攻撃を防ぐため、インターネットに双方向接続できないようにする。
今回は当該機器にIPフィルタをかける方法とDNSサーバを指定しない方法、デフォルトゲートウェイを指定しない方法の3重に行う。
### Windows7
#### IPフィルタ
IPフィルタをLAN→WAN、WAN→LANの両方にかける。

- IPv6は使わないのでチェックを外す。 
-  IPを固定する。
（IPを固定すると狙い撃ち攻撃のリスクが上がるため、あまりやりたくないが、DHCPによってコロコロ変わると困る。なにか良い方法があればコメントへ。）
 - IPの固定はIPアドレスとサブネットマスクに対応し、かつDHCPの割り振り範囲外である必要がある。




#### 参考
https://qiita.com/X-IA/items/ba2de188ed481a69f295
ガラケーからiPhoneへの連絡先移行

ガラケーからiPhoneへの連絡先移行

（を、した時の作業記録　いまどきガラケーからiPhoneなんて作業は発生しますかね...）

1. ガラケーでSDカードに連絡先をバックアップ
2. SDカードに作成されたAD__0000.VCFメモ帳で開く
3. すべてコピーしてsublime textに貼り付ける
4. sublimeの機能でVCFファイル中の文字列「SHIFT-JIS」を「UTF-8」に置換
5. ファイルを保存（UTF-8で保存される）
6. iCloudの連絡先にアップロード
7. iPhoneの連絡先アプリで同期されていることを確認


今回のポイントは、4.の「SHIFT-JIS」を「UTF-8」に置換の部分です。

これをしていないときは、iCloudでは、文字化けせずに表示されているのに
iPhoneでは文字化けする謎の現象が発生して、２時間は悩んでしましました。
文字コードさえ変えれば、iPhoneで文字化けがなくなると思ったのですが、
VCFファイルをよく見ると「SHIFT-JIS」の文字。ここも見ているのですね、当たり前か.....


「makisaoriのブログ」を参考にさせていただきました。感謝です。
https://ameblo.jp/makisaori/entry-12470213373.html


このあと

初めてiPhoneのメールの設定をしています。

使い慣れた「gmailアプリ」でメールを送信するときに、「連絡先アプリ」から
「gmailアプリ」を起動してメールを送信しようとしたのに、「メールアプリ」が起動してしまう。
う～む......

1. 「設定」アプリから「Gmail」を選択する
2. 「デフォルトのメールApp」をタップする
3. 「Gmail」を選択する  (「メール」にレが付いているので、「Gmail」にレを付ける)

で解決しました。

こちらは「iPhone格安SIM通信」さんの記事に助けていただきました。
https://www.kashi-mo.com/media/1384/#iPhoneGmail
Zope 5.0のインストール（Ubuntu 21.04)

（執筆 2021/5/6)

　とうとう Zope を再び試す日が来ました。Zope 3 で混乱に陥った人も、Zope 2 が帰ってきたと喜ぶでしょう。取りえず、標準のインストールと立ち上げを試みます。

# Python3 のインストール
　Zope 5.0 は、3.5 以前の Python では動作せず、 3.9 のサポートが追加されています。2021/5/6 時点で Ubuntu 20.10 は 3.8.6 、Ubuntu 21.04 は 3.9.4 です。Ubuntu 20.10 は、3.8.6 になっています。

```
sudo apt-get install -y build-essential python3-dev python3-venv libffi-dev
```

# ビルドアウト ([Zope documentation](https://zope.readthedocs.io/en/latest/INSTALL.html))
　Zopeのインストールには、Pythonの仮想環境で zc.buildout という仕組みで行われます。とりあえずホームディレクトリに環境を作成します。

```
wget https://pypi.org/packages/source/Z/Zope/Zope-5.0.tar.gz
tar xzvf Zope-5.0.tar.gz
cd Zope-5.0
python3 -m venv .
bin/pip install -U pip wheel zc.buildout
bin/buildout
```
　ここで、libffiがないとエラーが出るかもしれません。

# 設定と実行 ([Zope documentation](https://zope.readthedocs.io/en/latest/operation.html#))
　初期ユーザーの名前とパスワードを設定し、etc の下に設定ファイルを作成します。

```
bin/mkwsgiinstance -d .
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/7ef45f33-6035-d2cd-35fb-c7c9257a257e.png)

　これで、etc ディレクトリの中に、site.zcml, zope.ini, zope.conf のファイルが出来上がりますので、Zopeを起動します。

```
bin/runwsgi -v etc/zope.ini
```

http:localhost:8080/manage にアクセスし、初期ユーザーのユーザー名、パスワードを入力して、管理画面に入ることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/746461f9-0b36-53a4-9564-4b9bd75504f7.png)

　懐かしい、素っ気ない画面に出会うことができました。

# ページの作成
　テストページを作成します。
　右上の Select type to add を開いて、HTML Documentを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/d3b55a72-beb0-aaa0-4196-d6a958f4e5bc.png)
　IdとTitleを入力して、Addを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/1e155ea0-6f57-4413-0000-e100274c3989.png)
　Contentsのリストの中に test(テストページ) という項目が増えています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/a92c503f-57e0-0630-0a3c-9b2ff632083c.png)
　testを選択して開くと、HTMLコードが出来上がっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/640b9f2f-01d7-2b1c-1f82-d02d1e638348.png)
　ブラウザで、 http://localhost:8080/test をアクセスすると、以下の画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/345483f1-f473-7311-1623-4f8b391196d5.png)

　ページ作成の方法は、たぶんZope2と同じだと思うので、[Zope Book](https://zope.readthedocs.io/en/latest/zopebook/index.html)が参考になると思います。
sedでTeXファイルの句読点「、」「。」を「,」「.」に置換する

##はじめに
論文では句読点を「,」「.」を書くのが主流です。
研究室の後輩にTeXの書き方を指導しているとき、「,」「.」を入力するために日本語入力と英語入力の切り替えを多用しているようだったので、私がやっている置換方法を紹介します。


##sedを使った方法
以下のコマンドを.texファイルのあるディレクトリで実行するだけ。

```shell
for file in *.tex; do sed -i "-bak" -e "s/、/，/g" -e "s/。/．/g" $file; done
```
テキストエディタの置換機能を使うという方法もありますが、章ごとにファイルが分かれている場合にも対応できるようにシェルで一括置換をするコマンドです。

元のファイルは、ファイル名.tex-bak としてバックアップされます。
はじめて四則演算を使用したシェルスクリプトを作ってみた

#1．はじめに
今回は思い付きで、初めて作成した[シェルスクリプト](https://e-words.jp/w/%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88.html)を、ご紹介します。<br>また、本題材である[四則演算](https://ja.wikipedia.org/wiki/%E7%AE%97%E8%A1%93)の内容を簡単に説明すると、足算・引算・掛算・割算の総称です。<br>※まだまだ、改良の余地がある内容になっているので、暖かい眼差しで読んで頂ければと思います。

#2．シェルスクリプトとは
>シェルスクリプトとは、OS（オペレーティングシ>ステム）を操作するためのシェル上で<br>実行できる簡易なプログラミング言語（スクリプト言語）。

引用サイト：[『IT用語辞典 e-Words』](https://e-words.jp/)の[シェルスクリプト](https://e-words.jp/w/%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88.html)より
※Windowsでいうとバッチファイルのことを示します。

#3．処理の流れ
シェルスクリプトを作成するに当たって、処理する順序をざっくりと決めます。<br>今回の題材は、四則演算を使用したものになるので、下記の順序になります。

1．変数を設定する
2．事前に入力した変数を出力する
3．計算結果を出力する。

#4．作成
はじめに『work』フォルダを作成し、シェルスクリプトを作成します。
※フォルダ名・ファイル名は、分かりやすいもので大丈夫です。

```
mkdir work; cd /root/work
vi ＜ファイル名＞.sh

#!/bin/bash
#基本的にシェルを作成する上で、必ず『#!/bin/bash』を追加します。
```

数値を変数に入れる為、それぞれ用意する。

```
front_nb="x"
back_nb="y"
```
最後に計算する処理を追加する。

```
echo $((front_nb + back_nb))
```

#5. 実行

今回作成したシェルスクリプトを実行する場合、<br>それぞれ『x』と『y』に変数を入力する必要があるので、環境変数を入力する。

```
export x=＜数値＞
export y=＜数値＞
---
#環境変数を確認するコマンドは、下記のコマンドで確認できます。
export -p
```

実行前に、一度ファイル権限を確認してみます。ユーザーの実行権限がない場合、権限を付与します。
また権限が正しく付与されたか、再度『ls』コマンドで確認します。

```
chmod x ＜ファイル名＞.sh
chmod 744 ＜ファイル名＞.sh
#どちらでも権限を付与できます。
---
ls -l
```

実行コマンドを入力します。

```
./＜ファイル名＞.sh
/root/work/＜ファイル名＞.sh
#上記のコマンドは、作成した場所によってディレクトリが変わる為、要確認！
```
実行結果がこちらになります。今回の場合、『x=10』,『y=2』に変数を設定しました。

```
export x=10
export y=2
和:12
差:8
積:20
商:5
```

#6．完成形
今回自分が作成したシェルでは、下記の内容になりました。

```
#!/bin/bash
#変数を設定する
front_nb="x"
back_nb="y"
#事前に入力した変数を出力する
echo "export x="$x
echo "export y="$y
#計算結果を出力する
echo "和:"$((front_nb + back_nb))
echo "差:"$((front_nb - back_nb))
echo "積:"$((front_nb * back_nb))
echo "商:"$((front_nb / back_nb))
```

#7．まとめ
自分なりに調べながら、作成してみました。試行錯誤しながら、<br>作るシェルスクリプトも面白いと感じました。<br>今回の改善点を上げるとしたら、手動で変数を入力する手間を省く形式でも、良さそうですね。<br>次回作る機会があれば、もう少し工夫して作成してみようと思います。

#8. 参考文献
・[『IT用語辞典 e-Words』](https://e-words.jp/)
・[『Wikipedia』](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88)
・[『Bash $((算術式)) のすべて - B 罠・バグ回避編』](https://qiita.com/akinomyoga/items/9c9d6cfeb02f186f9185)