OmniAICreator/Qiita-1.07M huggingface dataset:
MAiX Qube 奮闘記02 SDカードに悪戦苦闘

最初の目標はMAiX Qube で名曲「Bad apple!」を再生することとした。
その為には容量的にSDカードが使えないとどうにもならない。
MAiX Qube で使用出来るSDカードは２つの要件を満たしている必要みたいだけど。
１SDカードがSPIプロトコルをサポートしていること。
２SDカードはMBRパーティションでFAT32フォーマットされていること。
　MBRパーテーション以外にはGPTパーテーションが有るようです。

https://wiki.sipeed.com/soft/maixpy/en/others/maixpy_faq.html#Micro-SD-card-cannot-be-read
ふむっMBRパーテーションかどうか確認するツールも無く手あたり次第に手元にあるマイクロSDカードを入れたけど認識っぽい動作はせず。
MAiX QubeってSDカード使えないのかもと諦めかけていたとき、たまたま試した１枚がうまく認識出来た。
やったー!!
カードによっては認識出来るんだ！
これは大きな前進！！
その後も試すと他にも認識出来るＳＤカードがみつかる。
![RIMG0014.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606106/68d0ad91-086b-621c-02ec-4f4eec772be8.jpeg)
右の３つは認識出来たＳＤカード。
左の２つは認識出来なかったカード。
下は認識出来たカードのアマゾンのリンクです。
https://www.amazon.co.jp/microSD-Nintendo-%E3%83%A1%E3%83%BC%E3%82%AB%E3%83%BC%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D%E6%B8%88-SanDisk-SDSQUA4-064G-EPK/dp/B08K4214KB/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2JVWEFSTE25RI&keywords=sd%E3%82%AB%E3%83%BC%E3%83%89%2B64gb%2B%E3%82%B5%E3%83%B3%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%2B%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD&qid=1648565322&sprefix=sd%E3%82%AB%E3%83%BC%E3%83%89%2B64gb%2B%E3%82%B5%E3%83%B3%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%2B%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD%2Caps%2C191&sr=8-3&th=1

最後に
認識出来ないSDカードが入った状態での起動画面。
![RIMG0015.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606106/a30e7495-f6f6-63a0-08c9-48d9cf1a0b4c.jpeg)

認識出来るSDカードが入った状態での起動画面。
(SDカードにboot.pyが有ればそちらが実行されるため、この画面は出ません。)

![RIMG0016.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606106/a0516020-859b-ff44-f86e-106385abc024.jpeg)

追加情報
認識できない事もMAiX Qubeの個体によってはありました。
下記2つのどちらかで僕の場合は認識出来るようになりました。
1.前回投稿したjsonファイルを消してからjsonファイルを再設定して解決。
2.パソコンでSDカードをフォーマット(クイックフォーマットではない方で)し直して解決。
AWS Organizationsの管理アカウントからメンバーアカウント削除ができるようになったのでやってみた

2022/3/29に、AWS Organizationsの管理アカウントからメンバーアカウント削除ができるようになったのでやってみました。

# 管理アカウントからメンバーアカウント削除

まずは削除したいメンバーアカウントをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/3122e663-eb77-439f-0495-8242aedc1330.png)
[閉じる]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/87096cfa-7f8e-c666-a4ef-21e3e055f267.png)
注意事項を確認してチェックし、アカウントIDを入力して[アカウントを閉じる]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/6491f21c-38bf-55ea-6259-b9e6c824a09a.png)
「このAWSアカウントは閉鎖を保留中です」と表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/a6fe1139-8e93-5dd5-2d55-1a20f972fc2c.png)
管理画面に戻り画面を更新すると、削除操作したメンバーアカウントの名前の横に(停止)と表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/c49ed0f9-bd36-02db-e9b4-e03e0751d4c1.png)

# 参考

https://awsapichanges.info/archive/changes/837027-organizations.html

https://github.com/aws/aws-sdk-go/blob/main/CHANGELOG.md

AWS Organizationsを一人で運用する方法は以下を参照してください。

https://qiita.com/emiki/items/f68bec2ef6f5d3dfe14f
[Swift]IDFAを取得する方法

## IDFAを取得する
admobのテストデバイスの登録時などにつかいます。
## 想定
+ Xcode 13
+ iOS 15
+ 新規プロジェクトを想定

## 注意
Simulatorの場合は「00000000-0000-0000-0000-000000000000」になり、必ずTest広告になる
## プログラミングで取得する
### 1. info.plistに追加する
+ これを追加する
```info.plist
<key>NSUserTrackingUsageDescription</key>
<string>トラッキングをしますか？</string>
```
1. info.plistを右クリック > Open As > Source Codeで開ける
2. 下の「ここに追加する」にペーストする


```info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>UIApplicationSceneManifest</key>
	<dict>
		<key>UIApplicationSupportsMultipleScenes</key>
		<false/>
		<key>UISceneConfigurations</key>
		<dict>
			<key>UIWindowSceneSessionRoleApplication</key>
			<array>
				<dict>
					<key>UISceneConfigurationName</key>
					<string>Default Configuration</string>
					<key>UISceneDelegateClassName</key>
					<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
					<key>UISceneStoryboardFile</key>
					<string>Main</string>
				</dict>
			</array>
		</dict>
	</dict>
	///
    ここに追加する
    ///
</dict>
</plist>
```

### 2. ViewControllerにいろいろ追加
```ViewController
import UIKit

///ここを追加
import AppTrackingTransparency
import AdSupport
///

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    ///ここを追加
    override func viewDidAppear(_ animated: Bool) {
        ATTrackingManager.requestTrackingAuthorization { status in
            switch status{
            case .notDetermined:
                //statusをアプリが判断できない
                print("判断できません")
            case .restricted:
                //statusが制限されている場合
                print("制限されています")
            case .denied:
                //承認を拒否した場合
                print("拒否されました")
            case .authorized:
                //承認した場合
                print("取得できました)
                print(ASIdentifierManager.shared().advertisingIdentifier)
            @unknown default:
                print("error")
            }
        }
    }
    ///


}
```

### 3. 実行して確認する
ポップアップの確認画面で許可するとIDFAがprintされます。拒否すると取得できません。拒否してしまった場合は以下二つの方法があります。
1. アプリを削除 > Run でもう一度確認画面が表示されます
2. スマホ設定 > アプリ名 > トラッキングを許可 した後でもう一度アプリを開くと取得できます

