OmniAICreator/Qiita-1.07M huggingface dataset:
paizaラーニング解答: Dランクレベルアップメニュー[Ruby]

# Dランクレベルアップメニュー
https://paiza.jp/works/mondai/d_rank_level_up_problems/problem_index?language_uid=ruby

問題集にチャレンジする際の参考にお読みください。
シンプルなコードで答える方針です。
## STEP: 1 1 つの文字列を出力
```ruby
puts "paiza"
```


## STEP: 2 2 つの文字列を出力
```ruby
puts "paiza learning"
```


## STEP: 3 1 行の出力
```ruby
puts 813
```


## STEP: 4 3 行の出力
```ruby
puts 8
puts 1
puts 3
```


## FINAL問題 2 つの数値を出力
```ruby
puts "1 1"
```


## STEP: 1 足し算
```ruby
puts 1_231 + 5_178
```
_は無くてもOK。
## STEP: 2 割り算
```ruby
A = 437_326
B = 9_085
X = A / B
Y = A % B
puts "#{X} #{Y}"
```

## STEP: 3 累乗
```ruby
A = 202
B = 134
C = 107
puts ((A + B) * C) ** 2
# puts ((A + B) * C).pow(2) でもOK
```

## FINAL問題 代入演算 1
```ruby
N = 0
N += 3_286
N *= 4_736
N %= 12_312
puts N
```

## STEP: 1 1 行の入力
```ruby
s = gets.chomp
puts s
```
## STEP: 2 2 行の入力
```ruby
s = gets.chomp
t = gets.chomp
puts s
puts t
```

## STEP: 3 1 つの入力
```ruby
s = gets.chomp
puts s
```

## FINAL問題 半角スペース区切りの 2 つの入力
```ruby
s_1, s_2 = gets.chomp.split
puts s_1
puts s_2
```

## STEP: 1 入力された 2 つの文字列を出力
```ruby
S = gets.chomp
T = gets.chomp
puts S
puts T
```

## STEP: 2 引き算・掛け算
```ruby
A, B = gets.split.map(&:to_i)
D = A - B
P = A * B
puts "#{D} #{P}"
```
.map(&:to_i)でsplitで分けたAとBを整数にしています。
## STEP: 3 代入演算 2
```ruby
N = 0
A, B, C = gets.split.map(&:to_i)
N += A
N *= B
N %= C
puts N
```

## FINAL問題 乗客人数
```ruby
a, b, c = gets.split.map(&:to_i)
puts a - b + c
```

## STEP: 1 単純な条件分岐
```ruby
s = gets.chomp
if s == "paiza"
    puts "YES"
else
    puts "NO"
end
```

## STEP: 2 数値の分岐
```ruby
N = gets.to_i
if N <= 100
    puts "YES"
else
    puts "NO"
end
```

## STEP: 3 数値演算結果で分岐
```ruby
A, B, C = gets.split.map(&:to_i)
if A * B <= C
    puts "YES"
else
    puts "NO"
end
```

## FINAL問題 占い
```ruby
n = gets.to_i
if n == 7
    puts "Yes"
else
    puts "No"
end
```

## STEP: 1 ある数字までの出力 2
```ruby
N = gets.to_i
(1..N).each do |i|
    puts i
end
```
forループ等でもOK。
## FINAL問題 FizzBuzz
```ruby
(1..100).each do |i|
    if i % 15 == 0
        puts "FizzBuzz"
    elsif i % 3 == 0
        puts "Fizz"
    elsif i % 5 == 0
        puts "Buzz"
    else
        puts i
    end
    
end
```
FizzBuzz問題の解き方はpaizaラーニングの講座で詳しく取り上げられています↓

https://paiza.jp/works/algorithm/primer/algorithm1
【Firebase】firebase deployでエラーが出る

Cloud Functions for Firebaseを使おうとした際にエラーが発生したので、解決策をまとめておきます。同じように困っている人が検索に引っ掛かればいいなと思って書きます。

## 結論
#### 入力（コマンド）
```sh
firebase deploy
```


#### 出力（エラー）
```sh
i  deploying firestore, functions
Running command: npm --prefix "$RESOURCE_DIR" run lint

> lint
> eslint .


/Users/nakamura/flutterInVscode/kanon_app/functions/index.js
  10:8  error  'onRequest' is assigned a value but never used  no-unused-vars
  11:7  error  'logger' is assigned a value but never used     no-unused-vars

✖ 2 problems (2 errors, 0 warnings)


Error: functions predeploy error: Command terminated with non-zero exit code 1
```

#### 解決方法
your_app_name/functions/index.jsの以下のコードを、コメントアウト解除する。


```js
exports.helloWorld = onRequest((request, response) => {
  logger.info("Hello logs!", {structuredData: true});
  response.send("Hello from Firebase!");
});
```


###### 修正後のコード
```js:index.js
/**
 * Import function triggers from their respective submodules:
 *
 * const {onCall} = require("firebase-functions/v2/https");
 * const {onDocumentWritten} = require("firebase-functions/v2/firestore");
 *
 * See a full list of supported triggers at https://firebase.google.com/docs/functions
 */

const {onRequest} = require("firebase-functions/v2/https");
const logger = require("firebase-functions/logger");

// Create and deploy your first functions



// https://firebase.google.com/docs/functions/get-started

exports.helloWorld = onRequest((request, response) => {
  logger.info("Hello logs!", {structuredData: true});
  response.send("Hello from Firebase!");
});

```

## 前提


- node v18.19.0
- macOS Monterey 12.3 M1



以下の記事に沿ってコマンドを入力しました。

https://firebase.google.com/docs/functions/get-started?hl=ja&gen=2nd
###### 実行したコマンド一覧

```sh 
npm install firebase-functions@latest firebase-admin@latest --save
npm install -g firebase-tools
firebase login
firebase init firestore
firebase init functions 
```

## 途中で発生した別のエラー
#### 入力（コマンド）
```sh
npm install -g firebase-tools
```
#### 出力（エラー）
```sh
npm ERR! Error: EACCES
```
（解決したのでエラー全文はどっか行きました...）

#### 解決方法
以下の記事に沿って、npmを再インストールする。

https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally


自分の場合は、以下のコマンドを入力するとエラーが消えました。
nodeのバージョンを、21から18にする必要があったらしい。



```sh
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
nvm ls-remote
nvm install 18.19.0 
nvm use 18.19.0
```


## おわり
読んでいただきありがとうございました。エラー文を読めばすぐ解決できるであろうくそみたいなエラーですが、自分はめちゃくちゃ手こずってしまいました。

同じようにインストールで詰まっている人の助けになれば幸いです！
【Python】再帰でフラクタルを描く①（フラクタルツリー）


## 事前準備

本記事はProcessingを使って，フラクタルの画像を生成しています．なので，Processingのインストールが済んでいない方はインストールを行なってください．
Processingのインストールの手順について記事を書いたのでよければそちらからどうぞ．

https://qiita.com/PRESENT_Science/items/122c43697bcb5f23a181

## フラクタルツリーを描いてみよう

以下のソースコードをProcessingで実行してみてください．

```python
def setup():
    size(600, 600) #ディスプレイウィンドウのサイズを指定
    
def draw():
    background(255) #背景色（255は白）
    translate(300, 500)
    level = int(map(mouseX, 0, width,  0, 15)) #枝分かれのレベル
    y(100, level)
    
def y(sz,level):
    if level > 0:
        line(0, 0, 0, -sz)
        translate(0, -sz)
        angle = map(mouseY, 0, height, 0, 180) #枝分かれの角度
        rotate(radians(angle))
        y(0.8 * sz, level - 1)
        rotate(radians(-2 * angle))
        y(0.8 * sz, level - 1)
        rotate(radians(angle))
        translate(0, sz)
```

![スクリーンショット 2024-01-10 20.01.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664417/c1bad76a-d605-e8ca-33f2-b67f0d5fde26.png)

マウスを上下左右に動かすことによって，ツリーの形が変化すると思います．

## 詳しい解説

### translate 関数 ： ディスプレイウィンドウの中心座標を変える

例 ： `translate(30,20)`で$x$軸方向に30，$y$軸方向に20移動します．

### rotate 関数 ： ディスプレイウィンドウを回転させる

例 ： `rotate(radians(30))`で30°回転します．角度は`rotate(PI/6)`などと弧度法で指定することもできます．

### line 関数 ： 直線を引く

例 ： `line(20, 30, 80, 70)`で`点(20,30)`と`点(80,70)`を結ぶ直線を描くことができます．

## 参考文献

- [Peter Farrell．Pythonではじめる数学の冒険（鈴木幸敏訳）．O'Reilly Japan，2020．](https://www.oreilly.co.jp/books/9784873119304/)
管理者不在な AWS Cloud9 環境への権限付与を依頼されたら

# はじめに
皆さんの会社で AWS Cloud9 は活用されていますでしょうか。
弊社でも幾つかのシステムで AWS Cloud9 を開発環境として採用しています。
便利ですよね。AWS Cloud9。

ところで、そんな中に **管理者不在の AWS Cloud9 環境** は存在していないでしょうか。
ここでいう管理者不在とは…

- 環境を作った人が既に退職している :scream:
- 環境を作った人が休職中ですぐに連絡がつかない:cold_sweat:
- 環境を作ったIAMユーザを削除してしまった :ghost:

といった開発環境の事を指しています。


今回はそんな AWS Cloud9 に対して権限を付与して欲しいと依頼され、
少し困った際の対応方法について記載していきます。


# 管理者不在の AWS Cloud9 環境とは
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1734719/f5ef0481-908d-8ac7-9894-53b01bacd058.png)


