OmniAICreator/Qiita-1.07M huggingface dataset:
Rails 検索ツイートを直接表示させる

# 概要

ツイート検索機能に加えて検索ツイートを以下のように直接表示させる
※クリック時に該当ツイートに直接飛ぶようにする。

![取得.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294345/d7237449-a629-9c88-8c3e-131f0b0b94b6.png)


Rails5.2.8使用

# 事前準備

・Twitter APIを取得(省略)

以下などを参考にしてください

https://wporz.com/twitterapi-apikey-accesstoken/

・Gemfileに必要な記述を追加

環境変数記述用に以下を
```
gem 'dotenv-rails'
```
twitterAPI使用のために以下を
```
gem 'twitter'
```
```
bundle install
```
```.env
TWITTER_API_KEY=取得したキーを入れてください
TWITTER_API_SECRET_KEY=取得したキーを入れてください
TWITTER_ACCESS_TOKEN=取得したキーを入れてください
TWITTER_ACCESS_SECRET_TOKEN=取得したキーを入れてください
```

# 記述

```config/routes.rb
get '/tweets/search' => 'tweets#search'
```
キーワード検索機能用にcontrollerファイルに以下記述

```app/controllers/tweets_controller.rb 
class TweetsController < ApplicationController
  def search
    client = Twitter::REST::Client.new do |config|
      # 事前準備で取得したキーのセット
      config.consumer_key        = ENV['TWITTER_API_KEY']
      config.consumer_secret     = ENV['TWITTER_API_SECRET_KEY']
      config.access_token        = ENV['TWITTER_ACCESS_TOKEN']
      config.access_token_secret = ENV['TWITTER_ACCESS_SECRET_TOKEN']
    end
    since_id = nil
    # 検索ワードが存在していたらツイートを取得
    if params[:keyword].present?
      # リツイートを除く、検索ワードにひっかかった最新10件のツイートを取得する
      @tweets = client.search(params[:keyword], count: 10, result_type: 'recent', exclude: 'retweets', since_id: since_id)
    end
  end
end
```
```app/views/tweets/search.html.erb
# ツイート検索部分
<%= form_tag('/tweets/search', method: :get) do %>
  <%= text_field_tag :tweet, nil,  id: "tweet_search", name: "keyword", required: true, placeholder: "キーワードを打ち込んでください", style: "width: 400px;"%>
  <button title="ツイート検索" type="submit" id ="button1">検索</button>
<% end %>

# 取得ツイート結果表示部分
<% if @tweets.present? %>
  <h2>"<%= params[:keyword] %>"の最新ツイート検索結果</h2>
  <% @tweets.first(10).each_with_index do |tweet, i| %>
    ツイート<%= i+1 %></br>
    <iframe frameborder="0" allowtransparency="true" allowfullscreen="true" src="https://platform.twitter.com/embed/Tweet.html?dnt=false&amp;id=<%= tweet.id %>"></iframe>
    <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
  <% end %>
<% end %>
```


「id=<= tweet.id %>」の部分をeachメソッドで回すことで
検索して取得した複数ツイートを直接表示させることができます。
controllerファイルにbinding.pryを埋め込んでインスタンス変数で取得したものの中身を調べたときに分かりますが 
「id」が各ツイートを識別するパラメータとなってます。
GASでDeepl APIを触ってみた

# やりたいこと
**gasでdeepl APIにリクエストを送り、英語を日本語に翻訳する。**
# どうやってやるか
- deepl無料版で登録する
- アカウントからkeyを入手
- gasでhttpリクエストを送る
# 全コード
```js
function deepl() {
 var headers = {
  "Content-type": "application/x-www-form-urlencoded" 
  };
  var API_KEY = "自分のアクセストークンを入力してください";

  var txt = "翻訳したいtextを入力してください"
  var data = {
     "auth_key": API_KEY,
      "text": txt,
      "source_lang": 'EN',//翻訳したい言語（この場合だったらEnglish）
      "target_lang": 'JA'//翻訳語の言語（この場合だったらJapanese）
  };
  //UrlFetchApp.fetch()の第二引数optionsの設定部分
  var options = {
    'method' : 'post',
    "headers" : headers,
    "payload" : data
  };

  var url1 = `https://api-free.deepl.com/v2/translate`;
  
  var response = UrlFetchApp.fetch(url1,options); //gas版http request パラメータあり
  var json=JSON.parse(response.getContentText());//これがJSON.parse（）メソッド
  var responseText = json['translations'][0]['text'];//textだけ出力
  console.log(responseText)//確認
}
```
# 参考記事
- **[APIキーの取得方法](https://qiita.com/rihok/items/962890b4b86ea052e54c)**

https://qiita.com/rihok/items/962890b4b86ea052e54c

# 感想
いつも大学の課題でお世話になっているdeeplがAPIを公開しているということで、触ってみました。プログラミング初心者の僕でも、すぐに出来たので、GoogleWorkSpaceとうまく使いこなせば、いろいろ出来そうな感じがしました。
新卒1年目の経歴　記録

# スキル
**担当業務**
・詳細設計
・製造
・単体テスト

**言語・フレームワーク**
・Python　
　└Django
・C#

**DB**
・SQLite

**ネットワーク、クラウド等**
・Git


# 職務内容
**2021年7月～2021年12月 データ解析**
・データセット生成処理、解析処理の詳細設計作成
・データセット生成処理、解析処理プログラム実装
・テスト項目書作成
・単体試験プログラム作成とカバレッジ向上
・解析の精度向上を目的とした既存と改修後の比較、考察

**2022年1月～2022年3月　AR開発**
・Unity上でAR画面作成
・画面遷移プログラム実装
・テスト項目書作成
・単体テスト実施

**2022年4月～2022年5月　AI開発**
・学習データの前処理プログラム実装
・学習データの前処理検討
・AI学習、評価、推論実施
・推論結果の考察、識別率向上検討
requirements.txtで複数の環境でバージョンを統一する

# 概要
Pythonで開発する際、インストールするパッケージのバージョンは、開発環境と本番環境で統一することがオススメされている。
バージョンを統一することで、各環境で動作が同じになり、「開発環境では問題なく動作していたが、本番環境では不具合が発生した」といったトラブルが防げます。
pipではパッケージ名とバージョン番号を指定したテキストファイルを用意することで、バージョンを統一できます。
テキストファイルの名前はrequirements.txtがよく使われます。

# 手順
requirements.txtを作成するには下記コマンドを実行します。
```
pip3 freeze > requirements.txt
```

# 編集
ターミナルで編集する時は下記コマンドを実行します。
```
cat requirements.txt
```

エディタで編集することもできます。

# requirements.txtの書き方例
```
# 先頭に"#"を入れた行はコメントになる
# 行の途中でもスペースの後に"#"があると、"#"以降はコメントになる
foo==1.0.0 # "=="だと指定されたバージョンがインストールされる
bar<2.0.0,>=1.2.0 #　バージョンの範囲指定もできる
div # バージョン番号を指定しなければ、インストール実行時点での最新版がインストールされる
```

# 補足
requirements.txtを参照してパッケージをインストールするには下記コマンドを実行する
```
pip3 install -r requirements.txt
```
Unknown alias: default (Psych::BadAlias)でRailsが立ち上がらないとき

Rails6以降の立ち上げで`rails s`をしたとき

こんな感じで立ち上がらなかった
```
hogehoge sample_app4 % rails s
=> Booting Puma
=> Rails 7.0.3 application starting in development 
=> Run `bin/rails server --help` for more startup options
Exiting
/Users/hogehoge/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:430:in `visit_Psych_Nodes_Alias': Unknown alias: default (Psych::BadAlias)
        from /Users/hogehoge/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/visitor.rb:30:in `visit'
        from /Users/hogehoge/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/visitor.rb:6:in `accept'
        from /Users/hogehoge/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:35:in `accept'
---
```


`Unknown alias: default (Psych::BadAlias)`を調べて見ると`psych`が必要みたいなので

```
gem 'psych', '~> 3.1'
```
を追加`bundel install`

無事に立ち上がりました。
BeanstalkでLaravelのシンボリックリンク設定を起動時に済ませたい

Beanstalkでは「.ebextensions」ディレクトリ配下に予め準備しておいたファイルをもとに、起動時に自動でコマンドを打ってくれます。

```config:set-timezone.config
# /.ebextensions/set-timezone.config

commands:
  set_time_zone:
    command: ln -f -s /usr/share/zoneinfo/Japan /etc/localtime
```

こんな感じ。

その勢いでLaravelのシンボリックリンク設定を自動化したかったんですが、そこで少し詰まったんで記事として書いておきます。

# うまく行かなかったケース

最初はこんな感じで記載していました。

```config:starage-link.config
# /.ebextensions/starage-link.config
# シンボリックリンクを作成

container_commands:
　　storage_link:
　　　　command: "php artisan storage:link"
```

いざデプロイしてみるとエラーは特に発生しなかったんですが、うまくリンクができていませんでした。

なんでや！と思ってサーバーの中見てたんですが、存在しない絶対パスをリンク先として参照しており、それで上手くいっていなかった模様…

色々調べましたが「php artisan storage:link」でシンボリックリンクを作る方法はBeanstalkでは適していないようです。

[過去に似た内容で質問されている方もいました](https://stackoverflow.com/questions/52288807/php-artisan-storagelink-linking-wrong-directory)


# うまく行ったケース
Linuxのlnコマンドを使うと解決しました。

```config:set-timezone.config
# /.ebextensions/starage-link.config
# シンボリックリンクを作成