## ソースコード
[GitHub](https://github.com/m-takuma/GetIDFA)
railsモデル　メモ

# Modelについてのメモ【Rails】

## モデル作成と削除
```
# モデル作成コマンド
rails g model モデル名(単数形)

# モデル削除コマンド
rails d model モデル名

## 例
rails generate model User
rails destroy User

```
モデル命名規則についてはこのページがわかりやすかった
[モデル命名規則](https://qiita.com/gakkie/items/3afcd505c786364aa5fa)

## モデルデータ型
- string : 文字列
- text : 長い文字列
- integer : 整数
- float : 浮動小数
- decimal : 精度の高い小数
- datetime : 日時
- timestamp : タイムスタンプ
- time : 時間
- date : 日付
- binary : バイナリデータ
- boolean : Boolean

## モデル作成からの手順
① モデル作成
```
rails g model User name:text age:integer post:string
```
②マイグレーションファイルの編集（①でオプションをつけなかった場合）
③マイグレーション実行(下記コマンド）
```
rails db:migrate
```
※以下任意
④間違えてマイグレーション実行した時(db:migrateの一つ前の状態に戻る）
・カラム名間違えてつけたり
・保存しないままマイグレートした時などに使える
```
rails db:rollback STEP=1

rails db:migrate:status
```
https://pikawaka.com/rails/migration

上記サイトがわかりやすかった

## マイグレーションファイルの書き方
```
class CreateUsers < ActiveRecord::Migration[7.0]
  def change
    create_table :users do |t|
      t.text :name
      t.integer :age
      t.timestamps
    end
  end
end


```
運用・保守プロジェクトから開発プロジェクトへの道のり②

## 挫折からの復活
 

このままずっと休憩していたらいつまでたっても開発のプロジェクトに参画することなんてできない！と思い、久しぶりにプログラミング学習を始めました。 

ここで不思議なことが起こります。久しぶりの学習だったので参考書を最初から見ながらプログラミング学習をしたのですが、以前わからなかったところが分かるようになったのです。 
 
それはどうしてでしょうか？答えは簡単です。私は「早く開発のプロジェクトに参画したい！」という気持ちが強かったので、学習のペースが速かったのです。その結果、大切な基礎の部分がしっかり知識として定着せず、部分的に抜けていたのです。 

ここで私が伝えたいのは、「基礎はめちゃくちゃ大事」です。 

そこからの学習は比較的にスムーズにできて、作ってみたかったスライドショーやアニメーションなども作ることが出来るようになりました。 


## どんなことをして開発のプロジェクトに参画したのか
 

ここまで私がどんな学習をしてきたのか紹介しましたが、ただプログラミング学習をすれば開発のプロジェクトに参画できるわけではありません。 
では、プログラミング学習以外にはどんなことをすればよいのか紹介します。  

私が参画していたプロジェクトは運用・保守のプロジェクトです。なので基本的にはコードを書くことがありません。ですが、ここで諦めてはいけません。 

私が実際、開発の経験を積みたいと嘆いていた時にとある上司がアドバイスをくれたのです。
> 「運用・保守の現場でも開発しちゃえばいいんだよ！」 

最初この言葉を聞いた時は頭の中が「？？？」になっていました（笑） 

つまりどういうことかというと、運用・保守の現場で役に立つようなツールなどを開発すれば、開発の経験にもなるし、業務の効率化にもなるから一石二鳥じゃないか！という事です。 

そこで私は今のプロジェクトに役立つものを作ろうと思い、下記のツールを作成しました。 
- RPAソフトを使用した、自動で必要なファイルを展開してくれるツール 
- コマンドを入力することなく該当の機器にログインをして、機器の再起動や、SW-HUBのポート制御をするTeraTermマクロ 

開発したツールは実際に他のメンバーにも使っていただき、「とても便利」と言っていただくこともできました。 
 
私はこういった実績を積みプロジェクトのリーダーや担当営業の方などに、自分は現場でこんなことをしているとアピールしました。その結果現場での評価も上がり、担当営業の方も熱心に開発のプロジェクトに参画させようと行動をしてくれたおかげで、現在開発のプロジェクトに参画することが出来ました。 
 

## まとめ 


実際に運用・保守のプロジェクトから開発のプロジェクトに参画するまで、何度も挫折しそうになりました。それでも諦めずに努力し続けることが出来たのは、「開発のプロジェクトに参画してやる！」という強い意思と、周りの人たちの応援があったからです。

最初のうちはわからないことだらけで辛い事も多いと思いますが、そこで諦めてしまったら成長することが出来ません。小さいことでもコツコツ続けて、少しずつスキルを身につけましょう！
それと自分が行っている事は積極的に上司や周りのメンバーに報告することも大事です。そうすることで自分の周りの人にも良い影響を与えることが出来ます。

これから頑張る方も、すでに頑張っている方も強い意思をもって頑張っていきましょう！
努力は決して無駄にはなりません。
SELECT文の結果を見やすくする

## 使用用途
SELECT文を流した際に、結果が多くて見ずらい時に結果を見やすくする

## 使用方法
#### ①SELECT文の最後を　 `;`　ではなく `\G`　にする

```:例文
SELECT　* from tableName \G
```

#### ②`pager less -S` を使用する
`-S`はlessのオプションで改行をしないという意味

```:例文
pager less -S
SELECT　* from tableName;
```
pagerを閉じる場合は `q`
解除するには `nopager` か `exit`
　
　
　
この記事は以下の情報を参考にして執筆しました。
- https://ameblo.jp/stylagy/entry-12383390406.html
Amazon Lightsailでwordpress環境構築するときのメモ

ansible対応するまではLightsailでポチポチ作成するのでメモ

# 前提
プラットフォーム : Linux
使用イメージ : アプリ+OS WordPress
すでに構築中のソースがあり、公開環境を作成したいという状況

# gitインストール

```
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install git
```
インスタンス作成後sshして作業するか起動スクリプトに指定する

# 管理画面パスワード確認

`cat /home/bitnami/bitnami_application_password`
ユーザー名は `user`

# wp-contentの入れ替え

ホームディレクトリにgithubからソースをクローン
`cd ~/`
`git clone hogehoge@github.com:hoge/hogehoge.git`

wp-contentを入れ替える
`cd /bitnami/wordpress/ && sudo mv wp-content _wp-content`
シンボリックリンクをはる
`ln -s /home/bitnami/path/to/wp-content wp-content`
所有者権限を元に戻す
`sudo chown -h bitnami:daemon wp-content`

# テーマ選択をする
管理画面
appearance > themes
カスタマイズしたテーマを追加

# basic認証をかける

```
sudo vim /opt/bitnami/apache2/conf/vhosts/wordpress-vhost.conf
```

```
    AuthType Basic
    AuthName "auth"
    AuthUserFile /opt/bitnami/apache/conf/.htpasswd
    Require valid-user
    # Require all granted
```

```
 sudo htpasswd /opt/bitnami/apache/conf/.htpasswd username
```

```
sudo /opt/bitnami/ctlscript.sh restart
```

# sqldump流し込み
`/bitnami/wordpress/wp-config.php`
でDB情報確認。任意のデータをリストアする

# sslしたくば
https://aws.amazon.com/jp/premiumsupport/knowledge-center/lightsail-install-certbot-package/
https://aws.amazon.com/jp/premiumsupport/knowledge-center/lightsail-standard-ssl-certificate/
Mi 11Lite 5Gのナイトモードを解除する

### 1.はじめに
MIUIやColor OSなど、中華スマホに搭載されているAndroid OSにはナイトモードのON/OFFを操作する項目が無く、ナイトモードがONになるとスマホ単体では初期化以外に解決する方法がありません。

今回OSアップデートを実施したところ、半年ほど前に無効化したはずのナイトモードが有効になったため、忘備録も兼ねて書いておこうと思います。


### 2.必要なもの
- スマホ
- PC
- USBケーブル

### 3.手順
1. PCにAndroid開発ツールを導入するか、[15 seconds ADB Installer](https://forum.xda-developers.com/t/official-tool-windows-adb-fastboot-and-drivers-15-seconds-adb-installer-v1-4-3.2588979/)を用いてadbコマンドが実行出来る状態にする
1. スマホの開発者オプションを有効にする
    1. 設定を開く
    1. デバイス情報に入る
    1. MIUIバージョンを連打
1. その他の設定 から 開発者オプション に入る
1. USBデバッグを有効にする
1. スマホをPCにつなぎ、USBデバッグの許可を出す
1. 以下のコマンドを実施
   ```
   adb shell settings put secure night_display_auto_mode 0
   adb shell settings put secure night_display_activated 0
   ```
1. (一部のアプリが起動しなくなるため)USBデバッグをOFFにする

以上で画面の黄ばみの原因、ナイトモードの解除が出来ました。
[ブロックチェーン]今知っておきたい頻出単語

# イントロ
「ブロックチェーンってなんて言えばいいんだ？」
「ナンスってなんだっけ？」

専門用語がとにかく多いブロックチェーン、
理解してるけど、うまく言葉にできないことってありませんか？

もっと理解して、人にも説明できるようになったらかっこいいですよね。
今回はできるだけ簡単な言葉で、関連用語をまとめてみました

# ブロックチェーンとは？
ブロックチェーンはビットコインで採用された、取引のデータを保存していく仕組みで、
すべてのデータを全員で持つという方法をとっているのが特徴です

現在、取引のデータは金融の会社のコンピュータで管理されています。
つまり、その会社のコンピュータが動かないと、取引を行うことができません

また、管理者が取引のデータを書き換えることもできてしまいます。
ならばいっそ、無数のコンピューターで管理してしまおうという手段がブロックチェーンです

# 頻出単語
* アルトコイン
    * 仮想通貨の代表であるビットコイン以外の仮想通貨
* 暗号通貨
    * セキュリティ対策として暗号技術を駆使している通貨
* アービトラージ
    * 仮装通貨の価格差を利用して、A取引所で安く買い、B取引所で高く売ること
* ERC20
    * イーサリアムのブロックチェーン上でトークンを発行する際の標準規格
* ウェブウォレット
    * 暗号通貨を管理する財布の一種
    * どこからでもアクセスできる
* ウォレット
    * 自分のビットコインアドレスをまとめたもの
    * 秘密鍵を保管する場所
* エアドロップ
    * 新しいコインを無料で配布すること
    * コインを使う人を増やすのが目的
* Orphan Block(孤立ブロック)
    * 別々のマイナーが別のブロックをそれぞれ追加したときにできるブロック
* Gas
    * イーサリアムの送金やプログラム実行の際に使われる燃料
* クラウドセール（ICO）
    * 取引市場に上場する前に暗号通貨の開発者から購入できる期間
* Coin Age
    * 仮想通貨におけるコインの保有年数
    * 送金をしたいなどの取引や、マイニングをして報酬を得る際の優先度を決める際に利用される
* コインベース
    * ビットコインをマイニングした人に対して支払われる報酬
* 公開鍵
    * 送金の際に、所有者が自分であることを証明する鍵のこと
    * 秘密鍵から生成される
* 公開鍵暗号
    * データの暗号化と元のデータに戻す復号をできるようにする暗号システム
* コールドストレージ
    * 外部と繋がるネットワークから遮断して保管すること
* Satoshi
    * ビットコインの最小単位
* スケーラビリティ問題
    * 取引が大量になると、承認までの待ち時間が長くなり、また取引手数料が高くなること
* スマートコントラクト
    * 契約を自動化させるプロセスシステム
* Segwit
    * 署名を書く場所を変えることで、ブロックのデータ容量を小さくすること
* DApps
    * 特定の管理者がいなくても動作し続けるアプリケーション
* Difficulty
    * マイニングの計算の難易度。
    * ブロックが生成される速度が遅すぎたり、速すぎたりしないよう調整される
* DEX
    * ブロックチェーン上に存在する取引所
* トークン
    * システム利用者が独自に学校する通貨
* ノンス
    * ブロックを生成する時に、マイナー（採掘者）によって生成される32ビットの数値
    * Number used once（一度だけ使用される使い捨ての数字）の略
* ノード
    * P2Pネットワークに参加するコンピュータまたは参加者のこと
    * データの署名や取引データを検証し、分散型台帳と比較することで監視・取引を承認する
* ハッシュ
    * とあるデータを変換した結果得られる一定長のデータ
    * 一度ハッシュ化されたデータは、元のデータに戻すことは通常不可能である
* 秘密鍵
    * 一般に公開されない鍵。 
    * 対になる公開鍵で暗号化されたデータは、この鍵でしか復号できない
* ビザンチン将軍問題
    * 多数決による合意形成はリスクを伴うことを示した例
* ビットコインアドレス
    * ビットコインを利用する際の口座番号のようなもの
    * 公開鍵から生成される
* BTC
    * ビットコインにおける通貨単位
* P2P
    * 他の端末と繋がることで情報を交換し合うことや、他の端末からのリクエストに応えて情報を共有する仕組み
* フィアットカレンシー
    * 国が発行している法定通貨
* フォーク
    * ブロックチェーンの分岐のこと
    * 複数のマイナーが同時にマイニングに成功してしまったときに起こる
* ブロック
    * 取引をまとめたもの
* Proof of stake
    * コインの保持量に応じてブロックの承認割合を決める仕組み
* Proof of Burn
    * 古いコインや紙幣といった通貨を燃やすことで、新しい通貨が得られる仕組み
* Proof of work
    * CPUの計算量に応じて、報酬を得られる仕組み
* ペーパーウォレット
    * 取引に用いるアドレスを紙に印刷して保管する方法
* ボラティリティ
    * 通貨や株式などの価格変動性のこと
* マイナー
    * 新しく行われた取引をまとめて、ブロックチェーンに追加する人
* マイニング
    * 新たなブロックを生成し、その報酬として仮想通貨を手に入れる行為のこと
* マルチシグ
    * 複数の署名がないと、送金できないアドレスのこと
    * セキュリティーを高めるための技術
* Minting
    * コインの保有量が多く、保有期間が長いほど、より多くのコインを鋳造できるようになる仕組み
* USDT
    * ビットコインの構造や仕組みを真似て作られたアルトコインの1つ
    * 1USドルと同じ価値を有する
### 参考文献
https://venturetimes.jp/coin-glossary
awkコマンドの使用例

# 概要
tsv、csvで扱われるデータやlogのフィルタリングでawkコマンドを使用することがあるので、備忘録的に使用例を残す。
# awkとは
ファイルでパターンに一致する行を検出し、検出された行に対して指定されたアクションを実行する
# コマンド例
## カンマで区切られたファイルの指定したフィールドが指定した値より大きいものを抽出し、降順にソートする。
例では第７フィールドが150より大きいものを抽出し、第７フィールドで降順ソートしている。
```
awk -F "," '{if($7 > 150) print}' hoge.tsv | sort -k 7 -t "," -r
```
## tabで区切られたファイルの指定したフィールドのみを抽出し、先頭に行数をつける
```
awk -F "\t" '{count++;print count,$1, $5}' hoge.tsv
```
## tabで区切られたファイルの指定したフィールドで日時比較して抽出する
```
awk -F "\t" '{date = $9; if(date > "2018-08-01 14:00:00"){print}}' hoge.tsv
```
## tabで区切られたファイルの指定したフィールドの合計値を最後に出力する
`BEGIN`\:最初のレコードの読み取り前に実行する
`END`\:最後に実行する
```
cat hoge.tsv | awk -F "\t" 'BEGIN{total=0}{total+=$7; print $0}END{print total}'
```
## apacheのアクセスログをhttpステータスコードを指定して確認する
例はステータスコード200を指定（200を監視し続けるなんてほぼ無いと思うが。。。）
```
tail -f /var/log/apache2/access.log | awk -F " " '{if($9 == 200) print}'
```
# 最後に
awkを使わなくてもgrepなどのコマンドでも十分に対応できるものもあるが、個人的には普段から使っておかないといざ必要な時にド忘れしていることがあるので積極的に使っておきたいコマンドです。
【rails】join先テーブルの指定カラムの合計値算出を370倍高速化した話【sum】



前提知識
-

`job_offers`(求人)テーブル
|field  |type |
|---|---|
|wage(賃金)  |integer  |　賃金
|transport_expense(交通費)  |integer  | 交通費
|work_date(勤務日)  |date  | 働く日

2022年3月30日の全ての求人の賃金と交通費の合計値を出したい場合、
以下のようにすれば簡単に取得できます。
```ruby
JobOffer.where(work_date: "2022-03-30".to_date.all_day).sum("wage + transport_expense")
 (1.5ms)  SELECT SUM(wage + transport_expense) FROM "job_offers"
=> 1000000
```


今回のテーマ
-


では、`transport_expense`と`wage`が、`job_offers`テーブルのカラムではなく、別テーブルになっている設計の場合はどうすればいいでしょうか？
具体的にいうと以下のようなテーブル設計で、賃金と交通費の合計を算出したいケースですね。


`job_offers`(求人)テーブル
|field  |type |
|---|---|
|work_date(勤務日) |date  | 

`wages`(賃金)テーブル
|field  |type |
|---|---|
|job_offer_id(外部キー)  |integer  |　
|amount(金額)  |integer  |　

`transport_expenses`(交通費)テーブル
|field  |type |
|---|---|
|job_offer_id(外部キー)  |integer  |　
|amount(金額)  |integer  |　

modelの`association`は以下とします。
`job_offer has_one wage`
`job_offer has_one transport_expense`

自分ははじめ以下を想定しました。
N+1問題の回避のために`eager_load`で関連テーブルのデータごと取得して、rubyのメソッド`Enumerable#inject`で合計値を算出する感じですね。
```ruby
job_offers = JobOffer.where(work_date: "2022-03-30".to_date.all_day).eager_load(:wage, :transport_expense)
job_offers.inject(0) { |sum, job_offer| sum + job_offer.wage.amount + job_offer.transport_expense.amount }
(SQL略)
=> 1000000
```

リファクタ
-
上記でもよかったんですが、もっとうまくできる方法がないか思案したところ以下のような手段を発見しました。
`join`した上で、`sum("テーブル名.カラム名 + テーブル名.カラム名")`という書き方ですね。
```ruby
JobOffer.where(work_date: "2022-03-30".to_date.all_day).joins(:wage, :transport_expense).sum("wages.amount + transport_expenses.amount")
(SQL略)
=> 1000000
```



Benchmarkで100回実行した結果を比較してたところ、以下のような結果になりました。
```
                          user     system    total        real
リファクタ前              6.380000   0.216000   21.792    ( 23.098)
リファクタ後              0.059999        0.0    0.059    (  0.545)
```
なんと、`total`で比較すると約370倍高速化しているという結果に❗❗

リファクタ前は、取得したデータからモデルオブジェクトの構築を行なった後、rubyのループ処理で合計値を算出するのに対し、リファクタ後は、それらを行わずDBで直接計算するので高速なのではないかと思います。

また、速度に加えて、余計なソースコードの削減にもなり一石二鳥ですね。

今回シンプルなケースですが、複雑に関連テーブルと結合している場合でも、結合先のテーブルのカラムの合計値を取得できるようです。とても便利だったので紹介させてもらいました。

今回の記事がどなたかの役に立にたてば幸いです！


参考
-
https://tanaken0515.hatenablog.com/entry/2018/12/30/214215

https://qiita.com/at_sushi/items/efa42191432478d1fdc8
エラーの読み方　～おい エラーを見るんだ～

# 初めに
　みなさんこんにちは。この記事を開いていただきありがとうございます。
　この記事は初心者に向けたエラーの読み方のコツについて紹介しています。簡単なエラーをQiitaやTeratailなんかに投稿してGGRKSの5文字を浴びせられて、しょんぼりするプログラマーを減らそうという思いで書いております。
　今ギクッとしたそこのあなた！　ギクッとしてない人も！　今悩んでいるエラーをひとまず置いておいてこの記事をゆっくり読んでみてください。
どうぞごゆっくり

# エラーとは？
　まず、エラーとは何ぞやというところから話します。ここを読んでもらいたい人はエラー文を友達だと思っていない人です。
「エラーが嫌だって？w　何言ってんだよぉｗ　エラーは友達に決まってんだろ」と心の底から思ってる人は飛ばしてどうぞ。（←頭おかしいな）
　
　それでは本題です。エラーとはプログラムを実行するうえで「このままプログラムが実行されるとＰＣがおかしくなってしまうよ～」というのを未然に防いで教えてくれる機能のことです。それだけ聞くと知っとるわって感じがしますよね？　でも実は自分でコードをバリバリ書く人にとってこのエラーはなんでも教えてくれる友達以上恋人未満の存在なのです。

# エラーが教えてくれること
+ エラーの種類
+ エラーが起きた理由
+ 発生場所（ものによっては出ないこともある）

　プログラマーはエラーを読むうえでこの３点に気をつける必要があります。
プログラマーはエラーをすべて読むわけではなくこの要点だけをうまく見つけているのです。

# エラーからうまく情報を抜き出す
　ここからは僕のエラーの読み方を順番に紹介します。あくまで僕のやり方なので自分に最適な方法を見つけてください。
ちなみに使用するコード・エラーの例はこれです。（エラーを用意するのは逆に結構めんどいｗ）

``` error.py
array = [23, 39, 45, 15, 72, 53, 324, 532]

print(array[len(array)])
```

```shell
Traceback (most recent call last):
  File "d:\my program\python\test\main.py", line 3, in <module>
    print(array[len(array)])
IndexError: list index out of range
```

クソみたいなエラーですね。

## 1. エラーの種類を見つける
　まずは、エラーの種類を見つけます。
Pythonならば大体下のほうに書いてあるので探しやすいですね。「例でいうと、IndexError」

## 2. エラーが起きた理由を見る
　次にエラーの起きた理由を見ます。例でいうと「list index out of range」です。
　ここで僕はよくGoogle翻訳を使います。まず一度検索する前に翻訳にかけて意味をよくくみ取ってください。要するに早とちりしてサンプルコードをコピペしまくってぐちゃぐちゃにするよりも、よく意味を理解したほうが後々同じエラーが出たときに楽だということです。
あとは、次の手順に行きましょう。

## 3. エラー箇所を見る
　最後にエラーが起きた個所を見ます。例でいうと```File "d:\my program\python\test\main.py", line 3, in <module>```の行です。
　この例では、すごく簡単ですね。ですがここが一番エラー読みで肝となる場所です。例えば、Qiitaによく投稿されてるエラーでRubyとかJavaとかのライブラリの中のファイルパスまで書かれているクソ長いエラー文をよく目にしますよね？　その場合は、どこを見ればいいかというと、自分が書いた中で一番階層が深いファイルまでです。

　このようなエラーは、自分でクラスなどを実装してImportしまくってるときによく出ます。
その時は、自分が書いた中で一番深い階層を調べます。必ずしもそのファイルがエラー原因になっているということではありませんが、そのファイルをもとにたどっていきます。
　めちゃ優しい言語だと、エラーの行だけでなく文字数まで出してくれるものまであるのでぜひ活用しましょう。

　そして、２番の情報を使ってコードを見ながら対話します。すると、「arrayっていう配列よりも指定したインデクスが大きいのね。ごめんちゃい」って分かるわけです。ここで大事なのは、友達であるエラーの話をよく聞いてあげることです。するとエラーもあなたに何か訴えかけてくれるでしょう。
　しかし、これはエラーを一度見たことがあるかエラー文がわかりやすいときに限ります。そこで次に進みます。

## 4. 検索する
　前の手順で解決法がわからないときは、google先生に聞きます。このとき大事なのは、よく言われることですがエラーの意味をよく理解してコピペしましょう。
 データがどのように流れ、どのような不具合を起こしたのか一度頭の中で一通りシュミレーションしましょう。それを繰り返すことでだんだんと脳内デバッグに慣れてくるとおもいます。

# おまけ
　エラーを見るうえで重要なのが上で紹介した３点ですが、TypeScriptなどのビルド・トランスパイルする系の言語ではトランスパイル前のファイルではどこがエラーかわからないことがよくあります。
　なので、このようなことを防ぐためにtsconfig.jsonのソースマップを有効にしましょう。
そうすると、ブラウザで表示したときにブラウザ側のほうでエラー箇所をたどってくれます。

# 最後に
　この記事によって、「GGRKS攻撃」および「DY(ドキュメント読め)攻撃」の被害者が減ることを切に願っております。
本当にクソみたいな基本的なことしか書けずすみませんでした。最後まで読んでいただきありがとうございました。
４回目　AWSとは

# Markdownはじめます。
## AWSについて
![AWS１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606732/f62263f0-fb54-077b-0ebc-139375545de6.png)

### 第一分岐点（サービスの種類）
### 第二分岐点（連想できる単語）
### 端的に言えばインターネット経由の豊富なサービス
![aws2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606732/9b3d7b72-25bd-55eb-3e8b-183a70262e6f.png)

#### サーバー・ストレージ・データベース・ソフトウェアなど、コンピュータとしての様々な使い方ができるため全てを説明することは不可能に近い。個人でサーバーを買う必要がなく手元のPC一台で利用できるというのが一番のメリットです。一方で、利用者が多いサービスは色々なトラブルや不具合が生じることがある。（プログラミングスクールで利用していたAWS Academyではアクセスできなくなるトラブルがあった）

#### メリットを思いつく限り箇条書きします。
##### ・容量がある
##### ・初期費用や契約費用がかからない
##### ・料金は利用量に応じて決まる
##### ・必要に応じて柔軟にリソースを増減できる
##### ・サービスの利用方法について個別のサポートはない

#### EC2について
##### 必要に応じてスペックを変更できる仮想サーバーを作成・利用できるサービス
#### RDSについて
##### フルマネージドで管理負担を抑えられるデータベースサービス

##### 色々できてしまうので専用の資格が10種類以上あるくらいです。この資格を持ったエンジニアはAWS導入時のコンサルティングから設計・構築・監視・保守管理などを仕事にしています。

もう少し他の人の書き方を参考にして書くようにしたいです。
次回は「ネットワーク」について書きます。
MAMPのローカル環境では動くのに、サーバーにアップするとphpが動かない（HTTP500エラー）

## サーバーのphpのshort_open_tagがoffになっている可能性
short_open_tagは、phpを省略して書く方法

## その情報を見るには
ファイルにinfo.phpという名前のからファイルを入れてアップ、アドレスバーにそこまでのファイルのパスを書く。
→サーバーの設定情報一覧が出る

## 解決策
info.phpページのuser_ini.filenameに書いてあるファイルの名前を作ってアップする
そこにshort_open_tagをオンにする記述して、アップする
例）.user.ini

記述するコード↓
https://helog.jp/php/short_open_tag/
Rでlouvain法を用いたクラスター抽出をする

#### やること

二次元の散布図をクラスタリングしたい場面が個人的によくあります。Rでは、kmean関数にデータフレームとクラスター数を入れてしまえば良いのですが、クラスター数の設定や初期値のあれやこれやが。そういった場合にk-means的なノリでlouvain法を用いる際の覚書。
散布図から隣接行列を作り、グラフにしてから、louvain法でクラスター抽出をします。

データはkaggle(https://www.kaggle.com/c/digit-recognizer/data )からMNISTをダウンロードして使ってみます。

#### 下処理

データを読み込みます。
tidyverseはマストではないです。

```r
library(tidyverse)
mnist <- read_csv("~/train.csv")
lab <- mnist %>% pull(label)
mnist <- mnist %>% select(-label)
```

データ数が42000個と結構多くて大変なので、適当に1割くらい抽出して使います。

```r
idx <- sample(1:nrow(mnist),0.1*nrow(mnist))
lab <- lab[idx]
mnist <- mnist[idx,]
```

二次元の散布図のクラスタリングを想定しているので、mnistを二次元に次元圧縮します。
ここではUMAPを使います。

```r
um <- uwot::umap(mnist)
```

プロットしてみます。色はラベルで。

```r
tab <- um %>%
  as_tibble() %>%
  rename(UMAP1=1,UMAP2=2) %>%
  mutate(label=as_factor(lab))
tab %>% 
  ggplot(aes(UMAP1,UMAP2,color=label)) +
    geom_point(size=.6,alpha=.6) + 
    theme_minimal() + coord_fixed()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/446050/259967c9-3b6a-de25-e58f-0e6bd9297b4f.png)


#### クラスタリング

louvain法はigraph::cluster_louvainで実装されていますが、入力がグラフなので、先ほどの散布図をグラフにしてから、この関数に入れます。

まず、座標（→距離行列）→隣接行列
```r
d <- dist(um)
adj <- as.matrix(d)<1.5
```

距離が1.5より近いデータ点同士を結んだ隣接行列を作っています。
ここの閾値の設定はもっと適切な方法がありそうです。

次に、隣接行列→グラフにしてから、クラスター抽出。
グラフにする際は、mode='undirected'で無向グラフに設定する必要があります。

```r
g <- igraph::graph_from_adjacency_matrix(adj,mode='undirected')
lou <- igraph::cluster_louvain(g)
```

抽出したクラスターで色分けしてプロットしてみます。
クラスタリングの結果は、membershipに格納されています。

```r
tab %>% 
  mutate(cluster=paste0('C',lou$membership)) %>%
  ggplot(aes(UMAP1,UMAP2,color=cluster)) +
    geom_point(size=.6,alpha=.6) + 
    theme_minimal() + coord_fixed()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/446050/d0c67393-f97e-abb9-7fd5-bd79a466b851.png)

いい感じです。


#### まとめ

louvain法はk-meansとかと比べてロバストで直感にあったクラスタリングしてくれるので好きです（こなみ）。
以下データと閾値を引数に入れるとfactorの行列でクラスター番号を返す形でまとめたものです。
```r
louvain <- function(mat,cut,membership=T){
  D <- as.matrix(dist(mat))
  g <- igraph::graph_from_adjacency_matrix(D<cut,mode='undirected')
  Lou <- igraph::cluster_louvain(g)
  res <- as.factor(Lou$membership)
  Nc <- length(levels(res))
  cat(paste0(Nc," clusters\n"))
  if(membership){
    return(res)
  }else{
    return(Lou)
    }
}
```
参加日記: AtCoder ABC 245 AからF(Python)



# A - Good morning

https://atcoder.jp/contests/abc245/tasks/abc245_a

`１日を86400秒とした時の比較`とすると単純です。秒数はh時m分の入力があった時、$60h + m$で求められます。青木くんは1秒後ということで+1して比較すれば良いです。

時間・空間計算量はO(1)です。

<details><summary>実装(Python)</summary><div>

```Python
a,b,c,d = map(int, input().split())
x = a*60 + b
y = c*60 + d + 1
if x < y: print("Takahashi")
else: print("Aoki")

```
</div></details>

https://atcoder.jp/contests/abc245/submissions/30569207

# B - Mex
https://atcoder.jp/contests/abc245/tasks/abc245_b

多少問題を言い換えると以下のようになります。
- 0,1,2...と数字を見ていき、Aに含まれない最初の数を答えてください

実装としては以下の２つが考えられます。
- 1: Aをリストとして扱い、存在を確認します。リストへの検索は各存在確認に対して$O(N)$です。全体で$O(N^2)$でTLに対して十分に動きます。
    - extraな空間計算量は$O(1)$です。
- 2: Aを辞書として扱います。辞書への追加と存在確認は$O(1)$のため全体で$O(N)$です。
    - なお、C++でsetを用いると$O(logN)$です。
    - extraな空間計算量は$O(N)$です。

時間、空間共に最悪のケースはNが2000であることからAが$0,1,2,..,1998,1999$の時で、答えが2000の時です。

<details><summary>実装(Python)</summary><div>

```Python
n = int(input())
dat = set(map(int, input().split()))
i = 0
while i in dat: i += 1
print(i)
```
</div></details>

https://atcoder.jp/contests/abc245/submissions/30569434

# C - Choose Elements
https://atcoder.jp/contests/abc245/tasks/abc245_c

この問題は解説以上に書くことがないので省略します。

https://atcoder.jp/contests/abc245/editorial/3634

私は値をとりうるか？の代わりに、None or 値が入っている場合は何が入っているか？という管理にしましたが、この問題の場合どちらでも良いでしょう。

時間空間計算量は$O(N)$です。

<details><summary>実装(Python)</summary><div>

```Python
n, k = map(int, input().split())
data = list(map(int, input().split()))
datb = list(map(int, input().split()))
dp = [[None] * 2 for _ in range(n)]
dp[0][0] = data[0]
dp[0][1] = datb[0]

for ind in range(1, n):
    if dp[ind - 1][0] is not None:
        if abs(data[ind] - dp[ind - 1][0]) <= k: dp[ind][0] = data[ind]
        if abs(datb[ind] - dp[ind - 1][0]) <= k: dp[ind][1] = datb[ind]
    if dp[ind - 1][1] is not None:
        if abs(data[ind] - dp[ind - 1][1]) <= k: dp[ind][0] = data[ind]
        if abs(datb[ind] - dp[ind - 1][1]) <= k: dp[ind][1] = datb[ind]

if dp[n - 1][0] is not None: print("Yes")
elif dp[n - 1][1] is not None: print("Yes")
else: print("No")

```
</div></details>

https://atcoder.jp/contests/abc245/submissions/30569608

# D - Polynomial division 
Python(numpy)すごいなー...

https://atcoder.jp/contests/abc245/editorial/3668

# E(別記事)

https://qiita.com/recuraki/items/248b416266337e45af3f

# F(別記事)

https://qiita.com/recuraki/items/4366e3c29f487bde1f6d
型定義で型の使い回し

# 前提
CMSのデータをNext.js+TypeScriptで管理していたときに遭遇
ブログ記事、カテゴリ、タグと３つの型がある
カテゴリとタグはブログ記事の情報に含まれるため、使い回したい

# コード
※カテゴリは単一、タグは複数
```index.ts
export type blog = {
  id: string,
  createdAt: string,
  updatedAt: string,
  publishedAt: string,
  revisedAt: string,
  title: string,
  body: string,
  category: category, // categoryを使い回し
  tag: tag[], // tagを使い回し
}

export type category = {
  id: string,
  createdAt: string,
  updatedAt: string,
  publishedAt: string,
  revisedAt: string,
  name: string,
}

export type tag = {
  id: string,
  createdAt: string,
  updatedAt: string,
  publishedAt: string,
  revisedAt: string,
  name: string,
}
```

# 参考
[型の再利用 | TypeScript入門『サバイバルTypeScript』](https://typescriptbook.jp/reference/type-reuse)
Redash

# 【Redash】
実務で Redash を使っているので簡単に調査した。 

## Webサービス運用にログ分析は必要不可欠
- しかし、生のアクセスログを集計する場合、
    - 保存場所からログを取得し、必要なログを抽出し、Web上のサービスと突き合わせる必要がある。
    - **手間と時間がかかる。**

## Redash
- Redash というツールを使うことでログ分析が簡単になる。
    - 単発で必要な数字や、集計処理の試行錯誤を行うときに使える。
    - 長期的に記録したい数値については処理をプログラムコードとして記述すれば良い。
- Redash はブラウザから各種DBへのクエリ発行ををWebUIでおこなえる。
- クエリを保存して定期実行も可能
- 実行結果をCSVで取得したいグラフとして表示することも可能
    - Amazon Aurora　MySQL に対応している。
[ VSCode-UIFlow ] 3年ぶりのリリース!!(概要)

# なぜやる気を出したか？
いや、ほんと分かりません。やる気スイッチが入ったんです。
なんとなくコードを書きたくなる衝動があって、もう一度やってみようという気になりました。


# 脆弱性の壁

```
npm audit fix
```
しても治りませんでした。確か、脆弱性は無くなったんだけど、起動しなくなりました。
もう土台が腐ってしまったんですね。
私のVSCode-UIFlowは`yo code`で生成した土台の上に造られていましたので、
ここで、一旦 `yo code`で土台を生成し直しました。


# Webpack!!!!

ついでにWebpackっていうのも初めて使いました。
最近のフロントエンド界隈では主流だとかいう話ですね。
まぁ、使う必要はなかったんですがロマンを感じましたね。

# TypeScriptのエラー
まぁ、３年間ほったらかしてたのでしょうがないですが、
色々とコンパイルエラーが出たので駆逐する作戦を行いました。

# `Viz.js`から`d3-graphviz.js`への移行
まぁ今回主目的があって、Windowsでのプレビューに関する不具合を改善する狙いがありました。
プレビューの機能を担っていたのがViz.jsでしたが、すでにメンテされていませんでした。
Twitterでd3-graphviz.jsいいぞって教えてくれる外人が登場してくれて、
これに切り替える方針にしました。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">You might look at <a href="https://t.co/ud38fdss36">https://t.co/ud38fdss36</a> and <a href="https://t.co/L60yo36uKU">https://t.co/L60yo36uKU</a>)</p>&mdash; sroush (@sroush10) <a href="https://twitter.com/sroush10/status/1505919948157337610?ref_src=twsrc%5Etfw">March 21, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

マジでemscriptenの沼にハマるところでした。Thanks!!!

# リリース！

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">本日 VSCode-UIFlow@2.0.0 をリリース致しました✨<br>経費を支援いただいた <a href="https://twitter.com/hiroki_daichi?ref_src=twsrc%5Etfw">@hiroki_daichi</a> 様　誠に有難う御座いました。<br><br>アップデートで不具合が出てしまった方は <a href="https://twitter.com/hashtag/Github?src=hash&amp;ref_src=twsrc%5Etfw">#Github</a> のIssueで報告していただければと思います。<a href="https://t.co/iOK7uCWUZ8">https://t.co/iOK7uCWUZ8</a><a href="https://twitter.com/hashtag/uiflow?src=hash&amp;ref_src=twsrc%5Etfw">#uiflow</a> <a href="https://twitter.com/hashtag/vscode?src=hash&amp;ref_src=twsrc%5Etfw">#vscode</a> <a href="https://twitter.com/hashtag/azure?src=hash&amp;ref_src=twsrc%5Etfw">#azure</a></p>&mdash; Kei Nakayama / VSCode-UIFlow (@keisan) <a href="https://twitter.com/keisan/status/1507696388246675466?ref_src=twsrc%5Etfw">March 26, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


今回のアップデートを支援してくださった @hirokidaichi さんありがとうございました！

# VSCode-UIFlow は無料で使えます
興味がある方はVSCodeをインストールした上で
https://marketplace.visualstudio.com/items?itemName=kexi.vscode-uiflow
からインストールしていただければと思います。

開発時の記事は以下のURLになります。
https://qiita.com/kexi/items/f5bd25fd4a7da81e62d4


# 最後に
本当はAzureなども初めて触ったので、そういったことにも触れていきたいと思います。

ではでは👋
［5行メモ］切り捨て・切り上げの名前をど忘れしたら

JavaScriptだと `Math.ceil` と `Math.floor`、 Java/Kotlinだと `BigDecimal.divide(divisor, roundingMode)` とかで切り捨て・切り上げが出てきますが、どっちだったっけ？と迷うことが偶にあります。

そんなときの簡単な覚え方。

- `ceil/ceiling`: シーリング、天井（シーリングライトとかの）。上のほうなので**切り上げ**。正の数に近い方になります。
- `floor`: フロア、床（フロアマットとかの）。下のほうなので**切り下げ**。負の数に近い方になります。
Perforceで特定のチェンジリストが空か確認する

Perforceの絡むバッチ処理を書いていると特定のチェンジリストが空かを確認したい場合が多々発生します。

特に下記のように特定の処理後の生成物をreconcileでチェンジリストに追加してsubmitすることが多いです。
```bat
<何かしらのビルド処理>
p4 reconcile 
p4 submit
```

しかし、定期実行を行っていると生成物の変化がなくreconcileの実行結果で
`no file(s) to reconcile.`
となる場合があります。

p4 reconcileはそれで問題なく通過できるのですが、チェンジリストが空の状態でp4 submitを実行すると
`No files to submit from the default changelist.`
と表示されエラーとなってしまいます。
エラーを握りつぶすこと自体は可能なのですが、このエラー以外の発生も握りつぶしてしまうため、チェンジリストが空でない場合のみsubmitを実行したいです。

p4コマンドで素直に確認する方法が調べた感じ見つからなかったので何かしら工夫が必要そうです。
（スクリプト言語などで解析する方法が楽ではあるかもしれないのですが、今回は実行環境に出来るだけ依存しない形にしたかったのでbatのみで対応しています）

対応してみたコードは下記になります。
```bat
<何かしらのビルド処理>
p4 reconcile

for /f %%A in('p4 -ztag opened -c default -m 1') do set aaa=%%A

if "%aaa%" == "" (
    echo "Skip submit."
) else (
    echo "Execute submit."
    p4 submit
)
```

p4 openedで指定のチェンジリストに含まれるファイルの情報を取得します。
内容は特に全チェックは不要で1ファイルでも含まれているか確認したいので`-m 1`で個数を制限します。
通常だと、チェンジリストが空の場合、
`File(s) not opened on this client.`
とログが表示されます。
`-ztag`を付与すると空の場合は何も表示されません。
（そのため、ログのチェックが楽になります）

そのログをfor文で変数取得することで文字列が空かどうかでチェンジリストの状況を確認することが出来ます。

これでなんとかエラー回避ができました。
p4コマンドでスマートに確認する方法ってあるんでしょうかね？
3回目（サーバー）

サーバについて
![サーバー1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606732/62e88f22-60ae-c8e3-b476-208bc34c8e56.png)


第一分岐（サーバーの利用形態、コスト面など）
第二分岐（サーバーの種類、使い方など）

端的に言えば高性能なパソコン。
処理能力が高くなることによってデータのアクセスや提供ができるようになる。

パソコンを水筒と考えるとサーバーはウォーターサーバー、やタンクなど単純に大きいイメージがつく。業者が必要になるのもイメージは付きやすい。例え話は限界を迎えます。水が高速で運ぶことが実現できれば世界の水不足問題は解決できるからです。
![サーバー2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606732/14f71388-976d-a0a6-1356-ea15593e826c.jpeg)

データの転送速度はネットワーク回線の発達により、高速化されてきました。そのため、情報分野に戻すとHTML/CSS、メール、動画など色々なファイル形式のものを、リクエストに応じてレスポンスを返すことができます。それぞれサーバーの機能が異なっていて、WEBサーバー、メールサーバー、ファイルサーバー、DNSサーバー、アプリケーションサーバーなど分類の仕方があげられる。

サーバーには企業が独自で持っている「専用サーバー」、個人が利用する際に使われる「共有サーバー」、多機能で従量課金制の「クラウドサービス」の三つに分類できる。
それぞれ処理能力、応答速度、コスト、セキュリティといった面から比較されるが詳しいことはわかりません。

その中でクラウドサービスの中で広く利用されているものには３つある。
AWS(Amazon Web servies)
Azure(Microsoft Azure)
GCP(Google cloud platform)
AWSは触ったことがある。

まとめサーバーは、高い処理能力によって利用者からの要求におうじて、必要なデータを提供するものである。サーバーを選ぶ際にはコスト面などから分けると、「専用」「共有」「クラウド」の３つに分けられる。

次回はAWSについて書きます。
【PHP】サマータイムかどうかを判定する

## 目的
サマータイムのある地域において、特定の日付がサマータイムの期間内かどうかを調べる機会があったので、PHPで判定の実装をしてみました。

## 結論
DateTimeZone::getTransitionsを用いて判定を行います。
```php
$timezone = new DateTimeZone('America/Los_Angeles');
$datetime = new DateTime('2022/3/12', $timezone);
$transitions = $tz->getTransitions($datetime->getTimestamp(), $datetime->getTimestamp());
echo $transitions[0]['isdst']; // false
```

## DateTimeZoneオブジェクト

PHPの日付クラスであるDateTimeはタイムゾーンの情報は持っていますが、サマータイムの情報はもっていません。
与えられた日時においてサマータイムかを判定するために<a href="https://www.php.net/manual/ja/datetimezone.gettransitions.php">DateTimeZone::getTransitions</a>を使用しました。

getTransitionsメソッドは与えられたUnixタイムスタンプの期間内において、そのタイムゾーンの推移を取得することができます。
|キー|型|説明|
|-|-|-|
|ts|int|Unixタイムスタンプ|
|time|string|DateTimeInterface::ISO8601 形式の文字列|
|offset|int|UTC からのオフセット(秒単位)|
|isdst|bool|サマータイムが有効かどうか|
|abbr|string|タイムゾーンの省略形|


たとえばロサンゼルスでは、2022/1/1〜12/31の期間の推移を調べてみましょう。
```php
$timezone = new DateTimeZone('America/Los_Angeles');
$timezone->getTransitions(strtotime('2022/1/1'), strtotime('2022/12/31'))
```
2022/3/13にサマータイムが開始され（PDT: 米国太平洋標準時(夏時間)になる）、2022/11/6にサマータイムが終了することがわかります（PST: 米国太平洋標準時になる）。

```shell
   [
     [
       "ts" => 1640962800,
       "time" => "2021-12-31T15:00:00+0000",
       "offset" => -28800,
       "isdst" => false,
       "abbr" => "PST",
     ],
     [
       "ts" => 1647165600,
       "time" => "2022-03-13T10:00:00+0000",
       "offset" => -25200,
       "isdst" => true,
       "abbr" => "PDT",
     ],
     [
       "ts" => 1667725200,
       "time" => "2022-11-06T09:00:00+0000",
       "offset" => -28800,
       "isdst" => false,
       "abbr" => "PST",
     ],
   ]

```

このとき、startとendを同一日時にしてやることでその時点においてサマータイムが適用されているかをisdistで調べてやることができます。
```php
$timezone->getTransitions(strtotime('2022/1/1'), strtotime('2022/1/1')); // startとendを一致させる
```
```shell
[
     [
       "ts" => 1640962800,
       "time" => "2021-12-31T15:00:00+0000",
       "offset" => -28800,
       "isdst" => false,
       "abbr" => "PST",
     ],
   ]
```

## 注意
### サマータイムの切り替え日における判定
サマータイムの切り替えタイミングでは意図していない挙動になる可能性があります。

たとえばロサンゼルスでは2022/11/6 2:00にサマータイムが終了し、また1:00に巻き戻す処理が行われます。
つまり2022/11/6 1:00〜2:00が2回存在し、サマータイムである状態とそうでない状態のどちらも両立するということです。
```php
$timezone = new DateTimeZone('America/Los_Angeles');
$datetime = new DateTime('2022/11/6 1:00', $timezone);
$timezone->getTransitions($datetime->getTimestamp(), $datetime->getTimestamp());
```
この場合、結果はサマータイムになります。
```shell
[
     [
       "ts" => 1667721600,
       "time" => "2022-11-06T08:00:00+0000",
       "offset" => -25200,
       "isdst" => true,
       "abbr" => "PDT",
     ],
   ]
```

### 判定可能日時

getTransitionsで取得可能な期間は2037年までですので、それ以降の判定にもちいることはできません。
TypeScriptとは【個人的なお勉強アウトプット】

マイクロソフトが開発したJavascriptを進化させたプログラミング言語。
Googleも社内標準言語として取り入れている。

## TypeScriptのメリット
- エラー防止できる
- コードが短く読みやすい
- 動作が早い


### エラー防止できる
#### 型が定義できる
型がわかりやすくまとまっている記事は以下。
https://qiita.com/uhyo/items/e2fdef2d3236b9bfe74a

#### コンパイル時にエラーチェックできる
型と値が異なること、変数が未定義なことなど、コンパイルエラーをだしてくれる

## コードが短く読みやすい
JacvaScriptでは使えなかったクラス生成が可能
TypeScriptのクラスの利用に関してすごくわかりやすい記事
https://atmarkit.itmedia.co.jp/ait/articles/1507/16/news022.html

## 動作が早い
静的型付けの言語なのでコード内で型を宣言できるぶん、実行時に型を決める動的型付けのJavaScriptより動作が早くなる
SQLメモ

## SQLを少しでも軽く
**１．SELECT句の「＊」**
「＊」の部分はできるだけ必要なカラム名だけを取得する

**２．WHERE句の条件指定順**
条件指定の順番は結果が少なくなるような条件を先に記述する

**３．テーブルに別名を付けてSQLを書く**
「FROM テーブル名 A」の「A」みたいな別名を付けるようにする

**４．COUNT関数**
COUNT(カラム名)のように書くようにする
列にインデクスが張られている場合はそのほうがいい

**５．IN句の引数リスト**
IN句の引数リストには左から順に最もありそうなキーを書くようにする
下記の場合、パターン２のほうがいいみたい
パターン１：IN ('鳥取', '徳島', '東京', '大阪');
パターン２：IN ('東京', '大阪', '鳥取', '徳島');

**６．左辺へ使用する関数**
WHEREの条件では右側に関数を使用するようにする
INDEXの使用できなくなる

**７．INDEXの利用**
GROUP BY、ORDER BY句でキーをを指定して高速化できる

WHERE句の条件が完全一致の場合は高速化できる
LIKEのワイルドカードを使用した場合は無理

JOINでの結合条件にインデクスのある列を使用すると高速化できる

**８．UNION**
重複を気にしなくてもいい場合はUNIONではなくUNION ALLを使用する
UNIONは重複行を排除するためのソートが発生するため遅くなる

**９．INDEXが使用できない場合**
IS NULLを使用している
ORを使用している
否定形を使用している 
複合INDEXの場合カラム順を間違えている
LIKEの記述で後方一致、中間一致を使用している

## ちょくちょく使うSQL
**LIKE**
「％」は任意の0文字以上の文字列
```sql
SELECT カラム1 FROM テーブル1 WHERE カラム1 LIKE '%A%'
```
「_」は任意の1文字
```sql
SELECT カラム1 FROM テーブル1 WHERE カラム1 LIKE '_A_'
```

**ANY**
比較演算子の条件が副問い合わせの結果と比較し一つでも真になるとき真
```sql
SELECT カラム1 FROM テーブル1 WHERE カラム1 =< ANY (副問い合せ)
```

**ALL**
比較演算子の条件が副問い合わせの結果と比較し全てが真になるとき真
```sql
SELECT カラム1 FROM テーブル1 WHERE カラム1 =< ALL (副問い合せ)
```

**MINUS**
最初の検索結果から次の検索結果と重複する部分を取り除く
```sql
SELECT カラム1 FROM テーブル1
MINUS
SELECT カラム1 FROM テーブル2
```

**INTERSECT**
２つの検索結果で重複するもの
```sql
SELECT カラム1 FROM テーブル1
INTERSECT
SELECT カラム1 FROM テーブル2
```

**CASE**
データ抽出時の条件分岐
```sql
SELECT
    CASE カラム1
        WHEN カラム1 < 20 THEN '1'
        ELSE '0'
    END AS 区分
FROM テーブル1
```

**LENGTH**
文字数を取得
```sql
SELECT LENGTH(カラム1) FROM テーブル1
```

**TRIM**
文字列の空白を削除
```sql
SELECT TRIM(カラム1) FROM テーブル1
```

**REPLACE**
指定文字列を置換する
```sql
SELECT REPLACE(カラム1,'A','B') FROM テーブル1
```

**SUBSTRING**
文字列から切り取り
```sql
SELECT SUBSTRING(カラム1,1,3) FROM テーブル1
```

**ROUND**
四捨五入
```sql
SELECT ROUND(カラム1,1) FROM テーブル1
```

**WITH**
一時的にビューを作成
```sql
WITH テーブル1 as {
    select カラム1 from テーブル2
)
select カラム1 from テーブル1
```

**UPPER**
大文字へ変換
```sql
SELECT UPPER('文字') FROM テーブル1
```

**LOWER**
小文字へ変換
```sql
SELECT LOWER('文字') FROM テーブル1
```

**SYSDATE**
システム日付を取得
```sql
SELECT SYSDATE FROM テーブル1
```

**TO_CHAR**
日付、数値を文字列へ変換
```sql
SELECT TO_CHAR(SYSDATE,'YYYY/MM/DD') FROM テーブル1
```

**TO_DATE**
文字列を日付へ変換
```sql
SELECT TO_CHAR('2022/03/01','YYYY/MM/DD') FROM テーブル1
```

**NVL**
第１引数がNULLの場合、第２引数の値に置き換える
```sql
SELECT NVL(カラム1,'nullでした') FROM テーブル1
```

**NVL2**
第１引数がNULLでない場合、第２引数の値に、NULLの場合、第３引数の値に置き換える
```sql
SELECT NVL(カラム1,'nullじゃない','nullでした') FROM テーブル1
```

**DECODE**
指定したカラムの値によって返却する値を変える
カラム1の値が値1の場合、結果1を返却
値2の場合は結果2の値でそれ以外の場合は結果3を返却
```sql
SELECT DECODE(カラム1,'値1','結果1','値2','結果2','結果3') FROM テーブル1
```

**DUAL**
ダミーテーブル
ちょっとした関数の確認とかに便利
```sql
SELECT 'test' FROM DUAL
```

**WHERE 1=1**
テストする時に条件を変更するのが楽になる
以下のcodeの条件を削除かコメントアウトしても1=1があるからname前のANDを消さなくてもすむとか
```sql
SELECT カラム1 F
ROM テーブル1 
WHERE 1=1
--AND code = 1
AND name = taro
```
SQL実行環境

## Oracle Database Express Editionのインストール
・[Oracle Database XE](https://www.oracle.com/jp/database/technologies/xe-downloads.html)のサイトからダウンロード
・setup.exeを実行しインストール
　パスワードとフォルダは任意の値で以下手順を進める
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643549/1f44b54b-603f-1500-c762-6c1f6de36f3a.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643549/f60354fc-022a-257d-9c18-32f8d21ed80a.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643549/fa655bf8-b057-c365-ac9b-943402ed290e.png)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643549/cb66aa9f-f5b6-cc7f-64fe-0daaeab05505.png)
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643549/5e89a2ca-d285-b094-9969-6a79fc330cf3.png)
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643549/25a3dcfa-bba6-a2f9-0424-d1eec4c9b76c.png)
完了押してインストール終了

## OSqlEditのダウンロード
・[OSqlEdit](http://www.hi-ho.ne.jp/a_ogawa/osqledit/)のサイトからダウンロード
　ダウンロードしたファイルは使用しやすい場所へ移動（C直下とか）
・以下パスにある「tnsnames.ora」の接続文字列を確認
　C:\oracle\homes\OraDB21Home1\network\admin
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643549/7d9785c0-fa30-c14b-0bd9-aa0b01a06edf.png)
・OSqlEditを起動して接続文字列を入力しログイン
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643549/3299b90e-87e8-6a49-b48e-959f2c667ec5.png)
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643549/0e4be511-d5e8-2e6a-e40e-4b022c13aaca.png)
・sql実行確認
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643549/fcfc5a72-62f3-ca41-f382-02b27ff57aec.png)
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643549/baba325c-a595-d576-3c21-f2bc0047825d.png)
MacでDreamWeaverが重い、開かないとき

