OmniAICreator/Qiita-1.07M huggingface dataset:
数行で簡単　Pythonでwebサイトから情報取得

#初めに
こんにちは、rickyです。
今回はPythonのLibraryであるBeautifulSoup(以下bs4)を用いて簡単にWebサイトから情報を取得する方法(構文解析)をご紹介します。
この知識を利用すればニュースサイトから必要な情報だけを取得することができます。
この記事ではQiitaのURLからトレンドを所得してみます。
まずはソースコードからです。

#Qiitaからトレンド取得のソースコード

```Python
import requests
from bs4 import BeautifulSoup

url = "https://qiita.com/"
html = requests.get(url)

soup = BeautifulSoup(html.text, 'html.parser')

for trand in soup.find_all(class_="tr-Item_title"):
    print(trand.text)
```


#補足
はじめてbs4とrequestsを使う場合はpipでインストールしてください。

```
pip install bs4
pip install requests
```


#解説
1.まずは必要なライブラリをインポートしていきます。

2.次にURLの情報をrequests.get(url)で取得します。
このとき変数htmlをprintすると<Response [200]>という情報が出力されます。
Response 200はHTTPのレスポンスが成功したことを示しています。
html.textでHTMLファイルの内部の情報を取得できます。

3.次にbs4を使ってデータを取り出します。
textデータをparser(構文解析)にかけます。

4.今回はqiitaのトレンドを取得します。
そのための必要な情報を知るためにブラウザ開発者ツール(F12で開く)を開きます。
開発者ツールを使って欲しい情報のタグを見つけます。
![2020-11-27 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330568/d422877c-1dfe-5379-d02a-100fdfb2f2db.png)

今回はclassタグのtr-Item_titleという情報がよさそうです。
このタグの情報をfind_allですべて取得します。
ちなみにclassタグなのにclass_としているのはclassという単語がpythonの予約語であるためです。
for文を使って出力をします。
このときもtextを使うことでトレンドの内容だけを取得することができます。
これでqiitaのトレンドが取得できました。
お疲れさまでした。


#おわりに
今回はbs4を使って構文解析を行いました。
簡単にかけてしっかり情報を取得できるので非常に便利です。
ぜひこのプログラミングを応用していろいろな情報を取得してください。
この記事が読んで下さった方の役に立てば幸いです。


#参考URL
https://developer.mozilla.org/ja/docs/Web/HTTP/Status
http://kondou.com/BS4/
旧インスタグラムAPI廃止の影響及び新APIのポイント


2020年のインスタグラムAPIにおける大きな変更について、過去のブログ記事から抜粋してまとめました。
****
##2020年6月29日にインスタグラムAPIの何が変わるのか？

インスタグラムはこれまで使われてきた旧インスタグラムAPI（the Basic Permission for Instagram Legacy API）を2020年6月29日に廃止すると発表しています。これに備え以前から、新インスタグラムAPIとして、Instagram Graph API（ビジネス/クリエイターアカウントからのインサイト情報取得、ハッシュタグ等による投稿収集が可能）、Instagram Basic Display API（画像や動画など基本情報の収集が可能）が提供されており、これら新しいAPIへの切り替えを促しています。

もし皆さんがお使いのツールが旧インスタグラムAPIをベースに開発されたままだと、2020年6月30日以降、個人のインスタグラムアカウントからウェブサイトに埋め込んだ画像が表示されなくなるなどの不具合が起こってしまいます。

インスタグラムが最近発表した最も大きなAPIに関するニュースは、2019年10月にアナウンスされた、Instagram Basic Display API（基本表示API）の導入でした。これによって全てのツール（サードバーティアプリとプラグイン）が今までと同じようにインスタグラムと連携した機能を提供し続けるためには、基本表示APIのアクセス許可を取得することが必要になりました。

この導入に伴い、以下のような変更がありました。

　 * プライバシー保護のため画像に位置情報が含まれなくなる
　 * オーバーレイでのいいね！数とコメント表示はビジネスアカウントのみ可能に
　 * 位置情報やフォロワー数などのデータフィールドの情報は打ち切り
　 

##切り替わった2つの新APIの概要
切り替わった新API、Instagram Graph APIとInstagram Basic Display APIは、アクセスできるインスタグラムアカウントと、取得できるデータに違いがあります。

###Instagram Graph APIは詳細データの取得用
Instagram Graph APIは、ビジネスアカウントとクリエイターアカウントがサードパーティ開発のアプリによるアクセスを許可するためのAPIです。ハッシュタグやメンションのついた投稿の発見など、以下のようなアクションを可能にします。

　 * ビジネス/クリエイターアカウントの写真、動画、ストーリーズの取得と管理
　 * 他のビジネス/クリエイターアカウントに関する基本データの取得
　 * インサイトデータの取得
　 * ハッシュタグが付いたメディアの発見
　 * @メンションが付いたメディアの発見　など

###Instagram Basic Display APIは基本情報の取得用
Instagram Basic Display API（Instagram基本表示API）は、インスタグラムアカウントの基本的な情報（プロフィール情報、写真、動画、アルバム）を取得することが可能になります。
このAPIはすべてのアカウントにアクセス可能ですが、基本的な情報しか取得できません。またインスタグラムビジネスアカウントやクリエイターアカウントからインサイトデータなどを取得したい場合は、Instagram Graph APIを利用する必要があります。

###（補足）インスタグラムには3つのアカウントがある
インスタグラムには3つのアカウントタイプがあります。上記のようにAPIにも関係しているので、ここで一度整理しておきましょう。

■ビジネスアカウント
ビジネスアカウントでは、ストーリーズ、投稿、フォロワーに関するインサイトを利用することができ、インスタグラムをマーケティングツール活用するための機能が付与されます。
インスタグラムは近年広告やEコマースに関する新しい機能を相次いで公開していますが、それらの利用にはこのビジネスアカウントが必要なため、企業や個人事業主でビジネスを行っているユーザーはこのビジネスアカウントの利用が推奨されています。

■クリエイターアカウント
インスタグラムは、多くのフォロワーに影響を与えるいわゆる人物をプロアマ問わず「クリエイター」と呼んでいます。クリエイターアカウントに切り替えると、フォロワーの管理や数の推移を確認することができるようになったり、ビジネスアカウントとコラボレーションして投稿を広告としてインスタグラム上に表示できるブランドコラボという仕組みの利用が可能になったりします（一定数のフォロワー数がいるなどの制限があります）。

■個人用アカウント
上記二つのアカウントに該当しない一般ユーザーのアカウントです。基本的なプロフィール情報の表示や写真・動画の投稿が行えます。

##新APIへの切り替えが、インスタグラムウィジェットとプラグインのユーザーに与える影響
​​​​​​​2つの新APIのうち後に発表されたInstagram Basic Display APIの導入によって、個人用アカウントへ接続しているインスタグラム関連アプリやプラグインの多くが、インスタグラム側に再登録をする必要があります。

言い換えれば、開発者はインスタグラムからInstagram Basic Display APIを実装する許可を取得し、その後APIの要件に従い、必要な機能の調整を行うことが求められます。

つまり、許可を受けていないアプリやプラグインは、新APIに対応できないため、2020年6月30日以降正常に動作しなくなります。
**************

その他の情報はこちらの記事をご覧ください。

