外部ファイルを使った比較

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
返信する
メッセージ
作成者
henry

外部ファイルを使った比較

#1 投稿記事 by henry »

今回、ActiveBasicを使って英単語のテストプログラムを作ってみたいと思い
自分のやろうとしていることができるか、ヘルプファイルをみてみたのですが
できそうなのかどうかわからないので質問させていただきます。

[やろうとしてること]
英単語だけが1行ずつ書いてあるテキストファイルを01.txtとする
01.txtに対応する日本語が1行ずつ書いてあるテキストファイルを02.txtとする
まず、01.txtファイルからランダムに1行単語を選び表示させ、その日本語をテキストボックスか何かに入力してもらう。
その日本語が合っているかどうか02.txtと比較し、
合っていればまたランダムに~~~の繰り返しです。

[相談内容]
ランダムに01.txtから1行抜いて同じ行で02.txtから抜けないと
訳が合わないと思うのですが、この部分ができるのかどうか。
そして、そこからの比較ができるか。
それ以前に外部ファイルを読み込むことができるのでしょうか?

先生方、よろしくお願いします。

ps.
違った方法で上記のようなことができるよ、みたいなアドバイスがあればそれも教えてください。
このようなプログラムはいろいろなやり方があると思うのですが、
自分は上記のが何かと便利いいかなと思いました。
ナナシ
記事: 11
登録日時: 2005年6月19日(日) 21:21
お住まい: 石川県
連絡する:

#2 投稿記事 by ナナシ »

[相談内容]
ランダムに01.txtから1行抜いて同じ行で02.txtから抜けないと
訳が合わないと思うのですが、この部分ができるのかどうか。
ファイルは先頭から連続で読み出す操作はしやすいですが、
ランダムな位置にあるものを読み込むのは苦手です。
出題のたびにファイルから問題を読み出そうとすると話が難しくなるので
ここはまず必要なデータをすべて配列に入れるのが良いでしょう。


読みやすさを損なわない程度に極力短くしたサンプルを載せます。

コード: 全て選択


#N88BASIC

' ↓ ここからプログラムが実行されます

Const NUM_QUESTION = 10	'問題数

Dim eng$(NUM_QUESTION) As String
Dim jpn$(NUM_QUESTION) As String
Dim ans$ As String
Dim no As Long
Dim i As Long

Open "01.txt" For Input As #1
i = 0
While Not(Eof(1))
	Input #1, eng$(i)
	i = i + 1
Wend
Close #1

Open "02.txt" For Input As #1
i = 0
While Not(Eof(1))
	Input #1, jpn$(i)
	i = i + 1
Wend
Close #1

Randomize

While 1
	no = Int(Rnd() * NUM_QUESTION)
	Print "問題 ";eng$(no);" を日本語に直すと?"
	Input "回答"; ans$
	Print "答えは ";jpn$(no);" です"
	If ans$=jpn$(no) Then Print "正解です" Else Print "残念、不正解"
	Print
Wend
eng$とjpn$には問題と答えが入ります。
それぞれ、配列に一問ずつ入れていきますので、
eng$(x) に対する答えは jpn$(x) になるということです。

問題はNUM_QUESTIONの数だけファイルから読み出すので、
サンプルの場合は10行分用意する必要があります。
11行以上あるとファイルの読み出しエラーになり、
9行以下だと足りない分が空白で出題されることがあります。
また、コンマやタブやスペースは問題と答えに使えません。

サンプルの状態でも一応動くことは動きます。
NUM_QUESTIONを100にして問題を100問分用意すれば
それなりのボリュームのあるテストができます。
ただし、サンプルだけあって多数の足りない点が存在します。

次のようなことに挑戦してみてはどうでしょうか?
・同じ問題が何度も出てきてしまわないようにする
・全部の問題を出題したら終了するようにする
・得点制にしたり、正解率を表示してゲーム的な要素を追加する
・学習状態を保存できるようにして、いつでも再開できるようにする
・レベルの選択ができて、それにあった問題が出るようにする
・問題ファイルの作り方に間違いがあるとき、それがわかるように表示する
・ひとつのファイルで問題と答えを設定できるようにしてみる
・N88BASICスタイルではなくウィンドウを使ったプログラムに改造する
henry

#3 投稿記事 by henry »

ナナシさん、レス&サンプルありがとうございます。

> ファイルは先頭から連続で読み出す操作はしやすいですが、
> ランダムな位置にあるものを読み込むのは苦手です。
> 出題のたびにファイルから問題を読み出そうとすると話が難しくなるので
> ここはまず必要なデータをすべて配列に入れるのが良いでしょう。
配列ですか。思いもつきませんでした。
入れた後の動作も勉強になりました。

