水曜日, 12月 30, 2015

PowerBuilder 12.6: 要素をリネーム

PowerBuilder ってのはクセのあるソフトで、気をつけないと半日を潰してしまう「仕様」があります。バグだと思うんですが

なぜか要素をリネームできないんですよ。右クリックしてもリネームなるメニューがない。

リネームなんて「別名でコピーして元のを消せばいい」、と思うかもしれませんが、PowerBuilder だとこれしかない。別名でコピーするしか方法がないんですね。

Save といっても右クリック→Copy ... とするとその要素はもうあるよ、とエラーを出してきます。
ここは File メニューから Save as とするのが正解です。

これがですね、そのままじゃ出てこない。Window を開かないとダメなわけなんです。

この思いがけない癖ってのが PowerBuilder の特徴です。ってことで

ここで一言: PowerBuilder は不安定ですぐクラッシュします。どうにかしてほしいです

こんなときは Regenerate です。

自作ブレッドボード版 Arduino

作ってみました。自作ブレッドボード版 Arduino です。

Arduino UNO を使ってブートローダーを焼いたので、プログラムのアップロードは完了していたわけなんですが、内部クロック(8MHz)だとそのままで動かないので16MHzのクリスタルが届くまでお預けとなっておりました。

で、昨日届いたわけなのでさっそく動かしてみました。

まず5V電源をつくります。ここではLM317を使いました。こいつは可変型のレギュレーターで、抵抗値で電圧を変えることができます。

基本これで動きますが

発振防止、逆流防止ダイオードなどつけるとこうなります

Atmega328P チップと電源をつなぎ、クリスタルをつないで、と




動きました。感動です。13ピンのLEDが点灯しています。電源とクリスタル、これだけで動くんですね。





電源モジュールです。


これで作ったプログラムを保存することができます。

木曜日, 12月 24, 2015

Arduino: リレーを使って明かりを消す

Arduino ってのはよくできたシステムです。

Arduino がどれだけすばらしいかって「発想から実現へ」の直截さが違うわけです。

例えばですね、明かりを消したいとします。つけた明かりが消えてほしい。一定時間たったら消えてほしいと思ったとします。

どうするかっていうとまず100V電源をいじらないといけないので、リレーを使います。5V回路で100Vを操作すると壊れるのでリレーで隔離するわけです。


このリレーですが、一定以上の電流が必要となります。Arduino 出力端子そのままだと心もとないので、こういうときはたいていトランジスタなどを使って電流を操作します。信号を増幅するわけですね。

まあ面倒なわけです。トランジスタ回路を組むというだけでなんか「仕事から帰ってきてこれって」とかいう気分が襲ってくる。

でそこは Arduino の世界なわけです。これがホントよくできててリレー・モジュールなるものが売っている。しかもいい値段で売っている。

(これです→http://www.ebay.com

早い話がこれをつなぐとそれだけで明かりが消せます。そのままつなげばいい。タイマーをプログラムし、信号線をつなぐだけです。

え、これだけ?これだけで動くんだ、という感動があったわけなんですが、これちょっと考えてみてください。このモジュールの利点です。部品が少ないってことは、つまりそれだけ安全だってことです。100V使うんですから安全第一です。

まあしっかり懐中電灯など用意して動かしてみたわけなんですが、大丈夫でした。リセットボタンなど押すと明かりがついて、一時間たつと消えてくれます。

*)整数型では上限を超えてしまうので時間は long 型である必要があります。

int relayPin = 7;
int buttonPin = 3;
int ledPin = 13;
unsigned long start = 0;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(relayPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
turnOn();
delay(60*60*1000L);
turnOff();
}
void turnOn()
{
digitalWrite(relayPin, LOW);
digitalWrite(ledPin, HIGH);
}
void turnOff()
{
digitalWrite(relayPin, HIGH);
digitalWrite(ledPin, LOW);
}
void loop() {
}
view raw lightOff.ino hosted with ❤ by GitHub

土曜日, 12月 12, 2015

Arduino Uno を使ってブートローダーを焼く



Arduino を使うと書いたプログラムで外部装置を動かすことができます。いくらJava/C++/Android でプログラムを書いても所詮ソフトウエアってだけです。家電、LED やセンサーを動かすことはできないですよね。Arduinoなら可能です。USBでつないで外部装置をつなぎ、アップロードすると動きます。このスムーズな流れが「よく考えられたシステム」であるArduinoの特徴です。
 
