OmniAICreator/Qiita-1.07M huggingface dataset:
SSH公開鍵認証ってなんぞやという前にとにかく公開鍵を送りましょう。

SSH とは、Secure SHell の略で、今やTelnetやFTPなど、平文で送受信してしまう方式の代わりの手段として
用いられているデファクトな通信方式です。
その中で、今日は公開鍵認証についてすこしやり方を書いておきます。
まぁ、難しい話はおいておいて、公開鍵認証のやりかただけ説明します。
「公開鍵を送ってください」と言われた時には是非、これだけ抑えておけばオーケーです。

```
$ ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/home/mishihara/.ssh/id_rsa): /home/mishihara/.ssh/id_rsa_hoge　← ここでファイル名入力して名前を変えてもよい。
Enter passphrase (empty for no passphrase):←ここでパスフレーズを入力 
Enter same passphrase again: ←もう一度パスフレーズを入力
Your identification has been saved in /home/mishihara/.ssh/id_rsa_hoge.
Your public key has been saved in /home/mishihara/.ssh/id_rsa_hoge.pub.
The key fingerprint is:
SHA256:HSfyxR5zXCQmTwyYq2sd1yiHWY3bwyjFuY155whgjtM mishihara@localhost.localdomain
The key's randomart image is:
+---[RSA 2048]----+
|           ooo+.o|
|          o. *.o |
|        . oo*++  |
|         ++**+.  |
|        S*o*.%   |
|        + E @ B .|
|         + * o = |
|        o .   . .|
|       .         |
+----[SHA256]-----+
```

これで終了。
あとは *.pub ファイルをメールに貼り付けます、方法は以下の通り。

```
$ cat < ~/.ssh/id_rsa_hoge.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABA*CV3afGd8jGZwcV1D+A3OzpEm80tEKMZ7BOwikJGDdacbHAdJRk4qKMjzGQw0+xD50c4M2QXPe5bLY4/qEoK94pUD00zLa/KKEnMcIwz7TNxxudB8+cSve+TGeO73z8aagZOCkUW/aDt3SXUgOvLDllN/GPLA5M7NRWlGAQR3rIl+CTRiamZjTzjhX3kP5qFndtLuk9mLPfwoIFhIN/l3RQhb8omuRs/i9NToN9tJyQrbhcvyHddEWUNid0tKcVAZxN/qpKoFKrzu5rYSF+fTiYGn1YWNOJFBysT2jDRchjAoQeGBjYrqj9x6mqBHY2lY25R2WunybvmGTg/fBqB+XL mishihara@localhost.localdomain

```
ここで間違えないで頂きたいのは、*.pub ファイルを送るのであって、もう一つのほう
 
```
$ cat < ~/.ssh/id_rsa_hoge
```

を送ってはいけないのです。
これについては、また別の機会に説明します。
先ほどcatコマンドで出力した *.pub ファイルの中身をメール本文にコピーアンドペーストして、送れば終了。

---追記---

そのまま*.pubファイルを添付しても相手側で何とかしてくれるはずなのでそれでもいいです。

--追記完--

あとは、メールを送ってくれ といった人が処理をして、パスフレーズを入力すればログインできるようにしてくれます。
ログインの方法とかも、また次の機会に説明します。
プログラミングを始めて1週間経った今思うこと

