OmniAICreator/Qiita-1.07M huggingface dataset:
【Javascript】郵便番号から住所を自動入力する方法

#成果物
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689019/17c46f71-c3cf-0ad3-adf7-9c7b4beaf485.png)
郵便番号を入力することで住所をある程度自動で入力できるものを作ったので
そのアウトプットです。(100-0000と入力しても自動入力可能です。)

#環境
・Windows10
・Visual Studio Code
・jQuery
・zip cloud

###zip cloudとは？
[公式サイト](https://zipcloud.ibsnet.co.jp/)の概要よると、
日本郵便のWebサイトで公開されている郵便番号データを再配信するサービスです。
Web APIをたたくと以下のようなJSONで返してくれます。

```
{
	"message": null,
	"results": [
		{
			"address1": "東京都",
			"address2": "千代田区",
			"address3": "",
			"kana1": "ﾄｳｷｮｳﾄ",
			"kana2": "ﾁﾖﾀﾞｸ",
			"kana3": "",
			"prefcode": "13",
			"zipcode": "1000000"
		}
	],
	"status": 200
}
```


#コード
zip cloudから得られるJSONを利用して成果物のコーディングをすると…

```index.html
    <body>
        <form>
            <div>
                <label for="zip">郵便番号：</label><br>
                <input id="zip" type="text" size="10">
            </div>
            <div>
                <label for="address">住所：</label><br>
                <input id="address" type="text" size="35">
            </div>
        </form>
        <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
        <script>
            $(function () {

                //郵便番号の入力時に実行
                $('#zip').change(function () {
                    
                    //WEB API取得
                    $.getJSON('http://zipcloud.ibsnet.co.jp/api/search?callback=?',
                        {
                            zipcode:$('#zip').val()
                        }
                    )
                    //結果を取得してからの処理
                    .done(function (data) {
                        //中身が空でなければその値を住所欄に反映
                        if (data.results) {
                            var result = data.results[0];
                            $('#address').val(result.address1 + result.address2 + result.address3);
                        } else {
                            $('#address').val('該当する住所が存在しません。')
                        }
                    })
                });
            });
            
        </script>
    </body>
```
Javascriptってすごいなー（小物感）
引数エラー


引数エラーが出ました。bmiメソッドはprintData内で受け取ってるので、代入においては型を指定する必要がありませんでした。


修正前

```main.java
class Main {
  public static void main(String[] args) {
    printData(fullName("Kate", "Jones"), 27, 1.6, 50.0);
    printData(fullName("John", "Christopher", "Smith"), 65, 1.75, 80.0);
  }

  public static void printData(String name, int age, double height, double weight) {
    System.out.println("私の名前は" + name + "です");
    System.out.println("年齢は" + age + "歳です");
    System.out.println("身長は" + height + "mです");
    System.out.println("体重は" + weight + "kgです");
    
    // 変数bmiに、bmiメソッドを用いてBMIを代入してください
        double bmi = bmi(double height, double weight );
    
    // 変数bmiを用いて、「BMIは◯◯です」と出力してください
    System.out.println("BMIは"+bmi+"です");
    
  }

  public static String fullName(String firstName, String lastName) {
    return firstName + " " + lastName;
  }
  
  public static String fullName(String firstName, String middleName, String lastName) {
    return firstName + " " + middleName + " " + lastName;
  }
  
  // bmiメソッドを定義してください
  public static double bmi(double height, double weight){
    return weight / height / height;
  }
  
}
```

修正後

```main.js
class Main {
  public static void main(String[] args) {
    printData(fullName("Kate", "Jones"), 27, 1.6, 50.0);
    printData(fullName("John", "Christopher", "Smith"), 65, 1.75, 80.0);
  }

  public static void printData(String name, int age, double height, double weight) {
    System.out.println("私の名前は" + name + "です");
    System.out.println("年齢は" + age + "歳です");
    System.out.println("身長は" + height + "mです");
    System.out.println("体重は" + weight + "kgです");
    
    // 変数bmiに、bmiメソッドを用いてBMIを代入してください
        double bmi = bmi( height,  weight );            ##**ここを変更。
    
    // 変数bmiを用いて、「BMIは◯◯です」と出力してください
    System.out.println("BMIは"+bmi+"です");
    
  }

  public static String fullName(String firstName, String lastName) {
    return firstName + " " + lastName;
  }
  
  public static String fullName(String firstName, String middleName, String lastName) {
    return firstName + " " + middleName + " " + lastName;
  }
  
  // bmiメソッドを定義してください
  public static double bmi(double height, double weight){
    return weight / height / height;
  }
  
}
```
WindowsのPostgreSQLで初めてDBを作ってみた

#はじめに
とりあえず仕事で、なんとはじめてpostgreSQLでテーブルを作ってみてphpで動かしてなんちゃらやるということをすることになった。
Wordpressでも結局使ってないのに。まあでも、これでテーブル作れたら、Woredpressで新規のテーブル作ってそれを表示させるなんてこともできる自信がつくと思うので頑張ろうと思う（まあそもそもWordpressのはMySQLなんだけど）

# やったこと
まずとにかくpostgreSQLをインストールして使えるようにすること。

https://www.dbonline.jp/postgresql/install/index1.html


https://www.dbonline.jp/postgresql/install/index3.html

　※　PATHを設定するというのはコマンドスクリプトから起動できるようにする作業のこと。

上記を見れば、多分インストールしてコマンドスクリプトで起動するところまでは困ることはないと思う。
※　コマンドスクリプトからインストールするという手もあるみたいですがそれは他のサイトを見ていただければ。

ただ、問題はそこから。

上を見ていても、
まずユーザー作るのが先なのか、DBを作るのが先なのか、というのがよくわからなかったのでググった。
いろいろ調べて、
ひとまず何もかも新規で、テーブルを作成するまでの順番を整理する。

## ０）コマンドスクリプトを起動
Win + R　で［ファイル名を指定して実行］ダイアログを開き「cmd」で検索し実行する

## １）　postgreSQLに接続
具体的には、
まずpostgresのユーザー（postgres)で、DB（postgres）にログインする形で
postgreSQLにログインする

```
psql -d postgres; //できない場合があります
psql -d postgres -U postgres; //上でできなければこれで
```
※　インストール完了後に、postgresユーザーとpostgresデータベースはできてる
※　ちなみにpsqlであって、psglではない。注意。　
　　　postのｐとs、そして最後のSQLのｑlを略称としてコマンドにしたっぽい。
　　　そう覚えておけばコマンドを打ち間違えるのは無いと思う。

## ２）　ユーザー作成と権限付与

<b>DBを作成するにはコマンドを実行するロールがスーパーユーザーか、
CREATEDB 権限を持っていないといけない。</b>
たしかインストールしてコマンドスクリプト内でユーザー作った気がするが、
忘れてしまったので確認
※ postgreSQLではユーザーのことをロールという

```
\du
```
※ Winの場合は英語モードで￥キーを押せばそのままバックスラッシュになる
　Macの場合はoption + ¥　キー

ロール名はpostgresだけでした。
なかったので以下で作る

```
create user (新規ロール名);
```
Enterして、「CREATE ROLE」と出てたら成功している。
※最後に「;」をつけるのを忘れない！
どうやら、;をつけるのとつけないコマンドの両方あるようだ

次にセキュリティ上、パスワードも設定する。

```
\password (今登録したロール名) 
```
Enterすると、「Enter new password:」がでるので新パスを入力、Enter
すると、「Enter it again:」が出るのでもう一度入力してEnter
postgres=#　（入力待ち状態）となって設定できたことになる

ただ、これはcreateの段階でできるらしい

```
create user (新規ロール名) with password '(新規パスワード)';
```
次に権限を付ける
具体的にはスーパーユーザー、DBを作れる権限をつける

```
ALTER ROLE （今登録したロール名）　with SUPERUSER　CREATEDB;
```
SUPERUSER と、CREATEDBの間は半角スペースを入れる
ALTER ROLEと返ってきて、成功している
\duしてみると権限が付与されていることが確認できる

##３）　データベース作成
ではつぎにいよいよDB作成。
今作ったロールで作成をするので作ったロールに移動する。

まずは一旦ログアウト。

```
\q
```
Uをさっき作ったロールにして、 最初はpostgres（デフォルトDB）にアクセスする形でログイン

```
psql -U （登録したユーザー）　postgres
```
●●のパスワード:というのが出るのでさっき設定したパスを入力
すると

```
psql(バージョン名）
"help"でヘルプを表示します。
postgres(テーブル名）=#
```
次にいよいよDB作成

```
create database (新規データベース名);
```
※；を忘れないように！（しつこい）
すると、しばらく待機中になって
「CREATE DATABASE」となり成功する

次にそのDBにアクセス

```
\connect (新規作成したDB名)
```
ここでは;をつけない。
どうやら頭に\がつくと、；はつけないみたいだ

すると、
「データベース（新規作成したDB名）にユーザ"(さっき登録したロール)"として接続しました。」
とでて、
（新規作成したDB名）=#　となり、コマンド待機状態になる

