ikautak.log

C/C++, Python, CUDA, Android, Linux kernel, Network, etc.

標準入力をsplitして、行と列を変換するpythonスクリプト

例えば、以下のような9行を3行ずつsplitして、

f:id:trisection:20160628232037p:plain

このように整形したいとき、bashで一度にうまくやる方法がわからなかったので自作。

f:id:trisection:20160721230201p:plain

split-transpose.py

#!/usr/bin/env python

import sys

def split_transpose(n):
    line = ''
    count = 0

    for l in iter(sys.stdin.readline, ''):
        line += l.rstrip() + '\t'
        count += 1

        if count == n:
            print(line)
            line = ''
            count = 0

    if count != 0:
        print(line)


if __name__ == '__main__':
    if len(sys.argv) > 1:
        split_transpose(int(sys.argv[1]))

デリミタはとりあえずtab固定。

seq 12 を4行ごとにsplit-transposeした結果

$ seq 12 | ./split-transpose.py 4
1   2   3   4   
5   6   7   8   
9   10  11  12  

標準入力をsplitしてpasteするpythonスクリプト

標準入力を指定行数でsplitして、その結果をpaste、 というのを一度にやりたかったけど良い方法がわからなかったのでpythonで自作した。

例えば以下のような9行を3行でsplitして、

f:id:trisection:20160628232037p:plain

このようにpasteする。

f:id:trisection:20160628232041p:plain

#!/usr/bin/env python

import sys

def split_paste(n):
    d = [[] for _ in range(n)]

    for i, l in enumerate(iter(sys.stdin.readline, '')):
        d[i % n].append(l.rstrip())

    for l in d:
        print('\t'.join(l))


if __name__ == '__main__':
    if len(sys.argv) > 1:
        split_paste(int(sys.argv[1]))

デリミタはとりあえずtab固定。

seq 12 を4行ごとにsplit-pasteした結果

$ seq 12 | ./split-paste.py 4
1   5   9
2   6   10
3   7   11
4   8   12

カーネルモジュールのサンプル

LinuxのCharacter deviceのひな形。最近はprintkではなく、pr_xxxを使うらしい。

まずMakefile

KDIR = /lib/modules/$(shell uname -r)/build
obj-m += sample.o

all:
  make -C $(KDIR) M=$(PWD)

clean:
  make -C $(KDIR) M=$(PWD) clean

Character deviceを作るsample.c。

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/slab.h>

#define DEV_NAME "sample"

struct sample_dev_t
{
    dev_t id;
    struct cdev cdev;
    struct class *class;
    struct device *dev;
} *sample_dev;

static int sample_open(struct inode *inode, struct file *filp)
{
    pr_info("open\n");
    return 0;
}

static int sample_close(struct inode *inode, struct file * filp)
{
    pr_info("close\n");
    return 0;
}

static ssize_t sample_read(struct file *filp, char __user *buf,
                size_t size, loff_t *offset)
{
    pr_info("read\n");
    return 0;
}

static ssize_t sample_write(struct file *filp, const char __user *buf,
                size_t size, loff_t *offset)
{
    pr_info("write\n");
    return 0;
}

static long sample_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
    pr_info("ioctl cmd %d arg %ld\n", cmd, arg);
    return 0;
}

struct file_operations sample_fops = {
    .owner          = THIS_MODULE,
    .open           = sample_open,
    .release        = sample_close,
    .read           = sample_read,
    .write          = sample_write,
    .unlocked_ioctl = sample_ioctl,
};

static int __init sample_init(void)
{
    int err;

    pr_info("%s:init\n", DEV_NAME);

    sample_dev = kmalloc(sizeof(struct sample_dev_t), GFP_KERNEL);
    if (!sample_dev) {
        pr_err("kmalloc err\n");
        return -ENOMEM;
    }

    err = alloc_chrdev_region(&sample_dev->id, 0, 1, DEV_NAME);
    if (err) {
        pr_err("alloc_chrdev_region err %d\n", err);
        goto out_free;
    }

    cdev_init(&sample_dev->cdev, &sample_fops);
    sample_dev->cdev.owner = THIS_MODULE;

    err = cdev_add(&sample_dev->cdev, sample_dev->id, 1);
    if (err) {
        pr_err("cdev_add err %d\n", err);
        goto out_unregister;
    }

    sample_dev->class = class_create(THIS_MODULE, DEV_NAME);
    if (IS_ERR(sample_dev->class)) {
        err = PTR_ERR(sample_dev->class);
        pr_err("class_create err %d\n", err);
        goto out_cdev_del;
    }

    sample_dev->dev = device_create(sample_dev->class, NULL,
            sample_dev->id, NULL, DEV_NAME);
    if (IS_ERR(sample_dev->dev)) {
        err = PTR_ERR(sample_dev->dev);
        pr_err("device_create err %d\n", err);
        goto out_class_destroy;
    }

    return 0;

out_class_destroy:
    class_destroy(sample_dev->class);

out_cdev_del:
    cdev_del(&sample_dev->cdev);

out_unregister:
    unregister_chrdev_region(sample_dev->id, 1);

out_free:
    kfree(sample_dev);

    return err;
}

static void __exit sample_exit(void)
{
    pr_info("exit\n");

    device_destroy(sample_dev->class, sample_dev->id);
    class_destroy(sample_dev->class);
    cdev_del(&sample_dev->cdev);
    unregister_chrdev_region(sample_dev->id, 1);
    kfree(sample_dev);
}

module_init(sample_init);
module_exit(sample_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("kernel module sample");

試しに /dev/sample をcatする。

sudo insmod ./sample.ko
sudo cat /dev/sample

syslogに以下のログが出る。

Mar 24 22:31:18 0805LM kernel: [12515.692818] sample:init
Mar 24 22:31:30 0805LM kernel: [12527.303679] open
Mar 24 22:31:30 0805LM kernel: [12527.303690] read
Mar 24 22:31:30 0805LM kernel: [12527.303692] close

Pythonで数値−色変換とPNGの書き出し

ヒートマップのようなものを作るとき用に調べた。

[0, 1]の範囲の値を青ー赤のカラーに変換
http://qiita.com/krsak/items/94fad1d3fffa997cb651

PNGの書き出し
http://danpansa.blog.jp/archives/12901916.html

#!/usr/bin/env python

import math
import Image

def colorscale(v):
    t = math.cos(4 * math.pi * v)
    c = int(((-t / 2) + 0.5) * 255)
    if v >= 1.0:
        return (255, 0, 0)
    elif v >= 0.75:
        return (255, c, 0)
    elif v >= 0.5:
        return (c, 255, 0)
    elif v >= 0.25:
        return (0, 255, c)
    elif v >= 0:
        return (0, c, 255)
    else:
        return (0, 0, 255)


if __name__ == '__main__':
    img = Image.new('RGB', (100, 100), 'white')
    pix = img.load()

    for x in range(100):
        (r, g, b) = colorscale(x / 100.0)
        for y in range(100):
            pix[x, y] = (r, g, b)

    img.save('out.png')

生成したPNG

f:id:trisection:20140315235149p:plain