OmniAICreator/Qiita-1.07M huggingface dataset:
【初心者用メモ】TypeORM / PostgreSQL で One-To-Many relation を定義する

# はじめに
TypeORMを勉強していたときのメモです。

#セットアップ
[こちら](https://qiita.com/theFirstPenguin/items/25b1dc093cd48e0c4c80)を参照

```
mkdir sample && cd sample
npx typeorm init --database postgres --express --docker
yarn
```
# One-To-Many relation
一人のユーザにいくつもの写真データが紐付いている場合を考えます。
![スクリーンショット 2020-11-19 10.09.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/f0646a34-7e23-2f7b-9d4e-21601bda897e.png)
# Entityの定義
```src/entity/User.ts
import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  OneToMany,
  BaseEntity,
} from 'typeorm';
import { Photo } from './Photo';

@Entity()
export class User extends BaseEntity { // extendしないとUser.createメソッドが使えない
  @PrimaryGeneratedColumn()
  readonly id: number;

  @Column()
  name: string;

  @OneToMany((type) => Photo, (photo) => photo.user) // これはフォールドでなく、relationを表現しているだけ
  photos: Photo[];
}
```

```src/entity/Photo.ts
import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  ManyToOne,
  JoinColumn,
  BaseEntity,
} from 'typeorm';
import { User } from './User';

@Entity()
export class Photo extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  url: string;

  @Column()
  userId: number;

  @ManyToOne((type) => User, (user) => user.photos) // relationを表現しているだけで、fieldとはならない
  @JoinColumn({ name: 'userId' }) // userIdがforeignキーとなることを表す。
  user: User;
}
```
# Controllerの実装
ここで、`UserContoller`で新しいリクエストがきた時の処理を例として考える
![スクリーンショット 2020-11-19 10.34.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/93ee0de3-2549-d7f6-f419-447bb6e3ba43.png)


```src/controller/UserController.ts

...

  async save(request: Request, response: Response, next: NextFunction) {
    const { name, url } = request.body;
    const user = await User.find({ where: { name } });
    if (user.length) {
      //すでにユーザーが登録済の場合
      await Photo.create({ url, userId: user[0].id }).save();
    } else {
      //ユーザーが未登録の場合
      const newUser = await User.create({ name }).save();
      const newPhoto = await Photo.create({ url, userId: newUser.id }).save();
    }

    return await getConnection() // ormconfig.jsonで定義したDBに接続する。今回はpostgresだけだが、複数のDBに接続している場合は、今回接続するDB名を第一引数にを明示する
      .createQueryBuilder(User, 'u') // 第一引数はテーブル名、第二引数はそのalias
      .leftJoinAndSelect('u.photos', 'photo')
      .getMany();
  }

...
```
こんな感じで返ってくる
![スクリーンショット 2020-11-19 10.41.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/a80cdd0b-8eea-4bdf-6774-5dbb9934955b.png)


# 参考
https://youtu.be/ao4C9dJO7n0
https://typeorm.io/#/many-to-one-one-to-many-relations
3分アジャイル XPの価値(2)

- コミュニケーション
- シンプリシティ
- フィードバック
- 勇気
- リスペクト

---
## 勇気
- コードの恐怖との戦い
- 明日のためではなく、今日のため
- コードを捨てる勇気
- 勇気だけではなく、他の価値とのバランスが重要

---
## リスペクト
- チームへの尊敬
- 他のメンバーへの尊敬
- チームワークを重視する

---

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/ba096976-70a4-8269-b9f6-a866a3602ef0.png)


---
## 参考
https://ja.wikipedia.org/wiki/%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%A0%E3%83%BB%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0

https://agilevelocity.com/xp-values-forgotten-agile-guidance/

https://ja.wikipedia.org/wiki/YAGNI

ＫｅｎｔＢｅｃｋ,ＣｙｎｔｈｉａＡｎｄｒｅｓ. エクストリームプログラミング (Japanese Edition) (Kindle Location 504). Kindle Edition.
Javascriptで現在時刻をyyyy/mm/ddの文字列で取得する方法

# Javascriptで現在時刻をyyyy/mm/ddの文字列で取得する方法

Javascriptで現在時刻をyyyy/mm/ddの文字列で取得する方法について備忘録的に記載します。

# Javascriptで現在日時の取得

Javascriptで現在日時の取得は

```
new Date();
```

を使ってDate型で取得出来る。これをyyyy/mm/dd形式に編集する場合、以下の様に年月日に分解してから連結する。

```
let date = new Date();				// 現在日時の取得
let year = date.getFullYear();		// 年の取り出し
let month = date.getMonth()+1;		// 月の取り出し
let day = date.getDate();			// 日の取り出し

window.confirm(year + "/" + month + "/" + day);	// 現在日付表示
```

現在日時が2020年10月10日の場合『2020/10/10』と表示される。
但し、現在日時が2021年1月1日の場合『2021/1/1』と表示される。
『2021/01/01』の様に月日を2桁に整形したい場合、以下の様に月日を取得する。

```
let month = ("00" + (date.getMonth()+1)).slice(-2);	// 月の取り出し
let day = ("00" + date.getDate()).slice(-2);		// 日の取り出し
```

頭に”00″をつけてslice(-2)とすることで、2桁に整形する。

sliceについては、以下を参照。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/slice



# 時分秒まで文字列で取得したい場合

時分秒まで取得する場合は、以下の様に記載する。


```
let date = new Date();				// 現在日時の取得
let year = date.getFullYear();		// 年の取り出し
let month = date.getMonth()+1;		// 月の取り出し
let day = date.getDate();			// 日の取り出し

let hour = date.getHours();			// 時の取り出し
let min = date.getMinutes();		// 分の取り出し
let sec = date.getSeconds();		// 秒の取り出し

window.confirm(year + "/" + month + "/" + day + " " + hour + ":" + min + ":" + sec);	// 現在日時表示
```

※時分秒を2桁に整形する場合は、月日と同様に頭に”00″をつけてslice(-2)とする。
Apple Silicon で psycopg2 (python3用pgsqlライブラリ) をインストール

Apple Silicon psycopg2 インストール作業メモ 2020/11/19

1, python3,pip3はos(Big Sur 11.1beta)バンドルのものを使う

$ which python3
/usr/bin/python3

$ python3 -V
Python 3.8.2

pip3は直接呼び出すとwarning出るので回避
alias pip3='/usr/bin/python3 -m pip'

$ pip3 -V
pip 20.2.4 from /Users/myname/Library/Python/3.8/lib/python/site-packages/pip (python 3.8)

2, Postgresqlをインストール
$ cd ~
$ wget https://ftp.postgresql.org/pub/source/v12.5/postgresql-12.5.tar.bz2
$ tar xvfz <上のファイル>
$ cd pgsql
$ ./configure
$ make
$ sudo make install
$ vi ~/.zshrc
export PATH=/usr/local/pgsql/bin:$PATH

ライブラリを使いたいだけなのでユーザなどは作らない

3, Opensslをインストール
$ cd ~
$ git clone git://git.openssl.org/openssl.git
$ cd openssl
$ vi Configurations/10-main.conf

1618     "darwin64-arm64-cc" => { inherit_from => [ "darwin64-arm64" ] }, # "His     toric" alias
1619     "darwin64-arm64" => {
1620         inherit_from     => [ "darwin-common" ],
1621         CFLAGS           => add("-Wall"),
1622         cflags           => add("-arch arm64"),
1623         lib_cppflags     => add("-DL_ENDIAN"),
1624         bn_ops           => "SIXTY_FOUR_BIT_LONG",
1625         asm_arch         => 'aarch64_asm',
1626         perlasm_scheme   => "macosx",   <----- ここを ios から macosxに書き換える
1627     },

$ ./Configure darwin64-arm64-cc --prefix="/usr/local/openssl-arm"
$ make
$ make test
$ sudo make install

$ vi ~/.zshrc
export LIBRARY_PATH=/usr/local/openssl-arm/lib:$LIBRARY_PATH
$ source ~/.zshrc

4, psycopg2をインストール
$ pip3 install psycopg2

以上

注：コンパイラがOSバージョンについてのエラーを吐くときは
以下の環境変数をセットしてください。
SYSTEM_VERSION_COMPAT=1

いずれこれは不要になるでしょうからその時は削除してください。
標準 SQL 規格の確認方法