> 次のようなことに挑戦してみてはどうでしょうか?
> ・同じ問題が何度も出てきてしまわないようにする
> ・全部の問題を出題したら終了するようにする
> ・得点制にしたり、正解率を表示してゲーム的な要素を追加する
> ・学習状態を保存できるようにして、いつでも再開できるようにする
> ・レベルの選択ができて、それにあった問題が出るようにする
> ・問題ファイルの作り方に間違いがあるとき、それがわかるように表示する
> ・ひとつのファイルで問題と答えを設定できるようにしてみる
> ・N88BASICスタイルではなくウィンドウを使ったプログラムに改造する
上記の機能ですが、
・同じ問題が何度も出てきてしまわないようにする
・全部の問題を出題したら終了するようにする
この2つに付け加え
・間違った単語を別ファイルに記録する
というのを付けてみようと思います。
しかし、実際どのように動かすのがいいのか
プログラムを組んだ経験が極めて少ない私には
なかなか動きを頭で追うことができないので相当な時間がかかりそうです。

今までperlでCGIを改造するぐらいしかやったことがなく
ActiveBasicも初めて二週間ぐらい・・・。
上のような機能を付けるにはやはり本格的に書籍を購入して勉強しないと難しいですかね?

ところでこのプログラムの用途なんですが、受験生である私が単語帳の暗記確認に使いたいためです。
なので、高機能じゃなくて全然問題ないんですよ(笑)
淡幻星
記事: 183
登録日時: 2005年7月19日(火) 07:02
お住まい: 宮城県
連絡する:

横スレかもしれませんが・・・

#4 投稿記事 by 淡幻星 »

失礼します。

> 上のような機能を付けるにはやはり本格的に書籍を購入して勉強しないと難しいですかね?
そんなことはありません。
ナナシさんのサンプルの流れを追っているうちに、すぐできると思います。

> ・同じ問題が何度も出てきてしまわないようにする
> ・全部の問題を出題したら終了するようにする
配列に読み込んだ内容を、ランダムに出力して、
ただし重複出力はせず、全て出力を終えたら終了、
のサンプルはこんな感じです。

コード: 全て選択

#N88BASIC

Const NUM_QUESTION = 10
Dim strBuf( NUM_QUESTION ) As String
Dim nAnswered( NUM_QUESTION ) As Long
Dim nNum As Long
Dim nFinishedNum As Long
Dim i As Long

strBuf(0) = "a"
strBuf(1) = "b"
strBuf(2) = "c"
strBuf(3) = "d"
strBuf(4) = "e"
strBuf(5) = "f"
strBuf(6) = "g"
strBuf(7) = "h"
strBuf(8) = "i"
strBuf(9) = "j"

i = 0
While( i < NUM_QUESTION )
	nAnswered( i ) = FALSE
	i = i + 1
Wend

nFinishedNum = 0
While( nFinishedNum < NUM_QUESTION )
	nNum = Int( Rnd() * NUM_QUESTION )
	If( nAnswered( nNum )=FALSE )Then
		Print Str$(nFinishedNum+1);"問目:";strBuf( nNum )
		nAnswered( nNum ) = TRUE
		nFinishedNum = nFinishedNum + 1
	EndIf
Wend

Print "すべての出力を終えました。"
nAnsweredで、strBufの内容が、既に出力済みか(TRUE)、そうでないか(FALSE)、
を記憶して判別しています。

公開されているCGIのPerlを読んで改造できるレベルでしたら、
AB(に限らずどんな言語も)も少しやればすぐに慣れると思いますよ。



≫ナナシさん
ふと。こういう横スレって失礼にあたるものでしょうか?
もしそうでしたら、以後は気をつけます。
それから、この場で言うのもなんですが、ナナシさんのサイトのAB講座は
大変参考になりました。とくにVer2.xでの窓のメッセージループの解説は助かりました。
あれでN88BASICからWindowsプログラミングに移れたようなものです。
ありがとうございました。
久しぶりにナナシさんに見かけましたので、コメントしてみました。
henry

#5 投稿記事 by henry »

コード: 全て選択


#N88BASIC

Const NUM_QUESTION = 4
Dim eng$(NUM_QUESTION) As String
Dim jpn$(NUM_QUESTION) As String
Dim nAnswered( NUM_QUESTION ) As Long
Dim ans$ As String
Dim no As Long
Dim nFinishedNum As Long
Dim i As Long

Open "01.txt" For Input As #1
i = 0
While Not(Eof(1))
    Input #1, eng$(i)
    i = i + 1
Wend
Close #1

Open "02.txt" For Input As #1
i = 0
While Not(Eof(1))
    Input #1, jpn$(i)
    i = i + 1
Wend
Close #1

Randomize

i = 0
While( i < NUM_QUESTION )
    nAnswered( i ) = FALSE
    i = i + 1
Wend

