Using text of txt file

HI Friends

I am developing an exam application using corona, It has more than 900 question. Now i have text document of the that in which all the information is written. Can any one help me how shall i use those information directly?

Hoping for reply asap.

Regards
Varun [import]uid: 130269 topic_id: 33696 reply_id: 333696[/import]

Hello Varun,
Are the test questions written in any predictable structure? You’ll probably need to use file I/O and detailed string matching functions to “pick” all of the information from a particular question, then place that into some kind of table-subtables arrangement. If you’ve done string matching before, you’ll know it’s complicated and prone to user error. But, I think you don’t have a better choice.

Brent [import]uid: 200026 topic_id: 33696 reply_id: 133990[/import]

HI Brent

Thanks for the reply, the in text file all the different objects are separated by double inverted comma("")
I dont know how to use I/O file, if you can share an similar example that will be great. SImilar type of coding can be done in core ios sdk or android sdk, but i dont know how to use it here.

Hoping for your reply.

Regards
Varun [import]uid: 130269 topic_id: 33696 reply_id: 133991[/import]

Hi Haroon

Thanks for your detail reply, I tried the code you send me, but it is showing error :

“attempt to call global ‘explode’ (a nil value)”

Do you have any idea regarding this error?

Regards
Varun [import]uid: 130269 topic_id: 33696 reply_id: 134006[/import]

oh , that should also include at the start!
function explode(div,str)
if (div==’’) then
return false
end
local pos=0
local arr = {}
– for each divider found
for st,sp in function() return string.find(str,div,pos,true) end do
table.insert(arr,string.sub(str,pos,st-1)) – Attach chars left of current divider
pos = sp + 1 – Jump past current divider
end
table.insert(arr,string.sub(str,pos)) – Attach chars right of last divider
return arr
end

and one thing more, at the end of line given below, put “, “, so it should be like
file:write( “MY NAME IS HAROON " …”, “…” AND I LOVE”…”, “…“CORONA”…”, ")

for any other error, feel free to post

Regards,
Haroon Yaseen [import]uid: 108129 topic_id: 33696 reply_id: 134012[/import]

HI VARUN,
I think, it will help u.
-------------------- TO WRITE ANY FILE IN TEXT FORMAT ------------------------------------------
local path = system.pathForFile( “nick_name.txt”, system.DocumentsDirectory )
local file = io.open( path, “w+b” )
– save current state variables in comma separated list
file:write( “MY NAME IS HAROON " …”, “…” AND I LOVE"…", "…"CORONA, ")
– at the end, the comma and space is much more important. it is used to differentiate in different objects written in text file.
– for line in file:lines() do print(“line”) end
io.close( file )
----------------------TO READ ANY FILE ----------------------------------------------------------------
function explode(div,str)
if (div==’’) then
return false
end
local pos=0
local arr = {}
– for each divider found
for st,sp in function() return string.find(str,div,pos,true) end do
table.insert(arr,string.sub(str,pos,st-1)) – Attach chars left of current divider
pos = sp + 1 – Jump past current divider
end
table.insert(arr,string.sub(str,pos)) – Attach chars right of last divider
return arr
end
function nick_name( )

local path = system.pathForFile( “nick_name.txt”, system.DocumentsDirectory )
local file = io.open( path, “r” )

