OmniAICreator/Qiita-1.07M huggingface dataset:
Firebaseを使わずにブラウザ上でローカル画像をリサイズ【canvasのdrawImage()をReactで利用した方法】

FileReaderを使ってローカルにある画像をアップロードさせる機能の作り方を実装します。


この記事をベースにした別記事も用意しています
準備中：Firebaseを使わずにブラウザ上でローカル画像のサイズをリサイズする new Image() のcanvasを利用した方法


## 完成品
![スクリーンショット 2021-05-07 11.11.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651103/d3f220e1-bda1-2d0c-65f6-1fb8ec4278e2.png)
ソースコード：https://codesandbox.io/s/react-img-upload-e4q8s?file=/src/App.js

無駄な要素は極力はぶいた簡素なアップローダーにしました。

## FileReaderを使って実装

```imgUploader.jsx
import { useState } from "react";
import "./styles.css";

const App = () => {
  const [uploadImg, setUploadImg] = useState("");

  const handleUploadImg = (e) => {
    if (!e.currentTarget.files || e.currentTarget.files.length === 0) return;

    const fileReader = new FileReader();
    const file = e.currentTarget.files[0];
    if (file.type !== "image/jpeg" && file.type !== "image/png") return;

    fileReader.onloadend = () => {
      setUploadImg(fileReader.result);
    };
    fileReader.readAsDataURL(file);
  };

  return (
    <div className="App">
      <h1>React画像アップロード</h1>
      <input type="file" onChange={(e) => handleUploadImg(e)} />
      <div style={{ margin: "10px" }}>
        <img
          src={uploadImg}
          alt="アップロード画像"
          style={{ maxWidth: "200px" }}
        />
      </div>
    </div>
  );
};

export default App;
```

### JSXエレメントの解説

```
省略
     <input type="file" onChange={(e) => handleUploadImg(e)} />
省略
```
上記のように input の属性 file に指定して onChange で画像を選ばれた後に関数が走るようにしておきます。



```
省略
        <img
          src={uploadImg}
          alt="アップロード画像"
          style={{ maxWidth: "200px" }}
        />
省略
```
src={} の中身には uploadImg の state を入れておきます。 state は onChange の中の関数（handleUploadImg）で変化させます。


### handleUploadImgの解説

```handleUploadImg.jsx
  const handleUploadImg = (e) => {
    if (!e.currentTarget.files || e.currentTarget.files.length === 0) return; //ファイルが存在しない状態ならそのまま離脱

    const fileReader = new FileReader();
    const file = e.currentTarget.files[0];

    if (file.type !== "image/jpeg" && file.type !== "image/png") return; //ファイル形式が jpeg, png 以外なら離脱

    fileReader.onloadend = () => {
      setUploadImg(fileReader.result); //resultの中にblob形式の画像データとして画像が格納されているのでそれをイメージ画像として読み込む
    };
    fileReader.readAsDataURL(file); //new FileReader()インスタンスの readAsDataURL() メソッドを使ってアップロードしたファイルをそのまま読み込ませて fireReader.onloadend を走らせ fileReader.result の中身を取り出す
  };
```


以上のように簡単に実装することができます。
HTTP通信について

## はじめに

フロントエンド開発を学んでいくにあたって、普段何気なく利用しているHTTP通信についてちょっとだけ調べてみました。（以下ざっくり解釈である旨ご了承ください。。）

## HTTP通信

**HTTP(Hyper Transfer Protocol)** はHTMLや画像、css、jsファイルなどを転送するためのプロトコル、つまり、決まりごとのひとつで、サーバーとクライアント（ブラウザなど）との通信に利用されています。  
以下、主にブラウザでページを表示する場合を想定した流れとなりますが、ブラウザとサーバーとの通信にはリクエストとレスポンスという組み合わせでやり取りを行っていて、  

- クライアントからリクエストを送る
- サーバーがリクエストを受け取る
- 受け取ったリクエストに対してレスポンスをクライアントに送る
- クライアントがレスポンスを受け取り表示する

といった一連の流れを繰り返してページを表示しています。

## リクエストとレスポンス

リクエストは、

- HTTPメソッド（GET、POST、DELETEなど）
- パス（/hoge/index.htmlなど）
- HTTPプロトコルのバージョン（HTTP/1.1など）
- 任意のヘッダー情報（API認証keyなど）

で構成されており、
レスポンスは、

- HTTPプロトコルのバージョン（HTTP/1.1など）
- ステータスコード（200、404など）
- ステータスメッセージ（OKなど）
- ヘッダー
- 結果のファイルの中身など

で構成されています。

## ステータスコード

ステータスコードには、成功時の200やページが見つからない時の404がありますが、下記サイトでステータスコードとその結果を実際に試すことができます。

https://httpstat.us/

## さいごに

実際のフロントエンド開発では、これらに加えて、HTTP通信のやり取りの中で、キャッシュやCORS、認証やセッションといった技術・知識も必要になってきます。
まだまだ学ぶことはたくさんありそうです。。。

## 参考情報

https://developer.mozilla.org/ja/docs/Web/HTTP
Laravelキューでのメール送信時に任意の言語設定を反映させる

#はじめに
メール本文の言語設定を画面と揃えたい場合と、固定したい場合があったので備忘録として残しておきます。


#セッションに格納されているlocaleを使用したい場合
```php
Mail::to($to)->locale(session('locale'))->queue($mail_object);
```
session('locale')の部分は環境に合わせて置き換えてください。


#固定したい場合
```php
Mail::to($to)->locale('en')->queue($mail_object);
```
そのままです。


#参考

https://readouble.com/laravel/7.x/ja/mail.html
【Rails】Rails5のアプリでES6の構文を使用し，Herokuにデプロイする場合


## はじめに
Rails5アプリをHerokuにてのデプロイ作業を行っていた時に`Uglifier::Error: Unexpected token:~`というエラーが発生した時に解決させた方法を記載して行きます。

![スクリーンショット 2021-05-07 12.56.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859347/e6c06010-56d6-bb67-0e29-a9a9690068de.png)


## 環境
* Ruby2.6.6
* Rails 5.2.4

## エラー内容
```ruby
remote:  !
remote:  !     Precompiling assets failed.
remote:  !
remote:  !     Push rejected, failed to compile Ruby app.
remote: 
remote:  !     Push failed
remote: Verifying deploy...
remote: 
remote: !   Push rejected to golfmatch.
remote: 
To https://git.heroku.com/golfmatch.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/アプリ名'
```

`Precompiling assets failed.`
プリコンパイルとはコンパイルする為にの事前処理（機械側が理解できる内容に処理）
とりあえずファイルの読み込みができませんと言うわれています。^^;

どこで処理が止まっているのかログを辿って行くと、

```ruby
rake aborted!
remote:        Uglifier::Error: Unexpected token: punc ()). To use ES6 syntax, harmony mode must be enabled with Uglifier.new(:harmony => true).
```

「ES6を使うにはUglifier.new(:harmony => true)でharmony modeを有効にしてね」とのエラー内容です。

なので、


## 解決策


```:config/environments/production.rb
config.assets.js_compressor = :uglifier

↓  以下に変更

config.assets.js_compressor = Uglifier.new(harmony: true)

```

本番環境の設定ファイルを変更してあげれば無事でデプロイができました！＾＾


## 終わりに

解決まで無事辿り着けたのもしっかりログを確認できたことでした！
文字の羅列がダーっと流れると読むのに嫌気が感じると思いますが、
*ここです！ rake aborted!*と記してくれているので、
見つけたら解決までそう時間はかからないと思います！
あと解決できると楽しいですしね＾＾

herokuデプロイにて困っている方の解決案になれば幸いです！
ありがとうございました！😊
【JavaScript】1から100までの整数に対し、  3で割り切れる場合は「Fizz」 5で割り切れる場合は「Buzz」 3でも5でも割り切れる場合は「FizzBuzz」 上記以外は数値そのまま を表示。 ※どの繰り返し処理を利用するかは自由。

```javascript
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8">
   <title>FizzBuzz</title>
</head>
<body>
<script>
        var i = 0;
        while (i <= 100) {
          i++;
            if (i % 3 === 0 && i % 5 === 0){
            document.write('<p>FizzBuzz【' + i +  '】3でも5でも割り切れる</p>');
            } else if (i % 3 === 0) {
            document.write('<p>Fizz【' + i +  '】3で割り切れる</p>');
            } else if  (i % 5 === 0){
            document.write('<p>Buzz【' + i +  '】5で割り切れる</p>');
            } else {
            document.write('<p>' +i+ '</p>' );
            }
          }
</script>
</body>
</html>
```

※3と5の倍数である「15の倍数」のときは

