OmniAICreator/Qiita-1.07M huggingface dataset:
<作成予定>Raspberry Pi4 とRaspberry Pi でスパコンを作ってみる By 書籍

参考書籍：https://www.kyoritsu-pub.co.jp/book/b10003954.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118752/eb6ba17d-351b-06c6-ae6b-a56a0e5c1670.png)

<作成予定>
[C#] もはや我々はnew ArgumentNullException(...)する必要はない

null許容参照型が導入された現在でも、引数のnullチェックに事欠かくことのない皆様、いかがお過ごしでしょうか。
今日も`new ArgumentNullException(...)`していますか。

しかし、もうこんなことをする必要はないんです。
.NET6以降の世界には `ArgumentNullException.ThrowIfNull(object? argument, string? paramName = default)` が存在します。

これによって我々は、

```csharp
public void AMethod(string str)
{
    if (str is null)
        throw new ArgumentNullException(nameof(str));
    ...
}
```

の替わりに

```csharp
public void AMethod(string str)
{
    ArgumentNullException.ThrowIfNull(str);
    ...
}
```

と書くことができます。

ほんの少しだけハッピーになれますね。
最適なアプリ開発ソフトを選ぶにはどうしたらいいのでしょうか

<h1>最適なアプリ開発ソフトを選ぶにはどうしたらいいのでしょうか？

![10354155_4440574.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92345/a2ad2088-31f1-7a9e-7f7a-480d514e65dd.jpeg)

ビジネスに適したモバイルアプリ開発プラットフォームを選択する場合、プログラマーや開発者は、構築しようとしているアプリケーションの種類だけでなく、ビジネス全体のユニークな特徴に依存する多くの要因を考慮する必要があります。

アプリ開発に最適なプラットフォームは、アプリケーションの作成、構築、デプロイだけでなく、ライフサイクルを通じてテスト、改善、保守を効率的に行えるようにします。そのため、アプリの世界での存在感を高めるには、生産性の高いミドルウェアとバックエンドのサービスが不可欠です。

アプリ開発ソフトウェアプラットフォームのサービスを検討する場合、個々の要件に合ったアプリビルダーを選びたいものです。ここでは、ソフトウェアアプリを選択する際に考慮したいいくつかの機能を紹介します。

<h2>ローコード＆コードに特化したデベロッパーツール

ローコードまたはコードレスアプリ開発プラットフォームは、一般的にドラッグ＆ドロップ方式を採用しており、プログラマーや開発者は、はるかに複雑で時間のかからないソフトウェアシステムにクリエイティブな機能を簡単に統合することができます。

また、この種のツールでは、メタデータやモデル駆動、その他いくつかの非コード化オプションを実装することができ、ユーザーのニーズに合わせてさまざまなアプリのテンプレートを開発する際に、より多様で創造的な余地を残しています。

一方、コード中心のアプリ開発ソフトウェアでは、コードに変更を加えることなく、アプリの構造とデザインについてより詳細な概要を知ることができます。コードがソフトウェアに統合されている場合、変更と更新を随時追跡することができます。

<h2>モニタリング＆データ分析

アプリのパフォーマンスを監視し、追跡することは、本当にどんなビジネスにも不可欠です。そのため、分析に特化した効果的なアプリ開発プラットフォームを導入し、このようなデータについて報告してもらえるようにしたいものです。

<h2>バックエンドサービス

バックエンドサービスを提供するソフトウェアアプリケーションを利用することで、より費用対効果の高い、よりスムーズなアプリ構築プロセスを実現することができるのです。


バックエンド・サービスには、ユーザー管理、プッシュ通知、オフライン同期、十分なデータ保存、最適な統合、API設計、オーケストレーションなどの便利な機能があります。

<h2>DevOps対応

最高のアプリ開発ソフトウェアを選択する際に探したい、もう一つの費用対効果や生産性の高いサービスは、DevOpsサポートです。自動化プロセスやリリース管理を促進し、作業負荷を軽減することで、アプリ開発プロセスを加速させ、質的な成果を確保することを支援します。

<h2>セキュリティ

企業のお客様にとって、モバイルアプリケーションを利用する際のセキュリティは極めて重要です。そのため、セキュリティの脆弱性に効果的に取り組み、排除するモバイルアプリケーションソフトウェアを選びたいものです。

<h2>互換性

iOS vs Android
最後に、アプリケーション開発プラットフォームで優先したい機能として、「互換性」があります。先に述べたように、今日のモバイルアプリ市場では、iOSとAndroidが2大プラットフォームとなっています。そのため、この2つのOSをサポートするプラットフォームで作成されたプログラムが必要です。

理想的には、クロスプラットフォームの開発ソフトウェアを選択し、複数のプラットフォームのユーザーがあなたの製品やサービスにアクセスできるようにするのがよいでしょう。
iOSとAndroidは最も人気のある2つのプラットフォームであり、何よりもまず、iOSとAndroidに対応したアプリを開発することをお勧めします。

<h3>iOS開発ツール

SwiftとObjective-CがiOSアプリケーションの主要な2つのコーディング言語であることを除けば、xCode IDE、エディタ、ライブラリ、プラグインなどのチュートリアルは膨大かつ高品質なものが豊富に用意されています。

<h3>Android開発ツール

iOSがより大きな存在感を示しているように見えますが、Androidも同様に安定した速度でアプリ市場を支配しています。Androidアプリケーションを開発する場合、開発者は通常JavaとHTML5にこだわりますが、幅広い言語リソース、プラグイン、IDEを活用することもできます。


アプリ開発に関するコンテンをもっと読む：https://miichisoft.com/app-development-flow/

Website: https://miichisoft.com/
組み合わせ応力 基本例題5.03 P131「材料力学演習(20221021)」をsympyでやってみたい。

申し訳ありません。意味がわかっていません。勉強中。
短くなる方法を教えて下さい。

# オリジナル
基本例題5.03 　P131
http://zairikiweb.starfree.jp/zai_enshuh/zai_enshuh_ver.3.3.pdf#page=136

「材料力学演習(20221021)一括(ver.3.3)」を勉強したい。＞sympy
https://qiita.com/mrrclb48z/items/c3274daf5f7a99cfe027#%E4%BD%9C%E6%A5%AD%E4%B8%AD%E7%A7%81%E3%81%AE%E8%A7%A3%E7%AD%94sympy

# sympyで
具体的な値を代入しました。???
```python
from sympy import *
sgx,sgy=symbols('sgx,sgy',real=True)
t      =symbols('t'      ,real=True)
tauxy  =symbols('tauxy'  ,real=True)
sg = Rational(1,2)*(sgx+sgy)         +Rational(1,2)*(sgx-sgy)*cos(2*t)+tauxy*sin(2*t)
tau=-Rational(1,2)*(sgx-sgy)*sin(2*t)+tauxy*cos(2*t)
mySubs45 ={sgx:1000,sgy:-200,tauxy:600,t: 45*pi/180}
mySubsm30={sgx:1000,sgy:-200,tauxy:600,t:-30*pi/180}
print("#(1)",round(sg.subs(mySubs45 ),0),round(tau.subs(mySubs45 ),0))
print("#(2)",round(sg.subs(mySubsm30),0),round(tau.subs(mySubsm30),0))
#(1) 1000 -600
#(2) 180.000000000000 820.000000000000
```

①私の環境は,pycharmです。
②よく聞くのは、Jupyterです。
③web上で、上記のソースを「SymPy Live shell」に、コピー貼り付けでもできました。
黒背景の右上に、マウスを移動すると、コピーマークが発生します。
???　タブレット環境で、コピー貼り付けが実行できませんでした。???

https://live.sympy.org/

# Mathematicaで
勉強中

# 作図
勉強中

# 参考
C++でHelloWorldプログラムを実装してみた

# 概要
C++でHelloWorldプログラムを実装してみました。

# ソースコード
プログラムは以下の通りです。
```main.cpp
#include<iostream>

int main(){
  std::cout << "Hello, World!" << std::endl;
  return 0;
}
```

# コンパイル
以下のコマンドを実行しました。
```
$ g++ main.cpp
```

# 実行
以下のコマンドを実行しました。
```
$ ./a.out
Hello, World!
```

無事動いているようです。何かの役に立てばと。
Mohr's stress circle 組み合わせ応力 発展例題5.06 P133「材料力学演習(20221021)」をsympyでやってみたい。

申し訳ありません。意味がわかっていません。勉強中。
短くなる方法を教えて下さい。

# オリジナル
発展例題5.06 P133 
http://zairikiweb.starfree.jp/zai_enshuh/zai_enshuh_ver.3.3.pdf#page=138

「材料力学演習(20221021)一括(ver.3.3)」を勉強したい。＞sympy
https://qiita.com/mrrclb48z/items/c3274daf5f7a99cfe027#%E4%BD%9C%E6%A5%AD%E4%B8%AD%E7%A7%81%E3%81%AE%E8%A7%A3%E7%AD%94sympy

# sympyで
TR5,TR7,cos(2t)→cos2t→cos(2t)の置き換えをやっています。(参照より)

```python
from sympy import *
from sympy.simplify.fu import TR5
from sympy.simplify.fu import TR7
sg     =symbols('sg'     ,real=True)
sgx,sgy=symbols('sgx,sgy',real=True)
t      =symbols('t'      ,real=True)
tau    =symbols('tau'    ,real=True)
tauxy  =symbols('tauxy'  ,real=True)
ds     =symbols('ds'     ,real=True)
dx,dy  =symbols('dx,dy'  ,real=True)
cos2t  =symbols('cos2t'  ,real=True)
myXhoko=Eq(sg*ds*cos(t)-tau*ds*sin(t),sgx*dy+tauxy*dx)
myYhoko=Eq(sg*ds*sin(t)+tau*ds*cos(t),sgy*dx+tauxy*dy)
mySubs1={ds*sin(t):dx,ds*cos(t):dy}
mySubs2={dx:ds*sin(t),dy:ds*cos(t)}
myXhoko=myXhoko.subs(mySubs1).subs(mySubs2)
myYhoko=myYhoko.subs(mySubs1).subs(mySubs2)
ans=solve([myXhoko,myYhoko],[sg,tau])
print("#sg =",Poly(TR7(TR5(ans[sg])).subs({cos(2*t):cos2t}),cos2t).args[0] .subs({cos2t:cos(2*t)}))
print("#tau=",ans[tau].simplify())
#sg = sgx/2 + sgy/2 + 2*tauxy*sin(t)*cos(t) + (sgx/2 - sgy/2)*cos(2*t)
#tau= -sgx*sin(2*t)/2 + sgy*sin(2*t)/2 + tauxy*cos(2*t)
```

# Mathematicaで
勉強中

# 作図
勉強中

# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342)

# いつもと違うおすすめです。
TR5() - powers of sin to powers of cos

https://docs.sympy.org/latest/modules/simplify/fu.html#sympy.simplify.fu.TR5

TR7() - reduce cos power (increase angle)

https://docs.sympy.org/latest/modules/simplify/fu.html#sympy.simplify.fu.TR7

#### 参考文献

~~＞一部に等分布荷重を受ける単純支持はり~~
~~＞JSME p89~~
　
~~＞片持ちばり 1)~~
~~＞構造力学公式集 表5.1 片持ちばりの公式　p128~~
コマンドプロンプトでpsファイルを実行する

