ゆうは

わかりたいことを深堀り

JavaScriptとPythonを両方書く人へ!言語ごとにフォーマッターを自動で切り替える設定

最近、メインのJavaScriptに加えて、またPythonも触る機会が増えてきました。

複数の言語を併用し始めると、地味にストレスになるのが「コードの自動整形(フォーマッター)」。 「JavaScriptを書いてる時はPythonの整形が効かないし、逆もしかり……」なんてこと、ありませんか?

今回は、VSCode(Visual Studio Code)で言語ごとにフォーマッターを賢く使い分けるための、簡単な設定方法を調べてみました!

設定手順:settings.jsonに追記するだけ

設定はとても簡単です。 VSCodeの設定ファイルに数行追加するだけで解決します。

  1. Ctrl + Shift + P(Macは Cmd + Shift + P)を押して、コマンドパレットを開きます。
  2. 「Preferences: Open User Settings (JSON)」 と入力して選択します。
  3. 開いた settings.json の中に、以下の記述を追加します。
{
  // JavaScript(デフォルト)は Prettier を使う
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,

  // Python は Black を使う
  "[python]": {
    "editor.defaultFormatter": "ms-python.black-formatter"
  }
}

まとめ

これで、ファイルを保存(Save)するだけで、JavaScriptならPrettier、PythonならBlackが自動で動いて綺麗に整形してくれるようになります!

言語を切り替えるたびに設定を気にする必要がなくなるので、開発がめちゃくちゃ快適になりますよ。同じ悩みを持つ方はぜひ試してみてください!

Processingの本のニュートン力学をCanvasで作ってみた

最近JavaScriptのCanvasを勉強しています。
主に本で勉強しているのですが、Canvasの本がかなり少ないです。なので、Processingの本も活用しつつやっています。

ニュートン力学

今回は「Processing クリエイティブ・コーディング入門 ―コードが生み出す創造表現」の第6章の「ニュートン力学でリアルな表現」をCanvasで作ってみました。

「ニュートン力学でリアルな表現」とは、ここではボールが突かれて、下に落ちていき、床で跳ねるアニメーションです。

X

作ったものをXにアップしています。

加速度と速度と位置

まず、右下に移動するだけのアニメーションを作ります。 動きはざっくりと以下の引用の通りです。

acceleration = force * mass; // 力と質量から加速度を求める
velocity = velocity + acceleration; // 加速度から速度を求める
location = location + velocity; // 速度から位置を求める

Canvasで作ったコードは以下となります。 setでゼロにしているのは、forceがあるのは最初だけだからです。

let canvas, ctx;
let force, acceleration, velocity, position, mass;

window.addEventListener("load", init, false);

function init() {
  canvas = document.getElementById("myCanvas");
  ctx = canvas.getContext("2d");

  setup();
  loop();
}

class Vector {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  set(x, y) {
    this.x = x;
    this.y = y;
    return this;
  }

  add(vector) {
    this.x += vector.x;
    this.y += vector.y;
    return this;
  }

  mult(scalar) {
    this.x *= scalar;
    this.y *= scalar;
    return this;
  }
}

function setup() {
  position = new Vector(0, 0);
  velocity = new Vector(0, 0);
  force = new Vector(3, 2);
  mass = 1;
  acceleration = force.mult(mass);
}

function haikei() {
  ctx.fillStyle = "white";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.strokeStyle = "black";
  ctx.strokeRect(0, 0, canvas.width, canvas.height);
}

function loop() {
  haikei();

  velocity.add(acceleration);
  position.add(velocity);
  acceleration.set(0, 0);

  getArc(position.x, position.y, 30);

  requestAnimationFrame(loop);
}

摩擦力を加える

次は、摩擦力を加えます。空気抵抗のことかなと思います。 setupで摩擦力(friction)を0.02と設定して、loop関数の中で加速度を加えた後に摩擦力をかけています。

let canvas, ctx;
let force, acceleration, velocity, position, mass, friction;

window.addEventListener("load", init, false);

function init() {
  canvas = document.getElementById("myCanvas");
  ctx = canvas.getContext("2d");

  setup();
  loop();
  setupMediaRecorder();
}