[2020年 旧Instagram API廃止の影響および新APIのポイントと対応策](https://embedsocial.jp/blog/instagram-api-changes-2020-2/)
Transformer(深層学習）とTransformers(タカラトミーとかの）が、融合しつつある。

#概要
例の**Attention is All xxxx**(2017)の**Transformer**が、ちょっと、**一般名詞過ぎて多少気になる**。
CNNみたいな名称にできなかったものか。
それとも、さらなる**Vision Transformer(ViT)**とかへの展開も想定して、自らは、短い名前にしたのか？？？

この記事の元のタイトルは、以下。
Transformer(深層学習）は、transformer(変圧器）から135年振りに単語を奪いとる気か？[息抜き]

#調査結果
以下の語源辞典で、transformerの動向を調べた。
https://www.etymonline.com/word/transformer

以下、そのページからの結果の引用。

>c. 1600, "one who or that which transforms," agent noun from transform (v.). Meaning "device to reduce electrical currents" is from 1882.


Google翻訳(ママ）
>c。 1600年、「変身する人または変身する人」、変身からの動作主名詞（v。）。 「電流を減らす装置」の意味は1882年からです。

⇒　**1882年から変圧器になっているよう。**

以下の図は、以下のWikiから引用。
https://en.wikipedia.org/wiki/Transformer

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/903c2838-77e3-17bf-161a-066d6f7f9f32.png)

そもそも、変圧器が独占し過ぎたとも言えるかも。


#Transformer(深層学習）とTransformers(タカラトミーとかの）が、融合しつつある。追記(2021/1/14)

以前、「余談」で、予想していたが。。。

以下、

PointTransformer

https://arxiv.org/pdf/2012.09164v1.pdf

から引用

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/e9c1f8a8-cc40-b618-97a4-8227e9edae62.png)

この論文は、以下のAI-SCHOLARの記事(2021/1/13)で、紹介されています。

https://ai-scholar.tech/articles/others/point%20transformer

#まとめ
特にありません。
ViTも含め、Transformerは、難しくて頭に簡単に入らないので、雑談でした。
コメントなどあればお願いします:candy:
この記事で役立つ情報は、**上記の語源のサイト、ここの正しさはよくわかっていないが、情報が詳細です、お薦めです。**

#余談
カタカナのトランスフォーマーは、余裕で、以下だと思うが。

図は、以下のWiki引用。
https://en.wikipedia.org/wiki/Transformers

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/9109d8ba-489e-bde0-a2c0-716f4a1b2188.png)

#関連（本人）

[画像認識、「Vision Transformer (ViT)」と「Visual Transformers」の比較](https://qiita.com/enoughspacefor/items/e41f5fe3a2febfabe3c3)

[自己注意Self-Attention の解説でわかりやすいと思った記事N選　(まだ、N＝5）](https://qiita.com/enoughspacefor/items/c9810d1065741a7f461c)
Dynamics 365 Finance and Operations トライアル版を試す

　Micorosft Dynamics 365 Finance and Operations のトライアル版を試す手順です。内容は 2020 年 11 月時点のもので、手順は変更になる可能性があります。試験的な操作を目的とする環境には、トライアル版の他に [Lifecycle Services （通称LCS）][101] からデプロイするデモ環境というものもあります。この記事で説明しているのは、デモ環境ではなく、トライアル版です。

- [Microsoft Docs - Try out Finance and Operations free for 30 days](https://docs.microsoft.com/dynamics365/fin-ops-core/fin-ops/get-started/before-you-buy#step-one-try-out-finance-and-operations-free-for-30-days)
- [Microsoft Docs - Deploy a demo environment](https://docs.microsoft.com/dynamics365/fin-ops-core/dev-itpro/deployment/deploy-demo-environment)

[101]: https://lcs.dynamics.com/v2

　支払情報の入力やソフトウェアのインストールは必要ありません。ただし、組織アカウント（職場または学校のメール アドレス）が必要です。個人用のメールアドレスで試みてもサインアップすることはできません。

## 1) Finance and Operations を選択して勤務先電子メールを入力する

　トライアル版のサインアップは [trials.dynamics.com][102] で **Finance and Operations** を選択し、勤務先電子メールと電話番号を入力するだけで、ほぼ完了です。メールアドレスは、実際に所属する組織のメールアドレスである必要はなく、試験用の組織アカウントでもトライアル版を試すことができます。ただし、この場合 Finance and Operations と Microsoft 365 との統合を試すことはできません。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58/c682d7c6-cf6f-ea95-3356-953cd2cb6662.png" width="700px">

　Dynamics の製品ページ [dynamics.microsoft.com][103] の [Finance][104] または [Supply Chain Management][105] にも無料試用版へのリンクがあります。

[102]: https://trials.dynamics.com/
[103]: https://dynamics.microsoft.com/
[104]: https://dynamics.microsoft.com/get-started/free-trial/?appname=finance
[105]: https://dynamics.microsoft.com/get-started/free-trial/?appname=SCM

## 2) プロビジョニングを15～30分ほど待つ

　ローディング画面にも記載があるとおり、準備ができるとリンクがメールで送られてきます。そのまま待っているとエラー画面が表示されることもありますが、用意されたリンクにアクセスして FO へサインインします。リンクは `https://trial-******.sandbox.operations.dynamics.com` という形になるようです

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58/c56d58b3-f83f-e3ad-c0c6-230ffd3a8c2c.png" width="700px">

　メールを確認できず、リンクがわからなくなってしまった場合、無料試用版の有効期間内であれば [trials.dynamics.com][102] から同じ手順をやりなおすとトライアル環境へアクセスすることができます

## 3) サインインする

　用意されたリンクにアクセスして FO へサインインします。英語の表示となっていますが、画面右上にある歯車のアイコン ⚙ のユーザーオプション／基本設定より、言語・数字の形式・タイムゾーンを日本語へ変更することができます

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58/84441b70-e43b-2111-9e0b-d95a009cc1db.png" width="700px">

　取得したトライアル版の情報は [Microsoft 365 admin center のサブスクリプション画面][106] で確認できるようです

## 参考リンク

- [Microsoft Learn - Finance and Operations 関連のラーニングパス][107]

[106]: https://admin.microsoft.com/Adminportal/Home?source=applauncher#/subscriptions
[107]: https://docs.microsoft.com/learn/browse/?expanded=dynamics-365&products=dynamics-finance%2Cdynamics-finance-operations%2Cdynamics-scm&resource_type=learning%20path
【Ruby ~条件分岐~】勉強メモ２

Rubyの復習。
ほぼ自分の勉強メモです。
過度な期待はしないでください。


変数展開
-
変数展開とは、変数を代入している値に置き換えて、文字列に含めること
書き方：`#{変数名}`

```.ruby:例
length = 9
width = 8
area = length * width

puts "面積は#{area}です"
```

```.text:出力結果
面積は72です
```

　
※変数展開の注意点
シングルクォーテーションを使った場合は、変数展開が行われず、
そのまま文字列として出力されてしまうので注意。

```.ruby:例
length = 9
width = 8
area = length * width

# シングルクォーテーションを使った場合
puts '面積は#{area}です'
```

```.text:出力結果
面積は#{area}です
```

<br>

条件分岐
-
条件分岐処理とは、条件を満たしているかどうかで実行内容を分岐する処理。
「もし〇〇だったら△△をする」と処理を分けることが出来る。

- 書き方は下記の通り

```.text:書き方
if 条件式
  処理
end
```

```.ruby:例
score = 92

if score > 80
  puts "値は正です"
end
```

```.text:出力結果
値は正です
```
　

- elseの書き方

ifにelseを組み合わせると「もし〇〇なら●●を行う、そうでなければ■■を行う」という処理が出来るようになる。

```.text:書き方
if 条件式
  # 条件式が真(true)のときに実行する処理
else
  # 条件式が偽(false)のときに実行する処理
end
```

```.ruby:例
score = 60

if score > 80
  puts "値は正です"
else
  puts "値は負です"
end
```

```.text:出力結果
値は負です
```
<br>

- elsif (条件を追加する)

ifとelseだけでなく、さらに条件を追加したい場合使用する。

```.text:書き方
if 条件式1
  # 条件式1が真(true)のときに実行する処理
elsif 条件式2
  # 条件式1が偽(false)のとき、かつ
  # 条件式2が真(true)のときに実行する処理
else
  # 条件式1と条件式2がどちらとも偽(false)のときに実行する処理
end
```

```.ruby:例
value = gets.to_i

if value > 0
  puts "値は正です"
elsif value < 0
  puts "値は負です"
else
  puts "値は0です"
end
```
　

- 条件を組み合わせ

-「かつ」
かつは、`「&&」`で表す。
「条件1 && 条件2」は「条件1かつ条件2」という意味で、複数の条件がすべてtrueならtrueになる。

<br>

-「または」
「または」は、`「||」`で表す。
「条件1 || 条件2」は「条件1または条件2」という意味で、この場合は、複数の条件のうち1つでもtrueならtrueになる。

```.ruby:例
score = 96

# 「95以上かつ99以下」の場合のif文
if score>=95 && score<=99
  puts "高得点です。"
end
```

```.text:出力結果
高得点です。
```
<br>
<br>

```.ruby:今迄の応用
number = gets.to_i

if number%3==0 && number%5==0
  puts "15の倍数です"
elsif number%5==0
  puts "5の倍数です"
elsif number%3==0
  puts "3の倍数です"
else
  puts "3の倍数でも5の倍数でもありません"
end
```

<br>
過去投稿記事
-
[【Ruby ~基本(コマンド/メソッド)~】勉強メモ](https://qiita.com/k-yasuhiro/items/8803203b29d04664c866)
Python学習 基礎編　~コメントアウトとは？~

こちらではPython学習の備忘録と、Ruby、JavaScriptとの比較も含め記載していきたいと思いましたが、Pythonの説明が意外と長くなってしまったので今回はPythonのみとします。
プログラミング初心者や他の言語にも興味、関心をお持ちの方の参考になれば幸いです。

###コメントアウトとは？
「コメントアウトした内容は実行プログラムから無視される」という特徴があります。
つまり、コードに関するメモや意味を、プログラムに影響を与えることなく残せるので便利です。
また、この特徴を活かして、コードを試行錯誤したい時にコメントアウトが役立ってくれます。
* * *

###コメントを記述するには？
###Python
- １行コメント

「#」から行末までは実行時に無視される。
「#」より前のコードは有効。
上記より範囲指定はできない。

```py:script.py
# この行はコメントです。
a = "コメント"
print(a) # 変数aを出力
```
- トリプルクォートによる複数行コメント

関数(defブロック)やクラスなどの先頭の文字列に説明を記述するdocstring(ドキュメンテーション文字列)という仕組みがある。
 【参考記事】
[Pythonのdocstring（ドキュメンテーション文字列）の書き方](https://note.nkmk.me/python-docstring/)


```py:script.py
def test(a, b):
    '''docstring
    description
    '''
    print(a)
    print(b)
```
シングルクォート「'」、　またはダブルクォート「"」を3つ繋げたトリプルクォート「'''または"""」で囲むことで改行を含めた文字列を生成することができるため、docstringではトリプルクォートが使われるいことが多い。
【参考記事】
[Pythonで文字列生成（引用符、strコンストラクタ）](https://note.nkmk.me/python-str-literal-constructor/)

文字列を単独で記述してもコードの処理に影響を与えないのでdocstring以外でもトリプルクォートが複数行のコメントやコメントアウトとして利用されている場合がある。

```py:script.py
a = 1
'''
b = 2
c = 3
d = 4
'''
e = 5
```
トリプルクォートはあくまでも文字列なので、「#」によるコメントのように実行時に無視されるわけではない。
そのため、インデントされているブロックの中でトリプルクォートをコメントとして利用する場合、インデントを合わせないとエラーになる。

```py:script.py
# インデントが合っているのでエラーにならない
def test(a, b):
    print(a)
    '''
    comment line1
    comment line2
    comment line3
    '''
    print(b)
```

```py:script.py
# インデントが合っていないのでエラー
def test(a, b):
    print(a)
'''
comment line1
comment line2
comment line3
'''
    print(b)

# IndentationError: unexpected indent
```
「#」によるコメントは実行時に無視されるのでインデントが合っていなくてもエラーにはならないが、コードとしての可読性を良くするにはインデントを合わせた方が良い。

```py:script.py
def test(a, b):
    print(a)
    # comment line1
    # comment line2
    # comment line3
    print(b)

def test(a, b):
    print(a)
# comment line1
# comment line2
# comment line3
    print(b)
```
* * *
###おわりに
いずれにせよトリプルクォートについては、コメントではなく文字列なのでdocstring以外では使わない方が無難だと思われます。
Python3.0以降では、関数アノテーションというものがあるらしいが、こちらはまた後日。
* * * 
【参考記事】
大変勉強になりました、ありがとうございます。
[Pythonのコメント、コメントアウトの書き方]
(https://note.nkmk.me/python-comment/)
LineRendererで割ときれいな線を描いてみる

## はじめに
この記事は以下のサイトの記事を参考にさせていただいてます
https://qiita.com/7of9/items/3750d30590e3efcfd389

## 注意
最適化までは行っていないのでその点はご注意ください

## 仕様的なもの
* 受け渡されたor設定された座標をつなぎ合わせて1本のきれいな線を描く
* Z軸は使用しない

## コード部分
```c#:DrawLine.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DrawLineUI : MonoBehaviour
{
    [SerializeField] private Material lineMaterial;  // 線に使うマテリアル
    [SerializeField] private Color lineColor;   // 線の色
    [SerializeField] private float lineWidth;    // 線の太さ
    [SerializeField] private List<GameObject> objList;    
    [SerializeField] private List<Vector2> positionObjList;
    
    // 追加されたゲームオブジェクトのリスト
    private List<GameObject> addGameObjectList = new List<GameObject>();

    void Start () 
    {
        DrawLine();
    }

    private void DrawLine()
    {
        List<Vector3> positionList = new List<Vector3>();
        positionList = StoringVector2ToVector3(positionObjList);
        for(int index = 0;index < positionObjList.Count - 1;++index)
        {
            CreateLine(positionObjList,index);
        }
    }

    // Vector2のリストを持ってきて、SetActiveを確認しながらCreateLineに使うListに格納していく
    private List<Vector3> StoringVector2ToVector3(List<Vector2> positionObjList)
    {
        List<Vector3> positionList = new List<Vector3>();
        for(int index=0;index<positionObjList.Count;++index)
        {
             if(objList[index].active == false)
             {   //gameObjectが設定されていない場合に飛ばす
                 continue;
             }
         }
        positionObjList.Add(positionList[index]);
        
        return positionObjList;
    }

    // 新しいオブジェクトを作ってLineRenderともろもろの設定を突っ込むとこ
    private void CreateLine(List<Vector3> vec3List, int indexNum)
    {
        List<Vector3> myPoint = new List<Vector3>();    // LineRendererのPositionを設定するのに使用
        for(int idx = 0; idx < 2; idx++) 
        {
            myPoint.Add(new Vector3(vec3List[indexNum + idx].x, vec3List[indexNum + idx].y, 0.0f));
        }
        // 生成するオブジェクト名
        GameObject newLine = new GameObject ("Line"+addGameObjectList.Count);   
        addGameObjectList.Add(newLine);
        LineRenderer lineRenderer = newLine.AddComponent<LineRenderer> ();
        lineRenderer.useWorldSpace = false;
        lineRenderer.SetVertexCount(2);
        lineRenderer.SetWidth (lineWidth, lineWidth);
        lineRenderer.SetColors(lineColor,lineColor);    // 色の設定
        if(lineMaterial != null)
        {
            lineRenderer.material = lineMaterial;
        }
        Vector3 startVec = myPoint[0];
        Vector3 endVec   = myPoint[1];
        lineRenderer.numCapVertices = 90;
        lineRenderer.SetPosition (0, startVec);
        lineRenderer.SetPosition (1, endVec);
    } 
}

```

## 最後に
LineRenderer複雑ですね～
もうちょっと簡単に線を実装できたらいいんですけど・・・・
PlotJugglerでrosbagのトピックを可視化する

PlotJugglerを用いることでrosbag中のtopicの値を横軸時間, 縦軸topic値のグラフとして可視化することができる.
また, 一度に複数のTopic値の可視化が可能. ロード時間もrqt_bagに比べて短い(と思う)
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696594/1a54c296-9520-e3d4-20f0-9d15d31746da.png">
もちろん再生も可能です

# PlotJugglerのインストール
こちらをインストールします
https://index.ros.org/p/plotjuggler/

以下のコマンドでplotjugglerをインストールします。ROS Pluginも同時にインストールされます。


```shell
sudo apt install ros-${ROS_DISTRO}-plotjuggler-ros
```

# 実行
以下のコマンドで実行できる

```shell
rosrun plotjuggler plotjuggler
```

File>Load Dataと選択し, 解析したいrosbagデータを選択するとrosbag中のTopic一覧が表示されるので, 可視化したいTopicを選択する
あとは以下のgifのように操作すればOK

![](http://wiki.ros.org/plotjuggler?action=AttachFile&do=get&target=PlotJuggler.gif)
http://wiki.ros.org/plotjuggler より引用
エンジニアとしての文章力

# エンジニアとしての文章力
## 経緯
転職するにあたって、文章を書く機会が増えて絶望しまくったのでメモ代わり、及び追々見返したときに初心にかえる意味で書いてみた。

## 概要
- 自己紹介（初めての記事なので）
- 設計書の文章について

## 自己紹介
- ３０代後半のシステムエンジニア（2020年時点）
- 民間、官公庁の開発からインフラまで、何でもやる人
- プロジェクトマネージャー（以下、PMとする）の役割も経験あるが、だれもPMの指導してくれないのでPMBOKに沿って我流で挑む。
- 資格を色々持っているが、~~IPAの高度情報処理試験に合格していない・・・頑張る（笑）~~ 情報処理安全確保支援士合格できた！
- 毎回、顔色悪いねと言われる。

## 設計書の文章について
※経験からメモ書きするものなので、正解ではないことに注意願いたい。
　次に挙げることは、どのプロジェクトに参画しても必ずと言っていいほど指摘されることで、仕様の検討に入れないくらい面倒なことだと思う。

1. 気をつけなくてはいけないこと
    1-1. 「です。ます」「だ。である。」プロジェクトのルールに沿って統一
    1-2. 主語抜け
    1-3. 5W1H
1. チェックツール使えばいいんじゃない？

### 1. 気をつけなくてはいけないこと
■　1-1．「です。ます」「だ。である。」プロジェクトのルールに沿って統一
文章で「～である。」と書いていたのに途中で「～です。」と混在する文章を書いてしまうときがある。これだと読み手が統一感の無い文章となり、気持ち悪くなる。
なぜ、気持ち悪くなるのか考えて見ようと思う。

そもそも「です。ます」調や「だ。である。」調の使い分けが何なのか？それぞれの使い方があるのかなと思ったので調べてみた。

「です。ます」調は、敬体（敬語）
「だ。である。」調は、常体（口語の文体）

ということがわかった。
つまり、敬語と口語が混ざると違和感を覚えるので、文章でも気持ち悪くなるのだと変に納得した。敬語だった人が途中にちょいちょいタメ語を入れるようなものとした。（笑）

設計書に敬うような文章を書くことはないので、「だ。である。」調に統一するのがいいと思うが、プロジェクトのルールがあればそれに沿ったほうが良いと思う。

■　1-2．主語抜け
設計書に限らず、課題管理票やメールも含まれるのだが、よく主語がないという言葉を聞くことが多い。

主語・・・文章で述語の主体となる部分
述語・・・文章で動作や状態を示す部分

「お客様の回答待ちです。」
と課題票に書かれたとした場合、何が？なんの？ってなる。
何が？の部分が主語となるので、
「◯◯は、お客様の回答待ちです。」
としないと意味分かんない。
ということが現場では意外と多かった・・・

■　1-3．5W1H
以外と出来ていない5W1H（5W2Hもあるけども）
いつ（When）
どこで（Where）
だれが（Who）
なにを（What）
なぜ（Why）
どうした（How）
※5W2Hの場合、どのくらい（How much）が追加


### 2. チェックツール使えばいいんじゃない？
文章を訂正するチェックツールとして、Wordがあれば文章校正機能を使ってある程度訂正できると思うが、プロジェクトによっては、ExcelやPowerPointを使う設計書や資料があり、その都度ツールを使いわけることになるため面倒だ。
最近は、Googleスライドやドキュメントを利用するので、生成AIを補助のチェックツールとして使うのもよいかと。
※便利で完璧なチェックツールを知らないだけかも・・・


## 最後に
メモ代わりで書いた記事なので、記事そのものの文章力が怪しいと思っている。記事を書いていくことで、文章力を高めていきたいと思っているので、間違いがあったら優しく指摘してもらえるととても嬉しい。頑張ろ。。。
文章力については、まだ書ききれないことがあるので、引き続き書いていこうと思う。※必ずやるとは言っていない。
Snowflakeにてユーザー別にパブリックIP制限を実施する方法について

## 概要
Snowflakeでは、アカウント（サイト全体）単位とユーザー単位でそれぞれ接続元IPアドレスを制限できるため、ユーザー単位での簡易的な手順を紹介します。

下記ドキュメントにて、アカウント単位とユーザー単位で制限を設定でき、その手順が紹介されております。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/59d2ab4d-1a31-4b2a-ba61-57893d900723.png)

引用元:[ネットワークポリシー](https://docs.snowflake.com/ja/user-guide/network-policies.html)

## 手順
1.ACCOUNTADMINでログイン後、"Account" -> "Polices" -> "Create"にて、ネットワークポリシーを作成。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/9fea65a9-ac6a-408e-34cb-91047c5ffc3d.png)

SQLとしては下記です。

```sql
CREATE NETWORK POLICY AZUREANALYSISSERVICES ALLOWED_IP_LIST=('113.197.228.100') BLOCKED_IP_LIST=();
```

2.IP制限を実施したいユーザーに対して、SQLにてネットワークポリシーを設定。

```sql
use role accountadmin;
ALTER USER AASUSER SET NETWORK_POLICY = 'AZUREANALYSISSERVICES';
```

3.ネットワークポリシー違反となるIPアドレスからログイン後、接続できないことを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/129c83d8-8126-5ee6-64fa-9f5284cb9d32.png)
Next.jsでパスパラメータを取得する方法

## 概要
フロントエンドのフレームワークを使うと、パスパラメータを使用したくなる時があります。パスパラメータについては、[パスパラメータとクエリパラメータの違い](https://qiita.com/ayacai115/items/33d4fc74e527c8015bfe)を参照頂きたいのですが、URLパスに変数の値を指定する手法です。これをNext.jsで実現したい場合、どうすれば良いのか今回書きます。

## どうすれば良いのか
ドキュメントの[動的なルーティング](https://nextjs-ja-translation-docs.vercel.app/docs/routing/dynamic-routes)に書いてあるとおり、パスパラメータを設定したいパスのjsファイル名に`[パスパラメータ名].js`を指定することで、パラメータの取得をそのjs内で行うことができます。言葉だけだと、ピンと来ないかもしれないので以下にサンプルを示します。

## 実装サンプル
今回は記事投稿を例にします。パスパラメータに`投稿id（post_id）`を設定し、これを取得するやり方を書きます。

**＜ファイルの配置＞**
`pages/post`の配下に[post_id].jsを配置します。
![スクリーンショット 2020-11-27 0.19.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32098/48db12c6-3355-6cf8-b3a9-972f29a02b83.png)

**<[post_id].jsの内容>**
`router.query`でパスパラメータ名（post_id）を指定することで取得できます。

```[post_id].js
import { useRouter } from "next/router";
import Header from "../../components/common/Header";
import PostRefer from "../../components/post/PostRefer";

const Index = () => {
  const router = useRouter();
  // パスパラメータから値を取得
  const { post_id } = router.query;
  return (
    <div>
      <Header />
      <PostRefer postId={post_id} />
    </div>
  );
};

export default Index;
```

**＜このページへのアクセス＞**
`http://localhost:3000/post/[post_id]`へアクセスすると、パスパラメータを取得するページにアクセスします。
![スクリーンショット 2020-11-27 1.50.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32098/c7ae3118-44db-d37f-1d96-4e8425674a63.png)
Transformer実装

# Tensor2Tensor
無理だった。

```
$ pip3 install tensorflow-gpu==2.1.0
# GPU対応のTensorflow

$ pip3 uninstall tensorflow-addons
$ pip3 install tensorflow-addons==0.9.1

$ t2t-datagen --data_dir=data/data1 --tmp_dir=tmp --problem=translate_jpen --t2t_usr_dir .

$ t2t-trainer --data_dir=data/data1 --problem=translate_jpen --model=transformer --hparams_set=transformer_base_single_gpu --output_dir=training_result1 --t2t_usr_dir=.
```

# Harvard

GPUを4つ使うので、`G.large`を借りる。

```
qrsh -g gcc50582 -l rt_G.large=1 -l h_rt=01:00:00
```

```
$ pip3 install torchtext spacy
# Error: python setup.py egg_info error code 1
```

~~`pip gradeup`できれば万事解決できそうだけど残念ながらできないので…~~

```:やらなくていい！
$ pip3 install cython --user
$ git clone https://github.com/explosion/spaCy
$ cd spaCy

$ pip3 install -r Translation/spaCy/requirements.txt --user
$ python Translation/spaCy/setup.py build_ext --inplace
```

できた！！！！！！歓喜の舞！！！！！！！

```:こっち！
$ pip3 install --user --upgrade pip
$ pip3 install torchtext spacy --user
```

```:はじめに入れるもの
$ pip3 install http://download.pytorch.org/whl/cu80/torch-0.3.0.post4-cp36-cp36m-linux_x86_64.whl numpy matplotlib spacy torchtext seaborn --user
$ pip3 install matplotlib --user
$ pip3 install seaborn --user
$ pip3 install torchtext --user

# Translation-Task
$ pip3 install torchtext spacy --user
$ python3 -m spacy download en --user
$ python3 -m spacy download de --user
```

```:setup.py
# 125行目
def write_git_info_py(filename="spacy/git_info.py"):
# 書き換え
def write_git_info_py(filename="Translation/spaCy/spacy/git_info.py")
```

```:batch.py
# import の下に追記
warnings.simplefilter('ignore')
# 警告の非表示
```

## データPATH

```
/home/acc12954dm/.local/lib/python3.6/site-packages/spacy/data/de
```


# 参考文献
## モデル
- [Tensor2Tensor](https://github.com/tensorflow/tensor2tensor#walkthrough)
- [Cloud TPU での Tensor2Tensor を使用した Transformer の実行](https://cloud.google.com/tpu/docs/tutorials/transformer)
- [harvard](http://nlp.seas.harvard.edu/2018/04/03/attention.html)
- [attention-is-all-you-need-pytorch](https://github.com/jadore801120/attention-is-all-you-need-pytorch)
- [PyTorchを用いたディープラーニング実装の学習方法](https://medium.com/pytorch/pytorch%E3%82%92%E7%94%A8%E3%81%84%E3%81%9F%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E5%AE%9F%E8%A3%85%E3%81%AE%E5%AD%A6%E7%BF%92%E6%96%B9%E6%B3%95-part-3-144f62b7d58c)
- [↑のGit](https://github.com/YutaroOgawa/pytorch_advanced)
- [Pytorch Tutorial](https://pytorch.org/tutorials/beginner/transformer_tutorial.html)
- [PyTorchTEXT_transformer_tutorial](https://colab.research.google.com/github/JPA-BERT/jpa-bert.github.io/blob/master/notebooks/01PyTorchTEXT_transformer_tutorial.ipynb)
- [kerasベース](https://qiita.com/halhorn/items/c91497522be27bde17ce)

## 今後？
- [LSTM+Transformerモデル](https://note.com/diatonic_codes/n/nab29c78bbf2e)

## エラー対処
- [100MB超えのファイルをGitに上げない](https://qiita.com/takish/items/71b167314b58557a853e)

## 技術
- [spaCy](https://www.ogis-ri.co.jp/otc/hiroba/technical/similar-document-search/part4.html)
RuntimeErrorで画像投稿ができなかった場合の対処法

#背景#
Refileなどの画像投稿が出来るgemを導入し、画像を実際に格納してみたら
RuntimeErrorとされた。よくあることらしいので備忘録も含めて。

**使用環境
ruby 2.7.2　Rails 6.0.3.4**
#対処法
エラー文をよく読むとそこまで難しくない。そのままの通り実行することする。


```
RuntimeError at / Refile.secret_key was not set.

Please add the following to your Refile configuration and restart your application:

Refile.secret_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
```

このRefile.secret_key='XXX'をそのままコピー。
時間を置くとkeyが変わるので注意。


```/config/initializers/application_controller_renderer.rb
# Be sure to restart your server when you modify this file.

# ActiveSupport::Reloader.to_prepare do
#   ApplicationController.renderer.defaults.merge!(
#     http_host: 'example.org',
#     https: false
#   )
# end

#以下を貼り付ける
Refile.secret_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
```




Railsを再起動し、リロードし直すと無事画像が投稿されたのが確認された。
VeturをインストールしてもEmmetが動作しない時の対処法

こんばんは
アロハな男、やすのりです！

今日は、Vue.jsでプログラミングしていく上で、必須級とも言われている`Vetur`という拡張機能の`.vueファイルでのEmmet動作`がうまくいかず、解決するまでに時間がかかったので備忘録も兼ねて書いていこうと思います。

まず、結論から述べますと...

#結論
拡張機能の設定画面で`Emmet`と検索して、下記画像のチェックボックスにチェックを入れると、TabボタンでのEmmet記法が有効化されます!!
![スクリーンショット 2020-11-27 1.02.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699622/6b6cf846-8739-4e5d-7a32-175eecfcb3d3.png)


#そもそもEmmet記法って？
Emmet記法とは、HTMLやCSSをコーディングしていく際にタグやプロパティの一部だけを入力するだけで、タグやプロパティを生成する為の記法です。

具体例をあげると、

>
>例：`div#test`  Tabキーを押すと → `<div id='test'></div>`
>

こんなふうにHTMLタグを作成できたり、

>
>例：`w100` Tabキーを押すと → `width: 100px;`
>

CSSのプロパティの記述が簡単にできたりします。

ただ、これは通常の`.htmlファイル`等だとTabキーを押さなくても、下記画像の様に変換先の候補が表示されていて、該当の候補を選択することで同じことが実現できていました。

![スクリーンショット 2020-11-27 1.17.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699622/4f2f8fef-7903-c9ab-ae71-52c321dda1aa.png)

ですが、こと`.vueファイル`では通常ではこの動作が適用されていませんでしたので使うことができませんでした。

#Vetur
そこで登場するのが、冒頭でも紹介した`Vetur`という拡張機能です。
↓英語になりますが、こちらに`Vetur`の設定方法や拡張機能の説明が載っています。
https://vuejs.github.io/vetur/

VeturをVSCodeにインストールすることにより、拡張機能の中の1つとして`.vueファイル内でのEmmet記法動作`があります。

よし、それならこれをインストールすれば万事解決っ!!とはならず...

[![Image from Gyazo](https://i.gyazo.com/29e7547848d3c8819f65ebcd14ffca02.gif)](https://gyazo.com/29e7547848d3c8819f65ebcd14ffca02)
この様にinputタグを作成しようとしてみても候補はおろか、Tabキーを押しても何も起きない状況でした...

『何か設定が必要なのかな...でも、いろんな人の記述を見てみてもVeturをインストールするだけで大丈夫って書いてあるし...』と八方塞がりな状態でした。

そんな中、下記のQiita記事を発見することができました!!
<a href='https://qiita.com/Eki-in-san/items/790b7c2ba2bec1087aaa'>【高速コーディング】Emmetを使ってみよう!</a>

この記事のおかげで設定の中のチェックボックスにチェックを入れることを知ることができました。

#しかし
結果として、.vueファイルでもEmmet記法が使える様になりましたが、この様な設定をしないといけないとはVetur関連の記事を読んでも書いてはいませんでしたし、元々.htmlではEmmet記法を使用できていました...

これは私の環境下だけでの事象なのかどうなのか...ゆくゆくは原因を突き止めたいですね。

もし、私と同じ様な状況になった人は設定を今一度確認してみてください。
Cloud Composer(Airflow)のDAGからメタデータCloud SQLにアクセスする

Cloud Composerでは外部に公開されていない、テナントプロジェクトのCloudSQL(MySQL)にAirflowメタデータが格納されている。（[参考](https://cloud.google.com/composer/docs/concepts/architecture)）

メタデータの内容を見て、レポーティングしたいようなDAGを作る際に、以下のようなコードで、メタデータにアクセスすることができる。


# 実装のポイント

- MySqlOperatorはrecordをfetchしてくれないので、MySqlHookを組み合わせる。
- `mysql_conn_id` に `airflow_db` を指定する。

```sample_task.py
import json
from datetime import timedelta

import airflow
from airflow import DAG
from airflow.hooks.mysql_hook import MySqlHook
from airflow.operators.mysql_operator import MySqlOperator
from airflow.operators.python_operator import PythonOperator


DAG_NAME = "sample_task"

default_args = {
    "owner": "airflow",
    "depends_on_past": False,
    "start_date": airflow.utils.dates.days_ago(1),
    "email": ["foo@example.com"],
    "email_on_failure": False,
    "email_on_retry": False,
    "retries": 1,
    "retry_delay": timedelta(minutes=10),
}


dag = DAG(dag_id=DAG_NAME, default_args=default_args, schedule_interval="0 * * * *")


class FetchMySqlOperator(MySqlOperator):
    def execute(self, context):
        hook = MySqlHook(
            mysql_conn_id=self.mysql_conn_id,
        )

        return hook.get_records(self.sql, parameters=self.parameters)


def execute_sql(**context):
    def date_handler(obj):
        if hasattr(obj, "isoformat"):
            return obj.isoformat()
        elif isinstance(obj, timedelta):
            return str(obj)
        elif isinstance(obj, bytes):
            return obj.hex()
        else:
            raise TypeError(
                "Unserializable object {} of type {}".format(obj, type(obj))
            )

    operator = FetchMySqlOperator(
        task_id="foo_mysql",
        mysql_conn_id="airflow_db",
        sql="（メタデータに対するselect文などを書く）",
    )
    result = operator.execute(context)
    # resultに結果が入る


t1 = PythonOperator(
    task_id="exequte_sql", provide_context=True, python_callable=execute_sql, dag=dag
)

t1

```
switch文[PHP]

#switch文をPHPで書く
if, elseifによる分岐が多く複雑な場合、switch文で書き換えるとシンプルで読みやすいコードにできる。switch(式)の(式)がcaseの値と一致したとき、そのブロックが実行される。caseのどれにも一致しなかった時、defaultのブロックが実行される
![1470803893312.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725167/5389320a-d636-b5c6-e282-d7765e74b862.png)
##break
break命令は現在のブロックから脱出するための命令。break命令がないと、後ろに続くcaseブロックが続けて実行されてしまう

```

    switch($remainder) {
      case 0:
        echo "大吉です。";
        break;
        
      case 1:
        echo "中吉です。";
        break;
      
      case 2:
        echo "小吉です。";
        break;
        
      default:
        echo "凶です。";
        break;
    }
```
#以上！
AWS GlueのCrawler（クローラ）をAWS CDKで生成する

# 概要
* S3にたくさん投入したデータをAthenaでサクッと分析・集計できるようにする際、Glue Crawlerが非常に便利。
* CDKで構築した例はまだあまりなかったので記事化。

# S3の設定について
* [先日の記事](https://qiita.com/Kit-Ok/items/fcc9a0b4e135168c1d36)で考察したが、S3はいまのところ手動設定したものを利用しても良いように思う。

# Glueの設定について
* 上記の理由より、S3はすでにあるものを利用する形にする。
* Roleについては、[公式](https://docs.aws.amazon.com/ja_jp/glue/latest/dg/crawler-prereqs.html)（日本語が怪しいですが）の通り、マネージドポリシーの`AWSGlueServiceRole`を付与し、さらにインラインポリシーで`対象のS3パスへのGetObject・PutObjectを許可`するようにします。
* [CDKのConstructは「High Level Construct」「Low Level Construct」「Patterns」の3種があります](https://dev.classmethod.jp/articles/aws-cdk-construct-explanation/)が、Glue Crawlerについては2020/11/26現在、まだ 「Low Level」= `Cfn...` 系のものしか無い（[公式doc](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-glue-readme.html)）ので、`CfnCrawler`を使います。
    - [High Levelの方を作るissueはもうあるようです。](https://github.com/aws/aws-cdk/issues/8863)
* [Glue Crawlerが意図しない複数のテーブルを作ってしまうことがある](https://aws.amazon.com/jp/premiumsupport/knowledge-center/glue-crawler-multiple-tables/)ので、今回はコンソール画面で設定できる「S3パスごとに単一のスキーマを作成する」ようにします。
    - これの実現方法を探すのに苦労しました。[参考のStack Overflow](https://stackoverflow.com/questions/57521175/how-can-i-set-create-a-single-schema-for-each-s3-path-in-cloudformation)。
        - `'{"Version": 1.0, "Grouping": {"TableGroupingPolicy": "CombineCompatibleSchemas"}}'`
        - GlueはVersion 2.0もありますが、指定すると未対応らしく "Version 2.0 is not supported." というエラーが出ます。
    - 分類子（Classifier）は`CfnClassifier`で「名前（`name`）を指定して生成」し、`CfnCrawler`の`props`内、`classifiers`にその名前を与えて使います。今回は割愛。

# ソースコード例

たとえばこんな感じ。

```typescript

import * as cdk from '@aws-cdk/core';
import * as iam from '@aws-cdk/aws-iam';
import * as glue from '@aws-cdk/aws-glue';
import * as s3  from '@aws-cdk/aws-s3';

export class MyStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const myBucketName = 'my-bucket';
    const myCrawlerName = 'myCrawler';
    const myCrawlerRoleName = 'myCrawlerRole';
    const myAthenaDBName = 'my_db';

    const myBucket = s3.Bucket.fromBucketName(this, myBucketName, myBucketName);

    const myCrawlerRole = new iam.Role(this, myCrawlerRoleName, {
      assumedBy: new iam.ServicePrincipal('glue.amazonaws.com')
    });
    myCrawlerRole.addManagedPolicy(
      iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSGlueServiceRole'));
    myCrawlerRole.addToPolicy(
      new iam.PolicyStatement({
        effect: iam.Effect.ALLOW,
        resources: [`${myBucket.bucketArn}/path-to-object-parent/*`],
        actions: ["s3:GetObject", "s3:PutObject"]
      })
    );

    const myCrawler = new glue.CfnCrawler(this, myCrawlerName, {
      role: myCrawlerRole.roleArn,
      databaseName: myAthenaDBName,
      targets: {
        s3Targets: [{ path: `${myBucket.s3UrlForObject()}/path-to-object-parent/` }]
      },
      configuration: '{"Version": 1.0, "Grouping": {"TableGroupingPolicy": "CombineCompatibleSchemas"}}'
    });
  }
}

```

# まだ良くわからないこと
わかる方いらっしゃいましたら教えてほしいです。

- Constructの「id」の活用方法。今のところ適当。
- S3もCDKで管理できたら良いけど、CDK（というかIaC？）の利点を活かせるやりかたは今のところ不明。
- TypeScriptはまだ1週間ほどしか触っていないので、いろいろ不安。
[Azure Functions] 長めの処理時間をかける関数 (C#)

# はじめに

Azure Functions では、SKU によって処理上限時間が決まっています ([参考](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-scale))。
これを試験とかで試してみる用に関数を作成したので、とりあえず公開しておこうかなと思います。

# 環境

* .NET Core 3.1

# コード

Visual Studio 2019 のテンプレートから HTTP Trigger で作成し、ちょちょっと変えただけですが。

```C#
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace LongRunFunctions01
{
    public static class Function1
    {
        [FunctionName("LongRunFunction01")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            // デフォルトでは5秒実行
            int sec = 5;

            // sec というパラメータに入れた数字を秒数として、その時間だけ実行する
            if (req.Query.ContainsKey("sec"))
            {
                sec = int.Parse(req.Query["sec"]);
            }

            for (int i = 0; i < sec; i++)
            {
                await Task.Delay(1000);
                if(i % 10 == 0)
                {
                    log.LogInformation($"{i} sec");
                }
            }

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);

            string responseMessage = "This HTTP triggered function executed successfully. ";

            return new OkObjectResult(responseMessage);
        }
    }
}
```

## Usage

下記のようにアクセスすると、100秒間実行しようとします。

```
<URL>/LongRunFunction01?sec=100
```

# さいごに

インフラエンジニアにとっては、こういうインフラの動きを試すためにコードを書く必要が出てきたりしていますね。良い勉強になるので、今後も色々と試してみようと思います。
Rails チュートリアル_7章_学習メモ

#学習メモ
##debugger
そもそも、デバッグとはバグを見つけて修正する作業の事。
今回ではバグを見つけるためのメソッド。
→ログを見ている感じ
##Gravatar
プロフィール写真をアップして、指定したアドレスと関連付ける事が出来る。
ユーザーのアドレスを組み込んだ画像パスを作成し、プロフィール画像を自動的に表示させる。

##ヘルパー
viewを短く見やすくする為に、関数を格納しておくシステムのようなもの。
ヘルパーを定義or用意されているヘルパーを使用して、viewsのコードを短く簡単に書く

###redirect_to @user
>これは次のコードと等価になります。

redirect_to user_url(@user)
これはredirect_to @userというコードから（Railsエンジニアが）user_url(@user)といったコードを実行したいということを、Railsが推察してくれた結果になります。
【実験】AWS Workspacesで３つのサブネットにそれぞれ配置できるか？

# AWS Workspacesで３つのサブネットにそれぞれ配置できるか？

On-PremにあるAD環境をAWSにリフトアップしてみようと検証を試みた記録です

## 前提条件

* 同一認証基盤を利用したい
* ネットワークセグメントが３つある

## 検証環境のイメージ

以下のような構成で検証を進めました。

機能としてはセカンダリといいつつつ、
ターシャリ（3番目）もアタッチ可能なVPCのセカンダリCIDRを使います。
[Associating a secondary IPv4 CIDR block with your VPC](https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html#add-ipv4-cidr)

![AWS Integration ap-northeast-1 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/0d0951a7-aa4c-6add-19b3-2ccb9efc1973.png)

## 結論

* 不可能でした
    * Workspacesで利用する認証基盤として以下の3つを用意しましたが、いずれも認証で利用可能なサブネットが２つまでしか選択できないため、一つの基盤で運用はできないことが分かりました

## 検証画像

3パターンのディレクトリサービスを立ち上げました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/f0fc5de0-bfd9-cf7d-67ae-32a6296d115b.png)

### 例）SimpleAD

Registerで色々見ましたが、ポップアップが出てくるが選択可能なサブネットは２つまでしか選べない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/3763c289-a76d-adfc-446c-2e2b73fc7e69.png)

## その他

### ADConnector でターゲットとして予定していたEC2について

予め利用するサブネットごとにENIを用意して、EC2のプライベートIPアドレスは固定化します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/2a295d11-62c6-0741-dacf-03132f17942c.png)

AWS公式ドキュメントにある[Elastic Network Interface](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-eni.html)に従って、
今回、NICを４つ採用する（インスタンス通信用１つ、Workspaces用だった３つ）ため、
`t3.xlarge` 以上のインスタンスが必要となります。

実際、Windowsで起動したインスタンスにもNICを接続して問題なく通信ができるところまで確認できました。
ADDSをインストールするため、 `getmac /V`や`ipconfig /all`でOSが認識しているインターフェースとIPアドレスの範囲を間違えないようにOS上からもIPアドレス固定化しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/c1e8a1f4-c82f-c366-cfa9-43ab43102921.png)

## まとめ

今回検証してみて、元々On-Premで出来ていたからクラウドでも出来るだろうとの見切り発車ではなく、
軽く作ってみようとクラウドらしくスモールかつクイックにやってみることの重要性を改めて感じました。
今回は、目的である環境の移設については、改めて構成検討から始めようと思います。

1台で賄っていたユーザをSimpleADを2台に分散するとして、おおよそ72USDなので、
分散管理になっていくかなとぼんやり考えています。
[
Simple AD スモールディレクトリへの月々の課金 (30 日後または 1,500 時間の無料トライアル期間終了後)](https://aws.amazon.com/jp/directoryservice/other-directories-pricing/)

-- 2020/11/30 追記

先日検証しているときに、Cognitoが表示されていたので改めて検証を試みたところ表示されず。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/ce12b21f-5f27-d7cb-ccb4-74e6242bda68.png)

下記のブログを見たところ、ADがあることを前提とした仕組みでした。
結局、ADがサブネット２つまでというところで、実現できないことが確定となりました。

Creating a self-service portal for Amazon WorkSpaces end users
https://aws.amazon.com/jp/blogs/desktop-and-application-streaming/creating-a-self-service-portal-for-amazon-workspaces-end-users/

> Authentication, which is handled by an Amazon Cognito User Pool federated via SAML 2.0 with Active Directory.
クリックイベントが2回（複数回）動くのは、.on()の重複が原因だった

# どうも7noteです。clickイベントが重複して動くのはon()の重複のせいだった。

以前、躓いてしまったのでまとめました。

## 問題
1回押したら開く、もしくは閉じるだけしたいのに、
以下のようにクリックしたら2回（もしくは2回以上）動作してしまう。

![sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/de290302-acc4-a10a-6fb2-5cf84979e96f.gif)

## 原因

**`on()`を複数回指定しているのが原因でした。**
ウィンドウサイズによって切り替えつつ、クリックイベントも同時に動かそうとしたときに発生しました。

```js
// 不具合が起こるソースの例
$(function(){
  $(window).on('load resize', function(){
    var w = $(window).width();
    var x = 768;
    if (w <= x) {
      $('.tab').on('click',function () {
        $('.hogehoge').slideToggle();
      });
    }
  });
});
```

### 他の原因

クリックしているのがlabel要素だと、labelとinputが重複して反応し2回になっている可能性も大。

## 対策
**`off()`を使うと対策可能。**

```例.js
//~~~省略~~~
$('.tab').off('click');     // 2回目のonの前にあらかじめ.off()を実行
$('.tab').on('click',function () {
  $('.hogehoge').slideToggle();
});
//~~~省略~~~
```

## まとめ

`.click()`でも同じことが起こるようです。
`.on()`では処理がどんどん積み重なり、それが重複して起動してしまう仕様のようです。


いままでも`on()`を重複して作成している時があったのですが、作りがたまたまよかったのか特に問題なく動くことがほとんどでした。
しかし、「前はこれでうごいたはずなのに」となってしまい原因の追求に時間がかかってしまいました。

プログラミングは**知っていれば1分もかからないことを、知らないと1時間2時間とかかってしまう**ので、基礎知識はとても重要だなと痛感しました。
これからも日々精進してまいります。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】HTML・CSSのちょいテク詰め合わせ](https://qiita.com/7note)


参考
https://qiita.com/nekoneko-wanwan/items/3d3da95f1127f743397d
SMT環境で物理コア数を取得するスクリプト

SMT環境で、スレッドが含まれたのコア数ではなく、物理コア数がほしいときもあると思います。
それ以外についても、加工しやすい形になっていないことが多いので単純に数をechoするだけです。

### 物理コア数の合計
```bash
echo $(($(grep physical.id /proc/cpuinfo|sort -u|wc -l)*$(grep core.id /proc/cpuinfo|sort -u|wc -l)))
```
### 論理コア数の合計 (nosmtだと上記と一致する。)
```bash
echo $(grep core.id /proc/cpuinfo|wc -l)
nproc
```
### CPU数
```bash
echo $(grep physical.id /proc/cpuinfo|sort -u|wc -l)
```
### 1CPUあたりの物理コア数
```bash
echo $(grep core.id /proc/cpuinfo|sort -u|wc -l)
```
Reactでdivdivする問題をReact.Fragmentで解決する

#JSXの記法
JSXファイルはreturnに1つのタグしか持てないというルールがあります。
そのため、以下のようにリストを２つ並べようとすると、2つのulタグをreturnが持つことになり、

```jsx
import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
		<ul>
			<li>Coke</li>
			<li>Soda</li>
			<li>Orange Juice</li>
		</ul>
		<ul>
			<td>Hamburger</td>
			<td>Fries</td>
			<td>Salad</td>
		</ul>
	);
  }
}

export default App;
```
以下のようにエラーになってしまいます。

```
Adjacent JSX elements must be wrapped in an enclosing tag
```

#余計なdivタグ

これを回避するためによく使われるのは、
以下のようにdivタグで全体を囲って1つの要素を返すようにする記法です。

```jsx
import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
		<div>
			<ul>
				<li>Coke</li>
				<li>Soda</li>
				<li>Orange Juice</li>
			</ul>
			<ul>
				<li>Hamburger</li>
				<li>Fries</li>
				<li>Salad</li>
			</ul>
		</div>
	);
  }
}

export default App;
```

しかし、この記法だと余計なdivタグが入ってしまいます。実際、開発ツールで確認すると
rootのdiv要素を開いたらさっき書いたdivが出てきてdivdivしちゃってぱっと見づらいですね。
要素が増えてくるとdivをいちいち一つ一つ開けないと中身がみれないので不便です。

![スクリーンショット 2020-11-27 0.26.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296645/13d06379-8ddd-90c5-60f8-5a8869c26111.png)

#divタグの代わりにReact.Fragmentを使う

そこで便利なのがdivではなく、React.Fragmentを用いる記法です。

```jsx
import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
		<React.Fragment>
			<ul>
				<li>Coke</li>
				<li>Soda</li>
				<li>Orange Juice</li>
			</ul>
			<ul>
				<li>Hamburger</li>
				<li>Fries</li>
				<li>Salad</li>
			</ul>
		</React.Fragment>
	);
  }
}

export default App;
```
React.Fragmentはそれ自体に意味を持たないので、開発ツールでは表示されません。したがって、rootの下にulタグが2つあるのが一目でわかり、画面に2つのリストが表示されていることと直感的にも合います。
![スクリーンショット 2020-11-27 0.32.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296645/927d6822-9743-119d-6b21-b0438b005481.png)

#結論
JSXのルール（1つしか要素返せない）に従うためだけのdivはReact.Fragmentに変えて可読性を高めよう！

#補足
React.Fragmentは1つしか要素返せないJSXのルールに対して、コードの構造を保つために作られたものです。そのため、divタグとは別物です。例えばReact.FragmentにclassNameを指定したり、styleを指定することはできません。そういう使い方をしたいときは普通にdivを使いましょう。

#参考
https://ja.reactjs.org/docs/fragments.html
https://stackoverflow.com/questions/49069746/workaround-to-add-classname-to-fragment-in-react
Teamsのショートカットキーまとめ

##Teamsのショートカットキーいろは（どんどん追加＆教えてください）
###基本なショートカットキー（[Ctrl] + [.]は除く）個人まとめ
全体的な構成
　　１．ホーム画面で
　　２．チャットで
　　３．予定表で
　　４．チームで
※基本Windowsのクライアントアプリベースです。ブラウザベースも同じはず。。。未検証（MacではTeams使わない）

----

####１．ホーム画面で
#####■　ショートカットキー

----

####２．チャットで
#####■　ショートカットキー
> Ctrl + Shift + x 

　新しい会話を作成ボックスモードで開始。
→　[Enter]改行ができないTeamsでは重宝。まずは絶対このショートカットキー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160422/4f25e455-776d-903b-eb04-350097ef56f5.png)

> Ctrl + Shift + v

　書式情報なしで貼り付けができる。
→　地味に助かる。Excelとかから貼り付けたい時に表とか字体とかそのまま貼り付けられてイラっとたまにするときに助かる～。
<< 普通の[Ctrl]+[v]（ｲﾗｲﾗ…） >>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160422/c11571ff-772d-64c3-4f5d-76ec1d110304.png)
<< [Ctrl]+[Shift]+[v]（ｽﾊﾞﾗｼｲ） >>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160422/ae2b74e1-229f-6240-399e-bb6ffbe44856.png)

> ↑

　チャット送信直後のメッセージを編集したい時に即編集モードに変わる。
→　チャットならではの機能。多用はしないけど覚えとくと便利！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160422/8b3c24d9-d7f1-4b06-673b-b6fb81fb13b7.png)
↓　[↑]を押すと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160422/53f3d617-2758-7b52-3e78-1122c83bb7bb.png)

> Ctrl + alt + 1

　書式の段落が見出し1になる。（2回押すと段落に戻る）
> Ctrl + alt + 2

　書式の段落が見出し2になる。（〃）
> Ctrl + alt + 3

　書式が見出し3になる。（〃）
> Ctrl + alt + 4

　書式が引用になる。（段落が等幅にならんのかーい。でも地味に便利）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160422/177ef9de-a9ec-406e-1c03-136ed32c637b.png)
ちなみに、[>]を先頭に入れることでも同じことできます。
> Ctrl + 5

→　書式が等幅になる。（〃）
>  ' (文字列) '

　Markdownと同じく文字列に小枠（？）がつく。
→あんまし使わない。けどたまーに使う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160422/9eee4fcf-4e74-d935-58b5-4cdd4f92887b.png)

> ~(文字列)~

　文字列に取り消し線がつく。
→これはよく使うね。便利。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160422/e0d93155-10c0-a31b-71ce-74b400aaf592.png)

> Ctrl + k

　リンクを作成する。


#####■　探し中（Help！！）
・ハイライトを付ける
・コードスニペット
・インデント
・書式クリア

----

####３．予定表で
#####■　ショートカットキー

----

----

####４．チームで
#####■　ショートカットキー

----

随時更新していきます～
Maven の mvn exec:java で実行した java のプログラムを datadog agent によりお手軽に Profile する方法

MAVEN_OPTS に、

https://docs.datadoghq.com/ja/tracing/setup/java/?tab=springboot

の、

![Screen Shot 2020-11-27 at 0.20.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18869/e0adf9f9-ff60-46f4-be33-f34b3ea29103.png)

で作った -javaagent の snipet を指定する。

```shell
export MAVEN_OPTS="-javaagent:/path/to/dd-java-agent.jar -Ddd.profiling.enabled=true -Ddd.logs.injection=true -Ddd.trace.sample.rate=1 -Ddd.service=YOURAPPNAME -Ddd.env=dev"

mvn install; mvn compile; mvn exec:java -Dexec.mainClass=YOURAPPCLASS -Dexec.args="arg1 arg2"
```

その後 Datadog の Web 画面から APM -> Profile にて、

![Screen Shot 2020-11-27 at 0.34.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18869/88b3c6c9-aaa6-02bf-d82f-48c84f800b98.png)

のような画面が確認できる。
3. Android学習 イベントリスナー編

**勉強できること**
Viewに対するイベントなどを検知して、それをトリガーに処理を実行できるようになる。


**環境**
AndroidStudioのバージョン：4.0.1
言語：Java

# イベントリスナーとは
スマートフォンの操作では、タップイベント、長押し、スクロール、戻るボタン操作などが発生します。
それらを検知するものがイベントリスナーです。

# リスナーの種類
イベントリスナーを抜粋して紹介します。

|リスナー名|メソッド|詳細|
|:--|:--|:--|
|クリックイベント|onClick()|ボタンなどのViewに対するタップ（クリックイベント）を検知する|
|長押しイベント|onLongClick()|ボタンなどのViewに対する長押しイベントを検知する|
|ハードウェアボタンイベント|onKey()|ホームボタンや戻るボタン押下時を検知する|

他にもViewによりスクロールや、タッチイベントなど色々なクリックリスナーが提供されています。
必要都度調べてみてください。

# 記述例

```java:MainActivity.java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ボタンタップされた内容を反映するTextView
        final TextView textView = (TextView)findViewById(R.id.text1);

        // ボタンのクリックリスナーを設定
        Button button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // ボタンクリック時にTextViewに文字を反映する
                textView.setText("タップしました。");
            }
        });

        // ボタンの長押しリスナーを設定
        button.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                // ボタン長押し時にTextViewに文字を反映する
                textView.setText("長押ししました。");
                return false;
            }
        });
    }
}
```

今回はここまでとなります。
お疲れさまでした！d(´∀｀)b
ハッシュ値を取得・検証するWindows Formアプリ(.NET Core, C#)を作成・GitHubで公開してみた

タイトル通りです。
実は以前にこういう記事を書きました。

- [ハッシュ値を出力する湯婆婆をC#で実装してみる（PBKDF2他対応）](https://qiita.com/yuki_h3/items/ffb29715e6f5fc0a5ed8)

何でまたハッシュとか思われそうですが、C#とアプリ開発の勉強もあるのですが、ときどき使用することがあるので、いちいちコマンドラインで出さなくても良いようにするためです。

## 公開してる場所

↓のGitHubに置いています。
まぁ、フリーソフトというかオープンソースです。

- [GetHash](https://github.com/yukgithub/GetHash)

![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323247/3ae5d8e2-d6b8-4e98-a767-33accbd4ea9e.png)

Git(GitHubも)の使い方、最初は全然分かりませんでしたが、徐々に使い慣れてきました。

`git init`で新規作成して、
`git config user.name`でユーザー名を登録して（メールアドレスも）、
`git remote add origin ...`して、
`git add`でファイル追加して、
`git commit -m コメント`でコミットして、
`git push ...`という流れでしょうか…。
（事前にGitHubのリポジトリ作成する必要あるけど）

除外したいファイルを事前に指定する方法が知りたいのですが、まだそこには至っていません。

## 機能

- 入力ソースは文字列・ファイル両方に対応
- 比較ができる（ダウンロードしたファイルのハッシュ値突合で使える）
- .NETで利用できる主要なハッシュ値には対応した（MD5, SHA1, SHA256, SHA386, SHA512）。
- 引数にファイルパスを指定可能（起動時にハッシュ値は自動で出力）。
- TextChangedイベントで、リアルタイムで出力する（いちいちボタンを押すのが面倒だから）
- ファイルはドラッグアンドドロップでも指定可能

基本的には.NET Coreの機能を使用してるだけのGUIラッパーだと思います。それを使いやすくしたものです（使いやすくできてるといいのだけど）。

## 開発にあたっての所感とか

###イベントドリブンやっぱり面倒
コンソールアプリと違って、イベントドリブンだと処理のパターンが単純ではないので、中身のロジックをどうすればすっきりするか、結構悩みます。

まぁ、前職でもVB.NETで開発はしていましたが、どうしてもごちゃごちゃしてしまうのが難点（スキル不足かもしれませんが）。

### ドラッグアンドドロップの実装も初めてしてみました

2つのイベントを使用して書かないといけないんですね…。何気にコードがごちゃごちゃします。

```csharp
        private void txtCharas_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.All;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        private void txtCharas_DragDrop(object sender, DragEventArgs e)
        {
            string[] dropdata =  (string[])e.Data.GetData(DataFormats.FileDrop);

            if (dropdata.Length > 0)
                this.txtCharas.Text = dropdata[0];
        }
```

あと、PBKDF2も入れようか迷いましたが、特にパスワード保管用のハッシュ値をわざわざ手作業で作る必要も今のところないので、これは省きました。あと、MD5やSHA256は継承元のクラスが同じですが、PBKDF2については違いますので、追加したら分岐がさらに増えます。

Windowアプリケーションの開発ってもっと楽にならないかなぁ……。WPFとかUWPも使ってはみたいのだけど、前者どうも普及しているかよく分からないし、後者もまだ様子見の段階。

すごく走り書きの記事になりましたが、どうぞ、温かい目で見て頂けると嬉しいです。
Goでstructをmapに変換する

## はじめに

似たような内容の記事はあったのですが、バージョンが変わったせいかうまく動かなくて苦労したので記事にしました。

## JSONを使うバージョン

```Go
var result map[string]interface{}
indirect, _ := json.Marshal(data)
json.Unmarshal(indirect, &result)

// 値がなかったら、キーの削除
for key, value := range result {
    if value == nil {
        delete(result, key)
    }
}
```

これだと、time.Time型がStringになってしまい、僕の用途には合いませんでした。。

## reflectを使うバージョン

```Go
result := make(map[string]interface{})

v := reflect.Indirect(reflect.ValueOf(data))
t := v.Type()
for i := 0; i < t.NumField(); i++ {
    ft := t.Field(i)
    fv := v.FieldByName(ft.Name)
   
    // nullの場合のみセット
    if !fv.IsNil() {
        result[ft.Name] = reflect.Indirect(reflect.ValueOf(fv.Interface()))
    }
}
```

`reflect.Indirect`は、`fv.Interface()`の値がポインタだった場合にそれを外す処理です。
ポインタのままmapに入れたい!って方にはいらないです。

参考文献

https://qiita.com/keitaj/items/440a50a53c8980ee338f
https://qiita.com/chimatter/items/b0879401d6666589ab71
https://qiita.com/nirasan/items/b6b89f8c61c35b563e8c