"FizzBuzz"のみを表示して

"Fizz"及び、"Buzz"及び、数値を表示してはならない


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954863/8455154b-59d2-4e59-46bc-bec4b4e6e289.png)
かわいい日本語音声合成（Tacotron2 + WaveGlow + CycleGAN-VC2）

ゴルシウィークの課題として音声合成に挑戦してみました。
ぶっちゃけ元論文もモデルの中身もわけわかめですが、ありものを組み合わせるだけである程度のものが作れました。
実装してくれてる神々、情報をまとめてくださってる神々には、頭が上がりませんね。
神は存在します。ネットで見た。

あと、皆さんご存知かと思いますが、

https://colab.research.google.com/notebooks/intro.ipynb?hl=ja

も神サービスでしたね。

なんにも知らなかったので普通にGCEで借りたGPUマシンぶん回して愚かにも8000円溶かしましたね。
流石にColab Proより1.5倍くらい早かったですが。

## できたもの

https://twitter.com/sutsurumu/status/1390683943863603201

https://twitter.com/sutsurumu/status/1390520487692828675

## どうやったか

### 入力データ

https://sites.google.com/site/shinnosuketakamichi/publication/jsut

https://github.com/PKSHATechnology-Research/tdmelodic

https://github.com/espeak-ng/espeak-ng

JSUTをmecab + tdmelodicでカタカナとピッチ情報にして、espeak-ngで下処理しました。

例)

```
便利屋は、一月と二月はわりあい暇だ。
↓ mecab + tdmelodic
ベ%]ンリヤワ イ%[チ%]ガ%]ツト ニ%]ガ%]ツワ ワ%[リアイヒ%[マダ.
↓ espeak-ng
bˈe̞↘nɽijˈäwä ˈi↗tɕˈi↘ɡˈä↘tsˈɯᵝto̞ nˈi↘ɡˈä↘tsˈɯᵝwä wˈä↗ɽˌiäʼˈiçi↗mˈädä.
```

CycleGAN-VC2には、委員長の雑談配信の声データをつっこみました。

ffmpegで無音期間で切り取り、

https://github.com/deezer/spleeter

で音声のみ抽出しました。

ffmpegのコマンドは以下を参考にしました。

https://stackoverflow.com/questions/36074224/how-to-split-video-or-audio-by-silent-parts

### モデル

https://github.com/NVIDIA/tacotron2

https://github.com/NVIDIA/waveglow

https://github.com/jackaduma/CycleGAN-VC2

上記3つを組み合わせただけです。

## くふうポイント

### カスタマイズしたIPA(International Phonetic Alphabet)をTacotron2の入力にした

先駆者の神々は日本語のローマ字を入力にしてましたが、あえてIPAにしてみました。
英語で学習済のモデルから転移学習？できなくて泣いた。

### IPAにピッチアクセントと母音同士がくっつかないことを表す記号を追加した

カスタマイズしたespeak-ngがこちら。
https://github.com/sujoyu/espeak-ng

加えて、dictsource/ja-extraに以下のテキストを保存します。

```
.group %
  %[   _b
  %]   _e
```

### 音声に文章情報を付加する作業はやりたくなかったので、CycleGAN-VC2を使った

神々、苦労を厭わなすぎて自分には無理だったので、変換機を噛ませました。

### Tacotron2はMozilla TTS実装ではなくNVIDIA実装を使った

https://github.com/mozilla/TTS

は自分のカスタマイズの仕方が悪かったのか、15000ステップあたりでLossが跳ねて、そのあとLossがNaNだよエラーを吐くようになってしまったので、諦めました。
10000ステップあたりではMozilla実装のほうがはっきり発音していたので、学習率の調整が必要だったのかもしれません。わかりませんが。

## 参考になる神記事

https://qiita.com/tset-tset-tset/items/7b388b0536fcc774b2ad

https://medium.com/@crosssceneofwindff/%E7%BE%8E%E5%B0%91%E5%A5%B3%E5%A3%B0%E3%81%B8%E3%81%AE%E5%A4%89%E6%8F%9B%E3%81%A8%E5%90%88%E6%88%90-fe251a8e6933

https://qiita.com/K2_ML/items/2804594454b39180c909

https://tosaka-mn.hatenablog.com/entry/2020/02/13/215656

https://note.com/npaka/n/n8c94da051c68

## 感想

https://coefont.studio/

さすがにこちらには敵いませんでしたね...
Intel C++, Intel MPIでOpenFOAM 8をビルド

# 環境
IntelコンパイラとMPIが無料で使えるようになったので（詳細は検索してください），この組み合わせでOpenFOAM 8をビルドします。OSはCent OS 7です。

# 設定
Intelコンパイラとかはインストールしたとします。ここではホームの下に入れてます。
OpenFOAMのソースはGithubからクローンしてきます。
git clone https://github.com/OpenFOAM/OpenFOAM-8.git

ThirdPartyは公式からダウンロードします。
http://dl.openfoam.org/third-party/8

## etc/bashrc
コンパイラとMPIを変更。

```diff
 #- Compiler:
 #    WM_COMPILER = Gcc | Gcc48 ... Gcc62 | Clang | Icc
-export WM_COMPILER=Gcc
+export WM_COMPILER=Icc

#- Memory addressing:
@@ -86,7 +86,7 @@ export WM_COMPILE_OPTION=Opt
 #- MPI implementation:
 #    WM_MPLIB = SYSTEMOPENMPI | OPENMPI | SYSTEMMPI | MPICH | MPICH-GM | HPMPI
 #               | MPI | FJMPI | QSMPI | SGIMPI | INTELMPI
-export WM_MPLIB=SYSTEMOPENMPI
+export WM_MPLIB=INTELMPI
```

## etc/config.sh/compiler
Iccの情報を追加。

```diff
@@ -63,6 +63,12 @@ OpenFOAM | ThirdParty)
         export WM_CXX='clang++'
         clang_version=llvm-3.7.0
         ;;
+    Icc)
+    export WM_CC='icc'
+    export WM_CXX='icpc'
+    ;;
+
     *)
```

## etc/config.sh/mpi
MPI_ROOTをインストールしたMPIに設定。


```diff
@@ -232,7 +232,9 @@ INTELMPI)
   　 # No trailing slash
     [ "${MPI_ROOT%/}" = "${MPI_ROOT}" ] || MPI_ROOT="${MPI_ROOT%/}"

+    export MPI_ROOT=$HOME/intel/oneapi/mpi/2021.2.0
     export FOAM_MPI="${MPI_ROOT##*/}"
```

これで./Allwmakeすればビルドできるはず。

Paraviewは環境によって，新しいバージョンが起動しなかったりするので，古いやつにしたりするほうがいいかもしれません。その場合はParaviewのソースをThirdPartyにダウンロードします。バージョンはetc/config.sh/paraviewで設定します。

# エラーしたとき
## Catastrophic error: could not set locale "" to allow processing of multibyte characters　ってなったとき

https://www.cdslab.org/paramonte/notes/troubleshooting/catastrophic-error-could-not-set-locale/
これによると，コンパイルオプションに-no-multibyte-charsをつければいいとある。
wmake/rules/linux64IccのなかのcOpt， c++Optをそれぞれ以下のようにする。

```c:cOpt
cDBUG       =
cOPT        = -O3 -no-multibyte-chars
```

```c:c++Opt
c++DBUG     =
c++OPT      = -O3 -no-multibyte-chars
```
ColdFusion コンポーネント使い方

# ColdFusion コンポーネント使い方
cfcにDBの作業や、if等の分岐作業をまとめておく。
その際のcfcomponentの使い方。

## cfmで使う側

- cfinvoke cfcのどのfunctionを使うか指示する
    - method   cfcのfunction要素
    - component　cfcのファイル名
    - returnVariable　戻り値を受け取る名前
- cfinvokeargumentで渡したい引数を準備する（ないならなし）
    - form送信した内容をusernameに入れて引数で渡している。

```html
<!---ユーザ追加のデータ渡す--->
    <cfif isDefined("form.action") and form.action is "add">
        <cfinvoke  method="createuser" component="login_function" returnvariable="message">
            <cfinvokeargument  name="username"  value="#form.username#">
            <cfinvokeargument  name="password"  value="#form.password#">  
        </cfinvoke>
        <cfoutput>#message#</cfoutput>     
    </cfif>

    <h2>ユーザの追加</h2>

    <form action="<cfoutput>#cgi.script_name#</cfoutput>" method="post">
        <input type="hidden" name="action" value="add">
        ユーザー名：<input type="text" name="username" size="20"><br>
        パスワード：<input type="password" name="password" size="20"><br>
        <br>
        <input type="submit" value="追加">
    </form>
```