標準 SQL 規格として、SQL92 / SQL99 というような言葉を聞いたことがあるかと思います。
Wikipedia だと[ISO/IEC 9075](https://en.wikipedia.org/wiki/ISO/IEC_9075) あたりの内容ですね。

SQL の標準規格が制定されているものですが、その内容を確認するためには、https://webdesk.jsa.or.jp/books/W11M0070/index にアクセスし、ISO 9075 の規格について検索を行うと、ドキュメントを購入することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33611/f947310c-881e-3d78-39b8-ad4b8f9fabd5.png)

私は購入したことがないのですが、以前、MariaDB から、SQL-99 Complete, Really というドキュメントが公開されていた時期があり、その流れで少しだけ内容を確認したことがあります。

MariaDB で公開されていたドキュメントについては、既に参照することはできないようですが、この流れで情報がアーカイブされているものがあります。
興味のある方は「SQL-99 Complete, Really」辺りで検索してみると、どのような内容が記載されているのかを確認できるのではないでしょうか。

[SQL overview](https://jakewheat.github.io/sql-overview/index.html) を見るのもよさそうです。
【Java】変更に強いコード - 変数名・メソッド化


変更に強いコードを書くための考え方を学びます

#目的ごとに変数を用意しよう
* 計算ロジックに意識が向き過ぎると変数名のことを忘れる
    * **入力、処理、出力の役割ごとに変数名を使う**	（説明用の変数を導入）
* **一個の変数を使いまわさない**
    * ロジックを変更しにくい。長い目で見ると副作用が伴う
* **Immutable**に書くことができる
    * オブジェクトを更新せずに別の目的のオブジェクトが必要な時に新しいオブジェクトをつくること（Immutableなオブジェクト）

```java
//目的ごとにローカル変数を使う
class Main {
        public static void main(String args[]) {
        int unitPrice = 1000;
        int quantity = 3;
        float tax  = 10;
        int basePrice = unitPrice * quantity;
        int shippingCost = 0;
        if (basePrice < 3000){
        	shippingCost = 500;
        }
        
        float basePriceWithTax = basePrice * (1+tax/100);
        
        //NG例1.0になってしまう
        //System.out.println((float)(1+10/100)); 
        
        System.out.println(basePriceWithTax);  //3300.0
        
       //NG例 一個の変数を使いまわさない
       //basePrice  = basePrice *  (1+tax/100);
            
        }
}

```

#メソッドとして独立させよう
* **関連性のあるデータとロジックをメソッドに抽出**
* **再利用/修正されることがあるかどうか**考えよう
    * ex: ShipppingCostの計算などは再利用されることがある機能
    * 同じ機能のコードを何回もかくことがないようにしよう
        * 複数箇所に渡って書いてしまうと変更時に回収できない
* 数値の直書きもよくない
    * **ロジックの中には固定値が入らないようにしよう**

```java
/*
point1:目的ごとにローカル変数を使う
point2:同じ機能のコードをメソッド化
point3:数値を固定値に（staticでいつでも参照できてfinalで変更できないようにする）
*/

public class Main {
        //クラス変数は、インスタンス化された各オブジェクトから共通してアクセス可能
        public static final int MIN_BASEPRICE = 500;
        public static final int SHIPPING_COST = 500;
        public static final int unitPrice = 1000;
        public static final int quantity = 3;
        public static final float tax  = 10;
        

        public static void main(String args[]) throws Exception {
        
        /*非static変数(ンスタンス変数)はインスタンス固有の変数
        int MIN_BASEPRICE = 500;
        int SHIPPING_COST = 500;
        int unitPrice = 1000;
        int quantity = 3;
        float tax  = 10;
        */
           
        var mainInstance  = new Main();
        var basePrice = mainInstance.run();
        var shippingCost = mainInstance.getShippingCost(basePrice);
        System.out.println("shippingCost " + shippingCost );  //shippingCost 0
                
        /* 上記はこのコードと同じ
        int basePrice = new Main().run();
        int shippinigCost = new Main().getShippingCost(basePrice);
        */   
        
        /*非staticメソッドはインスタンスから呼び出さなくてはならない
        error: non-static method getShippingCost(int) cannot be referenced from a static context
        int shippinigCost = getShippingCost(basePrice); 
        */
        
        }

        private int run(){
            int basePrice = unitPrice * quantity;
            float basePriceWithTax = basePrice * (1+tax/100);
            System.out.println("basePrice "+ basePrice);                //basePrice 3000
            System.out.println("basePriceWithTax "+ basePriceWithTax);  //basePriceWithTax 3300.0
            return basePrice;
        }

        public int getShippingCost(int basePrice){
            int shippingCost = 0; 
            if (basePrice<MIN_BASEPRICE){
                shippingCost = SHIPPING_COST;
            }
            return shippingCost;
        }
}
```
【VSCode】複数ファイルを開いている時にタブを多段表示する方法(Mac)


VSCode でたくさんファイルを開いていると、タブが横に広がりすぎてファイルが探しにくくなることがあるかと思います。

↓ こういうとき
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364501/b46a3945-7eb4-3e0e-d5e0-5961e5813509.png)
画面内に収まりきるならばいいですが、VSCode のウィンドウ幅を狭めるときには
横にスクロールしないと探さないといけなくなりますよね。
※左ペインから "OPEN EDITORS" で一気に閲覧できますが
　 WORKSPACE のファイル一覧も圧迫するため、今度はそちらが閲覧しにくくなりますというデメリットもあります

そういう時に ↓ のようにファイルタブを多段表示できるようにする方法を紹介します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364501/85d8ee49-0029-cea4-b766-6e1b204af00b.png)

## 拡張 CSS ファイルを準備

自分の好きなフォルダに CSS ファイルを作成します。
私の環境では下記のパスに作成しています.
"/Users/username/workspace/custom.css"

中身は下記のようにして保存します。

```css:/Users/username/workspace/custom.css
.tabs-and-actions-container > .monaco-scrollable-element {
  height: auto !important;
}

.tabs-and-actions-container > .monaco-scrollable-element > .tabs-container {
  height: auto !important;
  flex-wrap: wrap;
}
```

## 拡張パッケージをインストール

先ほど作成した CSS ファイルを VSCode で読み込むため、
**vscode-custom-css** というパッケージを VSCode にインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364501/24db2a83-5fdb-f585-9234-3943e099db08.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364501/4833610d-702b-9ba2-9120-a1218821abdc.png)

インストールできたら VSCode の Preferences > Settings を開いて settings.json 内に ↓ の設定を追記します。
拡張 CSS のファイルパスは絶対パスで記入するということと、絶対パスの前は file:// と入力することがポイントです。

```json:settings.json
...
    "vscode_custom_css.imports": ["file:///Users/username/workspace/custom.css"],
    "vscode_custom_css.policy": true,
...
```

書き込んだら VSCode で F1 (or Cmd+Shift+P) を押してコマンドパレットを開き
"Enable Custom Css and JS" と入力して Enter を押して実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364501/2d216bad-c92a-af2a-d2d2-7e69fd6c53f1.png)

実行したら VSCode を再起動します。
(再起動後に　"Your VS Code is corrupted" というポップアップメッセージが表示されることがありますが無視してよいようです）

## 多段表示になっていることを確認

たくさんのファイルを開いた時にタブが多段表示なっていることを確認します。
お疲れさまでした！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364501/af0ee3ae-18ae-b59d-ec3c-39dc3c287b8b.png)

## 参考にした情報

VSCode Github > https://github.com/microsoft/vscode/issues/70413
vscode-custom-css > https://github.com/be5invis/vscode-custom-css
個人的有識者まとめ

<h1>はじめに</h1>
日頃活用させていただいている情報源をリスト化しておこうと思いました。

<h1>有識者一覧</h1>

<table>
<tr>
 <th>技術領域</th><th>情報元</th><th>備考</th>
</tr>
<tr>
 <th>Windows全般</th>
 <th><a href=https://bizlog.tech/>どハマりエンジニアの備忘録</a></th>
 <th>サーバ、クライアント、AzureのWindows観点で幅広い技術情報を提供</th>
</tr>
<tr>
 <th>SV,NW全般</th>
　<th><a href=https://milestone-of-se.nesuke.com/>SEの道標</a></th>
　<th>サーバ、ネットワーク系の基礎知識から応用知識まで幅広い情報を提供</th>
</tr>
<tr>
 <th>Linux,OSS</th>
　<th><a href=https://densan-hoshigumi.com/>電算星組</a></th>
　<th>Linux,OSSの基礎知識や構築方法を提供</th>
</tr>
<tr>
 <th>Blockchain,コーディング</th>
　<th><a href=https://chal-convenience-info.net/>ちゃるの便利ブログ</a></th>
　<th>おひさま界のつよつよエンジニア。チャチャコインを実装してしまう</th>
</tr>
<tr>
 <th>Web系</th>
