OmniAICreator/Qiita-1.07M huggingface dataset:
疑似要素でつくったチェックボックスにブラウザ準拠のフォーカスを当てる

# はじめに
疑似要素を使用してチェックボックスを作った際に、ブラウザ準拠のフォーカスを当てたかったのですが、どうしようか…と少々苦戦したので備忘録として残すために記事にしました。 （既出ネタだったらすいません）
また、元々は先輩がラジオボタンで似たようなことをしてたのを思い出し、それをチェックボックス版にしました。
なので0から私のアイディアという訳ではないです。（土下座）

# 結論
先に結論書いちゃいます。

**疑似要素の下に普通のチェックボックス（input要素）置いちゃえ**

以上です！ 

# どういうこと？

では簡単に説明します。
の前に、カスタムチェックボックスを作成します。

## 事前準備

適当なinput要素、labelを用意。

```html
<div class="checkbox-group">
  <input type="checkbox" id="check1" class="checkbox">
  <label for="check1" class="checkbox-label">チェック1</label>
</div>
```
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251276/2324dc66-7c8e-997a-077c-f91789ed6b27.png)

すると上記のようなチェックボックスができるかと思います。  

では上記に以下のスタイルを当てます。

```css
.checkbox {
  display: none;
}

.checkbox-label {
  padding-left: 28px;
  position: relative;
}

.checkbox-label::before {
  content: "";
  width: 20px;
  height: 20px;
  border: solid 2px #b0c4de;
  background-color: #FFF;
  border-radius: 4px;
  position: absolute;
  top: 0;
  left: 0;
}

/* チェック済み */
.checkbox:checked + .checkbox-label::after {
  content: "";
  width: 16px;
  height: 16px;
  border-radius: 2px;
  background-color: #b0c4de;
  position: absolute;
  top: 4px;
  left: 4px;
}
```

すると

![2_未チェック.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251276/79f21051-d328-5b9a-3880-a1f68af7429e.png)

このようなチェックボックスができます。
ちなみにチェック済みの場合は…

![2_チェック済み.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251276/33e49ccd-5218-7d47-3881-42ef32d964a6.png)

こんな感じになります。

ここまでは、自分の好みのカスタムチェックボックスを作っていただいて大丈夫です。

## 考え方

では考え方ですが、文章は苦手なので、図で説明します。

<img width="400px" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251276/6f179726-76c4-2a4e-ecf1-ca80181e13a1.png">

（字が汚いのは申し訳ないです…ｗｗ） 
…~~図でもわかりにくい説？~~  
事前準備としてカスタムチェックボックスを作成しましたが、その際にinput要素を`display:none;`なりで非表示にするかと思います。
（実際に上記でもそのようにしています。）

ただそうするとフォーカスが当たらなくなってしまうので、
非表示にはせず、カスタムチェックボックスの真下に本来のチェックボックスを隠してやります。
そうすることで、あたかも疑似要素にフォーカスが合っているかのように見せています。

ということでスタイルは以下のようになります。

```css
.checkbox {
/*   display: none; */
  outline-offset: 8px;
}

.checkbox-label {
/*   padding-left: 28px; */
  position: relative;
}

.checkbox-label::before {
  content: "";
  width: 20px;
  height: 20px;
  border: solid 2px #b0c4de;
  background-color: #FFF;
  border-radius: 4px;
  position: absolute;
  top: -1px;
  left: -27px;
}

/* チェック済み */
.checkbox:checked + .checkbox-label::after {
  content: "";
  width: 16px;
  height: 16px;
  border-radius: 2px;
  background-color: #b0c4de;
  position: absolute;
  top: 3px;
  left: -23px;
}
```

したことは`.checkbox`クラスの`display: none;`を削除、
`outline-offset: 8px;`を擬似要素で隠れないように調整、
疑似要素の位置を調整くらいでしょうか。。

![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251276/f16116ed-b6ac-7f23-f59d-e4916cdb0631.png)

すると上記のようにフォーカスが当たるようになりました。
input要素自体を非表示にしていないので、スペースキーでチェックを入れたり、外したりも可能です！

考え方さえ分かってしまえば特に難しいことはしていないので、簡単だと思います。


# まとめ
結論として、input要素を非表示にせずに、その上に擬似要素を置いてやればフォーカスが当たるようになります。
他に良き方法があったら教えていただきたいです。
いいねとリプライ

## コメント機能
### ルーティング

```php:routes/web.php
// ログイン状態
Route::group(['middleware' => 'auth'], function() {
 // 省略
 // コメント関連
 Route::resource('comments', 'CommentsController', ['only' => ['store']]);
});
```
### Model

```php:app/Comment.php
 public function commentStore(Int $user_id, Array $data)
 {
 $this->user_id = $user_id;
 $this->tweet_id = $data['tweet_id'];
 $this->text = $data['text'];
 $this->save();
 return;
 }
```
### Controller

```terminal
php artisan make:controller CommentsController --resource
```

```php:app/Http/Controllers/CommentsController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\Models\Comment;
class CommentsController extends Controller
{
 public function store(Request $request, Comment $comment)
 {
 $user = auth()->user();
 $data = $request->all();
 $validator = Validator::make($data, [
 'tweet_id' =>['required', 'integer'],
 'text' => ['required', 'string', 'max:140']
 ]);
 $validator->validate();
 $comment->commentStore($user->id, $data);
 return back();
 }
}
```

## いいね機能
いいね機能では一人につき1回。
まだいいねを付けていない投稿に対してはいいねを保存。
逆に既にいいねを付けているツイートに対して再度いいねを押すと削除するという仕様。
### ルーティング

```php:routes/web.php
// ログイン状態
Route::group(['middleware' => 'auth'], function() {
 // 省略
 // いいね関連
 Route::resource('favorites', 'FavoritesController', ['only' => ['store', 'destroy']]);
});
```
### Model

```php:app/Favorite.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Favorite extends Model
{
 public $timestamps = false;
 // いいねしているかどうかの判定処理
 public function isFavorite(Int $user_id, Int $tweet_id)
 {
 return (boolean) $this->where('user_id', $user_id)->where('tweet_id', $tweet_id)->first();
 }
 public function storeFavorite(Int $user_id, Int $tweet_id)
 {
 $this->user_id = $user_id;
 $this->tweet_id = $tweet_id;
 $this->save();
 return;
 }
 public function destroyFavorite(Int $favorite_id)
 {
 return $this->where('id', $favorite_id)->delete();
 }
}
```
いいねを押した際にツイートに対して既にいいね済みであれば`false`、逆に存在しなければ`true`

### Controller

```terminal
php artisan make:controller FavoritesController --resource
```
```php:app/Http/Controllers/FavoritesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Favorite;
class FavoritesController extends Controller
{
 public function store(Request $request, Favorite $favorite)
 {
 $user = auth()->user();
 $tweet_id = $request->tweet_id;
 $is_favorite = $favorite->isFavorite($user->id, $tweet_id);
 if(!$is_favorite) {
 $favorite->storeFavorite($user->id, $tweet_id);
 return back();
 }
 return back();
 }
 public function destroy(Favorite $favorite)
 {
 $user_id = $favorite->user_id;
 $tweet_id = $favorite->tweet_id;
 $favorite_id = $favorite->id;
 $is_favorite = $favorite->isFavorite($user_id, $tweet_id);
 if($is_favorite) {
 $favorite->destroyFavorite($favorite_id);
 return back();
 }
 return back();
 }
}
```
str_random()が使用できなかった件

##環境
Laravel 7.3.1

##経緯
ログイン機能実装する上で`str_random(10)`を使用。
作成後エラーが発生。

下記のブログを参考。
https://oversealife.work/2019/09/11/laravel-6-helper/

```
composer require laravel/helpers
```

ヘルパーのライブラリをインストール。

```
str_random(10)
```

####補足

```
Str::random(10)
```
でも使用できる。

https://readouble.com/laravel/7.x/ja/seeding.html?header=%25E3%2582%25B7%25E3%2583%25BC%25E3%2583%2580%25E3%2582%25AF%25E3%2583%25A9%25E3%2582%25B9%25E5%25AE%259A%25E7%25BE%25A9
ログイン機能で詰まった箇所のメモ

##Laravle6.x/7.x/8.xのログイン実装コマンドの違い
#### Laravel6 / Laravel7 / Laravel8 ログイン画面作成
#####１. laravel/uiをインストール

