OmniAICreator/Qiita-1.07M huggingface dataset:
AWS Budgets便利なのに使ってなかった

#AWS Budgets 使ってますか？
AWSを個人利用したり、アカウント管理してる人だと使ってない人のほうが少ないですよね。きっと。
私その少数派でした。昔はバージニアリージョンにCloudWatchアラームをセットするのがお作法。満足して止まってたんです。

お金のしきい値見てアラートを出すだけならそれでも良いのですが、せっかくなのでどんな事ができるのか見てみることにします。

# 使ってみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/3c650cd1-b8f9-3ba7-9bb0-b8e15cc4905a.png)

なるほど。`コスト予算`のほかにいろいろ選べる。これが違う所なんですね。

>現時点では、コスト総額の予算作成機能のみをご利用いただけます。AWS のコスト、使用量、予約情報がすべてバックフィルされ、AWS 予算機能の全セットが利用可能になるまでに最長で 4 日かかります。後でもう一度確認してください。

私の環境ではコスト予算しか選べないようでした。そのまま進んでみよう。
予算は５０USDで仮置きしてみる。次へ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/45b66b68-47b9-fd5f-e1df-2a1017d1d231.png)

しきい値を求められた。割合でも出来るのか。とても優秀ですね。既に満足
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/114ce1e8-518c-cee6-f362-520fbdd0e090.png)

SNSトピックに連携できるようでしたので連携し、その後メールか何かに繋げると良いと思います。
私はメール全く見ない人なのでLambdaからSlcakへ連携しています。
素敵なBudgetsライフを。

※SNSのアクセスポリシーは以下を追記する必要がありました。

```
    {
      "Sid": "AWSBudgets-notification-1",
      "Effect": "Allow",
      "Principal": {
        "Service": "budgets.amazonaws.com"
      },
      "Action": "SNS:Publish",
      "Resource": "your topic ARN"
    },
```
DockerコンテナからWebサイトを公開する方法

ApacheのHTTPサーバのDockerコンテナからWebサイトを公開する方法を紹介する。
サーバ一台で複数のWebサイトを走らせたり、一時的にWebサイトを公開するのによさそう。

## 環境
 * Ubuntu 20.04.2 LTS
 * Docker 20.10.5