　<th><a href=https://github.com/yotaro-ok/>ようたろう</a></th>
　<th>無料オンラインサロンを展開。技術レベルが非常に高い。Twitterの鋭い投稿に注目</th>
</tr>
<tr>
 <th></th>
　<th><a href=https://www.depthbomb.net//>ITエンジニアの備忘録的技術ブログ【仮】</a></th>
　<th>キッティングに関する初級レクチャーあります。新入社員の時に知りたかった。。</th>
</tr>
</table>


<h1>おわりに</h1>
定期更新予定
WordPressで記事の状態を確認する関数

公式 → [WordPress codex](https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/get_post_status)

WordPressでの記事の状態にてその後の処理を決めるために
記事の状態を取得する処理を実装した

```PHP
<?php get_post_status( $ID ) ?>
```

既に用意されている関数だったのでリファレンスをしっかりと読めば
直ぐに処理を追加することが出来た
上記の$IDの中身は下記のいずれかになるのでそれに対して
条件を作れば求めた処理ができる

```
- 'publish' - 公開済
- 'pending' - 承認待ち
- 'draft' - 下書き
- 'auto-draft' - 新規作成された投稿。まだコンテンツがない。
- 'future' - 予約済（未来に投稿される）
- 'private' - 非公開（ログインしていないユーザーから見えない）
- 'inherit' - リビジョン。get_children() を見てください。
- 'trash' - ゴミ箱にある投稿。バージョン 2.9 で追加された。
```

条件の例

```PHP
<?php
	if ( get_post_status ( $ID ) == 'private' ) {
		echo '非公開';
	} else {
		echo '公開済';
	}
?>
```

今回自分が実装したものは
上記の一例にカスタムフィールドの値の確認を条件に追加したので
それについては後日纏めます。
Herokuに「The page you were looking for doesn't exist. 」が出たがコミットできてなかったという凡ミスだった、、、

拍子抜けするほどの凡ミスをして数十分ハマってたので、共有します:sweat_smile:

まず、PCの環境を分かる範囲で書いておきます。

* Ruby 2.6.5
* Ruby on Rails 6.0.3

試作のRailsアプリケーションをHerokuへデプロイし、URLを開こうとしたところ、
`The page you were looking for doesn't exist.`のエラー文が表示されました。。

![スクリーンショット 2020-11-19 0.18.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/892273/158f821f-6b14-a40e-56f6-22c958a7e202.png)

とりあえず、ググる、、、

ただ、調べた情報だと`root_path`を設定していなかったために、「それを設定してもう一回HerokuにpushしたらOKでした〜」というものがほとんど。

僕の場合は、ローカル環境できちんとrootに対応するviewが表示されていたので、そんなはずはないと思い引続き調査続行。。。

しかし、Terminal上でHerokuのエラーログを調査すると

```
ActionController::RoutingError (No route matches [GET] "/")
```

という記述があるので、やっぱりroutingはきちんと実装できてないんだなぁ、、、と。

格闘すること数十分、ふと目に止まったGitHub Desktopで異変に気づく。
Terminal上でコミットしたつもりだった「initial commit」以降の変更がcommitされていない模様、、、


なななんと、、、超初歩的なミスやないかい！！！(T_T)


ということで、再度コミット後、GitHubのリモートリポジトリにpush、そして、heroku masterにもpush

めでたくきちんと表示されました！！:joy:
AWS Git Codecommit で環境ごとにログイン情報を分ける方法(windows)

# 前提
OS: windows 10

# 課題
windows資格情報にログイン情報を登録するが、Codecommitの場合、環境ごとのURLが一緒になってしまう。
結果、1つの環境しか登録できない。

それを防ぐため、configファイルを編集し別ものとして登録する。

# 方法
## 資格情報を消す
既に登録されているものが優先されて使用されてしまうため、資格情報を消します。

1. windowsタスクバーの検索から、資格情報にアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384142/f30c5b75-c2af-8420-93e2-392e65fe50e3.png)

2. windows資格情報に行き、codecommitのURLが振られている資格情報を削除する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384142/d6883511-0cc0-47f6-e6f0-939ac95dd7a4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384142/f1ec4b87-8617-1e54-8dbf-c8280b880483.png)

## configファイルの編集
プロジェクトごとの.git/config内を追加編集する。

例. AWSの環境番号が`12345678`の場合
以下を追加する。

```text:.git/config
[credential]
	namespace = 12345678
```

## ログイン情報の設定
1. gitクライアント等でfetchコマンドを入力する。
2. 資格情報を入力する窓が表示される。設定値を入力する。

## 確認
資格情報に、指定された番号で登録されていればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384142/f23dccb4-07c3-0639-a986-6f0377edfc5c.png)
Dagger Hilt の Context まわりでハマったこと

