OmniAICreator/Qiita-1.07M huggingface dataset:
いまさらだけど#fileとかについて（Swift）

![Xcode-14.1](https://img.shields.io/badge/Xcode-14.1-brightgreen) ![Swift-5.7.1](https://img.shields.io/badge/Swift-5.7.1-brightgreen) 

## はじめに
https://qiita.com/uhooi/items/e5ee95c86f8d6734c6a7

こちらの記事を参考に下記のようなテストを書いているときにふと `#line` みたいなやつって `#file` とかあった気がするけど他にもなんかあったけ？と気になりました:thinking:

```swift
func testHogeWithFlagMethod() {
    let testCases: [(line: UInt, flag: Bool, expect: Int)] = [
        (#line, true, 0),
        (#line, false, 1)
    ]
    testCases.forEach {
        XCTAssertEqual(hoge(flag: $0.flag), $0.expect, line: $0.line)
    }
}
```

ということで `#file` とかのまとめです。

## 一覧
下記があるみたいです。

| Literal | Type | Value |
| --- | --- | --- |
| #file | String | ファイルパス |
| #fileID | String | ファイル名とモジュール名 |
| #filePath | String | ファイルパス |
| #line | Int | 行番号 |
| #column | Int | 列番号 |
| #function | String | 関数名 |
| #dsohandle | UnsafeRawPointer | The dynamic shared object (DSO) handle in use where it appears. （原文ママ）|

参考：[Swift - Language Reference - Expressions](https://docs.swift.org/swift-book/ReferenceManual/Expressions.html#ID390)

`#dsohandle` に関してはよくわかりませんでした:see_no_evil:

デスクトップに Hoge というプロジェクトを作成し下記を実行すると

<img width="400" alt="print1" src="https://user-images.githubusercontent.com/34936885/208229337-aca0cee3-0a91-4c89-8961-3e3580df97d9.png">

こうなりました。

```
file: /Users/am10/Desktop/Hoge/Hoge/ViewController.swift
fileID: Hoge/ViewController.swift
filePath: /Users/am10/Desktop/Hoge/Hoge/ViewController.swift
line: 17
column: 26
function: viewDidLoad()
```

`#file` は現状は `#filePath` と同じ動作で将来的には `#fileID` と同じ動作になる模様。

## 使い方
下記のようにデフォルト引数を設定すると呼び出し元の値が取得できます。

```swift
func logFunctionName(string: String = #function) {
    print(string)
}
func myFunction() {
    logFunctionName() // Prints "myFunction()".
}
```

参考：[Swift - Language Reference - Expressions](https://docs.swift.org/swift-book/ReferenceManual/Expressions.html#ID390)

下記のようなメソッドを作ります（今回は PrintLog.swift というファイルを作ってそこに書きました）。

```swift
func printLog(filePath: String = #filePath,
              line: Int = #line,
              column: Int = #column,
              functionName: String = #function) {
    print("filePath: \(filePath)", "line: \(line)", "column: \(column)", "function: \(functionName)", separator: "\n")
}
```

こんな感じで呼び出すと

<img width="400" alt="print2" src="https://user-images.githubusercontent.com/34936885/208229349-47e79179-ede4-40ff-9fcc-feb983f1e9b6.png">

こうなります。

```
filePath: /Users/am10/Desktop/Hoge/Hoge/ViewController.swift
line: 13
column: 17
function: piyo
piyo
filePath: /Users/am10/Desktop/Hoge/Hoge/ViewController.swift
line: 19
column: 17
function: fuga()
```

## おわりに
たまにしか使わないですがログ表示とかで使うと便利です:thumbsup:
Blenderでフィギュア作成忘備録

# はじめに
Blenderのスカルプトを使って押しのフィギュアを作りたい‼
そう思ったのに、Blenderのスカルプトチュートリアル動画とかは、主にゲームや動画用のモデリングについてばかりでした。
ゲームや動画用のモデリングでは、最終的にローポリのモデルに変換してしまうため、そのままでは3Dプリンタでの出力には使えません
なので、Blenderでフィギュアを作る際の流れや必要になりそうなものを忘備録としてまとめてみました。

# スカルプトを使った3Dモデリングの流れ
## ゲーム・動画用モデル
* スカルプト
    * 粘土こねる、ここは3Dプリント用モデルと共通
* リトポロジー
    * モデルのポリゴンを整えること
    * ゲーム・動画用モデルはこの段階でローポリ化もする
* UV展開
    * モデルのポリゴンを平面に展開すること
    * ちなみにUVは何かの略ではなく展開した2次元平面の座標系(U軸、V軸)のことらしい
        * 3DモデルのXYZ軸と名称が被らないようにしているらしい
    * BlenderにはUV展開方法がいろいろあるらしい
* ノーマルベイク
    * スカルプトで作った細かい凹凸の情報をノーマルマップとしてUVマップに焼き付ける
        * ノーマルマップについては[こちら](https://styly.cc/ja/tips/maku-blender-normalmap-bake/)を参照
        * ノーマルマップのノーマルは法線のことっぽい？
* マテリアル、テクスチャの編集
    * 色を付けたりする作業
    * 金属っぽい質感とかも設定できる

## 3Dプリント用モデル
* スカルプト
    * ゲーム・動画用モデルと同様
* リトポロジー(リメッシュ)
    * ゲーム動画用程ローポリにはしないがやはり必要らしい
    * 3Dモデリング関連の記事とかではリメッシュということが多そう
    * BlenderではQuad Remesher使うとよいらしい
* 3Dプリント処理
    * スライサに出力してサポートつけたりとかいろいろ
    * Blenderには3Dプリント用のアドオンとかあるらしい

# 参考
* https://note.com/histone/n/n875e3cdd0d46
【Deno Deploy Pro】ワイルドカードサブドメインを使う【Wildcard subdomains】

好きな文字を入れて試してみてください
https://好きな文字💩.github.day

ワイルドカードサブドメインで好きなサブドメインを作れます

```typescript:main.ts
import { serve } from "https://deno.land/std@0.155.0/http/server.ts";
import punycode from "https://deno.land/x/punycode/punycode.js";

serve((req: Request) => new Response('Hello ' + punycode.toUnicode(req.url.split(/\/|\./g)[2])))
```

設定ページから`*.example.com`のようにドメインを設定できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/52d54fca-e09d-6b2d-5716-b09c0622a05e.png)

Googleドメインなら以下のように設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/d29d4734-9230-c71c-1397-063fa04a95d1.png)
おすすめテック系PodCast【2022年末版】

![cover.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/312a2102-98cb-953f-ea6f-287db2830fd0.png)
# TLDR
- 全体的には[昨年](https://docs.google.com/spreadsheets/d/1MeFDu_8M1nxjzLH0RbDwsO5qWPeO7ZJQry45YcvVsaw/edit#gid=0)からは大きな変化はありませんでした
    - 2021年 34番組
    - 2022年 33番組(10減**9増**)
- 今年から聴き始めたテック系**以外**のポッドキャスト(終了も合わせて計11番組)、とてもよかったです

# おすすめテック系ポッドキャスト一覧
【元データ】

https://docs.google.com/spreadsheets/d/1T9K1qNvdvk9lKwWg_omGC5L6-rasM0T9KUYv0FBjrq0/edit?usp=sharing

![無題1_20221218053100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/4917ccf2-ce71-dacf-1851-0e64afef0368.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/8b4e084f-118e-f33b-cd58-95a64e825976.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/a5e0132f-e126-cc7b-0718-27395ffaa697.png)


# 2022年個人的ポッドキャスト2大ニュース

## 1. 「mozaic.fmの新企画がすごい！」
今年の夏に100回を迎えたmozaic.fm。これまで本番組ではブラウザや通信規格など Webの土台とも言える技術の最新動向を毎月長時間深堀りしてきましたが、新たにReactやNext.jsなどのwebフレームワークの最新動向を毎月長時間に渡って深堀りしていくという企画が始まりました。
**webフレームワーク**に対してピンポイントで情報紹介をしている番組は多いですが、ここまで**膨大な情報を定期的に提供**してくれる企画は他にないため、今一番おすすめの企画です。
ただ、注意事項としては紹介するフレームワークは紹介する人が普段使うツールに多少寄ってしまうため、全てのフレームワークを網羅しているわけではないではないという点は注意です(RailsやLaravelなどは基本紹介されません)

## 2. 「テック系以外のポッドキャストもすごい！」
podcastを聴き始めた2021年はテック系のポッドキャストばかりを聴いていましたが、今年に入ってからテック系以外のポッドキャストを聴いたところ非常に面白くエンジニアに取って有益なものを多数あり、こちらもお勧めしたいと思います

（元データ：[シート「非テック系」に記載](https://docs.google.com/spreadsheets/d/1T9K1qNvdvk9lKwWg_omGC5L6-rasM0T9KUYv0FBjrq0/edit?usp=sharing)）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/238ff987-c16b-72f7-10ef-291f93fc944c.png)



(※1) アイキャッチ画像はStable Diffusionで生成しました
NICのオフロード機能を確認する


# 0. 概要
NICのオフロード機能のステータスを取得及び有効化することを目的とした、ethtoolの使い方を紹介します。

# 1. 文法
## 1.1 ステータスの確認
```
# ethtool --show-offload <インターフェース名>
# ethtool -k <インターフェース名>
```
## 1.2 オフロード機能の有効化
```
# ethtool -K <インターフェース名> <オフロード機能名> on
```
# 2. 実施例
## 2.1 ステータスの確認
オフロード機能を確認。
```
# ethtool --show-offload enp3
Features for enp3:
rx-checksumming: on
tx-checksumming: on
	tx-checksum-ipv4: off [fixed]
	tx-checksum-ip-generic: on
	tx-checksum-ipv6: off [fixed]
	tx-checksum-fcoe-crc: on [fixed]
	tx-checksum-sctp: on
scatter-gather: on
	tx-scatter-gather: on
	tx-scatter-gather-fraglist: off [fixed]
tcp-segmentation-offload: on
	tx-tcp-segmentation: on
	tx-tcp-ecn-segmentation: off [fixed]
	tx-tcp-mangleid-segmentation: off
	tx-tcp6-segmentation: on
udp-fragmentation-offload: off
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off
rx-vlan-offload: on
tx-vlan-offload: on
ntuple-filters: off
receive-hashing: on
highdma: on [fixed]
rx-vlan-filter: on
vlan-challenged: off [fixed]
tx-lockless: off [fixed]
netns-local: off [fixed]
tx-gso-robust: off [fixed]
tx-fcoe-segmentation: on [fixed]
tx-gre-segmentation: on
tx-gre-csum-segmentation: on
tx-ipxip4-segmentation: on
tx-ipxip6-segmentation: on
tx-udp_tnl-segmentation: on
tx-udp_tnl-csum-segmentation: on
tx-gso-partial: on
tx-sctp-segmentation: off [fixed]
tx-esp-segmentation: off [fixed]
fcoe-mtu: off [fixed]
tx-nocache-copy: off
loopback: off [fixed]
rx-fcs: off [fixed]
rx-all: off
tx-vlan-stag-hw-insert: off [fixed]
rx-vlan-stag-hw-parse: off [fixed]
rx-vlan-stag-filter: off [fixed]
l2-fwd-offload: off
hw-tc-offload: off
esp-hw-offload: off [fixed]
esp-tx-csum-hw-offload: off [fixed]
rx-udp_tunnel-port-offload: on
```
## 2.2 オフロードの有効化
デフォルト設定の確認。今回はrx-allを有効化する。
```
# ethtool -k enp3
・・・
rx-all: off
・・・
```
rx-allを有効化。
```
# ethtool -K enp3 rx-all on
```
有効化されたかを確認。
```
# ethtool -k enp3
・・・
rx-all: on
・・・
```
ケバブケース とは？

## 勉強前イメージ

ケバブってあのケバブ？

## 調査

### ケバブケース とは

命名規則の一つで、複数の単語を繋げる場合にハイフンを入れるものです。
例えば `make-instance` とか `create-timer` みたいなイメージです。

## 似たようなのは他にもある

他にも、キャメルケースやすケークケースというのもあります。

- キャメルケース

先頭の単語を大文字にする命名規則の方法で、キャメルケースの中でも以下2つ種類があります。
アッパーキャメルケース : すべての単語の先頭を大文字にする (例) `MakeInstance` , `CreateTimer`
ローワーキャメルケース : 先頭の単語だけ小文字にする (例) `makeInstance` , `createTimer`


- スネークケース

単語の間をアンダーバーでつなぐ命名規則です。
例えば、 `make_instance` , `create_timer` などになります。

### まとめると

- ケバブケース : ハイフンでつなげる
- キャメルケース
	- アッパーキャメルケース : すべての単語の先頭を大文字
	- ローワーキャメルケース : 先頭の単語だけ小文字
- スネークケース : アンダーバーでつなげる

## 勉強後イメージ

キャメルケースとスネークケースは知ってたけどケバブケースは最近聞いた

## 参考

- [【命名規則】「キャメルケース」「スネークケース」「ケバブケース」とは？](https://codeclub965.com/?p=2215)
- [ケバブケース](https://www.itnavi.jp/words/%E3%82%B1%E3%83%90%E3%83%96%E3%82%B1%E3%83%BC%E3%82%B9-2/#)
ActiveRecordのjoinsメソッドはシンボルの引数と文字列の引数で挙動が異なる

先日微妙にハマってしまったRailsの小ネタです。

ActiveRecordは次のように`joins`メソッドを使って別のモデル（テーブル）をJOINすることができます。

```ruby 
Task.joins(:project)
```

また、`includes`メソッドなどはシンボルを渡しても文字列を渡しても同じ挙動になります。

```ruby 
# includesメソッドはシンボルでも文字列でも挙動は同じ
Task.includes(:project)
Task.includes('project')
```

これと同じように`joins`も同じようにシンボルでも文字列でも渡せるよね？と思ったんですが、文字列だとエラーが出ました。

```ruby 
Task.joins('project')
#  Task Load (0.2ms)  SELECT "tasks".* FROM "tasks" project
# .../sqlite3/database.rb:152:in `initialize': SQLite3::SQLException: no such table: tasks (ActiveRecord::StatementInvalid)
# .../sqlite3/database.rb:152:in `initialize': no such table: tasks (SQLite3::SQLException)
```

## なぜエラーが出たのか？
`joins`メソッドにシンボルを渡すとそれは関連名として扱われます。
ですが、文字列を渡すと独自のJOIN用SQLとして扱われます

```ruby 
# 引用: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-joins 
User.joins("LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id")
# SELECT "users".* FROM "users" LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id
```

そのため、文字列の"project"を渡すと予期せず無効なSQLが発行され、エラーが起きるのです。

```ruby 
# joinsにシンボルを渡した場合（関連名として扱われる）
puts Task.joins(:project).to_sql
# SELECT "tasks".* FROM "tasks" INNER JOIN "projects" ON "projects"."id" = "tasks"."project_id"

# joinsに文字列を渡した場合（tasksテーブルにprojectという別名が予期せず付いてしまう）
puts Task.joins('project').to_sql
# SELECT "tasks".* FROM "tasks" project
```

https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-joins

うっかりミスと言えばうっかりミスなのですが、「シンボルを渡しても文字列を渡しても、内部的に型が統一されるのでどっちでもOK」というケースはRailsを使っているとよくあることなので、てっきり`joins`メソッドもそんなふうに動いてくれるもんだと勘違いしていました。

ふつうに`joins`メソッドを使うときはシンボルで関連名を指定すると思いますが、プログラム上で動的にJOINするテーブルを指定する場合に、予期せず文字列で関連名を渡したりすることがあるかもしれません。みなさんも気を付けてください。
画面のロックを抑止する

```bat:nolock.bat
@(echo '> NUL
echo off)
setlocal enableextensions
:: ref: https://www.inasoft.org/mousefr.html
set "HERE=%~f0"
set LINE[1]=     dBBBBb  dBBBBP dBP    dBBBBP dBBBP  dBP dBP
set LINE[2]=        dBP dBP.BP        dBP.BP        d8P.dBP
set LINE[3]=   dBP dBP dBP.BP dBP    dBP.BP dBP    dBBBBP
set LINE[4]=  dBP dBP dBP.BP dBP    dBP.BP dBP    dBP BB
set LINE[5]= dBP dBP dBBBBP dBBBBP dBBBBP dBBBBP dBP dBP
echo.
echo %LINE[1]%
echo %LINE[2]%
echo %LINE[3]%
echo %LINE[4]%
echo %LINE[5]%
echo.
powershell.exe -Command "iex -Command ((gc \"%HERE:`=``%\") -join \"`n\")"
exit /b %ERRORLEVEL%
') | sv -Name nolock

add-type -AssemblyName System.Windows.Forms

$signature=@'
    [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
    public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
'@

$SendMouseEvent = Add-Type -memberDefinition $signature -name "Win32MouseEventNew" -namespace Win32Functions -passThru

echo "Press Ctrl + C to terminate this process."

$MOUSEEVENTF_MOVE = 0x00000001

$SleepSec = 50

$MoveMouseDistance = 1
$MoveMouseDistanceX = 1

$Flag = $true

while ($true) {
    Start-Sleep $SleepSec
    
    $x = [System.Windows.Forms.Cursor]::Position.X
    $y = [System.Windows.Forms.Cursor]::Position.Y
    
    $SendMouseEvent::mouse_event($MOUSEEVENTF_MOVE, -$MoveMouseDistance, 0, 0, 0)
    $SendMouseEvent::mouse_event($MOUSEEVENTF_MOVE,  $MoveMouseDistance, 0, 0, 0)
    
    if ($Flag) {
        $x += $MoveMouseDistanceX
        $Flag = $false;
    } else {
        $x -= $MoveMouseDistanceX
        $Flag = $true
    }
    [System.Windows.Forms.Cursor]::Position = new-object System.Drawing.Point($x, $y)
    $x = [System.Windows.Forms.Cursor]::Position.X
}
```

実行結果は以下のとおりです。
![nolock.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29814/df4c495c-c096-e073-66bb-0474dbdc5718.png)
Unityエディタ起動時にgit config --local core.autocrlf xxxを実行

2021/12/17 : 初稿
Unity : 2021.3.15f1


ソースファイルインポート時に文字コードをUTF8に書き換える、
なんてエディタ拡張は皆さんよくされていると思うのですが、
改行コードはどうされてますか？

チーム内にWindows派とMac派が混在していると、
「差分のない.csファイルが大量にSourceTreeのステージングリストに出るんだけど！」
みたいな問題を起こすことがあります。

これを解決するための第一歩ということで、
ちゃんとgitの改行コード設定をしておきましょうという話。

# やりたいこと

Unityエディタ起動時に自動でシェルスクリプトまたはバッチファイルを呼び出し、
Windowsなら
`git config --local core.autocrlf true`
Macなら
`git config --local core.autocrlf input`
を実行する。

いや、SourceTreeならSourceTree上でやればいいんだけど、
プログラマーではない人たちにとってはハードル高かったり、
クローンしなおした時に設定し忘れたりするので。

# 実現手順

1. gitコマンドを呼び出す`.sh`や`.bat`ファイルを作成
1. Unityエディタからそれらを実行する処理を記述。
この時、処理が終わったら自動でコンソールウインドウ閉じるように。
1. Unityエディタ起動時にそれを呼び出す。

## gitコマンドを呼び出す`.sh`や`.bat`ファイルを作成
とりあえず下記のような感じで用意して、
`[プロジェクトフォルダ]/Utils`というフォルダを掘ってそこに配置。

```sh:Utils/setgitautocrlf.sh
#!/bin/bash
cd `dirname $0`
cd ..
git config --local core.autocrlf input
git config --local core.ignorecase false
```

```sh:Utils/setgitautocrlf.bat
cd %~dp0
cd ..
git config --local core.autocrlf true
git config --local core.ignorecase false
```

## Unityエディタ起動時にそれらを呼び出す。
下記のようなエディタ拡張をします。
`Assets/Editor`とかに配置。

```cs:Assets/Editor/TerminalExecuter.cs
///
/// @file   TerminalExecuter.cs
/// @author KYukimoto
/// @date   
///
/// @brief　エディタから.shや.batを実行する。
///         ついでにエディタ起動時に
///         git config --local core.autocrlf inputに設定するシェルスクリプトを呼び出す
///
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Diagnostics;

#if UNITY_EDITOR
public class TerminalExecuter
{
    // ターミナル実行
    public static void ExecTerminalApp(string relPath)
    {
        string dir = Path.GetDirectoryName(Application.dataPath);
        string sh = Path.Combine(dir, relPath);
#if UNITY_EDITOR_OSX
        ProcessStartInfo startInfo = new ProcessStartInfo("/bin/bash");
        startInfo.WorkingDirectory = dir;
        startInfo.UseShellExecute = false;
        startInfo.RedirectStandardInput = true;
        startInfo.RedirectStandardOutput = true;

        Process process = new Process();
        process.StartInfo = startInfo;
        process.Start();

        process.StandardInput.WriteLine(sh);
        //process.StandardInput.WriteLine("osascript -e 'tell application \"Terminal\" to close first window' & exit");  // if no exit then WaitForExit will lockup your program
        process.StandardInput.WriteLine("ps - ef | grep Terminal | grep - v grep | awk '{print $2}' | xargs kill");
        process.StandardInput.Flush();
#endif
#if UNITY_EDITOR_WIN
        Process.Start(sh);
#endif
    }

    [InitializeOnLoadMethod]
    static void SetGitAutoCRLF()
    {
#if UNITY_EDITOR_OSX
        TerminalExecuter.ExecTerminalApp("Utils/setgitautocrlf.sh");
#endif
#if UNITY_EDITOR_WIN
        TerminalExecuter.ExecTerminalApp("Utils/setgitautocrlf.bat");
#endif
    }
}
#endif
```

## 忘れちゃいけない前提

`git`コマンド自体がインストールされてないといけないので、
Windowsマシンの場合は<a href="https://gitforwindows.org/">`git for Windows`</a>をインストールしておきます。

Macの場合は、最初から入ってることが多い？
実行時に「デベロッパーツールをインストールしますか？」みたいなダイアログが出て
「はい」を選べばその場でインストールしてくれる？よく分からず。

SourceTree内蔵のGitとか呼び出す方法ないのかなあ。
Github上で管理しているリポジトリのprivateとpublicを変更する方法

# はじめに
githubで外部に公開したくないリポジトリがあったので、publicからprivateに変更（逆も然り）する方法を記録に残す

# Github上で管理しているリポジトリのprivateとpublicを変更する方法
- 変更したいリポジトリのsettingをクリック
- 画面最下層にある、「Danger Zone」の「Change repository visibility」欄の「Change visibility」をクリック
- 「Change private」 もしくは、「Change public」が出るのでそれをクリック。
- パスワードの入力を求められるので、入力すれば変更完了
【フロントエンド】E2Eテストに期待すること

## はじめに

E2E (エンドツーエンド) テストはユーザーに一番近いテストです。
単体テストより、コンポーネントテストより、VR（ビジュアルリグレッション）テストよりユーザーに近いです。

ここで出てくる疑問。
**どこまで書けばいいの？**

人間の行動をターゲットにするわけですから、色々なパターンが考えられる訳です。

特に、Webを使う人たちというのは僕たちみたいなパソコンオタクじゃないので、ITリテラシーが高くないことも多いです。

どのユーザーのどんな行動まで担保すればいいんでしょうか？

## 僕曰く

**ユーザーの6~7割ぐらいの人が通るメインの動きを担保する（大きな障害を出さない**ぐらいの気持ちで書くといいなと思います。

なぜこれぐらいの気持ちの方がいいかという話をいかにしていきます。

### 1. テストケースが増えれば増えるほどリリースが遅くなる

E2Eテストってすごく時間を食います。

小さな変更であったとしても、CIでE2Eテストは動きます。

ビルドやlintはキャッシュから復元してできる限り高速化していくことができます。
これは、結果が変わらないということがわかっているからいいですね。

でも、E2Eテストはユーザーにリリースする前の最終チェックです。スキップはできない。
毎回ヘッドレスブラウザを立ち上げ、一つ一つ実行されていくので時間がかかる。

しかもparallelに動かせないものも多くあります。
テストケースが増えれば増えるほど時間がかかっていきます。

### 2. 共通化がしづらく、テストケースが増えると保守が難しい

他のテストもそうだったりしますが、特にE2Eの世界では共通化がしづらいです。
めちゃくちゃプログラムを書くのがうまい人でもE2Eを書いてもらうと結構見づらいコードになったりします。

これはしょうがないことです。

現実世界のユーザー行動を共通化しようというのがそもそも間違えているのです。
テストケースを増やしすぎるとメンテナンスがかなりしんどいです。

### 3. どうせ2~3ヶ月後には変わる

これはアプリケーションの性質に寄ったりしますが、ユーザーに提供する画面の場合、細かいUIや機能レベルで言うと頻繁に変更がかかると思います。

細部まで書いているとその度に変更が必要になります。

## まとめ ~ できる限り網羅したいという人へ ~

単体テストやコンポーネントテストを書きましょう。
役割分担があります。

各機能が単体でちゃんと動くことができるのであれば、大きな障害には繋がらないと思います。

ユーザーのためを思うのであれば、ちゃんと単体テストを充実させ、インクリメントを早く提供していった方がいいかと思います。
リモートレポジトリからSagemakerへpullできない（管理コンソールで操作）

Qiita記事と[公式チュートリアル](https://docs.aws.amazon.com/ja_jp/sagemaker/latest/dg/nbi-git-resource.html)を参考にやったけど失敗。
CLIを使えない自分は管理コンソールで操作するしかなく
そもそもどこにpull、pushボタンがあるかを見つけるまで数日かかってしまった。。。

当たり前のこと過ぎるが、自分のような初心者はそんなこと知らないし
親切に教えてくれる人もいないので、同じ境遇の人の役に立てば幸いです。
# TL ; DR
以下で数日間悩みました
1. 管理コンソールでpull、pushボタンの場所がわからない
    ⇒雲マークの所にある
2. pull、pushしようとするとエラーが出る
    ⇒git config pull.rebase falseで解決


# 1. pull、pushボタンの場所がわからない
[公式チュートリアル](https://docs.aws.amazon.com/ja_jp/sagemaker/latest/dg/nbi-git-resource.html)はCLIでのpull、push方法しか載ってなくて
ボタンを探すまで数日悩みました（情けない）。。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1683167/941d42e8-79ee-e6b2-ebd8-95f45fa6d32d.png)
やっとボタン場所がわかりpullしようとすると今度はエラーが。。。
ぐぬぬ・・・


# 2. pull、pushしようとするとエラー
初心者には読む気も失せるエラーがこちら

```
Git Pull failed with error: 
hint: You have divergent branches and need to specify how to reconcile them. hint: You can do so by running one of the following commands sometime before hint: your next pull: hint: hint: git config pull.rebase false # merge hint: git config pull.rebase true # rebase hint: git config pull.ff only # fast-forward only hint: hint: You can replace "git config" with "git config --global" to set a default hint: preference for all repositories. You can also pass --rebase, --no-rebase, hint: or --ff-only on the command line to override the configured default per hint: invocation. fatal: Need to specify how to reconcile divergent branches.
```

すごく助かる[参考記事](https://qiita.com/akiyama5433/items/5fcd23f4301ec8674d54)のお陰であっさり解決。
ターミナルでこのコードを打つだけです。
```
$ git config pull.rebase false
```
ちなみにターミナルをどこから開くかにも一苦労しました。。。
当たり前過ぎる事はネットで出てこなかったりする。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1683167/88011866-ff4e-0047-4a66-fe7441bc353f.png)

つまらない事で数日間悩みましたがやっとpullできました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1683167/26fda56b-d933-3924-99cb-78a219ca0ca9.png)
# 3.最後に（Changed→Staged→Commitって何？）
この流れすら私には？？？で悩みました。。。
まずファイル変更すると、その変更がChangedステージ？に移るので＋（プラス）を押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1683167/5d98d265-563c-92ac-75a3-7decfbd99894.png)
次はStagedステージ？に移ります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1683167/99d4f06c-ca03-fb98-4768-90d9494e024f.png)
サマリーを何でもいいので書いてCommit押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1683167/df1d76e2-de1d-96c3-9469-9045215bfa72.png)
最後にpushします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1683167/941d42e8-79ee-e6b2-ebd8-95f45fa6d32d.png)
無事pushされました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1683167/23803bc6-9c13-a657-3a9a-1de6d0601a74.png)

# 参考
[SageMakerとGitHubのプライベートリポジトリを連携させる](https://qiita.com/curshey/items/8c3c79b345b37be1415e)
[【GitHub】基本の使い方！初心者がPushするまで](https://qiita.com/TakuroKawakami/items/5d3a08bafb156e16491e)
[git pull したときに出たエラーの対処法](https://qiita.com/akiyama5433/items/5fcd23f4301ec8674d54)
ポモドーロテクニックのタイマーとして使えるChromeの拡張機能を使ってみた

# ポモドーロテクニックとは？
皆さんポモドーロテクニックはご存じでしょうか？
**25分作業に集中して5分休憩する**サイクルを１ポモドーロと言い、それを４回ほど繰り返した後に30分ほどの長めの休憩を取ってメリハリをつけて集中力と生産性を高め、効率よく仕事を進めることができる時間管理術のことです。
下記の記事で詳しく説明しておりますので是非ご覧ください。

https://qiita.com/so__hei__/items/663ffab85807189d5a89

# ポモドーロテクニックのタイマーとして使えるChromeの拡張機能
わざわざ携帯などで25分測って、終わったらまた５分測ってを繰り返す作業は面倒です。
そんな時に役に立つのがこの「**Marinara: Pomodoro® Assistant**」で以下の機能があります。
- ボタン一つで時間を測ってくれる(時間のカスタマイズも可能)
- 通知を設定できる
- 過去の記録をつけることができる

とシンプルで使いやすい便利な機能があります。

https://chrome.google.com/webstore/detail/marinara-pomodoro%C2%AE-assist/lojgmehidjdhhbmpjfamhpkpodfcodef/related

# 実際に使ってみよう
拡張機能を追加できたら使いやすいようにピンで固定しておきましょう。
![スクリーンショット 2022-12-17 13.54.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604036/742d961a-d3a6-996d-cecb-5e7fff349150.png)
これでボタンを押下するだけで集中モード(25分)、休憩モード(5分)を計測でき、一時停止もできます。
![de4cc3deb985a702292b4fc543ea0c0f.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604036/660c4e8c-f3dc-68af-2905-3746c96e4b4f.gif)

### アシスタント画面
ポモドーロのボタンを右クリックし、「ポモドーロの履歴」を開くと、時間のカスタマイズや通知の設定やサウンドの設定を行うことができます。履歴タブを開くと活動履歴も確認することが可能です。
![スクリーンショット 2022-12-17 14.09.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604036/472bceb8-84ef-22e4-8fc3-92464389ece7.png)
「**デスクトップ通知を表示する**」を設定すると他のアプリケーションを開いていても、通知が表示されます。
![スクリーンショット 2022-12-17 13.10.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604036/c6fc3c4f-0549-0394-166d-ccef1f7f12e9.png)
「**新しいタブ通知を表示する**」を設定すると新しいタブが開かれて、休憩を開始することや活動履歴画面へ遷移することも可能になります。
![スクリーンショット 2022-12-17 14.07.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604036/3d0f44ed-8e6e-a3a0-c05a-cdc5a012f399.png)

会社でキッチンタイマーを仕事中使うわけにもいかないですよね。。
急にジリジリなると周りの方にも迷惑にもなりますし、自分の作業が可視化できて非常にシンプルで使いやすい拡張機能ですので、皆さんも是非使ってみてください。
TwoStepView

![17.TwoStepView.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11525/68f7d588-5424-d352-89a4-0b25bf8af48c.png)

https://bliki-ja.github.io/pofeaa/TwoStepView/

Domain Model は饒舌に業務を表現しますが、必ずしもユーザーインターフェースに適したものとは言えません。プレゼンテーションの役に立たない情報を持っている場合もあれば、人に理解しやすい表現が足りていないこともあります。

Two Step View は、直接モデルをビューで視覚化する前に、いったんプレゼンテーションに適したデータモデルに変換するパターンです。モデルをページに表示するとき、「後はそのままテンプレートに流し込めばいいだけ」と言えるような形にしておくと、Template View での扱いがとても簡単になります。いちど、動的で有意な部分だけを集めた、論理的なページでのモデルビュー変換をするのです。

HTML などでユーザーインターフェースを作っているときは、レイアウトに意識が奪われています。そこに Domain Model の意味解釈をするプログラムを混ぜると、複数のことを同時に考えなければならなくなります。ロジックが難しくなりすぎると、不具合のリスクが高まります。つまり、賢すぎるビューの問題です。

似た問題に対応するパターンに Transform View があります。Transform View と Two Step View の違いは、扱うもののスコープです。Transform View はひとつのエンティティ単位といった、モデルの「部分」を扱います。その役目は Temoplate View の補佐です。テンプレート 1 に対して変換は 0 〜 N です。Two Step View が扱う単位は「ページ」、あるいは別の言い方をすると「URL が表すリソースプレゼンテーションの全て」です。テンプレートと変換を駆使したビューの前に、唯一の、間接的な論理ページ生成を挟むのです。

REST は (単なる CRUD API ではなく)、Representational State Transfer の略です。HAL あるいは HATEOAS を伴い、人にとって有意なデータと論理的なハイパーリンク選択肢を持つ Representational State は、Two Step View で言う論理ページにほかなりません。PoEAA 本が書かれた当時、REST は論文に初めて登場した頃で、本では XSLT などにたとえて説明されています。現代では、実質的に XSLT や SOAP といった当時のトレンドはみんな、JavaScript と親和性の高い、より大衆的な技術に取って代わられました。

REST は転送できる形式であることがポイントです。システム内部のプロセス間でやりとりする以外に、インターネットを通して、JavaScript で動くクライアントプログラムとも、スマートフォンアプリとも連携可能です。広い視点で言うと、それらは MVC のビューです。

HTML はブラウザでレンダリングしないと、どこに何が書いてあるのかがわかりにくく、レイアウトのせいで異様に長くもなります。コマンドラインから気軽に cURL でアクセスできるものではありません。いっぽう、論理ページとしての REST は多くの場合、JSON にシリアライズされます。cURL と jq を使って、Web ページの GUI と等価な情報を得ることができます。
python の落とし穴 ~lambda編~

# 落とし穴のコード

```python
def wrap(x, y):
    return x + y


func_ls = [
    lambda x: wrap(x, y)
    for y in [1, 2, 3]
]

for f in func_ls:
    c = f(1)
    print(c)

```
```bash
4
4
4
```

#　意図通りに動かすには

```python
def wrap(x, y):
    return x + y


func_ls = [
    lambda x, y=y: wrap(x, y)
    for y in [1, 2, 3]
]

for f in func_ls:
    c = f(1)
    print(c)

```
```bash
2
3
4
```
【React】Context を使おうと思った時に気をつけること

## はじめに

本記事はシリーズものです。

通常、React では props を通じて親コンポーネントから子コンポーネントへ値や関数の受け渡しを行います。
しかし、特定のケースにおいてはこれが面倒に感じてしまうパターンがあります。

いわゆるprops のバケツリレーが発生してしまうんですね。

これの回避のために、React では Context というものが用意されています。
今回はこの Context についてのお話を 3 回に分けてお話しします。

第 1 回では「[Context いつ使用するべきでいつ使用するべきではないか](https://qiita.com/anneau/items/c20afcb8693260cbb7ba)」
第 2 回では「[Context の使い方](https://qiita.com/anneau/items/7369152db5dc5219a7b4)」
第 3 回では「Context を使おうと思った時に気をつけること」 ← イマココ

についてお話しします。

## Context を使おうと思った時に気をつけること

### 0. そもそもContextが必要なのかどうかを考える

https://qiita.com/anneau/items/c20afcb8693260cbb7ba

にも書きましたが、Contextは乱用してしまうと保守性を下げる可能性があります。
Contextを使うと、それを利用したコンポーネントがContextProviderで囲まれている前提のコードになってしまうためですね。

つまり、捉え方によると、**子が親に依存する**状態になります。

なので、**そもそも必要なのかどうか**ということを考えましょう。

https://scrapbox.io/fsubal/props_%E3%81%AE%E3%83%90%E3%82%B1%E3%83%84%E3%83%AA%E3%83%AC%E3%83%BC%E3%81%A3%E3%81%A6%E4%BD%95%E3%81%8C%E6%82%AA%E3%81%84%E3%82%93%E3%81%A0%E3%81%A3%E3%81%91

にもありますが、propsのバケツリレーが悪いものだとは僕も思いません。

型を書くのが面倒というのであれば、

https://qiita.com/anneau/items/5e0c349c953ef4064881#%E5%AD%90%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%AEprops

に書いたように、`ComponentPropsWithoutRef`というものを使えば、親が子に依存するという構成を貫き通すことができます。

それでも必要だという判断になった場合は以下のことを気にしてください。

### 再レンダリングを意識する

詳しくは以下の記事を見ていただければと思いますが、Contextが保持するステートが変わった場合、意図した部分以外が再レンダリングされる可能性があります。

https://qiita.com/soarflat/items/b154adc768bb2d71af21

ステートを配布するProviderと更新関数を配布するProviderを分けましょう。という話。

記事の中ではuseMemo、React.memoによる再レンダリングを防ぐ手法も書かれていますが、基本的には使用側がProviderの中身を意識することなく使えるのが望ましいかなと思うので、ちゃんと分けましょう。

## まとめ

Contextは便利ですが、一種、グローバルステートのような扱いにもなりますし、保守性を下げてしまう可能性もあります。

使うべきなのか？ということを考えた上で、使うのであれば再レンダリングを起こさない設計を貫きましょう。
range of [-1, 0]というPyTorchメッセージは何の意味？

PyTorchを使う時に`x.transpose(2, 1)`のソースコードに下記のエラーメッセージが出ました。

> IndexError: Dimension out of range (expected to be in range of [-1, 0], but got 2)

意味がよくわかりませんでした。特に`range of [-1, 0]`の意味が理解できませんでした。

調べた結果、結論を簡単に言ってしまうと、`range of [-1, 0]`は-1から0までという意味です。上記IndexErrorメッセージの意味として、テンソル`x`は1次元配列ですが、`transpose`関数の引数に2が渡されました。`transpose`関数はテンソルに対して次元（軸）を入れ替えるため、引数で指定された二つの軸はテンソルに存在しなければなりません。

下記のStackOverflow回答がわかりやすいと思いますので、こちらに翻訳して載せます。

https://stackoverflow.com/a/59704613/444860

> テンソルの次元（軸）を関数の引数に指定する時（例えば`m = torch.nn.LogSoftmax(dim=1)`）に、0から始まり、1が二番目の正の次元を指定することができます。
代わりに、負の次元を指定することもできます。その場合、-1は末尾の軸、-2は末尾から二番目の軸です。
>
> 例えば、四次元である4Dテンソル`b * c * h * w`の場合、
>
> - バッチ（batch）の軸（一番目）は`dim=0`か`dim=-4`で指定できます。
> - チャンネル（channel）の軸（二番目）は`dim=1`か`dim=-3`で指定できます。
> - 高さ（height）・垂直（vertical）の軸（三番目）は`dim=2`か`dim=-2`で指定できます。
> - 幅（width）・水平（horizontal）の軸（四番目）は`dim=3`か`dim=-1`で指定できます。
>
> したがって、4Dテンソルの場合は`dim`引数に`[-4, 3]`の範囲にある値を設定できます。

冒頭の`x.transpose`のエラーメッセージに戻すと、`expected to be in range of [-1, 0]`と言われたので、`x`は1次元配列で、軸は一つしかありません。
AgileTPI でテストプロセスのアセスメントを実施し課題を分析する

株式会社LIFULLの品質戦略部の中野（@nakanon）です。

## はじめに
弊社QAチームでは今年の春にテストプロセス改善に向けて ソフトウェアテストのアセスメントモデルである「Agile TPI」の導入の検討に入り、その後 AgileTPIのテーラリングから全社向けのアセスメント活動を実施し、すべてのプロダクトのレポートに加え、全社での評価レポートをまとめました。
今回は、Agile TPIの概要とアセスメント活動の事例をご紹介します。

## Agile TPI （Agile Test Practice Improvement） とは

ソフトウェアテストプロセスの成熟度評価と改善モデルです。
TPI NEXTⓇ（ビジネス主導のテストプロセス改善）のアジャイル実践への応用としてSogeti社によって策定、提供されています。
[Agile Test Practice Improvement (Agile TPI)](https://www.tmap.net/building-blocks/agile-test-process-improvement-agile-tpi)

### Agile TPIの用語

**キーエリア**
テストプロセスの評価軸、分類を指します。例えば「テスト戦略」「テストツール」「メトリクス」などです。

**チェックポイント**
キーエリア毎に複数のチェックポイント（質問）が存在しています。
チェックポイントに回答することで個々のテスト活動の「出来ている」「出来ていない」を判断することが出来ます。

**クラスター**
各チェックポイントの改善の優先度があり、最優先のAから段階的にGまで定められています。

### アセスメントの実施
大まかに以下のような流れでアセスメントを実施しました。

##### 1. Agile TPIのテーラリング
Agile TPIでは「Agile TPI Tool」というアセスメント実施用のExcelが提供されており、Excelにあるチェックリスト形式の質問に回答することでテスト活動における様々な活動の実践度合いや成熟度を可視化することができます。

テーラリングでは、主に社内の開発チームが答えやすいように質問の具体性の調整や言葉選びなど、チェックポイント（成熟度判定の質問）の見直しを行いました。
また社内にはテスト組織がありませんので「04 テスト組織」を削除し、置き換える形でオリジナルには存在しなかった「レビュー」のチェックポイントを作成しました。
最終的なキー項目のリストは以下の通りです。「04」以外はオリジナルとなります。

| | キーエリア |　|キーエリア|
|:-----------|:------------|:-----------|:------------|
|01	|ステークホルダーのコミットメント|09	|メトリクス|
|02	|関与の度合い|10	|欠陥管理|
|03	|テスト戦略|11	|テストウェア管理|
|04	|レビュー|12	|手法の実践|
|05	|コミュニケーション|13	|テスト担当者のプロ意識|
|06	|報告|14	|テストケース設計|
|07	|テストプロセス管理|15	|テストツール|
|08	|見積もりと計画|16	|テスト環境|


##### 2.すべてのプロダクトの現状調査
作成したアセスメント用のチェックリストを用いてプロダクトの担当者から回答をいただきました。

##### 3.分析・レポーティング
集計した結果から個々のプロダクトに対しては現状分析と改善提案のレポートの提供を行いました。また、全体分析として組織としての強みや弱み、直近でQAが取り組むべき課題などをまとめたサマリーレポートを作成しました。

## 分析・レポートティングを通して
### プロダクト担当者からの支援要請
プロダクトに対するフィードバックのレポートを受けて、プロダクトの担当者よりプロセス改善の支援依頼が発生しました。今後プロセス改善に役立つコンテンツの必要性が高まった点も今回の活動における評価できるポイントだと感じています。

### サマリーレポートの分析軸
今回は全体分析として以下の3つの軸で分析を実施しました。
1. 組織全体の強み弱み
2. クラスター（改善の優先順位）毎の成熟度合いや傾向
3. 本番障害とプロセス成熟度の相関

今回の活動から組織全体の強み弱みを分析できた点は特にやって良かったと感じたところです。
全体のデータからインサイトを得ることでQAとして組織全体に対して今後のアプローチを決定する材料になりますし、ステークホルダーとも次につながるコミュニケーションが期待できます。

### 全体分析から得られたインサイト
得られたインサイトの一例として以下のようなことがありました。
- テストや品質の教育は十分に提供されているか。どの程度行き届いているか
- リグレッションテストの実践度合い、テストツールの導入やテスト自動化の状況はどうか
- テストプロセスの中で不足している技術は何か。例えば、メトリクス管理、レビュー、テスト戦略などのうち次に注力すべきポイントは何か
- キーエリアの3つの属性（ステークホルダーとの関係、テスト管理、テスト業務の専門性）から見た成熟度の偏り

上記のような視点を持つことでファクトをもとにステークホルダーに説明できることが可能になりました。

## 最後に
今回のアセスメント活動を通して、個々のプロダクトの改善提案をフィードバックできた点はもちろん、組織全体の課題を分析できたことから活動の有用性を感じています。
普段の開発プロジェクトや本番障害の分析などで感じていた肌感とのギャップを分析から気づけた点も良かったです。

## 参考
[Whitepaper Agile TPI](https://www.tmap.net/sites/tmap/files/files/Whitepaper%20-%20Agile%20TPI%20Japanese%20v1.0.pdf)
[Agile TPI Tool（ダウンロード）](https://www.tmap.net/sites/tmap/files/files/Agile%20TPI%20tool%20Japanese%20v1.0.xls)
Goのlog.Fatalではプログラムが終了してしまう

# TL;DR

Go言語の例外発生時に下記のような処理を行うことがあると思います。
```go
if err := hogeFunction; err != nil {
    // エラー処理
}
```

エラー処理のところでログ出力のために`log.Fatal(err)`を使っていたところ、意図せずプログラムが終了してしまいました。
処理を継続したければ`log.Print(err)`を使うのがよさそうです。

# 解決したい課題

Ruby on RailsのRakeタスクから、別のRuby on Railsアプリケーションにリクエストを送り、Goのコードを実行して外部のAPIを呼び出すシステムを構築をしていました。

(1) Ruby on Rails
↓ GraphQLにてリクエスト
(2) Ruby on Rails
↓コマンド実行
(3) Go
↓リクエスト
(4) 外部API

実行するRakeタスクについてはもとのRuby on Railsにある`Category`モデルのフェッチ対象を抽出する処理が書かれています。`ApiClient.new.request_to_fetch`に対象の`category_id`を渡すことでGraphQLを用いて別のRailsのエンドポイントに対してリクエストを送っています。
```ruby:fetch_categories.rb
desc 'APIへのリクエスト'
  task requestl: :environment do |_task, _args|
    Rails.logger.info "===== start fetch(#{Time.zone.now}) ====="

    Category.where(is_fetch_tareget: true).find_each do |category|
        ApiClient.new.request_to_fetch(category.fetch_id)
      end
    end

    Rails.logger.info "===== end fetch(#{Time.zone.now}) ====="
  end
end
```

GraphQL経由で受け取った`category_id`を引数として渡して`fetch_by_category_id.go`というGoのコードを実行します。それぞれの処理を並行して実行したかったためGoを使っています。

```ruby:fetch_by_category_id.rb
class Mutations::FetchByCategoryId < Mutations::BaseMutation
  argument :category_id, String, required: true

  field :status, String, null: true
  field :errors, [Types::ErrorType], null: true

  def resolve(category_id:)
    # NOTE: バックグラウンド実行
    system("nohup sh -c 'cd /app/go && ./bin/fetch_by_category_id #{category_id}' &")
    status = true

    {
      status: status && 'ok',
      errors: errors || nil
    }
  end
end

```
`fetch_by_category_id.go`の内部では、さらに他のサードパーティ製のAPIに`category_id`を渡して得られた結果を元に処理を行うようなコードが実装されていました。

APIのフェッチ部分では下記のような処理が書かれていました。（一部抜粋）
```go:fetch_by_category_id.go
items, err := client.SearchItems(categoryId)
if err != nil {
    log.Fatal(err)
}
```


# 課題の原因

(1)のシステムでバッチを回した際に正常終了すれば`===== end fetch(#{Time.zone.now}) =====`がログに出力されるはずですが、こちらが出力されないで終了されている問題が起きていました。


その原因として、`log.Fatal`で書かれていたため、サードパーティ製のAPIから意図しない結果やエラーが帰ってきた際にプログラムが終了してしまっていたため(1)と(2)の間の接続が切断されてしまっていることが原因のようでした。

`log.Fatal`のドキュメントの説明を調べてみると、`Print()`の後に`os.Exit(1)`を呼び出すのと変わらないという内容が書かれているため、エラーがあったさいにアプリケーションが終了されてしまいます。

> Fatal is equivalent to Print() followed by a call to os.Exit(1).

https://pkg.go.dev/log#Fatal


# 課題を解決する技術、手法

今回は(1)のバッチの段階ですべてのカテゴリについて一度回しきりたいという要求があったため、(3)の取得の際にエラーが起きても処理を継続するようにしました。

エラーを受けとったさいに内容をログに出力して、処理は継続するようにするために`log.Print(err)`を使うようにしました。

# 参考

https://qiita.com/ryokky59/items/19fa212d1898dcb4bcfd

https://qiita.com/neko_the_shadow/items/70642e57723d42b8514c
リリース数を急激に上げたチームで当たった壁と取り組み

## はじめに
エージェンシー開発チームでPMをしている若林です。
[ランサーズエージェンシー株式会社](https://lancers-agency.co.jp/)ではLancersAgentとPROSheetというサービスでフリーランスの方向けにお仕事を紹介するエージェントサービスを運営しています。

https://lancersagent.com/

https://prosheet.jp/

### 背景
エージェンシー開発チームは2021年の下期ごろから開発体制が拡充され、2022年には3本のプロジェクトが並行して開発されている状態になっていました。

#### 参考
2020年までのリリース数と2022年のリリース数の比較
| 年度 | masterマージ数 |
|:-----------|------------:|
| 2020       | 53        | 
| 2021       | 106        | 
| 2022     | 386      |

2022年は2リポジトリの合計(363+23)
※途中から新規の機能を作ったためリポジトリ自体も増えて2つのリポジトリで開発することになりました

```
# masterマージ数集計
git log --after '2022/01/01' --before '2022/12/31' --oneline --merges | grep "master" | wc -l
```

今まで細々と維持を続けていたチームが急にスピードをあげて開発をすることになり、こんな壁にぶち当たることになります。

よくある課題
-　コンフリクト
-　検証渋滞

本プロジェクト特有の課題
-　トリガー地獄
-　リポジトリが増えた

こんな壁があったとしても、事業成長を止めないために「出したいタイミングでリリースを継続していく」ことが必要になってきます。
「今」欲しいと言われた機能を2ヶ月後に出したとしても喜ばれないので、欲しい機能をタイムリーに継続的に出すことが開発チームには求められます。

今までより多くなったメンバーと大きくなったスコープで、スムーズにリリースし続けるためにチームとして取り組んできたことを1年の振り返りも兼ねて記載していきたいと思います。

### コンフリクト

Aさんの方が早く開発していて途中から開発要望が入ってBさんも同じ機能に対して別の開発を始めました。
Aさん方が速くリリースしてBさんがリリースしようとした時に、Aさんの開発差分を取り込めていなかったため修正箇所が競合してしまいました。
その結果一度受け入れOKとなったものが正しく動作しなくなってしまったりというデグレードが発生するパターンもありました。
上記のようなコンフリクトを回避するための取り組みとして大きく打ち手を打ったのは、以下2パターン。

-　小さく速く出す
-　同じところを触らない

1個目の「小さく速く出す」については読んで字の通りですが、開発者だけでなく、レビュワーやテスターもまとめて一気に実施するのではなく、
機能が確認可能になった時点で、できた順にレビューをしていく、順次テストをお願いするなどの運用をして、機能を細かくして速く出すということをやっていました。

それでも、大きな開発になってしまうとマスターマージまでの機能を小さくできない時もあります。
そんな時には機能を触る人（チーム）を分けることで対応していました。

運用として大きく変わったところは、開発定例会議。
今まではアップサイド開発、維持などチームごとにバラバラにやっていた定例をまとめて、開発進捗・リリース予定と開発範囲を確認してお互いの機能に影響がないかを洗い出す。
コンフリクトが発生しないように調整可能な場合は開発順序を変えるということをしていました。
開発順を変えられない場合であっても横の人がどの機能を触っているかわかることで、影響範囲の伝達ができ、重大エラーとなるようなコンフリクトが発生せずにリリースを続けられました。


### 検証渋滞

開発者10人に対して検証環境（ステージング）が一つ、ステージングで開発完了したものを本番環境にリリースするという運用をしていました。
容易に想像がつくかもしれないですが、人間が介在してくるところで渋滞が発生します。

[渋滞ポイント]
-　検証環境への反映待ち
-　検証環境での受け入れ待ち

これらを回避するためにやったこと

-　検証にリリースする人を複数人に増やす
-　検証環境を複数用意する

週ごとに検証環境のブランチを作成してその週で検証するブランチは全て検証用ブランチにマージしていきます。
その検証用ブランチは開発者であれば誰でも追加、検証環境への反映ができる状態にしました。
このことにより一人に検証反映の負荷が偏らず、検証環境への反映待ち時間を減らすことができました。

また、ステージングの前の検証環境をSREチームに用意してもらい、事前にある程度受け入れを行ってもらうことができました。
これによって最終的にはステージングで確認が必要だとしても大きなエラーを事前に潰すことができて、検証待ち時間を短縮しました。


### トリガー地獄
本プロジェクトはINSERTとUPDATEのタイミングでトリガーを使い、別テーブルに格納することで履歴を残していく方式を従来からとっていました。

[トリガーを使っていたことでリリースタイミングで困っていたこと]
-　最新のトリガーが本番を参照しないとわからない
-　トリガーとテーブルに差分があるとエラーになる

このうち最新のトリガーが開発環境で見れなかった事象については週次のDBのレプリケーション時にトリガーを含めてdumpをとってリストアする形式にSREチームに変更してもらったことで解消し、開発環境でも最新のトリガー状況がわかるようになりました。

トリガーとテーブルの差分についてはトリガーの記載方法を変えることで解消しました。
今までの書き方
```
INSERT INTO 履歴テーブル VALUES (null, NEW.id, NEW.カラム名, NEW.カラム名, NEW.カラム名, NEW.カラム名)
```

変更後の書き方
```
INSERT INTO 履歴テーブル SELECT null, 元テーブル.* FROM 元テーブル WHERE id = NEW.id
```
カラムの修正を行うたびにトリガーにもカラムの変更を反映する必要があり、トリガーとテーブル間での不整合が起きやすい状況になっていたため、リリース時に頻繁にエラーを起こす原因となっていました。
トリガーの記載方法を変更したことにより、テーブルとトリガーの不整合が発生しなくなり、リリース時のエラーが大幅に軽減されました。

### リポジトリが増えた
参照するリポジトリが増えることで管理コストも上がりましたが、プロジェクト全体のチケットを参照できるKANBANを作成することでリリースの抜けもれなく運用することができるようになりました。
（将来的には新しいリポジトリに機能全体を移行していきたい）


### まとめ
こうやって書いてみるとリリース運用の試行錯誤の1年だったなという感じです。
来年以降は体制もまた変わっていくので、より良い開発スタイルを開発チームとユーザで目指していければと思います！（抱負）
明日は@manamin0521さんです。
言語学習アプリのコンセプトを固める

前々からの持論、そしてアプリ開発のヒントに至るまで

https://qiita.com/EasyCording/items/9dbb13a1de6cc339cb1f

## 言語ＡＰＰ
昨年までに開発を終えているのは、FLASKを使った多言語辞書である。

https://www.youtube.com/watch?v=zT2vD0f_trw

実はSTREAMLITで置き換えようとか、REACTネイティブで開発しようとか、色々模索はしていたのであるが、一向に箸が進まない状態が続いていた。要するにアプリの開発コンセプトが、少しあいまいだったのが原因である。

# 勉強法　

最近の英語の勉強方法を少し触れておく
* Audibleでひたすら読書の音声を聞きまくる
* 毎日、2時間以上のリスニングと、睡眠時は装着したまま脳内にインプット
* イヤホンは耳が痛いので、骨伝導ヘッドホンを使用

# 成果

段々と耳が慣れてきて、知っている単語はほとんど理解できる状態になった。
アメリカ英語、ブリティシュ英語の違いがあるので、発話者をいろいろ変えて学習データを水増ししている。

# 課題感

結局、何十回聞いても、分からない単語は分からない状態で終わっている。
テキストファイルを最終的には購入して確認する必要がある。

# やりたいこと
書籍のジャンルによって、頻出する単語リストのようなものを作りたい。
これを元に、単語学習用の音声ファイルを作りたい（単語には意味理解できる情報を足してデータ化）
文章の中での、特徴的な文章（フレーズ）を抽出して、文章リストのみのＭＰ３ファイルを作りたい

# 仕様①　重要語

* テキストデータは、垂れ流して、ＢＯＷを作り頻出度（ＴＦ）を抽出する。
* 自分の暗記済み単語との差分を抽出する
* 単語を日本語翻訳（もしくは英英辞典）を通して、意味情報を加える。
* テキストデータをＭＰ３化する

# 仕様②　特徴語句

* 暗記ワードを含んだ文章をリスト化する
* 日本語訳、英語を交互に並べたテキストデータを作る
* テキストデータをＭＰ３化する

# まとめ

ひとまずデータ入力から、アウトプットまでのフローをまとめました。
プログラミング初学者がPHPを勉強する（配列編）

# 自己紹介
・製造業（全くパソコン触ったことない）からエンジニア転職を目指して学習しています。
・プログラミング初心者です。
・学習したことをメモ程度に書いていこうと思います！

# 何について？
今回はPHPの配列について記載していく！

## ・配列とは

１、複数の値をまとめたタンスのようなものです。引き出しに値を入れていくイメージ
２、データを「キーと値」のペアにしている。
３、「キー／値」のペアになっているデータを配列の要素と言う。
４、配列には全てのデータ型の値を格納することが出来る。

## ・配列の種類

**結論‥PHPには１種類しかない！**

キーに連続するint型を使うとインデックス配列になり、
キーにstring型を使うと連想配列になり、
値に配列を格納すると多次元配列になる。
なので考え方を変えて使用する必要はないと思う。

## ・配列の作成
配列の作成には２種類のやり方があります。
**１、arrayを使用する。**
`$fruits = array('peach', 'banana');`
**２、arrayを使用しない。**
`$fruits = [];`

## ・配列の操作
### ・先頭に要素を追加
```
array_unshift($fruits, 'grape');
```
### ・最後に要素を追加
```
$fruits[] = 'grape';
```
### ・配列の結合
```
$colors = array('red', 'blue');

$colors2 = array('white', 'green');

$new_colors = array_merge($colors, $colors2);
```
Jacksonデシリアライズをいい感じにしたい話

この記事は ウェブクルー Advent Calendar 2022 18日目の記事です。
昨日は [@yuko-tsutsui](https://qiita.com/yuko-tsutsui) さんの「[XXXXXXXXXXX](XXXXXXXXXXX)」でした。

## はじめに

弊社では、通常Scala + PlayFrameworkで開発をしているのですが、最近300年ぶりにJava + SpringBootでのAPI開発でJacksonに振り回された（いる）ので題材にしました。

## Jacksonってなんだ

Javaで使用するJson parseライブラリ。JavaのオブジェクトからJsonへの変換、またその逆をよしなにやってくれる便利くんです。

Scalaに関しては先週の[Scala + Play Frameworkでリクエストを値オブジェクトにする](https://qiita.com/yagiyuuuu/items/f6bf6252550021624bc5)で記事が書かれているので読んでください。

## 今回のお供JsonCreator

通常Jacksonはデシリアライズ時に、デフォルトコンストラクタを使用してインスタンスを生成します。JsonCreatorアノテーションをコンストラクタに付与することで、そちらを使用してデシリアライズをしてくれるようになります。

例えば、デフォルトコンストラクタを使用したくない、デシリアライズ時に何かしらの処理を実行したいなどがある場合には、これを使用することで実現することが可能になります。

というわけで

## デシリアライズ時に必須チェックがしたい
変換時にオブジェクトに対応するフィールドが存在しない場合など、nullを避けるためにエラーにしたいことがありました。

```java
@Data
public class FullName {
	private String familyName;
	private String firstName;
}
```

こんな感じのオブジェクトに

```java
{ "family_name": "田中" }
```

なJsonをデシリアライズしたい場合、通常は

```java
FullName("田中", null)
```

なオブジェクトが生成されます。`first_name`　ないのに生成されては困る！賢いことは罪！
ということなので、JsonPropertyアノテーションを使用して必須項目を指定してあげます。

```java
@Data
public class FullName {
	private String familyName;
	private String firstName;

  @JsonCreator
  public FullName(
		@JsonProperty(value = "family_name", required = true) String familyName,
		@JsonProperty(value = "first_name", required = true) String firstName
	){
		this.familyName = familyName;
		this.fistName = firstName;
	}
}
```

こうすることで、Json側にフィールドが存在しない場合、エラーを投げてもらえるようになります。

## ありがとうJsonCreator

開発中いろいろと文献を探しましたが、シリアライズに関しては結構拾えるのですが、デシリアライズはあまり見つけることができませんでした。
結論、JsonCreatorアノテーションを使用すれば、何だかんだほぼ全て多分解決するので、ここをスタートラインにすれば解決できるはずです。
セットでJsonPropertyアノテーションを使用することも忘れずに。

他にもMODE設定でも変えられるので興味がある人はぜひ。

## 終わり

明日は [@kalzit](https://qiita.com/kalzit) さんです。よろしくお願いします！

ウェブクルーでは一緒に働いていただける方を随時募集しております。

お気軽にエントリーください。

[https://www.webcrew.co.jp/recruit/](https://www.webcrew.co.jp/recruit/)
今日のElixirSchoolメモ11「ドキュメント」

Elixir Schoolの勉強メモです。

https://elixirschool.com/ja/lessons/basics/documentation

## 注釈

Elixirはドキュメントを第1級市民として扱い、プロジェクトのドキュメントにアクセスしたり、生成したりするための各種の関数を用意している。

* `#` インラインドキュメント用
* `@moduledoc` モジュールレベルのドキュメント用
* `@doc`　関数レベルのドキュメント用

### インラインドキュメント

```elixir
# コンソールに 'Hello, chum.' と出力します。
IO.puts "Hello, " <> "chum."
```

### モジュールレベルのドキュメント

`@moduledoc`アノテータはインラインドキュメントをモジュール単位で行うためのもの。
通常はファイル最上部で`defmodule`の宣言を直後に置かれる。

```elixir
defmodule Greeter do
  @moduledoc """
  ある人を歓迎する `hello/1` 関数を提供します
  """

  def hello(name) do
    "Hello, " <> name
  end
end
```

モジュールドキュメントは、IEx内で`h`ヘルパー関数を用いてアクセスできる。
`Greeter`モジュールを新しいファイル`greeter.ex`に入れてコンパイルすると、
これを自分で確認できる。

```elixir
iex(1)> c("greeter.ex", ".")
[Greeter]
iex(2)> h Greeter

                                    Greeter

ある人を歓迎する hello/1 関数を提供します
```

### 関数のドキュメント化

`@doc`アノテータは関数レベルでのインラインドキュメントを行うためのもの。
注釈をつけたい関数の直前に置かれる。

## ExDoc

ExDoxは公式のElixirプロジェクト。
ExDocはHTMLとオンラインドキュメントを生成する。

最初にアプリケーションのためにMixプロジェクトを生成する。

```elixir
$ mix new greet_everyone

* creating README.md
* creating .gitignore
* creating .formatter.exs
* creating mix.exs
* creating lib
* creating lib/greet_everyone.ex
* creating test
* creating test/test_helper.exs
* creating test/greet_everyone_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

    cd greet_everyone
    mix test

Run "mix help" for more commands.

$ cd greet_everyone
```

`lib/greeter.ex`ファイルを保存し、コマンドラインから動作を確認する。
`iex -S mix`コマンドで起動する。

```elixir
iex(2)> h Greeter.hello

                                def hello(name)

  @spec hello(String.t()) :: String.t()

Helloメッセージを表示します

## パラメータ

  • name: 人名を表現する文字です。

## 例

    iex> Greeter.hello("Sean")
    "Hello, Sean"

    iex> Greeter.hello("pete")
    "Hello, pete"
```


### インストール

全てがうまくいったらExDocの環境構築が準備できていることを意味します。
`mix.exs`ファイルに `:ex_doc`の依存関係を追加します。

```elixir
def deps do
  [{:ex_doc, "~> 0.21", only: :dev, runtime: false}]
end
```

`only: :dev`というキーバリューのペアを指定することで、
本番環境では`:ex_doc`の依存関係パッケージをダウンロードしたりコンパイルしあいようにしたりする。

`ex_doc`はEarmarkという別のライブラリも追加する。

Earmarkは、Exdocが`@moduledoc`および`@doc`内のドキュメントを美しいHTMLに変換するために使用するElixirプログラミング言語用のMarkdownパーサー。

### ドキュメント生成

コマンドラインから2つのコマンドを実行する。

```elixir
$ mix deps.get # ExDocとEarmarkを取得する
$ mix docs # ドキュメントを作成する
Generating docs...
View "html" docs at "doc/index.html"
View "epub" docs at "doc/greet_everyone.epub"
```

doc/ディレクトリにある生成されたドキュメントを見てみます。

![スクリーンショット 2022-12-17 13.02.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109744/d2d9f3d2-9ce1-1ffa-b01c-c2a10a02e254.png)

これでGithubや自身のWebサイト、HexDocsへデプロイできるようになります。

## ベストプラクティス

モジュールには常にドキュメントを書く。
だが、モジュールのドキュメントを書くつもりが無い場合は、空のままにせず`false`の注釈をつける。

```elixir
defmodule Greeter do
  @moduledoc false

end
```

また、`@doc`などの関数内でmarkdownを使うと、IExやExDocで読みやすくなる。
Vue 2.6 を 2.7 にしてみた

そろそろcomposition apiを試したく、心はreactだけどvue projectたくさんあるので、勉強してみる

# なぜ vue 3 ではなく 2.7 なのか
2.7からcomposition apiがplugin不要で使えるようになったらしい
vue3でvue2コードを動かすにはcompatというpluginが必要
それもけっこう設定があってめんどい、怖いので、いったん2.7の方が安全じゃない的な想像
あと、できれば2.7でcode freezeして、機能追加するときにはreactに移行してやりたい。。

# upgrade手順

まず、古いprojectの例として昔vuexの勉強をしたこれを使う
https://github.com/kujiy/vuex-study/tree/master/src

これは vue-cli-service で作ったほぼ巣のproject。
vue は 2.6.11 だった。この頃作ったprojectがたくさんあるのでちょうどいい。

```vue:package.json
    "vue": "2.6.11",
```


## まず起動しない。。
vue-cli-serviceがなくて起動しなかった。 

まず node.js のversionをできるだけ新しくする。

```
nvm use stable
```

nodeってバージョン上げてもなかなか問題でなくて、好印象

まずpackage.jsonに沿ってpackagesを入れる

```
yarn
```

なぜか vue-cli-serviceが使えないので手動でも打つ

```
yarn add @vue/cli
```

で、コマンドが使えるようになった

```
vue-cli-service
```


## vue を 2.7 にする
ここで v2-latest のバージョンを選ぶ。
https://www.npmjs.com/package/vue?activeTab=versions


```
yarn add vue@2.7.14
```

これでpackage.jsonも書き換わった。

起動すると version mismatch エラー。vue-template-compiler もupgradeする。

```
yarn add vue-template-compiler@2.7.14
```

これだけで起動した。
```
vue-cli-service serve
# or
yarn serve
```

# Options API を Composition API にする

そもそも vue には Extends API というものがあって、こう書くらしいんだが

```vue
<script lang="ts">
import Vue from "vue";
 
export default Vue.extend({
});
</script>
```

> In addition to the answers provided, there is a practical use case for calling Vue.extend() directly if you are using TypeScript.

TS 使ってると extends api を使うみたいだ。なるほど。これ js だからな。いろんな書き方があってマジわけわかめ。


僕のファイルはそうなってない。

```vue
    export default {
        name: 'HelloWorld',
        computed: {
```

これは Options API と言うらしい。

で、こんな感じにすれば composition apiになる

```vue
import { ref, reactive } from "vue";
export default {
  setup() {
    const countRef = ref(1);
   
    return {
      countRef,
    };
  },
};
```

最後に全部returnするあたりが今やってるreact projectぽくて好印象。


あとは一通り、このサイトのを実施して、data, method, computed, emit あたりを学びました。
ほとんどそのまま使えそう。

https://kobatech-blog.com/vue-composition-api/

うし、なんか行けそうな気がしてきた！













ref
https://tech.noricgeographic.com/vue-cli-vue%E6%9C%AC%E4%BD%93%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%83%E3%83%97%E3%82%92%E3%81%99%E3%82%8B/
https://www.asobou.co.jp/blog/web/composition-api1
https://kobatech-blog.com/vue-composition-api/
macでHomebrewをインストールする際にエラーになったので解決方法を記載する

## 概要
Macで[こちらのサイト](https://brew.sh/)を参照してHomebrewをインストールしようとすると下記エラーになったので解決方法を記載する。

## 環境
■ PC
macOS Monterey
バージョン 12.5.1
■ チップ
Apple M1 Pro

## エラー
```
Warning: /opt/homebrew/bin is not in your PATH.
  Instructions on how to configure your shell for Homebrew
  can be found in the 'Next steps' section below.
```
パスが通っていないようなのでパスを通す記述をする。
```
$ vi ~/.zshrc
export PATH="$PATH:/opt/homebrew/bin" 
```

上記の方法で解決可能であった。
JUnit5  メモ

## ルール
JUnitを利用する場合、import文を記述する
テストクラスの中に複数のテストメソッドを入力
mainメソッドを記述しない
@Testをつける。
@Test: JUnitにテストメソッドであることを認識させる．
値の確認には、専用のメソッドを使用する

## JUnitで利用できる主なメソッド
assertEquals(期待値,実際値)
 equalsで比較して同じことを検証

assertSame(期待値,実際値)
等号で比較して同じインスタンスであることを検証

assertNull(実際値)
 nullであることを検証

assetNotNull(実際値)
 nullでないことを検証

fail()
例外が発生時した際に正しく動くか検証する

```java
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;

import org.junit.jupiter.api.*;

public class BankTest {
	// 正常系:"kei"をセットできるか
	@Test
	public void setName() {
		Bank b = new Bank();
		b.setName("Kei");
	}

	// 異常系: nullをセットしようとしたら例外が起きるべき
	@Test
	public void setNameWithNull() {
		try {
			Bank b = new Bank();
			b.setName(null);
		} catch (NullPointerException e) {
			return;
		}
		fail();
	}

	// 異常系:2文字をセットしようとした場合、例外が起きるべき
	@Test
	public void throwExceptionWithTwoCharName() {
		Bank b = new Bank();
		assertThrows(IllegalArgumentException.class, () -> {
			b.setName("Ai");
		});
	}
}
```

```java
public class Bank {
	private String name;
	public String getName() {
		return this.name;
	}
	public void setName(String newName) {
	if(newName.length() <=3) {
		throw new IllegalArgumentException("名前が不正です");
		}
	this.name = newName;
	}
}
```

## 参考資料
スッキリわかるJava入門 実践編 第3版 (スッキリわかる入門シリーズ)
若手エンジニアに送る：能力×やる気×時間

先日、｢成果｣＝｢努力｣×｢運｣×｢対応力｣の記事を書きました。
https://qiita.com/k1morikawa@github/items/fd2e948bb4b20f4363f3
｢成果｣＝｢努力｣×｢運｣×｢対応力｣の記事
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/02819a78-d44e-cba2-23ce-9287d9977f02.png)

# 成果が出ない人達へ
## 努力は、人それぞれ
そもそも、｢努力｣というのは、個人に依存したものです。
英会話の勉強で考えても、
Ａ君は、一日10｢時間｣の勉強を半年続けて、TOEICで700点取れました。
Ｂ君は、一日10｢時間｣の勉強を半年続けて、TOEICで500点取れました。
同じく｢努力｣をしましたが結果が違います。
これは、Ａ君とＢ君の暗記力の違い、言語習得力の違いが影響した結果と思われます。

## 能力を下支えするもの
では、｢能力｣が全く同じの場合で結果は、一緒になるのか？
今度は、｢能力｣に影響を与えるのが、｢やる気｣になります。
めちゃめちゃ｢やる気｣のあるＡ君と全く｢やる気｣のないＢ君が同じ勉強をした場合に結果がどうでるかは、明白です。
## 時間の長さ
そして最後は、｢時間｣です。
｢やる気｣まんまんで集中力もバリバリある状態で、結果として他者に勝てない様であれば、後は、｢時間｣（量）でカバーする以外に方法はありません。
つまり、努力は　｢能力｣×｢やる気｣×｢時間｣に因数分解できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/cfdd0b31-b098-6a9e-5156-336199f3f064.png)

# ｢能力｣×｢やる気｣×｢時間｣×｢運｣×｢対応力｣
｢成果｣＝｢能力｣×｢やる気｣×｢時間｣×｢運｣×｢対応力｣となる訳で、これは、｢成果｣を出すというのは、5つの要素から成り立ってるという事です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/096283ac-887c-944f-0e54-61fc791f1cc8.png)

この5つの要素をしっかりと認識して仕事や物事にチャレンジするのは、とても重要です。
例えば、仕事をしている中で自分には｢能力｣が無いと壁を感じる事があったとしても、諦める必要は無いって事です！
｢成果｣を出すためには、
- ｢やる気｣を増やす
→がむしゃらに、そして、真剣に仕事をする。楽しみながら仕事をする。
- ｢時間｣を増やす
→単純に働く｢時間｣を増やす事も出来るし、それ以外にも、人よりも工夫できないか沢山考えたり、週末に本を読んだり、有識者のセミナーに参加して勉強する
- ｢対応力｣を増やす
→今の自分では出来ない可能性の高い物事に対しても、果敢に挑戦する
上記の事により｢成果｣は変わってきます。

｢やる気｣、｢時間｣、｢対応力｣の要素は、自分の｢努力｣次第で幾らでも頑張る事ができる。
そして、自分の｢成果｣は、｢能力｣の要素へ次第に組み込まれていきます。自分の身に付いてきます。

# まとめ
｢成果｣について悩んでる方々は、｢やる気｣、｢時間｣、｢対応力｣の要素を真剣に｢成果｣を出すためのプロセスを考えて、日々の行動を変えてみましょう
今後も記事を投稿していきますので、フォロー、イイねお願いします。
AysncValueメモ

# AsyncValueとは

Riverpod パッケージに含まれる非同期データを安全に扱うためのユティリティクラス。
非同期のloadingやerror処理を扱える。whenを使ってloading時にプログレスインディケーターを表示したりエラー処理、データを表示する事ができる。

AyncValueにObjectを入れてやると非同期処理時にそのObjectの状況を簡単に監視できるそう。

https://pub.dev/documentation/riverpod/latest/riverpod/AsyncValue-class.html

```Dart:AsyncValue
/// A provider that asynchronously exposes the current user
final userProvider = StreamProvider<User>((_) async* {
  // fetch the user
});

class Example extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final AsyncValue<User> user = ref.watch(userProvider);

    return user.when(
      loading: () => CircularProgressIndicator(),
      error: (error, stack) => Text('Oops, something unexpected happened'),
      data: (user) => Text('Hello ${user.name}'),
    );
  }
}
```

LoadingやError Stateを使わない場合は直接AsyncValueの中身（Value)にアクセスする事ができる。

:::note warn
valueはNullable。
:::

```Dart:AsyncValue Value
Widget build(BuildContext context, WidgetRef ref) {
  // reads the data state directly – will be throw during loading/error states
  final User user = ref.watch(userProvider).value;

  return Text('Hello ${user.name}');
}
```