OmniAICreator/Qiita-1.07M huggingface dataset:
create-react-appでhttps使いつつexpressにproxyするときにsecure: trueを有効にする方法

# 前提

- create-react-app(以下cra)を使ったSPA
- craのhttpsを有効化している
- expressを使ったサーバー
- SPAはexpressでホスティングする
- 本番環境はheroku想定
  - https終端が前段にいて、httpでexpressサーバーが動く形
- 開発時は[craのproxy](https://create-react-app.dev/docs/proxying-api-requests-in-development/) 機能を使ってsame originとして動かすようにしている

# どんな問題が起きるのか

craがhttps終端としてのプロキシサーバーになっていて、その後ろにhttpのexpressサーバーがいるという構成になるため、cookieなどの設定は本番と同等で問題なく動く理屈になるはずである

express-sessionの設定は以下のような実装とする

```js
app.use(session({
  store: redisStore,
  name: 'connect.sid',
  secret: 'abkl;aew',
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: true,
    httpOnly: true,
    path: '/',
    sameSite: 'strict',
  },
}))
```

httpsじゃないとcookieが付かないようにsecure属性を有効にしている

この状態でcraのproxyを挟むと何故かcookieがセットされないという問題が発生する


# 解決策

craの機能でsetupProxy.jsに `http-proxy-middleware` を使ってカスタマイズが出来るので、そこで `xfwd: true` を設定する

```js:setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = app => {
  app.use(
    ['/api'],
    createProxyMiddleware({
      target: 'http://localhost:3100',
      xfwd: true,
      changeOrigin: true,
    }),
  );
};
```

# 何が起きていたのか

express-sessionのドキュメントで以下のようなサンプルコードがある

```js
var app = express()
app.set('trust proxy', 1) // trust first proxy
app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: true }
}))
```

ここに記載されている `app.set('trust proxy', 1)` という設定によって、 `X-Forwarded-` 系のヘッダを利用してホスト名などを解決するようにexpressの動作が変更される（ref: [プロキシーの背後の Express](https://expressjs.com/ja/guide/behind-proxies.html)）

craのプロキシはデフォルトで `X-Forwarded-` ヘッダを付与しないため、ホスト名などを使ってsecure判定をしているexpress-sessionがcookieを付与しない、という振る舞いをしていたのであった

`app.set('trust proxy', 1)` をおまじない的に書いてたのでハマり散らかして大変だった・・・
画像をピクセル数で振り分ける～ついでにリサイズも

タイトル通りです:relaxed:
高解像度写真で行き詰まっているための急場しのぎのコード

```powershell:Get-ImageBasedOnArea.ps1

# 規定面積より大きいピクセル数の画像を取得する
function Get-ImageBasedOnArea{

    # 条件分岐のための規定面積
    param(
        [int]$default = 2000000
    )

    # アセンブリロード
    Add-Type -AssemblyName system.drawing

    # 画像を取得
    $image = New-Object System.Drawing.Bitmap($_.fullname)

    # 画像の縦横幅を取得しピクセル面積を求める
    $width = $image.Width
    $height = $image.Height
    $area = $width * $height

    # ピクセル面積が規定より大きい場合、$_を返す
    if($area -gt $default){
        return $_
    }

    $image.Dispose()
}

```
Windowsのペイントツールで開かない画像が出てきたためこんなことをしています。
加えて画像のリサイズも

```powershell:Resize-Image.ps1
# 規定面積へ画像をリサイズ
function Resize-Image{

    # ダウンサイジングの規定面積
    param(
        [int]$down_area = 1500000
        )

    # アセンブリロード
    Add-Type -AssemblyName system.drawing

    # 画像を取得
    $image = New-Object System.Drawing.Bitmap($_.fullname)

    # 画像の面積の平方根を取得 => $square
    $square = [Math]::Sqrt($image.Width * $image.Height)

    # ダウンサイジング規定面積の平方根 => $down_square
    $down_square = [Math]::Sqrt($down_area)

    # ダウンサイジング後の縦横幅
    $ratio = $down_square / $square
    [int]$new_width = $image.Width * $ratio
    [int]$new_height = $image.Height * $ratio

    # ダウンサイジング後のオブジェクトを作成　=> $canvas
    $canvas = New-Object System.Drawing.Bitmap($new_width, $new_height)
    
    # 描画
    $graphics = [System.Drawing.Graphics]::FromImage($canvas)
    $graphics.DrawImage($image, (New-Object System.Drawing.Rectangle(0, 0, $canvas.Width, $canvas.Height)))
    
    # 画像の保存
    $new_name =  $_.basename + "_down.jpg"
    $path = Join-Path $_.DirectoryName -ChildPath $new_name
    $canvas.Save($path,[System.Drawing.Imaging.ImageFormat]::Jpeg)

    # オブジェクト破棄
    $graphics.Dispose()
    $canvas.Dispose()
    $image.Dispose()

}
```
サービスにおける内部品質とは？


#アプリケーションサービスにおける品質とは？


アプリケーションサービスにおける品質とは以下の二種類に分類できる

* 外部品質（ユーザーに見える部分）


使用通りに動く、バグがない、高速に動作する

* 内部品質（ユーザーからは見えない）
保守性や柔軟性、可読性、一貫性


一度内部品質を下げると、その後内部の品質は崩壊し続ける。
「次のリリースを優先し、内部品質はリリース後に対応しよう」　⇦　この後は永遠と訪れない。

短期的には、リリースのスピードは上がるかもしれないが、中期的には逆効果で、さらに長期的にみた時には致命的な不具合の温床となるケースが多々あります。 


#内部品質を高く保つと良いこと

以下のような良いこと

* コードの変更速度が上がる
* 手戻りが減る
* 学びのループが早くなる
* 市場での競争力が上がる


#内部品質を上げるために必要なこと

知識、経験が品質を向上させます。
より良いコードを常に考えて、コーディングに取り組むことで少しずつよいコードというものがわかってきます。
実務では知らないとヤバイ!Railsで使われるGemを解説(基本から実務で使うもの、探し方まで解説)

# Gemとは
Gemはパッケージまたはパッケージ管理ツールです。
パッケージは便利な機能がまとまったものです。

例えばログイン機能や画像アップロードなどを実装したい時にGem中にインストールすると
効率的に実装したい機能を導入することができます。

Gemをインストールするときは

```
$ bundle install
```
でインストールできます。

## bundlerとは
***Bundlerはgemを管理してくれるツール***です。***bundlerもgemの1種***です。
いろいろなgemを管理してくれます。

# Gemfileの中身
このファイルにgemを置いてインストールしていきます。
環境によって必要なGemも変わってきます。

```Gemfile

ruby '2.7.1'　　#Rubyのバージョン　ここでは2.7.1

#省略

group :development do   #開発環境

#省略

end

group :test do　　#テスト環境

#省略

end


group :production do  #本番環境
     
	#省略

end

```

# Gemの一覧を見るには
以下のコマンドをコマンドラインで実行すると見ることができます。
```
gem list
```

# Gemの探し方
以下のコマンドでも探すことができます。
```
gem search <ライブラリ名> 
```
例えばrubocopのGemを探すなら
```
 % gem search rubocop

*** REMOTE GEMS ***

appbooster_rubocop_config (0.7)
armitage-rubocop (1.51.0.6)
#中略
```
みたいな感じで探すことができます。インストール済みのローカルのGemを探す場合はlをつけます。

```
% gem search -l <ライブラリ名> 
```

このサイトで探すこともできるみたいです。

https://rubygems.org/

# Gemを導入する時にはどんなものがあるか
正直多すぎて全部伝えることはできないです。よく使いそうなものだけ紹介していきます。

- ***テスト環境***
テストの効率向上や品質管理のためのものが多いです。
```Gemfile
group :development, :test do
  gem 'rspec-rails'　#rspecのGem
  gem 'factory_bot_rails' #factoryBotのgem
  gem 'faker'　#ダミーデータを生成するためのGem
  gem 'capybara' #統合テストのためのGem
  gem 'database_cleaner' #テストデータベースをクリーンにするためのGem
  gem 'simplecov', require: false #コードのカバレッジを計測するためのGem
  gem "pry-byebug" # デバックするためのGem(binding.pry)
  gem "rubocop-rails" # Rubyコードのスタイルと品質を自動的に検査するためのGem
  gem "rubocop-rspec" #RSpecのテストに対してコードのスタイルと品質を検査するためのもの
end
```
⚫︎補足
***コードカバレッジとはテストがこれくらい終わったという割合***のことです。

その他のGemも載せておきます。
```Gemfile
group :development do
  gem "annotate" #モデルやスキーマのファイルに注釈を追加
  gem "rails-erd" #データベーススキーマを可視化するためのGem
end

gem "jwt"   #JSON Web Token（JWT）を生成および検証するためのGem
gem "bcrypt"  #パスワードのハッシュ化を行うためのGem
gem 'dotenv-rails' #環境変数を管理するためのGemで.envファイルから環境変数を読み込みアプリ内で使えるようにする
gem 'prawn'　#PDFドキュメントを生成するためのGem
gem "paranoia" #論理削除（soft delete）を実現するためのGem。データベースレコードを物理的に削除せずに、削除済みとしてマーク
gem "device"  #認証およびユーザー管理のためのGem
gem "devise_token_auth"  #Deviseをベースにして、トークンベースのAPI認証を実装するためのGem
gem 'kaminari'#ページネーション
gem 'ransack'　#検索機能
gem 'bullet' #N+1クエリや冗長なデータベースクエリを検出し、最適化のヒントを提供するGem

```
などがあります。有名なのもさればそうでないのもあります。
参考にしてみてください。

この記事に実務のソースコードがあります。そこで実際に実務でどんなGemが使われているか
見てみてください。

https://qiita.com/jnchito/items/c9ca22efa270ff1b7f3d



# 参考資料

https://blog.codecamp.jp/rails-gem

https://yokoyamadesuga.com/rails-gem/

https://pikawaka.com/ruby/how-gem-works

https://zenn.dev/bon_saurus/articles/c79150b9242fae
tmuxinatorをmacで使ってみる

## 概要
tmuxinatorを使って__複数のアプリのログを１つのウィンドウに分割して表示__するのが便利そうだったので、まずtmuxinatorの構築だけやってみました。（今回ログ流すところまではやってない）
公式のドキュメントやネットで調べただけだとなかなかうまくいかなかったので備忘録。
__※home配下にyml作るパターンが多そうですが、今回は任意のディレクトリにymlを置くパターンでやってます__

## 構成イメージ

target_projects/
├ frontend_app/ 　#今回は使いません
├ backend_app/ 　#今回は使いません
├ .tmuxinator.yml 　#今回追加していく
└ .tmux.yml 　　　#今回追加していく

## 準備

#### tmuxinatorの準備

brewでの手順です（gem使う場合は[公式ドキュメント](https://github.com/tmuxinator/tmuxinator#installation)参照）

```
brew install tmuxinator
```
```
export EDITOR='vim'
```

``` :任意のディレクトリ（今回はtarget_projects/）にて
tmuxinator new --local .tmuxinator
```
vimが立ち上がったら下記を変更（カレントディレクトリの.tmux.confを使うための変更）
:wqで閉じると同ディレクトリに.tmuxinator.ymlができてます（※隠しファイルのため注意）

``` diff_yaml:.tmuxinator.yml
+ name: hoge
- name: .tmuxinator
+ root: .
- root: ~/.
...
+ tmux_options: -f .tmux.conf
- # tmux_options: -f ~/.tmux.mac.conf
```
ちなみに今回windowsの設定は一旦適当なものを設定しました

``` yaml:.tmuxinator.yml
windows:
  - editor:
      layout: even-vertical
      panes:
        - vim
        - vim
  - editor_solo: vim
```

#### .tmux.confの用意
次にウィンドウ切り替えをマウスのクリックで行うための設定

```
vi .tmux.conf
```
``` conf:.tmux.conf
set-option -g mouse on
bind -n WheelUpPane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'copy-mode -e'"
```

## 実行
``` :任意のディレクトリ（今回はtarget_projects/）にて
tmuxinator start .
```
この画面下部の「1:editor_solo」をマウスでクリックすると画面が切り替わります
![Screen Shot 2021-09-04 at 1.08.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148042/005e969c-9a0f-8304-b257-b952e3493076.png)

## 停止
``` :任意のディレクトリ（今回はtarget_projects/）にて
tmuxinator stop .
```

## 最後に
よくあるのはhome配下（~/.config/tmuxinator/hoge.yml、~/.tmux.conf）にそれぞれ作るパターンみたいなのですが、今回の用途だとプロジェクトフォルダを作ってそこにソースと今回のymlファイルをまとめたく、このような構成になりました。
ここまで構築できれば、あとは実際のログ見るコマンドを設定するだけです。
目的に合わせて使っていければと思います。
Xdebug ブレークポイントで止まらない！


vscodeとxdegugで快適なデバッグ生活を送りたいと思いググりながら設定したのにブレークポイントで止まらない！

ハマった所をQiitaに残します

## 環境

Mac上にdocker環境を構築。

- docker
 - php-fpm (PHP v8.0.8)
 - xDegug v3.0,4
 - laravel 8

php-fpmのコンテナにxdebugを入れる
(今回は直接コンテナ入って実行してます）

```sh:
apk add autoconf build-base
pecl install xdebug
docker-php-ext-enable xdebug
```

## xdebugの設定でまずハマる！

google先生に「vscode　xdebug docker」等ででググるとxcodeのv2系の記事がヒットします。

https://qiita.com/gigosa/items/90431be7a6a79db78480

このような設定が書かれています。

```ini:php.ini
[xdebug]
xdebug.remote_enable=1
xdebug.remote_autostart=1
xdebug.remote_host=host.docker.internal
xdebug.remote_port=9001
xdebug.remote_log=/tmp/xdebug.log
```

が、Xdebugのv３系だとパラメータ名が変わってました！

```ini:php.ini
[xdebug]
xdebug.mode=debug
xdebug.start_with_request = yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9013
xdebug.discover_client_host = 1
```

インストールされてるXdebugのバージョンをよく確認しましょう。

```
/var/www # php -v
PHP 8.0.8 (cli) (built: Jul  1 2021 22:58:34) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.8, Copyright (c) Zend Technologies
    with Xdebug v3.0.4, Copyright (c) 2002-2021, by Derick Rethans
```

## vscodeのlaunch.jsonでハマる

vscodeにまずはPHP Degugを入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143303/00f730dc-bf1d-373e-d953-9441fa6e8054.png)

左の実行とデバッグからlaunch.jsonを編集
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143303/0c7df473-21ce-98ee-6a6a-aa686565f790.png)


launch.json

```json:launch.json
    "configurations": [
        {
            "name": "Listen for Xdebug",
            "type": "php",
            "request": "launch",
            "port": 9013,
            "pathMappings": {
                "/var/www": "${workspaceRoot}/laravel"
            }
        },
```

「pathMappings」ですが、「ドキュメントルート」を指定するという記事を見て混乱しました。
ここはドキュメントルートではなく、ローカルとコンテナ側でマウントしている同じパスをマッピングすれば良さそうでした。

## ブレークポイントを置いてブラウザでアクセス

あとは、ブレークポイントを置いてブラウザでページを開けばちゃんと止まる。

![vscode.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143303/2601d872-272a-f35f-2cd0-0be797a4f7f3.gif)


これで快適なデバッグ生活ができそうです
PIOでTTGO T-Displayのファクトリーイメージを再コンパイル・アップロード

過去から何パターンかあったようで... 本日時点の情報をまとめる。

Mac + VSCode + PIO を使用

VCPドライバーをインストールしておく。 

https://jp.silabs.com/developers/usb-to-uart-bridge-vcp-drivers 

PIOでこんな感じで新規プロジェクトを作成 
 ![GetImage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/75b09fbd-fac6-98ab-6ad1-0c2d9ddadd2b.png)

PIO Library メニューから Button2 をインストール。さらに Installed に移って，Reveal を押すと，保存されているディレクトリーが表示される。 

 

そこに，本家ページからダウンロードして解凍したTFT_eSPIフォルダーを丸ごとコピー。 

https://github.com/Xinyuan-LilyGO/TTGO-T-Display 

 

さらにその中の examples – FactoryTest の中身を，PIOプロジェクトのsrcにコピー。 
Bmp.h Button2.cpp Button2.h FactoryTest.ino の4つになる。 

 

FactoryTest.ino を main.cpp にリネーム。 

 

これで PIO: Upload でコンパイルと本体への書き込みができた！ 

 
本家サポートページ 

https://github.com/Xinyuan-LilyGO/TTGO-T-Display  

参考リンク 

https://www.fxfrog.com/2020/04/20/post-8558/ 
https://qiita.com/ELIXIR/items/96436f886eaf4f5a9b6e
複数サブドメインを1つのCloudFrontディストリビューションに向ける

slackって、チームごとにサブドメインが発行されますよね。たとえば、私がSlackチームを作ると
 `k5trismegistus.slack.com` といった具合に。

こういう風に、ユーザーとかグループごとにサブドメインをわけてサービスを提供できるWebサービスってどう作るのかなと思い、実験してみました。

## 前提

- インフラはAWS
- アプリケーションのフロントエンドはCloudFrontが配信する
- サービスは \*.app.example.com で配信する。\*に入る文字列をアプリケーションが使う(example.comは適宜お持ちのドメインに読み替えて)
- すでにexample.com はRoute53に登録されている

## アプリケーション側

アプリケーション側は、きちんと到達できてサブドメインの情報がとれればよいので、Nuxt.jsで簡単にサブドメインを表示するだけのアプリを実験用に作成し、S3においておきました。

１番下位のサブドメイン、つまりa.b.example.com だったら、a を表示するだけのサービスです。

https://github.com/k5trismegistus/nuxt_subdomain_test/blob/master/pages/index.vue

ちなみに、Nuxt.jsのSPAをS3にホストしてCloudFrontで配信するにはちょっと手間がいります。(CloudFront Functionsなりで、 /path へのリクエストを /path/index.html へのリクエストにする必要がある)

## Route53の設定(上)

Route53にapp.example.com のホステッドゾーンを作成します。そしたら、example.comのホステッドゾーンにapp.example.comのNSレコードを作成します。

### 参考

https://aws.amazon.com/jp/premiumsupport/knowledge-center/create-subdomain-route-53/

## 証明書の発行

ACMより、*.app.example.comの証明書を発行します。

DNSでの検証を行う場合、前述の

> そしたら、example.comのホステッドゾーンにapp.example.comのNSレコードを作成します。

もやっておく必要がありそうです。こちらもうっかり忘れないように。

## CloudFrontの設定

CloudFrontディストリビューションを作成し、オリジンはアプリケーション(この例の場合はS3バケット)を指定し、先程発行した証明書を付け、CNAMEのところに *.app.example.com と書いておきます。CNAMEの指定は、該当するドメインで証明書を発行しておく必要があります。

##Route53の設定

そしたら、app.example.comのホステッドゾーンに、先程つくったCloudFrontディストリビューションに向いたエイリアスレコードを作ります。先にCNAMEの設定をしておかないと候補に出てこないようです。

このとき、レコード名は *.app.example.com とします。

### 参考

https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/resource-record-sets-values-alias.html

## 完了

できました。

![09040032.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133157/3adebe43-8449-5758-439a-80ff9bffae4a.png)
axiosでAPI連携したときにconsoleにCORSエラーが出て表示されなかった件(Laravel×Vue.js)

#概要
Vue3とLaravel8を使ってAPI通信で遊んでいたら遭遇したエラーです。
遭遇したのが初めての内容だったので、備忘録も兼ねて記載させていただきます。

#エラー文

```console.logエラー
Access to XMLHttpRequest at 'https://newsapi.org/v2/everything?q=Economy&apiKey=32e3595e76c247fea16c5fd7d7bb2df2' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Request header field x-requested-with is not allowed by Access-Control-Allow-Headers in preflight response

```

#事象が発生したタイミング

News API利用時に発生
AXIOSでAPI通信を実施した際に、コンソールにエラー表示確認。
通信が遮断され、データのResponse確認できず困ってしまった・・・。

#解決方法

resources/js/bootstrap.jsにて

```jsx:resources/js/bootstrap.js
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
```

が記載されているため、通信ができなかった。

コメントアウトして解決。

参考にさせていただいたサイト。
https://cpoint-lab.co.jp/article/202104/19526/

#そもそもCORSってなんじゃ？

MDNに記載がありました。

CORS (オリジン間リソース共有、 Cross-Origin Resource Sharing) は、 HTTP ヘッダーの転送で構成されるシステムであり、ブラウザーがオリジンをまたいだリクエストのレスポンスに、フロントエンドの JavaScript コードがアクセスすることをブロックするかどうかを決めるものです。

だそうです。
ほえ〜、そんな機能があるんだなぁ。

ソース。
https://developer.mozilla.org/ja/docs/Glossary/CORS

#最後に
いかがだったでしょうか。
今後もvue.js,Laravel中心に記事書いていきますので、フォローお願いします！
Unityでpng形式画像をsprite素材に変換する方法

# はじめに
突然ですが、このような画像をみたことありますか？

![$PW-DogBeagle01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153882/a13289f5-dbcb-9dd4-1c09-5da07e627c91.png)

[出典：ドット絵世界](http://yms.main.jp/)

こういったpng形式の画像をUnityに取り込んで実際にオブジェクトを配置するやり方を紹介します。

# 画像データをUnityに取り込む。
簡単です。
Projectエリアにドラッグ&ドロップで簡単に取り込めます。
![スクリーンショット (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153882/56d3f503-8f24-712b-7606-7bee2106caa0.png)

このような感じになればOK

# 画像の切り取りルールを設定する。
ただのpng画像を取り込んだだけだと、画像全体が一つの素材とみなされてしまうので、どの範囲が一つの素材なのかを指定してやる必要があります。
→　なるべく、等間隔で素材が並んでいる一枚絵が好ましいです。

先ほど取り込んだ画像をクリックすると、Inspectorエリア中部に、Sprite Modeのタブがあるので、それを「Single」→ 「Multiple」へ変更します。

Sprite Editorをクリックして開きます。

![スクリーンショット (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153882/b040a7c3-a2c2-f96b-74a7-7e64e9eac27b.png)

# Sprite Editor
ここでSpriteをどのルールで切り取るか決めていきます。
上メニューのSliceを押して、TypeをAutomaticにすれば、大抵よしなに切り取ってくれます。
Sliceを押して、警告が出たらApplyを押しましょう。

すると画像のように、各わんこが白い枠で囲われると思います。
自分が思った通りに切り取られたら成功です。

Automaticでうまくいかないときは、Grid By Cell Sizeなどに変更して各自調整を行ってください。

![スクリーンショット (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153882/6e10796d-6df7-e4b7-91bb-e0c3c729efc3.png)

#確認
ここまできたらSprite Editorは閉じてOKです。
ちゃんと素材が切り出されているか確認しましょう。

Projectエリアの先ほどの画像の横にある再生ボタンのような三角を押して展開押して画像のように分解されていれば成功です！

![スクリーンショット (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153882/652ce698-3fe2-8768-7468-d8d59a6f6b5f.png)

このように、フリー素材を活用してSpriteに切り出せると、個人でも開発の幅が広がりますね！
ぜひ試してみてください。
Rails HTTPメソッドとREST APIについて

# HTTPメソッドとは
クライアントからサーバーにこういうことをやりたいと伝えるためのものです。

⚫︎どういうことを伝えるのか

ex)
このデータを消してくれ　更新してくれ、そのデータをよこせと
お願いをします。これが```メソッド(HTtPメソッドリクエスト)```です。

クライアントとサーバーについては

https://qiita.com/Hashimoto-Noriaki/items/c5c9eb26565b01150556

から参照してください。

# よくHTTPメソッドの種類
よく使うHTTPメソッドは4つです。
|メソッド|
|--|
|***GET***|
|***POST***|
|***PUT***|
|***DELETE***|
 
それぞれ見ていきましょう。

***1 GET***  
***データ(リソースの取得)***
例えば　webページやAPIのデータをよこせみたいなお願いの時使います。

***2 POST***
***データの送信***
主に***新規作成***をしろとお願いをする時に使います。
例えば新しくアカウントを作る時やブログを新規で投稿するときです。

***3 PUT***
***データの送信
主に***すでにあるデータを更新する時に使います。***
例えば記事の更新や編集する時に使います。

***4 DELETE***
***データの削除***
上の説明だけでわかりますよね。
例えば　アカウント削除など削除関連はDELETEを使います。

# いろいろなHTTPメソッド
上の４つはよく使うものですが他にもあるみたいです。
ここは参考記事の
https://qiita.com/fukuma_biz/items/a9e8d18467fe3e04068e
から引用します。

|HEAD|リソースのヘッダ (メタデータの取得)|
|--|--|
|OPTIONS|リソースがサポートしているメソッドの取得|
|TRACE|プロキシ動作の確認|
|CONNECT|プロキシ動作のトンネル接続への変更|
|LINK|ちょっくらそのURLとこっちのリソースをくっつけさせてね|
|UNLINK|「LINK」を解除するよ～|
|PATCH|ちょっくら、データの一部を変えさせて|


⚫︎ちなみに***プロキシ***とは?
クライアントからサーバーにリクエストまたはレスポンスを返すときに
クライアントとサーバーの間にある両者の中継地点に当たるのがプロキシサーバーです。

⚫︎プロキシサーバーの役割は?
下の記事の言葉を借りると、
会社の社内ネットワークでインターネット接続をするときに、
コンピューターウイルスや不正アクセスなどのトラブルがあった時に、
それらから自分たちが使うネットワークを守ってくれる役割があります。


プロキシについて詳しくはこちらから
https://cybersecurity-jp.com/column/32171

# REST API(RESTful API)について
REST APIは上のよく使う4つのHTTPメソッドを使ってAPIで実装することです。
今回はstaffを例にします。

今回の***APIのURLは/staffs/:id***を基本に説明します。

***1 GET/staffs/1***
これはGET/staffs/1でリクエストをするとスタッフIDの1の人の情報を返してくれます。

***2 POST/staffs***
これは新規作成で使うのので/1はつきません。新規作成された後にidが付くからです。

***3 PUT/staffs/1***
PUT/staffs/1をリクエストする時、staff名も一緒にサーバーに送ると、
スタッフIDが1のスタッフの名前を更新できます。
またセキュリティとしてスタッフIDが1のスタッフがログインしていないと
処理が行えないようにしています。

***4 DElETE/staffs/1***
削除したいstaffのIDがわかっているのでデータを送ることはしません。
スタッフIDが１の人しか削除できないようにしています。



⚫︎補足
もちろんIDはデータに入っている数に夜ので数字は１以外もできます。

# REST API(RESTful API)とは
URLは同じだが、HTTPメソッドが変わると処理を切り替えられます。
これができるAPIのことが REST APIです。

記事を結構引用「してしまいましたがREST APIの定義はかなり広いみたいなので
いろいろ調べてみてください。

⚫︎参考資料
https://qiita.com/fukuma_biz/items/a9e8d18467fe3e04068e
https://wa3.i-3-i.info/word11405.html
https://tsuyopon.xyz/2019/01/31/understand-4-http-methods/
Windows アプリから WSL2 のファイルを読み書きする

# これは何?

WSL2 のファイルに、Windows のアプリから読み書きする方法です。

# 結論

[Windows 10 でネットワークドライブを割り当てる](https://support.microsoft.com/ja-jp/windows/windows-10-%E3%81%A7%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF-%E3%83%89%E3%83%A9%E3%82%A4%E3%83%96%E3%82%92%E5%89%B2%E3%82%8A%E5%BD%93%E3%81%A6%E3%82%8B-29ce55d1-34e3-a7e2-4801-131475f9557d) 方法に従って、 `\\wsl$\<distribution>` を適当なドライブに割り当てます。

もしくは、下記のように [PowerShellからネットワークドライブの割り当て](https://win.just4fun.biz/?PowerShell/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%89%E3%83%A9%E3%82%A4%E3%83%96%E3%81%AE%E6%8E%A5%E7%B6%9A%E3%83%BB%E5%88%87%E6%96%AD%E6%96%B9%E6%B3%95)ます。

```PowerShell
New-PSDrive -Persist -Name <ドライブ文字> -PSProvider FileSystem -Root \\WSL$\<ディストリビューション名>
```

# WSL と エクスプローラーとのファイルアクセス

https://qiita.com/quzq/items/1096c638c0d86795be13

に記載の通り、エクスプローラーからネットワーク `\\wsl$` に WSL の各ディストリビューションを見ることができます。
ネットワーク共有は既にされていることがわかります。

通常の Windows アプリは、ドライブ文字から始まるファイルパスじゃないとアクセスできません。
逆に言うとドライブ文字があればアクセスできます。

# コマンドプロンプトからアクセス確認

```PowerShell
New-PSDrive -Persist -Name U -PSProvider FileSystem -Root \\WSL$\Ubuntu
```
として、`U:\` に割り当てました。
アクセスを確認してみます。

```console
C:\>cd /d U:\

U:\>dir
 ドライブ U のボリューム ラベルがありません。
 ボリューム シリアル番号は 0000-0000 です

 U:\ のディレクトリ

2020/11/02  20:19    <DIR>          home
2020/08/05  06:39    <DIR>          srv
2021/09/03  21:37    <DIR>          etc
2020/08/05  06:39    <DIR>          opt
2021/02/19  21:47    <DIR>          root
2020/08/05  06:39    <JUNCTION>     lib [...]
2020/11/12  00:21    <DIR>          mnt
2021/04/16  01:07    <DIR>          usr
2020/08/05  06:39    <DIR>          media
2020/08/05  06:39    <JUNCTION>     lib64 [...]
2021/09/03  21:37    <DIR>          sys
2021/09/03  21:37    <DIR>          dev
2020/08/05  06:39    <JUNCTION>     sbin [...]
2020/08/05  06:47    <DIR>          boot
2020/08/05  06:39    <JUNCTION>     bin [...]
2021/09/03  21:37    <DIR>          run
2020/08/05  06:39    <JUNCTION>     lib32 [...]
2020/08/05  06:39    <JUNCTION>     libx32 [...]
2021/03/12  13:06           632,048 init
2021/09/03  21:37    <DIR>          proc
2020/07/10  22:59    <DIR>          snap
2021/08/24  20:39    <DIR>          tmp
2020/08/05  06:42    <DIR>          var
2019/04/11  01:35    <DIR>          lost+found
2021/09/03  21:37    <DIR>          ..
2021/09/03  21:37    <DIR>          .
               7 個のファイル             632,098 バイト
              19 個のディレクトリ  249,866,919,936 バイトの空き領域
```

普通にアクセスできます。 Windows Emacs でも余裕でファイル開けます。

# 感想

めっちゃ便利。 Windows Emacs から tramp とか要らなかったんや。
WSL2 に SSH ログインとか要らんのだ。
【備忘録】Wordpress(EC2)をELB経由でHTTPS通信にするときにハマったポイント

# AWSでWordpress立ち上げようと思ってしまった
きっかけは、[AWSのハンズオン](https://scalable-webapp-on-ec2.workshop.aws/)。
ここまで構築はなんなく出来た（資料あるし）。
「折角作った環境だから、セキュアなHTTPS通信にしよう」と意気込んだ途端、いろんな落とし穴に落とされてしまった。

このつまずいたポイントを列記した。
流れは、以下の通りである。詳しい方法はいくつかのURLを参照した。
※[料金](https://aws.amazon.com/jp/pricing/)が発生する作業もあるため、予め確認してほしい。

## プロセス
１. VPCを作成
２. EC2を作成(Wordpressインストール)
３. RDSを作成
４. ELBを作成
５. Wordpress設定(RDS等)
６. マルチAZ化
↑ここまでは[AWSのハンズオン](https://scalable-webapp-on-ec2.workshop.aws/)で詳しく解説されている。

７. Route53でドメイン購入（ドメイン登録は[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/registrar.html)）
８. ACMで証明書発行
９. ELBリスナーにHTTPSを追加
１０. Route53にELBと(サブ)ドメインを紐付け(Aレコード)
１１. WordpressでHTTPS設定

## ハマったポイント
### 【★☆☆】証明書の検証中で止まる(ACMで証明書発行)
完全なぽかミス。DNSの検証を選択したワケだが、検証のためにCNAMEを登録する必要があった。
`Route53でのレコードの作成`を押下したら、`成功`にステータスが変わった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59451/b8f4a024-b792-18c1-dfb9-4726c3086e39.png)

### 【★★☆】HTTS通信で`503 Bad Gateway`(ELBリスナーにHTTPSを追加)
ELBのリスナーにHTTPSを追加するまでは良かった。
リスナーのターゲット先でポート443の通信させるように設定していたのだが、
`https://～`でアクセスすると`503 Bad Gateway`が出てしまった。
セキュリティを見直したり、EC2の設定を見直したりしたが解消されなかった。
以下のサイトを見つけて、ようやく解決した。

https://zenn.dev/tikka/articles/6109990725a0f417d058

> HTTPS化をしたいのであればACMを使ってALBに証明書を設定すれば十分で、ALB→インスタンス間の通信はAWS内部の通信なので、そこに関しては基本的にHTTPで問題ありません。

### 【★☆☆】サブドメインが「保護されていない通信」(ACMで証明書発行)
AMCで発行した証明書がワイルドカードの形になっていなかったことが原因。
`ドメインの追加`のところで`*.XXXXX.XXX`の形にすれば良かった。
アスタリスクだけでは、ゾーンエイペックス（サブドメインではない、ドメイン自体）が登録されないので、一緒に登録しておく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59451/73e23b94-102b-9a0d-b842-9f1b8c45f694.png)

### 【★★★】 HTTPS通信で表示崩れ(WordpressでHTTPS設定)
HTTPS通信でアクセスすると表示崩れしてしまう。
検索をすると`Really Simple SSL`プラグインがオススメと言う記事がたくさん出てきた。
ただ、今回のようにELBで証明書を当てているWorpressではうまく行かない。
以下のサイト等を読んで、解決した。

https://www.d-wood.com/blog/2017/11/29_9354.html

原因は、HTTPSでアクセスしているのに、ELBのせいでHTTPでCSSやJSを読みに行ってしまうためとのこと。
以下のファイルに、ELB側でHTTPS通信があったら内部もHTTPS通信で行うように記述。

```bash
sudo vi /var/www/html/wp-config.php
```

以下を追記

```php
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
    $_SERVER['HTTPS'] = 'on';
```

Apache再起動

 ```bash
sudo systemctl restart httpd.service
 ```

以上をクリアし、無事に常時SSLのページを公開することができた。
画像認識(自分で画像用意)での備忘録

Pythonのsklearn（SVM）で画像認識の機械学習をする上で学んだことを備忘録として記録する。

#読み込み
ある特定のファイルに存在する画像データを一括で読み込む
→globを使用する
一例：testフォルダにあるJPGファイルを全て読み込む

```
import glob
file = glob.glob("/Users/Apple/Desktop/test/*JPG")
file
```
　これにより画像ファイル名がリストとして読み込まれる。
　画像データとして活用するにはこの後OpenCVでimreadが必要

#特徴量変数の作成
複数の画像を一つずつimreadで読み込んでimgに入れたのち、appendで空のリストに追加。それをarrayにする。

```
file_list= []

for i in file:
    img = cv2.imread(i)
    file_list.append(img)

file_arr = np.array(file_list)
```
　imreadはndarrayを返すので、この処理でリストの中にarrayが入る形となる。
　appendでリストに入れる方法をしないと、繰り返し処理でimgが上書きされてしまう。

　*2021.10.14追記
　上記コードではfileの中の"ファイル名"を読みに行ってNoneを返すことがある。
　正しくは下記がよい。

```
file_list= []

for i in range(len(file)):
    img = cv2.imread(file[i])
    file_list.append(img)

file_arr = np.array(file_list)
```

#正解ラベルの作成
特徴量変数の数に応じて、np.zeros, np.onesで作成
機械学習でyとして代入するためには、0と1を結合したものにしなければならない。
→ndarray同士では作れないので、一度リストにして結合したのちにndarrayに戻す。
一例としてラベル0と1をそれぞれ2つずつ作り、一つにまとめたもの

```
label_0 = np.zeros(2) #ラベル0作成 ndarray
label_1 = np.ones(2) #ラベル1作成 ndarray
label_0_list = label_0.tolist() #リスト化
label_1_list = label_1.tolist() #リスト化
label_list = label_0_list + label_1_list #リスト結合
label = np.array(label_list) #ndarrayに戻す
label #ラベル完成
```




#エラー対応（Found input variables with inconsistent numbers of samples: ）

```
from sklearn.model_selection import train_test_split
from sklearn import svm, metrics
from sklearn.metrics import accuracy_score

x = file_arr
y = label

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2)
clf = svm.LinearSVC()
clf.fit(x_train, y_train)
```
clf.fit(x_train, y_train)の時に下記エラー発生。
ValueError: Found input variables with inconsistent numbers of samples: 
→Numpy配列のshapeでxとyの行数を揃えれば解決。
[行数揃え](https://it-ojisan.tokyo/train_test_split-valueerror-found-input-variables-with-inconsistent-numbers-of-samples/)
→行数を合わせるとき、reshape引数に-1を入れると、変換元の要素数に合わせて自動で値が決定するため、簡単に補正できる。
【Laravel】find()とfindOrFail()の違い

# find()とfindOrFail()とは
Laravelで提供されているデータ操作の為の機能であるEloquent ORMのメソッドのひとつ。指定したidのレコードを取得することができる。

# 2つのメソッドの違い
## 定義の仕方
### find()

```PHP:
$flight = App\Flight::find(1);
```

### findOrFail()

```PHP:
$flight = App\Flight::findOrFail((1);
```

## idが見つからなかったとき
* find()：nullを返す。
* findOrFail()：エラー（404HTTPレスポンス）を返す。例外処理。

# どちらを使うべきか
### findOrFail()の方が良い（と思う）
* 見つからなかった時に、nullかエラーか、どっちを出したいかで決めると良い。

## find()


* 全然違う場所にエラーが出てしまい、原因を見つけることが難しい。
* コントローラーでid番号を探すクエリを出したのに、エラー画面では、Viewファイルでエラーがあると出てしまう。

## findOrFail()

* 詳細なエラーが原因がわからないことがデメリット。
* ユーザーにエラー画面を見せたくないときはこっち。


## ただし…

* 「find()でnullが出たら〇〇する」のような、if文、条件分岐を続けて使うのであれば、find()を使った方が、条件分岐を書きやすい。
* 仮にfind()を使ってても、.envファイルを開いて、APP_DEBUGをtrueからfalseに書き換えれば、同じように、404 | Not Foundが表示されるようになる。


# 参考記事

* [Laravel 6.x Eloquent：利用の開始](https://readouble.com/laravel/6.x/ja/eloquent.html)
* [Laravelのfind()とfindOrFail()の違い、使い分け方。初心者もよく分かる！](https://nebikatsu.com/8589.html/)
MySQL sorceコマンド

## sourceコマンドでテキストファイルからSQLを実行する。
* MySQLにログイン
* C:\ProgramData\Temp 等にsourceファイルを保存する
* sourceコマンドを実行する

## sourceファイルを保存
C:\ProgramData\Temp などにsourceファイルを保存する

##sourceコマンド
【ポイント】
コマンドプロンプトに**sourceファイルをドラッグ＆ドロップ**するとフルパスが自動入力される。

```:sql
source C:\ProgramData\Temp\ファイル名.sql
```
* sourceファイルの拡張子は.txtでも.dllでも.sqlでもOK。
* 実行結果が成功なら、Query OK,と表示される。

##sourceファイル 中身の例(データベースとテーブル定義)
```:sql
-- ※1
DROP DATABASE IF EXISTS `サンプルデータベース`;
CREATE DATABASE `サンプルデータベース` COLLATE utf8mb4_ja_0900_as_cs_ks;

-- ※2
USE `サンプルデータベース`;

-- ※3
DROP TABLE IF EXISTS `サンプルテーブル`;
CREATE TABLE `サンプルテーブル` (
  `id` int(5) NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(50) NOT NULL,
  `flag_display` BIT(1) default 1,
  `registration_date` DATETIME DEFAULT CURRENT_TIMESTAMP,

  PRIMARY KEY (`列名ID`)
) COLLATE utf8mb4_ja_0900_as_cs_ks;

```
* ※1 もし既に`サンプルデータベース`が存在していたら消す
* ※2 USEがないと「ERROR 1046 (3D000) at line 10: No database selected」が表示される。
* ※3 列名IDは「AUTO‗INCREMENT」を設定しているが、必要ないなら、外しても良い。
* ※3 テーブル内定義にミスがあるとDBのみ作成されて、テーブルは作成されない。
→例えば、intのDEFAULTに" "を設定すると、型が合わないのでエラーとなる。
* デフォルトの値を付けたい場合は「DATETIME DEFAULT CURRENT_TIMESTAMP」のように設定する。<br>
→【公式】https://www.dbonline.jp/mysql/table/index6.html<br>
→【参考】https://mikepon.jp/mysql-create-update-at/

##外部キー設定する場合
```
FOREIGN KEY 外部キー名(子カラム名) REFERENCES 親テーブル名(親カラム名))
```
|項目|説明||
|----|----|----|
|FOREIGN KEY|自分のカラムで外部キーにするもの||

```:例
CREATE TABLE hogehuga(
/* 中略*/
   PRIMARY KEY(sample_id),
   FOREIGN KEY hoge_id(hoge_id) REFERENCES hogeTable(hoge_id)),
   FOREIGN KEY huga_id(huga_id) REFERENCES hugaTable(huga_id))
)COLLATE utf8mb4_ja_0900_as_cs_ks;
```
https://www.dbonline.jp/mysql/table/index11.html
https://www.techscore.com/tech/sql/SQL3/03_04.html/
【Laravel】テーブルのリレーションについて

#リレーションとは
テーブル同士の関連付けのことを言います。
リレーションにはいくつかの種類があり、それぞれ関連付け方が異なります。
早速、リレーションの種類を１つ１つ見ていきたいのですが、ここでは主テーブルをuserテーブル、従テーブルをpostテーブルとして説明していきます。
※今回は、コントローラーやビューの記述は割愛させていただきます。

#リレーションの種類
##has One
「１対１」の関係で、主テーブルは従テーブルからデータを引っ張ってくることができます。
主テーブル側のUserモデルに以下のように記述します。

```php:User.php
public function post()
{
    return $this->hasOne('App\Models\Post');
}
```

##has Many
「１対多」の関係で、これも`hasOne`と同様、主テーブルが従テーブルからデータを引っ張ってきます。
主テーブル側のUserモデルに以下のように記述します。
`hasOne`は１対１でデータを１つしか取り出さないので`post`と単数形でしたが、`hasMany`では複数のデータを取り出すので`posts`と複数形にします。

```php:User.php
public function posts()
{
    return $this->hasMany('App\Models\Post');
}
```

##belongs To
`hasOne`や`hasMany`と異なり、従テーブルから主テーブルのデータを取り出します。
従テーブル側のPostモデルに以下のように記述します。

```php:Post.php
public function user()
{
    return $this->belongsTo('App\Models\User');
}
```

#おわりに
モデルへの記述にしぼって簡単に説明させていただきました。
何かご指摘等あればお申し付けください。
railsチュートリアル第４章 メソッドの定義

###演習
1.lengthメソッドを使って調べろ

```rb
>> a = "racecar"
=> "racecar"
>> a.length
=> 7
```
2.reverseメソッドを使って調べろ

```rb
>> a.reverse
=> "racecar"
```

3.等しいか比べろ

```rb
>> s = "racecar"
=> "racecar"
>> s == s.reverse
=> true
```
等しかった。

4.```puts "It's a palindrome!" if s ==s.reverse
```を実行するとどうなるか？

```rb
>> puts "It's a palindrome!" if s == s.reverse
It's a palindrome!
=> nil
```
nilが帰ってきた。
なんで？

```
puts "foo"は文字列「"foo"」を副作用としてスクリーンに表示しますが、戻り値には「文字どおりの無」であるnilを返します
予想ではsと等しい時に表示させると思う。
```
なんかわからんけど
スクリーンに表示させると戻り値はnilが帰ってくるらしい。

###メソッドの定義
homeアクションや、リスト 4.2のfull_titleヘルパーと同じ方法でメソッドを定義することができます

```rb
>> def string_message(str = '')
>>   if str.empty?
>>     "It's an empty string!"
>>   else
>>     "The string is nonempty."
>>   end
>> end
=> :string_message
>> puts string_message("foobar")
The string is nonempty.
>> puts string_message("")
It's an empty string!
>> puts string_message
It's an empty string!
```
メソッドの引数を省略することも可能です

```def string_message(str = '')```
引数にデフォルト値を含めているからです（この例のデフォルト値は空の文字列です）
str変数に引数を渡すことも渡さないこともできます。
指定のデフォルト値が自動的に使われます。

Rubyのメソッドには「暗黙の戻り値がある」
それは
メソッド内で最後に評価された式の値が自動的に返されること

```rb
>> def string_message(the_function_argument = '')
>>   if the_function_argument.empty?
>>     "It's an empty string!"
>>   else
>>     "The string is nonempty."
>>   end
>> end
=> :string_message
>> puts string_message("")
It's an empty string!
>> puts string_message("foobar")
The string is nonempty.
```
2番目のreturnは実はなくても良い。
メソッド内の最後に置かれた式```"The string is nonempty."```は、returnキーワードがなくても暗黙で値を返すため

両方にreturnを使う方が見た目の対称性が保たれるので好ましいと言える。

####演習
```rb
>> def palindrome_tester(s)
>>   if FILL_IN
>>     puts "It's a palindrome!"
>>   else
>>     puts "It's not a palindrome."
>>   end
>> end
```
1.FILL_INの部分を適切なコードに置き換え、回文かどうかをチェック

```rb
>> def palindrome_tester(s)
>>   if s == s.reverse
>>     puts "It's a palindrome!"
>>   else
>>     puts "It's not a palindrome."
>>   end
>> end
=> :palindrome_tester
```

2.上で定義したメソッドを使って “racecar” と “onomatopoeia” が回文かどうかを確かめろ

```rb
>> puts palindrome_tester("racecar")
It's a palindrome!

=> nil
>> puts palindrome_tester("onomatopeia")
It's not a palindrome.

=> nil
```

3.```palindrome_tester("racecar")```に対してnil?メソッドを呼び出し、戻り値がnilであるかどうかを確認しろ

```rb
>> puts palindrome_tester("racecar").nil?
It's a palindrome!
true
=> nil
```
文字列が返されたのでnilになった。
前に文字列を表示させた時にnilが返されたことがあったのを思い出した。
[Rails] ArgumentError Nil location provided. Can't build URI. が出た時の対処法　

# ArgumentError
![スクリーンショット 2021-09-03 22.04.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1572216/8db3023b-0afd-c385-d23a-fc0654fcff50.png)

Nil location provided. Can't build URI.
『提供された場所はありません。 URIを構築できません。』と怒られました:japanese_ogre:

# SQLで確認
![スクリーンショット 2021-09-03 22.37.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1572216/af0a406e-d70f-9685-f4cd-0ceab317000a.png)

今回、怒られたproduct.image_idを確認したらnilであった

# 解決方法

当該のviewページを確認したら、nilの場合の条件をつけていませんでした....

```erb
      <div class="mt-3" >
      <%= image_tag attachment_url(@product, :image, :fill, 250, 200 ) %>
      </div>
```
↓

```erb
      <% if @product.image_id.blank? %>
        <%= attachment_image_tag @product, :image, fallback:"no-image.png", size: '220x185' %>
      <% else%>
        <%= image_tag attachment_url(@product, :image, :fill, 250, 200 ) %>
      <% end %>
```

blank?メソッドは真偽値を返すので、if文を使ってオブジェクトが空白の場合と空白ではない場合で処理を分ける際に便利です。

```rb
if オブジェクト.blank?
  # オブジェクトが空白の場合の処理
else
  # オブジェクトが空白ではない場合の処理
end

```

この要領で画像:有、無しの処理を分岐しました！

エラーを切り分けていくことで無事解決できました！:heart_eyes:
git githubを勉強中

git githubを動画やgithub実践入門で学習しています。
git githubの概念や使い方ですがなんとなくですが理解ができました。
gitはプログラミングコードを管理するものだと理解が出来ました。
新しいコードを管理したり、新しいコードに不具合が出た場合に元に戻したりとするときに非常に便利なものだと理解ができました。
それをWeb上で管理するものがgithubだと言うことも理解ができました。

gitの使い方ですが・・・
まずパソコンにファイルを作成
ターミナルでgitを立ち上げ
ワークツリーにコードを保存
ステージングエリアにコピー
ローカルリポジトリに保存
と言う流れだと理解はできました。
ローカルリポジトリをWeb上で管理するのがgithubだとも理解ができました。

githubの使い方はあまりわかりません。
なぜならばチーム開発をするのには非常に便利だと思いましたが・・・
自分自身チームを持っていないので使えていないからです。
ですが、githubを使いこなせればすごく便利だとも思いました。
色々な人がソースコードを公開していてそれを利用できるというのは非常に便利だと思いました。

躓いた点ですが・・・。
gitからgithubへプッシュしようとすると
（remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
fatal: Authentication failed for 'https://github.com/daisuke-REIJI/github_practice.git/'）
と出ます。
調べた結果パスワードが使えないみたいです
どうすればいいかわかりません。
なので教えていただきたいと思います。
EC2 Global View とは

## 勉強前イメージ

新しいEC2の機能？
EC2の全部を見れる的な感じがする

## 調査

### EC2 Global View とは

単一の画面で、EC2の全リージョンのリソースを表示することができるサービスで
これまではEC2のリージョンごとのリソースしか見れなかったのですが
EC2 Global Viewを使うことで全体を見ることが可能になりました。

### 見てみる

- コンソールから検索

`EC2 Global View` で検索すると出てきます。

![1EC2 Global View - Google Chrome 2021-09-03 22.13.4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/0e60494c-1362-607d-6d3f-082b8aba155b.png)


- 見れるもの(リージョンエクスプローラー)

リソースの概要とリージョンあたりのリソース名が見れます。
リソースの概要は、インスタンスやボリュームなどどれだけあるか確認できます。
また、リージョンあたりのインスタンス数やボリュームも下で見れます。

![2EC2 Global View - Google Chrome 2021-09-03 22.14.5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/19c984f0-c8ea-ad6c-1495-59f6b5b4c4ce.png)


- 見れるもの(グローバル検索)

名前やリソースIDなどで検索もできます。

![3EC2 Global View - Google Chrome 2021-09-03 22.20.3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/52564661-ab27-f9e8-41bf-d624f659ffd5.png)


## 勉強後イメージ

リージョン間移行するときとか便利よね。
あとこのリソースIDどこ？みたいに探すときとか。

## 参考

- [[アップデート] 全リージョンを一望できる EC2 Global View が登場](https://dev.classmethod.jp/articles/ec2-global-view/)
AtCoderログ：0101 - ABC 216 C

# 問題

https://atcoder.jp/contests/abc216/tasks/abc216_c

## 問題文
> 空の箱があります。
> 髙橋君は以下の $2$ 種類の魔法を好きな順番で好きな回数使えます。
> ・魔法 A ：箱の中にボールを $1$ つ増やす
> ・魔法 B ：箱の中のボールの数を $2$ 倍にする
> 合計 $120$ 回以内の魔法で、箱の中のボールの数をちょうど $N$ 個にする方法を $1$ つ教えてください。なお、与えられた制約のもとで条件を満たす方法が必ず存在することが示せます。
> 魔法以外の方法でボールの数を変化させることはできません。

## 制約
> ・$1 \le N \le 10^{18}$
> ・入力は全て整数

# 回答
## 回答1 (AC)
魔法の操作が例えば ABABBA の場合、箱の中のボールの数は 0 → 1 → 2 → 3 → 6 → 12 → 13 と変化しますが、これを２進表現で記すと 0 → 1 → 10 → 11 → 110 → 1100 → 1101 となり、数字の並びと文字の並び (最初の A だけ 1, 残りは BAS=1, B=0 とみなす) が対応していることがわかります。そこで $N$ の２進展開求め、1 と 0 の並びから魔法を決めていけば良いでしょう。コードは以下のようになりました。

```C++:abc216c-1.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int64_t n;
  cin >> n;

  vector<int> d;
  while ( n>0 ) {
    d.push_back(n%2);
    n /= 2;
  }

  cout << "A";
  for ( int i=(int)d.size()-2; i>=0; i-- ) {
    cout << "B";
    if ( d.at(i)==1 ) {
      cout << "A";
    }
  }

}
```

$N$ が $n$ ビットの時、このコードは $n$ 個の A と最大 $n-1$ 個の B を出力します。$N$ の最大値 $10^{18}$ は60ビットなので、このコードが出力する文字の個数は最大119個であり、「120個以内」という条件をギリギリクリヤしていることがわかります。

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc216/tasks/abc216_c/editorial) → [公式解説](https://atcoder.jp/contests/abc216/editorial/2468)
回答1と同じ方針です。

## [AtCoder の解説](https://atcoder.jp/contests/abc216/tasks/abc216_c/editorial) → [公式解説](https://atcoder.jp/contests/abc216/editorial/2503)
２進展開を逆から使用する解法でした。

## [AtCoder の解説](https://atcoder.jp/contests/abc216/tasks/abc216_c/editorial) → [ユーザ解説](https://blog.hamayanhamayan.com/entry/2021/08/29/230859)
２進展開を逆から使用する解法でした。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0100 - 記事が100個目になりました](https://qiita.com/RoadLynton/items/4a6bfd6815fc29568a74)
- 次の記事 → [AtCoderログ：0102 - ABC 217 に参加しました](https://qiita.com/RoadLynton/items/17d83d58948355c23593)
新しく開いたブックを特定する


#概要
　マクロの実行中に新しくブックを開いた場合に，そのブックの名前を把握したい場面がありました。
　通常は名前を指定して開くことが多いですが，開いたときにはじめて名前が決まるなど，開いた時点では名前を把握できない場合を想定しています。

#コード
```vb:VBE
    Dim preBooksStr As String
    Dim preBook As Workbook
        For Each preBook In Workbooks
            preBooksStr = preBooksStr & preBook.FullName
        Next preBook
    
    'ブックを開く処理

    Dim newBook As Workbook
    Dim book As Workbook
        For Each book In Workbooks
            If InStr(preBooksStr, book.FullName) = 0 Then
                Set newBook = book
                Exit For
            End If
        Next book
    MsgBox newBook.Name
```

![2021-09-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/be9a5f3e-1af6-b7f1-ca19-cf5e0b2ad5a9.png)
　このマクロではメッセージボックスでブック名を表示しますが，newBookがブックのオブジェクトになるので，どのようにも使えます。


```vb:VBE
    Dim preBooksStr As String
    Dim preBook As Workbook
        For Each preBook In Workbooks
            preBooksStr = preBooksStr & preBook.FullName
        Next preBook
```
　まず，変数preBooksStrに元々開かれているブックのフルパスを全て加え，一つの文字列にします。
　Nameプロパティでもよほど大丈夫でしょうが，FullNameでフルパスを持ってくれば重複がないので安心です。

```vb:VBE
    Dim newBook As Workbook
    Dim book As Workbook
        For Each book In Workbooks
            If InStr(preBooksStr, book.FullName) = 0 Then
                Set newBook = book
                Exit For
            End If
        Next book
```
 ブックを開いたら，現在開いているブックのコレクションのフルパスが，変数preBooksStrに含まれているかをチェックします。preBooksStrには，元々開かれていたブックのパスが全て含まれていますから，新しく開かれたブック名のみがはじかれます(InStrの値が0になる)。

 複数のブックを新たに開く場合には，Exit Forをしなければ，InStrのIf文内で処理ができます。

```vb:VBE
    Dim newBook As Workbook
    Dim book As Workbook
        For Each book In Workbooks
            If InStr(preBooksStr, book.FullName) = 0 Then
                book.Close (False)'ここで処理をする（ブックを閉じる例）
            End If
        Next book
```

　既存のブックのコレクションを作って，新しいブックのコレクションとぶつけてというのは効率が悪いので，ブック名のみを集めて文字列でチェックをかけるのがよいかなと思います。
Avoid method calls or property accesses on a "dynamic" targetの警告がとれない時



Flutterを書いていて地味にハマった部分があったので共有します。

```list dynamic ' is not a subtype of type cast```
↑Listにキャストしようとするとよくこのエラーを吐きますよね。

これの対処法として検索したらよく出てくるものとして

```dart
final hogeList = responseJson.cast<Map<String, dynamic>>() as List<Map<String, dynamic>>
```

これでクラッシュ自体はしなくなりますが、警告が出続けるんですよね・・・

```Avoid method calls or property accesses on a "dynamic" target```
↑これをなくすためには

```dart
final hogeList = (responseJson as List).cast<Map<String, dynamic>>();
```

上記のように書き換えれば直りました
ページ内の文字列を検索してフィルタリングするコンポーネント

## ページ内の文字列を検索して、それだけ残す
#### こんなかんじに検索して、絞り込むものを作ります。
![2021-09-03 21_44_36-【コンペヤ】物件同士が比較しやすい部屋探しサイト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369162/72d3888d-967d-963f-81e2-97f6ca80d9af.png)
![2021-09-03 21_45_08-【コンペヤ】物件同士が比較しやすい部屋探しサイト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369162/3f7de83a-a44f-142f-d7df-12b6c1158812.png)
前提として、環境は
・Next.js
・TypeScript
となっています。
※アイコンとかは違うコンポーネントなので省略して書きます。

```tsx:index.tsx
import styles from './SearchForm.module.scss'
import cn from 'classnames'

export interface Props = {
  placeholder?: string
  className?: string
  id?: string
  onInput?: (e: React.FormEvent<HTMLInputElement>) => void
}

export const SearchForm: React.FC<Props> = ({ className, placeholder, id, onInput }) => (
  <form className={cn(styles.default, className)}>
    <input name="search" type="text" placeholder={placeholder} id={id} onInput={onInput} />
  </form>
)
```
このように検索するinputタグのコンポーネントを作ります。
これはまだ、外観を用意しただけで、実際に動かすのはimportされたコンポーネント内です。

```tsx:pages/index.tsx
import SearchForm from '~/components/domains/SearchForm'

const CityListPage: NextPage = () => {
　// 入力キーワードをState化する
　const [searchKeyword, updateSearchKeyword] = React.useState('')
 // 入力イベントに反応してStateを更新する
  const onInput = (event: React.FormEvent<HTMLInputElement>) => {
  　// 入力キーワードをstateに格納する
    updateSearchKeyword(event.currentTarget.value)
  }
  const filteredList = cities.filter((item) => {
  　// 文字列の部分一致するものだけを残す
    return new RegExp(searchKeyword).test(item.name)
  })
  return (
    <SearchForm placeholder="市郡を検索する" onInput={onInput} />
    <div>
    　　// ここでマッピングして表示されることとなります
	{filteredList.map((item, key) => {
          return (
            ...
          )
        })}
     </div>
  )
}

export default CityListPage
```

これで、実装は出来たかと思います。

このページを参考に、日本語の文字列で検索できるようにアレンジを加えました。
https://zenn.dev/himenon/articles/4c6d7ed8b7df30
[LiveView]handle_paramsでurlのparameterをバリデーションする方法


ドキュメントに記載がありますが、自分用の備忘録として。

params["hoge"]を対象に正しい文字列(huga)かどうかを判別する場合、case文を使って

```elixir
hoge when hoge in ~w(huga) -> ...
```
のように既述します。

[公式ドキュメント](https://hexdocs.pm/phoenix_live_view/live-navigation.html#handle_params-3)では具体的に以下のように記述されています。

```elixir
def handle_params(params, _uri, socket) do
  socket =
    case params["sort_by"] do
      sort_by when sort_by in ~w(name company) -> assign(socket, sort_by: sort)
      _ -> socket
    end

  {:noreply, load_users(socket)}
end
```
【stylus】コメントの書き方（1行コメント/複数行コメント）

stylusにおけるコメントの書き方について

参考：stylus公式サイト → [Comments - Stylus](https://stylus-lang.com/docs/comments.html)

## 1行コメント（出力されない）
コメントの先頭に`//`をつける

```javascript:stylus
// 1行コメント（出力されない）
```

```css:css

```

## 複数行コメント
### `compress`オプションの有効/無効に依存する複数行コメント
コメントを`/*`と`*/`で挟む
#### `compress`オプションが有効の場合（出力されない）
```css:stylus
/*
  出力されない複数行コメント
*/
```

```css:css

```

#### `compress`オプションが無効の場合（出力される）
```css:stylus
/*
  出力される複数行コメント
*/
```

```css:css
/*
  出力される複数行コメント
*/
```
### `compress`オプションの有効/無効に依存しない複数行コメント（出力される）
コメントを`/*!`と`*/`で挟む

```css:stylus
/*!
  出力される複数行コメント
*/
```

```css:css
/*
出力される複数行コメント
*/
```
【JavaScript】アロー関数について

#はじめに
こんにちは。
JavaScriptのアロー関数についてアウトプットします！
アロー関数を説明する前に、関数について触れていきます。

##関数とは
同じ処理を複数回使用するとき、事前に定義して必要な時に呼び出せるように名前をつけたもの。

```javascript:JavaScript
function hello(name){
  console.log('Hello' + name);
}
//function 関数名(引数){実行したい処理;}

hello('Sato!');  //HelloSato!
//関数名(引数);
```
関数を定義する際は、上記のようにfunction関数名と引数、実行したい処理を記述して定義する。
関数を定義するだけでは実行されず、関数名に括弧( )を使用して呼び出すことができる。また、呼び出す際に指定した引数を関数の引数に格納する。

<br>

```javascript:JavaScript
const hello = function(name){
  console.log('Hello' + name);
}

hello('Sato!');  //HelloSato!
```

関数は上記の記述のように、定数や変数に格納することもできる。

<br>

##アロー関数について

```javascript:JavaScript
const hello = (name) =>{
  console.log('Hello' + name);
}

hello('Sato!');  //HelloSato!

//const hello = name => console.log('Hello' + name);
```

先ほどの、定数helloに定義した関数を「=>」を用いて記述を省略できる。また、実行したい処理が1行の場合は{ }、引数が１つのときは( )も省略できる。

#最後に
ここまでアロー関数についてまとめてみました。
関数の種類はアロー関数以外にも複数あるので、それについても今後記事にしていこうと思います！
素数判定アルゴリズムでsqrtを使う理由が59秒でわかる記事

##素数を判定するアルゴリズムについて

例: 101が素数か判定するにあたって 1 -100すべてで割る（グリーディーなアルゴリズム）必要がありません

**(int) sqrt(101) = 10** を越えない素数 2,3,5,7だけでチェックすればいいというのが答えです　
`エラトステネスのふるい`とかいう魔法みたいな言葉はよくわからんでいいです

何故かについては下記理由となります

####理由1 平方根以下の数で探せばよい理由

101が10以上の数で割れるとした場合（19とかで割れるとしましょう）

101 = 19 x (`相方となる数`）がいます

そう考えると、この`相方`は101の平方根より小さくなるはずです、19で割れると同時に`相方でも`割れるはずですが、相方は19より先に出てきているはずです。そんな感じで`相方`のことを常に考えていくと、平方根以下で探せばよいことがわかります

####理由2　素数以外の数＝合成数(例14）で割る必要がない理由

101が「1 -100すべてで割る」で、例えば頑張って1-14まで探してようやく`14`で割れるとした場合を仮定するとこれはあり得ません。14は素因数分解すると`2x7`なので、`14`で割れるとしたら14より先に出てくる`2,7`の時点ですでに割れています
【JavaScript初心者】どうして躓いたのか？アロー関数

JavaScriptについて勉強していますが、アロー関数について躓いてしまいました。初心者だからこそ、なぜ、どこに理解できなかったのか、まとめました。実際に理解に苦しんでいる方、初心者に教える際の参考等になれば幸いです。

#####筆者の経歴
・Webコーディングの勉強を始めてから16ヶ月程度
・小規模サイト4,5件作成
・JavaScript、phpはほぼ初心者

##目次
[・アロー関数とは](#アロー関数とは)
[・どう躓いたのか](#どう躓いたのか)
[・なぜ躓いたのか](#なぜ躓いたのか)
[・どのようにして理解したか](#どのようにして理解したか)
[・どう理解したか](#どう理解したか)

#アロー関数とは
　『=>』で記載されたコードはアロー関数が使用されています。構文は以下です。
　　__(引数)=>{処理内容}__
functionを用いた構文と比較すると非常にシンプルです。
JavaScriptの仕様ES6(2015年)より導入されました。

#どう躓いたのか
```
const result = items.filter
(item => item === target);
```
教科書に上記のコードがいきなり掲載され、分からなくなってしまいました。このコードを例Aとします。

#なぜ躓いたのか
①教科書で、例Aのコードが関数の説明の章よりも前に記載されていた。そのため、これは「=>」を記載する場合は関数以外にもあるのだろうと考えてしまった。

②例Aのコードは知っている構文と違うので、アロー関数とは違う別のものだと考えてしまった。

③「===」はif構文当で使用するのにifが見当たらないので、「===」の立ち位置が分からなくなった。

④「=>」が指しているのは「item」なのか、「item === target」なのか判断できなかった。

⑤教科書は入念に検討されているという先入観があり、①〜④は間違っていないだろうと考えた。

・・・
以上のことから、アロー関数を特定するための「=>」がよく分からず、躓いてしまいました。

#どのようにして理解したか
JavaScriptについて先生に質問し、解決しました。
上記の質問に対する回答は以下になります。

①「=>」を記載する場合はアロー関数だと断言できる。多分これは教科書の作りが悪い。

②構文から書き方を変えている。

③filter関数によって条件式が設定されている。

④ちょっとここは理解が難しい気がしますが、「item === target」と区切るのが正解。

⑤僕の先入観が強すぎるのが悪い。

例Aをfunctionを用いたコードに直せば以下のようになります。見やすくなりましたね。

```
const result = items.filter
(function(item){ return item === target});
```
#どう理解したか
上の項で書き直したコードを比較することで、アロー関数の本質に近づけたような気がします。卵を使って目玉焼きを作る例を関数で表現するとこんな感じでしょうか？
・関数式・・・const フライパン = function(卵){焼く}　
・アロー関数・・・const フライパン = (卵)=>{焼く}
結果はいずれも目玉焼きができますね！

※コードはSAMURAI ENGINEER　の教材「
JavaScriptでWebサイトに動きを付ける方法を学ぼう」より一部を抜粋しました。
画像を並列に読み込む

画像を同時に読み込むをする

```javascript:qiita.js
var pathArray = ["*","*","*","*","*","*"];
var imgArray = [];
var counter = 0;
for(var i = 0 ; i < pathArray.length ; i++){
	var img = new Image();
	img.src = pathArray[i];
	imgArray.push(img);
	img.onload = function(){
		counter++;
		if(counter == pathArray.length){
			console.log("LOAD COMPLETE")
		}
	}
}

```

数個であればこれでもいいけど、実際に読み込みをする時に、N個並行で読み込むっていうのを作りたい。

```javascript:qiita.js
function loadPararell(_pathArray,N,_func){
	var imgArray = [];
	var counter = 0;
	for(var i = 0 ; i < N ; i++){
		loadimg(i)
	}
	function loadimg(i){
		var img = new Image();
		img.src = _pathArray[i];
		imgArray.push(img);
		img.onload = function(){
			console.log("LOAD:"+img.src)
			counter++;
			if(counter == _pathArray.length){
				console.log("LOAD COMPLETE")
				_func(imgArray);
			}else if(counter < _pathArray.length - 2){
				loadimg(counter+2);
			}
		}
	}
}
var pathArray = ["assets/img/place_1.png","assets/img/place_2.png","assets/img/place_3.png","assets/img/place_4.png","assets/img/place_1.png"];;
loadPararell(pathArray,3,function(arr){
	console.log(arr);
});
```

できた。これでpathArrayで画像を読み込んだら、その画像のデータを配列に入れて完成で返してくれるものができた。
[Ruby] shiftメソッド

##はじめに
shiftメソッドの紹介です。
プログラミング問題でsortメソッドと組み合わせると便利でした。

##Array#shift
配列に対して使用できます。
配列の先頭の要素を取り出してそれを返してくれます。そしてその配列から取り出した要素は削除されています。

どういうことかというと下記の例を見てください。

```ruby
array = [1, 2, 3, 4, 5]
array.shift
=> 1
```

このように先頭の数値を取り出してくれます。
配列の中を見て見ましょう。

```ruby
p array
=> [2, 3, 4, 5]
```

配列の中の先頭にあった1が消えています。

また引数を渡すこともできます。渡した数字の数だけ先頭から取り出して削除してくれます。

```ruby
array = [1, 2, 3, 4, 5]
array.shift(3)
=> [1, 2, 3]

p array
=> [4, 5]
```
ちなみに空の配列に対して使う時、引数を渡すのと、渡さない場合は結果が違うらしいです。

```ruby
array = []

p array.shift
=> nil

p array.shift(1)
=> []
```

参考: https://docs.ruby-lang.org/ja/latest/method/Array/i/shift.html
Djangoでデータベースをテスト的に利用するときのコード（備忘録）

# modelsのデータベースをテスト的に使うときの備忘録

DjangoのModelsを定義してから、views.pyからデータベースをテストしようとすると設定が面倒です。
かといって外部にファイルを作ってテストしようと思っても、Modelを関係のないファイルから呼び出せる環境設定にできるコードを忘れてしまう。それと意外とネット載っていない。

自分の備忘録として残しておきます。
下のコードのあと、自分で登録したModelsを呼び出すことが可能。

```setting_models.py
import os
from django import setup
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ModelProject.settings')
setup()
```
Kali LinuxにLibreOfficeを入れてみた

#概要
　Kali LinuxにLibreOfficeを入れたのでその備忘録です。ほぼほぼ参考サイト1と内容は同じですが、失敗なども記録しつつ、日本語対応までの流れを説明していきます。

#導入の背景
　CpawCTF Q19の答えを調べるとLibreOfficeを導入すれば良いようだったので…

#必要となる知識
　基本的にはLinux系は基本的なコマンドなどを調べながらできる人であれば問題ないかと
　私も大学の授業で軽くLinuxに触ったことあったくらいなので。

#環境
※以降ではバージョン情報などは適宜読み替えてください

- Windows10
- VirtualBox上のKali Linux2021.2(日本語化済み)
- LibreOffice7.2.0

#手順

1. ID: Kali Password: Kaliでログイン、ターミナルを開き、Kaliを最新バージョンにアップデート

2. LibreOfficeの[ダウンロードページ](https://ja.libreoffice.org/download/download/)にアクセス

3. Linux(64-bit)(deb)を選択し、ダウンロード
※私の環境では初期選択が(rpm)になっていて失敗しました。

4. LibreOfficeを日本語化したい場合、ダウンロード時に遷移した画面の「翻訳されたユーザーインターフェース」をクリックし、ダウンロード

5. 後は以下の手順でファイルを解凍し、debファイルをインストール
※Kaliを日本語化しているので、英語等の場合はそのように読み替えてください。


```
cd ダウンロード
```

lsコマンドを実行すると「LibreOffice_7.2.0_Linux_x86-64_deb.tar.gz」があることが確認できるので、以下で解凍

```
tar -cvzf LibreOffice_7.2.0_Linux_x86-64_deb.tar.gz
```

解凍後、lsコマンドを実行すると、「LibreOffice_7.2.0_Linux_x86-64_deb」ディレクトリができるので、cdで移動


```
cd LibreOffice_7.2.0.4_Linux_x86-64_deb
```

lsコマンドを実行すると、「DEBS」と「readmes」が存在するので、「DEBS」に移動

```
cd DEBS
```

ここにdebファイルが存在するので、すべてインストール


```
sudo dpkg -i *
```

これを「翻訳されたユーザーインターフェース」でダウンロードした「LibreOffice_7.2.0.4_Linux_x86-64_deb_langpack_ja」でも同様の手順でインストール

以上でLibreOfficeのダウンロードは完了

#(Q19の答え)
　他サイト等にも掲載されているが、zipファイルの拡張子をodgに変更し、LibreOffice Drawで開き、図形をずらすと答えが分かる

#参考サイト
1. [How to install LibreOffice for Kali Linux Guide for beginners](https://www.cyberpratibha.com/blog/download-and-install-free-libre-office-software-in-kali-linux/)
1. [tar コマンドで圧縮・解凍　まとめ](https://qiita.com/softbase/items/b00b407d0a7a9fdf2a35)
【エラー備忘録】ブラウザでSQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost'

##状況

phpのローカルサーバーを立ち上げ、ブラウザでlocalhost:8000へアクセスした時、ブラウザにエラーが表示された。

##エラー文

```
SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost'
```
MySQLへrootユーザーでログインできていないらしい。

##原因
ターミナルでMySQLへ下記コマンドでログインしてみる。

```
$ mysql -u root -p
Enter password: 
```
パスワードを求められ、「パスワードA（仮）」を入力するとログインできた。

laravelの.envファイルを見てみる。

```
DB_USERNAME=root
DB_PASSWORD=パスワードB（仮）
```
.envファイルで設定しているパスワードが異なっていた。

##解決法
.envファイルの```DB_PASSWORD```を「パスワードA(仮）」に書き換える。
ローカルサーバーを再起動すると、無事画面が表示できた。