OmniAICreator/Qiita-1.07M huggingface dataset:
【laravel】タグ検索機能の実装　


#タグ検索機能の実装　

画像のような、タグ名で投稿検索するフォームを実装する
![タイトルなし.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/750557/83ecbe44-e83b-4ec7-df76-e27cd768a102.gif)


# 前提
テーブル構造は以下の感じです。

![スクリーンショット 2021-03-16 17.57.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/750557/511e616e-edae-2db6-0fb2-f29b246c7d04.png)

#1 ビュー

```php

    <form action="{{url('/')}}" method="GET">
    <label for="">タグで検索</label>
    <input type="text"  name="keyword" value="{{$keyword}}">
    <input type="submit" value="検索"  class="btn-primary">
    </form>
```
#2 コントローラー

```php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Article;
use App\Tag;
use App\Http\ArticleRequest;
use App\Http\Requests\ArticleRequest as RequestsArticleRequest;

class ArticleController extends Controller
{
    public function __construct()
    {
        $this->authorizeResource(Article::class, "article");
    }

    public function index(Request $request)
    {
        $keyword = $request->input("keyword");
        $query = Article::query();
        $articles = Article::whereHas('tags', function ($query) use ($keyword) {
            $query->where('name', 'LIKE', "%{$keyword}%");
        })->get();
        return view("articles.index", ["articles" => $articles, "keyword" => $keyword]);
    }
}

```
ポイントは`wherehas`を使って、リレーション先のnameをクエリに指定していることです！
Laravel/Dusk でブラウザテストする際のちょっとしたTipを2つほど

# はじめに

Laravel/Duskを使い始めて標準で用意されていないケースが２つほどありました。
その対策を紹介したいと思います。

# 1.CSSの情報を取得

ElementResolverとWebDriverのメソッドを活用します。

```testExample1.php
    public function testExample1()
    {
        $this->browse(function (Browser $browser) {
            $browser->(略);
            $opacity = $browser->resolver->findOrFail('div.hoge button')->getCSSValue('background'); # buttonタグで指定されているStyleのbackground値を取得している
            $this->assertEquals($background, 'rgb( 128, 128, 128 )'); // 色情報はrgb関数で表記する。#は使えない
        });
    }

```

参考: Browser(Dusk)のソース、RemoteWebDriverElementのソース

# 2.target="_blank"を指定したリンク先へ移動

RemoteWebDriverの機能を使います。

```testExample2.php
    public function testExample2()
    {
        $this->browse(function (Browser $browser) {
            $browser->click('... a'); // target="_blank"なリンクをクリック
            $current_window = $browser->driver->getWindowHandle(); // 現在開いているウインドウに戻りたい時は予めハンドルを取得
            $target_window = collect($browser->driver->getWindowHandles())->last(); // 開いたタブはウインドウリストの最後と見て取得
            $browser->driver->switchTo()->window($target_window); // 対象のウインドウを移動

            // アサーションは略

            $browser->driver->switchTo()->window($current_window); // 対象のウインドウを最初のものに戻す
        });
    }
```

参考: [Duskのissue](https://github.com/laravel/dusk/issues/336), RemoteWebDriverのソース

# まとめ

標準に無いとしても諦めなければなんとかなりますね！
【Node.js】【npm】これらは何者？

何かと目にすることが多いが、いまいち概要がつかめていなかったNode.jsとnpm。ざっくりとですがまとめてみました。詳細は、今後学習する中で更新していきたいと思います。

##（前置き）JavaScriptとは
ブラウザ上で動くために開発されたプログラミング言語。コンテンツに動きをつけたり、DOM要素をいじったりすることができる。

・クリックしたら特定の位置まで画面がスクロールされる
・ポップアップで注意事項を表示する

等々のことが実装できる。

パソコン上で動くわけではないので、PHPやRubyなどのサーバーサイドの言語と異なり、OS上のファイル等にアクセスすることはできない。

##Node.jsとは
サーバサイドのJavaScript実行環境。

Node.jsではJavaScriptでOSの機能にアクセスするプログラムを組むことができる。それにより、ブラウザ上で動作していたときはできなかった、自由なファイルの読み書き等ができるようになる。

また、クライアントサイドの（ブラウザで実行する）JavaScriptの開発環境としても使用されている。

個人的に感じた使用する理由は以下の通り

・jsのバージョン変換のツールであるBabelを使用するため

jsはバージョンの更新により新しい機能が追加されている。しかし、ブラウザの使用がついてきておらず、うまく動作しないことがある。
そこで、「新バージョンのjsで記述したもの」を「旧バージョンのjsで記述したもの」に変換して使用するという方法がとられることが多い。

・jsファイルを分割・統合するwebpackを使用するため

記述量の増加に伴い、どこに何が書いてあるかが分かりづらくなってしまい、メンテナンスがしにくくなってしまう。そこで、ファイル毎に記述内容を分別し、最終的にそれらのファイルをまとめてしまい読み込む。

・Sassをコンパイルするため

##npmとは
Node.jsのパッケージ管理ツール。

パッケージとは、Vue.js、React、jQuery、webpack等のフレームワークやライブラリなどのこと。
Node.jsで使いたいフレームワークやライブラリがある場合、npmを用いてターミナル上でインストールして使用する。
【Rails】activerecord::recordinvalid:エラーの解決法【CSV】

#はじめに
現場で使える Ruby on Rails 5速習実践ガイド
「Chapter 7 機能を追加してみよう」の「7-6-2CSVデータを入力（インポート）する」で若干詰まったのでメモ。
#環境
Ruby 2.6.6
Rails 6.1.3
#エラー出現
models、controllers、views、routesに参考書通り記載し、
現れたインポートボタンにmac付属のテキストエディットでcsvファイルを作成しアップロード！
すると、、、
「activerecord::recordinvalid:バリデーションに失敗しました: 名称を入力してください:」と出現。
書いたコードを見返してもタイポ等は見つからず、、、
エラー画面にはtask.save!の所にマーカーが引かれていたので、モデルを確認することにした。
#app/models/task.rb
まず処理のロジックを確認する。

````ruby:task.rb
def self.import(file) #--1）
    CSV.foreach(file.path, headers: true) do |row|  #--2）
      task = new  #--3）
      task.attributes = row.to_hash.slice(*csv_attributes)  #--4）
      task.save!  #--5）
    end
end
````

１）fileと言う引数でアップロードされたファイルの内容にアクセスするためのオブジェクトを受け取る。
２）CSV.foreachメソッドを使ってCSVを一行ずつ読み取る。「headers: true」でCSVの一行目を無視する。
３）一行ごとにインスタンス生成。
４）生成したインスタンスをハッシュ形式にして「silce」メソッドで対応する値のみ取り出して入力するようにする。
５）データベースに登録。

つまり処理はOKだがデータベースへの書き込みがうまくいってない、、、？？
#CSVファイルを確認
自分で作ったCSVファイルをテキストエディットで開く。

````csv:add_task.csv
name,description,created_at,updated_at
餃子を作る,160個作ります
餃子を冷凍する,160個は食べきれないので冷凍する
````
カンマ忘れや誤字も特に見つからない。問題ない。。。
#試しにvscodeで開く
````csv:add_task.csv
{\rtf1\ansi\ansicpg932\cocoartf2578
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fnil\fcharset128 HiraginoSans-W3;}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;}
\paperw11900\paperh16840\margl1440\margr1440\vieww11520\viewh8400\viewkind0
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0

\f0\fs24 \cf0 name,description,created_at,updated_at\

\f1 \'e9\'4c\'8e\'71\'82\'f0\'8d\'ec\'82\'e9
\f0 ,160
\f1 \'8c\'c2\'8d\'ec\'82\'e9
\f0 \

\f1 \'e9\'4c\'8e\'71\'82\'f0\'97\'e2\'93\'80\'82\'b7\'82\'e9
\f0 ,160
\f1 \'8c\'c2\'82\'cd\'90\'48\'82\'d7\'82\'ab\'82\'ea\'82\'c8\'82\'a2\'82\'cc\'82\'c5\'97\'e2\'93\'80\'82\'b7\'82\'e9}
````
###*!?!?*

盛大に文字化け？していました。。。
文字化けのようなギリ読めるような、、、とにかくこれが原因なので、
vscodeで打ち直し、インポートすると無事にCSVは読み込まれました。
そういえば楽天の商品登録とかした時にCSVめっちゃ文字化けしてたな、、、と思い出し、
今後CSVの扱いには文字化けに気をつけようと思いました。
Railsの【session】を自分なりに噛み砕いた(３部作その２)

`flash`を理解する過程で、`params`や`session`についても理解できたのでまとめ
長くなりそうだったので、`1:params`、`2:session`、`3:flash`の3回に分けた

