プログラマの数学

とりあえず、プログラマの数学を買ってみた。

今更ながら、簡単なところから読み飛ばさずに理解しながら読んでみようかなと。

初歩的なところですが、なぜnの0乗が1なのかにガッテンしました。

プログラマの数学

プログラマの数学

Share

この前作ったサンプルのデザインだけ流用して1時間以内でお小遣い帳にしてみた

仕様は、

・持ち金をチャージできる。

・チャージ時の総額と総利用額と残金を表示。

・使った時は、何に使ったかと金額を入力。

・過去20件の利用データを表示。

・過去100件の利用データ中の何に使ったかをドロップダウン表示して選択できる。

・エラーチェックはまだしていない。

・オモローと表示していた部分を「ご利用は計画的に。」に変更。

気づいたこと。知ったこと。

・djangoのテンプレートに渡す値にmodelを使えるのが管理が煩雑にならないので楽だと思った。

・GQLでSQLのTOP 20をやりたいときは、ORDER BY等の後にLIMIT 20とやる。

・ORDER BY等はおおむねSQLと同じ。

・時間制限のため、コードが汚い(エクスキューズです。)。

・datetime型を使う場合はdatetimeモジュールをインポートする。

・djangoのテンプレート側で四則演算が出来ない。

・スペルミスで結構エラーになった。

サンプルか修正したオブジェクトだけ表示。

・テンプレート

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="ja" xml:lang="ja" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{{ userName }}のお小遣い帳</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link href="./styles/styles.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="./scripts/util.js" ></script>
<script type="text/javascript" src="./scripts/index.js" ></script>
</head>
<body>
<div id="body">
<div id="header">
<div id="user">
お小遣い帳
</div>
<div id="navigationOperation" >■</div>
</div>
<div id="navigation" >
<div id="logonControl">
{{ userName }} <br />
<a href="{{ logoutUrl }}">ログオフ</a>
</div>
<div id="settings">
<form action="/" method="post">
<div>年間チャージ額:<br /><input type="text" name="chargedValue" value="{{ setting.chargedValue }}" tabindex="1" accesskey="1" /><br /></div>
<div>前回チャージ後総額:<br />{{ setting.properValue }}円<br /></div>
<div>総利用額:<br />{{ setting.totalPayment }}円<br /></div>
<div>残額:<br />{{ currentValue }}円<br /></div>
<div><input type="submit" value="設定"  tabindex="2" accesskey="s" /></div>
{% if settingErrorMessage %}
<div class="errorMessage">{{ settingErrorMessage }} </div>
{% endif %}
</form>
</div>
</div>
<div id="contents">
<form action="/" method="post">
<div>使った内容:<select name="titles" tabindex="3">
<option value="" selected="selected"></option>
{% for value in titles %}
<option value="{{ value }}" >{{ value }}</option>
{% endfor %}
</select><input type="text" name="title" value="" tabindex="4" accesskey="c" /></div>
<div>使った金額:<input type="text" name="payment" value="" tabindex="5" accesskey="3" /><br /></div>
<div><input type="submit" value="設定"  tabindex="6" accesskey="s" /></div>
{% if paymentErrorMessage %}
<div class="errorMessage">{{ paymentErrorMessage }} </div>
{% endif %}
</form>
<div id="list" >
過去20件の利用状況:
<table border="1" cellspacing="0" >
<tr>
<th>日付</th>
<th>使った内容</th>
<th>金額</th>
</tr>
{% for value in outputValues  %}
<tr>
<td>{{ value.date }}</td>
<td>{{ value.title }}</td>
<td>{{ value.value }}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
<div id="footer">ご利用は計画的に。</div>
</div>
</body>
</html>

・データモデル

# -*- coding: utf-8 -*-
from google.appengine.ext import db
class UserMaster(db.Model):
#paymentを利用するユーザのマスタを定義するクラスです。
#db.Modelを継承しています。
author = db.UserProperty()
chargedValue = db.IntegerProperty()
totalPayment = db.IntegerProperty()
properValue = db.IntegerProperty()
class PaymentInfo(db.Model):
author = db.UserProperty()
title = db.StringProperty()
value = db.IntegerProperty()
date = db.DateTimeProperty(auto_now_add=True)