# 以下の方法を試してみる

### 方法1. shareや他のPCを参照している場合があるので、接続してから再度開く

### 方法2. デスクトップの移動を開いた状態でoptionキーを押すとライブラリが出現→<br>ApplicationSupport>Adobe>Dreamweaver使用中のバージョン>ja_JP>Configrationを選択→<br>siteChacheフォルダをフォルダごと消す（心配ならデスクトップかどこかに名前変えてバックアップ）

## 方法3. .steフォルダが破損している可能性があるので、壊れる直前に読み込んだサーバー情報を保存したサイトのフォルダを消す
cakephpのDebugKitがforceEnableをtrueにしているのに出ない

大体の記事ではタイトルの通り、DebugKitのforceEnableをtrueにしましょう！で終わっているのですが、trueにしてるのに出ないという人が何故かいない・・・
やらなきゃいけないことはやっているので、権限とかそういうのだろうなとは思っていましたが、以下の通りです。

## やったこと
```
sudo chmod 777 tmp
sudo chmod 777 tmp/debug_kit.sqlite
```

既に動いているcakephpのアプリをcpでコピーしたのに、なぜかここの権限のせいで出なくなっていました。
同じ悩みを抱えている方がいらっしゃったら、是非試してみてください。
【初心者向け】Tera Termのおすすめ設定

