OmniAICreator/Qiita-1.07M huggingface dataset:
BIOSをいじらずにUSBからUbuntuを起動する

最初から最後まで書いてある最新の記事が見つからなかったので。

## したこと
Windows10でブータブルUSBを作って、BIOSをいじらずにUbuntuを起動しました。

## 環境
・Win10
・ワイヤレスキーボード（logicool k270)

## つまったところ
・そもそも他のOSってどうやって起動するの？
・BIOSの設定画面がどのキー押しても出んぞ

## 流れ：
1. ブータブルUSBを作る。
2. Windowsの設定からUbuntuを起動する。

# 1. ブータブルUSBを作る。
UNetbootinを使いました。あらかじめUbuntuをダウンロードしておきましょう。フォーマットもしときましょう。
これは詰まることはないと思います。（調べればいくらでも出てくる）
他に候補としてはVMware使って仮想環境で、とか光学ドライブで、とかの候補があると思います。

# 2. Windowsの設定からUbuntuを起動する。
はい、一番書きたかったこと。
Ubuntu起動するために色んなサイトを見たわけですが、どこも「まずはBIOSの設定画面を起動してください」みたいな感じだった。僕は初心者 of 初心者なのでそもそもBIOS自体知らなかったのですが、どのキーを狂ったように押しても起動することはなかった。困った。