#はじめに
[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている[箕牧和廣](https://qiita.com/mimaki_kazuhiro)です。
プログラミング開発コースでインターンを開始して1週間になります。

今回は1週間プログラミングに触れてみての感想を書いていこうと思います。

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

#1. コードが形になる喜び
プログラミングでは自分が書いたコードが一つの文章、画像、デザイン、動作として表示されます。自分のイメージ通りのページを作ることができた時の達成感はすごいです。僕はまだHTML、CSS、Javascriptを少しかじったくらいしか理解していませんが、これらの言語や他の言語をもっと深く学ぶ中で、新たな発見をできるかもしれないと思うと、ワクワクしてたまりません。

#2. 覚えることが多い
プログラミング学習は楽しいですが、覚えることが多いです。まだHTML、CSS、Javascriptをかじったくらいしか勉強していませんが、すでに情報量に圧倒されています。コードの意味や使い方をインプットしつつ、忘れないようにアウトプットすることも必須だなと感じています。わからないことがあれば、すぐに検索する癖をつけていこうと思います。

#3. 圧倒的に知識が足りない
インターンを通じて少しづつプログラミングのことを勉強してきていますが、わからないことが圧倒的に多いです。自分で調べたり、すでに実務に入られている方の話を聞いたりして、インプットの量をもっと増やしていきたいです。
define_methodでDRYなコードを書いた


## 同じような処理をするmethodが複数ある
```ruby

class Weekday
   def sunday
     puts "今日はsundayです"
   end
   def monday
     puts "今日はmondayです"
   end
   def tuesday
     puts "今日はtuesdayです"
   end
   def wednesday
     puts "今日はwednesdayです"
   end
   def thursday
     puts "今日はthursdayです"
   end
   def friday
     puts "今日はfridayです"
   end
   def saturday
     puts "今日はsaturdayです"
   end
end
```

## define_methodで幸せになれた

```ruby

class Weekday
  %i(sunday monday tuesday wednesday thursday friday saturday).each do |day|
    define_method(day) do 
      puts "今日は#{day}です"
    end
  end
end
```

## 感想
- めっちゃ DRYで良い
- メタプログラミングすごい
- (少なくとも僕の)editorでハイライトされないからmethodの記述であると気づきにくい
Unity 2019.2.xのbatchmodeで `Unable to open log file, exiting.`

エラーの原因教えてもらったのでメモ

Unity 2019.2.xになってからビルドがコケるようになった。
下記のような雰囲気のコマンドで `Unable to open log file, exiting.` がでる
しかも `exit code 0` で成功している風味をだすのでかなりハマった。


```shell:shell
/Applications/Unity_2019.2.4f1/Unity.app/Contents/MacOS/Unity \
  -quit \
  -batchmode \
  -projectPath project \
  -executeMethod Hoge.Run_Android \
  -logFile /dev/stdout -buildTarget Android

Unable to open log file, exiting.
```


ReferenceのlogFileをみると

- https://docs.unity3d.com/Manual/CommandLineArguments.html

標準出力に出したい場合は、 `/dev/stdout` を `-` に変えろとのこと

```
Specify where Unity writes the Editor or Windows/Linux/OSX standalone log file.
To output to the console, specify - for the path name.
On Windows, specify - option to ensure output goes to stdout, which is not the console by default.
```
外部プロセス実行時の終了ステータスは`$?.to_i`では取得できない

Rubyで外部プロセスを実行する際には`system`コマンドやバッククオート(\`)を使う。
このプロセスの終了ステータスを得るには組み込み変数`$?`を使うが、終了ステータスを取ろうとして`to_i`をすると意図したものが取れない。正しくは`exitstatus`を呼ぶ必要がある。

例えば

```ruby
system("ls DONT_EXIST")    #=> ls: DONT_EXIST: No such file or directory
pp $?                      #=> #<Process::Status: pid 8905 exit 1>
pp $?.to_i                 #=> 256   （256倍されている）
pp $?.exitstatus           #=> 1  （シェル上で実行した時に得られる値と同じ）
```

`$?`には`Process::Status`クラスのインスタンスが格納されている。
これは終了コードだけではなく、どのシグナルで終了したかといった情報も持っている。

公式ドキュメントによれば、`to_i`は「C言語での終了ステータス表現の整数を返します。」と書いてあり、通常は上位８ビットに終了ステータスが格納され、下位ビットにはシグナルの情報が格納されている。
よって終了ステータスは、`to_i`をしたものを８ビット右シフトする必要がある。

公式ドキュメント
- https://docs.ruby-lang.org/ja/latest/class/Process=3a=3aStatus.html
Unity2019.3bと2019.2のLWRP(URP)でPostProcessingStackを比べてみた

対象Ver.　Unity2019.3.0b1とUnity2019.2.3f1
※2019/9/10時点での調査です。

2019.3のUniversalRenderPipelineでBloomを試そうとするもうまくいかない。

UniversalRPのドキュメントには対応してると書かれていて、
https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@7.0/manual/universalrp-builtin-feature-comparison.html

FAQにも「Some post-processing version 2 (PPv2) features are supported in UniversalRP. 」とあるので
https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@7.0/manual/faq.html

PackageManagerのPostProcessing Ver2.1.7の「View Documentation」から
ドキュメントの通りに試してみても反応なし。
https://docs.unity3d.com/Packages/com.unity.postprocessing@2.1/manual/Quick-start.html


プロジェクト生成時のサンプルシーンでは掛かっていたような…？
と思い上記2Verのサンプルシーンを比較してみると、

![2019_3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495221/713ab285-0b23-dc30-6228-8837c6b0ade6.png)

別のコンポーネントがついてました。

こちらが2019.2の同じGameObjectのインスペクタ表示。

![2019_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495221/b0a6b98e-0270-58ae-fa00-e2dc0242e112.png)

Main Cameraについているコンポーネントにも違いがあり、
![2019_3Cam.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495221/2d62dc2f-1593-ce83-a33b-d1cefb1b00e4.png)
![2019_2Cam.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495221/44895467-84cf-118a-64a9-e772e5d9cfdf.png)
PostProcessLayerがUniversalAdditionalCameraDataに代わっていました。
（上が2019.3、下が2019.2）

2019.3でUniversalRPを使う場合は、そもそもPostProcessingのパッケージを入れる必要がなかったようです。
ちょっと躓いたので、メモ代わりに。
（そもそも2019.3はベータなので、随時変更されるかもしれませんが）
【Rails】Refileで画像をアップロードする方法

#概要
gem`Refile`で画像を扱う方法についてを調べているといろいろできるようになったので、
記録しておこうと思います。

新規投稿
画像の表示

について記述していきます

#refileの導入
##gem導入

```:Gemfile
gem "refile", require: "refile/rails"
gem "refile-mini_magick"
```

Gemfileに追記していきましょう
それぞれのgemの役割は以下の通りです
`refile`： ファイルアップロードgem
`refile-mini_magick`: 画像処理のgem

```:ターミナル
bundle install
```
gemを追加するために`bundle install`しましょう

#モデル

```Ruby:user.rb
attachment :profile_image
```
モデルにrefileを使えるようにする記述をします

#マイグレーションファイル

```:ターミナル
rails generate migration add_profile_image_to_users profile_image_id:text
```

`add_profile_image_to_users`:マイレイションファイル名
`profile_image_id`:refileを使用するカラムの名前　　注）_idが必要です

profile_image_idには画像保存場所（URLみたいなもの）が入るのでデータ型はtextにします
詳しくは下で説明します

```:ターミナル
rails db:migrate
```

忘れずにマイグレーションしましょう
これで準備万端です

#新規投稿

##コントローラー
###new アクション

```Ruby:user_controller
def new
   @user = User.new
end
```

###ストロングパラメータ

```ruby:users_controller
def user_params
  params.require(:user).permit(:profile_image)
end
```

`:profile_image`ここにはidはいりません　ややこしいですね

※　privateの下に追記しましょう

##ビュー
投稿フォームを表示したいビューファイルに以下の記述を追記します

```HTML:new.html.erb
<%= form_for @user do |form| %>
  <%= form.attachment_field :profile_image %>
<% end %>
```

#画像の表示
画像の表示の方法は２種類あります

```HTML:~~.html.erb
<%= image_tag attachment_url(@user, :profile_image, :fill, 300, 300, format: "jpg") %>
<%= attachment_image_tag @user, :profile_image %>
```

`@user`:表示する画像の入ったレコード
`:profile_image`：画像のカラム名

##ちなみに
HTML形式に変換されて表示されます
そのソースコードが以下のようになっています

```HTML:
<img class="attachment user profile_image" src="/attachments/~~~~~/store/?????/profile_image.jpg">
```

`~~~~~`:モデルの保存場所
`?????`:画像の保存場所

`?????`の中身はuser.profile_imageです

###URLを取得する

```
/attachments/~~~~~/store/?????/profile_image.jpg
```

上記のURLを取得する方法は以下の通りです

```
Refile.attachment_url(@user, :profile_image)
```

上の方法で@userに入っている画像（profile_image）のURLを取得できます

###質問、気になるところなどございましたらコメントよろしくお願いします

#おわりに
他にもいろいろできることは多いので、探してみたら面白いと思います

公式ページ
refile https://github.com/refile/refile
||と&&の理解

#追記
こちらの記事には誤った理解による解説が含まれています。詳しくは@scivola様のコメントをお読みください。
#||は「または」と理解しないほうが良い
　ruby初学者が`||` この記号に触れるのは条件式の話の中が多いと思います。そして、これはどちらかが真ならtrueを返す「または」を意味する記号ですと紹介されます。
　これはもちろん正しいのですが応用の利かないとらえ方です。
例えば `ex ||= true`　←こういったイディオムが理解しにくくなります。
#||のより良い理解
　結論からいうと||は「最初に左辺を評価し、偽で合った場合のみ右辺を評価する記号」です。
　左辺が真であれば、そこで終了するので右辺の評価にかかわらずtrueを返す。左辺が偽なら右辺を評価し、結果が真ならtrueを返す。結果的に左右どちらかが真であればtrueを返す記号となります。
　これを踏まえて先ほどのイディオムをみると、まずこれは`ex||(ex=true)`の省略系です(`a+=2`などと同様です。)。
　すなわち、exという変数が定義されてnilでない場合そこで終了し、偽の場合は右辺が評価され、trueがexに代入されるということになります。
　つまり`||=`というイディオムは左辺が未定義または偽なら代入の意味となるため、nilガードなどと呼ばれているのです。

#&&は？
&&も同様に「左辺を評価し、真で合った場合のみ右辺を評価する記号である」と捉えたほうが良いと思います。

~~~ruby
 email = Email.find_by_id(id)
 if email && email.destroy
     #処理
 end
~~~

　このコードで`&&`を使わないとidにあったレコードが見つからない場合nilクラスに対してdestroyが呼び出されエラーとなってしまいます。
　上記のコードではemailがtrueを返す、つまりnilでなく存在する場合のみ右辺の式を実行するためエラーがでなくなります。

#まとめ
基本的なこともしっかり理解するのが大切。
Navigationを使ってDialogFragmentを表示する

`navigation#2.1.0-alpha03` から DialogFragmentがサポートされました。
https://developer.android.com/jetpack/androidx/releases/navigation#2.1.0-alpha03

`<dialog>`としてnavigationのxmlには定義する

```navigation.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tools="http://schemas.android.com/tools" android:id="@+id/top"
            app:startDestination="@id/TopFragment">
    略...
    <dialog
        android:id="@+id/datePickerDialogFragment"
        android:name="com.example.DatePickerDialogFragment"
        android:label="DatePickerDialogFragment" >
    </dialog>
</navigation>
```

ダイアログを表示したい時は通常のnavigationと同様

```
val action = TopFragmentDirections.actionTopFragmentToDatePickerDialogFragment()
findNavController().navigate(action)
```

ダイアログの結果の反映や値の受け渡しにはViewModelを使えば良い。

```kotlin:DatePickerDialogFragment.kt
class DatePickerDialogFragment : DialogFragment(), AnkoLogger {
    lateinit var viewModel: TopViewModel
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return DatePickerDialog(
            requireContext(),
            DatePickerDialog.OnDateSetListener { view, year, month, dayOfMonth ->
                viewModel.onDateSet(year,month,dayOfMonth)
            },
            viewModel.year,
            viewModel.month,
            viewModel.dayOfMonth)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProviders.of(this, ViewModelFactory).get(TopViewModel::class.java)
    }
}

```
hugoのテンプレート内で多言語の文字を使い回す。

#hugoの多言語でMarkdownファイル内で同じ文を書くのが面倒くさい
```html:layouts/shortcodes/my-i18n.html
{{ i18n (.Get "key") }}
```

i18n.en.tomlなどに翻訳を記入し、
呼び出しはこんな感じで。

```md:content/posts/article.en.md
<h2>{{< my-i18n key="test" >}}</h2>
```
シェルスクリプトの実行ディレクトリを取得


```
$(cd $(dirname $0); pwd)
```

## 動作確認

```test.sh
#!/bin/sh

DIR=$(cd $(dirname $0); pwd)
echo ${DIR}
```

```
$ ls -l /home/yuta/test.sh
-rw-rw-rw- 1 yuta yuta 54 Sep 10 16:10 /home/yuta/test.sh

$ sh test.sh
/home/yuta
```
Python if文と集合の演算について（入門Python3）

# 『入門Python3』 考察1

JDLAのE資格2019#2に無事合格したため、いよいよ本格的にMLやらDLやらの実装にチャレンジしてみよう！と思ったのですが、Pythonの知識の壁にぶつかったので「Bill Lubanovic『入門Python3』：オライリージャパン」で学習を始めました。
そこでも壁にぶつかったのでその内容を記載します。
なお、ここに掲載するコードは本文の内容をアレンジをし、Jupyterで動作した結果を記載しています。

# ぶつかった壁:ifと集合の演算
以下のコードを実行した際の結果で、混乱。
（3.5.4 組み合わせと演算に記載）

```python

drinks = {'martini':{'vodka', 'vermouth'},\
        'black russian':{'vodka', 'kahlua'},\
        'white russian':{'cream', 'vodka', 'kahlua'},\
        'manhattan':{'rye', 'vermouth', 'bitters'},\
        'screwdriver':{'orange juice', 'vodka'}\
        }

for name, contents in drinks.items():
    if contents & {'vermouth', 'orange juice'}:
        print(name)
```

結果として以下が表示される。

```
>>martini
manhattan
screwdriver
```

'vermouth'か'orange juice'を使ったカクテルを調べるコードなのですが、「&」演算子は積集合を求めるものにもかかわらず、和集合的な結果が出ている点に混乱。

# 演算子の検証
以下のように細切れにして検証

```
if {'vodka', 'vermouth'} & {'vodka', 'orange juice'}:
    print('true')
>>true
```

```
if {'vodka', 'vermouth'} & {'orange juice'}:
    print('true')
>>
```
上記は何も返答無し

```
if {'vodka', 'vermouth'} | {'orange juice'}:
    print('true')
>>true
```
和集合の演算子は何入れてもtrueが返ってくる模様

# 答えは本書の中に…（Trueとは何か？）
「4.3.1 Trueとは何か」に答えが記載されていた。
チェックする要素がFalseとみなされる値の一覧が記載されている。
集合の場合は空集合set()だとFalseとみなされるとのこと。
逆に言えば空集合でなければTrueと判定するということ。

つまり最初のコードでは

```
for name, contents in drinks.items():
    if contents & {'vermouth', 'orange juice'}:
        print(name)
```
のif文で空集合が返されない場合の辞書のnameをprintしていることになる。

検証で見た通り、共通の要素があれば空集合を返さないので、Trueと判定し
結果として、与えた要素が含まれるitemのnameが返される、との様ですね。

# 最後に
初心者的内容ですが、調べてもいまいちわからなかったので記事にしてみました。
今後も自分の備忘録がてら記載していこうと思います。
（後に見たときに恥ずかしいかもしれませんが。。。）
データの前処理　行の抽出　外れ値の処理　欠損値の処理

### 行を抽出する

https://kazutan.github.io/kazutanR/hands_on_170730/filter.html

```ruby:qiita.rb

install.packages("dplyr")
library(dplyr)
bmi <- filter(originaldata, originaldata$w0_bmi < 100)
```

https://kazutan.github.io/kazutanR/hands_on_170730/filter.html
を参照

データの前処理、データクリーニングは以下のサイトを参照
https://www.marketechlabo.com/r-read-rawdata/

「subset」と「select」
subsetは行を抽出する
selectは列を抽出する

filterはsubsetより複雑なことができるのかな
言語処理100本ノックやってみる　27

#27. 内部リンクの除去
26の処理に加えて，テンプレートの値からMediaWikiの内部リンクマークアップを除去し，テキストに変換せよ（参考: マークアップ早見表）．

```py
import gzip
import json
import re
fname = 'jawiki-country.json.gz'


def extract_UK():
    '''イギリスに関する記事本文を取得

    戻り値：
    イギリスの記事本文
    '''

    with gzip.open(fname, 'rt') as data_file:
        for line in data_file:
            data_json = json.loads(line)
            if data_json['title'] == 'イギリス':
                return data_json['text']

    raise ValueError('イギリスの記事が見つからない')


def remove_markup(target):
    '''マークアップの除去
    強調マークアップと内部リンクを除去する

    引数：
    target -- 対象の文字列
    戻り値：
    マークアップを除去した文字列
    '''

    # 強調マークアップの除去
    pattern = re.compile(r'''
        (\'{2,5})   # 2〜5個の'（マークアップの開始）
        (.*?)       # 任意の1文字以上（対象の文字列）
        (\1)        # 1番目のキャプチャと同じ（マークアップの終了）
        ''', re.MULTILINE + re.VERBOSE)
    target = pattern.sub(r'\2', target)

    # 内部リンクの除去
    pattern = re.compile(r'''
        \[\[        # '[['（マークアップの開始）
        (?:         # キャプチャ対象外のグループ開始
            [^|]*?  # '|'以外の文字が0文字以上、非貪欲
            \|      # '|'
        )??         # グループ終了、このグループが0か1出現、非貪欲
        ([^|]*?)    # キャプチャ対象、'|'以外が0文字以上、非貪欲（表示対象の文字列）
        \]\]        # ']]'（マークアップの終了）
        ''', re.MULTILINE + re.VERBOSE)
    target = pattern.sub(r'\1', target)

    return target


# 基礎情報テンプレートの抽出条件のコンパイル
pattern = re.compile(r'''
    ^\{\{基礎情報.*?$   # '{{基礎情報'で始まる行
    (.*?)       # キャプチャ対象、任意の0文字以上、非貪欲
    ^\}\}$      # '}}'の行
    ''', re.MULTILINE + re.VERBOSE + re.DOTALL)

# 基礎情報テンプレートの抽出
contents = pattern.findall(extract_UK())

# 抽出結果からのフィールド名と値の抽出条件コンパイル
pattern = re.compile(r'''
    ^\|         # '|'で始まる行
    (.+?)       # キャプチャ対象（フィールド名）、任意の1文字以上、非貪欲
    \s*         # 空白文字0文字以上
    =
    \s*         # 空白文字0文字以上
    (.+?)       # キャプチャ対象（値）、任意の1文字以上、非貪欲
    (?:         # キャプチャ対象外のグループ開始
        (?=\n\|)    # 改行+'|'の手前（肯定の先読み）
        | (?=\n$)   # または、改行+終端の手前（肯定の先読み）
    )           # グループ終了
    ''', re.MULTILINE + re.VERBOSE + re.DOTALL)

# フィールド名と値の抽出
fields = pattern.findall(contents[0])

# 辞書にセット
result = {}
keys_test = []      # 確認用の出現順フィールド名リスト
for field in fields:
    result[field[0]] = remove_markup(field[1])
    keys_test.append(field[0])

# 確認のため表示（確認しやすいようにkeys_testを使ってフィールド名の出現順にソート）
for item in sorted(result.items(),
        key=lambda field: keys_test.index(field[0])):
    print(item)
```
言語処理100本ノックやってみる　26

#26. 強調マークアップの除去
25の処理時に，テンプレートの値からMediaWikiの強調マークアップ（弱い強調，強調，強い強調のすべて）を除去してテキストに変換せよ（参考: マークアップ早見表）．

```py
import gzip
import json
import re
fname = 'jawiki-country.json.gz'


def extract_UK():
    '''イギリスに関する記事本文を取得

    戻り値：
    イギリスの記事本文
    '''

    with gzip.open(fname, 'rt') as data_file:
        for line in data_file:
            data_json = json.loads(line)
            if data_json['title'] == 'イギリス':
                return data_json['text']

    raise ValueError('イギリスの記事が見つからない')


def remove_markup(target):
    '''マークアップの除去
    強調マークアップを除去する

    引数：
    target -- 対象の文字列
    戻り値：
    マークアップを除去した文字列
    '''

    # 除去対象の正規表現のコンパイル
    pattern = re.compile(r'''
        \'{2,5} # 2〜5個の'
        ''', re.MULTILINE + re.VERBOSE)

    # 空文字に置換
    return pattern.sub('', target)


# 基礎情報テンプレートの抽出条件のコンパイル
pattern = re.compile(r'''
    ^\{\{基礎情報.*?$   # '{{基礎情報'で始まる行
    (.*?)       # キャプチャ対象、任意の0文字以上、非貪欲
    ^\}\}$      # '}}'の行
    ''', re.MULTILINE + re.VERBOSE + re.DOTALL)

# 基礎情報テンプレートの抽出
contents = pattern.findall(extract_UK())

# 抽出結果からのフィールド名と値の抽出条件コンパイル
pattern = re.compile(r'''
    ^\|         # '|'で始まる行
    (.+?)       # キャプチャ対象（フィールド名）、任意の1文字以上、非貪欲
    \s*         # 空白文字0文字以上
    =
    \s*         # 空白文字0文字以上
    (.+?)       # キャプチャ対象（値）、任意の1文字以上、非貪欲
    (?:         # キャプチャ対象外のグループ開始
        (?=\n\|)    # 改行+'|'の手前（肯定の先読み）
        | (?=\n$)   # または、改行+終端の手前（肯定の先読み）
    )           # グループ終了
    ''', re.MULTILINE + re.VERBOSE + re.DOTALL)

# フィールド名と値の抽出
fields = pattern.findall(contents[0])

# 辞書にセット
result = {}
keys_test = []      # 確認用の出現順フィールド名リスト
for field in fields:
    result[field[0]] = remove_markup(field[1])
    keys_test.append(field[0])

# 確認のため表示（確認しやすいようにkeys_testを使ってフィールド名の出現順にソート）
for item in sorted(result.items(),
        key=lambda field: keys_test.index(field[0])):
    print(item)
```
言語処理100本ノックやってみる　25

#24. ファイル参照の抽出
記事から参照されているメディアファイルをすべて抜き出せ．

```py
import gzip
import json
import re
fname = 'jawiki-country.json.gz'

def extract_UK():
    '''イギリスに関する記事本文を取得

    戻り値：
    イギリスの記事本文
    '''

    with gzip.open(fname, 'rt') as data_file:
        for line in data_file:
            data_json = json.loads(line)
            if data_json['title'] == 'イギリス':
                return data_json['text']

    raise ValueError('イギリスの記事が見つからない')


# 基礎情報テンプレートの抽出条件のコンパイル
pattern = re.compile(r'''
    ^\{\{基礎情報.*?$   # '{{基礎情報'で始まる行
    (.*?)       # キャプチャ対象、任意の0文字以上、非貪欲
    ^\}\}$      # '}}'の行
    ''', re.MULTILINE + re.VERBOSE + re.DOTALL)

# 基礎情報テンプレートの抽出
contents = pattern.findall(extract_UK())

# 抽出結果からのフィールド名と値の抽出条件コンパイル
pattern = re.compile(r'''
    ^\|         # '|'で始まる行
    (.+?)       # キャプチャ対象（フィールド名）、任意の1文字以上、非貪欲
    \s*         # 空白文字0文字以上
    =
    \s*         # 空白文字0文字以上
    (.+?)       # キャプチャ対象（値）、任意の1文字以上、非貪欲
    (?:         # キャプチャ対象外のグループ開始
        (?=\n\|)    # 改行+'|'の手前（肯定の先読み）
        | (?=\n$)   # または、改行+終端の手前（肯定の先読み）
    )           # グループ終了
    ''', re.MULTILINE + re.VERBOSE + re.DOTALL)

# フィールド名と値の抽出
fields = pattern.findall(contents[0])

# 辞書にセット
result = {}
keys_test = []      # 確認用の出現順フィールド名リスト
for field in fields:
    result[field[0]] = field[1]
    keys_test.append(field[0])

# 確認のため表示（確認しやすいようにkeys_testを使ってフィールド名の出現順にソート）
for item in sorted(result.items(),
        key=lambda field: keys_test.index(field[0])):
    print(item)
```
Node.jsからGoogle検索を利用する


# はじめに

この記事では
Node.jsの`googleapis`というモジュールを利用して
Node.jsのjsファイルから、Google検索を行います。

今行っている研究で、Node.js上からGoogleの検索結果を取得する必要があるため、その方法をまとめます。


例えば

`卯月コウ`と検索すると

![スクリーンショット 2019-09-10 15.23.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211482/7fbf05de-e7dd-d48e-6950-3d2495adcf3a.png)

の

「卯月コウ-YouTube」
「卯月コウ-Twiiter」
など各要素の取得をjs上で行うことを目指します。

# 手順１ GoogleAPIに登録する

jsファイル上からGoogleで検索を行うにはCustom Search APIに登録する必要があります。

登録手順は[Custom Search APIを使ってGoogle検索結果を取得する](https://qiita.com/zak_y/items/42ca0f1ea14f7046108c)がわかりやすく

「検索結果を取得するまで」の 「３．Custom Search Engineの取得」まで行ってください。

# 手順2 ライブラリのダウンロード

[GoogleがNode.js用にnpmライブラリを公開している](https://github.com/googleapis/google-api-nodejs-client)ためダウンロードします。

```
npm install googleapis
```

でダウンロードできます。

# 手順3 ライブラリの利用

jsファイルから以下のように利用します。

まず、googleapisから必要なcustomSearchを取り出します。

```js
const {google} = require('googleapis');
const customSearch = google.customsearch("v1");
```

次にキーワード検索を実際に行います。

```js

const {google} = require('googleapis');
const customSearch = google.customsearch("v1");

//非同期処理
async function search_keyword(event) {

    //htmlからキーワードを取ってくる
    let keyword = document.getElementById("search_keyword_input").value;
    if (!keyword) return;

    //非同期処理なので実行終了まで待つ
    let result = await customSearch.cse.list({

        //APIキー
        auth: "APIキー https://qiita.com/zak_y/items/42ca0f1ea14f7046108cの1.APIキーの取得",

        //カスタムエンジン名ID
        cx: "エンジンID https://qiita.com/zak_y/items/42ca0f1ea14f7046108cの3.CSEの取得の検索エンジンID　クリップボードにコピー",

        //検索したいキーワード
        q: keyword
    });

    //結果表示
    console.log(result);
}
```

customSearch.cse.list関数にパラメータを入力するのですが
名前がかなり分かりづらいです。

そもそもGoogleの検索をDevToolsで見ると分かるのですが多くのクラスがg, qなど一文字で表されています。
これは、おそらく大量のレスポンスを返すために可能な限り文字数を減らしており、その結果パラメータもものすごく単純に合わしているんだろうと思います。

`卯月コウ`と、上記のjsファイルのkeywordに入れると
コンソールでは以下のように表示されます。

![スクリーンショット 2019-09-10 15.40.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211482/d9c4e5e1-bb26-ab4d-09bc-248a39734c12.png)


# 参考文献いっぞ！

- [Custom Search APIを使ってGoogle検索結果を取得する](https://qiita.com/zak_y/items/42ca0f1ea14f7046108c)
- [node.jsでgoogle画像検索APIを使って、テスト用の画像を取得してみる](https://qiita.com/fumihiko-hidaka/items/0f2bbb2b419e8d313d7a)
言語処理100本ノックやってみる　24

#24. ファイル参照の抽出
記事から参照されているメディアファイルをすべて抜き出せ．

```python
import gzip
import json
import re
fname = 'jawiki-country.json.gz'


def extract_UK():
    '''イギリスに関する記事本文を取得

    戻り値：
    イギリスの記事本文
    '''

    with gzip.open(fname, 'rt') as data_file:
        for line in data_file:
            data_json = json.loads(line)
            if data_json['title'] == 'イギリス':
                return data_json['text']

    raise ValueError('イギリスの記事が見つからない')


# 正規表現のコンパイル
pattern = re.compile(r'''
    (?:File|ファイル)   # 非キャプチャ、'File'か'ファイル'
    :
    (.+?)   # キャプチャ対象、任意の文字1文字以上、非貪欲
    \|
    ''', re.VERBOSE)

# 抽出
result = pattern.findall(extract_UK())

# 結果表示
for line in result:
    print(line)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/b3a5052c-a5f0-64cd-7081-17a55a093dc3.png)
Railsでクリップボード機能を実装する。

#環境
Rails 5.2.3
Ruby 2.6.3

#1. application.js でclipboard.jsを読み込む。

~~~　
//= require clipboard.min
~~~


＊jqueryを使えるようにしておいてください。

#2. viewにボタンを置く。

~~~erb
  <a class="btn btn-sm btn-clipboard" data-clipboard-target="#text">
   <i class="fa fa-clipboard" aria-hidden="true"></i>
  </a>
~~~

data-clipboard-targetにコピーしたい要素のidなどを指定します。
コピーさせたい文字列を直接指定する場合はdata-clipboard-text=""となります。

#3. javascriptでClipboardのオブジェクトを作成する。

~~~javascript
var clipboard = new Clipboard('.btn-clipboard');
~~~

以上で簡単に実装できました。

#ちなみに.... area_hidden="true"とは
　fontawesomeなどでよく見るので軽く調べてみました。
　trueになっているとスクリーンリーダーによる読み上げをスキップできるそうです。

　障害をもった方を含めすべての人が快適に使えるように「アクセシビリティ」についても勉強していきたいと思っている今日この頃です。
2019-09-10 C++ Builder 10.2 Tokyo + TeeChart > bug > 縦軸ラベルの位置が2,3ピクセルずれる時がある

```txt:動作環境
RAD Studio 10.2 Tokyo Update 3
TeeChart Standard v2016.17.160129 32bit VCL
```

### 概要

- TeeChartの結果をSVGファイル出力 (自作)
- SVGファイルをGitリポジトリにチェックイン
    - 理由: ソースコードのリファクタリング時にエンバグしないことを確認するため

上記の状態でSVGファイルを見ていると、左軸ラベルのテキスト位置のX座標が2,3ずれる時がある。

ビルド後の実行1,2回目: ずれる
ビルド後の実行3回目: ずれない

TeeChartのふるまいかIDEのふるまいか不明であるが、3回目以降は安定するようだ。

2,3ピクセルのずれなので、見た目の影響は小さい（気づく人は気づくが）。

今回のようなエンバグチェックでこの症状が出るのは作業の障害になる。
Reactコンポーネントのoptional propsにデフォルト値を設定する

Reactコンポーネントを作っている際、storybookからpropsなしで呼び出してもエラーにならない方法が欲しかったので調べました。

# Optional Props

typeに`?`をつければoptional propsを作れます。

```tsx
import React from 'react';

export type HogeProps = {
  name?: string;
  age?: number;
};

const Hoge: React.FC<HogeProps> = (props: HogeProps) => {
  return (
    <>
      <div>{props.name}</div>
      <div>{props.age}</div>
    </>
  );
};

export default Hoge;
```

が、コンポーネント内で値をいじろうとすると`undefined`の可能性があるためエラーとなります。
`undefined`チェックを行えば回避可能ですがめんどくさいです。

```tsx
import React from 'react';

export type HogeProps = {
  name?: string;
  age?: number;
};

const Hoge: React.FC<HogeProps> = (props: HogeProps) => {
  const fuga = props.name.substring(0, 2); // Object is possibly 'undefined'.
  const piyo = 100 + props.age; // Object is possibly 'undefined'.
  const fugaValue = props.name === undefined ? 'undefined' : props.name // OK

  return (
    <>
      <div>{fuga}</div>
      <div>{piyo}</div>
    </>
  );
};

export default Hoge;
```

# デフォルト値を設定する

`defaultProps`でデフォルト値を設定できますが、関数内では`(string or number) | undefined`なのでエラーは解決できません。

```tsx
import React from 'react';

... // Object is possibly 'undefined'.

Hoge.defaultProps = {
  name: "hage",
  age: 35
}

export default Hoge;
```

# 解決法

これを解決するには、コンポーネントの呼び出しでは`undefined`を許容しつつ内部では`undefined`が除外された別の`type`として処理するようにします。

```tsx
import React from 'react';

type PropsBase = {
  name?: string;
  age?: number;
};
const defaultValue = {
  name: "hage",
  age: 35
};
const PropsDefault: Required<
  Pick<PropsBase, { [Key in keyof PropsBase]-?: Key }[keyof PropsBase]>
> = defaultValue;
type Props = PropsBase & typeof PropsDefault;

export { defaultValue as hogeDefaultValue };
export type HogeProps = Props;

const Hoge: React.FC<PropsBase> = (_props: PropsBase) => {
  const props = (defaultValue && _props) as Props;
  const fuga = props.name.substring(0, 2); // OK
  const piyo = 100 + props.age; // OK

  return (
    <>
      <div>{fuga}</div>
      <div>{piyo}</div>
    </>
  );
};
Hoge.defaultValue = defaultValue;

export default Hoge;

----------

import React from 'react';
import Hoge from './Hoge'

const FooBar: React.FC = () => {
  return(
    <>
      <Hoge> // OK
      <Hoge name={"fusa"}> // OK
      <Hoge name={"fusa"} age={50}> // OK
    </>
  )
};

export default FooBar;
```

テストの際などにどうなるのか調べてないのでコメントで教えていただければ嬉しいです。

# 参考
[Why don't use optional? in props params when interface work with defaultProps ?](https://github.com/microsoft/TypeScript/issues/30251) 
https://tinyurl.com/y4c33as9 (Credit: BY/bocong#4119 at Reactiflux Discord server)
IEハック

#IEちゃんとは長い付き合いだけど、そろそろ潮時別れたい
さすがに今更IE対応に注力するのは時間の無駄。基本はChrome等で作業して、最終確認時にIEでちらっと見て崩れがあったらIEハックでちょろっと直す感じ。対応バージョンももはや11だけでいいでしょ、みたいなところに落ち着く。本当は完全に縁を切りたいけど、まだ状況によっては「IEだと崩れてます！」って突っ込まれる……。

##IEハック

```css:css
_:-ms-input-placeholder, :root ここに適用したいセレクタ {
  css宣言
}
```

IE10と11に適用されるハック。いろんなハックを調べて見比べて最終的にこれにたどり着く。
何も考えずにこれを使うだけで実務上は問題ない。けど、仕組みを理解しないで使うのもなんともいえない気持ち悪さがあったから、なんでこれでIEハックになるのかも調べてみる。

###最初の「_（アンダースコア）」
理屈の上ではCSSを適用するサイトに影響しないセレクタなら何でもいい。ただ「_（アンダースコア）」や「-（ハイフン）」は予約語やらベンダープレフィックスの仕様上単体で使われることはまずない、ということでこうなってるっぽい。

###「:-ms-input-placeholder」
IE10と11が理解できる疑似クラス。

各ブラウザは理解できないコードに出くわすと、その宣言ブロックかCSS宣言をまるっと無視する。

```css:css
/* IE以外だと、宣言ブロックがまるっと無視される */
_:-ms-input-placeholder {
  color: #000;
}
```

```css:css
/* IE以外だと、CSS宣言がまるっと無視される */
.test {
  -ms-writing-mode: tb-rl;  /* この行が無視される */
  writing-mode: vertical-rl;
}
```

これを利用して、IEのみに適用する宣言ブロックを作っている。

つまり、最初の「_:-ms-input-placeholder」はIEのみが理解できる、サイトには存在しないセレクタを表しているっぽい。
あとは「,」でつないで、本命のセレクタを記述すればめでたくIEハックの完成。これ最初に考えたひとはどんな頭してるんだ……天才か。

###「:root」
適用するドキュメントのルート=&lt;html&gt;扱いになる。普通あまり使わない（当たり前といえば当たり前）。じゃあなんで使うのかというと詳細度を上げるためらしい。ぶっちゃけ、IEハックをCSSの最後に付け足すとかであれば、なくても問題なく動作する。ただ、どこに書かれるかははっきりしないから、どこに書いても大丈夫（な可能性が高いだろう）ということで付けてるっぽい。

---

これらの細かいテクニックの積み重ねにより、仕組みを理解する必要もなく手軽にIEハックを実現できてしまう。すごいんだけど、数年後には「そんなこともやってたね～あはは」みたいなテクニックになってしまうのは世知辛いですね。
超初心者が書く！ Project Euler を Python で解いてみた！ Problem4

#Problem4
使われている関数の説明がメインです。

##問題文
>左右どちらから読んでも同じ値になる数を回文数という. 2桁の数の積で表される回文数のうち, 最大のものは 9009 = 91 × 99 である.
>では, 3桁の数の積で表される回文数の最大値を求めよ.

##方針
100×100 ~ 999×999 を全て計算し、n = reverse:n となった n をlistに突っ込む。
　　　　　　　　　　　　　　　　↓
max関数で最大のものを引っ張ってくる。

##解答&解説
```Palindrome.py
def Palindrome_Count (start, stop):
    list = []
    for a in range (start, stop):
        for b in range (start, stop):
            if str (a * b) == str (a * b) [::-1] :
                list.append (a * b)
    return max (list)

print (Palindrome_Count(100, 1000))
```

for文を2つ使って3桁の数をつくっている。
5行目で回文になっているかを判定させている。[::-1]はスライス関数というものである。(後述)
あとは、回文になっているのをlistに突っ込んで、最大の回文を出力している。

###スライス関数
スライス関数を使うとリストや文字列から一部分を選択して値を取得することが可能！
例えば、

```test.py
list = [0,1,2,3,4,5,6,7,8,9]
print(list[1:7])
print(list[5:9])
str = "0123456789"
print(str[1:7])
print(str[5:9])
```

```
[1, 2, 3, 4, 5, 6]
[5, 6, 7, 8]
234567
6789
```
のように [ start : stop ] で記述される。（range関数のやつと同じ）
listでも文字列でも考え方は同じである。
また、同じということは [ start : stop : step ] とも書くことができる。

```test2.py
list = [0,1,2,3,4,5,6,7,8,9]
print(list[2:10:2])
print(list[10:5:-1])
str = "0123456789"
print(str[2:10:2])
print(str[10:5:-1])
``` 

```
[2, 4, 6, 8]
[9, 8, 7, 6]
2468
9876
```

そして、次のように値を省略することも可能である。

```test3.py
list = [0,1,2,3,4,5,6,7,8,9]
print(list[4::1])
print(list[:8:2])
print(list[::3])
print(list[5::-1])
print(list[::-1])
str = "0123456789"
print(str[4::1])
print(str[:8:2])
print(str[::3])
print(str[5::-1])
print(str[::-1])
```

```
[4, 5, 6, 7, 8, 9]
[0, 2, 4, 6]
[0, 3, 6, 9]
[5, 4, 3, 2, 1, 0]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
456789
0246
0369
543210
9876543210
```

ちなみに、範囲外の値をスライス関数に入力してもErrorにはならない。
空の値が返ってくるだけだ。

```test4.py
list = [0,1,2,3,4,5,6,7,8,9]
print(list[6:16])
print(list[16:20])
str = "0123456789"
print(str[6:16])
print(str[16:20])
```

```
[6, 7, 8, 9]
[]
6789

```

##最後に
投稿期間は空くものだと思います。（必死の言い訳）
Macでの文字コード変換

# Macでの文字コード変換

あるファイルに保存されたデータを扱っているときに， SHIFT-JISとutf-8が混在していてとても苦労した．
なので，今後のためにも備忘録的な感じで残しておく．

## 文字コードの確認

MacOSでファイルの文字コードを確認するときは

```terminal
$ file --mime hoge.html
hoge.html: text/plain; charset=utf-8
```
もしくは，

```terminal

$ nkf -g hoge.html
BINARY
```

で確認する．

ちなみにMacOSの標準には `nkf`ははいっていないので，　`brew install nkf`等でインストール

## 文字コードの変換
特定のファイルの文字コードを変換するときは

UTF-8の場合

```
$ nkf -g hoge.html
```

SHIFT-JISの場合

```
$ nkf -s hoge.html
```
とすればよい．
`--overwrite`のオプションを付けると特定のファイルは上書き保存される．
デフォルトでは，別で保存される．

カレントディレクトリ以下の文字コードを変換するときは

```
$ nkf -g ./*
```

とすれば，カレントディレクトリ以下ファイルの文字コードはすべてUTF-8となる．

# 参考
- [macでファイルの文字コードを変換する『nkfコマンド』の使い方とオプション一覧](http://kawatama.net/others/mac/1754)
[JavaScript]パスワードと確認用の値を一致かどうか判断する方法 

#はじめに
パスワードとパスワード（確認）を入力して一致しなければエラーが出るようにしたいけど…
[![Image from Gyazo](https://i.gyazo.com/19c8e89aed4feda3c66bf8cc1300ba62.png)](https://gyazo.com/19c8e89aed4feda3c66bf8cc1300ba62)
#解決方法
パスワードフォームの記述の説明
・minlength:7 (7文字以上の入力だよ)
・require:"" (必須入力だよ)
・oninput:"CheckPassword(this)"　（jsファイルの記述から呼び出ししてるよ）

views/customer_info.html.haml
[![Image from Gyazo](https://i.gyazo.com/c6ec5b1f45fd705b15704ba286978e00.png)](https://gyazo.com/c6ec5b1f45fd705b15704ba286978e00)

app/assets/javascript/signup.js
[![Image from Gyazo](https://i.gyazo.com/771500347ce68be5a64105d1a0e75335.png)](https://gyazo.com/771500347ce68be5a64105d1a0e75335)
#参考記事
https://xn--web-s70e101eh74aq95bj6d.xn--vcki1fxh883oon2c.com/%E8%A8%98%E4%BA%8B/40/
Apache Airflow / Cloud Composer メモ

# DAGのシンプルな構成

```python
```

# 公式ドキュメント

- Apache Airflow
    - http://airflow.apache.org
    - バージョン毎の使えたり使えなかったりが多いので使っているバージョンで固定して調べるのが良さそう。
        - https://airflow.readthedocs.io/en/1.10.4/

- Google Cloud Composer
    - Airflowのマネージドサービス
    - https://cloud.google.com/composer/docs/concepts/overview

# ローカル開発環境の作成(docker)

このimageをpullして使うのが便利。

- https://hub.docker.com/r/puckel/docker-airflow/

# ジョブパイプラインのチェック 

python dags/hoge.py でチェックできる。

airflow CLI の list_dags で↑と同じ結果が見れるけど、大元のDAGに結びついていない
subDAGのファイルはチェックされないのでファイル名をfetchして個別に python xxx.py と叩いたほうが網羅できるかも。


- https://airflow.apache.org/tutorial.html#running-the-script

# Slackに通知したい(SlackWebHookOperator, SlackPostAPIOperator)

- SlackWebHookOperator
    - WebHook URL作成、Airflow Conn 作る必要ある。
    - attachments 書けない（1.10.2時点）
    - slack用のパッケージインストールなどは不要。
- SlackPostAPIOperator
    - Airflow Connは不要。slack API tokenを引数にわたす必要ある。
    - slackclient(<2.0)のインストールが必要。
    - attachements書ける。

どちら使うにしてもterraformのようなツールで
Connection もしくは pythonパッケージを追加するプロビジョニングがしたくなるので悩ましい。

# ジョブの成否、retryステータスをhookして通知したい。

BaseOperator に `on_{success|failure|retry}_callback` という引数があり、
通知のメソッドを引数に渡せばよい。

- https://airflow.apache.org/howto/operator/dingding.html

# JSTで日付データを扱いたい（user_defined_filters）

ref.

- https://stackoverflow.com/questions/47112291/how-to-trigger-daily-dag-run-at-midnight-local-time-instead-of-midnight-utc-time/47227399#47227399

# SubDAGから別のDAGの結果と依存関係を作りたい(ExternalTaskSensor)

# CloudComposerのパッケージに依存しないジョブを実行したい（KubernetesPodOperator）

- image_pull_policy の初期値は `IfNotPresent` なので `Always` にする。
未指定だと、imageを最新にしても元のimageを消しても最新にならないので注意。

ref.

- https://cloud.google.com/composer/docs/how-to/using/using-kubernetes-pod-operator
- https://kubernetes.io/docs/concepts/configuration/overview/#container-images

# その他

- schedulerによる実行時の execution_date と Web UIのtriggerから実行するときのそれに入る値にズレがあるのが違和感。
    - スケジューリングの動作についてわかりやかった説明
https://medium.com/programming-soda/590ad9f9fb80
- AirflowSkipException についてもあとで書く。
psコマンドがなくても現在動作しているプロセスをなんとなく把握する方法

`cat /proc/{pid}/status`
を確認すればプロセス名といったステータスが書いてあります。
`status`以外にもファイルのような形で確認できるので`ls`してみてください。
ローカル環境のdockerコンテナ内などでどうぞ
Google Play Consoleの時間指定公開ができなかったのでお問い合わせしてみた

App Storeだけでなく、Google Play Storeでも審査が行われるようになりました。
場合によっては審査に数日かかることもあるらしく、

- 日本時間の土日にストアに上がってしまうとお問い合わせ対応が難しい
- プレスリリースと合わせてリリースしたい

など、問題が着いてきます。

そこで、Google Play Consoleの時間指定公開を使ってみることにしました。
ところがハマってしまい、サポートにお問い合わせする機会があったので共有したいと思います。

## 時間指定公開とは
はじめに注意点を言っておくと、 **日時を設定して、自動的にストアにリリースされる仕組みではありません。**

ストアに公開してほしい日時に、開発者が手動でアプリをリリースする機能です。

## 試したこと

https://support.google.com/googleplay/android-developer/answer/6334282?hl=ja
これに倣って公開する準備をしました。

> 時間指定公開を選択する場合、公開する前にアップデートが処理されている必要があります。処理には最大数時間かかります。

とあったので、リリース管理 > アプリのリリース　にてapkをアップロードするところまでやりました。
`製品版として公開` ボタンはこの時点で押していません。
**ここがハマりどころでした**

そして、手順2の
> 更新したら、画面右下の [アップデートを送信] をクリックします。アップデートは通常どおりに処理されます。この処理には数時間かかる場合があります。

アップデートを送信を押そうとしたのですが、

<img width="1006" alt="スクリーンショット 2019-09-09 12.08.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28622/96f2e645-41a0-41bd-82fa-2cae972ad649.png">

アップデートを送信がグレースケールのまま押せません。

https://twitter.com/androhi/status/1169424125762260992
こういった事例もあったため、審査中なのかな？と思いましたが審査中である表示もない。

周りにも尋ねてみましたが、有力な情報が見当たらず、サポートにお問い合わせしてみました。

## サポートからの返信
数日以内に返ってこればいいな..と思っていたら、まさかの1時間で返信がありました...!!
早い...

回答としては、


1.まずは時間指定公開をonにしてね。
2.製品として公開を押してアプリをアップロードしてね。公開ボタンを押さないとアップロードしたことにならないよ。
3.審査に入るよ。
4.時間指定公開ボタンが使えるようになるよ。

ということで、
**アプリのリリースにて公開ボタンを押さなければいけない** ということでした。

## 再チャレンジ
アプリが公開されないことを祈りつつ、公開ボタンを押しました。うう...怖い...

すると、
<img width="248" alt="スクリーンショット 2019-09-10 14.48.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28622/21918997-307c-a30f-0922-58790a83a315.png">

との表示が...!!
え、大丈夫だよな...?と心配しましたが、どうやら表示だけで実際は公開されていない模様。

すると、時間指定公開ボタンが有効化されていることが確認できました...!!

## まとめ
通常リリースした場合もすぐにはストアに反映されないため、まずリリースボタンを押してから時間指定公開の設定をする必要があったということです。
リリースされたら困る、と思ってしまい、公開ボタンを押す手前で止まってしまっていたため、アプリが更新されたとGooglePlayStoreが気づいてくれていなかったというわけでした。

GooglePlayデベロッパーサポートは本当に対応が早く、今回自分がなかなか仕様を理解できなくて何度もやり取りさせていただきましたが、懇切丁寧に対応してくださりました。
ありがとうございました。
【Android】Dialog Fragmentの作り方

```HogeActivity.java
public class HogeActivity extends AppCompatActivity  {
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Button button = findViewById(R.id.huga_button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              //ダイアログを表示する
              DialogFragment dialog = new DialogFragment();
              // 注意： getFragmentManager()を使用するとエラーになる
              dialog.show(getSupportFragmentManager(),"sample");
            }
        });
  }
}
```

```DialogFragment.java
public class BookReviewDialogFragment extends DialogFragment {
    // ダイアログが生成された時に呼ばれるメソッド
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // ダイアログ生成  AlertDialogのBuilderクラスを指定してインスタンス化します
        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity());
        // タイトル設定
        dialogBuilder.setTitle("ダイアログタイトル");
        // 表示する文章設定
        dialogBuilder.setMessage("値を入力してください");
        // 入力フィールド作成
        final EditText editText = new EditText(getActivity());
        dialogBuilder.setView(editText);
        // OKボタン作成
        dialogBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // editTextから値を取得
                String returnValue = editText.getText().toString();
                // HogeActivityのインスタンスを取得
                HogeActivity hogeActivity = (HogeActivity) getActivity();
                hogeActivity.setTextView(returnValue);
            }
        });
        // NGボタン作成
        dialogBuilder.setNegativeButton("NG", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // 何もしないで閉じる
            }
        });
        // dialogBulderを返す
        return dialogBuilder.create();
    }
}
```

■ ダイアログフラグメントのOKボタンの文字を@stringsから参照する

```
Resources res = getResources();
// OKボタン作成 dialogBuilder.setPositiveButton(res.getString(R.string.ok), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
            }
        });
```
Macでpipを使えるようにする

Seleniumを学ぶため、事前準備としてpipを使えるようにする方法の備忘録。

##環境
- macOS Majove (ver 10.14.6)
- Python 2.7.10

macには上記のpythonが標準搭載されているのでこれを使う。

##easy_installでpipを入れる

以下の場所に標準で``easy_install``が入っているのでこれを使う。

```terminal
/usr/bin/easy_install
```

`easy_install`を使ってインストールする場合は任意の場所で

```:terminal
$ sudo easy_install [package name]
```

の1行で完了。


今回は使わないが、パッケージを無効化させるには`-m`オプションを使用する。



```:terminal
$ sudo easy_install -m [package name]
```


ただし上記はあくまでパスの無効化なので、その後に削除する必要がある。


ということで今回は`pip`を入れるので

```terminal:terminal
$ sudo easy_install pip
Password:************
Searching for pip
Best match: pip 19.2.3
Adding pip 19.2.3 to easy-install.pth file
Installing pip script to /usr/local/bin
Installing pip3.7 script to /usr/local/bin
Installing pip3 script to /usr/local/bin

Using /Users/sf213471118/Library/Python/2.7/lib/python/site-packages
Processing dependencies for pip
Finished processing dependencies for pip
```

しっかり入ったか`pip`を確認

```
$ pip

Usage:   
  pip <command> [options]

Commands:            //省略
General Options:     //省略
```

これで入ったことを確認できた。
不正なマルチバイト文字ですと表示された時の対処法

不正なマルチバイト文字ですと出た時は、文字化けしてしまい読み込めていない可能性が高いです。
### 文字コードを調べる
まずはfileコマンドを用いて文字コードを調べる。

```ruby:qiita.rb
file sample.csv

sample.csv: Non-ISO extended-ASCII text, with very long lines, with CRLF line terminators
```

Non-ISO extended-ASCII textは文字コードがShift-JISであることを示しています。

### icovコマンドで文字コードを変換する

```ruby:qiita.rb
iconv -f sjis -t utf8 sample.csv > utf8sample.csv
```

https://www.atmarkit.co.jp/ait/articles/1609/12/news019.html
[HTML5]pattern属性を使ってお名前欄にバリデーションをかける方法

# はじめに
この新規登録フォームのお名前欄に、漢字・ひらがな・カタカナだけを入力できる正規表現て何だろうか…

[![Image from Gyazo](https://i.gyazo.com/5fe77ffd0691c6cb79cee7e894f816f3.png)](https://gyazo.com/5fe77ffd0691c6cb79cee7e894f816f3)
# 解決方法
それは、”半角英数字ではない”と書くことです。

pattern="[^\x20-\x7E]*"　

意外と簡単でした。
ちなみに、require:"" で必須入力にすることができます。
[![Image from Gyazo](https://i.gyazo.com/b4b9b8b32efbcc61e1fc4aeffafb0b0b.png)](https://gyazo.com/b4b9b8b32efbcc61e1fc4aeffafb0b0b)

#参考記事
https://blog.trippyboy.com/2014/html/html5input-pattern%EF%BD%9C%E3%81%B2%E3%82%89%E3%81%8C%E3%81%AA%E3%83%BB%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A%E3%83%BB%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%82%92pattern%E3%81%A7%E3%81%82%E3%82%89%E3%82%8F/
【AWS】豆知識まとめてみた


#目次

1. [データベースサーバーへのPing](#データベースサーバーへのping)
2. [EC2シャットダウンの罠](#ec2シャットダウンの罠)
3. [アカウント間のAMIの共有](#アカウント間のamiの共有)
4. [EC2のプロンプトをカスタマイズする](#ec2のプロンプトをカスタマイズする)

#データベースサーバーへのPing

AWSでデーターベースサーバーを構築して、「疎通確認するぞ♪」とDBサーバーのホスト名を指定してPingコマンドを叩いたことはないでしょうか？

僕はAWS触りたての頃そうでした(その頃からインフラやり始めたので無知だった)。
セキュリティグループに誤りがあると思ったり、実は起動してないんじゃないかと疑ったりしてました。

なぜか？

- [Amazon RDS DB のインスタンスに接続する問題を解決するには、どうすれば良いですか？](https://aws.amazon.com/jp/premiumsupport/knowledge-center/rds-cannot-connect/)

こちらにあるように、AWSのAuroraを含むRDSでは、pingなどのICMPトラフィックは受け付けないとのこと。
つまりはPingが通りません。

じゃぁどうするか？ 上記リンクに答えはありました。

```bash
telnet <RDS endpoint> <port number>
nc <RDS endpoint> <port number>
```

`telnet`もしくは、`nc`コマンドを利用しましょう。
個人的には`nc`コマンドがなんとなく好きです。

```bash
## 試しにDockerで立ち上げたローカルDBへ疎通確認
$ nc -z localhost 3306
Connection to localhost port 3306 [tcp/mysql] succeeded!
```

- オプションについて
  - z : ポートスキャンオプション[^1]

これで疎通に失敗した場合はセキュリティグループにより許可されてない可能性が高いです。
構築直後の疎通確認には良いと思います。

#EC2シャットダウンの罠

利用していないEC2をシャットダウン。
いつかは使うかもしれないと停止したリソースを削除せずにそのまま放置している方いませんか？
シャットダウン中は料金かからないと思ってませんか？
そのEC2インスタンス、EBSがアタッチされてませんか？

実はEC2が停止中でもアタッチされたEBSは継続して料金が発生します。当たり前ですが。
少額とは言え勿体無いので、利用していないEC2インスタンス・関連するEBSha
削除しましょう！

スナップショットも同様に料金が発生するので、利用しない場合は削除しましょう。

#アカウント間のAMIの共有

AのアカウントからBのアカウントへEC2をコピーして欲しいとの要望があり、[こちら](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/sharingamis-explicit.html)を参考に作業しました。

対象のEC2インスタンスをシャットダウンし、AMIの作成を開始した際に壁に当たりました。
10分で完了すると思っていた作成が1時間半経っても終わらないんですよね。

その日は放置して帰宅。次の日出社して確認すると作成済みになっており、トータルで3時間以上かかっていたようです。

原因としては、EC2のAMI自体はものの数分で完了していたようですが、EC2にアタッチされているEBSのスナップショット作成に時間を要しており、完了ステータスにならなかった模様。

#EC2のプロンプトをカスタマイズする

EC2に限らずできますが、環境ごとに色分けしても良いかもしれませんね。
![Visual_Studio_Code.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275273/43d3c3b8-8c25-be21-8629-e9cb237f1182.png)
この部分


EC2インスタンスにSSHログインして`.bash_profile`に以下を追記。

```bash:.bash_profile
PS1="\[\e[36m\e[40m\][\u@開発サーバーhoge]\[\e[0m\]\\$ "
```

- 解説。大きく3つにパーツ分割！
  - \[\e[36m\e[40m\]
     - 文字色を<font color="#00a1e9">シアン</font>で表示[^2]
     - 背景色を<font color="black">**ブラック**</font>で表示
  - [\u@開発サーバー002]
     - `[` : ただの「 [ 」を表示
     - `\u` : SSHログインしているユーザー名を表示
     - `@開発サーバーhoge]` : ただの文字列を表示
  - \[\e[0m\]\\$ 
     - これ以降の文字を<font color="#aaa">ホワイト</font>で表示

[^1]: REHL7系からポートスキャンオプション[z]は無くなったらしい。macでは一応使えてます。

[^2]: カラーコードや記法は[こちら](http://yanor.net/wiki/?%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88/bash%E3%81%AE%E3%82%AB%E3%83%A9%E3%83%BC%E3%82%B3%E3%83%BC%E3%83%89)を参考にすれば大丈夫だと思います。
【ServiceNow】学習コースが一新されたのでITSMコースを受講

## はじめに
ServiceNowのトレーニング教材は、アカウントを作成してからTrainingタブのトレーニング教材、もしくはYoutubeの動画などに頼るのが現状でしたが、**2019/09/10現在、新しいコースが開講**しました！
![FireShot Capture 127 - Now Learning Dashboard - Now Learning - nowlearning.service-now.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/9bb979ca-0f3e-b851-df76-c7b4ffe66743.png)
なんだかCouseraとかCodeAcademyみたいなUIですね！ServiceNowの学習教材が一つ増えてうれしい限りです。

## アクセス方法
![FireShot Capture 128 - Home - ServiceNow Developers - developer.servicenow.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/ffb3a9e0-01ab-c176-587d-8ec1b03f4802.png)
ログイン後のランディングページにでかでかと画像リンクがあるので、クリックするとログイン可能です。

とりあえず学習プランの**ITSM Simulator** の概要

- ユーザ作成
- コールフォーム作成
- インシデントフォーム設定
- カテゴリ、サブカテゴリ設定
- 状態のチョイスリスト設定
- インシデントから問題作成
- アサインルール設定
- 優先度設定
- インシデントの通知設定
- 解決済みインシデントのクローズ
- サーベイの設定
- レスポンスSLAの設定
- 問題の解決とクローズ
- 変更プロセスユーザの作成
- 変更管理フォームの作成
- リスク状態の設定
- スケジュールの設定
- 緊急の変更要求
- 問題から変更要求の作成
- 変更管理者の合意_通常変更
- 権限の変更
- 変更のレビュー要求
- 標準管理の変更カタログ
- 変更要求のコピー
- セキュリティルールの設定
- 変更通知

まさにITIL準拠でシステムを構築する手段を提供している形ですね。
S3+CloudFrontで静的HTMLを配信する構成での、安全そうな更新手順

## 背景
S3+CloudFrontの構成はよくあるので、デプロイして公開する方法は検索するとたくさんでてきますが、
既に配信した状態から更新をかけようとしたときにどうするんだ？ と少し悩みました。
こんなもんかなぁという更新手順と切り戻し手順を考えたのでメモします。

## 更新手順

### S3での操作
1. 新規バケットを作成
    + バケット名にgitのrevision番号など振っておくとよさそう
    + 旧いバケットは切り戻しのために残しておく
2. 作ったバケットに、新しいモジュール一式を置く

### CloudFrontでの操作
3. Originに、作ったバケットを追加
    + 「Restrict Bucket Access」を「Yes」にするなどして公開設定もする
    + 「Origin Domain Name」は入力欄で保管されるものは選ばず、オブジェクトURLのドメインをコピーした
    + 旧いOriginは切り戻しのために残しておく

4. 更新対象のBehaviorのOriginを、新しいOriginに切り替え
5. CloudFrontのキャッシュを無効化 (Invalidation)

## 切り戻し手順

### CloudFrontでの操作

1. Behaviorを旧Originに切り替える
2. CloudFrontのキャッシュを無効化 (Invalidation)

## 自動化
手順をまとめてやってくれるコマンドラインツールを作っておくと便利そう。

AWS Amplifyを学習し始めたとき、こういった操作を自動的にやってくれることを期待したのですがやってくれないですよね？ たぶん。
[enchant.js]格子(グリッド,grid)を描画する関数[javascript]

オセロや将棋のゲームを作りたい！
と思ったら、まずは格子を用意しなければならない。
簡単に作るために関数(メソッド)化してみた

## 格子を描画するメソッド

左上の座標が(lx, ly)
横のマスの数が x, 縦のマスの数が y
マスの幅が len
である格子(グリッド)を描画するメソッド

```javascript
avascript:main.js

function draw_grid(lx, ly, x, y, len){
    sprite = new Sprite(320, 320);
    surface = new Surface(320, 320);
    sprite.image = surface;
    context = surface.context;
    for(var i=0; i<=x; i++){
        context.beginPath();
        context.moveTo(lx, ly + (len * i));
        context.lineTo(lx + (len * y), ly + (len * i));
        context.closePath();
        context.stroke();
    }
    for(var i=0; i<=y; i++){
        context.beginPath();
        context.moveTo(lx + (len * i), ly);
        context.lineTo(lx + (len * i), ly + (len * x));
        context.closePath();
        context.stroke();
    }
}

```

## ブラウザでの見た目

因みに、

```javascript:main.js
draw_grid(10, 30, 4, 3, 30);
```

と呼び出すと、

![bandicam 2019-09-10 14-06-53-015.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240459/47e52f0e-0959-4313-300e-838ea317030c.jpeg)

このような表示になる
今日のPowerShell ERROR 読み取り中にログが削除された可能性があ ります。インデックス 5062 が境界を越えています。

ログオフ時間をコマンドで取る

https://qiita.com/aoi_erimiya/items/e8fdeb0e0d13641718a4



```shell-session:Powershell
> Get-EventLog system -After 2019-07-01 | Where-Object {$_.EventID -eq 7002} | Sort-Object Index | Se
lect-Object TimeGenerated
Get-EventLog : 次のエラーのため、ログ "system" の読み取りを完了できませんでした。読み取り中にログが削除された可能性があ
ります。インデックス 5062 が境界を越えています。
発生場所 行:1 文字:1
+ Get-EventLog system -After 2019-07-01 | Where-Object {$_.EventID -eq  ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ReadError: (:) [Get-EventLog], ArgumentException
    + FullyQualifiedErrorId : LogReadError,Microsoft.PowerShell.Commands.GetEventLogCommand
    + 
```

# 参考資料

【 Get-EventLog 】コマンドレット――Windowsのイベントログを取得する
https://www.atmarkit.co.jp/ait/articles/1608/23/news023.html

Get-EventLog
https://forsenergy.com/ja-jp/windowspowershellhelp/html/a4372a60-b7d9-4b1c-a268-aa5240300141.htm

PowerShellでイベント・ログの内容を参照する
https://www.atmarkit.co.jp/fwin2k/win2ktips/1036psevent2/psevent2.html

## 参考資料　on Qiita 
PowerShellでWindowsイベントログを取得する
https://qiita.com/gtom7156/items/f2e29d2abadb0134560f

Windows のイベント ログに特定のイベントが記録されたら LINE WORKS の Bot で通知
https://qiita.com/iwaohig/items/8853ed4433f6653396c2

WindowsPowerShell入門 - 日付毎に最後のイベントログを表示する
https://qiita.com/myokoym/items/cd3242b8a791b030b327

# 文書履歴(document history)
ver. 0.01 初稿 20190910
ver. 0.04 URL追記　20230228

### 最後までおよみいただきありがとうございました。

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

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

Please press the like icon 💚　and follow me for your happy life.
chef vault : how it works

##1) chef vaultとは

- chefが提供しているデータの暗号化の仕組み
- なんのデータ？chefが管理するサーバ毎のデータ。
- どんなユースケース？もっともあり得るのはroot passwordの管理をchefサーバでやる時
- chef vaultとは、という内容はchefのdocを読めばわかるけど、普段そんなに使わないので、どう使うのか、はすぐ忘れるのでまとめる

##2) 準備

- chefサーバと通信できるknifeコンフィグ(ユーザのpemファイルなどの設定を書いたもの)が必要。
- knifeコマンドでvaultを設定する

##3) vaultの作成

```bash

knife vault create rp exp1
#  rpというvault(data bag)を作成、その中に、exp1というvault itemを作成

knife vault update rp exp1 -A "gggg"
# ggggという名前のadminユーザを追加(chef serverのユーザ名)。あとでvaultアイテムを編集する権限を特定のユーザに付与

export EDITOR=vim
knife vault edit rp exp1
{
  "password": "xxx",
  "timestamp": "xxxx"
}
# 適当なjson形式のデータを入れる。この場合は、パスワードと日付を入れる。このデータが暗号化される

knife vault create　rp exp1　'{"password": "xxxxxx", "timestamp": "xxxxx"}'　-S mynodes_password:exp1 -A admin-a, admin-b
# ワンライナーでもできる
# このときSオプションでサーチクエリをセットしておくと便利

knife vault show rp exp1 -Fjson -p all
# 暗号化された情報はadmin権限がある人とrp:exp1が適用されたサーバだけが復号できる


```


##4) サーチクエリ

1.サーバ構築
2.chefで構成管理スタート（このときに、chefのrecipeか何か(roleでもnodeでもなんでもOK)で、例えばattribute`{"mynodes_password" : "exp1"}`をサーバに適用する。）
-> すると、さっきvaultに設定したサーチクエリにこのattributeが一致して、vaultがこのサーチクエリでヒットしたサーバに適用できるようになる



##5)その他

```
knife vault refresh/update
# 仮にデータ（この場合はパスワード）が変更になったらvaultをrefresh

```