OmniAICreator/Qiita-1.07M huggingface dataset:
【Python】matplotlibでデータラベル入り積み上げ棒グラフを作る

# 1．モジュールの準備
Pythonで積み上げ棒グラフを描く際の備忘録です。
まずは必要なモジュールをインポートします。

個人的にはラベル等は英語でいい気がしていますが、業務上レポートを書く際には日本語での記載する必要も多々あると思います。
``japanize_matplotlib``は、インポートするだけで簡単にタイトルや軸ラベルを日本語表示にすることができます。


```python
import matplotlib.pyplot as plt
import japanize_matplotlib
```


適当なデータセットを横持ちで作ります。縦持ちデータの場合は、``pivot_table``などを使うと簡単に横持ちにすることができます。
今回はどこかしらの施設の1～3月の入場者数を積み上げ棒グラフで表してみたいと思います。
```python
dataset = pd.DataFrame([[200, 350, 500], [150, 100, 250], [100, 400, 230]], 
                       columns=['1月', '2月', '3月'],
                       index=['male', 'female', 'Other'])
```
||1月|2月|3月|
|---:|---:|--:|--:|
|male|200|350|500|
|female|150|100|250|
|other|100|400|230|



# 2．関数定義
データの準備ができたら、可視化用の関数を定義します
グラフ作成の際には、大体グラフの高さ、横幅、データラベルのサイズをデータに応じて変更したくなるため、変数として放り込めるようにしたいと思います。
ただ、グラフサイズやラベルサイズを変更しても、凡例の文字は大きくならないため、``plt.rcParams.update(params)``を用いることで、凡例の文字サイズ、凡例ハンドル?サイズを変更しています。

```python
def make_stack_bar(data, width, height, font, ylim, title, xlabel, ylabel):
    fig, ax = plt.subplots(figsize=(width, height))
    ax.grid(True)
    for i in range(len(data)):
        ax.bar(data.columns, 
            data.iloc[i], 
            bottom=data.iloc[:i].sum()
            )
        for j in range(len(data.columns)):
            plt.text(x=j, 
                    y=data.iloc[:i, j].sum()+(data.iloc[i, j]/2), 
                    s=data.iloc[i, j], 
                    ha='center', 
                    va='bottom',
                    fontsize=font
                    )
    ax.set_ylim([0,ylim])
    ax.legend(data.index)
    ax.set_title(title, size=24)
    ax.set_xlabel(xlabel, size=16)
    ax.set_ylabel(ylabel, size=16)
    ax.tick_params(axis='x', labelsize= 16)
    ax.tick_params(axis='y', labelsize= 14)
    params = {'legend.fontsize': 16,
            'legend.handlelength': 2}
    plt.rcParams.update(params)
    plt.show()
```

# 3．可視化
関数が定義できたら、さっそく可視化します。
```python
make_stack_bar(dataset, 8, 8, 12, 1200, "各月の性別来場者数", "月", "人数")
```
これで下記のようなグラフができました。
簡単なグラフならばこれで内訳がよくわかりますね。

![stack_bar.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564653/7e149b59-d5f1-5cd9-e18e-af6709ff2be1.png)
WebSpeedHackasonに参加して感じたこと

# 概要
先日CyberAgentさんの主催するWebSpeedHackに参加しました。
その際にパフォーマンスチューニングについて感じたことをメモします。

# 重要だと感じた点
## ライブラリの削除
webpack bundle analyzerを用いて、どのパッケージが大きな容量を占めているか確認します。
削除できるライブラリは使用せず、大きなパッケージから小さなパッケージに書き換えたりします。

## 画像ファイルの拡張子を変える
jpegの拡張子を持つファイルをwebpに置き換えます。
これによってファイルの大きさが小さくなります。

## 画像ファイルのサイズを調整する
画像のファイルサイズが大きいと、読み込みに時間がかかってしまう。
画像のサイズを小さくすると良い。

## apiを用いたデータの読み込みを遅らせる。
すぐに用いるわけではないデータは、それを実際に使用するまで読み込むのをストップしておく。
それにより最初の画面の描画の速度が上がる。

# 感想
とても学びがあった。
パフォーマンスチューニングは、フロントエンドにおける深い知識を求められていると感じた。
ライブラリの表面だけを理解するのではなく、ソースコードを読み込むなどして、深い理解をする必要があると思った。
pythonで自分のIPアドレスをGETする


次のコードだと、 127.0.1.1　になる。ほしいのはコレじゃない。テックアカデミー等の記事が検索されるけど、ちゃんと書いてほしい。

```

import socket
# ホスト名を取得、表示
host = socket.gethostname()
print(host)

# ipアドレスを取得、表示
ip = socket.gethostbyname(host)
print(ip) # 192.168.○○○.○○○

```

pip install ipgetしてから、

```
    a = ipget.ipget()
    print(a.ipaddr("eth0")) # 172.xx.xx.xx/24 など
```

これで取得できる。
【スプレッドシート、GAS】先月の投稿件数をカウントしてメールを送る

# やったこと
目安箱シートに溜められた投稿の投稿日を見て、先月の件数をカウントしてメールを送るGASを書いた。