# はじめに
今回の記事では、弊社インプリムのリポジトリをクローンするバッチ処理(psファイル)を実行したときのエラーの対処方法です。今回、私が新入社員に業務をレクチャーすることになっていましたが、その前に思わぬところでエラーが出てしまったため、その解決方法を記載いたします。正直、この方法であっているのかわからないため、もし間違っていたらご教授いただけると嬉しいです。

# psファイルの実行
バッチ処理を記載したpsファイルを実行したのですが、[こちらの記事](https://qiita.com/Targityen/items/3d2e0b5b0b7b04963750)に記載されているエラー内容が表示されましたので、実行ポリシーを変更しました。そのうえで、psファイルを再度実行したのですが、下記のようなエラーが出てしまいダメでした・・・。
```powershell
./DevEnvSettings.ps1 : ファイル ～\DevEnvSettings.ps1 を読み込めません。ファイル
～\DevEnvSettings.ps1 はデジタル署名されていません。このスクリプトは現在のシステ
ムでは実行できません。スクリプトの実行および実行ポリシーの設定の詳細については、「about_Execution_Policies」(https://go
.microsoft.com/fwlink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1
+ ./DevEnvSettings.ps1
+ ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess
```
実行ポリシーを変更したにもかかわらず・・・なぜなのでしょうか？色々調べた結果、下記のサイトを見つけました。

https://checkertechmemo.blogspot.com/2019/06/powershell.html

ファイル自体のセキュリティーを変更することによってできる？見たいです。変更してみると実行できました。おそらく、ファイル自体のセキュリティーによって、実行できなかったのかなと推測しています。

# おわりに
今回のこの件は、これから先もお世話になるかもしれません。これから入る人の役に立つかもしれないので、この記事は残しておこうと思います。また、間違っている解釈等ありましたら、ご指摘いただけると嬉しいです。
FlutterのMateriaIのIconsの一覧をすばやく確認する

メモ用です。一瞬で記事が終わるやつなので注意。

いつもはIconsの型ファイルからそれっぽい名前で検索していたのですがどんなアイコンなのか確認しながら探した方が早いなと思って一覧ページを探したところ、以下のページが早いかと。

fluttericonの公式サイトにある「Names」ページでブラウザ上から検索 https://www.fluttericon.com/

![スクリーンショット 2023-05-10 16.39.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651103/a3519276-620f-c12a-e1af-69d15f3d9387.png)

大したことないですがNamesページに気がつかなくてググる時間を無駄にしてました。
Flutter + NCMB + ChatGPTでAIチャットアプリを作る（その1：画面仕様とNCMBの初期化）

NCMBでは公式SDKとしてSwift/Objective-C/Kotlin/Java/Unity/JavaScript SDKを用意しています。また、それ以外にもコミュニティSDKとして、非公式ながらFlutter/React Native/Google Apps Script/C#/Ruby/Python/PHPなど幅広い言語向けにSDKが開発されています。

今回はコミュニティSDKの一つ、Flutter/Dart SDKを使ってChatGPTを用いたチャットアプリを作ってみます。まず画面の仕様とSDKの初期化について解説します。

## コード

今回のコードは [NCMBMania/flutter-gpt-chat](https://github.com/NCMBMania/flutter-gpt-chat) にアップロードしてあります。実装時の参考にしてください。


## 利用技術について

今回は次のような組み合わせになっています。

- Flutter
- NCMB
- OpenAI API

## 仕様について

今回のアプリは以下のような機能があります。

- チャット画面
- メッセージをNCMBに保存
- OpenAI APIを使って返答を取得
- 返答をNCMBに保存

ChatGPTでは過去のメッセージもAPIで送信することで、以前の内容を踏まえた回答をしてくれます。過去のメッセージをNCMBに保存しているので、復元が容易です。

## 利用する機能について

このチャットアプリで利用しているNCMBの機能は以下の通りです。

- データストア
    - データ登録
    - データ検索
- スクリプト
    - OpenAI APIの実行

## 画面について

現時点で、画面は以下の1つのみです。

### チャット画面

チャット画面は[flutter\_chat\_ui | Flutter Package](https://pub.dev/packages/flutter_chat_ui)を使っています。

![localhost_63838_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/986f6312-ade0-df3d-bdd5-0db902b6992c.png)


### SDKのインストール

flutter_chat_uiとNCMBのSDKをflutterコマンドでインストールします。

```
flutter pub add flutter_chat_ui
flutter pub add ncmb
```

## NCMBのAPIキーを取得

[mBaaSでサーバー開発不要！ | ニフクラ mobile backend](https://mbaas.nifcloud.com/)にてアプリを作成し、アプリケーションキーとクライアントキーを作成します。

## 初期化

初期化は `lib/main.dart` にて行います。

```dart
import 'package:ncmb/ncmb.dart';

void main() {
  // NCMBの初期化
  NCMB('YOUR_APPLICATION_KEY',
      'YOUR_CLIENT_KEY');
  runApp(const MyApp());
}
```

これでNCMBの初期化が完了します。

## 画面の読み込み

チャット画面をChatPageとして、MyAppのbuildで読み込みます（チャット画面は次回作ります）。

```dart
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ChatGPT App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const ChatPage(),
      debugShowCheckedModeBanner: false,
    );
  }
}
```

## まとめ

今回はチャットアプリの仕様と画面、NCMBの初期化までを解説しました。[次回はOpenAI APIの呼び出し（スクリプト）](https://qiita.com/goofmint/items/f1257b16ae99fa142136)について解説します。
vue.jsのv-bindによるStyleの変更に関して

# V-bindによるStyle属性の変更に関して
最近vue.jsをキャッチアップする機会を頂いたので、youtubeを参考に寿司打をvue3で作っていた際に気づいたことを書きます。

※めっちゃ当たり前の内容かもしれませんが、自分が学習していく中で直面した問題のメモとして残します。

## v-bindによるStyleのバインドの仕方
全問題数を<font color = "red">questionCounts</font color>として分母
現在の問題数を<font color = "red">currentQuestionCounts</font color>として分子
currentQuestionCounts / questionCounts
として表示し、その問題が進むにつれてゲージが増えるという実装をしようと思っていました。

### <font color = "red">■最初に書いていた\<template>内はこんな感じ
```
<template>
    <div :style="{ 'width': styleObject, 'backgroundColor': styleObject }"></div>
</template>
```
#### ♦間違っている箇所
- styleObject内のプロパティにアクセスできていなかった
→styleObject.width, styleObject.backgroundColorと書き換えることで解決
→そもそもstyleObjectは変数なので、<font color = "red">:style="styleObject"</font color>と書いてしまえばいい

### <font color = "red">■最初に書いていた\<script>内はこんな感じ
```
//
<script setup>
    const styleObject = computed( () => {
        const styleWidth = 20 * currentQuestionCounts.value + "%";
        const styleColor = () => {
            if(currentQuestionCounts.value == questionCounts.value) {
                color: "skyblue"
            }else{
                color: "orange"
            }
        return {
            "width": styleWidth,
            "backgroundColor": styleColor
        }
    });
</script>

```
#### ♦間違っている箇所
- styleColorで条件によって色指定をしたいだけなのに、アロー関数を使っているから戻り値がうまくStyleObjectに戻ってなかった
→このままではStyleObjectに関数が入ってしまっているため、簡単に書き換える必要がある。




### <font color = "blue">■修正後の\<template>内はこんな感じ
```
<template>
    <div :style="styleObject"></div>
</template>
```

### <font color = "blue">■修正後の\<script>内はこんな感じ
```
<script setup>
    const styleObject = (computed () => {
        const styleWidth = 20 * currentQuestionCounts.value + "%";
        //もしくは
        const styleWidth = `${ 20 * currentQuestionCounts.value}`%;

        const styleColor = currentQuestionCounts.value === questionCounts.value ? "skyblue" : "orange";
        return {
            "width": styleWidth,
            "backgroundColor": styleColor
        }
    });
</script>

```

## まとめ
今回のエラー修正で4時間近く悩んだ末にChatGPTに聞いたら5分で解決したという無駄なことをしてしまったので、戒めの為にも残すことにしました。
何か困ったらchatGPTに助けてもらうのが一番早いかも。。

とはいえ、こういう書き方は実際にやってみてエラーに直面して解決したときに一番覚えられるのでとてもいい経験になったと思いました。
【AndroidStudio】ActivityやFragment外でgetStringを使いたい

# はじめに
TextView等のtextに「合計：1000円」や「合計：2000円」など、文字列の特定の数値だけを変えて表示したいときにはstrings.mxlに文字列リソースを用意してから、getStringで代入するというやり方をする。
しかし、困ったことにgetStringはActiviyやFragment外では使えない。今回はActiviyやFragment外でgetStringを使う方法についてまとめる。


# instanceの設定
プロジェクトに存在するActivityで以下のように宣言する。
```diff_kotlin:MainActivity.kt
class MainActivity : AppCompatActivity() {

+    companion object {
+        lateinit var instance: MainActivity
+            private set
+    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

+        instance = this

        // 関係ない部分は省略

    }

}
```

# getStringの利用
今回私はListAdapterの中で使いたかったので、その時の例を示す。
```diff_kotlin:CustomAdapter.kt
class CustomAdapter(
    private val itemClickListener: OnItemClickListener
): ListAdapter<Item, ViewHolder>(DiffCallback) {

+    private val context = MainActivity.instance.applicationContext
+    private val resources = context.resources

// 省略

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {

+        holder.itemName.text = resources.getString(R.string.item_name, item.itemName)

    }

// 省略

}
```
この時strings.xmlには以下のように文字列が入っている。
```xml
<resources>
    <string name="item_name">合計： %d 円</string>
</resources>
```
このようにすることで、getStringを利用している。
今回の場合、任意の金額を設定してtextに表示したいため、「合計： %d 円」となっている。
そのため、`resources.getString(R.string.item_name, item.itemName)`の`item.itemName`が1000の場合は「合計： 1000 円」に、2000の場合は「合計： 2000 円」となる。

# まとめ
今回はgetStringをActivityやFragment外で使って文字列を表示する方法をまとめた。
このやり方が違っていたり、もっといいやり方があるという場合はぜひ教えてください。

# 追記
コメントで上記やり方でなくてもgetStringが使える方法を教えてもらった。
```diff_kotlin:CustomAdapter.kt
class CustomAdapter(
    private val itemClickListener: OnItemClickListener
): ListAdapter<Item, ViewHolder>(DiffCallback) {

// 省略

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {

+        holder.itemName.text = holder.itemName.context.getString(R.string.item_name, item.itemName)

    }

// 省略

}
```
ViewからContextやResourcesを取得できるため、この書き方をするだけでも良かった。
AWS Cloud9からGitlabに接続してリポジトリをクローンするまで

Cloud9からGitlabにアクセスしたいタイミングがあったため、実施した手順をまとめています。
今回のQiita記事では、SSHキーの作成から、プロジェクトをクローンする方法までについて解説します。Gitlabのアカウント作成やCloud9リソース作成については触れませんのでご了承ください。

## 目次
1. SSHキーの生成と登録
2. Gitlabとの接続確認
3. リポジトリのクローン
4. まとめ

## 1. SSHキーの生成と登録
① AWS Cloud9のターミナルで、以下のコマンドを実行してSSHキーを生成します。

```bash
$ ssh-keygen -t ed25519 -C "your_email@example.com"
```
今までRSAの鍵タイプしか使っていませんでしたが、Ed25519鍵というものがセキュリティ的に優れているという記述を見たので、試しに使ってみました。

[SSHの公開鍵暗号には「RSA」「DSA」「ECDSA」「EdDSA」のどれを使えばよいのか？](https://gigazine.net/news/20200828-ssh-encryption-algorithm/)

② SSHキーをコピーする
cat コマンドで表示された内容をコピーします。
```bash
$ cat ~/.ssh/id_ed25519.pub
```

③ gitlabにログインし、ユーザアイコンから「Edit profile」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660703/7ea74e93-77ec-65a2-c6fb-057bf465e203.png)

④ 左側のメニューから「SSH Keys」を選択します。
Keyの部分に先ほどコピーしたSSH Keyの内容を張り付け、Titleに適当な名前を付けたら「Add key」を押してSSH keyの登録が完了となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660703/a0f14a9b-1877-7d9e-338a-6b1ea8bb61ad.png)

## 2. 接続確認
Cloud9からGitlabに接続できるか確かめてみます。

```bash
$ ssh -T git@gitlab.com
```
接続が成功すると、以下のようなメッセージが表示されます。
```bash
Welcome to GitLab, @username!
```

これで接続完了です。

## 3. リポジトリのクローン
最後にお試しで、リポジトリをCloneしてみます。

gitlabのプロジェクトページにアクセスし、Cloneボタンをクリックして、Clone with SSHのURLをコピーします。
AWS Cloud9のターミナルで、以下のコマンドを実行し、リポジトリをクローンします。
```bash
git clone [リポジトリのSSH URL]
```

これで、リポジトリがクローンされました。

## 4. まとめ
今回の記事では、AWS Cloud9からGitlabに接続し、リポジトリをクローンするまでの手順について解説しました。どなたかの参考になれば幸いです。
Serverless Framework v3 ComposeのuseDotenv注意点

# 以下の話をします
* `useDotenv: true` をどこに書くのか
* `.env` ファイルをどこに置くのか
* どこで使えるのか

# 結論
最終的に以下のようなディレクトリ構成になります。
```
rootdir/
┣ aaa/
┃ ┣ .env.dev
┃ ┣ .env.prod
┃ ┗ serverless.yml
┣ bbb/
┃ ┣ .env
┃ ┗ serverless.yml
┗ serverless-compose.yml
```

# `useDotenv: true` をどこに書くのか
`serverless-compose.yml` には書けません。（書いてもエラーにはなりませんが読まれません）
子フォルダの `serverless.yml` に個別に書きます。

# `.env`, `.env.{stage}` ファイルをどこに置くのか
`useDotenv: true` を子フォルダに書いたので、 `.env`, `.env.{stage}` ファイルは子フォルダにそれぞれ置きます。
共通の変数（システム名の接頭辞など）は１箇所にまとめたかったのですができませんでした。情報募集しています。

# `${env:prameterXX}` はどこで使えるのか
お察しの通り、子フォルダごとに `.env` ファイルを定義しているのでその範囲でしか使えません。
ただし、こんなところでも使えました。
```serverless.yml
service: ${env:serviceNamePrefix}-service
useDotenv: true
~~~
```
`useDotenv: true`　よりも上で参照しても使えました。これは便利ですね。
Databricksノートブック上からインストールされているライブラリをクイックに確認できるようになりました！

地味に嬉しいエンハンス。他の方に言われるまで気づきませんでした。

右側のアイコン一覧の一番下に**ライブラリ**ボタンが追加されています。
![Screenshot 2023-05-10 at 16.04.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/d6a98b00-16dc-99ff-548f-1a43f0e858e3.png)

Databricksのライブラリは適用スコープが異なるいくつかのタイプがあります。

- [クラスターライブラリ](https://qiita.com/taka_yayoi/items/9407356caadea3dfb47c)
- [ノートブックスコープライブラリ](https://qiita.com/taka_yayoi/items/d3a46efdc1ad01a581d0)

これらをクイックに確認することができます。上にある**Type**を選択することでライブラリをフィルタリングできます。こちらはノートブックスコープライブラリの一覧です。
![Screenshot 2023-05-10 at 15.57.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/d38f7011-839d-151a-14d1-6495c2bea5a2.png)

さらに、その上にあるテキストボックスでライブラリ名を指定して絞り込みを行うことができます。
![Screenshot 2023-05-10 at 15.57.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1d37487c-5418-e049-c2ed-d338b8f72e2b.png)


「あのライブラリ入ってたっけ」や「ライブラリのバージョンっていくつかだっけ？」という時に役立ちます。

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
Redis互換で25倍高速な「Dragonfly」をdocker-composeで使用する際に--requirepassなどを設定する

# Dragonflyとは
redis互換で25倍速いらしいです。
JSONとかも標準で入れられるっぽい。
2023年5月10日時点でv1.2.1がリリースされているので本番運用しても大丈夫……っぽい。

## confファイルはどこに置くのか？
わかりません……。
調べても出てこない……。

## とりあえずパスつけたいときはどうすればよいのか

docker-compose.ymlにcommandを足せばOK

```yml
version: "3.8"
services:
  dragonfly:
    image: "docker.dragonflydb.io/dragonflydb/dragonfly"
    network_mode: "host"
    volumes:
      - dragonflydata:/data
    command: ["dragonfly", "--logtostderr", "--requirepass=SUPER_STRONG_PASSWORD"]
volumes:
  dragonflydata:
```

他にもbindとかいろいろ変更できるっぽいです。
詳しくは

https://github.com/dragonflydb/dragonfly

ここのConfigurationを読んでみてください。

誰かredis.confみたいなものを置く場所を知っていたら教えてください……。
Serverless Framework v3 Composeのスタック削除

# 簡潔に
Serverless Framework v3のComposeで資材の初回デプロイ中にエラーが起き、
一度全て削除しようとしたらエラーになったので解決手順をまとめます。

# エラーが起きた原因と解決方法
以下のようなYAMLファイルで「Bのデプロイ中にエラーが起きた」とする。
```serverless-compose.yml
services:
  A:
    ~~~
  B:
    ~~~
    dependsOn:
      - A
  C:
    ~~~
    params:
      parameterBB: ${B.parameterBB}
```
## `sls remove` は「まだデプロイしてない資材かどうか」は考慮しません。
よって、Cが依存するBのOutputパラメータ `${B.parameterBB}` を解決しようとして
`The Variable "${B.parameterBB}" cannot be resolved: the referenced output does not exist.`
が出ます。
### 解決方法
デプロイがsuccessしたのはAまでなので
serverless-compose.ymlのB以降をコメントアウトして `sls remove` を実行することでデプロイ済みの資材を削除できます。
python maya change namespace

```python
import maya.cmds as cmds

def get_all_namespaces():
    namespaces = cmds.namespaceInfo(listOnlyNamespaces=True, recurse=True)
    return namespaces
    
def change_namespace(old_namespace, new_namespace):
    # Get a list of objects in the old namespace
    objects = cmds.namespaceInfo(old_namespace, listOnlyDependencyNodes=True, dagPath=True)

    # Create the new namespace
    cmds.namespace(add=new_namespace)

    # Rename the objects to the new namespace
    for obj in objects:
        new_name = obj.replace(old_namespace + ':', new_namespace + ':')
        cmds.rename(obj, new_name)

    # Remove the old namespace
    cmds.namespace(removeNamespace=old_namespace, mergeNamespaceWithRoot=True)

all_namespaces = get_all_namespaces()
print(all_namespaces)

map = {
    
    "s033": "step_002",
    "280": "004",
}

keys = map.keys()
for n in all_namespaces:
    renameJob = False
    newname = n
    for k in keys:
        if k in n:
            #print(n)
            newname = n.replace(k, map[k])
            renameJob=True
    if not renameJob: continue
    print(newname)
    change_namespace(n, newname)
```
Windows Host OS から InSpec で Hyper-V の Guest OS へテストするコマンドラインオプション

Windows Host OS から Hyper-V の Guest OS へ InSpec かけたい。  
chef-workstation はインストール済。  
Guest OS は winrm の設定済。

```
$ip = "172.24.11.22"
$port = "5985"
$user = "vagrant"
$password = "vagrant"
inspec exec . -t winrm://$ip`:$port --user=$user --password=$password --reporter=cli
```

VMのIPアドレスの調べ方
```
$vmname = "vmname"
Get-VMNetworkAdapter -VMName $vmname | Select IPAddresses
```

繋らないときはGUEST OS のWindows側でこれやる。
```
Enable-PSRemoting -SkipNetworkProfileCheck -Force
```
Redmine　で　put　しても更新できないのなんで？（解決済み）

Redmine　で　WEB　API使って登録するソフトを書いたのだが、
postでは作れる。putで更新できない。
なんでだ？
|
|
どこからやったら良いか分からーん、と悩みまくりながらいじって、半ば偶然な感じで、見つけた、

APIでつけている、キーのアカウントに、当該プロジェクトとそのプロジェクトの
ロール「報告者」
をつけたら、putで更新されるようになった。
「オブジェクトは、このプロパティまたはメソッドをサポートしていません。」のひとつ

ExcelVBA、
サブルーチンの引数をbyrefにしていても、
Call をつけていないで呼び出したら　ByRefでちゃんと渡してもらえず、
「オブジェクトは、このプロパティまたはメソッドをサポートしていません。」になる。

…で、これが出た時、サブルーチン名もモジュールも呼び出し元もなんにも出ないから、
起動したサブルーチンから順番にステップ実行とかブレークポイントで追いかけるしか無いから面倒面倒・・・。
Excel、グループ化で畳むとテキスト出力では見事に消える

ExcelってWYSIWYGなんですね。
グループ化で一部の列とか行を畳んであると、
.textで保存した時、そこのデータが""になって、
書いてあることが出力されない・・・。
みた通り（？）に消えてしまう。

必要なら開いて保存しなければ。
SwiftChartsのグラフを指一本で伸び縮みさせたい時

```swift
import SwiftUI
import Charts
struct BarGraph: View {

    @State private var domein = 5000
    let domeinMin = 50 //グラフを最大限に拡大したときに表示される棒の数の最小値
    let domeinMax = 11000

    var data:何らかのデータ
   
    var body: some View {
        GeometryReader{ geo in
                Chart{ /*dataをグラフ表示,今回は横に伸びるbar chart*/}
                }.chartXScale(domain: 0...domein)
                .gesture(scale(viewWidth:geo.size.width))
        }
    }
    
    func scale(viewWidth:CGFloat) -> some Gesture{
        DragGesture(minimumDistance: 30) //scrollviewなどの中ではminimumDistance: 30にするとscrollに干渉しない。
            .onChanged { value in
                print("dragged")
                
                let scaleRate = value.translation.width / viewWidth // -1 ~ +1
                var scaledDmain:CGFloat = 0
                if scaleRate != 0 {
                    scaledDmain =  CGFloat(domein) - CGFloat(domein) * scaleRate
                    print("scaleRate != 0\nscaledDmain:",scaledDmain)
                }
                
                if domeinMin < Int(scaledDmain) && Int(scaledDmain) < domeinMax{
                        domein = Int(scaledDmain)
                }
              }
    }
    
}



```
シンプルなToDoListのDBをローカル→Azure SQL Databaseに変更してみる

# はじめに
Azure SQL Databaseを作成して、
[シンプルなToDoList](https://qiita.com/Auggie_2345/items/5b8803a2bf6249ffac77) をCRUD処理させてみた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/aa12e581-5e8f-c82f-472a-415fbbc50c82.png)

# Azure SQL Databaseの作成
Azure PortalからSQL databasesを選択。
先に`SQL database`よりも`SQL server`の作成を求められます。
名称がややこしいが別物みたいです。

↓認証方法はSQLServer認証にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/1473e938-ee49-49fb-0ab0-9d008d72078d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/5480ff54-4b8c-ed73-61d5-b397c1568113.png)

DB名は`DB-ToDoList`としました。

↓SQL database(ローカルのSQLServerのデータベースに相当)を作成Serverのスペックは選択可能な最小の`Basic`にしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/8349b55a-ba18-3d0d-b55e-28efdd3f399b.png)

SQL databaseができたら、ローカルのSSMSから接続してみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/c44ccd8b-c504-f849-7eba-da3861ca57c5.png)

`Server name`：SQL database serverを作成したときにつけたServer名
`Authentication`：SQLServer認証
`Login`：SQL database serverを作成したときにつけたID
`Password`：SQL database serverを作成したときにつけたPW

↓こんな感じで、ローカルのSQLServerとおんなじ感じでローカルから接続可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/32af751f-eb3a-9934-6f9c-90531b604938.png)

Azure PortalでSQL Serverを作るときにFirewallの設定をやっていないと、SSMSでの初回アクセスでFirewall作成を求められる。

↓こんな感じで、SSMSで作ったFirewallはAzurePortalに反映される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/f4803c54-f24a-8096-2760-a8aa015b4518.png)

[前回作ったToDOList](https://qiita.com/Auggie_2345/items/5b8803a2bf6249ffac77) と同じDDLを流してテーブルをCreateしてあげる
```SQL:Create文
Create Table [dbo].[ToDo] (
[id] UNIQUEIDENTIFIER DEFAULT NEWID() NOT NULL 
,
[ToDo] [nvarchar] (50)
,
[DueDate] [datetime] NOT NULL 
, 
CONSTRAINT [PK_ToDo] PRIMARY KEY (id)
);
```

作ったテーブルをSELECTしたりINSERTしたりはSSMSからでも可能だが、AzurePortalのSQL database>Query editor(preview)からも同じく可能↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/50b99b55-b570-1258-471c-9a2d417e80fb.png)

# ToDoListアプリからのDB接続
Azure SQL Databaseから接続文字列を取得する。

SQL database>Settings>Connection stringsを選択。
↓ADO.NET (SQL authentication)の接続文字列をコピーする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/f3ca0f2c-c4be-2622-0106-df024ca0df8e.png)

ToDoListアプリをVisual Studioで開いて、appsettings.jsonを選択。
`ConnectionStrings:ToDoList`に接続文字列を貼り付けする。

VisualStudioで▷ボタンを押下してローカルでデバッグ実行。

↓Azure SQL databaseのレコードをアプリに読み込みできていることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/3b8079dd-2d70-c1ba-f50d-bfc3ed837ff0.png)

# 参考
https://learn.microsoft.com/ja-jp/azure/azure-sql/database/design-first-database-tutorial?view=azuresql
lightning locker

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめA～M](https://qiita.com/Keiji_otsubo/items/f3ddedee6793bf1576f8)



# 回避策："lightning locker"というアーキテクチャによってwindowオブジェクトが使用できない

+ [lightning lockerによるwindowオブジェクト制限の代替案](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000PeghL)

history.pushStateを使ってブラウザの戻るボタンを無効化するということなら
古い投稿(2016年ごろ)を見ると機能していたような感じもします。

https://salesforce.stackexchange.com/questions/126875/lightning-lockerservice-history-pushstate

https://developer.salesforce.com/forums/?id=906F0000000kDUQIA2

しかし、現状では既知の問題に上がっています。
ここには回避策は書かれてませんね。
[When history.pushState is used in a Lightning app, it gacks for certain urls. This is WAD and needs to be documented](https://issues.salesforce.com/issue/a028c00000gAx8vAAC/when-historypushstate-is-used-in-a-lightning-app-it-gacks-for-certain-urls-this-is-wad-and-needs-to-be-documented)

LWCならHistory APIを使って対応できるようなことが説明されていますが、私は使ったことがないです。

https://sfdc.danielzeidler.com/2019/12/19/integrating-the-browsers-back-and-forward-buttons-in-a-lightning-web-component/

:::note
addValueProviderを使って戻るボタンを押した時にあらかじめ用意した値を使う方法が述べられています。これが使えるかもしれません。

https://salesforce.stackexchange.com/questions/203755/lightning-component-back-button-and-caching
:::
ScrollView, SheetViewの中でDragGestureを使いたい時

普通に中のsubviewに実装するとDragGestureが盗まれて、scrollができなくなるから、こうする。
```swift
.gesture(DragGesture(minimumDistance: 30, coordinateSpace: .local)
```


https://stackoverflow.com/questions/57700396/adding-a-drag-gesture-in-swiftui-to-a-view-inside-a-scrollview-blocks-the-scroll
curlコマンドの-w (--write-out)オプションで各ステップの所要時間を出力してhttpとhttpsの差を確認してみる

# 確認スクリプト

while ループで、現在の時刻を表示しながら、2秒インターバルで curl コマンドを実行するスクリプトを作成しました

```sh
while true; do
    echo -n '['`date '+%Y/%m/%d %T'`'] '
    curl -s -o /dev/null -w "\
%{time_namelookup} \
%{time_connect} \
%{time_appconnect} \
%{time_pretransfer} \
%{time_starttransfer} \
%{time_total} \
%{remote_ip}\n" https://example.com/
    sleep 2
done
```

使用している curl のオプションは以下のとおりです

- `-s`: curl の進捗情報やエラーを表示しない
- `-o /dev/null`: レスポンスの内容を表示しない
- `-w`: curl の出力形式を指定（詳細は以下）

`-w` オプションの引数です。単位はすべて秒で、コマンドの実行開始からの経過時間を出力します

- `%{time_namelookup}`: DNS 名前解決が完了するまでにかかった時間
- `%{time_connect}`: サーバーへの TCP 接続が完了するまでにかかった時間
- `%{time_appconnect}`: サーバーへの TLS 接続が完了するまでにかかった時間
- `%{time_pretransfer}`: リクエスト送信が開始されるまでにかかった時間
- `%{time_starttransfer}`: レスポンスの最初のバイトを受信するまでにかかった時間
- `%{time_total}`: レスポンスの受信が終わるまでにかかった時間
- `%{remote_ip}`: 接続先の IP アドレス

なお、example.com は HTTPS ( https://example.com/ ) でも HTTP ( http://example.com/ ) でもアクセスできるようになっています。CDN に乗っているようです。

# コマンドの実行結果: https 編

簡単に10秒間だけ実行してみます

```
[2023/05/09 18:45:41] 0.004255 0.122943 0.382825 0.382982 0.504497 0.504939 93.184.216.34
[2023/05/09 18:45:43] 0.008665 0.126337 0.389283 0.389374 0.515294 0.515694 93.184.216.34
[2023/05/09 18:45:46] 0.006952 0.160491 0.456443 0.456597 0.575058 0.575518 93.184.216.34
[2023/05/09 18:45:48] 0.009867 0.127739 0.388252 0.388389 0.507338 0.507515 93.184.216.34
[2023/05/09 18:45:51] 0.008886 0.133743 0.400165 0.400278 0.521013 0.521195 93.184.216.34
```

なお、HTTP/2 での接続になっていました

# コマンドの実行結果: http 編

スクリプトのこちらの行を、https → http に変更して実行します

```diff
-%{remote_ip}\n" https://example.com/
+%{remote_ip}\n" http://example.com/
```

こちらも5回分だけ実行してみます

```
[2023/05/09 18:45:57] 0.009565 0.130113 0.000000 0.130274 0.252637 0.253150 93.184.216.34
[2023/05/09 18:45:59] 0.008010 0.125504 0.000000 0.125960 0.242670 0.243096 93.184.216.34
[2023/05/09 18:46:01] 0.008424 0.130206 0.000000 0.130604 0.252498 0.252901 93.184.216.34
[2023/05/09 18:46:04] 0.008872 0.127002 0.000000 0.127096 0.245600 0.246088 93.184.216.34
[2023/05/09 18:46:06] 0.007377 0.128108 0.000000 0.128185 0.249296 0.249794 93.184.216.34
```

http では TLS 接続のステップがないため、`time_appconnect` が省略されて0になっています


# 結果の比較

それぞれ5回分の平均値をとり、比較してみます。単位はミリ秒に直しています

|  | namelookup | connect | appconnect | pretransfer | starttransfer | total |
| --- | --: | --: | --: | --: | --: | --: |
| (1) https | 7.725 | 134.251 | 403.394 | 403.524 | 524.640 | 524.972 |
| (2) http | 8.450 | 128.187 | - | 128.424 | 248.540 | 249.006 |
| (1) - (2) | -0.725 | 6.064 | - | 275.100 | 276.100 | 275.966 |

誤差もあるはずですが、http の場合 TLS の処理 `appconnect` がない分、https よりも `pretransfer` まで200ミリ秒以上早く、total では2倍くらいの差が出ました

実際のブラウザによるアクセスなどのユースケースでは、

- 今回の実験よりもレスポンスのサイズが大きいことが多いと考えられるため、レスポンスのダウンロードにかかる時間のほうが支配的になるはず
- 複数のリクエストにまたがる場合にセッションが維持されることが多いと考えられるため、全体からすると `connect`, `appconnect` にかかる時間の割合は減っていくはず

など考えられますが、curl で簡易的な調査をする際には役立つことがあります
gorm Preloadで論理削除レコードをSELECTする【GORM】

golangのORマッパーであるgormにおいて、論理削除されたレコードを取得するにはUnscoped()を用いる。

Preloadで読み込むテーブルに対してもUnscoped()を適用する方法を記載する。

## メインテーブルの論理削除SELECT

```golang
db.Where("id = ?", id).Find(&table1)
```

## Preloadするテーブルの論理削除SELECT

```golang
db.Preload("Table2", func(db *gorm.DB) *gorm.DB { return db.Unscoped() })..Where("id = ?", id).Find(&table1)
```

以下のようにすることでPreload先の論理削除レコードをSELECTできる。
```golang
.Preload("Table2", func(db *gorm.DB) *gorm.DB {
  return db.Unscoped()
})
```

以上。
2年6ヵ月で会社の技術ブログを100記事以上書いたことによる、4つの変化

2020年11月から2023年5月までの間に、会社の技術ブログを100記事以上書きました。  
書き始めた頃と今で、自分にどういう変化があったのかを考えました。  

### 技術情報を説明・発信する人へのリスペクトが爆増した
技術ブログを書く前は、個人の技術ブログ、製品のマニュアル、サービスのヘルプページを閲覧する時には何も感じませんでした。知りたい情報が載っていない事に対して腹を立てることもありました。  

しかし、会社のブログで技術情報を書くようになって初めて、自分の知識を文章化することは決して簡単なことではないと気が付きました。

今でも、技術情報を説明・発信する人へのリスペクトは増す一方です。


### 他人が書いた文章を丁寧に読むクセがついた
私は自分が書いた文章が好きではありません。私の文章は表現が冗長になりがちで、主語が分かりずらい傾向があるからです。

だから日常的に、技術情報をわかりやすく 且つ 過度に端折ることなく正確に伝えている文章を探しています。

結果として、他人の書いたメール、ドキュメント、ブログを丁寧に読むクセがつきました。


### 自分が書いた文章を読み返すクセがついた
記事を書いた当時の私は「よっし！完璧！」などと満足して、記事を公開します。

しかし、あとから読み返すと「文章が長い、主語がない、端折りすぎ、脱線しすぎ。我ながら最悪な出来だ。」と思うのは毎度のことです。

ブログを書くことは、文章力の無さを自覚するきっかけになりました。
結果として、メールや提案資料の作成といった日常業務でも、自分の書いた文章を読み返すというクセがつきました。



### 知っている事、知らない事、知った気になっている事の境界を把握できるようになった
技術知識を文書化するにあたり、その技術に対する自分の理解度を素直に受け入れられるようになりました。
私の持つ技術的な知識は、おおよそ以下の3つに分類できました。

* 知っている事
* 知らない事 (自分が知らないということは理解している)
* 知った気になっているけれど、実はよくわかっていない事 (見栄っ張りな、にわか知識)

3点目が存在すること自体は問題ではないと思います。
問題は、その知識の詳細と真偽を確かめず、正確な情報であるかのように断定的に文書化し、他人に誤解を与えることです。

ブログを書き始める前は、自分の知識を全てとし、そこから導き出される思い込みの推測をあたかも正確な情報であるかのように伝え、混乱を招いたことがありました。
しかし、ブログを書くようになってからは、自分の知識が正確なのか、検証したのか、情報のソースは信用できるのか、例外は無いか、いつの情報か 等を客観的に評価し、それを受け入れるようになりました。
正確性に自信が持てない知識については、追加で検証を実施するか、思い切って書かないという選択をするようになりました。


以上の4点が、2年6ヵ月で技術ブログを100記事以上書いたことで変わったことです。

### 最後に
IT技術者において、技術情報のアウトプットのメリットとしてよくあげられるのは、"知識の定着" かと存じます。
もちろん知識の定着も大事なメリットなのですが、私の場合、知識の定着ではなく上記4点の変化が大きなメリットでした。

同僚や上司にアウトプットを求められた際、あまり気がのらないこともあるかもしれません。
私の場合も、アウトプットを依頼してきた方が、まじめに読んでくださらないことは日常茶飯事でした。(Readの履歴すらついてない事もしばしばでした。)

それでも、定期的なアウトプットを継続したことにより、自分自身が予期していなかった方面で、日常の業務への取り組み方を改善するきっかけになりました。
また、自分の書いたアウトプットを頼りにしてくださる方が一定数いらっしゃる事実は、単純にうれしいことでした。
「2年6ヵ月書き続けてこの程度のことしか得られないのかよ」とお思いの方もいらっしゃるかと存じますが、私にすれば大きな変化であり、特定の顧客に対して行うサービスとは違った満足感を得られました。

私のこの記事が、IT技術者において、アウトプットにどういった効果があるのかを調べている方の参考になれば幸いにございます。
お読みいただきありがとうございました。
Azure Data Fundamentals(DP-900)合格体験談

先日Azure Data Fundamentals(DP-900)に合格しました！
![scoreReport.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332975/5104462f-67a7-0514-a3ed-7e29a73df76d.png)
ハリボテの3冠です。
・DP-900(Azure Data Fundamentals)
・AZ-900(Azure Fundamentals)
・AZ-104(Azure Administrator Associate)

今回は、勉強方法や概要について記載してみようと思います。

# 概要
その名の通りデータに関する知識を問われる資格試験です。

・データの形式(構造化データ、半構造化データ、非構造化データ)
・データベースの種類(リレーショナルデータベース、非リレーショナルデータベース)
・SQLの基礎(データ記述言語 (DDL)、データ制御言語 (DCL)、データ操作言語 (DML)の違い)
・AzureのDBやストレージに関するサービスの概要(Azure SQL、Azure Cosmos DB、Azure Blob Storageなど)

[試験時間]
45分

[問題数]
45問前後(※私は42問でした)

[合格点]
700点/1,000点

[出題形式]
・選択形式
・はい/いいえの2択の選択形式
・ドロップダウンリスト形式
・ドラッグ＆ドロップ形式

[受験料]
¥12,500(+税)

[資格の有効期限]
なし

※最新の情報含め、詳しくは以下

https://learn.microsoft.com/ja-jp/certifications/exams/dp-900/

# 受験のきっかけ
年明けくらいに、ORACLE MASTERの勉強をしようと参考書を買ったのですが、間違えて旧体系の試験(Bronze DBA 12c)のものを買ってしまい、家に帰り解説編と練習問題編を分解した後に気づいたため、返品するわけにもいかず。。。

~~そんな本並べておかないで(泣)。~~ (よく確認しないで買った私が100%悪い。)

無駄にするのももったいなかったので、「SQLの話だし役に立つだろう」と、とりあえず1周読んだのが始まりです。

![IMG_4422.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332975/1f5d17fd-b498-d9a7-86c5-130e48c5c2b1.jpeg)

せっかくなので知識を活かせる今回のDP-900(Azure Data Fundamentals)の取得挑戦にいたりました。

また、直前にAZ-104(Azure Administrator Associate)を取得したのですが、少し難しめの資格を取得すると、燃え尽き症候群になり勉強の手がしばらく止まる癖があるので、習慣を途切れさせないためにも手を出しやすそうな資格を狙ってみました。

# 勉強期間
1日1,2時間やったり全くやらなかったりをだらだらと3週間ほど。
※色んな方の合格体験談を読む中で、詰め込めば1日で大丈夫と書いている人もいました。

# 勉強方法
### 無料の試験対策オンデマンド講座を受講

https://info.microsoft.com/JA-AzureSQL-WBNR-FY21-04Apr-14-MKTOFY21DP900PrepSessionOn-demandWebinar-SRDEM71243_LP02OnDemandRegistration-ForminBody.html

### Udemyの問題集をループ(3周くらい)

問題集系だとプレビューが見れないので(見れないよね?)どれを買えばよいのか悩ましい所ですが、レビューを読んで、以下のあたりを見極めるのがポイントかなと思います。

・解説がちゃんとしていそうか
・質問などの問い合わせに対応しているか
・定期的に更新されているか

### Microsoftの公式学習ページ

https://learn.microsoft.com/ja-jp/certifications/exams/dp-900/

　基本的にAzureの資格は公式の学習ページが整備されていますが、日本語の書き方などにアレルギーがあり全然頭に入ってこない印象があったので、今回は使わずに進めていたのですが、試験の2日前くらいにチラ見をしてみたら、これがとてもよくまとまっていて、今まで使わなかったことを後悔しました。

事前に学習を進めていたから把握しやすかったという可能性も十分にありますが、これから受ける方は試験までに1周しておくことをオススメします。

### 世界中の有識者の方々
#### 特にお世話になったサイト
https://teshi-learn.com/2021-05/microsoft-dp-900/#toc5

### (使わなかったけど)Microsoft トレーニングday

https://www.microsoft.com/ja-jp/events/top/training-days/

　Microsoftが開催している無料のオンライン講座です。直近の開催がなく今回は受講できませんでしたが、Fundamentals系の資格は該当の講座を受ければ試験を無料で受けられるバウチャーチケットがもらえます。

平日のみの開催ですが、可能であれば受けた方が良いと思います。内容もとても分かりやすいらしいです。

### その他
ケーススタディや計算問題などは出題されないので、時間が足りなくなることはほぼないと思います。

AZ-900を取得していて、データベースの知識が少しあれば取得は難しくないと感じました。AZ-900の方が範囲も広く難しいです。

Fundamentals系でAI-900を取得していないので、次はそれかなぁ。
この記事がDP-900を取得する誰かのためになれば幸いです。
Origin（オリジン）備忘録　 ~今まで見てみぬふりをしてたけど、さすがに調べた~

Originについて今まで見たことあったけど今度調べようと思って無視してた。
でも、最近クロスオリジンエラーが出てさすがに調べないといけなくなったので調べました。
軽く調べたことはすぐ忘れちゃうので、ここにメモしておきます。

# オリジンとは
オリジンとは、URL中の以下の３つで定義されます。
* スキーム（プロトコル）　
    ex) ***http***://example.com/v1/index.html
* ホスト（ドメイン）
    ex) http://***example.com***/v1/index.html
* ポート番号
    ex)  http://example.com:80←これ
    ※Webサーバの場合は既定で80番のポートなので省略される。

## 同一オリジン
つまり、下記リソースは同一のオリジンです。
```
http://example.com/v1/index.html
http://example.com/v1/index2.html
http://example.com/v2/index.html
http://example.com:80/v2/index.html
```
→ファイルパスが違うのは関係がありません！

## 異なるオリジン
```
http://example.com
https://example.com
http://example2.com
http://example.com:50001
```

# 同一オリジンポリシー（簡単に）
同一オリジンポリシーとは、別のオリジンからのリソースのアクセスを制限するセキュリティ上の仕組みのことです。
これによって、悪意のあるウェブサイトにアクセスした際に、JS（Javascript)が実行され、サインイン済みのサイト（例えばECサイト）から情報を抜かれてしまうのを防ぐことができます。

詳しくは他リソースを参考にしてください。

# 参考
オリジン
https://developer.mozilla.org/ja/docs/Glossary/Origin
同一オリジンポリシー
https://developer.mozilla.org/ja/docs/Web/Security/Same-origin_policy
https://qiita.com/ymbn/items/cc69dc3eccf5a13bbeed
<作成中>ピポットテーブル

やりたいこと
・移動元保管場所と移動先の保管場所
・移動元保管場所と移動先保管場所の組み合わせのサマリ

移動元の導出キー
　数量がマイナス
　明細が奇数

移動先の導出キー
　数量がマイナス
　明細が奇数

プラント/保管場所/伝票/明細/数量
PowerAutomateでExcelの「表に行を追加」アクションを使って表を作った後は、「待ち時間」アクションを入れたほうが良さそう

# 結論
PowerAutomateでExcelの「表に行を追加」アクションを使って表を作った後は30秒程度の「
待ち時間」アクションを入れたほうが良さそうだと個人的に思いました。

# 実際に起きた問題
PowerAutomateで、「表に行を追加」アクションを使ってSharePointに配置しているExcelファイルにいくつか行を追加。その後、そのExcelファイルをメール添付で送信するというフローを作成していました。
![powerautomate_エクセル01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/c9f870e8-62d3-85ad-798b-647e8c24398b.png)
そして、このフローをテストした結果、フローそのものはエラーが発生することなく完了しました。
ところが、添付されたエクセルファイルには追加されている行が想定よりも不足していました。
![powerautomate_エクセル02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/52545329-7fc8-0355-3a3d-22db0b6ed729.png)

# 調査
以下のページに記載されている内容に今回の問題の原因だと思われるものがありました。

https://learn.microsoft.com/ja-jp/connectors/excelonlinebusiness/

> 行の追加、行の更新、行の削除 などの操作によってコミットされた変更は、対応する 、Power Automate LogicApps または Power Apps のアクションからの応答が成功した直後に常に有効になるとは限りません。 基になるバックエンド サービスの制限により、最大 30 秒の遅延が予想されます。

# 調査を踏まえての対策
「表に行を追加」アクションで全ての行を追加しきった後に待ち時間のアクションを追加して遅延分を調整します。
今回は余裕をもって待ち時間を35秒にしました。
![powerautomate_エクセル03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/a100f909-e9f5-0a1e-84e0-14445f66232e.png)
この対策を入れてフローの運用を行ったところ、今の時点では上記の問題は発生しておりません。

# まとめ
記事に書いた問題から、「表に行を追加」アクションを使って表を作った後は30秒程度の「
待ち時間」アクションを入れたほうが良さそうだと個人的に思いました。
もし同じような問題に直面した方がいらっしゃれば、待ち時間を入れてみてもいいかもしれません。
Qiita アップデートのお知らせ - 2023年 04月

![thumbnail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/d2664ddd-55dd-f107-661d-301dfb50e0ff.png)

## はじめに
Qiitaでは、エンジニアのみなさんからの声をもとに、日々開発を続けています。
この記事では、2023年 04月にリリースした内容を紹介します。

Qiitaでアップデートやバグ修正をリリースしたら、[リリースノート](https://qiita.com/release-notes)、[Qiita 公式 Twitter](https://twitter.com/Qiita)、[Qiita Blog](https://blog.qiita.com/)でお知らせしています。

また、Qiitaへの質問や機能の要望などがありましたら、[Qiita Discussions](https://github.com/increments/qiita-discussions) へご投稿ください。


## エディタのデザイン変更を正式に公開しました
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/3a33c3d2-d477-75eb-ae5e-8dad94e22fe3.png)
*2023年 04月18日 リリース*

ベータ版で公開していたエディタのデザイン変更を正式に公開しました。

- エディタのスタイルを他ページに合わせて、サイト全体でトーンが揃うようにしました。
- エディタの横幅に最大幅を持たせることで、大型モニター使用時もエディタが利用しやすくなっています。
- 画像や絵文字の挿入、同時スクロールのオンオフなどのアクション類をまとめて配置することで、アクセスしやすくしています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/72d2bbeb-bf09-0a77-e254-2e1288c29c96.png" alt="" width="100%"></img>


## 質問ページのダークモード対応をベータ版として公開しました
![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/17cd877a-cad6-d025-026f-ff3b0bf4ec6f.png)
*2023年 04月18日 リリース*

質問ページのダークモード対応をベータ版として公開しました。
[以前お知らせした記事ページのダークモード対応](https://qiita.com/release-notes/2023-02-15)と同様の変更です。
詳しい設定方法は[Qiita Blog](https://blog.qiita.com/article-page-dark-mode-beta)をご覧ください。

| 通常の見た目 | ダークモード有効化時の見た目 |
| --- | --- |
| ![通常の質問ページのスクリーンショット。白背景に黒い文字で文章が書かれている。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/2a94583c-8cc5-62e5-bff6-6b33db2735b2.png) | ![ダークモード有効化時質問ページのスクリーンショット。黒背景に白い文字で文章が書かれている。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/59201c9e-f6d2-82df-05eb-2cbbd31a566d.png) |


## 回答に対するコメントをMarkdownで書けるようになりました。
*2023年 04月14日 リリース*

- 回答や質問と同様に、回答に対するコメントもMarkdownで書けるようになりました。
- 回答に対するコメント欄でメンション出来るようになりました。

![Markdown化された回答コメントフォーム](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/8d1651a2-3ce2-c74c-ac65-f1f580338f3e.gif)

## タグページのユーザーランキングの「すべて」を「年間」に変更しました
*2023年 04月19日 リリース*

より流動性のある情報をお届けるすため、タグページのユーザーランキングの「すべて」を「年間」に変更しました。

| Before | After |
|:-:|:-:|
| ![ユーザーランキング。ユーザーが5名一覧化されていて、「週間」、「月間」、「すべて」で絞り込むことができる。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/ecc458b8-3734-feaa-318b-f58d95416b62.png) | ![ユーザーランキング。ユーザーが5名一覧化されていて、「週間」、「月間」、「年間」で絞り込むことができる。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/3bacbec7-de3e-c6f1-6a98-98e5a70c3914.png) |
【C++Builder】user_versionを変更する方法

## 今回困ったこと
DBのuser_versionを変更しようと、SQLQueryに

		SQLQuery1->SQL->Text = ""PRAGMA user_version=1;";
		SQLQuery1->Active = true;

ってしたら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274481/59876dd2-0e2e-c639-6376-3a400b119b81.png)
って怒られてしまってできなかったので、調べたところ、どうもSQLQueryは結果を返すSQL文でないと使用できないっぽい。

## 解決策
SQLConnectionを使えばいけました。

```
SQLConnection1->Execute("PRAGMA user_version=1;",NULL);
```
国税庁インボイスシステムを使ってみた：Power Automate Desktop編

弊社Web掲載記事の要約版です。設定を含む[詳細はコチラの弊社ブログ](https://alpcom.co.jp/blog/20230510/?utm_source=Qiita&utm_medium=post&utm_campaign=yas&utm_id=20230510)の参照をお願いいたします。
## API例
[国税庁の適格請求書発行事業者公表システムWeb-API](https://www.invoice-kohyo.nta.go.jp/web-api/index.html)（以下インボイスシステム）をMicrosoftが提供する無償RPAツールPower Automate Desktop（以下PAD）で[「取得期間を指定して情報を取得する機能」](https://www.invoice-kohyo.nta.go.jp/web-api/index.html#:~:text=%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82-,%E5%8F%96%E5%BE%97%E6%9C%9F%E9%96%93%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%A6%E6%83%85%E5%A0%B1%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B%E6%A9%9F%E8%83%BD,-%E3%80%90Ver.1%E3%80%91)を試してみました。

APIは例えば以下のようなURL指定をGETメソッドで実行するとcsv形式でデータ取得が可能です。

```
https://web-api.invoice-kohyo.nta.go.jp/1/diff?id=アプリケーションID&from=2023-04-20&to=2023-04-25&type=01&divide=1
```

## PAD設定考慮例
インボイスシステムのPAD使用での考慮例を以下に記します。
下記以外にも[コチラの弊社ブログ](https://alpcom.co.jp/blog/20230510/?utm_source=Qiita&utm_medium=post&utm_campaign=yas&utm_id=20230510)で設定に関して細かく解説をしております。

### 1.情報は数回に分けて取得
今回使用した「取得期間を指定して情報を取得する機能」は、期間指定したデータがドカンと1つのファイルで落ちてくる仕様ではなく、データが500行以上存在する場合、500行単位に数回に分けてダウンロードする必要があります。上記のパラメータでは最後のdivide=1の部分です。

### 2.分割数の把握
データを数回に分けてダウンロードするため、最初に何回に分けてダウンロードすべきか、分割数の把握が必要です。分割数はダウンロードしたファイルの1行目の4列目で取得が可能です。

### 3.単純にファイル合体できない
数回に分けてダウンロードしたデータを1枚の表のように合体したくなります。ですが分割して取得した各csvファイルの1行目に上記で説明した分割数を表す余計なデータが入っているため、1行目を削除してから合体させる必要があります。
DJI Mobile SDK V4を使って得た知見まとめ

# はじめに
DJI Mobile SDK V4を使ってAndroidアプリを作ろうと思っても、SDKのバージョンは更新されているのに、公式のチュートリアルは更新されない。APIのドキュメントを見てもよくわからない。
そんな状態で研究を行ってきて得た様々な機能の実装方法について、ここに残していこうと思います。

# Mobile SDKとは
Mobile SDKとはDJI社から提供されているSDKであり、今回まとめるV4は最新版ではありません。
最新版はV5となっており(2023年5月現在)、SDKのバージョンによって使用できるドローンの種類が違うため、注意が必要です。
V4が対応しているドローンの種類の一覧は以下から確認できます。
[DJI Mobile SDK V4が対応している機種一覧](https://developer.dji.com/products/#!/mobile)

# 開発準備
DJI Mobile SDK V4を使ってアプリ開発を行うにあたり行わないといけないことがあります。

## DJI Developerへの登録
DJIのドローン向けのアプリを開発するためには、DJIのアカウントを作成し、アプリ開発者として登録する必要があります。
[DJI Developer](https://developer.dji.com/)

## アプリの登録とApp Keyの発行
1. DJI developerからログイン
[DJI Developer](https://developer.dji.com/)へアクセスし、ログインする。
![developerLogin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671458/41c00359-7ed3-eb52-e446-832b70ba7847.png)

2. CREATE APPをクリック
![createAppButton.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671458/f0645d05-2858-fe8d-fdc2-85a4624f090a.png)

3. アプリ情報を登録し、メール認証
App Type：Mobile SDKを使うアプリのため、Mobile SDKを選択。
App Name：作成するアプリの名前を入力。
Software Platform：Androidアプリの開発のため、Androidを選択。
Package Name：作成するアプリのパッケージ名を記入。AndroidManifestやbuild.gradleに書いてあります。
Category：作成するアプリのカテゴリーを選択。自分の場合は該当するものがなかったのでOtherにしています。
Description：作成するアプリの説明を入力。
![createApp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671458/05920985-85a2-3a1a-2f67-d49a8e293e65.png)
上記を埋めてCREATEをクリックすると、登録してあるメールアドレスに認証メールが届きます。
そこから認証をすることで、画像のようにアプリが表示されます。
![AllApp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671458/800f4ec4-b825-4d22-976a-a7246aaf19ba.png)

4. 登録情報の確認
登録したアプリをクリックすると、登録情報が確認できます。
その中でApp Keyをアプリ開発に使用します。
![AppKey.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671458/78afdf7d-f68d-6122-2353-6c09a04c016f.png)

以上がアプリ開発を行う上での準備となります。

# 投稿記事一覧
~~順次Qiitaに記事を投稿していきます。~~
~~投稿次第更新し、リンクを載せていきます。~~

~~以下今後記事で解説予定の機能~~
~~* ドローンの位置情報取得機能~~
~~* Waypoint Mission(Google mapから地点を選択し、選択された順番に自動飛行する)~~
~~* Timeline Mission(自動飛行する機能、Waypoint Missionよりも複雑な自動飛行が可能)~~

2024年5月9日追記
SDK自体が古く対象機体も生産終了が多い&研究終了のため記事にはしません。

# まとめ
DJIドローン向けにアプリ開発を行うために必要な準備と今回解説するSDKについて説明しました。
~~これから様々な機能について私が知っていることをまとめていこうと思います。~~
Android Studio Giraffe 以降で Settings Repository を扱う

# はじめに

Android Studio Giraffe になってから Android Studio > Preferences > Tools に Settings Repository が表示されなくなってしまいました。

# 原因

ドキュメントに記載がありました。

> バージョン 2022.3 以降、設定リポジトリ プラグインは IntelliJ IDEA にバンドルされていません。JetBrains Marketplace で引き続きインストールできます。設定リポジトリのセットアップ方法については、IntelliJ IDEA ドキュメントのバージョン 2022.2を参照してください。

https://www.jetbrains.com/help/idea/sharing-your-ide-settings.html

Android Studio Giraffe は 2022.3 ベースなので、該当しています。
![Android Studio Giraffe](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184644/9e1a350b-7788-061b-33c5-29ec62b0a980.png)


# 解決策

Android Studio > Preferences > Plugins から Settings Repository をインストールできます。
![Plugin](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184644/b27f726f-8df2-0026-9c1a-b7caa9751fe3.png)

これで今までどおり表示されるようになりました。
![Settings Repository](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184644/c1fb0a26-5134-f280-d758-8657574d8355.png)
【Tips】「定数」「変数」「@IBOutlet」の書く順番【リファクタリング】

下の画像のように

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359201/4e1402a5-6890-7e83-64e8-3cae1e7e2bec.png)

「定数」や「変数」が先に来るのではなく

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359201/c2cf4948-be46-0a15-37cc-7481a36965f6.png)

「@IBOutlet」が先に来るように書いた方が良い。
Google Earth Engineを使用したLandTrendrの実装方法

**1.初めに**
　Google Earth Engine (以下、GEE)がリリースされたことにより、衛星画像の取り扱いが簡単になりました。その機能は、pythonとjavascriptのポテンシャルを秘めており、汎用性が非常に高い。
　その中でも、これまで使用可能なソフトが限られていたLandTrendrも使用できるようになっています。しかし、LandTrendrの使用に関しては、日本語での説明書がない (英語ならやり方にたどり着くかもしれません)ことや提供されているLT-GEEの処理工程を使いたくない人もいると思います。
　よって、本記事はGEEにデフォルトで提供されているLandTrendrの使用方法についてまとめる。

**2.コード**
　LandTrendrは、時間の概念が重要です。なので、年あたり一つの画像が必須です。もし、NDVIなどへの加工により取得時間が失われた場合には、これを補完する必要があります。
　LT-GEEは、年ごとの合成画像をLandTrendrに入力しています。本記事では、自分で加工した年あたりの画像を入力します。

```javascript
///以下のコードで時間のデータを自作します。year,month,dayは任意
var date =ee.Date.fromYMD(year,month,day).millis()
////仮に、NDVIへ加工し、時間データが失われた画像をndviとします。
///以下のコードで、時間を画像にセットします。
var ndvi =ndvi.set("system:time_start",date).toFloat();
```
　上記のコードにより、複数枚の画像を作成し、それらを一つのImageCOllection (画像の塊)とします。これは、ご自分で作成してください

　次に、いよいよ入力します。
```javascript
///仮に作成したimagecollectionをicとします。
///LandTrendrに必要なパラメータの設定 (確かデフォルト値)
var Params = {maxSegments:6,spikeThreshold:0.9,vertexCountOvershoot:3,
  preventOneYearRecovery: true,recoveryThreshold:0.25,pvalThreshold:0.05,
  bestModelProportion:0.75,minObservationsNeeded:6
};
///作成したimagecollectionをパラメータの一つにする。
Params.timeSeries = ic;
var result=ee.Algorithms.TemporalSegmentation.LandTrendr(Params);
```

　入力が完了しましたが、以下で結果を加工しなければなりません。
```javascript
///年の値を入れる空のリストを作成する
var years=[]; 
for (var i = startyear; i <= endyear; ++i) years.push('yr'+i.toString());
///NDVI_fitという名前は、icの中に統一されて存在する名前が採用される。
///私は、icのバンド名を全てNDVIと設定しています。
var LT_result= result.select("NDVI_fit").arrayFlatten([years]); 
```
　LT_resultが最終的に出力されるLandTrendrの結果となります。
【Tips】画面遷移はなるべくSegueを使わない遷移をするべき。【identifier】

基本的にSegueを使わない遷移をするべき。
現場でSegueを使っているところはあまりないから。
なぜなら、1Storyboard、1画面で作るので。

segueのidentifierが必要になる場面は
一つのUIに複数のボタンがあって複数のUIに分岐するパターンのとき。
#includeを使い、fopenを使わずにcsvファイルから2次元配列を初期化する

## はじめに
stdio.hが使えずfopenが使えない環境下で、実行速度測定のために10000x10000の行列演算をプログラム埋め込みで行ったので、そのときのメモ

## 結論
```csv:matrix.csv
1,2,3,
4,5,6,
7,8,9,
```
上のような3x3の行列の値を示すcsvファイルがあり、Cプログラムでこの行列を2次元配列として扱いたい場合には、以下のように`#include`を配列初期化部分に記述することで実現できる。

```c
#define SIZE 3
int matrix[SIZE][SIZE] = {
    #include "matrix.csv"
};
// matrixの値は{{1,2,3},{4,5,6},{7,8,9}}となる
```


## 解説
ここからは解説なので読み飛ばしてもらって構いません。

上の書き方は配列初期化時の構文と`#include`の仕様により実現できている。

### C言語における配列の初期化
C言語では配列の宣言時に、以下のように各要素の初期値を設定できる。

```c
int array[3] = {1,2,3};
```

行列データをプログラム内で2次元配列として扱う場合、
```c
int matrix1[3][3] = {
    {1,2,3},
    {4,5,6},
    {7,8,9},
};
```
のように行の対応をとって初期化を行うことも可能だが、以下のように単純に値を並べるような初期化を行うこともできる。
```c
int matrix2[3][3] = {1,2,3,4,5,6,7,8,9};
```

### `#include`の仕様
`#include`が記述された部分はプリプロセッサにより、指定したファイルの中身に置換されるという仕様となっている。

```csv:matrix.csv
1,2,3,
4,5,6,
7,8,9,
```
```c
int matrix[3][3] = {
    #include "matrix.csv"
};
```
そのため上のように記述した場合、プリプロセッサにより置換された結果として次のようなソースコードになる。
```c
int matrix[3][3] = {
    1,2,3,
    4,5,6,
    7,8,9,
};
```
このように記述することで、csvファイルの値を2次元配列にセットすることができる。