####【３部作リンク】
[1:params](https://qiita.com/masahiroDIARY/items/68c5294c8160ef6499c5)
2:session（ここ）
[3:flash](https://qiita.com/masahiroDIARY/items/d2d81f55fd695eb9d44e)

####【ページ内リンク】
[０．環境](#０環境)
[１．前提知識](#１前提知識)
[２．利用例](#２利用例)
[３．結論](#３結論)

#０．環境
・AWS
・Rails 5.2.4.5
・ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]

#１．前提知識
`session`も値ではなく**ハッシュ**！！！！！（←超重要）

[ページ内リンクへ戻る](#ページ内リンク)

#２．利用例
###順序①：ログイン部分
```rb:sessions_controller.rb
class SessionsController < ApplicationController
  def create
    user = User.find_by(なんでも)
    session[:user_id] = user.id
  end
```
ユーザーを指定し、`session`に代入する。`user.id = 1`とすると、`session = { user_id: 1 }`が保存される。

###順序②：ログアウト部分
```rb:sessions_controller.rb
class SessionsController < ApplicationController
  def destroy
    session.delete(:user_id)
  end
end
```
`session`のキーが`user_id`の物を削除している。ログイン部分が`[:user_id]`でログアウト部分が`(:user_id)`なのは、`session`がハッシュだからなのか･･･
※`session.delete[:user_id]`にするとエラーとなる

[ページ内リンクへ戻る](#ページ内リンク)

#３．結論
【`session`の特徴】
`session`は削除しない限り、ページ遷移しても値を保持し続けるのが特徴

・`session`は**値**ではなく**ハッシュ**！！！！！（←再度）

性質は違うけど、`params`さえ理解できればササっと行けた

[ページ内リンクへ戻る](#ページ内リンク)
Outlook起動時にMicrosoft365認証させる方法

Outlook起動時のイベントをトリガーにタスクスケジューラでPowershellでの365認証。
認証前に1～2秒Outlookが表示されてしまうのが難点。

```posh:AzureADauth.ps1
#画面表示制御のWindows API
$signature = @"
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
"@
$SW_HIDE = 0
$SW_SHOW = 5
$func = Add-Type -MemberDefinition $signature -Namespace "Win32Functions" -name "ShowWindowFunction" -passThru

$process = Get-Process Outlook

#Outlookをまず非表示
if(!!$process){
	foreach($p in $process){
		if($p.MainWindowHandle -ne 0){
			$func::ShowWindow($p.MainWindowHandle, $SW_HIDE)
		}
	}
}

#エラーを非表示
$ErrorActionPreference = "silentlycontinue"

#AzureADがインストールされていなければインストール
if ($PSVersionTable.PSEdition -eq "Desktop" -and (Get-Module -Name AzureAD -ListAvailable)) {
	Write-Host "AzureAD module is installed."
} else {
	Write-Host "AzureAD module is installing Now..."
	Install-Module -Name AzureAD -AllowClobber -Force
}

Import-Module AzureAD

#アセンブリのロード
Add-Type -AssemblyName System.Windows.Forms

#iniファイルにMicrosoft365のメールアドレスを記載しておく
$mailaddressSetting = Join-Path $PSScriptRoot "mailaddress.ini"

$mailaddress = Get-Content $mailaddressSetting

$UserCredential = Get-Credential $mailaddress

#365認証が通った場合だけOutlookを表示
try {	
	Connect-AzureAD -Credential $UserCredential
	$func::ShowWindow($p.MainWindowHandle, $SW_SHOW)
}
#365認証が通らなければOutlookを終了
catch {
	[string]$msg = "Microsoft365の認証に失敗しました"
	[System.Windows.Forms.MessageBox]::Show($msg, "認証失敗", "OK", "Error")
	
	Stop-Process -Name Outlook
	exit
}
```

タスクスケジューラとメールアドレス設定セットアップ用bat

```bat:Setup.bat
@echo off
echo;

if not exist c:\temp mkdir c:\temp

copy /y %~dp0\AzureADauth.ps1 c:\temp
REM copy /y %~dp0\mailaddress.ini c:\temp
echo;
set /p MAILADDRESS="Microsoft365のメールアドレスを入力して下さい>"
echo %MAILADDRESS%>c:\temp\mailaddress.ini
echo;
echo 入力したメールアドレス：%MAILADDRESS%
echo;
Schtasks /delete /TN "OutlookAuth" /F > nul 2>&1
Schtasks /Create /TN "OutlookAuth" /SC ONEVENT /EC Application /MO "*[System[Provider[@Name='Outlook'] and (Level=4 or Level=0) and (EventID=63)]]" /TR "powershell.exe -noprofile -WindowStyle Minimized -executionpolicy ByPass -file c:\temp\AzureADauth.ps1"

echo;
echo Outlook起動時認証のセットアップが完了しました。
echo Outlookを終了して、起動し直してみて下さい。
echo;
echo メールアドレスを間違えた場合は、このSetup.batを再実行して下さい。
echo そうすると、設定が上書きされます。
echo;
echo 何かキーを押すと終了します。。。
pause > nul
```
Docker ComposeのRHEL7への導入

Docker ComposeをRHEL7に導入します。
以下のマニュアルを参考にしました。

https://docs.docker.com/compose/install/

■環境
RHEL 7.9
Docker 1.13.1-203.git0be3e21.el7_9
Docker Compose 1.28.5

## 前提環境の準備

dockerが導入されていることを以下で確認します。

```bash:コマンド
yum list installed|grep docker
```

```console:結果
[root@anaconda yum.repos.d]# yum list installed|grep docker
docker.x86_64                  2:1.13.1-203.git0be3e21.el7_9 @rhel-7-server-extras-rpms
docker-client.x86_64           2:1.13.1-203.git0be3e21.el7_9 @rhel-7-server-extras-rpms
docker-common.x86_64           2:1.13.1-203.git0be3e21.el7_9 @rhel-7-server-extras-rpms
docker-rhel-push-plugin.x86_64 2:1.13.1-203.git0be3e21.el7_9 @rhel-7-server-extras-rpms
[root@anaconda yum.repos.d]#
```



## 導入
以下のサイトに行くと安定板をダウンロードするコマンドがあります。

https://docs.docker.com/compose/install/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/f8c92bbc-5aa5-b6e8-c165-91544dff35cc.png)

上のサイトのコマンドでDocker Composeの現在の安定版リリースをダウンロードします。

```bash:コマンド
sudo curl -L "https://github.com/docker/compose/releases/download/1.28.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
```
```console:結果
[root@anaconda yum.repos.d]# sudo curl -L "https://github.com/docker/compose/releases/download/1.28.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   633  100   633    0     0   1422      0 --:--:-- --:--:-- --:--:--  1425
100 11.6M  100 11.6M    0     0  3589k      0  0:00:03  0:00:03 --:--:-- 4671k
[root@anaconda yum.repos.d]#
```

バイナリに実行可能なパーミッションを適用します。
/usr/binへのシンボリックリンクを作成します


```bash:コマンド
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
```
```console:結果
[root@anaconda yum.repos.d]# sudo chmod +x /usr/local/bin/docker-compose
[root@anaconda yum.repos.d]# sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
[root@anaconda yum.repos.d]#
```

## 導入の確認

導入の確認としてバージョンの確認をします

```bash:コマンド
docker-compose --version
```
```console:結果
[root@anaconda yum.repos.d]# docker-compose --version
docker-compose version 1.28.5, build c4eb3a1f
[root@anaconda yum.repos.d]#
```
GitLabから特定のファイルのみを取得するための手順(sparse-checkout)

##sparse-checkoutとは？
spareとは、「わずかな」「希薄な」という意味がある。
（参考）
https://eow.alc.co.jp/search?q=sparse

checkoutとは、ワーキングディレクトリを特定の状態に変更するためのコマンドを指す。
（参考）
https://kitsune.blog/git-command#checkout%EF%BC%88%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%82%A2%E3%82%A6%E3%83%88%EF%BC%89%E3%81%A8%E3%81%AF

つまり、わずかな変化（今回の場合だとリポジトリ内の一部のファイル取得）が起こった状態にcheckout（変更する）という意味になる。

##作業手順


以下は、カレントディレクトリがローカルリポジトリであることを前提とする

1.SPARSE CHECKOUTを有効にするために以下のコマンドを実行。

```
git config core.sparsecheckout true
```
参考
https://git-scm.com/docs/git-read-tree#_sparse_checkout

2.設定の一覧表示を確認するために以下のコマンドを実行。

```



git config -l
```

参考
https://note.nkmk.me/git-config-setting/

3.〜するために、git/info以下にsparse-checkoutという名前のファイルを作成。


```
vi .git/info/sparse-checkout
```
参考
https://git-scm.com/docs/git-read-tree#_sparse_checkout

4.リポジトリから得たいファイルをsparse-checkoutに記述する

``` :sparse-checkout
aaa #aaaを対象ファイルに指定
！/hoge/bbb #hoge/bbbは対象から除外

```
5.下記コマンドで、現在のローカルリポジトリに指定したリモートリポジトリを追加します。

```
git remote add origin リモートリポジトリの場所
```
参考
https://www.atmarkit.co.jp/ait/articles/2005/08/news017.html

6.リモートリポジトリの変更内容をローカルリポジトリに反映するために下記コマンドを実行

```
git pull リモートの名前 ブランチの名前
```

参考
https://www.atmarkit.co.jp/ait/articles/2003/06/news019.html




作業全体を通しての参考
https://qiita.com/shimamchan/items/88f6d0ad6231faea762a
https://leico.github.io/TechnicalNote/Git/sparse-checkout
祝★AWS Fault Injection Simulator

昨年のre:Inventで発表された中で個人的に注目していたサービス、「AWS Fault Injection Simulator（以降、FISと記載）」がリリースされました。

## What is "AWS Fault Injection Simulator"
一言で言えば、マネージドなカオスエンジニアリングサービスです。

https://aws.amazon.com/jp/blogs/aws/aws-fault-injection-simulator-use-controlled-experiments-to-boost-resilience/

EC2を落としたり、RDSをフェイルオーバーさせたり、OSにコマンドを送って負荷をかけたりといったことが実現可能です。

Get Started（ハンズオン的チュートリアル）(*1)も用意されているので、設定方法は割愛します。
ここでは、あくまで個人的に感じるFISの導入メリットを記載したいと思います。

## デメリット(?)
その前に、先立ってデメリット。
「追加コストがかかる」
この一点だけだと思います。FISはアクション時間に対しコストがかかります(*2)。
$0.10 per action-minute
ざっと見る限り、ほとんどのアクションはAPIやスクリプトで実現できそうなので、自前でもよく似たことは実現できそう。

## メリット
ここからが本題。
以下のような利点が挙げられます。

### 再実行が容易
テストシナリオはテンプレートとして保存可能です。
テンプレートを指定して、簡単に再実行可能です。
億劫になりがちな障害テストを簡単に実行できることが、品質の向上につながります。

### テスト対象のコントロール
リソースIDやタグなどで、簡単にテスト対象を定義することが可能です。

### セキュア
障害訓練を実行するために必要となるIAMポリシーは、強い権限になりがちです。
FISではAssume Roleの機構を使った権限の譲渡を、ユーザー側で作る必要なく実現できます。

### 実行履歴の管理
過去のテスト実施記録をコンソールなどで簡単に閲覧できます。
これは、ガバナンス構築の面で非常に強力なツールになります。

### （必要に応じて）後片付け
テスト後の環境ロールバック処理なども設定しておくことが可能です。

## まとめ
メリットを眺めて、そんなの昔から自前実装でやっているよ！って方もおられるかも知れません。
確かに、冒頭でも書いたとおり、自前でほぼ同じことは実現可能です。
または、すでにカオスエンジニアリングサービスを使って実現している方も一定数おられると思います。（実は自分自身も）
ただ、事前の知識がなくとも、これらのテストが行えるようになったことは、カオスエンジニアリングがさらに普及する上で、非常にいいサービスではなかろうかと思っています。
デメリットとして書いた料金の十分元を取れるサービスではないかと思っています。

Well-Architected Frameworkでも推奨されるカオスエンジニアリング、是非お試しいただければと思います！

## 参照
(*1) https://docs.aws.amazon.com/fis/latest/userguide/getting-started.html
(*2) https://aws.amazon.com/jp/fis/pricing/
Rubyのnilについて

参考文献 プロを目指す人のためのRuby入門より
参考サイト▶︎[Rubyリファレンスマニュアルより](https://docs.ruby-lang.org/ja/latest/class/NilClass.html)
参考記事▶︎[Ruby の nil は無か？](https://qiita.com/scivola/items/da2480ca4597a7dcf73d)

間違いあればご指摘いただければ幸いです。

## はじめに
Rubyはオブジェクト指向言語であり、文字列や配列、数値に関しても、全てがオブジェクトです。

そして今回焦点を当てる**「nil」**もオブジェクトの一つです。

# nilとは？
nil は**何かが存在しないことを表すために用いられるオブジェクト**のことです。
お恥ずかしながら、つい先程まで「nil」とは、何も存在しないことだと認識をしていましたがこれは間違いです。
存在してないことを教えてくれる役割も持っています。

# 真偽値のnil
Rubyの特徴とも言える真偽値のnilについてです。

Rubyでは真偽値のルールとして、以下の2点があります。

- false または nilであれば偽
- それ以外は全て真(trueそのもの、全ての数値、全ての文字列など)

このルールは他のプログラミング言語で該当しないそうです。Ruby独自のルールなんですね。
[各言語におけるtrue/falseまとめ](https://blog.mirakui.com/entry/20090604/truefalse)

# ?のつくnil
Rubyのメソッド名は?をつけることができます。
?をつけることでどうなるのかというと、**真偽値を返すメソッド**になります。

```ruby:
#オブジェクトがnilならtrue、そうでなければfalse
nil.nil? #=> true
```

これはnilに限ったことでなく、Rubyで最初から用意されているものにもいくつか存在します。
今回はnilにコミットしているので割愛しますので、参考記事を貼っておきます。
**nil?, empty?, blank? の違い▶︎**[参考記事](https://yu8mada.com/2018/04/26/difference-between-nil-empty-and-blank-in-rails/)

# NilClass
nilのクラスのことです。
nilはNilClassクラスの唯一のインスタンスになります。
nilもオブジェクトの一つという認識があれば違和感は感じないことと思います。
実際に、期待した値がなかった場合などに「nil」を返してくれますよね。
ChromeDriverをpipでバージョン指定してインストールする手順

###はじめに
・ChromeDriverのインストールは、pipを使用すればパスを通す必要が無い(import文で参照するだけで使用可能となる）。
・ChromeDriverは、使用しているChromeのバージョンに対応したバージョンをインストールする必要がある。

これらの理由により、ChromeDriverのインストールは、pipを使用してバージョン指定で行うのがよい。本記事に手順をまとめる。

###インストール手順
1. Chromeのバージョン確認
2. インストールすべきChromeDriverのバージョンの確認
3. ChromeDriverのインストール(pip使用 & バージョン指定）

###1.　Chromeのバージョン確認

Chromeにて、以下の手順でバージョンを表示する。
「設定→ヘルプ→Google Chromeについて」

![キャプチャ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608141/dc96fc4b-3c48-6200-cff8-9b1d9b7772c5.png)

今回の例では、Chromeのバージョンは `89` となる。

###2. インストールすべきChromeDriverのバージョンの確認

[ChromeDriver - WebDriver for Chrome  のページ]
(http://chromedriver.chromium.org/downloads) にて、使用しているChromeに対してインストールすべきバージョンを確認する。

![キャプチャ4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608141/8679aed5-c56d-e03d-bc50-a3c22f5f2e16.png)

###3. ChromeDriverのインストール(pip使用 & バージョン指定）

pipでバージョンを指定してインストールするコマンドは、下記の通り。
`pip install chromedriver-binary==<ChromeDriverバージョン番号>`

今回の例では、下記のコマンドとなる。

```
pip install chromedriver-binary==89.0.4389.23
```
### 動作方法
import文を使用したChromeDriverの動作方法は、[こちらの記事](https://qiita.com/ten_to_ten/items/f8946450338a6f8bcd46)のサンプルコード1を参照。
gradleの複数のrepositoryが複数ドメインにまたがる場合のエラーの対処

以下のようにすると、依存性の解決が上手く行かない場合がある。

```gradle
maven {
  url "https://hoge.com/"
  url "https://foorba.com/"
}
```

その場合は以下のように修正する。

```gradle
maven {url "https://hoge.com/"}
maven {url "https://foorba.com/"}
```
Discordで通話しながらゲームをする環境構築

# はじめに
みなさん、コロナ禍の中いかがお過ごしでしょうか？
友人と直接会う機会が減るなか、ZoomやDiscordを用いて会話する機会も多いと思います.
すると自然とZoomやDiscordで会話をしながらゲームをプレイしたくなるのですが, 快適なプレイ環境の構築は少し面倒です.
今回はDiscordやZoomで会話しながらゲームをする方法について解説していきたいと思います.

## 前提条件
* ゲームの音をヘッドフォンで聞く
* Discordもヘッドフォンで聞く
* 自分の音声を拾うマイクは用意してある

## PCゲーム
PCゲームの場合特に工夫する必要はなくマイクとヘッド本を用意して, ゲームを起動しているPCでDiscordを起動すれば問題なくボイスチャットを楽しむことが出来ます.
もともとDiscordはゲームのボイスチャット用に開発されているため非常に快適にプレイすることが出来るでしょう.
また、ゲーム画面の配信も「画面の共有」から簡単に行うことが出来ます.

## 据え置き型ゲーム

### ゲーム音とボイスチャットの共存
Nintendo SwitchやPS4といったゲーム専用機でプレイする場合、Discordで通話を行いながらゲームをプレイするには一工夫が必要です.
今回はNintendo Switchを例にとって説明していきます.
以下の図のように配線を行うとDiscordとswitchの共存が可能です. ![スクリーンショット (29).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251724/42a9da51-0a7b-70be-e4c0-f85c0cdadccd.png)
Nintendo Switchはヘッドホン出力を持っていますが, このヘッドホン出力はHDMI出力時にノイズが載ってしまうことが知られています.
そのためSwitchからHDMIを用いて出力した音声をモニターで受けとり, モニターのライン出力からPCに入力することが重要です.
また, Switchに用いるモニターをPCで用いるモニターと同一のものを用いる場合, 適宜モニター側で入力を切り替える必要があります.
デュアルディスプレイならばそれらの問題は発生しません.

### ゲーム画面のキャプチャ
ゲーム画面をキャプチャして録画したり配信したりする場合, 以下のようにキャプチャーボードを配置することでSwitchのHDMI出力をキャプチャすることが出来ます. 受け取ったHDMIをそのまま出力するパススルー出力機能が付いたキャプチャーボードを用いることで, ゲーム画面を遅延なく表示させることが出来ます. 
![スクリーンショット (31).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251724/f8b71e0e-c600-3160-8b15-3a8bacc8497e.png)
キャプチャーボードからのゲーム音は少し遅延していますが, キャプチャーボード経由のゲーム音ではなく, モニター経由のゲーム音を聞くと遅延なくゲーム音を聞くことが可能です. 
多少の音声遅延を許容する場合、キャプチャーボード経由の音を聞くこともできます. その場合, ライン入力端子は必要ありません

### Discordにおけるゲーム画面の共有
Discordの「画面の共有」機能でキャプチャしたゲーム画面とゲーム音声を共有することもできます. 今回はobsという配信界隈では有名なソフトを用いた方法を紹介します.
シンプルにOBSでキャプチャした画面を流していると, キャプチャーボード経由のゲーム音がヘッドホン出力されます. キャプチャーボード経由でゲーム音を聞いている場合, それで問題なく配信可能です. ライン入力経由で音声を聞いている場合, キャプチャーボード経由のゲーム音をヘッドホン出力せず Discordの配信には載せる必要があります. そのためには少し工夫をする必要があります. 以下にその手順を示します. 

* OBS上のソースに映像キャプチャデバイスを追加
* 映像キャプチャデバイスのプロパティを開き, 音声出力モードを「音声のみキャプチャ」に, カスタム音声デバイスを使用するにチェックを入れ, 音声デバイスをキャプチャボードにする. 
* 設定->音声->詳細設定->モニタリングデバイス をモニター等の使用していない出力に変更
* 音声ミキサー上で右クリックをしてオーディオの詳細プロパティを開き, 映像キャプチャデバイスの音声モニタリングを「モニターと出力」に変更
* OBSを再起動する（再起動しないと設定が反映されないことがよくある）
* 画面上部のゲーム画面を右クリックし, 全画面プロジェクター（プレビュー)を選択
* Dicordの「画面を共有」で全画面プロジェクター（プレビュー）を共有する
【Swift】FloatingPanelを使った、取っ手のないハーフモーダル実装と背景タップで閉じる処理

# どういうことか

こういうのを作る。

![Simulator Screen Shot - iPhone 11 Pro Max - 2021-03-16 at 16.42.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413699/0edaade6-5ebf-7eb8-f238-3fd4d59c5761.png)

よくあるドラムロール（PickerView）に見えるが、xibでUIを作ってハーフモーダルに載せている（TextFieldを使った実装だとバグることがあってよくないみたい）。

## 取っ手を非表示にする

取っ手（ハンドル？棒？伝わりやすい名前はなんだろう）を非表示にする。

```swift
let fpc = FloatingPanelController()
    
fpc.surfaceView.grabberHandle.isHidden = true
```

## 背景をタップで閉じる

モーダルの外をタップすると閉じる。

```swift
let fpc = FloatingPanelController()
    
fpc.backdropView.dismissalTapGestureRecognizer.isEnabled = true
```

おわり(´・ω・｀)
shopify構築で詰まったところ

# Shopify構築の備忘録

## 開発環境を整える

## 問題①ターミナル
OSがbic sur になってからhomebrewを触っていなかったため、
アップデートが必要がことに気がついた。

```
brew tap shopify/shopify
brew install themekit

```

をやってもthemeコマンドが使えない。

### 理由

big sur版のhomebrewの対応していなかった

### 解決策

```
sudo rm -rf /Library/Developer/CommandLineTools
```

ターミナルの問題はどうにかなった。
 
## 問題②
しかし、次はAPIの許可が降りていないという問題に直面。

### 原因
テーマのAPIの許可がをしていないかった

### 解決策
ここを読み取り及び書き込みにすること
![スクリーンショット 2021-03-16 16.55.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1211264/47de60eb-feba-cafa-0082-63f6f9e70bd9.png)

https://cloud6.net/so/shopify/1854175


参考記事
shopifyを勉強するためのudemy
https://www.udemy.com/course/master-shopify/

big sur版のhomebrewの環境
https://www.yokoweb.net/2020/12/05/homebrew-clt-macos11-error/

shopifyの環境
https://shopify.dev/tools/theme-kit/command-reference
【Railsチュートリアル】第13章 ユーザーのマイクロポスト④

# 13.4 マイクロポストの画像投稿
* 画像付きマイクロポストを投稿できるようにする

## 13.4.1 基本的な画像アップロード
* Railsに組み込まれているActive Storageという機能を用いる

### 演習 1
画像付きのマイクロポストを投稿してみましょう。もしかして、大きすぎる画像が表示されてしまいましたか?（心配しないでください、次の13.4.3でこの問題を直します）。

確認のみなので省略。


### 演習 2
リスト 13.64に示すテンプレートを参考に、13.4で実装した画像アップローダーをテストしてください。テストの準備として、まずはサンプル画像をfixtureディレクトリに追加してください（リスト 13.63）。リスト 13.64で追加したテストでは、Homeページにあるファイルアップロードと、投稿に成功した時に画像が表示されているかどうかをチェックしています。なお、テスト内にあるfixture_file_uploadというメソッドは、fixtureで定義されたファイルをアップロードする特別なメソッドです18 。ヒント: image属性が有効かどうかを確かめるときは、11.3.3で紹介したassignsメソッドを使ってください。このメソッドを使うと、投稿に成功した後にcreateアクション内のマイクロポストにアクセスするようになります。

```ruby:test/integration/microposts_interface_test.rb
require 'test_helper'

class MicropostInterfaceTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:michael)
  end

  test "micropost interface" do
    log_in_as(@user)
    get root_path
    assert_select 'div.pagination'
    assert_select 'input[type="file"]'
    # 無効な送信
    assert_no_difference 'Micropost.count' do
      post microposts_path, params: { micropost: { content: "" } }
    end
    assert_select 'div#error_explanation'
    assert_select 'a[href=?]', '/?page=2'  # 正しいページネーションリンク
    # 有効な送信
    content = "This micropost really ties the room together"
    image = fixture_file_upload('test/fixtures/kitten.jpg', 'image/jpeg')
    assert_difference 'Micropost.count', 1 do
      post microposts_path, params: { micropost:
                                      { content: content, image: image } }
    end
    assert FILL_IN.image.attached?
    follow_redirect!
    assert_match content, response.body
    # 投稿を削除する
    assert_select 'a', text: 'delete'
    first_micropost = @user.microposts.paginate(page: 1).first
    assert_difference 'Micropost.count', -1 do
      delete micropost_path(first_micropost)
    end
    # 違うユーザーのプロフィールにアクセスする
    get user_path(users(:archer))
    assert_select 'a', { text: 'delete', count: 0 }
  end
  .
  .
  .
end
```

## 13.4.2 画像の検証
### 演習 1
5MB以上の画像ファイルを送信しようとした場合、どうなりますか?
エラーが出る。

### 演習 2
無効な拡張子のファイルを送信しようとした場合、どうなりますか?
そもそも無効な拡張子を選ぶことができない。
（たぶん）エラーが出る（はず）。

## 13.4.3 画像のリサイズ
### 演習 1
解像度の高い画像をアップロードし、リサイズされているかどうか確認してみましょう。画像が長方形だった場合、リサイズはうまく行われているでしょうか?

確認のみなので省略

## 13.4.4 本番環境での画像アップロード
### 演習 1
本番環境で解像度の高い画像をアップロードし、適切にリサイズされているか確認してみましょう。長方形の画像であっても、適切にリサイズされていますか?

確認のみなので省略。

# さいごに
やりごたえのある章が終わりました。
ここまできて得たものは
1. エラーに屈しなくなった
2. コードを一行ずつ読むようになった
3. 学習をはじめた頃と比べてコードを読める（ふりがなをふれる）ようになったこと

これからは、上記に加えてコードを書けるように努力していきたいです。
さぁ、いよいよ最終章です！
Apache Windowsサービスから削除

# 作業前

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/2a47dac4-2a47-a900-1322-2e750a4362a1.png)

# 手順

`Apache24/bin`などhttpd.exeがあるディレクトリで以下のコマンドを実行する。

```console
httpd -k uninstall
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/edaff969-e6a2-6f7b-93cc-90600de95813.png)

# 作業後

Apacheのサービスが消えた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/4195b2e7-2251-2895-87e5-c6b66679338c.png)
cssで文が入り切らなかったとき

今回はcssで一文が入り切らなかったときの方法を学習していきます。
まず、HTMLに記入していきます。

```index.html
div class="form">
    <h1 class="title">ピエン</h1>
    <p>ピエンピエンピエンピエンピエンピエンピエン</p>
  </div>
```
```style.css
.form {
  border: 4px solid black;
  width: 10%;
}


p {
  border: 2px solid pink;

}
```
![スクリーンショット 2021-03-16 16.22.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/6b2a15b8-307e-f542-9858-10180488beb7.png)

pタグのピエンが入りきっていませんね。
それでは、ここで1行で収めたいと思います。

```style.css
p {
  border: 2px solid pink;
  overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;

}
```
ブラウザで表示してみましょう。
![スクリーンショット 2021-03-16 16.24.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/4180418b-80b8-b611-c887-41e732ae35d7.png)

はい、入り切りましたね。

#①overflow
これは、要素内に入り切らなかったときに使います。
いくつか種類がありますが、ここでは割愛していきます。
引用▶https://developer.mozilla.org/ja/docs/Web/CSS/overflow
![スクリーンショット 2021-03-16 16.29.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/1dae320c-8200-b39f-389e-2d31d2cd3c6c.png)

#②text-overflow
これは、非表示にした部分をユーザーにどのように表示されるのかを表します。いくつか種類がありますが、今回も割愛していきます。
引用▶https://developer.mozilla.org/ja/docs/Web/CSS/text-overflow

![スクリーンショット 2021-03-16 16.33.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/dedc9539-da33-38ea-dac5-fb2cfd724377.png)

#③white-space
こちらは要素内のスペースをどうするか決めることができます。
引用▶https://developer.mozilla.org/ja/docs/Web/CSS/white-space
![スクリーンショット 2021-03-16 16.35.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/12e7691b-2f78-e29c-fa61-9fd3c4999325.png)

色々あるので、試してみましょう👍
IBM Cloud（小ネタ）: VPCでstop/startをしてもUUIDは変更されなくなった

以前は、VPCでstop/startをしたらUUIDは変更されていたが、[2021/08/17のrelease notes](https://cloud.ibm.com/docs/vpc?topic=vpc-release-notes)によるとUUIDは変更されなくなったようだ。
バックアップソフトウェア（例えばVeeamなど）によっては、UUIDを元に同一サーバーであるかどうかを識別しているため、Stop/Start以外にもシステムメンテナンスによる強制停止・開始でも同様にUUIDが変更されてしまって、バックアップジョブを再登録する必要があったという問題があった。今回の仕様変更によってこうした問題が改善されたことはありがたい。

> Instance Identifier Update: The instance identifier (ID) now includes the SMBIOS system-uuid as a portion of the ID. The ID, including the SMBIOS system-uuid portion, is static and persists for the lifecycle of the virtual server instance until that virtual server instance is deleted. For more information, including how to retrieve this information from within your virtual server, see Retrieving the virtual server instance identifier section in Managing virtual server instances.

本稿は元々UUIDがstop/startによって変更されるということを紹介する記事だったが、これを受けて書き直すことにした。以下は実験例。

#1. 事前状態

```txt:Stop/Start前
# cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)

# dmidecode -s system-family
02e7_fe6b34c2-7609-47b6-8f62-b7aa0207ec8b
# dmidecode -s system-uuid
fe6b34c2-7609-47b6-8f62-b7aa0207ec8b
# cat /sys/devices/virtual/dmi/id/product_uuid
FE6B34C2-7609-47B6-8F62-B7AA0207EC8B
```

#2. IBM Cloud ConsoleからStopおよびStartの実行

- Stop<br> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/c31ae901-7f9f-65a2-e3ed-841d9ea0c6ec.png)
- Start<br> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/9ccd24a1-5841-51f0-52bb-770e99462b42.png)

#3. Stop/Start後の再確認（以前と違い、UUIDが変更されていない！）

```txt:Stop/Start後
# cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)

# dmidecode -s system-family
02e7_fe6b34c2-7609-47b6-8f62-b7aa0207ec8b
# dmidecode -s system-uuid
fe6b34c2-7609-47b6-8f62-b7aa0207ec8b
# cat /sys/devices/virtual/dmi/id/product_uuid
FE6B34C2-7609-47B6-8F62-B7AA0207EC8B

```
はじめてのLaravel環境構築（Docker）

###開発環境
**Docker環境**
* PHP 7.4-fpm
* Composer 2
* NginX 1.15.6
* MySQL 8.0.19

###以下を参照
DockerでLaravel環境を構築する①〜③
https://qiita.com/wjtnk/items/9d6a56a05bff2068cd2c
https://qiita.com/wjtnk/items/fa2b9d848bc64261d0e9
https://qiita.com/wjtnk/items/9e553f90f38e279a8b99

##NginXの設定ファイルについて詳しい説明がなかった為、解説してみる

```conf:default.conf
  server {
    listen 80; #IPとポートを指定する

    root  /var/www/html/laravel-app(プロジェクト名)/public; #ドキュメントルートを指定する
    index index.php index.html;　#index.phpがあればindex.php,なければindex.htmlを表示、なければエラーを返す

    access_log /var/log/nginx/access.log; #アクセスログの出力先のファイル名　
    error_log  /var/log/nginx/error.log; #エラーログの出力先のファイル名　デフォルトはerror以上のログのみ

    location / { #URIパス毎に設定ができる
        try_files $uri $uri/index.php; 
        #まずは指定したURIのファイルにアクセス->なければURIのディレクトリ内のindex.phpを探す->なければエラーを返す
    }

    location ~ \.php$ {　#PHPファイルのみの設定
          fastcgi_split_path_info ^(.+\.php)(/.+)$; #fastcgi_paramでキャプチャする正規表現を定義
          fastcgi_pass   app:9000; # FastCGI サーバへリクエストをプロキシする
          fastcgi_index  index.php; # $fastcgi_script_name の値になる
             
          include        fastcgi_params; #設定ファイルを読み込む
          # FastCGI サーバに渡されるべきパラメータを設定
          fastcgi_param SCRIPT_FILENAME $document_root/index.php; ##！！変更点！！
          fastcgi_param  PATH_INFO $fastcgi_path_info;
      }
}
```
**追記**
20行目は記事通りだと上手くいかなかった。
Laravelのroutingした通りに動かず、'File not Found'と表示される。
以下の記事の通り変更し、今度はうまく表示された。

https://qiita.com/mk-tool/items/0faff98d4108824b50ba

記事に従ってDockerを立ち上げてみる。
うまくいったようだ。

##Laravelのインストール

```zsh
$  docker-compose exec app composer create-project laravel/laravel --prefer-dist myblog
```

脱線するけど、--prefer-distって何？


https://kin29.info/composer-%E3%81%AE-prefer-dist%E3%81%A3%E3%81%A6%E3%82%88%E3%81%8F%E4%BD%BF%E3%81%86%E3%81%91%E3%81%A9%E4%BD%95%E3%81%97%E3%81%A6%E3%82%8B%EF%BC%9F/

composerのオプションらしい。
zipファイルだから高速でダウンロードできる。

インストールできたら、プロジェクト名のディレクトリが出来ているはずなので、そのディレクトリに移動する（今回はmyblogディレクトリ）。
以下のようにしてちゃんとインストールされているか確認。

```zsh
$ php artisan --version
```

結果、
Laravel Framework 8.32.1
と出たので正常にインストールできた。
[Flutter]  画面遷移元によって画面遷移先を分岐させる

複数のページから画面遷移される共通のページを作成し、その共通のページからの画面遷移をする際に、画面遷移先を共通ページの前の画面によって変えたい場合のやり方を調べて実装したので共有します。

##画面遷移元のページ
```dart
Navigator.pushNamed(context, NEXT_PATH, arguments: "/hoge/hoge/hoge");
```
まずは、画面遷移の際に、上記のように第三引数で次のページで使用するパスを渡すようにします。

##共通のページ
```dart
 Widget build(BuildContext context) {
    final String NEXT_PATH = ModalRoute.of(context).settings.arguments;
    Navigator.pushNamed(context, NEXT_PATH);
```
そして、上記のように受け取った値を次の画面遷移のパスに指定することで、画面遷移元によって、遷移先を指定することができます。


###参考
[Flutterでアプリ開発・画面間でデータを渡す – ギャップロ](https://gaprot.jp/2020/10/13/flutter-data-delivery/)

###会社の紹介
私は現在、[株式会社ダイアログ](https://www.dialog-inc.com/)という物流×ITの会社に勤務しております。
様々な職種を募集しているので、[Wantedly](https://www.wantedly.com/companies/company_3244501)のページをご覧ください。
文系ガチ未経験のエンジニア就活について

##はじめに
はじめまして、こんにちは。
この度Qiita初投稿でございます。

この記事は文系でホントなんの経験もないけどIT業界で一般によく知られたweb/スマホアプリ開発、もしくは企業向けのシステム開発をする企業のエンジニアとして仕事したいなーと考えている方向けのものとなります。
実体験をもとに書いておりますので、心当たりがある方にはぜひお読みいただきたいです。

##自己紹介
私は現在大学3年の終わり、就活期真っ只中でございます。
私はpaizaというサイトで競技プログラミングのe-larningを3か月ほど行い、
同サイトでBランクをゲットしました。
ランクをもとに割とバシバシスカウトが来るので、時間に余裕のあるエンジニア志望の方にはおススメです。有料ですが。
そして舞い上がった私は意気揚々と面接に臨んだわけです。

結果は...まー無残に撃沈。　(現状)

どの面接でも主体性と意欲、コミュ力は評価していただけるのですが、
カジュアル面談(初期段階)での落選を連発しておりました。

フィードバックに書かれるのは「スキル不足」の文字。
いや足きりラインは超えてるやないかい！次だ次！と思ったのですが、
どうもそうじゃないみたいなんですよね。

##敗因
先ほどの面談で企業の方にお聞きしたのがズバリ、
個人の勉強のみならず、開発実績なり、ブログなり、
アウトプットをした経験がとっっっっっても大事とのこと。

・自分で環境を作って何か作り、Githubなるサイトにあげる。
・Qiitaに学んだことをまとめた記事を書く。
・その他ブログで自分の実績(競技プログラミングでわからない点や、開発で困ったことなどでも可)を書く。

仮にたいしたことではなくても、これは必ずやっておいたほうがいいと
某メガベンチャーの企業の方は仰ってました。
その理由として、「エンジニアの世界に入る覚悟がどれだけあるか」を
見ているとその方は仰っていました。
私は競技プログラミングにどれだけ取り組んだかでアピールできると考えていましたが、どうやらそうではなく

「世の中にある問題をどういう風に解決したいと考え、実行したのか？」
が大事なんだそうです。なるほど。

以上です。
あと、ITという業界の中でもなぜ金融向けなのか、人材系なのか、などを
しっかり考えて志望動機を書くこと。
これが君はできてないと指摘されました。

##つまり何をすればいいのか？
私の考えですが、就職活動までの期間にもよりますが、
初めてプログラミングに触れる方はやはりe-larningのサイトで勉強するといいと思います。有料ですが、将来やりたい仕事で稼いで取り返すくらいの
気持ちでやってください。悩んでいる時間が勿体ないです。
何をやっていいかわからない方は、シェルコマンド→アプリ開発＋使う言語
みたいな感じで学べばいいのではないかなと思います。

それと並行して初心者でも○○が作れる！みたいな本も買って、何か興味を持ったものを作りましょう。
ネットで調べても多分作れますが、調べるのが大変です。


ついでに、どこから始めていいのかわからない～><という方も、自分の技術には大いに自信ありけり！という方も、
twitterなりQiitaなりGithubなりなんなり、「よくわからないから...」という気持ちを捨てて、エンジニアの世界に触れることから始めましょう。
そして、技術職を目指すからにはIT業界という大きなくくりだけではなく、エンジニアが何をしているのか？
エンジニアはどういうものを作っているのか？を考えましょう。
私もそうします。就職に間に合うかわかりませんが。

##追記:
あれから約2ケ月。
なんとかうまく行ってます。
受託のみのSIerと大手の100%子会社(web系)の内定をいただき、大手SIer(自社開発製品中心)とSESの最終面接結果待ちです。

成功要因は、
・真面目に自己分析したこと。
・文系なのになんでIT業界に？なんでプログラミングやったの？について筋が通るように説明したこと。
・プログラミングスキルについて言語化したこと(繰り返し文何個組み合わせたアルゴリズムが組める など)
・会社ごとの入社後の自分のキャリアをしっかり考えたこと。
と考えています。

ただ、某企業の役員の方からのフィードバックに、
「IT業界に興味を持ってから行動を起こしたのがよかった」というものがあったので、
やっぱりプログラミングの勉強した具体的なエピソードは就活に役立ちます。
あと基礎情報とかの資格勉強はまだ取得できてなくてもアピールポイントになるかと。おまけ程度ではありますが。

##まとめ
ということで、私の犯した過ち(競プロでランク上げていい気になる)と
同じ轍を踏まないように頑張ってください！

今後は秘蔵のメモからPythonの環境構築だったり競技プログラミングの知識だったり、初心者なりに初心者がつまずきやすそうな
部分についての解説記事とかあげていこうと思います。

ここまで読んでくださった方、お疲れさまでした！
Xplentyでよく行われる文字列操作（関数を使用した変換処理）

このブログでは、Xplentyでよく行われる文字列などの変換処理について解説します。
※今後、新しいケースがあれば、こちらのブログに随時追加していく予定です。

#よく行われる文字列操作
##Q1. 氏名を姓(Last Name)と名(First Name)に分けるには？
**STRSPLIT**関数を使用することで、区切り文字を指定し、文字列を分割して取得することが可能です。
例：field1:田中　太郎
`STRSPLIT(field1,' ').$0`
==> 田中
`STRSPLIT(field1,' ').$1`
==> 太郎

##Q2. 値がひらがなの場合のみ取得するには？
**REGEX_EXTRACT**関数を使用することで、正規表現を使用し、ひらがなおよび半角/全角スペースを含む文字列を取得することが可能です。
`REGEX_EXTRACT(field1,'[ぁ-ん( |　)]+',0)` 
例：field1:やまだ たろう
==> やまだ たろう
例：field1:山田　太郎
==> null

##Q3. 住所を分けるには?
Xplentyでは完全に実現することは難しいですが、以下のような方法で番地部分を分けることが可能です。
Xplentyでは、正規表現を使用して条件にマッチした部分のみを取得することが可能です。

###1. 都道府県部分を取得するには
**REGEX_EXTRACT**関数を使用し正規表現を使って、条件にマッチする部分を抽出します。
field1: 東京都港区六本木6-10-1
`REGEX_EXTRACT(field1,'(..都|..府|..道|([\u4E00-\u9FFF]{2,3})*県)',0)`
-> 東京都

###2. 上記以外の部分を取得
**INDEXOF**関数で、条件にマッチする文字列の場所を判定することが可能です。
field1: 東京都港区六本木6-10-1
field10: 東京都
`SUBSTRING(field1,INDEXOF(field1,field10)+Length(field10),Length(field3)) `
->港区六本木6-10-1

##Q4. Replace関数
###1. 通常文字列の置換
例）field1: '埼玉県埼玉市'
`REPLACE(field1,'埼玉市','さいたま市')`
-> 埼玉県さいたま市

###2. 一部の文字を除外する
文字列に含まれる「?」などの特殊な文字を置換する場合はエスケープ文字を利用する
?を除外したい場合は`\\?`とする
例）field1: '2022/?01/01'
`REPLACE(field1,'\\?','')`
-> '2022/01/01' 

###3. 改行コードの置換
Webアプリケーションデータなどに含まれる改行コードをDBに保存する際に改行コードとして保存するには?
例）field1='あああああああああああああ`<BR>`いいいいいいいいいいいいいいい'
`<BR>`部分をReplace関数を使用して、DBで設定されている文字コードに合わせて正しい改行コードに置換ください。
`REPLACE(field名,'<BR>','\r\n')`


##Q5. 半角カタカナを検知する
`CASE WHEN field1 MATCHES '.*[ｦ-ﾟ].*' THEN 'Y' ELSE 'N' END`

- field1の値が「あああアｱあ」　の場合 > Y
- field1の値が　「ああああアあ」　の場合 > N

##Q6. NULLの置換について
COALESCE関数もしくはCase文で可能です。

- Case文の例：`CASE WHEN field1 is null then 'なし' ELSE field1 END`

- COALESCE関数の例：`COALESCE(field1, 'なし')`
field1がNULLだった場合のみ２つ目の引数にセットされた値もしくは列（上記の例だと「なし」）がセットされる


#JSONの文字列操作
##Q1. JSONのBAG型データからネスト化された値を取得するには?
以下のような[]で複数の値をもつBAG型のデータをXplentyで扱う方法について紹介します。
`   [
        {
            "key": "first_name",
            "value": "Taro",
            "label": "FIRST NAME"
        },
       {
            "key": "last_name",
            "value": "Yamada",
            "label": "LAST NAME"
        },
        {
            "key": "gender",
            "value": "Male",
            "label": "GENDER",
            "is_required": "required",
            "datatype": "text"
        }
    ]`


BAG型のデータから必要な値だけを抽出する
ネスト化された値からパスを指定して取得するには、**JsonExtractScalar**関数を使用すると便利です。

FIRST NAMEを取得：`JsonExtractScalar(field名,'$.[0].value’)  > Taro`
LAST NAMEを取得：`JsonExtractScalar(field名,'$.[1].value’)  > Yamada`
GENDERを取得：`JsonExtractScalar(field名,'$.[1].value’)  > Male`
RailsでBigDecimal.new is deprecated; use BigDecimal() method instead.のエラーを解決した。

## なぜこのエラーが出るのか
> 内容的には BigDecimal.new は非推奨だから BigDecimal() 使えよってことです。
ruby v2.6 から BigDecimal.new は非推奨になっています。

<br>

僕の場合は、matcherがBigDecimal.newでした。

```
shoulda/matchers/active_model/validate_inclusion_of_matcher.rb:273:
warning: BigDecimal.new is deprecated; use BigDecimal() method instead.
```

これにぴったりのissueを見つけました。
https://github.com/thoughtbot/shoulda-matchers/pull/1070

## 解決方法

今のgemfileにあるmatcher

```ruby
group :test do
  gem 'shoulda-matchers',
    git: 'https://github.com/thoughtbot/shoulda-matchers.git',
    branch: 'rails-5'
```

公式を見ると、

```
 gem 'shoulda-matchers', '~> 4.0'
```
になっているから、それでbundle installをする。

[https://github.com/thoughtbot/shoulda-matchers](https://github.com/thoughtbot/shoulda-matchers)

```ruby
group :test do
  gem 'shoulda-matchers', '~> 4.0'
end
```
```ruby
rspec
....*****....................

Pending: (Failures listed here are expected and do not affect your suite's status)

  1) Comment add some examples to (or delete) /myapp/spec/models/comment_spec.rb
     # Not yet implemented
     # ./spec/models/comment_spec.rb:4

  2) Favorite add some examples to (or delete) /myapp/spec/models/favorite_spec.rb
     # Not yet implemented
     # ./spec/models/favorite_spec.rb:4

  3) Like add some examples to (or delete) /myapp/spec/models/like_spec.rb
     # Not yet implemented
     # ./spec/models/like_spec.rb:4

  4) PostTag add some examples to (or delete) /myapp/spec/models/post_tag_spec.rb
     # Not yet implemented
     # ./spec/models/post_tag_spec.rb:4

  5) Tag add some examples to (or delete) /myapp/spec/models/tag_spec.rb
     # Not yet implemented
     # ./spec/models/tag_spec.rb:4

Finished in 12.14 seconds (files took 3.48 seconds to load)
29 examples, 0 failures, 5 pending
```

無事warning: BigDecimal.new is deprecated; のエラーが消えていた。
Androidアプリ作成Tips

#はじめに
アプリ開発で忘れがちなアレコレを書いていきます。
個人的なメモとして残すので順序など適当な所も多いです。

##戻るボタンの簡単な実装
1. Buttonを配置してonClickのコールバックでfinish()を実行する。
2. AndroidManifest.xmlにandroid:parentActivityName属性を追加

```xml:2の記入例
    <activity
        android:name=".[戻るボタンを追加する対象]"
        android:parentActivityName="[App.Name].[親のアクティビティ]">
    </activity>
```

##Viewへのアクセス方法
###`findViewbyId`を使ったアクセス

```kotlin
val testTextView = findViewById<EditText>(R.id.testTextView)
testTextView = "Testです"
```

###`Kotlin Android Extension`でアクセス

```kotlin
testButtonView.setOnClickListener {
        testTextView.text = "Testです"
}
```
###`ViewBinding`を使ったアクセス *現在の公式推奨方法*
1.`app/build.gradle`にviewBinding設定を追加して`Sync`

```xml:app/build.gradle
android {
    .....
    buildFeatures {
        viewBinding = true
    }
    ....
}
```

2.アクティビティからのアクセス方法

```kotlin
class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding          // 追加
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)  // 追加
        setContentView(binding.root)                           // 追加    
        binding.testTextView.text = "Testです"
    }
}
```

##端末設定に関わらずライトモードを使用する
アンドロイドでは端末設定をダークモードにしている場合、アプリはそれに従ってしまいダークモードのカラーが設定されてしまう。
そうするとダークモード用のレイアウトを用意していないと意図しない配色になる可能性がある。
対策としてthemes.xmlの設定を変えてダークモードに非対応にすると良い。

parentの設定をTheme.MaterialComponents.Lightを継承させる。

```res/values/themes.xml
...
    <style name="Theme.MyPlot" parent="Theme.MaterialComponents.Light">
...
```
Qiitaに投稿する～本文の書き方～

##はじめに

　はじめまして、アウセです。Qiita初投稿しました。
　ここでひとまず、最初の記事として
　Qiitaに投稿するうえでの**「本文の書き方」**を自分なりに整理したいと思います。
　では、さっそく　ポチッポチッ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203650/da562694-1fa5-8a6e-5a9a-c809674ed4ab.png)
![win001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203650/adc83ead-bb19-388c-3cc7-6c03cd57c2a5.jpeg)
　注意：**コピーペーストせず**に入力した方が**キーボードを打つ時にためらわない**ので練習。

#見出しの付け方

```
#見出しの付け方
```

　**半角英数字＃(ハッシュ)**を最初に入力してから文字をうつと見出しができます。
　さらに、＃を増やすほど見出しが小さくなります。
##＃＃(2つ)見出し(ライン付けがここまで)
###＃＃＃(3つ)見出し
####＃＃＃＃(４つ)見出し
　ついでに**「ハッシュ（＃）」と「シャープ（♯）」**は別物で**シャープはお音符**です。

#太文字で協調
　太文字で協調→**太文字で協調**

```
**太文字で協調**
```
　*(アスタリスク/アスター)を2つずつ文字に囲めば太くなりキーワードとして強調されます。
　__(アンダーライン)2つ分でも同様。

#リンク付け
　[>>自分のマイページQiita](https://qiita.com/alce)

```
[>>自分のマイページ](https://qiita.com/alce)
```
　**[　]角カッコ**で閉じた文字列をリンクとして表示します。
　すぐ横に**( 　)の中にURL**を記述すればリンク先に飛ばせることができます。

#コードの記載(黒ワク)
　サーバ構築・運用の学習中なので**Linux/CentOSサーバのrootログインコード**を入れます。

```
CentOS Linux 7 (Core)

localhost login: root
```
　**上下に空行を挿入**しないと正しく表示されないことがある。
　**ソースコードの前後を「```」（バッククオート3つ）**で区切って書けば黒ワクで記載できる。
　実際は、こんな感じです。↓↓
>[空行]
> \`\`\`
>CentOS Linus 7 (Core)
>localhost login: root
>\`\`\`
>[空行]

　ちなみに、上記の**タテ線(引用ライン)**は、各行に>を最初にうてば表示できます。


>＞[空行]
>＞\`\`\`
>＞CentOS Linux 7 (Core)
>＞localhost login: root
>＞\`\`\`
>＞[空行]


#打ち消し線

　打消し線　→　~~打消し線~~

```
~~打消し線~~
```
　**～～(チルダ/チルダー/にょろ)**で囲めば打消し線を引けます。
#箇条書き
- 箇条書きテスト1
- 箇条書きテスト2


```
-箇条書きテスト1
-箇条書きテスト2
```
　行頭に**「-」を付け、文字列を入れる**と箇条書きにされる。
　また**「*」も使えるが、半角空白(スペース)**を入れないと表示されないので**手間がかかる**。

#チェックリスト型(ToDoリスト用)
- [ ] チェック1
- [x] チェック2

```
- [ ] チェック1
- [x] チェック2
```
　ここで**注意**したいのが `-(半角スペース)[(半角スペース)](半角スペース)`で入力したこと。
つまり、**[ ]の前後にスペース**があり、なおかつ**その中にもスペース**が必要です。
　**チェックを入れたい時**は、**[ ]の中のスペースの代わりに「ｘ」**を入れる。
　記事を書いていくうえで、手順作業として使えそうです。
#絵文字

>\:smile::notes:　絵文字で感情表現を出すのも大事。

```
>\:smile::notes:　絵文字で感情表現を出すのも大事。 

```
　**:で囲って**、絵文字コードを埋め込めます。
　絵文字チートシート >>http://www.emoji-cheat-sheet.com/
#リンクカード

https://qiita.com/alce

```
(空行)
URL
(空行)
```
　参考資料を載せるのに使えるかもしれません。

#もし、気になるQiita記事の載せ方が見つかったら
　記事よこにある**「・・・」**を選択して
　**「Markdownで本文」**にクリックしてその方の本文を見ましょう。
![win002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203650/cc7bfb25-24e6-07a9-0db8-4c8cf3e7126d.jpeg)
　**ウィンドウをタブ複製**すれば、照らし合わせると勉強になります。
#参考資料

- 完全説明書

https://qiita.com/Qiita/items/c686397e4a0f4f11683d

- 超ザックリに説明されている

https://qiita.com/toshihirooya/items/949f571b85cd7c297cca

https://qiita.com/tbpgr/items/989c6badefff69377da7
WindowsベースのDockerコンテナを動かす

#Windowsのコンテナを作ろう
Dockerといえば、普通はLinuxのコンテナですが、Windowsのコンテナを使いたいときもあると思います。
そんなボーイズ＆ガールズにWindowsのコンテナを作るDockerfileをお贈りしよう。

#GO言語の実行環境を構築
試しにGO言語の実行環境を構築してみます。
環境が変わればプレイングも変わるのが常ですが、
GOはオールラウンダーなので、さほど変わりませんから楽ですね。

```
FROM mcr.microsoft.com/windows:1909

ENV GOLANG_VERSION 1.14.10
ENV GOLANG_DOWNLOAD_URL "https://golang.org/dl/go$GOLANG_VERSION.windows-amd64.zip"

RUN powershell -Command \
    $ErrorActionPreference = 'Stop'; \
    (New-Object System.Net.WebClient).DownloadFile('%GOLANG_DOWNLOAD_URL%', 'go.zip') ; \
    Expand-Archive go.zip -DestinationPath c:\\ ; \
    Remove-Item go.zip -Force

RUN setx PATH %PATH%;c:\go\bin
```

Docker for Windowsで動かす場合は、「Switch to Windows containers」で
Windowsコンテナ稼働モードにしてください。
クラウドってなに？

完全独学でAzureについて学んでみて、15日間で人に使い方を提案できるようになるようにoutputをしてみます。
完全に自己満なので内容の保証もなしです。

Day1 Developer様向けのAzureサービス
Day2 結局自分でつくらないでもいいんじゃない？App編
Day3 クラウドのセキュリティって結局どうすればいい？
Day4 クラウドを使ってみよう！！ができない企業へのアプローチ
Day5 IoT向けのAzureサービス
Day6 結局自分でつくらないでもいいんじゃない？IoT編
Day7 Low code/No codeってなにができるの？(Logic App)
Day8 インフラ向けAzureサービス
Day9 オンプレ、IaaSって結局どう使い分ける？
Day10 DB向けAzureサービス
Day11 コンテナー、Micro serviceってどう実用化できるの？
Day12 最新ITキーワードを集めてみた
Day13 結局クラウドを使うといい事
Day14 海外のクラウド利用状況
Day15 これからのSIerとしてのあるべき姿とは
Kotlin KMMのTips集

Kotlin/NativeがBetaの頃から業務で使い続けているので、Tipsを書いていこうと思います。
随時更新予定。

# iOSの場合は実機よりシミュレータの方がコンパイル時間が短い

Kotlin/NativeのコンパイラはiOS Simulatorに最適化されているので、基本はシミュレータで開発した方がいいです。

https://youtrack.jetbrains.com/issue/KT-42294?_ga=2.9003446.2005538015.1617356323-2074967572.1616149914

>コンパイラの動作を遅くしていたいくつかの問題を解消することで、コンパイル時間を改善しました。コードに変更を加えた後、iOS Simulatorをターゲットにしたバイナリを再コンパイルするのに必要な時間を最小限に抑えることに重点を置いたため、iOS Simulator上でユニットテストやアプリケーションを再実行したときに最も大きな改善が見られます。例えば、KMMのネットワーキングとデータストレージのサンプルでは、フレームワークの再構築にかかる時間を、9.5秒（1.4.10）から4.5秒（1.4.30）に短縮しました。
>特定のケースに焦点を当てていますが、ほとんどの最適化は他のシナリオにも影響します。
>今後もコンパイラーの最適化を続けていく予定です。

# 「kotlin.native.concurrent.InvalidMutabilityException」対策

概要については以下の公式サイトを参照してください。
https://kotlinlang.org/docs/mobile/concurrent-mutability.html#atomicint-atomiclong

解決策としては、[touchlab/Stately](https://github.com/touchlab/Stately)というライブラリを使えばよいです。
このライブラリを使うことで、複数のスレッドから変数の値を変更できるようになります。

# Xcodeの「Validate Workspace」をYesにする

![スクリーンショット 2021-03-16 15.43.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9875/59cdda39-7f8e-8336-849d-f67180ba3140.png)

Xcodeで「Validate Workspace」をYesにすると、ビルド対象のデバイス(シミュレータ or 実機)を切り替えた時に、自動でsharedコードをリビルドするようになります。

# String.formatを使う

expect/actualを使えばできます。

```commonMain/.../Common.kt
expect fun stringFormat(format: String, vararg args: Any?): String
```

```androidMain/.../Common.kt
actual fun stringFormat(format: String, vararg args: Any?): String {
    return String.format(format, *args)
}
```

```iOSMain/.../Common.kt
// https://stackoverflow.com/a/64499248/4791194
actual fun stringFormat(format: String, vararg args: Any?): String {
    var returnString = ""
    val regEx = "%[\\d|.]*[sdf]|[%]".toRegex()
    val singleFormats = regEx.findAll(format).map {
        it.groupValues.first()
    }.asSequence().toList()
    val newStrings = format.split(regEx)
    for (i in 0 until args.count()) {
        val arg = args[i]
        returnString += when (arg) {
            is Double -> {
                NSString.stringWithFormat(newStrings[i] + singleFormats[i], args[i] as Double)
            }
            is Int -> {
                NSString.stringWithFormat(newStrings[i] + singleFormats[i], args[i] as Int)
            }
            else -> {
                NSString.stringWithFormat(newStrings[i] + "%@", args[i])
            }
        }
    }
    if (newStrings.count() > args.count()) {
        returnString += newStrings.last()
    }
    return returnString
}
```

```CommonTest.kt
class CommonTest {

    @Test
    fun testStringFormat() {
        assertEquals("test: a", stringFormat("test: %s", "a"))
        assertEquals("1, 2", stringFormat("%d, %d", 1, 2))
    }
}
```
Windows Server機にClickOnceアプリをインストールする際の注意点

ちょっとハマったのでメモ。

Windows Server OSにClickOnceアプリをセットアップする際は、事前にレジストリの設定が必要。

# 経緯
これまで、Windows10で使用実績のあるClickOnceアプリを、WindowsServerにもインストールする事になった。
ところが、setup.exeを実行したタイミングで、以下のエラーが表示された。
![error01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196121/7bfe111f-a5fb-ef62-a8dc-dba349174d4d.png)
セットアップ ログ ファイルを参照すると、このようなエラーが出力されていた。

```
URLDownloadToCacheFile failed with HRESULT '-2146697208'
Error: 'https://*****.****.jp/*****/************.application' をダウンロードしようとしてエラーが発生しました。
```

ログに記載の「 `https://*****.****.jp/*****/************.application` 」をブラウザで開いてみたら、正常にダウンロードできたので、何かの設定が足りてないらしい。

# 解決策
「`URLDownloadToCacheFile failed`」で検索してみたが、発行先のURLが間違っている、などの指摘ばかり。
URLは開けるのでURLの問題ではない。

英語サイトまで広げて検索していたところ、以下のレジストリ設定で解決したとの報告あり。
どうやら、Server機はデフォルトでSSLキャッシュが無効になっているらしい。

**レジストリ**

```
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings]
"DisableCachingOfSSLPages"=dword:00000000
```

レジストリを設定後、setup.exeを実行したらClickOnceアプリのインストールに進みました。

# 検証環境
* Windows Server 2016 Standard デスクトップエクスペリエンス
* Windows Server 2019 Standard デスクトップエクスペリエンス
* Windows Server 2019 Datacenter デスクトップエクスペリエンス

# 参考にしたページ
https://stackoverflow.com/questions/43451496/urldownloadtocachefile-failed-with-hresult-2146697208
サンプルアプリケーションをアレンジする、という学習法~todoアプリの例~

#「基礎学習の向こう側」
Java,PHP,JavaScript、世にプログラミング言語は数あれど、初学者が陥りがちな悩みは共通している。
それは、「どんなアプリケーション」を作ればよいかわからないことである。
特に、私自身も含め基礎文法を学習した方がその悩みを抱えているように感じる。
そのような方には、「アレンジ学習法」を提案したいと考え、本稿執筆に至った。

# アレンジ学習法
この学習法は、インターネットでよく見られる初学者向けのサンプルアプリケーションを自分なりに変更(アレンジ)するというものである。
例えばこちらの動画ではJavaScriptの基礎文法のみでクイズアプリを作成する方法が説明されている。

https://www.youtube.com/watch?v=fAluwAmHrws&t=806s

こういった初心者向けのアプリケーションの、仕様や一部機能を自分なりに変更するのがこの学習法である。
実践例としては、このクイズアプリのコードを流用してタスク管理アプリを実装することなどが挙げられる。

# 具体例
文章で説明してもわかりにくい点があるので以下、画像を用いて説明する。

例えば元動画のクイズアプリの画面はこうなっている。

![スクリーンショット 2021-03-16 14.21.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/961542/37cc3ada-3258-7ac2-dcdb-11799189c958.png)

空色の背景の部分が問題文で、その下に並ぶ4つの青いボタンが選択肢である。

## 変更(アレンジ)するポイント
上記アプリをもし、問題文の部分にテキストを打ち込めるようにして、ボタンの部分に「OK」や「▲」マークを付ければどうなるだろうか。

テキストをタスク名、ボタンを達成度とすれば、れっきとした達成度評価つきのタスク管理アプリらしきものが出来ないだろうか？
↓このように

![スクリーンショット 2021-03-16 15.29.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/961542/c598b5ad-afc8-205c-b9cf-eaee6106aed5.png)


少々設計の知識は必要かもしれないが、最初からターゲットユーザーを設定、用いる技術も選定...するよりはハードルが低いので、初級者から中級者へステップアップするにはお勧めの学習法ではないだろうか。

現在筆者は転職活動のため多忙であるので、どう実装したかは次回以降の記事で紹介しようと考えている。

以上

# 参考文献など
参考にさせて頂いたセイト先生の動画
https://www.youtube.com/watch?v=fAluwAmHrws

上記動画にて実装されたコード
https://github.com/seito-developer/js-quiz-apps