class Vector {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  set(x, y) {
    this.x = x;
    this.y = y;
    return this;
  }

  add(vector) {
    this.x += vector.x;
    this.y += vector.y;
    return this;
  }

  mult(scalar) {
    this.x *= scalar;
    this.y *= scalar;
    return this;
  }
}

function setup() {
  position = new Vector(0, 0);
  velocity = new Vector(0, 0);
  force = new Vector(3, 2);
  mass = 1;
  friction = 0.02;
  acceleration = force.mult(mass);
}

function haikei() {
  ctx.fillStyle = "white";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.strokeStyle = "black";
  ctx.strokeRect(0, 0, canvas.width, canvas.height);
}

function loop() {
  haikei();

  velocity.add(acceleration);
  velocity.mult(1 - friction);
  position.add(velocity);
  acceleration.set(0, 0);

  getArc(position.x, position.y, 30);

  requestAnimationFrame(loop);
}

function getArc(x, y, r) {
  ctx.beginPath();
  ctx.arc(x, y, r, 0, Math.PI * 2, false);
  ctx.strokeStyle = "black";
  ctx.stroke();
}

重力を付加

次に重力を加えます。 setup関数で重力(gravity)を真下に1に設定します。そして、loop関数の中で最初に加速度に重力を加えます。

let canvas, ctx;
let force, acceleration, velocity, position, mass, friction;

window.addEventListener("load", init, false);

function init() {
  canvas = document.getElementById("myCanvas");
  ctx = canvas.getContext("2d");

  setup();
  loop();
  setupMediaRecorder();
}

class Vector {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  set(x, y) {
    this.x = x;
    this.y = y;
    return this;
  }

  add(vector) {
    this.x += vector.x;
    this.y += vector.y;
    return this;
  }

  mult(scalar) {
    this.x *= scalar;
    this.y *= scalar;
    return this;
  }
}

function setup() {
  position = new Vector(0, 0);
  velocity = new Vector(0, 0);
  gravity = new Vector(0, 1);
  force = new Vector(3, 2);
  mass = 1;
  friction = 0.01;
  acceleration = force.mult(mass);
}

function haikei() {
  ctx.fillStyle = "white";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.strokeStyle = "black";
  ctx.strokeRect(0, 0, canvas.width, canvas.height);
}

function loop() {
  haikei();

  acceleration.add(gravity);
  velocity.add(acceleration);
  velocity.mult(1 - friction);
  position.add(velocity);
  acceleration.set(0, 0);

  getArc(position.x, position.y, 30);

  requestAnimationFrame(loop);
}

function getArc(x, y, r) {
  ctx.beginPath();
  ctx.arc(x, y, r, 0, Math.PI * 2, false);
  ctx.strokeStyle = "black";
  ctx.stroke();
}

壁によるバウンド

最後に下に当たったら跳ね返るようにします。ここでは跳ね返りの数値を1としていますが、Geminiに聞くと0.98とか少し勢いを下げるとより自然になるようです。

let canvas, ctx;
let force, acceleration, velocity, position, mass, friction;
let x, y, r;

window.addEventListener("load", init, false);

function init() {
  canvas = document.getElementById("myCanvas");
  ctx = canvas.getContext("2d");

  setup();
  loop();
  setupMediaRecorder();
}

class Vector {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  set(x, y) {
    this.x = x;
    this.y = y;
    return this;
  }

  add(vector) {
    this.x += vector.x;
    this.y += vector.y;
    return this;
  }

  mult(scalar) {
    this.x *= scalar;
    this.y *= scalar;
    return this;
  }
}

function setup() {
  position = new Vector(0, 0);
  velocity = new Vector(0, 0);
  gravity = new Vector(0, 1);
  force = new Vector(12, 2);
  mass = 1;
  friction = 0.01;
  acceleration = force.mult(mass);
  r = 50;
}

function haikei() {
  ctx.fillStyle = "rgba(255, 255, 255, 0.1)";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.strokeStyle = "black";
  ctx.strokeRect(0, 0, canvas.width, canvas.height);
}

function loop() {
  haikei();

  acceleration.add(gravity);
  velocity.add(acceleration);
  velocity.mult(1 - friction);
  position.add(velocity);
  acceleration.set(0, 0);

  getArc(position.x, position.y, r);
  bounceOffWalls();

  requestAnimationFrame(loop);
}