---

## cfcで作業する側

- cfcomponent　コンポーネントはまとめて1つでOK
    - 名前を付けても多分使わない。cfmで使う名前はファイル名 login_function.cfcを使うので。
- cffunction
    - name　cfmで付けた名前で
    - access　remote/public/private…
    - returntype　戻り値の型。 **複数⇒struct、DB参照の結果⇒query**
- cfargument　引数の受け取り（ないならなし）
    - name　名前を付ける。cfmと一緒の方が分かりやすい
    - type　型
    - required　引数の受け取りが必須かどうか
- cfreturn 戻り値（ないならなし）
    - 返したいものを記入する。DBの結果ならcfqueryにつけた名前。

```html
<!---ユーザの追加--->
<cfcomponent>
    <cffunction  name="createuser" access="remote" returntype="string">
        <cfargument  name="username" type="string" required="true">
        <cfargument  name="password" type="string" required="true">
    
    <cfquery datasource="sample" name="adduserck">
    select *
    from accounttable
    where username = '#arguments.username#'
    </cfquery>

    <cfif adduserck.recordcount gt 0>
        <cfset message = "#arguments.username#様は既に存在しているため登録できません">
        <cfelse>

        <cfquery datasource="sample" name="useradd">
        insert into accounttable values (
            '#arguments.username#', '#encrypt(arguments.password, "aaa")#',null,null,null,0,0,null,0,null
        )
        </cfquery>
        <cfset message = "#arguments.username#様を追加しました">
    </cfif>
    <cfreturn message>
</cffunction>
</cfcomponent>
```
SafariだけにCSS適用するためのmixinを作りました

最近ちょくちょく書くことがあり、どうせならmixin書いたほうが早いやとなったので。

```scss:mixin.scss
@mixin safari {
  @at-root _::-webkit-full-page-media, _:future, :root & {
    @content;
  }
}
```

```scss:main.scss
.selector {
  background-color: yellow;
  @include safari {
    background-color: pink;
  }
}
```

↑みたいに書くと、↓にコンパイルされます

```css:main.css
.selector {
  background-color: yellow;
}

_::-webkit-full-page-media, _:future, :root .selector {
  background-color: pink;
}
```
OpenFOAM 8をIntel C, MPIでビルドしようとしたらptscotchがないって怒られる

# エラー
OpenFOAM 8をIntel CとIntel MPIでビルドしたら，

```
cannot open source file "ptscotch.h"
```

って出て，ビルドが止まる。

# 対応
MPIの設定の書き方が悪かった。

OpenFOAM-8/etc/config.sh/mpi
のINTELMPIのところにIntel MPIのパスを追加する必要があるが，

```
export MPI_ROOT=$HOME/intel/oneapi/mpi/2021.2.0
```

って書けばよかった。

最初以下にしていて，だめだった。

```
export MPI_ROOT=$HOME/intel/oneapi/mpi/2021.2.0/
```

パスの最後に/があるとだめ。

同じエラーは古いバージョンだと割と起きていた。
参考　https://www.cfd-online.com/Forums/openfoam-installation/173590-failed-compile-openfoam-3-0-1-icc.html

設定ファイルもこなれてきて，最近だとそうそう起きないが，パスの書き方がだめだったってのはなかなか原因がわからず，ハマった。
ハマったメソッド覚書_アラフィフGAS初心者が業務効率化

#GASを書いているときにハマったことを書いていきます#
見つけたら記載していくので都度、更新していきます。

##Google Drive##
###メールの添付ファイルを名前を付け替えてドライブに保存したかった###

FolderクラスのcreateFile( )を見ると
同じ記載のメンバーで引数が違うものがありました。

||メンバー|説明|
|:-----------|:------------|:------------|
|(1)|createFile(blob)|blob用（同時に名前は指定できない）|
|(2)|createFile(name,content[,mimeType])|文字列用|

####blob？####
blobを見たことがなかったので、なんとなく（2）かなぁと思ったのですが、結果的には（1）でした。

blobとはファイル変換のために利用されるクラスのようです。
ちなみに（2）でファイル名を指定して添付ファイルをコンテンツとして作成してみると、ドライブから開く際に拡張子の形式に変換されずにエラーがおきました。
この（2）はテキストファイルの作成に使うようです。
ドライブのフォルダ内に名前と内容を同時に指定してファイルを作成できるのはテキストのみです。

(1)を使ってフォルダ内に添付ファイルを保存するには以下になります。
まずフォルダに保存して、それから名前を変更するので、3行必要になります。

```添付ファイルを保存する.gs
var store_folder = DriveApp.getFolderById('フォルダIDを入れる');

store_folder.createFile(attach[0]);
 
/*名前を付け替えたい場合は以下も必要*/
var file = store_folder.getFilesByName(attach[0].getName());
file.next().setName('新しい名前.拡張子');
```
TypeScriptでもJestのDateをmockする

この記事だとこうしてる

https://qiita.com/clown0082/items/bbe42001c31be5a87c04

```javascript
const mockDate = new Date(1594374371110)
const spy = jest.spyOn(global, "Date")
                .mockImplementation(() => mockDate)
```

でもTypeScriptだと「型 '() => Date' の引数を型 '() => string' のパラメーターに割り当てることはできません。型 'Date' を型 'string' に割り当てることはできません。ts(2345)」と言われる。

のでこうする

```typescript
const mockDate = new Date(1594374371110);
const spy = jest.spyOn(global, 'Date')
                .mockImplementation(() => (mockDate as unknown) as string);
```

動いてるからヨシ！
【Ruby】投稿一覧の表示の順番を変更する

#概要
投稿アプリを作成している時、投稿が表示される順番を変えたい時ってありますよね。
その際、「新しい順の投稿一覧」を表示する場合と「古い順の投稿一覧」を表示する場合の方法を記載しておきます！

#環境
ruby 2.6.5
Rails 6.0.3.5

#「新しい順の投稿一覧」

```ruby:controllers>comments.controller.rb
class CommentsController < ApplicationController
  def index
    @comments = Comment.all
  end
```

@comments = Comment.allと記載がある後ろにorder(created_at: :desc)を書きます。
(allは記述しなくて平気です)

```ruby:controllers>comments.controller.rb
class CommentsController < ApplicationController
  def index
    @comments = Comment.order(created_at: :desc) #created_atは作成日時　descは降順
  end
```
これで完了です。新しい投稿が上から表示されます！

#「古い順の投稿一覧」

```ruby:controllers>comments.controller.rb
class CommentsController < ApplicationController
  def index
    @comments = Comment.order(created_at: :asc) #created_atは作成日時　ascは昇順
  end
```

これで完了です。古い投稿から表示されます！

#まとめ

```ruby
#新しい順の投稿一覧
order(created_at: :desc) #created_atは作成日時　descは降順
#古い順の投稿一覧
order(created_at: :asc) #created_atは作成日時　ascは昇順
  
```
郵便番号や住所情報について

# 概要
郵便番号や住所情報の正規化をしたくて公式データを探しました。
ググればすぐわかることだけど、公式データは意外に見つかりづらいから、最終的なオフィシャルローデータの場所をログ化しておこうと思います。

# 郵便番号

https://www.post.japanpost.jp/zipcode/dl/oogaki-zip.html

CSVなら、「都道府県一覧」項目内の沖縄県の右「全国一括」がフルデータ。都道府県別ならそれぞれのCSVを。
なおフリガナもあるが、すべて「半角カナ」になっているため、カナを全角で扱いたい場合は苦労する。

追記：20210507
なお以下に加工済みデータ。

http://zipcloud.ibsnet.co.jp/

こちらのほうが使いやすいな。

# 都道府県および住所情報

https://www.e-stat.go.jp/municipalities/cities/areacode

全都道府県チェック(多分デフォルトON)
都市区分の別で、「市・区・郡・町・村」の5つにチェック入れればフルデータ。
カラム的には空白があったりするので、利用の際は一部分の整形が必要そう。

## 余談
こんなん何度も調べたくないわ。

なおテーブルのカラム名としては、

https://www.japan-guide.com/e/e2224.html

にそれっぽい英文字が書いてあるのでこれをベースにするといいかも(と思った)。
`npm install --save-dev @prisma/cli` でエラー

備忘録

# 結論

```yarn版

# @prisma/cli をアンイストール

yarn remove @prisma/cli

# prisma をインストール

yarn add prisma --dev

# prismaをついでにインストール

yarn add @prisma/client
```

`yarn add @prisma/cli ` が非推奨になり、
`yarn add prisma --dev ` が推奨されるようになりました。

```npm版
# @prisma/cliをアンイストールする。
npm uninstall @prisma/cli
# prismaをインストールする。
npm install prisma --save-dev
# prismaをついでにインストール
npm install @prisma/client

```



