色々な言語で偶数自乗和
TL;DR
- パイプライン演算子いいね
このごろ新しく言語を見る時、Hello world の次くらいに偶数自乗和を 作る関数を定義してる。Ruby で書くとこんな感じ。
def even_square_sum(n) (1..n) .select {|n| n % 2 == 0} .map {|n| n * n} .inject {|acc, n| n + acc} end puts(even_square_sum(10)) # => 220 が表示されると正解
いくつかルールがあって
- リストの内包表記は使わない
- range 的なのがあれば使う
- 最後の合計はなるべく畳み込み(reduce, fold系) を使う
これをやると
- 無名関数の定義のしかた
- 関数の定義のしかた
- 関数の呼び出しかた
- 基本的な高階関数の使い方
が分かるので、なかなか気にいってる。 では今まで作ったのを紹介してみる。
Rust
fn even_square_sum(n: isize) -> isize { (1..n) .filter(|n| n % 2 == 0) .map(|n| n * n) .fold(0, |acc, x| acc + x) } fn main() { let result = even_square_sum(10); println!("{}", result); }
普通かな。 でもこの書き方をゼロコストでやってくれるのはいいね。
Common Lisp
(defun range (from to &optional (res '())) (if (eq from to) (cons to res) (range from (1- to) (cons to res)))) (defun even-square-sum (n) (reduce #'+ (mapcar #'(lambda (n) (* n n)) (remove-if-not #'evenp (range 1 n))))) (setq result (even-square-sum 10)) (print result)
range がなかったので自作してみた。末尾再帰ではないので、ヒマがあったら変えたい。 適用する順番が頭で考えるのと逆順になってしまうので読みづらい。 マクロ作ればパイプライン的な事もやれそうだけど。
TypeScript
function evenSquareSum(n: number): number { const numList: number[] = Array.from(Array(n).keys()); return numList .filter((n) => n % 2 == 0) .map((n) => n * n) .reduce((acc, n) => acc + n); } const result = evenSquareSum(10) console.log(result);
普通かな。range がないので、Array.from() を使ったけどやはり気持ち悪い。
Elixir
evenSquareSum = fn (n) -> (1..n) |> Enum.filter(fn n -> rem(n, 2) == 0 end) |> Enum.map(fn x -> n * n end) |> Enum.reduce(0, fn n, acc -> n + acc end) end result = evenSquareSum(10) IO.puts(result)
パイプライン演算子(|>)いいね。 リスト操作以外にも使えそうだし、 もっと他の言語にも取り入れてもらいたい。
import Enum 1..10 |> filter(&rem(&1, 2) == 0) |> map(&(&1 * &1)) |> reduce(&(&1 + &2))
git rebase -i をちょっと楽にするエイリアス
いつもいつも git rebase -i HEAD^^
を打つのが
めんどくさいので作ってみました。
使用例
- git irebase
- → git rebase -i HEAD~2
- git irebase 5
- → git rebase -i HEAD~5
- 数字をつけるとその数さかのぼる
- git irebase ^^^
- → git rebase -i HEAD^^^
- ^ や ~ だけの場合、 HEAD からさかのぼる
- git irebase 2 develop
- →git rebase -i HEAD~2 develop
- ブランチ指定も可
詳しくはソースを参照の事。 以下を git-irebase として PATH の通ったディレクトリに置いて使います。 https://github.com/yosugi/git-irebase にも上げておいたので、 お好きな方をどうぞ。
#!/usr/bin/env perl use strict; use warnings; sub main { my ($upstream, $branch) = @_; $upstream = 2 unless ($upstream); $branch = "" unless ($branch); if ($upstream =~ /^[0-9]+$/) { $upstream = "HEAD~$upstream"; } elsif ($upstream =~ /^[0-9^~]+$/) { $upstream = "HEAD$upstream"; } exec "git rebase -i $upstream $branch"; } main(@ARGV); __END__ =head1 NAME git-irebase - alias for git rebase -i =head1 SYNOPSIS $ git irebase [<upstream>] [<branch>] =head1 DESCRIPTION $ git clone https://github.com/yosugi/git-irebase.git $ export PATH=./git-irebase:$PATH $ git irebase =head1 AUTHOR yosugi =head1 LICENSE MIT license (http://opensource.org/licenses/mit-license.php) =cut
github のリポジトリ構造は https://github.com/kyanny/git-copy を参考にさせて もらいました。感謝です。
MODx の管理画面ツールバーにボタンを追加する
MODx の管理画面をカスタマイズした時のメモです。 最後の doLayout() が分からなくてハマったので注意。
MODx.on('ready', function() { var buttons = []; buttons.push({ text: 'hello', handler: function () { alert('hello'); // 実行させたい処理をここに書く } }); var toolBar = Ext.getCmp('modx-action-buttons'); // この toolBar は Ext.Toolbar クラスなので対応するメソッドが使えます。 // http://extdocs.xenophy.com/?class=Ext.Toolbar toolBar.addButton(buttons); // 最後に追加 // toolBar.insertButton(3, buttons); // 3 番目に追加 toolBar.doLayout(); // 描画し直す }
vim のインサートモードで行頭をトグルする
vim を使ってて、emacs みたいに C-a で行頭と空白以外の最初の文字を トグルしたかったので作ってみました。
function! ToggleBol() let col = virtcol('.') let cmd = (col == 1) ? '^' : '0' execute "normal! " . cmd endfunction inoremap <C-a> <C-o>:call ToggleBol()<CR>
コメントアウトする時とかに便利かも。
追記
Qiitaのコメント で教えてもらったやり方のがよさそうなので、こっちにも書いときます。
inoremap <expr> <C-a> \ search('^\s\s*\%#', 'bcn') ? "\<C-o>0" : "\<C-o>^"
search とか初めて知ったよ。
twig で配列の数をカウントする
ちょっと検索しただけでは分からなかったので。 ほとんど参考サイトのコピペですが。
{% if my_list|length > 10 %} ... {% endif %}
ubuntu に samba を入れる
もう少し簡単にファイル共有できないかと思い、 ubuntu に samba を入れてみました。
いつも通り、 apt-get を使います
$ sudo apt-get install samba
共有するディレクトリを作成し、 だれでも読み書きできるようにオーナー、権限を設定します。
$ sudo mkdir /var/samba $ sudo chown nobody:nogroup /var/samba $ sudo chmod 777 /var/samba
/etc/samba/smb.conf をエディタで開いて設定します。
[global] workgroup = WORKGROUP dos charset = CP932 # Windows 側の文字コード unix charset = UTF-8 # Linux 側の文字コード map to guest = Bad User # Linux に存在しないユーザーでのアクセスはゲストとして扱う [share] path = /var/samba # さっき作ったディレクトリ writeable = yes # 書き込み許可 force create mode = 0666 # ファイルを作った時の権限 force directory mode = 0777 # ディレクトリを作った時の権限 guest ok = yes # ゲストアクセスを許可 guest only = yes
設定したら再帰動します。
sudo service smbd restart
これで接続できました。
ubuntu に Symfony2 をインストール
Symfony2 を ubuntu にインストールした時のメモ
まず、 Symfony を落としてきて展開
mkdir ~/temp cd ~/temp wget http://get.symfony.com/Symfony_Standard_Vendors_2.3.1.tgz tar -zxvf Symfony_Standard_Vendors_2.3.1.tgz sudo mv Symfony /var/www
で http://hostname/symfony/web/app_dev.php にアクセス。 以下のエラーが出たので、 app_dev.php を修正します。
You are not allowed to access this file. Check app_dev.php for more information.
sudo vim /var/www/Symfony/web/app_dev.php
app_dev.php はローカルからのみ接続できるようになっています。 今回は開発用に他マシンからも接続するので、 以下の行をコメントアウトします。
# if (isset($_SERVER['HTTP_CLIENT_IP']) # || isset($_SERVER['HTTP_X_FORWARDED_FOR']) # || !in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1')) # ) { # header('HTTP/1.0 403 Forbidden'); # exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.'); # }
再びブラウザからhttp://hostname/symfony/web/app_dev.php にアクセス
RuntimeException: Unable to create the cache directory (/var/www/Symfony/app/cache/dev)
エラーが出たので権限を変更します
chmod 777 /var/www/Symfony/app/cache
さらにブラウザでチェックすると エラーが出たので権限を変更します。 UnexpectedValueException: The stream or file "/var/www/Symfony/app/logs/dev.log
chmod 777 /var/www/Symfony/app/logs
これで正しく表示できるようになりました。