container_commands:
　　storage_link:
　　　　command: "ln -s ../storage/app/public public/storage"
```

-s オプションをつけることでシンボリックリンクを作ることができます。
これで上手くいきました！

BeanstalkはPaaSとして結構便利だと思ってるんですが、時よりこんな感じで詰まることがあります…
いい加減ECS辺りにお引越しさせようかと悩んでいるところです。
俺「MVC型のフレームワークってなんやねん」

分かりやすさ優先で書いてるから表現が正しくない箇所めちゃあるで、ゴメンやで🙏

# MVCフレームワークの簡単な説明

「どの役割はどこに書く」ってルールが決まってるタイプのソフトウェアのことだよ。

ソースコードを書くときに「一定のルールを作って皆んなでそれを守りながら書いたらめっちゃ開発ラクじゃん！？？」って感じ。

# 地のソースコードのとき

MVCみたいなフレームワークが登場する前のお話。

一般的なWebサイトってサイトにアクセスすると、そのサイトの表示に必要なデータをDBから引っ張ってきて、それをいい感じにHTMLの中に組み込んでそれを最後に表示する流れが大半。

これを（例えばPHPで）ベタ書きすると以下みたいになる。

1. DBとのやりとり
1. それの描画

の処理が同じファイルに書かれている。

```index.php
<?php
// ここでDBとやり取りする
$query = "SELECT * FROM users WHERE email = :email LIMIT 1";
$stmt = $dbh->prepare($query);
// 以下にまだDBとのやりとりが続く
$user = $stmt->fetch(PDO::FETCH_ASSOC);
?>
<head>
<!-- ここに諸々の設定 --->
</head>
<body>
    <h1><?= $user['name']; ?>さん、こんにちは。</h1>
    <div>
        <p><?= $user['name']; ?>さんの記事一覧は<a href="https://~~~.com/articles.php">こちら</a>から。</p>
    </div>
</body>
```

# どこに何がかいてあるんやっけ？

コードの量やファイルの数が少ないうちはあまり気にならない（処理が目視で追える程度の量）。

でも段々とコード量やファイル数が増えてくるにつれて、どこにどんな処理が書いてあるのか「ルールがないから」めちゃ分かりづらくなる。

しかも「書き方のルールがない」からほかのエンジニアと一緒に作業したときに、人によってコードの書き方がバラバラになる可能性がある。

> A氏「ページの表示に必要な処理は1枚のファイルに書いた方がスッキリするでやんすから、ワイはPHPの処理はファイルの上側に、HTMLはファイルの下側に寄せて書く派でやんす🤓」

> B氏「結局最後はHTMLに変換されるでやんすから、ワイは先にHTMLをガシガシ書いていって、必要になったら要所要所でPHPを書く派でやんす🤓」

> C氏「異なる言語が1枚のファイルに混在するのは嫌いでやんすから、ワイはHTMLとPHPはファイルごと分けてrequireで読み込む派でやんす🤓」

この3人が同じWebアプリを担当するってなったら、手戻りの連発や異なる文化による軋轢が生まれるのは必至でやんす（あ、もう「やんす」じゃなくていいか）。

# MVCが登場したら管理がラクになったよ！

そこでこれらの問題を解決するために生まれたのが「MVC型フレームワーク」ってこと。

# ちょっとだけMVCの解説

Model、View、Controllerの頭文字を取って「MVC」と呼ばれてるよ💡。

- **Model**はデータを操作できる
   - データベースとやり取りしてくれる。DB屋さんと思ってもらってOK。
-  **View**でサイトの描画できる
   -  HTMLとやりとりしてくれる。HTML屋さんと思ってもらってOK。
-  **Controller**は両者を仲介する
   -  ModelとViewとの間に入って仲介してくれる。仲介業者と思ってもらってOK。

# これらの処理を書く場所を決めようZE☆

今までは皆んなが思い思いの場所ややり方で書いてたのを「ちょ、一旦共通のルールで書きませんか？🤴」って導入された。

DBとのやり取りが含まれる処理はModelが担当して、Model内に全部書く。

最後の描画系のコードはViewが担当して、View内に全部書く。

どのページにアクセスされたときに「どのModelを呼び出して、どのViewを返すか」みたいな仲介の役割はControllerに全部書く。

こうすることで同じWebアプリを複数人が開発するってなっても、皆んなが共通のルールで気持ちよく開発できるね！😌

# 余談

🤓の気持ちに入りすぎて、🤓のセリフ終わってるのに間違えて語尾に「やんす」って続けちゃった😂
ファイル属性を変更して、ファイルを削除できないようにする

## 環境
Ubuntu20.4

## はじめに
rmをして、思わず、必要なファイルを削除してしまった経験はないだろうか。そのような事故を未然に防止するために、ファイル属性を変更して対応することができます。ファイルを削除しようとしても、削除できないようにするためのファイル属性があり、その設定を変更して対応することができます。

ファイル属性を確認するコマンドは、**lsattrコマンド**です。そして、ファイル属性を変更するコマンドは、**chattrコマンド**です。２つのコマンドを実行して、動作を確認してみましょう。

## やったこと

空ファイルを作成します。
```
touch test.txt
```

作成した、test.txtのファイル属性を確認します。デフォルトではこのように表示されます。削除できない属性は設定されていない状態です。
```
lsattr test.txt
--------------e----- test.txt
```

test.txtを削除できないファイル属性に変更します。変更は管理者権限でないと変更できません。
```
sudo chattr +i test.txt
```

このようにiが付きました。iが付くと、削除できないファイル属性になっていることを表しています。
```
lsattr test.txt
----i---------e----- test.txt
```

削除します。しかし、確かに削除ができません。
```
rm test.txt
rm: cannot remove 'test.txt': Operation not permitted
```

ファイルを削除できないファイル属性を取り除いて、元の状態に戻します。
```
sudo chattr -i test.txt
```

確かに、iの表示が消えました。
```
lsattr test.txt
--------------e----- test.txt
```

test.txtを削除しようとすると、削除されるようになりました。
```
rm test.txt
```

## 補足

lsattr、chattrは、e2fsprogsという、ext2/ext3/ext4ファイルシステムを操作できるユーティリティに含まれるコマンドです。上の記事で、ファイル属性という表現を使ったが、もう少し詳しくいえば、ファイルシステムのアトリビュート項目という言い方もできます。アトリビュートでiをたてれば、ルート権限でrmしても削除ができなくなります。
swift無料で学ぶとしたら、備忘

# 学習用の参考サイト

:::note info
まず、前段として

swift学びたいと思って、いろいろと検索してみると
よくわからない広告付きのプログラミング教室サイトみたいなのがひっかかります。
その中で独学は難しいから、スクール通いましょう、みたいなうたい文句もあったり。

で、そんな誘いには乗らず、何かないかな、とさらに検索をしてみて
これ無料なのに、すごいな、と思ったyoutubeサイトを見つけたので
備忘として、載せておきます。そこいらの有料商品よりも役に立つこと間違いなし。
:::


↓ この方のユーチューブチャンネルだけで、市販の本を買うよりも全然良いです。［2022/05/28、現在］
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2694206/b1c74aae-c60a-bf61-b58f-0b925b765b63.png)

> 参考サイト

https://www.youtube.com/watch?v=3v4OIds-OOg

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




以上
.NET MAUI と Visual Studio 2022 for Mac が正式リリースされたので試してみた

# はじめに

.NET MAUI と Visual Studio 2022 for Mac が正式リリースされました！

https://github.com/dotnet/maui/releases/tag/6.0.312

https://docs.microsoft.com/ja-jp/visualstudio/releases/2022/mac-release-notes#17.0.0

WindowsPCを使わず、MacBook Pro と Visual Studio 2022 for Mac で.NET MAUIのiOSアプリが作れるか試してみたので記録しておきます。（2022/5/28の時点の記録です）

# 環境

* MacBook Pro 2018
* macOS Monterey 12.3.1
* Xcode 13.3.1
* Visual Studio 2019 for Mac

# Visual Studio 2022 for Macのインストール

旧バージョンのVisual Studio 2019 for Macをインストールしていたのですが、アンインストールはせずにVisual Studio 2022 for Macをインストールしていきます。

以下のページからインストーラをダウンロードして実行します。
https://visualstudio.microsoft.com/ja/vs/mac/

インストーラーが起動した画面です。
旧バージョンを認識していますね。大丈夫そうなのでこのまま突き進みます。
![ScreenShot 2022-05-28 6.58.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/85c9ac2d-8caa-820d-ecfa-295bb8d5af11.png)

特に問題なくインストールできたので起動してみます。
![ScreenShot 2022-05-28 7.44.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/c34c1404-98c7-3b9e-d644-681f73976954.png)
ちゃんと「2022」になっていますね。

「+ 新規」を選択して新しいプロジェクトを作成してみます。
![ScreenShot 2022-05-28 7.45.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/884ffd54-4c5f-8b0f-5fd2-42ecbdd9f004.png)
.NET MAUIのテンプレートは無いです。

Windows版のVisual Studioには.NET MAUIのテンプレートはあるのですが、for Macはまだのようです。
https://docs.microsoft.com/ja-jp/dotnet/maui/get-started/first-app?pivots=devices-ios

# .NET MAUI プロジェクトを作成する。

テンプレートがないので、下記ドキュメントの手順でCLIから.NET MAUIプロジェクトを作成します。

https://docs.microsoft.com/ja-jp/dotnet/maui/ios/cli

手順通りの作業で、無事iOSシミュレータで.NET MAUIプロジェクトを実行できました。

# .NET MAUI プロジェクトを Visual Studio 2022 for Mac で開く

先ほど作成したプロジェクトのソリューションファイルを Visual Studio 2022 for Mac で開けばいけるんじゃね？ってことでやってみます。

まずは、躓いても元に戻せるようにgitのローカルリポジトリを作成してコミットしておきます。
.gitignoreは↓を使うで大丈夫。

https://github.com/dotnet/maui/blob/main/.gitignore

## ソリューションファイルを開く

では、.NET MAUI のソリューションファイルを開いてみます。
![ScreenShot 2022-05-28 8.55.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/d0100d9e-bca4-623d-44e9-79df00b1f7c1.png)

「.NET MAUIの開発は公式にサポートしてませんよー」と言っていますが、無事に開けました。

## デバッグ実行してみる

起動するデバイスをiOSシミュレータにして、実行ボタンをデバッグ実行してみます。
![ScreenShot 2022-05-28 11.40.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/73162d0d-f1cf-6a82-b39a-ae72760a5974.png)

動きました！

プロジェクト新規作成時点の動作はFlutterのプロジェクト新規作成時と同じで、ボタンをクリックするとクリックした回数が表示されます。

ブレークポイントはどうかな？
![ScreenShot 2022-05-28 9.01.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/eb0f6f95-720b-246d-4868-ee62728cbef6.png)
大丈夫ですね。

ホットリロードはどうかな？
![May-28-2022 12-06-28.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/4242afda-b7f1-7717-cc3a-ff57997ceeff.gif)
反映されました。
ソースを保存しなくても反映されます。
ボタンの追加はダメでした。

# 所感

簡単に動かしただけですが、旧バージョンと比べて良くなったなと感じた点は、

* Visual Studioの起動が速くなった。
* Gitウィンドウがまともになった。

といったところです。

Windows版にある「呼び出し階層を開く」は相変わらずありませんでした。残念！

ロードマップによると、現時点（2022/5/28)では、.NET MAUI用のテンプレート対応などは作業中の状態なので、今後に期待です！

https://docs.microsoft.com/ja-jp/visualstudio/productinfo/mac-roadmap
利用可能なAurora MySQLのエンジンバージョンの出力方法

## コマンド
```sh
aws rds describe-db-engine-versions \
  --engine aurora-mysql \
  --query 'DBEngineVersions[].EngineVersion'