AWS Cloud9 は通常、環境の所有者から共有されない限りアクセス権が付与されません。
（上記図のように共有されていない環境は「アクセスなし」となります。）

そんな環境に後からアクセス権を付与する方法を記載します。


# どうすればよいか
## 前提条件
アクセス権付与の前提条件として以下2つが必要になります。

- 作業者が対象アカウント上で AWS CloudShell の利用権限を持つ事
- 作業者が AWS Cloud9 に対する Admin 権限を持つ事


## 実施コマンド
権限付与自体は AWS CloudShell から コマンドを通じて実施可能です。
```
aws cloud9 create-environment-membership --environment-id <環境ID> --user-arn <UserARN> --permissions <Permission> 
```

環境IDは付与したい環境の画面から確認できます。
環境が実行されているEC2インスタンスのARN末尾にある `environment: xxxxxxx` の `xxxxxxx` 部分が環境IDになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1734719/46f778af-8779-bb3e-74d0-09a45c07003e.png)



UserARNは権限を付与したいIAMユーザのARNを調べて入力してください。
Permission は `read-write` または `read-only` と入力してください。 


# もし権限付与対象者がSAML連携ログインだった場合

権限付与する人がIAMユーザでログインしている場合は上記手順で権限付与出来ます。
しかし、権限付与対象者がADFSとSAML連携している場合はコマンドが少し変わります。

```
aws cloud9 create-environment-membership --environment-id <環境ID> --user-arn arn:aws:sts::<アカウントID>:assumed-role/<RoleName>/<UserMailAddress> --permissions <Permission> 
```

上記の様に、`<UserArn>` の部分を `ADFS経由でログインしているユーザの利用するRole` ＋ `ユーザのメールアドレス`
の形式で指定して権限を付与する形になります。



# 最後に
開発環境は得てして乱立し、管理者不在な状況になりがちかと思います。
そんな環境に権限付与が必要な事態に出くわした方の力になれれば幸いです。

最後に、環境の所有者であるユーザーアカウントを削除してしまった場合の詳細や、具体的に必要な権限が記載されていますので、こちらも是非参考にしてみてください。

https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/security-iam.html#how-cloud9-with-iam



# :bamboo:  弊社では一緒に働く仲間を募集中です :bamboo:
現在、様々な職種を募集しております。
カジュアル面談も可能ですので、ご連絡お待ちしております！

募集内容等詳細は、是非採用サイトをご確認ください。
https://engineer.po-holdings.co.jp/
Ubuntu 上の LibreOffice を PPA 最新版に


「Ubuntu 上の LibreOffice で TexMaths を使ってみる」
https://qiita.com/nanbuwks/items/940795b027593f96b881

では Ubuntu上のLibreOfficeのバージョンが低くて最新のTexMathsで問題が起こってました。

記事中では TexMaths のバージョンを落としましたが、ここでは Ubuntuパッケージより新しい LibreOffice を導入してみます。

# 環境
- Ubuntu Linux 22.04 
- 
Version: 7.6.4.1 (X86_64) / LibreOffice Community
Build ID: 60(Build:1)
CPU threads: 4; OS: Linux 6.2; UI render: default; VCL: gtk3
Locale: ja-JP (ja_JP.UTF-8); UI: ja-JP
Ubuntu package version: 4:7.6.4-0ubuntu0.22.04.1~lo1
Calc: threaded

事前に以下の作業でディストリビューション版のLibreOfficeを削除しています。
「Ubuntu パッケージ版の LibreOffice を削除する」
https://qiita.com/nanbuwks/items/baa3afe0761cd8f19895

# インストール方法

ここに方法がありますが、記述が少し古いです。
https://wiki.ubuntu.com/LibreOffice

以下のようなエラーが出るのでこの手順は飛ばしました。
```
$ sudo apt install python-software-properties
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています... 完了        
状態情報を読み取っています... 完了        
パッケージ python-software-properties は使用できませんが、別のパッケージから参照されます。
これは、パッケージが欠落しているか、廃止されたか、または別のソース
からのみ利用可能であることを意味します。
しかし、以下のパッケージが置き換えます:
  software-properties-common

E: パッケージ 'python-software-properties' にはインストール候補がありません
```


```
$ sudo apt-add-repository ppa:libreoffice/ppa
$ sudo apt update
$ sudo apt install libreoffice
```
インストールできました。

# 問題点

ヘルプを開こうとすると、以下のエラーが出ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/8829b6b6-c5b0-854d-528f-88199a37e587.png)

ヘルプは使わないのでそのまま使っています。
ライブラリインストール時nuxt prepareが失敗した時の対処

# 困っていたこと

`nuxt.config.ts`に下記のようにライブラリのインポートが記述してあると、`npm install`や`npm ci`でエラーになってしまう。

```typescript:nuxt.config.ts
import axios from 'axios'

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  devtools: { enabled: true },
```

エラーメッセージは以下。

```bash
$ npm ci
> postinstall
> nuxt prepare

Error:  connect ECONNREFUSED ::1:80
  at AxiosError.from (node_modules/axios/dist/node/axios.cjs:837:14)
  at RedirectableRequest.handleRequestError (node_modules/axios/dist/node/axios.cjs:3090:25)
  at RedirectableRequest.emit (node:events:517:28)
  at eventHandlers.<computed> (node_modules/follow-redirects/index.js:37:24)
  at ClientRequest.emit (node:events:517:28)
  at Socket.socketErrorListener (node:_http_client:501:9)
  at Socket.emit (node:events:517:28)
  at emitErrorNT (node:internal/streams/destroy:151:8)
  at emitErrorCloseNT (node:internal/streams/destroy:116:3)
  at process.processTicksAndRejections (node:internal/process/task_queues:82:21) 
```

# 解決策
原因はインストール完了後に走る`nuxt prepare`のようなのでこれを抑制した。

https://nuxt.com/docs/api/commands/prepare

方法は`--ignore-scripts`オプションを`npm install`や`npm ci`につけるだけ。
ただし、暫定っぽい対策な気はする。

# 参考

https://nju33.com/notes/yarn/articles/yarn%20install%20%E6%99%82%E3%81%AB%E3%83%95%E3%83%83%E3%82%AF%E9%96%A2%E6%95%B0%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%97%E3%81%AA%E3%81%84%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B#yarn_install_%E6%99%82%E3%81%AB%E3%83%95%E3%83%83%E3%82%AF%E9%96%A2%E6%95%B0%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%97%E3%81%AA%E3%81%84%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B
Playwrightのコード生成機能がすごい

## 概要

今回は、Playwrightのコード生成機能についてご紹介します。

## 前回の記事

前回の記事では、Playwright の紹介と簡単なコード実行をしています。
こちらを前提に進めていきます。

https://qiita.com/labeneko/items/a34eb67ad5dcaae94ef5

## コード生成機能

Playwrightを使ってのスクレイピングは、ログインが必要なページなど、一筋縄ではいかないページでもやりたい場合があると思います。

そういうときに、いちいち要素を調べてプログラミングしていては大変です。
Playwrightには、便利なコード生成機能があり、こういう時非常に役立ちます。

例えば、ニコニコの自分のアカウントのフォロー数とフォロワー数を取ってみましょう。（他にいいものが思いつかなかった汗）

コード生成機能は、

```
$ npx playwright codegen https://www.nicovideo.jp/
```

という形で、スクレイピングしたいページのURLを指定します。

そうするとブラウザが開きますので、実際にログイン処理を行い、欲しい要素のページまで遷移します。
そうすると、実際の操作がコードになって表示されます。

![スクリーンショット 2024-01-10 19.40.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61162/58679213-5380-d468-c178-378a0a5aaaa7.png)

このコードを基に、プログラムを書いていきます。
（ほとんどはそのまま使えるので、カスタマイズしていく感じです。）

コードを参考に書いたプログラムは以下の通りです。

```niconico.js
const playwright = require('playwright');

(async () => {
    const browser = await playwright.chromium.launch();
    const context = await browser.newContext();
    const page = await context.newPage();
    await page.goto('https://www.nicovideo.jp/');
    await page.getByRole('link', { name: 'ログイン' }).click();
    await page.locator('#input__mailtel').click();
    await page.locator('#input__mailtel').fill('xxxxxxx@xxxxxxx');
    await page.locator('#input__password').click();
    await page.locator('#input__password').fill('xxxxxxxxx');
    await page.getByRole('button', { name: 'ログイン' }).click();
    await page.goto('https://www.nicovideo.jp/my');
    await page.screenshot({ path: 'screenshot.png', fullPage: true });
    const follow = await page.getByRole('link', { name: 'フォロー中' }).innerText();
    console.log(follow)
    const follower = await page.getByRole('link', { name: 'フォロワー' }).innerText();
    console.log(follower)
    await browser.close();
})();
```

プログラミングしていて、途中で合ってるか不安になってきたら、スクリーンショットを簡単に取ることができます。

上のプログラミングの