# 前提
Googleフォームから投稿した内容をスプレッドシートに溜めるようにしている。
シートには下記の内容が溜められる。
[![Image from Gyazo](https://i.gyazo.com/1f4ac7a97ff0516a345e16b48314e6b2.png)](https://gyazo.com/1f4ac7a97ff0516a345e16b48314e6b2)
タイムスタンプが入力されたセルの値をスクリプトから`getValue()`で参照しようとすると`Tue Feb 22 07:13:43 GMT-05:00 2022`の形になっていた。
これを変えるのは奔走しそうだとおもったので英語表記の月のママ使った。


# 先月を英語表記で取得する関数
下記記事のものをコピペさせていただいた。
https://qiita.com/yu-smc/items/8bdde9ff6729ce848c09


```
function get_english_month() {
  const month_english_list = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
  //月の英語表記を配列に定義。

  var date = new Date()
  //Dateオブジェクトで日付を取得（引数を持たせなければ現在時刻を取得する)

  var last_month = date.getMonth()-1;
  //dateから月を取り出してmonthに代入
  var month_english =  month_english_list[last_month];
  //month_english-listのmonth番目の要素をmonth_englishに代入。　※getMonth()は0-11までの整数が返る（1月は0になる）ので、[month-1]とする必要はない
  return month_english
}
```
### 記事のスクリプトから微調整したこと
- 取得月を先月に変更
- 英語表記を3文字に統一
- 関数として呼びだすために戻り値を設定



# 先月の投稿が何件あったかカウント
```
function myFunction() {

  //現在のスプレッドシートを取得
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  //現在のシートを取得
  var sheet = spreadsheet.getSheetByName("Answer");  

  //最終行取得
  var lastRow = sheet.getLastRow()

  var last_month = get_english_month();

  var j = 0;

  for(var i = 1; i <= lastRow; i++){
    var range = sheet.getRange(i,1);
    var value = range.getValue();
    var month = String(value).substr(4,3);
    if(last_month === month){
      j++;
    }
  }

  sendMail(j);

}

```
セルの値のタイムスタンプの英語表記の月をsubstrで取得しようとするとsubstr関数が使えないエラーに。
`String(Value).substr(4,3)`とすることで取得できた。
セルの値対して使う場合、文字列だとString()で明示しないとsubstr関数が使えないのか？

# メール送信
```
function sendMail(j){
  var recipient = "メールアドレス";
  if(j > 0){
    var subject = "意見交換会開催のお知らせ";
  }else{
    var subject = "意見交換会は開催されません";
  }
  var d = new Date();
  var y = d.getFullYear();
  var mon = d.getMonth() + 1;
  var body = mon + "月の目安箱への投稿は" + j + "件でした";
  GmailApp.sendEmail(recipient, subject, body);
}
```

最後にGASのトリガーの発火日付を毎月1日に設定すれば完成。
Python アノテーションとは？

# 概要
1: アノテーションとは？
2: 使い方

## 1: アノテーションとは？

アノテーションとは、関数の戻り値の型（Decimal, string, int など）が何で返ってくるか示した注釈のようなもの。
使用することで、コーディングした人がどの型を想定してコーディングしたかを読み手に示すことができる。

※前提：pythonでは、型を指定することは不要

## 2: 使い方

* 通常の関数
```
def function (arg1, arg2, ..) :
    ・・・・
```

* アノテーション使用した関数
```
def function (arg1, arg2, ..) -> "戻り値の型名":
    ・・・・
```

↓

例）
```
def calc (number_1, number_2) -> int:
    return number_1 + number_2
```
Angular で ERR_CONTENT_LENGTH_MISMATCH

Angular で開発時に DB から多めのデータを取得すると
```ERR_CONTENT_LENGTH_MISMATCH``` でレスポンスコードは 200 なのに
データが表示できず何故に...、となった時の対応メモ。
どうも Angular のバージョンで挙動が変わるよう。
環境にも依存しそうな気がするのでご参考までに。

## ERR_CONTENT_LENGTH_MISMATCH が出た Angular のバージョン

```sh
ng version
     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 10.0.3
Node: 12.14.0
OS: darwin x64

Angular: 10.0.4
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.1000.3
@angular-devkit/build-angular     0.1000.3
@angular-devkit/build-optimizer   0.1000.3
@angular-devkit/build-webpack     0.1000.3
@angular-devkit/core              10.0.3
@angular-devkit/schematics        10.0.3
@angular/cli                      10.0.3
@ngtools/webpack                  10.0.3
@schematics/angular               10.0.3
@schematics/update                0.1000.3
rxjs                              6.5.4
typescript                        3.9.7
webpack                           4.43.0
```

## ERR_CONTENT_LENGTH_MISMATCH が出なくなった Angular のバージョン

```sh
ng version
     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 12.1.4
Node: 12.14.0
Package Manager: npm 7.20.6
OS: darwin x64

Angular: 12.1.4
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1201.4
@angular-devkit/build-angular   12.1.4
@angular-devkit/core            12.1.4
@angular-devkit/schematics      12.1.4
@schematics/angular             12.1.4
rxjs                            6.6.7
typescript                      4.3.5
```
【Autonomous Database】パフォーマンス・ハブとAWRレポートの取得

```Autonomous Databaseの詳細```から```パフォーマンス・ハブ```にアクセスします
![o1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/7d5ab21e-9b45-8e76-5710-f962f1a357b9.png)

# パフォーマンス・ハブの画面紹介
パフォーマンス・ハブのホーム画面（**ASH分析**）
![o4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/71933c2f-53c5-98fc-60c2-1b3f257527af.png)

SQLモニタリング
![o5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/3f5364ce-fc21-7418-5f4b-b6cb4ec52985.png)

ADDM
![o6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/80fa31b8-4150-0852-a71e-bf1660041ad1.png)

ワークロード
![i1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/ed2c9a7d-bb7d-cc16-1ed3-ca6deca99f9f.png)

ブロックしているセッション
![i2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/455c6d8e-86e8-537b-6358-a77463054918.png)

# パフォーマンス・ハブからのAWRレポート取得
右上の```レポート```　→　```自動ワークロード・リポジトリ```をクリック
![o9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/1470c185-8600-c806-6c25-5ed88b872c72.png)

レポートを取得したい期間のスナップショットの***開始***と***終了***を選択し```ダウンロード```

![o10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/c42c3105-e88d-7b43-6652-66a609b0f0f7.png)

「```AWRReport_<開始時間>-<終了時間>.html```」という名前のAWRレポートがダウンロードされます。

レポートを確認。

![o1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/a670816a-b3b3-2b3e-d269-613714ac4665.png)
Flutter webでネットワーク画像が表示されない時の対処法【2022年3月現在】

# はじめに
Firebaseなどから取ってきた画像のURLを使って、Flutter webで表示するとエラーが出ました。その時の対処法について書きます。
※2022年3月現在のエラーなので、今後のアップデートによりこのエラー自体が消える可能性があります。ご注意ください。
# エラーの例
例として以下の、URLから写真を表示するコードを使います。
```dart:net_sample.dart
class NetSample extends StatelessWidget {
  const NetSample({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: [
            Container(
                width: 500,
                height: 500,
                child: Image.network("https://user-images.githubusercontent.com/89324742/157608435-2aaf7d31-6db4-4831-a1c6-3bf9fdae8070.JPG"))
          ],
        ),
      ),
    );
  }
}
```
これを
```bash
flutter run -d chrome
```
でChromeデバッグをすると
![エラー画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1925070/2d5c322f-5c4e-c5e1-3bbf-2f2c3725fa3d.png)
このように画像が表示されません。ターミナルには
```
The following ImageCodecException was thrown resolving an image codec:
Failed to load network image.
```
とエラーメッセージが出ました。

# 対処法
以下のように実行してください。
```bash
flutter run -d chrome --web-renderer html
```
すると画像が正常に表示されます。
![スクリーンショット 2022-03-10 165336.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1925070/fc417af2-3e5c-6009-2233-200e998f7a37.png)
また、build webする時は、
```bash
flutter build web --web-renderer html --release
```
と実行してください。

# おわりに
少しでも参考になれば幸いです！！
[iOS] xibファイルを指定してViewControllerを生成する


ボタンタップなどで遷移する場合に、特定のストーリボードのViewControllerを生成する方法

~~~objc
Bool nib_b = YES;
NSString* nibname = @"Nibname_A";

//　　条件により表示させたいストリーボード名称をセット
if( nib_b ){
    nibname = @"Nibname_B";
}

// 特定のストーリーボードファイル名称のViewControllerを生成
UIViewController *vc = [[UIStoryboard storyboardWithName:nibname bundle:nil] instantiateViewControllerWithIdentifier:@"ViewConroller"];

// 生成したViewControllerへ遷移
[self.NavigationController pushViewController:vc animated:YES];

~~~
はじめてのHTML

# 前提
こちらの記事はプログラミング初学者による備忘録です。
私と同じような初心者の方がお読みになる場合は、決して鵜呑みにはせずあくまでも「ネット上の情報」だということをご理解くださいませ。
万が一誤りがありましたらお手数ですがご指摘いただけますと幸いです。
# HTMLとは
HyperTextMarkupLanguageの略。
日本語に訳すと「ハイパーテキストに目印をつける言語」というような意味でしょうか。
一言で表すと、ウェブサイトに表示される情報を記載する言語のことだそう。
ウェブページを作成するために開発された言語で、現在、インターネット上で公開されてるウェブページのほとんどは、HTMLで作成されているんだとか…
作成する際には〇〇.htmlという名前のファイルに記載するようです。
# CSSとは
CascadingStyleSheetsの略。
一言で表すと、HTMLに装飾を加えるための言語のこと。
HTMLと組み合わせて使用する言語で、 HTMLがウェブページ内の情報構造を定義するのに対して、CSSではそれらをどのように装飾するかを指定します。 例えば、ウェブページが表示される際の色・サイズ・レイアウトなどの表示スタイルなどについて指定することができます。
こちらは〇〇.cssという名前のファイルに記載するようです。
# 〇〇.〇〇の「.」とは何？
ファイルの末尾に付ける文字列のことを拡張子と呼ぶそうです。
拡張子を付けることで、ファイルに書かれている言語の種類を識別することが出来ます。
例えばhtmlのファイルを作成する場合は〇〇.htmlとなり、CSSの場合は〇〇.cssとなります。
ということは我々が普段目にしている「.png」「.pdf」なんかも拡張子だったと言うことでしょうか。
Autonomous Databaseの各種操作/設定

* ```Autonomous Databaseの詳細``` → ```他のアクション```よりADBの起動/停止をはじめてとした各種操作が行えます。
![o1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/defba4dd-6159-69b0-2c05-4c62a21f78ca.png)

# スケーリングの管理
* 次の操作が行えます
    * OCPU数やストレージの手動スケーリング
    * OCPU数やストレージの自動スケーリング有効/無効化

![o2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/97aa3334-644d-0800-5855-0032619e1669.png)

# 管理者パスワード
* ADMINユーザーのパスワード変更を行えます
![o3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/cff07fdc-ac60-7f17-9afc-c5fafef62f89.png)

# 自動開始/停止スケジュール
* DBの自動起動/停止のスケジューリングが行えます
    * 時間は```UTC```
![o4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/097f9626-782a-0faa-43e3-656549a50178.png)

# Autonomous Database情報から確認/設定できる項目
![o6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/fd5709b8-ff22-7755-85dc-a8140e07f90d.png)

## 自動開始/停止スケジュール
* 先程紹介した自動起動/停止のスケジューリングがこちらからも行えます。

## モード
* いずれのモードも、管理者ユーザーのみにアクセスを制限できます。

|データベース・モード|内容|
|:-----------------|:---|
|読み取り/書き込み|ユーザーはDMLおよびDDL操作を実行できます。|
|読み取り専用| ユーザーは問合せのみ実行できます。他のDMLおよびすべてのDDL操作は許可されません。|
|管理者アクセスのみを許可||

![o7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/d8f69c1b-bbd5-67a0-4bb5-2b28c9f9f9c5.png)

## データベース管理
* ```Database Management```の有効/無効化を設定できます
    * 詳細は[こちら](https://docs.oracle.com/ja-jp/iaas/database-management/doc/database-management-autonomous-databases.html)
* 有効化した場合
    * ```監視および管理``` →　```データベース管理``` →　```フリート・サマリー```

* 次の情報を確認できます
    * アクティビティ。クラス（平均アクティビティ・セッション）
    * CPU使用率（%）
    * ストレージ（TB）
    * SQL文
    * 失敗した接続

![o12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/016757bc-ace6-1641-8b4b-141dd2bc2791.png)

* DB Management上からもADBの```パフォーマンス・ハブ```に移動することができます

![o13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/bedfdbac-da52-f3ba-e691-f338d0984943.png)

* DB Managementのフリート・サマリーにADBが表示されます

![o11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/e4c6fff6-9644-fb3a-30ee-3921ed97e74a.png)

## オペレーション・インサイト
* ```Operations Insights```の有効/無効化を設定できます
    * 詳細は[こちら](https://docs.oracle.com/ja-jp/iaas/operations-insights/index.html)
* 有効化した場合
    * ```監視および管理``` →　```オペレーション・インサイト``` →　```フリート・サマリー```



## Autonomous Data Guard（AuDG）
* AuDGの有効/無効化を設定できます
![o8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/7c3803ae-3519-ada9-67db-30ddc99a67f8.png)

## アクセス制御リスト（ACL）
* このデータベースへのアクセスを許可するIPアドレスおよびVCNを指定します。
![o9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/f59e37e6-867e-dd71-178d-de78e6a58fa7.png)

## 相互TLS（mTLS）認証
* ACLまたはプライベート・エンドポイントを構成して、TLS認証を有効にできます。

## 顧客の連絡先
* このリストの連絡先は、運用上の通知およびお知らせ、および計画外メンテナンスを受け取ります。
![o10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/385bfc99-f681-b87b-2dc1-f78eb546178d.png)
ACDLを提唱します。その4

# 概要

ACDLとは、アプリは、クラウド、大切なデータは、ローカルです。
todoアプリ作ってみた。

# サンプルコード

```
new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data() {
    return {
     	headers: [{
    		text: "作業名",
		    sortable: true,
		    value: "task",
	    	width: "70%"
	    }, {
		    text: "優先順位",
		    sortable: true,
		    value: "assignee"
	    }, {
		    text: "操作",
		    sortable: false,
		    value: "control"
	    }, ],
	    items: [],
	    assignees: ["A", "B", "C", ],
	    task: "",
	    assignee: ""
    }
  },
  methods: {
    addTask: function() {
      if (!this.task || !this.assignee) 
	    {
     		alert("タスク名と作業者を入力してください。");
		    return;
	    }
      this.items.push({
		    "task": this.task,
		    "assignee": this.assignee,
	    });
	    this.task = "";
	    this.assignee = "";
    },
    deleteTask: function(item) {
      this.items.splice(this.items.indexOf(item), 1);
    },
    async loadLog(event) {
	    const files = event.target.files || event.dataTransfer.files;
   	  const file = files[0]
	    if (!this.checkFile(file)) 
	    {
		    alert("ファイルを読み込めませんでした")
		    return
	    }
	    const logData = await this.getFileData(file)
      //alert(logData);
	    var data = JSON.parse(logData);
			this.items = data.todo;
    }, 
    getFileData(file) {
	    return new Promise((resolve, reject) => {
		    const reader = new FileReader()
		    reader.readAsText(file)
		    reader.onload = () => resolve(reader.result)
		    reader.onerror = error => reject(error)
	    })
    },
    checkFile(file) {
	    if (!file) 
	    { 
		    return false
	    }
	    if (file.type !== 'application/json') 
	    {
		    return false
	    }
	    const SIZE_LIMIT = 5000000 
      if (file.size > SIZE_LIMIT) 
	    {
		    return false
	    }
	    return true
    },
    saveLog() {
			var line = {
			  "todo": this.items
			};
			var json = JSON.stringify(line); 
      //alert("ok1");
      var url = URL.createObjectURL(new Blob([json]) , { 
        type: "application/json" 
      });
      var a = document.createElement('A');
      a.download = 'todo.json';
      a.href = url;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
    },
  }
})




```

# 成果物

https://embed.plnkr.co/plunk/a0FnCMVZg6uFuzkj

以上。
【docker】dockerコマンド その2

dockerコマンドを備忘録としてメモしておく。各コマンドのオプションなどの詳細についてはdocker docsを参照。

# コンテナ

## コンテナの起動・停止・再起動

```
// 起動
docker start <オプション> <コンテナID>
// 停止
docker stop <オプション> <コンテナID>
// 再起動
docker restart <オプション> <コンテナID>
```
【参考:[起動(start)](https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/start/)・[停止(stop)](https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/stop/)・[再起動(restart)](https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/restart/)】

## コンテナからログを取得
```
docker logs <オプション> <コンテナID>
```
【参考:[ログ取得(logs)](https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/logs/)】

## 実行中コンテナ内でコマンド実行
```
docker exec <オプション> <コンテナID> <コマンド>
```
【参考:[コンテナ内でコマンド実行(exec)](https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/exec/)】

## コンテナを起動してコンテナ内で操作
```
docker run -it <イメージID>
```
【MUI】styled()内でのtheme.typographyの指定方法

# はじめに 
theme.typographyで文字サイズ等をまとめて管理したい、inputの入力文字サイズとかもtheme.typographyで指定したいとなったのでやってみた。
https://mui.com/system/styled/
https://mui.com/customization/typography/

## 通常のTypography（のvariant）指定
`<Typography variant="">hoge</Typography>`でok

## styled内でのTypography指定
input内の文字サイズを指定したいときなどに
`<Typography variant="">hoge</Typography>`を使うことができない。
その場合は、styledを利用してその中で下記のように指定する。
```ts
const MyTextField = styled(TextField)(({ theme }) => ({
  color: theme.palette.primary.main,
  '& .MuiInputBase-input': {
      ...theme.typography.h5,
  },
}));
```

## サンプルコード
```ts
import * as React from 'react';
import {
  createTheme,
  responsiveFontSizes,
  ThemeProvider,
} from '@mui/material/styles';
import { Typography, TextField } from '@mui/material';

let theme = createTheme();
theme = responsiveFontSizes(theme); 

const MyTextField = styled(TextField)(({ theme }) => ({
  color: theme.palette.primary.main,
  '& .MuiInputBase-input': {
      ...theme.typography.h5,
  },
}));

export default function MyTypographyComponent() {
  return (
    <div>
      <ThemeProvider theme={theme}>
        <Typography variant="h3">Responsive h3</Typography>
        <MyTextField/>
      </ThemeProvider>
    </div>
  );
}
```

※ ちなみに`responsiveFontSizes`を使うとmui側で設定されたレスポンシブなサイズを付与できる。
https://mui.com/customization/typography/#responsive-font-sizes
ディレクトリ構成図　参考サイト

https://qiita.com/townsoft/items/9452221f308554ba823a

### 先人のディレクトリ構造を真似る

まずは人が作った構成を真似てプログラムを配置するディレクトリ構造を考える。
間違ってても良いのでディレクトリ構成を先に作ってみる。


### 肝となるプログラムを考える

肝となる部分がどこかを見極め、その肝となるプログラムを軸に構成を組み立てる。
初めの一歩としては小さなプログラムの中で重要となるプログラムを見極める力を培うのは重要な事。

### ボトルネックとなりそうな部分の洗い出しと下調べ

ボトルネックを見極める事も重要

実際に現場でアーキテクチャーとして働く場合はボトルネックを先に調べないと、最後の最後に悲劇が待っている場合も。最後に実現不可能な事に気付き、泥臭い方法で回避するような局面を迎える等。。。

### 便利なサイト

https://qiita.com/paty-fakename/items/c82ed27b4070feeceff6
TD Toolbelt使ってみた

# はじめに
　TreasureData(以降TDとする)を利用する機会があり、TDに保存されているジョブに使用されているクエリを定期的に更新したいという要望があったためtdtoolbeltを用いトライしてみた記録になります。

# TD Toolbelt
TD Toolbeltを使用すると、コマンドラインインターフェイスを使用してTreasure Data機能にアクセスできます。TD Toolbelt WindowsおよびMacオペレーティングシステムでのみ使用できます。（引用：公式サイト）

# 使ってみた
 今回はテスト用にローカル環境から更新してみることにし、実行環境はDocker環境-ubuntuで用意した

### 1,rubyのインストール
```
# git clone https://github.com/rbenv/rbenv.git ~/.rbenv
Cloning into '/root/.rbenv'...
 
# git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
Cloning into '/root/.rbenv/plugins/ruby-build'...
 
# echo 'export PATH="$HOME/.rbenv/bin:$PATH"' > ~/.bashrc
root@7bb5a4d5c672:/usr/src# echo 'eval "$(rbenv init -)"' > ~/.bashrc
root@7bb5a4d5c672:/usr/src# source ~/.bashrc
 
# rbenv install -l
2.6.8
2.7.4
3.0.2
jruby-9.2.19.0
Downloading ruby-2.7.4.tar.bz2...
 
# rbenv global 2.7.4
# rbenv version
2.7.4 (set by /root/.rbenv/version)
```

### 2,tdコマンドをインストール
```
# gem install td
Fetching fluent-logger-0.9.0.gem
Fetching hirb-0.7.3.gem
 
#  which td
/root/.rbenv/shims/td
# td --version
0.16.9
```
### 3,ApiKeyなどの登録
```
# $ td apikey:set XXXXXXXXXXXXXXXXXXXXXXXXX　#apikey登録
# less ~/.td/td.conf #KEYはここに
 
# td
usage: td [options] COMMAND [args]
 
options:
  -c, --config PATH                path to the configuration file (default: ~/.td/td.conf)
  -k, --apikey KEY                 use this API key instead of reading the config file
  -e, --endpoint API_SERVER        specify the URL for API server to use (default: https://api.treasuredata.com).
                                     The URL must contain a scheme (http:// or https:// prefix) to be valid.
                                     Valid IPv4 addresses are accepted as well in place of the host name.
      --import-endpoint API_IMPORT_SERVER
```
ここまででTDコマンドの実行準備完了です。
あとは定期的に下記コマンドを実行するようにプログラムを組むだけです
```
td sched:update <job_name> -q <query>
```
# おわりに
あまり触れることのないTDですが、コマンドラインからの実行も簡単ですし、コマンドの種類も充実しているので、目的の遂行はスムーズに果たせたと思います
# 参考
・[TD Toolbelt(公式)](https://docs.treasuredata.com/display/public/PD/TD+Toolbelt)
ビューやコントローラー以外で `user.avatar` のurlにアクセスする


ビューやコントローラーでは `url_for` や `rails_blob_path` といったヘルパーメソッドが使える。しかし、それ以外の箇所ではこれらのメソッドをそのまま使うことができないため、ファイルのURLにアクセスするには `Rails.application.routes.url_helpers.rails_blob_path` のような長い記述が必要になる。

開発環境の場合は特に `default_url_options[:host]` を `localhost:3000` などにセットしておく必要がある。

```rb:development.rb
Rails.application.routes.default_url_options[:host] = 'localhost:3000'
```

また `include Rails.application.routes.url_helpers` のようにすることで `rails_blob_path` をそのまま使えるようにすることも可能。

```rb
class User < ApplicationRecord
  has_one_attached :avatar
end

class UserSerializer < ActiveModel::Serializer
  include Rails.application.routes.url_helpers

  def avatar
    rails_blob_url(object.avatar) if object.avatar.attached?
  end
end
```

### 参考
- https://railsguides.jp/active_storage_overview.html#%E3%83%AA%E3%83%80%E3%82%A4%E3%83%AC%E3%82%AF%E3%83%88%E3%83%A2%E3%83%BC%E3%83%89
- https://github.com/rails/rails/issues/32500#issuecomment-435083770
Qiitaでの情報発信で就職活動が有利になった話

# はじめに

私は、アプリ系SIerから内定を頂き、就職活動を3月に終えた大学3年生(2022年3月現在)です。
就活をしていく中で、**「Qiitaでの情報発信」がかなりプラスに働きました**
これから就職活動をする大学生にとって少しでも参考になればと思い、書かせていただきます。

# 私の特徴

「そもそもどんな状況で就活に臨んだのか」というところは気になると思いますので、記しておきます。

・大学の情報学科に通う、大学3年生
・個人的にアプリ開発の勉強はしていたが、インターンでの経験は無し
・特に受賞歴は無し

要するに、ちょっとアプリ好きな大学生です笑

内定は3つの会社から頂きました。

# 作戦

私は就活をするにあたり、

・積極的に学ぶ姿勢
・個人的にアプリ開発の勉強をしている
・Qiitaで機械学習やアプリ開発の記事を書いている(もちろん大した記事ではないと思うが…)

この3つをアピールしようと作戦を立てました。
個人的には「開発の勉強をしている」が「積極的に学ぶ姿勢」に繋がり、良いアピールになると考えました。

# 面接開始！
それでは、面接の様子を書きます。

面接官・・・面

自己紹介や志望理由などが終わり…

面「それでは今、頑張ってることを教えてください」

私「はい。個人的にアプリ開発の勉強をしていて、GitHubに作ったアプリを公開してます」

面「へー、どんなアプリ作りましたか？」

私「一つ目が…」
と作ったアプリの説明をして、

面「なるほど、自発的に取り組んでいるんですね」

まずまずの反応。こんな人もいるか、ぐらい。
そして…

面「ほかに何かありますか？」

私「はい。機械学習やアプリ開発の勉強でつまづいて、解決したことをQiitaに書いてます。」

面「へー！どのアカウントですか？見たいです！」

**好反応！！**
その後も…

面「なんでQiitaをやろうと？」

私「解決したことを自分だけに留めておくのは、もったいないと思いまして…」

面「へー！偉いですね！」
と**良い感じで面接が終わりました！**

**１つの会社だけではなく、複数で好反応でした！**

# なぜ好反応だったのか？

まず、「アプリ開発の勉強」がまずまずの反応で終わった理由としては、
・自主的にプログラミングをしている人はいっぱいいる
・アプリのレベルがまだまだ
が考えられます。
アプリのレベルに関しては、自分も「シンプルなアプリしか作れないな」と思っていました。

そして、「Qiitaでの情報発信」が好反応だった理由としては、
**・Qiitaで発信してる大学生は珍しい？(データは取れてません)**
**・アウトプットを大切にしてる姿勢が良かった**
が考えられます。
1つ目に関してはデータが取れていませんが、少なくとも「プログラミングを勉強している大学生」より「Qiitaで記事を書いている大学生」の方が少ないのは間違いないと思います。(プログラミングしてないのに、Qiitaで記事を書く人はいませんので)
2つ目はエンジニアとして「アウトプット」が重要なことから分かります。

# じゃあ、全部に受かったの？
「それだけ有利に働いたなら、全部の企業に受かったの？」と思うかもしれません。
結果としては、全て受かることは出来ませんでした。ただ、落ちたのは「コーディングテスト」や「ポートフォリオ」で落ちたので、面接としては効果がありました。
(Qiitaで記事書いてるのにコーディングテスト落ちたのかよ、というのは心に閉まってください笑)

# おわりに
私は「就活のためにQiitaを始めろ」とは言いません。
ただ、学生なりにプログラミングを勉強して得た知識を発信するのは誰から見ても高評価に繋がります。
この記事をきっかけに「ちょっとQiitaやってみよかな？」と思っていただければ幸いです。
[iOS] アプリ終了時　プッシュ通知表示


・プッシュ通知受信　アプリが起動中に受信した場合

~~~
-(void)application:(UIApplication *) application
    didReceivedRemoteNotification:(NSDirctionary *)usetInfo {
}
~~~



・プッシュ通知受信-アプリがフォアグランドの状態である場合に、通知表示前にコールされる

~~~
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
    willPresentNotification:(UNNotification *)notification
    withCompletionHandler:(void(^)(UNNotificationPresentationOptions))completionHandler{
    NSLog(@"Push通知受信");
}
~~~


・プッシュ通知受信-ユーザーが通知をタップ後にコールされる

~~~
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
    didReceiveNotificationResponse:(UNNotificationResponse *)response
    withCompletionHandler:(void(^))completionHandler{
    NSLog(@"Push通知受信");
}
~~~
・アプリ未起動時のプッシュ通知タップイベント受取
>func application(_:didFinishLaunchingWithOptions:)

~~~
-(BOOL) application:(UIApplication *)application
  didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
}
~~~
CellRangerでsingle cell RNAseq解析

single cellのalignment toolで10X社が提供しているCellRangerのセットアップと解析を行う。
Ubuntuを使う。

まずは、スペックの確認。
以下が、要求スペック。

Cell Ranger pipelines run on Linux systems that meet these minimum requirements:

8-core Intel or AMD processor (16 cores recommended)
64GB RAM (128GB recommended)
1TB free disk space
64-bit CentOS/RedHat 6.0 or Ubuntu 12.04

自分のを調べるためには、
```terminal:system_requirement
CPUmodel
grep -m 1 'model name' /proc/cpuinfo
CPUcore
grep -c processor /proc/cpuinfo
Memorytotal
grep MemTotal /proc/meminfo
storage
df -Ph
```

次に、10X社のページからソフトとリファレンスをダウンロードする。
https://support.10xgenomics.com/single-cell-gene-expression/software/downloads/latest

```terminal:soft&reference_downloads
mkdir cellranger_downloads
cd cellranger_downloads
#cellrangerのダウンロード
wget  -O "10Xのページからcellrangerのリンクをコピー"
#referenceのダウンロード
wget -O "mouseかhumanのreferenceが必要ならリンクをコピーしてダウンロード"
```
ここからは、https://support.10xgenomics.com/single-cell-gene-expression/software/pipelines/latest/installation
に沿ってinstall

```terminal:cellranger_install
#referenceの解凍
cd /opt
sudo tar -xzvf ~/cellranger_downloads/refdata-gex-GRCh38-2020-A.tar.gz
sudo tar -xzvf ~/cellranger_downloads/cellranger-6.1.2.tar.gz
#PATHのexport
export PATH=/opt/cellranger-6.1.2:$PATH
#testrun
cellranger testrun --id=tiny
...
Pipestance completed successfully!
...
#結果の確認。うまくいっているとoutsやsc_RNA_COUNTER_CSなどが出力されている。
#ls tiny/
...
SC_RNA_COUNTER_CS outs
...
```

ここから実際のサンプルを使って実行。
fastqファイルは以下のような階層になっている。
referenceは上でダウンロードしてきた10Xが提供してくれているものをありがたく使う。
（自分で作るとまぁまぁ時間かかる。)

```terminal:fastqs
CONTROL_fastqs
    ├── CONT_S1_L007_I1_001.fastq.gz
    ├── CONT_S1_L007_I2_001.fastq.gz
    ├── CONT_S1_L007_R1_001.fastq.gz
    ├── CONT_S1_L007_R2_001.fastq.gz

```

```terminal:cellranger
cellranger count --id=test --fastqs=/PATH/CONTROL_fastqs/ --sample=CONT --transcriptome=/opt/refdata-gex-GRCh38-2020-A/
```
--idは好きな名前をつければ良い。
--fastqsでfastqが入っているdirectoryまでのpathを指定。
--sampleは_S1の前の部分までを指定。
--transcriptomeはreferenceのdirectoryを指定。

あとは待つのみ。松の実。

しばらくほっとくと、結果が出力される。

```terminal:CellRanger_result
/test/outs/filtered_feature_bc_matrix
├── barcodes.tsv.gz
├── features.tsv.gz
└── matrix.mtx.gz

```
これをRに持っていってSeuratで解析（また次の機会）。
Power Automate で 複数行テキストを操作する

Power Automate を使っていて、SharePointのリストやFormsからアイテムを取得した際に、しばしば以下のような表示を目にしたことがあるのではないでしょうか。(赤文字の部分)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/b42411ac-d892-4443-d4dc-304c1a436a64.png)

これらは複数行テキストの列に格納されたデータを取得した時に発生します。例えば1個目の場合には改行コードが`\n`として見えています。
2個目の場合は、配列が文字列化されていますね。Formsで複数選択の設問をつくるとこんな感じで取れます。

このように、複数行テキストを値に持つようなケースにどう対応したらよいでしょうか？

# 例: 改行を消したい

1個目のような例で、改行を消したい場合。よくやりがちなのは「`\n`が余分だから`replace(....,'\n','')`で消してしまおう」というアプローチです。
残念ながらこの操作では期待通りの結果は得られません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/0e323817-7e9e-3277-9a2d-7b922fab31c9.png)

ではどうするのかというと、**改行コードを指定して消す** です。
上の例のように `\n`の場合 (LF)では、`decodeUriComponent('%0A')`が改行コードを表します。

※改行コードについてはこちらを参考に

https://www.tohoho-web.com/wwwxx011.htm

または `\r\n`で改行されている場合 (CRLF) には、`decodeUriComponent('%0D%0A')`が改行コードを表します。
これらを踏まえて、改行を消す場合の式は

```
replace(....,decodeUriComponent('%0A'),'') //LF(\n)の場合

replace(....,decodeUriComponent('%0D%0A'),'') //CRLF(\r\n)の場合
```

# 例: 改行で分割したい
例でいうと下図のように改行で分割して配列にするようなケースです。これもまあまあありますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/97c8e892-e454-6c9e-06d0-059d7418e1ef.png)