nFinishedNum = 0
While( nFinishedNum < NUM_QUESTION )
    no = Int( Rnd() * NUM_QUESTION )
    If( nAnswered( no )=FALSE )Then
        Print "問題 ";eng$(no);" を日本語に直すと?"
    	Input "回答"; ans$
    	Print "答えは ";jpn$(no);" です"
		If ans$=jpn$(no) Then Print "正解です" Else Print "残念、不正解"
		Print
        nAnswered( no ) = TRUE
        nFinishedNum = nFinishedNum + 1
    EndIf
Wend

Print "すべての問題を終えました。"
こんな感じにお二人のサンプルを合体してみましたが・・・・。


>・間違った単語を別ファイルに記録する
これに関してあれこれ探してみたんですが、
Else Print "残念、不正解"の部分を
Writeを使ってやれば別ファイルに記録できそうかな?とやってみたんですが無理でした・・・。
淡幻星
記事: 183
登録日時: 2005年7月19日(火) 07:02
お住まい: 宮城県
連絡する:

Re:

#6 投稿記事 by 淡幻星 »

> Writeを使ってやれば別ファイルに記録できそうかな?とやってみたんですが無理でした・・・。

コード: 全て選択


nFinishedNum = 0 
Open "03Misstake.txt" For Output As #1
While( nFinishedNum < NUM_QUESTION ) 
    no = Int( Rnd() * NUM_QUESTION ) 
    If( nAnswered( no )=FALSE )Then 
        Print "問題 ";eng$(no);" を日本語に直すと?" 
        Input "回答"; ans$ 
        Print "答えは ";jpn$(no);" です" 
        If( ans$=jpn$(no) )Then
            Print "正解です"
        Else
            Print "残念、不正解" 
            Print #1, eng$(no);"-->";jpn$(no)
        EndIf
        Print 
        nAnswered( no ) = TRUE 
        nFinishedNum = nFinishedNum + 1 
    EndIf 
Wend 
Close #1
で、別ファイル[ 03Misstake.txt ]に書き出せませんか?
今はAB環境がないのでテストしてませんが・・・。
あー、もしかすると

コード: 全て選択

Print #1, eng$(no);"-->";jpn$(no)

コード: 全て選択

Print #1, eng$(no) + "-->" + jpn$(no)
とする必要があるかもしれません。

追加書き出しとか上書きとかはHELPのOPEN文見てください。
henry

Re:

#7 投稿記事 by henry »

淡幻星さん、ありがとうございます。

コード: 全て選択


nFinishedNum = 0 
Open "03.txt" For Output As #1
While( nFinishedNum < NUM_QUESTION ) 
    no = Int( Rnd() * NUM_QUESTION ) 
    If( nAnswered( no )=FALSE )Then 
        Print "問題 ";eng$(no);" を日本語に直すと?" 
        Input "回答"; ans$ 
        Print "答えは ";jpn$(no);" です" 
        If( ans$=jpn$(no) )Then
            Print "正解です"
        Else
            Print "残念、不正解" 
            Print #1, eng$(no);"-->";jpn$(no)
        EndIf
        Print 
        nAnswered( no ) = TRUE 
        nFinishedNum = nFinishedNum + 1 
    EndIf 
Wend 
Close #1
で動作しました<(_ _)>

ところで、03.txtを
例えば2005.08.21.14:50.txtなどのように取得した年、月日、時間でファイル名を付ける場合
$yyyy.$mm.$dd.$HH.$mm.txt
で行けると思うのですが、このときGetDateFormatとGetTimeFormatを使用すればいいんですかね?

perlだと・・・

コード: 全て選択


#------------------------------------------------------------------  時刻取得▼
$ENV{'TZ'} = "JST-9";
my($sec, $min, $hour, $day, $mon, $year, $wday) = localtime(time);
$year += 1900;
$mon += 1;
if($mon < 10){ $mon = "0$mon"; }
if($day < 10){ $day = "0$day"; }
#------------------------------------------------------------------------------
#------------------------------------------------------ 記録ファイル名設定▼
$log_file = "[$year\.$mon\.$day\] "."txt";

