OmniAICreator/Qiita-1.07M huggingface dataset:
SQLiteが対応していないSQL文の仕様とALTER TABLE操作の対応法

# はじめに

SQLite3は構築が簡単であることや軽量で使い勝手はいいが、一部のSQL文が対応しておらず、苦労する部分がある。例えば、ALTER TABLE系の機能はRENAME COLUMNやADD COLUMNなどしか対応していない。

この仕様に辿り着くのも時間がかかったことと対処法が結構面倒なので、備忘として残しておく。
（やりたかったのはテーブル定義を変更するところなのでそれのやり方を）

# やりかた

大まかな手順は以下の通り

1. 元テーブルのCREATE TABLE文を取得する
1. 1で取得したSQLを基に、スキーマ定義を変更した一時テーブルを作成する
1. 2で作成したテーブルに、元テーブルのデータをINSERTする
1. 元テーブルをDROP TABLEする
1. 一時テーブルをRENAME TABLEする

やってること自体はシンプルだが、機械化するには2番目の操作が結構厄介。Pythonで対応してみたのが下の部分。（それでも、スキーマ定義の変更は都度設定が必要。。。。）

```python:SQLite3の操作
import sqlite3

con = sqlite3.connect('test.db')
cur = con.cursor()

create_table_sql = cur.execute("select sql from sqlite_master where name = 'target_table'").fetchone()[0]
create_temp_table_sql = (  # 一時テーブル作成SQLへの変更例
    create_table_sql
    .lower()
    .replace('target_table', 'temp_table')
    .replace(')', ', foreign key (test_fk) references test_table(id) )')  # 外部キーの追加文をいれる
)
cur.execute(create_temp_table_sql)
cur.execute('insert into temp_table select * from target_table')
cur.execute('drop table target_table')
cur.execute('alter table temp_table rename to target_table')

cur.close()
con.close()
```

これだと複雑な結合関係のテーブルの更新に苦労するので、他にいい手段がないだろうか。。。

# 参考

- [SQL Features That SQLite Does Not Implement](https://www.sqlite.org/omitted.html)
- [SQliteでカラム定義変更（カラム名変更、属性変更など）を行う最短ルート暫定版 - うつろぐ](http://distorted-unchi.hatenablog.com/entry/2017/11/30/002139)
UbuntuでImageMagickを使ってimageファイルをPDFに変換するときの注意

```
sudo apt install imagemagick
```

インストールして素のまま使うとUbuntuの場合、次のようなエラーとなる。

```
convert-im6.q16: not authorized `out.pdf' @ error/constitute.c/WriteImage/1037.
```

以前、convertコマンドで使われている`Ghostscript`にセキュリティーホールがあったための対策としてPDFファイルへの変換が出来ない仕様となっていたことが原因です。

# 直し方

次のようにリネームします。

```
sudo mv /etc/ImageMagick-6/policy.xml /etc/ImageMagick-6/policy.xmlout
```
これでエラー出なくなると思います。
Juliaインストールしてみた



https://twitter.com/yokoemon2112/status/1245334616187088896
> お陰さまで科研・基盤(C)「Julia言語を用いた新しい計算機数論システムの開発とその応用」が採択されました。
今年35歳なので、採択率の高い若手研究にも出せたのですが、背水の陣で基盤に通ったことに感謝。5年間 Julia 漬け（and 布教活動）になると思いますので、皆様のご協力をお願い致します。

という素晴らしいニュースを受け、久しぶりにJuliaを使いたくなりました。
__注意__: このtwitter accountは私ではないです。

今回はセットアップし、ベンチマークテストを実行してみて、その速度を味わってみようと思います。

## インストール

https://julialang.org/downloads/
から自分の環境にあうバージョンをDLして、デスクトップアプリケーションとしてのセットアップをすればよいです。


## Junoセットアップ

JunoはJupyterのIDEです。
これはAtomのプラグインとして実装されています。

インストールには以下のようにパッケージを選択し、`uber-juno`を選択すればいいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86021/35938a9f-46c1-e841-e0b4-f8ef616eaa77.png)

~~実際は自分はパッケージがインストールできずAtomが正常起動しなくなっため。~~
今回は以前別のPCでセットアップしてあったので、その設定を `sync-settings`を使っていれました

しかも、単純にsyncするだけでは、エラーになりましたが、
完全に同じエラーがあったので、これをみれば対処できました。
 http://docs.junolab.org/latest/man/faq/#Juno-doesn't-work-properly-after-an-Atom-update.-What-do-I-do?-1

最終的にインストールでき、こんな画面になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86021/bdfbb925-2ea0-4606-cd38-1063870c43f9.png)



インストールできたので、性能測定、描画ができるサンプルプログラムを実行しましょう。

## パッケージのインストール

最初に必要なPkgをインストールします。
REPLを `]`を押してpkgがインストールできるモードにした後、以下のように実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86021/4d25791b-a622-2613-50c8-5bd09c43a9f1.png)

今回のプログラムを実行するには以下3つが必要となります。

- BenchmarkTools
- TestImages
- Plots

## サンプルのコードを実行
```julia 
# %%
i = 1
j = 2
k = 3
@show i, j, k

# %%
@show 2i + 3j - 1k


# %% 関数の定義
tot_sum(n) = sum(k for k = 1:n)
tot_sum(10)

# %% ベンチマークツールで性能測定
using BenchmarkTools

a = @benchmark tot_sum(100)

@show a

# %% 画像plot
using TestImages
using Plots

cameraman=testimage("cameraman")
lena=testimage("lena")
plot(cameraman)
plot(lena)
```

やっぱりPython並のお手軽さでさくさくできるのいいですね。
Julia、本格的に使っていこうと思います。
Build OpenVpn server on CentOS 8


```
cm /tmp
wget https://raw.githubusercontent.com/Angristan/openvpn-install/master/openvpn-install.sh -O centos-8-vpn.sh
chmod +x centos-8-vpn.sh
sudo ./centos-8-vpn.sh
```
follow outputs and input your public IP. A openvep config file will be generated automatically.



Then, run openvpn.

```
sudo systemctl start openvpn-server@server.service
sudo systemctl enable openvpn-server@server.service
```


In addition to above, change firewall setting.

```
firewall-cmd --permanent --add-service openvpn
firewall-cmd --permanent --add-masquerade
firewall-cmd --reload
firewall-cmd --list-all
```

Reference:
https://www.cyberciti.biz/faq/centos-8-set-up-openvpn-server-in-5-minutes/
【Github】画像のサイズを指定する方法

通常，画像をドラッグ＆ドロップしてそのままコピー&ペーストするとこのようになります．

```
![代替テキスト](画像のURL)
```

しかし、これを `<img>` タグを使った方法に変更することで，画像のサイズを指定する`width`要素が使えるようになります．

```
<img src="画像のURL" width="画像のサイズ">
```


#参考資料
[GitHubの画像貼り付けでサイズを指定する方法](https://dackdive.hateblo.jp/entry/2015/05/08/110029)
GCP CloudAPIで"We recommend configuring the billing/quota_ project setting"というエラーが出た際の対処法

AccessContextManagerのCloudAPIを叩いた際に以下のエラーが出た

```bash
curl -H "Authorization: Bearer "$(gcloud auth print-access-token) "https://accesscontextmanager.googleapis.com/v1/accessPolicies?parent=organizations/12345"

{
  "error": {
    "code": 403,
    "message": "Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the accesscontextmanager.googleapis.com. We recommend configuring the billing/quota_
project setting in gcloud or using a service account through the auth/impersonate_service_account setting. For more information about service accounts and how to use them in your application, see https://cloud.google.com/docs/authenticat
ion/.",
    "status": "PERMISSION_DENIED"
  }
}
```

billingの設定が通ってないのか、ヘッダーに `X-Goog-User-Project: my-project` を入れることで解決

```bash
curl -H "X-Goog-User-Project: my-project" -H "Authorization: Bearer "$(gcloud auth print-access-token) "https://accesscontextmanager.googleapis.com/v1/accessPolicies?parent=organizations/12345"
```
Twitterのトレンドをミュートして快適なTwitterライフを！！

#TLが騒がしくない？
どうも、LilyMameokaです。お久しぶり。私ね、常日頃思っていたんですけど、**TL、騒がしくない？**
何かアニメが放送されている時間とか(日曜の朝とかね)、某コンビニ大手がキャンペーンやってる時とか、某ソシャゲがキャンペーンやってる時とか、某富豪やYoutuberがプレゼントキャンペーンやってる時とか、○断メー○ーとか...。普通にTLが賑やかなのはいいんですけど、先程挙げた、**見ている側には無益なツイート**でTLが騒がしいのは不快ですよね。~~どうでもいいツイートでTL埋めやがってクソが。~~
あと、折角現実逃避しにTwitterに来たのに、週刊誌が扱うような**THE☆俗世**なワードが流れてくるのもムカつくので...

**トレンドワードを片っ端からミュートして**平和なTLを取り戻したいと思いま〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜す！！！！

#トレンドの取得
まずはトレンドワードの取得です。ただし、トレンドワード全部から処理すると、かなりの量のユーザーをミュートしてしまうので(それは申し訳ないので)、ハッシュタグのついているものだけを取得したいと思います！

```python:get_trends.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tweepy

CONSUMER_KEY=''
CONSUMER_SECRET=''
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
ACCESS_TOKEN = ''
ACCESS_TOKEN_SECRET = ''
auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)

