「標準出力」を含む日記 RSS

はてなキーワード: 標準出力とは

2017-09-11

https://anond.hatelabo.jp/20170910205249

まじな話をすると、N予備校プログラミング入門コースやるのがオススメ

https://www.nnn.ed.nico

一日8時間勉強時間があるなら、だいたい一ヶ月で終わる内容。

月額1000円だけどしっかり勉強すれば一ヶ月の無料間中に終わると思う。

もともとN高等学校のノンプログラマーの生徒をWebエンジニアとして就職させるために作られたカリキュラム講師曰く去年はこれで二人エンジニア就職を決めたらしい。

内容も相当親切に説明していて、プログラミングで何か作るだけじゃなくて、就職必要な環境構築やセキュリティまでみっちりやる。

http://qiita.com/sifue/items/7e7c7867b64ce9742aee#%E3%82%B3%E3%83%B3%E3%82%BB%E3%83%97%E3%83%88%E3%82%92%E3%82%82%E3%81%A8%E3%81%AB%E6%A7%8B%E6%88%90%E3%81%95%E3%82%8C%E3%81%9F%E3%82%B3%E3%83%BC%E3%82%B9%E3%81%A8%E5%86%85%E5%AE%B9

講師が書いてる入門コースで習うことがまとめ。テキスト教材もあるけど授業も1項目を2時間で説明している。授業は週2の生放送とそのアーカイブがある。

↓みたいなことが学べる

----

Webプログラミング入門コース

Web ブラウザとは (Chrome, デベロッパーコンソール, alert)

はじめてのHTML (VSCode, HTML, Emmet)

さまざまなHTMLタグ (h, p, a, img, ul, tableタグ)

HTMLで作る自己紹介ページ (HTMLタグ組み合わせ, コンテンツ埋め込み)

はじめてのJavaScript (JS, ES6, エラー)

JavaScriptでの計算 (値, 算術演算子, 変数, 代入)

JavaScript論理を扱う (論理値, 論理積, 論理和, 否定, 比較演算子, if)

JavaScriptループ (ループ, for)

JavaScriptコレクション (コレクション, 配列, 添字, undefined)

JavaScript関数 (関数, 関数宣言, 引数, 戻り値, 関数呼び出し, 再帰)

JavaScriptオブジェクト (オブジェクト, モデリング, プロパティ, 要件定義)

はじめてのCSS (CSS, セレクタ, background-color, border)

CSSを使ったプログラミング (transform, id, class)

Webページの企画とデザイン (企画, 要件定義, モックアップ, 16進数カラーコード)

診断機能の開発 (const, let, JSDoc, インタフェース, 正規表現, テストコード)

診断機能組込み (div, 無名関数, アロー関数, ガード句, truthy, falsy)

ツイート機能の開発 (リバースエンジニアリング, URI, URL, URIエンコード)

Linux開発環境構築コース

LinuxというOS (VirtualBox, Vagrant, Ubuntuインストール, OS, CUIの大切さ)

コンピューター構成要素 (ノイマンコンピューター, プロセス, lshw, man, ps, dfの使い方)

ファイル操作 (pwd, ls, cd, mkdir, rm, cp, mv, find, ホストマシンとの共有ディレクトリ)

標準出力 (標準入力標準出力標準エラー出力パイプgrep)

vi (vimtutor)

シェルプログラミング (シバン, echo, read, 変数, if)

通信ネットワーク (パケット, tcpdump, IPアドレス, TCP, ルーター, ping)

サーバークライアント (tmux, nc, telnet)

HTTP通信 (http, https, DNS, hostsファイル, ポートフォワーディング)

通信をするボットの開発 (cron, ログ収集)

GitHubウェブサイトの公開 (GitHub, リポジトリ, fork, commit, 情報モラル)

イシュー管理とWikiによるドキュメント作成 (Issues, Wiki)

GitとGitHub連携 (git, ssh, clone, pull)

GitHubへのpush (init, add, status, インデックス, commit, push, tag)

Gitのブランチ (branch, checkout, merge, gh-pages)

ソーシャルコーディング (コンフリクト、プルリクエスト)

Webアプリ基礎コース

Node.js (Node.js, nodebrew, Linux, REPL, コマンドライン引数, プルリク課題)

集計処理を行うプログラム (集計, 人口動態CSV, Stream, for-of, 連想配列Map, map関数)

アルゴリズムの改善 (アルゴリズム, フィボナッチ数列, 再帰, time, プロファイル, nodegrind, O記法, メモ化)

ライブラリ (ライブラリ, パッケージマネージャー, npm)

Slackボット開発 (slack, mention, bot)

HubotとSlackアダプタ (hubot, yo)

モジュール化された処理 CRUD, オブジェクトライフサイクル, filter)

