初心者のメモ

Python enthusiast

JavaScript基礎

基礎

出力
console.log('hoge');
> hoge
コメントアウト
// console.log('hoge');
定数
const myName = 'Tom';
console.log(myName);
> Tom
変数
let age = 9;
console.log(age);
> 9

age += 1
console.log(age);
> 10
テンプレートリテラル
const selfIntro = `My name is ${myName}, ${age} years old.`;  // バッククォートで囲む
console.log(selfIntro);
> My name is Tom, 10 years old.
比較演算子
console.log(myName === 'Tom');
> True
console.log(myName !== 'Tom');
> False
and/or条件
console.log(myName === 'Tom' && age >= 10);
> True

console.log(myName !== 'Tom' || age >= 10);
> True

条件分岐

if文
if (age >= 20) {
  console.log('20歳以上です');
} else if(age >= 10) {
  console.log('10歳以上です');
} else {
  console.log('10歳未満です');
}
> 10歳以上です

switch文

switch(age) {
  case 9:
    console.log('9歳です');
    break;
  case 10:
    console.log('10歳です');
    break;
  case 11:
    console.log('11歳です');
    break;
  default:
    console.log('9歳未満か12歳以上です');
    break; 
}
> 10歳です

繰り返し処理

while
let number = 0;
while(number < 3) {
  console.log(number);
  number += 1;
}
> 0
> 1
> 2
for文
for(let i = 0; i < 3; i++) {
  console.log(i);
}
> 0
> 1
> 2
配列の処理
const fruits = ['apple', 'orange', 'banana'];
for(let i = 0; i < fruits.length; i++) {
  const fruit = fruits[i];
  console.log(fruit);
}
> apple
> orange
> banana
オブジェクトの処理
const items = [
  {name: 'apple', price: 100},
  {name: 'orange', price: 110},
  {name: 'banana'},
]

for(let i = 0; i < items.length; i++) {
  const price = items[i].price
  if(price !== undefined) {
    console.log(price);
  } else {
    console.log('unknown');
  }
}
> 100
> 110
> unknown

関数

rate = 110;

const convertToDollar = (priceYen) => {
  return priceYen / rate;
}

const info = (name, price) => {
  const priceDollar = convertToDollar(price);
  console.log(`${name}は${price}円、ドル換算では${priceDollar}ドルです`); 
}

for (let i = 0; i < items.length; i++) {
  const name = items[i].name;
  const price = items[i].price;

  if (price !== undefined) {
    info(name, price)
  } else {
    console.log(`${name}は価格不明です`)
  }
}

> appleは100円、ドル換算では0.90909090909ドルです
> orangeは110円、ドル換算では1ドルです
> bananaは価格不明です

Class

constructor, method
class Student {
  constructor(name, age){
    this.name = name;
    this.age = age;
  }
  
  greet(){
    console.log('hello');
  }
  
  info(){
    const selfIntro = `My name is ${this.name}.`
    console.log(selfIntro)
  }
}

student = new Student('taro', 10);
student.greet()
student.info()

> hello
> My name is taro.
classの継承、オーバーライド、親classのコンストラクタ呼び出し

animal.js

class Animal {
  constructor(name, age){
    this.name = name;
    this.age = age;
  }
  
  info(){
    console.log(`This is ${this.name}, ${this.age} years old`);
  }
}

// Animalクラスを他ファイルから参照できるように
export default Animal;

cat.js

import Animal from './animal.js';
class Cat extends Animal{
  constructor(name, age, breed){
    // 親クラスのコンストラクタを継承
    super(name, age);
    this.breed = breed;
  }
  
  info() {
    console.log(`This is ${this.name}, ${this.age} years old. Breed is ${this.breed}`);
  }
}

export default Cat;

main.js

import Cat from './cat.js';

const cat = new Cat('betty', 3, 'scottish fold');
cat.info();
> This is betty, 3 years old. Breed is scottish fold

brew installしたときにpkg-configでsyntax errorが起きる場合の対処法

> brew install any-package-name
Error: pkg-config: /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/pkg-config.rb:1: syntax error, unexpected <<
<<<<<<< HEAD
  ^
/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/pkg-config.rb:41: syntax error, unexpected ===, expecting end-of-input
=======
   ^

こんなときは

brew update-reset

で一発解決

Python コンソールへの出力を改行せずに上書きする方法

普通に出力すると

for i in range(0, 100):
    print(i)
> 0
> 1
> 2
...
> 99
> 100

と改行されて表示される。

改行せずに表示するにはsys.stdoutを使うといい。

import sys, times

def print_progress(text):
    sys.stdout.write("\r%s" % text)
    sys.stdout.flush()
    time.sleep(0.01)

for i in range(0, 100):
    print_progress('progress: %d' % i)

とすると、

> progress: 100

のように改行なしで数字が0~100まで表示される

Dockerで立ち上げたmySQLにターミナルから接続

docker psでmysqlコンテナのportsを確認。 仮にportsが 0.0.0.1:3356 だったら、 次のコマンドで、Dockerで立ち上げたmysqlにterminalから接続できる。

mysql -h 127.0.0.1  -p 3356 -u root -p

なお、普通に接続しようと次のエラーメッセージがでる。

> mysql -u root -p
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

このコマンドでは、UNIXドメインソケットを利用した通信で接続しようとしている。 しかし、Dockerで起動したデーモンは、同じローカルでもファイルシステムが切り分けられているため、UNIXドメインソケットを利用した通信はできない。

Amazon Linux - ログアウトした後もコマンドを実行し続ける方法

nohup COMMAND >out.log 2>err.log &

でok。

pythonでtest.pyを実行する場合なんかは、

nohup python test.py >out.log 2>err.log &

補足

nohup

バックグラウンドで実行中のプロセスでも、 ログアウトするとHUPシグナルによって終了する。 nohupは、これを無視して実行し続けるようにプログラム実行する。

>out.log 2>err.log

nohup COMMAND &

で実行すると、標準出力と標準エラーはnohup.outに追記される。

標準出力の書き出し先を指定するには >{OUTFILE} 標準エラー出力の書き出し先を指定するには 2>{OUTFILE} 標準エラー出力を標準出力と同じところに流すには >{OUTFILE} 2>&1

参考:

SQLAlchemy - 複数テーブルを横断してロードする方法

親テーブル - 子テーブル - 孫テーブル のようなrelationのデータベースがあるとして、

# models_generated.py
class Parent(Base):
    __tablename__ = 'parent'

    id = Column(Integer, primary_key=True)
    ..略..

    child = relationship('Child')


class Child(Base):
    __tablename__ = 'child'

    id = Column(Integer, primary_key=True)
    ..略..

    grandson = relationship('Grandson')


class Grandson(Base):
    __tablename__ = 'grandson'

    id = Column(Integer, primary_key=True)
    ..略..

親テーブルを子・孫テーブルのデータと一緒にロードする方法は次のとおり。

ses = init_session()
parent_models = ses.query(Parent).options(joinedload(Parent.child).joinedload(Child.grandson))