詳しい友人に聞いたところこんなサイトを見つけてくれた。
[Windows 10でUEFI (BIOS) 画面を起動する手順（ぼくんちのTV別館）](https://freesoft.tvbok.com/win10/access_uefi_bios_setup.html)
内容をざっくりいうと、最近のパソコンは起動が速すぎてF2キー連打とかだと起動できないよ、という話。
目からウロコ。

さてしかし。大体このサイトに書いてあることで正解だったのだが、このサイトはWindows8系のお話で少し10とは違った。（しかも結局BIOSはだめだった）なので10に直して手順と画像を載せる。

まずはWindowsの設定を開こう。そしたら更新とセキュリティをクリック。
![2018-10-25.png](https://qiita-image-store.s3.amazonaws.com/0/305208/fed84163-5ea4-0726-2df9-f39a3ad6fdc4.png)

次は回復のとこへ。不安に駆られるが今すぐ再起動をクリック。（再起動までにはUSBをさしておこう）
![2018-10-25 (1).png](https://qiita-image-store.s3.amazonaws.com/0/305208/ce754fdc-d43e-0971-1102-a684f75d371d.png)

謎の青い画面になったはずだ。（写真なくてすみません）
そしたらあとは「デバイスの使用」==>さしてあるUSB選択すればUbuntuが起動する。

きっとUbuntu以外でも大丈夫。

以上。
Integerに統合された整数をFixnumなのかBignumなのか判別する

Ruby2.4以降、整数型が統合されましたが内部のデータ構造として
どちらを使っているのかが気になることがあります。
# 判別方法
```rb
class Integer
  def is_fixnum?
    __id__ == self * 2 + 1
  end
end

def is_fix(num)
  kls = num.is_fixnum? ? "Fixnum" : "Bignum"
  puts "#{num} is #{kls}"
end

is_fix(2**30-1)
is_fix(2**30)
is_fix(2**62-1)
is_fix(2**62)
```

# 何やってるの？
object_idを比べています。
Fixnumのobject_idは固定(かつ内部データの都合で数値*2+1)になります。

# 実はwindows-x64の場合Fixnumは64bit対応していない
windowsの場合の結果は

```result
1073741823 is Fixnum
1073741824 is Bignum
4611686018427387903 is Bignum
4611686018427387904 is Bignum
```

Linuxの場合は

```result
1073741823 is Fixnum
1073741824 is Fixnum
4611686018427387903 is Fixnum
4611686018427387904 is Bignum
```

となり、windowsの場合x64ビルドだろうがFixnumは30bit程度になります。
二項定理をpythonで計算する

# 二項定理の定義

二項定理とは,  
>初等代数学における二項定理（にこうていり、英: binomial theorem）または二項展開 (binomial expansion) は二項式の冪の代数的な展開を記述するものである。定理によれば、冪 (x + y)n は a xb yc の形の項の和に展開できる。ただし、冪指数 b, c は b + c = n を満たす非負整数で、各項の係数 a は n と b に依存して決まる特定の正整数である。

[Wikipedia](https://ja.wikipedia.org/wiki/%E4%BA%8C%E9%A0%85%E5%AE%9A%E7%90%86)より

あっ…

# Pythonに計算させよう

``` python:BinomialTheorem.py

from math import *

def calc(k):
    return [ factorial(k)/(factorial(i)*factorial(k-i)) for i in range(k+1)]
    
```

これを使うと,

```
>>> calc(0)
[1]

>>> calc(6)
[1, 6, 15, 20, 15, 6, 1]

>>> calc(12)
[1, 12, 66, 220, 495, 792, 924, 792, 495, 220, 66, 12, 1]

```

こんな感じでlist型で返してくれる.

2018/10/25訂正
関数calc内で結果をreturnしてませんでした.
@shiracamus さん,ご指摘いただきありがとうございます.
tcshメモ書き

bashと微妙に違うtcshの文法について、メモ書きとして残しておきます。
(CシェルはC言語とよく似た文法ではあるが中途半端で分かりにくい...)

#シェバン行
文頭に記述する行であり、コメントではない。
`#!`の後ろに書かれたシェルを用いてシェルスクリプトは実行される。

```bash:test.sh
#! /bin/tcsh -f
```

#変数宣言いろいろ
cシェルではset,setenv,aliasで宣言方法に差異があるので要注意。
##setを使う
```bash
set var = a # OK bashと違ってスペースがないとエラーが出ます。
set var=a   # ダメ
set var =a  # ダメ
set var= a  # ダメ
#配列を宣言(配列番号は1origin)
set arr = ( 10 20 30 40 50 )  
#参照例
$ echo $arr[3] 
30     #output
```
##setenv を使う(環境変数)
```shell
setenv var a   #変数名と変数の間に'='は不要
```
##aliasを使う(コマンドに別名を与える)
```bash
#ここではエイリアス'ls'にコマンド'ls -l'が代入される
alias ls ls -l  #エイリアスとコマンドの間に'='は不要
```

#制御構文
ここでは繰り返し処理と条件分岐、またそのとき条件の指定に用いる演算子についてまとめる。
##条件式いろいろ
###整数に関する条件式

|条件式|意味|
|:---|:---|
|int1 == int2|int1とint2が等しい|
|int1 != int2|int1とint2が等しくない|
|int1 <  int2|int1はint2より小さい|
|int1 <= int2|int1はint2以下|
|int1 >  int2|int1はint2より大きい|
|int1 >= int2|int1はint2以上|

###ファイルに関する評価演算子
|条件式|意味|
|:--:|:--|
|-e file|fileが存在する|
|! -e file|fileが存在しない|
|-d file|fileが存在しディレクトリ|
|-h file|fileが存在しシンボリックリンク|
|-f file|fileが存在し通常ファイル|
##while ループ
'()'の両側にスペースがないとエラーが出ます

```bash
while ( 条件式 )
   <処理>
end
```
##if 条件分岐
これも'()'の両側にスペースがないとエラーが出ます

```bash
if ( 条件式 ) then
    <処理>
else if ( 条件式 ) then
    <処理>
else 
    <処理>
endif
```

##goto文
`goto name`で`name:`が書かれた行以下の処理にジャンプする。
if文と併用。あんまり使わない方がよい。

```bash
name:
<処理>

goto name
```

#算術演算
算術演算には行頭に`@`をつける。

```bash
set var = 5
@ var = $var + 3   #ここでは5+3が実行され、変数varの値は8となっている。
```

# その他Tips
### コマンドの実行結果を変数に代入する
```bash
set var = `<コマンド>`
#使用例
set var = `pwd`  #変数varにカレントディレクトリのパスが代入される  
```
### ファイルパスからファイル名だけを取り出す
```
filename <ファイルパス>
```
### ファイルパスからディレクトリだけを取り出す
```
dirname <ファイルパス>
```
#例文
最後に適当に例文を載せておく

```bash
#!/bin/tcsh -f
set ystr = 2005
set iyy = $ystr
set yend = 2010
set INPUT = $HOME/data
set OUTDIR = $HOME/data2
while ( $iyy <= $yend )
  set OUTPUT = $OUTDIR/$iyy 
    if ( ! -e $OUTPUT ) then
       mkdir -p $OUTPUT         #$OUTPUTで指定されるディレクトリがなかったら作成する
    endif
    cp $INPUT/$iyy/data.csv $OUTPUT/newdata.csv
@  iyy = $iyy + 1
end
```
python3で多数のcsv連結


## はじめに
タイトル通りです。
pythonである必要性はないのですが、

csvデータ複数取得 → pythonでcsv連結 → Jupyterでクラスタリング
csvデータ複数取得 → pythonでcsv連結 → 自然言語処理

等、開発環境をいちいち変えないようにできたらデータ管理しやすいですし、ある程度スムーズに作業できます。

## 前準備
今回は協調フィルタリング用に準備したファイルを使います。1列目に利用者ID、2列目は分解したコメントデータで構成されています。
![1.png](https://qiita-image-store.s3.amazonaws.com/0/273267/dec0f5b4-c55e-210a-d66f-61ad20ba06ca.png)

フォルダの場所は実行pythonファイルと同じディレクトリにある前提です。
main/
　├ csvフォルダ/
　└ 実行pythonファイル/

```
# -*- coding: utf-8 -*-
import os
import glob
import csv
import pandas as pd

# フォルダ中のパスを取得
DATA_PATH = "./<csvフォルダ名>/"
All_Files = glob.glob('{}*.csv'.format(DATA_PATH))
```

#csv連結
```
# フォルダ中の全csvをマージ
list = []
for file in All_Files:
    list.append(pd.read_csv(file))
df = pd.concat(list, sort=False)
```
#csv出力
わかりやすい名称を付けて結果をcsv形式で出力します。

```
df.to_csv('<*>.csv', encoding='utf_8')
```
#結果1
![1.png](https://qiita-image-store.s3.amazonaws.com/0/273267/e786d0ea-a3a6-52ee-1246-54158694ef4e.png)
![1.png](https://qiita-image-store.s3.amazonaws.com/0/273267/01ba34df-19a8-d794-4b60-3058c207fbe3.png)

自動的に'Unnamed: 0'という列が追加されています。python特有の仕様か私にはわかりませんが、修正しておきましょう。

```
# フォルダ中の全csvをマージ
list = []
for file in All_Files:
    list.append(pd.read_csv(file))
df = pd.concat(list, sort=False)
del df['Unnamed: 0']

# csv出力
df.to_csv('comm_datas.csv', encoding='utf_8')
```
del df['Unnamed: 0']を出力コードの手前に追加しました。再度出力結果を確認します。

#結果2
![1.png](https://qiita-image-store.s3.amazonaws.com/0/273267/788b79b5-722d-8038-0559-d605c59cfb0f.png)

目的の列は削除されていますね。これにて完了です。

#追記
出力されたデータですが、'utf_8'形式ですのでExcelで開くと当然文字化けします。そちらで確認したい場合にはエンコード形式を変えましょう。
一例：

```
# csv出力
df.to_csv('comm_datas.csv', encoding='utf_8_sig')
```
メルカリの検索結果が検索条件によって変わります

まず条件無しで検索結果
[条件無しで結果](https://www.mercari.com/jp/search/?keyword=%E8%A6%8B%E3%81%9B%E3%81%8B%E3%81%91%E3%81%AE%E5%8B%A4%E5%8B%89)
-> 18件
価格の安い順って条件で検索結果
[条件付き検索結果](https://www.mercari.com/jp/search/?sort_order=price_asc&keyword=%E8%A6%8B%E3%81%9B%E3%81%8B%E3%81%91%E3%81%AE%E5%8B%A4%E5%8B%89&category_root=&brand_name=&brand_id=&size_group=&price_min=&price_max=)
-> 5件
他の「価格の高い順」「いいね！の多い順」も同じような5件の結果が出ています。
「出品の古い順」「出品の新しい順」のほうがちゃんと18件を出します。
なんでこんな違いが出ているかよく分からない。コードにバグがあるかと考えられますね。メルカリに問い合わせしようと思うけど、HPに問い合わせ先が見つかりません。

僕のように安いものを探求するのが好きな人はやはり不利ですね。メルカリになんとかしてほしいです。
Railsでactiveadmin使用時にto_paramをid以外にしていた場合の対処法

[activeadmin](https://github.com/activeadmin/activeadmin/)はとても便利ですね！
簡単に管理画面を作成できるだけでなく、ある程度のカスタマイズにも対応できます。

## 何をしたいか :thinking: 

Railsではmodelに`to_param`というメソッドがあり、これを上書きすることでURLに含まれる`:id`を他のカラムにすることができます。
例えば以下のようにすることで、`/events/:id/`のidをnameカラムにすることできます。

```ruby
class Events < ApplicationRecord

  def to_param
    name
  end

end
```

to_paramの上書きはしばしばやると思うのですが、activeadminでの対応方法がネットで見つけづらかったので、記事にしようと思います。

## 何が起こるか :cry: 

上記のようにto_paramを上書きした場合activeadminではどうなるのでしょうか？

activeadminは今のモデル構造を分析することで自動的に管理画面を作成できるようになっています。そのため`to_param`もしっかり認識してくれます。
しかし、上書きした状態でactiveadminで詳細画面や編集画面を見ようとするとエラーしてしまいます。
<img width="1005" alt="スクリーンショット 2018-10-25 19.34.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/98204/4cca96bb-088d-ed47-3c04-54de4d282bbe.png">

これは、`admin/events`に表示される「閲覧・編集・削除」などのリンクがto_paramによって`admin/events/:name/`となっているものの、内部の`find`や`where`では**idで検索**していることに起因しています。

## 解決法 :hammer_pick: 

ActiveAdmin.registerのファイルに少しオプションを書くだけで対応できます。

```
ActiveAdmin.register Event do

  # ここから
  controller do
    def find_resource
      scoped_collection.where(name: params[:id]).first!
    end
  end
  # ここまで
end

```

読んでいるだけで理解できそうです。
通常`where(id: params[:id])`となるところを`where(name: params[:id])`にするだけです。

### 注意点 :warning: 
公式には以下のような文言で注意点が書かれています。

```
Note that if you use an authorization library like CanCan, you should be careful
to not write code like this, otherwise **your authorization rules won't be
applied**:

```ruby
ActiveAdmin.register Post do
  controller do
    def find_resource
      Post.where(id: params[:id]).first!
    end
  end
end
```

これはつまり、モデル名ではなく、`scoped_collection`を使わないとadminの権限管理が機能が効かないよ。ということですね。みなさんも注意してください！
AWSなどbitnamiで環境を整えたときにjavascriptがhtmlに展開される


# 概要

下記のコードが

```html:index.html
<script src="hoge.js"></script>
```

ブラウザで見ると下記のようになっている。

```html:index.html
<script><![CDATA[
console.log("hoge")
]]></script>
```

開発用などのサーバでこれが有効だと
`javascript` の変更が反映されるまで少し時間がかかって面倒い。

# 原因

`bitnami` の用意する `httpd.conf` に書かれた下記の中にあるっぽい。

```httpd.conf
Include conf/pagespeed.conf
Include conf/pagespeed_libraries.conf
```

パフォーマンスがいらないならコメントアウトすると良い。
スクラムのお供に「プランニングポーカー計算機」

# プランニングポーカーやるけど暗算苦手……
という事で、暗算するより計算機があったらいいんじゃないの？と思い立ち電卓ライクなツールを作りました。
EC2インスタンス立てて稼働させてたのですが、CloudFrontでの公開に移行できたのでツール自体を公開します。
（作りはとってもシンプルかつ簡素です）

## プランニングポーカー計算機

[PlanningPokerCalc](https://dpqd54wrk3eq7.cloudfront.net/)


## 使い方
1. プランニングポーカーで出たカードの数をポチポチ押していきます。
1. 人数分の数が押せたら「AVG」ボタンを押せば平均値が出ます。

「AVG」ボタンを押すまでは、下部に押した人数と数字が出るので参考にしてください。
初めからやる場合はクリアしてください。
（AVGボタン押した後でも、数字ボタンを押せば追加で計算可能。入れ忘れた時に便利）

## 技術的な概要
javascriptがメインです。
サーバー連携等特にないのでフロント側だけです。
エディターはVisualStudioCodeを使ってます。

S3 バケットにhtmlとcssとjsファイル入れてCloudFrontで配信してるだけです。

it so simple.
Lambda@Edgeのデプロイが簡単になった

us-east-1リージョン(バージニア北部)でLambda関数を作成し、新しいバージョンを発行して・・とやろうとしてたらアクションメニューにこんな項目を発見
<img width="231" alt="スクリーンショット 2018-10-25 20.24.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/249725/93123760-8d33-0d10-49da-015617efd4bb.png">
いつから追加されてたか知らないけどとても簡単にデプロイできるようになっている

従来であれば、us-east-1でLambda関数を作成し、新しいバージョンを発行し、CloudFrondディストリビューション作成時にLambda Function Associationsの項目に先ほどのバージョンのARNを貼り付けてやっていたものが、CloudFrontディストリビューションを作成し。Lambda関数をus-east-1で作成した後に、上記機能の項目をクリックして作成が可能になってる

さらに関数を更新した際の処理も簡単になっている、LATESTで関数を更新し、アクションからLambda@Edgeへデプロイを選択、「この関数で既存の CloudFront トリガーを使用」を選びデプロイするだけだ

<img width="805" alt="名称未設定.png" src="https://qiita-image-store.s3.amazonaws.com/0/249725/437dd6b4-785d-204e-041b-5ee9347c4825.png">
統合されたAI関連の検索用語集(案)

Search word / 検索用語集(案) / 2018.11
======================================
今後も新しい用語を見つけつつ、ある程度貯まったら更新していきたいと思います。
目的は、創造性（イマジネーション）を形にすることです。

ぼくの場合は、リアルな超絶美少女3DCGキャラクターにAIを入れてVR上で自由な発想で動いていただくことです＾＾

参考にはならないぼくのブログ：https://www.blissfulness5d.com/



5D AI（Five-dimensional Artificial Intelligence）
================================================
ディープラーニング（深層学習）、教師あり学習、HTM
ニューラルネットワーク、エキスパートシステム、遺伝的アルゴリズム
パーセプトロン
畳み込み
再起型ニューラルネットワーク(RNN)
強化学習（教師なし学習）
深層強化学習（Deep Reinforcement Learning）
オープンソース（TensorFlow、Chainer、Caffe、Neural Network Libraries by Sony）
量子人工知能
感性AI（冗談を言い合うAI、良きパートナー/友達）
デジタルアニーラ
プロシージャルモデリング
Houdini
意識 / 自意識 / 集合意識
自律式AI


4D VR（Four-dimensional Virtual Reality）
========================================
VR/AR/MR（Mixed Reality : 複合現実）
リアルタイム（即時性）
体験型
アバター
Unity、ユニティアセット
Unreal Engine
セミリアル
360°動画


3D CG（Three-dimensional Computer Graphics）
===========================================
モデリング（リファレンス、オブジェクト、人物、服、フォトリアル、セミリアル、カートゥーン）
Blender / ManuelBastioniLAB
ヴァーチャルヒューマン、メイクヒューマン
Marvelous Designer
スカルプト（ZBrush、ZBrushCore）
トポロジー
テクスチャマッピング (Texture mapping)
バンプマッピング
パーティクル
マッスル、リグ、IK、ボーン、ウェイト、モーフ
モーション（モーションキャプチャー、フェイスモーション、リップシンク）
VFX
ライティング
レンダリング
コンポジット
MMD
3Dゲーム（黒い砂漠）
3DCGアニメーション
セルルック


2D A（Two-dimensional Art）
==========================
写真、カメラ、ビデオ、HDR、4/8K、8/10/12-bit、30/60/120p
Raw Therapee
ラスター、ベクター
Gimp、Inkscape
フォトリアル
フォトジェニック
2DCGアニメーション
2Dゲーム
Live2D


1D C（One-dimensional Code）
===========================
プログラミング言語(C#、Python)
関数
素数 / 幾何学 / 数字 / ありとあらゆる言語体系
bit


0 (Zero)
====================
秩序が生まれた場所
ゼロポイント
無限が有限に変化する一点
エネルギー / 回転 / 動き
量子場
意識 / 無意識 / アイデア / 無限 / アーキテクト


α (alpha)
=========
nothing、無、実在
controller_spawnerで生成するros_controlのtopicはremapできない

`controller_spawner`で`diff_drive_controller`とかを作ると、

- `diff_drive_controller/cmd_vel`とか、
- `diff_drive_controller/odom`

的なトピックを使うことになると思いますが、このトピック名を変えたい事ってありますよね。`my_robot/odom`みたいに。
単純にremapしたらいいじゃん！と思ったのですが、spawnerの立ち上げ時にremapしても効かないんですね。

→　こんなのissueが上がってました。

- No way to remap controller topics #126
https://github.com/ros-controls/ros_controllers/issues/126

結論をいうと、remapする方法がなく、Twistならtwist_muxなど使ってがんばってくれとのこと。。。
普通に不便じゃないですか...?

追記:
topic_tools/relayでトピックをリレーしてあげたら、元のトピックは残ってしまうが目的としていることはできた。
http://wiki.ros.org/topic_tools/relay

他にいい方法があれば教えてください
Numpy配列のスライスで、変数のスワップ（交換）する時にハマった話

Pythonには変数のスワップ（交換）を簡潔に書けるコードがありますが、Numpy配列をスライスしたもの同士をスワップさせようとしたときにハマったのでメモしておきます。

環境：Numpy1.15.1、Python3.6.4

## 普通の変数のスワップはOK
普通の変数のスワップはもちろんOKです。一時的な変数を用意しなくていいのがとても良いですね。

```python
>>> a = 1
>>> b = 2
>>> a, b = b, a
>>> print(a, b)
2 1
```

aとbの値が入れ替わっていますね。

## Numpyのインデックスを指定してのスワップもOK
Numpy配列のスワップが全部ダメというわけではなく、インデックスを**値で**指定すればスワップできます。

```python
>>> a = np.arange(5)
>>> print(a)
[0 1 2 3 4]
>>> a[0], a[4] = a[4], a[0]
>>> print(a)
[4 1 2 3 0]
```

a[0]とa[4]が入れ替わっています。

## Numpy配列のスライス同士のスワップがNG
ここからが本題でこれがダメな例です。

```python
>>> a = np.arange(16).reshape(4,4)
>>> a[0:2, 0:2], a[2:4, 2:4] = a[2:4, 2:4], a[0:2, 0:2]
>>> print(a)
[[10 11  2  3]
 [14 15  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]
```

**えっ、右下の2x2の要素が[[0, 1], [4, 5]]に置き換わっていない？？**


### 順番を入れ替えたらどうなのか
0:2→2:4の順番で入れ替えたら2:4の値がコピーされましたが、2:4→0:2の順で入れ替えたらどうなるでしょうか？

```python
>>> a = np.arange(16).reshape(4,4)
>>> a[2:4, 2:4], a[0:2, 0:2] = a[0:2, 0:2], a[2:4, 2:4]
>>> print(a)
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9  0  1]
 [12 13  4  5]]
```

どうも先に代入されたほうの値がコピーされるみたいですね。この場合は後に代入するa[2:4, 2:4]が、最初の代入によって置き換えられてしまったのでしょう。

## 原因はNumpyのスライスが値のコピーではなくビューを作っているから
[StackOverFlow](https://stackoverflow.com/questions/14933577/swap-slices-of-numpy-arrays)にありました。

> This is because Numpy slices don't eagerly copy data, they create views into existing data. Copies are performed only at the point when slices are assigned to, but when swapping, the copy without an intermediate buffer destroys your data. 

[Numpyのドキュメント](https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#basic-slicing)には確かにビューを作っているとあります。

> All arrays generated by basic slicing are always views of the original array.

スライスはただ単にビューを作っているだけで、スライス単位でのスワップはそのビューの交換にすぎないから、元の値が置き換えられてしまうとスワップで期待された通りの結果が出ないということでしょうか。

追記：**コメント欄でこの内部挙動をを詳しく検証してくださった方がいました。必見です。**

## 解決法：2つ目のスライスを.copy()しよう
StackOverFlowの方法そのままですが、代入する側の値が置き換えられる前に.copy()してしまえばいいのです。

```python
>>> a = np.arange(16).reshape(4,4)
>>> a[0:2, 0:2], a[2:4, 2:4] = a[2:4, 2:4], a[0:2, 0:2].copy()
>>> print(a)
[[10 11  2  3]
 [14 15  6  7]
 [ 8  9  0  1]
 [12 13  4  5]]
>>> a = np.arange(16).reshape(4,4)
>>> a[2:4, 2:4], a[0:2, 0:2] = a[0:2, 0:2], a[2:4, 2:4].copy()
>>> print(a)
[[10 11  2  3]
 [14 15  6  7]
 [ 8  9  0  1]
 [12 13  4  5]]
```

どちらでもOKです。期待された通りの結果が出ました。

## 補足：Pythonのリストのスライス同士のスワップは一次元ならOK
Numpyの配列ではなく、Pythonのリストの場合はどうでしょうか？

```python
>>> # Numpyの場合（NG）
>>> a=np.arange(5)
>>> a[0:2], a[3:5] = a[3:5], a[0:2]
>>> print(a)
[3 4 2 3 4]
>>> # Pythonのリストの場合（OK）
>>> b=[0,1,2,3,4]
>>> b[0:2], b[3:5] = b[3:5], b[0:2]
>>> print(b)
[3, 4, 2, 0, 1]
```

Numpyの配列の場合はNGで、Pythonのリストの場合は一次元なら（追記）スライス同士をスワップさせてもOKという結果になりました。興味深いですね。

追記：一次元ならOKといったのは、リストの中にリストを入れたときにシャローコピーの関係で奇妙な挙動が起こるからです。ディープコピーではないのが注意が必要です。コメント欄で指摘してくださったshiracamusさん、ありがとうございました。感謝！（コードはコメント欄からです）

```python
>>> a = [[1],[2],[3],[4],[5],[6]]
>>> a[:3] = a[3:]
>>> a
[[4], [5], [6], [4], [5], [6]]
>>> a[0][0] = 999
>>> a
[[999], [5], [6], [999], [5], [6]]
```


## まとめ
「**Numpyの配列のスライス同士をスワップさせるときは、代入する側の2つ目の変数を.copy()しよう**」

以上です。思わぬ所に落とし穴があって勉強になりました。
Rubyのシンボルについてのメモ

最近Rubyについてきちんと勉強しようと思ってたのしいRubyを読んでたらシンボルが何かよくわからなかったのでメモ。

# シンボルって？
調べたところ、シンボルとは

* ソース上では文字列として
* 内部では数値として扱われる
* シンボルと文字列は一対一に対応
* メソッド名やクラス名、変数名などはシンボルになる

大事な性質はこんな感じ

# いろいろやってみる

## シンボルの表示
作ったシンボルを表示してみる。

まず変数`sym`にシンボル`:foo`を入れる。
で、`p`メソッドと`puts`メソッドで表示してみる。

```ruby
sym = :foo
p sym           #=> :foo
puts sym        #=> "foo"
```
うーん、普通に表示すると文字列として表示されるのか。
`p`メソッドで表示するとシンボルとして表示される。
つまりソース上では文字列として振る舞うけど、実際はシンボルだよーということがわかる。説明が難しい…。

ついでに楽しいRubyにも載っていた`to_s`と`to_sym`メソッドも試してみた。

```ruby
p sym.to_s      #=> "foo"
p "foo".to_sym  #=> :foo
```
なるほど。これはメソッドの説明通りそれぞれ文字列とシンボルオブジェクトに変わっている。
それにしても`to_s`はまだ使いそうだけど`to_sym`って使うことあるのだろうか…（使用する例とかあったら是非教えてください！）

## シンボルと文字列の違い

結局、これ、わざわざシンボル使わなくても文字列で良くない？って思っちゃうのでちょっと比較。

同じシンボルと文字列を作成してそれぞれのオブジェクトIDを比べてみる。

```Ruby
sym1 = :foo
sym2 = :foo
p sym1.object_id  #=> 496340
p sym2.object_id  #=> 496340

str1 = "foo"
str2 = "foo"
p str1.object_id  #=> 32323284
p str2.object_id  #=> 32323272
```

なるほど！シンボルでは結局同じ数値に変換されるから同じ名前のシンボルは同じ値、文字列は同じであっても違うオブジェクトとして認識されている。

要するにシンボルとは文字列の皮を被った数値なんですね！~~(言いたかっただけ)~~

# 終わりに
いろいろ自分で書いて実行してみてシンボルについての理解は深まったかな？と思う。
今後はしっかり文字列とシンボルをいい感じで使い分けていきたいなあ。

# 参考にさせて頂いたサイト
[Rubyの文字列とシンボルの違いをキッチリ説明できる人になりたい](https://qiita.com/Kta-M/items/53a13ef60e14fcb41193)
[Rubyのシンボルは文字列の皮を被った整数だ！](http://melborne.github.io/2008/08/02/Ruby/)
AndroidX Navigation SafeArgs で List を引数として渡す (Array として渡す方法追記)


2020/12/31 追記:
AndroidX Navigation SafeArgs 1.0.0-alpha08 からは、配列として引数を渡すことが可能になりました。

https://developer.android.com/jetpack/androidx/releases/navigation?hl=ja#1.0.0-alpha08

```xml
<argument
    android:name="items"
    app:argType="string[]"/>
```

プリミティブ型も Parcelable/Serializable もすべて上記の記述で Array となります。

Array として渡して、 受け取り側で List へ変換して使う形が良さそうです。
もともとのこの記事の方法で List を渡すこともできますが、 Parcelable な List に変換する手間がかかるため、Array を使う場合に比べて優位性はそこまでありません。

---
元記事:

AndroidX Navigation SafeArgs では List は引数として使えませんが、
Parcelable なクラスであれば使うことができます。

List を引数として使うときは `@Parcelize` と組み合わせます。

## Parcelize を使う設定

2020/12/31追記:
https://developer.android.com/kotlin/parcelize
https://developers-jp.googleblog.com/2020/11/the-future-of-kotlin-android-extensions.html
https://blog.jetbrains.com/ja/kotlin/2020/11/kotlin-1-4-20-released-ja/

Kotlin 1.4.20 からは Android Extensions は非推奨となり、 kotlin-parcelize プラグインを使うようになりました。

kotlin-parcelize を読み込めば使えるようになります。

build.gradle.kts

```
plugins {
    ..
    id("kotlin-parcelize")
}
```

build.gradle.kts にて `androidExtensions.experimental = true` の設定は不要です

## 引数クラスの定義

任意のパッケージで以下のような ArrayList を継承したクラスを定義します。
このクラスが Parcelable に対応します。

もちろん `Hoge` クラスも Parcelable であることが前提です。

```kotlin
@Parcelize
class HogeList(val list: List<Hoge>) : ArrayList<Hoge>(list), Parcelable
```

## Navigation XML の設定

`argType` を指定します。

```xml
<activity
    android:id="@+id/HogeActivity"
...
    tools:layout="@layout/activity_hoge">
        <argument
            android:name="hoge"
            app:argType="com.example.hoge.HogeActivity.HogeList"/>
```

## 引数の生成

引数を渡すときに、Parcelable なクラスに変換して、引数として使います。

```kotlin
HogeActivityArgs.Builder(HogeActivity.HogeList(list)).build()
```
シェルスクリプトを実行するときの引数の入力補完を設定する

プロジェクトの各ディレクトリに`upload.sh`というシェルスクリプトが置いてあって、`./upload.sh hostname`とやると、sshやscpでアップロードが行われるようになってます。
素のsshコマンドはbash-completionによって補完が行われれるようになっているけど、これと同じような補完をシェルスクリプトを実行するときにも行いたい。

[bash-completion を自分で作る。独自補完を作ってみた。 - それマグで！](http://takuya-1st.hatenablog.jp/entry/2016/02/10/175604)を参考に、以下のような感じでできました。

```bash:.bash_profile
complete_uploadsh() {
  local hosts=`grep "Host ${COMP_WORDS[COMP_CWORD]}" ~/.ssh/config | sed 's/^ *Host  *\(..*\)/\1/'`
  COMPREPLY=( $(compgen -W "${hosts}" ${COMP_WORDS[COMP_CWORD]}  ) )
}
complete -F complete_uploadsh upload.sh
```
Node.jsのネイティブモジュールをフェイクしてみた

Node.jsで使うことのできるモジュール `http` `fs` とかを自分の好きなように置き換えられるようにしてみた．
ちなみに，Node.js自体のバイナリは変更しない．

# フェイク被害を受けてもらうプログラム

```js:~/index.js
const http = require('http');
http.get('https://example.com/');
```

ここで， `http.get()` を本来の挙動ではないものにしてしまおう．

# `require` を置き換える

`require()` で呼ばれる関数はどこ？

自分の用意したモジュールを読み込むようにする．

```js:~/require.js
const overwrapNames = [
  'http',
];
const originalRequire = module.constructor.prototype.require;

module.constructor.prototype.require = function (id) {
  if (overwrapNames.some(name => name === id)) {
    return originalRequire.call(this, `${__dirname}/modules/${id}`);
  } else {
    return originalRequire.call(this, id);
  }
}
```

フェイクされて読み込まれるモジュールはこんな感じ．
既にrequireは置き換わっているので，フェイクされたモジュール内で本物のモジュールを使うときは `module.constructor._load()` を直接呼んで読み込む．

```js:~/modules/http.js
const http = module.constructor._load('http', module, false);
module.exports = {
  ...http,
  get(...args) {
    console.log('DUMMY!', ...args);
  },
};
```

# フェイク実行

```shell-session
$ node -r ./require.js ./index.js
DUMMY! https://example.com/
```
【Rails】ルーティングの確認方法

今日は、業務時によく使うルーティングの確認方法についてまとめます。

・ルーティングエラーが返ってきてしまった
・アクションを呼び出すための正しいURLが知りたい
・GETなのか、POSTなのか、リクエストの種類を確認したい

こんな時によく使います。

## rails routes
Railsのプロジェクト上のターミナルで

```
$ rails routes
```
と打つと

```
$ rails routes
                   Prefix Verb  URI Pattern                     Controller#Action
                 api_root GET   /api(.:format)                  api/root#index
                api_users POST  /api/users(.:format)            api/users#create
                 api_user GET   /api/users/:id(.:format)        api/users#show
                          PATCH /api/users/:id(.:format)        api/users#update
                          PUT   /api/users/:id(.:format)        api/users#update
```
現在のroutes.rbファイルに書かれているルーティングの一覧が取得できます。

今日はこのあたりで失礼します。
raspberrypiのOSを更新する方法

##### 2020年8月：記事の内容を更新しました。

授業で使うラズパイのOSを最新版に更新しろと先生から言われたので、クラスメイト向けに更新方法を説明します。

##結論
以下のコマンドを順に実行します。
（1）`sudo apt update`
（2）`sudo apt full-upgrade -y`
（3）`sudo apt autoremove -y`
（4）`sudo apt clean`
（5）`sudo reboot`


##少し詳しく説明

（1）`sudo apt update`
システムのパッケージを管理しているリストを更新します。

（2）`sudo apt full-upgrade -y` 
取得したパッケージリストに基づき、インストールされているすべてのパッケージを最新のバージョンにアップグレードします。
（この処理には時間がかかります。気長に待ちましょう。[^1]）

（3）`sudo apt autoremove -y`
（4）`sudo apt clean`
SDカードの空き容量を確保する為、不要なファイルを削除します。

（5）`sudo reboot`
ラズパイを再起動します。


これで完了です。お疲れ様でした！

## 最後に

不明点や間違っている点があればコメントでお知らせください

## 参考サイト

ラズパイの公式サイトを参考にしました。
[Updating and upgrading Raspberry Pi OS](https://www.raspberrypi.org/documentation/raspbian/updating.md)

sudo rpi-update は使わないようにしましょう。
https://qiita.com/takeaship/items/5861660c11d9d434368f

[^1]: raspberrypi zeroの場合60分ほどかかりました。
Pysparkでテキスト読み込み

Pysparkを使ってcsvファイルの読み込みを行います。

* CSVの行数をカウントする

```python
from pyspark import SparkContext
sc = SparkContext("local")
data = sc.textFile('sample_dataset.csv')
print(data.count())
sc.stop()
```

* ファイル内の指定した文字の件数をカウントする

```python
from pyspark import SparkContext

file = "C:\spark-2.3.1-bin-hadoop2.7\README.md" 
# SparkContext("local", "title")の()内は省略できるが、"local"を省略すると遅くなるらしい
sc = SparkContext("local", "sample")
data = sc.textFile(file).cache()

numAs = data.filter(lambda s: 'a' in s).count()
numBs = data.filter(lambda s: 'b' in s).count()

print("a: %i, b: %i" % (numAs, numBs))
sc.stop()

```

pythonはまだ慣れませんが、
テキストファイルの中身を簡単に取得できます。
Javaでtrimしても消えないスペースに悩まされた話 原因はBOM

csvファイルをJavaで読み込んだ後，文字列処理をする際にめちゃくちゃ悩まされた。

- 経緯
 - 文字列の最初に半角スペースがあるので，int型に変換できなかった．
 - なので，半角スペースを消そう！
 - …半角スペースが消えない！！！

# 半角スペースを消す

単純な方法としては　String.trim()　を行う．
（この時のスペースのunicodeは**\u0020**）

それでも消えないスペース（unicode **\u00A0**など）があるが，以下のサイトにまとまっていたので，参考に
https://eng-entrance.com/java-string-trim

でも，今回のスペースはそれだけでは消えなかった…

# 半角スペースのように見えるものを消す

エラーログに出力されるときは" "（通常のスペース）と同じ表示が出る．
この時に出力されたスペースをコピーして，貼り付けると通常のスペースと違う文字コードが表示される
その時のunicodeが
**\uFEFF**
………えっと，だれですか？

調べると，これがBOMのunicodeだった
http://e-words.jp/w/BOM.html．

これがわかれば置換できる！
**String.replace("\uFEFF","")** で対応

**スペース（のようなもの）が消えた！解決**

読み込んだcsvがUTF-8を使用するものだったからエラーが出ていたみたい
Vivus.js で「見えないペン」アニメーションを付けてみる

# はじめに

フロントエンドエンジニアをしています。
SVG画像に「見えないペン」でするする～と書いたようなアニメーションを付けられる Vivus.js を使ってみました。

**＊公式＊**
https://maxwellito.github.io/vivus/

**＊Github＊**
https://github.com/maxwellito/vivus/

**＊Vivus Instant＊**
https://maxwellito.github.io/vivus-instant/




# 実装方法

## 1. SVG画像の用意

イラレでSVG画像を作りました:fork_and_knife:
テキストデータはアウトライン化します。


![名称未設定-1_03.png](https://qiita-image-store.s3.amazonaws.com/0/287131/1055a224-596e-3a51-83cc-cd458c7204a4.png)


## 2. htmlの用意

htmlに、SVGのコードをいれます。
SVGにidを設定。

```python
<svg id="my-svg">
  <path...>
  <path...>
  <path...>
</svg>
```

## 3. CSS設定

今回は簡単に色を変えたりしているだけです。

```python
<style type="text/css">
  .st0 {
    fill: none;
    stroke: #00f4ff;
  }
# ↑fill は塗りつぶし。noneにしておく。stroke は線の色を指定しています。
  path {
    fill-opacity: 0;
    transition: fill-opacity 1s;
  }
# ↑pathの透明度を0にしておく。
  .fill path {
    fill: #ff94df;
    fill-opacity: 1;
    stroke: none;
  }
# ↑.fillがついたら、色をピンクに、pathの透明度を1に
</style>
```


## 4. アニメーション設定

vivus.jsの読み込みと、アニメーションのオプションを設定します。
公式にオプションのリストがあります。
https://github.com/maxwellito/vivus#vivusjs


```python
<script src="https://cdnjs.cloudflare.com/ajax/libs/vivus/0.3.2/vivus.js"></script>
<script>
  new Vivus('my-svg', # ここにはSVGに設定したidを入れる
    {
      duration: 120 , # アニメーションの時間
      start: 'autostart', # アニメーションの自動再生
      pathTimingFunction: Vivus.EASE_OUT # アニメーションのタイプ
    },
    function(obj){
      obj.el.classList.add('fill'); # アニメーション後、'fill'クラスを付与してアニメーションを実行
    }
  );
</script>
```

# 実装結果

<p data-height="265" data-theme-id="0" data-slug-hash="mzQdYR" data-default-tab="html,result" data-user="yuzukisakioka" data-pen-title="mzQdYR" class="codepen">See the Pen <a href="https://codepen.io/yuzukisakioka/pen/mzQdYR/">mzQdYR</a> by Yuzuki (<a href="https://codepen.io/yuzukisakioka">@yuzukisakioka</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>





# まとめ
今回は簡単なサンプルでしたが、オプションもたくさんあり、工夫次第でお手軽に素敵なアニメーションができるようです。
まずはぜひ触ってみてください:yum:
デザイナーさんにアニメーションを作ってもらわなくても、こんなこともできますよと提案できるようなエンジニアになりたいなーと思います。
position:fixedの親要素に収める方法が見当たらない

#目的
ページ全体ではなく、一部コンポーネント内で幅を納めた状態で`position:fixed`を効かせたい
![fixed.jpg](https://qiita-image-store.s3.amazonaws.com/0/290624/2e48d925-a036-ac16-ed1b-28870e56d71b.jpeg)

親に`transform: translate3d(0, 0, 0);`を書いてみると
今度は`fixed`が聞かなくなってしまう。

どうするか迷い中...
Phoenixのphx.gen.htmlでpasswordフィールドを生成するときは忘れずにtemplateを変更しよう！

## この記事の概要

* phx.gen.htmlでpasswordフィールドをテンプレート生成する際には`form.html.erb`の`text_field`を`password_field`に変更する

## 問題の再現

こんな感じで適当にアプリケーション生成して、passwordフィールドを持つUserモデルを生成してみます

```bash
mix phx.new hoge
cd hoge
mix ecto.create
mix phx.gen.html User User users name:string password:string
```

忘れずに`resources "/users", UserController`をrouter.exに追加して`mix ecto.migrate`します

そうすると以下のような`form.html.eex`が生成されると思います

```erb:hoge\lib\hoge_web\templates\user\form.html.eex

<%= form_for @changeset, @action, fn f -> %>
  <%= if @changeset.action do %>
    <div class="alert alert-danger">
      <p>Oops, something went wrong! Please check the errors below.</p>
    </div>
  <% end %>

  <div class="form-group">
    <%= label f, :name, class: "control-label" %>
    <%= text_input f, :name, class: "form-control" %>
    <%= error_tag f, :name %>
  </div>

  <div class="form-group">
    <%= label f, :password, class: "control-label" %>
    <%= text_input f, :password, class: "form-control" %>
    <%= error_tag f, :password %>
  </div>

  <div class="form-group">
    <%= submit "Submit", class: "btn btn-primary" %>
  </div>
<% end %>

```

## このままにしておくと？

`mix phx.server`して`localhost:4000/users/new`にアクセスしてみましょう
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201242/e32beb01-c6bf-b489-ce2d-3d7f07ff36ca.png)

こんな感じでNameフィールドを空にしてあえてエラーが出るようにしてsubmitしてみます（この時点でパスワード表示されているのでマズイです）
すると以下のようなエラーが出ます

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201242/522a8953-ea7d-7c21-bab8-38dc9b8a17be.png)

**入力したパスワード**が表示されてる！！
ちなみにパスワードハッシュ化してる場合はハッシュ化済みのパスワードが表示されるので、セキュリティ的に大変マズイです

### 解決策
こういう時にPhoenixは良い関数を用意してくれています。password_inputです！
先ほどの`form.html.eex`でpassword入力フォームの`text_input`となっている部分を`password_input`に変換します

```erb:form.html.eex
  <div class="form-group">
    <%= label f, :password, class: "control-label" %>
    <%= password_input f, :password, class: "form-control" %>
    <%= error_tag f, :password %>
  </div>
```

もう一度`localhost:4000/users/new`にアクセスしてみるとこうなります

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201242/b2d73803-1581-a52a-75ee-cecb9e15f8dd.png)

ちゃんとパスワード隠れてますね！submitしてみると以下のようにちゃんとパスワードフィールドは空で返ってきます

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201242/67730b3d-f030-2667-75f1-1fe5030de11d.png)


### text_input と password_input の違い
公式の説明を見てみると、入力したデータを再利用しないような配慮がされているみたいですね

> For security reasons, the form data and parameter values are never re-used in password_input/3. Pass the value explicitly if you would like to set one.

[password_input/3 | Phoenix.HTML.Form – Phoenix.HTML v2.12.0](https://hexdocs.pm/phoenix_html/Phoenix.HTML.Form.html#password_input/3)
[text_input/3 | Phoenix.HTML.Form – Phoenix.HTML v2.12.0](https://hexdocs.pm/phoenix_html/Phoenix.HTML.Form.html#text_input/3)

## まとめ
ちゃんとドキュメント把握しておくの大事ですね！
ちなみに`show.eex`とか`index.eex`にもパスワード表示されているので忘れずに削除しておきましょう笑

余談ですが本記事執筆時点（2018/10/25）で`mix phx.server`すると`{:plug_cowboy, "~> 1.0"}`を追加するようにエラーが出るので、その場合は`mix.exs`に追加して`mix deps.get`すればOKです
Google App Makerでスクリプト言語を使わず開発できますでしょうか。

Google App Makerを利用して、複数のスプレッドシートの情報をテーブルで参照し、更新、削除、追加などをスクリプト言語を使わずに実現することは可能でしょうか。
DBもCloud SQLを利用せず、DB用にスプレッドシートに保存できるようにしたいと考えてます。
ノンプログラマーの私でも、App Makerを利用して、管理アプリを作れないか検討しているのですが、現在ネットで調べながらでは必ずスクリプト言語を利用している感じがあります。
Wordに関連付けられているdotファイルを、テキストエディタで編集したい！

#バッチファイルで解決しよう！#
Graphvizでdotファイルを編集しようとすると、dotファイルがWordに関連付けられていることがあります。それを、わざわざ右クリックから"メモ帳で開く"で開いていませんか？そこで、txtファイルで編集しておいて、最後にpngやpdfにする際に、勝手にdotファイルに変換してくれるバッチファイルを作ってみました。ちなみに、バッチファイルの大まかな構造自体は、前回 [【Graphviz 】dotファイルを画像ファイルに変換する。(for Windows)](https://qiita.com/NumLocker/items/a145080647a69cd2997a) で紹介したものとほとんど変わっていません。

```
@echo off
pushd %~dp1
echo;
echo dotファイルに変換後、画像ファイル、pdfファイルに変換します。
ren "%1" "%~n1.dot"
set file=%~n1.dot
echo;
set /p type=変換先拡張子の入力  ＞＞＞  
"C:\Program Files (x86)\Graphviz2.38\bin\dot.exe" -Kdot -T%type% "%file%" -o"%~n1.%type%"
ren "%file%" "%~nx1"
```

最後 (10行目) には、もう一度拡張子をtxtに戻しています。

-------------
###追記 (2018/10/30)###
ファイル名を変更して保存させるバッチファイル
一度目に```変換先拡張子の入力  ＞＞＞  ```と出た際に、r (半角小文字) を入力することで、別名で保存可能。また、TXTファイルがD&Dされなかったり、ダブルクリックでバッチファイルが開かれたときに、エラーが返ってくるようにしました。

```
@echo off
pushd %~dp1
ren "%1" "%~n1.dot"
if %errorlevel% neq 0 (
echo TXTファイルをドラッグアンドドロップしてください。
timeout 7 > nul
exit
)
echo;
echo dotファイルに変換後、画像ファイル、pdfファイルに変換します。 (リネーム保存用隠しコマンド：r)
set file=%~n1.dot
echo;
set /p format=変換先拡張子の入力  ＞＞＞  


if "%format%"=="r" goto :ren_option
"C:\Program Files (x86)\Graphviz2.38\bin\dot.exe" -Kdot -T%format% "%file%" -o"%~n1.%format%"

ren "%file%" "%~nx1"

exit


:ren_option
echo;
set /p name=変換先ファイル名の入力  ＞＞＞  
echo;
set /p format=変換先拡張子の入力  ＞＞＞  

"C:\Program Files (x86)\Graphviz2.38\bin\dot.exe" -Kdot -T%format% "%file%" -o"%name%.%format%"

ren "%file%" "%~nx1"

exit

```
synchronizedとReentrantLockについて

logbackのwar間共有をするにあたってソースを読んでいたときのメモ

- [synchronizedブロックとReentrantLockの違いについて。](https://teratail.com/questions/1803)
- [JDK 5.0における、より柔軟でスケーラブルなロック](https://www.ibm.com/developerworks/jp/java/library/j-jtp10264/)
- [ロックとファイルロックの違い](https://qiita.com/chiharuisaki/items/034a9c8e9c91630cb8ce)


## logbackにおいて
ファイル出力を行う際は最終的に [ch.qos.logback.core.OutputStreamAppender<E>#writeBytes(bite[])](https://logback.qos.ch/apidocs/ch/qos/logback/core/OutputStreamAppender.html#writeOut(E)) で書き込みを実施。
ファイルオープン処理等も含め、ロックはReentrantLockにて実施しており、[FileLock](https://docs.oracle.com/javase/jp/6/api/java/nio/channels/FileLock.html)は実施していない。
rbenvで切り替わらないとき

rbenvでrubyのversionを新しくしたいのに切り替わらない．

# 症状<a id="sec-1" name="sec-1"></a>

    > rbenv versions
    system
    # 1.8.7-p249 (set by /Users/bob/.ruby-version)
    2.5.3

なんだけど，

    > rbenv global 2.5.3

としてもそのまま．

$PATHがダメという解説記事はたくさんあるが，

    > which ruby
    /Users/bob/.rbenv/shims/ruby

となっており，ちゃんと設定されている．

# 解決策（こいつは正しくないです．申し訳ない）

    > cd ~
    > rbenv local 2.5.3

で切り替わりました．なんかあったんだろう．⏎

# 追記
[uasi](https://qiita.com/uasi)さんのご指摘を受けての正しい対処法です．症状と原因は下のコメントを読んでください．

    > rm ~/.ruby-version
    > rbenv versions
      system
      1.8.7-p249
    * 2.5.3 (set by /Users/bob/.rbenv/version)
hover時にテキストを切り替える方法

#実装すること
マウスポインタが指定範囲に入った時、つまり`hover`時に表示を切り替える

#方法
`button`の子要素として`span`要素を２つ配置、`hover`時に２つの`span`の`css`を切り替えることによって実装します。

![Oct-25-2018 18-21-49.gif](https://qiita-image-store.s3.amazonaws.com/0/252342/3e92bed3-8785-f0f7-9a86-2434a9d7e057.gif)

###HTML
```html
<button>
  <span>おはよう</span>
  <span>こんばんは</span>
</button>
```

###CSS
```css
button {
  margin: 100px;
  display: inline-flex;
  justify-content: center;
  padding: 1em;
  border: solid 1px black;
}
span:nth-child(1) {
  position: absolute;
  display: none;
}
button:hover span:nth-child(1) {
  display: inline-block;
}
button:hover span:nth-child(2) {
  opacity: 0;
}
```
AWSのboto3を使ってサーバのコマンド結果をSQSのキューに飛ばしてSNSでメール送信してみた

# やりたいこと

1. AWS上のEC2(Linux)で一定時間毎に自動的にコマンドを叩く。
2. コマンドの標準出力をメールで飛ばす。ついでにSQSにも連携しとく。

# 方法
- pythonのboto3を用いて、SNSでメールを飛ばす。
- SQSへはSNSのサブスクリプションで連携する。

# 前提
- EC2を立てる(ここでのサーバはRHEL系を想定してます。)
- EC2にaws cli、python3、boto3のインストール。
- aws configureでユーザ認証。
- SNSでトピック及びサブスクリプション作成。
- SQSでキュー作成。

# コード
EC2上で以下のスクリプトを作成。
実行するコマンドやSNSのトピックはXXXXX表記ですので、適宜置き換えて下さい。あと、変数はテキトーです（笑）。

```
### send_msg.py ###

import boto3
import subprocess
import shlex
import time

# SNSのトピックのARNを記載
sns = boto3.resource('sns')
topic = sns.Topic('arn:aws:sns:ap-northeast-1:XXXXXXXX:topic-name')

def execute_command_and_publish(cmd):
    process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
    output = process.stdout.read()
    decoded_output = output.decode("UTF-8")
    
    response = topic.publish(Message=decoded_output)
    print(response)

# 出力させたいコマンドを指定
cmd = "XXXXXXX"
execute_command_and_publish(cmd)

# ループ処理（ここでは1分毎に定期実行）
while True:
    execute_command_and_publish(cmd)
    time.sleep(60)

```

# 参考にしたもの
以下参考にさせていただきました。ありがとうございました。
・[AWS SDKを使ってSNSにCPU使用率を送りつける](http://www.smokeymonkey.net/2013/10/aws-sdksnscpu.html)
・[boto3 (AWS SDK for Python) メモ - Qiita](https://qiita.com/draco/items/8b99e5494ec5b1371f32)
・[boto3を使ってAmazon SNSへpublishしてみた | DevelopersIO](https://dev.classmethod.jp/cloud/publish_to_sns_using_boto3/)
csh/tcsh で配列のソート

csh/tcshは人気がないらしく，tips的なものを見つけるのが難しいので自分でメモを残していくことにしました．
主に自分用なので質についてはあしからず．

# 配列のソート
tcshで変数に格納した配列をソートする．
以下が変数xの配列をソートして変数yに代入して表示するスクリプト．

```shell:
set x = (10 24 100 103 21 34 101)
echo $x
set y = `echo $x | tr ' ' '\n' | sort -n` 
echo $y
 ```

要は`tr`コマンドでスペースを改行に変換してから`sort`に渡している．
bashなどではfor文で配列の要素を１つずつ`echo`してそれを`sort`に渡せばいいが，
tcshはfor文をワンライナーで書きづらいので，こんな感じにした．

#文字列の配列を数字順にソート
「文字列\_数字」など，特定のフォーマットにそっていれば，
数字の直前にある文字や記号を区切り子に指定してソートすればいい．

```shell
set x = (a_10 a_24 a_103 a_21 a_34 a_310 a_250)
echo $x
set y = `echo $x | tr ' ' '\n' | sort -k 2 -t "_" -n`
echo $y
```

#おまけ：なぜtcshか
`set`と`=`と変数の間にスペースをすきなだけ入れられるので，
スクリプト内で実験条件などを変数に格納するとき`=`の位置を揃えられてキレイ．
UiPath StudioのPublish時のバージョンの算出方法について

UiPath Studio 2018.3、Community Editionだけでなく、商用版もリリースされましたね。

https://www.uipath.com/release-notes/uipath-v2018.3.1

さて、2018.2.xまでは明示的に指定出来なかった UiPath StudioでPublishする際のバージョンですが、 2018.3からはヒトが入力して明示的に指定出来るようになりました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/73777/8364afca-e9f0-3ff6-39e0-1ac0284e115c.png)

この、お客さんに「このバージョンどうやって決まるの？長いんだけど。。」って言われるヤツですね。明示的に指定出来るようになってよかったです。。


ところでこの自動生成される「6826」と「30547」ですが、どうやって出力されてるのかな？と思って調べてみると、、、、

[オートメーションプロジェクトの公開について](https://studio.uipath.com/lang-ja/v2018.2/docs/about-publishing-automation-projects)

どうやらここを見ると、


>ビルドバージョンとリビジョンバージョンはアルゴリズムに従って生成されます。ビルドの値は、01.01.2000 (2000 年 1 月 1 日) からの経過日数です。リビジョンの値は、GMT の午前 5 時からリリース日時までに経過した秒数です。

なるほど。

計算してみましょう。ちなみに、うえのこのキャプチャは日本時間の 2018/09/09/ 16:58のものです。。


### やってみる

GMTの5時から、ビルドバージョン 6826 を経過日数として足して、リビジョンバージョン 30547 を秒数として足せばよいんですね、、。


```C#
 static void Main(string[] args)
 {
     int build = 6826;
     int revision = 30547;
     pattern2(build, revision);
 }

 private static void pattern2(int build, int revision)
 {
     TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
     TimeSpan span = tz.BaseUtcOffset;

     // そのタイムゾーン(TimeSpan)の、DateTimeOffset オブジェクト作成
     DateTimeOffset date = new DateTimeOffset(2000, 1, 1, 5, 0, 0, span);

     date = date.AddDays(build).AddSeconds(revision);
     Console.WriteLine("Pattern2: {0}", date.ToString());
 }
```
こうなるのかな？やってみましょう。。。

```
Pattern2: 2018/09/09 13:29:07 +00:00
続行するには何かキーを押してください . . .
```

うん、合いませんね、、。。なんでだろう。。

### もすこし調べてみる

も少し調べてみると、、こんなサイトも見つけました。
[How to have an auto incrementing version number (Visual Studio)?](https://stackoverflow.com/questions/826777/how-to-have-an-auto-incrementing-version-number-visual-studio)

てことで再度、やってみましょう。

```C#
static void Main(string[] args)
{
    int build = 6826;
    int revision = 30547;

    pattern1(build, revision);

}

private static void pattern1(int build, int revision)
{
    TimeZoneInfo tz = TimeZoneInfo.Local;
    TimeSpan span = tz.BaseUtcOffset;

    // そのタイムゾーン(TimeSpan)の、DateTimeOffset オブジェクト作成
    DateTimeOffset date = new DateTimeOffset(2000, 1, 1, 0, 0, 0, span);

    date = date.AddDays(build).AddSeconds(revision * 2);
    Console.WriteLine("Pattern1: {0}", date.ToString());

}
```

実行結果は、、、

```
Pattern1: 2018/09/09 16:58:14 +09:00
続行するには何かキーを押してください . . .
```

なんでかよく分かりませんが、一致しました。。。。
Visual Studio界隈のお作法？なんですかね。

わかるひとおしえてくださーい。。。

以上、お疲れ様でした。
API Gateway用にSwaggerからexampleを削除する

# はじめに

swaggerファイルからexampleを取り除くnpmライブラリを作ってみました。

以下に公開してあります。

- [npm | swagger-rm-example](https://www.npmjs.com/package/swagger-rm-example)
- [GitHub | swagger-rm-example](https://github.com/segurvita/swagger-rm-example)


# なにができるの？

こんな感じに `example` が入ったSwaggerがあるとします。

```yaml
swagger: '2.0'
info:
  description: これはアパートに関するAPIです。
  version: 0.0.1
  title: アパートAPI
paths:
  '/rooms/{room-id}':
    get:
      summary: 部屋情報API
      description: 指定されたroom-idの情報を返します
      parameters:
        - name: room-id
          in: path
          description: 取得したい部屋のID
          required: true
          type: integer
          format: int64
      responses:
        '200':
          description: OK
          schema:
            type: object
            properties:
              id:
                type: integer
                format: int64
                example: 404
              comment:
                type: string
                example: 404号室です。どこにも存在しない部屋かも。
```

上記を入力すると、下記が出力されます！

```yaml
swagger: '2.0'
info:
  description: これはアパートに関するAPIです。
  version: 0.0.1
  title: アパートAPI
paths:
  '/rooms/{room-id}':
    get:
      summary: 部屋情報API
      description: 指定されたroom-idの情報を返します
      parameters:
        - name: room-id
          in: path
          description: 取得したい部屋のID
          required: true
          type: integer
          format: int64
      responses:
        '200':
          description: OK
          schema:
            type: object
            properties:
              id:
                type: integer
                format: int64
              comment:
                type: string
```

`example` だけ削除されました！
階層のどこにあっても見つけだして消します！


# なぜ作った？

Amazon API GatewayにSwaggerファイルをインポートしたところ、以下のようなエラーが発生しました。

```
errors : [Invalid model schema specified. Unsupported keyword(s): ["example"]]
```



Swaggerファイルの `definitions` から `example` を削除すれば、API Gatewayでエラーは発生しないようですが、Swagger UI では `example` を使っています。



それなら、普段はexample有り版で書いて、API Gatewayに登録する時だけ `example` を取り除けばいいじゃない！となりライブラリを作りました。



# インストール方法

本ライブラリの使用にはNode.jsが必要です。

Node.jsがインストール済みであれば、以下のコマンドでインストールできます。

```bash
npm install swagger-rm-example
```



# 使い方

サンプルコードは以下の通りです。

```javascript
// ライブラリを追加
var fs = require('fs');
var swaggerRmExample = require('swagger-rm-example');

// YAMLファイルを読み込み
var inputFile = "./swagger_input.yaml";
var strInput = fs.readFileSync(inputFile, 'utf8');

// 文字列からexampleを削除
var strOutput = swaggerRmExample.removeExample(strInput);

// 結果を表示
console.log(strOutput);

// YAMLファイル書き出し
var fileOutput = "./swagger_output.yaml";
fs.writeFile(fileOutput, strOutput);
```


# さいごに

これで快適なSwaggerライフが送れそうです。

npmにパッケージを公開するのは初めてでしたが、以下の記事がとてもわかりやすく、予想よりも短時間で済みました。

- [npmに自作ライブラリーを公開してみた](https://qiita.com/t-niiru/items/92b8d626126c48f68d66)
- [3分でできるnpmモジュール](https://qiita.com/fnobi/items/f6b1574fb9f4518ed520)
JuliaでDiscordのbotを書く(Python使わずに)

### はじめに
初投稿&タイトルのまんまです。
juliaあまり分かっていないので間違いがあるかもです。
#### 実行環境
> OS: Windows 10
> Julia: 1.0.1

JuliaだけでDiscordのBOT書けないかな～って探していたら

https://github.com/PurgePJ/Discord.jl 
こんなリポジトリを見つけてしまいました。
というわけでさっさとインストールしちゃいましょう。

```
(v1.0) pkg> add https://github.com/PurgePJ/Discord.jl.git
```
> ~~julia> using Pkg~~
> ~~julia> Pkg.clone("https://github.com/PurgePJ/Discord.jl.git")~~
> Pkg.cloneは過去の遺物だそうです。コメントでのご指摘ありがとうございます。<(_ _)>

インストールが完了したのでREADMEに書いてるのを真似してみます。

```julia
using Discord

c = Client("token")

add_handler!(c, MessageCreate, (_, e) -> println("Received message: $(e.message.content)"))
open(c)
wait(c)
```
これでDiscordに書いた内容がコンソール上に表示されるハズです。

#### add_command!()で簡単にコマンドを追加する

```julia
using Discord

function onCommand(c::Client, m::Discord.Message)
    reply(c, m, "HogeHoge")
end

c = Client("token")

add_command!(c, "!hoge", onCommand)
open(c)
wait(c)
```
Discordで`!hoge`と送ると`HogeHoge`と言い返してきます。
簡単。

というわけでとりあえずここまでです。
char(255) みたいな固定長文字列をMigrationしたい

# やりたいこと
Railsで固定長文字列 char(255) をDBに定義したいんです。

__固定長文字列は…__
- char()
- character()

__可変長文字列は…__
- varchar()
- character varying()

## :no_good:これだと varchar(255)
```ruby
create_table :hoge do |t|
  t.string :fuga, limit: 255
```

## :ok_woman: こうすると char(255)
```ruby
create_table :hoge do |t|
  t.column :fuga, "char(255)"
```

# 結論
`t.column :なんとか, "かんとか"`でゴリ押しできる

# おわり✨🍰✨
DeepLearningで似ている芸能人を判定するWebサービスを作りました

Courseraの授業を中心に遅ればせながらDeepLearningの勉強をしてきたので、なにかアウトプットしようと思い立ち、写真を撮るとどの芸能人に似ているか判定するWebサービスを作りました。

[Who Am I｜似ている芸能人診断Webアプリ｜有名人探しサイト](https://whoami.fun)

## 使った技術

### Siamese Network
DeepLearningで画像処理を行う場合はCNNをSoftmax関数でフィニッシュして分類問題として取り扱うのが普通ですが、Siamese Networkは異なる2つの画像をCNNに通してそれらがどのくらい似ているか(距離が近いか)をSigmoid関数で数値化するというものです。
画像が似ている/異なっているということがどういうことかを覚えさせ、それを予測に用いるモデルです。Courseraの中ではデータセットが少ない場合の選択肢となりうる、顔認識(オフィス入館のための本人認証など)で使われる、といったことが解説されていました。

### Flask
めちゃシンプルなサイトなので、いつもはDjangoを使うところFlaskを使ってみました。
評判の通り軽量で、サイトがソッコーで立ち上がりました。こりゃ簡単なサイトを作る時はいいですね。

### face_recognition
DeepLearningに渡す前に顔を認識して切り取る処理に[face_recognition](https://github.com/ageitgey/face_recognition)というライブラリを使いました。
当初はOpenCVを使っていたのですが、MacへのインストールまはまだしもLinux上でApache経由で使う時に謎のフリーズが発生し解決できなかったのでスイッチしました。
顔認識だけだったらOpenCVよりも断然使いやすいと思います。Web上ではOpenCVはインストールが大変という声が多いですし。

## 精度

似ている芸能人を上から10人まで表示していて、その中の3人くらいはまあ確かに言われてみれば、みたいな精度です。
芸能人本人の写真で試すと結構な確率で本人が一番似ていると判定するので、やはりこのモデルは同一人物特定に力を発揮するようです。そう考えると例えば工場のラインで商品の異常を見つける異常検知とか、異常のあるもののデータは基本的に少ないので、少ないデータセットでもうまく動かすことのできるこのモデルが利用できるかもしれません。

## その他
- PCならChrome、Firefox、iPhoneならSafari(設定からカメラのアクセスを許可する必要があります)、AndroidならChrome、Firefoxでの動作確認ができています。
- 撮影/アップロードされた画像は判定したらすぐに削除する作りです。自分だったら顔写真が保存されるのが嫌なのと、サーバー容量を圧迫したくなかったので。
- iPhoneアプリで類似のものがありましたが、頻繁に使うものでもないのでWebの方が利便性高いと考え開発しました。
- 結果ページで見せてる画像は著作権的にアウトっぽいので、万が一アクセスが伸びたら使うのやめたほうが良さそう。。
- 何度やってもバナナマンの日村に似てると判定される。。悲しい。

よかったら遊んでみてください。

[Who Am I｜似ている芸能人診断Webアプリ｜有名人探しサイト](https://whoami.fun)
Could not locate a virtual/physical font for TFM "uprml-h" というエラーでdvipdfmxが落ちるときの対処法

TeXのコンパイルが「"uprml-h"が見つからない」というエラーで落ちる時の対処法。

# 環境

- MacTeX2018
- macOSX High Sierra
- upTeX (pLaTeX)

# 状況

dvipdfmxが以下エラーでうまくいかず、TeXのコンパイルができない

```console
dvipdfmx:warning: Could not locate a virtual/physical font for TFM "uprml-h".
```

# 対処法

ヒラギノフォントを使おうとしていた時のエラーなので、一時的にipaex等のフォントに変更すれば動作した。

```bash
kanji-config-updmap-user ipaex
sudo mktexlsr
```

## 余談

実は以下サイトを参考にしたのですが、以下サイトの回答ではシステム設定を変更しています。しかし、システム設定を変更しただけでは、エラーが消えませんでした。しかし、上記コマンドでユーザ設定を変更したところ、エラーが消えました。原因は不明です。

> TeXとフォント>フォントを変えてみる（日本語フォント）
https://texwiki.texjp.org/?cmd=read&page=TeX%E3%81%A8%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88&word=mac%20%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88%20%E5%9F%8B%E3%82%81%E8%BE%BC%E3%81%BF%20ipa#q1b5e62f
を参考にとりあえず IPAex などに埋め込むフォントを変更してはどうでしょうか？
- - -
ありがとうございます。
% sudo kanji-config-updmap-sys ipaex
% sudo mktexlsr
にて対応できました。
【引用元】https://oku.edu.mie-u.ac.jp/tex/mod/forum/discuss.php?d=2267&parent=13345
leafletを鍛える。その11

#概要

leafletを鍛えてみた。
d3のv4でjsonよんでみた。

#写真

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/s/W/S/sWSk.jpg?t=1540438816)

#参考にしたページ

https://qiita.com/1coin178/items/38551d861ae6a11d545c

#サンプルコード

```
var map = L.map('map').setView([35.7, 139.7], 3);
var mapLink = '<a href="http://openstreetmap.org">OpenStreetMap</a>';
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '&copy; ' + mapLink + ' Contributors',
    maxZoom: 18,
}).addTo(map);


d3.json("http://jsrun.it/assets/Q/w/7/T/Qw7TW", function(error, json) {
    var data = json.results.bindings;
    data.forEach(function(d, i) {
        if (d.lat.value != null && d.long.value != null) 
        {
            var title = d.name.value;
            var mark = L.marker(([d.lat.value, d.long.value]), {
                title: title
            }).addTo(map);
        } 
    });
});
    

```

#成果物

https://embed.plnkr.co/zDbGl9QniIeFPTrSAuPL/


以上。
【baserCMS：初心者向け】ページごとにヘッダーなどの読み込みを分岐させる

#読み込みの分岐
例えばページによってヘッダーやフッターを切り分けたい時があると思います。
下層ページはヘッダーのデザインが違うとかメイン画像サイズが変わるとかメニューが変わるとか
そういう時に使えるタグです。
「"About"というスラッグのページだけはabout_header.phpを読み込む。」
「"Service"というスラッグのページだけはservice_header.phpを読み込む。」
「それ以外のページは共通でheader.phpを読み込む。」
といった感じになります。

~~~php
<?php if($this->BcBaser->getContentsName() === 'About'): ?>
	<?php $this->BcBaser->element('about_header') ?>
<?php elseif($this->BcBaser->getContentsName() === 'Service'): ?>
	<?php $this->BcBaser->element('service_header') ?>
<?php else: ?>
	<?php $this->BcBaser->element('header') ?>
<?php endif ?>
~~~

トップページだけに表示したい時はこんな感じ。

~~~php
<?php if($this->BcBaser->isHome()): ?>
<!-- トップページのみに出力する内容 -->
<?php endif ?>
        
~~~

ちなみに記事の詳細ページのみ分岐したい時はこうなります。

~~~php
<?php if ($this->BcBaser->isBlogSingle()): ?>
	<?php $this->BcBaser->element('single_header') ?>
<?php else: ?>
	<?php $this->BcBaser->element('header') ?>
<?php endif; ?>
~~~

あと〇〇ページじゃない時！とか

~~~php 
<?php if (strtolower($this->BcBaser->getContentsName(true)) !== 'work'): ?>
<?php endif; ?>
~~~

複数ページをまとめて指定だとこんな感じですね。(スラッグがpolicyページかfaqページじゃない時)

~~~php
<?php
$slug = strtolower($this->BcBaser->getContentsName(true));
if ($slug !== 'policy' && $slug !== 'faq'): ?>
〜コンテンツ〜
<?php endif; ?> 
~~~
分割圧縮

添付ファイルの大きさが制限されているWebサービスやメールサービスなどがある。
その際に、分割圧縮を利用することがある。

7zip
https://sevenzip.osdn.jp/howto/split-compress.html



# Windows
7-Zipを使用してファイルを分割する
https://qiita.com/a-tan/items/41e11b34d83dacf8b1c5

7-Zipの解凍パスワードを自動入力
https://qiita.com/hsakurada/items/6979b82afbcfe0294571

複数ファイルを個別にzip圧縮（パスワード付き）するバッチファイル
https://qiita.com/irohamaru/items/9a59a7105f5d56804a82

7Zipの別名保存のコマンドライン
https://qiita.com/h_pon_heapon/items/d7f7d38d11bfe15eebf8

C#で7zipの圧縮・解凍をする（SevenZipSharp）
https://qiita.com/koshian2/items/f648892f37cddaab7093

[VBS][7zip]コマンドラインからドライブごと圧縮したしたZipファイルを解凍するとき特定のフォルダ、拡張子を除外する
https://qiita.com/Q11Q/items/1fbaed03a5384c78a97c

[VBS][7zip]コマンドラインからドライブを圧縮するとき特定のフォルダを圧縮から除外する
https://qiita.com/Q11Q/items/aadd2c26606072ab37c1


Windows エクスプローラー、7-Zip でファイル名を UTF-8 エンコードした ZIP ファイルを文字化けせずに解凍するためには ZIP ファイル内で EFS が有効にされている必要がある？
https://qiita.com/Teloo/items/9cfd3b39a2a5cebf61b8

一度はちゃんと確認しておきたいデータ圧縮形式
https://qiita.com/1coin178/items/caacb46d630c4c98ce0f

今更7-zipのコマンドラインのVBScript
https://qiita.com/Q11Q/items/0d0d41fb858407a74212

VPS上のFileMaker ServerのバックアップをDropbox経由で取得する
https://qiita.com/nagaikao/items/84bf4f2a6377a54fad67

# Mac
7z ファイルを解凍する 【mac】

https://qiita.com/ntkgcj/items/afe4863c40680d72a755

# linux
Linuxで7zipを使うときのメモ

https://qiita.com/robozushi10/items/b334357244739d47f39e

7zipで分割圧縮されたファイルを元に戻す(LINUX)

https://qiita.com/daikumatan/items/0b24f066296d2e963679


# 文書履歴(document history)
ver. 0.01 初稿 　20181024
ver. 0.02 ありがとう追記　20230513
## 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

####  Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
コマンド操作で Google 翻訳できる translate-shell の任意の場所へのインストール


Makefile をただ書き換えただけ.

## 環境

- Ubuntu 16.04

## スクリプト

PREFIX で好きな場所を指定.

```bash
#!/bin/bash -e

TARGET=translate-shell
REPO=https://github.com/soimort/${TARGET}.git
PREFIX="${HOME}/opt/${TARGET}"

! [ -d ${PREFIX} ] && git clone ${REPO} ${PREFIX}

cd ${PREFIX}

sed -i "s/\(^PREFIX \+= *\).*/\1$(echo ${PREFIX} | sed "s/\//\\\\\//g")/" Makefile

make
make install
```