```
await page.screenshot({ path: 'screenshot.png', fullPage: true });
```

の部分です。

こんな感じでスクリーンショットが取れます。

![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61162/a35718af-ae41-d63b-8020-595e988d8605.png)

便利ですね。

実行してみると、フォロー数、フォロワー数が取れていることが分かります。

```
$ node niconico.js 
フォロー中
8
フォロワー
4
```

後は取得できたデータを基に色々処理をしていくという形になります。

プログラムは、Githubに公開しています。
参考にしてみてください。

https://github.com/labeneko/playwright_test
認証(Authentication)と認可(Authorization)の違い

## はじめに
フォームリクエストのauthorizeメソッドには「認可」の処理を実装します。

ただ、「認証」と何が違うのでしょうか？

Laravelの公式ドキュメントには、「認証」と「認可」をごちゃ混ぜにしないようにと注意書きがあります。

> ガードとプロバイダを「役割」や「許可」と混同しないでください。権限を介したユーザーアクションの認可の詳細については、認可のドキュメントを参照してください。（「Laravel 8.x 認証」より）

https://readouble.com/laravel/8.x/ja/authentication.html





## 認証(Authentication)とは
* 認証(Authentication)とは、**ユーザーが誰であるかを確認するプロセス**です

例えば、多くのアプリケーションにおいて、ユーザーがログインする時には登録したユーザー名とパスワードを入力します。

これらの情報が正しい（データベースに保存されている情報と一致する）時、

ユーザーは「**認証**」され、システムにアクセスできますね。

実際のLaravelプロジェクトでの例も見てみます。

```php: SalesOrdersController.php
<?php

// 中略

public function create()
{
    $user = Auth::user(); // ココが認証部分

    return view('sales.create', [
        'user' => $user,
    ]);
}

?>
```

上記のコードのcreateメソッドでは、Auth::user()を使用して、現在認証されているユーザ（ログインユーザ）を取得しています。

これは認証の一例だと言えるでしょう。


## 認可(Authorization)とは
* 認可(Authorization)とは、**認証されたユーザが特定のリソースにアクセスしたり、**
* **特定のアクションを実行したりできるかをどうかを決定する**プロセスです

例えば、特定のユーザーが特定のウェブページを表示したり、データを編集したりできるかどうかを制御します。

こちらも具体的な実装例で見てみます。

```php: SalesOrdersController.php
<?php

public function destroy($id) 
{
    $sales_order = SalesOrder::findOrFail($id);

    if (Auth::id() === $sales_order->user_id) // ココが認可部分 {
            $sales_order->delete();
            return back()
                ->with('発注は削除されました');
        }

    return back()
        ->with('削除に失敗しました');
```

上記のコードのdestroyメソッドでは、特定のSalesOrder（発注）を削除しますが、

この削除操作は通常、そのSalesOrderの所有者もしくは管理者のみが実行できるはずです。

でなければ、悪意あるユーザが不正に発注を削除してしまう可能性があります。

そこで「認可」の出番です。

```php: 
if (Auth::id() === $sales_order->user_id)
```

ここでは認可として、「$sales_orderに紐づいたユーザidが、現在認証されているユーザのユーザidと同じか否か」をチェックしています。

このチェックがtrueを返す場合、つまり認証されたユーザがSalesOrderの所有者である場合、

そのユーザはSalesOrderに対する特定のアクション（この場合は削除）を実行できます。

これは認可の一例です。

## まとめ

### 認証(Authentication)
* ユーザが本当にユーザ自身であるかを確認するプロセス
* 例: システムへのログイン

### 認可(Authorization)
* 認証されたユーザが特定のアクションを実行したりすることを許可するプロセス
* 例: 特定のユーザが特定のデータを編集・削除する権限の有無

### 超ざっくり日常レベルに落とし込むと…

ネットフリックスにおいて、全ユーザはログインを求められます（認証）。

そして、スタンダードプランのユーザとプレミアムプランのユーザで、得られる恩恵は変わるはずです（認可）。


## 参考
https://readouble.com/laravel/8.x/ja/authentication.html

https://readouble.com/laravel/8.x/ja/authorization.html
No certificates were found that met all the given criteria. のエラーの解決方法について

## 解決方法

Visual Studio を管理者として実行してみてください。

## 事象の詳細

ドライバーを Visual Studio から実装する際、通常の権限で Visual Studio を開いてビルドをすると、No certificates were found that met all the given criteria. のエラーが発生することがあります。

これは、証明書を読み込むための必要なアクセス権限が足りないからと推測されます。

結構調べたりしていたのですが、解決方法が検索しても出てこなかったため、メモ書きとして残しておきます。

## まとめ

Visual Studio でビルドエラーが起きるときは、切り分けとして管理者権限で実行することを試してみるのが良いと思います。
【Blender】レーザー光作成RTA

# はじめに

