OmniAICreator/Qiita-1.07M huggingface dataset:
【Coursera】AI for Medical Diagnosisレビュー

# 目的
Courseraの講座"AI for Medical Diagnosis"のレビュー、サマライズを行います。今後受講される予定の方、受講を迷ってる方の材料になれば嬉しいです。

# 記事の構成
本稿は全体を俯瞰する形をとり、内容の詳細はそれぞれWeek1, Week2, Week3と記事を分けて投稿します。
適宜、受講に応じて追加修正する予定です。

- [Week1（編集中）]()
- [Week2](https://qiita.com/makki_maki04/items/d7f19a9d37090c12110e)
- [Week3](https://qiita.com/makki_maki04/items/adf4dbd20c8e650218f1)

# 全体の感想
Weekごとの記事でも少し述べますが、それらをさらに俯瞰する感想として以下のようにまとめました。

|  評価対象  |  感想  |
| ---- | ---- |
|  学習対象者  |  公式には中級とされているが、CNNと二値分類を少しでも勉強したことあれば初心者教育として有用  |
|  医療的視点  |  医者じゃないので何とも言えないのが正直なところ。おそらく簡単な内容だと思われる。医学的ドメイン知識には結びつかないと感じる。  |
| コーディング | コーディング能力を発展させる内容ではない。しかし、二値分類に関わる具体的計算をsklearnなどで終わらせるだけだった人には良い視点を与えると思う。kerasを使っているが、概念を学ぶ講義なのでpytorchなどに置き換えて考えることは当然出来るので無駄にならない。 |
| 学習しやすいか| 英語は聞き取りやすい。日本語字幕はなし。概念をわかりやすく説明してくれていると思う。|
| 学習時間 | 体感、割とだらけながらも15時間ぐらいでWeek1～3を終えた。もっと早く終わる人もいると思う。トライアル期間で終えられると思う。 |
| 受けてよかった？|　すごく主観的な感想だが、受講してよかった。 | 

以上です。
MotionLayoutの例を試してみる(カスタム属性編)

前回は基本的なモーションをやりました。
[前回の基本的なモーション](https://qiita.com/yuta317/items/7a81ddcda30afc8e45d2)


今回はカスタム属性を試してみようと思います。


# 公式リファレンス
https://developer.android.com/training/constraint-layout/motionlayout/examples?hl=ja

https://developer.android.com/training/constraint-layout/motionlayout/ref?hl=ja

# カスタム属性

今回はビューの移動に伴ってビューの背景色を変更しようと思います。

こんな感じです。

![カスタム属性.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/8075cd7e-ba93-0b1c-e92a-fd11e8db46c6.gif)



``` sample_scene.xml
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto">

    <Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@+id/start"
        motion:duration="1000">
        <OnSwipe
            motion:dragDirection="dragUp"
            motion:touchAnchorId="@id/move_view"
            motion:touchAnchorSide="top" />
    </Transition>

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@id/move_view"
            android:layout_width="64dp"
            android:layout_height="64dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent" >
            <CustomAttribute
                motion:attributeName="BackgroundColor"
                motion:customColorValue="#D81B60" />

        </Constraint>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@id/move_view"
            android:layout_width="64dp"
            android:layout_height="64dp"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent" >
            <CustomAttribute
                motion:attributeName="BackgroundColor"
                motion:customColorValue="#9999FF" />
        </Constraint>
    </ConstraintSet>
</MotionScene>
```


# CustomAttribute

位置やViewの属性とは直接関連しない属性の遷移を指定できるみたいです。
Constraintの中に設定します。

今回は背景色の変更なのでこちらを指定します。
前回同様、モーション シーケンスの開始と終了、両方に設定します。


```
 motion:attributeName="backgroundColor"
```


customColorValueに色を指定します。


```
 motion:customColorValue="#D81B60" 

 motion:customColorValue="#9999FF" 
```

以上です！
アニメーションの動きによって色が変わりました。
他にも設定できるみたいなのですが、色変更ぐらいしかあまり使いどころが見つからないので、今回はここまでです。
GitHub Releases のリリースノートを自動生成する機能と renovate のプルリクを協調させとく

## TL;DR
 - GitHub Releases で、リリースノートを自動生成する機能が付いた
 - renovate は依存ライブラリの更新に必須だ
 - そこで、見やすいリリースノートを生成させる


## renovate 設定

 - GitHub Actions で定期的に実行させる
 - RENOVATE_TOKEN は 適宜　pat で生成すること  
    (残念 GITHUB_TOKEN は使えない)

```..github/workflows/renovate.yml
name: renovate

on:
  schedule:
    - cron: "0 21 * * *"

jobs:
  renovate:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Self-hosted Renovate
        uses: renovatebot/github-action@v31.62.0
        with:
          configurationFile: .github/renovate.json
          token: ${{ secrets.RENOVATE_TOKEN }}
```

- packageRules の matchUpdateTypes を使って 「Semantic Versioning」 のタイプ別にラベルを指定する
    - Update-Major
    - Update-Minor
    - Update-Patch
- [ドキュメント](https://docs.renovatebot.com/configuration-options/#addlabels)


```..github/renovate.json
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": [
    "config:base"
  ],
  "timezone": "Asia/Tokyo",
  "automerge": true,
  "packageRules": [
    {
      "matchUpdateTypes": [
        "major"
      ],
      "labels": [
        "Update-Major"
      ]
    },
    {
      "matchUpdateTypes": [
        "minor"
      ],
      "labels": [
        "Update-Minor"
      ]
    },
    {
      "matchUpdateTypes": [
        "patch"
      ],
      "labels": [
        "Update-Patch"
      ],
      "ignoreTests": true
    }
  ],
  "branchPrefix": "renovate/",
  "dryRun": false,
  "gitAuthor": "Renovate Bot <bot@renovateapp.com>",
  "onboarding": false,
  "platform": "github",
  "includeForks": true,
  "dependencyDashboard": true,
  "repositories": [
    "<OWNER>/<REPOSITORY>"
  ]
}
```

## GitHub リリースノート の テンプレート

 - GitHub リリースノート は テンプレート でカスタマイズ可能
 - renovate が issue に付与した 「ラベル」 で分類するように
     - Update-Major
     - Update-Minor
     - Update-Patch
 - [ドキュメント](https://docs.github.com/ja/repositories/releasing-projects-on-github/automatically-generated-release-notes#example-configuration)

```..github/release.yml
changelog:
  exclude:
    labels:
      - ignore-for-release
    authors:
      - octocat
  categories:
    - title: Breaking Changes 🛠
      labels:
        - Update-Major
        - breaking-change
    - title: Exciting New Features 🎉
      labels:
        - Update-Minor
        - enhancement
    - title: Other Changes
      labels:
        - "*"
```

## 出来上がり

![スクリーンショット 2022-01-30 19.19.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69410/fd7e1434-6238-9dd3-767d-0a0279933994.png)

## あとがき
 - 寂しい一人プロジェクトでも、にぎやかなリリースノートさえあれば、これでモチベが爆上がりですね。
Herokuのインストールからデプロイまで

###　作業内容
##### 1.　Heroku CLIのインストール
##### 2.　Herokuにデプロイ
##### 3.　Herokuデプロイ時のERROR対処


### 前提
下記の項目はすでに設定が終わっていたので、今回の作業からは割愛します。
・Herokuのユーザー登録済み
・Gitはすでにインストール済み（確認コマンド%　git --version）



###　1. Herokuのインストール

1.1　Heroku CLIをインストールする

```
​% brew tap heroku/brew && brew install heroku
```


1.2　バージョンの確認

```
% heroku --version
〜〜〜省略〜〜〜
heroku/7.59.2 darwin-x64 node-v12.21.0
```

インストール出来ていることが確認できました。


1.3　次にHerokuにログインする
（なお--interactiveオプションを使うと、herokuコマンドでブラウザを開かないようにできます）。

```
% heroku login --interactive
heroku: Enter your login credentials
Email: メールアドレス
Password: パスワード

Logged in as メールアドレス
```
ログインすることが出来ました。


1.4　最後にheroku createコマンドを実行して、Herokuサーバー上に今回開発したアプリケーションの実行場所を作成

※このherokuコマンドを実行すると、Railsアプリケーション専用のサブドメインが作成される。

```
% heroku create
```

#### 2. Herokuにデプロイ

2.1　Gitを使ってHerokuにリポジトリをプッシュ
すると、以下のERRORが発生しました。

```
%　git push heroku master
〜〜〜省略〜〜〜
〜〜〜省略〜〜〜
 !
 !     Failed to install gems via Bundler.
 !
 !     Push rejected, failed to compile Ruby app.
 !     Push failed
```

#### 3.　Herokuデプロイ時のERROR対処

3.1 
Bundler経由でgemをインストールできませんといっているので、bundle installを実行してみる。

```
%　bundle install
Bundler could not find compatible versions for gem "spring":
〜〜〜省略〜〜〜
```

3.2
Bundlerは、gem "spring"と互換性のあるバージョンを見つけることができませんでした。 
とERRORになったので、Gemfileの内容を書き換えて再トライ。
`bundle install` 又は　`bundle update`

```
%　bundle update
[!] There was an error parsing `Gemfile`: 'spring~> 1.2' is not a valid gem name because it contains whitespace. Bundler cannot continue.
〜〜〜省略〜〜〜
```

3.3
[！] `Gemfile`の解析中にエラーが発生しました： 'spring〜> 1.2'は空白が含まれているため、
有効なgem名ではありません。 Bundlerは続行できません。とツッコミを入れらてしまう。
確認してみると、
gem 'spring' '~> 1.2'　となっていたので「,」を追加して
gem 'spring', '~> 1.2'　へ修正。
そして、再トライ！

```
% bundle install
Fetching gem metadata from https://rubygems.org/..........
Resolving dependencies...
〜〜〜省略〜〜〜
〜〜〜省略〜〜〜
An error occurred while installing sqlite3 (1.3.13), and Bundler cannot continue.
```

3.4
今度はsqlite3（1.3.13）のインストール中にエラーが発生し、
Bundlerを続行できません。と言われるので、
またGemfileをsqlite3（1.3.13）に対応するよう修正。
ここで、、Git Hubへpushしておく。（git status →　git add . →　git　commit　→　git　push）
からの、再々トライ！

```
 % git push heroku master
〜〜〜省略〜〜〜
remote:  !
remote:  !     Failed to install gems via Bundler.
remote:  !
〜〜〜省略〜〜〜
```

3.5
Bundler経由でgemをインストールできませんでした。と再度ツッコミを入れられる・・・・・？
Your bundle only supports platforms ["x86_64-darwin-19"]
バンドルはプラットフォームのみをサポートします["x86_64-darwin-19"]と言われたので
指定された、bundle lock を実行してみる。

```
% bundle lock --add-platform x86_64-linux
```

3.6
あっ！なんかいったぽい。
ここで、、Git Hubへpushしておく。（git status →　git add . →　git　commit　→　git　push）

再再々トライ！！！！！

```
% git push heroku master
Enumerating objects: 118, done.
Counting objects: 100% (118/118), done.
〜〜〜省略〜〜〜
〜〜〜省略〜〜〜
〜〜〜省略〜〜〜
〜〜〜省略〜〜〜
〜〜〜省略〜〜〜
remote: Verifying deploy... done.
To https://git.heroku.com/peaceful-fortress-23034.git
 * [new branch]      master -> master
```

きたーーーー！
remote: Verifying deploy... done.（リモート：デプロイを確認しています...完了しました。）

はい。
無事デプロイ出来ました。


途中、Git Hubのディレクトリ構成がおかしいことを
メンターさんに指摘して頂いたことで次に進むことが出来ました。　
ありがとうございました。
Ruby on Rails パーシャルとヘルパー

## 初めに
`ヘルパー`と`パーシャル`の使い方
違いを紹介
基本は備忘録

## ヘルパー

  viewをよりシンプルにDRYに書くためのモジュール
  `app/helpers/<コントローラ名>_helper.rb`
  *moduleになっていてviewから呼び出せる*
  *`link_to`や*`render`*等がヘルパーに該当し、独自に定義もできる
  **`includeが必要な時`**
  ControllerやModelで使う時はincludeが必要

  ```rb
  # 例
  module ApplicationHelper

  # ページごとの完全なタイトルを返します。
  def full_title(page_title = '')
    base_title = "Ruby on Rails Tutorial Sample App"
    if page_title.empty?
      base_title
    else
      page_title + " | " + base_title
    end
  end
  
end
  ```
  
  **Controllerで使う時**

```rb
class ApplicationController < ActionController::Base
  # include <Helper名>
  # app/controllers/helpersと拡張子は省略できる
  # ApplicationControllerでincludeすることによって全て
  # のControllerが継承する
  include SessionsHelper
end
```

**Modelで使う時**

```rb
class モデル名 < ApplicationRecord
include ActionView::Helpers
end
```
**特定のhelperのみを使う時**

```rb
class モデル名 < ApplicationRecord
include ActionView::Helpers::TutorialHelper
end
```

## パーシャル
複数の場所から呼び出すために作成されたテンプレートのこと
パーシャルとして使うファイル名は`_sample.erb`のように`_`から始める

```rb
# renderというヘルパーの1種を使う
# 呼び出し方 読み込ませる時は「_」がいらない
# 第3引数に post: @postで変数も渡せる
<%= render "dir_name/file_name"%>
```

## 何が違うの？
`パーシャル`も`ヘルパー`もViewで使います。
`パーシャル`はhtml.erbテンプレートです
複数ページで同じレイアウトの箇所があれば、`パーシャル`として切り分けることで2つの利点があります。
1. コードの記述量が少なくなり可読性が高まる
2. 再利用性が高まる

ヘルパーはviweをDRY(同じコードを繰り返さない)ためのモジュールです。
大抵は少ないコード量で、目的の実装ができるようになります。
`link_to`や`img_tag`がそれにあたります。

**つまり**
使いまわしたhtmlテンプレートは`パーシャル`
関数などのロジックは`ヘルパー`


## 参考
[ヘルパーとパーシャルの違いは何か](https://teratail.com/questions/5586)
[Ruby on Railsチュートリアル](https://railstutorial.jp/)
技術系ブログまとめ

全て購読するわけにはいかないので、まとめておくことにする

## 企業、公式サイト

### Tech

#### Android

- [Android Developers Blog](https://android-developers.googleblog.com/)

#### AWS

- [Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/)

#### Docker

- [Docker Blog](https://www.docker.com/blog/)

#### IaC

- [HashiCorp Blog (Terraform)](https://www.hashicorp.com/blog/products/terraform)

#### WordPress

- 東日本橋の制作・開発会社 プレスマン
  - [PRESSMAN*Tech](https://www.pressmantech.com/)

### Security

- [NRIセキュア ブログ](https://www.nri-secure.co.jp/blog)
- [キャノンMJ サーバーセキュリティ](https://eset-info.canon-its.jp/malware_info/)
- [Trend Micro](https://is702.jp/search/tag/keyword/%E3%82%A6%E3%82%A4%E3%83%AB%E3%82%B9%E3%83%90%E3%82%B9%E3%82%BF%E3%83%BC/)
- [LAC WATCH](https://www.lac.co.jp/lacwatch/)

### Corporate

- [Base](https://devblog.thebase.in/)
- [Gunosy](https://tech.gunosy.io/)
- [Cookpad](https://techlife.cookpad.com/)
- [paiza](https://paiza.hatenablog.com/)
- [Fenrir](https://engineers.fenrir-inc.com/)
- [Cyber Agent](https://developers.cyberagent.co.jp/blog/)
- [Money Forward](https://moneyforward.com/engineers_blog)
- [Freee](https://developers.freee.co.jp/)
- [Developers IO (Classmethod)](https://dev.classmethod.jp/)
- Recruit
    - [Recruit](https://blog.recruit.co.jp/rtc)
    - [Study Sapuri (Recruit)](https://blog.studysapuri.jp/)
- [Mercari](https://engineering.mercari.com/)
- さくらインターネット
  - [さくらのナレッジ](https://knowledge.sakura.ad.jp/)
- [ぐるなび](https://developers.gnavi.co.jp/)
- TECH PLAY
  - [株式会社カケハシ](https://techplay.jp/community/kakehashi/blog)
  - [miracleave株式会社](https://techplay.jp/community/miracleave/blog)
- [Serverworks](https://blog.serverworks.co.jp/)
- [NTT FACILITIES JOURNAL](https://www.ntt-f.co.jp/ntt-fjd/)

### Test

[Google Testing Blog](https://testing.googleblog.com/)

その他
- [9TO5Mac](https://9to5mac.com/)
- [9TO5Google](https://9to5google.com/)

## 個人的によく使うサイト（既出）

- [Developers IO (Classmethod)](https://dev.classmethod.jp/)
- [Serverworks](https://blog.serverworks.co.jp/)
- [Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/)
Rails 新規登録フォームを作成する

## はじめに
基本は備忘録
Qiitaにすごく助けられている


## 新規登録フォーム
`今回はユーザー登録を参考に使うが、新規投稿でも似たような作り方`
*Userモデル・Controllerは生成済み*
*`bcrypt`*は設定済み
*users_ControllerやUser_Model*はログイン機構を参照
**bcryptを使う際の注意点**
新規登録時に`password`と`password_confirmation`を使用する

## 新規登録フォームの作り方
```rb
# view側
# model: に newアクションで生成したインスタンス変数をset
<div>
  <%= form_with(model: @user, local: true) do |f| %>

    <%= f.label :name %>
    <%= f.text_field :name, class: 'form-control' %>

    <%= f.label :email %>
    <%= f.email_field :email, class: 'form-control' %>

    <%= f.label :password %>
    <%= f.password_field :password, class: 'form-control' %>

    <%= f.label :password_confirmation, "Confirmation" %>
    <%= f.password_field :password_confirmation, class: 'form-control' %>

    <%= f.submit "Create my account", class: "btn btn-primary" %>
  <% end %>
</div>
```

```rb
# Controller
def new
  @user = User.new
end

def create
# User.create(name: params[:user][:name]..)をhashで一度で
# Usesr.create(params[:user])だとセキュリティー的にエラー
@user = User.create(user_params)
  if @user.save
  session[:user_id] = @user.id
  flash[:notice] = "ログインしました"
  # redirect_to user_path(@user.id)の省略
  # "/users/#{@user.id}"
  redirect_to @user
  else
  # render("/users/new")の省略
  render 'new'
  end
end


private

def user_params
  # ストロングパラメータの定義
  # paramsのどのハッシュのどのカラムを取得するか設定
  params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
```

## 参考
https://qiita.com/sew_sou19/items/e9944904b50899fbb4cf
入出力ストリーム

# コピー処理
Filesクラスを用いてのコピー処理は以下。

```
Files.copy(Path source,Path target,CopyOption...options);
```

1.`Path source`
    コピー元
2.`Path target`
    コピー先
3.`CopyOption...options`
    コピーの実行方法

Pathsクラスのgetメソッド(*1)を使用し、
コピー元とコピー先情報についてPathインターフェースをデータ型としてインスタンス化する。
作成したインスタンスをそれぞれ上記1と2に代入して、3でコピー方法を指定する。

[Files.copy（docs.oracle引用）](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/nio/file/Files.html#copy(java.nio.file.Path,java.nio.file.Path,java.nio.file.CopyOption...))

- *1　FileSystems.getDefault().getPathの省略形。非推奨？
Ruby on Rails form_withの使い方

## 初めに

`form_tag`しか使ったことがなく、`form_with`はじめてだったのでまとめてみた
基本は備忘録

## form_with
*railsで情報を送信するためのヘルパーメソッド*



## DBに保存するとき
```rb
# インスタンスが空ならcreateアクションへ
# 情報が入っているならupdateアクションへ
<%= form_with model: モデルクラスのインスタンス do |form| %>
  <!--フォーム内容 -->
<% end %>
```

```rb
# Contoroller
def new
  @user = User.new
end
```

```rb
# View
# newアクションで生成したインスタンスを指定する
<%= form_with model: @user do |form| %>
  <!--フォーム内容 -->
<% end %>
```

## フォームの作り方
`name`属性の値をkeyに`params`で入力内容を送る
受け取り方は`params[:モデル名][:key]`
通常は`ストロングパラメータ`を定義してハッシュで一括受け取り

```rb
# form.htmlタグ名 :カラム名
# カラム名は保存先のテーブルのカラム名を指定
<%= form_with model: @user do |form| %>

  <%= form.label :name %>
  <%= form.text_field :name, class: "hoge" %>
  
  <%= form.submit %>
<% end %>
```

---

## DBに保存しないとき
`name`属性の値をkeyに`params`で入力内容を送る
`scope`を省いた場合`params[:key]`で取得できる
`scope`を用いた場合`params[:スコープ名][:key]`で階層が1つ深くなる

```rb
<%= form_with url: "パス", scope: hoge, local: true do |form| %>
  <!--フォーム内容 -->
<% end %>
```

## html属性の付け方

```rb
<%= form_with model: @user, id: 'new_form' do |form| %>
  <!--フォーム内容 -->
<% end %>
```

## 直接ControllerとActionを指定する

```rb
# Routeingがうまくいかない時は直接指定する
<%= form_with @user, url: {controller: 'users', action: 'index' } do  |form| %>
  <%= form.text_field :name %>
  <%= form.submit %>
<% end %>
```

## 参考
[【Rails】 form_withの使い方を徹底解説！ \| Pikawaka](https://pikawaka.com/rails/form_with)
*使用可能なhtmlタグや使い方は参考先を確認*

[[Rails]初学者がform_withの流れを整理・理解するための記事 - Qiita](https://qiita.com/sew_sou19/items/e9944904b50899fbb4cf)
【メモ】自作パッケージの環境を有効化してライブラリをaddする方法

# Juliaで自作パッケージの環境を有効にし、ライブラリなどを追加する方法

毎回、自作したパッケージに既存ライブラリを追加する方法を忘れてしまうのでメモとして残しておきます。

自作パッケージの環境を有効化したい場合、自分のパッケージがあるディレクトリに行ってもらって、

juliaのPkgモードで

```
pkg> activate .
```

とすることで、環境を有効化しますと宣言したことになる。

```
add 〇〇
```
で〇〇というインストールしたいライブラリが入ったことになる。

依存パッケージを消して１から入れ直したい場合は、Manifest.toml を消して、以下のコマンドを実行する。
（Manifest.tomlには、ライブラリのバージョンなどが記述されている。一方でProject.tomlにはよりメタ的な情報が記入されている）

```
pkg> instantiate
```

をすると、新しくManifest.tomlを作ってくれる。

これは、pythohのpip install -r requirements.txtに対応する。
【AWS】Go Lambdaのローカル開発環境を作る ( aws-sam-cli + M1mac )

# はじめに

`aws-sam-cli`を利用すれば、手元の端末内にLambdaの実行環境を再現して、動作検証できる。
手元でコードを修正しながらその場で動作確認できるため、ディプロイの手間とLambdaの費用を削減できる。
nodejsとpythonの導入手順は多い中、Golangのドキュメントが少ないように感じたため、ここで纏める。


### やること

* 開発用にarm版Golangをローカル環境にインストールする
* `aws-sam-cli`でローカル環境にLambdaとAPIGatewayを構築する


### 前提

* arm版(M1チップ)の`macOS`環境をベースに説明する (goenv導入部分以外は大差ないはず)
* Z shell (zsh) をベースに説明する (環境変数の通し方以外は大差ないはず)
* Dockerは既にインストールしてあるものとして説明する


# もくじ

1. Golangをセットアップする
* aws-sam-cliをセットアップする
* ローカル環境でLambdaを起動する


# 1. Golangをセットアップする

### 1-1. goenvをインストール

brewでそのままgoenvをインストールすると、古いバージョンしか落ちてこない。
したがって、下記コマンドで強制的に最新版を取る。

``` macOSでgoenvをインストール.
% brew uninstall goenv && brew install --HEAD goenv
% goenv -v
goenv 2.0.0beta11
```

下記はarm版(M1チップ)の`macOS`でarm版Goを取得するための設定。
必要なければスキップしても良い。

``` zshrcに環境変数設定を追記(bashを使っているなら適宜読み換え).
% echo 'export GOENV_ROOT="$HOME/.goenv"' >> ~/.zshrc
% echo 'export PATH="$GOENV_ROOT/bin:$PATH"' >> ~/.zshrc
% echo 'eval "$(goenv init -)"' >> ~/.zshrc
% cat ~/.zshrc
export GOENV_ROOT="$HOME/.goenv"
export PATH="$GOENV_ROOT/bin:$PATH"
eval "$(goenv init -)"
```

### 1-2. Golangをインストール

``` インストールできるバージョンの一覧を確認.
% goenv install -l
Available versions:
  1.2.2
  1.3.0
    …
  1.17.5
  1.17.6
  1.18beta1
```

arm版`macOS`に対応しているのは1.16.0以降のみなので注意。

``` stableな最新版をインストール.
% goenv install 1.17.6
```

``` 使いたいバージョンを指定する.
% goenv global 1.17.6
```


↓ (amd版/arm版含み)意図通りのバージョンを参照できるようになったか確認。

``` ターミナル再起動後、参照バージョンを確認.
% exec $SHELL
% go version
go version go1.17.6 darwin/arm64
```


# 2. aws-sam-cliをセットアップする

### 2-1. aws-sam-cliをインストール

macOSの場合、brewで`aws-sam-cli`をインストールできる。

↓ macOS以外の環境でセットアップする手順

https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html

``` macOSでaws-sam-cliをインストール.
% brew tap aws/tap
% brew install aws-sam-cli
% sam --version
SAM CLI, version 1.37.0
```

### 2-2. aws-samの公式サンプルを取得

``` dockerがインストールされているか確認.
% docker --version
Docker version 20.10.12, build e91ed57
```

下記コマンドでAWS公式のサンプルファイル群を取得できる。
単に`% sam init`で実行すれば、対話的に各種設定を進めることもできる。

``` AWS公式サンプルを取得.
% mkdir lambda_go_test
% cd lambda_go_test
% sam init --package-type Image --base-image amazon/go1.x-base --name golang-sam-sample
```
# 3. ローカル環境でLambdaを起動する

生成されたサンプルファイル群のルートディレクトリに入ってDockerImageを焼く。

``` Dockerfileを読んでImageを焼くコマンド.
% cd golang-sam-sample
% sam build
```

Imageが焼き上がったらLambdaとAPIGatewayを動かしてみる。

``` aws-sam-localを起動するコマンド.
% sam local start-api
Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2022-01-30 18:31:58  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
```

curlで叩いて、挨拶してもらえたなら成功。

``` もう1つターミナルを開いて疎通確認.
% curl http://127.0.0.1:3000/hello
Hello, xxx.xxx.xxx.xxx
```

このあとは適宜main.goを編集してLambdaの処理内容を変えたり、template.yamlを編集してLambdaの数を増やしたりして遊ぶ。


# トラブルシューティング
### 何度やり直してもArm版Golangが落ちてこない

TerminalをRosetta2経由で起動していませんか (私はしていました)。
35歳未経験で社内SEになる方法①

#自己紹介
こんにちは！
銭湯・サウナと筋トレをこよなく愛する銭湯ジョグと申します。
僕は35歳に未経験で社内SEになりました。
なぜこの年の未経験でなれたのか、今までの経緯を含めて紹介できればと思います。
少しでも誰かのお役に立てれば光栄です。
##現在
本題ですが、簡単に自己紹介させていただきます。
僕は今ギリギリ36歳の千葉県在住でとある企業の社内SEをしております。
去年の2月から社内SEとして働き始めましたので、そろそろ転職して1年が年が経つ所です。
今は、優しい同僚や上司の元でノホホンと働いています。
正直に言いますと、今回の転職は結果的に大成功でした。
その経緯について、タラタラと話させて下さい。
##20歳〜30歳
僕は２浪をしてFラン大学に入り、新卒の4月までに就職先が決まらずその5月に
ギリギリ新卒採用枠で中小企業に就職したどうしようもないポンコツ人間です。
営業職で入社しましたが、上司にいびられ続け、入社後10ヶ月でその上の上司に泣きながらもう無理ですと報告。それから、技術職として働いて来ました。
その後、5,6年その会社で働きましたが、超絶ブラック企業だったため退職。
寝ずに客先に行って書類提出プレゼンする等で月180時間残業して来たため（休日出勤含まず）それだけ大変な企業で技術屋として働いていたため、特に就活もせず共何とかなるとたかを括って過ごしていました。
見事プー太郎になり、タバコを1日2箱吸いながらパチンコ三昧。6万擦ってムシャクシャして風俗で2万を使う。1日8万なくなるなんて事もありました。家に来た後輩にはキャバクラを奢り、北海道旅行に行って散財する始末。
結果、9ヶ月程で300万円貯めていたお金が見事に溶かしてしまいました。
ここからが地獄。。
##お金がない…
金がなさ過ぎて、自信がなくなり自暴自棄。
セ○レにはキツくあたり、ちょっとしたヒモ状態。
どうしようもないクズ野郎です。

しまいには、近くのハローワークにお金がないんです。助けて下さいと言う始末。
結局、生活保護に近いような住宅手当的な月５万円の受給を２ヶ月もらってほそぼぞと就活をしていました。

そんな状況で良い転職など出来るわけもなく、職業訓練で指導してくれていた方に企業紹介をされて入社したのが、工事の原価管理システムを作っている会社の営業。
年収は３００万円。月給手取り18万円でした。
それでも、お金がない僕がやっと再起出来たのだからと頑張っていました。
が、土曜日出勤当たり前。夜に明日までにプレゼンの練習をしろと言われ、寝ずに練習したりするなど、帰れない状況が続きますが残業代０。とんだブラック企業に就職してしまいました。
おまけに、社長も上司もヤクザみたいにオラオラ系の体育会系。
１ヶ月半で鬱病になって辞めました。

ですが、お金がない状況は変わらないため、そこから転職活動再開。
当時特に分かっていなかったため、特定派遣に就職。
正社員と言うのと、家賃手当が家賃の半分出ると言う言葉にまんまとハマり見事に
その会社に約５年間搾取される生活を送りました。

続く。。
【rails6】deviseによるユーザー登録失敗時に画面更新すると、Routing Errorが発生する

この記事は、<b>ruby on rails</b>とそのgemである<b>'devise'</b>についての基礎知識がある前提で書かれていますのでご注意ください。

# どのようなエラーか
deviseには標準でユーザー登録機能が備え付けられています。
この新規登録を行う際、入力情報に不備がある（バリデーションに引っかかる）とエラーが出て、新規登録画面のビューが返されるようになっています。
単純に、DBに保存されたか否かで条件分岐をしているだけだと思うのですが、deviseの中身をじっくり見たわけではないのでそこは明確ではありません。

そこで問題となるのが、登録に失敗することでビューが返された状態だと、よく見るとURLが変化してしまいます（登録画面自体にはさほど変化はありません）。


<b>登録ボタン押す前（エラー前）</b>
![スクリーンショット 2022-01-30 18.18.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2283370/6d840965-4165-c180-4177-a67bb2f4ef78.png)
<b>登録ボタン押した後（エラー後）</b>
![スクリーンショット 2022-01-30 18.18.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2283370/cdefbb05-e090-1d99-6702-1bef23c860b6.png)

画像のように<b>/users/sign_up</b>から、<b>/users</b>に変化しています。

そして、この状態で画面更新をしてしまうと、エラー画面が表示されてしまいます。
![スクリーンショット 2022-01-30 18.18.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2283370/748ff88d-2335-93e3-03a2-58dc338c28ca.png)

<b>Routing Error</b>で、
<b>「"/users"に対して、GETメソッドを用いているルーティングがないよ」</b>
と言われています。

変な設定をしているわけではない（つもり）ので、このエラーは気持ち悪いです。

# 解消方法
結論から述べると、ルーティングがないと言われているので、
<b>'/users'に対する、GETメソッドのルーティング</b>
を無理矢理ルーティングを作ってあげました。

```ruby
get '/users', to: '（なんらかのコントローラー名）#index'
```

このようにすると、エラーは出なくなるのですが、新規登録画面から離れてしまうことになります。

新規登録画面から移動せずにエラーを解消するには、<b>「deviseの中で、新規登録処理を行なっているコントローラーとアクション」</b>を把握すれば良いのではないかと思います。

私は、エラーが出てしまうのが気持ち悪くて解消したかったので、今回はここでとりあえず満足しました。
##(実話)大学へは行かずに、機械学習エンジニアになれた方法!!!

##(実話)大学へは行かずに、機械学習エンジニアになれた方法!!!

![Screenshot_2022-01-30 18.07.30_MaIrdu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/824783/755ebb24-66ba-2528-6fcd-270c69e7f9f0.png)


より詳細な記事は、[こちら](https://note.com/01shinji/n/ned058f82f11c) で詳しく解説しています。
【C#】コードの途中で登場するusingってなんだろう

# はじめに
C#初学者向け記事です。

今回はファイルの先頭にある、`using` ではなく、コードの途中に登場する `using` についてなんだろうと思ったので備忘録的な記事になります。

こんなコードです。

```c#
using (var stream = new StreamReader(filePath))
```

# 結論
- 外部リソースの破棄を確実にしてくれている

# 解説
- 外部リソースにアクセスするクラスは、使い終わった時に後始末をしないといけない
- IDisposableインターフェイスを実装しているクラスがこれにあたる
- Disposeメソッドの呼び出しを忘れると、ファイルがオープンにされたまま
	- 他から利用できなくなる
	- メモリリークのリスクがある

# コード例
```c#:using文を使わない例
public void Reader()
{
    StreamReader stream = new StreamReader(filePath);
    try
    {
        string texts = stream.ReadToEnd();
        // データの処理
    }
    finally
    {
        stream.Dispose(); // 最後にDisposeを呼び、後処理をする
    }
}
```

```c#:using文を使った例
public void Reader()
{
    using (var stream = new StreamReader(filePath))
    {
        var texts = stream.ReadToEnd();
        // データの処理
    }
}
```

- using文を使うだけで `using` を抜ける際に、自動的にDisposeメソッドが呼び出されます。
- IDisposableインターフェイスを実装しているクラスを使う際は、using文で確実に簡潔にリソースを破棄できます。
- IDisposableインターフェイスを実装していないクラスに対しては、using文は使えません。

今回は以上となります。
ご拝読有難うございました。
yukicoder No.1658 Product / Sum

今回は、 [yukicoder](https://yukicoder.me/) の問題紹介・解説を行っていきたいと思います！

2問目に紹介する問題はこちら！

## 概要
問題 ： [No.1658 Product / Sum](https://yukicoder.me/problems/no/1658)
レベル ： ★★
実行時間制限 ： 2000 ms

問題文へのリンク↓↓

https://yukicoder.me/problems/no/1658

<hr>

## 問題文

> $\displaystyle \frac{A_1 \times A_2 \times \dots \times A_n}{A_1 + A_2 + \dots + A_N} = K$ を満たす $N$ 個の正の整数 $A_1, A_2, \dots, A_N$ を $1$ 組求めてください。

> 本問の制約のもとで、答えは必ず存在することが証明できます。

## 制約

- $2 \leq N \leq 10^5$
- $1 \leq K \leq 10^5$
- 入力は全て整数

## 入力例
### 入力

```Bash:入力
2 5
```

### 出力

```Bash:出力
6 30
```

$\displaystyle \frac{A_1 \times A_2}{A_1 + A_2} = \frac{6 \times 30}{6 + 30} = 5$ となります。

## 解説

ここからは解説をしていきます。

自力で解いて見たい方はここでストップしてください！

### 大きい数は使えない

与式を変形すると以下のようになります。

```math
\prod_{i=1}^{N} A_i = K \times \sum_{i=1}^{N}A_i
```

$K$という定数が右辺にかかっていますが、本質は和と積の等式です。

**和と積では積の方が早く発散する** ので、基本的に １ ばかりで埋めていくことを考える。

### 全て1の場合

全ての値を1にした場合ではまだ右辺の方が大きいのは明らかです。

```math
1 = NK
```

となってしまうので、 $K \neq 1$ 以外で落ちてしまいます。

### １つだけ1以外した場合

全て1がダメだったので、１つだけ違う値で置いてみましょう。

その値を $A_1 = x$ とします。

立式していきましょう！

```math
\prod_{i=1}^{N} A_i = K \times \sum_{i=1}^{N}A_i \\

x = K \times \{ x + (N - 1) \} \\

x = \frac{(N - 1) K}{1 - K} \\
```

ここで、 $x$ を構築することができましたが、実は $K \geq 2$ でこれは負の値になってしまい、
問題文の条件を満たさなくなってしまいます。

ではもう１つ１以外の値で構築してみましょう。

### 2つだけを１以外にした場合

その値を $A_1 = x, A_2 = y$ とします。

立式していきましょう！

```math
\prod_{i=1}^{N} A_i = K \times \sum_{i=1}^{N}A_i \\

xy = K \times \{ x + y + (N - 2) \} \\

(x - K)(y - K) = K(N - 2 + K) \\
```

両辺を因数分解することができたので、解を１つ求めてみましょう。

すると、

```math
\left\{
\begin{array}{l}
x - K = K \\
y - K = N - 2 + K
\end{array}
\right.
```

```math
\left\{
\begin{array}{l}
x = 2K \\
y = N - 2 + 2K
\end{array}
\right.
```

$x$ は明らかに正であることが確認できます。

$y$ の方についても不等式で評価してみましょう！

```math
y = N - 2 + 2K \geq 2 - 2 + 2 \times 1 = 2 \geq 0
```

したがって、このような構築を行うことでこの問題を解くことが出来ました。

## ACコード
```python
n, k = map(int, input().split())

ans = [2 * k, n - 2 + 2 * k]
for _ in range(n - 2):
    ans.append(1)

print(*ans)
```

## 最後に
最後まで読んできただきありがとうございました！

構築問題はやはり面白いですね！！

リクエストなどがあればぜひ声かけて下さい！ありがとうございました！
【Android】アプリのローカライズ（海外言語対応）する方法について

# 海外言語の対応について
よく越境とかインバウンドとか聞きますが、ようするに海外言語に対応して表示する文字列を英語とかフランス語とかに対応させようって話で
Androidではどうやるのっていうのを記載します。

# ユーザによる言語変更のイメージ

私のOPPO端末でのイメージ画像ですが、このように言語設定変えることを指しています。

![Screenshot_2022-01-30-17-45-56-94_png_と_Screenshot_2022-01-30-17-45-52-56_png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574173/3796c948-39c3-a2a6-dc0e-a44cf8ca6491.png)

# 開発側でどこを変更するのか

※公式を参考に説明しています。~~知っている風に書いててごめんなs~~
https://developer.android.com/guide/topics/resources/localization?hl=ja

## Android のデフォルトリソース
`res`ディレクトリの配下にある各ファイルのことを指しています。
Androidアプリが必要とするテキスト文字列、レイアウト、音声、グラフィック、およびその他のすべての静的データのことです、
テキストに関しては特に指定がなければAndroidは自動で`res/values/strings.xml`からテキストを取得して表示しています。

一例

```xml:res/values/strings.xml
<!-- The action for submitting a form. This text is on a button that can fit 30 chars -->
    <string name="login_submit_button">Sign in</string>
```

この例で言えば"login_submit_button"という名前をつけて、文字列は「Sign in」になるようにしています。

## テキストの代替リソースの作成方法に関する概念
各ロケール用に代替リソースを作成するには、言語または言語と地域の組み合わせを指定する修飾子を使用します（リソース ディレクトリの名前は、代替リソースを提供する方法に記載されている[命名規則](https://developer.android.com/guide/topics/resources/providing-resources?hl=ja#AlternativeResources)に準拠する必要があります。準拠していないと、アプリはコンパイルできません）。

言語は2文字の[ISO639-1言語コード](https://ja.wikipedia.org/wiki/ISO_639-1%E3%82%B3%E3%83%BC%E3%83%89%E4%B8%80%E8%A6%A7)で定義できます。


つまりは英語ならen、フランス語ならfrになります。
~~plならPL学園ではなくポーランド語です。~~

## 実際の代替リソース変更例

上記の概念をもとにどのように変更するのか例の紹介です。
代替リソースを変更してテキストを海外言語に合わせるとアプリ内のすべてのテキストをフランス語にローカライズするとします。

### 各ロケール専用のリソースディレクトリにそれぞれ格納
フランス語なら`values-fr`のようになります。
英語なら`values-en`です。

### strings.xmlファイル作成
`res/values-fr/strings.xml`
titleなどすべての文字列に対してフランス語のテキストを含めます。

### どのように読み込むか
これによってtitleを読み込む際に
デバイスがフランス語に設定されている場合、Androidは`res/values-fr/strings.xml`ファイルからtitleを読み込みます。

もし日本語に設定されている場合はAndroidはres/values-ja/strings.xmlファイル内でtitleを探しますが、そんなものはないのでAndroidはデフォルトリソースのres/values/strings.xmlファイルから英語のtitleを読み込みます。

こんな流れです。
以上で終わりですが、下記は付随するTipsです。


# ローカライズする文字列を管理する

アプリを作成する際に、どの文字列もハードコードしないようにしてください。~~ハードコーディングはダメ絶対~~
すべての文字列をリソースとして、デフォルトの strings.xml ファイルに宣言します。

これによってローカライズがしやすくなりますし、アプリ内で文字列にアクセスする方法に一貫性ができて効率的な開発が望めます。

## コメントアウトを効果的に付ける
- この文字列は何のためか。いつ、どこでユーザーに表示されるか。
- レイアウトのどこに配置されるか。

これらがコメントで表現されていると翻訳する際や開発者同士の認識の齟齬が起きにくいです。

## メッセージ内の翻訳対象外の部分に印を付ける
他の言語に翻訳してはならないテキストが文字列に含まれることはよくあります。
例は、コードの一部、何かの値のプレースホルダ、特殊記号、名称などです。文字列を翻訳する準備の際に、翻訳せずにそのまま残す必要があるテキストを探して印を付け、翻訳者が変更しないようにします。
翻訳対象外のテキストに印を付けるには、<xliff:g> プレースホルダ タグを使用します。次の例では、テキスト「%1$s」が翻訳中に変更されないよう指定するタグを示します（タグを指定しないと、メッセージが壊れるおそれがあります）。

```xml:res/values/strings.xml
    <string name="prod_name">
        Learn more at <xliff:g id="prod_gamegroup">Game Group</xliff:g>
    </string>
```

until holidayの部分は固定なのですが日数は可変のため翻訳されないようにしています。
プレースホルダ タグを宣言する際は、何のためのプレースホルダかを説明する id属性を必ず追加します。

## MainActivityなどで値を可変にする例

```Java:MainActivity
private String method(String inputName) {
  String gameGroup = inputName;
  String inputThing = getString(R.string.prod_name, inputName);
}
```

methodを呼び出して引数に文字列を与えて呼び出しています。
string.xmlのprod_nameにアクセスしてprod_gamegroupの部分は引数で渡した文字列で埋めた文字列にしてくれます。






# 参考
https://developer.android.com/guide/topics/resources/localization?hl=ja
【STS4】Lombokを入れて作成したプロジェクトでクラスが作成できない時の対処法

<h3>【環境】</h3>
OS version ：Windows10 Home (version20H2)
STS version：version4.13.0.RELEASE

<h3>【不具合概要】</h3>
<ol>
<li>STS4にて、ファイル＞新規＞Springスタータープロジェクトを選択</li>
<li>新規Springスターター・プロジェクト依存関係画面にて"Lombok"を選択してプロジェクトを作成</li>
<li>上記手順で作成したプロジェクトにてクラスを作成しようとすると「入門コンテンツのインポート」というタスクが79%からまったく進まず、クラスを作成できない（以下画像参照）</li>
</ol>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587185/b8dec997-d0e0-0a06-db89-9166a219c70e.png)

<h3>試したこと</h3>
<ul>
<li>ひたすら待つ → 1週間ほど経過するも状況に変化なし。</li>
<li>Lombokを入れずにプロジェクトを作成 → 正常に動作する。</li>
<li>STS、Lombokをアンインストールして再インストール → 状況に変化なし。</li>
</ul>

<h3>解決方法</h3>
<ol>
<li>スタータープロジェクト作成時点ではLombokを選択せずにプロジェクトを作成。</li>
<li>設定ファイルのpom.xmlに直接Lombokの記述を追記<br>
</ol>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587185/0a20a763-7e98-2869-ce16-d7f74044fba3.png)
上記方法で正常にプロジェクト、クラスの作成ができた。

<h3>不具合原因</h3>
<p>現状わかっていない。
同事象について調べているとSTSの不具合という記事がチラホラ・・・。
尚、正常に動作した場合(画像左側)と正常に動作しない場合（画像右側）のpom.xmlのソースの差異は以下画像のとおり。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587185/f7235b39-d918-cc3b-5e02-2895fb084fef.png)
原因は調査中、わかり次第記事を更新予定です。
ServiceNow - 曜日を表示する

###課題：
日付の曜日を日本語で表示させる。
```*** Script: 2022年01月30日日曜日
```

###問題：
ServiceNowで.getByFormat()で曜日を表示すると曜日が英語になる。Javaの場合はSimpleDateFormat()でLocaleを指定することはできますが、ServiceNowではスクリプトからLocaleの利用を禁止されている。

```
var gdt = new GlideDateTime();
var format = 'MM月dd日EEEE曜日';
var gDate = gdt.getLocalDate();
gs.info(gDate.getByFormat(format));
```
その結果、上のスクリプトを実行すると曜日は英語になる。
``` 2022年01月30日Sunday
```

次ぎのようにスクリプトで日本語の曜日を配列にして取得することもできる。

```
var dayOfWeekStr = [ "日", "月", "火", "水", "木", "金", "土" ];

var gdt = new GlideDateTime();
var format = 'yyyy年MM月dd日E曜日';
var dow = gdt.getDayOfWeekLocalTime();

format = format.replace('E', dayOfWeekStr[dow]);
var gDate = gdt.getLocalDate();
gs.info(gDate.getByFormat(format));
```

しかし、ServiceNowでは各言語の翻訳をデータベースに保存してあるためそこから参照するようにしたら日本語だけではなく、他言語でも曜日を表示させることができる。

```
        var dowArray = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];

        function getDate(gdt, format, lang) {
            //var dow = getDayOfWeekList(lang);
            var dowNum = gdt.getDayOfWeekLocalTime();
            var gDate = gdt.getLocalDate();
            var orgStr = dowArray[dowNum - 1];
            orgStr = orgStr.charAt(0).toUpperCase() + orgStr.slice(1);
            return gDate.getByFormat(format).replace(orgStr, gs.getMessageLang(orgStr, lang));
        }

        var lang = 'ja';
        var format = 'yyyy年MM月dd日EEEE';
        var gdt = new GlideDateTime();

        gs.info(getDate(gdt, format, lang));

```
###実行結果
lang='ja'
```*** Script: 2022年01月30日日曜日```
lang='en'
```*** Script: 2022年01月30日Sunday```
以上
juliaの型でpythonオブジェクトをラップするときのテクニック

# juliaの型でpythonオブジェクトをラップするときのテクニック

いきなりだが、juliaでpythonパッケージをpyimportしてラップしたものを使う際に、hoge.pyobj~のように間にpyobjをうたないといけない。
本記事ではpyobjの入力を省略するテクニックを紹介する。

通常の場合

```julia
using PyCall

numpy = pyimport("numpy")

struct Hoge
    pyobj::PyObject
end
```

これを実行すると

```
hoge = Hoge(numpy)
hoge.pyobj.sqrt(2) #この例のようにいちいちpyobjを打たないといけない
```

これを以下のようにpyobjを省いて実行するのが本記事のゴールである。

```
hoge.sqrt(2)
```

コードは以下のようになる。

```julia
using PyCall

numpy = pyimport("numpy")

struct Hoge
    pyobj::PyObject
end

function Base.getproperty(h::Hoge, s::Symbol) #構造体を引数に保つ関数！
    if s == :pyobj
        getfield(h, s)
    else
        getproperty(getfield(h, :pyobj), s)
    end
end


```

実行

```
hoge = Hoge(numpy)

# Case1
hoge.sqrt(2) #1.4142135623730951

#Case2
hoge.pyobj.sqrt(2) #上と同じ結果
```

## 何が起こっているのか

### Case1の場合

結論から言うと、hoge.sqrtは、getproperty(hoge, :sqrt) と同じである(言い換えると、hoge.sqrt(2)は、getproperty(hoge, :sqrt)(2)と同じ)。

まず、hoge.sqrtが実行されると内部でBase.getproperty関数が呼び出される。Base.getpropertyの引数には、それぞれ第一引数hにhoge、第二引数sにsqrtが対応する。
s == :pyobjはFalseなので、getpropertyが呼びだれることになる。
ここで、getfield(h, :pyobj) は、Hogeのフィールドのpyobj,ここではnumpyに対応する。
（getfield(hoge, :pyobj)を実行するとわかります。）

従って、getproperty(getfield(h, :pyobj), s)とは、numpy.sqrtを実行していることになる。


### Case2の場合
hoge.pyobjでBase.getproperty関数が呼び出される。Base.getpropertyの引数には、それぞれ第一引数にhoge、第二引数にpyobjが対応する。
s == :pyobjがTrueなので、getfield(h, s)が実行される。
[初心者log]Rails(API)で複数のデータを結合してjson形式で返す

#本記事の目的
Rails(API)+Reactで開発をしているとき、投稿にユーザーネームの添付に手こずったので、
今回はPost(投稿)コントローラのindexにおいてUser情報も加え、必要なものを返却する方法を調べたのでまとめておきます。

##UserテーブルとPostテーブル
![users_posts_table.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2048885/a8178988-e4aa-cb1d-3712-5a3c5731bc10.png)

##必要な情報を結合して返却したい

```app/controller/post_controller.rb
class PostsController < ApplicationController
  def index
    posts = User.joins(:posts).select('posts.id, title, body, name AS user')

    render json: { data: posts }
  end
end
```

##joinsメソッドとselectメソッド

###joinメソッド
joinsメソッドは2つのテーブルを内部結合することができるメソッドです。

```
User.joins(:posts)
```
joinsメソッドを使って、usersテーブルとpostsテーブルを内部結合させます。


###selectメソッド
内部結合させたあとに、selectメソッドを使って、必要なカラムを指定して取得します。

```
.select('posts.id, title, body, name AS user')
```
* ここでposts.idとなっているのは、テーブル同士でカラム名が重複している場合、テーブルを指定してidを取得しています。titleやbodyなどの重複していないカラムはそのまま指定することができます。

* name AS userとしているのは、usersテーブルのnameカラム名を表示用にuserと変更しています。postsテーブルのカラムと一緒に返却しているためnameだと分かりづらいためuserに変更しています。

---
参照：[Rails API - 複数テーブル（親子テーブル）を結合して必要なカラムだけをJSONで返却したい](https://bamboo-note.tokyo/Ruby/rails-api-json-inner-join-response/)
DokuwikiをDockerで構築

bitnamiのdockerイメージはエラーが出て、一発で動かなかった。
調べる気力もなく、2番目に人気のイメージを試したら一発で動いた。

linuxserver.ioというチームがメンテしているらしい。そこそこメンテされてそう。

https://hub.docker.com/r/linuxserver/dokuwiki


```
docker run -d --name=dokuwiki -e PUID=1000 -e PGID=1000 -e TZ=Asia/Tokyo -p 80:80 -p 443:443 -v ~/dokuwiki:/config --restart unless-stopped lscr.io/linuxserver/dokuwiki
```

ブラウザで以下にアクセスすると、初期設定画面が出るので、
ユーザなどを設定する。
http://localhost/install.php
(日本語する場合は、右上の言語設定機能で。)


簡易的な情報共有目的なら使えそう。
![スクリーンショット 2022-01-30 18.15.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72933/9f7c24a6-d3a4-e765-8b2f-d45fcb047f8b.png)
optparse.py がエラーを吐く


# 症状
python3 が絡むほとんどの処理で optparse.py がエラーを吐いて困った。

e.g.: apt, command-not-found, pip3

# エラー内容
```
$ hoge
Traceback (most recent call last):
  File "/usr/lib/command-not-found", line 25, in <module>
    from optparse import OptionParser
  File "/usr/lib/python3.8/optparse.py", line 1
    nt to [a-zA-Z0-9_]
       ^
SyntaxError: invalid syntax
```

# 調査

/usr/lib/command-not-found は python3 で書かれている。

```
$ file /usr/lib/command-not-found
/usr/lib/command-not-found: Python script, ASCII text executable
```

/usr/lib/python3.8/optparse.py が壊れているようだ。
このファイルは python3 の基本的なライブラリ。

```
$ cat /usr/lib/python3.8/optparse.py
nt to [a-zA-Z0-9_]
             in bytes patterns or string patterns with the ASCII flag.
             In string patterns without the ASCII flag, it will match the
             range of Unicode alphanumeric characters (letters plus digits
             plus underscore).
             With LOCALE, it will match the set [0-9_] plus characters defined
             as letters for the current locale.
    \W       Matches the complement of \w.
    \\       Matches a literal backslash.

This module exports the following functions:
    match     Match a regular expression pattern to the beginning of a string.
    fullmatch Match a regular expression pattern to all of a string.
    search    Search a string for the presence of a pattern.
    sub       Substitute occurrences of a pattern found in a string.
    subn      Same as sub, but also return the number of substitutions made.
    split     Split a string by the occurrences of a pattern.
    findall   Find all occurrences of a pattern in a string.
    finditer  Return an iterator yielding a Match object for each match.
    compile   Compile a pattern into a Pattern object.
    purge     Clear the regular expression cache.
    escape    Backslash all non-alphanumerics in a string.

Each function other than purge and escape can take an optional 'flags' argument
consisting of one or more of the following module constants, joined by "|".
A, L, and U are mutually exclusive.
    A  ASCII       For string patterns, make \w, \W, \b, \B, \d, \D
                   match the corresponding ASCII character categories
                   (rath
```

# 解決方法

GitHub (https://github.com/python/cpython/tags) の対応するのバージョンの optparse.py で差し替える。

```bash
$ python3 -V
Python 3.8.10
```

-> 今回は 3.8.10 (https://github.com/python/cpython/releases/tag/v3.8.10)

```bash
$ wget https://github.com/python/cpython/archive/refs/tags/v3.8.10.tar.gz
$ tar xf v3.8.10.tar.gz
$ sudo cp cpython-3.8.10/Lib/optparse.py /usr/lib/python3.8/optparse.py
```

解決

```bash
$ hoge

Command 'hoge' not found, did you mean:

  command 'hose' from deb netpipes (4.2-8build1)

Try: sudo apt install <deb name>
```
TypeScriptの関数とインターフェースのメソッド実装における割り当てルールの違い

微妙に直感に反する仕様なのでメモ。

## 環境

TypeScript v4.5.5

## 詳細

```ts
function foo(arg: (arg: number | string) => number | string) {};

foo((arg: number | string | boolean): number => {return 1}); // OK
foo((arg: number | string | boolean): number | string | boolean => {return 1}); // 戻り値の型が広がるのは駄目
foo((arg: number): number => {return 1}); // 引数の型が狭まるのも駄目

interface I {
  bar(arg: number | string): number | string;
}

// 関数の割り当てルールと同様に OK
class A implements I {
  bar(arg: number | string | boolean): number {
    return 1;
  }
}

// B.bar() の戻り値の型が、I.arg() の戻り値の型より広がるのは駄目 → 関数の割り当てルールと同じ
class B implements I {
  bar(arg: number | string | boolean): number | string | boolean {
    return 1;
 }
}

// コンパイルエラーにならない！
// C.bar() の引数 arg の型が、I.arg() の引数 arg の型より狭まっても良い → 関数の割り当てルールと異なる
class C implements I {
  bar(arg: number): number {
    return 1;
  }
}
```
Windows11のWSL2でGPUを認識させてPyTorchを使えるようにする

# 記事の目的
Windows 11 の WSL2 で深層学習環境を構築する過程で必要となった作業について、類似記事はありますが Windows 10 のものが多いので、2022年1月30日時点での情報をまとめておきます。

# 実行環境

- Windows 11
- Ubuntu 20.04 on WSL2
- RTX 3060
- CUDA Toolkit 11.6
- Python 3.8
- PyTorch 1.10.2

# 実行手順
## 1. NVIDIA Drivers for CUDA on WSL のインストール

まず、Windows 側にドライバのインストールをします。
[CUDA on Windows Subsystem for Linux (WSL)](https://developer.nvidia.com/cuda/wsl) 内の [Get CUDA Driver](https://developer.nvidia.com/cuda/wsl/download) に飛ぶと、GEFORCE DRIVER for Windows 11 / Windows 10 があるのでダウンロードして実行し、インストールします。

## 2. CUDA Toolkit のインストール

次に、WSL2 内の Ubuntu に CUDA Toolkit をインストールしていきます。
[CUDA Toolkit Downloads](https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&Distribution=WSL-Ubuntu&target_version=2.0&target_type=deb_local) に飛んで以下の図のように Select Target Platform を選択してくと、最新版の Toolkit のコマンドを取得できます。
特に `Distribution` では `WSL-Ubuntu` を選ぶのを間違えないように気を付けてください。
![スクリーンショット 2022-01-30 011515.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542065/d4d4ebb8-5e32-c846-6434-c09536a08bc9.png)
CUDA Toolkit 11.6 で `Installer Type` を `deb (network)` にした場合は以下のようなコマンドになります (ページ内で表示されるコマンドの方が確実だと思います)。

```
$ wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin
$ sudo mv cuda-wsl-ubuntu.pin /etc/apt/preferences.d/cuda-repository-pin-600
$ sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/7fa2af80.pub
$ sudo add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/ /"
$ sudo apt-get update
$ sudo apt-get -y install cuda
```

コマンドを実行することで、Ubuntu に CUDA がインストールされます。

## 3. PyTorch のインストール

機械学習環境として使えることを確認するため、PyTorch で動作確認をできるようにします。
[PyTorch 公式サイト](https://pytorch.org/)の INSTALL PYTORCH でまた選択していくことで、コマンドを取得し、Ubuntu で実行します。
`Compute Platform` について、今回インストールしている `CUDA 11.6` は無かったのですが、 `CUDA 11.3` で実行することができました。
![スクリーンショット 2022-01-30 012654.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542065/24736337-a991-30c1-94c4-f888ed603fa2.png)
こちらも参考までにコマンドを載せておきます。

```
$ pip3 install torch==1.10.2+cu113 torchvision==0.11.3+cu113 torchaudio==0.10.2+cu113 -f https://download.pytorch.org/whl/cu113/torch_stable.html
```

## 4. PyTorch で GPU の動作確認

Ubuntu 内で以下の通り Python を実行し、`True` が返ってくれば Ubuntu 内の PyTorch で GPU を使うことが出来ています！

```
$ python
>>> import torch
>>> print(torch.cuda.is_available())
True
```

# まとめ

Windows 10 だと必要だった設定のいくつかが不要になっており、11 になって便利さが増しています。
WSL2 上の Ubuntu で深層学習ができてしまう便利な時代が来たなーという感じがします。

# 参考

- [待ってました CUDA on WSL 2](https://qiita.com/ksasaki/items/ee864abd74f95fea1efa)
- [WSL2のUbuntuにCUDAをインストールしてPyTorchを動かす](https://takake-blog.com/wsl-nvidia-cuda/#WSLPyTorch)
M1 MacでビルドしたイメージをFARGATEで使おうとした時の'exec user process caused: exec format error' の対処法

# exec user process caused: exec format error
M1 MacでビルドしてECRにプッシュしたnodejsのイメージをタスク定義に使用してFARGATEでコンテナを立ち上げようとしたところ、このエラーに遭遇。
#解決法
ローカルでイメージをビルドする時のコマンドを以下に変更することで問題なくFARGATEでコンテナを立ち上げることができた。

```shell
docker buildx build --platform=linux/amd64 -t <image-name> .
```
#参考
FARGATEがおそらくIntel x86-64 アーキテクチャの上で動いているのに対して、M1MacがARMアーキテクチャの上で動いているのが問題。

https://stackoverflow.com/questions/67361936/exec-user-process-caused-exec-format-error-in-aws-fargate-service
テキストファイルのBOM(Byte Order Mark)とは

##■BOM(Byte Order Mark)とは
Unicodeで書かれたテキストファイル(～.txt,～.csvとか)がUnicodeで書かれていることを示すもの。ファイルの先頭の数バイトに付与される。

##■文字コード:UTF-8を示すBOM
ファイルの先頭の3バイトに「0xEF 0xBB 0xBF」を付与することで、これが文字コード:UTF-8であることを示すBOMとなる。

##■BOMを付与する利点(個人的に)
Excelでテキストファイルを開く際、Excelは標準で入力ファイルを文字コード:SJIS(Shift-JIS)として開くらしいため、BOM無しの文字コード:UTF-8で作成されたテキストファイルは文字コード:SJIS(Shift-JIS)として開かれるため文字化けする。しかし、BOM付きの文字コード:UTF-8で作成されたテキストファイルであればExcelもUTF-8で書かれたものと解釈し開くため文字化けせずに開くことができる。
【Heroku】Github Actionsを利用してHerokuへ自動デプロイ

# 初めに

適当に作った React x Rails のアプリを heroku にデプロイしたはいいが、デプロイするのに一々コマンドを打つのがめんどくさくなった。
GitHub actions を利用して自動的にデプロイさせます。

### やりたいこと

GitHub actions を利用して heroku へ自動デプロイ
docker を利用する(heroku.yml を使う)
フロントエンドとバックエンドはサブディレクトにあり、それぞれに heroku アプリを作成

# 本文

## heroku.yml

heroku アプリを docker で動かすには、heroku.yml を書く必要があります。
あと起動時のコマンドなどが設定できます。

```yaml:frontend/heroku.yml
setup:
  config:
    NODE_ENV: production
    NPM_CONFIG_PRODUCTION: false
build:
  docker:
    web: Dockerfile
  config:
    WORKDIR: frontend
    NODE_ENV: production
run:
  web: yarn global add serve && serve -s build

```

```yaml:backend/heroku.yml
setup:
  addons:
    - plan: jawsdb
  config:
    LANG: en_US.UTF-8
    RACK_ENV: production
    RAILS_ENV: production
    RAILS_LOG_TO_STDOUT: enabled
    RAILS_SERVE_STATIC_FILES: enabled
build:
  docker:
    web: Dockerfile
run:
  web: pumactl start

```

## GitHub actions

ルート直下に.github、ディレクトリその下に workflow ディレクトリを作成
そこに heroku-backend.yml と heroku-frontend.yml を作成
heroku の APIkey とメールアドレスが必要になります。[ダッシュボードから取得](https://dashboard.heroku.com/account)
GitHub actions の secrets の設定方法は[こちら](https://docs.github.com/ja/actions/security-guides/encrypted-secrets)

```yaml:.github/workflow/heroku-backend.yml
name: Heroku backend deploy

on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: akhileshns/heroku-deploy@v3.12.12
        with:
          heroku_api_key: ${{secrets.HEROKU_API_KEY}} #herokuのAPIのkey
          heroku_app_name: 'coffee-oma-backend' #herokuアプリの名前
          heroku_email: ${{secrets.HEROKU_EMAIL}} #アカウントのメールアドレス
          appdir: "backend"　#サブディレクトリ名
          stack: "container"　#これがないとheroku.ymlを参照されません
```

```yaml:.github/workflow/heroku-frontend.yml
name: Heroku frontend deploy

on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: akhileshns/heroku-deploy@v3.12.12
        with:
          heroku_api_key: ${{secrets.HEROKU_API_KEY}}
          heroku_app_name: 'coffee-oma-frontend'
          heroku_email: ${{secrets.HEROKU_EMAIL}}
          appdir: "frontend"
          stack: "container"

```

これで master にマージされたら actions が走り、heroku にデプロイされます。

# まとめ

最近 GitHub actions を使い始めましたが他の CI/CD サービスよりわかりやすい気がします。
gorilla/csrfのオリジン間APIの実装とCORSエラー

バックエンドをGoでフロントエンドをReactでアプリを作成しており、CSRF攻撃の対策のためgorilla/csrfを導入しようとしたのですが、CORS関係でエラーが頻発しました。
この記事では、Reactは使わず、goで立ち上げた仮想フロントエンドサーバーにaxiosを入れて解説します。

gorilla/csrfライブラリの公式
https://github.com/gorilla/csrf#javascript-applications

実装結果は下記の通りです。

```sh:ファイル構成
.
├── back
│   └── main.go
├── front
│   ├── index.html
│   └── main.go
├── go.mod
└── go.sum
```

```go:front/main.go
package main

import (
	"log"
	"net/http"
	"text/template"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
		t, _ := template.ParseFiles("index.html")
		t.Execute(w, nil)
	})

	log.Fatal(http.ListenAndServe(":3000", nil))
}
```
```html:front/index.html
<!DOCTYPE html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
  <button onclick="submit()">Post Data</button>
  <script>
    async function submit() {
      const instance = axios.create({
        baseURL: "http://localhost:8000/api",
        withCredentials: true, // Cookieのやりとりをオンにする
      })

      // トークンを取得
      const response = await instance.get("/token")

      // 受け取ったトークンをX-CSRF-Tokenヘッダーに付ける
      instance.defaults.headers.post["X-CSRF-Token"] = response.headers["x-csrf-token"]
      instance
        .post("/post", new URLSearchParams({say: "The World! Stop time!"}))
        .then(res => alert(res.data))
    }
  </script>  
</body>
</html>
```
```go:back/main.go
package main

import (
	"fmt"
	"net/http"

	"github.com/gorilla/csrf"
	"github.com/gorilla/mux"
)

func main() {
	r := mux.NewRouter()
	csrfMiddleware := csrf.Protect([]byte("32-byte-long-auth-key"))

	api := r.PathPrefix("/api").Subrouter()
	api.Use(csrfMiddleware)
	api.HandleFunc("/token", token).Methods(http.MethodGet)
	api.HandleFunc("/post", post).Methods(http.MethodOptions) // プリフライトを受け付ける
	api.HandleFunc("/post", post).Methods(http.MethodPost)

	http.ListenAndServe(":8000", r)
}

func token(w http.ResponseWriter, r *http.Request) {
	// オリジン間リソース共有と言ったらこれが無いと始まらないよね
	w.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000")
	// X-CSRF-Tokenをフロント側で受け取れるようにする
	w.Header().Set("Access-Control-Expose-Headers", "X-CSRF-Token")
	// フロント側のブラウザにクッキーがセットされるようにする
	w.Header().Set("Access-Control-Allow-Credentials", "true")
	// トークンをセット
	w.Header().Set("X-CSRF-Token", csrf.Token(r))
}

func post(w http.ResponseWriter, r *http.Request) {
	// オリジン間リソース共有と言ったらこれが無いと始まらないよね
	w.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000")
	// 受け入れるヘッダーを指定。特にX-CSRF-Tokenは忘れずに。
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token")
	// プリフライトのときにPOSTメソッド許可を返す。
	w.Header().Set("Access-Control-Allow-Methods", "POST")
	// Cookieを受け入れる。
	w.Header().Set("Access-Control-Allow-Credentials", "true")

	fmt.Fprint(w, r.FormValue("say"))
}
```

動作確認

```sh:zsh
$ go run front/main.go
$ go run back/main.go
```
http://local:3000
をブラウザで開いて、ボタン押してコンソールエラーが無ければ、OKです。
![てsってst.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513214/ea763e8b-eaf5-a8fd-329c-0de38c461865.png)

以上です。