```
Output:
┌───────────────────────┐
│                                                                       │
│     The package @prisma/cli has been renamed to prisma.   │
│                                                                        │
│     Please uninstall @prisma/cli first.                      │
│     Then install prisma to continue using Prisma CLI: │
│                                                                       │
│         # Uninstall old CLI                                      │
│         yarn remove @prisma/cli                              │
│                                                                        │
│         # Install new CLI                                         │
│         yarn add prisma --dev                                 │
│                                                                        │
│         # Invoke via npx                                         │
│         yarn prisma --help                                      │
│                                                                        │
│     Learn more here: https://github.com/prisma/prisma/releases/tag/2.16.0   │
│                                                                         │
└───────────────────────┘


```

ちょっと古い記事だと
`npm uninstall @prisma/cli`のままなのが結構あるので検索用として残します。



# 起こった問題

```
npm install --save-dev @prisma/cli
npm i -D @prisma/cli
yarn add @prisma/cli
```

のどれかでインストールすると


```***err.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @prisma/cli@2.20.1 preinstall: `node scripts/preinstall-entry.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @prisma/cli@2.20.1 preinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\hi\AppData\Roaming\npm-cache\_logs\2021-05-07T03_05_47_308Z-debug.log
```

とエラーが出る

# 原因
`@prisma/cli`の名前がバージョンアップに伴い`prisma`に変更されました。
Bootstrap 5 と smooth-scroll.js の相性が悪かった話

# どのような現象になるか

Bootstrap5 と smooth-scroll.js （など、おそらく JavaScript を使ってのスムーズスクロール全般に言える可能性がある）を導入すると、スクロールが ”つっかかる” 動きになりました。（Chrome,Edge で確認。その他未確認。）

Bootstrap4 ではそのような動きでなかったため、どの部分で相性が悪いのかと探っていたら、Bootstrap5では、しれっと、CSSでスムーズスクロールを実現する、` scroll-behavior: smooth;` が入ってい
やがり
ました。

https://getbootstrap.jp/docs/5.0/migration/#reboot

# ひとまず こうやることで回避
Bootstrap 5 の CSS から、以下が省かれていれば良いってことになるはずです。

```css
@media (prefers-reduced-motion: no-preference) {
  :root {
    scroll-behavior: smooth;
  }
}
```

せいぜい上記部分なので、ダウンロードしたCSSを直接編集でも大丈夫かと思いますが、カスタマイズのやり方は以下などにて。

https://getbootstrap.jp/docs/5.0/customize/options/


# 結論
素直にCSS `scroll-behavior: smooth;` を導入しましょう！

https://github.com/cferdinandi/smooth-scroll

smooth-scroll.js のgithubを確認すると、「DEPRECATION NOTICE」 つまり 「廃止の通知」となっていて、CSSで導入したほうが良いよ、みたいな事が書いてありました……

## ヘッダサイズの調整について
CSS `scroll-margin-top` で調整しましょう。
こんな感じ。

```css
html, body {
  scroll-padding-top: 60px;
}
```


ヘッダのサイズを自動で取得してくれるんで、js の方が楽ちんなんだけどなぁ。


bootstrap5 でヘッダサイズ算出機能やスピード調整などもあると良いですね。（あるかも知れないですね）

### safari ブラウザについて
知らない子にしちゃおう…
M1 mac上のDockerでWordpressの環境構築

## 概要

M１Mac上でDockerを動かすのに少し躓いたので備忘録として残しておきます。

今回はDockerをM1 Macで動かすことを簡単にテストしたいだけですのでwordperssで試してみることにします。

## 準備

デフォルトのままだと

```
ERROR: no matching manifest for linux/arm64/v8 in the manifest list entries
```
と怒られてしまうのでdocker imageをamd64に対応させます。

```
docker pull --platform linux/amd64  mysql:5.7
```

## 実際のコード

``` docker-compose.yml

version: "3"
services:
  mysql000ex11:
    image: mysql:5.7
    networks:
      - wordpress000net1
    volumes:
      - mysql000vol11:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: myrootpass
      MYSQL_DATABASE: wordpress000db
      MYSQL_USER: wordpress000kun
      MYSQL_PASSWORD: wkunpass
  wordpress000ex12:
    depends_on:
      - mysql000ex11
    image: wordpress
    networks:
      - wordpress000net1
    volumes: 
      - wordpress000vol12:/var/www/html
    ports:
      - 8085:80
    restart: always
    environment:
      WORDPRESS_DB_HOST: mysql000ex11
      WORDPRESS_DB_NAME: wordpress000db
      WORDPRESS_DB_USER: wordpress000kun
      WORDPRESS_DB_PASSWORD: wkunpass
     
networks:
  wordpress000net1:
volumes:
  mysql000vol11:
  wordpress000vol12:

```

## まとめ
wordpressをDockerで環境構築する人はあまりいない（普通契約したサーバーで全部やってくれる）のであまり参考にはならないと思いますが、少しでも誰かのお役に立てれば幸いです。
掌田 津耶乃著『Android Jetpack プログラミング』の歩き方（Section3-4)　アラートダイアログを利用するのactivity_main.xmlについて補足

#1. はじめに
　掌田 津耶乃著『Android Jetpack プログラミング』(以下、本書と言う）で勉強しています。この本は、著者が記述しているように入門書ではないようです。それゆえ、本書をしっかりと読み込んでいないと、記載されているソースコード通りに写経しても、エラーで弾かれることがあります。本レポートでは、「『Android Jetpack プログラミング』の歩き方」と題して、[掌田 津耶乃著『Android Jetpack プログラミング』の歩き方（Section3-1)](https://qiita.com/guijiu/items/bcfa8fb666a4f159c15c)に引き続き、ソースコードどうりに写経してアプリが正常に動くようにするための注意点をレポートします。記述や考え方などに誤りがあれば、ぜひご教示いただきたいと思います。

#2. 注意点
#2.1　リスト3-21のactivity_main.xmlについて、
　本書p188のリスト3-21を写経する際、リスト3-19を元に写経（コピペ？）をすると思いますが、<Button>タグの中にある、onClickの行は不要になると思われますので削除しましょう。また、レイアウトが崩れるので、app:layout_constraintTop_toBottomOf="@+id/text1"と変更しましょう。最終的には以下の通りとなると思います。

```activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.ConstraintLayout
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
           著作権に配慮して、省略          />

        <!-- 以下、android:onClick="@{(vw) -> obj.doIt(frmNumber, text1)}"を削除 -->
        <!--      app:layout_constraintTop_toBottomOfをtext1に変更 -->
        <Button
            android:id="@+id/button1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="Button"
            android:textSize="18sp"
            app:layout_constraintTop_toBottomOf="@+id/text1"
            tools:layout_editor_absoluteX="0dp" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>


```

#3. 次の記事
[Section4-2](https://qiita.com/guijiu/items/4625362e503832a4196a)についても注意点を記述しました。ぜひご参照ください。
Swagger Editor 表記法まとめ

#はじめに
自分がswagger editorを使ってみて、わかった表記法を残します。
構成として、jsonでの表示をのせ、その書き方を記述します。
コードを記載しておきますが、Swaggerはインデントが違うだけでエラーを吐くので、インデントには気をつけてください。
##基本
#####オブジェクト
```json:response
{
  "message": "success",
  "uid": 1234
}
```

以上のレスポンスを得たい場合、下記のように書く

```
        200:
          description: "成功時のレスポンス"
          schema:
            type: "object"
            properties:
              message:
                type: "string"
                example: "success"
              uid:
                type: "integer"
                example: 1234
```
***
#####リスト
```json:response
{
  "id": [
    3,
    4,
    5,
    6
  ]
}
```

以上のレスポンスを得たい場合、下記のように書く

```
        200:
          description: "成功時のレスポンス"
          schema:
            type: "object"
            properties:
              id:
                type: "array"
                items:
                  type: "integer"
                example:
                 - 3
                 - 4
                 - 5
                 - 6
```
##応用
#####オブジェクトの中にリスト
```json:response
[
  {
    "uid": 1,
    "name": "田中"
  }
]
```
以上のレスポンスを得たい場合、下記のように書く

```
        200:
          description: "成功時のレスポンス"
          schema:
            type: "array"
            items:
              type: "object"
              properties:
                uid:
                  type: "integer"
                  format: "int64"
                  example: 1
                name:
                  type: "string"
                  example: "田中"