ボットインタフェースとの連携 (モジュールのつなぎ込み, trim, join)

同期I/Oと非同期I/O (同期I/O, 非同期I/O, ブロッキング)

例外処理 (try, catch, finally, throw)

HTTPサーバー (Web, TCPとUDP, Webサーバーの仕組み, Node.jsイベントループ, リスナー)

ログ (ログ, ログレベル)

HTTPのメソッド (メソッド, GET, POST, PUT, DELETE, CRUDとの対応)

HTMLフォーム (フォームの仕組み, form, input)

テンプレートエンジン (テンプレートエンジン, jade)

HerokuWebサービスを公開 (Webサービスの公開, heroku, dyno, toolbelt, login, create, logs)

認証利用者を制限する (認証, Basic認証, Authorizationヘッダ, ステータスコード)

Cookie を使った秘密匿名掲示板 (Cookie, Set-Cookie, expire)

UI、URI、モジュール設計 (モジュール設計, フォームメソッド制限, リダイレクト, 302)

フォームによる投稿機能の実装 (モジュール性, textarea, 303)

認証された投稿の一覧表示機能 (パスワードの平文管理の問題, 404, テンプレートのeach-in)

データベースへの保存機能の実装 (データベース, PostgreSQL, 主キー)

トラッキングCookieの実装 (トラッキング Cookie, IDの偽装, Cookie の削除)

削除機能の実装 (データベースを利用した削除処理, 認可, サーバーサイドでの認可)

管理者機能の実装 (Web サービス管理責任, 管理者機能の重要性)

デザインの改善 (Bootstrap, レスポンシブデザイン, セキュリティの問題があるサイトを公開しない)

脆弱性 (脆弱性, 脆弱性で生まれる損失, 個人情報保護法, OS コマンド・インジェクション)

XSS脆弱性対策 (XSS, 適切なエスケープ処理, リグレッション)

パスワード脆弱性対策(ハッシュ関数, メッセージダイジェスト, 不正アクセス禁止法, パスワードジェネレーター, 辞書攻撃)

セッション固定化攻撃脆弱性対策 (セッション, セッション固定化攻撃, ハッシュ値による正当性チェック)

より強固なセッション管理 (推測しづらいセッション識別子, 秘密鍵)

CSRF脆弱性対策 (CSRF, ワンタイムトークン)

安全なHerokuへの公開 (脆弱性に対する考え方, HTTPの廃止)

Webアプリ応用コース

Webフレームワーク (Express.js, フレームワーク導入, 簡単なAPI, セキュリティアップデート, Cookie パーサー, ミドルウェア, 外部認証, ロガー)

ExpressのAPI (app, Properties, Request, Response, Router)

GitHubを使った外部認証 (Passport, OAuth)

スティングフレームワーク (Mocha, レッド, グリーン, リファクタリング)

継続的インテグレーション (CircleCI)

クライアントフレームワーク (Webpack, Chrome 以外のブラウザでもES6)

DOM操作フレームワーク (jQuery, jQueryアニメーション, this)

AJAX (jQuery.ajax, クロスドメイン, 同一生成元ポリシー, x-requested-by, CORS)

WebSocket (WebSocket, WebSocketの状態遷移, Socket.io)

RDBとSQL (DDL, DCL, CREATE, DROP, INSERT, DELETE, UPDATE, WHERE)

データモデリング (リレーショナルモデル, 正規化)

テーブルの結合 (外部結合, 内部結合, 片側外部結合, JOIN ON)

インデックス (インデックス, 複合インデックス, Bツリー)

集計とソート (SUM, COUNT, ORDER BY, GROUP BY)

「予定調整くん」の設計 (要件定義、用語集、データモデル、URL設計モジュール設計、MVC)

認証とRouterモジュールの実装 (Mocha, supertest, passport-stub, モックテスト)

予定とユーザーの保存 (セキュリティ要件, UUID, 複合主キー)

予定とユーザーの一覧の表示 (非同期処理, Promise, then)

出欠とコメントの表示 (入れ子の連想配列, Promise.all, 子どもからデータを消す)

出欠とコメント更新 (Promiseチェイン, リファクタリング)

予定の編集と削除 (要件の衝突, 関数再利用)

デザインの改善 (this, グローバルオブジェクト)

セキュリティ対策と公開 (X-Frame-Options, Heroku環境変数)

2017-08-14

医者って大変だな

アダンプとメトリックVIEWから判断して原因特定するしかない職人技だ

細胞ログ吐いてくれれば少しは楽になりそうだが、それはそれで集約が面倒そうだ

2017-08-14 08:30:23 胃 処理し切れない油もの標準エラー出力します
2017-08-14 15:11:56 腸 乳糖過多のため柔らかめのを標準出力します
2017-12-24 17:00:01 NK がん細胞を殺し切れませんでした、すみません

