OmniAICreator/Qiita-1.07M huggingface dataset:
サービス内容



**URL：**[アプリの詳細](https://qiita.com/sirororo/items/e2ea79b717d9c7562f0c)
**URL：**[操作手順書](https://qiita.com/sirororo/items/d6ab481eee2c2a187cdb)
**URL：**[アプリ](http://handson-874214957.ap-northeast-1.elb.amazonaws.com/kiso/shop/index.php)
**URL：**[github](https://github.com/sirororo/nouheru)



![トップ１](https://github.com/sirororo/nouheru/blob/master/diagram/%E3%83%9B%E3%82%9A%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%AA%E3%82%AA%202.001.jpeg?raw=true)

![トップ２](https://raw.githubusercontent.com/sirororo/nouheru/b7994b3bf154f9d60a2bd4b3575192a2ccbe0f8c/diagram/%E3%83%9B%E3%82%9A%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%AA%E3%82%AA%202.002.jpeg)

![トップ3](https://raw.githubusercontent.com/sirororo/nouheru/b7994b3bf154f9d60a2bd4b3575192a2ccbe0f8c/diagram/%E3%83%9B%E3%82%9A%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%AA%E3%82%AA%202.003.jpeg)

![トップ4](https://raw.githubusercontent.com/sirororo/nouheru/b7994b3bf154f9d60a2bd4b3575192a2ccbe0f8c/diagram/%E3%83%9B%E3%82%9A%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%AA%E3%82%AA%202.004.jpeg)

![トップ5](https://raw.githubusercontent.com/sirororo/nouheru/b7994b3bf154f9d60a2bd4b3575192a2ccbe0f8c/diagram/%E3%83%9B%E3%82%9A%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%AA%E3%82%AA%202.005.jpeg)

![トップ6](https://raw.githubusercontent.com/sirororo/nouheru/b7994b3bf154f9d60a2bd4b3575192a2ccbe0f8c/diagram/%E3%83%9B%E3%82%9A%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%AA%E3%82%AA%202.006.jpeg)

![トップ7](https://raw.githubusercontent.com/sirororo/nouheru/b7994b3bf154f9d60a2bd4b3575192a2ccbe0f8c/diagram/%E3%83%9B%E3%82%9A%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%AA%E3%82%AA%202.007.jpeg)

![トップ8](https://raw.githubusercontent.com/sirororo/nouheru/b7994b3bf154f9d60a2bd4b3575192a2ccbe0f8c/diagram/%E3%83%9B%E3%82%9A%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%AA%E3%82%AA%202.008.jpeg)

![トップ9](https://raw.githubusercontent.com/sirororo/nouheru/b7994b3bf154f9d60a2bd4b3575192a2ccbe0f8c/diagram/%E3%83%9B%E3%82%9A%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%AA%E3%82%AA%202.009.jpeg)

![トップ10](https://raw.githubusercontent.com/sirororo/nouheru/b7994b3bf154f9d60a2bd4b3575192a2ccbe0f8c/diagram/%E3%83%9B%E3%82%9A%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%AA%E3%82%AA%202.010.jpeg)

![トップ11](https://raw.githubusercontent.com/sirororo/nouheru/b7994b3bf154f9d60a2bd4b3575192a2ccbe0f8c/diagram/%E3%83%9B%E3%82%9A%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%AA%E3%82%AA%202.011.jpeg)

![トップ12](https://github.com/sirororo/nouheru/blob/master/diagram/%E3%83%9B%E3%82%9A%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%AA%E3%82%AA.001.jpeg?raw=true)

![トップ13](https://github.com/sirororo/nouheru/blob/master/diagram/%E3%81%97%E3%82%93.001.jpeg?raw=true)
Windows の PowerShell で Oh My Posh が有効にならない場合、日本語ユーザー名が悪さをしているかも

# はじめに

PC が新しくなったので、[チュートリアル: Oh My Posh を使用して PowerShell または WSL のカスタム プロンプトをセットアップする](https://docs.microsoft.com/ja-jp/windows/terminal/tutorials/custom-prompt-setup) を参照しながら Oh My Posh をインストールしていたら、`Set-PoshPrompt` の実行に失敗した。

``` ps1
PS C:\> Set-PoshPrompt -Theme paradox
&: The term 'C:/Users/譚牙ｱｱ豢倶ｸ/AppData/Local/oh-my-posh/oh-my-posh.exe' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Invoke-Expression: Cannot bind argument to parameter 'Command' because it is an empty string.
```

もちろん？、`Get-PoshTemes` コマンドレットも失敗する。

```
PS C:\> Get-PoshThemes
Get-PoshThemes: The term 'Get-PoshThemes' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
```


# 回避方法

どうやら、日本語ユーザー名があるせいでパスの解決に失敗している模様。

Oh My Posh の FAQ を見ると解決方法が乗っていた

https://ohmyposh.dev/docs/faq#the-term-xxoh-my-poshexe-is-not-recognized-as-a-name-of-a-cmdlet

エンコーディングを UTF-8 にすればよいらしい。

```ps1
$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
```

この状態で、もう一度 Oh My Posh をインストールすれば、`Set-PoshPrompt`や`Get-PoshThemes` が実行できるようになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36535/7221dc3b-e5e2-3942-ec86-b2e20b599486.png)

# おわりに
日本語のユーザー名はまだまだ引っかかるところがありますね。
本日の基礎練習問題(22/3/14)

**問題**
以下の要件を満たすend_otherメソッドを実装しましょう。

メソッドの引数に、任意の2つの文字列を指定する。
引数に指定された2つの文字列のうち、どちらかがもう一方の文字列の末尾にある場合は、Trueを出力する
上記を満たせていない場合は、Falseを出力する
入力された文字が大文字でも小文字でも、同一の文字として処理を行う
```雛形.
def end_other(a, b)
  # 処理を記述
end
```

*呼び出し例
end_other('Hiabc', 'abc') 
*出力例
end_other('Hiabc', 'abc') → True
end_other('AbC', 'HiaBc') → True
end_other(‘abc’, ‘HaIoBc’) → False

# 私の回答
未回答(処理方法がわからず時間制限がきたため断念)

# 模範回答
```ruby
def end_other(a, b)
  a_down = a.downcase
  b_down = b.downcase
  a_len = a_down.length
  b_len = b_down.length
  if b_down.slice(-(a_len)..- 1) == a_down || a_down.slice(-(b_len)..- 1) == b_down
    puts "True"
  else
    puts "False"
  end
end

# 呼び出し例
end_other('Hiabc', 'abc') 
```

# 模範解説
大文字と小文字を区別しないという条件のため、2〜3行目で任意の2つの文字列を小文字に変換しています。

4〜6行目でどちらかの文字列がもう一方の文字列の最後にある場合を区別するための処理を行っています。
slice(-(a_len)..- 1)としているのは、対象の文字列分を切り取るための記述です。

たとえば、以下のようにend_other('Hiabc', 'abc')でメソッドを呼び出し、実行した場合を考えてみましょう。
```ruby
def end_other(a, b)
  a_down = a.downcase
  b_down = b.downcase
  a_len = a_down.length
  b_len = b_down.length
  if b_down.slice(-(a_len)..- 1) == a_down || a_down.slice(-(b_len)..- 1) == b_down
    puts "True"
  else
    puts "False"
  end
end

end_other('Hiabc', 'abc') 
```
すると、2〜5行目で以下のように処理されます。
```ruby
a_down = hiabc
b_down = abc
a_len = 5
b_len = 3
```
続いて6行目で、abcの最後にHiabcが含まれているか、Hiabcの最後にabcという文字列が含まれているかを判別しています。

まずは、条件式の左辺を見て見ましょう。
b_down.slice(-(a_len)..- 1)は、b_down.slice(-5..-1)となります。しかし、b_down = abcとなっているので、インデックス番号-5から-1という条件で切り取ることができません。そのため、この部分はnilとなります。結果、nil == a_downは等しくないと評価されるので、falseになります。

続いて、条件式の右辺を見てみましょう。
a_down.slice(-(b_len)..- 1)はと、a_down.slice(-3..-1)となります。ここで、hiabcという文字列の最後にabcが含まれているかを確認したいので、abcという文字列分を左から数えます。すると、hiabcの最後までを範囲指定していることがわかります。そしてa_down = hiabcとなるので、インデックス番号-3から-1という条件で切り取るとabcが残ります。結果、abc == b_downは等しいと評価されるので、trueとなります。

# 感じたこと
lengthメソッドが思いつかなかった。
またsliceメソッドも理解しきれておらず、まだまだ学習が足りないと感じた。
今回の処理内容を理解し、次に同じような処理方法を行う際は何も見ずに記述できるよう
日々精進していきたい。
Stripe Checkoutで事前に料金を登録せず（アドホック）に決済ページを作成する

今回の記事では、オーダーメイドな製品やパーソナライズした商品など、顧客によって価格や商品内容が異なるケースでのCheckoutの利用方法を紹介します。

# Checkoutでは、料金データを利用する

Stripe Checkoutを利用することで、簡単に決済ページを組み込むことができます。

![https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_2366300_6bcc3c66-7ca7-0d89-e178-12e01b586307.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/b8c771e7-91ca-f801-1be1-9c1cf567738f.png)

サンプルコードでは、一般的に「事前に作成した料金のID」を設定してCheckoutのセッションを開始します。

```js
const session = await stripe.checkout.sessions.create({
  success_url: 'https://example.com/success',
  cancel_url: 'https://example.com/cancel',
  customer_creation: 'if_required',
  line_items: [
    {
       price: 'price_xxx',
       quantity: 2
     },
  ],
  mode: 'payment',
});
```

ですが、オーダーメイドなサービス・製品を提供する場合には、前もって料金を登録することができません。

そのため、アドホックに料金・商品を登録する方法で実装する必要があります。

# 顧客ごとに、アドホックに料金を作成して処理する

Checkoutセッションを作成する際に料金を登録するには、`line_items.price_data`を利用します。

この中に、料金をAPIから作成する際に設定する値を入れることで、そのセッション用の料金を作ることができます。

```diff_javascript
await stripe.checkout.sessions.create({
  success_url: 'https://example.com/success',
  cancel_url: 'https://example.com/cancel',
  customer_creation: 'if_required',
  line_items: [{
-    price: 'price_xxx',
+    price_data: {
+      currency: 'jpy',
+      product: "prod_xxxx",
+      unit_amount: 1000,
+    },
    quantity: 1
  }],
  mode: 'payment',
})
```

## 作成した料金は、処理完了後にアーカイブされる

アドホックに作成した料金データは、Dashboardでは表示されません。

これは、自動的に料金のアーカイブまで行われるためです。

```bash
$ stripe prices retrieve price_xxxxx
{
  "id": "price_xxxxx",
  "object": "price",
  "active": false, # active=falseなのでアーカイブ済み
```

# アドホックに商品データも作成する

先ほどのサンプルでは、料金に紐づける商品データは事前に作成済みでした。
ですが、商品データについてもアドホックに作成することができます。


```diff_javascript
await stripe.checkout.sessions.create({
  success_url: 'https://example.com/success',
  cancel_url: 'https://example.com/cancel',
  customer_creation: 'if_required',
  line_items: [{
    price_data: {
      currency: 'jpy',
-      product: "prod_xxxx",
+      product_data: {
+        name: "アドホックな料金"
+      },
      unit_amount: 1000,
    },
    quantity: 1
  }],
  mode: 'payment',
})
```

商品についても、自動的にアーカイブされます。
そのため、セッション数が増えることでによってDashboardで商品・料金データの数が増えて探しにくくなることもありません。

# サブスクリプションにも対応

サブスクリプションについても、アドホックに商品・料金を登録して処理できます。

```js
await stripe.checkout.sessions.create({
  success_url: 'https://example.com/success',
  cancel_url: 'https://example.com/cancel',
  line_items: [{
    price_data: {
      currency: 'jpy',
      product_data: {
        name: "アドホックな料金"
      },
      unit_amount: 1000,
      recurring: {
        interval: "month",
      }
    },
    quantity: 1
  }],
  mode: 'subscription',
})
```

# オーダーメイドECやパーソナライズしたサービス提供にお使いください

アドホックな料金登録を利用することで、顧客に応じて料金の変わるオーダーメイド・パーソナライズ商品・サービスの提供がより簡単になります。

自動でアーカイブできるなど、料金・商品の登録APIを利用するよりも便利なケースがありますので、ご活用ください。


# 参考記事

https://docs.stripe.com/api/checkout/sessions/create#create_checkout_session-line_items-price_data
CSSだけでPinterest風レイアウトを作る

# 概要

![layout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67311/b16fcaf3-658e-a7c1-4cfc-858247fd9f0b.png)

* Pinterestっぽいレイアウトを実装する
    * 高さが異なるカードを縦方向に敷き詰める
    * 今回は2列で、左右の高さを不揃いに並べる
* Masonryレイアウトとも呼ばれているらしい
* 参考 : [ピンタレストっぽいMasonryレイアウトをCSSだけで簡易的に実現する \| blog\.ojisan\.io](https://blog.ojisan.io/masonry-style-css/)

# 失敗例

(実行結果が見にくいのでCodePenに移動するか下部の「0.5x」ボタンを押してください)

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

一見実装できているように見えるが、一番最後のハムスターのカードに文章が1文増えると…

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

レイアウトが崩れ、カードボックスとフッターの間に大きく余白ができてしまう。

# 実装例

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

* `card` を `display: inline-block` ではなく `display: block` に変更
* `card` の下部の余白を `margin-bottom` で調整するのではなく、
`card` の外側に配置した  `card-wrapper` の `padding-bottom` で調整する
* カードの並び全体を中央揃えにするため、 `card-box` の外側に `card-box-wrapper` を配置して `display: flex` で調整
* カード列の余白を調整するため、　`card-box` の `column-gap` を調整
AmazonLinux2にAuditdを設定する

Auditdの設定 参考記事
--

https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-linux-track-changes/

https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-monitor-file-system-changes/

https://www.linux.com/topic/desktop/customized-file-monitoring-auditd/

https://qiita.com/Brutus/items/7ec3d06adf6af6ca24b7

https://qiita.com/glostuan/items/8dad6d9b3b5ee123e7cf


インストールしようとすると、既に入っていますといわれます。

```code
[ec2-user@ip-10-0-0-25 ~]$ sudo yum install audit
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                                                                       | 3.7 kB  00:00:00
Package audit-2.8.1-3.amzn2.1.x86_64 already installed and latest version
Nothing to do
[ec2-user@ip-10-0-0-25 ~]$
```

ここにログがあります。
 sudo cat /var/log/audit/audit.log

現在の設定をみます
sudo auditctl -l
```code
[ec2-user@ip-10-0-0-25 ~]$ sudo auditctl -l
No rules
[ec2-user@ip-10-0-0-25 ~]$
```

ルールを書き込みます

sudo vi /etc/audit/rules.d/audit.rules

＞-w /home/ec2-user/test_dir -p rwxa -k test_watch

-w /home/ec2-user/test_dir/ は監視するディレクトリを指定します
（ファイルもOKのようです）

-p rwax は Auditdに監視する権限を与えます 
（r読み取りアクセス w書き込み a属性変更 x実行アクセス です）

-k test_watch 「test_watch」というキーを付けます

auditdを再起動します
```
# sudo service auditd restart
```

ログをそのまま見ると膨大なので
```
 ausearch -k test_watch | aureport -f -i
```
で確認します

CloudWatchLogsの設定
--

EC2インスタンスにIAMロールを設定します

https://recipe.kc-cloud.jp/archives/9709

↑こちらを参考に「/etc/awslogs/awslogs.conf」を編集します。↓

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178985/87e3c816-7e7b-6126-ef6c-aba7f9a1aa08.png" width="50%">

CloudWatchLogsロググループから確認できるようになります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178985/4cdd6366-7f43-3bc0-334d-58a05b879079.png" width="50%">
【パブリッシャー】Google Mapを使用したレポートを作ってみる - 拡張表現 その１

住所一覧などを地図付きレポートとしてブラウザに表示したいなんてことありませんか？
Expression(拡張表現)を利用して作成してみます。
[Sharperlight](https://sharperlight.jp/)のアップリケーションメニューから**パブリッシャー**を起動します。
![Qiita Common - Menu Publisher.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/39414522-0363-e916-c87d-de59bfd01760.png)
[新規]ボタンで新しいレポートを作成します。
**コード**、**グループ**、**タイトル**と**レポートのタイトル**を入力します。
![2022-03-14 Figure 02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/e74b16c5-a538-67db-80f5-71a742058333.png)
[クエリーを編集]ボタンでクエリの作成をします。
#### [フィルター]領域
今回はシステム(Sharperlight)の組み込みオプションの**カスタム定義のデータセット**をテーブルとして利用します。
![2022-03-14 Figure 03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/b39db7cb-268a-8365-7111-18f3a0d3abff.png)
**データセットを定義**では、このようにしてデータを作成します。
:bulb:カスタム定義のデータセットに関しては別の記事として投稿します。
![2022-03-14 Figure 04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/0ec82209-d49e-1873-5184-5c7ca153337a.png)
#### [選択]階層表示領域と[出力]領域
上記のようにカスタムデータを作成すると、[選択]階層表示領域にフィールド名が表示されます。コード、名称、住所を[出力]領域に設定します。
最後に地図を表示するための拡張表現を追加します。
関数一覧から**Google マップ** -> **Google Maps - Street map of address**を選びます。
テンプレートが編集領域に転送されます。
```
"<iframe src='https://maps.google.com/maps?output=embed&q="
  + UrlEncode(  {fullAddress} ) + 
"' width='400' height='300' frameborder=0 ></iframe>"
```
下図のように {fullAddress} の部分を住所フィールドへの参照に置き換えます。
![2022-03-14 Figure 05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/a45ef0bd-4515-e42e-90cf-8dd7788ab8c0.png)
全てを保存し、早速レポートを表示します。（Sharperlightサービスが動いていない場合は、サービスを起動します）
このように地図を配置したレポートが出来上がります。
![2022-03-14 Figure XX.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/265325ca-830f-8b3c-6dd9-37f4684c38a5.png)

:postbox:[Sharperlight](https://sharperlight.jp/)
(Linuxコマンド)findの使い方について

# この記事の内容
- Linux環境におけるfindコマンドについて


# findコマンドとは？
　`find`コマンドとは、ファイルやディレクトリなどを検索し見つけ出すためのコマンドです。オプションもたくさんあるので少しずつでもいいので覚えていきましょう!

# 基本的な使い方
```
$ find 検索場所 [オプション] 検索ファイル名
```
これだけだと少しわかりずらいと思うので、実際に入力したしたコマンドを見ていきましょう。

```
envader@172-19-4-2:~$ find *.go
main.go
main2.go
main3.go
main4.go
```
　上のコマンドは、すべての場所(`*`)から`.go`という拡張子をもったファイル、ディレクトリを検索するとしたものです。`*`は、ワイルドカードと呼ばれる`*`の前に書かれた文字は、どれでも対象にしますよという特殊な文字です。これが基本的な`find`の使い方です。次は、オプションについて見てみましょう。

# よく使うオプション
| オプション | 説明|
|:-:|:-:|
| -name  | ファイル名やディレクトリ名を指定して検索します。大文字と小文字を区別します。大文字と小文字を区別しないものに-inameがあります。  |
| -type  | ファイル、ディレクトリ、シンボリックリンクなどタイプを指定できます  |
| -atime  | ファイルにアクセスした時間を指定して検索ができます  |
| -mtime  | ファイルを更新した時間を指定して検索ができます  |
| -empty  | 空のファイルやディレクトリを検索します  |
| -size | ファイルやディレクトリのサイズを指定できます  |

参考資料:https://envader.plus/course/1/scenario/1016　

# 大文字と小文字を区別して検索する-name
```bash
$ find ./ -name \*.go
main.go
main1.go
# main2.GO 表示されない
# main2.Go 表示されない
```
　 `-name`は、大文字と小文字を区別して検索を行います。そのため、上記の入力では、`.go`のみ表示され、`.GO`は表示されません。また、`-name`は、特殊文字を使う場合は、`/`を使う必要があります。 `-name`に似たコマンドで、 `-iname`があります。これは、 `-name`とは逆で、大文字と小文字を区別しないで表示します。
```bash
$ find ./ -iname \*.go
main.go
main1.gO
main2.GO
```

# ファイル、ディレクトリのタイプを指定できる -type
```bash
$ find *2* -type f
main2.go
main2.py
```
`-type`の後ろに指定するタイプを書きます。
`-f`は、ファイル、`-d`は、ディレクトリ、`-l`は、シンボリックリンクです。

# ファイルにアクセスした時間を指定する-atime
```bash
$ find ./*.go -atime -2
./main2.go
./main.go
```
`-atime`の後にある`-2`は一昨日を表しています。
　今日であったら、0、昨日であったら１と書くことで時間を指定できます。
もし、数字の前に`-`がついていた場合は、その日数以内を意味します。なので、今回の上の実行では、2日以内にアクセスされた拡張子が.goと記されたファイルを検索します。

　また、下のように数字の前`+`がついていた場合は、その日数よりも前にアクセスしていた場合を指します。
この場合は、2日より前にアクセスされた.pyファイルを検索します。
```bash
$ find ./*.py -atime +2
./main2.py
./main3.py
```

# 空のファイルやディレクトリを検索できる-empty
```bash
find ./ -empty
```
`-empty`では、中身がからのファイルやディレクトリを検索できます。

# ファイルやディレクトリのサイズを指定しできる-size
```bash
find ./ -size 1k
./main4.go
./main4.py
./main.py
```
　`-size`は、ファイルやディレクトリのサイズを指定できます。
上の場合の`1k`は、1キロバイト(KB)を指しています。他にも、メガバイト（M）やギガバイト（Ｇ）などがあります。

# まとめ
　今回は、ファイルやディレクトリを探索し見つけ出す`find`コマンドについて学びました。`find`コマンドには、たくさんのオプションがあり、1度に覚えるのは大変だと思います。わからないときは、その都度調べ、徐々に身に着けられるようにしていきましょう！
# 実行環境
オンライン学習サービス[Envader](https://envader.plus/courses)を使いました。
Envaderは、環境構築が不要で簡単にLinux環境が学べるので学習するのにとても便利でした。コースは、
- Linux基礎
- Linux応用
- セキュリティー基礎　などなど

無料で使えて、初心者には難易度の高い環境構築しなくていいのでおすすめです。（一部有料）

[Envaderコース一覧](https://envader.plus/courses)

# 参考資料
【Linuxコマンド】findの使い方について:https://envader.plus/course/1/scenario/1016
python-docxにFastAPIから取得したファイルを読み込ませる

# はじめに
この記事は私がpython-docxをFastAPIから取得したファイルの読み込みを実装するにあたり躓いた点についてです。
この問題についての情報が無いに等しいほど見つからなかったため、備忘録もかねて置いておきます。

FastAPIやpython-docxの詳しい使い方はそれぞれのドキュメントや使い方についての記事を参照してください。

- FastAPIのドキュメント

https://fastapi.tiangolo.com/

- python-docxのドキュメント

https://python-docx.readthedocs.io/en/latest/

## バージョン情報
この記事の環境は以下のバージョンです。

- Python:3.9
- FastAPI:0.65.1
- python-docx:0.8.11

# 突き当たった問題
python-docxのドキュメントにはfile-like-objectに対応していると書かれており、FastAPIのUploadFileから取得できる物もfile-like-objectですが、FastAPIから取得したファイルはバイナリでないとpython-docxに読み込めないという現象が起こりました。

```python
from docx import Document
from fastapi import UploadFile
async def upload(file: UploadFile = File(...)):
    doc = Document(file.file)
```

この読み込み方法では私の環境では以下のようなAttlibuteエラーが発生しました。

```
AttributeError: 'SpooledTemporaryFile' object has no attribute 'seekable'
```
# 解決した方法
この問題はawaitを使用してUploadFileのバイナリを抽出し、BytesIOを利用してDocumentに渡すことで解決しました。
先程のコードは以下のように書き換えることで正常に動作します。

```python
from docx import Document
from fastapi import UploadFile
from io import BytesIO
async def upload(file: UploadFile = File(...)):
    doc = Document(BytesIO(await file.read()))
```
# 参考サイト
問題の解決にあたり以下のサイトの情報を参考にしました。

https://stackoverflow.com/questions/64375466/trying-to-read-a-docx-file-using-fastapi-and-python-docx-library-attributeerror

https://stackoverflow.com/questions/69404426/using-fastapi-uploadfile-with-libraries-that-accept-a-file-like-object

https://stackoverflow.com/questions/60093581/python-docx-attributeerror-bytes-object-has-no-attribute-seek
npmのインストールとvueのビルド実行まで

LaravelとVue.jsで作ったプロジェクトを別サーバに移動したところ動かなくなってしまいました。
Vue.jsで作った画面のビルドについてどうやったっけ？と忘れかけたのでそれも含めてメモしておきます。

# Vue.jsのインストール
以下を参考にインストールしました。

https://qiita.com/minato-naka/items/2d2def4d66ec88dc3ca2

ここでlaravel/uiインストールでてこずったんですが、最終的にはlaravel/frameworkをアンインストール、composer.jsonを初期化してインストールし直して動くようになりました。
(追加したコンポーネントも個別に全てインストールし直し)

:::note
npm installの実行にはyumでnode.jsの最新版を入れる必要があります。
また、npm run watchの実行時にパラメータエラーが発生するので以下により、package.jsからパラメータを削除する必要があります。
:::

https://qiita.com/yutarou/items/e00a05b4d84ed40dc444

# Vue.jsファイルのビルド
開発用のビルドは以下。
```
$ npm run dev
```

リリース用のビルドは以下。
```
$ npm run prod
```

# まとめ
Vue.jsはコードを修正するたびにビルドが必要なので少々厄介だなぁと思う今日この頃。
VSCode起動時に"No view is registered with id: codespaces.explorer"または"No view is registered with id: codespaces.explorerDetails"と表示される。

## 発生した状況

VSCodeを起動すると、VSCodeの右下のトースト下の画像のようなメッセージが表示されて鬱陶しいため、解決策を探した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161276/721374c0-d49d-f140-1ab9-582af6fb524a.png)

## 前提

VSCodeの設定同期には、Githubのアカウントを使用している。

## 対策

基本設定(Ctrl + P -> 設定(UI)を開く)から、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161276/ab0020f9-3038-1742-28ef-226e2c5ec4be.png)

`Coidespaces: Account Provider`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161276/2e72eae7-1982-ed4a-4c2c-daf33eb9e32c.png)

が`Microsoft`だとこのメッセージが発生し、

`GitHub`だとメッセージが発生しなくなる。

**追記(2022/03/31)**
`Microsoft`だけでなく、`Uninitialized`でも表示された。

## 原因

知見がないため、わからない。
特にCodespacesは使用していないため、メッセージが消えれば良しとした。
pyenvを使うけど ~/.pyenv/shims にはPATHを通さないというアプローチ

複数のPythonインタープリタをマシンにインストールするにはpyenvを使うのが一般的です。  
- ~/.pyenv/versions 以下に各バージョンのインタープリタを配置してくれる
- ~/.pyenv/shims に置かれた `python`, `python3`, `python3.10` などといった名前のスクリプトが実際のインタープリタを起動してくれる
- どのインタープリタが選択されるかはpyenvの設定でコントロールされる。（`pyenv global` や `pyenv local` コマンドで制御）
- だから、 ~/.pyenv/shims にPATHを通しておけばよい。この通りに自分でPATH追加してもいいし、 `eval "$(pyenv init --path)"` と書いてもよい。

という立て付けですね。  
ただこの仕組み、1番目のところ以外は微妙というか余計ですよね、というのがいろんなプロジェクトでPython使ってきての所感です。

- **pyenv localはまず使うことがない**。localでインタープリタバージョンを設定するくらいなら、普通は仮想環境を作ります。
- **pyenv globalはストレスフル**。そりゃあそうです。global、マシン全体に影響を及ぼすんだから、「ああっ、あっちの仕事でやった設定変更がこっちのスクリプトの動作に！」ってストレスが必ず生じます。よって、使いません。
- じゃあ、~/.pyenv/shims にPATH通す意味ないじゃん！

素のPythonインタープリタを使うのは結局のところ、**仮想環境を作るときだけ**です。（小物の自分用便利スクリプトを書くときにも、あらかじめ「小物の自分用」仮想環境を作っておいてそれにshebangを張る）  
ならば、`python3.9` コマンドがいつでもPyhton3.9インタープリタを、 `python3.10` コマンドがいつでもPython3.10インタープリタを呼び出してくれさえすれば十分となります。 `python3.10 -m venv` さえいつでも呼べればよい。

じゃあこれでいいじゃんと。（前提： ~/bin にはPATHが通してある。小物の自分用便利スクリプト置き場。）
```
ln -s ~/.pyenv/versions/3.9.10/bin/python3.9 ~/bin/python3.9
ln -s ~/.pyenv/versions/3.10.2/bin/python3.10 ~/bin/python3.10
```

別解としては、aliasコマンドを .zshrc / .bash_profile に書くという手もあります。

```
alias python3.9="$HOME/.pyenv/versions/3.9.10/bin/python3.9"
alias python3.10="$HOME/.pyenv/versions/3.10.2/bin/python3.10"
```

SYMLINK方式とalias方式とでは、仮想環境を作ったときの仮想環境のでき方がちょっとだけ異なります。  
（SYMLINK方式だと仮想環境の python3.10 は ~/bin/python3.10 へのSYMLINKとなり、本物のインタープリタへは2段リンクとなる）

チーム内の環境構築手順書は書きやすい
---
このような独自のやり方をやっても、そうでない人との間で環境構築手順の差異はこれといって生じません。  
環境構築手順書にはただ
```
前提：python3.10 コマンドでPython3.10インタープリタが呼び出せる状態になっていること。
```
と書いておけばよいのです。ふつーのpyenvの使い方をしている人はここで `pyenv global 3.10.2` などと打つだけ、そして自分は何もせずにここを通過するだけですから。
Ubuntu20.04 にインストールしたプリザンターで GoogleWorkspace をIdPとしてSAML認証する

# はじめに
公式ページにSAML認証を設定する記事はあるのですが、（https://pleasanter.org/manual/saml）
Ubuntu等のLinux環境にインストールした場合、証明書の置き方のところでハマったので、記事として残しておきます。

# 前提
- Ubuntu20.04上にプリザンターがインストールされていること。
（インストール方法：https://pleasanter.org/manual/getting-started-pleasanter-ubuntu）
- ドメインがHTTPS化されていること。（Certbotが便利です。）

# 手順
## Google管理コンソールでプリザンターをSAMLアプリとして登録
管理者アカウントでログインし、[Google管理コンソール](https://admin.google.com/)へ移動します。
[Googleのヘルプ記事](https://support.google.com/a/answer/6087519?hl=ja)を参考に、プリザンターをSAMLアプリとして登録します。

## 証明書のアップロード（本題）
Google管理コンソールから証明書をダウンロードし、拇印を確認します。
Ubuntu上で確認したい場合は以下のコマンドから。
```
openssl x509 -sha1 -fingerprint -noout -in 証明書.pem
```
ファイル名を拇印、拡張子を.pfxとし、~/.dotnet/corefx/cryptography/x509stores/my/に証明書をアップロード。
（参考：https://stackoverflow.com/questions/49789841/net-core-x509store-on-linux）
## プリザンターの設定
[公式の記事](https://pleasanter.org/manual/saml)を参考に設定し、プリザンターを再起動します。

## 動作確認
プリザンターにアクセスし、「SSOログイン」ボタンからログインできることを確認します。
LEFT JOINの最深部でWhereを追加する方法

元
~~~sql
(
    D_ACCEPTHEAD
    LEFT JOIN
        D_9145_GENKA_SEISAN ON
        D_ACCEPTHEAD.ACEH_ACCEPTNO = DGS145_JYU_DEN_NO
)
LEFT JOIN
~~~

where句で絞り込みたい対象テーブルを字下げする
~~~sql
(
        D_ACCEPTHEAD
        LEFT JOIN
            D_9145_GENKA_SEISAN ON
            D_ACCEPTHEAD.ACEH_ACCEPTNO = DGS145_JYU_DEN_NO
)
LEFT JOIN
~~~

かっこを追加してくくる
~~~sql
(
    (
        D_ACCEPTHEAD
        LEFT JOIN
            D_9145_GENKA_SEISAN ON
            D_ACCEPTHEAD.ACEH_ACCEPTNO = DGS145_JYU_DEN_NO
    )
)
LEFT JOIN
~~~

くくったエリアを from 句として、select * Where句を追加する
~~~sql
(
    SELECT *
    FROM 
    (
        D_ACCEPTHEAD
        LEFT JOIN
            D_9145_GENKA_SEISAN ON
            D_ACCEPTHEAD.ACEH_ACCEPTNO = DGS145_JYU_DEN_NO
    )
    WHERE
        D_ACCEPTHEAD.ACEH_ACCEPTNO = '1'
)
LEFT JOIN
~~~


追加した select * を内包するカッコの最後に、別名をつける
~~~sql
(
    SELECT *
    FROM 
    (
        D_ACCEPTHEAD
        LEFT JOIN
            D_9145_GENKA_SEISAN ON
            D_ACCEPTHEAD.ACEH_ACCEPTNO = DGS145_JYU_DEN_NO
    )
    WHERE
        D_ACCEPTHEAD.ACEH_ACCEPTNO = '1'
) AS ACH_NOU
LEFT JOIN
~~~

# 別名（AS ACH_NOU）を付ける位置を間違えやすいので、注意！
rails db:migrateしたのにDBに反映されなかった時の話① 

# はじめに

１月〜プログラミングスクールで学習しています。
これから平日は~3/25まで毎日何かしらアウトプットのため投稿を続ける予定です。
今回は rails db:migrateコマンドを実行した際にDBに反映されなかったことについて書きます。
長くなるので2つの記事に分けます。
まずは”NO FILE”というマイグレーションファイルができてしまったことについて書きました。
※Ruby2.6.5の環境を使用し学習しています。


# 事象

rails db:migrateを実行すると下記のようにエラーになりました。
```:ターミナル
% rails db:migrate       
== 20220310073337 CreateDietrecords: migrating ================================
-- create_table(:dietrecords)
   -> 0.0140s
== 20220310073337 CreateDietrecords: migrated (0.0141s) =======================

== 20220312031130 DeviseCreateUsers: migrating ================================
-- create_table(:users)
rails aborted!
StandardError: An error has occurred, all later migrations canceled:
```

どうやらマイグレーションの途中でエラーが出ているようです。
restコマンドなど、色々試してうまくいかないので一度エラー元と思われるusersテーブルを作り直してみましたが上記エラーは変わらず。。。
そこでrails db:migrate:statusでステータスを確認したのが下記です。
状況が悪化していますね。。。
```:ターミナル
% rails db:migrate:status

database: pfc_control_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20220310072650  ********** NO FILE **********
   up     20220310073337  Create dietrecords
  down    20220312031130  Devise create users
```

まずはNO FILEを削除するところから始めます。
touchコマンドでダミーファイルを作成し、中身を記述しておきます。
- touch db/migrate/20220310072650_hoge.rb

```ruby:db/migrate/20220310072650_hoge.rb
class Hoge < ActiveRecord::Migration[6.0]
  def change
  end
end
```

再度ステータス確認し、NO FILEから作成したダミーファイルに変わっていることが確認できました。
```:ターミナル
% rails db:migrate:status                

database: pfc_control_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20220310072650  Hoge
   up     20220310073337  Create dietrecords
  down    20220312031130  Devise create users
```

ダミーファイルを削除したいのでまずはステータスをdownに変更します。
```:ターミナル
% rails db:migrate:down VERSION=20220310072650
== 20220310072650 Hoge: reverting =============================================
== 20220310072650 Hoge: reverted (0.0120s) ====================================
```

これでダミーファイルのステータスが変わりました。
```:ターミナル
% rails db:migrate:status                     

database: pfc_control_development

 Status   Migration ID    Migration Name
--------------------------------------------------
  down    20220310072650  Hoge
   up     20220310073337  Create dietrecords
  down    20220312031130  Devise create users
```

rmコマンドでダミーファイルを削除します。
```:ターミナル
rm db/migrate/db/migrate/20190915065320_hoge.rb
```

これでようやく最初の状態まで戻りました。。。
```:ターミナル
% rails db:migrate:status                           

database: pfc_control_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20220310073337  Create dietrecords
  down    20220312031130  Devise create users
```

長くなるので今日はここまでにします。
明日は最終的にどうやって解決したかを書きます。
それでは:checkered_flag:
MacのターミナルでExcelファイルとbase64のエンコード/デコード変換

Macのターミナルで、Excelファイルをbase64にエンコードしたり、base64をデコードしてExcelファイルを生成する方法を残しておきます。

# Excelファイル → base64
```
base64 -i template.xlsx [-o output.txt]
```
-oオプションを付けない場合は、base64がターミナル上に出力されます。

# base64 → Excelファイル
```
echo "BASE_64_STRING" | base64 --decode > template.xlsx
```
【基礎】JSON  ってスゲェー！！

JSONは、他のフォーマット（特にXML）よりも優れています。

><b>コンパクト
柔軟性がある
編集が容易
変換可能なコードを持つ
独立して動作する
主要なプログラミング言語すべてで使用できる
</b>

JSONの最も大きな利点は、
<b>人間にとっては読みやすく理解しやすい</b>ことであり、
<b>コンピュータにとってはJSONデータの解析やパースが容易である</b>
ことである。

さらに、
このデータ表現形式により、<b>ウェブアプリケーションは複雑な手順を踏むことなく、データの転送や取得を行うことができる</b>。

無料でこれも使える

https://jsononline.net/ja

# JSONの利点
## JSONは、ほぼすべてのウェブブラウザと互換性がある
JSONを使ったアプリケーションを開発する際、開発者はその互換性を気にしますが、JSONはブラウザに合わせて動作する機能を持っています。

## 処理の高速化
SONの構文は驚くほど使いやすく、データの処理も簡単です。より高速にデータを処理することができます。また、遅延なくデータをパースするのに役立ちます。その軽量なフォーマットにより、迅速なレスポンスの実行が容易になります。

## JSONによるデータ共有
動画、画像、その他のファイルなど、データを共有したい場合。その場合、JSONは最良の選択肢であることが証明されます。

なぜなら、JSONのデータは配列の形式で保存されるので、ファイル転送のプロセスが速やかに、かつ十分にスマートになるからです。

これが、ウェブ開発者がこの形式をウェブ開発に使用し、ウェブAPIに最適な形式であると考える理由です。
OData #2 Power BI と SharePoint

# Power BIでODataを使う

https://docs.microsoft.com/ja-jp/power-bi/connect-data/desktop-connect-odata

　前回使用したNorthwindのODataをPower BIで使ってみます。

```text
https://services.odata.org/v2/northwind/northwind.svc/
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/8f673c44-b356-9c19-6e16-b0a4cc0e0757.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/3cc011ed-d839-78d9-3a2b-019b61a63bab.png)

　以下のようなナビゲータが表示され、使用できるテーブルの一覧が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/0bcc1ba5-80b4-fbaf-0b40-dd693e45dd4f.png)

　必要なテーブルにチェックを入れ、データの変換を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/08af8b45-19fb-0039-c871-69f7d4e48d63.png)

　自動的に作成されたリレーションは以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/81eb5987-aa83-64ee-5dc8-4ea65617c16a.png)

　非常に単純な例ですが、使うためには以下のようなリレーションに整理しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/13ffb646-5945-64f4-24ec-c4fcd4bb5533.png)

# SharePoint を ODataフィードとして使う

https://docs.microsoft.com/ja-jp/sharepoint/dev/sp-add-ins/use-odata-query-operations-in-sharepoint-rest-requests

　SharePointのODataをつかうには、サイトのURLを使って以下のような形式にします。

```
https://{site_url}/_api/web
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/c22151ca-ee43-e34c-f8d9-2f8dc3978de3.png)

　あとは、それらしいところを探っていけば、フォルダにたどり着きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/ee11b860-9f45-9aed-8936-ac9351fc47ca.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/a4ac6fab-13df-7624-7689-99310866bb65.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/c8ea5546-3355-e0d8-afd8-f02e7e9af845.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/1839c996-c90f-cc21-1ae4-c539d5b175f4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/3368c6df-1673-6562-edcf-0690745aae56.png)

　SharePointをODataを使って使用するには、情報がまったく足りていないもので、また何か発見がありましたら追記します。
【解決メモ】pip installのアクセス権限エラーで--userつけても直らん！！

**pip installのアクセス権限エラーで--userつけても直らない問題を解決**

**１．エラー内容**
Windows PowerShellにおいて、`pip install ~` としたとき、`Could not install packages due to an OSError: [WinError 5] アクセスが拒否されました。「--user」をつけてください。`というエラーはよくある質問であるが、「--user」をつけても直らなかった。

**２．解決法**
--userをつけてもエラーが出ていた時は、jupyter notebookを開いているPowerShellが別に開いていた。存在していた。そこで、２つのPowerShellを両方とも閉じ、新たにPowerShellを開き、pip installを行った結果、--userをつけなくてもエラーが出ずに、インストールが完了した。
これが、直接の原因かは分からないが、一応メモしておく。


**３．ご意見・ご感想をお待ちしております**
当方、未熟なプログラマーのため、よりよいコード等ありましたら教えていただけると幸いです。
皆様のメッセージをお待ちしております。
Unnecessary call to ‘package-initialize’ in init file を消す

emacs を起動したら下記のように言われる

```
Warning (package): Unnecessary call to ‘package-initialize’ in init file [2 times]
```

`~/.emacs.d/early-init.el` に

```
(setq warning-suppress-log-types '((package reinitialization)))
```

などと書くと消える。
railsにwebpackerを導入する方法

railsにwebpackerがない場合、導入する方法を紹介します。

※　注意

Rails7.0.0からwebpackerがなくなったので無理に導入するとエラーの元となります。

なので一番良いのはバージョンを下げてアプリを作成することです。

先にバージョンのインストールの説明を載せておきます。

https://qiita.com/ibarakishiminn/items/84838c810e3ddc2c4b9e

バージョンを指定したアプリ作成の例

```terminal:terminal
rails _6.X.X_ new 　sampleapp
```

webpackerをインストールするにはyarnを先にインストールしておく必要があります。

brewよりnpmでyarnをインストールした方がいいそうです。

https://qiita.com/suisui654/items/1b89446e03991c7c2c3d

https://qiita.com/NaokiIshimura/items/8203f74f8dfd5f6b87a0

まず最初にrailsのアプリを作成した状態にしておきます。

railsのアプリが作成できたら

rails の　gemfile に　以下を入力します。

```terminal:gemfile
gem 'webpacker', '~> 4.0'
```

次にターミナルでアプリファイルの場所でbundle installと入力します、

```terminal:terminal
bundle install
```

最後にターミナルでrails webpacker:installと入力します。

```terminal:terminal
rails webpacker:install
```

これでrailsにwebpackerが導入されました。
laravel8 で 並列 post 通信

並列処理。それは音速の処理。

・郵便番号から座標取得
・最寄り駅取得

の同時処理が可能になる。

下準備

```hoge.php

use Illuminate\Support\Facades\Http;
use Illuminate\Http\Client\Pool;

```

処理

```hoge.php

//        $postal = 1378088;
$postal = 4530013;

//        http://geoapi.heartrails.com/api.html#nearest heart rails api
$url = "http://geoapi.heartrails.com/api/xml?method=getStations&postal=".$postal;
$response = Http::get($url);

$responses = Http::pool(fn (Pool $pool) => [
    $pool->get('http://geoapi.heartrails.com/api/json', [
        'method' => 'searchByPostal',
        'postal' => $postal
    ]),
    $pool->get('http://geoapi.heartrails.com/api/json', [
        'method' => 'getStations',
        'postal' => $postal
    ])
]);


$res = [
    'searchByPostal' => [],
    'getStations' => [],
];

if($responses[0]->ok()){
    if(!empty($responses[0]->json()['response']['location'])){
        $res['searchByPostal'] = $responses[0]->json()['response']['location'][0];
    }
}


if($responses[1]->ok()){
    if(!empty($responses[1]->json()['response']['station'])) {
        $res['getStations'] = $responses[1]->json()['response']['station'][0];
    }
}



```

ざっと計測したけど、2つの処理を1つのスピードで処理できた。
Ansibleの個人的メモ (Terraform + Ansible)

# IaCツールの使い分け
ひとくちにIaCツールといっても、得意分野が異なるので
- プロビジョニングツール
- 構成管理ツール

### プロビジョニングツール
ネットワーク作成やサーバー配置などの***インフラの大まかな区分***の作成・変更が得意。

プロビジョニングツールの例
- CloudFormation
- Terraform

### 構成管理ツール
ミドルウェアのインストールやLinuxサーバの設定などの***インフラの細かな設定***の作成・変更が得意。

構成管理ツールの例
- Chef
- Ansible


(仮公開。後ほど追記)
（初心者）（VPSのMariaDB環境構築）パスワードが間違いないのに、ターミナルから、またはphpMyAdminからログインできない

# 環境
CentOS 7.9
MariaDB 5.5
phpMyAdmin 5.1

# 状況
MariaDBをインストールし、rootにパスワードを設定した。パスワードは間違いないのにターミナルからも、phpMyAdminからもログインできない。

# 解決
MariaDBのrootに設定したパスワードに、使用禁止文字が含まれていました。私の環境では、使用禁止文字でもパスワードの登録が通ってしまったため、ログインできずに行き詰まりました。
【Git】よく使うコマンド

# はじめに
gitのよく使うコマンドを備忘録として記述します。

# git add, commit の取り消し
### git add の取り消し

```:全てのファイルのgit addを取り消し
git reset HEAD
```

```:特定のファイルのgit addを取り消し
git reset HEAD <ファイルのパス名>
```

### git commitの取り消し

```
git reset --soft HEAD^
```


# git stash でよく使うコマンド
### 未追跡の特定のファイルを一時退避して、メッセージをつける方法

```
git stash push -m "メッセージ" -- <ファイルのパス名>
```

### git stashした内容を見たい時

```:stashした一覧を確認する
git stash list
```

```:特定のstashと現在のワーキングディレクトリとの差分を確認する
git diff HEAD..stash@{0} // stashのcommit番号は git stash list で確認可能
```

### git stashを元に戻したい時

```:直前のstashした内容をもとに戻す時
git stash apply
```


```:特定のstashした内容をもとに戻す時
git stash apply stash@{1}
```

# git revert
### git commit を打ち消すcommitをしたいとき

```
git revert <コミットのハッシュ値> // コミットのハッシュ値は、git logで確認できる
```

# 参考
- [git addを取り消す](https://qiita.com/yukure/items/89562e5eb1d03995dc5b)
- [[Git]コミットの取り消し、打ち消し、上書き](https://qiita.com/shuntaro_tamura/items/06281261d893acf049ed)
- [[Git] ファイル単位でstashする](https://qiita.com/yukitaka13-1110/items/935bfa233c6e024f82dc)


# おわりに
ほかにもこれはよく使うでしょ、みたいなものがあればコメントいただけますと幸いです。
【MySQL】AUTO_INCREMENTの値はロールバック後も戻らない

ロールバック処理の検証中にのidカラムの番号が飛んでいたので、調べたらタイトルの事実が判明しました。

忘れないようにまとめておきます。

# なぜ戻らないのか
MySQLの仕様でした。SQL全般の仕様なのかは分かりません。
[公式サイト](https://dev.mysql.com/doc/refman/5.6/ja/innodb-auto-increment-configurable.html)に説明があります。
>すべてのロックモード (0、1、および 2) では、自動インクリメント値を生成したトランザクションがロールバックされると、これらの自動インクリメント値が「失われます」。「INSERT のような」ステートメントが完了したかどうか、およびそれを含むトランザクションがロールバックされたかどうかに関係なく、自動インクリメントカラムの値は一度生成されたら、ロールバックできません。このような失われた値は再使用されません。したがって、テーブルの AUTO_INCREMENT カラムに格納されている値にはギャップが存在する可能性があります。

簡単にまとめると、実データ生成の有無にかかわらず下記の仕様が適用されます。
- AUTO_INCREMENTの値は一度生成されたら戻らない
- AUTO_INCREMENTの値は再使用されない
- AUTO_INCREMENTが設定されたカラムは連番にならない可能性がある

# 検証
テスト用のテーブルとデータを作成します。
テーブル・データの作成は[公式サイト](https://dev.mysql.com/doc/refman/5.6/ja/example-auto-increment.html)に掲載されているSQLを利用しました。

## テーブル作成
```sql
CREATE TABLE animals (
	id MEDIUMINT NOT NULL AUTO_INCREMENT,
	name CHAR(30) NOT NULL,
	PRIMARY KEY (id)
);
```
```sql
mysql> SHOW columns FROM animals;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | mediumint(9) | NO   | PRI | NULL    | auto_increment |
| name  | char(30)     | NO   |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
```

## テストデータ作成
```sql
INSERT INTO animals (name)
		VALUES('dog'), ('cat'), ('penguin'), ('lax'), ('whale'), ('ostrich');
```
```sql
mysql> SELECT * FROM animals;
+----+---------+
| id | name    |
+----+---------+
|  1 | dog     |
|  2 | cat     |
|  3 | penguin |
|  4 | lax     |
|  5 | whale   |
|  6 | ostrich |
+----+---------+
6 rows in set (0.00 sec)
```

## ロールバック実行
データを作成後、ロールバックで処理を戻しています。
実データは作成されません。
```sql
START TRANSACTION;
INSERT INTO animals (name)
		VALUES('rabbit');
ROLLBACK;
```
次にロールバックなしで実データを作成します。
```sql
INSERT INTO animals (name) VALUES('rabbit');
```

データを確認すると、AUTO_INCREMENTが設定されたidカラムでは``7``が飛ばされ``8``が登録されています。
ロールバック後もAUTO_INCREMENTの値は戻らないことが確認できました。
```sql
mysql> SELECT * FROM animals;
+----+---------+
| id | name    |
+----+---------+
|  1 | dog     |
|  2 | cat     |
|  3 | penguin |
|  4 | lax     |
|  5 | whale   |
|  6 | ostrich |
|  8 | rabbit  |
+----+---------+
7 rows in set (0.00 sec)
```

# まとめ
AUTO_INCREMENTで連番は保証できない(-_-;)

# 参考記事
- [メモ: DBでrollbackしてもauto_incrementが戻らない理由](https://qiita.com/ukoasis/items/75039e53b5cacdc12cf4)
- [DBの自動連番がロールバックしても戻らない理由](https://cs.hatenablog.jp/entry/2014/03/14/103358)

# 採用PR
弊社で一緒に働く仲間を募集しています。
全てのオタクを幸せにしたい方、是非ご覧ください！

https://hrmos.co/pages/vivion/jobs/0000191
【MySQL】同一トランザクションの実行結果は次の処理にも反映される

1つのトランザクションの中でINSERT、SELECTを連続で実行したところ、先にINSERTしたCOMMITされていないレコードも取得できました。

なぜ取得できるのか分からなかったので調査・検証してみました。

# 検証
## SQLを実行
トランザクション前のテーブルの状態です。
```sql
mysql> SELECT * FROM animals;
+----+------+
| id | name |
+----+------+
|  1 | dog  |
+----+------+
1 row in set (0.00 sec)
```

### トランザクション開始
トランザクション分離レベルはデフォルトの``REPEATABLE-READ``です。
```sql
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
```

### INSERT実行
```sql
mysql> INSERT INTO animals (name) VALUES ('cat');
Query OK, 1 row affected (0.00 sec)
```

### SELECT実行
まだCOMMITされていませんが、先ほどINSERTした``cat``が取得できます。
```sql
mysql> SELECT * FROM animals;
+----+------+
| id | name |
+----+------+
|  1 | dog  |
|  2 | cat  |
+----+------+
2 rows in set (0.00 sec)
```

## トランザクション分離レベルを変更して実行
他のトランザクション分離レベルに変更して検証しましたが、結果は同じでした。
- READ COMMITTED
- READ UNCOMMITTED
- SERIALIZABLE

### トランザクション分離レベルの変更方法

現在のトランザクション分離レベルを確認します。
[MySQL トランザクション分離レベルを確認する方法](https://marock.tokyo/2021/07/13/mysql-%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B6%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E5%88%86%E9%9B%A2%E3%83%AC%E3%83%99%E3%83%AB%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/)

```sql
-- 8系はSELECT @@transaction_isolation;
mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set, 1 warning (0.00 sec)
```

トランザクション分離レベルを変更します。グローバルではなくセッションのみ適用します。
[MySQL公式マニュアル: SET TRANSACTION 構文](https://dev.mysql.com/doc/refman/5.6/ja/set-transaction.html)
```sql
-- READ COMMITTEDに変更
mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
Query OK, 0 rows affected (0.01 sec)
```

# まとめ
調べても根拠となる資料は見つかりませんでしたが、とあるサイトに同様の質問が投稿されていました。
[【DB】同じトランザクション内でupdateとselectをしたときの結果値](https://oshiete.goo.ne.jp/qa/9803035.html)

>トランザクションというのはそういうものだからとしかいいようがないかと。
トランザクション内でupdateしたものが一時的に反映されないなら
updateされたことを前提に行うその後の処理が無意味になりますよね

確かに。分離レベル以前の問題でした。

ついでにトランザクション分離レベルについても調べました。こちらの記事が検証手順も詳細で分かりやすかったです。
[トランザクション分離レベルについてのまとめ](https://qiita.com/song_ss/items/38e514b05e9dabae3bdb)

# 採用PR
弊社で一緒に働く仲間を募集しています。
全てのオタクを幸せにしたい方、是非ご覧ください！

https://hrmos.co/pages/vivion/jobs/0000191
git pull origin <current branch> のエイリアスを作る

現在のブランチのみを pull したい場合、毎回

```bash
git pull origin 現在のブランチ名
```

と入力するのが面倒だった。

現在のブランチ名は `git rev-parse --abbrev-ref HEAD` で取得できるが、これを単純にエイリアスに登録しても上手く動かない。

```bash:エイリアス登録・NG
git config --global alias.pullcurrent 'pull origin $(git rev-parse --abbrev-ref HEAD)'
```

以下のように、先頭に `!git` を指定したらちゃんと動いてくれた。

```bash:エイリアス登録・OK
git config --global alias.pullcurrent '!git pull origin $(git rev-parse --abbrev-ref HEAD)'
```

```bash:実行
git pullcurrent
```

## 参考

- [How can you git pull only the current branch? | stackoverflow.com](https://stackoverflow.com/questions/6052005/how-can-you-git-pull-only-the-current-branch)
- [Git の基本 - Git エイリアス | git-scm.com](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E5%9F%BA%E6%9C%AC-Git-%E3%82%A8%E3%82%A4%E3%83%AA%E3%82%A2%E3%82%B9)
FreeTypeをOpenGLで使うときに困ったこと

GLEW、GLM、FreeTypeなどを使って、画面上に日本語を表示させる処理を作っているときに、自分が詰まったことを、記録しておきます。
なお、僕は主に以下のサイトを参考にしながら処理を作成しました。

https://learnopengl.com/In-Practice/Text-Rendering

https://blendgimper.hatenablog.jp/entry/2016/01/01/074615

https://tnzk.hatenadiary.org/entry/20081005/1223208785


## そもそも英文字が表示されない
"abc"みたいな簡単な英文字が画面に表示されない場合、とりあえず以下のことができているか、チェックしてみてください。

- __glTexImage2D__ 関数でformatとinternalformatを __GL_RED__ にしたか？
- vertex Shaderで、gl_Positionに view projectionもtransfrom matrixなどをかけずに、そのまま頂点座標をわたしたとき、描画されるか？
(描画される場合、view projectionやtransform matrixが間違っている。Uniformを指定する前に、glUseProgram呼び出してる？
描画されない場合、Vertex Arrayなどのほかのところが間違っている。)

2個目のやつで言っていたのは、以下のようなvetex shaderでとりあえず文字列が描画されるか調べてみよ、ということ。
```glsl:Vertex.vert
#version 330 core

layout(location = 0) in vec2 inPosition;
layout(location = 1) in vec2 inTexCoord;

out vec2 fragTexCoord;

void main()
{
	vec4 pos = vec4(inPosition, 0.0, 1.0);
	gl_Position = pos;
	fragTexCoord = inTexCoord;
}
```



## 日本語が思ったように表示されない(文字化けする)場合
以下のことを試してみてください。

- true typeのフォントが本当に日本語対応しているか？(SDL TTFで日本語表示できたからと言って、Free Typeでも同じようにやろうと思ったら、日本語が表示できませんでした。なぜかわからない！！)
僕は**Arial Unicode MS**でうまく表示できました。
記事執筆現在では、以下のサイトでダウンロードできます。

https://www.moedict.tw/fonts/truetype/arial/

- 	**FT_Select_Charmap(mFontFace, ft_encoding_unicode);** をコード中に記述してみたか？
- 	ソースコードのエンコーディングが**utf-8**か？
- 	**FT_Get_Char_Index**に渡す文字は**char16_t**か？

日本語文字列を読み込むイメージとしては以下のような感じです。

```cpp
	struct TexChar {
		GLuint texID;
		glm::ivec2 Size;
		glm::ivec2 Bearing;
		unsigned int Advance;
	};
	std::vector<TexChar> mJapanTexVec;
///////////////////////////////////////////

const char16_t str[] = u"あいうえお"; // 小文字のuを忘れない!!!
for (int i = 0; str[i] != '\0'; i++) {
			if (FT_Load_Glyph(mFontFace, FT_Get_Char_Index(mFontFace, str[i]), FT_LOAD_RENDER)) {
				std::cout << "ERROR::FREETYTPE: Failed to load Glyph" << std::endl;
				exit(-1);
			}
			GLuint tex;
			glGenTextures(1, &tex);
			glActiveTexture(GL_TEXTURE);
			glBindTexture(GL_TEXTURE_2D, tex);
			glPixelStorei(GL_UNPACK_ALIGNMENT, 1);


			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            // ↓↓↓ GL_REDにする ↓↓↓
			glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, mFontFace->glyph->bitmap.width, mFontFace->glyph->bitmap.rows,
				0, GL_RED, GL_UNSIGNED_BYTE, mFontFace->glyph->bitmap.buffer); 
			mFontWidth = mFontFace->glyph->bitmap.width;
			mFontHeight = mFontFace->glyph->bitmap.rows;

			TexChar	 tc = {
				tex,
				glm::ivec2(mFontFace->glyph->bitmap.width, mFontFace->glyph->bitmap.rows),
				glm::ivec2(mFontFace->glyph->bitmap_left, mFontFace->glyph->bitmap_top),
				mFontFace->glyph->advance.x
			};

			glGenerateMipmap(GL_TEXTURE_2D);
			glBindTexture(tex, 0);		// unbind

			mJapanTexVec.push_back(tc);
		}
```

文字列を描画する処理は、https://learnopengl.com/In-Practice/Text-Rendering のとおりに作成しました。
Heart rails 位置情報取得 APIをlaravelで使う

http://geoapi.heartrails.com/api.html#postal

郵便番号から最寄り駅が現在地を取得できるサービス。
まずは、POST、GET通信をするためにヘッダに以下を読み込む
```
use Illuminate\Support\Facades\Http;
```


```

//郵便番号から住所を
//都道府県・最寄り駅を取得

$postal = 3790111;

$response = Http::get('http://geoapi.heartrails.com/api/json', [
    'method' => 'searchByPostal',
    'postal' => $postal
]);

$json = $response->json();
pr($json['response']['location'][0]['prefecture']);//都道府県名
pr($json['response']['location'][0]['city']);//町名

$response = Http::get('http://geoapi.heartrails.com/api/json', [
    'method' => 'getStations',
    'postal' => $postal
]);

$json = $response->json();

pr($json['response']['station'][0]['name']);//最寄り駅の名前
pr($json['response']['station'][0]['line']);//最寄り駅が何線か

pr($json['response']['station'][0]['y']);//最寄り駅の y 軸
pr($json['response']['station'][0]['x']);//最寄り駅の x 軸

```

以上
windowsでフォルダをコピーするコマンド

(macos含む)unix系で以下のコマンドに相当することをWindowsでやりたい
```bash
cp -r [src_dir] [dest_dir]/

# [dest_dir]/[src_dir] が上書き作成される
```

Windowsの場合

```cmd
xcopy [src_dir] [dest_dir]\[src_dir] /E /C /Y /I /H /K /R
```

面倒くさすぎやろ、、、
TypeScript: Mapped Typesの中身を言語化してみる① [アウトプット全くしてこなかったのでアウトプットする015]

Mapped Types言語化するのが勉強になりそうだとふと感じたのでアウトプットします。

## Partial

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660329/b013a84c-a34a-d80a-d0c8-613125ef179f.png)

```ts: Partial.d.ts
type Partial<T> = {
    [P in keyof T]?: T[P];
};
```

ジェネリクスで型Tを受け取り、`in keyof`でTのkeyをプロパティPに渡しています。
また全てのプロパティはoptional型となります。。

## Required

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660329/8689830c-02e2-1b83-bf33-91cd823615c9.png)


```ts: Required.d.ts
type Required<T> = {
    [P in keyof T]-?: T[P];
};
```

ジェネリクスで型Tを受け取り、`in keyof`でTのkeyをプロパティPに渡しています。
ここは同じ。だけど`[P in keyof T]-?`の`-?`の部分でoptional型をなくして必須プロパティにしています。
`-?`は使ったことがないので自分の引き出しに増えて嬉しい。リバースエンジニアリングをする恩恵です。

## Readonly

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660329/7a57d605-1618-d6ff-8aa2-0209a25286cf.png)

```ts: Readonly.d.ts
type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};
```

ジェネリクスで型Tを受け取り、`in keyof`でTのkeyをプロパティPに渡しています。
全てのプロパティに対して読み取り専用のreadonly修飾子をつけています。

## Pick

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660329/cb011791-6304-46c8-0b9f-5595d25d05f6.png)


```ts: Pick.d.ts
type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};
```

Pickには2つのジェネリクスを渡します。
１つ目は型、2つ目は1つ目のジェネリクスに渡した型のサブタイプのプロパティ
`[P in K]`ここの部分のKには `"hoge" | "fuga"`のようなプロパティ名が入ってくるのでそれを`K extends keyof T`で行っています。
また`T[P]`で絶対に型情報が欲しいのですが、それは`K extends keyof T`で担保されています。

## Record

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660329/0138cc1d-1927-d4d5-8910-18e5d8880362.png)

```ts: Record.d.ts
type Record<K extends keyof any, T> = {
    [P in K]: T;
};
```

1つ目のジェネリクスであるKにはどんなプロパティでも渡せます(ただしユニオン型で)。Tには型情報を渡します(こちらも複数の場合はユニオン型で)。
全てのプロパティに対して同じ型情報を渡すというものです。

https://typescriptbook.jp/reference/values-types-variables/union

## Exclude,Extract

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660329/3ac4613d-fda2-f672-6511-7cbca806b193.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660329/c16391a8-2cc0-1741-8760-839f3840d8b3.png)


```ts: ExcludeAndExtract.d.ts
type Exclude<T, U> = T extends U ? never : T;
type Extract<T, U> = T extends U ? T : never;
```

この2つの原理はほぼ同じなので合わせて言語化します。
まず両方ともジェネリクスに2つ渡します。
1つ目の方には型を渡します。2つ目の方にも型を渡していて、
Excludeは`Tの型がUのサブタイプであればnever`を返す
逆にExtractの方は`Tの型がUのサブタイプであればT`を返す
となっています。

関連記事

https://qiita.com/cawauchi/items/3b929a7dc9337acf4d30
水漏れ検知

リヤドソリューションの漏水検知会社は、保証付きで割れることはありません。
 水漏れの検出は、ひび割れのないソリューションですAndalus Companyは、水漏れの問題に対する最良のソリューションを提供します。保証付きの最新の電子機器で水漏れを検出し、問題を最短時間で制限する高度な技術と正確な機器のチーム。そして、小さなエリアでは、最大35％の割引があり、修理時に無料で検出できます。


 高い水道料金を解決します。
高額な水道料金を解決するときは、地上と上部の水タンクの漏れを検出するだけでなく、家のすべての送水管をチェックして、水漏れがないことを確認する必要があります。また、節水ツールを設置する必要があります。サウジアラビア王国の水省によって推奨されています。

 水の消費量を抑える必要があります。これは、すべての市民の高額な水道料金の解決策です。
法案が高額の場合は、高水法案に反対することを躊躇しないでください。
高水法案に反対するために、報告書承認済みの苦情処理フォームを水道会社に提出してください。
水道料金が高い場合の水漏れ検知で、家を水漏れから守ります。
https://www.alandlos.net/%d9%83%d8%b4%d9%81-%d8%aa%d8%b3%d8%b1%d8%a8%d8%a7%d8%aa-%d8%a7%d9%84%d9%85%d9%8a%d8%a7%d9%87/
一覧表示を最新の10件を表示する方法

# users/index.html.erbの一覧表示を最新10件にするコード

```users_controller.eb
def index
    @resolutions = Resolution.includes(:user).order('created_at DESC').limit(10)
    @articles = Article.includes(:user).order('created_at DESC').limit(10)  
end
```
## 解説
- `order('created_at DESC')`
　一覧表示を最新から表示になります
- `limit(10)`
 表示10件までになります。