```
※ 'aurora-mysql'を指定しているので、対象はMySQL5.7と8系になります。

## 結果
```json
[
    "5.7.12",
    "5.7.mysql_aurora.2.03.2",
    "5.7.mysql_aurora.2.03.3",
    "5.7.mysql_aurora.2.03.4",
    "5.7.mysql_aurora.2.04.0",
    "5.7.mysql_aurora.2.04.1",
    "5.7.mysql_aurora.2.04.2",
    "5.7.mysql_aurora.2.04.3",
    "5.7.mysql_aurora.2.04.4",
    "5.7.mysql_aurora.2.04.5",
    "5.7.mysql_aurora.2.04.6",
    "5.7.mysql_aurora.2.04.7",
    "5.7.mysql_aurora.2.04.8",
    "5.7.mysql_aurora.2.04.9",
    "5.7.mysql_aurora.2.05.0",
    "5.7.mysql_aurora.2.06.0",
    "5.7.mysql_aurora.2.07.0",
    "5.7.mysql_aurora.2.07.1",
    "5.7.mysql_aurora.2.07.1",
    "5.7.mysql_aurora.2.07.2",
    "5.7.mysql_aurora.2.07.3",
    "5.7.mysql_aurora.2.07.4",
    "5.7.mysql_aurora.2.07.5",
    "5.7.mysql_aurora.2.07.6",
    "5.7.mysql_aurora.2.07.7",
    "5.7.mysql_aurora.2.08.0",
    "5.7.mysql_aurora.2.08.1",
    "5.7.mysql_aurora.2.08.2",
    "5.7.mysql_aurora.2.08.3",
    "5.7.mysql_aurora.2.08.4",
    "5.7.mysql_aurora.2.09.0",
    "5.7.mysql_aurora.2.09.1",
    "5.7.mysql_aurora.2.09.2",
    "5.7.mysql_aurora.2.09.3",
    "5.7.mysql_aurora.2.10.0",
    "5.7.mysql_aurora.2.10.1",
    "5.7.mysql_aurora.2.10.2",
    "8.0.mysql_aurora.3.01.0",
    "8.0.mysql_aurora.3.01.1",
    "8.0.mysql_aurora.3.02.0"
]
```
React Iconsが正常に表示されているのにデプロイ時にエラーが出る件

Next.jsでページ作ってVercelでデプロイしようとしたら下記のようなエラーが表示された。

```
Type error: Cannot find module 'react-icons/Bs' or its corresponding type declarations.
```

該当箇所はこんな感じ。

```js
import { BsTwitter, BsInstagram } from "react-icons/Bs";
```

アイコンも正常に表示されているしどうしたものか…と思っていたら正しくは↓だった。最後は小文字らしい。

```js
import { BsTwitter, BsInstagram } from "react-icons/bs";
```
23歳フリーターが、ライブ会場の座席検索サービスを作ってみた

今回、ポートフォリオとして**ライブ会場の座席検索サービス**を作ったので、少し解説します。

# 目次

[1.作った経緯](#1-作った経緯)
[2.実際のページ](#2-実際のページ)
[3.使用技術](#3-使用技術)
[4.工夫した点](#4-工夫した点)
[5.苦労した点](#5-苦労した点)
[6.これからの課題](#6-これからの課題)

# 1. 作った経緯

僕はよくアーティストのライブに行くのですが、チケットの席番号を見て毎回思うことがありまして、**「自分の席の位置がよくわからない」** ということです。

**特にスタンド席などは、会場全体を囲むように色々な方向に席があり、なおかつ 2階,3階とフロアも分かれているので、会場内で迷ってしまうこともあると思います。**

そんな悩みを解決するために今回作ったのが、**ライブ会場の座席検索サービス**です。
意外とありそうで無いサービスだったので、**だったら作ってしまおう！！** ということで作ってみました。

# 2. 実際のページ

[ライブ座席検索](http://www.search-venue-seat.com:8080/venue/pia)

**チケットに記載の座席フロアと席番号を入力すると、自分の座席位置が点滅します。**
![親.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2267102/d363d2d0-0c7f-8d05-6e04-315f902e2a52.gif)

# 3. 使用技術

* *Vue.js 3.2.31*
* *PHP 8.1.3*
* *Laravel Framework 8.83.7*
* *Docker/docker-compose*


# 4. 工夫した点

目的は座席の検索なので、シンプルで見やすくしました。
**検索後の画面自動遷移や、
別の座席を検索する時に入力フォームが自動クリアされるような工夫はしました。**
特にこだわった部分は、
**実際に会場に入った時、思っていたよりステージが遠かった...とならないように、なるべく会場の広さが伝わるような見た目にしました。**

# 5. 苦労した点

* **検索機能**
今回作った会場が、キャパシティ12000人の大きな会場だったため、その中から検索された席番号の対応箇所を光らせるのは少し工夫が必要でした。
**各エリアに軸となる席番号をあらかじめ設定しておき、検索された番号に一番近いエリアが光るような仕組みにしました。**

* **座席表の作成**
なんだかんだでこれが一番大変でした。
HTMLとCSSを使い、実際の会場を再現しましたが、席の配置やエリア分けがとても地道な作業でした、、笑

# 6. これからの課題

* **座席から見た会場の写真**
やはりユーザーの方が一番気になるのは、ステージまでの距離だと思うので、
**実際の座席から見た会場の写真**なんかを載せられたら、イメージも湧きやすくとても良いなと思いました。

* **会場の追加**
まだ会場が一つだけなので、東京ドームや横浜アリーナなどの主要会場も追加していきたいです。

* **レスポンシブ、CSSの改善**
まだ端末によっては不十分な部分があるので、修正していきます。
Overview of Functional Safety Measures in AUTOSAR, No.664, AUTOSAR 21-11 (222) CP

Overview of Functional Safety Measures in AUTOSAR, No.664, 2021-11

https://www.autosar.org/fileadmin/standards/classic/21-11/AUTOSAR_EXP_FunctionalSafetyMeasures.pdf


AUTOSAR R21-11記事一覧はこちら。

AUTOSAR 21-11, 200文書読んだ。2022年5月に全部到達。

https://qiita.com/kaizen_nagoya/items/4043e8414f850ce266a4

AUTOSAR R21-11(0) 仕様ダウンロード一覧。単語帳。参考文献資料作成

https://qiita.com/kaizen_nagoya/items/9b3a1b9b8d1e8d7e288e

# 用語(terms)

|Term|Description|
|:--|:--|
|HARA |Hazard Analysis
|HAZOP |Hazard & Operability Analysis
|SEooC |Safety Element out of Context
|HTM|Hardware Test Manager
|HTMSS |Hardware Test Manager on Startup and Shutdown
|ASIL |Automotive Safety Integrity Level
|DMA| Direct Memory Access
|EMC |Electromagnetic Compatibility
|IOC |Inter-OS-Application Communicator
|CRC |Cyclic Redundancy Check
|TP |Transport Protocol
|BIST| Built In Self Test
|FTTI |Fault Tolerant Time Interval
|MSTP| Microcontroller Specific Test Package
## 英日単語帳
日本語は仮訳

T.B.D.

# 参考(reference)

[1] ISO 26262:2018 (all parts) - Road vehicles - Functional Safety http://www.iso.org
[2] Specification of Operating System
[3] Requirements on AUTOSAR Features
[4] Layered Software Architecture
[5] Specification of Watchdog Manager
[6] Specification of SW-C End-to-End Communication Protection Library
[7] Specification of Module E2E Transformer
[8] General Specification on Transformers
[9] Specification of ECU State Manager
[10] Specification of ECU State Manager with fixed state machine
[11] Functional Safety analysis of an exemplary system using AUTOSAR
[12] Specifications of Safety Extensions
[13] Specification of ECU Configuration
[14] Technical Safety Concept Status Report
[15] Explanation of Error Handling on Application Level
[16] Specification of Core Test
[17] Requirements on Core Test
[18] Specification of RAM Test
[19] Requirements on RAM Test
[20] Specification of Synchronized Time-Base Manager
JavaScriptのオプショナルチェーンを使ってオブジェクトの値にアクセスする。

# オプショナルチェ-ンとは

オプショナルチェーン演算子 (`?.`)を使うと、 オブジェクトの深い階層に存在するプロパティ・メソッドへのアクセスの際に、指定のプロパティが存在しない場合にエラーを吐かず、undefinedを返します。

これを使うことで、`keyA.keyB.keyC...`というようにオブジェクトチェーンで値を指定する時に、「keyBが存在しない場合にエラーを吐くな。。」といったことを気にせずかけます。


# どんな挙動をするのか
まずは、以下のようなオブジェクトを定義します。
こちらのプロパティにアクセスしつつ挙動を見ていきます。

```js
const obj = {
  test: {
    key: 'value',
  },
}
```

### 通常の記述で存在しないプロパティにアクセス

以下のようにプロパティにアクセスすると、正常に値が帰ります。

![スクリーンショット 2022-05-28 11.02.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681029/110b1205-3417-df13-fe12-a9bbd39daf5d.png)

しかし以下のように存在しない`obj.test2`にアクセスしようとすると、エラーが表示されます。
これは、`undefined`や`null`に対してプロパティを参照しようとするとエラーを吐くというJavaScriptの仕様によるものです。
![スクリーンショット 2022-05-28 11.02.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681029/31e29d54-fc65-b70e-8ded-f1d3f934a324.png)

### オプショナルチェーンを使うと

オプショナルチェーンを使うと`undefined`が帰ります。
![スクリーンショット 2022-05-28 11.16.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681029/e41b1966-b464-a541-bd0c-a7378d65b0fe.png)


## 何が良いか

ここまでを参考に、以下と同じような判定がされているということがわかります。
つまり、オプショナルチェーン演算子（`.?`）を使うことで以下のように存在の確認をする処理を書く必要がないことが良さと感じています。

```js
obj != null ? obj.test2 : undefined
```

# 関数にも（番外編）
まずは、以下のようなオブジェクトを定義します。

```js
const obj = {
  funcA: function () {
    console.log('func発火')
  },
}
```

`obj.funcB`なんて無い、とエラーが表示される。
![スクリーンショット 2022-05-28 11.42.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681029/b6d7828f-9c09-327f-b719-addd73b8def0.png)

オプショナルチェーンを使って`obj.funcB?.()`とすると、undefined。
![スクリーンショット 2022-05-28 11.42.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681029/f1ce72f6-d5ba-be00-a5d8-930bde4ad50d.png)

### 使いどころ
用途は外部APIを使う時に、それが存在するかどうかわからないような状況で使えそう。
→MDNに以下の記述がありました。
>存在しない可能性がある関数の呼び出しを試行するときに、オプショナルチェーンを使うことができます。これはたとえば、ユーザーの端末上で使えなかったり、実装が古かったりするために使えなかったりする可能性がある API を使うときに役立ちます。

## 参考文献

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Optional_chaining
Requirements on Watchdog Driver, No.197, AUTOSAR 21-11 (221) CP

Requirements on Watchdog Driver, No.197, 2021-11

https://www.autosar.org/fileadmin/standards/classic/21-11/AUTOSAR_SRS_WatchdogDriver.pdf


AUTOSAR R21-11記事一覧はこちら。

AUTOSAR 21-11, 200文書読んだ。2022年5月に全部到達。

https://qiita.com/kaizen_nagoya/items/4043e8414f850ce266a4

AUTOSAR R21-11(0) 仕様ダウンロード一覧。単語帳。参考文献資料作成

https://qiita.com/kaizen_nagoya/items/9b3a1b9b8d1e8d7e288e

# 用語(terms)

|Term|Description|
|:--|:--|
|CS| Chip select
|DIO |Digital Input Output
|ECU |Electric Control Unit
|EOL |End Of Line. Often used in the term ’EOL Programming’ or ’EOL
Configuration’
|HIS |Herstellerinitiative Software
|ICU| Interrupt Capture Unit
|MAL |Old name of Microconroller Abstraction Layer (replaced by MCAL because ’MAL’ is a french term meaning ’bad’)
|MCAL| Microconroller Abstraction Layer
|MCU |Microcontroller Unit
|MMU |Memory Management Unit
|Master |A device controlling other devices (slaves, see below)
|Slave |A device beeing completely controlled by a master device
|NMI |Non maskable interrupt
|OS| Operating System
|PLL |Phase Locked Loop
|PWM |Pulse Width Modulation
|RX |Reception (in the context of bus communication)
|SPAL |The name of this working group
|SFR| Special Function Register
|RTE| Runtime environment
|WP |Work Package
|STD| Standard
|REQ| Requirement
|UNINIT| Uninitialized (= not initialized)
## 英日単語帳
日本語は仮訳

T.B.D.

# 参考(reference)

[1] Standardization Template
AUTOSAR_TPS_StandardizationTemplate
[2] Glossary, AUTOSAR_TR_Glossary
https://www.autosar.org/fileadmin/standards/foundation/21-11/AUTOSAR_TR_Glossary.pdf
[3] Requirements on AUTOSAR Features
AUTOSAR_RS_Features
[Mac]キャプチャした.movを１コマンドで.gifに変換する

# 使い所

- タイトルの通りですが、Macのキャプチャ(⇧⌘5などから)で.mov形式の動画が作成できますが、それを.gif形式でほしいな〜というときに使ってみてください！
- 僕はGithubリポジトリのREADME.mdに表示するための.gifファイル作成に使ってます
- (ブラウザ上で.movアップロードし、.gif変換したものをダウンロードできるサイト様はいくつか見つかりましたが、知らないサーバーにアップロードしたりブラックボックスな変換処理が行われたファイルをダウンロードしたくないな〜と思い、今回は信頼性が高い(と思っている)ffmpegを使用した方法をとってます)

# 環境

|  | バージョン | memo |
| --- | --- | --- |
| macOS | 11.6.1(BigSur) |  |
| ffmpeg | 5.0.1 |  |
| シェル |  | zshを使用 |

# 作業手順

1. ffmpegをbrewでインストール
    
    ```php
    brew install ffmpeg
    ```
    
2. ~/.zshrc に下記コマンドを追記し保存
    1. 保存後は、 `source ~/.zshrc`で読み込ませるかターミナル自体を立ち上げ直しが必要
    
    ```
    # ffmpegによる変換
    ## .mov => .gif($1: 対象ファイルの絶対パス)
    movtogif() {
      filepath="$1" # ファイルパス
      dirpath=$(dirname ${filepath}) # パス部
      fileNameExcludeExtension=$(basename ${filepath} .mov) # 拡張子を削除したファイル名
      if [ ! -d ${dirpath}/output ]; then
        mkdir ${dirpath}/output
      fi
      outputFile=${dirpath}/output/${fileNameExcludeExtension}.gif
      ffmpeg -i ${filepath} -r 12 ${outputFile}
      open -a /Applications/Google\ Chrome.app ${outputFile}
    }
    ```
    
3. 変換したい.movファイルのフルパスを取得
    -  対象をFinder上で右クリック
    -  ⌥(オプション)を押すことで「コピー」の項目が「パスを取得する」に変わるのでこの方法がおすすめ
    
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490917/2677b244-8bb6-1110-a077-ccf3e0b03b46.png)

    
4. コマンドを叩く！
    
    ```
    movtogif "任意の.movフルパス"
    ```
    

これで変換対象のhoge.movファイルと同じディレクトリに `output/hoge.gif` が作成され、作成された.gifファイルがGoogleブラウザで表示されます！

# コマンド部分の解説

```
filepath="$1" # ファイルパス
```

コマンドの第一引数が `$1` で取れます。

```
dirpath=$(dirname ${filepath}) # パス部
```

`dirname` は渡した引数からパス部分を返してくれます。

```
fileNameExcludeExtension=$(basename ${filepath} .mov) # 拡張子を削除したファイル名

