OmniAICreator/Qiita-1.07M huggingface dataset:
htaccessでstaging環境にのみIP制限をかける

# 今回やりたいこと

下記の環境を用意しており

- 本番環境
- staging環境
- local開発環境

staging環境にのみIP制限をかけたい

# htaccessでやりたいこと

- 特定のip、本番、localだと認証無しでアクセスできる
- 上記じゃない場合、basic認証をとおす

# htaccess記述内容

```
Order Deny,Allow
# Denyを評価したあとにAllow評価。今回は下記のDeny from allで一度全部拒否にしてその後でAllowを設定している。Satisfy Anyを最後につけることで一度DenyされていてもAllowに入っていれば通るようになっている
Deny from all
 
# 接続先ホスト名が www.example.com または localhost の場合の環境変数 NO_AUTH を定義
SetEnvIf HOST "^(www\.example\.com|localhost)$" NO_AUTH
# 環境変数（接続先ホスト名）による許可
Allow from env=NO_AUTH
 
# Basic認証      
AuthType Basic
AuthUserFile /home/xxxx/.htpasswds/passwd
AuthName "Login Password Required"
Require valid-user  
 
# IP アドレスがマッチする場合も許可する場合
# Allow from xxx.xxx.xxx.xxx
 
# Allow か Require いずれかの条件にマッチすれば許可
Satisfy Any
```

参考にした記事
https://www.tam-tam.co.jp/tipsnote/program/post7085.html

- 本来deny from allはあってもなくてもこの場合処理変わらないがわかりやすくするために記述されている
- http://koseki.hatenablog.com/entry/20100913/ApacheAccessControl
- `Satisfy Any`はどれかの条件にあっていればいい、`Satisfy All`はすべての条件をクリアしないとアクセスできない。
- `Satisfy Any`はどこにかいてもいい
- www\.example\.comの\は直後の正規表現をエスケープしている（ https://murashun.jp/article/programming/regular-expression.html ）
Same Origin Policy とは

## 勉強前イメージ

同一ドメインのなにかの認識
CORSと似たようなもん？なのかな？

## 調査

### Same Origin Policy とは

日本語にすると、同一生成元ポリシーといって
あるオリジンで読み込まれたリソースが異なるオリジン(クロスオリジン)のリソースへの通信・アクセスに制約をかけるものです。