**はじめに**
---
Tera Termを初めて触る方向けに、おすすめの設定をメモとして残そうかと思いました。
新卒でTeraTermを初めて触る方も増えてくるかと思うので参考にしてみてください。

***おすすめ設定一覧***
---
下記の設定を変更することで作業の効率化を図りたいと思います。

・自動ログ取得
・フォントサイズ変更
・シリアルポートの送信速度


***自動ログ取得***
---
ログ取得は上部タブのファイルからログを選択することで可能ですが、
TeraTermを起動させる度に毎回ログを取得するのを選ぶのは効率的に悪いです。
また、複数起動すると余計に時間がかかってしまいます。

そのため、TeraTermを起動する時に自動でログを取得するように設定します。
これにより、作業の効率化とログ取得を忘れるリスクを回避できます。

自動ログ取得のやり方は以下のとおりです。

①「設定」＞「その他の設定」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513082/3d018717-ede7-9c98-202d-b334597e0e68.png)

②上部タブより「ログ」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513082/49624b89-aa07-cba0-e817-4c069bc14c65.png)

③「標準ログファイル名」を【%Y%m%d_%H%M%S_&h.log】に変更します。
【%Y%m%d_%H%M%S_&h】にすることでファイル名を【日付_時間_接続先アドレス】にすることができます。
※自動ログだけでなく、手動でログを取得する際もこのファイル名が標準になります。

