OmniAICreator/Qiita-1.07M huggingface dataset:
Laravelの勉強用備忘録[環境構築]

#初めに
Laravelの環境構築から初期設定等の備忘録的なやつ書いています。
OSはwindows10です。
xampp環境でphpを動かしています。

#環境構築
とりあえずLaravelが動くまでの方法です。
あくまで一例です。

## comporserのインストール

###comporserとは
PHPのライブラリ管理ツールです。
詳しくは各々調べてください。
簡単に言うと依存関係にあるライブラリをまとめてインストールできる超優秀な子です。

###comporserのインストール方法
インストールには公式サイトに行きます。
comporser公式サイト：https://getcomposer.org/

Downloadって書いてるところからcomporser-Setup.exeと書かれたリンクをクリックします。

|![スクリーンショット 2021-06-30 121253.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/983036/fc275c42-0b4b-bb31-e35e-c34bedd08d06.png)
|:-:|

インストーラー起動したら下の所だけ各自の環境に合わせてください。

|![スクリーンショット 2021-06-30 121726.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/983036/5125b149-0dcf-205c-5709-83a481294003.png)
|:-:|

ここからは最後までnextクリックで大丈夫です。

確認のために以下のコマンドを入力してバージョンが帰ってきたらokです。

```
% composer -V

```


##Laravelのプロジェクト作成
###Laravelのインストールとプロジェクトの作成
インストールはcmdを使います。
cmdを開いてcdで使いたいディレクトリまで移動してもいいですが・・・
エクスプローラのアドレスバーに直接cmdと入力するとそこでコマンドプロンプトが起動します。

使用したいところでcmdを開き

```
% composer create-project laravel/laravel sample

```

を入力することで
「Laravelのインストール」と「ディレクトリの作成」が行われます。ディレクトリ名はこの場合sampleです。

他に作りたい場合

```
% composer create-project laravel/laravel [directory_name]

```

で作れます。

##webで表示確認

最後に作成したディレクトリ内で

```
% php artisan serve 

```

実行してください。

|![スクリーンショット 2021-06-30 151829_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/983036/8ad93fcb-f122-2b6f-5a37-e9a95b88499a.jpeg)
|:-:|

写真のようになればOKです。

実際にwebのURL欄に「<http://localhost:8000/>」を入力し画面が表示されたら環境構築完了です。

#最後に
とりあえずこれで環境構築はできたはずです。。。
つい最近勉強始めたばかりですので間違えてること等あるかと思いますがお手柔らかにお願いします。
次はDB関連のことを書いていこうかと思います。