このArduino、つないで動くというだけではありません。使える装置を作る方向へ発展させることができます。プログラムの書き込まれたCPUを取り出して使えばいい。

本家Arduino のボードのCPUは取り換えがききます。取り出せばそのまま同じ回路を独立して使うことができます。素晴らしいと思います。

このCPUですが、Atmega328のチップを使っています。ebayなど覗くとこのチップがまとめていい値段で販売されています。ありがたいです。

http://www.ebay.com

これらのチップはブートローダーが書き込まれていない場合があります。自分で書き込む必要があるわけですね。書き込みができると安いチップが使えます。挑戦する価値ありますよね。

どうやって書き込むのか、ですが、ネットではブレッドボードで回路を組む、専用のシールドを作る、専用ライターを使うなどいう手間のかかる方法が語られています。

でもですね、Arduino Unoを使うと手間いらずです。手間いらずということはつまり成功率が高いということです。是非お勧めしたい方法です。




どうするかというと、プログラムしたいチップを載せたArduino UnoArduino本体をつなぎます。

では焼き込みの手順です。まず ArduinoISPをアップロード。

ArduinoISPをアップロード
 
そしてArduino Uno をつなぎます。電源5VGNDをそれぞれ接続し、ピン11, 12, 13Arduino本体と接続します。あとはピン10とリセットとつなぎます。

新しいAtmega328Pチップを載せて、Board, Port, Programmerを設定します。それぞれArduino UnoUSBポート(ポート番号は環境で異なります)、Arduino as ISPを選択します。


 
ボード Board の設定


ポート Port の設定

 
プログラマ Programmer の設定

そして Burn Bootloader を選択してブートローダーを焼きます。
 
いよいよ書き込み