④「自動的にログ採取を開始する」にチェックを入れて、「OK」をクリックします。

　 また、好みに合わせて、「標準のログ保存先フォルダ」も選択できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513082/31bf76a0-63ea-6475-6bdb-ce3fa382ae78.png)

⑤最後に設定を保存します。
※これを忘れると自動ログ取得が出来ませんので注意してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513082/d0115fa0-bc63-e796-576c-46465abbd4d2.png)

以上で、自動ログ取得の手順は完了です。


***フォントサイズ***
---
TeraTermに表示される情報量には限りがあり、確認するのにスクロールを多用したりします。
少しでもそれを減らすためにフォントサイズを変更したいと思います。

①「設定」＞「フォント」＞「フォント」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513082/5969247a-a95a-7e14-1c93-42de1d8405be.png)

②「サイズ」で好みの大きさを選択します。
なるべく小さいサイズを選択することで、画面内に表示される情報量が増えます。
そのため、自身が読める最小サイズにすることをお勧めします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513082/f7a49290-a912-d1e6-5913-84703b1e3c68.png)

③最後に自動ログ取得時と同様に設定を保存してください。
※これを忘れると次回TeraTerm起動時に変更されたフォントサイズが反映されません。

以上で、フォントサイズの変更手順は完了です。


***シリアルポートの送信速度***
---
シリアルコンソールでコンフィグファイルの流し込みをした際にデフォルト設定だと文字ずれなどが起きたりします。
送信遅延設定を変更することで文字ずれなどを起きにくくしたいと思います。