Dockerのインストールは、[公式Docs](https://docs.docker.com/get-docker/)を参考にするべし。

## 手順
### 1. 前準備
まず、公開したいhtmlファイルを設置する。

```bash
> cd /var
> mkdir www
> sudo chown $USER www
> cd www
> mkdir html
> sudo chown $USER html

# 最後に公開したいhtmlファイルを設置した
```

### 2. Dockerコンテナの起動
httpdはApacheのDockerイメージ。コンテナの名前は`myweb`とする。

```bash
> docker run -d -p 80:80 --name myweb -v /var/www/html:/usr/local/apache2/htdocs httpd
```

### 3. 更新
htmlファイルを更新する。

```bash
> docker restart myweb
```

### 4. Dockerコンテナの停止
Dockerコンテナを停止。

```bash
> docker stop myweb
```

`docker stop myweb`を実行した後、再びDockerコンテナを再稼働させるとき

```bash
> docker start myweb
```

`docker stop myweb`を実行した後、再びDockerコンテナを削除させるとき

```bash
> docker rm myweb
```

## 補足
### Dockerfileからコンテナを起動
`FROM httpd`は最低限必要。Dokerfileは`/var/www/html/`に設置する。

```Dockerfile
FROM httpd

RUN set -ex && \
    apt update && \
    apt install -y vim && \
    apt install -y nano && \
    apt install -y less && \
    apt install -y tree && \
    cp /usr/share/zoneinfo/Japan /etc/localtime
```

DockerfileからDockerイメージ`img_myweb`を建てる。

```bash
> docker build -t img_myweb /var/www/html/
```

Dokerイメージ`img_myweb`からDokerコンテナ`myweb`を起動する。

```bash
> docker run -d -p 80:80 --name myweb -v /var/www/html:/usr/local/apache2/htdocs img_myweb
```
thymeleaf内で使う演算子について

# thymeleaf内で使う演算子について

htmlでthymeleafを使えば変数の指定ができると知り、「htmlに渡したリストのn番目のメッセージ内容を取得する」といった使い方をしていたところの問題が発生。<br>
具体的には20人毎に１ページのスライダーを使用していた時の話で<br>
1ページ目　1～20人目<br>
2ページ目　21～40人目　といったもの。<br>
上記のリストの情報を取得するために「n番目」の指定が必要だったのでnを変数として扱った。

### 例
```html
<div th:text="${list.get( ${stat.index} + (20 * ${i}) ).getMSG()" class="message"></div>
```
上記のような書き方を行った際、whiteLabelエラーが表示された。

${i}の指定が間違っているのはないか？と思い
```html
<div th:text="${list.get( ${stat.index} + (20 * 1) ).getMSG()" class="message"></div>
```
このように直接数字を書いてみたがエラーは解消されず・・・何故？？

いろんな記事を検索してみるも同じような現象に出会えず。
他にも()を増やしたり減らしたり、{}を増やしたり減らしたり、演算子を別のものに変えたり・・・と、途方もなくガチャガチャ弄っていたが一向に改善なし。

力技で動作させてみる方法に切り替えた。

## 無理くり改善させたコード
```html
<div type="hidden" th:with="msgNum = ${stat.index} + 20 * ${i}">
    <div th:text="${list.get(msgNum)" class="message"></div>
</div>
```
このように計算を変数に入れてしまえば想定通りの動きになった。

ただ書き方が気に入らない・・・なんかヤダなという思いが消えず・・・

推測として

- thタグ内で使える変数の数に指定がある？
- {}内で使える演算子の数に指定がある？

等が原因なのでは？と考えている。

今後原因がわかれば追記なりで詳しく説明していきたいと思う。
【amplify】 Can't find any frontend plugins configured for the CLI.

## amplify init でエラー

amplify 書籍の写経をしていたところ、 `amplify init` で エラーになり進められなくなりました。

```powershell
PS ...\sample-todo> amplify init
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project sampletodo
The following configuration will be applied:

Project information
| Name: sampletodo
| Environment: dev
| Default editor: Visual Studio Code
Can't find any frontend plugins configured for the CLI.
Run 'amplify plugin scan' to scan your system for plugins.
```

どうやら、

```
npm i -g @aws-amplify/cli
```

を何度か繰り返ししていたタイミングで、@aws-amplify/cli のバージョンが 4.49.0 から 4.50.0 にアップデートされたためのようでした。

以下のようにアンインストールして、バージョンをもとに戻したところエラーは起こらなくなりました。

```powershell:パッケージ削除とバージョン4.49.0指定のインストール
npm rm -g @aws-amplify/cli

npm i -g @aws-amplify/cli@4.49.0
```


## 実はもう一つの問題が。。。
`amplify init` エラーで色々悪戦苦闘していて yarn でも @aws-amplify/cli をインストールしてました。
これがまた解決に時間をかける原因になっていました。
このせいで npm rm しても 4.50.0 のパッケージが消えずに 4.49.0 に戻すことができなかったのです。

たまたま、 `npm ls -g` して @aws-amplify/cli があったところから yarn ディレクトリを見つけました。
なるほど、 yarn でも @aws-amplify/cli をアンインストールしないとダメでした！

ということで、 `yarn remove` もして 4.49.0 に戻せました。

```powershell:yarnでのアンインストール
yarn global remove @aws-amplify/cli
```

## 環境
Windows 10
［EXCEL関数］ファイル名やシート名を表示する

# 備忘メモ：CELL 関数

## 説明
ファイル名やシート名を取得する関数。

## 関数の例

### フルパス＋シート名
```
=CELL("filename")
```

### ファイル名
```
=MID(CELL("filename"),FIND("[",CELL("filename"))+1,FIND("]",CELL("filename"))-FIND("[",CELL("filename"))-1)
```

### シート名
```
=RIGHT(CELL("filename"),LEN(CELL("filename"))-FIND("]",CELL("filename")))
```
Firebase AuthenticationのEmail/Password認証とGoogle認証の併用（挙動メモ）

## はじめに
Flutterを使ってネイティブアプリを試しに作っていて、先日 `Firesbase Authentication` を使ったログイン機能を実装してみた。実装のためのサンプルコードは先日の記事に記載しているが、Email/Password認証とGoogle認証を併用する場合の挙動や、Email確認のステータスの変わり方などについて、いくつか気になったことをその後確認してみたので、その時の内容をメモとして残す。

## Flutterの実行環境

- Ubuntu 18.04LTS（GCP上）
- Flutter 1.22.6
- Dart 2.10.5
- Android Studio 4.1.2
- VScode 1.53.0
　　

## メモ内容
以下に、気になった事とそれに対する確認結果を列挙しているので、よければ参考にしてください。

#### Email確認やパスワード再設定の本文内容の変更はどの様にやるのか？
　⇒ Firebaseコンソールから`Authentication` を選択し、`Templates`のタグから各メール本文の内容を編集できる。（下図参照）
![Qiita-No038_img01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/f4fc3f25-c313-4d7e-bda4-690a380c28dc.jpeg)




#### Email確認やパスワード再設定のメールを2回以上送った場合は？
　⇒ 最新のメール以外からでメール内のリンク先に飛ぼうとすると、リクエスト期限切れとなりEmail確認 or 再設定ができない。


#### Email確認のステータスが未確認の状態で、Google認証をした場合、Email確認のステータスはどうなるのか？
　Google認証でログインしたタイミングで、Email確認のステータス（`isEmailVerified`の返り値）は`True`となる。


#### Google認証とEmail/Password認証で同じメールドレスを登録できるのか？

　Google認証でAのアドレス、Email/Password認証でAのアドレスという登録がそれぞれされている訳ではなく、あくまでも登録された1つのアドレスAに対し、そのユーザーがどの様な認証でログインするのか、という管理がされている。
具体的な挙動は以下の様な感じになる。

**【先にGoogle認証でログイン(登録)した場合】**
　⇒ Email/Password認証によるアカウント登録は**既に登録済みのメールアドレス**となってしまい登録できない。<font color="red">ただし、パスワード再設定メールは送ることができ、その再設定したパスワードを使えば、Email/Password認でログインができる。（パスワードの再設定画面はメール内のリンクから飛ぶため、Email確認もされた状態になる。）</font>
Firebaseのコンソール上での状態の変化は下図の様な感じ。
![Qiita-No038_img02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/4cbbc648-85ef-993d-3447-6d021e3f2bdd.jpeg)


　
**【先にEmail/Password認証のアカウント登録をした場合】**
　⇒ Email確認が完了していなくてもGoogle認証で入れるが、確認済みかどうかで下図の様に認証状態が変わる。
![Qiita-No038_img03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/516bfb84-cfd6-afce-28de-9446f93bddb2.jpeg)
<font color="red">先にEmail/Password認証のアカウント登録していたとしても、Email確認が済んでいない状態でGoogle認証をしてしまうと、最初に登録したPassword情報が消えてしまう。
そのため、パスワード再設定が必要になる。</font>

気になった部分については、認証の作業とコンソール上での変化を見ながら調べてみたが、実際の利用の話をすると、認証の仕方はいずれかだと思うので基本的には大した問題にはならないはず。。。

　
**あまり役立つ情報ではないかもしれませんが、誰かの参考になれば嬉しいです！**
　※もし何か追加で調べた事があったら、随時こちらの記事に追記していきたいと思います。
Nuxt.jsの基本的な使い方【コードの読み方編】

# プロローグ

Nuxt.jsを触り始めて三ヶ月弱くらいですが、
色々と使い方を覚えてきたので、メモとして記録を残します。

また、今書いているコードが先輩たちがつくりあげてきたおかげで便利にコードがかけるんだなと、調べていくうちにわかったりしたところがあったので、さらに理解を深めるために備忘録として残します。

不備不足だったり、理解が浅くて説明不足なところがあるかと思いますが、
勉強して更新していきたいとは思っています。

## この記事で何ができるようになるか

今回は、Nuxt.jsを触り始めた頃右も左も分からず、全くコードが読めなかったときから、今は「ここがこうなってるからここが動いて・・・」とゆっくりながら順を追って読めるようになったので、その経験をもとにそれぞれのコードがなにをしているか解説していきます。結果として、Nuxt.jsが少し読めるようになるかと思います。

## 解説

Vueファイルは下記の３つの構成になっていて、それぞれ役割があります。


| ブロック | 用途 | 
|:-----------|------------:|
| < template >       | HTML    | 
| < script >       | JavaScript    | 
| < style >       | CSS    | 


それぞれの関数に関して詳しくは調べていただければと思います。
あくまでも読み方がわかるようになるを重点にコメントにて解説を書いていきます。


```vuejs:hello.vue

//ここがHTML部分で、どのように表示したいか書きます。
<template>
 <div>
  <p>{{ name }}</p>
  <!-- 上記に関しては下記の[詳しい解説]にて説明します。 -->
  <button @click="console">コンソールを開いて確認しよう</button>
  <!-- ボタンを設置した際に、そのボタンがクリックされた時、consoleというメソッドが実行されます。 -->
  <!-- どのような内容が実行されるのかは、scriptブロックに記載します。 -->
 </div>
</template>
//ここまで


//ここがJavaScript部分で、どのように動かしたいかを書きます。
<script>
export default {
  data () {
    return {
      name: "チューリップ" //下記の[詳しい解説]にて説明します。
    }
  },
  watch: { 
   //watchプロパティというもので、データなどの変化を監視するものです。
  },
  mounted() {
   //初期化の中の決められたタイミングで実行される関数です。ここに記載したメソッドは最初に実行されます。
  },
  methods: { //ここにメソッドを書いていきます。
　　console()　//templateのbutton @click="console"で書いたメソッドです。
   {
     console.log("ボタンがクリックされたよ")
   }
   //上記のように、console(){}内に実行したい内容を書くことで、
 　//templateで書いたボタンがクリックされたときに、console(){}内の処理が実行されます。
  //上記だと、開発ツールを開いてボタンをクリックすれば「ボタンがクリックされたよ」とconsole上で表示されるかと思います。
  }
}
</script>
//ここまで

//ここがcss部分で、どのようなレイアウトデザインにしたいか書きます。
<style lang="scss">
p {
  text-align: center;
  font-size: 20px;
  color: red;
}
</style>
//ここまで

```

### 詳しい解説

``<p>{{ name }}</p>``で何を行っているのかというと、scriptブロックのdataにあるnameを読み取って、「チューリップ」と出力させています。

Vue.jsなどのドキュメントや初心者用の教材を見たとき、それなら直接``<p>チューリップ</p>``と書けばいいのに、なんでそんな回りくどいやり方をするんだろうなんて思っていました。

しかし、``<p>チューリップ</p>``だけ出力させたいならそれでもいいものの、ログインするユーザーに合わせて``<p>ひまわり</p>``や``<p>あじさい</p>``など出力したい場合はどうすればいいのでしょう？

そのときに、dataにあるnameにそれぞれの花の名前が入ったデータを格納してれば、``<p>{{ name }}</p>``とするだけで、データに保存してある名前を出力させることができます。

また、一覧としてチューリップ・ひまわり・あじさい・・・などと表示することもできます。便利ですね。

じゃあどうやって、dataにデータを格納するのか、どうやって一覧にデータ一覧を表示させるのかは別の記事で書こうと思います。

今の段階では、``name: "チューリップ"``としているので、``<p>{{ name }}</p>``とすると「チューリップ」が表示されますが、dataをうまく使うことで自由に表示することができます。

{{}}は、マスタッシュ構文というようで検索すると詳しい解説がありますので、ぜひ読んでみてください。

####  おわりに

壊滅的にNuxt.jsができなかったので、templateとscriptの関係性さえわかっていない状態でした。
しかし、templateで書いたものがどのようにscriptで動いているのかがわかれば、あとは関数やメソッドなどを理解できればある程度動くものがつくれるようになるんじゃないかと思います。
さらに、dataの使い方がわかれば、表示させたいデータや保存したいデータを自由自在に使えるのでよりよいアプリケーションが作れるようになるかと思います。
異なるアカウントのあるプロファイルで作業するためのaws-cli設定(備忘録)

## はじめに
Qiitaでは主にネタ記事を投稿する主義だったのですが、最後に投稿してから一年近く...笑

流石にまずいと思ったので、本来は自分のhatenaブログで投稿する内容ですが、aws-cliの設定方法の備忘録を載せたいと思います。

## 対象の読者
・既に自分のAWSアカウントでaws-cliの初期設定をしたことがある方
・働いてる企業のAWSアカウントでaws-cliをローカルで操作する必要が出てきた方
・複数のロール＆異なるAWSアカウントで行う必要がある方

## 手順

### ・アクセストークンとシークレットトークンを取得する
取得方法についてですが、AWSのコンソールの右上のアカウント部分を選択して、マイセキュリティ視覚情報をクリックすると確認することができます。ロール権限などの問題がある場合は取得できないと思いますので、そのときはインフラを管理してる方に事情を話して取得しましょう。

取得方法に関する説明はこちら）
https://www.multcloud.com/jp/tutorials/s3-key.html

### ・自分のパソコンのターミナルでaws configure —profile <好きな名前>を実行
例：

```
$ aws configure --profile company
AWS Access Key ID [None]: {アクセスキー(各自)}
AWS Secret Access Key [None]: {シークレットアクセスキー(各自)}
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

この処理が終わると、~/.aws/configファイルと~/.aws/credentialファイルの内容はそれぞれ以下のようになると思います。

```config
[default]
region = ap-northeast-1
output = json

[profile company]
region = ap-northeast-1
```


```credential
[default]
aws_access_key_id = *********************
aws_secret_access_key = *********************

[company]
aws_access_key_id = *********************
aws_secret_access_key = *********************
```

### ・プロファイルの追加

例えばcompanyで設定されているアカウントからスイッチロールしたい場合、configファイルを以下のように編集します(今回はロールの名前をsandboxとします)

```
[profile sandbox]
region = ap-northeast-1
role_arn = ロールの情報
source_profile = company(例えば、会社のアカウントならsource_profileを先ほど設定したcompanyにする)
```

確認用:

```
aws s3 ls --profile sandbox
```

ここまでできると、複数のAWSアカウントやロールを使ってaws-cliを使えるようになると思います。ただし、色んなプロファイルを扱うときは--profile指定をしないといけないので、忘れないように注意してください。

### 参考URL
https://blog.serverworks.co.jp/2021/03/15/093953
OpenID Connectの簡単な説明


## OpenID Connectとは何か
あるシステムが外部のIDプロバイダー（IdP)にユーザを識別と認証をしてもらう時の、システム間のやりとりの仕方を標準化したもの。
OpenID ConnectをサポートしたIdPを利用することで、利用側はIdPがユーザの識別と認証をした結果としてのユーザ識別子をid_tokenという形式で得ることができます。
またクライアント側で必要であれば、IdPが持つユーザ情報(userinfo)を取得することができます。

## ユーザの識別と認証とは
ユーザの識別とはある特定のユーザであると見分けることです。
よくあるログイン画面ではメールアドレスをIDとして入力しますが、そのケースではメールアドレスをもって識別することになります。
認証とは、パスワードの一致の確認など、色々な手段を用いて、アクセスしてきたユーザがある特定の人（メールアドレスなどで識別された人）であることを確認することです。

## id_token
OpenID Connectではユーザ識別子はID TokenというJSONの形でIdPが発行します。
ID TokenはJSONなのでissやsubといったユーザ識別子としての重要データの他、ID TOKEN発行元情報やID TOKEN発行時間などが含まれていて、利用側がID TOKENの受信時に妥当性を確認できるようになっています。

## OpenID Connectには関係ないもの
以下のものはOpenID Connectの規格とは関係ありません。

### ユーザアカウント作成
OpenID Connectは認証に関するシステム連携の仕方しか規定していません。
アカウント作成は認証に先立って行う必要がありますので、OpenID Connectの規格の範囲外です。

### 認証方法
OpenID Connectでは認証を外部にお願いしたいサービス(Client)と、ユーザ識別子を外部に提供するサービス(IdP)との間の、ユーザ認証依頼〜ユーザ識別子が提供されるまでの連携方法しか規定してません。パスワード認証や指紋認証といった認証自体の方法は規定していません。規格の範囲外です。

### セッション管理
OpenID ConnectをサポートするIdPが、それを利用するサービスのセッションを管理してくれることはありません。
例えばECサイトがGoogleログインを実装する場合、当たり前ですがECサイトのセッションはECサイト側で作成、管理する必要があります。

### マイクロサービスのセキュリティ
OpenID Connectでは「トークン」や「JWT」といった、マイクロサービスでのセキュリティに関する実装に使われる用語が出てくるので勘違いされる方もいますが、OpenID Connectという規格はマイクロサービス間の通信のような「1つのサービス内でのシステム間連携」には関係ありません。
また、OpenID Connectの規格がベースとしているOAuth2は認可（データアクセス権の制御）の仕組みを規定していますが、OpenID Connectは利用側のシステムの認可についても関係ありません。
Transformersの__init__() got an unexpected keyword argument 'prediction loss only'エラーを解決した件について

# はじめに
Huggingface Transformersを勉強しているのですが、Transformersが新しくなったようで、公式に乗っているコードも動かないものが多く、そちらの対処をしましたので記事にします。

私はこちらの[記事](https://note.com/npaka/n/nad450e772a84)を動かしている途中でエラーに遭遇しました。

https://note.com/npaka/n/nad450e772a84


# 問題
以下のコードで学習を実行したところ

```
# 学習
!python transformers/examples/language-modeling/run_language_modeling.py \
    --output_dir=output \
    --model_type=gpt2 \
    --model_name_or_path=gpt2 \
    --do_train \
    --train_data_file=train.txt \
    --do_eval \
    --eval_data_file=eval.txt \
    --per_device_train_batch_size=2 \
    --per_device_eval_batch_size=2 \
    --num_train_epochs=10 \
    --save_steps=5000 \
    --save_total_limit=3
```

以下のようなエラーがでた

```
__init__() got an unexpected keyword argument 'prediction loss only'
```

# 解決方法
[こちらの記事](https://www.gitmemory.com/issue/huggingface/blog/72/785454524)を参考に対処を行っていました。

`transformers/examples/legacy/run_language_modeling.py`を開いて以下の行をコメントアウトします。

```
# 318行目
# prediction_loss_onlyをコメントアウトする
    # Initialize our Trainer
    trainer = Trainer(
        model=model,
        args=training_args,
        data_collator=data_collator,
        train_dataset=train_dataset,
        eval_dataset=eval_dataset,
        # prediction_loss_only=True,
    )
```

# おわりに
`prediction_loss_only=True`が何を表しているのか、理解できていないのでがんばりたいです。
なんとか記事通りに動きました。めでたしめでたし。


# 参考サイト
https://note.com/npaka/n/nad450e772a84?magazine_key=mdf3ce11e35b9
https://www.gitmemory.com/issue/huggingface/blog/72/785454524
LeetCode日本語修行15日目- [633-平方数の総和]

###Sum of Square Numbers
参考：https://leetcode.com/problems/sum-of-square-numbers/
###問題の内容:
非負の整数c、a2＋b2＝cの条件を満足の整数a、bがあるかどうかを判断する。

###例:
例1:
Input: c = 5
Output: true
Explanation: 1 * 1 + 2 * 2 = 5

例2:
Input: c = 3
Output: false
###ヒント:
0 <= c <= 231 - 1

---

この問題は、普通のループを使って、解決できますが、
DoublePointerを使う方がいいと思います。
条件は：
0 <= a*a + b*b <= c
0 <= a,b <= sqrt(c)

```Kotlin
class Solution {
    fun judgeSquareSum(c: Int): Boolean {
        var a = 0
        var b = Math.sqrt(c.toDouble()).toInt()
        while(a <= b){
            when{
                a * a + b * b == c -> return true
                a * a + b * b > c -> b--
                else -> a++
            }
        }
        return false
    }
}

```
TransformersのAttributeError: 'Trainer' object has no attribute 'is_world_master'エラーを解決した件について

# はじめに
Huggingface Transformersを勉強しているのですが、Transformersが新しくなったようで、公式に乗っているコードも動かないものが多く、そちらの対処をしましたので記事にします。

私はこちらの[記事](https://note.com/npaka/n/nad450e772a84)を動かしている途中でエラーに遭遇しました。

https://note.com/npaka/n/nad450e772a84

# 問題

```
# 学習
!python transformers/examples/language-modeling/run_language_modeling.py \
    --output_dir=output \
    --model_type=gpt2 \
    --model_name_or_path=gpt2 \
    --do_train \
    --train_data_file=train.txt \
    --do_eval \
    --eval_data_file=eval.txt \
    --per_device_train_batch_size=2 \
    --per_device_eval_batch_size=2 \
    --num_train_epochs=10 \
    --save_steps=5000 \
    --save_total_limit=3
```

```
AttributeError: 'Trainer' object has no attribute 'is_world_master'
```
# 解決方法

[こちらの記事](https://github.com/huggingface/transformers/issues/8995)によると、transformersのバージョンが古いとのこと。どうしてもやる場合は以下の対応で可能とのことでした。

`is_world_master`を`is_world_process_zero`に変更することでエラーがなくなります。

具体的には`./transformers/examples/legacy/run_language_modeling.py`の以下の行を変更しています。

```
# 332行目

if trainer.is_world_process_zero():

# 346行目
if trainer.is_world_process_zero():
```

# おわりに
`is_wold_process_zero`を使わず、バージョンを上げて対応させたほうがよいそうなのですが、Gitからcloneしている場合は、`run_language_modeling.py`を使わない方法をとる必要がありそうです。詳しい方はコメントいただけると嬉しいです。

# 次回

次に起きるエラーはこちらで対応しています。

https://qiita.com/Sicut_study/items/dc7f729525653217149f



# 参考
https://note.com/npaka/n/nad450e772a84?magazine_key=mdf3ce11e35b9
https://github.com/huggingface/transformers/issues/8995
TransformersのAttributeError: 'gpt2tokenizerfast' object has no attribute 'max_len' エラーを解決した件について

# はじめに
Huggingface Transformersを勉強しているのですが、Transformersが新しくなったようで、公式に乗っているコードも動かないものが多く、そちらの対処をしましたので記事にします。

私はこちらの[記事](https://note.com/npaka/n/nad450e772a84)を動かしている途中でエラーに遭遇しました。

https://note.com/npaka/n/nad450e772a84

# 前回
このエラーの前に遭遇したエラーについては以下の[記事](https://qiita.com/Sicut_study/items/e12b605f2d0d5ad7abc1)をご参考ください。

https://qiita.com/Sicut_study/items/e12b605f2d0d5ad7abc1


# 問題
以下のコードで学習を始めるとエラーが発生します。

```
!python transformers/examples/legacy/run_language_modeling.py \
    --output_dir=output \
    --model_type=gpt2 \
    --model_name_or_path=gpt2 \
    --do_train \
    --train_data_file=train.txt \
    --do_eval \
    --eval_data_file=eval.txt \
    --per_device_train_batch_size=2 \
    --per_device_eval_batch_size=2 \
    --num_train_epochs=10 \
    --save_steps=5000 \
    --save_total_limit=3
```

実行途中で以下のエラーがでます。

```
AttributeError: 'RobertaTokenizerFast' object has no attribute 'max_len'
```

max_lenがないそうです。

[こちらの記事](https://github.com/huggingface/transformers/issues/8739)によると、記事に利用されていた`run_language_modeling.py`が非推奨となっており、`language-modeling/run_{clm, plm, mlm}.py`に切り替わっているとのことでした。

そもそも私はtransformersがわからない状態でハンズオン代わりに勉強しているため、切り替わったほうの使い方がわからないため、修正する方法で`run_language_model.py`を使うことにします。

(使い方がわかる方はコメントお待ちしております)

# 解決方法
`./transformers/examples/legacy/run_language_modeling.py`に`max_len`が２ヵ所あるので`model_max_length`に変更する。

```
# 280行目
data_args.block_size = tokenizer.model_max_length
```

```
# 282行目
    else:
        data_args.block_size = min(data_args.block_size, tokenizer.model_max_length)
```
# おわりに
だいぶコードが古くなっているようで、公式のハンズオンも動かないことが多く大変です。
推奨されている方法で同じことを実行できるようになりたいものです。

# 次回

次に起きるエラーはこちらで対応しています。

https://qiita.com/Sicut_study/items/f2399ad2b2687a67f8e5


# 参考サイト
https://github.com/huggingface/transformers/issues/8739
https://www.gitmemory.com/issue/huggingface/blog/72/785454524
Transformersのexamples/run_language_modeling.pyが見つからない件について

# はじめに
本日はHuggingface Transformersの[記事](https://note.com/npaka/n/nad450e772a84)を読み、同じコードを`Google Colabratory`で動かしていた際にファイルがないというエラーが発生したので、そちらを解決していきます。Transformersは大きな変更があったようで、公式のコードも動かないものが多いです。

[記事](https://note.com/npaka/n/nad450e772a84)のコードは3か所エラーが出ますので、次のエラーの解決方法は最後に紹介する[記事]()を確認して下さい。

私が行っていた記事は以下の記事となります。

https://note.com/npaka/n/nad450e772a84

# 環境
Google Colabratory

# 問題

```
python3: can't open file 'transformers/examples/run_language_modeling.py': [Errno 2] No such file or directory
```

ファイルが存在しないと言われて確認してみるとありませんでした。

# 解決方法

リポジトリが更新されてファイルの場所が変わっているようなので以下のコマンドで探しました。

```
!find ./transformers/ -type f -name "*run_language_modeling.py"
```

すると以下の返答が返ってきました。

```
./transformers/examples/legacy/run_language_modeling.py
```

どうやら記事が古いらしく、`./transformers/examples/legacy/run_language_modeling.py`にありました。

# おまけ
記事で推論を行うコードはこちらを利用しています。

```
!python transformers/examples/pytorch/text-generation/run_generation.py \
    --model_type=gpt2 \
    --model_name_or_path=output \
    --prompt "山田太郎。日本の小説家。 " \
    --seed=${RANDOM} \
    --length 1000
```

`run_generation.py`の場所も変わっておりました。
正しいファイルの位置は`transformers/examples/pytorch/text-generation/run_generation.py`です。

# おわりに
たくさんファイルがあるので、そもそも`run_language_modeling.py`があるのか心配でしたが、`find`を使うことで探すことができました。UNIXコマンドは使えるようになると便利なので覚えていきたいです。

# 次回


# 参考サイト
https://note.com/npaka/n/nad450e772a84
メソッドからオブジェクト指向へ

***
###■　メソッドを分けることについて
######　なぜ必要なのか
・可読性（読みやすさ）
・柔軟性（修正のしやすさ）
・再利用性（使いまわしやすさ）
mainメソッド内にすべてのソースコードを記述して把握しきれるような業務システムはまず存在しないだろう
例えばATMのシステムをイメージとして考えたときに

・受付（50行）
・残高問合せ（50行）
・入出金（50行）
・振込（50行）

という4つの仕事をするものとして、これらすべてのソースコードを、実行するmainメソッド内に記述し、修正が必要となった場合に、まずこれら200行のコードの中から修正箇所を探さなければならない
通常の数千、数万行にもなる業務システムでは尚更大変な作業となる

受付メソッドや残高問合せメソッドのように部品化しておくことで、修正範囲もある程度特定ができ、プログラム全体も分割した部品の組み合わせであるため見やすくなる

またコードを書いていて同じ作業をさせたい部分が出てくれば、同じメソッドを再利用して余計なコードを記述せず、手間も省くことができる、ということ


以下、渡した2つの引数を足して戻すだけの計算メソッド

```Java
public static void main(String[] args) {
    int sum1 = calc(10, 20);
    System.out.println(sum1);

    int sum2 = calc(20, 40);
    System.out.println(sum2);

public static int calc(int a, int b) {
    int ans = a + b;
    return ans;
    }
}

```

***
###■　クラス、パッケージに分ける
メソッド分けしても増えすぎれば読みづらいことには変わらないため、クラスやパッケージとしてまとめることで解消する
以下、mainメソッドのクラス、渡された引数で足し引きのみ行うクラス、掛ける割るのみ行うクラスに分類
######【mainメソッドのクラス】

```Java
public class Calc {
    public static void main(String[] args) {
            int plus = Plussub.tasu(10, 20);
            System.out.println(plus);

            double division = Muldiv.waru(10, 20);
            System.out.println(division);
    }
}
```

######【加算減算クラス】

```Java
public class Plussub {
    public static int tasu(int a, int b) {
        int plus = a + b;
        return plus;
    }

    public static int hiku(int a, int b) {
        int subtraction = a - b;
        return subtraction;
    }
}
```
######【乗算除算クラス】

```Java
public class Muldiv {
    public static int kakeru(int a, int b) {
        int multiplication = a * b;
        return multiplication;
    }

    public static double waru(double a, double b) {
        double division = (a / b);
        return division;
    }
}
```

メソッドをクラス分けするとmainメソッドのクラスからはスコープの外になるため、クラス名．メソッド名で指定して呼び出す必要がある

また同じ要領でパッケージ分けした際にはパッケージ名．クラス名．メソッド名（完全修飾名）で呼び出すかインポートする必要がある


***
###■　オブジェクト指向に沿った部品化
これまでは、あくまでmainメソッド内の作業を他のメソッドやクラスとして分割していただけだが、オブジェクト指向はより可読性、柔軟性、再利用性を向上させるために、ヒトやモノなど現実世界のものになぞらえてクラスに分割し、プログラムを作成するという考え方
各オブジェクトはそれぞれプログラムに対して負うべき責任を持ち、それに対してフィールド（属性）とメソッド（振る舞い）が定義される
部品化というが、正確には部品（オブジェクト）そのものではなく、クラスという設計図を定義する
mainメソッドを持つクラスはその設計図を生み出し（インスタンス化し）動かす。

以下、自己紹介をする人の設計図であるHumanクラスをmainメソッドを持つクラスでインスタンス化させ、TanakaとYamadaという2つ（人）のオブジェクトを生成させる

######mainメソッドを持つクラス
```Java
public class Main {
    public static void main(String[] args) {
        Human h1 = new Human();
        h1.name = "Tanaka";
        h1.age = 25;
        h1.address = "Tokyo";
        h1.hp = 100;
        h1.greet();

        Human h2 = new Human();
        h2.name = "Yamada";
        h2.age = 28;
        h2.address = "Kanagawa";
        h2.hp = 130;
        h2.greet();
    {
{
```

######【自己紹介するHumanクラス】
```Java
public class Human {

    String name;
    int age;
    String address;
    int hp;

    public void greet() {
        hp = hp - 10;
        System.out.print("My name is " + name + ".");
        System.out.print("I'm " + age + " years old.");
        System.out.print("I live in " + address + ". ");　
　      System.out.println("Current HP is " + hp + ".");
    }
}
```

指定した情報を受け取って自己紹介を行うという「責務」を持つ
【Unity】VRのアイテムスロットを作る

# はじめに

Snap Zone（スナップゾーン）とは，オブジェクトを指定した位置や角度で設置できる空間のことです．VRゲームでは，例えば，鍵穴に鍵をはめこんだり，アイテムスロットにアイテムを収納したりする処理に使われます．

https://learn.unity.com/tutorial/snap-zones#

VRでは主にVRTKやXR Interaction Toolkitなどのライブラリを用いて実装されることが多いですが，今回はOculusの開発で使う**Oculus Integrationの機能だけを使って実装しました**．

完成形は以下のようになります．掴んだオブジェクトをスナップゾーンの近くで放すと，オブジェクトが所定の位置と角度に固定されます．固定されているオブジェクトを再び掴めば取り出せます．

![snap-test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263889/0060bfcb-98f7-4295-3288-2af22fff10a3.gif)


# 環境
- Unity 2019.4.11f1
- Oculus Quest 2
- Oculus Integration 23


# スクリプト

以下のようなスクリプトを作成します．オブジェクトをスナップゾーンの中で手放したら，そのオブジェクトをスナップします．

```SnapZoneTest.cs
using UnityEngine;

public class SnapZoneTest : MonoBehaviour
{
    private bool isGrabbing;
    private bool isSnapped;
    public Transform snapPosition;

    private void OnTriggerStay(Collider other) {
        GameObject target = other.gameObject;

        if (target.GetComponent<OVRGrabbable>()) {
            isGrabbing = target.GetComponent<OVRGrabbable>().isGrabbed;
            if (isGrabbing) {
                isSnapped = false;
                target.GetComponent<Rigidbody>().isKinematic = false;
                GetComponent<MeshRenderer>().enabled = true;
            }

            if (!isSnapped) {
                if (!isGrabbing) {
                    target.GetComponent<Rigidbody>().isKinematic = true;
                    // スナップ時にはスナップゾーンを見えなくする
                    GetComponent<MeshRenderer>().enabled = false;
                    // 位置と角度をスナップ
                    target.transform.position = snapPosition.position;
                    target.transform.rotation = snapPosition.rotation;
                    isSnapped = true;
                }
            }
        }
    } 
}
```

# 使い方

シーンに以下のようにオブジェクトを配置します．
![スクリーンショット 2021-02-27 122013.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263889/0621e4c4-3561-0ef2-f8a5-348317097a50.png)

- OVRCameraRig
    - コントローラーに`OVRGrabber`をアタッチして，オブジェクトを掴めるようにしておきます．
        - 参考 (https://raspberly.hateblo.jp/entry/OculusQuestGrabberGrabbable)
- GrabbableObject
    - `OVRGrabbable`をアタッチして，掴めるオブジェクトとして設定します．
- SnapZone
    - 上記の`SnapZoneTest`というスクリプトをアタッチします．`SnapPosition`プロパティにはオブジェクトをスナップする位置を指定します．今回はスナップゾーン自身を指定しています．そのほかに何らかのColliderも必要です．また，今回はスナップゾーンであることがわかりやすいように透明なマテリアルを設定しています．

![スクリーンショット 2021-02-27 122352.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263889/db955ce8-cf74-3e16-a13a-ae7187a03e2e.png)

シーンビューは以下のようになっています．これでコントローラーで`GrabbableObject`を掴み，スナップゾーンの付近で手放すと，吸い寄せられるようにオブジェクトがスナップされるようになります．
![スクリーンショット 2021-02-27 122532.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263889/8785a9b7-efd3-68a1-2a2a-a00342e6b7cf.png)
Rails & Reactアプリ制作で参考にしたリンク集（Rails編）（随時更新）

<h2>Devise(gem)</h2>
https://qiita.com/tomokazu0112/items/5fdd6a51a84c520c45b5#%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3

https://qiita.com/ShotaImoto1/items/3fe92a6d4498f3f93b71

https://www.ryoblg.com/blog/post/devise-token-auth-rails-api/

https://github.com/heartcombo/devise/blob/master/app/controllers/devise/sessions_controller.rb

https://zenn.dev/kitabatake/articles/start-to-like-the-devise#%E3%83%AD%E3%82%B0%E3%82%A2%E3%82%A6%E3%83%88%E5%87%A6%E7%90%86


<h2>active_model_serializers</h2>

https://qiita.com/onikan/items/d24ce08adf144c326812

<h2>SSL(mkcert)</h2>

https://qiita.com/acannie/items/457bb2a8e2cc843f991e

https://note.com/miyazi777/n/n9482e7bc1882

https://ja.stackoverflow.com/questions/55929/rails-s%E6%99%82%E3%81%ABaddress-already-in-use%E3%81%A8%E8%A8%80%E3%82%8F%E3%82%8C%E3%82%8B%E3%81%8C-lsof%E3%81%A7%E3%81%AF%E4%BD%BF%E7%94%A8%E4%B8%AD%E3%83%9D%E3%83%BC%E3%83%88%E3%81%AB%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84

https://github.com/puma/puma/issues/1339

<h2>Subdomain</h2>

https://qiita.com/tatsumin0206/items/8b4d0930c0f58cef7813

https://note.com/emetselch1984/n/n7dc886b3d4ca

<h2>omniauth</h2>

https://github.com/lynndylanhurley/devise_token_auth/blob/master/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb

https://teratail.com/questions/149601

https://qiita.com/d0ne1s/items/e1ee23ea23343d6aaa34

https://qiita.com/togo_mentor/items/f5bbca8eb84354e5e32b

https://qiita.com/dl10yr/items/a338ca956090237d8ca6#%E5%8F%82%E8%80%83%E8%A8%98%E4%BA%8B

<h2>git</h2>

<h3>fatal: object {hash} is corrupt</h3>
https://bokunonikki.net/post/2018/0910_git_object_empty/

https://stackoverflow.com/questions/39409252/how-to-fix-git-error-head-invalid-reflog-entry-xxxxxxxxxxxxxxxx

<h2>heroku</h2>

https://qiita.com/at-946/items/6958b1d35330c87b8e50

https://qiita.com/tsuboyataiki/items/47cbdae2f87cd5ca9ffe
Linuxのローカライゼーション

lpicの勉強をしていて普段ロケールを使うことがないので忘れないようにまとめます。
#ローカライゼーション
ローカライゼーション(localization)とは言語や通貨の単位、日付の書式などを国や地域に合わせること。
これを国際化(internationalization)と言う。(i18n)と略される。

#主なロケール
###カテゴリ
lpicの本でピックアップされているロケールのカテゴリをまとめます。

LC_CTYPE : 文字の種類などの規定
LC_COLLATE : 文字の照合や整列に関する規定
LC_MESSAGES : メッセージ表示に使用する言語
LC_NUMERIC : 数値に書式に関する規定
LC_TIME : 日付や自国の書式に関する規定

環境変数```LC_ALL```を使用すると全てのカテゴリでその値が使われる。```LANG```が設定されていれば全てのカテゴリでその値が使われるが、個々の設定が可能(デフォルト値のような感じ)。

###ロケール名
C, POSIX : 英語
ja_JP.utf8(ja_JP.UTF-8) : 日本語/Unicode
ja_JP.eucJP : 日本語/EUC-JP
ja_JP.shiftJIS : 日本語/シフトJIS
en_US.utf8 : 英語(米)Unicode

localeコマンドを使うと現在のロケールを表示する。
```-a```オプションで設定可能なロケールの表示。
```-m```で利用できる文字コードの表示。
![Screen Shot 2021-04-28 at 21.59.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722539/f05d99a1-1190-df78-c4f3-c6232606240e.png)

その他のロケール名。

https://docs.oracle.com/cd/E26924_01/html/E27144/glset.html

###ロケールの一時的な変更
```変数名=ロケール名 コマンド```のように指定する。
例えば一時的に英語にしたい場合。

```
LANG=C man ls
```
とするとlsのマニュアルを英語で表示する。

#文字コード
これも本にまとめられているもののみ載せます。

ASCII : 7ビットで表される基本的な128種類の文字。
ISO-8859 : ASCIIを拡張した8ビットの文字コードで256種類の文字。
UTF-8 : Unicodeを使用した文字コードで、1文字を1~6バイトで表す。
EUC-JP : UNIX環境で標準的に利用されていた日本語の文字コード。
SHIFT-JIS : Windowsで利用される日本語の文字コード。
ISO-2022-JP : 電子メールなどで使用される日本語の文字コード(JISコード)。

文字コードの変換には```iconv```コマンドを使う。

```
iconv -f 文字コード -t 文字コード ファイルなど
```
オプションは、```-f```はfrom。```-t```はtoなどで覚えられそう。
```iconv -l```で扱える文字コードの一覧を表示できる。
ファイルの文字コードが不明な場合、```nkf -g ファイル名```で文字コードを確認できる。

**間違いがございましたらご指摘ください。**
LeetCodeWeekly 237 1834. Single-Threaded CPU プライオリティキュー典型


https://leetcode.com/contest/weekly-contest-237/problems/single-threaded-cpu/

# 題意
* $n$個の仕事がありそれぞれ、$a,b,c$のパラメータを持つ．
* aは$0..n-1$個目の仕事であるという仕事のindexである
* bは仕事に着手してもいい開始の時間である．つまり、その時間以上になるまで、その仕事は実施できない
* cはその仕事にかかる時間である
* ある瞬間、終わっていない仕事があるなら、cが最小、cが同じならaが最小のものから仕事に取り組む．これらの仕事の着手順序をインデックス(=a)で答えよ

# こう考えた

まず、単にシミュレーションを行う問題であることは題意より明らかである．
２つのキューを持つことにする.
- $q1:まだ実施できない仕事の候補$．これらは、b(実施可能なる時間)が小さいものから取り出せるべきである．
- $q2:現在時刻として着手できる仕事の候補$．これらは、実施時間(c)が小さいものから取り出されるべきであり、その中でも、インデックス(a)が小さいものから取り出せるべきである．

これが準備できれば、時間を持ちつつ、$q2$のタスクを取り出し時間を経過させて、$q1$から実施できるタスクを取り出していけばいい．
注意は、$q2$がからの場合は$q1$からタスクを１つ取り出し、時間をそこに進める必要がある点か．

```Python3
class Solution:
    def getOrder(self, tasks: List[List[int]]) -> List[int]:
        from collections import deque
        from heapq import heapify, heappop, heappush
        turn = 0
        madamadatask = []
        heapify(madamadatask)
        korekaraq = []
        heapify(korekaraq)
        for i in range(len(tasks)):
            enque, needtime = tasks[i]
            heappush(madamadatask, (enque,needtime, i))
        # madamada taskは全体のタスクをenqueの順番に並べたもの．
        # 実施するタスクではなくて、今後実施できるようになるタスク
        curtime = -1
        res = []
        # korekarataskはすでに実施できて、どれを実施するか迷うもの．
        # これは、条件の通り、needtimeが最小、同じ場合はindexが最小の物を取り出す
        while len(madamadatask) != 0 or len(korekaraq) != 0:
            if len(korekaraq) == 0: # キューに仕事がないなら新しい仕事が必要．
                # この場合、現在の時間に関係なく１つ取り出し、時間を開始時間まで飛ばす
                enque, needtime, index = heappop(madamadatask)
                heappush(korekaraq, (needtime, index, enque) )                #
                curtime = enque
                continue
            # やるべき仕事がある場合、それを実施する
            needtime, index, enque  = heappop(korekaraq)
            if curtime < enque:
                curtime = enque
            curtime += needtime
            res.append(index)
            # ここで時間は現在の実施後まで飛んでいるので、
            # それで実施可能になった仕事をキューに入れる
            while len(madamadatask) > 0:
                enque, needtime,  index = heappop(madamadatask)
                if enque > curtime:
                    heappush(madamadatask, (enque ,needtime, index))
                    break
                heappush(korekaraq, (needtime, index, enque) )
        return (res)
```

https://leetcode.com/contest/weekly-contest-237/submissions/detail/481988019/
【分子動力学】PLUMED入門 その1. インストール

#はじめに
これから数回に渡ってPLUMEDのチュートリアルを実行し、計算済みのトラジェクトリーに対して集団変数（CV）を計算する。
本記事ではまずPLUMEDでパッチを当てたGROMACSをインストールする。

#参考

https://www.plumed.org/doc-v2.6/user-doc/html/master-_i_s_d_d-1.html

#インストール方法
本記事では参考リンクにしたがい、condaを使ったお手軽な方法でGROMACS＋PLUMEDをインストールする。
本格的なインストールをしたい方は他の記事を当たってください。

なお、anacondaをインストール済みであるとする。
本チュートリアル用の環境を作成する。

```bash
# create environment
conda create --name ISDD-tutorial
# activate environment
conda activate ISDD-tutorial
```

以下のコマンドでGROMACS+PLUMEDをインストールする

```
conda install -c plumed/label/munster -c conda-forge gromacs
```

インストール途中で

```
    gromacs-2018.8             |       h3fd9d12_1         7.6 MB  plumed/label/munster

```
という記述があるので、PLUMEDでパッチを当てたgromacs-2018.8と思われる。

インストールできているか確認したければ以下を実行する

```
gmx mdrun -h
```

-plumedのオプションがあることも確認できる。


注意点として、新しくターミナルを立ち上げるときは必ず

```
conda activate ISDD-tutorial
```

を行うこと。
conda activateができない

# 概要
linux, condaで新しい仮想環境を作ろうとしたらconda activateコマンドが動かなかったのを解決した備忘録。多分ちゃんと正しい方法ではないので今度ちゃんと作り直そう。

# 環境
Ubuntu 18.04
python 3.8
pyenv
anaconda (miniconda3-4.7.12)


# レベル
導入レベル



# 解説
anacondaとpyenvはいっつも競合する。そして解決しては忘れる。もう嫌だ。


### 問題

普通、仮想環境は次のコマンドで作れる

```python
conda create -n test # testという名前の仮想環境を作成
conda activate test # 仮想環境をtestに切り替え
```
しかし、

```
home ❯ conda activate test
CommandNotFoundError: 'activate is not a conda command.
Did you mean 'source activate'?
```
通らない...

調べたところ、condaとpyenvの競合によるものらしい。


そして、言われるがままsourceを使っても、

```
home ❯ source activate test
pyenv-virtualenv: version 'test' is not a virtualenv
```

virtualenvの環境ではないと言われる。

そんなものいつ入れたっけ...

多分最初に入れていた。


##### 作った仮想環境の確認
pyenv+virtualenvとcondad作った仮想環境、それぞれを確認する

condaの仮想環境を確認

```python
conda info -e
```

pyenv+virtualenvの仮想環境を確認

```python
pyenv virtualenvs
```

両者は全く別物だとわかる。



### 解決方法

作る仮想環境は一つにまとめた方がいい。
今回はpyenv+virtulenvで作ることにする。

ちなみに、インストールしているpyenvのバージョンはminiconda3-4.7.12。最新のものを取得。

testという名前の仮想環境を作成。

```python
pyenv virtualenv miniconda3-4.7.12 test
```

インストールが進む...

```
Collecting package metadata (current_repodata.json): done
Solving environment: done
...

# To activate this environment, use
#
#     $ conda activate test
#
# To deactivate an active environment, use
#
#     $ conda deactivate

...

```


condaでactivateしろと言われるが無視。

pyenv-virtualenvの仮想環境切り替えはpyrnv localで行う。


```python
pyenv local test
```
切り替わっている

```python
(base) test ❯ 
```

解決！



## 参考
https://qiita.com/m3y/items/45c7be319e401b24fca8


https://www.medi-08-data-06.work/entry/python_env


https://uxmilk.jp/43185
Gmailで既読のメールを自動アーカイブする

メールボックスを重要なメールややり取りの最中のものだけ残してきれいにしておくと、気が散らなくていいということに気づき、実践しています。ところが、パソコン版は一括選択できて簡単にまとめてアーカイブできるものの、スマホ版だといちいち一個ずつ選択しなければアーカイブできず、それが面倒でした。
これを改善するため、「既読かつ☆マークがついていないメールをアーカイブする」スクリプトを組みました。
## コピペすれば動くやつ

```js
const main = () => {
  const inboxThreads = GmailApp.getInboxThreads()
  const shouldArchivedThreads = inboxThreads.filter(thread => !thread.isUnread() & !thread.hasStarredMessages())
  archiveThreads(shouldArchivedThreads)
}

const archiveThreads = (threads) => {
  threads.forEach(thread => thread.moveToArchive())
}
```

## 使い方

1. コピペする
2. 保存する
2. タイマーのマークからトリガーを設定する。僕は一日一回に設定しましたが、毎時または毎分でも問題なく動作します。ただし、スターマークをつける前にアーカイブされるとこまるので、あまり頻度は上げないほうがいいと思います。

## ちょっと解説
`getInboxThreads()`を使うことで、受信箱の全てのスレッド（メールに対する返信などをまとめたもの）を取得しています。次の行でそれぞれのthreadsの中に未読のものがないか(`isUnread()`)と☆がついているものがないか（`hasStarred()`）確認します。
ちなみに、jsやgasの初心者の人は下記のコードの方がわかりやすいと思います。

```js
const main = () => {
  const inboxThreads = GmailApp.getInboxThreads()
  inboxThreads.forEach(threads => {
    if (!thread.isUnread() & !thread.hasStarredMessages()) {
      thread.moveToArchive()
    }
  })
}
```

やっていることは同じです。僕の場合inboxから全て取得ではなくいろいろなボックスやくくりから取得して、それぞれをアーカイブしたり削除したりを分けることも考えていたため、機能を分離するという目的のために`archiveThread()`関数に書き出していましたが、inboxから取得してアーカイブするだけならこのコードの方がいいと思います（繰り返しますが同じことができます）
カウントボタンの書き方

Vue.jsでクリックすると数が増えていくカウントボタンの書き方をメモとして残しておこうと思います。

```App.vue
<template>
  <div id="app">
    <button v-on:click="number += 1">ボタン</button>
    <h1>{{ number }}回</h1>
  </div>
</template>

<script>
export default {
  data: function() {
    return {
      number: 0 ,
    }
  },
};
</script>
```
以上です。
MIB情報 とは

## 勉強前イメージ

本当に聞いたことない...
ITの用語的なのでちらっと見たくらい

## 調査

### MIB情報 とは

Management Information Base の略で みぶ と読みます。
MIB とはSNMPで機器を監視する際に用いられる、自分のデータの集合や規格のことです。
SNMPマネージャー(監視を行い管理するサーバ)とSNMPエージェント(監視対象サーバ)でのやり取りに使用しています。
MIBにより分類された情報はツリー構造で管理されています。

### SNMP とは？

Simple Network Management Protocol の略で
ネットワーク監視・管理を行うためのプロトコルです。
ネットワーク機器・サーバ機器の監視やリソース監視、トラフィック監視を行うために使用します。
ベンダーによって固有の管理項目を公開しているところもあり、詳細な監視を行うこともできます。

イメージとしては以下です。
マネージャーがエージェントに値を要求し、エージェントはマネージャーに値を返します。

![1# MIB情報 とは - diagrams.net - Google Chrome 2021-04-.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/289b2d40-a106-61d7-9ab2-e9b96b4d64e8.png)

一般的なSNMPエージェントはRFCで定義された管理情報を実装していて、
マネージャーは基本的にはその定義された管理情報を要求します。
それが、MIB情報です。

### MIBの種類

MIBには `標準MIB` と `拡張MIB` があります。

- 標準MIB

標準MIB は標準化され汎用的に使われてるMIBです。
いくつかグループがありますが、
例えば システムのホスト名 だったり、 管理者の連絡先 なども標準化されています。
また標準MIBの中には MIB1, MIB2 がありますが、
MIB1 からの見直しが入ったものが MIB2なので MIB2が現在主流で使われています。

- 拡張MIB

ベンダーMIB や プライベートMIB と呼ばれることがありますが、ベンダーごとに定義されたMIBになります。
例えばciscoのネットワーク機器の機器情報などを取得したい際は、
ベンダーごとに定義されているデータを使用するので拡張MIBを使用します。

## 勉強後イメージ

なんとなくそういう情報を持ってるっていうのは知ってたけど名称を知ったのは初めて。
特にネットワーク機器とかは機器によって操作方法とかも違うし。。
なので、その時にMIBの情報さえあればそれでやり取りができるのかー

## 参考

- [ネットワーク監視の超基本「SNMP」とは？](https://blogs.manageengine.jp/itom_what_is_snmp/)
- [SNMP入門](https://blogs.manageengine.jp/snmp/)
- [TCP/IP - SNMP](https://www.infraexpert.com/study/tcpip21.html)
Dart（Flutter）で2つの配列を結合する

## 概要
例えばJavaScriptでの、[Array.prototype.concat()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/concat)のように2つの配列を結合して返すようなメソッドがDartであるか。やりたいことはシンプルなのですが、日本語だとなかなかドンピシャの記事がなくて、少し探すのに苦労したのでメモ書きとして残しておきます。

## 対応
[How do I combine two lists in Dart?](https://stackoverflow.com/questions/21826342/how-do-i-combine-two-lists-in-dart)の記事に色々と方法が書いてあるのですが、Dart2以降であれば`+`記号を使うことで結合ができるので、これが一番シンプルな書き方かなと思います。以下のような感じで元の配列に影響を与えず、結合後の配列を取得することが可能です。

```dart:sample.dart
var list1 = [1, 2, 3];
var list2 = [4, 5, 6];

var newList = list1 + list2;

```
[SwiftUI]モディファイアとは（初学者向け）

## モディファイアとは
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("Hello, Udemy")

            //以下.（ドット）で始まるコードがモディファイア
            .font(.title)
            .fontWeight(.medium)
            .foregroundColor(Color.blue)
            .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

```

`上記コードのように.（ドット）〜を付け足すことでUIを変更するものをモディファイアと呼びます。`
今回の場合は、Text("Hello, Udemy")に対してモディファイアを適応しています。
絶対補完させたいブラウザ VS 絶対補完させたくない開発者

※Chromeバージョン: 90.0.4430.93で行ったときの記事になります。

#ブラウザの自動補完機能について
サイトにログインした時などに出るこれです。（以下はChromeの場合）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318640/0cea6641-ba06-4ff4-4f73-02e0a26cd882.png)

入力したIDとパスワードを保存し、次回以降のログイン時に自動でIDとパスワードを補完してくれるとても便利な機能です。

ただ、パスワードが変更できる画面やユーザーを新規登録する画面のIDとパスワードの部分など、してほしくないところまで補完をしてくれるので度々開発者を悩ませます。
私が行っている開発案件の中で、ユーザーを新規登録する画面でユーザーIDとパスワードを入力しようとしたらなんか勝手に入力されてる！？という事象が発生し、色々試行錯誤して無事解決したのでそのことについて書こうと思います。


#1戦目 autocomplete="off"を付ける

```
<input type="password" name="registPassword" autocomplete="off" />
```
ダメでした／(^o^)＼
昔は大丈夫だったそうなのですが、今はなぜか無視されてしまいます。
サイト側がoffにしてよって言っているのに、それを無視するとはどういうことなのよ・・・。

#2戦目 jQueryで消す

onloadされたら消しにいくような感じにしてみた。

```
$('input[name="registPassword"]').val("");
```


ダメでした／(^o^)＼ナンデヤ

```
setTimeout( function() {
    $('input[name="registPassword"]').val("");
}, 1000);
```

遅延させたらうまく消せました。（jQuery→補完の順番なのかな・・。）
ただ、一瞬表示されて消えるのですごく違和感が。

#3戦目 readonly属性使う

最初はreadonlyつけておいて・・・

```
<input type="password" name="registPassword" readonly />
```

focusされたらreadonly外す！

```
$('input[name="registPassword"]').focus(function() {
    $(this).attr('readonly',false);
});
```

これはうまくいきました＼(^o^)／
色々調べたところ、readonlyやdisabled属性がついているものは補完しないそうです。
見た目も自然。まさかreadonlyがかかっているとは利用者は思うまい・・・。

#他にも色々方法ありそう
調べていると、type="password"があるかで補完対象か判断しているようなので、初期表示時はテキストボックスにしておいて書き換えたりなど、他にもやり方は色々ありそうです。
バージョンが上がったら動作しなくなったりするかもしれないので、戦いはまだまだ続くのだろうな・・・。
Python株価取得グラフ作成

#前段:
メーカーの営業をしており、常日頃の思いとして「主要1,000製品の受注動向をデイリーで把握したい」という思いに駆られることが多々ある。色々試行した結果折れ線グラフでの可視化が一番効率良くモニターできると感じPythonでのグラフ作りに至った。
＊本投稿では受注データーの代わりに株価を使用。
(社内セキュリティーの関係でPythonを導入できていない為、実務上での解決には至っていない）


#構成:
株価を使用しPythonでのグラフ作り
以下手順
・Pythonで株価の自動取得
・データー整形
・データーを纏めてプロット


```Python
#必要ライブラリーのImport
from datetime import datetime
import pandas as pd
import matplotlib.pyplot as plt
import sys
from yahoo_finance_api2 import share
from yahoo_finance_api2.exceptions import YahooFinanceError
import numpy as np
import matplotlib.dates as mdate
```

```Python
#銘柄ファイルを先にエクセルで作成しておきPandasで読み込み（銘柄コード一覧はネットで拾ってくる)
df=pd.read_excel("/Users/銘柄.xlsx")
l=df["コード"]
```

```Python
#yahoo_finance_apiで株価を自動取得する為、銘柄コードの末尾に「.T」を付与する処理
j=list(l)
q=list(map(lambda x: str(x),j))
c = list(map(lambda x: x+".T", q))
```



![スクリーンショット 2021-04-28 21.28.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1389756/ab3e05a1-5702-719f-d4e4-bdf8649e824c.png)



```Python
#先ずは例として1銘柄2年分自動取得を行う。（今回はOpenのみ使用)
my_share = share.Share('1305.T')
symbol_data = None
 
try:
    symbol_data= my_share.get_historical(
        share.PERIOD_TYPE_YEAR, 2,
        share.FREQUENCY_TYPE_DAY,1)
except YahooFinanceError as e:
    print(e.message)
    sys.exit(1)
    
df = pd.DataFrame(symbol_data)
df["datetime"] = pd.to_datetime(df.timestamp, unit="ms")
g=df[["datetime","open"]]
g.rename(columns={'open': '1305.T'}, inplace=True)
```


![スクリーンショット 2021-04-28 21.16.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1389756/ad361425-1dae-d541-4725-5cddbf622c61.png)




```Python
#残りはfor loopで回し、上で作成した株価一覧に結合していく
for z in c:
    my_share = share.Share(z)
    symbol_data = None

    try:
        symbol_data = my_share.get_historical(
            share.PERIOD_TYPE_YEAR, 2,
            share.FREQUENCY_TYPE_DAY,1)
    except YahooFinanceError as e:
        print(e.message)
        sys.exit(1)

    df = pd.DataFrame(symbol_data)
    df["datetime"] = pd.to_datetime(df.timestamp, unit="ms")
    d=df[["datetime","open"]]
    d.rename(columns={'open': z}, inplace=True)
    g=pd.merge(g, d, on='datetime',how='left')
```


![スクリーンショット 2021-04-28 21.20.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1389756/a26164cb-0871-b02d-cfe8-7ce82f397d03.png)

```Python
#datetimeをインデックス化。また1305.Tの重複を削除
g.set_index('datetime', inplace=True)
print(g.columns[[0,1,2]])
g.rename(columns={'1305.T_y': '1305.T'}, inplace=True)
g.drop(g.columns[[0]], axis=1,inplace=True)
```

```Python
#複合グラフの処理、見やすさを加味し12x12とした
%matplotlib tk
fig, axes = plt.subplots(12,12,sharex=True,sharey=False, figsize = (19,10))

for ax, zz in zip(axes.ravel(),c):
    dt = g[zz]
    ax.plot(dt,label=zz)
    ax.grid(True)
    ax.legend(fontsize=6)
    ax.set_xticklabels(g.index,rotation=90,fontsize=8)
xfmt = mdates.DateFormatter("%y/%m/%d")
ax.xaxis.set_major_formatter(xfmt)

ax.tick_params(labelsize=8)
plt.tight_layout()
plt.show()
```
#結果:
下記データーを受注動向に置き換えると、増設の判断に役立ちそう👏
![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1389756/146ce59e-8dee-0f6d-a824-c04cbd00bd7f.png)
DOBOT MG400の可動域

[DOBOT MG400](https://techshare.co.jp/product/dobot/mg400/)の可動域を描画します。

スペックは次のようになります。

- 寸法
リンク1 = 175mm
リンク2 = 175mm
エンドオフセット (66,0,0)

- 関節範囲
J1 -160 ~ 160
J2 -25 ~ 85
J3 -25 ~ 105

![Screenshot from 2021-04-28 21-33-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/f113c94b-a857-3e80-8caf-811ec4637a1a.png)

```python:mg400.py
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import math

L1 = 284 - (175 + 66)
L2 = 175
L3 = 175
L4 = 66

def ki(j1,j2,j3):
  if(check_joint_limit(j1,j2,j3) == False):
    raise Exception('out of range')

  j1_rad = math.pi * j1 / 180
  j2_rad = math.pi * j2 / 180
  j3_rad = math.pi * j3 / 180

  l =L1 +  L2 * math.sin(j2_rad) + L3 * math.cos(j3_rad) + L4
  z = L2 * math.cos(j2_rad) - L3 * math.sin(j3_rad)

  x = l * math.cos(j1_rad)
  y = l * math.sin(j1_rad)

  return (x,y,z)

def check_joint_limit(j1,j2,j3):

  d_j = j3 - j2

  if (j1 >= -160 and j1 <= 160):
    if (j2 >= -25 and j2 <= 85):
      if (j3 >= -25 and j3 <= 105):
        return True

  return False

def check_coordinate(x,y,z):
  if x < 150 and x > -150:
    if y < 150 and y > -150:
      return False

  return True 


fig = plt.figure()
ax = Axes3D(fig)

ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")

ax.set_xlim(-500,500)
ax.set_ylim(-500,500)
ax.set_zlim(-200,250)

points = []

for j1 in range(-180,180,10):
  for j2 in range(-180,180,10):
    for j3 in range(-180,180,10):
      try:
        x,y,z = ki(j1,j2,j3)
        if check_coordinate(x,y,z):
          ax.plot([x],[y],[z],marker=".",linestyle='None',color='blue',alpha=0.2)
          points.append([x/1000,y/1000,z/1000])
      except:
        pass

#plt.show()


### change to ply

import open3d as o3d
import numpy as np

xyz = np.array(points)
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(xyz)
o3d.io.write_point_cloud("mg400.ply", pcd)
```

生成された点群をcloudcompareで描画すると次の様になりました。

![Screenshot from 2021-04-28 21-31-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/de817360-98f0-604f-4516-df0f81f42bed.png)

#参考

https://qiita.com/hoshianaaa/items/3499ea9485a92b6caf8a

https://qiita.com/hoshianaaa/items/fb175d3b039207e507ea
[反省]RailsAdminでundefind method ‘properties’ for nil:NilClassが発生した件について

# 始めに
反省含めて、記述します。
より詳しいことがわかる方いたら、コメントしてくださると嬉しいです。

#エラー内容
今回、RailsAdminを導入しました。導入後、画面の表示までは成功したのですが、一部のモデルにアクセスしようとするとエラーが発生しました。
![スクリーンショット 2021-04-28 21.18.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1128031/b8d26819-30f4-ba5d-7188-a11640ff3e1e.png)

# 試したこと

正直、何も心あたりがなかったので、まずは仮説すら立てられず、、、、が、とりあえずアクセスできないモデルとアクセス可能なモデルの比較を行いました。また、ネット等でひたすら調べました。

# わかったこと
ひとまず比較してみると、ActiveHashとアソシエーションを結んでいるものにエラーが出ていると言うところまで突き止めました。そこで、ActiveHashを使わずenumを使用するとうまくいくことはわかりました。

# わからないこと
依然として、なぜActiveHashが使えないのか不明のままです。また、使ってもうまくいくような対処法もわからないままです。

# 今回のエラー対応で学んだこと
エラーに対して、すぐ人に聞く、あるいは誰かに丸投げというのはあまり好きではない私ですが、さすがに6時間以上粘ってもダメなものはダメなんだなと感じました（実は今回、課金してプロエンジニアさんに相談しました）。時には、諦めて人に聞いたり、もしかしすると諦めることも”進める”ためには大切な選択肢なのかもしれません。

これから、転職してプロのエンジニアとして働いていくことを目指しておりますが、現場ではもっとスピードと正確性が求められるはずなので、今自分にできることとできないことの切り分けをしっかり行い、次に何ができるかを考えることが重要なんだと、感じました。