def get_trends(api):
    trend = api.trends_place(23424856)[0]
    trends = trend['trends']
    print(u"Trends:")
    for i in range(len(trends)):
        print(u"\t{0}".format(trends[i]["name"]))

if __name__ == '__main__':
    api = tweepy.API(auth)
    get_trends(api)
```

これを実行すると...

```
Trends:
	#この夏に水着姿を見たいキャラ
	#キン肉マンアニメ化
	#彼女からの予測変換でリア充がバレる
	#ドスパラ春のセールでほしいもの
	#少クラ
	#現金給付
	#まあたそ大先生
	#ムジカピッコリーノ
	#エイトちゃんのおたんじょう日会
	#あなたのおっさん度診断
	#関ジャニ8TV
	#かずみんモバメ
	#水着の上下重ねて
	#グラクロ攻略質問
	#うちで踊ろう
```

お！出てきたね〜〜〜。今回は日本のトレンドを対象にしているので場所のIDは23424856です。調べたら、東京は1118370らしい。

#平和なTLへ！！
さーて、本題。

**と思いきや！**なんと、TwitterAPIはキーワードミュートに対応していないとのこと。
https://stackoverflow.com/questions/55916527/is-there-a-way-to-create-and-destroy-muted-words-using-the-twitter-api
うーん。仕方ない。**その単語をツイートした人をミュートしちゃお☆**
私のTLの平和のためには多少の犠牲も仕方ないのだ！許してね♡


```python:trend_blocker.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tweepy

CONSUMER_KEY=''
CONSUMER_SECRET=''
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
ACCESS_TOKEN = ''
ACCESS_TOKEN_SECRET = ''
auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)

mute_words = []

def get_trends(api):
    trend = api.trends_place(23424856)[0]
    trends = trend['trends']
    for i in range(len(trends)):
        if trends[i]["name"].startswith("#"):
            mute_words.append(trends[i]["name"])
    
def mute():
    api = tweepy.API(auth)
    get_trends(api)
    count = 1 #各ワードにおけるお好みのミュート数を入れてください
    for mute_word in mute_words:
        print(mute_word)
        search_res = api.search(q = mute_word,count = count)
        for res in search_res:
            print(res.user.screen_name)
            api.create_mute(res.user.screen_name)
            print("--------------------------------------")

if __name__ == '__main__':
    mute()
```

よし！！！これで平和なTLが取り戻せた！素晴らしいね！
~~早速、快適なTLで現実逃避してきま〜〜〜〜〜〜〜〜〜す！！~~

#参考資料
http://docs.tweepy.org/en/latest/index.html
Mac初期設定

## 買った
MacBook Air 2020
macOS Catalina

## 最初にやる
* OSを最新にする
* トラックパッドの軌跡を速くする
* キーのリピートを速くする
* Caps LockをControlに置き換える
* 隠しファイル表示 -> Finderで「command + shift + .」
* [⌘英かな](https://ei-kana.appspot.com)
* [Macの起動音をOn/Offに切り替える](https://qiita.com/yumenomatayume/items/69ef0911d9a46145dfd5)

## よく使うやつ
```sh
# https://brew.sh
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

$ brew install bat colordiff ghq git go htop jq kotlin node tig tree yarn zsh
$ brew install clipy docker google-chrome intellij-idea iterm2 slack sourcetree visual-studio-code
```

## 設定

### zsh
[zshを使ってみる - Qiita](https://qiita.com/ryutoyasugi/items/cb895814d4149ca44f12)

### git
```sh
$ git config --global user.email 'XXX'
$ git config --global user.name 'XXX'

$ git config --global alias.st status
$ git config --global alias.cm commit
$ git config --global alias.br branch
$ git config --global alias.ch checkout
$ git config --global alias.sw switch
```

### GitHub
[GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~ - Qiita](https://qiita.com/shizuma/items/2b2f873a0034839e47ce)

### iTerm2
[iTerm2 にステータスバーが付いた - Qiita](https://qiita.com/delphinus/items/1748937aefeb241bdcee)

### peco
[pecoでzshのコマンド履歴検索を超快適にする！ - Qiita](https://qiita.com/shepabashi/items/f2bc2be37a31df49bca5)

### Octotree
https://www.octotree.io

Actionsタブとかでは無効にする設定しとく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110859/bb88fdf2-8027-8060-812b-034804aad4c4.png)
$php artisan migrateができない

#始めに
「はじめてのLaravel6入門 AWS Cloud9で学ぶ」という本で勉強しています。

#開発環境
PHP Version7.2
laravel Verson6.18.3


#$ php artisan migrateが実行できない

```
 Illuminate\Database\QueryException  : could not find driver (SQL: select * from information_schema.tables where table_schema = c9 and table_name = migrations and table_type = 'BASE TABLE')

  at /home/ec2-user/environment/cms/vendor/laravel/framework/src/Illuminate/Database/Connection.php:669
    665|         // If an exception occurs when attempting to run a query, we'll format the error
    666|         // message to include the bindings with SQL, which will make this exception a
    667|         // lot more helpful to the developer instead of just the database's errors.
    668|         catch (Exception $e) {
  > 669|             throw new QueryException(
    670|                 $query, $this->prepareBindings($bindings), $e
    671|             );
    672|         }
    673| 

  Exception trace:

  1   PDOException::("could not find driver")
      /home/ec2-user/environment/cms/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:70

  2   PDO::__construct("mysql:host=localhost;port=3306;dbname=c9", "root", "root", [])
      /home/ec2-user/environment/cms/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:70

  Please use the argument -v to see more details.
```

上記のエラー文が出てきて実行できない。

```
$ php -m | grep pdo
pdo_sqlite
```

"could not find driver"というエラー文を参考に、MySQLをインストールしようと試みるもうまくいかず。

#解決方法

```
sudo yum -y install php72 php72-cli php72-common php72-devel php72-mysqlnd php72-pdo php72-xml php72-gd php72-intl php72-mbstring php72-mcrypt php72-opcache php72-pecl-apcu php72-pecl-imagick php72-pecl-memcached php72-pecl-redis php72-pecl-xdebug
```

上記のPHPのバージョンを7.2に更新するコマンドで解決できた。
iOSアプリのAmazonリンクからAmazonアプリを起動する方法

>Info.plistにLSApplicationQueriesSchemesというキーでTypeをArrayにし、そこにアイテムを追加し、TypeをStringでvalueをcom.amazon.mobile.shopping.webにします

アソシエイトリンクの場合は、短縮URL`https://amzn.to/xxx`を使うと`Amazon モバイルは現在amzn.toでご利用いただけません`というエラーがでるので通常URLを使う。

```swift
urlString = "アソシエイトリンクの通常URLからhttps://を除いた文字列"
let urlStringWithSchema = "com.amazon.mobile.shopping.web://" + urlString
            guard let urlWithSchema = URL(string: urlStringWithSchema) else { return }
            if UIApplication.shared.canOpenURL(urlWithSchema){
                UIApplication.shared.open(urlWithSchema, options: [:], completionHandler: nil)
            } else {
                guard let url = URL(string: urlString) else { return }
                UIApplication.shared.open(url, options: [:], completionHandler: nil)
            }
```

一度アプリの該当画面からAmazonアプリを開く許可をすると、以後は許可を求められずに勝手にAmazonアプリが開く。これは Cunstom URL Schemas 