・index.py

# -*- coding: utf-8 -*-
import wsgiref.handlers
import cgi
import datetime
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.api import users
import models
import os
from google.appengine.ext.webapp import template
from google.appengine.ext.db import djangoforms
class MainPage(webapp.RequestHandler):
def view(self,user,settingErrorMessage = None,paymentErrorMessage = None):
settings = models.UserMaster.gql("where author = :author",author=user)
setting = None
if settings.count() > 0:
setting = settings[0]
else:
setting = models.UserMaster()
setting.author = user
setting.chargedValue = 600000
setting.properValue = setting.chargedValue
setting.totalPayment = 0
setting.put()
outputValues = models.PaymentInfo.gql("where author = :author order by date DESC LIMIT 20",author=user)
titles = self.titles(user)
template_values = {
'userName' : user.nickname(),
'logoutUrl': cgi.escape(users.create_logout_url("/")),
'setting' : setting,
'currentValue':setting.properValue - setting.totalPayment,
'outputValues': outputValues,
'titles': titles,
'settingErrorMessage': settingErrorMessage,
'paymentErrorMessage': paymentErrorMessage
}
path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, template_values))
def titles(self,user):
selections = models.PaymentInfo.gql("where author = :author order by title",author=user)
values = []
prev = ''
for value in selections:
if prev != value.title:
values.append(value.title)
prev = value.title
return values
def get(self):
user = users.get_current_user()
if not user:
self.redirect(users.create_login_url(self.request.uri))
return
self.view(user)
def post(self):
user = users.get_current_user()
if not user:
self.redirect(users.create_login_url(self.request.uri))
return
if self.request.get('chargedValue'):
if self.request.get('chargedValue').isdigit():
settings = models.UserMaster.gql("where author = :author",author=user)
setting = settings[0]
setting.properValue = setting.properValue + int(self.request.get('chargedValue'))
setting.put()
else:
self.view(user,u'チャージ金額には数字を入力してください。')
return
else:
payment = models.PaymentInfo()
payment.author = user
if len(self.request.get('titles')) == 0:
payment.title = self.request.get('title')
else:
payment.title = self.request.get('titles')
payment.value = int(self.request.get('payment'))
payment.put()
settings = models.UserMaster.gql("where author = :author",author=user)
setting = settings[0]
setting.totalPayment = setting.totalPayment + payment.value
setting.put()
self.view(user)
def main():
application = webapp.WSGIApplication(
[('/', MainPage)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == '__main__':
main()
Share

Microsoft Equipt(office+OneCareのサブスクリプション)

Equiptは、サブスクリプション版のOffice HomeおよびStudentに、Microsoftが提供するウイルス対策製品となる「OneCare」をバンドルしており、OneCare単体での推奨購入価格より20ドルだけ高い、年間69ドルの利用価格が設定されている。

MS、Officeのサブスクリプションサービス「Microsoft Equipt」を発表:ニュース – CNET Japan

これは、うれしい。

日本に展開される事があるのか、展開されるとしたらいつなのかは、全然謎だけど。

Share

.NET関連で困った時に調べる順番

.NET関連で困った時、昔は

1.Google

2.MSDN

という順番だったのだが結局正しい情報として検索結果の中からMSDを選択することが多かったので、最近は

1.MSDN

2.Microsoftの開発者向け情報サイト(http://asp.net等)

2.Google

という順番が多い。

そして、大抵1番で終了するパターンが多い。

あえてGoogleを使うときもMSDNの中を検索する為に利用する事が多い。

ナレッジベースなんかはGoogleでKB{番号}で検索した方が明らかに早いし。

それだけに、MSDNの重さとか、使いやすさがもうちょっと、どうにかならんもんかなと思う。

Share
カテゴリー: .NET

Hotmailのインタフェースに不満

用があって久しぶりにHotmailを使ってみた。

未読メールが死ぬほどあったので、一括で既読にしたかったんだけど、なぜかツールバーに存在するのは

「未開封にする」

のみだった。

結局、未読メールを既読にするのは諦めてブラウザを閉じた。

「開封済みにする」がなんで無いのだろうか・・・。

追記:

コメントでご指摘していただいたので、いろんな環境でアクセスしたところ。

どうも、標準バージョンだと「未開封にする。」しかできないだけのようです。

IEを利用して拡張バージョンのUIを使う事で、コンテキストメニューに「開封済みにする。」が表示されました。

これで、とりあえず纏めて開封済みにできました。

標準バージョンにも、「開封済みにする。」を用意しておいてほしいですね。

なんとか目的を達成できましたが、とりあえず、インタフェースに不満があることには変わりないですね。

とりあえず、FireFox2.0でも拡張バージョンが使えると書いてあったので、是非3.0にも対応してほしいところです。

ヘルプを見てみましたが、「拡張バージョン」とか「標準バージョン」とかが明記されていないですね。

「拡張バージョンの時のみできる」等の記述があれば良いのにと思いました。

http://help.live.com/help.aspx?project=mailfull&market=ja-jp&querytype=topic&query=wl_mail_proc_markreadunread.htm

まあ、そんなに利用しないので良いのですが・・・。

ちなみに、gmailは、簡易HTML表示でもちゃんと、一通りの操作ができるようになっていました。

Share
カテゴリー: Tool

匿名メソッドで再帰を実装する時

通常匿名メソッドを実装する時は、宣言と代入が同じになるパターンが多い。

例えば、下記のコードのように。

public void 匿名メソッドで再帰()
{
Func<int, bool> カウントダウン = (x) =>
{
if (x == 0)
{
return true;
}
Console.WriteLine(x);
x--;
return カウントダウン(x);
};
カウントダウン(40);
}

しかし、上記のコードだと、

未割り当てのローカル変数 'カウントダウン' が使用されました。

と言われてコンパイルエラーになる。

では、どうしたら良いかというと、先に匿名メソッドを代入する変数を宣言しておけばよい。

下記のコードならコンパイルエラーにならないで正しく動作する。

public void 匿名メソッドで再帰()
{
Func<int, bool> カウントダウン = null;
カウントダウン = (x) =>
{
if (x == 0)
{
return true;
}
Console.WriteLine(x);
x--;
return カウントダウン(x);
};
カウントダウン(40);
}
Share

パズル:nまでの整数を二つの組に分けて合計した結果が同じ時のnについて見つけた法則の実証をバイナリサーチで

なんでそうなのかをコンピュータによる実証以外に証明する事ができないので、ドラクエで言うと、まだ冒険の書を作ったところ。

いや、冒険の書すら作れていないのか。

nまでの整数を二つの組に分けて合計した結果が同じ時のnについて見つけた法則 – NAL-6295の舌先三寸

最近、続けている話題ですが、とりあえず見つけた法則が正しいのかどうかを実証するために法則を見つける前のコードをPCで実行させてみたら、さすがに死ぬほど時間がかかって800000に辿りつくまでですら一晩かかったので、バイナリサーチで書き直してみた。

配列なら、Array.BinarySearchがあるのだけれども・・・。

バイナリサーチにしたら、intの幅に関しては、1時間20分くらいで、戻ってくるようになった。

アルゴリズム一つでぜんぜん違うという事を改めて(今更ながら)実感。

public void nまでの整数を二つの組に分けて合計した結果が同じだった数字リスト実証()
{
Func<int, bool> 奇数が奇数個ある = x => ((x / 2) + (x % 2)) % 2 != 0;
//Enumerable.Select().Sum()は使わない方向で
Func<long, long, long> xからyまでの計 = (x, y) => ((x + y) * ((y - x + 1) / 2)) + (((y + x) / 2) * ((y - x + 1) % 2));
Func<int, long,long,long, bool> nまでの数字の合計の半分とnを二つの組にした合計が同じものがある = null;
nまでの数字の合計の半分とnを二つの組にした合計が同じものがある = (n, 総和の半分, 始点, 終点) =>
{
long 探索点 = (終点 + 始点) / 2;
long 総和 = xからyまでの計(探索点, (long)n);
if (総和 == 総和の半分)
{
return true;
}
if (始点 == 終点)
{
return false;
}
if (総和 > 総和の半分)
{
始点 = 探索点;
}
else
{
終点 = 探索点;
}
if (始点 + 1 == 終点)
{
if (総和 > 総和の半分)
{
始点++;
}
else
{
終点--;
}
}
return nまでの数字の合計の半分とnを二つの組にした合計が同じものがある(n, 総和の半分, 始点, 終点);
};
var 該当するnのリスト = Enumerable
.Range(2, int.MaxValue - 2)
.Where(n => !奇数が奇数個ある(n) && nまでの数字の合計の半分とnを二つの組にした合計が同じものがある(n, xからyまでの計(1, n) / 2, 1, n))
.Select(n => n);
foreach (var n in 該当するnのリスト)
{
Console.WriteLine(n);
}
}
Share
カテゴリー: C#

実力があっても生かせないのなら、会社にとっては実力が無いのと同じ

いろいろと、勿体ないけど、実力があってもそれを利用して仕事に生かせないのなら会社にとっては実力が無いのと同じだ。

炊飯する実力はあるのに炊飯ボタンが無い炊飯器のようなもん。

つまり、インタフェースが無くちゃ駄目だということ。

本当に実力がある人はちゃんと報われているはず。

ちなみに実力があるということと、知識が豊富ということは必ずしもイコールではない。

道具を持ってしまったばかりに、道具に使われちゃう人もいますからね。

Share

10のコーディングルール

以前、コードの10戒と題して、犬の10戒をまねしたコーディングルールを掲載しました。

しかし、若干カジュアルすぎるため仕事に適用するには文体を改修する必要があるかもしれません。

長いコーディング標準は、読むのも守るのもメンテするのも大変です。

なので、短いけど守ってほしい事と理由を犬の10戒の真似をしてまとめてみました。

コードの10戒 – NAL-6295の舌先三寸

そこで今回は、これを少しフォーマルなものにしてみました。

  • 1.識別子(名前)は分かりやすいものにすること。
    参画するメンバーにより理解してもらうために分かりやすい名前にすること。
    メソッド名等が文章になってもかまわない。
    何をしようとしているのかを明示すること。
    全ての識別子はその存在理由が明確である必要がある。
    また、その存在理由以外の目的で利用しないこと。
  • 2.”共通"とか"common"といった名前を利用しないこと。
    共通で利用するメソッドや定数やクラスも、必ず存在理由がある。
    その役割にあった場所に配置すること。
  • 3.事前条件、事後条件を利用すること。
    メソッドの処理に入る前に引数がとりえる範囲を事前条件として指定し、範囲外であれば例外を飛ばして排除すること。
    そうすることで処理中で考えなくてはいけない範囲を狭く出来る。
  • 4.スコープは最小にすること。
    複数の問題が同時に存在していると、ミスリードしてバグを誘発する可能性が高くなる。
    変数のスコープだけではなく、処理、問題等全てのスコープを最小にすること。
  • 5.「将来のため」のコードを残さないこと。
    不必要なコードを「将来のため」といった理由で作りこまないこと。
    必要になってから作ったコードは使われるが、
    「将来のため」に作ったコードは使うかもしれないし、使わないかもしれない。
  • 6.作るときにチューニングをしないこと。
    チューニングは非機能要求にそった計測後、足りていない部分においてのみ行う事。
    コードの調和の取れた構成をできるだけ崩さないようにするため。
  • 7.レビューを行うこと。
    コードは必ずレビューをすること。
    また、レビューにおいて指摘された点は速やかに修正すること。
    複数の視点で見たコードはより分かりやすくなるため。
  • 8.テストをすること。
    コードは思いどおりには動かない。
    自分が思ったとおりにコードを書いているかテストして確認すること。
    そして思い通りに動かないときは、まず自分を疑うこと。
  • 9.バージョン管理は構成管理ツールに任せること。
    コードをコメントにして残さないこと。
    修正履歴をコメントで残さないこと。
    その全てを構成管理ツールに任せること。
  • 10.保守で修正する前に、必要な範囲の構成について理解すること。
    修正する箇所だけではなく、その周辺の構成に理解したうえで、その秩序を乱さないように修正すること。
Share