ソフトウェアエンジニアの日常の雑記

日々思ったことをまとめます

新しく言語を習得するときにロゼッタコード(rosettacode)を参考にする

本家はこちら

タイトルの通りだが、新しく言語を習得するときは、チュートリアルもそうなんだが、結構rosettacodeで逆引きして、へぇーこーゆー風に書くんだーみたいなのをみてみたりする

ロゼッタコード

タスクを選ぶ

もちろん英語サイトなので、アレルギーがある人には見た瞬間「うっ」ってなるかもですけど、中身は簡単 下記のページで参考にしてみたいタスクをクリックし、言語ごとに実装例がかいてあるので、それを参考にする http://www.rosettacode.org/wiki/Category:Programming_Tasks

fizzbuzz

例えばみんなだいすきfizzbuzzとかもある http://www.rosettacode.org/wiki/FizzBuzz

Nimで書くとこんな感じ

for i in 1..100:
  if i mod 15 == 0:
    echo("FizzBuzz")
  elif i mod 3 == 0:
    echo("Fizz")
  elif i mod 5 == 0:
    echo("Buzz")
  else:
    echo(i)

Swiftで書くとこんな感じ

for i in 1...100 {
    switch (i % 3, i % 5) {
    case (0, 0):
        print("FizzBuzz")
    case (0, _):
        print("Fizz")
    case (_, 0):
        print("Buzz")
    default:
        print(i)
    }
}

Luaで書くとこんな感じ

word = {"Fizz", "Buzz", "FizzBuzz"}

for i = 1, 100 do
        print(word[(i % 3 == 0 and 1 or 0) + (i % 5 == 0 and 2 or 0)] or i)
end

Adaで書くとこんな感じ

with Ada.Text_IO; use Ada.Text_IO;