```cmd:ターミナル
#Laravel6.x 
composer require laravel/ui:^1.0 --dev
#laravel7の場合
composer require laravel/ui:^2.4
#laravel8の場合
composer require laravel/ui
```

２. ログイン機能作成

```cmd:ターミナル
php artisan ui vue --auth
```

# 参考
【ver6.x】https://laravel.com/docs/7.x/frontend#introduction
【ver7.x】https://laravel.com/docs/6.x/frontend#introduction
【ver8.x】https://laravel.com/docs/8.x/upgrade#updating-dependencies
Windows10でvagrant upを実行すると「VT-xが無効」になっているというエラーの解決

###環境
PC： HP ProDesk 400 G3 SFF
windows10 Home
Vagrant 2.2.14
ORACLE VM VirtualBox 6.1
VagrantBox centOS-7.7
PowerShell

###現象
Vangrant up を実行すると以下のようなエラーが発生する

```
> vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Checking if box 'bento/centos-7.7' version '202005.12.0' is up to date...
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.

Command: ["startvm", "e866d576-5a9b-4e45-bf9c-65ade2149b42", "--type", "headless"]

Stderr: VBoxManage.exe: error: Not in a hypervisor partition (HVP=0) (VERR_NEM_NOT_AVAILABLE).
VBoxManage.exe: error: VT-x is disabled in the BIOS for all CPU modes (VERR_VMX_MSR_ALL_VMX_DISABLED)
VBoxManage.exe: error: Details: code E_FAIL (0x80004005), component ConsoleWrap, interface IConsole
```

###原因
エラーメッセージある

```
VBoxManage.exe: error: VT-x is disabled in the BIOS for all CPU modes (VERR_VMX_MSR_ALL_VMX_DISABLED)

VT-xが無効になっているよ。全てのCPUモードに対するBIOSでね。（という感じの意味だと）

```

###解決策
WindowsのBoot設定からVT-xというものを有効にする。

私のPCはWindowsの起動画面でESCを連打することで起動できます。

端末によって連打するファンクションキーは違うので調べましょう。

####Bootの設定画面

![unnamed.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668402/7a0ffb0d-64d7-d3aa-9bc5-382f70f7a002.jpeg)

BIOS SETUPを選択