```

`basename` にファイルパスと除きたい文字列(ここでは”.mov”)を渡して拡張子を削除したファイル名を取得してます。

```
if [ ! -d ${dirpath}/output ]; then
  mkdir ${dirpath}/output
fi
```

output ディレクトリが存在しなければ `mkdir` で作成してます。

```
outputFile=${dirpath}/output/${fileNameExcludeExtension}.gif
```

出力ファイルパスを構築しています。拡張子は変換後の”.gif”。

```
ffmpeg -i ${filepath} -r 12 ${outputFile}
```

`ffmpeg` に `-i` で入力ファイルのパスを、 `-r` でフレームレートを設定し、.gitファイルを出力しています。

```
open -a /Applications/Google\ Chrome.app ${outputFile}
```

ここはGoogleをインストールしている前提ですが、Googleで出力した.gifファイルを開きます。
必要に応じて他のブラウザアプリに変更したりしてください。

# 締めの言葉

シェルコマンドの文法に慣れ親しんでいないので、こんな単純なコマンドでも結構時間がかかってしまいました。
回りくどい書き方をしていたり、何か考慮漏れなどありましたらぜひコメントいただきたいです。
結合テスト観点　殴り書き・・・

むしゃくしゃしてやった。
媒体はどこでもよかった。
反省している。

| 大項目| 小項目 |
|:--|:--|
| API | API正常系  |
| API   |  API境界値テスト　（戻り値は5桁、受け取る側の上限が4桁、など問題が無いかのチェック） |
|  API  |  APIフォーマットテスト（値の型、日本語カタカナ英数字、正常と異常（システムが受け取る予定の型と、APIが返す型が一致、異なる）） |
| DB|  値の型、日本語カタカナ英数字、正常と異常（DB受け取る予定の型と、システムが返す型が一致、異なる） |
| DB |  大量レコード数　例）１ユーザが何十万件のデータをシステムで抽出したときに、正常に処理できるか？|
| DB | 性能　例）１ユーザが何十万件のデータをシステムで抽出したときに、システム要件の5秒以内に正常に処理できるか？ |
| URL| データ変換XXボタンを押下したときに、ダッシュボードが表示できるか＝URLが正しいか。  |
|URL| データ変換XXボタンを押下したときに、URLパラメータを操作し、他人のデータ閲覧がされないか＝URLへの権限が正しいか。  |
| セッション管理| 本システムで登録したセッション情報を、本システムの関連システムで利用できるか。  |
| セッション管理  |  本システムで登録したセッション情報が有効期限切れになったとき、本システムの関連システムも有効期限切れでアクセス不可となるか。 |
iter()とnext()

リストやタプルから１つずつ取り出す方法
for文とかでも書ける

リストやタプルをイテレータに変換
```
iter()
```

イテレータから一つずつ取り出す
```
next()
```

```
a = [1, 2, 3, 4]
a_iter = iter(a)

