OmniAICreator/Qiita-1.07M huggingface dataset:
mapとreduceでforやif文を置き換える

#はじめに
最近、mapとreduceを用いた面白い配列操作を学んだので備忘録としてこちらにまとめます。

#for文をmapで書き換える
配列内の値に変更を加えて再度配列に格納し直したい場合を考えてみます。

for文だと配列のlengthの数だけループを回して処理を加えたのち、新しく定義した配列にpushするという方法が考えられます。

###forを使ったケース

```jsx
const numArray = [1, 2, 3, 4, 5, 6];

const array = [];
for(let i = 0; i < numArray.length; i++){
  const doubleNum = numArray[i] * 2;
  array.push(doubleNum);
}

//出力　[2, 4, 6, 8, 10, 12]
console.log(array);
```

###mapを使ったケース
これをmapで書くと以下のようにすっきりと書くことができます。

```jsx
const numArray = [1, 2, 3, 4, 5, 6];

const array = numArray.map(el => el * 2);

//出力　[2, 4, 6, 8, 10, 12]
console.log(array);
```


#reduceで配列内の数字の合計を出す
配列内の値を全て足し合わせたい場合。
forやmapで一つずつ取り出して足してもできますがreduceを使えば簡単です。

###reduceで合計値を計算

```jsx
const numArray = [1, 2, 2, 3, 3, 3, 3];

const getSum = array => {
  return numArray.reduce((a, b) => a + b, 0);
}

// 出力　17
console.log(getSum(numArray));
```

#ループ処理とif文をreduceと三項演算子ですっきり書き換える
こちらは配列内に2以上の数字がいくつあるかを数える関数です。
for文とif文を組み合わせて算出することも可能ですが、これもreduceを使えばすっきり書けます。

###forとif文のケース

```jsx
const numArray = [1, 2, 3, 4, 5, 6];

const getCount = array => {
  let count = 0;
  array.forEach(num => {
    if(num > 2){
      count += 1;
    }
  });
  return count;
}

//出力　4
console.log(getCount(num));
```

###reduceのケース
初期値を0に設定することで、三項演算子で記載した条件をクリアする値の数をカウントすることができています。

```jsx

const count = numArray.reduce((a, b) => {
  return b > 2 ? a + 1 : a + 0;
}, 0);

//出力　4
console.log(count);
```

#さいごに
mapもreduceもまだまだいろいろな使い方があります。
今後も新たな発見があればまとめていきたいと思います。
OktaとQuickSightの連携について

https://aws.amazon.com/jp/blogs/news/federate-amazon-quicksight-access-with-okta/

基本的に上記通りにやればいいんだけど、Okta側のDefault Relay Stateは
https://ap-northeast-1.quicksight.aws.amazon.com/

に変えておいた方がやりやすいかもね。東京リージョンの場合なので、他のリージョンの際はその通りに修正の必要ある。

特定のDashBoardに直接移動させたい場合は、
https://us-east-1.quicksight.aws.amazon.com/sn/dashboards/11111111-abcd-1234-efghi-111111111111

こんな感じに書いておく必要あるけど、こんなパターンそんなにあるかな、と思うし。
【AWS】踏み台サーバーを経由して目的のサーバーへアクセスする

# はじめに
キーペア、公開鍵、秘密鍵の理解から始まりましたが、なんとか踏み台サーバーを経由して目的のサーバーへアクセスすることができました。
ローカル、ファイルパス等基本的な用語の理解を復習すると良いのかと思います。

# 流れ
1. ローカル環境のキーペアを、踏み台サーバーへ送る
2. 踏み台サーバーへアクセスする
3. 受け取ったキーペアを持って目的のサーバーへアクセスする

# やったこと
まずは、ローカル環境のキーペアを踏み台サーバーへ送ります。
ローカル環境？となりましたが、ec2に接続する前の状態がローカル環境です。
ちなみにキーペアは、

```
cd #ホームディレクトリへ移動
cd ~/.ssh #sshへ移動
ls #中身を確認
```

この中にEC2作成時に作成したキーペアが存在します。
このキーペアの理解も私は躓きました。

https://wa3.i-3-i.info/word17048.html

この記事を読みイメージがしやすくなりました。


送る鍵がわかったところで、実際に踏み台サーバーへキーペアを送ります。

```
scp -i [キーペアファイルのパス] [送信元先ローカルファイルパス] [ユーザ名@ドメイン]:[転送先EC2ファイルパス]
scp -i ~/.ssh/lsで確認した送りたいキーペア ~/.ssh/lsで確認した送りたいキーペア ec2-user@送信先IPアドレス:.ssh/lsで確認した送りたいキーペア
```

私は、送りたい鍵を送信先でも同じように使用するため、
[転送先EC2ファイルパス]にも同様の名前を入力しました。
（理解が合っているかはわかりません、、、もっと調べます。）

一度、[送信元ローカルファイルパス]を送りたい鍵ではないものに設定し、
[転送先EC2ファイルパス]は使いたい名前、つまり.ssh/lsで確認した送りたいキーペアを指定して送信してしまい、
一見名前は合っているけど鍵の中身が異なっていて使えないという状況になったので、ファイルパス名はよく確認してください。


踏み台サーバーに接続し、

```ruby
#ホームディレクトリへ移動
cd　
#sshへ移動
cd ~/.ssh 
#中身を確認
ls
```

で確認することで、先ほどまではなかった鍵が受け取れていると思います。
目的のサーバーへの接続は、踏み台サーバーへの接続と同様のコマンドで大丈夫です。

```
ssh -i ~/.ssh/キーペア ec2-user@IPアドレス
```

# 終わりに
理解があまりできていないところ、おかしいところがあるかと思いますが、
その際はご指摘いただけると幸いです。


# 参考
https://dev.classmethod.jp/articles/scp-for-bigginer/
Safari 15 Beta リリースノート日本語訳

iOS15がそろそろリリースされるにあたり、safari 15 betaのリリースノートを見ていたついでにまとめておきます。
日本語訳するのめんどくさい人向け。

#概要
Safari 15は、iOSおよびiPadOS 15とmacOS 12に同梱されています。

##全体的な部分
macOS 12、iOSおよびiPadOS 15のSafariユーザーインターフェイスを再設計。
Tab Groupsとカスタマイズの同期を追加。

##認証・パスワード
- iCloudキーチェーンパスワードマネージャに検証コードのサポートを追加。SafariとAutofillで検証コードを使用するには、以下のようにする。
    - autocomplete=one-time-codeを適用し、inputタグを自動入力の対象にする。
    - 標準のotpauth URLを使用し、スキームをapple-otpauthに置き換えて、セットアップ用のパスワードマネージャーに直接リンクする。
    - ラスターイメージを使用して、検証コード生成機のセットアップを提供するotpauth QRコードのコンテクストメニューを有効にする。

- iCloudキーチェーンのパスキーのテクノロジープレビューを追加
    - パスキーは、デバイスの同期やバックアップを伴うウェブサイトやアプリケーションのパスワードを置き換えることを目的としたWebAuth認証情報。
    - テクノロジープレビューを有効にするには、Safariで「開発」＞「同期プラットフォーム認証機能を有効にする」を選択する。

##CSS
- box要素のアスペクト比をサポート。
- colorシンタックス lab(), lch(), hwb()のサポートを追加。
- color()構文を使った定義済み色空間のサポートを追加。(srgb, display-p3, a98-rgb, prophoto-rgb, rec2020, xyz)
- 新しいiOSデザインの安全領域に合わせて、環境変数の計算を適切に調整。

##HTML
- iOSのフォームコントロールのデザインを変更。
- macOSとiPadOSではタブバーの背景とオーバースクロール領域を、iOSではステータスバーを変更するためのテーマカラーメタタグのサポートを追加。
- ダークモードとライトアピアランスのテーマカラーメタタグを指定するmedia属性のサポートを追加。

```
<meta name="theme-color" content="#ecd96f" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#0b3e05" media="(prefers-color-scheme: dark)">
```

##JavaScript
- top-level awaitの追加。
- WorkersおよびServiceWorkersにおけるES6モジュールのサポートを追加。
- Error.causeのサポートを追加
- プライベートクラスのメソッドとアクセサのサポートを追加（Safari 14.1ではprivate data member構文のサポートが追加されました）。
- BigInt64Array と BigUint64Array のサポートを追加。

##メディア
- MediaSession APIのサポートを追加し、SharePlay体験を可能にした。
- 内蔵のメディアコントロールに「再生速度」と「チャプター」のメニューを追加。
- iPadOS 15をサポートするすべてのiPadで、MSEにハードウェアアクセラレーションによるVP9とWebMを追加。
- WebMコンテナにおけるOpusオーディオコーデックのサポートを追加。

##セキュリティ・プライバシー
- HTTPSの自動アップグレードのサポートを追加。
- 既知のトラッカーからIPアドレスを隠す機能が追加。ユーザーはSafariの環境設定で有効にできる。
- プライバシーを保護する広告クリックアトリビューションのためのプライベートクリック測定機能の強化。
- アトリビューションレポートを更新し、クリック先にもレポートを送信するようにしました。
- リンク不可能なトークンによるクリック詐欺防止機能を追加。
- アトリビューションレポートにIPアドレス保護機能を追加。

##支払い
- 後払いや定期的な支払いの作成に対応。
- 配送方法に到着予定日を表示できるようになりました。
- ユーザーがクーポンコードを入力できるようになりました。
- 配送方法を店頭受け取りに設定する機能を追加。

