OmniAICreator/Qiita-1.07M huggingface dataset:
[PHP] TraitのUnitテスト

PHPの`trait`のユニットテストを書く方法です。

## public関数
以下のような`trait`の`public`な関数を考えます。

```php
<?php

trait SomeTrait
{
    public function greet(): string
    {
        return 'hello';
    }
}
```

`trait`を取り込んだテスト用のクラスを作ることでテストができます。

```php
class TestTraitClass
{
    use SomeTrait;
}

-----

// チェック
$SUT = new TestTraitClass();
self::assertEquals('hello', $SUT->greeet());
```

もしくは、無名クラスでもOK。

```php
$SUT = new class() { use SomeTrait; };
self::assertEquals('hello', $SUT->greeet());
```

## protected関数
以下のように、テストしたいメソッドが`protected`な関数のときは一工夫が必要です。

```php
<?php

trait SomeTrait
{
    protected function protectedGreet(): string
    {
        return 'hello';
    }
}
```


やることとしては、`trait`を取り込んだテスト用のクラスを作る時に、`trait`のメソッドを`public`でオーバーライドします。

皆れない構文ですが、`trait`を`use`するときに`{}`で囲うことで、`trait`のメソッドに別名をつけることができます。
あとは、テストしたいメソッドと同名のメソッドを`public`で定義し、別名をつけた`protected`な`trait`のメソッドに処理を委譲すればOKです。

```php
class TestTraitClass
{
    use SomeTrait {
        protectedGreet as protected traitMethod;
    };

    public function protectedGreet(): string
    {
        return $this->traitMethod();
    }
}
```


# 終わりに
`protected`関数をテストしたくなること自体どうなの？って気持ちはあるけど、知ってて損はないかも。
ラズパイ4とcodamaの設定に苦労したIoT初心者の話

# 概要
IoT初心者がcodamaを使って遊ぼうとしたら、色々つまずいて苦労した話
エラー内容に絞って以下に残します。世界平和に役立てば光栄です。

# 参考にすべきサイト
・codamaのオフィシャル
https://codama.ux-xu.com/
・ロボスタの紹介ページ
https://robotstart.info/2018/12/28/cidama-dev-01.html

# 前提
・使用機材は、RaspberryPi4(Model B Rev 1.4)
・Raspbianのバージョン：10.10

# 第一関門「ウェイク・アップ・ワードの録音」の勘違い
全体を通して、ジャンパーピンの抜き差しのタイミングが重要。
ロボスタのページを参考に、逐一確認すること。
※ロボスタのページは公式より写真が多くわかりやすいが、ロボスタばかり見てると、
　公式掲載のコマンドを打ち忘れるという事象が発生するので、両方見比べることが重要w

### 公式の「1. PCとUSB接続するマイクとして使用する場合」にて実施
録音の際、以下の場面で、USB接続を選んでしまい、
ファームウェアビルドが永遠にできずに困った。
(注記はあるが、初心者ゆえに読み違えた・・・)
「1. PCとUSB接続するマイクとして使用する場合」は「I2C」が正解
![57433079-7bc72e00-7272-11e9-851b-572ccacf01ec.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1779723/7e417476-4162-30ad-1590-f237b64e0669.png)

# 第二関門「ウェイク・アップ・ワードの動作確認」
ウェイクワードの録音が成功し、binファイルをsshでラズパイのcodamaフォルダに保存。
いざ動作確認をすべく
①`$ while true; do sleep 0.2s; codama_i2c KEYWORDDETECT ;done`
を叩くと、
"rdwr ioctl error -1: Remote I/O error"
の無限地獄。認識されていないのでは？という疑問から
②'$ sudo i2cdetect -y 1'
を叩くと、懸念どおり何も表示されない。→全てが「--」表示
ジャンパーピンを刺して、①②を改めて実施すると
①　Remote I/O errorが出ずに、「KEYWORDDETECT:0」が返ってくること
　※ジャンパーピンありなので、ウェイクワードにはもちろん反映しない。
②　i2cdetect　が正しく反映されること
などから、もう一度ジャンパーピンの有無を詳細に確認のうえ、
公式とロボスタのページを見比べて、再度設定をやり直した結果、上記エラーは解消。
(具体的にどこを間違えたかは不明です。すみません)

# 第三関門「gpioの検知」
##①そもそも公式のコマンドが間違えている
　　誤）`$while true; do sleep 0.2s: gpio -g read 27 ;done`
公式の案内どおりに上記コマンドを入力すると、以下のエラーがエンドレスに・・・
" sleep: 無効なオプション -- 'g' "
" Try 'sleep --help' for more information. ”
かなりの時間を溶かした結果、まさかの公式コマンドが間違えていることに気付く
以下コマンドに修正し、無限エラーからは脱出
　　正）`$ while true; do sleep 0.2s; gpio -g read 27 ;done`
※ 0.2sの次は「：」ではなく「；」が正解

##②WiringPiというライブラリが古かった
無限エラーは解消したが、返ってきた値が「1 1 1 1...」
(本当は「0 0 0 0 0...」が通常。ウェイクワードに反応したときだけ「１」が正解)
gpio27がずっとhighなのか？
gpio27をどこかでいじってしまい初期値がhighになったのか？
などと意味不明な検討を重ねた結果、
`$ gpio readall`
を打つと以下エラーになることに気付く
“Oops - unable to determine board type... model: 17"
上記エラーを手がかりに、以下リンクに辿り着く
http://wiringpi.com/wiringpi-updated-to-2-52-for-the-raspberry-pi-4b/
※リンクの細かい内容は無視して、以下２つを実行すれば最新版にupdateできます
`$ wget https://project-downloads.drogon.net/wiringpi-latest.deb`
`$ sudo dpkg -i wiringpi-latest.deb`

`$ gpio readall`
で一覧表が表示されて喜ぶ
`$ while true; do sleep 0.2s; gpio -g read 27 ;done`
で「０　０　０」が続き、ウェイクワードに反応して「１」に変わるのを確認して歓喜。

初期設定の苦労話はここまで！
[Swift]カスタムrawタイプの列挙型