##４）　終わりに　 テーブル作成に入る前に
次に、テーブルを作るわけだが、あらかじめどういうテーブルを作成するのか考えておいて、
さらにはエクセルとかパワポとかでテーブルを仮作成してそれを見ながら作る。
こうすると考えて修正する手間が省けて工数削減できる。
これは当たり前っちゃ当たり前な話だと思うのだけど、重要だと思う。

ちなみに、テーブル作成から再開する場合は、
上のような面倒なことをやらなくても、下記コマンドからいきなり再開できる。

```
psql -U （登録したロール）　(新規作成したDB)
```

##　おまけ

たとえば、新しいロールを作りたい場合、
一旦ログアウトして、posgreロールでログインしてから作成しないといけない
なぜかというと、ロールを作れる権限がないから。
だから、結局ここの１）からやることになる。

逆に言えば、１）がもし既存のロールだった場合、
DBやロールを作る権限を持ってるロールでなければ１）以降のことができないので注意する。

新規ならともかくDB運用している間に、新規ロールを作りたくなったときにこれを実行して
エラーになる、、、ていうパターンがあり得ると思うのでメモとして残しておく
SORACOM Discovery 2021 Day3

# SORACOM Discovery 2021 Day3 レポート

## 【特別パネル】社会を進化させるIoT、イノベーション

「低容量向け」のサービスを競争力とする
→ 大企業とのターゲットの差別化→テクノロジーの民主化

お客様と企業の持続的関係がDXの本質

BtoCからBtoBへ

ユーザによる新しい発想、ユースケースが新しい技術ネタへとつながる

「危機」が新しいイノベーションを起こす
ベンチャー企業とのつながり→うまくいっても失敗しても学べることが多い

## AIカメラ、IoTを活用した、ユーザ系SIerの研究開発と進め方

IoT：離れたものを動かす
AI：人の知能をディジタル化

ニーズを起点にしたPoC、PoCから先を見据えて進めていくことが重要
提供されているデバイス、ネットワークを活用することでアプリケーションレイヤーへ集中できる

IoTと聞いても具体的なものをイメージするのが難しい
→ できることをみせていくことでわかりやすくする

感想：弊社の施策での取り組みに不足しているところを突きつけられました。。

## その他

* ５Gなどの技術を活用して価値を生み出していくことがDXにおいては重要。技術を導入することが目的ではない。
* 両利きの経営→探索と深化のバランスが大切
azure File shareをmacから直接マウントする方法