```
***
#####オブジェクトの中にオブジェクト

```json:response
{
  "id": 1002983,
  "category": {
    "id": 1,
    "name": "田中"
  }
}
```
以上のレスポンスを得たい場合、下記のように書く

```
        200:
          description: "成功時のレスポンス"
          schema:
            type: "object"
            properties:
              id:
                type: "integer"
                format: "int64"
                example: 1002983
              category:
                type: "object"
                properties:
                  id:
                    type: "integer"
                    format: "int64"
                    example: 1
                  name:
                    type: "string"
                    example: "田中"
```
RailsでCSV出力をviewに任せる実装


ほぼほぼこちらの記事の通りなのですが、自分でいろいろ試行錯誤する部分があったので自分用にメモ
https://qiita.com/ichi_s/items/eddf29d62ac09f6f9133

rails new などは割愛しますがCSV用の出力のコントローラーを作成しエクスポート用のアクションを以下のように用意します

```csv_export_controller.rb
class CsvExportController < ApplicationAdminController
  def index
    # index用のなにかしらの処理 
  end
  def export
    # Viewに渡すデータを用意
    @users = Users.all
    
    # csvの中身の組み立てはviewで行います
    send_data(render_to_string(template: 'csv_export/export.csv.ruby', type: 'text/csv', filename: 'export_csv.csv'))
  end
end
```

```views/export_csv/export.csv.ruby
#require 'csv' # Gemを使いましょう

# 出力に使うメソッドを定義すると呼び出せます（ヘルパーやデコレーターに書きましょう）
def user_name（user）
  user.last_name + user.last_name
end

header = %w(
    名前
    住所
    電話番号
    メールアドレス
  )

# 実際の処理
CSV.generate(headers: header, write_headers: true) do |csv|
  @users.find_each do |user|
    row = []
    row << user_name(user)
    row << user.address
    row << user.tel
    row << user.mail

    csv << row
    # sjisで出す場合、安全な文字に変換しとくと安心
    # https://qiita.com/cog1t0/items/263ab21a25e2cbd2ecc7
  end
end

# sjis
# csv_data = CSV.generate(~) o
# csv_data = csv_cata.encode(Encodinf::SJIS, { :invalid => :replace, :undef => :replace, :replace => ""}
```

Railsに慣れきってると、シンプルなrubyファイルに書くの戸惑いますね（笑）
vscode 1.56.0へアップデートしたら、remoteでLinuxにsshしたときに、.bash_profileの設定が読み込まれなくなった

vscode 1.56.0へアップデートしたら、remoteでLinuxにsshしたときに、ログインシェルが起動せず、.bash_profileの設定が読み込まれなくなった。

以前以下のように設定していたのが、deprecatedになったらしい。

```json:settings.json
"terminal.integrated.shellArgs.linux": [
    "-l"
]
```

この設定を改めて以下のようにする必要がある。

```json:settings.json
"terminal.integrated.profiles.linux": {
    "bash (login)": {
        "path": "bash",
        "args": ["-l"]
    }
}
```

この設定方法は以下に記載がある。

https://code.visualstudio.com/docs/editor/integrated-terminal#_configuring-profiles
win10の環境変数を「管理者権限」で開く方法



通常の場合
ここの「環境変数の変更」から開くか
直接スタートメニューで「環境変数」と開く場合が多いと思います
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61019/a4f7a137-c277-4132-2c73-1dda04e84926.png)

そうすると下記のように「**システム環境変数**」の部分は操作できません

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61019/827ec213-d1df-3e74-47f3-a622c6e1cef0.png)



##手順

1.[WIN]+[x]キーで設定系のメニューを表示します

2.「Windows Power Shell (管理者)」を選択して開きます


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61019/e218f01b-09c2-50bd-3505-1cb786408837.png)

3.「Windows Power Shell (管理者)」のコンソールが上がったら
　　下記のコマンドを入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61019/9fe8bf40-fb4c-53fc-3ead-f31ced387140.png)



````

Start C:\Windows\system32\rundll32.exe sysdm.cpl, EditEnvironmentVariables

```

4.そうすると「システム環境変数」のボタンもいじれるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61019/72232ea1-8da8-5fe1-49b6-0fe665a077e9.png)


###参考
---
管理者権限でシステム環境変数いじれない?！→2手で対処
https://www.lisz-works.com/entry/sys-env-admin
Subdiv2D使用時における領域外指定について

