OmniAICreator/Qiita-1.07M huggingface dataset:
【Git】作業巻き戻す

##前提条件として、Gitには以下の領域がある。
#####作業ディレクトリ
↓ $git add
#####ステージングエリア
↓ $git commit 
#####ローカルリポジトリ
↓ $git push
#####リモートリポジトリ

##過去の履歴に巻き戻す時は以下↓↓↓

####1 git revert  
コミットの歴史を改変するのではなく、新しくコミットが上に積まれるだけなので安心して使えるコマンド 
####2 git reset　
 コミットの歴史を改変＂ ※リモートリポジトリにはpush基本NG

#####2_1 git reset --soft　「commitしてリポジトリに上げたけど打ち消したい」
ローカルリポジトリへのcommit打消し
#####2_2 git reset --mixed  「git add してステージングに上げたけど打ち消したい」
ローカルリポジトリへのcommit＋ステージングエリアの変更打消し
#####2_3 git reset --hard　「ステージングエリアにも作業ディレクトリにも残らなくていいから、コミットをまるごと消したい」
ローカルリポジトリへのcommit＋ステージングエリアの変更＋作業ディレクトリの変更打消し


参考 
https://www.r-staffing.co.jp/engineer/entry/20191025_1
https://www.r-staffing.co.jp/engineer/entry/20191129_1
Linuxコマンドの履歴を検索して実行する方法

<kbd><kbd>Ctrl</kbd>+<kbd>R</kbd></kbd> を押すと、何か入力できそうなモードになります。

```shell
$
bck-i-search: _
```
例えば`pw`と入力すると、直近で実行した`pw`が入っているコマンド（例えば`pwd`）が表示されます。
表示されたコマンドでOKだったら <kbd>Enter</kbd> キーを押します。

もっと前のコマンドにさかのぼりたいときは、再度、<kbd><kbd>Ctrl</kbd>+<kbd>R</kbd></kbd> を連打します。
目当てのコマンドが見つかったら <kbd>Enter</kbd> キーを押してコマンドを実行します。


参考
<iframe width="966" height="510" src="https://www.youtube.com/embed/H0tUtzx2xX8" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

この技の存在は知っていたのですが、よく使い方が分からず結局いつも矢印キーを連打していました😂
今回ちゃんと知れて良かったです
標準入力を受け付けながら処理を分岐するシェルの書き方


たまーに書くことがある標準入力を受け付けながら処理を分岐するシェルのサンプル。

# こういうやつ

番号を入力したら入力された番号の処理を実行するってやつ。
以下のサンプルでは 1 を入力したら 1って処理を実行してる。
![movie.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/e9e974ce-3a69-2de8-1cbe-7b802b2d45ba.gif)

# テンプレート

read で標準入力を受け付けて、 Swith文で分岐する、みたいな感じ。

```bash
#! /bin/bash
####################################################
# スクリプト名 : main.sh
# 説明         : 指定された処理を実行するよ
# 引数         : なし
#   $1         : -
# 実行例       : ./main.sh
# 更新日       : YYYY/MM/DD
# 作成者       : takiguchi-yu
####################################################

# 処理1 引数なし
function _func1
{
  echo
  echo -e "\033[0;32m[INFO]: \033[0;39m"処理1 開始します
  echo -e "\033[0;32m[INFO]: \033[0;39m"処理1 終了します
  echo
}

# 処理2 引数2つ
function _func2
{
  echo
  echo -e "\033[0;32m[INFO]: \033[0;39m"一つ目の引数
  echo -e "\033[0;32m[INFO]: \033[0;39m"$1
  echo -e "\033[0;32m[INFO]: \033[0;39m"二つ目の引数
  echo -e "\033[0;32m[INFO]: \033[0;39m"$2
  exit 0
}

# メイン処理
while :
do
  echo "------------------------------------------------------"
  echo -e "\033[0;34m[1]: \033[0;39m"処理1 を実行します
  echo -e "\033[0;34m[2]: \033[0;39m"処理2 を実行します
  echo -e "\033[0;34m[3]: \033[0;39m"処理3 を実行します
  echo -e "\033[0;31m[q]: シェルを終了します\033[0;39m"
  echo "------------------------------------------------------"
  read -p "番号を選択してください: " num
  case "${num}" in
    "1" ) _func1 ;;
    "2" ) _func2 arg1 arg2 ;;
    "q" ) exit ;;
  esac
done

```
入社３年目Sier：初めての要件定義

#初めに
はじめまして、Dellgreenと申します。
要件定義に初めて参画しましたので、所感・反省点・今後生かしたいことなどを
まとめようと思いました。

はじめに以下私の自己紹介プロフィールになります。

>名前：Dellgreen
学歴：大学時　情報工学専攻（まじめに勉強してませんでした）
年齢：20代前半
経歴：システム系SIer入社
　　　配属後からずっと同じ案件の開発工程(たまに詳細設計),環境構築,運用担当
技術：Oracle(Bronzレベル)、Java(Struts)、Linux(基本操作レベル)
担当：パッケージ(購買領域)　　　　

入社よりパッケージの開発・運用をしており、要件定義から参画するのは
今回が初めてになります。
なので、右も左も分からない状態での参画でした。
※パッケージ・・・以下PKG

#案件について
以下案件の概要になります
>お客様：大手メーカホールディングス
案件概要：1.購買システムの刷新
　　　　　2.会社内の購買システム統合
　　　　　　SAPとスクラッチ購買システムの併用▶︎弊社購買パッケージに統合
　　　　　3.要件定義をしてる中で、想像以上のGapが発生
　　　　　　開発コスト50人月　Gap:150人月▶︎予定の３倍のGap
前提：弊社PKGに業務を合わせて統合する
個人の立ち回り：初要件定義なので役立たず
　　　　　　　　タスクは議事録作成、会議の資料作成レベル

私は要件定義の中盤からの参画でした。
思ったよりのGapが発生しており、弊社もお客様もどう収束していけば
よいか頭を悩ませている状態。。。

