OmniAICreator/Qiita-1.07M huggingface dataset:
Amazon Linuxへのログイン/apacheのインストール

1-1■Amazon Linuxへのログイン
-
①無料アカウントの作成
②Amazon LinuxのEC2を作成
③その際、公開キーを作成
④公開キーを使ってsshでログイン
ssh -i ec2-user@ipv4 dnsアドレス
⑤root権限でのログイン
sudo su -
1-2■トラブルーsshでログインできない
-
・ホスト名が間違っている
Amazon Linuxのホスト名はデフォルトではec2-user
ssh -i host名@パブリックipv4 dns名

・パーミッションが緩かった。
複数のユーザで公開キーを操作できるようにしていた。

Administratorのみが読み取り書き込み権限を持つように設定
*ただ、ホスト名が最も大きな原因だった為、どこから有効だったか不明


2-1■Apacheのインストール
-
①#yum install httpd
よく分からない表示が出た。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1189399/a1af9bd9-be18-d449-23fa-942d9b69a88b.png)
読んでみると、プラグインのロードは発生しているようだが
httpdのパッケージはすでに入っていたようので、
apacheのインストールは完了
→最初のログインの時に入れた？
→デフォルトで入ってた？

②インストール先
メイン設定ファイル
/etc/httpd/conf/httpd.conf
#vi httpd.conf

上記コマンドで空きポートの状態が確認できた。
空きポートは80番になっていた。
なぜ443番がlistenになっていないのか調べたところ
下記リンクで簡単にポートの追加などができることが確認できた。
https://www.adminweb.jp/apache/ini/index3.html

また、これ以上深堀しないが
ssl.confでは443の設定がデフォルトらしい。
httpd.confだけでなくssl.confもhttps通信の際には
利用される為、httpdはデフォルトで80なのだろうか？
https://www.white-space.work/apache-notes/

DSOという聞いたことのない表記も合ったので調べてみると
apacheには静的・動的なモジュールについての設定というものがあるらしい
http://cos.linux-dvr.biz/archives/tag/dso

ほかにもifmoduleというものがあったが長そうだったので割愛
DjangoのTemplateでcontext_dataをgroupしたい => regroupを使う

##経緯
例えば、フロントで表示したいデータがこんな感じだとする。

```python
goods = [
    {'name':'だいこん', 'price': '100', 'genre':'野菜', 'made_in': '埼玉'},
    {'name':'はまち', 'price': '500', 'genre':'魚', 'made_in': '富山'},
    {'name':'すいか', 'price': '1000', 'genre':'野菜', 'made_in': '千葉'},
    {'name':'かつお', 'price': '500', 'genre':'魚', 'made_in': '富山'},
    {'name':'とけい', 'price': '10000', 'genre':'機械', 'made_in': '埼玉'},
    {'name':'じてんしゃ', 'price': '20000', 'genre':'機械', 'made_in': '大阪'}
]
```
これらを、genreもしくはmade_inでまとめて表示したい。

##結論
データをgenre、もしくはmade_inでsortした後、templateでregroupを使う。
(-> regroupはsortしてくれないので)

## 内容
まずはtemplateの内容。

```django
{% regroup goods by genre as goods_list %}
<table class="table table-bordered table-sm">
    {% for goods in goods_list %}
    <thead>
    <tr>
        <th colspan="2" class="bg-primary">{{ goods.grouper }}</th>
    </tr>
    <tr class="bg-info">
        <th>商品名</th>
        <th>値段</th>
        <th>産地</th>
    </tr>
    </thead>
    <tbody>
    {% for g in goods.list %}
    <tr>
        <td>{{ g.name }}</td>
        <td>{{ g.price }}</td>
        <td>{{ g.made_in }}</td>
    </tr>
    {% endfor %}
    </tbody>
    {% endfor %}
</table>
```

###dataをsortしない場合
データがgenreでsortされていないので、野菜でまとまっていないが、機械はまとまっている…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52784/08b04128-8d8d-bee6-a8f5-99e9ba89fa40.png)

###dataをsortした場合
sortする。

```python
new_goods_list = sorted(goods, key=lambda k: k['genre'])
```

すると、goodsは以下のようにsortされる。

```
$new_goods_list
[
    {'name':'とけい', 'price': '10000', 'genre':'機械', 'made_in': '埼玉'},
    {'name':'じてんしゃ', 'price': '20000', 'genre':'機械', 'made_in': '大阪'},
    {'name':'だいこん', 'price': '100', 'genre':'野菜', 'made_in': '埼玉'},
    {'name':'すいか', 'price': '1000', 'genre':'野菜', 'made_in': '千葉'},
    {'name':'はまち', 'price': '500', 'genre':'魚', 'made_in': '富山'},
    {'name':'かつお', 'price': '500', 'genre':'魚', 'made_in': '富山'}
]
```
なので、表示は以下のようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52784/1f85f4d1-c3d6-133e-579a-c6cb734559d2.png)

### made_inでまとめたい場合
####1.made_inでsort
```python
new_goods_list = sorted(goods, key=lambda k: k['made_in'])
```
####2.templateでgroup by made_in
```django
{% regroup goods by made_in as goods_list %}
<table class="table table-bordered table-sm">
    {% for goods in goods_list %}
    <thead>
    <tr>
        <th colspan="2" class="bg-primary">{{ goods.grouper }}</th>
    </tr>
    <tr class="bg-info">
        <th>商品名</th>
        <th>値段</th>
        <th>産地</th>
    </tr>
    </thead>
    <tbody>
    {% for g in goods.list %}
    <tr>
        <td>{{ g.name }}</td>
        <td>{{ g.price }}</td>
        <td>{{ g.made_in }}</td>
    </tr>
    {% endfor %}
    </tbody>
    {% endfor %}
</table>
```
####3.できあがり
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52784/4f558bf8-044f-b307-a54a-41f73db2cb20.png)


以上。
##参考
https://blog.aristo-solutions.net/2018/07/django-regroup_12.html
実は簡単！？画像ファイルをinputでアップロードする時、サイズをMBからKBへ軽量化する方法

よくSNSとかでプロフィール画像としてアイコンを使うことが多いですよね。

今回はアイコンとかでよく使う画像をアップロードするときに画像サイスを軽量化する方法をお教えします！

画像ファイルって割と重いんですよね。。

本番環境で画像ファイルをMBのまま使ったり、画像ファイルをアップロードするときMBのままだと画像を読み込むのに時間がかかったり、データベースの容量も多く取ってしまいます。

なので、ユーザーにアップロードしてもらった画像はこちらで軽量化しましょう！

凄く簡単なので、肩の力を抜いてご覧ください。

#browser-image-compressionのインストール#

画像を軽量化する``browser-image-compression``というパッケージを使います。

```
> npm i --save browser-image-compression
```

#オプションの設定#

次にどのように画像をリサイズするかのオプションを設定します。

```index.js
const options = {
  maxSizeMB: 1, // 最大ファイルサイズ
  maxWidthOrHeight: 80 // 最大画像幅もしくは高さ
}
```

この他にもさまざまなオプションがあります。