こんにちは。
ジョジョ好きなXRクリエイターの [もふるね](https://twitter.com/mofurune_k) です。

ゲーム[Portal](https://store.steampowered.com/app/400/Portal/?l=japanese)のタレットちゃんを作りたいなぁ～
目線のレーザー光作らなきゃな～
作ろ


# 結果

<img width="600" alt="rather06.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518924/6b4c4eb2-cf61-7bdf-9cae-6f24c38c09dd.jpeg">

<iframe width="560" height="400" src="https://www.youtube.com/embed/ty_9R1STdpg?si=h_olwcys9OFtHx2D" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>


# 参考資料

https://www.youtube.com/watch?v=4HhavlMLV6k


# レーザー光の3Dモデル

レーザー光作成RTAは～じま～るよ～
はい、よーいスタート。

まずはBlenderを起動。
そして堂々たる態度で鎮座しているCubeを消します。

[Shift + A] > [メッシュ] > [円柱] を出現させます。
``Shift + A``はオブジェクト追加のショートカットキーなので、これで時間の短縮を図ります。


円柱を選択した状態で [S] > [Shift + Z] で円柱を細くなるように縮小します。
Sの後に``Shift + Z``を押すとZ方向は変化せず、XY方向だけ拡大縮小できます。

<img width="600" alt="rather01.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518924/61a5c9fb-8f66-3d40-ba0a-04973a63acfa.jpeg">


# シーン

シーンの「ブルーム」にチェックを付けます。
これは発光したときに周りにぼんやりとした光が出ます。
簡単にエモを演出できるのでおすすめです。

<img width="400" alt="rather02.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518924/2b044c66-4c45-e306-5e08-f9620c6263f4.jpeg">


# マテリアル

円柱のマテリアルを作成します。
サーフェスが「プリンシプルBSDF」となっていることを確認します。

放射が黒になってるので、白にして、自分の好きな色にします。

<img width="400" alt="rather03.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518924/b11d1732-16a8-4524-2e48-42ba8e66b2cc.jpeg">

放射の強さをクリックしたまま右に思いっきり動かします。
動かした分だけ光ります。

（放射の強さ：1 のとき）

<img width="400" alt="rather04.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518924/96e82c0f-de13-746f-9010-0188bb83ac3b.jpeg">

（放射の強さ：124.2 のとき）

<img width="400" alt="rather05.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518924/bbceec4d-1d59-9764-c9d3-780620da48c4.jpeg">

次に、透明感を出していきます。
[サーフェス] > [アルファ] を「0.05」
[設定] > [ブレンドモード] を「アルファブレンド」
にします。

アルファは0に近いほど透明になります。
（透明なのが分かりやすいように参考画像にはCubeを置いてます。）

<img width="600" alt="rather06.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518924/6b4c4eb2-cf61-7bdf-9cae-6f24c38c09dd.jpeg">


# 振り返り

これにてレーザー光作成RTA終了です。
記録は・・・59.50秒
1分切りを果たしました！
完走した感想は、良いタイムでしたが所々ガバがあったので、もっと詰めることができたと思います。
また、もっと良いチャートがあるかもしれません。
新たなるRTA走者の挑戦、お待ちしています。

それではみなさん、またお会いしましょう。
HTMLとCSSについて説明できる

# 1. HTMLとはなにか

HTMLはWebページを制作するための基本的なプログラミング言語の一つです。HTMLは、テキストベースの文書を構造化し、その文書に含まれる要素やコンテンツに意味を与えるためのマークアップ言語です。
# 2.CSSとはなにか
CSSは、Webページやウェブアプリケーションの見た目やスタイルを定義するためのスタイルシート言語です。HTMLが文書の構造を定義するのに対して、CSSはその文書のデザインやレイアウトを指定します。HTMLとCSSを組み合わせることで、魅力的で整然としたWebページを作成することができます。

# 3.HTML Living Standard
HTML Living Standard は、HTMLの仕様書の最新版であり、HTMLの標準使用を定義している文書です。これは、HTMLの進化についての指針や標準を提供するものであり、セブ開発者やブラウザメーカーが一貫した方法でHTMLを解釈・実装できるようにするためのドキュメントです。<br>
HTML Living Standardは、HTMLの進化に合わせて追加・改訂されるため、ウェブ開発者は最新の情報を確認するために定期的に参照することが推奨されます。
M5 DMX Baseでムービングライトを制御する

## はじめに

M5StackのM5 DMX Baseを手に入れたのでムービングライトを制御してみようと思います。DMXコネクタには3ピンと5ピンがありますが、付け替えができるようです。

https://www.switch-science.com/products/8961


## DMXとは

ライブや舞台などで広く利用される照明や演出機材の制御に特化した通信プロトコルです。
1本のケーブルで512チャンネルまでのデジタル信号の送受信ができ、256段階で制御できます。それぞれの機材はデイジーチェーン(数珠繋ぎ)で接続することができ同時に制御可能です。



## 構成

+ ムービングライト
+ M5Stack Core
+ [ジョイスティックユニット](https://www.switch-science.com/products/8101)
+ XLRケーブル


## 実装

プログラムはUIFlowで組んでみることにします。
ムービングライトは９チャンネルと14チャンネルが選べるようになっていました。今回は９チャンネルにすることにしたので、以下の内容です。

+ Channel 1 : X Axis
+ Channel 2 : Y Axis
+ Channel 3 : Light Pattern
+ Channel 4 : R LED
+ Channel 5 : G LED
+ Channel 6 : B LED
+ Channel 7 : W LED
+ Channel 8 : Speed
+ Channel 9 : Reset


このように組んでみました。
M5Stack Coreのボタンはそれぞれ赤、緑、青の3色、ジョイスティックはライトの向きに対応しています。
DMX write byteの後にwaitを入れないと入力が正しく反映されないことがあり、うまく動作しなかったので毎回入れています。 

![dmx_uiflow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3166965/228e83ba-e7fd-6271-483d-f1afa507cd03.png)


### 動画

<iframe width="560" height="315" src="https://www.youtube.com/embed/-HD_mxke5Vc?si=H8qNtxOUynWzEqog" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

少し動きが反映されるまでのラグが気になるところですが、手軽に操作できるのはいいですね。
[QLC+](https://www.qlcplus.org/)から試したところ、遅延なく動いたのでライト側の問題ではなさそうです。



## おまけ

少しコードを変更してデイジーチェーン(数珠繋ぎ)にも対応してみました。

<iframe width="331" height="588" src="https://www.youtube.com/embed/APk0SgJMG8k" title="test M5 dmx Base 2" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
nkfコマンドで文字コードや改行コードを変換する

# nkfコマンドとは

「nkf」は「Network Kanji Filter」の略で、LinuxとWindowsなど、異なるOS間でテキストデータを交換する際に問題となる文字コードと改行コードを変換するためのコマンド

オプションを指定することで、任意の文字コード、改行コードに変換することが出来ます。
オプション指定をしないで実行すると文字コードを「JIS」に変換します。
＊改行コードは変換されません。
```terminal:構文
nkf [オプション] [ファイル]
nkf [オプション] --overwrite ファイル(省略可)
```

# オプション

### 文字コード関係
|オプション|説明|
|-|-|
|-j|JISコードを出力する|
|-e|EUCコードを出力する|
|-s|Shift_JISコードを出力する|
|-w|UTF-8コードを出力する|
|-- overwrite|ファイルを変換して上書きする|
|-- guess|使用されている文字コードと改行コードの判定結果を表示|

### 改行コード関係
|オプション|説明|
|-|-|
|-d|改行をLFにする(UNIX系)|
|-c|改行をCRLFにする(Windows系)|
|-Lm|改行をCRにする(OS Xより前のmac OS系)|

### 半角/全角関係
|オプション|説明|
|-|-|
|-X|	半角カナ（JIS X 0201 片仮名）を全角カナ（JIS X 0208 片仮名）へ変換する|
|-x|	半角カナを保存する（通常は全角カナへの変換を行う）|
|-Z|全角を半角にする（JIS X 0208英数字と若干の記号をASCIIに変換する）。「-Z1」はJIS X 0208 和字間隔をASCIIスペース1つに変換。「-Z2」はASCIIスペース2つに変換。「-Z3」は「＞」「＜」「”」「＆」を、それぞれ「&gt;」「&lt;」「&quot;」「&amp;」に変換する|

### その他の整形
|オプション|説明|
|-|-|
|-f 文字数|1行の文字数を指定して簡単な整形を行う（「-f」のみの場合は60桁）|
|--hiragana|ひらがなで出力する|
|--katakana|カタカナで出力する|

＊オプションは他にもたくさんあります。確認次第、随時更新していく予定です。

# 実際に使ってみる
nkfは「nkf ファイル名」で指定したファイル、または標準入力から受け取った内容を変換して標準出力に書き出します。

```:例
cat 元ファイル | nkf -ec > 保存ファイル名
nkf -ec 元ファイル > 保存ファイル名
```

上記例では文字コードと変換コードを変換し、新たにファイルを作成して保存していますが、
`--overwrite`オプションを使うことで、「元ファイル」に変換内容を上書きして保存することが出来ます。（新しいファイルを作らない）

```:例
cat 元ファイル | nkf -ec --overwrite
nkf -ec --orverwrite 元ファイル
```

`--guess`オプションを使うことで、使用されている文字コードと改行コードの判定結果を表示することが出来ます。

```:例
nkf --guess 元ファイル
元ファイル:UTF-8(LF)
```

# まとめ
* nkfコマンドは文字コードと改行コードを変換することが出来る。
* 半角/全角関係の変換やひらがなで出力したりできるオプションが存在する。
* --guessオプションを使うことで、使用されている文字コードと改行コードの判定結果を表示することができる。
* デフォルトの出力はJISコードで、改行コードは変換されない。
【Salesforce】CRM Analyticsにおける複数値の処理1

CRMAにおける複数値のユースケースについて、よくお問い合わせいただくものをご紹介いたします。

**初期設定**

CRMAnalyticsでセールスフォースの複数選択値を表示するには、まずAnalyticsの設定を行う必要があります。
設定の画面でAnalyticsを検索して、Analyticsの設定画面でCRM Analytics の複数値項目のインデックス付けを有効にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3672646/3b87e08a-fe0c-8302-5a2d-ecb00edfd01f.png)



## レシピの変換ノードで複数値の置き換え
1. 複数値を直接置き換えることはできないので、最初はarray_join()関数を使って複数値型をテキスト型に置き換える必要があります。
【参考資料】[数式の複数値関数](https://help.salesforce.com/s/articleView?language=en_US&id=sf.bi_integrate_recipe_multivalueFunctions.htm&type=5)　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3672646/df855969-2180-7a4d-0eff-29a0026c9c7f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3672646/84c518ef-f44b-e211-e34e-45ca4f873aae.png)


2. Replace関数を利用して、テキスト内容を置き換えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3672646/a084c3b4-6081-03a4-9b8f-d04631969e86.png)

3. split関数を利用して、テキスト型を複数値型に変換することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3672646/59d1056b-7143-b4fc-776a-4973f77e60e3.png)




## ダッシュボードに複数値を表示 


[CRMAにおける複数値項目の制限](https://help.salesforce.com/s/articleView?id=000383895&type=1)によりますと、テーブルでは、値の完全なリストではなく、複数値フィールドの最初の値のみが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3672646/ae35f857-74cd-aebb-8c35-98819c4454e8.png)

しかし、複数値項目を利用して、テーブルをフィルタリングすることができます。そのため、フィルタリングと内容表示のために、テキスト型と複数値型の両方を維持することをお勧めします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3672646/d1566d5d-befd-2a4e-3cdc-c92e75a346fb.png)
【Python】Processing のインストール手順


## はじめに

Python上で画像処理をするにあたってProcessingを使うことになったので，そのインストールの手順を紹介します．

## Processing について

> Processingは、[キャセイ・レアス（Casey Reas）](https://en.wikipedia.org/wiki/Casey_Reas)と[ベンジャミン・フライ（Benjamin Fry）](https://en.wikipedia.org/wiki/Ben_Fry)によるオープンソースプロジェクトであり、かつてはMITメディアラボで開発されていた。電子アートとビジュアルデザインのためのプログラミング言語であり、統合開発環境（IDE）である。アーティストによるコンテンツ制作作業のために、詳細な設定を行う関数を排除している。 視覚的なフィードバックが即座に得られるため、初心者がプログラミングを学習するのに適しており、電子スケッチブックの基盤としても利用できる。Java を単純化し、グラフィック機能に特化した言語といえる。（Wikipediaより）

つまり，Processingとは，動的でインタラクティブな画像を生成できる画像ライブラリです．
詳しくは以下のWebサイトを参照してください．

https://processing.org

## Processing を使えるようにしよう

#### 手順１ Processing のインストール

[Download Processing](https://processing.org/download) からOSを選択し，インストーラをダウンロードします．完了したら，ダウンロードされたアプリケーションを開けましょう．

![スクリーンショット 2024-01-10 18.18.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664417/6c66e64d-ff15-3516-7d87-c304d2804d15.png)

#### 手順２ Python コードを書けるようにする

ProcessingはデフォルトではJavaでコード書けるようになっているので，Pythonコードを書けるようにするために，右上の［Java］のところから［Java ＞ Manage Modes... ＞ Python Mode for Processing X（本記事執筆時点では４） ＞ ↓install］を選択します．これでProcessingでPythonコードが書けるようになります．

![スクリーンショット 2024-01-10 18.31.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664417/892293fb-1815-1f93-8c3a-cd8d7cb29f51.png)
![スクリーンショット 2024-01-10 18.31.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664417/a447799f-cfdf-6148-8498-5b4add4b933b.png)

## 参考文献

- [Peter Farrell．Pythonではじめる数学の冒険（鈴木幸敏訳）．O'Reilly Japan，2020．](https://www.oreilly.co.jp/books/9784873119304/)
[現場に泣いた]社内システム開発の失敗から学んだこと

## はじめに
初投稿になります:relaxed:
現在、長期インターン先で社内システムの開発におけるプロダクトマネジメント業務をやらさせてもらってます。
今回はそこでのシステム開発の失敗経験から学んだことを戒めとして残しておこうと思います。

## 発端
これはつい先日、私が経営層から頼まれて、ある社内システムの新規開発に携わっていた時の話になります。簡単に言うと現状現場での紙媒体での作業をタブレットで行えるようにするというものです。

3ヶ月のチームでの努力の末、要件定義からデザインカンプの作成、コーディングまでを経営層とすり合わせながらやっと終えたところで、実機でのデモとプレゼンを現場の方達の前で行うことになりました。

## 結果
プレゼンの結果、
「この機能はこうしないと現場では使えないね。」や、
「それ面倒くさい」
などと正直使用したくないといった声もあがっていました。

現場の業務改善のため、顧客の満足のためにシステムを開発してきたのに、どうしてこのような結末になってしまったのでしょう？とても辛かったですが、原因を考えました。

<img src="https://3.bp.blogspot.com/-lQV3y6ENfrQ/XAnwFqYcITI/AAAAAAABQuA/Jwa8HXMUuQYFY1GP_jd7_vbGAdBM5UV2gCLcBGAs/s800/question_head_gakuzen_girl.png" width=30%>

## 原因
#### 現場の方たちと要件定義の段階でコミュニケーションを取れなかった。
これに尽きます。要件定義、遅くてもデザインカンプが完成したタイミングで現場の方の意見を聞くべきでした。現場での業務は何回か自分で体験していたし、これでいいだろうと思って開発に移ってしまいました。
レイヤーが上の方とは本部で話す機会が多くあったが、実際に現場で働いている人の意見はもっと聞くべきでした。


## 解決策
#### 1. 頻繁な現場との打ち合わせ
「想定と違う！」なんてことがないように、今後は企画段階、要件定義が終わった段階、デザインカンプが完成した段階などの要所で、実際にシステムを使用する現場との打ち合わせをするように心がけます。

#### 2. スケジュールの余裕確保
そもそも企画から開発までの期間が短すぎました。焦って作業を行うことで結局見落としも増え、出戻りも多かったように思います。今後は余裕を持ったスケジュールを組み、現場との打ち合わせの時間を多く取れるようにしたいと思います。

<img src="https://1.bp.blogspot.com/-65sJUctWUHk/VSufuTgnCUI/AAAAAAAAtBM/qp4kxYW0H-w/s800/syoudan_torihiki.png" width=65%>
Github Api GraphQLでissiue作成＆project紐付けなどをやってみました

## issue作成
```
mutation createIssue($title: String!, $body: String, $labelIds: [ID!]) {
      createIssue(input:{title: $title, body: $body, repositoryId: "Your Repository Id", labelIds: $labelIds}) {
        issue {
          id
          number
        }
      }
    }
```
## issueをproject(beta)に登録
```
mutation addProjectV2ItemById($issueId: ID!, $projectId: ID!) {
      addProjectV2ItemById(input: {contentId: $issueId, projectId: $projectId}) {
        item {
          id
        }
      }
    }
```
## project(beta)に紐ついたissueのprojectカスタム項目を更新（複数）
```
mutation updateProjectV2ItemFieldValue($issueId: ID!, $column1: String!, $column2: Float!, $column1FieldId: ID!, $column2FieldId: ID!, $projectId: ID!) {
      updateColumn1: updateProjectV2ItemFieldValue(input:{itemId: $issueId, fieldId: $column1FieldId, projectId: $projectId, value: {iterationId: $column1Id}}) {
        clientMutationId
      },
      updateColumn2: updateProjectV2ItemFieldValue(input:{itemId: $issueId, fieldId: $column2FieldId, projectId: $projectId, value: {number: $column2}}){
        clientMutationId
      }
    }
```
## Iteration項目のvalue idを見つかる
```
query($org: String!, $projectNum: Int!, $fieldName: String!) {
      organization(login: $org) {
        projectV2(number: $projectNum) {
          field(name: $fieldName) {
            ... on ProjectV2IterationField {
             id
              configuration {
                iterations {
                  id
                  title
                }
              }
            }
          }
        }
      }
    }
```

## 最後に
projectV2のField探す、repository id探すなどは[以前の記事](https://qiita.com/felinyan/items/85667d5c52a74b0a1773)にすでに紹介ずみ
FE 線形代数と統計

### 線形代数の活用例
- 線形代数は行列やベクトルといった数学的なツールを用いて、複雑な数や変数の関係を計算する学問
- 複雑な数式モデルが使われている身近なツールで計算する際に役立つ

### 行列
- 行列は選定台数で使用されるツールの１つであり、数字を盾と横に並べたもの
- 横方向"行"　　縦方向"列"

### 行列の四則計算
- 行列に対し、普段私たちが使用する単一の「数値をスカラーと呼ぶ
- 「行列と行列」および「行列とスカラー」の四則計算は計算できるものとできないものがある

### 統計の性質
- 度数分布表とは各階級に属するデータの数を表現したもので、ヒストグラムはそれを可視化したグラフ
- 統計データの中で特徴的なデータには名称が定められている
    - 中央値（メジアン）：データを順番に並べた際に中央に来る値
    -  最頻値（モード）：最も頻繁に登場する値
    -  平均値：データの合計をデータ数で割った値
    -  分散：平均からのズレの大きさ
    -  標準偏差：√分散

### 正規分布
- 平均値を中心に左右対称な分布を正規分布と呼ぶ

### 相関係数
- ２種間のデータの関連性を示す指標を相関係数と呼び、-1~1で表現される

### 統計的分析手法
- データを解析して変数間の関係性を理解したり、データの特性を把握する手法を統計的分析手法と呼ぶ
回帰分析、単回帰分析、重回帰分析、ロジスティック回帰分析、相関分析、主成分分析
HTTPリクエストとasync with ブロック

`aiohttp`ライブラリを使用して非同期リクエストを行った時に、何回かに一回、`asyncio.exceptions.TimeoutError`が発生しました。
ローカル環境ではサーバーでエラーが出なかったため、原因に思い至るまでに試行錯誤して時間がかかったので、メモしておきます。

## HTTPリクエストのテストコード

以下に、`aiohttp`を使用した非同期のGETリクエスト関数と、それに対する`aioresponses`を使用したテストの例を示します。

test()はテストが通ります。
test_ngは`aiohttp.client_exceptions.ClientConnectionError: Connection closed`が発生してテストが通りません。
違いは、コンテキストマネージャasyncの内と外のどちらで`response.text()`を実行するかですね。
自分は最初、NGパターンの方でやっていて、相手先サーバーが正常にレスポンスを返しているログはあるのになんでタイムアウトエラーが出るんだろう？と不思議でしたが、書いてみるとasync with ブロックを抜けてからだとreadできないのがわかります。

```
import aiohttp
import pytest
from aioresponses import aioresponses


async def fetch_data_pattern_1(url):
    async with aiohttp.ClientSession(timeout=1) as session:
        async with session.get(url) as response:
            return await response.text()


async def fetch_data_pattern_2(url):
    async with aiohttp.ClientSession(timeout=1) as session:
        response = await session.get(url)
        return response


@pytest.mark.asyncio()
async def test():
    mock_response_content = "Hello World!"
    test_url = "http://example.com"

    with aioresponses() as mocked:
        mocked.get(
            test_url,
            body=mock_response_content,
        )
        response = await fetch_data_pattern_1(test_url)
        assert response == mock_response_content
        print(f"response: {response}")


@pytest.mark.asyncio()
async def test_ng():
    mock_response_content = "Hello World!"
    test_url = "http://example.com"

    with aioresponses() as mocked:
        mocked.get(
            test_url,
            body=mock_response_content,
        )
        response = await fetch_data_pattern_2(test_url)
    data = await response.text()
    assert data == mock_response_content

```
ニフクラ mobile backendのファイルストアをParse Serverに移行する

[ニフクラ mobile backendは3月末で終了します](https://mbaas.nifcloud.com/info/2023/12/post-171.html)。

ニフクラ mobile backendからの移行先として、お勧めしているのが[Parse Server](https://parseplatform.org/)です。設計思想が近く、変更するコード量が少なく済むのではないかと思います。

そこでParse Serverへの移行をサポートできるスクリプトを作成中です。今回はファイルストアの移行スクリプトを紹介します。

## TL;DR

今回、移行用のスクリプトを作りました。

[NCMBMania/ncmb2parse](https://github.com/NCMBMania/ncmb2parse)

使い方は、以下のような形です。

```bash
npx node dist/file.js
	-a YOUR_APP_ID \
  -m YOUR_MASTER_KEY \
  -u YOUR_PARSE_SERVER_URL\
  -j YOUR_JAVASCRIPT_KEY \
  /path/to/files.json
```

## 必要な情報を用意する

### ニフクラ mobile backendのファイルストアをエクスポートする

ファイルストアのデータは、Chrome機能拡張で取得できます。全ファイルデータと、メタデータである `files.json` が必要です。

![1835_console_mbaas_nifcloud_com_-_1208153533.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/ac4a3b0d-0f9e-08cd-7766-78b40ae3ee97.jpeg)

ファイルと `files.json` は同じディレクトリに置いてください。

[NCMBのデータエクスポートに使えるGoogle Chrome機能拡張（ファイルストアの全ファイルダウンロード） \#JavaScript \- Qiita](https://qiita.com/goofmint/items/029896808b6c7fddd736)

## Parse Serverの各種データを取得する

Parse Serverを起動する際の、下記データが必要です。

- アプリケーションID
- マスターキー
- Parse ServerのURL
- JavaScript APIキー

これらを控えておきます。

## 移行用スクリプトを用意する

移行用スクリプトは、Node.jsで動作します。Node.jsがインストールされていない場合は、インストールしてください。

```bash
git clone https://github.com/NCMBMania/ncmb2parse.git
cd ncmb2parse
npm install
```

## 移行用スクリプトを実行する

先ほど取得したParse Serverの情報、files.jsonのパスを指定して、スクリプトを実行します。

```bash
npx node dist/file.js
	-a YOUR_APP_ID \
  -m YOUR_MASTER_KEY \
  -u YOUR_PARSE_SERVER_URL\
  -j YOUR_JAVASCRIPT_KEY \
  /path/to/files.json
```

ヘルプは以下の通りです。

```
Usage: file [options] <filePath>

Arguments:
  filePath                              インポートするJSONファイルのパス

Options:
  -k, --key <REST API Key>              Parse ServerのREST APIキー (default: "")
  -u, --url <URL>                       Parse ServerのURL
  -a, --app <Application ID>            Parse ServerのApplication ID
  -n, --name <Name>                     クラス名、ロール名を指定 (default: "")
  -m, --masterKey <Master Key>          Parse ServerのMaster Key (default: "")
  -j, --javascriptKey <JavaScript Key>  Parse ServerのJavaScript Key (default: "")
  -h, --help                            display help for command
```

## 注意点

- `-n` オプションはクラス名です。デフォルトは files クラスに保存されます。
- インポート対象になるファイルは `files.json` と同じディレクトに配置してください。

## まとめ

Parse ServerはデータやACLがニフクラ mobile backendと近いので、データ移行はさほど難しくありません。Parse Dashboardを使えば、Webブラウザからプッシュ通知の作成も可能です。自分でサーバーを立ち上げる必要はありますが、移行先として検討してみてください。

[Parse Platform](https://parseplatform.org/)
ニフクラ mobile backendのグループ（Role）データをParse Serverに移行する

[ニフクラ mobile backendは3月末で終了します](https://mbaas.nifcloud.com/info/2023/12/post-171.html)。

ニフクラ mobile backendからの移行先として、お勧めしているのが[Parse Server](https://parseplatform.org/)です。設計思想が近く、変更するコード量が少なく済むのではないかと思います。

そこでParse Serverへの移行をサポートできるスクリプトを作成中です。今回はグループ（Role）データの移行スクリプトを紹介します。

## TL;DR

今回、移行用のスクリプトを作りました。

[NCMBMania/ncmb2parse](https://github.com/NCMBMania/ncmb2parse)

使い方は、以下のような形です。

```bash
npx node dist/role.js -a YOUR_APP_ID \
  -m YOUR_MASTER_KEY \
  -u YOUR_PARSE_SERVER_URL\
  -j YOUR_JAVASCRIPT_KEY \
	-n YOUR_ROLE_NAME\
  /path/to/role-file.json
```

## 必要な情報を用意する

### ニフクラ mobile backendのロールデータをエクスポートする

ロールデータは、管理画面のエクスポート機能か、Chrome機能拡張で取得できます。JSONデータで取得してください。

[NCMBのデータエクスポートに使えるGoogle Chrome機能拡張（会員・ロールの全データダウンロード） \#JavaScript \- Qiita](https://qiita.com/goofmint/items/86fb1736c242131f6554)

データはrole-(ロール名).jsonという名前で保存されます。

![](https://camo.qiitausercontent.com/a483fd6a383f9d0d5a9d7f79cc28192eb82c8239/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3139373032362f64653433313034362d373061372d356265642d323062392d3037396439303535656332612e6a706567)

## Parse Serverの各種データを取得する

Parse Serverを起動する際の、下記データが必要です。

- アプリケーションID
- マスターキー
- Parse ServerのURL
- JavaScript APIキー

これらを控えておきます。

## 移行用スクリプトを用意する

移行用スクリプトは、Node.jsで動作します。Node.jsがインストールされていない場合は、インストールしてください。

```bash
git clone https://github.com/NCMBMania/ncmb2parse.git
cd ncmb2parse
npm install
```

## 移行用スクリプトを実行する

先ほど取得したParse Serverの情報、role-*.jsonのパスを指定して、スクリプトを実行します。

```bash
npx node dist/role.js -a YOUR_APP_ID \
  -k YOUR_REST_API_KEY \
  -u YOUR_PARSE_SERVER_URL\
  -j YOUR_JAVASCRIPT_KEY \
  -n YOUR_ROLE_NAME\
  /path/to/role-file.json
```

ヘルプは以下の通りです。

```
Usage: role [options] <filePath>

Arguments:
  filePath                              インポートするJSONファイルのパス

Options:
  -k, --key <REST API Key>              Parse ServerのREST APIキー (default: "")
  -u, --url <URL>                       Parse ServerのURL
  -a, --app <Application ID>            Parse ServerのApplication ID
  -n, --name <Name>                     クラス名、ロール名を指定 (default: "")
  -m, --masterKey <Master Key>          Parse ServerのMaster Key (default: "")
  -j, --javascriptKey <JavaScript Key>  Parse ServerのJavaScript Key (default: "")
  -h, --help                            display help for command
```

## 注意点

- `-n` オプションはロール名になります。AdminやMemberなどのグループ名を指定していくダサい。
- 入れ子のロールは復元できません。ロールに属するユーザー情報のみ移行できます。
- ユーザーデータはあらかじめ移行されている必要があります。 `users.json` を用意の上、こちらの記事を参考に取り込んでください。
- 現時点では1グループ最大1,000件のユーザーデータのみ移行できます。それ以上の場合は、スクリプトを修正してください。

## まとめ

Parse ServerはデータやACLがニフクラ mobile backendと近いので、データ移行はさほど難しくありません。Parse Dashboardを使えば、Webブラウザからプッシュ通知の作成も可能です。自分でサーバーを立ち上げる必要はありますが、移行先として検討してみてください。

[Parse Platform](https://parseplatform.org/)
ExcelでGrepするマクロ

```コード


Sub SearchAndRecordResultsRecursive()
    Dim currentDirectory As String
    Dim searchString As String
    Dim resultSheet As Worksheet
    Dim resultRow As Long
    
    ' スクリプトが格納されているディレクトリを取得
    currentDirectory = ThisWorkbook.Path
    
    ' Excelファイル内のセルから検索文字列を取得
    searchString = Sheets("Sheet1").Range("A1").Value ' A1 セルに検索文字列が格納されていると仮定
    
    ' 別シートに結果を記録するためのシートを作成または取得
    On Error Resume Next
    Set resultSheet = Worksheets("SearchResults")
    On Error GoTo 0
    
    If resultSheet Is Nothing Then
        Set resultSheet = Sheets.Add(After:=Sheets(Sheets.Count))
        resultSheet.Name = "SearchResults"
        resultSheet.Cells(1, 1).Value = "File Name"
        resultSheet.Cells(1, 2).Value = "Cell Address"
        resultRow = 2
    Else
        ' 既存のデータがある場合は最終行を取得
        resultRow = resultSheet.Cells(resultSheet.Rows.Count, 1).End(xlUp).Row + 1
    End If
    
    ' 指定されたディレクトリおよびサブディレクトリ内のすべてのExcelファイルに対して処理
    RecursiveSearch currentDirectory, searchString, resultSheet, resultRow
End Sub

Sub RecursiveSearch(directory As String, searchString As String, resultSheet As Worksheet, ByRef resultRow As Long)
    Dim filePath As String
    Dim wb As Workbook
    Dim ws As Worksheet
    Dim cell As Range
    
    ' 指定されたディレクトリ内のすべてのExcelファイルに対して処理
    filePath = Dir(directory & "\*.xlsx")
    Do While filePath <> ""
        ' Excelファイルを開く
        Set wb = Workbooks.Open(directory & "\" & filePath)
        
        ' 各シートに対して検索を実行
        For Each ws In wb.Worksheets
            For Each cell In ws.UsedRange
                If InStr(1, cell.Value, searchString, vbTextCompare) > 0 Then
                    ' 文字列が見つかった場合は結果を記録
                    resultSheet.Cells(resultRow, 1).Value = wb.Name
                    resultSheet.Cells(resultRow, 2).Value = cell.Address
                    resultRow = resultRow + 1
                End If
            Next cell
        Next ws
        
        ' 次のExcelファイルに進む
        wb.Close False
        filePath = Dir
    Loop
    
    ' サブディレクトリ内のExcelファイルに対して再帰的に処理
    filePath = Dir(directory & "\*", vbDirectory)
    Do While filePath <> ""
        If (GetAttr(directory & "\" & filePath) And vbDirectory) = vbDirectory And filePath <> "." And filePath <> ".." Then
            ' ディレクトリの場合は再帰的に処理
            RecursiveSearch directory & "\" & filePath, searchString, resultSheet, resultRow
        End If
        filePath = Dir
    Loop
End Sub

```
「Gaur ama hil zen, gaur goizean ama hil nuen.」における「ama hil」の係り受け関係

私(安岡孝一)個人の感覚に過ぎないのだが、バスク語とUniversal Dependenciesは、どうも相性が悪いように思える。もちろん、[UD_Basque-BDT](https://github.com/UniversalDependencies/UD_Basque-BDT)は開発が続けられているし、[Stanza](https://stanfordnlp.github.io/stanza/)も[Trankit](https://github.com/nlp-uoregon/trankit)もバスク語UDをサポートしている。それでも、しっくり来ないのだ。極端な例として「Gaur ama hil zen, gaur goizean ama hil nuen.」を、Google Colaboratory上のStanzaで係り受け解析してみよう。

```
!pip install stanza deplacy
import stanza
nlp=stanza.Pipeline("eu")
doc=nlp("Gaur ama hil zen, gaur goizean ama hil nuen.")
import deplacy
deplacy.serve(doc,port=None)
```

私の手元では、以下の結果が得られた。

```
# text = Gaur ama hil zen, gaur goizean ama hil nuen.
# sent_id = 0
1	Gaur	gaur	ADV	_	_	3	advmod	_	start_char=0|end_char=4
2	ama	ama	NOUN	_	Case=Abs|Definite=Def|Number=Sing	3	nsubj	_	start_char=5|end_char=8
3	hil	hil	VERB	_	Aspect=Perf|VerbForm=Part	0	root	_	start_char=9|end_char=12
4	zen	izan	AUX	_	Mood=Ind|Number[abs]=Sing|Person[abs]=3|VerbForm=Fin	3	aux	_	start_char=13|end_char=16
5	,	,	PUNCT	_	_	9	punct	_	start_char=16|end_char=17
6	gaur	gaur	ADV	_	_	9	advmod	_	start_char=18|end_char=22
7	goizean	goiz	NOUN	_	Animacy=Inan|Case=Ine|Definite=Def|Number=Sing	9	obl	_	start_char=23|end_char=30
8	ama	ama	NOUN	_	Case=Abs|Definite=Def|Number=Sing	9	obj	_	start_char=31|end_char=34
9	hil	hil	VERB	_	Aspect=Perf|VerbForm=Part	3	conj	_	start_char=35|end_char=38
10	nuen	edun	AUX	_	Mood=Ind|Number[abs]=Sing|Number[erg]=Sing|Person[abs]=3|Person[erg]=1|VerbForm=Fin	9	aux	_	start_char=39|end_char=43
11	.	.	PUNCT	_	_	3	punct	_	start_char=43|end_char=44
```


![eu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428317/96a73387-c26a-7320-d350-3235f92f000c.png)

この例文に2つ出てくる「ama hil」は、いずれも動詞hilに対して絶対格のamaが付いていて「ママンが死ぬ」を表している。これにzen (izanの3人称過去)が付くと「ママンは死んだ」となる。一方nuen (izanの絶対格3人称能格1人称過去)が付くと、能格の1人称が内包されているので「ママンは私が死なせた」となるわけだ。ところが、上の結果を見る限り、「ama hil zen」ではamaとhilがnsubj(主語)で繋がれているが、「ama hil nuen」ではamaとhilがobj(目的語)で繋がれている。端的には「ama hil nuen」を「ママンを私が殺した」と解釈して(意味的には確かにそうなのだが)、その上でamaをhilの目的語とみなしているように見える。能格言語であるバスク語の解釈としてはイマイチで、スペイン語などの印欧諸語に引きずられているようだ。

ただし、このあたりの議論は、Izaskun Aldezabal, Maxux Aranzabe, Jose Mari Arriola, Arantza Díaz de Ilarraza『[Syntactic annotation in the Reference Corpus for the Processing of Basque (EPEC): Theoretical and practical issues](https://www.ixa.eus/node/3218)』からMaria Jesus Aranzabe, Aitziber Atutxa, Kepa Bengoetxea, Arantza Díaz de Ilarraza, Iakes Goenaga, Koldo Gojenola, Larraitz Uria『[Dependentzia Unibertsalen eredura egokitutako euskarazko zuhaitz-bankua](http://hdl.handle.net/10810/39009)』へと引き継がれてきたものだ。これらの仕事をずっとやってきたEuskal Herriko Unibertsitateaがスペインにある以上、スペイン語UDとの連絡性は担保すべきだろう。まあ、難しいところだなあ。
プログラミングの際のエラー対処忘備録

## はじめに
エラーの対処で時間を浪費してしまう経験は、プログラマーなら何度も経験のあることではないでしょうか。筆者もエラーの対処方法をずっと考え込んでしまって日が暮れてしまうことが多々ありました。
そこでエラーの対処の効率的な遷移を考えました。これによってエラー対処がうまくなれば、コーディングにおいてかなりの時間を節約できます。
今回はそんな筆者が考える、効率的なエラー対処の遷移をまとめました。

## エラー対処の遷移
1\. エラー分をググる
やはりエラー文をGoogleで検索するのが最も確実で素早い方法です。
2\. エラーログを記述
ググってもうまく解決できない場合、そのエラー対処には時間がかかる可能性があります。そこで予めエラーログを記述することで頭の整理＋他の人に相談する際に状況をドキュメントで素早く共有することができるようになります。
3\. 現象把握・原因把握
まず、今起こっているエラーの現象を正しく把握しましょう。エラーが起こっているのはコードのどこに該当しているのかなどを把握できると、エラーの原因も正しく把握できます。
4\. 同じプロジェクトのコードから似たような例を参照する
エラーの該当箇所と似ているコードを同じプロジェクトから探しましょう。プロジェクト特有のルールに起因するエラーの場合はGoogleなどで検索しても解決しないことが多いです。
5\. ChatGPTの活用
ChatGPTを活用することによってエラーの対処方法を素早く知ることができる可能性があります。セキュリティに注意しながらChatGPTを賢く活用しましょう。
6\. 公式ドキュメント参照
Qiitaなどに乗っている情報は2次情報なので、公式ドキュメント一次情報のほうが信頼性があります。公式ドキュメントを参照することで正しい情報が手に入るかもしれません。
7\. 英語でググる
日本語よりも圧倒的に英語の文章のほうが情報が多いです。自分のエラーがニッチであればあるほど、英語で検索することでより多くの情報にアクセスすることが可能になります。
9\. 人に聞くOr該当するコードを違う記述方法で書き直し
上記の対処をしても、うまくエラーが解決できない場合は人に聞きましょう。自分で限界まで調べても解決策がわからない場合は、作業が止まってしまいます。そんなときはチームの生産性にも影響するので知っている人に聞きましょう。案外、すんなり解決することが多いですよ。


## おわりに
いかがだったでしょうか。エラー対処の技術を磨いて一流のエンジニアを目指しましょう！
応用情報に合格するまで

<h2>結果</h2>
試験は2回受けました。

1回目の試験は午後問の点数が足りず不合格。
2回目の試験は午前問62点。午後問61点でギリギリ合格しました。


2回目の試験までの取り組み方について書いていきます。

<h2>午前問題</h2>
テキストを一通り目を通して、過去問道場をひたすらやりました。
毎日80問をノルマとしてやっていましたが、ちょっと試行回数が足りなかった気がします。

とはいえ、試験当日までには7，8割は正解できるように取り組むことができました。

<h2>午後問題</h2>
午後問は午前問と違い、記述問題が出題され、分野を選択できます。
午後問は自分の得意な分野を選んで、そこだけ重点的に勉強しました。

以下の記事を参考に自分の得意分野の選定を行いました。
プログラミングは、時間が絶対足りなくなるので無理だと判断。

https://qiita.com/c60evaporator/items/0bbda34eead71c9e38d9

昔ほど文字が読めず、長文を読むときに文字が滑って読めなくなっていました。
その対策として、文を読んだら図にしていく作業を挟むことによって、その情報を整理してなんとか意味を理解するように努めました。

試験当日までに、1問30分くらいで解けるくらいにはなりました。
5問×30分で試験時間ギリギリです。

<h2>試験当日</h2>
午前問は、新規の問題が多く戸惑いました。結果、かなり点数が低くなってしまいました。
午後問は、いつも通り図にして整理してたものの、時間をかけすぎてしまい焦りながら問題を解きました。

1問に1時間使っていたりして、かなり絶望的な状況ではありましたが、諦めずに5問解きました。

あと、いつも書いている文字が汚いので、きれいに書くように心がけました。

<h2>総括</h2>
本当にギリギリで合格しました。シンプルに勉強時間が足りてなかったと思います。

あと、午後問の図を描いて整理するのは大事だとは思いましたが、時間がかかりすぎるのでより簡易的に図を書いたりするなどの方法を模索しておけば、もっと余裕を持って試験に臨めたんじゃないかなと思いました。

2回目の試験では、時計を買っていなかったので、時計を100均で購入しました。
1回目の試験では買うのを忘れていて、時計なしで挑んていたため、今自分がどれくらいの進捗なのかを把握できずにひたすら焦りながら問題を解く状態になっていたので、それも良くなかったです。

次回はSTを受験する予定です。
今回の振り返りをきちんと次回に生かしていければと思います。

<h2>参考</h2>

https://www.ap-siken.com/apkakomon.php

https://qiita.com/c60evaporator/items/0bbda34eead71c9e38d9
blenderについて超ざっくり解説

blenderについて超ざっくり解説

# blenderってなに
A:3DCGソフトです。点をこねこねして粘土みたいにしてオブジェクト（FBX）を作ります。
これをモデリングと言います。
基本的な操作を覚えれば直感的に誰でも使えます。
無料で使えます。ｺﾜｸﾅｲﾖｰ

ちなみにモデリングだけではなく、CG映画もつくられてます。
blenderだけで自作のCG映画も作れますし、
有名所の商用映画で言えばシン・エヴァンゲリオンでもblenderが使われています
https://news.mynavi.jp/article/20210804-1927380/
みんなも見ただろ？シン・エヴァンゲリオン
ホモピアノ好き（迫真）

# blenderはなんで無料なの！？
世界中のユーザーが資金を提供しているためらしい。
 Blenderの資金提供は公式サイトから受け付けているそう。
ちなみに個人だけではなく、Blenderには、MicrosoftやAWS、Facebook、Adobeなどの大手IT企業が出資しているそう。
（AWS・・ウッ・・・頭が・・登録するだけ登録してイジってない・・）
 2021年10月にはAppleも開発基金に参加し、寄付やエンジニアリングに関する専門知識と追加のリソースをBlender本部と開発コミュニティーに提供などの支援をすることを発表しているそう
Blenderの支援企業にビック・テックの4大企業であるGoogle、Amazon、Facebook、Apple（通称・GAFA）が揃うことになったそう！
（２０２１年の情報）

# Q:blenderの他に３DCGをイジれるソフトないの？
A:数えきれない位いーーっぱいあるよ！VRCでモデルを作りたいなら、
blenderかMayaか、ってくらいMayaが人気だよ！でもblenderの方に軍配があがるよ！

# Q:なんでMayaとblenderならblenderの方が人気なの？
A:blenderは完全無料だからだよ！学生も社会人でも無料だよ！
Mayaを利用するためにはライセンスの購入が必要らしいんだけど、価格は1ライセンスあたり1年間で248,000円（税別）らしい！値段が高い（直球）
ただし１点だけすごい点があって、学生の場合は無料でライセンスが提供される！ので、学生の間はMayaを使用した方がいいと思われます！
なんてったって、学校卒業後に社会人になったら1年間で248,000円（税別）ですからね！
それが無料で使えるわけですから、学校を卒業していない学生の間はMayaを使った方がいいでしょう！
逆に学校を卒業して社会人になってしまったら、Mayaの使用料がかかってしまうので、blenderのほうがいいでしょう。
私はMayaを触ったことがない＆学生ではないので、Mayaについては聞かれても答えられません、悪しからず。

# Q:早速blenderを使いたいけど、どのバージョンをDLすればいいの？
A:LTSって書いてあるやつがいいです。LTSとは「Long-term Support」つまり、公式が長い期間サポートするよ★っていうバージョンです。
LTSではないけど、もう新しいバージョンならなんでもいいんじゃない？と思いきや、あまり新しすぎてもバグがあったりするらしいです！

LTS適用のバージョンはこちらから見れます
https://www.blender.org/download/lts/3-6/

「Versions」の下のDownloadから、自分のPCのバージョンを選んでDLしましょう

2023/12/18現在、LTS適用で一番新しいバージョンは blender3.6です！

特にこだわりがなければ、LTSの中でなるべく新しいバージョンが良いでしょう。「使いやすい」と自分自身で感じるのであれば、古いバージョンでも大丈夫です。ただ、新しいバージョンのほうができることが多い、というのは意識しておいたほうがいいでしょう。
アバターでもなんでも作りつづけるということはツールをアップデートせざるをえない（ツールだけではなく、使用者自身のアップデートも不可避なので、新しいものにたいしての勉強や情報収集は避けては通れない）ということです。まあこれは仕事（IT系など）でも趣味（unity、VRC、blender）でも、同じですね。
ちなみに2023/12/18の現在、LTSではないですが、blenderの一番新しいバージョンはBlender 4.0.2となっております。

# Q:blender4.0の新機能は？
A:
詳細はここみて
https://cgbox.jp/2023/11/25/blender-4_0-release/

見るのめんどい！って民は↓見て、どうぞ
いっぱいあるけど一部だけピックアップします

１，ノードツールの仕様によりPython無しでツール作成が可（４番、５番とある意味かぶってはいる？）
２，マテリアルノードがグループ化
３，異方性反射の項目が追加
異方性反射について詳細はこちら：https://hainarashi.hatenablog.com/entry/20210710/1625899118
４，ジオメトリノードを使ってメッシュ操作などを行うことができる「ノードツール」がオブジェクトモードのみでしたが編集モードでもメッシュ操作を行うことが可能になったそうです

「おそらくVRCで服をつくるうえで参考になるかな？」って機能を勝手にピックアップしてるけど、服つくったことないから↑が役に立つ情報かわからん（ガバガバ）

次回はblenderのセットアップについてです！（いつやるんだ・・）




ちなみに一応、私のtwitterを載せておきます。
https://x.com/vrc_machida0312

twitterのプロフィールリンクから、私のyoutubeチャンネルに飛べます。unity2019やunity2022の解説もしているので、よかったらどうぞ。
Web系プログラミング学習にレンタルサーバーよりもVPSをお勧めする理由

# 対象
- Web系プログラミングを学習している人
- スクールに通ってる人
- ポートフォリオを作りたい人
- 未経験から就職したい人


# レンタルサーバーとは?
**名前の通り、借りれるサーバーのこと**
...というのも広義すぎるので**寮**というイメージを持っていただきたい
- 家具備え付け
- 身一本で入居/退去ができる
- 安い
といったように
- 1つのサーバーをみんなで使い分ける
- 必要なもの(ミドルウェア/実行環境)は備え付けれている

# VPSとは
**Virtual Private Serverの略**
...広義すぎるので**賃貸**というイメージを持っていただきたい
- 部屋を借りる（家具は自分で買う）
- 安い
といったように
- ひとつのサーバーをみんなで分ける
- ただしミドルウェアや実行環境などは自分でインストールしないといけない
- レンタルサーバーよりもLinuxの知識が必要


## なぜVPSをおすすめするのか
**結論.レンタルサーバーよりも難しいから**

レンタルサーバーは簡単にデプロイできることがメリットとして挙げられる。
しかし、できないことも多い。
例えば
- Webサーバーを最初から構築する
- Websocketを使った双方向通信の実装
- ファイアウォールの設定
- OSレベルで色々いじる
など...


「そういうのめんどくさいからレンタルサーバーでいいや」という声も聞こえてきそうだが
**よく考えてみて欲しい**

周りが同じようにプログラミング学習を行い、ポートフォリオなどをデプロイしていく中で
初心者でWebサーバーの構築を一からやる人はどれくらいいるだろうか。
企業は人間性で互角となった2人で頭をかけている場合、難易度の高い経験をしている人と・簡単に済ませばいいやと思って楽観視している人のどちらにポテンシャルを感じるだろうか?

**時間が同じであれば、より難しい挑戦をする方がいいと私は思う**

というのも今私はAWSなどのクラウドを用いて開発を行っているが、その際にVPSで身につけた知識が大いに役に立ったと感じているからだ。
MMAを利用している場合のLog Analytics ワークスペースとVMの切断方法

## はじめに
調べてもなかなか出てこなかったLog Analyticsワークスペースの切替方法を、備忘録として残しておきます。

# Log Analytics ワークスペースとVMの切断方法
今回はAzure Portal上で行える簡単な手順を紹介します。
 
①以下のリンク先を参考に、VMの管理を停止する。（リンク内の手順をすべて実施する。）
https://learn.microsoft.com/ja-jp/azure/automation/change-tracking/remove-vms-from-change-tracking?tabs=azure-vm#to-remove-your-machines 


② 接続を切りたい Log Analytics ワークスペースのページに移動し、[ソリューション] ＞ [Chanage Tracking]を選択し、[概要]ページから削除する。    
       
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115411/a2c5dd47-7839-d3dd-d460-f180cec140a9.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115411/8d87ff68-16a8-7204-fdf0-5baaeb8217e9.png)


③ Automation アカウントページに移動し、[リンクされたワークスペース] ＞ [ワークスペースリンクを解除]を選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115411/ca97735a-adda-ef3e-d09a-aff5d23e09df.png)


④ 対象のVMのページに移動し、[拡張機能とアプリケーション]からMMAをアンインストールする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115411/2ec975ce-4a3e-dce9-7be5-93b76d04c23f.png)



これにてMMAのアンインストール完了です。

なお、詳細は以下のリンクを参考にしてください。

https://learn.microsoft.com/ja-jp/azure/automation/change-tracking/remove-feature#sign-into-the-azure-portal

なお、Azure Portalへの反映は24時間後にされるため、画面上変わっていなくても焦る必要はないです。

新規にワークスペースと接続したい場合は通常通り設定すれば問題ありません。


## おわりに
次回はAMAの場合の切断方法をご紹介します。
結構詰まったので方法がわかってうれしいです。