OmniAICreator/Qiita-1.07M huggingface dataset:
[2019] Laravelを始める人へ　Mac  laravelインストーラーの導入方法

#Laravelのプロジェクトには2つの作り方がある

[公式](https://laravel.com/docs/6.0)のInstallationページを見ると、


- Via Laravel Installer
- Via Composer Create-Project

の２つがある。（viaは「経由」って意味の英単語）

今回は１つ目のLaravelインストーラーを使っての導入方法について。

Laravelインストーラーの方が、Composerを使ってプロジェクトを作る方法よりも少しだけコマンドが楽に。

#Laravel Installerをダウンロード

ターミナルを開いて
`composer global require laravel/installer`
をペースト。エンター。

で、**ここで終われば話は早い！！**

スッゲー簡単。

でも[公式](https://laravel.com/docs/6.0)さんによると、どうやらまだ終わりじゃないみたい。

#環境変数PATHを設定

環境変数PATHを設定?なんか怖い・・・。










しかし、まだ逃げるのは早い！

>Make sure to place Composer's system-wide vendor bin directory in your $PATH so the laravel executable can be located by your system. This directory exists in different locations based on your operating system; 

こいつは一体何を言っているのか？

ざっくり言うとこんな感じ。



1. PCにインスールされている**「Composer」**というパッケージ管理システムには、**binフォルダ**というものがある。
2. この**binフォルダ**がLaravelのプロジェクト作成に必要。
3. その**binフォルダ**の場所を、PCにインストールされたLaravelインストーラーに知らせる必要がある。
4. だから設定ファイル（.bash_profile）という、色々な「設定」が書かれてある「ファイル」に、**binファイルへのをPATH(行き方)**を書いてあげてねー

みたいな感じ。。。（間違ってたらすいません。あくまでイメージとして。。。）



#コマンドで環境変数PATHを設定

ターミナルで以下のコマンドをコピペ。

`$ echo 'export PATH="$HOME/.composer/vendor/bin:$PATH"' >> ~/.bash_profile`

このコマンドでは設定ファイルの.bash_profileに、binファイルへの行き方を書いた。

次に
`$ source ~/.bash_profile`
で追加した変更を反映させる。

**これでターミナルを再起動すれば、Laravelコマンドが利用できるはず！**

`$ laravel new プロジェクト名`

で、プロジェクトが作れたら

`$ php artisan serve`

の後に

`Laravel development server started: <http://127.0.0.1:8000>`

みたいに表示されたら、ブラウザでstarted以降のhttp://〜
にアクセスしてみましょう。

<img width="1272" alt="スクリーンショット 2019-09-11 18.42.23.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/96611b30-7ff5-e1a4-9b83-0e1f2efc4272.jpeg">

こうなってたら成功。

**※Laravelインストーラーではバージョン指定できず、最新版でプロジェクトが作られます。バージョン指定してプロジェクトを作成したい場合は、composerで作りましょう！**

`composer create-project laravel/laravel=5.7 sample`

こんな感じでね。


---

###参考
 https://code-graffiti.com/use-the-laravel-installer/
UbuntuにChromeをインストールする

# はじめに
UbuntuにChromeをインストールした手順書です。
Ubuntuには、デフォルトのWebブラウザとして「Mozilla Firefox」がプレインストールされているが、Chromeを使いたい場合は、多少手間ではあるが、新規にインストールする事になります。

# 環境
Utuntu16.04.5 LTS

# 手順

先ずは、自分の環境に、確かにChromeがインストールされていない事を確認する

```aa
apt list --installed google*
```

パッケージリストにChromeの情報が記述されていないため、自分で追加するところから行わないといけない
*Bシェルを実行して、google.listの最終行に、deb～で始まる１行を追加している*

```aa
sudo sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
```

下のコマンドで、確かに登録された事を確認する

```aa
ls -l /etc/apt/sources.list.d
cat /etc/apt/sources.list.d/google.list
```

公開鍵をダウンロードして、更に、公開鍵をapt-keyで登録する
*wgetはHTTP経由でダウンロードするコマンド。ダウンロードした、公開鍵をapt-keyコマンドに受け渡している*

```aa
sudo wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
```

ここで、パッケージリストを最新の状態にする

```aa
sudo apt update
```

ダウンロードをする前に、リモートリポジトリに、ダウンロードしたいパッケージが確かに存在する事を確認する
*リモートリポジトリとは、ダウンロード元、アプリの配布元サーバーの事。ここにあるパッケージが、aptコマンドでダウンロードできるという事*

```aa
apt list google*
```

ここまでが前準備で、いよいよ本番作業、インストールをする（結構時間が掛かります）

```aa
sudo apt-get install google-chrome-stable
```


自分の環境に、確かにインストールされた事を確認する

```aa
apt list --installed google*
```

# おまけ

TechPitに教材を執筆しています。学習にどうぞ。

https://www.techpit.jp/courses/190

# 参考記事

https://qiita.com/spiderx_jp/items/e6189a736ddec14ffa23
[NumPy基礎] 1次元配列 ⇔ 多次元配列

##1次元配列 → 多次元配列
reshape()メソッドを用いて各次元の要素数を指定することにより、1次元配列を任意の次元の配列に変換できます。配列の構造が分かっていない場合は、事前にshapeプロパティを用いて各次元の要素数を確認すれば良いでしょう。
以下の例では、$\begin{bmatrix}
1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\
\end{bmatrix}$ を $\begin{bmatrix}
1 & 2 & 3 & 4 \\\
5 & 6 & 7 & 8 \\
\end{bmatrix}$ に変換しています。

```py 
import numpy as np

data_1 = np.array([1,2,3,4,5,6,7,8])
print(data_1)
print(data_1.shape)

data_2 = data_1.reshape(2, 4)
print(data_2)
```
最初から $\begin{bmatrix}
1 & 2 & 3 & 4 \\\
5 & 6 & 7 & 8 \\
\end{bmatrix}$ を作りたいのであれば、以下のとおり1行で作ることもできます。

```py 
data = np.array([1,2,3,4,5,6,7,8]).reshape(2,4)
print(data)
```

##多次元配列 → 1次元配列

多次元配列を1次元配列に変換したい場合はいくつか方法があります。

### ravel() と flatten()
ravel() と flatten()はいずれも配列を1次元に平滑化（flatten）します。
flatten()を用いた場合は、新しくメモリを使用して配列を新規作成して返り値とします。そのため、返り値の配列の要素を更新した場合も、元の配列の要素は変わりません。
ravel()を用いた場合は、元の配列の形状を直接変更するため、処理速度が速いです。しかし元の配列の要素をそのまま残すことはできません。

```py
data = np.array([[1,2,3,4],[5,6,7,8]])
print(data.ravel())
print(data.flatten())
```
###reshape()
勿論、reshape()を用いることもできます。

```py
data = np.array([[1,2,3,4],[5,6,7,8]])
print(data.reshape(-1))
```
-1を使うと、指定した要素数以外は勝手に調節した配列に整形されます。以下では、4行2列の行列に整形しています。

```py
data = np.array([[1,2,3,4],[5,6,7,8]])
print(data.reshape(4,-1))
```

###多次元配列への応用
上記の方法を用いると、$(a, b, c, d)$ の形状の4次元配列 $X$ について、$(b*c*d, a)$ の形状に変更したい場合、以下のような方法で変更できます。

```py
X = X.reshape(X.shape[0], -1).T  # X.T: the transpose of X
```
stravaからglobal heat mapのデータを頂く

# 動機

自転車乗りにとって今年一番ではないかと思われるビッグニュース
[ルートラボ終了のお知らせ](https://latlonglab.yahoo.co.jp/close.html)

代替サービスをいろいろ探していますが、
実験の意味も含めて、自分でルート検索サービスを作ってみるのも面白そうだな、と。
で、以下のblogを発見、真似してみることにしました。
[ちゃりラボblog - Strava heatmapを使ったOSRM最適化](http://charilab.sakura.ne.jp/blog/2017/10/26/001-3/)

まずは Heatmap の取得から...

# stravaからglobal heat mapのデータを頂く

URLが変わっています。
新しいURLはこちら。
https://heatmap-external-b.strava.com/tiles/ride/hot/1/0/0.png

フォーマットは
https://heatmap-external-b.strava.com/tiles/ {移動手段} / {色} / {Zoom} / {x} / {y}.png

移動手段には ride / run / both / water / all などが選べます。
色は hot / blue など
[Strava Global Heatmap](https://www.strava.com/heatmap#7.00/-120.90000/38.36000/blue/all)
をいじると選択肢がわかると思います
(URLの変化に注目してください)

Zoomは1から11までOK。
12以上を指定すると

```console
authentication is now required for data access beyond zoom level 12, please login to strava.com and then visit /auth
```
と叱られます。
authすればいいのですが、今回は `zoom = 11` を使うこととします。

x と y はタイルの index です
例えば、`zoom = 1` ならば、世界は4分割なので、

```
x = {0, 1}
y = {0, 1}
```

の範囲が有効な index となります。

# 欲しい場所の index を調べる

じゃ、[彩湖](https://ja.wikipedia.org/wiki/%E8%8D%92%E5%B7%9D%E7%AC%AC%E4%B8%80%E8%AA%BF%E7%AF%80%E6%B1%A0)はどこなの？
となった時に手探りで値を探すのは大変！！
でもいいページを見つけました。
[osrmのタイルサービスのデモページ](http://map.project-osrm.org/debug/#11.47/35.7957/139.7246)

赤い線で区切られた区画ごとに zoom/x/y が記述されています。
この値を Strava Heatmap のURLに適用すると、その場所にヒートマップ(png画像)が取得できます。
便利！

はい、彩湖です
https://heatmap-external-b.strava.com/tiles/ride/hot/11/1818/805.png?px=512

# 複数のタイルを取得して大きな地図を作ってみる

タイル一枚一枚ではなく、広い範囲を取得して、つなげて大きな地図が欲しくなりますよね。
curlと[ImageMagick](https://imagemagick.org/index.php)で簡単にできました。
便利な世の中です。

## 1. ImageMagickをインストール

```console
$ sudo apt-get -y install imagemagick
$ which convert
/usr/bin/convert
```
## 2. 手動で連結

```console
$ ls
test_1817.png  test_1819.png test_1816.png  test_1818.png  test_1820.png

$ convert +append *.png concat.png
```

## 3. 自動で連結

```console
$ for y in {800..810} ; do
> for x in {1810..1825} ; do
> curl https://heatmap-external-b.strava.com/tiles/ride/hot/11/${x}/${y}.png?px=512 > test_${x}.png
> done
> mkdir ${y} ; convert +append *.png ${y}/${y}.png
> done
$ convert -append */*.png map.png
```

これで、Heatmapを入手できるようになりました。

次はルーティングエンジンの準備ですね
まて次号
cronologの-Sオプションはもう使えない

# はじめに
apacheのログローテートをcronologを使って設定していたのですが、-Sオプションを指定した場合にシンボリックリンクが更新されないことが分かりました。

調べた結果、特定gccバージョンだと-Sオプションは機能しなくなっているようでした。
今後どうなるか分かりませんが、cronolog自体全くメンテナンスされていないため、利用するかは検討したほうが良さそうです。

# 検証環境
OS
18.04.2 LTS (Bionic Beaver)
GCC
7
cronologバージョン
1.6.2
apacheバージョン
2.4.29

※ -Sオプションが問題なく動いた環境は以下
OS
16.04.3 LTS (Xenial Xerus)
GCC
5.4.0
cronologバージョン
1.6.2
apacheバージョン
2.4.18

# 確認したこと
apacheの設定でcronolog経由でのログ出力を設定する

```
CustomLog     "|/usr/bin/cronolog -S ${APACHE_LOG_DIR}/access.latest.log ${APACHE_LOG_DIR}/access.%Y%m%d.log" combined
```

数日後、ログの出力を確認

```
$ ls -ltr

lrwxrwxrwx 1 root root     56 Jul 12 17:07 access.latest.log -> ${APACHE_LOG_DIR}/access.20190712.log
-rw-rw-r-- 1 root root  75044 Jul 12 23:01 access.20190712.log
-rw-rw-r-- 1 root root    441 Jul 13 00:28 access.20190713.log
-rw-rw-r-- 1 root root   4190 Jul 16 20:35 access.20190716.log
-rw-rw-r-- 1 root root   8595 Jul 17 23:56 access.20190717.log
-rw-rw-r-- 1 root root  41455 Jul 18 23:56 access.20190718.log
-rw-rw-r-- 1 root root  39456 Jul 19 23:56 access.20190719.log
-rw-rw-r-- 1 root root  39456 Jul 20 23:56 access.20190720.log
```
access.latest.logのシンボリックリンクが最初に作成されたまま、更新されていない。

# 回避策
修正はされていないが有志によりパッチが作成されているため、それを適用することで回避可能（すみません私は適用確認できていません）。

https://bugs.launchpad.net/ubuntu/+source/cronolog/+bug/1012178

# 参考
https://github.com/fordmason/cronolog/issues/4
https://bugs.launchpad.net/ubuntu/+source/gcc-5/+bug/1770676
https://blog.1q77.com/2013/05/cronolog-bug/
Apache Impalaを試す。2019-09-11

# 概要
[Ubuntu18でApache Impalaをセットアップ](https://qiita.com/abetomo/items/b97b792dd3d2ecadb9f6) でImpalaが使えるようになったのでselectしたりしてみます。

参考: https://qiita.com/t-yotsu/items/747046ccb1ef363d1e3c
（参考というかこの記事の内容を自分なりに試したメモがこの記事です）

# とりあえずselect
CSVファイルをselectしてみます。

[Ubuntu18でApache Impalaをセットアップ](https://qiita.com/abetomo/items/b97b792dd3d2ecadb9f6) の通りImpalaを構築済みということで話を進めます。

Impalaから見えるところにCSVを置きます。

```:shell
% hdfs dfs -mkdir /test_data
% cat ./test.csv
a,1
b,2
c,3
d,4
e,5
% hdfs dfs -put ./test.csv /test_data
% hdfs dfs -ls /test_data
Found 1 items
-rw-r--r--   3 vagrant supergroup         20 2019-09-11 03:54 /test_data/test.csv
```

置いたら impala-shell でtableを作ってselectします。
（見やすいように結果は一部加工）

```:impala-shell
[localhost:21000] default> create external table test_tbl
(c0 string, c1 int)
row format delimited fields terminated by ','
location '/test_data';
+-------------------------+
| summary                 |
+-------------------------+
| Table has been created. |
+-------------------------+
Fetched 1 row(s) in 0.25s

[localhost:21000] default> show tables;
+------------------+
| name             |
+------------------+
| hive_warm_up_tbl |
| test_tbl         |
+------------------+
Fetched 2 row(s) in 0.01s

[localhost:21000] default> select * from test_tbl;
+----+----+
| c0 | c1 |
+----+----+
| a  | 1  |
| b  | 2  |
| c  | 3  |
| d  | 4  |
| e  | 5  |
+----+----+
Fetched 5 row(s) in 3.88s

[localhost:21000] default> select sum(c1) from test_tbl;
+---------+
| sum(c1) |
+---------+
| 15      |
+---------+
Fetched 1 row(s) in 0.18s

[localhost:21000] default> select * from test_tbl;
+----+----+
| c0 | c1 |
+----+----+
| a  | 1  |
| b  | 2  |
| c  | 3  |
| d  | 4  |
| e  | 5  |
+----+----+
Fetched 5 row(s) in 0.13s

[localhost:21000] default> drop table test_tbl;
+-------------------------+
| summary                 |
+-------------------------+
| Table has been dropped. |
+-------------------------+
Fetched 1 row(s) in 3.63s
```

impala-shellで実行してみた結果をそのままコピペしました。
少々見づらいですが、以下のcreate文でテーブルを作って

```sql
create external table test_tbl
(c0 string, c1 int)
row format delimited fields terminated by ','
location '/test_data';
```

以下のクエリを実行

```sql
select * from test_tbl;
select sum(c1) from test_tbl;
```

作ったテーブルをDropして終了

```sql
drop table test_tbl;
```

ということをしています

# そこそこでかめのデータをselect

せっかくImpalaなのでそこそこ大きめのデータに、重めのクエリを投げてみます
（1000万件くらいのデータで同じことをしようとしたら、構築した環境ではメモリが足りなくて落ちたので70万件程度のデータで示します:crying_cat_face: ）
（見やすいように結果は一部加工）

```
[localhost:21000] default> select count(*) from test_tbl;
+----------+
| count(*) |
+----------+
| 747865   |
+----------+
Fetched 1 row(s) in 4.78s
```

このデータ量で試します。重めのクエリを投げてみます。
（全く意味のないアホなクエリですみません）

```
[localhost:21000] default> select count(*) from test_tbl a join test_tbl b on a.id = b.id;
+-------------+
| count(*)    |
+-------------+
| 27681809023 |
+-------------+
Fetched 1 row(s) in 388.01s
```

6分30秒くらいで返ってきた。

**ちなみにMySQLで同じことしたら30分たっても結果が返ってこず。**（indexなど調整を何もしてない状態の結果。きちんとindexをはったら結果は変わると思います）

# まとめ
* CSVを置いてcreate tableをしたらselectできました
    * 比較的お手軽にselectできた:smile:
* ビッグデータ？も扱えました
    * メモリ8Gで起動したVirtualBox上でパラメータ調整など何も行なっていない状態での検証だったので、もう少し良い感じの環境でやれば、もう少し良い感じになりそう:question:
Win10でスクリーンショットだけが赤くなる

仕事で使っているWin10PC(Lenovo製　x280)が特定の条件でだけ画面が夜間モード気味(赤くなる)状態で困っていたというはなしの備忘録です。


![2019-09-11_152121.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317739/7817c01c-21ca-d1c9-22c4-f48f662cf009.jpeg)


##前提条件
・目に優しいということでしばらく日中でも夜間モードを使ってました
・飽きたのでやめました
・やめた後でもスクリーンショットのプレビュー画面(=スクショ画像)が赤くなる
・スリープ解除直後は普通なのに、徐々にわずかに赤くなる
・WWWWWWWHHHHHHYYYYYYYYY

##解決方法
・「System InterFace Foundation Service」をサービス画面から無効にした

![2019-09-11_155054.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317739/744123d1-1ad9-c526-e5ae-4fefb17258de.jpeg)



##解決までの流れ
1.スクショツール側の問題かどうかを切り分け
　→ツールの再インストール、類似ツールでの事象確認
　→改善せず、PC側の問題
2.PC側の問題切り分け
　→セーフモード実施
　→状況改善、何かソフトウェア側の問題っぽい
3.どのソフトウェア？
　→MS製アプリのユーザー補助、夜間モードのON/OFF再実施など
　→改善せず
4.最終的に
　→Google検索だと『含まれない』で勝手に単語が除かれてうまく検索できない
　→Bingありがとう先人の方ありがとう

#こちらが結果となります。お納めください。

![2019-09-11_150632.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317739/e13ffab4-f4be-8a2c-494b-67562bb76772.jpeg)



![2019-09-11_155517.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317739/b56b12fe-5ba9-9858-e846-cfaae173d132.jpeg)


##今後のために
1.無効化したツール「System InterFace Foundation Service」は、Lenovoの別アプリの起動のために必須とのことなので、このまま無効にするのか削除するのかを様子見する。
2.googleの検索設定を見直す
Python eval/execによる動的な変数定義と返り値

# 0. はじめに

本項は以下について述べます。

* Pythonにおける動的な変数定義
* 動的に定義した変数のreturnの取り方


念のため当方環境。

```python:
>>> python --version
Python 3.7.3
```

### [前提知識]

組み込み関数に `eval` `exec` があります。
`eval` `exec`はいずれも第一引数に文字列、第二引数にグローバル名前空間、第三引数にローカル名前空間をそれぞれとります。
文字列をわたすと、`eval`はそれを式として評価、`exec`は文として実行してくれます。

```python:
eval('type("viscera")')
# >> str

exec('x = "squirm"; print(x)')
# >> squirm
```

基本的なことは以下を参照。
- [Python の eval と exec - Qiita @kyoshidajp](https://qiita.com/kyoshidajp/items/57ae371b3f5d8a84fb13)
- [組み込み関数 — Python 3.7.4 ドキュメント](https://docs.python.org/ja/3/library/functions.html)

# 1. 動的な変数定義
本節では、任意の変数に格納されている文字列を変数名として新たに変数を定義する、動的な変数定義のやり方について述べます。

挙動についての留意点を列挙します。

まずはグローバル変数を定義する場合です。
この場合は思考停止で問題ありません。

```python:
def sample_a():
    exec('a=3', globals())
    print(a)

sample_a()
print(a)
# >> 3
# >> 3
```

値の変更も問題なくできます。

```python:
b = 1
def sample_b():
    exec('b=3', globals())
    print(b)

sample_b()
print(b)
# >> 3
# >> 3
```


が、ローカル変数を定義する場合には注意が必要です。


```python:
def sample_c():
    exec('c=3', {}, locals())
    print(c)

sample_c()
# >> NameError: name 'c' is not defined
```

第三引数にlocals()をわたしても、関数 `sample_c` 内のローカル変数を定義することはできません。従って以下のように閉じた名前空間を新たに定義する必要があります。

```python:
def sample_d():
    D = {} # インスタントな名前空間
    exec('d=3', {}, D)
    exec('print(d)', {}, D)

sample_d()
# >> 3
```

> この挙動の詳細については次記事を参照。
> [Pythonのlocals() - Qiita @amedama](https://qiita.com/amedama/items/e577324317b8939806ef)

以上を踏まえ、動的な変数定義が以下のようにして可能です。

```python:
def sample_e():
    e = "edifice"
    E = {}
    exec(e + '= "a building, especially a large one"', {}, E)
    exec('print(edifice)', {}, E)

sample_e()
# >> a building, especially a large one
```

# 2. return の取り方

動的な変数を定義する場合、コーディング時に変数名は未知です。
よってこの変数から返り値を取るには、

> 1. 新たに変数を定義する。
> 2. 定義された変数の変数名を取得し、文字列として格納する。
> 3. 2を参照し、文字列を変数名として認識させて`return`させる。

以上3工程が要求されます。


実装にあたり、`return` へ `eval` で変数名を与えればよさそうだと直感的にわかりますが、新たに定義された変数名を取得するには一工夫が要りそうです。

今回は、新たに変数が定義されると、辞書である名前空間に `key` が追加されることを利用します。次のようにして辞書の差分をとります。

```python:
from copy import deepcopy
f = "fertile"
FG = {}
checkpointBefore = deepcopy(FG)
exec(f + '= "able to produce good crops"', {}, FG)
checkpointAfter  = deepcopy(FG)
detector = list(filter(lambda x: x not in checkpointBefore.keys(), checkpointAfter.keys()))
```

例によって `exec` 文で変数を定義しますが、その前後の名前空間を `checkpoint` として `deepcopy` をとり、比較して新たに増えたkey値をリスト `detector` に格納します。
これを用いて、`return`を取ってみます。

```python:
from copy import deepcopy
def sample_fg():
    f = "fertile"
    g = "germ"
    FG = {}
    checkpointBefore = deepcopy(FG)
    exec(f + '= "able to produce good crops"', {}, FG)
    exec(g + '= "a very small living thing that can make you ill"', {}, FG)
    checkpointAfter  = deepcopy(FG)
    detector = list(filter(lambda x: x not in checkpointBefore.keys(), checkpointAfter.keys()))
    return eval(detector[0], {}, FG), eval(detector[1], {}, FG)

print(sample_fg())
# >> ('able to produce good crops', 'a very small living thing that can make you ill')
```

ここではローカルの名前空間を例にしましたが、`checkpoint` に `globals()` をわたすことでグローバルの名前空間についても同様に扱うことができます。
Windowsの壁紙スライダーをpythonで作ってみた

# 経緯

日頃貯めている画像たちをWindowsの背景にスライドで頻繁に切り替えたくなった。
当然Windowsのスライドショー機能を試したが2つの問題があった。

* 切り替えの時間を秒単位に指定できない
* モニタ2個使っていると交互に切り替わる

![背景設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/2f57afdf-0e30-a7c7-31e5-0dbfe0756e29.png)

ノートパソコンのモニタとHDMIで外部接続のモニタの2つを使っていると片方ずつ切り替わるようで、2分に1回ずつ切り替わる。
外部接続のモニタは「デジタルフォトフレーム」のようにしたかった。

探せばツールがあると思うがpythonの勉強がてら作ってみることにした。

# 使ってみたい方はこちら

https://github.com/HyunwookPark/background-slider

# 確認環境

* Windows10 Pro
* python3

# 動き

指定ディレクトリの画像をWindowsの背景として3秒おきに切り替える。
順序はファイル名の昇順。
プログラムを止めると実行前の背景に戻る。たぶん。

# 使い方

### 1. 画像が入っているディレクトリパスをtxtに記載

path.txtというファイルが入っているので好きなディレクトリに書き換える。

ex.

```
D:\あんな画像やこんな画像のディレクトリ
```

※日本語ディレクトリ名OK
※ディレクトリ名のうしろは```\```ありでもなしでもOK

### 2. メインのプログラムを実行

```
> python bg.py
```

コードはこちら。

```python
import ctypes
import os
import glob
import time
import threading
import random
import codecs
import sys

INTERVAL_SEC = 3


class BgSlider():
    def __init__(self):
        self.index = 0
        self.directory = None

    def setup(self):
        global off
        with codecs.open('path.txt', 'r', 'utf-8') as f:
            lines = f.readlines()
            self.directory = lines[0].strip()

    def worker(self):
        path = self.directory + r'\*.jpg'
        path.replace('\\\\', '\\')
        files = glob.glob(path)
        # [print(file) for file in files] # ファイルリストをコンソールにまとめて出力するときに使う
        # file = files[random.randint(0, len(files) - 1)] # ランダムにしたい場合はここを使う
        files = sorted(files) # 順番に表示したい場合はここを使う
        file = files[self.index] # 順番に表示したい場合はここを使う
        print(file)
        ctypes.windll.user32.SystemParametersInfoW(20, 0, file, 0)
        if self.index == len(files) - 1:
            self.index = 0
        else:
            self.index += 1
        time.sleep(INTERVAL_SEC)

    def schedule(self, interval, f, wait=True):
        base_time = time.time()
        next_time = 0
        while True:
            try:
                t = threading.Thread(target=f)
                t.start()
                if wait:
                    t.join()
                next_time = ((base_time - time.time()) % interval) or interval
                time.sleep(next_time)
            except KeyboardInterrupt:
                exit()


if __name__ == "__main__":
    try:
        bg = BgSlider()
        bg.setup()
        bg.schedule(INTERVAL_SEC, bg.worker, False)
    finally:
        ctypes.windll.user32.SystemParametersInfoW(20, 0, None, 0)
```

### 3. 止め方

Ctrl + C

※ボスがきたらこれ。

### 注意

このプログラムで切り替えた画像はWindowsの背景設定で画像の履歴として残る。

# 作ったときのメモ

## 参考

https://qiita.com/lobmto/items/6d3649e6c00b98553ca2
https://qiita.com/kurogelee/items/0e5fd8b6a1d1f169179a

## 地味にハマったところ

txtからパスを読み込んで使おうとしたところ、ファイルリストが取得できなかった。
原因は最後に改行コードが含まれていたため。

```python
path = self.directory + r'\*.jpg'
```

このように\*.jpgと連結時に改行込みになってしまっていた。

## 背景設定を色だけにできなかった

プログラム止めたときに背景を画像じゃなくて色だけにしたかったが
ctypes.windll.user32.SystemParametersInfoWをつかって
色だけ指定する方法がわからなかった。

## ちなみに32bit版 Windowsの場合はこれを使うらしい

ctypes.windll.user32.SystemParametersInfoA

# 機能追加予定

* スライドの順序をランダム/昇順/降順選択できるようにしたい
* Ctrl + Cじゃなくてショートカットキーとかでいつでも止められるようにしたい

# お願い

コーディングの指摘大募集です。
よろしくお願いします。
ESP-WROOM-02開発ボードでwi-fi接続からのWebサーバーにする

#初めに#
aruduino互換のesp-wroom-02開発ボードを使用するときに多少苦労したので,備忘録を兼ねてwi-fi接続してwebサーバーにしてみるまでの道のりをメモします.

画像がなくてごめんなさい.このページを作るにあたって参考にさせて頂いたページにはしっかりと画像が載っていいるので分かりにくかったらそちらも確認してください.

#参考#
・[0~3までの参考](https://qiita.com/dz_/items/27c2e19981e0bcddcf66)
・[3~4までの参考](https://qiita.com/dz_/items/27c2e19981e0bcddcf66)
・[全体的に参考](https://qiita.com/jun1_0803/items/bba03fb7e7b26596ec96)
・[こちらも参考にしました](https://deviceplus.jp/hobby/entry0033/)
・[ATコマンドについての有難いページ](https://keijirotanabe.github.io/blog/2017/02/17/esp8266-at-command-170218/)
・[ATコマンドでOKが返って来なかった人の救い](https://keijirotanabe.github.io/blog/2017/02/06/esp8266-at-reset-170207/)

#0.開発環境#
・PC(windows 10)
・arduino IDE 1.8.9
・ESPr One [(Arduino Uno同一形状　ESP-WROOM-02 開発ボード)](https://www.switch-science.com/catalog/2620/)
![0ff66443-30c2-465a-93f8-c51f0f915bf1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/4770cd0e-bbce-5ffb-1f7f-bfb72abfa04b.jpeg)



#1.Arduino IDEをインストール#
[こちら](https://www.arduino.cc/)からAruduinoのページに行き,
SOFTWARE→DOWNLOADSに行ってお使いのOS用をダウンロードしてインストールです.
![aru1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/3560498f-5eb2-7a0e-a932-11e799310a18.png)
![aru2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/6b706ed3-05ea-6bd8-7f9d-e535944c95c1.png)


#2.Arduino IDEにESP8266 のボードマネージャーを追加し設定する#
1 [esp8266のgithubのページ](https://github.com/esp8266/Arduino)に行って,
  「**Boards manager link**」を探してそこにあるURLをコピー
![aru3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/36720487-eb4c-e86a-b133-e70e2078624f.png)

2 Arduino IDE を開き　ファイル > 環境設定 を開く.
  **Additional Boards Manager URLs**にコピーしてきたURLを張り付ける.
3 ツール　> マイコンボードを選択して**Generic ESP8266 Module**を選択

#3.ATコマンドによる動作確認(ここ超重要)
**ここ超重要なので気を付けてください!!**
**ここミスるとめんどくさかったです!!(体験談　20代男子大学生)**

*※マイコンボードにプログラムを書き込む前にやってくださいマジで！*

1 Arduino IDE で　ツール　>　シリアルモニタを開く
2 モニタ上部の入力画面で`AT`と打ってEnter→`OK`と返ってきたらバッチリ
返って来なかった人→[救いのページ](https://keijirotanabe.github.io/blog/2017/02/06/esp8266-at-reset-170207/)を見て頑張ってください!!

#4.wi-fiに接続#
1 `AT+CWMODE=1`と入力してモードを設定する
2 `AT+CWLAP`と入力して接続できるアクセスポイントのリストを出す
3 `AT+CWJAP="リストから選んだSSID","パスワード"`を入力して接続
 **※2と3でコマンドが似ていますね. *L*と*J*を間違えないようにしましょうね...**
　(ここで20分くらい時間かかった...)

#5.Webサーバーにしてみる#
1 Arduino IDE でファイル>スケッチの例>ESP8266WebServer>HelloServerを選択
2 サンプルのSSIDとパスワードを接続したものに書き換える
3 プログラムをボードに書き込む

#6.Let's アクセス#
1 シリアルモニタにIPアドレスが書いてある
2 `http://シリアルモニタに書いてあるIPアドレス`にアクセスする
3 Fine!!

#終わりに#
あ~よく頑張った俺.
先人の方々ありがとうございました.
【java編】シリアライズの話

# serialVersionUIDとは
　ランタイムシリアライゼーションはすべてのシリアライズクラスにバージョン番号を付与します。
　それは`serialVersionUID`です。

　これは、シリアライズ化されたクラスをデシリアライズするとき、整合性チェックなどの認証を行います。
　もし、デシリアライズ後のクラスとクラスローダー中のクラスの`serialVersionUID`が違うようになったら、
　デシリアライズ処理は`InvalidClassException`例外が発生します。

　シリアライズ可能なクラスは、自分自身の`serialVersionUID`を定義することができます。
　ただし、 `serialVersionUID`フィールドはstatic、long、finalではなければいけない。
　例：

```java
private static final long serialVersionUID = 42L;
```

　もし、シリアライズ可能なクラスは、明示的に`serialVersionUID`フィールドを定義しなければ、ランタイムシリアライゼーションより
　そのクラスのフィールド、メソッドなど、クラスの構造に基づいて計算して`serialVersionUID`の値を自動生成します。

　それでも、すべてのシリアライズ可能なクラスは`serialVersionUID`を明示的に宣言することを強くお勧めします。
　なぜというと、`serialVersionUID`の計算方法はクラスの構造（計算時間もかかりそう）とJavaコンパイラに依存するため、
　デシリアライズ時を行うとき、想定外の`InvalidClassExceptions`例外が発生するかもしれません。

　だからこそ、違うJavaコンパイラーの環境でも、同じ`serialVersionUID`を保証するため、クラスは`serialVersionUID`を明示的に
　宣言すべきです。
　
　また、できるだけ明示的な`serialVersionUID`宣言にprivate修飾子を使用することを強くお勧めします。

>The serialization runtime associates with each serializable class a version number,
> called a serialVersionUID,
> which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. 
> If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class,
> then deserialization will result in an InvalidClassException. A serializable class can declare its own serialVersionUID explicitly by declaring a field named serialVersionUID that must be static,
> final,
> and of type long:
>ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
>If a serializable class does not explicitly declare a serialVersionUID,
> then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class,
> as described in the Java(TM) Object Serialization Specification. However,
> it is strongly recommended that all serializable classes explicitly declare serialVersionUID values,
> since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations,
> and can thus result in unexpected InvalidClassExceptions during deserialization. Therefore,
> to guarantee a consistent serialVersionUID value across different java compiler implementations,
> a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible.


※引用資料
[What is a serialVersionUID and why should I use it?](https://stackoverflow.com/questions/285793/what-is-a-serialversionuid-and-why-should-i-use-it)

※より一層理解したい方
[難解なSerializableという仕様について俺が知っていること、というか俺の理解](http://daisuke-m.hatenablog.com/entry/20100414/1271228333)
ggrksって言われたら… 〜効率よく検索する方法〜

#はじめに

プログラミングやるのに、なんだったら一番必要なスキル。
それが**検索する**（ググる）こと。

```
人に聞く => 「ググれ！」と怒られる
書籍 => まとまっていて分かりやすいけど、情報が古い
```
だったら、はじめから情報はネット検索で手に入れましょう！
ということで、検索力を上げる手法をお伝えしたいと思います。

##必要なもの

PC（タブレット、スマホでは厳しいかもしれません）
タブブラウザ（Chrome、firefoxなど）

##手順（ざっくり）

1. google検索をブラウザで開く
2. 検索したいワードを入力する
3. 検索結果を別タブで開く
4. 開いたページをざっくり見る
5. いらないページはどんどん閉じる
6. これは！というページをブックマークしていく
7. ときどきブックマークを見返して整理する

##それぞれくわしく

###1.google検索をブラウザで開く
好みのタブブラウザで[google](https://www.google.com/?hl=ja)を開きます
![google.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495631/f1c2bd32-e82a-0f95-3dca-55d0f46991ad.jpeg)


###2.検索したいワードを入力する

**ポイント**
・いろいろな検索ワードを試す
=> 例えば「Qiita」で検索するのと「Qiita 使い方」などスペース区切りで2ワード検索するのでは結果が異なってきます
=> 経験値が上がるとどういった検索ワードを入力すれば目当ての記事にたどり着くか推測できるようになります

・「ツール」を活用する
=> 検索バーの下にある「ツール」部分をクリックすると、言語やページが投稿された期間などをしぼりこむことができます。古い記事を検索結果から外すことができます
![ツールで絞り込み.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495631/e4b4a52a-2478-8d6d-1bde-9e2a416139cd.jpeg)



###3.検索結果を別タブで開く

**ポイント**
・マウスの中ボタンを押すと別タブでリンクが開くのは、意外と知らない小技
・検索結果は5ページ目くらいまで見て、そこまででよさげなサイトがなければ検索ワードを変えて再検索したほうが吉
・検索結果の見出しと内容から良さげなものを選びます。これも経験値が上がると目星をつける力がついてきます
・気になったらとにかく別タブで開きます。判断は後でやればOK!ここで時間は使わないこと！
![タブを開こう.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495631/347993c8-7fd0-d442-8749-6ef29d719d8a.jpeg)
***
![判断.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495631/27ebcc28-8115-9141-8b3f-e35fae5b7d13.jpeg)



###4.開いたページをざっくり見る

**ポイント**
・パッと見て、分かりやすそうか？2〜3スクロール分読んでみて、分かりやすそうか？図解が多いか？などで判断します
・タブの切替はcontrol+tabキー（macの場合）でできます。覚えておくと便利
![パッと見この辺まで.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495631/e8a3fdee-4d3f-b091-dc09-cbf201ada295.jpeg)



###5.いらないページはどんどん閉じる

**ポイント**
・最終的にタブが20個くらい開いてしまうので、いるいらないの選別はサクサクやりましょう
・まず、明らかにいらないものをサクっと閉じます。微妙なものは2周目に残しておきます。一通り見たら2周目。微妙なもの、まあいいんだけどブックマークするほどでもないものなどを閉じます
・command+Wキーでタブを閉じることができます

###6.これは！というページをブックマークしていく

**ポイント**
・ブックマーク（chromeの場合）はフォルダを入れ子にして管理できるので、大、中、小項目で階層化して保存していくと分かりやすいです
・command+Dキーでブックマークできます。また開いているタブ全部を一括でブックマークしたければcommand+shift+Dでできます
![ブックマークの階層化.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495631/d797dfc0-abfb-b283-1b04-0c039f000a33.jpeg)


###7.ブックマークを見返して整理する

**ポイント**
・後で見返すと、もういらない、リンク切れてる、など出てくると思います。適宜、消すなどして整理しましょう

##まとめ

検索することは学習、業務、趣味などどんなときでも必要なスキルです。
意外と見落としがちなスキルですが、上手い人と下手な人では作業効率、作業時間に圧倒的な差が出ます。
検索ワードを推測する力、検索したものを整理する力（それを再利用する力）、ショートカットを使う力など注力するポイントも多々あります。

単に「教えろください！」「ggrks!」で終わらないために、圧倒的な検索力を身につけてみてはいかがでしょうか？
VR学会2019@東大で個人的興味あり発表リスト

#VR学会2019@東大で個人的興味あり発表リスト

空中ディスプレイやペルチェ素子に興味があるようだ。
あと、VRからのフィードバックに関係するやつも。

第24回日本バーチャルリアリティ学会大会
http://conference.vrsj.org/ac2019/index.html

##興味ありメモ

|セクション|論文タイトル|気になりポイント|発表プレゼンURL|
|---|---|---|---|
|1B-08|きになるき|ペルチェ素子やLED、振動しの組み合わせで表現してるので混ぜた時の可能性|http://conference.vrsj.org/ac2019/live/live.php?n=1B8|
|1C-02|対称ミラー構造を用いたテーブルトップ空中像ディスプレイ|上と左右などでも空中に結像|http://conference.vrsj.org/ac2019/live/live.php?n=1C2|
|1C-03|周期運動する実素材を用いたリアリスティックな3次元ディスプレイの試作|扇風機の空中ディスプレイとの違い||
|1C-07|レイトレーシング法を用いた再帰透過光学系の再現のための基礎検討|VR関係内で空中ディスプレイの再現|http://conference.vrsj.org/ac2019/live/live.php?n=1C7|
|1C-08|形状変化が可能な広視野角フルパララックス立体空中像の検討|複数の視点に対応する空中結像|http://conference.vrsj.org/ac2019/live/live.php?n=1C8|
|3C-01|測定による再帰光学素子の解像性能評価|空中結像ディスプレイ使ってる||
|3C-10|2層構造の飴による食品の直接付与に安定で高反射率の食べられる再帰性反射材|食べれる反射材の着原点|http://conference.vrsj.org/ac2019/live/live.php?n=3C10|
|4A-04|異なる皮膚状態の触感再現に関する研究|人肌ゲルってなに？|http://conference.vrsj.org/ac2019/live/live.php?n=4A4|
|4A-05|非接触触覚提示による離散点刺激と連続刺激の類似度比較|音波でのフィードバック|http://conference.vrsj.org/ac2019/live/live.php?n=4A5|
|4A-08|表面粗さ感提示に向けた音波による平板振動生成|つくばでも合った|http://conference.vrsj.org/ac2019/live/live.php?n=4A8|
|4C-03|特定方向への視線の維持がVR 酔いに与える影響|VR酔の対策につながるか？！|http://conference.vrsj.org/ac2019/live/live.php?n=4C3|
|5A-01|刺激の提示面積が温冷感覚誤認現象に与える影響の分析|ペルチェ素子の最適な使い方の材料になるかも||
|5A-02|水流を用いた大面積温度ディスプレイの提示温度と面積に関する評価|水温をフィードバックにする||
|5A-03|ペルチェ素子を用いた温熱覚提示装置の開発|ペルチェ素子の最適な使い方の材料になるかも||
|6A-03|AR技術を用いたデバイス基準の拡張UIとのインタラクションにおける触覚提示部位の予備的検討|示唆による操作の実現性||

##気になり系メモ

|セクション|論文タイトル|気になりポイント|
|---|---|---|
|1A|背部にひずみ分布を提示する回転接触子アレイの基礎的検討|回転する触子デバイス|
|1A|平面ディスプレイの移動による擬似力覚の生成に関する研究|ディスプレイのほうが動くって|
|1A|筋電気刺激におけるモーターポイント推定による触覚提示の有効性|画像から触覚への変換|
|1B|首の触知覚を用いたナビゲーションシステムの提案|この部位での触覚によるフィードバック有用性|
|1B|拡張身体への応用を目指したVR環境上の裂ける手による自己受容感覚の変容|複数アームを片手で操作するときの気持ち実現|
|1B|雰囲気制御のための環境音変換手法の基礎的検討|ジャブラの集音マイク付きやつとの違い|
|1B|兎にも角にも|ステレオスピーカーで音を利用した前後の表現|
|1B|もっちゃぶる -頭部への刺激による食べ物体験-|ペルチェ素子で頭部を焼かれた際の再現|
|1B|超・呼吸体験: VReath|呼吸をインターフェースにする可能性|
|2A|餅つき体験システムにおける杵の沈み込み感提示のための計測と評価|反発の再現性|
|2A|低遅延杖型触覚提示デバイスの開発および性能評価|地面のテクスチャ振動子で再現|
|2C|蠢刺青|疑似腕で資格と触覚などで錯覚で感じるの入れ墨の錯覚の再現度|
|3A|対向噴流を用いた非接触型力覚提示装置の開発|送風によるフィードバックかな|
|3B|ほおずり電話|やばいな|
|3C|可搬全立体角没入ディスプレイ|需要ありそう？|
|4B|VR 空間中の旋回移動のための気流提示手法に関する研究|臨場感の演出、小型化しないと実用ひくい？|
|4D|THE WALKING NEKKO|腹上歩く猫の再現|
|4D|ねこ放題～もふもふを求めて～|暖かくなるらしい|

##参考サイト
- 第24回日本バーチャルリアリティ学会大会<br>http://conference.vrsj.org/ac2019/index.html
【メモ】Goで `blog-YYYYMMDD.md` のような感じで time.Time を Format する

## 背景

今更ながら、[time - The Go Programming Language](https://golang.org/pkg/time/#pkg-constants)を読んでいたら、`Time.Format` を以下のようなオーソドックスな使い方以外にも便利に使えることを発見したのでメモ。

```go
package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.Date(2019, 9, 5, 0, 0, 0, 0, time.Local)
	fmt.Println(t.Format("2006/01/02"))
	fmt.Println(t.Format(time.RFC1123))
}
```

## Time.Format で指定するレイアウトについて

> These are predefined layouts for use in Time.Format and time.Parse. The reference time used in the layouts is the specific time:
>
>  Mon Jan 2 15:04:05 MST 2006

【意訳】
Time.Format と time.Parse で使用するための事前に定義されたレイアウトが存在する。レイアウトで使用される参照時間は、具体的な時間。

Mon Jan 2 15:04:05 MST 2006

> To define your own format, write down what the reference time would look like formatted your way

【意訳】自身でフォーマットを定義するには、参照時間がどのようにフォーマットされるかを書く。

引用元: [time - The Go Programming Language](https://golang.org/pkg/time/#pkg-constants)


より具体的な使用方法は、[time - The Go Programming Language](https://golang.org/pkg/time/#pkg-constants)を参照されたいが、仕様に沿っていれば、結構柔軟にフォーマットを定義することができる。

## 実際にやってみた

### 実装例

```go
package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.Date(2019, 9, 5, 0, 0, 0, 0, time.Local)
	fmt.Println(t.Format("blog-20060102.md"))
}
```

### 実行結果

```
blog-20190905.md
```

### ダメな実装例
以下のようにすると、レイアウトが不正( `20050102` )なので、うまくフォーマットできない

```go
package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.Date(2019, 9, 5, 0, 0, 0, 0, time.Local)
	fmt.Println(t.Format("blog-20050102.md"))
}
```

### 実行結果

```
blog-50000905.md
```

## 参考
[time - The Go Programming Language](https://golang.org/pkg/time/#pkg-constants)
JavaにウォーターマークをPDFドキュメントに追加します

ウォーターマークは常に各種文書に使われる声明で、偽造防止の手段であり、文字の透かしを設定
したり、写真を読み込んだりすることができます。以下の内容はJavaを通じてPDFドキュメントに
透かし効果を追加する方法、すなわちテキスト透かしと画像透かしを共有します。

テキストウォーターマークを追加：

```java
import com.spire.pdf.*;
import com.spire.pdf.graphics.*;
import java.awt.*;
import java.awt.geom.*;

public class Textwatermark {
    public static void main(String[] args) {
        
        PdfDocument pdf = new PdfDocument();
        pdf.loadFromFile("Sample.pdf");
        PdfPageBase page = pdf.getPages().get(0);

        //use insertWatermark()to insert the watermark 
        insertWatermark(page, "E-ICEBLUE");
        pdf.saveToFile("out/textWaterMark.pdf");
    }
    static void insertWatermark(PdfPageBase page, String watermark) {
        Dimension2D dimension2D = new Dimension();
        dimension2D.setSize(page.getCanvas().getClientSize().getWidth() / 2, page.getCanvas().getClientSize().getHeight() / 3);
        PdfTilingBrush brush = new PdfTilingBrush(dimension2D);
        brush.getGraphics().setTransparency(0.3F);
        brush.getGraphics().save();
        brush.getGraphics().translateTransform((float) brush.getSize().getWidth() / 2, (float) brush.getSize().getHeight() / 2);
        brush.getGraphics().rotateTransform(-45);
        brush.getGraphics().drawString(watermark, new PdfFont(PdfFontFamily.Helvetica, 24), PdfBrushes.getViolet(), 0, 0, new PdfStringFormat(PdfTextAlignment.Center));
        brush.getGraphics().restore();
        brush.getGraphics().setTransparency(1);
        Rectangle2D loRect = new Rectangle2D.Float();
        loRect.setFrame(new Point2D.Float(0, 0), page.getCanvas().getClientSize());
        page.getCanvas().drawRectangle(brush, loRect);
    }
}
```
![JAVA-insert-text-watermark-to-PDF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/3b4b0d80-d6e1-10d1-f78e-4950808142f4.png)


画像のウォーターマークを追加：

```java
import com.spire.pdf.*;
import java.awt.geom.Rectangle2D;

public class watermark {

    public static void main(String[] args) {

        PdfDocument doc = new PdfDocument();
        doc.loadFromFile("Sample.pdf");
        PdfPageBase page = doc.getPages().get(0);  

        page.setBackgroundImage("logo.png");

        Rectangle2D.Float rect = new Rectangle2D.Float();
        rect.setRect(280, 300, 150, 150);
        page.setBackgroundRegion(rect);

        doc.saveToFile("output/imageWaterMark.pdf");
        doc.close();

    }
}
```
![JAVA-add-image-watermark-to-PDF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/dcb3553c-490e-9943-fc7c-bff8aac5e9b3.png)
digdagでscheduleを変更した際は日付を扱う処理で注意が必要

scheduleをdailyからcronに変更した際に動作が変わった点があったので紹介します
digdagのバージョンはv0.9.39です
※スケジュール実行された場合の挙動であり、UIから自分でRUNした場合などは以下のような動きにはなりません

```yaml:daily.dig
timezone: 'Asia/Tokyo'

schedule:
  daily>: 14:00:00

+task:
  sh>: echo ${moment(session_time).add(-1, 'hour').format("YYYYMMDD")}
```

```yaml:cron.dig
timezone: 'Asia/Tokyo'

schedule:
  cron>: "0 14 * * *"

+task:
  sh>: echo ${moment(session_time).add(-1, 'hour').format("YYYYMMDD")}
```

どちらも毎日14時にsession_timeから1時間前の日付をYYYYMMDD形式で出力するワークフローですが、上記2つは異なる日付を出力します

「2019-09-11 14:00:00」実行分を例にすると


#### (1)dailyで実行の場合

session_timeは「2019-09-11T00:00:00+09:00」となります

そのため「20190910」が出力されます


#### (2)cronで実行の場合

session_timeは「2019-09-11T14:00:00+09:00」となります

そのため「20190911」が出力されます
[Django]カスタムコマンドでバッチ処理をする

Djangoでアプリケーション作っていて定期的に行いたい処理があった。
例えば決められた時間にデータを更新するとか

いくつかの方法を考えたけどカスタムコマンド使うのが簡単そうだったのでそのやり方を


大まかな流れとしては

1. カスタムコマンドを作成
2. 外からcronとか使ってそのコマンドを叩く

って感じです
### カスタムコマンドを作る
Djangoやってるとおなじみの

```
python manage.py runserver
```
ってコマンドあるじゃないですか。今回はrunserverみたいなコマンドをオリジナルで作成します。
そのコマンドに自分の行いたい処理を記述しておくことでcronとか使って外部からそのコマンドを叩くだけでDjangoに処理を行わせることができます。


カスタムコマンドを作成するために必要なディレクトリを準備します

```
プロジェクト
    アプリケーション
        management
            commands
```
見にくいですが上記の階層になるように新たにmanagementとcommandsを用意してください
/プロジェクト/アプリケーション/management/commands
って感じです。

この時にアプリケーションは新規で作成しても既存の物を使っても問題なく動きます。新規で作成した時はsetting.pyでアプリケーションを追加しておくことを忘れないように。アプリケーションを追加しないとコマンドを認識してくれません

次にcommands内にpythonのファイルを作成します。この時の名前がコマンド名になります。

```
プロジェクト
    アプリケーション
        management
            commands
                test_command.py
```

pythonファイルは以下のような感じ

```python
from django.core.management.base import BaseCommand

class Command(BaseCommand):
    def handle(self, *args, **options):
        print('test command')
```

あとは

```shell
python manage.py test_command #test_command.pyじゃないことに注意
```
ってすれば

```
test command
```
って感じです
あとはcronとかで外部から叩いてあげればバッチ処理ができますね
Android10で戻るジェスチャーを一部無効にする

#はじめに
Android10がリリースされてバックキーが無くなり、エッジをスワイプすることでバックキーと同じ動作が可能になりました。
本稿ではエッジをスワイプし自前のUIを動かしたい時にバックの挙動を無効にする方法を紹介します。

#実装
```Kotlin:sampleFragment.kt
//バックの挙動を無効にしたいView
val view: View = findViewById(R.id.view)
//対象のViewのバックを無効にしたい範囲
val rect = Rect(0, 0, 100, 100)
//バック動作無効の設定
view.systemGestureExclusionRects = listOf(rect)
```
Android10から追加されたsetSystemGestureExclusionRects()メソッドをViewに対して設定します。
Viewの中で無効にしたい範囲(例だとViewの左上から縦横100px)を定義して引数とします。
この時Rectはlistで渡すので複数の範囲を指定することができます。

以上、この実装により指定したViewの範囲ではスワイプバックの挙動が無効になり自前で実装したジェスチャーが動きます。

#参考
[Android Developers](https://developer.android.com/preview/features/gesturalnav?hl=ja)
GAP.jl のDockerでの導入


# 本日は

最近はMacで作業・お仕事をしています．数学の話をJulia上で展開したいなーというお気持ちがあるので

OSCARシリーズのSingular.jlとかGAP.jlとか入れてみたいよねという気持ちが出てきました．
今回は GAP.jl の導入メモです．Singular.jlさんDockerでも入らないので絶望しています．

# Dockerfileを作る

ここではDockerが既に導入されていると仮定します．[ここなどをみてDockerを入れてください](https://docs.docker.com/docker-for-mac/)

```
FROM julia:1.1.1

RUN apt-get update && apt-get install -y \
    autoconf \
    autogen \
    build-essential \
    cmake \
    cmake-data \
    gfortran \
    libblas-dev \
    liblapack-dev \
    libgmp-dev \
    libmpfr-dev \
    git

RUN julia -e 'using Pkg; Pkg.add("GAP"); using GAP'
```

上記のDockerfileができたとします．依存パッケージはGAP.jlのtravisの設定ファイルなどから拝借しています．

## イメージを作る

```
$ ls
Dockerfile
$ docker build -t jlgap .
# しばらく待つとイメージが生成
```

## 動かし方

```
$ docker run --rm -it jlgap julia
```

下記のようになればOKです．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/7969ebda-2b2a-ce65-e233-fc5d6bab36dc.png)
HTMLから送信した画像データをバイナリにしてDBに収める

数年前、画像＋コメントのSNSライクなコンテンツを作って、画像処理で苦労したコードです。
コンテンツは、今も現役で動いています。

「縦なのに、データは横になっている写真を正しくグリンしたり」は、スマホなどで投稿する場合に、我ながら親切で、当時は感動しました。
特に、[山中などから実況投稿](https://www.chuo-system.co.jp/csclib/index.php/2019/03/04/orienteering/)する場合に有難いのです。

##画像処理コード

```HTML
<input type="file">
```

をPHPで受けて
- 縦なのに、データは横になっている写真を正しくグリンしたり
- サイズを変更したりして
- バッファリングして
- バイナリをゲットして
- DBに収められるようにする
というコードです。

```PHP
//フォームから送信された画像データが存在する場合のみ実行
if ($_FILES['localImage']['tmp_name'] != "") {

    //JPEGの場合
    if ($baseInfo['mime'] == "image/jpeg") {
        //画像を読み込む
        $imageInport = imagecreatefromjpeg($_FILES['localImage']['tmp_name']);
    }

    //PNGの場合
    if ($baseInfo['mime'] == "image/png") {
        //画像を読み込む
        $imageInport = imagecreatefrompng($_FILES['localImage']['tmp_name']);
    }

    //GIFの場合
    if ($baseInfo['mime'] == "image/gif") {
        //画像を読み込む
        $imageInport = imagecreatefromgif($_FILES['localImage']['tmp_name']);
    }

    //画像の向き
    $exifData = exif_read_data($_FILES['localImage']['tmp_name']);

    //90度画像の場合
    if ($exifData['Orientation'] == 6) {
        //画像回転
        $imageInport = imagerotate($imageInport, 270, 0);
    }

    //180度画像の場合
    if ($exifData['Orientation'] == 3) {
        //画像回転
        $imageInport = imagerotate($imageInport, 180, 0);
    }

    //270度画像の場合
    if ($exifData['Orientation'] == 8) {
        //画像回転
        $imageInport = imagerotate($imageInport, 90, 0);
    }

    //横サイズ
    $inWidth = imagesx($imageInport);

    //縦サイズ
    $inHeight = imagesy($imageInport);

    //サイズ変更後の縦サイズ（次第で、生成する画像サイズが決まる）
    $outHeight = 600;

    //サイズ変更後の横サイズ）
    $outWidth = $inWidth * ($outHeight / $inHeight);

    //サイズ変更後の画像データを生成
    $imageOutput = imagecreatetruecolor($outWidth, $outHeight);

    //imagecopyresampled(器, 画像データ, コピー先X座標, コピー先Y座標, コピー元X座標, コピー元Y座標, コピー先幅, コピー先高さ, コピー元幅, コピー元高さ)
    imagecopyresampled($imageOutput, $imageInport, 0, 0, 0, 0, $outWidth, $outHeight, $inWidth, $inHeight);

    //バッファリング
    ob_start();

    //JPEGとして出力
    imagejpeg($imageOutput);

    //要素を取得
    $imageOutput = ob_get_contents();

    //バッファリング終了
    ob_end_clean();

    //SQL用にエスケープ
    $insertImage = @mysqli_real_escape_string($con, $imageOutput);
}
```

##ファイルサイズチェックは

```PHP
//～2MBの例
if (filesize($_FILES['localImage']['tmp_name']) >1048576 * 2) {
    //処理しない
}
```

##確か透過を保持するのは（自信無し）
//サイズ変更後の画像データを生成
の後に

```PHP
//ブレンドモードを無効にする
imagealphablending($imageOutput, false);

//完全なアルファチャネル情報を保存するフラグをonにする
imagesavealpha($imageOutput, true);
```

出力はimagepng()かimagegif()か…覚えていません。
個人で良く使っているシェルスクリプトのテンプレートの備忘

# Set
※ -E 関数の中でもエラーを拾う。 -u 何も代入されていない変数を使おうとした場合エラーになる。

```
set -Eu
```

#trap
※set -Eか-eが必要

```
# スクリプト実行時にエラーが発生したときの動作。
trap 'trap ERR; echo -e "\nAn error occurred."; exit 1' ERR

# ここだけset -E解除
set +E
...
# set -E復帰
set -E
```


# VAR
※引数に何も入っていない場合エラー。

```
VAR=${1?"Invalid argument: VAR"}
```



# logging
```
LOG_FILE="/tmp/$(basename $0 | sed 's/\.[^\.]*$//').log"
exec > >(tee -a ${LOG_FILE}) 2>&1
```

# シェルスクリプトを実行しているディレクトリのフルパス取得
```
#シェルスクリプトを実行しているディレクトリのフルパス取得
SHELL_DIR=$(dirname $(readlink -f $0))
```

#正規表現チェック
```
if [[ $VAR1 == *"文字1"* && $VAR2 == *"文字2"* ]]; then
    #何もしない
    :
else
    xxx
fi
```


#ヒアドキュメントの変数代入

```
HOGEFUGA=$(
    cat << EOS
hoge
fuga
EOS
)
```

#変数名と変数の変数値を表示
```
echo "${TARGET} : $(eval echo \"\$${TARGET}\")"
```
RailsでAuditedとPaperTrailのどちらを導入すべきか

- 実際に選定してみた際に悩んだので、記事化
 
## この記事の内容
- Railsのgemの`Audited`と`PaperTrail`とは
- `Audited`と`PaperTrail`の違い
- おすすめのユースケース

## `Audited`と`PaperTrail`とは
- データの変更履歴やバージョンを管理するためのパッケージ
- 誰がどのレコードをどのように変更したかの履歴を自動的に保存してくれる
- 必要になるユースケースとしては、以下のような場合がある
    - プロフィールなど、変更記録を含めた検索をしたい
    - qitaの記事など、一回の編集量が多いデータの履歴を管理したい
    - 誰が変更したかが重要なデータ
        - 特にお金が関わる時！
- ↓がソース！
    - [Audited](https://github.com/collectiveidea/audited)
    - [PaperTrail](https://github.com/paper-trail-gem/paper_trail)

## `Audited`と`PaperTrail`の比較
### `Audited`のメリット
- 誰が変更したかをテーブル単位でデータが取れる
    - ログインできるモデルが複数ある場合に有効
        - UserテーブルとAdminテーブルで切り分けているなど
    - 誰が変更したかはリレーションだけではなく、文字列でも残せる
- 変更のBeforeとAfterが1レコードになる
    - 変更内容の監視が可能
    - DBから変更記録を追う際に、便利
- 変更時にコメントを残せる
- 変更リクエストのIPアドレスを自動で取得する

### `PaperTrail`のメリット
- バージョン管理がしやすい
    - 〇〇日に変更した内容などの記録が楽
    - モデルごとにバージョン管理用のテーブルが作れる
    - パッケージに、全変更履歴を取るためのメソッドが用意されている
    - 最新3バージョンまで保持するなどの管理がしやすい
- DBに入る実際の値をカスタマイズしやすい
    - get startedにカスタマイズ方法が記載されている

### 結論
- `PaperTrail`はバージョン管理に特化している
    - diffを見る
    - 〇〇日のバージョンを戻す、など
- `Audited`は監査用のログを管理する用途に特化している
    - 誰が〇〇日にどのデータをどのように変更したか、など

## オススメのユースケース 
- `PaperTrail`にオススメ
    - 履歴を含めた検索をしたい場合
    - ユーザーがデータのバージョンを確認したい場合
- `Audited`にオススメ
    - 変更履歴を管理したい場合
Git Fetchが役に立った

## Git Fetchが役に立った

- 状況
 - ローカルでマスターからブランチを派生させて作業をしていた時に、リモートのマスターに変更が加わった


- やったこと
 - git merge origin master

→だめだった・・・・・

- もう一度やったこと
 - git fetch (リモートの状況をローカルのブランチに持ってきた感じ？※この時点ではまだ反映されない)
 - git merge origin master (持ってきた最新ソースをローカルのソースコードに反映成功)


備忘録
Railsでグラフ描画に使えるgem

##はじめに
Rubyを使ったWebアプリにグラフを入れたいと考えたため、今回の記事に描画のやり方を投稿します。この記事が少しでも皆さんのお役に立てれば幸いです。
今回記事の作成にあたり、<a rel="stylesheet" href="https://chartkick.com/">Chartkick公式HP</a>を参考にしました。
<br>
##描画方法
まず、ターミナルで次の二つのgemをインストールします

```
gem install chartkick
gem install chartable
```

そして、Gemfileに次の2つを追記して、bundle installします。

```
gem 'chartkick'
gem 'chartable'
```

次にapp/assets/javascripts/application.jsへ移動し、以下の2つを追記します。

```
//= require Chart.bundle
//= require chartkick
```

これで準備は整いました。
最後に、コントローラのindexアクション(アクション名は任意)に

```
def index
    @sample = {'2019-06-01' => 60, '2019-06-02' => 65, '2019-06-03' => 64}
  end
```

と記述し、viewに

```
<%= pie_chart @sample %>
```

と記述すると、
[結果](https://gyazo.com/9d25abd9950d1e4c4db2b59c03de99cd)

##終わりに
これで、今回の投稿を終わります。何かご意見等がございましたらご連絡ください。
PythonでリモートリポジトリにCommit&Pushする最も簡単な方法

Pythonの良さは色々なところで耳にしますが、Gitの操作も非常に容易に出来ます。

下記は、Pythonを使ったGit操作の例です。

```python:git.py
import os
import git

#Pushしたいリポジトリに移動
os.chdir(r'C:\repo')
repo = git.Repo()

#最新を取り込むため一旦Pull
o = repo.remotes.origin
o.pull()

#Commit(サブディレクトリ含めて全て)
repo.git.commit('.','-m','\"Commit Log\"')

#Push
origin = repo.remote(name='origin')
origin.push()
```

サンプルの注意事項：
・既にGitの設定がローカルPCで出来ていて、Cloneされているものとします。
・プラグインをインストール済みの環境です。インストールしていない方は、`pip install gitpython`を実行しましょう。
画面遷移の際に位置をtopに戻す方法【React】

# 概要

画面遷移（URL移動）の際に画面の位置をトップに戻したい
ちょっとしたコード書くだけで解決できた
（ちなみにReactで作成したcomponentです）

# 実装

```react

  this.setState(() => window.scrollTo(0, 0));
```
Componentのよしななタイミングでこれをセットしてあげると画面位置がトップになります。

# 例

簡易な例でいうと、

```react

  componentDidMount() {
    this.setState(() => window.scrollTo(0, 0));
  }
```
これで画面遷移してきたページで前のページのlocationに影響されずに画面の位置がトップになります。

# 出典元
https://stackoverflow.com/questions/57534882/how-to-reset-scroll-position-on-single-page-pagination
batコマンドでPythonスクリプトの戻り値を取る際の注意点

Pythonスクリプトをbat経由で実行する際に、戻り値を取りたい場合があります。
その際に、%ERRORLEVEL%を使うというのは有名な話ですが、少々ハマったので、その部分を記載しておきます。

まず、基本形です。

```python:sample.py
import sys

sys.exit(1)

```

```bat:print.bat
@echo off

python sample.py
echo %ERRORLEVEL%

REM 実行結果
REM 1
```


sample.pyの実行結果が`%ERRORLEVEL%`に格納されるので、それを表示するだけの簡単なものです。
しかし、同じpyファイルを使った次のbatコードは上手く動きません。

```bat:print.bat
@echo off

python sample.py
cd /d d:\software
echo %ERRORLEVEL%

REM 実行結果
REM 0
```

気付いてしまえばそれまでなのですが、`ERRORLEVEL`は直前に実行されたコマンドの戻り値が入ります。
従って、間に他のコマンドが入ってしまうと、期待した結果が得られないことになります。
これを回避するためには、一旦他の変数に格納して参照するようにすれば良いです。

```bat:print.bat
@echo off

python sample.py
SET RESULT=%ERRORLEVEL%
cd /d d:\software
echo %RESULT%

REM 実行結果
REM 1
```
Oculus 端末の温度を知る

１．ADB（Android Device Monitor）を起動する。

２．Logcatのタブに遷移

３．Filterの追加画面で下図のように**thermal**と入力する。（Filter Nameは何でも良い）
![2019-09-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17904/a240b1e2-60f3-fe00-587c-7692ffb0e16e.png)

４．自分のアプリを起動 Or スリープさせる Or 一定周期？？

下記のようなログが通知される。

I/EventRecorder(1241): Event flushed: oculus_os_thermal
oculus_os_thermal {"build":"XXXXX","flavor":"XXXX","realtime_ms":159374047,"uptime_ms":159374047,"fan_speed_min":0,"fan_speed_max":0,"fan_speed_total":0,"fan_speed_total_square":0,"front_plate_temperature_min":31,"front_plate_temperature_max":32,"front_plate_temperature_total":412,"front_plate_temperature_total_square":13060,"cpu_temperature_min":41,"cpu_temperature_max":48,"cpu_temperature_total":637,"cpu_temperature_total_square":31475,"gpu_temperature_min":38,"gpu_temperature_max":44,"gpu_temperature_total":550,"gpu_temperature_total_square":23336,"battery_temperature_min":315,"battery_temperature_max":315,"battery_temperature_total":4120,"battery_temperature_total_square":1305770,"nb_samples":13,"shutdown":"false"}


◆参考URL
https://developer.oculus.com/documentation/mobilesdk/latest/concepts/mobile-power-overview/
Jenkins pipelineでSlave PCにあるファイルを読みこむ方法

Jenkins pipelineを使っていると、SlaveとMasterの概念がごちゃごちゃになって、ついついMaster PCの中を見に行ってしまうようなコードを書いてハマったりします。
そういった点を解消しながら、Slave PCのテキストファイルを読み込む方法をご紹介したいと思います。

まず、前提として`bat`コマンドを実行すると、Slave PC側で実行されるという基本を覚えておいてください。
一方、Pipeline scriptでGroovyによるコマンドでファイルを見に行こうとすると、Master PCの中身を見に行きますので、ご注意ください。

そのため、実現方法としては、
1. batコマンドでファイルを読みこむ
2. echoによる出力を戻り値で変数に返す

となります。

結果は以下です。

```groovy:jenkinsfile


TEXT_PATH = WORKSPACE+'/text_directory'
TEXT_CONTENTS = bat returnStdout: true, script: '''@echo off 
for /f " usebackq tokens=*" %%a in ('''+TEXT_PATH+'''/contents.txt) do (
echo %%a
goto :exit_for
)
:exit_for'''

print( TEXT_CONTENTS )

```

これはテキストファイルの最初の1行だけ読みこむ方法ですが、応用すれば複数行もいけます。

注意点としては、batファイル内でechoを使って文字列を出力してしまうと、それも戻り値に含まれてしまいますので、考慮するようにして下さい。
Reactでブラウザバック時に処理を実行しないようにする(React Hooks)

React(React Hooks)+Redux環境で、初回描画時には検索を実行したいけど
ブラウザバック時には走らせたくないときに書いたコードです。

(もっといい方法があれば教えていただければ嬉しい…)

```react
const isBrowzerBack = React.useRef(false);

// ブラウザ履歴を移動したときのみフラグをセット
window.onpopstate = () => {
    isBrowzerBack.current = true;
}

React.useEffect(() => {
    if(isBrowzerBack.current) {
        isBrowzerBack.current = false;
    } else {
        searchUser();
    }
}, []);

```
Macですが、世にも不思議な怪現象に遭遇報告。2019/09/11

shellスクリプトが、存在するスクリプトファイルを認識してくれません。
だども、
ls 取ると、ちゃんと返してくれます。

![Macの世にも不思議な怪現象 2019-09-11 14.01.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5135/18bfb1ca-b9f7-7973-d633-3889fa422f1e.png)

おそらく、なんか、既知のバグなんでしょう？いまからググって見ます。

<< 自己解決 >>

そうでした！「<」で解決。
たまに使うと忘れますねー。
:sunglasses:
APIって一体何？？

#APIってなに？

これは**「Application Programming Interface」**の頭文字です。
簡潔に言うとAPIとはソフトウェアの機能を共有することです。。。

もう少しわかりやすく言うとAPIは自己のソフトウェアを一部を外部に向けて公開して、他のソフトウェアと機能を共有できるようにしたものです。

#APIの利点

APIのイメージがついたところで、APIの利点について説明してみたいと思います。API機能には大きく3つの利点があります。

その3つとは、

 - **ソフトウェア開発の効率化**
 - **セキュリティの向上**
 - **最新情報を簡単に取得可能**
です。

######ソフトウェア開発の効率化によるコスト削減
APIで組み込むことができる信頼できるプログラムが世の中にすでに存在する場合、そのプログラムと連携することで、自分で1からプログラムを組む必要がなくなり、ソフトウェア開発の効率化がはかれます。プログラム開発側にとって、開発時間を短縮することができるのは大きなメリットです。

時間短縮ができれば他の工程に時間を割くことができ、結果的にコスト削減が可能となります。

######セキュリティの向上
大手SNSページやアプリ会員登録時、または買い物をする場合など、Googleアカウントやフェイスブックアカウント、またはTwitterアカウントを連携することで登録ができた、という経験はありませんか？

あれは各種サービスとAPI連携が行われているため、別アプリケーションログインによる、ログイン認証ができるようになっています。わかりやすい例を挙げるなら、フェイスブックとインスタグラムです。フェイスブックのアカウントを持っている人であれば誰でもインスタグラムのアカウントをすぐに作成可能です。

自社でセキュリティレベルの高い会員登録システムを入れるよりも、すでにあるセキュリティレベルの高い会員システムを導入する方がユーザーも安心ですよね。ユーザー新たにユーザー登録をしなくても良い、という大きなメリットがあり、より多くの人に使ってもらえる、というメリットが提供側にもあります。ちなみに、提供側は、APIの連携前に必ずユーザーの承諾を得る必要があります。ユーザー側も連携サービスを使うにはユーザー情報が共有されることを許可する必要があります。（どの情報が共有されるか、などはサービスにより異なります。）

######最新情報を簡単に取得可能
APIを使えば、それぞれのサービスの最新情報をこちら側が毎回更新しなくても取得、利用することができます。

例えば、自分のサイトでアマゾンの商品を売っている場合、アマゾンでの販売価格が変わった場合でも、API連携で情報を取得してきている場合、その変更は自動で反映されます。

Twitterやインスタグラムへの投稿をFacebookにも自動で投稿するように設定する、などが可能となっているのもAPIのおかげです。