OmniAICreator/Qiita-1.07M huggingface dataset:
GitHubの草の生やし方

# GitHubのContributionに草が生えない場合の解決方法

GitHubを登録し、最初にGitHub Desktopでコミット・プッシュをしていた時は、contributionに草（芝）が生えていました。
しかし、SourceTreeをインストールしGitHubに連携してから、GitHub Desktopでプッシュをしても草が生えなくなってしまいました、、進捗が目に見えなくて悲しい、、、
<img width="868" alt="GitHub草問題.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604769/ef763685-c71f-f1e1-7a82-ddad77cdc3d5.png">
「GitHub 草生えない」でググって試してみても草が生えない:cry:

## 草が生えない原因

**結論：**
**GitHubに登録しているメールアドレスと、ローカルのメールアドレスが違ったため、草が生えていなかったみたいです。**
他にも要因はあるみたいですが、ほとんどの場合はメールアドレスを連携させることで解決できるっぽい！

今まで出来てたのに急に出来なくなったのはSourceTreeと連携した時に、何らかの不具合が生じてしまった、、？

## 解決方法
GitHubに登録しているメールアドレスと、ローカルのGitのメールアドレスを一致させます。

**・GitHubのメールアドレスの確認方法**
右上のアイコン->Settings->Emails->Primaryと表示されているメールアドレス
<img width="1173" alt="GitHub草問題　２.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604769/c62b975c-686d-0708-f7a1-44d305f7ea43.png">

**・ローカルのメールアドレスの確認方法**
コマンドで

```ruby:command
$ git config user.email 
```
この時表示されるアドレスがローカルのGitのアドレスです。
何も表示されない場合は設定されていません。

**・ローカルのメールアドレスの設定、変更方法**

```ruby:command
$ git config user.email [GitHubのメールアドレス]
```

これで登録完了！


**e.g.)メールアドレスが"example@gmail.com"の場合**

```ruby:command
$ git config user.email example@gmail.com
```


これでメールアドレスが一致し、Contributionが反映され、草が生えるようになりました！草いっぱい生やしたい！みんなも緑でいっぱいにしよう！！:clap_tone1:
Google Home で家族みんなで同じ情報にアクセスできるようにする

もはやプログラミングとは何の関係もないけど、同じ設定を探している人がいるかもしれないのでメモ。

# 理解メモ
* 「家」の中に複数の「部屋」を持つことができる。
* 「部屋」の中に複数の「デバイス」を持つことができる。
* 「デバイス」に複数の「アカウント」をリンクすることができる。
* 初期設定？では「デバイス」の Voice Match が有効になっていて、話しかけた声に対応する「アカウント」の情報しか表示されない。

# 準備
自分のアカウントの情報を全部見られてもいい場合はその「アカウント」を使って「デバイス」にリンクさせてもいいけど、そうでない場合はデータ共有用のアカウントを 1 つ作った方がいいと思う。表示する「カレンダー」は選択できるみたいなので、当初は個人「アカウント」内に共用の「カレンダー」を追加して表示すればいいかと思ったけど、その「アカウント」のメイン「カレンダー」は表示対象から外せなかった。不便。

# 「デバイス」と「アカウント」のリンク
初期設定を共用アカウントを使ってやれば自動的にそれがリンクされるはず。そうでない場合はもやはどうやったのか覚えていないが、とりあえず共用「アカウント」と「デバイス」をリンクさせる。

# 「デバイス」に「アカウント」の情報を誰でも表示できるようにする
1. Google Home アプリ
2. 設定 -> 部屋、グループ、デバイス
3. 対象の「デバイス」を選択
4. 詳細 -> 認識とカスタマイズをタップ
    * アカウントに基づく情報の許可 -> on
    * アカウントに基づく情報の表示 -> 常に自動的に表示する
    * Voice Match -> 削除？ (記憶が曖昧)

# その他
数か月後には項目とか古新聞になってるだろう。複数アカウントがデバイスにリンクされている場合はどうなるんだろうね。
Spring Bootでファイルアップロードした際ファイルサイズの最大値を超えたときにエラー処理を行う

Spring Bootでファイルをアップロードする際にファイルサイズの最大値を設定することができる。
設定するのはapplication.propertesの以下のパラメータ

```
spring.servlet.multipart.enabled=true
# ファイル1つの最大サイズ
spring.servlet.multipart.max-file-size=10MB
# 複数ファイル全体の最大サイズ
spring.servlet.multipart.max-request-size=50MB
```

ここで設定した以上のサイズのファイルをアップロードしようとするとエラーが表示されるが、このエラー処理をカスタマイズしたいときの例を以下に記述する。

1.HandlerExceptionResolverの子クラス作成
プロジェクトの任意の箇所に以下のクラスを作成する。これによりファイルサイズ異常の例外を取得することができる。

```
@Component
public class ExceptionResolver implements HandlerExceptionResolver {
  @Override
  public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) {
    ModelAndView modelAndView = new ModelAndView();
    if (e instanceof MultipartException && e.getCause() instanceof IllegalStateException && e.getCause().getCause() instanceof FileSizeLimitExceededException) {
      //表示したいメッセージなど
      modelAndView.addObject("message", "ファイルサイズ超過");
    }
    //遷移したい画面を指定
    modelAndView.setViewName("error");
    return modelAndView;
  }
}
```

2.内蔵TomcatのMaxSwallowSizeの設定
1.だけではうまく動作しないため内蔵TomcatのMaxSwallowSizeに-1を設定する。
以下のメソッドはmainメソッドのあるXXXXApplication.java内に記述する。

```
 @Bean
  public TomcatServletWebServerFactory containerFactory() {
    return new TomcatServletWebServerFactory() {
      protected void customizeConnector(Connector connector) {
        super.customizeConnector(connector);
        if (connector.getProtocolHandler() instanceof AbstractHttp11Protocol) {

          ((AbstractHttp11Protocol<?>) connector.getProtocolHandler()).setMaxSwallowSize(-1);
        }
      }
    };
  }
```
【Rails】has_secure_password

#has_secure_password

```user.rb
class User < ApplicationRecord
  .
  .
  .
  has_secure_password
end
```
上記のようにユーザモデルに定義すると機能します。

#機能
Railsのメソッド、下記のような機能を持っています。

・セキュアなハッシュ化されたパスワードをpassword_digestカラムに保存する。
・passwordとpassword_confirmationという２つの仮想的な属性を追加する。
・`validations: true`を記載することで存在性と値が一致するかどうかのバリデーションが追加される。
（「password」は存在しているか、「password」と「password_confirmation」は同じか）
・authenticateメソッドが使えるようになる。
（引数の文字列がパスワードと一致するとUserオブジェクトを、間違っているとfalseを返すメソッド）

#前提条件
モデル内に`password_digest`という属性が含まれていないと`has_secure_password`の機能は動作しない。
1つ前のマイナーバージョンの最新パッチに更新する

# 要件

- `major.minor.patch` の semantic versioning に従っている
- このスクリプトを適切な頻度で実行する

# スクリプト

```python
#!/usr/bin/env python

import os
import re
import subprocess


def pick_versions(yum_list):
    current = None
    versions = {}
    for line in yum_list.splitlines():
        if line == 'Installed Packages':
            is_current = True
            continue
        elif line == 'Available Packages':
            is_current = False
            continue

        _, full_version, _ = line.split()
        matched = re.match(r'(\d+)\.(\d+)\.(\d+).*', full_version)
        numeric_version = tuple(int(matched.group(i)) for i in range(1, 4))
        if is_current:
            current = numeric_version
        else:
            versions[numeric_version] = full_version
    return current, versions


def get_target(current, versions):
    newer_versions = set(x[:2] for x in versions.keys() if current[:2] < x[:2])
    if len(newer_versions) > 1:
        target_version = sorted(newer_versions)[0]  # avoid jump
    else:
        target_version = current[:2]

    target_updates = [x for x in versions.keys() if x[:2] == target_version]
    return max(target_updates) if target_updates else None


package_name = 'gitlab-ee'
os.putenv('LANG', 'C')
subprocess.call(['yum', 'check-update'], stdout=subprocess.PIPE)
yum_list = subprocess.check_output(['yum', '--showduplicates', '--quiet', 'list', package_name])
current, versions = pick_versions(yum_list)
target = get_target(current, versions)
if target is not None:
    subprocess.call(['yum', 'update', '-y', package_name + '-' + versions[target]])
```
AwsCodecommit+TortoiseGitをWindows環境でCloneする手順（SSH）


環境：windows10Pro
目的：AWSCodeCommitにSSHキーあげてローカルにtortoisegitでクローンする
前提条件：gitとtortoiseGitインストール済み、AWSアカウント作成済み