#参考サイト
- [Laravel入門 - 使い方チュートリアル -](https://qiita.com/sano1202/items/6021856b70e4f8d3dc3d)
- [Composerの使い方](https://qiita.com/sano1202/items/50e5a05227d739302761)
- [PHP(Laravel)入門者のための要点まとめ](https://qiita.com/yyokii/items/c7c98d467239dda2a59d)
WordPress のDB一括変換でステージング→本番切替

##WordPressのステージング環境から本番へ更新する労力を減らしたい
WordPressでサイトを作る際、ステージングと本番環境を分けるにはどうしたら良いかと考えたわけです。
当初使ったのが [Duplicator](https://ja.wordpress.org/plugins/duplicator/) というプラグインです。
そこそこうまく行ったんですが、ステージング→本番の切替えにかかる手間暇がだんだんと気になるようになってきました。画面をいくつも開いてチェックしパラメータを変更し、ファイルをダウンロードして転送してスクリプトを起動し、等々やっていると1回につき10分ぐらいは時間を取られるので、ちょっとした変更をサクッと反映させるには向きません。（それを自動化するスクリプトを組むのもちょっと気が重い）

1つの記事を投稿した後で「あっ、誤字見つけた」みたいに軽い修正を入れたい時ってありますよね。でもそのたびに10分作業しなきゃいけないとなると大変なので「いくつかまとめて修正しよう」と思いがちで、修正が遅れたり忘れたりということになりがちでした。

##プラグインなしでステージング→本番更新をする方法はないものか？
そこで、なんとか良い方法はないものかと当初はまた別なプラグインを探してみたものの、なかなか良さげなものが見つかりません。

そうこうするうちに、できればプラグインなしでやりたいなと思うようになりました。Duplicator を使った運用ではステージング環境をローカルに置き、そのデータをプラグインでファイルにまとめて本番用サーバーにアップロードして更新していましたが、ひょっとしたらDBを一括コンバージョンすれば行けるんじゃないか？　と。

## ステージング用/本番用のDB一括コンバージョンを試してみた
つまり、ステージングと本番で違うのはURLのドメイン名部分だけなので、そこを一括でコンバージョンしてしまえば簡単なスクリプトでデプロイできるんじゃないかというわけです。

![capture210630-150238-30902.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1710522/fbda68c5-4b0f-eda2-1ed7-e651a47e5fd5.png)

実際やってみたら、できました。mysqldumpでステージング環境のDBをダンプし、sedで1行、

```sed -e 's/A\.xxx\.jp/B\.xxx\.jp/g'```

という感じのコードでコンバージョンして本番DBのほうでロードしてやるだけでした。

##VPSサーバーのサブドメインでステージング/本番を切替え
最終的にはステージング環境/本番環境とも同じVPS上に置いてこんな構成にしました。
![capture210630-151127-30903.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1710522/a2683f1f-1328-6ccd-6a77-82dc16fb7a6a.png)

ステージング環境は管理者のみがアクセス出来るようにIPアドレス制限をかけ、画像フォルダは本番と共有、ステージングの準備ができたら CONV_AtoB スクリプト一発で本番へデプロイします。

CONV_AtoBでやっているのは 

* DB-A をダンプ
* sed でURLを変換
* DB-B へロード

というだけです。一方的に情報発信するだけの単純な構成のサイトだったらこんな方法でもいけるようですね。

コメントがつくようなサイトだともう一工夫必要でしょうし、画像ファイルを共用していていいのか？　という問題もありますが、とりあえず今日はこのへんで。
SpringBootでTSVファイルのダウンロードボタンを実装する

#はじめに

SpringBootで商品テーブルからデータを検索し、TSVファイル出力してダウンロードするボタンを実装したい。

#依存関係の追加
"jackson-dataformat-csv"を追加するとcsvの変換をやってくれるので簡単です。

```java`pom.xml
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		
		<dependency>
    		<groupId>com.fasterxml.jackson.dataformat</groupId>
    		<artifactId>jackson-dataformat-csv</artifactId>
    	</dependency>
```
#Modelの実装
Item.javaに対して@JsonProperty を設定する

@JsonProperty で設定した値が、1行目に出力されます。設定しない場合はフィールド名が自動で出力されます。
また、@JsonPropertyOrder を設定することで任意の順番で出力することができます。

```java
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonPropertyOrder({"id","name","condition","category","brand","price","shipping","description"})
public class Item {
    @JsonProperty("id")
    private Integer id;
    @JsonProperty("name")
    private String name;
    @JsonProperty("condition")
    private Integer condition;
    @JsonProperty("category")
    private Integer category;
    @JsonProperty("brand")
    private String brand;
    @JsonProperty("price")
    private Integer price;
    @JsonProperty("shipping")
    private Integer shipping;
    @JsonProperty("description")
    private String description;

///以下getter/setter
```

一部余計なフィールドがcsvに出力されてしまうみたいなので、
@JsonIgnore を設定し、そのフィールドを変換の対象外にする。

```java
    @JsonIgnore
    private String nameAll;
```

フィールド変数"nameAll"は変換されなくなった。

#Controllerクラスの実装

Object <-> CSV の変換に CsvMapper というクラスを使用して、オブジェクトを CSV に変換します。
また、出力するcharset は Shift_JIS を指定します。

また、ダウンロードされるファイルのデフォルトの名前は URL に準じるため、"*.tsv" という URL を割り当てておくだけで、リクエストされたファイル名でそのままダウンロードさせることが可能になります。

```java
@Controller
@RequestMapping("tsv")
public class TsvController {
	@Autowired
	private ItemRepository itemRepository;
	
    @GetMapping(value = "*.tsv",
            produces = MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=Shift_JIS; Content-Disposition: attachment")
    @ResponseBody
    public Object getTsv() throws JsonProcessingException {
    	// DBから全件取得
    	List<Item> todos = itemRepository.findAll();        
        
        CsvMapper mapper = new CsvMapper();
        CsvSchema schema = mapper.schemaFor(Item.class).withHeader().withColumnSeparator('\t');
        return mapper.writer(schema).writeValueAsString(todos);
    }
}
```
ヘッダーありの場合は.withHeader()を付ける
csvをtsvに変換する場合は.withColumnSeparator('\t')を付ける

#DLボタンの作成

```html
    <!-- tsv_downloadボタン -->
    <form method="get" th:action="@{/tsv/demo.tsv}">
    	<input type="submit" name="download_file" value="ファイルをダウンロード">
    </form>
```
リクエストするファイル名でDLをすることができる。

#動作確認

![スクリーンショット 2021-06-29 12.25.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/791219/84fe49ff-57bf-4aea-c63d-2e1c09048e1b.png)

![スクリーンショット 2021-06-29 12.25.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/791219/00e57043-870a-7d66-afa2-29c06695e9b0.png)

無事tsv形式でDLができました。
STM32G031とMCP9701で温度をシリアルに出力 (STM32)


x MCP9701-E/TO 販売コード 103199

X swd-sck-txを潰すので上級者用　(リセット対応していないと書き込みが難しい)
X 極めてプログラムは、シンプル
X [ツール]->[U[S]ART support ...]->[Enabled generic Serial]
X STM32G031の電源を入れた後にSerialの電源を入れる　bootが起動するため
X 参考程度に
X シリアル通信と6GPIOを参照のこと
X 3秒以内にST-LINKを接続すると繋がるかも

目的
秋月で売っている安価なMCP9701(約25円)を使って温度を
シリアルに出力する。

構成
MCP9701-E/TO I-03199
STM32G031J6M6


```c++


//初期化
void setup()
{

  delay(3000); //not Delete

  Serial.begin(9600);

} //setup

//メインループ
void loop()
{

  int s;  //センサーの値
  int n0; //小数点以上

  analogReadResolution(12);
  s = analogRead(A3); // PA11 PIN5

  //電圧を温度に変換 ex 20.0 -> 200 温度の十倍を出力
  s=((s*1692)>>12)-205;

  //s = 0;   //0  debug
  //s = 200; //20 debug

  //小数点以上と小数点以下を分ける
  n0 =(s/10);      // 小数点以上
  s  =(s-(n0*10)); // 小数点以下

  //温度の小数点以上の表示
  Serial.print(n0);

  //小数点の表示
  Serial.print('.');

  //温度の小数点以下の表示
  Serial.println(s);

  //1秒の待ち
  delay(1000);

} //loop



```

![adc_9701_031_s_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f2d8741e-aa1d-5ee9-3cc3-2516db121297.jpeg)
NoMethodError 　「エラー」という名の道しるべ👈

エラーは，正しい道に導いてくれる道しるべのようなものです。
いろいろなエラーを学ぶことで，
「うわ，エラーだ💦」　から　「よし，間違い発見💡」
となれたら良いなと思います。
# 「NoMethodError」とは
「メソッドがありませんよ」という意味です。
![スクリーンショット 2021-06-30 14.30.11（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1376379/66cfb513-0723-141c-5c7c-ac527407f5cb.png)
## 「undefined method 'rende'」
ここでは，「'rende'というメソッドは定義されていませんよ。」と教えてくれています。
さらに
## 「Did you mean?  render」
「'render'という意味ですか？」と聞いてくれています。

表示されたように修正してみると，無事直りました💡

## ちなみに
「Did you mean?　◯◯」のとおりにすれば全てうまくいくというわけではありません。

提案の１つですね😄
C# PDFでフォントを置換

<p><strong>今回はSpire.PDFという無料で使いやすいライブラリを利用して、PDFでフォントを置換える方法を紹介します。</strong></p>
<h4><strong>下準備</strong></h4>
<p><strong>1.E-iceblueの公式サイトから<a href="https://www.e-iceblue.com/Download/download-pdf-for-net-free.html">Free Spire.PDF</a>無料版をダウンロードしてください。</strong></p>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210630/20210630145648.png" alt="f:id:lendoris:20210630145648p:plain" width="526" height="230" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /><br /><strong>2.Visual Studioを起動して新規プロジェクトを作成してから、インストールされたファイルにあった相応しいSpire. PDF.dllを参照に追加してください。</strong></p>
<p><strong>（Net 4.0を例としたら、デフォルトパスは“Bin→NET4.0→PDF.dll”というようです。）</strong></p>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210630/20210630145700.png" alt="f:id:lendoris:20210630145700p:plain" width="289" height="207" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /></p>
<h4><strong>元のファイル</strong></h4>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210630/20210630145829.png" alt="f:id:lendoris:20210630145829p:plain" width="478" height="311" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /><br /><br /></p>
```c#
using Spire.Pdf;
using Spire.Pdf.Graphics;
using Spire.Pdf.Graphics.Fonts;

namespace ConsoleApp1
{
	class Program
	{
	static void Main(string[] args)
		{
			//Pdf ファイルをロードします。
			PdfDocument doc = new PdfDocument();
			doc.LoadFromFile(PDF file);

			//UsedFontsでフォントを取得します。
			PdfUsedFont[] fonts = doc.UsedFonts;

			//新規フォントを作成します。
			Font newfont = new PdfFont(PdfFontFamily.TimesRoman, 18f, PdfFontStyle.Italic | PdfFontStyle.Bold);
            cjkFont = new PdfCjkStandardFont



			//ファイルのフォントをループして、新規フォントを適用します。
			foreach (PdfUsedFont font in fonts)
			{
				font.Replace(newfont);
			}

			//保存します。
			doc.SaveToFile(Result file);

		}
	}
}
```
<h4><strong>実行結果</strong></h4>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210630/20210630145816.png" alt="f:id:lendoris:20210630145816p:plain" width="467" height="327" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
iOSの認証情報管理方法

# 認証情報管理問題
iOS開発においてAPIKeyやSNS連携用のidなどの認証情報の管理をどうするかというのは悩ましいです。
こういった隠蔽したい情報を管理するにあたって避けたいことはいくつかあります。

# 避けたいこと
## gitの管理対象のファイルに記載する
プライベートリポジトリでも、意図せずパブリック化される事故はあるので避ける。

### NG例
- swiftコードに認証情報をベタ書き
- Build SchemeのEnvironment Variablesで宣言
- Build SettingsのUser Definedで宣言
- Build PhasesでScript実行し宣言、Script内にベタ書き.

## リソースファイルに記載する
昔から有名ですが、ipaファイルをunzipすると誰にでもリソースファイルは見えてしまいます。
info.plistでBuild Schemeごとに値を変えるというのは好ましくないです。

※ここでいうリソースファイルはBuild PhasesのCopy Bundle Resourcesで指定されているファイル群です。
plist、assetsなどのswiftファイル以外前半です。

### NG例
- リソースファイルに定義しCopy Bundle Resourcesでipaに含める

# 今のところ、良さそうな方法
## Git管理しない.swiftで定義する
git管理外(.gitignoreで指定)の.swiftファイルで定義する方法です。

.gitignoreにしておけば、変更を加えても、うっかりコミットされることはないです。
一方で.swiftファイルなので、何年か後に変更することがあっても容易。
info.plistや他のファイル形式と違って、定数なのに取得時にOptionalになるなどもない。

守るべき点としては、プロジェクトファイルでは認証情報.swiftをビルドに含めるということになっていれば良いです。
- projectからのリファレンスはある
- Compile Sourcesで定義されている
- でも.swift自体はgit管理しない.

手順はこの方法だとやりやすいかと思います。
1. .gitignoreに認証情報.swift追記しコミット.
2. 認証情報.swiftを通常のソースファイル追加手順で追加.
3. Finder上でファイルを削除.
4. 差分のあるproject.pbxprojをコミット

## Bitriseでソースファイルの追加方法
Bitriseに認証情報.swiftをuploadしておいて、workflow実行時にアクセスしてプロジェクトに追加して利用します。

### Generic file Storageに認証情報.swiftをuploadする
Workflow EditorのCode Signingタブ最下部ににGeneric file storageというものがあります。
あらかじめFileStorageIDを指定してファイルをuploadすると、storageのURLが発行されWorkflow内でアクセスできる仕組みになっています。
発行されるもの自体は`$BITRISEIO_YOUR_FILE_STORAGE_ID_URL`という形式の環境変数になります。

### File Downloaderでプロジェクト内に配置する

File DownloderというstepがあるのでそちらでDL先を指定します。
git clone時の **Clone destination (local) directory path** がデフォルトの$BITRISE_SOURCE_DIRであれば、カレントディレクトリがプロジェクトのルートになるので適切に配置してください。

以上で完成
next.jsでTypeScriptとsass使用での型宣言エラー


## 問題
next.jsにTypeScriptとsassを入れたときに発生。
モジュール '../pages/index.module.scss' またはそれに対応する型宣言が見つかりません。
と言われてしまう。


## 解決方法
next.jsに自動生成されるnext-env.d.tsの中に、
scssファイルのimportを構文エラーを回避するため以下を記述


```next-env.d.ts
declare module '*.scss';
```

初見で意外とハマってしまった...
Linux、コマンドctrl+zで一時停止したとき

#備忘録
インストール(pip install)したときに実行途中でCtrl +zで一時停止する。
(終了はCtrl +z),この後の操作

停止させているプログラムの一覧は、jobsコマンドで表示することができる
停止したプログラムの再開は、fgコマンドで行う。引数なしでfgコマンドを実行すると、最近停止したジョブが再開される。また、fgコマンドでは再開させるジョブを指定することもできる。fgコマンドの引数として再開させるジョブのジョブ番号（jobsコマンドで左端に表示される数字）を指定すればいい。
C# パワーポイントでスマートアートを挿入

<p><strong>「SmartArt」(スマートアート)とは、組織図やフロートチャートなどの図表を簡単に作成できる機能です。メント）とは、XMLをベースとしたオフィススイート用のファイルフォーマットです。今日はSpire.Presentationという無料のライブラリを使って、パワーポイントでスマートアートを挿入する方法を紹介します。</strong></p>
<h4><strong> </strong><strong>下準備</strong></h4>
<p><strong>1.E-iceblueの公式サイトから<a href="https://www.e-iceblue.com/Download/download-presentation-for-net-now.html">Free Spire. Presentation</a>無料版をダウンロードしてください。</strong></p>
<p><strong> </strong></p>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210630/20210630145016.png" alt="f:id:lendoris:20210630145016p:plain" width="554" height="205" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /></p>
<p><strong>2.Visual Studioを起動して新規プロジェクトを作成してから、インストールされたファイルにあった相応しいSpire. Presentation.dllを参照に追加してください。</strong></p>
<p><strong>（Net 4.0を例としたら、デフォルトパスは“Bin→NET4.0→Presentation.dll”というようになります。）</strong></p>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210630/20210630145022.png" alt="f:id:lendoris:20210630145022p:plain" width="250" height="216" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /></p>
```C#
using Spire.Presentation;
namespace RemoveWatermark
{

    class Program
    {

        static void Main(string[] args)
        {
            //スマートアートを挿入します。
            Presentation pres = new Presentation();
            Spire.Presentation.Diagrams.ISmartArt sa = pres.Slides[0].Shapes.AppendSmartArt(20, 40, 300, 300, Spire.Presentation.Diagrams.SmartArtLayoutType.Gear);

            //スマートアートのタイプを設定します。
            sa.Style = Spire.Presentation.Diagrams.SmartArtStyleType.SubtleEffect;
            sa.ColorStyle = Spire.Presentation.Diagrams.SmartArtColorType.GradientLoopAccent3;

            //図形をすべて除きます。
            foreach (object a in sa.Nodes)
                sa.Nodes.RemoveNode(a);

            //カスタムの図形を追加します。
            Spire.Presentation.Diagrams.ISmartArtNode node = sa.Nodes.AddNode();
            sa.Nodes[0].TextFrame.Text = "aa";
            node = sa.Nodes.AddNode();
            node.TextFrame.Text = "bb";
            node.TextFrame.TextRange.Fill.FillType = Spire.Presentation.Drawing.FillFormatType.Solid;
            node.TextFrame.TextRange.Fill.SolidColor.KnownColor = KnownColors.Black;

            //保存します。
            pres.SaveToFile("SmartArtTest1.pptx", FileFormat.Pptx2007);
            System.Diagnostics.Process.Start("SmartArtTest1.pptx");


        }
    }
}
```
<h4><strong>実行結果</strong></h4>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210630/20210630145120.png" alt="f:id:lendoris:20210630145120p:plain" width="554" height="320" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /></p>
<p> </p>
touchでディレクトリがなければmkdir -pしてくれるコマンドをgemにした話。(touch_p)

#はじめに
ファイル作ろー。親ディレクトリないけど`touch`に`-p`オプションつければ大丈夫！（だよな？）

```Bash:
$ touch -p parent_hoge/child_hoge
touch: illegal option -- p
~略~
```
あれ？touchコマンドにpオプションなかったっけ？mkdirにはあるのに！

みなさんも一度はこのミスをしたことがありますよね？(この記事にたどり着いたということはあるに違いない！)
しかし、ここで怒ってはいけません。
そもそもtouchは**ファイルのタイムスタンプを更新するコマンド**なので、**ディレクトリに対する操作がないのは当然**です。

かといって`mkdir`と`touch`2回もコマンドを実行するのは煩わしいですよね？

そこで！上記の挙動をするcliを**gem**で作ってしまいました！
とりあえずgemのページとソースコードです。

https://rubygems.org/gems/touch_p

https://github.com/H0R15H0/touch_p

# 使い方
まず、gemをインストールします

```Bash:
$ gem install touch_p
```
あとは通常の`touch`や`mkdir`のように使うだけです。
### パターン1 hoge/hogeのとき

```Bash:
$ tree
.
$ touch_p parent_hoge/child_hoge
$ tree
.
└── parent_hoge
    └── child_hoge
1 directory, 1 file
```
### パターン2 hoge/のとき

```Bash:
$ tree
.
$ touch_p hoge/
$ tree
.
└── hoge
1 directory, 0 files
```


# gemにした理由
すでにshellスクリプトで実装する記事もたくさんありますし、新たにgemで作る必要はありませんでした。
ただRubyを使用しているプログラマとしてgemの仕様を知っておくべきだ思ったので、思い切ってgemで作成することにしました。

# gemの作成にあたり参考にした記事
[gemの作り方から公開まで](https://qiita.com/9sako6/items/72994b8b1c00af4e61fe)
[rspec入門](https://qiita.com/jnchito/items/42193d066bd61c740612)
rails Shift_JISの日本語パラメータを受け取る

## 課題

```
ActionController::BadRequest: Invalid request parameters: Invalid encoding for parameter:
```

が発生した。
外部APIのレスポンスにShift_JISの日本語が入っていた。


## 解決
param_encodingを使う

### 検索結果
https://nts.strzibny.name/windows-1250-encoding-rails-action/

### doc
https://api.rubyonrails.org/classes/ActionController/ParameterEncoding/ClassMethods.html#method-i-param_encoding

sample

```ruby
class SampleController < ActionController::Base 
 param_encoding :action_name, :param_name, Encoding::Shift_JIS
 
 def action_name
 end
end
【Docker】コンテナを削除した後もデータが残るデータベースを作るには no.22

![パンプキン カフェ (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/b5649d45-5adc-7eda-de1b-feae5df17486.png)


こんにちは。まゆみです。

Dockerについての記事をシリーズで書いています。

[前回の記事](https://qiita.com/Mayumi_Pythonista/items/11b412e59e045a2c5eb3)では、データベース・バックエンド・フロントエンドのContainerをつなぎ、それぞれのContainerでコミュニケーションができるようにしました。(データベースにはmongodbを使用しました。)

Containerをつなげることには成功しましたが、<font color="Red">あのままでは、mongodbのContainerを削除した時にContainerと共にデータも消えてしまいます。</font>

今回の記事では、コンテナを削除してもデータベースは単独で生き残らせるにはどうしたら良いのかということに焦点を置いて書いていこうと思います。


ではさっそく始めていきますね。


#Named Volumeを使う
Containerを消しても、データだけは生き残らせるためには、<font color="Red">Named VolumeというContainerからは切り離されたVolumeを作る必要</font>があります

以前の記事で、Named Volumeについては軽く触れていますので、興味のある方は[こちら](https://qiita.com/Mayumi_Pythonista/items/15257212e0822b40a98a#2container%E3%81%AB%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E7%BD%AE%E3%81%8D%E3%81%9F%E3%81%8F%E3%81%AA%E3%81%84%E6%99%82)からどうぞ

#オフィシャルのmongoイメージを使う時のContainer側のデータの保存先

Named Volumeは下記のように、：(コロン)をはさんで左側にホスト側のディレクトリ右側にContainer側のディレクトリを書きます

```
-v <あなたの好きな保存先の名前> : <Container側のディレクトリ>
```

ただオフィシャルのmongoイメージを使う時、『Containerのどこにデータの保存先のディレクトリがあるのか』分からないですよね。

そこで、[ドキュメント](https://hub.docker.com/search?q=mongo%20&type=image)を見てみましょう。

![2021-06-30_14-08-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/7ee60009-326c-2971-73f1-21a19be45bde.png)


![2021-06-30_14-12-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/1fbfb1c1-bd70-f355-1d7e-9c304fec7928.png)

```
-v <ホスト側のディレクトリ> :/data/db
```

：の左側に書く、『ホスト側のディレクトリ』に関してはあなたが好きなところに作ってかまいません。(公式のドキュメントをそのままコピペする必要はありません)

ただ：の右側に書く『Container側のディレクトリ』に関しては、公式ドキュメントに書かれている通り

<font color="Red">/data/db</font>

と書きましょう

![2021-06-30_14-22-34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/14dda8b1-aa58-dd3a-6b6c-6935d9598d4a.png)

これで、例えContainerを削除したとしても、データは切り離されて生き続けます

#データを見るには？

```
docker volume ls
```

で今まで作ったVolumeのリストを表示する事ができます

![2021-06-30_14-30-29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/1e82b48e-2897-edc7-33a3-c472861f89df.png)

VOLUME NAMEにdataと名前が付けられているのが、今回作ったNamed Volumeになります


#まとめ
今回の記事はここで終わりにしますね。

次回の記事では、データベースのセキュリティについて書いていこうと思います

どうぞ、よろしくお願いいたします。<(_ _)>
複数のボタンをまとめdidTouchUpInsideで管理

複数のボタンdidTouchUpInsideでまとめて sender.tagにてcaseにて管理

```
    @IBAction func didTouchUpInside(_ sender: AnyObject) {
        //textTarget.resignFirstResponder()
        print("sender in")
        
        switch sender.tag {
        case 1:
            print("button1")
        //printerPicker!.showPicker()
        case 2:
            print("button2")
        //langPicker!.showPicker()
        case 3:
            print("button3")
        case 4:
            print("button4")
        default:
            print("sender out")
            break
        }
    }
```
下記の様な複数のボタンを配置し@IBAction func didTouchUpInside(_ sender: AnyObject) {....
内にcase文いて分岐する例。
![スクリーンショット 2021-06-30 13.33.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/32063ea7-c2ba-d33e-5bb9-4046f06bd731.png)
下記の様にドラッグし紐付けする。
![スクリーンショット 2021-06-30 13.36.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/17d502a5-07eb-2fa4-f682-ab573b8e9bff.png)

紐付けいしたボタンのtagIDを設定する。
![スクリーンショット 2021-06-30 13.34.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/52c1dd27-ebd5-98f6-e43f-60853c346eb3.png)
didTouchUpInsideがReceived Actionに追加されていることを確認。
![スクリーンショット 2021-06-30 14.18.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/dc246fd4-fcbd-75ab-634b-5573a11823ad.png)
AWSはじめました

本日は以下のことを行いました。

・AWSのアカウント作成
・IAMユーザー作成（利用制限をかけるため）
・二段階認証を設定（ルートユーザー、IAMユーザー）
・Authyでトークンを生成
・パケット（自分用のデータを保存する場所）作成
・パケットポリシー設定（IAMユーザーからのアクセスのみ許可）

慣れないことで大変でした。
しかし、要素を分解してみると１つひとつは難しくありません。

AWSおよびS3。
この２つも使っていくうちに慣れていくと思います。
【Flutter】Google Play Console リリースレビュー警告対応

本記事では、Flutterで開発したアプリのリリースの際に、Google Play Console内で表示された以下の警告への対応方法を記載します。

## 発生した警告はこの4つ

```
4 件の警告
4 件のメッセージ（バージョン コード: 4）
警告
現在、お客様のアプリは API レベル 29 を対象にしています。セキュリティとパフォーマンスが最適化された最新の API を利用するには、API レベル 30 以上を対象にする必要があります。

2021 年 8 月以降、新しいアプリは Android 11（API レベル 30）以上を対象にする必要があります。
2021 年 11 月以降、アプリのアップデートは Android 11（API レベル 30）以上を対象にする必要があります。

警告
この APK では、使用されていないコードやリソースがユーザーに送信されます。Android App Bundle を使用すると、アプリのサイズを小さくすることができます。デバイスの設定に合わせてアプリを最適化しないと、ユーザーのデバイスにダウンロードしてインストールするアプリのサイズが必要以上に大きくなります。アプリは、サイズが大きくなるほどインストール成功率の低下を招き、ユーザーのデバイスのストレージを消費します。

警告
この APK に含まれている Java / Kotlin コードは難読化されている可能性があります。クラッシュや ANR を簡単に分析、デバッグできるよう、難読化解除ファイルをアップロードすることをおすすめします。詳細

警告
この APK にはネイティブ コードが含まれ、デバッグ シンボルがアップロードされていません。クラッシュや ANR を簡単に分析、デバッグできるよう、シンボル ファイルをアップロードすることをおすすめします。詳細

```

経験がないと、おそらく誰もが引っかかったことがある警告なのではないでしょうか。
また、Flutterで開発したアプリですが、Androidでも発生し得る警告かと思われます。

参考にしてみください。

## APIレベルバージョンアップに関する警告
**TargetSdkVersionを上げましょう。**

```java:buld.gradle(/app)

android {
    ・・・
    defaultConfig {
        ・・・
        targetSdkVersion 30
    }
}
```

## App Bundleに関する警告
従来の.apkファイルではなく、app Bundle（.aab）形式のアプリケーションファイルにすることで、アプリのサイズが抑えられるそうです。

僕はFlutter CIツールの**Codemagic**を使用しておりますのでそちらでのやり方を説明します。

▼Codemagicの設定まわりで参考になった記事はこちら。
[Practical guide: Flutter + Firebase + Codemagic (for Android)](https://blog.codemagic.io/practical-guide-flutter-firebase-codemagic-on-android/)
[FlutterでCI(Codemagic編)](https://qiita.com/kasa_le/items/c8d45dcfaad6989009ac#1build-triggers)
[【Mac不要】FlutterアプリにFirebase SDKを組み込んでiOSとAndroidに実機配備する手順 - Codemagic編](https://qiita.com/kami_teru/items/d3b72f5c0aa97e6c1c08)

.aabファイルを出力する方法は簡単で、下図の通り、Buildオプションの「Android build format」にて、「**Android app bundle(AAB)**」を選択して、普段通りbuildしてあげればOK。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699790/1d8dc3f1-e485-b6fb-a459-7b5a15318a11.png)

## 難読化に関する警告

**mapping.txtをアップロードしましょう。**

Codemagicだと、buildが成功したもののダウンロードボタンを押すと、mapping.txtがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699790/5b47a1b4-f872-bf1f-0c46-efab33d1d28f.png)

クリックすると、ダウンロードされずに中身が開かれるので、全コピして自分で新規作成したmapping.txtファイルに貼り付けます。

Play Consoleに戻って、アップロードしたAPP BundleまたはAPKファイルの右側に三点ドットが表示されているのでそれをクリックすると、下図のような項目が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699790/ac7caecc-5301-4df7-0944-acc6b81195b7.png)

マッピングファイルをアップロードをクリックして、ここからmapping.txtをアップロードすればOK。

## デバッグシンボルのアップロードに関する警告
こちらの記事が参考になりました。
[【Flutter】Android デバッグシンボルのアップロード](https://qiita.com/yoshiike/items/2c934e91a699259d9ac3)
ありがとうございます。
管理者権限なしでpython環境(パッケージも含む)の構築

#背景

　開発部署でない人だと管理者権限のない貸与PCを使っているケースがあるかと思います。
　（自分も一時期そうでした。）
　そうすると困るのがpython使いたいけどインストールできない問題です。
　調べるとインストール不要のembeddable pythonが見つかり、「これは！」と思うが
　今度は「pipできねーじゃんか！」と新たな問題に直面し、めんどくなると・・・

　なので、今回はこれの回避策を調べました。
　結論はプロキシが分かればpythonもpipも動きますので、やってみて貰えれば良いかと！
　正しい手法かどうかはよくわかりませんが、プロキシ調べる方法ものっけておきます。

***

#本題

　管理者権限のないPCでpython(パッケージ含)を動かせたので展開します。
　プロキシが必要な時は以下からブラウザ接続時のプロキシを探せば良いと思います。
　[internet explore]インターネットオプション -> 接続タグ -> LANの設定 -> 自動構成スクリプトのpacファイルの場所をコピー
　pacファイルの場所をieのアドレスバーに張り付けてダウンロード。
　テキストエディタでpacファイルを開いて、PROXYを調べる。
　大体こんなのがプロキシです。　"http://.....:8080"

##pip利用までの環境構築

```shell:embeddable-pythonのダウンロード
wget "https://www.python.org/ftp/python/3.9.6/python-3.9.6-embed-amd64.zip" -O "epython_zip.zip"
```

epython_zip.zipを任意のフォルダへ展開。
以降は展開したフォルダ内で実行。

```:get-pip.pyのダウンロード　※pip本体
wget "https://bootstrap.pypa.io/get-pip.py" -O "get-pip.py"
```
```epython/python39._pthファイルの変更
　変更前　#import site
　変更後　import site
```

```shell:get-pip.pyの実行
.\python.exe get-pip.py --proxy=<プロキシ>
```
以上で、pythonならびにpipの実行環境構築完了

***

##インストール例

パッケージをひとつづつインストールする場合

```shell:matplotlibのインストール
.\python.exe get-pip.py install matplotlib --proxy=<プロキシ>
```

***
※requirements.txtに必要なパッケージを一式書いてインストールする場合

```text:requirements.txt
opencv-python
selenium
lxml
PyQT5
Torch
torchvision
```

```shell:requirements.txtを用いたインストール
.\python.exe get-pip.py install -r requirements.txt --proxy=<プロキシ>
```
Nuitrackの公式ソフト動作させようとしたらエラーしたの解消

公式の動作確認フトで動作チェックしようとしたらエラーが出てできなかったので解消メモ

### Nuitrack

![_無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/a584e9b6-65c1-362f-4af6-47e88649aba1.png)


### 原因と解消方法

RealSenceのCubemos SDKをインストールしてたのが原因でした。。
NuitrackのSDKと競合するようです、PATH変えるか削除とありましたので、
削除したら動作できました。。

### 参考サイト

https://community.nuitrack.com/t/help-with-entry-point-not-found-dynamic-link-library-libcnn-hpe-dll-when-i-open-the-activation-tool/2279/15
vue-routerでページ遷移を毎回検知したい

方法は簡単で、`$route`をwatchしてあげれば良いらしい。

```vue
<template>
     <router-view></router-view>
</template>

<script>

export default {
  watch: {
    '$route': function (to, from) {
      if (to.path !== from.path) {
        
      }
    }
  }
};
</script>
```

`router-view`を使っているページに記述しておけば、ページ遷移毎に好きな処理を実行させることができる。

**もしこの方法がアンチパターンだよって方がいましたら、ぜひコメントしてくださいm(_ _)m**
【Shell】変数への格納と標準出力を同時に行う方法

## はじめに

以下のような変数への格納と標準出力を、同時に行う方法を調べてみました。

```shell
$ var=hello
$ echo $var
hello
```

## 結論

[`tee`コマンド](<https://en.wikipedia.org/wiki/Tee_(command)>)と、[端末`/dev/tty`](https://tldp.org/HOWTO/Text-Terminal-HOWTO-7.html#ss7.3)を使用します。

```shell
$ var=$(echo "hello" | tee /dev/tty)
hello
$ echo $var
hello
```

## 詳細

### tee

`tee`コマンドは、リダイレクトされた内容を、引数のファイルや変数にコピーするコマンドです。

```shell
# helloを hello.txt にコピー
$ echo  "hello" | tee hello.txt
hello
$ cat hello.txt
hello
```

`tee`(T)という名前は、このスキームに由来するそうです (下図が`T`のように見えることから)

> ![Tee](https://upload.wikimedia.org/wikipedia/commons/thumb/2/24/Tee.svg/400px-Tee.svg.png)

引用: <https://en.wikipedia.org/wiki/Tee_(command)>

### /dev/tty

`/dev/tty`は現在のプロセスの制御端末を指します。
そのため、`/dev/tty`になにかを入力すると、現在の端末に出力されます。

```shell
$ echo 1 > /dev/tty
1
```

この 2 つを合わせることで、変数への格納と標準出力を同時に行います。

```shell
$ echo "hello" | tee /dev/tty
hello # echo "hello" の出力結果
hello # tee で /dev/tty にコピーされ、現在の端末に出力されたもの
```

```shell
# echo "hello" の出力結果が、$var に格納される
$ var=$(echo "hello" | tee /dev/tty)
hello # tee で /dev/tty にコピーされ、現在の端末に出力されたものは、変化なし
```

## 参考

- [Text-Terminal-HOWTO: Terminal Special Files such as /dev/tty](https://tldp.org/HOWTO/Text-Terminal-HOWTO-7.html#ss7.3)
- [tee (command) - Wikipedia](<https://en.wikipedia.org/wiki/Tee_(command)>)
- [Man page of TTY](https://linuxjm.osdn.jp/html/LDP_man-pages/man4/tty.4.html)
- [unix - What is special about /dev/tty? - Stack Overflow](https://stackoverflow.com/questions/8514735/what-is-special-about-dev-tty)
- [bash - How to store the output of a command in a variable at the same time as printing the output? - Stack Overflow](https://stackoverflow.com/questions/37067895/how-to-store-the-output-of-a-command-in-a-variable-at-the-same-time-as-printing)
ng build時のCommonJS or AMD dependencies can cause optimization bailoutsの対処法

<h1>現象</h1>
npm installでモジュールを追加すると下記警告がビルド時に発生しました。

```
Warning: {tsファイル名} depends on '{nodeパッケージ名}'. CommonJS or AMD dependencies can cause optimization bailouts.
For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies
```


この警告を放置しておくと、ビルド成果物のサイズが不必要に大きくなってしまうようです。

<h1>対処法</h1>
angular.jsonの"build"→"options配下にallowedCommonJsDependenciesの設定を追加します。仮にnpmでhogeというパッケージがこの警告に引っ掛かっている場合は下記のような記述をします。

```angular.json
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "allowedCommonJsDependencies": [
              "hoge"
            ],
            ...


```
Gitの過去のcommit情報を一括変更し、GitHub上に草を生やす

#　はじめに
GitHub上に草が反映されなかった時に本記事を行った結果、草を反映することができましたので、その時の備忘録になります。

# 手順
①　過去のcommit情報を確認する
②　過去のcommit情報を一括変更する

# 過去のcommit情報を確認する
GitHubに草が生えなかった原因として、最初にGitに登録したユーザー情報が、GitHubのアカウント情報と一致していなかったことが挙げられる。
git log　コマンドを使って、過去のcommit履歴を確認する。

```
$ git log
Merge: bdsb28a 94891d5
Author: ユーザー名 <メールアドレス>
Date:   Sat Jun 26 11:50:52 2021 +0900
```

この時、ユーザー名とメールアドレスがGitHubのアカウント情報と一致していなかった場合、この部分を修正すれば、草を生やすことができる。

# 過去のcommit情報を一括変更する
一括変更するために下記のコードを打つ。

```
git filter-branch -f --env-filter "GIT_AUTHOR_NAME=GitHubのアカウント名; GIT_AUTHOR_EMAIL=GitHubのメールアドレス; GIT_COMMITTER_NAME=GitHubのアカウント名; GIT_COMMITTER_EMAIL=GitHubのメールアドレス;" HEAD
```
その後、変更されているか確認する

```
$ git log
Merge: bdsb28a 94891d5
Author: GitHubのアカウント名 <GitHubのメールアドレス>
Date:   Sat Jun 26 11:50:52 2021 +0900
```

変更できているのを確認し、GitHubにpushする

```
$ git push -f origin master
```

これでGitHub上に今まで反映されなかった草が生えました！
AppleWatch の Digital Crown を使ってみた

## 概要
AppleWatchのDigital Crownを使うアプリを作ってみようと思い
Digital Crownの機能を簡単に試してみた。

## ソースコード
```swift:ContentView.swift
import SwiftUI

struct ContentView: View {
    @State var crownValue = 0.0
    
    var body: some View {
        Text("Value: \(crownValue)")
            .focusable()
            .digitalCrownRotation($crownValue, from: 0.0, through: 1.0)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```

##解説

Digital Crownを回すと対応する値を画面に表示します。
表示項目にモディファイアとして
```. focusable()``` に続けて
```.digitalCrownRotation($crownValue)```
で値を取得できるようでした。

また
```.digitalCrownRotation($crownValue, from: 0.0, through: 1.0)```
とすることで Min/Max 値を設定できます。

が、この Min/Max 値はDigital Crownを動かすと、設定値を行きすぎて
オーバーシュート、アンダーシュートが発生します。
今回の例の場合も以下のようになりました。

![Simulator Screen Shot - Apple Watch Series 6 - 44mm - 2021-06-30 at 13.09.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481708/a12a5f10-da1a-65ee-bd27-02dd61c0f049.png)

![Simulator Screen Shot - Apple Watch Series 6 - 44mm - 2021-06-30 at 13.10.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481708/90ada2ef-cac1-f75f-16e4-2b899db5b648.png)

##感想
入力値を取り出すことは簡単でした。
オーバーシュート、アンダーシュートが発生するところには注意が必要かと思います。
WORKGROUP環境のServer Coreマシンに対してサーバーマネージャでアクセスする

# はじめに
AWSでWindowsを安く運用する方法を考えていたところ、Server Coreで起動すればメモリを最小限にできると気づきました。しかし、コマンドで操作するのも面倒臭いので、サーバーマネージャでリモート操作できないか探していたところ、Qiitaの以下の記事を見つけました。

https://qiita.com/tosier/items/b75b395d1f3a327cc88d

しかし、試したところ手元の環境ではうまく接続できなかったため、試行錯誤した結果をまとめました。

# クライアント側で必要な条件
WORKGROUP環境のServer Coreマシン(以下リモートサーバー)に対してサーバーマネージャでアクセスするには、クライアントマシンで以下の条件を満たす必要があるようです。

- リモートサーバーの名前解決
- TrustedHostsにリモートサーバーのホスト名を登録
- 資格情報マネージャーでパスワードを登録

## リモートサーバーの名前解決
今回の検証では、IPアドレスを指定してリモート管理を実施することができませんでした。サーバーマネージャでサーバーを追加する際に、IPアドレスで検索を実施できますが、逆引きしたホスト名（画像赤枠）に対してアクセスするような挙動となるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/c6115cce-038f-e17a-f64e-f7ab4552dd2e.png)
DNSサーバーを変更して名前解決ができない環境にしたところ、以下のメッセージが表示されました。「はい」を押して続行しましたが、アクセスが拒否されてしまいました。名前解決ができない環境ではhostファイルにIPアドレスとホスト名の対応を記載しておく必要があるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/f725e1ed-ffc3-a489-4da1-1140dffd6664.png)
ちなみに、ホスト名はリモートサーバーのコンピュータ名と一致する必要はないです。hostsファイルに適当な名前を記載して、後述の2条件をクリアしたら接続できました。

## TrustedHostsにリモートサーバーのホスト名を登録
Qiitaの記事にも記載のあったTrustedHostの設定については、サーバーの追加時に表示されるホスト名（画像赤枠）に対して設定する必要があります。設定が間違っている場合は、WinRMのネゴシエート認証エラーと表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/c6115cce-038f-e17a-f64e-f7ab4552dd2e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/b8fa98e7-0ca7-e016-ecd0-978596421c8f.png)

表示画像のマシン（TESTAD）をTrustedHostsに登録するには、以下のPowerShellコマンドを適用します。`TESTAD`の部分を任意のコンピュータ名に置き換えてください。

```
Enable-PSRemoting -SkipNetworkProfileCheck
Set-Item WSMan:\localhost\Client\TrustedHosts -Value 'TESTAD'
```

## 資格情報マネージャーでパスワードを登録
上記の設定に加えて、リモートサーバーのパスワードを事前に資格情報マネージャに登録しておく必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/abf4909d-8e3e-47f2-0d34-7220a4e21606.png)

# サーバー側の設定（ファイアウォールの無効化）
AWSにインスタンスを2台立てて検証した際は、ここまで設定した内容で接続ができましたが、AWSのインスタンスに対しVPN越しにWindows10から操作しようとした際は、サーバー側のファイアウォールが邪魔してアクセスできませんでした。そのため、リモートサーバー側で以下のPowerShellコマンドを実行し、ファイアウォールを無効化しています。

```
Get-NetFirewallProfile | Set-NetFirewallProfile -Enabled false
```
非エンジニア31+110人にアプリのログイン方法アンケート取ってみた

自分がある程度期間コミットしていて、集団属性がなんとなく分かってるところで雑にやったアンケートの結果を発表するの記事です🥳
文章と集団を変えて2回アンケートを取ったので31+110人としています。

なお「非エンジニア」といっても、対象集団が「エンジニア」という属性と関係がないというだけで、エンジニアが紛れ込んでる可能性は普通にあるのでそこはあしからず…

👇**ちなみにこの記事で紹介しているアプリを作成するにあたって参考に取ったものです**⚛️

https://qiita.com/herishiro/items/52162695d633d884f10f

# 【集団1】 わたくしのリア垢Twitter

エンジニアの友達はエンジニアが多い、ということは多いですが、私の場合趣味を通じて出会った人中心で、少なくとも把握する限り直接のフォロワーにプログラマーは幼なじみの1人だけです。
一応RTされてますけど、フォロワーもそもそも数十人なのでほぼFF内で完結してる気がします。

| 条件 |  |
|:-:|:-|
| 推定集団属性 |20〜50歳/女性が多いと推測される  |
| アプリ親和性 |ある程度携帯やSNS慣れしているオタクが多い |
| 質問 |**メモ・ログ系のアプリで**、ログイン時に選択肢が全て用意されている場合はどれで登録しますか？  |

【結果】

<img width="250"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304716/ab6bb9ee-d27f-5e83-03e8-b04aec0538da.jpeg">

| 方法 | 票数 |割合|
|:-:|:-:|:-:|
| 🔑 アドレス＆パスワード |　19票 | 　61% |
| 🔍 Google連携 |　6票 | 　19% |
| 🕊 Twitter連携 |　6票 | 　19% |
| その他連携(Facebookとか) |　0票 | 　0% |

これまたカスの統計で申し訳ないのですが、身近な人15人くらいにも同様の質問をしてやはり3人に2人はパスワード、残りはGoogle連携で、1人だけTwitter連携との回答でした。
（20代後半〜50代までのエンジニアを半分くらい含む知り合いへのアンケートです）

ちなみに上記のアンケートに続けて聞いた理由はこちら👀

【パスワードを選ぶ理由】
<img width="300"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304716/286cd120-618b-a5e0-2f7f-4e915f9b841d.jpeg">

【SNS連携を選ぶ理由】
<img width="300"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304716/c4b25ce2-4025-3be9-6323-22eb2831381b.jpeg">


# 【集団2】 大規模discordサーバー

日本人向けではかなり大きいとされているdiscordサーバーの質問チャンネルで聞いたら100人以上答えてくれました。
仕様的には複数回答もできるアンケートだということをご了承ください。
あと上のと違ってアプリの種類は指定していません（実際それによって変えるから選べないという意見もあった）

| 条件 |  |
|:-:|:-|
| 推定集団属性 |10〜40歳/以前他の人が調べたら女性比が結構高いらしい、投稿を見るにアクティブユーザーの大半は20前後の学生  |
| アプリ親和性 |サブカル・オタク寄り、テクノロジーの話が好きな人が多く、正直世間よりはエンジニア比も高そう |
| 質問 |（アプリの種類は指定せず）ログインが必要な時に、全部選択できるならいつもどれでしますか？  |


【結果】

<img width="400"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304716/b686a22e-1e9c-5092-7438-b30ff4c2dfab.jpeg">

| 方法 | 票数 |割合|
|:-:|:-:|:-:|
| 🔑 アドレス＆パスワード |　26票 | 　24% |
| 🔍 **Googleアカウント連携** |　**46票** | 　**42%** |
| 🕊 Twitter連携 |　33票 | 　30% |
| 📘 Facebook連携 |　1票 | 　1% |
| 🍎 appleアカウント連携 |　4票 | 　3% |
| 🐙 Github連携 |　0票 | 　0% |

アプリの種類を指定しなかった結果、もうみんなが使ってる信用のおけるアプリを想定した人が多かった可能性はありますが、
みなさん結構気軽にSNS連携しますね。
私の世代（30前後）だとなんかSNS連携って気持ち悪いと思ってる人それなりにいるんですが（特にTwitterは一時期アカウント連携からの乗っ取りが流行ったし）


# 所感

ハッキリ言ってカスの統計なので、あんまりここから分析とかする気はしないんですが、

**思った以上にFacebook人気ないなぁ！！**

とは思いましたね。

他の不人気はそもそも連携が用意されてないことも多いアカウントなのでわかるのですが。

先日読んでた「スマホ脳」という最新のスマホユーザー事情を掲載してる？本でも、
「個人間のチャットツールとして一番メジャーなのはFB messangerだが、若い層に限るとスナップチャットが一番人気」と書いてありましたし、FBが中高年用ツールになるつつあるというのはマジなのかもなと思いました。

とはいえ私は中高年層に限定してアンケートを取る術がないので単なる推測ですが。（FBアカウント無いし）

誰かFBでアンケートやってみて欲しいですね。

あとは若い子は思いの外Twitter連携を使う。
最初のアンケートを元に自分のアプリにはパスワードとGoogle連携の２種類をつけてるのですが、
Twitterにシェアする機能をつける予定もあるし、Twitter連携も付けとこっかな〜と今考えています。

...
一応アンケート取ったから発表しとこうか程度の記事でしたが、
お読みいただきありがとうございましたm(_ _)m

（※探す人いないと思いますが、関連ツイートは削除済みです）
これまでに投稿した記事

# 記事まとめ
- ベイズ
    - [PRML 10章 分解による近似](https://qiita.com/takahashi-ry/items/269058f83e1dcedc9776)
    - [PRML 10章 一変数ガウス分布の変分推論　変分事後分布のプロット](https://qiita.com/takahashi-ry/items/b432cc2cc426294169f4)
    
- 時系列分析
    - [単位根過程とトレンド定常過程の線形トレンドの違い](https://qiita.com/takahashi-ry/items/a50f9808866cc955c7b2)
    - [グレンジャー因果性の実装 計量時系列分析4.3 P81～P82](https://qiita.com/takahashi-ry/items/74f39dc7d2304135ab36#%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE)
    - [ゆるくJuliaで直交化インパルス応答関数の実装](https://qiita.com/takahashi-ry/items/c5ca0d4acab98c28425d)
    - [時系列データにまだ差分とっているの？](https://qiita.com/takahashi-ry/items/17a101f10a54831cd324)
    - [ボラティリティ変動モデルに入門🔰](https://qiita.com/takahashi-ry/items/f659288b2fa1903c6e61) NEW!!

- 線形代数
    - [最小二乗法の学びなおし](https://qiita.com/takahashi-ry/items/6bb46cdde473b63379ed)
    - [X'X の列ベクトルが一次独立ならば, X の列ベクトルが一次独立であることを示す](https://qiita.com/takahashi-ry/items/ed2d0b59e967112a6710)

- アルゴリズム
    - [今日から始める基本情報技術者試験のアルゴリズム問題](https://qiita.com/takahashi-ry/items/e5c77e7ba64f48d11640)
    - [今日から始める基本情報技術者試験のアルゴリズム問題～その2](https://qiita.com/takahashi-ry/items/3c5d0db9d43cdbd53bcc)

- Julia
    - [JuliaでPyCallを使うあなたへ～PyObjectってどうやって扱うねんっていう気持ちに対しての一考察～](https://qiita.com/takahashi-ry/items/3c247bb30fad12168c96)
    - [Juliaで自作のモジュールや関数をファイル単位で分割する方法
](https://qiita.com/takahashi-ry/items/ebade14f6ac251b54df8)
    - [巡回セールスマン問題をJuliaで解いてみた](https://qiita.com/takahashi-ry/items/4e03959a5ed2e0276430)　NEW!!

- PHP
    - [include_pathで外部モジュールを呼び出せるようにする *laradock環境*](https://qiita.com/takahashi-ry/items/688f9b29030c5e356d7a)
    - [【Laravel】CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP のせいでtimestampのカラムが勝手に更新されてしまう](https://qiita.com/takahashi-ry/items/5adf385c8c0628e20e70) NEW!!

## 弊社社員のQiitaのリンク
 
https://qiita.com/tetutaro

https://qiita.com/sasuke_sss

https://qiita.com/tf_okrt

https://qiita.com/saikoro2007

https://qiita.com/nakahara-d

https://qiita.com/otani-h

https://qiita.com/mttk030

https://qiita.com/zixuan
ゼロから始める機械学習 事前準備

# 最終目的

プログラミングを全くやったことがないという状態から，機械学習を行えるようになるまで，順に勉強する．


#事前準備の流れ

勉強会に参加するにあたり，サーバー環境が必要となる．
また，プログラミングを全くやったことがない人向けに資料の読み方などを記載する．

- 流れ : 
    - 資料の読み方
    - 開発環境の準備
    - サーバー環境をもらって最初にやること
    - 学習用データのダウンロード


# 資料の読み方

黒塗りの部分にはコマンドもしくは，プログラムが記載されている．
白文字で記載されているのがコマンド，着色された文字が含まれているのがプログラムである．
今回の勉強会では，プログラミング言語はPythonのみであるため，プログラムが記載されている場合は，Pythonで記述されている．
※ コマンド : Linux OSを操作するための手段．文字列を入力し，OSを操作する．
※ プログラム : コンピュータが実行する処理手順をプログラミング言語で記述したもの．

```
ここには，コマンドもしくは，プログラムの内容が記載されている．
```

コマンドの場合，'$'が先頭にある行は，一般のユーザーで実行するということ．
'#'が先頭にある行は，管理者権限を持つユーザーで実行するということ．
'$', '#'のどちらもない場合は，コマンドの実行結果が表示されているということ．
自分で実行する際は，先頭の'$','#'は含めずに実行する点に注意．

```
$ ls -la
# ls -la
```


プログラムが記載されている場合，'#'の後には，プログラムの内容などの人間が読むための，
コンピューターの命令ではない文字列を記載してある．
(実際にPythonでは'#'以降をコンピューターは認識しない)
残して置きたいプログラムの内容を記述するときにも使用する．
プログラムはそのままコピー&ペーストすることで動作するように記載している．

```.py
print("プリント") #プログラムのコメントが記載
#print("残しておきたい")
```




# 開発環境の準備

分かる人は，好きなように
分からない人は，下記リンクのように
作りたくない人は，作ってもらった環境で

https://qiita.com/t-baba-11/items/1aa80df8df27e30dac4e

https://qiita.com/t-baba-11/items/9d74710ce960b582dcd2

上記の環境を自分で作成できる人は，ここまで




# サーバー環境をもらって最初にやること


### 秘密鍵，公開鍵の作成

秘密鍵，公開鍵を作成し，サーバーにアクセスできるようにする(リンク先参照)

https://qiita.com/t-baba-11/items/2af338e63ac24570093e

### パスワードの変更

初期パスワードを変更する.
ターミナルでログインして，初期パスワードを入力し，
新しいパスワードを二度入力する．

```
$ passwd 
Current password:
新しいパスワード:
新しいパスワードを再入力してください:
```

#学習用データのダウンロード

下記のコンペに参加登録を行い，学習用データを自分のPCにダウンロードしておく．

https://www.nishika.com/competitions/16
[Rails] find_or_create_byメソッド

##はじめに
find_or_create_byメソッド
ゲストログイン機能を実装しようとした時に、便利なメソッドを見つけたので、記事で残しておこうと思います。

##find_or_create_byメソッド
使い方はモデルに対して使ってあげて、対応したテーブルから条件に該当するレコードを探してくれます。find_byと同じです。

もし、その時該当レコードを見つけることができなかった場合に、その条件のレコードを新規作成してくれます。

```ruby
モデル.find_or_create_by(条件）
```

例えば、ゲストログイン機能を実装する過程で、Userテーブルからゲストユーザーを引っ張り出す時に、条件にemailを指定してあげると、テーブルから該当するレコードを持ってきてくれます。

それだけなら、find_byメソッドで事足りるだろうと思うかもしれませんが、もし、ゲストユーザーが削除されていたりすると、find_byが機能しなくなります。

もしそのようなことが起きても、新規で作成してくれるのでfind_or_create_byメソッドを使っていれば、安心というわけです。

```ruby
user = User.find_or_create_by!(email: 'guest@example.com') do |user|
  user.password = SecureRandom.urlsafe_base64
```

2行目はパスワードをランダムに生成してくれる記述です。
もし名前や他の情報が必要であれば、その記述も必要です。
→ user.name = "ゲストユーザー" とか

##最後に
少し目に止まったメソッドはこれからも記事として残していきたいと思います。
もし、使い方がおかしかった場合、コメントにてお知らせいただけると幸いです。
トラブルシューティングに悩んだ時に確認したいこと

# はじめに
トラブルシューティングが苦手で、途中で投げ出してしまう方向けに記載しました。

- なぜ答えに全然たどり着かないのか
- なぜ途中で「本当に調べたかったこと」を忘れてしまうのか
- どうやって調べはじめたらいいのか

このあたりの気づきになれば幸いです。
また、「私はこうしています！」などの情報がありましたら、
いただけると今後の成長につなげられます。

# 急ぎの人向けのポイント要約
調べても調べても進まないときは下記を書き出して整理してみると良いと思います。
調べていない検索ワードのパターンや、試していない対処パターンの気づきが得られるかもしれません。
また、誰かに聞くときの材料にもなりますし、
自分が何を調べて何が分かったのかを振り返ることもできます。

慣れてくると書き出しも要らなくなってきます。
キーワードのチョイスも上手になってきてトラブルシューティングが早くなってきます。

- 目的 : 「何を解決したかったのか」
    - 例) javaのプログラムを書いたけどエラーが出て動かない
- キーワード : トラブル時にでてきたワード・エラーログそのまま など（慣れてない場合は多めになるかもしれません）
    - 例) IOException, java, java11, Eclipse, jdk...
- 調べたこと と その結果
    - 例) 「java IOException」で調べた結果、「java Platform SE8」のサイトがヒットして、入出力の例外であることが分かった

# 極端な2つのパターンの調べ方
## 1つのことをとにかく深堀して調べるパターン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165314/dfa93c97-46ec-334f-5b24-5c2e4c2a854c.png)

こちらのパターンでは、とにかく1つのことを徹底的に調べます。
「可能性1」について調べた後、出てきた分らない「用語1」「用語2」「用語3」について徹底的に調べ上げ、
完全に理解しようとします。

例）javaのプログラムを書いたけどエラーが出て動かない場合

1. 「IOException」というエラーログが見えたので、「IOException」について調べる
1.  「入出力例外」がよくわからないので調べる
1.  「割り込み シグナル」がよくわからないので調べる
1. ： 

この調べ方のメリット/デメリットは下記になります。
デメリットの★に陥ってしまったりすると、「よくわからない！」と、
あきらめて投げ出してしまうこともあるのかなと思います。

- メリット : 専門的な知識まで付けられる
    - 原理的なところまで理解しようとすることができる
    - 詳細に調べるので、深く理解したうえで判断ができるようになる
- デメリット : 正解にたどり着きづらい
    - 1個ずつ丁寧に調べるので、正解にたどり着くまでに時間がかかる
    - 深堀しているうちに「本当は何を調べたかったのか」を見失う★
    - 「完全に理解」できない言葉が多く、1つの可能性から抜け出せなくなることがある★

## 色々なことをとにかく幅広く調べるパターン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165314/bb6b6360-0b0a-2934-83f9-ac50cd82083b.png)

こちらのパターンでは、とにかく色々な検索・解決方法を試してみます。
よくわからないワードがあったとしても、特に深堀はしません。

例）javaのプログラムを書いたけどエラーが出て動かない場合

1. 「IOException」というエラーログが見えたので、「IOException」について調べる
1.  「エラー行」に「try～catch～」を書きましょうと出たので、見よう見まねで書いてみる
1.  「ファイルが作成されているか？」の確認を推奨されていたので、確認してみる
1.  「ファイルの権限が正しいか？」の確認が推奨されていたので、確認してみる
1. ： 

この調べ方のメリット/デメリットは下記になります。
今後につなげたいかや、置かれている状況によっては、
デメリットの★部分を気を付ける必要があると思います。

- メリット : 正解にたどり着くのが比較的に早い
    - 色々試すので、とりあえず目的を達成することができる
    - 本来の目的を見失い辛い
    - 1つの可能性にはまって抜けられないことがない
- デメリット : 正確な知識が得られず真の原因が何だったかを把握しづらい
    - 詳しく調べないので、「本当はこれが問題だったんだ」という知識を得られづらい★
    - 浅い知識のまま終わってしまう可能性がある
    - 色々試したりするので壊してはいけない状況や環境では危険★

## 結局どちらが良いの？
どちらかに偏り過ぎず、いい塩梅で組み合わせられるのが理想です。
自分が深堀タイプなのか、浅く広くタイプなのかを把握して、
上手く組み合わせられるように下記を意識すると良いと思っています。

- 「1つのことをとにかく深堀して調べるパターン」の方の意識ポイント
    - 本当の目的を忘れないようにしておく（書き出すなど）
    - 深堀は時間を見ながら行って、ある程度で切り上げてみる
    - 深堀したことは書き出すなどして整理しておく
- 「色々なことをとにかく幅広く調べるパターン」の方の意識ポイント
    - 調べた結果を鵜呑みにせず、自分の状況と照らし合わせて少しだけ詳細に調べてみる
    - 解決後時間があるときに、深堀して詳しい知識を獲得しておく

# まとめ
トラブルシューティングや課題解決の上手な人は、

1. 頭の中で、色々な可能性を考える
1. 頭の中で、持っている知識で最も可能性がありそうなもの順に並べる
1. 可能性の高いものから順に調べてみる
    1. 分らない言葉があれば少しだけ調べる
    1. あまり時間をかけず可能性が薄くなれば調査は切り上げる
1. 次の可能性を調査する
1. :

という形なのかなと思います。
慣れないうちは、
「可能性がありそうな順に並べ」たり、
「可能性が薄くなれば調査は切り上げ」たりできず深堀したり
することが多いのかと思っています。

慣れないうちは [冒頭の要約](#急ぎの人向けのポイント要約) のように、
書き出すなどの工夫をして

- 目的
- キーワード
- 調べたこと/調べた結果

を意識して、
深堀しすぎて堂々巡りにならないよう、
ほかの可能性に気づかないことのないよう、
本当の目的を忘れちゃわないよう、
気を付けると良いと思います。

# その他
トラブルシューティングのプロセスは、
木の探索アルゴリズム似ている気がしています。
知識がついてくると枝刈りも上手になるので、
解決策にたどり着くのも早いですね。
Swift UIColorでオリジナルカラーを定義する


## UIColorで新たに自分で定義した色を使うには？

structやclassで関数定義するやり方はあったけど記述が増えるの嫌だった！
元々定義されている.redや.blackみたいに簡潔に使いたかった

でもextension内で定数を定義するとエラー出る
staticつけたら解決しました！


```swift:定義
extension UIColor {

    static let myColor = UIColor(red: 116/255, green: 190/255, blue: 247/255, alpha: 1)

    //Extensions must not contain stored properties
    //let myColor = UIColor(red: 116/255, green: 190/255, blue: 247/255, alpha: 1) staticつけないと定義できない
}
```

```swift:使い方
    let text = UILabel()
    text.textColor = .myColor//元々定義されていた色みたいに使える!
```
Windows Powershell にて base64コマンドを実現する

##結論
以下の関数をpowershell profileに登録すると、あたかもLinuxのbase64コマンドのようになります

```powershell
function base64(){
    Param([switch]$encode=$true, [switch]$decode=$false, [Parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$input)
    Begin{}
    Process{
        if($decode){
            $byte = [System.Convert]::FromBase64String($input)
            $txt = [System.Text.Encoding]::Default.GetString($byte)
            echo $txt
        }
        elseif($encode){
            $byte = ([System.Text.Encoding]::Default).GetBytes($input)
            $b64enc = [Convert]::ToBase64String($byte)
            echo $b64enc
        }
    }
    End{}
}
```

###使い方

```powershell
# encodeオプションは省略可
echo "text here" | base64 -encode
# -> "dGV4dCBoZXJl"
echo "dGV4dCBoZXJl" | base64 -decode
# -> "text here"

# 複数の入力も可
echo "text here", "sample text" | base64 -encode
# -> "dGV4dCBoZXJl"
# -> "c2FtcGxlIHRleHQ="
echo "dGV4dCBoZXJl", "c2FtcGxlIHRleHQ=" | base64 -decode
# -> "text here"
# -> "sample text"
```


##イントロ
WebサービスでAPIを使用する際やKubernetesの設定などで、Base64でエンコードされた文字列をデコードしたい場面がちょくちょくあります
Linuxの場合、以下のようにパイプラインをつないで一発でデコードできるのですが、Windowsの場合これが一発でできないので非常に不便でした

```sh
echo "dGV4dCBoZXJl" | base64 --decode
```

そこでWindows Powershellのプロファイルに関数を作って疑似的に作ってやろうというのが今回の試みです
提供した関数ではオプションのハイフンの数が１個少ないので、**ハイフン１個の時は省略形というこだわりがある方は好みで引数名を変更してください**


##関数の解説
関数の名前が疑似的なコマンドとなるので、今回はbase64という名前の関数を作ります
###Process部分
エンコード、デコード機能としての肝となる部分は`Process`ブロック内にあります
decodeオプションがついていれば`if($decode)`内のブロックが、
encodeオプションがついていれば`elseif($encode)`内のブロックが実行されます
実行内容については以下のページのコードを用いています
[PowerShellでBase64のエンコードとデコード](https://win.just4fun.biz/?PowerShell/PowerShell%E3%81%A7Base64%E3%81%AE%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A8%E3%83%87%E3%82%B3%E3%83%BC%E3%83%89)

###Param部分
本来のbase64は `encode`,`decode`のオプションがあり、引数としてエンコード/デコードするテキストが入ります
今回これを疑似的に再現するにあたって、オプション含めてすべてpowershell関数の引数（パラメータ）として扱います

**具体的なオプションの扱い方**
powershellでは引数の型を指定でき、`[switch]`というのは`bool`型を意味します
powershellでこの`bool`型の引数をトリガーするには`-引数名`という形になるため、Linuxのオプションのような表記になります
つまり、`[switch]$encode=$true` はデフォルトで`true`の`encode`という名前の引数をとる、ということを定義しています

**パイプラインからの入力を受け取る引数の指定**
`[string]$input`だけを定義して終わってしまうと、実はパイプラインからの入力を引数として受け取らないという問題が発生します
そこで`[Parameter(ValueFromPipeline=$true)]`を追加することで、パイプラインからの入力を受け付けるようにします

あとは必須の引数であることを宣言するため、`Mandatory=$true`を追加しています

###複数の入力に対応
`Process`ブロックの中身がそのまま記載された関数を作ってしまうと、最初の１つのみがパイプラインからの入力として認識されてしまいます
`Begin`ブロック、`Process`ブロック、`End`ブロックの３つで構成することにより、パイプラインから複数の入力が受け取れるようになります
参考: [PowerShell: Creating Functions that accept Pipeline Input (ByValue)](https://sid-500.com/2020/03/24/powershell-creating-functions-that-accept-pipeline-input-byvalue/)
Draftsightのaddinつくった

この手の奴って、購入するときはAPIがどうとか歌ってる割には扱いが雑すぎて、実際やろうとするとよくわかんないのよね。さて、なんとなく一つ作ってみたのでご報告いたします。まーーーーほぼほぼhelpページの愚痴です[原文](http://help.solidworks.com/2021/English/api/draftsightapi/GettingStarted-draftsightapi.html)。

## 開発環境
VisualStudio 2019　(VC++,C#コンポーネントいれてます。)
Draftsight 2021
windows 10 


## 開発
draftsightインストールすると、サンプルプロジェクトが自動的にインストールされるのでそれをベースに開発を進めていく感じです。プロジェクトテンプレートはインストールされないし、パスの設定とかなんとか面倒そうなので。だれかGitHubにでも上げてくれないかな。

インストールパスにAPISDKというフォルダがあると思います。デフォルトのインストールパスは「C:\Program Files\Dassault Systemes\DraftSight」です。

サンプルプロジェクトは「APISDK\samples\」に入っていますので、dsSamples.slnを開いてやればビルドは通ると思います。(たぶんパスの設定がらみだと思うけど)個々のプロジェクトだけ開くとビルドできない。DLLがビルドされるのでこれをdraftsight側から読めるように設定ファイルを作ってあげればOKです。

ただ、これを「ProgramFiles」フォルダでやろうとすると管理者権限がどうとかって面倒なので、APISDKのフォルダをどこか適当なところにコピーしてそこをいじっていくのがいいと思います。

後は、英語のAPI眺めながら組んでいく感じです。


## デプロイ
windowsの場合はUser Account Control (UAC)の設定でちょっと違うらしいのですが、要は「addinConfigs」というフォルダを探して、そこに設定ファイルを新たに作って、今回作ったDLLのパスとuuidを入れてあげればいいみたい。僕はめんどくさがりなので、パスはビルド先「APISDK\samples\\C++\Simple\\[????]\Release\\[????].dll」に設定してます。UUIDは「dsAddinConnection.cpp」の関数HasSignedByDraftSightに記載されているのを設定します。

```ruby:someaddin.xml
<addinmanager>
    <draftsight version="">
        <addin name="[アドイン名]" startup="1" help="[tool tip????]">
            <button bitmap=""/>
            <cpp uuid="[UUID]" pathname="[DLLのフルパス]"/>
        </addin>
    </draftsight>
</addinmanager>
```

## うまくいくと
draftsightの「管理」>「addin」のリストに表示されると思います。今回は、穴位置の指示を相対座標で入れるためのツール作ってみました。そうそう、modelとsheetで扱いがかなり違っててsheet側に座標出すのが少し面倒だった。というか、この方法でいいのかよくわからん。細かいところは需要があれば書いていきます。
![DraftSight-Professional-_NONAME_0.dwg__-2021-06-28-14-13-59_Trim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201158/3c19e0ae-5970-1bdf-c5cd-b4a6d7600128.gif)


## さいごに
ほしい人いたら売ります。(気分次第で)作ってほしいものあったら作ります。怒られたら消します。