プログラミング

プログラムの勉強でHelloWorldの次には何をつくったら良いか?【Go言語版】

 

新しいプログラミング言語の勉強をはじめたのだけど、Hello,World!の次って何をつくればいいか悩む
そんな時には、とっておきのプログラムがあるぞ

ということで、Go言語をインストールしたときに半分くらい作成しましたが、新しいプログラミング言語を学習のときには、僕は結構2番目につくる、「タッチタイピング」プログラムを紹介します。

 

Hello World!プログラムの次に作るプログラムはどんなものがいいのか?

HelloWorldの次のプログラム

2番目につくるプログラムでおすすめは?

おすすめは、「タッチタイピング」のプログラムです。

「文字列を表示、それと同じ文字列を入力して、正解率とかかった時間を表示する」というものです。

ファイルから文字列を読み込み、ランダムに表示したものに対して、入力にかかった時間と、文字列を比較して正解率を算出するというプログラムで、実行結果の例は下記のようになります。

	*** タイピング練習プログラム(Go言語版) ***

	表示された文字を入力してください.
	   qwert yuiop
	 > qwert yuio
	正解率:90 パーセント  時間:   5.71 秒

	表示された文字を入力してください.
	   1234567890
	 > 12345
	正解率:50 パーセント  時間:   5.30 秒

	表示された文字を入力してください.
	   asdf jkl;
	 > asdf jkl;
	正解率:100 パーセント  時間:   3.97 秒

	表示された文字を入力してください.
	   1234567890
	 >
	おつかれさまでした!


表示されている文字列は、最初にテキストファイルを用意しておいたものになります。

実はこのプログラム、いろいろな要素がつまったプログラムで、最初につくっておくと次のステップに進むのが楽になります。

他の言語を知っているのであれば、インストールしたその日に調べながら作成できるレベルだし、逆に、完全な初心者の場合は、簡単な本を勉強がてら時間をかけてつくってみてもいいと思います。

 

タッチタイピングプログラムが2番目のプログラムに適切な理由

なぜこのプログラムがいいか、それは、短い中に必要な要素が過不足なくつまっているからです。

タッチタイピングのプログラムを作ることで、次のような内容を学ぶことができます。

  • 文字列表示
  • 画面からの入力
  • 条件分岐
  • 繰り返し(ループ)
  • 文字列操作
  • 関数呼び出し
  • 計算処理
  • リスト・配列操作
  • ファイル読み込み
  • エラー処理
  • 時刻、時間処理
  • 乱数処理

言語処理系の違いもあるし、それぞれの人の書き方や、どこまでを作るかにもよりますが、数十ステップから、かなり長く書いたところで100ステップいかない程度で、これだけのことが学べるプログラムは、なかなかないです。

プログラミングがはじめての場合は、1項目ずつ数行の練習プログラムで勉強を重ねながら、作るものに悩んだときにトライしてみるといいかもしれません。

特殊な言語(画面表示だけのHTMLのような言語)以外の先ほど示した内容を網羅する、汎用的なプログラミング言語であれば、作ることができます。

もちろん、PHPやJavascript、.NET系のVBやC#であれば、コンソールではなくてブラウザ上で動かす等、一部仕様を変更したほうがよい部分はでてきますので、PHPでやってみる場合などは工夫してみてください。

ちなみに、僕がタッチタイピングのプログラムを最初につくったプログラミング言語は、FORTRANでした。

数値計算を極めたその言語には、タッチタイピングは向いてないとは思いますが、普通に作れました(笑)

もっとも、さしがにFORTRANで数値計算しかしないのであれば、別の練習プログラムの方がよい気はします。

 

タイピングプログラムは次の拡張も可能です

このままでも使えますが、さらに拡張すれば、より本格的なタイピング練習プログラムになります。

例えば、テキスト画面を、クライアントアプリや、Webアプリにする。

キー入力をリアルタイムにして、正解率や秒数をリアル表示にする。

目標タイムやレベルを設けてステージクリアできるようにする、などなど。

まあ、自分は正直ここまでやったことはありません。

 

Go言語での実例

Go言語をはじめて数時間で作成したものなので、言語特有のこう書いた方が良いという部分ができていない気はしますが、どのような機能のものを2作目に作っているのかのご参考までにソースコードを掲載します。

ただ勉強のためであれば、正解があるわけでもないので、実際にプログラムをどうつくるかを自分なりに考えてコーディングすることをお勧めします。

	package main

	import (
		"bufio"
		"fmt"
		"math"
		"math/rand"
		"os"
		"time"
	)