詳しいことは[こちら](https://www.npmjs.com/package/browser-image-compression)に書いてるので、興味にある方は是非ご覧ください！

#画像の圧縮#

これらを用いて画像を圧縮します。

```index.js
import imageCompression from 'browser-image-compression'

const options = {
  maxSizeMB: 1, // 最大ファイルサイズ
  maxWidthOrHeight: 80 // 最大画像幅もしくは高さ
}
const file = await imageCompression(event.target.files[0], options)

// 画像サイズの比較
console.log(${event.target.files[0].size / 1024 / 1024} MB)
console.log(${file.size / 1024 / 1024} MB)
```

このようにして画像を圧縮することができます！

実際に``console.log``で画像サイズが圧縮されているか目で確かめてみてください！！

以上、「実は簡単！？画像ファイルをinputでアップロードする時、サイズをMBからKBへ軽量化する方法」でした！

また、何か間違っていることがあればご指摘頂けると幸いです。

他にも初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい！！

あと、最近「ココナラ」で環境構築のお手伝いをするサービスを始めました。

気になる方はぜひ一度ご相談ください！

Thank you for reading
【Ruby】モデル名の前のダブルコロン::は何を意味しているのか？ない場合との違いについて

#Rubyでモデル名の前のダブルコロン::は何を意味しているのか？ない場合との違いについて



<br>
rubyのコントローラの中に`::Article`のようにモデル名の前にダブルコロンが２つつく処理が出てくる。

```rb:xxx_controller.rb
model = ::Article.where(active: true)
```

この、`::Article`と`Article`で

**（１）何か違いがあるのか？**
**（２）何のために`::`をつけているのか**

について。


##結論
`::Article`と`Article`の処理結果は同じになる。

```irb:
2.7.0 :009 > ::Article
 => Article(id: integer, title: string, body: text, created_at: datetime, updated_at: datetime) 

2.7.0 :010 > Article
 => Article(id: integer, title: string, body: text, created_at: datetime, updated_at: datetime)
```

どちらも、同じテーブルを指している。


##なぜ`::`をつけるのか？
誤作動防止のため。

以下のようにコントローラに名前空間がつけられている場合、ライブラリによっては、モデル`Article`を`Api::ArticlesController::Article`としてしまう場合がある。

この間違いが起こらないように、冒頭に`::`をつけることで、名前空間の中にない（一番上にある）ことを明示している。

```rb:
class Api::ArticlesController < ::Api::ApplicationController

  def lists
    model = ::Article.where(active: true)
  end
end
```

最近では、モデル名の上に名前空間をつけるバグはほとんどないそうなので、慣習的につけている場合が多いとのこと。
undefined method `make_response!'でちょっとつまづいた

# 概要
コード書いてる時、謎のエラーが起きた

undefined method `make_response!'

いつものあれね、と make_response! をコード上で探してみても見つからない。

# 原因
原因はめちゃくちゃ初歩的でした。

これを

```
class ExportsController
```
こうするだけ

```
class ExportsController < ApplicationController
```

初歩的すぎて自分もやはりまだまだだなと実感、、

参考：
https://github.com/lynndylanhurley/devise_token_auth/issues/1158
PCでスクリーンショット・スクリーンキャプチャをする方法


windows,linuxなど共通して以下のショートカットキーでスクリーンショットができます.

    [Prt Scrn] で、デスクトップのスクリーンショットを撮る。
    [Alt] + [Prt Scrn] で、ウィンドウのスクリーンショットを撮る。
    [Shift] + [Prt Scrn] で選択領域のスクリーンショットを撮る。

windows画面録画
http://t-ishii.la.coocan.jp/download/AGDRec.html
Airflowで月末に実行するスケジュールを設定する

# cronと月末

AirflowのDAGスケジュールにおいて、

* 1/31 0:00
* 2/28 0:00
* 3/31 0:00
* 4/30 0:00
* ...
* 12/31 0:00

のように毎月の月末に実行したい場合、標準のcron式だと設定がちょっと厄介です。
30日の月もあれば31日の月もありますし、2月にいたってはうるう年のことも考えなければなりません。

# Airflowではcron式の日フィールドに `L` が使える

幸いなことに、Airflowが使っているcronモジュール [croniter](https://pypi.org/project/croniter/) はいくつかの非標準のcron式もサポートしています。

その中には `L` があります。
Airflow（croniter）において `L` は日フィールドにのみ使える特殊な文字で、指定すると **その月の最後の日** を意味することになります。

したがって、

```python
dag = DAG(
    ...
    schedule_interval="0 0 L * *"
    ...
)
```

のように書けば毎月の月末に実行することができます。

# おまけ： Airflowではcron式の曜日フィールドには `#` が使える

完全なる余談ですが、他にサポートしている文字として、 `#` があります。

Airflow（croniter）において `#` は曜日フィールドにのみ使える特殊な文字です。
`L` と違い `#` 単体ではなく曜日指定との組み合わせで使います。 `曜日#n` のように指定すると **その月の第n曜日** を意味することになります。

たとえば、毎月第4火曜日 0:00に実行するDAGの場合、

```python
dag = DAG(
    ...
    schedule_interval="0 0 * * 2#4"
    ...
)
```

のように書くことができます。
H - まとめ売り

##[H - まとめ売り](https://atcoder.jp/contests/past201912-open/tasks/past201912_h)

O(Q^N)
問題文をシミュレーションした際のコードです。
TLEになります。

```python:python
import math
import heapq
import itertools
from functools import reduce
 
# main
def main():
    N = int(input())
    C = list(map(int, input().split()))
    Q = int(input())
    res = 0

    for i in range(0, Q):
        S = list(map(int, input().split()))

        if S[0] == 1:
            x = S[1] - 1
            if C[x] - S[2] >= 0:
                C[x] = C[x] - S[2]
                res += S[2]
        if S[0] == 2:
            ok = True
            for i in range(0, N, 2):
                if C[i] - S[1] < 0:
                    ok = False
            if ok:
                for i in range(0, N, 2):
                    C[i] = C[i] - S[1]
                    res += S[1]
        if S[0] == 3:
            ok = True
            for i in range(0, N):
                if C[i] - S[1] < 0:
                    ok = False
            if ok:
                for i in range(0, N):
                    C[i] = C[i] - S[1]
                    res += S[1]
    print(res)
            
# エントリポイント
if __name__ == '__main__':
    main()
```

クエリの2, 3の時の処理は改善できそうです。
奇数の購入枚数、全種類の購入枚数を保持します。
最後に加算すると良さそうです。

```python:python
import math
import heapq
import itertools
from functools import reduce
 
# main
def main():
    N = int(input())
    C = list(map(int, input().split()))
    Q = int(input())
    res = 0
    s = 0
    z = 0
    min_s_C = 1000000007
    min_z_C = 1000000007

    for i in range(0, N):
        if i % 2 == 0:
            min_s_C = min(min_s_C, C[i])
        else:
            min_z_C = min(min_z_C, C[i])

    for i in range(0, Q):
        S = list(map(int, input().split()))

        if S[0] == 1:
            if (S[1] - 1) % 2 == 0:
                if C[S[1]-1] - s - z - S[2] >= 0:
                    C[S[1]-1] = C[S[1]-1] - S[2]
                    min_s_C = min(min_s_C, C[S[1]-1])
                    res += S[2]
            else:
                if C[S[1]-1] - z - S[2] >= 0:
                    C[S[1]-1] = C[S[1]-1] - S[2]
                    min_z_C = min(min_z_C, C[S[1]-1])
                    res += S[2]

        if S[0] == 2:
            if min_s_C - s - z - S[1] >= 0:
                s += S[1]

        if S[0] == 3:
            if min(min_s_C - s - z, min_z_C - z) - S[1] >= 0:
                z += S[1]

    res += len(C) * z + (len(C)+1) // 2 * s
    print(res)
            
# エントリポイント
if __name__ == '__main__':
    main()
```
【メモ】EC2インスタンスの作成～いろいろなダウンロード

プログラミング初心者です。
windowsユーザーです。
メモとして残します。


LAMP環境構築をしたことがなかったので，構築してみました。
・AWS EC2
・Apache
・PHP
・Mysql

##EC2インスタンスの作成からteraturmでの実行 
https://proengineer.internous.co.jp/content/columnfeature/17201#11

手順通りに構築していく
SSL認証の部分で【失敗しました】出て下記の記事を参照して確認していったけど上手くいかなかった。

https://xn--o9j8h1c9hb5756dt0ua226amc1a.com/?p=3583

どこがおかしいんだーーーって考えてたけどとりあえず記事と通りに真似してみるかって思って，
User名を ec2-user に変更して行ったらすんなり通った。


##Apacheインストール時は，下記のサイト参照

https://www.dot-plus.com/cloud-service/aws/3033/


特段問題なく完了

## PHPのインストールからupdate(7.2)まで

```   
$ sudo yum install php70

>>> Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
    205 packages excluded due to repository priority protections
    No package php70 available.
```
無いよって出力されて，あれって思って調べてみたら
・epelリポジトリ追加
・remiリポジトリ追加
上記2つを行わないといけないらしく，追加する
追加後は下記の記事を参照する。

https://owani.net/2016/02/14/php56-php7/#%EF%BC%92php70%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB

※epel有効化はこの記事参照して，行いました。

https://qiita.com/yamada-hakase/items/fdf9c276b9cae51b3633

※updateはこの記事を参照

https://www.ninton.co.jp/archives/1762




## mysqlのインストール

https://www.acrovision.jp/service/aws/?p=2387

※項番14, 15, 16を参照
特段問題無し。


## 終了
これで完了！！！
【Project Euler】 Problem1 【解いてみた】

# はじめに
【Project Euler】とは、プログラミングで解く数学の問題集です。

本投稿では初学者なりに、Problem1 を解くにあたっての考え方を解説しています。
ちなみに言語はRubyを用いています。


※本投稿は、Project Eulerのガイドラインに従い、解答例としてのコードは載せておりません。
　また、問題に関しては私が翻訳しています。ミスがあればご指摘ください。
　　
【Project Euler】について知りたい方はこちらから↓

 https://projecteuler.net/

# 問題(original ver.)
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.

# 問題(翻訳ver.)
10未満の数字の中で3,もしくは５の倍数は3,5,6,9の4つである。そしてその4つの数字の合計は23である。
同じように、1000未満の数字において、3の倍数と5の倍数を挙げた時、その合計はいくつになるか計算せよ。

## 問題を解く上でのヒント
①まずは1000未満の数字の中から、3,もしくは5の倍数を取り出すことを考えなければいけません。
言い換えると、1から順に999まで数字を見ていって、3もしくは5の倍数を、**繰り返し**取り出します。
つまり、繰り返し処理を使います。

繰り返し処理のメソッドに関しては説明を省きます。わからない方は検索してください。

②つぎに、そもそも３の倍数、もしくは５の倍数はどのように表現するのかを考える必要があります。
これに関しては、※~~代数演算子~~を用いると簡単に表現できます。
どの演算子を使えば良いか考えてみてください。


ヒントとしては、nの倍数 =  nで割り切れる数であるということです。

以上がわかれば基本的に解ける問題かと思います。

※**代数演算子**ではなく、**算術演算子**が正しいようです( Arithmetic Operators がオリジナル)。
一部のサイトでは代数演算子として紹介されていますが、その場合は読み替えてください。

# おわりに
今回は【Project Euler】の問題1を解く上での考え方、流れを解説してきました。
問題1ということもあり、基礎が分かっていれば比較的かんたんな問題だったかなと思います。

このほかにも多くの問題が存在しているので、気になる方は最下部のリンクから挑戦して見てください。
また今後、私自身その他の問題にも挑戦し、同じような備忘録を投稿していきます。
私の備忘録が少しでも皆さんの参考になれば幸いです。ありがとうございました❗


https://projecteuler.net/about

P.S. 問題を閲覧するにはアカウント登録が必要です。↑
optionをテキストで検索してselected状態にする

##経緯
jQueryでselectのoptionから選択したい。
その時の指定方法は、valueではなくテキストで指定したい。

##結論
```html:example.html
<select id="selector">
    <option value="" selected>-</option>
    <option value="1">あああああ</option>
    <option value="2">ららららら</option>
    <option value="3">ぶらぶらぶーらぶら</option>
    <option value="4">あべし</option>
    <option value="5">ひでぶ</option>
</select>
```

```javascript:example.js
var blah = 'ぶらぶら'
$(`#selector :contains(${blah})`).prop('selected', true);
```
これで、value="3"のoptionがselectedされる。

##解説
コンテントフィルター`:contains`を使う。
https://api.jquery.com/contains-selector/#contains1

以上
Java学習　基礎編　~条件分岐 if文 ~

Java学習の備忘録になります。
内容は初心者なので基礎的な部分となります。
Javaに興味がある方やJava学習初心者の参考になれば幸いです。

* * *
### 条件分岐
簡単にいうと、
『**特定の状況のときだけ、ある処理を行う**』
というプログラムのことを条件分岐と言う。

#### if文を用いると

①「**もし○○ならば●●を行う**」
②「**もし○○ならば●●を行う、そうでなければ■■を行う**」
③「**もし○○だったら●●を行う、そうでなくもし△△であれば▲▲を行う、いずれでもなければ■■を行う**」

などの条件分岐ができる。

```Main.java

// ①
if (条件式) {
  処理 ; // 条件式が成り立てば実行される
}

// ②
if (条件式) {
  処理 ; // 条件がtrueのとき実行
} else {
  処理 ; // 条件がfalseのとき実行
}

// ③
if (条件式 1) {
  処理 ; // 条件式1がtrueのとき実行
} else if (条件式 2) {
  処理 ; // 条件式1がfalseで、条件式2がtrueのとき実行
} else {
  処理 ; // 条件式1&2ともfalseのとき実行
}

// if文で使う記号 { } を、ブロックと呼ぶ。ブロックの後には、セミコロンはいらない。
// else ifは、必要なだけ並べることができるが、実行されるのは最初に合致した条件だけなので注意。
```

* * *
#### おわりに
書き方としては、Java Scriptに近いですが、処理の後にセミコロンが必要になりますね。
他のプログラミング言語と比べると新しい気付きだったり、覚えるときに便利かもです。
みなさんの参考になれば幸いです。
正規表現で特定の文字列のあと or まえの情報だけとりたい

正規表現で特定の文字列のあと or まえの情報だけとりたい

数年に一回ぐらいこういう正規表現を書こうとしてどうやって書くんだっけ……とわけがわからなくなるので備忘録用メモ。

たとえばこういうURL（https://www.tiktok.com/@kyoookosan/video/6883074502054432002）　
から/video/の後の数字列だけを抜き出したい時（用途としてはvimeoのembedをこのIDから組み立てたい）

正規表現的にはこう

```
/(?<=video\/)\d{10,}/
```

ruby pry

```
[1] pry(main)> url = "https://www.tiktok.com/@kyoookosan/video/6883074502054432002"
=> "https://www.tiktok.com/@kyoookosan/video/6883074502054432002"

[2] pry(main)> url.match(/(?<=video\/)\d{10,}/)
=> #<MatchData "6883074502054432002">
```

後ろじゃなくて特定文字列の前を取りたい場合はこう

```
[1] pry(main)> url = "https://www.tiktok.com/@kyoookosan/video/6883074502054432002"
=> "https://www.tiktok.com/@kyoookosan/video/6883074502054432002"

[2] pry(main)> url.match(/(.*)(?=\/video)/).to_a.try(:first)
=> "https://www.tiktok.com/@kyoookosan"
```
Seleniumで横方向にセル結合されたテーブルを読み込む

## 概要
Seleniumで、以下のようにセル結合されたテーブルをいい感じに読み込みたい。
今回は、横方向に結合されたテーブルを対象とし、データの補完も左方向に補完して読み込みたいケースを想定しています。

**インプット**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507249/2301b700-71da-d261-c6a9-eb23babf51bd.png)

```html:table.html
<table id="tbl">
<tr>
	<td> a </td>
	<td> b </td>
	<td> c </td>
</tr>
<tr>
	<td colspan=2> 1 </td>
	<td> 2 </td>
</tr>
<tr>
	<td> 4 </td>
	<td colspan=2> 5 </td>
</tr>
</table>
```

**得たいアウトプット**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507249/2a54b62d-85f8-b6c7-87d2-74bc44e10b00.png)



## 実装
`pandas`の`read_html`を使います。
※参考にした記事：https://stackoverflow.com/questions/60823159/parsing-nested-td-and-colspan-elements-in-an-html-table-with-selenium-python

```python
#seleniumでサンプルのhtmlファイルを読み込む
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome(executable_path = '<<<CHROMEDRIVER>>>')
driver.get(r'C:\Users\<<<USERNAME>>>\Desktop\table.html')

#seleniumのfind_elementでテーブル要素を探してHTMLテキスト化して
table_id = driver.find_element(By.ID, 'tbl')
tabletext = table_id.get_attribute('outerHTML')

#pandasのread_htmlでDataFrameに変換する
import pandas as pd
df = pd.read_html(tabletext)
df = df[0]
df

#	0	1	2
#0	a	b	c
#1	1	1	2
#2	4	5	5
```

## 失敗例
いままでセルのデータを各セルごとに走査してしまっており、うまくいってませんでした。（そもそもこれもあんまりですけど…）
どうにかしてcolspanの情報を取ってこないとダメなのかなぁとか、悶々としていましたが、先述の記事みて目から鱗ボロボロでした。

```python
table_id = driver.find_element(By.ID, 'tbl')
rows = table_id.find_elements(By.TAG_NAME, "tr")
r_data = []
for i, row in enumerate(rows):
    cols = row.find_elements(By.TAG_NAME, "td")
    c_data = []
    for j, col in enumerate(cols):
        c_data.append(col.text)
    r_data.append(c_data)
r_data

#[['a', 'b', 'c'], ['1', '2'], ['4', '5']]
```

## まとめ
pandasってしゅごい
※行方向にセル結合されたものとかは検証していません。
PythonでLine apiを使ってメッセージを送る、LineのUser_idをデータベースに保存する

今日やること
・　Line apiを使い倒す
・　LineのUser＿idをrouterを使って取得してデータベースに保存する。

#1.LINE Developersコンソールでチャネルを作成する
[LINE Developers](https://developers.line.biz/ja/docs/messaging-api/getting-started/#using-console)から新しいチャンネルを作成し、

公式ドキュメントの方針に従って登録を進める。

#2. Messaging API設定からWebhook URLの設定を行う
Lineのチャンネルの作成が終わったら次にWehook URLを設定していく。

>Web hoookとは？
>>LINEプラットフォームから送信されたWebhookイベントを処理できるボットサーバーのエンドポイントのURLです。設定したURLがWebhookイベントを受け取るできることを確認するには「検証」ボタンをクリックします。

ここではテスト用として[request bin](https://requestbin.net/)をWeb hookとして設定する。

request binとはいろいろなHTTPリスエストを記録し、人間に読みやすい形で表示してくれるweb開発者向けのサービスです。Webアプリ開発中、どういうリクエストが送信されているのかを確認したい時に利用すれば便利です。

Messaging API設定のWeb hookの設定を入力してから利用のボタンをオンにしよう。

次にrequestbinのURLをリフレッシュする。

![スクリーンショット 2021-03-09 17.36.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965206/92f00bf4-ed37-3393-afbf-163ae298cbca.png)

この写真が表示されれば成功！

#プッシュメッセージの送信
アカウント追加したユーザーに対してプッシュメッセージを送信できるようにする。詳しくは[こちら](https://developers.line.biz/ja/reference/messaging-api/#send-push-message)から参照できる。

まずは下記をインストールする。

```
pip install line-bot-sdk
```
次にコードをを書いていく

```python
from linebot import LineBotApi
from linebot.models import TextSendMessage
from linebot.exceptions import LineBotApiError

line_bot_api = LineBotApi('<channel access token>')

try:
    line_bot_api.push_message('<to>', TextSendMessage(text='Hello World!'))
except LineBotApiError as e:
    # error handle
    ...
```
channel access token:　長期アクセストークンを入力

to: メッセージを送信する相手のline user idを入力（request binで取得可）

それぞれの情報を入力したのちコードを実行すると`Hello World!`というメッセージが公式ラインのアカウントより送信されてきていると思う。

ここは入力ミスが起こりやすいのでしっかり確認しよう。

#クエリーパラメーターの設定
ここから話はガラッと変わってvuejsでlineのUser idを設定してそこからパラメーターを取得する。

クエリーを設定して取得する手順は以下の通りである。

1. routeを使って変数にクエリの値を入れる。
2. 設定したuserIdをaxiosを使って送信

####1.userIdを設定する
```vue:IGButton.vue
    methods: {
        open() {
+          const userId = this.$route.query.user_id
+            document.location.href = `https://api.instagram.com/oauth/authorize?client_id=909807339845904&redirect_uri=${process.env.VUE_APP_IG_REDIRECT_URL}&scope=user_profile%2Cuser_media&response_type=code&state=${userId}`
        }
    }
```

#2.設定したuserIdをaxiosを使って送信

```vue:Insta.vue
    mounted () {
      let code = this.$route.query.code
+      let userId = this.$route.query.state
      console.log(userId)
      let redirect_uri = process.env.VUE_APP_IG_REDIRECT_URL
      if(code){
+        let data = {ig_code: code, redirect_uri: redirect_uri, line_user_id: userId}
        axios
        .post('/accounts/',data)
        .then(resp => {
          this.info = resp.data
            console.log(resp.data)
            this.$store.commit('setAccount', resp.data)
            axios.defaults.headers.common['Authorization'] = 'Token ' + resp.data.token
            localStorage.setItem("account", JSON.stringify(resp.data))
            this.$router.push('/profile/')
```
今日はここまで。

#今日の課題

djangoにline_user_idフィールドを追加してdjango上でline user idを保存できるように設定する。
Cross vCenter vMotionの並列実行時間について

#はじめに
どうもこんにちは、VMware愛好家のいけふちです。

Cross vCenter vMotion(以下、XVMという)を用いる移行について、1台ずつ愚直に実行した場合と並列で一遍に実行した場合とで、どちらが早く終わるのか気になりました。
「気になったら社内で検証！」ということで今回、XVMの並列数とタスク完了時間の関係について調べてみました。

##検証内容
・仮想ゲスト8台
ストレージ = 40GB
で統一しています。仮想ゲスト名以外に差異はありません。
・vCenter Server
移行元移行先ともvCSA 7.0 U1cを用いました。
vCPUとメモリは
(vCPU, メモリ) = (2, 12GB)
で検証しました。
・XVMの実行パターン
仮想ゲストを1台、2台、･･･、8台と1台刻みでXVMを実行しました。
1パターンずつ実行し、XVM実行中は極力それ以外にの負荷がかからないように配慮しました。

なお、複数台のXVM同時実行には、Advanced XVMのImport VMs機能を用いて行いました。
参考：[弊社Webサイトの筆者記事](http://c.itdo.jp/?p=3480)

##検証結果
以下の通りです。
※複数台の場合は最後の1台が終わるまでをXVM実行時間として集計しました。
1台：11分
2台：15分
3台：19分
4台：23分
5台：27分
6台：31分
7台：37分
8台：42分

##考察
結果、1台ずつ愚直にやるよりも、複数台同時実行の方が早そうということが分かりました。
ただし7台, 8台あたりから、微妙に時間が増えているように感じます。
ちなみに、「9台以上の検証は？」と疑問に思った方もいるかと思いますが、[vMotionの台数制限](https://docs.vmware.com/jp/VMware-vSphere/7.0/com.vmware.vsphere.vcenterhost.doc/GUID-25EA5833-03B5-4EDD-A167-87578B8009B3.html)で8並列が最大となっています。

#おわりに
そういえば、4並列で8台を実行するとどうなるかという観点での検証をしていませんでした。
これについては、またの機会に検証しようと思います。

なお、弊社Webサイトでは各種技術系記事を投稿しております。
[ITdo!/技術情報/いけふち](http://c.itdo.jp/author/ikefuchi/)
【Chrome拡張】WEB版Youtubeに10秒スキップを追加したよ

こんにちは、キラキラポンコツエンジニアです。
久しぶりに記事でも書こうかな～と思い、執筆中でございます。

今回は、**chorome拡張**を駆使して、web版youtubeに10秒スキップを
実装してみました。
画像にするとこんな感じ
![Screenshot 2021-02-28 125113.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433454/4520c66f-bbde-c807-5798-b578955771d0.png)
再生ボタンの左右にボタンが追加されていますね。
#用意したもの
中身は意外とシンプルです。
・jqueryファイル
・アイコン・ボタン画像
・ manifest.json
・ jsのソースコード
#ソースコード
ダウンロードして使いたい方は、下のリンクからどうぞ。
[ダウンロード](https://github.com/eara4005/YT-10Skip)
###1．画像の読み込み
まずは、再生ボタン横のボタンを読み込みます。

```main.js
const rightImg = chrome.extension.getURL("imgs/right.svg");
const leftImg = chrome.extension.getURL("imgs/left.svg");
```
###2. 10秒スキップ処理を定義
YouTubeって実は、
・ " j "で10秒戻る
・ " l "で10秒進む
・ " k "で再生/一時停止　と
キーボードのショートカット機能で標準実装されているみたいです。

これ知らない方結構いると思います。たち
（→キーでは5秒スキップなんですよ。連打しないといけないですから・・・）

なので、ボタンタップで「j」と「l」の入力を送ってやると動くというわけですわ・・・（簡単だね）
その処理がこちら

```main.js
const nextSkip = new KeyboardEvent( "keydown", { keyCode: 76 }); // lキー
const backSkip = new KeyboardEvent( "keydown", { keyCode: 74 }); // jキー
```

###3. スキップスキップボタンの埋め込み
続いては、このボタンたちをYouTube上に埋め込む処理を書いていきます。


```main.js
//ボタンをプレイヤーに挿入する
const setButton = () => {
    //10秒進
    $(`<button id="nextSkip-button" class="ytp-button"><img src="${rightImg}" id="skip-button-icon"></button>`)
        .insertAfter("button.ytp-play-button");
    $("#nextSkip-button")
        .on("click", () => {
            
        // シークバーの移動
        document.dispatchEvent(nextSkip);
    });

    //10秒戻る
    $(`<button id="backSkip-button" class="ytp-button"><img src="${leftImg}" id="skip-button-icon"></button>`)
        .insertBefore("button.ytp-play-button");
    $("#backSkip-button")
        .on("click", () => {
            
        // シークバーの移動
        document.dispatchEvent(backSkip);
    });

}

setButton(); // 実行
```


詳しく見ていきます。

```main.js
$(`<button id="nextSkip-button" class="ytp-button"><img src="${rightImg}" id="skip-button-icon"></button>`)
        .insertAfter("button.ytp-play-button");
```

ここでは、Youtube上の
```button.ytp-play-button```　つまり再生ボタンの前後に
button要素を埋め込む処理を書いています。

```main.js 
$("#nextSkip-button")
        .on("click", () => {

        // シークバーの移動
        document.dispatchEvent(nextSkip);
    });
```

そんでクリックされたら、先ほど定義したスキップ処理を
実行しているだけです。　ね、簡単でしょう・・・⁉
10秒戻しも同じような感じで書いたらもう完成！！

#参考にしたもの
[chrome拡張の作り方（超概要）](https://qiita.com/RyBB/items/32b2a7b879f21b3edefc)
[塗田一帆さん　SukoStamp](https://twitter.com/nulltypo/status/1277884875329007619?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1277884875329007619%7Ctwgr%5E%7Ctwcon%5Es1_&ref_url=https%3A%2F%2Fnull.style%2Fapp)

大変参考になりました。感謝申し上げます。
Cannot truncate a table referenced in a foreign key constraint

Sequelizeにて以下のエラー。

```
SequelizeDatabaseError: ER_TRUNCATE_ILLEGAL_FK: Cannot truncate a table referenced in a foreign key constraint (`test`.`test_table`, CONSTRAINT `test_table_ibfk_3` FOREIGN KEY (`operated_by`) REFERENCES `test`.`users` (`id`))
```

mysqlに接続して、一時的にforeign keyを外す。

```
mysql> SET GLOBAL foreign_key_checks = 0;
```

あとで、

```
mysql> SET GLOBAL foreign_key_checks = 1;
```

して元に戻す。
Pythonのlogging.exceptionには例外ではなく説明を入れるべき

## エラー時のログを出したい

`logging` モジュールにはログを出す方法がいくつかあります。

```
logging.debug()
logging.info()
logging.warning()
logging.error()
logging.critical()
```

これらの違いはログレベル(log level)によるもので、緊急度などに応じて設定しておけば「開発時は `debug` も含めて出力」「本番では `warn` 以上（または `info` 以上）」のように出力するレベルを変更できます。 

これと並んでもう一つ、 `logging.exception()` があり、ライブラリのリファレンスには次のように書いてあります。

> レベル ERROR のメッセージをこのロガーで記録します。引数は `debug()` と同じように解釈されます。例外情報がログメッセージに追加されます。このメソッドは例外ハンドラからのみ呼び出されるべきです。
https://docs.python.org/ja/3/library/logging.html#logging.Logger.exception

その名の通り、例外処理時に `except:` の中で利用することを想定しています。
しかし、実装するときに勘違いしている例をよく見かけます。（私もしょっちゅうやってました）

## 勘違い

よくある勘違いとは「キャッチした例外を引数に入れる」というものです。

```python
try:
    int("aaa")
except Exception as e:
    logging.exception(e)
```

これで出力されるログはこのようになります。

```
ERROR:root:invalid literal for int() with base 10: 'aaa'
Traceback (most recent call last):
  File "main.py", line 6, in hoge
    int("aaa")
ValueError: invalid literal for int() with base 10: 'aaa'
```

`invalid literal for int() with base 10: 'aaa'` というメッセージが2回重複しているのがわかるでしょうか。
 `ERROR:root:` となっている部分が引数から生成されたもので、 `Traceback` 以降は自動的に付加された例外情報です。
リファレンスにあったのはこの部分ですね。

> 例外情報がログメッセージに追加されます。

引数に例外オブジェクトを渡した場合、文字列化した値 `str(e)` が出力されるだけなので同じエラーメッセージが重複してしまいます。
例外情報は自動的に取得される[^1]ので、実際には例外オブジェクトのコード上の取得は不要です。

```python
try:
    int("aaa")
except:
    logging.exception("What is doing when exception happens.")
```

```
ERROR:root:What is doing when exception happens.
Traceback (most recent call last):
  File "main.py", line 6, in hoge
    int("aaa")
ValueError: invalid literal for int() with base 10: 'aaa'
```

例外だけを出力するのではなく、開発者が理解しやすいメッセージを付与するとよいでしょう。

- ログで状況を伝える
    - ログメッセージを読むときに、何をしていたときに発生した例外なのか読み取れるようにする
- 再現性のための情報
    - `try:` に入るときの事前条件（変数の値など）の出力をしてテストで再現できるようにする


[^1]: 「`except` または `finally` 節内で例外を送出 (または再送出) するとき、`__context__` は自動的に最後に捕まった例外に設定されます。」 https://docs.python.org/ja/3/library/exceptions.html
Vuetifyのドロワーでメニューがずれないようにする

#はじめに
Vuetifyで用意されているナビゲーションドロワーのコンポーネントを使用すると、スクロールしたときにドロワー内のメニューもスクロールされてしまい、表示されなくなります。

https://vuetifyjs.com/ja/components/navigation-drawers/#bottom-drawer

これを防ぐためにCSSを追加し、メニューをドロワー内で固定しました。

#コード
```Vue:src/App.vue
<template>
    <v-navigation-drawer
      v-model="drawer"
      absolute
      bottom
      temporary
      style="position:fixed;" // 追加
    >
      <v-list
        nav
        dense
      >
        <v-list-item-group
          v-model="group"
          active-class="deep-purple--text text--accent-4"
        >
          <v-list-item>
            <v-list-item-title>Foo</v-list-item-title>
          </v-list-item>

          <v-list-item>
            <v-list-item-title>Bar</v-list-item-title>
          </v-list-item>

          <v-list-item>
            <v-list-item-title>Fizz</v-list-item-title>
          </v-list-item>

          <v-list-item>
            <v-list-item-title>Buzz</v-list-item-title>
          </v-list-item>
        </v-list-item-group>
      </v-list>
    </v-navigation-drawer>
</template>
```

v-navigation-drawerに```style="position:fixed;"```を追加するだけでメニューが固定されました。


#参考サイト
https://webdesignday.jp/inspiration/technique/css/4166/
【CSS】line-breakの使い方

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

#line-breakとは
　改行規則の厳密さを指定するときに使用する。

#line-breakの使い方

```css:CSS
white-space: 値;
```

　この値には、`auto`, `loose`, `normal`, `strict`, `anywhere`のどれかを指定する。

　autoは初期値で、既定の改行規則を使用して改行する。
　looseは、最低限の改行規則でテキストを改行する。一般的には、新聞のような短い行を扱うときに使用される。
　normalは、一般的な改行規則を使用して改行する。
　strictは、細かい改行規則を適用する。
　anywhereは、テキスト中のどこでも改行する可能性がある。
　
　strictのときは、日本語の小文字かな(ぁぃぅぇぉヵ)の直前では改行は行わない。
　normal, looseのときは、日本語や中国語のハイフン(-, ~)の直前での改行は許される。
　looseのときは、反復記号(々〻ゝゞヽヾ )の直前、分離不可能な文字(‥…)の途中、日本語や中国語の特定の句読点(・：；･‼⁇⁈⁉！？)の直前、接頭辞の直前と直後での改行は許される。

#参考文献
[line-break](https://developer.mozilla.org/ja/docs/Web/CSS/line-break)
[CSSで改行ルールを簡単設定！改行をコントロールする方法](https://www.sejuku.net/blog/75317)
[line-break …… 改行規則の厳密さを指定する](http://www.htmq.com/css/line-break.shtml)
[line-break･･･禁則処理のしかたを指定する（IEがCSS3の草案を先行採用）](http://www.htmq.com/style/line-break.shtml)
Google Speech to Text で 長時間の音声ファイルの文字起こしを非同期的処理(ジョブ作成と結果取得を別プロセス)で行う

# 背景
- google stt で数十分 ~ 数時間のwavファイルを文字起こししたい
- ジョブ作成と結果取得は別のプロセスで行いたい
- プロセス間のジョブIDの受け渡しはDBなどでやれる前提とする
- `google-cloud-speech` のバージョンは `2.0.1`。 後述するが、バージョンが2以上かどうかで処理が変わるので注意。

##### 参考: [クイックスタート: クライアント ライブラリの使用](https://cloud.google.com/speech-to-text/docs/quickstart-client-libraries?hl=ja)


# 実装

```py:job_creater.py
from google.cloud import speech

client = speech.SpeechClient()
audio = speech.RecognitionAudio(uri='gs://bucket/sample.wav')
config = speech.RecognitionConfig(language_code="ja-JP")
operation = client.long_running_recognize(config=config, audio=audio)
```

```py:result_getter.py
from googleapiclient import discovery
import time

# google-cloud-speech にversion2以上を使っていると、operation_v1でのget_operationが使えないので、 v1p1beta1のやつを使う
# https://github.com/googleapis/google-cloud-python/issues/9101#issuecomment-770849213
speech_service = discovery.build('speech', 'v1p1beta1')

while True:
    # name は client.long_running_recognize() で返される Operation オブジェクトから取得できる
    # 例: operation.operation.name
    o = speech_service.operations().get(name='operation_name').execute()
    time.sleep(5)
    if o.get('done'):
        print(o.get('response', []).get('results'))
        continue
```

# 参照

- [How to get cloud speech api response in python if I only have the operation name?](https://github.com/googleapis/google-cloud-python/issues/9101)
- [Request a “get operation” from Google Speech to text API using Python Speech Client](https://stackoverflow.com/questions/61433235/request-a-get-operation-from-google-speech-to-text-api-using-python-speech-cli)
Vuetifyでページトップ(最上部)に戻るボタンを設置

#はじめに
Vue.js + Vuetifyで、ページ下部によくある丸いボタンを実装する。
・はじめはボタンが表示されない。
・一定の高さをスクロールするとボタンが現れる。
・ボタンはページの右下に固定される。
・ボタンを押すとページの最上部にスクロールする。ボタンはまた消える。
![スクリーンショット 2021-03-09 16.45.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934696/6c170802-f70d-c4a0-8c5d-2b20f410236a.png)

#コード

```vue:src/App.vue
<template>
  // .......
  <v-fab-transition>
    <v-btn
      color="pink"
      fab
      dark
      small
      absolute
      right
      style="bottom:20px; position:fixed;"
      @click="$vuetify.goTo(0)"  // トップに戻るのはこの処理だけ
      v-show="buttonActive"
    >
      <v-icon>mdi-chevron-up</v-icon>
    </v-btn>
  </v-fab-transition>

  // footerの上にボタンを配置
  <v-footer>
  // .......

</template>

<script>
export default {
  data () {
    return {
      buttonActive: false,
      scroll: 0
    }
  },
  mounted() {
    window.addEventListener('scroll', this.scrollWindow) // スクロールの位置を監視
  },
  methods: {
    scrollWindow() {
      const top = 200
      this.scroll = window.scrollY
      if (top <= this.scroll) { // 200px以上スクロールした場合のみボタンを表示
        this.buttonActive = true
      } else {
        this.buttonActive = false
      }
    }
  }
}
</script>
```

#参考サイト
https://qiita.com/hiroyukiwk/items/fcb76893457daf1a6327

https://qiita.com/TK-C/items/42b25ff4ec56528ad870
【Swift】UI要素をまとめて角丸（Corner Radius）にしたい

# どういうことか

これまで自分はStoryboardからControllerへ繋ぎこみ、`userButton.layer.cornerRadius = 20` とか書いていた。
もしページ内に角丸にするボタンがいくつも並んでいる場合、いちいち繋いでコードを書くのも面倒である。なのでStoryboardで設定したい。

**【Xcode】StoryboardでViewを角丸にする**
https://qiita.com/turmeric/items/046acb987c4353b3f308

その場合はこういう方法もあるが、欲を言えばちゃんと**角丸されたプレビュー**が表示されてほしい。

## カスタムクラスを作る

`ViewCustomUtility.swift` といった感じのファイルを作る。
ここに記述を書いておくと**Storyboardで角丸を設定できるメニューができる**。
コピペでもいける。

```swift:ViewCustomUtility.swift
import UIKit

@IBDesignable

// UIButtonと書いているが、たとえばUIViewと書けば "View" のパーツに適応される
class ViewCustom: UIButton {
    
    @IBInspectable var cornerRadius: CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
        }
    }
}
```

## Storyboardで設定する

角丸にしたいUIのパーツを選択したら **Custom Class** で `ViewCustom` を選択する。

![56f9914cb7fd1429be51795c0d20405a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413699/3dffa236-3c30-4a74-6c3e-f0798ac869f2.png)

なんと **Corner Radius** の選択項目が増えている。しかもちゃんとプレビューで表示される。
――で、本題の『**まとめて角丸**』をするには複数のパーツを選択したうえで上記の手順を踏めばよい。

## ちなみに

角丸だけじゃなくて他にもいろいろ作ることができる。

**Storyboard上だけでUIButtonを角丸に！カスタムクラスで設定項目を拡張する！**
<https://iritec.jp/web_service/9167/>

おわり(´・ω・｀)
caskの使い方が変わった

####事の発端
Macにフォントを入れようとしてcaskを使ったところエラーを吐かれた。

```
$ brew cask install font-fira-code
Error: Unknown command: cask
```

####原因と対処

以前はこれでイケたのになぜだろうと思い調べるとbrewのとあるバージョンから使えなくなり、記法が変わっているらしい。

```
$ brew install font-fira-code --cask
```

上記の書き方でインストール成功。


####参考文献
・[Calling brew cask install is disabled! Use brew install [--cask] instead.](https://github.com/ansible-collections/community.general/issues/1524)
・[いつの間にかbrew caskが使用できなくなっていた話](https://www.mathkuro.com/mac/brew-cask-command-error/)
colabで前まで動いていたYOLOv3がmakeできなくなっていた...※2021/03/09時点

### はじめに

久しぶりにYOLOv3(darknet)をcolabで動かそうとするとエラーが出たのでメモがてら投稿しておきます。

### エラー

```bash
!make

>> 
nvcc  -gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=sm_35 -gencode arch=compute_50,code=[sm_50,compute_50] -gencode arch=compute_52,code=[sm_52,compute_52] -Iinclude/ -Isrc/ -DOPENCV `pkg-config --cflags opencv`  -DGPU -I/usr/local/cuda/include/ -DCUDNN  --compiler-options "-Wall -Wno-unused-result -Wno-unknown-pragmas -Wfatal-errors -fPIC -Ofast -DOPENCV -DGPU -DCUDNN" -c ./src/convolutional_kernels.cu -o obj/convolutional_kernels.o
nvcc fatal   : Unsupported gpu architecture 'compute_30'
Makefile:93: recipe for target 'obj/convolutional_kernels.o' failed
make: *** [obj/convolutional_kernels.o] Error 1
```

このようにnvcc関連でエラーが出ます。

### 原因

昔は全く同じコードで動いていたので何が変わったのが調べているとcudaのバージョンの違いでした。

※2021/03/09時点

```bash
! nvcc -V

>> 
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2020 NVIDIA Corporation
Built on Wed_Jul_22_19:09:09_PDT_2020
Cuda compilation tools, release 11.0, V11.0.221
Build cuda_11.0_bu.TC445_37.28845127_0
```

colabのデフォルトのcudaのバージョンは11になっており、これを動いていた頃のバージョンまで下げることで動くようになりました。

### 解決方法

makeを実行する前に、以下の二つを実行することでcudaのバージョンを下げます(今回は11から8)

#### 1つめ

```bash
!apt install g++-5
!apt install gcc-5

!update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 10
!update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 20
!update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 10
!update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 20
!update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30
!update-alternatives --set cc /usr/bin/gcc
!update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30
!update-alternatives --set c++ /usr/bin/g++
```

#### 2つめ

```bash
#Now, here's a bunch of code that takes the longest to execute here but
#It's about installing CUDA and using the beautiful Tesla K80 GPU, so that
#Will worth it

!apt update -qq;
!wget https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb
!dpkg -i cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb
!apt-get update -qq

#Here were are installing compilers and creating some links
!apt-get install cuda -y -qq #gcc-5 g++-5 
#!ln -s /usr/bin/gcc-5 /usr/local/cuda/bin/gcc
#!ln -s /usr/bin/g++-5 /usr/local/cuda/bin/g++
!apt update
!apt upgrade
!apt install cuda-8.0 -y
```

#### 確認

```bash
! nvcc -V

>> 
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2016 NVIDIA Corporation
Built on Tue_Jan_10_13:22:03_CST_2017
Cuda compilation tools, release 8.0, V8.0.61
```

これでmakeがエラー吐くことなく動くようになりました。

### 参考

いつもYOLOv3をcolabで動かす際に大変お世話になっております。

[Google Colab上でYOLOv3の独自データ学習をする
](https://qiita.com/emi-cd/items/01bc601cb3797b762f8f)

[ivangrov/YOLOv3-GoogleColab](https://github.com/ivangrov/YOLOv3-GoogleColab/blob/master/YOLOv3_GoogleColab.ipynb)
[React Next.js Docker] Error: connect ECONNREFUSED 127.0.0.1:4000が出る問題

## はじめに

この記事はReact初学者が書いています
間違いがあれば指摘してください
よろしくお願いします。

## 筆者の環境
Dockerで、ReactとRailsのサーバーを別々で建てている

## エラーの発生状況

ReactからRailsのサーバーにAPIリクエストを送るときに以下のエラーが発生
![スクリーンショット 2021-03-09 16.04.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699910/0b68a572-a2d7-4967-eb71-75ea49a354d5.png)

とりあえずエラー名で検索してみるとOracleのソケットのエラーコードが載っているサイトを発見

> ECONNREFUSED
> ホストがサービスを拒否した。これは、要求されたアドレスにサーバープロセスが存在しない場合に発生する 
> - [接続エラー（ネットワークインターフェース）](https://docs.oracle.com/cd/E19455-01/806-2730/sockets-9/index.html)

つまり、サーバーが見つけられてないっぽい？

## 解決法

インフラにDockerを使用しているのでコンテナのネットワークがどうなっているのかを調べる
[Dockerの公式リファレンス](http://docs.docker.jp/v1.11/compose/networking.html)に書いてあったが、コンテナ内から他のコンテナにリクエストを送りたいときは
`http://宛先サーバー名:宛先サーバーの内側のポート`となるらしい。

## 原因

自分の場合はAPIのチェックをブラウザで行っていたため、コンテナ外から
`http://localhost:4000（宛先サーバーの外側のポート）`で接続していて、これを流用していたから繋がらなかった。

## 別のエラーが出た場合

自分の環境ではすでに設定が終わっていたが、
Cross-Originの設定も必要になるので
まだやってない人はそれをする必要がある。
獣医師が必死にバイオインフォマティクスPythonによる実践レシピをwin10で動かす（その5）

# Biopythonで遊ぶ

使えるデータベースの確認
アクセスする際に自分の責任を明確にするためにもメールアドレスを書こう
一応Biopythonの仕様で1秒に4個以上のクエリーを投げ込むことはしないが、バグでどうなるかわからないので、要注意
過剰アクセスで1事業所が1週間アクセス禁止になった現場を見たことがある

```
from Bio import Entrez, Medline, SeqIO

Entrez.email = "put@your_email.here" 
handle = Entrez.einfo()
rec = Entrez.read(handle)
print(rec)
```

現状使えるDbListの一覧が見える
とりあえず犬のNGF（Nerve Growth Factor）のmRNA配列を取ってくる事を目標にする

```
#犬のNGFの遺伝子配列を取ってくる
handle = Entrez.esearch(db="nucleotide", term='NGF[Gene Name] AND "Canis Lupus"[Organism]')
rec_list = Entrez.read(handle)
id_list = rec_list['IdList']
hdl = Entrez.efetch(db='nucleotide', id=id_list, rettype='gb')

recs = list(SeqIO.parse(hdl, 'gb'))
print(recs)

```

これでNGFの情報が取得できた
設定はデフォルトのままなので20以上出てこない
けどどうせ3つしかないので良い
この後情報を抜くのにnameのカラムに記載があるものを選べば抜ける
なのでとりあえずXM_038690419の遺伝子情報を取得してみる

```
for rec in recs:
    if rec.name == 'XM_038690419':
        break
print(rec.name)
print(rec.description)
print(rec.seq)
```

目標は無事に達成
ついでにどんな情報があるのかも見てみる

```
for feature in rec.features:
    if feature.type == 'gene':
        print(feature.qualifiers['gene'])
    elif feature.type == 'exon':
        loc = feature.location
        print('Exon', loc.start, loc.end, loc.strand)
    else:
        print('not processed:\n%s' % feature)

for name, value in rec.annotations.items():
    print('%s=%s' % (name, value))
```

この配列ラブラドールレトリーバーから取られたものらしい
CDSの開始点は220番目から、終了は946番目の塩基
割と面白いこと書いてあるね
Rで地図を描く【その4: 白地図にポイントを記入】

# 0. 白地図にポイントを記入する方法

シリーズ「Rで地図を描く」では、3回にわたって白地図の作り方をご紹介しました。「その4」では、白地図にポイントを記入してゆく方法について解説します。

# 1. point関数を用いる

白地図にポイントを記入するには、`R`の`points`関数を用います。`maps`パッケージで描いた白地図だろうと`raster`パッケージで描いた白地図だろうと変わりません。至ってシンプルです。

### 1.1 points関数の使い方
基本的な使い方は次の通りです。`x`はポイントを打つ$x$座標（経度）、`y`は$y$座標（緯度）を指定します。

```
points(x, y) # このRコードは実行しないでください
```
実際に地図を作成していると、ポイントに色をつけたい、ポイントの形（丸、三角、四角など）を指定したい、といったポイントをカスタマイズする場面にしばしば遭遇します。この時有効なのが、`col`や`pch`などのオプションです。`col`は色を指定し、`pch`はポイントの形を指定します。

```
points(x, y, col, pch) # このRコードは実行しないでください
```

詳細な使い方を確認したい場合は、下記リンク先の記事をご参照ください。1.2以降で、`points`関数を使って地図にポイントを打つやり方を具体的に見ていきます。

http://cse.naro.affrc.go.jp/takezawa/r-tips/r/53.html


### 1.2 地図にポイントを打ってみる
`R`で次のコードを実行すると、添付の地図のように兵庫県明石市付近に赤いポイントが打たれます。

```
library(maps)
map("world", xlim = c(125, 145), ylim = c(30, 45))
map.axes()
map.scale(x = 135, ratio = F)
points(135, 35, col = "red", pch = 19)
```

![スクリーンショット 2021-03-09 16.08.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449575/ba0cd27b-447d-8b90-98fb-bedc7530b18e.png)

### 1.3 地図に複数のポイントを打ってみる
複数のポイントを同時に打つこともできます。その際、`points`関数に緯度経度を一つづつ与えるのではなく、緯度のベクトルと経度のベクトルを与えることとなります。では、以下のコードを実行し、明石付近(135, 35)と那須付近（140, 37）の2箇所に点を打ちましょう。

```
library(maps)
map("world", xlim = c(125, 145), ylim = c(30, 45))
map.axes()
map.scale(x = 135, ratio = F)
xcoor <- c(135, 140) # 経度のベクトル
ycoor <- c(35, 37) # 緯度のベクトル
points(xcoor, ycoor, col = "red", pch = 19)
```


![スクリーンショット 2021-03-09 16.30.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449575/6b5cff04-3630-8d17-6139-1f91ab7acd3f.png)
Visual Studio 2017 と 2019 を共存させる

結構解決に時間が掛かったので備忘録を残します。

## やりたかったこと

今まではv141のビルドツールがメインでしたが、v142のプロジェクトファイルがあり、そちらでビルドしたかった。

## TL;DR;

Visual Studio 2017をアンインストールしましょう。

## 調査内容

今まではVisual Studio 2017（以降vs201x）を使用していて、vs2017だとv142のビルドツールが使えずvs2019から使えるらしい。
vs_installerからvs2019が入れられるため、早速インストール。

## 起きた問題

vs2019を入れてビルドに取り掛かったところ、エラーが出てビルドが通らなかった。

```
エラー	MSB8020	v142 (プラットフォーム ツールセット = 'v142') のビルド ツールが見つかりません。
v142 ビルド ツールを使用してビルドするには、v142 ビルド ツールをインストールしてください。
または、[プロジェクト] メニューを選択するかソリューションを右クリックし [ソリューションの再ターゲット] を選択して、現在の Visual Studio Tools にアップグレードすることもできます。
```

## 原因と解決策

環境変数に`VCTargetsPath`の設定と`MSBuild`へのパスを通していたこと（されていた？記憶なし）が原因です。
vs2019用に`VCTargetsPath`と`MSBuild`を以下のように設定したらビルド出来ました。

**`VCTargetsPath`**
`C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\`

**`MSBuild`**
`C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin`


batでvs2017とvs2019を切り替えるようにしてもいいかもしれませんが、vs2017で出来ることはvs2019でもできる気がするので、特別な事情が無い場合はvs2017はアンインストールしましょう。
詳細画面にコメント機能を作成[忘備録]

仕組みも含めて、詳細画面にコメント機能を作成しましたが、ルーティングをネストしている点仕組みの理解を含め、実装には結構苦労したので忘備録として残しておきます。とりあえずコントローラだけ。

(comments_controller.rb) part1

```
class CommentsController < ApplicationController
  def create
    comment = Comment.new(comment_params)
    comment.task_id = params[:task_id]
    comment.save
    redirect_to task_path(comment.task.id)
  end

  private
  def comment_params
    params.require(:comment).permit(:content)
  end
end

```


(comments_controller.rb) part2

```
class CommentsController < ApplicationController
  def create
    comment = Comment.create(comment_params)
    redirect_to task_path(comment.task.id)
  end

  private
  def comment_params
    params.require(:comment).permit(:content).merge(task_id: params[:task_id])
  end
end

```

redirect_to の部分は以下のコードで代替できます。

```
redirect_back(fallback_location: root_path)
Capistrano自動デプロイ時のエラー。"fatal: not a valid object name: master"の解消メモ

参考記事の方が既に具体的なところまで書いてくださっているので、この記事自体にあまり価値はないかもしれませんが、自分用メモとして、またどなたかのお役に立てればと思い、ログを読み解く形で投稿しました。

# エラー発生〜解決まで
Capistranoでデプロイしようとした際にタイトルの様なエラーが出て中断。
じっくりログを眺めると、

```
git:create_release
〜〜〜
git archive master |　〜〜〜
fatal: not a valid object name: master
```

このcreate_releaseという工程中にエラーが発生しているのがわかる。その理由は、"not a valid object name: master"（「masterという名前のオブジェクトが有効ではない」）

キーワードは"git", "create_release", "master"あたりでしょうか。
CapistranoはGithubのリポジトリから引っ張ってきてデプロイするので、"git"と通信してアプリを"create&release"しようとしてる最中に"master"なるものが見つからず、「すみません　よくわかりません」という状況になっているということですね。
ちなみに"git archive master"とありますが"archive"とは「保管場所」を意味する単語なので、gitのmasterっていう保管場所？、、、つまりブランチのことですね。「masterなんてブランチないです」と怒られてしまった。

現在、Gitでいうところのmasterブランチは、Githubだとデフォルトで"main"になっていますが、Capistranoのデフォルトの仕様はmasterブランチを探しに行くようになっているみたいですね。
ほほ〜ん、と思って設定ファイルを眺めていると、コメントアウトされたこんな記述を見つけました。

```ruby:config/deploy.rb
# Default branch is :master
```


やはりそうか。じゃあ解決法は簡単で、Capistranoに対して「mainブランチを参照してね」と宣言してあげれば良いだろう。でもどうすれば。
ということでその方法を調べた結果参考記事に辿り着き、無事解決させていただきました。感謝致します！

```ruby:config/deploy.rb
set :branch, "main"　#追記
```

# あとがき
エラーが出た時にログをしっかり読み解くことって凄く大事だなと改めて痛感。
また今回のCapistranoにしても、あとはdeviseとかransackとか色んなgemもありますが、それらの設定ファイル等をじっくり眺めてみると意外な発見があったり、それがエラーとか問題の解決の近道になることも多いんだろうなと感じました。



# 参考にさせていただいた記事
[【Rails】Capistranoによる自動デプロイで発生したエラー（fatal: not a valid object name: master）](https://qiita.com/9999Fringe/items/74313b8d9adf6de91967)
仮想ゲストのお引越し速度比較～ダイレクト vs OVF vs Cross vCenter vMotion～

#はじめに
どうもこんにちは、VMware愛好家のいけふちです。

ある時、VMDKファイルを移行先に持って行く機会があり、Cross vCenter vMotion（以下、XVMとする）を用いて移しました。そこでふと、その他の方法だとどのくらい時間がかかるのか気になり、検証を行ってみました。

#検証方法
・約40GBの仮想ゲストを以下の3つの方法で次期側に持って行く。それぞれの作業中は回線に余計な負荷がかからないよう配慮する。
※1）さすがに社内検証環境と作業端末間の回線を負荷ゼロにはしていません。
※2）次期側にVMDKファイルのみを移せばよいが、その他のファイルを含んでいても可とする。

1.VMDKファイルをローカル端末にダウンロードして、次期側のデータストアにアップロードする。
2.仮想ゲストをOVFテンプレートでエクスポートし、次期側でインポートする。
3.XVMで次期側にマイグレーションする。

では実施した結果です。

#1.データストアからダイレクトに移行の場合
ZIP形式でダウンロードするようですね。圧縮率はあまり期待できなさそう...
![WS000009 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618957/7e53e63c-9471-0bb4-5c08-368577059312.png)

**結果**
ダウンロードは50分、アップロードは2時間20分の計3時間10分でした。

#2.OVFテンプレート化→デプロイの場合
OVFはVMware独自の圧縮形式のため、サイズがかなり小さくなっています。
（40GBの仮想ゲストが5.3GB）


エクスポートが16分
![WS000010 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618957/700b33e6-c66d-d640-de22-59fcd5829637.png)
インポートも16分でした。
![WS000013 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618957/0bae0ac0-ef23-e21e-8a44-a5b97c0a2b9e.png)
**結果**
計32分でした。ダイレクト方式と比べると約6分の1の時間で済みそうです。

#3.Cross vCenter vMotionの場合
**結果**
なんと驚異の約10分でした。これが最速のようですね。
![WS000012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618957/36a4a74c-e166-2536-bd17-73cee4cf2741.png)

#おわりに
弊社検証環境ではXVMが最速という結果となりました。
ただし現地ではライセンスの都合でXVMが使えない場合もあると思いますので、その際はOVFテンプレート方式を使うとよいと思います。

本記事が、移行案件等で参考になれば幸いです。

また、弊社Webサイトでは各種技術系記事を投稿しております。
[ITdo!/技術情報/いけふち](http://c.itdo.jp/author/ikefuchi/)
Cross vCenter vMotionの速度とvCSAのメモリ量の関係について

#はじめに
どうもこんにちは、VMware愛好家のいけふちです。

ある時、数TBの仮想ゲストを、Cross vCenter vMotion(以下、XVMという)を用いて移行するにあたり、どうすれば早くタスクが完了するか悩みました。そんなとき、
「vCenter Serverのメモリ量を増やせばXVMは速くなるのではないか」
と思いつき、さっそく社内検証環境をパワーオンし検証を行ってみました。

##検証内容
・仮想ゲスト
ストレージ = 40GB, 400GB
の2パターンを用意しました。仮想ゲスト名とストレージ以外に差異はありません。
・vCenter Server
移行元移行先ともvCSA 7.0を用いました。
vCPUとメモリは
(vCPU, メモリ) = (2, 12GB), (16, 32GB)
の2パターンで検証しました。
※ちなみに、(2, 12GB)はTiny相当、(16, 32GB)はLargeに相当します。
・XVMの実行パターン
①.vCSAのvCPUとメモリを(2, 12GB)にし、
40GBの仮想ゲストを実行後、400GBの仮想ゲストを続けて実行
②.vCSAのvCPUとメモリを(16, 32GB)にし、
40GBの仮想ゲストを実行後、400GBの仮想ゲストを続けて実行

##検証結果
①.40GBの仮想ゲストは10分、400GBの仮想ゲストは19分でした。
②.40GBの仮想ゲストは10分、400GBの仮想ゲストは18分でした。
⇒両者ほぼ変わらず...
※ESXiにてvCSAの消費メモリを監視しましたが、XVM実行中は
　12GBの場合、12GB
　32GBの場合、27GB
でした。一応増やした分のメモリは使われているようでした。

#おわりに
結果、ほぼ変わらない結果となりました。やはりMTUを9000にするなどして、ネットワーク的なアプローチをしないと早くならないかもしれません。
また違う観点で検証を行いましたら、記事にしようと思います。

なお、弊社Webサイトでは各種技術系記事を投稿しております。
[ITdo!/技術情報/いけふち](http://c.itdo.jp/author/ikefuchi/)
シェルススクリプトファイル内での変数の使い方メモ　〜Linuxメモ〜

こんにちはshoです。

今回は本当に基礎の基礎のメモです。
シェルスクリプト書いていてまだ書き方のルールが覚えられていないせいで

「日付出力どう書くんだっけ・・・」
「変数どう書くんだっけ・・・」

というなんとも情けないことが度々起こるので、その初歩的といいますか、めっちゃ基礎的な基礎の基礎の部分のメモです。



（※学習記録やメモ書き目的で始めました。ほぼ初学者レベルなので理解が浅いところや誤りがあるかと思いますがよろしくお願いします。またアドバイス等コメントいただけるとすっごく嬉しいです。早く先輩方のお力になれるよう精進します。）


#変数の使い方

${変数名}　と書く。または
$変数名　　と書く。
これだけ。（・・・{ }で囲むことに慣れなかった）

```
#!/bin/sh

file_name="file"
echo ${file_name}
echo $file_name
```

実行結果

```
file
file
```


#date出力の仕方

いくつかの書き方がある。

```
#!/bin/sh

echo "1" $(date +%Y%m%d_%H%M%S)
echo "2" $(date '+%Y%m%d_%H%M%S')
echo "3" "$(date +%Y%m%d_%H%M%S)"
echo "4" "$(date '+%Y%m%d_%H%M%S')"
echo "5" `date +%Y%m%d_%H%M%S`
echo "6" "`date +%Y%m%d_%H%M%S`"

```

実行結果

```
1 20210307_205411
2 20210307_205411
3 20210307_205411
4 20210307_205411
5 20210307_205411
6 20210307_205759
```


##まとめ

こう改めて整理してみると簡単でしたね。

いつも難しくしているのは自分でした。ややこしくしているのは自分でした。


はい。以上！
Cross vCenter vMotion実行中にクラスタの再設定が実行されない件

#はじめに
どうもこんにちは、VMware愛好家のいけふちです。

Cross vCenter vMotion(以下、XVMという)の実行中にクラスタの再設定を実行したところ、待てど暮らせど進捗が0％から増えない事象に出会いました。
本番の移行作業で、クラスタの再設定後に動作確認を行うことがあると肝が冷えてしまうので、類似の事象がないか検証してみました。

##XVM中にクラスタの再設定⇒進捗0%で固まる
検証環境でも再現できました。やはり、XVM実行中はクラスタの再設定が止まるようです。
![WS000004 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618957/adcc502e-d13f-f815-b4c3-0b3e3384d626.png)

また、XVMがトリガーなのは、完了時刻を見ると明らかですね。
![WS000005 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618957/bd63b2b2-e183-2b8a-c096-7da61569e98b.png)

以下、XVM以外のパターンでも試してみました。
（それぞれ、クラスター配下でタスクを実行し、タスクの合間にクラスタの再設定を実行しています）
##通常のvMotion中にクラスタの再設定⇒問題なし
あれ、いつものStorage vMotionではクラスタの再設定は完了しますね。
![WS000008 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618957/213c0dc5-de6c-916b-49c5-3965b7b53f2c.png)

##クローン作成中にクラスタの再設定⇒問題なし
こちらも問題なし。
![WS000006 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618957/3b4e700b-7e5b-fab4-262c-e6dcc7fef791.png)


##OVFテンプレートのエクスポート中にクラスタの再設定⇒問題なし
......。
![WS000007 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618957/27d34c34-0f56-0802-94c0-efa8082e7be6.png)

#おわりに
結果、XVM特有の事象かもしれませんが、これについてはサポートに聞いてみないと結論が出ないと思います。また、クラスタの再設定以外にも進捗が0%から進まないものがあるかもしれません。こちらは今後発見次第追記していこうと思います。

本記事が、移行スケジュールを組む際の参考になれば幸いです。

また、弊社Webサイトでは各種技術系記事を投稿しております。
[ITdo!/技術情報/いけふち](http://c.itdo.jp/author/ikefuchi/)