OmniAICreator/Qiita-1.07M huggingface dataset:
[playframework2]scalaテンプレートで変数を状態に応じた値で初期化する

変数を状態に応じた値で初期化するコードを書きたくなった。

同じ結果を得るには以下の方法があるけど冗長なので。

* @if/else構文を使う
* 子テンプレートを実装
* ロジック側に状態に応じた結果を返すメソッドを実装。テンプレートからはそのメソッドを呼び出す

[公式ドキュメント(scala templates)](https://www.playframework.com/documentation/2.8.x/ScalaTemplates)には記載されていない。

色々とコンパイラに怒られながら試行錯誤した結果、以下のような変態的なコードで実現できました。

## 構文

```html:*.scala.html
@import scala.Predef; var 変数 = 初期値
@(変数 = if(condition){値1}else{値2})
```

## 例

体験プランの場合は、見出しを「体験談」、それ以外の場合は「口コミ」とする。

```html:*.scala.html
@import scala.Predef; var title = ""
@(title = if(isActivity){"体験談"}else{"口コミ"})

<span>@title</span>
```

これ、初見で読める人いないでしょうね。笑

可読性を考えると、極めてシンプルな場合にだけ利用を限定したほうが良いと思います。
基本的には`@if/else`構文もしくは`ロジック側に状態に応じた結果を返すメソッドを実装`するほうがよいと思います。

お役にたてば幸いです。
【Flutter】動的に年(year)のリストを生成する方法

## 動的にリストを生成する
[List<E>.generate](https://api.flutter.dev/flutter/dart-core/List/List.generate.html)クラスを利用します。

```dart:
final now = DateTime.now();
void main() {
  final yearList = List.generate(5, (i) => now.add(Duration(days: 365 * i)).year);
  print(yearList);
}
```

実行結果は以下になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/838e6373-f6fd-90b9-d2b2-0ff90c943e3b.png)

Listのgenerateクラスは意外と便利なので、色々な使い方ができるかと。
ぜひぜひ。
M1 Mac で x86_64 の ruby をビルドして CocoaPods を使う

M1 native な ruby ではまだ CocoaPods がうまく動かなかったので、x86_64 版 ruby をビルドして CocoaPods を動かすためのメモです。

追記: そういえば、いつの間にか brew で入れた cocoapods がちゃんと動くようになってますね。

## 目標

- Rosetta 2 の利用は最小限にする。
  - 特に、ターミナルを Rosetta 2 で動かすなんてあり得ない。
  - Homebrew は arm64 版のみを利用。
- x86_64 版 ruby は 2.7.2-x64 みたいな名前にして、arm64 版と共存させる。
- ruby のバージョンは rbenv global ではなく、環境変数で切り替える。

## ruby ビルド

1) Homebrew で rbenv をインストール
rbenv 自体はシェルスクリプトなので、CPU アーキテクチャ関係ないはず。

```
% brew install rbenv
```

2) x86_64 版 readline ライブラリをダウンロード
次のリンク先から、`readline-8.1.big_sur.bottle.tar.gz` をダウンロード。
x86_64 版が欲しいので、arm64 じゃないやつを選ぶこと。

https://bintray.com/homebrew/bottles/readline/8.1#files

3) ダウンロードした readline ライブラリを展開
展開先はとりあえず `~/.rbenv/lib-x64` あたりで。

```
% mkdir -p ~/.rbenv/lib-x64
% tar zxCf ~/.rbenv/lib-x64 ~/Downloads/readline-8.1.big_sur.bottle.tar.gz
```

4) ruby-build 定義ファイルを別名でコピー
この定義ファイルの名前が rbenv で指定する ruby のバージョン名になります。
ビルドに成功したらコピーした定義ファイルは消して構いません。

```
% cp $(brew --prefix ruby-build)/share/ruby-build/2.7.2 2.7.2-x64
```

5) ビルド
ちょっと長いけど、お間違えのないように。

```
% RUBY_CONFIGURE_OPTS=--with-readline-dir="$HOME/.rbenv/lib-x64/readline/8.1" arch -x86_64 rbenv install 2.7.2-x64
```

## CocoaPods インストール

1) 環境変数 PATH に ~/.rbenv/shims を追加しておく

```
export PATH="$HOME/.rbenv/shims:$PATH"
```

2) ビルドされた ruby を確認

```
% rbenv versions
* system (set by /Users/hoshi/.rbenv/version)
  2.7.2-x64
```

3) 環境変数 RBENV_VERSION で 2.7.2-x64 を指定して ruby を実行

```
% RBENV_VERSION=2.7.2-x64 ruby -v
ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin20]
```

4) CocoaPods をインストール

```
% RBENV_VERSION=2.7.2-x64 gem install cocoapods
```

## 使い方

環境変数を毎回指定して pod コマンドを実行するのは面倒。

```
% RBENV_VERSION=2.7.2-x64 pod --version
% RBENV_VERSION=2.7.2-x64 pod init
% RBENV_VERSION=2.7.2-x64 pod install
```

とはいえ、`rbenv global 2.7.2-x64` はしたくないので、.bashrc または .zshrc にエイリアスを登録。

```
alias pod='RBENV_VERSION=2.7.2-x64 pod'
```
ちょっと書くのが大変なC++vs書くのが簡単だけど遅いPython(再帰編)

Atcoder Beginner Contest 184にこのような問題があります