#目次
[1.はじめに](#1-はじめに)
[2.環境](#2-環境)
[3.エラーが起こった関数](#3-エラーが起こった関数)
[4.実装したコード](#4-実装したコード)
[5.エラー内容](#5-エラー内容)
[6.矩形の作り方](#6-矩形の作り方)
[7.解決法](#7-解決法)
[8.おわりに](#8-おわりに)
[9.参考文献](#9-参考文献)


#1. はじめに
今回はOpenCVの関数Subdiv2Dを使用した際に領域外指定のエラーが出現したことの記録，およびその解決法について記述する．

#2. 環境
・OpenCV 3.4.14
・Visual Studio 2017, 2019
・C++

#3. エラーが起こった関数
今回エラーが発生した関数はOpenCVに実装されている**Subdiv2D**という関数である．**ドロネー三角形分割**を行うためにこの関数を用いた．
関数の使い方としては，

１．矩形（Rectangle）を作成
２．矩形の大きさのSubdiv2Dオブジェクトを作成
３．領域内に母点となる点の座標を挿入

のような流れである．

#4. 実装したコード
今回実装したコードを記述する．

```
void drawDelaunay(cv::Mat img, cv::vector<Point> points)
{
    Size size = img.size();
    Rect rect(0, 0, size.width, size.height); // width, height共に500
    cv::Subdiv2D subdiv;
    subdiv.initDelaunay(rect); // 領域の指定
    Subdiv.insert(points); // 母点の挿入
 
    // ドロネー三角形のリストを取得する
    std::vector<cv::Vec6f> triangles;
    subdiv.getTriangleList(triangles);

/*----------------------------------------------------------------*/

// 以下描画の記述，今回は省略

}
```

上記はドロネー三角形分割を行い描画する関数drawDelaunay()である．幅と高さが500の画像imgと，母点となる配列pointsを引数として渡す．**今回pointsにはPoint(0,0) <= Point(x, y) <= Point(500, 500)の範囲の座標を格納してある．**描画する記述については，今回のエラーと関係がないので省略した．
なお，**母点**とはドロネー三角形分割を行うときの用語であるが，詳しいことは以下のサイトで参照してほしい．

[ボロノイ図とは](http://www.ics.kagoshima-u.ac.jp/~fuchida/edu/algorithm/voronoi-diagram/voronoi-diagram.html)
最終閲覧日：2021年5月7日

#5. エラー内容
今回のエラーは以下．

**OpenCV(3.4.13) Error: One of the arguments' values is out of range () in cv::Subdiv2D::locate, file C:\build\3_4_winpack-build-win64-vc15\opencv\modules\imgproc\src\subdivision2d.cpp, line 288**

これを見る限り，out of range とあるので領域外指定をしているらしい．
なぜだろうか，きちんと母点となる点の座標は「**0<=x<=500, 0<=y<=500**」にしているというのに．

#6. 矩形の作り方
ところで，C++で矩形（Rectangle）を作るときは**Rect rect(x, y, width, height);**と書けば良い．
ここで各パラメータは，
x : TopLeftのx座標
y : TopLeftのy座標
width : 矩形の幅
height : 矩形の高さ
である．

つまり，左上の頂点座標を指定，矩形の幅と高さを与えれば良いのである．

#7. 解決法
本題に入る．
さて，2節のコードに登場したrectは，左上の頂点座標が(0, 0)で，幅と高さ（width, height）はそれぞれ500, 500であるが，rectの右下の頂点座標はいくつだろうか？

**(500, 500)！**

なんてふざけたことを言ってはいけない．
左上の頂点が(0, 0)で幅と高さが500,500ということは，右下の頂点座標は**(499, 499)**なのだ．
（幅 = 500 = 右端のx座標 - 左端のx座標 ( = 0 ) + 1 → 右端のx座標 = 499） 

![スクリーンショット (29).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1417377/c087fd83-3836-db0e-f0a1-55f7879e8dfc.png)


つまり，今回私が指定した領域の端は，x = y = 499であるため，pointsに格納してあるx = 500またはy = 500の点を挿入すると当然領域外となる．

さて，エラー内容が至極単純なものだから解決法も単純明快だ．

**x = 500, y = 500 となるような点をx = 499, y = 499 に変更するだけ**である．
（画像サイズを変更しても対応できるように，**width-1, height-1** のように記述すると良いだろう．）

#8. おわりに
今回のエラー内容はドロネー三角形分割に直接関わるエラーではなく，至極単純なミスだった．しかし，こういった単純なミスによるエラーは単純すぎることによって発覚が遅れることがある．うっかりミスをなくしていきたいものだ．

#9. 参考文献
ドロネー図の描画について知りたいときは以下を参照すると良いだろう．

[OpenCV C++/IFでボロノイ図・ドロネー図を描く](http://schima.hatenablog.com/entry/2014/01/24/205517)
最終閲覧日：2021年5月7日
[Android]思考停止で使っていたonCreateViewとonViewCreatedの違いを少しだけ掘り下げる

#onCreateViewとonViewCreatedって当たり前のように使っているけど…
思考停止シリーズ第二弾です。
[前回](https://qiita.com/LaO/items/5cd82d02bd8de1ff14cc)は、思考停止で使っていたcontextを少し掘り下げました。
今回は、Fragmentで使うonCreateViewとonViewCreatedの違いについて少しだけ分かろうと思います。
筆者は、onCreateViewの方でData Bindingの紐づけを行って、onViewCreatedの方に色々書いていました。
しかし、どっちに書いても同じ気がしてならぬのです。

#違いは…
###onCreateViewというのは
onCreateView()の引数は、以下の三つです。
1. inflater: LayoutInflater,
2.container: ViewGroup?,
3.savedInstanceState: Bundle?
そして、戻り値はViewを返します。

このメソッドは、戻り値がルートとなっているViewなので、画面を描画する処理をしてくれます。
また、nullを返すと画面を描画させない処理ができます。（どんな時に使うのか…）

###onViewCreatedというのは
コンストラクタに、
view: View,
savedInstanceState: Bundle?
の二つを持ちます。

viewを持つということは、画面が出来上がった後に実行されるメソッドです。
ここで、Viewの操作をするようです。

#終わりに
結構、杜撰な記事になってしまいました。
ツッコミを受け付けております。
個人開発やり直し記録 -書き直したER図と使い古したDBの削除-

# 忘却
　教材の執筆や、ふつうの仕事や、デザインの学習などもろもろを行なっていたら、個人開発に対する記憶を失ってしまった。モチベーションも失ってしまったので、新しく作り直すことにした。

　さよなら、わいわい観察日記。

# 構想

　つくりたいものは決まっていた。日報アプリである。ただの日報ではなく、目標の設定と振り返りができる。個人開発は自分が使いたいものじゃないといけない。私は使いたいのでそれでよかった。

 ER図を書いた。

　https://github.com/kyokucho1989/simple-record/blob/main/db.md
　![スクリーンショット 2021-05-07 11.02.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104211/495fc812-4e43-f8b1-f48f-591b2220d759.png)

　Userは日々日報を記録し、毎週目標を設定する。そして定期的に目標が達成されたかを確認する。だれからのいいね！も賞賛もない。SNSの連携などはない。すっごいクローズにやっていくことにした。

# 環境

　なにも覚えていない。開発環境の構築さえ忘れてしまった。まずはrubyとrailsの最新バージョンをインストールしようとした。railsはxcodeをアップデートしないといけないらしかった。一旦アンイストールして再インストールしようとしたらエラーになった。容量が足りないらしい。

　macのストレージの「その他」にはなにが詰まっているのだろう。

　xcodeのキャッシュデータを消して、セーフブートで起動するなどして空き容量を30GB確保した。無事にxcodeはインストールできた。そしてrailsも。よかった。

　DBはpostgreSQLを使っていた記憶があった。でも、これらには何かが入っていた気がする。

```terminal
 $psql -l
```

データベースのリストが表示された。たしか「postgres」は除去してはいけなかった気がするので、その他のごちゃごちゃした名前のものを削除した。

```terminal
 $psql -d  (既存のDBの名前)

postgres=# drop database  (消したいDBの名前);
DROP DATABASE
```
スッキリした。

# 方針

　これから何をしていけばいいか。ひとまずは週1ペースでここに進捗を書こう。私がなにをしたか、どこで詰まっているかがわかる。想定する読者は未来の私だ。

　まずはrails newをやろう。
C++にpackが欲しい

書きかけ及びパラメータパックの習作
`std::format`という安全な`sprintf`があるならばP言語の`pack`/`unpack`も比較的安全に作れるのでは？という思いつき
(boostのiotreams使えばいいという話もある)

```c++:cpp20
#include <iostream>
#include <vector>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <string>
#include <type_traits>
#include <concepts>
#include <array>

template<typename T>
concept Serializable = std::copyable<T> && !std::is_pointer_v<T>;

template<Serializable T>
std::vector<uint8_t> _pack(T num){
  std::vector<uint8_t> r(sizeof(num));
  memcpy(r.data(), &num, sizeof(num));
  return r;
}

template<Serializable T, std::integral Tn, Tn m>
std::vector<uint8_t> _pack(T (&n)[m]){
    auto size = sizeof(n);
    std::vector<uint8_t> r(size);
    memcpy(r.data(), n, size);
    return r;
}

template<std::integral T>
struct rev{
    const T &val;
};

template<std::integral T>
std::vector<uint8_t> _pack(rev<T> n){
    auto size = sizeof(T);
    std::vector<uint8_t> r(size);
    auto b = _pack(n.val);
    for(size_t i = 0; i < size; i++){
        r[i] = b[size-i-1];
    }
    return r;
}

std::vector<uint8_t> _pack(std::vector<uint8_t> a){ return a; }

std::vector<uint8_t> _pack(std::string_view s){
  std::vector<uint8_t> r(s.size()+1);
  memcpy(r.data(), s.data(), s.size());
  r[s.size()] = 0;
  return r;
}

template<typename ... T>
std::vector<uint8_t> pack(T ...args){
    std::vector<std::vector<uint8_t>> tmp{ _pack(args)... };
    size_t total_size = 0;
    for(const auto& it : tmp){ total_size += size(it);  }
    
    std::vector<uint8_t> result(total_size);
    size_t offset = 0;
    uint8_t* ptr = result.data();
    for(const auto& it : tmp){
        memcpy(ptr + offset, it.data(), size(it));
        offset += size(it);
    }
    return result;
}

void display(std::vector<uint8_t> buf){
    printf("length: %zu\n", buf.size());
    for(const uint8_t& b : buf)
      printf("%02X ", b);
    puts("");
}

int main(){
    uint16_t a[] = {1,2,3,4,0xFFEF};
    auto b = pack(std::to_array(a), "1234567", rev<uint32_t>{0x123456}, uint32_t(0x987654));
    display(b);
}
```
Amazon Personalize の事例を紹介してみる

#はじめに
突然ですが、レコメンデーションという言葉を知っていますでしょうか？
簡単に説明すると、ECサイトなどで顧客の訪問履歴や購買履歴などのデータに基づき、顧客に自動的に商品やサービスなどをすすめる仕組みのことをレコメンデーションと呼びます。
まあ、通販サイトを利用してる時に「あなたにおすすめ」や「この商品をチェックした人はこんな商品もチェックしています」という感じで表示されてる商品リスト的なあれです。

ところで、この仕組みを自社サイトなどに導入するのって大変そうに感じないでしょうか。。。？
安心してください！Amazon Personalize を利用すれば、これまでのレコメンデーションシステムの開発時間を大幅に短縮することも可能です。

今回はそんなAmazon Personalize を自社サービスに導入したことでユーザーエクスペリエンス向上に成功した事例を2つほどご紹介いたします。

#Lotte Mart
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578416/c8772e23-abdf-34fc-21db-43b1a1e182c8.png" width="540px">

[引用元](https://aws.amazon.com/jp/blogs/machine-learning/increasing-customer-engagement-and-loyalty-with-personalized-coupon-recommendations-using-amazon-personalize/)
###Lotte Mart とは？
さまざまな食料品、衣料品、おもちゃ、電化製品などを販売する韓国の大手スーパーマーケットです。
###ユースケース
Amazon Personalize で顧客の嗜好を分析し、顧客ごとに最適化されたクーポンを発行しました。
###課題
従来利用していたレコメンデーションシステムは繰り返し購入を促進する効果はありましたが、下記のような課題がありました。

- 新商品の購買を促すことができない
- 顧客のニーズの変化に対応できない
- 分析エンジンの構築にリソースがかかりすぎる

###成果

- 新製品の購入頻度が1.7倍に増加
- クーポンの利用率が2倍以上に増加
- 全体の開発時間を半分に短縮

#StockX
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578416/a5f71401-4564-2955-4031-ece444d6ba44.png" width="540px">

[引用元](https://aws.amazon.com/jp/blogs/machine-learning/pioneering-personalized-user-experiences-at-stockx-with-amazon-personalize/)

###StockX とは？
スニーカーやストリートウェアなどの商品を取り扱うECサイトを運営する企業です。
###ユースケース
サイト上に顧客ごとにおすすめの商品を表示することで、ユーザーエクスペリエンスの向上を目指しました。
###課題
当初、StockX 社内では下記のような課題を抱えていました。

- 製品への関心の多様性が急速に広まっていった
- 最新のユーザーの嗜好をレコメンデーションに反映したかった

###成果
レコメンデーションモデルの構築後、A / Bテストを実施することで効果測定を実施しました。テストの結果、下記のようなマーケティング効果がみられました。

- 全体的な顧客エンゲージメントが50％増加
- 人気のある商品一覧のクリック率をおすすめ商品一覧のクリック率が上回った
- ユーザーのアクションから推奨事項を数秒で変更できるようになった

#おわりに
以上、代表的な事例をご紹介させていただきました。
今回ご紹介させていただいた事例以外にも、
Amazon Personalize はYamaha、NAVITIME、Subway、Domino's Pizza などでも利用されています。
あなたも試してみませんか？
Xcodeで新規プロジェクトを立ち上げた際に最初に呼ばれる画面を変更する方法

Xcodeで新規プロジェクトを立ち上げた際に、デフォルトで用意されている画面ではなく新規に作成した画面を利用したい。
方法を探ったのですが、ちょっと躓いたので備忘録として記載します。

###環境
Xcode12.4
Swift5

##新規プロジェクトのファイル構成
新規のプロジェクトを立ち上げると下記のファイルが作成されます。(初期設定や環境で若干異なります。)
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480691/9b04370b-9ca7-c8e1-40bf-0909d7736bf5.png">
最初の画面に関与しているのは、赤線部分のファイル達。

##表示したい画面を作成
表示したい画面を作成。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480691/7d926178-c1cf-8759-1b08-6f3487cabb61.png">
`First.storyboard`には3つの設定

+ ViewControllerとLabelを配置　※Labelは表示されたことを確認するため
+ ViewControllerの`Is Initial View Controller`をチェック
+ Custom ClassでFirstViewControllerクラスを選択して紐付け

`FirstViewController.swift`では画面が表示された際にLabelにテキストを代入

```swift:FirstViewController.swift
import UIKit

class FirstViewController: UIViewController {

    @IBOutlet weak var label: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        label.text = "First!!"
    }
}
```

##画面の変更
前置きが長くなってきましたが、肝心の画面変更をします。
info.plistを開きます。
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480691/738aac95-d6cf-fe47-6f4a-304ff13ae341.png">
設定項目の内、以下3つの項目を`First`に変更します。

+ Storyboard Name
+ Launch screen interface file base name
+ Main storyboard file base name

一つ目の`Storyboard Name`がネストしているので見つけるのに微妙に時間がかかってしまいました・・・

##結果
Buildしたら表示されました！
[Simulatorのスクリーンショットを撮る方法](https://qiita.com/riku333/items/8d1d0d3fd01f51842f1a)
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480691/89c98d6d-2c46-1453-fc7c-34ee47ddaea2.png">

##おわり
もし不備や補足があれば教えて頂けますと助かります。
AWS ほぼコピペでできる phpMyAdmin入れ方！！

ターミナルから操作するLinuxコマンド一覧
<font color="Red">個人で設定されているものが入る場合は赤文字</font>
<システムの更新>
```$sudo yum update```
MySQLをインストール
```$sudo yum install mysql```
<font color="Red">ここから</font>
MySQLへの接続確認
```$mysql -u admin -p -h MySQLDBのエンドポイント```
RDSで設定した
-h の後　エンドポイント
-u の後　ユーザーID　僕の場合admin
コマンド入力後RDSで設定したパスワードがもとめられる求められる
<font color="Red">ここまで</font>
```>quit```
<httpdとphpのインストール・起動確認>
```$sudo yum install httpd
$sudo systemctl enable httpd
$sudo systemctl start httpd```
（httpが正常に稼働しているかブラウザで確認）
```$sudo amazon-linux-extras enable php7.4
$sudo amazon-linux-extras install php7.4
$sudo yum install php-mbstring php-xml
$sudo systemctl enable php-fpm
$sudo systemctl start php-fpm
$sudo systemctl restart httpd
$sudo nano /var/www/html/index.php```
（phpが正常に稼働しているかブラウザで確認）
<phpMyAdminのインストール・起動確認>
```$cd /var/www/html```

```$sudo wget https://www.phpmyadmin.net/downloads/phpMyAdmin-latest-all-languages.tar.gz```

```$sudo mkdir phpMyAdmin```

```$sudo tar -xvzf phpMyAdmin-latest-all-languages.tar.gz -C phpMyAdmin --strip-components 1```

```$sudo rm phpMyAdmin-latest-all-languages.tar.gz```
```$sudo cp phpMyAdmin/config.sample.inc.php phpMyAdmin/config.inc.php```

```$sudo nano phpMyAdmin/config.inc.php```
（ファイルから下記の内容を探し、修正）

<font color="Red">ここから</font>
```$cfg['Servers'][$i]['host'] = 'localhost';
↑を↓に修正
$cfg['Servers'][$i]['host'] = '先程と同じエンドポイント';```
<font color="Red">ここまで</font>
（phpMyAdminが正常に稼働しているかブラウザで確認）

AWSインスタンスからパブリック　IPv4 DNS　オープンアドレスに
http://元々のアドレス/phpMyAdmin/
【Nuxt.js】v-app-varを位置固定する時にv-main上に自動でpaddingを入れるようにする

Vuetifyのv-app-barをabsoluteやfixedで上に配置する時に
v-app-barとv-mainを使いレイアウトを作る時v-app-barの部分が上に来て、v-mainの上の部分が重なってしまいます。

```vue
<template>
  <v-app>
    <v-app-bar id="app-bar" absolute>
      <v-app-bar-title>タイトル</v-app-bar-title>
    </v-app-bar>
    <v-main>
      <v-container>
        <nuxt />
      </v-container>
    </v-main>
  </v-app>
</template>
```

![Screen Shot 2021-04-25 at 15.16.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163786/ca828474-4438-d011-5b71-9b7ce06545b9.png)

このままではデフォルトではpaddingが0になってしまうのでclassを設定し、cssでpaddingを付け足さないといけません。

これを回避するためにv-app-barの属性にappを追加するとこで自動で丈夫にpaddingを追加してくれます。

```
<template>
  <v-app>
    <v-app-bar id="app-bar" absolute app>
      <v-app-bar-title>タイトル</v-app-bar-title>
    </v-app-bar>
    <v-main>
      <v-container>
        <nuxt />
      </v-container>
    </v-main>
  </v-app>
</template>
```

![Screen Shot 2021-04-25 at 15.23.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163786/afa8de34-2bca-1970-f6cb-18163ad34826.png)

うまく行きました、これで余計なcssを書かなくてすみますね。

参考:

https://vuetifyjs.com/ja/api/v-app-bar/
Flutter Web をFirebase hostingで公開(Firestore追加)

# はじめに
今回はFirebaseのFirestoreを使えるようにして、さらに、FirebaseのhostingにdeployしてWebアプリとして公開できるようにしようと思います。
# 更新履歴
2021.5.7 初回投稿
# 環境
- macOS Big Sur(11.2.3)
- Flutter (Channel stable, 2.0.6, on macOS 11.2.3 20D91 darwin-x64, locale ja-JP)
- Android toolchain - develop for Android devices (Android SDK version 30.0.3)
- Xcode - develop for iOS and macOS
- Chrome - develop for the web
- Android Studio (version 4.1)
- VS Code (version 1.56.0)

# 参考にしたサイト
- [flutter web + firebase(hosting)でポートフォリオサイトをつくったよ - Qiita](https://qiita.com/ampersand-dev/items/61ed134f871e7eab95ae)
- [HostingでWebアプリ公開 \| Flutterで始めるアプリ開発](https://www.flutter-study.dev/host-web-app/host-web-app)

# 準備
- Firebaseにプロジェクトを作成し、hostingを有効にしておく

# やりたいこと
- WebでFirebase Firestoreを使って公開したい

# 実装手順
1.Firebaseのプロジェクトでhostingを設定する(準備でできているはず)

2.Flutterでプロジェクト作成
 null safetyにしないと怒られるので、pubspec.yamlのsdkを以下のように変更

```pubspec.yaml
environment:
 sdk: ">=2.12.0 <3.0.0"
```

3.Flutterプロジェクト内でfirebase初期化
 
 ```
 firebase init
 ```

 ・`What do you want to use as your public directory?`では、`build/web`を指定

 ```
 ? What do you want to use as your public directory? build/web
 ? Configure as a single-page app (rewrite all urls to /index.html)? No
 ? File build/web/404.html already exists. Overwrite? No
 i Skipping write of build/web/404.html
 ? File build/web/index.html already exists. Overwrite? No
 ```

4.webアプリをビルド

 ```
 flutter build web
 ```
5.デプロイ

 ```
 firebase deploy
 ```

6.表示されたURLで動作を確認。いつものデモ画面が表示されます。

## Firestore設定
1.別記事を参照して実装

 [【Flutter】iOS/Android/WebでFirebase Firestoreを使えるようにする。 - Qiita](https://qiita.com/yoshikoba/items/1cfcda5b9f33555a113a)

2.webアプリをビルド

 ```
 flutter build web
 ```

3.デプロイ

 ```
 firebase deploy
 ```

4. 表示されたURLで動作を確認。

![sample.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9961/f8b622d6-a1db-c39f-0f3d-50590b261d7e.jpeg)

5.上記のように表示されればOK。FABを押して、Firestoreに追加されていればOK

## サンプルソースコード
https://github.com/yoshikoba/flutter_googlemap_sample

以上
AWSとWordPressを使ってWebサイトを構築しよう⑧

<h2>■インスタンスにApacheをインストールする</h2>
今回は作成したインスタンス「Webサーバー」に、オープンソースとして広く普及しているWebサーバーソフトの<b>Apache</b>をインストールしていきます。

#目次
[1.Apacheのインストールから起動までの方法](#1-apacheのインストールから起動までの方法)
[2.Apacheのプロセス確認](#2-apacheのプロセス確認)

#1. Apacheのインストールから起動までの方法
まずはインスタンスへSSH接続してください。
（SSH接続の方法は前回の記事を参考にしてください）

インスタンスへログイン後、下記コマンドを入力しApacheをインストールします。

```
sudo yum -y install httpd
```
ちなみにこのコマンドの意味は下記のようになっています。
「yum」コマンドはインストールやアンインストールするために用いるコマンド。
「sudo」コマンドは管理者権限でコマンドを実行するコマンド。
「httpd」はApacheのプロセスを表しています。
つまり、管理者権限(sudo)でApache(httpd)をインストール(yum)する。ということになります。
(「-y」はyumコマンドのオプションで「全ての質問にyesで答える、という意味があります)

![スクリーンショット 2021-05-07 9.01.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1159544/348bbf08-0735-05d6-7b48-b2594b17e382.png)

次に下記コマンドを実行しインストールしたApacheを起動します。

```
sudo systemctl start httpd.service
```

次に下記コマンドを実行しApacheが自動で起動するように設定します。
(自動で起動する設定をしないと、サーバーを停止して起動し直した時にApacheが同時に起動してくれません。)

```
sudo systemctl enable httpd.service
```

次に自動起動の設定が出来たか確認するため下記コマンド入力をします。

```
sudo systemctl list-unit-files -t service
```

するとコマンド実行結果の中に下記画像のように「httpd.service　enable」という表記があれば、ちゃんとApacheが自動起動の設定になっています。
![スクリーンショット 2021-05-07 9.35.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1159544/448659aa-46f6-ff6c-cd06-3815193aa8ef.png)

##2. Apacheのプロセス確認
Apacheがインストールされていること、自動起動の設定になっていることの確認ができました。
次はApacheのプロセスであるhttpdが実行中であることを確認します。

下記コマンドを入力して現在実行中のプロセスの中に「httpd」があることを確認しましょう。

```
ps -ax
```

コマンド実行後、下記画像のように「httpd」のプロセスが表示されているのが分かります。
(赤枠内の4277や4278などの先頭の番号は<b>プロセス番号</b>と言い、実行環境によりプロセス番号は異なります。)
![スクリーンショット 2021-05-07 9.51.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1159544/f2285cfa-b657-5921-044c-ad24fa764dfa.png)

次にApacheがどの<b>ポート</b>を開けて通信を待ち受けているのかを確認します。
ポートには「80番(HTTP)」や「443(HTTPS)」などがあります。

では下記コマンドを入力してどんなポートが開いているのか確認します。

```
sudo lsof -i -n -P
```
コマンド実行結果を見ると下記画像のように<b>「httpd」プロセスが80番ポート(「TCP *:80」)で待ち受けている</b>のが分かります。
![スクリーンショット 2021-05-07 10.07.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1159544/7351872f-03d2-9c4d-0af6-f6266b52ec1d.png)

</br>
今回はここまで。
本記事でApacheをインスタンスへインストールする方法、自動起動にする方法、プロセスの確認方法、ポートの確認方法を実践しました。

次回はWebブラウザからWebサーバーを見れるようにセキュリティグループを設定していきます。

次の記事はこちらから
<a href="https://qiita.com/uchino_infra/private/eff86cd1fe95b687d45c">AWSとWordPressを使ってWebサイトを構築しよう⑨</a>
SocialiteによるTwitter Login ~ Authorize編

# 概要
LaravelのSocialiteによるTwitter Loginにおいて、"Authenticate"から"Authorize"に変更する方法

# 環境情報
Laravel: 5.5.50
Socialite: 3.0

# 詳細
[LaravelのSocialiteを用いると、容易にTwitter Loginを実装できます](https://laravel.com/docs/5.5/socialite)が、
デフォルトでは、"[Authenticate](https://developer.twitter.com/en/docs/authentication/api-reference/authenticate)"版のTwitter Loginとなります。
これを"[Authorize](https://developer.twitter.com/en/docs/authentication/api-reference/authorize)"版のTwitter Loginに変更する方法です。

## 変更方法
(PJ Directory)/vendor/league/oauth1-client/src/Server/Twitter.phpにおけるurlAuthorization()メソッドを以下のように変更します。

【変更前】

~~~php
public function urlAuthorization()
{
    return 'https://api.twitter.com/oauth/authenticate';
}
~~~

【変更後】

~~~php
public function urlAuthorization()
{
    return 'https://api.twitter.com/oauth/authorize';
}
~~~


## AuthenticateとAuthorizeの相違点
Authenticate;
一度Twitter Loginを実施すると、次回以降はログインボタンをクリックした後に、
自動的にログインされるようになります。
そのため、複数アカウントを所有するユーザにとって、使い勝手が悪くなります。
※Twitter側で明示的にログアウトした後に、当該サイトにアクセスしないとアカウントを切り替えられない。
※1アカウントのみで運用しているユーザは使い勝手が良いと思います。
※個人的には情報を覚えられているように感じて、気持ち悪く感じます。

Authorize;
ログインボタンを押すたびに、TwitterアカウントをAuthorizedするかどうか聞かれるようになります。
と言っても、ユーザは毎回ユーザ情報を入力する必要ないので、使い勝手はある程度残ります。

## 関連情報
Laravel 5.5にSocialiteの最新版を導入しようとすると、
[エラーが出ますので、互換性があるSocialite3.0としています](https://qiita.com/Amy2020sg/items/ae287fa2cab7827dce39)。



##### 蛇足
今までは身内に教えることのみしていましたが、たまには記事を記載してアウトプットしようかと思います。
アプリのディープリンクまとめ

## ディープリンクとは？

urlでアプリの特定画面を開く技術全般のこと。

Androidにおいては、intent-filterでActivityを起動する仕組みのことも指す。

http/https以外のschemaに反応させたい場合もこれを使う。
（`tel://` とか `mailto://`とか）

## Androidアプリリンク

Android版Universal Links

intent-filterだと、同じ条件が設定されているActivityが起動し得るので（メールアドレスをタップすると複数のメーラーが候補に出てくるように）起動するアプリを限定したいときに使用する。
検証用にアプリサーバーなどに所有者を示すファイルを置く必要がある。

## Universal Links

iOSにおけるディープリンクの新しい実装。
Androidアプリリンクとだいたいの動作は同じ。
（使えるようになるまでの手順も似ている）

## Custom URLs

Androidにおけるintent-filterによるディープリンクの実装と同じもの（古い実装）。
例えば、Facebookならfb://user/hogehoge みたいなurlでFacebookアプリのユーザーページを開く、といったurlのこと。

## DynamicLinks

Android/iOSにおけるディープリンクの実装をラップしたサービス。
内部的には前述の実装を使い分けている。
v-for 識別子をとる

```vuejs
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
<div id="app">
<ul>
<li v-for="(fruit, index) in fruits">({{index}}){{fruit}}</li>
</ul>
</div>
```

```vuejs
new Vue({
  el: '#app',
   data: {
   fruits: ['りんご','バナナ','キュウイ','ぶどう']}
})
```
![20210507-101250.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/957da78e-9d3e-c74b-dce1-29c86b7c790e.png)


|エイリアス|ある対象や実体を、複数の異なるシンボルや識別子で同じように参照できるする仕組みを指す。別名。|
|----------|-|