if file then
print(“loading nick_name”)
local contents = file:read( “*a” )
print("the contents of file is “…contents)
local prevState1 = explode(”, ", contents)
io.close( file )
return prevState1
end
end

local nick_name_data = {}
nick_name_data = nick_name( )
– the actual data in text file can be retrieve like this, nick_name_data[1] = MY NAME IS HAROON and nick_name_data[2] = AND I LOVE and in third nick_name_data[3] = CORONA

Kind Regards,
Haroon Yaseen [import]uid: 108129 topic_id: 33696 reply_id: 133997[/import]

HI Haroon

I tried the same code you gave , but in this when i print nick_name_data[1], at that time only it is showing all the content and for nick_name_data[2] it is showing nil. [import]uid: 130269 topic_id: 33696 reply_id: 134026[/import]

Hello Varun,
I use the same basic method as Haroon to read the text file into a Lua string named “contents”, like this:

local filePath = system.pathForFile( "your\_file.txt", system.DocumentsDirectory )  
local contents = ""  
local file = io.open( filePath, "r" )  
if ( file ) then  
 contents = file:read( "\*a" ) ; io.close( file ) ; file = nil ; filePath = nil  
end  

But instead of using string.find, I use a nested series of string matching and group matching to search for “patterns” within the contents string.

Using group matching (string.gmatch), you would find a “pattern” that accommodates the entire chunk of each question in your exam text file. For example, you might determine that each question “begins with a number, followed by a period, and ends with 2 newline breaks”.

Once you have a method of group matching to separate the entire text file into individual questions (each will be a new string), you loop through that part and string-match or group-match to make the question into clear “parts” that you can manipulate in Lua, for example"

– question number
– question text
– possible answers (multiple choice?)
– correct answer

Unfortunately, string matching is a very complicated and tedious procedure, because it needs to be EXACT to pull out exactly what you need. But, that’s the necessary method, unless you want to manually cut-and-paste every question from your text file into Lua table or SQLite database, or XML, JSON, etc.

Here’s the Lua documentation on the string matching functions.
http://docs.coronalabs.com/api/library/string/gmatch.html
http://docs.coronalabs.com/api/library/string/match.html
http://developer.coronalabs.com/content/strings (look under “Patterns”)

Since this is a very complex procedure, I might be able to help you with a sample string search if you provide me with one sample question from your exam. Post the entire question text as it appears in your text file, and I’ll take a look.

Brent [import]uid: 200026 topic_id: 33696 reply_id: 134044[/import]

You didn’t give full specifics of what is in the file, however I think it may be easier to just use a text editor that has FIND & REPLACE functionality to prep the file for import as JSON.

If the file is formated like so:

“1. Why is the sky blue?”
“2. Why is grass green?”
“3. Why is water green or blue?”

You can easily make this into a file that can be JSON decoded.

If you add [at the beginning of the file,] and the end of the file and put a , between each question, it can be json decoded into a table. I would just insert the two brackets manually and then do a FIND & REPLACE for the carriage return, replace it with a carriage return with a , in front of it. Then just do something like the following in corona to put it in a table. To me this seems easier than coding something as most text editors can do the brunt of the work.

json = require("json")  
  
local text = {}  
  
local path = system.pathForFile( "questions.txt", system.ResourceDirectory )  
local fh = io.open( path, "r" )  
local data = fh:read( "\*a" )  
text = json.decode(data)  
  
print (text[1]) -- prints: 1. Why is the sky blue?  
print (text[2]) -- prints: 2. Why is grass green?  
print (text[3]) -- prints: 3. Why is water green or blue?  

From your description though I am not 100% sure how the file is formated. As other’s mentioned there could be answers in the file as well. Perhaps give as an example of what is really in the file? [import]uid: 56820 topic_id: 33696 reply_id: 134082[/import]

HI Brent and Anderoth

Thanks a lot for your comments will try both the ways you suggested and will let you know was i able to make ip with the work or not. But your answers were really impressive and it will really help me in future projects as well.

Once again thanks a lot man.

Regards
Varun [import]uid: 130269 topic_id: 33696 reply_id: 134115[/import]

– Hey varun, Just paste this text to main.lua and execute it. It’s working fine on my simulator
display.setStatusBar( display.HiddenStatusBar )
local function main()
-------------------- TO WRITE ANY FILE IN TEXT FORMAT ------------------------------------------
local path = system.pathForFile( “nick_name.txt”, system.DocumentsDirectory )
local file = io.open( path, “w+b” )
– save current state variables in comma separated list
file:write( “MY NAME IS HAROON " …”, “…” AND I LOVE"…", "…"CORONA, ")
– at the end, the comma and space is much more important. it is used to differentiate in different objects written in text file.
– for line in file:lines() do print(“line”) end
io.close( file )
----------------------TO READ ANY FILE ----------------------------------------------------------------
function explode(div,str)
if (div==’’) then
return false
end
local pos=0
local arr = {}
– for each divider found
for st,sp in function() return string.find(str,div,pos,true) end do
table.insert(arr,string.sub(str,pos,st-1)) – Attach chars left of current divider
pos = sp + 1 – Jump past current divider
end
table.insert(arr,string.sub(str,pos)) – Attach chars right of last divider
return arr
end

function nick_name( )

local path = system.pathForFile( “nick_name.txt”, system.DocumentsDirectory )
local file = io.open( path, “r” )

if file then
print(“loading nick_name”)
local contents = file:read( “*a” )
print("the contents of file is “…contents)
local prevState1 = explode(”, ", contents)
io.close( file )
return prevState1
end
end

local nick_name_data = {}
nick_name_data = nick_name( )
– the actual data in text file can be retrieve like this, nick_name_data[1] = MY NAME IS HAROON and nick_name_data[2] = AND I LOVE and in third nick_name_data[3] = CORONA
print(nick_name_data[1]…" its the first index “…nick_name_data[2]…” it is second index “…nick_name_data[3]…” it s third index")

return true
end

main() [import]uid: 108129 topic_id: 33696 reply_id: 134119[/import]

Anderoth, your method is much more easy and convenient to implement. Quick and easy approach.

Regards,
Haroon Yaseen [import]uid: 108129 topic_id: 33696 reply_id: 134121[/import]

Hi Haroon

I implemented the same code and now it is working fine, thanks a lot man.

Regards
Varun [import]uid: 130269 topic_id: 33696 reply_id: 134135[/import]

Hello Varun,
Are the test questions written in any predictable structure? You’ll probably need to use file I/O and detailed string matching functions to “pick” all of the information from a particular question, then place that into some kind of table-subtables arrangement. If you’ve done string matching before, you’ll know it’s complicated and prone to user error. But, I think you don’t have a better choice.

Brent [import]uid: 200026 topic_id: 33696 reply_id: 133990[/import]

HI Brent

Thanks for the reply, the in text file all the different objects are separated by double inverted comma("")
I dont know how to use I/O file, if you can share an similar example that will be great. SImilar type of coding can be done in core ios sdk or android sdk, but i dont know how to use it here.

Hoping for your reply.

Regards
Varun [import]uid: 130269 topic_id: 33696 reply_id: 133991[/import]

Hi Haroon

Thanks for your detail reply, I tried the code you send me, but it is showing error :

“attempt to call global ‘explode’ (a nil value)”

Do you have any idea regarding this error?

Regards
Varun [import]uid: 130269 topic_id: 33696 reply_id: 134006[/import]

oh , that should also include at the start!
function explode(div,str)
if (div==’’) then
return false
end
local pos=0
local arr = {}
– for each divider found
for st,sp in function() return string.find(str,div,pos,true) end do
table.insert(arr,string.sub(str,pos,st-1)) – Attach chars left of current divider
pos = sp + 1 – Jump past current divider
end
table.insert(arr,string.sub(str,pos)) – Attach chars right of last divider
return arr
end

and one thing more, at the end of line given below, put “, “, so it should be like
file:write( “MY NAME IS HAROON " …”, “…” AND I LOVE”…”, “…“CORONA”…”, ")

for any other error, feel free to post

Regards,
Haroon Yaseen [import]uid: 108129 topic_id: 33696 reply_id: 134012[/import]

HI VARUN,
I think, it will help u.
-------------------- TO WRITE ANY FILE IN TEXT FORMAT ------------------------------------------
local path = system.pathForFile( “nick_name.txt”, system.DocumentsDirectory )
local file = io.open( path, “w+b” )
– save current state variables in comma separated list
file:write( “MY NAME IS HAROON " …”, “…” AND I LOVE"…", "…"CORONA, ")
– at the end, the comma and space is much more important. it is used to differentiate in different objects written in text file.
– for line in file:lines() do print(“line”) end
io.close( file )
----------------------TO READ ANY FILE ----------------------------------------------------------------
function explode(div,str)
if (div==’’) then
return false
end
local pos=0
local arr = {}
– for each divider found
for st,sp in function() return string.find(str,div,pos,true) end do
table.insert(arr,string.sub(str,pos,st-1)) – Attach chars left of current divider
pos = sp + 1 – Jump past current divider
end
table.insert(arr,string.sub(str,pos)) – Attach chars right of last divider
return arr
end
function nick_name( )

local path = system.pathForFile( “nick_name.txt”, system.DocumentsDirectory )
local file = io.open( path, “r” )

if file then
print(“loading nick_name”)
local contents = file:read( “*a” )
print("the contents of file is “…contents)
local prevState1 = explode(”, ", contents)
io.close( file )
return prevState1
end
end

local nick_name_data = {}
nick_name_data = nick_name( )
– the actual data in text file can be retrieve like this, nick_name_data[1] = MY NAME IS HAROON and nick_name_data[2] = AND I LOVE and in third nick_name_data[3] = CORONA

Kind Regards,
Haroon Yaseen [import]uid: 108129 topic_id: 33696 reply_id: 133997[/import]

HI Haroon

I tried the same code you gave , but in this when i print nick_name_data[1], at that time only it is showing all the content and for nick_name_data[2] it is showing nil. [import]uid: 130269 topic_id: 33696 reply_id: 134026[/import]

Hello Varun,
I use the same basic method as Haroon to read the text file into a Lua string named “contents”, like this:

local filePath = system.pathForFile( "your\_file.txt", system.DocumentsDirectory )  
local contents = ""  
local file = io.open( filePath, "r" )  
if ( file ) then  
 contents = file:read( "\*a" ) ; io.close( file ) ; file = nil ; filePath = nil  
end  

But instead of using string.find, I use a nested series of string matching and group matching to search for “patterns” within the contents string.

Using group matching (string.gmatch), you would find a “pattern” that accommodates the entire chunk of each question in your exam text file. For example, you might determine that each question “begins with a number, followed by a period, and ends with 2 newline breaks”.

Once you have a method of group matching to separate the entire text file into individual questions (each will be a new string), you loop through that part and string-match or group-match to make the question into clear “parts” that you can manipulate in Lua, for example"

– question number
– question text
– possible answers (multiple choice?)
– correct answer

Unfortunately, string matching is a very complicated and tedious procedure, because it needs to be EXACT to pull out exactly what you need. But, that’s the necessary method, unless you want to manually cut-and-paste every question from your text file into Lua table or SQLite database, or XML, JSON, etc.

Here’s the Lua documentation on the string matching functions.
http://docs.coronalabs.com/api/library/string/gmatch.html
http://docs.coronalabs.com/api/library/string/match.html
http://developer.coronalabs.com/content/strings (look under “Patterns”)

Since this is a very complex procedure, I might be able to help you with a sample string search if you provide me with one sample question from your exam. Post the entire question text as it appears in your text file, and I’ll take a look.

Brent [import]uid: 200026 topic_id: 33696 reply_id: 134044[/import]