OmniAICreator/Qiita-1.07M huggingface dataset:
Maven Publish PluginでKotlinのソースコードを公開する

# 概要
[Maven Publish Plugin](https://docs.gradle.org/current/userguide/publishing_maven.html) で kotlin のソースコードを添付する方法です。

# build.gradle.kts(差分のみ)
以下、既に Maven Publish Plugin を利用している場合向けの、差分のみを示したコードです。
※ 各値は自身の環境に合わせてください

```kotlin:build.gradle.kts
tasks {
    val sourcesJar by creating(Jar::class) {
        archiveClassifier.set("sources")
        from(sourceSets["main"].allSource)
    }
}

afterEvaluate {
    publishing {
        publications {
            create<MavenPublication>("maven") {
                artifact(tasks["sourcesJar"])
            }
        }
    }
}
```

# build.gradle.kts
build.gradle.kts の全体像のサンプルです。

```kotlin
plugins {
    `java-library`
    kotlin("jvm")
    `maven-publish`
}

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72")
}

tasks {
    compileKotlin {
        kotlinOptions.jvmTarget = "1.8"
    }
    compileTestKotlin {
        kotlinOptions.jvmTarget = "1.8"
    }
    val sourcesJar by creating(Jar::class) {
        archiveClassifier.set("sources")
        from(sourceSets["main"].allSource)
    }
}

afterEvaluate {
    publishing {
        publications {
            create<MavenPublication>("maven") {
                from(components["kotlin"])
                artifact(tasks["sourcesJar"])
                groupId = "com.example"
                artifactId = "foo-bar"
                version = "1.0.0"
            }
        }
    }
}
```

# 実行
```
./gradlew publishMavenPublicationToMavenLocal
```
競プロで使うための GO 入門 ～math パッケージ～

# Index
- [はじめに](https://qiita.com/CamouflageSix/items/ab004a1078f491bd15ef)
- [Hello World](https://qiita.com/CamouflageSix/items/05e5a0f9616e28d6fca4)
- [標準入出力]
- [変数・定数]
- [制御構文]
- [配列～](https://qiita.com/CamouflageSix/items/41d901b9b170d5565895)
- [ソート](https://qiita.com/CamouflageSix/items/dbc2017504571e5a65aa)
- [関数](https://qiita.com/CamouflageSix/items/afb42d399a27f5ca3cf8)
- [ASCII変換](https://qiita.com/CamouflageSix/items/283655027e6581a79b4b)
- [math]

# math
```GO:
package main

import (
    "fmt"
    "math" // math
)

func main() {
}
```

## Abs()
```GO:
var f float64 = 12.3456
fmt.Println(math.Abs(-1)) // ->1
fmt.Println(math.Abs(1)) // ->1
```

## Cbrt()
func Cbrt(x float64) float64

## Ceil()
func Ceil(x float64) float64

## Floor()
func Floor(x float64) float64


#Pow()
func Pow(x, y float64) float64

## Round()
func Round(x float64) float64

```GO:
var f float64 = 12.3456
fmt.Println(math.Round(f * 100) / 100)   // ->12.35
fmt.Println(math.Round(f * 1000) / 1000) // ->12.346
```
Qiita投稿の参考ページ

# Qiita投稿にあたって
これから記事を投稿するにあたって、以下のページを参考にさせていただきたいと思います。
## 記事の書き方全般
>[Qiitaサポート](https://help.qiita.com/)のページ
>
> - [良い記事を書くためのガイドライン](https://help.qiita.com/ja/articles/qiita-article-guideline)



## Markdownの書き方
> Markdownについては、以下のページを参考にさせていただこうと思います。
>
> - [Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
> - [Qiita Markdown 書き方 まとめ](https://qiita.com/shizuma/items/8616bbe3ebe8ab0b6ca1)
Githubプライベートレポジトリでgit cloneとgit remote addを行う時のURL

※ssh部分は省略

##tldr;
URLのgithub.comの前にユーザー名+@をつける


##git clone(ユーザー名 = user01の場合)
```
git clone https://user01@github.com/xxxx/xxxx.git
```

##git remote add(ユーザー名 = user01の場合)
```
git remote add origin https://user01@github.com/xxxx/xxxx.git
```

##誤ってプライベートリポジトリをパブリックリポジトリの形式でremote add originしてしまった時の対処法

###1. リモートリポジトリのURLを確認
```
git remote -v
```

以下の結果が出力されることを確認

```
origin	https://user01@github.com/xxxx/xxxx.git (fetch)
origin	https://user01@github.com/xxxx/xxxx.git (push)
```

###2. 既存のリモートリポジトリを削除
```
git remote rm origin;
git remote remote -v　# 何も表示されないことを確認
```
###３. 正しいURLでremote addし直す(ユーザー名 = user01の場合)
```
git remote add origin https://user01@github.com/xxxx/xxxx.git
```
【PHP】composer require時にPHP Fatal error:  Allowed memory size of XXX bytes exhaustedが表示されたら

# 環境
- PHP 7.4.5
- Composer 1.10.5

# 事象
composer requireしようとしたら、メモリ確保できやんでと怒られた。
https://getcomposer.org/doc/articles/troubleshooting.md#memory-limit-errors を見ろと言われているので、それに従う。

```bash

$ composer require --dev nunomaduro/larastan
Using version ^0.6.1 for nunomaduro/larastan
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
PHP Fatal error:  Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes) in phar:///usr/local/bin/composer/src/Composer/DependencyResolver/Solver.php on line 223

Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes) in phar:///usr/local/bin/composer/src/Composer/DependencyResolver/Solver.php on line 223

Check https://getcomposer.org/doc/articles/troubleshooting.md#memory-limit-errors for more info on how to handle out of memory errors.
```

# 手順
※下記の手順は、PHP全体のメモリ上限値を無制限に変更しています。
　環境変数`COMPOSER_MEMORY_LIMIT=-1`を設定し、Composerのメモリ上限値のみ変更することを推奨いたします。
　（詳細は[こちら](https://getcomposer.org/doc/articles/troubleshooting.md#memory-limit-errors)を参照してください）

```bash
# memory_limitの設定値を確認
$ php -r "echo ini_get('memory_limit').PHP_EOL;"
128M

# php.iniの場所を確認
$ php -i | grep php.ini
Configuration File (php.ini) Path => /usr/local/etc/php/7.4
Loaded Configuration File => /usr/local/etc/php/7.4/php.ini

# memory_limitの設定値を更新
$ vi /usr/local/etc/php/7.4/php.ini
memory_limit = 128M
↓
memory_limit = -1

# memory_limitの設定値を確認
$ php -r "echo ini_get('memory_limit').PHP_EOL;"
-1
```

# composer requireをやり直す
うまくいきました:D

```bash

$ composer require --dev nunomaduro/larastan
Using version ^0.6.1 for nunomaduro/larastan
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
略
Package manifest generated successfully.
44 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
```

# memory_limitの設定値を元に戻す

```bash
# memory_limitの設定値を確認
$ php -r "echo ini_get('memory_limit').PHP_EOL;"
-1

# memory_limitの設定値を更新
$ vi /usr/local/etc/php/7.4/php.ini
memory_limit = -1
↓
memory_limit = 128M

# memory_limitの設定値を確認
$ php -r "echo ini_get('memory_limit').PHP_EOL;"
128M
```
FlutterFragmentを設置したらToolbarがStatus barにめり込んだ。対処法を解説。

Androidネイティブなアプリの一部機能をFlutterで開発するために、FlutterFragmentを設置しました。そうしたらAndroidネイティブなToolbarがStatus Barにめり込んでしまいました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334798/fd19ce16-83a7-5d61-4c2a-10e8ae750a6c.png" width="320px">

# 解決方法

レイアウトファイルに `android:fitsSystemWindows="true"` 属性を設定すればめり込まなくなります。

```activity_pager.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context="jp.bellware.echo.view.pager.PagerActivity">

    <androidx.appcompat.widget.Toolbar
        app:layout_constraintTop_toTopOf="parent"
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/primary"
        android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar"
        android:elevation="5dp"
        android:minHeight="?attr/actionBarSize" />
    <!-- Toolbarの下全体にFlutterFragmentを設置する -->
    <FrameLayout
        android:id="@+id/fragmentContainer"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toBottomOf="@id/toolbar"
        app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334798/19a3a648-20c7-2049-92aa-5a781781e0b4.png" width="320px">

# 詳細

FlutterFragmentを設置すると `window.decorView.systemUiVisibility` が書き換わってしまいます。

FlutterFragmentを設置しなければ0ですが、設置すると

- [SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN](https://developer.android.com/reference/android/view/View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
- [SYSTEM_UI_FLAG_LAYOUT_STABLE](https://developer.android.com/reference/android/view/View#SYSTEM_UI_FLAG_LAYOUT_STABLE)

が設定されてしまいます。
確認にはActivityのonPauseメソッドでLogcatを使いました。

[公式のFlutterFragmentの解説](https://flutter.dev/docs/development/add-to-app/android/add-flutter-fragment?tab=forward-activity-calls-java-tab#the-relationship-beween-flutterfragment-and-its-activity)では`shouldAttachEngineToActivity`という設定が紹介されていましたが、この設定を変更してもこの現象は変わりませんでした。

さて、 `SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN` と `SYSTEM_UI_FLAG_LAYOUT_STABLE` がなにを表しているかというと、[こちらの公式の解説](https://developer.android.com/training/system-ui/status#behind)でStatus barの後ろにアプリのコンテンツを設置できるとありました。さらに `android:fitsSystemWindows` 属性をtrueにすることでシステムウィンドウを避けたpaddingを設定出来るとあったので、今回もそれで解決できました。
GrasshopperによるZIGSIM連携

どこにも載ってなかったので備忘録として

RhinocerosのプラグインであるGrasshopperのプラグインgHowlを使ってZIGSIMと連携しスマートフォンから加速度やジャイロ、タッチセンサーのデータを取得します。

メリットとしてArdinoを使った方法よりも簡単かつ正確なデータが得られます。
デメリットは得られるデータがスマホのセンサーによることでしょうか

#ZIGSIMについて
このアプリを使用することでOSC通信を使って簡単にPCにスマホのセンサーの情報をPCに持っていくことができます。
有名どころではtouch designerでの利用があげられます。

詳細はここから↓
https://zig-project.com

#gHowlについて
grasshopperのプラグインでこれを使うと簡単にOSC通信ができます。

使い方は以下のページからコンポーネントをダウンロードしてcomponet folderにいれるだけです。
https://www.food4rhino.com/app/ghowl

#実装
1.　IPアドレスを調べます
　　コマンドプロンプトを起動します。
　　「ipconfig」と入力します。
　　その中にあるIPv4の項目をメモします。
　　これがIPアドレスになります。

2.　ZIGSIMの設定
　　ZIGSIMを起動します。
　　下のタブの右のものを選択し以下のように設定を変えます。
　　PROTOCOLはUDPを選択します。
　　IP ADDRESSには先ほどメモしたIPアドレスを入力します。
　　PORT NUMBERには好きな数字を入れます。
　　MESSAGE FORMATはOSC、MESSAGE RATEは30を選択します。
![IMG-5405_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/446399/eaf6831d-5696-f3f4-f805-3e2d8bd298c4.jpeg)

　　下のタブの左のものを選択し以下のようにPCに送りたいデータを選択します。
![IMG-5404.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/446399/cce7aabd-33ab-d902-eb01-896427753711.jpeg)

　　下のタブの中央のものを選択するとOSC通信が始まります。
![IMG-5405_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/446399/140dd004-dd15-42d0-3657-0a36affa6b05.jpeg)


　　最後にスマートフォンとPCを同じWi-Fiにつなぎます。


3.grasshopperでの操作
　　grasshopperで以下のようにコンポーネントを組みます。

![zigsim.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/446399/2586c499-320e-1b3e-ffb4-9bc7aac824f2.png)
　　＠には先ほどメモしたIPアドレスを入力します。
　　Pには先ほどZIGSIMでセットしたPortNumberのと同じ数字を入力します。
　　＃には999を入力します。

　　このようにやるとDから以下のように各値が出力されます。

![zigsim2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/446399/1efa1e62-8ebb-9c96-8596-54b1b1de38a3.png)
　　あとはListItemコンポーネントで煮るなり焼くなり好きにしましょう！!



暇があったらデータの使い方を追記します。

参考文献
https://amdlaboratory.com/amdblog/grasshopperghowlの使い方①/
ViewPager2のFragmentのtag名はf0, f1, f2

ActivityからFragmentのメソッドを呼びたいときは、[FragmentManager](https://developer.android.com/reference/androidx/fragment/app/FragmentManager)クラスの[findFragmentById](https://developer.android.com/reference/androidx/fragment/app/FragmentManager#findFragmentById(int))メソッドまたは[findFragmentByTag](https://developer.android.com/reference/androidx/fragment/app/FragmentManager?hl=ja#findFragmentByTag(java.lang.String))メソッドを使ってFragmentの参照を取得してメソッドを呼び出すことが公式で案内されています。

[アクティビティと通信する](https://developer.android.com/guide/components/fragments?hl=ja#CommunicatingWithActivity)

Fragmentが[ViewPager](https://developer.android.com/reference/androidx/viewpager/widget/ViewPager)のページを構成しているときは、公式の記載は無いですが、このようなやり方でFragmentの参照を取得することができます。

※ [ViewPagerのadapter](https://developer.android.com/reference/kotlin/androidx/viewpager/widget/ViewPager#setAdapter(androidx.viewpager.widget.PagerAdapter))に[FragmentPagerAdapter](https://developer.android.com/reference/androidx/fragment/app/FragmentPagerAdapter)を使っている場合のみ有効です。[FragmentStatePagerAdapter](https://developer.android.com/reference/androidx/fragment/app/FragmentStatePagerAdapter)を使っている場合はFragmentの参照を取得できませんでした。

```kotlin:PagerActivity.kt
// 2ページ目FragmentのsomeMethodメソッドを呼び出す
val id = viewPager.id
val index = 1
val tag = "android:switcher:$id:$index"
val f = supportFragmentManager.findFragmentByTag(tag) as SomeFragment?
f?.someMethod()
```

今回、[ViewPager２](https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2)を使っている場合はどうすれば良いか調べてみました。
f0, f1, f2のように、よりシンプルなタグ名が付けられていました。

```kotlin:PagerActivity.kt
// 2ページ目FragmentのsomeMethodメソッドを呼び出す
val tag = "f1"
val f = supportFragmentManager.findFragmentByTag(tag) as SomeFragment?
f?.someMethod()
```

[情報源(Stackoverflow)](https://stackoverflow.com/questions/55728719/get-current-fragment-with-viewpager2)

公式情報では無いのでライブラリをアップデートしたときはご注意ください。
［Vercel］build時のタイムゾーンを設定する

## 背景

- [Vercel](https://vercel.com/)でアプリをホスティングしている場合、基本的にVercel側でアプリをビルドすることになる
- Jamstackなアプリを作っていて、ビルド時に日付を取得しAPIを叩く処理を書いていた
- しかし、ビルドしている環境のタイムゾーンが日本時間ではないようで意図した動きになっていなかった

## 解決策

- ビルド時の環境変数としてタイムゾーンを設定するとそのタイムゾーンでビルドが実行されるようになる
- vcコマンドを叩いているのであれば`-b`オプションでビルド時の環境変数を設定できる

```
vc -b TZ=Asia/Tokyo
```

- これで無事日本時間でビルドすることができた
swift4でcollectionViewでcellのサイズを変更するUICollectionViewDelegateFlowLayout追加

swift4でcollectionViewでcellのサイズを変更するUICollectionViewDelegateFlowLayout追加

    swift4以降ではclassにUICollectionViewDelegateFlowLayoutを追加する

```
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        print(view.frame.height)
        
        let width: CGFloat = view.frame.width / 7 - 1
        
        print(view.frame.height)
        if(indexPath.section == 0){
            return CGSize(width: width, height: 20)
        }else{
            if(view.frame.height>480){
                let height: CGFloat = (view.frame.height - 100 ) / 7 - 7
                print("view.frame.height>480")
                print(height)
                return CGSize(width: width, height: height)
            }else{
                let height: CGFloat = (view.frame.height - 120 ) / 8 - 2
                print("view.frame.height<=480")
                print(height)
                return CGSize(width: width, height: height)
            }
        }  
    }
```
KubernetesのdownwardAPIでFeature Toggleを実現する

## まとめ

* [Kubernetes makes Feature Flags Incredibly Simple.](https://cloudnativeclojure.org/feature-flags/annotations/2019/03/03/feature-flags.html) に書かれていたことを試してみた
 * Kubernetesのラベルをフラグとして用いる
 * Podの中のアプリからはラベルをマウントされたファイルとしてアクセスする
 * Javaのファイル監視でファイルの変更を検知し反映させる
* 良かった点
 * `kubectl label pod`でラベルを変更した後でPodを再起動しても、ラベルの変更が維持される（Podを再作成すると変更が無かったことになる）
* よくわかっていない点
 * `kubectl label`ではPod単位でしかラベルを変更できない（他に方法があるかもしれない）
 * Javaでファイルの変更を検知する方法としてWatchServiceを使いたかったが、ラベルの変更検知はできなかった（ファイルシステムの変更を検知する仕組みが動かない。commons-ioのmonitorなら検知できた）


## 実装

Kubernetesマニフェストの例。downwardAPIでラベルを`/etc/podinfo/labels`というファイルとしてアクセス可能にする。

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  selector:
    matchLabels:
      app: myapp
  replicas: 1
  template:
    metadata:
      labels:
        app: myapp
        mylabel: bar
    spec:
      containers:
        - name: myapp
          image: myapp:1.0
          imagePullPolicy: IfNotPresent
          ports:
            - name: http-port
              containerPort: 9080
          volumeMounts:
            - name: podinfo
              mountPath: /etc/podinfo
      volumes:
        - name: podinfo
          downwardAPI:
            items:
              - path: "labels"
                fieldRef:
                  fieldPath: metadata.labels
```

Podのなかで稼働するJavaアプリケーション上で`/etc/podinfo`ディレクトリのファイル変更を検知する方法

```java
public class FileMonitorThread implements Runnable {
  public void run() {
    FileAlterationObserver observer = new FileAlterationObserver("/etc/podinfo");
    FileAlterationMonitor monitor = new FileAlterationMonitor(5000L);
    FileAlterationListener listener = new FileAlterationListenerAdaptor() {
      @Override
      public void onFileChange(File file) {
        // TODO
      }
    };
    observer.addListener(listener);
    monitor.addObserver(observer);
    try {
      monitor.start();
    } catch (Exception e) {
      throw new IllegalArgumentException(e);
    }
  }
}
```

ソースコード全体は[こちら](https://github.com/hiromitsu7/featuretoggle-example)。

## 動かしてみた結果

```bash
# デプロイ
$ kubectl apply -f deployment.yaml
deployment.apps/myapp created
service/myservice created
ingress.networking.k8s.io/myingress created

# 初期状態のラベルを確認
$ kubectl get pod --show-labels
NAME                     READY   STATUS    RESTARTS   AGE   LABELS
myapp-84f4f46d68-g2lmh   1/1     Running   0          11s   app=myapp,mylabel=bar,pod-template-hash=84f4f46d68

# ファイルができている
$ kubectl exec -it myapp-84f4f46d68-g2lmh -- ls -l /etc/podinfo/labels
lrwxrwxrwx 1 root root 13 Jul 24 17:40 /etc/podinfo/labels -> ..data/labels
% kubectl exec -it myapp-84f4f46d68-g2lmh -- cat /etc/podinfo/labels
app="myapp"
mylabel="bar"
pod-template-hash="84f4f46d68"

# ラベル(mylabel)の値をfooに変更する
$ kubectl label pods myapp-84f4f46d68-g2lmh mylabel=foo --overwrite
pod/myapp-84f4f46d68-g2lmh labeled

# ファイルのmylabelの値が変わっている
% kubectl exec -it myapp-84f4f46d68-g2lmh -- cat /etc/podinfo/labels
app="myapp"
mylabel="foo"
pod-template-hash="84f4f46d68"
```
vue-cli v4.5.0 を使って Vue 3 のプロジェクトを作成する


## はじめに

昨日(7/24)に、[vue-cli v4.5.0](https://github.com/vuejs/vue-cli/releases/tag/v4.5.0) がリリースされました。
これにより、vue-cli から一発で Vue 3 のプロジェクトが作れるようになりました。
(今までは、Vue 2 のプロジェクトを作成した後に、Vue 3 に upgrade する必要がありました)

さっそく、プロジェクトの作成から起動まで行ってみましょう。

## 使い方

##### 1. 最新の `@vue/cli` をグローバルにインストールする

```sh
yarn global add @vue/cli@next
# OR
npm install -g @vue/cli@next
```

既にプロジェクトが存在する場合は対象のプロジェクトを upgrade します。

```sh
vue upgrade --next
```

##### 2. create 時に `Vue 3` を選択する

```sh
vue create <project-name>
```

```sh
# Vue 3 のpresetを使用する場合
? Please pick a preset: (Use arrow keys)
  Default ([Vue 2] babel, eslint)
❯ Default (Vue 3 Preview) ([Vue 3] babel, eslint)
  Manually select features

# マニュアルで選択する場合
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, PWA, Router, Vuex, CSS Pre-processors, Linter, Unit, E2E
? Choose a version of Vue.js that you want to start the project with
  2.x
❯ 3.x (Preview)
```

もちろん、 `vue ui` から選択することもできます。

- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110860/9b442541-48d7-b55f-7ad6-7b27513315d2.png)

インストール後、 `package.json`を見ると vue 3.0 や vuex4.0 がインストールされているのが分かります。
(なんと、 `-beta` が外れています!!)

```json
  "dependencies": {
    "core-js": "^3.6.5",
    "register-service-worker": "^1.7.1",
    "vue": "^3.0.0-0",
    "vue-router": "^4.0.0-0",
    "vuex": "^4.0.0-0"
  },
```

##### 3. 起動する

おなじみの画面が起動します。

```sh
cd <project-name>
yarn serve
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110860/431b3900-da50-2e6b-30ae-fc1a0f0e2f5a.png)

## 最後に

[起動時にエラー](https://github.com/vuejs/vue-cli/issues/5712)が出るなど、不安定ではありますが CLI から Vue 3 のプロジェクトをかんたんに作れるようになりました。
8 月上旬の Vue 3 正式リリースへの期待も高まりますね。
Moodleで教師の権限昇格が可能な脆弱性を確認してみる

# おことわり
脆弱性を試すときは必ず自分の管理する検証用のシステムで実行してください。

# この脆弱性について
2020年7月12日にあったMoodle 3.9.1を始めとする全てのアップデートで修正された、「[コース内で教師ロールを持つユーザが、本来の権限を超えたロール割り当てが可能](https://moodle.org/mod/forum/discuss.php?d=407393)」な脆弱性。つまり、この脆弱性の影響を受けるのは、**悪意のあるユーザが教師としてコースに割り当てられている**場合となる。

Moodleでは通常、教師ロールを持つユーザはコース内で学生や、編集権限のない教師（TA）を割り当てることが可能であっても、他のユーザに教師ロールを割り当てたり、教師ロールを剥奪することは出来ないようになっている。マネージャなどの、それ以上の権限についても同様である。
しかしながら、この権限チェックの不備の脆弱性を利用する事で、自分にマネージャ権限を割り当てることが可能となり、他の教師の権限を剥奪することも可能となる。とは言ってもシステム管理者には勝てないので、三日天下に終わるわけだが…

# 脆弱性を試してみる
脆弱性があるとして[修正された部分](http://git.moodle.org/gw?p=moodle.git;a=commitdiff;h=d07fb8b9e8bf47fe60ad2aea553329bd1fb96e37)から、ロール割り当てをAjaxで行うところだと分かる。適当なテスト用環境を作成し、**教師1**と**教師2**を割り当ててみる。ここで教師1が悪意のあるユーザだとする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63695/830b903e-61cd-b2ac-85db-dd1804e6969b.png)


教師1で目的のコースにアクセスし、ユーザを登録するモーダルウインドウを開いて、適当なユーザを学生として登録してみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63695/f3982ca1-dbb4-d6f7-bda8-4bbc17e57182.png)

このとき、ウェブブラウザの開発ツールでリクエストを確認すると、``https://<MOODLE.YOURDOMAIN>/enrol/manual/ajax.php?mform_showmore_main=0&id=2&action=enrol&enrolid=1&sesskey=<SESSION_KEY>&_qf__enrol_manual_enrol_users_form=1&mform_showmore_id_main=0&userlist[]=3&roletoassign=5&duration=&startdate=4`` のようなURIへのGETリクエストが確認できる。
ここで、**userlist[]=3** が対象ユーザのID、**roletoassign=5** がロールIDとなる。他のパラメータは説明省略。

このURIのうち、ユーザIDを自分のIDに、ロールIDを1に変更して、ウェブブラウザのアドレスバーに突っ込んでリクエストを送る。なぜかXMLHttpRequestで無くても問題ない。ウェブブラウザのリロード機能などでページを更新すると、マネージャ権限が付与されていることがわかる。マネージャ権限が割り当てられているので、邪魔な教師2をコースから消し去ることが可能になっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63695/070771c4-ddfe-82d5-ac2f-011635d9196d.png)

# ログで確認
ログを確認すると、変更した履歴がちゃんと残っている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63695/a0d6954a-45cd-55d7-4b77-8045580fb509.png)
Woocommerceにプロダクトをphpから複数画像付きで追加する

#はじめに

- wordpressフォルダに配置されることを想定しています。位置が変わる場合はrequire_onceのパスを変更してください。
- POSTでタイトルはtitle,説明はExplanation,画像（複数)はuploadで 受け取ります。使用方法により書き換えてください。
- SKUや価格等は今回使用しなかったため含まれていません。
- 元となったものでは動作確認をしていますが、編集後動作確認をしていません。
- 投稿用に編集しているので、不自然な箇所があるかもしれません。

#全体
受け取る側

```php
<?php
require_once("./wp-load.php");
require_once('./wp-admin/includes/media.php');
require_once('./wp-admin/includes/file.php');
require_once('./wp-admin/includes/image.php');
mb_internal_encoding("UTF-8");


$title = $_POST["title"];
$explanation = $_POST["Explanation"];
if(title){
$post_id = wp_insert_post( array(
    'post_title' => $title,
    'post_content' => "$explanation",
    'post_status' => 'publish',
    'post_type' => "product",
) );

$total = count($_FILES['upload']['name']);
$mediaarray = array();
for( $i=0 ; $i < $total ; $i++ ) {
    $attachment_id = uploadimg($i,$post_id);
    array_push($mediaarray,$attachment_id);
    }
$revarray = array_reverse($mediaarray);
setimg($post_id,$revarray);

function uploadimg($i,$post_id){
    $tmpFilePath = $_FILES['upload']['tmp_name'][$i];
    if ($tmpFilePath != ""){
    $upload = wp_upload_bits($_FILES["upload"]["name"][$i], null, file_get_contents($_FILES["upload"]["tmp_name"][$i]));
    if (!$upload_file['error']) {
    $filename = $upload['file'];
    chmod($filename, 0777);
    $wp_filetype = wp_check_filetype($filename, null);
    $attachment = array(
        'post_mime_type' => $wp_filetype['type'],
        'post_parent' => $post_id,
        'post_title' => sanitize_file_name($filename),
        'post_content' => '',
        'post_status' => 'inherit'
    );
    $attachment_id = wp_insert_attachment($attachment, $filename, $post_id);
    if (!is_wp_error($attachment_id)) {
		$attachment_data = wp_generate_attachment_metadata( $attachment_id, $filename);
		wp_update_attachment_metadata( $attachment_id,  $attachment_data );
        return $attachment_id;
    }
}
}
}

function setimg($post_id, $image_id_array) {
    set_post_thumbnail($post_id, $image_id_array[0]);
    if(sizeof($image_id_array) > 1) { 
        array_shift($image_id_array);
        update_post_meta($post_id, '_product_image_gallery', implode(',',$image_id_array)); 
    }
}
?>
```

送る側

```html
<form action="[パス]" enctype="multipart/form-data" method="post">
<input type="text" name="title">
<input type="text" name="Explanation">
<input type="file" multiple accept="image/*" name="upload[]">
</form>
```

#解説は後で書きます
Dart オブジェクト内のリストのユニーク結合

#はじめに
最近、Flutterを業務でやり始めて早2ヶ月が経ちました。
FlutterでのWidget周りは調べながらわりと理解できてきたのですが、Dart言語自体の使い勝手がいまいちわからないことだらけの日々です。
今回もiOSの時と同じように自分の備忘録兼ねて残します。

#Dartのリスト(array)加工
stack overflowで調べたりするとよく、forEachやforの記事が結構出てくるんですが、もはや最近はmap使いますよね。

```dart
var array1 = ['a', 'b', 'c', 'd', 'e'];

array1.map((e) => e + 'b')
// こちらも結果は上と同じ
array1.map((e) {
  return e + 'b';
      }
 )

// (ab, bb, cb, db, eb)
// (ab, bb, cb, db, eb)

```
こんな感じで`(e)`に配列の中身が一つずつ入ってくるので、それを使って加工することができます。
javascriptのアロー関数的なやつが使えるので、他に処理がなければ`=>`ですっきり書けますね。
ファットアロー記法と呼ばれているらしいです。

#リストの中のリストやオブジェクトの中の結合ってどうやる？
というのが本題です。
簡単なリストの加工は問題ないけど、これどうやろうかな。Swiftならreduce、set,filterあたりで色々思いつくのですが。。。

例えば、以下のようなJsonがAPIから返ってくるとします。

```json
{
  "test": {
   "strs": [
      "1","2"
    ]
  },
  "test": {
   "strs": [
      "3","1"
    ]
  },
 "test": {
   "strs": [
      "3","2"
    ]
  },
  ....
}
```

このJsonをデコードしてオブジェクトに格納する場合は、カスタムクラスは以下のようになります。
<font color=red>※Jsonのデシリアライズ処理は省きます。</font>

```dart
class Test {
  final List<String> strs;
  
  Test({
    this.strs,
  });
}
```

先ほどのJsonからパースすると以下のようになります。

```dart
var testList = jsonパースする処理;
print(testList.toString());
// [Instance of 'Test', Instance of 'Test', Instance of 'Test']
```
そもそも論でいくと、APIから別でstrsの全種類を網羅したリストをjsonで返してもらうのがシンプルパターンかと思いますが、今回はそれは置いときます。
やりたいこととしては、

**・Testクラスの中にある`strs`をまとめた1つのリストが欲しい。 (つまり、構造はシンプルな1次元のリスト構造)**
**・かつstrsは重複していることもあるのでユニークにしたい。**

そんな時は、これです。

```dart
var testList = jsonパースする処理;
// こいつでまずstrsの配列に加工する
var result = testList.map((e) => e.strs);
// 結果： ([1, 2], [3, 1], [3, 2])

// 次にreduceを使ってすべてstrsの配列同士を結合する
var result2 = result.reduce((a, b) => a+b);
// 結果： [1, 2, 3, 1, 3, 2]

// 最後に.toSet()を使って重複を排除、それを.toList()で再びリスト型にキャストする
var result3 = result3.toSet().toList();
// 結果： [1, 2, 3]
```
めでたく、オブジェクト内のリストのユニーク結合ができました。
正確には、オブジェクトのリストを加工して、`strs`ごとのリストを作り、それらを結合をしてからユニークなものにリデュース(減らす)するとなります。

まとめないと冗長なので最後に綺麗にして完成。

```dart
testList.map((e) => e.strs)
        .reduce((a, b) => a+b)
        .toSet().toList();
```

#余談
最近知ったんですが、Dartって便利な演算子や記法が結構ありますよね。
その中でスプレット演算子なるものを知ったので載せておきます。

単純に結合したい場合は、変にするよりこのようにスプレット演算子を使用するのも良いと思います。
FlutterのRowやColumnのchildren[]で使ったりできるので、結構用途あるかと。

```dart
// スプレッド演算子
var l1 = [1, 2];
var l2 = [0, ...list1];
print(l2.length);
// 3

// null対応スプレッド演算子
var l3;
var l4 = [0, ...?l3];
print(l4.length);
// 1
```

#参考記事
・リストでよく使うメソッドまとめ
[Top 10 Array utility methods you should know (Dart)](https://codeburst.io/top-10-array-utility-methods-you-should-know-dart-feb2648ee3a2)
・型について
[おとなしく Dart のお勉強【型】](https://notes.tret.jp/dart-tour-built-in-types/)

#まとめ
調べればわかる内容だと思うので、改めて書くほどのことでもないかもしれませんが、
このあたりパッと出てくれば結構、ぐぐる時間削減できるので、など他の早く網羅したいものです。
もっといい方法ありましたらアドバイスお待ちしております。
最後までご覧いただきありがとうございました！
Android Studio で背景をダークモードに変更する

今日はAndroid Studioで背景をダークモードに変えてカッコよく見せたい！！
けどどうやってやるんだろう・・・で5分くらい悩んだので書くことにしました。

初投稿がこんなんでいいのか。いいんです(言い聞かせ)
なんせ初投稿なので書き方もろくに分かってない。ご容赦ください🙏

----------前提----------
・macOS Catalina 10.15.3
・Android Studio 4.0.1
・日本語plugin(pleiades-mac)を使用している
----------前提----------

前提条件に不足があったら編集しますがわからなくなった原因が日本語プラグインなので記載しておきます。。

ググればすぐ出るだろうと思いググった。
https://www.youfit.co.jp/archives/733

なんと日本語プラグインのおかげでファイル(File)選択時に
>Settings画面で、[ Appearance & Behavior ]　＞　[ Appearance ]
がないではありませんか。

これだけならよかったんです。

元々自分の環境でコード書いていたので(超簡単なやつ)、日本語プラグイン関係なしに
[外観と振る舞い]が選択肢になかったんです。
でもとりあえず他に方法ないかと思ってさらにググりました。
※この直前にAndroidStudioをアップデートしていたので選ぶ場所が変更されたのでは？という考えからです。

ググっても出てこなかったんですけどね。。
もしかして今すでに開いているのが原因か！？と思い立ってAndroidStudioさんを落として立ち上げてみた。
構成・・・もしかして。。

<img width="1106" alt="スクリーンショット 2020-07-25 1.57.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680258/084c1d0b-66a4-8771-e9d1-8cef5c58bf95.png">

アッはーい。
あとは
https://www.youfit.co.jp/archives/733
に記載の通り[Darcula]を選択してあげればちゃんとダークモードになりました。

めでたしめでたし。
GitHub Actionsでコマンド失敗時の実行結果をIssueに貼り付けて投稿する

# はじめに

先日GitHub Pagesを使って[自己紹介ページ](https://yktakaha4.github.io/)を作成したのですが、
外部リンク先が404になっていたらカッコ悪いので、GitHub Actionsでリンク切れをチェックするワークフローを定期実行することにしました🚨

リンク切れのチェック自体は[markdown-link-check](https://github.com/tcort/markdown-link-check)というナイスなパッケージを使ってすぐに実現できたのですが、
出力結果をIssueとして投稿しようとした時に、以下を実現しようとして少しハマったため共有します

- `npm run`の結果をcode記法で本文に貼り付けたい
    - もっと言うと、Issue Templateの中に埋め込んで投稿したい
- `npm run`が失敗した時だけIssueを作成したい

# 作ったもの

[こちら](https://github.com/yktakaha4/yktakaha4.github.io/blob/source/.github/workflows/schedule.yml)で動いてる実物に、コメントをつけてご紹介します🌾
なおテンプレートは[こちら](https://github.com/yktakaha4/yktakaha4.github.io/blob/source/.github/issue_template_link_check.md)です

```yaml:schedule.yml
name: Schedule

on:
  schedule:
    - cron: 0 0 * * 0 # 日本時間の毎週日曜9時に定期実行

jobs:
  schedule:
    name: Check
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v1
        with:
          node-version: '12'
      - run: npm install
      - id: check_link # idを設定して、後続のstepで参照できるようにする
        run: npm run check:link > ./out/check_link_result.txt # 実行結果をファイルに出力
        continue-on-error: true # このステップの終了ステータスが0以外でもエラーにせず、後続のステップを実行する
      - run: | # ::set-env を使って環境変数を後続ステップに渡す際に、改行コードのエスケープが必要なので実施する
          CHECK_LINK_RESULT="$(cat ./out/check_link_result.txt)"
          CHECK_LINK_RESULT="${CHECK_LINK_RESULT//'%'/'%25'}"
          CHECK_LINK_RESULT="${CHECK_LINK_RESULT//$'\n'/'%0A'}"
          CHECK_LINK_RESULT="${CHECK_LINK_RESULT//$'\r'/'%0D'}"
          echo "::set-env name=CHECK_LINK_RESULT::$CHECK_LINK_RESULT"
      - uses: JasonEtco/create-an-issue@v2
        if: steps.check_link.outcome == 'failure' # steps.ステップのid.outcome で、ステップ毎の実行の成否をチェックできる
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          CHECK_LINK_RESULT: ${{ env.CHECK_LINK_RESULT }} # テンプレート内で {{ env.XXX }} の形式で値を参照
        with:
          filename: .github/issue_template_link_check.md
      # Actionsとしては、 check_linkステップの成否に関わらず成功として扱われる
      # （それ以外のステップでエラーとなった場合は失敗となる）
```

エラーとなると、こんな感じでIssueを投稿してくれます💺
いい感じ...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106259/221f89b2-a7d4-8813-8abf-45cdab863197.png)

# 参考にしたもの

- https://docs.github.com/ja/actions/reference/context-and-expression-syntax-for-github-actions
- https://docs.github.com/ja/actions/reference/workflow-commands-for-github-actions
- https://github.community/t/set-output-truncates-multiline-strings/16852
AppSheetで外部APIを使用してQRコードを生成する（外部API利用）

# はじめに
相手にURLなどある程度の長さがあるテキスト情報を渡す際に、
メールやラインなどだと手間がかかるためQRコードにて送付できると楽。

# 考え方
1. QRコード生成APIのドキュメントを読み、API呼び出しの方法を確認する
2. カラムの式にAPIを設定する

# 設定方法
①QRコードの呼び出し方法を確認する。
QRコードAPI：コマンド「create-qr-code」（QRコードの生成、QRコードジェネレーター）
http://goqr.me/api/doc/create-qr-code/

を読む限り、最低限だと
"https://api.qrserver.com/v1/create-qr-code/?data=好きなテキスト"
で生成ができる。


②カラムの式に設定する
カラムを新規で作成して、式に以下のように入力
[体温]の部分はQRコード化したい元テキストのカラム名に変更する。
![コメント 2020-07-25 015023.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129423/54135e04-a6f5-28c2-63de-4ebc2f44f6b6.png)

カラムタイプをimageにすることを忘れない
![コメント 2020-07-25 015309.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129423/0bf81879-06b2-3f19-2a59-f4b4cb2716ef.png)


# テスト
プレビューにて、指定したテキストのQRコードが生成されていればOK
![コメント 2020-07-25 015449.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129423/2228a9b3-aa7a-cd05-2249-3c48e7060511.png)


# ＋Tips
QRコード生成APIに限らず、グラフ作成APIなども同じようにして利用することができる。

# 参考ページ
QRコードAPI：コマンド「create-qr-code」（QRコードの生成、QRコードジェネレーター）
http://goqr.me/api/doc/create-qr-code/


## ノーコード開発もくもく会のおしらせ
毎月1回ぐらい、「Play (No) Codes!」というグループ名でノーコード開発もくもく会をしています。
基本オンライン＋オフラインで実施しているので、よければ参加ください。
https://playnocodes.connpass.com/
GitHubってなに？

#1. はじめに
プログラミングを始めたての人ならすぐに見かける「GitHub」というワード。

ただでさえアルファベット多くて大変なのに、急に出てきたこいつ何だ？と思った方もいるのではないでしょうか？

今回は「GitHubってなに？」というのを極力簡単にお伝えします。

#Gitとは
Gitとはプログラムを管理する分散型の管理システムのこと。

....?

うん、「分散型」というよくわからん言葉はいったん置いときましょう。

とにかく基本はプログラム（書いた文字でコンピューターが動くもの）を管理できる仕組みの事です。

#システム＝「もの」
システムも一つの「もの」です。
なので作るためには細かい部品（つまり機能だったり見た目だったり）が合わさって出来上がります。

車を作るためにも、タイヤ、エンジン、ハンドル、車体などいろいろ必要ですよね。
そしてそれぞれを作る人がいます。

Gitによってそれが誰がどの部分を作っているのかが分かります。

#システムは実体がない
ここまでは現実世界で物を作るのと変わらないですが、システムは実体がありません。
なので、プログラムの変更履歴を見たり、戻ったりすることができます。

どういうことかというと、車の部品は接続部が曲がれば、うまく組み立てができないし、塗装が間違った色にしてしまうとその車は台無しになります。
しかしシステムは実体がないため、接続部が間違っていたら修正できるし、色が違えば変えられる、つまり再修正できる特徴があります。

この特徴もGitで活かされています。

#「分散型」であること
ここでもう一つの大きな特徴が、先ほど保留してた「分散型」であること。

プログラムは2つの空間で保存ができます。
それがローカルリポジトリとリモートリポジトリ、いわゆるプログラム用の「倉庫」です。
ローカルリポジトリ＝自分だけの倉庫、リモートリポジトリ＝みんなの倉庫と捉えてください。

昔は実は「集中型」といって、みんなの倉庫から部品を取り出して作ってみんなの倉庫に戻す作業を行っていました。
しかしそれではみんなの倉庫にいける環境（サーバーにアクセスできる状態）でないと作業が進められないデメリットがありました。

そこで自分だけの倉庫を持つ事でそこから作業を進めることができるし、動作確認を行ってからみんなの倉庫に収納することができるようになりました。

これも実体がないものなのでコピーが自由できるからこそ可能な特徴です。

#それで「GitHub」って？
ここまででGitという仕組みの意味はなんとなくわかったと思います。

戻りますが、GitHubはそのGitという仕組みの中の一つのサービスです。
（どのスケジュールアプリ使うかとか、どのメモアプリが最適かというの一緒です。）


#まとめ
システム開発をより便利に、円滑に、かつミスなく進めるためのツールです。
ゲームで言うとセーブポイントですね（←伝わる？）
システム開発は基本チームで作ることがほとんどです。
しっかりGitの使い方は学んでおきましょう！
ssh ログインしている人をslack に晒す

# やりたいこと
雪犬は、素人のためセキュリティが非常に弱い！
誰かに入られてもわからない！
サーバー怖い！

という事で、sshログインしているかどうかを確認したい。

なので、ただソースコピペしてパパーっとやりたい人向け。
★改行したい、ダブルクォート挟むなどの場合は、別のソースを探してください。

# 出来なかった事
- リアルタイムでのログイン確認
- 実行コマンド内の改行?空白?を改行としてそのまま送信

# やること
- スクリプト： ssh ログインの確認, slack にbotとして送信
- CRON: X分, X時間毎に実行させる

# ssh ログインの確認
[こちら](https://blog.mamansoft.net/2019/11/27/slack-notification-shell-script/) の方のソースを使わせていただいております。
詳細はサイトをご確認ください。

コマンド `who` `w` でssh がログインしているユーザを確認出来る。
変数`msg`へコマンドを代入し、それを送信している、というスクリプト。

```slack.sh
#!/bin/bash

set -eu

msg=`w`

SLACK_WEBHOOK_URL="https://hooks.slack.com/services/XXXXXXXXXXXXXXXXXXXXX"

post_slack() {
  channel="#bot"
  user="my_bot"
  emoji="ghost"
  message=${msg}
  # list: good / danger
  color=""

  file=$(mktemp)
  trap "rm ${file}" EXIT

  cat << EOJ > $file
    {
      "link_names": 1,
      "channel": "${channel}",
      "username": "${user}",
      "icon_emoji": ":${emoji}:",
      "attachments": [
        {
          "color": "${color}",
          "text": "${message}"
        }
      ]
    }
EOJ

  curl -s -S -X POST -d @$file ${SLACK_WEBHOOK_URL}
}

post_slack
```

# X分、X時間毎に実行する
[参考 cronサイト](https://memorva.jp/memo/linux/cron.php)

```
# リストの確認
$ crontab -l
# 編集
$ crontab -e
```

`crontab -e` を実行したら、vi と同じになるので、以下のように追記

```
# 3分毎に実行
*/3 * * * * /home/user/slack.sh
# 1h毎に実行
0 */1 * * * /home/user/slack.sh
```

# 最後に
お疲れさまでした。
別のソースで、改行やダブルクォート対応ソースあったのですが、知識なさすぎて・・・実行出来なかったので＞＜

本来はリアルタイムで通知したかったんですが、どうやったらリアルタイムで持ってこれるかわからず!!
ログの更新がされたら〜とかっていう事なのかも？？？

知識なくてわかりませんが、とりま現状はこの運用で。

ではではではではー、雪犬-snowdog-でした★
Neo4j: Nodeのキャプションを別のPropertyに変える

Neo4j Browser を使うと Node 間のリレーションがグラフィカルに表示される事で、全体の繋がりを容易に知る事ができる。

この時、デフォルトで name property がキャプションに使われるが、Nodeの設計次第では name property が無かったり、別の Property をキャプションに使いたい場合も出てくる。

## キャプションが表示されない例

以下の図では name property に値が入っていないためキャプション表示されない Nodeが存在する。
<img width="894" alt="neo4j - Neo4j Browser 2020-07-25 01-22-39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1576/ebbee464-bc0e-fc10-00b9-1f6e19417841.png">

以下の図はとても見辛く、せっかく繋がりがグラフィカルに表示されていても全然使えない。

## キャプションを別の property に変える

変更したい Node を選択。上でキャプションを変更したい Label を選ぶと最下部にその Label の Style 設定が表示される。

<img width="898" alt="neo4j - Neo4j Browser 2020-07-25 01-24-12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1576/77a1997a-e2be-1105-24dc-a1e8792c0ba3.png">

右下の三角形をクリックするとキャプションを選択できるようになる。

<img width="901" alt="neo4j - Neo4j Browser 2020-07-25 01-26-14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1576/8229870c-6baf-5682-9207-e527c8dbd3cc.png">

自分がその Label のキャプションとして表示したい property を選択すると Node のキャプションが変わる。

<img width="901" alt="neo4j - Neo4j Browser 2020-07-25 01-34-09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1576/ed3f7b52-0628-61a9-d6a8-dbc3c0c43946.png">


全部の Node のキャプションが表示されてみやすくなりました。
Swift5で特定のタブを無効にする方法

# 初めに
今回は特定のタブバーを無効にする方法を展開します。

##実装 
例えばある以下のタブがあるとします。
<dl>
  <dt>TabBarContlloer</dt>
  <dd>Tab:0 ・・・・ test.swift</dd>
  <dd>Tab:1 ・・・・ test1.swift</dd>
  <dd>Tab:2 ・・・・ test2.swift</dd>
</dl>
![IMG_0035.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397376/caaaf3c8-b048-ef87-db2f-3c8507143888.png)


test1.swiftのタブを何かの理由でユーザに押されたくないとき以下のコードを`test.swift`で実行すると押されなくなります。(すいません。説明下手くそで。。)

```swift:test.swift
//タブの番号
let tagetTabBar = 1
//タブの無効化
self.tabBarController!.tabBar.items![tagetTabBar].isEnabled = false
```

# 最後に
これで完了です。
お疲れ様でした。
AppSheetでテーブルをフィルタした結果をプライマリビューに表示する（スライス設定）

# はじめに
経費申請アプリなどで

- 承認が遅れている申請を随時表示したい
- 10万円以上の申請を常時表示したい

などフィルタ設定せずに、いつも見たい情報をトップ画面（プライマリビュー）に設定する方法。
もっと良い方法があれば教えてもらえると助かります。

# 考え方
1. data　→　Slice　にてフィルタ設定（スライス）を行う
2. UX　→　Addnewview　→　For this data　フィルタ設定したSliceを設定しプライマリビューに表示

# 設定方法
①新規スライス作成画面にて、以下設定をする。

- ソーステーブル：対象テーブルを指定
- 行filter条件：フィルタ条件を記載、関数利用可
- スライス列：列全体か、指定列の場合列を指定
- スライスアクション：スライスされた結果に対して、どのアクションが可能かの設定（二つ目イメージ）

![コメント 2020-07-25 011142.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129423/c2c93d6c-d2db-1c50-c60b-8b739b94541f.png)
![コメント 2020-07-25 011751.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129423/f6abca5f-3696-dfc0-82ab-a8ff83432836.png)

②UXの新規view作成画面で、以下設定をする。

- このデータについて：さきほど作ったスライスを指定

![コメント 2020-07-25 011212.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129423/f118dd10-9037-d8b7-5d6e-c3aafd99d0bb.png)

# テスト
アプリプレビューにて、フィルタ結果が反映されたビューが閲覧できること

# 参考ページ
Slices: The Essentials
https://help.appsheet.com/en/articles/895302-slices-the-essentials


## ノーコード開発もくもく会のおしらせ
毎月1回ぐらい、「Play (No) Codes!」というグループ名でノーコード開発もくもく会をしています。
基本オンライン＋オフラインで実施しているので、よければ参加ください。
https://playnocodes.connpass.com/
Python：クラスで多重継承

#Pythonで多重継承
多重継承するサンプルコードは以下の通り。

```Python:samplePython.py
#
#　　　2020.07.25 ProOJI
#

# 人は話す
class Person(object):
	def talk(self):
		print('talk.')

# 車は走る
class Car(object):
	def run(self):
		print('run.')

# ロボットは飛ぶ
class PersonCarRobot(Person, Car):
	def fly(self):
		print('fly.')

# インスタンス生成
person_car_robot = PersonCarRobot()
person_car_robot.talk()
person_car_robot.run()
person_car_robot.fly()

# 出力結果
# talk.
# run.
# fly.
```
`class Person`と`class Car`を継承すると
`class PersonCarRobot`になります。
ここまでは普通。

さてここで同じメソッドを継承した場合どうなるのか実験してみました。
そもそも人も走るものですので、`class Person`にもrunを作成してみました。
以下のようにコードを修正しました。

```Python:
# 人は話す そして走る
class Person(object):
	def talk(self):
		print('talk.')
    """ ここを追加 """
	def run(self):
		print('Person-Run.')

# 車は走る
class Car(object):
    """ 同じ runメソッド となり重なってしまう """
	def run(self):
		print('Car-Run.')
```
この場合の出力結果は、

```Python:
# 人は話す そして走る
class Person(object):
	def talk(self):
		print('talk.')
	def run(self):
		print('Person-Run.')

# 車は走る
class Car(object):
	def run(self):
		print('Car-Run.')

# ロボットは飛ぶ
class PersonCarRobot(Person, Car):
	def fly(self):
		print('fly.')

# インスタンス生成
person_car_robot = PersonCarRobot()
person_car_robot.talk()
person_car_robot.run()
person_car_robot.fly()

# 出力結果
# talk.
# Person-Run.
# fly.
```
##多重継承のクセとして…
多重継承の結果として、同じメソッドを作成して重複する場合

```Python:
# ロボットは飛ぶ
class PersonCarRobot(Person, Car): # <=左側のPersonが優先
```
左側のPerson内にある`run`が実行されCar内の`run`は実行されません。
試しに左右を逆にしてみると、

```Python:
# ロボットは飛ぶ
class PersonCarRobot(Car, Person):# <=左側のCarが優先
	def fly(self):
		print('fly.')
# 出力結果
# talk.
# Car-Run.
# fly.
```
となりました。
#まとめ
クラスを継承する際には、このクセを理解した上で進めることが必要かなと思いました。
できるだけ多重にならない継承を心がけた方がバグに繋がらないので、設計段階で気をつけることも必要かとも思いました。ただコードの量も増えてくるとどうしてもこういうケースも出没するかもしれません。気をつけないと…
Visual Studio Code プラグインを使ってssh接続先のファイルを接続元のウインドウで開く

# 目的

- とても便利なプラグイン「Remote Development」の導入方法と簡単な使い方を紹介する。

# 実施環境

- ssh接続元ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ssh接続元ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| VS Code バージョン | 1.47.1 | こちらの方法で導入→[~簡易版~ Mac Visual Studio Code に Remote Development を 導入 しよう](https://qiita.com/miriwo/items/287d8967e6a31c1ac0a8) |

- ssh接続先ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | CentOS 7 (7.8.2003) |
| ハードウェア | Dell Studio 1537 |
| プロセッサ | Intel(R) Core(TM)2 Duo CPU     P8400  @ 2.26GHz |
| メモリ | 4 GB DDR3 |
| グラフィックス | 不明 |

# 概要

1. ssh configの記載
1. プラグインのインストール
1. ssh接続

# 詳細

1. ssh configの記載
    1. まだssh configの作成、記載を行っていない場合は下記コマンドを実行して作成を行う。

        ```terminal
        $ vi ~/.ssh/config
        ```
    1. 開いたconfigファイルを下記の様に記載する。

        ```~/.ssh/config
        Host 接続先名(任意)
            HostName 接続先IPアドレス
	    User 接続先ユーザ名
        ```
1. プラグインのインストール
    1. プラグイン検索ウインドウを開く
    
        ![okawashun.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/557d183b-088a-7923-3f44-3c34ab98b7ce.png)

    1. 検索ウインドウにに「Remote Development」と入力して検索する。

        ![okawashun.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/8d52e103-2f23-1033-5117-215283bc76d8.png)

    1. 下記矢印部分をクリックしてプラグインをインストールする。

        ![okawashun.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/6f728f97-86a8-8e01-4dd9-fe9049891cd6.png)

    1. 一つインストールするだけで関連プラグインも一緒にインストールされる。

        ![スクリーンショット_2020_07_22_11_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/06792652-de12-c214-ffd9-cad50ff5022e.png)

1. ssh接続
    1. プラグインをインストールするとサイドバーに専用アイコンが追加されるのでクリックする。

        ![okawashun.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/d21de4a4-d834-21bf-1b5f-5cdccc05bfd2.png)

    1. 先にssh configに記載した接続先名が表示されているのでクリックする。

        ![okawashun.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/a1d0b7f4-2310-1178-f8a5-2244bb201f7b.png)

    1. 下記のアイコンをクリックする。

        ![okawashun.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/00b1748c-8e7e-4cd1-3aba-38314fa527cd.png)

    1. 新しいVS Codeのウインドウが開き、ssh接続先のパスワード入力を求められるので入力してEnterをw押下する。

        ![スクリーンショット_2020_07_22_11_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/2f0d5d95-6afc-bb94-4736-23becd5c2ccc.png)

    1. 接続先の名前がウインドウに表示されれば接続完了である。

        ![スクリーンショット_2020_07_22_11_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/9a4e76ea-dea2-f6c4-d74d-62cb6f037b04.png)
回転うんこCSSの開発に成功した

#動機
ページのタイトルをみて兄者たちは何のことを言っているのかさっぱりわからないと思われる。頭のおかしいヤツがいると思われたら悲しいので、説明させてください。

画像を見ればすべての疑問は氷解するハズ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647892/9fcbbbb2-ec3c-edd8-2bea-a0bf0ad870a0.png)

やったぜ！
#実装内容

```html:
    <style>
        .circlenizer{
            overflow: hidden;
            border-radius:50%;
            background-color: rgb(82, 22, 22);
            color:whitesmoke;
            box-shadow: 0 5px 5px 0 rgba(0, 0, 0, .8);
        }
        .circlenizer__edit-area{
            width:200%;
            height:200%;
            position: relative;
            top:-50%;
            left:-50%;
        }
        .circlenizer__edit-area__transform{
            transform: rotate(-45deg);
            top:14.5%;
            left:14.5%;
            width:71%;
            height:71%;
            display:table;
            overflow: hidden;
            position:relative;
            transform-origin: center;
        }
        .circlenizer__edit-area__transform__target{
            display:table-cell;
            vertical-align: middle;
            text-align:center;
        }
    </style>
    <div class="circlenizer" style="height:100px;width:100px;margin:50px;">
        <div class="circlenizer__edit-area">
            <div class="circlenizer__edit-area__transform">
                <div class="circlenizer__edit-area__transform__target">
                    <span style="font-size:50px;">💩</span>
                </div>
            </div>
        </div>
    </div>
```
#苦労した点
💩を真ん中に寄せるのが案外難しかった。
vertical-alignはtable-cellに効くけど、display:table-cellにheight,widthでパーセントが効かないので、中間にdisplay:tableを挟むことで何とかなった。
#説明
まあ、回転させるだけなら割と簡単にできるのだけど、なるべく汎用的なCSSにしたかった。
なので一応全部パーセント指定でいい感じになっていて、circlenizerブロックにだけwidth,heightを指定してあげればいい感じに動く、circlenizer__edit-area__transformのところをぐりぐり動かせば、いろいろな角度だったりおっきな💩が楽しめるのでどうだろうか。

#まとめ
私は頭がおかしくありません。（主張）
Qt Androidで外部ストレージにアクセス出来ない場合に試すこと

# 概要
Qt Creatorを使って書いたソフトウェアでAndroidのストレージにアクセスしようとしても「permission denied」となりハマりました。
インターネットで調べても中々これだ！という記事が見つけられず困ったので記事として残そうと思います。

Qtを使ったAndroid開発は初心者です。
こうするのが今の主流だ！などがあれば、是非ご指摘ください。

# 確認環境
Qt Version : 5.13.1
Qt Creator : 4.10.0

# 解決方法
以下の設定を行う必要があります。

1. 「AndroidManifest.xml」にて「android.permission.READ_EXTERNAL_STORAGE」を追加します。しかし、API Level 24以降(?)ではうまくいきません。
    ![androidPermission.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680230/4b7e1109-6466-a12c-4c30-fb07933dab72.png)

2. 以下のようなコードを書き、呼び出すことでAndroidデバイス上で「〇〇へのアクセスを許可しますか？」という確認ダイアログを表示させることが出来るようです。ダイアログ上で許可することでソフトウェアはAndroidストレージへアクセス出来るようになります。肝は「requestAndroidPermissions」メソッドになります。

```cpp:main.cpp

#if defined (Q_OS_ANDROID)
#include <QtAndroid>

bool requestAndroidPermissions(){
    //Request requiered permissions at runtime

    const QVector<QString> permissions({"android.permission.READ_EXTERNAL_STORAGE"});

    for(const QString &permission : permissions){
        auto result = QtAndroid::checkPermission(permission);
        if(result == QtAndroid::PermissionResult::Denied){
            auto resultHash = QtAndroid::requestPermissionsSync(QStringList({permission}));
            if(resultHash[permission] == QtAndroid::PermissionResult::Denied)
                return false;
        }
    }

    return true;
}
#endif
~
int main(int argc, char *argv[])
{
#if defined (Q_OS_ANDROID)
    if(!requestAndroidPermissions())
        return -1;
#endif
~
```

# 参考にしたサイト様
- http://amin-ahmadi.com/2015/11/29/how-to-add-permissions-to-your-qt-android-app/
- https://forum.qt.io/topic/100134/android-runtime-permissons

# 終わり
一つのソフトウェア完成までの道のりは長いです...。Qiita、Qt Forum、Qtの公式ドキュメントには毎回助けられています。ありがとうございます。
[Python]オブジェクトの属性にアクセスしたときの挙動

Pythonの属性にアクセスしたときの挙動が[この記事](https://www.lifewithpython.com/2018/09/python-attribute-access-internal-flow.html)にまとめられていたのですが、忘れそうなのでコードの形式で整理しておきます。

```python
class MyGetDescriptor:
    def __init__(self, msg):
        self.__msg = msg
    def __set_name__(self, owner, name):
        self.__name = name
    def __get__(self, instance, owner):
        return self.__name + " " + self.__msg
    def __set__(self, instance, value): # これは必要
        pass
class ClassA:
    get1 = MyGetDescriptor("A Descriptor")
    get2 = MyGetDescriptor("A Descriptor")
    get3 = MyGetDescriptor("A Descriptor")
    get4 = MyGetDescriptor("A Descriptor")
    get5 = MyGetDescriptor("A Descriptor")
    get6 = MyGetDescriptor("A Descriptor")
    get7 = "get7 ClassA"
    def __getattr__(self, name):
        if name in ["get1", "get2", "get3", "get4", "get5", 
                "get6", "get7", "get8", "get9"]:
            return name + " A.__getattr__"
        else:
            return super(self.__class__, self).__getattr__(name)
    def __getattribute__(self, attr):
        if attr == "get1":
            return "get1 A.__getattribute__"
        elif attr == "get2":
            return "get2 A.__getattribute__"
        else:
            return super(ClassA, self).__getattribute__(attr)
class ClassB(ClassA):
    get1 = MyGetDescriptor("B Descriptor")
    get2 = MyGetDescriptor("B Descriptor")
    get3 = MyGetDescriptor("B Descriptor")
    get4 = "get4 ClassB"
    get5 = "get5 ClassB"
    def __init__(self):
        self.get1 = "get1 InstanceB"
        self.get2 = "get2 InstanceB"
        self.get3 = "get3 InstanceB"
        self.get4 = "get4 InstanceB"
    def __getattr__(self, name):
        if name in ["get1", "get2", "get3", "get4", "get5", 
                "get6", "get7", "get8"]:
            return name + " B.__getattr__"
        else:
            return super(self.__class__, self).__getattr__(name)
    def __getattribute__(self, attr):
        if attr == "get1":
            # ここでself.__dict__を参照すると__getattribute__(self, '__dict__')が呼ばれる)
            return "get1 B.__getattribute__"
        else:
            return super(ClassB, self).__getattribute__(attr)
            # super(ClassB, self)をsuper(self.__class__, self)にするとスタックオーバーフロー

b = ClassB()
print(b.get1)   # get1 B.__getattribute__
print(b.get2)   # get2 A.__getattribute__
print(b.get3)   # get3 B Descriptor
print(b.get4)   # get4 InstanceB
print(b.get5)   # get5 ClassB
print(b.get6)   # get6 A Descriptor
print(b.get7)   # get7 ClassA
print(b.get8)   # get8 B.__getattr__
print(b.get9)   # get9 A.__getattr__
print(ClassB.get5)   # ClassB
print(ClassB.get6)   # A Descriptor
```

よって、属性を取得するときは以下の順番で確認していることがわかります。

- 該当クラスの`__getattribute__`
- 親クラスの`__getattribute__`
- Descriptorを用いた該当クラスのメンバ
- 該当インスタンスのメンバ
- 該当クラスのメンバ
- - Descriptorを用いた親クラスのメンバ
- 親クラスのメンバ
- 該当クラスの`__getattr__`
- 親クラスの`__getattr__`
JS初心者がKintoneカスタマイズ行うために その2

###お疲れ様です〜「りょうちん」です。
####やーKintoneのカスタマイズ難しいです！
というのも「Kintone JavaScript API」と「Kintone REST API」という関数群が存在するのですがごっちゃになってました。

[kintone rest apiとjavascript apiに関して](https://developer.cybozu.io/hc/ja/community/posts/360022663012-kintone-rest-api%E3%81%A8javascript-api%E3%81%AB%E9%96%A2%E3%81%97%E3%81%A6)
[kintone カスタマイズでできること](https://developer.cybozu.io/hc/ja/articles/360039349172)
[kintone 連携カスタマイズでできること](https://developer.cybozu.io/hc/ja/articles/900001164063)

同じく迷ってる人はこの辺り参考にしてみるといいかも知れません。

まだ完全に把握出来ていませんが、
Kintone JavaScript APIはKintoneの動作や見た目の変更できるAPI。
Kintone REST APIは主にkintoneアプリのレコード操作等が行えるAPI。という認識です。

>[kintone rest apiとjavascript apiに関して](https://developer.cybozu.io/hc/ja/community/posts/360022663012-kintone-rest-api%E3%81%A8javascript-api%E3%81%AB%E9%96%A2%E3%81%97%E3%81%A6)
>>両者に関係があるとすれば、kintone JavaScript APIで準備されているkintone.api() という関数を使うと、JavaScriptでkintoneのREST APIの操作が多少容易に行えるというくらいです。

上記の引用の通りですが、両者は切り離して考える方が理解しやすくなると思います。

####では、また次回！