procedure Fizzbuzz is
begin
   for I in 1..100 loop
      if I mod 15 = 0 then
         Put_Line("FizzBuzz");
      elsif I mod 5 = 0 then
         Put_Line("Buzz");
      elsif I mod 3 = 0 then
         Put_Line("Fizz");
      else
         Put_Line(Integer'Image(I));
      end if;
   end loop;
end Fizzbuzz;

まぁこのように結構な言語数がある。実際にこのコードがベスト・プラクティスなわけではないが、参考にはなる。

sha-256

nimでsha-256でハッシュしたいときに、さっと見られるので、便利

import strutils

const SHA256Len = 32

proc SHA256(d: cstring, n: culong, md: cstring = nil): cstring {.cdecl, dynlib: "libssl.so", importc.}

proc SHA256(s: string): string =
  result = ""
  let s = SHA256(s.cstring, s.len.culong)
  for i in 0 .. < SHA256Len:
    result.add s[i].BiggestInt.toHex(2).toLower

echo SHA256("Rosetta code")

まか書き方が冗長だったりすることもあるかもだが、それは自分で直せばいいし、あくまで参考程度にみるには結構重宝するサイトだと思う

nim tutorial part2 (1) memo [objects]

本家はこちら

つづき

nim チュートリアル part2 のメモ

objects

nimは最小限のOOP(オブジェクト指向)をサポートしている。

type
    Person = ref object of RootObj # 
        name*: string # *がつくと public
        age: int # * ないと private? 
    Student = ref object of Person
        id: int # with and id field

var
    student: Student
    person: Person
    sample: int

student = Student(name: "Anton" , age: 5,id: 2)
person = Person(name: "sample" , age: 10)

echo student[]
# echo student    -> これはエラーになる
echo person[]

classはないが、object型をrefすることで同じようなことはできる。 *のありなしで、public/privateをわけている。継承もできるが、多重継承はサポートしていない。ここらへんはPythonと異なる。 typeっていうのがあるので、お気づきかもだが、いくつか型を指定できる。enumとかobject とか ref objectとか... それは次回。

ライブチャットサービスのlivezillaを入れてみた

本家はこちら

ライブチャットサービスでいいのないかなーって探してたらオンプレでできそうないいものがあったので、メモ

サイトに来てもらって、そこからのコンバージョンを上げたいとかあるんだけど、ユーザが何思ってるかとか組み上げるものがあんまりなかったので、導入したいなーと思ってSaaSのものをみてたんだけど、月額安いんだけど、オペレータ増やすと途端に値段あがってくし、ログあんまり残らないし、性能でるかわからんしってことで、オンプレでできるのを探しており、Livezillaっていうのを見つけた。

LiveZilla概要

  • 構成はPHP + JS + MySQLという感じで超シンプル。
  • ソースコードはやや見づらいがメンテできないほどではない
  • オペレータは1名だけなら永久無料(30日間は無制限利用)
  • オペレータのクライアントアプリがある
  • 翻訳機能(エディタ)がある

  • ボット用のAPIがある
  • オペレータ画面でユーザが表示してる画面がみえる(入力までは見えない)
  • チケット管理ができる
  • ブラックリスト管理
  • 優先順位管理
  • slack連携できる などなど、もう機能としては十分である。

画面はこんな感じ

ライセンス

あと、ライセンスが買い切りで無制限プランが999ユーロらしく、結構やすい。 zopimとかのだと3オペレータ10ヶ月分で10万弱なので、ならボット無制限でつくれるので、いいかなと。

ビジネスとしては

アップデートライセンスは別にある。これは予測だけど、クライアントアプリ(デスクトップ、スマホとも)は多分、最新のLiveZillaのAPIにしか対応してないとかなんとかで、そのアップデートライセンスを買わせるモデルなんじゃないかなと。ただ、アップデートライセンスもそれほど高くなく、499ユーロくらいなので、別に全然いい。

さて、これでコンバージョンあがるといいなー。

ライブチャットサービスのlivezillaを入れてみた

本家はこちら

ライブチャットサービスでいいのないかなーって探してたらオンプレでできそうないいものがあったので、メモ

サイトに来てもらって、そこからのコンバージョンを上げたいとかあるんだけど、ユーザが何思ってるかとか組み上げるものがあんまりなかったので、導入したいなーと思ってSaaSのものをみてたんだけど、月額安いんだけど、オペレータ増やすと途端に値段あがってくし、ログあんまり残らないし、性能でるかわからんしってことで、オンプレでできるのを探しており、Livezillaっていうのを見つけた。

LiveZilla概要

  • 構成はPHP + JS + MySQLという感じで超シンプル。
  • ソースコードはやや見づらいがメンテできないほどではない
  • オペレータは1名だけなら永久無料(30日間は無制限利用)
  • オペレータのクライアントアプリがある
  • 翻訳機能(エディタ)がある

  • ボット用のAPIがある
  • オペレータ画面でユーザが表示してる画面がみえる(入力までは見えない)
  • チケット管理ができる
  • ブラックリスト管理
  • 優先順位管理
  • slack連携できる などなど、もう機能としては十分である。

画面はこんな感じ

ライセンス

あと、ライセンスが買い切りで無制限プランが999ユーロらしく、結構やすい。 zopimとかのだと3オペレータ10ヶ月分で10万弱なので、ならボット無制限でつくれるので、いいかなと。

ビジネスとしては

アップデートライセンスは別にある。これは予測だけど、クライアントアプリ(デスクトップ、スマホとも)は多分、最新のLiveZillaのAPIにしか対応してないとかなんとかで、そのアップデートライセンスを買わせるモデルなんじゃないかなと。ただ、アップデートライセンスもそれほど高くなく、499ユーロくらいなので、別に全然いい。

さて、これでコンバージョンあがるといいなー。

Nginxでお手軽なHLSストリーミング

本家はこちら

スマホで動画再生コンテンツをお手軽にリリースしたいなーって時に、mp4とかwebmとかだと正直再生までに時間かかるので、ストリーミングをちょっと触る。 Nginxは標準でストリーミング対応できてるっぽいので、これを使う。

お試しの環境はMacで。

下準備(動画変換ライブラリ)

動画変換にはffmpegを使う。 まずは、mp4とかwebmとかmovをHLSで再生できるm3u8に変換したいので、ffmpegを再ビルド・インストールする

$ brew reinstall ffmpeg  --with-fdk-aac --with-libvo-aacenc  --with-libvorbis --with-libvpx --with-openjpeg  --with-theora --with-opencore-amr

動画変換する

動画を下記コマンドで変換かける

$ ffmpeg -i video.mp4 -vcodec libx264  -b:v 768k -s 640x360 -acodec libfdk_aac  -b:a 96k -ar 44100 -flags +loop-global_header  -map 0 -vbsf h264_mp4toannexb -f segment  -segment_format mpegts -segment_time 10  -segment_list video.m3u8 video%03d.ts

video.mp4をm3u8形式に変換する。

マークアップに記述する

ブラウザでhlsを再生するのに、video.jsを使用する hlsのcontribモジュールも使用する。

index.htmlはこんな感じ iOSで自動再生するには、<video>タグ内に playsinlinemutedをいれれば自動再生できます

<!DOCTYPE html>
<html lang="ja">

<head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <link href="//vjs.zencdn.net/6.7/video-js.min.css" rel="stylesheet"> <title>HTTP Live Streaming Test</title> <style> .wrapper { height: 100%; width: 100%; position: relative; }

video {
  widows: 480px;
}

</style> </head>

<body> <script src="//vjs.zencdn.net/6.7/video.min.js"></script> <script src="https://unpkg.com/videojs-contrib-hls/dist/videojs-contrib-hls.js"></script> <script src="./videojs-contrib-media-sources.js"></script> <div class="container"> <header> <h1>HTTP Live Streaming Test</h1> </header> <video class="video-js vjs-default-skin" id="video" width="360" autoplay controls muted playsinline preload="metadata"> <source src="video/video.m3u8" type="application/x-mpegURL">

nim lang チュートリアル(4) (distinct,modules)

本家はこちら

つづき

distinct

これは他の言語でもあるのかな。理解するまで時間がかかったものだが、どうやらある型をベースに 異なる型を生成するもよう。

下記の例だとエラーになる

type  Dollar = distinct int

var  d: Dollar

echo d + 1   // Error: type mismatch: got (Dollar, int literal(12))

int型をベースにDollar型を生成している。 だが、演算子までは使えない

modules

nimはmodule機構がある

import

おなじみimport

import strutils

モジュール内の関数を読み込まないこともできる

import strutils expect isDigit

var a: string = "1"
echo isDigit(a)  // Error: undeclared identifier: 'isDigit'

コンパイルエラーになる

from statement

moduleの中からなにを使えるようにするか選択できる

from mymodule import x ,y ,z 
x()  # OK
from mymodule import nil
x()  # error
mymodule.x()  # OK

aliasも指定できる

from mymodule as m import nil
m.x()  # OK

include statement

モジュールのファイル分割時に使用するみたい

include fileA  , fileB , fileC

nim lang チュートリアル(4) (distinct,modules)

本家はこちら

つづき

distinct

これは他の言語でもあるのかな。理解するまで時間がかかったものだが、どうやらある型をベースに 異なる型を生成するもよう。

下記の例だとエラーになる

type  Dollar = distinct int

var  d: Dollar

echo d + 1   // Error: type mismatch: got (Dollar, int literal(12))

int型をベースにDollar型を生成している。 だが、演算子までは使えない

modules

nimはmodule機構がある

import

おなじみimport

import strutils

モジュール内の関数を読み込まないこともできる

import strutils expect isDigit

var a: string = "1"
echo isDigit(a)  // Error: undeclared identifier: 'isDigit'

コンパイルエラーになる

from statement

moduleの中からなにを使えるようにするか選択できる

from mymodule import x ,y ,z 
x()  # OK
from mymodule import nil
x()  # error
mymodule.x()  # OK

aliasも指定できる

from mymodule as m import nil
m.x()  # OK

include statement

モジュールのファイル分割時に使用するみたい

include fileA  , fileB , fileC