2016-08-02

http://anond.hatelabo.jp/20160727175016

どのように調べたのか。デバッガが使えない環境だとしても、標準出力ファイル出力、ウィンドウ表示など、いくらでも方法はあるだろう。他トラバでも指摘されているように、コードのものに不備がないのなら依存関係を含めて環境を疑うのが定石。

  • 見比べても違いがわからない

何と、何を、どのように見比べたのか。コードドキュメント目視diffコマンド?これもまた、他トラバでも指摘されているが、ドキュメント英文でも読むのは基本。それと、パンチャーなんていう時代ではないのだから現代プログラマーであれば、人間の力など信じてはいけない。

汎用的な解決方法試行錯誤できなくなったのであれば、

この 何か とは 解決力 だから、Fatal

2015-09-21

http://anond.hatelabo.jp/20150921151149

リアルな話、実際ハック的なことやる時はcatコマンド標準出力を何処かに流し込みながら作業とかは割とやるので、「よく見るパターン」ではあるけど別に誇張表現でもない気はするんぬ。

2014-07-01

php 画像表示で文字化けというか文字の羅列が表示されるとき readfile 使

readfile:

説明「ファイルを読んで標準出力に書き出します」

返り値「ファイルから読み込んだバイト数を返します」

header('Content-Type: image/jpeg') とか header("Content-Length: ???"); とか、ちゃんと書いているのに、ブラウザでなんで画像で表示されないんだろ...もしくは " headers already sent by ... "とエラー表示されてる... readfile のあと、データ出力前にソッコーで header 出力させているのになぁ。。

こんなとき、そのPHPコード、readfile の戻り値が読みこまれたデータである勘違いしてつくられてていませんか?

この件に限りませんが、サンプルコードとか勘違いが多いので要注意です。「脳内でうまく動いた」ものを、検証せずにそのままWEBに載せている人って結構ますから

ほかには php.ini の output_bufferingを On にしたら直った、phpファイルBOM 付き <?php や ?> の前後に空白や改行などがある、などが原因の場合もありますね。

2013-03-13

サーバ初心者Webサービスを公開するうえで考えたこと

だって自作Webサービス公開しました

http://www.radiosonde.net/

これまで他の人に用意してもらったサーバ自分プログラムを動かしたことはありましたが

自分自身で一からサーバをセットアップしたことはほとんどなかったので、いろいろとハマりました。

作業を進める上で困ったり考えたりしたことを書いていきます

ちなみにサーバ自体はさくらのクラウドOSにはCentOSを使用しているので、それ前提のお話になります

SSHファイヤーウォールの設定

最初サーバを起動してから速やかにSSHファイヤーウォールの設定を変更しました。

はてブなんかでも定期的に話題になっているのでおなじみですね。

SSHポートを22以外の別のポートに変更する

rootによるリモートログインを禁止する

パスワードログインを禁止し、鍵認証有効にする

・念のためrootパスワードを潰しておく

SSHHTTP(S)など、どうしても公開しなければならないポート以外は遮断する

SSHポートについてIP制限が行えるならば尚良い

さらっと書きましたが、設定をミスって自分自身もログインできなくなり、何度かOSの再インストールを繰り返しています

から気付いた事ですが、さくらのクラウドではクラウド管理画面のリモートスクリーン経由でローカルログインできるので

別にOSインストールしなくてもiptablesの設定を変更できたんですよね...

逆に言うといくらファイヤーウォールとSSHを設定しても管理画面にパスワードログイン環境が残ってしまうので

パスワード管理には引き続きしっかり気を使う必要がある。ということでもあります


Webアプリの動作が重い

httpd,php,mySQL,memcachedなど必要サービスインストール、設定し

作成したWebアプリプログラムを乗せて動かしてみました。が、動作が重いような...

開発環境ではさくさく動いていたのに、本番環境ではどのページ遷移ももっさりしています

abで計測してみたところ、開発環境のおよそ2分の1のスコアとなってしまいました。

開発環境が仮想2コアのメモリ1Gだったのに対し、本番環境が仮想1コアのメモリ2G

CPUの性能について半減しているのでそのせいかな、と思いつつ設定を見なおしていたところ

特に使っていないと思われたipv6を停止した途端にパフォーマンス改善されました。

ページ遷移に伴うもっさり感が解消され、abの計測結果も開発環境と遜色ない結果が出ています

デフォルト有効になっていたipv6の影響により余計な処理が走っていたのかもしれません。


サーバから送信したメール迷惑メールと判定される

パフォーマンス改善に喜んだのも束の間、会員登録などの処理でWebアプリからメールを送信したところ、Gmail宛のメールがことごとく迷惑メールと判定されるという事案が発生。