print(next(a_iter), next(a_iter), next(a_iter))
#1 2 3

a_next = next(a_iter)
print(a_next, a_next, a_next)
#1 1 1
```
Google Maps APIキーのHTTPリファラーを設定する

# 自分の状況
GoogleCloudPlatformに登録しAPIキーを作成しGoogleMapsAPIを使用したサイトを試しに作ってみた
ただHTTPリファラーなしでAPIキーの設定をしてしまったため後から設定をすることにした

- GoogleCloudPlatformにログイン

https://console.cloud.google.com/


- ヘッダーメニューのプロジェクト一覧リンクをクリックし、変更したいAPIキーのプロジェクトを選択する
![スクリーンショット 2022-05-28 11.17.38.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2532816/bf4c7143-5d1a-691e-0951-a418b710c734.jpeg)

- 左上ハンバーガーメニューから「APIとサービス」→「認証情報」選択
![スクリーンショット 2022-05-28 11.28.20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2532816/9d3452e2-f4ad-7542-5b16-7b82487222a1.jpeg)

- 認証情報画面にて変更したいAPIキーの「鍵を表示します」→「APIキーを編集」をクリック
![スクリーンショット 2022-05-28 11.33.04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2532816/879fabc3-7e0f-7c89-93ca-26b7ffd7e353.jpeg)

- APIキーを編集画面にて、「アプリケーションの制限」→「HTTP リファラー（ウェブサイト）」、「ウェブサイトの制限」→「項目を追加」クリック
![スクリーンショット 2022-05-28 11.40.02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2532816/b1d0fce4-d16e-abd6-c462-7a91180fedf0.jpeg)

- 「新しいアイテム」にGoogleMapsAPIを使用しているサイトURLに`*`を追加したものを入力し、「完了」
![スクリーンショット 2022-05-28 11.43.34.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2532816/ce47b631-acd2-36e6-a295-07815b6eb735.jpeg)

- 「APIの制限」は「キーを制限しない」のままで「保存」
![スクリーンショット 2022-05-28 11.47.31.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2532816/1289c29f-d8bd-076a-4369-da8cb54b5782.jpeg)
DeepNudeの学習済みファイルをBarracudaで使用するためにonnxファイルに変換する

# 環境
python3.7

# 概要
Unityの機械学習ライブラリであるBarracudaでDeepNudeの学習済みデータを使用するためにonnxファイルに変換します。

以下の関数をgan.py内にあるDeepModelクラスに追加します。
~~~python
	def export_onnx(self):
		self.netG.eval()
		
		batchSize = self.opt.batchSize
		imageChannel = self.opt.input_nc
		width = 512
		height = 512
		input = torch.randn(batchSize, imageChannel, width, height)
		checkpointPath = self.opt.checkpoints_dir
		basename_without_ext = os.path.splitext(os.path.basename(checkpointPath))[0]
		print(basename_without_ext)
		outputName = basename_without_ext + ".onnx"
		print(outputName)
		torch.onnx.export(
				self.netG,							# モデル
				input,								# モデルの入力
				outputName,						# ONNXファイル名
				export_params=True,			# 重みをONNXファイルに保存
				opset_version=9,				# ONNXのバージョン
				do_constant_folding=True,	# 最適化のために定数の折りたたみの実行
				input_names = ['X'],			# モデルの入力名
				output_names = ['Y'],		# モデルの出力名
				verbose=True						#変換中の詳細ログ
		)
~~~
run.py内の	model.initialize(opt)の後にmodel.export_onnx()を挿入して呼び出すとファイルに保存されます。

その学習済みデータ（水着部分を緑色にする）を使用してUnityで水玉コラージュを作成してみました。
詳しくはリンクを参照してください。
![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138534/55267bce-a95d-164e-27a9-00863a9fc310.png)


# 参照
https://github.com/zhengyima/DeepNude_NoWatermark_withModel
https://kenken5050.hatenablog.com/entry/2022/05/28/111144
dnsmap とは

## 勉強前イメージ

dnsのtreeが見えたりするのかな？

## 調査

### dnsmap とは

サブドメインの存在チェックを行うツールです。
DNSサーバはゾーンの転送が抑制されているのでサブドメインの情報を確認できません。
そこで辞書式にドメインを問い合わせてサブドメインを探すツールがdnsmapになります。
辞書式に問い合わせるのでアタックになるため第三者のサーバには使用しないでください。

しかし [フットプリンティング](https://qiita.com/miyuki_samitani/items/e8239518deed723a0f2f) で下調べを行う際に
使用されることがあります。

## 勉強後イメージ

総当りで無理やり引っ張ってくるって感じなのか・・・・
確かに攻撃として認識される。。

## 参考

- [特定ドメインのサブドメインを探る](https://one-it-thing.com/3935/)
SSMでリモートホストにPortForwardingする

# はじめに

下記アップデートにて、SSMのドキュメントでPortForwardingができるようになりました。
https://aws.amazon.com/jp/about-aws/whats-new/2022/05/aws-systems-manager-support-port-forwarding-remote-hosts-using-session-manager/

リンク先のドキュメントは何も書いてないに等しかったので、調査がてら試してみることにしました。
（尚、コンソールのセッションマネージャーやRunCommandからできたら楽だったのですが、現状はできない模様です）


# やりたいこと

今回はローカルPCからプライベートサブネット上のDocumentDBにログインしてみます。
```
【接続経路】
ローカルPC(WSL2)→EC2(AmazonLinux2)→DocumentDB(Port:27017)
```
※接続先がDocumentDBなのは今案件で使っていて試しやすかっただけで他意はないです（EC2やRDSでも可能です）
※そのせいでMongo-shellの実行環境を作る必要があって地味にめんどくさかったのは秘密


# 事前準備

PortForwarding用のEC2インスタンスを作成します。
基本デフォルト（キーペアもSGのインバウンドルールも不要）で問題ないですが、セッションマネージャーで接続ができることが前提なので「AmazonSSMManagedInstanceCore」権限のあるインスタンスプロファイル（IAMロール）をアタッチしてあれば良いです。

また、PortForwardingはSSMエージェントのバージョンが「3.1.1374.0以降」である必要があります。
尚、今日時点のAmazonLinux2のAMIにデフォルトで入っているエージェントは地味にバージョンが足りないので、利用する場合は手動アップデートが必要になります。
（昨日今日に追加された機能なので、そのうち更新されると思います）

※今日起動したインスタンスのSSMエージェントバージョン
```
# rpm -qa | grep -i ssm 
amazon-ssm-agent-3.1.1188.0-1.amzn2.x86_64
```
※バージョンアップ手順はこちら
https://docs.aws.amazon.com/systems-manager/latest/userguide/agent-install-al2.html
※更新後のバージョン
```
# rpm -qa | grep -i ssm 
amazon-ssm-agent-3.1.1446.0-1.x86_64
```


# 接続コマンド

SSMドキュメント名は「AWS-StartPortForwardingSessionToRemoteHost」です。
詳細はドキュメントの説明（SSMのコンソールから見れます）に譲りますが、パラメータにローカル/リモートのポートと転送先のホスト（今回はDocumentDBのエンドポイント）を設定すれば接続できます。

```
$ aws ssm start-session --target i-xxxxxxxxxxxx --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters 'portNumber=27017,localPortNumber=27017,host=docdb.cluster-abcdefghij.ap-northeast-1.docdb.amazonaws.com'

