HIRO's.NET Blog

PowerShellが好き

目次

Blog 利用状況

ニュース

あわせて読みたい

書庫

日記カテゴリ

リンク

PowerShell でタイピング練習(PowerShell Tips)

ちょっと前に、PowerShellで作ったタイピング練習用ソフトを紹介します。

 

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

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

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

 

#===============================================================================
# Typing: CNNの記事(RSS)を利用してタイピング練習する
#
# パラメータ
#        なし
# 使用例
#   PS > Typing
#
# copyright HIRO's.NET(http://hiro.wankuma.com/)
#===============================================================================
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" と書けば鳴らすことができます。

 

ほんとは、もう少しコードをきれいにしてから載せるつもりでしたが...

温めすぎても腐りそうなのでアップします。



 

投稿日時 : 2008年2月17日 22:31

コメントを追加

# re: PowerShell でタイピング練習(PowerShell Tips) 2008/02/19 12:29 S.K.

2.0のCTP版ならPSJobで処理を分けることできるんじゃないかなー、とか。
バックグラウンド処理らしいので可能かどうか分かりませんが・・・。
自分の環境(XPSP2)じゃ何故か管理者権限でStart-PSjobしてもすぐFailedになっちゃうんですよね。。。

# re: PowerShell でタイピング練習(PowerShell Tips) 2008/02/19 12:39 HIRO

S.K.さんコメントありがとうございます。
正直2.0はまだ、あまり触ってないんです。

有用な情報ありがとうございます。

# YaJznLMCUbFB 2015/04/20 1:37 sally

1e4zJ8 http://www.FyLitCl7Pf7kjQdDUOLQOuaxTXbj5iNG.com

タイトル  
名前  
URL
コメント