>制限時間:2sec/ メモリ制限:1024MB
>
>袋の中に金貨が$A$枚、銀貨が$B$枚、銅貨が$C$枚入っています。袋の中にあるいずれかの種類の硬貨が100$枚になるまで以下の操作を繰り返します。
>操作：袋の中から硬貨をランダムに$1$枚取り出す。(どの硬貨も等確率で選ばれる。) 取り出した硬貨と同じ種類の硬貨を$2$枚袋に戻す。
>操作回数の期待値を求めてください。
>
>制約:
> ・ $0 \leq A, B, C \leq 99$
> ・ $A + B + C \geq 1$
[ABC184 D - increment of coins](https://atcoder.jp/contests/abc184/tasks/abc184_d)

この問題は文中の「繰り返す」という単語からも察せられる通り、再帰を用いて考えていくのですが(詳しい解説はリンク先の解説を見てください。)、素直に再帰関数を記述すると、例えば$(A, B, C) = (0, 0, 1)$のようなケースでは処理回数が莫大になり、TLE(制限時間オーバー)となってしまいます。そこで、メモ化回帰をするということが必要になっていきます。これは以下の記事がわかりやすいのでそちらを参照してください。

https://qiita.com/drken/items/23a4f604fa3f505dd5ad

メモ化再帰を用いてC++で実装したコードがこちらになります。

```cpp
#include <bits/stdc++.h>
using namespace std;
double dp[101][101][101];
double count(int a,int b,int c){
    if(dp[a][b][c]){//メモ化部分。すでに計算済みだったら計算済みの数値を返す
        return dp[a][b][c];
    }
    double d = (double)a/(a+b+c);
    double e = (double)b/(a+b+c);
    double f = (double)c/(a+b+c);
    if(a == 100 || b== 100|| c==100){
        return 0;
    }else{
        double dd = d*(count(a+1, b, c)+1) + e*(count(a, b+1, c)+1) + f*(count(a, b, c+1)+1);
        dp[a][b][c] = dd;
        return dp[a][b][c];
    }
}

int main(void){
    int a, b, c;
    cin >> a >> b >> c;
    cout << setprecision(10) << count(a, b, c) << endl;
    return 0;
}
```

もう少し記述を最適化できると思いますがこれでACできます。C++初心者なので出力するときに有効数字を記述してあげなくてWAを1回出しました。

C++は自分で配列を用意し、計算結果を入れ、チェックするという処理が必要でしたが、Pythonではどう書けばよいでしょうか。実はPythonにはfunctools.lru_cacheというライブラリがその役割を果たしてくれます。

具体的には
>@functools.lru_cache(maxsize=128, typed=False)
>
>関数をメモ化用の呼び出し可能オブジェクトでラップし、最近の呼び出し最大 maxsize 回まで保存するするデコレータです。高価な関数や I/O に束縛されている関数を定期的に同じ引数で呼び出すときに、時間を節約できます。
>結果のキャッシュには辞書が使われるので、関数の位置引数およびキーワード引数はハッシュ可能でなくてはなりません。
>引数のパターンが異なる場合は、異なる呼び出しと見なされ別々のキャッシュエントリーとなります。 例えば、 f(a=1, b=2) と f(b=2, a=1) はキーワード引数の順序が異なっているので、2つの別個のキャッシュエントリーになります。
>
>https://docs.python.org/ja/3/library/functools.html
とあるように、関数の計算結果をmaxsize回保存してくれます。maxsize=Noneとすることによって保存回数を無制限にできます。

例えば、フィボナッチ数列において

```python
@lru_cache(maxsize=None)
def fib_memo(n):
    if(n < 2):
        return n
    else:
        return fib_memo(n-1)+fib_memo(n-2)
```
このように記述するだけでメモ化の役割を果たしてくれます。

そこで```@lru_cache```デコーダーを実際に使用して上の問題を解くと

```python
from functools import lru_cache

@lru_cache(maxsize=None) #メモ化
def count(a, b, c):
    if(a == 100 or b == 100 or c == 100):
        return 0
    else:
       return  (a/(a+b+c))*(count(a+1, b, c)+1) + (b/(a+b+c))*(count(a, b+1, c)+1) + (c/(a+b+c))*(count(a, b, c+1)+1)
    
a,b,c = map(int, input().split())
print(count(a, b, c))
```
かなり簡単に記述することができました。

しかし、その一方で実行時間を比較してみると

|     |  C++  |Python|
|-----|:----:|:------:|
|実行時間(ms)| 34| 1155|

となり、かなりの差があります。なので制約がこれより大きくなるとPythonではTLEする危険性もあります。(ちなみに、PythonでTLEした際に回避策として用いられるPypy3だと1452msでした)。

# まとめ
Pythonは記述が楽なので早解きする際には使っていきたい一方で制約が大きいとTLEする可能性もありました。なので急いでいない場合にはC++で慎重に書いた方が安全です。両方使えるようになると良いとこ取りできて良さそうですね。
未経験が始めるWebアプリ開発 ~ポートフォリオ作成前に潜む3つの不安~

# はじめに
(※Web系自社開発志望者向けです)
この記事は Rails Tutorial を一周やり切ったエンジニア職種未経験者が、
就活用ポートフォリオ作成で当然ぶち当たる不安や悩みを自分なりの調査で結論を出した物です。

・ポートフォリオってどこが見られるの？
・どんな機能が必要なの？
・何から手をつければいいの？

特にこの三点は悩みました。
私も同じくポートフォリオ作成中ですが、
ここに記事をまとめることで思考の整理を行ってます。
作成前に考えないと後から軌道修正しにくい問題もありますので、
早い段階でこの不安を解消した方が後々効率よく開発できると思います。

なお、記事は自分の考えが変わり次第アップデートしていく予定です。
私の就職が決まったら業界内部からの情報も追加していきますね。
LGTMよろしくお願いします！

(2021/3/11)


# 目次
<!-- タイトルとアンカー名を編集 -->
1. [採用担当者はここを見る！](#Chapter1)
2. [当たり前の機能は点数を稼げない現実](#Chaprter２)
3. [開発初期は〇〇から入れ！](#Chapter3)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# 採用担当者はここを見る！
● 前提
あなたが採用担当者になったらどんな人を採用したいですか？
相手の立場になって考えてみましょう。

採用は人を選ぶ仕事
↓
履歴書だけでなく、ポートフォリオからも人間性を読み取ることが仕事
↓
それらで本人の性格やエンジニアになる理由が伝わる作品であることは大前提

問1 : 君はどんな人なの？(自己PR)
問2 : なんでエンジニアになりたいの？(志望動機)

つまり、この二つの問いに真っ直ぐな回答をぶつけましょう。
具体的にはポートフォリオのコンセプトをしっかり考えてください。

そのサービスが実現するとどんな人が喜ぶのか？
そのサービスを作ろうとした背景は？　etc

● GitHub上で見られるところ
・READMEでアプリの概要を把握する（※重要！）
・コードの可読性が高いか？（静的解析ツールを活用しているか？）
・テストが十分か？
・[issue](https://seleck.cc/647)や[PR](https://ics.media/entry/14449/)を活用しているか？
・インフラにAWSを使っているか？(差がつくポイント！)
・CircleCI等のCIツールを活用しているか？(差がつくポイント！)
・開発環境と本番環境でDockerが活用されているか？(差がつくポイント！)

● アプリ上で見られるところ
・TOPページでアプリがどんな使い方をするか想像する（※重要！）
・[UI/UX](https://wepress.web-magazine.jp/2018/12/06/uiux/#:~:text=%E3%81%A4%E3%81%BE%E3%82%8A%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%A8%E8%A3%BD%E5%93%81%E3%82%84,%E3%81%AA%E6%84%8F%E5%91%B3%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82)が整っているか？
・レスポンスが早いか？
・機能が十分か？
・不具合がないか？

<a id="#Chapter2"></a>
# 当たり前の機能は点数を稼げない現実
● 基本機能
・ユーザー登録
・ログイン（アウト）
・ゲストログイン
・ユーザー情報編集
・記事投稿
・記事詳細
・記事一覧
・いいねボタン
・コメント
・お気に入り
・ユーザー検索
・記事検索
・レスポンシブ対応

これらの機能は他の人と差がつきません。
さらに追加しましょう。

● 発展機能
・シェアボタン
・自分のアプリの実現に必要だと思った難易度の高い機能
・SPA（シングルページアプリケーション）化　etc

＋αの機能に挑戦する姿勢は評価されるでしょう。

<a id="#Chapter3"></a>
# 開発は〇〇から入れ！
コンセプトも決めました。実装する機能も決めました。
次に行うことは設計です。

画面設計を先に行い、それに基づいてDB設計を行います。
それらに関してはたくさん記事があるのでググりましょう。


<a id="#Chapter4"></a>
# さいごに
計画を立てて少しづつやっていきましょう。
作業量は多いですが、焦ってはいけません。

そんな僕と同じ不安を持った人にとって、少しでも前に進む助けになったら幸いです！
LGTMよろしくお願いします！

<a id="#reference"></a>
# 参考動画
詳しい参考情報はこちらです
- [Web系自社開発企業さんへの転職に必要なポートフォリオのレベルとは](https://youtu.be/N0yetny4Zco)
- [ポートフォリオで「やってはいけない」5つのアンチパターン](https://youtu.be/zbJPRNtFdtI)
- [ポートフォリオのトップページとREADMEに関する重要な注意事項](https://youtu.be/vpldv8TZQtY)
(enter "h" for help) [Ynaqdhm]の対処方法

#概要
以下のようにPCから聞かれたときの返答方法について、紹介します。

```
（ターミナル）
Overwrite 〜省略〜 .rb? (enter "h" for help) [Ynaqdhm] 
```

#返答方法
以下のいずれかのアルファベットを、自身の意図に合わせて入力して、enterを押してください。

```
（ターミナル）
 Y - yes, overwrite #上書する。
        n - no, do not overwrite #上書きしない。
        a - all, overwrite this and all others #全てを上書きする
        q - quit, abort #実行の中断をする
        d - diff, show the differences between the old and the new #ファイルを古いデータ、新しいデータで比較する？
        h - help, show this help #ヘルプを呼び出す
        m - merge, run merge tool #マージする
```

#今回は
今回は以下のエラー文のように、もう既に作成していたファイルを、誤って再度作成コマンドを実行したため起こりました。

```
（ターミナル）
〜省略〜
 conflict  spec/system/reviews_spec.rb
```

なので「実行中断をする」のqを選択しエンターを押し、無事対処できました。

以上です。
FreeBSD を 11.x から 12.x にアップグレードしたときに ports が perl 周りで引っかかる

FreeBSD を EoL となる 11.x から 12.x にアップグレードした後に各種アプリケーションなどを ports で再インストールしようとした際に以下のようなメッセージが出てビルドに perl モジュールを使用するものが全部ビルドできなくなった。

```
loadable library and perl binaries are mismatched (got handshake key 0xd480080, needed 0xe180080)
```

解決策はないものかと他での事例を参照すると、perl と perl モジュールの依存関係が再構築できないのでいったん全部削除してインストールしなおすしかないという書き方をしてるところがほとんどだった。

それが正しいのだろうけど、perl モジュールに依存してる ports にも影響があるのでなんとか回避できないものかとジタバタしてみたところ、「perl のバージョンを上げると handshake key の更新されるため、perl モジュールも handshake key の更新も併せて処理してくれる」という回避策を見つけた。

あまりお勧めできるやり方ではないだろうけど、あくまでも事例紹介ということで。


# 作業したときの環境
- FreeBSD 12 (11.x から upgrade した）
- perl5-5.30 → perl5-5.32
【PHP】配列を操作する関数まとめ

PHPを学習しておりまして、アウトプットのために投稿させて頂きます。

#配列操作関数まとめ
###array_unshift
配列の先頭に値を追加

```
$scores = [30, 40, 50];

array_unshift($scores, 10, 20);
print_r($scores);
```
```
Array
(
    [0] => 10
    [1] => 20
    [2] => 30
    [3] => 40
    [4] => 50
)
```

###array_push
配列の末尾に値を追加

```
$scores = [30, 40, 50];

array_push($scores, 60, 70);
print_r($scores);
```
```
Array
(
    [0] => 30
    [1] => 40
    [2] => 50
    [3] => 60
    [4] => 70
)
```

###array_slice
先頭から指定した個数分の値を返す
`array_slice(変数, 位置, 個数);`のように書く

```
$scores = [30, 40, 50, 60, 70, 80];
$partial = array_slice($scores, 2, 4);
#最後までを取得する場合は個数は省略できる
#末尾から指定したい場合は($scores, -2)等とする

print_r($partial);

```
```
Array
(
    [0] => 50
    [1] => 60
    [2] => 70
    [3] => 80
)
```

###array_splice
指定した位置から指定した個数分の値を取り除く
`array_splice(変数, 位置, 個数);`のように書く。

```
$scores = [30, 40, 50, 60, 70, 80];

array_splice($scores, 2, 1);
#値を追加したい場合はarray_splice($scores, 2, 1, 100);のように書く

print_r($scores);

```
```
Array
(
    [0] => 30
    [1] => 40
    [2] => 60
    [3] => 70
    [4] => 80
)

```
###sort
配列を小さい順に並び替える

```
$scores = [40, 50, 20, 30];

sort($scores);
#大きい順に並べるときはrsortを使う
print_r($scores);
```
###shuffle
配列をシャッフルする

```
$scores = [40, 50, 20, 30];

shuffle($scores);
print_r($scores);
```
```
Array
(
    [0] => 20
    [1] => 40
    [2] => 50
    [3] => 30
)
#毎回ランダムにシャッフルされる
```
###array_rand
指定した個数をランダムに取り出し、新たに配列を作成
＊このとき取り出すのは値ではなく、キーを取り出す

```
$scores = [40, 50, 20, 30];
$picked = array_rand($scores, 2);
#新しい配列を作るので、新しい変数に追加しています

print_r($picked). PHP_EOL;
#値を取り出すためには以下のようにする
echo $scores[$picked[0]] . PHP_EOL;
echo $scores[$picked[1]] . PHP_EOL;
```
```
Array
(
    [0] => 1
    [1] => 2
)
50
20
```
###array_fill
指定した位置から指定した個数分を値で埋める

```
$scores = array_fill(0, 5, 10);

print_r($scores);
```

```

Array
(
    [0] => 10
    [1] => 10
    [2] => 10
    [3] => 10
    [4] => 10
)
```

###array_merge
配列同士をくっつけ、新しい配列を作る

```
$a = [3, 4, 8];
$b = [4, 8, 12];

$merged = array_merge($a, $b);
// $merged = [...$a, ...$b];#これも同じ意味
print_r($merged);
```

```
Array
(
    [0] => 3
    [1] => 4
    [2] => 8
    [3] => 4
    [4] => 8
    [5] => 12
)
```

###array_unique
配列の中から一意の値を取り出す

```
$a = [3, 4, 8, 3];

$uniques = array_unique($a);
print_r($uniques);
```
```
Array
(
    [0] => 3
    [1] => 4
    [2] => 8
)
```

###array_diff
配列同士を比較し、差分を取り出す

```
$a = [3, 4, 8];
$b = [4, 8, 12];

$diff1 = array_diff($a, $b);
print_r($diff1);

$diff2 = array_diff($b, $a);
print_r($diff2);
```
```
#diff1の実行結果
Array
(
    [0] => 3
)
#diff2の実行結果
Array
(
    [2] => 12
)
```

###array_intersect
配列同士を比較し、共通項を取り出し、新しい配列を作る

```
$a = [3, 4, 8];
$b = [4, 8, 12];

$common = array_intersect($a, $b);
print_r($common);
```
```
Array
(
    [1] => 4
    [2] => 8
)

```

#最後に
他にもまだまだありますが、今回は以上です！
【Ubuntu 16.04】Git を最新版にバージョンアップ


gitのclone脆弱性が公開されたので2.30.2にバージョンアップ。
PPAリポジトリでは最新が2.29.0だったのでソースからインストール。

#change current directory
```
cd ~
```

#make source file directory
```
sudo mkdir ~/src
```

#change current directory
```
cd ~/src
```

#install
```
sudo apt install -y libssl-dev libcurl4-gnutls-dev zlib1g-dev
sudo wget https://www.kernel.org/pub/software/scm/git/git-2.30.2.tar.gz
sudo tar -xvzf git-2.30.2.tar.gz && cd git-2.30.2
sudo make configure
sudo ./configure
sudo make install
```

#(Optional) copy to /usr/bin/git
```
sudo cp ./git /usr/bin/git
```

#(Optional) If you have "/.config/git/attribute" Permission denied 
```
sudo chown -R $(whoami) ~/.config
```

#confirm
```
$ git version
git version 2.30.2
```

done
ポスト自己主権型アイデンティティ

**日々、渡辺さんの特許のPRについて考えてます。PR TIMESの閲覧数伸びてて感謝**


読んでくださっている方々に感謝です。


ただ、「もう一声」というところで行き詰まっている感もあり、さてこの状況をどう考えるべきか・・・。


技術自体は来る時代に必ず備えておくべき「量子耐性技術」なんですが、いかんせんまだ量子コンピューターが普及していないので脅威に対する具体的なアクションに結びついてないのかも。


渡辺さんは5G、6Gのバックドア問題（その存在はみんな知ってる）を回避する技術の特許も持ってるので、そっちもなんとかパートナーを見つけたい。


まあ、こういう時はあれこれもがいてもしょうがないし、もがけばもがくほどドツボにハマるものなのでしばらく今まで蒔いた種を静観するのが吉かもしれません。


ただ、


**社会実験というか、特定の地域を舞台にした実証（実装）実験はやってみたい**


と最近思ってます。


僕、実は大学、大学院と専門がツーリズムだったこともあって、「まちづくりとは何か」みたいなテーマはけっこう好きです。


最近トヨタがウーブンシティ構想を進めてますが、東京や大都市一極集中型経済圏への依存をやめ、地方を含む地域経済圏の見直しがこれからどんどん進むはず。


**中央集権から地方散権**とでも言いますか。
Web3.0が分散型の時代なので、政治もそうなっていくんでしょうか。


こういうトレンド自体は歓迎する人が多いと思います。


**大事なのは政治性と私企業の過剰な営利追求の排除**


だと僕は思ってます。


自己主権型アイデンティティあたりのキーワードはもう絶対大事で、システムやテクノロジーを使うユーザー側に主権はあるべきだと強く思ってます。


僕が渡辺さんの特許に関わると決めたのも、この**自己主権型アイデンティティを超える技術**だから。


本来、ウーブンシティのような構想にはこういう「居住者（ユーザー）の主権をどう保護するか」というプライバシーの議論がセットのはずだけど、今のところそこまで突っ込んだ議論は見かけない。


これから私企業による似たようなプロジェクトが追従してくると思いますが、彼らが「うちのシステムはプライバシー完璧です！」と宣言するためにも、渡辺さんの特許はもってこいですし必要なわけです。


**誰か渡辺さんと一緒に最強のステーブルコインでも発行しましょうよ**


結局はこういうことに尽きるんですが、なんらかの形で渡辺さんの**特許をサービスなりプロダクトなりに落とし込めるチャレンジングで野心的な人**を探してます。


GAFAMが世界を制して久しいけど、ポスト自己主権型アイデンティティを制する者はWeb3.0の世界でネットの民主化を実現できると思ってます。


==================


**アクセスが多い他の記事**


**【多変数(量子耐性)暗号方式の特許を使って事業創造したい方求む！】**


- 既存の暗号技術に代わり標準化されるべき技術。
- ブロックチェーンの強力な補完技術でもあります。
- キーワードは＝**データ管理をユーザー主権に**。
- GAFAM超えを目指せます。


>→[記事①:強いて言えばこれは「ポストゼロ知識証明」という発明。事業者やユーザーは量子コンピュータによる未来の攻撃に対し完璧にリスクフリーになる](https://note.com/kosaka_/n/n6a54e3498cea)


>→[記事②:渡辺さんの特許「多変数暗号方式＝量子耐性」が備わるとブロックチェーンは真価を発揮して最強になる](https://note.com/kosaka_/n/nba6d69d8b5d5)


>→[記事③:渡辺さんの特許「多変数(量子耐性)暗号✖️ブロックチェーン」で「発言歴が消えない」「絶対に乗っ取られない」「事業者をみんなでチェックする」民主的なSNS（事業創造パートナー求む）](https://note.com/kosaka_/n/n76c259e42f65)


**【僕の略歴】**


- 新潟で面白いことやりましょう！


>→[記事①:何かワクワクできることを一緒にやりましょう](https://note.com/kosaka_/n/ne312cba752ba)


>→[記事②:新潟で面白いことやりましょう！](https://note.com/kosaka_/n/na8dc65342b29)


>→[記事③:地方ベッドタウンの宅地210坪を「坪47円」で買えた理由とその秘訣](https://note.com/kosaka_/n/nab5e7d013d28)


**【連絡先】**


- 遠慮なくメールください！
- メール→ tadahide@protonmail.com
- ライン→ Tora3307tora
- twitter→@Tadahide_Kosaka
mac上でワイルドカードなSSL証明書をLet's encryptで発行してCloudLoadBalancerに設定する

GCP上でSSL証明書を発行できるのですが、ワイルドカードには非対応です。
[SSL 証明書の概要  \|  負荷分散  \|  Google Cloud](https://cloud.google.com/load-balancing/docs/ssl-certificates)


そこで、適当な証明書を外部で発行して、登録するという手順が必要となります。証明書の発行手順はいくつかありますが、今回は無料で使用できるLet's encryptを使います。

[Let's Encrypt \- フリーな SSL/TLS 証明書](https://letsencrypt.org/ja/)


# 前提

- ドメインは作成・登録済
- 自端末はMac
  - Mojave 10.14.6

# 証明書発行

## certbot インストール

[Certbot](https://certbot.eff.org/)というcliツールをinstallします。

`Let's encrypt` でぐぐると、Linux上で実施している手順がよく見つかりますが、Mac上にもinstallできます。


``` bash
$ brew install certbot
$ certbot --version

certbot 1.10.1

```


## 証明書作成


```bash
$ sudo certbot certonly --manual \
--server https://acme-v02.api.letsencrypt.org/directory \
--preferred-challenges dns \
-d "*.XXXXX.com" -d "XXXXX.com" \
-m "XXXXX@XXXXX.co.jp" \
--agree-tos 
```

DNSにTXTレコードを設定するように言われるので、使用しているDNSサービスで設定します。
（設定画面の説明は省略）

```
Please deploy a DNS TXT record under the name
_acme-challenge.XXXXX.com with the following value:

XXXXXXXXXXXXXXXXXXXXX

Before continuing, verify the record is deployed.
```



設定後、反映されたか確認（通常、数分かかります）

```bash
dig @8.8.8.8 _acme-challenge.XXXXX.com  txt
```

確認できたら、certbotの方でEnter。

この手順が2回あります。



うまくいくとこういうメッセージが出ます。

```
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/XXXX.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/XXXX.com/privkey.pem
   Your cert will expire on 2021-06-09. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le
```

指定された場所を見るとファイルが作成されています。

```bash
sudo ls -altr /etc/letsencrypt/live/XXXX.com
```


# LoadBalancerに反映

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32169/d828600e-1fe7-0a7f-28a3-3bfed8528da9.png)



公開鍵証明書 -> `cert.pem`
証明書チェーン -> `chain.pem`
秘密鍵 -> `privkey.pem`

を設定します。



# 参考

[Let's Encryptでワイルドカード証明書を取得する \| クラウドのエスエスアイ・ラボ](https://ssilab.co.jp/blog/tech-blog/tech-blog-child/lets-encrypt_wildcard)
多数の画像を一括でリネイム、リサイズ、拡張子を変更しzip化

#画像のリネイム・リサイズ・拡張子変更・zip化するクラス

ディレクトリに入っている画像の名前、サイズ、拡張子を一括で変更してzip化までやりたかったのでコードを書いてみた


```python:画像前処理クラス.py
from  PIL import Image
import os
import shutil
import cv2
from pathlib import Path

class IMG():
    def __init__(self,dic):
        """初期化時には画像を置いてるディレクトリのパスをいれる"""
        self.directory=dic
    
    def convert(self,suffix):
        """拡張子を任意の拡張子に変更するメソッド
        引数には.(ドット)を除いた拡張子をいれる"""
        for i in os.listdir(self.directory):
            fp = self.directory + '/' + i 
            img=cv2.imread(fp)
            file_Path=Path(fp)
            cv2.imwrite(self.directory + '/' +file_Path.stem + '.' + suffix,img)
            if file_Path.suffix != '.jpg':
                os.remove(fp)
        return self

    
    def rename(self,new_file):
        """ファイル名を任意をファイル名に変更するメソッド
        引数には変更したいファイル名をいれる"""
        data=os.listdir(self.directory)
        for i, old_name in enumerate(data):
            path = self.directory + '/' + old_name
            # ファイル名の決定
            new_name = new_file + "_{0:03d}.jpg".format(i + 1)
            new_path= self.directory + '/' +new_name
            # ファイル名の変更
            os.rename(path, new_path)
        return self
            
    def resize(self,width,height):
        """ファイルサイズを任意のサイズに変更するメソッド
        引数には幅、高さをいれる"""
        for i in os.listdir(self.directory):
            path= self.directory + '/' + i
            img = cv2.imread(path)
            img_resize = cv2.resize(img,(width, height))
            cv2.imwrite(path,img_resize)
        return self
    
    def make_zip(self,zip_name):
        """ディレクトリの画像をzip化するメソッド
        引数には作成するzipファイル名をいれる"""
        shutil.make_archive(zip_name, 'zip', root_dir = self.directory)
```
まず画像が置かれているディレクトリ名を引数に入れて初期化・
その後任意のメソッドを実行可能、
その際引数には注意(コード上に引数の説明あり)

```python:実行.py
IMG('画像変換_resize/rename').convert('jpg').rename('test').resize(416,416).make_zip('zip化完了')
```
zip化メソッドまで実行した際にはカレントディレクトリにzipファイルが存在しているはず
Pythonの開発環境を勉強する

# 仮想環境での開発について

複数の開発を進めていくと、開発プロジェクトごとに独自のライブラリをインストールすることも考えられる。
そのため、プロジェクト毎に仮想環境を作成し、開発を行いたい。

本テキストでは、その過程でいろいろ調べたものをまとめた内容です。
だいたい参考リンク先の内容を抽出しているものなので、詳しくはそちらをご参考ください…。

# 環境
* Windows 10
* python 3以降

##  Python本体のバージョン管理

参考：[Pythonの複数バージョンの扱い方（Windowsの場合）](https://gammasoft.jp/python/python-version-management/)

バージョン管理は自分で行う。
※pipenvはより高度な管理が可能となります。が、とりあえず、venvはpythonの標準機能となっており、取り扱いしやすいと考えてました。
※virtualenvが類似情報で出てきますが、venvはvirtualenvを元にしており、標準機能を採用しました。

Python3.3以降からはデフォルトでインストールされるPythonランチャー（py.exe）のおかげで、個々のバージョンでも指示できるようになりました。

インストールされているバージョンは`--list-paths`で確認できます。
*(アスタリスク)がついているのはデフォルトに設定されているバージョンです。

```shell
> py --list-paths
Installed Pythons found by C:\WINDOWS\py.exe Launcher for Windows
 -3.9-64        C:\Users\username\AppData\Local\Programs\Python\Python39\python.exe *
 -3.6-64        C:\Users\username\AppData\Local\Programs\Python\Python36\python.exe
```

バージョンを指定してコマンド実行する場合は以下の通り。

```shell
> py pip install pipenv          <= デフォルトにインストールされる
> py -3.6 -m pip install pipenv  <= Pytyon 3.6にインストールされる
```

参照リンクの記載にある通り、以下の通り実行を切り替えることが出来る
1. ファイルごとに実行バージョンを切り替える

例えば、「今までバージョン3.5を使用していて、3.6にグレードアップしたら、一部のPytyonプログラムが動かなくなった。動かなくなったプログラムだけは、3.5のまま使用したい。」そのような場合は、プログラムファイルの先頭に以下の1行を付けてください。

```python
#!python3.5
```

2. コマンドごとに実行バージョンを切り替える

```shell
 > py -3.5 sample.py
```

## 仮想環境(venv)

顧客の開発毎に利用するパッケージは限定させたい。
このため、開発には仮想環境を用いる。

参照：[venv: Python 仮想環境管理](https://qiita.com/fiftystorm36/items/b2fd47cf32c7694adc2e)

venvのコマンドは以下の通り

```python
 >py -m venv [newenvname]                    <= デフォルトのpythonバージョン作成される

 > py -[python-version] -m venv [newenvname] <= pythonバージョン指定

 > py -3.6 -m venv venv
```

複数のバージョンで実行環境を持つことも可能。
※ バージョンに関しては[newenvname]/pyvenv.cfgファイルに記載されている

```cfg
home=C:\Users\[username]\AppData\Local\Programs\Python\Python39
include-system-site-packages=false
version=3.9.0
```

環境を有効にするには以下の通り。

```shell
 > .\[newenvname]\Scripts\activate
```

pycharmでは、メニュー - [実行] - [構成の編集] - [構成]内の [Python インタープリター]のパスを[newenvname]\Script\python.exeを指定する。
これにより実行時に利用されるpythonはvenv環境となる。


### 作成した環境にインストールされているパッケージの確認


```shell
 [newenvname]> pip freeze <= 作成直後は何も表示されないはず。
```

### 仮想環境を終了する場合


```shell
 [newenvname] > deactivate
```

#### パッケージの一括インストール
ほかの環境内容を持ってくる場合、requirements.txtを利用してインストールするのが便利。
仮想環境を有効化した状態で、以下のコマンドを実行する。

```shell
 [newenvname] > pip install -r requirements.txt
```

## Pycharmに環境を追加する

*  [ファイル] - [設定]  - > Python インタープリター から歯車マークを選択 -> 追加を選ぶ
*  Virtualenv Environment -> 既存の環境から \[newenvname]\Scripts\python.exe を選択する

### Pycharmでパッケージをインストールする

Pycharmを起動すると「Package requirements '…(パッケージ名)'」と出るため、「install requirements」を選択することで仮想環境(venv)内に一括インストールする。

# 困ったときに
## PIPが使えない
### 原因：社内ネットワークのプロキシ
やったかな？
+ プロキシをコマンドラインで設定
+ インストール時に「信頼するホスト名」を指定


### 原因：インストール先が外部ネットワークと切り離されている
pipでダウンロードがそもそもできない時は、別の経路でファイルをダウンロード・環境でビルド＆インストールする必要があります。
AWS Lightsail でサクッとWordPress環境構築(2) 〜独自ドメイン 編〜

### はじめに

こちらの記事の続きになります。
[AWS Lightsail でサクッとWordPress環境構築(1) 〜サイト立ち上げ編〜](https://qiita.com/fgem28/items/1ba8e295ee3f049ba6b9)

__上の記事内で行ったこと__

- AWSのLightsailでホームページ用にインスタンスを作りました。
- 静的IPアドレス(固定されたアドレス)を作成し、`http://54.***.**.243`の様な決まったURLにアクセスすることでホームページを閲覧できる様にしました。

### ドメインを取得する
Route53で登録する方法や、お名前.comなどのサービスで登録する方法があります。

### お名前.comでドメイン登録する場合
お名前.comなどで好きなドメインを取得します。(料金がかかります。1円~)
ドメインの利用期限の更新などについては省略します。

### AWS Route 53のDNSを設定する
Route53で、ホストゾーンの作成をします。
「ドメイン名」の欄に取得したドメイン名を入力し、他はデフォルトのまま「ホストゾーンの作成」をします。
[![Image from Gyazo](https://i.gyazo.com/731832e8702b277b0d9ceefa25caea31.png)](https://gyazo.com/731832e8702b277b0d9ceefa25caea31)

作成したホストゾーンに入り、「レコードの作成」をします。
「値」の欄に、Lightsailで作成した静的IPアドレスを入力し、他はデフォルトのまま「レコードを作成」します。
[![Image from Gyazo](https://i.gyazo.com/bddad7965920a2d879322babf97560ee.png)](https://gyazo.com/bddad7965920a2d879322babf97560ee)

これでAWS Route 53のDNS設定が完了です。

### ドメインのネームサーバーを変更する
お名前.comで、ドメイン > ドメイン詳細 > ネームサーバー設定 から、「その他のネームサーバーを使う」を選択し、
ネームサーバー1~4に、AWS Rounte 53の作成したレコードのうち「タイプ」が「NS」の4つの値をそれぞれ、お名前.comに入力し設定完了させます。

### Lightsailの設定ファイルを変更する
Lightsailの設定ファイルには、「サイトのURLは`http://54.238.44.243`です」の様に書かれている部分があるので、`http://54.238.44.243`の部分を、独自ドメインに書き換えます。
Lightsailからインスタンスを選択し、「sshを使用して接続」をクリックして、サーバーに入ります。

`apps/wordpress/htdocs/wp-config.php`というパスのファイルが設定ファイルになります。
Vimで編集するため次のコマンドを入力します。
`vim apps/wordpress/htdocs/wp-config.php`

Vimが起動すると、下の方にこの様な箇所があります。

```
define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST'] . '/');
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST'] . '/');
```
これを以下の様に書き換えます。(末尾の「;」を忘れないように)

```
define('WP_SITEURL', 'http://独自ドメイン');
define('WP_HOME', 'http://独自ドメイン');
```

上書きしてVimを閉じます。

インスタンスを再起動すると、`http://独自ドメイン`にアクセスすることができる様になります(少し時間がかかる場合があります)。

## Route53でドメイン登録する場合
上記はお名前.comでドメイン登録する場合ですが、Route53でドメイン登録する場合の手順も簡単に書きます。

Route53のメニューから、好きな文字列に.comや.netなどを選んでドメイン登録します。
初めての場合「Eメール検証のスキップ」というポップアップが出るかもしれませんが、「同意」で大丈夫です。
その後メールアドレスに確認メールが送られて来るので、確認すればドメイン登録完了です。

ドメイン登録が完了するとホストゾーンが作られてるのでRoute53から確認します。
NSレコードとSOAレコードが作られているはずです。

### LightsailでDNSゾーンの作成をする
ホーム-ネットワーキング-DNSゾーンの作成から、Route53で作成したドメインを入力してDNSゾーンを作成します。
作ったDNSゾーンにはネームサーバー(NSレコード)が既に作られています。
続いてレコードの追加をします。
Aのレコードにして、サブドメインには「@」、解決先にはプルダウンに作成済みの静的IPアドレスが出るので選択します。

### ネームサーバーの変更をする
LightsailのDNSゾーンのネームサーバーをコピーして、Route53のドメイン画面に入ります。
登録済みドメインに、作成したドメインがあるので、ネームサーバーを編集してLightsailのDNSゾーンのネームサーバーにします。
ホストゾーンのNSレコードも同じネームサーバーにします。

Lightsailのwp-config.phpを変更する手順などは、お名前.comの場合と変わりません。

### おわりに
[AWS Lightsail でサクッとWordPress環境構築(3) 〜お問い合わせフォーム編〜](https://qiita.com/fgem28/items/49cdc0d81a9810b0600c)を公開しました。
SPFレコードの要点を簡潔にまとめる

## 3行で説明
- なりすましメールを防ぐための技術
- 設定することで、迷惑メール判定されるリスクを下げることもできる
- DNSのTXTレコードを使って、メール送信元のIPを登録する

## なぜ必要か
メール送信のプロトコル、SMTPのセキュリティ上の弱点として、誰でも任意のドメインの差出人になりすますことができる、というものがある。

SPFレコードを設定することによって、自分が所有しているドメインを使ったメールアドレスから、第三者が自由にメールを送信することを防ぐことができる。

## 設定方法
所有するドメインのTXTレコード(自由にコメントをかけるレコード)に`v=spf`で始まる以下のような形式で記述することにより、SPFレコードとして認識されるようになる。

```
example.jp. IN TXT "v=spf1 +ip4:192.168.100.0/24 ~all"
```
```
example.jp. IN TXT "v=spf1 include:kagoya.net ~all"
```

## SPFレコードが使われるタイミング
メール受信サーバーが、メール受信の直前に、DNSサーバーにSPFレコードがあるかどうか確認する
↓
・レコードがなければ普通に受信
・レコードがあれば、送信元のIPアドレスとSPFレコードに書かれているIPアドレスが一致しているか確認し、一致しなければ受信を拒否する

![202008b_027.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244893/be3bd35d-23c8-1ac0-ae56-7e4827736571.png)
[SPFレコードとは？正しい書き方を徹底解説 | カゴヤのサーバー研究室](https://www.kagoya.jp/howto/rentalserver/spf/)


## 関連ツール
ドメインを入力すると、そのドメインに設定されているSPFレコードを確認できる。
https://www.kitterman.com/spf/validate.html

フォームに必要事項を入力すると、SPFレコードが生成される
https://www.spfwizard.net/

## CNAMEレコードを使った設定
例えばSendGrid使ってメールを送信する場合、自分が所有するドメインのCNAMEレコードにSendGridのドメインを設定する。
そうすることで、SendGrid側で設定されているSPFレコードを使うことができる。

## 参考
- [送信ドメインを認証するためのSPFレコードに詳しくなろう | SendGridブログ](https://sendgrid.kke.co.jp/blog/?p=3509)
- [SPFレコードとは？正しい書き方を徹底解説 | カゴヤのサーバー研究室](https://www.kagoya.jp/howto/rentalserver/spf/)
- [TXTレコードとは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word12294.html)
[Spigot]Minecraftでモンスターハンターのスタミナのような機能を簡単に実装する

##概要
タイトル通り、モンハンのスタミナ機能を実現できるPluginです
どこかのFPSゲームにもありますね
![MHStamina.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854414/9247a706-b0b6-d6d0-d947-dccc2e847a13.gif)
Youtube: https://youtu.be/uuAmWKzlnUA
GitHub: https://github.com/FratikaK/MHStamina_Sample

##作成した経緯
PvPのゲームを作っていて、モンハンのようなゲージ減少を実装してみたいなと思っていました
BukkitRunnableで簡単に出来たので共有してみたいと思います

##どのように動いているか
#### EventListenerでプレイヤーがスプリントする動作を検知する

```java
    @EventHandler
    public void onToggleSplint(PlayerToggleSprintEvent event) {
        //スプリントを切り替えたプレイヤーを取得
        Player player = event.getPlayer();

        if (event.isSprinting()) { //スプリントを始めた時
            new DecreaseTask(player).runTaskTimer(this, 0, 10);
        } else { //スプリントをやめた時
            new RecoveryTask(player).runTaskTimer(this, 0, 5);
        }
    }
```
PlayerToggleSplintEventでeventを取得してプレイヤーがスプリント、
または歩行の状態でそれぞれのTaskを実行します

DecreaseTaskは減少、RecoveryTaskは回復です
BukkitRunnableのrunTaskTimerで定期的に実行させて、プレイヤーの食糧ゲージを増減させます

####スプリントを始めた時

```java
public class DecreaseTask extends BukkitRunnable {

    private final Player player;

    public DecreaseTask(Player player) {
        this.player = player;
    }

    @Override
    public void run() {

        //プレイヤーがスプリントをしていなければTaskをキャンセル
        if (!player.isSprinting()) {
            cancel();
            return;
        }

        //プレイヤーのFoodLevelを1減らす
        player.setFoodLevel(player.getFoodLevel() - 1);
    }
}
```

runTaskTimerのperiodを10tickにしてあるので0.5秒ほどずつゲージを減らします

####スプリントをやめた時(歩行、止まっている時)
```java
public class RecoveryTask extends BukkitRunnable {

    private final Player player;

    //delayが0になったらFoodLevelを回復させる
    private int delay = 5;

    public RecoveryTask(Player player) {
        this.player = player;
    }

    @Override
    public void run() {

        //プレイヤーがスプリント状態か、FoodLevelが全快している時はTaskをキャンセル
        if (player.isSprinting() || player.getFoodLevel() == 20) {
            cancel();
            return;
        }

        if (delay <= 0) {
            player.setFoodLevel(player.getFoodLevel() + 1);
            return;
        }
        delay--;
    }
}
```
こちらはperiodを5tickにしてあります
(モンハンはスタミナ減少より回復の方が早かったと記憶している)

```java
//delayが0になったらFoodLevelを回復させる
private int delay = 5;
```
スプリントをやめてすぐ回復するのを防ぐためにdelayを入れています

###問題点
一応食べ物を食べることで食糧ゲージ回復を無効化させるeventを入れています

```java
    @EventHandler
    public void onChangeFoodLevel(FoodLevelChangeEvent event) {
        event.setCancelled(true);
    }
```

FPSみたいなゲームには食べ物を食べる動作はいらないのですが、
モンハンのゲームをマネしようとするとMinecraftの仕様上、食糧ゲージが満タンだと食事が出来ないです
金リンゴしか食べれません(モンハンには肉を食べたり、薬を飲んだりする動作がある)

RecoveryTaskで

```java
      if (player.isSprinting() || player.getFoodLevel() >= 18) {
            cancel();
            return;
        }
```
Taskキャンセルする条件式をplayer.getFoodLevel() >= (19以下の数字)とすることで
食事の動作が出来るようになりますが...

食糧ゲージが満タンじゃないのはなんか違和感があります(個人の感想です) 

###今後実装してみたいこと
このPluginを応用して、モンハンの強走薬みたいな効果や
プレイヤーアビリティの有無でスタミナ増減が違う処理を入れてみたいですね
Linuxコマンド備忘録


絶対に覚えておきたい点をまとめておく。
頻度高めに更新予定


##ファイルの中身表示
``cat ファイル名``
行数見たいなら
``cat -n　見たい行数``
 
##ファイル作成
``touch ファイル名``

##ディレクトリ作成
``mkdir ファイル名``

##ディレクトリ移動
``cd 指定したディレクトリ``

##ホームディレクトリ移動
``cd``

##カレントディレクトリ（現在地）確認
``pwd``

##ファイルの中身を一覧で表示
``ls``
すべて表示
``ls -a``
ファイルの詳細も表示
``ls -l``

##ファイル・ディレクトリ移動
``mv 移動前 移動先``

##ファイル・ディレクトリ名変更
``mv 変更前 変更後``

##コピー
``cp 元ファイル コピー後ファイル名``
``cp -r　元ディレクトリ コピー後ディレクトリ名``

##削除
``rm ファイル名``
``rm -r ディレクトリ名``

##ファイルに直接文字を書き込む
既存データ残さず上書き用
``echo "書き込む内容" > ファイル名``

既存データを残して上書き
``echo "書き込む内容" >> ファイル名``

##ファイルや標準入力の中から特定の単語を検索
``grep 正規表現or検索したい文字列 検索したいファイル``

大文字小文字を区別しない　
``grep -i ``

再帰的（下位フォルダ）に検索
``grep -r``

複数の文字列をOR検索
``grep -e 検索文字列 -e 検索文字列 ファイル名``

複数の文字列をAND検索
``grep 【検索文字列】 【ファイル名】 | grep 【検索文字列】``

##検索

####完全一致で指定

ディレクトリ検索
``find ディレクトリ名``
ファイル検索
``find -name ファイル名``

前後に文字列が入る場合ワイルドカード使用
ファイル名の前後に`**`をつける

#ショートカットキー一覧


``Ctrl+B`` カーソルを1文字左へ（［←］キー）
``Ctrl+F`` カーソルを1文字右へ（［→］キー）
``Ctrl+A`` 行の先頭へ
``Ctrl+E`` 行の末尾へ

``Ctrl+D``  カーソル位置の1文字を削除（［Delete］キー）
``Ctrl+H``  カーソル直前の1文字を削除（［Back Space］キー）
``Ctrl+K``  カーソル位置から行末までを削除
``Ctrl+U``  行頭からカーソル直前までを削除
``Ctrl+W``  カーソル直前の単語を削除
``Ctrl+Y``  削除文字列（［Ctrl］＋［D］／［H］キー意外による）の貼付
HerokuにLaravelをデプロイしたらSeverError500が発生した話

【前提条件】gitを使用している、Heroku CLIをインストール済み、Herockのリモートリポジトリが登録出来ている。

#デプロイしてみると500servererrorが…

![500server.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1020834/0af6faa3-ded6-57e6-f102-867e06030468.png)

絶望の白画面が……
.envファイルはgitの管轄外なので作動しません。

#たった一つのコマンドで設定できる!!‼
ここでherokuと紐付いているディレクトリ直下で以下の
コマンドを打ち込みます

↓キーの生成と設定を一挙にやってくれます。

```
heroku config:set APP_KEY=$(php artisan --no-ansi key:generate --show)
```



成功すると以下のような表示が現れます。

```
Setting APP_KEY and restarting ⬢ appname... done, v5
APP_KEY: *******************************************
```
すると……
![Screenshot from 2021-03-11 12-00-41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1020834/2db71011-1fb1-e946-48cb-c3b785377e3a.png)


いつものあのページが……
unityを使ったゲームでadmobを出したら表示制限かかった時の対応策

こんにちは。[virapture株式会社](https://virapture.com)の[もぐめっと](https://mogmet.com)です。

![IMG_4519.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42234/518f1ee6-1754-f934-c586-c5135e27a1d3.jpeg)
実は、カンペがないと緊張しちゃって発表とかできない人です。

今日は最近出した[ワンナイト人狼オンライン](https://online.1nite-jinro.com/link/blog)というゲームで広告を配信していたのですが、広告配信制限を食らってしまっていたのでその原因や対策を紹介しようと思います。

## 広告表示制限になる原因

原因としては[広告配信の制限](https://support.google.com/admob/answer/9493252?hl=ja)や、[無効なトラフィック](https://support.google.com/admob/answer/3342054)にも記載されておりますが、簡単に言うと、誤って押されたり、繰り返しクリックしたり、BOTぽい動きで広告クリックしたりすることが多かったりすると制限くらうよとのことだそうです。

しかし、具体的にどの画面でどんなクリックされたのかというのが具体的にわからないので、自分で怪しい挙動するところを見つけるしかありません。

## 対策

対策としては[無効な操作を防止する](https://support.google.com/admob/answer/3342099?hl=ja)にありますが、自分で広告をクリックさせないようにしたり、アクセス元や、行動を見て疑わしい行動してないかをチェックしろとあります。

具体的に言うと、アクションするボタンと広告の位置が近かったりすると誤クリック判定されて制限を食らうことが多いようです。

なので最初に広告の位置とボタンの位置を離したりとかしました。
ワンナイト人狼オンラインだとこの位置とかですね。
![IMG_0DD998A4FD4C-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42234/f6cd314e-9520-d9da-0d3d-03e9b13a31a6.jpeg)

はやければ大体2,3日、最大遅くても1ヶ月くらいで制限が解除されるとのことらしいのですが、待てども待てども解除されず気づいたら2ヶ月が立っていました。。。

全然解除されないので、Googleの人と連絡をとって確認してみたところ、まだまだ誤クリック判定されているとのことでした。
（AdMobは制限中も時折広告を配信して改善されたかを定期的にみていてそこで判定している模様）

ちなみに誤クリック判定はどう判定しているかというと、例えばユーザが広告をクリックして、すぐにアプリに戻ってきたり、ページを閉じてしまったりなどをすると判定されるそうです。
そこでユーザがなぜそのような行動をとるかを考えた結果、一つ思いついたことがありました。

それが、**全画面**です。

iosだとアプリを閉じるときは下から上にひょーいとやったり、ホームボタンで閉じれたりするのですが、Androidの場合は全画面にしてしまうとホームボタンとかが消えてしまい、出すためには下から上にひょーいとやったあとにホームボタンをする必要があるのですが、意外とこれを知らないユーザが多いです。

cf: [Androidアプリの戻るボタンが無い、効かない話](https://naoyu.dev/android%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%E6%88%BB%E3%82%8B%E3%83%9C%E3%82%BF%E3%83%B3%E3%81%8C%E7%84%A1%E3%81%84%E3%80%81%E5%8A%B9%E3%81%8B%E3%81%AA%E3%81%84%E8%A9%B1/)

```
私の普段使いスマホはiPhoneなので、このバーの存在を知りませんでした…オハズカシイ（iPhoneには戻るボタンが存在しないんですね）

Android使いの嫁さんに、ゲームのテストプレイしてもらった時に「このゲームやめれないんだけど！」と指摘されて気付きました。トホホ…
```

この視点は私も全然気づかなかったです。
上記視点で考えた結果、ユーザがホームに戻るために広告をクリックしてもどったり、ホームボタンを出そうとして誤ってクリックしてしまってるのではないかと考えました。

ということでandroidに関しては早速フルスクリーンをやめるようにしてみました。
記事では

```
Screen.fullScreen = false; //ナビゲーションバーを常時表示
```

のようにやってますが、私はPlayerのSettingの方で「Start in fullscreen mode」をOffにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42234/2eb91108-9ba0-b068-8921-d3838c8707ef.png)

その上でアプリをリリースしたところ、無事広告が配信されるようになりました！！めでたい！

## まとめ

画面下に広告を出すときは全画面に気をつけよう！というお話でした。

また、ユーザがどう使うかに立ち返って考えることは大事というのを改めて知りました。
今後も引き続きユーザ視点での考えを忘れることなくやっていけたらと思います。



最後に、[ワンナイト人狼オンライン](https://online.1nite-jinro.com/link/blog)というゲームを作ってます！よかったら遊んでね！
他にも[camecon](https://camecon.me/)や[offcha](http://offcha.com/)といったサービスも作ってるのでよかったら使ってね！
render 'shared/error_messages'でエラーが出たのを解決した

# 原因
sharedディレクトリにerror_messagesファイルを置いていたのが原因でした。
layoutsディレクトリにファイルを移動するとすんなり解決しました。
# エラー内容
renderメソッドでエラーメッセージを呼ぶためにsharedディレクトリの_error_messagesファイルを呼び出すようにしましたが、MissingTemplateと出てしまいました。

# 解決まで確認したこと
deviseを使ってのユーザー管理機能実装中の出来事だったのでコントローラーやマイグレーションファイルなどにスペルミスがないか、呼び出すファイルの名前を間違ってないかなどを確認しました。
GithubのREADMEに、動画を載せたい！

# READMEに動画を載せようとすると・・
面接等で、Githubを人に見せる時に、中身のコードが一番重要ですが、見る人の負担を軽減するための、見やすいリポジトリも重要かなと思います。
その為に、READMEを書く＆整える必要が出てくるのかなと。
文字だけでも、書かないよりかはそのリポジトリの概要が分かるのでいいかなと思うのですが、やはり画像や動画があった方がいいと思います。
筆者は、過去に作成したクイズアプリのREADMEを書いていなかったので、スマホの画面録画をREADMEに載せようかなと思いました。

しかし！！！！！！！！！！！
画像と同じように、コピペしてPreviewで確認してもリンクしか載せられませんでした。

# 原因は？
筆者の撮影した画面録画は、MP4でした。
どうやら、READMEに上げられる動画ファイルはGifでないといけないみたいだ。
仕方なく、Gifに変換する方法をググることに。。

筆者は、基本情報の学習で暗記したくらいで、ファイルの形式とかに全然精通しておりません。
良く分からないが、こんなサイトを見つけました。
他の記事とかだと、ffmpegとかインストールするやり方が主流？見たいですけど、実際にこのサイトで、変換してみて、簡単且解像度やアニメーション速度に問題がなかったので、いい方法だったのかなと？？？
zipファイルをダウンロードして、解凍するのが良きかなと。

https://www.aconvert.com/jp/video/mp4-to-gif/

# 結果発表～
無事に変換できました。
####拡張子にご注目ください。

元のMP4が……
https://user-images.githubusercontent.com/65647834/110725966-df01bd00-825b-11eb-8230-0fedd2d5fb5c.mp4
Gifに変換できた！！！
https://user-images.githubusercontent.com/65647834/110722021-eb364c00-8254-11eb-84b5-9b99988e80a2.gif

あとあと、READMEに貼る前にissueにて、アップロードします。
そして、そのリンクをREADMEに貼って完成です。
こんな感じに。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599059/414a5329-bbbc-ac56-d20c-cf36680ec9ab.png)

# おまけ
ちなみに、サイズも変更できるみたいですよ！！！　
※ただ、解像度が悪くなったり、見切れたりする。いいサイトが見つからなかった…
https://www.bannerkoubou.com/anime/gif-resize/
https://www.iloveimg.com/ja/compress-image/compress-gif
ただ、もっといい方法があったかもしれないので、「こうしたほうがいいよ～」ということがありましたら、教えていただけると幸いです。
[Oracle Cloud] コンピュートイメージのエクスポート形式が増えたらしい

# はじめに
何気なくrelease noteを見ていたら...
https://docs.oracle.com/en-us/iaas/releasenotes/changes/0d6740d1-c71b-4853-bb42-d1d62c3f3a06/
↓↓↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567355/f814a817-990f-15f6-a383-064f75d9240d.png)
なんだと...？
便利そう
ということで試してみます

ちなみにここで言うエクスポートとは、
カスタムイメージをオブジェクトストレージにはき出す行為ですね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567355/ee7f506b-b2a5-839e-08fa-fa1b8bcd3c97.png)
ちなみに、カスタムイメージの作成は稼働中のインスタンスにも実施できますが、
イメージ作成プロセス中はインスタンスはシャットダウンし、
数分間利用できないので注意です
プロセスが終了するとインスタンスは再起動されます
# コンソール操作
インスタンス画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567355/8265ff01-c354-56d9-aa55-88c802dc12b6.png)
まずはカスタムイメージを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567355/87213e64-7502-0a51-765a-b04ea12dc3a6.png)
名前を付けて作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567355/647896e0-f57b-e757-1bbd-99df7b23a1d3.png)
カスタムイメージのコンソールへ移動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567355/eb305cee-664e-3371-6c57-5f227a8a1654.png)
無事にできてます
では、いよいよエクスポート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567355/66450f78-ae60-592f-e8eb-30db3884d441.png)
エクスポート画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567355/12daee5a-6b49-5b20-c173-39bcfeabd3a4.png)
おお、これは...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567355/9625d3e5-c620-7c9d-bde9-1bdccbba8f06.png)
おお、形式増えとる！
vmdkでエクスポートしてみます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567355/6ad72244-65db-75b3-81d4-514fe35dfe7f.png)
エクスポート中
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567355/36255de5-0968-dceb-3175-40bb93b5a19f.png)
出来たので、バケットのページへ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567355/c6a3c88f-d910-ad8d-4f6d-7edc83d67674.png)
おお、できてる
ファイル形式や拡張子が無いので不安になりますが、
紛れもなく先ほど作成したイメージです

今回、イメージのインポート、デプロイチェックは行いませんが、
エクスポートの形式が増えたことが確認できました
クラウドのリソースを外に持ち出すのも、より便利になりそうですね

ありがとうございました
Amazon SNSを利用してモバイルプッシュ通知を送信するやり方ー HMS対応（ソリューション）

# Amazon SNSのモバイルプッシュ通知の対応範囲
Amazon SNSは以下のプラットフォームのモバイルプッシュ通知にしか対応していません。

- Amazon Device Messaging (ADM)
- iOS および Mac OS X 用の Apple Push Notification Service (APNs)
- Baidu Cloud Push (Baidu)
- Firebase クラウドメッセージング (FCM)
- Windows Phone 用 Microsoft プッシュ通知サービス (MPNS)
- Windows プッシュ通知サービス (WNS)

<b>ファーウェイのAndroid HMS端末ではGMS（Google Mobile Services）が入っていないため、FCMを受信することができません。</b>では、Amazon SNSでHMS端末にプッシュ通知を送る方法があるでしょうか？

<b>あります！</b>
<b>Amazon SNSでHMS端末にプッシュ通知を送る方法があります！</b>

# Amazon SNSでHMS端末にプッシュ通知を送る方法
<b><font color="red">Amazon SNS</font> ＋ <font color="red">AWS Lambdaのサブスクリプション</font> ＋ <font color="red">AWS Lambda</font> ＝ <font color="#DD0000">Amazon SNSでHMS端末にプッシュ通知を送る方法</font></b>

Amazon SNSはモバイルプッシュ通知だけではなく、Lambdaの通知にも対応しています。そこで、Lambdaと紐付けて、Lambdaの中でHMSプッシュサーバーのAPIを実行すれば、HMS端末にプッシュ通知を送ることができます。

### シーケンス図
![Sequence Diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/39ac5e57-92c4-3d27-74c6-191fade06aa0.png)

実装が必要なのはサブスクリプションの作成とLambdaの作成だけです。

# 参考
[Amazon SNSを利用してモバイルプッシュ通知を送信するやり方ーコンソール利用](https://qiita.com/Rei_2020/items/ab1768c1a0191b73492e)
[Amazon SNSを利用してモバイルプッシュ通知を送信するやり方ー Node.js](https://qiita.com/Rei_2020/items/fd8c679f697b0e0f5ca7)
[Amazon SNSを利用してモバイルプッシュ通知を送信するやり方ー HMS対応（ソリューション）](https://qiita.com/Rei_2020/items/352a0b02d6eb13ab19da)
[Amazon SNSを利用してモバイルプッシュ通知を送信するやり方ー HMS対応（実装）](https://qiita.com/Rei_2020/items/ad4046b59d3e2cc7111c)
Yahooの3.11検索での募金をワンライナーで

# Yahooで3.11を検索すると10円募金になるらしい
同一IPからでもいいのかわかりませんが、curlを使ってワンライナーで書いてみました。

```
n=0; while :; do curl -s 'https://search.yahoo.co.jp/search?ei=UTF-8&fr=other_evt311_pc&p=3.11' > /dev/null && echo "n=$n"; let n++; done
```
やりすぎ注意！

## 追記
そもそも募金総額は5000万円が上限らしいので、普通に500万回くらいは達成できそう。
Qiita API v2を使ってみる【JavaScript】

# はじめに
APIについて勉強すべく，JavaScript (React) を使ってQiita API v2から自分の記事を取得して表示させてみたので，簡単にまとめておきます．

# 手順
Qiita API v2ではGETメソッドによって投稿の取得ができます．

## 1. アクセストークンの発行
[Qiita API v2のドキュメント](https://qiita.com/api/v2/docs)で仕様について確認したところ，アクセストークンをリクエストに含める必要があるようです．

アクセストークンの発行については他の記事で丁寧に紹介されているので，ここでは割愛します．

- [Qiita APIを触ってみる](https://qiita.com/miyuki_samitani/items/bfe89abb039a07e652e6)
- [Qiita APIを使って記事一覧を取得する](https://qiita.com/kou_pg_0131/items/57f86a1abc332ed2185d)

## 2. 投稿の取得
投稿の取得は以下のコードで実装できます．
（以下のコードで使用しているaxiosについては[こちら](https://www.digitalocean.com/community/tutorials/react-axios-react-ja)）

```React
  // 投稿の取得
  fetchPosts = async () => {
    const res = await axios.get(
      'https://qiita.com/api/v2/authenticated_user/items',
      {
        headers: {
          Authorization: 'Bearer [ここにアクセストークンをいれる]>',
        },
      }
    );
    console.log(res);
    return res.data;
  };
```

fetchPostsを実行すると，取得した記事がコンソールに表示されます．
![スクリーンショット 2021-03-11 10.43.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840171/7075eda1-fa9e-b9b8-671a-6af597db2dff.png)

## 3. 必要なデータを表示
上に示した表示結果から分かるように，返されるオブジェクトにはconfigやstatusなど不要な情報が多く含まれています．
記事を表示するだけならdata内の一部の情報のみで十分です．

返される項目についての詳細は，[Qiita API v2ドキュメント](https://qiita.com/api/v2/docs)から確認できます．

今回は，以下の情報を表示しました．

- ユーザのプロフィール画像
- ユーザ名
- ユーザID
- 記事タイトル
- LGTM数
- タグ
- 投稿日時

例えば，返ってきたデータを`res`としたとき，ユーザ名(name)は`res.data.name`で取得できます．

表示の詳細についてはここでは割愛しますが，React，Tailwind等を使ってこのように実装しました．

![スクリーンショット 2021-03-11 10.59.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840171/75e10ac0-2435-16d3-26ad-9a8415c588e3.png)

これで自分好みにデザインした第2のQiitaの完成です．

ちなみに，返されるオブジェクトの中には記事のURLも含まれているので、クリックするとその記事に飛ぶような処理も実装できます．(実は実装済み)
OpenSiv3DのP2Bodyにテクスチャを貼り付ける

# 概要
現在のOpenSiv3Dでは、Rectなどにはデクスチャは貼り付けられるものの、P2Bodyには貼り付けることができません(出来なかった気がする)。
~~そのため、P2BodyのオブジェクトからRectを作成し、そこにテクスチャを貼り付けます。~~

2021.3.11 11:14追記
`P2Body::as<P2XXXX>(size_t index)` で、形状別の内部オブジェクトへのポインタが得られるとのこと。そこからメンバ関数 `getQuad()` で`Quad`を取得し、テクスチャが貼り付けられます。
@Reputeless さん、ありがとうございます!

# ソースコード

```C++
# include <Siv3D.hpp> // v0.4.3

void Main()
{
    P2World world(9.8);
    
    // 地面
    P2Body Ground=world.createStaticLine(Vec2(0,0), Line(-100,100,100,100));
    
    // 落下させる箱
    P2Body Box=world.createRect(Vec2(0,0), Rect(0,0,50)).setAngle(60_deg);
    
    // 貼り付けるテクスチャ
    // TextureDesc::Mipped でGPU負荷軽減・画質向上
    Texture texture(U"example/windmill.png",TextureDesc::Mipped);
    
    // カメラ
    Camera2D camera(Vec2(0,0));
    

    while (System::Update())
    {
        // 物理演算
        world.update();
        
        // 2D カメラを更新
        camera.update();
        {   // 2D カメラの設定から Transformer2D を作成・適用
            const auto t = camera.createTransformer();
            
            // 1.Box.as(0) でBoxのQuadを取得
            const Quad quad = Box.as<P2Rect>(0)->getQuad();

            // 2.テクスチャを貼り付けて描画
            quad(texture).draw();
            
            // 地面の描画
            Ground.draw(Palette::Lightgreen);
        }
        
        // UI表示
        camera.draw(Palette::Orange);
    }
}

```

# 実行結果
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596925/baaed19f-84c5-10d6-1c1f-911ebca75402.gif" width="600px">
YouTubeの動画をQiita記事に埋め込んでみた

## 記事内で動画再生できるようになった？

[Qiita更新情報ページ 2021-03-11](https://qiita.com/release-notes#2021-03-11)

今までは、YouTubeを記事内に置く方法はサムネール写真があって、それをクリックするとYouTubeに遷移する方法しかなかったため、ただの写真かな？と思われてクリックはされづらかったかと思います。
もしくは、動画付きTwitter埋め込みでした。

<iframe width="1062" height="606" src="https://www.youtube.com/embed/DyyCbks2pWY" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

できました！

## 記事書き途中のプレビューでも再生できるようになってます！

[![Image from Gyazo](https://i.gyazo.com/83ab172e93b32af1ce9eaf917e8aa1fc.png)](https://gyazo.com/83ab172e93b32af1ce9eaf917e8aa1fc)

安心！！

## ライブ配信の埋め込みはどうなるかな

<iframe width="1254" height="641" src="https://www.youtube.com/embed/5qap5aO4i9A" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

同じようにできます！

## 埋め込み方法

[![Image from Gyazo](https://i.gyazo.com/01aff0f77b6895d49a9bf5d2f399c858.png)](https://gyazo.com/01aff0f77b6895d49a9bf5d2f399c858)

埋め込みたいYouTubeを右クリックし、「埋め込みコードをコピー」をクリック

Qiitaの記事記入欄でペーストすると

```
<iframe width="1254" height="641" src="https://www.youtube.com/embed/5qap5aO4i9A" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
```

このようなiframeタグを挿入し、上記のようにプレビューで動画が見えるようになっていればOKです

### 追記
iframe内の「width="〇〇"」ここの数値を変更すると大きさ変更できます。
実際に記事で見るときや、特にスマートフォンで見るときはでかすぎるので、`100%`とするのがおすすめです。（heightは400くらい）

<iframe width="100%" height="400" src="https://www.youtube.com/embed/5qap5aO4i9A" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

```
<iframe width="100%" height="400" src="https://www.youtube.com/embed/5qap5aO4i9A" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
```

### さらに追記

再生時間を指定しての埋め込みもできました！

<iframe width="100%" height="400" src="https://www.youtube.com/embed/XMsWBgNbuU0?t=2778" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

```
<iframe width="100%" height="400" src="https://www.youtube.com/embed/XMsWBgNbuU0?t=2778" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
```

[![Image from Gyazo](https://i.gyazo.com/b5575e2bf41a024532822378dfcc42d5.png)](https://gyazo.com/b5575e2bf41a024532822378dfcc42d5)

YouTubeでは現時点のURLをコピーできます。
例えば画像のやつですとこんなURLが取得できます。

```
https://youtu.be/XMsWBgNbuU0?t=2778
```

この`?t=2778`が再生位置を表すパラメータになっているので、これを埋め込みの`src=`のところにあるURLを末尾に追加してあげるとできました！

「現時点の埋め込みコードをコピー」なんて項目がでたら一発なんですけどねぇ

## 感想

簡単にできるようになってうれしいです！
過去の記事も更新していこうかと思うくらいいいアップデートだったなと思いました！
【CSS】word-breakの使い方

#プログラミング勉強日記
2021年3月11日


#word-breakとは
　改行方法を指定する。要素からテキストがはみ出る場合に改行方法を制御する。

#word-breakの使い方

```css:CSS
word-break: 値;
```

 この値には、`normal`, `break-all`, `keep-all`のどれかを指定する。

　normalは初期値で、既定の改行規則を適用する。
　break-allは、要素の幅に合わせて改行する。(単語の途中であっても改行する。)
　keep-allは、CJK(中国語、台湾語、日本語、韓国語)の改行を許可しない。


#参考文献
[CSSのword-breakプロパティを使った文章の改行の仕方を現役エンジニアが解説【初心者向け】](https://techacademy.jp/magazine/38602)
[word-breakプロパティの意味と使い方](dekiru.net/article/13129/)
【研究室向け】UbuntuでC/C++を用いたプログラミングの研修（ROSも）

# この記事の概要

- 個人的に，研究をやる上で必要と思う最低限のC/C++を用いたROSを含むプログラミングに関する知識を得るための研修的な動画を撮影
- それらをYouTubeにアップしているので，その動画へのリンクをまとめまています


# 環境

Ubuntu 20.04を使っています．インストールしていない方は，Web記事を参考にインストールを済ませてください．

テキストエディタにはgeditを基本的に使っています（たまにviも）．geditはデフォルトでインストールされていて，使い勝手も良いので使っています．ただしgeditに拘る必要はありません（私も実際にプログラミングするときは違うエディタを用いています）．適宜，お気に入りのエディタを探してみてください．



# 動画へのリンク

[【第1回】UbuntuでC言語を用いたHello worldの実行（.bashrcでaliasの設定も）](https://www.youtube.com/watch?v=ES9dMxD8hiM)
[【第2回】C言語でifとforとwhileを使ったプログラミング](https://www.youtube.com/watch?v=vbg3L-29914)
[【第3回】C言語におけるポインタと構造体を用いたプログラミング](https://www.youtube.com/watch?v=5qtrBIUF9cQ)
[【第4回】C++のプログラムをcmakeでコンパイル](https://www.youtube.com/watch?v=9FiBC7GZuqc)
[【第5回】C++におけるclass作り方（privateとpublicとコンストラクタ）](https://www.youtube.com/watch?v=waax8V0P-Zk)
[【第6回】ヘッダファイルの書き方と複数ソースファイルのコンパイル](https://www.youtube.com/watch?v=UMq1Fb9vXrU)
[【第7回】ファイルへの書き込みと読み込み（fprintfとfscanfの使い方）](https://www.youtube.com/watch?v=uBltzrOB1g0)
[【第8回】ファイルに書き込んだデータをgnuplotで描画](https://www.youtube.com/watch?v=j_PXNte4JEs)
[【第9回】gnuplotでアニメーションの描画](https://www.youtube.com/watch?v=l8ulqhd_ghw)
[【第10回】プログラムの引数とシェルスクリプトを用いた効率的な一括処理](https://www.youtube.com/watch?v=1WikAzrZka8)
[【第11回】std::vectorを用いたプログラミング（配列の利用）](https://www.youtube.com/watch?v=X6L_7vZRn2E)

ここからROSを使ったプログラミングになります．ROSのインストールは[こちら](https://qiita.com/oguashiii/items/f23f2d25531c9311e614)を参考にしました．

[【第12回】ROSを用いたプログラミング（std_msgs/Headerのpublish）](https://www.youtube.com/watch?v=Fs4tATada-0)
[【第13回】std_msgs/Headerのsubscriberの実装（classを用いたpub/subの実装例も）](https://www.youtube.com/watch?v=GfHUJVObdwA)
[【第14回】ROSで画像処理1（OpenCVで画像を読み込んでpublishする）](https://www.youtube.com/watch?v=ayDcyrZZQkw)
[【第15回】ROSで画像処理2（画像をsubscribeしてエッジ抽出してpublishする）](https://www.youtube.com/watch?v=gTDcwJpHDXU)
[【第16回】ROSで画像処理3（エッジ画像からハフ変換で直線抽出する）](https://www.youtube.com/watch?v=kQIkreWe9WY)

PCLを使った点群処理もやろうかと思いましたが時間の都合で断念しました．[コチラ](https://github.com/NaokiAkai/ros_intro)に解説付きのサンプルプログラムをアップしているので参考にしてください．サンプルプログラムに関する解説記事は[コチラ](https://qiita.com/NaokiAkai/items/4d0b18c0d71976d3fec5)に．

[【第17回】TFのbroadcastとstatic_transform_publisher](https://www.youtube.com/watch?v=DOsLH1W-8_k)
[【第18回】TF ListenerでTFツリーから座標を読む](https://www.youtube.com/watch?v=vCRsbNn09YU)


# まとめ

UbuntuでC/C++を用いたプログラミングの研修に関する動画へのリンクをまとめています．ROSに関するプログラミングもあります．もう少し充実させます．

21年3月11日作成開始
21年3月25日更新