OmniAICreator/Qiita-1.07M huggingface dataset:
曜日のキーに気をつけよう

[いえらぶアドベントカレンダー](https://qiita.com/advent-calendar/2020/ielove-group)の4日目が空いていたので、勢いで、私が初めて対応した緊急メンテナンスの話を書こうと思います。


# 起こっていたこと
弊社が提供しているシステムの中にあるスケジュール機能について、**画面が開かない**とクライアントから連絡がありました。

スケジュール機能に近いところの修正は数日前に行っていたので、上司からも関連性を疑われましたが、開発者の私からすれば、関連しているわけがない、と思われるところで、原因の検討がつかなかったのと、障害対応をしたことがなかったので、高い緊張感とローカルや弊社のテストアカウントでは再現がとれないことに焦り、解決まで時間がかかってしまいました。

わかってしまえば単純(?)な話だったのですが、多大なレガシーであり、再発はなんとしても防ぎたい・エンジニア全員の頭に入れておいてもいい話だと思うので、原因とともに記載します。

細かいソースコード等は覚えていないし、あまり細かく書いても弊社のあれ的にあれだと思うので雰囲気で書きます。悪しからず。


## スケジュール登録画面

どのスケジュール機能にもあると思うのですが、「繰り返しスケジュール」を登録することができます。
その際に「何曜日に繰り返すか」を登録するフォームがあるのですが、それはこのように作られていました。

``` php
$week = [
    '0' => '日',
    '1' => '月',
    '2' => '火',
    '3' => '水',
    '4' => '木',
    '5' => '金',
    '6' => '土',
];
```


日曜日に繰り返す予定なら「0」、水曜日に繰り返す予定なら「3」、日曜日と土曜日に繰り返す予定なら「0/6」がデータベースに登録されます。

## スケジュール取得・表示処理

登録したスケジュールを表示する処理では、登録してあるデータが何曜日に繰り返すものなのか、foreachで判定を行っていました。

``` php

// データベースから取得したスケジュール
$scheduleData = [
    [0] => [
        'title' => '繰り返し予定',
        'week'  => '0',
    ],
    [1] => [
        'title' => '休日',
        'week'  => '3',
    ],
];

// 何曜日のスケジュールか判定
foreach ($scheduleData as $schedule) {
    $week = self::$checkWeek([$schedule['week']]);
}

static function $checkWeek= [
      '1' => '月',
      '2' => '火',
      '3' => '水',
      '4' => '木',
      '5' => '金',
      '6' => '土',
      '7' => '日',
];

```

おわかりでしょうか。

登録時は**0で登録していたはずの日曜日が7になっています**。

このせいで、`self::$checkWeek()`の引数に日曜日(0)が入ると、`$checkWeek`にキーが0の要素はないので、Fatal Errorになり、画面が映らないという事態になっていました。

そしてこの原因となった**処理が書かれたのは2年前**でした。


この処理事態がif文の中のif文の中のif文の中の...と階層の深いところにあったので、2年間この処理を通ることなく息を潜めていたのです。

# こんな悲劇がおきないために

曜日を登録するシステムを作る際は、何曜日はじまりか、キーは0からにするのか、しっかり決めて、**共通のメソッドを使いましょう。**

今回は、Commonフォルダに曜日の配列自体はあったのですが、なぜかそれを使っていなかったため、齟齬が起きていました。

しかも、日曜日以外はキーと曜日があっていたため、いくつもあるif文を全部通ったとしても、**日曜日以外は正常に動いていた**のも、開発時に気付かなかった要因かなと思います。
【18日目】トランザクションサポートデータベース実装

# まえがき
今までシリアライザブルなトランザクションをサポートするための仕組みについて説明・実装してきました。果たして、これでACID特性がどのように実装されたのかについて振り返ってみましょう。

## Atomicity(原子性)→△
原子性が守られているか検証してみる。トランザクションは高々一つしか実行できないので、各トランザクションの中で、原子性が守られれば良いということになる。

### コミットしない場合(トランザクションのキャンセル・アボート)
gitと同じように、トランザクション内での変更は各ローカル環境のみに閉じ込めておく実装にしたため、COMMIT以前にトランザクションがキャンセル、もしくはアボートされた場合はローカル環境を潰すだけでトランザクションがなかったことにできる。

### コミットした場合
トランザクションをCOMMITした場合はローカル環境の変更を共有データ領域に書き込むことになるが、もし共有データ領域の書き込み途中でプロセスが死んだりすると残念ながらデータベースは不整合な状態になる。

したがって、原子性を担保するためには、コミット途中でプロセスが死んだりエラーが発生した場合の処理について別途実装が必要である。

## Consistency(一貫性)→✕
RDBにおける一貫性の定義はいくつかあると思うが、「トランザクションが実行されたとき、データベースが次の状態に遷移し、それが想定通りでないことはない。」とするならば、原子性が満たされていない状態なので、一貫性も満たさない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201287/d742dedc-ed02-327d-97a5-cc2a0fe139e8.png)
データベースは各トランザクションの実行ごとに次の状態へと遷移していく。◯から◯へと。この◯から外れた状態に落ちることはあってはならないべき。しかし、トランザクションのコミット途中にプロセスが落ちれば、DBは中途半端な状態へと落ちてしまう。当然その後に続くトランザクションの処理も想定していない状態へと影響を与えてしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201287/4c1c4c89-0c77-4646-32b1-b9356dd881dd.png)
一貫性を担保するには、マリオカートで道を外れたときに救い上げてくれる「じゅげむ」のような存在が必要ということである。

## Isolation(独立性)→◯
今のところトランザクションは複数同時に実行できない前提であるため、トランザクションの分離レベルでいうSerializableが実装できた。

## Durability(永続性)→✕
共有データ領域を保持しているプロセスが死ぬと、メモリ上のデータが吹き飛ぶため永続性は明らかに担保されていない。もし、すべてのデータをファイルに書き込むことにした場合は、永続性がある程度担保される。なぜなら、プロセスが死んだとしても、プロセスを再起動し、ファイルを読み込むことでデータを復旧できるからである。プロセス再起動→データリカバリの手続きも実装しなければいけない。エラーリカバリについては、様々なケースが考えられるのでまとめて設計・実装する。

# まとめ

|             |     | 
| ----------- | --- | 
| Atomicity   | △  | 
| Consistency | ✕  | 
| Isolation   | ◯  | 
| Durability  | ✕  | 

トランザクションを高々一本しか実行できないように制限すると、ローカル/共有のデータ空間を分けることによって、ACID特性の一部分が実装できた。これからはエラーリカバリの挙動について、設計・実装していきAtomicity、Consistency、Durabilityを実装していく。
複数トランザクションをスケジューリングして、実行していく部分はさらにその後に。
「Factoryメソッドでドメインオブジェクトを生成する」という規約をArchUnitでテストする

## 概要

ドメインオブジェクト自体が複雑になってくると、その生成ロジックも同じく複雑になりやすい。

複雑化したドメインオブジェクトの生成ロジックをクライアント側にもたせると、ドメインが流出してしまう懸念がある。

上記の課題を解決するには、以下のような解決策が考えられる。

* ドメインオブジェクト自身にFactoryメソッドをもたせる
* ドメインオブジェクトの生成を責務とするFactoryクラスを用意する

今回は「ドメインオブジェクト自身にFactoryメソッドをもたせる」ことをArchUnitを使用して機械的にチェックしてみる。

## 実行環境
```
// build.gradle

dependencies {
    testImplementation 'com.tngtech.archunit:archunit-junit5:0.14.1'
}

test {
    useJUnitPlatform()
}
```

## テスト対象のイメージ

```java
// Hoge.java

public class Hoge {

    public Hoge create() {
        return this;
    }
    public void fuga() {}
    private Hoge(){};
}
```

## テストコード

```java

@AnalyzeClasses(packages = "com.example")
public class DomainObjectTest {

    // コンストラクタはすべてprivateであること
    @ArchTest
    static ArchRule domain_object_has_no_public_constructors =
        constructors()
            .that().areDeclaredInClassesThat().haveSimpleName("Hoge")
            .should().bePrivate();

    // Hogeクラスにcreateという名前の自身を返すpublicメソッドが存在すること
    @ArchTest
    static ArchRule domain_object_has_factory_methods =
        methods()
            .that().areDeclaredInClassesThat().haveSimpleName("Hoge")
            .and().haveName("create")
            .should().haveRawReturnType(Hoge.class)
            .andShould().bePublic();

```

テストしている内容はコメントに記載の通り。
新しいドメインオブジェクトが追加されたときでも、パッケージやクラス名で動的にテスト対象を追加できるような仕組みにできるとより実用的になりそう。
Xdebug3.xでProfilerを動かす雑な設定

## Profilerを動かす
偶然にも関わっているお仕事で「APIあたりのレスポンスタイムがよろしくない」という事象にぶち当たり「Profilerで確認してくれない？」というリーダーからのお達しが別のメンバーに来たものの「設定をしたことがない」というので私の方でProfilerの設定を調べました。

せっかくなので動作した設定をここに記しておきます。

## 設定
```ini
xdebug.mode=profile
xdebug.start_with_request=trigger
xdebug.trigger_value=""
```

簡単に説明します。

### mode
```ini
xdebug.mode=profile
```
modeでXdebugの各種動作モードを設定します。

Profilerの場合、時間などを計測しているので、もしかしたら他の機能は削除した方が良いかもしれないです。

### start_with_request
```ini
xdebug.start_with_request=trigger
```