#目的
azure File shareを、ブラウザからではなく、macから直接マウントする。
タイトル通りなのだが、こちらの[Azure公式の説明](https://docs.microsoft.com/ja-jp/azure/storage/files/storage-how-to-use-files-mac)を読んでも私は全くできなかったので、メモする。

#手順
1. つなぎたいazure file shareのページをブラウザで開き、左側の"Properties"をクリックし、出てきた"URL"欄のurlをコピー
1. Mac からFinder を開き、上部の[移動]メニューから[サーバーへ接続]を選択し、先ほどコピーしたurlを貼り付け、httpsをsmbに書き換えてエンターを押す。→ユーザー名とパスワードの入力を求められる。
1. [azure portal](https://portal.azure.com/)　の対象のresource groupのページをブラウザで開き、左側ペインの"Access keys"をクリックする。ここの、"Storage account name"を上記の"ユーザ名"
に、"show keys"をクリックして現れた"Key"を上記の"パスワード"に入れる。複数のキーがある場合はどちらでもよいが、key1を使えば良いだろう。

#終わりに
以上、ちょっとしたメモでした。
【BizRobo!】稼働の仕方でエラー時の挙動が異なる

# はじめに
現在、RAPを実務で行っていますが、まだまだまだまだ経験が浅く、日々勉強中です。
本記事については、自身の備忘録も含め同じ様な所で頭を抱えている方に対して、
少しでもヒントになり、先に進める力となれれば良いなと思い記事にしましたーー！

## 今回のTips
Kapplets実行とスケジュール実行でエラー時の挙動が異なる件について、ご紹介します。
これは、はじめ知らなくてKappletsにて稼働しているお客様のロボットでエラーが発生した時にエラー内容を見ていると、何かおかしいなという違和感から突き詰めていくと分かった事実です💦

当時は、だいぶ困りました…このknowledgeをはじめから知っていたら、あんなに解決まで時間がかからなかったはずなのに…と思いましたので、ご紹介します。

## Tips概要
詳しくは、以下のknowledgeを見て頂ければと思うのですが、
内容としては、エラーが発生した時にその後に処理されるステップに差分が発生するという内容です。開発時は、「ここで、エラーが出ても、次のブランチで…」って計算しながら開発していると思うのですが、その常識がKappletsで実行した時は通じないよという内容です。

[▼Kappletとスケジュール実行でエラーハンドリングの挙動が異なる](https://knowledge.bizrobo.com/hc/ja/articles/360027607431-Kapplet%E3%81%A8%E3%82%B9%E3%82%B1%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E5%AE%9F%E8%A1%8C%E3%81%A7%E3%82%A8%E3%83%A9%E3%83%BC%E3%83%8F%E3%83%B3%E3%83%89%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%AE%E6%8C%99%E5%8B%95%E3%81%8C%E7%95%B0%E3%81%AA%E3%82%8B)

## まとめ
実際のロボットをどの形式(MC or Kapplets)で稼働するかによって、ロボットの挙動が変わるので開発段階では気づきにくいです！要件調整をするときに、このことを念頭に置き、このロボットの内容だとKappletsだなと思った場合は、上記を考慮しながら開発を進める様にしましょう！
DialogFragmentをdismiss()するときに安全に値渡しする（setFragmentResultListenerを使用）

``setTargetFragment()``が気付いたらdeprecated（非推奨）になっていたので書き換えよう・・・

と思い、調べてみたのですが思いのほか自作コールバックをしている記事ばかり:joy:

自作コールバックはやめたほうが良いです。
画面回転やbluetoothのオンオフなど、何かしらの設定変更をするとクラッシュしてしまったりするので。

というわけで、あれこれ調べていたら書き換える方法がわかったので共有します。

まずは呼び出し元に

```kotlin:ParentFragment.kt
   override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        
        this.childFragmentManager.setFragmentResultListener(
            RESULT_CODE,
            this,
            { requestKey, bundle ->
                // ここにコールバックされます
            })
    }
```

このように書きます。
注意するところは、childFragmentManagerを使うことです。
子fragmentにリスナーを設定するのでこっちです。

次に呼び出し元についてですが、

```kotlin:childDialogFragment.kt
    companion object {
        const val RESULT_CODE = "111"
    }

    override fun onCreate(savedInstanceState: Bundle?)) {
        viewModel.hoge.observe(this) {
            this.parentFragmentManager.setFragmentResult(RESULT_CODE, Bundle())
            dismiss()
        }
    }
```

ここでも注意ポイントはparentFragmentManagerを使うことです。
ここではBundle()をそのまま引数に渡していますが、もし何か他にも値を親にコールバックしたければよしなに設定してください。
ALB+EC2構成をCloudFront+ALB+ECS環境に乗せ換えたときに認証が通らなくなった



## 構成
### インフラ側
CloudFront → ALB → ECS(Nginx用コンテナ→App用コンテナ)

### アプリ側
- よくわからないけれど、CookieにTokenを乗せて認証エンドポイントへリクエストすることで、認証済かどうかを判断する

## 事象
- ブラウザの開発ツールでネットワークの流れを追っていると、ログイン処理時に付与されるはずなSet-Cookieヘッダがない
- なので、それ以降の処理すべてにClookieがセットされておらず、認証エンドポイントからは認証してないとして返ってくる


## 対応
Behavior→ForwardlCookieをAllにするといい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/637713e9-c162-cca6-125f-8995b27d76aa.png)
【BizRobo!】ISAについて

# はじめに
現在、RAPを実務で行っていますが、まだまだまだまだ経験が浅く、日々勉強中です。
本記事については、自身の備忘録も含め同じ様な所で頭を抱えている方に対して、
少しでもヒントになり、先に進める力となれれば良いなと思い記事にしましたーー！

## 今回のTips
今回は、ISAについてご紹介しようと思います。
普段、業務をしている時には、僕はほとんど使用しないんですが、一度あるシステムの自動化をする時に、レガシーなシステムだった為に、ISAではないと認識しない状況があり、その時に初めて使用しました。まるまる使い方を覚える必要はないと思うのですが、BizRobo!では、こういった要素認識方法もあるという事をは知っておいて損はないと思います!

## Tips概要
ISAとは、
[▼ISA（Intelligent Screen Automation）の説明](https://knowledge.bizrobo.com/hc/ja/articles/360028154751)

>10.3から実装された、Intelligent Screen Automation（ISA）は、Citrixなどの自動化APIの効果が限られている、または利用できないアプリケーションを自動化するために設計されています。
>ISAは、ボタン、アイコン、オプションボタン、チェックボックス、テキストフィールド、テキストラベル、およびその他のUI要素を自動的に見つけるのを支援する拡張イメージ検索機能と画面認識機能を提供します。
>このオプションは、ウィジェットツリーが正しく配置されていないアプリケーションや、それ以外のファインダを作成することが困難なアプリケーションで使用できます。

要は、通常であれば認識しない画面をISAモードに変更する事で、認識できるようになりますよ！という内容です。別のknowledgeに記載もありますが、ISAによるオブジェクト認識で生成される要素(属性)は、ISA独自のものとなります。

詳しいISAの各要素の説明に関しては、以下になります。
[▼ISAの要素(各属性)の説明](https://knowledge.bizrobo.com/hc/ja/articles/360029240151-ISA%E3%81%AE%E8%A6%81%E7%B4%A0-%E5%90%84%E5%B1%9E%E6%80%A7-%E3%81%AE%E8%AA%AC%E6%98%8E)

ISAモードに変換した後の、開発方法については通常と同じく画面を選択し、クリックステップなどを作成します。
Visual Studio では CMAKE_BUILD_TYPE=Release 指定しても無視される

CMAKE_BUILD_TYPE=Release としても Visual Studio で .sln 開くと VS 上では Debug がデフォルトになる...

Visual Studio では, .sln を開いたときのデフォルトのビルドタイプは指定できませんでした. :cry:

https://stackoverflow.com/questions/19024259/how-to-change-the-build-type-to-release-mode-in-cmake

GUI でやる場合は手動で切り替えが必要です
(CMake スクリプトを頑張ればなにかうまくやれるかもであるが)

Visual Studio 2019 では, CMakeSettings.json or CMakePresets.json で, デフォルトのビルドタイプを設定できるでしょう(未検証)

https://docs.microsoft.com/en-us/cpp/build/cmakesettings-reference?view=msvc-160
【BizRobo!】MC × cron × スケジュール設定について

# はじめに
現在、RAPを実務で行っていますが、まだまだまだまだ経験が浅く、日々勉強中です。
本記事については、自身の備忘録も含め同じ様な所で頭を抱えている方に対して、
少しでもヒントになり、先に進める力となれれば良いなと思い記事にしましたーー！

## 今回のTips
今回は、MCのスケジュール実行機能にてスケジュールを設定する時に使用する「Cron」についてご紹介したいと思います。Cronに関しては、世の中に情報がたくさんあるので、検索してもらえばOKなんですが、RPATのknowledgeを見つけましたので、ご連携したいと思います。

[▼Cron(クーロン)形式のスケジュール](https://knowledge.bizrobo.com/hc/ja/articles/360034654472-Cron-%E3%82%AF%E3%83%BC%E3%83%AD%E3%83%B3-%E5%BD%A2%E5%BC%8F%E3%81%AE%E3%82%B9%E3%82%B1%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB)

実際の設定に関しては、スケジュールの設定画面でCronを設定してみて、
「次の実行」を見てもらえば正しく設定できているかわかるので、何度も試してみてください！
【BizRobo!】Excelの行数列数制限について

# はじめに
現在、RAPを実務で行っていますが、まだまだまだまだ経験が浅く、日々勉強中です。
本記事については、自身の備忘録も含め同じ様な所で頭を抱えている方に対して、
少しでもヒントになり、先に進める力となれれば良いなと思い記事にしましたーー！

## 今回のTips
今回の内容はDSでExcelを扱う際の行数や列数の制限についてです。
Excelで作業する際に、そこまで大きな行数や列数を使用する事はないと思うのですが、
ロボット化が出来た時に、「自動で出来るんだから」という理由で処理数が増え、手作業なら使用しない行数や列数を使用するケースに直面するかもしれません。
そんな時に今回のTipsを思い出して頂ければ幸いです。

## Tips概要
knowledgeに記載されている内容になりますが、DSでExcelを扱う際も行数と列数の制限は存在します！

行数制限：1,048,576
列数制限：1,048,576

明言はされていませんが、Excelの仕様に則って制限が決められている様です。
詳しくは、以下のknowledgeをご覧ください。

[▼Excelの行数列数制限](https://knowledge.bizrobo.com/hc/ja/articles/360028155931-Excel%E3%81%AE%E8%A1%8C%E6%95%B0%E5%88%97%E6%95%B0%E5%88%B6%E9%99%9)

普段、業務中にそこまでの行数を使用する事は、稀だと思いますが、
例えばお客様から不意に「これってロボットで処理する場合、どれぐらいまで行数いけるの？」って質問された時に、『Excelの仕様と同じなので、1,048,576行まで大丈夫ですよ』と、素早くこたえられたら、信頼が爆上がりするかもです！笑

頭のどこかに入れておくと便利な情報だと思います！
【BizRobo!】DSでExcelを読み込む際のファイルサイズの制限について

# はじめに
現在、RAPを実務で行っていますが、まだまだまだまだ経験が浅く、日々勉強中です。
本記事については、自身の備忘録も含め同じ様な所で頭を抱えている方に対して、
少しでもヒントになり、先に進める力となれれば良いなと思い記事にしましたーー！

## 今回のTips
BizRobo!ではExcelファイルの操作を行う際、DSの中でExcelファイルの情報をキャッシュして遷移状態を保持し、1MBのファイル操作で最大1GBのメモリがロボット内で消費される事があります。
これにより、メモリが不足しファイルを読み込めない等の事象が発生することがあります。
今回は、そんな時に実施する対処方法についてknowledgeを見つけましたので、ご紹介します。

[▼DSでExcelを読み込む際のファイルサイズの制限](https://knowledge.bizrobo.com/hc/ja/articles/360032906992-DS%E3%81%A7Excel%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80%E9%9A%9B%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B5%E3%82%A4%E3%82%BA%E3%81%AE%E5%88%B6%E9%99%90#:~:text=RS%2FDS%E3%81%A8Webkit%E9%96%93,%E3%82%B5%E3%82%A4%E3%82%BA%E3%81%AE%E4%B8%8A%E9%99%90%E3%81%A8%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82)

knowledgeでは、**「①DS自体のメモリを増やす方法（64bit端末のみ）」**、**「②DSでExcelを読み込まずに処理するロボットを作成する方法」** の二つが紹介されていますが、もし出来るのであれば運用を少し変えて使用するExcelファイルの変更するというのも、ありだと思います。
(長年使っているExcelファイルで、実は使用していないシートや関数がありました!というのは良く聞く話です)

お客様が手作業で実施していた手順を、そのまま踏襲するだけが自動化のメリットではありませんので、無理のない範囲でお客様への提案はOKだと思います。
Ubuntu で Dash メニューやトップバーがマウスで反応しなくなった

2023/05/19 追記
初出では、Ubuntu20.04の環境上の記事でしたが、2023/05/19 にUbuntu22.04でも同様に有効であることがわかりました。そのため記事タイトルや記事タグも Ubuntu 20.04 から Ubuntu に変更しました。


デスクトップ画面左側のDashメニュー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/bbddcc61-e5f0-6306-b39f-181051d6e12e.png)

や、
デスクトップ画面最上部のトップバー。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/8d57059c-ac11-d7ff-8849-92907b418847.png)

画面更新はなされているけど、マウスに反応しなくなった。

はてな〜？

# 環境

- Ubuntu 20.04 LTS
- Ubuntu 22.04 LTS
- 
# 解決方法


「Ubuntu 18.04でDockが表示されないときの対処方法」
https://qiita.com/Shunmo17/items/3afc05bc49b29af54c05


では、

> alt+F2を押す
> 出てきた画面にrと入力してEnter


と紹介されていた方法を試してみた。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a72331a1-4394-e01c-2bdd-9c44e653e658.png)

しばらく「再起動中」と出て、その後直った。

# Alt+F2+r で何が行われているか

「cinnamon - What commands are run by ALT+F2 and "r"? - Unix & Linux Stack Exchange」
https://unix.stackexchange.com/questions/518001/what-commands-are-run-by-altf2-and-r

によると、gnome を再起動するそうだ。
【BizRobo!】「ファイル繰り返し(For Each File)」ステップにてエラー処理を設定する方法

# はじめに
現在、RAPを実務で行っていますが、まだまだまだまだ経験が浅く、日々勉強中です。
本記事については、自身の備忘録も含め同じ様な所で頭を抱えている方に対して、
少しでもヒントになり、先に進める力となれれば良いなと思い記事にしましたーー！

## 今回のTips
今回の内容ですが、僕がロボットを開発していて「完成した！さぁテストだ！」とテストをしている時に沼りそうになったTipsです。
knowledgeから引用した内容を記載すると…

>「ファイル繰り返し(For Each File)」ステップにて、指定したフォルダ内に対象のファイルが存在しない場合、製品の仕様により、エラーとしては認識されず、ループが一度も実行されず終了(ブランチがある場合はブランチへ移動)します。
そのため、「エラー処理(Error Handling)」タブにて「次の代替手段を試行(Try Next Alternative)」などのエラー処理を設定していても、実行されません。

あるファルダの中にあるファイルをループさせて、1つずつ読込後続処理を進めるようなロボットの場合、そのフォルダにファイルがない場合、製品の仕様によりエラーとして認識されないんです！
当時は、ファイルがばい事も想定しており、それ用のステップも作成していたと思うのですが、その想定していたステップに進まず、僕の作り方が悪いのかなと悩んでいた所、本knowledgeを見つけました。

## Tips概要
対応策としては、ループ時にファイル名が格納される変数に、あらかじめ「NoFiles」などの値を入れておき、その有無でファイルなしかどうかを判断するという内容です。
詳しくは、以下をご覧ください。
[▼「ファイル繰り返し(For Each File)」ステップにてエラー処理を設定する方法](https://knowledge.bizrobo.com/hc/ja/articles/360028583872--%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E7%B9%B0%E3%82%8A%E8%BF%94%E3%81%97-For-Each-File-%E3%82%B9%E3%83%86%E3%83%83%E3%83%97%E3%81%AB%E3%81%A6%E3%82%A8%E3%83%A9%E3%83%BC%E5%87%A6%E7%90%86%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)

これは、あらかじめ知っておかないと、だいぶ沼にはまっていくと思います。
僕と同じような経験をしないためにも、頭の片隅に置いて頂ければ幸いです！
PyTorchのインストール

# 初めに
環境設定......なにそれおいしいの？
そんな自分が出会った，やらなければいけない事orzについて，備忘録として記載していきます．
（文章力が無いので読みづらい場合はすいません...）

本稿では，PyTorchのインストール方法について記載します．

# PyTorchのインストールに必要なこと
##1. CUDAのインストール準備
PyTorchを用いるためにはCUDAをインストールする必要がありますが，最新のCUDAにPyTorchが対応していないってことも......
（確認はしていないため，最新版でも出来る可能性あり）
そのため，入れるべきCUDAのバージョンを確認します．

確認は以下のサイトから行います．（リンク先は公式PyTorchのホーム画面です）
[https://pytorch.org/](#https://pytorch.org/)
![PyTorch.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545522/0138dea0-44f1-59ac-5bde-a90dc5e7e1ee.png)

Compute Platformというのがありますが，ここで選択するのは，自身がインストールしているCUDAのバージョンになります．
そのため，この画面を見て対応されたCUDAのバージョンを控えておきましょう．

##2. CUDAのインストール
以下のサイトから，控えていたCUDAのバージョンを選択し，インストールします．
（リンク先は，CUDAホームページ＞右上の検索マーク＞CUDA Toolkit Archive　で入れます．）

[https://developer.nvidia.com/cuda-toolkit-archive](#https://developer.nvidia.com/cuda-toolkit-archive)
![CUDA.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545522/71d53197-5a5a-3ae4-6993-99b32f2b8a93.png)

私は，CUDA11.1に対応したPyTorchをインストールする予定であったため，CUDA Toolkit 11.1.1をインストールしました．
因みに，画像内のVersionがWindows10の10の部分（のはず），Installer TypeはPCがネットワークに接続されていればnetworkの方で大丈夫です．

##3. PyTorchのインストール
後は，PyTorchをインストールするだけです．

[https://pytorch.org/](#https://pytorch.org/)
![PyTorch1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545522/94c5c69d-f992-a3b8-1a2e-500c425701dd.png)


自身の環境に応じてそれぞれ選択し，Run this Command:に記載されたコードをコピペしましょう．

```
conda install pytorch torchvision torchaudio cudatoolkit=11.1 -c pytorch -c conda-forge
```
以上です．

# 動作確認
PyTorchがGPUを認識出来ているか確認するためには，以下のコードを記載します．

```
import torch
print(torch.cuda.is_available())
```
出力が_True_であれば終了です．

# 最後に
次回から，CNNに取り組もうかと考えてます．（......やるとは言ってない）
Docker で Apache2 サーバーを立てる

こちらと同じことを、Apache2 で行いました。
[Docker で Nginx サーバーを立てる](https://qiita.com/ekzemplaro/items/8a73aec039e079e2177f)

<ol>
<li>Apache2 のインストールと起動

```bash
docker run --name some-apache2 -d -p 8080:80 httpd
```

<li>イメージの確認

```text
$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED        SIZE
httpd                latest    30287d899656   25 hours ago   138MB
```

<li>Apache2 が動いていることを確認

```text
$ docker ps -a
CONTAINER ID   IMAGE                    COMMAND                  CREATED          STATUS                      PORTS                  NAMES
38c467378cf0   httpd                    "httpd-foreground"       10 minutes ago   Up 10 minutes               0.0.0.0:8080->80/tcp   some-apache2
```

<li>ブラウザーで http://localhost:8080 にアクセス</li>

![apache2_aa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/6939565c-dfaf-454a-b53f-bfd5e88ee3d3.png)

<li>ssh でログインする

```text
$ docker exec -it some-apache2 bash
root@38c467378cf0:/usr/local/apache2#
```

<li>ログイン後 vim をインストールする

```bash
apt update
apt install vim
```

<li>index.html を編集する

```html:/usr/local/apache2/htdocs/index.html
<html><body>
<h1>It works!</h1>
<p>Jun/24/2021</p>
</body></html>
```

<li>ブラウザーでアクセス

![apache2_bb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/b2e3a823-6d72-8698-6431-76d8ff99b76d.png)

</ol>

## 参考
Docker 内のファイルをホストにコピーする方法

```bash
docker cp some-apache2:/usr/local/apache2/htdocs/index.html /tmp
```

ホスト内のファイルを Docker にコピーする方法

```bash
docker cp index.html some-apache2:/usr/local/apache2/htdocs
```

## 確認したバージョン

```text
$ docker --version
Docker version 28.0.1, build 068a01ea94
```

## ベースになっている OS

```text
# cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
```
ECS FargateからIAMロールでAWSリソースにアクセスする


アプリケーションからのAWSの操作はアクセスキーを発行するのではなくIAMロールを使うことが推奨されています。

FargateのアプリケーションからAWSアクセスキーではなくIAMロールでS3等のAWS上のリソースを操作するのにハマりポイントがあったのでメモ。
EC2からのアクセスと同じだと思いこんでいたら違った。

## 環境
* ECS Fargate 1.14
* aws-sdk-php version3

## 方法
### SDK

SDKの使い方はECSでIAMロールを使う場合と同じ。アクセスキーではなくIAMロールを使う場合は'credentials'は記述しない。

```php
$config = [
    'version' => '2017-10-17',
    'region' => 'ap-northeast-1',
];

return new S3Client($config);
```

### タスクロールに必要なポリシーをアタッチ

タスクからS3などのリソースにアクセスするため、タスクロール（タスク実行ロールではない）にポリシーをアタッチ。
今回はS3、Lambda、Route53等権限が必要なリソースが多くあったため個別サービスに対しての権限ではなく"PowerUserAccess"をアタッチ。ここは要件に応じてもっと細かく制御もできる。
ここまではEC2からのIAMロールの利用と同じ。
![スクリーンショット_2021-06-24_15_38_40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260824/5fc72651-09e4-06ef-5d87-c594115fc239.png)


### ハマりどころ

この状態でタスクを実行すると以下のエラーがでた。

```
2021-06-18 01:52:12 Error: [Aws\Exception\CredentialsException] Error retrieving credentials from the instance profile metadata service. (Client error: `GET http://169.254.169.254/latest/meta-data/iam/security-credentials/` resulted in a `404 Not Found` response:
```

後から分かったのですが、EC2とFargateのタスクロールでは、AWSの認証情報を取得するエンドポイントが異なるそう。

* EC2の場合

```
http://169.254.169.254/latest/meta-data/iam/security-credentials/
```

* Fargateの場合

```
http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
```

Fargateの場合は後者に接続しなければならないのが、`$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI`　この環境変数がセットされていなかったためにエラーが出た模様。
[こちらのブログ](https://sodane.hokkaido.jp/tech/202006301909000211.html)を参考に、環境変数追加のためDockerfileに以下の一行を追加。（Bashの場合）

```
RUN echo 'export $（strings /proc/1/environ | grep AWS_CONTAINER_CREDENTIALS_RELATIVE_URI）' >> /etc/bashrc​
```

これでタスクを実行するとIAMロールでAWSリソースにアクセスできた。


## 参考
* [タスク用の IAM ロール](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-iam-roles.html)
Firefox Quantumの上部メニューエリアをコンパクトにしたい

20230803 firefoxアプデに伴い、表示が崩れたのでCSS修正

# 画面表示領域を拡大したい
今使ってるのは結構上下に広いディスプレイなのだが、なるべく上下領域は大きめに確保したい。
ムダに画面上部を占有しているエリアを小さくしたい。もっと上下領域が欲しい。
そう思って調べてみた。

# 試行１

[Firefox でタブバーを非表示にする方法 - Technotes WEBプログラミング関連の技術系の備忘録用ブログ](https://michaeluno.sakura.ne.jp/technotes/firefox-%E3%81%A7%E3%82%BF%E3%83%96%E3%83%90%E3%83%BC%E3%82%92%E9%9D%9E%E8%A1%A8%E7%A4%BA%E3%81%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/)

[Tree Style Tab](https://addons.mozilla.org/en-US/firefox/addon/tree-style-tab/) というアドオンを入れるのが常道のようだ。
昨今のワイドディスプレイ事情をみるに、横になら多少は広くなってもかまわないだろうという考え。
これを採用。
だいたい上記ページ参照の手順でスムーズにコンパクト化出来るのだが、
この手順だとWindowsOS自体のウィンドウコントロールエリアが邪魔だ。
なのでさらに検索。

# 試行２

[@chatrate - MacでFireFoxのタブを左側に配置し、上部のタブの領域を削除（非表示）する方法](https://qiita.com/chatrate/items/50d9338453f7d2a19ace)
[@techno-tanoC - firefox でタブバーや URL バーを非表示にする](https://qiita.com/techno-tanoC/items/0f9df63bfaf54ced3cfa)

検索すると情報が結構引っかかる。
上記のQiita記事が結構攻めた出来栄えになっていいのだけどれども、少々自分には攻めすぎの設定に見えた。
なので少しだけ、userChrome.cssを改変して掲載する。

# 試行３

```css:userChrome.css
#sidebar-header {
    /* display: none; 20230803コメントアウト */
}
#TabsToolbar {
    visibility: collapse !important;
}
#nav-bar {
    /* margin-top: -32px !important; 20230803コメントアウト */
    /* margin-bottom: -4px !important; 20230803コメントアウト */
}
/* サイドバーのヘッダーを消す */
#sidebar-header {
    display: none;
}

```

###適用前
![スクリーンショット 2021-06-24 152232.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25349/c983bd37-cccf-c424-593b-c7aec5f6ef38.png)
###適用後
![スクリーンショット 2021-06-24 152056.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25349/3f2d3db6-4fd6-c547-16ab-c716219780ab.png)

これで上部メニューエリアが、いい感じにコンパクトな1行表示になったと思う。
WindowsOS側のウィンドウコントロール部すら隠れてしまっているので、Firefoxの終了はタスクバーからのみになりそうだ。
無駄を削って美しい見た目を前にしてしまえば、こんなものは大した問題ではない。

うまくいかない場合は、この辺の、メニューから制御可能な項目はオンオフしてみよう。
あるいはカスタマイズメニューから、ツールバー項目をドラックドロップで移動したりしてみよう。
![スクリーンショット 2021-06-24 154453.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25349/2ed3fa1e-c93c-b2a0-bdf5-e27f67f5dd1b.png)


先人の知恵に感謝。
aurora mysqlでdeadlockエラーが出るがプロセスkillできないとき

# 結論
インスタンスを再起動すればよい

# 環境
エンジンバージョン
5.7.mysql_aurora.2.07.4（mysql 5.7.12）

# 現象
処理中にDBをダウンさせたので後続の処理でdeadlockエラーが出た

```
ERROR 1213 (40001) at line 24: Deadlock found when trying to get lock; try restarting transaction
```

ぐぐると大抵プロセスを探してkillしろと書かれている
こんなかんじ↓

https://libitte.hatenablog.jp/entry/20141129/1417254010

しかし `SHOW ENGINE INNODB STATUS;` で該当のthread idを見つけてkillしてもエラーになった

```sql
kill xxx;
[HY000][1094] Unknown thread id: xxx
```
これでも同じ

```sql
CALL mysql.rds_kill(xxx);
[HY000][1094] Unknown thread id: xxx
```
そもそも `show full processlist;` を見ても該当のidがないのである :thinking: 

# 原因と対処

> There is no way to clear the LATEST DETECTED DEADLOCK section in SHOW ENGINE INNODB STATUS unfortunately. The query has already been killed by the deadlock detector, so there's nothing you can KILL. The only way to reset that information is to restart the server.
> 
> No properly written software should continuously alert due to the presence of something in that output.

https://stackoverflow.com/questions/21573684/mysql-innodb-deadlock-how-to-remove-old-event

クエリは既にデッドロック検出器によってキルされているので、キルできるものはなく、
リセットするには、サーバを再起動するしかない、と書かれている
Thank you jeremycole!

まさにこの状態だったので再起動したところ、 
もう `SHOW ENGINE INNODB STATUS;` に `LATEST DETECTED DEADLOCK` の項は出てこなくなり、後続の処理が動くようになった

# FYI
同じ現象のひと

https://living-sun.com/ja/mysql/572334-why-can39t-i-kill-a-specific-thread-query-in-mysql-mysql-innodb-deadlock-kill.html
アドミニストレーター認定の準備: 設定とオブジェクト～ユーザ設定の練習～

アドミニストレーター認定試験に向けた学習 
アドミニストレーター認定の準備: 設定とオブジェクト 
ユーザ設定の練習
の中にある「練習問題」を解説します
https://trailhead.salesforce.com/ja/content/learn/modules/administrator-certification-prep-setup-and-objects/practice-user-setup?trail_id=administrator-certification-prep&trailmix_creator_id=welcome4&trailmix_slug=prepare-for-your-salesforce-administrator-credential


####質問1/5
![2021-06-24 15_19_23-ユーザ設定の練習 単元 _ Salesforce Trailhead1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/7010bb5b-b7be-08ac-3d68-b17cc83854f2.png)

正解はAです。
ではServiceCloudユーザの有効場所を確認しましょう
それは「ユーザレコード」詳細から可能です。
![ServiceCloud1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/4080969e-a52b-1698-6c8b-77a090e14c36.png)

####質問2/5
![2021-06-24 15_32_25-ユーザ設定の練習 単元 _ Salesforce Trailhead.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/388db9b6-a6d9-2e93-6691-477e1ae3109a.png)

正解はAとBです。

Aの解説として、すべての環境でオリジナルの必要があります。
オリジナルでない場合下記のエラーが表示されます
エラー: ユーザ名がすでに登録されています。
この Salesforce 組織または別の Salesforce 組織に、ユーザ名がすでに存在します。ユーザ名は、すべての Salesforce 組織で一意である必要があります。解決するには、異なるユーザ名を使用します (ユーザのメールアドレスと一致する必要はありません)。
![ユーザ名0624.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/b458d4bc-dcad-0553-dd6a-b62b6eb44e3c.png)

Bの解説として、ユーザ名はメールアドレス形式にしないと下記エラーが発生します
john@acme.comのような形式で設定してください。
エラー: ユーザ名はメールアドレスと同じ形式にしてください(例: john@acme.com)

####質問3/5

![質問3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/91d8e539-e1cb-b1fb-e603-e29163b962eb.png)

正解はAです。
ユーザがログインに失敗しているか否かはユーザレコードのページから確認可能です。

![成功.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/4c94975f-4972-4710-c3f0-7fdd6f306674.png)

「成功」とでていればログインに成功したことが分かります。


####質問4/5
![質問4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/1ca1548a-92a0-71f3-62b5-d57b1e131f0c.png)

正解はBです。
凍結することによりログインできなくなり、またログインさせたい場合は速やかに凍結解除すればいいだけなので楽な運用になります、
凍結する設定はユーザレコードから下記となります。
![凍結.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/10cb13a2-3d6a-ad8e-eacc-23a37190134a.png)


####質問5/5
![質問５.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/1fa4622d-2eb6-4e8b-bf66-5a3f7f6155b5.png)

正解はAです。
無効化させれば再割り当ては可能です。
Python　poetryを使用したPyPIパッケージ公開

# poetryのインストール

基本ドキュメントに従って行う。

[Introduction | Documentation | Poetry - Python dependency management and packaging made easy](https://python-poetry.org/docs/)

```
# pipを使ったインストール(バージョンごとにインストール必須になるがpathの設定等が不要になる。)
pip install poetry

# インストールできているかチェック
poetry --version
```

## API Tokenの登録

### アカウントの作成, API Tokenの発行

[PyPI · The Python Package Index](https://pypi.org/)

### API Tokenの登録

```
poetry config pypi-token.pypi "PyPIのAPI Token"
```

## パッケージの作成, ビルド, アップロード

### パッケージの作成

```
poetry new [パッケージ名]
```

以下のディレクトリが作成されます。パッケージ名のディレクトリの中に、パッケージ名のディレクトリが作成されるので、その中にPythonファイルを入れます。

```
❯ tree
[パッケージ名]
├── README.rst
├── pyproject.toml
├── tests
│   ├── __init__.py
│   └── test_[パッケージ名].py
└── [パッケージ名] (ここにPythonファイルを入れる)
    └── __init__.py
```

`pyproject.toml`ファイルの中に以下の`[tool.poetry.scripts]`を追記してください。
そうすることで、パッケージがコマンドとして使用することができるようになります。

```pyproject.toml
[tool.poetry.scripts]
パッケージ名 = "パッケージ名.[pythonファイル名]:main"
```

パッケージディレクトの中でビルド

```
poetry build
```

以下コマンドでアップロードします。

```
poetry publish
```

## 参考

[[Python] poetryを使用したPyPIパッケージ公開手順 - Qiita](https://qiita.com/sengoku/items/af301fe89b55706ca0c2)

[Python初心者がPyPIにコマンドラインツールを登録してみた](https://blog.freedom-man.com/python-pypi-cli)
【Windows ショートカットキー】　一覧

Windowsで作業用ショートカットキーのメモ。

##ブラウザ操作

|`キー`    |`機能`                  |
|----------|--------------------------|
|**command + R**  |**リロード**|
|**command + T**  |**新規ブラウザ作成**|
|**command + W**  |**ブラウザ削除**|
|**command + shift + T**  |**ブラウザ削除後復元**|


##上下左右に一文字ずつ移動する

|`キー`    |`機能`                  |
|----------|--------------------------|
|**Control + F**  |**カーソルを右へ**|
|**Control + B**  |**カーソルを左へ**|
|**Control + P**  |**カーソルを上へ**|
|**Control + N**  |**カーソルを下へ**|

##テキストの端に移動する

|`キー`    |`機能`                  |
|----------|--------------------------|
|**Home**  |**行先頭に移動**|
|**End**  |**行後尾に移動**|

##行の端に移動する

|`キー`    |`機能`                  |
|----------|--------------------------|
|**Control + Home**  |**行先頭に移動**|
|**Control + End**  |**行後尾に移動**|

##カーソルから行の端まで選択する

|`キー`    |`機能`                  |
|----------|--------------------------|
|**Control + →**  |**行後尾まで選択**|
|**Control + ←**  |**行先頭まで選択**|
【Ruby】10進数 ⇔ n進数の変換

# n進数の文字列を10進数の数値へ変換する → String#to_iメソッド

```ruby
# 2進数を10進数に変換
puts '101'.to_i(2)
#=> 5

# 5進数を10進数に変換
puts '144'.to_i(5)
#=> 49

# 16進数を10進数に変換
puts 'FA'.to_i(16)
#=> 250
```

# 10進数の数値をn進数の文字列へ変換する → Integer#to_s

```ruby
# 10進数を2進数に変換
puts 1010.to_s(2)
#=> '1111110010'

# 10進数を8進数に変換
puts 1010.to_s(8)
#=> '1762'

# 10進数を16進数に変換
puts 1010.to_s(16)
#=> '3F2'
```

https://docs.ruby-lang.org/ja/latest/method/String/i/to_i.html

https://docs.ruby-lang.org/ja/latest/method/Integer/i/to_s.html
React Hooksでレスポンシブデザインを実装する方法

CSSやメディアクエリではなく、Reactのコードでレスポンシブデザインで実装する。

１．useStateで、widthの状態を管理する。

- Window.innerWidthプロパティは、ウィンドウの内部の幅をピクセル単位で返します。

２．useEffectで、window幅の変化を操作する。

- resizeイベント：ブラウザのウィンドウサイズが変更されたときに発生するイベント。

- resizeイベントが発生したときに、handleWindowReize()メソッドを実行する。

- useEffectに空の配列を渡すことで、コンポートマウント時のみレンダリングする。

- window.removeEventListener()で、不要になったときのためにイベントリスナーを削除する。

３．return内で三項演算子を使って、モバイルの時は`<News />`を表示し、デスクトップの時は`<Blog />`を表示する。

```jsx
const OurComonent = () => {

  const [width, setWidth] = React.useState(window.innerWidth);
  const breakpoint = 620;

  React.useEffect(() => {
    const handleWindowResize = () => setWidth(window.innerWidth)
    window.addEventListener("resize", handleWindowResize);

    return () => window.removeEventListener("resize", handleWindowResize);
  }, []);

  return (
    {width < breakpoint ? <News /> : <Blog />} 
  )
```

ただし、ローカルだと問題なかったが、Gatbyを使ってfirebase deployをおこなうと、firebase deployエラーが起きた。

```
 "can't access lexical declaration `width' before initialization" 
```

調べてみたところ、JavaScriptの巻き上げが起こっているからなのか？

##解決方法##
```jsx
  const [width, setWidth] = React.useState(400);
  const breakpoint = 620;

  React.useEffect(() => {
    setWidth(window.innerWidth)
    const handleWindowResize = () => setWidth(window.innerWidth)
    window.addEventListener("resize", handleWindowResize);

    return () => window.removeEventListener("resize", handleWindowResize);
  }, []);

  return (
    {width < breakpoint ? <News /> : <Blog />}
  )
```

useState()で、widthの初期値にwindow.innerWidthを使わないようにして、コードをuseEffect()内に移した。

FIrebase deployのエラーが無くなった。
Salesforce認定アドミニストレーター勉強方法～無料でここまで学べる～

※最新版の情報ばこちらからどうぞ

https://qiita.com/Takaa/items/485dc2dd1e61f31f2ff9


##Salesforce認定アドミニストレーターとは？

Salesforceの基本的な資格です。まずは下記URLから受験ガイドを確認することをおすすめします。
https://tandc.salesforce.com/credentials

##Salesforce認定アドミニストレーター勉強方法は？（無料）
Salesforceのコンテンツにより無料で学べるものがあります。今回は無料で学べるコンテンツをご紹介します。


###1.無料セミナー
定期的に無料試験対策ウェビナーが開催されています。
直近では２０２１年６月１６日に開催されましたが、２０２１年９月１０日にも開催されるようで定期的な開催がされるようです。
下記URLをチェックしましょう。
https://www.salesforce.com/jp/campaign/trailhead-academy/certification-days/

###2.Trailheadでの学習

Salesforce公式のTrailmixがあります。
こちらで一通りモジュールをこなしてみましょう。
https://trailhead.salesforce.com/ja/users/welcome4/trailmixes/prepare-for-your-salesforce-administrator-credential
【Jest】mockClear()・mockReset()・mockRestore()の違い

## mockClear()
- `mockFn.mock.calls` と `mockFn.mock.instances` の配列に格納されている全ての情報をリセットする

## mockReset()
- `mockFn.mock.calls` と `mockFn.mock.instances` の配列に格納されている全ての情報をリセットする
- モックされた戻り値と実装を削除する

## mockRestore()
- モック関数を利用していたものを本物のモジュールに戻す
- `jest.spyOn()` でモック化したモジュールにのみ使用可能
opencv_createsamplesで複数の画像データをまとめて水増しして一つのvecファイルを生成するプログラム

<h1>前置き</h1>
OpenCVで画像認識させる際に<b>opencv_createsamples.exe</b>を用いて画像データの水増しをすると思いますが、この機能の欠点としてポジティブ画像を複数準備した際にまとめて回転や変形の処理をしてくれない...

<b>”-info 〇.txtで実行するとポジティブ画像のフォルダ内から-numで指定した枚数を使ってvecファイルを生成しますという仕様”</b>

であるため、画像データ1つからvecファイルを生成してから最後に<b>mergevec.py</b>を用いて一つにする作業が発生します。
なので本記事では勝手にポジティブ画像のフォルダ内からvecファイルを生成できるコードを自分自身のためにも残しておこうと思い投稿します。

お役に立てたら幸いです。

<h1>環境</h1>
<b>・VScode＋Python3.6.13+OpenCV3.4.14

参考記事は↓

https://qiita.com/obikata/items/1e66dc8c958cac06cacc

<b>作業フォルダは以下の通り</b>

下３つのopecv~~のファイルは[OpenCVのサイト](https://opencv.org/releases/)から
ver3.〇.〇<b>(ver4.〇.〇にはopencv_createsamples.exeがないらしい)</b>のexeファイルをダウンロードし実行後、opencv/build/x64/vc15/binから作業フォルダに移動させましょう。

```terminal
<DIR>          cascade
<DIR>          ng
<DIR>          pos
<DIR>          vec
               samplecreates.py
               samplecreates_ALL.py
               mergevec.py
               opencv_createsamples.exe
               opencv_traincascade.exe
               opencv_world3414.dll
```
<h1>mergevec.pyについて</h1>

 https://github.com/wulfebw/mergevec/blob/master/mergevec.py 
上記のgithubからmaergevec.pyをダウンロードし、作業フォルダに入れておく。

以下のコードを実行すれば、１つのvecファイルが生成される。

```powershell
!python mergevec.py -v vec -o vec/pos.vec
```

-v vec : いままで生成されたvecファイルがあるフォルダを指定
-o vec/pos.vec : 出力先のフォルダと出力するファイル名の指定

<h1>CODE</h1>
必要なファイルは2つ

呼び出されるファイル（コマンドプロンプトに書き込むメインのファイル）↓

```samplecreates.py
import subprocess
from subprocess import PIPE

def main(img):

    print(img) #実行中のファイルを確認する
    
    #opencv_createsamples実行（-numの数字が増やす枚数）
    subprocess.run("opencv_createsamples.exe -img pos/"+img+" -vec vec/positive"+img+".vec -num 20 -maxidev 40 -maxxangle 0.8 -maxyangle 0.8 -maxzangle 0.5 -w 24 -h 24",shell=True)

subprocess.run("python mergevec.py -v vec -o vec/pos.vec",shell=True) #vecファイルを一つにする
```
<b>※エラーが出る場合はパスの見直しを忘れずに</b>

上のファイルを呼ぶファイル（ポジティブ画像のフォルダからリストを作成しファイルの数だけループさせる。）↓

```creates_ALL.py
import os
import samplecreates

#パスの取得&リスト作成　
path = r'C:/Users/user/Desktop/cascade/pos' #ポジティブ画像があるファイルのフルパス
files = os.listdir(path)

for dir in files:
    samplecreates.main(dir)
```

<b>・pathにはポジティブ画像が入っているフォルダのフルパスを貼り付ける。</b>


2つ目のファイルを実行すれば、ポジティブ画像が何百枚もあった場合でも勝手にvecファイルが生成され最終的には<b>pos.vec</b>というファイルが生成されるのでこれを使って学習を始めます。
加えて-numで指定した枚数まで手軽に増やせるので目安とされる7000枚まで簡単にそろえることが出来ると思います。

以上
[python] カレントディレクトリの移動

## やりたいこと
* カレントディレクトリの取得
* カレントディレクトリの移動

## ディレクトリ構造

サンプルのディレクトリはこんな感じ

Sample 
└ Input
├ Output
└  PY
　　├ sample.py 
　　└ sql
　　　└ aaa.sql

## ライブラリ

* カレントディレクトリの取得　`os.getcwd()`
* カレントディレクトリを移動 　`os.chdir()`

## やってみる
`Sample\PY`の**sample.pyが実行ファイル**としてやってみる
よって、カレントディレクトリは`Sample\PY`でスタート

### カレントディレクトリを取得する
`os.getcwd()`を使う

```python
# カレントディレクトリ
print(os.getcwd())
```
```python:結果
c:\Users\Sample\PY
```

### カレントディレクトリの直下のディレクトリを取得する
```python
# カレントディレクトリの直下のディレクトリ
print(os.path.join(os.getcwd(),'sql'))

# カレントディレクトリ
print(os.getcwd())
```
```python:結果
c:\Users\Sample\PY\sql
c:\Users\Sample\PY
```
直下のディレクトリとは`os.path.join`で**つないであげる**
ディレクトリを移動したわけではないので、 **1階層下を取得してもカレントディレクトリは変わらない**

### カレントディレクトリを移動する
`os.chdir()`を使って移動
上の階層は`..`を使う


```python
# カレントディレクトリ
print(os.getcwd())

# 上の階層に移動
os.chdir('../Output')

# カレントディレクトリ
print(os.getcwd())
```
```python:結果
c:\Users\Sample\PY
c:\Users\Sample\Output
```
WEBフレームワーク「express」について

# expressとは
サーバサイドのWEBアプリケーションフレームワークである。
Node.jsで作成する。
必要最小限の機能しかないため、その他ミドルウェアと組み合わせて使用する。

## expressでできること
- ルーティング
- リクエスト整形

## expressではできないこと
- リクエスト分析
- 認証認可
- DB接続

## expressを補うミドルウェアの例
- リクエスト分析：　body-parser
- セッション管理:express-session
- 認証:passport

# expressでWEBアプリケーションサーバを作成

## express環境構築
```
npm init
```

init実行後の設定項目
![スクリーンショット 2021-06-24 14.44.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533960/be285890-3932-1a1b-e077-31c4ca753438.png)


```shell
npm install express --save
```

## app.jsファイルを作成

```javascript:app.js
var express = require("express"),
    app = express();

app.get("/", (req, res) => {
  res.status(200).send("Hello ,world.");
});

app.listen(3000);
```

## ファイルを実行する。
```shell
node app.js
```

実行後、ブラウザを立ち上げて下記へアクセスする。

http://localhost:3000/

下記画面が出てくればOK
![スクリーンショット 2021-06-24 14.55.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533960/d0d79c7d-8a99-d543-4452-e2173c0b5424.png)

以上。
【GoogleMapsApi】Geocondingエラー「This API project is not authorized to use this API」の解消法

# エラー内容
GoogleMapsApiを使って、ウエブサービスにGoogleMapを取得しています。
その際、地名検索をGeocoding Apiを用いて実装してみることにしましたが、下記エラーが発生。

>Geocoding Service: This API project is not authorized to use this API. For more information on authentication and Google Maps JavaScript API services please see: https://developers.google.com/maps/documentation/javascript/get-api-key

#### コード概要

```GoogleMap.tsx
import React, { FC, useState } from "react";
import styles from "./GoogleMap.module.scss";
import GoogleMapReact from "google-map-react";

const GoogleMap: FC = () => {
  const [map, setMap] = useState(null);
  const [maps, setMaps] = useState(null);
  const [geocoder, setGeocoder] = useState(null);
  const [address, setAddress] = useState(null);
  const [marker, setMarker] = useState(null);
  const GoogleApiKey: any = process.env.REACT_APP_GOOGLE_MAP_API_KEY;

  const defaultLatLng = {
    lat: 35.7022589,
    lng: 139.7744733,
  };

  // map, maps で受け取ると変数が被るので object で受け取っています
  const handleApiLoaded = (object: any) => {
    setMap(object.map);
    setMaps(object.maps);
    setGeocoder(new object.maps.Geocoder());
  };

  const search = () => {
    geocoder.geocode(
      {
        address,
      },
      (results, status) => {
        if (status === maps.GeocoderStatus.OK) {
          map.setCenter(results[0].geometry.location);
          if (marker) {
            marker.setMap(null);
          }
          setMarker(
            new maps.Marker({
              map,
              position: results[0].geometry.location,
            })
          );
          console.log(results[0].geometry.location.lat());
          console.log(results[0].geometry.location.lng());
        }
      }
    );
  };

  return (
    <div className={styles.root}>
      <div className={styles.input_form}>
        <input type="text" onChange={(e) => setAddress(e.target.value)} />
        <button type="button" onClick={search}>
          Search
        </button>
      </div>
      <div className={styles.google_map_react}>
        <GoogleMapReact
          bootstrapURLKeys={{ key: GoogleApiKey }}
          defaultCenter={defaultLatLng}
          defaultZoom={8}
          onGoogleApiLoaded={handleApiLoaded}
          yesIWantToUseGoogleMapApiInternals={true}
        />
      </div>
    </div>
  );
};

export default GoogleMap;
```

エラー文を検索して、問題解決に繋がりそうな記事を探すこと５〜６時間…こちらの記事にて問題解決に至りました。

https://empoh.com/2019/03/02/538/

問題となっていた箇所は、**「認証情報」画面で行う「キーの制限」-「APIの制限」の設定でした。**

![スクリーンショット 2021-06-24 14.15.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1472874/9942a4b8-3de0-a5cd-5a12-a479da8cb2fd.png)

ここに「Geocoding API」を追加でエラー解消です。

# まとめ

解決してみれば「なんでこんな簡単なことで。。。」とほっとするような、自分に呆れるような。

まぁ、エラーのおかげである意味その周辺の知識が深まるので良しとします。

それでは引続き、開発を頑張っていきます。
【TypeScript超入門 - 型注釈編】TypeScriptでDOMを取得するときに初学者が躓きやすいポイントを分かりやすく解説

##この記事で学べること
- Non-null assertion operator（例: document.getElementById("〇〇")__!__）
- Type Assertions（例: document.getElementById("〇〇") __as HTMLElement__）

TypeScript入門者はもちろん、JavaScriptしか触ったことのないプログラミング初心者も対象です。

## Non-null assertion operatorとは
私がTypeScriptに入門して最初に躓いたのがDOM操作でした。TypeScriptはJavaScriptより型に厳しいので、同じコードを書いてもTypeScriptだと警告が出ることがあります。簡単な例を紹介します。

```javascript
// Javascriptファイル
const input = document.getElementById("usernameInput");
input.placeholder = "ユーザー名を入力してください";
```

```typescript
// Typescriptファイル
const input = document.getElementById("usernameInput");
input.placeholder = "ユーザー名を入力してください"; // 警告が出る
```
![スクリーンショット 2021-06-22 16.42.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1028795/2b9d8bb9-edc6-f3cb-9f64-38931914ccea.png)


警告文は、inputは__HTMLElement__と__null__を値として取る可能性があるオブジェクトであり、そうしたnullを取りうるオブジェクトにplaceholderプロパティは使用できない、という意味になります。

なぜnullを含むのかというと、getElementByIdメソッドの引数をタイポしていた場合それが返るからです。引数の文字列が正しいかどうか、つまりHTMLファイルの中に実際に

```html
<input id="usernameInput">
```
があるかどうかまではTypeScriptコンパイラーは判断できないため、代わりにnullが返る可能性を憂慮してくれています。
このとき、引数の文字列が正しいと分かっている場合、TypeScriptコンパイラーに対して、「nullの心配はない」と教えてあげる必要があります。その方法が__Non-null assertion operator__でして、__！__を末尾につけて書きます。
![スクリーンショット 2021-06-22 16.42.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1028795/d3308833-faa9-01f3-befb-4d526300105c.png)
これで、inputはHTMLElementだけを取りうるオブジェクトになりました。ただ、placeholderにまだ警告が出てます。
## Type Assertionsとは
![スクリーンショット 2021-06-22 16.46.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1028795/59099578-6fc4-70d5-ee43-9c5c30253dde.png)

警告文はだいたいこんな意味になります。

```javascript
const taro = {
 name: "太郎",
 age: 22
}

taro.language = "English" // 'language'というプロパティは'taro'に存在しない
```
もともとplaceholderは、__[HTMLInputElement](https://developer.mozilla.org/ja/docs/Web/API/HTMLInputElement)__オブジェクト*または__[HTMLTextAreaElement](https://developer.mozilla.org/ja/docs/Web/API/HTMLTextAreaElement)__オブジェクトがもつプロパティです。つまり、inputタグまたはtextareaタグにしか使えません。
（注: 正確には、HTMLInputElementというインターフェースが適用されたオブジェクトです）

```html
<input placeholder="ユーザー名を入力してください。">
<textarea placeholder="ご感想など"></textarea>
```
一方、getElementByIdメソッドは__[HTMLElement](https://developer.mozilla.org/ja/docs/Web/API/HTMLElement)__オブジェクトを返します。これはHTMLInputElementオブジェクトとHTMLTextAreaElementオブジェクトを含むあらゆるHTML要素の親にあたるものです。

したがって、警告文は「placeholderプロパティを更新したければどういうDOMか具体的に教えて欲しい」みたいに読み替えられます。では、__Type Assertions（型注釈）__を使って「それはinputだ」と教えてあげましょう。

Type Assertionsには__as__を使う方法と__< >__を使う方法があり、どちらを使うかは好みだと思います。

```typescript
const input = document.getElementById("usernameInput") as HTMLInputElement;
input.placeholder = "ユーザー名を入力してください。"
```

```typescript
const input = <HTMLInputElement>document.getElementById("usernameInput");
input.placeholder = "ユーザー名を入力してください。"
```
なお、一行で書くには__( )__で囲む必要があるのと、注釈をつけることでnullの可能性は否定されるため、__Non-null assertion operator__ は省略できます。

```typescript
(document.getElementById("usernameInput") as HTMLInputElement).placeholder = "ユーザー名を入力してください。";
(<HTMLInputElement>document.getElementById("usernameInput")).placeholder = "ユーザー名を入力してください。";
```
ちなみにReactなどでJSXを書く場合、コンポーネントと混同しやすいため、as形式しか使えません。
基本的な開発用語を整理

今回は開発と関して重要な基本知識を勉強しようと思う。
今週の日曜日からまたswiftの勉強を続けるつもり、、、

##1.デバッグ、デバッグ

デバッグとはソフトウェアから発生する問題の原因を探して解決する過程を言う。 
実際にコーディングを行う時間の相当部分をデバッグに割り当てることになる。 

##2.コンパイル

コーディングの過程で使われるプログラミング言語は、人が調べ、作成しやすいように作られた言語である。 
コンピュータは0と1の信号だけを認識するため、作成したコード自体をコンピュータが理解することはできない。 
それで、コードをコンピュータが理解できる言語に翻訳することをコンパイルという。 
それでコンパイル作業が要求される言語をコンパイラ言語といい、その例としてC、C++、Javaなどがある。 

コンピューターはコンパイルされた言語を読むだけなのでコンパイラ言語は実行速度が速い代わりにコードを作成するたびに 
コンパイル作業をしなければならない不便がある。 

コンパイル言語は、用途に応じて0と1で構成された機械語だけでなく、
プログラミング言語と機械語の中間段階の様々な形態で翻訳することもある。 

##3.インタープリター

コンパイル言語とは異なり、パイソン、ルビー、JavaScript、HTML、SQLなどの言語は翻訳作業を前もって行わずに
実行するたびに「インタープリター」というプログラムはコンピュータにコードを機械語に翻訳する言語である。 

コンパイル過程が必要ないため、コードの修正が多い製品の場合は配布が楽ですが、実行速度は 
コンパイラ言語に比べて遅く、プログラマーが組んだコードがそのまま露出され得るという短所がある。 

参考までにインタプリタ言語でコンパイルされる場合がある。 
タイプスクリプトという言語で、JavaScriptにより多様で強力な機能を組み込んだ言語である。 

プログラマがタイプスクリプトでコードを構成しても
実行環境はJavaScriptなので、そのコードが読めないため、 
JavaScriptと訳すコンパイル過程が必要になる。 

参考までに、C言語はインタプリタ方式であって、インタプリタ言語ではない（上から順に実行する方式を意味するだけ）。

##4.ビルド

プログラムコードは1つのファイルではなく、数百以上のファイルをまたいで作成されますが、 
完成し配布するには、特定の形態に圧縮したり変更しなければならない。
こうした過程をビルドという。 

コンパイラ言語は当然ビルドにコンパイル過程が含まれる。 

ビルドはコードを集めて1つの実行ファイルを作ったり、コードファイルの大きさを小さくしてより少ない容量のファイルにしたり、
他人が容易に読めないように難読化することもある。 

##5.配布

プログラマーがコーディングを完成してビルドを終えた後、ソフトウェアをユーザが使うように配布する過程を言う。 
ウェブサイトの場合には、作業結果をユーザが接続してブラウザで閲覧できるように反映する作業をいう。 

##6. 環境変数

環境変数とはソフトウェアが回る環境毎に特定変数名に指定された値をいう。 
環境変数を使用するソフトウェアは、各自の環境に指定された変数を基準に動作することになる。
各コンピュータの条件や用途に合わせてソフトウェアが回るようにしたり、セキュリティに敏感な情報をコードから切り離すなど、
環境変数も多様な目的と形態で活用される。 

##7. ライブラリー

プログラマーがコーディングをする過程で、すべてを手作業で作るわけではない。 
信頼できる企業や団体、個人が作成した良質なコードを 
ソフトウェアの作成にもたらされ活用する。 
このように必要に応じて使用できるように特定の機能をコードとして作成したものをライブラリという。 
例えば、Javaには基本的にJavaライブラリーがありますが、
日常的にコーディングをしながらよく使われる関数がすべてライブラリに含まれていると考えればいい。 

##8.フレームワーク

フレームワークには、既に特定の形態のソフトウェアが基本的な枠組みとなっており、
その上に、自分のコードを付添うことができるように構成されたものをいう。 
構造が複雑で広く使われる形態のソフトウェアの場合、このようなフレームワークが提供され、これを基盤に製品を作るのに
スプリングやジャンゴが代表例である
今更ながらRedux Toolkitに入門してみた②

この記事は
https://qiita.com/nisitin/items/ba91fb51885b0e98e4eb
の続編です！


###Reduxの復習
Reduxは状態を管理するためのライブラリーです
大きく分けて三つの機能があります。

```
1.Action　Creator(action)
2.store
3.reducer
```
上記の説明は①の記事に記載しているので省きますが、①の方を見るとさらに理解が深まると思います。


# Redux ToolKitとReduxの比較
Reduxは必要最低限の機能しかなく、いくつもの部品を実装する必要があります。Reducer, state,switch文、ReducerのためのAction Creatorや、非同期通信を行いたかったらRedux Thunkなども必要になります。

Redux ToolkitではcreateSliceという関数があり既存のReduxでaction type定義とaction creatorを別々に定義していたものを一発で作られるようになりました。
# Redux Toolkitの場合
※公式ドキュメントから抜粋

```couterSlice.ts
import { createAsyncThunk, createSlice, payloadAction } from "@reduxjs/toolkit"

export interface CounterState {
  value: number;
  status: 'idle' | 'loading' | 'failed';
}


export initialState: CounterState = {
  value 0,
  status: "idle",
};

export const incrementAsync = createAsyncThunk(
  'counter/fetchCount',
  async (amount: number) => {
    const response = await fetchCount(amount);
    // The value we return becomes the `fulfilled` action payload
    return response.data;
  }
);  

const counterSlice = createSlice({
  name: "counter",
  initialState,
  reducers: {
    inclement: (state) => { 
        state.value += 1
    },
    decrement: (state) => {
        state.value -= 1; 
  },
)
```
このような感じでActionとReducerを定義できるようになり、Reduxよりも簡単に定義できるようになったと思います。
この中に出てくるcreateAsyncThunk関数は非同期処理の実行状況に応じたActionCreatorを生成する関数でReduxThunkが採用されています。そしてこのcreateAsyncThunkでは三つのActionを振り分けておりそれは

- pending
- fulfilled
- rejected

になっています！



#参考文献
https://zenn.dev/eitches/articles/2021-0329-redux-tool-kit
https://qiita.com/shikazuki/items/02fb27dc741cbff18811