Starting session with SessionId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
Port 27017 opened for sessionId xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
Waiting for connections...
```

実行後、別画面でlocalhost宛てに接続すれば転送先にログインできます。
```
$ mongo --host localhost:27017 --username mongo
MongoDB shell version v4.4.14
Enter password: 
connecting to: mongodb://localhost:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("c5988ed1-5497-4e17-9138-16ae18b0b71e") }
MongoDB server version: 4.0.0

(※中略)

rs0:PRIMARY>
```


# 参考

WSL2でMongo-shellを使いたい場合、単にaptではインストールできないようです。
自分は下記サイトを参考にしました。
（DBが必要なわけではないのでmongodb-org-shellのみインストールしました）
https://www.lisz-works.com/entry/mongodb-wsl-ubuntu
SSHの作成に関するメモ

SSHキーの作り方は下記が参考になります。
[Gitサーバー - SSH 公開鍵の作成](https://git-scm.com/book/ja/v2/Git%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-SSH-%E5%85%AC%E9%96%8B%E9%8D%B5%E3%81%AE%E4%BD%9C%E6%88%90)
[GitHub に SSH で接続する](https://docs.github.com/ja/authentication/connecting-to-github-with-ssh)

### 公開鍵(id_rsa.pub) : 外部のサーバーなどに設置して、自分のPCから接続するための南京錠のこと。
### 秘密鍵(id_rsa) : 自分のPCから秘密鍵を利用して公開鍵が置いてるサーバーに接続することができる。
[公開鍵と秘密鍵の参考](https://qiita.com/aiandrox/items/98ad9b7551481d890916)


```
// 公開鍵と秘密鍵の作り方の一つ
ssh-keygen -t rsa -C "your_email@example.com ←登録したいメールアドレス"
```

> 「ssh-keygen」はSSH（Secure SHell）の公開鍵と秘密鍵を作成するコマンドです
[参考](https://atmarkit.itmedia.co.jp/ait/articles/1908/02/news015.htmlhttps://qiita.com/aiandrox/items/98ad9b7551481d890916)

`-tコマンド : 暗号形式の種類を選びます。`
色々種類はありますが`rsa`または`ed25519`を指定します。
sshで困った時の参考にするサイトは`rsa`でやっていることが多いので、私は`rsa`を選んでいます。初心者のうちはそれでいいかなと。

`-Cコマンド : 鍵にコメントを追加します。`
メールアドレスを登録することが多いですが、外部と接続する際にメールアドレスも打たなければいけないということが多々出てくる場合は登録しておくと便利だという認識です。
【GAS】プロパティストア・プロパティサービスを使ってみる

# はじめに
GASで以下のようなQiitaの集計botを作成したことがあります。
その際、QiitaAPIなどのトークンを使用する時、ソースに直書きしていました。

https://qiita.com/sasao3/items/cbc43a669a109c6aee38

しかし、こういった重要な情報をソースに直接書くのはよろしくないと思い、調べてみたところ「プロパティサービス」で保存するのがいいとのことだったのでプロパティサービスについて簡単にまとめます。

# プロパティサービス

>プロパティサービスを使用すると、 1つのスクリプト、スクリプトの1人のユーザー、またはアドオンが使用されている1つのドキュメントを対象とするキーと値のペアで単純なデータを保存できます。これは通常、開発者の構成またはユーザー設定を保存するために使用されます。プロパティがスクリプト間で共有されることはありません。

簡単に説明すると、プロパティストアと呼ばれるデータを保存する場所があり、プロパティサービスを使ってプロパティストアからデータをセットしたり取得したりできるといった内容。

全てのデータはキーと値のペア`文字列`として保存されます。
文字列ではないデータ型は自動的に文字列に変換されるとのことです。

## PropertiesServiceの3つのアクセス権
使用するメソッドによって、アクセス権が異なります。
なので用途にあったメソッドを使う必要があります。

- getScriptProperties()：スクリプト、アドオン、Webアプリの全てのユーザ
- getUserProperties()：スクリプト、アドオン、Webアプリの現在のユーザ
- getDocumentProperties()：開いているドキュメント内のアドオンの全てのユーザ

https://developers.google.com/apps-script/guides/properties?hl=en#comparison_of_property_stores

## データの登録
データの登録方法は、スクリプトから登録する方法と手動で登録する2パターンあります。

### スクリプトから登録する
ここでは、getUserProperties()のアクセス権限での例を記載します。
ストアに1つのkeyとvalueのペアを登録するには、`setProperty(key, value)`を使用します。

```js
//スクリプトの現在のユーザのみがアクセスできるプロパティストアオブジェクトを取得
var userProperties = PropertiesService.getUserProperties();

//setProperty()でkeyとvalueをセットします。
userProperties.setProperty('test', 'hogehoge');

//プロパティストアから取得
userProperties.getProperty('test'); //結果 hogehoge
```

もし複数のペアを一度に登録したい場合は、`setProperties(properties)`でできます。
引数は登録したいkeyと値を記述したオブジェクトです。

```js
var userProperties = PropertiesService.getUserProperties();
var newProperties = {nickname: 'Bob', region: 'US', language: 'EN'};
userProperties.setProperties(newProperties);
```

### 手動で登録する
GASのエディタから登録することができます。
※どうやら新しいエディタからではできないらしいので旧エディタにしてから行います。

旧エディタのファイル>プロジェクトのプロパティを開きます。
画像のように「スクリプトのプロパティ」タブで、行を追加しそこにプロパティ(key)、値（value）を記述して保存するだけです。

![スクリーンショット 2022-04-23 13.31.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/2c41d955-000e-f964-b01e-d41a65feb1f0.png)





# 参考
https://developers.google.com/apps-script/guides/properties?hl=en

https://developers.google.com/apps-script/reference/properties/properties-service#getUserProperties()
PowerVC Tips: PowerVC 2.0.2.1 でストレージ・テンプレートの閾値設定が外れていることがある

##### はじめに

PowerVC でストレージ・テンプレートで設定した内容が、作成したボリュームで設定が適用されていないことがあったので確認しました。


-----

##### 環境

PowerVC 2.0.2.1


-----

##### 事象確認


ストレージ・テンプレートの作成：

Thin Provisioning タイプのテンプレートの作成時に、閾値チェックを設定していますが...

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517421/58909f12-7251-3b97-df82-8cfd21d0100c.png)


作成後に確認すると、設定したはずの設定が外れていました。


![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517421/7227a3fb-0dcb-f772-bb94-7a4fc2194e97.png)

この状態でボリュームを作成すると、ストレージ上では warning 0% で解釈されます。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517421/83ed0098-a43f-119d-c613-6046d6ac1517.png)



-----
##### 回避策


・作成した対象のストレージ・テンプレートを再度編集し、閾値設定を入力して保存します。
・修正したストレージ・テンプレートが正しく設定されているか確認します。


(修正後のストレージ・テンプレートで正しく閾値の設定(80%)がコマンドに渡っていることを確認しています。)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517421/17923c9d-0030-62b3-cf10-f027a15bbd46.png)


-----

##### おわりに

当事象ではストレージ・テンプレートの設定が作成時に反映されていないことを確認しました。

ストレージ・テンプレートはたまにGUI表示で「あれ?」と思うことがあるので、当バージョンでは画面をリフレッシュしたり、設定がきちんと入っているかどうか確認することを留意しておいた方がよさそうです。




以上です。
フットプリンティング とは

## 勉強前イメージ

セキュリティ分野でー....
いろんなところに攻撃する的な？
足跡いっぱいつけていくぞーみたいな

## 調査

### フットプリンティング とは

サイバー攻撃を行う前に標的の弱点を下調べすることを指します。
攻撃手法を検討するために行われます。

### フットプリンティングの種類

- 受動的フットプリンティング

標的に接触せずに情報収集することを指します。
例えば、ドメイン名の登録情報を見たりwhois情報を確認したりします。

- 能動的フットプリンティング

標的に接触して情報収集することを指します。
何らかの方法でハッキングなどして情報を収集します。

### フットプリンティングで取得する情報

主に以下のような情報の取得を狙っています。

- 組織情報
- ネットワーク情報
- システム情報

この情報を元に脆弱性の特定などを行い、攻撃を仕掛けます。

## 勉強後イメージ

攻撃をする前に探るのか
結構攻撃って無差別にする的なイメージもあったけど
大きな企業？とか狙ってたらたしかに下調べも必要か。

## 参考

- [「フットプリンティング」とは](https://atmarkit.itmedia.co.jp/ait/articles/0401/01/news045.html)
- [フットプリンティング 【footprinting】](https://e-words.jp/w/%E3%83%95%E3%83%83%E3%83%88%E3%83%97%E3%83%AA%E3%83%B3%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0.html)
- [【CEHのお勉強】フットプリンティングって何？ WEB編](https://chikoblog.hatenablog.jp/entry/2020/12/23/182248)
Enterキー押下でForm内のButtonにonClickイベントが発生する

## 経緯

[Semantic UI React](https://react.semantic-ui.com/)でFormをよく使うのですが、EnterキーでButtonのonClickイベントが発生して困ったので、記録用に。

<details><summary>サンプルコード</summary><div>

```jsx
import React from 'react'
import { Form, Button } from 'semantic-ui-react'