spfの設定を行なうメールの内容について吟味するなどの回避策を試してみましたが一向に改善されません。

試しにHotMailexciteメールアカウントに送信したところ、そちらではそもそもメールを受け付けてもらえずエラーコードが返って来る始末。

困り果てていたところ、エラーの内容からサーバIPがspamhousにスパム送信元として登録されていることが判明しました。

postfixホスト名の設定がデフォルトで「localhost.localdomain」などとなっており、それをそのまま使っていたためにGmailスパム送信元として通報してしまったようです。

設定を修正し、spamhousに解除依頼を提出。事なきを得ました。


KVSの変更

クラウドを利用すれば、サーバを停止することなく簡単な設定でスケールできるようになる。

と、自分勝手に思い込んでいたせいなのですが、消えては困るデータの一部をmemcachedに保存する実装を行なっていました。

実際のところさくらのクラウドではサーバを完全に停止しなければプラン変更を実施できないし

そもそもサーバが落ちたらどうするんだよ。ということで、急遽KVSを変更する必要に迫られました。

速度の低下が気にかかったため、いくつかの候補を実際に動かし

phpスクリプトから1万件のデータ読み書きを行うという形でmemcached比較してみたところ次のような結果に。

サービス1万件書込1万件読込
memcached 2.55秒 2.30秒
handlersocket 21.23 2.71秒
InnoDB20.23 5.10
kyotoTycoon 8.22秒 7.72秒

さすがに読み書きそれぞれmemcachedが最速ですが、読み出しについてはhandlersocketも負けていません。mySQLから普通にSELECTしてもmemcachedの2倍程度の時間しかからないという結果が意外でした。

しかしながら書き込みのほうではhandlersocketもmemcached10倍近くの時間がかかっており、少々速度的な影響が気になってきますmemcachedの倍のパフォーマンスを記録したという記事を見たことがあるので、設定、チューニングについて生かしきれていない部分があるのかもしれないとも思いましたが、知識が不足しているところで無理をすると問題が発生した時に対処できないと考え、候補から除外することとしました。

結局、今回の用途では読み込み処理より書き込み処理のほうが圧倒的に多いことも考慮し、kyotoTycoonを採用しました。実際の利用箇所に組み込んでabで計測してみたところ、だいたい30%程度のパフォーマンス低下にとどまっており、これなら許容範囲かと考えています

mySQLレプリケーションが止まる

実行系と参照系に分ける形でmySQLレプリケーションを行なっていたのですが、度々レプリケーションが停止する現象が発生しました。

一部のテーブルについて肥大する可能性が考えられたため、参照系に接続するプログラムで使わないテーブルをレプリケーションから除外していたのが原因です。

例えばtabelAをレプリケーションし、tableXをレプリケーションしないという設定にしたうえで

実行系でINSERT INTO `tableA` SELECT `value` FROM `tableX`などといったクエリを発行すると、参照系にtableXが無いためエラーが発生して止まってしまます

レプリケーションするテーブルを限定する場合プログラム側でも注意を払わないと危険です。当たり前ですが。

サーバ監視にmonitを使用

監視といえばcactinagios定番なのかもしれませんが、設定が複雑そうで尻込みし、monitを使用することにしました。

簡単な設定でloadaverageやメモリHDDの使用量をチェックできるほか

httpdmysqldなどといったサービスプロセス監視し、もし落ちていたら自動で起動してくれるので助かります

Webアプリの秘匿

パスワード保護を行うとしても、サイト全体の管理画面など自分しか使わないプログラムWeb晒しておきたくない。

というわけで、一部のWebアプリを秘匿する設定を行いました。

管理画面のWebアプリを9999番など閉じているポートに設置した上で、SSHを利用したトンネルを掘ります。といっても

ssh -t -L 9999:localhost:9999 user@xxx.xxx.xxx.xxx

上記のようなコマンド管理画面のWebアプリを置いたサーバログインするだけです。

ブラウザアドレス欄にhttp://localhost:9999/と打ち込めば、接続が開いている間のみアクセス可能になる感じですね。

サーバログインできる人でなければ実行できないことなので、気分的にある程度安心します。

SSHログバックアップ

自動ログバックアップを行いたいと考えたのですが、パスワード無しの鍵でログインして転送する形には抵抗がありました。

調べてみたところ、authorized_keysに公開鍵を記入する際の設定で、その鍵でできることを制限するという手段があるようでした。

具体的には、authorized_keysに

no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,command="some commands" ssh-rsa AAAAB3NzaC1yc2EAAA...

などとして公開鍵を追加しておくと、その鍵でログインした直後にcommand=""の部分で設定したコマンドを実行して接続を終了する挙動となり