#------------------------------------------------------------------------------
(上記だと2005.08.21.txtというような感じ)
というように自分で簡単に書けるのですが・・・(汗
淡幻星
記事: 183
登録日時: 2005年7月19日(火) 07:02
お住まい: 宮城県
連絡する:

Re:

#8 投稿記事 by 淡幻星 »

> ところで、03.txtを
> 例えば2005.08.21.14:50.txtなどのように取得した年、月日、時間でファイル名を付ける場合
> $yyyy.$mm.$dd.$HH.$mm.txt
> で行けると思うのですが、このときGetDateFormatとGetTimeFormatを使用すればいいんですかね?
その2つでできます。相変わらずAB環境がない場所に居る&などによりサンプルは割あい。
ちなみに、

コード: 全て選択

Dim strFileName As String

strFileName = Date$ + "." + Time$ + ".txt"
Open strFileName For Output As #1
'以下略

などとして簡単に、日時をファイル名することも出来ます。
henry

Re:

#9 投稿記事 by henry »

どうもです。
ヘルプファイルを参考にコード書いてみたんですけど・・・。
全然だめです。

コード: 全て選択


GetTimeFormat(LOCALE_USER_DEFAULT, 0, 0, HHmm, buffer, 255)
GetDateFormat(LOCALE_USER_DEFAULT, 0, 0, yyyyMMdd, buffer, 255)
ヘルプも書き方の一例でも書いてくれればいいのに。
淡幻星
記事: 183
登録日時: 2005年7月19日(火) 07:02
お住まい: 宮城県
連絡する:

間違ってました。

#10 投稿記事 by 淡幻星 »

すいません。
さっきのコード間違ってました。関数名が違ってました。
ついでに、ファイル名に「/:」は使えないので、弾かれちゃいます。

コード: 全て選択

Dim strFileName As String
Dim strDate As String
Dim strTime As String

strTime = Time$()
strDate = Date$()
strFileName = Left$( strDate, 4 ) + "." + Mid$( strDate, 6, 2 ) + "." + Right$( strDate, 2 ) + "."
strFileName = strFileName + Left$( strTime, 2 ) + "." + Mid$( strTime, 4, 2 ) + "." + Right$( strTime, 2 ) + ".txt"
Open strFileName For Output As #1
	Print #1, strFileName
Close #1
End
たぶん、これでファイル作れると思います。

APIの方も一例だけ。

コード: 全て選択

Dim strDateTime As String
Dim retAns As Long

strDateTime = String$( 255, Chr$(0) )
retAns = GetTimeFormat( LOCALE_USER_DEFAULT, NULL, ByVal NULL, "HHmm", StrPtr(strDateTime), 255 )
たぶんこれで行けるかと。
出来なかったらごめんなさい。試してないので。
ちょっと時間が迫ってるので。では。
ゲスト

Re: 間違ってました。

#11 投稿記事 by ゲスト »

> strDateTime = String$(255, Chr$(0))
ZeroString(255)でいいんじゃありませんか?
henry

ありがとうございました。

#12 投稿記事 by henry »

淡幻星さん、お忙しい中ありがとうございました。
無事満足する物ができました<(_ _)>

コード: 全て選択


strTime = Time$()
strDate = Date$()
strFileName = Left$( strDate, 4 ) + "/" + Mid$( strDate, 6, 2 ) + "/" + Right$( strDate, 2 ) + "_"
strFileName = strFileName + Left$( strTime, 2 ) + ":" + Mid$( strTime, 4, 2 ) + ":" + Right$( strTime, 2 ) + ";;ミス単語.txt"
[: /]を全角の[:/]で対応させました。

ナナシさん、淡幻星さん、本当にありがとうございました。
ナナシ
記事: 11
登録日時: 2005年6月19日(日) 21:21
お住まい: 石川県
連絡する:

#13 投稿記事 by ナナシ »

淡幻星さん
> ふと。こういう横スレって失礼にあたるものでしょうか?
> もしそうでしたら、以後は気をつけます。

そのように受け止める人はいるかもしれません。
私は、多くの人がレスをつけているほうが掲示板らしくていいと思いますね。
(荒らしなんかは論外ですが)

> それから、この場で言うのもなんですが、ナナシさんのサイトのAB講座は
> 大変参考になりました。とくにVer2.xでの窓のメッセージループの解説は助か
> りました。

そういっていただけると嬉しいです。
淡幻星
記事: 183
登録日時: 2005年7月19日(火) 07:02
お住まい: 宮城県
連絡する:

Re: 間違ってました。

#14 投稿記事 by 淡幻星 »

≫ゲストさん
> > strDateTime = String$(255, Chr$(0))
> ZeroString(255)でいいんじゃありませんか?
そちらの方が書き方はスマートですね。
でも、これは好みの問題かと思います。


≫ナナシさん
レスありがとうございますw
Sinryow
記事: 141
登録日時: 2005年5月31日(火) 09:34
お住まい: 北海道
連絡する:

Re: 間違ってました。

#15 投稿記事 by Sinryow »

淡幻星 さんが書きました:> > strDateTime = String$(255, Chr$(0))
> ZeroString(255)でいいんじゃありませんか?
そちらの方が書き方はスマートですね。
でも、これは好みの問題かと思います。
細かいことを言えば,恐らくZeroStringの方が処理速度が速いです。
※String$は文字列の連結処理が回数分行われるため

頻繁に呼び出す処理なのであれば,ZeroStringに変更した方がよいでしょうね。
' ============================================================
' Sinryow Game Home Page - http://www.sinryow.net/
' Sinryow ActiveBasic Center - http://ab.sinryow.net/
' ============================================================
返信する