※この記事は[Swift by Sundell](https://www.swiftbysundell.com/tips/enums-with-custom-raw-types/)の内容を日本語に翻訳したものです。

# Swift列挙型はカスタムなRaw型をもてる

Swift列挙型は、*Raw値*（文字列や整数など）の完全なリストを作成するために非常に一般的に使用され、タイプセーフ(正しく型付けされたプログラムは不正な動作をしない)な方法で処理できます。たとえば、ファイル拡張子に基づいた形式のリストを含む`VideoFormat`列挙型を定義する方法は次のとおりです。

```.swift
enum VideoFormat: String {
    case mp4
    case webM = "webm"
    case ogg
}
```

上記のような*Raw値*ベースの列挙型を宣言すると、コンパイラは自動的にそれを`RawRepresentable`プロトコルに準拠させます。これにより、`init？（rawValue :)`イニシャライザや`rawValue`プロパティなどのAPIにアクセスできるようになります。列挙型のインスタンスとの間で*Raw値*を簡単に変換できるようにします。

この種の機能では、最初は列挙型の*Rawタイプ*を`String`のような`built-in(組み込み)`型にする必要があるように見えるかもしれませんが、実際には、両方が`Equatable`に準拠し、文字列または数値リテラルのいずれかを使用して表現される限り、完全にカスタムの型でも機能します。

例として、次の`Path`型を使用して、より強く型付けされた方法でファイルシステムパスをモデル化するアプリで作業しているとします（常に*Raw*文字列を渡すのと比較して）。

```.swift
struct Path: Equatable {
    var string: String
}
```

`Path`ベースの*Raw値*で列挙型を定義できたら、すばらしいと思いませんか？たとえば、次のように、特定のファイルシステム操作のターゲットの完全なリストを指定するには、次のようにします。

```.swift
enum Target: Path {
    case content
    case resources
    case images = "resources/images"
}
```

すばらしいことに、上記を可能にするために必要なのは、`Path型`を`ExpressibleByStringLiteral`に準拠させることだけです。残りはコンパイラーが処理します。

```.swift
extension Path: ExpressibleByStringLiteral {
    init(stringLiteral: String) {
        string = stringLiteral
    }
}
```

列挙型が完全にカスタムの*Raw*型を持つことができるという事実は、Swiftのコア機能の多くが独自の型システムを使用して実装されていることのさらに別の例です。これにより、カスタム型が組み込み型とまったく同じように動作することが可能になります。


### 元の記事

[Enums with custom raw types](https://www.swiftbysundell.com/tips/inferred-generic-type-constraints/) Swift by Sundell
splunkbase上のCommunity Apps達との付き合い方

はじめに
----
- splunkはなんと言っても[communityの力](https://splunkbase.splunk.com/)が頼もしいです
- communityによってみんなでデータのパーサーやダッシュボードを共有しあっています
- でもappsって誰が作っていてどこまでサポートしてくれるの？って不安もありますよね？
- そこで筆者体験談に基づくappsとのうまい付き合い方をまとめました

Appsの種別
---
- AppsとAdd-on
![スクリーンショット 2021-09-03 14.44.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185759/7b9f75f7-03fd-5235-f21b-03b2a4c74fc1.png)


- パーサーとダッシュボードだけではない。ユーティリティーツールもある。
![スクリーンショット 2021-09-03 14.44.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185759/64ee8f83-a258-0a91-2a81-8cc80390be58.png)

開発者及びサポートレベルの見分け方
---
### 1.Appsの開発者って誰？の確認方法
    
- このアイコンの位置をチェックし、どこの団体が作っているのか確認する
![スクリーンショット 2021-09-03 14.52.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185759/a8edda5c-7b2b-a37e-7ace-dcae279104fa.png)

- 上の場合、splunk builｔなのでSplunk社で開発している事がわかります。

- Palo AltoのAppの場合、Splunk Builtアイコンが無いことがわかります。
![スクリーンショット 2021-09-03 16.25.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185759/23ee6e23-40b2-35cd-6089-5456330bea1c.png)
    
- こういうときは右下のサポート内容をチェックします。
![スクリーンショット 2021-09-03 16.25.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185759/9cdc740f-af3b-1eda-0b71-d4bcda053f5b.png)

- Palo Alto Appの場合、Developer Supportedであることがわかります。


### 2.サポートレベルの確認方法

- サポートレベルの公式資料
    - https://dev.splunk.com/enterprise/docs/releaseapps/splunkbase/optionsforsubmittingcontent/#Support-content


パターン別サポートの実態（※個人の体験に基づきます）
---

- Splunk Supported(Splunk Built)
    - SplunkサポートのSLAに基づき対応
- **Splunk Works**
    - splunk社員が開発したもの。該当社員によるベストエフォートでサポート
- Developer Support
    - ベンダー毎でサポートレベルは異なる
- **Community Support**
    - みんなで助け合いましょう精神

### Splunk WorksとCommunity Supportの扱い
- Appのコード管理はgithubで行っていることが多い
- 修正のリクエスト方法は以下中心
    - Splunk Answer
    - メール
    - github上でissue登録

- appの人気度合いと更新度合いを見て、活況なものであれば**１〜２日**で連絡がついた
    - [Alert Manager](https://splunkbase.splunk.com/app/2665/)
        - 当時issue登録した[やりとり](https://github.com/alertmanager/alert_manager/issues/created_by/odorusatoshi)
    - [Sigbay Link Analysis](https://splunkbase.splunk.com/app/5126/)
        - 当時のメールのやりとり
![スクリーンショット 2021-09-03 16.43.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185759/9a9dcd59-7b48-db9a-c855-5f3246b71ac2.png)


所感
---
- Community Appsであっても、英語で質問や問題内容を説明できれば解決していくことができる
- 個人的にはsplunk社/べンダーサポートよりも、個人で対応、修正してくれるcommunity appのほうが対応早い気がする（※ハズレもあるかも）



参考
---
- [無償のセキュリティ神Apps10選](https://speakerdeck.com/odorusatoshi/wu-chang-falsesekiyuriteishen-apps10xuan)
MQTTトピックのベストプラクティス

# 前置き
MQTTを使ったシステムを設計する上でのトピックに関するベストプラクティスについて調べてみました。
個人的な調査なので、間違い、意見等ありましたらコメント頂けると幸いです。

# MQTTの一般的な特徴
- まず初めに、把握しておくと良さそうな一般的な特徴を挙げておきます
1. SubscriberはどのPublisherが送信したメッセージかを知らない
    - ただし、トピックに識別子を含めることで知ることはできます（後述）
1. Brokerからすべてのトピック一覧を取得することはできない
    - BrokerはSubscriberのいないトピック（メッセージ）を捨ててしまう
    - ただし、`retain`フラグを設定している場合を除く
1. PublishしたメッセージをどのSubscriberがSubscribeしたかを知ることはできない

# トピックのベストプラクティス
トピックの定義には気をつけると良いポイントがいくつかあるようです

## 先頭にスラッシュ(`/`)をつけない
- mqttでは先頭のスラッシュは禁止(例: :x:`/cmd/echo`, :o:`cmd/echo`)

## 小文字、数字、ダッシュ(`-`)だけを使う
- トピックは小文字と大文字を区別しないため、小文字で統一する
- スペース(" ")はデバッグを困難にするので使わない
- スペースの代わりにダッシュ(`-`)を使う
- 日本語は:x:

## 右に行くほど、狭域になるようにする
- トピックは左から右へ読まれるため、広域(一般的)なものから狭域(特徴的)なものへと流れるようにする
- 例えば自宅の庭のラズパイ101の温度を表すメッセージの場合
    - `myhouse/garden/raspy101/temperature`

## できるだけ短く、簡潔にする
- 組み込みデバイスなどのリソースの小さいデバイスにも使われるため、トピックはできるだけ短くする
- 使われるメッセージのみを含める

## 識別子を含める
- 特定のデバイスのメッセージのみ取得したい場合やSubscriberがPublisherを把握したい場合などに有用であるため
- デバイス名、IDなどをトピックに含める

## スケーラビリティに気をつかう
- 例えば、新たなセンサー、デバイスを追加するとき
- 新たな機能を追加するとき
- トピック全体の構成が変わらないように気を使います

## ワイルドカードを使う
- Subscribeするときなど、トピックに2種類のワイルドカードが使えます
- 一階層の場合は`+`
    - 例: `myhouse/garden/+/temparature`の場合
        - :o: `myhouse/garden/raspy101/temparature`
        - :x: `myhouse/kitchen/raspy101/temparature`
        - :x: `myhouse/garden/raspy101/humidity`
- 複数階層の場合は`#`
    - 例: `myhouse/#/temparature`の場合
        - :o: `myhouse/garden/raspy101/temparature`
        - :o: `myhouse/kitchen/raspy202/temparature`
        - :x: `myoffice/raspy101/temparature`

## #でSubscribeしない
- 上記で登場したワイルドカード`#`を使うと、Brokerを経由するすべてのメッセージをSubscribeできるが、
- Subscribeするクライアントに大きな負荷がかかるため、使わない
- すべてのメッセージを確認したい場合はBrokerにプラグインを設定する
    - 例として[HiveMQ](https://www.hivemq.com/extension/mqtt-message-log-extension/)があるそうです（使ったことありません）

## `$`で始まるトピック
- `$`で始まるトピックはBrokerの内部状態のために占有されているので、Publishできない。
- また、`#`でも`$`で始まるトピックはSubscribeされない
- 標準化されていないため、実装によって仕様が異なる。`$SYS/`で始まるトピックのみ共通で使われる。
    - 例: [mqttのGithub](https://github.com/mqtt/mqtt.org/wiki/SYS-Topics)に書かれている

# まとめ
- 一般的に言えることを書いたつもりですが、用途によってはこれに該当しない場合もあると思われます。

# 参考
- https://mqtt.org/
- https://www.hivemq.com/blog/mqtt-essentials-part-5-mqtt-topics-best-practices/
- https://docs.aws.amazon.com/whitepapers/latest/designing-mqtt-topics-aws-iot-core/mqtt-design-best-practices.html
- https://www.hivemq.com/extension/mqtt-message-log-extension/
- https://pi3g.com/2019/05/29/mqtt-topic-tree-design-best-practices-tips-examples/
composer installでS3のregionが設定されていないというエラーが出る

## 現象
composer installすると以下のようなエラーが出る。

```
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi

   InvalidArgumentException  : Missing required client configuration options:

region: (string)

  A "region" configuration value is required for the "s3" service
  (e.g., "us-west-2"). A list of available public regions and endpoints can be
  found at http://docs.aws.amazon.com/general/latest/gr/rande.html.

  at /Users/shohei.hagiwara/s4bids_ponpare/admin/vendor/aws/aws-sdk-php/src/ClientResolver.php:397
    393|             $missing[] = $this->getArgMessage($k, $args, true);
    394|         }
    395|         $msg = "Missing required client configuration options: \n\n";
    396|         $msg .= implode("\n\n", $missing);
  > 397|         throw new IAE($msg);
    398|     }
    399|
    400|     public static function _apply_retries($value, array &$args, HandlerList $list)
    401|     {

  Exception trace:

  1   Aws\ClientResolver::throwRequired()
      /Users/shohei.hagiwara/s4bids_ponpare/admin/vendor/aws/aws-sdk-php/src/ClientResolver.php:293

  2   Aws\ClientResolver::resolve(Object(Aws\HandlerList))
      /Users/shohei.hagiwara/s4bids_ponpare/admin/vendor/aws/aws-sdk-php/src/AwsClient.php:187

  Please use the argument -v to see more details.
```

## 原因と解決方法
ただ単にS3クライアントを使っている場所でちゃんとクライアントを初期化できていないだけだった。
storage/logs/laravel.log を見るとどの場所でエラーかわかるので直す。
Mayaスクリプトの見分け方

MelとPythonでMayaスクリプトは記述されていますが、
「Maya Pythonモジュール」をimportすることで多様な書き方になっています。


そこで<b>「Maya Pythonモジュール」</b>を判別するための記事として以下の記述例を用意しました。
注意：「maya.mel」のみスクリプトエディターの「MEL」タブ、他は「Python」タブにて使用する想定で記述しています。



<hr>

<h5>maya.mel</h5>

```
string $selObjs[] = `ls -sl`;
for($selObj in $selObjs){
	print ($selObj + "\n");
}
```



<h5>maya.cmds</h5>

```py
import maya.cmds as cmds
selObjs = cmds.ls(sl=1)
for selObj in selObjs:
	print selObj
```

```py
import maya.cmds as mc
mc.sphere()
```
<sup>注：Autodesk公式で「cmds」と「mc」の表記が混ざっている。
好きなプレフィックスを使ってよい…とされているが、統一してほしいところ。</sup>



<h5>pymel（PyMEL for Maya）</h5>

```py
import pymel.core as pm
for selObj in pm.selected():
	print selObj
```



<h5>maya.OpenMaya（Maya Python API 1.0）</h5>

```py
import maya.OpenMaya as om
selObjs = om.MSelectionList()
```
<sup>注：1.0と2.0を見分けるために「om1」と書いたり、
API2.0のことを「om」と記述している場合があるので気を付けたい。</sup>



<h5>maya.api.OpenMaya（Maya Python API 2.0）</h5>

```py
import maya.api.OpenMaya as om2
selObjs = om2.MSelectionList()
```
<sup>注：API2.0を単純に「om」と記述している場合がある。
他人がスクリプトを見ることを考えて「om2」と書く方が合理的に思える。</sup>

<h5>その他（Mayaでしか動かないAPIの一例）</h5>

```py
# XGen Python API
import xgenm as xg
import xgenm.xgGlobal as xgg

#レンダリング設定 Python API
import maya.app.renderSetup.model.override as override
import maya.app.renderSetup.model.selector as selector
import maya.app.renderSetup.model.collection as collection
import maya.app.renderSetup.model.renderLayer as renderLayer
import maya.app.renderSetup.model.renderSetup as renderSetup
```


<hr>

<h5>一般的なpythonでみかけるimport文</h5>

```py
import sys
import time
import re
import math
from itertools import izip 
```
<sup>Mayaでpython3系が使えないので、itertoolsをimportする必要があった。Maya2022からPython3が使えるのでこの記述は不要かも…。</sup>
<hr>
Mayaのヘルプにあるように、APIの記述では「C++」という言語も登場します。
melともpythonとも記法が違い、C, C#, Javaに似た記法のものです。
>Maya の C++ と Python API の違い
>Maya Python API は C++ Maya API の正確なコピーではありません。統合のため、Python のバインドには変更を加えています。

<h5>C++</h5>

```cpp
#include "XXXX.h"

void XXXX{
    for (int i = 0; i < 3; i++)
    {
        printf(i);
    }
    return 0;
}
```

<hr>
今回の記事には、各モジュールの特性や速度比較などは載せていません。
気になる方は以下を参考にしてみて下さい。<br><br>

参考
[AUTODESK MAYA2020 / MayaのPython](https://help.autodesk.com/view/MAYAUL/2020/JPN/?guid=GUID-C0F27A50-3DD6-454C-A4D1-9E3C44B3C990)
[MayaPythonScriptを比較してみる](https://dftalk.jp/?p=12128)
[【Maya】Python,C++,C#で比較。スキンウエイトの取得と設定](http://ueta.hateblo.jp/entry/2015/08/24/102937)


<br><br><br>
補記
cmdsとapi2.0で速度比較して
「apiの方が700倍速い！」と示しているデータもある。
頂点処理など大量にかさむ場合、apiは必須。

また、いくら調べてもMELしか記述が見つからないことも結構あるので、
あまりこだわらずにMELもpythonも適宜使っていきたい。
【Rails】Your Ruby version is 3.0.2, but your Gemfile specified 2.7.2の対処法

<h2>症状</h2>
Gitから新しいPCにプロジェクトをpullした後、railsサーバーを起動しようとしたところ、下記のエラーが表示されてしまいました。
バージョンが違うと怒られているようです。

```terminal:error
Your Ruby version is 3.0.2, but your Gemfile specified 2.7.2
```

Gemfileに記述されているバージョンを確認したところ、下記でした。

```ruby:Gemfile.rb
ruby '2.7.2'
```

現在インストールしているバージョンを確認したところ、下記でした。
エラーメッセージ通りでした。

```terminal:rubyバージョン
ruby -v
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x64-mingw32]
```

<h2>解決策</h2>
Gemfileに書かれているバージョンを現在のバージョンに変更し、bundle updateをすることで解決しました。

```ruby:Gemfile.rb
ruby '3.0.2'
```

```terminal:アップデート
bundle update
```
Powershellの起動時のディレクトリを変更する方法(Windows10)

`$profle`に"`cd 任意のディレクトリ`"を追記するだけ。

1 . powershellで`$profile`と打つ。

```powershell
> $profile
C:\Users\<ユーザー名>\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
```

2 . 1で出力されたファイルにテキスタエディタ(メモ帳など)で以下を追記する。

```
cd 任意のディレクトリ(例：C:\Users\ユーザー名\Documents)
```

これだけ！超簡単！
[js] ajaxの書き方 (おまけaxios, fetch関数)

## この記事について
ajaxの書き方についてjQueryと生JS両方の書き方の備忘。

## ajaxとは
webページを再読み込みせずにサーバと通信を行い、結果を画面に反映すること(非同期処理)ができる技術

## jQueryでの書き方
```javascript:jQuery
$(function() {
  let url = "https//xxxxx";
  $.ajax({
    url: url,
    dataType : 'json'　//データ形式
  }).done(function(data) {
    //通信成功時の処理
  }).fail(function(data) {
    //通信失敗時の処理
  }).always(() => {
    //通信の成否に関わらず実行する処理
  });
});
```

## JavaScriptでの書き方
```javascript:javascript
let url = "https//xxxxx";
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
    if ( xhr.readyState === 4 ) {
        if( xhr.status == 200) {
            var data = JSON.parse(xhr.response);
            //通信成功時の処理
        } else {
            //通信失敗時の処理
        }
        //通信の成否に関わらず実行する処理
    }
};
xhr.open( 'GET', url );
xhr.send();
```

## おまけ axiosについて
### axiosとは
ブラウザやnode.js上で動くPromiseベースのHTTPクライアント
Vue.jsやReactで非同期通信を行う際はaxiosがスタンダード

### 書き方
```javascript:vue.js
let url = "https//xxxxx";
axios
.get(url)
.then(function (response) {
    //通信成功時の処理
})
.catch(function (error) {
    //通信失敗時の処理
})
.finally(function () {
    //通信の成否に関わらず実行する処理
});
```

## おまけ JS fetch関数によるAPIの取得について

JSのfetch関数でAPIを叩くときの書き方

### Promiseチェーンを使用した場合 
サンプル：https://jsfiddle.net/Maro1027/964x7tug/
```js
function callApi() {
  const url = 'https//xxxxx';
  const res = fetch(url)
  .then(resData => {
    // データが返ってこなかった場合はエラーを返却
    if(!resData.ok) {
      throw new Error('response error');
    }
    // JSON形式でデータを返却
    return resData.json();
  })
  .then(parseData => {
    // resData.json()をparseDataとし受け取り
    // 通信成功、正常にデータを取得した時の処理
  })
  .catch(error => {
    //通信失敗時の処理
	console.log(error);
  })
}

callApi();
```

### async/awaitとtry/catch文を使用した場合 
サンプル：https://jsfiddle.net/Maro1027/dpqcsuhm/
```js
const url = 'https//xxxxx';
async function callApi() {
  try {
    const response = await fetch(url);
    const data = await response.json();
    //通信成功時の処理
  } catch (error) {
    //通信失敗時の処理
  }
}

callApi();
```




## 参考

https://qiita.com/frost_star/items/3dec133b5213f5cd7a35

https://www.willstyle.co.jp/blog/2751/

https://apidog.com/jp/blog/javascript-fetch-ajax/
Laravelのリソースコントローラー便利～～～！！

#リソースコントローラーとは
一般的なCRUD処理は以下の通り。 
生成(Create)、読み込み(Read)、更新(Update) 、削除(Delete)

しかし気の利くLaravelちゃんには
「リソースコントローラー」という機能があり
7つの要素を持ったコントローラーを自動で作ってくれる。

|名前  |機能  |
|---|---|
|index  |データを一覧表示  |
|create  |新規作成用フォームの表示  |
|store  |新規作成を保存  |
|show  |作成データを個別表示  |
|edit  |作成データ編集用フォームの表示  |
|update  |編集したデータを保存  |
|destroy  |データを削除  |

##実行方法
###コンソール画面

```php
php artisan make:controller 任意のコントローラー名 --resource
```


ふーん！やるじゃん！！
すごいじゃん！まだすごさを分かってないけど。
すごい予感がする。私の直感が！！鳥肌が立ってる！！

はい。リソースコントローラーでした！7つの要素言えるかな～！

ええーーと

index, create, store, show, edit, update, destroy。
今勉強したばっかだから言えた！ｗ

#ルート設定も簡単に。
7つ分のページのルート設定がなんと🔽この一行で。
###route/web.php

```php
Route::resource(/post,Postcontroller);
```
えええ。楽しちゃって良いのかな。ラクできるとこは楽するけど。
ちなみにリソースコントローラーを使わない場合に
ルート設定をする時は下記の方式で書きます。

Route::HTTPメソッド('URL','コントローラー@メソッド')->name('ルート名');

Laravelがスマートな言語ってことは伝わってきた。うむ。好きだ。

よーし。今日も一緒にプログラミングしていこう！
ターミナルからGitHubラベルを作成・削除する簡単なCLIツール作った

先日、[この記事](https://qiita.com/willow-micro/items/51eeb3efe5b4192a4abd)を読んで、確かにRepo作るとデフォルトのラベルとは別に必ず追加するなぁと。

実際、作ること自体は難しい作業ではないですが、複数のラベルを作成することが多いので、ちょいちょい面倒だなぁと思ってました。
はじめに、GitHub CLIにラベル作る機能があるかもしれないと、確認したところそれっぽいものはありませんでした。
https://cli.github.com/manual/gh_issue_create

なので、GitHub APIをチェックしました。
https://docs.github.com/en/rest/reference/issues#labels

APIのドキュメントによると、基本的にはoctokit.jsをインストールして、personal tokenを渡してインスタンスを作り、パラメータとして、ユーザーIDとラベルを作成・削除したレポジトリの名前に加えて、ラベルを作成したい場合はラベルの情報（ラベル名、ラベルの色、ラベルの説明）。削除したい場合はラベルの名前を渡せば良いようです。

https://github.com/octokit/octokit.js


現状、このツールで出来ることは以下の4つです。

- ラベルを作成する
- 複数のラベルを作成する　constant.tsに定義してあるnewLabel（https://github.com/koji/github-label-manager/blob/main/src/constant.ts#L22-L205）
- ラベルを削除する
- 全てのラベルを削除する

複数の指定したラベルを削除する機能は近日中に追加する予定です。

ちなみ、`constant.ts` はこちらの記事を元にしています。

https://qiita.com/willow-micro/items/51eeb3efe5b4192a4abd


### デモ
<iframe width="560" height="315" src="https://www.youtube.com/embed/NwGOl6usJ-A" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

### レポジトリ
https://github.com/koji/github-label-manager

### 使い方

```zsh
# repoをクローン
$ git clone https://github.com/koji/github-label-manager.git
$ cd github-label-manager

# パッケージをインストール
# use yarn
$ yarn # install packages
$ yarn build # compile typescript
$ yarn start # run index.js

# use npm
$ npm install
$ npm run build
$ npm start

# buildしないでts-nodeで直接tsを実行
# or use ts-node
$ npx ts-node src/index.ts # this might be slow
```

###  補足
octkit.jsに加えて、ターミナルからの入力のためにpromptsを使っています。

https://github.com/terkelg/prompts


一番最初にざっと機能を実装した時は、readline-syncを使っていました。
ただ、その名の通りsyncだったので、1つラベル作ってツール終了して、削除するときはまたツールを起動みたいな使うのが面倒な作りにしてしまったので、ラベル作成はレポ作ったときにやるくらいだけれど、この面倒さだと使わないなと思い、promptsに切り替えました。

https://github.com/anseki/readline-sync


ちなみに、ベースは `typescript-starter` を使って作りました。
ただ、後からDenoとかで作った方が良かったかなぁと。`typescript-starter`は悪くないんですが、自分のVSCodeのconfigとの相性が良くなかったみたいで、その部分を解消するのに結構時間が取られました

https://github.com/bitjson/typescript-starter
Docker よく使用するコマンド集

よく使用するコマンド集を自分用にメモ

## docker container系

### docker container run [コンテナ名]

- 新しいコンテナを実行
- オプション"-d"でバックグラウンドで実行できる
- オプション"-p"でポートの指定ができる
- オプション"—name"で名前をつけることができる

    ```docker
    // ポート番号は左がローカルのポート番号、右がコンテナのポート番号
    docker container run -d -p 8080:8080 --name sampleApp amygdalus/sampleApp:latest
    ```

### docker container start [コンテナ名]

- 停止中のコンテナを起動

### docker container stop [コンテナ名]

- 実行中のコンテナを停止

### docker container ls

- コンテナ一覧の表示
- "ls -a"で停止中のコンテナも表示

### docker container logs [コンテナ名]

- コンテナのログを出力

### docker container exec [コンテナ名] [コマンド]

- 実行中のコンテナ内でコマンド実行

### docker container rm [コンテナ名]

- コンテナの削除

### docker container prune

- 停止中のコンテナを全削除

## docker image系

### docker image build

- Dockerfile からイメージを構築（ビルド）
- オプション"-t"でタグをつけることができる

    ```docker
    // 最後のドットは今いるディレクトリに存在するdockerfileを参照するという意味
    docker image build -t amygdalus/sampleApp:latest .
    ```

### docker image ls

- イメージ一覧表示

### docker image prune

- 使用していないイメージを削除

### docker image rm [イメージ名]

- イメージを削除
HDF5について③ ~Groups~

備忘録です。かなり初心者なので、どしどしご指摘お願いします。
https://docs.h5py.org/en/latest/index.html
を参考にしています。
###準備
```py
#準備
import h5py
f = h5py.File('foo.hdf5','w')
f.name,list(f.keys())
```
Pythonから扱うとき、Groupsは、辞書のように振る舞う（は？）。keysはグループ内のメンバーの名前を、valuesはメンバー自身（Group及びDataset）を示す。

##Creating groups
```py
grp = f.create_group("bar")
subgrp = grp.create_group("baz")
grp2 = f.create_group("/some/long/path")
```
のように、.create_groupで新たなグループを作成できる。3行目のように絶対パスでも良い。

##Dict interface and links
※dict()は、Pythonで辞書型配列をつくるためのオブジェクト
GroupsはPython辞書配列の一部のような感じ？Groupsにはkeys(),values()のようなメソッドがある。
また、オブジェクトは削除することもできる

```py
 del subgroup["MyDataset"]
#ただしdelはpython上にある変数を削除するだけ?
```
##Hard links
グループ内の名前にobjectを割り当てると何が起こるのか？それは割り当てられるオブジェクトのタイプによる。Numpy配列や他のデータのデフォルトではDatasetを作成する。

```py
grp["name"] = 42
out = grp["name"]
out
#出力<HDF5 dataset "name": shape (), type "<i8">
```
オブジェクトがすでに存在するGroupやDatasetの場合、新しいリンクがオフジェクトに対して作成される

```py
grp["other name"] = out
grp["other name"]
#出力<HDF5 dataset "name": shape (), type "<i8">
```
これは、Detasetのコピーではないことに注意。hard linkでは、HDF5ファイルのオブジェクトは複数のgroupsに保存できる。

```py
grp["other name"] == grp["name"]
```
##Soft links
UNIXのファイルシステムのように、HDF5のGroupsはsoftな、あるいは抽象的なリンクを持つことができる。それは、オブジェクト自身を指すのではなく、テキストパスを持つ。

```py
group = f.create_group("somegroup")
list(f.keys())
#出力 ('/', ['bar', 'some', 'somegroup'])

f["alias"] = h5py.SoftLink('/somegroup')
list(f.keys())
#['alias', 'bar', 'some', 'somegroup']
```
ターゲットが削除されると、、

```py
del myfile['somegroup']

print(f['alias'])
#出力 KeyError: 'Unable to open object (component not found)'
list(f.keys())
#出力 ['alias', 'bar', 'some']
```
bitnami redmine knowledgebaseプラグインでthumbnailsが表示されない

##■経緯
　・bitnami redmine4.2に、knowledgebaseプラグインをインストールして記事を作成した。
　　また記事には、画像をthumbnailに設定していたが、一覧表示でthumbnailが表示されなかった。
　　※Redmineのプラグイン設定でもthumbnail表示は設定済み
<img width="400" alt="fdcfde34-8133-e20d-4b75-e0af0594d987.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651745/fdcfde34-8133-e20d-4b75-e0af0594d987.png">

##■環境：
 Environment:
  Redmine version                4.2.1.stable
  Ruby version                   2.6.7-p197 (2021-04-05) [x64-mingw32]
  Rails version                  5.2.5
  Environment                    production
  Database adapter               Mysql2
  Mailer queue                   ActiveJob::QueueAdapters::AsyncAdapter
  Mailer delivery                smtp
 SCM:
  Git                            2.31.1
  Filesystem                     
 Redmine plugins:
  redmine_agile                  1.6.1
  redmine_knowledgebase          4.1.1
  redmine_wiki_extensions        0.9.2
  redmine_wiki_lists             0.0.11

##■やりたいこと：
　・knowledgebaseで記事一覧表示でthumbnailが表示させたい。


##■調査
　knowledgebaseで記事一覧表示の時点でのログを表示解析する。

  [1m[36mSetting Load (0.4ms)[0m  [1m[34mSELECT  `settings`.* FROM `settings` WHERE `settings`.`name` = 'thumbnails_enabled' ORDER BY `settings`.`id` DESC LIMIT 1[0m
Imagemagick's convert binary (C:\Bitnami\redmine-4.2.1-1/imagemagick/convert.exe) not available
  Rendered plugins/redmine_knowledgebase/app/views/attachments/_links.html.erb (4.9ms)

##■調査２
ログを確認し、convert.exe場所を確認するとログのパスと実際のパスとで異なることが分かった。

（ログ）C:\Bitnami\redmine-4.2.1-1\imagemagick\convert.exe
（実際）C:\Bitnami\redmine-4.2.1-1\imagemagick\bin\convert.exe

##■修正
configuration.ymlを以下に修正して再起動する。

（修正前）imagemagick_convert_command: 'C:\Bitnami\redmine-4.2.1-1/imagemagick/convert.exe'
（修正後）imagemagick_convert_command: 'C:\Bitnami\redmine-4.2.1-1/imagemagick/bin/convert.exe'

##■確認結果
再起動後に、knowledgebaseの記事一覧表示でthumbnailが表示されることを確認できた。

<img width="400" alt="f6b0fd3d-e132-2cdc-0e14-adc16c270b9f.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651745/f6b0fd3d-e132-2cdc-0e14-adc16c270b9f.png">


以上です、お疲れ様です。
Python を EXE 化する

## Python を配布用に EXE 化したい
### 1. 環境

| 内容 | バージョン |
|:-|:-|
| OS  | Windows 10 Pro (64bit)  |
| Chrome  | 92.0.4515.159  |
| ChromeDriver  | 92.0.4515.107  |
| Python  | 3.9.0  |
| selenium  | 3.141.0  |

+ Visual Studio Code

| アイテム | バージョン |
|:-|:-|
| バージョン  | 1.59.1 (user setup)  |
| コミット  | 3866c3553be8b268c8a7f8c0482c0c0177aa8bfa  |
| 日付  | 2021-08-19T11:56:46.957Z  |
| Electron  | 13.1.7  |
| Chrome  | 91.0.4472.124  |
| Node.js  | 14.16.0  |
| V8  | 9.1.269.36-electron.0  |
| OS  | Windows_NT x64 10.0.19042  |
| Python | 3.9.0 64bit  |

### 2. 仮想環境を構築する
EXE ファイルをできるだけ小さくするには、仮想環境を構築して、
使用するモジュールのみをインストールするようにするといらないモジュールを読み込まず軽くなる。
仮想環境構築はこちらのサイトが大変わかりやすかったです。

https://qiita.com/enya314/items/0e62b68fe70f52a628bf

仮想環境のパッケージ情報を書き出すときは、
`pip freeze > requirements.txt`
仮想環境を終わるときは、
`deactivate`
仮想環境を削除するときは作成したフォルダを削除。

### 3. Pyinstaller モジュールを使う
Pyinstaller インストール
`pip install pyinstaller`

### 4. Pythonファイルをexe化する。
目的のPythonファイルが存在するディレクトリに移動し、
その後、以下のコマンドを実行します。
`pyinstaller ファイル名 -–onefile -–noconsole`
--onefileは生成されるものを1つのファイルにまとめる。
--noconsoleはexeファイル実行時にコンソールが表示されないようにする。

EXEファイルは、ファイルがあったフォルダ直下の新しくできた「distフォルダ」に入っている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637498/7ff1b97d-774b-dc63-c941-ebd6943ca0db.png)

+ アイコン設定

`pyinstaller ファイル名 -–onefile -–noconsole --icon=test.ico`
.ico ファイルを同じフォルダに置く。

### 参考にさせて頂いたサイト
https://office54.net/python/python-pyinstaller

https://techacademy.jp/magazine/18963

https://acokikoy.hatenablog.com/entry/2019/09/14/141128
Nuxt Composition APIでシンプルなToDoリストを作る[TypeScript]

# はじめに

Nuxt.jsで Composition API を使う新しい方法である`Nuxt Composition API`(@nuxtjs/composition-api)を使ってシンプルなToDoリストを作ります。

https://composition-api.nuxtjs.org/

# `Nuxt Composition API`とは

Nuxt Composition APIとは、Nuxt.jsの次期バージョンである、Nuxt 3のための実験的なパッケージです。

> Note: the main aim is to allow experimentation and feedback before the final release of Nuxt 3. The API of Nuxt-specific methods will likely change before Nuxt 3 is released.
> (Google Translate) 注：主な目的は、Nuxt 3の最終リリースの前に実験とフィードバックを可能にすることです。Nuxt固有のメソッドのAPIは、Nuxt3がリリースされる前に変更される可能性があります。


npmでは、`@nuxtjs/composition-api`として提供されています。


NuxtでComposition APIを使う方法は２つあります。`@vue/composition-api`を使う方法と、今回紹介する`@nuxtjs/composition-api`を使う方法です。
今回はより新しい方法である、`@nuxtjs/composition-api`を試してみます。

Nuxt Composition APIの最新バージョンは`v0.27.0`です。 v1にも満たないパッケージなので本番環境で使うのは少し早いかもしれません。


# セットアップ

## Nuxtインストール


```
mkdir simple-todo
cd simple-todo
yarn create nuxt-app 
```
流れに沿ってインストールするが今回は`TypeScript`を選択する

## Composition APIをセットアップ

https://composition-api.nuxtjs.org/getting-started/setup

```
yarn add @nuxtjs/composition-api
```

nuxt.config.jsに以下を追加

```diff
{
  buildModules: [
    '@nuxt/typescript-build',
+    '@nuxtjs/composition-api/module'
  ]
}
```

# 完成イメージ

![Sep-02-2021 21-29-42.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/cb13facd-04fb-121b-5f10-c0786c5459d3.gif)


# コード

```vue:pages/index.vue
<template>
  <div>
    <ul>
      <li v-for="(todo, index) in todos">
        <input type="checkbox" v-model="todo.done"/>
        <span>{{ todo.title }}</span>
        <button @click="remove(index)">REMOVE</button>
      </li>
    </ul>
    <input type="text" v-model="newToDoTitle"/>
    <button @click="add">ADD</button>
  </div>
</template>

<script lang="ts">
import {defineComponent, ref} from "@nuxtjs/composition-api";

type ToDo = {
  done: boolean,
  title: string
}

export default defineComponent({
  head: {
    title: 'My Page'
  },
  setup() {
    const todos = ref<ToDo[]>([
      {
        done: false,
        title: 'これはやることです'
      }, {
        done: true,
        title: '二つ目のやること'
      }, {
        done: false,
        title: '三つ目のやること'
      },
    ])
    const newToDoTitle = ref<string>('')
    const add = () => {
      todos.value.push(
          {
            done: false,
            title: newToDoTitle.value
          }
      )
      newToDoTitle.value = ''
    }
    const remove = (index: number) => {
      todos.value.splice(index, 1);
    }

    return {
      todos,
      newToDoTitle,
      add,
      remove
    }
  }
})
</script>
```

## 終わり

参考になりましたら幸いです
react-aceをNext.jsで使うときのメモ

## 概要
react-aceは簡単にサイトにコードエディタを埋め込めるのでとても便利
だけどグローバルのwindowを参照するのでNext.jsで使うときに一苦労する
dynamic importを使う方法がいまいち調べても出てこなかったので書き留めておく。

## Next.jsで使う
上述の通りwindowを参照するので公式に紹介されてる通りでは使えない
→dynamic importを使う

必要なライブラリをインストールする

```
npm install react-ace ace-builds
```

next.jsのdynamic importを使う

```react
import dynamic from 'next/dynamic';

const AceEditor = dynamic(async () => {
  const ace = await import('react-ace');
  await import("ace-builds/src-noconflict/mode-???");
  await import("ace-builds/src-noconflict/theme-???");
  return ace;
}, { ssr: false });
```

???には自分の好きなモードとかテーマを入れてください
awaitしているのは、react-aceが読み込まれた状態じゃないとace-buildsのモードとかテーマが適用できないからです。

モードとかテーマとかなしにデフォルトで使うなら

```react
import dynamic from 'next/dynamic';

const AceEditor = dynamic(async () => import('react-ace'), { ssr: false });
```

でいいと思います。

あとは公式で紹介されてる通りに使えるはずです
TwitterとLINEのシェアボタンカスタマイズ（改行タグ・半角スペース・絵文字・文中ハッシュタグ）

# 基本フォーマット
### Twitter

`https://twitter.com/share?url=[URL]&text=[テキスト]&hashtags=[ハッシュタグ1,ハッシュタグ2]`

▼例

```html
<a href="https://twitter.com/share?url=https://omochilab.net/&text=Webデザイナー真符の個人サイトです%0aウェブサイトはこちら▼%0a&hashtags=デザイン,WEBデザイナー" target="_blank">ツイートする</a>
```
シェアしたい[URL]と[テキスト]と[ハッシュタグ]を&で繋ぎます。
ハッシュタグはカンマ繋ぎで複数指定可能。

### LINE
`https://social-plugins.line.me/lineit/share?url=[URL]&text=[テキスト]`

▼例

```html
<a href="https://social-plugins.line.me/lineit/sharehttps://omochilab.net/&text=Webデザイナー真符の個人サイトです%0aウェブサイトはこちら▼%0a" target="_blank">LINEに送る</a>
```

# 改行や半角スペース、絵文字の入れ方
`%0a` 改行
`%20` 半角スペース
絵文字はそのまま書いてOK

#テキスト内にハッシュタグを入れたい時
`#`は`%23`に変更し、前後に半角スペース`%20`を入れる。
▼例
`%20%23ハッシュタグ%20`

```html
<a href="https://twitter.com/share?url=https://omochilab.net/&text=Webデザイナー真符の個人サイト「%20%23おもちラボ%20」です%0aウェブサイトはこちら▼✨%0a%0a&hashtags=デザイン,Webデザイナー" target="_blank">ツイートする</a>
```
▼実際のボタン
<a href="https://twitter.com/share?url=https://omochilab.net/&text=Webデザイナー真符の個人サイト「%20%23おもちラボ%20」です%0aウェブサイトはこちら▼✨%0a%0a&hashtags=デザイン,Webデザイナー" target="_blank">ツイートする</a>

![スクリーンショット 2021-09-03 15.39.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101367/cc977dd4-00c9-712e-c645-37a9cdcc3719.png)
LeetCord(記録）python3

##1. Two Sum

```
nums = [2,7,11,15]
target = 9
result = []
for i in range(len(nums)):
  for j in range(i,len(nums)):
    if nums[i] + nums[j] == target:
      result = [i, j]
      break;

print(result)
```

##7. Reverse Integer
符号付き32ビット整数xが与えられた場合、桁を逆にしてxを返します。 xを逆にすると、値が符号付き32ビット整数の範囲[-231、231-1]の外に出る場合は、0を返します。

環境では64ビット整数（符号付きまたは符号なし）を格納できないと想定します。

```python
x = 123

s = (x > 0) - (x < 0) #1(true)-0(false)
r = int(str(x*s)[::-1])
y = s*r * (r < 2**31) #321*1(true)

print (s)#1
print (r)#321
print (y)#321
```




###範囲を全指定にしてマイナスステップにすると、要素がリバースする。

```
>>> a[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1]
```

https://qiita.com/kaeruair/items/e7f1c08915839ce3c9b4


##True, False に四則演算を適用すると
True は 1、False は 0 として扱われます。

```
(x > 0) - (x < 0) #1か0を返す
```
Cloudfront＋LambdaEdgeでリダイレクトを行う。

こちらに書いてあるサンプルをそのまま載せてます…

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/lambda-examples.html

`HTTP リダイレクトの生成 (生成されたレスポンス)`


lambdaはバージニア北部で作ります。
Pythonは３．８です（３．９で作ったらCloudfrontが対応してないって言われました。）

ロールは新たに作ります。
[基本エッジ Lambda のアクセス許可]を指定。


```python
import json
 
def lambda_handler(event, context):
    print("event:{}".format(event))
    print("context:{}".format(context))
     # Generate HTTP redirect response with 302 status code and Location header.
     
    response = {
     'status': '302',
     'statusDescription': 'Found',
     'headers': {
         'location': [{
             'key': 'Location',
             'value': 'http://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html'
         }]
     }
    }
     
    return response
```


こちらをDeployし、バージョンを発行します。
Cloudfrontのビヘイビアに設定します。

![スクリーンショット 2021-09-03 15.21.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213689/558adfb4-f878-093d-8d8c-afa905fc0be6.png)

lambdaのコンソールでARNをコピーしましょう
`arn:aws:lambda:us-east-1:99999999:function:EdgeTest:1`
※バージョンも指定しないと駄目みたいです。

これでCloudfrontにアクセスするとリダイレクトされます。
Python 3 UTCエポックから日本標準時変換

とある通信機器からUTCエポックを受信する機会があった。Python3での日本標準時への変換方法をPythonライブラリーリファレンスで調べた。

# 方法
変換方法は1つではないが、`datetime` モジュールとサードパーティーライブラリー `dateutil` パッケージを使用する方法がある。 `dateutil` は標準では無いので実行環境にない場合はインストールが必要。

# `dateutil` パッケージのインストールコマンド

```
pip install python-dateutil
```

# 変換コード

```py

from datetime import datetime
from dateutil import tz

utc_epoch = 1630557969 # UTCエポックの一例
time_zone = tz.gettz('Asia/Tokyo')
jst_time = datetime.fromtimestamp(utc_epoch, time_zone)
```

UTCエポックは少数部も含むが、ここでは`etc_epoch` に整数部だけの数値を代入。`tz.gettz(name=None)` メソッドは引数にIANAタイムゾーンの文字列表現を取って `tzinfo` オブジェクトを返す。引数の `Asia/Tokyo` で日本標準時を意味する。 `Ameria/NewYork` , `Europe/Paris` など別のタイムゾーンオブジェクトを受け取ることも可能。`datetime.fromtimestamp(timestamp, tz=None)` メソッドは第一引数にPOSIXタイム, 第二引数にオブジェクトを受けて `datetime` オブジェクトを返す。

# 余談
エポックとは時刻の基準のこと。Windows、ほとんどのUnixシステムでは1970年1月1日0時0分0秒(UTC)を基準にとっている。Python 3では下記のようにしてエポックを調べられる。エポック時間とは、この基準からの経過秒を示す。Unixタイムと表現されることもある。

```py
import time

print(time.gmtime(0))
```

# 参考
* [Python datetime モジュール](https://docs.python.org/release/3.8.11/library/datetime.html)
* [Python dateutil パッケージ](https://dateutil.readthedocs.io/en/stable/)
WebPとはなんぞや？

#WebPとは
　最近よく見かけるようになった形式。新しい規格なんだろうなと思っていたけど、実際どういうものかよく知らなかったので調べてみたまとめ。拡張子は[.webp]で読み方はウェッピー。

　Googleが作ったweb用の画像フォーマットの一つ。実は10年以上前からあるがブラウザの互換性や書き出しでの対応がなかったので思ったより普及しなかった。最近の主要ブラウザが軒並み対応したので最近よく見るようになってきた。そのうちウェブ画像のスタンダードになりそうです。カンタンにまとめると以下の特徴を持つ。

**・JPEGは約25〜34%、PNGは約28%、元の75%程度に圧縮。
・PNG同様アルファチャンネルを持つことができる。
・GIFのようにアニメーションを持つことができる。**

　と言うようにJPEGとPNGとGIFの特徴を足して、さらに75%くらいの軽量化できるといった感じか。

## 作り方
　とはいえWebPはまだ作る方法が限られている。自分が普段趣味の制作用で使っているAffinity Designer / Photoは直接書き出しが出来ない。Adobe PhotoshopはGitHubに公開されているGoogle公式のプラグイン「WebPShop」を使うことによって直接作成できる。

　他のやりかたはGoogleが用意している画像変換ウェブサービス「Squoosh」(スクワッシュ)を使って変換するのが分かりやすい。

　コマンドラインを叩いて変換もできるらしいが少々難易度は高め。しばらくはSquooshを使って慣れたらコマンドラインをやって見ようかと思う。
## Squoosh
https://squoosh.app/

　作業画面はこちら、何で書き出すか？どれくらいの圧縮率にするか？何%圧縮できるか等の設定できる。中央のスライダーは元と加工後の比較用。今の画像をWebP形式にすると45%削減できますよ、と右下の数値に出ている状態。
![Web キャプチャ_1-9-2021_18259_squoosh.app.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686943/99b0b8c3-b051-7df4-796a-4aad17dbb795.jpeg)


　本当にそれくらい削減できるかは不明だったので、この写真を元に少し試してみる。画像は16:9の4K(3840 x 2160)サイズ。


元画像 JPEG
1.16MB
![PXL_20210825_104230919.NIGHT - 2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686943/918fdd6d-7869-f82b-c892-5905ec54775e.jpeg)

変換後 WebP
0.67MB
![PXL_20210825_104230919.NIGHT - web.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686943/585df0df-fc49-de87-2546-fb905e97049a.jpeg)
　見た目上の違いは全くわからないが、70%以上軽量化された。ただ毎回これをやるのは結構面倒。。。Affinityが対応したら積極的に使ってみたい。Photoshop使う時は毎回これでいいかも。
コマンドライン上で引数を受け取りRスクリプトを実行する

# 背景
Rはインタラクティブにプログラミングできるのが魅力ですが、バッチ処理などコマンドライン上で引数を受け取ってスクリプトを実行したいときもあります。

# 環境
PC: MacBook Pro 2020
OS: macOS Catalina (10.15.5)
shell: zsh (5.7.1)
R: 4.0.2 (2020-06-22)

# 方法
下記のように入力すればコマンドライン上でRのスクリプトを実行できます。

```sh
Rscript Rのスクリプトファイル（.R） 引数1 引数2 引数3…
```
具体例として、2引数を受け取って和と積を計算して表示するCalculation.Rを作成しました。


```R
# Calculation.R
# 引数の取得
num1 <- commandArgs(trailingOnly = TRUE)[1]
num2 <- commandArgs(trailingOnly = TRUE)[2]

# 和と積の計算
sum <- as.numeric(num1) + as.numeric(num2)
product <- as.numeric(num1) * as.numeric(num2)

# コマンドライン上に表示
cat(paste("Sum is ", sum, ".\nProduct is ", product, ".\n", sep = ""))
```
実行してみます。

```sh
Rscript Calculation.R 2 4
Sum is 6.
Product is 8.
```
2と4を受け取って和の6と積の8が出力されました。

# 注意点
### 1. 引数は文字列ベクトルとして受け取られる。
引数がどのように受け取られるのか確認するため、下記のArgsClass.Rを実行してみます。

```R
# ArgsClass.R
# 引数の取得
args <- commandArgs(trailingOnly = TRUE)
args
class(args)
```
```sh
Rscript ArgsClass.R 2 4
[1] "2" "4"
[1] "character"
```
長さ2の文字列ベクトルであることが分かります。そのため、Calculation.Rでは添え字で1つ目の引数と2つ目の引数を取得し（2・3行目）、as.numeric()で数値に型変換しています（6・7行目）。

### 2. commandArgs()で「trailingOnly = TRUE」を指定する
commandArgs()で引数を取得していますが、このときオプションで「trailingOnly = TRUE」を指定する必要があります。

commandArgs()のドキュメントには
>Arguments
trailingOnly　logical. Should only arguments after --args be returned?

とありますが、イマイチよく分からないので「trailingOnly = **FALSE**」を指定して比較してみます。

```R
# trailingOnlyF.R
# 引数の取得
args <- commandArgs(trailingOnly = FALSE)
args
class(args)
```

```sh
Rscript trailingOnlyF.R 2 4
[1] "/Library/Frameworks/R.framework/Resources/bin/exec/R"
[2] "--no-echo"                                           
[3] "--no-restore"                                        
[4] "--file=trailingOnlyF.R"                              
[5] "--args"                                              
[6] "24"                                                  
[1] "character"
```
「trailingOnly = FALSE」を指定すると、引数として入力した「2　4」以外にパスやファイル名なども引数として受け取られていることが分かります。
すなわち、「trailingOnly = TRUE」はコマンドライン上で入力した引数（--argsとして引き渡された引数）のみを返すオプションになります。


参考：[【R言語】実行時引数の取得方法](https://starpentagon.net/analytics/r_command_args/)
useEffectの中のonSnapshot()で無限ループに陥る問題


## やりたいこと
useRouterによって、query.qに一致するPosts(投稿一覧)を取得&購読したい。

## 問題
FirestoreにあるPostsコレクションを購読（onSnapshot）したものの、useEffect()の第２引数にuserを入れると無限ループに落ちいった。

```jsx
import firebase from 'firebase/app';
import { db } from '../lib/firebase'; // export const db したものをimport

import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';

import { useRecoilValue } from 'recoil';
import { userState } from '../hooks/authentication'; // key"userState"のatomをimport

import { Post } from '../models/Post'
import Posts from '../components/Posts';

export default function SearchResultShow() {
  const user = useRecoilValue(userState);
  const [posts, setPosts] = useState<Post[]>(null);

  const router = useRouter();
  const query = router.query as Query;

  useEffect(() => {
    console.log('--- Start useEffect ---')

    if (query.q === undefined) {
      console.log('query.q is undefined');
      return;
    }

    if (!user) {
      console.log('user is undefined')
      return;
    }

    // setPosts(null); ←これが原因
    const unsubscribe = db.collection('posts')
      .where('query', '==', query.q)
      .orderBy('createdAt', 'desc')
      .onSnapshot((snapshot) => {
        console.log('Getting firestore data..')
        const posts = snapshot.docs.map((doc) => {
          const data = doc.data();
          const post = JSON.parse(JSON.stringify(data));
          post.id = doc.id;
          return post;
        });
        setPosts(posts);
      })
    return () => unsubscribe();
  }, [query.q, user]);

  return (
    <Posts posts={posts} />
  );
}
```

## 原因
useEffect()の中で`setPosts(null)`を呼んでいたのが原因だった。

そもそもReactというのは、useStateによって生成している各Stateが変更されたときにComponentが再描画される。そのためuseEffectも当然再度呼ばれる。

普通はuseEffectの中で`setPosts()`のようにState変更の処理を書いていた場合、setPosts()→postsが変わったので再描画→setPosts→postsが変わったので再描画...と無限ループに陥るので、useEffectの第２引数に`[posts]`を入れてやることで前回のpostsと差分があるときだけuseEffectが呼ばれるようになる。

しかし上記コードのように`setPosts(null)`と`setPosts(posts)`の2つが記述されていた場合、`setPosts(null)`→`setPosts(posts)`→postsが変わったので再描画→`setPosts(null)`→postsが変わったので再描画→`setPosts(null)`→`setPosts(posts)`→postsが変わったので再描画..のような変なループに陥る。

そもそもsetPosts()されるときは`Array.push()`のようにデータを追加しているわけではないので、setPosts(null)を呼ばなくてもpostsは新しいものに丸々すげ替えられる。だからchangeTypeを使った出し分けをしなくてもいいはず。

## 補足
Recoilを使っていたり、Firebaseのexportの仕方で若干import部分の書き方などが異なると思う（`db`はexportせずとも都度`firebase.firestore()`で生成してもいい）。
Azure StrageからPython APIでデータを読み込む

Pythonで、Azure StorageのコンテナからBLOBを読み込む方法です。

## 準備その１
```
pip3 install azure-storage-blob
```

## 準備その２
Azure Portalから"ストレージアカウント"を作成し、"コンテナ"を作成して、その配下にファイルをアップロードしておきます。
また、"ストレージアカウント"の"アクセスキー"から"接続文字列"を取得し、環境変数`AZURE_STORAGE_CONNECTION_STRING`に設定しておきます。

## Pythonコード
```py
import os, sys
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient

# "接続文字列"を用いてBlobServiceClientを作成
connect_str = os.getenv('AZURE_STORAGE_CONNECTION_STRING')
blob_service_client = BlobServiceClient.from_connection_string(connect_str)

# コンテナ名を指定してContainerClientを取得
container_client = blob_service_client.get_container_client(container='data')

# コンテナ配下のBLOB一覧の取得と、各BLOBの読み込み
blob_list = container_client.list_blobs()
for blob in blob_list:
    print(blob.name)
    blob_client = blob_service_client.get_blob_client(container='data', blob=blob['name'])
    xd = blob_client.download_blob().readall()
    print("\t{} bytes".format(len(xd)))
python3 記録

##配列から数値に変換

```python
n = int(input())

a = input().split()

print(a)
for i in range(n):
    print(a[i])

```


```
print(a[i])
```
これでリストから対象の番号を参照して1つずつ表示してくれる

##任意の文字列を含むか判定: in演算子

```
a = input()
b = input()

if a in b:
    print("YES")
else:
    print("NO")
```
Ubuntu以外のディストリビューションで起動時のデフォルトユーザーを設定する。(WSL)

# 導入
備忘録用に記録しておきます。

Ubuntuはインストールした直後にsudoユーザーの作成プロンプトが表示され、それでユーザーを一度作ってしまえばそれがデフォルトユーザーになり、次回以降からubuntu wslを起動すると最初からそのユーザーでセッションが始まるわけですが。

microsoft storeにリリースされていないディストロでwsl環境を作成すると、デフォルトユーザーがrootで始まってしまって非常によろしくない。毎回 `su <username>` を打つのも精神衛生上よろしくない。

これをどうにかしたい、今回は Gentoo Linux on WSL2 でこの問題を解決していくとする。私はホモでせっかちなのですぐ下に結論を書いておいた。

# 結論
わたしは Gentoo Linux for WSL2を使用してるので、`Gentoo.exe`があるディレクトリまでcdコマンドで移動して以下のコマンドを打つだけで済んだ。**コマンドは Powershellで実行すること。**
*hogehogeは起動時に指定したいデフォルトユーザー名。

``` .\Gentoo.exe config --default-user hogehoge
```
Arch Linuxだったら `.\Arch.exe config --default-user hogehoge` で、ほかのディストロも exe のところだけ変えれば問題なくできると思う。

# 結論に至るまで試行錯誤
wsl のコマンドで設定できればいいのに、とは思ったがそれはできないらしい。

`wsl -d Gentoo -u hogehoge` 
上記のコマンドでGentoo WSLを起動し、 hogehoge ユーザーで実行できる。ならば

`wsl -s Gentoo -u hogehoge` 
これでデフォルトのWSLをGentooに設定しながらデフォルトのユーザーを hogehoge にできるのではないかと思ったができなかった。

そしてとある記事を見た。
https://hetarena.com/archives/2856

どうやらUbuntuでは `ubuntu config --default-user hogehoge` と打つだけでユーザーを変えられるらしい、このubuntuを置き換えればいけそうではないか？
結果うまくいった、といった感じだった。
Tomcat に SpringBootで作成したwarファイルをデプロイする

##Tomcatのルートディレクトリへ移動
```
cd opt/tomcat/latest
```
###tomcatのインストール方法

https://qiita.com/YuichiTanaka007/items/171e8fe2490d9d9bf59a

##Tomcatのルートディレクトリ確認
```
ls
```
|ディレクトリ|説明|
|----|----|----|
|bin|実行ファイル||
|conf|設定ファイル||
|lib|APIファイル（TomatのデフォルトAPI）||
|logs|ログファイル||
|temp|一時ファイル||
|**webapps**|**プログラムファイル(ここにファイルを作成)**||
|work|作業ファイル||

##RLoginでwarファイルの転送
【重要ポイント】
・ **webappsフォルダ直下にwarファイルを転送する。**
・ ファイル転送後、**tomcatが自動でwarファイルを展開し、ファイルと同名のプロジェクトディレクトリを生成してくれる。**
・ 転送プロトコル：SFTP(portは22番なので、追加設定は必要ない)

|プロトコル|略|ポート|備考|
|----|----|----|----|
|FTP|FileTransferProtocol|20 : FTPデータ転送ポート<br>21 : FTP制御ポート|キュリティ的な不具合が多い。|
|FTPS|File Transfer Protocol over SSL/TLS|989 : FTPデータ転送ポート<br>990 : FTP制御ポート|FTPの通信をSSL/TLSで暗号化 → FTPの拡張|
|SFTP|SSH File Transfer Protocol|22|SSHの通信を使って、FTPを行う → SSHで動作する|
参考
https://qiita.com/kasei-san/items/bf766e6c2ececa4c3905

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637823/f3734b91-6ed3-719f-1d73-1a6af3690d6d.png)

**右クリック>ファイルのアップロード** もしくは **ドラッグ＆ドロップ**操作が可能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637823/9a070017-e730-1c11-76fc-8dfad7caabb3.png)

##アクセスエラー Set Remote Cwd Error
「attr」（attribute）を確認して、その他ユーザーの権限がない場合発生する。

##パーミッション確認
```
ll
```
##パーミッション変更
```
chmod 777 対象
```
再帰的に変更する場合はRオプションをつけること。

【検索用】
権限

参考

https://qiita.com/YuichiTanaka007/items/2ea800053c841553c2fa

## warファイル転送後
tomcatが自動でwarファイルを展開し、ファイルと同名のプロジェクトディレクトリを生成してくれる。


https://blog.cosnomi.com/posts/1395/
https://qiita.com/NagaokaKenichi/items/3f191aeb6f161101d5f6
https://searchman.info/java_eclipse/1030.html
Node.js: コマンドラインオプション--preserve-symlinksの挙動

https://nodejs.org/api/cli.html#cli_preserve_symlinks

- `--preserve-symlinks`なし（デフォルト）の場合
    - シムリンクファイルから`require(相対パス)`すると、実体ファイルからの相対パスになる
- `--preserve-symlinks`ありの場合
    - シムリンクファイルから`require(相対パス)`すると、シムリンクからの相対パスになる

公式ドキュメントに書いてある通り、たいていの場合は「なし」（デフォルト）のままでうまくいくと思う。

## 例1
```
.
├── a.js    // require("./b")
├── b.js -> sub/b.js
└── sub
    ├── b.js    // require("./c")
    └── c.js
```

`--preserve-symlinks`なし（デフォルト）の場合

```console
$ node a.js
=> OK
```

`--preserve-symlinks`ありの場合
./c.jsを読みに行こうとしてエラー。

```console
$ node --preserve-symlinks a.js
internal/modules/cjs/loader.js:892
  throw err;
  ^

Error: Cannot find module './c'
```

## 例2

（ファイルの内容は例１と同じ）

```
.
├── a.js    // require("./b")
├── b.js -> sub/b.js
├── c.js -> sub2/c.js
├── sub
│   └── b.js    // require("./c")
└── sub2
    └── c.js
```



`--preserve-symlinks`なし（デフォルト）の場合
./sub/c.jsを読みに行こうとしてエラー。

```console
$ node a.js
internal/modules/cjs/loader.js:892
  throw err;
  ^

Error: Cannot find module './c'
```

`--preserve-symlinks`ありの場合

```console
$ node --preserve-symlinks a.js
=> OK
```
Pythonファイルをexe化する


pyinstallerを使うとexeに変換できる。
WindowsでPythonがインストールされてない場合はexeじゃないと動かない。


```
pip install pyinstaller
```


```
pyinstaller sample.py --onefile
```

プロンプトを出したくない場合
sample.pyをsample.pywに拡張子を変更。

```
pyinstaller sample.pyw --onefile
```



# 参考

https://leez.info/archives/4818


https://qiita.com/takanorimutoh/items/53bf44d6d5b37190e7d1
Laravelの勉強用備忘録[コマンドリスト]

#初めに
Laravelでよく使うコマンドをリスト化しました。
載ってない分もあると思うので参考程度に。
※随時追加します。
#コマンド一覧

##Laravelの機能確認

###コマンド一覧表示

```
php artisan list
```

###バージョン確認

```
php artisan --version
```

もしくは

```
php artisan -V
```

###mixのインストール

```
npm install
```

###mixの実行(コンパイル)

```
npm run dev
```

###デバッグバーのインストール

```
composer require barryvdh/laravel-debugbar
```

###マイグレーション

####作成

```
php artisan make:migration create_[テーブル名]_table --create=[テーブル名]
```


####削除
```
php artisan migrate:reset
```

####実行

```
php artisan migrate
```

####全部ロールバックしてからマイグレーションし直す
```
php artisan migrate:refresh
```

####一旦全てのテーブルを削除してマイグレーションし直す
```
php artisan migrate:fresh
```

###seederの実行
```
php artisan db:seed
```

###モデル作成
```
php artisan make:model [モデル名]
```

###バンドルのインストール
```
composer update
```

### npm自体のアップデート
```
npm install -g npm
```

### npmインストール
```
npm install
```

### シンボリックリンク
```
php artisan storage:link
```

#参考サイト
- [Laravel artisanコマンドメモ](https://qiita.com/zaburo/items/37768b743ed6d0e28bf5)
- [Laravelコマンド一覧](https://qiita.com/krs91tk/items/d816e02b667a306d696f)
- [PHP(Laravel)入門者のための要点まとめ](https://qiita.com/yyokii/items/c7c98d467239dda2a59d)
【2枚目】おっさんが入門CakePHP　(動画第３回)

<B>第3回：CakePHPインストール【環境構築】</B>
https://www.youtube.com/watch?v=pg6Ih-eIKXg

フレームワークのインストールですが動画見ていくと、
phpが動くか？まで確認するようです。
XAMPP入れた後何もしてないので
phpにpathが通っているはずもなくpathの設定手順まで説明してくれています。
Apacheのconfigを変更して再起動するとブラウザで確認できます。
![PHP_home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102625/0fe0ba13-5522-d066-10b9-a9e872b5d3f7.png)


5年ほど前にcake使ったときは一個づつ入れてた気がするんだけど
今回はcomposerを使うようです。
![composer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102625/6ab367d0-204f-8781-e07c-6d48a3e230ca.png)

ダウンロードするのだけど、URLはYouTubeの概要に書いてあってコピーするだけ
概要、こんな使い方あるのね。
Composerインストール用のアドレス
``` https://getcomposer.org/Composer-Setup.exe ```
ダウンロード済んだらインストール。

composerのコマンドでCakephp3をインストールするのだけど、これも概要からのコピペ。

```
 composer create-project --prefer-dist cakephp/app:^3.8 cake-project 
```

インストール済んだらアパッチのhttpd.confのDocumentRootを修正

```DocumentRoot "D:\work\src\php_src\cake-project\webroot"
<Directory "D:\work\src\php_src\cake-project\webroot">　```

アパッチ再起動してcakeを確認。
![cake.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102625/e0df3e50-0f87-398f-64fb-53910e50d04e.png)

今回XAMPPコントロールパネルを使ったけど便利ね。。。

動画見ながら手動かした感想だけど、細かいところの説明は省略してドンドン前に進めるのは初心者向けで良いと思う。
動画一本短いので昼休みとかちょっとした時間でも勉強進められるの便利かもしれない。
【C#】＜If文＞初心者学習メモ

##書いた理由
* 自己学習のメモ用
* 考え方や使い方のストックのため
<br>
<br>
<br>
<br>


```C#:if文
            for (int i = 0; i < 15; i++) {
                Console.Write("{0} ", i);
                if (i % 5 == 4) {                   //もしiを5で割って4が余ったら
                    Console.WriteLine("");          //改行します。
                }
            }
```
```結果:結果
0  1  2  3  4 
5  6  7  8  9 
10 11 12 13 14
```
<br>

##なぜこの一文なのか
例えば「２の倍数の時に○○させる」などは、よく「％」表記を使って

`if (i % 2 == 0)`

などを見かけてはいました。
しかし、余りを使う条件式を見たことがなく、
今回見た時になるほど…と思ったため学習メモに残します。
<br>

＊＊補足メモ＊＊
int i = 0; とした条件なら、
if (i % 改行させたい列の番号 == 改行させたい列の番号 - 1)
という捉え方もできるなと思いました。