const FormExample = () => (
  <Form>
    <Form.Group widths='equal'>
      <Form.Input label='First name'  />
      <Form.Input label='Middle Name' />
      <Form.Input label='Last Name' />
    </Form.Group>
    <Form.TextArea label="Note" />
    <Button icon="plus" onClick={() => console.log("Click!")} />
  </Form>
)

export default FormExample
```
</div></details>

## 対処法1:ButtonをFormの外に出す

サンプルコードみたいに一番下や一番上にある場合は出すのが簡単。

<details><summary>対処法1を適用すると...</summary><div>

```jsx
import React from 'react'
import { Form, Button } from 'semantic-ui-react'

const Solution1 = () => (
  <>
    <Form>
      <Form.Group widths='equal'>
        <Form.Input label='First name'  />
        <Form.Input label='Middle Name' />
        <Form.Input label='Last Name' />
      </Form.Group>
      <Form.TextArea label="Note" />
    </Form>
    <Button icon="plus" onClick={() => console.log("Click!")} />
  </>
)

export default Solution1
```
</div></details>

## 対処法2:Formを使わない

Formを使わず、InputやDropdownを使用する方法。
ただ、<code>\<Form.Input /></code>と<code>\<Input /></code>ではlabelの表示が異なるため、注意が必要です。

<details><summary>対処法2を適用すると...</summary><div>

```jsx
import React from 'react'
import { Input, Form, TextArea, Button } from 'semantic-ui-react'

const Solution2 = () => (
  <>
    <Input label='First name'  />
    <Input label='Middle Name' />
    <Input label='Last Name' />
    <Form>
      <TextArea label="Note" />
    </Form>
    <Button icon="plus" onClick={() => console.log("Click!")} />
  </>
)

export default Solution2
```
</div></details>

## 対処法3:Buttonにtype="button"を指定する

こちらの記事を参考にしました。
これが一番良い解決方法かなと思います。

https://qiita.com/mimoe/items/89b317be5e38bfbc44ee


<details><summary>対処法3を適用すると...</summary><div>

```jsx
import React from 'react'
import { Input, Form, TextArea, Button } from 'semantic-ui-react'

const Solution3 = () => (
  <Form>
    <Form.Group widths='equal'>
      <Form.Input label='First name'  />
      <Form.Input label='Middle Name' />
      <Form.Input label='Last Name' />
    </Form.Group>
    <Form.TextArea label="Note" />
    <Button icon="plus" onClick={() => console.log("Click!")} type="button" />
  </Form>
)

export default Solution3
```
</div></details>
俺「namespaceってなんやねん」

# ざっくり言うと

中身は全然違うけど名前が同じファイルは同じディレクトリに複数枚共存することはできない（めっちゃ当たり前やんけ）。

PHP（やLaravel）でも同様に、中身が別で名前が同じメソッドやプロパティは同じファイル内に共存することはできない。

これを解決するために使うのが「名前空間namespace」やで。

# 前提や問題点

例えば2人の「潤」という名前の人が同じ部屋にいたとする。

そこにスタッフが入ってきて「潤さん、出番です！」と言った。

当人も周りの人もどっちの「潤」さんが呼ばれたのか、これだけだと全く分からない状態が起きる（目線とかは一旦抜きにして）。

# 区別できるようにしたらええやん

これを解決するために、同じ部屋にいる2人の潤さんに苗字を導入しようと番組ディレクターが言い出す。

イケメンな方の潤さんには「松本」という苗字を与えて、面白い方の潤さんには「名倉」という苗字を与えよう！

これで番組スタッフも「松本潤さん、出番です！」と言えば、どっちの「潤」が呼ばれたかすぐに分かるし、石原さとみとの大事なキスシーンなのに面白い方の潤がキスしなくて済む。

:::note warn
名倉潤と石原さとみがキスするようなエラーは必ず防ぎたい
:::

プログラミングでも一緒で、中身や処理が全く別なのに名前が一緒なメソッドやプロパティが同じファイル内に共存することがある（requireとかで別のファイルを読み込んだり、useで別のクラスを読み込んだり）。

それを阻止するためにnamespaceを導入して「この2つのメソッドは名前が一緒だけど別物だよ！」と識別させることができる👍

# 余談

名前が重複している芸能人の件で、ほかにも「ひろゆき（eg. 宮迫博之、西村博之、矢部浩之などなど、、、）」も使ってみたかったなぁと。
model.fit エラー

model.fit(,)を起動させようとするけれども、エラーが出てしまう。そんなときの対策方法をこの記事で挙げる。

Ex）model.fitエラーの例　　　　　　　　　　　　　　　　
事前情報
　data0={　　　　　　
'MaxTemp': [33,33,34,34,35,35,34,32,28,35,33,28,32,33,35,30,29,32,34,35],
'NumOfCus':[382,324,338,317,341,360,339,329,218,402,342,205,368,351,304,294,275,336,384,368]
}
Ice_data=DataFrame(data0)
Ice_data






X=Ice_data.loc[:,'MaxTemp'].values　
Y=Ice_data['NumOfCus'].values
model.fit(X,Y)
print('RegCoef:',model.coef_)
print('Inter:',model.intercept_)
--------------------
これだとエラーが出てしまう。なぜだろうか？
その原因について探っていこう！


原因　数値が横ベクトルである　(n=np.array[33,33,34,・・・]
sklearnのfit()では、DataFrame型やnumpyの行列形式（縦ベクトル）のみを受け付けているので、横ベクトルは不可！


model.fitをうまく表示させる対策
①配列をベクトル表示にする。つまり、[[33,33,34,・・・]]　←二重[]を用いて、ベクトルにする。
②reshape(-1,1)を用いる。
今回のようなEx)場合を考えると

X=Ice_data.loc[:,'MaxTemp'].values
Y=Ice_data['NumOfCus'].values
★x=np.array(X).reshape(-1,1)←ベクトルに直している
---------------------
model.fit(x,Y)
print('RegCoef:',model.coef_)
print('Inter:',model.intercept_)
------------------
RegCoef: [17.6756487]
Inter: -249.14371257485038　　　

結果が出ました。
成功です！
this language feature is only supported for ECMASCRIPT6 mode or better 【Google Tag Manager】

Google Tag Manager でカスタムHTMLを作成していたとき、次のようなエラーに遭遇

>JavaScript Compiler Error Typeform Tag Error at line 3, character 5: This language feature is only supported for ECMASCRIPT6 mode or better: const declaration.

同様に、line4, 5, 6, 7, 11, 22 行目もエラーがあるらしい

書いていたコードは以下

```HTML
<script>
 function formatDate(dt) {
    const y = ('00'+ dt.getFullYear()).slice(-2);
    const m = ('00' + (dt.getMonth()+1)).slice(-2);
    const d = ('00' + dt.getDate()).slice(-2);
    const h = ('00' + dt.getHours()).slice(-2);
    const mm = ('00' + dt.getMinutes()).slice(-2);
    return (y  + m + d +  h  + mm);
 }
 nowDate = formatDate(new Date());
 const getAfbItem = `${nowDate}`;

if (!window.dtlpcvCvConf) {
  window.dtlpcvCvConf = [];
}
window.dtlpcvCvConf.push({
  siteId: "",
  commitData: {
    pid: "",
    amount: "",
    mid: "",
    u: `${getAfbItem}`, 
    t:"",
    cvinfo:"1.1.1"
    }
});
</script>
```

どうやらGTMはES6に対応していないとのこと :(

# 解決方法

以下の記事を参考に書き直しました

[JavaScript ES5以前とES6(ES2015)以降の違いについて](https://zenn.dev/lily_jenny/articles/3d1107b62b6c61)

* 変数の宣言`const`は対応していない
* [テンプレートリテラル](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)もES6から対応
* `${<variable>}`も`<variable>`のみで良い

書き直したコード↓
```HTML
<script>
 function formatDate(dt) {
    var y = ('00'+ dt.getFullYear()).slice(-2);
    var m = ('00' + (dt.getMonth()+1)).slice(-2);
    var d = ('00' + dt.getDate()).slice(-2);
    var h = ('00' + dt.getHours()).slice(-2);
    var mm = ('00' + dt.getMinutes()).slice(-2);
    return (y  + m + d +  h  + mm);
 }
 nowDate = formatDate(new Date());
 var getAfbItem = nowDate;

