HIRO's.NET

VB.NET, C#, PowerShell Tipsサイト

 VB.NET, C#, PowerShellを使用しているエンジニアのためのサイト。

 基本的な使用方法から開発で役立つTipsまで幅広く取り扱っています。

HIRO's.NET RSSHIRO's.NET RSS


PowerShellの開発でお困りのことはありませんか?
そんな悩みは当サイトで解決!!

HOME > PowerShell Tips > 自作関数 Tips メニュー

10.タイピング練習

 
UPDATE:2008/05/02    
 



PowerShellで作ったタイピング練習ソフトです。

このタイピングソフトは、CNNの記事をダウンロードしてきて、その記事から1単語ずつ画面に表示し、ユーザーにその通り入力してもらうというものです。

タイピング速度の速い人は、CNNの最新記事(英語)をちょろっと読めてしまう、一石二鳥のソフトとなっています。

制限時間は60秒1本勝負で(実際には正確に60秒にすることはできませんでした。後述します)、記事カテゴリを選択できるようにしてあります。

Typing.ps1

#===============================================================================
# Typing: CNNの記事(RSS)を利用してタイピング練習する
#
# パラメータ
# なし
# 使用例
# PS > Typing
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#===============================================================================
function global:Typing
{
#===============================================
# 初期化処理
#===============================================
#背景色を保存
$bgclr = $host.UI.RawUI.BackgroundColor

#前景色を保存
$fgclr = $host.UI.RawUI.ForegroundColor

#問題の色を定義
$questioncolor = [System.ConsoleColor]::Red

$rss_list = @(
@("Top Stories","http://rss.cnn.com/rss/cnn_topstories.rss"),
@("World", "http://rss.cnn.com/rss/edition_world.rss"),
@("Africa","http://rss.cnn.com/rss/edition_africa.rss"),
@("Americas","http://rss.cnn.com/rss/edition_americas.rss"),
@("Asia","http://rss.cnn.com/rss/edition_asia.rss"),
@("Europe","http://rss.cnn.com/rss/edition_europe.rss"),
@("Middle East","http://rss.cnn.com/rss/edition_meast.rss"),
@("U.S.","http://rss.cnn.com/rss/edition_us.rss"),
@("World Business","http://rss.cnn.com/rss/edition_business.rss"),
@("Technology","http://rss.cnn.com/rss/edition_technology.rss"),
@("Science & Space","http://rss.cnn.com/rss/edition_space.rss"),
@("Entertainment","http://rss.cnn.com/rss/edition_entertainment.rss"),
@("World Sport","http://rss.cnn.com/rss/edition_sport.rss"),
@("Football","http://rss.cnn.com/rss/edition_football.rss"),
@("Travel","http://rss.cnn.com/rss/edition_travel.rss"),
@("Video","http://rss.cnn.com/rss/cnn_freevideo.rss"),
@("Most Recent","http://rss.cnn.com/rss/cnn_latest.rss"),
@("Art of Life Blog","http://rss.cnn.com/rss/edition_artoflife.rss"),
@("Business Traveller Blog","http://rss.cnn.com/rss/edition_richardquest.rss"),
@("In the Field Blog","http://rss.cnn.com/rss/edition_inthefield.rss"),
@("World's Untold Stories Blog","http://rss.cnn.com/rss/edition_untoldstories.rss"),
@("The Screening Room Blog","http://rss.cnn.com/rss/edition_screeningroom.rss"),
@("Marketplace Middle East Blog","http://rss.cnn.com/rss/edition_mme.rss"),
@("Inside the Middle East Blog","http://rss.cnn.com/rss/edition_ime.rss")
)

Write-Host "タイピング練習の問題カテゴリーを選択してください"
for ( $icnt = 0; $icnt -lt $rss_list.Length; $icnt++)
{
Write-Host $($($icnt + 1).ToString("0#") + ": " + $rss_list[$icnt][0])
}

#ユーザーが選択したカテゴリ番号を保存
$no = Read-Host

if ( $([int]$no) -le 0 -and $([int]$no) -gt $rss_list.Length )
{
Write-Host "Noを正しく入力してね"
return
}
Write-Host "データダウンロード中..."
$feed = [xml](new-object system.net.webclient).downloadstring($rss_list[$no - 1][1])
$contents =$($feed.rss.channel.item | Select-Object -property DESCRIPTION)
Write-Host "データダウンロード完了"

foreach ( $content in $contents )
{
$a += $content.Description.split(" ")
}

Write-Host "[Enter]キーを押すと始まります"
Read-Host

$start = Get-Date
$i = 0
$score = 0
$miss = 0

#背景色を黒にする
$host.UI.RawUI.BackgroundColor = [System.ConsoleColor]::Black
cls

while ( $(Get-Date).subtract($start).TotalSeconds -lt 60)
{
#問題を出す
if ( $a[$i] -ne " ")
{
Write-Host $a[$i] -foregroundcolor $questioncolor

#ユーザーからの回答入力を取得する
$Host.UI.RawUI.ForegroundColor = $fgclr
$input = Read-Host

cls

#正解したらスコアをカウントアップ
if ( $input -ceq $a[$i] )
{
$score += 10
}
else
{
$miss++;
Write-Host "`a"
cls
}
}
$i++

#問題がなくなったら終了
if ($a.Length -eq $i )
{
break;
}
}

Write-Host $("start: " + $start)
Write-Host $("end: " + $(Get-Date))
Write-Host $("Score: " + $Score)
Write-Host $("Miss:" + $miss)
}

ポイント

1.背景色と前景色


PowerShellのコンソールウィンドウの背景色や前景色は $host.UI.RawUI のBackgroundColor と ForegroundColor を指定することで変更できます。

色はSystem.ConsoleColor列挙体を指定します。

2.問題の色

出題する問題(単語)の色は Write-Hostコマンドレットの-foregroundcolor パラメータで指定しています。

3.カテゴリを選択させる

 カテゴリはあらかじめ変数として持っておくこととしました。($rss_list) このとき変数は2次元配列変数にし、カテゴリ名とRSSのURLをペアで持たせています。

$rss_list[0][1]とするとURL http://rss.cnn.com/rss/cnn_topstories.rss が取り出せるという寸法です。

で、ユーザーにカテゴリを入力させるわけですが、Read-Hostコマンドレットを使用することで入力を取得することができます。

4.rssのダウンロード

rssのダウンロードはsystem.net.webclientのdownloadstringメソッドを使用しています。

[xml](new-object system.net.webclient).downloadstring($rss_list[$no - 1][1]) の部分です。

先頭に[xml]と付けることでxmlにキャストしています。

5.descriptionタグ内容の取り出し

$contents =$($feed.rss.channel.item | Select-Object -property DESCRIPTION)

 で行っています。 Select-Object でDescriptionを取り出します。

6.制限時間

whileでループして60秒経過したら終わるようにしています。

while ( $(Get-Date).subtract($start).TotalSeconds -lt 60)

{

}

ただし、このタイピングソフトは正確には60秒を計測することはできません。

 なぜなら、Whileの中でRead-Hostコマンドレットを使用しているからです。

Read-Hostコマンドレットはユーザーが[Enter]を押すまで処理を止めてしまいます。よって60秒経過してもユーザーが何も入力しなければ、このループは1時間経過しようが止まらないのです。 だれか良い方法知っていたら教えてください。 Read-Keyみたいなコマンドレット作れば良いのかしら?

7.入力ミスをしたらBeepを鳴らす

Beep音はWrite-Host "`a" と書けば鳴らすことができます。