接続フォワードもできなくなるため、パスワード無しでも鍵の流出に関するリスクを最低限に留めることができるというわけです。

commandの実行結果は標準出力から受け取ることができるので、例えばcommand=""の部分にファイルの内容を表示する処理を設定していたとすれば

ssh -i .ssh/no_password_key user@xxx.xxx.xxx.xxx > /path/to/file

などとしてログインの結果をファイルに書き込むだけで、簡単にファイル転送が実現できます


まとめ

他にも大小さまざまな問題に行きあたりましたが、忘れてしまったor書ききれないのでここまでとします。

たった1つのサイトを公開するにしても問題というのは尽きないものだと実感させられました。

今は基本的な情報だけでなく、ちょっと突っ込んだ内容でも検索で解決していけるので嬉しいですね。手がかりを残してくれた先達に感謝することしきりです。

現状ではひとまずの見切りを付けて公開していますが、より堅牢で負荷に強いサーバとなるよう、随時チューニングを行なっていこうと考えています

最後

作ったWebサービスについて少し書きます

サイト名は「Radiosonde」

個人サイトや小規模な商業サイトなどプロモーションにあまりお金をかけられないサイトを主な対象とした、無料で出稿できる広告ネットワークサービスです。

既存サービスで近いのは「あわせて読みたい」や「zenback」、各社提供RSS相互リンクサービスなどになるでしょうか。

広告としての体裁がある分、それらより若干積極的な性質になるのではと考えています

現時点ではサービス本体のプロモーションに苦心するという本末転倒のものの状況でありますが、もしよろしければ見ていただけると嬉しいです。

2013-02-21

めも

STDIN 標準入力キーボードから入力など。

STDOUT 標準出力。画面への出力など。

STDERR 標準エラーエラーとしての出力。

2011-03-30

http://anond.hatelabo.jp/20110330122305

ここを読めば、PHPPHPコードの実行が遅くて、JavaI/Oが遅い事が分かると思う。

特にJava標準出力に出したときは、内部文字コードシステムコードが異なるので、文字コード変換を毎回行っているはず。

なお、PHPはメソッド・コールが他のスクリプト言語と比較しても遅いPHPコード量が増えると、他のプログラミング言語よりも、速度の低下が激しくなる傾向がある。

利用目的が違うので、JavaPHPの速度比較なんて不毛だが、特性としては以上のような違いがある。

2010-01-14

http://anond.hatelabo.jp/20100113192313

これで40分。

タイムアタックってことでアルゴリズムは全幅探索で書き上げました。

エラーチェック皆無。

A*ならもう5分ほど延びるかな?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Maze
{
    class Program
    {
        // 探索用地図
        static int[,] maze;

        // 始点終点
        static Position Start = new Position(0, 0), Goal = new Position(0, 0);

        static void Main(string[] args)
        {
            //////////////////////////// まずは各行のリストとして読み込み
            string[] inMaze;

            using (var fp = new FileStream(args[0], FileMode.Open, FileAccess.Read))
            using (var iStream = new StreamReader(fp))
                inMaze = iStream.ReadToEnd().Split('\n');

            // 迷路幅
            int height = inMaze.Length;

            // 迷路高さ
            int width = inMaze[0].Length;

            /////////////////////////// 読み込んだ迷路を作業用地図に展開
            maze = new int[width, height];
            for (int y = 0; y < height; ++y)
            {
                string line = inMaze[y];
                for (int x = 0; x < line.Length; ++x)
                {
                    maze[x, y] = line[x] == '*'
                        ? -1
                        : 0;
                    if (line[x] == 'S') Start = new Position(x, y);
                    if (line[x] == 'G') Goal = new Position(x, y);
                }
            }

            // 探索実行
            int dist = Search(maze, Start);

            // 探索結果から最短経路を再現
            Position backTracer = Goal;
            while (dist&gt;1){
                --dist;
                backTracer = backTracer.Nearbys.First(pos =&gt; maze[pos.X,pos.Y] == dist);
                maze[backTracer.X, backTracer.Y] = -2;
            }

            //////////////////// 最短経路こみのアスキー地図に変換
            char[,] outMaze = new char[width, height];

            for (int y = 0; y < height; ++y)
            {
                for (int x = 0; x < width; ++x)
                {
                    outMaze[x, y] = maze[x, y] == -2
                        ? '$'
                        : maze[x, y] == -1
                            ? '*'
                            : ' ';
                }
            }
            outMaze[Start.X, Start.Y] = 'S';
            outMaze[Goal.X, Goal.Y] = 'G';


            ////////////////////// 結果は標準出力に。
            for (int y = 0; y < height; ++y)
            {
                for (int x = 0; x < width; ++x)
                    Console.Write(outMaze[x, y]);
                Console.WriteLine();
            }
            Console.ReadLine();
        }

        /// <summary&gt;
        /// 探索する。SG間の道のりを返す(道のり=SGが隣接しているなら1)
        /// </summary&gt;
        private static int Search(int[,] maze, Position Start)
        {
            List<Position&gt; FrontLine = new List<Position&gt;();
            FrontLine.Add(Start);
            int dist = 1;
            for (; ; )
            {
                List<Position&gt; NextFrontLine = new List<Position&gt;();
                foreach (var pos in FrontLine)
                {
                    foreach (var nextPos in pos.Nearbys)
                    {
                        if (nextPos == Goal) return dist;
                        if (maze[nextPos.X, nextPos.Y] == 0)
                        {
                            maze[nextPos.X, nextPos.Y] = dist;
                            NextFrontLine.Add(nextPos);
                        }
                    }
                }
                FrontLine = NextFrontLine;
                ++dist;
            }
        }
    }

    struct Position
    {
        public readonly int X, Y;
        public Position(int x, int y) { X = x; Y = y; }

        public IEnumerable<Position&gt; Nearbys
        {
            get
            {
                return new[]{
                    new Position(X-1,Y),
                    new Position(X,Y-1),
                    new Position(X+1,Y),
                    new Position(X,Y+1),
                };
            }
        }

        public static bool operator==(Position p1, Position p2){
            return p1.X == p2.X &amp;&amp; p1.Y == p2.Y;
        }

        public static bool operator!=(Position p1, Position p2){
            return p1.X != p2.X || p1.Y != p2.Y;
        }
    }
}