この方法でなんの問題もなくブートローダーを焼き込むことができました。チップをとりかえてLチカとかアップロードすると動くわけですね。これでArduinoマシンを量産できます。なんだろうこの安心感は(笑

#Arduino 基板を使わない場合はクリスタルで外部からクロックを供給してやる必要があります。

 
写真は自作のAVR-ISP・シールドです。

土曜日, 12月 05, 2015

Arduinoの流行るわけ・電子サイコロ


電子サイコロというものを見たことがあるでしょうか。LED回路などでサイコロの目をつくり、電子回路で操作・表示するものです。

乱数を生成し、各LEDを点灯させるというのはもし回路を自分で組むとしたら面倒な話です。


こんな作業も Arduino があるときちんと組めます。乱数はライブラリを利用し、各LEDへの出力をプログラムで操作します。

Arduinoが外部インターフェースとして便利な件


フォトレジスタというセンサーがあります。明るさを探知します。でもこれをどうやって利用したらいいでしょうか。電源を与え、抵抗値を読み取る装置をどうやって作ったらよいでしょうか。
そこで Arduino を利用します。電源を与え、アナログ値を読み取り、シリアル信号としてPCで読み取るなどという作業はこの Arduinoで行います。つまり、Arduino ならUSBケーブルをつなぐだけでアナログ値が読み取れます。





あとは読み取った値を利用して装置を動かすなどという作業をリレーなど通じてArduinoで行えばいい。

この一連の作業がUSB接続できるArduinoならスムーズかつ危険なく行うことができます。考えてもみてください。旧態然とした開発過程だと、マイコンチップを用意し特殊な装置でプログラムを焼き、電源装置を用意して動かすなどという手間が必要です。このハードルをArduinoがあると楽々と超えられるわけです。





金曜日, 11月 20, 2015

EPUB形式で電子本を作る

アドビ社の迫害をものともせずオープン規格EPUB電子本を作るとここで宣言。

mimetype
META-INF/
 container.xml
OEBPS/
 content.opf
 toc.ncx
 xhtml file

できた。が自前のJavaアプリで圧縮する必要があった。こんな感じです。

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipOutputStream;
public class Zip
{
static boolean debug = true;
public static void main(String args[])
{
String sourceDir = "d:/ebook/mybook/";
String zipFile = "d:/ebook/mybook.epub";
try
{
FileOutputStream fout = new FileOutputStream(zipFile);
ZipOutputStream zout = new ZipOutputStream(fout);
File fileSource = new File(sourceDir);
mimeType(zout, sourceDir);
addDirectory(zout, fileSource);
zout.close();
} catch (IOException ioe)
{
System.out.println("IOException :" + ioe);
}
}
static void mimeType(ZipOutputStream zout, String sourceDir)
{
try
{
byte[] buffer = new byte[1024];
FileInputStream fin = new FileInputStream(sourceDir + "/mimetype");
zout.putNextEntry(new ZipEntry("mimetype"));
zout.setLevel(ZipOutputStream.STORED);
int length;
while ((length = fin.read(buffer)) > 0)
{
zout.write(buffer, 0, length);
}
} catch (Exception e)
{
e.printStackTrace();
}
}
private static void addDirectory(ZipOutputStream zout, File fileSource)
{
File[] files = fileSource.listFiles();
if (debug)
System.out.println("Adding directory " + fileSource.getName());
zout.setLevel(ZipOutputStream.DEFLATED);
for (int i = 0; i < files.length; i++)
{
if (files[i].isDirectory())
{
addDirectory(zout, files[i]);
continue;
}
try
{
if (!files[i].getName().equals("mimetype"))
{
if (debug)
System.out.println("Adding file " + files[i].getName());
byte[] buffer = new byte[1024];
FileInputStream fin = new FileInputStream(files[i]);
zout.putNextEntry(new ZipEntry(files[i].getName()));
int length;
while ((length = fin.read(buffer)) > 0)
{
zout.write(buffer, 0, length);
}
zout.closeEntry();
fin.close();
}
} catch (IOException ioe)
{
System.out.println("IOException :" + ioe);
}
}
}
}
view raw Zip.java hosted with ❤ by GitHub

木曜日, 10月 08, 2015

PowerBuilder 12.6, C#: データベースへの接続方法

PowerBuilder でデータベースへ接続する方法を示します。

DataObject が機能していることが前提です。

SQLCA.DBMS = "ODBC"
SQLCA.AutoCommit = False
SQLCA.DBParm = "ConnectString='DSN=<server name>;UID=<user name>;PWD=<password>'"
CONNECT;
If SQLCA.SQLCode=-1 Then
MessageBox("Error","Database connection error")
HALT CLOSE
End If
dw_zip_code.SetTransObject( SQLCA )
string zip
zip=sle_zip_code.Text
dw_zip_code.Retrieve(zip)
DISCONNECT;

C# でいうと以下のようなコードとなります。

using (OdbcConnection connection = new OdbcConnection(Properties.Resources.DatabaseConnectionParam))
{
try
{
string zip = "55555";
if(0<args.Length)
zip=args[0];
connection.Open();
string sql = "Select * from zipcode_usa where zip_code='"+zip+"';";
OdbcDataAdapter adapter = new OdbcDataAdapter(sql, connection);
DataSet dataSet = new DataSet();
adapter.Fill(dataSet);
DataTable table = dataSet.Tables[0];
for (int i = 0; i < table.Columns.Count; i++)
{
Console.Write(table.Columns[i].ToString());
Console.Write(": ");
Console.WriteLine(table.Rows[0][i]);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
view raw USZip.cs hosted with ❤ by GitHub


月曜日, 10月 05, 2015

PowerBuilder 12.6: 画像ファイルを読み込む

PowerBuilder で画像ファイルを読み込む方法を示します。というか、そのままじゃだめなんですね。

PictureControl とかがあって、じゃあ置いておけばあとで そのまま読んでくれとかファイル名を渡す、そういう形式だと思っておりました。

C# だとかそうですよね。

ところが FileRead() だと 32KB しか読まないらしいわけです。手元の情報だとそれだけしかないんですが、どこか見てるところが間違えてるんでしょうか。



まあいいんですが、バッファが必要なら書くまでです。

こんな感じで書くと画像ファイルが読み込めます。blob で読み込んで渡してやれば表示してくれます。

integer fp, err
blob buf, b
long flen
string filename
int loops, i
string pathname
int result
result = getFileOpenName("Open image file", pathname, filename, "BMP", "BMP Files (*.BMP),*.BMP,")
if result=1 then
flen=fileLength(pathname)
fp = fileOpen(pathname, StreamMode!, Read!, Shared!)
if fp<>-1 then
if 32765 < flen then
if Mod(flen,32765)=0 then
loops=flen/32765
else
loops=(flen/32765)+1;
end if
else
loops=1
end if
for i=1 to loops
err=fileRead(fp,b)
buf=buf+b
next
p_1.SetPicture(buf)
end if
fileClose(fp)
end if

PowerBuilder 12.6: UTF-8 ファイルを読み込む

ひょんなことで PowerBuilder プロジェクトの案件を扱うこととなりました。ので、関連情報など載せていきたいと思います。

まずは IDE など勝手が違うので、多少の忍耐が必要です。

日本語のファイルを扱うのでまずはまってしまったので、まずはファイルの読み書きから書いていきたいと思います。

UTF-8 ファイルを読む方法です。

integer fp, err
blob buf
string pathname="text.txt"
fp = fileOpen(pathname, StreamMode!, Read!, Shared!)
if fp<>-1 then
err = fileRead(fp, buf)
ie_1.Text=string( buf, encodingUTF8!)
fileClose(fp)
end if

UTF-8 ファイルはこれで読み込めます。

書き込みは以下の通りです。

FileOpen で文字コード EncodingUTF8! を指定します。

string filename, pathname
integer result
string str
integer fp, err
result = getFileSaveName("Save file as", pathname, filename, "TXT", "Text Files (*.TXT),*.TXT,")
if result=1 then
fp = fileOpen(pathname, LineMode!, Write!, LockWrite!, Replace!, EncodingUTF8!)
if fp<>-1 then
str=ie_1.Text
err = fileWrite(fp, str)
fileClose(fp)
end if
end if

木曜日, 9月 24, 2015

C#: ハッシュテーブルをXML形式で書き出す・読み込む

C#でHashtableのデータをXML形式で読み書きするためのコードです。

忙しい貴方のため(将来の自分ですね)コピペできるようそのまま置いておきます。

  • writeXML(Hashtable directory, string fileName):
    Hashtable のデータをXML形式で保存します。

  • readXML(string fileName):
    XML形式のデータをHashtable 形式で読み込みます。

public static Hashtable readXML(string fileName)
{
Hashtable directory = new Hashtable();
XmlDocument document = new XmlDocument();
document.Load(fileName);
foreach (XmlElement element in document.DocumentElement)
{
string name = element.GetAttribute("name");
int number = int.Parse(element.GetAttribute("number"));
directory.Add(name, number);
}
return directory;
}
public static void writeXML(Hashtable directory, string fileName)
{
XmlDocument document = new XmlDocument();
XmlDeclaration declaration = document.CreateXmlDeclaration("1.0", "UTF-8", null);
XmlElement root = document.CreateElement("directory");
document.AppendChild(declaration);
document.AppendChild(root);
foreach (DictionaryEntry entry in directory)
{
XmlElement element = document.CreateElement("extension");
element.SetAttribute("name", entry.Key.ToString());
element.SetAttribute("number", entry.Value.ToString());
root.AppendChild(element);
}
document.Save(fileName);
}
view raw xml.cs hosted with ❤ by GitHub

出来上がったXML形式のファイルです。

<?xml version="1.0" encoding="UTF-8"?>
<directory>
<extension name="L. G." number="8209" />
<extension name="L. D." number="8220" />
<extension name="F. G." number="8227" />
<extension name="J. Q." number="8214" />
<extension name="K. P." number="8215" />
</directory>
view raw directory.xml hosted with ❤ by GitHub

金曜日, 7月 03, 2015

配列をムダなく並び替える

ここでは配列をムダなく並び替える方法を提案します。

提案というより、いつもの「ループをまわして違う値が出るまで繰り返す」という方法をやめようという提案です。

何度もまわしていれば終わる作業ではあるはずですが、当然のごとくこのアルゴリズムだと終わるという確証がありません。

カウンタなどつけていれば無限ループという最悪の事態は防げるわけですが、ここでは「乱数は配列の大きさだけ計算すればいいはず」というアルゴリズムの提案です。

大げさなことはないわけなのですが、計算しなければならない乱数ってのは「まだ選択されていない数からのみ」なわけなので、その方法を示します。

まずはコード permute() をご覧ください。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Permute
{
class Program
{
// Permute 0 .. n
static int[] permute(int n)
{
Random random = new Random();
int[] index = new int[n];
int[] x = new int[n];
for (int i = 0; i < n; i++)
{
int r = random.Next(n-i)+1;
int count = 0;
int j = 0;
for (; j < n;j++)
{
if (index[j] == 0)
count++;
if (r <= count)
break;
}
if(j<n)
{
x[i] = j;
index[j] = 1;
}
}
return x;
}
// Select max elements from 0 .. n
static int[] withoutDuplicate(int n, int max)
{
Random random = new Random();
int[] index = new int[n];
int[] x = new int[max];
for (int i = 0; i < max; i++)
{
int r = random.Next(n - i) + 1;
int count = 0;
int j = 0;
for (; j < n; j++)
{
if (index[j] == 0)
count++;
if (r <= count)
break;
}
if (j < n)
{
x[i] = j;
index[j] = 1;
}
}
return x;
}
// Select [max] elements from 0 .. n excluding [excluded]
static int[] selectWithout(int n, int max, int excluded)
{
Random random = new Random();
int[] index = new int[n];
int[] x = new int[max];
for (int i = 0; i < max; i++)
{
int r = random.Next(n - i) + 1;
int count = 0;
int j = 0;
for (; j < n; j++)
{
if (index[j] == 0 && j != excluded)
count++;
if (r <= count)
break;
}
if (j < n)
{
x[i] = j;
index[j] = 1;
}
}
return x;
}
static void Main(string[] args)
{
int[] x=Program.permute(10);
foreach(int i in x)
{
Console.Write(i+" ");
}
Console.ReadLine();
int[] y = Program.withoutDuplicate(10, 3);
foreach(int i in y)
{
Console.Write(i + " ");
}
Console.ReadLine();
int[] y = Program.selectWithout(10, 3, 6);
foreach (int i in y)
{
Console.Write(i + " ");
}
Console.ReadLine();
}
}
}
view raw Permute.cs hosted with ❤ by GitHub
… というわけです。選択されていない中から選ぶので乱数の計算が配列の大きさで済むというわけです。

どうでしょうか。

permute() の応用で、重複しない要素を選択する関数 withoutDuplicate(int n, int max) というのも作れます。

selectWithout(int n, int max, int excluded) は選択すべき要素から一定要素を除いた重複しない要素を選択する関数です。

よく使うアルゴリズムだと思います。

火曜日, 6月 23, 2015

コマンドラインでシカゴの気温を調べる(C# で JSON データを読む)

先日 Java での JSON データの読み方を紹介しました。

ここでは C# で JSON データを読む方法を紹介します。

DataContractJsonSerializer を使った方法です。

DataContractJsonSerializer.ReadObject() を使うと JSON データを読み、オブジェクトとして出力してくれます。

オブジェクトへの変換が「宣言」となっているところがいくらか分かりやすいといえるでしょうか。

まず、読み込みたいデータ構造をクラスとして宣言し、DataContract 属性を付加します。JSON データは DataMember 属性を付加します。ネストされているデータはクラスとして宣言しDataContract 属性を付加します。コードを参照してください。#配列データは配列として宣言します。

出来上がったデータクラスを DataContractJsonSerializer のコンストラクタの引数として渡します。

準備が出来たらHttpWebResponse として読んできたデータを、DataContractJsonSerializer.ReadObject() で読み込みます。

と、この手順を踏むとめでたく JSON データが読み込めます。あとは出力するだけ。

ここの気温の表示はデフォルト設定でなんとK(ケルビン)です。ので 273.15 を引いてやります。

#華氏(℉)か摂氏(℃)か迷ったんでしょうか(もめたんですかね)。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading.Tasks;
using System.Net;
namespace JSONTest
{
class Program
{
static void Main(string[] args)
{
try
{
String url = "http://api.openweathermap.org/data/2.5/weather?q=chicago";
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception(String.Format(
"Server error (HTTP {0}: {1}).",
response.StatusCode,
response.StatusDescription));
DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Response));
object objResponse = jsonSerializer.ReadObject(response.GetResponseStream());
Response jsonResponse = objResponse as Response;
//Console.WriteLine(jsonResponse.main.temp - 273.15);
jsonSerializer.WriteObject(Console.OpenStandardOutput(), jsonResponse);
Console.ReadLine();
}
}
catch (Exception e)
{
Console.Error.WriteLine(e.ToString());
//throw e;
Console.ReadLine();
}
}
}
[DataContract]
public class Response
{
[DataMember(Name = "main")]
public Main main { get; set; }
[DataMember(Name = "coord")]
public Coord coord { get; set; }
[DataMember(Name = "sys")]
public Sys sys { get; set; }
[DataMember(Name = "weather")]
public Weather[] weather { get; set; }
[DataMember(Name = "wind")]
public Wind wind { get; set; }
[DataContract]
public class Coord
{
[DataMember(Name = "lon")]
public double lon { get; set; }
[DataMember(Name = "lat")]
public double lat { get; set; }
}
[DataContract]
public class Sys
{
[DataMember(Name = "message")]
public double message { get; set; }
[DataMember(Name = "country")]
public string country { get; set; }
[DataMember(Name = "sunrise")]
public long sunrise { get; set; }
[DataMember(Name = "sunset")]
public long sunset { get; set; }
}
[DataContract]
public class Weather
{
[DataMember(Name = "id")]
public long id { get; set; }
[DataMember(Name = "main")]
public string main { get; set; }
[DataMember(Name = "description")]
public string description { get; set; }
[DataMember(Name = "icon")]
public string icon { get; set; }
}
[DataMember(Name = "base")]
public string _base { get; set; }
[DataContract]
public class Main
{
[DataMember(Name = "temp")]
public double temp { get; set; }
[DataMember(Name = "temp_min")]
public double temp_min { get; set; }
[DataMember(Name = "temp_max")]
public double temp_max { get; set; }
[DataMember(Name = "pressure")]
public double pressure { get; set; }
[DataMember(Name = "sea_level")]
public double sea_level { get; set; }
[DataMember(Name = "grnd_level")]
public double grnd_level { get; set; }
[DataMember(Name = "humidity")]
public long humidity { get; set; }
}
[DataContract]
public class Wind
{
[DataMember(Name = "speed")]
public double speed { get; set; }
[DataMember(Name = "deg")]
public double deg { get; set; }
}
[DataContract]
public class Clouds
{
[DataMember(Name = "all")]
public long all { get; set; }
}
[DataMember(Name = "dt")]
public long dt { get; set; }
[DataMember(Name = "id")]
public long id { get; set; }
[DataMember(Name = "name")]
public string name { get; set; }
[DataMember(Name = "cod")]
public long cod { get; set; }
}
}

木曜日, 6月 11, 2015

コマンドラインでシカゴの気温を調べる(Java で JSON データを読む)

なんと、近々発表されるはずの Java 9 から JSON ライブラリが外されてしまいました。

これは、政治ですね?(笑・XML派の妨害ですね。)

JSON ってコンパクトですよね。名前なしの{}(中括弧)を使うところが XML 形式より多少なりとも不確実ではあっても記述が短くて済むわけです。

openweathermap サイトのデフォルト設定は JSON 出力です。

{"coord":{"lon":-87.65,"lat":41.85},"sys":{"message":1.2238,"country":"US","sunrise":1434017699,"sunset":1434072341},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"base":"stations","main":{"temp":290.857,"temp_min":290.857,"temp_max":290.857,"pressure":1002.52,"sea_level":1024.25,"grnd_level":1002.52,"humidity":74},"wind":{"speed":2.13,"deg":53.5001},"clouds":{"all":48},"rain":{"3h":0.595},"dt":1434048065,"id":4887398,"name":"Chicago","cod":200}
view raw Chicago Weather hosted with ❤ by GitHub


このサイトは天気情報を提供してくれます。都市名とかを URL で送ってやると天気情報を返してくれます。

そこで、「ねえ、パーサーを書いたら?」とかいう余計な手間をかけたくない忙しいプログラマのため org.json.simple ライブラリの使い方を紹介します。

まず JSON.simple JAR ファイルをダウンロード


データを読み込むプログラムの手順を示します。

  1. まず、JSONParser オブジェクトをインスタンス化。
  2. URL オブジェクトから InputStreamReader、BufferedReader をインスタンス化。
  3. JSONParser.parse() でパース。
  4. あとは JSONParser.get() で要素を読んでいくだけです。
  5. ネストされている要素であれば、JSONParser オブジェクトとして扱う。

// WeatherApp.java -- Get Chicago weather from openweathermap site
// Copyright (c) 2015 easai
// Author: easai
// Created: Thu Jun 11 13:23:04 2015
// Keywords:
// This file is not part of GNU Emacs.
// WeatherApp.java is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
// This software is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; see the file COPYING. If not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
// Commentary:
//
//
//
// Code:
import java.io.*;
import java.net.*;
import java.util.*;
import org.json.simple.*;
import org.json.simple.parser.*;
public class WeatherApp
{
public static void main(String args[])
{
JSONParser parser=new JSONParser();
try
{
URL url = new URL("http://api.openweathermap.org/data/2.5/weather?q=chicago");
try (BufferedReader reader
= new BufferedReader(new InputStreamReader(url.openStream())))
{
JSONObject obj = (JSONObject)parser.parse(reader);
JSONObject main = (JSONObject)obj.get("main");
double temp = (double)main.get("temp")-273.15;
System.out.println(temp);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
// WeatherApp.java ends here
view raw WeatherApp.java hosted with ❤ by GitHub

あとは、JAR ファイルとコンパイルするだけ。

javac -classpath "JARファイルのあるディレクトリ;." WeatherApp.java
これで、コマンドラインからシカゴの気温が検索できます。

月曜日, 4月 20, 2015

Matlab でカージオイドを描く

Matlab でカージオイドを描いてみました。
t=1:.0001:3*pi;
x=(1+cos(t)).*sin(t);
y=-1.9.*(1+cos(t)).*cos(t);
plot(x,y);
axis([-1.5 1.5 -4 .7]);
title('Cardioid');
ylabel('y=-1.9.*(1+cos(t)).*cos(t)');
xlabel('x=(1+cos(t)).*sin(t)');
view raw cardioid hosted with ❤ by GitHub

水曜日, 2月 25, 2015

Java: データ・マイニング ECLAT変換

データ・マイニングなんぞでデータ変換など需要がありましたので、プログラムなど置いておきます。

変換といっても縦のものを横にするという種類のもので、こんな感じです。


 アルファベットが項目で、数字がIDです。

走らせるとアルファベットからIDを列挙します。

import java.util.*;
// Equivalence Class Transformation
public class ECLAT
{
public static void main(String args[])
{
HashMap<Integer, byte[]> hash=new HashMap<>();
hash.put(10,new String("acde").getBytes());
hash.put(20,new String("abe").getBytes());
hash.put(30,new String("bce").getBytes());
Set<Integer> keys=hash.keySet();
TreeSet<Integer> sortedKeys=new TreeSet<>();
TreeSet<Character> itemset=new TreeSet<>();
for(Integer key: keys)
{
sortedKeys.add(key);
}
for(Integer key: sortedKeys)
{
System.out.print(key+" | ");
byte[] buf=hash.get(key);
for(int i=0;i<buf.length;i++)
{
itemset.add((char)buf[i]);
System.out.print((char)buf[i]);
if(i<buf.length-1)
System.out.print(",");
}
System.out.println();
}
System.out.println();
for(Character ch: itemset)
{
System.out.print(ch+" | ");
for(Integer key: sortedKeys)
{
byte[] buf=hash.get(key);
int i=0;
while(buf[i]!=ch && ++i<buf.length){}
if(i<buf.length)
{
System.out.print(key+", ");
}
}
System.out.println();
}
}
}
view raw ECLAT.java hosted with ❤ by GitHub

火曜日, 2月 24, 2015

Java: 楕円銀河

銀河系ってのはさまざまな形をしていますが、楕円形ってのがもっとも多いわけです。

楕円形のつぶれかたで記号までついてるわけですね。

E0 から E7 まであるわけですが、E0 がもっとも丸い。E7 がつぶれた形をしている。



こんなのを Java でインタラクティブで動かせたらいいかな、というんで書いてみました。

そのままコンパイルすると動くはずです。です。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.geom.*;
public class EllipticalGalaxies
{
public static void main(String args[])
{
new EllipticalFrame();
}
}
class EllipticalFrame extends JFrame implements ActionListener
{
EllipticalPanel panel=new EllipticalPanel();
JButton plus=new JButton("+");
JButton minus=new JButton("-");
EllipticalFrame()
{
setTitle("Elliptical Gallaxies");
setSize(500,500);
setVisible(true);
JPanel control=new JPanel();
control.setLayout(new FlowLayout());
control.add(plus);
control.add(minus);
getContentPane().add(control,BorderLayout.NORTH);
getContentPane().add(panel,BorderLayout.CENTER);
plus.addActionListener(this);
minus.addActionListener(this);
}
public void actionPerformed(ActionEvent event)
{
String cmd=event.getActionCommand();
if(cmd.equals("+"))
{
panel.n++;
repaint();
}
else
{
panel.n--;
repaint();
}
if(7<panel.n)
panel.n=7;
if(panel.n<0)
panel.n=0;
}
}
class EllipticalPanel extends JPanel
{
int n=0;
public void paint(Graphics graphics)
{
Graphics2D g=(Graphics2D)graphics;
int w=getWidth();
int h=getHeight();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g.setColor(Color.black);
g.fillRect(0,0,w,h);
g.setColor(Color.white);
int r=(int)w/8;
int x0=r;
int y0=r;
int d=(int)3*w/4;
if (w<h)
{
h=(int)w/8;
d=(int)3*w/4;
}
y0=(int)((h-d)*.5);
y0=(int)((h-(1-n/10.0)*d)*.5);
int dh=(int)(((1-n/10.0)*d));
float dash[]={10.0f};
Stroke stroke=new BasicStroke(3.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f);
g.setStroke(stroke);
g.draw(new Ellipse2D.Double(x0,y0,d,dh));
g.setColor(Color.white);
Font font=new Font("Arial",Font.BOLD,30);
FontMetrics fm=g.getFontMetrics(font);
String label="E"+n;
int stringWidth=fm.stringWidth(label);
int stringHeight=fm.getHeight();
g.setFont(font);
g.drawString(label,(int)((w-stringWidth)*.5),(int)((h+stringHeight*.5)*.5));
}
}
view raw gistfile1.txt hosted with ❤ by GitHub

火曜日, 1月 13, 2015

Java: BigInteger で階乗を計算する

自然数ってのは限りがありません。もし上限 n があったと仮定すると、 n+1 が整数、これは矛盾します。よって上限はない。数学ってのは証明ができていいですね。

ところがいざプログラムで実装となるとガラスの壁ってのがあるわけです。ご存じのとおり整数型の上限は64ビット long で -9223372036854775808 から 9223372036854775807。

これだともっと大きな整数は扱えません。そこで、Java では整数を抽象化し、BigInteger として制限のない整数を表現します。

この BigInteger、四則演算は揃っているのですが、演算メソッドが限られていて、階乗がありません。いちいち定義すればいいわけですが、こんなところで立ち止まっていては世界が見えてこない。

そこで、BigInteger で階乗を計算するコードを載せておきます。

public static BigInteger factorial(BigInteger x){
return factorial(x,BigInteger.ONE);
}
public static BigInteger factorial(BigInteger x, BigInteger lowerLimit) throws NumberFormatException{
BigInteger res=BigInteger.ONE;
if(x.equals(BigInteger.ZERO))
{
return res;
}
else if(x.compareTo(BigInteger.ZERO)<0 || x.compareTo(lowerLimit)<0)
{
throw new NumberFormatException();
}
BigInteger i=lowerLimit;
for(;i.compareTo(x)<=0;i=i.add(BigInteger.ONE))
{
res=res.multiply(i);
}
return res;
}
view raw factorial.java hosted with ❤ by GitHub


この階乗を使うと、組み合わせなど計算ができます。階乗で定義されるやつですね。

public static BigInteger combinatoire(BigInteger n, BigInteger k){
BigInteger res=BigInteger.ZERO;
if(n.compareTo(k)==0)
res=BigInteger.ONE;
else if(k.equals(BigInteger.ONE))
res=n;
else if(n.equals(BigInteger.ONE))
res=BigInteger.ONE;
else if(n.compareTo(k)<0)
res=BigInteger.ZERO;
else if(0<n.compareTo(k))
res=Combinatoire.factorial(n).divide(Combinatoire.factorial(k).multiply(Combinatoire.factorial(n.subtract(k))));
));
return res;
}


実はこの組み合わせ、再帰で定義できます。パスカルの三角形といわれるやつです。



public static BigInteger combinatoire(BigInteger n, BigInteger k){
BigInteger res=BigInteger.ZERO;
if(n.compareTo(k)==0)
res=BigInteger.ONE;
else if(k.equals(BigInteger.ONE))
res=n;
else if(n.equals(BigInteger.ONE))
res=BigInteger.ONE;
else if(n.compareTo(k)<0)
res=BigInteger.ZERO;
else if(0<n.compareTo(k))
res=combinatoire(n.subtract(BigInteger.ONE),k.subtract(BigInteger.ONE)).add(combinatoire(n.subtract(BigInteger.ONE),k));
return res;
}
view raw Pascal.java hosted with ❤ by GitHub
証明はこちら。

Qt: 外部プログラムを起動する

  Qt/C++ のアプリは、外部へ直接アクセスできます。これはネットアプリでは不可能な Qt のメリットです。 外部プログラムを起動することもできます。QProcess::startDetached() を使うと独立したプロセスを立ち上げることができます。 この QProces...