[Apple Developer のリファレンス](https://developer.apple.com/documentation/uikit/inter-process_communication/allowing_apps_and_websites_to_link_to_your_content/defining_a_custom_url_scheme_for_your_app)等にあるような、`URL Types`に値を追加する云々は、あくまでSafariなどでブラウジングしていて特定のURLを踏んだときに自社アプリを起動させるための設定なので混同しないように。

##参考文献

https://lima.world/iphone-url/

https://qiita.com/zakiyamaaaaa/items/96c6fb8ee5a93c963bbc

https://stackoverflow.com/questions/27693062/iphone-ios-amazon-scheme-uri-not-working-anymore-amzn-version-4-3-1-deep-li
※`amzn://content/item?id=<some valid id>`という方式は使えなくなったようだ。
VMware Playerで仮想ネットワーク環境を作成

# はじめに
クラスタを構築する業務を任させることになったため、練習としてまずVMwareで仮想ネットワークを構築しました。備忘録兼いつか来るかもしれない後輩のために本記事を書きました。

# 仮想ネットワーク概要
想定環境は以下の通り。計4台の仮想マシン（青色）を用いてネットワークを構築します。今回は外部ネットワークにつなぐ必要がないので、物理マシンの存在を無視するように設計します。
ネットワークアドレス(198.10.10.0/24)は適当につけています。
![想定ネットワーク.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464948/0a742d13-73fd-b153-60a9-045b0f83dcf7.png)

# 使用環境
使用した環境は以下の通り。
- 物理マシン：Windows10
- 仮想マシン：VMware Player 15
- 仮想マシンOS：CentOS7(計算用はCUIインストール)
- 外部ネットワークに仮想環境を繋げられない(社内LANとか、yumなど使えない)

※オフライン環境でOSをインストールかつNFSを使用したクラスタ構築をする場合(つまりyumを使いたいけど使えない場合)、インストール時にnfs-utilsをインストールしておく必要があります。管理端末はオプションからNFSサーバを選択、GUIを使う端末（今回はプリポスト端末）と計算端末はネットワークストレージサービスクライアントのオプションを選択してインストールしてください。また、簡易インストールではこれらオプションの選択ができないので注意してください。
この辺りは別で記事を作成します（気が向いたら...）

# 実施手順
## VMwarePlayerインストール・CentOS7の入手・インストールまで
[VMwareのページ](http://www.vmware.com/jp.html)からインストールファイルをダウンロードして、インストールをします。
インストール手順は[こちら](https://eng-entrance.com/linux-vmware-install)が参考になります。このページではisoファイルの入手からOSのインストール(GUI)までわかりやすく説明されています（ありがとうございました）。
CUIでのインストールは[こちら](https://qiita.com/sugimount/items/71d456f3af52a47c29b6)の記事が参考になります。CUIでインストールする場合、GUIと違いインストール時点で手動でIPアドレスを設定するので注意してください(後述)。

## 仮想ネットワーク設定
インストールが完了するとIPアドレスを設定していきます（インストール時にもできる）。
仮想マシン設定のハードウェアにあるネットワークアダプタを編集します。ネットワーク接続をカスタムに変更し好きなvmnet番号(0,1,8を除く)を一つ選択します。vmnetはざっくりいうとスイッチのようなものです。vmnetについてもっと詳しく知りたい場合は、[こちら](https://qiita.com/Higemal/items/b8124b047a3d0393e697)の記事がめちゃめちゃ参考になります。
この状態でOSを立ち上げ、ipアドレスを手動で設定します。上図のプリポスト端末（GUI）の場合、右上電源ボタンの右側の▼から[Wired]->[Wired Setting]を選択します。表示されたウインドウの中からWiredを選択、右下歯車を押下します。
下図のように、IPv4を開き、AddressesをManualに変更し、IPアドレスを設定します。
![IP設定例.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464948/6197472a-0f35-f99b-a864-cf82a5efb574.png)

この設定をGUIの他の端末でも同様に行います(同じネットワークアドレスで別のホストアドレスになるように設定すること)。

CUIの場合、紹介したインストール手順内のアドレス設定の際に、指定したいアドレスとネットマスクを設定してください。ただし、CUI版の場合そのままだと(仮想的な)有線がつながっていないという状況になっていることがあります。その場合インストール後、ターミナルから

```
nmtui
```
でNetworkManager TUIを起動してください。起動後Activate aconnectionを選択し、イーサネットをAcctivateに変更してください。

GUI・CUIともに設定が終わったら（途中でもいいけど）、pingコマンドでネットワークの疎通ができるか確認しましょう。

疎通が確認できれば終了です。

#最後に
今回は仮想ネットワーク環境構築の手順を（めちゃめちゃ他の人の説明を引用しながら）説明しました。参考になればいいねボタンを押していただけると嬉しいです！
MacOS + crontab で定時にチャイムを鳴らす

フリー素材サイト OtoLogic さんのチャイム素材を使う:

https://otologic.jp/free/se/school_bell01.html

好きなのをおもむろに配置します (この例ではホームディレクトリに配置してみました)．

`crontab` をいじります．

```sh
crontab -e
```

```crontab
0 10,13,19 * * * afplay ~/bell.mp3 > /dev/null 2>&1
```

リモートワークでもメリハリがつきます．

Linux だと X とかのからみで面倒くさそうですね．
ファルコン・パンチの表示順をランダムにする

# 作成にあたって
友人がpythonを用いてターミナル上動作するこれを作っていたので、僕はhtmlとjs使って作成してみました。
動けばいいだけだったので1つのファイルにまとめて書いています。

# コード
```html:index.html
<!doctype html>
<html>
<head>
<title>ファルコン・パンチ</title>

<script type="text/javascript">
    function exchangeText() {
        var text = document.forms.id_form.id_textBox.value.split("");
        target = document.getElementById("output");
        if(exchange(text)){
            target.innerText = exchange(text);
        }else{
            target.innerText = "";
        }
    }
    // 文字の順番を入れ替える
    function exchange(text) {
        for(i=0; i<text.length; i++){
            var rand = Math.floor(Math.random()*text.length);
            var tmp = text[i];
            text[i] = text[rand];
            text[rand] = tmp;
        }
        var output;
        for(i=0; i<text.length; i++){
            if(output){
                output = output + text[i];
            }else{
                output = text[i];
            }
        }
        return output;
    }
</script>
</head>

<body>
    <p><b>ファルコンのうんちぶり</b></p>
    <form name="form" id="id_form" action="">
        <input name="textBox" id="id_textBox" type="text" value="ファルコン・パンチ" />
        <input type="button" value="入れ替え" onclick="exchangeText()" />
    </form>
    <div id="output"></div>

</body>
</html>
```

# おわりに
実務経験が少ないため、どうかけば可読性が向上するのか等コメント頂ければ幸いです。
RaspberryPi 3にインストールしたCentOS7で「yum update」したときの「Cannot find a valid baseurl for repo: centos-kernel/7/armhfp」の回避方法

RaspberryPi 3にインストールしたCentOS7で、「yum update」を実行したら下記のエラーになってしまいました。

```
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile


 One of the configured repositories failed (Unknown),
 and yum doesn't have enough cached data to continue. At this point the only
 safe thing yum can do is fail. There are a few ways to work "fix" this:

     1. Contact the upstream for the repository and get them to fix the problem.

     2. Reconfigure the baseurl/etc. for the repository, to point to a working
        upstream. This is most often useful if you are using a newer
        distribution release than is supported by the repository (and the
        packages for the previous distribution release still work).

     3. Run the command with the repository temporarily disabled
            yum --disablerepo=<repoid> ...

     4. Disable the repository permanently, so yum won't use it by default. Yum
        will then just ignore the repository until you permanently enable it
        again or use --enablerepo for temporary usage:

            yum-config-manager --disable <repoid>
        or
            subscription-manager repos --disable=<repoid>

     5. Configure the failing repository to be skipped, if it is unavailable.
        Note that yum will try to contact the repo. when it runs most commands,
        so will have to try and fail each time (and thus. yum will be be much
        slower). If it is a very temporary problem though, this is often a nice
        compromise:

            yum-config-manager --save --setopt=<repoid>.skip_if_unavailable=true

Cannot find a valid baseurl for repo: centos-kernel/7/armhfp
```

「***/etc/yum/vars/kvariant***」ファイルが欠落していることが原因のようです。

下記のコマンドを実行して、「***/etc/yum/vars/kvariant***」ファイルを作成することによって回避できました。

```
echo rpi2 > /etc/yum/vars/kvariant
```

###参考情報
- [https://forums.centos.org/viewtopic.php?t=70696](https://forums.centos.org/viewtopic.php?t=70696)
- [https://github.com/scaleway/image-centos/issues/32](https://github.com/scaleway/image-centos/issues/32)
【CSS】フォントサイズの指定方法

## はじめに
CSSでのフォントサイズの指定方法には２つの分類がある。
##### 絶対値
サイズが固定される。指定されたサイズで表示され、他の要素の影響を受けない。
##### 相対値
指定された要素自体の値を持っていない。サイズは親要素のフォントサイズによって変わる。依存する親要素のフォントサイズが変われば、それに応じて相対値を指定された要素のフォントサイズも変わる。


### フォントサイズ指定によく使われる単位
#### px
絶対値
指定されたサイズが16pxであれば親要素のサイズに関係なくフォントサイズは16px

#### %
相対値
親要素のフォントサイズに対する割合。親要素のサイズによって指定した要素のサイズも変わる。emと同じ。

```sample.css
html {
  font-size: 100%;
}
div {
  font-size: 16px;
}
/* 親要素の半分の8px */
div > p {
font-size: 50%;
}
```

### em
相対値
％と同じ。親要素のフォントサイズに影響される。

```sample.css
html {
  font-size: 100%;
}
div {
  font-size: 16px;
}
/* 親要素の半分の8px */
div > p {
font-size: 0.5em;
}
```

### rem
相対値
ルート（html）要素が基準になる。

```sample.css
/* 16px */
html {
  font-size: 100%;
}
/* html要素の2倍の32px */
div {
  font-size: 2em;
}
/* html要素の半分の8px */
div > p {
font-size: 0.5em;
}
```

### vw 
ビューポートの幅の1/100の大きさを持った単位。ビューポートが100pxの場合1vw、1vwは1pxとなる。
画面サイズによってフォントサイズが変わる。

↓画面サイズによって可変する単位

| 単位              |        説明　　  | 
|:----------------:|:-----------------:|
| vw               |ビューポートの幅の1/100(100vwで横幅いっぱい)|
| vh               |ビューポートの高さの1/100(100vhで縦幅いっぱい)|
| vmax             |ビューポートの高さか幅の大きいほうの1/100|
| vmin             |ビューポートの高さか幅の小さいほうの1/100|

##### レスポンシブデザインと画面サイズによって可変する単位
vwで指定すると画面サイズが小さい時にはフォントサイズも小さくなり、画面サイズが大きくなればフォントサイズも大きくなるのでレスポンシブデザインに使用するとフォントサイズが扱いやすくなる。
**320px**（一番小さいデバイスの幅）を基準としてフォントサイズを指定する。これで画面サイズに合わせてフォントサイズも大きくなってくれる。

##### サイズ早見表
| px              |     vw  | 
|:---------------:|:---------------:|
| 10px            |  3.125vw        |
| 11px            |  3.4375vw       |
| 12px            |  3.75vw         |
| 13px            |  4.0625vw       |
| 14px            |  4.375vw        |
| 15px            |  4.6875vw       |
| 16px            |  5vw            |

##### 計算方法
```
フォントサイズ14pxの場合
14px ÷ 320px = 0.04375(4.375%) = 4.375vw
```



## ブラウザのデフォルト

ブラウザのデフォルトフォントサイズは

```
100% = 16px = 1em = 1rem
```
Perl と Ruby で解く AtCoder ABC146 B - ROT N

# はじめに
*[Pocket詳解 Perl/CGI辞典](https://www.amazon.co.jp/dp/4798012971)*をパラパラっと眺めておりましたら、*pack/unpack* 関数が目に留まりましたので、投稿いたします。
# 次の文字を取得する場合
'A' の次の文字 'B' を取得する場合、
***C言語***でしたら、'A' + 1 より 'B' を得られます。
しかし ***Perl*** の場合、'A' + 1 の結果は、1 となってしまいます。
# pack/unpack 関数
よって、次の文字を取得する場合、一旦バイナリ値に変換し足し算を行ってから、*char* 値に逆変換することにより、期待する操作が行えます。

***pack***   char値をバイナリ値に変換
***unpack*** バイナリ値をchar値に変換

|Perl|Ruby|Python|
|:--:|:--:|:--:|
|pack/chr|pack/chr|chr|
|unpack/ord|unpack/ord|ord|
```unpack.pl
unpack("C*", 'A'); # => 65
pack("C*", 66);    # => B
```
```unpack.rb
"A".ord            # => 65
66.chr             # => B
```
***Python*** に *pack/unpack* があるかどうかは不明 ~~適当~~
# B - ROT N
*[AtCoder ABC 146 B - ROT N](https://atcoder.jp/contests/abc146/tasks/abc146_b)*

```perl.pl
use v5.18;
use warnings;

chomp (my $n = <STDIN>);
chomp (my $s = <STDIN>);
my @s = split '', $s;
map {$s[$_] = chr((ord($s[$_]) + $n) % ord("A") % 26 + ord("A"))} (0..@s-1);
say join('', @s);
```
```ruby.rb
n = gets.chomp.to_i
s = gets.chomp.split('')
(0..s.size-1).each do |i|
  s[i] = ((s[i].ord + n) % "A".ord % 26 + "A".ord).chr
end
puts s.join()
```
むむっ、*ruby* のスッキリ感は凄いですね。
# まとめ
+ ***Perl*** の関数 *pack/unpack* を覚えた
+ ***Ruby*** のメソッド *chr/ord* も覚えた


参照したサイト
*[pack テンプレート文字列](https://docs.ruby-lang.org/ja/latest/doc/pack_template.html)*
*[instance method String#ord](https://docs.ruby-lang.org/ja/latest/method/String/i/ord.html)*
*[ABC146 感想](https://qiita.com/micasa/items/7c00d1546c2ed9902a03)*
Proxy有りでUnityのAndroidビルド



ユーザー名フォルダの直下にある **.gradle** フォルダの中に

**gradle.properties** という名前のファイルを作成

作成したファイルをエディタ等で開き、下記のように記述（Http・Https両方必要かは環境による気がする）

```gradle.properties
systemProp.http.proxyHost=Proxy指定ホスト
systemProp.http.proxyPort=8080
systemProp.http.proxyUser=ログインユーザーID
systemProp.http.proxyPassword=パスワード

systemProp.https.proxyHost=Proxy指定ホスト
systemProp.https.proxyPort=8080
systemProp.https.proxyUser=ログインユーザーID
systemProp.https.proxyPassword=パスワード

```


■参考URL
https://answers.unity.com/questions/1621072/how-to-fix-gradle-build-error-when-building-androi.html
さすがに無いと思うが、古いLinuxを使っててTLS1.2に対応できない対処方法

Chromeが81にバージョンアップされると、TLS1.0や1.1を使っていると警告ブロックになるとのうわさがあるため、弊社のサーバは問題無いけど、困っている人がもしかしたらいるかも！？という前提で簡単にまとめておきます。
OpenSSLとmod_sslだけソースからコンパイルしたものを使う方法もあるようだけど、OPenSSLのバージョンが新しくならなかったので速攻であきらめました。

#大まかな手順
ApacheとOpenSSLをソースからコンパイルする。移行をできるだけ簡単にしたいので、Apacheの設定ファイルは基本的にそのまま使用する。

#サーバ環境
Debian5(lenny)
Apache2.2.9
OpenSSL0.9.8

# 手順
####OpenSSL
まずはOpenSSLをDLしてコンパイル。今回は「openssl-1.0.1q.tar.gz」を選択。こっちは簡単。
https://www.openssl.org/source/old/1.0.1/

```shell
./config --prefix=/usr/local/ssl shared zlib
make
make install
```
続いてldconfigで共有ライブラリを設定。下記のファイルを新規で作成したパスを追加。

```shell:/etc/ld.so.conf.d/openssl.conf
/usr/local/ssl/lib
```

キャッシュファイル更新後、grepで確認。

```shell

ldconfig
ldconfig -p | grep -i libssl
        libssl.so.1.0.0 (libc6) => /usr/local/ssl/lib/libssl.so.1.0.0
        libssl.so.0.9.8 (libc6, hwcap: 0x0008000000008000) => /usr/lib/i686/cmov/libssl.so.0.9.8
        libssl.so.0.9.8 (libc6, hwcap: 0x0004000000000000) => /usr/lib/i586/libssl.so.0.9.8
        libssl.so.0.9.8 (libc6, hwcap: 0x0002000000000000) => /usr/lib/i486/libssl.so.0.9.8
        libssl.so.0.9.8 (libc6) => /usr/lib/libssl.so.0.9.8
        libssl.so (libc6) => /usr/local/ssl/lib/libssl.so
        libssl.so (libc6) => /usr/lib/libssl.so
```
libssl.soが二つあるけど、気にしないようにした。

####Apache
下記サイトより、同バージョンもしくは、ちょっと新しいバージョンをＤＬして展開。今回は「httpd-2.2.10.tar.gz」を使用。
https://archive.apache.org/dist/httpd/

```shell
./configure --enable-so --enable-ssl --with-ssl=/usr/local/ssl/ --with-included-apr --with-included-apr-util --enable-mods-shared="all ssl"
make
ここでエラー
　ssl_engine_init.c:576: error: ‘STACK’ undeclared (first use in this function)
　ssl_engine_init.c:576: error: (Each undeclared identifier is reported only once
```
新しいOpenSSLでは「STACK」が「_STACK」に変更されているので、下記２ファイルを修正。「httpd-2.2.16」以降では対応できている可能性あり。

```shell
httpd-2.2.10/modules/ssl/modules/ssl/ssl_engine_init.c
httpd-2.2.10/modules/ssl/modules/ssl/ssl_util_ssl.c
```
そしてコンパイル。

```shell
make
make install
```

設定ファイルを修正。追加だけ書いておきます。

```shell:/usr/local/apache2/conf/httpd.conf
Listen 443

LoadModule log_config_module modules/mod_log_config.so
LoadModule ssl_module modules/mod_ssl.so
※mod_sslはここで読むのがポイント。パッケージconfのパスを変更してもOpenSSLが新しくならない。
※他のLoadModuleはコメントアウト

//パッケージの設定ファイル
Include /etc/apache2/mods-enabled/*.load
Include /etc/apache2/mods-enabled/*.conf

NameVirtualHost *:80
NameVirtualHost *:443

//パッケージの設定ファイル
Include /etc/apache2/sites-enabled/
```

#最後に

パッケージApacheを停止してソースバージョンを起動。下記コマンドなどで確認できます。

```shell
openssl s_client -connect ******.com:443
```
Windows＋Docker＋Laravelでの開発時に「There is no existing directory at "C:\........\storage\logs" and its not buildable: No such file or directory」が出る時の対処

## 環境
Windows10 pro
Docker for Windows
Laravel 7.x
ローカルのDockerでphp、nginxのコンテナを立てています。

## 状況
/config/logging.phpの設定を変えた後、反映させるためにWindows側のコマンドプロンプトで「php artisan config:cache」を打ったら急に出るようになりました。
ネットで情報を探すと再度キャッシュを消すと直る等ありましたが、直らず..。

## 解決した方法
Docker側phpのコンテナにCliで入り、そっちの方で上記コマンドを打つと解消されました。
しっかりと原因特定まではできてませんが、Windows側でやるとパスの解決がWindows仕様になってしまうとかですかね。

## 余談
解決後、`Log::debug(storage_path());`でログに吐いたら正しいパスはこうなってました。

```
[2020-04-03 09:58:48] local.DEBUG: /var/www/APP_NAME/storage
```
PHPファイルをhtml-loaderにかけたときにエラーが出るときの対策

PHPプロジェクトをejs（ejs-html-loader）で管理していて、共通ヘッダーのincludeなど、`?>` で終わらないファイルが存在する場合、**productionビルドでエラーが出る**。

```
Parse Error: <?php
```

これは [html-loader](https://github.com/webpack-contrib/html-loader)（正確にはそこから利用される [html-minifier-terser](https://github.com/DanielRuf/html-minifier-terser) ）のminimizeオプションでパースエラーとなるため。

これを回避するためには html-loader に `continueOnParseError: true` を指定してやれば良い。


```webpack.config.js
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = [
	{
		context: path.resolve(__dirname, 'dev'),
		entry: {
			// ?> で終わらないファイルを含む
			index: './index.php'.
			header: './header.php'
		},
		output: {
			path: path.resolve(__dirname, 'public'),
			filename: '[name].php'
		},
		module: {
			rules: [
				{
					test: /\.php/,
					exclude: /node_modules/,
					use: ExtractTextPlugin.extract({
						fallback: "raw-loader",
						use: [
							{
								loader: 'html-loader',
								options: {
									minimize: {
										continueOnParseError: true
									}
								}
							},
							{
								loader: 'ejs-html-loader',
								options: {
									context: {
										// タイムスタンプをPHPファイルに渡すとか
										timestamp: +new Date()
									}
								}
							}
						]
					})
				}
			]
		},
		plugins: [
			new ExtractTextPlugin('[name].php')
		]
	}
];
```

### 2020/06/03追記

こちらでうまく行かない場合、minimizeをfalse（ソースの圧縮を行わない）にする。
最新のhtml-loaderだとこちらでないとうまく行かないかもしれない。


``` webpack.config.js
								loader: 'html-loader',
								options: {
									minimize: false
								}
```


参考： [【備忘録】HTMLMinifierの全オプションについて調査した](https://qiita.com/ryo_hisano/items/9d41cd447a69943f8eb1)
vimの検索「○○以外の行」

#vimの検索「○○以外の行」

正規表現で攻めると「否定」は意外にややこしい．
vimではうまく行かないことが多い．

で、調べたら、"LogiPat" という便利なコマンドが！！！

[pi\_logipat \- Vim日本語ドキュメント](https://vim-jp.org/vimdoc-ja/pi_logipat.html)

```
:LogiPat !"hogehoge"
または
:LP !"hogehoge"
```

で行けるじゃん！すげえ！**抜け道感半端ない！**

※追加：TomosurebaOrangeさんにコメントいただきました．
```:v/hoge```
でも単純な「否定検索」が可能です．これは":!g"と同じ意味のコマンドです．

":g"コマンドといえば"grep"の語源になったもので，
```:g/regex/p```
で検索したものを出力します．":!g"":v"はその論理否定．
```:v/hogehoge/s/hoge/age/```
というふうに，sコマンドにつなげたりできますね．

ですがこれはexコマンドなので，visualモードで検索文字にジャンプするとかそういうことはできません．exモードで完結できる，いわば論理的な使い方ができる人向けですね．

(TNKS: TomosurebaOrangeさん)
djangoのセッション保持期間について調べてみた

# 疑問点

djangoアプリの作成中にrunserverでアプリの再起動した場合、
画面をリロードしたり、URLを直接叩いてもログインしたままの状態となっていた。
views.pyで定義した`@login_required`を疑ったが問題なかった。

そもそもログインセッションをどのタイミングで更新しているのか、
どれぐらいの期間で保持しているのか、ログインセッションについて調べたことを忘備録として作成する。

djangoのセッションについては主に↓を参照した

* [公式doc セッションの使いかた](https://docs.djangoproject.com/ja/3.0/topics/http/sessions/)
* [【Django入門】sessionの使い方](https://www.sejuku.net/blog/31661)

# セッション情報の入出力

セッション情報はdjango_sessinoテーブルにセッション情報データを管理しており、
ログイン時はセッションデータをinsertし、ログアウト時はセッションデータをdeleteしている。
つまり、django_sessinoテーブルにセッション情報データが登録されている間が認証中となる。

上記はデータベースを使ったセッションの管理方法であり、
ファイルやクッキーを使ったセッションの管理方法は対象外とする。

# セッションの永続化

ブラウザの終了でセッションを破棄するかはパラメータ`SESSION_EXPIRE_AT_BROWSER_CLOSE`で制御しており、デフォルト値は**False**。

ブラウザ終了時のセッションを
* True －破棄する
* False－破棄しない

`SESSION_EXPIRE_AT_BROWSER_CLOSE`がFalseの場合、セッション情報は利用者のクッキーで保管される。
保存期間は`SESSION_COOKIE_AGE`パラメータで制御され、デフォルト値は1209600(**2週間の秒表記**)。

# まとめ

* 画面を開いている間でログインセッションを有効にする場合は`SESSION_EXPIRE_AT_BROWSER_CLOSE`をTrueにする
* 一定期間でセッションタイムアウトを行うには、`SESSION_EXPIRE_AT_BROWSER_CLOSE`をFalseに、`SESSION_COOKIE_AGE`に期間を指定する。
* djangoのチュートリアルに出てこない内容は難しい
MATLABでGitを操作しよう (第6回 : クローンを作成する)

引き続きMATLAB GUIによるGit操作の第6回目
作成環境は最新のR2020aですが、第5回まで使っていたR2019bでも操作方法は同様です。
操作自体は簡単なので、短めの記事となっています。

作成環境 MATLAB **R2020a**
作業前提 GitHubアカウントを作成しておくこと

[第1回 : プロジェクト作成とGUIの説明](https://qiita.com/stozaki/items/e4fa14c36f6c134e53e7)
[第2回 : git add/git commit](https://qiita.com/stozaki/items/4bacb2e988c74f7a16e4)
[第3回 : チェックアウト "特定のコミットに戻る"](https://qiita.com/stozaki/items/e618748b867b6a609333)
[第4回 : ブランチ作成](https://qiita.com/stozaki/items/9711d48b63fcf4be4b20)
[第5回 : リモートリポジトリとの連携 (git push/git pull)](https://qiita.com/stozaki/items/757b3fa687016a14a0a1)
**▶ 第6回 : クローンを作成する**
第7回 : 応用1
第8回 : 応用2

今回は、リモートリポジトリのクローンを作成します。
MathWorks社のドキュメントには「クローン」というキーワードで書かれているのですが、MATLABのツール上に「クローンを作成する」という様なアイコンやコマンドは見つからないので、少し戸惑うかもしれません。
公式のドキュメントには、単にリモートリポジトリからクローンを作成する方法が記載されていますが、本記事では、プロジェクト作成からクローンを作成する方法を紹介します。
単にリモートリポジトリからクローンを作成する場合は[**こちら**](https://jp.mathworks.com/help/matlab/matlab_prog/retrieve-from-git-repository.html)

#### 操作1 : GitHubにリモートリポジトリを作成する
これは前回の記事を参考にして頂ければと思います。[第5回 : リモートリポジトリとの連携 (git push/git pull)](https://qiita.com/stozaki/items/757b3fa687016a14a0a1)

#### 操作2 : プロジェクトを使ってクローンを作成する
「新規作成」＞「プロジェクト」＞「作成元Git」を選択して新規プロジェクトを作成します。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/87be1260-f518-0ff9-fa6e-fd7c2fb361b8.png)

「ソース管理からの新規プロジェクト」ダイアログが起動するので、リモートリポジトリのパスとサンドボックスのパスを設定します。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/464758fb-c2f5-93e9-d667-8bb2e31bfd4e.png)

「取得」をクリックすると「フォルダーを作成しますか？」というダイアログが起動するので「はい」をクリックします。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/05c4d154-b61d-37dd-68ef-299a3d119d94.png)

プロジェクトの作成を促されるので、プロジェクト名を設定して「OK」をクリックします。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/3b6b6563-70c4-674b-1301-b642ec5422f1.png)

この後、必要に応じてプロジェクトパス設定や起動・終了設定を行えば完了です。



次回、応用1としてスタッシュを扱う予定です。
MathWorksのドキュメントには[**ここ**](https://jp.mathworks.com/help/matlab/matlab_prog/push-and-fetch-with-git.html)の下の方に少しだけ記載があります。
私自身も操作に手間取ったので、まとめてみようと思います。(応用1の前に1回割り込みがあるかも)
2020年 PDFをWordに簡単変換するツール5選

#####PDFとは？
PDFは文字、図形、表などを紙に印刷するようにレイアウト（配置）したページの状態を保存するためのファイル形式の名前です。Portable Document Format（ポータブル・ドキュメント・フォーマット）の頭文字を取ったものです。
転送、保存、読みやすい「ポータブルドキュメント形式」を意味しますが、直接編集できないため、PDF変換に対する要求はますます高まっています。中でも、PDFからWordへの変換が最も一般的な要件です。 使いやすく、文字化けのない高い変換品質を備えたPDF to Wordツールが必要な場合は、このコンテンツが最適です！ 次に、いくつかの優れたPDF変換ツールをお勧めします。

#####1.iLovePDF
iLovePDFは完全無料のPDFの為のオンラインサービスです。使い方はとても簡単で、PDFの結合、分割、圧縮、officeファイルのPDF変換、PDFからJPGへの変換など他にも多くの機能があります！
「ilovepdf.com」は、オンラインで複数のPDFファイルを結合したり、ひとつのPDFファイルを複数に分割できるサービスだ。手元にPDF編集ソフトがない場合に、結合や分割、さらにこれらの機能を組み合わせてのページの入れ替えといった操作をオンラインで行なうことができる。
https://www.ilovepdf.com/ja
![alt](https://jp.scrapestorm.com/wp-content/uploads/2020/03/1.ilovePDF.png)

#####2.PDFから簡単変換
『PDF から簡単変換！』は、日常のお仕事上でよく使われているPDF ファイルからワード (Word)、エクセル(Excel)、パワーポイント(PowerPoint)、HTML、EPUB、画像ファイル形式に簡単かつ高精度に変換してくれます！非常に便利です。複数のPDFファイルを一括でMicrosoft Word形式の文書に変換することが可能。PDFをドラッグ＆ドロップするだけで、テキストファイルを抽出・変換してくれます。簡単にPDFをEPUBに変換し、Latin、Cyrillic、ほとんどのアジア各言語及び主流のiPad 、iPod Touch、Sonyリーダーなど電子ブックリーダーに対応します。
https://www.wondershare.jp/win/pdf-converter.html
![alt](https://jp.scrapestorm.com/wp-content/uploads/2020/03/2.PDF%E3%81%8B%E3%82%89%E7%B0%A1%E5%8D%98%E5%A4%89%E6%8F%9B.png)

#####3.PDF Shaper
PDFの変換、編集、結合、分割ができるユーティリティーツールです。
PDFからテキストやイメージの抽出、RTFへの変換ができるほか、PDFからイメージ、イメージからPDFへの相互変換、ページの回転や削除、PDFメタデータの追加、PDFページの抽出、複数PDFを一つにまとめる結合、パスワードによる暗号化のできるセキュリティ機能など幅広い機能を一つのソフトで利用できます。
https://www.pdfshaper.com/download.html
![alt](https://jp.scrapestorm.com/wp-content/uploads/2020/03/3.PDF-Shaper.png)

#####4.LightPDF
LightPDFは、素人ユーザー向けのシンプルで効率的なオンラインPDFエディターです。 すべての機能はダウンロードまたはインストールせずにWebサイドの操作に基づいており、Webページを開く限り、PDFをWord、PNG、JPG、PPT、またはWord、Excelなどの他のさまざまな形式に簡単に変換できます。
https://lightpdf.com/jp/
![alt](https://jp.scrapestorm.com/wp-content/uploads/2020/03/4.LightPDF.png)

#####5.Smallpdf
Smallpdfは、ウェブ上で利用できるPDF作成サービスです。WordやExcellなどのOfficeファイルをPDFに書き出したり、逆にPDFをWordやExcellなどに変換することができます。ウェブ上のサービスなので、Smallpdfのページにブラウザでアクセスしていただければすぐに利用できます。トップページを見ていただくとわかるように、様々なコンテンツが用意されています。
https://smallpdf.com/jp
![alt](https://jp.scrapestorm.com/wp-content/uploads/2020/03/5.Smallpdf.png)
日本語の動詞における文生成器の開発

動詞と助動詞をつなげるpypiパッケージを作成したので紹介します
## 動詞と助動詞を組み合わせるライブラリの使い方

```
$ pip install kotodama
$ python
$ > from kotodama import kotodama
$ > print(kotodama.transformVerb("行く",{"過去","伝聞","希望","です・ます"}))
-> 行きたかったらしいです 
```
詳細は[github](https://github.com/tennmoku71/kotodama)を見てください

以下は蛇足です

# 対話システムではなぜ動詞の変換が必要なのか

チャットボットやロボット対話などを研究していると、動詞の形を変えたいという時がちょくちょくあります
例えばtwitterなどから、「オーストラリアでパンダを見たけど、超かわいかった」というツイートを収集し、それをチャットボットに話させる場合

```

・「オーストラリアでパンダを見たけど、超かわいかった」とそのまま言わせる
・(場所:オーストラリア,対象：パンダ,動詞：見る)を抽出し、「[場所]で[対象]を[動詞]」というテンプレートを用意しておき文字列を置き換えることで「オーストラリアでパンダを見る」と言わせる
```

簡単な方法で済ませようとすると、こういったやり方があります
ロボットの記憶をもたせたりなど、ちょっとリッチな処理をしようとすれば文の内容に関して記号論的に取り扱える後者の手法がありがたかったりします

このとき「オーストラリアでパンダを見る」とだけ言われても聞き手は不自然さを感じます。最低でも「オーストラリアでパンダを見た」といった過去形になおしたほうがよいですし、「オーストラリアでパンダを見たらしい」と過去＋伝聞の形にしたほうがユーザに「どこの動物園？」とか聞かれても「ネットで聞いた話だから詳しくはわからない」とか逃げ道ができたりします。

さらに音声認識と音声合成を組み合わせて音声対話システムとする場合、例えば音声合成システムによっては丁寧語しか自然に話せないといった場合が多いです（ニュースやアナウンサーの発話を元に作られている場合が多いため）

そうすると「オーストラリアでパンダを見たらしいです」というように、過去＋伝聞＋丁寧といった形が欲しくなります

もちろん、「見たらしいです」＝「見たと聞きました」と言い換えができるので、過去＋伝聞＋丁寧といった必要な組み合わせが予めわかっているなら

```
「動詞の過去形＋と聞きました」[過去,伝聞,丁寧]
「動詞の原型＋ことをしたいです」[過去,伝聞,希望,丁寧]
「動詞の連用形＋たかったらしいです」[過去,伝聞,希望,丁寧]
「動詞の連用形＋たいそうです」[希望,伝聞,丁寧]
```
という形で、動詞の活用形生成エンジンと、使う助動詞の組み合わせの数だけテンプレートを用意しておけば目的が達成できそうです

ですが、あの助動詞が使いたい、この助動詞がほしい、と思うたびにテンプレートを作りなおすことが面倒になってきたため、汎用的な動詞と助動詞を組み合わせて文生成を行うモジュールを作ってしまうことにしました

## 基本的なアルゴリズム

中高の授業で習ったような話ですが、動詞と助動詞を組み合わせるためには

```
動詞の活用形＋助動詞＋（必要なら）終助詞
```
という形になります
このとき、動詞の活用形の種類[未然形,連体形,連用形,終止形,仮定形,命令形]はその直後に続く助動詞によって決まります
つまりこういうことです

![無題のプレゼンテーション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163759/cabbf0c6-f94e-3e39-0b70-a36fdeaff29d.png)


また、「見る」に対して「希望」「過去」と言った形で複数助動詞をつなげる場合「どちらが先に来て、どちらが後に来るのか」というのもルールがあり

```
見る/希望/過去 => 見たかった　自然
見る/過去/希望 => 見たたく　　不自然
```
のように過去に対しては希望が先に連なるというルールがあります
ですので、動詞に助動詞をつなげるためには

```
1. 動詞・助動詞の活用形を生成するライブラリを作成
2. 与えられた助動詞を並べ替えて順番を確定する（先頭は動詞）
3. 先頭から順に活用形を生成する(後ろの助動詞が何かによって活用形の種類が確定する)
```
という処理をしています

## 何が難しかったのか

一例を挙げます

### 「です」と「ます」の順序の違い


意味的には

```
です：丁寧な断定
ます：丁寧
```
と、違いは一般的に議論されているみたいですが、使う側としては「とにかく丁寧な感じが出せたらいい」「です・ます調に変換したい」という場合が多いので「です・ます」というラベルで定義しています
ここで問題になるのが、「です」と「ます」のどちらを使えばいいのか？ということです

動詞の活用に限定すると

```
見る/です・ます/過去 => 見ました
見る/希望/です・ます => 見たいです
見る/過去/希望 => 見たかった

ます ＞ 過去 ＞ 希望 ＞ です
```
同じ「見る」でも「です」の場合も「ます」の場合もあります
つまり助動詞の組み合わせによって決まると考えたほうが良さそうです

いくつかの組み合わせを試したうえで

```
並び替えの順番 = ["使役", "可能", "受け身", "自分の希望", "他人の希望", "ます", "否定", "過去", "推定", "伝聞", "様態", "例示", "勧誘", "です"]
```

と定義し、与えられた助動詞の順番が一番遅いものが何なのかによって「です」「ます」が決まります

```
です = {"自分の希望", "推定", "伝聞", "様態", "例示", "勧誘"}
ます = {"使役", "可能", "受け身", "他人の希望", "否定", "過去"}
```
このあたりは知見を見つけられなかったので、誰か詳しい方がいたら教えてください

## 最後に

形容詞に対応させたり、格助詞「は・が」をどうやって使い分けるかなど、文生成器の開発に関心のある人がいましたらご協力いただけるとうれしいです
記事の内容の間違いのコメントもお待ちしています
OpenlayersでResolutionを使ってスケールフィルタする際にハマったこと

# Mapに設定したResolutionとは異なる範囲の地図画像がMapServerから返ってくる
OpenlayersとMapserverの組み合わせており、ImageWMSレイヤを使って複数レイヤの地図画像を1リクエストで取得しようとした場合、Mapserver側でスケールフィルタを設定する必要がある。Openlayers側でのスケールフィルタはレイヤ単位であるため、複数レイヤを表示する目的のImageWMSに対してスケールフィルタを設定すると、すべてのレイヤを同時にON⇔OFFと切り替えることしかできないからだ。

ImageWMSはMapserverへリクエストを送信する際に、現在のResolutionからBBOXを計算し、地図のピクセルサイズと共にリクエストパラメータに設定してくれる。MapserverはこのBBOXと地図のピクセルサイズからスケールを計算するわけだが、これがOpenlayersとMapserverで一致しない場合があり、スケールフィルタの表示範囲外のResolutionをOpenlayers側に指定しているのにも関わらず、Mapserverから返ってくる地図画像には出力されてしまっている場合や、その逆の現象が発生する現象に遭遇した。

## 解決方法
ol.Map生成時のoptionsにpixelRatioという項目があり、これに1を明示的に設定することで解決した。特に理由がなければ地図を生成する際はこの項目には1を指定することを忘れずに。
turbolinkのページごとの使用・不使用について

色々調べたものの、意外と時間を食ったので書きました。

#ページごとに消すには、２つの方法がある。

1. data-turbolinks="false"を、ページのトップの親要素に入れる.
2. content_for?を使用する

---
###1. data-turbolinks="false"を、ページのトップの親要素に入れる.

1ページだけなど、使用しないページが少ない場合は、１番だけで済む。
ポイントは、**最上位の親要素**にいれること。
他の記事で、親要素に入れると書いてあるが、該当リンクの親要素では効かない。
ページ全体の親要素にいれること。

```ruby:app/views/
<article data-turbolinks="false">
  <div>
    <a>
  </div>
</article>
```
こんな感じ。

---
###2. content_for?を使用する

具体的な使用法はこちらに書いてあったので、ご紹介。
基本的には、キーを決めて、そのキーの有無でページの処理を決めるイメージ。

https://qiita.com/Cheekyfunkymonkey/items/216bf7426493e6213927

---

ほとんど1番の方で済みそうですよね。
Git　アウトプット

#Gitって？
####バージョン管理システムのこと。
つまり、ファイルの記録や、変更履歴を残すもの。
複数人での開発で重宝されます。
例えば、誰がどこを変更したなどの記録は全て残ります。
また、Gitはバージョン管理システムの中でも分散型と呼ばれます。
分散型メリットは、それぞれの人のパソコンでファイルの変更などの作業を行えるため、いつでもどこでも変更が可能です。

#Gitを使うメリットって？
・分散型であること

・元の状態に戻せること
→例えエラーが起きてしまっても大丈夫。前に戻ることができます。

・リリースサイクルが短くなる。
→分散型でそれぞれが同時並行で開発が行えるし、コードレビューもスムーズに行えるため。

・変更の差分が見れるのはGitのメリット！
→$git diffとかね。

・オフラインでのローカル環境でも作業が可能

#最後に
また、徐々にこの記事をアップデートしていきます。
forループでparallelを

```
fx () {
  name=$1
  age=$2
　echo $name $age
}
```

みたいな関数を並列でやりたいと思う。どうしてもprallelで。
引数リストがタブ区切りのテキストで与えられているもしくはパイプの向こうからやってくる場合。

```
hoge 10
fuga 20
piyo 30
```

例えばとかいうnenrei.txtみたいなファイルがあった時

```
cat nenrei.txt | while read name age; do
  parallel --colsep '\t' fx $name $age
done
```

でいける。並列数を制限したい時は

```
cat nenrei.txt | while read name age; do
  parallel -j 3 --colsep '\t' fx $name $age
done
```

とかすれば良い。


```
cat nenrei.txt | while read name age; do
  parallel -j 3 --colsep '\t' fx $name $age
done > kekka.txt
```

とかすれば結果は書き込まれるが終わった順になるのでランダムに並びます。
Pythonで毎日AtCoder #25

### はじめに
[前回](https://qiita.com/taxfree_python/items/1ca14488b2c46a0b6c05)

### #25
おすすめされた問題を解きます。
[ABC105-C](https://atcoder.jp/contests/abc105/tasks/abc105_c)

**考えたこと**
まず、普通の2進数にするときの手法を考えます。[これ](https://sci-pursuit.com/math/binary-number-conversion.html)で10進数を2進数に変換します。これを-2進数版にします。変更点は、余りは自然数になるのでうまく余りを調整しないといけない点です。
-2で割りきれるときは余りが出ないのでそのままn//2します。余りが出る時は、n-1してから-2で割るとうまく計算できます。
この計算方法でappendしていくと、答えの順番が逆なのでreverseします。あとは、joinでstrにするだけです。

```python
n = int(input())

if n == 0:
    print(0)
    quit()
base = []
while n != 1:
    if n % -2 == 0:
        base.append('0')
        n //= -2
    else:
        base.append('1')
        n -= 1
        n //= -2
base.append('1') #最後に1するのを忘れない
base.reverse()
ans = ''.join(base)
print(ans)
```

### まとめ
楽しい。では、また
SCPで踏み台の向こうにあるホストへ多段接続してファイルを一発で送る方法

- 環境
    - 接続元
        - CentOS Linux release 7.6.1810 (Core)
        - OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017
    - 踏み台ホスト : Amazon Linux release 2 (Karoo)
    - 置き場ホスト : Red Hat Enterprise Linux Server release 5.11 (Tikanga)

# やりたいこと : 踏み台の向こうにある置き場ホストに一発でファイルを転送したい
ファイルを接続元から踏み台において、踏み台から置き場において・・・というのが面倒くさい。
![2020-04-03 17.18.36.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/5079d146-2f29-95ac-920b-2264432f8352.jpeg)

# SCPで`ProxyCommand`を使って多段接続すればいい
- 参考
    - [ssh/scp多段接続〜踏み台サーバを越えて〜 - Qiita](https://qiita.com/S-T/items/18af2bfcc4e5a72202da)
    - [鍵認証で踏み台経由で多段scp接続する - かべぎわブログ](https://www.kabegiwablog.com/entry/2019/01/24/140000)

```bash:フォーマット
# 例）特定ディレクトリにある拡張子jarのファイルを全部転送する
# -r : ディレクトリ内を再帰的にコピーします。
# -o : 設定ファイル(ssh_config)で使われている形式のオプションを ssh に渡す
# -W : %hと%pを本来の接続先とそのポートへ置換する
$ scp -i {置き場鍵} -r -o ProxyCommand='ssh -i {踏み台鍵} -W %h:%p {踏み台ユーザ}@{踏み台アドレス}' {自分ディレクトリパス}/*.jar {置き場ユーザ}@{置き場アドレス}:{置き場ディレクトリパス}
```

# やってみた
SSHでも同じように`ProxyCommand`を使って多段接続すれば、踏み台の向こうにあるホストへ一発でログインできる。

```bash
# SCPでファイルを転送する
$ scp -i ~/.ssh/okiba.pem -r -o ProxyCommand='ssh -i ~/.ssh/fumidai.pem ponsuke@12.134.567.890 -W %h:%p' /home/ponsuke/HOGE.war ponsuke@10.0.2.1:/tmp/.
Enter passphrase for key '/home/ponsuke/.ssh/fumidai.pem':
Enter passphrase for key '/home/ponsuke/.ssh/okiba.pem':
HOGE.war                                                                                                                   100%   38MB  44.2MB/s   00:00
Killed by signal 1.

# SSH接続しておいたファイルを確認しに行ってみる
$ ssh -i ~/.ssh/okiba.pem -r -o ProxyCommand='ssh -i ~/.ssh/fumidai.pem ponsuke@12.134.567.890 -W %h:%p' ponsuke@10.0.2.1
Enter passphrase for key '/home/ponsuke/.ssh/fumidai.pem':
Enter passphrase for key '/home/ponsuke/.ssh/okiba.pem':
Last login: Thu Apr  2 14:49:44 2020 from 10.0.3.182
# ちゃんと送られていた
$ ls /tmp/
HOGE.war
```


# .ssh/configに書いて楽をする方法
「踏み台の向こうにある置き場ホストに一発でファイルを転送」をコマンドで書くと異様に長いし覚えられないので`~/.ssh/config`に設定を書くと楽になりました。

```config
# 踏み台
Host fumidai
    HostName 12.134.567.890
    User ponsuke
    IdentityFile ~/.ssh/fumidai.pem

# 置き場
Host okiba
    HostName 10.0.2.1
    User ponsuke
    IdentityFile ~/.ssh/okiba.pem
    ProxyCommand ssh fumidai -W %h:%p
```

上記にのように`~/.ssh/config`を書くと簡単に多段階接続してSCPできます。

```bash
# configに設定を書いた場合
$ scp -r {自分ディレクトリパス}/*.jar okiba:{置き場ディレクトリパス}

# configに設定を書かない場合
$ scp -i {置き場鍵} -r -o ProxyCommand='ssh -i {踏み台鍵} -W %h:%p {踏み台ユーザ}@{踏み台アドレス}' {自分ディレクトリパス}/*.jar {置き場ユーザ}@{置き場アドレス}:{置き場ディレクトリパス}
```
Ｃ言語　ALDS1_2_C　Stable Sort

##問題
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_2_C&lang=ja


##コード

```c
#include <stdio.h>

typedef struct
{
    char mark;
    char num;
} Card;

static void swap(Card *a, Card *b)
{
    Card tmp = *a;
    *a = *b;
    *b = tmp;
}

static void print_array(Card array[], int array_len)
{
    for (int i = 0; i < array_len; i++)
    {
        printf("%c%c", array[i].mark, array[i].num);
        if (i != array_len - 1)
            printf(" ");
    }
    printf("\n");
}

/* 選択ソート */
static void selection_sort(Card A[], int N)
{
    int min_index;

    for (int i = 0; i < N; i++)
    {
        min_index = i;
        for (int j = i; j < N; j++)
            if (A[j].num < A[min_index].num)
                min_index = j;
        if (i != min_index)
            swap(&A[i], &A[min_index]);
    }
    print_array(A, N);
}

/* バブルソート */
static void bubble_sort(Card A[], int N)
{
    for (int i = 0; i < N; i++)
        for (int j = 0; j + 1 < N - i; j++)
            if (A[j].num > A[j + 1].num)
                swap(&A[j], &A[j + 1]);
    print_array(A, N);
}

/* 安定性判定(A[]には必ずバブルソート済みの配列を入れる) */
static void isStable(Card A[], Card B[], int N)
{
    for(int i = 0; i < N; i++)
        if(A[i].mark != B[i].mark){
            printf("Not stable\n");
            return;
        }
    printf("Stable\n");
    return;
}

int main(void)
{
    int N;
    char card[3];
    Card A[36];
    Card B[36];

    scanf("%d", &N);
    for (int i = 0; i < N; i++)
    {
        scanf("%s", card);
        A[i].mark = card[0];
        A[i].num = card[1];
        B[i] = A[i];
    }

    bubble_sort(A, N);
    isStable(A,A,N);
    selection_sort(B, N);
    isStable(A,B,N);
    return 0;
}
```

##ポイント
安定なソートか、の判断は、安定なソート比べることでわかる。
今回の場合は、バブルソートと比べることで安定かどうかを判断した。

##所感
- バブルソートの昇順と降順でfor文の条件のところが変わることの理解が甘かったので、手間取った。
- 構造体を使うのは思いつかなかった。

所要時間85分

【復習】

- 2020/04/05
    - OK,イメージできた
    - 実装はまだ
タスクスケジューラのバッチが動かない[終了コード(0x1)]時にやること

急いでる人向け。

**1.手動でたたいて実行できているかを確認。**
　そもそもバッチは動きますか？という確認。ここでひっかかることはまずないはず。

**2.バッチファイル名に括弧を使用していないか**
　**終了コード(0x1)と検索するとバッチのディレクトリ設定～が先にでてきますが、ここにもトラップがあります。**
　括弧を使用するとだめらしいです。
　私チンパンなのでここで1時間くらい無駄にしました、みんなも凡ミスに気を付けてね！
　
**3.全般タブ：セキュリティオプション項目で「最上位の特権で実行する」にチェックが入っているか**
　凡ミス系統。

**4.トリガータブ：「トリガーの編集」の詳細設定項目で有効にチェックが入っているか**
　これも凡ミス系統。

**5.操作タブ：「操作の編集」の開始(オプション)項目にバッチファイルまでのディレクトリパスが設定されているか**
　batファイルでしか作らないからこの場面に遭遇した事はないのですが。
　パワーシェルとかそのあたりの方は上の項目と合わせて要注意。

私は2と4をよくやらかします。
このあたりを見直すだけで動くようになる可能性がぐっと上がるんじゃないでしょうか。
Tableauで3つ以上のメジャーを可視化する

#はじめに

Tableauでグラフを表現する際、2つのメジャーを使いグラフを作ることはよくありますが、
3つ以上のメジャーを使ったグラフを作りたいというときの参考まで。

#テストデータ
テストデータは本の「タイトル」「売上」「利益」「数量」とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270976/aff8ab63-d980-d3d3-b05c-92efe800f073.png)

#1．タイトルに対し「売上」と「利益」の積上グラフを作る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270976/54e97a92-f231-65f5-718e-55c531c3ca89.png)

##1-2．軸の数値が積上げのまま
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270976/e9907475-7d45-3c92-1834-be2282b5813b.png)

#2．スタックマークをOFFにする
スタックマークをOFFにすることで、2つのメジャーをオーバーラップさせる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270976/bbed498e-a671-fa0f-dacc-4efb98aac25b.png)

**下記のようになります。**
（積みあがっているのではなく重なっているため、軸の数値も値の大きい方が適用）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270976/2316f06a-2398-ccaf-e162-8ebe88deaebf.png)

#3．幅やグラフ種類を変え見やすく
メジャーネームをCtrlキーを押しながら「サイズ」へドラッグ＆ドロップ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270976/0776cbab-92f5-0cdf-40a3-b483ca31b091.png)

とか、グラフの種類を線グラフなど表現したい形へ変える

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270976/2ab13740-7d9f-3d69-b6eb-2815afcae799.png)


#4．最後に「数量」の軸を追加する

例では

- 売上、利益は棒グラフ
- 数量は線グラフで二重軸に設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270976/fedae0c1-70dd-06fb-581e-a5090c184028.png)

#おわりに
1つのグラフに表現するメジャー数を増やすことで、まとめて情報を伝えることは出来ますが、
情報が増えるほど伝えたい内容が薄くなり、人が理解するのも難しくなりますので、
用量、用法を守って正しく使いましょう！
VirtualBoxでクリップボードの共有ができない

# 現象
2020/04/02現在、以下の構成でクリップボード共有ができなかった

|構成|OS|バージョン|
|:---|:---|:---|
|VirtualBox|-|6.1.4.r136177|
|Host OS|Windows|10|
|Guest OS|Ubuntu|18.0.4.4LTS|

* Guest Additionインストール済
* 対象のvmで[一般] -> [高度] の [クリップボードの共有][ドラッグ & ドロップ]が "双方向"

ドラッグ & ドロップや画面のリサイズは機能するが、クリップボード共有のみ機能しない

# 原因
最新版のGuest Addition(6.1.4)で正常に動作していない[^1]

clipboardのプロセスがない

```
pldb@pldb-vm:~$ ps aux | grep '/usr/bin/VBoxClient'
pldb     1505  0.0  0.0  60760   380 ?        S    08:55   0:00 /usr/bin/VBoxClient --seamless
pldb     1506  0.0  0.0  60760   380 ?        S    08:55   0:00 /usr/bin/VBoxClient --display
pldb     1507  0.0  0.0  60892  2908 ?        S    08:55   0:00 /usr/bin/VBoxClient --display
pldb     1509  0.0  0.0 192996  2928 ?        Sl   08:55   0:00 /usr/bin/VBoxClient --seamless
pldb     1519  0.0  0.0  60760   376 ?        S    08:55   0:00 /usr/bin/VBoxClient --draganddrop
pldb     1521  0.2  0.0 193512  2884 ?        Sl   08:55   0:17 /usr/bin/VBoxClient --draganddrop
pldb     3104  0.0  0.0  22556  1028 pts/0    S+   11:13   0:00 grep --color=auto /usr/bin/VBoxClient
```


```
pldb@pldb-vm:~$ ps aux | grep '/usr/bin/VBoxClient --clipboard'
pldb     5362  0.0  0.0  22556  1028 pts/0    S+   11:28   0:00 grep --color=auto /usr/bin/VBoxClient --clipboard
```

以下のように起動させてもコピペはできない

```
pldb@pldb-vm:~$ /usr/bin/VBoxClient --clipboard

pldb@pldb-vm:~$ ps aux | grep '/usr/bin/VBoxClient --clipboard'
pldb     5659  0.0  0.0  60760   380 ?        S    11:33   0:00 /usr/bin/VBoxClient --clipboard
pldb     5660  0.0  0.0  60760   380 ?        S    11:33   0:00 /usr/bin/VBoxClient --clipboard
pldb     5663  0.0  0.0  22556  1036 pts/0    S+   11:33   0:00 grep --color=auto /usr/bin/VBoxClient --clipboard
```

# 解決
1つ前のバージョン（6.1.2）に落とすことで暫定的に回避できる

http://download.virtualbox.org/virtualbox/6.1.2/
*VBoxGuestAdditions_6.1.2.iso*

ubuntuをインストールした時と同様に、isoファイルをダウンロードして光学ドライブに入れれば良い
表示されたデスクトップ上のCDアイコンを開き、[ソフトウェアの実行]すればインストールできる

残念ながら次バージョンが出るまではこのような対応になってしまう

[^1]: [Copy paste not working on Virtual box 6.1 running Ubuntu 18.04 on Windows 10 Machine](https://forums.virtualbox.org/viewtopic.php?f=6&t=97052) / [[Resolved] Kali: Bidirectional Clipboard Issue](https://forums.virtualbox.org/viewtopic.php?f=3&t=96087)