先頭には、自分のパッケージ名と利用するパッケージのインポート文が入ります。

入出力、計算、エラー制御、時間管理と一通りインポートです。

次は、メインの処理です。

func main() {
	fmt.Println("*** タイピング練習プログラム(Go言語版) ***")
	// タイピング用テキストの読込
	textLines, err := readTextlines("typetext.txt")
	if err != nil {
		os.Exit(1)
	}

	rand.Seed(time.Now().UnixNano())
	scn := bufio.NewScanner(os.Stdin)
	for {
		fmt.Println("\n表示された文字を入力してください.")
		id := rand.Intn(len(textLines))
		prtstr := textLines[id]
		if len(prtstr) == 0 {
			continue
		}
		fmt.Println("   " + prtstr)
		fmt.Print(" > ")
		inpstr := ""
		ts := time.Now()
		if scn.Scan() {
			inpstr = scn.Text()
		}
		te := time.Now()
		// 入力がなかった場合は終了
		if len(inpstr) == 0 {
			fmt.Println("おつかれさまでした!")
			break
		}
		tsub := float64(te.Sub(ts)) / float64(math.Pow(10, 9))
		fmt.Printf("正解率:%d パーセント  時間: %6.2f 秒\n", 
				CalcHitRate(prtstr, inpstr), tsub)
	}
}

 

メイン処理部分は、次のような流れです。

  1. 表示するためのテキスト情報をファイルから読み込む
  2. 以下を繰り返し処理
  3. 表示対象を読み込んだテキストからランダムに表示
  4. 入力開始時刻を取得
  5. テキストを入力してもらう(リターンキーを押すまで)
  6. 入力終了時刻を取得
  7. 表示文字と入力された文字列の一致の割合を計算
  8. 一致割合と、入力前後の時間差を表示
  9. 入力がなかった場合はメッセージを出して終了

ファイルからリスト(今回のGoの場合は、スライス)に行単位にテキストを読み込みました。

最近のプログラミング言語では、一行で読み込む部品が用意されているものも多いですが、見つけられなかったためネットの情報も参考にして自作しました。

 

	// ファイルから配列にテキストを読込み
	func readTextlines(filename string) ([]string, error) {
		fp, err := os.Open(filename)
		if err != nil {
			fmt.Fprintf(os.Stderr,
				 "ファイル(%s)が見つかりません(%v)\n", filename, err)
			return nil, err
		}
		defer fp.Close()

		var lines []string
		scanner := bufio.NewScanner(fp)
		for scanner.Scan() {
			lines = append(lines, scanner.Text())
		}
		serr := scanner.Err()
		if serr != nil {
		 fmt.Fprintf(os.Stderr, 
		 "ファイル(%s)の読込に失敗しました(%v)\n", filename, serr)
		}

		return lines, serr
	}

 

エラー処理は、トライ-キャッチで拾うパターンではなく、関数のリターン値で返す形式を想定している言語処理系のようなので、結果の値とエラーを返すようにしました。
スライスをリターンにすべきかは議論の余地はあるかもですが、今回程度の情報であれば問題はなさそうということでこの形の実装です。

 

後は、表示文字列と入力文字列の一致度を計算する関数です。

// 表示文字列と入力文字列の一致度合いを返す
func CalcHitRate(prtstr string, inpstr string) int {
	linp := len(inpstr)
	ihit := 0
	for i, _ := range prtstr {
		if i >= linp {
			break
		}
		if prtstr[i] == inpstr[i] {
			ihit = ihit + 1
		}
	}
	return int((ihit * 100) / len(prtstr))
}

 

この関数は、単純に頭から一文字ずつ比較して一致していたら一致数をカウントアップ。最後に、表示文字の数でわって100をかければ、一致割合がでるという計算をしているだけです。

こういう場合、ゼロ割が発生しないようにチェックをいれるのが基本ですが、今回はメイン側で空行文字列は渡さないように制御しているので、この関数内でのチェックは割愛しました。

 

 

以上、今回は、実際にGo言語でHello、Wolrdの次につくってみた内容をお伝えしました。

タイピングのプログラムはさまざまな言語仕様を学ぶのに適切な例題になると考えています。

機会があれば、ぜひ試してみてください

 

最後までお読みいただき、ありがとうございました。

-プログラミング

Copyright© SIMPLEONESOFT (BLOG) , 2024 All Rights Reserved.