異なるオリジンのリソースへの通信・アクセスに制限をかける目的としては、
クロスサイトスクリプティング(XSS)を防止するためになります。
XSSに関しまして、 [こちら](https://qiita.com/miyuki_samitani/items/f9d7feaf06aff447c691) で記載しておりますので、ご確認ください

### CORS とは何が違うの？

- Same Origin Policy とは

あるオリジンで読み込まれたリソースが
異なるオリジンのリソースへの通信に制限をかけるもの

- CORS とは

ブラウザで見ているページとは違うオリジン(ドメイン)からデータの取得を許可する仕組みのこと

- 要するに・・・

`Same Origin Policy` で、別オリジンデータへのアクセスに制限をかけられているが
`CORS` で、別オリジンデータへのアクセスを許可する、というもの。

## 勉強後イメージ

CORSやるより先にSame Origin Policy勉強しといたほうが良かったと思った。

## 参考

- [CORS & Same Origin Policy 入門](https://yamory.io/blog/about-cors/)
macbook の firmware パスワードが解除できずにハマった話　〜解決済み〜


## OS アップグレードで、firmware パスワードの解除ができなくなった
![recovery mode](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604208/dbe59f1b-c432-4516-8ba1-08c4bfd9523d.png)

### 対象者
以下に該当する方は、ぜひ試してみてください。

1. OS アップグレード後に、firmware にログインできなくなった
2. firmware パスワードに記号を使っている
3. firmware パスワードが合っていると確信している
4. JIS キーボード配列の macbook を使っている  


### 原因と解決方法
ここを見た方は、既にお困りの方だと思うので、さっさと結論を書きます。

OS アップグレード後、キーボード配列が **US キーボード** に置き換わっています。
US キーボード をお持ちでない方は、Googleなどで [ **US キーボード** ] と調べれば、 
JIS キーボード と US キーボード のキー配列の違いは、すぐわかると思います。

JIS キーボードのままで大丈夫ですので、キー配列を照らし合わせながら入力してみてください。

## 悲しいストーリー

macOS **Catalina** だったときに、firmware にパスワードをかけていました。
**Big Sur** にアップデートしてから、しばらく経った後、**リカバリーモード** <kbd><kbd>⌘ cmd</kbd> + <kbd>R</kbd></kbd> を使おうとしたところ何とログインできないではありませんか...!!

パスワードを失念している可能性は十分ありましたが、パスワード管理ツールにも登録してあったので間違えるはずはありません。

思いつく限りのパスワードを入力しても解除できなかったため、[Apple サポート](https://www.apple.com/jp/contact/) に助けを求めました。

非常に気持ちの良い対応をしていただけましたが、残念ながらこの問題は解決せず。
「購入証明を持って Apple Store 等の Apple サービスプロバイダに行くように」促されました。

...と行っても、私の住んでいる近隣にそんな高度な施設はないのです。


もう少しだけ足掻いてみるために、使わなくなったキーボード達を引っ張り出してきて試したところ US キーボードでならログインできたという話でした。

めでたし、めでたし。


## おわりに

同じ現象で泣きそうになった方の参考になれば幸いです。
Git pushできない　エラー発生対応

#Git pushできない　エラー発生対応
push時にエラーが発生しその時の対応を記録。

```csharp
ec2-user:~/environment/〇〇 (main) $ git push origin main
～～～～～～～省略～～～～～～～～～～～～～～～～～～～～～～～～～～～

 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'git@github.com:〇〇/〇〇.git'

～～～～～～～省略～～～～～～～～～～～～～～～～～～～～～～～～～～～
```

#対処法
リモートリポジトリを再設定する必要がある。GitHubのリポジトリの、「Initialize this repository with a README」が働いているため。


①リモート URL を削除するには git remote rm コマンドを打ち込む

```
$ git remote rm origin
```

②GitHubのリポジトリを、「Initialize this repository with a README」のチェックを入れずに作り直しましょう。

③リモートリポジトリを再設定

```
$ git remote add origin SSHを入力
```

④push使用

```
git push origin main
```

自分がこれで改善できたので記録しています。
Gitlab-CI でartifactのパス階層を浅くしたい

## 概要
`gitlab-ci.yml` ではアーティファクト設定をすることができる。以下のような感じ。

```yaml
pdf:
  script: xelatex mycv.tex
  artifacts:
    name: "app"
    paths:
      - hoge/moge/piyo/
    expire_in: 1 week
```

pathsにディレクトリを指定すると、自動でzipにしてくれるが、そのzipファイル内に、pathsに記載したパスすべてが含まれる仕様となっている。上の例だと、app.zipを解凍すると、`hoge/moge/piyo/` というパス階層が現れるので、じゃまくさい。

## 対処法
単純にビルドファイルを移動することで対応した。

```yaml
build:
  stage: build
  script:
    - ..
    - (build/path/に成果物ができたとする)
    - mkdir Artifact
    - robocopy build/path Artifact /s /e & set errorlevel=0
  artifact:
    - paths: Artifact
```
ランナーがLinuxならrobocopyじゃなくて、mv で問題なさそう。

## 参考　
- https://gitlab.com/gitlab-org/gitlab-runner/-/issues/1057
Flutter webでクエリストリングを考慮したルーティング

Flutter webでクエリストリングを考慮したルーティングの方法を紹介します。
私の調査不足のせいかサクッと実現する方法が見つからなかったので以下のような実装になりました。

# 問題
以下のようなルーティング設定をした場合、 `/hoge` でアクセスすればHogeScreenが表示されます。
しかし、 `/hoge?a=b` でアクセスした場合は、HogeScreenは表示されずDefaultScreenが表示されてしまいます。
期待する動作としては、クエリストリングの含まれたリクエストでも `/hoge` というパス部分でルーティングしてほしいです。

```dart
MaterialApp(
      // 略
      home: DefaultScreen(),
      routes: {
        "/hoge": (context) { 
          return HogeScreen();
        },
        "": (context) => DefaultScreen()
      },
    );
```

# 解決方法
以下のように `onGenerateRoute` を記述することでパス部分のみに依存したルーティングが可能になります。

```dart
MaterialApp(
      // 略
      home: DefaultScreen(),
      onGenerateRoute: (setting) {
        print(setting);
        String? name = setting.name;
        if (name == null ){
          // TODO
          return null;
        }
        final uri = Uri.parse(name);
        print(uri.path);
        print(uri.pathSegments);
        print(uri.queryParameters["xxx"]);
        if (uri.path == "/hoge){
          return MaterialPageRoute(builder: (context){
            return HogeScreen();
          });
        } else {
          return MaterialPageRoute(builder: (context){
            return DefaultScreen();
          });
        }
      },
    );
```


# 参考
https://medium.com/flutter-community/advance-url-navigation-for-flutter-web-d8b5f2d424e6
【Javascriptの基本的な文法を学ぼう①】デベロッパーツール編

#はじめに
今回からは複数回に分けて`Javascript`についての基本的な文法を見ていこうと思います。
ではなぜ今回Javascriptの基本的な文法をアウトプットしようと思ったかというと、`私自身、プログラミングを初めて学んだ際、難しいと思い、挫折しかけた言語の一つだからです。`
しかし、Javascriptを学ぶことで、`ユーザーにとって利用しやすいWebページを作成することができます。`
また、以下の表をご覧ください。
>
![](https://i.gyazo.com/6eebb41f81f7c37918b7f915f528a026.png)

この表は、簡単に言うとよく使われているプログラミング言語のまとめのような表なのですが、`Javascriptは７０％近くのアプリ開発に使用されており、需要の高い言語とも言えます。`
これらのことから、今回は「難しいけど、需要の高い言語」であるJavascriptの基本的な文法をアウトプットしていきます。

#この記事を読むべき人
・プログラミングを学んでみたいと思っている人
・Javascriptを学んでいる初学者
・３ヶ月前の自分

#Javascriptが実行できるツール
JavaScriptを学ぶ際に、都度テキストエディタでファイルを用意して基本文法を試すのは手間です。しかしJavascriptにはコードを実行したらすぐに結果が表示されるツールがあり、デベロッパーツールによって、それが実現できます。

####`デベロッパーツール`
ブラウザ開発者ツール、検証ツールなどとも呼ばれます。一般的なブラウザに付属し、誰でもすぐに使うことができます。デベロッパーツールでは主に以下のようなことができます。

・表示しているサイトのHTMLの要素の確認・編集
・表示しているサイトのCSSの確認・編集
・JavaScriptの実行

HTMLやCSSの確認・編集はElements（エレメンツ）パネルで操作することができ、JavaScriptの実行はConsole（コンソール）パネルにて行うことができます。

#デベロッパーツールの使い方を学ぼう
それでは実際にデベロッパーツールを使ってみましょう。使い方はとても簡単です。
1.ブラウザ上で二本指クリックする
2.「検証」を選択する
これで、デベロッパーツールを開く事ができます。

#コンソールパネルの使って文字を表示させてみよう

続いて、コンソールパネルでJavaScriptのコードを実行する方法を学びましょう。
本来は、テキストエディタで用意したファイルにソースコードを記述して、JavaScriptを実行することもできます。しかし、今回は手軽に練習をするため、コンソールにJavaScriptの記述をし、実行していきます。
コンソールに文字を表示させるには`console.log`というメソッドを使います。

>
######コンソール
```javascript
console.log("Hello JavaScript")
```

>
上記のコードをコンソールで「Enterキー」を押して実行してみて、以下のように結果が表示されていれば成功です。
![コンソール](https://i.gyazo.com/ee44292fdc0a127273ddc4b1e5aa14a7.png)

#おわりに
第一回目はJavascriptの基本的な文法を書く準備段階のようなことをしました。
次回からは複数回に分けてJavascriptの基本文法を見ていきたいと思いますので、次回の記事もぜひ見てください！
Vue でのレスポンシブ対応に v-media-query を使う

# はじめに
Web サイトのレスポンシブ対応のため、 Vue で Media Query を扱えるパッケージを探したところ、直近で最新のものが v-media-query だったので使ってみた（もっと探せば他にあるかもしれません）
https://www.npmjs.com/package/v-media-query

# 実際に使ってみた
## 基本的な使い方
1. 導入する

    ```terminal
    $ npm install v-media-query
    ```

1. Vue で使えるようにする

    ```js
    import vMediaQuery from 'v-media-query'
    
    Vue.use(vMediaQuery.default)
    ```

1. `v-if` に条件を記述する

    ```vue
    <div v-if="$mq.resize && $mq.above('767px')"></div>
    ```

ビューポートのサイズ変更後、 `width > 767px` となっている場合にこの要素がレンダされる

## カスタムメソッド
上記の場合、条件にサイズを直接書くことになるため、複数箇所で利用する場合、利便性に欠ける
カスタムメソッドを定義しておくと、同じ値を複数箇所で記述する必要がなくなる

```js
import vMediaQuery from 'v-media-query'

Vue.use(vMediaQuery.default, {
  methods: {
    abovePc() {
      // width > 767px
      return vMediaQuery.methods.above('767px')
    }
  }
})
```

```vue
<div v-if="$mq.resize && $mq.abovePc()"></div>
```
Amazon S3 ライフサイクルルールを利用して特定タグを持つオブジェクトを削除する

## 概要

- 特定のタグを付与したオブジェクトを[S3 ライフサイクルルール](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/object-lifecycle-mgmt.html)で削除
- LambdaなどからAPIでオブジェクト削除を実行する際は、Lambdaの実行時間等が掛かりますが、ライフサイクルルールを使うことで無料で削除可能
  - なお、削除までに少なくとも1日掛かります。

## ライフサイクルルールの設定

ライフサイクルルールを設定したいAmazon S3バケットをコンソールで開きます。
ライフサイクルの作成を選択し、以下のように空欄を埋めていきます。なお、ここではオブジェクトに`is_translated: True`というタグがあった場合、ルールの対象とします。  

![20210519171841.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484840/13982492-77c5-45c4-8dbd-a234376c7db4.png)
![20210519171849.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484840/dc8177dc-787b-c65b-6dcb-a5b0d45c0563.png)

このルールにより、1日でオブジェクトの有効期限切れと設定すると、最終更新日から1日過ぎた日の午前9時（JST）に削除フラグが付与され、削除されます。（バージョニングを有効にしている場合、完全には消えません。  

> - アクションが実行される、オブジェクト作成からの日数です。
> - Amazon S3 は、ルールに指定された日数をオブジェクトの作成時間に加算し、得られた日時を翌日の午前 00:00 UTC (協定世界時) に丸めることで、時間を算出します。たとえば、あるオブジェクトが 2014 年 1 月 15 日午前 10 時 30 分 (UTC) に作成され、移行ルールに 3 日と指定した場合、オブジェクトの移行日は 2014 年 1 月 19 日 0 時 0 分 (UTC) となります。  
(https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/intro-lifecycle-rules.html)

## 実際に見てみる

実際にバケットにルールを適応して、オブジェクトにタグを付与します。そうすると、以下のように有効期限日が表示されます。
![20210519173924.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484840/a2845e7e-60c8-50ab-0561-aed41469e401.png)
09:00 JSTに削除と書いてありますが、実際はかなり遅延があるようです。私が試したときは、約3~5時間ほどの遅延がありました。
Dosコマンドでファイル、フォルダを移動したい

## 概要
- windowsのdosコマンドで、Linuxのmv相当の機能を探した。

## 結論
- move か robocopy を使うべし
- move
    - moveはサブフォルダを移動できないという制約がある
    - ファイルだけならOK
- robocopy
    - 基本的にはコピーするコマンドだが、/move オプションをつけることで移動できる
    - サブフォルダと空フォルダを対象にするには、/s /e をつける
 
## 参考
- https://www.ne.jp/asahi/hishidama/home/tech/windows/bat.html
素晴らしい数式

Answersで遊んでいると、数式の質問が多いことに気づきます。その中の回答で、えええ思いつかないという素晴らしい数式が披露されることもあります。大概は力技で解決されているんですがね。

その素晴らしい数式を発見次第まとめていきたいと思います。

#BLANKVALUEを使う

数式は加工せず、そのままを載せています。悪意はないですよ。単に改行の入れ方も見欲しい。
いい数式はデバックがしやすいのです。単にうごけばいいというわけでないです。


質問者の数式（たぶん動きません）

```
IF (NOT (ISBLANK(WW_VP_Override__c)),WW_VP_Override__c,
(OR(ISPICKVAL(Type,"Contracted Paid Renewal"),ISPICKVAL(Type,"Renewal Business"),ISPICKVAL(Type,"Contracted Renewal"), ISPICKVAL(Type,"Expansion Business"),ISPICKVAL(Type,"New Business"),ISPICKVAL(Type,"Services"),ISPICKVAL(Type,"Paid POV") "N/A"))
```

回答者さんの数式

```
BLANKVALUE(WW_VP_Override__c,
CASE( Type,
"Contracted Paid Renewal", "N/A",
"Renewal Business", "N/A",
"Contracted Renewal", "N/A", 
"Expansion Business", "N/A",
"New Business", "N/A",
"Services", "N/A",
"Paid POV","N/A",
NULL))
```

Caseを使うやり方までは分かったのですが、BLANKVALUEは思いつきませんでした。IFでネストするより見やすいし、もしかしたらコンパクトになっているかもしれません。数式が大きすぎる時にも使える技かもしれないです。

# Formula for Shipping and Physical (Mailing State)

https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000C6A87SAF

```
IF(CONTAINS("AL:AK:AZ:AR:CA:CO:CT:DE:FL:GA:HI:ID:IL:IN:IA:KS:KY:LA:ME:MD:MA:MI:MN:MS:MO:MT:NE:NV:NH:NJ:NM:NY:NC:ND:OH:OK:OR:PA:RI:SC:SD:TN:TX:UT:VT:VA:WA:WV:WI:WY", ShippingState), ShippingState, 
CASE(ShippingState,
"Alabama", "AL",
"Alaska", "AK",
"Arizona", "AZ",
"Arkansas", "AR",
"California", "CA",
"Colorado", "CO",
"Connecticut", "CT",
"Delaware", "DE",
"Florida", "FL",
"Georgia", "GA",
"Hawaii", "HI",
"Idaho", "ID",
"Illinois", "IL",
"Indiana", "IN",
"Iowa", "IA",
"Kansas", "KS",
"Kentucky", "KY",
"Louisiana", "LA",
"Maine", "ME",
"Maryland", "MD",
"Massachusetts", "MA",
"Michigan", "MI",
"Minnesota", "MN",
"Mississippi", "MS",
"Missouri", "MO",
"Montana", "MT",
"Nebraska", "NE",
"Nevada", "NV",
"New Hampshire", "NH",
"New Jersey", "NJ",
"New Mexico", "NM",
"New York", "NY",
"North Carolina", "NC",
"North Dakota", "ND",
"Ohio", "OH",
"Oklahoma", "OK",
"Oregon", "OR",
"Pennsylvania", "PA",
"Rhode Island", "RI",
"South Carolina", "SC",
"South Dakota", "SD",
"Tennessee", "TN",
"Texas", "TX",
"Utah", "UT",
"Vermont", "VT",
"Virginia", "VA",
"Washington", "WA",
"West Virginia", "WV",
"Wisconsin", "WI",
"Wyoming", "WY",
"Other"))
```
Giới thiệu về Công ty Cổ phần công nghệ New Tech Pharm

Công ty Cổ phần công nghệ New Tech Pharm là một công ty đang lớn mạnh không ngừng đặc biệt về lĩnh vực Marketing online Dược phẩm với nhiều sản phẩm có thương hiệu trên thị trường hiện nay như: Narcugo, Nacurgo Gel, Lovin skin, Migrin,…
Với tiêu chí lấy khách hàng là trung tâm, mỗi một sản phẩm đều là tâm huyết của Ban lãnh đạo Công ty và tập thể nhân viên công ty. New Tech Pharm luôn cung cấp đầy đủ thông tin khoa học, bằng chứng khoa học nhằm chứng minh hiệu quả của sản phẩm, từ đó tạo mối liên kết giữa khách hàng với sản phẩm cũng như công ty.

Công ty CP Công nghệ New Tech Pharm là công ty chuyên về lĩnh vực Marketing online Dược với nhiều sản phẩm nổi tiếng như: Narcugo Gel, Nacurgo, Lovin skin, Migrin
Email: cskh@newtechpharm.vn
Hotline: 18006626
Địa chỉ: Tầng 5, Tòa nhà Comatce Tower, số 61 phố Ngụy Như Kon Tum P. Nhân Chính, Thanh Xuân, Hà Nội
https://newtechpharm.com/gioi-thieu/

NewTechpharm trên các Mạng xã hội social:
https://www.facebook.com/ctcpcn.newtechpharm
https://twitter.com/newtech_pharm
https://www.pinterest.com/newtechpharm/
https://www.linkedin.com/in/newtechpharm/
https://ameblo.jp/newtechpharm/
https://about.me/newtechpharm/
https://500px.com/p/newtechpharm
https://www.instagram.com/newtechpharm
https://www.producthunt.com/@newtechpharm
https://angel.co/company/newtechpharm/
https://www.behance.net/newtechpharm/
https://newtechpharm.blogspot.com/
https://www.blogger.com/profile/08285869847634278491
https://social.msdn.microsoft.com/Profile/newtechpharm
https://www.flickr.com/people/newtechpharm/
https://disqus.com/by/newtechpharm/
https://www.openstreetmap.org/user/newtechpharm
https://gitlab.com/newtechpharm
https://newtechpharm.business.site/
https://www.deviantart.com/newtechpharm
https://www.youtube.com/channel/UCO9HJ6WkJU85wrZidE57z3A
https://www.mixcloud.com/newtechpharm/
https://hub.docker.com/u/newtechpharm
https://github.com/newtechpharm
https://bitbucket.org/newtechpharm/
https://hub.docker.com/orgs/ctcpnewtechpharm/
https://gumroad.com/newtechpharm
https://fliphtml5.com/homepage/bwnso
https://profile.ameba.jp/ameba/newtechpharm
https://newtechpharm.mystrikingly.com/
http://newtechpharm.simplesite.com/
https://sketchfab.com/newtechpharm
Ruby、Ruby on Rails エラーが表示された場合

#エラーが表示された場合
プログラムの誤り（バグ）を見つけて修正する作業を「デバッグ（debug）」と呼びます。

#Routing Error
ルーティングのエラーです。主に2パターンがあります。

**①No route matches [GET] "/〇〇〇"**
「ルートが見つかりません」というエラーです。
この場合は、routes.rbでうまく定義できていないことが多い。
スペルミスなどの場合が多いためroutes.rbを開き、正しいスペルに修正。

**②Uninitialized constant booksController**
「booksコントローラが見つかりません」というエラーです。
books_controller.rbのファイル名や、記述内容にミスがある場合が多いです。

#ActionController::UnknownFormat
Viewファイルが正しく作成できていない場合は、「テンプレートが見つかりません」というエラーが表示されます。
このエラーが表示されたときは、ActionController::UnknownFormatの記述の後にある#〇〇〇の箇所を修正しましょう。

#Unknown action
「アクションが見つかりません」または「定義されていません」というエラー。
〇〇_controller.rbにtopアクションは定義しているか、 app/views/〇〇ディレクトリにtop.html.erbが置けているかを確認しましょう


・**アクションの名前が間違っている**
　　　　　　　or
・**アクションが定義されていない**　　　　　場合に発生します。

#ArgumentError
メソッドの引数が正しくない時や足りない時に発生するエラーです。
【エラー内容の解説】
**・Argument Error in books#〇〇**
⇒エラーが起きているアクションの場所を教えてくれています。その場所にまず移動してみよう。

**・First argument in form cannot contain nil or be empty**
First argument in form → フォームの中にある1番目の引数(〇〇〇)が
nil or be empty → 存在していない or 空っぽ

#RuntimeError in PostImages#index
以下のようなRefile.secret_keyのエラーが表示された場合は、キー情報をconfig/initializers/application_controller_renderer.rbに記述し、設定する。

![図14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1514036/a6b6b383-3ad5-b9ac-4cd0-b38be2df0d24.png)

#NameError in Todolists#show
この場合は、インスタンス変数の設定に誤りがあります。
![図15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1514036/e0e5851e-65c6-7690-1084-92b1345a97f1.png)


今回はコントローラーで、

```
list= list(params[:id])
```
↓に修正する

```csharp
@list= list(params[:id])
```

#NoMethodError in Users#show

![図1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1514036/68e3de6e-4ccf-6814-a663-ab2927dd4cd5.jpeg)

Userコントローラのshowアクションで定義されていないメソッドがある。
＃９と記載されているところがエラーの発生しているところ。
name_missというメソッドの定義がされていないのが問題と分かります。

【原因】
Userモデルのカラムにname_missというカラムが設定されていなかった

【解決策】
①name_missというカラムを追加する
②name_missが打ち間違えだった。nameと定義しなおす。name_missを削除する
JetsonにVSCodeをインストールする　JetsonNX Jetpack4.5

Jetson上にVSCodeをインストールする方法が分かりづらかったので記録。
ビルドとか不要でインストールできます。
結果的には、sshで別マシンのVS-codeからアクセスした方が快適。
##VS-codeのインストール

git上の JetsonHacksNanoに記載があった。NanoでJetpack4.4.1でテストしたと記載されている。
https://github.com/JetsonHacksNano/installVSCode
```git clone https://github.com/JetsonHacksNano/installVSCode
cd installVSCode
./installVSCodeWithPython.sh #pythonの拡張も入れるとき（自分）
./installVSCode.sh　#拡張無し
```
以下を参考にメニューバーを表示させる。
https://qiita.com/koppe/items/64d155bc7814441920f9#%E3%83%A1%E3%83%8B%E3%83%A5%E3%83%BC%E3%83%90%E3%83%BC%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B

機能拡張ctrl + shift + p で日本語パックを選ぶ。

以下のページも試しましたが、インストール失敗しました。
zenetio/Install-VScode-On-TX2
https://github.com/zenetio/Install-VScode-On-TX2
manimの作法 その58

#概要

manimの作法、調べてみた。
LaggedStartMap、使ってみた。

#サンプルコード

```
from manimlib.imports import *

class test(Scene):
	CONFIG = {
		"axes_config": {
			"x_min": 0,
			"x_max": TAU,
			"y_min": -1.5,
			"y_max": 1.5,
			"x_axis_config": {
				"tick_frequency": PI / 2,
				"unit_size": 1,
				"include_tip": False,
			},
			"y_axis_config": {
				"unit_size": 1,
				"tick_frequency": 0.5,
				"include_tip": False,
			},
		},
		"n_axes": 5,
		"trig_func": np.cos,
		"trig_func_tex": "\\cos",
		"bc_words": "Restricted by\\\\boundary conditions",
	}
	def construct(self):
		self.setup_little_axes()
		self.show_cosine_waves()
	def setup_little_axes(self):
		axes_group = VGroup(*[Axes(**self.axes_config) for n in range(self.n_axes)])
		axes_group.set_stroke(width=2)
		axes_group.arrange(DOWN, buff=1)
		axes_group.set_height(FRAME_HEIGHT - 1.25)
		axes_group.to_edge(RIGHT)
		axes_group.to_edge(UP, buff=MED_SMALL_BUFF)
		dots = TextMobject("\\vdots")
		dots.next_to(axes_group, DOWN)
		dots.shift_onto_screen()
		self.add(axes_group)
		self.add(dots)
		self.axes_group = axes_group
	def show_cosine_waves(self):
		axes_group = self.axes_group
		colors = [BLUE, GREEN, RED, YELLOW, PINK]
		graphs = VGroup()
		h_lines = VGroup()
		func_labels = VGroup()
		for k, axes, color in zip(it.count(1), axes_group, colors):
			L = axes.x_max
			graph = axes.get_graph(lambda x: self.trig_func(x * k * PI / L),color=color)
			graph.set_stroke(width=2)
			graphs.add(graph)
			func_label = TexMobject(self.trig_func_tex + "\\left(", str(k), "(\\pi / L)x\\right)", tex_to_color_map={
				str(k): color,
			})
			func_label.scale(0.7)
			func_label.next_to(axes, LEFT)
			func_labels.add(func_label)
			hl1 = DashedLine(LEFT, RIGHT)
			hl1.set_width(0.5)
			hl1.set_stroke(WHITE, 2)
			hl1.move_to(graph.get_start())
			hl2 = hl1.copy()
			hl2.move_to(graph.get_end())
			h_lines.add(hl1, hl2)
		words = TextMobject(self.bc_words)
		words.next_to(axes_group, LEFT)
		words.to_edge(UP)
		self.play(FadeIn(words), LaggedStartMap(ShowCreation, graphs,))
		self.play(Write(h_lines))
		self.play(FadeOut(h_lines))
		self.wait()
		self.play(words.next_to, func_labels, LEFT, words.to_edge, UP, LaggedStartMap(FadeInFrom, func_labels,lambda m: (m, RIGHT)))
		self.wait()



```

#生成した動画

https://www.youtube.com/watch?v=Ee1kQAVbPxg

以上。
CodePenのCSS PreprocessorでSCSSを指定

自分メモです('ω')

本日、ハンズオン的な爆速Webアプリ開発でCodePenを初めて使いました。リアルタイムプレビュー、すごく便利でした。作業後によく見ると、途中でデフォルトブラウザに引っ張られて意図したアカウントでサインアップできていないブラウザ側で成果物を作ってしまっていました。

これを本来のアカウント環境に移行した時に、「おやっ？」となった時の調査経緯です。

##事象

CodePenの「HTML」、「CSS」、「js」のコードをすべてコピペしました。結果↓（著作権フリーと信じています('ω')）
<img width="50%" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264253/9eecd73e-be65-7088-2c7d-56814803b8e5.png">

うーん、CSS周りが崩れていそうです。

##確認

本日のハンズオンから、以下順で確認していきます。

- コードのコピペミスは無いか
- ライブラリは同一のモノを設定できているか ← 怪しんでいる
- その他（今日触れなかった要素）

うーん、コピペし直しても状況は変わらず。HTML内のライブラリ読み込みは関係無いですよね。
続けて、CSSのライブラリ設定が怪しいと踏むも、何も拡張設定はしていなさそうです。↓
<img width="50%" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264253/56b0c06a-e3ed-0aca-7aa9-59341203fe3b.png">

JSのライブラリ等も特に設定はありませんでした。。

こうなると目視が頼りです('ω')

二画面を横に並べて、凝視すること一分、、

<img width="70%" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264253/e0043e30-790c-a82f-744f-0641a925bccd.png">

ここ、何か違う('ω')

<img width="70%" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264253/4e32a942-1d29-55e5-5f5d-8a6bf610d03a.png">

何やら、Pen Settingsの「CSS Preprocessor」という設定で、CSSの拡張言語にも対応させられるみたいです。
<img width="50%" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264253/ff3c8dac-fdb5-1ffc-e49e-e2e2e9daf1cc.png">

ここでSCSSを設定してあげることで、無事に意図した表示になりました！

##参考記事

まだまだ理解はしていないので、勉強していきます('ω')

https://qiita.com/mame_hashbill/items/e5f01d0f2523de6a13e5

https://qiita.com/fumu238/items/f73274aa1a188eb15794
【TypeScript】TypeScript の Genericsクラス


# Genericsクラス
* Genericsクラスは、クラスの中のメソッドの引数の型が統一していることのみを指定したいときに使います
    * stringか、numberか、objectか、指定せず、特定の型のみ受け取れるメソッドを定義できます


```ts
//Genericsクラス
class DataStorage<T> {
    private data: T[] = [];
   addItem(item: T) {
       this.data.push(item);
  }

  removeItem(item: T) {
    this.data.splice(this.data.indexOf(item), 1); 
  }

  getItems() {
    return [...this.data];
  }
}

//文字列のみを格納できる
const textStorage = new DataStorage<string>();
textStorage.addItem('cat1');
// textStorage.addItem(123); // NG

//numberのみを格納できる
const numberStorage = new DataStorage<number>();

//numberかstringを格納できる
const numberStorage = new DataStorage<number|string>();
numberStorage2.addItem('cat2'); // OK
numberStorage2.addItem(123); // OK
```

###問題点
* 全ての型を受け取れるようにすると、例えば参照型を受け取った時に、期待していない処理になってしまう、などの問題が発生する可能性があります

```ts

// 参照型であるObjectを格納した場合にremoveItemが動作しない
const objStorage = new DataStorage<object>();
objStorage.addItem({ name: 'Cat' });
objStorage.addItem({ name: 'Dog' });
objStorage.removeItem({ name: 'Cat' }); 
console.log(objStorage.getItems());          //Catが残っている！

```

* 上の例での問題点は、 `removeItem`メソッドは`indexOf`で  `item`を探す際に、渡す`item` が参照型であるので、参照先が同じオブジェクト(`item`)を渡せていないことです
* よって、最後の要素を削除してしまう仕様になっています

```ts
//略 
 removeItem(item: T) { 
    this.data.splice(this.data.indexOf(item), 1);  //見つからない場合-1を返し、最後の要素を削除してしまう
  }

//問題点
objStorage.addItem({ name: 'Cat' }); //追加
objStorage.removeItem({ name: 'Cat' }); //削除するのはアドレスが異なるオブジェクト

```


### primitive型のみを受け取るクラスに変更する
* そこでクラスの型を柔軟に変更し、目的に応じて制約を課すことができます
    * `class DataStorage<T extends string | number | boolean> { `
* クラスの中で、メソッド毎に独自のGenerics型を追加して制約を課すことも可能
* 型の柔軟性と安全性を同時に教授できます(^o^)★

```ts
// 解決方法

class DataStorage<T extends string | number | boolean> { //object型を許可しない
  private data: T[] = [];

  addItem(item: T) {
    this.data.push(item);
  }

  removeItem(item: T) {
    if (this.data.indexOf(item) === -1) { //itemが存在するか確認
      return;
    }
    this.data.splice(this.data.indexOf(item), 1); // -1
  }

  getItems() {
    return [...this.data];
  }
}
```

* 以下ように同じオブジェクトを指定することも可能です

```ts
const objStorage = new DataStorage<object>();
//定数に格納することで、primitive型のみで実行する
const obj = { name: 'Cat' };
objStorage.addItem(obj);
objStorage.addItem({ name: 'Dog' });

objStorage.removeItem(obj); //同じオブジェクトを削除できる
console.log(objStorage.getItems());

```
gsutil で No command was given. って言われる件

google-cloud-sdk の gsutil が使いたい

### 同じ名前のpackageが存在するらしい
https://stackoverflow.com/questions/7989741/how-to-configure-gsutil

いつもお世話になっておりますstackoverflow

### 削除ッ！
aptで入ってたっぽいので以下のコマンドだけで良いですね。

```
sudo apt-get remove --purge gsutil  
```

### 動作確認
ログインし直した人でもちゃんと動くのか確認するためいったんexit→gsutil ls

```
# いったんシェルを抜ける
exit
ssh ユーザー名@サーバ名

# 動作確認
gsutil ls 
(一覧が表示される)
```

これで一覧が表示されればOK

### 参考
https://groups.google.com/g/googleclusterdata-discuss/c/eh38DDUWmR8
Ruby on Railsで新規アプリケーションを作成する

#Ruby on Railsで新規アプリケーションを作成する

```csharp
username:~/environment $ rails new アプリケーション名
```

今回は、「practice_app」という名のアプリケーションを作成します。

```csharp
ec2-user:~ $ cd environment
username:~/environment $ rails new practice_app
```

#アプリケーションを削除するには
以下のコマンドを入力してアプリケーションを削除する。

```csharp
username:~/environment $ rm -rf アプリケーション名
```

**rm**はremoveのことで、ファイルやフォルダを削除するコマンド。
**-rf** はコマンドオプションの1つで、「フォルダ内のすべてのファイルとフォルダを削除する」という意味を持つ。

今回の場合は以下のように入力すると、アプリケーションを削除できる。

```csharp
username:~/environment $ rm -rf practice_app
```
【学習法】DeepLearning 高速化 高精度化 論文リスト

# 背景
Deep Learningで高速化、高精度化したい時に役立ちそうな論文リストをメモしておきます。

## 速度の向上
[MobileNets: Efficient Convolutional Neural Networks for Mobile Vision](https://arxiv.org/pdf/1704.04861.pdf)
convolutionを2つに分けると精度を大きく落とさず採算量を大幅に小さくする事が出来る。

[Pruning and Quantization for Deep Neural Network Acceleration: A
Survey](https://arxiv.org/pdf/2101.09671.pdf)
FP32をFP16に代用する事で計算コストを落とす。

[nn.ReLU(inplace=True)](https://pytorch.org/docs/stable/generated/torch.nn.ReLU.html)
無駄なコピーがなくせる



## 精度の向上
[Deep Residual Learning for Image Recognition](https://arxiv.org/pdf/1512.03385.pdf)
Residualを使うと学習が安定する。

[Identity Mappings in Deep Residual Networks](https://arxiv.org/pdf/1603.05027.pdf)
ResBlockは最初にBatchNormとActivationをすると一番精度が高くなる。

[Wide Residual Networks](https://arxiv.org/pdf/1605.07146.pdf)
channel数とconvolutionの数は良い感じ塩梅を取ると良い結果が得られる。

[Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift](https://arxiv.org/pdf/1502.03167.pdf)
BatchNormをすると学習が安定化する。

[MULTI-SCALE CONTEXT AGGREGATION BY
DILATED CONVOLUTIONS](https://arxiv.org/pdf/1511.07122.pdf)
dilationを使う事でreceptive fieldを広げる。

[Spatial Pyramid Pooling in Deep Convolutional
Networks for Visual Recognition](https://arxiv.org/pdf/1406.4729.pdf)
SPPでreceptive fieldを広げられる。

[Dropout: A Simple Way to Prevent Neural Networks from
Overfitting](https://jmlr.org/papers/volume15/srivastava14a.old/srivastava14a.pdf)
Dropoutするとoverfittingを防げる。
[Ruby]method_missingを扱って魔術師見習いになろう！

# method_missingとは
method_missingとは[Rubyリファレンスマニュアル](https://docs.ruby-lang.org/ja/latest/method/BasicObject/i/method_missing.html)に記載の通り、呼びだされたメソッドが定義されていなかった時、Rubyインタプリタがこのメソッドを呼び出します。

また、本来存在しないメソッドを呼び出すので、これらの呼び出されたメソッドは**ゴーストメソッド**とも呼ばれます。

## 魔術師としての使い方
呼び出しに失敗したメソッドの名前 (Symbol) が name にその時の引数が第二引数以降に渡されます。デフォルトではこのメソッドは`例外NoMethodErrorを発生`させます。

```ruby
class Foo
end

foo = Foo.new

# 未定義のメソッドを呼び出すとNoMethodErrorとなる
foo.sample_method #=> NoMethodError!
```

しかし、`method_missingをオーバーライドすることで未定義のメソッドが呼び出されても、意図的に未定義メソッドに対して任意の処理`を加えることが出来る。

```ruby
class Foo
  def method_missing(method, *args)
    # 任意の処理
    puts "#{method}が呼び出されましたが未定義です。"
  end
end

foo = Foo.new

# 未定義のメソッドを呼び出すしてもNoMethodErrorとならずに、任意の処理が出来る
foo.sample_method #=> "sample_methodが呼び出されましたが未定義です。"
```

## method_missingという魔術の闇
以下のコードには無限ループするというエラーが隠れています。どこで発生しているか分かりますでしょうか？？

```ruby
class Roulette
  def method_missing(name, *args)
    person = name.to_s.upcase
    3.times do
      number = rand(10) + 1
      puts "#{number}..."
    end
    "#{person} got a #{number}"
  end
end

rand_num = Roulette.new
puts rand_num.tanaka
#=> 4...
#=> 2...
#=> 9...
#=> 7...
#=> …
#=> …
#=> SystemStackError: stack level too deep from..
```

ブロックローカル変数であるnumberが、ブロック外部で参照しようとしていることがエラーの原因となっています。
Rubyは「number」が見つからないので、method_missingメソッドを呼び出そうとするが、`method_missingメソッド内で発生しているバグなので無限ループ`を起こしてしまいます。

### 注意点
method_missingメソッド自体にバグが潜んでいると、問題が特定しづらいため、必要のないゴーストメソッドは導入しないようにしましょう。

#### 修正後コード

```ruby
class Roulette
  def method_missing(name, *args)
    person = name.to_s.capitalize
    # 想定される名前以外は通常のmethod_missingを呼び出す
    super unless %w[tanaka sato suzuki].include?(person)
    # numberをブロック外から参照できるように事前に定義しておく
    number = 0
    3.times do
      number = rand(10) + 1
      puts "#{number}..."
    end
    "#{person} got a #{number}"
  end
end

rand_num = Roulette.new

# NoMethodError発生
puts rand_num.foo
=> NoMethodError: undefined method `foo' for #<Roulette:0x007fe4bb9ac7a0>

puts number_of.tanaka
#=> 3...
#=> 5...
#=> 5...
#=> tanaka got a 5
```

# まとめ
method_missingは、魔術の一種として用いることができますが、リスクも伴っているので、利用するときは`本当にこのやり方でいいか？`を意識した上で利用しましょう！
STM32L010とSTTS751で温度をシリアルに出力 (RawSerial)


x 愛用していたSTTS751の入手が難しくなったので代用品は、S-5851A。(おもにアドレスの違い)

温度を表示

x Mbedのリビジョンは、125

目的
STM32L010(STM32L010F4P6)には、内部温度センサーがついていないので
秋月で売っている安価なSTTS751を使って温度をシリアルに出力する。

忙しい人よう

https://os.mbed.com/users/caa45040/code/serial_raw_temp_010/

```c++

#include "mbed.h"

//10の割り算 0から1028までは、正しい。主に0から999
#define DVI10(n) ((n*205)>>11)

#define ADDR        (0x72)   //  address


RawSerial pc(PA_2, PA_3); //010

//I2C i2c(I2C_SDA, I2C_SCL); //767
//I2C i2c(dp5, dp27); //1114
I2C i2c(PA_10, PA_9); //010

int     tempval;        //温度
char    data_read[6];   //i2cバッファー
int     n10;            //10の桁

int main()
{

    while (1) {

        //温度の読み込み
        // Read temperature register
        i2c.read(ADDR, data_read,1,false);

        //温度の保存
        // Calculate temperature value in Celcius
        tempval =  data_read[0];

        //計算
        // Calculation temp
        //tempval = 12;
        n10 = DVI10(tempval);             //10の桁
        tempval = tempval - ( n10 * 10 ); //1の桁

        //液晶に出力
        // Display result
        data_read[0] = '0' + n10;
        data_read[1] = '0' + tempval;
        data_read[2] = '\r';
        //data_read[3] = '\n';
        data_read[3] = 0;

        //温度の出力
        puts(data_read);

        wait_ms(1000);
    }//while

}//main

//容量削減
void error(const char* format, ...){}

```

![serial_raw_temp_010_r1_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/65e8a662-1252-72be-4160-688dfaef46e5.jpeg)

![serial_raw_temp_010_r1_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/724fa516-2dad-7e00-1b76-4c5ba87037d0.jpeg)
sudo snap install google-cloud-sdk で classic 付けろって言われる件

「classic付けろって言われるくらいなら最新版入れたいんだけど...」って思うのに
調べてみると何年もclassic付けろって言われているみたいなので「ちっ、ちゃんと調べるか」ってなっちゃう件ですね
ちなみに私がそもそも入れたかったのはgsutilです。

### ubuntuでgsutil使おうとするとこんな事言われる

```
$ gsutil

Command 'gsutil' not found, but can be installed with:

sudo snap install google-cloud-sdk  # version 340.0.0, or
sudo apt  install gsutil            # version 3.1-1

See 'snap info google-cloud-sdk' for additional versions.
```
あーはい、って感じ


### google-cloud-sdk を入れようとすると classic 付けろと言われる

```
$ sudo snap install google-cloud-sdk
[sudo] password for (ユーザ名):
error: This revision of snap "google-cloud-sdk" was published using classic confinement and thus
       may perform arbitrary system changes outside of the security sandbox that snaps are usually
       confined to, which may put your system at risk.

       If you understand and want to proceed repeat the command including --classic.
```

classic付けなくても動くようにして欲しいお気持ちではあるけど  
今のところは修正に時間がかかるんでしょうね  
とは言え他の手段でclassic付けなくても済むならそっちを使いたいところ  

### 公式的にもsnap使う場合はclassic付けろらしい
https://cloud.google.com/sdk/docs/downloads-snap

使う時はsudo付けないと怒られる

### ちなみにclassic付けずにaptで入れる方法もある
https://cloud.google.com/sdk/docs/quickstart#deb

めんどい

### というわけで

```
sudo snap install google-cloud-sdk --classic
```

でインスコしましょう。
IcT関連の特許侵害訴訟の判決が出ました

LINEを相手取った特許侵害訴訟の判決が出ました（平成２９年（ワ）第３６５０６号）。
IcT分野でマネタイズの主流となっている「広告収益」が損害賠償の対象にならないとの、判決です。この判決により、下図に示すような弊害が出ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461483/1e8dd1da-243a-66ac-9bab-333fe91ac1e6.png)
Git Hubを使う際に実務で困らないために、、、

#pullリクエストの使い方

プルリクエストは、自分の変更したコードを
リポジトリに取り込んでもらえるように依頼する機能であり。
チームで開発している場合を想定すると、
自分（生徒）がテストを提出して、それをチームメンバー（先生）にレビューしてもらい、
採点をもらって、合格すれば提出されるみたいな感覚です:relaxed:

##プルリクエストの手順

1. masterブランチを最新に更新
1. ブランチを作成
1. ファイルを新規作成・変更
1. 変更をコミット
1. Git Hubへプッシュ ※ここまでがローカルで行われること
1. プルリクエストを送る ※ここからGit Hubのホームページ上で行う作業
1. コードレビュー
1. プルリクエストをマージ
1. ブランチを削除

- - -
よくここで、やってしまうのがローカルの状況とGitHub上の状況を
最新にしていないと、変更の積み上げによって生じる歪みで、
コンフリクトが発生する:sleepy:ということです。

常に、今の自分がどういう状況なのかは確認しておくことと
自分が実際どんな操作を行っているのかはよく把握しておくことが大事。

基本的には、GitHubフローと呼ばれるGitHub社が推奨している形に沿って
開発を進めるのがベターになってくる。

やりがちなのが後始末をしっかりとしないためにリモートとローカルの環境に差異が起きて
無駄なコンフリクトが発生してしまうこと。
なので、プルリプが終わったら、必ずローカルのブランチも綺麗にして
最後に`git pull origin master`をしてから終了して、
新たにブランチを切って開発・修正するようにしていきたい。

今後もここには気をつけたい。。。
Arm Communityの記事などについて

# Arm他、企業のCommunityのBlog他の記事はどの程度信頼できるのだろう（答え、知りません。）
ARMのチップの情報とかを調べている場合、Arm Blogの記事に辿りつく場合が、結構ある。

<font color="orange">**記事の内容が正しいのかどうか**</font>が、ちょっと、よくわかりません。

すみません、この記事、特に答えはありません。

# Armのが、どんな感じか。
## Arm Community
https://community.arm.com/ から引用すると、

>Welcome to the Arm Community

>The Arm Community makes it easier to design on Arm with discussions, blogs and information to help deliver an Arm-based design efficiently through collaboration. If you have general technical questions about Arm products, anything from the architecture itself to one of our software tools, find your answer from developers, Arm engineers, tech enthusiasts and our ecosystem of partners.

DeepL翻訳
>Arm Communityは、Armでの設計を容易にするために、ディスカッション、ブログ、情報などを提供し、コラボレーションを通じてArmベースの設計を効率的に実現できるようにします。Arm製品に関する一般的な技術的質問があれば、アーキテクチャそのものからソフトウェアツールの一つに至るまで、開発者、Armエンジニア、技術愛好家、そしてパートナーのエコシステムから回答を得ることができます。

となっている。

## Arm blog

同じく、https://community.arm.com/ から引用すると、

>Keep up to date with the latest news on Arm solutions,　products and ecosystem.

と書かれている。

https://community.arm.com/p/arm-blog のページは、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473789/ec5c6d9c-f782-b16d-34ff-587f95a364a1.png)

みたいな画面で始まる。

↓　こっちの筆者は、ARMのDirectorとなっており、Top 1% (人気？？）となっているので、
なんとなく信頼感がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473789/caec65a6-a4c6-54ee-c2fc-d3f06591bef3.png)

↓　こっちの筆者は、一般人？？、Top 50%（←　普通じゃないか）となっているので、
どの程度信用できるBlogなんだろう。。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473789/6f604fd6-842c-cc73-9cd0-0981f62a17bf.png)

# 普通の技術ブログと同じでしょ
「普通の技術ブログと同じでしょ」と言ってしまえばそうかもしれないが。。。そうなると情報の信頼度が「？」となる。ただし、それも、普通の技術ブログと同じでしょうと言えばそれまでだが。

# このメモを書いていて気づいたこと

上記の『そしてパートナーのエコシステムから回答を得ることができます。』（抜粋）のあたりも含むと、ARMで閉じてARMの責(文責）で情報を出すわけにもいかないな。。。とは、理解しました。

# まとめ
まだ、なじめてません。
PowerShellでキーボードマクロ書いた。

#これ何
なんでもキーボードマクロ送れる奴。

#どうやって使うの
キーボードマクロ送りたいソフトの同じディレクトリに置いて
`$script:TargetFile`にターゲットの実行ファイル名を拡張子無しで`"notepad"`みたいに書く。
`$script:Macros`は送りたいキーコードをステップ毎に`,`で区切って`@("test1","test2")`みたいに書く。
`$script:StartWait`これはもしソフトが起動していないときに起動するけどマクロ受け付けるまで待ち時間が生じるときのために待ち時間を設ける数値、単位はms(ミリセカンド)。

##ちょっとややこしいやつ
これの設定`$script:Wait`ちょっと理解しづらいかもしれない。ステップごとのウェイト時間を書く。単位はms。
操作後のラグなどで待ち時間が必要なときのためにウェイトを設けたい時が有ったりすると思う。そんなときはステップを分けてあげればいい。キーボードマクロは配列として設定するので`@()`の中に`,`で区切ってステップを記述する。各ステップは`""`で囲う。ステップの書き方は[MSDN:SendKeys](https://docs.microsoft.com/ja-jp/previous-versions/windows/scripting/cc364423(v=msdn.10)?redirectedfrom=MSDN)を参考にしてください。

#コード
```powershell
#Auto-Macro by Fizz

#references https://qiita.com/nimzo6689/items/488467dbe0c4e5645745

#paramater
param(
    $script:RootDirectory = (Split-Path $MyInvocation.MyCommand.path),
    $script:TargetFile = "notepad",
    $script:Macros = @("test1","test2"),
    $script:StartWait = 3000,
    $script:Wait = 1000
)

#declare assembly
Add-Type -AssemblyName Microsoft.VisualBasic
Add-Type -AssemblyName System.Windows.Forms

#main
function main{
    $pobj = GetProcessObject $script:TargetFile
    if($null -eq $pobj){
        try{
            Start-Process -FilePath $(GetFilePath $script:TargetFile "exe")
            Start-Sleep -m $script:StartWait
            $pobj = GetProcessObject $script:TargetFile
        }catch{
            Pause
            throw
        }
    }
    AppActivate $pobj
    SendKeysMacro $script:Macros
}

#functions
function GetFilePath($filename,$extention){
    $fn = $filename + "." + $extention
    return $(Join-Path -Path $script:RootDirectory -ChildPath $fn -Resolve)
}

function SendKeysMacro($macros){
    foreach($command in $macros){
        Start-Sleep -m $script:Wait
        [System.Windows.Forms.SendKeys]::SendWait($command)
    }
}

function AppActivate($pobj){
    [Microsoft.VisualBasic.Interaction]::AppActivate($pobj.ID)
}

function GetProcessObject($name){
    return (Get-Process $name | Where-Object {$_.MainWindowTitle -ne ""})
}

#entry
main
```

#参考
https://docs.microsoft.com/ja-jp/previous-versions/windows/scripting/cc364423(v=msdn.10)?redirectedfrom=MSDN
https://qiita.com/nimzo6689/items/488467dbe0c4e5645745
[Github]リポジトリ作成〜プルリクエストするまでの大まかな流れ

最低限これをやればOK

前提条件: 
    Githubがユーザー登録済みである
    windows PCやMacbookにGitコマンドがインストールされていること
    
1.Githubにて、新規リポジトリを作成する。
ホーム画面>Repositoriesの「new」をクリック。
Repository nameに任意の名前をつける(今回は「test」にした)
「Add a README file」にチェックをつける。
「Create repository」をクリック。

2.terminalを開き、下記コマンドを任意の場所で実行する。(Documentディレクトリなどにおいた方が後でvscodeから開くときに楽)
mkdir (ディレクトリの作成 今回は「test」ディレクトリを作成した。)
cd test (testディレクトリへ移動)
git init (gitの初期処理)

3.新規ファイル(今回はhtmlファイル)をローカルで作成する。

  git cloneしたい時はこの段階で実行する。

4.作成したhtmlファイルを2.で作成した「test」フォルダに保存する。

5.terminal上で「test」ディレクトリへ移動し下記コマンドを実行していく。

簡易版
git add .
git commit -m "add new file"
git remote add origin https://github.com/xxxxx/xxx.git
git push origin master


git add test.html
git commit -m "add new file"
git status
↓ここでローカル作成したディレクトリとGitHubに作成したリモートリポジトリを紐づける(このコマンドを忘れるとpushできない)
git remote add origin https://github.com/xxxxx/xxx.git
URLは1.で行った新規リポジトリ作成時に生成されたURL
作成したリポジトリのページにあるcode>vlone>HTTPSに記載されているURL
間違ったURLを設定してしまった場合
git remote -v (現在設定されている内容を確認できる)
git remote rm origin (設定内容を削除)
git push origin master

[ファイル修正してリモートリポジトリにpushする]
git add [ファイル名]
git commit -m "[コメント]"
git push origin master

[リモートリポジトリを更新しているためローカルリポジトリをpushできない時の対処法]
1.ローカルリポジトリでコミットする
git commit -m "[コメント]"
2.リモートリポジトリの方が最新の状態なので、リモートリポジトリの内容をフェッチ&マージする
git fetch
git merge origin/master
3.ローカルリポジトリをプッシュする。
git push origin master

■vscodeからターミナルを開く方法
「Terminal」>「New Terminal」

■ローカルリポジトリにGit cloneした後、vscodeにcloneしたディレクトリを読み込む方法
「File」>「Open Folder」

■リモートリポジトリのマスターを更新する方法

　大まかな流れ
　　ローカルのマスターを更新し、反映させる
　　　 git pull origin master

■フォルダごとadd,commit,pushする方法

git add .
git commit -m "コメント"
git push origin master

上記のコマンド実行してもコミットが反映されない時がある。その時は、
git commit (空コミット)
git push origin master
を再実行する。(GitHubが不安定だとこの現象が起きる)
また、GitHubのトップページ>Code>コミット履歴 の「xxxxx x minutes ago xxx commits」の左側のアイコンがオレンジの時はまだpush処理の途中(「Some checks haven't completed yet」と表示される。)
完了すると緑のチェックマークになる。
[Node]AWS LambdaからDynamoDBを操作する

こんにちは takeです。

今回はnodeでAWS Lambda関数を作成しました。(DymanoDBも触りました)

今後開発する際のテンプレートとして残しておきたいと思います。

(今回はDynamoDBのデータを取得しています)

```javascript:index.js
const AWS = require("aws-sdk");
// DBと接続　(regionを指定するとaws accountに紐づくDynamoDBに接続されます。)
const dynamoDB = new AWS.DynamoDB.DocumentClient({
    // region は人によって変わります。日本だとap-northeast-1かな？
    region: "ap-northeast-1"
});
exports.handler = async (event) => {
    //DynamoDB のクエリを記載する
    let getDatas = async (argument) => {
        const params = {
            // 操作するテーブルの名前を指定
            TableName: "Table Name",
            // 条件式を記載 #key = :key
            KeyConditionExpression: "#key = :key",
            // 条件式に出てきた変数と実際のDBのテーブルの要素を結合 #keyはDBのId
            ExpressionAttributeNames: { '#key':'Id'},
            // 条件式に出てきた変数と関数内の変数を結合 :keyはargument
            ExpressionAttributeValues: {':key':argument},
            // 検索する際のsort
            ScanIndexForward: true,
        };
        return await dynamoDB.query(params).promise();
    };

    //クエリを実行
    let key = "sample"
    let data = await getDatas(key);
    // 取得結果をパース
    data = data.Items;

    // ここで取得したデータをコネコネ

    //レスポンスを作成
    const response = {
        statusCode: 200,
        headers: {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*'
        },
        body:data,
    };
    return response;
};
```
ファイルがHTML化できないときの対処法

#環境
OSはWindows10です。

#やりたかったこと
ファイルを新規作成するとき、HTMLファイルとして作成したかった。しかし、テキストドキュメントの名前に.htmlをつけてもHTMLファイルではなくテキストドキュメントになってしまった。

#解決方法
拡張子が表示されていないので、拡張子を表示させて、拡張子を変更する。
##拡張子を表示
>エクスプローラーを開き、表示を開く。
![hyouzi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1522733/b2bee60e-9d4b-af1d-3c64-456704683e73.png)
ファイル拡張子のチェックボックスにチェックを入れる。
![タイトル333.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1522733/41e3a30f-14db-f355-8aef-d34b34b97c02.png)
これで新規作成からテキストドキュメントを作成すると拡張子が表示されるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1522733/5ab0208b-c7b7-2199-710a-57f98eae2873.png)

##拡張子を変更
>後はもともとあった名前を消して拡張子.htmlをつけると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1522733/fef98a6c-ccc4-9dc1-a2f9-0814ca1e5da4.png)
HTMLファイルとして保存できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1522733/d0ad753b-78c6-b3fe-e695-8e6f7caa2c7b.png)

以上がWindows10でファイルをHTMLファイルとして作成する方法です。
#補足
HTMLだけでなくPHPなどでも同様の方法で解決することができます。
また拡張子は他にもいろいろあるので気になる方は[こちら](https://www.tohoho-web.com/ex/draft/extension.htm)をご覧ください。
Vue.jsでHTML5標準のフォームバリデータを使う

Vueでバリデーションというと、まず挙がるのは[VeeValidate](https://vee-validate.logaretm.com/)かと思います。
ある仕事でNuxt.jsを使う現場にアサインされた時も、バリデーターはVeeValidateが採用されてました。
でもあれ、記述が重いんですよね…。
どっちにしろバックエンドでバリデーションしますし。

趣味のサイトで、あそこまで高機能じゃなくていいからもうちょい楽にバリデーションできないかなぁと考えて思い出したのがHTML5標準のフォームバリデータ。
挙動はブラウザ依存にはなってしまいますが、例えば```required```タグを付けるだけで、IE以外はバルーン表示でユーザに告知してくれます。必要十分で、楽です。

https://developer.mozilla.org/ja/docs/Learn/Forms/Form_validation#using_built-in_form_validation

## 素のJavaScriptによるHTML5フォームバリデータ例

MDNでは「JavaScript無しの素のHTMLフォームでもバリデーション可能です」という紹介のされ方ですが、JavaScriptからDOM操作で該当のイベントを起動することが出来ます。

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="js,result" data-user="belgh" data-slug-hash="XWMNPbW" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="HTML5 フォームバリデーション 素JavaScript実装例">
  <span>See the Pen <a href="https://codepen.io/belgh/pen/XWMNPbW">
  HTML5 フォームバリデーション 素JavaScript実装例</a> by belgh (<a href="https://codepen.io/belgh">@belgh</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

チェックボタンを押すと、HTMLのinputタグの属性に従ってバリデーションが行われるのが確認できると思います。
（本サンプルでは、:valid、:invalidで自動適用されるclassも設定しています）
JavaScript側ではイベント起動してるだけで、他は何もしていません。

上記のチェック例は```required``` ```minlength="10"```です。
他にemailやtel、dateなどの```input type```によるバリデーションや、```pattern```属性で正規表現を使うことも出来ます。

また、後述する方法で独自のバリデーションを実装することも出来ます。
（あまり複雑になるようだと、モジュール使ったほうがいいような気もしますが…）

## Vue3(TypeScript)での実装例
ポイントは```ref```を使うこと。
TypeScriptの場合はHTMLInputElement型を明示します。
それだけです。

```vue
<script setup lang="ts">
import { ref } from 'vue'

// props略

const form = ref<HTMLInputElement | null>(null)
const validate = () => {
  if (form.value?.checkValidity() == false) {
    form.value.reportValidity()
    return false
  }
  return true
}
const create = () => {
  if (!validate()) {
    return false
  }
  // 以下略
}
</script>

<template>
  <form ref="form">
    <input :model="params.name" type="text" required minlength="10">
    <button type="button" @click="create">
      登録
    </button>
  </form>
</template>
```

- 参考
https://ja.vuejs.org/guide/essentials/template-refs.html#accessing-the-refs
https://reffect.co.jp/vue/vue3-composition

エラーの表現方法はバルーンで固定されてしまいますが、

- template部分のルール記載がものすごくシンプル
- バリデーションのトリガイベントを書くだけで、実際のバリデーションとエラー告知はブラウザ任せ

であることが利点です。
楽でいいですよね。

### 独自のバリデーションを実装する

これに手を出すくらいなら有り物のモジュールに乗っかったほうがいいのでは…？
という意味であまり使う機会はないかもしれませんが、
独自のバリデーション実装も可能です。

以下は、標準では行えない「添付ファイルのサイズ」をチェックする例です。

```vue
<script>
const catchFile = (e: Event) => {
  if (e.target instanceof HTMLInputElement) {
    // checkValidityはエラーメッセージの有無に依存するので、必ずクリアする
    e.target.setCustomValidity('')
    if (e.target.files) {
      const image = e.target.files.item(0);
      if (image.size > 1024 * 1024 * 5) {
        // エラーメッセージを設定すると、checkValidityがfalseになる
        e.target.setCustomValidity(
          'ファイルサイズは5MB以下にしてください。'
        )
      }
    }
  }
}
</script>

<template>
  <input @change="catchFile" type="file" required>
</template>
```

これくらいなら許容範囲かな？と思います。
おわり。
HerokuでRubyのバージョンを指定する方法

## Herokuにデプロイしたが、意図してないRubyバージョンになっている

```
-----> Building on the Heroku-20 stack
-----> Using buildpack: heroku/ruby
-----> Ruby app detected
-----> Installing bundler 2.2.16
-----> Removing BUNDLED WITH version in the Gemfile.lock
-----> Compiling Ruby/Rails
-----> Using Ruby version: ruby-2.6.6
```

Ruby Versionが `2.6.6` になっている。
本当は、`3.0.1` を使いたい

## 解決方法

```:Gemfile
ruby '3.0.1'
```

の記述を加えて、

```:console
$ bundle update --ruby
```
を実行すると、Gemfile.lockが更新される

```:Gemfile.lock
RUBY VERSION
   ruby 3.0.1p64
```

もう一度、Herokuにデプロイ

```
-----> Building on the Heroku-20 stack
-----> Using buildpack: heroku/ruby
-----> Ruby app detected
-----> Installing bundler 2.2.16
-----> Removing BUNDLED WITH version in the Gemfile.lock
-----> Compiling Ruby/Rails
-----> Using Ruby version: ruby-3.0.1
```

無事、 `3.0.1` になりました。
PHPUnitでプライベートメソッドのテストを行う方法

## はじめに
通常の方法ではpublicメソッドしかテスト対象とすることができませんが、少しコードに手を加えることでprivateやprotectedのメソッドもテストができるようになります。
このページでは、private（protected）メソッドのテストを簡単に行うためのメソッドの紹介をします。

## 対象
- Laravel
- PHPUnit  

## ソースコード
```php
/**
 * Execute private function test.
 *
 * @param $class 対象とするクラス
 * @param  string  $methodName メソッド名
 * @param  array  $arguments 引数(配列指定)
 * @return mixed
 */
protected function executePrivateFunction($class, string $methodName, array $arguments)
{
    $reflection = new ReflectionClass($class);
    $method = $reflection->getMethod($methodName);
    $method->setAccessible(true);

    return $method->invokeArgs($class, $arguments);
}
```

## 使い方
上記コードをテストコードのベースクラスに貼り付けます。
あとは、テストしたいコード上で該当メソッドを呼び出すことでprivateメソッドのテストが可能です。

## サンプル
```php
/**
 * @test
 */
public function isReadSkip(): void
{
    $parentAttribute = new ParentAttribute('spreadsheetCategoryName', 'sheetName');
    $parentAttribute->setParentAttributeDetails('Users', 'tableName');
    $parentAttribute->setParentAttributeDetails('user_db', 'connection');
    $argument = [
        'category_name'               => 'MasterData',
        'use_blade'                   => 'master_data',
        'sheet_id'                    => 'sheet_id',
        'output_directory_path'       => base_path('definition_document/database/master_data'),
        'separation_key'              => 'ColumnName',
        'attribute_group_column_name' => null,
    ];
    $fileOperation = $this->app->make(FileOperation::class);
    $spreadSheetReader = $this->app->make(SpreadSheetReader::class);

    /* @see SingleGroup::isReadSkip() */
    $singleGroup = new SingleGroup($fileOperation, $spreadSheetReader, $argument);
    $response = $this->executePrivateFunction($singleGroup, 'isReadSkip', [$parentAttribute, 'users']);
    self::assertFalse($response);
}
```

## 補足
プライベートメソッドのテストは通常書く必要は無いはずです。
どうしてもプライベートメソッドをテストしたい場合にだけ利用するくらいがちょうど良いと思います。
草野球の出欠確認Webアプリを作ろう！　part.9

これから作っていく簡単なWebアプリの作成メモ（自分の備忘）です。
自分用なのであまり凝りすぎないように書いていきたい。

[<<前回の記事](https://qiita.com/tomodachi_uec/items/759418e0c871c7076c5f)

##今回やったこと

###ユーザーの編集

前回に引き続き、ユーザーのデータを編集できるようにしていく。

```rb:app/controllers/users_controller.rb
（略）
  def edit
    @users = User.find(params[:id])
  end

  def update
    @users = User.find(params[:id])
    if @users.update(users_params)
      redirect_to user_path(@users), notice: "ユーザーを編集しました。"
    else
      render :edit
    end
  end
（略）
```

```erb:app/views/users/edit.html.erb
<h1>ユーザーの編集</h1>
<div class="row_line">
  <%= link_to 'ユーザー一覧へ', users_path, class: 'btn btn-primary' %>
</div>

<%= form_for @users, url: {action: "update", id: @users.id} do |f| %>
  <div class="row_line">
    <label>ユーザー名：</label>
    <%= f.text_field :name %>
  </div>
  <div class="row_line">
    <label>メールアドレス：</label>
    <%= f.email_field :email %>
  </div>
  <div class="row_line">
    <label>パスワード：</label>
    <%= f.password :password %>
  </div>
  <div class="row_line">
    <label>パスワード（確認欄）：</label>
    <%= f.password_confirmation :password_confirmation %>
  </div>

  <div class="row_line">
    <%= f.submit "保存する" %>
  </div>
<% end %>
```

```erb:app/views/users/index.html.erb
（略）
<tbody>
  <% @users.each do |lst| %>
    <tr class="clickable-row" data-href="<%= user_path lst.id %>">
（略）
```

この段階で動作を見てみると、以下のようになった。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534558/69ae33b4-cdc1-5386-6a93-78b8cac3370b.png)

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534558/498ae312-e61e-f6bd-950b-28d2292faf84.png)

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534558/168dac0f-e535-a2b4-4eb0-125dfd25f7ad.png)

ちなみにこの段階では、パスワードを入力しないとユーザー情報を変更できない。
これは今後の課題にしたい。

...また、意図していないことだったが、ユーザー用のjavascriptを用意しなくともユーザー一覧のテーブルの行をクリックするとユーザー詳細画面に遷移できてしまった。
これは現状でどの画面でもschedules.jsが読み込まれており、スケジュールの実装の時と同様にクラスやデータ属性を整えると、同じように遷移できてしまうようになっていることが原因。
→理想的には、全画面共通のjavascriptが基本処理としてあり、そこに画面ごとに個別処理のjavascriptを使って実装を進めるのが良いと思う。


時間もなかったので今回はここまで。


[次回の記事>>](https://qiita.com/tomodachi_uec/items/4d9633635c9964053efd)