①「設定」＞「シリアルポート」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513082/816153d6-2932-44c4-9ede-1395ead6eeb3.png)

②「送信遅延」にて【5ミリ秒/字】と【1ミリ秒/行】に変更します。

※上記設定でも文字ずれなどが発生する場合は、より長めの遅延にすることで解決する場合があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513082/aea9ac1d-e16d-4bc9-86fc-8c6fbf4d1eee.png)

③最後に自動ログ取得時と同様に設定を保存してください。
※これを忘れると次回TeraTerm起動時に変更されたシリアルポートの設定が反映されません。

以上で、シリアルポートの送信速度の変更手順は完了です。


***参考サイト***
http://www.j-oosk.com/teraterm/logging/114/
自動ログ取得の設定の参考にしました。

https://syszo.com/items/CMVdadjqUI
シリアルポートの送信速度設定の参考にしました。

***最後に***
---
これからTeraTermに触れるという方の参考になれば幸いです。
LaravelのSMTPサーバを動的に設定する

LaravelでSMTPサーバを設定するとき通常であれば`.env`に設定しますが、DBなどの動的な値を設定することができません。`.env`以外の方法を使ってSMTPサーバを動的に設定してみます。

## 環境
- PHP: 8.0.3
- Laravel: 8.65.0

## 手順