if (!window.dtlpcvCvConf) {
  window.dtlpcvCvConf = [];
}
window.dtlpcvCvConf.push({
  siteId: "",
  commitData: {
    pid: "",
    amount: "",
    mid: "",
    u: "getAfbItem", 
    t:"",
    cvinfo:"1.1.1"
    }
});
</script>
```

これでエラーは無くなりました

## 参考記事

* [GTM JavaScript Compiler Error ECMASCRIPT6](https://stackoverflow.com/questions/53302907/gtm-javascript-compiler-error-ecmascript6?rq=1)
* [Intercom ECMASCRIPT6 Tag Manager Error](https://stackoverflow.com/questions/48765570/intercom-ecmascript6-tag-manager-error?rq=1)
Jupyter Notebook上でkernelを追加したり削除したりする方法

# おおきな流れ
1. condaに仮想環境を作る
2. 仮想環境にパッケージインストール
3. ipykernelをインストール
4. jupyter notebookに1で作成した仮想環境を追加
5. 不必要なkernelを削除

## condaに仮想環境を作る
以下のコマンドで仮想環境を作成
*hogeの部分は好きな名前に変更してください。pythonのversionは適当に変更してください
```
conda create -n hoge python=3.7
```
仮想環境を作成されているか確認
```
conda info -e
```

## 仮想環境にパッケージインストール
作成した仮想環境をアクティベートする
```
conda activate hoge
```

例としてpytorchをインストール
```
conda install pytorch==1.8.0 torchvision==0.9.0 torchaudio==0.8.0 cudatoolkit=10.2 -c pytorch
```

pytorchがインストールされているかを確認
```
conda list
```

## ipykernelをインストール
作成した仮想環境にipykernelをインストールする
```
conda install -c anaconda ipykernel
```

## jupyter notebookに1で作成した仮想環境を追加
1で作成した仮想環境がアクティベートされている状態で以下のコマンドを実行
*hogehogeの部分は好きな名前に変更してください
```
ipython kernel install --user --name=hogehoge
```
jupyter notebookにkernelが追加されたか確認
```
jupyter kernelspec list
```

## 不必要なkernelを削除
以下のコマンドを実行
*hogehogeの部分は削除したいkernelの名前に変更
```
jupyter kernelspec uninstall hogehoge
```
【Tableau Data Saber挑戦記】2. 進捗と解説動画との差について


先日から【Tableau Data Saber挑戦記】としてこちらのブログをスタートいたしました。
前回の記事はこちら→[【Tableau Data Saber挑戦記】1. はじめます](https://qiita.com/hetare/items/d55a7dda34f3b0e9073b)

今回も進捗状況やこれからはじめる方に向けてお伝えしたいことなどを書いていきたいと思います。

# 進捗
- 進度
1. HandsOn - Fundamental　→クリア
3. HandsOn - Intermediate I　→挑戦中
5. HandsOn - Intermediate II　→挑戦中
8. HandsOn - Advanced I 　→挑戦中
9. HandsOn - Advanced II　→クリア
10. ZEN問答　→挑戦中（未提出）
- 学習時間
30時間/14日間

# これから始めようとする方に伝えたいこと
以前の記事でも書いたのですが、解説の動画があるのですが環境の差異で動画ではできるけど自分の環境ではできない、といったことが多々あります。
ですので、今回はOrd1のHandsOn - Fundamental のなかででてきたそういったことについて簡単に記述しておきたいと思います。

まず前提として環境について整理しておきます。
1. Tableau Desktop （Creatorライセンス）
2. Tableau Desktop （Explorerライセンス）（WEB)
3. Tableau Public APP版
4. Tableau Public WEB版

動画では 1. Tableau Desktop （Creator）のほうを使っています。
私は 3. Tableau Public APP版のほうを使っています。
それゆえ操作や機能面でできることに差があったりします。
Ord1のHandsOn - Fundamental の解説動画はこちら→[DATA Saber Boot Camp Week1 “HandsOn – Fundamental”](https://www.youtube.com/watch?v=vaDpfaL3-2M&list=PLR1ulf4cyh2lTnNKO1m3_VGgKRLczHOgO&index=10)


そして早速差が出てしまう問題についてですが下記になります。

- Q6
動画で説明がある「カスタム分割」機能はWeb、及びTableau Public(APP)で使えない。
私はPublic(APP)なのでカスタム分割ができなかったわけですが、その場合はsplit関数を対応するとのことです。（まだやってない）

- Q16
地域の地理的割り当てがWebでできない。
列に経度：行に地域を入れた後、以下作業を行うと都道府県が地図単位で色分けされます
国>地理的役割>国/地域を選択し、マークに詳細でドラッグ
都道府県>地理的役割>都道府県/州を選択肢、マークに色分けでドラッグ

- Q17
クラスタ分析はWebで使えない。
Creator/Public(AP)では利用可能。

という感じでいくつもこういったことが出てきます。
なのでもう最近はちょっと躓いたら、そのことをメモしておいてどんどん飛ばして進んでいっています。
それゆえ私の場合は、Vizはちゃんと作成できていないけど、動画を見て設問の解答を見て回答して…って感じで
Ord1と9はクリアになっている状況なのです。
あとで時間できたら復習しようということで先に進んで概観掴むことを優先してます。

# 今後について
技術試練もさることながら、この先はコミュニティ活動のほうに注力していきたいと思っています。
自分でVizを作成するというところは特に気になっていて、何か業務にも関わりそうなテーマで作っていけたらなと考えています。
あとこのブログのほうも続けていくので、知りたいこととかあればコメントいただけると嬉しいです。
また、今後の活動の励みになるのでよければLGTMもいただけたら更に嬉しいです!
文章の改行を反映してくれるsimple_format

通常、フォームのテキストエリアに文章を入力する際、改行を入れて入力したとしてもページに表示するときに何もしなければ改行が無視される。そのときに使えるのが「simple_format」という機能。
## 使い方
データを作成する際は通常どうりに改行を入れて作成すれば良い。
「simple_format」の出番は表示するとき
通常のテキストをそのまま表示する場合
```
= @task.body
```
と書くところ
```
= simple_form @task.body
```
とすればOK。これで作成時の改行が反映される。
## hオプションをつける
ユーザーが作成した文字列をそのまま表示する際は危険なscriptタグを入力され、XSSの危険があるため「hオプション」をつけて表示するのが良い。
```
= simple_format(h(@task.body))
```
これで危険なタグを文字列にエスケープすることができる。
pythonのcsv読み込みでズッこけた

（2022/05/28 追記）
よりスマートな方法、早速コメントいただきましてありがとうございます！
ぜひコメントまで含めて読んでいっていただけると幸いです！

# はじめに
久々にpythonでcsv読み書きしてどうのこうのするプログラム書いてたら、
デバッグで実際データ入れたときに思うように動かんすぎてズッこけたので備忘録です。
エクセルで作ったcsvファイル（CSV UTF-8(コンマ区切り)）を読み書きしようとしてオッ...となりました。

以下のような２行５列のデータが入ってるcsvファイルがあると思って以降のプログラム見てってください。
|１|2|3|4|5|
|:----:|:----:|:----:|:----:|:----:|
|<b>6</b>|<b>7</b>|<b>8</b>|<b>9</b>|<b>10</b>|

最初に私が書いたプログラムは以下です。

```python 
import csv
with open(filename) as f:
    reader = csv.reader(f)
    l = [row for row in reader]
print(l)

"""結果
[['\ufeff1', '2', '3', '4', '5'], ['6', '7', '8', '9', '10']]
""""
```

+ 読み込んだら頭に'\ufeff'ついてて焦った
+ そもそもcsv読み込みデフォルトは文字列読み込みだった
の二本立てです。


# 読み込んだら頭に'\ufeff'ついてて焦った
まず結果printしてみて、'\ufeff'...君誰！！！
実際にいろいろ書いて動かしてたプログラムでは、
[ invalid literal for int() with base 10: '\ufeff1' ]
ってエラーが出て止まってました。
int()に'\ufeff1'を入れようとしてしまってたために出たエラー。

'\ufeff'調べてみると、BOMというテキストの始まりを伝えるためのマークなんだそうです。
このBOMすっ飛ばして読み込めれば！ということなのですが、
これはエンコーディングを"utf-8-sig"に設定してあげればOKです。
```python 
import csv
with open(filename, encoding="utf-8-sig") as f:
    reader = csv.reader(f)
    l = [row for row in reader]
print(l)

"""結果
[['1', '2', '3', '4', '5'], ['6', '7', '8', '9', '10']]
""""
```

utf-8形式のファイルにはこのBOMがあるものとないものがあるんだそうでその辺も考慮必要そう。
[参考：Python Tips: Python で UTF-8 の BOM ありなしを見分けたい](https://www.lifewithpython.com/2017/10/python-detect-bom-in-utf8-file.html)



# そもそもデフォルトは文字列読み込みだった
今まで数値のcsvファイルをimport csvして読み込んだことなかったのか、すっかり失念しておりました。
読み込み結果、文字列じゃん...

結果使うときにintとかfloatとかに適宜直してもいいんですが、今回の実装では以下の縛りがあったので
+ 読み込み時にもうintやらfloatやらにしときたい
+ できるだけ標準ライブラリのみでやりたい

読み込む型設定して読み込みできたらいいよねーってことで関数作ってみました。

```python 
import csv

def open_csv(filename,mode): 
    with open(filename,encoding="utf-8-sig") as f:
        reader = csv.reader(f)
        l = [row for row in reader]
    if mode == "int": 
        l = [[int(y) for y in x ] for x in l]
    elif mode == "float": 
        l = [[float(y) for y in x ] for x in l]
    else: 
        pass
    return l  

arr = open_csv(filename,"str")
print(arr)
"""結果
[['1', '2', '3', '4', '5'], ['6', '7', '8', '9', '10']]
"""

arr = open_csv(filename,"int")
print(arr)
"""結果
[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
"""

arr = open_csv(filename,"float")
print(arr)
"""結果
[[1.0, 2.0, 3.0, 4.0, 5.0], [6.0, 7.0, 8.0, 9.0, 10.0]]
"""
``` 

いいかんじ！

# さいごに
無限に知らないこと湧いて出てくるので最近逆に面白くなってきましたプログラミング
もっとスマートなやり方あればぜひ教えてください！