OmniAICreator/Qiita-1.07M huggingface dataset:
LibreOffice CalcをJScriptなどから操作してみた

#はじめに

- [C# で LibreOffice を操作する]
(http://home.a00.itscom.net/hatada/libreoffice/calc/libreoffice_calc01.html)
- [Excelの参照を追加せずにExcelを使う[C#] | zenmai software]
(https://zenmai.wordpress.com/2011/06/24/excel%e3%81%ae%e5%8f%82%e7%85%a7%e3%82%92%e8%bf%bd%e5%8a%a0%e3%81%9b%e3%81%9a%e3%81%abexcel%e3%82%92%e4%bd%bf%e3%81%86c/)

を参考にさせて頂きました。圧倒的感謝……！

#環境
- Windows 10 Home (64bit)
- Visual Studio Community 2019

#サンプルソース

##JScript

```libreoffice.js
{
	var factory = WScript.CreateObject("com.sun.star.ServiceManager");
	var loader = factory.createInstance("com.sun.star.frame.Desktop");
	var doc = loader.loadComponentFromURL("file:///C:/data/test.ods", "_blank", 0, []);

	var sheets = doc.getSheets();
	var sheet = sheets.getByName("Sheet1");
	var cell = sheet.getCellByPosition(0, 0);
	cell.setFormula("hello, world");
}
```

##VB.NET

```Module1.vb
Module Module1

    Sub Main()
        Dim factory, loader, doc As Object
        Dim d(0) As Object

        factory = CreateObject("com.sun.star.ServiceManager")
        loader = factory.createInstance("com.sun.star.frame.Desktop")
        doc = loader.loadComponentFromURL("private:factory/scalc", "_blank", 0, d)

        Dim sheets, sheet, cell As Object
        sheets = doc.getSheets()
        sheet = sheets.getByName("Sheet1")
        cell = sheet.getCellByPosition(1, 1)
        cell.setFormula("hello, world")
    End Sub

End Module
```

##C＃
LibreOffice SDKを使う方法もあるが、使わない方法もある。

```Program.cs
using System;
using System.Reflection;
using System.Runtime.InteropServices;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var t = Type.GetTypeFromProgID("com.sun.star.ServiceManager");
            var factory = Activator.CreateInstance(t);

            object[] a = { "com.sun.star.frame.Desktop" };
            var loader = factory.GetType().InvokeMember("createInstance",
                BindingFlags.InvokeMethod, null, factory, a);

            object[] b = { };
            object[] c = { "private:factory/scalc", "_blank", 0, b };
            var doc = loader.GetType().InvokeMember("loadComponentFromURL",
                BindingFlags.InvokeMethod, null, loader, c);

            Marshal.ReleaseComObject(factory);
        }
    }
}
```
ValueError at / の解消方法備忘録

エラー文
`ValueError at /
The view myapp.views.Index didn't return an HttpResponse object. It returned None instead.`

『HttpResponse object』
HttpResponseが返せていないと言う意味。

変更するコード内容

```
def Index(TemplateView): 
    template_name = 'myapp/imdex.html'
```

Djangoでは`Index(TemplateView)`をあらかじめ用意してくれる。
その為、`(TemplateView)`を使うときは関数である`def`を使わず`class`を使う
結果

```
class Index(TemplateView):
    template_name = 'myapp/imdex.html'
```

とすると解消できる
Docker buildでのSSL証明書エラー対処 【GitHub Actions】

# 状況
GitHub Actionsを利用した``Docker buildx``中の``gem install``で以下のエラーが[発生](https://github.com/kurema/forkedLetMeSee/runs/1360344632?check_suite_focus=true#step:10:2066)。

```
#24 [linux/arm/v7  7/10] RUN gem install iconv
#24 2.493 ERROR:  SSL verification error at depth 1: unable to get local issuer certificate (20)
#24 2.495 ERROR:  You must add /C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA to your local trusted store
```

ベース・イメージはDocker Hubの``httpd:2.4.46``と``httpd:2.4.43``(2020年11月時点のlatest)の``linux/arm/v7``です。
``linux/arm64``と``linux/amd64``では発生していません。

詳しくは[レポジトリ](https://github.com/kurema/forkedLetMeSee)を参照してください。
後述の通りその後対処が不要になったので``Dockerfile``等は[当時の版](https://github.com/kurema/forkedLetMeSee/tree/ffa42ae0363e0b2d640a2c0ebc50793597f69e52)を参照。

# 原因
原因は書いてある通り証明書エラーです。
``GlobalSign Root CA``の証明書が入っていません。

# 対処
証明書を追加すれば解決します。
Bundlerのページにある[トラブルシュート](https://bundler.io/v2.0/guides/rubygems_tls_ssl_troubleshooting_guide.html)に従い、[pemファイルへの直接リンク](https://raw.githubusercontent.com/rubygems/rubygems/master/lib/rubygems/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem)からダウンロードします。
署名の追加方法は[Life with ITさんの記事](https://l-w-i.net/t/aws/ec2_100.txt)と[@msiさんの記事](https://qiita.com/msi/items/9cb90271836386dafce3)に従いました。

ただし、証明書が不足している/古い場合はcurlが動作しないことがあります、``Dockerfile``内ではなく外部でcurlから取得し、``COPY``した方が良いでしょう。

```yaml:.github/workflows/docker.yml
      - name: Download GlobalSignRootCA.pem
        run: curl https://raw.githubusercontent.com/rubygems/rubygems/master/lib/rubygems/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem -o GemCert.pem
```

```dockerfile:Dockerfile
COPY GemCert.pem /tmp/GemCert.pem
RUN mkdir /usr/share/ca-certificates/Gem && \
    cp /tmp/GemCert.pem /usr/share/ca-certificates/Gem && \
    echo "Gem/GemCert.pem" >> /etc/ca-certificates.conf && \
    update-ca-certificates && \
    rm /tmp/GemCert.pem
```

なお、``apt-get install ca-certificates``では解決しませんでした。
他には、

```bash
$ curl -Lks 'https://git.io/rg-ssl' | ruby # SSLのチェック
$ gem install bundler # Bundlerの更新
$ gem update --system # RubyGemsの更新
```

が推奨されていました。私の場合更新は必要ありませんでしたが、チェックスクリプトは便利です。

なお、今回は証明書をインストールしましたが、SSLなしに設定するという選択肢もあります。お勧めしません。

# 懸念点
SSLの証明書をGitHubからダウンロードするというのはセキュリティ上心配です。
GitHubでなくとも将来ずっとURLが維持されるか、証明書自体が今後も信用できるのかなど不安が残ります。
特に定期実行もするGitHub Actionsで現時点で動作するだけのワークアラウンドも避けた方が良いでしょう。

ここではやりませんでしたが、追加し処理が終わった後証明書を削除するのも一つのやり方でしょう。

私の場合は、この後ソースコードを修正し``gem install``自体が不要になり、この対処を削除しました。

# 参考記事
* Lief with IT (2019) 「Amazon Linux 2上でcurl実行時に「SSL certificate problem: unable to get local issuer certificate」というエラーが出る場合の対応」 https://l-w-i.net/t/aws/ec2_100.txt
* Bundler 「How to troubleshoot RubyGems and Bundler TLS/SSL Issues」https://bundler.io/v2.0/guides/rubygems_tls_ssl_troubleshooting_guide.html
* @msi (2020)「独自(root)CA のインストール方法」Qiita https://qiita.com/msi/items/9cb90271836386dafce3
決定木（load_iris）

## ■ はじめに
今回は、決定木の実装～プロットをまとめていきます。

【対象とする読者の方】
・決定木における、基礎のコードを学びたい方
・理論は詳しく分からないが、実装を見てイメージをつけたい方　など
<br>
##1. モジュールの用意
最初に、必要なモジュールをインポートしておきます。

```python

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import plot_tree
```
<br>
##2. データの準備
load_iris データセットを使用します。

```python

iris = load_iris()
X, y = iris.data[:, [0, 2]], iris.target

print(X.shape)
print(y.shape)

# (150, 2)
# (150,)
```
trainとtestデータに分割します。

```python

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 123)

print(X_train.shape)
print(y_train.shape)
print(X_test.shape)
print(y_train.shape)

# (105, 2)
# (105,)
# (45, 2)
# (45,)
```
決定木では個々の特徴量は独立に処理され、データの分割はスケールに依存しないため
正規化や標準化は不要となります。
<br>
## 3. データの可視化

モデリングする前に、データをプロットして見ておきます。

 ```python

fig, ax = plt.subplots()

ax.scatter(X_train[y_train == 0, 0], X_train[y_train == 0, 1], 
           marker = 'o', label = 'Setosa')

ax.scatter(X_train[y_train == 1, 0], X_train[y_train == 1, 1],
           marker = 'x', label = 'Versicolor')

ax.scatter(X_train[y_train == 2, 0], X_train[y_train == 2, 1],
           marker = 'x', label = 'Varginica')

ax.set_xlabel('Sepal Length')
ax.set_ylabel('Petal Length')
ax.legend(loc = 'best')

plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725082/2bfc739c-25d7-1381-fed8-d06dce9a70d8.png)
##4. モデルの作成
決定木のモデルを作成します。

```python

tree = DecisionTreeClassifier(max_depth = 3)
tree.fit(X_train, y_train)

'''
DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',
                       max_depth=3, max_features=None, max_leaf_nodes=None,
                       min_impurity_decrease=0.0, min_impurity_split=None,
                       min_samples_leaf=1, min_samples_split=2,
                       min_weight_fraction_leaf=0.0, presort='deprecated',
                       random_state=None, splitter='best')

'''
```
併せて、可視化もしておきます。

```python

fig, ax = plt.subplots(figsize=(10, 10))
plot_tree(tree, feature_names=iris.feature_names, filled=True)
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725082/180294cb-bbf2-65d1-9a8c-24ad65dc7674.png)
<br>
##5. 予測値の出力
テストデータに対する予測を行います。

```python

y_pred = tree.predict(X_test)

print(y_pred[:10])
print(y_test[:10])

# [2 2 2 1 0 1 1 0 0 1]
# [1 2 2 1 0 2 1 0 0 1]
```
0：Setosa　1：Versicolor　2：Verginica
<br>
##6. 性能評価
今回の分類予測における、正解率を求めます。

```python

print('{:.3f}'.format(tree.score(X_test, y_test)))

# 0.956
```
<br>
##■ 最後に
今回は上記1～6の手順をもとに、決定木のモデル作成・評価を行いました。
初学者の方にとって、少しでもお役に立てたようでしたら幸いです。
<br>
## ■ 参考文献
・[Pythonによるあたらしいデータ分析の教科書](https://www.shoeisha.co.jp/book/detail/9784798158341)
Pythonで「SSL: CERTIFICATE_VERIFY_FAILED _ssl.c:1056」が出た時の対処法

## 自分の環境について
エラーを吐いた環境の概要を記す。
- macbookAir(とりあえず，macであるということが重要)
- Homebrewでpython3.7を入れた(ここが一番大事)
 
## エラーの解決方法について
自分の場合は，sklearnでデータセットをインポートするときに出て詰まってしまった。
ネットで調べたときに出てくる解決法では。

```python:python3の実行コード

>>>import certifi
>>>certifi.where()
'/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/certifi/cacert.pem'
```

と，出てくる。
こいつをSSL認証のための鍵(?)にしてやればよい。


```shell:terminalでの実行コード

$ touch /Library/Frameworks/Python.framework/Versions/3.7/etc/openssl/cert.pem #ファイルがなければ

$ ln -s /Library/Frameworks/Python.framework/Versions/3.7/etc/openssl/cert.pem /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/certifi/cacert.pem

$ ls -l /Library/Frameworks/Python.framework/Versions/3.7/etc/openssl
lrwxr-xr-x  1  ユーザ名  admin  96 11 22 10:04 cert.pem -> /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/certifi/cacert.pem

```

と，なります。
これで，たぶん解消するはず。

## 参考
[[youtube-dl] python3のSSLエラー(CERTIFICATE_VERIFY_FAILED)
](https://qiita.com/tommy19970714/items/96edba36dfde468e26f3)
[macOS用公式インストーラーのPython 3.6でCERTIFICATE_VERIFY_FAILEDとなる問題](https://qiita.com/orangain/items/0a641d980019fd7e0c52)
CleanArchitecture的な構成のGo API サーバー サンプルコード(echo, wire利用)

# はじめに

CleanArchitecture的なパッケージ構成に照準を合わせてGoのREST API Serverの実装をしてみる。
更にGoのweb framework [echo](https://github.com/labstack/echo)とDI code generatorである[wire](https://github.com/google/wire)を組み込む。



### excuse

この構成で本番稼働実績が有る訳ではなく、まずは叩き台的に考えてみました。
まだ改善の余地は有りそうです。


# 実装リポジトリ

[![img](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307773/a0675efd-6389-cd62-455e-b9eb8bb9e26f.png)](https://github.com/fukuyama012/go-server-layered-sample/tree/main)

＊利用方法はREADMEを参照。

# ディレクトリ構成

```
├── cmd
│   └── server
├── db
├── domain
│   ├── model
│   └── repository
├── handler
├── infra
│   └── mysql
├── response
├── router
└── usecase
```

## cmd 

sever起動のmainファイル。

## db

dbへの接続情報。
migration情報もここに置くかもしれない。
infraに置いても良いかもしれない。

## domain/model

単一エンティティのドメインロジックはこちらに記述。

## domain/repository

永続化情報のインターフェイス。

## handler

echoのエンドポイント処理から呼ばれるハンドラ郡。
ここでwireを使いDependeny Injectionする構成とした。

## infra

永続化処理の実装詳細。

## response

要件に応じてこちらでレスポンスフォーマットを決める。

## router

echoのルーティング エンドポイント定義を集約する。

## usecase

ドメインロジック以外のアプリケーションロジックをこちらに記述。


# 更に実装する場合の検討ポイント

### DBトランザクションどこに置く？

usecase内でbeginして引数にDBセッション持ち回るくらいが収まりが良さそうな気がしている。
(infraに永続化実装詳細が収まってないが、、)

### レイヤーが分離してない？

もっと厳密にやるならinfraで構造体に別途DBタグを用意してmodelと相互変換してもよさそうだが出来ればmodel structをそのまま持ち回って手数を減らしたい。

### sqlでtable joinとかしたら？

`domain/service`にてネストした構造体を用意してinfraでクエリ結果を受け取れば良い？

```Go
type (
	Joined struct {
		Example
		Example2
	}
)
```

## 参考

[Clean Architecture 達人に学ぶソフトウェアの構造と設計](https://www.kadokawa.co.jp/product/301806000678/)
https://github.com/golang-standards/project-layout
https://future-architect.github.io/articles/20200528/
[Rails]リロードしないと投稿できないちょっとした不具合

Railsの学習中で、作った料理のレシピを共有するサイトを作成している時、
投稿画面でリロードしないとどこを押しても何も反応しないという現象が起きた。

原因は至極単純なものだったが、恥ずかしながら解決に時間がかかってしまったため備忘録として残しておく。

#現象#
投稿画面に遷移したあと、フォームへの入力はできるが、
submitボタンを押しても何も起こらない。DBへの保存もできてない模様。
リロードをして再度記入、submitで投稿可能。

#原因#
form_with（今回はnested_form_for）をdiv要素を跨いで書いてしまっていた。

```ruby:_rescipe_form.html.erb


    <div class="row">
     <%= nested_form_for recipe, local: true do |f| %>
      <div class="col-lg-4">
        <h5>料理の写真</h5>
        <%= attachment_image_tag recipe, :recipe_image, fallback: "no_image.png", class: "img_prev", style: "height: 250px; width:300px;" %><br>
        <%= f.attachment_field :recipe_image %>
      </div>
      
         ~~~~~~(省略)~~~~~~~
      
      <% if recipe.new_record? %>
        <%= f.submit 'レシピを公開する'%>
      <% else %>
        <%= f.submit 'レシピを書き換える' %>
      <% end %>
     </div>
    <% end %> 
```

#まとめ#
初歩的なところで躓き時間を使ってしまった。
この現象が起きた時、formの中身ばかりを見ていたので
入れ子構造がちゃんとなっているか、全体をよくみる癖を付けたい
pythonで英単語アプリを作成

#仕様
- 入力した単語を翻訳サイトからスクレイピングし、翻訳結果を表示する
- 翻訳と同時にに音声ファイルも出力する
- 音声ファイルを単語名.mp3で保存する

#ライブラリ
使用したライブラリは以下の通りです。

|ライブラリ|用途|
|:---|:---|
|os|パスの確認|
|requests|htmlの入手、mp3のダウンロード|
|bs4|htmlの解析|
|tkinter|GUIの作成|
|pygame|mp3の再生|
|random|例外処理|

#コード
```python
import os
import random
import tkinter
import requests
from bs4 import BeautifulSoup
from pygame import mixer


class Translation:
    def __init__(self):
        self.root = tkinter.Tk()
        self.root.title('Translation')
        self.root.geometry('500x200')
        self.root.attributes('-topmost', True)
        self.text_box = tkinter.Entry(width=20, font=('', 20), justify='center')
        self.text_box.focus_set()
        self.text_box.pack()
        self.root.bind('<Return>', self.scraping)
        self.root.bind('<space>', self.delete)
        self.answer = tkinter.Message(self.root, text='', font=('', 20), width=450)
        self.answer.pack(anchor='center', expand=1)
        self.root.mainloop()
    
    def scraping(self, event): #スクレイピング
        try:
            res = requests.get('https://ejje.weblio.jp/content/' + self.text_box.get())
            soup = BeautifulSoup(res.content, 'html.parser')
            txt = soup.find('td', {'class': 'content-explanation ej'})
            self.answer['text'] = txt.text
            self.sound(soup)
        except:
            self.answer['text'] = random.choice(('(^^;)?', '(・ω・)?', "('Д')?", '(; ･`д･´)?'))
    
    def sound(self, soup): #mp3をダウンロードし再生する
        mp3_directory_path = 'd:/python/Application/mp3/' #mp3の保存先
        if not os.path.exists(mp3_directory_path):
            os.mkdir(mp3_directory_path)

        if os.path.exists(mp3_directory_path + self.text_box.get() + '.mp3'):
            pass
        else:
            audio = soup.find('audio', {'class': 'contentAudio'})
            src = audio.find('source')['src']
            res = requests.get(src, stream=True)

            with open(mp3_directory_path + self.text_box.get() + '.mp3', 'wb') as f:
                f.write(res.content)

        mixer.init()
        mixer.music.load(mp3_directory_path + self.text_box.get() + '.mp3')
        mixer.music.play()

    def delete(self, event): #スペースキーで入力欄の文字を全て削除する
        self.text_box.delete(0, tkinter.END)


Translation()
```

#実行結果
![result1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579920/5a032f75-f19c-3b29-df51-e4a986cdba5c.png)


![result2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579920/6ac15768-7f27-1438-a5b9-d3f3a8e6bcff.png)

#感想
　なんとか形にできました。他の方が作ったQiitaの記事がとても参考になりました。あとはデスクトップにbatファイルを作れば気軽に立ち上げることができると思います。また、ダウンロードしたmp3ファイルから単語のリスニングテストなんかも作れるかもしれません。
[ServiceNow] CSVファイルのインポートで先頭カラムが「u__」で取り込まれる

## 事象
Excelで作成したCSVファイルをServiceNowにインポートすると先頭のフィールドがマッピングできない。
インポートテーブルに`u__フィールド名`と_（アンダースコア）が2文字続いたフィールドが作られてしまう。

### プラットフォーム
NewYork, Orlando

## 対処方法
他のエディタでCSVファイルを保存する。

### 原因
ExcelでCSVファイルにして保存するとBOM付きになってしまうため。

### 参考URL
[How to import csv which charset is UTF-8 BOM?](https://hi.service-now.com/kb_view.do?sysparm_article=KB0827242)

### きっかけ
他チームの人からの質問で、以前同じ現象になったことを思い出しました。
ExcelでBOMなしのCSVを保存する方法はあるんでしょうか？
Big Sur アップデート後 brew doctor でCLTアップデートを要求されたがインストールエラーが出る時の対処手順

## 実行環境
Big Sur バージョン11.0.1

###1. 警告メッセージ
警告：CLTはmacOS11.0をサポートしていません。
古くなっているか、変更されています。
CLTを更新するか、更新が利用できない場合は削除してください。

```
$ brew doctor

Warning: Your CLT does not support macOS 11.0.
It is either outdated or was modified.
Please update your CLT or delete it if no updates are available.
```

###2. brewのコンフィグ確認
対処前のコンフィグを確認する。

```
$ brew --config

HOMEBREW_VERSION: 2.5.11
ORIGIN: https://github.com/Homebrew/brew
HEAD: 07b3aa69f8dc5098437cf2562864558bae2d45aa
Last commit: 7 days ago
Core tap ORIGIN: https://github.com/Homebrew/homebrew-core
Core tap HEAD: 21b577dcda1154b6238c014e4db6aa6e4bf964d9
Core tap last commit: 7 minutes ago
Core tap branch: master
HOMEBREW_PREFIX: /usr/local
HOMEBREW_CASK_OPTS: []
HOMEBREW_MAKE_JOBS: 8
Homebrew Ruby: 2.6.3 => /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby
CPU: octa-core 64-bit icelake
Clang: 12.0 build 1200
Git: 2.29.2 => /usr/local/bin/git
Curl: 7.64.1 => /usr/bin/curl
Java: 15.0.1
macOS: 11.0.1-x86_64
CLT: 12.0.32.2
```
###3. xcode最新版をインストールするもエラー
他のツールを提案される。
エラー：コマンドラインツールはすでにインストールされています。「ソフトウェアアップデート」を使用してアップデートをインストールしてください

```
$ xcode-select --install

xcode-select: error: command line tools are already installed, use "Software Update" to install updates
```

###4. ソフトウェアアップデートツールリストを確認
利用可能な新しいソフトウェアはありません。

```
$ softwareupdate --list
Software Update Tool

Finding available software
No new software available.
```

###5. 手動でインストールを試みる

- Macのシステム環境設定でソフトウェア・アップデート　※私の場合xcodeのアップデートがありました
- [More Downloads for Apple Developers](https://developer.apple.com/download/more/)
- 上記リンク先ページにて　``command + F``
- ``command line tools`` をページ内検索する　 
- xcodeのバージョンに合う ``command line tools`` を選択してインストール

###6. brewのコンフィグ確認
対処後のコンフィグを確認する。
CLT、Xcodeの更新確認ができた。

```
$ brew --config 
HOMEBREW_VERSION: 2.5.11
ORIGIN: https://github.com/Homebrew/brew
HEAD: 07b3aa69f8dc5098437cf2562864558bae2d45aa
Last commit: 7 days ago
Core tap ORIGIN: https://github.com/Homebrew/homebrew-core
Core tap HEAD: 21b577dcda1154b6238c014e4db6aa6e4bf964d9
Core tap last commit: 73 minutes ago
Core tap branch: master
HOMEBREW_PREFIX: /usr/local
HOMEBREW_CASK_OPTS: []
HOMEBREW_MAKE_JOBS: 8
Homebrew Ruby: 2.6.3 => /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby
CPU: octa-core 64-bit icelake
Clang: 12.0 build 1200
Git: 2.29.2 => /usr/local/bin/git
Curl: 7.64.1 => /usr/bin/curl
Java: 15.0.1
macOS: 11.0.1-x86_64
CLT: 12.2.0.0.1.1604076827
Xcode: 12.2
```

###７. brew doctor
警告メッセージが消えたことを確認する。

## 参考
- [Command Line Toolsを手動でインストールする](https://qiita.com/___xxx_/items/4a318f29e1dd68ad8071)
overflow autoについて

##overflowとは
CSSのプロパティの１つで、`要素のボックスからはみ出た部分をどう扱うかを指定する。`

`visible`：初期値。はみ出た部分がはみ出たままの状態で表示される場合がある。
`hidden` ：はみ出た部分が隠れる。
`scroll` ：はみ出た部分が隠れてスクロールできる状態になる。
`auto`   ：ブラウザにより表示が変わる（基本的にはスクロールできる状態に）。

##auto
`はみ出た部分の処理をブラウザに委ねることになる。ほとんどの場合はscrollと同じくスクロールに。`

```
<!-- html -->
<p class="menu">あいうえおあいうえおあいうえお</p>

/* css */
.menu {
    width: 50px;
    height: 50px;
    overflow: auto;
    background: rgb(242, 173, 173);
}
```

![スクリーンショット 2020-11-24 9.24.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601015/a73ae76a-148e-ef4b-707e-f1f639188bd7.png) ![スクリーンショット 2020-11-24 9.25.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601015/c8c1bf9c-f59c-4b38-d608-eb0da3f9b324.png)

参考元はこちら
(https://saruwakakun.com/html-css/basic/overflow)
overflow scrollについて

##overflowとは
CSSのプロパティの１つで、`要素のボックスからはみ出た部分をどう扱うかを指定する。`

`visible`：初期値。はみ出た部分がはみ出たままの状態で表示される場合がある。
`hidden` ：はみ出た部分が隠れる。
`scroll` ：はみ出た部分が隠れてスクロールできる状態になる。
`auto`   ：ブラウザにより表示が変わる（基本的にはスクロールできる状態に）。

##scroll
`はみ出た部分が非表示になるが、スクロールにより表示することができるようになる。`

`white-space:nowrap;`を指定することで、横向きにスクロールできるようにすることも可能。

```
<!-- html -->
<p class="menu">あいうえおあいうえおあいうえお</p>

/* css */
.menu {
    width: 50px;
    height: 50px;
    overflow: scroll;
    background: rgb(242, 173, 173);
}
```

![スクリーンショット 2020-11-24 9.24.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601015/a73ae76a-148e-ef4b-707e-f1f639188bd7.png) ![スクリーンショット 2020-11-24 9.25.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601015/c8c1bf9c-f59c-4b38-d608-eb0da3f9b324.png)

参考元はこちら
(https://saruwakakun.com/html-css/basic/overflow)
overflow hiddenについて

##overflowとは
CSSのプロパティの１つで、`要素のボックスからはみ出た部分をどう扱うかを指定する。`

`visible`：初期値。はみ出た部分がはみ出たままの状態で表示される場合がある。
`hidden` ：はみ出た部分が隠れる。
`scroll` ：はみ出た部分が隠れてスクロールできる状態になる。
`auto`   ：ブラウザにより表示が変わる（基本的にはスクロールできる状態に）。

##hidden
`要素のボックスからはみ出てしまった部分を非表示にする。`

```
<!-- html -->
<p class="menu">あいうえおあいうえおあいうえお</p>

/* css */
.menu {
    width: 50px;
    height: 50px;
    overflow: hidden;
    background: rgb(242, 173, 173);
}
```

![スクリーンショット 2020-11-24 9.13.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601015/9e0123b1-137b-2750-7164-4eeecd27755e.png)

参考元はこちら
(https://saruwakakun.com/html-css/basic/overflow)
overflow visibleについて

##overflowとは
CSSのプロパティの１つで、`要素のボックスからはみ出た部分をどう扱うかを指定する。`

`visible`：初期値。はみ出た部分がはみ出たままの状態で表示される場合がある。
`hidden` ：はみ出た部分が隠れる。
`scroll` ：はみ出た部分が隠れてスクロールできる状態になる。
`auto`   ：ブラウザにより表示が変わる（基本的にはスクロールできる状態に）。

##visible

```
<!-- html -->
<p class="menu">あいうえおあいうえお</p>

/* css */
.menu {
    width: 50px;
    height: 50px; /*  heightを指定しなければはみ出ない。 */
    overflow: visible; /* visibleは初期値の為、書かれていなくても同じ表示になる。 */
    background: rgb(242, 173, 173);
}

```

![スクリーンショット 2020-11-24 8.59.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601015/32c61443-3a7b-742f-b0d7-cbac4c2cceff.png)

#####・`white-space: nowrap;`
heightを指定せずに、`white-space: nowrap;`を指定することで、横にはみ出るようになる。
`white-space` = `行の折り返しを決めるプロパティ`
`nowrap` = `自動的に改行しない`
`normal` = `右端で折り返す`

```
<!-- html -->
<p class="menu">あいうえおあいうえお</p>

/* css */
.menu {
    white-space: nowrap;
    width: 50px;
    overflow: visible; /* visibleは初期値の為、書かれていなくても同じ表示になる。 */
    background: rgb(242, 173, 173);
}
```

![スクリーンショット 2020-11-24 9.11.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601015/d306843d-0a20-3081-5c12-a628d34e48fe.png)

参考元はこちら
(https://saruwakakun.com/html-css/basic/overflow)
TypeScriptで指定した内のちょうど1つのエントリーだけが存在するオブジェクト型を作る

# 例
こういう `OneOf` が欲しい

```typescript
type FetchData<T = {}, E = Error> = OneOf<{
    data: T,
    error: E,
    loading: boolean
}>

var example: FetchData = {};                             // Error
var example: FetchData = { data: {} };                   // OK
var example: FetchData = { data: {}, error: undefined }; // OK
var example: FetchData = { data: {}, error: Error() };   // Error
```



# 実装
```typescript
type Mask<T, K extends keyof T = keyof T> = Pick<T, K> &
  { [key in Exclude<keyof T, K>]?: undefined };

type OneOf<T, K extends keyof T = keyof T> = K extends keyof T
  ? Mask<T, K>
  : never;
```

* [もう少しいろいろな例とともにTypeScript Playgroundで検証したものはこちら](https://www.typescriptlang.org/play?#code/C4TwDgpgBAsghgZwNYB4AqAaKBpKEAewEAdgCYJRIQgD2AZlGlALyXX2MB8LUACgJYBjVJhzcAZACgoUAN5QA2lRBR+xKAFF8ggDYBXUhBTKOo7JwC6AfgBcUPWQh01EUlAC+AbkmTQkKADyxBABdOhYuAREZBQmDEyscVw8kYQk5Gy08dJQVrCIIhGcOXbBAG4QAE7evuDQAGIQwIIAFgAicMBw6Dyy7lgaPBqVlTSV3KxBIWGyOTKknXB2aN4yMlWjlXYaq2s6NHCkagDmdgBGNDQ6EHDE3u7FkmVwlXj4cAC2YNd2jc3ti16Xh8z1eBE+3wgvyarQ6XV6UAWXTsfQ83lBbwhPygf1hgNY8iRSzk-TwIzGdgchmcwTcwIx4K+2NxAPhBMRixRpP2hxOlMcNNcaKeL0xTKhOJhrLgCKJXKwGwp9gFLlIWB5R2Ip2V1NVwpFYPe4uh-zhMvZiq2mnJlQAFABKYUMo2Qk14tlyKAavlQOhwHQIaDAg1i12S034z1ykkKm3bG0Op2ixlhllm2WcmNkzb83W09UHTXa4CVPRB9HJl3MqXp9nRqlOVWxnPWzYOgu8rV2EtlpOGrEStORwmZvrNpXDNv2jtF7ul8sgysDt3ShFRSrEhQWPuh6sRj0j5FZ9eb7f0pfG8Pu81R0eky3xqczn09iAKwgbuxbtFAA)


# 解説
書こうと思ったら、かなり近いものがすでにあった（[TypeScriptで最低一つは必須なオプションオブジェクトの型を作る](https://qiita.com/uhyo/items/583ddf7af3b489d5e8e9)）ので割愛

# おまけ
こういうのを定義して

```typescript
type NoneOf<T> = Mask<T, never>;

type OneOrNoneOf<T> = OneOf<T> | NoneOf<T>;
```
こういうこともできる

```typescript
type FetchResult<T = {}, E = Error> = OneOrNoneOf<{
    data: T,
    error: E
}>

type FetchState = OneOrNoneOf<{
    loading: boolean,
    loaded: boolean
}>

type FetchData<T = {}, E = Error> = FetchResult<T, E> & FetchState

var example: FetchData = { data: {}, error: undefined };                     // OK
var example: FetchData = { data: {}, error: Error() };                       // Error
var example: FetchData = { data: {}, error: undefined, loading: true };      // OK
var example: FetchData = { data: undefined, error: Error(), loading: true }; // OK
var example: FetchData = { data: {}, error: Error(), loading: true };        // Error

```
【個人開発】DjangoRESTFrameworkとVue-CliでSPAでアーティスト向けのアプリを作成した話【DRF+Vue.js】

#はじめに
こんにちは。
2年目ペーペー新人エンジニアです。
今回は、個人開発したアプリをついにリリースしたので、
それを記事にしようとおもいます。

#作成物

**PS: このサービスは2024年11月に停止しました。**

今回作成したのは、『PaintMonitor』というアプリです。
**※追記ー2021年アプリ名を改名し、『お絵描き道場』にしました。**
![top-cap.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493888/5eaea80a-8f7f-1bd1-84f1-a71c2b4c6ac6.jpeg)

名前も当初かなり迷走して、結局わかりやすく、
Paint（描いて）Monitor（見える化）にしました。
アプリの特徴としては、
描いて(Paint)、解析して(Monitor)、共有する(SNS)。の3点です。

#システム構成
![Drainer.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493888/2ed9bb87-e5b4-4e87-a4b8-5ab93257b4d9.jpeg)

システム構成は、一番使い慣れているUbuntuServerで、
開発言語はDjangoのDjangoRESTFrameworkを利用しました。
DjangoRESTFrameworkは、とても使いやすく、直感的に理解しやすかったです。
認証回りの構築は、『現場で使えるDjangoRESTFramework』の本を参考にしました。
このDjangoの現場で使えるシリーズは、本当に現場で使えそうな内容が豊富なのでおすすめです。

フロント周りは、最近仕事でもよく使うVue.jsを利用しました。
Vue.jsは、開発コストは低く使いやすいので、
SPAの作成にはとてもよかったです。
Webpackで、利用すればhotタイミングでコードが反映されるので開発スピードを上げてくれました。
開発当初は、jQueryで開発していましたが、ネイティブ展開もしたかったので、
モダンな構築に作り変えました。

DBはいつものMySQL。ストレージはAWSを利用しています。
APサーバーはGunicornを利用しています。
シングルパフォーマンスでは、uWSGIのほうが優れていますが、
システムの安定度を重視したい場合は、Gunicornがいいみたいです。
WEBサーバーはいつものNginxでリリース、それをLetsEncriptで暗号化しました。

#個人開発で作ろうと思ったきっかけ
ある程度WEBができるようになって、何か作りたいなぁと常に何かしらは作っていました。
アートとテクノロジーが好きなので、
それらを合わせてアーティスト向けのアプリを作ろうと思ったのがきっかけでした。
WEBで描いて、練習して、SNSにするサービスっていいなと思い、作り始めました。
最初は、tensorflowを利用して、絵をスコア化して、レート戦の
バトルをメインとするアプリを作ろうと考えたのですが、
普通に絵の練習するアプリのほうが実用的だなと思って、練習をメインとするアプリにしました。
バトルやそのほかの機能は後からのアップデートで追加していければいいかなと。

#個人開発で苦労したところ
###全部ひとりで考えなくてはいけなくて、大変な作業量になる。
単純に作業量が暴力的なので、仕事の合間に開発するには少ししんどかったです。
会社へ行く電車の乗り降りの時間、座れる時間帯に電車にのり、Surfaceを広げてカタカタと作業してました。
でもコードを書くのは好きなので、なんだかんだ充実した日々を過ごせました。

###デザインや仕様を考えるのが大変。
私は考えるより手を動かす派なので、デザインに関しては、FIGMAやXD等は使わずに、簡単に画面をスケッチしてデザインしました。
私の場合は、好きなWEBサービスのPinterestを参考したりしました。
仕様は、適当に考えて、修正があればその都度修正する、みたいなチーム開発なら怒られるであろう進め方をしていました。

###こだわりすぎて時間がかかる
私自身よく絵を描くので、ペイント部分はかなりこだわって作りました。
WEBでありながら実用的なペイントツールを作るのに4，5回新規でペイントアプリを作り、
開発の７割はこのペイントツールに費やしたせいで、開発に半年以上かかりました。

#最後に
個人開発は大変でしたが、
個人のポートフォリオにもなるし、なによりめちゃくちゃ勉強になります。
開発力をつける一番の方法は、アプリを作ってリリースするのがいいのでは？
と感じました。
長々と話してしまいましたが、
作成したPaintMonitor
昨日の夜にリリースしたばかりなので、まだ利用者が全然いません。
ぜひ触ってあそんでもらえたらうれしいです。
今後もアップデート頑張っていきたいと思います。
[Swift] APIレスポンス値はそのまま判定せずenumに置き換えた方が良い

前提環境：
・Xcode：12.1
・Swift：5.3


私はコードレビュー等でしばしば以下のような実装を見かけるのですが、Swiftの良さを活かしていないなと感じます…

```swift:改善前
// APIレスポンスの値と仮定
let memberType = "1"

func foo() {
    switch memberType {
    case "0":
        print("通常会員の処理を行う")
    case "1":
        print("プレミアム会員の処理を行う")
    case "2":
        print("お試し会員の処理を行う")
    default:
        break
    }
}
foo() // "プレミアム会員の処理を行う"
```

以下が改善したコードです。

```swift:改善後
// APIレスポンスの値と仮定
let memberTypeRaw = "1"

enum MemberType: String {
    case normal = "0"
    case premium = "1"
    case trial = "2"
}

func foo() {
    guard let memberType = MemberType(rawValue: memberTypeRaw) else {
        preconditionFailure("定義されていない値")
    }
    switch memberType {
    case .normal:
        print("通常会員の処理を行う")
    case .premium:
        print("プレミアム会員の処理を行う")
    case .trial:
        print("お試し会員の処理を行う")
    }
}
foo() // "プレミアム会員の処理を行う"
```

改善後のコードには以下の利点があります。

- enumを定義することによって、APIレスポンスとして返却されうる値に対して型と名前が付与されることで、その仕様が読み取りやすくなる。
- guard節によって、MemberType型に変換した結果がnilである＝仕様として想定外の値である、という実装意図が明確である。
- 将来`enum MemberType`にcaseが増えた際に、`switch memberType`にてcaseを網羅していないとコンパイルエラーとして検出でき、改修漏れを防止できる。

一行でまとめると、
Swiftの「Null安全」、「型安全」、そして「コンパイラによるenumの全ケース網羅チェック」という特徴を活かしましょう、
というお話でした。
macのsmbサーバーの設定(com.apple.smb.server.plistの値)を書き換える

macでsambaを運用している場合、sambaの設定は/Library/Preferences/com.apple.smb.server.plistを書き換える必要がある。



```
sudo scutil --prefs com.apple.smb.server.plist

get /

d.add ProtocolVersionMap # 7

set /

commit

apply

quit
```


https://support.apple.com/ja-jp/HT204021

7なのは
　1	SMB 1 をサポートする
　2	SMB 2 をサポートする
　4	SMB 3 をサポートする
のビット和

SMB1を無効にしたいなら、6
SMB3だけにするなら、4
S3の画像データを無理やりBlob型に変換する方法

# なにこれ
S3の画像データをBlob型にしたい！っていう珍しい状況になった時の解決策です。
Vue(Nuxt)で下記のように`'Content-Type': 'multipart/form-data'`で送りたい！って時に遭遇する可能性が高そうです。

```test.js
        const response = await this.$axios.put(`/hoges/${this.hoge.id}`, req, {
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        })
```

# どうやるか
### axiosを利用します
axiosでs3のURLをgetして、その時にresponseをblobで受け取ります。
受け取ったresponseを使って、new BlobでBlob型に変換します。

```test.js
import axios from 'axios'

// 〜省略〜
          const req = new FormData()
          try{
            const response = await axios.get(S3のURL, { responseType: 'blob' })
            const blobData = new Blob([ response.data ], { type: "image/png" })
            req.append(`image`, blobData)
          } catch (error) {
            console.error(error.response)
          }
```

その後は肉なり焼くなり好きに処理してください！
【SNS】SNSとは

## SNSとは
**Amazon Simple Notification Service** の略
パブリッシャーからサブスクライバーへのメッセージ配信を提供するマネージド型サービス

**パブリッシャー**：メッセージの送信を行う側
**サブスクライバー**：メッセージの受信を行う側

- 通信の取り消しは不可
- メッセージの通信順序は保証されない
- 1メッセージあたりの **最大サイズは256KB**
- 、**HTTP(S)**、**Eメール**、**SMS（Mobile Push*）*、**AWS SQS**といった様々なプロトコルによりPush型で通知する
- 各プロトコルに合わせメッセージを変換するため、パブリッシャーはサブスクライバーが利用しているプロトコルを意識せずメッセージを配信可能

## SNS連携
AWSの様々なサービスと連携可能で、疎結合アーキテクチャを実現

- Amazon CloudWatch：Billing Alertの通知
- Amazon SES：Bounce/Complaintのフィードバック通知
- Amazon S3：ファイルアップロード時の通知
- Amazon Elastic Transcoder：動画変換処理完了/失敗時の通知

## 仕組み
1. トピックを作成する
2. サブスクライバーとの紐付けを行う
3. トピックにメッセージを送信すると紐付けられたサブスクライバーにメッセージが送信される

**トピック**：メッセージを送信し、通知を受信する通信チャネルで、発行者と受信者が相互に意思疎通するためのアクセスポイントを提供する

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/e645efc1-1659-6ad5-3ba1-247db534fcb1.png">
【HTML・CSS】ゲーミングな文字を作ります

ゲーミングPCが欲しい・・・でも高すぎる・・・そんな風に考えたことはありませんか？
雰囲気だけでもゲーミング感を味わいたい・・・そんな私のために、HTMLとCSSでゲーミング風＝虹色に光る文字を作ります。
実用性はあまりないので、ネタとしてご覧ください。

# 作り方
作り方としては、大きく分けて2段階あります。

1. 背景を文字で切り抜く
2. 背景に虹色を適用する

以上の順で、作成していきます。


## 背景を文字で切り抜く
背景を文字で切り取るには、CSSの`background-clip`を使います。
これは背景を適用する範囲を決めるプロパティです。（[参考](https://developer.mozilla.org/ja/docs/Web/CSS/background-clip)）
使用できる値には以下があります。

* `border-box` : 境界の外側の辺まで背景を表示する
* `padding-box` ： パディングの外側の辺まで背景を表示する
* `content-box` ： コンテンツのみ背景を表示する
* `text` ： テキスト部分のみ背景を表示する

このうち、`text`を使うことで、背景を文字にすることができるようになります。
また、文字の色を透明にすることを忘れないようにしましょう。切り取った背景が文字で見えなくなってしまいます。

```css:style.css
.gaming{
    color: transparent;             /*文字を透明にする*/
    background-clip: text;          /*背景を文字で切り抜く*/
    background-image : hogehoge     /*文字にしたい背景を入れる*/
}
```

## 背景に虹色を適用する
背景を虹色にするにはグラデーションを使います。（[参考](https://webparts.cman.jp/box/rainbow/)）
`background-image`プロパティに`linear-gradient`を使うことでグラデーションを作ることができます。
ここで注意しないといけないのが、`background`でも背景をグラデーションにできます。
が、`background-clip`は`background`で指定した背景を切り取ることができません。必ず`background-image`プロパティに指定しましょう。

```css:style.css
.gaming{
    color: transparent;             /*文字を透明にする*/
    background-clip: text;          /*背景を文字で切り抜く*/
    background-image : linear-gradient(45deg,
        red,
        orange,
        yellow,
        green,
        aqua,
        blue,
        purple);
}
```

これで文字が虹色になりました。
さらにアニメーションをつけてゲーミング感をアップさせます。
`animation`プロパティで、アニメーションをつけることができます。
詳細は[こちら](https://developer.mozilla.org/ja/docs/Web/CSS/animation)を参照してください。
下の例では、4秒で左右に無限回往復移動するアニメーションになっています。

```css:style.css
.gaming{
    font-size: 36px;
    color: transparent;             /*文字を透明にする*/
    background-clip: text;          /*背景を文字で切り抜く*/
    background-image: linear-gradient(45deg,
        red,
        orange,
        yellow,
        green,
        aqua,
        blue,
        purple);
    background-size: 1200%; 
    animation: 4s linear 0s infinite alternate slide;    /* slideアニメーションを4秒で往復の線形移動を無限回行う */
}

@keyframes slide { 
    from { background-position: 0% 0%; } 
    to { background-position: 100% 0%; }    /* 右から左へ移動するアニメーション */
}
```

これで、`gaming`クラスを適用した箇所が、色が変わりながら光る文字ようになります。
ぜひ試してみてください。
【モバイル】【Chrome】画面スクロール時に Resize イベントも同時に発火されるので注意する

## 結論

タイトルそのまま。

モバイル版の Chrome(Android, iPhone 問わず)では、画面をスクロールした際に resize イベントも同時に発火されるので、注意したい。
※Safari は不明。

## 挙動

挙動自体は Chrome の仕様。

スクロールした際、 Chrome の画面上部のアドレスバーの表示・非表示が切り替わる。
それにより Chrome の画面サイズが変更するため、Resize イベントが発行されるとのこと。
詳細は以下を参照。

### 参考

- <https://developers.google.com/web/updates/2016/12/url-bar-resizing>
- <https://stackoverflow.com/questions/17328742/mobile-chrome-fires-resize-event-on-scroll>
- [Viewport height is taller than the visible part of the document in some mobile browsers](https://nicolas-hoizey.com/articles/2015/02/18/viewport-height-is-taller-than-the-visible-part-of-the-document-in-some-mobile-browsers/)

## 対策

画面描画時に画面サイズを格納しておき、

```js
let width = window.innerWidth,
  height = window.innerHeight;
```

Resize イベント発火時に現在の画面サイズと発火前のそれを比較することで、画面サイズが変わった場合にのみイベントを発火させることができる。

```js
if (window.innerWidth !== width || window.innerHeight !== height) {
  //Do something
}
```

## 最後に

今回開発中の Web アプリにおいて、「モバイルを傾けた際に実行したい処理」を resize イベントに仕込んだところ、画面がスクロールされた際にも発火されてしまった。
以後気をつけたい。
【Java・SpringBoot・Thymeleaf】エラーメッセージを実装（SpringBootアプリケーション実践編3）

ログインをして、ユーザー一覧を表示するアプリケーションを作成し、
Springでの開発について勉強していきます🌟
前回のデータバインドに引き続きバインド失敗時のエラーメッセージを実装します

前回の記事🌟
[【Java・SpringBoot・Thymeleaf】データバインド（SpringBootアプリケーション実践編2）](https://qiita.com/suema0331/items/aa2f225c6974397f2c8d)

#エラーメッセージを実装
* src/main/resouces配下に**`messages.properties`**というファイルを作成
* その内に、**各フィールドに対応するメッセージを設定**する

##パターン1
* **`typeMismatch.<ModelAttributeのキー名>.<フィールド名>=<エラーメッセージ>`**

```src/main/resources/messages.properties
typeMismatch.signupForm.age=数値を入力してください
typeMismatch.signupForm.birthday=yyyy/MM/dd形式で入力してください
```

##パターン2
* **`typeMismatch.<フィールド名>=<エラーメッセージ>`**
* 複数のオブジェクトでageやbirthdayというフィールド名を使っていた場合、すべてにメッセージが適用される

```src/main/resources/messages.properties
typeMismatch.age=数値を入力してください(パターン2)
typeMismatch.birthday=yyyy/MM/dd形式で入力してください(パターン2)
```

##パターン3
* **`typeMismatch.<フィールドのデータ型>=<エラーメッセージ>`**
* 同じデータ型にメッセージが適用される

```src/main/resources/messages.properties
typeMismatch.int=数値を入力してください(パターン3)
typeMismatch.java.util.Date=yyyy/MM/dd形式で入力してください(パターン3)
```

#SpringBootを起動して、ログイン画面を確認！
* http://localhost:8080/login
* ユーザー登録ボタンをクリックするとログイン画面に遷移
* プロパティファイルを作成後、エラー文字列を入れると**作成したエラーメッセージが表示**されましたo(^_^)o
* 次回はメッセージプロパティファイルを複数用意して切り替える方法を実践します🌟

![修正後エラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/5b29d31d-58d6-f9a7-2914-2051ed8629ac.png)
Wordpressにおけるregister_sidebar()

<h1>register_sidebar()関数について</h1>

Wordpressに予め用意されている※ウィジェットを利用するためには予め機能の有効化が必要。

register_sidebar()はサイドバーを定義する関数。


※ウィジェットとはWordpressでは１つ１つのブログパーツのことを指しています。


![スクリーンショット 2020-11-24 7.01.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/794525/1d17faba-c9f9-4049-2021-7daa0226dd74.png)
スクロールして画面に表示されたらイベントが発生する

やりたいこと
---
スクロールして要素が画面に表示されると同時にイベントを発生させたい。

```sass:stylesheet.scss

$(window).scroll(function () {
  $(".slide").each(function (index, el) {
    let scroll = $(window).scrollTop();
    let offset = $(el).offset().top;
    let winH = $(window).height();
    if (scroll > offset - winH / 2) {
      $(el).addClass("in");
    }
  });
});

```

表示させたい要素のクラス名が「slide」で、複数の要素に当てたいので、「each」を使って繰り返し処理をかけています。

とりあえず画面中央まで来たらイベントが発生するように記述していますが、winH/2の２の部分を、小さい数字に変えていくと、早くイベントを発生させることができますし、大きい数字に変えると遅くイベントを発生させることができます。

結論
---
elが何者かよくわかっていないのでこれからも勉強します。。
thisのようなものだとは聞いたがイマイチ…
uBlock OriginでYouTubeが正常に表示されない解決する

#はじめに
最近ではアドブロックを使用している人も多いと思います。
その中でも[**uBlock Origin**](https://chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm)はChromeウェブストアから無料で入手することができるため、使用されている方も多いのではないでしょうか。

しかし、uBlock Originを作動中に[**YouTube**](https://www.youtube.com)を開くと**サイドバーが空白**になっていたり、**YouTubeライブのコメントが更新されなかったり**、**高評価が反映されなかったり**、様々な機能が使えなくなってしまいます。

この記事ではそのような問題を簡単に解決する方法を紹介します。(2020/11/24時点)

#環境
Google Chrome
uBlock Origin v1.30.6

#方法
初めに、Google Chrome右上の拡張機能一覧から**uBlock Originをクリック**します
電源ボタンとブロックした数などの情報が現れます
その中から**［ダッシュボードを開く］**のマークを選択します
（表示されていない場合は**詳細を表示**を押してみてください。）
これです↓
![adbrok.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333697/229be428-ae65-9729-ff2e-c65d382330eb.png)

クリックするとダッシュボードが現れるのですが
**［MYフィルター］**を選択します

ここでは特定のサイトをブロックする設定ができますが、今回はホワイトリスト機能を使ってYoutubeのドメインをフィルターから除外します。

やり方は**下記のコードを新たに追加**するだけ

```
@@||www.youtube.com/*^
```
入力したら**［✔変更を適用］**を押してください。


これで[**Youtube**](https://www.youtube.com)にアクセスしても様々な機能が使えたまま広告がブロックできます。
KotlinでMockolo風のモック生成ライブラリを作ってみた

## 作ってみたライブラリ

KotlinでMockolo風のライブラリがあるか調べてみたが、なさそうだったので自分で作ってみた[^2]。名前は、kotlin-simple-mockとした。
interfaceに@Mockableというアノテーションを付けると、そのMockを生成する。

**GitHub**
https://github.com/KamikazeZirou/kotlin-simple-mock


## なぜライブラリを作ったか

普段、Kotlinでテストコードを書くときにmockKやMockitoを使っている。
これらのライブラリに大体満足しているのだが、一つだけ不満がある。

複雑でもなく、数も少ないテストケースを実行するときに、もっさり感があることだ。

mockKだと1秒以上かかることもざらである。Mockitoはmockより格段に高速だが、それでも100ms以上かかることはざらである。

同じような条件で、自前でテストモックを作ってテストを実行させると、100msもかからなかった。

高速なテスト実行を重視するのであれば、自前mockを作れば良いということだ。だが、mockをいちいち実装するのは面倒だ。

そこで思いあったのが、Swiftの[Mockolo](https://github.com/uber/mockolo)というモック生成ライブラリだ。MockoloはProtocol[^1]から単純なmockを高速に生成するライブラリだ。Kotlinでもこの方式のライブラリがあれば、Mockを自動生成しつつ、テストの実行時間を高速にできると考えた。

### ざっくりとした使い方

#### Step 1. Mockを生成したいinterfaceを指定する

Mockを生成したいinterfaceに@Mockableを付与する。

```kotlin

import mock.simple.kotlin.Mockable

@Mockable
interface Hello {
    fun add(a: Int, b: Int): Int
    var num: Int
}
```

#### Step 2. ソースコードをビルドして、Mockを生成する

Mock生成にkaptを利用しているので、kaptを実行させるためにソースコードをビルドする。以下のようなコードがMockHello.ktとして生成される。

```kotlin
class MockHello : Hello {
  public var addHandler: ((a: Int, b: Int) -> Int)? = null
  public var addCallCount: Int = 0
  public var addArgValues: MutableList<List<*>> = mutableListOf()
  public override fun add(a: Int, b: Int): Int {
    addCallCount += 1
    addArgValues.add(listOf(a,b))
    return addHandler!!(a,b)
  }

  public var underlyingNum: Int? = null
  public var numSetCallCount: Int = 0
  public override var num: Int
    get() = underlyingNum!!
    set(newValue) {
      underlyingNum = newValue
      numSetCallCount += 1
    }
}
```

#### Step 3. テストコードを書く

```kotlin
class HelloTest {
    @Test
    fun add() {
        // <メソッド名>FuncHandlerに関数を設定することで処理を差し替える
        val mock = MockHello()
        mock.addHandler = { a, b ->
            a + b
        }

        val result = mock.add(1, 2)

        assertEquals(3, result)
        // <メソッド名>CallCountという変数で、メソッドの呼び出し回数を取得する
        assertEquals(1, mock.addCallCount)
        // <メソッド名>FuncArgValuesという変数で、メソッドが呼ばれたときの引数を取得する
        assertEquals(listOf(1, 2), mock.addArgValues.first())
    }
}
```

## Mockライブラリのテスト実行時間の比較

https://qiita.com/zigenin/items/75679e1988b72dd728ac
(この記事の自前Mock = このライブラリで生成したMock)

## 最後に

ライブラリを作ったり、この記事をここまで書いておいてなんだが、Kotlinでテスト速度を追求したい人はMockitoを使うのが良いと思う。

初回のテスト実行時間はこのライブラリで短くなるが、kaptによってビルド時間が長くなることを考慮すると、Mockito使った方が良さそう[^3]。


[^1]: Kotlinのinterfaceに相当する。
[^2]: ある用途のサービスやライブラリを誰も作っていない時、本当に新規な時と考え方の筋が悪い時がある。後述するが、このライブラリは後者のケースだと思う。単に作っておしまいで済ませるのも勿体なく感じたので、この記事を書いた。
[^3]: このライブラリによるビルド時間の増加量は検証していない。
UserScriptでの@includeで詰まったので

atcoder関連のUserScriptを書いていて、

<strong>https:// atcoder.jp/users</strong>　のみでスクリプトを実行したいが
<strong>https:// atcoder.jp/users/kemkemG0?graph=rank</strong> や、
<strong>https:// atcoder.jp/users/kemkemG0/history</strong>　等では実行してほしくない ということがあった。

シンプルに

```javascript
// @include      *://atcoder.jp/users*
// @exclude      *://atcoder.jp/users/*?graph=rank
// @exclude      *://atcoder.jp/users/*/history*
```

でよかった。
ASPEED SOCFLASHを使ったBMCファームウェアのインストール方法

Yafuflashなど通常のツールでのファームウェア更新に失敗してサーバーのBMCが文鎮化した時の救出方法です。開発中の製品で通常の方法ではまだファームがうまく更新できないなんて時にも実行します。

# 適用できるサーバ
ASPEED製のBMCを搭載しているサーバなら、どれでもいけると思います。サプライヤーはSuperMicro、Quantaなどいろいろありますね。`readme.txt`に対応しているASPEED BMCのモデルが記載されています。

# SOCFLASHの入手方法
SOCFLASHはサーバーのサプライヤーが提供するものを使うのが基本です。本家の[ASPEEDのダウンロードサイト](https://www.aspeedtech.com/support_driver/)では登録デベロッパー限定となっています。登録用のリンクなど見当たらず、一般ユーザーが登録するのはハードルが高そうです。サプライヤーとASPEED以外にも、ググると第3者の共有もすぐに見つかりました。

# 使い方
DOS環境にブート可能なUSBメモリを作成します。[Rufus](https://rufus.ie/)というツールを利用すると簡単です。USBメモリにSOCFLASHとインストールしたいBMCファームをコピーします。

あとは、サーバーのブートモードをLegacy BIOSモードに変更して、USBメモリから起動して、下記を実行します。

```
C:\>socflash.efi if=rom.ima_enc option=cfr
```
`if=`は入力ファイル名の指定。書き込みたいBMCファームを指定します。
`option=`はオプション指定です。
`readme.txt`に詳細が載っています。
>    +++ if=the update file
>    +++ of=the backup file
>    +++ option=f|c|2|r|d|x|l|i|m
>    ++++ f: skip the comparision of flash data and force to update
>    ++++ c: use chip erase instead of sector erase
>    ++++ r: reset scratch

今回はサプライヤーから提供されたSOCFLASHがDOS用だけだったのでDOS環境にブート可能なUSBメモリを作成しましたが、SOCFLASHはDOS以外にも、bsd、inux、uefiシェル、windowsに対応しています。ほとんどのサーバーでUEFIシェルは標準装備ですし、uefiシェルはDOSよりもシェルとしての使い勝手が良いので、救出用としてはuefi版を使うのが一番良さそうですね。

# 注意
このSOCFLASHとは読んで字の如く、指定したファイルの内容をただ単にBMCに書き込むツールです。Yafuflashなどの通常方法でのファーム更新と違って、電子署名を検証して改竄されてないことを確認したりとか、機種適合性とかは一切確認しないのでご利用は自己責任で。
Illuminate\Database\QueryException  : could not find driver (SQL: PRAGMA foreign_keys = ON;)の解決方法

##結論　SQLiteの接続用ドライバーをインストール
まずPHPのバージョン確認

```Ruby:
$ php -v
PHP 7.4.12 (cli) (built: Oct 31 2020 17:04:25) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.12, Copyright (c), by Zend Technologies
```
PHPのバージョンに合わせてインストール

```Ruby:
$　sudo apt-get install php7.4-sqlite3
```

##無事に "php artisan migrate" できました

```Ruby:
$  php artisan migrate
Migration table created successfully.
```
AOJ 用のコマンドライン CLI ツールを作った

ちょっと前に [Aizu Online Judge (AOJ)](https://onlinejudge.u-aizu.ac.jp/home) のための CLI ツールを作成したので記事を書いてみようと思う

作成したものはこれ: https://github.com/travelist/aoj-cli

機能は限りなくシンプルで、以下のことができる:

- 問題文のテストケースを含むディレクトリ作成
- テストの実行
- 提出

![animation (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31970/1af25b39-8996-9de1-6b44-07dd24be4b68.gif)


### 導入方法

バイナリーならば [ここ](https://github.com/travelist/aoj-cli/releases) からダウンロードでき、Mac ならば homebrew を使って以下のコマンドでインストールできる:

```shell
brew tap travelist/homebrew-aoj-cli
brew install aoj
```

本題とは関係ないけれども、CLI ツールを作って配布するのに Go が便利だと感じた。
バイナリーとして配布できるので、他人のPCの実行環境(例えば Python のバージョンなど)を気にしなくてよいのは大きなメリットだと思う。

### AOJ CLI の設定 (初回のみ実行)

```shell
aoj init
```

### テストサンプルのダウンロードとディレクトリの作成

```shell
aoj gen [PROBLEM-ID]
```

### ソースコードのテスト

```shell
# cd ./[PROBLEM-ID]
aoj test
```

### ソースコードの提出

```shell
aoj submit
```

###  その他設定

デフォルトの設定ファイル: `~/.aoj-cli/config.toml`
デフォルトのテンプレートファイル: `~/.aoj-cli/template.txt`

```toml
[gen]
template_file = "$HOME/.aoj-cli/template.txt"
destination_file_name = "main.cpp"

[test]
before_all="g++ main.cpp -o a.out"
before_each=""
command="a.out"
after_each=""
after_all=""

[submit]
language = "C++"
source_file_name = "main.cpp"
```

|parameter|description||
|---|---|---|
| gen.template_file | テンプレートファイルへのパス | |
| gen.destination_file_name | 生成するコードのファイル名 | |
| test.before_all | テスト全体の前に実行するコマンド | |
| test.before_each | 各テスト前に実行するコマンド | |
| test.test_commands | テストで実行するコマンド | |
| test.after_each | 各テスト後に実行するコマンド | |
| test.after_all | すべてのテスト後に実行するコマンド | |
| submit.language | 提出するプログラムの言語 | ex: `JAVA`, `C++` |
| submit.source_file_name | 提出時するファイル名 | |


### 最後に

もしよければ使ってみてもらえたらと思います m(__)m
Laravel 環境構築 (Ubuntu 18.04 LTS )

##1. PHP7.4のインストール
###下準備
```ruby:
$ sudo apt-get update
$ sudo apt -y install software-properties-common
$ sudo add-apt-repository ppa:ondrej/php
$ sudo apt-get update
```
 これでPHP 7.4 をインストール可能なリポジトリを apt で使えるようになった。
###インストール
```ruby:
$ sudo apt install php7.4 php7.4-mbstring php7.4-dom
```
他に必要なものも一緒にインストールしておく。

###インストールできたか確認

```ruby:
$ php -v
PHP 7.4.12 (cli) (built: Oct 31 2020 17:04:09) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.12, Copyright (c), by Zend Technologies
```
こうなればOK！

##2. Comporserのインストール

LaravelをインストールするためにはComposerというのもをインストールする必要があります。
ComposerはPHPのパッケージ管理ツールで、Composerを使うとパッケージを効率よく管理することができるらしい。

```ruby:
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
```

公式サイトのコマンドを使用　(https://getcomposer.org/download/)

###確認
```ruby:
$ ./composer.phar -V
Composer version 1.10.1 2020-03-13 20:34:27
```
これでOK

###いつでもComposerを使えるようにする
```ruby:
$ sudo mv composer.phar /usr/local/bin/composer
$ sudo chmod +x /usr/local/bin/composer
$ composer -v
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 2.0.7 2020-11-13 17:31:06
```
以下省略。
##zipコマンドをインストール
```ruby:
$ sudo apt install -y zip unzip
```
Laravelのインストールを行う際にunzipコマンドが必要になるため、zipコマンドのインストール。

##Laravel6.xをインストール
```ruby:
$composer create-project --prefer-dist laravel/laravel="6.*" laravel6
```

下記を実行すると実行フォルダの下にlaravel6というフォルダが作成され、そのフォルダの中にLaravelに必要なファイルが保存される。

laravel6のところは好きな名前でOK

##サーバー起動して確認

```ruby:
$ cd laravel6
$ php artisan serve
```
![SharedScreenshot.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513128/79bcbb08-0ce7-a463-de36-dc38f122842d.jpeg)
http://127.0.0.1:8000/
にアクセスしてこの画面になればOK！
Laravelのバージョンを指定する方法

##結論　composerコマンドで指定する
```ruby:ターミナル
$ composer create-project --prefer-dist laravel/laravel="6.*" sample_app
```
これでLaravel6系統がインストールされる。
##バージョン確認
```ruby:ターミナル
$ php artisan -V
Laravel Framework 6.20.4
```
管理者以外も Chocolatey でインストールできるようにする

# はじめに

Chocolatey 自体はとても便利で気に入っているのですが、管理者権限で PowerShell を実行してから都度 `choco install ~` するのが面倒すぎて、何か良い解決策は無いかと調べていました。:mag: 

一応公式サイトにも [管理者以外でインストール可能にする手順](https://chocolatey.org/docs/installation#non-administrative-install) は掲載されているのですが、私の手元の環境だとエラーが発生してしまいセットアップできませんでした。。 :persevere: 

しかし、お手軽に管理者以外でもインストール可能にする方法を他に見つけましたので、備忘録も兼ねて記事として残しておくことにしました :writing_hand: 

# 対処法

1. PowerShell を起動して `powershell start-process cmd -verb runas` を実行する
2. 別ウインドウでコマンドプロンプトが起動したら `choco install gsudo` を実行する
3. 先ほどの PowerShell で `gsudo choco install ~` でインストールが成功するか確認する

`powershell start-process cmd -verb runas` コマンドを実行すると、**別ウインドウで管理者として実行したコマンドプロンプトが起動します。**そこで `choco install gsudo` を実行することで、Windows 版の sudo である [gsudo](https://github.com/gerardog/gsudo) をインストールします。

これで `gsudo choco install ~` のような形で PowerShell からコマンドを打ち込むことで、管理者として `choco install ~` が実行できるようになりました。今後は管理者として PowerShell を起動せずとも各種ソフトウェアのインストールが Chocolatey で可能になります！ :relaxed: 

# おわりに

PowerShell については最近使い始めたせいもあって不慣れなため、本記事タイトルの内容をどう実現すればよいか良く分かりませんでした。。

ただ sudo のような仕組みが Windows にもあれば、それだけでサクッと解決できそうだなーと思いググっていたら、非常に楽な解決策を見つけることが出来て満足です :laughing: 

# 参考リンク

- [macOS（またはLinux）用パッケージマネージャー — Homebrew](https://brew.sh/index_ja)
- [Chocolatey Software | Chocolatey - The package manager for Windows](https://chocolatey.org/)
- [gsudo - a sudo for Windows](https://github.com/gerardog/gsudo)
- [コマンドから管理者モードでWindows Terminalを起動する](https://www.xenos.jp/~zen/blog2/index.php/2020/05/31/post-3944/)
【RSpec】traitの使い方を整理してみた

　最近RSpecについて勉強している者です。

　他の方のポートフォリオを拝見する機会がありまして、
「テストに書いてあるtraitって何だろう？」
と疑問に思ったため、現在理解している点についてアウトプットしました。
（「everyday rails - rspecによるrailsテスト入門」
を参考に勉強している途中です）

　間違っている点などありましたらご指摘よろしくお願いします。

# traitの使い方
FactoryBotを用いて次のようなテストデータ（ファクトリ）を作成するとします。

```ruby:spec/factories/user.rb
FactoryBot.define do
  factory :user do
    name = "Taro"
    name { name }
    email = "test1@example.com"
    email { email }
    password = "pass123"
    password { password }
  end
end
```

Userというモデルにnameカラム、emailカラム、passwordカラムが存在しますね。

ここで
「emailだけ『test2@example.com』になっているファクトリを新しく作りたいな」
と考えたとします。その時は「継承」という機能を使うと便利です。

```ruby:spec/factories/user.rb
FactoryBot.define do
  factory :user do
    name = "Taro"
    name { name }
    email = "test1@example.com"
    email { email }
    password = "pass123"
    password { password }

    #新しいファクトリを定義
    factory :another_user do
      email = "test2@example.com"
      email { email }
    end
  end
end
```

　なぜ「継承」を利用するのかというと、「記述が重複してしまうことを防ぐため」です。
継承を利用しない場合、今回のような規模なら問題ありませんが、これがもっとファクトリ内のインスタンス数が多い中で、「新しいファクトリを定義したい」となった場合、非常に手間です。例えば、「10個のインスタンスがある内の1個だけ属性値を変えたい」という場合でも、その10個全てを再定義しないといけませんから😅

　そこで、継承を使うことで、「emailだけ『test2@example.com』のファクトリを新しく作る」ということが可能になります（つまり、記述の重複がなくなる！）。

　しかし、複雑なオブジェクトを構築したいときや、テストデータに関する要件がもっと複雑になってきた時は、継承よりも「trait」の方が向いているそうです（こちらに関しては、現在勉強中です。こちらの方が、traitを使う本当の理由のようです）。

  継承をtraitにしたい時は、次のように記述します。

```ruby:spec/factories/user.rb
FactoryBot.define do
  factory :user do
    name = "Taro"
    name { name }
    email = "test1@example.com"
    email { email }
    password = "pass123"
    password { password }

    #新しいファクトリを定義
    trait :another_user do
      email = "test2@example.com"
      email { email }
    end
  end
end
```

　定義したファクトリをspecファイルで呼び出したい時は、以下のように記述します。

```ruby:user_spec.rb
user = FactoryBot.create(:user(モデル名), :another_user（ファクトリ名）)
```

　このtraitを使用することでも、「記述が重複してしまうことを防ぐこと」ができます。


　いかがでしたか？
　traitは、複雑なオブジェクトを構築したいときや、テストデータに関する要件がもっと複雑になってきた時にこそ輝くそうなので、今後理解できたら、また内容を更新したいと思います。

　ここまで読んでいただきありがとうございました。