2009-03-10

http://anond.hatelabo.jp/20090310095053

オブジェクト指向はとりあえず無視していいし、ウィンドウアプリも無視していいから、プログラム原理というか入出力という概念を理解するとよし。

具体的に言えばコンソールアプリケーションのそれだ。

例えば、標準入力に「こんにちは」と入れたら「ごきげんよう」と標準出力に返すようなプログラムを、「今日はいい天気ですね」と入れたら「そうですね」と返すようなプログラムを、書いてみるといい。

要するに、ハローワールドくらいに戻れと、君は!

2007-10-30

[]55行で作るC#テンプレートエンジン

http://anond.hatelabo.jp/20071030034313二番煎じ

あまりのアホさに、作ってて気が狂いかけた

方針


using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Microsoft.CSharp;

delegate void ConvertTemplateDelegate(TextWriter tw, Dictionary<object, object> args);
static class TemplateGenerator {
    public static ConvertTemplateDelegate Generate(string code) {
        CompilerParameters param = new CompilerParameters();
        param.GenerateInMemory = true;
        param.ReferencedAssemblies.Add("System.Web.dll");
        CompilerResults rs = new CSharpCodeProvider().CompileAssemblyFromSource(param, ParseTemplate(code));
        if (0 < rs.Errors.Count) {
            StringWriter sw = new StringWriter();
            sw.WriteLine("Compile Error...");
            foreach (CompilerError err in rs.Errors)
                sw.WriteLine(err.ToString());
            throw new Exception(sw.ToString());
        }
        return (ConvertTemplateDelegate) Delegate.CreateDelegate(typeof(ConvertTemplateDelegate), rs.CompiledAssembly.GetType("Template", true).GetMethod("Convert"));
    }
    private static string ParseTemplate(string code) {
        using (StringWriter sw = new StringWriter()) {
            sw.WriteLine("using System; using System.Collections.Generic; using System.IO; using System.Web;");
            sw.WriteLine("public static class Template {");
            sw.WriteLine("public static void Convert(TextWriter tw, Dictionary<object, object> args) {");
            int index = 0;
            while (0 <= index &amp;&amp; index < code.Length) {
                int i = code.IndexOf("<%", index);
                sw.WriteLine("tw.Write(\"{0}\");", EscapeString(i < 0 ? code.Substring(index) : code.Substring(index, i - index)));
                if (0 <= i) {
                    i += 2;
                    int i2 = code.IndexOf("%>", i);
                    if (0 <= i2) {
                        string cc = code.Substring(i, i2 - i);
                        if (cc.StartsWith("="))
                            sw.WriteLine("tw.Write(HttpUtility.HtmlEncode(\"\"+({0})));", cc.Substring(1));
                        else
                            sw.WriteLine(cc);
                        i = i2 + 2;
                    }
                }
                index = i;
            }
            sw.WriteLine("}}");
            return sw.ToString();
        }
    }
    private static string EscapeString(string code) {
        return code.Replace("\\", "\\e").Replace("\"", "\\\"").Replace("\t", "\\t").Replace("\n", "\\n").Replace("\r", "\\r").Replace("\\e", "\\\\");
    }
}

サンプル C# コード。ためしにテンプレートから Xml 生成して、標準出力してみる。