## 1.Windowsのローカルでキー作成
コマンドプロンプトにてssh-keygenを起動して、キーを作成する。

```cmd
c:\temp\sshkey>ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\xxxx/.ssh/id_rsa): C:\temp\sshkey\id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\temp\sshkey\id_rsa.
Your public key has been saved in C:\temp\sshkey\id_rsa.pub.
The key fingerprint is:
```
## 2.CodeCommitにキーをアップロード
「AWSコンソール > Iam > 認証情報 > SSHパブリックキーアップロード」にて１で作成したid_rsa.pubを設定し、`SSH キー ID`をメモする。（これがCodeCommitへの認証ユーザーになる）

## 3.puttykeyGenによるputtykey認証キーの作成
puttykeygen起動（tortoiseGitに標準でついてる）

```cmd
C:\Users\xxxx>puttygen
```

`メニュー > importkey`で1で作成したid_rsaを指定
`savePriveteKey`を押して認証キーを保存

## 4.tortoiseGitでリポジトリクローン
tortoiseGitを起動し、クローンを選択したあと、URLと認証キーを設定すればOK

画面設定項目

```
URL:ssh:[CodeCommitのリポジトリURL]
putty認証キー：[3で作成した認証キー]
```

## 補足
接続の度に「login as」とログインユーザーをきかれる場合は、リモート設定のURLに直接ユーザー名「SSHキーID」をつけておくいい（標準のtortoisegitPlinkを使ってSSHしているとき）
ssh://[ユーザーID]@[リポジトリURL]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604715/03f6390d-9d29-4bdc-6af7-d57f1b43f2e3.png)
おうちハック Vol.3 玄関の防犯ライトを夜だけ動作するようにしてみた