### 1. Mailableの生成

まずMailableを生成します。

```bash
php artisan make:mail Hoge
```

### 2. buildメソッドでSwiftMailerの上書きする

LaravelではSwiftMailerが使用されており、`setSwiftMailer`で上書きすることができます。1. で作成したMailableの`build`メソッド内で呼び出します。

```php:app/Mail/Hoge.php
    public function build()
    {
        $config = # DBなどから設定情報を取得する

        /** @var \Illuminate\Mail\Mailer $mailer */
        $mailer = Mail::mailer();
        $transport = new Swift_SmtpTransport($config['mail_host'], $config['mail_port']);
        $transport->setUsername($config['mail_username']);
        $transport->setPassword($config['mail_password']);
        $mailer->setSwiftMailer(new Swift_Mailer($transport));
        $mailer->alwaysFrom($config['mail_from_address'], config('mail.from.name'));

        # 通常通りビューなどの設定を行う
        return $this->view('view.name');
    }
```

### 3. メールを送信する

あとは`send`メソッドや`queue`メソッドでメール送信、キュー投入すればOKです。

```php
Mail::to('to_address@example.com')->send(new Hoge());
Mail::to('to_address@example.com')->queue(new Hoge());
```

## 没案：Providerを作る

`$mailer->setSwiftMailer`で行う上書き処理は必ずしも`build`メソッドで行う必要はないのですが、以下の理由からProviderで行うことは避けた方が良さそうでした。