##WebAssembly
- ストリーミングコンパイルのサポートを追加。
- バルクメモリ操作のサポートを追加。
- 参照型をサポートの追加。
- floatからintへのノントラッピング変換のサポートを追加。

##Web API
- WebGL 2のサポートを追加。 WebGLの実装はMetalの上で実行され、パフォーマンスが向上しています。
- Webページからアプリへのファイル共有を可能にする、Web Shareのレベル2の拡張機能のサポートを追加。詳細については、「Web Share API」を参照してください。
- ユーザーのジェスチャーがrequestAnimationFrameを通じて1秒の時間制限付きで伝達されるようになりました。

##Web Extensions
- iOSおよびiPadOSのSafari Web Extensionsのサポートを追加。
- Safari Web ExtensionsでdeclarativeNetRequestのサポートを追加。

##Web Inspector
- CSSグリッドコンテクストを視覚化してデバッグするための検査済みページオーバーレイを追加。
ADVANCED ECONOMETRICS:A BRIDGE TO THE LITERATURE,   EDWARD GREENBERG et.al,   WILEY SERIES IN PROBABILITY AND MATHMATICAL STATISTICS

```{r}

#ridge regression p.207

data("airquality")

data=na.omit(airquality)

X=data[,-1]

x=array(0,dim=dim(X))

for(j in 1:nrow(X)){
  
x[j,]=as.numeric(X[j,])  
  
}

X=x

Y=data[,1];N=length(Y)

k=1;p=ncol(X)

beta=solve(t(X)%*%X+diag(rep(k,ncol(X))))%*%t(X)%*%Y

C=eigen(t(X)%*%X)$vectors

lam=eigen(t(X)%*%X)$values

alpha_R=t(C)%*%beta

#OLS estimator : alpha

alpha_hat=diag(1/lam)%*%t(C)%*%t(X)%*%Y

EV=sum((Y-X%*%C%*%alpha_hat)^2)

Ve=EV/(N-p-1)

#GRE : generalized ridge estimator

#case1:

ki_hat=Ve/alpha_hat

alpha_GRE=solve(diag(lam)+diag(ki_hat))%*%diag(lam)%*%alpha_hat

pre=X%*%C%*%alpha_GRE

#case2:Hudson(1974) and Berger(1975)

#分散はわかっていないが、Veとした

ki_hat=(p-2)*Ve*lam^2/(sum((lam*alpha_hat)^2)-(p-2)*Ve*lam)

alpha_GRE=solve(diag(lam)+diag(ki_hat))%*%diag(lam)%*%alpha_hat

pre=X%*%C%*%alpha_GRE

#case3:strawderman considers

B=diag(rep(1,length(beta)))

lam_M=eigen(B%*%t(X)%*%X)$values[1]

a=sample(seq(0,2*(p-2)/(lam_M*(N-p+2)),0.001),1)

s=EV;g=1;h=1

beta_GR=solve(diag(1,ncol(X))+a*s*B%*%t(X)%*%X/as.numeric(t(C%*%alpha_hat)%*%t(X)%*%X%*%(C%*%alpha_hat)+g*s+h))%*%C%*%alpha_hat


```
【キャッチアップ】swift

### 変数についている！・？マークについて
！＝値が入ってないとエラーになる　＝　nilの場合はエラーが発生する(暗黙的アンラップ)
?=値が入っていなくてもエラーにならない　＝　nilの場合でもエラーが発生しない　
こちらの記事に詳細が書いてありました。
https://qiita.com/og_omochi/items/0b255c790c4c3aecc630

### アンラップの方法
1. 強制アンラップ(変数!)  
nilの場合エラーが発生する
2. if let  
nilの場合、処理がスルーされる
3. guard let  
nilの場合、elseの処理が実行される
4. オプショナルチェイニング(変数?)  
nilの場合でも処理が実行される

### Delegate
tableViewCellで実行できない処理を記載できる
1. protcolで宣言する
2. 実行処理を記載する
3. 受け渡し元のViewにdelegateをセット
4. 受け渡し先のViewにdelegateを呼び出す

### extension
クラスの機能を拡張することができるが、元の機能は変更できない

### `this class is not key value coding-compliant for the key`エラーについて
controllerのみから@IBOutletや@IBActionを削除すると発生します。
Show the Connections inspecterからも削除してやる必要があります。
こちらの記事に詳細が書いてありました。
https://qiita.com/Atsushi_/items/f7930dd00a2c2ea464cd

### つまづきポイント`Redundant conformance of 'mapViewController' to protocol 'MKMapViewDelegate'`
classとextension両方に~Delegateを記載していると発生するので、classの方を削除すると解消する


【参考URL】

https://www.youtube.com/watch?v=yS2WgnQPNvA&t=4s

https://www.youtube.com/watch?v=3v4OIds-OOg&t=20s

実践的なコーディングを紹介されています

https://www.youtube.com/channel/UC52aQ60K4lYYo150waDOt5w
Rails turbolinksとbootstrapのドロップダウン

##turbolinksとbootstrap
バージョン
Rails6.0.3
bootstrap4.5

今回発生した問題
サイト内にドロップダウンメニューをBootstrapで導入したが、ページ遷移直後にドロップダウンメニューを押しても機能せず、一度サイトを更新し直さないとドロップダウンが機能しないという点。

解決方法
application.js内にあったrequire("turbolinks").start()この記述を消す
turbolinksによって少し挙動に影響があったみたいです。
ここを消すことによる弊害が今後発生するかもしれませんが、一旦今日のところは解決です。
ぜひ参考にしてみてください!
Django rest_framework にてカスタムのレスポンスステータス・ボディを返却する方法について