[前回の記事](https://qiita.com/zrock/items/d86c0795e0880473ea76)で防犯ライトを作ってみましたが、昼間も点くのがかっこ悪い。そこで、夜だけ動作するようにしてみました。と言っても、照度センサーはない（対応センサーはあるけどBLEなのでイマイチ）ので、アクション側で時間帯で動作するかしないか判定するように変更。

# ポイント

* **BranchTimeCase**コンポーネントを使用する
* そのために、**CreateRecord**でステップ出力に時刻情報をマッピングする

**BranchTimeCase**は**Branch**コンポーネント配下で利用する条件指定コンポーネントですが、時間の範囲を指定して、配下のステップを実行するかどうかを決めることができるんです。なので、今回はこのコンポーネントを使いました。

# CreateRecordで時刻をステップ出力に渡す

まずは**BranchTimeCase**で使えるように**CreateRecord**コンポーネントで時刻情報をステップ出力に渡します。

**CreateRecord**を追加したら、**ステップ出力**をクリックします。で、右ペインのところで「+」をクリックしてフィールドを追加します。**出力フィールド名**は`Timestamp`にしましょう。**型**は`DateTime`。**式**はアクション変数から持ってくるので、`av.Timestamp`とします。
![createrecord1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/25f2a70f-920b-b867-7d98-eb5c98253092.png)

これでOK。これでステップ出力として次のコンポーネントのステップ入力として時刻情報が渡せるようになりました。**Branch**や**Filter**を使うときには**アクション変数ではなくてステップ入力として値を渡さなければなりません**ので注意しましょう。
![createrecord2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/6969f4c0-bbc9-caf4-e26c-c58767041bae.png)

# BranchTimeCaseを使う

さて、今回のポイント、**BranchTimeCase**です。上に書いたとおり、**時刻情報から指定された時間内であれば配下の処理を実行するコンポーネント**です。

まずは**CreateRecord**のあとに**Branch**を追加します。**Branch**をダブルクリックするとその配下に処理が移ります。**BranchCase**が追加されてますので、これを削除し、新たに**BranchTimeCase**を追加します。ちなみに、Branchの配下にはいくつか条件指定コンポーネントを配置できますが、左から順に評価され、評価されたレコードは次の条件指定には渡されません。プログラム的に言うと、`if-else`構文に近いのですが、ステップ入力はレコード（配列）なので、それぞれのレコードが`if-else`で評価されていくと考えるといいと思います。ある条件で合致して処理されたレコードが削除された形で次の条件に進むって感じですかね。
![branchtimecase.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/55eb95ea-f215-1b3e-6435-6c4acb929395.png)

さて、**BranchTimeCase**は時間に特化した条件指定コンポーネントです。なので、まずは評価するフィールドとして**Target**を指定します。これには**CreateRecord**で作成した`Timestamp`を指定します。ここでは`av`だとか`sin`だとかのプレフィックスは必要ありません。単にステップ入力のフィールド名を指定します。また、この時刻はローカルタイムとして評価されますので、特に変換等は気にしなくて良いです。HubKitの動作OSのタイムゾーンだけは正しく指定しておきましょう。

**Start time**と**End time**には、配下の処理を実行したい時間帯の、それぞれ開始時刻、終了時刻を指定します。ここでは、**Start time**に`16:00`、**End time**に`8:00`を指定しました。ここで、一つポイントです。そうです、**Start time**よりも**End time**の方が早い時間になってます。通常この手の指定は、開始が終了よりも早ければなりません。もしくは、`0:00`をまたぐことはできないのです。つまり、`16:00～32:00`と指定するか、`0:00～08:00`と`16:00～24:00`の2つの条件を指定しなければならないことも多いです。でも、**BranchTimeCase**はそれをいい感じで処理してくれます。直感的ですねー。
![Branchtimecase2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/77e962f8-27b0-d157-e5f5-1be1f1f6a81e.png)

条件指定はここまでです。あとは、**BranchTimeCase**をダブルクリックして、中に[前回](https://qiita.com/zrock/items/d86c0795e0880473ea76)指定した**GeneralLight**を配置します。今回は玄関に行かなくても分かりやすいように**LineNotify**で自分にもテスト用に通知するようにしてみました。
![light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/cb656524-cc08-91ad-13cc-62ea3da35290.png)

以上です。これで、暗い時間帯だけライトが点くようになりました。
エラー文First argument in form cannot contain nil or be emptyの対処法

前提条件は以下の通り。
・投稿にコメント機能をつける。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568461/b7eafbe9-e2ae-78f1-a7a8-de85f7fd0937.png)




問題のコードは以下の通り。

```gym_controller.rb
class GymsController < ApplicationController
    before_action :logged_in_user, only: [:show, :create, :destroy]
    before_action :correct_user,   only: :destroy

  def index

    if logged_in?
        @gym  = current_user.gyms.build
        @feed_items = current_user.feed.paginate(page: params[:page])
      end

  end

  def show
  @gym = Gym.find(params[:id])

  end

  #ログインしたユーザーがジムを投稿する
  def create
   @gym = current_user.gyms.build(gym_params)
   if @gym.save
       flash[:success] = "投稿ありがとうございます!"
       redirect_to request.referrer ||  'gyms_path'
       else
               @feed_items = []
       render 'gyms/index'
       end
  end

  def destroy
    @gym.destroy
  flash[:success] = "ジムを削除しました"
  redirect_to request.referrer ||  'gyms_path'
  end

  private

     def gym_params
       params.require(:gym).permit(:name, :content)
     end

     def correct_user
       @gym = current_user.gyms.find_by(id: params[:id])
       redirect_to gyms_path if @gym.nil?
end
end
```


```views/gyms/show.html.erb
<div><%= @gym.name %></div>
<div><%= @gym.content %></div>

<div><%= render partial:'comments/comment_form' %></div>
<p></p>
<div class="col-md-6">
  <% if @comments.any? %>
  <ol class="microposts">
    <%= render @comments %>
  </ol>
  <%= will_paginate @comments %>
  <% end %>
</div>
```



```_comment_form.html.erb
    <%= form_for(@comment) do |f| %>
        <%= hidden_field_tag :gym_id, @gym.id %>
        <%= f.text_field :content, placeholder: "Comment..." %>

        <%= f.submit "コメントする", class: "btn btn-primary btn-sm" %>
    <% end %>

```

こちらの記事の通りに、gym_controller.rb内のshowアクションで@comment = Comment.new記述したところ動きました。
https://teratail.com/questions/16823


```gym_controller.rb
class GymsController < ApplicationController
    before_action :logged_in_user, only: [:show, :create, :destroy]
    before_action :correct_user,   only: :destroy

  def index

    if logged_in?
        @gym  = current_user.gyms.build
        @feed_items = current_user.feed.paginate(page: params[:page])
      end

  end

  def show
  @gym = Gym.find(params[:id])
  @comment = Comment.new
  end

  #ログインしたユーザーがジムを投稿する
  def create
   @gym = current_user.gyms.build(gym_params)
   if @gym.save
       flash[:success] = "投稿ありがとうございます!"
       redirect_to request.referrer ||  'gyms_path'
       else
               @feed_items = []
       render 'gyms/index'
       end
  end

  def destroy
    @gym.destroy
  flash[:success] = "ジムを削除しました"
  redirect_to request.referrer ||  'gyms_path'
  end

  private

     def gym_params
       params.require(:gym).permit(:name, :content)
     end

     def correct_user
       @gym = current_user.gyms.find_by(id: params[:id])
       redirect_to gyms_path if @gym.nil?
end
end
```
スムーススクロールとフェードインで動きがおかしくなった時

#両方使ったら、飛ぶ位置がおかしくなった
ナビバーのメニュークリックで各コンテンツに飛ぶようにしてたのに、各コンテンツをフェードインさせるアニメーションつけたら、違う位置で止まるようになった。
![ezgif-2-2565a44d6d2f.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604796/4d6908c5-4962-81f5-731a-02da09881f4f.gif)
myskillをクリックしているが、一回目では位置がずれてる。

#各コンテンツをdivにいれて修正
修正前

```html
                <section id="profile" class="animated">
                <h2>Profile</h2>
                    <div class="prof">
                        <div class="profile-img">
                            <img src="../img/profile.jpg" alt="プロフィール画像">
                        </div>
                        <h3>Name</h3>
                        <p>松江　渚</p>
                        <h3>Birthday</h3>
                        <p>1998/5/14</p>
                        <h3>Summary</h3>
                        <p>
                            2017年　関西大学に入学、2021年卒業予定。<br>
                            2020年2月からTechAcademyでフロントエンドについて学び始める。<br>
                            現在も勉強中！
                        </p>
                        <h3>Hobby</h3>
                        <p>
                            絵を描くことや、ゲームをすること。<br>
                            雑貨集めなどなど。
                        </p>
                    </div>
                    <!--プロフィールの下にあるSNSなどの画像リンク-->
                    <div class="SNS">
                        <p>SNSもやってます。</p>
                        <a href="https://twitter.com/mnagisa2" class="twitter" target="_blank"><i class="fab fa-twitter fa-3x twitter-ico"></i></a>
                    </div>
            </section>
```

修正後

```html
<div id="profile">
                <section class="animated">
                <h2>Profile</h2>
                    <div class="prof">
                        <div class="profile-img">
                            <img src="../img/profile.jpg" alt="プロフィール画像">
                        </div>
                        <h3>Name</h3>
                        <p>松江　渚</p>
                        <h3>Birthday</h3>
                        <p>1998/5/14</p>
                        <h3>Summary</h3>
                        <p>
                            2017年　関西大学に入学、2021年卒業予定。<br>
                            2020年2月からTechAcademyでフロントエンドについて学び始める。<br>
                            現在も勉強中！
                        </p>
                        <h3>Hobby</h3>
                        <p>
                            絵を描くことや、ゲームをすること。<br>
                            雑貨集めなどなど。
                        </p>
                    </div>
                    <!--プロフィールの下にあるSNSなどの画像リンク-->
                    <div class="SNS">
                        <p>SNSもやってます。</p>
                        <a href="https://twitter.com/mnagisa2" class="twitter" target="_blank"><i class="fab fa-twitter fa-3x twitter-ico"></i></a>
                    </div>
            </section>
            </div>
```
アンカーポイント位置がフェードインする前は確定していないのでずれていた？
位置を確定させるためにdivにアンカーポイントをつけた。
![ezgif-2-00f4e752a312.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604796/7318c56b-e375-2286-90be-72425f3c95bd.gif)

これで解決！
説明が下手すぎるけど自分用だからいいかな:thinking:
Psych::SyntaxErrorの対処法

##エラーの内容

s3に画像をアップさせる関係で、secrets.ymlを書き換えたら、**rails s**で以下のエラーが出た。

```terminal
`parse': (<unknown>): did not find expected key while parsing a block mapping at line 13 column 1 (Psych::SyntaxError)

```

##解決した方法

上記のエラーについて調べたところ、[検索で上位表示される記事](https://www.google.com/search?rlz=1C5CHFA_enJP798JP798&sxsrf=ALeKk01SapwEinUqfxivUVJqjcu1UOnDKw%3A1584509745013&ei=MbNxXrQ8h6egBJielKgB&q=+did+not+find+expected+key+while+parsing+a+block+mapping+at+line+13+column+1+%28Psych%3A%3ASyntaxError%29&oq=+did+not+find+expected+key+while+parsing+a+block+mapping+at+line+13+column+1+%28Psych%3A%3ASyntaxError%29&gs_l=psy-ab.3...4054.4054..4289...0.0..0.74.74.1......1....1..gws-wiz.qmVVJN7F4fA&ved=0ahUKEwj0mPrjpqPoAhWHE4gKHRgPBRUQ4dUDCAs&uact=5)のほとんどで、ymlファイルのインデントがずれていることによるエラーが出ると書いてあった。

そこで、筆者はVScodeを利用していることから、(command)+Pを用いて、.ymlのつくファイルを検索しインデントのずれを探した。

まあ、.ymlファイルをいじったことは記憶に新しかった（s3関連でいじってる）ので、secrets.ymlをまず確認したところ、development、test、productionが全てずれていた。

これを戻し、**rails s**をし直すと、、、

できた！！！！！
GitHub Actions から Azure にデプロイ！

ちょっと目を離してるうちに GitHub Actions の Azure 向けのものが充実してますね！
[GitHub Actions for deploying to Azure](https://github.com/Azure/actions)

ということで試してみましょう。Azure 側に Function App を 1 つ作っておきます。

そして、適当に GitHub に node の Azure Functions を作ってしまいましょう。

以下のコマンドで生成してものを使ってみましょう。

```
> func init
node
> func new
8. Http trigger
Function name: HttpTrigger1
> npm install
```

以下のコマンドで実行して動作確認んをしましょう

```
> func host start
```

ばっちり動いてます。name パラメーターつけて叩くと Hello って付けて返してくれるデフォルトのテンプレートのやつですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/dfec7c89-f674-2a57-4125-db91070eb4f3.png)

GitHub に適当なリポジトリ（ghactionsfunctions という名前で作りました）に push しておきましょう。

```
> git init
> git add --all
> git remote add origin https://github.com/runceel/ghactionsfunctions.git
> git push -u origin master 
```

## 本題

さて、やっと本題です。デプロイしよう！
とりあえず [Starter Action Workflows to deploy to Azure](https://github.com/Azure/actions-workflow-samples) のリポジトリに沢山サンプルがあります。

Node.js の Azure Functions をデプロイするためのサンプルの `windows-node.js-functionapp-on-azure.yml` というのがありますね。

https://github.com/Azure/actions-workflow-samples/blob/master/FunctionApp/windows-node.js-functionapp-on-azure.yml

これをベースにしてみましょう。リポジトリの Actions から新しい Workflow を作って、上のファイルの内容を張り付けて編集していきます。

ます、`env:` のところを自分に合わせて書き換えます。

```yaml
env:
  AZURE_FUNCTIONAPP_NAME: ghactions   # set this to your application's name
  AZURE_FUNCTIONAPP_PACKAGE_PATH: '.'      # set this to the path to your web app project, defaults to the repository root
  NODE_VERSION: '12.x'                     # set this to the node version to use (supports 8.x, 10.x, 12.x)
```

publish-profile として `${{ secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE }}` を使ってるのでリポジトリの Settings に Secrets という項目があるので、ここに `AZURE_FUNCTIONAPP_PUBLISH_PROFILE` という名前の Secret を作ります。Value には Azure ポータルからデプロイ先の Function App を選択して「発行プロファイルの取得」でダウンロードできるファイルの中身を設定しましょう。

取得して…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/54c30090-16cd-adc0-122e-daabd1b342bf.png)

設定！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/bf11e20e-5037-d161-9385-92b827b5ab80.png)

シークレットも作ったら GitHub Actions の YAML ファイルを保存しましょう。そうすると、今回は push の度に走るので、自動的に走り始めます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/f50ab6a5-0800-c516-dd47-7ea6be0c53af.png)

暫く待ってると…、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/84711e7e-6e1a-3e6f-889e-df41e287e606.png)

いい感じの実行結果が出ました。
ポータルを覗いてみると HttpTrigger1 が Function App に出来てるので URL を取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/c14f42b5-601a-21f4-86f4-061dce13d14b.png)

ちゃんと動いてますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/967c324d-f14d-e725-4f67-91749499dd18.png)

あとはスワップとかにも対応させたいけど、AppService を swap させる専用のものはなさそうなので、Azure CLI の GitHub Actions あたりでやる感じかな。

https://github.com/Azure/CLI

後で時間を見てやってみよう。
OutlookVBA関連の参考URL

Outlookでマクロ作成する際に参考にしたサイト

- そもそものoutlookでのマクロの始め方

[https://outlooklab.wordpress.com/2007/02/18/outlook-vba-%E3%83%9E%E3%82%AF%E3%83%AD%E3%80%81%E3%81%AF%E3%81%98%E3%82%81%E3%81%AE%E4%B8%80%E6%AD%A9/](https://outlooklab.wordpress.com/2007/02/18/outlook-vba-%E3%83%9E%E3%82%AF%E3%83%AD%E3%80%81%E3%81%AF%E3%81%98%E3%82%81%E3%81%AE%E4%B8%80%E6%AD%A9/)

- マクロの保存先

[https://zero0nine.com/archives/3163](https://zero0nine.com/archives/3163)

- 特定の件名のメールを受信した際に何かしたい場合

[https://tonari-it.com/outlook-vba-outlookvbaapplicationnewmailex/](https://tonari-it.com/outlook-vba-outlookvbaapplicationnewmailex/)


- 他のアプリケーションを呼び出したい

[https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/shell-function](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/shell-function)

- メール返信を実装したい

[https://www.ka-net.org/blog/?p=4522](https://www.ka-net.org/blog/?p=4522)

- ファイルを添付して送信したい

[https://tsware.jp/tips/tips_256.htm](https://tsware.jp/tips/tips_256.htm)
Xamarin.Android, Xamarin.iOS, Mono バージョン対応表

# 背景

AzurePipelineでXamarinを運用する時には、`~/scripts/select-xamarin-sdk.sh`を用いてMonoのバージョンを指定する必要があります。
しかしXamarinのリリースノートにはXamarin.Android/iOSのバージョンで表記されているのでその対応関係の表があると便利だなあと思ったので作りました。

* AppCenterで選択可能なバージョンを参考に列挙しています
* 手動で作っているので間違っていたら教えて下さい。

# Xamarin.Android
|Xamarin.Android version|Mono.Version|
|---|---|
|10.2|6_8_0|
|10.1|6_6_0|
|10.0|6_4_0|
|9.4|6_0_0|
|9.3|5_18_3|
|9.2|5_18_2|
|9.1|5_16_0|
|9.0|5_12_0|
|8.3.3|5_10_1|

# Xamarin.iOS

|Xamarin.iOS version|Mono.Version|
|---|---|
|13.14|6_8_0|
|13.10|6_6_1|
|13.8|6_6_0|
|13.6|6_4_2|
|13.4|6_4_1|
|13.2|6_4_0|
|12.6|5_18_1|
プロジェクトリーダーというお仕事をスクラムに置き換えてみる

# まえおき
プロジェクトリーダーというお仕事
https://qiita.com/br_branch/items/bbbaba835b45e79efa5b


を読んでよく体系立てて実際のタスクから精神面のフォローまできちんとか書かれている良い記事だなと思いました。
私はスクラムをやっている人間なので、よくいわゆるプロジェクトリーダーをされている方々に「プロジェクトマネージャーとスクラムマスターはどう違うんですか」とか「誰がスクラムでは責任を持つのですか？」と言われます。

だったらこの記事を元にスクラムとの対比を書いてしまえばいいんじゃないと思っています。

あちなみにスクラムの敵はスクラムですから、べ、べ、別に旧態依然のプロジェクトに喧嘩売っているわけではないからねっ！

# 前提条件
スクラムの役割

- スクラムマスター　以下SM
- プロダクトオーナー　以下PO
- チームメンバー　以下メンバー

の３つの役割の話をします。マネージャーやタスクフォースチームやステークホルダーの話はしないです。

#まず結論
スクラムではプロジェクトリーダーという役目は定義されていません。しかし、メンバーの中に歴戦の勇者が少ない場合はそういう人がいても良いと思います。いずれ全員がプロジェクトリーダーの役目が務まるように成長するはずです。

またスクラムの型にハマるとプロジェクトリーダーのやることが他の人に回ってしまったり、やらなくて良いことが現れます。

# スクラムの使命
>「担当するプロジェクトを成功へと導く」

POがその使命を持っています。
それに対してSMがしっかりサポートしていきます。
この二人のコミュニケーションが取れることが大事です。
「プロジェクトの成功」の定義もほぼほぼそのままでいいでしょう。
メンバーはチームの生産性を上げることを使命に。
スクラムマスターはチームの幸福度を上げることを使命に。

# スクラムでの役割
## ゴールの設定を行う
POの役割です。
SMやメンバーにきっちり示しましょう。
ただし、ただしKPIの設定やKGIの設定についてはメンバーで協議しても良いでしょう
また非機能要件や環境の整備についてはメンバーと決めることになります。成果物もきちんとメンバーと約束しましょう。

### タスクの管理と工数の見積もり
　タスクをプロダクトバックログアイテムと定義すれば、これはPOが責任を持ちます。またその優先順位についてもPOが責任を持ちます。タスクの見積もりはメンバーが責任を持ちます。
やりたいことをプロダクトバックログにアイテムとして記述して、それらを常にメンバーと一緒に整理します。整理しながら見積もりを立てます。ストーリーポイント性を導入することが多いでしょう。
　スプリント内のタスクや見積もりについてはメンバーで管理します。

### スケジュールを管理する
タスクを見積もるのはメンバーの役割です。
ではスケジュールを管理するのは誰か？
スプリント中のスケジュールはメンバーで管理します。スプリント内で終わらせられるようにメンバーできちんと調整しましょう。
スプリントに入る前のプロダクトバックログでのスケジュールについては ポイントとベロシティを用いて、SMがきちんと見える化します。それを元にPOがマイルストーンの設定します。
クリティカルパスの把握はそもそもスケジュールを大きく見積もっているので発生しがちですが、小さくスプリントを区切ってリリースをしていくのであまり発生しない印象です。
とはいっても発生しますけどね。

###メンバーの役割の割当
メンバーの役割です。自分たちで組織し自分たちで改編していく。自己組織化の原則です。

### リスク管理
リスク管理についてはSMの責任です。
リスクの探索、リスクを見える化、それに対する解決策の模索、実行。
ただし実行するのはメンバーが実行しますので、SMが常にアンテナを張ってメンバーとコミュニケーションを取りつつ、進めることになります。

### 品質管理
品質はメンバーが責任を持ちます。
POがビジネス価値を踏まえて定義する品質に向かって、メンバーが推し進めることになります。

#### チームビルディング
SMの役割です。
チームがコラボレーションできるように常に全員と話をして信頼される必要があります。


#最後に
こう見るとプロジェクトリーダーの役割をSMやPOに割り当てられることで権限が縮小されています。
更にはリーダーという「個」から、メンバーという「集団」に責任を持ってきています。
これが実は大事なことで、既存のプロジェクトリーダーは単純にやることが多すぎ、広すぎ、細かすぎな感じがしますね。権限を分けてかつ薄めるという目的もありそうです。

これが数ヶ月単位のウォーターフォールだとなかなかまとまらないかもしれないですが、1週間単位のスプリントならなんとなくできると思います。

ぜひ皆さんもレッツスクラム！！
OpenAPIドキュメントを使ってモックサーバーを起動する

OpenAPIを使ってAPI定義を書いている場合、その定義ファイルからモックのサーバーが起動できれば便利ですよね。
実際にAPIサーバーの実装が完了する前からクライアント側の実装を行うことができるので、とても効率が良いです！

調べれば色々と方法が出てきますが、個人的に楽だった方法をまとめておきます。

# Prismがめちゃくちゃ便利
stoplight社のprismというOSSのモックサーバーを使います。
今回は[このDockerイメージ](https://hub.docker.com/r/stoplight/prism)を使うので、Dockerを入れていない場合は先に入れておいてください。

# openapi.yamlの準備
まずはAPI定義を行った `openapi.yaml` を準備してください。
今回は、例としてシンプルな内容の定義ファイルを用意しました。

```openapi.yaml
openapi: 3.0.0
info:
  version: 1.0.0
  title: Swagger Petstore
  license:
    name: MIT
servers:
  - url: http://petstore.swagger.io/
paths:
  /pets:
    get:
      summary: List all pets
      operationId: listPets
      tags:
        - pets
      parameters:
        - name: limit
          in: query
          description: How many items to return at one time (max 100)
          required: false
          schema:
            type: integer
            format: int32
      responses:
        '200':
          description: A paged array of pets
          headers:
            x-next:
              description: A link to the next page of responses
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Pets"
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
components:
  schemas:
    Pet:
      required:
        - id
        - name
      properties:
        id:
          type: integer
          format: int64
          example: 1
        name:
          type: string
          example: "pochi"
        tag:
          type: string
          example: "dog"
    Pets:
      type: array
      items:
        $ref: "#/components/schemas/Pet"
    Error:
      required:
        - code
        - message
      properties:
        code:
          type: integer
          format: int32
        message:
          type: string
```

# モックサーバーの起動
先程用意した `openapi.yaml` と同じディレクトリ内で、下記を実行します。
これだけです！

```sh
docker run --rm -it -p 4010:4010 -v $PWD:/tmp stoplight/prism:3 mock -h 0.0.0.0 /tmp/openapi.yaml
```

実際にAPIを叩いてみます。

```sh
curl 'localhost:4010/pets'
```
レスポンスとして、 `openapi.yaml` の `example` で定義した内容が返ってきます。

```json
[
  {
    "id": 1,
    "name": "pochi",
    "tag": "dog"
  }
]
```

ちなみに、 `-d` オプションを使うと、レスポンスが動的に変わります。

```sh
docker run --rm -it -p 4010:4010 -v $PWD:/tmp stoplight/prism:3 mock -h 0.0.0.0 -d /tmp/openapi.yaml
```

レスポンスはこの様に、毎回変わります。

```json
[
  {
    "id": 8872624476737700000,
    "name": "Duis",
    "tag": "magna in laborum"
  },
  {
    "id": 6385831628202697000,
    "name": "veniam in do fugiat irure",
    "tag": "consequat Ut Excepteur anim tempor"
  },
  {
    "id": 4943733727999074000,
    "name": "dolor dolor",
    "tag": "dolore pariatur ullam"
  },
  {
    "id": 1524702861247148000,
    "name": "irure voluptate dolor mollit ex",
    "tag": "quis"
  }
]
```

本当に簡単ですね！
laravelプロジェクトにfaviconの設定

# faviconの設定
faviconを設定することがあったので備忘録として残します。

## faviconとは
[参考：ファビコンとは](https://digital-marketing.jp/creative/what-is-favicon/)
ファビコンはタブの上に設定してあるアイコン。

## laravelで設定する
laravelプロジェクトで設定することになった。
favicon.icoはデザイナーの方に作っていただいたので、それをpublicの直下に配置する
今回はviews/layout/base.blade.phpのheadに以下のように設定

```php
<link rel="shortcut icon" href="{{ asset('/favicon.ico') }}">
```

faviconはpublicの配下におかないと読み込まないのかな。
その辺がいまいち分かっていない。
あと、assetヘルパーの使い方も。

## 参考
[laravelのサイトでfaviconを設定する方法](https://motomublog.com/archives/621)
[laravel assetヘルパーについて](https://qiita.com/sakuraya/items/411dbc2e1e633928340e)
shader graphメモ

#shader見習いのチュートリアル的なメモ
　shaderを学習し始め、なぜかプログラムを書く前にノードベースでお勉強する

### Toonのやり方
　初めに使用しているバージョンはunity2019.3.0ｆ6です。

使用しているパイプラインはURP

では最初に完成したものを張っておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433236/201a9c7b-ad90-e38c-b464-caf6189632dd.png)

基本的なToonの原理をただノードベースで実行しただけです。

## 処理内容
詳しいことは　https://www.slideshare.net/UnityTechnologiesJapan/unity-75745044　こちらが参考になると思います。

※ここからは箇条書きになっています。

### ライトの方向とメッシュの法線方向を内積する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433236/f2de87fc-63ff-e00a-21c1-142875a1aedf.png)

こうすることで光の当たり具合を取得することができる。

ちなみにライトの取得ですが、初めはunity公式ブログのインクルードファイルから取得する方法を試みたのですがなぜかshadowcodeがないとかなんとかでエラーがでてできなかった。。。
　理由を調べてもわからなかったので他の人がやっていたスクリプトで直接ライトから取得することにしました。
リンク張ろうと見たサイト探してたらすごい人がいたので　https://github.com/simplestargame/VRM-Toon-for-Universal-RP　
見たサイト見つからなかった。。。。

スクリプトの処理張っときます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433236/7997bfdc-a7ae-6f7f-950c-b3b1ef45e472.png)

正直あとはlerpで影の値と通常の値を求めるだけだから説明するとこない。。

完成はこんなの

https://media.giphy.com/media/UrWFWqgY6CRQlhari9/giphy.gif

　一応Githubにソース上げときます。
https://github.com/kobayashiyuuhi/ToonshaderGraph

以上！！
shader言語勉強しなきゃ。
パイプラインいじってる人見ると自分もやりたくなる。。
HDDの完全抹消方法(Linux、Windowsなんでも)

# 0. 概要
パソコンを破棄する際にHDDのデータを全て削除したい時がある。今回はその方法を説明する。
簡単に、UbuntuをLiveで起動してUbuntu上のコマンドで削除する方法である。

# 1. 起動
以下の手順でUbuntu 18.04を起動する。

- 対象となるマシンにDVDを挿入し電源を投入
- F2またはF11などを押しBIOSを起動する
- BIOSでブート優先度をDVDが一番高くなるように設定する
- 再起動

再起動後に以下のような画面が表示される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95636/a3c59c22-6d8b-50b6-4906-50838ee7ee11.png)

次に、このような画面に遷移したら`Ubuntuを試す`をクリックする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95636/8efadbf4-00e6-9fd7-d24f-e85ffeec81ab.png)

Ubuntuが完全に立ち上がれば以下のような画面が表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95636/f3ee8f58-c128-0c48-ab07-447f2000d736.png)


# 2. HDDの削除
`CTRL+ALT+T`でTerminalを起動する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95636/451d5a1e-a4c1-6fb4-c2fc-a50bb2a64435.png)

後はターミナル上で以下を実行

ディスク一覧を得る

``` bash
$ sudo fdisk -l
```

ここでは、抹消したいドライブを`/dev/sda`とする。
以下で`shred`を用いHDDの抹消を開始する。

``` bash
$ sudo shred -uvz /dev/sda
```

デフォルトで同じ領域に3回ランダム値を書き込んで削除するため
復元はかなり難しくなるはずである。

このような形で抹消が始まれば後は放置すればよい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95636/83042f0f-9312-c608-e32c-5683fb037565.png)

もし削除してしまったが、復旧させたい方はこちら（多分できない）

https://qiita.com/harmegiddo/items/d420dca41009fc89cc36
BefungeでFizzBuzz[追記あり]

**(※より短く、密度を濃くしたソースコードを追記しました。)**
二次元指向言語BefungeでFizzBuzzを書いたのでコードを紹介します。
始めて24時間くらいなのでコードは稚拙ですし最適化されていませんが、完成はしたので…

#仕様
- 100までFizzBuzzする(もっといけるけどとりあえずで100)
- 区切りにはLF(改行)を使う

#全体像

```:Befunge
0 > 1+:3%!#v_:5%!#v_v
  ^,+<     "        :
 > 55^     z        .
 |!`+9+9<  z        :
 @  >99*^  i
    ^:,,,, F"Buzz"<   <
    ^      "#       <
           >,,,,:96+%!|
    ^               : <
```
こうして見ると「卍」みたいですね

#ループ処理部分

```:Befunge
0 > 1+
  ^,+<
 > 55^
 |!`+9+9<
 @  >99*^
    
```
いろいろくっついてますが、大事なのはこの抜粋した部分です。
一番最初にポインタが出現する左上でスタックの一番下に```0```を入れ、そのあとfor文に掛けています。```1+```というのは一番下のカウンタに使用するスタックの値を1増やすって意味ですね。
そのあとループ中処理を終わらせたポインタは、どのルートを通っても最終的には```99*^```の左の```>```にたどり着き、その後```9*9+9+9```の式でスタックに```99```を格納します。[^1]そして、その99をスタックの一番下にあるカウンタと比較し、カウンタが```99```以下だったら上、```99```より大きかったら下に行きます。下にはプログラム終了を示す```@```が置いてあるので下に行ったらプログラムが止まり、上に行くと```55+,```という改行を出力するコードを踏んだ後また```1+```に戻ります。
これを繰り返すことで、ループを運用しているわけです。

#選り分け部分
```:Befunge
3%!#v_:5%!#v_v
```
この部分では、FizzBuzzの肝と言っていい選り分けを行っています。
まず```:3%```、カウンタ(正確にはそのコピー)を3で割った余りを算出して、それを```!#v_```で「余りが0なら下へ、でなければ右へ」行かせています。その隣の```:5%!#v_v```も仕組みとしては大差なくて、違う点はどちらの道を辿ろうと下に行っていることくらいです。
ちなみにこの選り分け部分では、値は次の三つのカテゴリに分けられます。

- 「3で割り切れる数」
- 「5で割り切れるが3で割り切れない数」
- 「5でも3でも割り切れない数」

「5でも3でも割り切れる数がないじゃねーか頭バグってんのか」と思ったそこのあなた、大丈夫です。それは「3で割り切れる数」の処理終了後にやりますから。

#出力部分

```:Begunge
+<     "        :
5^     z        .
+9+9<  z        :
>99*^  i
^:,,,, F"Buzz"<   <
^      "#       <
       >,,,,:96+%!|
^               : <
```
基本的には文字列を```"```リテラルで読み込んで```,```で出力しているだけです。
特筆すべき点としては、さっきの選り分けで「3で割り切れる数」として判定された値に```Fizz```を付加したあとの挙動でしょうか。```:96+%```部分でその値が```96+```、つまり15で割れるかどうか判定して```|```で分岐させ、割り切れる場合は丁度近くにある「5で割り切れるが3で割り切れない数」用の```Buzz```付加ラインに送り込んでいます。15で割り切れなかった場合はループ終了地点に放り込んでいます。

#インタプリタで実行してみた
Befungeをオンライン実行できる有能インタプリタ「[Befunge Playground](https://www.bedroomlan.org/tools/befunge-playground/#top)」で実行してみました。![実行結果.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603574/e934310d-59dd-2117-dbc9-c0e31e3cc9f3.gif)

これぞBefunge、って感じでポインタが動いてますね。じっと見ていたくなります。

#総括
もうちょっと面積と文字数減らせたんじゃないの？

#追記
この記事を書いた後にトライしてみたら割と短縮できたので載せておきます。解説はしません。
しめて横幅2文字・行数2行・文字数42文字の短縮に成功しました。

```:Befunge
0>1+:3%!#v_:5%! #v_ v
>^       >"zziF"vv <
^,+55_@v<v      <  |:
>v   !v,,,"Buzz" <  .
^ :, ` ,^< ,       #
 >"c"^,>:96+%!     ^
^    :<       <    <<
```

ちなみに実行結果はこんな感じ
![実行結果2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603574/eac18555-baf0-2eab-32eb-7f3f37e93e78.gif)

#追記2
更に改良しました。

```:Befunge
0>1+:3%!#v_:5%!#v_v
>^> "z" #<"i"v  v<
^,+55_@v<v"F"<   |:
     !v,,,"Buzz"< .
  :, ` ,^< ,     #
> "c"^,>:96+%!   ^
^    :<          <<
```

Fizzの出力方法をちょっと変えるだけで幅が2文字分減りました。

#追記3
まだ改良できました。

```:Befunge
0>1+:3%!#v_:5%!#v_v
>^> "z" #<"i"v    #
^,+55_@vv,"F"<  v_^
v  ,,!#<,,"Buzz"< :
  :, `v,<     >  ^.
>:"c"^>,:96+%!^   >
```
1行減りました。
ループ処理部への移動をちょっと工夫して気合で詰めてます。

#追記4
更なる改良を加えました。

```:Befunge

0>1+:3%!#v_:5%v> v
>^> "z" #<"i"v>| #
^,+55_@vv,"F"< v_^
v,,!#!#,,"Buzz"< :
 ,   `v,<     > ^.
>:"c"^>,:96+%!^  >
```
これ以上は無理
[^1]: 実のところASCIIコード99番の「c」を```"```リテラルで読み込ませた方が文字数が少なく済むことに今気付きました
【Rails】URLテキストにaタグを自動でつける

#はじめに
ユーザーがフォームに投稿したURLテキストに自動でaタグをつけて表示できたらなーーと調べていたら、uriライブラリーのおかげでとても簡単にできたので、備忘録としてまとめます。

#uriライブラリーを読み込む
Rubyの標準ライブラリーとして'uri'というURIを扱う標準ライブラリ-があるので、読み込みます。
https://docs.ruby-lang.org/ja/latest/class/URI.html

```app/helpers/application_helper.rb
require "uri"
```
#ヘルパーメソッドを作成
uriライブラリーを読み込んだapplication_helper.rbでメソッドを作成します。

```app/helpers/application_helper.rb
require "uri"
#追加
def text_url_to_link(text)

  URI.extract(text, ['http', 'https']).uniq.each do |url|
    sub_text = ""
    sub_text << "<a href=" << url << " target=\"_blank\">" << url << "</a>"

    text.gsub!(url, sub_text)
  end

  return text
end
```
1. 
`URI.extract`で、`http`もしくは`https`で始まるtextを `url` として取り出し、`sub_text` という変数に代入

2.
`gsub!`メソッドで textをsub_textに変換

3.
変換したtextを返す

#該当のviewに表示させる

URLテキストにaタグをつけて表示させたい部分に、以下のように先ほど作成したメソッドを使用して、表示させます。

```app/views/sample.html.erb
<%= text_url_to_link(h(該当する変数)).html_safe %>
```
これで、無事にURLテキストに自動でaタグをつけて表示してくれるようになります。
Android StudioでGradle Build Runningがいつまで経っても終わらない件

ある日、突然、Android Studioを立ち上げると、ステータスバーに「Gradle Build Running」と表示され、いつまで経っても終わらなくなりました。
Android Studioをインストールしてもダメ、OSから再インストールしてもダメ。
インターネットを調べるとオフラインキャッシュを有効にするとかいろいろと情報がありましたが、そんな設定はどこにもなく、途方にくれていたのですが･･･。

# 環境
この環境だと間違いなくおきます。

* MacOS Catalina 10.15.3
* Android Studio 3.6.1
* Gradle 5.6.4
* ESET Endpoint Security 6.8.400.0


# 原因
ESET Endpoint Securityのパーソナルファイアウォールでルールが見つからないとブロックされていたのが原因でした。
2020/3/1頃は問題ありませんでしたので、それ以降のアップデートからかも知れません。

# 対処
GradleはTCPの内向きのアクセスを必要としているようです。
ポートは動的に変わります。何度か様子を見てみると40000から60000の間だったので、ファイアウォールのルールを以下のように追加します。

![ScreenShot 2020-03-18 12.56.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334727/139afa08-26a0-71de-e2f3-38aa4f7bcc00.png)
![ScreenShot 2020-03-18 12.56.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334727/97315611-1575-5927-7641-c1b149b9e87f.png)
![ScreenShot 2020-03-18 12.56.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334727/3a3b6832-ae4b-a9a1-29e1-3fb7647a507d.png)
![ScreenShot 2020-03-18 12.57.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334727/c53a9558-136a-064b-21ff-a3107f0e0141.png)

これにはまって3日間、仕事がスタックしてしまいました。
ESETが入っているところは少なくないと思いますので、この記事で一人でも多く人が救われますように。
iOSでデバイスの回転ロック時に、回転情報を取得する

# 背景

デバイスを回転させた時の情報を取得する際、通常であれば、 `NotificationCenter` や `viewWillTransition` を使用すれば簡単に出来るのですが、デバイスの設定で回転をロックしている場合、これらの方法では回転の情報を取得することが出来ませんでした。
そこで、色々と調べた結果、CoreMotionを使用することで回転情報の取得が出来ることが分かったので、メモしておきたいと思います。

# CoreMotionを使用した取得方法
```
import CoreMotion

var motionManager: CMMotionManager!

class ViewController: UIViewController {
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        motionManager = CMMotionManager()
        motionManager.accelerometerUpdateInterval = 0.2
        motionManager.startAccelerometerUpdates( to: OperationQueue() ) { p, _ in
            if p != nil {
                if let acceleration = p?.acceleration {
                    let d =
                        fabs( acceleration.y ) < fabs( acceleration.x )
                            ?   acceleration.x > 0 ? "Right"  :   "Left"
                            :   acceleration.y > 0 ? "Down"   :   "Up"
                    print(d)
                }
            }
        }
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        motionManager.stopAccelerometerUpdates()
    }
}
```

CMMotionManagerを使用し、一定時間毎にAccelerometerを更新することで、ロックしていても無事回転をチェックすることが出来ました。
kintoneで使うメールサービスまとめ

kintoneにはいわゆるメールサーバー機能はありませんので、例えば「顧客マスタに登録されたメールアドレス宛にメールを送信する」という時は外部のメールサービスを利用することになります。
kintoneの開発時によく使うメールサービスをまとめます。

# よく使うメールサービス一覧
(2020-03-17調べ)

* kMailer（ケーメイラー） https://km.kintoneapp.com/ トヨクモさんのサービス
* メールワイズ https://mailwise.cybozu.co.jp/ サイボウズさんのサービス
* SendGrid（センドグリッド）　https://sendgrid.kke.co.jp/

# kMailer

以下Webサイトより引用します。

>kMailerは、kintoneに連携するメール送信システムです。kintoneで管理している顧客に向けて個別／一斉送信が可能です。送信内容には、kintoneからのテキスト引用はもちろん、添付ファイルを含んで送信することも可能です。添付ファイルはダウンロードリンク化され、セキュリティのためにパスワードがかかっています。誰に、いつ、どんなメールを送信したか、受信者がいつ資料をダウンロードしたかをログとして確認も可能です。


## 特徴
kintoneと連携する外部Webサービス。
メールのフォーマット（テンプレート）を作成して、そこにkintoneのレコードを流し込むような感じで使う。
メール開封ログ、ダウンロードログも確認することが可能。
メールサーバーは自前で用意する。

## 感想
ユーザーがメールフォーマットを追加、修正することが前提の場合におすすめ。

---
# メールワイズ
サイボウズさんのサービス。会社の代表メールを設定して、メールワイズにメールを集約し、全員でメールを共有する感じで利用する。
kintoneにメールワイズプラグインが用意されていて、kintoneの顧客台帳のメールアドレスとメールワイズに来たメールを紐付けて、kintoneの関連レコードの様に見ることができる。

## 特徴
kintoneからメールワイズのサービスを直接使う運用は出来ないが、メールワイズプラグインを使ってkintoneアプリにメール送信テンプレートを作成してメールワイズと連携することができる。
この場合もメール送信自体はメールワイズのメール送信画面から行う。

## 感想
ユーザーがメールワイズを使っている場合はプラグインを使ってそのまま利用してもらう。
kintoneの添付ファイルを添付したいという場合は現状のプラグインでは出来ないので、kMailerなどを勧める。

---
# SendGrid
いわゆるメール配信サービス。メール配信データを用意して、APIを利用してSendGridに投げる様なイメージ。
kintoneのユーザーが使うには一般的では無いが、kintoneの開発を行う会社には一般的。

APIリファレンス概要
https://sendgrid.kke.co.jp/docs/API_Reference/index.html

## 特徴
ただのメール配信サービスだけでなく、メールの開封などを専用のダッシュボード画面から確認することができる。

![スクリーンショット 2020-03-18 12.28.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/6b0a7d52-1b98-0cce-90d9-ae209e090c3a.png)


## 感想
APIが用意されているので開発者は利用しやすいと思われる。
開発の自由度は高いが開発工数はそれなりに掛かる。
要件的にkMailerでは満たせない場合に利用する。
Freeプラン有り。
固定IPの場合はProプランを利用する必要有り。
独自ドメインの設定も可能。
　https://sendgrid.kke.co.jp/docs/Tutorials/D_Improve_Deliverability/using_whitelabel.html

## 参考

* SendGrid利用時のエラー処理のベストプラクティス 
https://sendgrid.kke.co.jp/blog/?p=10306
【kaggle初心者向け】Kaggle API を活用する

# kaggle APIとは
kaggle APIを活用すると、データセットダウンロードやsummitなどの操作が、CUIで操作できるようになります。
なお、APIのみでしか出来ない操作はないそうなので、ブラウザで操作したい方はそっとこのページを閉じてください。

# kaggle APUを活用する
では早速kaggle APIの活用方法を記載したいと思うのですが、簡単に前提と本記事のゴールと流れを以下に記載します。
####前提
PC：macOS Catalina
####ゴール
CUI(ターミナル)で
・kagleのデータセットをダウンロードする
・コンペ情報の確認
・submitする
####大まかな流れ
1.kaggle APIトークンの入手
2.kaggle APIのインストール
3.実行

##1.kaggle APIトークンの入手
まずは、Kaggleにアクセスし、サイトの右上自分のアイコンをクリック -> My Account -> APIの項目の"Create New API Token"をクリックしダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269343/829037b6-aa0a-1258-91a5-debfeba691b0.png)

##2.kaggle APIのインストール
ターミナルを立ち上げて

```
pip install kaggle
```

終了後念の為に利用できるかどうかの確認、

```
which kaggle
```

そうしたら先程、ダウンロードしたトークンをkaggleのディレクトリに移動します。

```
mv ~/.Downloads/kaggle.json ~/.kaggle/
```
そして、実行できるように、

```
chmod 600 ~/.kaggle/kaggle.json
```

のコマンドを実行します。
これで、利用できるはずです。
試しに、以下のコマンドを実行してみてください。

```
kaggle competitions list
```

<img width="872" alt="kaggle_competitions.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269343/dc580673-1efd-ebbd-adbd-fdd334068ccb.png">

このような、表示がされれば設定完了です！

##3.実行
では、実際にkaggle APIを活用して色々とやってみましょう。
・データセットのダウンロード

```
kaggle c download -c titanic -p ./Downloads/
```

今回はtitanicコンペのデータセットをダウンロードしていますが、もちろん *titanic* を他のコンペ名にすると他のデータセットもダウンロード可能です。

・submitする

```
kaggle competitions submit -c titanic -f submission.csv -m test
```

*submission.csv* というファイルをsubmitしています。

ちなみに、以下のコマンドを実行することによって、ヘルプを参照することが出来ます。

```
kaggle c -h
```

以上で今回の記事は終わりです。

# 最後に
万が一、誤りや改善したほうがいい点などありましたら、お気軽にコメントやリクエスト頂けると嬉しいです。
PDF-1.7 ページの領域定義

[目次へ](https://qiita.com/RT-EGG/items/70f9107c6300f24b23c4)
<b>ver.1.7仕様書 6th edition、10.10.1に相当します。</b>

PDFは、紙媒体への印刷や、映像や複製原版などの中間媒体へのコンテンツ配置といった印刷前工程の一部といったメディア向けに使うことを考慮しています。特に後者の場合、中間データと最終的なページデータを区別する必要があります。中間ページデータには多くの場合、裁ち落としやプリンターマークなど、最終的なページの境界外に製作時向けのコンテンツが含まれます。PDFではこの製作プロセス中の様々な側面を制御するため、最大5つの境界を定義できます。

###MediaBox
ページが印刷される際の物理サイズを定義します。この領域には、断ち落としや印刷マーク、あるいはその他の目的の拡張領域を含めることがあります。また、出力デバイスの物理的制限のためにマークできない、メディアの端近くの領域も含めることがあります。この境界の外にあるコンテンツは、PDFファイルに影響を与えることなく、安全に破棄されます。

###CropBox
ページのコンテンツが表示あるいは印刷される際に、クリップ（トリミング）される領域を定義します。他の領域とは異なり、CropBoxは物理的なページ構成または使用目的に関して意味を定義せず、単にページのコンテンツにクリッピングを課します。ただし、追加除法（JDFやPJTFジョブチケットで指定された面付け指示など）がない場合、CropBoxはページのコンテンツを出力メディアに配置する方法を決定します。
デフォルト値はMediaBoxと同値です。

###BleedBox (PDF1.3以降)
製造環境で出力する際の、ページのコンテンツをクリップする領域を定義します。これには、切断、折り込み、およびトリミングの物理的制限に対応するために必要な、余分な裁ち落とし領域が含まれることがあります。実際に印刷されるページには、BleedBoxの外側に印刷マークが含まれている場合があります。
デフォルト値はCropBoxと同値です。

###TrimBox (PDF1.3以降)
トリミング後の最終的なページの寸法を明示します。印刷指示、カットマーク、カラーバーなどの製作時コンテンツを考慮するため、MediaBoxより小さくなることがあります。
デフォルト値はCropBoxと同値です。

###AtrBox (PDF1.3以降)
ページ製作者によって明示される、ページ内の意味のあるコンテンツ（潜在的な空白を含む）の領域です。
デフォルト値はCropBoxと同値です。

---
これらの領域はすべて、ユーザー空間単位で表される長方形です。
CropBox、BleedBox、TrimBox、ArtBoxは、通常、MediaBOxの領域を超えてはいけません。数値上で超えている場合は、MediaBoxの交差位置まで縮小します。
vagrantとvirtualBoxのバージョン対応問題

## vagrantとvirtualBoxのバージョン対応問題
vagrantとvirtualBoxのバージョンによって、
`$ vagrant up`
をしてもエラーが出てしまう。

## 解決策
virtualBoxのバージョンを下げてあげる（6.0以下？）。
[VirtualBox公式ダウンロードページ]https://www.virtualbox.org/wiki/Downloads

- Windowsの場合はWindows hostsを選択。
- Macの場合はOS X hostsを選択。

### 結果
`$ vagrant up`
が上手くいく！！
テンプレートのディレクティブ基本

#テンプレートでよく使うディレクティブ

@section
@yield
@component
@slot
@each

#@sectionと@yield
まずはこの２つの解説です。
テンプレートを使う上で欠かせないのが、この２つ。
役割を大雑把に説明すると、
@section ----> 場所を指定
@yield ----> セクションを表示

ファンタジー風にするならば 

@section ----> 呪文を用意
@yield ----> 呪文を唱える 
こんな感じ。


```index.php
@section ('名前'）
こんにちは
@endsection

```

```ko_template.php

@yield('名前')

```

```

こんにちは

```

となります。


#@componentと@slot
まずcomponentとはレイアウトの中のレイアウトのようなものです。
親レイアウトの中からさらに、タイトルだけとかフッターだけとかのレイアウトのことです。

@slotはcomponent内に変数を使ったならば、その変数に代入するためのディレクティブです。


使い方は、componentを作ったら親レイアウト内で

```index.php

@component('フォルダ名.componentを書いたファイルの名前')

　@slot('componentの中で変数を指定したもののクラスやid')
　変数に代入したいこと
　@endslot

@endcomponent

```

とすれば、componentが表示されます。

#@eachについて

@eachは、繰り返したいものをテンプレート化したいときに使います。
まずは@eachを使ってどのように表示したいのかを書いたファイルを作ります。
ここではリスト形式で作ってみます

```use_each.php

<li>
名前：{{$item['name']}}
/メール：{{$item['mail']}}
</li>

```

次に、use_eachで使いたい配列をcontrollerで書いてあげます。

```controller.php

public_function index () {
    
    $data = [
      ['name' => '山田太郎', ''mail' => 'tarou@yamada'],
      ['name' => '山田桜', ''mail' => 'sakura@yamada'],
      ['name' => '山田久美子', ''mail' => 'kumiko@yamada']
    ]


    return view('フォルダ名.index', ['data' => $data]);

}
```

そして親テンプレート内で

```index.php

@section('名前')

 <ul>
 @each('フォルダ名.use_each', controllerで指定したuse_eachで使いたい配列, 第二引数を代入したいuse_each内の変数）
 </ul>


```

とすると、

```

・名前：山田太郎/メール：tarou@yamada
・名前：山田桜/メール：sakura@yamada
・名前：山田久美子/メール：kumiko@yamada


```

と表示されます
インタビュー音声をCloud Speech-to-Text APIに食わせて楽に文字起こしする

# はじめに
音声データを自動的に文字起こしできたらとてもハッピーなはず、とのことでCloud Speech-to-Text APIを使ってみました。本記事はその際の備忘録です。

# 事前準備
Cloud Speech-to-Text APIを使うために以下を準備。

* GCP環境（Speech-to-Text APIを有効化しておく）
* Google Cloud SDK（今回は `gcloud` コマンド経由でAPIコールしたため）

# やってみる
今回変換しようとした音声ファイルは1時間ちょっとあったので、非同期での変換を試みた。
https://cloud.google.com/speech-to-text/docs/async-recognize?hl=ja

Cloud Storageに音声ファイルを置いておき、そのパスを指定する形で以下コマンドでAPIをコールする。

```sh
$ gcloud ml speech recognize-long-running 'gs://<YOUR FILE PATH>' --language-code='ja-JP' --async --project <YOUR PROJECT ID>
Check operation [operations/<OPERATION ID>] for status.
{
  "name": "<OPERATION ID>"
}
```

対応言語は以下のページで確認することができる。今回は日本語なので `ja-JP` を指定。
https://cloud.google.com/speech-to-text/docs/languages

ちなみに、拡張子含め文字列は完全に一致している必要がある模様。拡張子の大文字小文字が違っても `NOT FOUND` エラーとなった。

```sh
ERROR: (gcloud.ml.speech.recognize-long-running) NOT_FOUND: No such object: <YOUR BUCKET PATH>/<YOUR FILE NAME>.mp3
```

また、非可逆圧縮式であるMP3形式などは非推奨で、実際に音声認識させてみたところ、たしかに結果は散々だった。
そのため `MP3` → `FLAC` への変換を行った。

Mac環境だったため、 `homebrew` 経由で `sox` をインストール。

```sh

brew install lame
brew install sox
```

`sox` を利用して `FLAC` 形式への変換を行った。（インプット音声はステレオではなくモノラルである必要があります）

```sh
sox input.mp3 --rate 16k --bits 16 --channels 1 output.flac
```

先程取得したOPERATION IDを使って、プロセスの進捗を確認することができる。

```sh
gcloud ml speech operations describe <OPERATION ID> --project <YOUR PROJECT ID>
```

また、処理が完了するまでポーリングさせることも可能。

```sh
gcloud ml speech operations wait <OPERATION ID> --project <YOUR PROJECT ID>
```

ただし処理が30分を超えるとポーリングは自動的に停止してしまうみたい。

```sh
ERROR: (gcloud.ml.speech.operations.wait) Operation https://speech.googleapis.com/v1/operations/<OPERATION ID> has not finished in 1800 seconds. The operations may still be underway remotely and may still succeed; use gcloud list and describe commands or https://console.developers.google.com/ to check resource state.
```

APIで取得した結果はJSON形式だが、文字起こしの結果だけをシンプルに取得するためにjqで以下のようにこねくり回した。

```sh
cat output.json | jq .response.results[].alternatives[].transcript > text.txt
```

# 参考リンク群
* [クイックスタート: gcloud ツールの使用](https://cloud.google.com/speech-to-text/docs/quickstart-gcloud?hl=ja)
* [Speech-to-Text の基本](https://cloud.google.com/speech-to-text/docs/basics?hl=ja)
* [長い音声ファイルの文字変換](https://cloud.google.com/speech-to-text/docs/async-recognize?hl=ja#speech-async-recognize-gcs-gcloud)
* [ストリーミング入力の音声文字変換](https://cloud.google.com/speech-to-text/docs/streaming-recognize?hl=ja)
Ultra 96 v2 に入門する (Ubuntu)

# 0. 概要
以下のURLからUltra96にPetalinuxをインストールした。
[Ultra 96 v2 に入門する (Ubuntu)](https://qiita.com/harmegiddo/items/bba9b967a86fa716f680)

しかし、Petalinuxだとパッケージ管理ソフトウェア等入っていないし、
一般的なLinuxがよりかは使い勝手が悪い・・・。
そこで、出来ればPynqと同じようにUbuntuで動作させたい！

ソフトウェアはPynqでボードのドライバだとかperipheralのマッピングのみ変更されているような構成が望ましい。
探していたところ、Ultra96 向けのPynq isoがあったのでそのインストールを行ってみる。

![006.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95636/031cb5e9-2afb-5699-510a-f4ea9660a8c6.jpeg)

# 1. Installation
ではUltra96 v2にUbuntuをインストールして動作させていきたいと考える。

まず以下のURLから`Avnet Ultra96-V2: v2.5 PYNQ image`をダウンロードする。
http://www.pynq.io/board.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95636/821d58f1-5147-f7e1-fed1-3c1fc42ff83a.png)

次にファイルを解凍する。解凍したファイルを`dd`コマンドでSDカードに焼く。

``` bash
$ sudo fdisk -l
$ sudo umount <YOUR_DISK>
$ sudo dd if=./ultra96v2_v2.5.img of=/dev/<YOUR_DISK> bs=64M
```

次にSDカードをUltra96本体に挿して
1をOFF、2をONにしてPWRボタンを押して起動する

![ultra96-check-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95636/3d91b97c-5914-26b5-3e98-c382ff852caa.jpeg)

起動後、どのように端末に接続すべきか。
マウスやキーボードをつないでもよいが非常に面倒である。そこでUARTを変換してUSB-Serial通信を行いたい。

以下のUARTをUSBに変換するボードを取り付けUSB接続を行う。

 - (任意) Ultra96 USB-to-JTAG/UART Pod

次に以下のURLから`USB to UART Bridge`をダウンロードしインストールしておく。

https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95636/6659e6dd-2649-7055-e2a2-18e7c3012f30.png)

後はターミナルから以下のように設定し、接続すればシリアルコンソール接続ができる。

 - baud rate = 115200
 - data bits = 8
 - stop bits = 1
 - flow control = none
 - parity = none

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95636/16ca1451-a641-8a6b-e054-78caad959627.png)

sudoのパスワードは`xilinx`である。

# 2. Wifi
`iwconfig`を実行して見るとWi-Fiアダプタが認識されている。
`wlan0`を用いてWi-Fi接続を行う。

まず接続先のSSIDとPWを用いて以下のように設定ファイルを作る。

``` bash
$ sudo wpa_passphrase <SSID> <PW>
```

次に出力した結果を以下に張り付ける

``` bash
sudo vi /etc/wpa_supplicant.conf
```

```bash:wpa_supplicant.conf
network={
        ssid="YOUR_SSID"
        #psk="YOUR_PW"
        psk=YOUR_PW
        key_mgmt=WPA-PSK
}
```

後は再起動を行う

``` bash
$ ps aux | grep wpa
$ kill <psid>
$ sudo /etc/init.d/networking restart
```