function bounceOffWalls() {
  if (position.x > canvas.width - r) {
    position.x = canvas.width - r;
    velocity.x *= -1;
  }
  if (position.x < r) {
    position.x = r;
    velocity.x *= -1;
  }
  if (position.y > canvas.height - r) {
    position.y = canvas.height - r;
    velocity.y *= -1;
  }
  if (position.y < r) {
    position.y = r;
    velocity.y *= -1;
  }
}

function getArc(x, y, r) {
  ctx.beginPath();
  ctx.arc(x, y, r, 0, Math.PI * 2, false);
  ctx.strokeStyle = "black";
  ctx.stroke();
}

ABC435のA問題の振り返り

AtCoder ABC435のA問題の振り返りです。

atcoder.jp

この問題はいろんな書籍でも見るものだったのでOKでした。

function Main(input) {
  input = input.split("\n");
  N = parseInt(input[0]);
  console.log(((N + 1) * N) / 2);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));

この足し算の公式の名前はあるのかな?と思い、AIに聞いてみました。 すると、この公式には一般に広く使われている固有名はありませんが「三角数(triangular number)の公式」と呼ばれることが多いです、と答えが返ってきました。 三角数をWikipediaで調べてみると「なるほど」という感じだったのですが、文章から届いてくる熱量は今の私では受け止められない感じでした。がんばって理解できるようにしようと思います。

ダンスは音楽

私はダンスの経験はないですが、昔からなぜかダンスを観るのが好きでした。

そのダンスでずっと疑問がありました。
それは、「かっこいいはずなのに魅力を感じないダンスがある」ということです。

腕の角度や身体の向きが揃っているけど魅力は感じないダンスがある一方で、一人ひとりが好きなように踊っているように見えるけど「おぉー!かっこいい!」と思うダンスがある。

私はすべてがきっちり揃っているダンスの方がプロフェッショナルだと思ってました。
けど、そんなダンスを観てもなんとも思わないことが多い。
長年の疑問でした。

最近、疑問が晴れました。
まんが「ワンダンス」にありました。

・・・形を合わせなくても
同じ音を 同じアクセントで取ればダンスは揃う
2人ともリズムを体感で受け止めて動こうとしている・・・

そもそもダンスにはこういう考え方があったんですね。

このセリフの前には主人公のセリフがあります。

「音を聴く」・・・
そうだよな
音楽があって
その後にダンスがあるんだから

踊っている感じが全然ちがう
何で今まで気付かなかっただろう

「ダンスは身体を動かすもの」という先入観があったけど、身体を動かすことの前にまず音楽がある。ダンスは「音楽を表現しているもの」と考えると、音楽が好きな私がダンスを好きなのも理解できる。

ワンダンスの主題歌のBE:FIRSTの「Stare In Wonder」のダンスは全然揃えようとしてしていないけど、揃っているしかっこいい。このダンスを観ると、曲がより好きになる。


www.youtube.com

まず、書き終える

ブログを書こうとしても書けません。
このブログもずっと更新できずにいてます。なんとかしようと思っていたところ、良い言葉に出会いました。

三宅香帆さんの書籍『「好き」を言語化する技術』にこうありました。

なによりも重要なのは「まず、書き終える」こと。

これですね。書き終えないからブログにできない。
今までいろんな文章作成系の本を読んできましたが、これについて書かれているのを見たことがないです。書いてあったかもしれませんが、ここまではっきりと書いているのはなかったと思います。

書き終えるのが重要なんて、みんなが「当然でしょ」と思っているから書かないと思うんです。しかし、私は下書きだけが日々増えていき、書き終えることがむつかしいです。集中力がない、テーマが決まっていないのが原因と思っていました。

原因は、書き終えようとしていないから書けないんです。書き終えるためには考えていることをシンプルにしなければいけないですが、それができない。ごちゃごちゃと考えすぎて疲れて途中でやめてしまう。

しばらくは、とにかく書き終えることをがんばろうと思います。

Amazonのアソシエイトとして、当メディアは適格販売により収入を得ています。