# 概要
Django rest_framework を利用して API を設計しています。
アプリケーションでは、別サーバーへ HTTP アクセスしています。
HTTP アクセスが失敗して、なにもハンドリングをしないと、自前の Django アプリケーションで 500 エラーが発生してしまいます。
500 エラーは「うっかり」ででるような類のサーバーエラーのニュアンスがあるように感じられたので、起きうることは予想できるけれど、どうしようもない例外ということで [502 エラー](https://developer.mozilla.org/ja/docs/Web/HTTP/Status/502) を返そうとしました。
Spring MVC のようなことができることを想定していたのですが、既定の機能では、レスポンスステータスを、502 で返す方法がなさそうなので、カスタムのレスポンスを返却する方法を調査しました。

# 環境
* Python: 3.9
* Django: 3.1.4
* Django Rest Framework: 3.12.2


# 実現方法
公式ページのやり方を模倣するだけで実現できました。
[rest_framework.exceptions.APIException](https://www.django-rest-framework.org/api-guide/exceptions/#apiexception) を継承したクラスを作成します。

* status_code : ステータスコード
* detail: レスポンスボディのメッセージ

となりました。

```.py
from dataclasses import dataclass
from rest_framework.exceptions import APIException


@dataclass(frozen=True)
class ServerNotWorkedResponse(APIException):
    source_exception: Exception # 元となった例外
    message: str

    status_code = 502
    detail = "外部サーバーへのアクセスに失敗しました。"
```

このクラスを try catch でハンドルします。
もしも、リクエストする関数をモジュール化している場合、戻り値を [Union](https://docs.python.org/ja/3/library/typing.html#typing.Union) に設定して、呼び出し元 (アプリケーションレイヤー) で最後の振る舞いを決めることができます。
ライブラリの中でいきなり例外を投げたると、関数の本当の目的 (外部サーバーにアクセスしてレスポンスを利用元に返す) 以外に、「外部サーバーへのアクセスに失敗すると例外が発生する」という機能が入り込み、結果としてモなにか予想外のことがおきる、副作用があるライブラリになります。一番外側の利用元で最後の振る舞いを決める設計にすると、副作用を減らしたライブラリ設計を実現するための手段として活用できます。

```.py
import json
from dataclasses import dataclass
import ServerNotWorkedResponse
from typing import Union, cast
from urllib import request
from urllib.error import HTTPError, URLError

@dataclass(frozen=True)
class ExampleDomainResponse:
    id: int,
    name: str

# 呼び出し先
def request_towards_example(id: int) -> Union[ServerNotWorkedResponse, ExampleDomainResponse]:
    req = request.Request(f'https://example.domain.io/resources/{id}')
    try:
        with request.urlopen(req) as res:
            resource = json.loads(res.read())
    except HTTPError as e
        return ServerNotWorkedResponse(source_exception=e, message='サーバーがエラーを返してきました。')
    except URLError as e:
        return ServerNotWorkedResponse(source_exception=e, message='このサーバーは名前解決ができませんでした。URL を解決できるよう設定してください。')
    else:
        return ExampleDomainResponse(
            id=cast(int, resource['id'])
            name=resource['name']
        )

# 最も外側の呼び出し元
response_from_example: Union[ServerNotWorkedResponse, ExampleDomainResponse] = request_towards_example(1)
if isinstance(response_from_example, ServerNotWorkedResponse):
    server_not_worked = cast(ServerNotWorkedResponse, response_from_example)
    logger.error(server_not_worked.source_error)
    logger.error(server_not_worked.message)
    raise server_not_worked


```
[UE5] Canvasの表示切り替えコマンド

# 概要
　Widget表示のON/OFFを一括で切り替えるためのコンソールコマンドが最近追加されました。これは以下のリンクのUE5.0Mainのリポジトリには入っておりUE4.27には入っていません。

https://github.com/EpicGames/UnrealEngine/commit/43337b3e261a39c322041d382cd573e1b7b5e201

　このコンソールコマンドを利用することで、以下のように画面上に表示しているWidgetをON/OFFを切り替えることができます。
![2021-09-06_14h48_53.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/750117ab-47b6-e278-df0c-2ce781454ef1.gif)

# 説明
　以下のコマンドが用意されており、各キャンバス/スロットの表示を0=非表示, 1=表示で切り替えることができます。

```:コマンド一覧
Slate.GameLayer.PlayerCanvasVisible
Slate.GameLayer.ViewportSlotVisible
Slate.GameLayer.DebugCanvasVisible
Slate.GameLayer.AllCanvasesVisible
```

以下のコマンドでは、画面全体を示すビューポートに追加されたウィジェットの表示を一括でオフにします。

```:コマンド使用例1
Slate.GameLayer.ViewportSlotVisible 0
```
このコマンドは、スレートのルートにビューポートの子に位置する「GameLayerManager」と呼ばれる上位レイヤーで処理を行い、GameLayerManagerが所有する上位のCanvasやSlotを制御することによって、一括での表示切替を実現します。各階層に関しては以下のようにWidgetReflectorで確認すると可視化できます。

![2021-09-06_12h50_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/11075266-1020-17e8-c973-8946469b3b54.png)

関連するコマンドとスレートオブジェクトの関連は以下の通りです。

#### Slate.GameLayer.PlayerCanvasVisible
上記図の①に該当する、プレイヤー毎のレイヤーCanvasのON/OFFを切り替えます。
AddToPlayerScreenで追加したWidgetの表示に関連します。

#### Slate.GameLayer.ViewportSlotVisible
上記図の②に該当する、ビューポート全体のSlotのON/OFFを切り替えます。
AddToViewportで追加したWidgetの表示に関連します。

#### Slate.GameLayer.DebugCanvasVisible
上記図の③に該当する、デバッグCanvasのON/OFFを切り替えます。
コンソールコマンドを入力する際のデバッグ表示に関連します。

#### Slate.GameLayer.AllCanvasesVisible
上記の3点を一括して制御する時に使用します。


これらのコンソールコマンドを利用するとデバッグがはかどるかと思いますのでご活用ください。
JavaScriptでコードに影響を与える記号などを表示したい場合の方法

<h1>概要</h1>
JavaScriptにてシングルクオーテーション（'）など、パラメータ内で使用している記号をそのまま表示しようとすると　
エラーが発生してしまうため、その表示方法についてのまとめとなります。


<h1>内容</h1>
　　　
以下の文章を表示したい場合を例に説明したいと思います。
　　　``` I'm Japanese```
これをそのままプログラムで表示しようとした場合、
　　　```document.write('I'm Japanese');```

となりますが、シングルクオーテーションとアポストロフィが同じ記号であるためエラーが発生してしまいます。
このように、特殊な文字を表示したい場合はエスケープシーケンスと呼ばれるものを使って表示するようにできます。
上記の場合だとシングルクオーテーションであることを出力したいので__「\'」__と記載することで表示が可能となります。

　　　```document.write('I\'m Japanese');```

<h3>その他まとめ</h3>
エスケープシーケンスには他にもいくつかあるので、表示でエラーが発生した場合に参考してみてください。


|記号|意味|
|:-----|:------|
|\b|バックスペース|
|\t|水平タブ|
|\v|垂直タブ|
|\n|改行|
|\r|復帰|
|\f|改ページ|
|\'|シングルクォーテーション|
|\''|ダブルクォーテーション|
|\\|円マーク（またはバックスラッシュ）|
|\0|NULL文字|
|\xXX|2桁のXX（16進数）が表すLatin-1文字|
|\uXXXX|4桁のXXXX（16進数）が表すUnicode文字|
[UE4] コンソールコマンドから指定したアセットのロード (LoadPackageAsync)

検証バージョン：UE4.27

# 概要
　コンソールコマンドからのアセットロードする方法について記載します。このコマンドはShipping以外のビルドで利用することができ、さまざまなケースに応用することができます。

 **・アセット単独でのロードの負荷を調べることができる**
　アセットを指定してロードすることができます。これは「空のレベルで指定のアセットのみをロードする」といったことを行うことによって、1つのアセットがロードされる際の純粋なロードの負荷を調べる際に役に立ちます。レベルのロード時や初期化時には大量のアセットがロードされがちですがこのコマンドを利用して単独でアセットをロードすることによって、本当に原因となっているアセットや処理を特定することができます。

 **・特定のアセットにリファレンスされたアセットを調べることができる**
　Unreal Insightsでアセットロード状況を確認することによって、どのようなアセットが紐づいていてロードされているかを調べる事ができます。

 **・アセットがパッケージに存在していることを調べることができる**
　アセットを指定したロードができるため、現在のパッケージ内にアセットが含まれているかどうかを調べるのにも役に立ちます。特にDLCやパッチにおいて、アセットはチャンク毎に分割してインストールされることになるので、現在マウントされたパックにアセットが存在しているかを調べることができます。


# 使用方法
　コンソールコマンド **`LoadPackageAsync`** を使用することで、指定したアセットをロードすることができます。**`引数としてアセットのパッケージパス`**を渡します。

```:コマンド例1：1つのテクスチャをロード
LoadPackageAsync /Game/Mannequin/Character/Textures/T_UE4Logo_Mask
```

　複数のパッケージパスを指定する事で複数のアセットをロードします。以下の例ではWorld1, World2のマップがバックグラウンドでロードされます。

```:コマンド例2：2つのレベルをロード
LoadPackageAsync /Game/Maps/World1 /Game/Maps/World2
```

　ロードの負荷を見たい場合は、Unreal InsightsでAssetLoadingInsightsを有効にしてこのコマンドを実行するだけです。特定のアセットのみがロードされてプロファイルにも出力されます。例えば以下のように、レベルにリファレンスされたウィジェットがあるような条件において、レベル(World2)だけをロードすると、

![2021-09-05_14h25_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/da1b6fa1-fba7-cfac-5298-845832df3cfb.png)

以下のような出力が得られます。レベルだけを指定してロードした時に、LoadingトラックではリファレンスされたWB_Testのウィジェットも含む2つのアセット(水色と緑色のバーのアセット)がロードされていることが分かります。

![2021-09-05_14h30_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/5adf5da4-6e42-854b-c350-aa8a1ea5b137.png)


# コード部
　以下はこのコンソールコマンドを実行する部分のコードになります。Shipping以外では動作しないようになっていますが、ロジック自体はShippingでも利用できるので、LoadPackageAsync()の処理をプロジェクト側で再利用しても問題はありません。

```cpp:AsyncPackageLoader.cpp
static void LoadPackageAsyncCommand(const TArray<FString>& Args)
{
	for (const FString& PackageName : Args)
	{
		UE_LOG(LogStreaming, Display, TEXT("LoadPackageAsyncCommand: %s - Requested"), *PackageName);
		LoadPackageAsync(PackageName, FLoadPackageAsyncDelegate::CreateLambda(
			[](const FName& PackageName, UPackage* Package, EAsyncLoadingResult::Type Result)
		{
			UE_LOG(LogStreaming, Display, TEXT("LoadPackageAsyncCommand: %s - %s"),
				*PackageName.ToString(), (Package != nullptr) ? TEXT("Loaded") : TEXT("Failed"));
		}
		));
	}
}

static FAutoConsoleCommand CVar_LoadPackageAsyncCommand(
	TEXT("LoadPackageAsync"),
	TEXT("Loads packages async by names. Usage: LoadPackageAsync <package name> [<package name> ...]"),
	FConsoleCommandWithArgsDelegate::CreateStatic(LoadPackageAsyncCommand));
```

また、このコマンドと同じような"LoadPackage"というコマンドもありますが、こちらはGameThreadでの非同期実行待ち処理が走りスパイクが発生することがあります。ですので、LoadPackage"よりは"LoadPackageAsync"をご利用ください。
【Mac】Docker+rails6+postgreSQLでの環境構築完全版

環境
---
MacOS Big Sur 11.5.2
ruby 3.0.2
rails 6.1.4
Docker 20.10.8
postgreSQL 13.4
ディレクトリ　myapp
全て現時点(2021/09/06)での最新バージョンです。

1.用意するファイル
---
・Dockerfile
・Gemfile
・Gemfile.lock
・entrypoint.sh
・docker-compose.yml

```docker:Dockerfile
FROM ruby:3.0.2
  # yarnパッケージ管理ツールをインストール
  RUN apt-get update && apt-get install -y curl apt-transport-https wget && \
  curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
  echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
  apt-get update && apt-get install -y yarn
  RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
  RUN mkdir /myapp
  WORKDIR /myapp
  COPY Gemfile /myapp/Gemfile
  COPY Gemfile.lock /myapp/Gemfile.lock
  RUN bundle install
  COPY . /myapp

  # Add a script to be executed every time the container starts.
  COPY entrypoint.sh /usr/bin/
  RUN chmod +x /usr/bin/entrypoint.sh
  ENTRYPOINT ["entrypoint.sh"]
  EXPOSE 3000

  # Start the main process.
  CMD ["rails", "server", "-b", "0.0.0.0"]
```
ここでyarnをインストールしておくのがポイントです。しないと後でwebpackerがインストールできずエラーになります。

```rails:Gemfile
source 'https://rubygems.org'
  gem 'rails', '~>6'
```
Gemfile.lockは空のままで大丈夫です

```docker:entrypoint.sh
#!/bin/bash
  set -e

  # Remove a potentially pre-existing server.pid for Rails.
  rm -f /myapp/tmp/pids/server.pid

  # Then exec the container's main process (what's set as CMD in the Dockerfile).
  exec "$@"
```
```docker:docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
       - POSTGRES_PASSWORD=password
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
 ```
2.実行
---
```
$ docker-compose run web rails new . --force --no-deps --database=postgresql
```
↓

```
$ docker-compose build
```
ここでdatabase.ymlを編集します

```docker:config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: password
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  database: app_development

test:
  <<: *default
  database: app_test

production:
  <<: *default
  database: app_production
  username: app
  password: <%= ENV['APP_DATABASE_PASSWORD'] %>
```
パスワードなど設定した後データベースと接続します。

```
$ docker-compose run web rake db:create
```
↓

```
$ docker-compose up
```
終わったらlocalhost:3000とネットで検索すればこの画面が出てきます。
そしたら環境構築成功です！

![スクリーンショット 2021-09-06 13.25.32.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340036/a975dd7a-a241-0dcd-bd7e-27db1d3fe6a8.jpeg)

おわりに
---

[【Mac】Docker+rails6+MySQLでの環境構築完全版](https://qiita.com/minoppp411/items/fbef2581385bf02a2fe5)
MySQLバージョンも作ったのでぜひ参考にしてください！
Figma Bootstrap5 レイアウトグリッド設定まとめ

FigmaでBootstrap5のデザインをする際のレイアウトグリッド設定まとめです。

##グリッドの見方

まずは簡単にグリッドレイアウトの見方です。
下の図をご覧ください。Bootstrapではお馴染みの12列で分けられたグリッドシステムになります。

![2021-09-05_22h19_49.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/1e3fb554-d77c-14aa-b1ee-0f762d890d93.jpeg)
![名称未設定.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/6649d445-fb77-1d93-8c76-b564d7e40a2f.jpeg)


それぞれについて解説します。

**ブレイクポイント**
デバイスの幅の切り替わるポイント。v5.0.0-alpha1からXXLが追加されました。
figmaでフレームを作る際はここの下限値をwidthに設定します。（例：XLなら1200px、MDなら768px）

**コンテナの幅**
ウェブサイトで実際のコンテンツの入る部分。<font color="red">左端のガター（赤い部分）から右端のガターまで</font>すべてを含みます。

**列（ガター）の幅**
列と列の間の余白。<font color="Blue">12列（青と青の間）</font>と<font color="red">両端に2列（赤い部分）</font>あります。
ルートHTMLのサイズを特にカスタマイズしていない場合、デフォルトで1rem=16pxとなり、ガターは16×1.5=24pxとなります。
両端のガターは16×.75=12pxです。

## レイアウトグリッドの設定

### ワイド画面サイズ 1320px XXL - 1400px->

Bootstrap5から新しく追加されたサイズです。
XLサイズで作っていれば、大抵の場合XXLも同じデザインになる場合が多いので作らずともよいサイズかと思います。

フレームは**1400px**です。
![a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/75b7f839-7473-9703-8807-47fddbb70b7e.jpeg)![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/5692eb79-4307-a202-14a9-72a0907cf5b0.jpeg)

### 大画面サイズ 1140px XL - 1200px-1399px

フレームは**1200px**です。
![b.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/c837068b-d278-ea55-0db2-d2c23be07964.jpeg)![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/0d07b5cf-11d0-92ff-8d6a-400beb058e9f.jpeg)

### デスクトップサイズ 960px LG - 992px-1199px

フレームは**992px**です。
![c.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/548551e8-f711-4dda-875d-594f1b37491f.jpeg)![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/938752e2-d327-aa09-a329-7320e2f0d094.jpeg)

### タブレットサイズ 720px md - 768px-991px

フレームは**768px**です。
![d.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/d4d24e25-7045-386a-f584-a0160bfcb2b3.jpeg)![4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/96552f55-2630-c018-d16d-ae1934e92129.jpeg)

### 横モバイルサイズ 540px sm - 576px-767px

フレームは**576px**です。
![e.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/bc940995-a931-e8fc-0a94-725d1982a184.jpeg)![5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/aded5ac8-0fc8-a73e-017d-382cccce9a1e.jpeg)

### 縦モバイルサイズ 320px XS <-576px

XSは少し特殊です。
コンテナの幅は0（auto）となり、ブレイクポイントの576pxに達するまでは左右のパディングがありません。
よって、グリッドも同様に横幅いっぱいに広がります。

フレームは**320px**です。
![f.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/dc191201-5e82-889d-ed1a-64765601c5d4.jpeg)![6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/1214cf63-a10d-04b9-f42b-d6ae89417a13.jpeg)
【AWS】新しいVPCにEC2インスタンスのコピーを作成する　

#はじめに
AWSのEC2画面からスタートします。
#AMIを作成する
1. サイドメニュー[インスタンス]から、コピーしたいインスタンスを選択
2. 右上の[アクション]>[イメージとテンプレート]>[イメージを作成]を選択
3. [イメージ名]にどこのインスタンスのコピー情報かわかるよう任意の名前を入力
4. 再起動しない/[有効化]にチェック
5. 終了時に削除/[有効化]にチェックが入っているか確認（デフォルトで入っています） 
6. [イメージを作成]を選択
7. サイドメニュー[イメージ]>[AMI]を選択
8. 先ほどのAMIが作成されていることを確認
9. ステータスが[available]になったら終了


#EC2インスタンスを作成する
1. サイドメニュー[イメージ]>[AMI]を選択
2. 作成したAMIを選択
3. [アクション]>[起動]を選択し、インスタンスの情報を入力
4. 無料枠の方は無料枠の設定に気をつけて、コピー元と同じように作成していくイメージ
5. [インスタンスの作成]でインスタンス一覧に複製したEC2インスタンスが存在することを確認

#　終わりに
思っていたよりも簡単にコピーが作れました。
VPCについての理解がまだまだ浅いので何をやっているのかわかりませんでしたが、
ひとつずつ手順を踏んで、何度も復習することでイメージが少しずつできるようになってきました。
RDSも同じVPC内に移行することで作成した新しいEC2に接続し、作成物を閲覧することができるようになりました。

# 参考
https://qiita.com/ponsuke0531/items/ceca4ac18c097f8b24b8
技術的読書ノート

#1冊ですべて身につくHTML ＆ CSSとWebデザイン入門講座 by Mana 
2回読みました。 

##TakeAway
```

コメント
HTML
<!-- コメント -->
CSS
/*と */

<div style="text-align: center;">
<p style="font-weight: bold;">これはテストの文章です。</p>
</div>
```

#動かして学ぶ！Vue.js開発入門 by 森巧尚 
##シラバス
Chapter 1　Vue.jsって何？
　01　Vue.jsって何？
　02　Vue.jsは「データと表示をつなげる仕組み」
　03　インストールしてみよう
　04　試してみよう
　05　まとめ

Chapter 2　データを表示するとき
　01　Vue インスタンスを作る：new Vue
　02　データをそのまま表示する：{{ データ }}
　03　使えるデータの種類
　04　まとめ

Chapter 3　属性を指定するとき
　01　要素の属性をデータで指定する：v-bind
　02　まとめ

Chapter 4　ユーザーの入力をつなぐとき
　01　入力フォームをデータとつなぐ：v-model
　02　まとめ

Chapter 5　ユーザーの操作をつなぐとき
　01　イベントとつなぐ：v-on
　02　まとめ

Chapter 6　条件とくり返しを使うとき
　01　条件によって表示する：v-if
　02　くり返し表示する：v-for
　03　まとめ

Chapter 7　Google Chartsと連動させてみよう
　01　Google Chartsとは？
　02　Google Chartsと連動させる
　03　まとめ

Chapter 8　データの変化を監視するとき
　01　データを使って別の計算をする：算出プロパティ
　02　データの変化を監視する：監視プロパティ
　03　まとめ

Chapter 9　Markdownエディタを作ってみよう
　01　Markdown エディタとは？
　02　Markdown エディタを作る
　03　まとめ

Chapter 10　アニメーションするとき
　01　表示／非表示時にアニメーションする：transition
　02　リストのトランジション：transition-group
　03　リストの並びが移動するトランジション
　04　まとめ

Chapter 11　ToDoリストを作ってみよう
　01　ToDoリストとは？
　02　仮データでToDoリストを表示する
　03　改良する：追加＆削除機能
　04　まとめ

Chapter 12　部品にまとめるとき
　01　部品にまとめる：コンポーネント
　02　コンポーネントのdata はfunction にする
　03　値を渡す：props
　04　まとめ

Chapter 13　JSONデータを表示させてみよう
　01　JSONファイルの読み込み方
　02　JSONデータを読み込んで、コンポーネントで並べる
　03　改良する：トランジションをつける
　04　まとめ
##用語
マスタッシュタグ
ActiveRecord の accepts_nested_attributes_for の _destory をサーバー側で設定する。

自分のメモ用にスニペットとして残す。説明わかりにくくてごめんよ。


### やりたいこと

accepts_nested_attributes_for指定により(一つまたは複数の)子レコードを持つ特定のモデルのupdate(PUT)時を考える。
子レコードのうち削除したいレコードのhashには、`_destroy: true`を指定する。

一般的に、`_destroy: true`はこのフォームで指定する。
が、これをサーバーサイドにおいて、既存レコードとの差分を見て消滅したレコードに、上記の指定を加えるようにしたい。


### 実装
User has many taggings の例で説明する。下のようにモデル層でtaggings=を上書きしてやった。


```user.rb
class User
  had_many :taggings, dependent_destroy: true
  accepts_nested_attributes_for :user_taggings, allow_destroy: true

  # ここ！
  def taggings=(attributes)
    curr_user_taggings = self.user_taggings.map{ |t| [t.user_id, t.id] }.to_h  # 既存のtaggingをここで取得

    attributes.each do |attribute|
      if curr_user_taggings[attribute[:user_id]]
        attribute[:id] = curr_user_taggings[attribute[:user_id]]
        curr_user_taggings.delete(attribute[:user_id])
      end
    end
    curr_user_taggings.each do |user_id, tag_id|  ### ここに残っているものは、消されるべきものに他ならない。
      attributes << { id: tag_id, _destroy: true } 
    end
    super(attributes)
  end
end

```
オンラインゲームの作り方【Unity+Mirror】

オンラインゲームを作りたい！でも作り方がわからない...という方はよくいると思いますが、
今回はそういう方に向けて
Unity+Mirrorでのオンラインゲーム制作のやり方を記載していきたいと思います。

<h1>【目次】</h1>
* 事前準備について
 * Unityって？
 * Mirrorって？
* オンラインゲームの実際の作り方（基盤作りまで）

<h1>事前準備は何が必要なの？</h1>
今回推奨するのはUnity+Unity内のアセット（追加パッチみたいなもの）「Mirror」だけで作れるよ！

Unityの公式ダウンロードサイトはここだよ！

https://unity3d.com/jp/get-unity/download

Unityは複数Versionを所有していてVersion違いでバグが発生する可能性があるからUnityHubっていう
複数のバージョンのダウンロード＆管理や切り替えが出来るツールの方をダウンロードしてね！
その後はとりあえずUnity公式が推奨する安定版のVersionを使用すればいいと思うよ！
参考にしているサイトとか動画がある場合に最新版を使って、
エラーが出るなら参考のバージョンに合わした方がいいかも？

<h2>まずUnityって？</h2>
Unityっていうのはゲームエンジンといって、
ゲーム制作をする際に最低限の色々な機能を持った空間を用意してくれているものだよ！
初期画面としてはこんな感じだよ！この空間に色々物体を置いたりして調整してゲームを作るんだ！
![New Unity Project - SampleScene - PC, Mac & Linux Standalone - Unity 2020.3.16f1 Personal _DX11_ 2021_09_06 14_58_56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1981364/ec41dce5-bbda-2e7e-8132-2913f843bf28.png)

ゲームエンジンとしてはこのUnityとUE4（Unreal Engine4）というのが二大巨頭になっているんだけど...
どちらかというとUnityは汎用的ゲーム制作に使えて
UE4は本格3Dゲーム制作を作るのに適しているっていうのが通例だね！
といってもシェアを厳密に分割するとUnityの方が多く使われているからUnityを採用するよ！

<h2>Mirrorって？</h2>
MirrorはUnity内で追加出来るアセットで、
これをUnity内にいれるだけで大体オンライン通信が出来る環境の基盤が出来るよ！
更に内容物に手を少し手を加えるだけで
色んなカスタムも出来るからかなり時短になるありがたいアセットだよ！

<h1>オンラインゲームの実際の作り方（基盤作りまで）</h1>
さて、早速本題に入っていくよ！
まずUnityhubをダウンロードしてMirrorをインポートしていくよ！

詳しいやり方について、
本当に初心者向け（実際に初期ダウンロードから始めてるよ）に、
自分が実際に動画で解説したものがあるから字でわからない人はこっちを見てね！

■【基礎編】Unityオンラインゲーム作り方解説動画！【Unity初心者向け】

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


※将来的に色んなジャンルでの
　オンラインゲーム制作の動画を上げていく予定だからチャンネル登録よろしくね！

<h3>Unity上の操作</h3>
インポートが終わったら、ヒエラレルキー右クリックから「空のオブジェクト」を作成して、
それを「NetworkManger」って名前にしてネットワークを管理するオブジェクトとして設定するよ！

「ネットワークマネージャ」に「ネットワークHUB」を追加してね！
この段階で実行すると、もうネットワークに接続できる状態になってるよ！とても簡単だね！
でもまだこの段階じゃ何も設定してないから何も出るはずはなく...

最初にプレイヤーはどのゲームにもいるはずだからプレイヤーを出現させていくよ！
ヒエラルキーから右クリックで仮にプレイヤーを作っていくよ！
「3Dオブジェクト」→「スフィア」で名前を「Player」に設定するよ！
それをネットワーク空間に適応させるためにコンポーネント「NetworkTransform」を追加！
それからプレハブ化だよ！

そしたら「NetworkManger」の「プレイヤープレハブ」にその「Player」を追加してね！
すると、実行した時にHost又はClientで接続した時に設定したプレイヤーが表示されるはずだよ！
確認方法としては、
二人プレイヤーがいるからUnity上の実行+ビルドした実際のゲームで見比べていくよ！
ビルドしたゲームとUnity上で接続して確認してみてね！

...とこの段階ではまだプレイヤーが一つ召喚されたようにしか見えないんだ！
なぜならプレイヤーは二つ確かに出てるんだけど
当たり判定も設定してないから完全に同じ座標に表示されてるんだよね...

対策としてプレイヤーに
リジッドボディコンポーネント（当たり判定とか重力とか付属させるコンポーネント）を追加すると、
区別がつくようになると思うよ！
![tes.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1981364/5b5db821-8a3b-b0d1-9d22-8432b43b577a.png)


以上でオンラインゲーム制作の基礎の基礎は終わりだよ！
これからどんなゲームを作りたいかによって作り方を色々変えていってね！
自分チャンネルで将来的に【FPS】【2Dスクロールゲーム】を作れるようになるまで動画を用意するつもりだよ！
（現段階はFPS編が途中まで公開されているよ！）
他につくってほしいゲームジャンルとかがあったら気軽にyoutubeでコメントしてみてね！
59日後にITパスポートを受けるFラン私大文系既卒(40日目)

# プロジェクトマネジメント
* プロジェクトマネジメントとは?
 * 作業範囲、期限、費用を調整し、管理すること

# PMBOK(Project Management Body of Knowledge)
* PMBOKとは?
 * プロジェクトマネジメントの体系化された知識
* PMBOKの10の知識
 * プロジェクト総合マネジメント
 * プロジェクトスコープマネジメント
 * プロジェクトステークホルダマネジメント
 * プロジェクトコストマネジメント
 * プロジェクト品質マネジメント
 * プロジェクト資源マネジメント
 * プロジェクトコミュニケーションマネジメント
 * プロジェクトリスクマネジメント
 * プロジェクト調達マネジメント

# プロジェクトスコープマネジメント
* プロジェクトスコープマネジメントとは?
 * プロジェクトに必要な作業を抽出すること

# WBS(Work Breakdown Structure)
* WBSとは?
 * プロジェクトを細かい作業単位に分割すること
 * WBSで一番小さい単位をワークパッケージという

# プロジェクト憲章
* プロジェクト憲章とは?
 * プロジェクトの目的などを記載した文書
 * プロジェクトマネージャを任命し、責任と権限を明確にする

# ガントチャート
* ガントチャートとは?
 * プロジェクトの進捗状態を視覚的に表す図
 * タスクの所要時間を表す

# PERT(Program Evaluation and Review Technique)
* アローダイアグラムを使ったプロジェクト分析手法

# ダミー作業
* ダミー作業とは?
 * 所要時間が0日の作業

# マスタスケジュール
* マスタスケジュールとは?
 * 作業の工程が示された表
 * マイルストーンなどを記入する
 * 細かい作業内容などは省略される

# ディシジョンツリー
* デシジョンツリーとは?
 * 決定や選択、分類などを多段階で繰り返し行う場合、その「分岐の繰り返し」を階層化して樹形図に描き表したグラフ表現、あるいはその構造モデル。
フォロー・フォロワー機能

##1. Relationshipモデルを作成

```terminal
$ rails g model Relationship follower_id:integer followed_id:integer
# follower_id:フォローするユーザーのid, followed_id:フォローされるユーザーのid
$ rails db:migrate
# マイグレーション実行
```
##2. アソシエーションを記述

```app/models/relationship.rb
class Relationship < ApplicationRecord
  belongs_to :follower, class_name: "User"
  belongs_to :followed, class_name: "User"
  # class_name: "User"を定義することでUserテーブルのレコードを参照する
end
```
補足説明：belongs_to :followerでfollowerテーブルのfollower_idを探しにいきます。
ただ、今回はfollowerテーブルは作成していないのと、
参照してもらいたいのはfollower_idに格納されている値と同じuser_idなので
class_name: "User"でUserテーブルを参照するように定義します。
##3. Userモデルにメソッドを記述
```app/models/user.rb
class User < ApplicationRecord
def follow(user_id)
    relationships.create(followed_id: user_id)/1
end

def unfollow(user_id)
    relationships.find_by(followed_id: user_id).destroy/2
 end

  def following?(user)
    followings.include?(user)/3
  end
end
```
1.followed_idがuser_idであるRelationshipsモデルを生成して保存します。
2.followed_idがuser_idであるRelationshipsモデルを取得してActiveRecordを使って削除します。
3.userが、Followingsモデルの中に含まれているか判定します。

```app/models/user.rb
class User < ApplicationRecord
  has_many :reverse_of_relationships, class_name: "Relationship", foreign_key: "followed_id", dependent: :destroy
  has_many :followers, through: :reverse_of_relationships, source: :follower
  # 被フォロー関係を通じて参照→followed_idをフォローしている人

  has_many :relationships, class_name: "Relationship", foreign_key: "follower_id", dependent: :destroy
  # 【class_name: "Relationship"】は省略可能
  has_many :followings, through: :relationships, source: :followed
  # 与フォロー関係を通じて参照→follower_idをフォローしている人
end
```
##4. Relationshipコントローラを作成・編集
まずはrelationshipsコントローラを作成します。

```
$　rails g controller relationships
```

``` relationships_controller.rb
class RelationshipsController < ApplicationController
  before_action :authenticate_user
  def create
    following = @current_user.follow(params[:user_id])/1
    flash[:notice] = if following.save
                       'ユーザーをフォローしました'
                     else
                       'ユーザーのフォローに失敗しました'
                     end
    redirect_to("/users/#{params[:user_id]}")
  end

  def destroy
    following = @current_user.unfollow(params[:user_id])/2
    flash[:notice] = if following.destroy
                       'ユーザーのフォローを解除しました'
                     else
                       'ユーザーのフォロー解除に失敗しました'
                     end
    redirect_to("/users/#{params[:user_id]}")
  end

  def followings
    user = User.find(params[:user_id])/3
    @users = user.followings/4
  end

  def followers
    user = User.find(params[:user_id])/3
    @users = user.followers/4
  end
```
1.relationshipsコントローラーのcreateアクションにおいては、先程userモデルで定義したfollowメソッドを使っています。
2.relationshipsコントローラーのdestroyアクションにおいて、先程userモデルで定義したunfollowメソッドを使っています。
3.user = User.find(params[:user_id])で取得したユーザーのidが、
フォローしている　もしくは　フォローされている ユーザーのid一覧を
取得することができます。
4.@users = user.followings、
@users = user.followersでは、
先程userモデルで定義したアソシエーションを利用します。
##引用記事 
[【Ruby on Rails】フォロー・フォロワー機能の実装](https://qiita.com/MOEKASAKAI/items/69ae05554b1562a603ea)
[Railsでフォロー機能を作る方法](https://qiita.com/mitsumitsu1128/items/e41e2ff37f143db81897)
【JavaScript】forEarchメソッド

#はじめに
こんにちは。
今回は、JavaScriptのforEarchメソッドについてアウトプットしていきます！

##forEarchメソッドとは
>`forEach()` メソッドは与えられた関数を、配列の各要素に対して一度ずつ実行します。

> 参照：https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

```javascript:JavaScript
const arry = [1,2,3,4,5];

arry.forEach(function(v){
  console.log(v);          //1,2,3,4,5
})
```
配列arryには、1から5までの要素が格納されているので、要素の数だけ処理を実行している。

<br>

```javascript:JavaScript
const ary = [1,2,3,4,5];

for(let i = 0; i< ary.length; i++){
  const v = ary[i];
  console.log(v);          //1,2,3,4,5
}
```
上記のfor文とforEachメソッドの実行結果は同じだが、forEarchメソッドの方が記述を少なくできる。

<br>

###forEachメソッドの引数

```javascript:JavaScript
const arry = [1,2,3];

arry.forEach(function(v,i,ary){
  console.log(v,i,ary);
})

//実行結果
//1 0 [1, 2, 3]
//2 1 [1, 2, 3]
//3 2 [1, 2, 3]
```
forEachメソッドの第１引数には配列の値、第２引数には添字、第３引数には配列が渡される。

<br>

#最後に
ここまでforEarchメソッドについてまとめました。
これからもJavaScriptの理解を深めていきます！
気づいたらhuskyが7系になっていたので、導入手順確認する

# はじめに
今までhuskyの4系を使っていたのですが、気づいたら7系まであがっていました。
で、久しぶりに入れてみたら4系の設定で動かなかったので、
コミット時にhusky,lint-stagedで、eslint,prettierを走らせる設定手順を書き残しておきます。

# リポジトリ

コード（設定）はこちら

https://github.com/alternacrow/Husky7AndLintStaged

# ライブラリとバージョン

```json
"husky": "7.0.2"
"lint-staged": "11.1.2"
```

# 手順

## lint-stagedの設定

パッケージの追加

```bash
yarn add -D lint-staged
```

gitのステージングのファイル処理の設定を追加

ステージにあがっている対象ファイルに対して、lintとprettierをかける。
処理後、処理された状態で自動addされる

`.lintstagedrc.js`

```js
module.exports = {
  "*.{js,jsx,ts,tsx}": [
    "eslint --fix",
    "prettier --write",
  ],
}
```

## huskyの設定

パッケージの追加

```bash
yarn add -D husky
```

huskyの設定をインストール

```bash
npx husky install
```

prepareスクリプトを追加

`package.json`

```json
{
  "scripts": {
    "prepare": "husky install"
  }
}
```

pre-commit時に、lint-stagedの処理が走るように設定を追加

```bash
npx husky add .husky/pre-commit "yarn lint-staged"
```

下記のファイルが追加されます

`.husky/pre-commit`

```bash
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

yarn lint-staged
```

# どう使うの
修正ファイルをコミットすれば、対象ファイルに対して、
`eslint --fix`と`prettier --write`が走り、整形してくれます。
テストなども走らせたい場合には、
`.husky/pre-commit`にスクリプトを追加することで様々な処理を行うことが出来ます。

# 参考

https://typicode.github.io/husky/#/

https://github.com/okonet/lint-staged
Jetpack のL4TのNFSサーバーはNFSv3までしか対応していない

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

# 0. はじめに

JetsonでNFSサーバーを立てようと思いました。
普通にNFSサーバーを立てられました。

「問題なし」と思ったのですが、NFSv3で接続していました。
21世紀にNFSv3もないもんだろうとNFSv4オプションを付けても動きません...。

```
mount.nfs4: No such device
```

としか返ってこなくて、絶望した話です。

JetPackバージョン:4.6
JetsonのL4Tのバージョンは以下の通りです。

```
$ uname -a
Linux jetson1 4.9.253-tegra #1 SMP PREEMPT Mon Jul 26 12:19:28 PDT 2021 aarch64 aarch64 aarch64 GNU/Linux
```

# 1. 結論

NFSv4のKernelモジュールが入っていないので無理

散々調べて、いろいろ試してたどり着いたのがここ。

NFSv4 on jetpack 4.4 - Jetson & Embedded Systems / Jetson Xavier NX - NVIDIA Developer Forums
https://forums.developer.nvidia.com/t/nfsv4-on-jetpack-4-4/126896

NFSv4は対応していないカーネルリコンパイルが必要

# 2. 確認

ビルドインモジュールは、`cat /lib/modules/$(uname -r)/modules.builtin | grep nfs`で確認できたはず。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/306dc185-a2b5-11a3-9009-325fe8c17ece.png)
なし..。

Kernelモジュールにあれば...。

```
$ ls -la  /lib/modules/$(uname -r)/kernel/fs/nfsd
total 220
drwxr-xr-x 2 root root   4096  8月 19 09:33 .
drwxr-xr-x 8 root root   4096  8月 19 09:33 ..
-rw-r--r-- 1 root root 213736  7月 27 04:36 nfsd.ko
```

なし。

Ubuntu 20.04 LTSでは、`nfs-kernel-server`をインストールすれば以下のように出ますが...

```
$ sudo cat /proc/fs/nfsd/versions
-2 +3 +4 +4.1 +4.2
```

Jetsonでは、

```
$ sudo cat /proc/fs/nfsd/versions
-2 +3
```

残念...。

# 3. まとめ

Kernelのリコンパイルなんて、もう20年以上やってないのでNFSv3で我慢します。。
Firebaseとフロントエンドのみで作ったオンラインゲーム『バトルアクターズオンライン』をリリース

# どんなゲーム？
RPGの戦闘部分のみ切り出したようなオンライン対戦ゲームです
（会員登録不要・完全無料）
2～4人までのオンライン対戦とオフラインで遊ぶことも出来ます
また、チャット機能やコマンド入力までの時間制限も付けました

![Videotogif (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911989/fe0f6ea9-3769-b787-d868-e41a532c665a.gif)

https://battle-actors-online.web.app

# 技術スタック
- 言語
typescript

- フレームワーク
vue.js

- データベース
Firebase RealtimeDatabase

- ホスティング
Firebase

- バックエンド
無し（サーバレスと呼ばれる Google Apps Script や AWS Lambda も使用していません）

# なぜ作ったのか
- サクッとオンラインゲーム遊びたい・対戦したい　ということがありますが
会員登録が不要のゲームが無く、長い会員登録のあと長いチュートリアルをやって
ようやくゲームが出来るというモノばかりだと思った
-  最近のゲームは課金ドリブンで、金で殴るゲームばかりだなと思い
プレイヤースキルが試されるゲームを作りたかったから
-  RealtimeDatabaseでゲームが作れる！みたいなのをよく目にしたもんですが、実際出来るのかどうかと言うのを試してみたかった
（下記記事の応用って感じですが）

https://qiita.com/HawkClaws/items/08fd697954cda1cde855

# 開発時に注意したこと
一番気を使ったところが、

- オンラインゲームのなのでホスト・クライアント同士で齟齬が発生しないか
- 無料枠に収めるためになるべくRealtimeDatabaseの通信量を抑える
- アニメーションで画像表示時に遅延しないようにプリロードをする
というところです

ダメージ計算も全てフロントエンドで行っていますが
ホストで計算を行い、各クライアントに返すようにしています（これが基本だとは思いますが）
また、通信量を抑えるために、メッセージの送信は行わずEnumで定義したKeyをクライアントに送信し、クライアント側でEnumからメッセージを作り直して表示するようにしました
アニメーションの遅延の件ですが、はじめはアニメーション実行時にサーバに画像取得するようにしていました
しかし、１回目のアニメーション表示時に飛び飛びになってしまってアニメーションと呼べるものではありませんでした
そこで、プリロードを行うことによって、キャッシュから画像を取得され、遅延なくアニメーションが表示出来るようになりました

# リリース後に分かったこと
「開発時に注意したこと」のときに「RealtimeDatabaseの通信量を抑える」ということを注意して開発し、RealtimeDatabaseの通信量に関しては問題ありませんでした
しかし・・・Hostingの方の通信量がヤバかったです・・・
キャラグラフィック・アニメーション・サウンドエフェクト等のアセットを使用しており
１つ１つは100kbもいかないくらいなのですが、プレイヤーが増えるたびに読み込まれて大変でした
リリース直後150人程度にプレイしてもらって600MBの読み取りくらいだったと思います
これに関しては、一番容量の食っていたキャラグラフィックを縮小したり圧縮したりで一応改善しました


# 課題
課題としてはRealtimeDatabaseにゴミデータが残ってしまうことがあるということです
プレイヤー参加時にDBに追加、退出時にDBから削除というような処理があるのですが
ブラウザバックではなく、ブラウザを強制終了した場合退出の処理が走らないのでゴミデータが残ってしまいます
バックエンドが無いので、ここらへんの処理がどうすることも出来ず・・・。ということがあります
GASを使って定期的にお掃除するのが一番いいのかなとは考えています


# 最後に
オンラインゲームはプレイヤーが居てなんぼのものなので
良かったら遊んでやったください

https://battle-actors-online.web.app
Rancher in Docker バージョンアップスクリプト v2

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

# 0. はじめに

昔、以下の投稿をしてDockerで動かしたRancherをアップグレードするスクリプトを書いたのですが、
Rancher 2.6へバージョンアップするにあたりスクリプトを改修したので再度投稿です。
バージョン2とします。

Rancher 2.0 バージョンアップ - Qiita
https://qiita.com/ynott/items/2a631e907fa1850210fb

以下のページを参考にしました。

Rancher Docs: Upgrading Rancher Installed with Docker
https://rancher.com/docs/rancher/v2.6/en/installation/other-installation-methods/single-node-docker/single-node-upgrades/

# 1. シェルスクリプト

修正点は、以下の通りです。

1. 既存RancherコンテナのIDを自動取得に変更
1. 新しいバージョンのRancherバージョンを自動チェック

`UPCOMING_VERSION`のみ指定してください。

```bash:upgrade-rancher-v2.sh
#!/bin/bash -xe

export RANCHER_CONTAINER_ID=''
export UPCOMING_VERSION=v2.6.0
export LATEST_VERSION=$(curl -s https://registry.hub.docker.com/v1/repositories/rancher/rancher/tags | jq -r '.[].name' | sort -h | grep -v "-" | tail -1)

# UPCOMING_VERSIONの修正し直し漏れをチェック
if [ "${UPCOMING_VERSION}" == "${LATEST_VERSION}" ]
then
   :
else
   echo "$UPCOMING_VERSION is not match $LATEST_VERSION"
   exit
fi

# 既存RancherコンテナのIDとインストールされているバージョンを取得
RANCHER_CONTAINER_ID=$(sudo docker ps -a --filter name=rancher --format "{{.ID}}")
RANCHER_CURRENT_VERSION_TAG=$(sudo docker ps -a --filter name=rancher --format "{{ .Image }}" | sed -ne 's/rancher\/rancher:\(v.*\)/\1/p')
docker stop $RANCHER_CONTAINER_ID

echo "RANCHER_CURRENT_VERSION_TAG is: $RANCHER_CURRENT_VERSION_TAG"
echo "RANCHER_CONTAINER_ID is: $RANCHER_CONTAINER_ID"

# 既存コンテナからバックアップボリュームコンテナを作成
docker create --volumes-from $RANCHER_CONTAINER_ID \
--name rancher-data rancher/rancher:$RANCHER_CURRENT_VERSION_TAG

# ボリュームコンテナからtarファイルを作成
docker run  --volumes-from rancher-data -v $PWD:/backup \
alpine tar zcvf /backup/rancher-data-backup-$RANCHER_CURRENT_VERSION_TAG.tar.gz /var/lib/rancher

docker pull rancher/rancher:$UPCOMING_VERSION

# ボリュームコンテナを参照しつつ新しいRancherを起動
docker run -d --volumes-from rancher-data \
  --restart=unless-stopped \
  -p 80:80 -p 443:443 \
  -v /host/rancher:/var/lib/rancher \
  -v /var/log/rancher/auditlog:/var/log/auditlog \
  -e AUDIT_LEVEL=1 \
  --privileged \
  rancher/rancher:$UPCOMING_VERSION
```

# 2. まとめ

Rancher 2.6は画面が変わりすぎててビックリしました。
Pythonを使ってYoutubeから字幕を抽出する。


Youtubeを見ていると自動生成される字幕がでてくると思います。
今回はそれをテキスト化し抜き出してみます。

2021/09/06 さきほど動作確認したところ、エラーが出て動かなくなっていました。。
調べたところYouTube側のAPIの変更などが原因の用です。pytubeがissueを出していたのでバージョンを上げれば動作するかも。。
https://stackoverflow.com/questions/68680322/pytube-urllib-error-httperror-http-error-410-gone
これでうまくいくのかな？

#LanguageReactorつかえば？
GoogleChromeのLanguageReactorというプラグインを使うと同じようなことが搭載されています。
字幕の開始時間はとれるんですが今回は終了時刻が欲しかったので別途Pythonで実装しました。

#実装
```Python
import os
from pytube import YouTube


#字幕出力
def outContext(url):
    #動画のクラス取得
    yt = YouTube(url)
    # 動画の字幕の言語一覧
    print(yt.captions.get_by_language_code)
    # 指定した言語の字幕取得
    caption = yt.captions.get_by_language_code('a.ja')
    # srt形式で取得
    contexts = caption.generate_srt_captions()  
    # ファイルに出力
    f = open('../字幕テキスト/' + yt.video_id + '_字幕.srt', 'w')
    f.write(contexts)
    f.close()

common_url = "https://www.youtube.com/watch?v=sFPqmy1rOmA"
outContext(url)
```


#出力結果
出力を試したものはひろゆきの動画です。
https://www.youtube.com/watch?v=sFPqmy1rOmA

```
1
00:00:02,500 --> 00:00:05,200
いっ

2
00:00:03,820 --> 00:00:06,640
にっ

3
00:00:05,200 --> 00:00:10,210
村

4
00:00:06,640 --> 00:00:15,340
45敗えっ

5
00:00:10,210 --> 00:00:17,470
8知らせを取れちゃったんですけどあのいつもながらラグが8秒ぐらいあるんですけど

6
00:00:15,340 --> 00:00:23,400
あの今日はな具があの

7
00:00:17,470 --> 00:00:28,320
だから2秒事から柴田はちょっとあの自分のことだから勝手にびっくりしました

8
00:00:23,400 --> 00:00:32,099
えっとですねあの中いつもこう予約して時間が今日5:55いう役だったんですけど

9
00:00:28,320 --> 00:00:38,910
ちょっとあの予約時間前に初めて見たですよね
【React】React AppをGitHub Pagesでデプロイする(2021年9月)

# はじめに
Reactで作成したWebアプリをGitHub Pagesでデプロイする際に結構躓いたので，こうすると出来たよという現時点での情報を備忘録として残す。

# 環境
* Windows

# 完成品
https://fk-ln.github.io/react-test/
とりあえずデプロイの手順だけを示すので，使うリポジトリは`npx create-react-app`で作成したデフォルトのサンプル。

# 手順
1. GitHubでリポジトリを作成してmain(master)リポジトリにpush
1. ローカルリポジトリで`npm install gh-pages --save-dev`
1. `package.json`を開いて以下を追記(`/`と`/Scripts/`の二か所)

```
{ 
  ~省略~

  "homepage": "https://fk-ln.github.io/tdu-new-school/",
　※GitHubの`Settings`→`Pages`に表示されるURLをコピペ

  ~省略~

 "Scripts": {

    ~省略~

    deploy": "npm run build && gh-pages -d build",
  }

  ~省略~
}
```

1. `npm run build`を実行
1. GitHubの`Settings`→`Pages`でBranchを`gh-pages`，フォルダを`/(root)`に設定

これで先ほど設定した(package.jsonに書いた)URLにアクセスするとアプリが使えるはず。(反映に数分かかるかも)

# gh-pages
`gh-pages`というnpmパッケージではソースコードをコンパイルして`build`フォルダを作成し，それを`gh-pages`ブランチにpushしてくれる。

# 躓いた点
1. `package.json`に`"homepage": `を書いていなかった
　→どうやらデプロイ先のURLは明示的に示す必要があるっぽい
1. 操作にWindows Powershellを使っていた
　→npm run buildではGitHubにpushする作業が行われるのでgit bashなどのgitコマンドを使える環境で行う。
210911_Pythonプログラミング教室

## 演習問題①の解答

```
# 全ての果物の金額を変数に代入する
apple = 100
orange = 120

# 「税抜き価格は〇〇円になります」と出力する
non_taxed_price = apple * 2 + orange
print('税抜き価格は' + str(non_taxed_price) + '円になります')

# 「税込価格は〇〇円になります」と出力する
tax_included_price = int(non_taxed_price * 1.1)
print('税込み価格は' + str(tax_included_price) + '円になります')
```

## 演習問題②の解答
```
test_scores =[50, 65, 45, 75, 70]

# 解答1) 国語の点数（50点→80点）に書き換えてください
test_scores[0] = 80

# 解答2) 体育の点数（90点）を加えて出力してください
test_scores.append(90)
print(test_scores)

# 解答3) 「最低スコアは◯点、最高スコアは◯点です。」と出力してください
print("最低スコアは" + str(test_scores[2]) + "点、最高スコアは" + str(test_scores[-1]) + "点です。")
```

## 演習問題③の解答
```
test_scores_d ={'国語':50,'算数':65,'理科':45,'社会':75,'英語':70}

# 解答1) 国語の点数（50点→80点）に書き換えてください
test_scores_d['国語'] = 80

# 解答2) 体育の点数（90点）を加えて出力してください
test_scores_d['体育'] = 90
print(test_scores_d)

# 解答3) 「最低スコアは◯点、最高スコアは◯点です。」と出力してください
print("最低スコアは" + str(test_scores_d['理科']) + "点、最高スコアは" + str(test_scores_d['体育']) + "点です。")
```
LaravelでonDelete('cascade')を書けば勝手にリレーション先の子供が削除されるわけではない

今回発見があったので備忘録。
usersテーブルに紐づくpostsテーブルがあったとして、マイグレーションファイルには

```php
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
```
こう書けば、勝手に削除されると思ってました。。。
この場合で削除されるのは、親（User）を物理削除した場合のみ。
論理削除だと、削除されないようなのです。

自動で削除してくれるのは、物理削除によって親が完全にDB上から消えた場合であって
論理削除のようにまだデータが残っている場合、DBは親が削除されたとはみなさないようです。

## 参考
https://teratail.com/questions/273050
【Git】コマンド辞典　~ブランチとマージの仕組み~

##ブランチとマージ
###【前置き】Gitのデータの持ち方
Gitでは、変更差分ではなくスナップショットでデータを管理する。
リポジトリの中で、の3つのファイルでデータを保管している。
・圧縮ファイル…ファイルの中身を圧縮したもの。（git addにより作成される）
・ツリーファイル…git addした時のスナップショットを記録する。ファイルの中身と、圧縮ファイル名をマッピングする。
・コミットファイル…ツリーファイル、作成者、日付、コミットメッセージ、親コミットが記録される。

ツリーファイルでスナップショットを記録し、コミットファイルでツリーファイルを指定していることで、コミットはスナップショットを記録していることになる。

**まとめると…**
Gitでは`コミットでスナップショットを記録`して、コミットの`parent（親コミット情報）でコミットを時系列順に辿れる`ようにしている。

###ブランチとは
並行して複数機能の開発をするための仕組み。
ブランチを使って分岐して開発をすることで、他のメンバーの行なった変更が、自分の開発には影響を与えないで済む。

###ブランチの仕組み
* ブランチ：コミットファイルを指し示すポインタ（コミットIDを記録したポインタ）
* HEAD：現在自分が作業しているブランチを指し示すポインタ
* masterブランチ：Gitのデフォルトのブランチ名

コミットを行うと、ブランチが指し示すコミットファイルが最新のコミットファイルに変わる。

###branch　（ブランチを確認・新規追加・変更・削除する）

```
//今あるブランチの一覧を表示する
$ git branch

//リモートリポジトリも含め、今あるブランチの一覧を表示する
$ git branch -a

//ブランチを新規追加する（ブランチの切り替えは行わない）
$ git branch ブランチ名

//今いるブランチを変更する
$ git branch -m ブランチ名

//ブランチを削除する（masterにマージされていない変更が残っている場合は削除しない）
$ git branch -d ブランチ名

//ブランチを強制削除する
$ git branch -D　ブランチ名
```


###checkout　（ブランチを切り替える）

```
//既存のブランチへ切り替える
$ git checkout 既存のブランチ名

//ブランチを新規作成して切り替える
$ git checkout -b 新ブランチ名
```

###merge　（変更を統合する）
他の人の変更内容を、自分のブランチに取り込む。

```
$ git merge ブランチ名　（ローカルブランチの場合）
$ git merge　　リモート名/ブランチ名　（リモートブランチを参照する場合）

例
$ git merge origin/master
//リモートリポジトリ「origin」のmasuterブランチの内容を、自分の作業中のブランチに統合する
```

**mergeには3種類ある**
・Fast foward：早送りになるマージ
ブランチが枝分かれしていなかったときは、ブランチのポインタを前に進めるだけ。

・Auto Merge：基本的なマージ
ブランチが枝分かれしているときは、作業中のブランチをベースに、mergeしたブランチの変更分を取り込んだ内容をスナップショットとして、マージコミットという新しいコミットが作成される。（parentを2つ持つことになる）

・Conflict
同じファイルの同じ行に対して、複数人が異なる編集をおこなった場合。

###コンフリクトを解決する
コンフリクトが発生したファイルのコンフリクト箇所には、以下のように表示される。

```
<<<<<<< HEAD　（現在の変更）
あいうえお
=======
かきくけこ
>>>>>>> feature　（入力側の変更）


//HEAD：現在の自分の作業ブランチの内容
//feature：mergeしてきたブランチの内容
```

**コンフリクト解消手順**

* 最終的に残したい内容へ、ファイルの内容を書き換える。
* << == >>の記述を削除する。


**コンフリクトを起こさないために**

* 複数人で同じファイルを変更しない
* pullやmergeする前に、変更中の状態をなくしておく。（commitやstashをした上でpullやmergeを行う）
* pullする際は、pullするブランチに移動してからpullを実行する。

###ブランチの利用方法の基本
masterブランチでは開発せず、リリース専用のブランチとする。
開発はトピックブランチを作成して進める。
→こうすることで、masterブランチを常に最新の状態に、リリースしている状態と同じに保つことができる。



<br><br>
##参考教材
https://www.udemy.com/course/unscared_git/
文系大学生がTech.uni(プログラミングサークル)に入って成長した話

9月４日に開催されたTech.uni主催のハッカソンに参加させてもらいました。この記事ではハッカソンのチーム開発における、私自身の話をさせてもらいます。

Twitter　https://twitter.com/yoshikigram
Github　https://github.com/Tech-Uni-Summer-Hackathon2021/team-d

![Tech.Uni SummerHack](https://user-images.githubusercontent.com/63713624/126744501-639e7f32-0ed9-48ff-91e1-2fdee17d7830.jpg)

![背景](https://user-images.githubusercontent.com/75286616/132077555-71d3a008-bd66-43a7-9bbe-76026d08c04a.png)



##1.最初に

　私は文系の大学に通う２回生で、プログラミングに触れるまでは簿記と英語を中心に勉強している平凡な大学生でした。プログラミングを本格的に始めたのが今年の４月でした。これまでにSwiftでtoDoリストを作ったり、先輩とRailsを使ってwebアプリを作ったりしたことがありましたが、自分が主体となって本格的な開発をしたことはありませんでした。

##2.チームリーダになって

　このハッカソンではチームに分かれて開発をするというイベントでした。私はチームDのリーダに選ばれました。そのため責任感が強く私を成長させる要因の一つになりました。人に教えるほどプログラミングができない、人にタスクを振るのが苦手、Githubの使い方がわからないと言う状態で１ヶ月間リーダとして開発しました。リーダの自分ができなければならないと言う責任感が自分を成長させてくれました。

##3.開発を終えて

　今回Flutterを使って、スマホアプリを作ろうとチーム内で決まりました。もちろん私はFlutterを使ったことがなく、かなり苦戦しました。また環境構築に手間取ったり、予定を入れすぎていたことから、開発を始めれたのが、8月１５日ぐらいでした。そのため、時間もなく、人一倍に努力しなければならないと感じました。私は追われすぎて、電車の移動時間ですら、開発をするという生活を3週間続けました。もちろん予定のない日は一日開発をしていました。そのような生活をすることで、結果的に「しゅわしゅわ」と言うアプリを作り上げることができました。このアプリを開発する過程でチームメンバーの助けが重要になったと感じました。メンタルケアだけでなく、技術の共有やUIデザインの相談、アイコンの作成や、まるまる一つの機能を任せたりと、本当に助けられた開発でした。

##4.使用技術や技術面で困ったこと

・フロントエンドにFlutterとRuby
・バックエンドにFirebase

　私はFlutterを使いこなすまでに時間がかかり、最初の１週間はほとんど何もできず、本当に焦りました。残りに2週間でようやく、基礎的な使い方がわかり、Firebaseをうまく使い、ユーザー情報の管理、匿名ログイン、質問の投稿と回答、いいね機能、保存機能を実装することができました。ベストアンサー機能を実装できなかったことをすごく悔やんでいます。「しゅわしゅわ」と言うアプリは関学生向けの質問解決プラットフォームで某知恵袋の関学生専用アプリです。これから新機能をつけて、関学生が今より楽しく、充実した生活を送れるように、私は開発していこうと思っています。「しゅわしゅわ」は９月中にリリースする予定です！

##5.これからの自分

これから私は「しゅわしゅわ」と言うアプリをApp storeで配信して、多くの関学生がこのアプリを使ってもらうことを目標にUIの改善や新機能の追加をし、また多くの人に「しゅわしゅわ」を知ってもらうために、宣伝活動をしていこうと思っています！また今年はプログラミングだけに打ち込むために常に開発し、多くのエンジニアさんと交流して、優秀なエンジニアになれるように日々精進していこうと思います！「しゅわしゅわ」をリリースしたら、別の記事を書かせてもらいます！