Dagger Hilt では、Context クラスが必要な場合のために、`@ApplicationContext`アノテーションと`@ActivityContext`アノテーションが用意されています。
[Hilt を使用した依存関係の注入  |  Android デベロッパー  |  Android Developers](https://developer.android.com/training/dependency-injection/hilt-android?hl=ja#predefined-qualifiers)
Context を使う上でハマったポイントがあったので、備忘録として残しておきます。

# 事例

例えば SharedPreferences をラップした、`SharedPreferencesWrapper`クラスを`MainActivity`で使う場合を考えてみます。

```kotlin:MainActivity.kt
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    @Inject
    lateinit var sharedPreferencesWrapper: SharedPreferencesWrapper
    ...
}
```

```kotlin:SharedPreferencesWrapper.kt
/**
 * SharedPreferencesのラッパークラス
 */
class SharedPreferencesWrapper @Inject constructor(@ActivityContext context: Context) {

    private val sharedPreferences = context.getSharedPreferences("test", Context.MODE_PRIVATE)
    ...
}
```

そして、SharedPreferencesWrapper のインスタンスを提供するため、`ActivityProvidesModule`クラスを以下の通り作成します。

```kotlin:ActivityProvidesModule.kt
/**
 * DI用ProvidesModule
 * @Inject が付いたプロパティや引数に提供する値の実体を定義
 */
@Module
@InstallIn(ActivityComponent::class)
object ActivityProvidesModule {

    /**
     *　SharedPreferencesWrapperの提供
     */
    @Provides
    fun provideSharedPreferencesWrapper(context: Context): SharedPreferencesWrapper {
        return SharedPreferencesWrapper(context)
    }
}
```

ここでアプリをビルドすると、以下のエラーが出力されます。

```
/Users/Hitoshi/src/MyApplication/app/build/generated/source/kapt/debug/com/kmdhtsh/myapplication/MainApplication_HiltComponents.java:144: エラー: [Dagger/MissingBinding] android.content.Context cannot be provided without an @Provides-annotated method.
  public abstract static class ApplicationC implements MainApplication_GeneratedInjector,
                         ^
      android.content.Context is injected at
          com.kmdhtsh.myapplication.ActivityProvidesModule.provideSharedPreferencesWrapper(context)
      com.kmdhtsh.myapplication.SharedPreferencesWrapper is injected at
          com.kmdhtsh.myapplication.MainActivity.sharedPreferencesWrapper
      com.kmdhtsh.myapplication.MainActivity is injected at
          com.kmdhtsh.myapplication.MainActivity_GeneratedInjector.injectMainActivity(com.kmdhtsh.myapplication.MainActivity) [com.kmdhtsh.myapplication.MainApplication_HiltComponents.ApplicationC → com.kmdhtsh.myapplication.MainApplication_HiltComponents.ActivityRetainedC → com.kmdhtsh.myapplication.MainApplication_HiltComponents.ActivityC]
```

エラーを直訳すると、「Context は`@Provides`アノテーションメソッドがないと提供できません」と出ています。
解決策として、`ActivityProvidesModule`クラスの`provideSharedPreferencesWrapper`メソッドにも、同様のアノテーションを付与します。

```kotlin:ActivityProvidesModule.kt
/**
 *　SharedPreferencesWrapperの提供
 */
@Provides
fun provideSharedPreferencesWrapper(@ActivityContext context: Context): SharedPreferencesWrapper {
    return SharedPreferencesWrapper(context)
}
```

これでビルドエラーが解消されるはずです。
「コピペで使える」都道府県のプルダウン

#都道府県のプルダウン
そのままでcopyすれば使えるため、メモ帳として記録します。
※間違いがあれば、ご指摘ください。

```php
<label class="form-label"><strong>都道府県</strong><span class="badge badge-danger ml-1">必須</span></label>
<select name="prefecture_of_address" id="prefecture_of_address">
    <option value="" >▼</option>
    @foreach (config('pref') as $pref)
    <option value="{{ $pref }}">{{ $pref }}</option>
    @endforeach
</select>
```
CycloneVSoCにOpenCVを組み込んでUSBカメラの映像をLinux Desktopに表示する


#CycloneVSoCにOpenCVを組み込んでUSBカメラの映像をLinux Desktopに表示する
##はじめに
Cyclone V SoCをつかった基板でAIの開発をする際、カメラ映像の取り込みはベースとなるので、自分への忘却録としても手順を記載したいと思います。

##開発環境（Linux）

* クロスコンパイル環境： VirtualBox グラフィカルユーザーインターフェースバージョン 6.1.14 r140239 (Qt5.6.2)
* ゲストOS：Ubuntu18.04lts
* FPGAコンパイル環境:Quartus Prime Version 18.1.1 build 646

##Linux Desktopの構築
こちらのサイトの7.6.2項までを参考に、Cyclone V SoCにLinux Desktopのインストールをします。
https://rocketboards.org/foswiki/Projects/OpenVINOForSoCFPGA

手順は上記サイトを参考に、下記の変更を加えています。

* ツールチェーン：gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
* Linuxカーネル： socfpga-5.4.45-lts
* rootfs：linaro-stretch-developer-20170706-43.tar.gz

##OpenCVのインストール
下記公式サイトを参考にインストールを進めていきます。
https://docs.opencv.org/4.4.0/d7/d9f/tutorial_linux_install.html

###ツールのインストール

``` 
$ sudo apt-get install build-essential
$ sudo sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
$ sudo apt-get install python-dev python-numpy libtbb2 libtbb5-dev libjpeg-dev libpng-dev libtiff-dev  libdc1394-22-dev
```
公式には、libtbb-devが指定してありましたが、パッケージが見つからなかったので代わりにlibtbb5-devを、libjasper-devは見つからなかったので省略します。

###GitからOpenCVをチェックアウト

``` 
$ git clone https://github.com/opencv/opencv.git
$ git clone https://github.com/opencv/opencv_contrib.git
``` 

###OpenCVのビルド

``` 
$ cd ~/opencv
$ mkdir build
$ cd build
$ cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
$ make -j2
``` 

###OpenCVのインストール

``` 
$ sudo make install
``` 
正常にインストールされているか確認します。Pythonのインタラクティブコンソールを使えば確認できると思います。

``` 
$ Python3
>>> import cv2
>>>
``` 
エラーが出ずにプロンプト>>>が返ってくれば正常にインストールされていると思います。


##Pythonプログラム

```preview.py
#!/usr/bin/env python3

import cv2

cap = cv2.VideoCapture(0)

while(True):
    ret, frame = cap.read()
    if not ret:
        break
    cv2.imshow('preview', frame)
    key = cv2.waitKey(1)
    if key == 27:  # ESC 
        break

cap.release()
cv2.destroyAllWindows()
```

##実行
下記でプログラムを実行すれば、カメラの映像がWindowに表示されます。

``` 
$ python3 preview.py
```
本当にあったUIの指摘事項（営業担当からの指摘編）

# 営業担当より頂いたUIの指摘
## 始めに
~~~
これは、私が実際に業務で体験した、UIへの指摘事項の話です。

私は数年間、社内ポータルの開発に携わってきました。
これまで学んできた UI のお作法に則って開発をしてきましたが、
まさか、そこに様々な指摘事項を貰うことになるとは
思いもよりませんでした。

今回はそのうち、
営業担当の方から頂いたお便り（指摘）を紹介します。

※個人情報、および業務上の情報は伏せています
~~~

+ <font color="DarkGray">他の指摘事項（運用担当者からの指摘など）には以下ページから移動できます。
  - [本当にあったUIの指摘事項（メインページ）](https://qiita.com/hantyou-k/items/2ed207a6ff38a2da58e5)

## 自動検索は時と場合によりけり
#### 最初の状態
最近の流行りに乗っかり、検索画面を自動検索（項目を入力 or 選択しただけで検索が走る UI）にした。
#### 指摘
営業担当Aさんよりご指摘を頂いた。
まだ全項目を入力していないのに勝手に検索が走る。
いちいち入力や選択の度に検索が実行されると、ちょっとイラっとする、とのこと。

特に期間検索で広範囲を入力した際は、
検索に時間がかかるので猶更イライラするとのこと。
#### 対応
入力項目が多い検索ページについては自動検索を廃止し、
検索ボタンで検索を開始するようにした。
#### 反響
担当者にも満足して頂けた。

なお、検索項目が少ない場合は自動検索の方が喜ばれることもある。
特に運用者向けページでは、障害対応で急いでいる場合など、
日時や障害種別を選んだだけで検索開始できた方がよい、
という意見もあった。
#### 教訓
自動検索は一見スマートで便利そうに見えるが、
検索が毎回走る、というのは人によってはストレスになるため、あまり多用しない方が良い。
ただし、ページの利用用途に応じて、自動検索の方が良い場合もある。
（前述の運用者向けページなど）

## 相対検索より期間検索
#### 最初の状態
検索画面の日時入力項目を作成する際、
検索範囲を、デートピッカーで指定した日から過去ｎ日、
のような相対的な検索方法（相対検索）で統一した。

※デートピッカー
　カレンダーのようなウィンドウが開き、日付や時刻を選択できる機能
<img width="30%" border="5" alt="デートピッカー" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568441/4feca4b1-54d5-9e02-dde0-d0178a580686.png">

#### 指摘
営業担当Bさんよりご意見を頂いた。
過去ｎ日、だと開始日がいつなのか分からない。
特に、特定の月のデータが欲しいときに困る。

ここからここまで、みたいな期間検索の方が直感的で分かりやすい、とのこと。
#### 対応
以下のような期間検索を実装した。

+ 開始日 と 終了日 を指定する
+ 検索ボタンをクリックすることで期間検索が走る

ただし、相対検索は 運用担当 が監視などでよく使うので、
文句を言われないように、どちらも使えるようにしておいた。
#### 反響
営業担当Bさんより、自分の検索したい期間を自由に選べるので、効率的に探せるようになった、とのご意見を頂いた。
#### 教訓
相対検索は日時検索のお作法の一つだが、
人によっては期間検索（絶対指定）の方が探しやすい
という場合もある。

両方の方式で検索できるのがベターだが、
実装が難しい場合、そのページの利用者（例：営業か運用か）によって使い分けるのも手。

## 英語より日本語の方がいい！
#### 最初の状態
運用と営業担当向けに、自社サービスAの統計ページを作成した。
グラフの項目名に、サービスAの独自用語が幾つか出てくるのだが、そのまま※掲載した。
※運用や開発でよく使う言葉のまま記載。ほぼ英語
#### 指摘
営業担当Cさんよりご指摘を頂いた。
グラフの項目の意味が分からない、とのこと。

営業部門には運用などで通用している用語では伝わらなかった模様。
サービスで外部公開している言葉に直し、
かつ漢字やカタカタで書いてくれた方が分かりやすい、とのこと。
#### 対応
サービスAの独自用語を外部公開している言葉で、
かつ漢字やカタカタにして記載するようにした。

ただし、運用権限などでログインした際は、英語での表記にした。
※運用部門ではこちらの方が把握しやすい
#### 反響
営業部門から、グラフの用語が分からない、という声は出なくなった。
#### 教訓
サービスや社内に限った専門用語を使う場合、
ログインするユーザに応じて表記を出し分けたほうが良い。

+ 例：営業向け＝日本語表記、運用向け＝英語そのまま
+ ログイン権限などで表示方法を判定するのが無難

## グラフにコメントを書きたい
#### 最初の状態
とあるサービスの統計グラフを作成して欲しい、との依頼があった。
グラフ作成の某JSライブラリを使用し、いい感じのグラフが描けた！
そのときはそう思った。
#### 指摘
営業担当Dさんよりご相談を頂いた。
データをグラフで可視化できたのはいいけれど、
このグラフを１つ１つJPG形式で保存し、毎回PDFを書くのが面倒、
とのこと。

話によると、グラフをJPG形式でダウンロードした後、
パワーポイントに貼りつけてコメント（例：今月はコロナの影響で下方修正で・・・）を書き、
それをPDFに変換してサービス利用実績などの報告をしているそうだ。
#### 対応
個々の統計グラフの真下に **コメント欄** を設置。
また、ページの右上に **PDF出力ボタン** を設置し、
クリックすることで グラフ と コメント を同時に PDF 化できるようにした。
#### 反響
営業資料の作成の手間が減った、とのご意見を頂いた。
これはかなり喜んでもらえたものの一つ。
#### 教訓
データの可視化は **グラフに出したら終わり** ではない。
活用用途によっては、そこにコメントを描いたり、
PDF としてまとめて出力したいこともある。

可視化とは、データを見えるようにして、
更に、利用者のニーズを反映さえてこそ、
完成といえるのかもしれない。


```
※本記事に登場する人物やサービスは仮名です
```
Mac Os Big Sur ではデータローダが動かないようです 2020/11/19時点

Big Surにアップデートしたら、データローダが動かないと報告されています。

+ [Download and Install Data Loader](https://developer.salesforce.com/docs/atlas.en-us.dataLoader.meta/dataLoader/loader_install_mac.htm)


#追記　2021/01/08
一旦修正済みになったようですが、さらにうまくいかないという報告も上がっています。
https://trailblazers.salesforce.com/answers?id=9064S000000DRDU

回避方法も紹介されています。

ターミナルを開き、次のコマンドを実行しました
softwareupdate --install-rosetta

https://osxdaily.com/2020/12/04/how-install-rosetta-2-apple-silicon-mac/
次に、zulu11をインストールしました.43.55-ca-jdk11.0.9.1-macosx_x64.dmg
次に、ダウンロードしたデータローダーフォルダーからinstall.commandを実行しました。
デスクトップのデータローダーアイコンをクリックすると、
バックグラウンドでターミナルセッションが実行されます。
開いたままにしておく限り、データローダーは機能します。
今のところ回避策ですが、私はテストを行い、これまでのところうまくいっています。


[Dataloader and macOs Big Sur](https://trailblazers.salesforce.com/answers?id=9064S000000DLe5)

2020/11/19時点では

Apple has made some changes to the dynamic linker in MacOS Big Sur that appears to have broken Java GUI apps that use the older version of the SWT library. It has affected Data Loader and Pentaho Data Integration on my system regardless of which Java I use, and there is no known workaround beyond rebuilding the app from source using a newer version of SWT.

新しいバージョンのSWTを使用してソースからアプリを再構築する以外に既知の回避策はありません。

あとは、以前のOSにダウングレードするしかなさそう。


# 原因
問題はJavaの依存関係にあり、SWTライブラリはBig Surで機能しません。
データローダーを開こうとすると、白い画面が表示され、ターミナルでNullPointerExceptionが表示されます。
問題は、SWTライブラリをBig Surと互換性のあるバージョンですが、新しい問題があります。
最新のSWTライブラリには、非推奨のコードがあり、データローダーがそれを読み込もうとするため壊れます。

https://github.com/forcedotcom/dataloader/issues/217

# Known Issues · 修正済　2020/12/16時点
既知の問題に上がりました。

[Data Loader does not work properly on MacOS 11](https://trailblazer.salesforce.com/issues_view?id=a1p4V000000oRffQAE)


Big Sur 11.0.1（ Beta版でない）で動いたとの報告　2020/11/26
https://github.com/forcedotcom/dataloader/issues/217#issuecomment-733949227

米国の休日変更モラトリアムのため、2020年12月2日以降まで修正を正式にリリースできません。それ以前に修正データローダーが必要な場合は、MacOS11「BigSur」の修正が含まれているMacO用データローダーをダウンロードしてください。 」

https://github.com/forcedotcom/dataloader/files/5599246/dataloader_mac.zip

# 2025年度も

+ [Can't download Data Loader on Mac M1](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000KEN0G0AX)

:::note alert
Last login: Sun Mar  2 18:01:17 on ttys000  /Users/saibandari/Downloads/dataloader_v63.0.0/install.command ; exit;            saibandari@SAIs-MacBook-Air ~ % /Users/saibandari/Downloads/dataloader_v63.0.0/install.command ; exit;  readlink: illegal option -- f  usage: readlink [-n] [file ...]  /Users/saibandari/Downloads/dataloader_v63.0.0/install.command: line 4: ./util/util.sh: No such file or directory     Saving session...  ...copying shared history...  ...saving history...truncating history files...  ...completed.     [Process completed] 
:::
PHP テンポラリーファイルが作成されるディレクトリを確認する

# 目的

- PHPで作成されるテンポラリーファイルがどのディレクトリに作成されるかを得る方法をメモ的にまとめる。

# 詳細

- 下記を実行するとsys_temp_dirの値が返される。

    ```php
    sys_get_temp_dir();
    ```

# 参考文献

- [https://www.php.net/manual/ja/function.sys-get-temp-dir.php](https://www.php.net/manual/ja/function.sys-get-temp-dir.php)
- [https://www.php.net/manual/ja/ini.core.php#ini.sect.file-uploads](https://www.php.net/manual/ja/ini.core.php#ini.sect.file-uploads)
コントロールを動的に変更する方法：Xamarin

どんなことをする？
---
図のように実行したらテキストを変更する
![スクリーンショット 2020-11-19 8.06.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808622/040b6f66-67e5-baea-bd25-86c845446cd0.png)

環境
---
Visual Studio Community 2019 for Mac 8.8
Xamarin.Mac 6.22.1.26

方法
---
1.xamlでx:Name="識別文字"を追加

```
<Label Text="Test" x:Name="識別文字"/>
```

2.xaml.csで以下のコードを追加

```c#
Label label = NameScopeExtensions.FindByName<Label>(this, "識別文字");
label.Text = "Change by source";
```

ソース
---
```xaml:MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HelloWorld.MainPage">

    <StackLayout>
        <Frame BackgroundColor="#FF0000" Padding="24" CornerRadius="0">
            <Label Text="Welcome to Xamarin.Forms!" HorizontalTextAlignment="Center" TextColor="White" FontSize="36"/>
        </Frame>
        <Label Text="Test" x:Name="TestLabel"/>
    </StackLayout>

</ContentPage>

```

```C#:MainPage.xaml.cs
using Xamarin.Forms;

namespace HelloWorld
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            Label label = NameScopeExtensions.FindByName<Label>(this, "TestLabel");
            label.Text = "Change by source";
        }
    }
}
```
Typescript(Node.js)でtgzを解凍する

## Typescriptでtgz(tar.gz)ファイルを解凍する

実装例が少ないことと、紹介されている実装方法では展開先などが指定できなかったりするものがあるため、紹介しておきたいと思います。

## 使用するパッケージ

[npm tar]("https://www.npmjs.com/package/tar","npm tar")

## よく見る実装方法

```typescript
import * as fs from 'fs';
import * as zlib from 'zlib';
import * as tar from 'tar';

const tgzPath = '/file/hoge.tgz';
const outPath  = '/path/output';

const gunzip    = zlib.createGunzip();
const extractor = tar.Extract({path: outputPath});

fs.createReadStream(tgzPath).pipe(gunzip).pipe(extractor);

```

## tarパッケージ内でgzipは解凍してくれる

extractメソッドには以下のような説明書きがされている。

```
/**
 * Extract a tarball archive. The fileList is an array of paths to extract
 * from the tarball. If no paths are provided, then all the entries are
 * extracted. If the archive is gzipped, then tar will detect this and unzip
 * it. Note that all directories that are created will be forced to be
 * writable, readable, and listable by their owner, to avoid cases where a
 * directory prevents extraction of child entries by virtue of its mode. Most
 * extraction errors will cause a warn event to be emitted. If the cwd is
 * missing, or not a directory, then the extraction will fail completely.
 */

```

## よりかんたんな実装

実のところ、以下のコードだけでtar.gzを解凍できる。

```typescript
import * as tar from 'tar';

tar.x({path:'/file/hoge.tgz', cwd:'/path/output'}

```

以上
Sassで擬似要素を書くには

**環境**
---
Mac OS

**やりたいこと**
---
Sassで擬似要素を使いたい

**やったこと**
---
::afterの前に&をつけた

```
.body {
  position: relative;
  width: 80%;
  margin: 90px auto;
  text-align: center;
  &::after{
    position: absolute;
    content: "";
    display: block;
    width: 100%;
    height: 1px;
    bottom: 0;
    background-color: black;
  }
}
```

要素の下側に線を引きたかったのでこのような記述にしました
クラス名のところを＆に変えるだけで良いんですね🤔
aタグを使ったときのボタンの作り方

aタグを使ってリンクボタンを作る時に気をつけたいところを書いておきます。
たまーに、このようにボタンになっているのに文字部分だけしかリンクとして機能していないボタンを見ることがあります。

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="css,result" data-user="okalog" data-slug-hash="zYBQOKm" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="buttonNG">
  <span>See the Pen <a href="https://codepen.io/okalog/pen/zYBQOKm">
  buttonNG</a> by TakahiroOkada (<a href="https://codepen.io/okalog">@okalog</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

MOREにカーソルを当てると、リンク先に飛ぶようになっています。
問題ないと言えば問題ないのかもしれませんが、ユーザーは青色の範囲もリンクとして機能していると期待しているはずですよね。

なので、ボタン全体をリンクボタンとして機能させるためにはこのように書いてあげましょう。

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

と書きながらも実はこれが最適解なのかわかっていなかったり。
もっと良い書き方あれば教えて頂きたいです。
2020年に実施してうまくいった開発組織のマネジメント施策3つ

皆さんこんにちは。

税理士・中小企業向けクラウド会計・給与・税務システム「A-SaaS（エーサース）」を提供するMikatus株式会社でプロダクト責任者を務めている上村です。

50人規模の開発組織を統括しています。

この記事は[Mikatus Advent Calendar 2020](Mikatus Advent Calendar 2020)の最終日の記事となります。

# 2020年に実施して成果が出た施策

事業戦略にフォーカスし、俊敏に動ける開発組織を目指し、今年もいろいろな施策を社内で実施しました。

そのなかでうまくいったことを3つご紹介したいと思います。

## 組織や職種の壁を壊す

3月に大掛かりな組織再編を行いました。

それまで、「企画」「開発」「QA」という職種ごとに分かれた機能別組織だったものを、「既存事業グループ」「新規事業グループ」というように事業別組織に改めました。

機能別組織と事業別組織にはそれぞれメリット・デメリットがあります。

職種ごとの専門性を高めるうえでは機能別組織のほうが優れており、事業ごとの生産性を高めるうえでは事業別組織のほうが優れています。

今年は、事業戦略にフォーカスする形で事業別組織に振り切りました。

そして、その際に組織や職種の壁をなるべくなくす取り組みをしました。

これまで10年間機能別組織でやってきたので、今回の組織再編ではメンバー全員に大きな意識変革が求められました。「自分はピッチャーだから守らない、打たない」ではなく、「ピッチャーだからこそ、空いたベースのカバーのために走り回るし、バントもきっちり決めて攻撃にも貢献する」ように心がけよう、といった話をして、理解を求めていきました。

意外なことに、この意識は組織に急速に浸透し、企画や開発が下流工程のQAのテストを手伝ったり、自分の所属するチーム以外で困っている人がいたら助けるということが普通に起きるようになりました。

この下地として、Mikatusではチームワークを大事にする価値観が浸透していたことが成功要因の一つだったかもしれません。

Mikatusにはカリスマ技術者もスタープレイヤーもいませんが、チームワークで開発を進めることができる非常に良い組織になったと思います。

## OKRを導入

組織再編後、OKRを試験的に導入しました。

開発チームに売上責任を負わせられるほどには組織が成熟していないため、一旦、開発計画やシステム稼働率に対してチームがコミットするような形としました。

これまでは、顧客の声（Voice of Customer）を拾って優先度の高いものから開発してリリースする、ボトムアップ型の開発計画の立案手法を採っていました。

ビジネスや技術が安定している局面においてはこれでいいと思います。しかし、技術進化のスピードが早まり、競争環境がダイナミックに変化していくなかで、より戦略的な開発が求められるようになり、顧客の声を拾って開発するスタイルを続けていては時代に乗り遅れる危機が生まれてきました。

そこで、OKRを導入し、短期と中長期の目標を明確にして、トップダウン型で開発計画を立案する手法に切り替えました。

OKRの試験導入に際しては、戦略に沿った形で開発計画を立案する重要性や、チームメンバー全員で戦略への意識を統一して開発しよう、といったことをメンバーに話しました。

OKR自体もいきなり全メンバーに導入するのではなく、まずはマネージャー層から導入する形で、クッションを入れました。

試験導入期ということもあり、戦略とは関係性が薄い開発に時間を使ってしまうケースもありましたが、時間とともに、そういうケースは減っていき、半年たった今ではほぼ100%戦略に沿った開発計画の立案と実行ができるようになってきました。

## メンター制度の導入

本記事でご紹介する施策の最後となります。

メンター制度を導入し、メンターとメンティの関係を明確にしました。

これまでもなんとなく徒弟制度のようなものはありましたが、より強く組織全体で成長と育成への意識を持ちたかったので、正式にメンター制度を導入しました。

メンターとメンティのバランスについては、特定のメンターの負担が増えすぎないよう、メンター1人がメンティ1〜2人を見る形にしました。

また、メンター各人に活動方針を立案してもらい、メンティとのコミュニケーションを密に行ってもらいました。

結果的に、若手のメンティが成長するだけでなく、ベテランのメンター側の育成意識が高まり、当初狙っていた組織全体の意識の高まりを実現することができました。

Mikatusは社員の成長を何よりも大事にしています。

メンター制度の導入によって、社員の成長がより促進される方向に進化できたことを大変うれしく思います。今後も運用を続けていきたいと思います。

## 最後に

本記事は以上となります。

開発組織のマネジメントはうまくいくこともいかないことも多々ありますが、今年は大きな改革を行い手応えを感じられた1年でした。

日本全国の技術者の皆さん、2020年もお疲れさまでした。良いクリスマスを。そしてまた来年、ともに高め合いましょう。
RailsでPAY.JP APIを利用する 〜カード更新・削除編〜（payjp.js v2）

# 概要
PAY.JP APIでのカード登録/変更/削除機能実装の覚書です。
今回は登録したカード情報を更新するための手順をまとめていきます。
※簡潔にするため実装のために必要な最低限のコードのみ書いています。

なにか間違い等あれば編集リクエストをいただけると幸いです。

ちなみにpayjp.jsはv1に関する記事は多いですが現行のv2とは異なる部分が多いので注意が必要です。


実装準備編
https://qiita.com/nissy7ok/items/9790ef5ee1dec2863a62
カード登録編
https://qiita.com/nissy7ok/items/cea6789fe3b99654e473
カード更新・削除編←今ここ
https://qiita.com/nissy7ok/items/0ed52954f8fdad772da3

# 環境
```
# OS Version
ProductName:	Mac OS X
ProductVersion:	10.15.7
BuildVersion:	19H2

# Ruby Version
ruby:           2.6.5p114
Rails:          6.0.3.3
```

# 前提条件
PAY.JP APIを用いてカード登録をするところまでできている。
[前回](https://qiita.com/nissy7ok/items/cea6789fe3b99654e473)の記事参照。

# 手順
## 更新機能
API上で複数のカードを登録させることもできますが、
今回は既存のカード情報を削除し、再度登録するようにしています。
※最低限の記述に削っているので実際は条件分岐をしたほうが良いです。

```ruby:card_controller.rb
def edit
    @title = "カード情報変更"
    @btn ="変更"
    @card = Card.find(params[:id])
    redirect_to "/"
  end

  def update
    @card = Card.find(params[:id])
    Payjp.api_key = ENV['PAYJP_SECRET_KEY']
    customer = Payjp::Customer.retrieve(@card.customer_id)
    # 既存のカード情報を削除
    card = customer.cards.retrieve(@card.card_id)
    card.delete
    # カードを新しく登録
    customer.cards.create(
      card: params['payjp_token']
    )
    @card.update(card_id: params['card_token'])
    redirect_to "/"
  end
end
```

## 削除機能
私の場合条件分岐をすべて書き換えないといけなくなってしまうため、モデル内の情報も削除しています。
カード情報は一人一枚という仕様で割り切っています。
実際は一人で複数枚登録するケースはあるし、PAY.JP側で複数枚のカード情報を管理することも当然できます。
ここはもうちょっとうまくできたかも・・・。

```ruby:card_controller.rb
  def destroy
    @card = Card.find_by(user_id: current_user.id)
    Payjp.api_key = ENV['PAYJP_SECRET_KEY']
    customer = Payjp::Customer.retrieve(@card.customer_id)
    customer.delete
    @card.destroy
    redirect_back(fallback_location: root_path)
  end
```


# 参考
結局の所公式APIとガイドが最強です。
ただ読み慣れないうちはQiita等で実際の実装手順を見ながら感覚を掴むと理解が早まると思います。

PAY.JP API リファレンス
https://pay.jp/docs/api/

PAY.JP API 利用ガイド | PAY.JP
https://pay.jp/docs/started
<br>
公式ブログも参考になりますが、情報が古くv1準拠で書かれている場合が多いので注意が必要です。

ごく基本的なPAY.JPの使い方（Ruby編） - PAY.JP Engineering Blog
https://payjp.hatenablog.com/entry/2017/11/21/191916
<br>
その他参考にした記事等

Railsで　Payjp.js V2　でクレジットカード登録機能実装　フリマアプリ - Qiita
https://qiita.com/ta9301/items/6b736390c49c3f40edb6

[HowTo]Pay.jpを用いた商品購入機能実装から商品購入後の設定まで
https://qiita.com/Tatsu88/items/eb420e372077939a4627
[Rails初心者]コピペでwebアプリが作れる。魔法のコード。

細かいことは抜きにこのコードを自分のターミナルで打ってみてください。


```
rails new testapp; cd testapp && rails g scaffold post title body && rails g scaffold comment content post:references && bundle && rails db:create && rails db:migrate &&  rails 　s
```

このコードだけでwebアプリを作ることができます。

用途としては、
- 使ったことないgemのテストのためのアプリとして
- Railsでどんなことができるのか初めの一歩としてとりあえず動かしてみたいとき

などです。

コードの詳細としては

```
rails new testapp -d postgresql
```


```
cd testapp
```

```
rails g scaffold post title:string body:string
```

```
rails g scaffold comment content:string post:references
```

```
bundle 
```

```
rails db:create
```

```
rails db:migrate
```

```
rails 　s
```

です。
それぞれの意味がわからない人は是非調べてみてください！

他にも便利で楽しいコードを発見したら投稿したいと思います。
Vue.jsで作成したアプリをfirebaseにデプロイする方法(Firebase Hosting Setup Completeへの対処)

# 概要
React.jsやVue.jsで作成したアプリのホスティングの方法にはいくつかありますが、今回はVue.jsのfirebase Hostingによるホスティング方法について説明します。
Firebase Hosting Setup Completeの対処法がイマイチ見つからなかったので、多く出ている方法ですが今回記事にしました。

# 手順
##1, firebaseにログインする

```sh
// firebase-cliをインストールする
npm install -g firebase-tools

//firebase にログインする。
firebase login

※ログアウト方法は　firebase logout
```
こんな画面が出てくるので、「許可」を押して下さい。
![スクリーンショット 2020-10-19 20.35.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320677/cada660f-9756-0db3-fb8f-4abb7d81b321.png)

成功すると、こんな感じの画面になります。
![スクリーンショット 2020-10-19 20.35.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320677/aaf9ff3b-8d0d-ae19-b83d-67df4288ee0c.png)


##2, 必要な設定をして、リリースする

```sh

//初期化処理を行う
firebase init

// サービスを選択する
→「Hosting」を選択
→Projectを選択。
(firebase側で手動で作っていればUse an existing project )
(なければ Create a new project )

// 以下の質問に下記画像のように回答する
What do you want to use as your public directory? (public) dist
Configure as a single-page app (rewrite all urls to /index.html)? Yes
File dist/index.html already exists. Overwrite? No

// デプロイする。
firebase deploy

// 下記のように表示されるので、Hosting URLをブラウザで開くと、デプロイが確認できる。
✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/プロジェクト名/overview
Hosting URL: https://プロジェクト名.firebaseapp.com
```

##3,Firebase Hosting Setup Completeへの対処
もしも、リリースしたページにアクセスしたのに
<font color="DeepPink">Firebase Hosting Setup Complete</font>
としか表示されないことがあるかと思います。
これはfirebaseがホスティングしているファイルパスが正しくない場合に起きる状態です。
![スクリーンショット 2020-11-19 5.46.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320677/9743a7e0-e3c9-c634-4045-76e039359cc5.png)


対処としては、下記２点が正しくできているかを確認してください。
１、firebase.jsonのpublicがdistになっているか
![スクリーンショット 2020-11-19 5.36.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320677/3ae5f38c-a121-5dd2-907f-03b701a04bf6.png)

２、distを削除して、firebase initを再度実行し、下記設定でできていることを確認してください。
![スクリーンショット 2020-11-19 5.52.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320677/c45b343f-9463-1fec-43a0-acf6384f246f.png)
Git mergeする時に迷ったこと　〜現在の変更と入力側の変更〜

#Githubでmerge作業をしようとした際プルリクがToo complexとなった時の話

GitHubでプルリクを出すと、```”These conflicts are too complex to resolve in the web editor”```となった。
（こうなるのは変更点が多すぎるとなる様子）

解決に参考にした記事：https://kei178.me/programming/235/

こういう場合はVS Codeでmerge出来る

##手順

VS Codeの対象プロジェクトのターミナル上で
```$ git merge master```
この時mergeしたいブランチが自分の現在のブランチからdevelopブランチの場合は

```$ git merge origin/develop```
(この時　```git merge develop```でない点注意！)
（仮にこうした場合ターミナルに

```
merge: develop - not something we can merge
Did you mean this?
        origin/develop
```
と表示される）
なのでorign/develpとすれば良いことがわかる。

次に
```$git status```
を実行すると以下のようにコンフリクトしている箇所がわかるようになる

```
Unmerged paths:
  (use "git add/rm <file>..." as appropriate to mark resolution)
        both modified:   css/main.css
        deleted by us:   css/style.css
        both modified:   footer.php
        both modified:   sidebar.php
        both modified:   single.php
```

上記のようにコンフリクトが起きている箇所が表示される。
ここまで実行すると該当のコンフリクトのあるファイルに
![スクリーンショット 2020-11-19 6.01.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/4f977900-ba7b-b2a5-ed5f-528e2b74c9a4.png)

上記画像のように「現在の変更」と「入力側の変更」が表示される

###ここで今回のポイント
**現在の変更：自分のこれまでのブランチで入力していた内容**
**入力側の変更：mergeしようとしていたブランチ側（今回ならdevelop）で入力されている内容**

自分のブランチの内容をそのまま使いたければ現在の変更を取り込む
developブランチの内容をそのまま使いたければ入力側の変更を取り込む

必要な部分を選びたければdeleteキーを使用して手動で削除していけば良い

###変更が終わったら

```
git add .
git commit -m '変更をコミット'
git push origin ブランチ名
```

でプッシュし、再度Github上でプルリクしてマージすればOK
ターミナルからフォントをインストールする

# 状況
homebrewからフォントをインストールしたかったのですが、brew install rictyでエラーが出て行き詰まりました。

# 解決策

```shell
brew update

brew tap homebrew/cask

brew tap homebrew/cask-fonts

# ”ricty”の部分にはインストールしたいフォント
brew search ricty

# ”font- （フォント名）”が出てくるので、それをインストールする
brew cask install font-ricty-diminished
```

MacでFont Bookを開き、インストールしたフォントがあるか確認。

# 参考

[Install Mac Fonts on Terminal - Fastest Way to Add Mac Fonts (Youtube)](https://www.youtube.com/watch?v=vw19GDo-d1I)
[CentOS/Ubuntu/Macに]ag(the silver searcher)をインストール


# この記事を書いた理由 :shinto_shrine:

ファイルの中身を検索できるコマンドと言えば『grep』ですが、そのgrepを高速化した『grab』や『ack』、『ag』等が登場し移行する人が出てきています。

今回はその中で特に早いと噂[^1]の**ag**を、VirtualBox/Vagrantで仮想構築したCentOS8上に[GitHubのドキュメント](https://github.com/ggreer/the_silver_searcher)に沿って下記のコマンドでインストールしようとしました。しかし...

```
-- yumでも結果は同じ
$ sudo dnf update
$ sudo dnf install the_silver_searcher
-- 下記のエラーが出てインストール出来ない
Failed to set locale, defaulting to C.UTF-8
Last metadata expiration check: 0:04:22 ago on Wed Nov 18 17:23:56 2020.
No match for argument: the_silver_searcher
Error: Unable to find a match: the_silver_searcher
```

しかし上記のようにエラーが出てインストール出来なかったので上手く行く方法を下記していきます。
ついでにMacやUbuntuでも同じことをやっていきます。

# 各種OSにインストール :champagne:
## CentOS8
- バージョン確認

```
$ cat /etc/redhat-release
CentOS Linux release 8.0.1905 (Core)
```

- インストール

```
-- README.mdのdependenciesに下記二つ記載あり
$ sudo dnf -y groupinstall "Development Tools"
$ sudo dnf -y install pcre-devel xz-devel zlib-devel
$ cd /usr/local/src
$ sudo git clone https://github.com/ggreer/the_silver_searcher.git
$ cd the_silver_searcher/
$ sudo ./build.sh
$ sudo make install
-- agが入っていることを確認
$ which ag
/usr/local/bin/ag
```

## Ubuntu
- バージョン確認

```
$ cat /etc/os-release
-- 一部省略
VERSION="20.04.1 LTS (Focal Fossa)"
```

- インストール

```
$ apt update
$ sudo apt install silversearcher-ag
-- agが入っていることを確認
$ which ag
/usr/bin/ag
```

※Ubuntuは仮想環境ではなくLENOVO ideapad 330Sに直インスコしたのを使っています。


## MacOS
- バージョン確認

```
$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.15.7
BuildVersion:   19H15
```

- インストール

```
$ sudo brew install the_silver_searcher
-- agが入っていることを確認 
$ which ag
/usr/local/bin/ag
```

※Homebrewが未インストールなら[このリンク先記事](https://qiita.com/digitalhimiko/items/438fb17706873b476040#%E3%81%BE%E3%81%9A%E3%81%AFhomebrew%E3%82%92%E5%B0%8E%E5%85%A5%E3%81%97%E3%82%88%E3%81%86)を参考にインストールしてください。

今後、時間を見つけてagの使い方やgrepとの比較について軽く記事を書く予定です。:rocket:
本日は以上です。

# 参考記事 :blue_book:

- [The Siver Searcher README.md/GitHub](https://github.com/ggreer/the_silver_searcher)
- [Installing ag on CentOS/GitHub](https://gist.github.com/rkaneko/988c3964a3177eb69b75)

[^1]: 筆者の感覚値としても圧倒的に早いし[grepより速いackより3〜5倍高速](https://www.softantenna.com/wp/software/the-silver-searcher/)との情報もある。ただこれに[異議を唱える人](https://entree.hatenadiary.org/entry/20150105/1420467355)もおり筆者も数値的な検証はしていないのでここで明言はできません。ごめんね。
【PHP】日本語のyyyy年MM月dd日という文字列をyyyy-MM-ddにサクッと変換する方法

## はじめに
先日[teratailで回答した内容](https://teratail.com/questions/304156#reply-427340)と同じになりますが、メモも兼ねて。

| PHPのバージョン |
|:-:|
| 7.4.10 |

## コードと簡単な説明
```php
$date = DateTime::createFromFormat('Y年m月d日', '2020年11月19日');
echo $date->format('Y-m-d');
// 出力：2020-11-19
```
日時表示を特定のルールでフォーマットする場合は、`DateTime::createFromFormat`が便利です。
第1引数に書式を、第2引数に日時を渡すと、フォーマットされたDateTime型のインスタンスが返ってきます。
> 返り値
> 新しい DateTime のインスタンス、失敗した場合に FALSE を返します。

[公式ドキュメント](https://www.php.net/manual/ja/datetime.createfromformat.php)にはサンプルや書式のオプションも色々書いてあるので、詳しく知りたい方はそちらをご確認ください。
GitHub Desktopから卒業したい人のためのGitコマンド まとめ

GitHub Desktopに慣れ親しんできたけど、そろそろ卒業したくなったみなさまへ。きっと、私のほかにもいるはずだ！ と思ったので基本動作と思われるものを中心にまとめます。

## ブランチ
### 一覧を見る
```
$ git branch # ローカルブランチ
$ git branch -r # リモートブランチ
$ git branch -a # すべてのブランチ
```

### 作成・変更・削除する
```
$ git branch [ブランチ名]  # 作成
$ git checkout [ブランチ名]  # 変更
$ git branch -d [ブランチ名]  # 削除
```
ブランチ関連は、このあたりでやっていること。
![git03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410392/13f42a6b-5d48-41f4-6ea9-439185624477.png)

## 変更ファイル
### 一覧を見る
```
$ git status
On branch xxxxxx
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   package-lock.json
        modified:   package.json
        new file:   src/components/Message.vue
        new file:   src/components/Rate.vue
        modified:   src/router/index.js
```
要するに、この部分の情報。
![Group 7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410392/1f163b74-5ac1-a9c9-db70-dc7c621b40f5.png)

### コミットの対象にする
```
$ git add .
```
`.`はカレントディレクトリを意味する。この場合、画像でいう以下の操作に近い。なお、`git add`の後、空欄区切りでファイル名を指定していくこともできる。
![git01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410392/c24b346e-cb6f-5c7c-f30c-fa9bcb33834b.png)
`add`がやっていることに関しては「ステージングエリア」の理解も必要。以下が可愛い。

- [git add ってなんのためにやるの？ Gitの「ステージング」をイラストで解説します！](https://kray.jp/blog/expound-git-add/#:~:text=%E3%82%B9%E3%83%86%E3%83%BC%E3%82%B8%E3%83%B3%E3%82%B0%E3%81%A8%E3%81%AF,%E3%81%A8%E3%80%8C%E3%82%A4%E3%83%B3%E3%83%87%E3%83%83%E3%82%AF%E3%82%B9%E3%80%8D%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82&text=%E3%83%AF%E3%83%BC%E3%82%AD%E3%83%B3%E3%82%B0%E3%83%84%E3%83%AA%E3%83%BC%E3%81%AF%E4%BD%9C%E6%A5%AD%E3%81%97,%E3%81%8A%E3%81%8F%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B9%E3%83%9A%E3%83%BC%E3%82%B9%E3%81%A7%E3%81%99%E3%80%82)

また、コマンドのバリエーションについては以下も参考にしたい。

- [git add -u と git add -A と git add . の違い](https://note.nkmk.me/git-add-u-a-period/)

### 差分を確認する
```
$ git diff HEAD # 前回コミットとの差分
```
GitHub Desktopでいう、これ。
![スクリーンショット 2020-11-19 2.20.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410392/2a42c8ff-e9f8-0460-034d-2997c7ee4bde.png)
コマンドを打つと、差分は以下のように表示される。
![スクリーンショット 2020-11-19 2.21.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410392/94f4659d-1554-2703-c43b-a933f2d8ca4a.png)
`diff`関連のコマンドは非常に豊富なので、以下を参照。

- [忘れやすい人のための git diff チートシート](https://qiita.com/shibukk/items/8c9362a5bd399b9c56be)

### コミットする
```
$ git commit -m "コメント"
```
ここで言う"コメント"は以下の部分。
![commit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410392/accdede3-c15c-542b-f028-f88e554e6952.png)
#### note： コミットのコメントを書き換える
undoで戻って、編集したくなる人は覚えておきたい。

```
$ git commit --amend
```

### プッシュする
```
$ git push -u origin [ブランチ名] # そのブランチではじめてのpush
$ git push # そのブランチで2回目以降のpushなら省略できる
```
`origin`とはリモートリポジトリが置いてある場所を意味する。上のコマンドは`origin`のどのブランチにプッシュするか、という意味。

pushはこのボタンでやっていること。
![git02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410392/3e3750ab-805a-f902-fa7c-9bba1977f9fa.png)

# さいごに
とにかく、普段使っている操作、目についたものから列挙してみました。常日頃から「それってGitHub Desktopで言う、どれよ」という熟練者には伝わらない切なさも感じていたので、これを機にGitHubへの理解を深めたいなと思い、まとめました。少しでもお役に立てることがあればうれしいです。
遺伝研スパコンで全部入りのSingularityコンテナイメージファイルをつかう

このページを参照すると

https://sc.ddbj.nig.ac.jp/ja/guide/software/singularity

どうやらsifファイルがあるっぽい。

![スクリーンショット 2020-11-19 2.21.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58589/6d7f87d1-6da5-d471-7e64-0d8ee4a1a1aa.png)


スパコンに入ってqlogin（作業環境に移動）したあと以下のコマンドでもってくる。

```
[xxx@atxxx ~]$ singularity pull shub://oogasawa/singularity-ubuntu18
INFO:    Use image from cache

エイリアスをつける
[xxx@xxx ~]$ alias sing="singularity exec $HOME/singularity-ubuntu18_latest.sif"

Rを起動
[xxx@atxxx ~]$sing R

```

singularityコンテナから起動できた。
array_slice関数

# array_slice
配列の一部の範囲をスライス（切り取る、取得する）

```
array_slice(array $array, int $offset [,int $lenght = NULL[, bool $preserve_keys=False]]):array
```
## 引数　
$array=>対象の配列

$offset=>取得したい要素

$lenght=>取得したい要素の数

$preservekeys=>trueのときは、引数preservekeys=>trueのときは、引数arrayのキー番号を保持した戻り値を返す。falseのときは、戻り値のキー番号は始まりになる

##戻り値
offsetから$lenght分の要素

## 使用例
入力

```
$array=["a","b","c","d","e","f","g"];

echo var_dump($array);

$array_slice=array_slice($array,3,2);

echo var_dump($array_slice);
```

出力

 ```
array(7) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" [3]=> string(1) "d" [4]=> string(1) "e" [5]=> string(1) "f" [6]=> string(1) "g" }

array(2) {
  [0]=>
  string(1) "d"
  [1]=>
  string(1) "e"
}
```