#要件定義
下記の３本立てでメモを残します。
◆進め方
◆反省点(弊社・顧客両者の視点）
◆個人の反省点

##進め方
まず弊社側がどのように要件定義を進めていったか簡単にまとめます。
1.弊社のPKG説明(説明資料・デモの提示)
2.お客様の業務フローを受領、弊社PKGで実現できるかマッピング
3.実現不可で、Gapになる箇所を洗い出し
4.お客様でそのGapが絶対に必要か・希望レベルか・PKGで代替可能か分類

###弊社反省点
弊社反省点といいつつ、個人的に「これどうなの？」と思った点です。

・**PKGのイメージが共有できていない**
まずこれです。
・パワーポイントで図説使って説明しました。
・デモ画面を使って説明しました。

ですが・・・・・
こちらは説明したつもりになっていましたが、
お客様には十分にPKG機能が伝わってないように見受けられました。

会議参加しているお客様全員にデモ機をお渡しして
実際にPKGを触って感覚を掴んでもらう必要があるのでは？と思いました。

・**PKGなのにPKG資料が少ない**

お客様「SAPとテーブル構造・カラムのすり合わせをしたい、
　　　　御社PKGの資料をいただける？」
弊社　「テーブル定義書レベルのものしかない」
お客様「このテーブルのこのカラムは何に使用するかとかの説明書きはない？」
弊社　「ありません！」

いやあれよ！
このPKGは開発されてから１０年くらいたってるものです。
資料がもう少し充実しててもいい気がします。
PKG保守にお金をあまりかけれないというのも理解できますが、
もう少し充実しておいてもよいのでは、、、？
個人的には要件定義が後ろ工程で全ての影響を決めるもっとも重要な過程だと
認識しているので、もう少し手厚く資料を作っておくべきでは？と思いました。

SAPレベルになるとネットで概要とか簡単に転がっていますが。
(SAPみたいにシェア率が桁違いのものと比較するのはどうかとは思いますが)
https://tokulog.org/blog/tutorial_fi/

・**１人の技術者の頭の中で完結している**
お客様「このGapの影響画面はどのレベル？どう実現しよとしている？」
弊社A 「〜〜〜で、〜〜です」
弊社B 「(そうなんだ)」
弊社C 「(そういうことか)」
お客様「御社Aさんは把握できているかも知れないが、こちらは把握できていない」

Gapの実現方法を弊社の技術者１人で完結してしまっていて、
共有ができていないことが多かったです。
お客さんだけでなく弊社内でもわかないことが多い現状。

会議の中でどう実現するかもしっかり打ち合わせし、文言を残していくべきだったと
思います。

###お客様反省点

・**PKGに合わせる前提を忘れている**
「今のシステムはこうなっている」
「この機能がないと業務が回らない」

といったように、PKGに合わせる前提を忘却していました。
運用視点で見ると、システム依存で業務が改革される恐怖はあると思います。
ただシステム開発の前提を見失っています。

もう少し、「PKGに合わせるんだぞ、この案件は」といった発言ができる
参加者がいたらだいぶ違ったのかと思います。

###個人反省点

今もまだ要件定義段階です。
要件定義が終わり次第、個人的な反省点もまとめようと思います。

この案件が炎上しませんように。。。。。。
TypeScriptのUtility Typesを理解して活用する

# この記事は何？
TypeScriptの**Utility Types**の概要について紹介する記事です。

# Utility Typesとは？

そもそも英単語としてのUtilityの意味は、**実用性や役に立つ**ということのようです。
> utility [名]
> 実用性、役に立つこと、用役、有用性、効用
> https://eow.alc.co.jp/search?q=utility

TypeScriptにおけるUtility Typesとは、
**TypeScriptが提供する関数のような便利な機能**の型になります。

また、公式にはこう書いてあります
> TypeScript provides several utility types to facilitate common type transformations.
> TypeScriptは、一般的な型変換を容易にするいくつかのユーティリティ型を提供します。

型を変換する時に使うものがUtility Typesと思って良さそうです。

# 具体例
定義だけ見てもわかりずらいので、実際に使用例を見てみましょう。
実務でもめちゃくちゃ使う`Pick`についてです。

説明の例として、ある型`Todo`を作ったとします。

```typescript
interface Todo {
  title: string;
  description: string;
  completed: boolean;
  pending: boolean;
  percentage: number;
}
```

これを使いまわして、あるオブジェクトで使いたいのですが、
必要なのは`title`, `description`だけの時、
同じように記述するのは、**なんだか冗長な気がします。**

その時に活躍するのが`Pick`です。

```typescript
type TodoPreview = Pick<Todo, "title" | "description">;
```

これにより、型`Todo`から新しい型`TodoPreview`を作成することが出来ました。
`TodoPreview`は以下と同義です。

```typescript
interface TodoPreview {
  title: string;
  description: string;
}
```

このように`Pick`では、既にある型から一部だけピックして、新しい型を作ることが出来ます。

以上のように、**型定義をスマートに書くことが出来るもの**が`Utility Types`の一例になります。

# Utility Types一覧
Utility Typesはたくさんあります。
全部覚える必要はないと思いますが、それぞれ簡単に理解しておくと、よりスマートなコーディングに活用できるかもしれません。

- [Partial＜Type＞](https://qiita.com/NOMURA_keibyou38/items/0771efb6661bfa4f5178): Typeをオプショナル型にして型を作成
- Required＜Type＞
- [Readonly＜Type＞](https://qiita.com/NOMURA_keibyou38/items/a0729cc05909cea858d5): ReadOnlyな型を作成
- [Record＜Keys,Type＞](https://qiita.com/NOMURA_keibyou38/items/b7fe5fcb08a825dda16d): 型を組み合わせてオブジェクトの型を作成
- [Pick＜Type, Keys＞](https://qiita.com/NOMURA_keibyou38/items/03a18b64864a21e0a512): TypeからKeysを取得する型
- [Omit＜Type, Keys＞](https://qiita.com/NOMURA_keibyou38/items/7bbc49bbdbe97f3649a6): TypeからKeysを除外する型
- [Exclude＜Type, ExcludedUnion＞](https://qiita.com/NOMURA_keibyou38/items/bb44c71668f73e296a30): Typeの中から指定したUnion型を取り除いて、新しい型を作成
- [Extract＜Type, Union＞](https://qiita.com/NOMURA_keibyou38/items/591f25549b5a7445100e): Typeの中から指定したUnion型を抜き取って、新しい型を作成
- NonNullable＜Type＞
- [Parameters＜Type＞](https://qiita.com/NOMURA_keibyou38/items/ecfc6c798f4d59d762a4): Type（関数の引数）から型を作成する
- ConstructorParameters＜Type＞
- [ReturnType＜Type＞](https://qiita.com/NOMURA_keibyou38/items/fc9d21aee217b4213430): 関数の返り値の型で型を作成
- InstanceType＜Type＞
- ThisParameterType＜Type＞
- OmitThisParameter＜Type＞
- ThisType＜Type＞
- Intrinsic String Manipulation Types
- Uppercase＜StringType＞
- Lowercase＜StringType＞
- Capitalize＜StringType＞
- Uncapitalize＜StringType＞

# おわりに
この記事では、Utility Typesそのものを簡単に紹介しました。
場面にあったUtility Typesを利用して、快適なコーディングライフとサービスの品質を向上させちゃいましょう！
自分は、Reactで開発する際にめちゃくちゃ使っています！！

# 参考にした記事
- https://www.typescriptlang.org/docs/handbook/utility-types.html
- https://qiita.com/k-penguin-sato/items/e2791d7a57e96f6144e5
- https://eow.alc.co.jp/search?q=utility
【備忘録】非同期通信（Ajax）

<h1>前置き
<p>ポートフォリオに非同期通信の実装をした時の流れ
PHPは作成済みとする。

非同期通信を分かりやすく言うとページ移動をせずにページ更新を行うこと。


<h1>全体的な流れ
<p>
1.更新したときに表示させたいtころに＜div＞を作る。idもつける
<a href="#anchor1">2.＜/body＞直上に＜script＞の追加 
<a href="#anchor2">3.＜script＞で送られた情報をPHPにて操作する





<h1 id="anchor1">2.＜/body＞直上に＜script＞の追加
<p>

```
  <script>
    $(function() {

      // ボタンがクリックされた時の処理
      $("[type=submit]").on('click', function() {
        $.ajax({
          // 送信方法
          type: "POST",
          // 送信先ファイル名（この場合だとpost.php）
          url: "post.php",
          // 受け取りデータの種類
          datatype: "json",
          // 送信データ
          data: {
            // POSTに送る情報をいい感じに（IDをつけておく）
            "id": $('#id').val(),
            "message": $('#message').val(),
          },

          // 通信が成功した時
          success: function(data) {
            console.log("通信成功");

          //通信成功した時の操作
            $("#mein").prepend('<div id="ajax" class="item"></div>');
            $("#ajax").prepend('<div id="item-left" class="item-left pt-3"></div>');
            $("#ajax").append('<div id="item-right" class="item-right m-lg-3"></div>');
            $("#item-left").append('<img src="member_picture/<?php print(htmlspecialchars($member['picture'], ENT_QUOTES)); ?>" alt="<?php print(htmlspecialchars($member['name'], ENT_QUOTES)); ?>">');

            $("#item-right").append('<p><?php print(htmlspecialchars($member['name'], ENT_QUOTES)); ?></p><p>' + data.message + ' </p> <a><p style="background-color: #0D6EFD;color: #fff;border-radius: 3px;padding: 5px;" >新規投稿しました！</p>');
            $('textarea').val(""); 
            console.log(data)
          } 
        });
      });
    });
  </script>

```
<p>通信が成功した時の操作より前はID以外ほぼテンプレ
注目すべきはここ

```
 $("#item-right").append('<p><?php print(htmlspecialchars($member['name'], ENT_QUOTES)); ?></p><p>' + data.message + ' </p> <a><p style="background-color: #0D6EFD;color: #fff;border-radius: 3px;padding: 5px;" >新規投稿しました！</p>');
```

<p >+ date.message+ とすることで打ち込んだメッセージをすぐに表示できている


成功した時の操作はこちらを参考にしました。
分かりやすかったです。
<a href="https://qiita.com/nekoneko-wanwan/items/227ccad5f8cc449e91e9">jQueryを利用したDOM操作 要素の追加メソッドまとめ





<h1 id="anchor2">3.＜script＞で送られた情報をPHPにて操作する
<p>さあここよな～

```PHP:post.php
<?php
//お決まり
session_start();
require('dbconnect.php');

//まずは
$id = $_POST['id'];
$message = $_POST['message'];
$reply = $_POST['reply'];

//POSTの値をDBにINSRT
if (!empty($_POST)) {
  if ($_POST['message'] !== '') {
    $message = $db->prepare('INSERT INTO messages SET member_id=?, message=?, reply=?,created=NOW()');
    $message->execute(array(
$_POST['id'],
   $_POST['message'],
   $_POST['reply']
    ));

//ここはテンプレ
    header('Content-Type: application/json; charset=utf-8',);
//ここはね～多分結び付けかな？
//ここの＄idとscriptのidは一緒に！みたいな？？
    echo json_encode(['id' => $id, 'message' => $_POST['message']);
} else {header('Content-Type: application/json; charset=utf-8',);}} 
?>
```

<p>正直最後の一文はあいまいな理解です。
これをポートフォリオに実装することで、Javascriptへの理解が深まった（少しだけ）
海外のスライド共有サービスがやる気ないので自分で作ってみた

先日「ドクセル」というサービスをリリースしたので技術的な振り返りをQiitaにも投稿します。

追記：Qiitaにドクセルの埋め込み機能が対応しました！
<script async class="docswell-embed" src="https://www.docswell.com/assets/libs/docswell-embed/docswell-embed.min.js" data-src="https://www.docswell.com/slide/LK7J5V/embed" data-aspect="0.5625"></script><div class="docswell-link"><a href="https://www.docswell.com/s/ku-suke/LK7J5V-hello-docswell">Docswell（ドクセル）はじめました by @ku-suke</a></div>


# モチベーション
- SlideShareが親会社をころころ変えるわりに中身が進化してなくてやる気ない
- SpeakerDeckが日本語のファイルをアップするとSlugを勝手に中国語読みにする
- なんか個人サービス作りたい

# 作ったもの
- https://www.docswell.com
- ドクセル　と読ませるようにしている
- シンプルなスライド共有サービス
- Laravelベース

![2021-03-07_h7m9u_スライドやPDFをかんたん共有 _ ドクセル - Google Chrome.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8727/75c8674b-4da3-74b2-2a77-24b9e6f06bde.png)

## 特徴
- 画質がいい（長辺1920px・Full HD相当のプロジェクターにも耐えうる）
- URL（Slug）をある程度自分で決めることができる
- マウスオーバーに頼らない（タッチデバイスを意識）

## アーキテクチャ

![Docswell Architecture (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8727/ec5c8632-2510-2186-1a27-ba996792bf82.png)

アーキテクチャはこんな感じです。初期バージョンとしては、PHPなので共用サーバで済ませました。SMTPサーバもついてるし楽ちんですね。Deployerというものを教えてもらったので、Github Actions経由で自動デプロイできて、何かあったときのロールバックもコマンド一つでできます。

### 変換エンジンの悩み

PDFを画像にするまではいろいろ悩みました。まずOfficeファイルを対応するかですが、当初LibreOfficeをCloudRunでうごかしたりしていたのですが、なかなか良い変換結果が出なかったので本家MSのサービスを利用しました。

PDFから画像にするエンジンもいろいろあり、大きく分けてGhostscript系、Poppler系、PDFium系などがあり、当初Poppler系で実装していました。

ところが、内輪でテストしたときに、Google Slidesからエクスポートしたスライドでエラーをはくことがわかりました。そこでリリース直前にGhostScript系に変更しました。

> 💡 余談ですが、簡単にエンジンを変更できるのは、単純にCloud Runのnodejsからspawnでコマンドラインをたたいているからです。PDFの取り扱いは、セキュリティ界隈では有名ですが脆弱性のワンダーランド、脆弱性の大海原となっておるわけです。そのため、メインのアプリケーションからは分離して、コンテナ環境で都度変換する仕組みをとっています。

しかし、リリースしていろんな方にファイルをアップしていただくと、ことごとく変換に失敗してしまいました。また、変換ができているケースも、速度が6倍ほど遅く、タイムアウトになっているケースもありました。そのため、Poppler系に戻しつつ、エラーハンドリングを強化するという実装に着地しました。

## いずれ引っ越し、商用プランに耐えうるように

（自分の本業はエンジニアくずれのPMなのですが）当初、この企画を作るにあたり勉強を兼ねてReact/Firebaseで開発する予定でした。しかし、B2Bプロダクトの特性上、将来的に企業利用が進む場合あのめんどくさいセキュリティチェックシートを書かなくてはなりません。そうでなくとも、お堅い企業から通信先としてホワイトリストに登録してもらうには、fqdnを限定する必要があります。

そのようなビジネス的な要件に対応するため（要はマネタイズのため）枯れた技術で作ることにしました。こうしておけば、アプリケーション本体も変換エンジンも基本はDockerコンテナがホストできれば動作するので、5000兆円払うからプライベートクラウド版作ってほしい！みたいなオファーをいただいた時にも対応できるようになりました。同様の理由で、InternetExplorer 11にもおおむね対応しています。なお本体部分は最初の実装と実装アドバイスを@mikkameさん、プレーヤ部分は自分の技術力では無理だったので[Splide.js](https://splidejs.com/)の作者様にカスタマイズ依頼をそれぞれ発注させていただきました。

# みなさんのスライドをアップしてみてほしい

今後ドクセルでは、noteやZennのようにスライドを有償販売できたり、作成者を応援できる機能などを予定しています。でもその前に、安定したサービス運営のため、皆さんのスライドをどんどんアップいただきたいと思います。ぜひslideshareやspeakerdeckにアップしたスライドを転載いただけると嬉しいです！

- https://www.docswell.com
【Rails】bundle install --without productionすると、You have requested:   listen = 3.1.5というエラーになった場合の対処法【Ruby】

<h2>症状</h2>
Railsチュートリアル3章でセットアップしようとしたときに遭遇したエラーです。
環境はCloud9で、Gemなど他は<a href="https://railstutorial.jp/chapters/static_pages?version=6.0#cha-static_pages">Railsチュートリアル3章</a>と同様になります。

自分の環境でセットアップをしようとしても、うまく動作しませんでした。


```
bundle install --without production
```

bundle install --without productionで帰ってきたエラーが下記です。


```
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
Fetching gem metadata from https://rubygems.org/............
Fetching gem metadata from https://rubygems.org/.
You have requested:
  listen = 3.1.5

The bundle currently has listen locked at 3.4.1.
Try running `bundle update listen`

If you are updating multiple gems in your Gemfile at once,
try passing them all to `bundle update`
```

メッセージ通りに、 `bundle update listen`を実施しても下記エラーが出てしまいました。

```
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
Fetching gem metadata from https://rubygems.org/............
Fetching gem metadata from https://rubygems.org/.
You have requested:
  spring = 2.1.0

The bundle currently has spring locked at 2.1.1.
Try running `bundle update spring`

If you are updating multiple gems in your
```

返ってきたエラー通りに、bundle update springをしても下記エラーが出てしまいました。

```
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
Fetching gem metadata from https://rubygems.org/............
Fetching gem metadata from https://rubygems.org/.
You have requested:
  listen = 3.1.5

The bundle currently has listen locked at 3.4.1.
Try running `bundle update listen`

If you are updating multiple gems in your Gemfile at once,
try passing them all to `bundle update`
```


<h2>解決策</h2>

bundle updateをしたら、bundle installが通るようになりました。

```
bundle update
```

Railsチュートリアルを下にスクロールしていくと、普通にエラー対処が載ってました。

躓いたらそこで止まってしまいがちですが、そのまま下に行くとエラー処理について書いてあることがあるので、気を付けていきたいです。
Office 365 Management APIによる監査ログの取得

# 概要
Office 365で監査ログをAPIにより取得する方法です。
監査ログはMicrosoft365 コンプライアンス画面からも取得可能ですが、本稿ではAPIで取得する方法を記載します。

# 監査ログ取得手順

おおよそ以下の手順です。

1. Exchange Online PowerShellのインストール
2. Office365の監査ログの有効化
3. APIアクセスのためのアプリケーション登録
4. APIの呼び出し

## 1. Exchange Online PowerShellのインストール

Exchange Online PowerShellは直接的には必要ありませんが、何かと使えた方が便利ですし、後続の監査ログの有効化を行う場合は必須です。
基本的には、以下のページに記載された手順を行えば問題ありません。（インストール済みの方は本手順は不要です）

https://docs.microsoft.com/ja-jp/powershell/exchange/connect-to-exchange-online-powershell?view=exchange-ps

この手順はモジュールがインストールされていることを前提にしているので、インストールされていない場合は、以下のページの通りモジュールをインストールします。

https://docs.microsoft.com/ja-jp/powershell/exchange/exchange-online-powershell-v2?view=exchange-ps

このページに記載の「EXO V2 モジュールをインストールする」手順を実行すればよいです。
PowerShellの起動は以下の通りです。

```PowerShell
Install-Module -Name ExchangeOnlineManagement
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName your_UPN
```

1行目は、モジュールをインストールするためのものです。インストール中にプロンプトが表示されますが、インストールを続行する方向で回答してください。
すでにモジュールをインストール済みであれば、2行目から実行してください。

## 2. Office365の監査ログの有効化

おおよそのことは以下のページに記載があります。

https://docs.microsoft.com/ja-jp/microsoft-365/compliance/turn-audit-log-search-on-or-off?view=o365-worldwide

「Microsoft 365 および Office 365 Enterprise 組織では、監査ログは既定でオンになっています。」ということですので、既にオンになっている環境では本手順は不要です。が、私の環境の初期状態はオフでした。何度か試しましたが、すべてオフでしたので、ドキュメントのエラーかと思われます。
いずれにしても、オンオフの状態は、以下のコマンドで確認できます。

```
Get-AdminAuditLogConfig | FL UnifiedAuditLogIngestionEnabled
```

オフになっている環境では以下の手順で有効化してください。

1. Exchange Online PowerShellに接続します。
2. ```Enable-OrganizationCustomization```を実行し、30分から1時間程度待ちます。
3. 監査ログを有効化します。

```
Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true
```

有効化には60分程度かかるそうです。
あとは、監査ログに記録が残るように、いろいろとOffice365にアクセスしてください。

## 3. APIアクセスのためのアプリケーション登録

Azure ADでアプリ登録を行います。手順は多数の有識者が説明してくれていますので、ここでは割愛します。
ここにも記載がありました。

https://qiita.com/ta9ma_0k/items/998f616f86af528253e1

アプリを登録したら、Office 365 Management APIの権限を付与してください。

## 4. APIの呼び出し

以下のページに9割の情報が記載されていますので、（多少の記載の誤りはありますが）そちらを見ていただくのがよいかと思います。

https://docs.microsoft.com/ja-jp/office/office-365-management-api/office-365-management-activity-api-reference

### ドキュメントの補足

上記ドキュメントの分かりにくいところを補足します。
APIのエンドポイントは、たとえばサブスクリプションの開始であれば ```/subscriptions/start?contentType={ContentType}``` と記載されていますが、これはほとんどの環境では以下のようになります。

```
https://manage.office.com/api/v1.0/{tenant_id}/activity/feed/subscriptions/start?contentType={ContentType}
```

これらAPIはすべて、OAuth2 アクセス トークンを取得して、HTTP ヘッダに```Authorization```を含める必要があります。トークンの取得方法は以下のドキュメントを参考にしてください。

https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow

ですので、API呼び出しの流れは、以下のようになります。

1. OAuth2 アクセス トークンの取得
2. サブスクリプションの開始 (```/subscriptions/start```)
3. 利用可能なコンテンツのリストの作成 (```/subscriptions/content```)
4. コンテンツの取得 (```/subscriptions/content``` から返されるURL)
5. サブスクリプションの停止 (```/subscriptions/stop```)

サブスクリプションは、一度開始してしまえば停止する必要はないようです。また、サブスクリプションを開始後、停止しないまま再度サブスクリプション開始のエンドポイントを呼び出すとエラーになります。
サブスクリプションが開始されているかどうかは、```/subscriptions/list```エンドポイントで確認が可能です。

# 最後に

記載の内容は、Microsoft 365 Developer Program の環境で確認しています。Microsoft社のドキュメントと動作が異なる箇所がいくつかありましたので、実際の開発では実際の動作を確認しながら行う必要があります。
amplifyの作法 その26

#概要

amplifyの作法、調べてみた。
ナップザック問題やってみた。

#参考にしたページ。

https://qiita.com/drken/items/ace3142967c4f01d42e9

#サンプルコード

```
from amplify import BinaryPoly, gen_symbols, sum_poly, BinaryQuadraticModel, Solver, decode_solution
from amplify.constraint import less_equal, equal_to
from amplify.client import FixstarsClient

a = [1, 6, 9, 36, 81] 
c = [1, 1, 1, 1, 1] 
q = gen_symbols(BinaryPoly, 5)
f = a[0] * q[0] + a[1] * q[1] + a[2] * q[2] + a[3] * q[3] + a[4] * q[4] 
h0 = equal_to(f, 127)
h1 = -0.1 * (c[0] * q[0] + c[1] * q[1] + c[2] * q[2] + c[3] * q[3] + c[4] * q[4])
H = h0 + h1
model = BinaryQuadraticModel(H)
solver = Solver(client)
result = solver.solve(model)
values = result[0].values
print(values)
print(f"q = {decode_solution(q, values)}")

```


以上。
CSS gridでrepeat関数にauto-fillとauto-fitを指定した時の動作の違い

CSS gridレイアウトのgrid-template-columnsプロパティで、repeat()関数にauto-fillとauto-fitを指定した時の動作の違いがよくわからなかったので、調べたメモです。
たとえば下記のCSSの場合、AとBでブラウザに表示される列グリッドの見た目にどんな違いが生じるでしょうか？

```css:css
.container {
  display: grid;
/* A */ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* B */ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
```

[MDNの説明](https://developer.mozilla.org/ja/docs/Web/CSS/repeat())によると、auto-fitについては

> auto-fill と同様に動作しますが、グリッドアイテムを配置した後、**空の繰り返しトラックが折りたたまれる点が異なります**。空のトラックとは、フロー内のグリッドアイテムが配置されていない、またはそれをまたいで配置されているものがないトラックのことです。（以下略）


言葉だけだとわかりにくいので、実際２つのgridコンテナにそれぞれauto-fillとauto-fitを指定したものを並べてトラック幅を変化させてみたら違いを理解でました。この動画です。

<p class="codepen" data-height="542" data-theme-id="light" data-default-tab="result" data-user="kaz_hashimoto" data-slug-hash="bGBxMYa" style="height: 542px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="[CSS grid demo] Differences between auto-fill and auto-fit in repeat() function">
  <span>See the Pen <a href="https://codepen.io/kaz_hashimoto/pen/bGBxMYa">
  [CSS grid demo] Differences between auto-fill and auto-fit in repeat() function</a> by Kazuhiro Hashimoto (<a href="https://codepen.io/kaz_hashimoto">@kaz_hashimoto</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

動画で使用したサンプルのHTML/CSSコード：
https://codepen.io/kaz_hashimoto/pen/MWbGewB

**参考記事**
[What is the difference between auto-fill and auto-fit?](https://stackoverflow.com/questions/46226539/what-is-the-difference-between-auto-fill-and-auto-fit)
AWSの分散負荷テストツールを使ってみた

AWSで負荷分散テストのツールがリリースされてたので使ってみました
・[AWS負荷分散テスト](https://aws.amazon.com/jp/solutions/implementations/distributed-load-testing-on-aws/)

#特徴
* CloudFormationで5分～10分でデプロイできる
* コンテナから対象のサーバへ負荷をかけらる
* 数千のリクエストをエミュレートできる
* コストは無料
　(デプロイしたコンテナとかのサービス自体のコストは発生だけど数十円)
* HTTP(S)リクエストのみで負荷がかけられる
　(SQLクエリや認証の負荷はかけられない)
* AWSから負荷テストを実行するのに 承認を得る必要はない

　※通常は負荷テストを行うのにAWSへの申請が必要です

#構成図
AWSに公開されている、分散負荷テストルーツの構成図
![スクリーンショット 2021-03-07 161434.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197418/f3014265-50d1-dc0c-d9db-0f64071bea2d.jpeg)

#デプロイ-実行-結果までのプロセス
![スクリーンショット 2021-03-07 162114.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197418/a56baa9b-801a-671c-aef4-56e951d672c1.jpeg)

#デモテスト環境の構成
* 負荷分散テストのコンテナからEC2上のApache(Httpサーバ)へ負荷をかける

　 ※コンテナの台数はシナリオ作成時に調整できます
![スクリーンショット 2021-03-07 162244.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197418/fe0fabeb-03d7-b15e-0f71-c23d9ef7057a.jpeg)

#シナリオの作成
* 100(①)×100(②)=10,000リクエスト​

* ③　3分間かけて10,000リクエスト​

* ④　2分間10,000リクエストを維持
![2021-03-07_16h47_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197418/bb806536-7bc6-e294-b1d8-b16d68c99945.png)


#テスト結果
* 5分間で約100万リクエストが成功
* エラー数はゼロ

![2021-03-07_17h00_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197418/6fdef9d6-296b-d4dd-c1c9-5781bd74688f.png)

#感想
機能は限定されますが、短時間で負荷テストの環境が構築できるのは便利ですね！

以前にJmaterで認証の負荷テストをやったことがありますが
その時はPC数台を準備して、そこにJmeterを入れてシナリオ作成しました

それに比べるとAWSの分散柄テストツールは準備時間20分くらいでしたのでかなり楽でした
コストもほぼ発生しないです

**負荷テストの選択肢に検討してみるとよいのではと思います**
Dartでクロージャを利用したコールバックを書く

最近Flutterがマイブームです。
めちゃくちゃ実装が楽ですね。

が、Dart自体はJavaに似ていてあまり使い勝手の良い言語ではない気がします。

SwiftやKotlinだとよく見られる、クロージャを利用したコールバックですが、Dartだとあまり出てきませんでした。

例えばKotlinだと

```kotlin
fun hoge(completion: ((text: String) -> Unit) {
    if (isEnd) {
        completion("終わりました")
    }
}
```
呼び出すときは

```kotlin
completion { text in
    print(text) // 終わりました
}
```

↑こんなやつ。Swiftもほぼ一緒ですね。
が、Dartだとどう書けば良いだろうと悩みました。
~~そして何度書いてもすぐ忘れてしまうのでちゃんと書いときます~~

例としてカウントダウンを実装してみます。
※主旨はコールバックの説明なので、厳密にカウントするわけではなくざっくり一秒ずつカウントします

initState()でカウントダウンをコールバックするメソッドを実行して、このメソッドで一秒経つごとにコールバックするという仕組みです。（当たり前ですがどこで呼び出しても良いです）

↓早速実際のコードです

```dart
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    // ↓ここで呼び出して、カウントをコールバックされてる
    _countDown((String count) {
      print(count);
    });
  }
  // ↓ここでカウントダウンをコールバックしてる
  Future<void> _countDown(void Function(String text) completion) async {
    for (int count = 10; count >= 0; count--){
      await Future.delayed(Duration(seconds: 1));
      completion(count.toString());
    }
  }
```

「Function」と明示的に書かなきゃいけないのがちょっと新鮮でした。
が、使い勝手はSwiftやKotlinと大差ないので一安心です。
【Rails】バリデーションエラーのメッセージを日本語化する方法

##デフォルトのエラーメッセージ

https://gyazo.com/3291dba8372c0364dff4f94fed2f8184

分からなくもないですが見た目がイマイチですよね...
このエラーメッセージを日本語化していきます！

###日本語化の手順
まずはgemを記述して bundle install します。

```ruby:Gemfile
gem 'rails-i18n'
```

次に config/application.rb に以下を記述します。

```ruby:config/application.rb
config.i18n.default_locale = :ja
```

これで準備は整いました。
あとはサーバを起動するだけです！
（サーバが起動済みの場合は、再起動してください。）

https://gyazo.com/fd93e80edf6fc65e725bf278be912af6

おお...
日本語にはなりましたがカラム名がそのままなので少し違和感がありますね。
せっかくなのでカラム名も変えましょう！

###カラム名を日本語化する手順
まず config/locales/models/に、ja.ymlというファイルを手動で作成します。
そこに以下のようにカラムに対して名前を記述していきます。

```ruby:config/locales/models/ja.yml
ja:
  activerecord:
    models:
      user: ユーザー
    attributes:
      user:
        name: ユーザー名
        email: メールアドレス
        password: パスワード
```
次に config/application.rb に以下を記述します。

```ruby:config/application.rb
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.yml').to_s]
```
これで準備が整いました。さっそく見てみましょう！

https://gyazo.com/1b80790dfbeb196b73788682b0471317

とても見やすくなりました！
ずっとエラー文が英語なのが気になっていたのでスッキリしました。

Qiitaで初めて記事を書きました。
日々の学びを、日記感覚で投稿していこうと思います。
初学者故に至らない所も多々あると思いますが、宜しくお願い致します。


####【参考にさせていただいた記事】

https://qiita.com/Ushinji/items/242bfba84df7a5a67d5b
例外処理　すべてのコントローラーに共通する設定

・すべてのコントローラーに共通する例外処理を設定することができる。
　そのためには[ControllerAdvice](https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ControllerAdvice.html)クラスを作成します。
・ControllerAdviceクラスはすべてのコントローラーで共通する処理を定義する。
　例外処理はその共通する処理として定義できる1つ。

```CustomController.java

@ControllerAdvice
public class CustomControllerAdvice {
  @ExceptionHandler
  public String handleException(Exception e) {
    return "error/index.html";
  }
  
}
```

ControllerAdviceクラスはクラスのアノテーションとして「@ControllerAdvice」を追加
特定の例外を処理したい場合はアノテーションにExceptionクラスを指定します。

[・ExceptionHandler](https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ExceptionHandler.html)
例外のハンドルは「@ExceptionHandler」を付与したメソッドで行います。
これを使用することでtry-catchも少しだけ減らすことができ、コントローラクラスに複数のAPIを用意した場合にエラー処理を共通的に記述することができます。

#####例外処理の優先度
個別設定（try-catch）
⬇️
コントローラー設定
⬇︎
全体設定の順になります。
「404 Not Found」などはコントローラーで処理する前に処理されます。




####参考記事
https://b1tblog.com/2020/02/07/spring-boot-8/

https://qiita.com/NagaokaKenichi/items/2f199134a881a776b717
ROSの勉強　第21弾：地図サーバ

# #プログラミング ROS< 地図サーバ >

##はじめに
1つの参考書に沿って，ROS(Robot Operating System)を難なく扱えるようになることが目的である．その第21弾として，「地図サーバ」を扱う．


##環境
#####仮想環境
|||
|:-:|:--|
|ソフト|VMware Workstation 15|
|実装RAM|2 GB|
|OS|Ubuntu 64 ビット|
|isoファイル|ubuntu-mate-20.04.1-desktop-amd64.iso|

#####コンピュータ
|||
|:-:|:--|
|デバイス|MSI|
|プロセッサ|Intel(R) Core(TM) i5-7300HQ CPU @ 2.50GHz 2.50GHz|
|実装RAM|8.00 GB (7.89 GB 使用可能)|
|OS|Windows (Windows 10 Home, バージョン：1909)|

#####ROS
|||
|:-:|:--|
|Distribution|noetic|
|プログラミング言語|Python 3.8.5|
|シミュレーション|gazebo|

##地図サーバ
ここでは，前回(https://qiita.com/Yuya-Shimizu/items/515d76ba83d3ce8b208e )作成した地図データをROSで使えるように``map_server``パッケージの``map_server``ノードを使う．YAMLファイルに適用し，その後rvizでの地図表示についても学習する．

##map_server
以下に，画像を適宜示しながら，地図についてのトピックを配信する様子を示す．

**map_serverにmap.yamlを適用して実行**
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/a3f81024-130c-b9fc-ab58-6a9d38a77017.png)
これにより，2つのトピックが配信される．

**トピックの確認**
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/60801970-1da5-a8a3-b239-712c17c9f854.png)
上から2つが先ほどの操作により配信されたトピックである．

**mapトピック**
![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/ae7bccb5-b4fb-5236-b8f1-e8343480f868.png)
mapトピックは``nav_msgs/OccupancyGrid``型のメッセージで地図そのものに対応する．

**map_metaトピック**
![キャプチャ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/86c71cb4-099e-7308-9c98-7bd723521667.png)
map_metaトピックは``nav_msgs/MapMetaData``型のメッセージでYAMLファイルのデータに対応する．
次に示すのは，map_metaトピックが配信している内容である．
![キャプチャ5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/1cf6c5c1-e94d-d0c1-3dfc-ebcd100e339a.png)
確かにYAMLファイルあったデータと一致している部分があることが分かる．

なお，ここでは見にくかったため示していないが，mapトピックが配信している内容を``echo``により確認したところ，-1,0,1の数字で構成された画像データであった．地図そのものということで，たくさんの数字の羅列でうまく画像を切り取れなかったが，地図そのものに対応していることが文字通りであったと確認できた．

##rvizでの表示
以下では，地図をrvizで表示させる様子を，適宜画像を示しながら説明している．
**rvizの準備**
![キャプチャ6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/0af8dc74-46bb-29db-7a44-fbfe31cc9b16.png)
ここに，画像トピックを呼び込む．

**画像トピックの指定**
![キャプチャ7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/449f425d-0b4a-5ca0-b2cd-ad4eefd6b68a.png)

**画像の表示**
![キャプチャ8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/0c8c7c3f-c907-41db-239d-13e29024c449.png)
確かに画像が表示された．rviz空間は観る方向を自在に変えられるので，次に示すような俯瞰的な視点にもできる．
![キャプチャ9.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/c74d73d1-a59e-1c3b-d27c-77b5de152804.png)

##地図の編集
画像編集ファイルを使って，地図を編集することもできる．例えば，ロボットに通ってほしくない場所があった場合，そこを黒で塗りつぶしたり，通路をふさぐようにすると，擬似的な障害物としてロボットは判断してくれる．実際に障害物が無くても地図上ではあるということとできる．ここでは示さないが，本当にお絵かき感覚で黒や白で描けばいいらしい．

##感想
地図サーバを構築し，rvizでも表示できるようになり，いよいよロボットに地図を使わせる準備に入っており，これからの学習がますます楽しみである．また，最後に地図の編集について示したが，これもまたやってみたい．


##参考文献
プログラミングROS Pythonによるロボットアプリケーション開発
　　　　　　　　Morgan Quigley, Brian Gerkey, William D.Smart 著
　　　　　　　　　　　　　　　　　　　　　　　河田　卓志　監訳
　　　　　　　　　　  　松田　晃一，福地　正樹，由谷　哲夫　訳
　　　　　　　　　　　　　　　　　　オイラリー・ジャパン　発行
RailsのViewでのERB閉じタグ忘れエラーメッセージ

通常Railsでのエラーであれば
【１】
![スクリーンショット 2021-03-07 16.09.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/2b6e9de7-8c47-ac08-52b6-5bab09e345a2.png)
のような画面が通常ですが、

今日はこんなエラー画面でした。
【２】
![スクリーンショット 2021-03-07 16.12.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/864247e9-d87d-45c5-0fa7-b6a51e1dc59b.png)

見たこともないので少し焦りましたが、調べていくと
Ruby上でのエラーは【１】の形式で表示されるのですが
された HTML機能で発生したエラーです。Ruby及びRailsでのエラーとは違うメッセージを表示する仕様のようです。

ちなみにその時のコードは次のように記述しておりました。

エラー発生時のコードは以下に記述しました。

```ruby
<div>
  <%= render partial: 'message', collection: @messages
</div>
```

ちなみに正解のコードは以下に記述しました。

```ruby
<div>
  <%= render partial: 'message', collection: @messages %>
</div>
```

単純なミスでした。
【ReactNative】内部画像ファイルを動的に読み込む

# 環境
- React Native 0.63

# 問題
外部ネットワークからと同じ要領で `Image` コンポーネントの `source` に、パスを格納した変数を渡し、画像を読み込もうとするとエラーになる。

```tsx
<Image source={require(pathToImageFile)} />
```

# 解決方法
予め静的ファイル群を読み込んだオブジェクトを参照する。
なお、オブジェクトは階層化しない方が変数での読み込みが簡単にしやすい。

```ts:assets/images/index.ts
import { ImageSourcePropType } from 'react-native';

export enum imageNames {
  noImage = 'noImage',
  defaultProfileImage = 'defaultProfileImage',
}

export const images: { [key in imageNames]: ImageSourcePropType } = {
  noImage: require('./noImage.jpg'),
  defaultProfileImage: require('./defaultProfileImage.png'),
};

```

```tsx:動的に呼び出したいファイル.tsx
import { imageNames } from '@src/assets/images';

const Component: React.FC = () => (
  <Image source={imageNames.defaultProfileImage} />
);
```

# 参考記事
https://stackoverflow.com/questions/33907218/react-native-use-variable-for-image-file

# 編集後記
ReactNativeでは画像は外部ソースから読み込むことが多いし、内部に置いている画像はロゴなど数少ないので、動的に読み込む機会が少ない。
思いのほか躓いた部分だった。
【monaca】nend広告をタップできない（何も起こらない）時の解決方法

monacaアプリにnend広告を実装しても、広告はちゃんと表示できるのに広告をタップしても何も反応しないことがあります。原因は、広告のロードにタイムラグがあるからです。タイムラグがあったらなぜ反応しないのかは僕の知識ではよくわかりませんが、とにかく原因はそれです。

解決方法を探していたら次の記事を見つけ、これで解決することができました。

https://ja.stackoverflow.com/questions/5969/monacaでnend広告を別ウインドウで開く方法

ただ、この記事は2015年に書かれたもので、このままではちゃんと動かないので少し修正を加えて以下のようにしました。これをheadに挿入すると広告をタップできるようになります。

````Javascript

         addEventListener('load', onLoad, false);
      function onLoad() {
                //nendの広告タグのロードにラグがあるので、決め打ちで処理を遅延させています。
                var TIME_FOR_WAITING_NEND_AD = 500;
    
                setTimeout(function () {
    
                    var nendAdSpace = document.querySelector('div[id^=nend_adspace]');
                    var nendAdAnchors = nendAdSpace.querySelectorAll('a');
    
                    for (var i = 0; i < nendAdAnchors.length; i++) {
                        var hrefShelter = nendAdAnchors[i].href;
                        nendAdAnchors[i].removeAttribute('href');
                        nendAdAnchors[i].addEventListener('click', function () {
                           cordova.InAppBrowser.open(hrefShelter, "_system", 'location=yes');
                        }, false);
                    }                
    
                }, TIME_FOR_WAITING_NEND_AD);
            }

````

<code> cordova.InAppBrowser.open(hrefShelter, "_system", 'location=yes');</code>によって広告がSafariで開くようになっています。InAppBrowserプラグインを有効にしておいてください。



#ちょこっと宣伝

monacaでアプリ作ってます

オナ禁アプリ↓
![kinyoku-100px-icon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1159193/e4e3ef0f-f893-59bd-540b-d3c09d83e2ae.png)
[禁欲エボリューション](https://apps.apple.com/jp/app/禁欲エボリューション/id1553966013)


レポート用メモアプリ↓
![mem-100px-icon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1159193/c4b778ff-7a14-b489-c71e-23fe6f6b7eb8.png)
[文字数制限メモ](https://apps.apple.com/jp/app/文字数制限メモ/id1552651234)
[小ネタ]VSCodeのデフォルトファイルをmarkdownにする方法

# はじめに
markdownで記事やメモやPRを作る際に、VSCodeを用いると、たくさんの拡張機能([参考](https://qiita.com/sola-msr/items/cfe448db958da3d08863#excel-to-markdown-table))が使えてめちゃめちゃ便利です。
そこで、VSCodeのデフォルトをmarkdownに変更する方法をシェアします。

# 動作環境
VSCode ver1.54

# 1. 設定を開く
Macだと`command + ,`/Windowsだと`Ctrl + ,`

# 2.default languageをmarkdownに設定する
`Files: Default Language`で検索し、`markdown`と記述

![スクリーンショット 2021-03-07 16.04.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595260/762843e5-2dbe-9645-2dfa-661256aa7a7f.png)
【Nuxt.js】TypeScript,asyncDataでnuxtjs/axiosを使う

Nuxt.jsでaxiosを使う際に用途によって使い方が異なるのでそれぞれのやり方をまとめました。

1. vueファイルで使う
2. TypeScriptで使う
3. asyncDataで使う

APIはテスト用の[JSONPlaceholder](https://jsonplaceholder.typicode.com/)を使います

※今回はaxiosの使い方のみ書いていくのでエラーハンドリングは省略しております

## 1.vueで$axiosを使う

プロジェクト立ち上げ時にaxiosを導入している場合はインストールとconfigファイルへの記述は不要です

```:npm
$ npm install @nuxtjs/axios
```
```:yarn
$ yarn add @nuxtjs/axios
```

```nuxt.config.js
export default {
  modules: ['@nuxtjs/axios']
}
```
これでNuxt.jsのvueファイルで`this.$axios`が使えるようになります


```index.vue
<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  async created(){
    const ALBUM_API = "https://jsonplaceholder.typicode.com/albums"
    const albums = await this.$axios.$get(ALBUM_API)
    console.log("createdでALBUM_APIをGET:",albums);
  }
})
</script>
```


## TypeScriptで$axiosを使う
こちらの設定もプロジェクト作成時にaxiosを入れていればconfigファイルに設定が既に書いてあるはずです。

```tsconfig.json
{
  "compilerOptions": {
    "types": [
      "@nuxt/types",
      "@nuxtjs/axios"
    ]
  }
}
```

ここからtsファイルで使用するためにaxiosの設定ファイルを作成しPlaginsで読み込んで使います

`@nuxtjs/axios`をplaginsで使用するためにexportする

```utils/api.ts
import { NuxtAxiosInstance } from '@nuxtjs/axios'

let $axios: NuxtAxiosInstance

export function initializeAxios(axiosInstance: NuxtAxiosInstance) {
  $axios = axiosInstance
}
   
export { $axios }
```
plaginsで`$axios`を読み込んでTSファイルで汎用的に使えるようにする

```plugins/axios-accessor.ts
import { Plugin } from '@nuxt/types';
import { initializeAxios } from '~/utils/api';

export const accessor: Plugin = ({ $axios }): void => {
  initializeAxios($axios);
};

export default accessor;
```
`nuxt.config.js`でplaginsの設定を反映する


```nuxt.config.js
  plugins: [
    '@/plugins/axios-accessor',
  ]
```

TSファイルで$axiosをインポートして使う

```user.ts
import { $axios } from "./utils/api"

export const getUser = async () => {
  const USER_API = "https://jsonplaceholder.typicode.com/users"

  const users = await $axios.$get(USER_API)

  return users
}
```
index.vueで読み込んだ関数を実行

```index.vue
<script lang="ts">
import Vue from 'vue'
import { getUser } from "@/user"

export default Vue.extend({
  async created(){
    const users = await getUser()
    console.log("createdでTSファイルのUSER_APIをGET:",users);
  }
})
</script>
```

## asyncDataで$axiosを使う
asyncDataはvueインスタンスが生成される前に実行されるので`this`が使えません。
ですが、引数で`context`を受け取れるのでそれを使って`$axios`を使うことができます。

詳しくは公式に図解で詳しく載っているのでこちらがわかりやすいです。
[コンテキストとヘルパー](https://ja.nuxtjs.org/docs/2.x/concepts/context-helpers)

```index.vue
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
  data(){
    return{
      posts:[],
    }
  },
//引数でcontextの中のappを分割代入で受け取る
  async asyncData({ app }){
    const POST_API = "https://jsonplaceholder.typicode.com/posts"
    const posts = await app.$axios.$get(POST_API)
    console.log("asyncDataでPOST_APIをGET",posts);
  
  return { posts }
  },
})
</script>
```
asyncDataでreturnした変数はdataプロパティと同名であればそこにセットされます。
画面の初期データの表示などに使えますね！


## 参考
[nuxt/axios](https://axios.nuxtjs.org/)
[Nuxt TypeScript](https://typescript.nuxtjs.org/ja)
[Nuxt](https://ja.nuxtjs.org/)
[Rails]routes.rbでのredirect

### シンプルアクセス制御

'api/v1/users/:id'にアクセスしたら'api/v1/users'にリダイレクトする。

```routes.rb
Rails.application.routes.draw do
  namespace 'api' do
    namespace 'v1' do
      get 'users', to: 'users#index'
      # get 'users/:id', to: 'users#show'
      get 'users/:id', to: redirect('api/v1/users')
    end
  end
end
```
Filter　Spring boot　共通処理

〜フィルタを使った実装の復習、学習記録用です。〜
###Filterとは
・フィルタは各コントローラーの前に共通して行いたい処理をまとめたクラス
・Spring Bootでは、web.xmlのような設定ファイルは不要で、コントローラやフィルタなどのクラスを実装し、アノテーションやBean定義を行なうだけで、容易にSpring Bootに追加したい機能（今回はフィルタ）を認識させることができます。
・クライアントからのリクエストおよびレスポンスに対して、リソース（サーブレット／JSP／HTMLなど）での処理の前および後に何らかの処理を行うオブジェクトの事です。
###Filterの実装
```filter.java
package com.hoge.app.filter

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.springframework.stereotype.Component;

@Component //コンポーネントアノテーションをつける
public class hogeFilter implements Filter {
　　@Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("Filterが実行されました");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }
}

```

[@Componentアノテーション]
(https://qiita.com/RitaChan/items/d3504332664379ec5450)

[Filterインターフェース](https://spring.pleiades.io/specifications/platform/8/apidocs/javax/servlet/filter　)
フィルターは、doFilter メソッドでフィルタリングを実行します。

・doFilterメソッド
Filterからオーバーライドされたメソッド
フィルタの対象となるリソースが呼び出されたときに実行されます。「FilterChain」は次のフィルタやリクエストの対象であるJSPページやサーブレットの処理を実行するのに使用されます。


・FilterChainインターフェース
どのサーブレットを呼び出そうとした時にこのフィルタが呼ばれ、このフィルタの次に呼び出すべきサーブレットは何かということを管理しています。フィルタの次に別のフィルタがさらに呼び出される場合もありますし、本来の目的のサーブレットが呼び出される場合もありますが、フィルタではあまり意識することなく、FilterChainインターフェースで定義されている"doFilter"メソッドを呼び出すだけで次のサーブレットへ処理を移してくれます。
フィルタ内の処理が終わった段階で"doFilter"メソッドを呼び出すことでフィルタとしての処理を終了します。
※FilterインターフェースとFilterChainインターフェースで同じ名前で定義されている"doFilter"メソッドをそれぞれ使うので注意

#####参考記事
https://qiita.com/NagaokaKenichi/items/630ce51bbe2b15589dd2

https://qiita.com/kazuki43zoo/items/757b557c05f548c6c5db

https://www.samuraiz.co.jp/adobeproduct/jrun/docs/jr4/docs/html/Programmers_Guide/filters3.html

https://www.techscore.com/tech/Java/JavaEE/Servlet/6/

https://www.javadrive.jp/servlet/filter/index3.html
railsでform_withの送信ボタンを画像で作りたい

現在学習しているプログラミングスクールの課題の中で、
表題の通り、フォームの送信ボタンに画像を設置するのに少し詰まりました。
## 解決したかったこと
railsのform_withを用いた入力フォームの送信ボタンに画像を設置したい
## 解決方法
image_submit_tag を用いる

参考資料
https://railsdoc.com/page/image_submit_tag

ビューファイルに以下の様に記述し、解決できました。

```erb
<%= form_with(url: search_items_path, local: true, method: :get, class: "search-form") do |form| %>
  <%= form.text_field :keyword, class: 'input-box', placeholder: 'キーワードから探す' %>
  <div class="search-button">
    <%= image_submit_tag("search.png", class: 'search-icon') %>
  </div>
<% end %>
```
【Laravel8】インストールからユーザー認証導入まで

Laravel初学者です。
以前[【Laravel】Dockerコンテナ内でのユーザー認証導入](https://qiita.com/mumucochimu/items/3d4ff8fa8fcb9826339f)でまとめた通りLaravelの導入からユーザー認証導入まで行ったのですが、もう一度きちんと学ぼうと思い公式ドキュメントを参考に勉強を始めました。


## 参考

[Laravel Document（ドキュメント）](https://readouble.com/laravel/8.x/ja/installation.html)

一番新しいLaravel8を勉強していきます。


## 前提

- Docker Desktopがインストールされていること
- MacOSで行っています


## 新規アプリケーション作成

公式の通りに行っただけなのですが、コマンドだけで新規アプリケーションが簡単に作成できます。

sample-appという新規アプリケーションを作成します。
ターミナルで以下コマンドを実行します。

```PHP:ターミナル
curl -s https://laravel.build/sample-app | bash
```

以下コマンドでsample-appのディレクトリに移動します。

```PHP:ターミナル
cd sample-app
```

以下コマンドで`Laravel Sail`を起動します。
アプリケーションコンテナがマシン上に構築されます。
私の場合10分弱くらいかかりました。

```PHP:ターミナル
./vendor/bin/sail up
```

成功すれば`http://localhost`にアクセスできるようになって、Laravelの初期画面が出るようになります。

この起動は最初は時間かかるのですが2回目以降は早いです。

2回目以降も起動コマンドは変わりません。

```PHP:ターミナル
./vendor/bin/sail up
```

バックグランドで起動するときは以下コマンドです。

```PHP:ターミナル
./vendor/bin/sail up -d
```

停止するときは`control + c`もしくは以下のコマンドです。

```PHP:ターミナル
./vendor/bin/sail up
```


## ユーザー認証導入

ドキュメントの[こちら](https://readouble.com/laravel/8.x/ja/starter-kits.html)のページを参考にしています。

`Laravel Breeze`という認証方法がシンプルで入門にはいいと書いてあったのでこちらを導入してみます。

先ほど作成した新規アプリケーションのディレクトリで以下のコマンドを順番に実行します。

```PHP:ターミナル
composer require laravel/breeze --dev

php artisan breeze:install

npm install

npm run dev
```

これだけで導入が完了します。

Laravel初期画面の右上に`Log in`と`Register`という文字が出てアクセスするとそれぞれの画面が出ます。

簡単！
CentOS6.10 に docker をインストールするまで (2021年版)

## kickstart で CentOS6.10をインストールする時のハマりポイント

* Escapeキーを押して`linux ks`
* kickstartでエラーになる場合、以下のようにbaseurlを修正するとよい。

```diff:kickstart.ks
- repo --name="CentOS"  --baseurl=cdrom:sr0 --cost=100
+ repo --name="CentOS"  --baseurl=file:///mnt/source/ --cost=100
```

## リポジトリをVaultに切り替え

```sh:vaultに切り替え
sed -i \
 -e "s/^mirrorlist=http:\/\/mirrorlist.centos.org/#mirrorlist=http:\/\/mirrorlist.centos.org/g" \
 -e "s/^#baseurl=http:\/\/mirror.centos.org/baseurl=http:\/\/vault.centos.org/g" \
 /etc/yum.repos.d/CentOS-Base.repo
```

## dockerのインストール

```sh:dockerのインストール
curl -o docker-engine-1.7.1-1.el6.x86_64.rpm \
  "https://get.docker.com/rpm/1.7.1/centos-6/RPMS/x86_64/docker-engine-1.7.1-1.el6.x86_64.rpm"

yum localinstall -y "docker-engine-1.7.1-1.el6.x86_64.rpm"
```


## dockerをOS起動時に起動

```sh
chkconfig docker on
# dockerグループに追加
usermod -aG docker $SUDO_USER
```

## docker-compose

```sh
# docker-compose 1.5.2 (CentOS6でサポートされている最終バージョン)
wget "https://github.com/docker/compose/releases/download/1.5.2/docker-compose-Linux-x86_64"
mv docker-compose-Linux-x86_64 /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
```

* reboot

## 起動確認

```sh
docker run -it --rm -p 8080:80 nginx:alpine
```

* http://ipアドレス:8080/
rails Controllerについてまとめてみた

初心者がController についてアウトプットをかねてまとめます。
＊訂正あれば是非お願い致します。

#Controller
Controllerの生成
Controller名は<font color="Red">モデルの複数形</font>
ex) `Messageモデルなら` `Messages`


```
rails g controller コントローラ名 --(オプションがあれば)
```
生成されるファイル↓（messagesの部分は例として）
`app/controllers/messages_controller.rb`
↓のようなの書き方をする

```
class MessagesController < ApplicationController
    def index
    end
  
    def show
    end
  
    def new
    end
  
    def create
    end
  
    def edit
    end
  
    def update
    end
  
    def destroy
    end
end

```
「net-ssh-cli」を使う

# 概要／背景
JewelCaseというちょっとしたDockerで動かすRailsアプリを作りました。
https://github.com/hakua-doublemoon/JewelCase
ここでDockerからホストにインストールされたVLCをCLI（SSH）で操作したかったのですが、net-sshだけだと難しかったのでこの`net-ssh-cli`を使いました。

# 詳細
## ドキュメントなど
https://rubygems.org/gems/net-ssh-cli/versions/1.6.0
https://www.rubydoc.info/gems/net-ssh-cli/1.6.0
最新が「`1.7.0 - February 01, 2021 `」で、割と継続的にメンテナンスされているようなのが、これを採用した理由の１つでもあります。

## 基本的な使いかたと特徴
``` app/models/VlcConsole.rb
        # ログインしてセッションを作る
        @session = Net::SSH.start('172.18.0.1', user, password: passwd)
        @cli = @session.cli(default_prompt: />|#{vlc_user}/)
        # コマンド実行する
        puts @cli.cmd("vlc --equalizer-bands \"3 2 1 0 1 2 3 4 5\" --equalizer-preamp 0")
```

ドキュメントにあるように、startはブロック（`begin - end`）で使うこともできます。が、このgemの特徴は`long living CLI sessions`であり、ブロックで区切るのはもったいないです。
実際、上記のコードで作った`@cli`は、このインスタンス変数を持つインスタンスが生きている限り（接続が切れない限り）使えます。`net-ssh`だけだとコンソールを開きっぱなしにするのはちょっと頭を使うと思いますが、`net-ssh-cli`だと簡単です。

## 注意点
`net-ssh-cli`も完璧ではないです。

### コマンドを打ったあとに応答がすぐ得られない場合がある
上のコードのように、基本的には`cmd`の応答でコマンドの結果を得られますが、確実ではないです。コマンドによっては応答を受け取れず、自分のコードが予期せぬ動作に入る場合があります。
そこで下記のように対応します。

``` app/models/VlcConsole.rb
        @cli.write(cmd + "\n")
        2.times do
            sleep 0.2
            puts @cli.read
        end
```

`write`メソッドでコマンドの実行だけ行い、出力は`read`で得ます。コマンド結果の受け取りに失敗するような場合は、writeとreadの間にsleepを入れたり、再度`read`をしてみたりします。
ここらへんの動作は場合によりけりな気がしますので、コードを試しに組んでから動作確認して考えるといいと思います。
なお、`read`の結果が複数行になる場合も、戻り値は改行文字で結合された文字列オブジェクトであり配列にはなりません。（これは`cmd`なども同じです）。
【Java】Enum(列挙型)の使い方

#Enum(列挙型)とは？
Enum(列挙型)とは、**``複数の定数をひとつにまとめておくことができる型``**のことで、
指定した種類の値のみ格納できます。

#定義方法
列挙型で定義する具体的な値を**`列挙子`**と呼び、カンマで区切って宣言します。

```java

アクセス修飾子 enum 列挙名 {列挙子1, 列挙子2, 列挙子3,・・・};
```

#使い方

```java

package animal;

enum Animals {
    DOG,
    CAT,
    TIGER,
}

public class Animal {
    public static void main(String[] args) {
    	animalName.outputAnimalName(Animals.TIGER);
    }
}

class animalName {
	static void outputAnimalName(Animals animal){
    	if(animal == Animals.DOG) {
    		System.out.println("イヌです");

    	}else if(animal == Animals.CAT) {
    		System.out.println("ネコです");

    	}else if (animal == Animals.TIGER){
    		System.out.println("トラです"); //-> トラです
    	}
	}
}

```

# 列挙型の定数に値を設定する方法

```java

package animal;

public enum Animals {
    DOG(1),
    CAT(2),
    TIGER(3);

    private int animalNum;

    private Animals(int num){
        this.animalNum = num;
    }

    public int getAnimalNumber(){
        return animalNum;
    }
}

public class Test1 {
    public static void main(String[] args) {

        System.out.println(Animals.DOG.getAnimalNumber()); // 1
        System.out.println(Animals.CAT.getAnimalNumber()); // 2
        System.out.println(Animals.TIGER.getAnimalNumber()); // 3
    }
}

```

#参照
[【Java 入門】Enum(列挙型)の使い方総まとめ
](https://www.sejuku.net/blog/14779)
PowerShellでAzure CLIをインストールする

## 1. 管理者権限でPowerShellを開く (Windowsキー + X, A)
もしくはDockerでもテストできます。

```console
> docker container run --rm -it mcr.microsoft.com/powershell pwsh
PowerShell 7.1.2
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

PS C:\>
```

## 2. Azure CLIをインストールする

```powershell:powershell
Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile .\AzureCLI.msi; Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet'; rm .\AzureCLI.msi
```

## 3. PATHを再読込する

```powershell:powershell
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
```

## 4. 確認

```powershell:powershell
PS C:\> az version
{
  "azure-cli": "2.20.0",
  "azure-cli-core": "2.20.0",
  "azure-cli-telemetry": "1.0.6",
  "extensions": {}
}
```

以上