`start_with_request`はリクエストが来たときにスタートするタイミングを設定します。

valueとしては3つ。

- yes
    - リクエスト開始と共に自動で開始
- no
    - 何もしない設定。ただし、xdebug_start_trace()やxdebug_break()でトレースは可能。リクエストで無条件では何もしないということ。
- trigger
    - Cookie等にトリガー用のパラメーターが存在すれば動作する。パラメーターにはXDEBUG_PROFILE/XDEBUG_TRACE/XDEBUG_SESSION/XDEBUG_SESSION_START等があり、それぞれの機能に紐付く

### trigger_value
```ini
xdebug.trigger_value=""
```

valueが設定してあれば、リクエスト時にそれを指定して動作させることが可能になります。

参考のように空の場合、XDEBUG_PROFILE={任意の値}のように好きな値を設定できます。おそらくこの挙動は「値が設定されたらトリガーオン！」ということだと思います。

## コンバート表
|以前の設定|新しい設定|
|:---:|:---:|
|profiler_enable_trigger|xdebug.mode=profileかつxdebug.start_with_request=trigger|
|profiler_enable_trigger_value|trigger_value|

## Xdebug Helper
リクエストトリガーの設定はブラウザの場合、各種ブラウザ向けの拡張機能が使えます。

拡張に関してはPhpStormのマニュアルにまとまっているのでリンク先を参照してください。