この時も改行コードで分割するということを念頭に置くと、必要な式は

```
split(....,decodeUriComponent('%0A')) //LF(\n)の場合

split(....,decodeUriComponent('%0D%0A')) //CRLF(\r\n)の場合
```
となります。

# 例: JSON/配列をJSON/配列として扱いたい

最後にJSONオブジェクトや配列が文字列になっているケースです。これもよくやりがちなのは「ダブルクォーテーションが `\"` となっているから `"`で置換しよう」です。
もちろんうまくいきません。

こんなケースでは素直に`json()`関数を利用します。

https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference

単純な1個の関数で対象の列を囲んであげると・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/b953d549-55ec-5b9a-be61-0b7996b88794.png)

期待通り、配列になってくれています。オブジェクトの場合にも同様です。


# おわり

複数行テキストって便利なんですが、加工して利用しようと思うと少しハードルがありますね。
あとはAPIの仕様によっても、JSONが文字列化されて返されるケースもあります。

そんなときには今回ご紹介したようなアプローチを試してみてください。

[MoreBeerMorePower](https://mofumofupower.hatenablog.com/)もよろしくね！
ActiveStorageでN+1回避のための `with_attached_#{name}` が使えないとき


Userモデルから10件取得し、それぞれのavatarを参照する場合を考える。
何も考えずにやるとN+1クエリの問題が発生してしまう。

```rb
class User < ApplicationRecord
  has_one_attached :avatar
end

# N+1クエリが発生する
User.limit(10).each do |user|
  p user.avatar.attached?
end
```

N＋1クエリを回避するためには `with_attached_#{name}` という [scope](https://github.com/rails/rails/blob/166b63eb674b56faf4f75dfe300b14f00fb79dae/activestorage/lib/active_storage/attached/model.rb#L66
) が使える。[^1]

[^1]: `has_many_attached` の場合は [こちら](https://github.com/rails/rails/blob/166b63eb674b56faf4f75dfe300b14f00fb79dae/activestorage/lib/active_storage/attached/model.rb#L154)

```rb
# with_attached_#{name} を使えば回避できる
User.limit(10).with_attached_avatar.each do |user|
  p user.avatar.attached?
end
```

ただし `with_attached_#{name}` は内部的には [includes](https://railsguides.jp/active_record_querying.html#includes) を使っているため、たとえばUserモデルの主キーがRails標準の `id` ではなく、独自のstring型の `user_id` を利用していた場合には、このスコープは使えない。

そのような場合にActiveStorageのテーブルから直接一括取得して回避する方法がある。
具体的には以下のようにする。

```rb
avatars = ActiveStorage::Attachment.where(
  record_type: 'User',
  name: 'avatar',
  record_id: User.limit(10).ids.map(&:to_i)
).preload(:blob)

User.limit(10).each do |user|
  avatar = avatars.detect { |a| a.record_id == user.id }
  p avatar&.attached?
end
```
Apache と Nginx の比較　参考サイトと自分用メモ

https://www.geekly.co.jp/column/cat-technology/1903_096/

https://kinsta.com/jp/blog/nginx-vs-apache/

https://qiita.com/kamihork/items/49e2a363da7d840a4149

#### 処理
___Apache___
アプリケーション、データベース、動的コンテンツなどの動的コンテンツのような重たい処理が得意

___Nginx___
大量の同時接続数に耐えることができる。速い速度でコンテンツを提供することができる。

#### 設定
___Apache___
設定に `.htaccess` を使用する。

https://www.kagoya.jp/howto/it-glossary/web/htaccess/


___Nginx___
設定システムを持っていない

#### モジュール
___Apache　___
ウェブサーバーのインストールとデプロイが完了した後に、モジュールをインストールし、 必要に応じて有効化/無効化できる。

___Nginx___　
通常ビルド時に有効にする必要がある。これにはより技術的な能力が必要であり、モジュールのインストール後の追加はやや複雑。

#### 効果的なサーバー構築

___Apache___ は ___少量の同時接続数で重い処理___ を担当させ、 __Nginx__ には __大量の同時接続数や軽い静的コンテンツ__ を担当させることで効果的なサーバ構築ができます。

また、 __大量の同時接続数で重たい処理の場合__ は ___Nginxをリバースプロキシサーバー___ として利用して、 ___動的コンテンツはApacheに処理させる___ という相互の利用も効果的です。
Next.jsで今の場所（current url）を取得

業務でcurrent urlを使用する機会があったのでメモ。

# useRouter
Next.jsにはuseRouterというhookがあるので、そちらを使用しました。

# URLを取得する方法
```JavaScript:JavaScript
import { useRouter } from "next/router";

const router = useRouter(); 

console.log(router.pathname)
// http://localhost:3000/aaa/bbb ▶︎ /aaa/bbb
```
useRouterを使うことで現在のページのドメイン以下のURLを取得することができます。

# routerオブジェクト
※よく使いそうなもの

## pathname

`router.pathname`でドメイン以降のpathが取得できます。
パラメータやクエリは取得できず、たとえば
`http://localhost:3000/blog/[id]`の[id]の動的ルーティング部分は取得できません。

## asPath
`router.asPath`でドメイン以降のpathと[id]の中身も文字列で取得できます。
`http://localhost:3000/blog/[id]`の[id]の中身が[aaa]ならば`/blog/aaa`で取得できます。

## query
`router.query`でオブジェクトとして動的ルーティングの中身を取得できます。
`http://localhost:3000/blog/aaa`の[aaa]が[id]の場合{ id: 'aaa' }として取得できます。

そのほかにも色々あるみたいなので気になる方は調べてみてください。
[https://nextjs.org/docs/api-reference/next/router](https://nextjs.org/docs/api-reference/next/router)
ローカルブランチをリモートのブランチに強制的に合わせたい時には・・・

## やりたいこと
Gitのローカルブランチをリモートブランチの最新状態と同じにしたい。

## ことの発端
ローカルのmasterブランチで修正を行ったが、revertとか色々行ってるちによくわからなくなってしまったので、ひとまずリモートブランチが正しいのでそこに合わせたかった。

![スクリーンショット 2022-03-10 15.06.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1583420/c028d996-76f0-12cd-13d2-dd605bfe8ebf.png)

一度revertしたがためにその後のpullした差分がどんどん広がっていく。。。。。

## 【注意】前提条件
```
今回の対処法は、現在のブランチがmasterにマージされていないことが条件です。
ローカルでの変更がまだ反映されていないことを確認してください。
```

## 細かいことはどうでいい。とりあえずローカルのブランチをリモートに強制的に合わせたい。

```
git fetch origin
git reset --hard origin/対象のブランチ
```
で解決できる。

例えば`master`ブランチをやる場合は
```
git fetch origin
git reset --hard origin/master
```

`feature/hogehoge_fugafuga`ブランチなら
```
git fetch origin
git reset --hard origin/feature/hogehoge_fugafuga
```

となる。

#### 参考文献

https://leaclaw-media.com/reset-hard/

https://www.r-staffing.co.jp/engineer/entry/20191129_1
DocumentRoot とは  /  設定ファイルの置き場所

### 参考サイト

https://gihyo.jp/admin/serial/01/unix/0008

__DocumentRoot__ とはWeb上に公開することのできるディレクトリのルートのことです。

設定方法としては，見せたいディレクトリのパスを指定をします。すると，その __ディレクトリ配下のファイル__ へ __すべてアクセスができる__ ようになります。

たとえば，DocumentRoot直下に `foo.html` というファイルを配置をします。
すると `http://servername/foo.html` というURLで対象のファイルにアクセスをすることができます。

DocumentRootの設定は __慎重に__ してください。

DocumentRootに置いた __秘密情報が漏洩する__ といったことは常にありえます。“⁠ユーザに見せてはいけないものをリストアップする（ブラックリスト方式）⁠”という考え方では必ず漏れがでてしまいます。トラブルを回避するためにも， __“⁠ユーザに見せるべきコンテンツをリストアップする（ホワイトリスト方式）⁠”__ 方法の採用を検討しましょう。


### ファイルの置き場所に関して

https://teratail.com/questions/166004

質問
Mysqlのユーザー名やパスワードが書かれてあるファイルを安全に保管するためには、どこに置くのが良いのでしょうか？

回答
設定ファイルは基本的にWebから __アクセスできない__ 場所に置くものだと思います。
Laravel　共通関数作成

コントローラー等で使いたい共通関数の作成方法。
app/ 直下にフォルダを作成しその中にファイルを作成。今回はLibraryフォルダを作成した。

```php:app/Library/Hoge.php
<?php

namespace App\Library;

use Illuminate\Support\Facades\Facade;

class Hoge extends Facade
{
    public function fuga ()
    {
        //処理を書く
    }

}
```

エイリアス登録。
登録はしなくてもuse使用すればOK。
```php:config/app.php
'Hoge' => App\Library\Hoge::class,
```

コントローラーから呼び出し
```php:app/Http/Controllers/UserController.php
\Hoge::huga();
```
Precompiling assets failed. Herokuデプロイエラー解決法

## エラー内容

いつも通り```git push heroku main```でデプロイしようとしたら、```Precompiling assets failed.```なるエラーが発生🤯



## 開発環境
Rails６系
Ruby３系
Herokuデプロイ済



## 結論
```manifest.js```の```//= link_tree```で指定していたディレクトリが空だったので、そこにファイルを入れたらエラー解消しました！！！


## 解決に至るまで

<font color="LimeGreen">その１</font>
```Precompiling assets failed.```エラーが発生

<br>
<br>

<font color="LimeGreen">その２</font>
```terminal:terminal
% heroku logs --tail
```
でエラー詳細を確認→「Herokuのダッシュボードのログを見よ！」とのログとリンクを発見

<br>
<br>

<font color="LimeGreen">その３</font>
```terminal:HerokuダッシュボードActivityのログ
〜省略〜
rake aborted!
Sprockets::ArgumentError: link_tree argument must be a directory
```
ログ内に上記メッセージを発見！
翻訳をかけると、、、
```terminal:HerokuダッシュボードActivityのログ
rake aborted!
Sprockets::ArgumentError: link_tree 引数はディレクトリでなければなりません。
```

<br>
<br>

<font color="LimeGreen">その４</font>
翻訳からlink_tree記載箇所を確認
```javascript:assets/config/manifest.js
//= link_tree ../images
//= link_tree ../music
//= link_tree ../json
//= link_directory ../stylesheets .css
```
こちらの```/json```フォルダが空ということに気づく。

<br>
<br>

<font color="LimeGreen">その５</font>
```/json```にファイルを入れて再度herokuにpushしたら無事通りました🎉

<br>
<br>

<font color="LimeGreen">まとめ</font>
```//= link_tree```で指定したディレクトリ内には、何らかのファイルを入れておかないと、プレコンパイルエラーになるみたいです⚠️


## 最後に
Herokuデプロイ時のエラー内容は多岐に渡るので、本記事で解決できるとは限りませんが、多くの悩める方に届けば幸いです🌱
Apacheログの探し方

## httpd.confの場所を探す
こちらの記事が参考になった

https://qiita.com/s2maeda/items/21d9458e44f86597d1ae

## httpd.confでログの場所を確認
httpd.confで
 - `CustomLog` をgrep→ログのパスとどのフォーマットを使ってるかチェック（ログのパスは`ServerRoot`からの相対パスになっているので`ServerRoot`もgrepする）
```
ServerRoot "/etc/httpd"
CustomLog "logs/access_log" combined env=!nolog
```
→　「ログの場所は `/etc/httpd/logs/access_log` で、フォーマットは`combined`」ということがわかる

## フォーマットを確認

- httpd.confで`LogFormat` をgrep→実際のフォーマットをチェック
```
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
```
→ 「（このサーバーでは`combined`が使われているので)ログのフォーマットは `%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"`」ということがわかる

フォーマットの見方はこちらが参考になった
https://qiita.com/ryounagaoka/items/e7782ab29ff9fbe8f891
Jetson Nano 環境構築メモ 

## IP固定

有線LANのIPを192.168.1.27へ。
```sh
$ nmcli connection show
NAME                UUID                                  TYPE      DEVICE  
Wired connection 1  74834813-6545-3009-8897-6e6d5e83232e  ethernet  eth0    
docker0             7d8c5b9e-03fd-4c0d-9f04-d84f371ed579  bridge    docker0 
```
名前を確認したら
```sh
$ sudo nmcli -f ipv4 con mod "Wired connection 1" ipv4.addresses "192.168.1.27/24"
$ sudo nmcli -f ipv4 con mod "Wired connection 1" ipv4.gateway  "192.168.1.1"
```
（gatewayの設定は必要なのか不明。ど素人なので一応設定。）

```sh
$ sudo vi /etc/network/interfaces

auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
        address 192.168.1.27/24
        gateway 192.168.1.1
        dns-nameservers 192.168.1.1
```

## GUI 無効／有効

```sh
$ sudo systemctl set-default multi-user.target # 無効
$ sudo systemctl set-default graphical.target # 有効
```


## VNCを使う
https://developer.nvidia.com/embedded/learn/tutorials/vnc-setup
解像度が640x480のため変更するには
https://qiita.com/otomon10/items/7b219e0a9a98ae22ba71

## デスクトップの文字を大きくする
OSインストール直後、なぜかデスクトップの文字が小さくなっているので
```sh
sudo nano /usr/share/lightdm/lightdm.conf.d/50-xserver-command.conf 
```

-dpi 96を追加する。
```text:例
[Seat:*]
# Dump core
xserver-command=X -core -dpi 96
```

参考：https://www.1br.de/menu-and-desktop-font-too-small-to-read-on-nvidia-jetson-nano-on-tv/
Array と Parameters の `select!` について

# `Array#select!` と `Parameters#select!` の返り値が違う

- `Array` の方は，ブロックの返り値の全部が `true` を返した場合に `nil`を返している
    - 変化が無いので `self` を返さないとのこと
- `ActionController::Parameters` の方は，最後に `self` を強制的に返すようになっている

普通はひっかからないと思うけど，これに依存したコードを書くのは良くなさそうなので，一応記す．
→ `select!` を使わないだろう．の意

## Refs

- https://docs.ruby-lang.org/ja/latest/class/Array.html#I_FILTER--21

```ruby
a = %w{ a b c d e f }
a.select! {|v| v =~ /[a-z]/ }   # => nil
a # => ["a", "b", "c", "d", "e", "f"]
```

- https://apidock.com/rails/v6.1.3.1/ActionController/Parameters/select%21

> Equivalent to Hash#keep_if, but returns nil if no changes were made.


```ruby
    def select!(&block)
      @parameters.select!(&block)
      self
    end
```

- https://docs.ruby-lang.org/ja/latest/class/Hash.html#I_FILTER--21

> keep_if は常に self を返します。 filter! と select! はオブジェクトが変更された場合に self を、されていない場合に nil を返します。
T3のCPUクレジットの料金確認方法

請求ダッシュボード->請求書に出てた。Elastic Compute Cloudのツリーを展開する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/936820/17791527-a12f-8e30-3bb4-6a97f4828199.png)

1vCPUあたり1時間クレジット消費で5円くらいかかるみたいだけど、僕の環境では(CPUクレジット無制限のT3インスタンス複数あるけど)料金は発生していないようだった

ちなみに真ん中の```0.001 vCPU-Hours```が実際のクレジット稼働時間のよう。別の月の請求書見ると、そちらは0.002になってた。これが1に達すると課金が発生するということか。
SubstrateのPermissioned Networkでノードを削除してみる

# はじめに

[Substrateのチュートリアル](https://docs.substrate.io/tutorials/v3/)に[Permissioned Network](https://docs.substrate.io/tutorials/v3/permissioned-network/)というセクションがあります。
こちらのチュートリアルでは許可制ネットワーク(Permissioned Network)へのノードの追加の手順は記載がありますが、削除する記載がないため今回の記事では許可制ネットワークでどのようにノードを削除するのか？(ブロック同期させなくするか？)を簡単にですが紹介します。

# 導入手順

### Permissioned Networkを実行

[Start a Permissioned Network](https://docs.substrate.io/tutorials/v3/permissioned-network/)のチュートリアルをページにしたがって実行しておきます。
こちらのチュートリアルでは主に以下を実行しています。

1. node-authorization pallet追加
1. Permissioned Networkのノード起動

チュートリアルが終わると以下のようにAlice, Bob, Charlieはそれぞれ繋がっていて、DaveはCharlieのみと繋がった状態のノード構成になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2560317/237eab7c-ef13-99d0-3f70-3dbfa4ab2013.png)

Alice, Bob は初期設定でWellKnownNodesとしてすでに登録されていて、その後Sudo権限でのaddWellKnownNodeというメソッドを使用してCharlieをネットワークに参加させています。
DaveはCharlieへの接続にclaimNodeメソッドでまず自分自身を宣言した後に Dave, CharlieそれぞれがaddConnectionsを使ってお互いにネットワーク通信する事を許可しています。

# 確認手順

チュートリアルには記載がない、参加したノードをネットワークから切り離す、という事をしてみます。
チュートリアルを終わらせた上での環境を前提としてこれからの手順を記載していきます。

### Daveの切り離し(removeClaim)

Charileにのみ接続しているDaveをネットワークから切り離すには、removeClaimメソッドを実行します。
removeClaimメソッドを使用することによってaddConnectionsで繋げた情報も全て削除することができます。

やり方はチュートリアルで実行したブロックチェーンノード４台全てを動かした状態で、ブラウザから[Polkadot-JS application](https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/extrinsics")のExtrinsicsページにアクセスします。

表示されたページで以下を指定し[トランザクションを提出]ボタンを押します。

- 選択されたアカウントを使用する - Dave
- 次のextrinsicを提出する - nodeAuthorization.removeClaim
- node - DaveのPeerId(チュートリアルに記載があります)

![image.png](https://user-images.githubusercontent.com/1214532/156112351-f00d2a47-b139-45f3-8fd2-38d272e59bc9.png)

上記を実施した後にブロックにtx(トランザクション)が取り込まれると、Daveのノードはブロック同期がされなくなります。

### Charileの切り離し(removeWellKnownNode)

CharlieはSudo権限でaddWellKnownNodeメソッドを使ってノードをネットワークに追加しました。
このため、逆にSudo権限でremoveWellKnownNodeメソッドを使ってノードをネットワークから削除します。

ブラウザから[Polkadot-JS application](https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/sudo")のSudoページにアクセスします。

表示されたページで以下を指定し[Sudoを提出する]ボタンを押します。

- 以下の変更を提出する - nodeAuthorization.removeWellKnownNode
- node - CharlieのPeerId

![image.png](https://user-images.githubusercontent.com/1214532/156112748-9d51c358-3f73-4c51-af02-2a061727cb83.png)

上記を実施した後にブロックにtx(トランザクション)が取り込まれると、Charlieのノードはブロック同期がされなくなります。

# 終わりに

許可制ネットワーク（Permissioned Network)でのノードの削除(ブロック同期させなくする)を今回試してみました。
ブロックチェーンの思想とは異なる部分(管理者がいるという点)があるかもしれませんが、管理者がいる、もしくは統治しやすいブロックチェーンネットワーク（コンソーシアムなど）の際には、ノードの追加や削除を行えないと実運用は難しいと思いますので、今回の記事の内容は覚えておいておいた方が良いかもしれません。

# 参考

https://docs.substrate.io/tutorials/v3/permissioned-network/
「これ、何のためにやってるの？」をまとめてみました【Node.js】

## はじめに
Node.js初学者が、N予備校のプログラミング入門コースを一通り勉強して、少し忘れてしまってる部分や「これ、何のためにやってるの？」という部分を洗い出してみました。

## GitHub
```
ssh-keygen
```
秘密鍵`id_rsa`と公開鍵`id_rsa.pug`を作成する
　このうち、公開鍵をGitHubに登録する。

```
ls /.ssh
```
ここに作られていることを確認する。

### pushする際の設定
```
git config --global user.name "名前"
git config --global user.email メールアドレス
git config --global core.editor "vim"
```
設定しない場合、PCにログインしているユーザー名で`Commit`される。というかされた。

## Node.js
### nvm
Node.jsのバージョン管理を行うツール

```
nvm install v10.14.2
```
Node.jsのインストール

### yarn
Node.jsで使えるパッケージマネージャ

```
yarn init
```
npmパッケージ化。`package.json`が作られる。

```json:package.json
"scripts": {
    "start": "node ./bin/www",
    "test": "jest --testTimeout=20000 --forceExit",
    "test:unit": "jest --maxWorkers=1"
  }
```

`scripts`に追加することで、`yarn test`など省略して書けるようになる。

```
yarn add
```

依存関係のあるパッケージも一緒にインストール。
`package.json`に情報が`dependencies`の項目に書き込まれる。

```
yarn install
```
`dependencies`に書かれたパッケージをインストール。
`node_modules`がgitignoreされている場合など、`node_modules`のディレクトリに何も格納されていない時は忘れずに実行する。

#### yarn.lock
インストールしたパッケージのバージョンが記述されている。

### Docker
```
docker-compose up -d
```

`-d`がない場合、バックで起動するがログは出力されない。

```yml:docker-compose.yml
version: '3'
services:
  app:
    build: .
    tty: true
    ports:
      - 8000:8000
    volumes:
      - .:/app
      - /app/node_modules
```

`volumes`
Mac/Windows側の`.`と dockerコンテナの`./app`を同期する。

## npx
`npm`コマンドの一つ。
ローカルにインストールされたモジュールを直接実行できる。
```
node node_modules/.bin/jest -h
```
が、
```
npx jest -h
```

にできる。

## express
```
yarn global add express-generator@4.16.0
```
expressの雛形を作る。

### webpack
複数ファイルのJavaScriptを一つのファイルにまとめられる、モジュールハンドラー。
```
npx webpack
```
`webpack.config.js`の情報をもとに1つにまとめる。
クライアント側のJavaScriptを変更した場合に使う。

## テストの高速化
```yml:docker-compose.yml
volumes:
     - .:/app
     - /app/node_modules
```
```json:package.json
"scripts": {
    "start": "node ./bin/www",
    "test": "jest --testTimeout=20000 --forceExit",
    "test:unit": "jest --maxWorkers=1"
  }
```
`jest`の実行が早くなる。


## まとめ
もう少しうまくまとめられたらよかったんですが。
あと誤解している部分もあるかと思うので、その辺りは指摘していただければ。
Harbor Server を立てましょう

　Harbor は OSS の container registry でありながら、vSphere with Tanzu に内蔵したり、TKG の付帯 package で提供されたりする Tanzu と相性が良い registry です。

　vSphere with Tanzu の場合は workload cluster の有効化によって Harbor が自動的に展開されるし、TKG の場合、tanzu cli package 使えば、workload cluster に1ステップで構成することは可能ですが、他の場合は手動で Harbor を構成する必要があります。

　構成方法も例えば Helm を使って K8S にデプロイする方法もありますが、今回は一番シンプルに [Harbor official docs](https://goharbor.io/docs/1.10/install-config/) に従って、VM として立ててみます。

# 準備
　Harbor Server の要件は下記のようです。

#### ハードウェア
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2385161/10129217-fd81-6462-4652-d11756a53c37.png)

#### ソフトウェア
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2385161/34753f52-7643-bdb5-b240-c2441be8df6b.png)

　今回の OS は Ubuntu 20.04.3 を使っています。
　Docker Engine / Docker Compose のインストールは
[Docker Engine Documentation](https://docs.docker.com/engine/installation/) / [Docker Compose Documentation](https://docs.docker.com/compose/install/) を参照しながら行いました。

　オンラインインストールを実施する場合、インターネットへのアクセスが必要です。

# ダウンロード
　[Harbor Release Page](https://github.com/goharbor/harbor/releases) からダウンロードします。
　オンラインとオフライン両方のパッケージがあります。今回はオンラインのパッケージをダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2385161/fe86dd04-9d55-268c-bf0b-1563696f2db7.png)

# インストール
　ダウンロードしてきたパッケージを解凍すると、harbor のフォルダーに harbor.yml とのファイルがあります。
これはインストールの設定ファイルとなります。まずはこちらのファイルを編集します。

　必須項目として

```yaml:harbor.yml
hostname: 外部からアクセスする際の FQDN / IP
http: http ポート
https: https ポートと証明書
harbor_admin_password: Harbar の admin user のパスワード
database: DB パスワード等
data_volume: データ保存用ディレクトリ、デフォルトは /data を使います
```

　https 証明書は self signed cert でも問題ないです。作り方はこちら [Openssl self signed cert Blog](https://www.baeldung.com/openssl-self-signed-cert) をご参照ください。

　他に proxy server などの設定もありますが、今回は default のままにしています。

　harbor.yaml ファイルが用意出来たら、harbor フォルダー内の install.sh スクリプトを実行します。

```
$ sudo ./install.sh
[Step 0]: checking if docker is installed ...
Note: docker version: 20.10.12
[Step 1]: checking docker-compose is installed ...
Note: docker-compose version: 1.29.2
[Step 2]: preparing environment ...
[Step 3]: preparing harbor configs ...
...
? ----Harbor has been installed and started successfully.----
```

# Harbor にアクセスみます
　インストールが完了後、ブラウザーからアクセスしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2385161/72f0b9b6-c467-e201-b276-6008ef2888db.png)
　ユーザ：admin
　パスワード：harbor.yml に設定した値
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2385161/2fa73933-91db-34bd-b8ed-2c44860e5291.png)

　Harbor の使い方等は今後書いていきます。
Rustに入門する。～Docker Composeを添えて～

# はじめに

卒研を通してGoの速度を知った男。どうも僕です。

Goを用いて卒研をしてたんですけど、シングルスレッド的に動作させると遅いねって言われてしまいました。
（まぁマルチスレッドに実装できなかった俺が悪いんですけどね）

有名なDiscordもGoからRustに移行しました。→[リンク](https://atmarkit.itmedia.co.jp/ait/articles/2002/10/news038.html)
そんなこんなでGoとRustは速度で比較されがち


そんなこんなでRust入門です。

# Dokcer Compose
docker-compose.ymlをとりあえずいいのあるかなーと思い、検索。

[Rustの開発環境を整えるまでにやったことメモ](https://qiita.com/irutack/items/0bcd225bfae574f03c55)

この記事を発見。

参考にしたけど、なんかエラーでたからとりあえず最小限で構成する。

```yml:docker-compose.yml
version: '3.7'

services:
  rust-dev:
    image: rust:latest
    container_name: rust_dev
    working_dir: /app
    volumes:
      - ./:/app
    tty: true
```
んでもって
```sh
$ docker pull rust:latest
$ docker-compose up -d
$ docker-compose exec --user 1000 rust-dev bash # バッシュに入る際、一般ユーザのidで入る
--- docker コンテナ ---
$ cargo new hello --bin
```

実行してみる

```sh
$ cd hello
$ cargo run

Hello, world!
```

以上。
とりあえずAtCoderの問題でも解いてみます