class Program {
    static void Main(string[] args) {
        ConvertTemplateDelegate func = TemplateGenerator.Generate(TemplateEngine.Resource1.template);
        using (StringWriter sw = new StringWriter()) {
            Dictionary<object, object> arg = new Dictionary<object, object>();
            arg["title"] = "template sample";
            arg["data"] = new string[] { "foo", "fooo", "<strong>foooooooooo!</strong>" };
            func(sw, arg);
            Console.WriteLine(sw);
        }
    }
}

サンプルテンプレート

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title><%= args["title"] %></title>
  </head>
  <body>
    <h1><%= args["title"] %></h1>
    <table>
<% string[] data = (string[]) args["data"]; %>
<% for(int i = 0; i < data.Length; i++) { %>
      <tr bgcolor="<%= i % 2 == 0 ? "#FFCCCC" : "#CCCCFF" %>">
        <td><%= i %></td>
        <td><%= data[i] %></td>
      </tr>
<% } %>
    </table>
  </body>
</html>

出力例

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>template sample</title>
  </head>
  <body>
    <h1>template sample</h1>
    <table>


      <tr bgcolor="#FFCCCC">
        <td>0</td>
        <td>foo</td>
      </tr>

      <tr bgcolor="#CCCCFF">
        <td>1</td>
        <td>fooo</td>
      </tr>

      <tr bgcolor="#FFCCCC">
        <td>2</td>
        <td>&lt;strong&gt;foooooooooo!&lt;/strong&gt;</td>
      </tr>

    </table>
  </body>
</html>

CodeDom 使って動的コンパイル……って、このコードのままだとセキュリティ的に大問題な気がするな。

素直に ASP.NET 使ったほうが楽だと直感した。

あと EscapeString すっごく自信ない。たぶん修正が必要だと思うw

2007-09-01

9月になったし、もうそろそろ書いておくか

これから就職活動するバカはいないだろうけど、そういう人もいるだろうから少し書いておこう。

どちらかというと、アンチMS派なUnix技術者Windowsだけの世界で仕事をする辛さを。

Unix技術者は、業務実績にSolaris/AIX/Linuxって書いてあってもちゃんと質問しろ。Windows仕事は無いですよね?って。

僕が食べるために職を手にしているこのIT業界というのは、バッドノウハウMicroSoftExcelで出来ている。

その為、僕が手にしたUnixの知識は、特定の仕事以外でしか役に立たないし、使わない。

viだろうが、TeXだろうが、Xの知識よりも、MFCVBAのちょっとした知識のあるヤツが上にみられる。

ExcelWindowsの知識があればそれだけで仕事になるからだ。

いいか、viTeX、Xなんて捨てちまえ、Excelがあればそれでいいのだ。

Unix技術者でいうハッカーとはなんだろう。

MSでは、ActiveXを使ってCOMを操作し、クライアントレジストリを操作し、IE単体でできないことをやってしまうヤツがハッカーと思われている。

VBAマクロで作ったなんちゃってツールを3時間で作れるほうが、

perlruby/pythonで、より少ない時間で作ったツールよりも凄く思われてしまう。

そして、それができるヤツの方が、Unix技術者よりもよりハッカーであり、技術力があると思われている。

ブラウザを例にしたが、

javascriptでalert/confirmを出すよりも、vbscriptでMsgBoxの方が多くのことができるから、

javascriptNumberの計算よりも、vbscriptでDecimalを使った方が倍密度の計算ができるから、

vbscriptを駆使できるヤツは、凄く重宝される。

いいか、javascriptで汎用的に書くのなんてナンセンスだ。javascriptなんて捨てちまえ、覚えるのはJScript実装(WSH)だ。

この業界、何が不満になるかというと、

MSの、もっというとWindowsのことしか知らないヤツが多すぎるということ。

そういうヤツらは、Windowsだったらこんなこともできるのに、なぜUnix/Linuxだとこんなこともできないのか。と言う

そういうヤツらは、Windowsの未修正バグの合間を縫いながら中途半端な実装しかしない。

だって、中途半端(もしくは大雑把)な実装で動いているものの中で動くから。それ以上に実装しようとしてもできないのだ。

いいか、win32のメッセージングの仕組を覚えるんだ。無理矢理send_keyみたいなコードを書けるようにしろ。

コマンドを連結するよりも、結果に近いコードを書くんだ。線形になろうがヤツらは気にしないだろう。

ヤツらは、javapythonをバカにする。

何故か。

それは、.NETで作ればお客さんの要望が実現でき、Excelと連携できるからだ。

ヤツらは、C/Sの世界でこそ役に立つ技術者だが、Webの世界に連れてきてはならない。すぐに実装がIEだけになる。

ヤツらにLLを覚えさせるのは無理だ。