[ブラウザーのデバッグ拡張機能](https://pleiades.io/help/phpstorm/browser-debugging-extensions.html)

（ちなみにMicrosoft Edge用にはすでにMicrosoft Storeでも公開されてました）。

## Xdebug2.xからXdebug3.xの設定コンバートについては
ここに書かれていないXdebug2.xからXdebug3.xの雑な設定コンバートに関しては1つ前の記事もゼヒ参照してください。

[Xdebug3.0.0がリリースされたので、ver2からの雑な設定コンバート
](https://qiita.com/naoyukik/items/ef83fd9f59228694556d)

以上。
コロナ禍で表面化した負の遺産(Excel VBA)

# 要約
テレワークにより、自分の派遣先の負の遺産が可視化された。
VBAのマクロは言語設計の古さからデバッグしにくいコードが生産されやすい。
特に例外処理には最低限に抑えよう。

※なお、本内容は自分の業務の特定を防ぐために発生時の状況やコード内容は架空のものを使用しています。

#発生したトラブル
テレワークをしているAさんから、業務で使っているマクロが使えなくなったとの報告があった。
詳しく聞き取りを行っても、例外が発生している様子はなく、ただ期待されている成果物が出力されていない状態だった。

#調査
バグ調査を行ったのは自分だが、マクロ自体を書いたのは先人である。
しかも自分は派遣されてから日が浅く、業務内容を理解しきれていなかった。
(その上自分も含めてチーム全員がVBAはあまり詳しくないようだった。)

成果物の生成方法を先人に確認し、社内ネットワーク上にあるファイルを読み取っていることを確認し、
仕方ないからバグの原因がわかるようにMsgBoxを大量に配置して実行してもらい、
何が起きているかを確認した。

その結果、今回のトラブルは3つの要因のあわせ技になっていたことがわかった。

#原因
VBAの例外を回避できない関数と、社内ネットワークに接続していなかったこと、
それと製作者とVBAの例外に対する意識の甘さが原因の特定が困難な挙動を起こしていた。
(VBAは一回滅んだほうが良いんじゃないかな)

大雑把に書けば、次のようなコードが今回のトラブルの要因になっていた。

```vb

Sub Macro1()
    On Error Resume Next

    Dim a As String
    Dim b As String
    ' 以下初期化が少し続く

    Activesheet.Range("全部").ShowAllData ' フィルタ設定がなければ例外が発生する

    If Function1 Then
        ' 成果物を作る処理
    End If

End Sub

Function Function1() As Boolean
    Dim wb As WorkBook
    Function1 = False
    wb := Workbooks.Open("社内ネットワーク上のファイル")
    Function1 = True
End Function

```

まず、ShowAllData関数はその範囲にかかっているすべてのフィルタ効果を解除する効果を持つ。
これはそもそもフィルタがかかっていなければ確定で例外を吐くようになっている。
仕方ないからOn Error Resume Nextで失敗時のフォローを行っているようだ。

Q. さて、では普段は正常に動いているこのMacro1を、社内のネットワークへアクセスできない人が使用したらどうなるだろう。
A. Function1でエラーが発生するため、Macro1のエラー処理によりFunction1の戻り値がFalseの状態で処理が帰ってしまい、成果物を作る処理に入らなくなってしまう。しかも正常に動作しているように見える。

#対応
vbaで例外を握りつぶす場合は必要最低限の部分に留め、必要なくなったら```On Error Goto 0```を使用して
把握できていないエラーが発生するようにして、エラー発生後のダウンタイムを最低限に抑えよう。

##真の要因への対応
**そもそもVBAなんていう全てが時代遅れのクソツールを使うのをやめたほうが良いんじゃないかな**
ターミナルの出力内容をカスタマイズ

# 出力内容を設定する


|左寄せ|真ん中|
|:-----|:-----|
|\h|ホスト名（最初の.まで）|
|\H|ホスト名|
|\t|時間（24時間形式）|
|\u|ユーザー名|
|\w|現在のディレクトリ(フルパス)|
|\W|現在のディレクトリ名|


```
$ PS1="\u:\t \W $"           # ユーザー名:時間 ディレクトリ名 $
```


|番号|色|
|:-----|:-----|
|30|	Black|
|31|	Red|
|32|	Green|
|33|	Yellow|
|34|	Blue|
|35|	Magenta|
|36|	Cyan|
|37|	White|

```
$ PS1="\[\033[31m\]\u:\t \W $\[\033[0m\]"

# 31が赤で、32が緑です
$ PS1="\[\033[31m\]\u:\t\[\033[0m\]\[\033[32m\] \W\[\033[0m\] $"	


```

ターミナルを再起動すると設定が戻ってしまいますので、 今後、設定したプロンプト表現を使いたい場合には、
~/.bashrc
~/.bash_profile

両方に記載します。
※なかったら作る。

touch ~/.bashrc
そのままファイルを開いて書き込むか、vimで編集。
lazygitを使って開発をする


##はじめに
スクール時代からGitHubを使ってバージョン管理をしていたので
Github Desktopとコマンドラインを使っていた
会社ではGitLabを使っているので、もちろんGithub Desktopが使えない
しばらくはコマンドラインのみで作業していたがlazygitの存在を教えてもらった

今回は実際にlazygitを使ったワークフローを紹介したいと思います

##新しくブランチを切ってリモートにプッシュする
###新しくブランチを切る
1. コマンドラインから「lazygit」を実行
2. 「Local Branches」のタブの「master」にフォーカスを合わせて「n」キーを押す
3. 「New Branch Name」ウィンドウが出てくるのでブランチ名を入力して「Enter」キーを押す
![newbranch1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566444/68abb9a0-f6e8-0748-646c-d749bb3ca4b2.png)

###変更点をステージングに追加してコミットする
1.「Files」タブでステージングに追加したいファイルにフォーカスを合わせて「space」キーを押す

「space」キーでstagedとunstagedを切り替える事が出来ます
追加したいファイルが複数ある場合は「a」キーを押すと全てのファイルに対してstagedとunstagedを切り替える事が出来ます
変更内容を確認しながら簡単にステージングへの追加と取り消しをする事ができます
 
2.「c」キーを押すと「Commit message」ウィンドウが出てくるのでコミットメッセージを入力して「Enter」キーを押す
![commit3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566444/8e59c8dd-dc4b-30b4-dfc5-36ad0287710a.png)

3.「Commits」タブにフォーカスを合わせて「P」キーを押すとリモートにプッシュできる
![push.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566444/0dc4e635-22c7-eb05-b68f-2ce80e101e5c.png)
##コミットメッセージを修正する
1. 「Commits」タブの変更したいコミットにフォーカスを合わせて「r」キーを押すと「reword commit」ウィンドウが出てくるのでメッセージを変更して「Enter」キーを押す
![reword1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566444/c0ae62e3-49fc-24f7-a62d-c7698b13fb38.png)
![reword2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566444/aa1e545a-d44d-dada-0aaf-7d9413e06c6c.png)

##直前のコミットに修正項目を追加する
1. 「Files」タブで追加したいファイルをステージングに追加する
2. 「A」キーを押すと直前のコミットに追加できる
![amend1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566444/5d3e4c4c-3e01-358e-1c69-6e1ced4b3f88.png)

##stashをする
1.「Files」のタブにフォーカスを合わせて「s」キーを押すと「Stash changes」ウィンドウが出てくるのでメッセージを入力「Enter」キーを押す

メッセージを入力しなくてもstashする事ができます
![stash1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566444/7b44724a-62f0-39ac-1479-3caf908c8274.png)

2.stashを戻す時は「Stash」タブの戻したい変更にフォーカスを合わせて「g」キーを押す
![stash2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566444/586b4aa5-45fe-b52d-10ff-20c9b8739941.png)

##リモートマスターをローカルマスターに反映する
1. 「Local Branches」タブの「master」にフォーカスを合わせて「f」キーを押すと反映できます

##masterをrebaseする
1.「Local Branches」タブでrebaseを実行したいブランチにチェックアウトする
2.「Local Branches」タブのmasterブランチにフォーカスを合わせて「r」キーを押す
![rebase3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566444/2541c0fd-f828-65d2-bc18-ec334d2d9c05.png)

##おわりに
タブの選択カーソルの移動はvimのキーバインドの「h, j, k, l」が使えるのでマウスを使わずキーボードから手を離さずに作業ができます
十字キーやマウス操作にも対応しているのでvimのキーバインドに馴染みがなくても使う事ができて
コマンドラインの作業からの切り替えがスムーズ、そして何より見た目がかっこいいです
なので今はlazygitとコマンドラインで開発をしています
40%の確率で失敗するコード

この記事は、[上智大学エレクトロニクス研究部Advent Calendar](https://qiita.com/advent-calendar/2020/sophia_ele_lab)第6日目の記事です。

## まえがき

今日のお題は確率的に発生するバグです。入力を受け付けたり、ランダムに値を生成するプログラムを作っていると、手元では動いたのに別環境にデプロイした後バグが発覚する事例があります。この記事では実際に僕が実装した例を紹介いたします。

## どんなものを作っていたか

個人サイトのアプリケーションでLambda(とDynamoDB)を使ってセッション管理をしようとしていました。普段であれば、FlaskなどのWebフレームワークを使っているのでセッション管理もライブラリを使っていますが、今回はLambda上の実行ということで、極力外部モジュールを使わず自力で実装しました。
そこで、NodeJSの標準モジュールである `crypto`の `randomBytes` メソッドを使いランダムなバイト列を作り、それをURL安全な形にするために `base64` でエンコードすることにしました。
最初に書いたコードは以下の通りです。

```ts
import {APIGatewayProxyHandler} from "aws-lambda";
import * as crypto from "crypto";

export const hello: APIGatewayProxyHandler = async (_event, _context) => {
  const sessionId = crypto.randomBytes(24).toString("base64");
  const setCookie = `sessionId=${sessionId}; HttpOnly; Secure`

  return {
    statusCode: 200,
    body: "hello, world!",
    headers: httpUtils.toKebabCase({setCookie})
  };
};

```

## 何が問題だったか

`base64` で完璧にエスケープできていると思いこんでいたのが間違いだったのです。 `base64` はバイト列を印字可能な文字列に変換するために、`a-zA-Z0-9/+` の64種類の文字を使います。しかし、この中に1文字だけ `Set-Cookie` ヘッダの値にそのまま使うとまずい文字が紛れています。そう、`+` が問題の文字です。NodeJS(に限らずサーバー)は値を処理するときに、 `+` を発見すると空白文字として処理してしまうのです。それを回避するには、`+` を `%2b` に置き換えてあげる必要があったのです。

## 教訓

- しっかりとエスケープを行う
- 動作確認を何回も行う。テストケースを書く。

## あとがき

最後になぜ40%の確率で失敗するのかを計算で示します。
上記のコードの `sessionId` は24バイトのものをbase64でエンコードしているので、 `24 * 4 / 3 = 32(文字)` となっています。32文字のうち1文字も `+` が含まれない確率は `(63/64) ** 32 ~ 0.604 = 60%`。逆に含まれてしまう確率は `40%` であることがわかります。

この記事以外にも上智大学エレクトロニクス研究部の部員が面白い記事をたくさん書いているので、ぜひ読んでみてください！

[上智大学エレクトロニクス研究部Advent Calendar](https://qiita.com/advent-calendar/2020/sophia_ele_lab)
[上智大学エレクトロニクス研究部の公式サイト](https://selelab.com)
30代からのプログラミング勉強　10日目【HYML/CSS】

昨日は記事執筆中に寝てしまったので今日は二本立て。

##学習内容

[HTML/CSS/JavaScript] フロントエンドエンジニアになりたい人の Webプログラミング入門 セクション3まで完了。

レスポンシブWebデザインについて学んだ。

###CSS

```CSS:メディアクエリ
@media only screen and(max-width:600px){}
```
記述された条件下になると{}内のCSSが適用される様になる。上記の場合だと画面のピクセル幅が600ピクセル以下の場合。only　screenとすると古いブラウザでの誤作動を防ぐことが出来るらしい。

```CSS
width: inherit;
```
幅を親の要素に合わせる事が出来る。今回は下線を端まで伸ばす為に用いた。

```CSS:最大幅
max-width: 800px;
```
画面幅が800ピクセル以上ある時は800ピクセルを維持、それ未満の時はそれに合わせて伸縮するという設定。

```CSS:不透明度
opacity:任意
```
任意の数値を入力する事で透明度を変えられる。

```CSS:アニメーション
transition-property: opacity;
transition-duration: 1s;
transition-timing-function: ease;
transition-delay: 0s;
```
上記の場合はopacityに対してこういうアニメーションをかけるというもの。durationは実行時間、timing-functionは徐々に早く遅くなどの効果、delayは開始タイミングを表す。


####疑似クラス
今回はhoverを使用した。マウスカーソルを合わせると効果が発生する。　
種類は多岐に渡るそう。


##所感
写経ミスもあり途中手本通りの動作がされなかったりエラー部分を探して修正しなければならなかった分時間がかかってしまった。
ミスってしまうのは仕方のない事ではあるのでスムーズな対処法を身につけていきたい。
シェル変数

シェル変数を一部抜粋

シェル変数とは、設定されたシェルだけが使用する変数。
わかりにくい・・・
簡単にいうと、シェルが持っている値を入れておく箱
シェルが動いているときに使える変数のこと。


・PWD
カレントディレクトリの絶対パス

```
〇〇:~ naoya$ PWD
/Users/naoya
〇〇:~ naoya$ 
```

・PATH
コマンド検索パス

・PS1
ユーザーのホームディレクトリ

・PS2
２次コマンドプロンプトを定義

・HISTFILE
コマンド履歴を格納するファイルを定義

・LANG
言語情報
【Java】jarファイルってなに？

#プログラミング勉強日記
2020年12月5日
jarファイルを扱うことが増えたが、実際のところ圧縮ファイルであることしか理解していないのでjarファイルについてまとめる。

#jarファイルとは
　拡張子が`.jar`であるものがjarファイルである。
　jarはJava Archiveの略でJavaのファイルがまとめられてアプリケーションとして使えるファイルのことである。コンパイルされた複数のクラスファイルや画像といったプログラムに必要なものがjarファイルの中に入っている。ファイルを全て入れると容量が大きくなってしまうので、jarファイルはzip形式で圧縮されている。ただ、jarファイルは圧縮された状態のまま使用することができる。

#jarファイルの使い方
　Windowsの場合コマンドプロンプトで操作することができる。jarファイルを操作するためには<b>jarコマンド</b>を入力する必要がある。ここではjarコマンドのオプションを紹介する。

| オプション | 説明 |
|:--:|:--:|
| -f | jarファイル名を指定する |
| -c | jarファイルを新規作成する |
| -t | jarファイルの中身を表示する |
| -x | jarファイルを展開する |
| -u | jarファイルを更新する |
| -v | コマンドラインに処理内容を表示する |
| -o | 圧縮をしない |
| -m | マニフェストファイルを指定する |
| -M | マニフェストファイルを作成しない |
| -i | インデックス情報を作成する |



#参考文献
[【初心者向け】Javaのjarファイルの操作方法を解説！オプションの使い方も紹介！](https://www.tech-teacher.jp/blog/java-jar/)
Vuetifyのv-btnが英字を勝手に大文字にするのを阻止する

# version情報

Vuetify 2.3.19

# v-btn の問題
`v-btn`内の英字テキストは全て大文字にされてしまいます。
例えば「Qiita」と入力したのに表示は「QIITA」になってしまう感じです。

![スクリーンショット 2020-12-05 22.23.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123809/64bb4e79-2e3a-010f-a558-f1b04f327ac1.png)

これは`text-transform: uppercase`が効いているためです。

# 解決法

組み込みの`text-none`クラスを付ければ、`text-transform: none`が付与されるためこれを阻止することが可能です。

```html:大文字にならない
  <v-btn class="text-none">
    Qiita
  </v-btn>
```

##### CodePen

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="POPOPON" data-slug-hash="abmNZgJ" 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="Vuetify text-none sample">
  <span>See the Pen <a href="https://codepen.io/POPOPON/pen/abmNZgJ">
  Vuetify text-none sample</a> by Masa-Shin (<a href="https://codepen.io/POPOPON">@POPOPON</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

色々な記事で様々な解決法が紹介されていますが、恐らくこれが2020年12月現在もっとも適切な方法だと思われます。
SwiftConfettiViewを使って紙吹雪を降らしてみた

#はじめに
現在開発中のプロダクトで紙吹雪のアニメーションを入れたいと考えライブラリを探したところ、とても利用しやすいライブラリだったので、もし「紙吹雪を降らして画面を豪華にしたいなー」と考えている方がいれば少しでも参考になれいいなと言う気持ちを込めて記事を書きました。
#完成形
<img width="300" alt="ezgif-6-9dfc727a8702.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/930365/a2c0ed9a-8194-1a8d-f6f1-70013bb72f45.gif">
#使用したライブラリ
[SwiftConfettiView](https://github.com/ugurethemaydin/SwiftConfettiView)
#準備
プロジェクトを作成し、Storyboardに以下のようにパーツを配置してください。
<img width="300" alt="スクリーンショット 2020-12-05 20.48.06.pn" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/930365/75450cae-1e60-31ef-d6d7-b999e02d0105.png">
#CocoaPodsを利用してインストール
CocoaPodsを使用してSwiftConfettiViewをインストールします。
まず、PodFileを作成します。

```
$pod init
```
次に、PodFileを開き以下のコードを入力してください。

```
pod 'SwiftConfettiView'
```
そして、ターミナルに戻り実行してください。

```
$pod install
```
#インポート
正しくインストールできていればすぐ語換が出てくると思います。

```
import SwiftConfettiView
```
#コーディング
```Swift:ViewController.swift

    @IBAction func startButton(_ sender: Any) {
        //Viewを生成
        let confettiView = SwiftConfettiView(frame: self.view.bounds)
        //Viewを追加
        self.view.addSubview(confettiView)
        //パーティクルの種類を設定
        confettiView.type = .confetti
        //パーティクルのカラーを設定
        confettiView.colors = [UIColor.purple, UIColor.systemPink, UIColor.blue, UIColor.green]
        //パーティクルの強度を設定
        confettiView.intensity = 0.75
        //紙吹雪をスタート
        confettiView.startConfetti()
        //3秒後に紙吹雪を停止する
        DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
            confettiView.stopConfetti()
        }
        //6秒後にSubviewを削除する
        DispatchQueue.main.asyncAfter(deadline: .now() + 6) {
            confettiView.removeFromSuperview()
        }
    }
```
#工夫したところ
実際に開発をしている時に少し手間取ってしまったのは、追加したViewを削除しないとストーリーボードに配置したボタンが押せないことでした。また、ストップと同じタイミング Viewを削除すると紙吹雪がパッと消えて不自然になってしまいます。
そこで、今回は時間差で紙吹雪をストップさせ、紙吹雪がほぼ落ち切ったタイミングでViewを削除すると言う風に実装しました。
#最後に
このライブライはパーティクルの種類が複数用意されていたり、カラーも追加することができたりと、自分のイメージ通りにカスタマイズすることができると思います。
ぜひ、試してみてください！
Rstudio のプロジェクトフォルダにある .git と .Rproj.user を Dropbox 非同期に設定する

Rstudio を使っていると Dropbox が常に同期状態となっていることがあります。 Rstudio 内のプロジェクトファイル監視機能と、 Git の一時ファイルが競合しているようです。そのため、 Dropbox の設定で、それらのフォルダを非同期に設定する必要があります。

# Dropbox で対象ファイルの非同期設定を行う

現在のDropboxのUIの問題なのですが、
1. エクスプローラー（Mac：Finder）からフォルダを右クリックして同期マークを外す設定をする方法
2. Dropbox のWebアプリケーションから該当フォルダを指定して非同期設定にする方法。
3. Dropboxのデスクトップアプリケーションから非同期設定する方法
など、大きく3つ考えられると思うのですが、結論から申し上げると、**可能な方法は3のみ**でした。

## Dropbox フォルダを開く

常駐しているタスクバーのアプリケーションをクリックして、ユーザー名の隣にある、フォルダマークをクリックします。

## .git と .Rproj.user を 非同期に設定

プロジェクトファイルに移動して、対象の「.git」と「.Rproj.user」を右クリック -> **「dropbox.com に同期しない」** を選択します。これで非同期にすることができました。

それほど難しい話ではないのですが、あまりまとまっている記事がなかったため、健忘録としてまとめてみました。参考になれば幸いです。
php.logをgit管理から外す方法(PHP初心者)

#はじめに

素のPHPにてWEBアプリを作成中、ソース管理で、php.logを管理から外す方法についてつまづいたので共有します。

##環境
　【開発環境】
　　MacOS Catalina 10.15.5
　【言語】
　　PHP 7.3.9
　【バージョン管理】
　　Git 2.24.3
##手順
① .gitignoreファイル作成
②管理から外したいファイル（php.log）を.gitignoreファイル内に書き込み
③コミット→プッシュ

これで管理から外すことができるというネット情報を見つけ実行。

参考：https://www-creators.com/archives/1662



##しかしながら全く反映されず。
ずっとこの常態。。↓

```
【ターミナル（git stauts実行時）】
modified:   .gitignore
modified:   php.log
```

##キャッシュが削除されていないと反映されない
キャッシュが削除されていないと反映されないらしく。下記を実行。

```

$ git rm -r --cached php.log  //php.logファイルのキャッシュを削除

```

その後、コミット→プッシュで

```
【ターミナル（git stauts実行時）】
modified:   .gitignore
```

無事、php.logを管理から外すことに成功しました。
embeddable pythonを使うとき、ドラッグアンドドロップされたファイルパスを渡す

#ものすごい単純だった
蛇口です。
あまりパソコンが得意ではないので、徐々に自分なりに課題を見つけていきたいと考えています。
普段は、エンジニアとは全く関係のない仕事をしています。

今回は、ショートカット伝いにファイルパスを渡していくだけの記事でした。
そんなん当たり前じゃん、と言われるような内容でした。

##渡していく前に
[embeddable](https://qiita.com/mm_sys/items/1fd3a50a930dac3db299)はWindows限定ではありますが、実行ファイルのような使い方ができて、かつ、pyinstallerで作ったexeファイルよりも、かなり速い立ち上がりを見せてくれます。

実行環境を渡すという特性上からか、大量のファイルを渡してしまうことになるので、そのまま使わせるのはなんだか悪いような気がしてきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311431/d155ad48-a3c8-70c8-c041-b5f952250f35.png)
（pyinstaller --onefile　なら1つで済むが、こちらだと大量のファイルが必要）

ただ、こちらを利用するときに実際に操作が必要なのは、main.cmdだけなので、ショートカットを作成し、外部においてやれば実質1つのファイルしか触らせずに済みます。

まあ、そうすると、そのショートカットファイルにファイルをドロップしても、実行するpyファイルにはパスがたどり着きませんでした。当たり前ですが。

##.cmdにこんなふうに書いた
.cmdにはbatファイルを書く要領で.pyファイルのコマンドライン引数を渡してあげます。
batではドロップされたファイルのパスは「%0」「%1」という形で扱われるようなので、これらをすべてpyの後に渡してあげる形にします。

```python.exe main.py %*```
初学者がLpic1を学習してみた。

<h3>知識レベル</h3>
運用保守でLinuxを使用しているが、、。（実務経験1ヶ月レベル）
一応自宅でｐｃを利用する際は、コマンドプロンプトでファイルを生成したり消したりする程度

<h3>学習に利用した本</h3>
![51mzBac6Q0L._SX350_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703749/231f3db8-4157-1b0e-b238-17422fb0eb40.jpeg)


<h3>結論</h3>　
初学者レベルだとキツイ笑
いきなり問題よりかは、参考書を進めながら本書で問題を説いて行くべきと感じた。


具体的にいうとオプションの存在を知らなかった・・・。
責任のプロセスをしり、価値を最大化する

# 責任のプロセス

スクラムマスターは組織を支援していく必要がある。
その時に、
組織のメンバーのモチベーションが高い状態や
良い組織に変えていくために
それぞれのマインドセットを良くする必要がある。

課題に対する取り組む姿勢 ＝ 責任

と言う観点で、どのような状態のマインドセットが存在するかをまとめる


## 大きく言うと

責任には全部で6つの状態がある。
それは下記


1. responsibility(責任)
1. Obligation(義務)
1. Shame(恥)
1. Justify(正当化)
1. Lay Blame(他責)
1. Denial(否定)


「Lay Blame(他責)」の状態から一つずつ壁を乗り越えていくことにより
最上位の「responsibility(責任)」の状態となる。
そしてそれは仕事にせよ私生活にせよ、最も効果的な状態になる。
「Lay Blame(他責)」の状態すら放棄した状態は「Denial(否定)」となる。

![20200528-Rco-PosterDev10refine-1448x2048.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329357/3538557f-6701-3ee3-fc6c-bdbb41e38e90.jpeg)


# 各状態の説明

責任のある状態と

* responsibility(責任)

責任のない状態(以下5つ)の2種類に分類される

* Obligation(義務)
* Shame(恥)
* Justify(正当化)
* Lay Blame(他責)
* Denial(否定)


## Lay Blame(他責)

責任感の最下層の状態は「Lay Blame(他責)」である。
これは怒る、苛立つ状態。
他責では問題は解決しない。「誰かの責任だ」。
自分ではない誰かが行動を変えることで解決しようとする行動である。
他者に違う結果を求めている。
その他社が変わらなかったらどうするのだろう？

真の課題とは自分の中にあり、解決策も自分の中にある。
もし、「Lay Blame(他責)」な状態にいる限り、自分では見えることはないだろう

## Justify(正当化)

「Lay Blame(他責)」を乗り越えた時に待っているのは「Justify(正当化)」である。

他者のせいにする事からは脱したが、次は環境や条件のせいにしている状態である。
そうなるべくしてなった。外部の状況の生で自分の制御化ではないと思う。  
例えば以下

* これが経済だ  
* これがマネジメントのやり方  
* 文化だから仕方ない  

## Shame(恥)

「Justify(正当化)」を乗り越えると次は「Shame(恥)」の段階になる。
外部要因を理由にする事を乗り越えると、次は内部要因にフォーカスしすぎるのである。

十分に実力がなかったと言った、自分に責任を感じ、常に罪悪感を感じる状態である。

これは自己に責任が向いている状態であるが、限定的で、本質的に選択肢も自由もない。

## Obligation(義務)

そして次の段階は「Obligation(義務)」。
したくないけどやらなければいけない。他に方法がなかったと言い訳をする。

成功者と言われる人でも「あれをしなければならない」「これをしなければならない」
と考えている。

選択肢が無いように感じていて。
これはただの重荷である。

## Quit(放棄)

「Shame(恥)」と「Obligation(義務)」の横に存在するのが「Quit(放棄)」である。

外部要因からの恥の意識や、重すぎる義務を感じた時に、逃げる先として存在する。
どのようにオーナーシップを持って学び作っていくのかの検討がつかない場合、一時保管先としてここに問題を放置する。

しかし

いつでも結局は問題として戻ってくる。

例えば、いつもの会議に出たく無い。意味がないと思っている場合。
いつでもそれはやってくるし、やるたびに憂鬱になるだろう。
だから、「止めません？」と勇気を出す必要がある。

## Denial(否定)

問題がある事を否定し、受け付けない。それにより問題に取りかからない.
これは防衛本能の一つで、存在している問題から目を背け、現実から逃げるためにある。

これは実に強烈な状態である。
問題や心配事から目を背けて、立ち向かう事を止めているのである。

## Responsibility(責任)

義務感からではなく、実行責任(responsibility)や結果責任(accountability)を持つ。  
non-responsibilityを乗り越えcommitmentを果たそうとするときにこの領域に到達する

3つのキー

* Intention：状態が良くなっていない時に責任を持って反応していく
* Awareness：いち早く、協力状態になれるように
* Comfront：何を学べるか、何が正しいか、何がより良い進歩なのか自分に問いただす


# まとめ

スクラムマスターとして組織を支援するためには、
組織が
メンバーが
どの状態にあり
次にどうなっていく必要があるのかを
再認識する必要がある

# 参考

責任のプロセスについて書かれているHP
https://responsibility.com/responsibility-process/
https://responsibility.com/exploring-the-stages/

youtubeでの簡易的説明
https://www.youtube.com/watch?v=-T3IZ2ISxag
firebase extensions の resize images を使っているのですが：その２

こんにちは、趣味で firebase を使っている者です。
Trigger Email という extension について書こうかなと思ってたんですけど、他の方が書かれるようなので・・・・・・うーんうーん、ネタが思いつかなかったので、去年の記事、「[firebase extensions の resize images を使っているのですが](https://qiita.com/ukisoft/items/b1cc941a4b302affe3e4)」の続きを書きますｗ

# 要約

- 書いたら、CHANGELOG を翻訳しただけの記事になりました。
- bug fix と、拡張機能の画面の option の追加だけなので、option 画面見れば大体わかります。

# resize images とは

firabase storage に画像を upload すると、自動でサムネイルを作ってくれる拡張機能です。
去年は 0.1.3 までのバグについて書いているので、0.1.4 以降の[修正点](https://github.com/firebase/extensions/blob/master/storage-resize-images/CHANGELOG.md)と、機能追加については動作検証を書いていきたいと思います。
翻訳間違ってたらスミマセン。

# 0.1.4

0.1.4 の変更点は以下の通りです。

- 拡張子がない場合、ファイル名が消えてしまうバグを修正
- [メタデータが上手く設定できていないバグを修正](https://github.com/firebase/extensions/pull/142/files)
- 一部のバケット名で上手く動作しないバグを修正

1 つ目は、僕が去年書いてたやつですね。
直ってよかったです（プルリク出せば良かった。

# 0.1.5

- Content-Type に MIME type を設定できなかったバグを修正

# 0.1.6

- MIME type の image/webp で動作しなかったバグを修正

# 0.1.7

- resize した画像がコンソールで見れないバグを修正
- 同名の画像を upload したときに、古い画像を resize してしまうバグを修正

# 0.1.8

- resize したときに画像の向きが変わるバグを修正

# 0.1.9

- vector 画像の場合、resize しないよう変更
- mkdirp-promise が deprecated になったので、mkdirp に置き換えるよう変更
- resize 後よりも小さい画像の場合、resize しないよう変更

# 0.1.10

- token の使いまわしをやめ、resize 毎に生成するよう変更

# 0.1.11

- node.js 10 に対応 🎉

# 0.1.12

- gzip ファイルを無視するよう修正
- 新しい location（リージョン）に対応

# 0.1.13

うおおお。
ようやく新機能だ。

- content-type を変える option を追加

拡張機能の画面の一番下の項目です。

![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39090/31ed9306-90f9-55a9-12c3-ae915e8c46ab.png)

選択肢は下記です（リポジトリでは[ここ](https://github.com/firebase/extensions/blob/master/storage-resize-images/extension.yaml)）。

![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39090/fd79d3fb-6608-7eff-2979-6a1189f85caf.png)

例えば png に設定し、jpg を upload すると、png になります。

![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39090/3e18da1a-b400-d74b-b2e3-cb9c3d1480c7.png)

![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39090/7be09cef-2d9e-6a5a-fa34-368e3081a3bd.png)

# 0.1.14

- resize が成功した際に、元画像を消す option を追加

拡張機能の画面の真ん中くらいにあります。

![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39090/fceb5b53-6053-2385-5c32-01cd4de45a02.png)

選択肢は下記です。
Yes があるということは、今までは resize の成否に関わらず消すということしかできなかったみたいです。

![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39090/ff5b973a-66c3-8b95-2e20-50f0b558e6c0.png)

一応、resize 後に消えたことを確認したんですけど、そのままなので画像などは割愛。

# 0.1.15

- 拡張子が想定された画像の拡張子でない場合、名前が変になるバグを修正

ファイル名にドットが含まれてたりすると、それが拡張子と判断されて、resize のサイズがファイル名の変な場所にくっついてたみたいですね（[issue](https://github.com/firebase/extensions/issues/476)）。

# 0.1.16

- resize する画像が置かれてあるディレクトリを、絶対パスで指定する機能を追加

これも拡張機能の画面の真ん中くらいにあります。

![010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39090/99b173ec-ff01-31d8-36d8-141e0ba9e18d.png)

こちらも検証画像は割愛・・。

# 終わりに

全然検証するところありませんでしたｗ
来年は、もうちょっと役立つ記事を書きたいです（フラグ。
Pythonで東京の１日の新規感染者数を予想してみた！

今回は、Pythonを使って東京の１日の新規感染者数を予想してみました。

初めての機械学習ということで、シンプルなことしかできませんが、温かい目で見ていただけたら幸いです。

1. NumPyやPandasなどの外部ライブラリをインポート！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933659/29ac568c-2219-a3fb-5242-0a28dc1c1b14.png)

NumPy, Pandas, Matplotlibをそれぞれインポートします。
import matplotlib.dates as mdatesは、後にグラフを作る際に日にちを加えるためのコードです。

２. データを集める
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933659/9d2204d8-488e-5b86-06d5-cda25324f4a4.png)

都内の最新感染動向というホームページに、これまでの感染者数の推移が乗っているので、そこからデータを集めます。こちらがそのホームページです。
https://stopcovid19.metro.tokyo.lg.jp/

上記の画像は２月１４日から１２月２日までの１日の新規感染者数をまとめたデータです。NumPyを使って、ndarray化させています。

次にPandasのDataFrameを使って、綺麗な表を作ります。​
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933659/9aa78dbe-180d-5142-5720-93fff99468f9.png)

３. 説明変数と目的変数を決め、訓練データとテストデータに分ける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933659/acea14b3-e4c2-f718-3c78-e81413e9ae8c.png)
ここではTechAcademyで習った技術を生かします。Xは、その日の感染者数、y は次の日の感染者数とします。ある日の感染者数がXなら、その次の日の感染者数はy になる」という形で X（説明変数）と y（目的変数）を設定します。

今回は、直近（後半の）３０日をテストデータにします。つまり、２月１４日から１１月３日までのデータを訓練データとし、１１月４日から１２月２日までをテストデータにします。

４. scikit-learnのLinearRegression（回帰）を使って、学習させる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933659/04565d71-9e35-81a9-28a2-0b46bf5c135d.png)
今回は感染者数の予測を行いたいため、 linear_modelをインポートし、linear_model.LinearRegression()で学習をさせます。

predict()を使って、期待する性能が出たかを評価します。

５. matplotlibを使って、グラフ化する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933659/94595799-dea2-01fd-f92d-66acbc3e1fe6.png)

Pandasのpd.date_range()を使って、１１月４日から１２月２日までのデータを作ります。
あとはラベルやタイトルを入れて完成です。

結果はこうなりました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933659/874f0a1d-352f-b46c-190f-992b505e3044.png)

赤い線はコンピューターが予想した数で、青い線は実際の数を表しています。
こうして見ると、ちゃんと予想はできてるように感じますが、専門家ではないので詳しい事はわからないです。
でも、初めての機械学習にしては上出来だったかなと思います。
もっと機械学習についての知識を深めて、難しいことにチャレンジしていけたらなと思います！


最後まで読んでいただきありがとうございました！
【個人アプリ作成】情報管理アプリ制作7日目

昨日は着手できずでした、、、、

今日はもうひたすらHTML/CSS。。ただ、自分で創作してみるとHTMLとCSSの扱い方が、かなり分かりました。

#今日の作成画面

![スクリーンショット 2020-12-05 21.54.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759485/266e4c83-671d-0a0b-2866-6071151406d7.png)

自分で試行錯誤しながらではかなりできたと思います。
fixのメソッドを使うと画面固定できたりとCSSはやってみると面白く、沼にはまらない程度に実用的なメソッドをどんどん付けていきたいと思います！


#今日の良かったこと

>・部分テンプレートに拘ったので、応用できること。<br>・自分の想像の８０％くらいのものができて自信がついた。
[Flutter] 即完了。Bundle IDとアプリアイコンとスプラッシュの設定。



Flutterでモバイルアプリを作成する際に、
どんなアプリでも必ず設定が必要な内容があると思います。

今回は開発の最初に設定しておいた方が良さそうな以下の内容を、
すぐに終わらせるように記事を書いてみました。

- プロジェクトの作成 + Bundle IDの調整
- アプリアイコンの変更
- スプラッシュスクリーン設定

プロジェクトの作成は当然必要ですし、Bundle IDの設定も必要です。
アプリアイコンもデフォルトのままでは審査に通らないはずなので、後々調整する必要が出てきます。
スプラッシュスクリーンもiOSの審査に必要なので、最初にやってしまいましょう。

出来るだけコピペで動くように書いてみました。

## プロジェクトの作成 + Bundle IDの調整

Bundle IDはflutter createコマンドの実行時に設定することができます。
ファイルを直接調整したり、Xcodeで修正したりすることもできますが、面倒なのでこの方法でやってしまいましょう。

```
$ flutter create --org com.your_bundle your_app
```


## アプリアイコンとスプラッシュスクリーンの変更

アプリアイコンの変更はflutter_launcher_iconsを使うと簡単です。
iOSとAndroidそれぞれに必要な複数の画像を一括で作成することができます。

[flutter_launcher_icons]
(https://pub.dev/packages/flutter_launcher_icons/install)

スプラッシュはflutter_native_splashを使って設定していきます。

[flutter_native_splash]
(https://pub.dev/packages/flutter_native_splash)


productionでは必要ないので、dev_dependenciesに記載しましょう。
また、画像のパスやその他のオプションも設定しましょう。


```yaml:pubspec.yaml
dev_dependencies:　
　~~
  # アプリアイコン
  flutter_launcher_icons: ^0.8.1
  # スプラッシュ。
  flutter_native_splash: ^0.1.9

# コマンドはflutter pub run flutter_launcher_icons:mainでicon設定。
flutter_icons:
  android: "launcher_icon"
  ios: true
  image_path: "assets/images/icon.png"

# コマンドはflutter pub pub run flutter_native_splash:create
flutter_native_splash:
  image: assets/images/splash.png
  color: "ffffff"
```

icon.pngとsplash.pngを指定したディレクトリに設定してコマンドを実行していきましょう。

```
$ flutter pub get
// アプリアイコンの設定
$ flutter pub run flutter_launcher_icons:main
// スプラッシュの設定
$ flutter pub pub run flutter_native_splash:create
```

これで、Bundle IDとアプリアイコンとスプラッシュの設定が完了しました。
必要に応じて、オプションを確認して調整していきましょう。
python typing example

after set `python.linting.mypyEnabled` to true(not to sell you have Pylance in place) you are equipped with typing

```python 

import sys
from typing import Tuple, Union

global nums


def sum2(start: int, end: int, target: int) -> Union[Tuple[int, int], None]:
    seen = set()
    for i in range(start, end):
        n = nums[i]
        if target - n in seen:
            return (n, (2020 - n))
        else:
            seen.add(n)
    return None


if __name__ == "__main__":
    nums = sorted(map(int, sys.stdin))
    end = len(nums)
    for i, num in enumerate(nums):
        ret = sum2(i, end, 2020 - num)
        if ret is not None:
            print(num * ret[0] * ret[1])

```
#IotHub と #StreamAnalytics と #PowerAutomate を使って 室温異常時に #Teams に通知する仕組みを作ってみた

# 初めに

Azure IoT Hub ちゃんとやりはじめないといけないよなーと思いまして
色々ネットサーフィン（死語）してたら、この記事見つけたんですよ。

[Microsoft Docs Raspberry Pi の Azure IoT Hub への接続 (Node.js)](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-raspberry-pi-kit-node-get-started)

んで、実際に作ってみたんですよ。
そして、この記事の続きで、 Logic Apps 経由でメールを飛ばすっていう記事があったので
[Azure Logic Apps で IoT Hub とメールボックスに接続した状態での IoT リモート監視と通知](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-monitoring-notifications-with-azure-logic-apps)

あ、じゃあ Power Automate でもいけるな！と思ったわけです。

ただ、Power Automate って Logic Apps と違って 実行回数の制約があるんですよね。
なので、その辺も考慮しないといけません。

# とりあえず 作ってみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/de82ff29-af8c-464c-fc46-17ab0410eccd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/4889f581-7c44-db3d-0862-900393267ec6.png)

ただ、このままだと、室温が30度を下回らないと、Raspberry Pi 側から通知されるたびにTeams の投稿が行われてしまうので、この部分を制御しないといけないですね。

# Power Automate フローの無効化

一番手っ取り早いのは、一度実行されたら、フローを無効化するように設定しておけば、次回から実行されることはないので、連続投稿されることもなくなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/88b2dabc-b5cf-86e8-1577-0255eab70c2e.png)

対処が終わったら有効化するようなフローを作成すればよいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/784861ff-814c-71ba-da7c-6db274e0972f.png)

フロー状態を取得して、Stoppedだったら、有効化するアクションを実行すればOkですね！
【初心者向け】コーディングでは積極的にメモにまとめよう（効率化）

#メモにするメリット
急がば回れ、
コードを書く前にしないといけないことを明確にすることで、無駄なコードを書いて混乱せずに済みます。結局そのほうが開発が早く進みます。
また、後にコーディング内容に問題があったときに『自分が何を考えて何をコーディングしたのか』を振り替えることができます。

特にPHPやHTML、JavaScriptなど複数言語を同じ開発で扱うときには、どの部分で何をするかもわかりやすくなるでしょう。

#ToDoリストを書く
コードを書く前にやることをToDoリストにまとめましょう。

<b>コードを書く前に</b>
手順（しないといけないこと）をまとめる。
手順の中での課題になりそうなことをまとめる。
チーム開発では、何を相談すべきか明確する。

<b>コードを書きながら</b>
やったことを都度まとめる。
新たに生まれた『これからやること』をまとめる。

これらをメモすることで、分からなくなったときに今までしていたことを振り返ることができ、
チームメンバーに説明するときにも開発内容を説明しやすくなります。

#初心忘れるべからず
とても基本的なことですが、メモにすることを忘れてしまうことはよくあると思います。
積極的にメモをとって、自分がすることを明確にして理解した上でコードを書きましょう。
Kibanaのダッシュボードをiframeとして埋め込む


# 解決したい課題
元々Kibana6.x環境で、作成したダッシュボードを他のサーバからiframeを使って表示させていました。Kibana環境を7.xを変更したところ、デフォルトの状態だとダッシュボードにアクセスするにも認証が必要になるようで、これを回避するためにnginxを間に挟み、ヘッダーを使って認証情報を渡す形にしました。
※バージョンというより導入方法の違いかもしれませんが。

# 環境
Elastic: 7.10.0
Nginx: 1.19.5
CoreOS: 2247.6.0

# 構成
あまり本筋には関係ないですが、全体の構成としては以下のような形になっています。
![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159980/386ec310-d09a-3587-16e6-4dfaa631a96b.png)

既にKibanaのダッシュボードと、それを表示させるウェブサーバは構築済の前提です。

# Nginxの導入と構成
CoreOS上でdocker-composeを使用して導入しました。
以下のようなディレクトリ構造を作成します。

nginx/
├docker-compose.yml
└nginx.conf

それぞれの中身はこちら。

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

services:
  reverse-proxy:
    image: nginx
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    ports:
      - 80:80
```

docker-compose.ymlについては、同じディレクトリにあるnginx.confを設定ファイルとして使用するという設定が入っています。

```nginx:nginx.conf
events {
        worker_connections  1024;
}
http {
        server {
                listen       80;
                server_name  10.10.10.100;

                location / {
                        proxy_set_header  Authorization "Basic xxxxxxxxxxxxxx"; #ユーザとパスワードをエンコード
                        proxy_pass  https://10.10.10.200:5601; # KibanaサーバのURL
                }
        }
}
```

proxy_set_headerというパラメータで認証情報を渡します。Base64でエンコードしたものを使用します。あまりセンシティブでなければ、オンラインでエンコードすることも可能。
https://www.base64encode.org/

proxy_passにKibanaのURLを渡します。ここではポートまでしか記載しないことがポイントです。最後にスラッシュを含めると解釈がややこしくなるので、含めないほうがよいです。
× proxy_pass  https://10.10.10.200:5601/
× proxy_pass  https://10.10.10.200:5601/app/dashboards

これらを用意したら、起動します。

```shell-session
core@localhost ~/nginx $ docker-compose up -d
Creating network "nginx_default" with the default driver
Creating nginx_reverse-proxy_1 ... done
```

# ウェブサーバ側(iframe)
以下のようなiframeタグを用意すれば、認証無しでダッシュボードが表示されます。Kibanaのダッシュボード画面のShareというボタンからURLは取得できますが、ホスト名とポートの部分を自分の環境に合わせて変更しています。

```html
<iframe src="http://10.10.10.100:8080/app/dashboards#/view/c7a7ef90-361f-11eb-9711-6531136bb57b?embed=true&_g=(filters%3A!()%2CrefreshInterval%3A(pause%3A!t%2Cvalue%3A0)%2Ctime%3A(from%3Anow-2y%2Cto%3Anow))&hide-filter-bar=true" height="1600" width="100%" scrolling="no" frameborder="0"></iframe>
```

# 参考
iframeとしてKibanaのダッシュボードを認証無しで表示する方法
https://discuss.elastic.co/t/auto-authenticating-to-iframe-embedded-kibana-dashboard/46091/4

nginxのconfの書き方
https://heartbeats.jp/hbblog/2012/04/nginx04.html
javascript 問題集 No.3 関数名(array,callback)

function 関数名(array,callback)
を作る問題でした。

最初はcallbackの部分を埋めるために関数をもう一つ作っていました。

けど、こんなやり方もありました。

console.log(arrayの部分,(item)=>{
 return item<=20
}

>consoleに直接埋め込む方法です。
>最初のfunctionにif文を埋め込むだけでできますね。
更新頻度の低い連携はデータフローを活用しましょう。

Power Appsアドベントカレンダー6日目は、データフローをご紹介します。

今回、ホントはPower Automate Desktopで自動的にEightの名刺データをOneDriveにダウンロードして、定期に最新の顧客情報を取り込む仕組みを披露したかったんですが、アドベントカレンダーまでに課題が解決できず💦次回のブログにまとめて書きます。
#データフローとは
Power Appsでアプリを作る際に、他のサービスからリアルタイムにデータを取得するには、用意されたコネクタを利用しますが、別のシナリオとして更新頻度の低いデータ連携には、データフローを活用しましょう。
注意：Microsoft Dataverse(CDS)の利用が前提なので有料ライセンスが必要です。


##設定してみましょう
今回は、OneDriveに保存された顧客情報のCSVファイルを取り込みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/878347ff-612a-1e98-cca3-66c6be32d894.png)
「空白から開始」を選んでください。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/2ef1ac48-2393-439f-9353-525fccabf506.png)
「名前」に、このデータフローの名称をつけて「作成」してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/419bf1aa-abf5-61e3-e92f-0f2a91d00fdf.png)
接続先一覧が表示されます。とりあえず、今回は「テキスト/CSV」を選びます。
※ExcelでもJSONでもCSVでもAzure SQL Database、MySQLも、様々なサービスに対応しています。
個人的に面白いと思うのは**Webページ**です。
指定したURLのHTMLページ内のTableタグの内容を取込出来ますので、ウェブサイトで発表されるような内容を定期的に取込することも可能です。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/c724e060-0e85-41f4-15c1-9fd007ab5861.png)
取り込みたいデータをファイルまたはURLの横にある「OneDriveの参照」から選択して「次へ」を押してください。「接続」はログインしているアカウントが自動的に選択されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/591e6413-126c-1e00-198b-62516e334fe2.png)
「元のファイル」で文字コードを選んで、「区切り文字」を選び、CSVデータがカラムに分割されているか確認します。問題なければ「OK」を押してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/0d2e8a57-aea6-69da-ad40-b91b2784584c.png)
各カラムのデータ型を選びます。テキスト型は文字列として取り込まれすが、更新日などは日付型等、金額なら整数か通貨等、データの内容によって適切に選択しないと、思うような検索ができませんので、注意してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/42fb82c3-2f0d-ab81-c976-17419bc9a8d8.png)
顧客情報ですが、
読み込みの設定は「既存のテーブル」に読み込みます。
宛先テーブルは「Account」を選んでください。
フィールド マッピングで、Eightのデータレイアウトから、既存のAccountのカラムに合うものを指定してください。
全て指定したら、「次へ」を教えてください。

**予備知識**：今回、顧客情報を取込ますが、新たにデータベースを作成する場合、自身で考えたデータレイアウトや、Eightからダウンロードしたままでも良いのですが、Microsoft Dataverse(CDS)には、顧客情報を保存する既存テーブル「取引先企業」があります。
特にこだわりがなければ、その後のデータ共有を考慮して、既存テーブルに入れておきましょう。
Common Data Modelと呼ばれていますが、他にどんなテーブルがあるか、調べてみると面白いと思います。
※詳しく知りたい方は、中村さん（@kenakamu）のブログを参照してください。
https://qiita.com/kenakamu/items/21f91df6c42e9a0e8e19

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/a76972b2-78f6-623a-0f02-b635add15191.png)
最後に、更新設定を行い終了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/a1527b1c-f0f2-5950-4d53-2bf1aeb9e33b.png)


実際に取り込まれたデータを確認してみましょう。
左メニューの「データ」から「テーブル」を選び、一覧から「取引先企業」を開いて、「データ」タブを選んで内容を確認しましょう。
※すべてのカラムを表示したい場合には、右上の「ビューの選択」から「すべての列」を選択すると表示されます。

以上で、データ フローの設定は終了です。
頻度の高くないデータ連携は、こちらをお勧めします。
Animation Eventの使い方

# この記事でできること
- animationを使用して、関数を呼び出すことができます。
- animation eventのレシピの末尾にあるよ!

# animationで似たような派生テクニック
- [【Unity】任意のタイミングでanimationを発動させるやり方【animation／animator】](https://qiita.com/sanpeita/items/3864578e852801c15f80)

# つくりかた

- まずは通常通りに、animationを設定します。
- animationの作り方は、
- [【Unity】ノンコーディングでオブジェクトを動かしたい【Animation】](https://qiita.com/sanpeita/items/b947227cdbad0c26e1e2)　または、
- cluster公式記事の「[動きのあるワールドを制作する（アニメーション・アニメーター編）](https://creator.cluster.mu/2020/08/26/animation-animator/)」も参考になるのでぜひどうぞ!!

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/ed36df66-2210-7408-1253-1e55710358e0.png)


![ダウンロード.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/43014b53-7562-b2f9-4b25-db59d9eb94d1.gif)

- 関数を作ります。今回はテスト用なので、シンプルにコンソールに"HelloWolrd!!"を表示させます。

```

using UnityEngine;

public class testDebug : MonoBehaviour
{
    void Hello()
    {
        Debug.Log(" ----- HelloWorld!! ----- ");
    }
}

```

- animationのタイムラインで、「Add event」をクリックします。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/ae96e9c4-33a1-559a-2dce-1d001a7ecffc.png)

- インスペクターウィンドウで、関数を選択します。(事前に、スクリプトはオブジェクトにアタッチしております)

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/203cfa13-df11-568b-589c-8f511b6e227c.png)

- 実行すると、animationの指定のタイムラインで、関数が実行されます。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/e8a603b3-fe1d-26d8-6102-cab3b3eb0fad.png)

# AnimationEventのレシピ集
- [AnimationEventレシピ ~アニメーションで当たり判定を切り替える~](https://qiita.com/mino4273/items/ef58de54b585b804f08c#_reference-2175f659a2f8f8442ba0)(@mino4273さん作成)
「【GAS】緯度経度から２点間の距離を求める」を参考に、国土地理院とWolfram|Alphaでやってみた。

###(参考)【GAS】緯度経度から２点間の距離を求める
https://qiita.com/YasumiYasumi/items/7f6c19f5611707f7a6b3

東京タワーからスカイツリーまでの距離8.23428881
・東京タワー
緯度35.658607経度139.745444
35.658607
139.745444
・スカイツリー
緯度35.710089経度139.810711
35.710089
139.810711

###(参考)測量計算(距離と方位角の計算) - 国土地理院
https://vldb.gsi.go.jp/sokuchi/surveycalc/surveycalc/bl2stf.html

GRS80の場合 8,217.866(m)45.9472194444444(度)225.985291666667(度)
bessel  の場合 8,216.937(m)45.9468388888889(度)225.984911111111(度)

###(参考)Wolfram|Alpha
https://www.wolframalpha.com/input/?i=Latitude+35.658607+longitude+139.745444%E3%80%80Latitude+35.710089+longitude+139.810711&lang=ja
Latitude 35.658607 longitude 139.745444　Latitude 35.710089 longitude 139.810711
8.218 km (キロメートル)



###(参考)自宅からスカイツリーの距離と方位角 
https://keisan.casio.jp/exec/system/1335163996
東京スカイツリー
35.71014
139.81083
結果
距離8.237828km
方位角45°50′38.23″

#(参考)東京タワーと東京スカイツリーは直線距離だと何キロくらい＜Yahoo!知恵袋 
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1238837467
8.2キロくらい
Linux で転送ビットレートを表示

# Linux で転送ビットレートを表示

ubuntu 20.04.1 で確認しました。

## インストール方法

```
sudo apt-get install iftop -y
```

## 使い方

```
sudo iftop -i <インターフェース名>
```

## 例

```
sudo iftop -i wlp0s20f3
```
アドベントカレンダー3日目：SREを読んでみた「イントロダクション」編②

前回はSREの「[イントロダクション](https://qiita.com/user_h/items/27c35a0a7ff850ee7941)」の途中までを読みました。今回はその続きからです。
前回の内容を振り返ると、従来のシスアド方式でのサービス管理は、手作業による運用の為、システムの巨大化に伴い、運用コストが増大していくこと、そして、シスアドと開発の分断が生まれてしまうことがわかりました。
特にチームの分断は対立を生み、病的な状態に陥ることさえあることがわかりました。
では、それらの問題を解決するためのSREのアプローチはどういったものなのでしょうか？

## 選ばれたのはソフトウェアエンジニアでした
> **Google内で規定されることになったサイトリライアビリティエンジニアリングとは、いったい何なのでしょうか。私の説明は単純明快です。SREとは、ソフトウェアエンジニアに運用チームの設計を依頼した時に出来上がるものです。**<sup>1</sup>

運用の手作業のコストが増大していくなら、その作業を自動化すればいい。運用システムをエンジニアに書かせればいい。というのがGoogleの回答でした。

サービス管理に対するGoogleのアプローチの主要な構成要素は、SREチームのチーム編成にあると書かれています。

>（チームの）**50から60％は、Googleのソフトウェアエンジニアです。** <中略> **残りの40%から50%は、Googleのソフトウェアエンジニアリングの必要条件をほぼ満たしている（すなわち、必要なスキルセットの85%から99%）候補者であり、加えてSREにとって有益でありながら、ほとんどのソフトウェアエンジニアが持っていないような一連の技術的スキルを持っているエンジニアです。私たちがさらに求めている技術的スキルの中で最も代表的な物を2つ挙げるなら、間違いなくUNIXシステムの内部とネットワーキング（レイヤー１から３）に関する専門知識です。**<sup>1</sup>

> **そして、すべてのSREに共通するのは、複雑な問題を解決するソフトウェアシステムの開発に対する信念と適正です。**<sup>1</sup>

SREの手法がGoogleで上手くいったのは、Googleのエンジニアが優秀であることも大きな要因だと思いました。
そんな人たちの知見を得られることは、とてもうれしいですが、今後、読み進めるのが不安になりました。頑張っていこうと思います。

もちろんSREはエンジニアの優秀さだけで成り立っていたわけではなく、SREチーム独自のルール設定もあります。

## Google SREチームルール
> **GoogleではすべてのSREに対して、チケット、オンコール、手作業といった「運用」業務の合計を50%以下にするよう、上限を設けました。**<sup>1</sup>

> **Googleにおける大まかなルールは、SREチームは残りの50%の時間を実際に開発を行う為に使わなければならないというものです。**<sup>1</sup>

この50%という数字が何を根拠としているのかは、ここでは書かれていませんが、運用のコストを増やし続けないためにその上限を設けるというのは、重要なことだなと思いました。

上のルールをどのように実行していくのかが書かれます。

> **まずは、SREがどのように時間を使っているかを計測しなければなりません。計測ができれば、常に50%以下の時間しか開発作業に費やしていないチームの習慣を変えることができます。これは運用の負担の一部を開発チームに差し戻りたり運用上の責任を増やすことなく、追加の人員をチームに加えることを意味します。**<sup>1</sup>

これはチーム単位の割合の話ですが、実際に自分がどの程度運用に時間を掛けているのか、（チケット管理など含めて）を計測したことはなかったので、少し書き留めてみようかなと思いました。
また、ソフトウェアエンジニアに運用をさせる強みは、ここにあると思います。
SERチーム内では、運用も開発も両方できる人たちが集まっているので、開発と運用のタスクを人数で管理できます。

## SREのメリット

SREの直接的なメリットは、運用システムの構築により、手作業のコストが減ることは、明らかですが、シスアド方式にあった間接的なコストの解消も行うことができると書かれています。

> **Googleのシステムを自動的に動作させることを追求するために直接コードを修正するので、SREチームは、素早いイノベーションを変更を広く受け入れる特徴を持つこととなります。**<sup>1</sup>

昨日のまとめで相手のことを考えようとと書きましたが、相手のことを理解するための方法の一つは、相手と同じことをしてみることでした。

そして、運用チームがコード修正できることは、プロダクト開発チームも改善してくれると書かれています。

> **プロダクト開発チームとSREチームとの間の移動が容易ないことで、グループ全体を相互にトレーニングすることになり、開発者のスキルを改善できるのです。**<sup>1</sup>

## GoogleSREの課題

従来のシスアドによるサービス管理モデルの直接的なコストや間接的なコストをSREは改善できるメリットがありますが、SREにも独自の課題があるそうです。Googleが継続的に抱えているのは、GoogleSRE採用基準が高いため、採用の対象者が少ないこと。そしてSREのアプローチは新しい試みの為、管理層からのサポートが必要であることだそうです。

> **例えば、エラーバジェットの消費状況によって四半期の残りの期間はリリースをやめるという判断は、管理層が要求しない限りプロダクト開発チームには受け入れられないでしょう。**<sup>1</sup>

## まとめ
* SREチームは、運用システムの開発を行う。
* SREルール：運用コストの上限は50%、そして、全体の50%は開発に当てる。

## 雑感
今回の内容は管理側の視点で書かれており、エンジニアの経験しかない自分にはまとめるのが難しい感がありました。
今日までのアドベントカレンダーで連載の漫画家は、必ずストックをつくってから、連載すべきと思いました。
イントロダクションは、後一回分ありますが、それで最後です。今度は嘘じゃないっす。

#### 引用
1. Betsy Seyerほか　SRE サイトリライアビリティエンジニアリング　オライリー　5-7
共同開発で学んだGitとGitHub

共同開発に参加する機会があり、一人で開発していた時には知らなかったことがたくさんありました。
そのうちのひとつがGitとGitHubの使い方だったので備忘録。

#リモートリポジトリ から ローカルへのクローン
他の人がリポジトリを作った場合は権限の付与が必要になるので自分のGitのアカウントを教える。
権限が付与され次第、クローンする

クローンするディレクトリ先に移動

```
$ cd ディレクトリ名
```

リポジトリをクローン


```
 $ git clone リポジトリURL
```
クローンしたリポジトリが正しいかを確認する

```
$ git remote -v 
```

#リモートでブランチを作成し、ローカルにブランチを引っ張る方法

GitHubでリモート上でリモートブランチを作成し、ローカル引っ張る。
リモートでのブランチ作成方法は下記参照。

>[GitHub Docs](https://docs.github.com/ja/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-and-deleting-branches-within-your-repository)
リモートリポジトリでのブランチ作成方法


リモートでブランチ作成後、下記コマンドを実行

```
git checkout -b ローカルでのブランチ名 origin/リモートで作成したブランチ名
```

#ローカルでmainからブランチを作成する方法

git branchで現在のブランチの確認をする(※がついているブランチが現在のブランチとなる)

```
$ git branch
 ＊ master
```

新しいブランチを作成

```
$ git checkout -b 新ブランチ名
```
確認すると新しいブランチができ、現在のブランチも変わっている

```
$ git branch 
　 master
　＊　新ブランチ名

```

#作業ブランチ上でステージング、コミットする

```
$ git add .
```

```
$ git commit -m ”コミット時のコメント”
```

#リモートリポジトリへpush, プルリクをする

```
$ git push origin ブランチ名
```
にてpushをすると、GitHub上でCompare & pull requestボタンが表示されるので、クリックし
何を変更したのか等の記述をし、プルリクを送信。

>[GitHub Docs](https://docs.github.com/ja/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request)
プルリクエストの作成方法

#間違えてmainブランチで作業してしまった時にブランチを切り替える方法

まずは今のmainからの変更をコミットではなく保存する

```
 $ git stash save
```

ブランチを切り替える

```
$ git checkout ブランチ名
```

切り替えたブランチで保存した変更を戻す

```
$ git stash pop
```
変更を戻すと下記のように変更のあったファイルの一覧が表示される
→コミットする前にgit addをしてコミットすればOK


```
Changes not staged for commit:
Use git add <file>… to update what will be committed
Use git restore <file>… to discard changes in working directory
  modified: 変更のあったファイル名
　modified: 変更のあったファイル名
No changes added to commit (use “git add” and/or “git commit -a”)
```


他にもあれば追記していく予定です。
配列から要素の削除方法

##配列の削除方法のまとめ

```Array.swift
var club = ["football","basketball","handball","baseball"]
```

##最初の要素を削除

```removeFirst.swift
club.removeFirst() // "football"
print(club) // ["basketball","handball","baseball"]

```

##最後の要素の削除

```removeLast.swift
club.removeLast() // "baseball"
print(club) // ["football","basketball","handball"]

```

##indexからの削除

```remove.swift
club.remove(at:2) // "handball"
print(club) // ["football","basketball","baseball"]

```

##特定の要素の削除

複数削除の場合

```Array.swift

var club = ["football","basketball","handball","baseball","basketball"]

club =club.removeAll(where: {$0 == "basketball"})
print(club) // ["football","handball","baseball"]
```



##全削除

```removeAll.swift

  club.remove(at: index)
print(club) // []
```
【初心者でもわかる】ワンクリックでテキストをコピーできるボタンの作り方

#どうも7noteです。クリップボードにテキストをコピーさせる方法。

ユーザーがわざわざドラッグしてコピーしなくても、任意のテキストをクリップボードにコピーさせることができます。
`input`や`textarea`などの要素のテキストをコピーさせることができます。

**サンプル**

![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/8cdcb2d6-75e6-7410-eab9-174123bc18ac.png)


## ソース

```index.html
<p>確認コード：<input type="text" id="code" value="1234"></p>
<button onclick="copy();">コピーする</button>
```

```script.js
function copy() {
	var targetCode = document.getElementById("code"); // コピー対象のテキストを選択する
	targetCode.select();                              // コピーしたい要素を選択状態にする
	document.execCommand("Copy");                     // 選択しているテキストをクリップボードにコピーする
	alert("コピーしました！");                            // 任意でアラートを出す
}
```

## 解説
`.select()`は`input`などの**ユーザーが選択したり入力したりする要素にしか効かないので注意!**
アラートは出す必要はないですが、あったほうがちゃんとコピーできてるというのがわかって使いやすいと思います。
もっと突き詰めるなら、バルーンなどが一瞬表示されてフェードアウトしていくような処理を入れたらもっと今っぽい感じになると思います。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】HTML・CSSのちょいテク詰め合わせ](https://qiita.com/7note)