![unnamed (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668402/0645814b-0a49-21aa-24d6-55b97a1c8eb1.jpeg)

Advancedを選択

![unnamed (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668402/38abdb6d-fc7c-ec7c-d078-0b603af6cf3d.jpeg)

System Options を選択


やっと見つけました
Virtualization Technology（VTx）

これにEnterでチェックを入れ、変更を保存して起動し直してからVagrant upを実行すると問題なく実行されました。
Fargateプラットフォーム1.4.0の変更点

[Fargateプラットフォームバージョン](https://aws.amazon.com/jp/blogs/news/aws-fargate-platform-versions-primer/) をLATESTにすると1.4.0を指すようになった。
1.3.0から1.4.0の主な変更点は下記の通り。

- EFSエンドポイントのサポート
- ボリュームサイズが単一ボリュームで20GBに
- ネットワーク経路の変更
- CloudWatch Container Insightsにネットワーク関連のメトリクス追加
- CAP_SYS_PTRACEのサポート
- メタデータサービスv4の提供
- メタデータサービスにネットワーク関連の情報とAZ情報の追加
- 共通ECSエージェントからFargate専用エージェントへの変更

# ネットワーク関連の変更点

いまいちネットワーク関連の変更点がよく分からなかったので調べた。

## FargateのENI

Fargateは、コンテナを実行する仮想サーバーをAWSユーザーから隠蔽することで、管理コストを減らしてくれる。
仮想サーバーは、AWS管轄のVPCで動作しており、そのVPC内のENIがアサインされる。
これを **Fargate ENI** と呼ぶ。

仮想サーバー上で動作する個々のFargateタスクには、AWSユーザー側のVPCのENIがアサインされる。
これを **Task ENI** と呼ぶ。

## 通信処理ごとのネットワーク経路

1.3.0までは、一部の通信をFargate ENI経由で行っていた。
Fargate ENIなのでAWSユーザーからは見えないVPC上を経由していたはず。
一部の通信はこちら。

- ECRへのログイン
- Secrets Managerへのアクセス
- Parameter Storeへのアクセス

1.4.0からは、Fargate ENIが使われなくなり、全てTask ENIを経由するようになった。
Task ENIはAWSユーザーのVPCを経由し、ユーザーの管理下にあることになる。

# 注意点

ネットワーク経路の変更に伴って、VPCエンドポイント経由でアクセスしているリソースの追加設定が必要になる。
ECRに対する処理は、ログインとイメージのダウンロードがあり、それぞれにエンドポイントがあるため1.4.0以降は両方の設定が必要になる。

ECR関連のVPCエンドポイントについては、こちらにまとめた。

https://qiita.com/ryo0301/items/df4ef5a971fa6349ecd0#ecr-amazon-elastic-container-registry
windowsのバックアップで$OFフォルダができちゃった、、、。

<h1>はじめに</h1>
&nbsp;&nbsp;&nbsp;&nbsp;windowsバックアップの中にある謎の$OFファイルについて、シェルスクリプトを使った解決手段を一つ提案したいと思います。

<h1>目次</h1>
<ol>
　　<li>経緯</li>
   <li>$OFフォルダって何なのか</li>
   <li>解決手段</li>
</ol>

#1.経緯
&nbsp;&nbsp;&nbsp;&nbsp;先日、windowsより使いやすいと気づいたので、macに移行することを決めましたが、諸事情につき移行アシスタントが使えませんでした。そこでハードディスクにバックアップをとっておき、それをmacに移すことにしましたが、、、、。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692354/042aac1c-ab47-03b6-145c-f6ee2674c61d.png" width=67%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692354/d11c36fe-b91a-35a7-fead-2489fea8df15.png" width=65%>
Cドライブの他に、$OFフォルダができています。またこのフォルダの中にはさらに数字が割り振られているフォルダがあり、その中にいくつかのファイルが存在しているようで、ファイルをチェックすると前のPCで作成したプログラムやスクリーンショットなどが散見されましたが、元のファイルにあった階層関係及びファイル名が失われているようでした。
#2.$OFフォルダって何なのか
microsoftの質問フォーラムにていくつか回答が載っていました。windowsのファイル履歴によるバックアップの際に、フォルダ名(ファイル名)+タイムスタンプの文字数が255文字の制限を超えた時、あるいはパスが長すぎる時に別のファイル名として保存されたものが、$OFにまとめられているようでした。OF(Over Flow)ということらしいです。



https://answers.microsoft.com/en-us/windows/forum/windows8_1-files/file-history-and-the-of-folder-on-my-external/ba3bf6bf-7d09-4c93-a1ba-9689f2739981

#3.解決手段
フォルダを全部開いてファイルをチェックしていたら日が暮れてしまうので、ファイルに残っている情報をもとにシェルスクリプトでファイルの分別を行うことにしました。ファイルにある情報とは拡張子のことです。xlsxだったりpngのような拡張子ごとにファイル分けされれば、このままの状態よりは探しやすくなると思います。

```sh:of.sh
#IFS(Internal Filed Separator)
IFS_BACKUP=$IFS
IFS=$'\n'  
     
#全てのファイル再帰検索
ALLFILE=$(find . -name '*.*')

#全てのファイルから、拡張子を重複なしで抽出 sedでタイムスタンプなどを取り除いている
find . -name $ALLFILE | sed -r s#"\./[0-9]*/[0-9]* \([0-9]{4}_[0-9]{2}_[0-9]{2} [0-9]{2}_[0-9]{2}_[0-9]{2} UTC)."## >> in.txt
EXTENSION=$(sort in.txt | uniq)

for folder in $EXTENSION
do
    #その拡張子のファイルができていないなら新たに作成する
    if [ ! -e {$folder} ]; then
            mkdir $folder
    fi
done

for file in $ALLFILE
do
    #拡張子ごとにファイルに振るい分ける
    EX=$(echo $file | sed -r s#"\./[0-9]*/[0-9]* \([0-9]{4}_[0-9]{2}_[0-9]{2} [0-9]{2}_[0-9]{2}_[0-9]{2} UTC)."##)
    #コピーする
    cp $file $EX/
    
done

IFS=$IFS_BACKUP
```
実行後、こんな感じで拡張仕事に割り振られます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692354/da4f5df0-f528-d0e2-4fb2-2905dd6feaf5.png" width=67%>

#4.おわりに
$OFフォルダに重要なファイルがいくつかあったので取り出せて良かったです。しかし、macは使いやすいですね。visual studioかxcodeかで言われると今のところvisual studioの方が好きですが。
Laravelのクエリビルダ(Eloquent)のまとめ

LaravelでのSQLの書き方がごっちゃになってきたので、まとめる。

## Raw

```php
$users = DB::select('select * from users')  
```
insert, update, delete でも同様

## クエリビルダ

```php
$email = DB::table('email')
   ->join('telephone',  'email.id', '=', 'telephone.id') //combining methods
   ->where('vip', true) //constraing methods
   ->orderBy('last_name','desc') //modifiyng methods
   ->get() //ending methods
```

### combining methods
- join
- union

### constraining methods
- select
- where
- orWhere
- whereBetween
- whereIn
- whereNull
- whereExists
- distinct

### modyfing methods
- orderBy
- groupBy and having
- skip and take
- latest/oldest
- inRandomOrder

### conditional methods
- when
- unless

### ending methods
- get
- first
- find
- value
- count
- min/max
- sum/avg
- all(ただしこれは、Eloquentのときだけ)


## まとめ
特にgetを忘れてエラーを出しやすい。
findやallのときはいらないが、それ以外の時は基本いるものと考えたほうが良い。
Refileの保存先をS3に変更する（Rails, AWS）

#環境
- Ruby 2.6.3
- Rails 5.2.4

#[IAM]ユーザー作成
IAMのダッシュボードでユーザーを選択し、ユーザーの追加をクリックします。
ユーザー名を入力AWSアクセスの種類を選択**プログラムによるアクセス**を選択肢、次へ

![スクリーンショット 2021-03-22 12.30.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/972403/44111854-5d12-cbea-f22f-889c87e5dab4.png)


既存のポリシーを直接アタッチを選択後**S3**で検索`AmazonS3FullAccess`を選択し、次へ
ユーザー登録は完了させ、**.csvダウンロード**する。
`access_key` `secret_access_key`が書いてあるので忘れないように保管する。


![（IAM）ユーザーのポリシーの追加](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/972403/1bf8e02e-0a7a-09e6-b741-003a5cfb5fa8.png)


#[S3]バケットポリシーの編集
S3に入ってバケットの選択し、アクセス許可のタブをクリック
バケットポリシーを編集するをクリックし、下のコード追加します。
AWSアカウントのidは右上の自分の名前をクリックし、マイアカウントの数字です。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::awsアカウントのid:user/IAMで作成したユーザー名""
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::バケット名/*"
        }
    ]
}
```


#refile.rbを作成


```
$ touch config/initializers/refile.rb
```

```ruby:config/initializers/refile.rb
require 'refile/s3'

#if !Rails.env.production? # 開発環境でS3へアップロードできているか確認する方法

if Rails.env.production? # 本番環境の場合
  aws = {
    access_key_id: ENV['S3_ACCESS_KEY_ID'], # アクセスキーID
    secret_access_key: ENV['S3_SECRET_ACCESS_KEY'], # シークレットアクセスキー
    region: 'ap-northeast-1', # リージョン
    bucket: 'S3バケット名',
  }
  Refile.cache = Refile::S3.new(prefix: 'cache', **aws)
  Refile.store = Refile::S3.new(prefix: 'store', **aws)
end
```
`Refile.cache` `Refile.store`残っていると本番環境で反映されなかったので
エラーになる方は消した方がいいです。

```:.env
AWS_ACCESS_KEY_ID="アクセスキー"
AWS_SECRET_ACCESS_KEY="シークレットキー"
```

```ruby:Gemfile
gem "refile-s3"
```
`bundle install`でgemを入れます。
本番環境にも同じように反映させたら完成です。


参考になった記事です
https://qiita.com/matsubishi5/items/c2abdd7375a4c683392a
https://qiita.com/piyor/items/36d2c3c9b8fd638a71a0
UnityでFacebookSDKのAndroidでログインエラーの解決方法

# 概要
UnityでFacebookSDKを使用してAndroidでログインエラーが出てしまう問題の解決方法

# 問題点
KeyStoreの作り方がFacebookで紹介されているものと別であったため、Unity上で表示されたキーハッシュが間違っていた

# 解決方法
確実なキーハッシュの取得方法はIResultのRawResultの中に記載されている

```
// 初期化等は割愛

FB.LogInWithReadPermissions(・・・, OnLogin);


void OnLogin(IResult result)
{
	// こいつを確認する！！！
	Debug.Log($"Raw:[{result.RawResult}]");
}
```


# その他エラー解消のための参考文献
[公式](https://developers.facebook.com/docs/unity/getting-started/android)
[ザ・ゆるふわ](http://ado3s.hatenablog.com/entry/2016/11/07/015736)
[cloudpack.media](https://cloudpack.media/14824)
【Oracle Cloud Infrastructure】CLI で Vault に Secret を作成する

Oracle Cloud Infrastructure(OCI) の Key Management Service である Vault では、暗号鍵だけでなくシークレットも保管できる。

![Screen Shot 2021-03-22 at 12.30.27 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66988/32031fc7-6248-fdd9-a44c-70791858b7ec.png)[^1]

OCI CLI を使った Secret の作成と、作成した Secret の確認について。

## Secret の登録

`oci vault secret create-base64` で作成できる。
`--vault-id` と `--key-id` が必要なので、事前に Vault とマスター鍵を作成しておく必要がある。
なお、管理コンソールからは平文のまま作成することもできるが、CLI からは Base64 値だけのよう。

```shell-session:fish
$ set secretvalue (echo "This is a test value" | base64)
$ echo $secretvalue
VGhpcyBpcyBhIHRlc3QgdmFsdWUK
$ oci vault secret create-base64 -c ocid1.compartment.oc1.exampleuniqueID --secret-name test-value --vault-id ocid1.vault.oc1.ap-tokyo-1.exampleuniqueID --key-id ocid1.key.oc1.ap-tokyo-1.exampleuniqueID --secret-content-content $secretvalue
{
  "data": {
    "compartment-id": "ocid1.compartment.oc1.exampleuniqueID",
    "current-version-number": 1,
    "defined-tags": {
      "control_internal": {
        "owner_id": "${iam.principal.id}",
        "owner_name": "oracleidentitycloudservice/hitsumabushi845@example.com"
      }
    },
    "description": null,
    "freeform-tags": {},
    "id": "ocid1.vaultsecret.oc1.ap-tokyo-1.exampleuniqueID",
    "key-id": "ocid1.key.oc1.ap-tokyo-1.exampleuniqueID",
    "lifecycle-details": null,
    "lifecycle-state": "CREATING",
    "metadata": null,
    "secret-name": "test-value",
    "secret-rules": null,
    "time-created": "2021-03-22T03:22:39.184000+00:00",
    "time-of-current-version-expiry": null,
    "time-of-deletion": null,
    "vault-id": "ocid1.vault.oc1.ap-tokyo-1.exampleuniqueID"
  },
  "etag": "d89a537eba6c2f7652a4cf6647d3cf673b6290bc3423b85a4719e676c0d4c6e6"
}
```

## Secret の確認

`oci secrets secret-bundle get` で作成済みの Secret を取得する。
Base64 値の場合は jq と組み合わせて以下のようなワンライナーで確認できる。

```shell-session
$ oci secrets secret-bundle get --secret-id ocid1.vaultsecret.oc1.ap-tokyo-1.exampleuniqueID | jq '.data["secret-bundle-content"].content' -r | base64 -d
This is a test value
```

## See also 

- [OCI CLI Command Reference - vault](https://docs.oracle.com/en-us/iaas/tools/oci-cli/2.12.8/oci_cli_docs/cmdref/vault.html)
- [OCI CLI Command Reference - secrets](https://docs.oracle.com/en-us/iaas/tools/oci-cli/2.12.8/oci_cli_docs/cmdref/secrets.html)
- [SpeakerDeck - Vault概要](https://speakerdeck.com/oracle4engineer/oci-vault-ji-neng-gai-yao-tote-zheng)

[^1]: 図は[SpakerDeck](https://speakerdeck.com/oracle4engineer/oci-vault-ji-neng-gai-yao-tote-zheng)から。
複数行のUILabelのテキストを垂直方向に中央揃えにする方法(iOS)

## はじめに

UILabelのテキストは工夫しないと垂直方向に中央揃えにできません。
先日私が教えてもらって実現した方法を紹介します。

## 環境

- OS：macOS Big Sur 11.1
- Xcode：12.4 (12D4e)
- Swift：5.3.2
- iOS：14.4

## やり方

1. 透明のビューを配置し、適切にAuto Layoutを設定する
2. ラベルを透明のビューの上に配置し、Align Center Y to:に設定する  
![スクリーンショット 2021-03-22 12.41.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/531cd42e-0f5c-78bf-7141-bf915591d990.png)

以下の画面の「名前」がこの方法で実現しています。
![Simulator Screen Shot - iPhone SE (2nd generation) - 2021-03-21 at 20.36.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/d94ded91-e2e7-5507-4d19-f214fdb924f1.png)

「ドラゴン」など名前が1行でも垂直方向に中央揃えになっていることがわかります。

## おわりに

これだけで実現できます！
UILabelはデフォルトでサイズが可変なので、それを利用した方法です。

## 参考リンク

- https://twitter.com/the_uhooi/status/1373449342351147011?s=20
android:translationX（translationY）とは

`android:translationX（translationY）`は、「座標」を使ってViewを位置を指定する属性です。

android:translationX（translationY）共に、画面中央を0として「X座標」「Y座標」を指定します。

[リファレンス](https://developer.android.com/reference/android/view/View#attr_android:translationX)によると、「px/dp/sp/in/mm」を指定出来るとのことです。

# 使い方

まずは、何も設定していない状態です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365643/e8e32976-558c-653a-58a5-a9d686582d85.png" width="300" />

`android:translationX="100dp"`を指定すると、右側に「100dp」だけ移動します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365643/00200aac-2167-5ee1-2e7e-05a40a9ad1ca.png" width="300" />

もし左側に移動させたい場合は、`android:translationX="-100dp"`のようにマイナスを指定します。

次は、Y座標で移動させるために`android:translationY="100dp"`を指定します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365643/38185b82-c45d-0441-1970-90b656092daa.png" width="300" />

上に移動させたいときはX座標のときと同様に、`android:translationY="-100dp"`にマイナスを指定します。
【Kotlin 初心者】アプリにロゴを設置する方法

## アプリにロゴを設置する方法
アプリを作る際には必ずロゴを設置しなければいけません。
手順はとても簡単です。

Android Studioなら簡単にロゴを設定できます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320838/8e4cdc98-574f-3718-9673-f1c18ba097dc.png" width="400">

- 参考URL
https://developer.android.com/studio/write/image-asset-studio?hl=ja

## 手順
- app > res > New > image Assetをクリック

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320838/9d7a33bd-2974-e42c-58b2-eed1325f4f7b.png" width="400">

- このような画面が出てきます

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320838/8e4cdc98-574f-3718-9673-f1c18ba097dc.png" width="400">

ここでロゴ画像をアップロードやテキストでアプリ名を入力し、Next > Finishをクリックすれば完了です
deviseの削除方法

```
rails db:rollback
```
①マイグレーションファイルをdownにしてusersテーブルを削除

```
rails d devise:views
```
②devise関連のviewsを削除

```
rails d devise user
```
③deviseを介して作成したUserモデルを削除


```
rails d devise:install
```
④deviseをアプリケーションから除く
Powerwash 後の Crostini に対する restore が途中で止まるときの対応

# TL;DR

正解: Penguin コンテナに割り当てられたストレージのサイズを確認し、足りなさそうなら増やす。

# 対象

stable channel で現象確認

Version 89.0.4389.82 (Official Build) (64-bit)

dev channel で問題解消

Version 91.0.4449.0 (Official Build) dev (64-bit)

でもたぶん stable でも同じ方法で解消できると思う。

# 理由

GUI 経由で作成したバックアップ (拡張子 .tini) は、実は圧縮をかけた tar アーカイブでしかない。よって、バックアップを取ったコンテナに、どれくらいのストレージがあったのかは記録されていない。

一方、Powerwash 後に有効にした Penguin コンテナには 7.5GB のストレージが割り当てられる。

仮に展開後に必要となる容量が 7.5GB を超える(厳密にはそれ以下でも起きうる)場合、展開先となるコンテナは空きストレージが枯渇する。よって、途中で失敗する。

考えてみれば当たり前。しかし拡張子が独自なので、その辺もよしなにしてくれると思い込んでしまいがち。

# 余談

ある時期の LXC では、データベースのロック解除待ち周りで "Database is locked" なるエラーがでるケースが報告されている。

https://github.com/lxc/lxd/issues/6439

トラブルシュートの途中で、このバグを踏んだ。当初はこれが restore 失敗の原因かと思ったのだが、どうやら GUI 経由での restore に関しては無関係のようだ。

一方、(過去に推奨されていた) CUI でのリストアでは、このバグ踏むんじゃないかなぁとかいう気が少しする。
エラ〜メッセージ

エラーメッセージの日本語化の実装
app/modelsにて

with_options numericality: { other_than: 1 } do
    validates :category_id
    validates :status_id
    validates :cost_id
    validates :prefecture_id
    validates :by_send_id
  end

と記述。するとこのように表示される。

https://i.gyazo.com/257cb457c1e59d19c9150372b1b06d56.png


しかしこのままでは下５つの「１以外の値を入力してください」の部分がユーザー視点だと分かりづらい。

そこで


with_options numericality: { other_than: 1, message: 'を選択してください' } do
    validates :category_id
    validates :status_id
    validates :cost_id
    validates :prefecture_id
    validates :by_send_id
  end

このように変更。

すると

https://i.gyazo.com/4ac8ab75924cb81e3ed2eca358c21203.png

これで分かりやすくなった。
[swift×Firebase]ドキュメントIDから単体情報をクエリする方法

# やりたかったこと

ドキュメントIDを使用して、各データにアクセスしたかった。
今回は、複数ではなく単体のデータさえ返って来ればよかった。

# やったこと
以下のようにドキュメントIDはクエリ条件に設定することが可能。

「.whereField(FieldPath.documentID(),  in: [documentid])」

```
func getMemo(documentid:String){
        
        let db = Firestore.firestore()
        
        db.collection("memoes")
            .whereField(FieldPath.documentID(),  in: [documentid])
                .getDocuments(){ (querySnapshot, err) in
                if let error = err{
                    print("error: \(error.localizedDescription)")
                    return
                }
                guard let snapshot = querySnapshot else{
                    return
                }
                for document in snapshot.documents{
                    print("ドキュメントタイトル：\(document.get("title") as! String)")
                }
            }
    }
```

これでできた。
Djangoアプリの記述方法

## なぜアプリが必要か？

様々なページが増えるとテンプレートやデータが増える。
アプリごとに管理するほうがわかりやすい。開発がしやすい。

プロジェクトは一つ。アプリは複数作られる。

まず、プロジェクトのurls.pyがリクエストを受けて、その後にアプリごとの
urls.pyに振り分けられる。

## アプリの記述

pycharmでappを作成する。
![スクリーンショット 2021-03-22 11.27.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1226385/77534df2-f79e-b995-d27d-29db1f87d6d1.png)

startappコマンド
```
manage.py@djangoProject > startapp helloworldapp
```

プロジェクトのurls.pyからアプリのurls.pyにつなげるためにincludeを使用する。


```djangoProject/urls.py
from django.contrib import admin
from django.urls import path, include
from .views import helloworldfunction, HelloWorldView

urlpatterns = [
    path('admin/', admin.site.urls),
    path('hello/', include('helloworldapp.urls'))
]
```

アプリのurls.pyでは、hello/を抜いていることに注意。

```helloworldapp/urls.py
from django.urls import path
from .views import hellofunction

urlpatterns = [
    path('world/', hellofunction),
]
```



```helloworldapp/views.py
from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.
def hellofunction(response):
    return HttpResponse('hello')
```
文字列を指定文字数で分解し、逆順で出力する

# 目次

[1.はじめに](#1)
[2.リトルエンディアン](#2)
[3.import](#3)
[4.文字列を指定文字数で分解](#4)
[5.逆順に並び替える](#5)
[6.splitを使う場合](#6) 


<h1 id="1">1.はじめに</h1>

…主に自分が見直すための記録です…

16進数の文字列データをリトルエンディアンにしたかった。

調べると split で正規表現を用いて分解する例が多かったが、今回は
0E0A0D6F0014A55F29
みたいな区切られていない文字列を
[0E,0A,0D,6F,00,14,A5,5F,29]　(配列)
　　　　　　　↓
295FA514006F0D0A0E  (リトルエンディアン文字列)
にしたかった。

<h2 id="2">2.リトルエンディアン</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/721559/6f8fca4c-a7b9-5260-2513-84d68ba64e85.png)


<h1 id="3">3.import</h1>
以下をimportします。

 ```java
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
```


<h1 id="4">4.文字列を指定文字数で分解</h1>

```java

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SortingStrings {

    public static void main(String[] args) {
        String hexString = "0E0A0D6F0014A55F29";
        System.out.println("変換前:" + hexString);

        String result = sortingHex(hexString);
        System.out.println("変換後:" + result);
    }

    /**
     * 16進数文字列を逆順にする関数
     * 
     * @param str
     * @return result
     */
    public static String sortingHex(String str) {
        //Matcherで分割する文字数を指定する　今回は2文字で分割
        final Matcher m = Pattern.compile(".{1,2}").matcher(str);
        //Listを作成
        List<String> strList = new ArrayList<>();

        while (m.find()) {
            //作成したListに分割しながら挿入する
            strList.add(str.substring(m.start(), m.end()));
        }
        String result = strList.toString();
        //結果を返す
        return result;
    }
}
```
これで

```
変換前:0E0A0D6F0014A55F29
変換後:[0E, 0A, 0D, 6F, 00, 14, A5, 5F, 29]
```
と出力されます。

<h1 id="5">5.逆順に並び替える</h1>
Listを逆順に並び替えます。
sortingHexの中身のみ下記に示します。

```java

 public static String sortingHex(String str) {
        // Matcherで分割する文字数を指定する 今回は2文字で分割
        final Matcher m = Pattern.compile(".{1,2}").matcher(str);
        // Listを作成
        List<String> strList = new ArrayList<>();

        while (m.find()) {
            // 作成したListに分割しながら挿入する
            strList.add(str.substring(m.start(), m.end()));
        }
        //ListのCollectionsで逆順にする
        Collections.reverse(strList);
        String result = strList.toString();
        return result;
    }
```

これで

```
変換前:0E0A0D6F0014A55F29
変換後:[29, 5F, A5, 14, 00, 6F, 0D, 0A, 0E]
```
と出力されます。リトルエンディアンになった！
配列形式ではなく文字列で出力したい場合は、

```java
String result = strList.toString();　の部分を
↓
String result = String.join("", strList);
```
とすればいい。
出力結果

```
変換前:0E0A0D6F0014A55F29
変換後:295FA514006F0D0A0E
```
<h1 id="6">6.splitを使う場合</h1>
~~変更前が0E:0A:0D:6F:00:14:A5:5F:29 みたいな形なら split が使える。~~
@saka1029 さん からのアドバイスを基に追記。
split を使えばもっと簡単でした！　正規表現の勉強をスルーしたつけがｗ


```java

public static String sortingHex(String str) {
     List<String> strList = Arrays.asList(str.split("(?<=\\G..)"));
     Collections.reverse(strList);
     String result = String.join("", strList);
     return result;
}
```

JavaScriptだと slice とか、もっと書き方がわかるけどJavaは完全シロートでちょっと詰まってしまいました…。
コントローラー　単体テスト実装

今回詰まった内容を備忘録のためと、知識定着させるためアウトプット！

現在ポートフォリオで簡単な画像付きの投稿サイトを作成中、コントローラーの単体テストを行っておりました。

`indexアクションにリクエストするとレスポンスに投稿済みの画像が存在する`

上記テストだけがどうしてもうまくいかず、進まなかった状況です。


開発フレームワークは`rails`を使用しており、
`RSpec` `FactoryBot`
は導入済みの状態です。

エラー内容

```
TypeError:
       no implicit conversion of ActiveStorage::Attached::Many into String
     # ./spec/requests/posts_spec.rb:19:in `block (3 levels) in <top (required)>'
```

ソースコード

`posts_spec.rb`

```
equire 'rails_helper'
describe PostsController, type: :request do
  before do
    @post = FactoryBot.create(:post)
  end

  describe 'GET #index' do
    it 'indexアクションにリクエストすると正常にレスポンスが返ってくる' do 
      get posts_path
      expect(response.status).to eq 200
    end
    it 'indexアクションにリクエストするとレスポンスに投稿済みのテキストが存在する' do
      get posts_path
      expect(response.body).to include(@post.name)
    end
    it 'indexアクションにリクエストするとレスポンスに投稿済みの画像が存在する' do
      get posts_path
      expect(response.body).to include("@post.images")
    end
    it 'indexアクションにリクエストするとレスポンスに投稿検索フォームが存在する' do
      get posts_path
      expect(response.body).to include('')
    end
  end
end
```

`posts.rb`

```
FactoryBot.define do
  factory :post do
    name { '投稿名' }
    post_text { '投稿文' }
    association :user

    after(:build) do |post|
      post.images.attach(io: File.open('public/test_image.png'), filename: 'test_image.png')
    end
  end
end
```


上記の記述で行っていました。
どうしても画像の確認だけができず、つまずいていたという状況でした。

エラーログから考察するに、画像がstring（文字列型）になっているため確認が取れないよと認識する。

そのため`binding.pry`を入力してターミナル上で情報の確認
`response.body`
`@post`
`@post.images`
`@post.images.blobs`

上記全てをターミナル上で確認して、正常に画像がある事を把握する。

画像があるのに対して、string（文字列）になってしまっているエラーのためなぜかを考察する。

そこで、

```
include("@post.images")
```

上記の記述の仕方が行けないのではないかと仮説を立てる。

画像情報を取得しているname属性の値を入れてみた。

```
include("post[images][]")
```

上記に変更してみたが、同様のstring（文字列）のエラーが出ている。

それでエラーが出るのであれば、直接画像のimg属性のクラス名を指定するやり方で再度実行する

```
include("item-box-img")
```

上記コードで出力を行う。

そうしたらテストが成功した。

エラーの原因で文字列になってしまっているというところに着目し、修正を加えて行ったのがエラー解読につながったとみている。

未だ一点だけ不明点があり、
なぜ画像を指定する際に、その画像のname属性ではなく、クラスを指定しなくては行けないのかという点が不明であった。

同じ指定方法をしているのになぜなんだろうと思っている。

参考記事等も見つからず、もしご教授いただけるようでしたら、コメントいただけましたら助かります！


今回はコントローラー単体テストで画像確認のテストをする際におきたエラーでした。

同じようなエラーで迷われている方いましたら、是非ご参考にして頂けましたら幸いです！

宜しくお願いします！
Mac Terminal ディレクトリ構造の可視化

##概要
ターミナルでこんな感じにフォルダ構造を可視化したいと思った。
ちょっと調べるとTreeっていうコマンドがあるらしいと知ったのでちょっとメモメモ

[サンプル図]

```zsh

❯ tree sampleTypeScript -L 2 --filelimit 10
sampleTypeScript
├── node_modules [40 entries exceeds filelimit, not opening dir]
├── package-lock.json
├── package.json
├── src
│   └── index.ts
├── tsconfig.json
└── tslint.json

```
##導入方法
homebrew がインストールされている前提で進みます
###インストール
これだけ（簡単や・・・）

```zsh
% brew install tree
```
終わるとこんな感じでパスとか表示してくれる

```zsh
==> Downloading https://homebrew.bintray.com/bottles/tree-1.8.0.arm64_big_sur.bottle.tar.gz
######################################################################## 100.0%
==> Pouring tree-1.8.0.arm64_big_sur.bottle.tar.gz
🍺  /opt/homebrew/Cellar/tree/1.8.0: 8 files, 158.3KB
```

###確認方法
```zsh
% tree --version
tree v1.8.0 (c) 1996 - 2018 by Steve Baker, Thomas Moore, Francesc Rocher, Florian Sesser, Kyosuke Tokoro
# ↑ tree --version と入力でこんなのが出てきたらOK
```
##使用方法
ちょっと使いそうなやつだけメモします。

```zsh
% tree --version # バージョン確認
% tree --help # ヘルプ表示
% tree # 現在のディレクトリを全てtreeで表示 (めっちゃいっぱいでてびっくりした)
% tree （フォルダ名） # tree で表示したいフォルダを選択
% tree -L (数値) # 何下層まで表示するか
% tree --filelimit (数値) # 表示するディレクトリの要素の上限を指定（上限以上だと表示されません）
```
色々と組み合わせたり正規表現などのパターンマッチも使用できる為色々応用が効きそう。
上の [ [サンプル図](#概要) ] は sampleTypeScriptフォルダの中身を2階層まで表示して欲しいんだけどを中身が10以上のフォルダは中身は表示しないでっていう感じです。

##参考
[【 tree 】コマンド――ディレクトリをツリー状に表示する](https://www.atmarkit.co.jp/ait/articles/1802/01/news025.html)
AzureBlobストレージのファイルをphpで削除する

本当はディレクトリ指定して下層にあるやつ丸ごと削除したかったが
仮想ディレクトリだから出来ないらしいので
対象のディレクトリ内のファイルリストを取得→1ファイルごとに削除処理するしかないらしい
とてもめんどくさい

```php
public function deleteBlob(){
	$listBlobsOptions = new ListBlobsOptions();
	$listBlobsOptions->setPrefix("対象のディレクトリ名");
	$fileList = $this->blobClient->listBlobs("コンテナ名", $listBlobsOptions);
	foreach ($fileList->getBlobs() as $val){
		$this->blobClient->deleteBlob("コンテナ名",$val->getName());
	}
	return ;
}
```

## 解説
### ListBlobOptionsでプレフィックスを指定する
コンテナ以下の下層ディレクトリにあたる部分を指定

```
container/folder1/folder2/test1.txt
container/folder1/folder2/test2.txt
container/folder1/folder2/test3.txt
container/folder1/folder2/test4.txt
```

↑こういう時、folder2以下にあるテキストファイルを全部削除したい場合は

```php
$listBlobsOptions->setPrefix("folder1/folder2");
```

と指定しましょう。

### 指定したPrefix内のファイル一覧を取得

listBlobsで対象のコンテナに対してBlobsOptionを付与
fileListに一覧データが入ります。

### 1個ずつ取り出して削除処理を実行する

fileList内にBlobsメンバがあるのでfileList->Blobsをforeachでブン回したら
privateだからアクセス出来ないよ！って言われたので、
ソースを読んでみたらgetBlobsってpublicメソッドがあったからそれを使う。
同様にBlob->nameもprivateだったのでgetNameメソッドで取得。

**おわり。**
IAMユーザーに AWS Cost Explorer へのアクセスを許可する

# 概要
IAMユーザーで Cost Explorer にアクセスするための設定方法を備忘として残しています。
設定前は画像の通り権限エラーとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503672/a3a1a08b-569a-8238-2ef9-d9314df224d9.png)

# 手順
### 画面右上のアカウント名から「マイアカウント」をクリック
※ルートユーザーでログインしている状態で操作してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503672/50addb59-0a46-b348-19ea-69daec8db807.png)
### IAM ユーザー/ロールによる請求へのアクセス を有効化
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503672/cf508d41-73dd-edbf-0c92-4df7ef4d50cf.png)
### ポリシーを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503672/29015922-e832-5bdb-de50-e0b20e03d167.png)
### JSONで下記の通りに記述
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503672/fbcec15e-175e-aec3-c155-6f10d5e70f36.png)

~~~
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ce:Get*",
                "ce:Describe*",
                "ce:List*",
                "ce:GetCostAndUsage",
                "account:GetAccountInformation",
                "billing:Get*",
                "payments:List*",
                "payments:Get*",
                "tax:List*",
                "tax:Get*",
                "consolidatedbilling:Get*",
                "consolidatedbilling:List*",
                "invoicing:List*",
                "invoicing:Get*",
                "cur:Get*",
                "cur:Validate*",
                "freetier:Get*"
            ],
            "Resource": "*"
        }
    ]
}
~~~

※Action の aws-portal が廃止され、機能毎に細分化されました。

### ポリシー名を入力して作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503672/3f2bdd0d-b0f5-42d2-1bb1-9411d7ac3b52.png)
### IAMユーザーにポリシーをアタッチ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503672/8bc2c9a8-c11f-16e5-4251-758b8cfaf5e2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503672/7252f07b-abd2-09e7-8e19-4abaab3a8429.png)

以上で設定が完了です。
JavaScript コンテキストとスコープ

　　変数や関数の実行コンテキストでアクセスできるデータ及び動きが決められる。そして実行コンテキスト毎に「変数オブジェクト」という物を紐付けている、実行コンテキストの中で宣言した変数と関数はその「変数オブジェクト」の中に存在している。外部では直接「変数オブジェクト」をアクセスできないが、内部で使われている。

　　ブラウザの中ではグローバルコンテキストがwindowオブジェクトです。そこで、letとconst以外で宣言したグローバル変数と関数はwindowオブジェクトのプロパティとメソッドになるわけです。


###コンテキストスタック(context stack)
　　すべての関数呼び出しには独自のコンテキストが存在する。プログラムの実行が関数の中に入った時、該当関数のコンテキストがコンテキストスタックの中にpushされる。関数の実行が終わったら該当関数のコンテキストがコンテキストスタックからpopされる。これによってプログラムのコントロール権が一個前のコンテキストに移動する。よって今現在プログラムのコントロール権を持っているのはコンテキストスタックへ最後にpushされたコンテキストです。
　　上記で見たの通り、JavaScriptプログラムの実行の流れがこのコンテキストスタックによって制御されている。

　　図で見るとこんな感じです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1088099/250e9c5c-bbc7-a452-29d2-b2505b0797a9.png)

###スコープチェーン(scope chain)
　　コンテキストのプログラムが実行する際変数オブジェクトの「スコープチェーン」を構築する、このスコープチェーンによって各コンテキストのプログラムがアクセスする変数や関数の順番を決める。今実行中のコンテキストの変数オブジェクトが常にスコープチェーンの先頭にあります。
　　グローバル変数オブジェクトが常にスコープチェーンの最後にあります。
　　コンテキストのプログラムを実行する時、利用する変数や関数をこのスコープチェーンの先頭から最後のグローバル変数オブジェクトまで検索していきます、見つけたらそこで終了、見つけられなかったらエラーになる。

```JavaScript:スコープチェーンの例
var globalVar = "global";
function outterFunc(){
  let outVar = "outterFunc";
  
  function innerFunc(){
     let innerVar = "innerFunc";
     
     console.log(globalVar);  //アクセスできる
     console.log(outVar);  //アクセスできる
     console.log(innerVar);  //アクセスできる
  }
  innerFunc();
  console.log(globalVar);  //アクセスできる
  console.log(outVar);  //アクセスできる
  console.log(innerVar);  //アクセスできない
}
outterFunc();
console.log(globalVar);  //アクセスできる
console.log(outVar);  //アクセスできない
console.log(innerVar);  //アクセスできない
```
図でみるとこんな感じです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1088099/dea29bc1-9ed7-8855-a47b-e81f04945f14.png)
　　矢印のように内部のコンテキストはスコープチェーンを使って外部コンテキストの変数や関数を検索してアクセスする、逆の外部から内部をアクセスすることはできない。

####「catch」と「with」におけるスコープチェーン
実行コンテキストは主にグローバルコンテキストと関数コンテキストの二種類です。
だが「try/catchのcatchブロック」と「with」の場合はスコープチェーンの先頭に一時的なコンテキストを追加する。

* 「catch」の場合、追加したコンテキストには例外情報が入っている、この例外情報は「catch」の中でしかアクセスできないわけはスコープチェーンから考えると分かり易い（IE9以前ではこのように実装されていないので、catch以外のところでもアクセスできる）。
* 「with」の場合もスコープチェーンから考えると{}の中で変数をアクセスするようにwithで指定した対象オブジェクトのプロパティを簡単にアクセス出来ちゃう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1088099/816555d3-1e62-e684-0abd-6ed39efba7f4.png)
図のように実行プログラムが「catch」又は「with」に合った際、スコープチェーンの先頭に一時的なコンテキストを追加される。
[Python][Pandas] Dataframeの列の処理いろいろ

個人的な備忘録です。


pandasの文字列の列にスライスを適用
https://note.nkmk.me/python-pandas-str-slice/
df['a'].str[:2]


pandasで文字の長さによる抽出
https://ja.stackoverflow.com/questions/63216/pandas%E3%81%A7%E6%96%87%E5%AD%97%E3%81%AE%E9%95%B7%E3%81%95%E3%81%AB%E3%82%88%E3%82%8B%E6%8A%BD%E5%87%BA
mask = df['moji'].str.len() >= 3
df[mask]


pandas.DataFrame, Seriesの要素の値を置換するreplace　正規表現
()で囲んだ部分をグループとして、置換後の値の中で\1, \2のように順番に使用可能。
https://note.nkmk.me/python-pandas-replace/
df.replace('(.*)li(.*)', r'\1LI\2', regex=True)
※rを入れるのを忘れないこと！

カラム名変更
df.rename(columns={'A': 'a', 'C': 'c'})
※意外に面倒・・

データフレームの列・行の合計追加
df['Total'] = df.sum(axis=1)  #列
df.loc['Total']= df.sum() #行
https://stackoverflow.com/questions/20804673/appending-column-totals-to-a-pandas-dataframe

Change to datetime format　強引にdatetimeに変換
https://stackoverflow.com/questions/25146121/extracting-just-month-and-year-separately-from-pandas-datetime-column
df['date_column'] = pd.to_datetime(df['date_column'])

DatetimeからYYYY-MMに変換する
df['Month']=df['Month'].dt.strftime('%Y-%m')

列の中で条件に合うものを、他の列の値にする
loc, ilocでブールインデックス参照
https://note.nkmk.me/python-pandas-where-mask/
df.loc[~(df['A'] < 0), 'A'] = df['B']

ちょっと複雑な例：
df.loc[(~df["dest"].str.contains('USA')) & (df['name']=='mellisa'), 'name'] = 'hole'


（列には関係ないが、便利なので載せておく）

全部のシートへアクセス
for sheetN in pd.ExcelFile(fname).sheet_names:
https://stackoverflow.com/questions/26521266/using-pandas-to-pd-read-excel-for-multiple-worksheets-of-the-same-workbook
A360「Excelの高度な操作：テーブルをフィルター」アクション

#A360「Excelの高度な操作：テーブルをフィルター」アクション
Excelの高度な操作パッケージに、「テーブルをフィルター」というアクションがあります。
こちらは、Excel内で定義されたテーブルに対して、フィルターをかける操作となります。
具体的に何が出来るのかイメージしづらいので、実際に使ってみた内容をご紹介します。

##下準備
用意したのはこちらのエクセル。
Yahooファイナンスから取ってきた今の値上がり率上位のデータですが、
この「テーブルをフィルター」アクションを使うには、Excelでテーブルが設定されている必要がありますので、
Excelのメニューから挿入→テーブルと選択し、テーブルとして定義します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/237814a7-b94f-f651-fddc-88b32b1f5368.png)

すると、表の部分にカーソルを合わせると「テーブルデザイン」というメニューが表示されるようになります。
この時、左端にテーブル名が表示されます。アクションの中ではこのテーブル名をIDとして使用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/4dedab44-54c4-3a77-c018-0250ae70b676.png)

##Bot作成
ではBotを作っていきます。
フィルターを適用するだけなので、シンプルにExcelを開いてフィルターをかけ、閉じています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/dfd527b4-d597-8573-6e57-582d32a42076.png)

例えば、「東証」を含むテキストでフィルターをするには、下記の様に設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/2f34959a-9c40-fab3-b373-5ca59bcefa2d.png)

##実行結果
今回、C列の「市場」に対してフィルターを掛けましたが、きちんと適用されています。（ラベル行にフィルターアイコン出てます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/eaea3698-da5a-793a-376b-a18b845f0fb0.png)

フィルターアイコンクリックすると、その内容が出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/d9826981-349d-ca02-93eb-867eae91fc12.png)

詳細を出すと、指定通りに設定されているのが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/49b7e11d-d945-74e3-d3b8-9f6bb9035f39.png)

##条件2つ設定できる？
Excelでは、ユーザー設定フィルターとして条件をAND/ORを使って2つ設定できるようになっていますが、
残念ながらこのコマンドからは設定できないようです。
必要な場合は、ショートカットコマンドを利用して設定する必要があります。
Chef で Ruby 2.4 を使っていて依存関係を解決した話

# Chef で Ruby 2.4 を使っていて依存関係を解決した話

- td-agent のバージョンには 2, 3, 4 などがある
    - https://docs.fluentd.org/quickstart/td-agent-v2-vs-v3-vs-v4
- [fluent-plugin-bigquery](https://github.com/fluent-plugins-nursery/fluent-plugin-bigquery) に依存で [google-api-client](https://github.com/googleapis/google-api-ruby-client) とかが入る
- required ruby version が 2.5

| td-agent | Ruby |
|:-:|:-:|
|  v4  |  2.7  |
|  v3  |  2.4  |

## 起こったこと

```shell-session
       STDERR: ERROR:  Error installing fluent-plugin-bigquery:
        signet requires Ruby version >= 2.5.
```

chef でインストールバージョンを特に変更していないのに，`fluent-plugin-bigquery`のインストールができなくなった．
Error は，`requires Ruby version >= 2.5`．
確かに，今の td-agent の Ruby version は 2.4 なので満たせていないが，今までインストールできていた．

## Require (Ruby) version を確認する

### 依存関係を確認する

例えば，1つの gem の require を確認するのは簡単だが，そこに至るrequire tree を確認しておかないとどういう解決をするか検討しにくい．

https://github.com/googleapis/google-api-ruby-client/blob/master/google-apis-core/google-apis-core.gemspec

とりあえず，これは Require 2.5 なので無理．

検索してみたところ依存関係を再帰的に辿ってくれれるツールがあるらしい．

https://gist.github.com/andrew-d/2927533


http://rubygems.org/ → https://rubygems.org/ にするだけで動く

どういう依存ツリーでそのパッケージ(Ruby 2.5 以上を必要としているかはこれでわかる)

### required バージョンを確認する

```
$ ruby depsearch.rb fluent-plugin-bigquery | grep signet | sed -e 's/^ *//' | uniq
signet ~> 0.14
```

https://github.com/googleapis/signet/compare/signet/v0.14.0...signet/v0.15.0#diff-cd03b1ea000c03b6c5c89bccd9d04486b36976aef245f00ea92aaef2bd98ebb7L24

version 0.14.1 → 0.15 で変更になっている．

https://railsdoc.com/gem

| バージョン | 説明 |
|:-:|:-:|
| ~> x.0  | x.1からx.9は良いが、メインのバージョンがあがるとは不可。例えば、3.2は良いが、4.0は不可など  |

## 対応する

シンプルには，td-agent パッケージを v4 にすれば Ruby 2.7 になってOK そうだが，
td-agent パッケージを上げるのが少し面倒だった．
([td-agent](https://github.com/treasure-data/chef-td-agent) が v4 に対応していないというのもある)

v3 のまま何かできないかと考えて，先に必要なgem をインストールしておけばrequired が満たされて新しいバージョンをインストールしようとしないだろうという想定．

```shell-session
$ gem install signet -v=0.14.1
```

大丈夫そうでした．
	
## その他

バージョンチェックのツリーをバージョン指定して確認できるといいかも．
あと Ruby のバージョンのチェックも可能にしてもいいかもな．と思った．

https://gist.github.com/atm-snag2/f5e0a27a1984fc911fd06003285417b3

https://github.com/googleapis/google-api-ruby-client/blob/f1fe51bc249dc65f40b4b94a81dae1671d671e4f/google-apis-core/google-apis-core.gemspec#L26

```ruby
  gem.add_runtime_dependency "signet", "~> 0.14"
```

正直これが `~> 0.14.0` だったらなあ… とは思った
言語やフレームワークが多すぎてわからん

スマホ開発いいなぁ、Web開発いいなぁ、と思いながらネットを見たり、ツイートを見たり、はたまた畑の違う人とお話したりするけど、○○で作ってみたとか、○○ってあれだよね、とか見ても聞いても？？何それ、言語なの？フレームワークなの？何のフレームワークなの？と頭がついていきません。もう多すぎんねん！何回聞いても覚えられん！
ということで、独自にまとめてみました。

１．聞いたことのある単語をあげて、言語なのかフレームワークなのか調べる
２．フレームワークなら何の言語のフレームワークなのか調べる
３．言語はどの分野で使われているのか調べる
（調べるといっても検索して、Wikiるだけなのですが）

４，組み込み、PC、Web、スマホの分野にざっくり分けてみて可視化してみる

その結果がこれ
![言語フレームワーク.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649784/62b77268-183a-59b5-e010-40a1a178af44.png)

以下、注意事項）

a. 黒字が言語、白抜きがその言語のフレームワークです。

b. 言語はできるだけ、以下のサイトの人気言語の20位まであげてみました。
https://www.tiobe.com/tiobe-index/
ただし、20位以内のものであげてないものもありますし、20位以降であげているものもあります。独断と偏見で。

c. 色、大きさは適当です。言語のアイコンカラーを使おうとしましたが青が多すぎたので、出来るだけ青じゃないものを。先ほどのランキングサイトのグラフに使われてる色もつかってたりします。

d. どの分野にも対応している言語もたくさんありますが、流行りも含めてより使われることが多いであろうという分野に独断と偏見で寄せています。Pythonは機械学習でよく使われていますが、機械学習の分野をどう記載していいか浮かばなかったので、省いていますし、真ん中に置いちゃってます。

間違っていたり、意見はいろいろあると思いますが、修正する気はありません。あくまでも2021年3月時点での私の中で整理した結果です。
ネット上の一情報としてとらえてください。

以上、ご覧いただきありがとうございます。
Powershell で Curl を実行する際は引数が少し違う

# 2021-11-04 追記

`curl.exe` を叩けば Shellscript ライクな引数でも実行できるとコメントで教えて頂いたので試してみました。Powershell ではエラーになってしまいますが、**コマンドプロンプトでは** 以下のコマンドで実行できました！

``` ShellScript
"C:\windows\System32\curl.exe" ^
    http://localhost/auth -X POST ^
        -H "Content-Type: application/json" ^
        -d "{ 'user': 'user1', 'pw': 'abcxyz' }"
```


# `curl` を Powershell 上でそのまま打ったら失敗した

フレームワークのチュートリアルに、以下のような `curl` を打てと書かれていた。

``` ShellScript
curl http://localhost/auth -X POST \
                           -H "Content-Type: application/json" \ 
                           -d "{ 'user': 'user1', 'pw': 'abcxyz' }"
```

最近の PowerShell は `ls` とかが普通に使えるので、`curl` も行けるかと思いコピペして実行したら以下の通りエラーとなった。

```
Invoke-WebRequest : パラメーター 'Headers' をバインドできません。
"Content-Type: application/json" の値を "System.String" 型から
"System.Collections.IDictionary" 型に変換できません。
発生場所 行:1 文字:44
... (省略) ...
```

引数が Linux の `curl` とは完全一致していないようで、先述のコードは以下の通り書いたら動いた。

```
Invoke-RestMethod -Uri "http://localhost:5000/auth" -Method POST `
                  -Body (@{"user"="user1";"pw"="abcxyz"} | ConvertTo-Json) `
                  -ContentType "application/json"
```

ヘッダーを送信したい場合、以下のように書いたら動いた。

```
$headers = @{}
$headers["Authorization"] = "JWT aaa.bbb.ccc"
$headers["X-AAA"] = "AAA"
$headers["X-BBB"] = "BBB"
Invoke-RestMethod -Uri "http://localhost:5000/protected" -Headers $headers
```
gitignoreが反映されなかったとき

#why
railsでgitignoreが反映されず、大事なenvファイルがGitHubモロ出しになってしまっていたのでこの対処方をアウトプットします。

##問題
「.envファイル」を作成し、APIキーなどを記述、

```.env.
API=*****************
API2=****************
```
GitHubに載せたくないので「gitignore」に「.envファイル」を記述

```.gitignore.
/.env
```

ローカルにプッシュ

```ターミナル.
git push origin master
```

しかしこれだけだとローカルリポジトリのコードをみてみると「envファイル」が、、、
中を見てもしっかりとAPI記述されてしまっています、、、

##解決
こちらがとてもわかりやすかったです
https://blog.s-giken.net/394.html

原因はなにやらGitのキャッシュがあるため、、、

キャッシュとは、一度得たリソースをクライアント側で保存しそれを使い回す仕組みのことらしいです
ここでいうクライアントはGit側だと思います、

そのためgitignoreを変更した際はキャッシュをクリアしなければ反映されないということですね

ということでキャッシュをクリアしていきます。
クリアの仕方は調べるとかなり出てきました、誰もがぶち当たる初学者の壁的なものらしいです

```アプリケーションのターミナル.
git status

git rm -r --cached .
git status

git add .
git status

git commit -m ".gitignore update"

git push origin master
```

##解説
「git rm -r --cached .」で一括でキャッシュをクリアしています。
すべてのキャッシュを削除することに抵抗がある場合は、下記のようにファイルごとに指定することもできます。

```ターミナル.
git rm -r --cached ファイル名
```

「git add」後に「git status」を実行すると、更新された .gitignoreの内容に従って更新されたファイルのみが表示されます。

```ターミナル.
git add .
git status

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	deleted:    .env
```

このとき、想定したファイルが正しく追加、削除されていることを確認してください。
想定していた結果と違う場合は、一度「git commit」した後、改めて、.gitignoreファイルを更新し、最初の「git rm」からやり直します。

何度もやり直しできるらしいので安心してできますね

最後にプッシュしてあげて再度ローカル側を確認してみるときちんと「gitignore」が反映されていました！

-----
この件ではかなりGitHubを触っていたのでいろいろ覚えることができました！！
今回とても参考にしてもらった記事です
https://blog.s-giken.net/394.html
海外のPlayストアのランキングを見る方法(クエリ使うだけ)

以前アフリカのザンビアに住んでいたことがあるのですが、ふと、「**ザンビアでの今のGooglePlayストアのランキングってどうなってるんだろ**？」と気になりました。

ググるとプロキシ変える方法やApp Annieを使う方法が出てきましたが、PlayStoreのURL( https://play.google.com/store/apps/top )にクエリ(`?hl=ja&gl={2文字の国コード}`[^1])を加えるだけでも国外のPlayストアの情報を見ることができるようです。
※国コードである根拠はないのですが、挙動見る限り合ってそう。

例

- US
  - https://play.google.com/store/apps/top?hl=ja&gl=US
- ザンビア
  - https://play.google.com/store/apps/top?hl=ja&gl=ZM
- ロシア
  - https://play.google.com/store/apps/top?hl=ja&gl=RU
- 中国
  - https://play.google.com/store/apps/top?hl=ja&gl=CN

余談ですが、中国では有料アプリをPlayストアからインストールできない[^2]ので、無料アプリのランキングしかないですね。 


参考

[^1]: 国コード検索
  - https://www.iso.org/obp/ui/#search (Alpha-2 codeを使う)
[^2]: Google Play ユーザーへの配布がサポートされている国や地域 | 購入者の現地通貨と価格帯
  - https://support.google.com/googleplay/android-developer/table/3541286
signate:日本取引所グループ ニュース分析チャレンジ①

#初めに
この記事は、現在signateで開催されているニュース分析チャレンジのコンペティションの自分の学習過程を発信するために記述しています。

おそらく、チュートリアルに関しては自分なりに噛み砕いた形でコンペティション期間中に記載し、実際の提出モデルに関しては、コンペティション終了後に提出すると思います。

#本記事のシリーズについて
本記事は、signateで公開されているチュートリアルを自分なりに噛み砕いて、
再掲載することを目的に記述しています。

そのため、誤り等あるかもしれませんが、その際にはご指摘いただくとありがたいです。

#本コンペティション参加動機
僕は、資産運用を実際に行っており、できれば機械学習を活用してポートフォリオを作成できないか考えていました。今回は、その足掛かりとなりうるコンペティションとなっているため、かなり意欲的に参加・開発ができるかなと思っています。

このコンペを通して次のことを身につけたいと思っています。
・基礎的な金融知識
・機械学習を活用した、資産運用AIの開発

#次回予告
次回は、チュートリアル第二章について自分なりに咀嚼して書いていきたいと思います。