クロージャなんて知らないし、高階関数カリーなんてコードを教えてみろ。後から辛くなるのは自分だ。

ヤツらにはPHPを教えておけ、それだけで満足する。すごいヤツになった気にさせれる。

バッドノウハウ慣れしているヤツらはそれを使ってコードを書いてもらえ、rubyで書かせるよりも修正が20倍楽だ。

いいか、まとめるぞ。

今まで一生懸命Unix勉強してきたのは無駄だ。いますぐ忘れるんだ。

Excelを今から覚えろ。VBAを覚えろ。そしてMSの動きを身に着けるんだ。

Windowsでは単位がFormだ。それが標準出力標準入力と思え。ときどきSheetとかWorkbookになるぞ。

ストリームファイル操作には気をつけろ。Unixの気分でいると思わぬところで抜けが出るぞ。

IRCは使うな。Jabberを使うな。メッセンジャーを使え。移行のお薦めはGaimだ。Windows版がある。

viの使用頻度を減らせ、変なコマンドを身に着ける前に、秀丸マクロを書けるようにしろ、Notepadのショートカットを覚えとけ。

BindとかApache(Httpd)の知識はいらない。IISだ。ActiveDirectoryだ。

文字コードはCp943cを何がなんでも押せ。Shift_JISっていう大雑把な伝えかたはダメだ。絶対cp943cにしろ。UTF8/UTF7との格闘で身も心もぼろぼろになるぞ。

汎用性なんて無いんだ。Windowsというプラットフォームがあれば。



ああ、心が渇いていく。

2007-04-29

オブジェクト指向って言葉も大昔からあるよ!

http://anond.hatelabo.jp/20070429155517

えー、IME 任せは微妙だなあ。めんどくさくてもオンオフぐらいしようよ。状況に応じた大文字小文字の選択もしづらい(できない?)し微妙だよ。少なくともそういう入力方法を叩くプログラマーは少なくないと思う。

19世紀はgoto文の時代だと思ってましたよ。

というかあまりオブジェクト指向プログラムってみたことないかも。

goto文不要論なんてもう何十年も議論され続けてるよ。大体 90年代終盤にはそこそこ普及してた Java は既に goto が実装されてなかったでしょ。今でも実装されないままだし。

それから Amazon.co.jp で「オブジェクト指向」を検索して「出版年月日が新しい順番」にソートして一番ケツに飛ぶ80年代オブジェクト指向本なんて山程出てくる。

というかあまりオブジェクト指向プログラムってみたことないかも。

なんかこのご時世におすすめないかな?

学生さんかなんかかな。もしオブジェクト指向の利点がまだ理解できてないなら、この話の増田ツリーのどっかにあったと思うけど、

  1. 関数も使わずベタ書き
  2. ベタ書きに絶望関数で手続き指向プログラミング
  3. スパゲッティ絶望オブジェクト指向プログラミングカプセル化モジュール
  4. 同じインターフェイスなのに姿を変えてしまうモジュール絶望インターフェイス概念に目覚める

ぐらいの経緯を辿ればまあオブジェクト指向の基本は掴めると思う。当然ある程度の大きさのプログラム(あんまり行数で言いたくないけど、せめて 1000行以上)を書かないと、各プロセス絶望を知ることはできないと思うけど。必要は発明の母。あとは平行して適当Amazon.co.jp で評価のいい本を読めばいい。

インターフェイス概念については、一般に知られているものだと C のストリームで理解できると思う。

FILE *fp;
fp = fopen("log.txt", "w");
fprintf(fp, "Starting log...\n");
fclose(fp);

これは log.txt ってファイルログを吐いてるのね。でも fprintf() ってのは次のような使い方もできる。

fprintf(stdout, "Starting log...\n");

stdout ってのは標準出力で、そこに fprintf でデータを渡すと(Windows の場合)コマンドプロンプトに文字列を表示する。ファイル標準出力は全く違うものだけど、インターフェイスが同じだから全く同じように出力処理を書けてるでしょ。これを発展させれば、

FILE *stream;

if (log_kind == LOG_FILE) {
  stream == fopen("log.txt", "w");
} else if (log_kind == LOG_STDOUT) {
  stream == stdout;
}

fprintf(stream, "Starting log...\n"); /* この時点で stream の種類を知る必要が無い! */

if (log_kind == LOG_FILE) {
  fclose(stream);
}

と書くことができる。年賀状大学受験合格通知は違うものだけど、初期化(書き方)が違うだけでインターフェイスポストに投函)は同じ、みたいな。それよりよく考えたら C を知ってるとは限らんよな。めんどくさくなってきた。あとはしりません。

 
アーカイブ ヘルプ
ログイン ユーザー登録
ようこそ ゲスト さん