- キューでメールを処理する場合に対応できない
- メールに関係のないリクエストのときにも処理が発生してしまう（この問題は遅延プロバイダを使えば解決できそうですが）

## 参考

https://readouble.com/laravel/8.x/ja/mail.html

https://swiftmailer.symfony.com/docs/introduction.html
Laravel docker buildする用のDockerFileの書き方

## LaravelのコンテナをビルドしてECRにpushする場合など

よく見かける開発用のdocker構成だと、volumeがリンクなので、そのままbuildしても何もファイルがない、という状態になる。

また、composer installなどは手動でやる前提のままになっているのでdocker build=laravelがそのまま動く状態になっていない。

よって、DockerFileを少し変更する必要があった。

## DockerFile Example

```
FROM php:7.4-fpm-buster
SHELL ["/bin/bash", "-oeux", "pipefail", "-c"]

# timezone environment
ENV LANG=C.UTF-8 \
    LANGUAGE=en_US: \
    LC_ALL=C.UTF-8 \
    TZ=UTC

# ini and conf
COPY ./infra/docker/php/zzz-www.conf /usr/local/etc/php-fpm.d/zzz-www.conf
COPY ./infra/docker/php/php.ini.production /usr/local/etc/php/php.ini

# ここでローカルのlaravelのディレクトリをコピーする
COPY ./local_develop_BackEnd /work/backend

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git \
    curl \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    libzip-dev \
    zip \
    unzip \
    vim

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install PHP extensions
RUN docker-php-ext-install intl pdo zip gd pdo_mysql mbstring xml bcmath opcache

# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
RUN composer config -g process-timeout 3600 && \
    composer config -g repos.packagist composer https://packagist.org

RUN apt-get update

# Set working directory
WORKDIR /work/backend

# ローカルフォルダをコピーしているので、不要なキャッシュなどをクリアする
RUN php artisan cache:clear
RUN rm -rf vendor 
RUN rm -rf bootstrap/cache/*
RUN rm composer.lock

# laravelの初期インストールを行う。
RUN composer install --optimize-autoloader --no-dev
RUN cp .env.production .env
RUN chmod -R 777 storage bootstrap/cache
```
[備忘録]map関数とuseState,条件(3項)演算子の復習

## 前書き
どうも皆さん！見習いエンジニアの佐野です！
最近はメガベンチャーの選考を受けつつインターンを頑張っているのですが、やはりメガベンチャーの選考は難しいですねw
コーディングテストがなかなか突破できません。
また、運よくコーディングテストを突破できた会社もあるのですが、面接の時にコーディングテストの内容について詰められたらどうしようかと戦々恐々です😭
まあ、未経験文系エンジニアなので落とされても文句は言えませんね
前書きはこのくらいにして、今回はmap関数とuseState、条件演算子の復習をしていきたいと思います！

## 本文

### map関数
map関数の厳格な定義に関しては各自で調べていただきたいのですが、個人的には　**シーケンスの構成要素に対してひとつずつ処理を行わせることができる関数**だと思っています。もっと簡単にいうと、オブジェクトの中にあるデータを１つずつ取り出すことです！これを使うことで、繰り返しの処理などを簡潔に行えます。具体的には以下のようなコードが例です。

```
function Section({ id, title, children }) {
  return (
    <section id={id} className="box">
      <h1 className="title">{title}</h1>
      {children}
    </section>
  );
}

function DefinitionList({ items }) {
  return (
    <dl className="definition">
      {items.map(item => (
        <div key={item.title}>
          <dt className="definition-title">
            {item.title}
          </dt>
          <dd className="definition-content">
            {item.content}
          </dd>
        </div>
      ))}
    </dl>
  );
}





export default function App() {
  return (
    <>
      <Section id="react" title="React">
      <DefinitionList
        items={[
          { title: 'Initial release', content: '2013/5' },
          { title: 'Github stars', content: '147,940' }
        ]}
      />
    </Section>
    <Section id="vue" title="Vue.js">
      <DefinitionList
        items={[
          { title: 'Initial release', content: '2014/2' },
          { title: 'Github stars', content: '163,165' }
        ]}
      />
    </Section>
    <Section id="angular" title="Angular">
      <DefinitionList
        items={[
          { title: 'Initial release', content: '2016/9' },
          { title: 'Github stars', content: '60,571' }
        ]}
      />
    </Section>
    </>
  )
}

```

参考：https://www.hypertextcandy.com/react-tutorial-02-jsx


map関数を使うときは、関数の引数のところにまずオブジェクトを入れ、その後にmap関数を用いて一度取り出します。その後に、任意の処理を行なっていく感じです！上記のこの部分ですね
```
function DefinitionList({ items }) {
  return (
    <dl className="definition">
      {items.map(item => (
        <div key={item.title}>
          <dt className="definition-title">
            {item.title}
          </dt>
          <dd className="definition-content">
            {item.content}
          </dd>
        </div>
      ))}
    </dl>
  );
}
```


## useState

つぎはuseStateです。reactを使う上では避けては通れないhooksの基本的な機能の一つですね。
基本的には、データを変化させたい時に使います。
具体的には、カウンターを作ったりする時に使うものです。以下のコードが例です。

```
export default function App() {
  const [num, setNum] = useState(0);

  const plus = () => setNum(num + 1);
  const reset =() => setNum(num=0);
  const minus = () => setNum(num-1);
  return (
    <>
      <div>今の値：{num}</div>
      <button onClick={plus}>+1</button>
      <button onClick={reset}>reset</button>
      <button onClick={minus}>-1</button>
    </>
  )
}
```

三つボタンがあり、それぞれを押すと、ボタン以下いてある処理が行われます。
自分はまだ未熟なのでこれぐらいしか例を出せませんが、こ応用していくと色々な機能が作れます


## 条件(3項)演算子
最後に条件演算子を紹介します。この演算子の使い方は、条件に基づいて　２つの値のうちの1つを選択します。
```
条件　?　値１：　値２
```

条件が真なら値１が、偽なら値２が採用されるものです。条件に当てはまるか否か、という処理を行う時に使います。


## 最後に
てことで今回はここまでにします！
やっぱプログラミングは難しいですね(小並感)
もし最後まで見てくれた方がいましたらLGTMをいただけると幸いです。
ではまた違う記事で！